UEsDBBQAAAAAAAAAIQAAAAAAAAAAAAAAAAAEAAAAY29tL1BLAwQUAAAAAAAAACEAAAAAAAAAAAAAAAAACwAAAGNvbS9nb29nbGUvUEsDBBQAAAAAAAAAIQAAAAAAAAAAAAAAAAAPAAAAY29tL2dvb2dsZS9hcGkvUEsDBBQAAAAAAAAAIQAAAAAAAAAAAAAAAAAYAAAAY29tL2dvb2dsZS9hcGkvc2VydmljZXMvUEsDBBQAAAAAAAAAIQAAAAAAAAAAAAAAAAAcAAAAY29tL2dvb2dsZS9hcGkvc2VydmljZXMvaWFtL1BLAwQUAAAAAAAAACEAAAAAAAAAAAAAAAAAHwAAAGNvbS9nb29nbGUvYXBpL3NlcnZpY2VzL2lhbS92MS9QSwMEFAAAAAAAAAAhAIOvde+8BQAAvAUAAC0AAABjb20vZ29vZ2xlL2FwaS9zZXJ2aWNlcy9pYW0vdjEvSWFtU2NvcGVzLmphdmEvKgogKiBDb3B5cmlnaHQgMjAxMCBHb29nbGUgSW5jLgogKgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQKICogaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UKICogaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzCiAqIG9yIGltcGxpZWQuIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMgdW5kZXIKICogdGhlIExpY2Vuc2UuCiAqLwovKgogKiBUaGlzIGNvZGUgd2FzIGdlbmVyYXRlZCBieSBodHRwczovL2dpdGh1Yi5jb20vZ29vZ2xlL2FwaXMtY2xpZW50LWdlbmVyYXRvci8KICogKGJ1aWxkOiAyMDE4LTEwLTA4IDE3OjQ1OjM5IFVUQykKICogb24gMjAyMC0wMy0xOSBhdCAwMTo1Mjo0MSBVVEMgCiAqIE1vZGlmeSBhdCB5b3VyIG93biByaXNrLgogKi8KCnBhY2thZ2UgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuaWFtLnYxOwoKLyoqCiAqIEF2YWlsYWJsZSBPQXV0aCAyLjAgc2NvcGVzIGZvciB1c2Ugd2l0aCB0aGUgSWRlbnRpdHkgYW5kIEFjY2VzcyBNYW5hZ2VtZW50IChJQU0pIEFQSS4KICoKICogQHNpbmNlIDEuNAogKi8KcHVibGljIGNsYXNzIElhbVNjb3BlcyB7CgogIC8qKiBWaWV3IGFuZCBtYW5hZ2UgeW91ciBkYXRhIGFjcm9zcyBHb29nbGUgQ2xvdWQgUGxhdGZvcm0gc2VydmljZXMuICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQ0xPVURfUExBVEZPUk0gPSAiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vYXV0aC9jbG91ZC1wbGF0Zm9ybSI7CgogIC8qKgogICAqIFJldHVybnMgYW4gdW5tb2RpZmlhYmxlIHNldCB0aGF0IGNvbnRhaW5zIGFsbCBzY29wZXMgZGVjbGFyZWQgYnkgdGhpcyBjbGFzcy4KICAgKgogICAqIEBzaW5jZSAxLjE2CiAgICovCiAgcHVibGljIHN0YXRpYyBqYXZhLnV0aWwuU2V0PFN0cmluZz4gYWxsKCkgewogICAgamF2YS51dGlsLlNldDxTdHJpbmc+IHNldCA9IG5ldyBqYXZhLnV0aWwuSGFzaFNldDxTdHJpbmc+KCk7CiAgICBzZXQuYWRkKENMT1VEX1BMQVRGT1JNKTsKICAgIHJldHVybiBqYXZhLnV0aWwuQ29sbGVjdGlvbnMudW5tb2RpZmlhYmxlU2V0KHNldCk7CiAgfQoKICBwcml2YXRlIElhbVNjb3BlcygpIHsKICB9Cn0KUEsDBBQAAAAAAAAAIQBDDSEmFR4AABUeAAAuAAAAY29tL2dvb2dsZS9hcGkvc2VydmljZXMvaWFtL3YxL0lhbVJlcXVlc3QuamF2YS8qCiAqIENvcHlyaWdodCAyMDEwIEdvb2dsZSBJbmMuCiAqCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdAogKiBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZQogKiBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3MKICogb3IgaW1wbGllZC4gU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucyB1bmRlcgogKiB0aGUgTGljZW5zZS4KICovCi8qCiAqIFRoaXMgY29kZSB3YXMgZ2VuZXJhdGVkIGJ5IGh0dHBzOi8vZ2l0aHViLmNvbS9nb29nbGUvYXBpcy1jbGllbnQtZ2VuZXJhdG9yLwogKiAoYnVpbGQ6IDIwMTgtMTAtMDggMTc6NDU6MzkgVVRDKQogKiBvbiAyMDIwLTAzLTE5IGF0IDAxOjUyOjQxIFVUQyAKICogTW9kaWZ5IGF0IHlvdXIgb3duIHJpc2suCiAqLwoKcGFja2FnZSBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5pYW0udjE7CgovKioKICogSWFtIHJlcXVlc3QuCiAqCiAqIEBzaW5jZSAxLjMKICovCkBTdXBwcmVzc1dhcm5pbmdzKCJqYXZhZG9jIikKcHVibGljIGFic3RyYWN0IGNsYXNzIElhbVJlcXVlc3Q8VD4gZXh0ZW5kcyBjb20uZ29vZ2xlLmFwaS5jbGllbnQuZ29vZ2xlYXBpcy5zZXJ2aWNlcy5qc29uLkFic3RyYWN0R29vZ2xlSnNvbkNsaWVudFJlcXVlc3Q8VD4gewoKICAvKioKICAgKiBAcGFyYW0gY2xpZW50IEdvb2dsZSBjbGllbnQKICAgKiBAcGFyYW0gbWV0aG9kIEhUVFAgTWV0aG9kCiAgICogQHBhcmFtIHVyaVRlbXBsYXRlIFVSSSB0ZW1wbGF0ZSBmb3IgdGhlIHBhdGggcmVsYXRpdmUgdG8gdGhlIGJhc2UgVVJMLiBJZiBpdCBzdGFydHMgd2l0aCBhICIvIgogICAqICAgICAgICB0aGUgYmFzZSBwYXRoIGZyb20gdGhlIGJhc2UgVVJMIHdpbGwgYmUgc3RyaXBwZWQgb3V0LiBUaGUgVVJJIHRlbXBsYXRlIGNhbiBhbHNvIGJlIGEKICAgKiAgICAgICAgZnVsbCBVUkwuIFVSSSB0ZW1wbGF0ZSBleHBhbnNpb24gaXMgZG9uZSB1c2luZwogICAqICAgICAgICB7QGxpbmsgY29tLmdvb2dsZS5hcGkuY2xpZW50Lmh0dHAuVXJpVGVtcGxhdGUjZXhwYW5kKFN0cmluZywgU3RyaW5nLCBPYmplY3QsIGJvb2xlYW4pfQogICAqIEBwYXJhbSBjb250ZW50IEEgUE9KTyB0aGF0IGNhbiBiZSBzZXJpYWxpemVkIGludG8gSlNPTiBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKiBAcGFyYW0gcmVzcG9uc2VDbGFzcyByZXNwb25zZSBjbGFzcyB0byBwYXJzZSBpbnRvCiAgICovCiAgcHVibGljIElhbVJlcXVlc3QoCiAgICAgIElhbSBjbGllbnQsIFN0cmluZyBtZXRob2QsIFN0cmluZyB1cmlUZW1wbGF0ZSwgT2JqZWN0IGNvbnRlbnQsIENsYXNzPFQ+IHJlc3BvbnNlQ2xhc3MpIHsKICAgIHN1cGVyKAogICAgICAgIGNsaWVudCwKICAgICAgICBtZXRob2QsCiAgICAgICAgdXJpVGVtcGxhdGUsCiAgICAgICAgY29udGVudCwKICAgICAgICByZXNwb25zZUNsYXNzKTsKICB9CgogIC8qKiBWMSBlcnJvciBmb3JtYXQuICovCiAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleSgiJC54Z2FmdiIpCiAgcHJpdmF0ZSBqYXZhLmxhbmcuU3RyaW5nICRYZ2FmdjsKCiAgLyoqCiAgICogVjEgZXJyb3IgZm9ybWF0LgogICAqLwogIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldCRYZ2FmdigpIHsKICAgIHJldHVybiAkWGdhZnY7CiAgfQoKICAvKiogVjEgZXJyb3IgZm9ybWF0LiAqLwogIHB1YmxpYyBJYW1SZXF1ZXN0PFQ+IHNldCRYZ2FmdihqYXZhLmxhbmcuU3RyaW5nICRYZ2FmdikgewogICAgdGhpcy4kWGdhZnYgPSAkWGdhZnY7CiAgICByZXR1cm4gdGhpczsKICB9CgogIC8qKiBPQXV0aCBhY2Nlc3MgdG9rZW4uICovCiAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleSgiYWNjZXNzX3Rva2VuIikKICBwcml2YXRlIGphdmEubGFuZy5TdHJpbmcgYWNjZXNzVG9rZW47CgogIC8qKgogICAqIE9BdXRoIGFjY2VzcyB0b2tlbi4KICAgKi8KICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRBY2Nlc3NUb2tlbigpIHsKICAgIHJldHVybiBhY2Nlc3NUb2tlbjsKICB9CgogIC8qKiBPQXV0aCBhY2Nlc3MgdG9rZW4uICovCiAgcHVibGljIElhbVJlcXVlc3Q8VD4gc2V0QWNjZXNzVG9rZW4oamF2YS5sYW5nLlN0cmluZyBhY2Nlc3NUb2tlbikgewogICAgdGhpcy5hY2Nlc3NUb2tlbiA9IGFjY2Vzc1Rva2VuOwogICAgcmV0dXJuIHRoaXM7CiAgfQoKICAvKiogRGF0YSBmb3JtYXQgZm9yIHJlc3BvbnNlLiAqLwogIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICBwcml2YXRlIGphdmEubGFuZy5TdHJpbmcgYWx0OwoKICAvKioKICAgKiBEYXRhIGZvcm1hdCBmb3IgcmVzcG9uc2UuIFtkZWZhdWx0OiBqc29uXQogICAqLwogIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldEFsdCgpIHsKICAgIHJldHVybiBhbHQ7CiAgfQoKICAvKiogRGF0YSBmb3JtYXQgZm9yIHJlc3BvbnNlLiAqLwogIHB1YmxpYyBJYW1SZXF1ZXN0PFQ+IHNldEFsdChqYXZhLmxhbmcuU3RyaW5nIGFsdCkgewogICAgdGhpcy5hbHQgPSBhbHQ7CiAgICByZXR1cm4gdGhpczsKICB9CgogIC8qKiBKU09OUCAqLwogIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICBwcml2YXRlIGphdmEubGFuZy5TdHJpbmcgY2FsbGJhY2s7CgogIC8qKgogICAqIEpTT05QCiAgICovCiAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0Q2FsbGJhY2soKSB7CiAgICByZXR1cm4gY2FsbGJhY2s7CiAgfQoKICAvKiogSlNPTlAgKi8KICBwdWJsaWMgSWFtUmVxdWVzdDxUPiBzZXRDYWxsYmFjayhqYXZhLmxhbmcuU3RyaW5nIGNhbGxiYWNrKSB7CiAgICB0aGlzLmNhbGxiYWNrID0gY2FsbGJhY2s7CiAgICByZXR1cm4gdGhpczsKICB9CgogIC8qKiBTZWxlY3RvciBzcGVjaWZ5aW5nIHdoaWNoIGZpZWxkcyB0byBpbmNsdWRlIGluIGEgcGFydGlhbCByZXNwb25zZS4gKi8KICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgcHJpdmF0ZSBqYXZhLmxhbmcuU3RyaW5nIGZpZWxkczsKCiAgLyoqCiAgICogU2VsZWN0b3Igc3BlY2lmeWluZyB3aGljaCBmaWVsZHMgdG8gaW5jbHVkZSBpbiBhIHBhcnRpYWwgcmVzcG9uc2UuCiAgICovCiAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0RmllbGRzKCkgewogICAgcmV0dXJuIGZpZWxkczsKICB9CgogIC8qKiBTZWxlY3RvciBzcGVjaWZ5aW5nIHdoaWNoIGZpZWxkcyB0byBpbmNsdWRlIGluIGEgcGFydGlhbCByZXNwb25zZS4gKi8KICBwdWJsaWMgSWFtUmVxdWVzdDxUPiBzZXRGaWVsZHMoamF2YS5sYW5nLlN0cmluZyBmaWVsZHMpIHsKICAgIHRoaXMuZmllbGRzID0gZmllbGRzOwogICAgcmV0dXJuIHRoaXM7CiAgfQoKICAvKioKICAgKiBBUEkga2V5LiBZb3VyIEFQSSBrZXkgaWRlbnRpZmllcyB5b3VyIHByb2plY3QgYW5kIHByb3ZpZGVzIHlvdSB3aXRoIEFQSSBhY2Nlc3MsIHF1b3RhLCBhbmQKICAgKiByZXBvcnRzLiBSZXF1aXJlZCB1bmxlc3MgeW91IHByb3ZpZGUgYW4gT0F1dGggMi4wIHRva2VuLgogICAqLwogIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICBwcml2YXRlIGphdmEubGFuZy5TdHJpbmcga2V5OwoKICAvKioKICAgKiBBUEkga2V5LiBZb3VyIEFQSSBrZXkgaWRlbnRpZmllcyB5b3VyIHByb2plY3QgYW5kIHByb3ZpZGVzIHlvdSB3aXRoIEFQSSBhY2Nlc3MsIHF1b3RhLCBhbmQKICAgKiByZXBvcnRzLiBSZXF1aXJlZCB1bmxlc3MgeW91IHByb3ZpZGUgYW4gT0F1dGggMi4wIHRva2VuLgogICAqLwogIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldEtleSgpIHsKICAgIHJldHVybiBrZXk7CiAgfQoKICAvKioKICAgKiBBUEkga2V5LiBZb3VyIEFQSSBrZXkgaWRlbnRpZmllcyB5b3VyIHByb2plY3QgYW5kIHByb3ZpZGVzIHlvdSB3aXRoIEFQSSBhY2Nlc3MsIHF1b3RhLCBhbmQKICAgKiByZXBvcnRzLiBSZXF1aXJlZCB1bmxlc3MgeW91IHByb3ZpZGUgYW4gT0F1dGggMi4wIHRva2VuLgogICAqLwogIHB1YmxpYyBJYW1SZXF1ZXN0PFQ+IHNldEtleShqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgdGhpcy5rZXkgPSBrZXk7CiAgICByZXR1cm4gdGhpczsKICB9CgogIC8qKiBPQXV0aCAyLjAgdG9rZW4gZm9yIHRoZSBjdXJyZW50IHVzZXIuICovCiAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleSgib2F1dGhfdG9rZW4iKQogIHByaXZhdGUgamF2YS5sYW5nLlN0cmluZyBvYXV0aFRva2VuOwoKICAvKioKICAgKiBPQXV0aCAyLjAgdG9rZW4gZm9yIHRoZSBjdXJyZW50IHVzZXIuCiAgICovCiAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0T2F1dGhUb2tlbigpIHsKICAgIHJldHVybiBvYXV0aFRva2VuOwogIH0KCiAgLyoqIE9BdXRoIDIuMCB0b2tlbiBmb3IgdGhlIGN1cnJlbnQgdXNlci4gKi8KICBwdWJsaWMgSWFtUmVxdWVzdDxUPiBzZXRPYXV0aFRva2VuKGphdmEubGFuZy5TdHJpbmcgb2F1dGhUb2tlbikgewogICAgdGhpcy5vYXV0aFRva2VuID0gb2F1dGhUb2tlbjsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgLyoqIFJldHVybnMgcmVzcG9uc2Ugd2l0aCBpbmRlbnRhdGlvbnMgYW5kIGxpbmUgYnJlYWtzLiAqLwogIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICBwcml2YXRlIGphdmEubGFuZy5Cb29sZWFuIHByZXR0eVByaW50OwoKICAvKioKICAgKiBSZXR1cm5zIHJlc3BvbnNlIHdpdGggaW5kZW50YXRpb25zIGFuZCBsaW5lIGJyZWFrcy4gW2RlZmF1bHQ6IHRydWVdCiAgICovCiAgcHVibGljIGphdmEubGFuZy5Cb29sZWFuIGdldFByZXR0eVByaW50KCkgewogICAgcmV0dXJuIHByZXR0eVByaW50OwogIH0KCiAgLyoqIFJldHVybnMgcmVzcG9uc2Ugd2l0aCBpbmRlbnRhdGlvbnMgYW5kIGxpbmUgYnJlYWtzLiAqLwogIHB1YmxpYyBJYW1SZXF1ZXN0PFQ+IHNldFByZXR0eVByaW50KGphdmEubGFuZy5Cb29sZWFuIHByZXR0eVByaW50KSB7CiAgICB0aGlzLnByZXR0eVByaW50ID0gcHJldHR5UHJpbnQ7CiAgICByZXR1cm4gdGhpczsKICB9CgogIC8qKgogICAqIEF2YWlsYWJsZSB0byB1c2UgZm9yIHF1b3RhIHB1cnBvc2VzIGZvciBzZXJ2ZXItc2lkZSBhcHBsaWNhdGlvbnMuIENhbiBiZSBhbnkgYXJiaXRyYXJ5IHN0cmluZwogICAqIGFzc2lnbmVkIHRvIGEgdXNlciwgYnV0IHNob3VsZCBub3QgZXhjZWVkIDQwIGNoYXJhY3RlcnMuCiAgICovCiAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogIHByaXZhdGUgamF2YS5sYW5nLlN0cmluZyBxdW90YVVzZXI7CgogIC8qKgogICAqIEF2YWlsYWJsZSB0byB1c2UgZm9yIHF1b3RhIHB1cnBvc2VzIGZvciBzZXJ2ZXItc2lkZSBhcHBsaWNhdGlvbnMuIENhbiBiZSBhbnkgYXJiaXRyYXJ5IHN0cmluZwogICAqIGFzc2lnbmVkIHRvIGEgdXNlciwgYnV0IHNob3VsZCBub3QgZXhjZWVkIDQwIGNoYXJhY3RlcnMuCiAgICovCiAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0UXVvdGFVc2VyKCkgewogICAgcmV0dXJuIHF1b3RhVXNlcjsKICB9CgogIC8qKgogICAqIEF2YWlsYWJsZSB0byB1c2UgZm9yIHF1b3RhIHB1cnBvc2VzIGZvciBzZXJ2ZXItc2lkZSBhcHBsaWNhdGlvbnMuIENhbiBiZSBhbnkgYXJiaXRyYXJ5IHN0cmluZwogICAqIGFzc2lnbmVkIHRvIGEgdXNlciwgYnV0IHNob3VsZCBub3QgZXhjZWVkIDQwIGNoYXJhY3RlcnMuCiAgICovCiAgcHVibGljIElhbVJlcXVlc3Q8VD4gc2V0UXVvdGFVc2VyKGphdmEubGFuZy5TdHJpbmcgcXVvdGFVc2VyKSB7CiAgICB0aGlzLnF1b3RhVXNlciA9IHF1b3RhVXNlcjsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgLyoqIExlZ2FjeSB1cGxvYWQgcHJvdG9jb2wgZm9yIG1lZGlhIChlLmcuICJtZWRpYSIsICJtdWx0aXBhcnQiKS4gKi8KICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgcHJpdmF0ZSBqYXZhLmxhbmcuU3RyaW5nIHVwbG9hZFR5cGU7CgogIC8qKgogICAqIExlZ2FjeSB1cGxvYWQgcHJvdG9jb2wgZm9yIG1lZGlhIChlLmcuICJtZWRpYSIsICJtdWx0aXBhcnQiKS4KICAgKi8KICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRVcGxvYWRUeXBlKCkgewogICAgcmV0dXJuIHVwbG9hZFR5cGU7CiAgfQoKICAvKiogTGVnYWN5IHVwbG9hZCBwcm90b2NvbCBmb3IgbWVkaWEgKGUuZy4gIm1lZGlhIiwgIm11bHRpcGFydCIpLiAqLwogIHB1YmxpYyBJYW1SZXF1ZXN0PFQ+IHNldFVwbG9hZFR5cGUoamF2YS5sYW5nLlN0cmluZyB1cGxvYWRUeXBlKSB7CiAgICB0aGlzLnVwbG9hZFR5cGUgPSB1cGxvYWRUeXBlOwogICAgcmV0dXJuIHRoaXM7CiAgfQoKICAvKiogVXBsb2FkIHByb3RvY29sIGZvciBtZWRpYSAoZS5nLiAicmF3IiwgIm11bHRpcGFydCIpLiAqLwogIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkoInVwbG9hZF9wcm90b2NvbCIpCiAgcHJpdmF0ZSBqYXZhLmxhbmcuU3RyaW5nIHVwbG9hZFByb3RvY29sOwoKICAvKioKICAgKiBVcGxvYWQgcHJvdG9jb2wgZm9yIG1lZGlhIChlLmcuICJyYXciLCAibXVsdGlwYXJ0IikuCiAgICovCiAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0VXBsb2FkUHJvdG9jb2woKSB7CiAgICByZXR1cm4gdXBsb2FkUHJvdG9jb2w7CiAgfQoKICAvKiogVXBsb2FkIHByb3RvY29sIGZvciBtZWRpYSAoZS5nLiAicmF3IiwgIm11bHRpcGFydCIpLiAqLwogIHB1YmxpYyBJYW1SZXF1ZXN0PFQ+IHNldFVwbG9hZFByb3RvY29sKGphdmEubGFuZy5TdHJpbmcgdXBsb2FkUHJvdG9jb2wpIHsKICAgIHRoaXMudXBsb2FkUHJvdG9jb2wgPSB1cGxvYWRQcm90b2NvbDsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgQE92ZXJyaWRlCiAgcHVibGljIGZpbmFsIElhbSBnZXRBYnN0cmFjdEdvb2dsZUNsaWVudCgpIHsKICAgIHJldHVybiAoSWFtKSBzdXBlci5nZXRBYnN0cmFjdEdvb2dsZUNsaWVudCgpOwogIH0KCiAgQE92ZXJyaWRlCiAgcHVibGljIElhbVJlcXVlc3Q8VD4gc2V0RGlzYWJsZUdaaXBDb250ZW50KGJvb2xlYW4gZGlzYWJsZUdaaXBDb250ZW50KSB7CiAgICByZXR1cm4gKElhbVJlcXVlc3Q8VD4pIHN1cGVyLnNldERpc2FibGVHWmlwQ29udGVudChkaXNhYmxlR1ppcENvbnRlbnQpOwogIH0KCiAgQE92ZXJyaWRlCiAgcHVibGljIElhbVJlcXVlc3Q8VD4gc2V0UmVxdWVzdEhlYWRlcnMoY29tLmdvb2dsZS5hcGkuY2xpZW50Lmh0dHAuSHR0cEhlYWRlcnMgaGVhZGVycykgewogICAgcmV0dXJuIChJYW1SZXF1ZXN0PFQ+KSBzdXBlci5zZXRSZXF1ZXN0SGVhZGVycyhoZWFkZXJzKTsKICB9CgogIEBPdmVycmlkZQogIHB1YmxpYyBJYW1SZXF1ZXN0PFQ+IHNldChTdHJpbmcgcGFyYW1ldGVyTmFtZSwgT2JqZWN0IHZhbHVlKSB7CiAgICByZXR1cm4gKElhbVJlcXVlc3Q8VD4pIHN1cGVyLnNldChwYXJhbWV0ZXJOYW1lLCB2YWx1ZSk7CiAgfQp9ClBLAwQUAAAAAAAAACEAvaqQQkIxBQBCMQUAJwAAAGNvbS9nb29nbGUvYXBpL3NlcnZpY2VzL2lhbS92MS9JYW0uamF2YS8qCiAqIENvcHlyaWdodCAyMDEwIEdvb2dsZSBJbmMuCiAqCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdAogKiBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZQogKiBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3MKICogb3IgaW1wbGllZC4gU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucyB1bmRlcgogKiB0aGUgTGljZW5zZS4KICovCi8qCiAqIFRoaXMgY29kZSB3YXMgZ2VuZXJhdGVkIGJ5IGh0dHBzOi8vZ2l0aHViLmNvbS9nb29nbGUvYXBpcy1jbGllbnQtZ2VuZXJhdG9yLwogKiAoYnVpbGQ6IDIwMTgtMTAtMDggMTc6NDU6MzkgVVRDKQogKiBvbiAyMDIwLTAzLTE5IGF0IDAxOjUyOjQxIFVUQyAKICogTW9kaWZ5IGF0IHlvdXIgb3duIHJpc2suCiAqLwoKcGFja2FnZSBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5pYW0udjE7CgovKioKICogU2VydmljZSBkZWZpbml0aW9uIGZvciBJYW0gKHYxKS4KICoKICogPHA+CiAqIE1hbmFnZXMgaWRlbnRpdHkgYW5kIGFjY2VzcyBjb250cm9sIGZvciBHb29nbGUgQ2xvdWQgUGxhdGZvcm0gcmVzb3VyY2VzLCBpbmNsdWRpbmcgdGhlIGNyZWF0aW9uIG9mIHNlcnZpY2UgYWNjb3VudHMsIHdoaWNoIHlvdSBjYW4gdXNlIHRvIGF1dGhlbnRpY2F0ZSB0byBHb29nbGUgYW5kIG1ha2UgQVBJIGNhbGxzLgogKiA8L3A+CiAqCiAqIDxwPgogKiBGb3IgbW9yZSBpbmZvcm1hdGlvbiBhYm91dCB0aGlzIHNlcnZpY2UsIHNlZSB0aGUKICogPGEgaHJlZj0iaHR0cHM6Ly9jbG91ZC5nb29nbGUuY29tL2lhbS8iIHRhcmdldD0iX2JsYW5rIj5BUEkgRG9jdW1lbnRhdGlvbjwvYT4KICogPC9wPgogKgogKiA8cD4KICogVGhpcyBzZXJ2aWNlIHVzZXMge0BsaW5rIElhbVJlcXVlc3RJbml0aWFsaXplcn0gdG8gaW5pdGlhbGl6ZSBnbG9iYWwgcGFyYW1ldGVycyB2aWEgaXRzCiAqIHtAbGluayBCdWlsZGVyfS4KICogPC9wPgogKgogKiBAc2luY2UgMS4zCiAqIEBhdXRob3IgR29vZ2xlLCBJbmMuCiAqLwpAU3VwcHJlc3NXYXJuaW5ncygiamF2YWRvYyIpCnB1YmxpYyBjbGFzcyBJYW0gZXh0ZW5kcyBjb20uZ29vZ2xlLmFwaS5jbGllbnQuZ29vZ2xlYXBpcy5zZXJ2aWNlcy5qc29uLkFic3RyYWN0R29vZ2xlSnNvbkNsaWVudCB7CgogIC8vIE5vdGU6IExlYXZlIHRoaXMgc3RhdGljIGluaXRpYWxpemVyIGF0IHRoZSB0b3Agb2YgdGhlIGZpbGUuCiAgc3RhdGljIHsKICAgIGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLlByZWNvbmRpdGlvbnMuY2hlY2tTdGF0ZSgKICAgICAgICBjb20uZ29vZ2xlLmFwaS5jbGllbnQuZ29vZ2xlYXBpcy5Hb29nbGVVdGlscy5NQUpPUl9WRVJTSU9OID09IDEgJiYKICAgICAgICBjb20uZ29vZ2xlLmFwaS5jbGllbnQuZ29vZ2xlYXBpcy5Hb29nbGVVdGlscy5NSU5PUl9WRVJTSU9OID49IDE1LAogICAgICAgICJZb3UgYXJlIGN1cnJlbnRseSBydW5uaW5nIHdpdGggdmVyc2lvbiAlcyBvZiBnb29nbGUtYXBpLWNsaWVudC4gIiArCiAgICAgICAgIllvdSBuZWVkIGF0IGxlYXN0IHZlcnNpb24gMS4xNSBvZiBnb29nbGUtYXBpLWNsaWVudCB0byBydW4gdmVyc2lvbiAiICsKICAgICAgICAiMS4yNS4wIG9mIHRoZSBJZGVudGl0eSBhbmQgQWNjZXNzIE1hbmFnZW1lbnQgKElBTSkgQVBJIGxpYnJhcnkuIiwgY29tLmdvb2dsZS5hcGkuY2xpZW50Lmdvb2dsZWFwaXMuR29vZ2xlVXRpbHMuVkVSU0lPTik7CiAgfQoKICAvKioKICAgKiBUaGUgZGVmYXVsdCBlbmNvZGVkIHJvb3QgVVJMIG9mIHRoZSBzZXJ2aWNlLiBUaGlzIGlzIGRldGVybWluZWQgd2hlbiB0aGUgbGlicmFyeSBpcyBnZW5lcmF0ZWQKICAgKiBhbmQgbm9ybWFsbHkgc2hvdWxkIG5vdCBiZSBjaGFuZ2VkLgogICAqCiAgICogQHNpbmNlIDEuNwogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIERFRkFVTFRfUk9PVF9VUkwgPSAiaHR0cHM6Ly9pYW0uZ29vZ2xlYXBpcy5jb20vIjsKCiAgLyoqCiAgICogVGhlIGRlZmF1bHQgZW5jb2RlZCBzZXJ2aWNlIHBhdGggb2YgdGhlIHNlcnZpY2UuIFRoaXMgaXMgZGV0ZXJtaW5lZCB3aGVuIHRoZSBsaWJyYXJ5IGlzCiAgICogZ2VuZXJhdGVkIGFuZCBub3JtYWxseSBzaG91bGQgbm90IGJlIGNoYW5nZWQuCiAgICoKICAgKiBAc2luY2UgMS43CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgREVGQVVMVF9TRVJWSUNFX1BBVEggPSAiIjsKCiAgLyoqCiAgICogVGhlIGRlZmF1bHQgZW5jb2RlZCBiYXRjaCBwYXRoIG9mIHRoZSBzZXJ2aWNlLiBUaGlzIGlzIGRldGVybWluZWQgd2hlbiB0aGUgbGlicmFyeSBpcwogICAqIGdlbmVyYXRlZCBhbmQgbm9ybWFsbHkgc2hvdWxkIG5vdCBiZSBjaGFuZ2VkLgogICAqCiAgICogQHNpbmNlIDEuMjMKICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBERUZBVUxUX0JBVENIX1BBVEggPSAiYmF0Y2giOwoKICAvKioKICAgKiBUaGUgZGVmYXVsdCBlbmNvZGVkIGJhc2UgVVJMIG9mIHRoZSBzZXJ2aWNlLiBUaGlzIGlzIGRldGVybWluZWQgd2hlbiB0aGUgbGlicmFyeSBpcyBnZW5lcmF0ZWQKICAgKiBhbmQgbm9ybWFsbHkgc2hvdWxkIG5vdCBiZSBjaGFuZ2VkLgogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIERFRkFVTFRfQkFTRV9VUkwgPSBERUZBVUxUX1JPT1RfVVJMICsgREVGQVVMVF9TRVJWSUNFX1BBVEg7CgogIC8qKgogICAqIENvbnN0cnVjdG9yLgogICAqCiAgICogPHA+CiAgICogVXNlIHtAbGluayBCdWlsZGVyfSBpZiB5b3UgbmVlZCB0byBzcGVjaWZ5IGFueSBvZiB0aGUgb3B0aW9uYWwgcGFyYW1ldGVycy4KICAgKiA8L3A+CiAgICoKICAgKiBAcGFyYW0gdHJhbnNwb3J0IEhUVFAgdHJhbnNwb3J0LCB3aGljaCBzaG91bGQgbm9ybWFsbHkgYmU6CiAgICogICAgICAgIDx1bD4KICAgKiAgICAgICAgPGxpPkdvb2dsZSBBcHAgRW5naW5lOgogICAqICAgICAgICB7QGNvZGUgY29tLmdvb2dsZS5hcGkuY2xpZW50LmV4dGVuc2lvbnMuYXBwZW5naW5lLmh0dHAuVXJsRmV0Y2hUcmFuc3BvcnR9PC9saT4KICAgKiAgICAgICAgPGxpPkFuZHJvaWQ6IHtAY29kZSBuZXdDb21wYXRpYmxlVHJhbnNwb3J0fSBmcm9tCiAgICogICAgICAgIHtAY29kZSBjb20uZ29vZ2xlLmFwaS5jbGllbnQuZXh0ZW5zaW9ucy5hbmRyb2lkLmh0dHAuQW5kcm9pZEh0dHB9PC9saT4KICAgKiAgICAgICAgPGxpPkphdmE6IHtAbGluayBjb20uZ29vZ2xlLmFwaS5jbGllbnQuZ29vZ2xlYXBpcy5qYXZhbmV0Lkdvb2dsZU5ldEh0dHBUcmFuc3BvcnQjbmV3VHJ1c3RlZFRyYW5zcG9ydCgpfQogICAqICAgICAgICA8L2xpPgogICAqICAgICAgICA8L3VsPgogICAqIEBwYXJhbSBqc29uRmFjdG9yeSBKU09OIGZhY3RvcnksIHdoaWNoIG1heSBiZToKICAgKiAgICAgICAgPHVsPgogICAqICAgICAgICA8bGk+SmFja3Nvbjoge0Bjb2RlIGNvbS5nb29nbGUuYXBpLmNsaWVudC5qc29uLmphY2tzb24yLkphY2tzb25GYWN0b3J5fTwvbGk+CiAgICogICAgICAgIDxsaT5Hb29nbGUgR1NPTjoge0Bjb2RlIGNvbS5nb29nbGUuYXBpLmNsaWVudC5qc29uLmdzb24uR3NvbkZhY3Rvcnl9PC9saT4KICAgKiAgICAgICAgPGxpPkFuZHJvaWQgSG9uZXljb21iIG9yIGhpZ2hlcjoKICAgKiAgICAgICAge0Bjb2RlIGNvbS5nb29nbGUuYXBpLmNsaWVudC5leHRlbnNpb25zLmFuZHJvaWQuanNvbi5BbmRyb2lkSnNvbkZhY3Rvcnl9PC9saT4KICAgKiAgICAgICAgPC91bD4KICAgKiBAcGFyYW0gaHR0cFJlcXVlc3RJbml0aWFsaXplciBIVFRQIHJlcXVlc3QgaW5pdGlhbGl6ZXIgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICogQHNpbmNlIDEuNwogICAqLwogIHB1YmxpYyBJYW0oY29tLmdvb2dsZS5hcGkuY2xpZW50Lmh0dHAuSHR0cFRyYW5zcG9ydCB0cmFuc3BvcnQsIGNvbS5nb29nbGUuYXBpLmNsaWVudC5qc29uLkpzb25GYWN0b3J5IGpzb25GYWN0b3J5LAogICAgICBjb20uZ29vZ2xlLmFwaS5jbGllbnQuaHR0cC5IdHRwUmVxdWVzdEluaXRpYWxpemVyIGh0dHBSZXF1ZXN0SW5pdGlhbGl6ZXIpIHsKICAgIHRoaXMobmV3IEJ1aWxkZXIodHJhbnNwb3J0LCBqc29uRmFjdG9yeSwgaHR0cFJlcXVlc3RJbml0aWFsaXplcikpOwogIH0KCiAgLyoqCiAgICogQHBhcmFtIGJ1aWxkZXIgYnVpbGRlcgogICAqLwogIElhbShCdWlsZGVyIGJ1aWxkZXIpIHsKICAgIHN1cGVyKGJ1aWxkZXIpOwogIH0KCiAgQE92ZXJyaWRlCiAgcHJvdGVjdGVkIHZvaWQgaW5pdGlhbGl6ZShjb20uZ29vZ2xlLmFwaS5jbGllbnQuZ29vZ2xlYXBpcy5zZXJ2aWNlcy5BYnN0cmFjdEdvb2dsZUNsaWVudFJlcXVlc3Q8Pz4gaHR0cENsaWVudFJlcXVlc3QpIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgIHN1cGVyLmluaXRpYWxpemUoaHR0cENsaWVudFJlcXVlc3QpOwogIH0KCiAgLyoqCiAgICogQW4gYWNjZXNzb3IgZm9yIGNyZWF0aW5nIHJlcXVlc3RzIGZyb20gdGhlIElhbVBvbGljaWVzIGNvbGxlY3Rpb24uCiAgICoKICAgKiA8cD5UaGUgdHlwaWNhbCB1c2UgaXM6PC9wPgogICAqIDxwcmU+CiAgICogICB7QGNvZGUgSWFtIGlhbSA9IG5ldyBJYW0oLi4uKTt9CiAgICogICB7QGNvZGUgSWFtLklhbVBvbGljaWVzLkxpc3QgcmVxdWVzdCA9IGlhbS5pYW1Qb2xpY2llcygpLmxpc3QocGFyYW1ldGVycyAuLi4pfQogICAqIDwvcHJlPgogICAqCiAgICogQHJldHVybiB0aGUgcmVzb3VyY2UgY29sbGVjdGlvbgogICAqLwogIHB1YmxpYyBJYW1Qb2xpY2llcyBpYW1Qb2xpY2llcygpIHsKICAgIHJldHVybiBuZXcgSWFtUG9saWNpZXMoKTsKICB9CgogIC8qKgogICAqIFRoZSAiaWFtUG9saWNpZXMiIGNvbGxlY3Rpb24gb2YgbWV0aG9kcy4KICAgKi8KICBwdWJsaWMgY2xhc3MgSWFtUG9saWNpZXMgewoKICAgIC8qKgogICAgICogTGludHMgYSBDbG91ZCBJQU0gcG9saWN5IG9iamVjdCBvciBpdHMgc3ViIGZpZWxkcy4gQ3VycmVudGx5IHN1cHBvcnRzCiAgICAgKiBnb29nbGUuaWFtLnYxLkJpbmRpbmcuY29uZGl0aW9uLgogICAgICoKICAgICAqIEVhY2ggbGludCBvcGVyYXRpb24gY29uc2lzdHMgb2YgbXVsdGlwbGUgbGludCB2YWxpZGF0aW9uIHVuaXRzLiBFYWNoIHVuaXQgaW5zcGVjdHMgdGhlIGlucHV0CiAgICAgKiBvYmplY3QgaW4gcmVnYXJkIHRvIGEgcGFydGljdWxhciBsaW50aW5nIGFzcGVjdCBhbmQgaXNzdWVzIGEgZ29vZ2xlLmlhbS5hZG1pbi52MS5MaW50UmVzdWx0CiAgICAgKiBkaXNjbG9zaW5nIHRoZSByZXN1bHQuCiAgICAgKgogICAgICogVGhlIHNldCBvZiBhcHBsaWNhYmxlIHZhbGlkYXRpb24gdW5pdHMgaXMgZGV0ZXJtaW5lZCBieSB0aGUgQ2xvdWQgSUFNIHNlcnZlciBhbmQgaXMgbm90CiAgICAgKiBjb25maWd1cmFibGUuCiAgICAgKgogICAgICogUmVnYXJkbGVzcyBvZiBhbnkgbGludCBpc3N1ZXMgb3IgdGhlaXIgc2V2ZXJpdGllcywgc3VjY2Vzc2Z1bCBjYWxscyB0byBgbGludFBvbGljeWAgcmV0dXJuIGFuCiAgICAgKiBIVFRQIDIwMCBPSyBzdGF0dXMgY29kZS4KICAgICAqCiAgICAgKiBDcmVhdGUgYSByZXF1ZXN0IGZvciB0aGUgbWV0aG9kICJpYW1Qb2xpY2llcy5saW50UG9saWN5Ii4KICAgICAqCiAgICAgKiBUaGlzIHJlcXVlc3QgaG9sZHMgdGhlIHBhcmFtZXRlcnMgbmVlZGVkIGJ5IHRoZSBpYW0gc2VydmVyLiAgQWZ0ZXIgc2V0dGluZyBhbnkgb3B0aW9uYWwKICAgICAqIHBhcmFtZXRlcnMsIGNhbGwgdGhlIHtAbGluayBMaW50UG9saWN5I2V4ZWN1dGUoKX0gbWV0aG9kIHRvIGludm9rZSB0aGUgcmVtb3RlIG9wZXJhdGlvbi4KICAgICAqCiAgICAgKiBAcGFyYW0gY29udGVudCB0aGUge0BsaW5rIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmlhbS52MS5tb2RlbC5MaW50UG9saWN5UmVxdWVzdH0KICAgICAqIEByZXR1cm4gdGhlIHJlcXVlc3QKICAgICAqLwogICAgcHVibGljIExpbnRQb2xpY3kgbGludFBvbGljeShjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5pYW0udjEubW9kZWwuTGludFBvbGljeVJlcXVlc3QgY29udGVudCkgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBMaW50UG9saWN5IHJlc3VsdCA9IG5ldyBMaW50UG9saWN5KGNvbnRlbnQpOwogICAgICBpbml0aWFsaXplKHJlc3VsdCk7CiAgICAgIHJldHVybiByZXN1bHQ7CiAgICB9CgogICAgcHVibGljIGNsYXNzIExpbnRQb2xpY3kgZXh0ZW5kcyBJYW1SZXF1ZXN0PGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmlhbS52MS5tb2RlbC5MaW50UG9saWN5UmVzcG9uc2U+IHsKCiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBSRVNUX1BBVEggPSAidjEvaWFtUG9saWNpZXM6bGludFBvbGljeSI7CgogICAgICAvKioKICAgICAgICogTGludHMgYSBDbG91ZCBJQU0gcG9saWN5IG9iamVjdCBvciBpdHMgc3ViIGZpZWxkcy4gQ3VycmVudGx5IHN1cHBvcnRzCiAgICAgICAqIGdvb2dsZS5pYW0udjEuQmluZGluZy5jb25kaXRpb24uCiAgICAgICAqCiAgICAgICAqIEVhY2ggbGludCBvcGVyYXRpb24gY29uc2lzdHMgb2YgbXVsdGlwbGUgbGludCB2YWxpZGF0aW9uIHVuaXRzLiBFYWNoIHVuaXQgaW5zcGVjdHMgdGhlIGlucHV0CiAgICAgICAqIG9iamVjdCBpbiByZWdhcmQgdG8gYSBwYXJ0aWN1bGFyIGxpbnRpbmcgYXNwZWN0IGFuZCBpc3N1ZXMgYSBnb29nbGUuaWFtLmFkbWluLnYxLkxpbnRSZXN1bHQKICAgICAgICogZGlzY2xvc2luZyB0aGUgcmVzdWx0LgogICAgICAgKgogICAgICAgKiBUaGUgc2V0IG9mIGFwcGxpY2FibGUgdmFsaWRhdGlvbiB1bml0cyBpcyBkZXRlcm1pbmVkIGJ5IHRoZSBDbG91ZCBJQU0gc2VydmVyIGFuZCBpcyBub3QKICAgICAgICogY29uZmlndXJhYmxlLgogICAgICAgKgogICAgICAgKiBSZWdhcmRsZXNzIG9mIGFueSBsaW50IGlzc3VlcyBvciB0aGVpciBzZXZlcml0aWVzLCBzdWNjZXNzZnVsIGNhbGxzIHRvIGBsaW50UG9saWN5YCByZXR1cm4gYW4KICAgICAgICogSFRUUCAyMDAgT0sgc3RhdHVzIGNvZGUuCiAgICAgICAqCiAgICAgICAqIENyZWF0ZSBhIHJlcXVlc3QgZm9yIHRoZSBtZXRob2QgImlhbVBvbGljaWVzLmxpbnRQb2xpY3kiLgogICAgICAgKgogICAgICAgKiBUaGlzIHJlcXVlc3QgaG9sZHMgdGhlIHBhcmFtZXRlcnMgbmVlZGVkIGJ5IHRoZSB0aGUgaWFtIHNlcnZlci4gIEFmdGVyIHNldHRpbmcgYW55IG9wdGlvbmFsCiAgICAgICAqIHBhcmFtZXRlcnMsIGNhbGwgdGhlIHtAbGluayBMaW50UG9saWN5I2V4ZWN1dGUoKX0gbWV0aG9kIHRvIGludm9rZSB0aGUgcmVtb3RlIG9wZXJhdGlvbi4gPHA+CiAgICAgICAqIHtAbGluawogICAgICAgKiBMaW50UG9saWN5I2luaXRpYWxpemUoY29tLmdvb2dsZS5hcGkuY2xpZW50Lmdvb2dsZWFwaXMuc2VydmljZXMuQWJzdHJhY3RHb29nbGVDbGllbnRSZXF1ZXN0KX0KICAgICAgICogbXVzdCBiZSBjYWxsZWQgdG8gaW5pdGlhbGl6ZSB0aGlzIGluc3RhbmNlIGltbWVkaWF0ZWx5IGFmdGVyIGludm9raW5nIHRoZSBjb25zdHJ1Y3Rvci4gPC9wPgogICAgICAgKgogICAgICAgKiBAcGFyYW0gY29udGVudCB0aGUge0BsaW5rIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmlhbS52MS5tb2RlbC5MaW50UG9saWN5UmVxdWVzdH0KICAgICAgICogQHNpbmNlIDEuMTMKICAgICAgICovCiAgICAgIHByb3RlY3RlZCBMaW50UG9saWN5KGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmlhbS52MS5tb2RlbC5MaW50UG9saWN5UmVxdWVzdCBjb250ZW50KSB7CiAgICAgICAgc3VwZXIoSWFtLnRoaXMsICJQT1NUIiwgUkVTVF9QQVRILCBjb250ZW50LCBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5pYW0udjEubW9kZWwuTGludFBvbGljeVJlc3BvbnNlLmNsYXNzKTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBMaW50UG9saWN5IHNldCRYZ2FmdihqYXZhLmxhbmcuU3RyaW5nICRYZ2FmdikgewogICAgICAgIHJldHVybiAoTGludFBvbGljeSkgc3VwZXIuc2V0JFhnYWZ2KCRYZ2Fmdik7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgTGludFBvbGljeSBzZXRBY2Nlc3NUb2tlbihqYXZhLmxhbmcuU3RyaW5nIGFjY2Vzc1Rva2VuKSB7CiAgICAgICAgcmV0dXJuIChMaW50UG9saWN5KSBzdXBlci5zZXRBY2Nlc3NUb2tlbihhY2Nlc3NUb2tlbik7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgTGludFBvbGljeSBzZXRBbHQoamF2YS5sYW5nLlN0cmluZyBhbHQpIHsKICAgICAgICByZXR1cm4gKExpbnRQb2xpY3kpIHN1cGVyLnNldEFsdChhbHQpOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIExpbnRQb2xpY3kgc2V0Q2FsbGJhY2soamF2YS5sYW5nLlN0cmluZyBjYWxsYmFjaykgewogICAgICAgIHJldHVybiAoTGludFBvbGljeSkgc3VwZXIuc2V0Q2FsbGJhY2soY2FsbGJhY2spOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIExpbnRQb2xpY3kgc2V0RmllbGRzKGphdmEubGFuZy5TdHJpbmcgZmllbGRzKSB7CiAgICAgICAgcmV0dXJuIChMaW50UG9saWN5KSBzdXBlci5zZXRGaWVsZHMoZmllbGRzKTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBMaW50UG9saWN5IHNldEtleShqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIHJldHVybiAoTGludFBvbGljeSkgc3VwZXIuc2V0S2V5KGtleSk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgTGludFBvbGljeSBzZXRPYXV0aFRva2VuKGphdmEubGFuZy5TdHJpbmcgb2F1dGhUb2tlbikgewogICAgICAgIHJldHVybiAoTGludFBvbGljeSkgc3VwZXIuc2V0T2F1dGhUb2tlbihvYXV0aFRva2VuKTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBMaW50UG9saWN5IHNldFByZXR0eVByaW50KGphdmEubGFuZy5Cb29sZWFuIHByZXR0eVByaW50KSB7CiAgICAgICAgcmV0dXJuIChMaW50UG9saWN5KSBzdXBlci5zZXRQcmV0dHlQcmludChwcmV0dHlQcmludCk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgTGludFBvbGljeSBzZXRRdW90YVVzZXIoamF2YS5sYW5nLlN0cmluZyBxdW90YVVzZXIpIHsKICAgICAgICByZXR1cm4gKExpbnRQb2xpY3kpIHN1cGVyLnNldFF1b3RhVXNlcihxdW90YVVzZXIpOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIExpbnRQb2xpY3kgc2V0VXBsb2FkVHlwZShqYXZhLmxhbmcuU3RyaW5nIHVwbG9hZFR5cGUpIHsKICAgICAgICByZXR1cm4gKExpbnRQb2xpY3kpIHN1cGVyLnNldFVwbG9hZFR5cGUodXBsb2FkVHlwZSk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgTGludFBvbGljeSBzZXRVcGxvYWRQcm90b2NvbChqYXZhLmxhbmcuU3RyaW5nIHVwbG9hZFByb3RvY29sKSB7CiAgICAgICAgcmV0dXJuIChMaW50UG9saWN5KSBzdXBlci5zZXRVcGxvYWRQcm90b2NvbCh1cGxvYWRQcm90b2NvbCk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgTGludFBvbGljeSBzZXQoU3RyaW5nIHBhcmFtZXRlck5hbWUsIE9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiAoTGludFBvbGljeSkgc3VwZXIuc2V0KHBhcmFtZXRlck5hbWUsIHZhbHVlKTsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiBSZXR1cm5zIGEgbGlzdCBvZiBzZXJ2aWNlcyB0aGF0IHN1cHBvcnQgc2VydmljZSBsZXZlbCBhdWRpdCBsb2dnaW5nIGNvbmZpZ3VyYXRpb24gZm9yIHRoZSBnaXZlbgogICAgICogcmVzb3VyY2UuCiAgICAgKgogICAgICogQ3JlYXRlIGEgcmVxdWVzdCBmb3IgdGhlIG1ldGhvZCAiaWFtUG9saWNpZXMucXVlcnlBdWRpdGFibGVTZXJ2aWNlcyIuCiAgICAgKgogICAgICogVGhpcyByZXF1ZXN0IGhvbGRzIHRoZSBwYXJhbWV0ZXJzIG5lZWRlZCBieSB0aGUgaWFtIHNlcnZlci4gIEFmdGVyIHNldHRpbmcgYW55IG9wdGlvbmFsCiAgICAgKiBwYXJhbWV0ZXJzLCBjYWxsIHRoZSB7QGxpbmsgUXVlcnlBdWRpdGFibGVTZXJ2aWNlcyNleGVjdXRlKCl9IG1ldGhvZCB0byBpbnZva2UgdGhlIHJlbW90ZQogICAgICogb3BlcmF0aW9uLgogICAgICoKICAgICAqIEBwYXJhbSBjb250ZW50IHRoZSB7QGxpbmsgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuaWFtLnYxLm1vZGVsLlF1ZXJ5QXVkaXRhYmxlU2VydmljZXNSZXF1ZXN0fQogICAgICogQHJldHVybiB0aGUgcmVxdWVzdAogICAgICovCiAgICBwdWJsaWMgUXVlcnlBdWRpdGFibGVTZXJ2aWNlcyBxdWVyeUF1ZGl0YWJsZVNlcnZpY2VzKGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmlhbS52MS5tb2RlbC5RdWVyeUF1ZGl0YWJsZVNlcnZpY2VzUmVxdWVzdCBjb250ZW50KSB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIFF1ZXJ5QXVkaXRhYmxlU2VydmljZXMgcmVzdWx0ID0gbmV3IFF1ZXJ5QXVkaXRhYmxlU2VydmljZXMoY29udGVudCk7CiAgICAgIGluaXRpYWxpemUocmVzdWx0KTsKICAgICAgcmV0dXJuIHJlc3VsdDsKICAgIH0KCiAgICBwdWJsaWMgY2xhc3MgUXVlcnlBdWRpdGFibGVTZXJ2aWNlcyBleHRlbmRzIElhbVJlcXVlc3Q8Y29tLmdvb2dsZS5hcGkuc2VydmljZXMuaWFtLnYxLm1vZGVsLlF1ZXJ5QXVkaXRhYmxlU2VydmljZXNSZXNwb25zZT4gewoKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFJFU1RfUEFUSCA9ICJ2MS9pYW1Qb2xpY2llczpxdWVyeUF1ZGl0YWJsZVNlcnZpY2VzIjsKCiAgICAgIC8qKgogICAgICAgKiBSZXR1cm5zIGEgbGlzdCBvZiBzZXJ2aWNlcyB0aGF0IHN1cHBvcnQgc2VydmljZSBsZXZlbCBhdWRpdCBsb2dnaW5nIGNvbmZpZ3VyYXRpb24gZm9yIHRoZSBnaXZlbgogICAgICAgKiByZXNvdXJjZS4KICAgICAgICoKICAgICAgICogQ3JlYXRlIGEgcmVxdWVzdCBmb3IgdGhlIG1ldGhvZCAiaWFtUG9saWNpZXMucXVlcnlBdWRpdGFibGVTZXJ2aWNlcyIuCiAgICAgICAqCiAgICAgICAqIFRoaXMgcmVxdWVzdCBob2xkcyB0aGUgcGFyYW1ldGVycyBuZWVkZWQgYnkgdGhlIHRoZSBpYW0gc2VydmVyLiAgQWZ0ZXIgc2V0dGluZyBhbnkgb3B0aW9uYWwKICAgICAgICogcGFyYW1ldGVycywgY2FsbCB0aGUge0BsaW5rIFF1ZXJ5QXVkaXRhYmxlU2VydmljZXMjZXhlY3V0ZSgpfSBtZXRob2QgdG8gaW52b2tlIHRoZSByZW1vdGUKICAgICAgICogb3BlcmF0aW9uLiA8cD4ge0BsaW5rIFF1ZXJ5QXVkaXRhYmxlU2VydmljZXMjaW5pdGlhbGl6ZShjb20uZ29vZ2xlLmFwaS5jbGllbnQuZ29vZ2xlYXBpcy5zZXJ2aWMKICAgICAgICogZXMuQWJzdHJhY3RHb29nbGVDbGllbnRSZXF1ZXN0KX0gbXVzdCBiZSBjYWxsZWQgdG8gaW5pdGlhbGl6ZSB0aGlzIGluc3RhbmNlIGltbWVkaWF0ZWx5IGFmdGVyCiAgICAgICAqIGludm9raW5nIHRoZSBjb25zdHJ1Y3Rvci4gPC9wPgogICAgICAgKgogICAgICAgKiBAcGFyYW0gY29udGVudCB0aGUge0BsaW5rIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmlhbS52MS5tb2RlbC5RdWVyeUF1ZGl0YWJsZVNlcnZpY2VzUmVxdWVzdH0KICAgICAgICogQHNpbmNlIDEuMTMKICAgICAgICovCiAgICAgIHByb3RlY3RlZCBRdWVyeUF1ZGl0YWJsZVNlcnZpY2VzKGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmlhbS52MS5tb2RlbC5RdWVyeUF1ZGl0YWJsZVNlcnZpY2VzUmVxdWVzdCBjb250ZW50KSB7CiAgICAgICAgc3VwZXIoSWFtLnRoaXMsICJQT1NUIiwgUkVTVF9QQVRILCBjb250ZW50LCBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5pYW0udjEubW9kZWwuUXVlcnlBdWRpdGFibGVTZXJ2aWNlc1Jlc3BvbnNlLmNsYXNzKTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBRdWVyeUF1ZGl0YWJsZVNlcnZpY2VzIHNldCRYZ2FmdihqYXZhLmxhbmcuU3RyaW5nICRYZ2FmdikgewogICAgICAgIHJldHVybiAoUXVlcnlBdWRpdGFibGVTZXJ2aWNlcykgc3VwZXIuc2V0JFhnYWZ2KCRYZ2Fmdik7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgUXVlcnlBdWRpdGFibGVTZXJ2aWNlcyBzZXRBY2Nlc3NUb2tlbihqYXZhLmxhbmcuU3RyaW5nIGFjY2Vzc1Rva2VuKSB7CiAgICAgICAgcmV0dXJuIChRdWVyeUF1ZGl0YWJsZVNlcnZpY2VzKSBzdXBlci5zZXRBY2Nlc3NUb2tlbihhY2Nlc3NUb2tlbik7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgUXVlcnlBdWRpdGFibGVTZXJ2aWNlcyBzZXRBbHQoamF2YS5sYW5nLlN0cmluZyBhbHQpIHsKICAgICAgICByZXR1cm4gKFF1ZXJ5QXVkaXRhYmxlU2VydmljZXMpIHN1cGVyLnNldEFsdChhbHQpOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIFF1ZXJ5QXVkaXRhYmxlU2VydmljZXMgc2V0Q2FsbGJhY2soamF2YS5sYW5nLlN0cmluZyBjYWxsYmFjaykgewogICAgICAgIHJldHVybiAoUXVlcnlBdWRpdGFibGVTZXJ2aWNlcykgc3VwZXIuc2V0Q2FsbGJhY2soY2FsbGJhY2spOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIFF1ZXJ5QXVkaXRhYmxlU2VydmljZXMgc2V0RmllbGRzKGphdmEubGFuZy5TdHJpbmcgZmllbGRzKSB7CiAgICAgICAgcmV0dXJuIChRdWVyeUF1ZGl0YWJsZVNlcnZpY2VzKSBzdXBlci5zZXRGaWVsZHMoZmllbGRzKTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBRdWVyeUF1ZGl0YWJsZVNlcnZpY2VzIHNldEtleShqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIHJldHVybiAoUXVlcnlBdWRpdGFibGVTZXJ2aWNlcykgc3VwZXIuc2V0S2V5KGtleSk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgUXVlcnlBdWRpdGFibGVTZXJ2aWNlcyBzZXRPYXV0aFRva2VuKGphdmEubGFuZy5TdHJpbmcgb2F1dGhUb2tlbikgewogICAgICAgIHJldHVybiAoUXVlcnlBdWRpdGFibGVTZXJ2aWNlcykgc3VwZXIuc2V0T2F1dGhUb2tlbihvYXV0aFRva2VuKTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBRdWVyeUF1ZGl0YWJsZVNlcnZpY2VzIHNldFByZXR0eVByaW50KGphdmEubGFuZy5Cb29sZWFuIHByZXR0eVByaW50KSB7CiAgICAgICAgcmV0dXJuIChRdWVyeUF1ZGl0YWJsZVNlcnZpY2VzKSBzdXBlci5zZXRQcmV0dHlQcmludChwcmV0dHlQcmludCk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgUXVlcnlBdWRpdGFibGVTZXJ2aWNlcyBzZXRRdW90YVVzZXIoamF2YS5sYW5nLlN0cmluZyBxdW90YVVzZXIpIHsKICAgICAgICByZXR1cm4gKFF1ZXJ5QXVkaXRhYmxlU2VydmljZXMpIHN1cGVyLnNldFF1b3RhVXNlcihxdW90YVVzZXIpOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIFF1ZXJ5QXVkaXRhYmxlU2VydmljZXMgc2V0VXBsb2FkVHlwZShqYXZhLmxhbmcuU3RyaW5nIHVwbG9hZFR5cGUpIHsKICAgICAgICByZXR1cm4gKFF1ZXJ5QXVkaXRhYmxlU2VydmljZXMpIHN1cGVyLnNldFVwbG9hZFR5cGUodXBsb2FkVHlwZSk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgUXVlcnlBdWRpdGFibGVTZXJ2aWNlcyBzZXRVcGxvYWRQcm90b2NvbChqYXZhLmxhbmcuU3RyaW5nIHVwbG9hZFByb3RvY29sKSB7CiAgICAgICAgcmV0dXJuIChRdWVyeUF1ZGl0YWJsZVNlcnZpY2VzKSBzdXBlci5zZXRVcGxvYWRQcm90b2NvbCh1cGxvYWRQcm90b2NvbCk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgUXVlcnlBdWRpdGFibGVTZXJ2aWNlcyBzZXQoU3RyaW5nIHBhcmFtZXRlck5hbWUsIE9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiAoUXVlcnlBdWRpdGFibGVTZXJ2aWNlcykgc3VwZXIuc2V0KHBhcmFtZXRlck5hbWUsIHZhbHVlKTsKICAgICAgfQogICAgfQoKICB9CgogIC8qKgogICAqIEFuIGFjY2Vzc29yIGZvciBjcmVhdGluZyByZXF1ZXN0cyBmcm9tIHRoZSBPcmdhbml6YXRpb25zIGNvbGxlY3Rpb24uCiAgICoKICAgKiA8cD5UaGUgdHlwaWNhbCB1c2UgaXM6PC9wPgogICAqIDxwcmU+CiAgICogICB7QGNvZGUgSWFtIGlhbSA9IG5ldyBJYW0oLi4uKTt9CiAgICogICB7QGNvZGUgSWFtLk9yZ2FuaXphdGlvbnMuTGlzdCByZXF1ZXN0ID0gaWFtLm9yZ2FuaXphdGlvbnMoKS5saXN0KHBhcmFtZXRlcnMgLi4uKX0KICAgKiA8L3ByZT4KICAgKgogICAqIEByZXR1cm4gdGhlIHJlc291cmNlIGNvbGxlY3Rpb24KICAgKi8KICBwdWJsaWMgT3JnYW5pemF0aW9ucyBvcmdhbml6YXRpb25zKCkgewogICAgcmV0dXJuIG5ldyBPcmdhbml6YXRpb25zKCk7CiAgfQoKICAvKioKICAgKiBUaGUgIm9yZ2FuaXphdGlvbnMiIGNvbGxlY3Rpb24gb2YgbWV0aG9kcy4KICAgKi8KICBwdWJsaWMgY2xhc3MgT3JnYW5pemF0aW9ucyB7CgogICAgLyoqCiAgICAgKiBBbiBhY2Nlc3NvciBmb3IgY3JlYXRpbmcgcmVxdWVzdHMgZnJvbSB0aGUgUm9sZXMgY29sbGVjdGlvbi4KICAgICAqCiAgICAgKiA8cD5UaGUgdHlwaWNhbCB1c2UgaXM6PC9wPgogICAgICogPHByZT4KICAgICAqICAge0Bjb2RlIElhbSBpYW0gPSBuZXcgSWFtKC4uLik7fQogICAgICogICB7QGNvZGUgSWFtLlJvbGVzLkxpc3QgcmVxdWVzdCA9IGlhbS5yb2xlcygpLmxpc3QocGFyYW1ldGVycyAuLi4pfQogICAgICogPC9wcmU+CiAgICAgKgogICAgICogQHJldHVybiB0aGUgcmVzb3VyY2UgY29sbGVjdGlvbgogICAgICovCiAgICBwdWJsaWMgUm9sZXMgcm9sZXMoKSB7CiAgICAgIHJldHVybiBuZXcgUm9sZXMoKTsKICAgIH0KCiAgICAvKioKICAgICAqIFRoZSAicm9sZXMiIGNvbGxlY3Rpb24gb2YgbWV0aG9kcy4KICAgICAqLwogICAgcHVibGljIGNsYXNzIFJvbGVzIHsKCiAgICAgIC8qKgogICAgICAgKiBDcmVhdGVzIGEgbmV3IFJvbGUuCiAgICAgICAqCiAgICAgICAqIENyZWF0ZSBhIHJlcXVlc3QgZm9yIHRoZSBtZXRob2QgInJvbGVzLmNyZWF0ZSIuCiAgICAgICAqCiAgICAgICAqIFRoaXMgcmVxdWVzdCBob2xkcyB0aGUgcGFyYW1ldGVycyBuZWVkZWQgYnkgdGhlIGlhbSBzZXJ2ZXIuICBBZnRlciBzZXR0aW5nIGFueSBvcHRpb25hbAogICAgICAgKiBwYXJhbWV0ZXJzLCBjYWxsIHRoZSB7QGxpbmsgQ3JlYXRlI2V4ZWN1dGUoKX0gbWV0aG9kIHRvIGludm9rZSB0aGUgcmVtb3RlIG9wZXJhdGlvbi4KICAgICAgICoKICAgICAgICogQHBhcmFtIHBhcmVudCBUaGUgYHBhcmVudGAgcGFyYW1ldGVyJ3MgdmFsdWUgZGVwZW5kcyBvbiB0aGUgdGFyZ2V0IHJlc291cmNlIGZvciB0aGUKICAgICAgcmVxdWVzdCwgbmFtZWx5CiAgICAgICAqICAgICAgICBbYHByb2plY3RzYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9wcm9qZWN0cy5yb2xlcykgb3IKICAgICAgICogICAgICAgIFtgb3JnYW5pemF0aW9uc2BdKC9pYW0vcmVmZXJlbmNlL3Jlc3QvdjEvb3JnYW5pemF0aW9ucy5yb2xlcykuIEVhY2gKICAgICAgcmVzb3VyY2UgdHlwZSdzCiAgICAgICAqICAgICAgICBgcGFyZW50YCB2YWx1ZSBmb3JtYXQgaXMgZGVzY3JpYmVkIGJlbG93OgogICAgICAqCiAgICAgICAqICAgICAgICBbYHByb2plY3RzLnJvbGVzLmNyZWF0ZSgpYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9wcm9qZWN0cy5yb2xlcy9jcmVhdGUpOgogICAgICAgKiAgICAgICAgYHByb2plY3RzL3tQUk9KRUNUX0lEfWAuIFRoaXMgbWV0aG9kIGNyZWF0ZXMgcHJvamVjdC1sZXZlbAogICAgICAgIFtjdXN0b20gcm9sZXNdKC9pYW0vZG9jcwogICAgICAgKiAgICAgICAgL3VuZGVyc3RhbmRpbmctY3VzdG9tLXJvbGVzKS4KICAgICAgICBFeGFtcGxlIHJlcXVlc3QgVVJMOgogICAgICAgKiAgICAgICAgYGh0dHBzOi8vaWFtLmdvb2dsZWFwaXMuY29tL3YxL3Byb2plY3RzL3tQUk9KRUNUX0lEfS9yb2xlc2AKICAgICAgKgogICAgICAgKiAgICAgICAgW2Bvcmdhbml6YXRpb25zLnJvbGVzLmNyZWF0ZSgpYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9vcmdhbml6YXRpb25zLnJvbGVzL2NyZWF0ZSk6CiAgICAgICAqICAgICAgICBgb3JnYW5pemF0aW9ucy97T1JHQU5JWkFUSU9OX0lEfWAuIFRoaXMgbWV0aG9kIGNyZWF0ZXMgb3JnYW5pemF0aW9uLWxldmVsCiAgICAgICAgW2N1c3RvbQogICAgICAgKiAgICAgICAgcm9sZXNdKC9pYW0vZG9jcy91bmRlcnN0YW5kaW5nLWN1c3RvbS1yb2xlcykuIEV4YW1wbGUgcmVxdWVzdAogICAgICAgIFVSTDoKICAgICAgICogICAgICAgIGBodHRwczovL2lhbS5nb29nbGVhcGlzLmNvbS92MS9vcmdhbml6YXRpb25zL3tPUkdBTklaQVRJT05fSUR9L3JvbGVzYAogICAgICBOb3RlOiBXaWxkY2FyZCAoKikKICAgICAgICogICAgICAgIHZhbHVlcyBhcmUgaW52YWxpZDsgeW91IG11c3Qgc3BlY2lmeSBhIGNvbXBsZXRlIHByb2plY3QKICAgICAgSUQgb3Igb3JnYW5pemF0aW9uIElELgogICAgICAgKiBAcGFyYW0gY29udGVudCB0aGUge0BsaW5rIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmlhbS52MS5tb2RlbC5DcmVhdGVSb2xlUmVxdWVzdH0KICAgICAgICogQHJldHVybiB0aGUgcmVxdWVzdAogICAgICAgKi8KICAgICAgcHVibGljIENyZWF0ZSBjcmVhdGUoamF2YS5sYW5nLlN0cmluZyBwYXJlbnQsIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmlhbS52MS5tb2RlbC5DcmVhdGVSb2xlUmVxdWVzdCBjb250ZW50KSB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgQ3JlYXRlIHJlc3VsdCA9IG5ldyBDcmVhdGUocGFyZW50LCBjb250ZW50KTsKICAgICAgICBpbml0aWFsaXplKHJlc3VsdCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHVibGljIGNsYXNzIENyZWF0ZSBleHRlbmRzIElhbVJlcXVlc3Q8Y29tLmdvb2dsZS5hcGkuc2VydmljZXMuaWFtLnYxLm1vZGVsLlJvbGU+IHsKCiAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFJFU1RfUEFUSCA9ICJ2MS97K3BhcmVudH0vcm9sZXMiOwoKICAgICAgICBwcml2YXRlIGZpbmFsIGphdmEudXRpbC5yZWdleC5QYXR0ZXJuIFBBUkVOVF9QQVRURVJOID0KICAgICAgICAgICAgamF2YS51dGlsLnJlZ2V4LlBhdHRlcm4uY29tcGlsZSgiXm9yZ2FuaXphdGlvbnMvW14vXSskIik7CgogICAgICAgIC8qKgogICAgICAgICAqIENyZWF0ZXMgYSBuZXcgUm9sZS4KICAgICAgICAgKgogICAgICAgICAqIENyZWF0ZSBhIHJlcXVlc3QgZm9yIHRoZSBtZXRob2QgInJvbGVzLmNyZWF0ZSIuCiAgICAgICAgICoKICAgICAgICAgKiBUaGlzIHJlcXVlc3QgaG9sZHMgdGhlIHBhcmFtZXRlcnMgbmVlZGVkIGJ5IHRoZSB0aGUgaWFtIHNlcnZlci4gIEFmdGVyIHNldHRpbmcgYW55IG9wdGlvbmFsCiAgICAgICAgICogcGFyYW1ldGVycywgY2FsbCB0aGUge0BsaW5rIENyZWF0ZSNleGVjdXRlKCl9IG1ldGhvZCB0byBpbnZva2UgdGhlIHJlbW90ZSBvcGVyYXRpb24uIDxwPiB7QGxpbmsKICAgICAgICAgKiBDcmVhdGUjaW5pdGlhbGl6ZShjb20uZ29vZ2xlLmFwaS5jbGllbnQuZ29vZ2xlYXBpcy5zZXJ2aWNlcy5BYnN0cmFjdEdvb2dsZUNsaWVudFJlcXVlc3QpfSBtdXN0CiAgICAgICAgICogYmUgY2FsbGVkIHRvIGluaXRpYWxpemUgdGhpcyBpbnN0YW5jZSBpbW1lZGlhdGVseSBhZnRlciBpbnZva2luZyB0aGUgY29uc3RydWN0b3IuIDwvcD4KICAgICAgICAgKgogICAgICAgICAqIEBwYXJhbSBwYXJlbnQgVGhlIGBwYXJlbnRgIHBhcmFtZXRlcidzIHZhbHVlIGRlcGVuZHMgb24gdGhlIHRhcmdldCByZXNvdXJjZSBmb3IgdGhlCiAgICAgIHJlcXVlc3QsIG5hbWVseQogICAgICAgKiAgICAgICAgW2Bwcm9qZWN0c2BdKC9pYW0vcmVmZXJlbmNlL3Jlc3QvdjEvcHJvamVjdHMucm9sZXMpIG9yCiAgICAgICAqICAgICAgICBbYG9yZ2FuaXphdGlvbnNgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL29yZ2FuaXphdGlvbnMucm9sZXMpLiBFYWNoCiAgICAgIHJlc291cmNlIHR5cGUncwogICAgICAgKiAgICAgICAgYHBhcmVudGAgdmFsdWUgZm9ybWF0IGlzIGRlc2NyaWJlZCBiZWxvdzoKICAgICAgKgogICAgICAgKiAgICAgICAgW2Bwcm9qZWN0cy5yb2xlcy5jcmVhdGUoKWBdKC9pYW0vcmVmZXJlbmNlL3Jlc3QvdjEvcHJvamVjdHMucm9sZXMvY3JlYXRlKToKICAgICAgICogICAgICAgIGBwcm9qZWN0cy97UFJPSkVDVF9JRH1gLiBUaGlzIG1ldGhvZCBjcmVhdGVzIHByb2plY3QtbGV2ZWwKICAgICAgICBbY3VzdG9tIHJvbGVzXSgvaWFtL2RvY3MKICAgICAgICogICAgICAgIC91bmRlcnN0YW5kaW5nLWN1c3RvbS1yb2xlcykuCiAgICAgICAgRXhhbXBsZSByZXF1ZXN0IFVSTDoKICAgICAgICogICAgICAgIGBodHRwczovL2lhbS5nb29nbGVhcGlzLmNvbS92MS9wcm9qZWN0cy97UFJPSkVDVF9JRH0vcm9sZXNgCiAgICAgICoKICAgICAgICogICAgICAgIFtgb3JnYW5pemF0aW9ucy5yb2xlcy5jcmVhdGUoKWBdKC9pYW0vcmVmZXJlbmNlL3Jlc3QvdjEvb3JnYW5pemF0aW9ucy5yb2xlcy9jcmVhdGUpOgogICAgICAgKiAgICAgICAgYG9yZ2FuaXphdGlvbnMve09SR0FOSVpBVElPTl9JRH1gLiBUaGlzIG1ldGhvZCBjcmVhdGVzIG9yZ2FuaXphdGlvbi1sZXZlbAogICAgICAgIFtjdXN0b20KICAgICAgICogICAgICAgIHJvbGVzXSgvaWFtL2RvY3MvdW5kZXJzdGFuZGluZy1jdXN0b20tcm9sZXMpLiBFeGFtcGxlIHJlcXVlc3QKICAgICAgICBVUkw6CiAgICAgICAqICAgICAgICBgaHR0cHM6Ly9pYW0uZ29vZ2xlYXBpcy5jb20vdjEvb3JnYW5pemF0aW9ucy97T1JHQU5JWkFUSU9OX0lEfS9yb2xlc2AKICAgICAgTm90ZTogV2lsZGNhcmQgKCopCiAgICAgICAqICAgICAgICB2YWx1ZXMgYXJlIGludmFsaWQ7IHlvdSBtdXN0IHNwZWNpZnkgYSBjb21wbGV0ZSBwcm9qZWN0CiAgICAgIElEIG9yIG9yZ2FuaXphdGlvbiBJRC4KICAgICAgICAgKiBAcGFyYW0gY29udGVudCB0aGUge0BsaW5rIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmlhbS52MS5tb2RlbC5DcmVhdGVSb2xlUmVxdWVzdH0KICAgICAgICAgKiBAc2luY2UgMS4xMwogICAgICAgICAqLwogICAgICAgIHByb3RlY3RlZCBDcmVhdGUoamF2YS5sYW5nLlN0cmluZyBwYXJlbnQsIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmlhbS52MS5tb2RlbC5DcmVhdGVSb2xlUmVxdWVzdCBjb250ZW50KSB7CiAgICAgICAgICBzdXBlcihJYW0udGhpcywgIlBPU1QiLCBSRVNUX1BBVEgsIGNvbnRlbnQsIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmlhbS52MS5tb2RlbC5Sb2xlLmNsYXNzKTsKICAgICAgICAgIHRoaXMucGFyZW50ID0gY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuUHJlY29uZGl0aW9ucy5jaGVja05vdE51bGwocGFyZW50LCAiUmVxdWlyZWQgcGFyYW1ldGVyIHBhcmVudCBtdXN0IGJlIHNwZWNpZmllZC4iKTsKICAgICAgICAgIGlmICghZ2V0U3VwcHJlc3NQYXR0ZXJuQ2hlY2tzKCkpIHsKICAgICAgICAgICAgY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuUHJlY29uZGl0aW9ucy5jaGVja0FyZ3VtZW50KFBBUkVOVF9QQVRURVJOLm1hdGNoZXIocGFyZW50KS5tYXRjaGVzKCksCiAgICAgICAgICAgICAgICAiUGFyYW1ldGVyIHBhcmVudCBtdXN0IGNvbmZvcm0gdG8gdGhlIHBhdHRlcm4gIiArCiAgICAgICAgICAgICAgICAiXm9yZ2FuaXphdGlvbnMvW14vXSskIik7CiAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQ3JlYXRlIHNldCRYZ2FmdihqYXZhLmxhbmcuU3RyaW5nICRYZ2FmdikgewogICAgICAgICAgcmV0dXJuIChDcmVhdGUpIHN1cGVyLnNldCRYZ2FmdigkWGdhZnYpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIENyZWF0ZSBzZXRBY2Nlc3NUb2tlbihqYXZhLmxhbmcuU3RyaW5nIGFjY2Vzc1Rva2VuKSB7CiAgICAgICAgICByZXR1cm4gKENyZWF0ZSkgc3VwZXIuc2V0QWNjZXNzVG9rZW4oYWNjZXNzVG9rZW4pOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIENyZWF0ZSBzZXRBbHQoamF2YS5sYW5nLlN0cmluZyBhbHQpIHsKICAgICAgICAgIHJldHVybiAoQ3JlYXRlKSBzdXBlci5zZXRBbHQoYWx0KTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBDcmVhdGUgc2V0Q2FsbGJhY2soamF2YS5sYW5nLlN0cmluZyBjYWxsYmFjaykgewogICAgICAgICAgcmV0dXJuIChDcmVhdGUpIHN1cGVyLnNldENhbGxiYWNrKGNhbGxiYWNrKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBDcmVhdGUgc2V0RmllbGRzKGphdmEubGFuZy5TdHJpbmcgZmllbGRzKSB7CiAgICAgICAgICByZXR1cm4gKENyZWF0ZSkgc3VwZXIuc2V0RmllbGRzKGZpZWxkcyk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQ3JlYXRlIHNldEtleShqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgICAgcmV0dXJuIChDcmVhdGUpIHN1cGVyLnNldEtleShrZXkpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIENyZWF0ZSBzZXRPYXV0aFRva2VuKGphdmEubGFuZy5TdHJpbmcgb2F1dGhUb2tlbikgewogICAgICAgICAgcmV0dXJuIChDcmVhdGUpIHN1cGVyLnNldE9hdXRoVG9rZW4ob2F1dGhUb2tlbik7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQ3JlYXRlIHNldFByZXR0eVByaW50KGphdmEubGFuZy5Cb29sZWFuIHByZXR0eVByaW50KSB7CiAgICAgICAgICByZXR1cm4gKENyZWF0ZSkgc3VwZXIuc2V0UHJldHR5UHJpbnQocHJldHR5UHJpbnQpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIENyZWF0ZSBzZXRRdW90YVVzZXIoamF2YS5sYW5nLlN0cmluZyBxdW90YVVzZXIpIHsKICAgICAgICAgIHJldHVybiAoQ3JlYXRlKSBzdXBlci5zZXRRdW90YVVzZXIocXVvdGFVc2VyKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBDcmVhdGUgc2V0VXBsb2FkVHlwZShqYXZhLmxhbmcuU3RyaW5nIHVwbG9hZFR5cGUpIHsKICAgICAgICAgIHJldHVybiAoQ3JlYXRlKSBzdXBlci5zZXRVcGxvYWRUeXBlKHVwbG9hZFR5cGUpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIENyZWF0ZSBzZXRVcGxvYWRQcm90b2NvbChqYXZhLmxhbmcuU3RyaW5nIHVwbG9hZFByb3RvY29sKSB7CiAgICAgICAgICByZXR1cm4gKENyZWF0ZSkgc3VwZXIuc2V0VXBsb2FkUHJvdG9jb2wodXBsb2FkUHJvdG9jb2wpOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogVGhlIGBwYXJlbnRgIHBhcmFtZXRlcidzIHZhbHVlIGRlcGVuZHMgb24gdGhlIHRhcmdldCByZXNvdXJjZSBmb3IgdGhlIHJlcXVlc3QsIG5hbWVseQogICAgICAgICAqIFtgcHJvamVjdHNgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL3Byb2plY3RzLnJvbGVzKSBvcgogICAgICAgICAqIFtgb3JnYW5pemF0aW9uc2BdKC9pYW0vcmVmZXJlbmNlL3Jlc3QvdjEvb3JnYW5pemF0aW9ucy5yb2xlcykuIEVhY2ggcmVzb3VyY2UgdHlwZSdzCiAgICAgICAgICogYHBhcmVudGAgdmFsdWUgZm9ybWF0IGlzIGRlc2NyaWJlZCBiZWxvdzoKICAgICAgICAgKgogICAgICAgICAqICogW2Bwcm9qZWN0cy5yb2xlcy5jcmVhdGUoKWBdKC9pYW0vcmVmZXJlbmNlL3Jlc3QvdjEvcHJvamVjdHMucm9sZXMvY3JlYXRlKToKICAgICAgICAgKiBgcHJvamVjdHMve1BST0pFQ1RfSUR9YC4gVGhpcyBtZXRob2QgY3JlYXRlcyBwcm9qZWN0LWxldmVsIFtjdXN0b20gcm9sZXNdKC9pYW0vZG9jcwogICAgICAgICAqIC91bmRlcnN0YW5kaW5nLWN1c3RvbS1yb2xlcykuIEV4YW1wbGUgcmVxdWVzdCBVUkw6CiAgICAgICAgICogYGh0dHBzOi8vaWFtLmdvb2dsZWFwaXMuY29tL3YxL3Byb2plY3RzL3tQUk9KRUNUX0lEfS9yb2xlc2AKICAgICAgICAgKgogICAgICAgICAqICogW2Bvcmdhbml6YXRpb25zLnJvbGVzLmNyZWF0ZSgpYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9vcmdhbml6YXRpb25zLnJvbGVzL2NyZWF0ZSk6CiAgICAgICAgICogYG9yZ2FuaXphdGlvbnMve09SR0FOSVpBVElPTl9JRH1gLiBUaGlzIG1ldGhvZCBjcmVhdGVzIG9yZ2FuaXphdGlvbi1sZXZlbCBbY3VzdG9tCiAgICAgICAgICogcm9sZXNdKC9pYW0vZG9jcy91bmRlcnN0YW5kaW5nLWN1c3RvbS1yb2xlcykuIEV4YW1wbGUgcmVxdWVzdCBVUkw6CiAgICAgICAgICogYGh0dHBzOi8vaWFtLmdvb2dsZWFwaXMuY29tL3YxL29yZ2FuaXphdGlvbnMve09SR0FOSVpBVElPTl9JRH0vcm9sZXNgCiAgICAgICAgICoKICAgICAgICAgKiBOb3RlOiBXaWxkY2FyZCAoKikgdmFsdWVzIGFyZSBpbnZhbGlkOyB5b3UgbXVzdCBzcGVjaWZ5IGEgY29tcGxldGUgcHJvamVjdCBJRCBvcgogICAgICAgICAqIG9yZ2FuaXphdGlvbiBJRC4KICAgICAgICAgKi8KICAgICAgICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuU3RyaW5nIHBhcmVudDsKCiAgICAgICAgLyoqIFRoZSBgcGFyZW50YCBwYXJhbWV0ZXIncyB2YWx1ZSBkZXBlbmRzIG9uIHRoZSB0YXJnZXQgcmVzb3VyY2UgZm9yIHRoZSByZXF1ZXN0LCBuYW1lbHkKICAgICAgIFtgcHJvamVjdHNgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL3Byb2plY3RzLnJvbGVzKSBvcgogICAgICAgW2Bvcmdhbml6YXRpb25zYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9vcmdhbml6YXRpb25zLnJvbGVzKS4gRWFjaCByZXNvdXJjZSB0eXBlJ3MgYHBhcmVudGAgdmFsdWUKICAgICAgIGZvcm1hdCBpcyBkZXNjcmliZWQgYmVsb3c6CgogICAgICAgKiBbYHByb2plY3RzLnJvbGVzLmNyZWF0ZSgpYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9wcm9qZWN0cy5yb2xlcy9jcmVhdGUpOgogICAgICAgYHByb2plY3RzL3tQUk9KRUNUX0lEfWAuIFRoaXMgbWV0aG9kIGNyZWF0ZXMgcHJvamVjdC1sZXZlbCBbY3VzdG9tIHJvbGVzXSgvaWFtL2RvY3MvdW5kZXJzdGFuZGluZy0KICAgICAgIGN1c3RvbS1yb2xlcykuIEV4YW1wbGUgcmVxdWVzdCBVUkw6IGBodHRwczovL2lhbS5nb29nbGVhcGlzLmNvbS92MS9wcm9qZWN0cy97UFJPSkVDVF9JRH0vcm9sZXNgCgogICAgICAgKiBbYG9yZ2FuaXphdGlvbnMucm9sZXMuY3JlYXRlKClgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL29yZ2FuaXphdGlvbnMucm9sZXMvY3JlYXRlKToKICAgICAgIGBvcmdhbml6YXRpb25zL3tPUkdBTklaQVRJT05fSUR9YC4gVGhpcyBtZXRob2QgY3JlYXRlcyBvcmdhbml6YXRpb24tbGV2ZWwgW2N1c3RvbSByb2xlc10oL2lhbS9kb2NzCiAgICAgICAvdW5kZXJzdGFuZGluZy1jdXN0b20tcm9sZXMpLiBFeGFtcGxlIHJlcXVlc3QgVVJMOgogICAgICAgYGh0dHBzOi8vaWFtLmdvb2dsZWFwaXMuY29tL3YxL29yZ2FuaXphdGlvbnMve09SR0FOSVpBVElPTl9JRH0vcm9sZXNgCgogICAgICAgTm90ZTogV2lsZGNhcmQgKCopIHZhbHVlcyBhcmUgaW52YWxpZDsgeW91IG11c3Qgc3BlY2lmeSBhIGNvbXBsZXRlIHByb2plY3QgSUQgb3Igb3JnYW5pemF0aW9uIElELgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFBhcmVudCgpIHsKICAgICAgICAgIHJldHVybiBwYXJlbnQ7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiBUaGUgYHBhcmVudGAgcGFyYW1ldGVyJ3MgdmFsdWUgZGVwZW5kcyBvbiB0aGUgdGFyZ2V0IHJlc291cmNlIGZvciB0aGUgcmVxdWVzdCwgbmFtZWx5CiAgICAgICAgICogW2Bwcm9qZWN0c2BdKC9pYW0vcmVmZXJlbmNlL3Jlc3QvdjEvcHJvamVjdHMucm9sZXMpIG9yCiAgICAgICAgICogW2Bvcmdhbml6YXRpb25zYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9vcmdhbml6YXRpb25zLnJvbGVzKS4gRWFjaCByZXNvdXJjZSB0eXBlJ3MKICAgICAgICAgKiBgcGFyZW50YCB2YWx1ZSBmb3JtYXQgaXMgZGVzY3JpYmVkIGJlbG93OgogICAgICAgICAqCiAgICAgICAgICogKiBbYHByb2plY3RzLnJvbGVzLmNyZWF0ZSgpYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9wcm9qZWN0cy5yb2xlcy9jcmVhdGUpOgogICAgICAgICAqIGBwcm9qZWN0cy97UFJPSkVDVF9JRH1gLiBUaGlzIG1ldGhvZCBjcmVhdGVzIHByb2plY3QtbGV2ZWwgW2N1c3RvbSByb2xlc10oL2lhbS9kb2NzCiAgICAgICAgICogL3VuZGVyc3RhbmRpbmctY3VzdG9tLXJvbGVzKS4gRXhhbXBsZSByZXF1ZXN0IFVSTDoKICAgICAgICAgKiBgaHR0cHM6Ly9pYW0uZ29vZ2xlYXBpcy5jb20vdjEvcHJvamVjdHMve1BST0pFQ1RfSUR9L3JvbGVzYAogICAgICAgICAqCiAgICAgICAgICogKiBbYG9yZ2FuaXphdGlvbnMucm9sZXMuY3JlYXRlKClgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL29yZ2FuaXphdGlvbnMucm9sZXMvY3JlYXRlKToKICAgICAgICAgKiBgb3JnYW5pemF0aW9ucy97T1JHQU5JWkFUSU9OX0lEfWAuIFRoaXMgbWV0aG9kIGNyZWF0ZXMgb3JnYW5pemF0aW9uLWxldmVsIFtjdXN0b20KICAgICAgICAgKiByb2xlc10oL2lhbS9kb2NzL3VuZGVyc3RhbmRpbmctY3VzdG9tLXJvbGVzKS4gRXhhbXBsZSByZXF1ZXN0IFVSTDoKICAgICAgICAgKiBgaHR0cHM6Ly9pYW0uZ29vZ2xlYXBpcy5jb20vdjEvb3JnYW5pemF0aW9ucy97T1JHQU5JWkFUSU9OX0lEfS9yb2xlc2AKICAgICAgICAgKgogICAgICAgICAqIE5vdGU6IFdpbGRjYXJkICgqKSB2YWx1ZXMgYXJlIGludmFsaWQ7IHlvdSBtdXN0IHNwZWNpZnkgYSBjb21wbGV0ZSBwcm9qZWN0IElEIG9yCiAgICAgICAgICogb3JnYW5pemF0aW9uIElELgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBDcmVhdGUgc2V0UGFyZW50KGphdmEubGFuZy5TdHJpbmcgcGFyZW50KSB7CiAgICAgICAgICBpZiAoIWdldFN1cHByZXNzUGF0dGVybkNoZWNrcygpKSB7CiAgICAgICAgICAgIGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLlByZWNvbmRpdGlvbnMuY2hlY2tBcmd1bWVudChQQVJFTlRfUEFUVEVSTi5tYXRjaGVyKHBhcmVudCkubWF0Y2hlcygpLAogICAgICAgICAgICAgICAgIlBhcmFtZXRlciBwYXJlbnQgbXVzdCBjb25mb3JtIHRvIHRoZSBwYXR0ZXJuICIgKwogICAgICAgICAgICAgICAgIl5vcmdhbml6YXRpb25zL1teL10rJCIpOwogICAgICAgICAgfQogICAgICAgICAgdGhpcy5wYXJlbnQgPSBwYXJlbnQ7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBDcmVhdGUgc2V0KFN0cmluZyBwYXJhbWV0ZXJOYW1lLCBPYmplY3QgdmFsdWUpIHsKICAgICAgICAgIHJldHVybiAoQ3JlYXRlKSBzdXBlci5zZXQocGFyYW1ldGVyTmFtZSwgdmFsdWUpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogU29mdCBkZWxldGVzIGEgcm9sZS4gVGhlIHJvbGUgaXMgc3VzcGVuZGVkIGFuZCBjYW5ub3QgYmUgdXNlZCB0byBjcmVhdGUgbmV3IElBTSBQb2xpY3kgQmluZGluZ3MuCiAgICAgICAqIFRoZSBSb2xlIHdpbGwgbm90IGJlIGluY2x1ZGVkIGluIGBMaXN0Um9sZXMoKWAgdW5sZXNzIGBzaG93X2RlbGV0ZWRgIGlzIHNldCBpbiB0aGUKICAgICAgICogYExpc3RSb2xlc1JlcXVlc3RgLiBUaGUgUm9sZSBjb250YWlucyB0aGUgZGVsZXRlZCBib29sZWFuIHNldC4gRXhpc3RpbmcgQmluZGluZ3MgcmVtYWlucywgYnV0IGFyZQogICAgICAgKiBpbmFjdGl2ZS4gVGhlIFJvbGUgY2FuIGJlIHVuZGVsZXRlZCB3aXRoaW4gNyBkYXlzLiBBZnRlciA3IGRheXMgdGhlIFJvbGUgaXMgZGVsZXRlZCBhbmQgYWxsCiAgICAgICAqIEJpbmRpbmdzIGFzc29jaWF0ZWQgd2l0aCB0aGUgcm9sZSBhcmUgcmVtb3ZlZC4KICAgICAgICoKICAgICAgICogQ3JlYXRlIGEgcmVxdWVzdCBmb3IgdGhlIG1ldGhvZCAicm9sZXMuZGVsZXRlIi4KICAgICAgICoKICAgICAgICogVGhpcyByZXF1ZXN0IGhvbGRzIHRoZSBwYXJhbWV0ZXJzIG5lZWRlZCBieSB0aGUgaWFtIHNlcnZlci4gIEFmdGVyIHNldHRpbmcgYW55IG9wdGlvbmFsCiAgICAgICAqIHBhcmFtZXRlcnMsIGNhbGwgdGhlIHtAbGluayBEZWxldGUjZXhlY3V0ZSgpfSBtZXRob2QgdG8gaW52b2tlIHRoZSByZW1vdGUgb3BlcmF0aW9uLgogICAgICAgKgogICAgICAgKiBAcGFyYW0gbmFtZSBUaGUgYG5hbWVgIHBhcmFtZXRlcidzIHZhbHVlIGRlcGVuZHMgb24gdGhlIHRhcmdldCByZXNvdXJjZSBmb3IgdGhlCiAgICAgIHJlcXVlc3QsIG5hbWVseQogICAgICAgKiAgICAgICAgW2Bwcm9qZWN0c2BdKC9pYW0vcmVmZXJlbmNlL3Jlc3QvdjEvcHJvamVjdHMucm9sZXMpIG9yCiAgICAgICAqICAgICAgICBbYG9yZ2FuaXphdGlvbnNgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL29yZ2FuaXphdGlvbnMucm9sZXMpLiBFYWNoCiAgICAgIHJlc291cmNlIHR5cGUncyBgbmFtZWAKICAgICAgICogICAgICAgIHZhbHVlIGZvcm1hdCBpcyBkZXNjcmliZWQgYmVsb3c6CiAgICAgICoKICAgICAgICogICAgICAgIFtgcHJvamVjdHMucm9sZXMuZGVsZXRlKClgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL3Byb2plY3RzLnJvbGVzL2RlbGV0ZSk6CiAgICAgICAqICAgICAgICBgcHJvamVjdHMve1BST0pFQ1RfSUR9L3JvbGVzL3tDVVNUT01fUk9MRV9JRH1gLiBUaGlzIG1ldGhvZCBkZWxldGVzIG9ubHkKICAgICAgICBbY3VzdG9tCiAgICAgICAqICAgICAgICByb2xlc10oL2lhbS9kb2NzL3VuZGVyc3RhbmRpbmctY3VzdG9tLXJvbGVzKSB0aGF0IGhhdmUgYmVlbgogICAgICAgIGNyZWF0ZWQgYXQgdGhlIHByb2plY3QKICAgICAgICogICAgICAgIGxldmVsLiBFeGFtcGxlIHJlcXVlc3QgVVJMOgogICAgICAgKiAgICAgICAgYGh0dHBzOi8vaWFtLmdvb2dsZWFwaXMuY29tL3YxL3Byb2plY3RzL3tQUk9KRUNUX0lEfS9yb2xlcy97Q1VTVE9NX1JPTEVfSUR9YAogICAgICAqCiAgICAgICAqICAgICAgICBbYG9yZ2FuaXphdGlvbnMucm9sZXMuZGVsZXRlKClgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL29yZ2FuaXphdGlvbnMucm9sZXMvZGVsZXRlKToKICAgICAgICogICAgICAgIGBvcmdhbml6YXRpb25zL3tPUkdBTklaQVRJT05fSUR9L3JvbGVzL3tDVVNUT01fUk9MRV9JRH1gLiBUaGlzIG1ldGhvZAogICAgICAgIGRlbGV0ZXMgb25seQogICAgICAgKiAgICAgICAgW2N1c3RvbSByb2xlc10oL2lhbS9kb2NzL3VuZGVyc3RhbmRpbmctY3VzdG9tLXJvbGVzKSB0aGF0CiAgICAgICAgaGF2ZSBiZWVuIGNyZWF0ZWQgYXQgdGhlCiAgICAgICAqICAgICAgICBvcmdhbml6YXRpb24gbGV2ZWwuIEV4YW1wbGUgcmVxdWVzdCBVUkw6CiAgICAgICAqICAgICAgICBgaHR0cHM6Ly9pYW0uZ29vZ2xlYXBpcy5jb20vdjEvb3JnYW5pemF0aW9ucy97T1JHQU5JWkFUSU9OX0lEfS9yb2xlcy97Q1VTVE9NX1JPTEVfSUR9YAogICAgICAgKiAgICAgICAgTm90ZTogV2lsZGNhcmQgKCopIHZhbHVlcyBhcmUgaW52YWxpZDsgeW91IG11c3Qgc3BlY2lmeSBhIGNvbXBsZXRlIHByb2plY3QKICAgICAgSUQgb3IKICAgICAgICogICAgICAgIG9yZ2FuaXphdGlvbiBJRC4KICAgICAgICogQHJldHVybiB0aGUgcmVxdWVzdAogICAgICAgKi8KICAgICAgcHVibGljIERlbGV0ZSBkZWxldGUoamF2YS5sYW5nLlN0cmluZyBuYW1lKSB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgRGVsZXRlIHJlc3VsdCA9IG5ldyBEZWxldGUobmFtZSk7CiAgICAgICAgaW5pdGlhbGl6ZShyZXN1bHQpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBjbGFzcyBEZWxldGUgZXh0ZW5kcyBJYW1SZXF1ZXN0PGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmlhbS52MS5tb2RlbC5Sb2xlPiB7CgogICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBSRVNUX1BBVEggPSAidjEveytuYW1lfSI7CgogICAgICAgIHByaXZhdGUgZmluYWwgamF2YS51dGlsLnJlZ2V4LlBhdHRlcm4gTkFNRV9QQVRURVJOID0KICAgICAgICAgICAgamF2YS51dGlsLnJlZ2V4LlBhdHRlcm4uY29tcGlsZSgiXm9yZ2FuaXphdGlvbnMvW14vXSsvcm9sZXMvW14vXSskIik7CgogICAgICAgIC8qKgogICAgICAgICAqIFNvZnQgZGVsZXRlcyBhIHJvbGUuIFRoZSByb2xlIGlzIHN1c3BlbmRlZCBhbmQgY2Fubm90IGJlIHVzZWQgdG8gY3JlYXRlIG5ldyBJQU0gUG9saWN5CiAgICAgICAgICogQmluZGluZ3MuIFRoZSBSb2xlIHdpbGwgbm90IGJlIGluY2x1ZGVkIGluIGBMaXN0Um9sZXMoKWAgdW5sZXNzIGBzaG93X2RlbGV0ZWRgIGlzIHNldCBpbiB0aGUKICAgICAgICAgKiBgTGlzdFJvbGVzUmVxdWVzdGAuIFRoZSBSb2xlIGNvbnRhaW5zIHRoZSBkZWxldGVkIGJvb2xlYW4gc2V0LiBFeGlzdGluZyBCaW5kaW5ncyByZW1haW5zLCBidXQKICAgICAgICAgKiBhcmUgaW5hY3RpdmUuIFRoZSBSb2xlIGNhbiBiZSB1bmRlbGV0ZWQgd2l0aGluIDcgZGF5cy4gQWZ0ZXIgNyBkYXlzIHRoZSBSb2xlIGlzIGRlbGV0ZWQgYW5kIGFsbAogICAgICAgICAqIEJpbmRpbmdzIGFzc29jaWF0ZWQgd2l0aCB0aGUgcm9sZSBhcmUgcmVtb3ZlZC4KICAgICAgICAgKgogICAgICAgICAqIENyZWF0ZSBhIHJlcXVlc3QgZm9yIHRoZSBtZXRob2QgInJvbGVzLmRlbGV0ZSIuCiAgICAgICAgICoKICAgICAgICAgKiBUaGlzIHJlcXVlc3QgaG9sZHMgdGhlIHBhcmFtZXRlcnMgbmVlZGVkIGJ5IHRoZSB0aGUgaWFtIHNlcnZlci4gIEFmdGVyIHNldHRpbmcgYW55IG9wdGlvbmFsCiAgICAgICAgICogcGFyYW1ldGVycywgY2FsbCB0aGUge0BsaW5rIERlbGV0ZSNleGVjdXRlKCl9IG1ldGhvZCB0byBpbnZva2UgdGhlIHJlbW90ZSBvcGVyYXRpb24uIDxwPiB7QGxpbmsKICAgICAgICAgKiBEZWxldGUjaW5pdGlhbGl6ZShjb20uZ29vZ2xlLmFwaS5jbGllbnQuZ29vZ2xlYXBpcy5zZXJ2aWNlcy5BYnN0cmFjdEdvb2dsZUNsaWVudFJlcXVlc3QpfSBtdXN0CiAgICAgICAgICogYmUgY2FsbGVkIHRvIGluaXRpYWxpemUgdGhpcyBpbnN0YW5jZSBpbW1lZGlhdGVseSBhZnRlciBpbnZva2luZyB0aGUgY29uc3RydWN0b3IuIDwvcD4KICAgICAgICAgKgogICAgICAgICAqIEBwYXJhbSBuYW1lIFRoZSBgbmFtZWAgcGFyYW1ldGVyJ3MgdmFsdWUgZGVwZW5kcyBvbiB0aGUgdGFyZ2V0IHJlc291cmNlIGZvciB0aGUKICAgICAgcmVxdWVzdCwgbmFtZWx5CiAgICAgICAqICAgICAgICBbYHByb2plY3RzYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9wcm9qZWN0cy5yb2xlcykgb3IKICAgICAgICogICAgICAgIFtgb3JnYW5pemF0aW9uc2BdKC9pYW0vcmVmZXJlbmNlL3Jlc3QvdjEvb3JnYW5pemF0aW9ucy5yb2xlcykuIEVhY2gKICAgICAgcmVzb3VyY2UgdHlwZSdzIGBuYW1lYAogICAgICAgKiAgICAgICAgdmFsdWUgZm9ybWF0IGlzIGRlc2NyaWJlZCBiZWxvdzoKICAgICAgKgogICAgICAgKiAgICAgICAgW2Bwcm9qZWN0cy5yb2xlcy5kZWxldGUoKWBdKC9pYW0vcmVmZXJlbmNlL3Jlc3QvdjEvcHJvamVjdHMucm9sZXMvZGVsZXRlKToKICAgICAgICogICAgICAgIGBwcm9qZWN0cy97UFJPSkVDVF9JRH0vcm9sZXMve0NVU1RPTV9ST0xFX0lEfWAuIFRoaXMgbWV0aG9kIGRlbGV0ZXMgb25seQogICAgICAgIFtjdXN0b20KICAgICAgICogICAgICAgIHJvbGVzXSgvaWFtL2RvY3MvdW5kZXJzdGFuZGluZy1jdXN0b20tcm9sZXMpIHRoYXQgaGF2ZSBiZWVuCiAgICAgICAgY3JlYXRlZCBhdCB0aGUgcHJvamVjdAogICAgICAgKiAgICAgICAgbGV2ZWwuIEV4YW1wbGUgcmVxdWVzdCBVUkw6CiAgICAgICAqICAgICAgICBgaHR0cHM6Ly9pYW0uZ29vZ2xlYXBpcy5jb20vdjEvcHJvamVjdHMve1BST0pFQ1RfSUR9L3JvbGVzL3tDVVNUT01fUk9MRV9JRH1gCiAgICAgICoKICAgICAgICogICAgICAgIFtgb3JnYW5pemF0aW9ucy5yb2xlcy5kZWxldGUoKWBdKC9pYW0vcmVmZXJlbmNlL3Jlc3QvdjEvb3JnYW5pemF0aW9ucy5yb2xlcy9kZWxldGUpOgogICAgICAgKiAgICAgICAgYG9yZ2FuaXphdGlvbnMve09SR0FOSVpBVElPTl9JRH0vcm9sZXMve0NVU1RPTV9ST0xFX0lEfWAuIFRoaXMgbWV0aG9kCiAgICAgICAgZGVsZXRlcyBvbmx5CiAgICAgICAqICAgICAgICBbY3VzdG9tIHJvbGVzXSgvaWFtL2RvY3MvdW5kZXJzdGFuZGluZy1jdXN0b20tcm9sZXMpIHRoYXQKICAgICAgICBoYXZlIGJlZW4gY3JlYXRlZCBhdCB0aGUKICAgICAgICogICAgICAgIG9yZ2FuaXphdGlvbiBsZXZlbC4gRXhhbXBsZSByZXF1ZXN0IFVSTDoKICAgICAgICogICAgICAgIGBodHRwczovL2lhbS5nb29nbGVhcGlzLmNvbS92MS9vcmdhbml6YXRpb25zL3tPUkdBTklaQVRJT05fSUR9L3JvbGVzL3tDVVNUT01fUk9MRV9JRH1gCiAgICAgICAqICAgICAgICBOb3RlOiBXaWxkY2FyZCAoKikgdmFsdWVzIGFyZSBpbnZhbGlkOyB5b3UgbXVzdCBzcGVjaWZ5IGEgY29tcGxldGUgcHJvamVjdAogICAgICBJRCBvcgogICAgICAgKiAgICAgICAgb3JnYW5pemF0aW9uIElELgogICAgICAgICAqIEBzaW5jZSAxLjEzCiAgICAgICAgICovCiAgICAgICAgcHJvdGVjdGVkIERlbGV0ZShqYXZhLmxhbmcuU3RyaW5nIG5hbWUpIHsKICAgICAgICAgIHN1cGVyKElhbS50aGlzLCAiREVMRVRFIiwgUkVTVF9QQVRILCBudWxsLCBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5pYW0udjEubW9kZWwuUm9sZS5jbGFzcyk7CiAgICAgICAgICB0aGlzLm5hbWUgPSBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5QcmVjb25kaXRpb25zLmNoZWNrTm90TnVsbChuYW1lLCAiUmVxdWlyZWQgcGFyYW1ldGVyIG5hbWUgbXVzdCBiZSBzcGVjaWZpZWQuIik7CiAgICAgICAgICBpZiAoIWdldFN1cHByZXNzUGF0dGVybkNoZWNrcygpKSB7CiAgICAgICAgICAgIGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLlByZWNvbmRpdGlvbnMuY2hlY2tBcmd1bWVudChOQU1FX1BBVFRFUk4ubWF0Y2hlcihuYW1lKS5tYXRjaGVzKCksCiAgICAgICAgICAgICAgICAiUGFyYW1ldGVyIG5hbWUgbXVzdCBjb25mb3JtIHRvIHRoZSBwYXR0ZXJuICIgKwogICAgICAgICAgICAgICAgIl5vcmdhbml6YXRpb25zL1teL10rL3JvbGVzL1teL10rJCIpOwogICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIERlbGV0ZSBzZXQkWGdhZnYoamF2YS5sYW5nLlN0cmluZyAkWGdhZnYpIHsKICAgICAgICAgIHJldHVybiAoRGVsZXRlKSBzdXBlci5zZXQkWGdhZnYoJFhnYWZ2KTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBEZWxldGUgc2V0QWNjZXNzVG9rZW4oamF2YS5sYW5nLlN0cmluZyBhY2Nlc3NUb2tlbikgewogICAgICAgICAgcmV0dXJuIChEZWxldGUpIHN1cGVyLnNldEFjY2Vzc1Rva2VuKGFjY2Vzc1Rva2VuKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBEZWxldGUgc2V0QWx0KGphdmEubGFuZy5TdHJpbmcgYWx0KSB7CiAgICAgICAgICByZXR1cm4gKERlbGV0ZSkgc3VwZXIuc2V0QWx0KGFsdCk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgRGVsZXRlIHNldENhbGxiYWNrKGphdmEubGFuZy5TdHJpbmcgY2FsbGJhY2spIHsKICAgICAgICAgIHJldHVybiAoRGVsZXRlKSBzdXBlci5zZXRDYWxsYmFjayhjYWxsYmFjayk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgRGVsZXRlIHNldEZpZWxkcyhqYXZhLmxhbmcuU3RyaW5nIGZpZWxkcykgewogICAgICAgICAgcmV0dXJuIChEZWxldGUpIHN1cGVyLnNldEZpZWxkcyhmaWVsZHMpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIERlbGV0ZSBzZXRLZXkoamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICAgIHJldHVybiAoRGVsZXRlKSBzdXBlci5zZXRLZXkoa2V5KTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBEZWxldGUgc2V0T2F1dGhUb2tlbihqYXZhLmxhbmcuU3RyaW5nIG9hdXRoVG9rZW4pIHsKICAgICAgICAgIHJldHVybiAoRGVsZXRlKSBzdXBlci5zZXRPYXV0aFRva2VuKG9hdXRoVG9rZW4pOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIERlbGV0ZSBzZXRQcmV0dHlQcmludChqYXZhLmxhbmcuQm9vbGVhbiBwcmV0dHlQcmludCkgewogICAgICAgICAgcmV0dXJuIChEZWxldGUpIHN1cGVyLnNldFByZXR0eVByaW50KHByZXR0eVByaW50KTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBEZWxldGUgc2V0UXVvdGFVc2VyKGphdmEubGFuZy5TdHJpbmcgcXVvdGFVc2VyKSB7CiAgICAgICAgICByZXR1cm4gKERlbGV0ZSkgc3VwZXIuc2V0UXVvdGFVc2VyKHF1b3RhVXNlcik7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgRGVsZXRlIHNldFVwbG9hZFR5cGUoamF2YS5sYW5nLlN0cmluZyB1cGxvYWRUeXBlKSB7CiAgICAgICAgICByZXR1cm4gKERlbGV0ZSkgc3VwZXIuc2V0VXBsb2FkVHlwZSh1cGxvYWRUeXBlKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBEZWxldGUgc2V0VXBsb2FkUHJvdG9jb2woamF2YS5sYW5nLlN0cmluZyB1cGxvYWRQcm90b2NvbCkgewogICAgICAgICAgcmV0dXJuIChEZWxldGUpIHN1cGVyLnNldFVwbG9hZFByb3RvY29sKHVwbG9hZFByb3RvY29sKTsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIFRoZSBgbmFtZWAgcGFyYW1ldGVyJ3MgdmFsdWUgZGVwZW5kcyBvbiB0aGUgdGFyZ2V0IHJlc291cmNlIGZvciB0aGUgcmVxdWVzdCwgbmFtZWx5CiAgICAgICAgICogW2Bwcm9qZWN0c2BdKC9pYW0vcmVmZXJlbmNlL3Jlc3QvdjEvcHJvamVjdHMucm9sZXMpIG9yCiAgICAgICAgICogW2Bvcmdhbml6YXRpb25zYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9vcmdhbml6YXRpb25zLnJvbGVzKS4gRWFjaCByZXNvdXJjZSB0eXBlJ3MKICAgICAgICAgKiBgbmFtZWAgdmFsdWUgZm9ybWF0IGlzIGRlc2NyaWJlZCBiZWxvdzoKICAgICAgICAgKgogICAgICAgICAqICogW2Bwcm9qZWN0cy5yb2xlcy5kZWxldGUoKWBdKC9pYW0vcmVmZXJlbmNlL3Jlc3QvdjEvcHJvamVjdHMucm9sZXMvZGVsZXRlKToKICAgICAgICAgKiBgcHJvamVjdHMve1BST0pFQ1RfSUR9L3JvbGVzL3tDVVNUT01fUk9MRV9JRH1gLiBUaGlzIG1ldGhvZCBkZWxldGVzIG9ubHkgW2N1c3RvbQogICAgICAgICAqIHJvbGVzXSgvaWFtL2RvY3MvdW5kZXJzdGFuZGluZy1jdXN0b20tcm9sZXMpIHRoYXQgaGF2ZSBiZWVuIGNyZWF0ZWQgYXQgdGhlIHByb2plY3QgbGV2ZWwuCiAgICAgICAgICogRXhhbXBsZSByZXF1ZXN0IFVSTDoKICAgICAgICAgKiBgaHR0cHM6Ly9pYW0uZ29vZ2xlYXBpcy5jb20vdjEvcHJvamVjdHMve1BST0pFQ1RfSUR9L3JvbGVzL3tDVVNUT01fUk9MRV9JRH1gCiAgICAgICAgICoKICAgICAgICAgKiAqIFtgb3JnYW5pemF0aW9ucy5yb2xlcy5kZWxldGUoKWBdKC9pYW0vcmVmZXJlbmNlL3Jlc3QvdjEvb3JnYW5pemF0aW9ucy5yb2xlcy9kZWxldGUpOgogICAgICAgICAqIGBvcmdhbml6YXRpb25zL3tPUkdBTklaQVRJT05fSUR9L3JvbGVzL3tDVVNUT01fUk9MRV9JRH1gLiBUaGlzIG1ldGhvZCBkZWxldGVzIG9ubHkKICAgICAgICAgKiBbY3VzdG9tIHJvbGVzXSgvaWFtL2RvY3MvdW5kZXJzdGFuZGluZy1jdXN0b20tcm9sZXMpIHRoYXQgaGF2ZSBiZWVuIGNyZWF0ZWQgYXQgdGhlCiAgICAgICAgICogb3JnYW5pemF0aW9uIGxldmVsLiBFeGFtcGxlIHJlcXVlc3QgVVJMOgogICAgICAgICAqIGBodHRwczovL2lhbS5nb29nbGVhcGlzLmNvbS92MS9vcmdhbml6YXRpb25zL3tPUkdBTklaQVRJT05fSUR9L3JvbGVzL3tDVVNUT01fUk9MRV9JRH1gCiAgICAgICAgICoKICAgICAgICAgKiBOb3RlOiBXaWxkY2FyZCAoKikgdmFsdWVzIGFyZSBpbnZhbGlkOyB5b3UgbXVzdCBzcGVjaWZ5IGEgY29tcGxldGUgcHJvamVjdCBJRCBvcgogICAgICAgICAqIG9yZ2FuaXphdGlvbiBJRC4KICAgICAgICAgKi8KICAgICAgICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuU3RyaW5nIG5hbWU7CgogICAgICAgIC8qKiBUaGUgYG5hbWVgIHBhcmFtZXRlcidzIHZhbHVlIGRlcGVuZHMgb24gdGhlIHRhcmdldCByZXNvdXJjZSBmb3IgdGhlIHJlcXVlc3QsIG5hbWVseQogICAgICAgW2Bwcm9qZWN0c2BdKC9pYW0vcmVmZXJlbmNlL3Jlc3QvdjEvcHJvamVjdHMucm9sZXMpIG9yCiAgICAgICBbYG9yZ2FuaXphdGlvbnNgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL29yZ2FuaXphdGlvbnMucm9sZXMpLiBFYWNoIHJlc291cmNlIHR5cGUncyBgbmFtZWAgdmFsdWUKICAgICAgIGZvcm1hdCBpcyBkZXNjcmliZWQgYmVsb3c6CgogICAgICAgKiBbYHByb2plY3RzLnJvbGVzLmRlbGV0ZSgpYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9wcm9qZWN0cy5yb2xlcy9kZWxldGUpOgogICAgICAgYHByb2plY3RzL3tQUk9KRUNUX0lEfS9yb2xlcy97Q1VTVE9NX1JPTEVfSUR9YC4gVGhpcyBtZXRob2QgZGVsZXRlcyBvbmx5IFtjdXN0b20gcm9sZXNdKC9pYW0vZG9jcwogICAgICAgL3VuZGVyc3RhbmRpbmctY3VzdG9tLXJvbGVzKSB0aGF0IGhhdmUgYmVlbiBjcmVhdGVkIGF0IHRoZSBwcm9qZWN0IGxldmVsLiBFeGFtcGxlIHJlcXVlc3QgVVJMOgogICAgICAgYGh0dHBzOi8vaWFtLmdvb2dsZWFwaXMuY29tL3YxL3Byb2plY3RzL3tQUk9KRUNUX0lEfS9yb2xlcy97Q1VTVE9NX1JPTEVfSUR9YAoKICAgICAgICogW2Bvcmdhbml6YXRpb25zLnJvbGVzLmRlbGV0ZSgpYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9vcmdhbml6YXRpb25zLnJvbGVzL2RlbGV0ZSk6CiAgICAgICBgb3JnYW5pemF0aW9ucy97T1JHQU5JWkFUSU9OX0lEfS9yb2xlcy97Q1VTVE9NX1JPTEVfSUR9YC4gVGhpcyBtZXRob2QgZGVsZXRlcyBvbmx5IFtjdXN0b20KICAgICAgIHJvbGVzXSgvaWFtL2RvY3MvdW5kZXJzdGFuZGluZy1jdXN0b20tcm9sZXMpIHRoYXQgaGF2ZSBiZWVuIGNyZWF0ZWQgYXQgdGhlIG9yZ2FuaXphdGlvbiBsZXZlbC4KICAgICAgIEV4YW1wbGUgcmVxdWVzdCBVUkw6CiAgICAgICBgaHR0cHM6Ly9pYW0uZ29vZ2xlYXBpcy5jb20vdjEvb3JnYW5pemF0aW9ucy97T1JHQU5JWkFUSU9OX0lEfS9yb2xlcy97Q1VTVE9NX1JPTEVfSUR9YAoKICAgICAgIE5vdGU6IFdpbGRjYXJkICgqKSB2YWx1ZXMgYXJlIGludmFsaWQ7IHlvdSBtdXN0IHNwZWNpZnkgYSBjb21wbGV0ZSBwcm9qZWN0IElEIG9yIG9yZ2FuaXphdGlvbiBJRC4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXROYW1lKCkgewogICAgICAgICAgcmV0dXJuIG5hbWU7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiBUaGUgYG5hbWVgIHBhcmFtZXRlcidzIHZhbHVlIGRlcGVuZHMgb24gdGhlIHRhcmdldCByZXNvdXJjZSBmb3IgdGhlIHJlcXVlc3QsIG5hbWVseQogICAgICAgICAqIFtgcHJvamVjdHNgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL3Byb2plY3RzLnJvbGVzKSBvcgogICAgICAgICAqIFtgb3JnYW5pemF0aW9uc2BdKC9pYW0vcmVmZXJlbmNlL3Jlc3QvdjEvb3JnYW5pemF0aW9ucy5yb2xlcykuIEVhY2ggcmVzb3VyY2UgdHlwZSdzCiAgICAgICAgICogYG5hbWVgIHZhbHVlIGZvcm1hdCBpcyBkZXNjcmliZWQgYmVsb3c6CiAgICAgICAgICoKICAgICAgICAgKiAqIFtgcHJvamVjdHMucm9sZXMuZGVsZXRlKClgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL3Byb2plY3RzLnJvbGVzL2RlbGV0ZSk6CiAgICAgICAgICogYHByb2plY3RzL3tQUk9KRUNUX0lEfS9yb2xlcy97Q1VTVE9NX1JPTEVfSUR9YC4gVGhpcyBtZXRob2QgZGVsZXRlcyBvbmx5IFtjdXN0b20KICAgICAgICAgKiByb2xlc10oL2lhbS9kb2NzL3VuZGVyc3RhbmRpbmctY3VzdG9tLXJvbGVzKSB0aGF0IGhhdmUgYmVlbiBjcmVhdGVkIGF0IHRoZSBwcm9qZWN0IGxldmVsLgogICAgICAgICAqIEV4YW1wbGUgcmVxdWVzdCBVUkw6CiAgICAgICAgICogYGh0dHBzOi8vaWFtLmdvb2dsZWFwaXMuY29tL3YxL3Byb2plY3RzL3tQUk9KRUNUX0lEfS9yb2xlcy97Q1VTVE9NX1JPTEVfSUR9YAogICAgICAgICAqCiAgICAgICAgICogKiBbYG9yZ2FuaXphdGlvbnMucm9sZXMuZGVsZXRlKClgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL29yZ2FuaXphdGlvbnMucm9sZXMvZGVsZXRlKToKICAgICAgICAgKiBgb3JnYW5pemF0aW9ucy97T1JHQU5JWkFUSU9OX0lEfS9yb2xlcy97Q1VTVE9NX1JPTEVfSUR9YC4gVGhpcyBtZXRob2QgZGVsZXRlcyBvbmx5CiAgICAgICAgICogW2N1c3RvbSByb2xlc10oL2lhbS9kb2NzL3VuZGVyc3RhbmRpbmctY3VzdG9tLXJvbGVzKSB0aGF0IGhhdmUgYmVlbiBjcmVhdGVkIGF0IHRoZQogICAgICAgICAqIG9yZ2FuaXphdGlvbiBsZXZlbC4gRXhhbXBsZSByZXF1ZXN0IFVSTDoKICAgICAgICAgKiBgaHR0cHM6Ly9pYW0uZ29vZ2xlYXBpcy5jb20vdjEvb3JnYW5pemF0aW9ucy97T1JHQU5JWkFUSU9OX0lEfS9yb2xlcy97Q1VTVE9NX1JPTEVfSUR9YAogICAgICAgICAqCiAgICAgICAgICogTm90ZTogV2lsZGNhcmQgKCopIHZhbHVlcyBhcmUgaW52YWxpZDsgeW91IG11c3Qgc3BlY2lmeSBhIGNvbXBsZXRlIHByb2plY3QgSUQgb3IKICAgICAgICAgKiBvcmdhbml6YXRpb24gSUQuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIERlbGV0ZSBzZXROYW1lKGphdmEubGFuZy5TdHJpbmcgbmFtZSkgewogICAgICAgICAgaWYgKCFnZXRTdXBwcmVzc1BhdHRlcm5DaGVja3MoKSkgewogICAgICAgICAgICBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5QcmVjb25kaXRpb25zLmNoZWNrQXJndW1lbnQoTkFNRV9QQVRURVJOLm1hdGNoZXIobmFtZSkubWF0Y2hlcygpLAogICAgICAgICAgICAgICAgIlBhcmFtZXRlciBuYW1lIG11c3QgY29uZm9ybSB0byB0aGUgcGF0dGVybiAiICsKICAgICAgICAgICAgICAgICJeb3JnYW5pemF0aW9ucy9bXi9dKy9yb2xlcy9bXi9dKyQiKTsKICAgICAgICAgIH0KICAgICAgICAgIHRoaXMubmFtZSA9IG5hbWU7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CgogICAgICAgIC8qKiBVc2VkIHRvIHBlcmZvcm0gYSBjb25zaXN0ZW50IHJlYWQtbW9kaWZ5LXdyaXRlLiAqLwogICAgICAgIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICAgICAgICBwcml2YXRlIGphdmEubGFuZy5TdHJpbmcgZXRhZzsKCiAgICAgICAgLyoqIFVzZWQgdG8gcGVyZm9ybSBhIGNvbnNpc3RlbnQgcmVhZC1tb2RpZnktd3JpdGUuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0RXRhZygpIHsKICAgICAgICAgIHJldHVybiBldGFnOwogICAgICAgIH0KCiAgICAgICAgLyoqIFVzZWQgdG8gcGVyZm9ybSBhIGNvbnNpc3RlbnQgcmVhZC1tb2RpZnktd3JpdGUuICovCiAgICAgICAgcHVibGljIERlbGV0ZSBzZXRFdGFnKGphdmEubGFuZy5TdHJpbmcgZXRhZykgewogICAgICAgICAgdGhpcy5ldGFnID0gZXRhZzsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIERlbGV0ZSBzZXQoU3RyaW5nIHBhcmFtZXRlck5hbWUsIE9iamVjdCB2YWx1ZSkgewogICAgICAgICAgcmV0dXJuIChEZWxldGUpIHN1cGVyLnNldChwYXJhbWV0ZXJOYW1lLCB2YWx1ZSk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBHZXRzIGEgUm9sZSBkZWZpbml0aW9uLgogICAgICAgKgogICAgICAgKiBDcmVhdGUgYSByZXF1ZXN0IGZvciB0aGUgbWV0aG9kICJyb2xlcy5nZXQiLgogICAgICAgKgogICAgICAgKiBUaGlzIHJlcXVlc3QgaG9sZHMgdGhlIHBhcmFtZXRlcnMgbmVlZGVkIGJ5IHRoZSBpYW0gc2VydmVyLiAgQWZ0ZXIgc2V0dGluZyBhbnkgb3B0aW9uYWwKICAgICAgICogcGFyYW1ldGVycywgY2FsbCB0aGUge0BsaW5rIEdldCNleGVjdXRlKCl9IG1ldGhvZCB0byBpbnZva2UgdGhlIHJlbW90ZSBvcGVyYXRpb24uCiAgICAgICAqCiAgICAgICAqIEBwYXJhbSBuYW1lIFRoZSBgbmFtZWAgcGFyYW1ldGVyJ3MgdmFsdWUgZGVwZW5kcyBvbiB0aGUgdGFyZ2V0IHJlc291cmNlIGZvciB0aGUKICAgICAgcmVxdWVzdCwgbmFtZWx5CiAgICAgICAqICAgICAgICBbYHJvbGVzYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9yb2xlcyksCiAgICAgICAqICAgICAgICBbYHByb2plY3RzYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9wcm9qZWN0cy5yb2xlcyksIG9yCiAgICAgICAqICAgICAgICBbYG9yZ2FuaXphdGlvbnNgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL29yZ2FuaXphdGlvbnMucm9sZXMpLiBFYWNoCiAgICAgIHJlc291cmNlIHR5cGUncyBgbmFtZWAKICAgICAgICogICAgICAgIHZhbHVlIGZvcm1hdCBpcyBkZXNjcmliZWQgYmVsb3c6CiAgICAgICogW2Byb2xlcy5nZXQoKWBdKC9pYW0vcmVmZXJlbmNlL3Jlc3QvdjEvcm9sZXMvZ2V0KToKICAgICAgICogICAgICAgIGByb2xlcy97Uk9MRV9OQU1FfWAuCiAgICAgICAgVGhpcyBtZXRob2QgcmV0dXJucyByZXN1bHRzIGZyb20gYWxsCiAgICAgICAgW3ByZWRlZmluZWQgcm9sZXNdKC9pYW0vZG9jcwogICAgICAgKiAgICAgICAgL3VuZGVyc3RhbmRpbmctcm9sZXMjcHJlZGVmaW5lZF9yb2xlcykgaW4KICAgICAgICBDbG91ZCBJQU0uIEV4YW1wbGUgcmVxdWVzdCBVUkw6CiAgICAgICAqICAgICAgICBgaHR0cHM6Ly9pYW0uZ29vZ2xlYXBpcy5jb20vdjEvcm9sZXMve1JPTEVfTkFNRX1gCiAgICAgICoKICAgICAgICogICAgICAgIFtgcHJvamVjdHMucm9sZXMuZ2V0KClgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL3Byb2plY3RzLnJvbGVzL2dldCk6CiAgICAgICAqICAgICAgICBgcHJvamVjdHMve1BST0pFQ1RfSUR9L3JvbGVzL3tDVVNUT01fUk9MRV9JRH1gLiBUaGlzIG1ldGhvZCByZXR1cm5zIG9ubHkKICAgICAgICBbY3VzdG9tCiAgICAgICAqICAgICAgICByb2xlc10oL2lhbS9kb2NzL3VuZGVyc3RhbmRpbmctY3VzdG9tLXJvbGVzKSB0aGF0IGhhdmUgYmVlbgogICAgICAgIGNyZWF0ZWQgYXQgdGhlIHByb2plY3QKICAgICAgICogICAgICAgIGxldmVsLiBFeGFtcGxlIHJlcXVlc3QgVVJMOgogICAgICAgKiAgICAgICAgYGh0dHBzOi8vaWFtLmdvb2dsZWFwaXMuY29tL3YxL3Byb2plY3RzL3tQUk9KRUNUX0lEfS9yb2xlcy97Q1VTVE9NX1JPTEVfSUR9YAogICAgICAqCiAgICAgICAqICAgICAgICBbYG9yZ2FuaXphdGlvbnMucm9sZXMuZ2V0KClgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL29yZ2FuaXphdGlvbnMucm9sZXMvZ2V0KToKICAgICAgICogICAgICAgIGBvcmdhbml6YXRpb25zL3tPUkdBTklaQVRJT05fSUR9L3JvbGVzL3tDVVNUT01fUk9MRV9JRH1gLiBUaGlzIG1ldGhvZAogICAgICAgIHJldHVybnMgb25seQogICAgICAgKiAgICAgICAgW2N1c3RvbSByb2xlc10oL2lhbS9kb2NzL3VuZGVyc3RhbmRpbmctY3VzdG9tLXJvbGVzKSB0aGF0CiAgICAgICAgaGF2ZSBiZWVuIGNyZWF0ZWQgYXQgdGhlCiAgICAgICAqICAgICAgICBvcmdhbml6YXRpb24gbGV2ZWwuIEV4YW1wbGUgcmVxdWVzdCBVUkw6CiAgICAgICAqICAgICAgICBgaHR0cHM6Ly9pYW0uZ29vZ2xlYXBpcy5jb20vdjEvb3JnYW5pemF0aW9ucy97T1JHQU5JWkFUSU9OX0lEfS9yb2xlcy97Q1VTVE9NX1JPTEVfSUR9YAogICAgICAgKiAgICAgICAgTm90ZTogV2lsZGNhcmQgKCopIHZhbHVlcyBhcmUgaW52YWxpZDsgeW91IG11c3Qgc3BlY2lmeSBhIGNvbXBsZXRlIHByb2plY3QKICAgICAgSUQgb3IKICAgICAgICogICAgICAgIG9yZ2FuaXphdGlvbiBJRC4KICAgICAgICogQHJldHVybiB0aGUgcmVxdWVzdAogICAgICAgKi8KICAgICAgcHVibGljIEdldCBnZXQoamF2YS5sYW5nLlN0cmluZyBuYW1lKSB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgR2V0IHJlc3VsdCA9IG5ldyBHZXQobmFtZSk7CiAgICAgICAgaW5pdGlhbGl6ZShyZXN1bHQpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBjbGFzcyBHZXQgZXh0ZW5kcyBJYW1SZXF1ZXN0PGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmlhbS52MS5tb2RlbC5Sb2xlPiB7CgogICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBSRVNUX1BBVEggPSAidjEveytuYW1lfSI7CgogICAgICAgIHByaXZhdGUgZmluYWwgamF2YS51dGlsLnJlZ2V4LlBhdHRlcm4gTkFNRV9QQVRURVJOID0KICAgICAgICAgICAgamF2YS51dGlsLnJlZ2V4LlBhdHRlcm4uY29tcGlsZSgiXm9yZ2FuaXphdGlvbnMvW14vXSsvcm9sZXMvW14vXSskIik7CgogICAgICAgIC8qKgogICAgICAgICAqIEdldHMgYSBSb2xlIGRlZmluaXRpb24uCiAgICAgICAgICoKICAgICAgICAgKiBDcmVhdGUgYSByZXF1ZXN0IGZvciB0aGUgbWV0aG9kICJyb2xlcy5nZXQiLgogICAgICAgICAqCiAgICAgICAgICogVGhpcyByZXF1ZXN0IGhvbGRzIHRoZSBwYXJhbWV0ZXJzIG5lZWRlZCBieSB0aGUgdGhlIGlhbSBzZXJ2ZXIuICBBZnRlciBzZXR0aW5nIGFueSBvcHRpb25hbAogICAgICAgICAqIHBhcmFtZXRlcnMsIGNhbGwgdGhlIHtAbGluayBHZXQjZXhlY3V0ZSgpfSBtZXRob2QgdG8gaW52b2tlIHRoZSByZW1vdGUgb3BlcmF0aW9uLiA8cD4ge0BsaW5rCiAgICAgICAgICogR2V0I2luaXRpYWxpemUoY29tLmdvb2dsZS5hcGkuY2xpZW50Lmdvb2dsZWFwaXMuc2VydmljZXMuQWJzdHJhY3RHb29nbGVDbGllbnRSZXF1ZXN0KX0gbXVzdCBiZQogICAgICAgICAqIGNhbGxlZCB0byBpbml0aWFsaXplIHRoaXMgaW5zdGFuY2UgaW1tZWRpYXRlbHkgYWZ0ZXIgaW52b2tpbmcgdGhlIGNvbnN0cnVjdG9yLiA8L3A+CiAgICAgICAgICoKICAgICAgICAgKiBAcGFyYW0gbmFtZSBUaGUgYG5hbWVgIHBhcmFtZXRlcidzIHZhbHVlIGRlcGVuZHMgb24gdGhlIHRhcmdldCByZXNvdXJjZSBmb3IgdGhlCiAgICAgIHJlcXVlc3QsIG5hbWVseQogICAgICAgKiAgICAgICAgW2Byb2xlc2BdKC9pYW0vcmVmZXJlbmNlL3Jlc3QvdjEvcm9sZXMpLAogICAgICAgKiAgICAgICAgW2Bwcm9qZWN0c2BdKC9pYW0vcmVmZXJlbmNlL3Jlc3QvdjEvcHJvamVjdHMucm9sZXMpLCBvcgogICAgICAgKiAgICAgICAgW2Bvcmdhbml6YXRpb25zYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9vcmdhbml6YXRpb25zLnJvbGVzKS4gRWFjaAogICAgICByZXNvdXJjZSB0eXBlJ3MgYG5hbWVgCiAgICAgICAqICAgICAgICB2YWx1ZSBmb3JtYXQgaXMgZGVzY3JpYmVkIGJlbG93OgogICAgICAqIFtgcm9sZXMuZ2V0KClgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL3JvbGVzL2dldCk6CiAgICAgICAqICAgICAgICBgcm9sZXMve1JPTEVfTkFNRX1gLgogICAgICAgIFRoaXMgbWV0aG9kIHJldHVybnMgcmVzdWx0cyBmcm9tIGFsbAogICAgICAgIFtwcmVkZWZpbmVkIHJvbGVzXSgvaWFtL2RvY3MKICAgICAgICogICAgICAgIC91bmRlcnN0YW5kaW5nLXJvbGVzI3ByZWRlZmluZWRfcm9sZXMpIGluCiAgICAgICAgQ2xvdWQgSUFNLiBFeGFtcGxlIHJlcXVlc3QgVVJMOgogICAgICAgKiAgICAgICAgYGh0dHBzOi8vaWFtLmdvb2dsZWFwaXMuY29tL3YxL3JvbGVzL3tST0xFX05BTUV9YAogICAgICAqCiAgICAgICAqICAgICAgICBbYHByb2plY3RzLnJvbGVzLmdldCgpYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9wcm9qZWN0cy5yb2xlcy9nZXQpOgogICAgICAgKiAgICAgICAgYHByb2plY3RzL3tQUk9KRUNUX0lEfS9yb2xlcy97Q1VTVE9NX1JPTEVfSUR9YC4gVGhpcyBtZXRob2QgcmV0dXJucyBvbmx5CiAgICAgICAgW2N1c3RvbQogICAgICAgKiAgICAgICAgcm9sZXNdKC9pYW0vZG9jcy91bmRlcnN0YW5kaW5nLWN1c3RvbS1yb2xlcykgdGhhdCBoYXZlIGJlZW4KICAgICAgICBjcmVhdGVkIGF0IHRoZSBwcm9qZWN0CiAgICAgICAqICAgICAgICBsZXZlbC4gRXhhbXBsZSByZXF1ZXN0IFVSTDoKICAgICAgICogICAgICAgIGBodHRwczovL2lhbS5nb29nbGVhcGlzLmNvbS92MS9wcm9qZWN0cy97UFJPSkVDVF9JRH0vcm9sZXMve0NVU1RPTV9ST0xFX0lEfWAKICAgICAgKgogICAgICAgKiAgICAgICAgW2Bvcmdhbml6YXRpb25zLnJvbGVzLmdldCgpYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9vcmdhbml6YXRpb25zLnJvbGVzL2dldCk6CiAgICAgICAqICAgICAgICBgb3JnYW5pemF0aW9ucy97T1JHQU5JWkFUSU9OX0lEfS9yb2xlcy97Q1VTVE9NX1JPTEVfSUR9YC4gVGhpcyBtZXRob2QKICAgICAgICByZXR1cm5zIG9ubHkKICAgICAgICogICAgICAgIFtjdXN0b20gcm9sZXNdKC9pYW0vZG9jcy91bmRlcnN0YW5kaW5nLWN1c3RvbS1yb2xlcykgdGhhdAogICAgICAgIGhhdmUgYmVlbiBjcmVhdGVkIGF0IHRoZQogICAgICAgKiAgICAgICAgb3JnYW5pemF0aW9uIGxldmVsLiBFeGFtcGxlIHJlcXVlc3QgVVJMOgogICAgICAgKiAgICAgICAgYGh0dHBzOi8vaWFtLmdvb2dsZWFwaXMuY29tL3YxL29yZ2FuaXphdGlvbnMve09SR0FOSVpBVElPTl9JRH0vcm9sZXMve0NVU1RPTV9ST0xFX0lEfWAKICAgICAgICogICAgICAgIE5vdGU6IFdpbGRjYXJkICgqKSB2YWx1ZXMgYXJlIGludmFsaWQ7IHlvdSBtdXN0IHNwZWNpZnkgYSBjb21wbGV0ZSBwcm9qZWN0CiAgICAgIElEIG9yCiAgICAgICAqICAgICAgICBvcmdhbml6YXRpb24gSUQuCiAgICAgICAgICogQHNpbmNlIDEuMTMKICAgICAgICAgKi8KICAgICAgICBwcm90ZWN0ZWQgR2V0KGphdmEubGFuZy5TdHJpbmcgbmFtZSkgewogICAgICAgICAgc3VwZXIoSWFtLnRoaXMsICJHRVQiLCBSRVNUX1BBVEgsIG51bGwsIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmlhbS52MS5tb2RlbC5Sb2xlLmNsYXNzKTsKICAgICAgICAgIHRoaXMubmFtZSA9IGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLlByZWNvbmRpdGlvbnMuY2hlY2tOb3ROdWxsKG5hbWUsICJSZXF1aXJlZCBwYXJhbWV0ZXIgbmFtZSBtdXN0IGJlIHNwZWNpZmllZC4iKTsKICAgICAgICAgIGlmICghZ2V0U3VwcHJlc3NQYXR0ZXJuQ2hlY2tzKCkpIHsKICAgICAgICAgICAgY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuUHJlY29uZGl0aW9ucy5jaGVja0FyZ3VtZW50KE5BTUVfUEFUVEVSTi5tYXRjaGVyKG5hbWUpLm1hdGNoZXMoKSwKICAgICAgICAgICAgICAgICJQYXJhbWV0ZXIgbmFtZSBtdXN0IGNvbmZvcm0gdG8gdGhlIHBhdHRlcm4gIiArCiAgICAgICAgICAgICAgICAiXm9yZ2FuaXphdGlvbnMvW14vXSsvcm9sZXMvW14vXSskIik7CiAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5hcGkuY2xpZW50Lmh0dHAuSHR0cFJlc3BvbnNlIGV4ZWN1dGVVc2luZ0hlYWQoKSB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuZXhlY3V0ZVVzaW5nSGVhZCgpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIGNvbS5nb29nbGUuYXBpLmNsaWVudC5odHRwLkh0dHBSZXF1ZXN0IGJ1aWxkSHR0cFJlcXVlc3RVc2luZ0hlYWQoKSB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuYnVpbGRIdHRwUmVxdWVzdFVzaW5nSGVhZCgpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIEdldCBzZXQkWGdhZnYoamF2YS5sYW5nLlN0cmluZyAkWGdhZnYpIHsKICAgICAgICAgIHJldHVybiAoR2V0KSBzdXBlci5zZXQkWGdhZnYoJFhnYWZ2KTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBHZXQgc2V0QWNjZXNzVG9rZW4oamF2YS5sYW5nLlN0cmluZyBhY2Nlc3NUb2tlbikgewogICAgICAgICAgcmV0dXJuIChHZXQpIHN1cGVyLnNldEFjY2Vzc1Rva2VuKGFjY2Vzc1Rva2VuKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBHZXQgc2V0QWx0KGphdmEubGFuZy5TdHJpbmcgYWx0KSB7CiAgICAgICAgICByZXR1cm4gKEdldCkgc3VwZXIuc2V0QWx0KGFsdCk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgR2V0IHNldENhbGxiYWNrKGphdmEubGFuZy5TdHJpbmcgY2FsbGJhY2spIHsKICAgICAgICAgIHJldHVybiAoR2V0KSBzdXBlci5zZXRDYWxsYmFjayhjYWxsYmFjayk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgR2V0IHNldEZpZWxkcyhqYXZhLmxhbmcuU3RyaW5nIGZpZWxkcykgewogICAgICAgICAgcmV0dXJuIChHZXQpIHN1cGVyLnNldEZpZWxkcyhmaWVsZHMpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIEdldCBzZXRLZXkoamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICAgIHJldHVybiAoR2V0KSBzdXBlci5zZXRLZXkoa2V5KTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBHZXQgc2V0T2F1dGhUb2tlbihqYXZhLmxhbmcuU3RyaW5nIG9hdXRoVG9rZW4pIHsKICAgICAgICAgIHJldHVybiAoR2V0KSBzdXBlci5zZXRPYXV0aFRva2VuKG9hdXRoVG9rZW4pOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIEdldCBzZXRQcmV0dHlQcmludChqYXZhLmxhbmcuQm9vbGVhbiBwcmV0dHlQcmludCkgewogICAgICAgICAgcmV0dXJuIChHZXQpIHN1cGVyLnNldFByZXR0eVByaW50KHByZXR0eVByaW50KTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBHZXQgc2V0UXVvdGFVc2VyKGphdmEubGFuZy5TdHJpbmcgcXVvdGFVc2VyKSB7CiAgICAgICAgICByZXR1cm4gKEdldCkgc3VwZXIuc2V0UXVvdGFVc2VyKHF1b3RhVXNlcik7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgR2V0IHNldFVwbG9hZFR5cGUoamF2YS5sYW5nLlN0cmluZyB1cGxvYWRUeXBlKSB7CiAgICAgICAgICByZXR1cm4gKEdldCkgc3VwZXIuc2V0VXBsb2FkVHlwZSh1cGxvYWRUeXBlKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBHZXQgc2V0VXBsb2FkUHJvdG9jb2woamF2YS5sYW5nLlN0cmluZyB1cGxvYWRQcm90b2NvbCkgewogICAgICAgICAgcmV0dXJuIChHZXQpIHN1cGVyLnNldFVwbG9hZFByb3RvY29sKHVwbG9hZFByb3RvY29sKTsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIFRoZSBgbmFtZWAgcGFyYW1ldGVyJ3MgdmFsdWUgZGVwZW5kcyBvbiB0aGUgdGFyZ2V0IHJlc291cmNlIGZvciB0aGUgcmVxdWVzdCwgbmFtZWx5CiAgICAgICAgICogW2Byb2xlc2BdKC9pYW0vcmVmZXJlbmNlL3Jlc3QvdjEvcm9sZXMpLAogICAgICAgICAqIFtgcHJvamVjdHNgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL3Byb2plY3RzLnJvbGVzKSwgb3IKICAgICAgICAgKiBbYG9yZ2FuaXphdGlvbnNgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL29yZ2FuaXphdGlvbnMucm9sZXMpLiBFYWNoIHJlc291cmNlIHR5cGUncwogICAgICAgICAqIGBuYW1lYCB2YWx1ZSBmb3JtYXQgaXMgZGVzY3JpYmVkIGJlbG93OgogICAgICAgICAqCiAgICAgICAgICogKiBbYHJvbGVzLmdldCgpYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9yb2xlcy9nZXQpOiBgcm9sZXMve1JPTEVfTkFNRX1gLiBUaGlzIG1ldGhvZAogICAgICAgICAqIHJldHVybnMgcmVzdWx0cyBmcm9tIGFsbCBbcHJlZGVmaW5lZCByb2xlc10oL2lhbS9kb2NzL3VuZGVyc3RhbmRpbmctCiAgICAgICAgICogcm9sZXMjcHJlZGVmaW5lZF9yb2xlcykgaW4gQ2xvdWQgSUFNLiBFeGFtcGxlIHJlcXVlc3QgVVJMOgogICAgICAgICAqIGBodHRwczovL2lhbS5nb29nbGVhcGlzLmNvbS92MS9yb2xlcy97Uk9MRV9OQU1FfWAKICAgICAgICAgKgogICAgICAgICAqICogW2Bwcm9qZWN0cy5yb2xlcy5nZXQoKWBdKC9pYW0vcmVmZXJlbmNlL3Jlc3QvdjEvcHJvamVjdHMucm9sZXMvZ2V0KToKICAgICAgICAgKiBgcHJvamVjdHMve1BST0pFQ1RfSUR9L3JvbGVzL3tDVVNUT01fUk9MRV9JRH1gLiBUaGlzIG1ldGhvZCByZXR1cm5zIG9ubHkgW2N1c3RvbQogICAgICAgICAqIHJvbGVzXSgvaWFtL2RvY3MvdW5kZXJzdGFuZGluZy1jdXN0b20tcm9sZXMpIHRoYXQgaGF2ZSBiZWVuIGNyZWF0ZWQgYXQgdGhlIHByb2plY3QgbGV2ZWwuCiAgICAgICAgICogRXhhbXBsZSByZXF1ZXN0IFVSTDoKICAgICAgICAgKiBgaHR0cHM6Ly9pYW0uZ29vZ2xlYXBpcy5jb20vdjEvcHJvamVjdHMve1BST0pFQ1RfSUR9L3JvbGVzL3tDVVNUT01fUk9MRV9JRH1gCiAgICAgICAgICoKICAgICAgICAgKiAqIFtgb3JnYW5pemF0aW9ucy5yb2xlcy5nZXQoKWBdKC9pYW0vcmVmZXJlbmNlL3Jlc3QvdjEvb3JnYW5pemF0aW9ucy5yb2xlcy9nZXQpOgogICAgICAgICAqIGBvcmdhbml6YXRpb25zL3tPUkdBTklaQVRJT05fSUR9L3JvbGVzL3tDVVNUT01fUk9MRV9JRH1gLiBUaGlzIG1ldGhvZCByZXR1cm5zIG9ubHkKICAgICAgICAgKiBbY3VzdG9tIHJvbGVzXSgvaWFtL2RvY3MvdW5kZXJzdGFuZGluZy1jdXN0b20tcm9sZXMpIHRoYXQgaGF2ZSBiZWVuIGNyZWF0ZWQgYXQgdGhlCiAgICAgICAgICogb3JnYW5pemF0aW9uIGxldmVsLiBFeGFtcGxlIHJlcXVlc3QgVVJMOgogICAgICAgICAqIGBodHRwczovL2lhbS5nb29nbGVhcGlzLmNvbS92MS9vcmdhbml6YXRpb25zL3tPUkdBTklaQVRJT05fSUR9L3JvbGVzL3tDVVNUT01fUk9MRV9JRH1gCiAgICAgICAgICoKICAgICAgICAgKiBOb3RlOiBXaWxkY2FyZCAoKikgdmFsdWVzIGFyZSBpbnZhbGlkOyB5b3UgbXVzdCBzcGVjaWZ5IGEgY29tcGxldGUgcHJvamVjdCBJRCBvcgogICAgICAgICAqIG9yZ2FuaXphdGlvbiBJRC4KICAgICAgICAgKi8KICAgICAgICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuU3RyaW5nIG5hbWU7CgogICAgICAgIC8qKiBUaGUgYG5hbWVgIHBhcmFtZXRlcidzIHZhbHVlIGRlcGVuZHMgb24gdGhlIHRhcmdldCByZXNvdXJjZSBmb3IgdGhlIHJlcXVlc3QsIG5hbWVseQogICAgICAgW2Byb2xlc2BdKC9pYW0vcmVmZXJlbmNlL3Jlc3QvdjEvcm9sZXMpLCBbYHByb2plY3RzYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9wcm9qZWN0cy5yb2xlcyksIG9yCiAgICAgICBbYG9yZ2FuaXphdGlvbnNgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL29yZ2FuaXphdGlvbnMucm9sZXMpLiBFYWNoIHJlc291cmNlIHR5cGUncyBgbmFtZWAgdmFsdWUKICAgICAgIGZvcm1hdCBpcyBkZXNjcmliZWQgYmVsb3c6CgogICAgICAgKiBbYHJvbGVzLmdldCgpYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9yb2xlcy9nZXQpOiBgcm9sZXMve1JPTEVfTkFNRX1gLiBUaGlzIG1ldGhvZCByZXR1cm5zCiAgICAgICByZXN1bHRzIGZyb20gYWxsIFtwcmVkZWZpbmVkIHJvbGVzXSgvaWFtL2RvY3MvdW5kZXJzdGFuZGluZy1yb2xlcyNwcmVkZWZpbmVkX3JvbGVzKSBpbiBDbG91ZCBJQU0uCiAgICAgICBFeGFtcGxlIHJlcXVlc3QgVVJMOiBgaHR0cHM6Ly9pYW0uZ29vZ2xlYXBpcy5jb20vdjEvcm9sZXMve1JPTEVfTkFNRX1gCgogICAgICAgKiBbYHByb2plY3RzLnJvbGVzLmdldCgpYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9wcm9qZWN0cy5yb2xlcy9nZXQpOgogICAgICAgYHByb2plY3RzL3tQUk9KRUNUX0lEfS9yb2xlcy97Q1VTVE9NX1JPTEVfSUR9YC4gVGhpcyBtZXRob2QgcmV0dXJucyBvbmx5IFtjdXN0b20gcm9sZXNdKC9pYW0vZG9jcwogICAgICAgL3VuZGVyc3RhbmRpbmctY3VzdG9tLXJvbGVzKSB0aGF0IGhhdmUgYmVlbiBjcmVhdGVkIGF0IHRoZSBwcm9qZWN0IGxldmVsLiBFeGFtcGxlIHJlcXVlc3QgVVJMOgogICAgICAgYGh0dHBzOi8vaWFtLmdvb2dsZWFwaXMuY29tL3YxL3Byb2plY3RzL3tQUk9KRUNUX0lEfS9yb2xlcy97Q1VTVE9NX1JPTEVfSUR9YAoKICAgICAgICogW2Bvcmdhbml6YXRpb25zLnJvbGVzLmdldCgpYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9vcmdhbml6YXRpb25zLnJvbGVzL2dldCk6CiAgICAgICBgb3JnYW5pemF0aW9ucy97T1JHQU5JWkFUSU9OX0lEfS9yb2xlcy97Q1VTVE9NX1JPTEVfSUR9YC4gVGhpcyBtZXRob2QgcmV0dXJucyBvbmx5IFtjdXN0b20KICAgICAgIHJvbGVzXSgvaWFtL2RvY3MvdW5kZXJzdGFuZGluZy1jdXN0b20tcm9sZXMpIHRoYXQgaGF2ZSBiZWVuIGNyZWF0ZWQgYXQgdGhlIG9yZ2FuaXphdGlvbiBsZXZlbC4KICAgICAgIEV4YW1wbGUgcmVxdWVzdCBVUkw6CiAgICAgICBgaHR0cHM6Ly9pYW0uZ29vZ2xlYXBpcy5jb20vdjEvb3JnYW5pemF0aW9ucy97T1JHQU5JWkFUSU9OX0lEfS9yb2xlcy97Q1VTVE9NX1JPTEVfSUR9YAoKICAgICAgIE5vdGU6IFdpbGRjYXJkICgqKSB2YWx1ZXMgYXJlIGludmFsaWQ7IHlvdSBtdXN0IHNwZWNpZnkgYSBjb21wbGV0ZSBwcm9qZWN0IElEIG9yIG9yZ2FuaXphdGlvbiBJRC4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXROYW1lKCkgewogICAgICAgICAgcmV0dXJuIG5hbWU7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiBUaGUgYG5hbWVgIHBhcmFtZXRlcidzIHZhbHVlIGRlcGVuZHMgb24gdGhlIHRhcmdldCByZXNvdXJjZSBmb3IgdGhlIHJlcXVlc3QsIG5hbWVseQogICAgICAgICAqIFtgcm9sZXNgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL3JvbGVzKSwKICAgICAgICAgKiBbYHByb2plY3RzYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9wcm9qZWN0cy5yb2xlcyksIG9yCiAgICAgICAgICogW2Bvcmdhbml6YXRpb25zYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9vcmdhbml6YXRpb25zLnJvbGVzKS4gRWFjaCByZXNvdXJjZSB0eXBlJ3MKICAgICAgICAgKiBgbmFtZWAgdmFsdWUgZm9ybWF0IGlzIGRlc2NyaWJlZCBiZWxvdzoKICAgICAgICAgKgogICAgICAgICAqICogW2Byb2xlcy5nZXQoKWBdKC9pYW0vcmVmZXJlbmNlL3Jlc3QvdjEvcm9sZXMvZ2V0KTogYHJvbGVzL3tST0xFX05BTUV9YC4gVGhpcyBtZXRob2QKICAgICAgICAgKiByZXR1cm5zIHJlc3VsdHMgZnJvbSBhbGwgW3ByZWRlZmluZWQgcm9sZXNdKC9pYW0vZG9jcy91bmRlcnN0YW5kaW5nLQogICAgICAgICAqIHJvbGVzI3ByZWRlZmluZWRfcm9sZXMpIGluIENsb3VkIElBTS4gRXhhbXBsZSByZXF1ZXN0IFVSTDoKICAgICAgICAgKiBgaHR0cHM6Ly9pYW0uZ29vZ2xlYXBpcy5jb20vdjEvcm9sZXMve1JPTEVfTkFNRX1gCiAgICAgICAgICoKICAgICAgICAgKiAqIFtgcHJvamVjdHMucm9sZXMuZ2V0KClgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL3Byb2plY3RzLnJvbGVzL2dldCk6CiAgICAgICAgICogYHByb2plY3RzL3tQUk9KRUNUX0lEfS9yb2xlcy97Q1VTVE9NX1JPTEVfSUR9YC4gVGhpcyBtZXRob2QgcmV0dXJucyBvbmx5IFtjdXN0b20KICAgICAgICAgKiByb2xlc10oL2lhbS9kb2NzL3VuZGVyc3RhbmRpbmctY3VzdG9tLXJvbGVzKSB0aGF0IGhhdmUgYmVlbiBjcmVhdGVkIGF0IHRoZSBwcm9qZWN0IGxldmVsLgogICAgICAgICAqIEV4YW1wbGUgcmVxdWVzdCBVUkw6CiAgICAgICAgICogYGh0dHBzOi8vaWFtLmdvb2dsZWFwaXMuY29tL3YxL3Byb2plY3RzL3tQUk9KRUNUX0lEfS9yb2xlcy97Q1VTVE9NX1JPTEVfSUR9YAogICAgICAgICAqCiAgICAgICAgICogKiBbYG9yZ2FuaXphdGlvbnMucm9sZXMuZ2V0KClgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL29yZ2FuaXphdGlvbnMucm9sZXMvZ2V0KToKICAgICAgICAgKiBgb3JnYW5pemF0aW9ucy97T1JHQU5JWkFUSU9OX0lEfS9yb2xlcy97Q1VTVE9NX1JPTEVfSUR9YC4gVGhpcyBtZXRob2QgcmV0dXJucyBvbmx5CiAgICAgICAgICogW2N1c3RvbSByb2xlc10oL2lhbS9kb2NzL3VuZGVyc3RhbmRpbmctY3VzdG9tLXJvbGVzKSB0aGF0IGhhdmUgYmVlbiBjcmVhdGVkIGF0IHRoZQogICAgICAgICAqIG9yZ2FuaXphdGlvbiBsZXZlbC4gRXhhbXBsZSByZXF1ZXN0IFVSTDoKICAgICAgICAgKiBgaHR0cHM6Ly9pYW0uZ29vZ2xlYXBpcy5jb20vdjEvb3JnYW5pemF0aW9ucy97T1JHQU5JWkFUSU9OX0lEfS9yb2xlcy97Q1VTVE9NX1JPTEVfSUR9YAogICAgICAgICAqCiAgICAgICAgICogTm90ZTogV2lsZGNhcmQgKCopIHZhbHVlcyBhcmUgaW52YWxpZDsgeW91IG11c3Qgc3BlY2lmeSBhIGNvbXBsZXRlIHByb2plY3QgSUQgb3IKICAgICAgICAgKiBvcmdhbml6YXRpb24gSUQuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIEdldCBzZXROYW1lKGphdmEubGFuZy5TdHJpbmcgbmFtZSkgewogICAgICAgICAgaWYgKCFnZXRTdXBwcmVzc1BhdHRlcm5DaGVja3MoKSkgewogICAgICAgICAgICBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5QcmVjb25kaXRpb25zLmNoZWNrQXJndW1lbnQoTkFNRV9QQVRURVJOLm1hdGNoZXIobmFtZSkubWF0Y2hlcygpLAogICAgICAgICAgICAgICAgIlBhcmFtZXRlciBuYW1lIG11c3QgY29uZm9ybSB0byB0aGUgcGF0dGVybiAiICsKICAgICAgICAgICAgICAgICJeb3JnYW5pemF0aW9ucy9bXi9dKy9yb2xlcy9bXi9dKyQiKTsKICAgICAgICAgIH0KICAgICAgICAgIHRoaXMubmFtZSA9IG5hbWU7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBHZXQgc2V0KFN0cmluZyBwYXJhbWV0ZXJOYW1lLCBPYmplY3QgdmFsdWUpIHsKICAgICAgICAgIHJldHVybiAoR2V0KSBzdXBlci5zZXQocGFyYW1ldGVyTmFtZSwgdmFsdWUpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogTGlzdHMgdGhlIFJvbGVzIGRlZmluZWQgb24gYSByZXNvdXJjZS4KICAgICAgICoKICAgICAgICogQ3JlYXRlIGEgcmVxdWVzdCBmb3IgdGhlIG1ldGhvZCAicm9sZXMubGlzdCIuCiAgICAgICAqCiAgICAgICAqIFRoaXMgcmVxdWVzdCBob2xkcyB0aGUgcGFyYW1ldGVycyBuZWVkZWQgYnkgdGhlIGlhbSBzZXJ2ZXIuICBBZnRlciBzZXR0aW5nIGFueSBvcHRpb25hbAogICAgICAgKiBwYXJhbWV0ZXJzLCBjYWxsIHRoZSB7QGxpbmsgTGlzdCNleGVjdXRlKCl9IG1ldGhvZCB0byBpbnZva2UgdGhlIHJlbW90ZSBvcGVyYXRpb24uCiAgICAgICAqCiAgICAgICAqIEBwYXJhbSBwYXJlbnQgVGhlIGBwYXJlbnRgIHBhcmFtZXRlcidzIHZhbHVlIGRlcGVuZHMgb24gdGhlIHRhcmdldCByZXNvdXJjZSBmb3IgdGhlCiAgICAgIHJlcXVlc3QsIG5hbWVseQogICAgICAgKiAgICAgICAgW2Byb2xlc2BdKC9pYW0vcmVmZXJlbmNlL3Jlc3QvdjEvcm9sZXMpLAogICAgICAgKiAgICAgICAgW2Bwcm9qZWN0c2BdKC9pYW0vcmVmZXJlbmNlL3Jlc3QvdjEvcHJvamVjdHMucm9sZXMpLCBvcgogICAgICAgKiAgICAgICAgW2Bvcmdhbml6YXRpb25zYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9vcmdhbml6YXRpb25zLnJvbGVzKS4gRWFjaAogICAgICByZXNvdXJjZSB0eXBlJ3MKICAgICAgICogICAgICAgIGBwYXJlbnRgIHZhbHVlIGZvcm1hdCBpcyBkZXNjcmliZWQgYmVsb3c6CiAgICAgICoKICAgICAgICogICAgICAgIFtgcm9sZXMubGlzdCgpYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9yb2xlcy9saXN0KTogQW4gZW1wdHkgc3RyaW5nLgogICAgICAgIFRoaXMgbWV0aG9kCiAgICAgICAqICAgICAgICBkb2Vzbid0IHJlcXVpcmUgYSByZXNvdXJjZTsgaXQgc2ltcGx5IHJldHVybnMgYWxsCiAgICAgICAgW3ByZWRlZmluZWQgcm9sZXNdKC9pYW0vZG9jcwogICAgICAgKiAgICAgICAgL3VuZGVyc3RhbmRpbmctcm9sZXMjcHJlZGVmaW5lZF9yb2xlcykgaW4KICAgICAgICBDbG91ZCBJQU0uIEV4YW1wbGUgcmVxdWVzdCBVUkw6CiAgICAgICAqICAgICAgICBgaHR0cHM6Ly9pYW0uZ29vZ2xlYXBpcy5jb20vdjEvcm9sZXNgCiAgICAgICoKICAgICAgICogICAgICAgIFtgcHJvamVjdHMucm9sZXMubGlzdCgpYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9wcm9qZWN0cy5yb2xlcy9saXN0KToKICAgICAgICogICAgICAgIGBwcm9qZWN0cy97UFJPSkVDVF9JRH1gLiBUaGlzIG1ldGhvZCBsaXN0cyBhbGwgcHJvamVjdC1sZXZlbAogICAgICAgIFtjdXN0b20gcm9sZXNdKC9pYW0vZG9jcwogICAgICAgKiAgICAgICAgL3VuZGVyc3RhbmRpbmctY3VzdG9tLXJvbGVzKS4KICAgICAgICBFeGFtcGxlIHJlcXVlc3QgVVJMOgogICAgICAgKiAgICAgICAgYGh0dHBzOi8vaWFtLmdvb2dsZWFwaXMuY29tL3YxL3Byb2plY3RzL3tQUk9KRUNUX0lEfS9yb2xlc2AKICAgICAgKgogICAgICAgKiAgICAgICAgW2Bvcmdhbml6YXRpb25zLnJvbGVzLmxpc3QoKWBdKC9pYW0vcmVmZXJlbmNlL3Jlc3QvdjEvb3JnYW5pemF0aW9ucy5yb2xlcy9saXN0KToKICAgICAgICogICAgICAgIGBvcmdhbml6YXRpb25zL3tPUkdBTklaQVRJT05fSUR9YC4gVGhpcyBtZXRob2QgbGlzdHMgYWxsCiAgICAgICAgb3JnYW5pemF0aW9uLWxldmVsIFtjdXN0b20KICAgICAgICogICAgICAgIHJvbGVzXSgvaWFtL2RvY3MvdW5kZXJzdGFuZGluZy1jdXN0b20tcm9sZXMpLgogICAgICAgIEV4YW1wbGUgcmVxdWVzdCBVUkw6CiAgICAgICAqICAgICAgICBgaHR0cHM6Ly9pYW0uZ29vZ2xlYXBpcy5jb20vdjEvb3JnYW5pemF0aW9ucy97T1JHQU5JWkFUSU9OX0lEfS9yb2xlc2AKICAgICAgTm90ZTogV2lsZGNhcmQgKCopCiAgICAgICAqICAgICAgICB2YWx1ZXMgYXJlIGludmFsaWQ7IHlvdSBtdXN0IHNwZWNpZnkgYSBjb21wbGV0ZSBwcm9qZWN0CiAgICAgIElEIG9yIG9yZ2FuaXphdGlvbiBJRC4KICAgICAgICogQHJldHVybiB0aGUgcmVxdWVzdAogICAgICAgKi8KICAgICAgcHVibGljIExpc3QgbGlzdChqYXZhLmxhbmcuU3RyaW5nIHBhcmVudCkgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIExpc3QgcmVzdWx0ID0gbmV3IExpc3QocGFyZW50KTsKICAgICAgICBpbml0aWFsaXplKHJlc3VsdCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHVibGljIGNsYXNzIExpc3QgZXh0ZW5kcyBJYW1SZXF1ZXN0PGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmlhbS52MS5tb2RlbC5MaXN0Um9sZXNSZXNwb25zZT4gewoKICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgUkVTVF9QQVRIID0gInYxL3srcGFyZW50fS9yb2xlcyI7CgogICAgICAgIHByaXZhdGUgZmluYWwgamF2YS51dGlsLnJlZ2V4LlBhdHRlcm4gUEFSRU5UX1BBVFRFUk4gPQogICAgICAgICAgICBqYXZhLnV0aWwucmVnZXguUGF0dGVybi5jb21waWxlKCJeb3JnYW5pemF0aW9ucy9bXi9dKyQiKTsKCiAgICAgICAgLyoqCiAgICAgICAgICogTGlzdHMgdGhlIFJvbGVzIGRlZmluZWQgb24gYSByZXNvdXJjZS4KICAgICAgICAgKgogICAgICAgICAqIENyZWF0ZSBhIHJlcXVlc3QgZm9yIHRoZSBtZXRob2QgInJvbGVzLmxpc3QiLgogICAgICAgICAqCiAgICAgICAgICogVGhpcyByZXF1ZXN0IGhvbGRzIHRoZSBwYXJhbWV0ZXJzIG5lZWRlZCBieSB0aGUgdGhlIGlhbSBzZXJ2ZXIuICBBZnRlciBzZXR0aW5nIGFueSBvcHRpb25hbAogICAgICAgICAqIHBhcmFtZXRlcnMsIGNhbGwgdGhlIHtAbGluayBMaXN0I2V4ZWN1dGUoKX0gbWV0aG9kIHRvIGludm9rZSB0aGUgcmVtb3RlIG9wZXJhdGlvbi4gPHA+IHtAbGluawogICAgICAgICAqIExpc3QjaW5pdGlhbGl6ZShjb20uZ29vZ2xlLmFwaS5jbGllbnQuZ29vZ2xlYXBpcy5zZXJ2aWNlcy5BYnN0cmFjdEdvb2dsZUNsaWVudFJlcXVlc3QpfSBtdXN0IGJlCiAgICAgICAgICogY2FsbGVkIHRvIGluaXRpYWxpemUgdGhpcyBpbnN0YW5jZSBpbW1lZGlhdGVseSBhZnRlciBpbnZva2luZyB0aGUgY29uc3RydWN0b3IuIDwvcD4KICAgICAgICAgKgogICAgICAgICAqIEBwYXJhbSBwYXJlbnQgVGhlIGBwYXJlbnRgIHBhcmFtZXRlcidzIHZhbHVlIGRlcGVuZHMgb24gdGhlIHRhcmdldCByZXNvdXJjZSBmb3IgdGhlCiAgICAgIHJlcXVlc3QsIG5hbWVseQogICAgICAgKiAgICAgICAgW2Byb2xlc2BdKC9pYW0vcmVmZXJlbmNlL3Jlc3QvdjEvcm9sZXMpLAogICAgICAgKiAgICAgICAgW2Bwcm9qZWN0c2BdKC9pYW0vcmVmZXJlbmNlL3Jlc3QvdjEvcHJvamVjdHMucm9sZXMpLCBvcgogICAgICAgKiAgICAgICAgW2Bvcmdhbml6YXRpb25zYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9vcmdhbml6YXRpb25zLnJvbGVzKS4gRWFjaAogICAgICByZXNvdXJjZSB0eXBlJ3MKICAgICAgICogICAgICAgIGBwYXJlbnRgIHZhbHVlIGZvcm1hdCBpcyBkZXNjcmliZWQgYmVsb3c6CiAgICAgICoKICAgICAgICogICAgICAgIFtgcm9sZXMubGlzdCgpYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9yb2xlcy9saXN0KTogQW4gZW1wdHkgc3RyaW5nLgogICAgICAgIFRoaXMgbWV0aG9kCiAgICAgICAqICAgICAgICBkb2Vzbid0IHJlcXVpcmUgYSByZXNvdXJjZTsgaXQgc2ltcGx5IHJldHVybnMgYWxsCiAgICAgICAgW3ByZWRlZmluZWQgcm9sZXNdKC9pYW0vZG9jcwogICAgICAgKiAgICAgICAgL3VuZGVyc3RhbmRpbmctcm9sZXMjcHJlZGVmaW5lZF9yb2xlcykgaW4KICAgICAgICBDbG91ZCBJQU0uIEV4YW1wbGUgcmVxdWVzdCBVUkw6CiAgICAgICAqICAgICAgICBgaHR0cHM6Ly9pYW0uZ29vZ2xlYXBpcy5jb20vdjEvcm9sZXNgCiAgICAgICoKICAgICAgICogICAgICAgIFtgcHJvamVjdHMucm9sZXMubGlzdCgpYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9wcm9qZWN0cy5yb2xlcy9saXN0KToKICAgICAgICogICAgICAgIGBwcm9qZWN0cy97UFJPSkVDVF9JRH1gLiBUaGlzIG1ldGhvZCBsaXN0cyBhbGwgcHJvamVjdC1sZXZlbAogICAgICAgIFtjdXN0b20gcm9sZXNdKC9pYW0vZG9jcwogICAgICAgKiAgICAgICAgL3VuZGVyc3RhbmRpbmctY3VzdG9tLXJvbGVzKS4KICAgICAgICBFeGFtcGxlIHJlcXVlc3QgVVJMOgogICAgICAgKiAgICAgICAgYGh0dHBzOi8vaWFtLmdvb2dsZWFwaXMuY29tL3YxL3Byb2plY3RzL3tQUk9KRUNUX0lEfS9yb2xlc2AKICAgICAgKgogICAgICAgKiAgICAgICAgW2Bvcmdhbml6YXRpb25zLnJvbGVzLmxpc3QoKWBdKC9pYW0vcmVmZXJlbmNlL3Jlc3QvdjEvb3JnYW5pemF0aW9ucy5yb2xlcy9saXN0KToKICAgICAgICogICAgICAgIGBvcmdhbml6YXRpb25zL3tPUkdBTklaQVRJT05fSUR9YC4gVGhpcyBtZXRob2QgbGlzdHMgYWxsCiAgICAgICAgb3JnYW5pemF0aW9uLWxldmVsIFtjdXN0b20KICAgICAgICogICAgICAgIHJvbGVzXSgvaWFtL2RvY3MvdW5kZXJzdGFuZGluZy1jdXN0b20tcm9sZXMpLgogICAgICAgIEV4YW1wbGUgcmVxdWVzdCBVUkw6CiAgICAgICAqICAgICAgICBgaHR0cHM6Ly9pYW0uZ29vZ2xlYXBpcy5jb20vdjEvb3JnYW5pemF0aW9ucy97T1JHQU5JWkFUSU9OX0lEfS9yb2xlc2AKICAgICAgTm90ZTogV2lsZGNhcmQgKCopCiAgICAgICAqICAgICAgICB2YWx1ZXMgYXJlIGludmFsaWQ7IHlvdSBtdXN0IHNwZWNpZnkgYSBjb21wbGV0ZSBwcm9qZWN0CiAgICAgIElEIG9yIG9yZ2FuaXphdGlvbiBJRC4KICAgICAgICAgKiBAc2luY2UgMS4xMwogICAgICAgICAqLwogICAgICAgIHByb3RlY3RlZCBMaXN0KGphdmEubGFuZy5TdHJpbmcgcGFyZW50KSB7CiAgICAgICAgICBzdXBlcihJYW0udGhpcywgIkdFVCIsIFJFU1RfUEFUSCwgbnVsbCwgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuaWFtLnYxLm1vZGVsLkxpc3RSb2xlc1Jlc3BvbnNlLmNsYXNzKTsKICAgICAgICAgIHRoaXMucGFyZW50ID0gY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuUHJlY29uZGl0aW9ucy5jaGVja05vdE51bGwocGFyZW50LCAiUmVxdWlyZWQgcGFyYW1ldGVyIHBhcmVudCBtdXN0IGJlIHNwZWNpZmllZC4iKTsKICAgICAgICAgIGlmICghZ2V0U3VwcHJlc3NQYXR0ZXJuQ2hlY2tzKCkpIHsKICAgICAgICAgICAgY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuUHJlY29uZGl0aW9ucy5jaGVja0FyZ3VtZW50KFBBUkVOVF9QQVRURVJOLm1hdGNoZXIocGFyZW50KS5tYXRjaGVzKCksCiAgICAgICAgICAgICAgICAiUGFyYW1ldGVyIHBhcmVudCBtdXN0IGNvbmZvcm0gdG8gdGhlIHBhdHRlcm4gIiArCiAgICAgICAgICAgICAgICAiXm9yZ2FuaXphdGlvbnMvW14vXSskIik7CiAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5hcGkuY2xpZW50Lmh0dHAuSHR0cFJlc3BvbnNlIGV4ZWN1dGVVc2luZ0hlYWQoKSB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuZXhlY3V0ZVVzaW5nSGVhZCgpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIGNvbS5nb29nbGUuYXBpLmNsaWVudC5odHRwLkh0dHBSZXF1ZXN0IGJ1aWxkSHR0cFJlcXVlc3RVc2luZ0hlYWQoKSB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuYnVpbGRIdHRwUmVxdWVzdFVzaW5nSGVhZCgpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIExpc3Qgc2V0JFhnYWZ2KGphdmEubGFuZy5TdHJpbmcgJFhnYWZ2KSB7CiAgICAgICAgICByZXR1cm4gKExpc3QpIHN1cGVyLnNldCRYZ2FmdigkWGdhZnYpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIExpc3Qgc2V0QWNjZXNzVG9rZW4oamF2YS5sYW5nLlN0cmluZyBhY2Nlc3NUb2tlbikgewogICAgICAgICAgcmV0dXJuIChMaXN0KSBzdXBlci5zZXRBY2Nlc3NUb2tlbihhY2Nlc3NUb2tlbik7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgTGlzdCBzZXRBbHQoamF2YS5sYW5nLlN0cmluZyBhbHQpIHsKICAgICAgICAgIHJldHVybiAoTGlzdCkgc3VwZXIuc2V0QWx0KGFsdCk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgTGlzdCBzZXRDYWxsYmFjayhqYXZhLmxhbmcuU3RyaW5nIGNhbGxiYWNrKSB7CiAgICAgICAgICByZXR1cm4gKExpc3QpIHN1cGVyLnNldENhbGxiYWNrKGNhbGxiYWNrKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBMaXN0IHNldEZpZWxkcyhqYXZhLmxhbmcuU3RyaW5nIGZpZWxkcykgewogICAgICAgICAgcmV0dXJuIChMaXN0KSBzdXBlci5zZXRGaWVsZHMoZmllbGRzKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBMaXN0IHNldEtleShqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgICAgcmV0dXJuIChMaXN0KSBzdXBlci5zZXRLZXkoa2V5KTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBMaXN0IHNldE9hdXRoVG9rZW4oamF2YS5sYW5nLlN0cmluZyBvYXV0aFRva2VuKSB7CiAgICAgICAgICByZXR1cm4gKExpc3QpIHN1cGVyLnNldE9hdXRoVG9rZW4ob2F1dGhUb2tlbik7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgTGlzdCBzZXRQcmV0dHlQcmludChqYXZhLmxhbmcuQm9vbGVhbiBwcmV0dHlQcmludCkgewogICAgICAgICAgcmV0dXJuIChMaXN0KSBzdXBlci5zZXRQcmV0dHlQcmludChwcmV0dHlQcmludCk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgTGlzdCBzZXRRdW90YVVzZXIoamF2YS5sYW5nLlN0cmluZyBxdW90YVVzZXIpIHsKICAgICAgICAgIHJldHVybiAoTGlzdCkgc3VwZXIuc2V0UXVvdGFVc2VyKHF1b3RhVXNlcik7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgTGlzdCBzZXRVcGxvYWRUeXBlKGphdmEubGFuZy5TdHJpbmcgdXBsb2FkVHlwZSkgewogICAgICAgICAgcmV0dXJuIChMaXN0KSBzdXBlci5zZXRVcGxvYWRUeXBlKHVwbG9hZFR5cGUpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIExpc3Qgc2V0VXBsb2FkUHJvdG9jb2woamF2YS5sYW5nLlN0cmluZyB1cGxvYWRQcm90b2NvbCkgewogICAgICAgICAgcmV0dXJuIChMaXN0KSBzdXBlci5zZXRVcGxvYWRQcm90b2NvbCh1cGxvYWRQcm90b2NvbCk7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiBUaGUgYHBhcmVudGAgcGFyYW1ldGVyJ3MgdmFsdWUgZGVwZW5kcyBvbiB0aGUgdGFyZ2V0IHJlc291cmNlIGZvciB0aGUgcmVxdWVzdCwgbmFtZWx5CiAgICAgICAgICogW2Byb2xlc2BdKC9pYW0vcmVmZXJlbmNlL3Jlc3QvdjEvcm9sZXMpLAogICAgICAgICAqIFtgcHJvamVjdHNgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL3Byb2plY3RzLnJvbGVzKSwgb3IKICAgICAgICAgKiBbYG9yZ2FuaXphdGlvbnNgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL29yZ2FuaXphdGlvbnMucm9sZXMpLiBFYWNoIHJlc291cmNlIHR5cGUncwogICAgICAgICAqIGBwYXJlbnRgIHZhbHVlIGZvcm1hdCBpcyBkZXNjcmliZWQgYmVsb3c6CiAgICAgICAgICoKICAgICAgICAgKiAqIFtgcm9sZXMubGlzdCgpYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9yb2xlcy9saXN0KTogQW4gZW1wdHkgc3RyaW5nLiBUaGlzIG1ldGhvZAogICAgICAgICAqIGRvZXNuJ3QgcmVxdWlyZSBhIHJlc291cmNlOyBpdCBzaW1wbHkgcmV0dXJucyBhbGwgW3ByZWRlZmluZWQgcm9sZXNdKC9pYW0vZG9jcwogICAgICAgICAqIC91bmRlcnN0YW5kaW5nLXJvbGVzI3ByZWRlZmluZWRfcm9sZXMpIGluIENsb3VkIElBTS4gRXhhbXBsZSByZXF1ZXN0IFVSTDoKICAgICAgICAgKiBgaHR0cHM6Ly9pYW0uZ29vZ2xlYXBpcy5jb20vdjEvcm9sZXNgCiAgICAgICAgICoKICAgICAgICAgKiAqIFtgcHJvamVjdHMucm9sZXMubGlzdCgpYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9wcm9qZWN0cy5yb2xlcy9saXN0KToKICAgICAgICAgKiBgcHJvamVjdHMve1BST0pFQ1RfSUR9YC4gVGhpcyBtZXRob2QgbGlzdHMgYWxsIHByb2plY3QtbGV2ZWwgW2N1c3RvbSByb2xlc10oL2lhbS9kb2NzCiAgICAgICAgICogL3VuZGVyc3RhbmRpbmctY3VzdG9tLXJvbGVzKS4gRXhhbXBsZSByZXF1ZXN0IFVSTDoKICAgICAgICAgKiBgaHR0cHM6Ly9pYW0uZ29vZ2xlYXBpcy5jb20vdjEvcHJvamVjdHMve1BST0pFQ1RfSUR9L3JvbGVzYAogICAgICAgICAqCiAgICAgICAgICogKiBbYG9yZ2FuaXphdGlvbnMucm9sZXMubGlzdCgpYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9vcmdhbml6YXRpb25zLnJvbGVzL2xpc3QpOgogICAgICAgICAqIGBvcmdhbml6YXRpb25zL3tPUkdBTklaQVRJT05fSUR9YC4gVGhpcyBtZXRob2QgbGlzdHMgYWxsIG9yZ2FuaXphdGlvbi1sZXZlbCBbY3VzdG9tCiAgICAgICAgICogcm9sZXNdKC9pYW0vZG9jcy91bmRlcnN0YW5kaW5nLWN1c3RvbS1yb2xlcykuIEV4YW1wbGUgcmVxdWVzdCBVUkw6CiAgICAgICAgICogYGh0dHBzOi8vaWFtLmdvb2dsZWFwaXMuY29tL3YxL29yZ2FuaXphdGlvbnMve09SR0FOSVpBVElPTl9JRH0vcm9sZXNgCiAgICAgICAgICoKICAgICAgICAgKiBOb3RlOiBXaWxkY2FyZCAoKikgdmFsdWVzIGFyZSBpbnZhbGlkOyB5b3UgbXVzdCBzcGVjaWZ5IGEgY29tcGxldGUgcHJvamVjdCBJRCBvcgogICAgICAgICAqIG9yZ2FuaXphdGlvbiBJRC4KICAgICAgICAgKi8KICAgICAgICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuU3RyaW5nIHBhcmVudDsKCiAgICAgICAgLyoqIFRoZSBgcGFyZW50YCBwYXJhbWV0ZXIncyB2YWx1ZSBkZXBlbmRzIG9uIHRoZSB0YXJnZXQgcmVzb3VyY2UgZm9yIHRoZSByZXF1ZXN0LCBuYW1lbHkKICAgICAgIFtgcm9sZXNgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL3JvbGVzKSwgW2Bwcm9qZWN0c2BdKC9pYW0vcmVmZXJlbmNlL3Jlc3QvdjEvcHJvamVjdHMucm9sZXMpLCBvcgogICAgICAgW2Bvcmdhbml6YXRpb25zYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9vcmdhbml6YXRpb25zLnJvbGVzKS4gRWFjaCByZXNvdXJjZSB0eXBlJ3MgYHBhcmVudGAgdmFsdWUKICAgICAgIGZvcm1hdCBpcyBkZXNjcmliZWQgYmVsb3c6CgogICAgICAgKiBbYHJvbGVzLmxpc3QoKWBdKC9pYW0vcmVmZXJlbmNlL3Jlc3QvdjEvcm9sZXMvbGlzdCk6IEFuIGVtcHR5IHN0cmluZy4gVGhpcyBtZXRob2QgZG9lc24ndCByZXF1aXJlCiAgICAgICBhIHJlc291cmNlOyBpdCBzaW1wbHkgcmV0dXJucyBhbGwgW3ByZWRlZmluZWQgcm9sZXNdKC9pYW0vZG9jcy91bmRlcnN0YW5kaW5nLQogICAgICAgcm9sZXMjcHJlZGVmaW5lZF9yb2xlcykgaW4gQ2xvdWQgSUFNLiBFeGFtcGxlIHJlcXVlc3QgVVJMOiBgaHR0cHM6Ly9pYW0uZ29vZ2xlYXBpcy5jb20vdjEvcm9sZXNgCgogICAgICAgKiBbYHByb2plY3RzLnJvbGVzLmxpc3QoKWBdKC9pYW0vcmVmZXJlbmNlL3Jlc3QvdjEvcHJvamVjdHMucm9sZXMvbGlzdCk6IGBwcm9qZWN0cy97UFJPSkVDVF9JRH1gLgogICAgICAgVGhpcyBtZXRob2QgbGlzdHMgYWxsIHByb2plY3QtbGV2ZWwgW2N1c3RvbSByb2xlc10oL2lhbS9kb2NzL3VuZGVyc3RhbmRpbmctY3VzdG9tLXJvbGVzKS4gRXhhbXBsZQogICAgICAgcmVxdWVzdCBVUkw6IGBodHRwczovL2lhbS5nb29nbGVhcGlzLmNvbS92MS9wcm9qZWN0cy97UFJPSkVDVF9JRH0vcm9sZXNgCgogICAgICAgKiBbYG9yZ2FuaXphdGlvbnMucm9sZXMubGlzdCgpYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9vcmdhbml6YXRpb25zLnJvbGVzL2xpc3QpOgogICAgICAgYG9yZ2FuaXphdGlvbnMve09SR0FOSVpBVElPTl9JRH1gLiBUaGlzIG1ldGhvZCBsaXN0cyBhbGwgb3JnYW5pemF0aW9uLWxldmVsIFtjdXN0b20KICAgICAgIHJvbGVzXSgvaWFtL2RvY3MvdW5kZXJzdGFuZGluZy1jdXN0b20tcm9sZXMpLiBFeGFtcGxlIHJlcXVlc3QgVVJMOgogICAgICAgYGh0dHBzOi8vaWFtLmdvb2dsZWFwaXMuY29tL3YxL29yZ2FuaXphdGlvbnMve09SR0FOSVpBVElPTl9JRH0vcm9sZXNgCgogICAgICAgTm90ZTogV2lsZGNhcmQgKCopIHZhbHVlcyBhcmUgaW52YWxpZDsgeW91IG11c3Qgc3BlY2lmeSBhIGNvbXBsZXRlIHByb2plY3QgSUQgb3Igb3JnYW5pemF0aW9uIElELgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFBhcmVudCgpIHsKICAgICAgICAgIHJldHVybiBwYXJlbnQ7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiBUaGUgYHBhcmVudGAgcGFyYW1ldGVyJ3MgdmFsdWUgZGVwZW5kcyBvbiB0aGUgdGFyZ2V0IHJlc291cmNlIGZvciB0aGUgcmVxdWVzdCwgbmFtZWx5CiAgICAgICAgICogW2Byb2xlc2BdKC9pYW0vcmVmZXJlbmNlL3Jlc3QvdjEvcm9sZXMpLAogICAgICAgICAqIFtgcHJvamVjdHNgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL3Byb2plY3RzLnJvbGVzKSwgb3IKICAgICAgICAgKiBbYG9yZ2FuaXphdGlvbnNgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL29yZ2FuaXphdGlvbnMucm9sZXMpLiBFYWNoIHJlc291cmNlIHR5cGUncwogICAgICAgICAqIGBwYXJlbnRgIHZhbHVlIGZvcm1hdCBpcyBkZXNjcmliZWQgYmVsb3c6CiAgICAgICAgICoKICAgICAgICAgKiAqIFtgcm9sZXMubGlzdCgpYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9yb2xlcy9saXN0KTogQW4gZW1wdHkgc3RyaW5nLiBUaGlzIG1ldGhvZAogICAgICAgICAqIGRvZXNuJ3QgcmVxdWlyZSBhIHJlc291cmNlOyBpdCBzaW1wbHkgcmV0dXJucyBhbGwgW3ByZWRlZmluZWQgcm9sZXNdKC9pYW0vZG9jcwogICAgICAgICAqIC91bmRlcnN0YW5kaW5nLXJvbGVzI3ByZWRlZmluZWRfcm9sZXMpIGluIENsb3VkIElBTS4gRXhhbXBsZSByZXF1ZXN0IFVSTDoKICAgICAgICAgKiBgaHR0cHM6Ly9pYW0uZ29vZ2xlYXBpcy5jb20vdjEvcm9sZXNgCiAgICAgICAgICoKICAgICAgICAgKiAqIFtgcHJvamVjdHMucm9sZXMubGlzdCgpYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9wcm9qZWN0cy5yb2xlcy9saXN0KToKICAgICAgICAgKiBgcHJvamVjdHMve1BST0pFQ1RfSUR9YC4gVGhpcyBtZXRob2QgbGlzdHMgYWxsIHByb2plY3QtbGV2ZWwgW2N1c3RvbSByb2xlc10oL2lhbS9kb2NzCiAgICAgICAgICogL3VuZGVyc3RhbmRpbmctY3VzdG9tLXJvbGVzKS4gRXhhbXBsZSByZXF1ZXN0IFVSTDoKICAgICAgICAgKiBgaHR0cHM6Ly9pYW0uZ29vZ2xlYXBpcy5jb20vdjEvcHJvamVjdHMve1BST0pFQ1RfSUR9L3JvbGVzYAogICAgICAgICAqCiAgICAgICAgICogKiBbYG9yZ2FuaXphdGlvbnMucm9sZXMubGlzdCgpYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9vcmdhbml6YXRpb25zLnJvbGVzL2xpc3QpOgogICAgICAgICAqIGBvcmdhbml6YXRpb25zL3tPUkdBTklaQVRJT05fSUR9YC4gVGhpcyBtZXRob2QgbGlzdHMgYWxsIG9yZ2FuaXphdGlvbi1sZXZlbCBbY3VzdG9tCiAgICAgICAgICogcm9sZXNdKC9pYW0vZG9jcy91bmRlcnN0YW5kaW5nLWN1c3RvbS1yb2xlcykuIEV4YW1wbGUgcmVxdWVzdCBVUkw6CiAgICAgICAgICogYGh0dHBzOi8vaWFtLmdvb2dsZWFwaXMuY29tL3YxL29yZ2FuaXphdGlvbnMve09SR0FOSVpBVElPTl9JRH0vcm9sZXNgCiAgICAgICAgICoKICAgICAgICAgKiBOb3RlOiBXaWxkY2FyZCAoKikgdmFsdWVzIGFyZSBpbnZhbGlkOyB5b3UgbXVzdCBzcGVjaWZ5IGEgY29tcGxldGUgcHJvamVjdCBJRCBvcgogICAgICAgICAqIG9yZ2FuaXphdGlvbiBJRC4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgTGlzdCBzZXRQYXJlbnQoamF2YS5sYW5nLlN0cmluZyBwYXJlbnQpIHsKICAgICAgICAgIGlmICghZ2V0U3VwcHJlc3NQYXR0ZXJuQ2hlY2tzKCkpIHsKICAgICAgICAgICAgY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuUHJlY29uZGl0aW9ucy5jaGVja0FyZ3VtZW50KFBBUkVOVF9QQVRURVJOLm1hdGNoZXIocGFyZW50KS5tYXRjaGVzKCksCiAgICAgICAgICAgICAgICAiUGFyYW1ldGVyIHBhcmVudCBtdXN0IGNvbmZvcm0gdG8gdGhlIHBhdHRlcm4gIiArCiAgICAgICAgICAgICAgICAiXm9yZ2FuaXphdGlvbnMvW14vXSskIik7CiAgICAgICAgICB9CiAgICAgICAgICB0aGlzLnBhcmVudCA9IHBhcmVudDsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KCiAgICAgICAgLyoqIEluY2x1ZGUgUm9sZXMgdGhhdCBoYXZlIGJlZW4gZGVsZXRlZC4gKi8KICAgICAgICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuQm9vbGVhbiBzaG93RGVsZXRlZDsKCiAgICAgICAgLyoqIEluY2x1ZGUgUm9sZXMgdGhhdCBoYXZlIGJlZW4gZGVsZXRlZC4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgamF2YS5sYW5nLkJvb2xlYW4gZ2V0U2hvd0RlbGV0ZWQoKSB7CiAgICAgICAgICByZXR1cm4gc2hvd0RlbGV0ZWQ7CiAgICAgICAgfQoKICAgICAgICAvKiogSW5jbHVkZSBSb2xlcyB0aGF0IGhhdmUgYmVlbiBkZWxldGVkLiAqLwogICAgICAgIHB1YmxpYyBMaXN0IHNldFNob3dEZWxldGVkKGphdmEubGFuZy5Cb29sZWFuIHNob3dEZWxldGVkKSB7CiAgICAgICAgICB0aGlzLnNob3dEZWxldGVkID0gc2hvd0RlbGV0ZWQ7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CgogICAgICAgIC8qKiBPcHRpb25hbCBwYWdpbmF0aW9uIHRva2VuIHJldHVybmVkIGluIGFuIGVhcmxpZXIgTGlzdFJvbGVzUmVzcG9uc2UuICovCiAgICAgICAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogICAgICAgIHByaXZhdGUgamF2YS5sYW5nLlN0cmluZyBwYWdlVG9rZW47CgogICAgICAgIC8qKiBPcHRpb25hbCBwYWdpbmF0aW9uIHRva2VuIHJldHVybmVkIGluIGFuIGVhcmxpZXIgTGlzdFJvbGVzUmVzcG9uc2UuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0UGFnZVRva2VuKCkgewogICAgICAgICAgcmV0dXJuIHBhZ2VUb2tlbjsKICAgICAgICB9CgogICAgICAgIC8qKiBPcHRpb25hbCBwYWdpbmF0aW9uIHRva2VuIHJldHVybmVkIGluIGFuIGVhcmxpZXIgTGlzdFJvbGVzUmVzcG9uc2UuICovCiAgICAgICAgcHVibGljIExpc3Qgc2V0UGFnZVRva2VuKGphdmEubGFuZy5TdHJpbmcgcGFnZVRva2VuKSB7CiAgICAgICAgICB0aGlzLnBhZ2VUb2tlbiA9IHBhZ2VUb2tlbjsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KCiAgICAgICAgLyoqIE9wdGlvbmFsIGxpbWl0IG9uIHRoZSBudW1iZXIgb2Ygcm9sZXMgdG8gaW5jbHVkZSBpbiB0aGUgcmVzcG9uc2UuICovCiAgICAgICAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogICAgICAgIHByaXZhdGUgamF2YS5sYW5nLkludGVnZXIgcGFnZVNpemU7CgogICAgICAgIC8qKiBPcHRpb25hbCBsaW1pdCBvbiB0aGUgbnVtYmVyIG9mIHJvbGVzIHRvIGluY2x1ZGUgaW4gdGhlIHJlc3BvbnNlLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBqYXZhLmxhbmcuSW50ZWdlciBnZXRQYWdlU2l6ZSgpIHsKICAgICAgICAgIHJldHVybiBwYWdlU2l6ZTsKICAgICAgICB9CgogICAgICAgIC8qKiBPcHRpb25hbCBsaW1pdCBvbiB0aGUgbnVtYmVyIG9mIHJvbGVzIHRvIGluY2x1ZGUgaW4gdGhlIHJlc3BvbnNlLiAqLwogICAgICAgIHB1YmxpYyBMaXN0IHNldFBhZ2VTaXplKGphdmEubGFuZy5JbnRlZ2VyIHBhZ2VTaXplKSB7CiAgICAgICAgICB0aGlzLnBhZ2VTaXplID0gcGFnZVNpemU7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIE9wdGlvbmFsIHZpZXcgZm9yIHRoZSByZXR1cm5lZCBSb2xlIG9iamVjdHMuIFdoZW4gYEZVTExgIGlzIHNwZWNpZmllZCwgdGhlCiAgICAgICAgICogYGluY2x1ZGVkUGVybWlzc2lvbnNgIGZpZWxkIGlzIHJldHVybmVkLCB3aGljaCBpbmNsdWRlcyBhIGxpc3Qgb2YgYWxsIHBlcm1pc3Npb25zIGluIHRoZQogICAgICAgICAqIHJvbGUuIFRoZSBkZWZhdWx0IHZhbHVlIGlzIGBCQVNJQ2AsIHdoaWNoIGRvZXMgbm90IHJldHVybiB0aGUgYGluY2x1ZGVkUGVybWlzc2lvbnNgCiAgICAgICAgICogZmllbGQuCiAgICAgICAgICovCiAgICAgICAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogICAgICAgIHByaXZhdGUgamF2YS5sYW5nLlN0cmluZyB2aWV3OwoKICAgICAgICAvKiogT3B0aW9uYWwgdmlldyBmb3IgdGhlIHJldHVybmVkIFJvbGUgb2JqZWN0cy4gV2hlbiBgRlVMTGAgaXMgc3BlY2lmaWVkLCB0aGUgYGluY2x1ZGVkUGVybWlzc2lvbnNgCiAgICAgICBmaWVsZCBpcyByZXR1cm5lZCwgd2hpY2ggaW5jbHVkZXMgYSBsaXN0IG9mIGFsbCBwZXJtaXNzaW9ucyBpbiB0aGUgcm9sZS4gVGhlIGRlZmF1bHQgdmFsdWUgaXMKICAgICAgIGBCQVNJQ2AsIHdoaWNoIGRvZXMgbm90IHJldHVybiB0aGUgYGluY2x1ZGVkUGVybWlzc2lvbnNgIGZpZWxkLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFZpZXcoKSB7CiAgICAgICAgICByZXR1cm4gdmlldzsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIE9wdGlvbmFsIHZpZXcgZm9yIHRoZSByZXR1cm5lZCBSb2xlIG9iamVjdHMuIFdoZW4gYEZVTExgIGlzIHNwZWNpZmllZCwgdGhlCiAgICAgICAgICogYGluY2x1ZGVkUGVybWlzc2lvbnNgIGZpZWxkIGlzIHJldHVybmVkLCB3aGljaCBpbmNsdWRlcyBhIGxpc3Qgb2YgYWxsIHBlcm1pc3Npb25zIGluIHRoZQogICAgICAgICAqIHJvbGUuIFRoZSBkZWZhdWx0IHZhbHVlIGlzIGBCQVNJQ2AsIHdoaWNoIGRvZXMgbm90IHJldHVybiB0aGUgYGluY2x1ZGVkUGVybWlzc2lvbnNgCiAgICAgICAgICogZmllbGQuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIExpc3Qgc2V0VmlldyhqYXZhLmxhbmcuU3RyaW5nIHZpZXcpIHsKICAgICAgICAgIHRoaXMudmlldyA9IHZpZXc7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBMaXN0IHNldChTdHJpbmcgcGFyYW1ldGVyTmFtZSwgT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgICByZXR1cm4gKExpc3QpIHN1cGVyLnNldChwYXJhbWV0ZXJOYW1lLCB2YWx1ZSk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBVcGRhdGVzIGEgUm9sZSBkZWZpbml0aW9uLgogICAgICAgKgogICAgICAgKiBDcmVhdGUgYSByZXF1ZXN0IGZvciB0aGUgbWV0aG9kICJyb2xlcy5wYXRjaCIuCiAgICAgICAqCiAgICAgICAqIFRoaXMgcmVxdWVzdCBob2xkcyB0aGUgcGFyYW1ldGVycyBuZWVkZWQgYnkgdGhlIGlhbSBzZXJ2ZXIuICBBZnRlciBzZXR0aW5nIGFueSBvcHRpb25hbAogICAgICAgKiBwYXJhbWV0ZXJzLCBjYWxsIHRoZSB7QGxpbmsgUGF0Y2gjZXhlY3V0ZSgpfSBtZXRob2QgdG8gaW52b2tlIHRoZSByZW1vdGUgb3BlcmF0aW9uLgogICAgICAgKgogICAgICAgKiBAcGFyYW0gbmFtZSBUaGUgYG5hbWVgIHBhcmFtZXRlcidzIHZhbHVlIGRlcGVuZHMgb24gdGhlIHRhcmdldCByZXNvdXJjZSBmb3IgdGhlCiAgICAgIHJlcXVlc3QsIG5hbWVseQogICAgICAgKiAgICAgICAgW2Bwcm9qZWN0c2BdKC9pYW0vcmVmZXJlbmNlL3Jlc3QvdjEvcHJvamVjdHMucm9sZXMpIG9yCiAgICAgICAqICAgICAgICBbYG9yZ2FuaXphdGlvbnNgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL29yZ2FuaXphdGlvbnMucm9sZXMpLiBFYWNoCiAgICAgIHJlc291cmNlIHR5cGUncyBgbmFtZWAKICAgICAgICogICAgICAgIHZhbHVlIGZvcm1hdCBpcyBkZXNjcmliZWQgYmVsb3c6CiAgICAgICoKICAgICAgICogICAgICAgIFtgcHJvamVjdHMucm9sZXMucGF0Y2goKWBdKC9pYW0vcmVmZXJlbmNlL3Jlc3QvdjEvcHJvamVjdHMucm9sZXMvcGF0Y2gpOgogICAgICAgKiAgICAgICAgYHByb2plY3RzL3tQUk9KRUNUX0lEfS9yb2xlcy97Q1VTVE9NX1JPTEVfSUR9YC4gVGhpcyBtZXRob2QgdXBkYXRlcyBvbmx5CiAgICAgICAgW2N1c3RvbQogICAgICAgKiAgICAgICAgcm9sZXNdKC9pYW0vZG9jcy91bmRlcnN0YW5kaW5nLWN1c3RvbS1yb2xlcykgdGhhdCBoYXZlIGJlZW4KICAgICAgICBjcmVhdGVkIGF0IHRoZSBwcm9qZWN0CiAgICAgICAqICAgICAgICBsZXZlbC4gRXhhbXBsZSByZXF1ZXN0IFVSTDoKICAgICAgICogICAgICAgIGBodHRwczovL2lhbS5nb29nbGVhcGlzLmNvbS92MS9wcm9qZWN0cy97UFJPSkVDVF9JRH0vcm9sZXMve0NVU1RPTV9ST0xFX0lEfWAKICAgICAgKgogICAgICAgKiAgICAgICAgW2Bvcmdhbml6YXRpb25zLnJvbGVzLnBhdGNoKClgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL29yZ2FuaXphdGlvbnMucm9sZXMvcGF0Y2gpOgogICAgICAgKiAgICAgICAgYG9yZ2FuaXphdGlvbnMve09SR0FOSVpBVElPTl9JRH0vcm9sZXMve0NVU1RPTV9ST0xFX0lEfWAuIFRoaXMgbWV0aG9kCiAgICAgICAgdXBkYXRlcyBvbmx5CiAgICAgICAqICAgICAgICBbY3VzdG9tIHJvbGVzXSgvaWFtL2RvY3MvdW5kZXJzdGFuZGluZy1jdXN0b20tcm9sZXMpIHRoYXQKICAgICAgICBoYXZlIGJlZW4gY3JlYXRlZCBhdCB0aGUKICAgICAgICogICAgICAgIG9yZ2FuaXphdGlvbiBsZXZlbC4gRXhhbXBsZSByZXF1ZXN0IFVSTDoKICAgICAgICogICAgICAgIGBodHRwczovL2lhbS5nb29nbGVhcGlzLmNvbS92MS9vcmdhbml6YXRpb25zL3tPUkdBTklaQVRJT05fSUR9L3JvbGVzL3tDVVNUT01fUk9MRV9JRH1gCiAgICAgICAqICAgICAgICBOb3RlOiBXaWxkY2FyZCAoKikgdmFsdWVzIGFyZSBpbnZhbGlkOyB5b3UgbXVzdCBzcGVjaWZ5IGEgY29tcGxldGUgcHJvamVjdAogICAgICBJRCBvcgogICAgICAgKiAgICAgICAgb3JnYW5pemF0aW9uIElELgogICAgICAgKiBAcGFyYW0gY29udGVudCB0aGUge0BsaW5rIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmlhbS52MS5tb2RlbC5Sb2xlfQogICAgICAgKiBAcmV0dXJuIHRoZSByZXF1ZXN0CiAgICAgICAqLwogICAgICBwdWJsaWMgUGF0Y2ggcGF0Y2goamF2YS5sYW5nLlN0cmluZyBuYW1lLCBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5pYW0udjEubW9kZWwuUm9sZSBjb250ZW50KSB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgUGF0Y2ggcmVzdWx0ID0gbmV3IFBhdGNoKG5hbWUsIGNvbnRlbnQpOwogICAgICAgIGluaXRpYWxpemUocmVzdWx0KTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBwdWJsaWMgY2xhc3MgUGF0Y2ggZXh0ZW5kcyBJYW1SZXF1ZXN0PGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmlhbS52MS5tb2RlbC5Sb2xlPiB7CgogICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBSRVNUX1BBVEggPSAidjEveytuYW1lfSI7CgogICAgICAgIHByaXZhdGUgZmluYWwgamF2YS51dGlsLnJlZ2V4LlBhdHRlcm4gTkFNRV9QQVRURVJOID0KICAgICAgICAgICAgamF2YS51dGlsLnJlZ2V4LlBhdHRlcm4uY29tcGlsZSgiXm9yZ2FuaXphdGlvbnMvW14vXSsvcm9sZXMvW14vXSskIik7CgogICAgICAgIC8qKgogICAgICAgICAqIFVwZGF0ZXMgYSBSb2xlIGRlZmluaXRpb24uCiAgICAgICAgICoKICAgICAgICAgKiBDcmVhdGUgYSByZXF1ZXN0IGZvciB0aGUgbWV0aG9kICJyb2xlcy5wYXRjaCIuCiAgICAgICAgICoKICAgICAgICAgKiBUaGlzIHJlcXVlc3QgaG9sZHMgdGhlIHBhcmFtZXRlcnMgbmVlZGVkIGJ5IHRoZSB0aGUgaWFtIHNlcnZlci4gIEFmdGVyIHNldHRpbmcgYW55IG9wdGlvbmFsCiAgICAgICAgICogcGFyYW1ldGVycywgY2FsbCB0aGUge0BsaW5rIFBhdGNoI2V4ZWN1dGUoKX0gbWV0aG9kIHRvIGludm9rZSB0aGUgcmVtb3RlIG9wZXJhdGlvbi4gPHA+IHtAbGluawogICAgICAgICAqIFBhdGNoI2luaXRpYWxpemUoY29tLmdvb2dsZS5hcGkuY2xpZW50Lmdvb2dsZWFwaXMuc2VydmljZXMuQWJzdHJhY3RHb29nbGVDbGllbnRSZXF1ZXN0KX0gbXVzdAogICAgICAgICAqIGJlIGNhbGxlZCB0byBpbml0aWFsaXplIHRoaXMgaW5zdGFuY2UgaW1tZWRpYXRlbHkgYWZ0ZXIgaW52b2tpbmcgdGhlIGNvbnN0cnVjdG9yLiA8L3A+CiAgICAgICAgICoKICAgICAgICAgKiBAcGFyYW0gbmFtZSBUaGUgYG5hbWVgIHBhcmFtZXRlcidzIHZhbHVlIGRlcGVuZHMgb24gdGhlIHRhcmdldCByZXNvdXJjZSBmb3IgdGhlCiAgICAgIHJlcXVlc3QsIG5hbWVseQogICAgICAgKiAgICAgICAgW2Bwcm9qZWN0c2BdKC9pYW0vcmVmZXJlbmNlL3Jlc3QvdjEvcHJvamVjdHMucm9sZXMpIG9yCiAgICAgICAqICAgICAgICBbYG9yZ2FuaXphdGlvbnNgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL29yZ2FuaXphdGlvbnMucm9sZXMpLiBFYWNoCiAgICAgIHJlc291cmNlIHR5cGUncyBgbmFtZWAKICAgICAgICogICAgICAgIHZhbHVlIGZvcm1hdCBpcyBkZXNjcmliZWQgYmVsb3c6CiAgICAgICoKICAgICAgICogICAgICAgIFtgcHJvamVjdHMucm9sZXMucGF0Y2goKWBdKC9pYW0vcmVmZXJlbmNlL3Jlc3QvdjEvcHJvamVjdHMucm9sZXMvcGF0Y2gpOgogICAgICAgKiAgICAgICAgYHByb2plY3RzL3tQUk9KRUNUX0lEfS9yb2xlcy97Q1VTVE9NX1JPTEVfSUR9YC4gVGhpcyBtZXRob2QgdXBkYXRlcyBvbmx5CiAgICAgICAgW2N1c3RvbQogICAgICAgKiAgICAgICAgcm9sZXNdKC9pYW0vZG9jcy91bmRlcnN0YW5kaW5nLWN1c3RvbS1yb2xlcykgdGhhdCBoYXZlIGJlZW4KICAgICAgICBjcmVhdGVkIGF0IHRoZSBwcm9qZWN0CiAgICAgICAqICAgICAgICBsZXZlbC4gRXhhbXBsZSByZXF1ZXN0IFVSTDoKICAgICAgICogICAgICAgIGBodHRwczovL2lhbS5nb29nbGVhcGlzLmNvbS92MS9wcm9qZWN0cy97UFJPSkVDVF9JRH0vcm9sZXMve0NVU1RPTV9ST0xFX0lEfWAKICAgICAgKgogICAgICAgKiAgICAgICAgW2Bvcmdhbml6YXRpb25zLnJvbGVzLnBhdGNoKClgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL29yZ2FuaXphdGlvbnMucm9sZXMvcGF0Y2gpOgogICAgICAgKiAgICAgICAgYG9yZ2FuaXphdGlvbnMve09SR0FOSVpBVElPTl9JRH0vcm9sZXMve0NVU1RPTV9ST0xFX0lEfWAuIFRoaXMgbWV0aG9kCiAgICAgICAgdXBkYXRlcyBvbmx5CiAgICAgICAqICAgICAgICBbY3VzdG9tIHJvbGVzXSgvaWFtL2RvY3MvdW5kZXJzdGFuZGluZy1jdXN0b20tcm9sZXMpIHRoYXQKICAgICAgICBoYXZlIGJlZW4gY3JlYXRlZCBhdCB0aGUKICAgICAgICogICAgICAgIG9yZ2FuaXphdGlvbiBsZXZlbC4gRXhhbXBsZSByZXF1ZXN0IFVSTDoKICAgICAgICogICAgICAgIGBodHRwczovL2lhbS5nb29nbGVhcGlzLmNvbS92MS9vcmdhbml6YXRpb25zL3tPUkdBTklaQVRJT05fSUR9L3JvbGVzL3tDVVNUT01fUk9MRV9JRH1gCiAgICAgICAqICAgICAgICBOb3RlOiBXaWxkY2FyZCAoKikgdmFsdWVzIGFyZSBpbnZhbGlkOyB5b3UgbXVzdCBzcGVjaWZ5IGEgY29tcGxldGUgcHJvamVjdAogICAgICBJRCBvcgogICAgICAgKiAgICAgICAgb3JnYW5pemF0aW9uIElELgogICAgICAgICAqIEBwYXJhbSBjb250ZW50IHRoZSB7QGxpbmsgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuaWFtLnYxLm1vZGVsLlJvbGV9CiAgICAgICAgICogQHNpbmNlIDEuMTMKICAgICAgICAgKi8KICAgICAgICBwcm90ZWN0ZWQgUGF0Y2goamF2YS5sYW5nLlN0cmluZyBuYW1lLCBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5pYW0udjEubW9kZWwuUm9sZSBjb250ZW50KSB7CiAgICAgICAgICBzdXBlcihJYW0udGhpcywgIlBBVENIIiwgUkVTVF9QQVRILCBjb250ZW50LCBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5pYW0udjEubW9kZWwuUm9sZS5jbGFzcyk7CiAgICAgICAgICB0aGlzLm5hbWUgPSBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5QcmVjb25kaXRpb25zLmNoZWNrTm90TnVsbChuYW1lLCAiUmVxdWlyZWQgcGFyYW1ldGVyIG5hbWUgbXVzdCBiZSBzcGVjaWZpZWQuIik7CiAgICAgICAgICBpZiAoIWdldFN1cHByZXNzUGF0dGVybkNoZWNrcygpKSB7CiAgICAgICAgICAgIGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLlByZWNvbmRpdGlvbnMuY2hlY2tBcmd1bWVudChOQU1FX1BBVFRFUk4ubWF0Y2hlcihuYW1lKS5tYXRjaGVzKCksCiAgICAgICAgICAgICAgICAiUGFyYW1ldGVyIG5hbWUgbXVzdCBjb25mb3JtIHRvIHRoZSBwYXR0ZXJuICIgKwogICAgICAgICAgICAgICAgIl5vcmdhbml6YXRpb25zL1teL10rL3JvbGVzL1teL10rJCIpOwogICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFBhdGNoIHNldCRYZ2FmdihqYXZhLmxhbmcuU3RyaW5nICRYZ2FmdikgewogICAgICAgICAgcmV0dXJuIChQYXRjaCkgc3VwZXIuc2V0JFhnYWZ2KCRYZ2Fmdik7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgUGF0Y2ggc2V0QWNjZXNzVG9rZW4oamF2YS5sYW5nLlN0cmluZyBhY2Nlc3NUb2tlbikgewogICAgICAgICAgcmV0dXJuIChQYXRjaCkgc3VwZXIuc2V0QWNjZXNzVG9rZW4oYWNjZXNzVG9rZW4pOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFBhdGNoIHNldEFsdChqYXZhLmxhbmcuU3RyaW5nIGFsdCkgewogICAgICAgICAgcmV0dXJuIChQYXRjaCkgc3VwZXIuc2V0QWx0KGFsdCk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgUGF0Y2ggc2V0Q2FsbGJhY2soamF2YS5sYW5nLlN0cmluZyBjYWxsYmFjaykgewogICAgICAgICAgcmV0dXJuIChQYXRjaCkgc3VwZXIuc2V0Q2FsbGJhY2soY2FsbGJhY2spOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFBhdGNoIHNldEZpZWxkcyhqYXZhLmxhbmcuU3RyaW5nIGZpZWxkcykgewogICAgICAgICAgcmV0dXJuIChQYXRjaCkgc3VwZXIuc2V0RmllbGRzKGZpZWxkcyk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgUGF0Y2ggc2V0S2V5KGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgICByZXR1cm4gKFBhdGNoKSBzdXBlci5zZXRLZXkoa2V5KTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBQYXRjaCBzZXRPYXV0aFRva2VuKGphdmEubGFuZy5TdHJpbmcgb2F1dGhUb2tlbikgewogICAgICAgICAgcmV0dXJuIChQYXRjaCkgc3VwZXIuc2V0T2F1dGhUb2tlbihvYXV0aFRva2VuKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBQYXRjaCBzZXRQcmV0dHlQcmludChqYXZhLmxhbmcuQm9vbGVhbiBwcmV0dHlQcmludCkgewogICAgICAgICAgcmV0dXJuIChQYXRjaCkgc3VwZXIuc2V0UHJldHR5UHJpbnQocHJldHR5UHJpbnQpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFBhdGNoIHNldFF1b3RhVXNlcihqYXZhLmxhbmcuU3RyaW5nIHF1b3RhVXNlcikgewogICAgICAgICAgcmV0dXJuIChQYXRjaCkgc3VwZXIuc2V0UXVvdGFVc2VyKHF1b3RhVXNlcik7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgUGF0Y2ggc2V0VXBsb2FkVHlwZShqYXZhLmxhbmcuU3RyaW5nIHVwbG9hZFR5cGUpIHsKICAgICAgICAgIHJldHVybiAoUGF0Y2gpIHN1cGVyLnNldFVwbG9hZFR5cGUodXBsb2FkVHlwZSk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgUGF0Y2ggc2V0VXBsb2FkUHJvdG9jb2woamF2YS5sYW5nLlN0cmluZyB1cGxvYWRQcm90b2NvbCkgewogICAgICAgICAgcmV0dXJuIChQYXRjaCkgc3VwZXIuc2V0VXBsb2FkUHJvdG9jb2wodXBsb2FkUHJvdG9jb2wpOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogVGhlIGBuYW1lYCBwYXJhbWV0ZXIncyB2YWx1ZSBkZXBlbmRzIG9uIHRoZSB0YXJnZXQgcmVzb3VyY2UgZm9yIHRoZSByZXF1ZXN0LCBuYW1lbHkKICAgICAgICAgKiBbYHByb2plY3RzYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9wcm9qZWN0cy5yb2xlcykgb3IKICAgICAgICAgKiBbYG9yZ2FuaXphdGlvbnNgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL29yZ2FuaXphdGlvbnMucm9sZXMpLiBFYWNoIHJlc291cmNlIHR5cGUncwogICAgICAgICAqIGBuYW1lYCB2YWx1ZSBmb3JtYXQgaXMgZGVzY3JpYmVkIGJlbG93OgogICAgICAgICAqCiAgICAgICAgICogKiBbYHByb2plY3RzLnJvbGVzLnBhdGNoKClgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL3Byb2plY3RzLnJvbGVzL3BhdGNoKToKICAgICAgICAgKiBgcHJvamVjdHMve1BST0pFQ1RfSUR9L3JvbGVzL3tDVVNUT01fUk9MRV9JRH1gLiBUaGlzIG1ldGhvZCB1cGRhdGVzIG9ubHkgW2N1c3RvbQogICAgICAgICAqIHJvbGVzXSgvaWFtL2RvY3MvdW5kZXJzdGFuZGluZy1jdXN0b20tcm9sZXMpIHRoYXQgaGF2ZSBiZWVuIGNyZWF0ZWQgYXQgdGhlIHByb2plY3QgbGV2ZWwuCiAgICAgICAgICogRXhhbXBsZSByZXF1ZXN0IFVSTDoKICAgICAgICAgKiBgaHR0cHM6Ly9pYW0uZ29vZ2xlYXBpcy5jb20vdjEvcHJvamVjdHMve1BST0pFQ1RfSUR9L3JvbGVzL3tDVVNUT01fUk9MRV9JRH1gCiAgICAgICAgICoKICAgICAgICAgKiAqIFtgb3JnYW5pemF0aW9ucy5yb2xlcy5wYXRjaCgpYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9vcmdhbml6YXRpb25zLnJvbGVzL3BhdGNoKToKICAgICAgICAgKiBgb3JnYW5pemF0aW9ucy97T1JHQU5JWkFUSU9OX0lEfS9yb2xlcy97Q1VTVE9NX1JPTEVfSUR9YC4gVGhpcyBtZXRob2QgdXBkYXRlcyBvbmx5CiAgICAgICAgICogW2N1c3RvbSByb2xlc10oL2lhbS9kb2NzL3VuZGVyc3RhbmRpbmctY3VzdG9tLXJvbGVzKSB0aGF0IGhhdmUgYmVlbiBjcmVhdGVkIGF0IHRoZQogICAgICAgICAqIG9yZ2FuaXphdGlvbiBsZXZlbC4gRXhhbXBsZSByZXF1ZXN0IFVSTDoKICAgICAgICAgKiBgaHR0cHM6Ly9pYW0uZ29vZ2xlYXBpcy5jb20vdjEvb3JnYW5pemF0aW9ucy97T1JHQU5JWkFUSU9OX0lEfS9yb2xlcy97Q1VTVE9NX1JPTEVfSUR9YAogICAgICAgICAqCiAgICAgICAgICogTm90ZTogV2lsZGNhcmQgKCopIHZhbHVlcyBhcmUgaW52YWxpZDsgeW91IG11c3Qgc3BlY2lmeSBhIGNvbXBsZXRlIHByb2plY3QgSUQgb3IKICAgICAgICAgKiBvcmdhbml6YXRpb24gSUQuCiAgICAgICAgICovCiAgICAgICAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogICAgICAgIHByaXZhdGUgamF2YS5sYW5nLlN0cmluZyBuYW1lOwoKICAgICAgICAvKiogVGhlIGBuYW1lYCBwYXJhbWV0ZXIncyB2YWx1ZSBkZXBlbmRzIG9uIHRoZSB0YXJnZXQgcmVzb3VyY2UgZm9yIHRoZSByZXF1ZXN0LCBuYW1lbHkKICAgICAgIFtgcHJvamVjdHNgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL3Byb2plY3RzLnJvbGVzKSBvcgogICAgICAgW2Bvcmdhbml6YXRpb25zYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9vcmdhbml6YXRpb25zLnJvbGVzKS4gRWFjaCByZXNvdXJjZSB0eXBlJ3MgYG5hbWVgIHZhbHVlCiAgICAgICBmb3JtYXQgaXMgZGVzY3JpYmVkIGJlbG93OgoKICAgICAgICogW2Bwcm9qZWN0cy5yb2xlcy5wYXRjaCgpYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9wcm9qZWN0cy5yb2xlcy9wYXRjaCk6CiAgICAgICBgcHJvamVjdHMve1BST0pFQ1RfSUR9L3JvbGVzL3tDVVNUT01fUk9MRV9JRH1gLiBUaGlzIG1ldGhvZCB1cGRhdGVzIG9ubHkgW2N1c3RvbSByb2xlc10oL2lhbS9kb2NzCiAgICAgICAvdW5kZXJzdGFuZGluZy1jdXN0b20tcm9sZXMpIHRoYXQgaGF2ZSBiZWVuIGNyZWF0ZWQgYXQgdGhlIHByb2plY3QgbGV2ZWwuIEV4YW1wbGUgcmVxdWVzdCBVUkw6CiAgICAgICBgaHR0cHM6Ly9pYW0uZ29vZ2xlYXBpcy5jb20vdjEvcHJvamVjdHMve1BST0pFQ1RfSUR9L3JvbGVzL3tDVVNUT01fUk9MRV9JRH1gCgogICAgICAgKiBbYG9yZ2FuaXphdGlvbnMucm9sZXMucGF0Y2goKWBdKC9pYW0vcmVmZXJlbmNlL3Jlc3QvdjEvb3JnYW5pemF0aW9ucy5yb2xlcy9wYXRjaCk6CiAgICAgICBgb3JnYW5pemF0aW9ucy97T1JHQU5JWkFUSU9OX0lEfS9yb2xlcy97Q1VTVE9NX1JPTEVfSUR9YC4gVGhpcyBtZXRob2QgdXBkYXRlcyBvbmx5IFtjdXN0b20KICAgICAgIHJvbGVzXSgvaWFtL2RvY3MvdW5kZXJzdGFuZGluZy1jdXN0b20tcm9sZXMpIHRoYXQgaGF2ZSBiZWVuIGNyZWF0ZWQgYXQgdGhlIG9yZ2FuaXphdGlvbiBsZXZlbC4KICAgICAgIEV4YW1wbGUgcmVxdWVzdCBVUkw6CiAgICAgICBgaHR0cHM6Ly9pYW0uZ29vZ2xlYXBpcy5jb20vdjEvb3JnYW5pemF0aW9ucy97T1JHQU5JWkFUSU9OX0lEfS9yb2xlcy97Q1VTVE9NX1JPTEVfSUR9YAoKICAgICAgIE5vdGU6IFdpbGRjYXJkICgqKSB2YWx1ZXMgYXJlIGludmFsaWQ7IHlvdSBtdXN0IHNwZWNpZnkgYSBjb21wbGV0ZSBwcm9qZWN0IElEIG9yIG9yZ2FuaXphdGlvbiBJRC4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXROYW1lKCkgewogICAgICAgICAgcmV0dXJuIG5hbWU7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiBUaGUgYG5hbWVgIHBhcmFtZXRlcidzIHZhbHVlIGRlcGVuZHMgb24gdGhlIHRhcmdldCByZXNvdXJjZSBmb3IgdGhlIHJlcXVlc3QsIG5hbWVseQogICAgICAgICAqIFtgcHJvamVjdHNgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL3Byb2plY3RzLnJvbGVzKSBvcgogICAgICAgICAqIFtgb3JnYW5pemF0aW9uc2BdKC9pYW0vcmVmZXJlbmNlL3Jlc3QvdjEvb3JnYW5pemF0aW9ucy5yb2xlcykuIEVhY2ggcmVzb3VyY2UgdHlwZSdzCiAgICAgICAgICogYG5hbWVgIHZhbHVlIGZvcm1hdCBpcyBkZXNjcmliZWQgYmVsb3c6CiAgICAgICAgICoKICAgICAgICAgKiAqIFtgcHJvamVjdHMucm9sZXMucGF0Y2goKWBdKC9pYW0vcmVmZXJlbmNlL3Jlc3QvdjEvcHJvamVjdHMucm9sZXMvcGF0Y2gpOgogICAgICAgICAqIGBwcm9qZWN0cy97UFJPSkVDVF9JRH0vcm9sZXMve0NVU1RPTV9ST0xFX0lEfWAuIFRoaXMgbWV0aG9kIHVwZGF0ZXMgb25seSBbY3VzdG9tCiAgICAgICAgICogcm9sZXNdKC9pYW0vZG9jcy91bmRlcnN0YW5kaW5nLWN1c3RvbS1yb2xlcykgdGhhdCBoYXZlIGJlZW4gY3JlYXRlZCBhdCB0aGUgcHJvamVjdCBsZXZlbC4KICAgICAgICAgKiBFeGFtcGxlIHJlcXVlc3QgVVJMOgogICAgICAgICAqIGBodHRwczovL2lhbS5nb29nbGVhcGlzLmNvbS92MS9wcm9qZWN0cy97UFJPSkVDVF9JRH0vcm9sZXMve0NVU1RPTV9ST0xFX0lEfWAKICAgICAgICAgKgogICAgICAgICAqICogW2Bvcmdhbml6YXRpb25zLnJvbGVzLnBhdGNoKClgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL29yZ2FuaXphdGlvbnMucm9sZXMvcGF0Y2gpOgogICAgICAgICAqIGBvcmdhbml6YXRpb25zL3tPUkdBTklaQVRJT05fSUR9L3JvbGVzL3tDVVNUT01fUk9MRV9JRH1gLiBUaGlzIG1ldGhvZCB1cGRhdGVzIG9ubHkKICAgICAgICAgKiBbY3VzdG9tIHJvbGVzXSgvaWFtL2RvY3MvdW5kZXJzdGFuZGluZy1jdXN0b20tcm9sZXMpIHRoYXQgaGF2ZSBiZWVuIGNyZWF0ZWQgYXQgdGhlCiAgICAgICAgICogb3JnYW5pemF0aW9uIGxldmVsLiBFeGFtcGxlIHJlcXVlc3QgVVJMOgogICAgICAgICAqIGBodHRwczovL2lhbS5nb29nbGVhcGlzLmNvbS92MS9vcmdhbml6YXRpb25zL3tPUkdBTklaQVRJT05fSUR9L3JvbGVzL3tDVVNUT01fUk9MRV9JRH1gCiAgICAgICAgICoKICAgICAgICAgKiBOb3RlOiBXaWxkY2FyZCAoKikgdmFsdWVzIGFyZSBpbnZhbGlkOyB5b3UgbXVzdCBzcGVjaWZ5IGEgY29tcGxldGUgcHJvamVjdCBJRCBvcgogICAgICAgICAqIG9yZ2FuaXphdGlvbiBJRC4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgUGF0Y2ggc2V0TmFtZShqYXZhLmxhbmcuU3RyaW5nIG5hbWUpIHsKICAgICAgICAgIGlmICghZ2V0U3VwcHJlc3NQYXR0ZXJuQ2hlY2tzKCkpIHsKICAgICAgICAgICAgY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuUHJlY29uZGl0aW9ucy5jaGVja0FyZ3VtZW50KE5BTUVfUEFUVEVSTi5tYXRjaGVyKG5hbWUpLm1hdGNoZXMoKSwKICAgICAgICAgICAgICAgICJQYXJhbWV0ZXIgbmFtZSBtdXN0IGNvbmZvcm0gdG8gdGhlIHBhdHRlcm4gIiArCiAgICAgICAgICAgICAgICAiXm9yZ2FuaXphdGlvbnMvW14vXSsvcm9sZXMvW14vXSskIik7CiAgICAgICAgICB9CiAgICAgICAgICB0aGlzLm5hbWUgPSBuYW1lOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQoKICAgICAgICAvKiogQSBtYXNrIGRlc2NyaWJpbmcgd2hpY2ggZmllbGRzIGluIHRoZSBSb2xlIGhhdmUgY2hhbmdlZC4gKi8KICAgICAgICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgICAgICAgcHJpdmF0ZSBTdHJpbmcgdXBkYXRlTWFzazsKCiAgICAgICAgLyoqIEEgbWFzayBkZXNjcmliaW5nIHdoaWNoIGZpZWxkcyBpbiB0aGUgUm9sZSBoYXZlIGNoYW5nZWQuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIFN0cmluZyBnZXRVcGRhdGVNYXNrKCkgewogICAgICAgICAgcmV0dXJuIHVwZGF0ZU1hc2s7CiAgICAgICAgfQoKICAgICAgICAvKiogQSBtYXNrIGRlc2NyaWJpbmcgd2hpY2ggZmllbGRzIGluIHRoZSBSb2xlIGhhdmUgY2hhbmdlZC4gKi8KICAgICAgICBwdWJsaWMgUGF0Y2ggc2V0VXBkYXRlTWFzayhTdHJpbmcgdXBkYXRlTWFzaykgewogICAgICAgICAgdGhpcy51cGRhdGVNYXNrID0gdXBkYXRlTWFzazsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFBhdGNoIHNldChTdHJpbmcgcGFyYW1ldGVyTmFtZSwgT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgICByZXR1cm4gKFBhdGNoKSBzdXBlci5zZXQocGFyYW1ldGVyTmFtZSwgdmFsdWUpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogVW5kZWxldGUgYSBSb2xlLCBicmluZ2luZyBpdCBiYWNrIGluIGl0cyBwcmV2aW91cyBzdGF0ZS4KICAgICAgICoKICAgICAgICogQ3JlYXRlIGEgcmVxdWVzdCBmb3IgdGhlIG1ldGhvZCAicm9sZXMudW5kZWxldGUiLgogICAgICAgKgogICAgICAgKiBUaGlzIHJlcXVlc3QgaG9sZHMgdGhlIHBhcmFtZXRlcnMgbmVlZGVkIGJ5IHRoZSBpYW0gc2VydmVyLiAgQWZ0ZXIgc2V0dGluZyBhbnkgb3B0aW9uYWwKICAgICAgICogcGFyYW1ldGVycywgY2FsbCB0aGUge0BsaW5rIFVuZGVsZXRlI2V4ZWN1dGUoKX0gbWV0aG9kIHRvIGludm9rZSB0aGUgcmVtb3RlIG9wZXJhdGlvbi4KICAgICAgICoKICAgICAgICogQHBhcmFtIG5hbWUgVGhlIGBuYW1lYCBwYXJhbWV0ZXIncyB2YWx1ZSBkZXBlbmRzIG9uIHRoZSB0YXJnZXQgcmVzb3VyY2UgZm9yIHRoZQogICAgICByZXF1ZXN0LCBuYW1lbHkKICAgICAgICogICAgICAgIFtgcHJvamVjdHNgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL3Byb2plY3RzLnJvbGVzKSBvcgogICAgICAgKiAgICAgICAgW2Bvcmdhbml6YXRpb25zYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9vcmdhbml6YXRpb25zLnJvbGVzKS4gRWFjaAogICAgICByZXNvdXJjZSB0eXBlJ3MgYG5hbWVgCiAgICAgICAqICAgICAgICB2YWx1ZSBmb3JtYXQgaXMgZGVzY3JpYmVkIGJlbG93OgogICAgICAqCiAgICAgICAqICAgICAgICBbYHByb2plY3RzLnJvbGVzLnVuZGVsZXRlKClgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL3Byb2plY3RzLnJvbGVzL3VuZGVsZXRlKToKICAgICAgICogICAgICAgIGBwcm9qZWN0cy97UFJPSkVDVF9JRH0vcm9sZXMve0NVU1RPTV9ST0xFX0lEfWAuIFRoaXMgbWV0aG9kIHVuZGVsZXRlcwogICAgICAgIG9ubHkgW2N1c3RvbQogICAgICAgKiAgICAgICAgcm9sZXNdKC9pYW0vZG9jcy91bmRlcnN0YW5kaW5nLWN1c3RvbS1yb2xlcykgdGhhdCBoYXZlIGJlZW4KICAgICAgICBjcmVhdGVkIGF0IHRoZSBwcm9qZWN0CiAgICAgICAqICAgICAgICBsZXZlbC4gRXhhbXBsZSByZXF1ZXN0IFVSTDoKICAgICAgICogICAgICAgIGBodHRwczovL2lhbS5nb29nbGVhcGlzLmNvbS92MS9wcm9qZWN0cy97UFJPSkVDVF9JRH0vcm9sZXMve0NVU1RPTV9ST0xFX0lEfWAKICAgICAgKgogICAgICAgKiAgICAgICAgW2Bvcmdhbml6YXRpb25zLnJvbGVzLnVuZGVsZXRlKClgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL29yZ2FuaXphdGlvbnMucm9sZXMvdW5kZWxldGUpOgogICAgICAgKiAgICAgICAgYG9yZ2FuaXphdGlvbnMve09SR0FOSVpBVElPTl9JRH0vcm9sZXMve0NVU1RPTV9ST0xFX0lEfWAuIFRoaXMgbWV0aG9kCiAgICAgICAgdW5kZWxldGVzIG9ubHkKICAgICAgICogICAgICAgIFtjdXN0b20gcm9sZXNdKC9pYW0vZG9jcy91bmRlcnN0YW5kaW5nLWN1c3RvbS1yb2xlcykgdGhhdAogICAgICAgIGhhdmUgYmVlbiBjcmVhdGVkIGF0IHRoZQogICAgICAgKiAgICAgICAgb3JnYW5pemF0aW9uIGxldmVsLiBFeGFtcGxlIHJlcXVlc3QgVVJMOgogICAgICAgKiAgICAgICAgYGh0dHBzOi8vaWFtLmdvb2dsZWFwaXMuY29tL3YxL29yZ2FuaXphdGlvbnMve09SR0FOSVpBVElPTl9JRH0vcm9sZXMve0NVU1RPTV9ST0xFX0lEfWAKICAgICAgICogICAgICAgIE5vdGU6IFdpbGRjYXJkICgqKSB2YWx1ZXMgYXJlIGludmFsaWQ7IHlvdSBtdXN0IHNwZWNpZnkgYSBjb21wbGV0ZSBwcm9qZWN0CiAgICAgIElEIG9yCiAgICAgICAqICAgICAgICBvcmdhbml6YXRpb24gSUQuCiAgICAgICAqIEBwYXJhbSBjb250ZW50IHRoZSB7QGxpbmsgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuaWFtLnYxLm1vZGVsLlVuZGVsZXRlUm9sZVJlcXVlc3R9CiAgICAgICAqIEByZXR1cm4gdGhlIHJlcXVlc3QKICAgICAgICovCiAgICAgIHB1YmxpYyBVbmRlbGV0ZSB1bmRlbGV0ZShqYXZhLmxhbmcuU3RyaW5nIG5hbWUsIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmlhbS52MS5tb2RlbC5VbmRlbGV0ZVJvbGVSZXF1ZXN0IGNvbnRlbnQpIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBVbmRlbGV0ZSByZXN1bHQgPSBuZXcgVW5kZWxldGUobmFtZSwgY29udGVudCk7CiAgICAgICAgaW5pdGlhbGl6ZShyZXN1bHQpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBjbGFzcyBVbmRlbGV0ZSBleHRlbmRzIElhbVJlcXVlc3Q8Y29tLmdvb2dsZS5hcGkuc2VydmljZXMuaWFtLnYxLm1vZGVsLlJvbGU+IHsKCiAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFJFU1RfUEFUSCA9ICJ2MS97K25hbWV9OnVuZGVsZXRlIjsKCiAgICAgICAgcHJpdmF0ZSBmaW5hbCBqYXZhLnV0aWwucmVnZXguUGF0dGVybiBOQU1FX1BBVFRFUk4gPQogICAgICAgICAgICBqYXZhLnV0aWwucmVnZXguUGF0dGVybi5jb21waWxlKCJeb3JnYW5pemF0aW9ucy9bXi9dKy9yb2xlcy9bXi9dKyQiKTsKCiAgICAgICAgLyoqCiAgICAgICAgICogVW5kZWxldGUgYSBSb2xlLCBicmluZ2luZyBpdCBiYWNrIGluIGl0cyBwcmV2aW91cyBzdGF0ZS4KICAgICAgICAgKgogICAgICAgICAqIENyZWF0ZSBhIHJlcXVlc3QgZm9yIHRoZSBtZXRob2QgInJvbGVzLnVuZGVsZXRlIi4KICAgICAgICAgKgogICAgICAgICAqIFRoaXMgcmVxdWVzdCBob2xkcyB0aGUgcGFyYW1ldGVycyBuZWVkZWQgYnkgdGhlIHRoZSBpYW0gc2VydmVyLiAgQWZ0ZXIgc2V0dGluZyBhbnkgb3B0aW9uYWwKICAgICAgICAgKiBwYXJhbWV0ZXJzLCBjYWxsIHRoZSB7QGxpbmsgVW5kZWxldGUjZXhlY3V0ZSgpfSBtZXRob2QgdG8gaW52b2tlIHRoZSByZW1vdGUgb3BlcmF0aW9uLiA8cD4KICAgICAgICAgKiB7QGxpbmsKICAgICAgICAgKiBVbmRlbGV0ZSNpbml0aWFsaXplKGNvbS5nb29nbGUuYXBpLmNsaWVudC5nb29nbGVhcGlzLnNlcnZpY2VzLkFic3RyYWN0R29vZ2xlQ2xpZW50UmVxdWVzdCl9CiAgICAgICAgICogbXVzdCBiZSBjYWxsZWQgdG8gaW5pdGlhbGl6ZSB0aGlzIGluc3RhbmNlIGltbWVkaWF0ZWx5IGFmdGVyIGludm9raW5nIHRoZSBjb25zdHJ1Y3Rvci4gPC9wPgogICAgICAgICAqCiAgICAgICAgICogQHBhcmFtIG5hbWUgVGhlIGBuYW1lYCBwYXJhbWV0ZXIncyB2YWx1ZSBkZXBlbmRzIG9uIHRoZSB0YXJnZXQgcmVzb3VyY2UgZm9yIHRoZQogICAgICByZXF1ZXN0LCBuYW1lbHkKICAgICAgICogICAgICAgIFtgcHJvamVjdHNgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL3Byb2plY3RzLnJvbGVzKSBvcgogICAgICAgKiAgICAgICAgW2Bvcmdhbml6YXRpb25zYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9vcmdhbml6YXRpb25zLnJvbGVzKS4gRWFjaAogICAgICByZXNvdXJjZSB0eXBlJ3MgYG5hbWVgCiAgICAgICAqICAgICAgICB2YWx1ZSBmb3JtYXQgaXMgZGVzY3JpYmVkIGJlbG93OgogICAgICAqCiAgICAgICAqICAgICAgICBbYHByb2plY3RzLnJvbGVzLnVuZGVsZXRlKClgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL3Byb2plY3RzLnJvbGVzL3VuZGVsZXRlKToKICAgICAgICogICAgICAgIGBwcm9qZWN0cy97UFJPSkVDVF9JRH0vcm9sZXMve0NVU1RPTV9ST0xFX0lEfWAuIFRoaXMgbWV0aG9kIHVuZGVsZXRlcwogICAgICAgIG9ubHkgW2N1c3RvbQogICAgICAgKiAgICAgICAgcm9sZXNdKC9pYW0vZG9jcy91bmRlcnN0YW5kaW5nLWN1c3RvbS1yb2xlcykgdGhhdCBoYXZlIGJlZW4KICAgICAgICBjcmVhdGVkIGF0IHRoZSBwcm9qZWN0CiAgICAgICAqICAgICAgICBsZXZlbC4gRXhhbXBsZSByZXF1ZXN0IFVSTDoKICAgICAgICogICAgICAgIGBodHRwczovL2lhbS5nb29nbGVhcGlzLmNvbS92MS9wcm9qZWN0cy97UFJPSkVDVF9JRH0vcm9sZXMve0NVU1RPTV9ST0xFX0lEfWAKICAgICAgKgogICAgICAgKiAgICAgICAgW2Bvcmdhbml6YXRpb25zLnJvbGVzLnVuZGVsZXRlKClgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL29yZ2FuaXphdGlvbnMucm9sZXMvdW5kZWxldGUpOgogICAgICAgKiAgICAgICAgYG9yZ2FuaXphdGlvbnMve09SR0FOSVpBVElPTl9JRH0vcm9sZXMve0NVU1RPTV9ST0xFX0lEfWAuIFRoaXMgbWV0aG9kCiAgICAgICAgdW5kZWxldGVzIG9ubHkKICAgICAgICogICAgICAgIFtjdXN0b20gcm9sZXNdKC9pYW0vZG9jcy91bmRlcnN0YW5kaW5nLWN1c3RvbS1yb2xlcykgdGhhdAogICAgICAgIGhhdmUgYmVlbiBjcmVhdGVkIGF0IHRoZQogICAgICAgKiAgICAgICAgb3JnYW5pemF0aW9uIGxldmVsLiBFeGFtcGxlIHJlcXVlc3QgVVJMOgogICAgICAgKiAgICAgICAgYGh0dHBzOi8vaWFtLmdvb2dsZWFwaXMuY29tL3YxL29yZ2FuaXphdGlvbnMve09SR0FOSVpBVElPTl9JRH0vcm9sZXMve0NVU1RPTV9ST0xFX0lEfWAKICAgICAgICogICAgICAgIE5vdGU6IFdpbGRjYXJkICgqKSB2YWx1ZXMgYXJlIGludmFsaWQ7IHlvdSBtdXN0IHNwZWNpZnkgYSBjb21wbGV0ZSBwcm9qZWN0CiAgICAgIElEIG9yCiAgICAgICAqICAgICAgICBvcmdhbml6YXRpb24gSUQuCiAgICAgICAgICogQHBhcmFtIGNvbnRlbnQgdGhlIHtAbGluayBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5pYW0udjEubW9kZWwuVW5kZWxldGVSb2xlUmVxdWVzdH0KICAgICAgICAgKiBAc2luY2UgMS4xMwogICAgICAgICAqLwogICAgICAgIHByb3RlY3RlZCBVbmRlbGV0ZShqYXZhLmxhbmcuU3RyaW5nIG5hbWUsIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmlhbS52MS5tb2RlbC5VbmRlbGV0ZVJvbGVSZXF1ZXN0IGNvbnRlbnQpIHsKICAgICAgICAgIHN1cGVyKElhbS50aGlzLCAiUE9TVCIsIFJFU1RfUEFUSCwgY29udGVudCwgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuaWFtLnYxLm1vZGVsLlJvbGUuY2xhc3MpOwogICAgICAgICAgdGhpcy5uYW1lID0gY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuUHJlY29uZGl0aW9ucy5jaGVja05vdE51bGwobmFtZSwgIlJlcXVpcmVkIHBhcmFtZXRlciBuYW1lIG11c3QgYmUgc3BlY2lmaWVkLiIpOwogICAgICAgICAgaWYgKCFnZXRTdXBwcmVzc1BhdHRlcm5DaGVja3MoKSkgewogICAgICAgICAgICBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5QcmVjb25kaXRpb25zLmNoZWNrQXJndW1lbnQoTkFNRV9QQVRURVJOLm1hdGNoZXIobmFtZSkubWF0Y2hlcygpLAogICAgICAgICAgICAgICAgIlBhcmFtZXRlciBuYW1lIG11c3QgY29uZm9ybSB0byB0aGUgcGF0dGVybiAiICsKICAgICAgICAgICAgICAgICJeb3JnYW5pemF0aW9ucy9bXi9dKy9yb2xlcy9bXi9dKyQiKTsKICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBVbmRlbGV0ZSBzZXQkWGdhZnYoamF2YS5sYW5nLlN0cmluZyAkWGdhZnYpIHsKICAgICAgICAgIHJldHVybiAoVW5kZWxldGUpIHN1cGVyLnNldCRYZ2FmdigkWGdhZnYpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFVuZGVsZXRlIHNldEFjY2Vzc1Rva2VuKGphdmEubGFuZy5TdHJpbmcgYWNjZXNzVG9rZW4pIHsKICAgICAgICAgIHJldHVybiAoVW5kZWxldGUpIHN1cGVyLnNldEFjY2Vzc1Rva2VuKGFjY2Vzc1Rva2VuKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBVbmRlbGV0ZSBzZXRBbHQoamF2YS5sYW5nLlN0cmluZyBhbHQpIHsKICAgICAgICAgIHJldHVybiAoVW5kZWxldGUpIHN1cGVyLnNldEFsdChhbHQpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFVuZGVsZXRlIHNldENhbGxiYWNrKGphdmEubGFuZy5TdHJpbmcgY2FsbGJhY2spIHsKICAgICAgICAgIHJldHVybiAoVW5kZWxldGUpIHN1cGVyLnNldENhbGxiYWNrKGNhbGxiYWNrKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBVbmRlbGV0ZSBzZXRGaWVsZHMoamF2YS5sYW5nLlN0cmluZyBmaWVsZHMpIHsKICAgICAgICAgIHJldHVybiAoVW5kZWxldGUpIHN1cGVyLnNldEZpZWxkcyhmaWVsZHMpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFVuZGVsZXRlIHNldEtleShqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgICAgcmV0dXJuIChVbmRlbGV0ZSkgc3VwZXIuc2V0S2V5KGtleSk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgVW5kZWxldGUgc2V0T2F1dGhUb2tlbihqYXZhLmxhbmcuU3RyaW5nIG9hdXRoVG9rZW4pIHsKICAgICAgICAgIHJldHVybiAoVW5kZWxldGUpIHN1cGVyLnNldE9hdXRoVG9rZW4ob2F1dGhUb2tlbik7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgVW5kZWxldGUgc2V0UHJldHR5UHJpbnQoamF2YS5sYW5nLkJvb2xlYW4gcHJldHR5UHJpbnQpIHsKICAgICAgICAgIHJldHVybiAoVW5kZWxldGUpIHN1cGVyLnNldFByZXR0eVByaW50KHByZXR0eVByaW50KTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBVbmRlbGV0ZSBzZXRRdW90YVVzZXIoamF2YS5sYW5nLlN0cmluZyBxdW90YVVzZXIpIHsKICAgICAgICAgIHJldHVybiAoVW5kZWxldGUpIHN1cGVyLnNldFF1b3RhVXNlcihxdW90YVVzZXIpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFVuZGVsZXRlIHNldFVwbG9hZFR5cGUoamF2YS5sYW5nLlN0cmluZyB1cGxvYWRUeXBlKSB7CiAgICAgICAgICByZXR1cm4gKFVuZGVsZXRlKSBzdXBlci5zZXRVcGxvYWRUeXBlKHVwbG9hZFR5cGUpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFVuZGVsZXRlIHNldFVwbG9hZFByb3RvY29sKGphdmEubGFuZy5TdHJpbmcgdXBsb2FkUHJvdG9jb2wpIHsKICAgICAgICAgIHJldHVybiAoVW5kZWxldGUpIHN1cGVyLnNldFVwbG9hZFByb3RvY29sKHVwbG9hZFByb3RvY29sKTsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIFRoZSBgbmFtZWAgcGFyYW1ldGVyJ3MgdmFsdWUgZGVwZW5kcyBvbiB0aGUgdGFyZ2V0IHJlc291cmNlIGZvciB0aGUgcmVxdWVzdCwgbmFtZWx5CiAgICAgICAgICogW2Bwcm9qZWN0c2BdKC9pYW0vcmVmZXJlbmNlL3Jlc3QvdjEvcHJvamVjdHMucm9sZXMpIG9yCiAgICAgICAgICogW2Bvcmdhbml6YXRpb25zYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9vcmdhbml6YXRpb25zLnJvbGVzKS4gRWFjaCByZXNvdXJjZSB0eXBlJ3MKICAgICAgICAgKiBgbmFtZWAgdmFsdWUgZm9ybWF0IGlzIGRlc2NyaWJlZCBiZWxvdzoKICAgICAgICAgKgogICAgICAgICAqICogW2Bwcm9qZWN0cy5yb2xlcy51bmRlbGV0ZSgpYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9wcm9qZWN0cy5yb2xlcy91bmRlbGV0ZSk6CiAgICAgICAgICogYHByb2plY3RzL3tQUk9KRUNUX0lEfS9yb2xlcy97Q1VTVE9NX1JPTEVfSUR9YC4gVGhpcyBtZXRob2QgdW5kZWxldGVzIG9ubHkgW2N1c3RvbQogICAgICAgICAqIHJvbGVzXSgvaWFtL2RvY3MvdW5kZXJzdGFuZGluZy1jdXN0b20tcm9sZXMpIHRoYXQgaGF2ZSBiZWVuIGNyZWF0ZWQgYXQgdGhlIHByb2plY3QgbGV2ZWwuCiAgICAgICAgICogRXhhbXBsZSByZXF1ZXN0IFVSTDoKICAgICAgICAgKiBgaHR0cHM6Ly9pYW0uZ29vZ2xlYXBpcy5jb20vdjEvcHJvamVjdHMve1BST0pFQ1RfSUR9L3JvbGVzL3tDVVNUT01fUk9MRV9JRH1gCiAgICAgICAgICoKICAgICAgICAgKiAqCiAgICAgICAgICogW2Bvcmdhbml6YXRpb25zLnJvbGVzLnVuZGVsZXRlKClgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL29yZ2FuaXphdGlvbnMucm9sZXMvdW5kZWxldGUpOgogICAgICAgICAqIGBvcmdhbml6YXRpb25zL3tPUkdBTklaQVRJT05fSUR9L3JvbGVzL3tDVVNUT01fUk9MRV9JRH1gLiBUaGlzIG1ldGhvZCB1bmRlbGV0ZXMgb25seQogICAgICAgICAqIFtjdXN0b20gcm9sZXNdKC9pYW0vZG9jcy91bmRlcnN0YW5kaW5nLWN1c3RvbS1yb2xlcykgdGhhdCBoYXZlIGJlZW4gY3JlYXRlZCBhdCB0aGUKICAgICAgICAgKiBvcmdhbml6YXRpb24gbGV2ZWwuIEV4YW1wbGUgcmVxdWVzdCBVUkw6CiAgICAgICAgICogYGh0dHBzOi8vaWFtLmdvb2dsZWFwaXMuY29tL3YxL29yZ2FuaXphdGlvbnMve09SR0FOSVpBVElPTl9JRH0vcm9sZXMve0NVU1RPTV9ST0xFX0lEfWAKICAgICAgICAgKgogICAgICAgICAqIE5vdGU6IFdpbGRjYXJkICgqKSB2YWx1ZXMgYXJlIGludmFsaWQ7IHlvdSBtdXN0IHNwZWNpZnkgYSBjb21wbGV0ZSBwcm9qZWN0IElEIG9yCiAgICAgICAgICogb3JnYW5pemF0aW9uIElELgogICAgICAgICAqLwogICAgICAgIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICAgICAgICBwcml2YXRlIGphdmEubGFuZy5TdHJpbmcgbmFtZTsKCiAgICAgICAgLyoqIFRoZSBgbmFtZWAgcGFyYW1ldGVyJ3MgdmFsdWUgZGVwZW5kcyBvbiB0aGUgdGFyZ2V0IHJlc291cmNlIGZvciB0aGUgcmVxdWVzdCwgbmFtZWx5CiAgICAgICBbYHByb2plY3RzYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9wcm9qZWN0cy5yb2xlcykgb3IKICAgICAgIFtgb3JnYW5pemF0aW9uc2BdKC9pYW0vcmVmZXJlbmNlL3Jlc3QvdjEvb3JnYW5pemF0aW9ucy5yb2xlcykuIEVhY2ggcmVzb3VyY2UgdHlwZSdzIGBuYW1lYCB2YWx1ZQogICAgICAgZm9ybWF0IGlzIGRlc2NyaWJlZCBiZWxvdzoKCiAgICAgICAqIFtgcHJvamVjdHMucm9sZXMudW5kZWxldGUoKWBdKC9pYW0vcmVmZXJlbmNlL3Jlc3QvdjEvcHJvamVjdHMucm9sZXMvdW5kZWxldGUpOgogICAgICAgYHByb2plY3RzL3tQUk9KRUNUX0lEfS9yb2xlcy97Q1VTVE9NX1JPTEVfSUR9YC4gVGhpcyBtZXRob2QgdW5kZWxldGVzIG9ubHkgW2N1c3RvbSByb2xlc10oL2lhbS9kb2NzCiAgICAgICAvdW5kZXJzdGFuZGluZy1jdXN0b20tcm9sZXMpIHRoYXQgaGF2ZSBiZWVuIGNyZWF0ZWQgYXQgdGhlIHByb2plY3QgbGV2ZWwuIEV4YW1wbGUgcmVxdWVzdCBVUkw6CiAgICAgICBgaHR0cHM6Ly9pYW0uZ29vZ2xlYXBpcy5jb20vdjEvcHJvamVjdHMve1BST0pFQ1RfSUR9L3JvbGVzL3tDVVNUT01fUk9MRV9JRH1gCgogICAgICAgKiBbYG9yZ2FuaXphdGlvbnMucm9sZXMudW5kZWxldGUoKWBdKC9pYW0vcmVmZXJlbmNlL3Jlc3QvdjEvb3JnYW5pemF0aW9ucy5yb2xlcy91bmRlbGV0ZSk6CiAgICAgICBgb3JnYW5pemF0aW9ucy97T1JHQU5JWkFUSU9OX0lEfS9yb2xlcy97Q1VTVE9NX1JPTEVfSUR9YC4gVGhpcyBtZXRob2QgdW5kZWxldGVzIG9ubHkgW2N1c3RvbQogICAgICAgcm9sZXNdKC9pYW0vZG9jcy91bmRlcnN0YW5kaW5nLWN1c3RvbS1yb2xlcykgdGhhdCBoYXZlIGJlZW4gY3JlYXRlZCBhdCB0aGUgb3JnYW5pemF0aW9uIGxldmVsLgogICAgICAgRXhhbXBsZSByZXF1ZXN0IFVSTDoKICAgICAgIGBodHRwczovL2lhbS5nb29nbGVhcGlzLmNvbS92MS9vcmdhbml6YXRpb25zL3tPUkdBTklaQVRJT05fSUR9L3JvbGVzL3tDVVNUT01fUk9MRV9JRH1gCgogICAgICAgTm90ZTogV2lsZGNhcmQgKCopIHZhbHVlcyBhcmUgaW52YWxpZDsgeW91IG11c3Qgc3BlY2lmeSBhIGNvbXBsZXRlIHByb2plY3QgSUQgb3Igb3JnYW5pemF0aW9uIElELgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldE5hbWUoKSB7CiAgICAgICAgICByZXR1cm4gbmFtZTsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIFRoZSBgbmFtZWAgcGFyYW1ldGVyJ3MgdmFsdWUgZGVwZW5kcyBvbiB0aGUgdGFyZ2V0IHJlc291cmNlIGZvciB0aGUgcmVxdWVzdCwgbmFtZWx5CiAgICAgICAgICogW2Bwcm9qZWN0c2BdKC9pYW0vcmVmZXJlbmNlL3Jlc3QvdjEvcHJvamVjdHMucm9sZXMpIG9yCiAgICAgICAgICogW2Bvcmdhbml6YXRpb25zYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9vcmdhbml6YXRpb25zLnJvbGVzKS4gRWFjaCByZXNvdXJjZSB0eXBlJ3MKICAgICAgICAgKiBgbmFtZWAgdmFsdWUgZm9ybWF0IGlzIGRlc2NyaWJlZCBiZWxvdzoKICAgICAgICAgKgogICAgICAgICAqICogW2Bwcm9qZWN0cy5yb2xlcy51bmRlbGV0ZSgpYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9wcm9qZWN0cy5yb2xlcy91bmRlbGV0ZSk6CiAgICAgICAgICogYHByb2plY3RzL3tQUk9KRUNUX0lEfS9yb2xlcy97Q1VTVE9NX1JPTEVfSUR9YC4gVGhpcyBtZXRob2QgdW5kZWxldGVzIG9ubHkgW2N1c3RvbQogICAgICAgICAqIHJvbGVzXSgvaWFtL2RvY3MvdW5kZXJzdGFuZGluZy1jdXN0b20tcm9sZXMpIHRoYXQgaGF2ZSBiZWVuIGNyZWF0ZWQgYXQgdGhlIHByb2plY3QgbGV2ZWwuCiAgICAgICAgICogRXhhbXBsZSByZXF1ZXN0IFVSTDoKICAgICAgICAgKiBgaHR0cHM6Ly9pYW0uZ29vZ2xlYXBpcy5jb20vdjEvcHJvamVjdHMve1BST0pFQ1RfSUR9L3JvbGVzL3tDVVNUT01fUk9MRV9JRH1gCiAgICAgICAgICoKICAgICAgICAgKiAqCiAgICAgICAgICogW2Bvcmdhbml6YXRpb25zLnJvbGVzLnVuZGVsZXRlKClgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL29yZ2FuaXphdGlvbnMucm9sZXMvdW5kZWxldGUpOgogICAgICAgICAqIGBvcmdhbml6YXRpb25zL3tPUkdBTklaQVRJT05fSUR9L3JvbGVzL3tDVVNUT01fUk9MRV9JRH1gLiBUaGlzIG1ldGhvZCB1bmRlbGV0ZXMgb25seQogICAgICAgICAqIFtjdXN0b20gcm9sZXNdKC9pYW0vZG9jcy91bmRlcnN0YW5kaW5nLWN1c3RvbS1yb2xlcykgdGhhdCBoYXZlIGJlZW4gY3JlYXRlZCBhdCB0aGUKICAgICAgICAgKiBvcmdhbml6YXRpb24gbGV2ZWwuIEV4YW1wbGUgcmVxdWVzdCBVUkw6CiAgICAgICAgICogYGh0dHBzOi8vaWFtLmdvb2dsZWFwaXMuY29tL3YxL29yZ2FuaXphdGlvbnMve09SR0FOSVpBVElPTl9JRH0vcm9sZXMve0NVU1RPTV9ST0xFX0lEfWAKICAgICAgICAgKgogICAgICAgICAqIE5vdGU6IFdpbGRjYXJkICgqKSB2YWx1ZXMgYXJlIGludmFsaWQ7IHlvdSBtdXN0IHNwZWNpZnkgYSBjb21wbGV0ZSBwcm9qZWN0IElEIG9yCiAgICAgICAgICogb3JnYW5pemF0aW9uIElELgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBVbmRlbGV0ZSBzZXROYW1lKGphdmEubGFuZy5TdHJpbmcgbmFtZSkgewogICAgICAgICAgaWYgKCFnZXRTdXBwcmVzc1BhdHRlcm5DaGVja3MoKSkgewogICAgICAgICAgICBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5QcmVjb25kaXRpb25zLmNoZWNrQXJndW1lbnQoTkFNRV9QQVRURVJOLm1hdGNoZXIobmFtZSkubWF0Y2hlcygpLAogICAgICAgICAgICAgICAgIlBhcmFtZXRlciBuYW1lIG11c3QgY29uZm9ybSB0byB0aGUgcGF0dGVybiAiICsKICAgICAgICAgICAgICAgICJeb3JnYW5pemF0aW9ucy9bXi9dKy9yb2xlcy9bXi9dKyQiKTsKICAgICAgICAgIH0KICAgICAgICAgIHRoaXMubmFtZSA9IG5hbWU7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBVbmRlbGV0ZSBzZXQoU3RyaW5nIHBhcmFtZXRlck5hbWUsIE9iamVjdCB2YWx1ZSkgewogICAgICAgICAgcmV0dXJuIChVbmRlbGV0ZSkgc3VwZXIuc2V0KHBhcmFtZXRlck5hbWUsIHZhbHVlKTsKICAgICAgICB9CiAgICAgIH0KCiAgICB9CiAgfQoKICAvKioKICAgKiBBbiBhY2Nlc3NvciBmb3IgY3JlYXRpbmcgcmVxdWVzdHMgZnJvbSB0aGUgUGVybWlzc2lvbnMgY29sbGVjdGlvbi4KICAgKgogICAqIDxwPlRoZSB0eXBpY2FsIHVzZSBpczo8L3A+CiAgICogPHByZT4KICAgKiAgIHtAY29kZSBJYW0gaWFtID0gbmV3IElhbSguLi4pO30KICAgKiAgIHtAY29kZSBJYW0uUGVybWlzc2lvbnMuTGlzdCByZXF1ZXN0ID0gaWFtLnBlcm1pc3Npb25zKCkubGlzdChwYXJhbWV0ZXJzIC4uLil9CiAgICogPC9wcmU+CiAgICoKICAgKiBAcmV0dXJuIHRoZSByZXNvdXJjZSBjb2xsZWN0aW9uCiAgICovCiAgcHVibGljIFBlcm1pc3Npb25zIHBlcm1pc3Npb25zKCkgewogICAgcmV0dXJuIG5ldyBQZXJtaXNzaW9ucygpOwogIH0KCiAgLyoqCiAgICogVGhlICJwZXJtaXNzaW9ucyIgY29sbGVjdGlvbiBvZiBtZXRob2RzLgogICAqLwogIHB1YmxpYyBjbGFzcyBQZXJtaXNzaW9ucyB7CgogICAgLyoqCiAgICAgKiBMaXN0cyB0aGUgcGVybWlzc2lvbnMgdGVzdGFibGUgb24gYSByZXNvdXJjZS4gQSBwZXJtaXNzaW9uIGlzIHRlc3RhYmxlIGlmIGl0IGNhbiBiZSB0ZXN0ZWQgZm9yIGFuCiAgICAgKiBpZGVudGl0eSBvbiBhIHJlc291cmNlLgogICAgICoKICAgICAqIENyZWF0ZSBhIHJlcXVlc3QgZm9yIHRoZSBtZXRob2QgInBlcm1pc3Npb25zLnF1ZXJ5VGVzdGFibGVQZXJtaXNzaW9ucyIuCiAgICAgKgogICAgICogVGhpcyByZXF1ZXN0IGhvbGRzIHRoZSBwYXJhbWV0ZXJzIG5lZWRlZCBieSB0aGUgaWFtIHNlcnZlci4gIEFmdGVyIHNldHRpbmcgYW55IG9wdGlvbmFsCiAgICAgKiBwYXJhbWV0ZXJzLCBjYWxsIHRoZSB7QGxpbmsgUXVlcnlUZXN0YWJsZVBlcm1pc3Npb25zI2V4ZWN1dGUoKX0gbWV0aG9kIHRvIGludm9rZSB0aGUgcmVtb3RlCiAgICAgKiBvcGVyYXRpb24uCiAgICAgKgogICAgICogQHBhcmFtIGNvbnRlbnQgdGhlIHtAbGluayBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5pYW0udjEubW9kZWwuUXVlcnlUZXN0YWJsZVBlcm1pc3Npb25zUmVxdWVzdH0KICAgICAqIEByZXR1cm4gdGhlIHJlcXVlc3QKICAgICAqLwogICAgcHVibGljIFF1ZXJ5VGVzdGFibGVQZXJtaXNzaW9ucyBxdWVyeVRlc3RhYmxlUGVybWlzc2lvbnMoY29tLmdvb2dsZS5hcGkuc2VydmljZXMuaWFtLnYxLm1vZGVsLlF1ZXJ5VGVzdGFibGVQZXJtaXNzaW9uc1JlcXVlc3QgY29udGVudCkgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBRdWVyeVRlc3RhYmxlUGVybWlzc2lvbnMgcmVzdWx0ID0gbmV3IFF1ZXJ5VGVzdGFibGVQZXJtaXNzaW9ucyhjb250ZW50KTsKICAgICAgaW5pdGlhbGl6ZShyZXN1bHQpOwogICAgICByZXR1cm4gcmVzdWx0OwogICAgfQoKICAgIHB1YmxpYyBjbGFzcyBRdWVyeVRlc3RhYmxlUGVybWlzc2lvbnMgZXh0ZW5kcyBJYW1SZXF1ZXN0PGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmlhbS52MS5tb2RlbC5RdWVyeVRlc3RhYmxlUGVybWlzc2lvbnNSZXNwb25zZT4gewoKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFJFU1RfUEFUSCA9ICJ2MS9wZXJtaXNzaW9uczpxdWVyeVRlc3RhYmxlUGVybWlzc2lvbnMiOwoKICAgICAgLyoqCiAgICAgICAqIExpc3RzIHRoZSBwZXJtaXNzaW9ucyB0ZXN0YWJsZSBvbiBhIHJlc291cmNlLiBBIHBlcm1pc3Npb24gaXMgdGVzdGFibGUgaWYgaXQgY2FuIGJlIHRlc3RlZCBmb3IKICAgICAgICogYW4gaWRlbnRpdHkgb24gYSByZXNvdXJjZS4KICAgICAgICoKICAgICAgICogQ3JlYXRlIGEgcmVxdWVzdCBmb3IgdGhlIG1ldGhvZCAicGVybWlzc2lvbnMucXVlcnlUZXN0YWJsZVBlcm1pc3Npb25zIi4KICAgICAgICoKICAgICAgICogVGhpcyByZXF1ZXN0IGhvbGRzIHRoZSBwYXJhbWV0ZXJzIG5lZWRlZCBieSB0aGUgdGhlIGlhbSBzZXJ2ZXIuICBBZnRlciBzZXR0aW5nIGFueSBvcHRpb25hbAogICAgICAgKiBwYXJhbWV0ZXJzLCBjYWxsIHRoZSB7QGxpbmsgUXVlcnlUZXN0YWJsZVBlcm1pc3Npb25zI2V4ZWN1dGUoKX0gbWV0aG9kIHRvIGludm9rZSB0aGUgcmVtb3RlCiAgICAgICAqIG9wZXJhdGlvbi4gPHA+IHtAbGluayBRdWVyeVRlc3RhYmxlUGVybWlzc2lvbnMjaW5pdGlhbGl6ZShjb20uZ29vZ2xlLmFwaS5jbGllbnQuZ29vZ2xlYXBpcy5zZXJ2CiAgICAgICAqIGljZXMuQWJzdHJhY3RHb29nbGVDbGllbnRSZXF1ZXN0KX0gbXVzdCBiZSBjYWxsZWQgdG8gaW5pdGlhbGl6ZSB0aGlzIGluc3RhbmNlIGltbWVkaWF0ZWx5IGFmdGVyCiAgICAgICAqIGludm9raW5nIHRoZSBjb25zdHJ1Y3Rvci4gPC9wPgogICAgICAgKgogICAgICAgKiBAcGFyYW0gY29udGVudCB0aGUge0BsaW5rIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmlhbS52MS5tb2RlbC5RdWVyeVRlc3RhYmxlUGVybWlzc2lvbnNSZXF1ZXN0fQogICAgICAgKiBAc2luY2UgMS4xMwogICAgICAgKi8KICAgICAgcHJvdGVjdGVkIFF1ZXJ5VGVzdGFibGVQZXJtaXNzaW9ucyhjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5pYW0udjEubW9kZWwuUXVlcnlUZXN0YWJsZVBlcm1pc3Npb25zUmVxdWVzdCBjb250ZW50KSB7CiAgICAgICAgc3VwZXIoSWFtLnRoaXMsICJQT1NUIiwgUkVTVF9QQVRILCBjb250ZW50LCBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5pYW0udjEubW9kZWwuUXVlcnlUZXN0YWJsZVBlcm1pc3Npb25zUmVzcG9uc2UuY2xhc3MpOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIFF1ZXJ5VGVzdGFibGVQZXJtaXNzaW9ucyBzZXQkWGdhZnYoamF2YS5sYW5nLlN0cmluZyAkWGdhZnYpIHsKICAgICAgICByZXR1cm4gKFF1ZXJ5VGVzdGFibGVQZXJtaXNzaW9ucykgc3VwZXIuc2V0JFhnYWZ2KCRYZ2Fmdik7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgUXVlcnlUZXN0YWJsZVBlcm1pc3Npb25zIHNldEFjY2Vzc1Rva2VuKGphdmEubGFuZy5TdHJpbmcgYWNjZXNzVG9rZW4pIHsKICAgICAgICByZXR1cm4gKFF1ZXJ5VGVzdGFibGVQZXJtaXNzaW9ucykgc3VwZXIuc2V0QWNjZXNzVG9rZW4oYWNjZXNzVG9rZW4pOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIFF1ZXJ5VGVzdGFibGVQZXJtaXNzaW9ucyBzZXRBbHQoamF2YS5sYW5nLlN0cmluZyBhbHQpIHsKICAgICAgICByZXR1cm4gKFF1ZXJ5VGVzdGFibGVQZXJtaXNzaW9ucykgc3VwZXIuc2V0QWx0KGFsdCk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgUXVlcnlUZXN0YWJsZVBlcm1pc3Npb25zIHNldENhbGxiYWNrKGphdmEubGFuZy5TdHJpbmcgY2FsbGJhY2spIHsKICAgICAgICByZXR1cm4gKFF1ZXJ5VGVzdGFibGVQZXJtaXNzaW9ucykgc3VwZXIuc2V0Q2FsbGJhY2soY2FsbGJhY2spOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIFF1ZXJ5VGVzdGFibGVQZXJtaXNzaW9ucyBzZXRGaWVsZHMoamF2YS5sYW5nLlN0cmluZyBmaWVsZHMpIHsKICAgICAgICByZXR1cm4gKFF1ZXJ5VGVzdGFibGVQZXJtaXNzaW9ucykgc3VwZXIuc2V0RmllbGRzKGZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgUXVlcnlUZXN0YWJsZVBlcm1pc3Npb25zIHNldEtleShqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIHJldHVybiAoUXVlcnlUZXN0YWJsZVBlcm1pc3Npb25zKSBzdXBlci5zZXRLZXkoa2V5KTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBRdWVyeVRlc3RhYmxlUGVybWlzc2lvbnMgc2V0T2F1dGhUb2tlbihqYXZhLmxhbmcuU3RyaW5nIG9hdXRoVG9rZW4pIHsKICAgICAgICByZXR1cm4gKFF1ZXJ5VGVzdGFibGVQZXJtaXNzaW9ucykgc3VwZXIuc2V0T2F1dGhUb2tlbihvYXV0aFRva2VuKTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBRdWVyeVRlc3RhYmxlUGVybWlzc2lvbnMgc2V0UHJldHR5UHJpbnQoamF2YS5sYW5nLkJvb2xlYW4gcHJldHR5UHJpbnQpIHsKICAgICAgICByZXR1cm4gKFF1ZXJ5VGVzdGFibGVQZXJtaXNzaW9ucykgc3VwZXIuc2V0UHJldHR5UHJpbnQocHJldHR5UHJpbnQpOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIFF1ZXJ5VGVzdGFibGVQZXJtaXNzaW9ucyBzZXRRdW90YVVzZXIoamF2YS5sYW5nLlN0cmluZyBxdW90YVVzZXIpIHsKICAgICAgICByZXR1cm4gKFF1ZXJ5VGVzdGFibGVQZXJtaXNzaW9ucykgc3VwZXIuc2V0UXVvdGFVc2VyKHF1b3RhVXNlcik7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgUXVlcnlUZXN0YWJsZVBlcm1pc3Npb25zIHNldFVwbG9hZFR5cGUoamF2YS5sYW5nLlN0cmluZyB1cGxvYWRUeXBlKSB7CiAgICAgICAgcmV0dXJuIChRdWVyeVRlc3RhYmxlUGVybWlzc2lvbnMpIHN1cGVyLnNldFVwbG9hZFR5cGUodXBsb2FkVHlwZSk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgUXVlcnlUZXN0YWJsZVBlcm1pc3Npb25zIHNldFVwbG9hZFByb3RvY29sKGphdmEubGFuZy5TdHJpbmcgdXBsb2FkUHJvdG9jb2wpIHsKICAgICAgICByZXR1cm4gKFF1ZXJ5VGVzdGFibGVQZXJtaXNzaW9ucykgc3VwZXIuc2V0VXBsb2FkUHJvdG9jb2wodXBsb2FkUHJvdG9jb2wpOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIFF1ZXJ5VGVzdGFibGVQZXJtaXNzaW9ucyBzZXQoU3RyaW5nIHBhcmFtZXRlck5hbWUsIE9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiAoUXVlcnlUZXN0YWJsZVBlcm1pc3Npb25zKSBzdXBlci5zZXQocGFyYW1ldGVyTmFtZSwgdmFsdWUpOwogICAgICB9CiAgICB9CgogIH0KCiAgLyoqCiAgICogQW4gYWNjZXNzb3IgZm9yIGNyZWF0aW5nIHJlcXVlc3RzIGZyb20gdGhlIFByb2plY3RzIGNvbGxlY3Rpb24uCiAgICoKICAgKiA8cD5UaGUgdHlwaWNhbCB1c2UgaXM6PC9wPgogICAqIDxwcmU+CiAgICogICB7QGNvZGUgSWFtIGlhbSA9IG5ldyBJYW0oLi4uKTt9CiAgICogICB7QGNvZGUgSWFtLlByb2plY3RzLkxpc3QgcmVxdWVzdCA9IGlhbS5wcm9qZWN0cygpLmxpc3QocGFyYW1ldGVycyAuLi4pfQogICAqIDwvcHJlPgogICAqCiAgICogQHJldHVybiB0aGUgcmVzb3VyY2UgY29sbGVjdGlvbgogICAqLwogIHB1YmxpYyBQcm9qZWN0cyBwcm9qZWN0cygpIHsKICAgIHJldHVybiBuZXcgUHJvamVjdHMoKTsKICB9CgogIC8qKgogICAqIFRoZSAicHJvamVjdHMiIGNvbGxlY3Rpb24gb2YgbWV0aG9kcy4KICAgKi8KICBwdWJsaWMgY2xhc3MgUHJvamVjdHMgewoKICAgIC8qKgogICAgICogQW4gYWNjZXNzb3IgZm9yIGNyZWF0aW5nIHJlcXVlc3RzIGZyb20gdGhlIFJvbGVzIGNvbGxlY3Rpb24uCiAgICAgKgogICAgICogPHA+VGhlIHR5cGljYWwgdXNlIGlzOjwvcD4KICAgICAqIDxwcmU+CiAgICAgKiAgIHtAY29kZSBJYW0gaWFtID0gbmV3IElhbSguLi4pO30KICAgICAqICAge0Bjb2RlIElhbS5Sb2xlcy5MaXN0IHJlcXVlc3QgPSBpYW0ucm9sZXMoKS5saXN0KHBhcmFtZXRlcnMgLi4uKX0KICAgICAqIDwvcHJlPgogICAgICoKICAgICAqIEByZXR1cm4gdGhlIHJlc291cmNlIGNvbGxlY3Rpb24KICAgICAqLwogICAgcHVibGljIFJvbGVzIHJvbGVzKCkgewogICAgICByZXR1cm4gbmV3IFJvbGVzKCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBUaGUgInJvbGVzIiBjb2xsZWN0aW9uIG9mIG1ldGhvZHMuCiAgICAgKi8KICAgIHB1YmxpYyBjbGFzcyBSb2xlcyB7CgogICAgICAvKioKICAgICAgICogQ3JlYXRlcyBhIG5ldyBSb2xlLgogICAgICAgKgogICAgICAgKiBDcmVhdGUgYSByZXF1ZXN0IGZvciB0aGUgbWV0aG9kICJyb2xlcy5jcmVhdGUiLgogICAgICAgKgogICAgICAgKiBUaGlzIHJlcXVlc3QgaG9sZHMgdGhlIHBhcmFtZXRlcnMgbmVlZGVkIGJ5IHRoZSBpYW0gc2VydmVyLiAgQWZ0ZXIgc2V0dGluZyBhbnkgb3B0aW9uYWwKICAgICAgICogcGFyYW1ldGVycywgY2FsbCB0aGUge0BsaW5rIENyZWF0ZSNleGVjdXRlKCl9IG1ldGhvZCB0byBpbnZva2UgdGhlIHJlbW90ZSBvcGVyYXRpb24uCiAgICAgICAqCiAgICAgICAqIEBwYXJhbSBwYXJlbnQgVGhlIGBwYXJlbnRgIHBhcmFtZXRlcidzIHZhbHVlIGRlcGVuZHMgb24gdGhlIHRhcmdldCByZXNvdXJjZSBmb3IgdGhlCiAgICAgIHJlcXVlc3QsIG5hbWVseQogICAgICAgKiAgICAgICAgW2Bwcm9qZWN0c2BdKC9pYW0vcmVmZXJlbmNlL3Jlc3QvdjEvcHJvamVjdHMucm9sZXMpIG9yCiAgICAgICAqICAgICAgICBbYG9yZ2FuaXphdGlvbnNgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL29yZ2FuaXphdGlvbnMucm9sZXMpLiBFYWNoCiAgICAgIHJlc291cmNlIHR5cGUncwogICAgICAgKiAgICAgICAgYHBhcmVudGAgdmFsdWUgZm9ybWF0IGlzIGRlc2NyaWJlZCBiZWxvdzoKICAgICAgKgogICAgICAgKiAgICAgICAgW2Bwcm9qZWN0cy5yb2xlcy5jcmVhdGUoKWBdKC9pYW0vcmVmZXJlbmNlL3Jlc3QvdjEvcHJvamVjdHMucm9sZXMvY3JlYXRlKToKICAgICAgICogICAgICAgIGBwcm9qZWN0cy97UFJPSkVDVF9JRH1gLiBUaGlzIG1ldGhvZCBjcmVhdGVzIHByb2plY3QtbGV2ZWwKICAgICAgICBbY3VzdG9tIHJvbGVzXSgvaWFtL2RvY3MKICAgICAgICogICAgICAgIC91bmRlcnN0YW5kaW5nLWN1c3RvbS1yb2xlcykuCiAgICAgICAgRXhhbXBsZSByZXF1ZXN0IFVSTDoKICAgICAgICogICAgICAgIGBodHRwczovL2lhbS5nb29nbGVhcGlzLmNvbS92MS9wcm9qZWN0cy97UFJPSkVDVF9JRH0vcm9sZXNgCiAgICAgICoKICAgICAgICogICAgICAgIFtgb3JnYW5pemF0aW9ucy5yb2xlcy5jcmVhdGUoKWBdKC9pYW0vcmVmZXJlbmNlL3Jlc3QvdjEvb3JnYW5pemF0aW9ucy5yb2xlcy9jcmVhdGUpOgogICAgICAgKiAgICAgICAgYG9yZ2FuaXphdGlvbnMve09SR0FOSVpBVElPTl9JRH1gLiBUaGlzIG1ldGhvZCBjcmVhdGVzIG9yZ2FuaXphdGlvbi1sZXZlbAogICAgICAgIFtjdXN0b20KICAgICAgICogICAgICAgIHJvbGVzXSgvaWFtL2RvY3MvdW5kZXJzdGFuZGluZy1jdXN0b20tcm9sZXMpLiBFeGFtcGxlIHJlcXVlc3QKICAgICAgICBVUkw6CiAgICAgICAqICAgICAgICBgaHR0cHM6Ly9pYW0uZ29vZ2xlYXBpcy5jb20vdjEvb3JnYW5pemF0aW9ucy97T1JHQU5JWkFUSU9OX0lEfS9yb2xlc2AKICAgICAgTm90ZTogV2lsZGNhcmQgKCopCiAgICAgICAqICAgICAgICB2YWx1ZXMgYXJlIGludmFsaWQ7IHlvdSBtdXN0IHNwZWNpZnkgYSBjb21wbGV0ZSBwcm9qZWN0CiAgICAgIElEIG9yIG9yZ2FuaXphdGlvbiBJRC4KICAgICAgICogQHBhcmFtIGNvbnRlbnQgdGhlIHtAbGluayBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5pYW0udjEubW9kZWwuQ3JlYXRlUm9sZVJlcXVlc3R9CiAgICAgICAqIEByZXR1cm4gdGhlIHJlcXVlc3QKICAgICAgICovCiAgICAgIHB1YmxpYyBDcmVhdGUgY3JlYXRlKGphdmEubGFuZy5TdHJpbmcgcGFyZW50LCBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5pYW0udjEubW9kZWwuQ3JlYXRlUm9sZVJlcXVlc3QgY29udGVudCkgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIENyZWF0ZSByZXN1bHQgPSBuZXcgQ3JlYXRlKHBhcmVudCwgY29udGVudCk7CiAgICAgICAgaW5pdGlhbGl6ZShyZXN1bHQpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBjbGFzcyBDcmVhdGUgZXh0ZW5kcyBJYW1SZXF1ZXN0PGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmlhbS52MS5tb2RlbC5Sb2xlPiB7CgogICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBSRVNUX1BBVEggPSAidjEveytwYXJlbnR9L3JvbGVzIjsKCiAgICAgICAgcHJpdmF0ZSBmaW5hbCBqYXZhLnV0aWwucmVnZXguUGF0dGVybiBQQVJFTlRfUEFUVEVSTiA9CiAgICAgICAgICAgIGphdmEudXRpbC5yZWdleC5QYXR0ZXJuLmNvbXBpbGUoIl5wcm9qZWN0cy9bXi9dKyQiKTsKCiAgICAgICAgLyoqCiAgICAgICAgICogQ3JlYXRlcyBhIG5ldyBSb2xlLgogICAgICAgICAqCiAgICAgICAgICogQ3JlYXRlIGEgcmVxdWVzdCBmb3IgdGhlIG1ldGhvZCAicm9sZXMuY3JlYXRlIi4KICAgICAgICAgKgogICAgICAgICAqIFRoaXMgcmVxdWVzdCBob2xkcyB0aGUgcGFyYW1ldGVycyBuZWVkZWQgYnkgdGhlIHRoZSBpYW0gc2VydmVyLiAgQWZ0ZXIgc2V0dGluZyBhbnkgb3B0aW9uYWwKICAgICAgICAgKiBwYXJhbWV0ZXJzLCBjYWxsIHRoZSB7QGxpbmsgQ3JlYXRlI2V4ZWN1dGUoKX0gbWV0aG9kIHRvIGludm9rZSB0aGUgcmVtb3RlIG9wZXJhdGlvbi4gPHA+IHtAbGluawogICAgICAgICAqIENyZWF0ZSNpbml0aWFsaXplKGNvbS5nb29nbGUuYXBpLmNsaWVudC5nb29nbGVhcGlzLnNlcnZpY2VzLkFic3RyYWN0R29vZ2xlQ2xpZW50UmVxdWVzdCl9IG11c3QKICAgICAgICAgKiBiZSBjYWxsZWQgdG8gaW5pdGlhbGl6ZSB0aGlzIGluc3RhbmNlIGltbWVkaWF0ZWx5IGFmdGVyIGludm9raW5nIHRoZSBjb25zdHJ1Y3Rvci4gPC9wPgogICAgICAgICAqCiAgICAgICAgICogQHBhcmFtIHBhcmVudCBUaGUgYHBhcmVudGAgcGFyYW1ldGVyJ3MgdmFsdWUgZGVwZW5kcyBvbiB0aGUgdGFyZ2V0IHJlc291cmNlIGZvciB0aGUKICAgICAgcmVxdWVzdCwgbmFtZWx5CiAgICAgICAqICAgICAgICBbYHByb2plY3RzYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9wcm9qZWN0cy5yb2xlcykgb3IKICAgICAgICogICAgICAgIFtgb3JnYW5pemF0aW9uc2BdKC9pYW0vcmVmZXJlbmNlL3Jlc3QvdjEvb3JnYW5pemF0aW9ucy5yb2xlcykuIEVhY2gKICAgICAgcmVzb3VyY2UgdHlwZSdzCiAgICAgICAqICAgICAgICBgcGFyZW50YCB2YWx1ZSBmb3JtYXQgaXMgZGVzY3JpYmVkIGJlbG93OgogICAgICAqCiAgICAgICAqICAgICAgICBbYHByb2plY3RzLnJvbGVzLmNyZWF0ZSgpYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9wcm9qZWN0cy5yb2xlcy9jcmVhdGUpOgogICAgICAgKiAgICAgICAgYHByb2plY3RzL3tQUk9KRUNUX0lEfWAuIFRoaXMgbWV0aG9kIGNyZWF0ZXMgcHJvamVjdC1sZXZlbAogICAgICAgIFtjdXN0b20gcm9sZXNdKC9pYW0vZG9jcwogICAgICAgKiAgICAgICAgL3VuZGVyc3RhbmRpbmctY3VzdG9tLXJvbGVzKS4KICAgICAgICBFeGFtcGxlIHJlcXVlc3QgVVJMOgogICAgICAgKiAgICAgICAgYGh0dHBzOi8vaWFtLmdvb2dsZWFwaXMuY29tL3YxL3Byb2plY3RzL3tQUk9KRUNUX0lEfS9yb2xlc2AKICAgICAgKgogICAgICAgKiAgICAgICAgW2Bvcmdhbml6YXRpb25zLnJvbGVzLmNyZWF0ZSgpYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9vcmdhbml6YXRpb25zLnJvbGVzL2NyZWF0ZSk6CiAgICAgICAqICAgICAgICBgb3JnYW5pemF0aW9ucy97T1JHQU5JWkFUSU9OX0lEfWAuIFRoaXMgbWV0aG9kIGNyZWF0ZXMgb3JnYW5pemF0aW9uLWxldmVsCiAgICAgICAgW2N1c3RvbQogICAgICAgKiAgICAgICAgcm9sZXNdKC9pYW0vZG9jcy91bmRlcnN0YW5kaW5nLWN1c3RvbS1yb2xlcykuIEV4YW1wbGUgcmVxdWVzdAogICAgICAgIFVSTDoKICAgICAgICogICAgICAgIGBodHRwczovL2lhbS5nb29nbGVhcGlzLmNvbS92MS9vcmdhbml6YXRpb25zL3tPUkdBTklaQVRJT05fSUR9L3JvbGVzYAogICAgICBOb3RlOiBXaWxkY2FyZCAoKikKICAgICAgICogICAgICAgIHZhbHVlcyBhcmUgaW52YWxpZDsgeW91IG11c3Qgc3BlY2lmeSBhIGNvbXBsZXRlIHByb2plY3QKICAgICAgSUQgb3Igb3JnYW5pemF0aW9uIElELgogICAgICAgICAqIEBwYXJhbSBjb250ZW50IHRoZSB7QGxpbmsgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuaWFtLnYxLm1vZGVsLkNyZWF0ZVJvbGVSZXF1ZXN0fQogICAgICAgICAqIEBzaW5jZSAxLjEzCiAgICAgICAgICovCiAgICAgICAgcHJvdGVjdGVkIENyZWF0ZShqYXZhLmxhbmcuU3RyaW5nIHBhcmVudCwgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuaWFtLnYxLm1vZGVsLkNyZWF0ZVJvbGVSZXF1ZXN0IGNvbnRlbnQpIHsKICAgICAgICAgIHN1cGVyKElhbS50aGlzLCAiUE9TVCIsIFJFU1RfUEFUSCwgY29udGVudCwgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuaWFtLnYxLm1vZGVsLlJvbGUuY2xhc3MpOwogICAgICAgICAgdGhpcy5wYXJlbnQgPSBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5QcmVjb25kaXRpb25zLmNoZWNrTm90TnVsbChwYXJlbnQsICJSZXF1aXJlZCBwYXJhbWV0ZXIgcGFyZW50IG11c3QgYmUgc3BlY2lmaWVkLiIpOwogICAgICAgICAgaWYgKCFnZXRTdXBwcmVzc1BhdHRlcm5DaGVja3MoKSkgewogICAgICAgICAgICBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5QcmVjb25kaXRpb25zLmNoZWNrQXJndW1lbnQoUEFSRU5UX1BBVFRFUk4ubWF0Y2hlcihwYXJlbnQpLm1hdGNoZXMoKSwKICAgICAgICAgICAgICAgICJQYXJhbWV0ZXIgcGFyZW50IG11c3QgY29uZm9ybSB0byB0aGUgcGF0dGVybiAiICsKICAgICAgICAgICAgICAgICJecHJvamVjdHMvW14vXSskIik7CiAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQ3JlYXRlIHNldCRYZ2FmdihqYXZhLmxhbmcuU3RyaW5nICRYZ2FmdikgewogICAgICAgICAgcmV0dXJuIChDcmVhdGUpIHN1cGVyLnNldCRYZ2FmdigkWGdhZnYpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIENyZWF0ZSBzZXRBY2Nlc3NUb2tlbihqYXZhLmxhbmcuU3RyaW5nIGFjY2Vzc1Rva2VuKSB7CiAgICAgICAgICByZXR1cm4gKENyZWF0ZSkgc3VwZXIuc2V0QWNjZXNzVG9rZW4oYWNjZXNzVG9rZW4pOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIENyZWF0ZSBzZXRBbHQoamF2YS5sYW5nLlN0cmluZyBhbHQpIHsKICAgICAgICAgIHJldHVybiAoQ3JlYXRlKSBzdXBlci5zZXRBbHQoYWx0KTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBDcmVhdGUgc2V0Q2FsbGJhY2soamF2YS5sYW5nLlN0cmluZyBjYWxsYmFjaykgewogICAgICAgICAgcmV0dXJuIChDcmVhdGUpIHN1cGVyLnNldENhbGxiYWNrKGNhbGxiYWNrKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBDcmVhdGUgc2V0RmllbGRzKGphdmEubGFuZy5TdHJpbmcgZmllbGRzKSB7CiAgICAgICAgICByZXR1cm4gKENyZWF0ZSkgc3VwZXIuc2V0RmllbGRzKGZpZWxkcyk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQ3JlYXRlIHNldEtleShqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgICAgcmV0dXJuIChDcmVhdGUpIHN1cGVyLnNldEtleShrZXkpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIENyZWF0ZSBzZXRPYXV0aFRva2VuKGphdmEubGFuZy5TdHJpbmcgb2F1dGhUb2tlbikgewogICAgICAgICAgcmV0dXJuIChDcmVhdGUpIHN1cGVyLnNldE9hdXRoVG9rZW4ob2F1dGhUb2tlbik7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQ3JlYXRlIHNldFByZXR0eVByaW50KGphdmEubGFuZy5Cb29sZWFuIHByZXR0eVByaW50KSB7CiAgICAgICAgICByZXR1cm4gKENyZWF0ZSkgc3VwZXIuc2V0UHJldHR5UHJpbnQocHJldHR5UHJpbnQpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIENyZWF0ZSBzZXRRdW90YVVzZXIoamF2YS5sYW5nLlN0cmluZyBxdW90YVVzZXIpIHsKICAgICAgICAgIHJldHVybiAoQ3JlYXRlKSBzdXBlci5zZXRRdW90YVVzZXIocXVvdGFVc2VyKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBDcmVhdGUgc2V0VXBsb2FkVHlwZShqYXZhLmxhbmcuU3RyaW5nIHVwbG9hZFR5cGUpIHsKICAgICAgICAgIHJldHVybiAoQ3JlYXRlKSBzdXBlci5zZXRVcGxvYWRUeXBlKHVwbG9hZFR5cGUpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIENyZWF0ZSBzZXRVcGxvYWRQcm90b2NvbChqYXZhLmxhbmcuU3RyaW5nIHVwbG9hZFByb3RvY29sKSB7CiAgICAgICAgICByZXR1cm4gKENyZWF0ZSkgc3VwZXIuc2V0VXBsb2FkUHJvdG9jb2wodXBsb2FkUHJvdG9jb2wpOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogVGhlIGBwYXJlbnRgIHBhcmFtZXRlcidzIHZhbHVlIGRlcGVuZHMgb24gdGhlIHRhcmdldCByZXNvdXJjZSBmb3IgdGhlIHJlcXVlc3QsIG5hbWVseQogICAgICAgICAqIFtgcHJvamVjdHNgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL3Byb2plY3RzLnJvbGVzKSBvcgogICAgICAgICAqIFtgb3JnYW5pemF0aW9uc2BdKC9pYW0vcmVmZXJlbmNlL3Jlc3QvdjEvb3JnYW5pemF0aW9ucy5yb2xlcykuIEVhY2ggcmVzb3VyY2UgdHlwZSdzCiAgICAgICAgICogYHBhcmVudGAgdmFsdWUgZm9ybWF0IGlzIGRlc2NyaWJlZCBiZWxvdzoKICAgICAgICAgKgogICAgICAgICAqICogW2Bwcm9qZWN0cy5yb2xlcy5jcmVhdGUoKWBdKC9pYW0vcmVmZXJlbmNlL3Jlc3QvdjEvcHJvamVjdHMucm9sZXMvY3JlYXRlKToKICAgICAgICAgKiBgcHJvamVjdHMve1BST0pFQ1RfSUR9YC4gVGhpcyBtZXRob2QgY3JlYXRlcyBwcm9qZWN0LWxldmVsIFtjdXN0b20gcm9sZXNdKC9pYW0vZG9jcwogICAgICAgICAqIC91bmRlcnN0YW5kaW5nLWN1c3RvbS1yb2xlcykuIEV4YW1wbGUgcmVxdWVzdCBVUkw6CiAgICAgICAgICogYGh0dHBzOi8vaWFtLmdvb2dsZWFwaXMuY29tL3YxL3Byb2plY3RzL3tQUk9KRUNUX0lEfS9yb2xlc2AKICAgICAgICAgKgogICAgICAgICAqICogW2Bvcmdhbml6YXRpb25zLnJvbGVzLmNyZWF0ZSgpYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9vcmdhbml6YXRpb25zLnJvbGVzL2NyZWF0ZSk6CiAgICAgICAgICogYG9yZ2FuaXphdGlvbnMve09SR0FOSVpBVElPTl9JRH1gLiBUaGlzIG1ldGhvZCBjcmVhdGVzIG9yZ2FuaXphdGlvbi1sZXZlbCBbY3VzdG9tCiAgICAgICAgICogcm9sZXNdKC9pYW0vZG9jcy91bmRlcnN0YW5kaW5nLWN1c3RvbS1yb2xlcykuIEV4YW1wbGUgcmVxdWVzdCBVUkw6CiAgICAgICAgICogYGh0dHBzOi8vaWFtLmdvb2dsZWFwaXMuY29tL3YxL29yZ2FuaXphdGlvbnMve09SR0FOSVpBVElPTl9JRH0vcm9sZXNgCiAgICAgICAgICoKICAgICAgICAgKiBOb3RlOiBXaWxkY2FyZCAoKikgdmFsdWVzIGFyZSBpbnZhbGlkOyB5b3UgbXVzdCBzcGVjaWZ5IGEgY29tcGxldGUgcHJvamVjdCBJRCBvcgogICAgICAgICAqIG9yZ2FuaXphdGlvbiBJRC4KICAgICAgICAgKi8KICAgICAgICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuU3RyaW5nIHBhcmVudDsKCiAgICAgICAgLyoqIFRoZSBgcGFyZW50YCBwYXJhbWV0ZXIncyB2YWx1ZSBkZXBlbmRzIG9uIHRoZSB0YXJnZXQgcmVzb3VyY2UgZm9yIHRoZSByZXF1ZXN0LCBuYW1lbHkKICAgICAgIFtgcHJvamVjdHNgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL3Byb2plY3RzLnJvbGVzKSBvcgogICAgICAgW2Bvcmdhbml6YXRpb25zYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9vcmdhbml6YXRpb25zLnJvbGVzKS4gRWFjaCByZXNvdXJjZSB0eXBlJ3MgYHBhcmVudGAgdmFsdWUKICAgICAgIGZvcm1hdCBpcyBkZXNjcmliZWQgYmVsb3c6CgogICAgICAgKiBbYHByb2plY3RzLnJvbGVzLmNyZWF0ZSgpYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9wcm9qZWN0cy5yb2xlcy9jcmVhdGUpOgogICAgICAgYHByb2plY3RzL3tQUk9KRUNUX0lEfWAuIFRoaXMgbWV0aG9kIGNyZWF0ZXMgcHJvamVjdC1sZXZlbCBbY3VzdG9tIHJvbGVzXSgvaWFtL2RvY3MvdW5kZXJzdGFuZGluZy0KICAgICAgIGN1c3RvbS1yb2xlcykuIEV4YW1wbGUgcmVxdWVzdCBVUkw6IGBodHRwczovL2lhbS5nb29nbGVhcGlzLmNvbS92MS9wcm9qZWN0cy97UFJPSkVDVF9JRH0vcm9sZXNgCgogICAgICAgKiBbYG9yZ2FuaXphdGlvbnMucm9sZXMuY3JlYXRlKClgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL29yZ2FuaXphdGlvbnMucm9sZXMvY3JlYXRlKToKICAgICAgIGBvcmdhbml6YXRpb25zL3tPUkdBTklaQVRJT05fSUR9YC4gVGhpcyBtZXRob2QgY3JlYXRlcyBvcmdhbml6YXRpb24tbGV2ZWwgW2N1c3RvbSByb2xlc10oL2lhbS9kb2NzCiAgICAgICAvdW5kZXJzdGFuZGluZy1jdXN0b20tcm9sZXMpLiBFeGFtcGxlIHJlcXVlc3QgVVJMOgogICAgICAgYGh0dHBzOi8vaWFtLmdvb2dsZWFwaXMuY29tL3YxL29yZ2FuaXphdGlvbnMve09SR0FOSVpBVElPTl9JRH0vcm9sZXNgCgogICAgICAgTm90ZTogV2lsZGNhcmQgKCopIHZhbHVlcyBhcmUgaW52YWxpZDsgeW91IG11c3Qgc3BlY2lmeSBhIGNvbXBsZXRlIHByb2plY3QgSUQgb3Igb3JnYW5pemF0aW9uIElELgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFBhcmVudCgpIHsKICAgICAgICAgIHJldHVybiBwYXJlbnQ7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiBUaGUgYHBhcmVudGAgcGFyYW1ldGVyJ3MgdmFsdWUgZGVwZW5kcyBvbiB0aGUgdGFyZ2V0IHJlc291cmNlIGZvciB0aGUgcmVxdWVzdCwgbmFtZWx5CiAgICAgICAgICogW2Bwcm9qZWN0c2BdKC9pYW0vcmVmZXJlbmNlL3Jlc3QvdjEvcHJvamVjdHMucm9sZXMpIG9yCiAgICAgICAgICogW2Bvcmdhbml6YXRpb25zYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9vcmdhbml6YXRpb25zLnJvbGVzKS4gRWFjaCByZXNvdXJjZSB0eXBlJ3MKICAgICAgICAgKiBgcGFyZW50YCB2YWx1ZSBmb3JtYXQgaXMgZGVzY3JpYmVkIGJlbG93OgogICAgICAgICAqCiAgICAgICAgICogKiBbYHByb2plY3RzLnJvbGVzLmNyZWF0ZSgpYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9wcm9qZWN0cy5yb2xlcy9jcmVhdGUpOgogICAgICAgICAqIGBwcm9qZWN0cy97UFJPSkVDVF9JRH1gLiBUaGlzIG1ldGhvZCBjcmVhdGVzIHByb2plY3QtbGV2ZWwgW2N1c3RvbSByb2xlc10oL2lhbS9kb2NzCiAgICAgICAgICogL3VuZGVyc3RhbmRpbmctY3VzdG9tLXJvbGVzKS4gRXhhbXBsZSByZXF1ZXN0IFVSTDoKICAgICAgICAgKiBgaHR0cHM6Ly9pYW0uZ29vZ2xlYXBpcy5jb20vdjEvcHJvamVjdHMve1BST0pFQ1RfSUR9L3JvbGVzYAogICAgICAgICAqCiAgICAgICAgICogKiBbYG9yZ2FuaXphdGlvbnMucm9sZXMuY3JlYXRlKClgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL29yZ2FuaXphdGlvbnMucm9sZXMvY3JlYXRlKToKICAgICAgICAgKiBgb3JnYW5pemF0aW9ucy97T1JHQU5JWkFUSU9OX0lEfWAuIFRoaXMgbWV0aG9kIGNyZWF0ZXMgb3JnYW5pemF0aW9uLWxldmVsIFtjdXN0b20KICAgICAgICAgKiByb2xlc10oL2lhbS9kb2NzL3VuZGVyc3RhbmRpbmctY3VzdG9tLXJvbGVzKS4gRXhhbXBsZSByZXF1ZXN0IFVSTDoKICAgICAgICAgKiBgaHR0cHM6Ly9pYW0uZ29vZ2xlYXBpcy5jb20vdjEvb3JnYW5pemF0aW9ucy97T1JHQU5JWkFUSU9OX0lEfS9yb2xlc2AKICAgICAgICAgKgogICAgICAgICAqIE5vdGU6IFdpbGRjYXJkICgqKSB2YWx1ZXMgYXJlIGludmFsaWQ7IHlvdSBtdXN0IHNwZWNpZnkgYSBjb21wbGV0ZSBwcm9qZWN0IElEIG9yCiAgICAgICAgICogb3JnYW5pemF0aW9uIElELgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBDcmVhdGUgc2V0UGFyZW50KGphdmEubGFuZy5TdHJpbmcgcGFyZW50KSB7CiAgICAgICAgICBpZiAoIWdldFN1cHByZXNzUGF0dGVybkNoZWNrcygpKSB7CiAgICAgICAgICAgIGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLlByZWNvbmRpdGlvbnMuY2hlY2tBcmd1bWVudChQQVJFTlRfUEFUVEVSTi5tYXRjaGVyKHBhcmVudCkubWF0Y2hlcygpLAogICAgICAgICAgICAgICAgIlBhcmFtZXRlciBwYXJlbnQgbXVzdCBjb25mb3JtIHRvIHRoZSBwYXR0ZXJuICIgKwogICAgICAgICAgICAgICAgIl5wcm9qZWN0cy9bXi9dKyQiKTsKICAgICAgICAgIH0KICAgICAgICAgIHRoaXMucGFyZW50ID0gcGFyZW50OwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQ3JlYXRlIHNldChTdHJpbmcgcGFyYW1ldGVyTmFtZSwgT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgICByZXR1cm4gKENyZWF0ZSkgc3VwZXIuc2V0KHBhcmFtZXRlck5hbWUsIHZhbHVlKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFNvZnQgZGVsZXRlcyBhIHJvbGUuIFRoZSByb2xlIGlzIHN1c3BlbmRlZCBhbmQgY2Fubm90IGJlIHVzZWQgdG8gY3JlYXRlIG5ldyBJQU0gUG9saWN5IEJpbmRpbmdzLgogICAgICAgKiBUaGUgUm9sZSB3aWxsIG5vdCBiZSBpbmNsdWRlZCBpbiBgTGlzdFJvbGVzKClgIHVubGVzcyBgc2hvd19kZWxldGVkYCBpcyBzZXQgaW4gdGhlCiAgICAgICAqIGBMaXN0Um9sZXNSZXF1ZXN0YC4gVGhlIFJvbGUgY29udGFpbnMgdGhlIGRlbGV0ZWQgYm9vbGVhbiBzZXQuIEV4aXN0aW5nIEJpbmRpbmdzIHJlbWFpbnMsIGJ1dCBhcmUKICAgICAgICogaW5hY3RpdmUuIFRoZSBSb2xlIGNhbiBiZSB1bmRlbGV0ZWQgd2l0aGluIDcgZGF5cy4gQWZ0ZXIgNyBkYXlzIHRoZSBSb2xlIGlzIGRlbGV0ZWQgYW5kIGFsbAogICAgICAgKiBCaW5kaW5ncyBhc3NvY2lhdGVkIHdpdGggdGhlIHJvbGUgYXJlIHJlbW92ZWQuCiAgICAgICAqCiAgICAgICAqIENyZWF0ZSBhIHJlcXVlc3QgZm9yIHRoZSBtZXRob2QgInJvbGVzLmRlbGV0ZSIuCiAgICAgICAqCiAgICAgICAqIFRoaXMgcmVxdWVzdCBob2xkcyB0aGUgcGFyYW1ldGVycyBuZWVkZWQgYnkgdGhlIGlhbSBzZXJ2ZXIuICBBZnRlciBzZXR0aW5nIGFueSBvcHRpb25hbAogICAgICAgKiBwYXJhbWV0ZXJzLCBjYWxsIHRoZSB7QGxpbmsgRGVsZXRlI2V4ZWN1dGUoKX0gbWV0aG9kIHRvIGludm9rZSB0aGUgcmVtb3RlIG9wZXJhdGlvbi4KICAgICAgICoKICAgICAgICogQHBhcmFtIG5hbWUgVGhlIGBuYW1lYCBwYXJhbWV0ZXIncyB2YWx1ZSBkZXBlbmRzIG9uIHRoZSB0YXJnZXQgcmVzb3VyY2UgZm9yIHRoZQogICAgICByZXF1ZXN0LCBuYW1lbHkKICAgICAgICogICAgICAgIFtgcHJvamVjdHNgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL3Byb2plY3RzLnJvbGVzKSBvcgogICAgICAgKiAgICAgICAgW2Bvcmdhbml6YXRpb25zYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9vcmdhbml6YXRpb25zLnJvbGVzKS4gRWFjaAogICAgICByZXNvdXJjZSB0eXBlJ3MgYG5hbWVgCiAgICAgICAqICAgICAgICB2YWx1ZSBmb3JtYXQgaXMgZGVzY3JpYmVkIGJlbG93OgogICAgICAqCiAgICAgICAqICAgICAgICBbYHByb2plY3RzLnJvbGVzLmRlbGV0ZSgpYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9wcm9qZWN0cy5yb2xlcy9kZWxldGUpOgogICAgICAgKiAgICAgICAgYHByb2plY3RzL3tQUk9KRUNUX0lEfS9yb2xlcy97Q1VTVE9NX1JPTEVfSUR9YC4gVGhpcyBtZXRob2QgZGVsZXRlcyBvbmx5CiAgICAgICAgW2N1c3RvbQogICAgICAgKiAgICAgICAgcm9sZXNdKC9pYW0vZG9jcy91bmRlcnN0YW5kaW5nLWN1c3RvbS1yb2xlcykgdGhhdCBoYXZlIGJlZW4KICAgICAgICBjcmVhdGVkIGF0IHRoZSBwcm9qZWN0CiAgICAgICAqICAgICAgICBsZXZlbC4gRXhhbXBsZSByZXF1ZXN0IFVSTDoKICAgICAgICogICAgICAgIGBodHRwczovL2lhbS5nb29nbGVhcGlzLmNvbS92MS9wcm9qZWN0cy97UFJPSkVDVF9JRH0vcm9sZXMve0NVU1RPTV9ST0xFX0lEfWAKICAgICAgKgogICAgICAgKiAgICAgICAgW2Bvcmdhbml6YXRpb25zLnJvbGVzLmRlbGV0ZSgpYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9vcmdhbml6YXRpb25zLnJvbGVzL2RlbGV0ZSk6CiAgICAgICAqICAgICAgICBgb3JnYW5pemF0aW9ucy97T1JHQU5JWkFUSU9OX0lEfS9yb2xlcy97Q1VTVE9NX1JPTEVfSUR9YC4gVGhpcyBtZXRob2QKICAgICAgICBkZWxldGVzIG9ubHkKICAgICAgICogICAgICAgIFtjdXN0b20gcm9sZXNdKC9pYW0vZG9jcy91bmRlcnN0YW5kaW5nLWN1c3RvbS1yb2xlcykgdGhhdAogICAgICAgIGhhdmUgYmVlbiBjcmVhdGVkIGF0IHRoZQogICAgICAgKiAgICAgICAgb3JnYW5pemF0aW9uIGxldmVsLiBFeGFtcGxlIHJlcXVlc3QgVVJMOgogICAgICAgKiAgICAgICAgYGh0dHBzOi8vaWFtLmdvb2dsZWFwaXMuY29tL3YxL29yZ2FuaXphdGlvbnMve09SR0FOSVpBVElPTl9JRH0vcm9sZXMve0NVU1RPTV9ST0xFX0lEfWAKICAgICAgICogICAgICAgIE5vdGU6IFdpbGRjYXJkICgqKSB2YWx1ZXMgYXJlIGludmFsaWQ7IHlvdSBtdXN0IHNwZWNpZnkgYSBjb21wbGV0ZSBwcm9qZWN0CiAgICAgIElEIG9yCiAgICAgICAqICAgICAgICBvcmdhbml6YXRpb24gSUQuCiAgICAgICAqIEByZXR1cm4gdGhlIHJlcXVlc3QKICAgICAgICovCiAgICAgIHB1YmxpYyBEZWxldGUgZGVsZXRlKGphdmEubGFuZy5TdHJpbmcgbmFtZSkgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIERlbGV0ZSByZXN1bHQgPSBuZXcgRGVsZXRlKG5hbWUpOwogICAgICAgIGluaXRpYWxpemUocmVzdWx0KTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBwdWJsaWMgY2xhc3MgRGVsZXRlIGV4dGVuZHMgSWFtUmVxdWVzdDxjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5pYW0udjEubW9kZWwuUm9sZT4gewoKICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgUkVTVF9QQVRIID0gInYxL3srbmFtZX0iOwoKICAgICAgICBwcml2YXRlIGZpbmFsIGphdmEudXRpbC5yZWdleC5QYXR0ZXJuIE5BTUVfUEFUVEVSTiA9CiAgICAgICAgICAgIGphdmEudXRpbC5yZWdleC5QYXR0ZXJuLmNvbXBpbGUoIl5wcm9qZWN0cy9bXi9dKy9yb2xlcy9bXi9dKyQiKTsKCiAgICAgICAgLyoqCiAgICAgICAgICogU29mdCBkZWxldGVzIGEgcm9sZS4gVGhlIHJvbGUgaXMgc3VzcGVuZGVkIGFuZCBjYW5ub3QgYmUgdXNlZCB0byBjcmVhdGUgbmV3IElBTSBQb2xpY3kKICAgICAgICAgKiBCaW5kaW5ncy4gVGhlIFJvbGUgd2lsbCBub3QgYmUgaW5jbHVkZWQgaW4gYExpc3RSb2xlcygpYCB1bmxlc3MgYHNob3dfZGVsZXRlZGAgaXMgc2V0IGluIHRoZQogICAgICAgICAqIGBMaXN0Um9sZXNSZXF1ZXN0YC4gVGhlIFJvbGUgY29udGFpbnMgdGhlIGRlbGV0ZWQgYm9vbGVhbiBzZXQuIEV4aXN0aW5nIEJpbmRpbmdzIHJlbWFpbnMsIGJ1dAogICAgICAgICAqIGFyZSBpbmFjdGl2ZS4gVGhlIFJvbGUgY2FuIGJlIHVuZGVsZXRlZCB3aXRoaW4gNyBkYXlzLiBBZnRlciA3IGRheXMgdGhlIFJvbGUgaXMgZGVsZXRlZCBhbmQgYWxsCiAgICAgICAgICogQmluZGluZ3MgYXNzb2NpYXRlZCB3aXRoIHRoZSByb2xlIGFyZSByZW1vdmVkLgogICAgICAgICAqCiAgICAgICAgICogQ3JlYXRlIGEgcmVxdWVzdCBmb3IgdGhlIG1ldGhvZCAicm9sZXMuZGVsZXRlIi4KICAgICAgICAgKgogICAgICAgICAqIFRoaXMgcmVxdWVzdCBob2xkcyB0aGUgcGFyYW1ldGVycyBuZWVkZWQgYnkgdGhlIHRoZSBpYW0gc2VydmVyLiAgQWZ0ZXIgc2V0dGluZyBhbnkgb3B0aW9uYWwKICAgICAgICAgKiBwYXJhbWV0ZXJzLCBjYWxsIHRoZSB7QGxpbmsgRGVsZXRlI2V4ZWN1dGUoKX0gbWV0aG9kIHRvIGludm9rZSB0aGUgcmVtb3RlIG9wZXJhdGlvbi4gPHA+IHtAbGluawogICAgICAgICAqIERlbGV0ZSNpbml0aWFsaXplKGNvbS5nb29nbGUuYXBpLmNsaWVudC5nb29nbGVhcGlzLnNlcnZpY2VzLkFic3RyYWN0R29vZ2xlQ2xpZW50UmVxdWVzdCl9IG11c3QKICAgICAgICAgKiBiZSBjYWxsZWQgdG8gaW5pdGlhbGl6ZSB0aGlzIGluc3RhbmNlIGltbWVkaWF0ZWx5IGFmdGVyIGludm9raW5nIHRoZSBjb25zdHJ1Y3Rvci4gPC9wPgogICAgICAgICAqCiAgICAgICAgICogQHBhcmFtIG5hbWUgVGhlIGBuYW1lYCBwYXJhbWV0ZXIncyB2YWx1ZSBkZXBlbmRzIG9uIHRoZSB0YXJnZXQgcmVzb3VyY2UgZm9yIHRoZQogICAgICByZXF1ZXN0LCBuYW1lbHkKICAgICAgICogICAgICAgIFtgcHJvamVjdHNgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL3Byb2plY3RzLnJvbGVzKSBvcgogICAgICAgKiAgICAgICAgW2Bvcmdhbml6YXRpb25zYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9vcmdhbml6YXRpb25zLnJvbGVzKS4gRWFjaAogICAgICByZXNvdXJjZSB0eXBlJ3MgYG5hbWVgCiAgICAgICAqICAgICAgICB2YWx1ZSBmb3JtYXQgaXMgZGVzY3JpYmVkIGJlbG93OgogICAgICAqCiAgICAgICAqICAgICAgICBbYHByb2plY3RzLnJvbGVzLmRlbGV0ZSgpYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9wcm9qZWN0cy5yb2xlcy9kZWxldGUpOgogICAgICAgKiAgICAgICAgYHByb2plY3RzL3tQUk9KRUNUX0lEfS9yb2xlcy97Q1VTVE9NX1JPTEVfSUR9YC4gVGhpcyBtZXRob2QgZGVsZXRlcyBvbmx5CiAgICAgICAgW2N1c3RvbQogICAgICAgKiAgICAgICAgcm9sZXNdKC9pYW0vZG9jcy91bmRlcnN0YW5kaW5nLWN1c3RvbS1yb2xlcykgdGhhdCBoYXZlIGJlZW4KICAgICAgICBjcmVhdGVkIGF0IHRoZSBwcm9qZWN0CiAgICAgICAqICAgICAgICBsZXZlbC4gRXhhbXBsZSByZXF1ZXN0IFVSTDoKICAgICAgICogICAgICAgIGBodHRwczovL2lhbS5nb29nbGVhcGlzLmNvbS92MS9wcm9qZWN0cy97UFJPSkVDVF9JRH0vcm9sZXMve0NVU1RPTV9ST0xFX0lEfWAKICAgICAgKgogICAgICAgKiAgICAgICAgW2Bvcmdhbml6YXRpb25zLnJvbGVzLmRlbGV0ZSgpYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9vcmdhbml6YXRpb25zLnJvbGVzL2RlbGV0ZSk6CiAgICAgICAqICAgICAgICBgb3JnYW5pemF0aW9ucy97T1JHQU5JWkFUSU9OX0lEfS9yb2xlcy97Q1VTVE9NX1JPTEVfSUR9YC4gVGhpcyBtZXRob2QKICAgICAgICBkZWxldGVzIG9ubHkKICAgICAgICogICAgICAgIFtjdXN0b20gcm9sZXNdKC9pYW0vZG9jcy91bmRlcnN0YW5kaW5nLWN1c3RvbS1yb2xlcykgdGhhdAogICAgICAgIGhhdmUgYmVlbiBjcmVhdGVkIGF0IHRoZQogICAgICAgKiAgICAgICAgb3JnYW5pemF0aW9uIGxldmVsLiBFeGFtcGxlIHJlcXVlc3QgVVJMOgogICAgICAgKiAgICAgICAgYGh0dHBzOi8vaWFtLmdvb2dsZWFwaXMuY29tL3YxL29yZ2FuaXphdGlvbnMve09SR0FOSVpBVElPTl9JRH0vcm9sZXMve0NVU1RPTV9ST0xFX0lEfWAKICAgICAgICogICAgICAgIE5vdGU6IFdpbGRjYXJkICgqKSB2YWx1ZXMgYXJlIGludmFsaWQ7IHlvdSBtdXN0IHNwZWNpZnkgYSBjb21wbGV0ZSBwcm9qZWN0CiAgICAgIElEIG9yCiAgICAgICAqICAgICAgICBvcmdhbml6YXRpb24gSUQuCiAgICAgICAgICogQHNpbmNlIDEuMTMKICAgICAgICAgKi8KICAgICAgICBwcm90ZWN0ZWQgRGVsZXRlKGphdmEubGFuZy5TdHJpbmcgbmFtZSkgewogICAgICAgICAgc3VwZXIoSWFtLnRoaXMsICJERUxFVEUiLCBSRVNUX1BBVEgsIG51bGwsIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmlhbS52MS5tb2RlbC5Sb2xlLmNsYXNzKTsKICAgICAgICAgIHRoaXMubmFtZSA9IGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLlByZWNvbmRpdGlvbnMuY2hlY2tOb3ROdWxsKG5hbWUsICJSZXF1aXJlZCBwYXJhbWV0ZXIgbmFtZSBtdXN0IGJlIHNwZWNpZmllZC4iKTsKICAgICAgICAgIGlmICghZ2V0U3VwcHJlc3NQYXR0ZXJuQ2hlY2tzKCkpIHsKICAgICAgICAgICAgY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuUHJlY29uZGl0aW9ucy5jaGVja0FyZ3VtZW50KE5BTUVfUEFUVEVSTi5tYXRjaGVyKG5hbWUpLm1hdGNoZXMoKSwKICAgICAgICAgICAgICAgICJQYXJhbWV0ZXIgbmFtZSBtdXN0IGNvbmZvcm0gdG8gdGhlIHBhdHRlcm4gIiArCiAgICAgICAgICAgICAgICAiXnByb2plY3RzL1teL10rL3JvbGVzL1teL10rJCIpOwogICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIERlbGV0ZSBzZXQkWGdhZnYoamF2YS5sYW5nLlN0cmluZyAkWGdhZnYpIHsKICAgICAgICAgIHJldHVybiAoRGVsZXRlKSBzdXBlci5zZXQkWGdhZnYoJFhnYWZ2KTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBEZWxldGUgc2V0QWNjZXNzVG9rZW4oamF2YS5sYW5nLlN0cmluZyBhY2Nlc3NUb2tlbikgewogICAgICAgICAgcmV0dXJuIChEZWxldGUpIHN1cGVyLnNldEFjY2Vzc1Rva2VuKGFjY2Vzc1Rva2VuKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBEZWxldGUgc2V0QWx0KGphdmEubGFuZy5TdHJpbmcgYWx0KSB7CiAgICAgICAgICByZXR1cm4gKERlbGV0ZSkgc3VwZXIuc2V0QWx0KGFsdCk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgRGVsZXRlIHNldENhbGxiYWNrKGphdmEubGFuZy5TdHJpbmcgY2FsbGJhY2spIHsKICAgICAgICAgIHJldHVybiAoRGVsZXRlKSBzdXBlci5zZXRDYWxsYmFjayhjYWxsYmFjayk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgRGVsZXRlIHNldEZpZWxkcyhqYXZhLmxhbmcuU3RyaW5nIGZpZWxkcykgewogICAgICAgICAgcmV0dXJuIChEZWxldGUpIHN1cGVyLnNldEZpZWxkcyhmaWVsZHMpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIERlbGV0ZSBzZXRLZXkoamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICAgIHJldHVybiAoRGVsZXRlKSBzdXBlci5zZXRLZXkoa2V5KTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBEZWxldGUgc2V0T2F1dGhUb2tlbihqYXZhLmxhbmcuU3RyaW5nIG9hdXRoVG9rZW4pIHsKICAgICAgICAgIHJldHVybiAoRGVsZXRlKSBzdXBlci5zZXRPYXV0aFRva2VuKG9hdXRoVG9rZW4pOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIERlbGV0ZSBzZXRQcmV0dHlQcmludChqYXZhLmxhbmcuQm9vbGVhbiBwcmV0dHlQcmludCkgewogICAgICAgICAgcmV0dXJuIChEZWxldGUpIHN1cGVyLnNldFByZXR0eVByaW50KHByZXR0eVByaW50KTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBEZWxldGUgc2V0UXVvdGFVc2VyKGphdmEubGFuZy5TdHJpbmcgcXVvdGFVc2VyKSB7CiAgICAgICAgICByZXR1cm4gKERlbGV0ZSkgc3VwZXIuc2V0UXVvdGFVc2VyKHF1b3RhVXNlcik7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgRGVsZXRlIHNldFVwbG9hZFR5cGUoamF2YS5sYW5nLlN0cmluZyB1cGxvYWRUeXBlKSB7CiAgICAgICAgICByZXR1cm4gKERlbGV0ZSkgc3VwZXIuc2V0VXBsb2FkVHlwZSh1cGxvYWRUeXBlKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBEZWxldGUgc2V0VXBsb2FkUHJvdG9jb2woamF2YS5sYW5nLlN0cmluZyB1cGxvYWRQcm90b2NvbCkgewogICAgICAgICAgcmV0dXJuIChEZWxldGUpIHN1cGVyLnNldFVwbG9hZFByb3RvY29sKHVwbG9hZFByb3RvY29sKTsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIFRoZSBgbmFtZWAgcGFyYW1ldGVyJ3MgdmFsdWUgZGVwZW5kcyBvbiB0aGUgdGFyZ2V0IHJlc291cmNlIGZvciB0aGUgcmVxdWVzdCwgbmFtZWx5CiAgICAgICAgICogW2Bwcm9qZWN0c2BdKC9pYW0vcmVmZXJlbmNlL3Jlc3QvdjEvcHJvamVjdHMucm9sZXMpIG9yCiAgICAgICAgICogW2Bvcmdhbml6YXRpb25zYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9vcmdhbml6YXRpb25zLnJvbGVzKS4gRWFjaCByZXNvdXJjZSB0eXBlJ3MKICAgICAgICAgKiBgbmFtZWAgdmFsdWUgZm9ybWF0IGlzIGRlc2NyaWJlZCBiZWxvdzoKICAgICAgICAgKgogICAgICAgICAqICogW2Bwcm9qZWN0cy5yb2xlcy5kZWxldGUoKWBdKC9pYW0vcmVmZXJlbmNlL3Jlc3QvdjEvcHJvamVjdHMucm9sZXMvZGVsZXRlKToKICAgICAgICAgKiBgcHJvamVjdHMve1BST0pFQ1RfSUR9L3JvbGVzL3tDVVNUT01fUk9MRV9JRH1gLiBUaGlzIG1ldGhvZCBkZWxldGVzIG9ubHkgW2N1c3RvbQogICAgICAgICAqIHJvbGVzXSgvaWFtL2RvY3MvdW5kZXJzdGFuZGluZy1jdXN0b20tcm9sZXMpIHRoYXQgaGF2ZSBiZWVuIGNyZWF0ZWQgYXQgdGhlIHByb2plY3QgbGV2ZWwuCiAgICAgICAgICogRXhhbXBsZSByZXF1ZXN0IFVSTDoKICAgICAgICAgKiBgaHR0cHM6Ly9pYW0uZ29vZ2xlYXBpcy5jb20vdjEvcHJvamVjdHMve1BST0pFQ1RfSUR9L3JvbGVzL3tDVVNUT01fUk9MRV9JRH1gCiAgICAgICAgICoKICAgICAgICAgKiAqIFtgb3JnYW5pemF0aW9ucy5yb2xlcy5kZWxldGUoKWBdKC9pYW0vcmVmZXJlbmNlL3Jlc3QvdjEvb3JnYW5pemF0aW9ucy5yb2xlcy9kZWxldGUpOgogICAgICAgICAqIGBvcmdhbml6YXRpb25zL3tPUkdBTklaQVRJT05fSUR9L3JvbGVzL3tDVVNUT01fUk9MRV9JRH1gLiBUaGlzIG1ldGhvZCBkZWxldGVzIG9ubHkKICAgICAgICAgKiBbY3VzdG9tIHJvbGVzXSgvaWFtL2RvY3MvdW5kZXJzdGFuZGluZy1jdXN0b20tcm9sZXMpIHRoYXQgaGF2ZSBiZWVuIGNyZWF0ZWQgYXQgdGhlCiAgICAgICAgICogb3JnYW5pemF0aW9uIGxldmVsLiBFeGFtcGxlIHJlcXVlc3QgVVJMOgogICAgICAgICAqIGBodHRwczovL2lhbS5nb29nbGVhcGlzLmNvbS92MS9vcmdhbml6YXRpb25zL3tPUkdBTklaQVRJT05fSUR9L3JvbGVzL3tDVVNUT01fUk9MRV9JRH1gCiAgICAgICAgICoKICAgICAgICAgKiBOb3RlOiBXaWxkY2FyZCAoKikgdmFsdWVzIGFyZSBpbnZhbGlkOyB5b3UgbXVzdCBzcGVjaWZ5IGEgY29tcGxldGUgcHJvamVjdCBJRCBvcgogICAgICAgICAqIG9yZ2FuaXphdGlvbiBJRC4KICAgICAgICAgKi8KICAgICAgICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuU3RyaW5nIG5hbWU7CgogICAgICAgIC8qKiBUaGUgYG5hbWVgIHBhcmFtZXRlcidzIHZhbHVlIGRlcGVuZHMgb24gdGhlIHRhcmdldCByZXNvdXJjZSBmb3IgdGhlIHJlcXVlc3QsIG5hbWVseQogICAgICAgW2Bwcm9qZWN0c2BdKC9pYW0vcmVmZXJlbmNlL3Jlc3QvdjEvcHJvamVjdHMucm9sZXMpIG9yCiAgICAgICBbYG9yZ2FuaXphdGlvbnNgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL29yZ2FuaXphdGlvbnMucm9sZXMpLiBFYWNoIHJlc291cmNlIHR5cGUncyBgbmFtZWAgdmFsdWUKICAgICAgIGZvcm1hdCBpcyBkZXNjcmliZWQgYmVsb3c6CgogICAgICAgKiBbYHByb2plY3RzLnJvbGVzLmRlbGV0ZSgpYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9wcm9qZWN0cy5yb2xlcy9kZWxldGUpOgogICAgICAgYHByb2plY3RzL3tQUk9KRUNUX0lEfS9yb2xlcy97Q1VTVE9NX1JPTEVfSUR9YC4gVGhpcyBtZXRob2QgZGVsZXRlcyBvbmx5IFtjdXN0b20gcm9sZXNdKC9pYW0vZG9jcwogICAgICAgL3VuZGVyc3RhbmRpbmctY3VzdG9tLXJvbGVzKSB0aGF0IGhhdmUgYmVlbiBjcmVhdGVkIGF0IHRoZSBwcm9qZWN0IGxldmVsLiBFeGFtcGxlIHJlcXVlc3QgVVJMOgogICAgICAgYGh0dHBzOi8vaWFtLmdvb2dsZWFwaXMuY29tL3YxL3Byb2plY3RzL3tQUk9KRUNUX0lEfS9yb2xlcy97Q1VTVE9NX1JPTEVfSUR9YAoKICAgICAgICogW2Bvcmdhbml6YXRpb25zLnJvbGVzLmRlbGV0ZSgpYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9vcmdhbml6YXRpb25zLnJvbGVzL2RlbGV0ZSk6CiAgICAgICBgb3JnYW5pemF0aW9ucy97T1JHQU5JWkFUSU9OX0lEfS9yb2xlcy97Q1VTVE9NX1JPTEVfSUR9YC4gVGhpcyBtZXRob2QgZGVsZXRlcyBvbmx5IFtjdXN0b20KICAgICAgIHJvbGVzXSgvaWFtL2RvY3MvdW5kZXJzdGFuZGluZy1jdXN0b20tcm9sZXMpIHRoYXQgaGF2ZSBiZWVuIGNyZWF0ZWQgYXQgdGhlIG9yZ2FuaXphdGlvbiBsZXZlbC4KICAgICAgIEV4YW1wbGUgcmVxdWVzdCBVUkw6CiAgICAgICBgaHR0cHM6Ly9pYW0uZ29vZ2xlYXBpcy5jb20vdjEvb3JnYW5pemF0aW9ucy97T1JHQU5JWkFUSU9OX0lEfS9yb2xlcy97Q1VTVE9NX1JPTEVfSUR9YAoKICAgICAgIE5vdGU6IFdpbGRjYXJkICgqKSB2YWx1ZXMgYXJlIGludmFsaWQ7IHlvdSBtdXN0IHNwZWNpZnkgYSBjb21wbGV0ZSBwcm9qZWN0IElEIG9yIG9yZ2FuaXphdGlvbiBJRC4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXROYW1lKCkgewogICAgICAgICAgcmV0dXJuIG5hbWU7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiBUaGUgYG5hbWVgIHBhcmFtZXRlcidzIHZhbHVlIGRlcGVuZHMgb24gdGhlIHRhcmdldCByZXNvdXJjZSBmb3IgdGhlIHJlcXVlc3QsIG5hbWVseQogICAgICAgICAqIFtgcHJvamVjdHNgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL3Byb2plY3RzLnJvbGVzKSBvcgogICAgICAgICAqIFtgb3JnYW5pemF0aW9uc2BdKC9pYW0vcmVmZXJlbmNlL3Jlc3QvdjEvb3JnYW5pemF0aW9ucy5yb2xlcykuIEVhY2ggcmVzb3VyY2UgdHlwZSdzCiAgICAgICAgICogYG5hbWVgIHZhbHVlIGZvcm1hdCBpcyBkZXNjcmliZWQgYmVsb3c6CiAgICAgICAgICoKICAgICAgICAgKiAqIFtgcHJvamVjdHMucm9sZXMuZGVsZXRlKClgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL3Byb2plY3RzLnJvbGVzL2RlbGV0ZSk6CiAgICAgICAgICogYHByb2plY3RzL3tQUk9KRUNUX0lEfS9yb2xlcy97Q1VTVE9NX1JPTEVfSUR9YC4gVGhpcyBtZXRob2QgZGVsZXRlcyBvbmx5IFtjdXN0b20KICAgICAgICAgKiByb2xlc10oL2lhbS9kb2NzL3VuZGVyc3RhbmRpbmctY3VzdG9tLXJvbGVzKSB0aGF0IGhhdmUgYmVlbiBjcmVhdGVkIGF0IHRoZSBwcm9qZWN0IGxldmVsLgogICAgICAgICAqIEV4YW1wbGUgcmVxdWVzdCBVUkw6CiAgICAgICAgICogYGh0dHBzOi8vaWFtLmdvb2dsZWFwaXMuY29tL3YxL3Byb2plY3RzL3tQUk9KRUNUX0lEfS9yb2xlcy97Q1VTVE9NX1JPTEVfSUR9YAogICAgICAgICAqCiAgICAgICAgICogKiBbYG9yZ2FuaXphdGlvbnMucm9sZXMuZGVsZXRlKClgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL29yZ2FuaXphdGlvbnMucm9sZXMvZGVsZXRlKToKICAgICAgICAgKiBgb3JnYW5pemF0aW9ucy97T1JHQU5JWkFUSU9OX0lEfS9yb2xlcy97Q1VTVE9NX1JPTEVfSUR9YC4gVGhpcyBtZXRob2QgZGVsZXRlcyBvbmx5CiAgICAgICAgICogW2N1c3RvbSByb2xlc10oL2lhbS9kb2NzL3VuZGVyc3RhbmRpbmctY3VzdG9tLXJvbGVzKSB0aGF0IGhhdmUgYmVlbiBjcmVhdGVkIGF0IHRoZQogICAgICAgICAqIG9yZ2FuaXphdGlvbiBsZXZlbC4gRXhhbXBsZSByZXF1ZXN0IFVSTDoKICAgICAgICAgKiBgaHR0cHM6Ly9pYW0uZ29vZ2xlYXBpcy5jb20vdjEvb3JnYW5pemF0aW9ucy97T1JHQU5JWkFUSU9OX0lEfS9yb2xlcy97Q1VTVE9NX1JPTEVfSUR9YAogICAgICAgICAqCiAgICAgICAgICogTm90ZTogV2lsZGNhcmQgKCopIHZhbHVlcyBhcmUgaW52YWxpZDsgeW91IG11c3Qgc3BlY2lmeSBhIGNvbXBsZXRlIHByb2plY3QgSUQgb3IKICAgICAgICAgKiBvcmdhbml6YXRpb24gSUQuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIERlbGV0ZSBzZXROYW1lKGphdmEubGFuZy5TdHJpbmcgbmFtZSkgewogICAgICAgICAgaWYgKCFnZXRTdXBwcmVzc1BhdHRlcm5DaGVja3MoKSkgewogICAgICAgICAgICBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5QcmVjb25kaXRpb25zLmNoZWNrQXJndW1lbnQoTkFNRV9QQVRURVJOLm1hdGNoZXIobmFtZSkubWF0Y2hlcygpLAogICAgICAgICAgICAgICAgIlBhcmFtZXRlciBuYW1lIG11c3QgY29uZm9ybSB0byB0aGUgcGF0dGVybiAiICsKICAgICAgICAgICAgICAgICJecHJvamVjdHMvW14vXSsvcm9sZXMvW14vXSskIik7CiAgICAgICAgICB9CiAgICAgICAgICB0aGlzLm5hbWUgPSBuYW1lOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQoKICAgICAgICAvKiogVXNlZCB0byBwZXJmb3JtIGEgY29uc2lzdGVudCByZWFkLW1vZGlmeS13cml0ZS4gKi8KICAgICAgICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuU3RyaW5nIGV0YWc7CgogICAgICAgIC8qKiBVc2VkIHRvIHBlcmZvcm0gYSBjb25zaXN0ZW50IHJlYWQtbW9kaWZ5LXdyaXRlLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldEV0YWcoKSB7CiAgICAgICAgICByZXR1cm4gZXRhZzsKICAgICAgICB9CgogICAgICAgIC8qKiBVc2VkIHRvIHBlcmZvcm0gYSBjb25zaXN0ZW50IHJlYWQtbW9kaWZ5LXdyaXRlLiAqLwogICAgICAgIHB1YmxpYyBEZWxldGUgc2V0RXRhZyhqYXZhLmxhbmcuU3RyaW5nIGV0YWcpIHsKICAgICAgICAgIHRoaXMuZXRhZyA9IGV0YWc7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBEZWxldGUgc2V0KFN0cmluZyBwYXJhbWV0ZXJOYW1lLCBPYmplY3QgdmFsdWUpIHsKICAgICAgICAgIHJldHVybiAoRGVsZXRlKSBzdXBlci5zZXQocGFyYW1ldGVyTmFtZSwgdmFsdWUpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogR2V0cyBhIFJvbGUgZGVmaW5pdGlvbi4KICAgICAgICoKICAgICAgICogQ3JlYXRlIGEgcmVxdWVzdCBmb3IgdGhlIG1ldGhvZCAicm9sZXMuZ2V0Ii4KICAgICAgICoKICAgICAgICogVGhpcyByZXF1ZXN0IGhvbGRzIHRoZSBwYXJhbWV0ZXJzIG5lZWRlZCBieSB0aGUgaWFtIHNlcnZlci4gIEFmdGVyIHNldHRpbmcgYW55IG9wdGlvbmFsCiAgICAgICAqIHBhcmFtZXRlcnMsIGNhbGwgdGhlIHtAbGluayBHZXQjZXhlY3V0ZSgpfSBtZXRob2QgdG8gaW52b2tlIHRoZSByZW1vdGUgb3BlcmF0aW9uLgogICAgICAgKgogICAgICAgKiBAcGFyYW0gbmFtZSBUaGUgYG5hbWVgIHBhcmFtZXRlcidzIHZhbHVlIGRlcGVuZHMgb24gdGhlIHRhcmdldCByZXNvdXJjZSBmb3IgdGhlCiAgICAgIHJlcXVlc3QsIG5hbWVseQogICAgICAgKiAgICAgICAgW2Byb2xlc2BdKC9pYW0vcmVmZXJlbmNlL3Jlc3QvdjEvcm9sZXMpLAogICAgICAgKiAgICAgICAgW2Bwcm9qZWN0c2BdKC9pYW0vcmVmZXJlbmNlL3Jlc3QvdjEvcHJvamVjdHMucm9sZXMpLCBvcgogICAgICAgKiAgICAgICAgW2Bvcmdhbml6YXRpb25zYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9vcmdhbml6YXRpb25zLnJvbGVzKS4gRWFjaAogICAgICByZXNvdXJjZSB0eXBlJ3MgYG5hbWVgCiAgICAgICAqICAgICAgICB2YWx1ZSBmb3JtYXQgaXMgZGVzY3JpYmVkIGJlbG93OgogICAgICAqIFtgcm9sZXMuZ2V0KClgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL3JvbGVzL2dldCk6CiAgICAgICAqICAgICAgICBgcm9sZXMve1JPTEVfTkFNRX1gLgogICAgICAgIFRoaXMgbWV0aG9kIHJldHVybnMgcmVzdWx0cyBmcm9tIGFsbAogICAgICAgIFtwcmVkZWZpbmVkIHJvbGVzXSgvaWFtL2RvY3MKICAgICAgICogICAgICAgIC91bmRlcnN0YW5kaW5nLXJvbGVzI3ByZWRlZmluZWRfcm9sZXMpIGluCiAgICAgICAgQ2xvdWQgSUFNLiBFeGFtcGxlIHJlcXVlc3QgVVJMOgogICAgICAgKiAgICAgICAgYGh0dHBzOi8vaWFtLmdvb2dsZWFwaXMuY29tL3YxL3JvbGVzL3tST0xFX05BTUV9YAogICAgICAqCiAgICAgICAqICAgICAgICBbYHByb2plY3RzLnJvbGVzLmdldCgpYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9wcm9qZWN0cy5yb2xlcy9nZXQpOgogICAgICAgKiAgICAgICAgYHByb2plY3RzL3tQUk9KRUNUX0lEfS9yb2xlcy97Q1VTVE9NX1JPTEVfSUR9YC4gVGhpcyBtZXRob2QgcmV0dXJucyBvbmx5CiAgICAgICAgW2N1c3RvbQogICAgICAgKiAgICAgICAgcm9sZXNdKC9pYW0vZG9jcy91bmRlcnN0YW5kaW5nLWN1c3RvbS1yb2xlcykgdGhhdCBoYXZlIGJlZW4KICAgICAgICBjcmVhdGVkIGF0IHRoZSBwcm9qZWN0CiAgICAgICAqICAgICAgICBsZXZlbC4gRXhhbXBsZSByZXF1ZXN0IFVSTDoKICAgICAgICogICAgICAgIGBodHRwczovL2lhbS5nb29nbGVhcGlzLmNvbS92MS9wcm9qZWN0cy97UFJPSkVDVF9JRH0vcm9sZXMve0NVU1RPTV9ST0xFX0lEfWAKICAgICAgKgogICAgICAgKiAgICAgICAgW2Bvcmdhbml6YXRpb25zLnJvbGVzLmdldCgpYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9vcmdhbml6YXRpb25zLnJvbGVzL2dldCk6CiAgICAgICAqICAgICAgICBgb3JnYW5pemF0aW9ucy97T1JHQU5JWkFUSU9OX0lEfS9yb2xlcy97Q1VTVE9NX1JPTEVfSUR9YC4gVGhpcyBtZXRob2QKICAgICAgICByZXR1cm5zIG9ubHkKICAgICAgICogICAgICAgIFtjdXN0b20gcm9sZXNdKC9pYW0vZG9jcy91bmRlcnN0YW5kaW5nLWN1c3RvbS1yb2xlcykgdGhhdAogICAgICAgIGhhdmUgYmVlbiBjcmVhdGVkIGF0IHRoZQogICAgICAgKiAgICAgICAgb3JnYW5pemF0aW9uIGxldmVsLiBFeGFtcGxlIHJlcXVlc3QgVVJMOgogICAgICAgKiAgICAgICAgYGh0dHBzOi8vaWFtLmdvb2dsZWFwaXMuY29tL3YxL29yZ2FuaXphdGlvbnMve09SR0FOSVpBVElPTl9JRH0vcm9sZXMve0NVU1RPTV9ST0xFX0lEfWAKICAgICAgICogICAgICAgIE5vdGU6IFdpbGRjYXJkICgqKSB2YWx1ZXMgYXJlIGludmFsaWQ7IHlvdSBtdXN0IHNwZWNpZnkgYSBjb21wbGV0ZSBwcm9qZWN0CiAgICAgIElEIG9yCiAgICAgICAqICAgICAgICBvcmdhbml6YXRpb24gSUQuCiAgICAgICAqIEByZXR1cm4gdGhlIHJlcXVlc3QKICAgICAgICovCiAgICAgIHB1YmxpYyBHZXQgZ2V0KGphdmEubGFuZy5TdHJpbmcgbmFtZSkgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIEdldCByZXN1bHQgPSBuZXcgR2V0KG5hbWUpOwogICAgICAgIGluaXRpYWxpemUocmVzdWx0KTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBwdWJsaWMgY2xhc3MgR2V0IGV4dGVuZHMgSWFtUmVxdWVzdDxjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5pYW0udjEubW9kZWwuUm9sZT4gewoKICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgUkVTVF9QQVRIID0gInYxL3srbmFtZX0iOwoKICAgICAgICBwcml2YXRlIGZpbmFsIGphdmEudXRpbC5yZWdleC5QYXR0ZXJuIE5BTUVfUEFUVEVSTiA9CiAgICAgICAgICAgIGphdmEudXRpbC5yZWdleC5QYXR0ZXJuLmNvbXBpbGUoIl5wcm9qZWN0cy9bXi9dKy9yb2xlcy9bXi9dKyQiKTsKCiAgICAgICAgLyoqCiAgICAgICAgICogR2V0cyBhIFJvbGUgZGVmaW5pdGlvbi4KICAgICAgICAgKgogICAgICAgICAqIENyZWF0ZSBhIHJlcXVlc3QgZm9yIHRoZSBtZXRob2QgInJvbGVzLmdldCIuCiAgICAgICAgICoKICAgICAgICAgKiBUaGlzIHJlcXVlc3QgaG9sZHMgdGhlIHBhcmFtZXRlcnMgbmVlZGVkIGJ5IHRoZSB0aGUgaWFtIHNlcnZlci4gIEFmdGVyIHNldHRpbmcgYW55IG9wdGlvbmFsCiAgICAgICAgICogcGFyYW1ldGVycywgY2FsbCB0aGUge0BsaW5rIEdldCNleGVjdXRlKCl9IG1ldGhvZCB0byBpbnZva2UgdGhlIHJlbW90ZSBvcGVyYXRpb24uIDxwPiB7QGxpbmsKICAgICAgICAgKiBHZXQjaW5pdGlhbGl6ZShjb20uZ29vZ2xlLmFwaS5jbGllbnQuZ29vZ2xlYXBpcy5zZXJ2aWNlcy5BYnN0cmFjdEdvb2dsZUNsaWVudFJlcXVlc3QpfSBtdXN0IGJlCiAgICAgICAgICogY2FsbGVkIHRvIGluaXRpYWxpemUgdGhpcyBpbnN0YW5jZSBpbW1lZGlhdGVseSBhZnRlciBpbnZva2luZyB0aGUgY29uc3RydWN0b3IuIDwvcD4KICAgICAgICAgKgogICAgICAgICAqIEBwYXJhbSBuYW1lIFRoZSBgbmFtZWAgcGFyYW1ldGVyJ3MgdmFsdWUgZGVwZW5kcyBvbiB0aGUgdGFyZ2V0IHJlc291cmNlIGZvciB0aGUKICAgICAgcmVxdWVzdCwgbmFtZWx5CiAgICAgICAqICAgICAgICBbYHJvbGVzYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9yb2xlcyksCiAgICAgICAqICAgICAgICBbYHByb2plY3RzYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9wcm9qZWN0cy5yb2xlcyksIG9yCiAgICAgICAqICAgICAgICBbYG9yZ2FuaXphdGlvbnNgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL29yZ2FuaXphdGlvbnMucm9sZXMpLiBFYWNoCiAgICAgIHJlc291cmNlIHR5cGUncyBgbmFtZWAKICAgICAgICogICAgICAgIHZhbHVlIGZvcm1hdCBpcyBkZXNjcmliZWQgYmVsb3c6CiAgICAgICogW2Byb2xlcy5nZXQoKWBdKC9pYW0vcmVmZXJlbmNlL3Jlc3QvdjEvcm9sZXMvZ2V0KToKICAgICAgICogICAgICAgIGByb2xlcy97Uk9MRV9OQU1FfWAuCiAgICAgICAgVGhpcyBtZXRob2QgcmV0dXJucyByZXN1bHRzIGZyb20gYWxsCiAgICAgICAgW3ByZWRlZmluZWQgcm9sZXNdKC9pYW0vZG9jcwogICAgICAgKiAgICAgICAgL3VuZGVyc3RhbmRpbmctcm9sZXMjcHJlZGVmaW5lZF9yb2xlcykgaW4KICAgICAgICBDbG91ZCBJQU0uIEV4YW1wbGUgcmVxdWVzdCBVUkw6CiAgICAgICAqICAgICAgICBgaHR0cHM6Ly9pYW0uZ29vZ2xlYXBpcy5jb20vdjEvcm9sZXMve1JPTEVfTkFNRX1gCiAgICAgICoKICAgICAgICogICAgICAgIFtgcHJvamVjdHMucm9sZXMuZ2V0KClgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL3Byb2plY3RzLnJvbGVzL2dldCk6CiAgICAgICAqICAgICAgICBgcHJvamVjdHMve1BST0pFQ1RfSUR9L3JvbGVzL3tDVVNUT01fUk9MRV9JRH1gLiBUaGlzIG1ldGhvZCByZXR1cm5zIG9ubHkKICAgICAgICBbY3VzdG9tCiAgICAgICAqICAgICAgICByb2xlc10oL2lhbS9kb2NzL3VuZGVyc3RhbmRpbmctY3VzdG9tLXJvbGVzKSB0aGF0IGhhdmUgYmVlbgogICAgICAgIGNyZWF0ZWQgYXQgdGhlIHByb2plY3QKICAgICAgICogICAgICAgIGxldmVsLiBFeGFtcGxlIHJlcXVlc3QgVVJMOgogICAgICAgKiAgICAgICAgYGh0dHBzOi8vaWFtLmdvb2dsZWFwaXMuY29tL3YxL3Byb2plY3RzL3tQUk9KRUNUX0lEfS9yb2xlcy97Q1VTVE9NX1JPTEVfSUR9YAogICAgICAqCiAgICAgICAqICAgICAgICBbYG9yZ2FuaXphdGlvbnMucm9sZXMuZ2V0KClgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL29yZ2FuaXphdGlvbnMucm9sZXMvZ2V0KToKICAgICAgICogICAgICAgIGBvcmdhbml6YXRpb25zL3tPUkdBTklaQVRJT05fSUR9L3JvbGVzL3tDVVNUT01fUk9MRV9JRH1gLiBUaGlzIG1ldGhvZAogICAgICAgIHJldHVybnMgb25seQogICAgICAgKiAgICAgICAgW2N1c3RvbSByb2xlc10oL2lhbS9kb2NzL3VuZGVyc3RhbmRpbmctY3VzdG9tLXJvbGVzKSB0aGF0CiAgICAgICAgaGF2ZSBiZWVuIGNyZWF0ZWQgYXQgdGhlCiAgICAgICAqICAgICAgICBvcmdhbml6YXRpb24gbGV2ZWwuIEV4YW1wbGUgcmVxdWVzdCBVUkw6CiAgICAgICAqICAgICAgICBgaHR0cHM6Ly9pYW0uZ29vZ2xlYXBpcy5jb20vdjEvb3JnYW5pemF0aW9ucy97T1JHQU5JWkFUSU9OX0lEfS9yb2xlcy97Q1VTVE9NX1JPTEVfSUR9YAogICAgICAgKiAgICAgICAgTm90ZTogV2lsZGNhcmQgKCopIHZhbHVlcyBhcmUgaW52YWxpZDsgeW91IG11c3Qgc3BlY2lmeSBhIGNvbXBsZXRlIHByb2plY3QKICAgICAgSUQgb3IKICAgICAgICogICAgICAgIG9yZ2FuaXphdGlvbiBJRC4KICAgICAgICAgKiBAc2luY2UgMS4xMwogICAgICAgICAqLwogICAgICAgIHByb3RlY3RlZCBHZXQoamF2YS5sYW5nLlN0cmluZyBuYW1lKSB7CiAgICAgICAgICBzdXBlcihJYW0udGhpcywgIkdFVCIsIFJFU1RfUEFUSCwgbnVsbCwgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuaWFtLnYxLm1vZGVsLlJvbGUuY2xhc3MpOwogICAgICAgICAgdGhpcy5uYW1lID0gY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuUHJlY29uZGl0aW9ucy5jaGVja05vdE51bGwobmFtZSwgIlJlcXVpcmVkIHBhcmFtZXRlciBuYW1lIG11c3QgYmUgc3BlY2lmaWVkLiIpOwogICAgICAgICAgaWYgKCFnZXRTdXBwcmVzc1BhdHRlcm5DaGVja3MoKSkgewogICAgICAgICAgICBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5QcmVjb25kaXRpb25zLmNoZWNrQXJndW1lbnQoTkFNRV9QQVRURVJOLm1hdGNoZXIobmFtZSkubWF0Y2hlcygpLAogICAgICAgICAgICAgICAgIlBhcmFtZXRlciBuYW1lIG11c3QgY29uZm9ybSB0byB0aGUgcGF0dGVybiAiICsKICAgICAgICAgICAgICAgICJecHJvamVjdHMvW14vXSsvcm9sZXMvW14vXSskIik7CiAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5hcGkuY2xpZW50Lmh0dHAuSHR0cFJlc3BvbnNlIGV4ZWN1dGVVc2luZ0hlYWQoKSB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuZXhlY3V0ZVVzaW5nSGVhZCgpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIGNvbS5nb29nbGUuYXBpLmNsaWVudC5odHRwLkh0dHBSZXF1ZXN0IGJ1aWxkSHR0cFJlcXVlc3RVc2luZ0hlYWQoKSB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuYnVpbGRIdHRwUmVxdWVzdFVzaW5nSGVhZCgpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIEdldCBzZXQkWGdhZnYoamF2YS5sYW5nLlN0cmluZyAkWGdhZnYpIHsKICAgICAgICAgIHJldHVybiAoR2V0KSBzdXBlci5zZXQkWGdhZnYoJFhnYWZ2KTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBHZXQgc2V0QWNjZXNzVG9rZW4oamF2YS5sYW5nLlN0cmluZyBhY2Nlc3NUb2tlbikgewogICAgICAgICAgcmV0dXJuIChHZXQpIHN1cGVyLnNldEFjY2Vzc1Rva2VuKGFjY2Vzc1Rva2VuKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBHZXQgc2V0QWx0KGphdmEubGFuZy5TdHJpbmcgYWx0KSB7CiAgICAgICAgICByZXR1cm4gKEdldCkgc3VwZXIuc2V0QWx0KGFsdCk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgR2V0IHNldENhbGxiYWNrKGphdmEubGFuZy5TdHJpbmcgY2FsbGJhY2spIHsKICAgICAgICAgIHJldHVybiAoR2V0KSBzdXBlci5zZXRDYWxsYmFjayhjYWxsYmFjayk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgR2V0IHNldEZpZWxkcyhqYXZhLmxhbmcuU3RyaW5nIGZpZWxkcykgewogICAgICAgICAgcmV0dXJuIChHZXQpIHN1cGVyLnNldEZpZWxkcyhmaWVsZHMpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIEdldCBzZXRLZXkoamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICAgIHJldHVybiAoR2V0KSBzdXBlci5zZXRLZXkoa2V5KTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBHZXQgc2V0T2F1dGhUb2tlbihqYXZhLmxhbmcuU3RyaW5nIG9hdXRoVG9rZW4pIHsKICAgICAgICAgIHJldHVybiAoR2V0KSBzdXBlci5zZXRPYXV0aFRva2VuKG9hdXRoVG9rZW4pOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIEdldCBzZXRQcmV0dHlQcmludChqYXZhLmxhbmcuQm9vbGVhbiBwcmV0dHlQcmludCkgewogICAgICAgICAgcmV0dXJuIChHZXQpIHN1cGVyLnNldFByZXR0eVByaW50KHByZXR0eVByaW50KTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBHZXQgc2V0UXVvdGFVc2VyKGphdmEubGFuZy5TdHJpbmcgcXVvdGFVc2VyKSB7CiAgICAgICAgICByZXR1cm4gKEdldCkgc3VwZXIuc2V0UXVvdGFVc2VyKHF1b3RhVXNlcik7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgR2V0IHNldFVwbG9hZFR5cGUoamF2YS5sYW5nLlN0cmluZyB1cGxvYWRUeXBlKSB7CiAgICAgICAgICByZXR1cm4gKEdldCkgc3VwZXIuc2V0VXBsb2FkVHlwZSh1cGxvYWRUeXBlKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBHZXQgc2V0VXBsb2FkUHJvdG9jb2woamF2YS5sYW5nLlN0cmluZyB1cGxvYWRQcm90b2NvbCkgewogICAgICAgICAgcmV0dXJuIChHZXQpIHN1cGVyLnNldFVwbG9hZFByb3RvY29sKHVwbG9hZFByb3RvY29sKTsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIFRoZSBgbmFtZWAgcGFyYW1ldGVyJ3MgdmFsdWUgZGVwZW5kcyBvbiB0aGUgdGFyZ2V0IHJlc291cmNlIGZvciB0aGUgcmVxdWVzdCwgbmFtZWx5CiAgICAgICAgICogW2Byb2xlc2BdKC9pYW0vcmVmZXJlbmNlL3Jlc3QvdjEvcm9sZXMpLAogICAgICAgICAqIFtgcHJvamVjdHNgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL3Byb2plY3RzLnJvbGVzKSwgb3IKICAgICAgICAgKiBbYG9yZ2FuaXphdGlvbnNgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL29yZ2FuaXphdGlvbnMucm9sZXMpLiBFYWNoIHJlc291cmNlIHR5cGUncwogICAgICAgICAqIGBuYW1lYCB2YWx1ZSBmb3JtYXQgaXMgZGVzY3JpYmVkIGJlbG93OgogICAgICAgICAqCiAgICAgICAgICogKiBbYHJvbGVzLmdldCgpYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9yb2xlcy9nZXQpOiBgcm9sZXMve1JPTEVfTkFNRX1gLiBUaGlzIG1ldGhvZAogICAgICAgICAqIHJldHVybnMgcmVzdWx0cyBmcm9tIGFsbCBbcHJlZGVmaW5lZCByb2xlc10oL2lhbS9kb2NzL3VuZGVyc3RhbmRpbmctCiAgICAgICAgICogcm9sZXMjcHJlZGVmaW5lZF9yb2xlcykgaW4gQ2xvdWQgSUFNLiBFeGFtcGxlIHJlcXVlc3QgVVJMOgogICAgICAgICAqIGBodHRwczovL2lhbS5nb29nbGVhcGlzLmNvbS92MS9yb2xlcy97Uk9MRV9OQU1FfWAKICAgICAgICAgKgogICAgICAgICAqICogW2Bwcm9qZWN0cy5yb2xlcy5nZXQoKWBdKC9pYW0vcmVmZXJlbmNlL3Jlc3QvdjEvcHJvamVjdHMucm9sZXMvZ2V0KToKICAgICAgICAgKiBgcHJvamVjdHMve1BST0pFQ1RfSUR9L3JvbGVzL3tDVVNUT01fUk9MRV9JRH1gLiBUaGlzIG1ldGhvZCByZXR1cm5zIG9ubHkgW2N1c3RvbQogICAgICAgICAqIHJvbGVzXSgvaWFtL2RvY3MvdW5kZXJzdGFuZGluZy1jdXN0b20tcm9sZXMpIHRoYXQgaGF2ZSBiZWVuIGNyZWF0ZWQgYXQgdGhlIHByb2plY3QgbGV2ZWwuCiAgICAgICAgICogRXhhbXBsZSByZXF1ZXN0IFVSTDoKICAgICAgICAgKiBgaHR0cHM6Ly9pYW0uZ29vZ2xlYXBpcy5jb20vdjEvcHJvamVjdHMve1BST0pFQ1RfSUR9L3JvbGVzL3tDVVNUT01fUk9MRV9JRH1gCiAgICAgICAgICoKICAgICAgICAgKiAqIFtgb3JnYW5pemF0aW9ucy5yb2xlcy5nZXQoKWBdKC9pYW0vcmVmZXJlbmNlL3Jlc3QvdjEvb3JnYW5pemF0aW9ucy5yb2xlcy9nZXQpOgogICAgICAgICAqIGBvcmdhbml6YXRpb25zL3tPUkdBTklaQVRJT05fSUR9L3JvbGVzL3tDVVNUT01fUk9MRV9JRH1gLiBUaGlzIG1ldGhvZCByZXR1cm5zIG9ubHkKICAgICAgICAgKiBbY3VzdG9tIHJvbGVzXSgvaWFtL2RvY3MvdW5kZXJzdGFuZGluZy1jdXN0b20tcm9sZXMpIHRoYXQgaGF2ZSBiZWVuIGNyZWF0ZWQgYXQgdGhlCiAgICAgICAgICogb3JnYW5pemF0aW9uIGxldmVsLiBFeGFtcGxlIHJlcXVlc3QgVVJMOgogICAgICAgICAqIGBodHRwczovL2lhbS5nb29nbGVhcGlzLmNvbS92MS9vcmdhbml6YXRpb25zL3tPUkdBTklaQVRJT05fSUR9L3JvbGVzL3tDVVNUT01fUk9MRV9JRH1gCiAgICAgICAgICoKICAgICAgICAgKiBOb3RlOiBXaWxkY2FyZCAoKikgdmFsdWVzIGFyZSBpbnZhbGlkOyB5b3UgbXVzdCBzcGVjaWZ5IGEgY29tcGxldGUgcHJvamVjdCBJRCBvcgogICAgICAgICAqIG9yZ2FuaXphdGlvbiBJRC4KICAgICAgICAgKi8KICAgICAgICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuU3RyaW5nIG5hbWU7CgogICAgICAgIC8qKiBUaGUgYG5hbWVgIHBhcmFtZXRlcidzIHZhbHVlIGRlcGVuZHMgb24gdGhlIHRhcmdldCByZXNvdXJjZSBmb3IgdGhlIHJlcXVlc3QsIG5hbWVseQogICAgICAgW2Byb2xlc2BdKC9pYW0vcmVmZXJlbmNlL3Jlc3QvdjEvcm9sZXMpLCBbYHByb2plY3RzYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9wcm9qZWN0cy5yb2xlcyksIG9yCiAgICAgICBbYG9yZ2FuaXphdGlvbnNgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL29yZ2FuaXphdGlvbnMucm9sZXMpLiBFYWNoIHJlc291cmNlIHR5cGUncyBgbmFtZWAgdmFsdWUKICAgICAgIGZvcm1hdCBpcyBkZXNjcmliZWQgYmVsb3c6CgogICAgICAgKiBbYHJvbGVzLmdldCgpYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9yb2xlcy9nZXQpOiBgcm9sZXMve1JPTEVfTkFNRX1gLiBUaGlzIG1ldGhvZCByZXR1cm5zCiAgICAgICByZXN1bHRzIGZyb20gYWxsIFtwcmVkZWZpbmVkIHJvbGVzXSgvaWFtL2RvY3MvdW5kZXJzdGFuZGluZy1yb2xlcyNwcmVkZWZpbmVkX3JvbGVzKSBpbiBDbG91ZCBJQU0uCiAgICAgICBFeGFtcGxlIHJlcXVlc3QgVVJMOiBgaHR0cHM6Ly9pYW0uZ29vZ2xlYXBpcy5jb20vdjEvcm9sZXMve1JPTEVfTkFNRX1gCgogICAgICAgKiBbYHByb2plY3RzLnJvbGVzLmdldCgpYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9wcm9qZWN0cy5yb2xlcy9nZXQpOgogICAgICAgYHByb2plY3RzL3tQUk9KRUNUX0lEfS9yb2xlcy97Q1VTVE9NX1JPTEVfSUR9YC4gVGhpcyBtZXRob2QgcmV0dXJucyBvbmx5IFtjdXN0b20gcm9sZXNdKC9pYW0vZG9jcwogICAgICAgL3VuZGVyc3RhbmRpbmctY3VzdG9tLXJvbGVzKSB0aGF0IGhhdmUgYmVlbiBjcmVhdGVkIGF0IHRoZSBwcm9qZWN0IGxldmVsLiBFeGFtcGxlIHJlcXVlc3QgVVJMOgogICAgICAgYGh0dHBzOi8vaWFtLmdvb2dsZWFwaXMuY29tL3YxL3Byb2plY3RzL3tQUk9KRUNUX0lEfS9yb2xlcy97Q1VTVE9NX1JPTEVfSUR9YAoKICAgICAgICogW2Bvcmdhbml6YXRpb25zLnJvbGVzLmdldCgpYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9vcmdhbml6YXRpb25zLnJvbGVzL2dldCk6CiAgICAgICBgb3JnYW5pemF0aW9ucy97T1JHQU5JWkFUSU9OX0lEfS9yb2xlcy97Q1VTVE9NX1JPTEVfSUR9YC4gVGhpcyBtZXRob2QgcmV0dXJucyBvbmx5IFtjdXN0b20KICAgICAgIHJvbGVzXSgvaWFtL2RvY3MvdW5kZXJzdGFuZGluZy1jdXN0b20tcm9sZXMpIHRoYXQgaGF2ZSBiZWVuIGNyZWF0ZWQgYXQgdGhlIG9yZ2FuaXphdGlvbiBsZXZlbC4KICAgICAgIEV4YW1wbGUgcmVxdWVzdCBVUkw6CiAgICAgICBgaHR0cHM6Ly9pYW0uZ29vZ2xlYXBpcy5jb20vdjEvb3JnYW5pemF0aW9ucy97T1JHQU5JWkFUSU9OX0lEfS9yb2xlcy97Q1VTVE9NX1JPTEVfSUR9YAoKICAgICAgIE5vdGU6IFdpbGRjYXJkICgqKSB2YWx1ZXMgYXJlIGludmFsaWQ7IHlvdSBtdXN0IHNwZWNpZnkgYSBjb21wbGV0ZSBwcm9qZWN0IElEIG9yIG9yZ2FuaXphdGlvbiBJRC4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXROYW1lKCkgewogICAgICAgICAgcmV0dXJuIG5hbWU7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiBUaGUgYG5hbWVgIHBhcmFtZXRlcidzIHZhbHVlIGRlcGVuZHMgb24gdGhlIHRhcmdldCByZXNvdXJjZSBmb3IgdGhlIHJlcXVlc3QsIG5hbWVseQogICAgICAgICAqIFtgcm9sZXNgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL3JvbGVzKSwKICAgICAgICAgKiBbYHByb2plY3RzYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9wcm9qZWN0cy5yb2xlcyksIG9yCiAgICAgICAgICogW2Bvcmdhbml6YXRpb25zYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9vcmdhbml6YXRpb25zLnJvbGVzKS4gRWFjaCByZXNvdXJjZSB0eXBlJ3MKICAgICAgICAgKiBgbmFtZWAgdmFsdWUgZm9ybWF0IGlzIGRlc2NyaWJlZCBiZWxvdzoKICAgICAgICAgKgogICAgICAgICAqICogW2Byb2xlcy5nZXQoKWBdKC9pYW0vcmVmZXJlbmNlL3Jlc3QvdjEvcm9sZXMvZ2V0KTogYHJvbGVzL3tST0xFX05BTUV9YC4gVGhpcyBtZXRob2QKICAgICAgICAgKiByZXR1cm5zIHJlc3VsdHMgZnJvbSBhbGwgW3ByZWRlZmluZWQgcm9sZXNdKC9pYW0vZG9jcy91bmRlcnN0YW5kaW5nLQogICAgICAgICAqIHJvbGVzI3ByZWRlZmluZWRfcm9sZXMpIGluIENsb3VkIElBTS4gRXhhbXBsZSByZXF1ZXN0IFVSTDoKICAgICAgICAgKiBgaHR0cHM6Ly9pYW0uZ29vZ2xlYXBpcy5jb20vdjEvcm9sZXMve1JPTEVfTkFNRX1gCiAgICAgICAgICoKICAgICAgICAgKiAqIFtgcHJvamVjdHMucm9sZXMuZ2V0KClgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL3Byb2plY3RzLnJvbGVzL2dldCk6CiAgICAgICAgICogYHByb2plY3RzL3tQUk9KRUNUX0lEfS9yb2xlcy97Q1VTVE9NX1JPTEVfSUR9YC4gVGhpcyBtZXRob2QgcmV0dXJucyBvbmx5IFtjdXN0b20KICAgICAgICAgKiByb2xlc10oL2lhbS9kb2NzL3VuZGVyc3RhbmRpbmctY3VzdG9tLXJvbGVzKSB0aGF0IGhhdmUgYmVlbiBjcmVhdGVkIGF0IHRoZSBwcm9qZWN0IGxldmVsLgogICAgICAgICAqIEV4YW1wbGUgcmVxdWVzdCBVUkw6CiAgICAgICAgICogYGh0dHBzOi8vaWFtLmdvb2dsZWFwaXMuY29tL3YxL3Byb2plY3RzL3tQUk9KRUNUX0lEfS9yb2xlcy97Q1VTVE9NX1JPTEVfSUR9YAogICAgICAgICAqCiAgICAgICAgICogKiBbYG9yZ2FuaXphdGlvbnMucm9sZXMuZ2V0KClgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL29yZ2FuaXphdGlvbnMucm9sZXMvZ2V0KToKICAgICAgICAgKiBgb3JnYW5pemF0aW9ucy97T1JHQU5JWkFUSU9OX0lEfS9yb2xlcy97Q1VTVE9NX1JPTEVfSUR9YC4gVGhpcyBtZXRob2QgcmV0dXJucyBvbmx5CiAgICAgICAgICogW2N1c3RvbSByb2xlc10oL2lhbS9kb2NzL3VuZGVyc3RhbmRpbmctY3VzdG9tLXJvbGVzKSB0aGF0IGhhdmUgYmVlbiBjcmVhdGVkIGF0IHRoZQogICAgICAgICAqIG9yZ2FuaXphdGlvbiBsZXZlbC4gRXhhbXBsZSByZXF1ZXN0IFVSTDoKICAgICAgICAgKiBgaHR0cHM6Ly9pYW0uZ29vZ2xlYXBpcy5jb20vdjEvb3JnYW5pemF0aW9ucy97T1JHQU5JWkFUSU9OX0lEfS9yb2xlcy97Q1VTVE9NX1JPTEVfSUR9YAogICAgICAgICAqCiAgICAgICAgICogTm90ZTogV2lsZGNhcmQgKCopIHZhbHVlcyBhcmUgaW52YWxpZDsgeW91IG11c3Qgc3BlY2lmeSBhIGNvbXBsZXRlIHByb2plY3QgSUQgb3IKICAgICAgICAgKiBvcmdhbml6YXRpb24gSUQuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIEdldCBzZXROYW1lKGphdmEubGFuZy5TdHJpbmcgbmFtZSkgewogICAgICAgICAgaWYgKCFnZXRTdXBwcmVzc1BhdHRlcm5DaGVja3MoKSkgewogICAgICAgICAgICBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5QcmVjb25kaXRpb25zLmNoZWNrQXJndW1lbnQoTkFNRV9QQVRURVJOLm1hdGNoZXIobmFtZSkubWF0Y2hlcygpLAogICAgICAgICAgICAgICAgIlBhcmFtZXRlciBuYW1lIG11c3QgY29uZm9ybSB0byB0aGUgcGF0dGVybiAiICsKICAgICAgICAgICAgICAgICJecHJvamVjdHMvW14vXSsvcm9sZXMvW14vXSskIik7CiAgICAgICAgICB9CiAgICAgICAgICB0aGlzLm5hbWUgPSBuYW1lOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgR2V0IHNldChTdHJpbmcgcGFyYW1ldGVyTmFtZSwgT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgICByZXR1cm4gKEdldCkgc3VwZXIuc2V0KHBhcmFtZXRlck5hbWUsIHZhbHVlKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIExpc3RzIHRoZSBSb2xlcyBkZWZpbmVkIG9uIGEgcmVzb3VyY2UuCiAgICAgICAqCiAgICAgICAqIENyZWF0ZSBhIHJlcXVlc3QgZm9yIHRoZSBtZXRob2QgInJvbGVzLmxpc3QiLgogICAgICAgKgogICAgICAgKiBUaGlzIHJlcXVlc3QgaG9sZHMgdGhlIHBhcmFtZXRlcnMgbmVlZGVkIGJ5IHRoZSBpYW0gc2VydmVyLiAgQWZ0ZXIgc2V0dGluZyBhbnkgb3B0aW9uYWwKICAgICAgICogcGFyYW1ldGVycywgY2FsbCB0aGUge0BsaW5rIExpc3QjZXhlY3V0ZSgpfSBtZXRob2QgdG8gaW52b2tlIHRoZSByZW1vdGUgb3BlcmF0aW9uLgogICAgICAgKgogICAgICAgKiBAcGFyYW0gcGFyZW50IFRoZSBgcGFyZW50YCBwYXJhbWV0ZXIncyB2YWx1ZSBkZXBlbmRzIG9uIHRoZSB0YXJnZXQgcmVzb3VyY2UgZm9yIHRoZQogICAgICByZXF1ZXN0LCBuYW1lbHkKICAgICAgICogICAgICAgIFtgcm9sZXNgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL3JvbGVzKSwKICAgICAgICogICAgICAgIFtgcHJvamVjdHNgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL3Byb2plY3RzLnJvbGVzKSwgb3IKICAgICAgICogICAgICAgIFtgb3JnYW5pemF0aW9uc2BdKC9pYW0vcmVmZXJlbmNlL3Jlc3QvdjEvb3JnYW5pemF0aW9ucy5yb2xlcykuIEVhY2gKICAgICAgcmVzb3VyY2UgdHlwZSdzCiAgICAgICAqICAgICAgICBgcGFyZW50YCB2YWx1ZSBmb3JtYXQgaXMgZGVzY3JpYmVkIGJlbG93OgogICAgICAqCiAgICAgICAqICAgICAgICBbYHJvbGVzLmxpc3QoKWBdKC9pYW0vcmVmZXJlbmNlL3Jlc3QvdjEvcm9sZXMvbGlzdCk6IEFuIGVtcHR5IHN0cmluZy4KICAgICAgICBUaGlzIG1ldGhvZAogICAgICAgKiAgICAgICAgZG9lc24ndCByZXF1aXJlIGEgcmVzb3VyY2U7IGl0IHNpbXBseSByZXR1cm5zIGFsbAogICAgICAgIFtwcmVkZWZpbmVkIHJvbGVzXSgvaWFtL2RvY3MKICAgICAgICogICAgICAgIC91bmRlcnN0YW5kaW5nLXJvbGVzI3ByZWRlZmluZWRfcm9sZXMpIGluCiAgICAgICAgQ2xvdWQgSUFNLiBFeGFtcGxlIHJlcXVlc3QgVVJMOgogICAgICAgKiAgICAgICAgYGh0dHBzOi8vaWFtLmdvb2dsZWFwaXMuY29tL3YxL3JvbGVzYAogICAgICAqCiAgICAgICAqICAgICAgICBbYHByb2plY3RzLnJvbGVzLmxpc3QoKWBdKC9pYW0vcmVmZXJlbmNlL3Jlc3QvdjEvcHJvamVjdHMucm9sZXMvbGlzdCk6CiAgICAgICAqICAgICAgICBgcHJvamVjdHMve1BST0pFQ1RfSUR9YC4gVGhpcyBtZXRob2QgbGlzdHMgYWxsIHByb2plY3QtbGV2ZWwKICAgICAgICBbY3VzdG9tIHJvbGVzXSgvaWFtL2RvY3MKICAgICAgICogICAgICAgIC91bmRlcnN0YW5kaW5nLWN1c3RvbS1yb2xlcykuCiAgICAgICAgRXhhbXBsZSByZXF1ZXN0IFVSTDoKICAgICAgICogICAgICAgIGBodHRwczovL2lhbS5nb29nbGVhcGlzLmNvbS92MS9wcm9qZWN0cy97UFJPSkVDVF9JRH0vcm9sZXNgCiAgICAgICoKICAgICAgICogICAgICAgIFtgb3JnYW5pemF0aW9ucy5yb2xlcy5saXN0KClgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL29yZ2FuaXphdGlvbnMucm9sZXMvbGlzdCk6CiAgICAgICAqICAgICAgICBgb3JnYW5pemF0aW9ucy97T1JHQU5JWkFUSU9OX0lEfWAuIFRoaXMgbWV0aG9kIGxpc3RzIGFsbAogICAgICAgIG9yZ2FuaXphdGlvbi1sZXZlbCBbY3VzdG9tCiAgICAgICAqICAgICAgICByb2xlc10oL2lhbS9kb2NzL3VuZGVyc3RhbmRpbmctY3VzdG9tLXJvbGVzKS4KICAgICAgICBFeGFtcGxlIHJlcXVlc3QgVVJMOgogICAgICAgKiAgICAgICAgYGh0dHBzOi8vaWFtLmdvb2dsZWFwaXMuY29tL3YxL29yZ2FuaXphdGlvbnMve09SR0FOSVpBVElPTl9JRH0vcm9sZXNgCiAgICAgIE5vdGU6IFdpbGRjYXJkICgqKQogICAgICAgKiAgICAgICAgdmFsdWVzIGFyZSBpbnZhbGlkOyB5b3UgbXVzdCBzcGVjaWZ5IGEgY29tcGxldGUgcHJvamVjdAogICAgICBJRCBvciBvcmdhbml6YXRpb24gSUQuCiAgICAgICAqIEByZXR1cm4gdGhlIHJlcXVlc3QKICAgICAgICovCiAgICAgIHB1YmxpYyBMaXN0IGxpc3QoamF2YS5sYW5nLlN0cmluZyBwYXJlbnQpIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBMaXN0IHJlc3VsdCA9IG5ldyBMaXN0KHBhcmVudCk7CiAgICAgICAgaW5pdGlhbGl6ZShyZXN1bHQpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBjbGFzcyBMaXN0IGV4dGVuZHMgSWFtUmVxdWVzdDxjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5pYW0udjEubW9kZWwuTGlzdFJvbGVzUmVzcG9uc2U+IHsKCiAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFJFU1RfUEFUSCA9ICJ2MS97K3BhcmVudH0vcm9sZXMiOwoKICAgICAgICBwcml2YXRlIGZpbmFsIGphdmEudXRpbC5yZWdleC5QYXR0ZXJuIFBBUkVOVF9QQVRURVJOID0KICAgICAgICAgICAgamF2YS51dGlsLnJlZ2V4LlBhdHRlcm4uY29tcGlsZSgiXnByb2plY3RzL1teL10rJCIpOwoKICAgICAgICAvKioKICAgICAgICAgKiBMaXN0cyB0aGUgUm9sZXMgZGVmaW5lZCBvbiBhIHJlc291cmNlLgogICAgICAgICAqCiAgICAgICAgICogQ3JlYXRlIGEgcmVxdWVzdCBmb3IgdGhlIG1ldGhvZCAicm9sZXMubGlzdCIuCiAgICAgICAgICoKICAgICAgICAgKiBUaGlzIHJlcXVlc3QgaG9sZHMgdGhlIHBhcmFtZXRlcnMgbmVlZGVkIGJ5IHRoZSB0aGUgaWFtIHNlcnZlci4gIEFmdGVyIHNldHRpbmcgYW55IG9wdGlvbmFsCiAgICAgICAgICogcGFyYW1ldGVycywgY2FsbCB0aGUge0BsaW5rIExpc3QjZXhlY3V0ZSgpfSBtZXRob2QgdG8gaW52b2tlIHRoZSByZW1vdGUgb3BlcmF0aW9uLiA8cD4ge0BsaW5rCiAgICAgICAgICogTGlzdCNpbml0aWFsaXplKGNvbS5nb29nbGUuYXBpLmNsaWVudC5nb29nbGVhcGlzLnNlcnZpY2VzLkFic3RyYWN0R29vZ2xlQ2xpZW50UmVxdWVzdCl9IG11c3QgYmUKICAgICAgICAgKiBjYWxsZWQgdG8gaW5pdGlhbGl6ZSB0aGlzIGluc3RhbmNlIGltbWVkaWF0ZWx5IGFmdGVyIGludm9raW5nIHRoZSBjb25zdHJ1Y3Rvci4gPC9wPgogICAgICAgICAqCiAgICAgICAgICogQHBhcmFtIHBhcmVudCBUaGUgYHBhcmVudGAgcGFyYW1ldGVyJ3MgdmFsdWUgZGVwZW5kcyBvbiB0aGUgdGFyZ2V0IHJlc291cmNlIGZvciB0aGUKICAgICAgcmVxdWVzdCwgbmFtZWx5CiAgICAgICAqICAgICAgICBbYHJvbGVzYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9yb2xlcyksCiAgICAgICAqICAgICAgICBbYHByb2plY3RzYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9wcm9qZWN0cy5yb2xlcyksIG9yCiAgICAgICAqICAgICAgICBbYG9yZ2FuaXphdGlvbnNgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL29yZ2FuaXphdGlvbnMucm9sZXMpLiBFYWNoCiAgICAgIHJlc291cmNlIHR5cGUncwogICAgICAgKiAgICAgICAgYHBhcmVudGAgdmFsdWUgZm9ybWF0IGlzIGRlc2NyaWJlZCBiZWxvdzoKICAgICAgKgogICAgICAgKiAgICAgICAgW2Byb2xlcy5saXN0KClgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL3JvbGVzL2xpc3QpOiBBbiBlbXB0eSBzdHJpbmcuCiAgICAgICAgVGhpcyBtZXRob2QKICAgICAgICogICAgICAgIGRvZXNuJ3QgcmVxdWlyZSBhIHJlc291cmNlOyBpdCBzaW1wbHkgcmV0dXJucyBhbGwKICAgICAgICBbcHJlZGVmaW5lZCByb2xlc10oL2lhbS9kb2NzCiAgICAgICAqICAgICAgICAvdW5kZXJzdGFuZGluZy1yb2xlcyNwcmVkZWZpbmVkX3JvbGVzKSBpbgogICAgICAgIENsb3VkIElBTS4gRXhhbXBsZSByZXF1ZXN0IFVSTDoKICAgICAgICogICAgICAgIGBodHRwczovL2lhbS5nb29nbGVhcGlzLmNvbS92MS9yb2xlc2AKICAgICAgKgogICAgICAgKiAgICAgICAgW2Bwcm9qZWN0cy5yb2xlcy5saXN0KClgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL3Byb2plY3RzLnJvbGVzL2xpc3QpOgogICAgICAgKiAgICAgICAgYHByb2plY3RzL3tQUk9KRUNUX0lEfWAuIFRoaXMgbWV0aG9kIGxpc3RzIGFsbCBwcm9qZWN0LWxldmVsCiAgICAgICAgW2N1c3RvbSByb2xlc10oL2lhbS9kb2NzCiAgICAgICAqICAgICAgICAvdW5kZXJzdGFuZGluZy1jdXN0b20tcm9sZXMpLgogICAgICAgIEV4YW1wbGUgcmVxdWVzdCBVUkw6CiAgICAgICAqICAgICAgICBgaHR0cHM6Ly9pYW0uZ29vZ2xlYXBpcy5jb20vdjEvcHJvamVjdHMve1BST0pFQ1RfSUR9L3JvbGVzYAogICAgICAqCiAgICAgICAqICAgICAgICBbYG9yZ2FuaXphdGlvbnMucm9sZXMubGlzdCgpYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9vcmdhbml6YXRpb25zLnJvbGVzL2xpc3QpOgogICAgICAgKiAgICAgICAgYG9yZ2FuaXphdGlvbnMve09SR0FOSVpBVElPTl9JRH1gLiBUaGlzIG1ldGhvZCBsaXN0cyBhbGwKICAgICAgICBvcmdhbml6YXRpb24tbGV2ZWwgW2N1c3RvbQogICAgICAgKiAgICAgICAgcm9sZXNdKC9pYW0vZG9jcy91bmRlcnN0YW5kaW5nLWN1c3RvbS1yb2xlcykuCiAgICAgICAgRXhhbXBsZSByZXF1ZXN0IFVSTDoKICAgICAgICogICAgICAgIGBodHRwczovL2lhbS5nb29nbGVhcGlzLmNvbS92MS9vcmdhbml6YXRpb25zL3tPUkdBTklaQVRJT05fSUR9L3JvbGVzYAogICAgICBOb3RlOiBXaWxkY2FyZCAoKikKICAgICAgICogICAgICAgIHZhbHVlcyBhcmUgaW52YWxpZDsgeW91IG11c3Qgc3BlY2lmeSBhIGNvbXBsZXRlIHByb2plY3QKICAgICAgSUQgb3Igb3JnYW5pemF0aW9uIElELgogICAgICAgICAqIEBzaW5jZSAxLjEzCiAgICAgICAgICovCiAgICAgICAgcHJvdGVjdGVkIExpc3QoamF2YS5sYW5nLlN0cmluZyBwYXJlbnQpIHsKICAgICAgICAgIHN1cGVyKElhbS50aGlzLCAiR0VUIiwgUkVTVF9QQVRILCBudWxsLCBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5pYW0udjEubW9kZWwuTGlzdFJvbGVzUmVzcG9uc2UuY2xhc3MpOwogICAgICAgICAgdGhpcy5wYXJlbnQgPSBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5QcmVjb25kaXRpb25zLmNoZWNrTm90TnVsbChwYXJlbnQsICJSZXF1aXJlZCBwYXJhbWV0ZXIgcGFyZW50IG11c3QgYmUgc3BlY2lmaWVkLiIpOwogICAgICAgICAgaWYgKCFnZXRTdXBwcmVzc1BhdHRlcm5DaGVja3MoKSkgewogICAgICAgICAgICBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5QcmVjb25kaXRpb25zLmNoZWNrQXJndW1lbnQoUEFSRU5UX1BBVFRFUk4ubWF0Y2hlcihwYXJlbnQpLm1hdGNoZXMoKSwKICAgICAgICAgICAgICAgICJQYXJhbWV0ZXIgcGFyZW50IG11c3QgY29uZm9ybSB0byB0aGUgcGF0dGVybiAiICsKICAgICAgICAgICAgICAgICJecHJvamVjdHMvW14vXSskIik7CiAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5hcGkuY2xpZW50Lmh0dHAuSHR0cFJlc3BvbnNlIGV4ZWN1dGVVc2luZ0hlYWQoKSB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuZXhlY3V0ZVVzaW5nSGVhZCgpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIGNvbS5nb29nbGUuYXBpLmNsaWVudC5odHRwLkh0dHBSZXF1ZXN0IGJ1aWxkSHR0cFJlcXVlc3RVc2luZ0hlYWQoKSB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuYnVpbGRIdHRwUmVxdWVzdFVzaW5nSGVhZCgpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIExpc3Qgc2V0JFhnYWZ2KGphdmEubGFuZy5TdHJpbmcgJFhnYWZ2KSB7CiAgICAgICAgICByZXR1cm4gKExpc3QpIHN1cGVyLnNldCRYZ2FmdigkWGdhZnYpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIExpc3Qgc2V0QWNjZXNzVG9rZW4oamF2YS5sYW5nLlN0cmluZyBhY2Nlc3NUb2tlbikgewogICAgICAgICAgcmV0dXJuIChMaXN0KSBzdXBlci5zZXRBY2Nlc3NUb2tlbihhY2Nlc3NUb2tlbik7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgTGlzdCBzZXRBbHQoamF2YS5sYW5nLlN0cmluZyBhbHQpIHsKICAgICAgICAgIHJldHVybiAoTGlzdCkgc3VwZXIuc2V0QWx0KGFsdCk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgTGlzdCBzZXRDYWxsYmFjayhqYXZhLmxhbmcuU3RyaW5nIGNhbGxiYWNrKSB7CiAgICAgICAgICByZXR1cm4gKExpc3QpIHN1cGVyLnNldENhbGxiYWNrKGNhbGxiYWNrKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBMaXN0IHNldEZpZWxkcyhqYXZhLmxhbmcuU3RyaW5nIGZpZWxkcykgewogICAgICAgICAgcmV0dXJuIChMaXN0KSBzdXBlci5zZXRGaWVsZHMoZmllbGRzKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBMaXN0IHNldEtleShqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgICAgcmV0dXJuIChMaXN0KSBzdXBlci5zZXRLZXkoa2V5KTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBMaXN0IHNldE9hdXRoVG9rZW4oamF2YS5sYW5nLlN0cmluZyBvYXV0aFRva2VuKSB7CiAgICAgICAgICByZXR1cm4gKExpc3QpIHN1cGVyLnNldE9hdXRoVG9rZW4ob2F1dGhUb2tlbik7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgTGlzdCBzZXRQcmV0dHlQcmludChqYXZhLmxhbmcuQm9vbGVhbiBwcmV0dHlQcmludCkgewogICAgICAgICAgcmV0dXJuIChMaXN0KSBzdXBlci5zZXRQcmV0dHlQcmludChwcmV0dHlQcmludCk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgTGlzdCBzZXRRdW90YVVzZXIoamF2YS5sYW5nLlN0cmluZyBxdW90YVVzZXIpIHsKICAgICAgICAgIHJldHVybiAoTGlzdCkgc3VwZXIuc2V0UXVvdGFVc2VyKHF1b3RhVXNlcik7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgTGlzdCBzZXRVcGxvYWRUeXBlKGphdmEubGFuZy5TdHJpbmcgdXBsb2FkVHlwZSkgewogICAgICAgICAgcmV0dXJuIChMaXN0KSBzdXBlci5zZXRVcGxvYWRUeXBlKHVwbG9hZFR5cGUpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIExpc3Qgc2V0VXBsb2FkUHJvdG9jb2woamF2YS5sYW5nLlN0cmluZyB1cGxvYWRQcm90b2NvbCkgewogICAgICAgICAgcmV0dXJuIChMaXN0KSBzdXBlci5zZXRVcGxvYWRQcm90b2NvbCh1cGxvYWRQcm90b2NvbCk7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiBUaGUgYHBhcmVudGAgcGFyYW1ldGVyJ3MgdmFsdWUgZGVwZW5kcyBvbiB0aGUgdGFyZ2V0IHJlc291cmNlIGZvciB0aGUgcmVxdWVzdCwgbmFtZWx5CiAgICAgICAgICogW2Byb2xlc2BdKC9pYW0vcmVmZXJlbmNlL3Jlc3QvdjEvcm9sZXMpLAogICAgICAgICAqIFtgcHJvamVjdHNgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL3Byb2plY3RzLnJvbGVzKSwgb3IKICAgICAgICAgKiBbYG9yZ2FuaXphdGlvbnNgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL29yZ2FuaXphdGlvbnMucm9sZXMpLiBFYWNoIHJlc291cmNlIHR5cGUncwogICAgICAgICAqIGBwYXJlbnRgIHZhbHVlIGZvcm1hdCBpcyBkZXNjcmliZWQgYmVsb3c6CiAgICAgICAgICoKICAgICAgICAgKiAqIFtgcm9sZXMubGlzdCgpYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9yb2xlcy9saXN0KTogQW4gZW1wdHkgc3RyaW5nLiBUaGlzIG1ldGhvZAogICAgICAgICAqIGRvZXNuJ3QgcmVxdWlyZSBhIHJlc291cmNlOyBpdCBzaW1wbHkgcmV0dXJucyBhbGwgW3ByZWRlZmluZWQgcm9sZXNdKC9pYW0vZG9jcwogICAgICAgICAqIC91bmRlcnN0YW5kaW5nLXJvbGVzI3ByZWRlZmluZWRfcm9sZXMpIGluIENsb3VkIElBTS4gRXhhbXBsZSByZXF1ZXN0IFVSTDoKICAgICAgICAgKiBgaHR0cHM6Ly9pYW0uZ29vZ2xlYXBpcy5jb20vdjEvcm9sZXNgCiAgICAgICAgICoKICAgICAgICAgKiAqIFtgcHJvamVjdHMucm9sZXMubGlzdCgpYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9wcm9qZWN0cy5yb2xlcy9saXN0KToKICAgICAgICAgKiBgcHJvamVjdHMve1BST0pFQ1RfSUR9YC4gVGhpcyBtZXRob2QgbGlzdHMgYWxsIHByb2plY3QtbGV2ZWwgW2N1c3RvbSByb2xlc10oL2lhbS9kb2NzCiAgICAgICAgICogL3VuZGVyc3RhbmRpbmctY3VzdG9tLXJvbGVzKS4gRXhhbXBsZSByZXF1ZXN0IFVSTDoKICAgICAgICAgKiBgaHR0cHM6Ly9pYW0uZ29vZ2xlYXBpcy5jb20vdjEvcHJvamVjdHMve1BST0pFQ1RfSUR9L3JvbGVzYAogICAgICAgICAqCiAgICAgICAgICogKiBbYG9yZ2FuaXphdGlvbnMucm9sZXMubGlzdCgpYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9vcmdhbml6YXRpb25zLnJvbGVzL2xpc3QpOgogICAgICAgICAqIGBvcmdhbml6YXRpb25zL3tPUkdBTklaQVRJT05fSUR9YC4gVGhpcyBtZXRob2QgbGlzdHMgYWxsIG9yZ2FuaXphdGlvbi1sZXZlbCBbY3VzdG9tCiAgICAgICAgICogcm9sZXNdKC9pYW0vZG9jcy91bmRlcnN0YW5kaW5nLWN1c3RvbS1yb2xlcykuIEV4YW1wbGUgcmVxdWVzdCBVUkw6CiAgICAgICAgICogYGh0dHBzOi8vaWFtLmdvb2dsZWFwaXMuY29tL3YxL29yZ2FuaXphdGlvbnMve09SR0FOSVpBVElPTl9JRH0vcm9sZXNgCiAgICAgICAgICoKICAgICAgICAgKiBOb3RlOiBXaWxkY2FyZCAoKikgdmFsdWVzIGFyZSBpbnZhbGlkOyB5b3UgbXVzdCBzcGVjaWZ5IGEgY29tcGxldGUgcHJvamVjdCBJRCBvcgogICAgICAgICAqIG9yZ2FuaXphdGlvbiBJRC4KICAgICAgICAgKi8KICAgICAgICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuU3RyaW5nIHBhcmVudDsKCiAgICAgICAgLyoqIFRoZSBgcGFyZW50YCBwYXJhbWV0ZXIncyB2YWx1ZSBkZXBlbmRzIG9uIHRoZSB0YXJnZXQgcmVzb3VyY2UgZm9yIHRoZSByZXF1ZXN0LCBuYW1lbHkKICAgICAgIFtgcm9sZXNgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL3JvbGVzKSwgW2Bwcm9qZWN0c2BdKC9pYW0vcmVmZXJlbmNlL3Jlc3QvdjEvcHJvamVjdHMucm9sZXMpLCBvcgogICAgICAgW2Bvcmdhbml6YXRpb25zYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9vcmdhbml6YXRpb25zLnJvbGVzKS4gRWFjaCByZXNvdXJjZSB0eXBlJ3MgYHBhcmVudGAgdmFsdWUKICAgICAgIGZvcm1hdCBpcyBkZXNjcmliZWQgYmVsb3c6CgogICAgICAgKiBbYHJvbGVzLmxpc3QoKWBdKC9pYW0vcmVmZXJlbmNlL3Jlc3QvdjEvcm9sZXMvbGlzdCk6IEFuIGVtcHR5IHN0cmluZy4gVGhpcyBtZXRob2QgZG9lc24ndCByZXF1aXJlCiAgICAgICBhIHJlc291cmNlOyBpdCBzaW1wbHkgcmV0dXJucyBhbGwgW3ByZWRlZmluZWQgcm9sZXNdKC9pYW0vZG9jcy91bmRlcnN0YW5kaW5nLQogICAgICAgcm9sZXMjcHJlZGVmaW5lZF9yb2xlcykgaW4gQ2xvdWQgSUFNLiBFeGFtcGxlIHJlcXVlc3QgVVJMOiBgaHR0cHM6Ly9pYW0uZ29vZ2xlYXBpcy5jb20vdjEvcm9sZXNgCgogICAgICAgKiBbYHByb2plY3RzLnJvbGVzLmxpc3QoKWBdKC9pYW0vcmVmZXJlbmNlL3Jlc3QvdjEvcHJvamVjdHMucm9sZXMvbGlzdCk6IGBwcm9qZWN0cy97UFJPSkVDVF9JRH1gLgogICAgICAgVGhpcyBtZXRob2QgbGlzdHMgYWxsIHByb2plY3QtbGV2ZWwgW2N1c3RvbSByb2xlc10oL2lhbS9kb2NzL3VuZGVyc3RhbmRpbmctY3VzdG9tLXJvbGVzKS4gRXhhbXBsZQogICAgICAgcmVxdWVzdCBVUkw6IGBodHRwczovL2lhbS5nb29nbGVhcGlzLmNvbS92MS9wcm9qZWN0cy97UFJPSkVDVF9JRH0vcm9sZXNgCgogICAgICAgKiBbYG9yZ2FuaXphdGlvbnMucm9sZXMubGlzdCgpYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9vcmdhbml6YXRpb25zLnJvbGVzL2xpc3QpOgogICAgICAgYG9yZ2FuaXphdGlvbnMve09SR0FOSVpBVElPTl9JRH1gLiBUaGlzIG1ldGhvZCBsaXN0cyBhbGwgb3JnYW5pemF0aW9uLWxldmVsIFtjdXN0b20KICAgICAgIHJvbGVzXSgvaWFtL2RvY3MvdW5kZXJzdGFuZGluZy1jdXN0b20tcm9sZXMpLiBFeGFtcGxlIHJlcXVlc3QgVVJMOgogICAgICAgYGh0dHBzOi8vaWFtLmdvb2dsZWFwaXMuY29tL3YxL29yZ2FuaXphdGlvbnMve09SR0FOSVpBVElPTl9JRH0vcm9sZXNgCgogICAgICAgTm90ZTogV2lsZGNhcmQgKCopIHZhbHVlcyBhcmUgaW52YWxpZDsgeW91IG11c3Qgc3BlY2lmeSBhIGNvbXBsZXRlIHByb2plY3QgSUQgb3Igb3JnYW5pemF0aW9uIElELgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFBhcmVudCgpIHsKICAgICAgICAgIHJldHVybiBwYXJlbnQ7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiBUaGUgYHBhcmVudGAgcGFyYW1ldGVyJ3MgdmFsdWUgZGVwZW5kcyBvbiB0aGUgdGFyZ2V0IHJlc291cmNlIGZvciB0aGUgcmVxdWVzdCwgbmFtZWx5CiAgICAgICAgICogW2Byb2xlc2BdKC9pYW0vcmVmZXJlbmNlL3Jlc3QvdjEvcm9sZXMpLAogICAgICAgICAqIFtgcHJvamVjdHNgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL3Byb2plY3RzLnJvbGVzKSwgb3IKICAgICAgICAgKiBbYG9yZ2FuaXphdGlvbnNgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL29yZ2FuaXphdGlvbnMucm9sZXMpLiBFYWNoIHJlc291cmNlIHR5cGUncwogICAgICAgICAqIGBwYXJlbnRgIHZhbHVlIGZvcm1hdCBpcyBkZXNjcmliZWQgYmVsb3c6CiAgICAgICAgICoKICAgICAgICAgKiAqIFtgcm9sZXMubGlzdCgpYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9yb2xlcy9saXN0KTogQW4gZW1wdHkgc3RyaW5nLiBUaGlzIG1ldGhvZAogICAgICAgICAqIGRvZXNuJ3QgcmVxdWlyZSBhIHJlc291cmNlOyBpdCBzaW1wbHkgcmV0dXJucyBhbGwgW3ByZWRlZmluZWQgcm9sZXNdKC9pYW0vZG9jcwogICAgICAgICAqIC91bmRlcnN0YW5kaW5nLXJvbGVzI3ByZWRlZmluZWRfcm9sZXMpIGluIENsb3VkIElBTS4gRXhhbXBsZSByZXF1ZXN0IFVSTDoKICAgICAgICAgKiBgaHR0cHM6Ly9pYW0uZ29vZ2xlYXBpcy5jb20vdjEvcm9sZXNgCiAgICAgICAgICoKICAgICAgICAgKiAqIFtgcHJvamVjdHMucm9sZXMubGlzdCgpYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9wcm9qZWN0cy5yb2xlcy9saXN0KToKICAgICAgICAgKiBgcHJvamVjdHMve1BST0pFQ1RfSUR9YC4gVGhpcyBtZXRob2QgbGlzdHMgYWxsIHByb2plY3QtbGV2ZWwgW2N1c3RvbSByb2xlc10oL2lhbS9kb2NzCiAgICAgICAgICogL3VuZGVyc3RhbmRpbmctY3VzdG9tLXJvbGVzKS4gRXhhbXBsZSByZXF1ZXN0IFVSTDoKICAgICAgICAgKiBgaHR0cHM6Ly9pYW0uZ29vZ2xlYXBpcy5jb20vdjEvcHJvamVjdHMve1BST0pFQ1RfSUR9L3JvbGVzYAogICAgICAgICAqCiAgICAgICAgICogKiBbYG9yZ2FuaXphdGlvbnMucm9sZXMubGlzdCgpYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9vcmdhbml6YXRpb25zLnJvbGVzL2xpc3QpOgogICAgICAgICAqIGBvcmdhbml6YXRpb25zL3tPUkdBTklaQVRJT05fSUR9YC4gVGhpcyBtZXRob2QgbGlzdHMgYWxsIG9yZ2FuaXphdGlvbi1sZXZlbCBbY3VzdG9tCiAgICAgICAgICogcm9sZXNdKC9pYW0vZG9jcy91bmRlcnN0YW5kaW5nLWN1c3RvbS1yb2xlcykuIEV4YW1wbGUgcmVxdWVzdCBVUkw6CiAgICAgICAgICogYGh0dHBzOi8vaWFtLmdvb2dsZWFwaXMuY29tL3YxL29yZ2FuaXphdGlvbnMve09SR0FOSVpBVElPTl9JRH0vcm9sZXNgCiAgICAgICAgICoKICAgICAgICAgKiBOb3RlOiBXaWxkY2FyZCAoKikgdmFsdWVzIGFyZSBpbnZhbGlkOyB5b3UgbXVzdCBzcGVjaWZ5IGEgY29tcGxldGUgcHJvamVjdCBJRCBvcgogICAgICAgICAqIG9yZ2FuaXphdGlvbiBJRC4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgTGlzdCBzZXRQYXJlbnQoamF2YS5sYW5nLlN0cmluZyBwYXJlbnQpIHsKICAgICAgICAgIGlmICghZ2V0U3VwcHJlc3NQYXR0ZXJuQ2hlY2tzKCkpIHsKICAgICAgICAgICAgY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuUHJlY29uZGl0aW9ucy5jaGVja0FyZ3VtZW50KFBBUkVOVF9QQVRURVJOLm1hdGNoZXIocGFyZW50KS5tYXRjaGVzKCksCiAgICAgICAgICAgICAgICAiUGFyYW1ldGVyIHBhcmVudCBtdXN0IGNvbmZvcm0gdG8gdGhlIHBhdHRlcm4gIiArCiAgICAgICAgICAgICAgICAiXnByb2plY3RzL1teL10rJCIpOwogICAgICAgICAgfQogICAgICAgICAgdGhpcy5wYXJlbnQgPSBwYXJlbnQ7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CgogICAgICAgIC8qKiBJbmNsdWRlIFJvbGVzIHRoYXQgaGF2ZSBiZWVuIGRlbGV0ZWQuICovCiAgICAgICAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogICAgICAgIHByaXZhdGUgamF2YS5sYW5nLkJvb2xlYW4gc2hvd0RlbGV0ZWQ7CgogICAgICAgIC8qKiBJbmNsdWRlIFJvbGVzIHRoYXQgaGF2ZSBiZWVuIGRlbGV0ZWQuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIGphdmEubGFuZy5Cb29sZWFuIGdldFNob3dEZWxldGVkKCkgewogICAgICAgICAgcmV0dXJuIHNob3dEZWxldGVkOwogICAgICAgIH0KCiAgICAgICAgLyoqIEluY2x1ZGUgUm9sZXMgdGhhdCBoYXZlIGJlZW4gZGVsZXRlZC4gKi8KICAgICAgICBwdWJsaWMgTGlzdCBzZXRTaG93RGVsZXRlZChqYXZhLmxhbmcuQm9vbGVhbiBzaG93RGVsZXRlZCkgewogICAgICAgICAgdGhpcy5zaG93RGVsZXRlZCA9IHNob3dEZWxldGVkOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQoKICAgICAgICAvKiogT3B0aW9uYWwgcGFnaW5hdGlvbiB0b2tlbiByZXR1cm5lZCBpbiBhbiBlYXJsaWVyIExpc3RSb2xlc1Jlc3BvbnNlLiAqLwogICAgICAgIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICAgICAgICBwcml2YXRlIGphdmEubGFuZy5TdHJpbmcgcGFnZVRva2VuOwoKICAgICAgICAvKiogT3B0aW9uYWwgcGFnaW5hdGlvbiB0b2tlbiByZXR1cm5lZCBpbiBhbiBlYXJsaWVyIExpc3RSb2xlc1Jlc3BvbnNlLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFBhZ2VUb2tlbigpIHsKICAgICAgICAgIHJldHVybiBwYWdlVG9rZW47CiAgICAgICAgfQoKICAgICAgICAvKiogT3B0aW9uYWwgcGFnaW5hdGlvbiB0b2tlbiByZXR1cm5lZCBpbiBhbiBlYXJsaWVyIExpc3RSb2xlc1Jlc3BvbnNlLiAqLwogICAgICAgIHB1YmxpYyBMaXN0IHNldFBhZ2VUb2tlbihqYXZhLmxhbmcuU3RyaW5nIHBhZ2VUb2tlbikgewogICAgICAgICAgdGhpcy5wYWdlVG9rZW4gPSBwYWdlVG9rZW47CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CgogICAgICAgIC8qKiBPcHRpb25hbCBsaW1pdCBvbiB0aGUgbnVtYmVyIG9mIHJvbGVzIHRvIGluY2x1ZGUgaW4gdGhlIHJlc3BvbnNlLiAqLwogICAgICAgIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICAgICAgICBwcml2YXRlIGphdmEubGFuZy5JbnRlZ2VyIHBhZ2VTaXplOwoKICAgICAgICAvKiogT3B0aW9uYWwgbGltaXQgb24gdGhlIG51bWJlciBvZiByb2xlcyB0byBpbmNsdWRlIGluIHRoZSByZXNwb25zZS4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgamF2YS5sYW5nLkludGVnZXIgZ2V0UGFnZVNpemUoKSB7CiAgICAgICAgICByZXR1cm4gcGFnZVNpemU7CiAgICAgICAgfQoKICAgICAgICAvKiogT3B0aW9uYWwgbGltaXQgb24gdGhlIG51bWJlciBvZiByb2xlcyB0byBpbmNsdWRlIGluIHRoZSByZXNwb25zZS4gKi8KICAgICAgICBwdWJsaWMgTGlzdCBzZXRQYWdlU2l6ZShqYXZhLmxhbmcuSW50ZWdlciBwYWdlU2l6ZSkgewogICAgICAgICAgdGhpcy5wYWdlU2l6ZSA9IHBhZ2VTaXplOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiBPcHRpb25hbCB2aWV3IGZvciB0aGUgcmV0dXJuZWQgUm9sZSBvYmplY3RzLiBXaGVuIGBGVUxMYCBpcyBzcGVjaWZpZWQsIHRoZQogICAgICAgICAqIGBpbmNsdWRlZFBlcm1pc3Npb25zYCBmaWVsZCBpcyByZXR1cm5lZCwgd2hpY2ggaW5jbHVkZXMgYSBsaXN0IG9mIGFsbCBwZXJtaXNzaW9ucyBpbiB0aGUKICAgICAgICAgKiByb2xlLiBUaGUgZGVmYXVsdCB2YWx1ZSBpcyBgQkFTSUNgLCB3aGljaCBkb2VzIG5vdCByZXR1cm4gdGhlIGBpbmNsdWRlZFBlcm1pc3Npb25zYAogICAgICAgICAqIGZpZWxkLgogICAgICAgICAqLwogICAgICAgIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICAgICAgICBwcml2YXRlIGphdmEubGFuZy5TdHJpbmcgdmlldzsKCiAgICAgICAgLyoqIE9wdGlvbmFsIHZpZXcgZm9yIHRoZSByZXR1cm5lZCBSb2xlIG9iamVjdHMuIFdoZW4gYEZVTExgIGlzIHNwZWNpZmllZCwgdGhlIGBpbmNsdWRlZFBlcm1pc3Npb25zYAogICAgICAgZmllbGQgaXMgcmV0dXJuZWQsIHdoaWNoIGluY2x1ZGVzIGEgbGlzdCBvZiBhbGwgcGVybWlzc2lvbnMgaW4gdGhlIHJvbGUuIFRoZSBkZWZhdWx0IHZhbHVlIGlzCiAgICAgICBgQkFTSUNgLCB3aGljaCBkb2VzIG5vdCByZXR1cm4gdGhlIGBpbmNsdWRlZFBlcm1pc3Npb25zYCBmaWVsZC4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRWaWV3KCkgewogICAgICAgICAgcmV0dXJuIHZpZXc7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiBPcHRpb25hbCB2aWV3IGZvciB0aGUgcmV0dXJuZWQgUm9sZSBvYmplY3RzLiBXaGVuIGBGVUxMYCBpcyBzcGVjaWZpZWQsIHRoZQogICAgICAgICAqIGBpbmNsdWRlZFBlcm1pc3Npb25zYCBmaWVsZCBpcyByZXR1cm5lZCwgd2hpY2ggaW5jbHVkZXMgYSBsaXN0IG9mIGFsbCBwZXJtaXNzaW9ucyBpbiB0aGUKICAgICAgICAgKiByb2xlLiBUaGUgZGVmYXVsdCB2YWx1ZSBpcyBgQkFTSUNgLCB3aGljaCBkb2VzIG5vdCByZXR1cm4gdGhlIGBpbmNsdWRlZFBlcm1pc3Npb25zYAogICAgICAgICAqIGZpZWxkLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBMaXN0IHNldFZpZXcoamF2YS5sYW5nLlN0cmluZyB2aWV3KSB7CiAgICAgICAgICB0aGlzLnZpZXcgPSB2aWV3OwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgTGlzdCBzZXQoU3RyaW5nIHBhcmFtZXRlck5hbWUsIE9iamVjdCB2YWx1ZSkgewogICAgICAgICAgcmV0dXJuIChMaXN0KSBzdXBlci5zZXQocGFyYW1ldGVyTmFtZSwgdmFsdWUpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogVXBkYXRlcyBhIFJvbGUgZGVmaW5pdGlvbi4KICAgICAgICoKICAgICAgICogQ3JlYXRlIGEgcmVxdWVzdCBmb3IgdGhlIG1ldGhvZCAicm9sZXMucGF0Y2giLgogICAgICAgKgogICAgICAgKiBUaGlzIHJlcXVlc3QgaG9sZHMgdGhlIHBhcmFtZXRlcnMgbmVlZGVkIGJ5IHRoZSBpYW0gc2VydmVyLiAgQWZ0ZXIgc2V0dGluZyBhbnkgb3B0aW9uYWwKICAgICAgICogcGFyYW1ldGVycywgY2FsbCB0aGUge0BsaW5rIFBhdGNoI2V4ZWN1dGUoKX0gbWV0aG9kIHRvIGludm9rZSB0aGUgcmVtb3RlIG9wZXJhdGlvbi4KICAgICAgICoKICAgICAgICogQHBhcmFtIG5hbWUgVGhlIGBuYW1lYCBwYXJhbWV0ZXIncyB2YWx1ZSBkZXBlbmRzIG9uIHRoZSB0YXJnZXQgcmVzb3VyY2UgZm9yIHRoZQogICAgICByZXF1ZXN0LCBuYW1lbHkKICAgICAgICogICAgICAgIFtgcHJvamVjdHNgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL3Byb2plY3RzLnJvbGVzKSBvcgogICAgICAgKiAgICAgICAgW2Bvcmdhbml6YXRpb25zYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9vcmdhbml6YXRpb25zLnJvbGVzKS4gRWFjaAogICAgICByZXNvdXJjZSB0eXBlJ3MgYG5hbWVgCiAgICAgICAqICAgICAgICB2YWx1ZSBmb3JtYXQgaXMgZGVzY3JpYmVkIGJlbG93OgogICAgICAqCiAgICAgICAqICAgICAgICBbYHByb2plY3RzLnJvbGVzLnBhdGNoKClgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL3Byb2plY3RzLnJvbGVzL3BhdGNoKToKICAgICAgICogICAgICAgIGBwcm9qZWN0cy97UFJPSkVDVF9JRH0vcm9sZXMve0NVU1RPTV9ST0xFX0lEfWAuIFRoaXMgbWV0aG9kIHVwZGF0ZXMgb25seQogICAgICAgIFtjdXN0b20KICAgICAgICogICAgICAgIHJvbGVzXSgvaWFtL2RvY3MvdW5kZXJzdGFuZGluZy1jdXN0b20tcm9sZXMpIHRoYXQgaGF2ZSBiZWVuCiAgICAgICAgY3JlYXRlZCBhdCB0aGUgcHJvamVjdAogICAgICAgKiAgICAgICAgbGV2ZWwuIEV4YW1wbGUgcmVxdWVzdCBVUkw6CiAgICAgICAqICAgICAgICBgaHR0cHM6Ly9pYW0uZ29vZ2xlYXBpcy5jb20vdjEvcHJvamVjdHMve1BST0pFQ1RfSUR9L3JvbGVzL3tDVVNUT01fUk9MRV9JRH1gCiAgICAgICoKICAgICAgICogICAgICAgIFtgb3JnYW5pemF0aW9ucy5yb2xlcy5wYXRjaCgpYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9vcmdhbml6YXRpb25zLnJvbGVzL3BhdGNoKToKICAgICAgICogICAgICAgIGBvcmdhbml6YXRpb25zL3tPUkdBTklaQVRJT05fSUR9L3JvbGVzL3tDVVNUT01fUk9MRV9JRH1gLiBUaGlzIG1ldGhvZAogICAgICAgIHVwZGF0ZXMgb25seQogICAgICAgKiAgICAgICAgW2N1c3RvbSByb2xlc10oL2lhbS9kb2NzL3VuZGVyc3RhbmRpbmctY3VzdG9tLXJvbGVzKSB0aGF0CiAgICAgICAgaGF2ZSBiZWVuIGNyZWF0ZWQgYXQgdGhlCiAgICAgICAqICAgICAgICBvcmdhbml6YXRpb24gbGV2ZWwuIEV4YW1wbGUgcmVxdWVzdCBVUkw6CiAgICAgICAqICAgICAgICBgaHR0cHM6Ly9pYW0uZ29vZ2xlYXBpcy5jb20vdjEvb3JnYW5pemF0aW9ucy97T1JHQU5JWkFUSU9OX0lEfS9yb2xlcy97Q1VTVE9NX1JPTEVfSUR9YAogICAgICAgKiAgICAgICAgTm90ZTogV2lsZGNhcmQgKCopIHZhbHVlcyBhcmUgaW52YWxpZDsgeW91IG11c3Qgc3BlY2lmeSBhIGNvbXBsZXRlIHByb2plY3QKICAgICAgSUQgb3IKICAgICAgICogICAgICAgIG9yZ2FuaXphdGlvbiBJRC4KICAgICAgICogQHBhcmFtIGNvbnRlbnQgdGhlIHtAbGluayBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5pYW0udjEubW9kZWwuUm9sZX0KICAgICAgICogQHJldHVybiB0aGUgcmVxdWVzdAogICAgICAgKi8KICAgICAgcHVibGljIFBhdGNoIHBhdGNoKGphdmEubGFuZy5TdHJpbmcgbmFtZSwgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuaWFtLnYxLm1vZGVsLlJvbGUgY29udGVudCkgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIFBhdGNoIHJlc3VsdCA9IG5ldyBQYXRjaChuYW1lLCBjb250ZW50KTsKICAgICAgICBpbml0aWFsaXplKHJlc3VsdCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHVibGljIGNsYXNzIFBhdGNoIGV4dGVuZHMgSWFtUmVxdWVzdDxjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5pYW0udjEubW9kZWwuUm9sZT4gewoKICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgUkVTVF9QQVRIID0gInYxL3srbmFtZX0iOwoKICAgICAgICBwcml2YXRlIGZpbmFsIGphdmEudXRpbC5yZWdleC5QYXR0ZXJuIE5BTUVfUEFUVEVSTiA9CiAgICAgICAgICAgIGphdmEudXRpbC5yZWdleC5QYXR0ZXJuLmNvbXBpbGUoIl5wcm9qZWN0cy9bXi9dKy9yb2xlcy9bXi9dKyQiKTsKCiAgICAgICAgLyoqCiAgICAgICAgICogVXBkYXRlcyBhIFJvbGUgZGVmaW5pdGlvbi4KICAgICAgICAgKgogICAgICAgICAqIENyZWF0ZSBhIHJlcXVlc3QgZm9yIHRoZSBtZXRob2QgInJvbGVzLnBhdGNoIi4KICAgICAgICAgKgogICAgICAgICAqIFRoaXMgcmVxdWVzdCBob2xkcyB0aGUgcGFyYW1ldGVycyBuZWVkZWQgYnkgdGhlIHRoZSBpYW0gc2VydmVyLiAgQWZ0ZXIgc2V0dGluZyBhbnkgb3B0aW9uYWwKICAgICAgICAgKiBwYXJhbWV0ZXJzLCBjYWxsIHRoZSB7QGxpbmsgUGF0Y2gjZXhlY3V0ZSgpfSBtZXRob2QgdG8gaW52b2tlIHRoZSByZW1vdGUgb3BlcmF0aW9uLiA8cD4ge0BsaW5rCiAgICAgICAgICogUGF0Y2gjaW5pdGlhbGl6ZShjb20uZ29vZ2xlLmFwaS5jbGllbnQuZ29vZ2xlYXBpcy5zZXJ2aWNlcy5BYnN0cmFjdEdvb2dsZUNsaWVudFJlcXVlc3QpfSBtdXN0CiAgICAgICAgICogYmUgY2FsbGVkIHRvIGluaXRpYWxpemUgdGhpcyBpbnN0YW5jZSBpbW1lZGlhdGVseSBhZnRlciBpbnZva2luZyB0aGUgY29uc3RydWN0b3IuIDwvcD4KICAgICAgICAgKgogICAgICAgICAqIEBwYXJhbSBuYW1lIFRoZSBgbmFtZWAgcGFyYW1ldGVyJ3MgdmFsdWUgZGVwZW5kcyBvbiB0aGUgdGFyZ2V0IHJlc291cmNlIGZvciB0aGUKICAgICAgcmVxdWVzdCwgbmFtZWx5CiAgICAgICAqICAgICAgICBbYHByb2plY3RzYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9wcm9qZWN0cy5yb2xlcykgb3IKICAgICAgICogICAgICAgIFtgb3JnYW5pemF0aW9uc2BdKC9pYW0vcmVmZXJlbmNlL3Jlc3QvdjEvb3JnYW5pemF0aW9ucy5yb2xlcykuIEVhY2gKICAgICAgcmVzb3VyY2UgdHlwZSdzIGBuYW1lYAogICAgICAgKiAgICAgICAgdmFsdWUgZm9ybWF0IGlzIGRlc2NyaWJlZCBiZWxvdzoKICAgICAgKgogICAgICAgKiAgICAgICAgW2Bwcm9qZWN0cy5yb2xlcy5wYXRjaCgpYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9wcm9qZWN0cy5yb2xlcy9wYXRjaCk6CiAgICAgICAqICAgICAgICBgcHJvamVjdHMve1BST0pFQ1RfSUR9L3JvbGVzL3tDVVNUT01fUk9MRV9JRH1gLiBUaGlzIG1ldGhvZCB1cGRhdGVzIG9ubHkKICAgICAgICBbY3VzdG9tCiAgICAgICAqICAgICAgICByb2xlc10oL2lhbS9kb2NzL3VuZGVyc3RhbmRpbmctY3VzdG9tLXJvbGVzKSB0aGF0IGhhdmUgYmVlbgogICAgICAgIGNyZWF0ZWQgYXQgdGhlIHByb2plY3QKICAgICAgICogICAgICAgIGxldmVsLiBFeGFtcGxlIHJlcXVlc3QgVVJMOgogICAgICAgKiAgICAgICAgYGh0dHBzOi8vaWFtLmdvb2dsZWFwaXMuY29tL3YxL3Byb2plY3RzL3tQUk9KRUNUX0lEfS9yb2xlcy97Q1VTVE9NX1JPTEVfSUR9YAogICAgICAqCiAgICAgICAqICAgICAgICBbYG9yZ2FuaXphdGlvbnMucm9sZXMucGF0Y2goKWBdKC9pYW0vcmVmZXJlbmNlL3Jlc3QvdjEvb3JnYW5pemF0aW9ucy5yb2xlcy9wYXRjaCk6CiAgICAgICAqICAgICAgICBgb3JnYW5pemF0aW9ucy97T1JHQU5JWkFUSU9OX0lEfS9yb2xlcy97Q1VTVE9NX1JPTEVfSUR9YC4gVGhpcyBtZXRob2QKICAgICAgICB1cGRhdGVzIG9ubHkKICAgICAgICogICAgICAgIFtjdXN0b20gcm9sZXNdKC9pYW0vZG9jcy91bmRlcnN0YW5kaW5nLWN1c3RvbS1yb2xlcykgdGhhdAogICAgICAgIGhhdmUgYmVlbiBjcmVhdGVkIGF0IHRoZQogICAgICAgKiAgICAgICAgb3JnYW5pemF0aW9uIGxldmVsLiBFeGFtcGxlIHJlcXVlc3QgVVJMOgogICAgICAgKiAgICAgICAgYGh0dHBzOi8vaWFtLmdvb2dsZWFwaXMuY29tL3YxL29yZ2FuaXphdGlvbnMve09SR0FOSVpBVElPTl9JRH0vcm9sZXMve0NVU1RPTV9ST0xFX0lEfWAKICAgICAgICogICAgICAgIE5vdGU6IFdpbGRjYXJkICgqKSB2YWx1ZXMgYXJlIGludmFsaWQ7IHlvdSBtdXN0IHNwZWNpZnkgYSBjb21wbGV0ZSBwcm9qZWN0CiAgICAgIElEIG9yCiAgICAgICAqICAgICAgICBvcmdhbml6YXRpb24gSUQuCiAgICAgICAgICogQHBhcmFtIGNvbnRlbnQgdGhlIHtAbGluayBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5pYW0udjEubW9kZWwuUm9sZX0KICAgICAgICAgKiBAc2luY2UgMS4xMwogICAgICAgICAqLwogICAgICAgIHByb3RlY3RlZCBQYXRjaChqYXZhLmxhbmcuU3RyaW5nIG5hbWUsIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmlhbS52MS5tb2RlbC5Sb2xlIGNvbnRlbnQpIHsKICAgICAgICAgIHN1cGVyKElhbS50aGlzLCAiUEFUQ0giLCBSRVNUX1BBVEgsIGNvbnRlbnQsIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmlhbS52MS5tb2RlbC5Sb2xlLmNsYXNzKTsKICAgICAgICAgIHRoaXMubmFtZSA9IGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLlByZWNvbmRpdGlvbnMuY2hlY2tOb3ROdWxsKG5hbWUsICJSZXF1aXJlZCBwYXJhbWV0ZXIgbmFtZSBtdXN0IGJlIHNwZWNpZmllZC4iKTsKICAgICAgICAgIGlmICghZ2V0U3VwcHJlc3NQYXR0ZXJuQ2hlY2tzKCkpIHsKICAgICAgICAgICAgY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuUHJlY29uZGl0aW9ucy5jaGVja0FyZ3VtZW50KE5BTUVfUEFUVEVSTi5tYXRjaGVyKG5hbWUpLm1hdGNoZXMoKSwKICAgICAgICAgICAgICAgICJQYXJhbWV0ZXIgbmFtZSBtdXN0IGNvbmZvcm0gdG8gdGhlIHBhdHRlcm4gIiArCiAgICAgICAgICAgICAgICAiXnByb2plY3RzL1teL10rL3JvbGVzL1teL10rJCIpOwogICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFBhdGNoIHNldCRYZ2FmdihqYXZhLmxhbmcuU3RyaW5nICRYZ2FmdikgewogICAgICAgICAgcmV0dXJuIChQYXRjaCkgc3VwZXIuc2V0JFhnYWZ2KCRYZ2Fmdik7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgUGF0Y2ggc2V0QWNjZXNzVG9rZW4oamF2YS5sYW5nLlN0cmluZyBhY2Nlc3NUb2tlbikgewogICAgICAgICAgcmV0dXJuIChQYXRjaCkgc3VwZXIuc2V0QWNjZXNzVG9rZW4oYWNjZXNzVG9rZW4pOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFBhdGNoIHNldEFsdChqYXZhLmxhbmcuU3RyaW5nIGFsdCkgewogICAgICAgICAgcmV0dXJuIChQYXRjaCkgc3VwZXIuc2V0QWx0KGFsdCk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgUGF0Y2ggc2V0Q2FsbGJhY2soamF2YS5sYW5nLlN0cmluZyBjYWxsYmFjaykgewogICAgICAgICAgcmV0dXJuIChQYXRjaCkgc3VwZXIuc2V0Q2FsbGJhY2soY2FsbGJhY2spOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFBhdGNoIHNldEZpZWxkcyhqYXZhLmxhbmcuU3RyaW5nIGZpZWxkcykgewogICAgICAgICAgcmV0dXJuIChQYXRjaCkgc3VwZXIuc2V0RmllbGRzKGZpZWxkcyk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgUGF0Y2ggc2V0S2V5KGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgICByZXR1cm4gKFBhdGNoKSBzdXBlci5zZXRLZXkoa2V5KTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBQYXRjaCBzZXRPYXV0aFRva2VuKGphdmEubGFuZy5TdHJpbmcgb2F1dGhUb2tlbikgewogICAgICAgICAgcmV0dXJuIChQYXRjaCkgc3VwZXIuc2V0T2F1dGhUb2tlbihvYXV0aFRva2VuKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBQYXRjaCBzZXRQcmV0dHlQcmludChqYXZhLmxhbmcuQm9vbGVhbiBwcmV0dHlQcmludCkgewogICAgICAgICAgcmV0dXJuIChQYXRjaCkgc3VwZXIuc2V0UHJldHR5UHJpbnQocHJldHR5UHJpbnQpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFBhdGNoIHNldFF1b3RhVXNlcihqYXZhLmxhbmcuU3RyaW5nIHF1b3RhVXNlcikgewogICAgICAgICAgcmV0dXJuIChQYXRjaCkgc3VwZXIuc2V0UXVvdGFVc2VyKHF1b3RhVXNlcik7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgUGF0Y2ggc2V0VXBsb2FkVHlwZShqYXZhLmxhbmcuU3RyaW5nIHVwbG9hZFR5cGUpIHsKICAgICAgICAgIHJldHVybiAoUGF0Y2gpIHN1cGVyLnNldFVwbG9hZFR5cGUodXBsb2FkVHlwZSk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgUGF0Y2ggc2V0VXBsb2FkUHJvdG9jb2woamF2YS5sYW5nLlN0cmluZyB1cGxvYWRQcm90b2NvbCkgewogICAgICAgICAgcmV0dXJuIChQYXRjaCkgc3VwZXIuc2V0VXBsb2FkUHJvdG9jb2wodXBsb2FkUHJvdG9jb2wpOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogVGhlIGBuYW1lYCBwYXJhbWV0ZXIncyB2YWx1ZSBkZXBlbmRzIG9uIHRoZSB0YXJnZXQgcmVzb3VyY2UgZm9yIHRoZSByZXF1ZXN0LCBuYW1lbHkKICAgICAgICAgKiBbYHByb2plY3RzYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9wcm9qZWN0cy5yb2xlcykgb3IKICAgICAgICAgKiBbYG9yZ2FuaXphdGlvbnNgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL29yZ2FuaXphdGlvbnMucm9sZXMpLiBFYWNoIHJlc291cmNlIHR5cGUncwogICAgICAgICAqIGBuYW1lYCB2YWx1ZSBmb3JtYXQgaXMgZGVzY3JpYmVkIGJlbG93OgogICAgICAgICAqCiAgICAgICAgICogKiBbYHByb2plY3RzLnJvbGVzLnBhdGNoKClgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL3Byb2plY3RzLnJvbGVzL3BhdGNoKToKICAgICAgICAgKiBgcHJvamVjdHMve1BST0pFQ1RfSUR9L3JvbGVzL3tDVVNUT01fUk9MRV9JRH1gLiBUaGlzIG1ldGhvZCB1cGRhdGVzIG9ubHkgW2N1c3RvbQogICAgICAgICAqIHJvbGVzXSgvaWFtL2RvY3MvdW5kZXJzdGFuZGluZy1jdXN0b20tcm9sZXMpIHRoYXQgaGF2ZSBiZWVuIGNyZWF0ZWQgYXQgdGhlIHByb2plY3QgbGV2ZWwuCiAgICAgICAgICogRXhhbXBsZSByZXF1ZXN0IFVSTDoKICAgICAgICAgKiBgaHR0cHM6Ly9pYW0uZ29vZ2xlYXBpcy5jb20vdjEvcHJvamVjdHMve1BST0pFQ1RfSUR9L3JvbGVzL3tDVVNUT01fUk9MRV9JRH1gCiAgICAgICAgICoKICAgICAgICAgKiAqIFtgb3JnYW5pemF0aW9ucy5yb2xlcy5wYXRjaCgpYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9vcmdhbml6YXRpb25zLnJvbGVzL3BhdGNoKToKICAgICAgICAgKiBgb3JnYW5pemF0aW9ucy97T1JHQU5JWkFUSU9OX0lEfS9yb2xlcy97Q1VTVE9NX1JPTEVfSUR9YC4gVGhpcyBtZXRob2QgdXBkYXRlcyBvbmx5CiAgICAgICAgICogW2N1c3RvbSByb2xlc10oL2lhbS9kb2NzL3VuZGVyc3RhbmRpbmctY3VzdG9tLXJvbGVzKSB0aGF0IGhhdmUgYmVlbiBjcmVhdGVkIGF0IHRoZQogICAgICAgICAqIG9yZ2FuaXphdGlvbiBsZXZlbC4gRXhhbXBsZSByZXF1ZXN0IFVSTDoKICAgICAgICAgKiBgaHR0cHM6Ly9pYW0uZ29vZ2xlYXBpcy5jb20vdjEvb3JnYW5pemF0aW9ucy97T1JHQU5JWkFUSU9OX0lEfS9yb2xlcy97Q1VTVE9NX1JPTEVfSUR9YAogICAgICAgICAqCiAgICAgICAgICogTm90ZTogV2lsZGNhcmQgKCopIHZhbHVlcyBhcmUgaW52YWxpZDsgeW91IG11c3Qgc3BlY2lmeSBhIGNvbXBsZXRlIHByb2plY3QgSUQgb3IKICAgICAgICAgKiBvcmdhbml6YXRpb24gSUQuCiAgICAgICAgICovCiAgICAgICAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogICAgICAgIHByaXZhdGUgamF2YS5sYW5nLlN0cmluZyBuYW1lOwoKICAgICAgICAvKiogVGhlIGBuYW1lYCBwYXJhbWV0ZXIncyB2YWx1ZSBkZXBlbmRzIG9uIHRoZSB0YXJnZXQgcmVzb3VyY2UgZm9yIHRoZSByZXF1ZXN0LCBuYW1lbHkKICAgICAgIFtgcHJvamVjdHNgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL3Byb2plY3RzLnJvbGVzKSBvcgogICAgICAgW2Bvcmdhbml6YXRpb25zYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9vcmdhbml6YXRpb25zLnJvbGVzKS4gRWFjaCByZXNvdXJjZSB0eXBlJ3MgYG5hbWVgIHZhbHVlCiAgICAgICBmb3JtYXQgaXMgZGVzY3JpYmVkIGJlbG93OgoKICAgICAgICogW2Bwcm9qZWN0cy5yb2xlcy5wYXRjaCgpYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9wcm9qZWN0cy5yb2xlcy9wYXRjaCk6CiAgICAgICBgcHJvamVjdHMve1BST0pFQ1RfSUR9L3JvbGVzL3tDVVNUT01fUk9MRV9JRH1gLiBUaGlzIG1ldGhvZCB1cGRhdGVzIG9ubHkgW2N1c3RvbSByb2xlc10oL2lhbS9kb2NzCiAgICAgICAvdW5kZXJzdGFuZGluZy1jdXN0b20tcm9sZXMpIHRoYXQgaGF2ZSBiZWVuIGNyZWF0ZWQgYXQgdGhlIHByb2plY3QgbGV2ZWwuIEV4YW1wbGUgcmVxdWVzdCBVUkw6CiAgICAgICBgaHR0cHM6Ly9pYW0uZ29vZ2xlYXBpcy5jb20vdjEvcHJvamVjdHMve1BST0pFQ1RfSUR9L3JvbGVzL3tDVVNUT01fUk9MRV9JRH1gCgogICAgICAgKiBbYG9yZ2FuaXphdGlvbnMucm9sZXMucGF0Y2goKWBdKC9pYW0vcmVmZXJlbmNlL3Jlc3QvdjEvb3JnYW5pemF0aW9ucy5yb2xlcy9wYXRjaCk6CiAgICAgICBgb3JnYW5pemF0aW9ucy97T1JHQU5JWkFUSU9OX0lEfS9yb2xlcy97Q1VTVE9NX1JPTEVfSUR9YC4gVGhpcyBtZXRob2QgdXBkYXRlcyBvbmx5IFtjdXN0b20KICAgICAgIHJvbGVzXSgvaWFtL2RvY3MvdW5kZXJzdGFuZGluZy1jdXN0b20tcm9sZXMpIHRoYXQgaGF2ZSBiZWVuIGNyZWF0ZWQgYXQgdGhlIG9yZ2FuaXphdGlvbiBsZXZlbC4KICAgICAgIEV4YW1wbGUgcmVxdWVzdCBVUkw6CiAgICAgICBgaHR0cHM6Ly9pYW0uZ29vZ2xlYXBpcy5jb20vdjEvb3JnYW5pemF0aW9ucy97T1JHQU5JWkFUSU9OX0lEfS9yb2xlcy97Q1VTVE9NX1JPTEVfSUR9YAoKICAgICAgIE5vdGU6IFdpbGRjYXJkICgqKSB2YWx1ZXMgYXJlIGludmFsaWQ7IHlvdSBtdXN0IHNwZWNpZnkgYSBjb21wbGV0ZSBwcm9qZWN0IElEIG9yIG9yZ2FuaXphdGlvbiBJRC4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXROYW1lKCkgewogICAgICAgICAgcmV0dXJuIG5hbWU7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiBUaGUgYG5hbWVgIHBhcmFtZXRlcidzIHZhbHVlIGRlcGVuZHMgb24gdGhlIHRhcmdldCByZXNvdXJjZSBmb3IgdGhlIHJlcXVlc3QsIG5hbWVseQogICAgICAgICAqIFtgcHJvamVjdHNgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL3Byb2plY3RzLnJvbGVzKSBvcgogICAgICAgICAqIFtgb3JnYW5pemF0aW9uc2BdKC9pYW0vcmVmZXJlbmNlL3Jlc3QvdjEvb3JnYW5pemF0aW9ucy5yb2xlcykuIEVhY2ggcmVzb3VyY2UgdHlwZSdzCiAgICAgICAgICogYG5hbWVgIHZhbHVlIGZvcm1hdCBpcyBkZXNjcmliZWQgYmVsb3c6CiAgICAgICAgICoKICAgICAgICAgKiAqIFtgcHJvamVjdHMucm9sZXMucGF0Y2goKWBdKC9pYW0vcmVmZXJlbmNlL3Jlc3QvdjEvcHJvamVjdHMucm9sZXMvcGF0Y2gpOgogICAgICAgICAqIGBwcm9qZWN0cy97UFJPSkVDVF9JRH0vcm9sZXMve0NVU1RPTV9ST0xFX0lEfWAuIFRoaXMgbWV0aG9kIHVwZGF0ZXMgb25seSBbY3VzdG9tCiAgICAgICAgICogcm9sZXNdKC9pYW0vZG9jcy91bmRlcnN0YW5kaW5nLWN1c3RvbS1yb2xlcykgdGhhdCBoYXZlIGJlZW4gY3JlYXRlZCBhdCB0aGUgcHJvamVjdCBsZXZlbC4KICAgICAgICAgKiBFeGFtcGxlIHJlcXVlc3QgVVJMOgogICAgICAgICAqIGBodHRwczovL2lhbS5nb29nbGVhcGlzLmNvbS92MS9wcm9qZWN0cy97UFJPSkVDVF9JRH0vcm9sZXMve0NVU1RPTV9ST0xFX0lEfWAKICAgICAgICAgKgogICAgICAgICAqICogW2Bvcmdhbml6YXRpb25zLnJvbGVzLnBhdGNoKClgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL29yZ2FuaXphdGlvbnMucm9sZXMvcGF0Y2gpOgogICAgICAgICAqIGBvcmdhbml6YXRpb25zL3tPUkdBTklaQVRJT05fSUR9L3JvbGVzL3tDVVNUT01fUk9MRV9JRH1gLiBUaGlzIG1ldGhvZCB1cGRhdGVzIG9ubHkKICAgICAgICAgKiBbY3VzdG9tIHJvbGVzXSgvaWFtL2RvY3MvdW5kZXJzdGFuZGluZy1jdXN0b20tcm9sZXMpIHRoYXQgaGF2ZSBiZWVuIGNyZWF0ZWQgYXQgdGhlCiAgICAgICAgICogb3JnYW5pemF0aW9uIGxldmVsLiBFeGFtcGxlIHJlcXVlc3QgVVJMOgogICAgICAgICAqIGBodHRwczovL2lhbS5nb29nbGVhcGlzLmNvbS92MS9vcmdhbml6YXRpb25zL3tPUkdBTklaQVRJT05fSUR9L3JvbGVzL3tDVVNUT01fUk9MRV9JRH1gCiAgICAgICAgICoKICAgICAgICAgKiBOb3RlOiBXaWxkY2FyZCAoKikgdmFsdWVzIGFyZSBpbnZhbGlkOyB5b3UgbXVzdCBzcGVjaWZ5IGEgY29tcGxldGUgcHJvamVjdCBJRCBvcgogICAgICAgICAqIG9yZ2FuaXphdGlvbiBJRC4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgUGF0Y2ggc2V0TmFtZShqYXZhLmxhbmcuU3RyaW5nIG5hbWUpIHsKICAgICAgICAgIGlmICghZ2V0U3VwcHJlc3NQYXR0ZXJuQ2hlY2tzKCkpIHsKICAgICAgICAgICAgY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuUHJlY29uZGl0aW9ucy5jaGVja0FyZ3VtZW50KE5BTUVfUEFUVEVSTi5tYXRjaGVyKG5hbWUpLm1hdGNoZXMoKSwKICAgICAgICAgICAgICAgICJQYXJhbWV0ZXIgbmFtZSBtdXN0IGNvbmZvcm0gdG8gdGhlIHBhdHRlcm4gIiArCiAgICAgICAgICAgICAgICAiXnByb2plY3RzL1teL10rL3JvbGVzL1teL10rJCIpOwogICAgICAgICAgfQogICAgICAgICAgdGhpcy5uYW1lID0gbmFtZTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KCiAgICAgICAgLyoqIEEgbWFzayBkZXNjcmliaW5nIHdoaWNoIGZpZWxkcyBpbiB0aGUgUm9sZSBoYXZlIGNoYW5nZWQuICovCiAgICAgICAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogICAgICAgIHByaXZhdGUgU3RyaW5nIHVwZGF0ZU1hc2s7CgogICAgICAgIC8qKiBBIG1hc2sgZGVzY3JpYmluZyB3aGljaCBmaWVsZHMgaW4gdGhlIFJvbGUgaGF2ZSBjaGFuZ2VkLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0VXBkYXRlTWFzaygpIHsKICAgICAgICAgIHJldHVybiB1cGRhdGVNYXNrOwogICAgICAgIH0KCiAgICAgICAgLyoqIEEgbWFzayBkZXNjcmliaW5nIHdoaWNoIGZpZWxkcyBpbiB0aGUgUm9sZSBoYXZlIGNoYW5nZWQuICovCiAgICAgICAgcHVibGljIFBhdGNoIHNldFVwZGF0ZU1hc2soU3RyaW5nIHVwZGF0ZU1hc2spIHsKICAgICAgICAgIHRoaXMudXBkYXRlTWFzayA9IHVwZGF0ZU1hc2s7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBQYXRjaCBzZXQoU3RyaW5nIHBhcmFtZXRlck5hbWUsIE9iamVjdCB2YWx1ZSkgewogICAgICAgICAgcmV0dXJuIChQYXRjaCkgc3VwZXIuc2V0KHBhcmFtZXRlck5hbWUsIHZhbHVlKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFVuZGVsZXRlIGEgUm9sZSwgYnJpbmdpbmcgaXQgYmFjayBpbiBpdHMgcHJldmlvdXMgc3RhdGUuCiAgICAgICAqCiAgICAgICAqIENyZWF0ZSBhIHJlcXVlc3QgZm9yIHRoZSBtZXRob2QgInJvbGVzLnVuZGVsZXRlIi4KICAgICAgICoKICAgICAgICogVGhpcyByZXF1ZXN0IGhvbGRzIHRoZSBwYXJhbWV0ZXJzIG5lZWRlZCBieSB0aGUgaWFtIHNlcnZlci4gIEFmdGVyIHNldHRpbmcgYW55IG9wdGlvbmFsCiAgICAgICAqIHBhcmFtZXRlcnMsIGNhbGwgdGhlIHtAbGluayBVbmRlbGV0ZSNleGVjdXRlKCl9IG1ldGhvZCB0byBpbnZva2UgdGhlIHJlbW90ZSBvcGVyYXRpb24uCiAgICAgICAqCiAgICAgICAqIEBwYXJhbSBuYW1lIFRoZSBgbmFtZWAgcGFyYW1ldGVyJ3MgdmFsdWUgZGVwZW5kcyBvbiB0aGUgdGFyZ2V0IHJlc291cmNlIGZvciB0aGUKICAgICAgcmVxdWVzdCwgbmFtZWx5CiAgICAgICAqICAgICAgICBbYHByb2plY3RzYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9wcm9qZWN0cy5yb2xlcykgb3IKICAgICAgICogICAgICAgIFtgb3JnYW5pemF0aW9uc2BdKC9pYW0vcmVmZXJlbmNlL3Jlc3QvdjEvb3JnYW5pemF0aW9ucy5yb2xlcykuIEVhY2gKICAgICAgcmVzb3VyY2UgdHlwZSdzIGBuYW1lYAogICAgICAgKiAgICAgICAgdmFsdWUgZm9ybWF0IGlzIGRlc2NyaWJlZCBiZWxvdzoKICAgICAgKgogICAgICAgKiAgICAgICAgW2Bwcm9qZWN0cy5yb2xlcy51bmRlbGV0ZSgpYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9wcm9qZWN0cy5yb2xlcy91bmRlbGV0ZSk6CiAgICAgICAqICAgICAgICBgcHJvamVjdHMve1BST0pFQ1RfSUR9L3JvbGVzL3tDVVNUT01fUk9MRV9JRH1gLiBUaGlzIG1ldGhvZCB1bmRlbGV0ZXMKICAgICAgICBvbmx5IFtjdXN0b20KICAgICAgICogICAgICAgIHJvbGVzXSgvaWFtL2RvY3MvdW5kZXJzdGFuZGluZy1jdXN0b20tcm9sZXMpIHRoYXQgaGF2ZSBiZWVuCiAgICAgICAgY3JlYXRlZCBhdCB0aGUgcHJvamVjdAogICAgICAgKiAgICAgICAgbGV2ZWwuIEV4YW1wbGUgcmVxdWVzdCBVUkw6CiAgICAgICAqICAgICAgICBgaHR0cHM6Ly9pYW0uZ29vZ2xlYXBpcy5jb20vdjEvcHJvamVjdHMve1BST0pFQ1RfSUR9L3JvbGVzL3tDVVNUT01fUk9MRV9JRH1gCiAgICAgICoKICAgICAgICogICAgICAgIFtgb3JnYW5pemF0aW9ucy5yb2xlcy51bmRlbGV0ZSgpYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9vcmdhbml6YXRpb25zLnJvbGVzL3VuZGVsZXRlKToKICAgICAgICogICAgICAgIGBvcmdhbml6YXRpb25zL3tPUkdBTklaQVRJT05fSUR9L3JvbGVzL3tDVVNUT01fUk9MRV9JRH1gLiBUaGlzIG1ldGhvZAogICAgICAgIHVuZGVsZXRlcyBvbmx5CiAgICAgICAqICAgICAgICBbY3VzdG9tIHJvbGVzXSgvaWFtL2RvY3MvdW5kZXJzdGFuZGluZy1jdXN0b20tcm9sZXMpIHRoYXQKICAgICAgICBoYXZlIGJlZW4gY3JlYXRlZCBhdCB0aGUKICAgICAgICogICAgICAgIG9yZ2FuaXphdGlvbiBsZXZlbC4gRXhhbXBsZSByZXF1ZXN0IFVSTDoKICAgICAgICogICAgICAgIGBodHRwczovL2lhbS5nb29nbGVhcGlzLmNvbS92MS9vcmdhbml6YXRpb25zL3tPUkdBTklaQVRJT05fSUR9L3JvbGVzL3tDVVNUT01fUk9MRV9JRH1gCiAgICAgICAqICAgICAgICBOb3RlOiBXaWxkY2FyZCAoKikgdmFsdWVzIGFyZSBpbnZhbGlkOyB5b3UgbXVzdCBzcGVjaWZ5IGEgY29tcGxldGUgcHJvamVjdAogICAgICBJRCBvcgogICAgICAgKiAgICAgICAgb3JnYW5pemF0aW9uIElELgogICAgICAgKiBAcGFyYW0gY29udGVudCB0aGUge0BsaW5rIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmlhbS52MS5tb2RlbC5VbmRlbGV0ZVJvbGVSZXF1ZXN0fQogICAgICAgKiBAcmV0dXJuIHRoZSByZXF1ZXN0CiAgICAgICAqLwogICAgICBwdWJsaWMgVW5kZWxldGUgdW5kZWxldGUoamF2YS5sYW5nLlN0cmluZyBuYW1lLCBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5pYW0udjEubW9kZWwuVW5kZWxldGVSb2xlUmVxdWVzdCBjb250ZW50KSB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgVW5kZWxldGUgcmVzdWx0ID0gbmV3IFVuZGVsZXRlKG5hbWUsIGNvbnRlbnQpOwogICAgICAgIGluaXRpYWxpemUocmVzdWx0KTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBwdWJsaWMgY2xhc3MgVW5kZWxldGUgZXh0ZW5kcyBJYW1SZXF1ZXN0PGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmlhbS52MS5tb2RlbC5Sb2xlPiB7CgogICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBSRVNUX1BBVEggPSAidjEveytuYW1lfTp1bmRlbGV0ZSI7CgogICAgICAgIHByaXZhdGUgZmluYWwgamF2YS51dGlsLnJlZ2V4LlBhdHRlcm4gTkFNRV9QQVRURVJOID0KICAgICAgICAgICAgamF2YS51dGlsLnJlZ2V4LlBhdHRlcm4uY29tcGlsZSgiXnByb2plY3RzL1teL10rL3JvbGVzL1teL10rJCIpOwoKICAgICAgICAvKioKICAgICAgICAgKiBVbmRlbGV0ZSBhIFJvbGUsIGJyaW5naW5nIGl0IGJhY2sgaW4gaXRzIHByZXZpb3VzIHN0YXRlLgogICAgICAgICAqCiAgICAgICAgICogQ3JlYXRlIGEgcmVxdWVzdCBmb3IgdGhlIG1ldGhvZCAicm9sZXMudW5kZWxldGUiLgogICAgICAgICAqCiAgICAgICAgICogVGhpcyByZXF1ZXN0IGhvbGRzIHRoZSBwYXJhbWV0ZXJzIG5lZWRlZCBieSB0aGUgdGhlIGlhbSBzZXJ2ZXIuICBBZnRlciBzZXR0aW5nIGFueSBvcHRpb25hbAogICAgICAgICAqIHBhcmFtZXRlcnMsIGNhbGwgdGhlIHtAbGluayBVbmRlbGV0ZSNleGVjdXRlKCl9IG1ldGhvZCB0byBpbnZva2UgdGhlIHJlbW90ZSBvcGVyYXRpb24uIDxwPgogICAgICAgICAqIHtAbGluawogICAgICAgICAqIFVuZGVsZXRlI2luaXRpYWxpemUoY29tLmdvb2dsZS5hcGkuY2xpZW50Lmdvb2dsZWFwaXMuc2VydmljZXMuQWJzdHJhY3RHb29nbGVDbGllbnRSZXF1ZXN0KX0KICAgICAgICAgKiBtdXN0IGJlIGNhbGxlZCB0byBpbml0aWFsaXplIHRoaXMgaW5zdGFuY2UgaW1tZWRpYXRlbHkgYWZ0ZXIgaW52b2tpbmcgdGhlIGNvbnN0cnVjdG9yLiA8L3A+CiAgICAgICAgICoKICAgICAgICAgKiBAcGFyYW0gbmFtZSBUaGUgYG5hbWVgIHBhcmFtZXRlcidzIHZhbHVlIGRlcGVuZHMgb24gdGhlIHRhcmdldCByZXNvdXJjZSBmb3IgdGhlCiAgICAgIHJlcXVlc3QsIG5hbWVseQogICAgICAgKiAgICAgICAgW2Bwcm9qZWN0c2BdKC9pYW0vcmVmZXJlbmNlL3Jlc3QvdjEvcHJvamVjdHMucm9sZXMpIG9yCiAgICAgICAqICAgICAgICBbYG9yZ2FuaXphdGlvbnNgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL29yZ2FuaXphdGlvbnMucm9sZXMpLiBFYWNoCiAgICAgIHJlc291cmNlIHR5cGUncyBgbmFtZWAKICAgICAgICogICAgICAgIHZhbHVlIGZvcm1hdCBpcyBkZXNjcmliZWQgYmVsb3c6CiAgICAgICoKICAgICAgICogICAgICAgIFtgcHJvamVjdHMucm9sZXMudW5kZWxldGUoKWBdKC9pYW0vcmVmZXJlbmNlL3Jlc3QvdjEvcHJvamVjdHMucm9sZXMvdW5kZWxldGUpOgogICAgICAgKiAgICAgICAgYHByb2plY3RzL3tQUk9KRUNUX0lEfS9yb2xlcy97Q1VTVE9NX1JPTEVfSUR9YC4gVGhpcyBtZXRob2QgdW5kZWxldGVzCiAgICAgICAgb25seSBbY3VzdG9tCiAgICAgICAqICAgICAgICByb2xlc10oL2lhbS9kb2NzL3VuZGVyc3RhbmRpbmctY3VzdG9tLXJvbGVzKSB0aGF0IGhhdmUgYmVlbgogICAgICAgIGNyZWF0ZWQgYXQgdGhlIHByb2plY3QKICAgICAgICogICAgICAgIGxldmVsLiBFeGFtcGxlIHJlcXVlc3QgVVJMOgogICAgICAgKiAgICAgICAgYGh0dHBzOi8vaWFtLmdvb2dsZWFwaXMuY29tL3YxL3Byb2plY3RzL3tQUk9KRUNUX0lEfS9yb2xlcy97Q1VTVE9NX1JPTEVfSUR9YAogICAgICAqCiAgICAgICAqICAgICAgICBbYG9yZ2FuaXphdGlvbnMucm9sZXMudW5kZWxldGUoKWBdKC9pYW0vcmVmZXJlbmNlL3Jlc3QvdjEvb3JnYW5pemF0aW9ucy5yb2xlcy91bmRlbGV0ZSk6CiAgICAgICAqICAgICAgICBgb3JnYW5pemF0aW9ucy97T1JHQU5JWkFUSU9OX0lEfS9yb2xlcy97Q1VTVE9NX1JPTEVfSUR9YC4gVGhpcyBtZXRob2QKICAgICAgICB1bmRlbGV0ZXMgb25seQogICAgICAgKiAgICAgICAgW2N1c3RvbSByb2xlc10oL2lhbS9kb2NzL3VuZGVyc3RhbmRpbmctY3VzdG9tLXJvbGVzKSB0aGF0CiAgICAgICAgaGF2ZSBiZWVuIGNyZWF0ZWQgYXQgdGhlCiAgICAgICAqICAgICAgICBvcmdhbml6YXRpb24gbGV2ZWwuIEV4YW1wbGUgcmVxdWVzdCBVUkw6CiAgICAgICAqICAgICAgICBgaHR0cHM6Ly9pYW0uZ29vZ2xlYXBpcy5jb20vdjEvb3JnYW5pemF0aW9ucy97T1JHQU5JWkFUSU9OX0lEfS9yb2xlcy97Q1VTVE9NX1JPTEVfSUR9YAogICAgICAgKiAgICAgICAgTm90ZTogV2lsZGNhcmQgKCopIHZhbHVlcyBhcmUgaW52YWxpZDsgeW91IG11c3Qgc3BlY2lmeSBhIGNvbXBsZXRlIHByb2plY3QKICAgICAgSUQgb3IKICAgICAgICogICAgICAgIG9yZ2FuaXphdGlvbiBJRC4KICAgICAgICAgKiBAcGFyYW0gY29udGVudCB0aGUge0BsaW5rIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmlhbS52MS5tb2RlbC5VbmRlbGV0ZVJvbGVSZXF1ZXN0fQogICAgICAgICAqIEBzaW5jZSAxLjEzCiAgICAgICAgICovCiAgICAgICAgcHJvdGVjdGVkIFVuZGVsZXRlKGphdmEubGFuZy5TdHJpbmcgbmFtZSwgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuaWFtLnYxLm1vZGVsLlVuZGVsZXRlUm9sZVJlcXVlc3QgY29udGVudCkgewogICAgICAgICAgc3VwZXIoSWFtLnRoaXMsICJQT1NUIiwgUkVTVF9QQVRILCBjb250ZW50LCBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5pYW0udjEubW9kZWwuUm9sZS5jbGFzcyk7CiAgICAgICAgICB0aGlzLm5hbWUgPSBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5QcmVjb25kaXRpb25zLmNoZWNrTm90TnVsbChuYW1lLCAiUmVxdWlyZWQgcGFyYW1ldGVyIG5hbWUgbXVzdCBiZSBzcGVjaWZpZWQuIik7CiAgICAgICAgICBpZiAoIWdldFN1cHByZXNzUGF0dGVybkNoZWNrcygpKSB7CiAgICAgICAgICAgIGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLlByZWNvbmRpdGlvbnMuY2hlY2tBcmd1bWVudChOQU1FX1BBVFRFUk4ubWF0Y2hlcihuYW1lKS5tYXRjaGVzKCksCiAgICAgICAgICAgICAgICAiUGFyYW1ldGVyIG5hbWUgbXVzdCBjb25mb3JtIHRvIHRoZSBwYXR0ZXJuICIgKwogICAgICAgICAgICAgICAgIl5wcm9qZWN0cy9bXi9dKy9yb2xlcy9bXi9dKyQiKTsKICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBVbmRlbGV0ZSBzZXQkWGdhZnYoamF2YS5sYW5nLlN0cmluZyAkWGdhZnYpIHsKICAgICAgICAgIHJldHVybiAoVW5kZWxldGUpIHN1cGVyLnNldCRYZ2FmdigkWGdhZnYpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFVuZGVsZXRlIHNldEFjY2Vzc1Rva2VuKGphdmEubGFuZy5TdHJpbmcgYWNjZXNzVG9rZW4pIHsKICAgICAgICAgIHJldHVybiAoVW5kZWxldGUpIHN1cGVyLnNldEFjY2Vzc1Rva2VuKGFjY2Vzc1Rva2VuKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBVbmRlbGV0ZSBzZXRBbHQoamF2YS5sYW5nLlN0cmluZyBhbHQpIHsKICAgICAgICAgIHJldHVybiAoVW5kZWxldGUpIHN1cGVyLnNldEFsdChhbHQpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFVuZGVsZXRlIHNldENhbGxiYWNrKGphdmEubGFuZy5TdHJpbmcgY2FsbGJhY2spIHsKICAgICAgICAgIHJldHVybiAoVW5kZWxldGUpIHN1cGVyLnNldENhbGxiYWNrKGNhbGxiYWNrKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBVbmRlbGV0ZSBzZXRGaWVsZHMoamF2YS5sYW5nLlN0cmluZyBmaWVsZHMpIHsKICAgICAgICAgIHJldHVybiAoVW5kZWxldGUpIHN1cGVyLnNldEZpZWxkcyhmaWVsZHMpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFVuZGVsZXRlIHNldEtleShqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgICAgcmV0dXJuIChVbmRlbGV0ZSkgc3VwZXIuc2V0S2V5KGtleSk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgVW5kZWxldGUgc2V0T2F1dGhUb2tlbihqYXZhLmxhbmcuU3RyaW5nIG9hdXRoVG9rZW4pIHsKICAgICAgICAgIHJldHVybiAoVW5kZWxldGUpIHN1cGVyLnNldE9hdXRoVG9rZW4ob2F1dGhUb2tlbik7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgVW5kZWxldGUgc2V0UHJldHR5UHJpbnQoamF2YS5sYW5nLkJvb2xlYW4gcHJldHR5UHJpbnQpIHsKICAgICAgICAgIHJldHVybiAoVW5kZWxldGUpIHN1cGVyLnNldFByZXR0eVByaW50KHByZXR0eVByaW50KTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBVbmRlbGV0ZSBzZXRRdW90YVVzZXIoamF2YS5sYW5nLlN0cmluZyBxdW90YVVzZXIpIHsKICAgICAgICAgIHJldHVybiAoVW5kZWxldGUpIHN1cGVyLnNldFF1b3RhVXNlcihxdW90YVVzZXIpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFVuZGVsZXRlIHNldFVwbG9hZFR5cGUoamF2YS5sYW5nLlN0cmluZyB1cGxvYWRUeXBlKSB7CiAgICAgICAgICByZXR1cm4gKFVuZGVsZXRlKSBzdXBlci5zZXRVcGxvYWRUeXBlKHVwbG9hZFR5cGUpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFVuZGVsZXRlIHNldFVwbG9hZFByb3RvY29sKGphdmEubGFuZy5TdHJpbmcgdXBsb2FkUHJvdG9jb2wpIHsKICAgICAgICAgIHJldHVybiAoVW5kZWxldGUpIHN1cGVyLnNldFVwbG9hZFByb3RvY29sKHVwbG9hZFByb3RvY29sKTsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIFRoZSBgbmFtZWAgcGFyYW1ldGVyJ3MgdmFsdWUgZGVwZW5kcyBvbiB0aGUgdGFyZ2V0IHJlc291cmNlIGZvciB0aGUgcmVxdWVzdCwgbmFtZWx5CiAgICAgICAgICogW2Bwcm9qZWN0c2BdKC9pYW0vcmVmZXJlbmNlL3Jlc3QvdjEvcHJvamVjdHMucm9sZXMpIG9yCiAgICAgICAgICogW2Bvcmdhbml6YXRpb25zYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9vcmdhbml6YXRpb25zLnJvbGVzKS4gRWFjaCByZXNvdXJjZSB0eXBlJ3MKICAgICAgICAgKiBgbmFtZWAgdmFsdWUgZm9ybWF0IGlzIGRlc2NyaWJlZCBiZWxvdzoKICAgICAgICAgKgogICAgICAgICAqICogW2Bwcm9qZWN0cy5yb2xlcy51bmRlbGV0ZSgpYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9wcm9qZWN0cy5yb2xlcy91bmRlbGV0ZSk6CiAgICAgICAgICogYHByb2plY3RzL3tQUk9KRUNUX0lEfS9yb2xlcy97Q1VTVE9NX1JPTEVfSUR9YC4gVGhpcyBtZXRob2QgdW5kZWxldGVzIG9ubHkgW2N1c3RvbQogICAgICAgICAqIHJvbGVzXSgvaWFtL2RvY3MvdW5kZXJzdGFuZGluZy1jdXN0b20tcm9sZXMpIHRoYXQgaGF2ZSBiZWVuIGNyZWF0ZWQgYXQgdGhlIHByb2plY3QgbGV2ZWwuCiAgICAgICAgICogRXhhbXBsZSByZXF1ZXN0IFVSTDoKICAgICAgICAgKiBgaHR0cHM6Ly9pYW0uZ29vZ2xlYXBpcy5jb20vdjEvcHJvamVjdHMve1BST0pFQ1RfSUR9L3JvbGVzL3tDVVNUT01fUk9MRV9JRH1gCiAgICAgICAgICoKICAgICAgICAgKiAqCiAgICAgICAgICogW2Bvcmdhbml6YXRpb25zLnJvbGVzLnVuZGVsZXRlKClgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL29yZ2FuaXphdGlvbnMucm9sZXMvdW5kZWxldGUpOgogICAgICAgICAqIGBvcmdhbml6YXRpb25zL3tPUkdBTklaQVRJT05fSUR9L3JvbGVzL3tDVVNUT01fUk9MRV9JRH1gLiBUaGlzIG1ldGhvZCB1bmRlbGV0ZXMgb25seQogICAgICAgICAqIFtjdXN0b20gcm9sZXNdKC9pYW0vZG9jcy91bmRlcnN0YW5kaW5nLWN1c3RvbS1yb2xlcykgdGhhdCBoYXZlIGJlZW4gY3JlYXRlZCBhdCB0aGUKICAgICAgICAgKiBvcmdhbml6YXRpb24gbGV2ZWwuIEV4YW1wbGUgcmVxdWVzdCBVUkw6CiAgICAgICAgICogYGh0dHBzOi8vaWFtLmdvb2dsZWFwaXMuY29tL3YxL29yZ2FuaXphdGlvbnMve09SR0FOSVpBVElPTl9JRH0vcm9sZXMve0NVU1RPTV9ST0xFX0lEfWAKICAgICAgICAgKgogICAgICAgICAqIE5vdGU6IFdpbGRjYXJkICgqKSB2YWx1ZXMgYXJlIGludmFsaWQ7IHlvdSBtdXN0IHNwZWNpZnkgYSBjb21wbGV0ZSBwcm9qZWN0IElEIG9yCiAgICAgICAgICogb3JnYW5pemF0aW9uIElELgogICAgICAgICAqLwogICAgICAgIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICAgICAgICBwcml2YXRlIGphdmEubGFuZy5TdHJpbmcgbmFtZTsKCiAgICAgICAgLyoqIFRoZSBgbmFtZWAgcGFyYW1ldGVyJ3MgdmFsdWUgZGVwZW5kcyBvbiB0aGUgdGFyZ2V0IHJlc291cmNlIGZvciB0aGUgcmVxdWVzdCwgbmFtZWx5CiAgICAgICBbYHByb2plY3RzYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9wcm9qZWN0cy5yb2xlcykgb3IKICAgICAgIFtgb3JnYW5pemF0aW9uc2BdKC9pYW0vcmVmZXJlbmNlL3Jlc3QvdjEvb3JnYW5pemF0aW9ucy5yb2xlcykuIEVhY2ggcmVzb3VyY2UgdHlwZSdzIGBuYW1lYCB2YWx1ZQogICAgICAgZm9ybWF0IGlzIGRlc2NyaWJlZCBiZWxvdzoKCiAgICAgICAqIFtgcHJvamVjdHMucm9sZXMudW5kZWxldGUoKWBdKC9pYW0vcmVmZXJlbmNlL3Jlc3QvdjEvcHJvamVjdHMucm9sZXMvdW5kZWxldGUpOgogICAgICAgYHByb2plY3RzL3tQUk9KRUNUX0lEfS9yb2xlcy97Q1VTVE9NX1JPTEVfSUR9YC4gVGhpcyBtZXRob2QgdW5kZWxldGVzIG9ubHkgW2N1c3RvbSByb2xlc10oL2lhbS9kb2NzCiAgICAgICAvdW5kZXJzdGFuZGluZy1jdXN0b20tcm9sZXMpIHRoYXQgaGF2ZSBiZWVuIGNyZWF0ZWQgYXQgdGhlIHByb2plY3QgbGV2ZWwuIEV4YW1wbGUgcmVxdWVzdCBVUkw6CiAgICAgICBgaHR0cHM6Ly9pYW0uZ29vZ2xlYXBpcy5jb20vdjEvcHJvamVjdHMve1BST0pFQ1RfSUR9L3JvbGVzL3tDVVNUT01fUk9MRV9JRH1gCgogICAgICAgKiBbYG9yZ2FuaXphdGlvbnMucm9sZXMudW5kZWxldGUoKWBdKC9pYW0vcmVmZXJlbmNlL3Jlc3QvdjEvb3JnYW5pemF0aW9ucy5yb2xlcy91bmRlbGV0ZSk6CiAgICAgICBgb3JnYW5pemF0aW9ucy97T1JHQU5JWkFUSU9OX0lEfS9yb2xlcy97Q1VTVE9NX1JPTEVfSUR9YC4gVGhpcyBtZXRob2QgdW5kZWxldGVzIG9ubHkgW2N1c3RvbQogICAgICAgcm9sZXNdKC9pYW0vZG9jcy91bmRlcnN0YW5kaW5nLWN1c3RvbS1yb2xlcykgdGhhdCBoYXZlIGJlZW4gY3JlYXRlZCBhdCB0aGUgb3JnYW5pemF0aW9uIGxldmVsLgogICAgICAgRXhhbXBsZSByZXF1ZXN0IFVSTDoKICAgICAgIGBodHRwczovL2lhbS5nb29nbGVhcGlzLmNvbS92MS9vcmdhbml6YXRpb25zL3tPUkdBTklaQVRJT05fSUR9L3JvbGVzL3tDVVNUT01fUk9MRV9JRH1gCgogICAgICAgTm90ZTogV2lsZGNhcmQgKCopIHZhbHVlcyBhcmUgaW52YWxpZDsgeW91IG11c3Qgc3BlY2lmeSBhIGNvbXBsZXRlIHByb2plY3QgSUQgb3Igb3JnYW5pemF0aW9uIElELgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldE5hbWUoKSB7CiAgICAgICAgICByZXR1cm4gbmFtZTsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIFRoZSBgbmFtZWAgcGFyYW1ldGVyJ3MgdmFsdWUgZGVwZW5kcyBvbiB0aGUgdGFyZ2V0IHJlc291cmNlIGZvciB0aGUgcmVxdWVzdCwgbmFtZWx5CiAgICAgICAgICogW2Bwcm9qZWN0c2BdKC9pYW0vcmVmZXJlbmNlL3Jlc3QvdjEvcHJvamVjdHMucm9sZXMpIG9yCiAgICAgICAgICogW2Bvcmdhbml6YXRpb25zYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9vcmdhbml6YXRpb25zLnJvbGVzKS4gRWFjaCByZXNvdXJjZSB0eXBlJ3MKICAgICAgICAgKiBgbmFtZWAgdmFsdWUgZm9ybWF0IGlzIGRlc2NyaWJlZCBiZWxvdzoKICAgICAgICAgKgogICAgICAgICAqICogW2Bwcm9qZWN0cy5yb2xlcy51bmRlbGV0ZSgpYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9wcm9qZWN0cy5yb2xlcy91bmRlbGV0ZSk6CiAgICAgICAgICogYHByb2plY3RzL3tQUk9KRUNUX0lEfS9yb2xlcy97Q1VTVE9NX1JPTEVfSUR9YC4gVGhpcyBtZXRob2QgdW5kZWxldGVzIG9ubHkgW2N1c3RvbQogICAgICAgICAqIHJvbGVzXSgvaWFtL2RvY3MvdW5kZXJzdGFuZGluZy1jdXN0b20tcm9sZXMpIHRoYXQgaGF2ZSBiZWVuIGNyZWF0ZWQgYXQgdGhlIHByb2plY3QgbGV2ZWwuCiAgICAgICAgICogRXhhbXBsZSByZXF1ZXN0IFVSTDoKICAgICAgICAgKiBgaHR0cHM6Ly9pYW0uZ29vZ2xlYXBpcy5jb20vdjEvcHJvamVjdHMve1BST0pFQ1RfSUR9L3JvbGVzL3tDVVNUT01fUk9MRV9JRH1gCiAgICAgICAgICoKICAgICAgICAgKiAqCiAgICAgICAgICogW2Bvcmdhbml6YXRpb25zLnJvbGVzLnVuZGVsZXRlKClgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL29yZ2FuaXphdGlvbnMucm9sZXMvdW5kZWxldGUpOgogICAgICAgICAqIGBvcmdhbml6YXRpb25zL3tPUkdBTklaQVRJT05fSUR9L3JvbGVzL3tDVVNUT01fUk9MRV9JRH1gLiBUaGlzIG1ldGhvZCB1bmRlbGV0ZXMgb25seQogICAgICAgICAqIFtjdXN0b20gcm9sZXNdKC9pYW0vZG9jcy91bmRlcnN0YW5kaW5nLWN1c3RvbS1yb2xlcykgdGhhdCBoYXZlIGJlZW4gY3JlYXRlZCBhdCB0aGUKICAgICAgICAgKiBvcmdhbml6YXRpb24gbGV2ZWwuIEV4YW1wbGUgcmVxdWVzdCBVUkw6CiAgICAgICAgICogYGh0dHBzOi8vaWFtLmdvb2dsZWFwaXMuY29tL3YxL29yZ2FuaXphdGlvbnMve09SR0FOSVpBVElPTl9JRH0vcm9sZXMve0NVU1RPTV9ST0xFX0lEfWAKICAgICAgICAgKgogICAgICAgICAqIE5vdGU6IFdpbGRjYXJkICgqKSB2YWx1ZXMgYXJlIGludmFsaWQ7IHlvdSBtdXN0IHNwZWNpZnkgYSBjb21wbGV0ZSBwcm9qZWN0IElEIG9yCiAgICAgICAgICogb3JnYW5pemF0aW9uIElELgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBVbmRlbGV0ZSBzZXROYW1lKGphdmEubGFuZy5TdHJpbmcgbmFtZSkgewogICAgICAgICAgaWYgKCFnZXRTdXBwcmVzc1BhdHRlcm5DaGVja3MoKSkgewogICAgICAgICAgICBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5QcmVjb25kaXRpb25zLmNoZWNrQXJndW1lbnQoTkFNRV9QQVRURVJOLm1hdGNoZXIobmFtZSkubWF0Y2hlcygpLAogICAgICAgICAgICAgICAgIlBhcmFtZXRlciBuYW1lIG11c3QgY29uZm9ybSB0byB0aGUgcGF0dGVybiAiICsKICAgICAgICAgICAgICAgICJecHJvamVjdHMvW14vXSsvcm9sZXMvW14vXSskIik7CiAgICAgICAgICB9CiAgICAgICAgICB0aGlzLm5hbWUgPSBuYW1lOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgVW5kZWxldGUgc2V0KFN0cmluZyBwYXJhbWV0ZXJOYW1lLCBPYmplY3QgdmFsdWUpIHsKICAgICAgICAgIHJldHVybiAoVW5kZWxldGUpIHN1cGVyLnNldChwYXJhbWV0ZXJOYW1lLCB2YWx1ZSk7CiAgICAgICAgfQogICAgICB9CgogICAgfQogICAgLyoqCiAgICAgKiBBbiBhY2Nlc3NvciBmb3IgY3JlYXRpbmcgcmVxdWVzdHMgZnJvbSB0aGUgU2VydmljZUFjY291bnRzIGNvbGxlY3Rpb24uCiAgICAgKgogICAgICogPHA+VGhlIHR5cGljYWwgdXNlIGlzOjwvcD4KICAgICAqIDxwcmU+CiAgICAgKiAgIHtAY29kZSBJYW0gaWFtID0gbmV3IElhbSguLi4pO30KICAgICAqICAge0Bjb2RlIElhbS5TZXJ2aWNlQWNjb3VudHMuTGlzdCByZXF1ZXN0ID0gaWFtLnNlcnZpY2VBY2NvdW50cygpLmxpc3QocGFyYW1ldGVycyAuLi4pfQogICAgICogPC9wcmU+CiAgICAgKgogICAgICogQHJldHVybiB0aGUgcmVzb3VyY2UgY29sbGVjdGlvbgogICAgICovCiAgICBwdWJsaWMgU2VydmljZUFjY291bnRzIHNlcnZpY2VBY2NvdW50cygpIHsKICAgICAgcmV0dXJuIG5ldyBTZXJ2aWNlQWNjb3VudHMoKTsKICAgIH0KCiAgICAvKioKICAgICAqIFRoZSAic2VydmljZUFjY291bnRzIiBjb2xsZWN0aW9uIG9mIG1ldGhvZHMuCiAgICAgKi8KICAgIHB1YmxpYyBjbGFzcyBTZXJ2aWNlQWNjb3VudHMgewoKICAgICAgLyoqCiAgICAgICAqIENyZWF0ZXMgYSBTZXJ2aWNlQWNjb3VudCBhbmQgcmV0dXJucyBpdC4KICAgICAgICoKICAgICAgICogQ3JlYXRlIGEgcmVxdWVzdCBmb3IgdGhlIG1ldGhvZCAic2VydmljZUFjY291bnRzLmNyZWF0ZSIuCiAgICAgICAqCiAgICAgICAqIFRoaXMgcmVxdWVzdCBob2xkcyB0aGUgcGFyYW1ldGVycyBuZWVkZWQgYnkgdGhlIGlhbSBzZXJ2ZXIuICBBZnRlciBzZXR0aW5nIGFueSBvcHRpb25hbAogICAgICAgKiBwYXJhbWV0ZXJzLCBjYWxsIHRoZSB7QGxpbmsgQ3JlYXRlI2V4ZWN1dGUoKX0gbWV0aG9kIHRvIGludm9rZSB0aGUgcmVtb3RlIG9wZXJhdGlvbi4KICAgICAgICoKICAgICAgICogQHBhcmFtIG5hbWUgUmVxdWlyZWQuIFRoZSByZXNvdXJjZSBuYW1lIG9mIHRoZSBwcm9qZWN0IGFzc29jaWF0ZWQgd2l0aCB0aGUgc2VydmljZQogICAgICBhY2NvdW50cywgc3VjaCBhcyBgcHJvamVjdHMKICAgICAgICogICAgICAgIC9teS1wcm9qZWN0LTEyM2AuCiAgICAgICAqIEBwYXJhbSBjb250ZW50IHRoZSB7QGxpbmsgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuaWFtLnYxLm1vZGVsLkNyZWF0ZVNlcnZpY2VBY2NvdW50UmVxdWVzdH0KICAgICAgICogQHJldHVybiB0aGUgcmVxdWVzdAogICAgICAgKi8KICAgICAgcHVibGljIENyZWF0ZSBjcmVhdGUoamF2YS5sYW5nLlN0cmluZyBuYW1lLCBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5pYW0udjEubW9kZWwuQ3JlYXRlU2VydmljZUFjY291bnRSZXF1ZXN0IGNvbnRlbnQpIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBDcmVhdGUgcmVzdWx0ID0gbmV3IENyZWF0ZShuYW1lLCBjb250ZW50KTsKICAgICAgICBpbml0aWFsaXplKHJlc3VsdCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHVibGljIGNsYXNzIENyZWF0ZSBleHRlbmRzIElhbVJlcXVlc3Q8Y29tLmdvb2dsZS5hcGkuc2VydmljZXMuaWFtLnYxLm1vZGVsLlNlcnZpY2VBY2NvdW50PiB7CgogICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBSRVNUX1BBVEggPSAidjEveytuYW1lfS9zZXJ2aWNlQWNjb3VudHMiOwoKICAgICAgICBwcml2YXRlIGZpbmFsIGphdmEudXRpbC5yZWdleC5QYXR0ZXJuIE5BTUVfUEFUVEVSTiA9CiAgICAgICAgICAgIGphdmEudXRpbC5yZWdleC5QYXR0ZXJuLmNvbXBpbGUoIl5wcm9qZWN0cy9bXi9dKyQiKTsKCiAgICAgICAgLyoqCiAgICAgICAgICogQ3JlYXRlcyBhIFNlcnZpY2VBY2NvdW50IGFuZCByZXR1cm5zIGl0LgogICAgICAgICAqCiAgICAgICAgICogQ3JlYXRlIGEgcmVxdWVzdCBmb3IgdGhlIG1ldGhvZCAic2VydmljZUFjY291bnRzLmNyZWF0ZSIuCiAgICAgICAgICoKICAgICAgICAgKiBUaGlzIHJlcXVlc3QgaG9sZHMgdGhlIHBhcmFtZXRlcnMgbmVlZGVkIGJ5IHRoZSB0aGUgaWFtIHNlcnZlci4gIEFmdGVyIHNldHRpbmcgYW55IG9wdGlvbmFsCiAgICAgICAgICogcGFyYW1ldGVycywgY2FsbCB0aGUge0BsaW5rIENyZWF0ZSNleGVjdXRlKCl9IG1ldGhvZCB0byBpbnZva2UgdGhlIHJlbW90ZSBvcGVyYXRpb24uIDxwPiB7QGxpbmsKICAgICAgICAgKiBDcmVhdGUjaW5pdGlhbGl6ZShjb20uZ29vZ2xlLmFwaS5jbGllbnQuZ29vZ2xlYXBpcy5zZXJ2aWNlcy5BYnN0cmFjdEdvb2dsZUNsaWVudFJlcXVlc3QpfSBtdXN0CiAgICAgICAgICogYmUgY2FsbGVkIHRvIGluaXRpYWxpemUgdGhpcyBpbnN0YW5jZSBpbW1lZGlhdGVseSBhZnRlciBpbnZva2luZyB0aGUgY29uc3RydWN0b3IuIDwvcD4KICAgICAgICAgKgogICAgICAgICAqIEBwYXJhbSBuYW1lIFJlcXVpcmVkLiBUaGUgcmVzb3VyY2UgbmFtZSBvZiB0aGUgcHJvamVjdCBhc3NvY2lhdGVkIHdpdGggdGhlIHNlcnZpY2UKICAgICAgYWNjb3VudHMsIHN1Y2ggYXMgYHByb2plY3RzCiAgICAgICAqICAgICAgICAvbXktcHJvamVjdC0xMjNgLgogICAgICAgICAqIEBwYXJhbSBjb250ZW50IHRoZSB7QGxpbmsgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuaWFtLnYxLm1vZGVsLkNyZWF0ZVNlcnZpY2VBY2NvdW50UmVxdWVzdH0KICAgICAgICAgKiBAc2luY2UgMS4xMwogICAgICAgICAqLwogICAgICAgIHByb3RlY3RlZCBDcmVhdGUoamF2YS5sYW5nLlN0cmluZyBuYW1lLCBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5pYW0udjEubW9kZWwuQ3JlYXRlU2VydmljZUFjY291bnRSZXF1ZXN0IGNvbnRlbnQpIHsKICAgICAgICAgIHN1cGVyKElhbS50aGlzLCAiUE9TVCIsIFJFU1RfUEFUSCwgY29udGVudCwgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuaWFtLnYxLm1vZGVsLlNlcnZpY2VBY2NvdW50LmNsYXNzKTsKICAgICAgICAgIHRoaXMubmFtZSA9IGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLlByZWNvbmRpdGlvbnMuY2hlY2tOb3ROdWxsKG5hbWUsICJSZXF1aXJlZCBwYXJhbWV0ZXIgbmFtZSBtdXN0IGJlIHNwZWNpZmllZC4iKTsKICAgICAgICAgIGlmICghZ2V0U3VwcHJlc3NQYXR0ZXJuQ2hlY2tzKCkpIHsKICAgICAgICAgICAgY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuUHJlY29uZGl0aW9ucy5jaGVja0FyZ3VtZW50KE5BTUVfUEFUVEVSTi5tYXRjaGVyKG5hbWUpLm1hdGNoZXMoKSwKICAgICAgICAgICAgICAgICJQYXJhbWV0ZXIgbmFtZSBtdXN0IGNvbmZvcm0gdG8gdGhlIHBhdHRlcm4gIiArCiAgICAgICAgICAgICAgICAiXnByb2plY3RzL1teL10rJCIpOwogICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIENyZWF0ZSBzZXQkWGdhZnYoamF2YS5sYW5nLlN0cmluZyAkWGdhZnYpIHsKICAgICAgICAgIHJldHVybiAoQ3JlYXRlKSBzdXBlci5zZXQkWGdhZnYoJFhnYWZ2KTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBDcmVhdGUgc2V0QWNjZXNzVG9rZW4oamF2YS5sYW5nLlN0cmluZyBhY2Nlc3NUb2tlbikgewogICAgICAgICAgcmV0dXJuIChDcmVhdGUpIHN1cGVyLnNldEFjY2Vzc1Rva2VuKGFjY2Vzc1Rva2VuKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBDcmVhdGUgc2V0QWx0KGphdmEubGFuZy5TdHJpbmcgYWx0KSB7CiAgICAgICAgICByZXR1cm4gKENyZWF0ZSkgc3VwZXIuc2V0QWx0KGFsdCk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQ3JlYXRlIHNldENhbGxiYWNrKGphdmEubGFuZy5TdHJpbmcgY2FsbGJhY2spIHsKICAgICAgICAgIHJldHVybiAoQ3JlYXRlKSBzdXBlci5zZXRDYWxsYmFjayhjYWxsYmFjayk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQ3JlYXRlIHNldEZpZWxkcyhqYXZhLmxhbmcuU3RyaW5nIGZpZWxkcykgewogICAgICAgICAgcmV0dXJuIChDcmVhdGUpIHN1cGVyLnNldEZpZWxkcyhmaWVsZHMpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIENyZWF0ZSBzZXRLZXkoamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICAgIHJldHVybiAoQ3JlYXRlKSBzdXBlci5zZXRLZXkoa2V5KTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBDcmVhdGUgc2V0T2F1dGhUb2tlbihqYXZhLmxhbmcuU3RyaW5nIG9hdXRoVG9rZW4pIHsKICAgICAgICAgIHJldHVybiAoQ3JlYXRlKSBzdXBlci5zZXRPYXV0aFRva2VuKG9hdXRoVG9rZW4pOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIENyZWF0ZSBzZXRQcmV0dHlQcmludChqYXZhLmxhbmcuQm9vbGVhbiBwcmV0dHlQcmludCkgewogICAgICAgICAgcmV0dXJuIChDcmVhdGUpIHN1cGVyLnNldFByZXR0eVByaW50KHByZXR0eVByaW50KTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBDcmVhdGUgc2V0UXVvdGFVc2VyKGphdmEubGFuZy5TdHJpbmcgcXVvdGFVc2VyKSB7CiAgICAgICAgICByZXR1cm4gKENyZWF0ZSkgc3VwZXIuc2V0UXVvdGFVc2VyKHF1b3RhVXNlcik7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgQ3JlYXRlIHNldFVwbG9hZFR5cGUoamF2YS5sYW5nLlN0cmluZyB1cGxvYWRUeXBlKSB7CiAgICAgICAgICByZXR1cm4gKENyZWF0ZSkgc3VwZXIuc2V0VXBsb2FkVHlwZSh1cGxvYWRUeXBlKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBDcmVhdGUgc2V0VXBsb2FkUHJvdG9jb2woamF2YS5sYW5nLlN0cmluZyB1cGxvYWRQcm90b2NvbCkgewogICAgICAgICAgcmV0dXJuIChDcmVhdGUpIHN1cGVyLnNldFVwbG9hZFByb3RvY29sKHVwbG9hZFByb3RvY29sKTsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIFJlcXVpcmVkLiBUaGUgcmVzb3VyY2UgbmFtZSBvZiB0aGUgcHJvamVjdCBhc3NvY2lhdGVkIHdpdGggdGhlIHNlcnZpY2UgYWNjb3VudHMsIHN1Y2ggYXMKICAgICAgICAgKiBgcHJvamVjdHMvbXktcHJvamVjdC0xMjNgLgogICAgICAgICAqLwogICAgICAgIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICAgICAgICBwcml2YXRlIGphdmEubGFuZy5TdHJpbmcgbmFtZTsKCiAgICAgICAgLyoqIFJlcXVpcmVkLiBUaGUgcmVzb3VyY2UgbmFtZSBvZiB0aGUgcHJvamVjdCBhc3NvY2lhdGVkIHdpdGggdGhlIHNlcnZpY2UgYWNjb3VudHMsIHN1Y2ggYXMgYHByb2plY3RzCiAgICAgICAvbXktcHJvamVjdC0xMjNgLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldE5hbWUoKSB7CiAgICAgICAgICByZXR1cm4gbmFtZTsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIFJlcXVpcmVkLiBUaGUgcmVzb3VyY2UgbmFtZSBvZiB0aGUgcHJvamVjdCBhc3NvY2lhdGVkIHdpdGggdGhlIHNlcnZpY2UgYWNjb3VudHMsIHN1Y2ggYXMKICAgICAgICAgKiBgcHJvamVjdHMvbXktcHJvamVjdC0xMjNgLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBDcmVhdGUgc2V0TmFtZShqYXZhLmxhbmcuU3RyaW5nIG5hbWUpIHsKICAgICAgICAgIGlmICghZ2V0U3VwcHJlc3NQYXR0ZXJuQ2hlY2tzKCkpIHsKICAgICAgICAgICAgY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuUHJlY29uZGl0aW9ucy5jaGVja0FyZ3VtZW50KE5BTUVfUEFUVEVSTi5tYXRjaGVyKG5hbWUpLm1hdGNoZXMoKSwKICAgICAgICAgICAgICAgICJQYXJhbWV0ZXIgbmFtZSBtdXN0IGNvbmZvcm0gdG8gdGhlIHBhdHRlcm4gIiArCiAgICAgICAgICAgICAgICAiXnByb2plY3RzL1teL10rJCIpOwogICAgICAgICAgfQogICAgICAgICAgdGhpcy5uYW1lID0gbmFtZTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIENyZWF0ZSBzZXQoU3RyaW5nIHBhcmFtZXRlck5hbWUsIE9iamVjdCB2YWx1ZSkgewogICAgICAgICAgcmV0dXJuIChDcmVhdGUpIHN1cGVyLnNldChwYXJhbWV0ZXJOYW1lLCB2YWx1ZSk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBEZWxldGVzIGEgU2VydmljZUFjY291bnQuCiAgICAgICAqCiAgICAgICAqIENyZWF0ZSBhIHJlcXVlc3QgZm9yIHRoZSBtZXRob2QgInNlcnZpY2VBY2NvdW50cy5kZWxldGUiLgogICAgICAgKgogICAgICAgKiBUaGlzIHJlcXVlc3QgaG9sZHMgdGhlIHBhcmFtZXRlcnMgbmVlZGVkIGJ5IHRoZSBpYW0gc2VydmVyLiAgQWZ0ZXIgc2V0dGluZyBhbnkgb3B0aW9uYWwKICAgICAgICogcGFyYW1ldGVycywgY2FsbCB0aGUge0BsaW5rIERlbGV0ZSNleGVjdXRlKCl9IG1ldGhvZCB0byBpbnZva2UgdGhlIHJlbW90ZSBvcGVyYXRpb24uCiAgICAgICAqCiAgICAgICAqIEBwYXJhbSBuYW1lIFJlcXVpcmVkLiBUaGUgcmVzb3VyY2UgbmFtZSBvZiB0aGUgc2VydmljZSBhY2NvdW50IGluIHRoZSBmb2xsb3dpbmcgZm9ybWF0OgogICAgICAgKiAgICAgICAgYHByb2plY3RzL3tQUk9KRUNUX0lEfS9zZXJ2aWNlQWNjb3VudHMve0FDQ09VTlR9YC4KICAgICAgVXNpbmcgYC1gIGFzIGEgd2lsZGNhcmQgZm9yIHRoZQogICAgICAgKiAgICAgICAgYFBST0pFQ1RfSURgIHdpbGwgaW5mZXIgdGhlIHByb2plY3QgZnJvbQogICAgICB0aGUgYWNjb3VudC4gVGhlIGBBQ0NPVU5UYCB2YWx1ZSBjYW4gYmUgdGhlCiAgICAgICAqICAgICAgICBgZW1haWxgIGFkZHJlc3Mgb3IgdGhlCiAgICAgIGB1bmlxdWVfaWRgIG9mIHRoZSBzZXJ2aWNlIGFjY291bnQuCiAgICAgICAqIEByZXR1cm4gdGhlIHJlcXVlc3QKICAgICAgICovCiAgICAgIHB1YmxpYyBEZWxldGUgZGVsZXRlKGphdmEubGFuZy5TdHJpbmcgbmFtZSkgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIERlbGV0ZSByZXN1bHQgPSBuZXcgRGVsZXRlKG5hbWUpOwogICAgICAgIGluaXRpYWxpemUocmVzdWx0KTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBwdWJsaWMgY2xhc3MgRGVsZXRlIGV4dGVuZHMgSWFtUmVxdWVzdDxjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5pYW0udjEubW9kZWwuRW1wdHk+IHsKCiAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFJFU1RfUEFUSCA9ICJ2MS97K25hbWV9IjsKCiAgICAgICAgcHJpdmF0ZSBmaW5hbCBqYXZhLnV0aWwucmVnZXguUGF0dGVybiBOQU1FX1BBVFRFUk4gPQogICAgICAgICAgICBqYXZhLnV0aWwucmVnZXguUGF0dGVybi5jb21waWxlKCJecHJvamVjdHMvW14vXSsvc2VydmljZUFjY291bnRzL1teL10rJCIpOwoKICAgICAgICAvKioKICAgICAgICAgKiBEZWxldGVzIGEgU2VydmljZUFjY291bnQuCiAgICAgICAgICoKICAgICAgICAgKiBDcmVhdGUgYSByZXF1ZXN0IGZvciB0aGUgbWV0aG9kICJzZXJ2aWNlQWNjb3VudHMuZGVsZXRlIi4KICAgICAgICAgKgogICAgICAgICAqIFRoaXMgcmVxdWVzdCBob2xkcyB0aGUgcGFyYW1ldGVycyBuZWVkZWQgYnkgdGhlIHRoZSBpYW0gc2VydmVyLiAgQWZ0ZXIgc2V0dGluZyBhbnkgb3B0aW9uYWwKICAgICAgICAgKiBwYXJhbWV0ZXJzLCBjYWxsIHRoZSB7QGxpbmsgRGVsZXRlI2V4ZWN1dGUoKX0gbWV0aG9kIHRvIGludm9rZSB0aGUgcmVtb3RlIG9wZXJhdGlvbi4gPHA+IHtAbGluawogICAgICAgICAqIERlbGV0ZSNpbml0aWFsaXplKGNvbS5nb29nbGUuYXBpLmNsaWVudC5nb29nbGVhcGlzLnNlcnZpY2VzLkFic3RyYWN0R29vZ2xlQ2xpZW50UmVxdWVzdCl9IG11c3QKICAgICAgICAgKiBiZSBjYWxsZWQgdG8gaW5pdGlhbGl6ZSB0aGlzIGluc3RhbmNlIGltbWVkaWF0ZWx5IGFmdGVyIGludm9raW5nIHRoZSBjb25zdHJ1Y3Rvci4gPC9wPgogICAgICAgICAqCiAgICAgICAgICogQHBhcmFtIG5hbWUgUmVxdWlyZWQuIFRoZSByZXNvdXJjZSBuYW1lIG9mIHRoZSBzZXJ2aWNlIGFjY291bnQgaW4gdGhlIGZvbGxvd2luZyBmb3JtYXQ6CiAgICAgICAqICAgICAgICBgcHJvamVjdHMve1BST0pFQ1RfSUR9L3NlcnZpY2VBY2NvdW50cy97QUNDT1VOVH1gLgogICAgICBVc2luZyBgLWAgYXMgYSB3aWxkY2FyZCBmb3IgdGhlCiAgICAgICAqICAgICAgICBgUFJPSkVDVF9JRGAgd2lsbCBpbmZlciB0aGUgcHJvamVjdCBmcm9tCiAgICAgIHRoZSBhY2NvdW50LiBUaGUgYEFDQ09VTlRgIHZhbHVlIGNhbiBiZSB0aGUKICAgICAgICogICAgICAgIGBlbWFpbGAgYWRkcmVzcyBvciB0aGUKICAgICAgYHVuaXF1ZV9pZGAgb2YgdGhlIHNlcnZpY2UgYWNjb3VudC4KICAgICAgICAgKiBAc2luY2UgMS4xMwogICAgICAgICAqLwogICAgICAgIHByb3RlY3RlZCBEZWxldGUoamF2YS5sYW5nLlN0cmluZyBuYW1lKSB7CiAgICAgICAgICBzdXBlcihJYW0udGhpcywgIkRFTEVURSIsIFJFU1RfUEFUSCwgbnVsbCwgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuaWFtLnYxLm1vZGVsLkVtcHR5LmNsYXNzKTsKICAgICAgICAgIHRoaXMubmFtZSA9IGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLlByZWNvbmRpdGlvbnMuY2hlY2tOb3ROdWxsKG5hbWUsICJSZXF1aXJlZCBwYXJhbWV0ZXIgbmFtZSBtdXN0IGJlIHNwZWNpZmllZC4iKTsKICAgICAgICAgIGlmICghZ2V0U3VwcHJlc3NQYXR0ZXJuQ2hlY2tzKCkpIHsKICAgICAgICAgICAgY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuUHJlY29uZGl0aW9ucy5jaGVja0FyZ3VtZW50KE5BTUVfUEFUVEVSTi5tYXRjaGVyKG5hbWUpLm1hdGNoZXMoKSwKICAgICAgICAgICAgICAgICJQYXJhbWV0ZXIgbmFtZSBtdXN0IGNvbmZvcm0gdG8gdGhlIHBhdHRlcm4gIiArCiAgICAgICAgICAgICAgICAiXnByb2plY3RzL1teL10rL3NlcnZpY2VBY2NvdW50cy9bXi9dKyQiKTsKICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBEZWxldGUgc2V0JFhnYWZ2KGphdmEubGFuZy5TdHJpbmcgJFhnYWZ2KSB7CiAgICAgICAgICByZXR1cm4gKERlbGV0ZSkgc3VwZXIuc2V0JFhnYWZ2KCRYZ2Fmdik7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgRGVsZXRlIHNldEFjY2Vzc1Rva2VuKGphdmEubGFuZy5TdHJpbmcgYWNjZXNzVG9rZW4pIHsKICAgICAgICAgIHJldHVybiAoRGVsZXRlKSBzdXBlci5zZXRBY2Nlc3NUb2tlbihhY2Nlc3NUb2tlbik7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgRGVsZXRlIHNldEFsdChqYXZhLmxhbmcuU3RyaW5nIGFsdCkgewogICAgICAgICAgcmV0dXJuIChEZWxldGUpIHN1cGVyLnNldEFsdChhbHQpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIERlbGV0ZSBzZXRDYWxsYmFjayhqYXZhLmxhbmcuU3RyaW5nIGNhbGxiYWNrKSB7CiAgICAgICAgICByZXR1cm4gKERlbGV0ZSkgc3VwZXIuc2V0Q2FsbGJhY2soY2FsbGJhY2spOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIERlbGV0ZSBzZXRGaWVsZHMoamF2YS5sYW5nLlN0cmluZyBmaWVsZHMpIHsKICAgICAgICAgIHJldHVybiAoRGVsZXRlKSBzdXBlci5zZXRGaWVsZHMoZmllbGRzKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBEZWxldGUgc2V0S2V5KGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgICByZXR1cm4gKERlbGV0ZSkgc3VwZXIuc2V0S2V5KGtleSk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgRGVsZXRlIHNldE9hdXRoVG9rZW4oamF2YS5sYW5nLlN0cmluZyBvYXV0aFRva2VuKSB7CiAgICAgICAgICByZXR1cm4gKERlbGV0ZSkgc3VwZXIuc2V0T2F1dGhUb2tlbihvYXV0aFRva2VuKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBEZWxldGUgc2V0UHJldHR5UHJpbnQoamF2YS5sYW5nLkJvb2xlYW4gcHJldHR5UHJpbnQpIHsKICAgICAgICAgIHJldHVybiAoRGVsZXRlKSBzdXBlci5zZXRQcmV0dHlQcmludChwcmV0dHlQcmludCk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgRGVsZXRlIHNldFF1b3RhVXNlcihqYXZhLmxhbmcuU3RyaW5nIHF1b3RhVXNlcikgewogICAgICAgICAgcmV0dXJuIChEZWxldGUpIHN1cGVyLnNldFF1b3RhVXNlcihxdW90YVVzZXIpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIERlbGV0ZSBzZXRVcGxvYWRUeXBlKGphdmEubGFuZy5TdHJpbmcgdXBsb2FkVHlwZSkgewogICAgICAgICAgcmV0dXJuIChEZWxldGUpIHN1cGVyLnNldFVwbG9hZFR5cGUodXBsb2FkVHlwZSk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgRGVsZXRlIHNldFVwbG9hZFByb3RvY29sKGphdmEubGFuZy5TdHJpbmcgdXBsb2FkUHJvdG9jb2wpIHsKICAgICAgICAgIHJldHVybiAoRGVsZXRlKSBzdXBlci5zZXRVcGxvYWRQcm90b2NvbCh1cGxvYWRQcm90b2NvbCk7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiBSZXF1aXJlZC4gVGhlIHJlc291cmNlIG5hbWUgb2YgdGhlIHNlcnZpY2UgYWNjb3VudCBpbiB0aGUgZm9sbG93aW5nIGZvcm1hdDoKICAgICAgICAgKiBgcHJvamVjdHMve1BST0pFQ1RfSUR9L3NlcnZpY2VBY2NvdW50cy97QUNDT1VOVH1gLiBVc2luZyBgLWAgYXMgYSB3aWxkY2FyZCBmb3IgdGhlCiAgICAgICAgICogYFBST0pFQ1RfSURgIHdpbGwgaW5mZXIgdGhlIHByb2plY3QgZnJvbSB0aGUgYWNjb3VudC4gVGhlIGBBQ0NPVU5UYCB2YWx1ZSBjYW4gYmUgdGhlCiAgICAgICAgICogYGVtYWlsYCBhZGRyZXNzIG9yIHRoZSBgdW5pcXVlX2lkYCBvZiB0aGUgc2VydmljZSBhY2NvdW50LgogICAgICAgICAqLwogICAgICAgIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICAgICAgICBwcml2YXRlIGphdmEubGFuZy5TdHJpbmcgbmFtZTsKCiAgICAgICAgLyoqIFJlcXVpcmVkLiBUaGUgcmVzb3VyY2UgbmFtZSBvZiB0aGUgc2VydmljZSBhY2NvdW50IGluIHRoZSBmb2xsb3dpbmcgZm9ybWF0OgogICAgICAgYHByb2plY3RzL3tQUk9KRUNUX0lEfS9zZXJ2aWNlQWNjb3VudHMve0FDQ09VTlR9YC4gVXNpbmcgYC1gIGFzIGEgd2lsZGNhcmQgZm9yIHRoZSBgUFJPSkVDVF9JRGAKICAgICAgIHdpbGwgaW5mZXIgdGhlIHByb2plY3QgZnJvbSB0aGUgYWNjb3VudC4gVGhlIGBBQ0NPVU5UYCB2YWx1ZSBjYW4gYmUgdGhlIGBlbWFpbGAgYWRkcmVzcyBvciB0aGUKICAgICAgIGB1bmlxdWVfaWRgIG9mIHRoZSBzZXJ2aWNlIGFjY291bnQuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TmFtZSgpIHsKICAgICAgICAgIHJldHVybiBuYW1lOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogUmVxdWlyZWQuIFRoZSByZXNvdXJjZSBuYW1lIG9mIHRoZSBzZXJ2aWNlIGFjY291bnQgaW4gdGhlIGZvbGxvd2luZyBmb3JtYXQ6CiAgICAgICAgICogYHByb2plY3RzL3tQUk9KRUNUX0lEfS9zZXJ2aWNlQWNjb3VudHMve0FDQ09VTlR9YC4gVXNpbmcgYC1gIGFzIGEgd2lsZGNhcmQgZm9yIHRoZQogICAgICAgICAqIGBQUk9KRUNUX0lEYCB3aWxsIGluZmVyIHRoZSBwcm9qZWN0IGZyb20gdGhlIGFjY291bnQuIFRoZSBgQUNDT1VOVGAgdmFsdWUgY2FuIGJlIHRoZQogICAgICAgICAqIGBlbWFpbGAgYWRkcmVzcyBvciB0aGUgYHVuaXF1ZV9pZGAgb2YgdGhlIHNlcnZpY2UgYWNjb3VudC4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgRGVsZXRlIHNldE5hbWUoamF2YS5sYW5nLlN0cmluZyBuYW1lKSB7CiAgICAgICAgICBpZiAoIWdldFN1cHByZXNzUGF0dGVybkNoZWNrcygpKSB7CiAgICAgICAgICAgIGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLlByZWNvbmRpdGlvbnMuY2hlY2tBcmd1bWVudChOQU1FX1BBVFRFUk4ubWF0Y2hlcihuYW1lKS5tYXRjaGVzKCksCiAgICAgICAgICAgICAgICAiUGFyYW1ldGVyIG5hbWUgbXVzdCBjb25mb3JtIHRvIHRoZSBwYXR0ZXJuICIgKwogICAgICAgICAgICAgICAgIl5wcm9qZWN0cy9bXi9dKy9zZXJ2aWNlQWNjb3VudHMvW14vXSskIik7CiAgICAgICAgICB9CiAgICAgICAgICB0aGlzLm5hbWUgPSBuYW1lOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgRGVsZXRlIHNldChTdHJpbmcgcGFyYW1ldGVyTmFtZSwgT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgICByZXR1cm4gKERlbGV0ZSkgc3VwZXIuc2V0KHBhcmFtZXRlck5hbWUsIHZhbHVlKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIERpc2FibGVTZXJ2aWNlQWNjb3VudCBpcyBjdXJyZW50bHkgaW4gdGhlIGFscGhhIGxhdW5jaCBzdGFnZS4KICAgICAgICoKICAgICAgICogRGlzYWJsZXMgYSBTZXJ2aWNlQWNjb3VudCwgd2hpY2ggaW1tZWRpYXRlbHkgcHJldmVudHMgdGhlIHNlcnZpY2UgYWNjb3VudCBmcm9tIGF1dGhlbnRpY2F0aW5nIGFuZAogICAgICAgKiBnYWluaW5nIGFjY2VzcyB0byBBUElzLgogICAgICAgKgogICAgICAgKiBEaXNhYmxlZCBzZXJ2aWNlIGFjY291bnRzIGNhbiBiZSBzYWZlbHkgcmVzdG9yZWQgYnkgdXNpbmcgRW5hYmxlU2VydmljZUFjY291bnQgYXQgYW55IHBvaW50LgogICAgICAgKiBEZWxldGVkIHNlcnZpY2UgYWNjb3VudHMgY2Fubm90IGJlIHJlc3RvcmVkIHVzaW5nIHRoaXMgbWV0aG9kLgogICAgICAgKgogICAgICAgKiBEaXNhYmxpbmcgYSBzZXJ2aWNlIGFjY291bnQgdGhhdCBpcyBib3VuZCB0byBWTXMsIEFwcHMsIEZ1bmN0aW9ucywgb3Igb3RoZXIgam9icyB3aWxsIGNhdXNlIHRob3NlCiAgICAgICAqIGpvYnMgdG8gbG9zZSBhY2Nlc3MgdG8gcmVzb3VyY2VzIGlmIHRoZXkgYXJlIHVzaW5nIHRoZSBkaXNhYmxlZCBzZXJ2aWNlIGFjY291bnQuCiAgICAgICAqCiAgICAgICAqIFRvIGltcHJvdmUgcmVsaWFiaWxpdHkgb2YgeW91ciBzZXJ2aWNlcyBhbmQgYXZvaWQgdW5leHBlY3RlZCBvdXRhZ2VzLCBpdCBpcyByZWNvbW1lbmRlZCB0byBmaXJzdAogICAgICAgKiBkaXNhYmxlIGEgc2VydmljZSBhY2NvdW50IHJhdGhlciB0aGFuIGRlbGV0ZSBpdC4gQWZ0ZXIgZGlzYWJsaW5nIHRoZSBzZXJ2aWNlIGFjY291bnQsIHdhaXQgYXQKICAgICAgICogbGVhc3QgMjQgaG91cnMgdG8gdmVyaWZ5IHRoZXJlIGFyZSBubyB1bmludGVuZGVkIGNvbnNlcXVlbmNlcywgYW5kIHRoZW4gZGVsZXRlIHRoZSBzZXJ2aWNlCiAgICAgICAqIGFjY291bnQuCiAgICAgICAqCiAgICAgICAqIENyZWF0ZSBhIHJlcXVlc3QgZm9yIHRoZSBtZXRob2QgInNlcnZpY2VBY2NvdW50cy5kaXNhYmxlIi4KICAgICAgICoKICAgICAgICogVGhpcyByZXF1ZXN0IGhvbGRzIHRoZSBwYXJhbWV0ZXJzIG5lZWRlZCBieSB0aGUgaWFtIHNlcnZlci4gIEFmdGVyIHNldHRpbmcgYW55IG9wdGlvbmFsCiAgICAgICAqIHBhcmFtZXRlcnMsIGNhbGwgdGhlIHtAbGluayBEaXNhYmxlI2V4ZWN1dGUoKX0gbWV0aG9kIHRvIGludm9rZSB0aGUgcmVtb3RlIG9wZXJhdGlvbi4KICAgICAgICoKICAgICAgICogQHBhcmFtIG5hbWUgVGhlIHJlc291cmNlIG5hbWUgb2YgdGhlIHNlcnZpY2UgYWNjb3VudCBpbiB0aGUgZm9sbG93aW5nIGZvcm1hdDoKICAgICAgICogICAgICAgIGBwcm9qZWN0cy97UFJPSkVDVF9JRH0vc2VydmljZUFjY291bnRzL3tBQ0NPVU5UfWAuCiAgICAgIFVzaW5nIGAtYCBhcyBhIHdpbGRjYXJkIGZvciB0aGUKICAgICAgICogICAgICAgIGBQUk9KRUNUX0lEYCB3aWxsIGluZmVyIHRoZSBwcm9qZWN0IGZyb20KICAgICAgdGhlIGFjY291bnQuIFRoZSBgQUNDT1VOVGAgdmFsdWUgY2FuIGJlIHRoZQogICAgICAgKiAgICAgICAgYGVtYWlsYCBhZGRyZXNzIG9yIHRoZQogICAgICBgdW5pcXVlX2lkYCBvZiB0aGUgc2VydmljZSBhY2NvdW50LgogICAgICAgKiBAcGFyYW0gY29udGVudCB0aGUge0BsaW5rIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmlhbS52MS5tb2RlbC5EaXNhYmxlU2VydmljZUFjY291bnRSZXF1ZXN0fQogICAgICAgKiBAcmV0dXJuIHRoZSByZXF1ZXN0CiAgICAgICAqLwogICAgICBwdWJsaWMgRGlzYWJsZSBkaXNhYmxlKGphdmEubGFuZy5TdHJpbmcgbmFtZSwgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuaWFtLnYxLm1vZGVsLkRpc2FibGVTZXJ2aWNlQWNjb3VudFJlcXVlc3QgY29udGVudCkgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIERpc2FibGUgcmVzdWx0ID0gbmV3IERpc2FibGUobmFtZSwgY29udGVudCk7CiAgICAgICAgaW5pdGlhbGl6ZShyZXN1bHQpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBjbGFzcyBEaXNhYmxlIGV4dGVuZHMgSWFtUmVxdWVzdDxjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5pYW0udjEubW9kZWwuRW1wdHk+IHsKCiAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFJFU1RfUEFUSCA9ICJ2MS97K25hbWV9OmRpc2FibGUiOwoKICAgICAgICBwcml2YXRlIGZpbmFsIGphdmEudXRpbC5yZWdleC5QYXR0ZXJuIE5BTUVfUEFUVEVSTiA9CiAgICAgICAgICAgIGphdmEudXRpbC5yZWdleC5QYXR0ZXJuLmNvbXBpbGUoIl5wcm9qZWN0cy9bXi9dKy9zZXJ2aWNlQWNjb3VudHMvW14vXSskIik7CgogICAgICAgIC8qKgogICAgICAgICAqIERpc2FibGVTZXJ2aWNlQWNjb3VudCBpcyBjdXJyZW50bHkgaW4gdGhlIGFscGhhIGxhdW5jaCBzdGFnZS4KICAgICAgICAgKgogICAgICAgICAqIERpc2FibGVzIGEgU2VydmljZUFjY291bnQsIHdoaWNoIGltbWVkaWF0ZWx5IHByZXZlbnRzIHRoZSBzZXJ2aWNlIGFjY291bnQgZnJvbSBhdXRoZW50aWNhdGluZwogICAgICAgICAqIGFuZCBnYWluaW5nIGFjY2VzcyB0byBBUElzLgogICAgICAgICAqCiAgICAgICAgICogRGlzYWJsZWQgc2VydmljZSBhY2NvdW50cyBjYW4gYmUgc2FmZWx5IHJlc3RvcmVkIGJ5IHVzaW5nIEVuYWJsZVNlcnZpY2VBY2NvdW50IGF0IGFueSBwb2ludC4KICAgICAgICAgKiBEZWxldGVkIHNlcnZpY2UgYWNjb3VudHMgY2Fubm90IGJlIHJlc3RvcmVkIHVzaW5nIHRoaXMgbWV0aG9kLgogICAgICAgICAqCiAgICAgICAgICogRGlzYWJsaW5nIGEgc2VydmljZSBhY2NvdW50IHRoYXQgaXMgYm91bmQgdG8gVk1zLCBBcHBzLCBGdW5jdGlvbnMsIG9yIG90aGVyIGpvYnMgd2lsbCBjYXVzZQogICAgICAgICAqIHRob3NlIGpvYnMgdG8gbG9zZSBhY2Nlc3MgdG8gcmVzb3VyY2VzIGlmIHRoZXkgYXJlIHVzaW5nIHRoZSBkaXNhYmxlZCBzZXJ2aWNlIGFjY291bnQuCiAgICAgICAgICoKICAgICAgICAgKiBUbyBpbXByb3ZlIHJlbGlhYmlsaXR5IG9mIHlvdXIgc2VydmljZXMgYW5kIGF2b2lkIHVuZXhwZWN0ZWQgb3V0YWdlcywgaXQgaXMgcmVjb21tZW5kZWQgdG8KICAgICAgICAgKiBmaXJzdCBkaXNhYmxlIGEgc2VydmljZSBhY2NvdW50IHJhdGhlciB0aGFuIGRlbGV0ZSBpdC4gQWZ0ZXIgZGlzYWJsaW5nIHRoZSBzZXJ2aWNlIGFjY291bnQsCiAgICAgICAgICogd2FpdCBhdCBsZWFzdCAyNCBob3VycyB0byB2ZXJpZnkgdGhlcmUgYXJlIG5vIHVuaW50ZW5kZWQgY29uc2VxdWVuY2VzLCBhbmQgdGhlbiBkZWxldGUgdGhlCiAgICAgICAgICogc2VydmljZSBhY2NvdW50LgogICAgICAgICAqCiAgICAgICAgICogQ3JlYXRlIGEgcmVxdWVzdCBmb3IgdGhlIG1ldGhvZCAic2VydmljZUFjY291bnRzLmRpc2FibGUiLgogICAgICAgICAqCiAgICAgICAgICogVGhpcyByZXF1ZXN0IGhvbGRzIHRoZSBwYXJhbWV0ZXJzIG5lZWRlZCBieSB0aGUgdGhlIGlhbSBzZXJ2ZXIuICBBZnRlciBzZXR0aW5nIGFueSBvcHRpb25hbAogICAgICAgICAqIHBhcmFtZXRlcnMsIGNhbGwgdGhlIHtAbGluayBEaXNhYmxlI2V4ZWN1dGUoKX0gbWV0aG9kIHRvIGludm9rZSB0aGUgcmVtb3RlIG9wZXJhdGlvbi4gPHA+CiAgICAgICAgICoge0BsaW5rCiAgICAgICAgICogRGlzYWJsZSNpbml0aWFsaXplKGNvbS5nb29nbGUuYXBpLmNsaWVudC5nb29nbGVhcGlzLnNlcnZpY2VzLkFic3RyYWN0R29vZ2xlQ2xpZW50UmVxdWVzdCl9IG11c3QKICAgICAgICAgKiBiZSBjYWxsZWQgdG8gaW5pdGlhbGl6ZSB0aGlzIGluc3RhbmNlIGltbWVkaWF0ZWx5IGFmdGVyIGludm9raW5nIHRoZSBjb25zdHJ1Y3Rvci4gPC9wPgogICAgICAgICAqCiAgICAgICAgICogQHBhcmFtIG5hbWUgVGhlIHJlc291cmNlIG5hbWUgb2YgdGhlIHNlcnZpY2UgYWNjb3VudCBpbiB0aGUgZm9sbG93aW5nIGZvcm1hdDoKICAgICAgICogICAgICAgIGBwcm9qZWN0cy97UFJPSkVDVF9JRH0vc2VydmljZUFjY291bnRzL3tBQ0NPVU5UfWAuCiAgICAgIFVzaW5nIGAtYCBhcyBhIHdpbGRjYXJkIGZvciB0aGUKICAgICAgICogICAgICAgIGBQUk9KRUNUX0lEYCB3aWxsIGluZmVyIHRoZSBwcm9qZWN0IGZyb20KICAgICAgdGhlIGFjY291bnQuIFRoZSBgQUNDT1VOVGAgdmFsdWUgY2FuIGJlIHRoZQogICAgICAgKiAgICAgICAgYGVtYWlsYCBhZGRyZXNzIG9yIHRoZQogICAgICBgdW5pcXVlX2lkYCBvZiB0aGUgc2VydmljZSBhY2NvdW50LgogICAgICAgICAqIEBwYXJhbSBjb250ZW50IHRoZSB7QGxpbmsgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuaWFtLnYxLm1vZGVsLkRpc2FibGVTZXJ2aWNlQWNjb3VudFJlcXVlc3R9CiAgICAgICAgICogQHNpbmNlIDEuMTMKICAgICAgICAgKi8KICAgICAgICBwcm90ZWN0ZWQgRGlzYWJsZShqYXZhLmxhbmcuU3RyaW5nIG5hbWUsIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmlhbS52MS5tb2RlbC5EaXNhYmxlU2VydmljZUFjY291bnRSZXF1ZXN0IGNvbnRlbnQpIHsKICAgICAgICAgIHN1cGVyKElhbS50aGlzLCAiUE9TVCIsIFJFU1RfUEFUSCwgY29udGVudCwgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuaWFtLnYxLm1vZGVsLkVtcHR5LmNsYXNzKTsKICAgICAgICAgIHRoaXMubmFtZSA9IGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLlByZWNvbmRpdGlvbnMuY2hlY2tOb3ROdWxsKG5hbWUsICJSZXF1aXJlZCBwYXJhbWV0ZXIgbmFtZSBtdXN0IGJlIHNwZWNpZmllZC4iKTsKICAgICAgICAgIGlmICghZ2V0U3VwcHJlc3NQYXR0ZXJuQ2hlY2tzKCkpIHsKICAgICAgICAgICAgY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuUHJlY29uZGl0aW9ucy5jaGVja0FyZ3VtZW50KE5BTUVfUEFUVEVSTi5tYXRjaGVyKG5hbWUpLm1hdGNoZXMoKSwKICAgICAgICAgICAgICAgICJQYXJhbWV0ZXIgbmFtZSBtdXN0IGNvbmZvcm0gdG8gdGhlIHBhdHRlcm4gIiArCiAgICAgICAgICAgICAgICAiXnByb2plY3RzL1teL10rL3NlcnZpY2VBY2NvdW50cy9bXi9dKyQiKTsKICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBEaXNhYmxlIHNldCRYZ2FmdihqYXZhLmxhbmcuU3RyaW5nICRYZ2FmdikgewogICAgICAgICAgcmV0dXJuIChEaXNhYmxlKSBzdXBlci5zZXQkWGdhZnYoJFhnYWZ2KTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBEaXNhYmxlIHNldEFjY2Vzc1Rva2VuKGphdmEubGFuZy5TdHJpbmcgYWNjZXNzVG9rZW4pIHsKICAgICAgICAgIHJldHVybiAoRGlzYWJsZSkgc3VwZXIuc2V0QWNjZXNzVG9rZW4oYWNjZXNzVG9rZW4pOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIERpc2FibGUgc2V0QWx0KGphdmEubGFuZy5TdHJpbmcgYWx0KSB7CiAgICAgICAgICByZXR1cm4gKERpc2FibGUpIHN1cGVyLnNldEFsdChhbHQpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIERpc2FibGUgc2V0Q2FsbGJhY2soamF2YS5sYW5nLlN0cmluZyBjYWxsYmFjaykgewogICAgICAgICAgcmV0dXJuIChEaXNhYmxlKSBzdXBlci5zZXRDYWxsYmFjayhjYWxsYmFjayk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgRGlzYWJsZSBzZXRGaWVsZHMoamF2YS5sYW5nLlN0cmluZyBmaWVsZHMpIHsKICAgICAgICAgIHJldHVybiAoRGlzYWJsZSkgc3VwZXIuc2V0RmllbGRzKGZpZWxkcyk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgRGlzYWJsZSBzZXRLZXkoamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICAgIHJldHVybiAoRGlzYWJsZSkgc3VwZXIuc2V0S2V5KGtleSk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgRGlzYWJsZSBzZXRPYXV0aFRva2VuKGphdmEubGFuZy5TdHJpbmcgb2F1dGhUb2tlbikgewogICAgICAgICAgcmV0dXJuIChEaXNhYmxlKSBzdXBlci5zZXRPYXV0aFRva2VuKG9hdXRoVG9rZW4pOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIERpc2FibGUgc2V0UHJldHR5UHJpbnQoamF2YS5sYW5nLkJvb2xlYW4gcHJldHR5UHJpbnQpIHsKICAgICAgICAgIHJldHVybiAoRGlzYWJsZSkgc3VwZXIuc2V0UHJldHR5UHJpbnQocHJldHR5UHJpbnQpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIERpc2FibGUgc2V0UXVvdGFVc2VyKGphdmEubGFuZy5TdHJpbmcgcXVvdGFVc2VyKSB7CiAgICAgICAgICByZXR1cm4gKERpc2FibGUpIHN1cGVyLnNldFF1b3RhVXNlcihxdW90YVVzZXIpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIERpc2FibGUgc2V0VXBsb2FkVHlwZShqYXZhLmxhbmcuU3RyaW5nIHVwbG9hZFR5cGUpIHsKICAgICAgICAgIHJldHVybiAoRGlzYWJsZSkgc3VwZXIuc2V0VXBsb2FkVHlwZSh1cGxvYWRUeXBlKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBEaXNhYmxlIHNldFVwbG9hZFByb3RvY29sKGphdmEubGFuZy5TdHJpbmcgdXBsb2FkUHJvdG9jb2wpIHsKICAgICAgICAgIHJldHVybiAoRGlzYWJsZSkgc3VwZXIuc2V0VXBsb2FkUHJvdG9jb2wodXBsb2FkUHJvdG9jb2wpOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogVGhlIHJlc291cmNlIG5hbWUgb2YgdGhlIHNlcnZpY2UgYWNjb3VudCBpbiB0aGUgZm9sbG93aW5nIGZvcm1hdDoKICAgICAgICAgKiBgcHJvamVjdHMve1BST0pFQ1RfSUR9L3NlcnZpY2VBY2NvdW50cy97QUNDT1VOVH1gLiBVc2luZyBgLWAgYXMgYSB3aWxkY2FyZCBmb3IgdGhlCiAgICAgICAgICogYFBST0pFQ1RfSURgIHdpbGwgaW5mZXIgdGhlIHByb2plY3QgZnJvbSB0aGUgYWNjb3VudC4gVGhlIGBBQ0NPVU5UYCB2YWx1ZSBjYW4gYmUgdGhlCiAgICAgICAgICogYGVtYWlsYCBhZGRyZXNzIG9yIHRoZSBgdW5pcXVlX2lkYCBvZiB0aGUgc2VydmljZSBhY2NvdW50LgogICAgICAgICAqLwogICAgICAgIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICAgICAgICBwcml2YXRlIGphdmEubGFuZy5TdHJpbmcgbmFtZTsKCiAgICAgICAgLyoqIFRoZSByZXNvdXJjZSBuYW1lIG9mIHRoZSBzZXJ2aWNlIGFjY291bnQgaW4gdGhlIGZvbGxvd2luZyBmb3JtYXQ6CiAgICAgICBgcHJvamVjdHMve1BST0pFQ1RfSUR9L3NlcnZpY2VBY2NvdW50cy97QUNDT1VOVH1gLiBVc2luZyBgLWAgYXMgYSB3aWxkY2FyZCBmb3IgdGhlIGBQUk9KRUNUX0lEYAogICAgICAgd2lsbCBpbmZlciB0aGUgcHJvamVjdCBmcm9tIHRoZSBhY2NvdW50LiBUaGUgYEFDQ09VTlRgIHZhbHVlIGNhbiBiZSB0aGUgYGVtYWlsYCBhZGRyZXNzIG9yIHRoZQogICAgICAgYHVuaXF1ZV9pZGAgb2YgdGhlIHNlcnZpY2UgYWNjb3VudC4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXROYW1lKCkgewogICAgICAgICAgcmV0dXJuIG5hbWU7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiBUaGUgcmVzb3VyY2UgbmFtZSBvZiB0aGUgc2VydmljZSBhY2NvdW50IGluIHRoZSBmb2xsb3dpbmcgZm9ybWF0OgogICAgICAgICAqIGBwcm9qZWN0cy97UFJPSkVDVF9JRH0vc2VydmljZUFjY291bnRzL3tBQ0NPVU5UfWAuIFVzaW5nIGAtYCBhcyBhIHdpbGRjYXJkIGZvciB0aGUKICAgICAgICAgKiBgUFJPSkVDVF9JRGAgd2lsbCBpbmZlciB0aGUgcHJvamVjdCBmcm9tIHRoZSBhY2NvdW50LiBUaGUgYEFDQ09VTlRgIHZhbHVlIGNhbiBiZSB0aGUKICAgICAgICAgKiBgZW1haWxgIGFkZHJlc3Mgb3IgdGhlIGB1bmlxdWVfaWRgIG9mIHRoZSBzZXJ2aWNlIGFjY291bnQuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIERpc2FibGUgc2V0TmFtZShqYXZhLmxhbmcuU3RyaW5nIG5hbWUpIHsKICAgICAgICAgIGlmICghZ2V0U3VwcHJlc3NQYXR0ZXJuQ2hlY2tzKCkpIHsKICAgICAgICAgICAgY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuUHJlY29uZGl0aW9ucy5jaGVja0FyZ3VtZW50KE5BTUVfUEFUVEVSTi5tYXRjaGVyKG5hbWUpLm1hdGNoZXMoKSwKICAgICAgICAgICAgICAgICJQYXJhbWV0ZXIgbmFtZSBtdXN0IGNvbmZvcm0gdG8gdGhlIHBhdHRlcm4gIiArCiAgICAgICAgICAgICAgICAiXnByb2plY3RzL1teL10rL3NlcnZpY2VBY2NvdW50cy9bXi9dKyQiKTsKICAgICAgICAgIH0KICAgICAgICAgIHRoaXMubmFtZSA9IG5hbWU7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBEaXNhYmxlIHNldChTdHJpbmcgcGFyYW1ldGVyTmFtZSwgT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgICByZXR1cm4gKERpc2FibGUpIHN1cGVyLnNldChwYXJhbWV0ZXJOYW1lLCB2YWx1ZSk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBFbmFibGVTZXJ2aWNlQWNjb3VudCBpcyBjdXJyZW50bHkgaW4gdGhlIGFscGhhIGxhdW5jaCBzdGFnZS4KICAgICAgICoKICAgICAgICogIFJlc3RvcmVzIGEgZGlzYWJsZWQgU2VydmljZUFjY291bnQgIHRoYXQgaGFzIGJlZW4gbWFudWFsbHkgZGlzYWJsZWQgYnkgdXNpbmcKICAgICAgICogRGlzYWJsZVNlcnZpY2VBY2NvdW50LiBTZXJ2aWNlICBhY2NvdW50cyB0aGF0IGhhdmUgYmVlbiBkaXNhYmxlZCBieSBvdGhlciBtZWFucyBvciBmb3Igb3RoZXIKICAgICAgICogcmVhc29ucywgIHN1Y2ggYXMgYWJ1c2UsIGNhbm5vdCBiZSByZXN0b3JlZCB1c2luZyB0aGlzIG1ldGhvZC4KICAgICAgICoKICAgICAgICogIEVuYWJsZVNlcnZpY2VBY2NvdW50IHdpbGwgaGF2ZSBubyBlZmZlY3Qgb24gYSBzZXJ2aWNlIGFjY291bnQgdGhhdCBpcyAgbm90IGRpc2FibGVkLiAgRW5hYmxpbmcKICAgICAgICogYW4gYWxyZWFkeSBlbmFibGVkIHNlcnZpY2UgYWNjb3VudCB3aWxsIGhhdmUgbm8gIGVmZmVjdC4KICAgICAgICoKICAgICAgICogQ3JlYXRlIGEgcmVxdWVzdCBmb3IgdGhlIG1ldGhvZCAic2VydmljZUFjY291bnRzLmVuYWJsZSIuCiAgICAgICAqCiAgICAgICAqIFRoaXMgcmVxdWVzdCBob2xkcyB0aGUgcGFyYW1ldGVycyBuZWVkZWQgYnkgdGhlIGlhbSBzZXJ2ZXIuICBBZnRlciBzZXR0aW5nIGFueSBvcHRpb25hbAogICAgICAgKiBwYXJhbWV0ZXJzLCBjYWxsIHRoZSB7QGxpbmsgRW5hYmxlI2V4ZWN1dGUoKX0gbWV0aG9kIHRvIGludm9rZSB0aGUgcmVtb3RlIG9wZXJhdGlvbi4KICAgICAgICoKICAgICAgICogQHBhcmFtIG5hbWUgVGhlIHJlc291cmNlIG5hbWUgb2YgdGhlIHNlcnZpY2UgYWNjb3VudCBpbiB0aGUgZm9sbG93aW5nIGZvcm1hdDoKICAgICAgICogICAgICAgIGBwcm9qZWN0cy97UFJPSkVDVF9JRH0vc2VydmljZUFjY291bnRzL3tBQ0NPVU5UfWAuCiAgICAgIFVzaW5nIGAtYCBhcyBhIHdpbGRjYXJkIGZvciB0aGUKICAgICAgICogICAgICAgIGBQUk9KRUNUX0lEYCB3aWxsIGluZmVyIHRoZSBwcm9qZWN0IGZyb20KICAgICAgdGhlIGFjY291bnQuIFRoZSBgQUNDT1VOVGAgdmFsdWUgY2FuIGJlIHRoZQogICAgICAgKiAgICAgICAgYGVtYWlsYCBhZGRyZXNzIG9yIHRoZQogICAgICBgdW5pcXVlX2lkYCBvZiB0aGUgc2VydmljZSBhY2NvdW50LgogICAgICAgKiBAcGFyYW0gY29udGVudCB0aGUge0BsaW5rIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmlhbS52MS5tb2RlbC5FbmFibGVTZXJ2aWNlQWNjb3VudFJlcXVlc3R9CiAgICAgICAqIEByZXR1cm4gdGhlIHJlcXVlc3QKICAgICAgICovCiAgICAgIHB1YmxpYyBFbmFibGUgZW5hYmxlKGphdmEubGFuZy5TdHJpbmcgbmFtZSwgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuaWFtLnYxLm1vZGVsLkVuYWJsZVNlcnZpY2VBY2NvdW50UmVxdWVzdCBjb250ZW50KSB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgRW5hYmxlIHJlc3VsdCA9IG5ldyBFbmFibGUobmFtZSwgY29udGVudCk7CiAgICAgICAgaW5pdGlhbGl6ZShyZXN1bHQpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBjbGFzcyBFbmFibGUgZXh0ZW5kcyBJYW1SZXF1ZXN0PGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmlhbS52MS5tb2RlbC5FbXB0eT4gewoKICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgUkVTVF9QQVRIID0gInYxL3srbmFtZX06ZW5hYmxlIjsKCiAgICAgICAgcHJpdmF0ZSBmaW5hbCBqYXZhLnV0aWwucmVnZXguUGF0dGVybiBOQU1FX1BBVFRFUk4gPQogICAgICAgICAgICBqYXZhLnV0aWwucmVnZXguUGF0dGVybi5jb21waWxlKCJecHJvamVjdHMvW14vXSsvc2VydmljZUFjY291bnRzL1teL10rJCIpOwoKICAgICAgICAvKioKICAgICAgICAgKiBFbmFibGVTZXJ2aWNlQWNjb3VudCBpcyBjdXJyZW50bHkgaW4gdGhlIGFscGhhIGxhdW5jaCBzdGFnZS4KICAgICAgICAgKgogICAgICAgICAqICBSZXN0b3JlcyBhIGRpc2FibGVkIFNlcnZpY2VBY2NvdW50ICB0aGF0IGhhcyBiZWVuIG1hbnVhbGx5IGRpc2FibGVkIGJ5IHVzaW5nCiAgICAgICAgICogRGlzYWJsZVNlcnZpY2VBY2NvdW50LiBTZXJ2aWNlICBhY2NvdW50cyB0aGF0IGhhdmUgYmVlbiBkaXNhYmxlZCBieSBvdGhlciBtZWFucyBvciBmb3Igb3RoZXIKICAgICAgICAgKiByZWFzb25zLCAgc3VjaCBhcyBhYnVzZSwgY2Fubm90IGJlIHJlc3RvcmVkIHVzaW5nIHRoaXMgbWV0aG9kLgogICAgICAgICAqCiAgICAgICAgICogIEVuYWJsZVNlcnZpY2VBY2NvdW50IHdpbGwgaGF2ZSBubyBlZmZlY3Qgb24gYSBzZXJ2aWNlIGFjY291bnQgdGhhdCBpcyAgbm90IGRpc2FibGVkLiAgRW5hYmxpbmcKICAgICAgICAgKiBhbiBhbHJlYWR5IGVuYWJsZWQgc2VydmljZSBhY2NvdW50IHdpbGwgaGF2ZSBubyAgZWZmZWN0LgogICAgICAgICAqCiAgICAgICAgICogQ3JlYXRlIGEgcmVxdWVzdCBmb3IgdGhlIG1ldGhvZCAic2VydmljZUFjY291bnRzLmVuYWJsZSIuCiAgICAgICAgICoKICAgICAgICAgKiBUaGlzIHJlcXVlc3QgaG9sZHMgdGhlIHBhcmFtZXRlcnMgbmVlZGVkIGJ5IHRoZSB0aGUgaWFtIHNlcnZlci4gIEFmdGVyIHNldHRpbmcgYW55IG9wdGlvbmFsCiAgICAgICAgICogcGFyYW1ldGVycywgY2FsbCB0aGUge0BsaW5rIEVuYWJsZSNleGVjdXRlKCl9IG1ldGhvZCB0byBpbnZva2UgdGhlIHJlbW90ZSBvcGVyYXRpb24uIDxwPiB7QGxpbmsKICAgICAgICAgKiBFbmFibGUjaW5pdGlhbGl6ZShjb20uZ29vZ2xlLmFwaS5jbGllbnQuZ29vZ2xlYXBpcy5zZXJ2aWNlcy5BYnN0cmFjdEdvb2dsZUNsaWVudFJlcXVlc3QpfSBtdXN0CiAgICAgICAgICogYmUgY2FsbGVkIHRvIGluaXRpYWxpemUgdGhpcyBpbnN0YW5jZSBpbW1lZGlhdGVseSBhZnRlciBpbnZva2luZyB0aGUgY29uc3RydWN0b3IuIDwvcD4KICAgICAgICAgKgogICAgICAgICAqIEBwYXJhbSBuYW1lIFRoZSByZXNvdXJjZSBuYW1lIG9mIHRoZSBzZXJ2aWNlIGFjY291bnQgaW4gdGhlIGZvbGxvd2luZyBmb3JtYXQ6CiAgICAgICAqICAgICAgICBgcHJvamVjdHMve1BST0pFQ1RfSUR9L3NlcnZpY2VBY2NvdW50cy97QUNDT1VOVH1gLgogICAgICBVc2luZyBgLWAgYXMgYSB3aWxkY2FyZCBmb3IgdGhlCiAgICAgICAqICAgICAgICBgUFJPSkVDVF9JRGAgd2lsbCBpbmZlciB0aGUgcHJvamVjdCBmcm9tCiAgICAgIHRoZSBhY2NvdW50LiBUaGUgYEFDQ09VTlRgIHZhbHVlIGNhbiBiZSB0aGUKICAgICAgICogICAgICAgIGBlbWFpbGAgYWRkcmVzcyBvciB0aGUKICAgICAgYHVuaXF1ZV9pZGAgb2YgdGhlIHNlcnZpY2UgYWNjb3VudC4KICAgICAgICAgKiBAcGFyYW0gY29udGVudCB0aGUge0BsaW5rIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmlhbS52MS5tb2RlbC5FbmFibGVTZXJ2aWNlQWNjb3VudFJlcXVlc3R9CiAgICAgICAgICogQHNpbmNlIDEuMTMKICAgICAgICAgKi8KICAgICAgICBwcm90ZWN0ZWQgRW5hYmxlKGphdmEubGFuZy5TdHJpbmcgbmFtZSwgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuaWFtLnYxLm1vZGVsLkVuYWJsZVNlcnZpY2VBY2NvdW50UmVxdWVzdCBjb250ZW50KSB7CiAgICAgICAgICBzdXBlcihJYW0udGhpcywgIlBPU1QiLCBSRVNUX1BBVEgsIGNvbnRlbnQsIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmlhbS52MS5tb2RlbC5FbXB0eS5jbGFzcyk7CiAgICAgICAgICB0aGlzLm5hbWUgPSBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5QcmVjb25kaXRpb25zLmNoZWNrTm90TnVsbChuYW1lLCAiUmVxdWlyZWQgcGFyYW1ldGVyIG5hbWUgbXVzdCBiZSBzcGVjaWZpZWQuIik7CiAgICAgICAgICBpZiAoIWdldFN1cHByZXNzUGF0dGVybkNoZWNrcygpKSB7CiAgICAgICAgICAgIGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLlByZWNvbmRpdGlvbnMuY2hlY2tBcmd1bWVudChOQU1FX1BBVFRFUk4ubWF0Y2hlcihuYW1lKS5tYXRjaGVzKCksCiAgICAgICAgICAgICAgICAiUGFyYW1ldGVyIG5hbWUgbXVzdCBjb25mb3JtIHRvIHRoZSBwYXR0ZXJuICIgKwogICAgICAgICAgICAgICAgIl5wcm9qZWN0cy9bXi9dKy9zZXJ2aWNlQWNjb3VudHMvW14vXSskIik7CiAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgRW5hYmxlIHNldCRYZ2FmdihqYXZhLmxhbmcuU3RyaW5nICRYZ2FmdikgewogICAgICAgICAgcmV0dXJuIChFbmFibGUpIHN1cGVyLnNldCRYZ2FmdigkWGdhZnYpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIEVuYWJsZSBzZXRBY2Nlc3NUb2tlbihqYXZhLmxhbmcuU3RyaW5nIGFjY2Vzc1Rva2VuKSB7CiAgICAgICAgICByZXR1cm4gKEVuYWJsZSkgc3VwZXIuc2V0QWNjZXNzVG9rZW4oYWNjZXNzVG9rZW4pOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIEVuYWJsZSBzZXRBbHQoamF2YS5sYW5nLlN0cmluZyBhbHQpIHsKICAgICAgICAgIHJldHVybiAoRW5hYmxlKSBzdXBlci5zZXRBbHQoYWx0KTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBFbmFibGUgc2V0Q2FsbGJhY2soamF2YS5sYW5nLlN0cmluZyBjYWxsYmFjaykgewogICAgICAgICAgcmV0dXJuIChFbmFibGUpIHN1cGVyLnNldENhbGxiYWNrKGNhbGxiYWNrKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBFbmFibGUgc2V0RmllbGRzKGphdmEubGFuZy5TdHJpbmcgZmllbGRzKSB7CiAgICAgICAgICByZXR1cm4gKEVuYWJsZSkgc3VwZXIuc2V0RmllbGRzKGZpZWxkcyk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgRW5hYmxlIHNldEtleShqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgICAgcmV0dXJuIChFbmFibGUpIHN1cGVyLnNldEtleShrZXkpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIEVuYWJsZSBzZXRPYXV0aFRva2VuKGphdmEubGFuZy5TdHJpbmcgb2F1dGhUb2tlbikgewogICAgICAgICAgcmV0dXJuIChFbmFibGUpIHN1cGVyLnNldE9hdXRoVG9rZW4ob2F1dGhUb2tlbik7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgRW5hYmxlIHNldFByZXR0eVByaW50KGphdmEubGFuZy5Cb29sZWFuIHByZXR0eVByaW50KSB7CiAgICAgICAgICByZXR1cm4gKEVuYWJsZSkgc3VwZXIuc2V0UHJldHR5UHJpbnQocHJldHR5UHJpbnQpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIEVuYWJsZSBzZXRRdW90YVVzZXIoamF2YS5sYW5nLlN0cmluZyBxdW90YVVzZXIpIHsKICAgICAgICAgIHJldHVybiAoRW5hYmxlKSBzdXBlci5zZXRRdW90YVVzZXIocXVvdGFVc2VyKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBFbmFibGUgc2V0VXBsb2FkVHlwZShqYXZhLmxhbmcuU3RyaW5nIHVwbG9hZFR5cGUpIHsKICAgICAgICAgIHJldHVybiAoRW5hYmxlKSBzdXBlci5zZXRVcGxvYWRUeXBlKHVwbG9hZFR5cGUpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIEVuYWJsZSBzZXRVcGxvYWRQcm90b2NvbChqYXZhLmxhbmcuU3RyaW5nIHVwbG9hZFByb3RvY29sKSB7CiAgICAgICAgICByZXR1cm4gKEVuYWJsZSkgc3VwZXIuc2V0VXBsb2FkUHJvdG9jb2wodXBsb2FkUHJvdG9jb2wpOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogVGhlIHJlc291cmNlIG5hbWUgb2YgdGhlIHNlcnZpY2UgYWNjb3VudCBpbiB0aGUgZm9sbG93aW5nIGZvcm1hdDoKICAgICAgICAgKiBgcHJvamVjdHMve1BST0pFQ1RfSUR9L3NlcnZpY2VBY2NvdW50cy97QUNDT1VOVH1gLiBVc2luZyBgLWAgYXMgYSB3aWxkY2FyZCBmb3IgdGhlCiAgICAgICAgICogYFBST0pFQ1RfSURgIHdpbGwgaW5mZXIgdGhlIHByb2plY3QgZnJvbSB0aGUgYWNjb3VudC4gVGhlIGBBQ0NPVU5UYCB2YWx1ZSBjYW4gYmUgdGhlCiAgICAgICAgICogYGVtYWlsYCBhZGRyZXNzIG9yIHRoZSBgdW5pcXVlX2lkYCBvZiB0aGUgc2VydmljZSBhY2NvdW50LgogICAgICAgICAqLwogICAgICAgIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICAgICAgICBwcml2YXRlIGphdmEubGFuZy5TdHJpbmcgbmFtZTsKCiAgICAgICAgLyoqIFRoZSByZXNvdXJjZSBuYW1lIG9mIHRoZSBzZXJ2aWNlIGFjY291bnQgaW4gdGhlIGZvbGxvd2luZyBmb3JtYXQ6CiAgICAgICBgcHJvamVjdHMve1BST0pFQ1RfSUR9L3NlcnZpY2VBY2NvdW50cy97QUNDT1VOVH1gLiBVc2luZyBgLWAgYXMgYSB3aWxkY2FyZCBmb3IgdGhlIGBQUk9KRUNUX0lEYAogICAgICAgd2lsbCBpbmZlciB0aGUgcHJvamVjdCBmcm9tIHRoZSBhY2NvdW50LiBUaGUgYEFDQ09VTlRgIHZhbHVlIGNhbiBiZSB0aGUgYGVtYWlsYCBhZGRyZXNzIG9yIHRoZQogICAgICAgYHVuaXF1ZV9pZGAgb2YgdGhlIHNlcnZpY2UgYWNjb3VudC4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXROYW1lKCkgewogICAgICAgICAgcmV0dXJuIG5hbWU7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiBUaGUgcmVzb3VyY2UgbmFtZSBvZiB0aGUgc2VydmljZSBhY2NvdW50IGluIHRoZSBmb2xsb3dpbmcgZm9ybWF0OgogICAgICAgICAqIGBwcm9qZWN0cy97UFJPSkVDVF9JRH0vc2VydmljZUFjY291bnRzL3tBQ0NPVU5UfWAuIFVzaW5nIGAtYCBhcyBhIHdpbGRjYXJkIGZvciB0aGUKICAgICAgICAgKiBgUFJPSkVDVF9JRGAgd2lsbCBpbmZlciB0aGUgcHJvamVjdCBmcm9tIHRoZSBhY2NvdW50LiBUaGUgYEFDQ09VTlRgIHZhbHVlIGNhbiBiZSB0aGUKICAgICAgICAgKiBgZW1haWxgIGFkZHJlc3Mgb3IgdGhlIGB1bmlxdWVfaWRgIG9mIHRoZSBzZXJ2aWNlIGFjY291bnQuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIEVuYWJsZSBzZXROYW1lKGphdmEubGFuZy5TdHJpbmcgbmFtZSkgewogICAgICAgICAgaWYgKCFnZXRTdXBwcmVzc1BhdHRlcm5DaGVja3MoKSkgewogICAgICAgICAgICBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5QcmVjb25kaXRpb25zLmNoZWNrQXJndW1lbnQoTkFNRV9QQVRURVJOLm1hdGNoZXIobmFtZSkubWF0Y2hlcygpLAogICAgICAgICAgICAgICAgIlBhcmFtZXRlciBuYW1lIG11c3QgY29uZm9ybSB0byB0aGUgcGF0dGVybiAiICsKICAgICAgICAgICAgICAgICJecHJvamVjdHMvW14vXSsvc2VydmljZUFjY291bnRzL1teL10rJCIpOwogICAgICAgICAgfQogICAgICAgICAgdGhpcy5uYW1lID0gbmFtZTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIEVuYWJsZSBzZXQoU3RyaW5nIHBhcmFtZXRlck5hbWUsIE9iamVjdCB2YWx1ZSkgewogICAgICAgICAgcmV0dXJuIChFbmFibGUpIHN1cGVyLnNldChwYXJhbWV0ZXJOYW1lLCB2YWx1ZSk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBHZXRzIGEgU2VydmljZUFjY291bnQuCiAgICAgICAqCiAgICAgICAqIENyZWF0ZSBhIHJlcXVlc3QgZm9yIHRoZSBtZXRob2QgInNlcnZpY2VBY2NvdW50cy5nZXQiLgogICAgICAgKgogICAgICAgKiBUaGlzIHJlcXVlc3QgaG9sZHMgdGhlIHBhcmFtZXRlcnMgbmVlZGVkIGJ5IHRoZSBpYW0gc2VydmVyLiAgQWZ0ZXIgc2V0dGluZyBhbnkgb3B0aW9uYWwKICAgICAgICogcGFyYW1ldGVycywgY2FsbCB0aGUge0BsaW5rIEdldCNleGVjdXRlKCl9IG1ldGhvZCB0byBpbnZva2UgdGhlIHJlbW90ZSBvcGVyYXRpb24uCiAgICAgICAqCiAgICAgICAqIEBwYXJhbSBuYW1lIFJlcXVpcmVkLiBUaGUgcmVzb3VyY2UgbmFtZSBvZiB0aGUgc2VydmljZSBhY2NvdW50IGluIHRoZSBmb2xsb3dpbmcgZm9ybWF0OgogICAgICAgKiAgICAgICAgYHByb2plY3RzL3tQUk9KRUNUX0lEfS9zZXJ2aWNlQWNjb3VudHMve0FDQ09VTlR9YC4KICAgICAgVXNpbmcgYC1gIGFzIGEgd2lsZGNhcmQgZm9yIHRoZQogICAgICAgKiAgICAgICAgYFBST0pFQ1RfSURgIHdpbGwgaW5mZXIgdGhlIHByb2plY3QgZnJvbQogICAgICB0aGUgYWNjb3VudC4gVGhlIGBBQ0NPVU5UYCB2YWx1ZSBjYW4gYmUgdGhlCiAgICAgICAqICAgICAgICBgZW1haWxgIGFkZHJlc3Mgb3IgdGhlCiAgICAgIGB1bmlxdWVfaWRgIG9mIHRoZSBzZXJ2aWNlIGFjY291bnQuCiAgICAgICAqIEByZXR1cm4gdGhlIHJlcXVlc3QKICAgICAgICovCiAgICAgIHB1YmxpYyBHZXQgZ2V0KGphdmEubGFuZy5TdHJpbmcgbmFtZSkgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIEdldCByZXN1bHQgPSBuZXcgR2V0KG5hbWUpOwogICAgICAgIGluaXRpYWxpemUocmVzdWx0KTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBwdWJsaWMgY2xhc3MgR2V0IGV4dGVuZHMgSWFtUmVxdWVzdDxjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5pYW0udjEubW9kZWwuU2VydmljZUFjY291bnQ+IHsKCiAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFJFU1RfUEFUSCA9ICJ2MS97K25hbWV9IjsKCiAgICAgICAgcHJpdmF0ZSBmaW5hbCBqYXZhLnV0aWwucmVnZXguUGF0dGVybiBOQU1FX1BBVFRFUk4gPQogICAgICAgICAgICBqYXZhLnV0aWwucmVnZXguUGF0dGVybi5jb21waWxlKCJecHJvamVjdHMvW14vXSsvc2VydmljZUFjY291bnRzL1teL10rJCIpOwoKICAgICAgICAvKioKICAgICAgICAgKiBHZXRzIGEgU2VydmljZUFjY291bnQuCiAgICAgICAgICoKICAgICAgICAgKiBDcmVhdGUgYSByZXF1ZXN0IGZvciB0aGUgbWV0aG9kICJzZXJ2aWNlQWNjb3VudHMuZ2V0Ii4KICAgICAgICAgKgogICAgICAgICAqIFRoaXMgcmVxdWVzdCBob2xkcyB0aGUgcGFyYW1ldGVycyBuZWVkZWQgYnkgdGhlIHRoZSBpYW0gc2VydmVyLiAgQWZ0ZXIgc2V0dGluZyBhbnkgb3B0aW9uYWwKICAgICAgICAgKiBwYXJhbWV0ZXJzLCBjYWxsIHRoZSB7QGxpbmsgR2V0I2V4ZWN1dGUoKX0gbWV0aG9kIHRvIGludm9rZSB0aGUgcmVtb3RlIG9wZXJhdGlvbi4gPHA+IHtAbGluawogICAgICAgICAqIEdldCNpbml0aWFsaXplKGNvbS5nb29nbGUuYXBpLmNsaWVudC5nb29nbGVhcGlzLnNlcnZpY2VzLkFic3RyYWN0R29vZ2xlQ2xpZW50UmVxdWVzdCl9IG11c3QgYmUKICAgICAgICAgKiBjYWxsZWQgdG8gaW5pdGlhbGl6ZSB0aGlzIGluc3RhbmNlIGltbWVkaWF0ZWx5IGFmdGVyIGludm9raW5nIHRoZSBjb25zdHJ1Y3Rvci4gPC9wPgogICAgICAgICAqCiAgICAgICAgICogQHBhcmFtIG5hbWUgUmVxdWlyZWQuIFRoZSByZXNvdXJjZSBuYW1lIG9mIHRoZSBzZXJ2aWNlIGFjY291bnQgaW4gdGhlIGZvbGxvd2luZyBmb3JtYXQ6CiAgICAgICAqICAgICAgICBgcHJvamVjdHMve1BST0pFQ1RfSUR9L3NlcnZpY2VBY2NvdW50cy97QUNDT1VOVH1gLgogICAgICBVc2luZyBgLWAgYXMgYSB3aWxkY2FyZCBmb3IgdGhlCiAgICAgICAqICAgICAgICBgUFJPSkVDVF9JRGAgd2lsbCBpbmZlciB0aGUgcHJvamVjdCBmcm9tCiAgICAgIHRoZSBhY2NvdW50LiBUaGUgYEFDQ09VTlRgIHZhbHVlIGNhbiBiZSB0aGUKICAgICAgICogICAgICAgIGBlbWFpbGAgYWRkcmVzcyBvciB0aGUKICAgICAgYHVuaXF1ZV9pZGAgb2YgdGhlIHNlcnZpY2UgYWNjb3VudC4KICAgICAgICAgKiBAc2luY2UgMS4xMwogICAgICAgICAqLwogICAgICAgIHByb3RlY3RlZCBHZXQoamF2YS5sYW5nLlN0cmluZyBuYW1lKSB7CiAgICAgICAgICBzdXBlcihJYW0udGhpcywgIkdFVCIsIFJFU1RfUEFUSCwgbnVsbCwgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuaWFtLnYxLm1vZGVsLlNlcnZpY2VBY2NvdW50LmNsYXNzKTsKICAgICAgICAgIHRoaXMubmFtZSA9IGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLlByZWNvbmRpdGlvbnMuY2hlY2tOb3ROdWxsKG5hbWUsICJSZXF1aXJlZCBwYXJhbWV0ZXIgbmFtZSBtdXN0IGJlIHNwZWNpZmllZC4iKTsKICAgICAgICAgIGlmICghZ2V0U3VwcHJlc3NQYXR0ZXJuQ2hlY2tzKCkpIHsKICAgICAgICAgICAgY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuUHJlY29uZGl0aW9ucy5jaGVja0FyZ3VtZW50KE5BTUVfUEFUVEVSTi5tYXRjaGVyKG5hbWUpLm1hdGNoZXMoKSwKICAgICAgICAgICAgICAgICJQYXJhbWV0ZXIgbmFtZSBtdXN0IGNvbmZvcm0gdG8gdGhlIHBhdHRlcm4gIiArCiAgICAgICAgICAgICAgICAiXnByb2plY3RzL1teL10rL3NlcnZpY2VBY2NvdW50cy9bXi9dKyQiKTsKICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLmFwaS5jbGllbnQuaHR0cC5IdHRwUmVzcG9uc2UgZXhlY3V0ZVVzaW5nSGVhZCgpIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICAgIHJldHVybiBzdXBlci5leGVjdXRlVXNpbmdIZWFkKCk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5hcGkuY2xpZW50Lmh0dHAuSHR0cFJlcXVlc3QgYnVpbGRIdHRwUmVxdWVzdFVzaW5nSGVhZCgpIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICAgIHJldHVybiBzdXBlci5idWlsZEh0dHBSZXF1ZXN0VXNpbmdIZWFkKCk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgR2V0IHNldCRYZ2FmdihqYXZhLmxhbmcuU3RyaW5nICRYZ2FmdikgewogICAgICAgICAgcmV0dXJuIChHZXQpIHN1cGVyLnNldCRYZ2FmdigkWGdhZnYpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIEdldCBzZXRBY2Nlc3NUb2tlbihqYXZhLmxhbmcuU3RyaW5nIGFjY2Vzc1Rva2VuKSB7CiAgICAgICAgICByZXR1cm4gKEdldCkgc3VwZXIuc2V0QWNjZXNzVG9rZW4oYWNjZXNzVG9rZW4pOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIEdldCBzZXRBbHQoamF2YS5sYW5nLlN0cmluZyBhbHQpIHsKICAgICAgICAgIHJldHVybiAoR2V0KSBzdXBlci5zZXRBbHQoYWx0KTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBHZXQgc2V0Q2FsbGJhY2soamF2YS5sYW5nLlN0cmluZyBjYWxsYmFjaykgewogICAgICAgICAgcmV0dXJuIChHZXQpIHN1cGVyLnNldENhbGxiYWNrKGNhbGxiYWNrKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBHZXQgc2V0RmllbGRzKGphdmEubGFuZy5TdHJpbmcgZmllbGRzKSB7CiAgICAgICAgICByZXR1cm4gKEdldCkgc3VwZXIuc2V0RmllbGRzKGZpZWxkcyk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgR2V0IHNldEtleShqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgICAgcmV0dXJuIChHZXQpIHN1cGVyLnNldEtleShrZXkpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIEdldCBzZXRPYXV0aFRva2VuKGphdmEubGFuZy5TdHJpbmcgb2F1dGhUb2tlbikgewogICAgICAgICAgcmV0dXJuIChHZXQpIHN1cGVyLnNldE9hdXRoVG9rZW4ob2F1dGhUb2tlbik7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgR2V0IHNldFByZXR0eVByaW50KGphdmEubGFuZy5Cb29sZWFuIHByZXR0eVByaW50KSB7CiAgICAgICAgICByZXR1cm4gKEdldCkgc3VwZXIuc2V0UHJldHR5UHJpbnQocHJldHR5UHJpbnQpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIEdldCBzZXRRdW90YVVzZXIoamF2YS5sYW5nLlN0cmluZyBxdW90YVVzZXIpIHsKICAgICAgICAgIHJldHVybiAoR2V0KSBzdXBlci5zZXRRdW90YVVzZXIocXVvdGFVc2VyKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBHZXQgc2V0VXBsb2FkVHlwZShqYXZhLmxhbmcuU3RyaW5nIHVwbG9hZFR5cGUpIHsKICAgICAgICAgIHJldHVybiAoR2V0KSBzdXBlci5zZXRVcGxvYWRUeXBlKHVwbG9hZFR5cGUpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIEdldCBzZXRVcGxvYWRQcm90b2NvbChqYXZhLmxhbmcuU3RyaW5nIHVwbG9hZFByb3RvY29sKSB7CiAgICAgICAgICByZXR1cm4gKEdldCkgc3VwZXIuc2V0VXBsb2FkUHJvdG9jb2wodXBsb2FkUHJvdG9jb2wpOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogUmVxdWlyZWQuIFRoZSByZXNvdXJjZSBuYW1lIG9mIHRoZSBzZXJ2aWNlIGFjY291bnQgaW4gdGhlIGZvbGxvd2luZyBmb3JtYXQ6CiAgICAgICAgICogYHByb2plY3RzL3tQUk9KRUNUX0lEfS9zZXJ2aWNlQWNjb3VudHMve0FDQ09VTlR9YC4gVXNpbmcgYC1gIGFzIGEgd2lsZGNhcmQgZm9yIHRoZQogICAgICAgICAqIGBQUk9KRUNUX0lEYCB3aWxsIGluZmVyIHRoZSBwcm9qZWN0IGZyb20gdGhlIGFjY291bnQuIFRoZSBgQUNDT1VOVGAgdmFsdWUgY2FuIGJlIHRoZQogICAgICAgICAqIGBlbWFpbGAgYWRkcmVzcyBvciB0aGUgYHVuaXF1ZV9pZGAgb2YgdGhlIHNlcnZpY2UgYWNjb3VudC4KICAgICAgICAgKi8KICAgICAgICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuU3RyaW5nIG5hbWU7CgogICAgICAgIC8qKiBSZXF1aXJlZC4gVGhlIHJlc291cmNlIG5hbWUgb2YgdGhlIHNlcnZpY2UgYWNjb3VudCBpbiB0aGUgZm9sbG93aW5nIGZvcm1hdDoKICAgICAgIGBwcm9qZWN0cy97UFJPSkVDVF9JRH0vc2VydmljZUFjY291bnRzL3tBQ0NPVU5UfWAuIFVzaW5nIGAtYCBhcyBhIHdpbGRjYXJkIGZvciB0aGUgYFBST0pFQ1RfSURgCiAgICAgICB3aWxsIGluZmVyIHRoZSBwcm9qZWN0IGZyb20gdGhlIGFjY291bnQuIFRoZSBgQUNDT1VOVGAgdmFsdWUgY2FuIGJlIHRoZSBgZW1haWxgIGFkZHJlc3Mgb3IgdGhlCiAgICAgICBgdW5pcXVlX2lkYCBvZiB0aGUgc2VydmljZSBhY2NvdW50LgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldE5hbWUoKSB7CiAgICAgICAgICByZXR1cm4gbmFtZTsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIFJlcXVpcmVkLiBUaGUgcmVzb3VyY2UgbmFtZSBvZiB0aGUgc2VydmljZSBhY2NvdW50IGluIHRoZSBmb2xsb3dpbmcgZm9ybWF0OgogICAgICAgICAqIGBwcm9qZWN0cy97UFJPSkVDVF9JRH0vc2VydmljZUFjY291bnRzL3tBQ0NPVU5UfWAuIFVzaW5nIGAtYCBhcyBhIHdpbGRjYXJkIGZvciB0aGUKICAgICAgICAgKiBgUFJPSkVDVF9JRGAgd2lsbCBpbmZlciB0aGUgcHJvamVjdCBmcm9tIHRoZSBhY2NvdW50LiBUaGUgYEFDQ09VTlRgIHZhbHVlIGNhbiBiZSB0aGUKICAgICAgICAgKiBgZW1haWxgIGFkZHJlc3Mgb3IgdGhlIGB1bmlxdWVfaWRgIG9mIHRoZSBzZXJ2aWNlIGFjY291bnQuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIEdldCBzZXROYW1lKGphdmEubGFuZy5TdHJpbmcgbmFtZSkgewogICAgICAgICAgaWYgKCFnZXRTdXBwcmVzc1BhdHRlcm5DaGVja3MoKSkgewogICAgICAgICAgICBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5QcmVjb25kaXRpb25zLmNoZWNrQXJndW1lbnQoTkFNRV9QQVRURVJOLm1hdGNoZXIobmFtZSkubWF0Y2hlcygpLAogICAgICAgICAgICAgICAgIlBhcmFtZXRlciBuYW1lIG11c3QgY29uZm9ybSB0byB0aGUgcGF0dGVybiAiICsKICAgICAgICAgICAgICAgICJecHJvamVjdHMvW14vXSsvc2VydmljZUFjY291bnRzL1teL10rJCIpOwogICAgICAgICAgfQogICAgICAgICAgdGhpcy5uYW1lID0gbmFtZTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIEdldCBzZXQoU3RyaW5nIHBhcmFtZXRlck5hbWUsIE9iamVjdCB2YWx1ZSkgewogICAgICAgICAgcmV0dXJuIChHZXQpIHN1cGVyLnNldChwYXJhbWV0ZXJOYW1lLCB2YWx1ZSk7CiAgICAgICAgfQogICAgICB9CiAgICAgIC8qKgogICAgICAgKiBSZXR1cm5zIHRoZSBDbG91ZCBJQU0gYWNjZXNzIGNvbnRyb2wgcG9saWN5IGZvciBhIFNlcnZpY2VBY2NvdW50LgogICAgICAgKgogICAgICAgKiBOb3RlOiBTZXJ2aWNlIGFjY291bnRzIGFyZSBib3RoIFtyZXNvdXJjZXMgYW5kIGlkZW50aXRpZXNdKC9pYW0vZG9jcy9zZXJ2aWNlLQogICAgICAgKiBhY2NvdW50cyNzZXJ2aWNlX2FjY291bnRfcGVybWlzc2lvbnMpLiBUaGlzIG1ldGhvZCB0cmVhdHMgdGhlIHNlcnZpY2UgYWNjb3VudCBhcyBhIHJlc291cmNlLiBJdAogICAgICAgKiByZXR1cm5zIHRoZSBDbG91ZCBJQU0gcG9saWN5IHRoYXQgcmVmbGVjdHMgd2hhdCBtZW1iZXJzIGhhdmUgYWNjZXNzIHRvIHRoZSBzZXJ2aWNlIGFjY291bnQuCiAgICAgICAqCiAgICAgICAqIFRoaXMgbWV0aG9kIGRvZXMgbm90IHJldHVybiB3aGF0IHJlc291cmNlcyB0aGUgc2VydmljZSBhY2NvdW50IGhhcyBhY2Nlc3MgdG8uIFRvIHNlZSBpZiBhIHNlcnZpY2UKICAgICAgICogYWNjb3VudCBoYXMgYWNjZXNzIHRvIGEgcmVzb3VyY2UsIGNhbGwgdGhlIGBnZXRJYW1Qb2xpY3lgIG1ldGhvZCBvbiB0aGUgdGFyZ2V0IHJlc291cmNlLiBGb3IKICAgICAgICogZXhhbXBsZSwgdG8gdmlldyBncmFudHMgZm9yIGEgcHJvamVjdCwgY2FsbCB0aGUgW3Byb2plY3RzLmdldElhbVBvbGljeV0oL3Jlc291cmNlLQogICAgICAgKiBtYW5hZ2VyL3JlZmVyZW5jZS9yZXN0L3YxL3Byb2plY3RzL2dldElhbVBvbGljeSkgbWV0aG9kLgogICAgICAgKgogICAgICAgKiBDcmVhdGUgYSByZXF1ZXN0IGZvciB0aGUgbWV0aG9kICJzZXJ2aWNlQWNjb3VudHMuZ2V0SWFtUG9saWN5Ii4KICAgICAgICoKICAgICAgICogVGhpcyByZXF1ZXN0IGhvbGRzIHRoZSBwYXJhbWV0ZXJzIG5lZWRlZCBieSB0aGUgaWFtIHNlcnZlci4gIEFmdGVyIHNldHRpbmcgYW55IG9wdGlvbmFsCiAgICAgICAqIHBhcmFtZXRlcnMsIGNhbGwgdGhlIHtAbGluayBHZXRJYW1Qb2xpY3kjZXhlY3V0ZSgpfSBtZXRob2QgdG8gaW52b2tlIHRoZSByZW1vdGUgb3BlcmF0aW9uLgogICAgICAgKgogICAgICAgKiBAcGFyYW0gcmVzb3VyY2UgUkVRVUlSRUQ6IFRoZSByZXNvdXJjZSBmb3Igd2hpY2ggdGhlIHBvbGljeSBpcyBiZWluZyByZXF1ZXN0ZWQuCiAgICAgIFNlZSB0aGUgb3BlcmF0aW9uIGRvY3VtZW50YXRpb24gZm9yCiAgICAgICAqICAgICAgICB0aGUgYXBwcm9wcmlhdGUgdmFsdWUgZm9yIHRoaXMgZmllbGQuCiAgICAgICAqIEByZXR1cm4gdGhlIHJlcXVlc3QKICAgICAgICovCiAgICAgIHB1YmxpYyBHZXRJYW1Qb2xpY3kgZ2V0SWFtUG9saWN5KGphdmEubGFuZy5TdHJpbmcgcmVzb3VyY2UpIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICBHZXRJYW1Qb2xpY3kgcmVzdWx0ID0gbmV3IEdldElhbVBvbGljeShyZXNvdXJjZSk7CiAgICAgICAgaW5pdGlhbGl6ZShyZXN1bHQpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBjbGFzcyBHZXRJYW1Qb2xpY3kgZXh0ZW5kcyBJYW1SZXF1ZXN0PGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmlhbS52MS5tb2RlbC5Qb2xpY3k+IHsKCiAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFJFU1RfUEFUSCA9ICJ2MS97K3Jlc291cmNlfTpnZXRJYW1Qb2xpY3kiOwoKICAgICAgICBwcml2YXRlIGZpbmFsIGphdmEudXRpbC5yZWdleC5QYXR0ZXJuIFJFU09VUkNFX1BBVFRFUk4gPQogICAgICAgICAgICBqYXZhLnV0aWwucmVnZXguUGF0dGVybi5jb21waWxlKCJecHJvamVjdHMvW14vXSsvc2VydmljZUFjY291bnRzL1teL10rJCIpOwoKICAgICAgICAvKioKICAgICAgICAgKiBSZXR1cm5zIHRoZSBDbG91ZCBJQU0gYWNjZXNzIGNvbnRyb2wgcG9saWN5IGZvciBhIFNlcnZpY2VBY2NvdW50LgogICAgICAgICAqCiAgICAgICAgICogTm90ZTogU2VydmljZSBhY2NvdW50cyBhcmUgYm90aCBbcmVzb3VyY2VzIGFuZCBpZGVudGl0aWVzXSgvaWFtL2RvY3Mvc2VydmljZS0KICAgICAgICAgKiBhY2NvdW50cyNzZXJ2aWNlX2FjY291bnRfcGVybWlzc2lvbnMpLiBUaGlzIG1ldGhvZCB0cmVhdHMgdGhlIHNlcnZpY2UgYWNjb3VudCBhcyBhIHJlc291cmNlLiBJdAogICAgICAgICAqIHJldHVybnMgdGhlIENsb3VkIElBTSBwb2xpY3kgdGhhdCByZWZsZWN0cyB3aGF0IG1lbWJlcnMgaGF2ZSBhY2Nlc3MgdG8gdGhlIHNlcnZpY2UgYWNjb3VudC4KICAgICAgICAgKgogICAgICAgICAqIFRoaXMgbWV0aG9kIGRvZXMgbm90IHJldHVybiB3aGF0IHJlc291cmNlcyB0aGUgc2VydmljZSBhY2NvdW50IGhhcyBhY2Nlc3MgdG8uIFRvIHNlZSBpZiBhCiAgICAgICAgICogc2VydmljZSBhY2NvdW50IGhhcyBhY2Nlc3MgdG8gYSByZXNvdXJjZSwgY2FsbCB0aGUgYGdldElhbVBvbGljeWAgbWV0aG9kIG9uIHRoZSB0YXJnZXQKICAgICAgICAgKiByZXNvdXJjZS4gRm9yIGV4YW1wbGUsIHRvIHZpZXcgZ3JhbnRzIGZvciBhIHByb2plY3QsIGNhbGwgdGhlIFtwcm9qZWN0cy5nZXRJYW1Qb2xpY3kKICAgICAgICAgKiBdKC9yZXNvdXJjZS1tYW5hZ2VyL3JlZmVyZW5jZS9yZXN0L3YxL3Byb2plY3RzL2dldElhbVBvbGljeSkgbWV0aG9kLgogICAgICAgICAqCiAgICAgICAgICogQ3JlYXRlIGEgcmVxdWVzdCBmb3IgdGhlIG1ldGhvZCAic2VydmljZUFjY291bnRzLmdldElhbVBvbGljeSIuCiAgICAgICAgICoKICAgICAgICAgKiBUaGlzIHJlcXVlc3QgaG9sZHMgdGhlIHBhcmFtZXRlcnMgbmVlZGVkIGJ5IHRoZSB0aGUgaWFtIHNlcnZlci4gIEFmdGVyIHNldHRpbmcgYW55IG9wdGlvbmFsCiAgICAgICAgICogcGFyYW1ldGVycywgY2FsbCB0aGUge0BsaW5rIEdldElhbVBvbGljeSNleGVjdXRlKCl9IG1ldGhvZCB0byBpbnZva2UgdGhlIHJlbW90ZSBvcGVyYXRpb24uIDxwPgogICAgICAgICAqIHtAbGluawogICAgICAgICAqIEdldElhbVBvbGljeSNpbml0aWFsaXplKGNvbS5nb29nbGUuYXBpLmNsaWVudC5nb29nbGVhcGlzLnNlcnZpY2VzLkFic3RyYWN0R29vZ2xlQ2xpZW50UmVxdWVzdCl9CiAgICAgICAgICogbXVzdCBiZSBjYWxsZWQgdG8gaW5pdGlhbGl6ZSB0aGlzIGluc3RhbmNlIGltbWVkaWF0ZWx5IGFmdGVyIGludm9raW5nIHRoZSBjb25zdHJ1Y3Rvci4gPC9wPgogICAgICAgICAqCiAgICAgICAgICogQHBhcmFtIHJlc291cmNlIFJFUVVJUkVEOiBUaGUgcmVzb3VyY2UgZm9yIHdoaWNoIHRoZSBwb2xpY3kgaXMgYmVpbmcgcmVxdWVzdGVkLgogICAgICBTZWUgdGhlIG9wZXJhdGlvbiBkb2N1bWVudGF0aW9uIGZvcgogICAgICAgKiAgICAgICAgdGhlIGFwcHJvcHJpYXRlIHZhbHVlIGZvciB0aGlzIGZpZWxkLgogICAgICAgICAqIEBzaW5jZSAxLjEzCiAgICAgICAgICovCiAgICAgICAgcHJvdGVjdGVkIEdldElhbVBvbGljeShqYXZhLmxhbmcuU3RyaW5nIHJlc291cmNlKSB7CiAgICAgICAgICBzdXBlcihJYW0udGhpcywgIlBPU1QiLCBSRVNUX1BBVEgsIG51bGwsIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmlhbS52MS5tb2RlbC5Qb2xpY3kuY2xhc3MpOwogICAgICAgICAgdGhpcy5yZXNvdXJjZSA9IGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLlByZWNvbmRpdGlvbnMuY2hlY2tOb3ROdWxsKHJlc291cmNlLCAiUmVxdWlyZWQgcGFyYW1ldGVyIHJlc291cmNlIG11c3QgYmUgc3BlY2lmaWVkLiIpOwogICAgICAgICAgaWYgKCFnZXRTdXBwcmVzc1BhdHRlcm5DaGVja3MoKSkgewogICAgICAgICAgICBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5QcmVjb25kaXRpb25zLmNoZWNrQXJndW1lbnQoUkVTT1VSQ0VfUEFUVEVSTi5tYXRjaGVyKHJlc291cmNlKS5tYXRjaGVzKCksCiAgICAgICAgICAgICAgICAiUGFyYW1ldGVyIHJlc291cmNlIG11c3QgY29uZm9ybSB0byB0aGUgcGF0dGVybiAiICsKICAgICAgICAgICAgICAgICJecHJvamVjdHMvW14vXSsvc2VydmljZUFjY291bnRzL1teL10rJCIpOwogICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIEdldElhbVBvbGljeSBzZXQkWGdhZnYoamF2YS5sYW5nLlN0cmluZyAkWGdhZnYpIHsKICAgICAgICAgIHJldHVybiAoR2V0SWFtUG9saWN5KSBzdXBlci5zZXQkWGdhZnYoJFhnYWZ2KTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBHZXRJYW1Qb2xpY3kgc2V0QWNjZXNzVG9rZW4oamF2YS5sYW5nLlN0cmluZyBhY2Nlc3NUb2tlbikgewogICAgICAgICAgcmV0dXJuIChHZXRJYW1Qb2xpY3kpIHN1cGVyLnNldEFjY2Vzc1Rva2VuKGFjY2Vzc1Rva2VuKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBHZXRJYW1Qb2xpY3kgc2V0QWx0KGphdmEubGFuZy5TdHJpbmcgYWx0KSB7CiAgICAgICAgICByZXR1cm4gKEdldElhbVBvbGljeSkgc3VwZXIuc2V0QWx0KGFsdCk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgR2V0SWFtUG9saWN5IHNldENhbGxiYWNrKGphdmEubGFuZy5TdHJpbmcgY2FsbGJhY2spIHsKICAgICAgICAgIHJldHVybiAoR2V0SWFtUG9saWN5KSBzdXBlci5zZXRDYWxsYmFjayhjYWxsYmFjayk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgR2V0SWFtUG9saWN5IHNldEZpZWxkcyhqYXZhLmxhbmcuU3RyaW5nIGZpZWxkcykgewogICAgICAgICAgcmV0dXJuIChHZXRJYW1Qb2xpY3kpIHN1cGVyLnNldEZpZWxkcyhmaWVsZHMpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIEdldElhbVBvbGljeSBzZXRLZXkoamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICAgIHJldHVybiAoR2V0SWFtUG9saWN5KSBzdXBlci5zZXRLZXkoa2V5KTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBHZXRJYW1Qb2xpY3kgc2V0T2F1dGhUb2tlbihqYXZhLmxhbmcuU3RyaW5nIG9hdXRoVG9rZW4pIHsKICAgICAgICAgIHJldHVybiAoR2V0SWFtUG9saWN5KSBzdXBlci5zZXRPYXV0aFRva2VuKG9hdXRoVG9rZW4pOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIEdldElhbVBvbGljeSBzZXRQcmV0dHlQcmludChqYXZhLmxhbmcuQm9vbGVhbiBwcmV0dHlQcmludCkgewogICAgICAgICAgcmV0dXJuIChHZXRJYW1Qb2xpY3kpIHN1cGVyLnNldFByZXR0eVByaW50KHByZXR0eVByaW50KTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBHZXRJYW1Qb2xpY3kgc2V0UXVvdGFVc2VyKGphdmEubGFuZy5TdHJpbmcgcXVvdGFVc2VyKSB7CiAgICAgICAgICByZXR1cm4gKEdldElhbVBvbGljeSkgc3VwZXIuc2V0UXVvdGFVc2VyKHF1b3RhVXNlcik7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgR2V0SWFtUG9saWN5IHNldFVwbG9hZFR5cGUoamF2YS5sYW5nLlN0cmluZyB1cGxvYWRUeXBlKSB7CiAgICAgICAgICByZXR1cm4gKEdldElhbVBvbGljeSkgc3VwZXIuc2V0VXBsb2FkVHlwZSh1cGxvYWRUeXBlKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBHZXRJYW1Qb2xpY3kgc2V0VXBsb2FkUHJvdG9jb2woamF2YS5sYW5nLlN0cmluZyB1cGxvYWRQcm90b2NvbCkgewogICAgICAgICAgcmV0dXJuIChHZXRJYW1Qb2xpY3kpIHN1cGVyLnNldFVwbG9hZFByb3RvY29sKHVwbG9hZFByb3RvY29sKTsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIFJFUVVJUkVEOiBUaGUgcmVzb3VyY2UgZm9yIHdoaWNoIHRoZSBwb2xpY3kgaXMgYmVpbmcgcmVxdWVzdGVkLiBTZWUgdGhlIG9wZXJhdGlvbgogICAgICAgICAqIGRvY3VtZW50YXRpb24gZm9yIHRoZSBhcHByb3ByaWF0ZSB2YWx1ZSBmb3IgdGhpcyBmaWVsZC4KICAgICAgICAgKi8KICAgICAgICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuU3RyaW5nIHJlc291cmNlOwoKICAgICAgICAvKiogUkVRVUlSRUQ6IFRoZSByZXNvdXJjZSBmb3Igd2hpY2ggdGhlIHBvbGljeSBpcyBiZWluZyByZXF1ZXN0ZWQuIFNlZSB0aGUgb3BlcmF0aW9uIGRvY3VtZW50YXRpb24gZm9yCiAgICAgICB0aGUgYXBwcm9wcmlhdGUgdmFsdWUgZm9yIHRoaXMgZmllbGQuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0UmVzb3VyY2UoKSB7CiAgICAgICAgICByZXR1cm4gcmVzb3VyY2U7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiBSRVFVSVJFRDogVGhlIHJlc291cmNlIGZvciB3aGljaCB0aGUgcG9saWN5IGlzIGJlaW5nIHJlcXVlc3RlZC4gU2VlIHRoZSBvcGVyYXRpb24KICAgICAgICAgKiBkb2N1bWVudGF0aW9uIGZvciB0aGUgYXBwcm9wcmlhdGUgdmFsdWUgZm9yIHRoaXMgZmllbGQuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIEdldElhbVBvbGljeSBzZXRSZXNvdXJjZShqYXZhLmxhbmcuU3RyaW5nIHJlc291cmNlKSB7CiAgICAgICAgICBpZiAoIWdldFN1cHByZXNzUGF0dGVybkNoZWNrcygpKSB7CiAgICAgICAgICAgIGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLlByZWNvbmRpdGlvbnMuY2hlY2tBcmd1bWVudChSRVNPVVJDRV9QQVRURVJOLm1hdGNoZXIocmVzb3VyY2UpLm1hdGNoZXMoKSwKICAgICAgICAgICAgICAgICJQYXJhbWV0ZXIgcmVzb3VyY2UgbXVzdCBjb25mb3JtIHRvIHRoZSBwYXR0ZXJuICIgKwogICAgICAgICAgICAgICAgIl5wcm9qZWN0cy9bXi9dKy9zZXJ2aWNlQWNjb3VudHMvW14vXSskIik7CiAgICAgICAgICB9CiAgICAgICAgICB0aGlzLnJlc291cmNlID0gcmVzb3VyY2U7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIE9wdGlvbmFsLiBUaGUgcG9saWN5IGZvcm1hdCB2ZXJzaW9uIHRvIGJlIHJldHVybmVkLgogICAgICAgICAqCiAgICAgICAgICogVmFsaWQgdmFsdWVzIGFyZSAwLCAxLCBhbmQgMy4gUmVxdWVzdHMgc3BlY2lmeWluZyBhbiBpbnZhbGlkIHZhbHVlIHdpbGwgYmUgcmVqZWN0ZWQuCiAgICAgICAgICoKICAgICAgICAgKiBSZXF1ZXN0cyBmb3IgcG9saWNpZXMgd2l0aCBhbnkgY29uZGl0aW9uYWwgYmluZGluZ3MgbXVzdCBzcGVjaWZ5IHZlcnNpb24gMy4gUG9saWNpZXMKICAgICAgICAgKiB3aXRob3V0IGFueSBjb25kaXRpb25hbCBiaW5kaW5ncyBtYXkgc3BlY2lmeSBhbnkgdmFsaWQgdmFsdWUgb3IgbGVhdmUgdGhlIGZpZWxkIHVuc2V0LgogICAgICAgICAqLwogICAgICAgIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkoIm9wdGlvbnMucmVxdWVzdGVkUG9saWN5VmVyc2lvbiIpCiAgICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuSW50ZWdlciBvcHRpb25zUmVxdWVzdGVkUG9saWN5VmVyc2lvbjsKCiAgICAgICAgLyoqIE9wdGlvbmFsLiBUaGUgcG9saWN5IGZvcm1hdCB2ZXJzaW9uIHRvIGJlIHJldHVybmVkLgoKICAgICAgIFZhbGlkIHZhbHVlcyBhcmUgMCwgMSwgYW5kIDMuIFJlcXVlc3RzIHNwZWNpZnlpbmcgYW4gaW52YWxpZCB2YWx1ZSB3aWxsIGJlIHJlamVjdGVkLgoKICAgICAgIFJlcXVlc3RzIGZvciBwb2xpY2llcyB3aXRoIGFueSBjb25kaXRpb25hbCBiaW5kaW5ncyBtdXN0IHNwZWNpZnkgdmVyc2lvbiAzLiBQb2xpY2llcyB3aXRob3V0IGFueQogICAgICAgY29uZGl0aW9uYWwgYmluZGluZ3MgbWF5IHNwZWNpZnkgYW55IHZhbGlkIHZhbHVlIG9yIGxlYXZlIHRoZSBmaWVsZCB1bnNldC4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgamF2YS5sYW5nLkludGVnZXIgZ2V0T3B0aW9uc1JlcXVlc3RlZFBvbGljeVZlcnNpb24oKSB7CiAgICAgICAgICByZXR1cm4gb3B0aW9uc1JlcXVlc3RlZFBvbGljeVZlcnNpb247CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiBPcHRpb25hbC4gVGhlIHBvbGljeSBmb3JtYXQgdmVyc2lvbiB0byBiZSByZXR1cm5lZC4KICAgICAgICAgKgogICAgICAgICAqIFZhbGlkIHZhbHVlcyBhcmUgMCwgMSwgYW5kIDMuIFJlcXVlc3RzIHNwZWNpZnlpbmcgYW4gaW52YWxpZCB2YWx1ZSB3aWxsIGJlIHJlamVjdGVkLgogICAgICAgICAqCiAgICAgICAgICogUmVxdWVzdHMgZm9yIHBvbGljaWVzIHdpdGggYW55IGNvbmRpdGlvbmFsIGJpbmRpbmdzIG11c3Qgc3BlY2lmeSB2ZXJzaW9uIDMuIFBvbGljaWVzCiAgICAgICAgICogd2l0aG91dCBhbnkgY29uZGl0aW9uYWwgYmluZGluZ3MgbWF5IHNwZWNpZnkgYW55IHZhbGlkIHZhbHVlIG9yIGxlYXZlIHRoZSBmaWVsZCB1bnNldC4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgR2V0SWFtUG9saWN5IHNldE9wdGlvbnNSZXF1ZXN0ZWRQb2xpY3lWZXJzaW9uKGphdmEubGFuZy5JbnRlZ2VyIG9wdGlvbnNSZXF1ZXN0ZWRQb2xpY3lWZXJzaW9uKSB7CiAgICAgICAgICB0aGlzLm9wdGlvbnNSZXF1ZXN0ZWRQb2xpY3lWZXJzaW9uID0gb3B0aW9uc1JlcXVlc3RlZFBvbGljeVZlcnNpb247CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBHZXRJYW1Qb2xpY3kgc2V0KFN0cmluZyBwYXJhbWV0ZXJOYW1lLCBPYmplY3QgdmFsdWUpIHsKICAgICAgICAgIHJldHVybiAoR2V0SWFtUG9saWN5KSBzdXBlci5zZXQocGFyYW1ldGVyTmFtZSwgdmFsdWUpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogTGlzdHMgU2VydmljZUFjY291bnRzIGZvciBhIHByb2plY3QuCiAgICAgICAqCiAgICAgICAqIENyZWF0ZSBhIHJlcXVlc3QgZm9yIHRoZSBtZXRob2QgInNlcnZpY2VBY2NvdW50cy5saXN0Ii4KICAgICAgICoKICAgICAgICogVGhpcyByZXF1ZXN0IGhvbGRzIHRoZSBwYXJhbWV0ZXJzIG5lZWRlZCBieSB0aGUgaWFtIHNlcnZlci4gIEFmdGVyIHNldHRpbmcgYW55IG9wdGlvbmFsCiAgICAgICAqIHBhcmFtZXRlcnMsIGNhbGwgdGhlIHtAbGluayBMaXN0I2V4ZWN1dGUoKX0gbWV0aG9kIHRvIGludm9rZSB0aGUgcmVtb3RlIG9wZXJhdGlvbi4KICAgICAgICoKICAgICAgICogQHBhcmFtIG5hbWUgUmVxdWlyZWQuIFRoZSByZXNvdXJjZSBuYW1lIG9mIHRoZSBwcm9qZWN0IGFzc29jaWF0ZWQgd2l0aCB0aGUgc2VydmljZQogICAgICBhY2NvdW50cywgc3VjaCBhcyBgcHJvamVjdHMKICAgICAgICogICAgICAgIC9teS1wcm9qZWN0LTEyM2AuCiAgICAgICAqIEByZXR1cm4gdGhlIHJlcXVlc3QKICAgICAgICovCiAgICAgIHB1YmxpYyBMaXN0IGxpc3QoamF2YS5sYW5nLlN0cmluZyBuYW1lKSB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgTGlzdCByZXN1bHQgPSBuZXcgTGlzdChuYW1lKTsKICAgICAgICBpbml0aWFsaXplKHJlc3VsdCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHVibGljIGNsYXNzIExpc3QgZXh0ZW5kcyBJYW1SZXF1ZXN0PGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmlhbS52MS5tb2RlbC5MaXN0U2VydmljZUFjY291bnRzUmVzcG9uc2U+IHsKCiAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFJFU1RfUEFUSCA9ICJ2MS97K25hbWV9L3NlcnZpY2VBY2NvdW50cyI7CgogICAgICAgIHByaXZhdGUgZmluYWwgamF2YS51dGlsLnJlZ2V4LlBhdHRlcm4gTkFNRV9QQVRURVJOID0KICAgICAgICAgICAgamF2YS51dGlsLnJlZ2V4LlBhdHRlcm4uY29tcGlsZSgiXnByb2plY3RzL1teL10rJCIpOwoKICAgICAgICAvKioKICAgICAgICAgKiBMaXN0cyBTZXJ2aWNlQWNjb3VudHMgZm9yIGEgcHJvamVjdC4KICAgICAgICAgKgogICAgICAgICAqIENyZWF0ZSBhIHJlcXVlc3QgZm9yIHRoZSBtZXRob2QgInNlcnZpY2VBY2NvdW50cy5saXN0Ii4KICAgICAgICAgKgogICAgICAgICAqIFRoaXMgcmVxdWVzdCBob2xkcyB0aGUgcGFyYW1ldGVycyBuZWVkZWQgYnkgdGhlIHRoZSBpYW0gc2VydmVyLiAgQWZ0ZXIgc2V0dGluZyBhbnkgb3B0aW9uYWwKICAgICAgICAgKiBwYXJhbWV0ZXJzLCBjYWxsIHRoZSB7QGxpbmsgTGlzdCNleGVjdXRlKCl9IG1ldGhvZCB0byBpbnZva2UgdGhlIHJlbW90ZSBvcGVyYXRpb24uIDxwPiB7QGxpbmsKICAgICAgICAgKiBMaXN0I2luaXRpYWxpemUoY29tLmdvb2dsZS5hcGkuY2xpZW50Lmdvb2dsZWFwaXMuc2VydmljZXMuQWJzdHJhY3RHb29nbGVDbGllbnRSZXF1ZXN0KX0gbXVzdCBiZQogICAgICAgICAqIGNhbGxlZCB0byBpbml0aWFsaXplIHRoaXMgaW5zdGFuY2UgaW1tZWRpYXRlbHkgYWZ0ZXIgaW52b2tpbmcgdGhlIGNvbnN0cnVjdG9yLiA8L3A+CiAgICAgICAgICoKICAgICAgICAgKiBAcGFyYW0gbmFtZSBSZXF1aXJlZC4gVGhlIHJlc291cmNlIG5hbWUgb2YgdGhlIHByb2plY3QgYXNzb2NpYXRlZCB3aXRoIHRoZSBzZXJ2aWNlCiAgICAgIGFjY291bnRzLCBzdWNoIGFzIGBwcm9qZWN0cwogICAgICAgKiAgICAgICAgL215LXByb2plY3QtMTIzYC4KICAgICAgICAgKiBAc2luY2UgMS4xMwogICAgICAgICAqLwogICAgICAgIHByb3RlY3RlZCBMaXN0KGphdmEubGFuZy5TdHJpbmcgbmFtZSkgewogICAgICAgICAgc3VwZXIoSWFtLnRoaXMsICJHRVQiLCBSRVNUX1BBVEgsIG51bGwsIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmlhbS52MS5tb2RlbC5MaXN0U2VydmljZUFjY291bnRzUmVzcG9uc2UuY2xhc3MpOwogICAgICAgICAgdGhpcy5uYW1lID0gY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuUHJlY29uZGl0aW9ucy5jaGVja05vdE51bGwobmFtZSwgIlJlcXVpcmVkIHBhcmFtZXRlciBuYW1lIG11c3QgYmUgc3BlY2lmaWVkLiIpOwogICAgICAgICAgaWYgKCFnZXRTdXBwcmVzc1BhdHRlcm5DaGVja3MoKSkgewogICAgICAgICAgICBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5QcmVjb25kaXRpb25zLmNoZWNrQXJndW1lbnQoTkFNRV9QQVRURVJOLm1hdGNoZXIobmFtZSkubWF0Y2hlcygpLAogICAgICAgICAgICAgICAgIlBhcmFtZXRlciBuYW1lIG11c3QgY29uZm9ybSB0byB0aGUgcGF0dGVybiAiICsKICAgICAgICAgICAgICAgICJecHJvamVjdHMvW14vXSskIik7CiAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5hcGkuY2xpZW50Lmh0dHAuSHR0cFJlc3BvbnNlIGV4ZWN1dGVVc2luZ0hlYWQoKSB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuZXhlY3V0ZVVzaW5nSGVhZCgpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIGNvbS5nb29nbGUuYXBpLmNsaWVudC5odHRwLkh0dHBSZXF1ZXN0IGJ1aWxkSHR0cFJlcXVlc3RVc2luZ0hlYWQoKSB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgICByZXR1cm4gc3VwZXIuYnVpbGRIdHRwUmVxdWVzdFVzaW5nSGVhZCgpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIExpc3Qgc2V0JFhnYWZ2KGphdmEubGFuZy5TdHJpbmcgJFhnYWZ2KSB7CiAgICAgICAgICByZXR1cm4gKExpc3QpIHN1cGVyLnNldCRYZ2FmdigkWGdhZnYpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIExpc3Qgc2V0QWNjZXNzVG9rZW4oamF2YS5sYW5nLlN0cmluZyBhY2Nlc3NUb2tlbikgewogICAgICAgICAgcmV0dXJuIChMaXN0KSBzdXBlci5zZXRBY2Nlc3NUb2tlbihhY2Nlc3NUb2tlbik7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgTGlzdCBzZXRBbHQoamF2YS5sYW5nLlN0cmluZyBhbHQpIHsKICAgICAgICAgIHJldHVybiAoTGlzdCkgc3VwZXIuc2V0QWx0KGFsdCk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgTGlzdCBzZXRDYWxsYmFjayhqYXZhLmxhbmcuU3RyaW5nIGNhbGxiYWNrKSB7CiAgICAgICAgICByZXR1cm4gKExpc3QpIHN1cGVyLnNldENhbGxiYWNrKGNhbGxiYWNrKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBMaXN0IHNldEZpZWxkcyhqYXZhLmxhbmcuU3RyaW5nIGZpZWxkcykgewogICAgICAgICAgcmV0dXJuIChMaXN0KSBzdXBlci5zZXRGaWVsZHMoZmllbGRzKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBMaXN0IHNldEtleShqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgICAgcmV0dXJuIChMaXN0KSBzdXBlci5zZXRLZXkoa2V5KTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBMaXN0IHNldE9hdXRoVG9rZW4oamF2YS5sYW5nLlN0cmluZyBvYXV0aFRva2VuKSB7CiAgICAgICAgICByZXR1cm4gKExpc3QpIHN1cGVyLnNldE9hdXRoVG9rZW4ob2F1dGhUb2tlbik7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgTGlzdCBzZXRQcmV0dHlQcmludChqYXZhLmxhbmcuQm9vbGVhbiBwcmV0dHlQcmludCkgewogICAgICAgICAgcmV0dXJuIChMaXN0KSBzdXBlci5zZXRQcmV0dHlQcmludChwcmV0dHlQcmludCk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgTGlzdCBzZXRRdW90YVVzZXIoamF2YS5sYW5nLlN0cmluZyBxdW90YVVzZXIpIHsKICAgICAgICAgIHJldHVybiAoTGlzdCkgc3VwZXIuc2V0UXVvdGFVc2VyKHF1b3RhVXNlcik7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgTGlzdCBzZXRVcGxvYWRUeXBlKGphdmEubGFuZy5TdHJpbmcgdXBsb2FkVHlwZSkgewogICAgICAgICAgcmV0dXJuIChMaXN0KSBzdXBlci5zZXRVcGxvYWRUeXBlKHVwbG9hZFR5cGUpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIExpc3Qgc2V0VXBsb2FkUHJvdG9jb2woamF2YS5sYW5nLlN0cmluZyB1cGxvYWRQcm90b2NvbCkgewogICAgICAgICAgcmV0dXJuIChMaXN0KSBzdXBlci5zZXRVcGxvYWRQcm90b2NvbCh1cGxvYWRQcm90b2NvbCk7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiBSZXF1aXJlZC4gVGhlIHJlc291cmNlIG5hbWUgb2YgdGhlIHByb2plY3QgYXNzb2NpYXRlZCB3aXRoIHRoZSBzZXJ2aWNlIGFjY291bnRzLCBzdWNoIGFzCiAgICAgICAgICogYHByb2plY3RzL215LXByb2plY3QtMTIzYC4KICAgICAgICAgKi8KICAgICAgICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuU3RyaW5nIG5hbWU7CgogICAgICAgIC8qKiBSZXF1aXJlZC4gVGhlIHJlc291cmNlIG5hbWUgb2YgdGhlIHByb2plY3QgYXNzb2NpYXRlZCB3aXRoIHRoZSBzZXJ2aWNlIGFjY291bnRzLCBzdWNoIGFzIGBwcm9qZWN0cwogICAgICAgL215LXByb2plY3QtMTIzYC4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXROYW1lKCkgewogICAgICAgICAgcmV0dXJuIG5hbWU7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiBSZXF1aXJlZC4gVGhlIHJlc291cmNlIG5hbWUgb2YgdGhlIHByb2plY3QgYXNzb2NpYXRlZCB3aXRoIHRoZSBzZXJ2aWNlIGFjY291bnRzLCBzdWNoIGFzCiAgICAgICAgICogYHByb2plY3RzL215LXByb2plY3QtMTIzYC4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgTGlzdCBzZXROYW1lKGphdmEubGFuZy5TdHJpbmcgbmFtZSkgewogICAgICAgICAgaWYgKCFnZXRTdXBwcmVzc1BhdHRlcm5DaGVja3MoKSkgewogICAgICAgICAgICBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5QcmVjb25kaXRpb25zLmNoZWNrQXJndW1lbnQoTkFNRV9QQVRURVJOLm1hdGNoZXIobmFtZSkubWF0Y2hlcygpLAogICAgICAgICAgICAgICAgIlBhcmFtZXRlciBuYW1lIG11c3QgY29uZm9ybSB0byB0aGUgcGF0dGVybiAiICsKICAgICAgICAgICAgICAgICJecHJvamVjdHMvW14vXSskIik7CiAgICAgICAgICB9CiAgICAgICAgICB0aGlzLm5hbWUgPSBuYW1lOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiBPcHRpb25hbCBsaW1pdCBvbiB0aGUgbnVtYmVyIG9mIHNlcnZpY2UgYWNjb3VudHMgdG8gaW5jbHVkZSBpbiB0aGUgcmVzcG9uc2UuIEZ1cnRoZXIKICAgICAgICAgKiBhY2NvdW50cyBjYW4gc3Vic2VxdWVudGx5IGJlIG9idGFpbmVkIGJ5IGluY2x1ZGluZyB0aGUKICAgICAgICAgKiBMaXN0U2VydmljZUFjY291bnRzUmVzcG9uc2UubmV4dF9wYWdlX3Rva2VuIGluIGEgc3Vic2VxdWVudCByZXF1ZXN0LgogICAgICAgICAqLwogICAgICAgIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICAgICAgICBwcml2YXRlIGphdmEubGFuZy5JbnRlZ2VyIHBhZ2VTaXplOwoKICAgICAgICAvKiogT3B0aW9uYWwgbGltaXQgb24gdGhlIG51bWJlciBvZiBzZXJ2aWNlIGFjY291bnRzIHRvIGluY2x1ZGUgaW4gdGhlIHJlc3BvbnNlLiBGdXJ0aGVyIGFjY291bnRzIGNhbgogICAgICAgc3Vic2VxdWVudGx5IGJlIG9idGFpbmVkIGJ5IGluY2x1ZGluZyB0aGUgTGlzdFNlcnZpY2VBY2NvdW50c1Jlc3BvbnNlLm5leHRfcGFnZV90b2tlbiBpbiBhCiAgICAgICBzdWJzZXF1ZW50IHJlcXVlc3QuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIGphdmEubGFuZy5JbnRlZ2VyIGdldFBhZ2VTaXplKCkgewogICAgICAgICAgcmV0dXJuIHBhZ2VTaXplOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogT3B0aW9uYWwgbGltaXQgb24gdGhlIG51bWJlciBvZiBzZXJ2aWNlIGFjY291bnRzIHRvIGluY2x1ZGUgaW4gdGhlIHJlc3BvbnNlLiBGdXJ0aGVyCiAgICAgICAgICogYWNjb3VudHMgY2FuIHN1YnNlcXVlbnRseSBiZSBvYnRhaW5lZCBieSBpbmNsdWRpbmcgdGhlCiAgICAgICAgICogTGlzdFNlcnZpY2VBY2NvdW50c1Jlc3BvbnNlLm5leHRfcGFnZV90b2tlbiBpbiBhIHN1YnNlcXVlbnQgcmVxdWVzdC4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgTGlzdCBzZXRQYWdlU2l6ZShqYXZhLmxhbmcuSW50ZWdlciBwYWdlU2l6ZSkgewogICAgICAgICAgdGhpcy5wYWdlU2l6ZSA9IHBhZ2VTaXplOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiBPcHRpb25hbCBwYWdpbmF0aW9uIHRva2VuIHJldHVybmVkIGluIGFuIGVhcmxpZXIKICAgICAgICAgKiBMaXN0U2VydmljZUFjY291bnRzUmVzcG9uc2UubmV4dF9wYWdlX3Rva2VuLgogICAgICAgICAqLwogICAgICAgIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICAgICAgICBwcml2YXRlIGphdmEubGFuZy5TdHJpbmcgcGFnZVRva2VuOwoKICAgICAgICAvKiogT3B0aW9uYWwgcGFnaW5hdGlvbiB0b2tlbiByZXR1cm5lZCBpbiBhbiBlYXJsaWVyIExpc3RTZXJ2aWNlQWNjb3VudHNSZXNwb25zZS5uZXh0X3BhZ2VfdG9rZW4uCiAgICAgICAgICovCiAgICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0UGFnZVRva2VuKCkgewogICAgICAgICAgcmV0dXJuIHBhZ2VUb2tlbjsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIE9wdGlvbmFsIHBhZ2luYXRpb24gdG9rZW4gcmV0dXJuZWQgaW4gYW4gZWFybGllcgogICAgICAgICAqIExpc3RTZXJ2aWNlQWNjb3VudHNSZXNwb25zZS5uZXh0X3BhZ2VfdG9rZW4uCiAgICAgICAgICovCiAgICAgICAgcHVibGljIExpc3Qgc2V0UGFnZVRva2VuKGphdmEubGFuZy5TdHJpbmcgcGFnZVRva2VuKSB7CiAgICAgICAgICB0aGlzLnBhZ2VUb2tlbiA9IHBhZ2VUb2tlbjsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIExpc3Qgc2V0KFN0cmluZyBwYXJhbWV0ZXJOYW1lLCBPYmplY3QgdmFsdWUpIHsKICAgICAgICAgIHJldHVybiAoTGlzdCkgc3VwZXIuc2V0KHBhcmFtZXRlck5hbWUsIHZhbHVlKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFBhdGNoZXMgYSBTZXJ2aWNlQWNjb3VudC4KICAgICAgICoKICAgICAgICogQ3VycmVudGx5LCBvbmx5IHRoZSBmb2xsb3dpbmcgZmllbGRzIGFyZSB1cGRhdGFibGU6IGBkaXNwbGF5X25hbWVgIGFuZCBgZGVzY3JpcHRpb25gLgogICAgICAgKgogICAgICAgKiBPbmx5IGZpZWxkcyBzcGVjaWZpZWQgaW4gdGhlIHJlcXVlc3QgYXJlIGd1YXJhbnRlZWQgdG8gYmUgcmV0dXJuZWQgaW4gdGhlIHJlc3BvbnNlLiBPdGhlciBmaWVsZHMKICAgICAgICogaW4gdGhlIHJlc3BvbnNlIG1heSBiZSBlbXB0eS4KICAgICAgICoKICAgICAgICogTm90ZTogVGhlIGZpZWxkIG1hc2sgaXMgcmVxdWlyZWQuCiAgICAgICAqCiAgICAgICAqIENyZWF0ZSBhIHJlcXVlc3QgZm9yIHRoZSBtZXRob2QgInNlcnZpY2VBY2NvdW50cy5wYXRjaCIuCiAgICAgICAqCiAgICAgICAqIFRoaXMgcmVxdWVzdCBob2xkcyB0aGUgcGFyYW1ldGVycyBuZWVkZWQgYnkgdGhlIGlhbSBzZXJ2ZXIuICBBZnRlciBzZXR0aW5nIGFueSBvcHRpb25hbAogICAgICAgKiBwYXJhbWV0ZXJzLCBjYWxsIHRoZSB7QGxpbmsgUGF0Y2gjZXhlY3V0ZSgpfSBtZXRob2QgdG8gaW52b2tlIHRoZSByZW1vdGUgb3BlcmF0aW9uLgogICAgICAgKgogICAgICAgKiBAcGFyYW0gbmFtZSBUaGUgcmVzb3VyY2UgbmFtZSBvZiB0aGUgc2VydmljZSBhY2NvdW50IGluIHRoZSBmb2xsb3dpbmcgZm9ybWF0OgogICAgICAgKiAgICAgICAgYHByb2plY3RzL3tQUk9KRUNUX0lEfS9zZXJ2aWNlQWNjb3VudHMve0FDQ09VTlR9YC4KICAgICAgUmVxdWVzdHMgdXNpbmcgYC1gIGFzIGEgd2lsZGNhcmQgZm9yCiAgICAgICAqICAgICAgICB0aGUgYFBST0pFQ1RfSURgIHdpbGwgaW5mZXIgdGhlCiAgICAgIHByb2plY3QgZnJvbSB0aGUgYGFjY291bnRgIGFuZCB0aGUgYEFDQ09VTlRgIHZhbHVlIGNhbiBiZQogICAgICAgKiAgICAgICAgdGhlIGBlbWFpbGAKICAgICAgYWRkcmVzcyBvciB0aGUgYHVuaXF1ZV9pZGAgb2YgdGhlIHNlcnZpY2UgYWNjb3VudC4KICAgICAgSW4gcmVzcG9uc2VzIHRoZSByZXNvdXJjZQogICAgICAgKiAgICAgICAgbmFtZSB3aWxsIGFsd2F5cyBiZSBpbiB0aGUgZm9ybWF0CiAgICAgIGBwcm9qZWN0cy97UFJPSkVDVF9JRH0vc2VydmljZUFjY291bnRzL3tBQ0NPVU5UfWAuCiAgICAgICAqIEBwYXJhbSBjb250ZW50IHRoZSB7QGxpbmsgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuaWFtLnYxLm1vZGVsLlBhdGNoU2VydmljZUFjY291bnRSZXF1ZXN0fQogICAgICAgKiBAcmV0dXJuIHRoZSByZXF1ZXN0CiAgICAgICAqLwogICAgICBwdWJsaWMgUGF0Y2ggcGF0Y2goamF2YS5sYW5nLlN0cmluZyBuYW1lLCBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5pYW0udjEubW9kZWwuUGF0Y2hTZXJ2aWNlQWNjb3VudFJlcXVlc3QgY29udGVudCkgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIFBhdGNoIHJlc3VsdCA9IG5ldyBQYXRjaChuYW1lLCBjb250ZW50KTsKICAgICAgICBpbml0aWFsaXplKHJlc3VsdCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHVibGljIGNsYXNzIFBhdGNoIGV4dGVuZHMgSWFtUmVxdWVzdDxjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5pYW0udjEubW9kZWwuU2VydmljZUFjY291bnQ+IHsKCiAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFJFU1RfUEFUSCA9ICJ2MS97K25hbWV9IjsKCiAgICAgICAgcHJpdmF0ZSBmaW5hbCBqYXZhLnV0aWwucmVnZXguUGF0dGVybiBOQU1FX1BBVFRFUk4gPQogICAgICAgICAgICBqYXZhLnV0aWwucmVnZXguUGF0dGVybi5jb21waWxlKCJecHJvamVjdHMvW14vXSsvc2VydmljZUFjY291bnRzL1teL10rJCIpOwoKICAgICAgICAvKioKICAgICAgICAgKiBQYXRjaGVzIGEgU2VydmljZUFjY291bnQuCiAgICAgICAgICoKICAgICAgICAgKiBDdXJyZW50bHksIG9ubHkgdGhlIGZvbGxvd2luZyBmaWVsZHMgYXJlIHVwZGF0YWJsZTogYGRpc3BsYXlfbmFtZWAgYW5kIGBkZXNjcmlwdGlvbmAuCiAgICAgICAgICoKICAgICAgICAgKiBPbmx5IGZpZWxkcyBzcGVjaWZpZWQgaW4gdGhlIHJlcXVlc3QgYXJlIGd1YXJhbnRlZWQgdG8gYmUgcmV0dXJuZWQgaW4gdGhlIHJlc3BvbnNlLiBPdGhlcgogICAgICAgICAqIGZpZWxkcyBpbiB0aGUgcmVzcG9uc2UgbWF5IGJlIGVtcHR5LgogICAgICAgICAqCiAgICAgICAgICogTm90ZTogVGhlIGZpZWxkIG1hc2sgaXMgcmVxdWlyZWQuCiAgICAgICAgICoKICAgICAgICAgKiBDcmVhdGUgYSByZXF1ZXN0IGZvciB0aGUgbWV0aG9kICJzZXJ2aWNlQWNjb3VudHMucGF0Y2giLgogICAgICAgICAqCiAgICAgICAgICogVGhpcyByZXF1ZXN0IGhvbGRzIHRoZSBwYXJhbWV0ZXJzIG5lZWRlZCBieSB0aGUgdGhlIGlhbSBzZXJ2ZXIuICBBZnRlciBzZXR0aW5nIGFueSBvcHRpb25hbAogICAgICAgICAqIHBhcmFtZXRlcnMsIGNhbGwgdGhlIHtAbGluayBQYXRjaCNleGVjdXRlKCl9IG1ldGhvZCB0byBpbnZva2UgdGhlIHJlbW90ZSBvcGVyYXRpb24uIDxwPiB7QGxpbmsKICAgICAgICAgKiBQYXRjaCNpbml0aWFsaXplKGNvbS5nb29nbGUuYXBpLmNsaWVudC5nb29nbGVhcGlzLnNlcnZpY2VzLkFic3RyYWN0R29vZ2xlQ2xpZW50UmVxdWVzdCl9IG11c3QKICAgICAgICAgKiBiZSBjYWxsZWQgdG8gaW5pdGlhbGl6ZSB0aGlzIGluc3RhbmNlIGltbWVkaWF0ZWx5IGFmdGVyIGludm9raW5nIHRoZSBjb25zdHJ1Y3Rvci4gPC9wPgogICAgICAgICAqCiAgICAgICAgICogQHBhcmFtIG5hbWUgVGhlIHJlc291cmNlIG5hbWUgb2YgdGhlIHNlcnZpY2UgYWNjb3VudCBpbiB0aGUgZm9sbG93aW5nIGZvcm1hdDoKICAgICAgICogICAgICAgIGBwcm9qZWN0cy97UFJPSkVDVF9JRH0vc2VydmljZUFjY291bnRzL3tBQ0NPVU5UfWAuCiAgICAgIFJlcXVlc3RzIHVzaW5nIGAtYCBhcyBhIHdpbGRjYXJkIGZvcgogICAgICAgKiAgICAgICAgdGhlIGBQUk9KRUNUX0lEYCB3aWxsIGluZmVyIHRoZQogICAgICBwcm9qZWN0IGZyb20gdGhlIGBhY2NvdW50YCBhbmQgdGhlIGBBQ0NPVU5UYCB2YWx1ZSBjYW4gYmUKICAgICAgICogICAgICAgIHRoZSBgZW1haWxgCiAgICAgIGFkZHJlc3Mgb3IgdGhlIGB1bmlxdWVfaWRgIG9mIHRoZSBzZXJ2aWNlIGFjY291bnQuCiAgICAgIEluIHJlc3BvbnNlcyB0aGUgcmVzb3VyY2UKICAgICAgICogICAgICAgIG5hbWUgd2lsbCBhbHdheXMgYmUgaW4gdGhlIGZvcm1hdAogICAgICBgcHJvamVjdHMve1BST0pFQ1RfSUR9L3NlcnZpY2VBY2NvdW50cy97QUNDT1VOVH1gLgogICAgICAgICAqIEBwYXJhbSBjb250ZW50IHRoZSB7QGxpbmsgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuaWFtLnYxLm1vZGVsLlBhdGNoU2VydmljZUFjY291bnRSZXF1ZXN0fQogICAgICAgICAqIEBzaW5jZSAxLjEzCiAgICAgICAgICovCiAgICAgICAgcHJvdGVjdGVkIFBhdGNoKGphdmEubGFuZy5TdHJpbmcgbmFtZSwgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuaWFtLnYxLm1vZGVsLlBhdGNoU2VydmljZUFjY291bnRSZXF1ZXN0IGNvbnRlbnQpIHsKICAgICAgICAgIHN1cGVyKElhbS50aGlzLCAiUEFUQ0giLCBSRVNUX1BBVEgsIGNvbnRlbnQsIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmlhbS52MS5tb2RlbC5TZXJ2aWNlQWNjb3VudC5jbGFzcyk7CiAgICAgICAgICB0aGlzLm5hbWUgPSBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5QcmVjb25kaXRpb25zLmNoZWNrTm90TnVsbChuYW1lLCAiUmVxdWlyZWQgcGFyYW1ldGVyIG5hbWUgbXVzdCBiZSBzcGVjaWZpZWQuIik7CiAgICAgICAgICBpZiAoIWdldFN1cHByZXNzUGF0dGVybkNoZWNrcygpKSB7CiAgICAgICAgICAgIGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLlByZWNvbmRpdGlvbnMuY2hlY2tBcmd1bWVudChOQU1FX1BBVFRFUk4ubWF0Y2hlcihuYW1lKS5tYXRjaGVzKCksCiAgICAgICAgICAgICAgICAiUGFyYW1ldGVyIG5hbWUgbXVzdCBjb25mb3JtIHRvIHRoZSBwYXR0ZXJuICIgKwogICAgICAgICAgICAgICAgIl5wcm9qZWN0cy9bXi9dKy9zZXJ2aWNlQWNjb3VudHMvW14vXSskIik7CiAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgUGF0Y2ggc2V0JFhnYWZ2KGphdmEubGFuZy5TdHJpbmcgJFhnYWZ2KSB7CiAgICAgICAgICByZXR1cm4gKFBhdGNoKSBzdXBlci5zZXQkWGdhZnYoJFhnYWZ2KTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBQYXRjaCBzZXRBY2Nlc3NUb2tlbihqYXZhLmxhbmcuU3RyaW5nIGFjY2Vzc1Rva2VuKSB7CiAgICAgICAgICByZXR1cm4gKFBhdGNoKSBzdXBlci5zZXRBY2Nlc3NUb2tlbihhY2Nlc3NUb2tlbik7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgUGF0Y2ggc2V0QWx0KGphdmEubGFuZy5TdHJpbmcgYWx0KSB7CiAgICAgICAgICByZXR1cm4gKFBhdGNoKSBzdXBlci5zZXRBbHQoYWx0KTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBQYXRjaCBzZXRDYWxsYmFjayhqYXZhLmxhbmcuU3RyaW5nIGNhbGxiYWNrKSB7CiAgICAgICAgICByZXR1cm4gKFBhdGNoKSBzdXBlci5zZXRDYWxsYmFjayhjYWxsYmFjayk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgUGF0Y2ggc2V0RmllbGRzKGphdmEubGFuZy5TdHJpbmcgZmllbGRzKSB7CiAgICAgICAgICByZXR1cm4gKFBhdGNoKSBzdXBlci5zZXRGaWVsZHMoZmllbGRzKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBQYXRjaCBzZXRLZXkoamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICAgIHJldHVybiAoUGF0Y2gpIHN1cGVyLnNldEtleShrZXkpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFBhdGNoIHNldE9hdXRoVG9rZW4oamF2YS5sYW5nLlN0cmluZyBvYXV0aFRva2VuKSB7CiAgICAgICAgICByZXR1cm4gKFBhdGNoKSBzdXBlci5zZXRPYXV0aFRva2VuKG9hdXRoVG9rZW4pOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFBhdGNoIHNldFByZXR0eVByaW50KGphdmEubGFuZy5Cb29sZWFuIHByZXR0eVByaW50KSB7CiAgICAgICAgICByZXR1cm4gKFBhdGNoKSBzdXBlci5zZXRQcmV0dHlQcmludChwcmV0dHlQcmludCk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgUGF0Y2ggc2V0UXVvdGFVc2VyKGphdmEubGFuZy5TdHJpbmcgcXVvdGFVc2VyKSB7CiAgICAgICAgICByZXR1cm4gKFBhdGNoKSBzdXBlci5zZXRRdW90YVVzZXIocXVvdGFVc2VyKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBQYXRjaCBzZXRVcGxvYWRUeXBlKGphdmEubGFuZy5TdHJpbmcgdXBsb2FkVHlwZSkgewogICAgICAgICAgcmV0dXJuIChQYXRjaCkgc3VwZXIuc2V0VXBsb2FkVHlwZSh1cGxvYWRUeXBlKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBQYXRjaCBzZXRVcGxvYWRQcm90b2NvbChqYXZhLmxhbmcuU3RyaW5nIHVwbG9hZFByb3RvY29sKSB7CiAgICAgICAgICByZXR1cm4gKFBhdGNoKSBzdXBlci5zZXRVcGxvYWRQcm90b2NvbCh1cGxvYWRQcm90b2NvbCk7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiBUaGUgcmVzb3VyY2UgbmFtZSBvZiB0aGUgc2VydmljZSBhY2NvdW50IGluIHRoZSBmb2xsb3dpbmcgZm9ybWF0OgogICAgICAgICAqIGBwcm9qZWN0cy97UFJPSkVDVF9JRH0vc2VydmljZUFjY291bnRzL3tBQ0NPVU5UfWAuCiAgICAgICAgICoKICAgICAgICAgKiBSZXF1ZXN0cyB1c2luZyBgLWAgYXMgYSB3aWxkY2FyZCBmb3IgdGhlIGBQUk9KRUNUX0lEYCB3aWxsIGluZmVyIHRoZSBwcm9qZWN0IGZyb20gdGhlCiAgICAgICAgICogYGFjY291bnRgIGFuZCB0aGUgYEFDQ09VTlRgIHZhbHVlIGNhbiBiZSB0aGUgYGVtYWlsYCBhZGRyZXNzIG9yIHRoZSBgdW5pcXVlX2lkYCBvZiB0aGUKICAgICAgICAgKiBzZXJ2aWNlIGFjY291bnQuCiAgICAgICAgICoKICAgICAgICAgKiBJbiByZXNwb25zZXMgdGhlIHJlc291cmNlIG5hbWUgd2lsbCBhbHdheXMgYmUgaW4gdGhlIGZvcm1hdAogICAgICAgICAqIGBwcm9qZWN0cy97UFJPSkVDVF9JRH0vc2VydmljZUFjY291bnRzL3tBQ0NPVU5UfWAuCiAgICAgICAgICovCiAgICAgICAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogICAgICAgIHByaXZhdGUgamF2YS5sYW5nLlN0cmluZyBuYW1lOwoKICAgICAgICAvKiogVGhlIHJlc291cmNlIG5hbWUgb2YgdGhlIHNlcnZpY2UgYWNjb3VudCBpbiB0aGUgZm9sbG93aW5nIGZvcm1hdDoKICAgICAgIGBwcm9qZWN0cy97UFJPSkVDVF9JRH0vc2VydmljZUFjY291bnRzL3tBQ0NPVU5UfWAuCgogICAgICAgUmVxdWVzdHMgdXNpbmcgYC1gIGFzIGEgd2lsZGNhcmQgZm9yIHRoZSBgUFJPSkVDVF9JRGAgd2lsbCBpbmZlciB0aGUgcHJvamVjdCBmcm9tIHRoZSBgYWNjb3VudGAgYW5kCiAgICAgICB0aGUgYEFDQ09VTlRgIHZhbHVlIGNhbiBiZSB0aGUgYGVtYWlsYCBhZGRyZXNzIG9yIHRoZSBgdW5pcXVlX2lkYCBvZiB0aGUgc2VydmljZSBhY2NvdW50LgoKICAgICAgIEluIHJlc3BvbnNlcyB0aGUgcmVzb3VyY2UgbmFtZSB3aWxsIGFsd2F5cyBiZSBpbiB0aGUgZm9ybWF0CiAgICAgICBgcHJvamVjdHMve1BST0pFQ1RfSUR9L3NlcnZpY2VBY2NvdW50cy97QUNDT1VOVH1gLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldE5hbWUoKSB7CiAgICAgICAgICByZXR1cm4gbmFtZTsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIFRoZSByZXNvdXJjZSBuYW1lIG9mIHRoZSBzZXJ2aWNlIGFjY291bnQgaW4gdGhlIGZvbGxvd2luZyBmb3JtYXQ6CiAgICAgICAgICogYHByb2plY3RzL3tQUk9KRUNUX0lEfS9zZXJ2aWNlQWNjb3VudHMve0FDQ09VTlR9YC4KICAgICAgICAgKgogICAgICAgICAqIFJlcXVlc3RzIHVzaW5nIGAtYCBhcyBhIHdpbGRjYXJkIGZvciB0aGUgYFBST0pFQ1RfSURgIHdpbGwgaW5mZXIgdGhlIHByb2plY3QgZnJvbSB0aGUKICAgICAgICAgKiBgYWNjb3VudGAgYW5kIHRoZSBgQUNDT1VOVGAgdmFsdWUgY2FuIGJlIHRoZSBgZW1haWxgIGFkZHJlc3Mgb3IgdGhlIGB1bmlxdWVfaWRgIG9mIHRoZQogICAgICAgICAqIHNlcnZpY2UgYWNjb3VudC4KICAgICAgICAgKgogICAgICAgICAqIEluIHJlc3BvbnNlcyB0aGUgcmVzb3VyY2UgbmFtZSB3aWxsIGFsd2F5cyBiZSBpbiB0aGUgZm9ybWF0CiAgICAgICAgICogYHByb2plY3RzL3tQUk9KRUNUX0lEfS9zZXJ2aWNlQWNjb3VudHMve0FDQ09VTlR9YC4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgUGF0Y2ggc2V0TmFtZShqYXZhLmxhbmcuU3RyaW5nIG5hbWUpIHsKICAgICAgICAgIGlmICghZ2V0U3VwcHJlc3NQYXR0ZXJuQ2hlY2tzKCkpIHsKICAgICAgICAgICAgY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuUHJlY29uZGl0aW9ucy5jaGVja0FyZ3VtZW50KE5BTUVfUEFUVEVSTi5tYXRjaGVyKG5hbWUpLm1hdGNoZXMoKSwKICAgICAgICAgICAgICAgICJQYXJhbWV0ZXIgbmFtZSBtdXN0IGNvbmZvcm0gdG8gdGhlIHBhdHRlcm4gIiArCiAgICAgICAgICAgICAgICAiXnByb2plY3RzL1teL10rL3NlcnZpY2VBY2NvdW50cy9bXi9dKyQiKTsKICAgICAgICAgIH0KICAgICAgICAgIHRoaXMubmFtZSA9IG5hbWU7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBQYXRjaCBzZXQoU3RyaW5nIHBhcmFtZXRlck5hbWUsIE9iamVjdCB2YWx1ZSkgewogICAgICAgICAgcmV0dXJuIChQYXRjaCkgc3VwZXIuc2V0KHBhcmFtZXRlck5hbWUsIHZhbHVlKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFNldHMgdGhlIENsb3VkIElBTSBhY2Nlc3MgY29udHJvbCBwb2xpY3kgZm9yIGEgU2VydmljZUFjY291bnQuCiAgICAgICAqCiAgICAgICAqIE5vdGU6IFNlcnZpY2UgYWNjb3VudHMgYXJlIGJvdGggW3Jlc291cmNlcyBhbmQgaWRlbnRpdGllc10oL2lhbS9kb2NzL3NlcnZpY2UtCiAgICAgICAqIGFjY291bnRzI3NlcnZpY2VfYWNjb3VudF9wZXJtaXNzaW9ucykuIFRoaXMgbWV0aG9kIHRyZWF0cyB0aGUgc2VydmljZSBhY2NvdW50IGFzIGEgcmVzb3VyY2UuIFVzZQogICAgICAgKiBpdCB0byBncmFudCBtZW1iZXJzIGFjY2VzcyB0byB0aGUgc2VydmljZSBhY2NvdW50LCBzdWNoIGFzIHdoZW4gdGhleSBuZWVkIHRvIGltcGVyc29uYXRlIGl0LgogICAgICAgKgogICAgICAgKiBUaGlzIG1ldGhvZCBkb2VzIG5vdCBncmFudCB0aGUgc2VydmljZSBhY2NvdW50IGFjY2VzcyB0byBvdGhlciByZXNvdXJjZXMsIHN1Y2ggYXMgcHJvamVjdHMuIFRvCiAgICAgICAqIGdyYW50IGEgc2VydmljZSBhY2NvdW50IGFjY2VzcyB0byByZXNvdXJjZXMsIGluY2x1ZGUgdGhlIHNlcnZpY2UgYWNjb3VudCBpbiB0aGUgQ2xvdWQgSUFNIHBvbGljeQogICAgICAgKiBmb3IgdGhlIGRlc2lyZWQgcmVzb3VyY2UsIHRoZW4gY2FsbCB0aGUgYXBwcm9wcmlhdGUgYHNldElhbVBvbGljeWAgbWV0aG9kIG9uIHRoZSB0YXJnZXQgcmVzb3VyY2UuCiAgICAgICAqIEZvciBleGFtcGxlLCB0byBncmFudCBhIHNlcnZpY2UgYWNjb3VudCBhY2Nlc3MgdG8gYSBwcm9qZWN0LCBjYWxsIHRoZSBbcHJvamVjdHMuc2V0SWFtUG9saWN5CiAgICAgICAqIF0oL3Jlc291cmNlLW1hbmFnZXIvcmVmZXJlbmNlL3Jlc3QvdjEvcHJvamVjdHMvc2V0SWFtUG9saWN5KSBtZXRob2QuCiAgICAgICAqCiAgICAgICAqIENyZWF0ZSBhIHJlcXVlc3QgZm9yIHRoZSBtZXRob2QgInNlcnZpY2VBY2NvdW50cy5zZXRJYW1Qb2xpY3kiLgogICAgICAgKgogICAgICAgKiBUaGlzIHJlcXVlc3QgaG9sZHMgdGhlIHBhcmFtZXRlcnMgbmVlZGVkIGJ5IHRoZSBpYW0gc2VydmVyLiAgQWZ0ZXIgc2V0dGluZyBhbnkgb3B0aW9uYWwKICAgICAgICogcGFyYW1ldGVycywgY2FsbCB0aGUge0BsaW5rIFNldElhbVBvbGljeSNleGVjdXRlKCl9IG1ldGhvZCB0byBpbnZva2UgdGhlIHJlbW90ZSBvcGVyYXRpb24uCiAgICAgICAqCiAgICAgICAqIEBwYXJhbSByZXNvdXJjZSBSRVFVSVJFRDogVGhlIHJlc291cmNlIGZvciB3aGljaCB0aGUgcG9saWN5IGlzIGJlaW5nIHNwZWNpZmllZC4KICAgICAgU2VlIHRoZSBvcGVyYXRpb24gZG9jdW1lbnRhdGlvbiBmb3IKICAgICAgICogICAgICAgIHRoZSBhcHByb3ByaWF0ZSB2YWx1ZSBmb3IgdGhpcyBmaWVsZC4KICAgICAgICogQHBhcmFtIGNvbnRlbnQgdGhlIHtAbGluayBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5pYW0udjEubW9kZWwuU2V0SWFtUG9saWN5UmVxdWVzdH0KICAgICAgICogQHJldHVybiB0aGUgcmVxdWVzdAogICAgICAgKi8KICAgICAgcHVibGljIFNldElhbVBvbGljeSBzZXRJYW1Qb2xpY3koamF2YS5sYW5nLlN0cmluZyByZXNvdXJjZSwgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuaWFtLnYxLm1vZGVsLlNldElhbVBvbGljeVJlcXVlc3QgY29udGVudCkgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIFNldElhbVBvbGljeSByZXN1bHQgPSBuZXcgU2V0SWFtUG9saWN5KHJlc291cmNlLCBjb250ZW50KTsKICAgICAgICBpbml0aWFsaXplKHJlc3VsdCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHVibGljIGNsYXNzIFNldElhbVBvbGljeSBleHRlbmRzIElhbVJlcXVlc3Q8Y29tLmdvb2dsZS5hcGkuc2VydmljZXMuaWFtLnYxLm1vZGVsLlBvbGljeT4gewoKICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgUkVTVF9QQVRIID0gInYxL3srcmVzb3VyY2V9OnNldElhbVBvbGljeSI7CgogICAgICAgIHByaXZhdGUgZmluYWwgamF2YS51dGlsLnJlZ2V4LlBhdHRlcm4gUkVTT1VSQ0VfUEFUVEVSTiA9CiAgICAgICAgICAgIGphdmEudXRpbC5yZWdleC5QYXR0ZXJuLmNvbXBpbGUoIl5wcm9qZWN0cy9bXi9dKy9zZXJ2aWNlQWNjb3VudHMvW14vXSskIik7CgogICAgICAgIC8qKgogICAgICAgICAqIFNldHMgdGhlIENsb3VkIElBTSBhY2Nlc3MgY29udHJvbCBwb2xpY3kgZm9yIGEgU2VydmljZUFjY291bnQuCiAgICAgICAgICoKICAgICAgICAgKiBOb3RlOiBTZXJ2aWNlIGFjY291bnRzIGFyZSBib3RoIFtyZXNvdXJjZXMgYW5kIGlkZW50aXRpZXNdKC9pYW0vZG9jcy9zZXJ2aWNlLQogICAgICAgICAqIGFjY291bnRzI3NlcnZpY2VfYWNjb3VudF9wZXJtaXNzaW9ucykuIFRoaXMgbWV0aG9kIHRyZWF0cyB0aGUgc2VydmljZSBhY2NvdW50IGFzIGEgcmVzb3VyY2UuCiAgICAgICAgICogVXNlIGl0IHRvIGdyYW50IG1lbWJlcnMgYWNjZXNzIHRvIHRoZSBzZXJ2aWNlIGFjY291bnQsIHN1Y2ggYXMgd2hlbiB0aGV5IG5lZWQgdG8gaW1wZXJzb25hdGUKICAgICAgICAgKiBpdC4KICAgICAgICAgKgogICAgICAgICAqIFRoaXMgbWV0aG9kIGRvZXMgbm90IGdyYW50IHRoZSBzZXJ2aWNlIGFjY291bnQgYWNjZXNzIHRvIG90aGVyIHJlc291cmNlcywgc3VjaCBhcyBwcm9qZWN0cy4gVG8KICAgICAgICAgKiBncmFudCBhIHNlcnZpY2UgYWNjb3VudCBhY2Nlc3MgdG8gcmVzb3VyY2VzLCBpbmNsdWRlIHRoZSBzZXJ2aWNlIGFjY291bnQgaW4gdGhlIENsb3VkIElBTQogICAgICAgICAqIHBvbGljeSBmb3IgdGhlIGRlc2lyZWQgcmVzb3VyY2UsIHRoZW4gY2FsbCB0aGUgYXBwcm9wcmlhdGUgYHNldElhbVBvbGljeWAgbWV0aG9kIG9uIHRoZSB0YXJnZXQKICAgICAgICAgKiByZXNvdXJjZS4gRm9yIGV4YW1wbGUsIHRvIGdyYW50IGEgc2VydmljZSBhY2NvdW50IGFjY2VzcyB0byBhIHByb2plY3QsIGNhbGwgdGhlCiAgICAgICAgICogW3Byb2plY3RzLnNldElhbVBvbGljeV0oL3Jlc291cmNlLW1hbmFnZXIvcmVmZXJlbmNlL3Jlc3QvdjEvcHJvamVjdHMvc2V0SWFtUG9saWN5KSBtZXRob2QuCiAgICAgICAgICoKICAgICAgICAgKiBDcmVhdGUgYSByZXF1ZXN0IGZvciB0aGUgbWV0aG9kICJzZXJ2aWNlQWNjb3VudHMuc2V0SWFtUG9saWN5Ii4KICAgICAgICAgKgogICAgICAgICAqIFRoaXMgcmVxdWVzdCBob2xkcyB0aGUgcGFyYW1ldGVycyBuZWVkZWQgYnkgdGhlIHRoZSBpYW0gc2VydmVyLiAgQWZ0ZXIgc2V0dGluZyBhbnkgb3B0aW9uYWwKICAgICAgICAgKiBwYXJhbWV0ZXJzLCBjYWxsIHRoZSB7QGxpbmsgU2V0SWFtUG9saWN5I2V4ZWN1dGUoKX0gbWV0aG9kIHRvIGludm9rZSB0aGUgcmVtb3RlIG9wZXJhdGlvbi4gPHA+CiAgICAgICAgICoge0BsaW5rCiAgICAgICAgICogU2V0SWFtUG9saWN5I2luaXRpYWxpemUoY29tLmdvb2dsZS5hcGkuY2xpZW50Lmdvb2dsZWFwaXMuc2VydmljZXMuQWJzdHJhY3RHb29nbGVDbGllbnRSZXF1ZXN0KX0KICAgICAgICAgKiBtdXN0IGJlIGNhbGxlZCB0byBpbml0aWFsaXplIHRoaXMgaW5zdGFuY2UgaW1tZWRpYXRlbHkgYWZ0ZXIgaW52b2tpbmcgdGhlIGNvbnN0cnVjdG9yLiA8L3A+CiAgICAgICAgICoKICAgICAgICAgKiBAcGFyYW0gcmVzb3VyY2UgUkVRVUlSRUQ6IFRoZSByZXNvdXJjZSBmb3Igd2hpY2ggdGhlIHBvbGljeSBpcyBiZWluZyBzcGVjaWZpZWQuCiAgICAgIFNlZSB0aGUgb3BlcmF0aW9uIGRvY3VtZW50YXRpb24gZm9yCiAgICAgICAqICAgICAgICB0aGUgYXBwcm9wcmlhdGUgdmFsdWUgZm9yIHRoaXMgZmllbGQuCiAgICAgICAgICogQHBhcmFtIGNvbnRlbnQgdGhlIHtAbGluayBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5pYW0udjEubW9kZWwuU2V0SWFtUG9saWN5UmVxdWVzdH0KICAgICAgICAgKiBAc2luY2UgMS4xMwogICAgICAgICAqLwogICAgICAgIHByb3RlY3RlZCBTZXRJYW1Qb2xpY3koamF2YS5sYW5nLlN0cmluZyByZXNvdXJjZSwgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuaWFtLnYxLm1vZGVsLlNldElhbVBvbGljeVJlcXVlc3QgY29udGVudCkgewogICAgICAgICAgc3VwZXIoSWFtLnRoaXMsICJQT1NUIiwgUkVTVF9QQVRILCBjb250ZW50LCBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5pYW0udjEubW9kZWwuUG9saWN5LmNsYXNzKTsKICAgICAgICAgIHRoaXMucmVzb3VyY2UgPSBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5QcmVjb25kaXRpb25zLmNoZWNrTm90TnVsbChyZXNvdXJjZSwgIlJlcXVpcmVkIHBhcmFtZXRlciByZXNvdXJjZSBtdXN0IGJlIHNwZWNpZmllZC4iKTsKICAgICAgICAgIGlmICghZ2V0U3VwcHJlc3NQYXR0ZXJuQ2hlY2tzKCkpIHsKICAgICAgICAgICAgY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuUHJlY29uZGl0aW9ucy5jaGVja0FyZ3VtZW50KFJFU09VUkNFX1BBVFRFUk4ubWF0Y2hlcihyZXNvdXJjZSkubWF0Y2hlcygpLAogICAgICAgICAgICAgICAgIlBhcmFtZXRlciByZXNvdXJjZSBtdXN0IGNvbmZvcm0gdG8gdGhlIHBhdHRlcm4gIiArCiAgICAgICAgICAgICAgICAiXnByb2plY3RzL1teL10rL3NlcnZpY2VBY2NvdW50cy9bXi9dKyQiKTsKICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBTZXRJYW1Qb2xpY3kgc2V0JFhnYWZ2KGphdmEubGFuZy5TdHJpbmcgJFhnYWZ2KSB7CiAgICAgICAgICByZXR1cm4gKFNldElhbVBvbGljeSkgc3VwZXIuc2V0JFhnYWZ2KCRYZ2Fmdik7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgU2V0SWFtUG9saWN5IHNldEFjY2Vzc1Rva2VuKGphdmEubGFuZy5TdHJpbmcgYWNjZXNzVG9rZW4pIHsKICAgICAgICAgIHJldHVybiAoU2V0SWFtUG9saWN5KSBzdXBlci5zZXRBY2Nlc3NUb2tlbihhY2Nlc3NUb2tlbik7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgU2V0SWFtUG9saWN5IHNldEFsdChqYXZhLmxhbmcuU3RyaW5nIGFsdCkgewogICAgICAgICAgcmV0dXJuIChTZXRJYW1Qb2xpY3kpIHN1cGVyLnNldEFsdChhbHQpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFNldElhbVBvbGljeSBzZXRDYWxsYmFjayhqYXZhLmxhbmcuU3RyaW5nIGNhbGxiYWNrKSB7CiAgICAgICAgICByZXR1cm4gKFNldElhbVBvbGljeSkgc3VwZXIuc2V0Q2FsbGJhY2soY2FsbGJhY2spOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFNldElhbVBvbGljeSBzZXRGaWVsZHMoamF2YS5sYW5nLlN0cmluZyBmaWVsZHMpIHsKICAgICAgICAgIHJldHVybiAoU2V0SWFtUG9saWN5KSBzdXBlci5zZXRGaWVsZHMoZmllbGRzKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBTZXRJYW1Qb2xpY3kgc2V0S2V5KGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgICByZXR1cm4gKFNldElhbVBvbGljeSkgc3VwZXIuc2V0S2V5KGtleSk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgU2V0SWFtUG9saWN5IHNldE9hdXRoVG9rZW4oamF2YS5sYW5nLlN0cmluZyBvYXV0aFRva2VuKSB7CiAgICAgICAgICByZXR1cm4gKFNldElhbVBvbGljeSkgc3VwZXIuc2V0T2F1dGhUb2tlbihvYXV0aFRva2VuKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBTZXRJYW1Qb2xpY3kgc2V0UHJldHR5UHJpbnQoamF2YS5sYW5nLkJvb2xlYW4gcHJldHR5UHJpbnQpIHsKICAgICAgICAgIHJldHVybiAoU2V0SWFtUG9saWN5KSBzdXBlci5zZXRQcmV0dHlQcmludChwcmV0dHlQcmludCk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgU2V0SWFtUG9saWN5IHNldFF1b3RhVXNlcihqYXZhLmxhbmcuU3RyaW5nIHF1b3RhVXNlcikgewogICAgICAgICAgcmV0dXJuIChTZXRJYW1Qb2xpY3kpIHN1cGVyLnNldFF1b3RhVXNlcihxdW90YVVzZXIpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFNldElhbVBvbGljeSBzZXRVcGxvYWRUeXBlKGphdmEubGFuZy5TdHJpbmcgdXBsb2FkVHlwZSkgewogICAgICAgICAgcmV0dXJuIChTZXRJYW1Qb2xpY3kpIHN1cGVyLnNldFVwbG9hZFR5cGUodXBsb2FkVHlwZSk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgU2V0SWFtUG9saWN5IHNldFVwbG9hZFByb3RvY29sKGphdmEubGFuZy5TdHJpbmcgdXBsb2FkUHJvdG9jb2wpIHsKICAgICAgICAgIHJldHVybiAoU2V0SWFtUG9saWN5KSBzdXBlci5zZXRVcGxvYWRQcm90b2NvbCh1cGxvYWRQcm90b2NvbCk7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiBSRVFVSVJFRDogVGhlIHJlc291cmNlIGZvciB3aGljaCB0aGUgcG9saWN5IGlzIGJlaW5nIHNwZWNpZmllZC4gU2VlIHRoZSBvcGVyYXRpb24KICAgICAgICAgKiBkb2N1bWVudGF0aW9uIGZvciB0aGUgYXBwcm9wcmlhdGUgdmFsdWUgZm9yIHRoaXMgZmllbGQuCiAgICAgICAgICovCiAgICAgICAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogICAgICAgIHByaXZhdGUgamF2YS5sYW5nLlN0cmluZyByZXNvdXJjZTsKCiAgICAgICAgLyoqIFJFUVVJUkVEOiBUaGUgcmVzb3VyY2UgZm9yIHdoaWNoIHRoZSBwb2xpY3kgaXMgYmVpbmcgc3BlY2lmaWVkLiBTZWUgdGhlIG9wZXJhdGlvbiBkb2N1bWVudGF0aW9uIGZvcgogICAgICAgdGhlIGFwcHJvcHJpYXRlIHZhbHVlIGZvciB0aGlzIGZpZWxkLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFJlc291cmNlKCkgewogICAgICAgICAgcmV0dXJuIHJlc291cmNlOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogUkVRVUlSRUQ6IFRoZSByZXNvdXJjZSBmb3Igd2hpY2ggdGhlIHBvbGljeSBpcyBiZWluZyBzcGVjaWZpZWQuIFNlZSB0aGUgb3BlcmF0aW9uCiAgICAgICAgICogZG9jdW1lbnRhdGlvbiBmb3IgdGhlIGFwcHJvcHJpYXRlIHZhbHVlIGZvciB0aGlzIGZpZWxkLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBTZXRJYW1Qb2xpY3kgc2V0UmVzb3VyY2UoamF2YS5sYW5nLlN0cmluZyByZXNvdXJjZSkgewogICAgICAgICAgaWYgKCFnZXRTdXBwcmVzc1BhdHRlcm5DaGVja3MoKSkgewogICAgICAgICAgICBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5QcmVjb25kaXRpb25zLmNoZWNrQXJndW1lbnQoUkVTT1VSQ0VfUEFUVEVSTi5tYXRjaGVyKHJlc291cmNlKS5tYXRjaGVzKCksCiAgICAgICAgICAgICAgICAiUGFyYW1ldGVyIHJlc291cmNlIG11c3QgY29uZm9ybSB0byB0aGUgcGF0dGVybiAiICsKICAgICAgICAgICAgICAgICJecHJvamVjdHMvW14vXSsvc2VydmljZUFjY291bnRzL1teL10rJCIpOwogICAgICAgICAgfQogICAgICAgICAgdGhpcy5yZXNvdXJjZSA9IHJlc291cmNlOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgU2V0SWFtUG9saWN5IHNldChTdHJpbmcgcGFyYW1ldGVyTmFtZSwgT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgICByZXR1cm4gKFNldElhbVBvbGljeSkgc3VwZXIuc2V0KHBhcmFtZXRlck5hbWUsIHZhbHVlKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqICoqTm90ZSoqOiBUaGlzIG1ldGhvZCBpcyBpbiB0aGUgcHJvY2VzcyBvZiBiZWluZyBkZXByZWNhdGVkLiBDYWxsIHRoZQogICAgICAgKiBbYHNpZ25CbG9iKClgXSgvaWFtL2NyZWRlbnRpYWxzL3JlZmVyZW5jZS9yZXN0L3YxL3Byb2plY3RzLnNlcnZpY2VBY2NvdW50cy9zaWduQmxvYikgbWV0aG9kIG9mCiAgICAgICAqIHRoZSBDbG91ZCBJQU0gU2VydmljZSBBY2NvdW50IENyZWRlbnRpYWxzIEFQSSBpbnN0ZWFkLgogICAgICAgKgogICAgICAgKiBTaWducyBhIGJsb2IgdXNpbmcgYSBzZXJ2aWNlIGFjY291bnQncyBzeXN0ZW0tbWFuYWdlZCBwcml2YXRlIGtleS4KICAgICAgICoKICAgICAgICogQ3JlYXRlIGEgcmVxdWVzdCBmb3IgdGhlIG1ldGhvZCAic2VydmljZUFjY291bnRzLnNpZ25CbG9iIi4KICAgICAgICoKICAgICAgICogVGhpcyByZXF1ZXN0IGhvbGRzIHRoZSBwYXJhbWV0ZXJzIG5lZWRlZCBieSB0aGUgaWFtIHNlcnZlci4gIEFmdGVyIHNldHRpbmcgYW55IG9wdGlvbmFsCiAgICAgICAqIHBhcmFtZXRlcnMsIGNhbGwgdGhlIHtAbGluayBTaWduQmxvYiNleGVjdXRlKCl9IG1ldGhvZCB0byBpbnZva2UgdGhlIHJlbW90ZSBvcGVyYXRpb24uCiAgICAgICAqCiAgICAgICAqIEBwYXJhbSBuYW1lIFJlcXVpcmVkLiBUaGUgcmVzb3VyY2UgbmFtZSBvZiB0aGUgc2VydmljZSBhY2NvdW50IGluIHRoZSBmb2xsb3dpbmcgZm9ybWF0OgogICAgICAgKiAgICAgICAgYHByb2plY3RzL3tQUk9KRUNUX0lEfS9zZXJ2aWNlQWNjb3VudHMve0FDQ09VTlR9YC4KICAgICAgVXNpbmcgYC1gIGFzIGEgd2lsZGNhcmQgZm9yIHRoZQogICAgICAgKiAgICAgICAgYFBST0pFQ1RfSURgIHdpbGwgaW5mZXIgdGhlIHByb2plY3QgZnJvbQogICAgICB0aGUgYWNjb3VudC4gVGhlIGBBQ0NPVU5UYCB2YWx1ZSBjYW4gYmUgdGhlCiAgICAgICAqICAgICAgICBgZW1haWxgIGFkZHJlc3Mgb3IgdGhlCiAgICAgIGB1bmlxdWVfaWRgIG9mIHRoZSBzZXJ2aWNlIGFjY291bnQuCiAgICAgICAqIEBwYXJhbSBjb250ZW50IHRoZSB7QGxpbmsgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuaWFtLnYxLm1vZGVsLlNpZ25CbG9iUmVxdWVzdH0KICAgICAgICogQHJldHVybiB0aGUgcmVxdWVzdAogICAgICAgKi8KICAgICAgcHVibGljIFNpZ25CbG9iIHNpZ25CbG9iKGphdmEubGFuZy5TdHJpbmcgbmFtZSwgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuaWFtLnYxLm1vZGVsLlNpZ25CbG9iUmVxdWVzdCBjb250ZW50KSB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgU2lnbkJsb2IgcmVzdWx0ID0gbmV3IFNpZ25CbG9iKG5hbWUsIGNvbnRlbnQpOwogICAgICAgIGluaXRpYWxpemUocmVzdWx0KTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBwdWJsaWMgY2xhc3MgU2lnbkJsb2IgZXh0ZW5kcyBJYW1SZXF1ZXN0PGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmlhbS52MS5tb2RlbC5TaWduQmxvYlJlc3BvbnNlPiB7CgogICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBSRVNUX1BBVEggPSAidjEveytuYW1lfTpzaWduQmxvYiI7CgogICAgICAgIHByaXZhdGUgZmluYWwgamF2YS51dGlsLnJlZ2V4LlBhdHRlcm4gTkFNRV9QQVRURVJOID0KICAgICAgICAgICAgamF2YS51dGlsLnJlZ2V4LlBhdHRlcm4uY29tcGlsZSgiXnByb2plY3RzL1teL10rL3NlcnZpY2VBY2NvdW50cy9bXi9dKyQiKTsKCiAgICAgICAgLyoqCiAgICAgICAgICogKipOb3RlKio6IFRoaXMgbWV0aG9kIGlzIGluIHRoZSBwcm9jZXNzIG9mIGJlaW5nIGRlcHJlY2F0ZWQuIENhbGwgdGhlCiAgICAgICAgICogW2BzaWduQmxvYigpYF0oL2lhbS9jcmVkZW50aWFscy9yZWZlcmVuY2UvcmVzdC92MS9wcm9qZWN0cy5zZXJ2aWNlQWNjb3VudHMvc2lnbkJsb2IpIG1ldGhvZCBvZgogICAgICAgICAqIHRoZSBDbG91ZCBJQU0gU2VydmljZSBBY2NvdW50IENyZWRlbnRpYWxzIEFQSSBpbnN0ZWFkLgogICAgICAgICAqCiAgICAgICAgICogU2lnbnMgYSBibG9iIHVzaW5nIGEgc2VydmljZSBhY2NvdW50J3Mgc3lzdGVtLW1hbmFnZWQgcHJpdmF0ZSBrZXkuCiAgICAgICAgICoKICAgICAgICAgKiBDcmVhdGUgYSByZXF1ZXN0IGZvciB0aGUgbWV0aG9kICJzZXJ2aWNlQWNjb3VudHMuc2lnbkJsb2IiLgogICAgICAgICAqCiAgICAgICAgICogVGhpcyByZXF1ZXN0IGhvbGRzIHRoZSBwYXJhbWV0ZXJzIG5lZWRlZCBieSB0aGUgdGhlIGlhbSBzZXJ2ZXIuICBBZnRlciBzZXR0aW5nIGFueSBvcHRpb25hbAogICAgICAgICAqIHBhcmFtZXRlcnMsIGNhbGwgdGhlIHtAbGluayBTaWduQmxvYiNleGVjdXRlKCl9IG1ldGhvZCB0byBpbnZva2UgdGhlIHJlbW90ZSBvcGVyYXRpb24uIDxwPgogICAgICAgICAqIHtAbGluawogICAgICAgICAqIFNpZ25CbG9iI2luaXRpYWxpemUoY29tLmdvb2dsZS5hcGkuY2xpZW50Lmdvb2dsZWFwaXMuc2VydmljZXMuQWJzdHJhY3RHb29nbGVDbGllbnRSZXF1ZXN0KX0KICAgICAgICAgKiBtdXN0IGJlIGNhbGxlZCB0byBpbml0aWFsaXplIHRoaXMgaW5zdGFuY2UgaW1tZWRpYXRlbHkgYWZ0ZXIgaW52b2tpbmcgdGhlIGNvbnN0cnVjdG9yLiA8L3A+CiAgICAgICAgICoKICAgICAgICAgKiBAcGFyYW0gbmFtZSBSZXF1aXJlZC4gVGhlIHJlc291cmNlIG5hbWUgb2YgdGhlIHNlcnZpY2UgYWNjb3VudCBpbiB0aGUgZm9sbG93aW5nIGZvcm1hdDoKICAgICAgICogICAgICAgIGBwcm9qZWN0cy97UFJPSkVDVF9JRH0vc2VydmljZUFjY291bnRzL3tBQ0NPVU5UfWAuCiAgICAgIFVzaW5nIGAtYCBhcyBhIHdpbGRjYXJkIGZvciB0aGUKICAgICAgICogICAgICAgIGBQUk9KRUNUX0lEYCB3aWxsIGluZmVyIHRoZSBwcm9qZWN0IGZyb20KICAgICAgdGhlIGFjY291bnQuIFRoZSBgQUNDT1VOVGAgdmFsdWUgY2FuIGJlIHRoZQogICAgICAgKiAgICAgICAgYGVtYWlsYCBhZGRyZXNzIG9yIHRoZQogICAgICBgdW5pcXVlX2lkYCBvZiB0aGUgc2VydmljZSBhY2NvdW50LgogICAgICAgICAqIEBwYXJhbSBjb250ZW50IHRoZSB7QGxpbmsgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuaWFtLnYxLm1vZGVsLlNpZ25CbG9iUmVxdWVzdH0KICAgICAgICAgKiBAc2luY2UgMS4xMwogICAgICAgICAqLwogICAgICAgIHByb3RlY3RlZCBTaWduQmxvYihqYXZhLmxhbmcuU3RyaW5nIG5hbWUsIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmlhbS52MS5tb2RlbC5TaWduQmxvYlJlcXVlc3QgY29udGVudCkgewogICAgICAgICAgc3VwZXIoSWFtLnRoaXMsICJQT1NUIiwgUkVTVF9QQVRILCBjb250ZW50LCBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5pYW0udjEubW9kZWwuU2lnbkJsb2JSZXNwb25zZS5jbGFzcyk7CiAgICAgICAgICB0aGlzLm5hbWUgPSBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5QcmVjb25kaXRpb25zLmNoZWNrTm90TnVsbChuYW1lLCAiUmVxdWlyZWQgcGFyYW1ldGVyIG5hbWUgbXVzdCBiZSBzcGVjaWZpZWQuIik7CiAgICAgICAgICBpZiAoIWdldFN1cHByZXNzUGF0dGVybkNoZWNrcygpKSB7CiAgICAgICAgICAgIGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLlByZWNvbmRpdGlvbnMuY2hlY2tBcmd1bWVudChOQU1FX1BBVFRFUk4ubWF0Y2hlcihuYW1lKS5tYXRjaGVzKCksCiAgICAgICAgICAgICAgICAiUGFyYW1ldGVyIG5hbWUgbXVzdCBjb25mb3JtIHRvIHRoZSBwYXR0ZXJuICIgKwogICAgICAgICAgICAgICAgIl5wcm9qZWN0cy9bXi9dKy9zZXJ2aWNlQWNjb3VudHMvW14vXSskIik7CiAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgU2lnbkJsb2Igc2V0JFhnYWZ2KGphdmEubGFuZy5TdHJpbmcgJFhnYWZ2KSB7CiAgICAgICAgICByZXR1cm4gKFNpZ25CbG9iKSBzdXBlci5zZXQkWGdhZnYoJFhnYWZ2KTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBTaWduQmxvYiBzZXRBY2Nlc3NUb2tlbihqYXZhLmxhbmcuU3RyaW5nIGFjY2Vzc1Rva2VuKSB7CiAgICAgICAgICByZXR1cm4gKFNpZ25CbG9iKSBzdXBlci5zZXRBY2Nlc3NUb2tlbihhY2Nlc3NUb2tlbik7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgU2lnbkJsb2Igc2V0QWx0KGphdmEubGFuZy5TdHJpbmcgYWx0KSB7CiAgICAgICAgICByZXR1cm4gKFNpZ25CbG9iKSBzdXBlci5zZXRBbHQoYWx0KTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBTaWduQmxvYiBzZXRDYWxsYmFjayhqYXZhLmxhbmcuU3RyaW5nIGNhbGxiYWNrKSB7CiAgICAgICAgICByZXR1cm4gKFNpZ25CbG9iKSBzdXBlci5zZXRDYWxsYmFjayhjYWxsYmFjayk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgU2lnbkJsb2Igc2V0RmllbGRzKGphdmEubGFuZy5TdHJpbmcgZmllbGRzKSB7CiAgICAgICAgICByZXR1cm4gKFNpZ25CbG9iKSBzdXBlci5zZXRGaWVsZHMoZmllbGRzKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBTaWduQmxvYiBzZXRLZXkoamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICAgIHJldHVybiAoU2lnbkJsb2IpIHN1cGVyLnNldEtleShrZXkpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFNpZ25CbG9iIHNldE9hdXRoVG9rZW4oamF2YS5sYW5nLlN0cmluZyBvYXV0aFRva2VuKSB7CiAgICAgICAgICByZXR1cm4gKFNpZ25CbG9iKSBzdXBlci5zZXRPYXV0aFRva2VuKG9hdXRoVG9rZW4pOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFNpZ25CbG9iIHNldFByZXR0eVByaW50KGphdmEubGFuZy5Cb29sZWFuIHByZXR0eVByaW50KSB7CiAgICAgICAgICByZXR1cm4gKFNpZ25CbG9iKSBzdXBlci5zZXRQcmV0dHlQcmludChwcmV0dHlQcmludCk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgU2lnbkJsb2Igc2V0UXVvdGFVc2VyKGphdmEubGFuZy5TdHJpbmcgcXVvdGFVc2VyKSB7CiAgICAgICAgICByZXR1cm4gKFNpZ25CbG9iKSBzdXBlci5zZXRRdW90YVVzZXIocXVvdGFVc2VyKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBTaWduQmxvYiBzZXRVcGxvYWRUeXBlKGphdmEubGFuZy5TdHJpbmcgdXBsb2FkVHlwZSkgewogICAgICAgICAgcmV0dXJuIChTaWduQmxvYikgc3VwZXIuc2V0VXBsb2FkVHlwZSh1cGxvYWRUeXBlKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBTaWduQmxvYiBzZXRVcGxvYWRQcm90b2NvbChqYXZhLmxhbmcuU3RyaW5nIHVwbG9hZFByb3RvY29sKSB7CiAgICAgICAgICByZXR1cm4gKFNpZ25CbG9iKSBzdXBlci5zZXRVcGxvYWRQcm90b2NvbCh1cGxvYWRQcm90b2NvbCk7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiBSZXF1aXJlZC4gVGhlIHJlc291cmNlIG5hbWUgb2YgdGhlIHNlcnZpY2UgYWNjb3VudCBpbiB0aGUgZm9sbG93aW5nIGZvcm1hdDoKICAgICAgICAgKiBgcHJvamVjdHMve1BST0pFQ1RfSUR9L3NlcnZpY2VBY2NvdW50cy97QUNDT1VOVH1gLiBVc2luZyBgLWAgYXMgYSB3aWxkY2FyZCBmb3IgdGhlCiAgICAgICAgICogYFBST0pFQ1RfSURgIHdpbGwgaW5mZXIgdGhlIHByb2plY3QgZnJvbSB0aGUgYWNjb3VudC4gVGhlIGBBQ0NPVU5UYCB2YWx1ZSBjYW4gYmUgdGhlCiAgICAgICAgICogYGVtYWlsYCBhZGRyZXNzIG9yIHRoZSBgdW5pcXVlX2lkYCBvZiB0aGUgc2VydmljZSBhY2NvdW50LgogICAgICAgICAqLwogICAgICAgIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICAgICAgICBwcml2YXRlIGphdmEubGFuZy5TdHJpbmcgbmFtZTsKCiAgICAgICAgLyoqIFJlcXVpcmVkLiBUaGUgcmVzb3VyY2UgbmFtZSBvZiB0aGUgc2VydmljZSBhY2NvdW50IGluIHRoZSBmb2xsb3dpbmcgZm9ybWF0OgogICAgICAgYHByb2plY3RzL3tQUk9KRUNUX0lEfS9zZXJ2aWNlQWNjb3VudHMve0FDQ09VTlR9YC4gVXNpbmcgYC1gIGFzIGEgd2lsZGNhcmQgZm9yIHRoZSBgUFJPSkVDVF9JRGAKICAgICAgIHdpbGwgaW5mZXIgdGhlIHByb2plY3QgZnJvbSB0aGUgYWNjb3VudC4gVGhlIGBBQ0NPVU5UYCB2YWx1ZSBjYW4gYmUgdGhlIGBlbWFpbGAgYWRkcmVzcyBvciB0aGUKICAgICAgIGB1bmlxdWVfaWRgIG9mIHRoZSBzZXJ2aWNlIGFjY291bnQuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TmFtZSgpIHsKICAgICAgICAgIHJldHVybiBuYW1lOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogUmVxdWlyZWQuIFRoZSByZXNvdXJjZSBuYW1lIG9mIHRoZSBzZXJ2aWNlIGFjY291bnQgaW4gdGhlIGZvbGxvd2luZyBmb3JtYXQ6CiAgICAgICAgICogYHByb2plY3RzL3tQUk9KRUNUX0lEfS9zZXJ2aWNlQWNjb3VudHMve0FDQ09VTlR9YC4gVXNpbmcgYC1gIGFzIGEgd2lsZGNhcmQgZm9yIHRoZQogICAgICAgICAqIGBQUk9KRUNUX0lEYCB3aWxsIGluZmVyIHRoZSBwcm9qZWN0IGZyb20gdGhlIGFjY291bnQuIFRoZSBgQUNDT1VOVGAgdmFsdWUgY2FuIGJlIHRoZQogICAgICAgICAqIGBlbWFpbGAgYWRkcmVzcyBvciB0aGUgYHVuaXF1ZV9pZGAgb2YgdGhlIHNlcnZpY2UgYWNjb3VudC4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgU2lnbkJsb2Igc2V0TmFtZShqYXZhLmxhbmcuU3RyaW5nIG5hbWUpIHsKICAgICAgICAgIGlmICghZ2V0U3VwcHJlc3NQYXR0ZXJuQ2hlY2tzKCkpIHsKICAgICAgICAgICAgY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuUHJlY29uZGl0aW9ucy5jaGVja0FyZ3VtZW50KE5BTUVfUEFUVEVSTi5tYXRjaGVyKG5hbWUpLm1hdGNoZXMoKSwKICAgICAgICAgICAgICAgICJQYXJhbWV0ZXIgbmFtZSBtdXN0IGNvbmZvcm0gdG8gdGhlIHBhdHRlcm4gIiArCiAgICAgICAgICAgICAgICAiXnByb2plY3RzL1teL10rL3NlcnZpY2VBY2NvdW50cy9bXi9dKyQiKTsKICAgICAgICAgIH0KICAgICAgICAgIHRoaXMubmFtZSA9IG5hbWU7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBTaWduQmxvYiBzZXQoU3RyaW5nIHBhcmFtZXRlck5hbWUsIE9iamVjdCB2YWx1ZSkgewogICAgICAgICAgcmV0dXJuIChTaWduQmxvYikgc3VwZXIuc2V0KHBhcmFtZXRlck5hbWUsIHZhbHVlKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqICoqTm90ZSoqOiBUaGlzIG1ldGhvZCBpcyBpbiB0aGUgcHJvY2VzcyBvZiBiZWluZyBkZXByZWNhdGVkLiBDYWxsIHRoZQogICAgICAgKiBbYHNpZ25Kd3QoKWBdKC9pYW0vY3JlZGVudGlhbHMvcmVmZXJlbmNlL3Jlc3QvdjEvcHJvamVjdHMuc2VydmljZUFjY291bnRzL3NpZ25Kd3QpIG1ldGhvZCBvZiB0aGUKICAgICAgICogQ2xvdWQgSUFNIFNlcnZpY2UgQWNjb3VudCBDcmVkZW50aWFscyBBUEkgaW5zdGVhZC4KICAgICAgICoKICAgICAgICogU2lnbnMgYSBKV1QgdXNpbmcgYSBzZXJ2aWNlIGFjY291bnQncyBzeXN0ZW0tbWFuYWdlZCBwcml2YXRlIGtleS4KICAgICAgICoKICAgICAgICogSWYgbm8gZXhwaXJ5IHRpbWUgKGBleHBgKSBpcyBwcm92aWRlZCBpbiB0aGUgYFNpZ25Kd3RSZXF1ZXN0YCwgSUFNIHNldHMgYW4gYW4gZXhwaXJ5IHRpbWUgb2Ygb25lCiAgICAgICAqIGhvdXIgYnkgZGVmYXVsdC4gSWYgeW91IHJlcXVlc3QgYW4gZXhwaXJ5IHRpbWUgb2YgbW9yZSB0aGFuIG9uZSBob3VyLCB0aGUgcmVxdWVzdCB3aWxsIGZhaWwuCiAgICAgICAqCiAgICAgICAqIENyZWF0ZSBhIHJlcXVlc3QgZm9yIHRoZSBtZXRob2QgInNlcnZpY2VBY2NvdW50cy5zaWduSnd0Ii4KICAgICAgICoKICAgICAgICogVGhpcyByZXF1ZXN0IGhvbGRzIHRoZSBwYXJhbWV0ZXJzIG5lZWRlZCBieSB0aGUgaWFtIHNlcnZlci4gIEFmdGVyIHNldHRpbmcgYW55IG9wdGlvbmFsCiAgICAgICAqIHBhcmFtZXRlcnMsIGNhbGwgdGhlIHtAbGluayBTaWduSnd0I2V4ZWN1dGUoKX0gbWV0aG9kIHRvIGludm9rZSB0aGUgcmVtb3RlIG9wZXJhdGlvbi4KICAgICAgICoKICAgICAgICogQHBhcmFtIG5hbWUgUmVxdWlyZWQuIFRoZSByZXNvdXJjZSBuYW1lIG9mIHRoZSBzZXJ2aWNlIGFjY291bnQgaW4gdGhlIGZvbGxvd2luZyBmb3JtYXQ6CiAgICAgICAqICAgICAgICBgcHJvamVjdHMve1BST0pFQ1RfSUR9L3NlcnZpY2VBY2NvdW50cy97QUNDT1VOVH1gLgogICAgICBVc2luZyBgLWAgYXMgYSB3aWxkY2FyZCBmb3IgdGhlCiAgICAgICAqICAgICAgICBgUFJPSkVDVF9JRGAgd2lsbCBpbmZlciB0aGUgcHJvamVjdCBmcm9tCiAgICAgIHRoZSBhY2NvdW50LiBUaGUgYEFDQ09VTlRgIHZhbHVlIGNhbiBiZSB0aGUKICAgICAgICogICAgICAgIGBlbWFpbGAgYWRkcmVzcyBvciB0aGUKICAgICAgYHVuaXF1ZV9pZGAgb2YgdGhlIHNlcnZpY2UgYWNjb3VudC4KICAgICAgICogQHBhcmFtIGNvbnRlbnQgdGhlIHtAbGluayBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5pYW0udjEubW9kZWwuU2lnbkp3dFJlcXVlc3R9CiAgICAgICAqIEByZXR1cm4gdGhlIHJlcXVlc3QKICAgICAgICovCiAgICAgIHB1YmxpYyBTaWduSnd0IHNpZ25Kd3QoamF2YS5sYW5nLlN0cmluZyBuYW1lLCBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5pYW0udjEubW9kZWwuU2lnbkp3dFJlcXVlc3QgY29udGVudCkgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIFNpZ25Kd3QgcmVzdWx0ID0gbmV3IFNpZ25Kd3QobmFtZSwgY29udGVudCk7CiAgICAgICAgaW5pdGlhbGl6ZShyZXN1bHQpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBjbGFzcyBTaWduSnd0IGV4dGVuZHMgSWFtUmVxdWVzdDxjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5pYW0udjEubW9kZWwuU2lnbkp3dFJlc3BvbnNlPiB7CgogICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBSRVNUX1BBVEggPSAidjEveytuYW1lfTpzaWduSnd0IjsKCiAgICAgICAgcHJpdmF0ZSBmaW5hbCBqYXZhLnV0aWwucmVnZXguUGF0dGVybiBOQU1FX1BBVFRFUk4gPQogICAgICAgICAgICBqYXZhLnV0aWwucmVnZXguUGF0dGVybi5jb21waWxlKCJecHJvamVjdHMvW14vXSsvc2VydmljZUFjY291bnRzL1teL10rJCIpOwoKICAgICAgICAvKioKICAgICAgICAgKiAqKk5vdGUqKjogVGhpcyBtZXRob2QgaXMgaW4gdGhlIHByb2Nlc3Mgb2YgYmVpbmcgZGVwcmVjYXRlZC4gQ2FsbCB0aGUKICAgICAgICAgKiBbYHNpZ25Kd3QoKWBdKC9pYW0vY3JlZGVudGlhbHMvcmVmZXJlbmNlL3Jlc3QvdjEvcHJvamVjdHMuc2VydmljZUFjY291bnRzL3NpZ25Kd3QpIG1ldGhvZCBvZgogICAgICAgICAqIHRoZSBDbG91ZCBJQU0gU2VydmljZSBBY2NvdW50IENyZWRlbnRpYWxzIEFQSSBpbnN0ZWFkLgogICAgICAgICAqCiAgICAgICAgICogU2lnbnMgYSBKV1QgdXNpbmcgYSBzZXJ2aWNlIGFjY291bnQncyBzeXN0ZW0tbWFuYWdlZCBwcml2YXRlIGtleS4KICAgICAgICAgKgogICAgICAgICAqIElmIG5vIGV4cGlyeSB0aW1lIChgZXhwYCkgaXMgcHJvdmlkZWQgaW4gdGhlIGBTaWduSnd0UmVxdWVzdGAsIElBTSBzZXRzIGFuIGFuIGV4cGlyeSB0aW1lIG9mCiAgICAgICAgICogb25lIGhvdXIgYnkgZGVmYXVsdC4gSWYgeW91IHJlcXVlc3QgYW4gZXhwaXJ5IHRpbWUgb2YgbW9yZSB0aGFuIG9uZSBob3VyLCB0aGUgcmVxdWVzdCB3aWxsCiAgICAgICAgICogZmFpbC4KICAgICAgICAgKgogICAgICAgICAqIENyZWF0ZSBhIHJlcXVlc3QgZm9yIHRoZSBtZXRob2QgInNlcnZpY2VBY2NvdW50cy5zaWduSnd0Ii4KICAgICAgICAgKgogICAgICAgICAqIFRoaXMgcmVxdWVzdCBob2xkcyB0aGUgcGFyYW1ldGVycyBuZWVkZWQgYnkgdGhlIHRoZSBpYW0gc2VydmVyLiAgQWZ0ZXIgc2V0dGluZyBhbnkgb3B0aW9uYWwKICAgICAgICAgKiBwYXJhbWV0ZXJzLCBjYWxsIHRoZSB7QGxpbmsgU2lnbkp3dCNleGVjdXRlKCl9IG1ldGhvZCB0byBpbnZva2UgdGhlIHJlbW90ZSBvcGVyYXRpb24uIDxwPgogICAgICAgICAqIHtAbGluawogICAgICAgICAqIFNpZ25Kd3QjaW5pdGlhbGl6ZShjb20uZ29vZ2xlLmFwaS5jbGllbnQuZ29vZ2xlYXBpcy5zZXJ2aWNlcy5BYnN0cmFjdEdvb2dsZUNsaWVudFJlcXVlc3QpfSBtdXN0CiAgICAgICAgICogYmUgY2FsbGVkIHRvIGluaXRpYWxpemUgdGhpcyBpbnN0YW5jZSBpbW1lZGlhdGVseSBhZnRlciBpbnZva2luZyB0aGUgY29uc3RydWN0b3IuIDwvcD4KICAgICAgICAgKgogICAgICAgICAqIEBwYXJhbSBuYW1lIFJlcXVpcmVkLiBUaGUgcmVzb3VyY2UgbmFtZSBvZiB0aGUgc2VydmljZSBhY2NvdW50IGluIHRoZSBmb2xsb3dpbmcgZm9ybWF0OgogICAgICAgKiAgICAgICAgYHByb2plY3RzL3tQUk9KRUNUX0lEfS9zZXJ2aWNlQWNjb3VudHMve0FDQ09VTlR9YC4KICAgICAgVXNpbmcgYC1gIGFzIGEgd2lsZGNhcmQgZm9yIHRoZQogICAgICAgKiAgICAgICAgYFBST0pFQ1RfSURgIHdpbGwgaW5mZXIgdGhlIHByb2plY3QgZnJvbQogICAgICB0aGUgYWNjb3VudC4gVGhlIGBBQ0NPVU5UYCB2YWx1ZSBjYW4gYmUgdGhlCiAgICAgICAqICAgICAgICBgZW1haWxgIGFkZHJlc3Mgb3IgdGhlCiAgICAgIGB1bmlxdWVfaWRgIG9mIHRoZSBzZXJ2aWNlIGFjY291bnQuCiAgICAgICAgICogQHBhcmFtIGNvbnRlbnQgdGhlIHtAbGluayBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5pYW0udjEubW9kZWwuU2lnbkp3dFJlcXVlc3R9CiAgICAgICAgICogQHNpbmNlIDEuMTMKICAgICAgICAgKi8KICAgICAgICBwcm90ZWN0ZWQgU2lnbkp3dChqYXZhLmxhbmcuU3RyaW5nIG5hbWUsIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmlhbS52MS5tb2RlbC5TaWduSnd0UmVxdWVzdCBjb250ZW50KSB7CiAgICAgICAgICBzdXBlcihJYW0udGhpcywgIlBPU1QiLCBSRVNUX1BBVEgsIGNvbnRlbnQsIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmlhbS52MS5tb2RlbC5TaWduSnd0UmVzcG9uc2UuY2xhc3MpOwogICAgICAgICAgdGhpcy5uYW1lID0gY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuUHJlY29uZGl0aW9ucy5jaGVja05vdE51bGwobmFtZSwgIlJlcXVpcmVkIHBhcmFtZXRlciBuYW1lIG11c3QgYmUgc3BlY2lmaWVkLiIpOwogICAgICAgICAgaWYgKCFnZXRTdXBwcmVzc1BhdHRlcm5DaGVja3MoKSkgewogICAgICAgICAgICBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5QcmVjb25kaXRpb25zLmNoZWNrQXJndW1lbnQoTkFNRV9QQVRURVJOLm1hdGNoZXIobmFtZSkubWF0Y2hlcygpLAogICAgICAgICAgICAgICAgIlBhcmFtZXRlciBuYW1lIG11c3QgY29uZm9ybSB0byB0aGUgcGF0dGVybiAiICsKICAgICAgICAgICAgICAgICJecHJvamVjdHMvW14vXSsvc2VydmljZUFjY291bnRzL1teL10rJCIpOwogICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFNpZ25Kd3Qgc2V0JFhnYWZ2KGphdmEubGFuZy5TdHJpbmcgJFhnYWZ2KSB7CiAgICAgICAgICByZXR1cm4gKFNpZ25Kd3QpIHN1cGVyLnNldCRYZ2FmdigkWGdhZnYpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFNpZ25Kd3Qgc2V0QWNjZXNzVG9rZW4oamF2YS5sYW5nLlN0cmluZyBhY2Nlc3NUb2tlbikgewogICAgICAgICAgcmV0dXJuIChTaWduSnd0KSBzdXBlci5zZXRBY2Nlc3NUb2tlbihhY2Nlc3NUb2tlbik7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgU2lnbkp3dCBzZXRBbHQoamF2YS5sYW5nLlN0cmluZyBhbHQpIHsKICAgICAgICAgIHJldHVybiAoU2lnbkp3dCkgc3VwZXIuc2V0QWx0KGFsdCk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgU2lnbkp3dCBzZXRDYWxsYmFjayhqYXZhLmxhbmcuU3RyaW5nIGNhbGxiYWNrKSB7CiAgICAgICAgICByZXR1cm4gKFNpZ25Kd3QpIHN1cGVyLnNldENhbGxiYWNrKGNhbGxiYWNrKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBTaWduSnd0IHNldEZpZWxkcyhqYXZhLmxhbmcuU3RyaW5nIGZpZWxkcykgewogICAgICAgICAgcmV0dXJuIChTaWduSnd0KSBzdXBlci5zZXRGaWVsZHMoZmllbGRzKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBTaWduSnd0IHNldEtleShqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgICAgcmV0dXJuIChTaWduSnd0KSBzdXBlci5zZXRLZXkoa2V5KTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBTaWduSnd0IHNldE9hdXRoVG9rZW4oamF2YS5sYW5nLlN0cmluZyBvYXV0aFRva2VuKSB7CiAgICAgICAgICByZXR1cm4gKFNpZ25Kd3QpIHN1cGVyLnNldE9hdXRoVG9rZW4ob2F1dGhUb2tlbik7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgU2lnbkp3dCBzZXRQcmV0dHlQcmludChqYXZhLmxhbmcuQm9vbGVhbiBwcmV0dHlQcmludCkgewogICAgICAgICAgcmV0dXJuIChTaWduSnd0KSBzdXBlci5zZXRQcmV0dHlQcmludChwcmV0dHlQcmludCk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgU2lnbkp3dCBzZXRRdW90YVVzZXIoamF2YS5sYW5nLlN0cmluZyBxdW90YVVzZXIpIHsKICAgICAgICAgIHJldHVybiAoU2lnbkp3dCkgc3VwZXIuc2V0UXVvdGFVc2VyKHF1b3RhVXNlcik7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgU2lnbkp3dCBzZXRVcGxvYWRUeXBlKGphdmEubGFuZy5TdHJpbmcgdXBsb2FkVHlwZSkgewogICAgICAgICAgcmV0dXJuIChTaWduSnd0KSBzdXBlci5zZXRVcGxvYWRUeXBlKHVwbG9hZFR5cGUpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFNpZ25Kd3Qgc2V0VXBsb2FkUHJvdG9jb2woamF2YS5sYW5nLlN0cmluZyB1cGxvYWRQcm90b2NvbCkgewogICAgICAgICAgcmV0dXJuIChTaWduSnd0KSBzdXBlci5zZXRVcGxvYWRQcm90b2NvbCh1cGxvYWRQcm90b2NvbCk7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiBSZXF1aXJlZC4gVGhlIHJlc291cmNlIG5hbWUgb2YgdGhlIHNlcnZpY2UgYWNjb3VudCBpbiB0aGUgZm9sbG93aW5nIGZvcm1hdDoKICAgICAgICAgKiBgcHJvamVjdHMve1BST0pFQ1RfSUR9L3NlcnZpY2VBY2NvdW50cy97QUNDT1VOVH1gLiBVc2luZyBgLWAgYXMgYSB3aWxkY2FyZCBmb3IgdGhlCiAgICAgICAgICogYFBST0pFQ1RfSURgIHdpbGwgaW5mZXIgdGhlIHByb2plY3QgZnJvbSB0aGUgYWNjb3VudC4gVGhlIGBBQ0NPVU5UYCB2YWx1ZSBjYW4gYmUgdGhlCiAgICAgICAgICogYGVtYWlsYCBhZGRyZXNzIG9yIHRoZSBgdW5pcXVlX2lkYCBvZiB0aGUgc2VydmljZSBhY2NvdW50LgogICAgICAgICAqLwogICAgICAgIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICAgICAgICBwcml2YXRlIGphdmEubGFuZy5TdHJpbmcgbmFtZTsKCiAgICAgICAgLyoqIFJlcXVpcmVkLiBUaGUgcmVzb3VyY2UgbmFtZSBvZiB0aGUgc2VydmljZSBhY2NvdW50IGluIHRoZSBmb2xsb3dpbmcgZm9ybWF0OgogICAgICAgYHByb2plY3RzL3tQUk9KRUNUX0lEfS9zZXJ2aWNlQWNjb3VudHMve0FDQ09VTlR9YC4gVXNpbmcgYC1gIGFzIGEgd2lsZGNhcmQgZm9yIHRoZSBgUFJPSkVDVF9JRGAKICAgICAgIHdpbGwgaW5mZXIgdGhlIHByb2plY3QgZnJvbSB0aGUgYWNjb3VudC4gVGhlIGBBQ0NPVU5UYCB2YWx1ZSBjYW4gYmUgdGhlIGBlbWFpbGAgYWRkcmVzcyBvciB0aGUKICAgICAgIGB1bmlxdWVfaWRgIG9mIHRoZSBzZXJ2aWNlIGFjY291bnQuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TmFtZSgpIHsKICAgICAgICAgIHJldHVybiBuYW1lOwogICAgICAgIH0KCiAgICAgICAgLyoqCiAgICAgICAgICogUmVxdWlyZWQuIFRoZSByZXNvdXJjZSBuYW1lIG9mIHRoZSBzZXJ2aWNlIGFjY291bnQgaW4gdGhlIGZvbGxvd2luZyBmb3JtYXQ6CiAgICAgICAgICogYHByb2plY3RzL3tQUk9KRUNUX0lEfS9zZXJ2aWNlQWNjb3VudHMve0FDQ09VTlR9YC4gVXNpbmcgYC1gIGFzIGEgd2lsZGNhcmQgZm9yIHRoZQogICAgICAgICAqIGBQUk9KRUNUX0lEYCB3aWxsIGluZmVyIHRoZSBwcm9qZWN0IGZyb20gdGhlIGFjY291bnQuIFRoZSBgQUNDT1VOVGAgdmFsdWUgY2FuIGJlIHRoZQogICAgICAgICAqIGBlbWFpbGAgYWRkcmVzcyBvciB0aGUgYHVuaXF1ZV9pZGAgb2YgdGhlIHNlcnZpY2UgYWNjb3VudC4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgU2lnbkp3dCBzZXROYW1lKGphdmEubGFuZy5TdHJpbmcgbmFtZSkgewogICAgICAgICAgaWYgKCFnZXRTdXBwcmVzc1BhdHRlcm5DaGVja3MoKSkgewogICAgICAgICAgICBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5QcmVjb25kaXRpb25zLmNoZWNrQXJndW1lbnQoTkFNRV9QQVRURVJOLm1hdGNoZXIobmFtZSkubWF0Y2hlcygpLAogICAgICAgICAgICAgICAgIlBhcmFtZXRlciBuYW1lIG11c3QgY29uZm9ybSB0byB0aGUgcGF0dGVybiAiICsKICAgICAgICAgICAgICAgICJecHJvamVjdHMvW14vXSsvc2VydmljZUFjY291bnRzL1teL10rJCIpOwogICAgICAgICAgfQogICAgICAgICAgdGhpcy5uYW1lID0gbmFtZTsKICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFNpZ25Kd3Qgc2V0KFN0cmluZyBwYXJhbWV0ZXJOYW1lLCBPYmplY3QgdmFsdWUpIHsKICAgICAgICAgIHJldHVybiAoU2lnbkp3dCkgc3VwZXIuc2V0KHBhcmFtZXRlck5hbWUsIHZhbHVlKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIFRlc3RzIHRoZSBzcGVjaWZpZWQgcGVybWlzc2lvbnMgYWdhaW5zdCB0aGUgSUFNIGFjY2VzcyBjb250cm9sIHBvbGljeSBmb3IgYSBTZXJ2aWNlQWNjb3VudC4KICAgICAgICoKICAgICAgICogQ3JlYXRlIGEgcmVxdWVzdCBmb3IgdGhlIG1ldGhvZCAic2VydmljZUFjY291bnRzLnRlc3RJYW1QZXJtaXNzaW9ucyIuCiAgICAgICAqCiAgICAgICAqIFRoaXMgcmVxdWVzdCBob2xkcyB0aGUgcGFyYW1ldGVycyBuZWVkZWQgYnkgdGhlIGlhbSBzZXJ2ZXIuICBBZnRlciBzZXR0aW5nIGFueSBvcHRpb25hbAogICAgICAgKiBwYXJhbWV0ZXJzLCBjYWxsIHRoZSB7QGxpbmsgVGVzdElhbVBlcm1pc3Npb25zI2V4ZWN1dGUoKX0gbWV0aG9kIHRvIGludm9rZSB0aGUgcmVtb3RlIG9wZXJhdGlvbi4KICAgICAgICoKICAgICAgICogQHBhcmFtIHJlc291cmNlIFJFUVVJUkVEOiBUaGUgcmVzb3VyY2UgZm9yIHdoaWNoIHRoZSBwb2xpY3kgZGV0YWlsIGlzIGJlaW5nIHJlcXVlc3RlZC4KICAgICAgU2VlIHRoZSBvcGVyYXRpb24KICAgICAgICogICAgICAgIGRvY3VtZW50YXRpb24gZm9yIHRoZSBhcHByb3ByaWF0ZSB2YWx1ZSBmb3IgdGhpcyBmaWVsZC4KICAgICAgICogQHBhcmFtIGNvbnRlbnQgdGhlIHtAbGluayBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5pYW0udjEubW9kZWwuVGVzdElhbVBlcm1pc3Npb25zUmVxdWVzdH0KICAgICAgICogQHJldHVybiB0aGUgcmVxdWVzdAogICAgICAgKi8KICAgICAgcHVibGljIFRlc3RJYW1QZXJtaXNzaW9ucyB0ZXN0SWFtUGVybWlzc2lvbnMoamF2YS5sYW5nLlN0cmluZyByZXNvdXJjZSwgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuaWFtLnYxLm1vZGVsLlRlc3RJYW1QZXJtaXNzaW9uc1JlcXVlc3QgY29udGVudCkgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIFRlc3RJYW1QZXJtaXNzaW9ucyByZXN1bHQgPSBuZXcgVGVzdElhbVBlcm1pc3Npb25zKHJlc291cmNlLCBjb250ZW50KTsKICAgICAgICBpbml0aWFsaXplKHJlc3VsdCk7CiAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKICAgICAgcHVibGljIGNsYXNzIFRlc3RJYW1QZXJtaXNzaW9ucyBleHRlbmRzIElhbVJlcXVlc3Q8Y29tLmdvb2dsZS5hcGkuc2VydmljZXMuaWFtLnYxLm1vZGVsLlRlc3RJYW1QZXJtaXNzaW9uc1Jlc3BvbnNlPiB7CgogICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBSRVNUX1BBVEggPSAidjEveytyZXNvdXJjZX06dGVzdElhbVBlcm1pc3Npb25zIjsKCiAgICAgICAgcHJpdmF0ZSBmaW5hbCBqYXZhLnV0aWwucmVnZXguUGF0dGVybiBSRVNPVVJDRV9QQVRURVJOID0KICAgICAgICAgICAgamF2YS51dGlsLnJlZ2V4LlBhdHRlcm4uY29tcGlsZSgiXnByb2plY3RzL1teL10rL3NlcnZpY2VBY2NvdW50cy9bXi9dKyQiKTsKCiAgICAgICAgLyoqCiAgICAgICAgICogVGVzdHMgdGhlIHNwZWNpZmllZCBwZXJtaXNzaW9ucyBhZ2FpbnN0IHRoZSBJQU0gYWNjZXNzIGNvbnRyb2wgcG9saWN5IGZvciBhIFNlcnZpY2VBY2NvdW50LgogICAgICAgICAqCiAgICAgICAgICogQ3JlYXRlIGEgcmVxdWVzdCBmb3IgdGhlIG1ldGhvZCAic2VydmljZUFjY291bnRzLnRlc3RJYW1QZXJtaXNzaW9ucyIuCiAgICAgICAgICoKICAgICAgICAgKiBUaGlzIHJlcXVlc3QgaG9sZHMgdGhlIHBhcmFtZXRlcnMgbmVlZGVkIGJ5IHRoZSB0aGUgaWFtIHNlcnZlci4gIEFmdGVyIHNldHRpbmcgYW55IG9wdGlvbmFsCiAgICAgICAgICogcGFyYW1ldGVycywgY2FsbCB0aGUge0BsaW5rIFRlc3RJYW1QZXJtaXNzaW9ucyNleGVjdXRlKCl9IG1ldGhvZCB0byBpbnZva2UgdGhlIHJlbW90ZQogICAgICAgICAqIG9wZXJhdGlvbi4gPHA+IHtAbGluayBUZXN0SWFtUGVybWlzc2lvbnMjaW5pdGlhbGl6ZShjb20uZ29vZ2xlLmFwaS5jbGllbnQuZ29vZ2xlYXBpcy5zZXJ2aWNlcy5BCiAgICAgICAgICogYnN0cmFjdEdvb2dsZUNsaWVudFJlcXVlc3QpfSBtdXN0IGJlIGNhbGxlZCB0byBpbml0aWFsaXplIHRoaXMgaW5zdGFuY2UgaW1tZWRpYXRlbHkgYWZ0ZXIKICAgICAgICAgKiBpbnZva2luZyB0aGUgY29uc3RydWN0b3IuIDwvcD4KICAgICAgICAgKgogICAgICAgICAqIEBwYXJhbSByZXNvdXJjZSBSRVFVSVJFRDogVGhlIHJlc291cmNlIGZvciB3aGljaCB0aGUgcG9saWN5IGRldGFpbCBpcyBiZWluZyByZXF1ZXN0ZWQuCiAgICAgIFNlZSB0aGUgb3BlcmF0aW9uCiAgICAgICAqICAgICAgICBkb2N1bWVudGF0aW9uIGZvciB0aGUgYXBwcm9wcmlhdGUgdmFsdWUgZm9yIHRoaXMgZmllbGQuCiAgICAgICAgICogQHBhcmFtIGNvbnRlbnQgdGhlIHtAbGluayBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5pYW0udjEubW9kZWwuVGVzdElhbVBlcm1pc3Npb25zUmVxdWVzdH0KICAgICAgICAgKiBAc2luY2UgMS4xMwogICAgICAgICAqLwogICAgICAgIHByb3RlY3RlZCBUZXN0SWFtUGVybWlzc2lvbnMoamF2YS5sYW5nLlN0cmluZyByZXNvdXJjZSwgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuaWFtLnYxLm1vZGVsLlRlc3RJYW1QZXJtaXNzaW9uc1JlcXVlc3QgY29udGVudCkgewogICAgICAgICAgc3VwZXIoSWFtLnRoaXMsICJQT1NUIiwgUkVTVF9QQVRILCBjb250ZW50LCBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5pYW0udjEubW9kZWwuVGVzdElhbVBlcm1pc3Npb25zUmVzcG9uc2UuY2xhc3MpOwogICAgICAgICAgdGhpcy5yZXNvdXJjZSA9IGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLlByZWNvbmRpdGlvbnMuY2hlY2tOb3ROdWxsKHJlc291cmNlLCAiUmVxdWlyZWQgcGFyYW1ldGVyIHJlc291cmNlIG11c3QgYmUgc3BlY2lmaWVkLiIpOwogICAgICAgICAgaWYgKCFnZXRTdXBwcmVzc1BhdHRlcm5DaGVja3MoKSkgewogICAgICAgICAgICBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5QcmVjb25kaXRpb25zLmNoZWNrQXJndW1lbnQoUkVTT1VSQ0VfUEFUVEVSTi5tYXRjaGVyKHJlc291cmNlKS5tYXRjaGVzKCksCiAgICAgICAgICAgICAgICAiUGFyYW1ldGVyIHJlc291cmNlIG11c3QgY29uZm9ybSB0byB0aGUgcGF0dGVybiAiICsKICAgICAgICAgICAgICAgICJecHJvamVjdHMvW14vXSsvc2VydmljZUFjY291bnRzL1teL10rJCIpOwogICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFRlc3RJYW1QZXJtaXNzaW9ucyBzZXQkWGdhZnYoamF2YS5sYW5nLlN0cmluZyAkWGdhZnYpIHsKICAgICAgICAgIHJldHVybiAoVGVzdElhbVBlcm1pc3Npb25zKSBzdXBlci5zZXQkWGdhZnYoJFhnYWZ2KTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBUZXN0SWFtUGVybWlzc2lvbnMgc2V0QWNjZXNzVG9rZW4oamF2YS5sYW5nLlN0cmluZyBhY2Nlc3NUb2tlbikgewogICAgICAgICAgcmV0dXJuIChUZXN0SWFtUGVybWlzc2lvbnMpIHN1cGVyLnNldEFjY2Vzc1Rva2VuKGFjY2Vzc1Rva2VuKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBUZXN0SWFtUGVybWlzc2lvbnMgc2V0QWx0KGphdmEubGFuZy5TdHJpbmcgYWx0KSB7CiAgICAgICAgICByZXR1cm4gKFRlc3RJYW1QZXJtaXNzaW9ucykgc3VwZXIuc2V0QWx0KGFsdCk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgVGVzdElhbVBlcm1pc3Npb25zIHNldENhbGxiYWNrKGphdmEubGFuZy5TdHJpbmcgY2FsbGJhY2spIHsKICAgICAgICAgIHJldHVybiAoVGVzdElhbVBlcm1pc3Npb25zKSBzdXBlci5zZXRDYWxsYmFjayhjYWxsYmFjayk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgVGVzdElhbVBlcm1pc3Npb25zIHNldEZpZWxkcyhqYXZhLmxhbmcuU3RyaW5nIGZpZWxkcykgewogICAgICAgICAgcmV0dXJuIChUZXN0SWFtUGVybWlzc2lvbnMpIHN1cGVyLnNldEZpZWxkcyhmaWVsZHMpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFRlc3RJYW1QZXJtaXNzaW9ucyBzZXRLZXkoamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICAgIHJldHVybiAoVGVzdElhbVBlcm1pc3Npb25zKSBzdXBlci5zZXRLZXkoa2V5KTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBUZXN0SWFtUGVybWlzc2lvbnMgc2V0T2F1dGhUb2tlbihqYXZhLmxhbmcuU3RyaW5nIG9hdXRoVG9rZW4pIHsKICAgICAgICAgIHJldHVybiAoVGVzdElhbVBlcm1pc3Npb25zKSBzdXBlci5zZXRPYXV0aFRva2VuKG9hdXRoVG9rZW4pOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFRlc3RJYW1QZXJtaXNzaW9ucyBzZXRQcmV0dHlQcmludChqYXZhLmxhbmcuQm9vbGVhbiBwcmV0dHlQcmludCkgewogICAgICAgICAgcmV0dXJuIChUZXN0SWFtUGVybWlzc2lvbnMpIHN1cGVyLnNldFByZXR0eVByaW50KHByZXR0eVByaW50KTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBUZXN0SWFtUGVybWlzc2lvbnMgc2V0UXVvdGFVc2VyKGphdmEubGFuZy5TdHJpbmcgcXVvdGFVc2VyKSB7CiAgICAgICAgICByZXR1cm4gKFRlc3RJYW1QZXJtaXNzaW9ucykgc3VwZXIuc2V0UXVvdGFVc2VyKHF1b3RhVXNlcik7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgVGVzdElhbVBlcm1pc3Npb25zIHNldFVwbG9hZFR5cGUoamF2YS5sYW5nLlN0cmluZyB1cGxvYWRUeXBlKSB7CiAgICAgICAgICByZXR1cm4gKFRlc3RJYW1QZXJtaXNzaW9ucykgc3VwZXIuc2V0VXBsb2FkVHlwZSh1cGxvYWRUeXBlKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBUZXN0SWFtUGVybWlzc2lvbnMgc2V0VXBsb2FkUHJvdG9jb2woamF2YS5sYW5nLlN0cmluZyB1cGxvYWRQcm90b2NvbCkgewogICAgICAgICAgcmV0dXJuIChUZXN0SWFtUGVybWlzc2lvbnMpIHN1cGVyLnNldFVwbG9hZFByb3RvY29sKHVwbG9hZFByb3RvY29sKTsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIFJFUVVJUkVEOiBUaGUgcmVzb3VyY2UgZm9yIHdoaWNoIHRoZSBwb2xpY3kgZGV0YWlsIGlzIGJlaW5nIHJlcXVlc3RlZC4gU2VlIHRoZSBvcGVyYXRpb24KICAgICAgICAgKiBkb2N1bWVudGF0aW9uIGZvciB0aGUgYXBwcm9wcmlhdGUgdmFsdWUgZm9yIHRoaXMgZmllbGQuCiAgICAgICAgICovCiAgICAgICAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogICAgICAgIHByaXZhdGUgamF2YS5sYW5nLlN0cmluZyByZXNvdXJjZTsKCiAgICAgICAgLyoqIFJFUVVJUkVEOiBUaGUgcmVzb3VyY2UgZm9yIHdoaWNoIHRoZSBwb2xpY3kgZGV0YWlsIGlzIGJlaW5nIHJlcXVlc3RlZC4gU2VlIHRoZSBvcGVyYXRpb24KICAgICAgIGRvY3VtZW50YXRpb24gZm9yIHRoZSBhcHByb3ByaWF0ZSB2YWx1ZSBmb3IgdGhpcyBmaWVsZC4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRSZXNvdXJjZSgpIHsKICAgICAgICAgIHJldHVybiByZXNvdXJjZTsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIFJFUVVJUkVEOiBUaGUgcmVzb3VyY2UgZm9yIHdoaWNoIHRoZSBwb2xpY3kgZGV0YWlsIGlzIGJlaW5nIHJlcXVlc3RlZC4gU2VlIHRoZSBvcGVyYXRpb24KICAgICAgICAgKiBkb2N1bWVudGF0aW9uIGZvciB0aGUgYXBwcm9wcmlhdGUgdmFsdWUgZm9yIHRoaXMgZmllbGQuCiAgICAgICAgICovCiAgICAgICAgcHVibGljIFRlc3RJYW1QZXJtaXNzaW9ucyBzZXRSZXNvdXJjZShqYXZhLmxhbmcuU3RyaW5nIHJlc291cmNlKSB7CiAgICAgICAgICBpZiAoIWdldFN1cHByZXNzUGF0dGVybkNoZWNrcygpKSB7CiAgICAgICAgICAgIGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLlByZWNvbmRpdGlvbnMuY2hlY2tBcmd1bWVudChSRVNPVVJDRV9QQVRURVJOLm1hdGNoZXIocmVzb3VyY2UpLm1hdGNoZXMoKSwKICAgICAgICAgICAgICAgICJQYXJhbWV0ZXIgcmVzb3VyY2UgbXVzdCBjb25mb3JtIHRvIHRoZSBwYXR0ZXJuICIgKwogICAgICAgICAgICAgICAgIl5wcm9qZWN0cy9bXi9dKy9zZXJ2aWNlQWNjb3VudHMvW14vXSskIik7CiAgICAgICAgICB9CiAgICAgICAgICB0aGlzLnJlc291cmNlID0gcmVzb3VyY2U7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBUZXN0SWFtUGVybWlzc2lvbnMgc2V0KFN0cmluZyBwYXJhbWV0ZXJOYW1lLCBPYmplY3QgdmFsdWUpIHsKICAgICAgICAgIHJldHVybiAoVGVzdElhbVBlcm1pc3Npb25zKSBzdXBlci5zZXQocGFyYW1ldGVyTmFtZSwgdmFsdWUpOwogICAgICAgIH0KICAgICAgfQogICAgICAvKioKICAgICAgICogUmVzdG9yZXMgYSBkZWxldGVkIFNlcnZpY2VBY2NvdW50LiBUaGlzIGlzIHRvIGJlIHVzZWQgYXMgYW4gYWN0aW9uIG9mIGxhc3QgcmVzb3J0LiAgQSBzZXJ2aWNlCiAgICAgICAqIGFjY291bnQgbWF5IG5vdCBhbHdheXMgYmUgcmVzdG9yYWJsZS4KICAgICAgICoKICAgICAgICogQ3JlYXRlIGEgcmVxdWVzdCBmb3IgdGhlIG1ldGhvZCAic2VydmljZUFjY291bnRzLnVuZGVsZXRlIi4KICAgICAgICoKICAgICAgICogVGhpcyByZXF1ZXN0IGhvbGRzIHRoZSBwYXJhbWV0ZXJzIG5lZWRlZCBieSB0aGUgaWFtIHNlcnZlci4gIEFmdGVyIHNldHRpbmcgYW55IG9wdGlvbmFsCiAgICAgICAqIHBhcmFtZXRlcnMsIGNhbGwgdGhlIHtAbGluayBVbmRlbGV0ZSNleGVjdXRlKCl9IG1ldGhvZCB0byBpbnZva2UgdGhlIHJlbW90ZSBvcGVyYXRpb24uCiAgICAgICAqCiAgICAgICAqIEBwYXJhbSBuYW1lIFRoZSByZXNvdXJjZSBuYW1lIG9mIHRoZSBzZXJ2aWNlIGFjY291bnQgaW4gdGhlIGZvbGxvd2luZyBmb3JtYXQ6CiAgICAgICAqICAgICAgICBgcHJvamVjdHMve1BST0pFQ1RfSUR9L3NlcnZpY2VBY2NvdW50cy97QUNDT1VOVF9VTklRVUVfSUR9YC4KICAgICAgVXNpbmcgYC1gIGFzIGEgd2lsZGNhcmQgZm9yCiAgICAgICAqICAgICAgICB0aGUgYFBST0pFQ1RfSURgIHdpbGwgaW5mZXIgdGhlIHByb2plY3QgZnJvbQogICAgICB0aGUgYWNjb3VudC4KICAgICAgICogQHBhcmFtIGNvbnRlbnQgdGhlIHtAbGluayBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5pYW0udjEubW9kZWwuVW5kZWxldGVTZXJ2aWNlQWNjb3VudFJlcXVlc3R9CiAgICAgICAqIEByZXR1cm4gdGhlIHJlcXVlc3QKICAgICAgICovCiAgICAgIHB1YmxpYyBVbmRlbGV0ZSB1bmRlbGV0ZShqYXZhLmxhbmcuU3RyaW5nIG5hbWUsIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmlhbS52MS5tb2RlbC5VbmRlbGV0ZVNlcnZpY2VBY2NvdW50UmVxdWVzdCBjb250ZW50KSB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgVW5kZWxldGUgcmVzdWx0ID0gbmV3IFVuZGVsZXRlKG5hbWUsIGNvbnRlbnQpOwogICAgICAgIGluaXRpYWxpemUocmVzdWx0KTsKICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CgogICAgICBwdWJsaWMgY2xhc3MgVW5kZWxldGUgZXh0ZW5kcyBJYW1SZXF1ZXN0PGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmlhbS52MS5tb2RlbC5VbmRlbGV0ZVNlcnZpY2VBY2NvdW50UmVzcG9uc2U+IHsKCiAgICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFJFU1RfUEFUSCA9ICJ2MS97K25hbWV9OnVuZGVsZXRlIjsKCiAgICAgICAgcHJpdmF0ZSBmaW5hbCBqYXZhLnV0aWwucmVnZXguUGF0dGVybiBOQU1FX1BBVFRFUk4gPQogICAgICAgICAgICBqYXZhLnV0aWwucmVnZXguUGF0dGVybi5jb21waWxlKCJecHJvamVjdHMvW14vXSsvc2VydmljZUFjY291bnRzL1teL10rJCIpOwoKICAgICAgICAvKioKICAgICAgICAgKiBSZXN0b3JlcyBhIGRlbGV0ZWQgU2VydmljZUFjY291bnQuIFRoaXMgaXMgdG8gYmUgdXNlZCBhcyBhbiBhY3Rpb24gb2YgbGFzdCByZXNvcnQuICBBIHNlcnZpY2UKICAgICAgICAgKiBhY2NvdW50IG1heSBub3QgYWx3YXlzIGJlIHJlc3RvcmFibGUuCiAgICAgICAgICoKICAgICAgICAgKiBDcmVhdGUgYSByZXF1ZXN0IGZvciB0aGUgbWV0aG9kICJzZXJ2aWNlQWNjb3VudHMudW5kZWxldGUiLgogICAgICAgICAqCiAgICAgICAgICogVGhpcyByZXF1ZXN0IGhvbGRzIHRoZSBwYXJhbWV0ZXJzIG5lZWRlZCBieSB0aGUgdGhlIGlhbSBzZXJ2ZXIuICBBZnRlciBzZXR0aW5nIGFueSBvcHRpb25hbAogICAgICAgICAqIHBhcmFtZXRlcnMsIGNhbGwgdGhlIHtAbGluayBVbmRlbGV0ZSNleGVjdXRlKCl9IG1ldGhvZCB0byBpbnZva2UgdGhlIHJlbW90ZSBvcGVyYXRpb24uIDxwPgogICAgICAgICAqIHtAbGluawogICAgICAgICAqIFVuZGVsZXRlI2luaXRpYWxpemUoY29tLmdvb2dsZS5hcGkuY2xpZW50Lmdvb2dsZWFwaXMuc2VydmljZXMuQWJzdHJhY3RHb29nbGVDbGllbnRSZXF1ZXN0KX0KICAgICAgICAgKiBtdXN0IGJlIGNhbGxlZCB0byBpbml0aWFsaXplIHRoaXMgaW5zdGFuY2UgaW1tZWRpYXRlbHkgYWZ0ZXIgaW52b2tpbmcgdGhlIGNvbnN0cnVjdG9yLiA8L3A+CiAgICAgICAgICoKICAgICAgICAgKiBAcGFyYW0gbmFtZSBUaGUgcmVzb3VyY2UgbmFtZSBvZiB0aGUgc2VydmljZSBhY2NvdW50IGluIHRoZSBmb2xsb3dpbmcgZm9ybWF0OgogICAgICAgKiAgICAgICAgYHByb2plY3RzL3tQUk9KRUNUX0lEfS9zZXJ2aWNlQWNjb3VudHMve0FDQ09VTlRfVU5JUVVFX0lEfWAuCiAgICAgIFVzaW5nIGAtYCBhcyBhIHdpbGRjYXJkIGZvcgogICAgICAgKiAgICAgICAgdGhlIGBQUk9KRUNUX0lEYCB3aWxsIGluZmVyIHRoZSBwcm9qZWN0IGZyb20KICAgICAgdGhlIGFjY291bnQuCiAgICAgICAgICogQHBhcmFtIGNvbnRlbnQgdGhlIHtAbGluayBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5pYW0udjEubW9kZWwuVW5kZWxldGVTZXJ2aWNlQWNjb3VudFJlcXVlc3R9CiAgICAgICAgICogQHNpbmNlIDEuMTMKICAgICAgICAgKi8KICAgICAgICBwcm90ZWN0ZWQgVW5kZWxldGUoamF2YS5sYW5nLlN0cmluZyBuYW1lLCBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5pYW0udjEubW9kZWwuVW5kZWxldGVTZXJ2aWNlQWNjb3VudFJlcXVlc3QgY29udGVudCkgewogICAgICAgICAgc3VwZXIoSWFtLnRoaXMsICJQT1NUIiwgUkVTVF9QQVRILCBjb250ZW50LCBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5pYW0udjEubW9kZWwuVW5kZWxldGVTZXJ2aWNlQWNjb3VudFJlc3BvbnNlLmNsYXNzKTsKICAgICAgICAgIHRoaXMubmFtZSA9IGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLlByZWNvbmRpdGlvbnMuY2hlY2tOb3ROdWxsKG5hbWUsICJSZXF1aXJlZCBwYXJhbWV0ZXIgbmFtZSBtdXN0IGJlIHNwZWNpZmllZC4iKTsKICAgICAgICAgIGlmICghZ2V0U3VwcHJlc3NQYXR0ZXJuQ2hlY2tzKCkpIHsKICAgICAgICAgICAgY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuUHJlY29uZGl0aW9ucy5jaGVja0FyZ3VtZW50KE5BTUVfUEFUVEVSTi5tYXRjaGVyKG5hbWUpLm1hdGNoZXMoKSwKICAgICAgICAgICAgICAgICJQYXJhbWV0ZXIgbmFtZSBtdXN0IGNvbmZvcm0gdG8gdGhlIHBhdHRlcm4gIiArCiAgICAgICAgICAgICAgICAiXnByb2plY3RzL1teL10rL3NlcnZpY2VBY2NvdW50cy9bXi9dKyQiKTsKICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBVbmRlbGV0ZSBzZXQkWGdhZnYoamF2YS5sYW5nLlN0cmluZyAkWGdhZnYpIHsKICAgICAgICAgIHJldHVybiAoVW5kZWxldGUpIHN1cGVyLnNldCRYZ2FmdigkWGdhZnYpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFVuZGVsZXRlIHNldEFjY2Vzc1Rva2VuKGphdmEubGFuZy5TdHJpbmcgYWNjZXNzVG9rZW4pIHsKICAgICAgICAgIHJldHVybiAoVW5kZWxldGUpIHN1cGVyLnNldEFjY2Vzc1Rva2VuKGFjY2Vzc1Rva2VuKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBVbmRlbGV0ZSBzZXRBbHQoamF2YS5sYW5nLlN0cmluZyBhbHQpIHsKICAgICAgICAgIHJldHVybiAoVW5kZWxldGUpIHN1cGVyLnNldEFsdChhbHQpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFVuZGVsZXRlIHNldENhbGxiYWNrKGphdmEubGFuZy5TdHJpbmcgY2FsbGJhY2spIHsKICAgICAgICAgIHJldHVybiAoVW5kZWxldGUpIHN1cGVyLnNldENhbGxiYWNrKGNhbGxiYWNrKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBVbmRlbGV0ZSBzZXRGaWVsZHMoamF2YS5sYW5nLlN0cmluZyBmaWVsZHMpIHsKICAgICAgICAgIHJldHVybiAoVW5kZWxldGUpIHN1cGVyLnNldEZpZWxkcyhmaWVsZHMpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFVuZGVsZXRlIHNldEtleShqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgICAgcmV0dXJuIChVbmRlbGV0ZSkgc3VwZXIuc2V0S2V5KGtleSk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgVW5kZWxldGUgc2V0T2F1dGhUb2tlbihqYXZhLmxhbmcuU3RyaW5nIG9hdXRoVG9rZW4pIHsKICAgICAgICAgIHJldHVybiAoVW5kZWxldGUpIHN1cGVyLnNldE9hdXRoVG9rZW4ob2F1dGhUb2tlbik7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgVW5kZWxldGUgc2V0UHJldHR5UHJpbnQoamF2YS5sYW5nLkJvb2xlYW4gcHJldHR5UHJpbnQpIHsKICAgICAgICAgIHJldHVybiAoVW5kZWxldGUpIHN1cGVyLnNldFByZXR0eVByaW50KHByZXR0eVByaW50KTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBVbmRlbGV0ZSBzZXRRdW90YVVzZXIoamF2YS5sYW5nLlN0cmluZyBxdW90YVVzZXIpIHsKICAgICAgICAgIHJldHVybiAoVW5kZWxldGUpIHN1cGVyLnNldFF1b3RhVXNlcihxdW90YVVzZXIpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFVuZGVsZXRlIHNldFVwbG9hZFR5cGUoamF2YS5sYW5nLlN0cmluZyB1cGxvYWRUeXBlKSB7CiAgICAgICAgICByZXR1cm4gKFVuZGVsZXRlKSBzdXBlci5zZXRVcGxvYWRUeXBlKHVwbG9hZFR5cGUpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFVuZGVsZXRlIHNldFVwbG9hZFByb3RvY29sKGphdmEubGFuZy5TdHJpbmcgdXBsb2FkUHJvdG9jb2wpIHsKICAgICAgICAgIHJldHVybiAoVW5kZWxldGUpIHN1cGVyLnNldFVwbG9hZFByb3RvY29sKHVwbG9hZFByb3RvY29sKTsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIFRoZSByZXNvdXJjZSBuYW1lIG9mIHRoZSBzZXJ2aWNlIGFjY291bnQgaW4gdGhlIGZvbGxvd2luZyBmb3JtYXQ6CiAgICAgICAgICogYHByb2plY3RzL3tQUk9KRUNUX0lEfS9zZXJ2aWNlQWNjb3VudHMve0FDQ09VTlRfVU5JUVVFX0lEfWAuIFVzaW5nIGAtYCBhcyBhIHdpbGRjYXJkIGZvcgogICAgICAgICAqIHRoZSBgUFJPSkVDVF9JRGAgd2lsbCBpbmZlciB0aGUgcHJvamVjdCBmcm9tIHRoZSBhY2NvdW50LgogICAgICAgICAqLwogICAgICAgIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICAgICAgICBwcml2YXRlIGphdmEubGFuZy5TdHJpbmcgbmFtZTsKCiAgICAgICAgLyoqIFRoZSByZXNvdXJjZSBuYW1lIG9mIHRoZSBzZXJ2aWNlIGFjY291bnQgaW4gdGhlIGZvbGxvd2luZyBmb3JtYXQ6CiAgICAgICBgcHJvamVjdHMve1BST0pFQ1RfSUR9L3NlcnZpY2VBY2NvdW50cy97QUNDT1VOVF9VTklRVUVfSUR9YC4gVXNpbmcgYC1gIGFzIGEgd2lsZGNhcmQgZm9yIHRoZQogICAgICAgYFBST0pFQ1RfSURgIHdpbGwgaW5mZXIgdGhlIHByb2plY3QgZnJvbSB0aGUgYWNjb3VudC4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXROYW1lKCkgewogICAgICAgICAgcmV0dXJuIG5hbWU7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiBUaGUgcmVzb3VyY2UgbmFtZSBvZiB0aGUgc2VydmljZSBhY2NvdW50IGluIHRoZSBmb2xsb3dpbmcgZm9ybWF0OgogICAgICAgICAqIGBwcm9qZWN0cy97UFJPSkVDVF9JRH0vc2VydmljZUFjY291bnRzL3tBQ0NPVU5UX1VOSVFVRV9JRH1gLiBVc2luZyBgLWAgYXMgYSB3aWxkY2FyZCBmb3IKICAgICAgICAgKiB0aGUgYFBST0pFQ1RfSURgIHdpbGwgaW5mZXIgdGhlIHByb2plY3QgZnJvbSB0aGUgYWNjb3VudC4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgVW5kZWxldGUgc2V0TmFtZShqYXZhLmxhbmcuU3RyaW5nIG5hbWUpIHsKICAgICAgICAgIGlmICghZ2V0U3VwcHJlc3NQYXR0ZXJuQ2hlY2tzKCkpIHsKICAgICAgICAgICAgY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuUHJlY29uZGl0aW9ucy5jaGVja0FyZ3VtZW50KE5BTUVfUEFUVEVSTi5tYXRjaGVyKG5hbWUpLm1hdGNoZXMoKSwKICAgICAgICAgICAgICAgICJQYXJhbWV0ZXIgbmFtZSBtdXN0IGNvbmZvcm0gdG8gdGhlIHBhdHRlcm4gIiArCiAgICAgICAgICAgICAgICAiXnByb2plY3RzL1teL10rL3NlcnZpY2VBY2NvdW50cy9bXi9dKyQiKTsKICAgICAgICAgIH0KICAgICAgICAgIHRoaXMubmFtZSA9IG5hbWU7CiAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBVbmRlbGV0ZSBzZXQoU3RyaW5nIHBhcmFtZXRlck5hbWUsIE9iamVjdCB2YWx1ZSkgewogICAgICAgICAgcmV0dXJuIChVbmRlbGV0ZSkgc3VwZXIuc2V0KHBhcmFtZXRlck5hbWUsIHZhbHVlKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLyoqCiAgICAgICAqIE5vdGU6IFRoaXMgbWV0aG9kIGlzIGluIHRoZSBwcm9jZXNzIG9mIGJlaW5nIGRlcHJlY2F0ZWQuIFVzZSBQYXRjaFNlcnZpY2VBY2NvdW50IGluc3RlYWQuCiAgICAgICAqCiAgICAgICAqIFVwZGF0ZXMgYSBTZXJ2aWNlQWNjb3VudC4KICAgICAgICoKICAgICAgICogQ3VycmVudGx5LCBvbmx5IHRoZSBmb2xsb3dpbmcgZmllbGRzIGFyZSB1cGRhdGFibGU6IGBkaXNwbGF5X25hbWVgIGFuZCBgZGVzY3JpcHRpb25gLgogICAgICAgKgogICAgICAgKiBDcmVhdGUgYSByZXF1ZXN0IGZvciB0aGUgbWV0aG9kICJzZXJ2aWNlQWNjb3VudHMudXBkYXRlIi4KICAgICAgICoKICAgICAgICogVGhpcyByZXF1ZXN0IGhvbGRzIHRoZSBwYXJhbWV0ZXJzIG5lZWRlZCBieSB0aGUgaWFtIHNlcnZlci4gIEFmdGVyIHNldHRpbmcgYW55IG9wdGlvbmFsCiAgICAgICAqIHBhcmFtZXRlcnMsIGNhbGwgdGhlIHtAbGluayBVcGRhdGUjZXhlY3V0ZSgpfSBtZXRob2QgdG8gaW52b2tlIHRoZSByZW1vdGUgb3BlcmF0aW9uLgogICAgICAgKgogICAgICAgKiBAcGFyYW0gbmFtZSBUaGUgcmVzb3VyY2UgbmFtZSBvZiB0aGUgc2VydmljZSBhY2NvdW50IGluIHRoZSBmb2xsb3dpbmcgZm9ybWF0OgogICAgICAgKiAgICAgICAgYHByb2plY3RzL3tQUk9KRUNUX0lEfS9zZXJ2aWNlQWNjb3VudHMve0FDQ09VTlR9YC4KICAgICAgUmVxdWVzdHMgdXNpbmcgYC1gIGFzIGEgd2lsZGNhcmQgZm9yCiAgICAgICAqICAgICAgICB0aGUgYFBST0pFQ1RfSURgIHdpbGwgaW5mZXIgdGhlCiAgICAgIHByb2plY3QgZnJvbSB0aGUgYGFjY291bnRgIGFuZCB0aGUgYEFDQ09VTlRgIHZhbHVlIGNhbiBiZQogICAgICAgKiAgICAgICAgdGhlIGBlbWFpbGAKICAgICAgYWRkcmVzcyBvciB0aGUgYHVuaXF1ZV9pZGAgb2YgdGhlIHNlcnZpY2UgYWNjb3VudC4KICAgICAgSW4gcmVzcG9uc2VzIHRoZSByZXNvdXJjZQogICAgICAgKiAgICAgICAgbmFtZSB3aWxsIGFsd2F5cyBiZSBpbiB0aGUgZm9ybWF0CiAgICAgIGBwcm9qZWN0cy97UFJPSkVDVF9JRH0vc2VydmljZUFjY291bnRzL3tBQ0NPVU5UfWAuCiAgICAgICAqIEBwYXJhbSBjb250ZW50IHRoZSB7QGxpbmsgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuaWFtLnYxLm1vZGVsLlNlcnZpY2VBY2NvdW50fQogICAgICAgKiBAcmV0dXJuIHRoZSByZXF1ZXN0CiAgICAgICAqLwogICAgICBwdWJsaWMgVXBkYXRlIHVwZGF0ZShqYXZhLmxhbmcuU3RyaW5nIG5hbWUsIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmlhbS52MS5tb2RlbC5TZXJ2aWNlQWNjb3VudCBjb250ZW50KSB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgVXBkYXRlIHJlc3VsdCA9IG5ldyBVcGRhdGUobmFtZSwgY29udGVudCk7CiAgICAgICAgaW5pdGlhbGl6ZShyZXN1bHQpOwogICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KCiAgICAgIHB1YmxpYyBjbGFzcyBVcGRhdGUgZXh0ZW5kcyBJYW1SZXF1ZXN0PGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmlhbS52MS5tb2RlbC5TZXJ2aWNlQWNjb3VudD4gewoKICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgUkVTVF9QQVRIID0gInYxL3srbmFtZX0iOwoKICAgICAgICBwcml2YXRlIGZpbmFsIGphdmEudXRpbC5yZWdleC5QYXR0ZXJuIE5BTUVfUEFUVEVSTiA9CiAgICAgICAgICAgIGphdmEudXRpbC5yZWdleC5QYXR0ZXJuLmNvbXBpbGUoIl5wcm9qZWN0cy9bXi9dKy9zZXJ2aWNlQWNjb3VudHMvW14vXSskIik7CgogICAgICAgIC8qKgogICAgICAgICAqIE5vdGU6IFRoaXMgbWV0aG9kIGlzIGluIHRoZSBwcm9jZXNzIG9mIGJlaW5nIGRlcHJlY2F0ZWQuIFVzZSBQYXRjaFNlcnZpY2VBY2NvdW50IGluc3RlYWQuCiAgICAgICAgICoKICAgICAgICAgKiBVcGRhdGVzIGEgU2VydmljZUFjY291bnQuCiAgICAgICAgICoKICAgICAgICAgKiBDdXJyZW50bHksIG9ubHkgdGhlIGZvbGxvd2luZyBmaWVsZHMgYXJlIHVwZGF0YWJsZTogYGRpc3BsYXlfbmFtZWAgYW5kIGBkZXNjcmlwdGlvbmAuCiAgICAgICAgICoKICAgICAgICAgKiBDcmVhdGUgYSByZXF1ZXN0IGZvciB0aGUgbWV0aG9kICJzZXJ2aWNlQWNjb3VudHMudXBkYXRlIi4KICAgICAgICAgKgogICAgICAgICAqIFRoaXMgcmVxdWVzdCBob2xkcyB0aGUgcGFyYW1ldGVycyBuZWVkZWQgYnkgdGhlIHRoZSBpYW0gc2VydmVyLiAgQWZ0ZXIgc2V0dGluZyBhbnkgb3B0aW9uYWwKICAgICAgICAgKiBwYXJhbWV0ZXJzLCBjYWxsIHRoZSB7QGxpbmsgVXBkYXRlI2V4ZWN1dGUoKX0gbWV0aG9kIHRvIGludm9rZSB0aGUgcmVtb3RlIG9wZXJhdGlvbi4gPHA+IHtAbGluawogICAgICAgICAqIFVwZGF0ZSNpbml0aWFsaXplKGNvbS5nb29nbGUuYXBpLmNsaWVudC5nb29nbGVhcGlzLnNlcnZpY2VzLkFic3RyYWN0R29vZ2xlQ2xpZW50UmVxdWVzdCl9IG11c3QKICAgICAgICAgKiBiZSBjYWxsZWQgdG8gaW5pdGlhbGl6ZSB0aGlzIGluc3RhbmNlIGltbWVkaWF0ZWx5IGFmdGVyIGludm9raW5nIHRoZSBjb25zdHJ1Y3Rvci4gPC9wPgogICAgICAgICAqCiAgICAgICAgICogQHBhcmFtIG5hbWUgVGhlIHJlc291cmNlIG5hbWUgb2YgdGhlIHNlcnZpY2UgYWNjb3VudCBpbiB0aGUgZm9sbG93aW5nIGZvcm1hdDoKICAgICAgICogICAgICAgIGBwcm9qZWN0cy97UFJPSkVDVF9JRH0vc2VydmljZUFjY291bnRzL3tBQ0NPVU5UfWAuCiAgICAgIFJlcXVlc3RzIHVzaW5nIGAtYCBhcyBhIHdpbGRjYXJkIGZvcgogICAgICAgKiAgICAgICAgdGhlIGBQUk9KRUNUX0lEYCB3aWxsIGluZmVyIHRoZQogICAgICBwcm9qZWN0IGZyb20gdGhlIGBhY2NvdW50YCBhbmQgdGhlIGBBQ0NPVU5UYCB2YWx1ZSBjYW4gYmUKICAgICAgICogICAgICAgIHRoZSBgZW1haWxgCiAgICAgIGFkZHJlc3Mgb3IgdGhlIGB1bmlxdWVfaWRgIG9mIHRoZSBzZXJ2aWNlIGFjY291bnQuCiAgICAgIEluIHJlc3BvbnNlcyB0aGUgcmVzb3VyY2UKICAgICAgICogICAgICAgIG5hbWUgd2lsbCBhbHdheXMgYmUgaW4gdGhlIGZvcm1hdAogICAgICBgcHJvamVjdHMve1BST0pFQ1RfSUR9L3NlcnZpY2VBY2NvdW50cy97QUNDT1VOVH1gLgogICAgICAgICAqIEBwYXJhbSBjb250ZW50IHRoZSB7QGxpbmsgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuaWFtLnYxLm1vZGVsLlNlcnZpY2VBY2NvdW50fQogICAgICAgICAqIEBzaW5jZSAxLjEzCiAgICAgICAgICovCiAgICAgICAgcHJvdGVjdGVkIFVwZGF0ZShqYXZhLmxhbmcuU3RyaW5nIG5hbWUsIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmlhbS52MS5tb2RlbC5TZXJ2aWNlQWNjb3VudCBjb250ZW50KSB7CiAgICAgICAgICBzdXBlcihJYW0udGhpcywgIlBVVCIsIFJFU1RfUEFUSCwgY29udGVudCwgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuaWFtLnYxLm1vZGVsLlNlcnZpY2VBY2NvdW50LmNsYXNzKTsKICAgICAgICAgIHRoaXMubmFtZSA9IGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLlByZWNvbmRpdGlvbnMuY2hlY2tOb3ROdWxsKG5hbWUsICJSZXF1aXJlZCBwYXJhbWV0ZXIgbmFtZSBtdXN0IGJlIHNwZWNpZmllZC4iKTsKICAgICAgICAgIGlmICghZ2V0U3VwcHJlc3NQYXR0ZXJuQ2hlY2tzKCkpIHsKICAgICAgICAgICAgY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuUHJlY29uZGl0aW9ucy5jaGVja0FyZ3VtZW50KE5BTUVfUEFUVEVSTi5tYXRjaGVyKG5hbWUpLm1hdGNoZXMoKSwKICAgICAgICAgICAgICAgICJQYXJhbWV0ZXIgbmFtZSBtdXN0IGNvbmZvcm0gdG8gdGhlIHBhdHRlcm4gIiArCiAgICAgICAgICAgICAgICAiXnByb2plY3RzL1teL10rL3NlcnZpY2VBY2NvdW50cy9bXi9dKyQiKTsKICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBVcGRhdGUgc2V0JFhnYWZ2KGphdmEubGFuZy5TdHJpbmcgJFhnYWZ2KSB7CiAgICAgICAgICByZXR1cm4gKFVwZGF0ZSkgc3VwZXIuc2V0JFhnYWZ2KCRYZ2Fmdik7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgVXBkYXRlIHNldEFjY2Vzc1Rva2VuKGphdmEubGFuZy5TdHJpbmcgYWNjZXNzVG9rZW4pIHsKICAgICAgICAgIHJldHVybiAoVXBkYXRlKSBzdXBlci5zZXRBY2Nlc3NUb2tlbihhY2Nlc3NUb2tlbik7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgVXBkYXRlIHNldEFsdChqYXZhLmxhbmcuU3RyaW5nIGFsdCkgewogICAgICAgICAgcmV0dXJuIChVcGRhdGUpIHN1cGVyLnNldEFsdChhbHQpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFVwZGF0ZSBzZXRDYWxsYmFjayhqYXZhLmxhbmcuU3RyaW5nIGNhbGxiYWNrKSB7CiAgICAgICAgICByZXR1cm4gKFVwZGF0ZSkgc3VwZXIuc2V0Q2FsbGJhY2soY2FsbGJhY2spOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFVwZGF0ZSBzZXRGaWVsZHMoamF2YS5sYW5nLlN0cmluZyBmaWVsZHMpIHsKICAgICAgICAgIHJldHVybiAoVXBkYXRlKSBzdXBlci5zZXRGaWVsZHMoZmllbGRzKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBVcGRhdGUgc2V0S2V5KGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgICByZXR1cm4gKFVwZGF0ZSkgc3VwZXIuc2V0S2V5KGtleSk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgVXBkYXRlIHNldE9hdXRoVG9rZW4oamF2YS5sYW5nLlN0cmluZyBvYXV0aFRva2VuKSB7CiAgICAgICAgICByZXR1cm4gKFVwZGF0ZSkgc3VwZXIuc2V0T2F1dGhUb2tlbihvYXV0aFRva2VuKTsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBVcGRhdGUgc2V0UHJldHR5UHJpbnQoamF2YS5sYW5nLkJvb2xlYW4gcHJldHR5UHJpbnQpIHsKICAgICAgICAgIHJldHVybiAoVXBkYXRlKSBzdXBlci5zZXRQcmV0dHlQcmludChwcmV0dHlQcmludCk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgVXBkYXRlIHNldFF1b3RhVXNlcihqYXZhLmxhbmcuU3RyaW5nIHF1b3RhVXNlcikgewogICAgICAgICAgcmV0dXJuIChVcGRhdGUpIHN1cGVyLnNldFF1b3RhVXNlcihxdW90YVVzZXIpOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIFVwZGF0ZSBzZXRVcGxvYWRUeXBlKGphdmEubGFuZy5TdHJpbmcgdXBsb2FkVHlwZSkgewogICAgICAgICAgcmV0dXJuIChVcGRhdGUpIHN1cGVyLnNldFVwbG9hZFR5cGUodXBsb2FkVHlwZSk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgVXBkYXRlIHNldFVwbG9hZFByb3RvY29sKGphdmEubGFuZy5TdHJpbmcgdXBsb2FkUHJvdG9jb2wpIHsKICAgICAgICAgIHJldHVybiAoVXBkYXRlKSBzdXBlci5zZXRVcGxvYWRQcm90b2NvbCh1cGxvYWRQcm90b2NvbCk7CiAgICAgICAgfQoKICAgICAgICAvKioKICAgICAgICAgKiBUaGUgcmVzb3VyY2UgbmFtZSBvZiB0aGUgc2VydmljZSBhY2NvdW50IGluIHRoZSBmb2xsb3dpbmcgZm9ybWF0OgogICAgICAgICAqIGBwcm9qZWN0cy97UFJPSkVDVF9JRH0vc2VydmljZUFjY291bnRzL3tBQ0NPVU5UfWAuCiAgICAgICAgICoKICAgICAgICAgKiBSZXF1ZXN0cyB1c2luZyBgLWAgYXMgYSB3aWxkY2FyZCBmb3IgdGhlIGBQUk9KRUNUX0lEYCB3aWxsIGluZmVyIHRoZSBwcm9qZWN0IGZyb20gdGhlCiAgICAgICAgICogYGFjY291bnRgIGFuZCB0aGUgYEFDQ09VTlRgIHZhbHVlIGNhbiBiZSB0aGUgYGVtYWlsYCBhZGRyZXNzIG9yIHRoZSBgdW5pcXVlX2lkYCBvZiB0aGUKICAgICAgICAgKiBzZXJ2aWNlIGFjY291bnQuCiAgICAgICAgICoKICAgICAgICAgKiBJbiByZXNwb25zZXMgdGhlIHJlc291cmNlIG5hbWUgd2lsbCBhbHdheXMgYmUgaW4gdGhlIGZvcm1hdAogICAgICAgICAqIGBwcm9qZWN0cy97UFJPSkVDVF9JRH0vc2VydmljZUFjY291bnRzL3tBQ0NPVU5UfWAuCiAgICAgICAgICovCiAgICAgICAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogICAgICAgIHByaXZhdGUgamF2YS5sYW5nLlN0cmluZyBuYW1lOwoKICAgICAgICAvKiogVGhlIHJlc291cmNlIG5hbWUgb2YgdGhlIHNlcnZpY2UgYWNjb3VudCBpbiB0aGUgZm9sbG93aW5nIGZvcm1hdDoKICAgICAgIGBwcm9qZWN0cy97UFJPSkVDVF9JRH0vc2VydmljZUFjY291bnRzL3tBQ0NPVU5UfWAuCgogICAgICAgUmVxdWVzdHMgdXNpbmcgYC1gIGFzIGEgd2lsZGNhcmQgZm9yIHRoZSBgUFJPSkVDVF9JRGAgd2lsbCBpbmZlciB0aGUgcHJvamVjdCBmcm9tIHRoZSBgYWNjb3VudGAgYW5kCiAgICAgICB0aGUgYEFDQ09VTlRgIHZhbHVlIGNhbiBiZSB0aGUgYGVtYWlsYCBhZGRyZXNzIG9yIHRoZSBgdW5pcXVlX2lkYCBvZiB0aGUgc2VydmljZSBhY2NvdW50LgoKICAgICAgIEluIHJlc3BvbnNlcyB0aGUgcmVzb3VyY2UgbmFtZSB3aWxsIGFsd2F5cyBiZSBpbiB0aGUgZm9ybWF0CiAgICAgICBgcHJvamVjdHMve1BST0pFQ1RfSUR9L3NlcnZpY2VBY2NvdW50cy97QUNDT1VOVH1gLgogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldE5hbWUoKSB7CiAgICAgICAgICByZXR1cm4gbmFtZTsKICAgICAgICB9CgogICAgICAgIC8qKgogICAgICAgICAqIFRoZSByZXNvdXJjZSBuYW1lIG9mIHRoZSBzZXJ2aWNlIGFjY291bnQgaW4gdGhlIGZvbGxvd2luZyBmb3JtYXQ6CiAgICAgICAgICogYHByb2plY3RzL3tQUk9KRUNUX0lEfS9zZXJ2aWNlQWNjb3VudHMve0FDQ09VTlR9YC4KICAgICAgICAgKgogICAgICAgICAqIFJlcXVlc3RzIHVzaW5nIGAtYCBhcyBhIHdpbGRjYXJkIGZvciB0aGUgYFBST0pFQ1RfSURgIHdpbGwgaW5mZXIgdGhlIHByb2plY3QgZnJvbSB0aGUKICAgICAgICAgKiBgYWNjb3VudGAgYW5kIHRoZSBgQUNDT1VOVGAgdmFsdWUgY2FuIGJlIHRoZSBgZW1haWxgIGFkZHJlc3Mgb3IgdGhlIGB1bmlxdWVfaWRgIG9mIHRoZQogICAgICAgICAqIHNlcnZpY2UgYWNjb3VudC4KICAgICAgICAgKgogICAgICAgICAqIEluIHJlc3BvbnNlcyB0aGUgcmVzb3VyY2UgbmFtZSB3aWxsIGFsd2F5cyBiZSBpbiB0aGUgZm9ybWF0CiAgICAgICAgICogYHByb2plY3RzL3tQUk9KRUNUX0lEfS9zZXJ2aWNlQWNjb3VudHMve0FDQ09VTlR9YC4KICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgVXBkYXRlIHNldE5hbWUoamF2YS5sYW5nLlN0cmluZyBuYW1lKSB7CiAgICAgICAgICBpZiAoIWdldFN1cHByZXNzUGF0dGVybkNoZWNrcygpKSB7CiAgICAgICAgICAgIGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLlByZWNvbmRpdGlvbnMuY2hlY2tBcmd1bWVudChOQU1FX1BBVFRFUk4ubWF0Y2hlcihuYW1lKS5tYXRjaGVzKCksCiAgICAgICAgICAgICAgICAiUGFyYW1ldGVyIG5hbWUgbXVzdCBjb25mb3JtIHRvIHRoZSBwYXR0ZXJuICIgKwogICAgICAgICAgICAgICAgIl5wcm9qZWN0cy9bXi9dKy9zZXJ2aWNlQWNjb3VudHMvW14vXSskIik7CiAgICAgICAgICB9CiAgICAgICAgICB0aGlzLm5hbWUgPSBuYW1lOwogICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgVXBkYXRlIHNldChTdHJpbmcgcGFyYW1ldGVyTmFtZSwgT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgICByZXR1cm4gKFVwZGF0ZSkgc3VwZXIuc2V0KHBhcmFtZXRlck5hbWUsIHZhbHVlKTsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIC8qKgogICAgICAgKiBBbiBhY2Nlc3NvciBmb3IgY3JlYXRpbmcgcmVxdWVzdHMgZnJvbSB0aGUgS2V5cyBjb2xsZWN0aW9uLgogICAgICAgKgogICAgICAgKiA8cD5UaGUgdHlwaWNhbCB1c2UgaXM6PC9wPgogICAgICAgKiA8cHJlPgogICAgICAgKiAgIHtAY29kZSBJYW0gaWFtID0gbmV3IElhbSguLi4pO30KICAgICAgICogICB7QGNvZGUgSWFtLktleXMuTGlzdCByZXF1ZXN0ID0gaWFtLmtleXMoKS5saXN0KHBhcmFtZXRlcnMgLi4uKX0KICAgICAgICogPC9wcmU+CiAgICAgICAqCiAgICAgICAqIEByZXR1cm4gdGhlIHJlc291cmNlIGNvbGxlY3Rpb24KICAgICAgICovCiAgICAgIHB1YmxpYyBLZXlzIGtleXMoKSB7CiAgICAgICAgcmV0dXJuIG5ldyBLZXlzKCk7CiAgICAgIH0KCiAgICAgIC8qKgogICAgICAgKiBUaGUgImtleXMiIGNvbGxlY3Rpb24gb2YgbWV0aG9kcy4KICAgICAgICovCiAgICAgIHB1YmxpYyBjbGFzcyBLZXlzIHsKCiAgICAgICAgLyoqCiAgICAgICAgICogQ3JlYXRlcyBhIFNlcnZpY2VBY2NvdW50S2V5IGFuZCByZXR1cm5zIGl0LgogICAgICAgICAqCiAgICAgICAgICogQ3JlYXRlIGEgcmVxdWVzdCBmb3IgdGhlIG1ldGhvZCAia2V5cy5jcmVhdGUiLgogICAgICAgICAqCiAgICAgICAgICogVGhpcyByZXF1ZXN0IGhvbGRzIHRoZSBwYXJhbWV0ZXJzIG5lZWRlZCBieSB0aGUgaWFtIHNlcnZlci4gIEFmdGVyIHNldHRpbmcgYW55IG9wdGlvbmFsCiAgICAgICAgICogcGFyYW1ldGVycywgY2FsbCB0aGUge0BsaW5rIENyZWF0ZSNleGVjdXRlKCl9IG1ldGhvZCB0byBpbnZva2UgdGhlIHJlbW90ZSBvcGVyYXRpb24uCiAgICAgICAgICoKICAgICAgICAgKiBAcGFyYW0gbmFtZSBSZXF1aXJlZC4gVGhlIHJlc291cmNlIG5hbWUgb2YgdGhlIHNlcnZpY2UgYWNjb3VudCBpbiB0aGUgZm9sbG93aW5nIGZvcm1hdDoKICAgICAgICAgKiAgICAgICAgYHByb2plY3RzL3tQUk9KRUNUX0lEfS9zZXJ2aWNlQWNjb3VudHMve0FDQ09VTlR9YC4KICAgICAgICBVc2luZyBgLWAgYXMgYSB3aWxkY2FyZCBmb3IgdGhlCiAgICAgICAgICogICAgICAgIGBQUk9KRUNUX0lEYCB3aWxsIGluZmVyIHRoZSBwcm9qZWN0IGZyb20KICAgICAgICB0aGUgYWNjb3VudC4gVGhlIGBBQ0NPVU5UYCB2YWx1ZSBjYW4gYmUgdGhlCiAgICAgICAgICogICAgICAgIGBlbWFpbGAgYWRkcmVzcyBvciB0aGUKICAgICAgICBgdW5pcXVlX2lkYCBvZiB0aGUgc2VydmljZSBhY2NvdW50LgogICAgICAgICAqIEBwYXJhbSBjb250ZW50IHRoZSB7QGxpbmsgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuaWFtLnYxLm1vZGVsLkNyZWF0ZVNlcnZpY2VBY2NvdW50S2V5UmVxdWVzdH0KICAgICAgICAgKiBAcmV0dXJuIHRoZSByZXF1ZXN0CiAgICAgICAgICovCiAgICAgICAgcHVibGljIENyZWF0ZSBjcmVhdGUoamF2YS5sYW5nLlN0cmluZyBuYW1lLCBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5pYW0udjEubW9kZWwuQ3JlYXRlU2VydmljZUFjY291bnRLZXlSZXF1ZXN0IGNvbnRlbnQpIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICAgIENyZWF0ZSByZXN1bHQgPSBuZXcgQ3JlYXRlKG5hbWUsIGNvbnRlbnQpOwogICAgICAgICAgaW5pdGlhbGl6ZShyZXN1bHQpOwogICAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBjbGFzcyBDcmVhdGUgZXh0ZW5kcyBJYW1SZXF1ZXN0PGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmlhbS52MS5tb2RlbC5TZXJ2aWNlQWNjb3VudEtleT4gewoKICAgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBSRVNUX1BBVEggPSAidjEveytuYW1lfS9rZXlzIjsKCiAgICAgICAgICBwcml2YXRlIGZpbmFsIGphdmEudXRpbC5yZWdleC5QYXR0ZXJuIE5BTUVfUEFUVEVSTiA9CiAgICAgICAgICAgICAgamF2YS51dGlsLnJlZ2V4LlBhdHRlcm4uY29tcGlsZSgiXnByb2plY3RzL1teL10rL3NlcnZpY2VBY2NvdW50cy9bXi9dKyQiKTsKCiAgICAgICAgICAvKioKICAgICAgICAgICAqIENyZWF0ZXMgYSBTZXJ2aWNlQWNjb3VudEtleSBhbmQgcmV0dXJucyBpdC4KICAgICAgICAgICAqCiAgICAgICAgICAgKiBDcmVhdGUgYSByZXF1ZXN0IGZvciB0aGUgbWV0aG9kICJrZXlzLmNyZWF0ZSIuCiAgICAgICAgICAgKgogICAgICAgICAgICogVGhpcyByZXF1ZXN0IGhvbGRzIHRoZSBwYXJhbWV0ZXJzIG5lZWRlZCBieSB0aGUgdGhlIGlhbSBzZXJ2ZXIuICBBZnRlciBzZXR0aW5nIGFueSBvcHRpb25hbAogICAgICAgICAgICogcGFyYW1ldGVycywgY2FsbCB0aGUge0BsaW5rIENyZWF0ZSNleGVjdXRlKCl9IG1ldGhvZCB0byBpbnZva2UgdGhlIHJlbW90ZSBvcGVyYXRpb24uIDxwPiB7QGxpbmsKICAgICAgICAgICAqIENyZWF0ZSNpbml0aWFsaXplKGNvbS5nb29nbGUuYXBpLmNsaWVudC5nb29nbGVhcGlzLnNlcnZpY2VzLkFic3RyYWN0R29vZ2xlQ2xpZW50UmVxdWVzdCl9IG11c3QKICAgICAgICAgICAqIGJlIGNhbGxlZCB0byBpbml0aWFsaXplIHRoaXMgaW5zdGFuY2UgaW1tZWRpYXRlbHkgYWZ0ZXIgaW52b2tpbmcgdGhlIGNvbnN0cnVjdG9yLiA8L3A+CiAgICAgICAgICAgKgogICAgICAgICAgICogQHBhcmFtIG5hbWUgUmVxdWlyZWQuIFRoZSByZXNvdXJjZSBuYW1lIG9mIHRoZSBzZXJ2aWNlIGFjY291bnQgaW4gdGhlIGZvbGxvd2luZyBmb3JtYXQ6CiAgICAgICAgICogICAgICAgIGBwcm9qZWN0cy97UFJPSkVDVF9JRH0vc2VydmljZUFjY291bnRzL3tBQ0NPVU5UfWAuCiAgICAgICAgVXNpbmcgYC1gIGFzIGEgd2lsZGNhcmQgZm9yIHRoZQogICAgICAgICAqICAgICAgICBgUFJPSkVDVF9JRGAgd2lsbCBpbmZlciB0aGUgcHJvamVjdCBmcm9tCiAgICAgICAgdGhlIGFjY291bnQuIFRoZSBgQUNDT1VOVGAgdmFsdWUgY2FuIGJlIHRoZQogICAgICAgICAqICAgICAgICBgZW1haWxgIGFkZHJlc3Mgb3IgdGhlCiAgICAgICAgYHVuaXF1ZV9pZGAgb2YgdGhlIHNlcnZpY2UgYWNjb3VudC4KICAgICAgICAgICAqIEBwYXJhbSBjb250ZW50IHRoZSB7QGxpbmsgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuaWFtLnYxLm1vZGVsLkNyZWF0ZVNlcnZpY2VBY2NvdW50S2V5UmVxdWVzdH0KICAgICAgICAgICAqIEBzaW5jZSAxLjEzCiAgICAgICAgICAgKi8KICAgICAgICAgIHByb3RlY3RlZCBDcmVhdGUoamF2YS5sYW5nLlN0cmluZyBuYW1lLCBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5pYW0udjEubW9kZWwuQ3JlYXRlU2VydmljZUFjY291bnRLZXlSZXF1ZXN0IGNvbnRlbnQpIHsKICAgICAgICAgICAgc3VwZXIoSWFtLnRoaXMsICJQT1NUIiwgUkVTVF9QQVRILCBjb250ZW50LCBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5pYW0udjEubW9kZWwuU2VydmljZUFjY291bnRLZXkuY2xhc3MpOwogICAgICAgICAgICB0aGlzLm5hbWUgPSBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5QcmVjb25kaXRpb25zLmNoZWNrTm90TnVsbChuYW1lLCAiUmVxdWlyZWQgcGFyYW1ldGVyIG5hbWUgbXVzdCBiZSBzcGVjaWZpZWQuIik7CiAgICAgICAgICAgIGlmICghZ2V0U3VwcHJlc3NQYXR0ZXJuQ2hlY2tzKCkpIHsKICAgICAgICAgICAgICBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5QcmVjb25kaXRpb25zLmNoZWNrQXJndW1lbnQoTkFNRV9QQVRURVJOLm1hdGNoZXIobmFtZSkubWF0Y2hlcygpLAogICAgICAgICAgICAgICAgICAiUGFyYW1ldGVyIG5hbWUgbXVzdCBjb25mb3JtIHRvIHRoZSBwYXR0ZXJuICIgKwogICAgICAgICAgICAgICAgICAiXnByb2plY3RzL1teL10rL3NlcnZpY2VBY2NvdW50cy9bXi9dKyQiKTsKICAgICAgICAgICAgfQogICAgICAgICAgfQoKICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgcHVibGljIENyZWF0ZSBzZXQkWGdhZnYoamF2YS5sYW5nLlN0cmluZyAkWGdhZnYpIHsKICAgICAgICAgICAgcmV0dXJuIChDcmVhdGUpIHN1cGVyLnNldCRYZ2FmdigkWGdhZnYpOwogICAgICAgICAgfQoKICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgcHVibGljIENyZWF0ZSBzZXRBY2Nlc3NUb2tlbihqYXZhLmxhbmcuU3RyaW5nIGFjY2Vzc1Rva2VuKSB7CiAgICAgICAgICAgIHJldHVybiAoQ3JlYXRlKSBzdXBlci5zZXRBY2Nlc3NUb2tlbihhY2Nlc3NUb2tlbik7CiAgICAgICAgICB9CgogICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICBwdWJsaWMgQ3JlYXRlIHNldEFsdChqYXZhLmxhbmcuU3RyaW5nIGFsdCkgewogICAgICAgICAgICByZXR1cm4gKENyZWF0ZSkgc3VwZXIuc2V0QWx0KGFsdCk7CiAgICAgICAgICB9CgogICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICBwdWJsaWMgQ3JlYXRlIHNldENhbGxiYWNrKGphdmEubGFuZy5TdHJpbmcgY2FsbGJhY2spIHsKICAgICAgICAgICAgcmV0dXJuIChDcmVhdGUpIHN1cGVyLnNldENhbGxiYWNrKGNhbGxiYWNrKTsKICAgICAgICAgIH0KCiAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgIHB1YmxpYyBDcmVhdGUgc2V0RmllbGRzKGphdmEubGFuZy5TdHJpbmcgZmllbGRzKSB7CiAgICAgICAgICAgIHJldHVybiAoQ3JlYXRlKSBzdXBlci5zZXRGaWVsZHMoZmllbGRzKTsKICAgICAgICAgIH0KCiAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgIHB1YmxpYyBDcmVhdGUgc2V0S2V5KGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgICAgIHJldHVybiAoQ3JlYXRlKSBzdXBlci5zZXRLZXkoa2V5KTsKICAgICAgICAgIH0KCiAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgIHB1YmxpYyBDcmVhdGUgc2V0T2F1dGhUb2tlbihqYXZhLmxhbmcuU3RyaW5nIG9hdXRoVG9rZW4pIHsKICAgICAgICAgICAgcmV0dXJuIChDcmVhdGUpIHN1cGVyLnNldE9hdXRoVG9rZW4ob2F1dGhUb2tlbik7CiAgICAgICAgICB9CgogICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICBwdWJsaWMgQ3JlYXRlIHNldFByZXR0eVByaW50KGphdmEubGFuZy5Cb29sZWFuIHByZXR0eVByaW50KSB7CiAgICAgICAgICAgIHJldHVybiAoQ3JlYXRlKSBzdXBlci5zZXRQcmV0dHlQcmludChwcmV0dHlQcmludCk7CiAgICAgICAgICB9CgogICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICBwdWJsaWMgQ3JlYXRlIHNldFF1b3RhVXNlcihqYXZhLmxhbmcuU3RyaW5nIHF1b3RhVXNlcikgewogICAgICAgICAgICByZXR1cm4gKENyZWF0ZSkgc3VwZXIuc2V0UXVvdGFVc2VyKHF1b3RhVXNlcik7CiAgICAgICAgICB9CgogICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICBwdWJsaWMgQ3JlYXRlIHNldFVwbG9hZFR5cGUoamF2YS5sYW5nLlN0cmluZyB1cGxvYWRUeXBlKSB7CiAgICAgICAgICAgIHJldHVybiAoQ3JlYXRlKSBzdXBlci5zZXRVcGxvYWRUeXBlKHVwbG9hZFR5cGUpOwogICAgICAgICAgfQoKICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgcHVibGljIENyZWF0ZSBzZXRVcGxvYWRQcm90b2NvbChqYXZhLmxhbmcuU3RyaW5nIHVwbG9hZFByb3RvY29sKSB7CiAgICAgICAgICAgIHJldHVybiAoQ3JlYXRlKSBzdXBlci5zZXRVcGxvYWRQcm90b2NvbCh1cGxvYWRQcm90b2NvbCk7CiAgICAgICAgICB9CgogICAgICAgICAgLyoqCiAgICAgICAgICAgKiBSZXF1aXJlZC4gVGhlIHJlc291cmNlIG5hbWUgb2YgdGhlIHNlcnZpY2UgYWNjb3VudCBpbiB0aGUgZm9sbG93aW5nIGZvcm1hdDoKICAgICAgICAgICAqIGBwcm9qZWN0cy97UFJPSkVDVF9JRH0vc2VydmljZUFjY291bnRzL3tBQ0NPVU5UfWAuIFVzaW5nIGAtYCBhcyBhIHdpbGRjYXJkIGZvciB0aGUKICAgICAgICAgICAqIGBQUk9KRUNUX0lEYCB3aWxsIGluZmVyIHRoZSBwcm9qZWN0IGZyb20gdGhlIGFjY291bnQuIFRoZSBgQUNDT1VOVGAgdmFsdWUgY2FuIGJlIHRoZQogICAgICAgICAgICogYGVtYWlsYCBhZGRyZXNzIG9yIHRoZSBgdW5pcXVlX2lkYCBvZiB0aGUgc2VydmljZSBhY2NvdW50LgogICAgICAgICAgICovCiAgICAgICAgICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgICAgICAgICBwcml2YXRlIGphdmEubGFuZy5TdHJpbmcgbmFtZTsKCiAgICAgICAgICAvKiogUmVxdWlyZWQuIFRoZSByZXNvdXJjZSBuYW1lIG9mIHRoZSBzZXJ2aWNlIGFjY291bnQgaW4gdGhlIGZvbGxvd2luZyBmb3JtYXQ6CiAgICAgICAgIGBwcm9qZWN0cy97UFJPSkVDVF9JRH0vc2VydmljZUFjY291bnRzL3tBQ0NPVU5UfWAuIFVzaW5nIGAtYCBhcyBhIHdpbGRjYXJkIGZvciB0aGUgYFBST0pFQ1RfSURgCiAgICAgICAgIHdpbGwgaW5mZXIgdGhlIHByb2plY3QgZnJvbSB0aGUgYWNjb3VudC4gVGhlIGBBQ0NPVU5UYCB2YWx1ZSBjYW4gYmUgdGhlIGBlbWFpbGAgYWRkcmVzcyBvciB0aGUKICAgICAgICAgYHVuaXF1ZV9pZGAgb2YgdGhlIHNlcnZpY2UgYWNjb3VudC4KICAgICAgICAgICAqLwogICAgICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TmFtZSgpIHsKICAgICAgICAgICAgcmV0dXJuIG5hbWU7CiAgICAgICAgICB9CgogICAgICAgICAgLyoqCiAgICAgICAgICAgKiBSZXF1aXJlZC4gVGhlIHJlc291cmNlIG5hbWUgb2YgdGhlIHNlcnZpY2UgYWNjb3VudCBpbiB0aGUgZm9sbG93aW5nIGZvcm1hdDoKICAgICAgICAgICAqIGBwcm9qZWN0cy97UFJPSkVDVF9JRH0vc2VydmljZUFjY291bnRzL3tBQ0NPVU5UfWAuIFVzaW5nIGAtYCBhcyBhIHdpbGRjYXJkIGZvciB0aGUKICAgICAgICAgICAqIGBQUk9KRUNUX0lEYCB3aWxsIGluZmVyIHRoZSBwcm9qZWN0IGZyb20gdGhlIGFjY291bnQuIFRoZSBgQUNDT1VOVGAgdmFsdWUgY2FuIGJlIHRoZQogICAgICAgICAgICogYGVtYWlsYCBhZGRyZXNzIG9yIHRoZSBgdW5pcXVlX2lkYCBvZiB0aGUgc2VydmljZSBhY2NvdW50LgogICAgICAgICAgICovCiAgICAgICAgICBwdWJsaWMgQ3JlYXRlIHNldE5hbWUoamF2YS5sYW5nLlN0cmluZyBuYW1lKSB7CiAgICAgICAgICAgIGlmICghZ2V0U3VwcHJlc3NQYXR0ZXJuQ2hlY2tzKCkpIHsKICAgICAgICAgICAgICBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5QcmVjb25kaXRpb25zLmNoZWNrQXJndW1lbnQoTkFNRV9QQVRURVJOLm1hdGNoZXIobmFtZSkubWF0Y2hlcygpLAogICAgICAgICAgICAgICAgICAiUGFyYW1ldGVyIG5hbWUgbXVzdCBjb25mb3JtIHRvIHRoZSBwYXR0ZXJuICIgKwogICAgICAgICAgICAgICAgICAiXnByb2plY3RzL1teL10rL3NlcnZpY2VBY2NvdW50cy9bXi9dKyQiKTsKICAgICAgICAgICAgfQogICAgICAgICAgICB0aGlzLm5hbWUgPSBuYW1lOwogICAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICAgIH0KCiAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgIHB1YmxpYyBDcmVhdGUgc2V0KFN0cmluZyBwYXJhbWV0ZXJOYW1lLCBPYmplY3QgdmFsdWUpIHsKICAgICAgICAgICAgcmV0dXJuIChDcmVhdGUpIHN1cGVyLnNldChwYXJhbWV0ZXJOYW1lLCB2YWx1ZSk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIERlbGV0ZXMgYSBTZXJ2aWNlQWNjb3VudEtleS4KICAgICAgICAgKgogICAgICAgICAqIENyZWF0ZSBhIHJlcXVlc3QgZm9yIHRoZSBtZXRob2QgImtleXMuZGVsZXRlIi4KICAgICAgICAgKgogICAgICAgICAqIFRoaXMgcmVxdWVzdCBob2xkcyB0aGUgcGFyYW1ldGVycyBuZWVkZWQgYnkgdGhlIGlhbSBzZXJ2ZXIuICBBZnRlciBzZXR0aW5nIGFueSBvcHRpb25hbAogICAgICAgICAqIHBhcmFtZXRlcnMsIGNhbGwgdGhlIHtAbGluayBEZWxldGUjZXhlY3V0ZSgpfSBtZXRob2QgdG8gaW52b2tlIHRoZSByZW1vdGUgb3BlcmF0aW9uLgogICAgICAgICAqCiAgICAgICAgICogQHBhcmFtIG5hbWUgUmVxdWlyZWQuIFRoZSByZXNvdXJjZSBuYW1lIG9mIHRoZSBzZXJ2aWNlIGFjY291bnQga2V5IGluIHRoZSBmb2xsb3dpbmcgZm9ybWF0OgogICAgICAgICAqICAgICAgICBgcHJvamVjdHMve1BST0pFQ1RfSUR9L3NlcnZpY2VBY2NvdW50cy97QUNDT1VOVH0va2V5cy97a2V5fWAuCiAgICAgICAgVXNpbmcgYC1gIGFzIGEgd2lsZGNhcmQgZm9yCiAgICAgICAgICogICAgICAgIHRoZSBgUFJPSkVDVF9JRGAgd2lsbCBpbmZlciB0aGUgcHJvamVjdCBmcm9tCiAgICAgICAgdGhlIGFjY291bnQuIFRoZSBgQUNDT1VOVGAgdmFsdWUgY2FuIGJlIHRoZQogICAgICAgICAqICAgICAgICBgZW1haWxgIGFkZHJlc3Mgb3IgdGhlCiAgICAgICAgYHVuaXF1ZV9pZGAgb2YgdGhlIHNlcnZpY2UgYWNjb3VudC4KICAgICAgICAgKiBAcmV0dXJuIHRoZSByZXF1ZXN0CiAgICAgICAgICovCiAgICAgICAgcHVibGljIERlbGV0ZSBkZWxldGUoamF2YS5sYW5nLlN0cmluZyBuYW1lKSB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgICBEZWxldGUgcmVzdWx0ID0gbmV3IERlbGV0ZShuYW1lKTsKICAgICAgICAgIGluaXRpYWxpemUocmVzdWx0KTsKICAgICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgY2xhc3MgRGVsZXRlIGV4dGVuZHMgSWFtUmVxdWVzdDxjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5pYW0udjEubW9kZWwuRW1wdHk+IHsKCiAgICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgUkVTVF9QQVRIID0gInYxL3srbmFtZX0iOwoKICAgICAgICAgIHByaXZhdGUgZmluYWwgamF2YS51dGlsLnJlZ2V4LlBhdHRlcm4gTkFNRV9QQVRURVJOID0KICAgICAgICAgICAgICBqYXZhLnV0aWwucmVnZXguUGF0dGVybi5jb21waWxlKCJecHJvamVjdHMvW14vXSsvc2VydmljZUFjY291bnRzL1teL10rL2tleXMvW14vXSskIik7CgogICAgICAgICAgLyoqCiAgICAgICAgICAgKiBEZWxldGVzIGEgU2VydmljZUFjY291bnRLZXkuCiAgICAgICAgICAgKgogICAgICAgICAgICogQ3JlYXRlIGEgcmVxdWVzdCBmb3IgdGhlIG1ldGhvZCAia2V5cy5kZWxldGUiLgogICAgICAgICAgICoKICAgICAgICAgICAqIFRoaXMgcmVxdWVzdCBob2xkcyB0aGUgcGFyYW1ldGVycyBuZWVkZWQgYnkgdGhlIHRoZSBpYW0gc2VydmVyLiAgQWZ0ZXIgc2V0dGluZyBhbnkgb3B0aW9uYWwKICAgICAgICAgICAqIHBhcmFtZXRlcnMsIGNhbGwgdGhlIHtAbGluayBEZWxldGUjZXhlY3V0ZSgpfSBtZXRob2QgdG8gaW52b2tlIHRoZSByZW1vdGUgb3BlcmF0aW9uLiA8cD4ge0BsaW5rCiAgICAgICAgICAgKiBEZWxldGUjaW5pdGlhbGl6ZShjb20uZ29vZ2xlLmFwaS5jbGllbnQuZ29vZ2xlYXBpcy5zZXJ2aWNlcy5BYnN0cmFjdEdvb2dsZUNsaWVudFJlcXVlc3QpfSBtdXN0CiAgICAgICAgICAgKiBiZSBjYWxsZWQgdG8gaW5pdGlhbGl6ZSB0aGlzIGluc3RhbmNlIGltbWVkaWF0ZWx5IGFmdGVyIGludm9raW5nIHRoZSBjb25zdHJ1Y3Rvci4gPC9wPgogICAgICAgICAgICoKICAgICAgICAgICAqIEBwYXJhbSBuYW1lIFJlcXVpcmVkLiBUaGUgcmVzb3VyY2UgbmFtZSBvZiB0aGUgc2VydmljZSBhY2NvdW50IGtleSBpbiB0aGUgZm9sbG93aW5nIGZvcm1hdDoKICAgICAgICAgKiAgICAgICAgYHByb2plY3RzL3tQUk9KRUNUX0lEfS9zZXJ2aWNlQWNjb3VudHMve0FDQ09VTlR9L2tleXMve2tleX1gLgogICAgICAgIFVzaW5nIGAtYCBhcyBhIHdpbGRjYXJkIGZvcgogICAgICAgICAqICAgICAgICB0aGUgYFBST0pFQ1RfSURgIHdpbGwgaW5mZXIgdGhlIHByb2plY3QgZnJvbQogICAgICAgIHRoZSBhY2NvdW50LiBUaGUgYEFDQ09VTlRgIHZhbHVlIGNhbiBiZSB0aGUKICAgICAgICAgKiAgICAgICAgYGVtYWlsYCBhZGRyZXNzIG9yIHRoZQogICAgICAgIGB1bmlxdWVfaWRgIG9mIHRoZSBzZXJ2aWNlIGFjY291bnQuCiAgICAgICAgICAgKiBAc2luY2UgMS4xMwogICAgICAgICAgICovCiAgICAgICAgICBwcm90ZWN0ZWQgRGVsZXRlKGphdmEubGFuZy5TdHJpbmcgbmFtZSkgewogICAgICAgICAgICBzdXBlcihJYW0udGhpcywgIkRFTEVURSIsIFJFU1RfUEFUSCwgbnVsbCwgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuaWFtLnYxLm1vZGVsLkVtcHR5LmNsYXNzKTsKICAgICAgICAgICAgdGhpcy5uYW1lID0gY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuUHJlY29uZGl0aW9ucy5jaGVja05vdE51bGwobmFtZSwgIlJlcXVpcmVkIHBhcmFtZXRlciBuYW1lIG11c3QgYmUgc3BlY2lmaWVkLiIpOwogICAgICAgICAgICBpZiAoIWdldFN1cHByZXNzUGF0dGVybkNoZWNrcygpKSB7CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuUHJlY29uZGl0aW9ucy5jaGVja0FyZ3VtZW50KE5BTUVfUEFUVEVSTi5tYXRjaGVyKG5hbWUpLm1hdGNoZXMoKSwKICAgICAgICAgICAgICAgICAgIlBhcmFtZXRlciBuYW1lIG11c3QgY29uZm9ybSB0byB0aGUgcGF0dGVybiAiICsKICAgICAgICAgICAgICAgICAgIl5wcm9qZWN0cy9bXi9dKy9zZXJ2aWNlQWNjb3VudHMvW14vXSsva2V5cy9bXi9dKyQiKTsKICAgICAgICAgICAgfQogICAgICAgICAgfQoKICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgcHVibGljIERlbGV0ZSBzZXQkWGdhZnYoamF2YS5sYW5nLlN0cmluZyAkWGdhZnYpIHsKICAgICAgICAgICAgcmV0dXJuIChEZWxldGUpIHN1cGVyLnNldCRYZ2FmdigkWGdhZnYpOwogICAgICAgICAgfQoKICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgcHVibGljIERlbGV0ZSBzZXRBY2Nlc3NUb2tlbihqYXZhLmxhbmcuU3RyaW5nIGFjY2Vzc1Rva2VuKSB7CiAgICAgICAgICAgIHJldHVybiAoRGVsZXRlKSBzdXBlci5zZXRBY2Nlc3NUb2tlbihhY2Nlc3NUb2tlbik7CiAgICAgICAgICB9CgogICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICBwdWJsaWMgRGVsZXRlIHNldEFsdChqYXZhLmxhbmcuU3RyaW5nIGFsdCkgewogICAgICAgICAgICByZXR1cm4gKERlbGV0ZSkgc3VwZXIuc2V0QWx0KGFsdCk7CiAgICAgICAgICB9CgogICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICBwdWJsaWMgRGVsZXRlIHNldENhbGxiYWNrKGphdmEubGFuZy5TdHJpbmcgY2FsbGJhY2spIHsKICAgICAgICAgICAgcmV0dXJuIChEZWxldGUpIHN1cGVyLnNldENhbGxiYWNrKGNhbGxiYWNrKTsKICAgICAgICAgIH0KCiAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgIHB1YmxpYyBEZWxldGUgc2V0RmllbGRzKGphdmEubGFuZy5TdHJpbmcgZmllbGRzKSB7CiAgICAgICAgICAgIHJldHVybiAoRGVsZXRlKSBzdXBlci5zZXRGaWVsZHMoZmllbGRzKTsKICAgICAgICAgIH0KCiAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgIHB1YmxpYyBEZWxldGUgc2V0S2V5KGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgICAgIHJldHVybiAoRGVsZXRlKSBzdXBlci5zZXRLZXkoa2V5KTsKICAgICAgICAgIH0KCiAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgIHB1YmxpYyBEZWxldGUgc2V0T2F1dGhUb2tlbihqYXZhLmxhbmcuU3RyaW5nIG9hdXRoVG9rZW4pIHsKICAgICAgICAgICAgcmV0dXJuIChEZWxldGUpIHN1cGVyLnNldE9hdXRoVG9rZW4ob2F1dGhUb2tlbik7CiAgICAgICAgICB9CgogICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICBwdWJsaWMgRGVsZXRlIHNldFByZXR0eVByaW50KGphdmEubGFuZy5Cb29sZWFuIHByZXR0eVByaW50KSB7CiAgICAgICAgICAgIHJldHVybiAoRGVsZXRlKSBzdXBlci5zZXRQcmV0dHlQcmludChwcmV0dHlQcmludCk7CiAgICAgICAgICB9CgogICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICBwdWJsaWMgRGVsZXRlIHNldFF1b3RhVXNlcihqYXZhLmxhbmcuU3RyaW5nIHF1b3RhVXNlcikgewogICAgICAgICAgICByZXR1cm4gKERlbGV0ZSkgc3VwZXIuc2V0UXVvdGFVc2VyKHF1b3RhVXNlcik7CiAgICAgICAgICB9CgogICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICBwdWJsaWMgRGVsZXRlIHNldFVwbG9hZFR5cGUoamF2YS5sYW5nLlN0cmluZyB1cGxvYWRUeXBlKSB7CiAgICAgICAgICAgIHJldHVybiAoRGVsZXRlKSBzdXBlci5zZXRVcGxvYWRUeXBlKHVwbG9hZFR5cGUpOwogICAgICAgICAgfQoKICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgcHVibGljIERlbGV0ZSBzZXRVcGxvYWRQcm90b2NvbChqYXZhLmxhbmcuU3RyaW5nIHVwbG9hZFByb3RvY29sKSB7CiAgICAgICAgICAgIHJldHVybiAoRGVsZXRlKSBzdXBlci5zZXRVcGxvYWRQcm90b2NvbCh1cGxvYWRQcm90b2NvbCk7CiAgICAgICAgICB9CgogICAgICAgICAgLyoqCiAgICAgICAgICAgKiBSZXF1aXJlZC4gVGhlIHJlc291cmNlIG5hbWUgb2YgdGhlIHNlcnZpY2UgYWNjb3VudCBrZXkgaW4gdGhlIGZvbGxvd2luZyBmb3JtYXQ6CiAgICAgICAgICAgKiBgcHJvamVjdHMve1BST0pFQ1RfSUR9L3NlcnZpY2VBY2NvdW50cy97QUNDT1VOVH0va2V5cy97a2V5fWAuIFVzaW5nIGAtYCBhcyBhIHdpbGRjYXJkCiAgICAgICAgICAgKiBmb3IgdGhlIGBQUk9KRUNUX0lEYCB3aWxsIGluZmVyIHRoZSBwcm9qZWN0IGZyb20gdGhlIGFjY291bnQuIFRoZSBgQUNDT1VOVGAgdmFsdWUgY2FuCiAgICAgICAgICAgKiBiZSB0aGUgYGVtYWlsYCBhZGRyZXNzIG9yIHRoZSBgdW5pcXVlX2lkYCBvZiB0aGUgc2VydmljZSBhY2NvdW50LgogICAgICAgICAgICovCiAgICAgICAgICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgICAgICAgICBwcml2YXRlIGphdmEubGFuZy5TdHJpbmcgbmFtZTsKCiAgICAgICAgICAvKiogUmVxdWlyZWQuIFRoZSByZXNvdXJjZSBuYW1lIG9mIHRoZSBzZXJ2aWNlIGFjY291bnQga2V5IGluIHRoZSBmb2xsb3dpbmcgZm9ybWF0OgogICAgICAgICBgcHJvamVjdHMve1BST0pFQ1RfSUR9L3NlcnZpY2VBY2NvdW50cy97QUNDT1VOVH0va2V5cy97a2V5fWAuIFVzaW5nIGAtYCBhcyBhIHdpbGRjYXJkIGZvciB0aGUKICAgICAgICAgYFBST0pFQ1RfSURgIHdpbGwgaW5mZXIgdGhlIHByb2plY3QgZnJvbSB0aGUgYWNjb3VudC4gVGhlIGBBQ0NPVU5UYCB2YWx1ZSBjYW4gYmUgdGhlIGBlbWFpbGAKICAgICAgICAgYWRkcmVzcyBvciB0aGUgYHVuaXF1ZV9pZGAgb2YgdGhlIHNlcnZpY2UgYWNjb3VudC4KICAgICAgICAgICAqLwogICAgICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TmFtZSgpIHsKICAgICAgICAgICAgcmV0dXJuIG5hbWU7CiAgICAgICAgICB9CgogICAgICAgICAgLyoqCiAgICAgICAgICAgKiBSZXF1aXJlZC4gVGhlIHJlc291cmNlIG5hbWUgb2YgdGhlIHNlcnZpY2UgYWNjb3VudCBrZXkgaW4gdGhlIGZvbGxvd2luZyBmb3JtYXQ6CiAgICAgICAgICAgKiBgcHJvamVjdHMve1BST0pFQ1RfSUR9L3NlcnZpY2VBY2NvdW50cy97QUNDT1VOVH0va2V5cy97a2V5fWAuIFVzaW5nIGAtYCBhcyBhIHdpbGRjYXJkCiAgICAgICAgICAgKiBmb3IgdGhlIGBQUk9KRUNUX0lEYCB3aWxsIGluZmVyIHRoZSBwcm9qZWN0IGZyb20gdGhlIGFjY291bnQuIFRoZSBgQUNDT1VOVGAgdmFsdWUgY2FuCiAgICAgICAgICAgKiBiZSB0aGUgYGVtYWlsYCBhZGRyZXNzIG9yIHRoZSBgdW5pcXVlX2lkYCBvZiB0aGUgc2VydmljZSBhY2NvdW50LgogICAgICAgICAgICovCiAgICAgICAgICBwdWJsaWMgRGVsZXRlIHNldE5hbWUoamF2YS5sYW5nLlN0cmluZyBuYW1lKSB7CiAgICAgICAgICAgIGlmICghZ2V0U3VwcHJlc3NQYXR0ZXJuQ2hlY2tzKCkpIHsKICAgICAgICAgICAgICBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5QcmVjb25kaXRpb25zLmNoZWNrQXJndW1lbnQoTkFNRV9QQVRURVJOLm1hdGNoZXIobmFtZSkubWF0Y2hlcygpLAogICAgICAgICAgICAgICAgICAiUGFyYW1ldGVyIG5hbWUgbXVzdCBjb25mb3JtIHRvIHRoZSBwYXR0ZXJuICIgKwogICAgICAgICAgICAgICAgICAiXnByb2plY3RzL1teL10rL3NlcnZpY2VBY2NvdW50cy9bXi9dKy9rZXlzL1teL10rJCIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHRoaXMubmFtZSA9IG5hbWU7CiAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgICAgfQoKICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgcHVibGljIERlbGV0ZSBzZXQoU3RyaW5nIHBhcmFtZXRlck5hbWUsIE9iamVjdCB2YWx1ZSkgewogICAgICAgICAgICByZXR1cm4gKERlbGV0ZSkgc3VwZXIuc2V0KHBhcmFtZXRlck5hbWUsIHZhbHVlKTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogR2V0cyB0aGUgU2VydmljZUFjY291bnRLZXkgYnkga2V5IGlkLgogICAgICAgICAqCiAgICAgICAgICogQ3JlYXRlIGEgcmVxdWVzdCBmb3IgdGhlIG1ldGhvZCAia2V5cy5nZXQiLgogICAgICAgICAqCiAgICAgICAgICogVGhpcyByZXF1ZXN0IGhvbGRzIHRoZSBwYXJhbWV0ZXJzIG5lZWRlZCBieSB0aGUgaWFtIHNlcnZlci4gIEFmdGVyIHNldHRpbmcgYW55IG9wdGlvbmFsCiAgICAgICAgICogcGFyYW1ldGVycywgY2FsbCB0aGUge0BsaW5rIEdldCNleGVjdXRlKCl9IG1ldGhvZCB0byBpbnZva2UgdGhlIHJlbW90ZSBvcGVyYXRpb24uCiAgICAgICAgICoKICAgICAgICAgKiBAcGFyYW0gbmFtZSBSZXF1aXJlZC4gVGhlIHJlc291cmNlIG5hbWUgb2YgdGhlIHNlcnZpY2UgYWNjb3VudCBrZXkgaW4gdGhlIGZvbGxvd2luZyBmb3JtYXQ6CiAgICAgICAgICogICAgICAgIGBwcm9qZWN0cy97UFJPSkVDVF9JRH0vc2VydmljZUFjY291bnRzL3tBQ0NPVU5UfS9rZXlzL3trZXl9YC4KICAgICAgICBVc2luZyBgLWAgYXMgYSB3aWxkY2FyZCBmb3IKICAgICAgICAgKiAgICAgICAgdGhlIGBQUk9KRUNUX0lEYCB3aWxsIGluZmVyIHRoZSBwcm9qZWN0IGZyb20KICAgICAgICB0aGUgYWNjb3VudC4gVGhlIGBBQ0NPVU5UYCB2YWx1ZSBjYW4gYmUgdGhlCiAgICAgICAgICogICAgICAgIGBlbWFpbGAgYWRkcmVzcyBvciB0aGUKICAgICAgICBgdW5pcXVlX2lkYCBvZiB0aGUgc2VydmljZSBhY2NvdW50LgogICAgICAgICAqIEByZXR1cm4gdGhlIHJlcXVlc3QKICAgICAgICAgKi8KICAgICAgICBwdWJsaWMgR2V0IGdldChqYXZhLmxhbmcuU3RyaW5nIG5hbWUpIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICAgIEdldCByZXN1bHQgPSBuZXcgR2V0KG5hbWUpOwogICAgICAgICAgaW5pdGlhbGl6ZShyZXN1bHQpOwogICAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBjbGFzcyBHZXQgZXh0ZW5kcyBJYW1SZXF1ZXN0PGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmlhbS52MS5tb2RlbC5TZXJ2aWNlQWNjb3VudEtleT4gewoKICAgICAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBSRVNUX1BBVEggPSAidjEveytuYW1lfSI7CgogICAgICAgICAgcHJpdmF0ZSBmaW5hbCBqYXZhLnV0aWwucmVnZXguUGF0dGVybiBOQU1FX1BBVFRFUk4gPQogICAgICAgICAgICAgIGphdmEudXRpbC5yZWdleC5QYXR0ZXJuLmNvbXBpbGUoIl5wcm9qZWN0cy9bXi9dKy9zZXJ2aWNlQWNjb3VudHMvW14vXSsva2V5cy9bXi9dKyQiKTsKCiAgICAgICAgICAvKioKICAgICAgICAgICAqIEdldHMgdGhlIFNlcnZpY2VBY2NvdW50S2V5IGJ5IGtleSBpZC4KICAgICAgICAgICAqCiAgICAgICAgICAgKiBDcmVhdGUgYSByZXF1ZXN0IGZvciB0aGUgbWV0aG9kICJrZXlzLmdldCIuCiAgICAgICAgICAgKgogICAgICAgICAgICogVGhpcyByZXF1ZXN0IGhvbGRzIHRoZSBwYXJhbWV0ZXJzIG5lZWRlZCBieSB0aGUgdGhlIGlhbSBzZXJ2ZXIuICBBZnRlciBzZXR0aW5nIGFueSBvcHRpb25hbAogICAgICAgICAgICogcGFyYW1ldGVycywgY2FsbCB0aGUge0BsaW5rIEdldCNleGVjdXRlKCl9IG1ldGhvZCB0byBpbnZva2UgdGhlIHJlbW90ZSBvcGVyYXRpb24uIDxwPiB7QGxpbmsKICAgICAgICAgICAqIEdldCNpbml0aWFsaXplKGNvbS5nb29nbGUuYXBpLmNsaWVudC5nb29nbGVhcGlzLnNlcnZpY2VzLkFic3RyYWN0R29vZ2xlQ2xpZW50UmVxdWVzdCl9IG11c3QgYmUKICAgICAgICAgICAqIGNhbGxlZCB0byBpbml0aWFsaXplIHRoaXMgaW5zdGFuY2UgaW1tZWRpYXRlbHkgYWZ0ZXIgaW52b2tpbmcgdGhlIGNvbnN0cnVjdG9yLiA8L3A+CiAgICAgICAgICAgKgogICAgICAgICAgICogQHBhcmFtIG5hbWUgUmVxdWlyZWQuIFRoZSByZXNvdXJjZSBuYW1lIG9mIHRoZSBzZXJ2aWNlIGFjY291bnQga2V5IGluIHRoZSBmb2xsb3dpbmcgZm9ybWF0OgogICAgICAgICAqICAgICAgICBgcHJvamVjdHMve1BST0pFQ1RfSUR9L3NlcnZpY2VBY2NvdW50cy97QUNDT1VOVH0va2V5cy97a2V5fWAuCiAgICAgICAgVXNpbmcgYC1gIGFzIGEgd2lsZGNhcmQgZm9yCiAgICAgICAgICogICAgICAgIHRoZSBgUFJPSkVDVF9JRGAgd2lsbCBpbmZlciB0aGUgcHJvamVjdCBmcm9tCiAgICAgICAgdGhlIGFjY291bnQuIFRoZSBgQUNDT1VOVGAgdmFsdWUgY2FuIGJlIHRoZQogICAgICAgICAqICAgICAgICBgZW1haWxgIGFkZHJlc3Mgb3IgdGhlCiAgICAgICAgYHVuaXF1ZV9pZGAgb2YgdGhlIHNlcnZpY2UgYWNjb3VudC4KICAgICAgICAgICAqIEBzaW5jZSAxLjEzCiAgICAgICAgICAgKi8KICAgICAgICAgIHByb3RlY3RlZCBHZXQoamF2YS5sYW5nLlN0cmluZyBuYW1lKSB7CiAgICAgICAgICAgIHN1cGVyKElhbS50aGlzLCAiR0VUIiwgUkVTVF9QQVRILCBudWxsLCBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5pYW0udjEubW9kZWwuU2VydmljZUFjY291bnRLZXkuY2xhc3MpOwogICAgICAgICAgICB0aGlzLm5hbWUgPSBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5QcmVjb25kaXRpb25zLmNoZWNrTm90TnVsbChuYW1lLCAiUmVxdWlyZWQgcGFyYW1ldGVyIG5hbWUgbXVzdCBiZSBzcGVjaWZpZWQuIik7CiAgICAgICAgICAgIGlmICghZ2V0U3VwcHJlc3NQYXR0ZXJuQ2hlY2tzKCkpIHsKICAgICAgICAgICAgICBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5QcmVjb25kaXRpb25zLmNoZWNrQXJndW1lbnQoTkFNRV9QQVRURVJOLm1hdGNoZXIobmFtZSkubWF0Y2hlcygpLAogICAgICAgICAgICAgICAgICAiUGFyYW1ldGVyIG5hbWUgbXVzdCBjb25mb3JtIHRvIHRoZSBwYXR0ZXJuICIgKwogICAgICAgICAgICAgICAgICAiXnByb2plY3RzL1teL10rL3NlcnZpY2VBY2NvdW50cy9bXi9dKy9rZXlzL1teL10rJCIpOwogICAgICAgICAgICB9CiAgICAgICAgICB9CgogICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5hcGkuY2xpZW50Lmh0dHAuSHR0cFJlc3BvbnNlIGV4ZWN1dGVVc2luZ0hlYWQoKSB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgICAgIHJldHVybiBzdXBlci5leGVjdXRlVXNpbmdIZWFkKCk7CiAgICAgICAgICB9CgogICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICBwdWJsaWMgY29tLmdvb2dsZS5hcGkuY2xpZW50Lmh0dHAuSHR0cFJlcXVlc3QgYnVpbGRIdHRwUmVxdWVzdFVzaW5nSGVhZCgpIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmJ1aWxkSHR0cFJlcXVlc3RVc2luZ0hlYWQoKTsKICAgICAgICAgIH0KCiAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgIHB1YmxpYyBHZXQgc2V0JFhnYWZ2KGphdmEubGFuZy5TdHJpbmcgJFhnYWZ2KSB7CiAgICAgICAgICAgIHJldHVybiAoR2V0KSBzdXBlci5zZXQkWGdhZnYoJFhnYWZ2KTsKICAgICAgICAgIH0KCiAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgIHB1YmxpYyBHZXQgc2V0QWNjZXNzVG9rZW4oamF2YS5sYW5nLlN0cmluZyBhY2Nlc3NUb2tlbikgewogICAgICAgICAgICByZXR1cm4gKEdldCkgc3VwZXIuc2V0QWNjZXNzVG9rZW4oYWNjZXNzVG9rZW4pOwogICAgICAgICAgfQoKICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgcHVibGljIEdldCBzZXRBbHQoamF2YS5sYW5nLlN0cmluZyBhbHQpIHsKICAgICAgICAgICAgcmV0dXJuIChHZXQpIHN1cGVyLnNldEFsdChhbHQpOwogICAgICAgICAgfQoKICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgcHVibGljIEdldCBzZXRDYWxsYmFjayhqYXZhLmxhbmcuU3RyaW5nIGNhbGxiYWNrKSB7CiAgICAgICAgICAgIHJldHVybiAoR2V0KSBzdXBlci5zZXRDYWxsYmFjayhjYWxsYmFjayk7CiAgICAgICAgICB9CgogICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICBwdWJsaWMgR2V0IHNldEZpZWxkcyhqYXZhLmxhbmcuU3RyaW5nIGZpZWxkcykgewogICAgICAgICAgICByZXR1cm4gKEdldCkgc3VwZXIuc2V0RmllbGRzKGZpZWxkcyk7CiAgICAgICAgICB9CgogICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICBwdWJsaWMgR2V0IHNldEtleShqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgICAgICByZXR1cm4gKEdldCkgc3VwZXIuc2V0S2V5KGtleSk7CiAgICAgICAgICB9CgogICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICBwdWJsaWMgR2V0IHNldE9hdXRoVG9rZW4oamF2YS5sYW5nLlN0cmluZyBvYXV0aFRva2VuKSB7CiAgICAgICAgICAgIHJldHVybiAoR2V0KSBzdXBlci5zZXRPYXV0aFRva2VuKG9hdXRoVG9rZW4pOwogICAgICAgICAgfQoKICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgcHVibGljIEdldCBzZXRQcmV0dHlQcmludChqYXZhLmxhbmcuQm9vbGVhbiBwcmV0dHlQcmludCkgewogICAgICAgICAgICByZXR1cm4gKEdldCkgc3VwZXIuc2V0UHJldHR5UHJpbnQocHJldHR5UHJpbnQpOwogICAgICAgICAgfQoKICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgcHVibGljIEdldCBzZXRRdW90YVVzZXIoamF2YS5sYW5nLlN0cmluZyBxdW90YVVzZXIpIHsKICAgICAgICAgICAgcmV0dXJuIChHZXQpIHN1cGVyLnNldFF1b3RhVXNlcihxdW90YVVzZXIpOwogICAgICAgICAgfQoKICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgcHVibGljIEdldCBzZXRVcGxvYWRUeXBlKGphdmEubGFuZy5TdHJpbmcgdXBsb2FkVHlwZSkgewogICAgICAgICAgICByZXR1cm4gKEdldCkgc3VwZXIuc2V0VXBsb2FkVHlwZSh1cGxvYWRUeXBlKTsKICAgICAgICAgIH0KCiAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgIHB1YmxpYyBHZXQgc2V0VXBsb2FkUHJvdG9jb2woamF2YS5sYW5nLlN0cmluZyB1cGxvYWRQcm90b2NvbCkgewogICAgICAgICAgICByZXR1cm4gKEdldCkgc3VwZXIuc2V0VXBsb2FkUHJvdG9jb2wodXBsb2FkUHJvdG9jb2wpOwogICAgICAgICAgfQoKICAgICAgICAgIC8qKgogICAgICAgICAgICogUmVxdWlyZWQuIFRoZSByZXNvdXJjZSBuYW1lIG9mIHRoZSBzZXJ2aWNlIGFjY291bnQga2V5IGluIHRoZSBmb2xsb3dpbmcgZm9ybWF0OgogICAgICAgICAgICogYHByb2plY3RzL3tQUk9KRUNUX0lEfS9zZXJ2aWNlQWNjb3VudHMve0FDQ09VTlR9L2tleXMve2tleX1gLgogICAgICAgICAgICoKICAgICAgICAgICAqIFVzaW5nIGAtYCBhcyBhIHdpbGRjYXJkIGZvciB0aGUgYFBST0pFQ1RfSURgIHdpbGwgaW5mZXIgdGhlIHByb2plY3QgZnJvbSB0aGUgYWNjb3VudC4KICAgICAgICAgICAqIFRoZSBgQUNDT1VOVGAgdmFsdWUgY2FuIGJlIHRoZSBgZW1haWxgIGFkZHJlc3Mgb3IgdGhlIGB1bmlxdWVfaWRgIG9mIHRoZSBzZXJ2aWNlCiAgICAgICAgICAgKiBhY2NvdW50LgogICAgICAgICAgICovCiAgICAgICAgICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgICAgICAgICBwcml2YXRlIGphdmEubGFuZy5TdHJpbmcgbmFtZTsKCiAgICAgICAgICAvKiogUmVxdWlyZWQuIFRoZSByZXNvdXJjZSBuYW1lIG9mIHRoZSBzZXJ2aWNlIGFjY291bnQga2V5IGluIHRoZSBmb2xsb3dpbmcgZm9ybWF0OgogICAgICAgICBgcHJvamVjdHMve1BST0pFQ1RfSUR9L3NlcnZpY2VBY2NvdW50cy97QUNDT1VOVH0va2V5cy97a2V5fWAuCgogICAgICAgICBVc2luZyBgLWAgYXMgYSB3aWxkY2FyZCBmb3IgdGhlIGBQUk9KRUNUX0lEYCB3aWxsIGluZmVyIHRoZSBwcm9qZWN0IGZyb20gdGhlIGFjY291bnQuIFRoZSBgQUNDT1VOVGAKICAgICAgICAgdmFsdWUgY2FuIGJlIHRoZSBgZW1haWxgIGFkZHJlc3Mgb3IgdGhlIGB1bmlxdWVfaWRgIG9mIHRoZSBzZXJ2aWNlIGFjY291bnQuCiAgICAgICAgICAgKi8KICAgICAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldE5hbWUoKSB7CiAgICAgICAgICAgIHJldHVybiBuYW1lOwogICAgICAgICAgfQoKICAgICAgICAgIC8qKgogICAgICAgICAgICogUmVxdWlyZWQuIFRoZSByZXNvdXJjZSBuYW1lIG9mIHRoZSBzZXJ2aWNlIGFjY291bnQga2V5IGluIHRoZSBmb2xsb3dpbmcgZm9ybWF0OgogICAgICAgICAgICogYHByb2plY3RzL3tQUk9KRUNUX0lEfS9zZXJ2aWNlQWNjb3VudHMve0FDQ09VTlR9L2tleXMve2tleX1gLgogICAgICAgICAgICoKICAgICAgICAgICAqIFVzaW5nIGAtYCBhcyBhIHdpbGRjYXJkIGZvciB0aGUgYFBST0pFQ1RfSURgIHdpbGwgaW5mZXIgdGhlIHByb2plY3QgZnJvbSB0aGUgYWNjb3VudC4KICAgICAgICAgICAqIFRoZSBgQUNDT1VOVGAgdmFsdWUgY2FuIGJlIHRoZSBgZW1haWxgIGFkZHJlc3Mgb3IgdGhlIGB1bmlxdWVfaWRgIG9mIHRoZSBzZXJ2aWNlCiAgICAgICAgICAgKiBhY2NvdW50LgogICAgICAgICAgICovCiAgICAgICAgICBwdWJsaWMgR2V0IHNldE5hbWUoamF2YS5sYW5nLlN0cmluZyBuYW1lKSB7CiAgICAgICAgICAgIGlmICghZ2V0U3VwcHJlc3NQYXR0ZXJuQ2hlY2tzKCkpIHsKICAgICAgICAgICAgICBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5QcmVjb25kaXRpb25zLmNoZWNrQXJndW1lbnQoTkFNRV9QQVRURVJOLm1hdGNoZXIobmFtZSkubWF0Y2hlcygpLAogICAgICAgICAgICAgICAgICAiUGFyYW1ldGVyIG5hbWUgbXVzdCBjb25mb3JtIHRvIHRoZSBwYXR0ZXJuICIgKwogICAgICAgICAgICAgICAgICAiXnByb2plY3RzL1teL10rL3NlcnZpY2VBY2NvdW50cy9bXi9dKy9rZXlzL1teL10rJCIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHRoaXMubmFtZSA9IG5hbWU7CiAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgICAgfQoKICAgICAgICAgIC8qKgogICAgICAgICAgICogVGhlIG91dHB1dCBmb3JtYXQgb2YgdGhlIHB1YmxpYyBrZXkgcmVxdWVzdGVkLiBYNTA5X1BFTSBpcyB0aGUgZGVmYXVsdCBvdXRwdXQgZm9ybWF0LgogICAgICAgICAgICovCiAgICAgICAgICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgICAgICAgICBwcml2YXRlIGphdmEubGFuZy5TdHJpbmcgcHVibGljS2V5VHlwZTsKCiAgICAgICAgICAvKiogVGhlIG91dHB1dCBmb3JtYXQgb2YgdGhlIHB1YmxpYyBrZXkgcmVxdWVzdGVkLiBYNTA5X1BFTSBpcyB0aGUgZGVmYXVsdCBvdXRwdXQgZm9ybWF0LgogICAgICAgICAgICovCiAgICAgICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRQdWJsaWNLZXlUeXBlKCkgewogICAgICAgICAgICByZXR1cm4gcHVibGljS2V5VHlwZTsKICAgICAgICAgIH0KCiAgICAgICAgICAvKioKICAgICAgICAgICAqIFRoZSBvdXRwdXQgZm9ybWF0IG9mIHRoZSBwdWJsaWMga2V5IHJlcXVlc3RlZC4gWDUwOV9QRU0gaXMgdGhlIGRlZmF1bHQgb3V0cHV0IGZvcm1hdC4KICAgICAgICAgICAqLwogICAgICAgICAgcHVibGljIEdldCBzZXRQdWJsaWNLZXlUeXBlKGphdmEubGFuZy5TdHJpbmcgcHVibGljS2V5VHlwZSkgewogICAgICAgICAgICB0aGlzLnB1YmxpY0tleVR5cGUgPSBwdWJsaWNLZXlUeXBlOwogICAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICAgIH0KCiAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgIHB1YmxpYyBHZXQgc2V0KFN0cmluZyBwYXJhbWV0ZXJOYW1lLCBPYmplY3QgdmFsdWUpIHsKICAgICAgICAgICAgcmV0dXJuIChHZXQpIHN1cGVyLnNldChwYXJhbWV0ZXJOYW1lLCB2YWx1ZSk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIC8qKgogICAgICAgICAqIExpc3RzIFNlcnZpY2VBY2NvdW50S2V5cy4KICAgICAgICAgKgogICAgICAgICAqIENyZWF0ZSBhIHJlcXVlc3QgZm9yIHRoZSBtZXRob2QgImtleXMubGlzdCIuCiAgICAgICAgICoKICAgICAgICAgKiBUaGlzIHJlcXVlc3QgaG9sZHMgdGhlIHBhcmFtZXRlcnMgbmVlZGVkIGJ5IHRoZSBpYW0gc2VydmVyLiAgQWZ0ZXIgc2V0dGluZyBhbnkgb3B0aW9uYWwKICAgICAgICAgKiBwYXJhbWV0ZXJzLCBjYWxsIHRoZSB7QGxpbmsgTGlzdCNleGVjdXRlKCl9IG1ldGhvZCB0byBpbnZva2UgdGhlIHJlbW90ZSBvcGVyYXRpb24uCiAgICAgICAgICoKICAgICAgICAgKiBAcGFyYW0gbmFtZSBSZXF1aXJlZC4gVGhlIHJlc291cmNlIG5hbWUgb2YgdGhlIHNlcnZpY2UgYWNjb3VudCBpbiB0aGUgZm9sbG93aW5nIGZvcm1hdDoKICAgICAgICAgKiAgICAgICAgYHByb2plY3RzL3tQUk9KRUNUX0lEfS9zZXJ2aWNlQWNjb3VudHMve0FDQ09VTlR9YC4KICAgICAgICBVc2luZyBgLWAgYXMgYSB3aWxkY2FyZCBmb3IgdGhlCiAgICAgICAgICogICAgICAgIGBQUk9KRUNUX0lEYCwgd2lsbCBpbmZlciB0aGUgcHJvamVjdCBmcm9tCiAgICAgICAgdGhlIGFjY291bnQuIFRoZSBgQUNDT1VOVGAgdmFsdWUgY2FuIGJlIHRoZQogICAgICAgICAqICAgICAgICBgZW1haWxgIGFkZHJlc3Mgb3IgdGhlCiAgICAgICAgYHVuaXF1ZV9pZGAgb2YgdGhlIHNlcnZpY2UgYWNjb3VudC4KICAgICAgICAgKiBAcmV0dXJuIHRoZSByZXF1ZXN0CiAgICAgICAgICovCiAgICAgICAgcHVibGljIExpc3QgbGlzdChqYXZhLmxhbmcuU3RyaW5nIG5hbWUpIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICAgIExpc3QgcmVzdWx0ID0gbmV3IExpc3QobmFtZSk7CiAgICAgICAgICBpbml0aWFsaXplKHJlc3VsdCk7CiAgICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICAgIH0KCiAgICAgICAgcHVibGljIGNsYXNzIExpc3QgZXh0ZW5kcyBJYW1SZXF1ZXN0PGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmlhbS52MS5tb2RlbC5MaXN0U2VydmljZUFjY291bnRLZXlzUmVzcG9uc2U+IHsKCiAgICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgUkVTVF9QQVRIID0gInYxL3srbmFtZX0va2V5cyI7CgogICAgICAgICAgcHJpdmF0ZSBmaW5hbCBqYXZhLnV0aWwucmVnZXguUGF0dGVybiBOQU1FX1BBVFRFUk4gPQogICAgICAgICAgICAgIGphdmEudXRpbC5yZWdleC5QYXR0ZXJuLmNvbXBpbGUoIl5wcm9qZWN0cy9bXi9dKy9zZXJ2aWNlQWNjb3VudHMvW14vXSskIik7CgogICAgICAgICAgLyoqCiAgICAgICAgICAgKiBMaXN0cyBTZXJ2aWNlQWNjb3VudEtleXMuCiAgICAgICAgICAgKgogICAgICAgICAgICogQ3JlYXRlIGEgcmVxdWVzdCBmb3IgdGhlIG1ldGhvZCAia2V5cy5saXN0Ii4KICAgICAgICAgICAqCiAgICAgICAgICAgKiBUaGlzIHJlcXVlc3QgaG9sZHMgdGhlIHBhcmFtZXRlcnMgbmVlZGVkIGJ5IHRoZSB0aGUgaWFtIHNlcnZlci4gIEFmdGVyIHNldHRpbmcgYW55IG9wdGlvbmFsCiAgICAgICAgICAgKiBwYXJhbWV0ZXJzLCBjYWxsIHRoZSB7QGxpbmsgTGlzdCNleGVjdXRlKCl9IG1ldGhvZCB0byBpbnZva2UgdGhlIHJlbW90ZSBvcGVyYXRpb24uIDxwPiB7QGxpbmsKICAgICAgICAgICAqIExpc3QjaW5pdGlhbGl6ZShjb20uZ29vZ2xlLmFwaS5jbGllbnQuZ29vZ2xlYXBpcy5zZXJ2aWNlcy5BYnN0cmFjdEdvb2dsZUNsaWVudFJlcXVlc3QpfSBtdXN0IGJlCiAgICAgICAgICAgKiBjYWxsZWQgdG8gaW5pdGlhbGl6ZSB0aGlzIGluc3RhbmNlIGltbWVkaWF0ZWx5IGFmdGVyIGludm9raW5nIHRoZSBjb25zdHJ1Y3Rvci4gPC9wPgogICAgICAgICAgICoKICAgICAgICAgICAqIEBwYXJhbSBuYW1lIFJlcXVpcmVkLiBUaGUgcmVzb3VyY2UgbmFtZSBvZiB0aGUgc2VydmljZSBhY2NvdW50IGluIHRoZSBmb2xsb3dpbmcgZm9ybWF0OgogICAgICAgICAqICAgICAgICBgcHJvamVjdHMve1BST0pFQ1RfSUR9L3NlcnZpY2VBY2NvdW50cy97QUNDT1VOVH1gLgogICAgICAgIFVzaW5nIGAtYCBhcyBhIHdpbGRjYXJkIGZvciB0aGUKICAgICAgICAgKiAgICAgICAgYFBST0pFQ1RfSURgLCB3aWxsIGluZmVyIHRoZSBwcm9qZWN0IGZyb20KICAgICAgICB0aGUgYWNjb3VudC4gVGhlIGBBQ0NPVU5UYCB2YWx1ZSBjYW4gYmUgdGhlCiAgICAgICAgICogICAgICAgIGBlbWFpbGAgYWRkcmVzcyBvciB0aGUKICAgICAgICBgdW5pcXVlX2lkYCBvZiB0aGUgc2VydmljZSBhY2NvdW50LgogICAgICAgICAgICogQHNpbmNlIDEuMTMKICAgICAgICAgICAqLwogICAgICAgICAgcHJvdGVjdGVkIExpc3QoamF2YS5sYW5nLlN0cmluZyBuYW1lKSB7CiAgICAgICAgICAgIHN1cGVyKElhbS50aGlzLCAiR0VUIiwgUkVTVF9QQVRILCBudWxsLCBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5pYW0udjEubW9kZWwuTGlzdFNlcnZpY2VBY2NvdW50S2V5c1Jlc3BvbnNlLmNsYXNzKTsKICAgICAgICAgICAgdGhpcy5uYW1lID0gY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuUHJlY29uZGl0aW9ucy5jaGVja05vdE51bGwobmFtZSwgIlJlcXVpcmVkIHBhcmFtZXRlciBuYW1lIG11c3QgYmUgc3BlY2lmaWVkLiIpOwogICAgICAgICAgICBpZiAoIWdldFN1cHByZXNzUGF0dGVybkNoZWNrcygpKSB7CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuUHJlY29uZGl0aW9ucy5jaGVja0FyZ3VtZW50KE5BTUVfUEFUVEVSTi5tYXRjaGVyKG5hbWUpLm1hdGNoZXMoKSwKICAgICAgICAgICAgICAgICAgIlBhcmFtZXRlciBuYW1lIG11c3QgY29uZm9ybSB0byB0aGUgcGF0dGVybiAiICsKICAgICAgICAgICAgICAgICAgIl5wcm9qZWN0cy9bXi9dKy9zZXJ2aWNlQWNjb3VudHMvW14vXSskIik7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KCiAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLmFwaS5jbGllbnQuaHR0cC5IdHRwUmVzcG9uc2UgZXhlY3V0ZVVzaW5nSGVhZCgpIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICAgICAgcmV0dXJuIHN1cGVyLmV4ZWN1dGVVc2luZ0hlYWQoKTsKICAgICAgICAgIH0KCiAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLmFwaS5jbGllbnQuaHR0cC5IdHRwUmVxdWVzdCBidWlsZEh0dHBSZXF1ZXN0VXNpbmdIZWFkKCkgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgICAgICByZXR1cm4gc3VwZXIuYnVpbGRIdHRwUmVxdWVzdFVzaW5nSGVhZCgpOwogICAgICAgICAgfQoKICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgcHVibGljIExpc3Qgc2V0JFhnYWZ2KGphdmEubGFuZy5TdHJpbmcgJFhnYWZ2KSB7CiAgICAgICAgICAgIHJldHVybiAoTGlzdCkgc3VwZXIuc2V0JFhnYWZ2KCRYZ2Fmdik7CiAgICAgICAgICB9CgogICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICBwdWJsaWMgTGlzdCBzZXRBY2Nlc3NUb2tlbihqYXZhLmxhbmcuU3RyaW5nIGFjY2Vzc1Rva2VuKSB7CiAgICAgICAgICAgIHJldHVybiAoTGlzdCkgc3VwZXIuc2V0QWNjZXNzVG9rZW4oYWNjZXNzVG9rZW4pOwogICAgICAgICAgfQoKICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgcHVibGljIExpc3Qgc2V0QWx0KGphdmEubGFuZy5TdHJpbmcgYWx0KSB7CiAgICAgICAgICAgIHJldHVybiAoTGlzdCkgc3VwZXIuc2V0QWx0KGFsdCk7CiAgICAgICAgICB9CgogICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICBwdWJsaWMgTGlzdCBzZXRDYWxsYmFjayhqYXZhLmxhbmcuU3RyaW5nIGNhbGxiYWNrKSB7CiAgICAgICAgICAgIHJldHVybiAoTGlzdCkgc3VwZXIuc2V0Q2FsbGJhY2soY2FsbGJhY2spOwogICAgICAgICAgfQoKICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgcHVibGljIExpc3Qgc2V0RmllbGRzKGphdmEubGFuZy5TdHJpbmcgZmllbGRzKSB7CiAgICAgICAgICAgIHJldHVybiAoTGlzdCkgc3VwZXIuc2V0RmllbGRzKGZpZWxkcyk7CiAgICAgICAgICB9CgogICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICBwdWJsaWMgTGlzdCBzZXRLZXkoamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICAgICAgcmV0dXJuIChMaXN0KSBzdXBlci5zZXRLZXkoa2V5KTsKICAgICAgICAgIH0KCiAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgIHB1YmxpYyBMaXN0IHNldE9hdXRoVG9rZW4oamF2YS5sYW5nLlN0cmluZyBvYXV0aFRva2VuKSB7CiAgICAgICAgICAgIHJldHVybiAoTGlzdCkgc3VwZXIuc2V0T2F1dGhUb2tlbihvYXV0aFRva2VuKTsKICAgICAgICAgIH0KCiAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgIHB1YmxpYyBMaXN0IHNldFByZXR0eVByaW50KGphdmEubGFuZy5Cb29sZWFuIHByZXR0eVByaW50KSB7CiAgICAgICAgICAgIHJldHVybiAoTGlzdCkgc3VwZXIuc2V0UHJldHR5UHJpbnQocHJldHR5UHJpbnQpOwogICAgICAgICAgfQoKICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgcHVibGljIExpc3Qgc2V0UXVvdGFVc2VyKGphdmEubGFuZy5TdHJpbmcgcXVvdGFVc2VyKSB7CiAgICAgICAgICAgIHJldHVybiAoTGlzdCkgc3VwZXIuc2V0UXVvdGFVc2VyKHF1b3RhVXNlcik7CiAgICAgICAgICB9CgogICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICBwdWJsaWMgTGlzdCBzZXRVcGxvYWRUeXBlKGphdmEubGFuZy5TdHJpbmcgdXBsb2FkVHlwZSkgewogICAgICAgICAgICByZXR1cm4gKExpc3QpIHN1cGVyLnNldFVwbG9hZFR5cGUodXBsb2FkVHlwZSk7CiAgICAgICAgICB9CgogICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICBwdWJsaWMgTGlzdCBzZXRVcGxvYWRQcm90b2NvbChqYXZhLmxhbmcuU3RyaW5nIHVwbG9hZFByb3RvY29sKSB7CiAgICAgICAgICAgIHJldHVybiAoTGlzdCkgc3VwZXIuc2V0VXBsb2FkUHJvdG9jb2wodXBsb2FkUHJvdG9jb2wpOwogICAgICAgICAgfQoKICAgICAgICAgIC8qKgogICAgICAgICAgICogUmVxdWlyZWQuIFRoZSByZXNvdXJjZSBuYW1lIG9mIHRoZSBzZXJ2aWNlIGFjY291bnQgaW4gdGhlIGZvbGxvd2luZyBmb3JtYXQ6CiAgICAgICAgICAgKiBgcHJvamVjdHMve1BST0pFQ1RfSUR9L3NlcnZpY2VBY2NvdW50cy97QUNDT1VOVH1gLgogICAgICAgICAgICoKICAgICAgICAgICAqIFVzaW5nIGAtYCBhcyBhIHdpbGRjYXJkIGZvciB0aGUgYFBST0pFQ1RfSURgLCB3aWxsIGluZmVyIHRoZSBwcm9qZWN0IGZyb20gdGhlIGFjY291bnQuCiAgICAgICAgICAgKiBUaGUgYEFDQ09VTlRgIHZhbHVlIGNhbiBiZSB0aGUgYGVtYWlsYCBhZGRyZXNzIG9yIHRoZSBgdW5pcXVlX2lkYCBvZiB0aGUgc2VydmljZQogICAgICAgICAgICogYWNjb3VudC4KICAgICAgICAgICAqLwogICAgICAgICAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogICAgICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuU3RyaW5nIG5hbWU7CgogICAgICAgICAgLyoqIFJlcXVpcmVkLiBUaGUgcmVzb3VyY2UgbmFtZSBvZiB0aGUgc2VydmljZSBhY2NvdW50IGluIHRoZSBmb2xsb3dpbmcgZm9ybWF0OgogICAgICAgICBgcHJvamVjdHMve1BST0pFQ1RfSUR9L3NlcnZpY2VBY2NvdW50cy97QUNDT1VOVH1gLgoKICAgICAgICAgVXNpbmcgYC1gIGFzIGEgd2lsZGNhcmQgZm9yIHRoZSBgUFJPSkVDVF9JRGAsIHdpbGwgaW5mZXIgdGhlIHByb2plY3QgZnJvbSB0aGUgYWNjb3VudC4gVGhlCiAgICAgICAgIGBBQ0NPVU5UYCB2YWx1ZSBjYW4gYmUgdGhlIGBlbWFpbGAgYWRkcmVzcyBvciB0aGUgYHVuaXF1ZV9pZGAgb2YgdGhlIHNlcnZpY2UgYWNjb3VudC4KICAgICAgICAgICAqLwogICAgICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TmFtZSgpIHsKICAgICAgICAgICAgcmV0dXJuIG5hbWU7CiAgICAgICAgICB9CgogICAgICAgICAgLyoqCiAgICAgICAgICAgKiBSZXF1aXJlZC4gVGhlIHJlc291cmNlIG5hbWUgb2YgdGhlIHNlcnZpY2UgYWNjb3VudCBpbiB0aGUgZm9sbG93aW5nIGZvcm1hdDoKICAgICAgICAgICAqIGBwcm9qZWN0cy97UFJPSkVDVF9JRH0vc2VydmljZUFjY291bnRzL3tBQ0NPVU5UfWAuCiAgICAgICAgICAgKgogICAgICAgICAgICogVXNpbmcgYC1gIGFzIGEgd2lsZGNhcmQgZm9yIHRoZSBgUFJPSkVDVF9JRGAsIHdpbGwgaW5mZXIgdGhlIHByb2plY3QgZnJvbSB0aGUgYWNjb3VudC4KICAgICAgICAgICAqIFRoZSBgQUNDT1VOVGAgdmFsdWUgY2FuIGJlIHRoZSBgZW1haWxgIGFkZHJlc3Mgb3IgdGhlIGB1bmlxdWVfaWRgIG9mIHRoZSBzZXJ2aWNlCiAgICAgICAgICAgKiBhY2NvdW50LgogICAgICAgICAgICovCiAgICAgICAgICBwdWJsaWMgTGlzdCBzZXROYW1lKGphdmEubGFuZy5TdHJpbmcgbmFtZSkgewogICAgICAgICAgICBpZiAoIWdldFN1cHByZXNzUGF0dGVybkNoZWNrcygpKSB7CiAgICAgICAgICAgICAgY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuUHJlY29uZGl0aW9ucy5jaGVja0FyZ3VtZW50KE5BTUVfUEFUVEVSTi5tYXRjaGVyKG5hbWUpLm1hdGNoZXMoKSwKICAgICAgICAgICAgICAgICAgIlBhcmFtZXRlciBuYW1lIG11c3QgY29uZm9ybSB0byB0aGUgcGF0dGVybiAiICsKICAgICAgICAgICAgICAgICAgIl5wcm9qZWN0cy9bXi9dKy9zZXJ2aWNlQWNjb3VudHMvW14vXSskIik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdGhpcy5uYW1lID0gbmFtZTsKICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgICB9CgogICAgICAgICAgLyoqCiAgICAgICAgICAgKiBGaWx0ZXJzIHRoZSB0eXBlcyBvZiBrZXlzIHRoZSB1c2VyIHdhbnRzIHRvIGluY2x1ZGUgaW4gdGhlIGxpc3QgcmVzcG9uc2UuIER1cGxpY2F0ZSBrZXkKICAgICAgICAgICAqIHR5cGVzIGFyZSBub3QgYWxsb3dlZC4gSWYgbm8ga2V5IHR5cGUgaXMgcHJvdmlkZWQsIGFsbCBrZXlzIGFyZSByZXR1cm5lZC4KICAgICAgICAgICAqLwogICAgICAgICAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogICAgICAgICAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuU3RyaW5nPiBrZXlUeXBlczsKCiAgICAgICAgICAvKiogRmlsdGVycyB0aGUgdHlwZXMgb2Yga2V5cyB0aGUgdXNlciB3YW50cyB0byBpbmNsdWRlIGluIHRoZSBsaXN0IHJlc3BvbnNlLiBEdXBsaWNhdGUga2V5IHR5cGVzIGFyZQogICAgICAgICBub3QgYWxsb3dlZC4gSWYgbm8ga2V5IHR5cGUgaXMgcHJvdmlkZWQsIGFsbCBrZXlzIGFyZSByZXR1cm5lZC4KICAgICAgICAgICAqLwogICAgICAgICAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5TdHJpbmc+IGdldEtleVR5cGVzKCkgewogICAgICAgICAgICByZXR1cm4ga2V5VHlwZXM7CiAgICAgICAgICB9CgogICAgICAgICAgLyoqCiAgICAgICAgICAgKiBGaWx0ZXJzIHRoZSB0eXBlcyBvZiBrZXlzIHRoZSB1c2VyIHdhbnRzIHRvIGluY2x1ZGUgaW4gdGhlIGxpc3QgcmVzcG9uc2UuIER1cGxpY2F0ZSBrZXkKICAgICAgICAgICAqIHR5cGVzIGFyZSBub3QgYWxsb3dlZC4gSWYgbm8ga2V5IHR5cGUgaXMgcHJvdmlkZWQsIGFsbCBrZXlzIGFyZSByZXR1cm5lZC4KICAgICAgICAgICAqLwogICAgICAgICAgcHVibGljIExpc3Qgc2V0S2V5VHlwZXMoamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLlN0cmluZz4ga2V5VHlwZXMpIHsKICAgICAgICAgICAgdGhpcy5rZXlUeXBlcyA9IGtleVR5cGVzOwogICAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICAgIH0KCiAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgIHB1YmxpYyBMaXN0IHNldChTdHJpbmcgcGFyYW1ldGVyTmFtZSwgT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgICAgIHJldHVybiAoTGlzdCkgc3VwZXIuc2V0KHBhcmFtZXRlck5hbWUsIHZhbHVlKTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogVXBsb2FkIHB1YmxpYyBrZXkgZm9yIGEgZ2l2ZW4gc2VydmljZSBhY2NvdW50LiBUaGlzIHJwYyB3aWxsIGNyZWF0ZSBhIFNlcnZpY2VBY2NvdW50S2V5IHRoYXQgaGFzCiAgICAgICAgICogdGhlIHByb3ZpZGVkIHB1YmxpYyBrZXkgYW5kIHJldHVybnMgaXQuCiAgICAgICAgICoKICAgICAgICAgKiBDcmVhdGUgYSByZXF1ZXN0IGZvciB0aGUgbWV0aG9kICJrZXlzLnVwbG9hZCIuCiAgICAgICAgICoKICAgICAgICAgKiBUaGlzIHJlcXVlc3QgaG9sZHMgdGhlIHBhcmFtZXRlcnMgbmVlZGVkIGJ5IHRoZSBpYW0gc2VydmVyLiAgQWZ0ZXIgc2V0dGluZyBhbnkgb3B0aW9uYWwKICAgICAgICAgKiBwYXJhbWV0ZXJzLCBjYWxsIHRoZSB7QGxpbmsgVXBsb2FkI2V4ZWN1dGUoKX0gbWV0aG9kIHRvIGludm9rZSB0aGUgcmVtb3RlIG9wZXJhdGlvbi4KICAgICAgICAgKgogICAgICAgICAqIEBwYXJhbSBuYW1lIFRoZSByZXNvdXJjZSBuYW1lIG9mIHRoZSBzZXJ2aWNlIGFjY291bnQgaW4gdGhlIGZvbGxvd2luZyBmb3JtYXQ6CiAgICAgICAgICogICAgICAgIGBwcm9qZWN0cy97UFJPSkVDVF9JRH0vc2VydmljZUFjY291bnRzL3tBQ0NPVU5UfWAuCiAgICAgICAgVXNpbmcgYC1gIGFzIGEgd2lsZGNhcmQgZm9yIHRoZQogICAgICAgICAqICAgICAgICBgUFJPSkVDVF9JRGAgd2lsbCBpbmZlciB0aGUgcHJvamVjdCBmcm9tCiAgICAgICAgdGhlIGFjY291bnQuIFRoZSBgQUNDT1VOVGAgdmFsdWUgY2FuIGJlIHRoZQogICAgICAgICAqICAgICAgICBgZW1haWxgIGFkZHJlc3Mgb3IgdGhlCiAgICAgICAgYHVuaXF1ZV9pZGAgb2YgdGhlIHNlcnZpY2UgYWNjb3VudC4KICAgICAgICAgKiBAcGFyYW0gY29udGVudCB0aGUge0BsaW5rIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmlhbS52MS5tb2RlbC5VcGxvYWRTZXJ2aWNlQWNjb3VudEtleVJlcXVlc3R9CiAgICAgICAgICogQHJldHVybiB0aGUgcmVxdWVzdAogICAgICAgICAqLwogICAgICAgIHB1YmxpYyBVcGxvYWQgdXBsb2FkKGphdmEubGFuZy5TdHJpbmcgbmFtZSwgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuaWFtLnYxLm1vZGVsLlVwbG9hZFNlcnZpY2VBY2NvdW50S2V5UmVxdWVzdCBjb250ZW50KSB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgICBVcGxvYWQgcmVzdWx0ID0gbmV3IFVwbG9hZChuYW1lLCBjb250ZW50KTsKICAgICAgICAgIGluaXRpYWxpemUocmVzdWx0KTsKICAgICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgY2xhc3MgVXBsb2FkIGV4dGVuZHMgSWFtUmVxdWVzdDxjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5pYW0udjEubW9kZWwuU2VydmljZUFjY291bnRLZXk+IHsKCiAgICAgICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgUkVTVF9QQVRIID0gInYxL3srbmFtZX0va2V5czp1cGxvYWQiOwoKICAgICAgICAgIHByaXZhdGUgZmluYWwgamF2YS51dGlsLnJlZ2V4LlBhdHRlcm4gTkFNRV9QQVRURVJOID0KICAgICAgICAgICAgICBqYXZhLnV0aWwucmVnZXguUGF0dGVybi5jb21waWxlKCJecHJvamVjdHMvW14vXSsvc2VydmljZUFjY291bnRzL1teL10rJCIpOwoKICAgICAgICAgIC8qKgogICAgICAgICAgICogVXBsb2FkIHB1YmxpYyBrZXkgZm9yIGEgZ2l2ZW4gc2VydmljZSBhY2NvdW50LiBUaGlzIHJwYyB3aWxsIGNyZWF0ZSBhIFNlcnZpY2VBY2NvdW50S2V5IHRoYXQKICAgICAgICAgICAqIGhhcyB0aGUgcHJvdmlkZWQgcHVibGljIGtleSBhbmQgcmV0dXJucyBpdC4KICAgICAgICAgICAqCiAgICAgICAgICAgKiBDcmVhdGUgYSByZXF1ZXN0IGZvciB0aGUgbWV0aG9kICJrZXlzLnVwbG9hZCIuCiAgICAgICAgICAgKgogICAgICAgICAgICogVGhpcyByZXF1ZXN0IGhvbGRzIHRoZSBwYXJhbWV0ZXJzIG5lZWRlZCBieSB0aGUgdGhlIGlhbSBzZXJ2ZXIuICBBZnRlciBzZXR0aW5nIGFueSBvcHRpb25hbAogICAgICAgICAgICogcGFyYW1ldGVycywgY2FsbCB0aGUge0BsaW5rIFVwbG9hZCNleGVjdXRlKCl9IG1ldGhvZCB0byBpbnZva2UgdGhlIHJlbW90ZSBvcGVyYXRpb24uIDxwPiB7QGxpbmsKICAgICAgICAgICAqIFVwbG9hZCNpbml0aWFsaXplKGNvbS5nb29nbGUuYXBpLmNsaWVudC5nb29nbGVhcGlzLnNlcnZpY2VzLkFic3RyYWN0R29vZ2xlQ2xpZW50UmVxdWVzdCl9IG11c3QKICAgICAgICAgICAqIGJlIGNhbGxlZCB0byBpbml0aWFsaXplIHRoaXMgaW5zdGFuY2UgaW1tZWRpYXRlbHkgYWZ0ZXIgaW52b2tpbmcgdGhlIGNvbnN0cnVjdG9yLiA8L3A+CiAgICAgICAgICAgKgogICAgICAgICAgICogQHBhcmFtIG5hbWUgVGhlIHJlc291cmNlIG5hbWUgb2YgdGhlIHNlcnZpY2UgYWNjb3VudCBpbiB0aGUgZm9sbG93aW5nIGZvcm1hdDoKICAgICAgICAgKiAgICAgICAgYHByb2plY3RzL3tQUk9KRUNUX0lEfS9zZXJ2aWNlQWNjb3VudHMve0FDQ09VTlR9YC4KICAgICAgICBVc2luZyBgLWAgYXMgYSB3aWxkY2FyZCBmb3IgdGhlCiAgICAgICAgICogICAgICAgIGBQUk9KRUNUX0lEYCB3aWxsIGluZmVyIHRoZSBwcm9qZWN0IGZyb20KICAgICAgICB0aGUgYWNjb3VudC4gVGhlIGBBQ0NPVU5UYCB2YWx1ZSBjYW4gYmUgdGhlCiAgICAgICAgICogICAgICAgIGBlbWFpbGAgYWRkcmVzcyBvciB0aGUKICAgICAgICBgdW5pcXVlX2lkYCBvZiB0aGUgc2VydmljZSBhY2NvdW50LgogICAgICAgICAgICogQHBhcmFtIGNvbnRlbnQgdGhlIHtAbGluayBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5pYW0udjEubW9kZWwuVXBsb2FkU2VydmljZUFjY291bnRLZXlSZXF1ZXN0fQogICAgICAgICAgICogQHNpbmNlIDEuMTMKICAgICAgICAgICAqLwogICAgICAgICAgcHJvdGVjdGVkIFVwbG9hZChqYXZhLmxhbmcuU3RyaW5nIG5hbWUsIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmlhbS52MS5tb2RlbC5VcGxvYWRTZXJ2aWNlQWNjb3VudEtleVJlcXVlc3QgY29udGVudCkgewogICAgICAgICAgICBzdXBlcihJYW0udGhpcywgIlBPU1QiLCBSRVNUX1BBVEgsIGNvbnRlbnQsIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmlhbS52MS5tb2RlbC5TZXJ2aWNlQWNjb3VudEtleS5jbGFzcyk7CiAgICAgICAgICAgIHRoaXMubmFtZSA9IGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLlByZWNvbmRpdGlvbnMuY2hlY2tOb3ROdWxsKG5hbWUsICJSZXF1aXJlZCBwYXJhbWV0ZXIgbmFtZSBtdXN0IGJlIHNwZWNpZmllZC4iKTsKICAgICAgICAgICAgaWYgKCFnZXRTdXBwcmVzc1BhdHRlcm5DaGVja3MoKSkgewogICAgICAgICAgICAgIGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLlByZWNvbmRpdGlvbnMuY2hlY2tBcmd1bWVudChOQU1FX1BBVFRFUk4ubWF0Y2hlcihuYW1lKS5tYXRjaGVzKCksCiAgICAgICAgICAgICAgICAgICJQYXJhbWV0ZXIgbmFtZSBtdXN0IGNvbmZvcm0gdG8gdGhlIHBhdHRlcm4gIiArCiAgICAgICAgICAgICAgICAgICJecHJvamVjdHMvW14vXSsvc2VydmljZUFjY291bnRzL1teL10rJCIpOwogICAgICAgICAgICB9CiAgICAgICAgICB9CgogICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICBwdWJsaWMgVXBsb2FkIHNldCRYZ2FmdihqYXZhLmxhbmcuU3RyaW5nICRYZ2FmdikgewogICAgICAgICAgICByZXR1cm4gKFVwbG9hZCkgc3VwZXIuc2V0JFhnYWZ2KCRYZ2Fmdik7CiAgICAgICAgICB9CgogICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICBwdWJsaWMgVXBsb2FkIHNldEFjY2Vzc1Rva2VuKGphdmEubGFuZy5TdHJpbmcgYWNjZXNzVG9rZW4pIHsKICAgICAgICAgICAgcmV0dXJuIChVcGxvYWQpIHN1cGVyLnNldEFjY2Vzc1Rva2VuKGFjY2Vzc1Rva2VuKTsKICAgICAgICAgIH0KCiAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgIHB1YmxpYyBVcGxvYWQgc2V0QWx0KGphdmEubGFuZy5TdHJpbmcgYWx0KSB7CiAgICAgICAgICAgIHJldHVybiAoVXBsb2FkKSBzdXBlci5zZXRBbHQoYWx0KTsKICAgICAgICAgIH0KCiAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgIHB1YmxpYyBVcGxvYWQgc2V0Q2FsbGJhY2soamF2YS5sYW5nLlN0cmluZyBjYWxsYmFjaykgewogICAgICAgICAgICByZXR1cm4gKFVwbG9hZCkgc3VwZXIuc2V0Q2FsbGJhY2soY2FsbGJhY2spOwogICAgICAgICAgfQoKICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgcHVibGljIFVwbG9hZCBzZXRGaWVsZHMoamF2YS5sYW5nLlN0cmluZyBmaWVsZHMpIHsKICAgICAgICAgICAgcmV0dXJuIChVcGxvYWQpIHN1cGVyLnNldEZpZWxkcyhmaWVsZHMpOwogICAgICAgICAgfQoKICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgcHVibGljIFVwbG9hZCBzZXRLZXkoamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICAgICAgcmV0dXJuIChVcGxvYWQpIHN1cGVyLnNldEtleShrZXkpOwogICAgICAgICAgfQoKICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgcHVibGljIFVwbG9hZCBzZXRPYXV0aFRva2VuKGphdmEubGFuZy5TdHJpbmcgb2F1dGhUb2tlbikgewogICAgICAgICAgICByZXR1cm4gKFVwbG9hZCkgc3VwZXIuc2V0T2F1dGhUb2tlbihvYXV0aFRva2VuKTsKICAgICAgICAgIH0KCiAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgIHB1YmxpYyBVcGxvYWQgc2V0UHJldHR5UHJpbnQoamF2YS5sYW5nLkJvb2xlYW4gcHJldHR5UHJpbnQpIHsKICAgICAgICAgICAgcmV0dXJuIChVcGxvYWQpIHN1cGVyLnNldFByZXR0eVByaW50KHByZXR0eVByaW50KTsKICAgICAgICAgIH0KCiAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgIHB1YmxpYyBVcGxvYWQgc2V0UXVvdGFVc2VyKGphdmEubGFuZy5TdHJpbmcgcXVvdGFVc2VyKSB7CiAgICAgICAgICAgIHJldHVybiAoVXBsb2FkKSBzdXBlci5zZXRRdW90YVVzZXIocXVvdGFVc2VyKTsKICAgICAgICAgIH0KCiAgICAgICAgICBAT3ZlcnJpZGUKICAgICAgICAgIHB1YmxpYyBVcGxvYWQgc2V0VXBsb2FkVHlwZShqYXZhLmxhbmcuU3RyaW5nIHVwbG9hZFR5cGUpIHsKICAgICAgICAgICAgcmV0dXJuIChVcGxvYWQpIHN1cGVyLnNldFVwbG9hZFR5cGUodXBsb2FkVHlwZSk7CiAgICAgICAgICB9CgogICAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgICBwdWJsaWMgVXBsb2FkIHNldFVwbG9hZFByb3RvY29sKGphdmEubGFuZy5TdHJpbmcgdXBsb2FkUHJvdG9jb2wpIHsKICAgICAgICAgICAgcmV0dXJuIChVcGxvYWQpIHN1cGVyLnNldFVwbG9hZFByb3RvY29sKHVwbG9hZFByb3RvY29sKTsKICAgICAgICAgIH0KCiAgICAgICAgICAvKioKICAgICAgICAgICAqIFRoZSByZXNvdXJjZSBuYW1lIG9mIHRoZSBzZXJ2aWNlIGFjY291bnQgaW4gdGhlIGZvbGxvd2luZyBmb3JtYXQ6CiAgICAgICAgICAgKiBgcHJvamVjdHMve1BST0pFQ1RfSUR9L3NlcnZpY2VBY2NvdW50cy97QUNDT1VOVH1gLiBVc2luZyBgLWAgYXMgYSB3aWxkY2FyZCBmb3IgdGhlCiAgICAgICAgICAgKiBgUFJPSkVDVF9JRGAgd2lsbCBpbmZlciB0aGUgcHJvamVjdCBmcm9tIHRoZSBhY2NvdW50LiBUaGUgYEFDQ09VTlRgIHZhbHVlIGNhbiBiZSB0aGUKICAgICAgICAgICAqIGBlbWFpbGAgYWRkcmVzcyBvciB0aGUgYHVuaXF1ZV9pZGAgb2YgdGhlIHNlcnZpY2UgYWNjb3VudC4KICAgICAgICAgICAqLwogICAgICAgICAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogICAgICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuU3RyaW5nIG5hbWU7CgogICAgICAgICAgLyoqIFRoZSByZXNvdXJjZSBuYW1lIG9mIHRoZSBzZXJ2aWNlIGFjY291bnQgaW4gdGhlIGZvbGxvd2luZyBmb3JtYXQ6CiAgICAgICAgIGBwcm9qZWN0cy97UFJPSkVDVF9JRH0vc2VydmljZUFjY291bnRzL3tBQ0NPVU5UfWAuIFVzaW5nIGAtYCBhcyBhIHdpbGRjYXJkIGZvciB0aGUgYFBST0pFQ1RfSURgCiAgICAgICAgIHdpbGwgaW5mZXIgdGhlIHByb2plY3QgZnJvbSB0aGUgYWNjb3VudC4gVGhlIGBBQ0NPVU5UYCB2YWx1ZSBjYW4gYmUgdGhlIGBlbWFpbGAgYWRkcmVzcyBvciB0aGUKICAgICAgICAgYHVuaXF1ZV9pZGAgb2YgdGhlIHNlcnZpY2UgYWNjb3VudC4KICAgICAgICAgICAqLwogICAgICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TmFtZSgpIHsKICAgICAgICAgICAgcmV0dXJuIG5hbWU7CiAgICAgICAgICB9CgogICAgICAgICAgLyoqCiAgICAgICAgICAgKiBUaGUgcmVzb3VyY2UgbmFtZSBvZiB0aGUgc2VydmljZSBhY2NvdW50IGluIHRoZSBmb2xsb3dpbmcgZm9ybWF0OgogICAgICAgICAgICogYHByb2plY3RzL3tQUk9KRUNUX0lEfS9zZXJ2aWNlQWNjb3VudHMve0FDQ09VTlR9YC4gVXNpbmcgYC1gIGFzIGEgd2lsZGNhcmQgZm9yIHRoZQogICAgICAgICAgICogYFBST0pFQ1RfSURgIHdpbGwgaW5mZXIgdGhlIHByb2plY3QgZnJvbSB0aGUgYWNjb3VudC4gVGhlIGBBQ0NPVU5UYCB2YWx1ZSBjYW4gYmUgdGhlCiAgICAgICAgICAgKiBgZW1haWxgIGFkZHJlc3Mgb3IgdGhlIGB1bmlxdWVfaWRgIG9mIHRoZSBzZXJ2aWNlIGFjY291bnQuCiAgICAgICAgICAgKi8KICAgICAgICAgIHB1YmxpYyBVcGxvYWQgc2V0TmFtZShqYXZhLmxhbmcuU3RyaW5nIG5hbWUpIHsKICAgICAgICAgICAgaWYgKCFnZXRTdXBwcmVzc1BhdHRlcm5DaGVja3MoKSkgewogICAgICAgICAgICAgIGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLlByZWNvbmRpdGlvbnMuY2hlY2tBcmd1bWVudChOQU1FX1BBVFRFUk4ubWF0Y2hlcihuYW1lKS5tYXRjaGVzKCksCiAgICAgICAgICAgICAgICAgICJQYXJhbWV0ZXIgbmFtZSBtdXN0IGNvbmZvcm0gdG8gdGhlIHBhdHRlcm4gIiArCiAgICAgICAgICAgICAgICAgICJecHJvamVjdHMvW14vXSsvc2VydmljZUFjY291bnRzL1teL10rJCIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHRoaXMubmFtZSA9IG5hbWU7CiAgICAgICAgICAgIHJldHVybiB0aGlzOwogICAgICAgICAgfQoKICAgICAgICAgIEBPdmVycmlkZQogICAgICAgICAgcHVibGljIFVwbG9hZCBzZXQoU3RyaW5nIHBhcmFtZXRlck5hbWUsIE9iamVjdCB2YWx1ZSkgewogICAgICAgICAgICByZXR1cm4gKFVwbG9hZCkgc3VwZXIuc2V0KHBhcmFtZXRlck5hbWUsIHZhbHVlKTsKICAgICAgICAgIH0KICAgICAgICB9CgogICAgICB9CiAgICB9CiAgfQoKICAvKioKICAgKiBBbiBhY2Nlc3NvciBmb3IgY3JlYXRpbmcgcmVxdWVzdHMgZnJvbSB0aGUgUm9sZXMgY29sbGVjdGlvbi4KICAgKgogICAqIDxwPlRoZSB0eXBpY2FsIHVzZSBpczo8L3A+CiAgICogPHByZT4KICAgKiAgIHtAY29kZSBJYW0gaWFtID0gbmV3IElhbSguLi4pO30KICAgKiAgIHtAY29kZSBJYW0uUm9sZXMuTGlzdCByZXF1ZXN0ID0gaWFtLnJvbGVzKCkubGlzdChwYXJhbWV0ZXJzIC4uLil9CiAgICogPC9wcmU+CiAgICoKICAgKiBAcmV0dXJuIHRoZSByZXNvdXJjZSBjb2xsZWN0aW9uCiAgICovCiAgcHVibGljIFJvbGVzIHJvbGVzKCkgewogICAgcmV0dXJuIG5ldyBSb2xlcygpOwogIH0KCiAgLyoqCiAgICogVGhlICJyb2xlcyIgY29sbGVjdGlvbiBvZiBtZXRob2RzLgogICAqLwogIHB1YmxpYyBjbGFzcyBSb2xlcyB7CgogICAgLyoqCiAgICAgKiBHZXRzIGEgUm9sZSBkZWZpbml0aW9uLgogICAgICoKICAgICAqIENyZWF0ZSBhIHJlcXVlc3QgZm9yIHRoZSBtZXRob2QgInJvbGVzLmdldCIuCiAgICAgKgogICAgICogVGhpcyByZXF1ZXN0IGhvbGRzIHRoZSBwYXJhbWV0ZXJzIG5lZWRlZCBieSB0aGUgaWFtIHNlcnZlci4gIEFmdGVyIHNldHRpbmcgYW55IG9wdGlvbmFsCiAgICAgKiBwYXJhbWV0ZXJzLCBjYWxsIHRoZSB7QGxpbmsgR2V0I2V4ZWN1dGUoKX0gbWV0aG9kIHRvIGludm9rZSB0aGUgcmVtb3RlIG9wZXJhdGlvbi4KICAgICAqCiAgICAgKiBAcGFyYW0gbmFtZSBUaGUgYG5hbWVgIHBhcmFtZXRlcidzIHZhbHVlIGRlcGVuZHMgb24gdGhlIHRhcmdldCByZXNvdXJjZSBmb3IgdGhlCiAgICByZXF1ZXN0LCBuYW1lbHkKICAgICAqICAgICAgICBbYHJvbGVzYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9yb2xlcyksCiAgICAgKiAgICAgICAgW2Bwcm9qZWN0c2BdKC9pYW0vcmVmZXJlbmNlL3Jlc3QvdjEvcHJvamVjdHMucm9sZXMpLCBvcgogICAgICogICAgICAgIFtgb3JnYW5pemF0aW9uc2BdKC9pYW0vcmVmZXJlbmNlL3Jlc3QvdjEvb3JnYW5pemF0aW9ucy5yb2xlcykuIEVhY2gKICAgIHJlc291cmNlIHR5cGUncyBgbmFtZWAKICAgICAqICAgICAgICB2YWx1ZSBmb3JtYXQgaXMgZGVzY3JpYmVkIGJlbG93OgogICAgKiBbYHJvbGVzLmdldCgpYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9yb2xlcy9nZXQpOgogICAgICogICAgICAgIGByb2xlcy97Uk9MRV9OQU1FfWAuCiAgICAgIFRoaXMgbWV0aG9kIHJldHVybnMgcmVzdWx0cyBmcm9tIGFsbAogICAgICBbcHJlZGVmaW5lZCByb2xlc10oL2lhbS9kb2NzCiAgICAgKiAgICAgICAgL3VuZGVyc3RhbmRpbmctcm9sZXMjcHJlZGVmaW5lZF9yb2xlcykgaW4KICAgICAgQ2xvdWQgSUFNLiBFeGFtcGxlIHJlcXVlc3QgVVJMOgogICAgICogICAgICAgIGBodHRwczovL2lhbS5nb29nbGVhcGlzLmNvbS92MS9yb2xlcy97Uk9MRV9OQU1FfWAKICAgICoKICAgICAqICAgICAgICBbYHByb2plY3RzLnJvbGVzLmdldCgpYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9wcm9qZWN0cy5yb2xlcy9nZXQpOgogICAgICogICAgICAgIGBwcm9qZWN0cy97UFJPSkVDVF9JRH0vcm9sZXMve0NVU1RPTV9ST0xFX0lEfWAuIFRoaXMgbWV0aG9kIHJldHVybnMgb25seQogICAgICBbY3VzdG9tCiAgICAgKiAgICAgICAgcm9sZXNdKC9pYW0vZG9jcy91bmRlcnN0YW5kaW5nLWN1c3RvbS1yb2xlcykgdGhhdCBoYXZlIGJlZW4KICAgICAgY3JlYXRlZCBhdCB0aGUgcHJvamVjdAogICAgICogICAgICAgIGxldmVsLiBFeGFtcGxlIHJlcXVlc3QgVVJMOgogICAgICogICAgICAgIGBodHRwczovL2lhbS5nb29nbGVhcGlzLmNvbS92MS9wcm9qZWN0cy97UFJPSkVDVF9JRH0vcm9sZXMve0NVU1RPTV9ST0xFX0lEfWAKICAgICoKICAgICAqICAgICAgICBbYG9yZ2FuaXphdGlvbnMucm9sZXMuZ2V0KClgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL29yZ2FuaXphdGlvbnMucm9sZXMvZ2V0KToKICAgICAqICAgICAgICBgb3JnYW5pemF0aW9ucy97T1JHQU5JWkFUSU9OX0lEfS9yb2xlcy97Q1VTVE9NX1JPTEVfSUR9YC4gVGhpcyBtZXRob2QKICAgICAgcmV0dXJucyBvbmx5CiAgICAgKiAgICAgICAgW2N1c3RvbSByb2xlc10oL2lhbS9kb2NzL3VuZGVyc3RhbmRpbmctY3VzdG9tLXJvbGVzKSB0aGF0CiAgICAgIGhhdmUgYmVlbiBjcmVhdGVkIGF0IHRoZQogICAgICogICAgICAgIG9yZ2FuaXphdGlvbiBsZXZlbC4gRXhhbXBsZSByZXF1ZXN0IFVSTDoKICAgICAqICAgICAgICBgaHR0cHM6Ly9pYW0uZ29vZ2xlYXBpcy5jb20vdjEvb3JnYW5pemF0aW9ucy97T1JHQU5JWkFUSU9OX0lEfS9yb2xlcy97Q1VTVE9NX1JPTEVfSUR9YAogICAgICogICAgICAgIE5vdGU6IFdpbGRjYXJkICgqKSB2YWx1ZXMgYXJlIGludmFsaWQ7IHlvdSBtdXN0IHNwZWNpZnkgYSBjb21wbGV0ZSBwcm9qZWN0CiAgICBJRCBvcgogICAgICogICAgICAgIG9yZ2FuaXphdGlvbiBJRC4KICAgICAqIEByZXR1cm4gdGhlIHJlcXVlc3QKICAgICAqLwogICAgcHVibGljIEdldCBnZXQoamF2YS5sYW5nLlN0cmluZyBuYW1lKSB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIEdldCByZXN1bHQgPSBuZXcgR2V0KG5hbWUpOwogICAgICBpbml0aWFsaXplKHJlc3VsdCk7CiAgICAgIHJldHVybiByZXN1bHQ7CiAgICB9CgogICAgcHVibGljIGNsYXNzIEdldCBleHRlbmRzIElhbVJlcXVlc3Q8Y29tLmdvb2dsZS5hcGkuc2VydmljZXMuaWFtLnYxLm1vZGVsLlJvbGU+IHsKCiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBSRVNUX1BBVEggPSAidjEveytuYW1lfSI7CgogICAgICBwcml2YXRlIGZpbmFsIGphdmEudXRpbC5yZWdleC5QYXR0ZXJuIE5BTUVfUEFUVEVSTiA9CiAgICAgICAgICBqYXZhLnV0aWwucmVnZXguUGF0dGVybi5jb21waWxlKCJecm9sZXMvW14vXSskIik7CgogICAgICAvKioKICAgICAgICogR2V0cyBhIFJvbGUgZGVmaW5pdGlvbi4KICAgICAgICoKICAgICAgICogQ3JlYXRlIGEgcmVxdWVzdCBmb3IgdGhlIG1ldGhvZCAicm9sZXMuZ2V0Ii4KICAgICAgICoKICAgICAgICogVGhpcyByZXF1ZXN0IGhvbGRzIHRoZSBwYXJhbWV0ZXJzIG5lZWRlZCBieSB0aGUgdGhlIGlhbSBzZXJ2ZXIuICBBZnRlciBzZXR0aW5nIGFueSBvcHRpb25hbAogICAgICAgKiBwYXJhbWV0ZXJzLCBjYWxsIHRoZSB7QGxpbmsgR2V0I2V4ZWN1dGUoKX0gbWV0aG9kIHRvIGludm9rZSB0aGUgcmVtb3RlIG9wZXJhdGlvbi4gPHA+IHtAbGluawogICAgICAgKiBHZXQjaW5pdGlhbGl6ZShjb20uZ29vZ2xlLmFwaS5jbGllbnQuZ29vZ2xlYXBpcy5zZXJ2aWNlcy5BYnN0cmFjdEdvb2dsZUNsaWVudFJlcXVlc3QpfSBtdXN0IGJlCiAgICAgICAqIGNhbGxlZCB0byBpbml0aWFsaXplIHRoaXMgaW5zdGFuY2UgaW1tZWRpYXRlbHkgYWZ0ZXIgaW52b2tpbmcgdGhlIGNvbnN0cnVjdG9yLiA8L3A+CiAgICAgICAqCiAgICAgICAqIEBwYXJhbSBuYW1lIFRoZSBgbmFtZWAgcGFyYW1ldGVyJ3MgdmFsdWUgZGVwZW5kcyBvbiB0aGUgdGFyZ2V0IHJlc291cmNlIGZvciB0aGUKICAgIHJlcXVlc3QsIG5hbWVseQogICAgICogICAgICAgIFtgcm9sZXNgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL3JvbGVzKSwKICAgICAqICAgICAgICBbYHByb2plY3RzYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9wcm9qZWN0cy5yb2xlcyksIG9yCiAgICAgKiAgICAgICAgW2Bvcmdhbml6YXRpb25zYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9vcmdhbml6YXRpb25zLnJvbGVzKS4gRWFjaAogICAgcmVzb3VyY2UgdHlwZSdzIGBuYW1lYAogICAgICogICAgICAgIHZhbHVlIGZvcm1hdCBpcyBkZXNjcmliZWQgYmVsb3c6CiAgICAqIFtgcm9sZXMuZ2V0KClgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL3JvbGVzL2dldCk6CiAgICAgKiAgICAgICAgYHJvbGVzL3tST0xFX05BTUV9YC4KICAgICAgVGhpcyBtZXRob2QgcmV0dXJucyByZXN1bHRzIGZyb20gYWxsCiAgICAgIFtwcmVkZWZpbmVkIHJvbGVzXSgvaWFtL2RvY3MKICAgICAqICAgICAgICAvdW5kZXJzdGFuZGluZy1yb2xlcyNwcmVkZWZpbmVkX3JvbGVzKSBpbgogICAgICBDbG91ZCBJQU0uIEV4YW1wbGUgcmVxdWVzdCBVUkw6CiAgICAgKiAgICAgICAgYGh0dHBzOi8vaWFtLmdvb2dsZWFwaXMuY29tL3YxL3JvbGVzL3tST0xFX05BTUV9YAogICAgKgogICAgICogICAgICAgIFtgcHJvamVjdHMucm9sZXMuZ2V0KClgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL3Byb2plY3RzLnJvbGVzL2dldCk6CiAgICAgKiAgICAgICAgYHByb2plY3RzL3tQUk9KRUNUX0lEfS9yb2xlcy97Q1VTVE9NX1JPTEVfSUR9YC4gVGhpcyBtZXRob2QgcmV0dXJucyBvbmx5CiAgICAgIFtjdXN0b20KICAgICAqICAgICAgICByb2xlc10oL2lhbS9kb2NzL3VuZGVyc3RhbmRpbmctY3VzdG9tLXJvbGVzKSB0aGF0IGhhdmUgYmVlbgogICAgICBjcmVhdGVkIGF0IHRoZSBwcm9qZWN0CiAgICAgKiAgICAgICAgbGV2ZWwuIEV4YW1wbGUgcmVxdWVzdCBVUkw6CiAgICAgKiAgICAgICAgYGh0dHBzOi8vaWFtLmdvb2dsZWFwaXMuY29tL3YxL3Byb2plY3RzL3tQUk9KRUNUX0lEfS9yb2xlcy97Q1VTVE9NX1JPTEVfSUR9YAogICAgKgogICAgICogICAgICAgIFtgb3JnYW5pemF0aW9ucy5yb2xlcy5nZXQoKWBdKC9pYW0vcmVmZXJlbmNlL3Jlc3QvdjEvb3JnYW5pemF0aW9ucy5yb2xlcy9nZXQpOgogICAgICogICAgICAgIGBvcmdhbml6YXRpb25zL3tPUkdBTklaQVRJT05fSUR9L3JvbGVzL3tDVVNUT01fUk9MRV9JRH1gLiBUaGlzIG1ldGhvZAogICAgICByZXR1cm5zIG9ubHkKICAgICAqICAgICAgICBbY3VzdG9tIHJvbGVzXSgvaWFtL2RvY3MvdW5kZXJzdGFuZGluZy1jdXN0b20tcm9sZXMpIHRoYXQKICAgICAgaGF2ZSBiZWVuIGNyZWF0ZWQgYXQgdGhlCiAgICAgKiAgICAgICAgb3JnYW5pemF0aW9uIGxldmVsLiBFeGFtcGxlIHJlcXVlc3QgVVJMOgogICAgICogICAgICAgIGBodHRwczovL2lhbS5nb29nbGVhcGlzLmNvbS92MS9vcmdhbml6YXRpb25zL3tPUkdBTklaQVRJT05fSUR9L3JvbGVzL3tDVVNUT01fUk9MRV9JRH1gCiAgICAgKiAgICAgICAgTm90ZTogV2lsZGNhcmQgKCopIHZhbHVlcyBhcmUgaW52YWxpZDsgeW91IG11c3Qgc3BlY2lmeSBhIGNvbXBsZXRlIHByb2plY3QKICAgIElEIG9yCiAgICAgKiAgICAgICAgb3JnYW5pemF0aW9uIElELgogICAgICAgKiBAc2luY2UgMS4xMwogICAgICAgKi8KICAgICAgcHJvdGVjdGVkIEdldChqYXZhLmxhbmcuU3RyaW5nIG5hbWUpIHsKICAgICAgICBzdXBlcihJYW0udGhpcywgIkdFVCIsIFJFU1RfUEFUSCwgbnVsbCwgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuaWFtLnYxLm1vZGVsLlJvbGUuY2xhc3MpOwogICAgICAgIHRoaXMubmFtZSA9IGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLlByZWNvbmRpdGlvbnMuY2hlY2tOb3ROdWxsKG5hbWUsICJSZXF1aXJlZCBwYXJhbWV0ZXIgbmFtZSBtdXN0IGJlIHNwZWNpZmllZC4iKTsKICAgICAgICBpZiAoIWdldFN1cHByZXNzUGF0dGVybkNoZWNrcygpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5QcmVjb25kaXRpb25zLmNoZWNrQXJndW1lbnQoTkFNRV9QQVRURVJOLm1hdGNoZXIobmFtZSkubWF0Y2hlcygpLAogICAgICAgICAgICAgICJQYXJhbWV0ZXIgbmFtZSBtdXN0IGNvbmZvcm0gdG8gdGhlIHBhdHRlcm4gIiArCiAgICAgICAgICAgICAgIl5yb2xlcy9bXi9dKyQiKTsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5hcGkuY2xpZW50Lmh0dHAuSHR0cFJlc3BvbnNlIGV4ZWN1dGVVc2luZ0hlYWQoKSB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmV4ZWN1dGVVc2luZ0hlYWQoKTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLmFwaS5jbGllbnQuaHR0cC5IdHRwUmVxdWVzdCBidWlsZEh0dHBSZXF1ZXN0VXNpbmdIZWFkKCkgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBzdXBlci5idWlsZEh0dHBSZXF1ZXN0VXNpbmdIZWFkKCk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgR2V0IHNldCRYZ2FmdihqYXZhLmxhbmcuU3RyaW5nICRYZ2FmdikgewogICAgICAgIHJldHVybiAoR2V0KSBzdXBlci5zZXQkWGdhZnYoJFhnYWZ2KTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBHZXQgc2V0QWNjZXNzVG9rZW4oamF2YS5sYW5nLlN0cmluZyBhY2Nlc3NUb2tlbikgewogICAgICAgIHJldHVybiAoR2V0KSBzdXBlci5zZXRBY2Nlc3NUb2tlbihhY2Nlc3NUb2tlbik7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgR2V0IHNldEFsdChqYXZhLmxhbmcuU3RyaW5nIGFsdCkgewogICAgICAgIHJldHVybiAoR2V0KSBzdXBlci5zZXRBbHQoYWx0KTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBHZXQgc2V0Q2FsbGJhY2soamF2YS5sYW5nLlN0cmluZyBjYWxsYmFjaykgewogICAgICAgIHJldHVybiAoR2V0KSBzdXBlci5zZXRDYWxsYmFjayhjYWxsYmFjayk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgR2V0IHNldEZpZWxkcyhqYXZhLmxhbmcuU3RyaW5nIGZpZWxkcykgewogICAgICAgIHJldHVybiAoR2V0KSBzdXBlci5zZXRGaWVsZHMoZmllbGRzKTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBHZXQgc2V0S2V5KGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgcmV0dXJuIChHZXQpIHN1cGVyLnNldEtleShrZXkpOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIEdldCBzZXRPYXV0aFRva2VuKGphdmEubGFuZy5TdHJpbmcgb2F1dGhUb2tlbikgewogICAgICAgIHJldHVybiAoR2V0KSBzdXBlci5zZXRPYXV0aFRva2VuKG9hdXRoVG9rZW4pOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIEdldCBzZXRQcmV0dHlQcmludChqYXZhLmxhbmcuQm9vbGVhbiBwcmV0dHlQcmludCkgewogICAgICAgIHJldHVybiAoR2V0KSBzdXBlci5zZXRQcmV0dHlQcmludChwcmV0dHlQcmludCk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgR2V0IHNldFF1b3RhVXNlcihqYXZhLmxhbmcuU3RyaW5nIHF1b3RhVXNlcikgewogICAgICAgIHJldHVybiAoR2V0KSBzdXBlci5zZXRRdW90YVVzZXIocXVvdGFVc2VyKTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBHZXQgc2V0VXBsb2FkVHlwZShqYXZhLmxhbmcuU3RyaW5nIHVwbG9hZFR5cGUpIHsKICAgICAgICByZXR1cm4gKEdldCkgc3VwZXIuc2V0VXBsb2FkVHlwZSh1cGxvYWRUeXBlKTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBHZXQgc2V0VXBsb2FkUHJvdG9jb2woamF2YS5sYW5nLlN0cmluZyB1cGxvYWRQcm90b2NvbCkgewogICAgICAgIHJldHVybiAoR2V0KSBzdXBlci5zZXRVcGxvYWRQcm90b2NvbCh1cGxvYWRQcm90b2NvbCk7CiAgICAgIH0KCiAgICAgIC8qKgogICAgICAgKiBUaGUgYG5hbWVgIHBhcmFtZXRlcidzIHZhbHVlIGRlcGVuZHMgb24gdGhlIHRhcmdldCByZXNvdXJjZSBmb3IgdGhlIHJlcXVlc3QsIG5hbWVseQogICAgICAgKiBbYHJvbGVzYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9yb2xlcyksCiAgICAgICAqIFtgcHJvamVjdHNgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL3Byb2plY3RzLnJvbGVzKSwgb3IKICAgICAgICogW2Bvcmdhbml6YXRpb25zYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9vcmdhbml6YXRpb25zLnJvbGVzKS4gRWFjaCByZXNvdXJjZSB0eXBlJ3MgYG5hbWVgCiAgICAgICAqIHZhbHVlIGZvcm1hdCBpcyBkZXNjcmliZWQgYmVsb3c6CiAgICAgICAqCiAgICAgICAqICogW2Byb2xlcy5nZXQoKWBdKC9pYW0vcmVmZXJlbmNlL3Jlc3QvdjEvcm9sZXMvZ2V0KTogYHJvbGVzL3tST0xFX05BTUV9YC4gVGhpcyBtZXRob2QKICAgICAgICogcmV0dXJucyByZXN1bHRzIGZyb20gYWxsIFtwcmVkZWZpbmVkIHJvbGVzXSgvaWFtL2RvY3MvdW5kZXJzdGFuZGluZy1yb2xlcyNwcmVkZWZpbmVkX3JvbGVzKQogICAgICAgKiBpbiBDbG91ZCBJQU0uIEV4YW1wbGUgcmVxdWVzdCBVUkw6IGBodHRwczovL2lhbS5nb29nbGVhcGlzLmNvbS92MS9yb2xlcy97Uk9MRV9OQU1FfWAKICAgICAgICoKICAgICAgICogKiBbYHByb2plY3RzLnJvbGVzLmdldCgpYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9wcm9qZWN0cy5yb2xlcy9nZXQpOgogICAgICAgKiBgcHJvamVjdHMve1BST0pFQ1RfSUR9L3JvbGVzL3tDVVNUT01fUk9MRV9JRH1gLiBUaGlzIG1ldGhvZCByZXR1cm5zIG9ubHkgW2N1c3RvbQogICAgICAgKiByb2xlc10oL2lhbS9kb2NzL3VuZGVyc3RhbmRpbmctY3VzdG9tLXJvbGVzKSB0aGF0IGhhdmUgYmVlbiBjcmVhdGVkIGF0IHRoZSBwcm9qZWN0IGxldmVsLgogICAgICAgKiBFeGFtcGxlIHJlcXVlc3QgVVJMOgogICAgICAgKiBgaHR0cHM6Ly9pYW0uZ29vZ2xlYXBpcy5jb20vdjEvcHJvamVjdHMve1BST0pFQ1RfSUR9L3JvbGVzL3tDVVNUT01fUk9MRV9JRH1gCiAgICAgICAqCiAgICAgICAqICogW2Bvcmdhbml6YXRpb25zLnJvbGVzLmdldCgpYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9vcmdhbml6YXRpb25zLnJvbGVzL2dldCk6CiAgICAgICAqIGBvcmdhbml6YXRpb25zL3tPUkdBTklaQVRJT05fSUR9L3JvbGVzL3tDVVNUT01fUk9MRV9JRH1gLiBUaGlzIG1ldGhvZCByZXR1cm5zIG9ubHkgW2N1c3RvbQogICAgICAgKiByb2xlc10oL2lhbS9kb2NzL3VuZGVyc3RhbmRpbmctY3VzdG9tLXJvbGVzKSB0aGF0IGhhdmUgYmVlbiBjcmVhdGVkIGF0IHRoZSBvcmdhbml6YXRpb24KICAgICAgICogbGV2ZWwuIEV4YW1wbGUgcmVxdWVzdCBVUkw6CiAgICAgICAqIGBodHRwczovL2lhbS5nb29nbGVhcGlzLmNvbS92MS9vcmdhbml6YXRpb25zL3tPUkdBTklaQVRJT05fSUR9L3JvbGVzL3tDVVNUT01fUk9MRV9JRH1gCiAgICAgICAqCiAgICAgICAqIE5vdGU6IFdpbGRjYXJkICgqKSB2YWx1ZXMgYXJlIGludmFsaWQ7IHlvdSBtdXN0IHNwZWNpZnkgYSBjb21wbGV0ZSBwcm9qZWN0IElEIG9yCiAgICAgICAqIG9yZ2FuaXphdGlvbiBJRC4KICAgICAgICovCiAgICAgIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuU3RyaW5nIG5hbWU7CgogICAgICAvKiogVGhlIGBuYW1lYCBwYXJhbWV0ZXIncyB2YWx1ZSBkZXBlbmRzIG9uIHRoZSB0YXJnZXQgcmVzb3VyY2UgZm9yIHRoZSByZXF1ZXN0LCBuYW1lbHkKICAgICBbYHJvbGVzYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9yb2xlcyksIFtgcHJvamVjdHNgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL3Byb2plY3RzLnJvbGVzKSwgb3IKICAgICBbYG9yZ2FuaXphdGlvbnNgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL29yZ2FuaXphdGlvbnMucm9sZXMpLiBFYWNoIHJlc291cmNlIHR5cGUncyBgbmFtZWAgdmFsdWUKICAgICBmb3JtYXQgaXMgZGVzY3JpYmVkIGJlbG93OgoKICAgICAqIFtgcm9sZXMuZ2V0KClgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL3JvbGVzL2dldCk6IGByb2xlcy97Uk9MRV9OQU1FfWAuIFRoaXMgbWV0aG9kIHJldHVybnMKICAgICByZXN1bHRzIGZyb20gYWxsIFtwcmVkZWZpbmVkIHJvbGVzXSgvaWFtL2RvY3MvdW5kZXJzdGFuZGluZy1yb2xlcyNwcmVkZWZpbmVkX3JvbGVzKSBpbiBDbG91ZCBJQU0uCiAgICAgRXhhbXBsZSByZXF1ZXN0IFVSTDogYGh0dHBzOi8vaWFtLmdvb2dsZWFwaXMuY29tL3YxL3JvbGVzL3tST0xFX05BTUV9YAoKICAgICAqIFtgcHJvamVjdHMucm9sZXMuZ2V0KClgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL3Byb2plY3RzLnJvbGVzL2dldCk6CiAgICAgYHByb2plY3RzL3tQUk9KRUNUX0lEfS9yb2xlcy97Q1VTVE9NX1JPTEVfSUR9YC4gVGhpcyBtZXRob2QgcmV0dXJucyBvbmx5IFtjdXN0b20gcm9sZXNdKC9pYW0vZG9jcwogICAgIC91bmRlcnN0YW5kaW5nLWN1c3RvbS1yb2xlcykgdGhhdCBoYXZlIGJlZW4gY3JlYXRlZCBhdCB0aGUgcHJvamVjdCBsZXZlbC4gRXhhbXBsZSByZXF1ZXN0IFVSTDoKICAgICBgaHR0cHM6Ly9pYW0uZ29vZ2xlYXBpcy5jb20vdjEvcHJvamVjdHMve1BST0pFQ1RfSUR9L3JvbGVzL3tDVVNUT01fUk9MRV9JRH1gCgogICAgICogW2Bvcmdhbml6YXRpb25zLnJvbGVzLmdldCgpYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9vcmdhbml6YXRpb25zLnJvbGVzL2dldCk6CiAgICAgYG9yZ2FuaXphdGlvbnMve09SR0FOSVpBVElPTl9JRH0vcm9sZXMve0NVU1RPTV9ST0xFX0lEfWAuIFRoaXMgbWV0aG9kIHJldHVybnMgb25seSBbY3VzdG9tCiAgICAgcm9sZXNdKC9pYW0vZG9jcy91bmRlcnN0YW5kaW5nLWN1c3RvbS1yb2xlcykgdGhhdCBoYXZlIGJlZW4gY3JlYXRlZCBhdCB0aGUgb3JnYW5pemF0aW9uIGxldmVsLgogICAgIEV4YW1wbGUgcmVxdWVzdCBVUkw6CiAgICAgYGh0dHBzOi8vaWFtLmdvb2dsZWFwaXMuY29tL3YxL29yZ2FuaXphdGlvbnMve09SR0FOSVpBVElPTl9JRH0vcm9sZXMve0NVU1RPTV9ST0xFX0lEfWAKCiAgICAgTm90ZTogV2lsZGNhcmQgKCopIHZhbHVlcyBhcmUgaW52YWxpZDsgeW91IG11c3Qgc3BlY2lmeSBhIGNvbXBsZXRlIHByb2plY3QgSUQgb3Igb3JnYW5pemF0aW9uIElELgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TmFtZSgpIHsKICAgICAgICByZXR1cm4gbmFtZTsKICAgICAgfQoKICAgICAgLyoqCiAgICAgICAqIFRoZSBgbmFtZWAgcGFyYW1ldGVyJ3MgdmFsdWUgZGVwZW5kcyBvbiB0aGUgdGFyZ2V0IHJlc291cmNlIGZvciB0aGUgcmVxdWVzdCwgbmFtZWx5CiAgICAgICAqIFtgcm9sZXNgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL3JvbGVzKSwKICAgICAgICogW2Bwcm9qZWN0c2BdKC9pYW0vcmVmZXJlbmNlL3Jlc3QvdjEvcHJvamVjdHMucm9sZXMpLCBvcgogICAgICAgKiBbYG9yZ2FuaXphdGlvbnNgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL29yZ2FuaXphdGlvbnMucm9sZXMpLiBFYWNoIHJlc291cmNlIHR5cGUncyBgbmFtZWAKICAgICAgICogdmFsdWUgZm9ybWF0IGlzIGRlc2NyaWJlZCBiZWxvdzoKICAgICAgICoKICAgICAgICogKiBbYHJvbGVzLmdldCgpYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9yb2xlcy9nZXQpOiBgcm9sZXMve1JPTEVfTkFNRX1gLiBUaGlzIG1ldGhvZAogICAgICAgKiByZXR1cm5zIHJlc3VsdHMgZnJvbSBhbGwgW3ByZWRlZmluZWQgcm9sZXNdKC9pYW0vZG9jcy91bmRlcnN0YW5kaW5nLXJvbGVzI3ByZWRlZmluZWRfcm9sZXMpCiAgICAgICAqIGluIENsb3VkIElBTS4gRXhhbXBsZSByZXF1ZXN0IFVSTDogYGh0dHBzOi8vaWFtLmdvb2dsZWFwaXMuY29tL3YxL3JvbGVzL3tST0xFX05BTUV9YAogICAgICAgKgogICAgICAgKiAqIFtgcHJvamVjdHMucm9sZXMuZ2V0KClgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL3Byb2plY3RzLnJvbGVzL2dldCk6CiAgICAgICAqIGBwcm9qZWN0cy97UFJPSkVDVF9JRH0vcm9sZXMve0NVU1RPTV9ST0xFX0lEfWAuIFRoaXMgbWV0aG9kIHJldHVybnMgb25seSBbY3VzdG9tCiAgICAgICAqIHJvbGVzXSgvaWFtL2RvY3MvdW5kZXJzdGFuZGluZy1jdXN0b20tcm9sZXMpIHRoYXQgaGF2ZSBiZWVuIGNyZWF0ZWQgYXQgdGhlIHByb2plY3QgbGV2ZWwuCiAgICAgICAqIEV4YW1wbGUgcmVxdWVzdCBVUkw6CiAgICAgICAqIGBodHRwczovL2lhbS5nb29nbGVhcGlzLmNvbS92MS9wcm9qZWN0cy97UFJPSkVDVF9JRH0vcm9sZXMve0NVU1RPTV9ST0xFX0lEfWAKICAgICAgICoKICAgICAgICogKiBbYG9yZ2FuaXphdGlvbnMucm9sZXMuZ2V0KClgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL29yZ2FuaXphdGlvbnMucm9sZXMvZ2V0KToKICAgICAgICogYG9yZ2FuaXphdGlvbnMve09SR0FOSVpBVElPTl9JRH0vcm9sZXMve0NVU1RPTV9ST0xFX0lEfWAuIFRoaXMgbWV0aG9kIHJldHVybnMgb25seSBbY3VzdG9tCiAgICAgICAqIHJvbGVzXSgvaWFtL2RvY3MvdW5kZXJzdGFuZGluZy1jdXN0b20tcm9sZXMpIHRoYXQgaGF2ZSBiZWVuIGNyZWF0ZWQgYXQgdGhlIG9yZ2FuaXphdGlvbgogICAgICAgKiBsZXZlbC4gRXhhbXBsZSByZXF1ZXN0IFVSTDoKICAgICAgICogYGh0dHBzOi8vaWFtLmdvb2dsZWFwaXMuY29tL3YxL29yZ2FuaXphdGlvbnMve09SR0FOSVpBVElPTl9JRH0vcm9sZXMve0NVU1RPTV9ST0xFX0lEfWAKICAgICAgICoKICAgICAgICogTm90ZTogV2lsZGNhcmQgKCopIHZhbHVlcyBhcmUgaW52YWxpZDsgeW91IG11c3Qgc3BlY2lmeSBhIGNvbXBsZXRlIHByb2plY3QgSUQgb3IKICAgICAgICogb3JnYW5pemF0aW9uIElELgogICAgICAgKi8KICAgICAgcHVibGljIEdldCBzZXROYW1lKGphdmEubGFuZy5TdHJpbmcgbmFtZSkgewogICAgICAgIGlmICghZ2V0U3VwcHJlc3NQYXR0ZXJuQ2hlY2tzKCkpIHsKICAgICAgICAgIGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLlByZWNvbmRpdGlvbnMuY2hlY2tBcmd1bWVudChOQU1FX1BBVFRFUk4ubWF0Y2hlcihuYW1lKS5tYXRjaGVzKCksCiAgICAgICAgICAgICAgIlBhcmFtZXRlciBuYW1lIG11c3QgY29uZm9ybSB0byB0aGUgcGF0dGVybiAiICsKICAgICAgICAgICAgICAiXnJvbGVzL1teL10rJCIpOwogICAgICAgIH0KICAgICAgICB0aGlzLm5hbWUgPSBuYW1lOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIEdldCBzZXQoU3RyaW5nIHBhcmFtZXRlck5hbWUsIE9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiAoR2V0KSBzdXBlci5zZXQocGFyYW1ldGVyTmFtZSwgdmFsdWUpOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIExpc3RzIHRoZSBSb2xlcyBkZWZpbmVkIG9uIGEgcmVzb3VyY2UuCiAgICAgKgogICAgICogQ3JlYXRlIGEgcmVxdWVzdCBmb3IgdGhlIG1ldGhvZCAicm9sZXMubGlzdCIuCiAgICAgKgogICAgICogVGhpcyByZXF1ZXN0IGhvbGRzIHRoZSBwYXJhbWV0ZXJzIG5lZWRlZCBieSB0aGUgaWFtIHNlcnZlci4gIEFmdGVyIHNldHRpbmcgYW55IG9wdGlvbmFsCiAgICAgKiBwYXJhbWV0ZXJzLCBjYWxsIHRoZSB7QGxpbmsgTGlzdCNleGVjdXRlKCl9IG1ldGhvZCB0byBpbnZva2UgdGhlIHJlbW90ZSBvcGVyYXRpb24uCiAgICAgKgogICAgICogQHJldHVybiB0aGUgcmVxdWVzdAogICAgICovCiAgICBwdWJsaWMgTGlzdCBsaXN0KCkgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBMaXN0IHJlc3VsdCA9IG5ldyBMaXN0KCk7CiAgICAgIGluaXRpYWxpemUocmVzdWx0KTsKICAgICAgcmV0dXJuIHJlc3VsdDsKICAgIH0KCiAgICBwdWJsaWMgY2xhc3MgTGlzdCBleHRlbmRzIElhbVJlcXVlc3Q8Y29tLmdvb2dsZS5hcGkuc2VydmljZXMuaWFtLnYxLm1vZGVsLkxpc3RSb2xlc1Jlc3BvbnNlPiB7CgogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgUkVTVF9QQVRIID0gInYxL3JvbGVzIjsKCiAgICAgIC8qKgogICAgICAgKiBMaXN0cyB0aGUgUm9sZXMgZGVmaW5lZCBvbiBhIHJlc291cmNlLgogICAgICAgKgogICAgICAgKiBDcmVhdGUgYSByZXF1ZXN0IGZvciB0aGUgbWV0aG9kICJyb2xlcy5saXN0Ii4KICAgICAgICoKICAgICAgICogVGhpcyByZXF1ZXN0IGhvbGRzIHRoZSBwYXJhbWV0ZXJzIG5lZWRlZCBieSB0aGUgdGhlIGlhbSBzZXJ2ZXIuICBBZnRlciBzZXR0aW5nIGFueSBvcHRpb25hbAogICAgICAgKiBwYXJhbWV0ZXJzLCBjYWxsIHRoZSB7QGxpbmsgTGlzdCNleGVjdXRlKCl9IG1ldGhvZCB0byBpbnZva2UgdGhlIHJlbW90ZSBvcGVyYXRpb24uIDxwPiB7QGxpbmsKICAgICAgICogTGlzdCNpbml0aWFsaXplKGNvbS5nb29nbGUuYXBpLmNsaWVudC5nb29nbGVhcGlzLnNlcnZpY2VzLkFic3RyYWN0R29vZ2xlQ2xpZW50UmVxdWVzdCl9IG11c3QgYmUKICAgICAgICogY2FsbGVkIHRvIGluaXRpYWxpemUgdGhpcyBpbnN0YW5jZSBpbW1lZGlhdGVseSBhZnRlciBpbnZva2luZyB0aGUgY29uc3RydWN0b3IuIDwvcD4KICAgICAgICoKICAgICAgICogQHNpbmNlIDEuMTMKICAgICAgICovCiAgICAgIHByb3RlY3RlZCBMaXN0KCkgewogICAgICAgIHN1cGVyKElhbS50aGlzLCAiR0VUIiwgUkVTVF9QQVRILCBudWxsLCBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5pYW0udjEubW9kZWwuTGlzdFJvbGVzUmVzcG9uc2UuY2xhc3MpOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUuYXBpLmNsaWVudC5odHRwLkh0dHBSZXNwb25zZSBleGVjdXRlVXNpbmdIZWFkKCkgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBzdXBlci5leGVjdXRlVXNpbmdIZWFkKCk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5hcGkuY2xpZW50Lmh0dHAuSHR0cFJlcXVlc3QgYnVpbGRIdHRwUmVxdWVzdFVzaW5nSGVhZCgpIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gc3VwZXIuYnVpbGRIdHRwUmVxdWVzdFVzaW5nSGVhZCgpOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIExpc3Qgc2V0JFhnYWZ2KGphdmEubGFuZy5TdHJpbmcgJFhnYWZ2KSB7CiAgICAgICAgcmV0dXJuIChMaXN0KSBzdXBlci5zZXQkWGdhZnYoJFhnYWZ2KTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBMaXN0IHNldEFjY2Vzc1Rva2VuKGphdmEubGFuZy5TdHJpbmcgYWNjZXNzVG9rZW4pIHsKICAgICAgICByZXR1cm4gKExpc3QpIHN1cGVyLnNldEFjY2Vzc1Rva2VuKGFjY2Vzc1Rva2VuKTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBMaXN0IHNldEFsdChqYXZhLmxhbmcuU3RyaW5nIGFsdCkgewogICAgICAgIHJldHVybiAoTGlzdCkgc3VwZXIuc2V0QWx0KGFsdCk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgTGlzdCBzZXRDYWxsYmFjayhqYXZhLmxhbmcuU3RyaW5nIGNhbGxiYWNrKSB7CiAgICAgICAgcmV0dXJuIChMaXN0KSBzdXBlci5zZXRDYWxsYmFjayhjYWxsYmFjayk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgTGlzdCBzZXRGaWVsZHMoamF2YS5sYW5nLlN0cmluZyBmaWVsZHMpIHsKICAgICAgICByZXR1cm4gKExpc3QpIHN1cGVyLnNldEZpZWxkcyhmaWVsZHMpOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIExpc3Qgc2V0S2V5KGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgcmV0dXJuIChMaXN0KSBzdXBlci5zZXRLZXkoa2V5KTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBMaXN0IHNldE9hdXRoVG9rZW4oamF2YS5sYW5nLlN0cmluZyBvYXV0aFRva2VuKSB7CiAgICAgICAgcmV0dXJuIChMaXN0KSBzdXBlci5zZXRPYXV0aFRva2VuKG9hdXRoVG9rZW4pOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIExpc3Qgc2V0UHJldHR5UHJpbnQoamF2YS5sYW5nLkJvb2xlYW4gcHJldHR5UHJpbnQpIHsKICAgICAgICByZXR1cm4gKExpc3QpIHN1cGVyLnNldFByZXR0eVByaW50KHByZXR0eVByaW50KTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBMaXN0IHNldFF1b3RhVXNlcihqYXZhLmxhbmcuU3RyaW5nIHF1b3RhVXNlcikgewogICAgICAgIHJldHVybiAoTGlzdCkgc3VwZXIuc2V0UXVvdGFVc2VyKHF1b3RhVXNlcik7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgTGlzdCBzZXRVcGxvYWRUeXBlKGphdmEubGFuZy5TdHJpbmcgdXBsb2FkVHlwZSkgewogICAgICAgIHJldHVybiAoTGlzdCkgc3VwZXIuc2V0VXBsb2FkVHlwZSh1cGxvYWRUeXBlKTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBMaXN0IHNldFVwbG9hZFByb3RvY29sKGphdmEubGFuZy5TdHJpbmcgdXBsb2FkUHJvdG9jb2wpIHsKICAgICAgICByZXR1cm4gKExpc3QpIHN1cGVyLnNldFVwbG9hZFByb3RvY29sKHVwbG9hZFByb3RvY29sKTsKICAgICAgfQoKICAgICAgLyoqIEluY2x1ZGUgUm9sZXMgdGhhdCBoYXZlIGJlZW4gZGVsZXRlZC4gKi8KICAgICAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogICAgICBwcml2YXRlIGphdmEubGFuZy5Cb29sZWFuIHNob3dEZWxldGVkOwoKICAgICAgLyoqIEluY2x1ZGUgUm9sZXMgdGhhdCBoYXZlIGJlZW4gZGVsZXRlZC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuQm9vbGVhbiBnZXRTaG93RGVsZXRlZCgpIHsKICAgICAgICByZXR1cm4gc2hvd0RlbGV0ZWQ7CiAgICAgIH0KCiAgICAgIC8qKiBJbmNsdWRlIFJvbGVzIHRoYXQgaGF2ZSBiZWVuIGRlbGV0ZWQuICovCiAgICAgIHB1YmxpYyBMaXN0IHNldFNob3dEZWxldGVkKGphdmEubGFuZy5Cb29sZWFuIHNob3dEZWxldGVkKSB7CiAgICAgICAgdGhpcy5zaG93RGVsZXRlZCA9IHNob3dEZWxldGVkOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICAvKiogT3B0aW9uYWwgcGFnaW5hdGlvbiB0b2tlbiByZXR1cm5lZCBpbiBhbiBlYXJsaWVyIExpc3RSb2xlc1Jlc3BvbnNlLiAqLwogICAgICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgICAgIHByaXZhdGUgamF2YS5sYW5nLlN0cmluZyBwYWdlVG9rZW47CgogICAgICAvKiogT3B0aW9uYWwgcGFnaW5hdGlvbiB0b2tlbiByZXR1cm5lZCBpbiBhbiBlYXJsaWVyIExpc3RSb2xlc1Jlc3BvbnNlLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0UGFnZVRva2VuKCkgewogICAgICAgIHJldHVybiBwYWdlVG9rZW47CiAgICAgIH0KCiAgICAgIC8qKiBPcHRpb25hbCBwYWdpbmF0aW9uIHRva2VuIHJldHVybmVkIGluIGFuIGVhcmxpZXIgTGlzdFJvbGVzUmVzcG9uc2UuICovCiAgICAgIHB1YmxpYyBMaXN0IHNldFBhZ2VUb2tlbihqYXZhLmxhbmcuU3RyaW5nIHBhZ2VUb2tlbikgewogICAgICAgIHRoaXMucGFnZVRva2VuID0gcGFnZVRva2VuOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICAvKiogT3B0aW9uYWwgbGltaXQgb24gdGhlIG51bWJlciBvZiByb2xlcyB0byBpbmNsdWRlIGluIHRoZSByZXNwb25zZS4gKi8KICAgICAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogICAgICBwcml2YXRlIGphdmEubGFuZy5JbnRlZ2VyIHBhZ2VTaXplOwoKICAgICAgLyoqIE9wdGlvbmFsIGxpbWl0IG9uIHRoZSBudW1iZXIgb2Ygcm9sZXMgdG8gaW5jbHVkZSBpbiB0aGUgcmVzcG9uc2UuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLkludGVnZXIgZ2V0UGFnZVNpemUoKSB7CiAgICAgICAgcmV0dXJuIHBhZ2VTaXplOwogICAgICB9CgogICAgICAvKiogT3B0aW9uYWwgbGltaXQgb24gdGhlIG51bWJlciBvZiByb2xlcyB0byBpbmNsdWRlIGluIHRoZSByZXNwb25zZS4gKi8KICAgICAgcHVibGljIExpc3Qgc2V0UGFnZVNpemUoamF2YS5sYW5nLkludGVnZXIgcGFnZVNpemUpIHsKICAgICAgICB0aGlzLnBhZ2VTaXplID0gcGFnZVNpemU7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIC8qKgogICAgICAgKiBPcHRpb25hbCB2aWV3IGZvciB0aGUgcmV0dXJuZWQgUm9sZSBvYmplY3RzLiBXaGVuIGBGVUxMYCBpcyBzcGVjaWZpZWQsIHRoZQogICAgICAgKiBgaW5jbHVkZWRQZXJtaXNzaW9uc2AgZmllbGQgaXMgcmV0dXJuZWQsIHdoaWNoIGluY2x1ZGVzIGEgbGlzdCBvZiBhbGwgcGVybWlzc2lvbnMgaW4gdGhlCiAgICAgICAqIHJvbGUuIFRoZSBkZWZhdWx0IHZhbHVlIGlzIGBCQVNJQ2AsIHdoaWNoIGRvZXMgbm90IHJldHVybiB0aGUgYGluY2x1ZGVkUGVybWlzc2lvbnNgIGZpZWxkLgogICAgICAgKi8KICAgICAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogICAgICBwcml2YXRlIGphdmEubGFuZy5TdHJpbmcgdmlldzsKCiAgICAgIC8qKiBPcHRpb25hbCB2aWV3IGZvciB0aGUgcmV0dXJuZWQgUm9sZSBvYmplY3RzLiBXaGVuIGBGVUxMYCBpcyBzcGVjaWZpZWQsIHRoZSBgaW5jbHVkZWRQZXJtaXNzaW9uc2AKICAgICBmaWVsZCBpcyByZXR1cm5lZCwgd2hpY2ggaW5jbHVkZXMgYSBsaXN0IG9mIGFsbCBwZXJtaXNzaW9ucyBpbiB0aGUgcm9sZS4gVGhlIGRlZmF1bHQgdmFsdWUgaXMKICAgICBgQkFTSUNgLCB3aGljaCBkb2VzIG5vdCByZXR1cm4gdGhlIGBpbmNsdWRlZFBlcm1pc3Npb25zYCBmaWVsZC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFZpZXcoKSB7CiAgICAgICAgcmV0dXJuIHZpZXc7CiAgICAgIH0KCiAgICAgIC8qKgogICAgICAgKiBPcHRpb25hbCB2aWV3IGZvciB0aGUgcmV0dXJuZWQgUm9sZSBvYmplY3RzLiBXaGVuIGBGVUxMYCBpcyBzcGVjaWZpZWQsIHRoZQogICAgICAgKiBgaW5jbHVkZWRQZXJtaXNzaW9uc2AgZmllbGQgaXMgcmV0dXJuZWQsIHdoaWNoIGluY2x1ZGVzIGEgbGlzdCBvZiBhbGwgcGVybWlzc2lvbnMgaW4gdGhlCiAgICAgICAqIHJvbGUuIFRoZSBkZWZhdWx0IHZhbHVlIGlzIGBCQVNJQ2AsIHdoaWNoIGRvZXMgbm90IHJldHVybiB0aGUgYGluY2x1ZGVkUGVybWlzc2lvbnNgIGZpZWxkLgogICAgICAgKi8KICAgICAgcHVibGljIExpc3Qgc2V0VmlldyhqYXZhLmxhbmcuU3RyaW5nIHZpZXcpIHsKICAgICAgICB0aGlzLnZpZXcgPSB2aWV3OwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICAvKioKICAgICAgICogVGhlIGBwYXJlbnRgIHBhcmFtZXRlcidzIHZhbHVlIGRlcGVuZHMgb24gdGhlIHRhcmdldCByZXNvdXJjZSBmb3IgdGhlIHJlcXVlc3QsIG5hbWVseQogICAgICAgKiBbYHJvbGVzYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9yb2xlcyksCiAgICAgICAqIFtgcHJvamVjdHNgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL3Byb2plY3RzLnJvbGVzKSwgb3IKICAgICAgICogW2Bvcmdhbml6YXRpb25zYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9vcmdhbml6YXRpb25zLnJvbGVzKS4gRWFjaCByZXNvdXJjZSB0eXBlJ3MKICAgICAgICogYHBhcmVudGAgdmFsdWUgZm9ybWF0IGlzIGRlc2NyaWJlZCBiZWxvdzoKICAgICAgICoKICAgICAgICogKiBbYHJvbGVzLmxpc3QoKWBdKC9pYW0vcmVmZXJlbmNlL3Jlc3QvdjEvcm9sZXMvbGlzdCk6IEFuIGVtcHR5IHN0cmluZy4gVGhpcyBtZXRob2QgZG9lc24ndAogICAgICAgKiByZXF1aXJlIGEgcmVzb3VyY2U7IGl0IHNpbXBseSByZXR1cm5zIGFsbCBbcHJlZGVmaW5lZCByb2xlc10oL2lhbS9kb2NzL3VuZGVyc3RhbmRpbmctCiAgICAgICAqIHJvbGVzI3ByZWRlZmluZWRfcm9sZXMpIGluIENsb3VkIElBTS4gRXhhbXBsZSByZXF1ZXN0IFVSTDoKICAgICAgICogYGh0dHBzOi8vaWFtLmdvb2dsZWFwaXMuY29tL3YxL3JvbGVzYAogICAgICAgKgogICAgICAgKiAqIFtgcHJvamVjdHMucm9sZXMubGlzdCgpYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9wcm9qZWN0cy5yb2xlcy9saXN0KToKICAgICAgICogYHByb2plY3RzL3tQUk9KRUNUX0lEfWAuIFRoaXMgbWV0aG9kIGxpc3RzIGFsbCBwcm9qZWN0LWxldmVsIFtjdXN0b20gcm9sZXNdKC9pYW0vZG9jcwogICAgICAgKiAvdW5kZXJzdGFuZGluZy1jdXN0b20tcm9sZXMpLiBFeGFtcGxlIHJlcXVlc3QgVVJMOgogICAgICAgKiBgaHR0cHM6Ly9pYW0uZ29vZ2xlYXBpcy5jb20vdjEvcHJvamVjdHMve1BST0pFQ1RfSUR9L3JvbGVzYAogICAgICAgKgogICAgICAgKiAqIFtgb3JnYW5pemF0aW9ucy5yb2xlcy5saXN0KClgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL29yZ2FuaXphdGlvbnMucm9sZXMvbGlzdCk6CiAgICAgICAqIGBvcmdhbml6YXRpb25zL3tPUkdBTklaQVRJT05fSUR9YC4gVGhpcyBtZXRob2QgbGlzdHMgYWxsIG9yZ2FuaXphdGlvbi1sZXZlbCBbY3VzdG9tCiAgICAgICAqIHJvbGVzXSgvaWFtL2RvY3MvdW5kZXJzdGFuZGluZy1jdXN0b20tcm9sZXMpLiBFeGFtcGxlIHJlcXVlc3QgVVJMOgogICAgICAgKiBgaHR0cHM6Ly9pYW0uZ29vZ2xlYXBpcy5jb20vdjEvb3JnYW5pemF0aW9ucy97T1JHQU5JWkFUSU9OX0lEfS9yb2xlc2AKICAgICAgICoKICAgICAgICogTm90ZTogV2lsZGNhcmQgKCopIHZhbHVlcyBhcmUgaW52YWxpZDsgeW91IG11c3Qgc3BlY2lmeSBhIGNvbXBsZXRlIHByb2plY3QgSUQgb3IKICAgICAgICogb3JnYW5pemF0aW9uIElELgogICAgICAgKi8KICAgICAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogICAgICBwcml2YXRlIGphdmEubGFuZy5TdHJpbmcgcGFyZW50OwoKICAgICAgLyoqIFRoZSBgcGFyZW50YCBwYXJhbWV0ZXIncyB2YWx1ZSBkZXBlbmRzIG9uIHRoZSB0YXJnZXQgcmVzb3VyY2UgZm9yIHRoZSByZXF1ZXN0LCBuYW1lbHkKICAgICBbYHJvbGVzYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9yb2xlcyksIFtgcHJvamVjdHNgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL3Byb2plY3RzLnJvbGVzKSwgb3IKICAgICBbYG9yZ2FuaXphdGlvbnNgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL29yZ2FuaXphdGlvbnMucm9sZXMpLiBFYWNoIHJlc291cmNlIHR5cGUncyBgcGFyZW50YCB2YWx1ZQogICAgIGZvcm1hdCBpcyBkZXNjcmliZWQgYmVsb3c6CgogICAgICogW2Byb2xlcy5saXN0KClgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL3JvbGVzL2xpc3QpOiBBbiBlbXB0eSBzdHJpbmcuIFRoaXMgbWV0aG9kIGRvZXNuJ3QgcmVxdWlyZQogICAgIGEgcmVzb3VyY2U7IGl0IHNpbXBseSByZXR1cm5zIGFsbCBbcHJlZGVmaW5lZCByb2xlc10oL2lhbS9kb2NzL3VuZGVyc3RhbmRpbmctCiAgICAgcm9sZXMjcHJlZGVmaW5lZF9yb2xlcykgaW4gQ2xvdWQgSUFNLiBFeGFtcGxlIHJlcXVlc3QgVVJMOiBgaHR0cHM6Ly9pYW0uZ29vZ2xlYXBpcy5jb20vdjEvcm9sZXNgCgogICAgICogW2Bwcm9qZWN0cy5yb2xlcy5saXN0KClgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL3Byb2plY3RzLnJvbGVzL2xpc3QpOiBgcHJvamVjdHMve1BST0pFQ1RfSUR9YC4KICAgICBUaGlzIG1ldGhvZCBsaXN0cyBhbGwgcHJvamVjdC1sZXZlbCBbY3VzdG9tIHJvbGVzXSgvaWFtL2RvY3MvdW5kZXJzdGFuZGluZy1jdXN0b20tcm9sZXMpLiBFeGFtcGxlCiAgICAgcmVxdWVzdCBVUkw6IGBodHRwczovL2lhbS5nb29nbGVhcGlzLmNvbS92MS9wcm9qZWN0cy97UFJPSkVDVF9JRH0vcm9sZXNgCgogICAgICogW2Bvcmdhbml6YXRpb25zLnJvbGVzLmxpc3QoKWBdKC9pYW0vcmVmZXJlbmNlL3Jlc3QvdjEvb3JnYW5pemF0aW9ucy5yb2xlcy9saXN0KToKICAgICBgb3JnYW5pemF0aW9ucy97T1JHQU5JWkFUSU9OX0lEfWAuIFRoaXMgbWV0aG9kIGxpc3RzIGFsbCBvcmdhbml6YXRpb24tbGV2ZWwgW2N1c3RvbQogICAgIHJvbGVzXSgvaWFtL2RvY3MvdW5kZXJzdGFuZGluZy1jdXN0b20tcm9sZXMpLiBFeGFtcGxlIHJlcXVlc3QgVVJMOgogICAgIGBodHRwczovL2lhbS5nb29nbGVhcGlzLmNvbS92MS9vcmdhbml6YXRpb25zL3tPUkdBTklaQVRJT05fSUR9L3JvbGVzYAoKICAgICBOb3RlOiBXaWxkY2FyZCAoKikgdmFsdWVzIGFyZSBpbnZhbGlkOyB5b3UgbXVzdCBzcGVjaWZ5IGEgY29tcGxldGUgcHJvamVjdCBJRCBvciBvcmdhbml6YXRpb24gSUQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRQYXJlbnQoKSB7CiAgICAgICAgcmV0dXJuIHBhcmVudDsKICAgICAgfQoKICAgICAgLyoqCiAgICAgICAqIFRoZSBgcGFyZW50YCBwYXJhbWV0ZXIncyB2YWx1ZSBkZXBlbmRzIG9uIHRoZSB0YXJnZXQgcmVzb3VyY2UgZm9yIHRoZSByZXF1ZXN0LCBuYW1lbHkKICAgICAgICogW2Byb2xlc2BdKC9pYW0vcmVmZXJlbmNlL3Jlc3QvdjEvcm9sZXMpLAogICAgICAgKiBbYHByb2plY3RzYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9wcm9qZWN0cy5yb2xlcyksIG9yCiAgICAgICAqIFtgb3JnYW5pemF0aW9uc2BdKC9pYW0vcmVmZXJlbmNlL3Jlc3QvdjEvb3JnYW5pemF0aW9ucy5yb2xlcykuIEVhY2ggcmVzb3VyY2UgdHlwZSdzCiAgICAgICAqIGBwYXJlbnRgIHZhbHVlIGZvcm1hdCBpcyBkZXNjcmliZWQgYmVsb3c6CiAgICAgICAqCiAgICAgICAqICogW2Byb2xlcy5saXN0KClgXSgvaWFtL3JlZmVyZW5jZS9yZXN0L3YxL3JvbGVzL2xpc3QpOiBBbiBlbXB0eSBzdHJpbmcuIFRoaXMgbWV0aG9kIGRvZXNuJ3QKICAgICAgICogcmVxdWlyZSBhIHJlc291cmNlOyBpdCBzaW1wbHkgcmV0dXJucyBhbGwgW3ByZWRlZmluZWQgcm9sZXNdKC9pYW0vZG9jcy91bmRlcnN0YW5kaW5nLQogICAgICAgKiByb2xlcyNwcmVkZWZpbmVkX3JvbGVzKSBpbiBDbG91ZCBJQU0uIEV4YW1wbGUgcmVxdWVzdCBVUkw6CiAgICAgICAqIGBodHRwczovL2lhbS5nb29nbGVhcGlzLmNvbS92MS9yb2xlc2AKICAgICAgICoKICAgICAgICogKiBbYHByb2plY3RzLnJvbGVzLmxpc3QoKWBdKC9pYW0vcmVmZXJlbmNlL3Jlc3QvdjEvcHJvamVjdHMucm9sZXMvbGlzdCk6CiAgICAgICAqIGBwcm9qZWN0cy97UFJPSkVDVF9JRH1gLiBUaGlzIG1ldGhvZCBsaXN0cyBhbGwgcHJvamVjdC1sZXZlbCBbY3VzdG9tIHJvbGVzXSgvaWFtL2RvY3MKICAgICAgICogL3VuZGVyc3RhbmRpbmctY3VzdG9tLXJvbGVzKS4gRXhhbXBsZSByZXF1ZXN0IFVSTDoKICAgICAgICogYGh0dHBzOi8vaWFtLmdvb2dsZWFwaXMuY29tL3YxL3Byb2plY3RzL3tQUk9KRUNUX0lEfS9yb2xlc2AKICAgICAgICoKICAgICAgICogKiBbYG9yZ2FuaXphdGlvbnMucm9sZXMubGlzdCgpYF0oL2lhbS9yZWZlcmVuY2UvcmVzdC92MS9vcmdhbml6YXRpb25zLnJvbGVzL2xpc3QpOgogICAgICAgKiBgb3JnYW5pemF0aW9ucy97T1JHQU5JWkFUSU9OX0lEfWAuIFRoaXMgbWV0aG9kIGxpc3RzIGFsbCBvcmdhbml6YXRpb24tbGV2ZWwgW2N1c3RvbQogICAgICAgKiByb2xlc10oL2lhbS9kb2NzL3VuZGVyc3RhbmRpbmctY3VzdG9tLXJvbGVzKS4gRXhhbXBsZSByZXF1ZXN0IFVSTDoKICAgICAgICogYGh0dHBzOi8vaWFtLmdvb2dsZWFwaXMuY29tL3YxL29yZ2FuaXphdGlvbnMve09SR0FOSVpBVElPTl9JRH0vcm9sZXNgCiAgICAgICAqCiAgICAgICAqIE5vdGU6IFdpbGRjYXJkICgqKSB2YWx1ZXMgYXJlIGludmFsaWQ7IHlvdSBtdXN0IHNwZWNpZnkgYSBjb21wbGV0ZSBwcm9qZWN0IElEIG9yCiAgICAgICAqIG9yZ2FuaXphdGlvbiBJRC4KICAgICAgICovCiAgICAgIHB1YmxpYyBMaXN0IHNldFBhcmVudChqYXZhLmxhbmcuU3RyaW5nIHBhcmVudCkgewogICAgICAgIHRoaXMucGFyZW50ID0gcGFyZW50OwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIExpc3Qgc2V0KFN0cmluZyBwYXJhbWV0ZXJOYW1lLCBPYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gKExpc3QpIHN1cGVyLnNldChwYXJhbWV0ZXJOYW1lLCB2YWx1ZSk7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogUXVlcmllcyByb2xlcyB0aGF0IGNhbiBiZSBncmFudGVkIG9uIGEgcGFydGljdWxhciByZXNvdXJjZS4gQSByb2xlIGlzIGdyYW50YWJsZSBpZiBpdCBjYW4gYmUgdXNlZAogICAgICogYXMgdGhlIHJvbGUgaW4gYSBiaW5kaW5nIGZvciBhIHBvbGljeSBmb3IgdGhhdCByZXNvdXJjZS4KICAgICAqCiAgICAgKiBDcmVhdGUgYSByZXF1ZXN0IGZvciB0aGUgbWV0aG9kICJyb2xlcy5xdWVyeUdyYW50YWJsZVJvbGVzIi4KICAgICAqCiAgICAgKiBUaGlzIHJlcXVlc3QgaG9sZHMgdGhlIHBhcmFtZXRlcnMgbmVlZGVkIGJ5IHRoZSBpYW0gc2VydmVyLiAgQWZ0ZXIgc2V0dGluZyBhbnkgb3B0aW9uYWwKICAgICAqIHBhcmFtZXRlcnMsIGNhbGwgdGhlIHtAbGluayBRdWVyeUdyYW50YWJsZVJvbGVzI2V4ZWN1dGUoKX0gbWV0aG9kIHRvIGludm9rZSB0aGUgcmVtb3RlIG9wZXJhdGlvbi4KICAgICAqCiAgICAgKiBAcGFyYW0gY29udGVudCB0aGUge0BsaW5rIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmlhbS52MS5tb2RlbC5RdWVyeUdyYW50YWJsZVJvbGVzUmVxdWVzdH0KICAgICAqIEByZXR1cm4gdGhlIHJlcXVlc3QKICAgICAqLwogICAgcHVibGljIFF1ZXJ5R3JhbnRhYmxlUm9sZXMgcXVlcnlHcmFudGFibGVSb2xlcyhjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5pYW0udjEubW9kZWwuUXVlcnlHcmFudGFibGVSb2xlc1JlcXVlc3QgY29udGVudCkgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBRdWVyeUdyYW50YWJsZVJvbGVzIHJlc3VsdCA9IG5ldyBRdWVyeUdyYW50YWJsZVJvbGVzKGNvbnRlbnQpOwogICAgICBpbml0aWFsaXplKHJlc3VsdCk7CiAgICAgIHJldHVybiByZXN1bHQ7CiAgICB9CgogICAgcHVibGljIGNsYXNzIFF1ZXJ5R3JhbnRhYmxlUm9sZXMgZXh0ZW5kcyBJYW1SZXF1ZXN0PGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmlhbS52MS5tb2RlbC5RdWVyeUdyYW50YWJsZVJvbGVzUmVzcG9uc2U+IHsKCiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBSRVNUX1BBVEggPSAidjEvcm9sZXM6cXVlcnlHcmFudGFibGVSb2xlcyI7CgogICAgICAvKioKICAgICAgICogUXVlcmllcyByb2xlcyB0aGF0IGNhbiBiZSBncmFudGVkIG9uIGEgcGFydGljdWxhciByZXNvdXJjZS4gQSByb2xlIGlzIGdyYW50YWJsZSBpZiBpdCBjYW4gYmUKICAgICAgICogdXNlZCBhcyB0aGUgcm9sZSBpbiBhIGJpbmRpbmcgZm9yIGEgcG9saWN5IGZvciB0aGF0IHJlc291cmNlLgogICAgICAgKgogICAgICAgKiBDcmVhdGUgYSByZXF1ZXN0IGZvciB0aGUgbWV0aG9kICJyb2xlcy5xdWVyeUdyYW50YWJsZVJvbGVzIi4KICAgICAgICoKICAgICAgICogVGhpcyByZXF1ZXN0IGhvbGRzIHRoZSBwYXJhbWV0ZXJzIG5lZWRlZCBieSB0aGUgdGhlIGlhbSBzZXJ2ZXIuICBBZnRlciBzZXR0aW5nIGFueSBvcHRpb25hbAogICAgICAgKiBwYXJhbWV0ZXJzLCBjYWxsIHRoZSB7QGxpbmsgUXVlcnlHcmFudGFibGVSb2xlcyNleGVjdXRlKCl9IG1ldGhvZCB0byBpbnZva2UgdGhlIHJlbW90ZQogICAgICAgKiBvcGVyYXRpb24uIDxwPiB7QGxpbmsgUXVlcnlHcmFudGFibGVSb2xlcyNpbml0aWFsaXplKGNvbS5nb29nbGUuYXBpLmNsaWVudC5nb29nbGVhcGlzLnNlcnZpY2VzLgogICAgICAgKiBBYnN0cmFjdEdvb2dsZUNsaWVudFJlcXVlc3QpfSBtdXN0IGJlIGNhbGxlZCB0byBpbml0aWFsaXplIHRoaXMgaW5zdGFuY2UgaW1tZWRpYXRlbHkgYWZ0ZXIKICAgICAgICogaW52b2tpbmcgdGhlIGNvbnN0cnVjdG9yLiA8L3A+CiAgICAgICAqCiAgICAgICAqIEBwYXJhbSBjb250ZW50IHRoZSB7QGxpbmsgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuaWFtLnYxLm1vZGVsLlF1ZXJ5R3JhbnRhYmxlUm9sZXNSZXF1ZXN0fQogICAgICAgKiBAc2luY2UgMS4xMwogICAgICAgKi8KICAgICAgcHJvdGVjdGVkIFF1ZXJ5R3JhbnRhYmxlUm9sZXMoY29tLmdvb2dsZS5hcGkuc2VydmljZXMuaWFtLnYxLm1vZGVsLlF1ZXJ5R3JhbnRhYmxlUm9sZXNSZXF1ZXN0IGNvbnRlbnQpIHsKICAgICAgICBzdXBlcihJYW0udGhpcywgIlBPU1QiLCBSRVNUX1BBVEgsIGNvbnRlbnQsIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmlhbS52MS5tb2RlbC5RdWVyeUdyYW50YWJsZVJvbGVzUmVzcG9uc2UuY2xhc3MpOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIFF1ZXJ5R3JhbnRhYmxlUm9sZXMgc2V0JFhnYWZ2KGphdmEubGFuZy5TdHJpbmcgJFhnYWZ2KSB7CiAgICAgICAgcmV0dXJuIChRdWVyeUdyYW50YWJsZVJvbGVzKSBzdXBlci5zZXQkWGdhZnYoJFhnYWZ2KTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBRdWVyeUdyYW50YWJsZVJvbGVzIHNldEFjY2Vzc1Rva2VuKGphdmEubGFuZy5TdHJpbmcgYWNjZXNzVG9rZW4pIHsKICAgICAgICByZXR1cm4gKFF1ZXJ5R3JhbnRhYmxlUm9sZXMpIHN1cGVyLnNldEFjY2Vzc1Rva2VuKGFjY2Vzc1Rva2VuKTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBRdWVyeUdyYW50YWJsZVJvbGVzIHNldEFsdChqYXZhLmxhbmcuU3RyaW5nIGFsdCkgewogICAgICAgIHJldHVybiAoUXVlcnlHcmFudGFibGVSb2xlcykgc3VwZXIuc2V0QWx0KGFsdCk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgUXVlcnlHcmFudGFibGVSb2xlcyBzZXRDYWxsYmFjayhqYXZhLmxhbmcuU3RyaW5nIGNhbGxiYWNrKSB7CiAgICAgICAgcmV0dXJuIChRdWVyeUdyYW50YWJsZVJvbGVzKSBzdXBlci5zZXRDYWxsYmFjayhjYWxsYmFjayk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgUXVlcnlHcmFudGFibGVSb2xlcyBzZXRGaWVsZHMoamF2YS5sYW5nLlN0cmluZyBmaWVsZHMpIHsKICAgICAgICByZXR1cm4gKFF1ZXJ5R3JhbnRhYmxlUm9sZXMpIHN1cGVyLnNldEZpZWxkcyhmaWVsZHMpOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIFF1ZXJ5R3JhbnRhYmxlUm9sZXMgc2V0S2V5KGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgcmV0dXJuIChRdWVyeUdyYW50YWJsZVJvbGVzKSBzdXBlci5zZXRLZXkoa2V5KTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBRdWVyeUdyYW50YWJsZVJvbGVzIHNldE9hdXRoVG9rZW4oamF2YS5sYW5nLlN0cmluZyBvYXV0aFRva2VuKSB7CiAgICAgICAgcmV0dXJuIChRdWVyeUdyYW50YWJsZVJvbGVzKSBzdXBlci5zZXRPYXV0aFRva2VuKG9hdXRoVG9rZW4pOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIFF1ZXJ5R3JhbnRhYmxlUm9sZXMgc2V0UHJldHR5UHJpbnQoamF2YS5sYW5nLkJvb2xlYW4gcHJldHR5UHJpbnQpIHsKICAgICAgICByZXR1cm4gKFF1ZXJ5R3JhbnRhYmxlUm9sZXMpIHN1cGVyLnNldFByZXR0eVByaW50KHByZXR0eVByaW50KTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBRdWVyeUdyYW50YWJsZVJvbGVzIHNldFF1b3RhVXNlcihqYXZhLmxhbmcuU3RyaW5nIHF1b3RhVXNlcikgewogICAgICAgIHJldHVybiAoUXVlcnlHcmFudGFibGVSb2xlcykgc3VwZXIuc2V0UXVvdGFVc2VyKHF1b3RhVXNlcik7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgUXVlcnlHcmFudGFibGVSb2xlcyBzZXRVcGxvYWRUeXBlKGphdmEubGFuZy5TdHJpbmcgdXBsb2FkVHlwZSkgewogICAgICAgIHJldHVybiAoUXVlcnlHcmFudGFibGVSb2xlcykgc3VwZXIuc2V0VXBsb2FkVHlwZSh1cGxvYWRUeXBlKTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBRdWVyeUdyYW50YWJsZVJvbGVzIHNldFVwbG9hZFByb3RvY29sKGphdmEubGFuZy5TdHJpbmcgdXBsb2FkUHJvdG9jb2wpIHsKICAgICAgICByZXR1cm4gKFF1ZXJ5R3JhbnRhYmxlUm9sZXMpIHN1cGVyLnNldFVwbG9hZFByb3RvY29sKHVwbG9hZFByb3RvY29sKTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBRdWVyeUdyYW50YWJsZVJvbGVzIHNldChTdHJpbmcgcGFyYW1ldGVyTmFtZSwgT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIChRdWVyeUdyYW50YWJsZVJvbGVzKSBzdXBlci5zZXQocGFyYW1ldGVyTmFtZSwgdmFsdWUpOwogICAgICB9CiAgICB9CgogIH0KCiAgLyoqCiAgICogQnVpbGRlciBmb3Ige0BsaW5rIElhbX0uCiAgICoKICAgKiA8cD4KICAgKiBJbXBsZW1lbnRhdGlvbiBpcyBub3QgdGhyZWFkLXNhZmUuCiAgICogPC9wPgogICAqCiAgICogQHNpbmNlIDEuMy4wCiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBjbGFzcyBCdWlsZGVyIGV4dGVuZHMgY29tLmdvb2dsZS5hcGkuY2xpZW50Lmdvb2dsZWFwaXMuc2VydmljZXMuanNvbi5BYnN0cmFjdEdvb2dsZUpzb25DbGllbnQuQnVpbGRlciB7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGFuIGluc3RhbmNlIG9mIGEgbmV3IGJ1aWxkZXIuCiAgICAgKgogICAgICogQHBhcmFtIHRyYW5zcG9ydCBIVFRQIHRyYW5zcG9ydCwgd2hpY2ggc2hvdWxkIG5vcm1hbGx5IGJlOgogICAgICogICAgICAgIDx1bD4KICAgICAqICAgICAgICA8bGk+R29vZ2xlIEFwcCBFbmdpbmU6CiAgICAgKiAgICAgICAge0Bjb2RlIGNvbS5nb29nbGUuYXBpLmNsaWVudC5leHRlbnNpb25zLmFwcGVuZ2luZS5odHRwLlVybEZldGNoVHJhbnNwb3J0fTwvbGk+CiAgICAgKiAgICAgICAgPGxpPkFuZHJvaWQ6IHtAY29kZSBuZXdDb21wYXRpYmxlVHJhbnNwb3J0fSBmcm9tCiAgICAgKiAgICAgICAge0Bjb2RlIGNvbS5nb29nbGUuYXBpLmNsaWVudC5leHRlbnNpb25zLmFuZHJvaWQuaHR0cC5BbmRyb2lkSHR0cH08L2xpPgogICAgICogICAgICAgIDxsaT5KYXZhOiB7QGxpbmsgY29tLmdvb2dsZS5hcGkuY2xpZW50Lmdvb2dsZWFwaXMuamF2YW5ldC5Hb29nbGVOZXRIdHRwVHJhbnNwb3J0I25ld1RydXN0ZWRUcmFuc3BvcnQoKX0KICAgICAqICAgICAgICA8L2xpPgogICAgICogICAgICAgIDwvdWw+CiAgICAgKiBAcGFyYW0ganNvbkZhY3RvcnkgSlNPTiBmYWN0b3J5LCB3aGljaCBtYXkgYmU6CiAgICAgKiAgICAgICAgPHVsPgogICAgICogICAgICAgIDxsaT5KYWNrc29uOiB7QGNvZGUgY29tLmdvb2dsZS5hcGkuY2xpZW50Lmpzb24uamFja3NvbjIuSmFja3NvbkZhY3Rvcnl9PC9saT4KICAgICAqICAgICAgICA8bGk+R29vZ2xlIEdTT046IHtAY29kZSBjb20uZ29vZ2xlLmFwaS5jbGllbnQuanNvbi5nc29uLkdzb25GYWN0b3J5fTwvbGk+CiAgICAgKiAgICAgICAgPGxpPkFuZHJvaWQgSG9uZXljb21iIG9yIGhpZ2hlcjoKICAgICAqICAgICAgICB7QGNvZGUgY29tLmdvb2dsZS5hcGkuY2xpZW50LmV4dGVuc2lvbnMuYW5kcm9pZC5qc29uLkFuZHJvaWRKc29uRmFjdG9yeX08L2xpPgogICAgICogICAgICAgIDwvdWw+CiAgICAgKiBAcGFyYW0gaHR0cFJlcXVlc3RJbml0aWFsaXplciBIVFRQIHJlcXVlc3QgaW5pdGlhbGl6ZXIgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICAgKiBAc2luY2UgMS43CiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyKGNvbS5nb29nbGUuYXBpLmNsaWVudC5odHRwLkh0dHBUcmFuc3BvcnQgdHJhbnNwb3J0LCBjb20uZ29vZ2xlLmFwaS5jbGllbnQuanNvbi5Kc29uRmFjdG9yeSBqc29uRmFjdG9yeSwKICAgICAgICBjb20uZ29vZ2xlLmFwaS5jbGllbnQuaHR0cC5IdHRwUmVxdWVzdEluaXRpYWxpemVyIGh0dHBSZXF1ZXN0SW5pdGlhbGl6ZXIpIHsKICAgICAgc3VwZXIoCiAgICAgICAgICB0cmFuc3BvcnQsCiAgICAgICAgICBqc29uRmFjdG9yeSwKICAgICAgICAgIERFRkFVTFRfUk9PVF9VUkwsCiAgICAgICAgICBERUZBVUxUX1NFUlZJQ0VfUEFUSCwKICAgICAgICAgIGh0dHBSZXF1ZXN0SW5pdGlhbGl6ZXIsCiAgICAgICAgICBmYWxzZSk7CiAgICAgIHNldEJhdGNoUGF0aChERUZBVUxUX0JBVENIX1BBVEgpOwogICAgfQoKICAgIC8qKiBCdWlsZHMgYSBuZXcgaW5zdGFuY2Ugb2Yge0BsaW5rIElhbX0uICovCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBJYW0gYnVpbGQoKSB7CiAgICAgIHJldHVybiBuZXcgSWFtKHRoaXMpOwogICAgfQoKICAgIEBPdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgc2V0Um9vdFVybChTdHJpbmcgcm9vdFVybCkgewogICAgICByZXR1cm4gKEJ1aWxkZXIpIHN1cGVyLnNldFJvb3RVcmwocm9vdFVybCk7CiAgICB9CgogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBzZXRTZXJ2aWNlUGF0aChTdHJpbmcgc2VydmljZVBhdGgpIHsKICAgICAgcmV0dXJuIChCdWlsZGVyKSBzdXBlci5zZXRTZXJ2aWNlUGF0aChzZXJ2aWNlUGF0aCk7CiAgICB9CgogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBzZXRCYXRjaFBhdGgoU3RyaW5nIGJhdGNoUGF0aCkgewogICAgICByZXR1cm4gKEJ1aWxkZXIpIHN1cGVyLnNldEJhdGNoUGF0aChiYXRjaFBhdGgpOwogICAgfQoKICAgIEBPdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgc2V0SHR0cFJlcXVlc3RJbml0aWFsaXplcihjb20uZ29vZ2xlLmFwaS5jbGllbnQuaHR0cC5IdHRwUmVxdWVzdEluaXRpYWxpemVyIGh0dHBSZXF1ZXN0SW5pdGlhbGl6ZXIpIHsKICAgICAgcmV0dXJuIChCdWlsZGVyKSBzdXBlci5zZXRIdHRwUmVxdWVzdEluaXRpYWxpemVyKGh0dHBSZXF1ZXN0SW5pdGlhbGl6ZXIpOwogICAgfQoKICAgIEBPdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgc2V0QXBwbGljYXRpb25OYW1lKFN0cmluZyBhcHBsaWNhdGlvbk5hbWUpIHsKICAgICAgcmV0dXJuIChCdWlsZGVyKSBzdXBlci5zZXRBcHBsaWNhdGlvbk5hbWUoYXBwbGljYXRpb25OYW1lKTsKICAgIH0KCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHNldFN1cHByZXNzUGF0dGVybkNoZWNrcyhib29sZWFuIHN1cHByZXNzUGF0dGVybkNoZWNrcykgewogICAgICByZXR1cm4gKEJ1aWxkZXIpIHN1cGVyLnNldFN1cHByZXNzUGF0dGVybkNoZWNrcyhzdXBwcmVzc1BhdHRlcm5DaGVja3MpOwogICAgfQoKICAgIEBPdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgc2V0U3VwcHJlc3NSZXF1aXJlZFBhcmFtZXRlckNoZWNrcyhib29sZWFuIHN1cHByZXNzUmVxdWlyZWRQYXJhbWV0ZXJDaGVja3MpIHsKICAgICAgcmV0dXJuIChCdWlsZGVyKSBzdXBlci5zZXRTdXBwcmVzc1JlcXVpcmVkUGFyYW1ldGVyQ2hlY2tzKHN1cHByZXNzUmVxdWlyZWRQYXJhbWV0ZXJDaGVja3MpOwogICAgfQoKICAgIEBPdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgc2V0U3VwcHJlc3NBbGxDaGVja3MoYm9vbGVhbiBzdXBwcmVzc0FsbENoZWNrcykgewogICAgICByZXR1cm4gKEJ1aWxkZXIpIHN1cGVyLnNldFN1cHByZXNzQWxsQ2hlY2tzKHN1cHByZXNzQWxsQ2hlY2tzKTsKICAgIH0KCiAgICAvKioKICAgICAqIFNldCB0aGUge0BsaW5rIElhbVJlcXVlc3RJbml0aWFsaXplcn0uCiAgICAgKgogICAgICogQHNpbmNlIDEuMTIKICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIgc2V0SWFtUmVxdWVzdEluaXRpYWxpemVyKAogICAgICAgIElhbVJlcXVlc3RJbml0aWFsaXplciBpYW1SZXF1ZXN0SW5pdGlhbGl6ZXIpIHsKICAgICAgcmV0dXJuIChCdWlsZGVyKSBzdXBlci5zZXRHb29nbGVDbGllbnRSZXF1ZXN0SW5pdGlhbGl6ZXIoaWFtUmVxdWVzdEluaXRpYWxpemVyKTsKICAgIH0KCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHNldEdvb2dsZUNsaWVudFJlcXVlc3RJbml0aWFsaXplcigKICAgICAgICBjb20uZ29vZ2xlLmFwaS5jbGllbnQuZ29vZ2xlYXBpcy5zZXJ2aWNlcy5Hb29nbGVDbGllbnRSZXF1ZXN0SW5pdGlhbGl6ZXIgZ29vZ2xlQ2xpZW50UmVxdWVzdEluaXRpYWxpemVyKSB7CiAgICAgIHJldHVybiAoQnVpbGRlcikgc3VwZXIuc2V0R29vZ2xlQ2xpZW50UmVxdWVzdEluaXRpYWxpemVyKGdvb2dsZUNsaWVudFJlcXVlc3RJbml0aWFsaXplcik7CiAgICB9CiAgfQp9ClBLAwQUAAAAAAAAACEAAAAAAAAAAAAAAAAAJQAAAGNvbS9nb29nbGUvYXBpL3NlcnZpY2VzL2lhbS92MS9tb2RlbC9QSwMEFAAAAAAAAAAhAKqhnC6cCQAAnAkAADgAAABjb20vZ29vZ2xlL2FwaS9zZXJ2aWNlcy9pYW0vdjEvbW9kZWwvQWRtaW5BdWRpdERhdGEuamF2YS8qCiAqIENvcHlyaWdodCAyMDEwIEdvb2dsZSBJbmMuCiAqCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdAogKiBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZQogKiBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3MKICogb3IgaW1wbGllZC4gU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucyB1bmRlcgogKiB0aGUgTGljZW5zZS4KICovCi8qCiAqIFRoaXMgY29kZSB3YXMgZ2VuZXJhdGVkIGJ5IGh0dHBzOi8vZ2l0aHViLmNvbS9nb29nbGUvYXBpcy1jbGllbnQtZ2VuZXJhdG9yLwogKiAoYnVpbGQ6IDIwMTgtMTAtMDggMTc6NDU6MzkgVVRDKQogKiBvbiAyMDIwLTAzLTE5IGF0IDAxOjUyOjQxIFVUQyAKICogTW9kaWZ5IGF0IHlvdXIgb3duIHJpc2suCiAqLwoKcGFja2FnZSBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5pYW0udjEubW9kZWw7CgovKioKICogQXVkaXQgbG9nIGluZm9ybWF0aW9uIHNwZWNpZmljIHRvIENsb3VkIElBTSBhZG1pbiBBUElzLiBUaGlzIG1lc3NhZ2UgaXMgc2VyaWFsaXplZCBhcyBhbiBgQW55YAogKiB0eXBlIGluIHRoZSBgU2VydmljZURhdGFgIG1lc3NhZ2Ugb2YgYW4gYEF1ZGl0TG9nYCBtZXNzYWdlLgogKgogKiA8cD4gVGhpcyBpcyB0aGUgSmF2YSBkYXRhIG1vZGVsIGNsYXNzIHRoYXQgc3BlY2lmaWVzIGhvdyB0byBwYXJzZS9zZXJpYWxpemUgaW50byB0aGUgSlNPTiB0aGF0IGlzCiAqIHRyYW5zbWl0dGVkIG92ZXIgSFRUUCB3aGVuIHdvcmtpbmcgd2l0aCB0aGUgSWRlbnRpdHkgYW5kIEFjY2VzcyBNYW5hZ2VtZW50IChJQU0pIEFQSS4gRm9yIGEKICogZGV0YWlsZWQgZXhwbGFuYXRpb24gc2VlOgogKiA8YSBocmVmPSJodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9hcGktY2xpZW50LWxpYnJhcnkvamF2YS9nb29nbGUtaHR0cC1qYXZhLWNsaWVudC9qc29uIj5odHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9hcGktY2xpZW50LWxpYnJhcnkvamF2YS9nb29nbGUtaHR0cC1qYXZhLWNsaWVudC9qc29uPC9hPgogKiA8L3A+CiAqCiAqIEBhdXRob3IgR29vZ2xlLCBJbmMuCiAqLwpAU3VwcHJlc3NXYXJuaW5ncygiamF2YWRvYyIpCnB1YmxpYyBmaW5hbCBjbGFzcyBBZG1pbkF1ZGl0RGF0YSBleHRlbmRzIGNvbS5nb29nbGUuYXBpLmNsaWVudC5qc29uLkdlbmVyaWNKc29uIHsKCiAgLyoqCiAgICogVGhlIHBlcm1pc3Npb25fZGVsdGEgd2hlbiB3aGVuIGNyZWF0aW5nIG9yIHVwZGF0aW5nIGEgUm9sZS4KICAgKiBUaGUgdmFsdWUgbWF5IGJlIHtAY29kZSBudWxsfS4KICAgKi8KICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgcHJpdmF0ZSBQZXJtaXNzaW9uRGVsdGEgcGVybWlzc2lvbkRlbHRhOwoKICAvKioKICAgKiBUaGUgcGVybWlzc2lvbl9kZWx0YSB3aGVuIHdoZW4gY3JlYXRpbmcgb3IgdXBkYXRpbmcgYSBSb2xlLgogICAqIEByZXR1cm4gdmFsdWUgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIFBlcm1pc3Npb25EZWx0YSBnZXRQZXJtaXNzaW9uRGVsdGEoKSB7CiAgICByZXR1cm4gcGVybWlzc2lvbkRlbHRhOwogIH0KCiAgLyoqCiAgICogVGhlIHBlcm1pc3Npb25fZGVsdGEgd2hlbiB3aGVuIGNyZWF0aW5nIG9yIHVwZGF0aW5nIGEgUm9sZS4KICAgKiBAcGFyYW0gcGVybWlzc2lvbkRlbHRhIHBlcm1pc3Npb25EZWx0YSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgQWRtaW5BdWRpdERhdGEgc2V0UGVybWlzc2lvbkRlbHRhKFBlcm1pc3Npb25EZWx0YSBwZXJtaXNzaW9uRGVsdGEpIHsKICAgIHRoaXMucGVybWlzc2lvbkRlbHRhID0gcGVybWlzc2lvbkRlbHRhOwogICAgcmV0dXJuIHRoaXM7CiAgfQoKICBAT3ZlcnJpZGUKICBwdWJsaWMgQWRtaW5BdWRpdERhdGEgc2V0KFN0cmluZyBmaWVsZE5hbWUsIE9iamVjdCB2YWx1ZSkgewogICAgcmV0dXJuIChBZG1pbkF1ZGl0RGF0YSkgc3VwZXIuc2V0KGZpZWxkTmFtZSwgdmFsdWUpOwogIH0KCiAgQE92ZXJyaWRlCiAgcHVibGljIEFkbWluQXVkaXREYXRhIGNsb25lKCkgewogICAgcmV0dXJuIChBZG1pbkF1ZGl0RGF0YSkgc3VwZXIuY2xvbmUoKTsKICB9Cgp9ClBLAwQUAAAAAAAAACEAopr0ctkTAADZEwAANQAAAGNvbS9nb29nbGUvYXBpL3NlcnZpY2VzL2lhbS92MS9tb2RlbC9BdWRpdENvbmZpZy5qYXZhLyoKICogQ29weXJpZ2h0IDIwMTAgR29vZ2xlIEluYy4KICoKICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0CiAqIGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4gWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlCiAqIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcwogKiBvciBpbXBsaWVkLiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zIHVuZGVyCiAqIHRoZSBMaWNlbnNlLgogKi8KLyoKICogVGhpcyBjb2RlIHdhcyBnZW5lcmF0ZWQgYnkgaHR0cHM6Ly9naXRodWIuY29tL2dvb2dsZS9hcGlzLWNsaWVudC1nZW5lcmF0b3IvCiAqIChidWlsZDogMjAxOC0xMC0wOCAxNzo0NTozOSBVVEMpCiAqIG9uIDIwMjAtMDMtMTkgYXQgMDE6NTI6NDEgVVRDIAogKiBNb2RpZnkgYXQgeW91ciBvd24gcmlzay4KICovCgpwYWNrYWdlIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmlhbS52MS5tb2RlbDsKCi8qKgogKiBTcGVjaWZpZXMgdGhlIGF1ZGl0IGNvbmZpZ3VyYXRpb24gZm9yIGEgc2VydmljZS4gVGhlIGNvbmZpZ3VyYXRpb24gZGV0ZXJtaW5lcyB3aGljaCBwZXJtaXNzaW9uCiAqIHR5cGVzIGFyZSBsb2dnZWQsIGFuZCB3aGF0IGlkZW50aXRpZXMsIGlmIGFueSwgYXJlIGV4ZW1wdGVkIGZyb20gbG9nZ2luZy4gQW4gQXVkaXRDb25maWcgbXVzdAogKiBoYXZlIG9uZSBvciBtb3JlIEF1ZGl0TG9nQ29uZmlncy4KICoKICogSWYgdGhlcmUgYXJlIEF1ZGl0Q29uZmlncyBmb3IgYm90aCBgYWxsU2VydmljZXNgIGFuZCBhIHNwZWNpZmljIHNlcnZpY2UsIHRoZSB1bmlvbiBvZiB0aGUgdHdvCiAqIEF1ZGl0Q29uZmlncyBpcyB1c2VkIGZvciB0aGF0IHNlcnZpY2U6IHRoZSBsb2dfdHlwZXMgc3BlY2lmaWVkIGluIGVhY2ggQXVkaXRDb25maWcgYXJlIGVuYWJsZWQsCiAqIGFuZCB0aGUgZXhlbXB0ZWRfbWVtYmVycyBpbiBlYWNoIEF1ZGl0TG9nQ29uZmlnIGFyZSBleGVtcHRlZC4KICoKICogRXhhbXBsZSBQb2xpY3kgd2l0aCBtdWx0aXBsZSBBdWRpdENvbmZpZ3M6CiAqCiAqICAgICB7ICAgICAgICJhdWRpdF9jb25maWdzIjogWyAgICAgICAgIHsgICAgICAgICAgICJzZXJ2aWNlIjogImFsbFNlcnZpY2VzIgogKiAiYXVkaXRfbG9nX2NvbmZpZ3MiOiBbICAgICAgICAgICAgIHsgICAgICAgICAgICAgICAibG9nX3R5cGUiOiAiREFUQV9SRUFEIiwKICogImV4ZW1wdGVkX21lbWJlcnMiOiBbICAgICAgICAgICAgICAgICAidXNlcjpqb3NlQGV4YW1wbGUuY29tIiAgICAgICAgICAgICAgIF0gICAgICAgICAgICAgfSwKICogeyAgICAgICAgICAgICAgICJsb2dfdHlwZSI6ICJEQVRBX1dSSVRFIiwgICAgICAgICAgICAgfSwgICAgICAgICAgICAgeyAgICAgICAgICAgICAgICJsb2dfdHlwZSI6CiAqICJBRE1JTl9SRUFEIiwgICAgICAgICAgICAgfSAgICAgICAgICAgXSAgICAgICAgIH0sICAgICAgICAgeyAgICAgICAgICAgInNlcnZpY2UiOgogKiAic2FtcGxlc2VydmljZS5nb29nbGVhcGlzLmNvbSIgICAgICAgICAgICJhdWRpdF9sb2dfY29uZmlncyI6IFsgICAgICAgICAgICAgewogKiAibG9nX3R5cGUiOiAiREFUQV9SRUFEIiwgICAgICAgICAgICAgfSwgICAgICAgICAgICAgeyAgICAgICAgICAgICAgICJsb2dfdHlwZSI6ICJEQVRBX1dSSVRFIiwKICogImV4ZW1wdGVkX21lbWJlcnMiOiBbICAgICAgICAgICAgICAgICAidXNlcjphbGl5YUBleGFtcGxlLmNvbSIgICAgICAgICAgICAgICBdICAgICAgICAgICAgIH0KICogXSAgICAgICAgIH0gICAgICAgXSAgICAgfQogKgogKiBGb3Igc2FtcGxlc2VydmljZSwgdGhpcyBwb2xpY3kgZW5hYmxlcyBEQVRBX1JFQUQsIERBVEFfV1JJVEUgYW5kIEFETUlOX1JFQUQgbG9nZ2luZy4gSXQgYWxzbwogKiBleGVtcHRzIGpvc2VAZXhhbXBsZS5jb20gZnJvbSBEQVRBX1JFQUQgbG9nZ2luZywgYW5kIGFsaXlhQGV4YW1wbGUuY29tIGZyb20gREFUQV9XUklURSBsb2dnaW5nLgogKgogKiA8cD4gVGhpcyBpcyB0aGUgSmF2YSBkYXRhIG1vZGVsIGNsYXNzIHRoYXQgc3BlY2lmaWVzIGhvdyB0byBwYXJzZS9zZXJpYWxpemUgaW50byB0aGUgSlNPTiB0aGF0IGlzCiAqIHRyYW5zbWl0dGVkIG92ZXIgSFRUUCB3aGVuIHdvcmtpbmcgd2l0aCB0aGUgSWRlbnRpdHkgYW5kIEFjY2VzcyBNYW5hZ2VtZW50IChJQU0pIEFQSS4gRm9yIGEKICogZGV0YWlsZWQgZXhwbGFuYXRpb24gc2VlOgogKiA8YSBocmVmPSJodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9hcGktY2xpZW50LWxpYnJhcnkvamF2YS9nb29nbGUtaHR0cC1qYXZhLWNsaWVudC9qc29uIj5odHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9hcGktY2xpZW50LWxpYnJhcnkvamF2YS9nb29nbGUtaHR0cC1qYXZhLWNsaWVudC9qc29uPC9hPgogKiA8L3A+CiAqCiAqIEBhdXRob3IgR29vZ2xlLCBJbmMuCiAqLwpAU3VwcHJlc3NXYXJuaW5ncygiamF2YWRvYyIpCnB1YmxpYyBmaW5hbCBjbGFzcyBBdWRpdENvbmZpZyBleHRlbmRzIGNvbS5nb29nbGUuYXBpLmNsaWVudC5qc29uLkdlbmVyaWNKc29uIHsKCiAgLyoqCiAgICogVGhlIGNvbmZpZ3VyYXRpb24gZm9yIGxvZ2dpbmcgb2YgZWFjaCB0eXBlIG9mIHBlcm1pc3Npb24uCiAgICogVGhlIHZhbHVlIG1heSBiZSB7QGNvZGUgbnVsbH0uCiAgICovCiAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8QXVkaXRMb2dDb25maWc+IGF1ZGl0TG9nQ29uZmlnczsKCiAgc3RhdGljIHsKICAgIC8vIGhhY2sgdG8gZm9yY2UgUHJvR3VhcmQgdG8gY29uc2lkZXIgQXVkaXRMb2dDb25maWcgdXNlZCwgc2luY2Ugb3RoZXJ3aXNlIGl0IHdvdWxkIGJlIHN0cmlwcGVkIG91dAogICAgLy8gc2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9nb29nbGUvZ29vZ2xlLWFwaS1qYXZhLWNsaWVudC9pc3N1ZXMvNTQzCiAgICBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5EYXRhLm51bGxPZihBdWRpdExvZ0NvbmZpZy5jbGFzcyk7CiAgfQoKICAvKioKICAgKiBTcGVjaWZpZXMgYSBzZXJ2aWNlIHRoYXQgd2lsbCBiZSBlbmFibGVkIGZvciBhdWRpdCBsb2dnaW5nLiBGb3IgZXhhbXBsZSwKICAgKiBgc3RvcmFnZS5nb29nbGVhcGlzLmNvbWAsIGBjbG91ZHNxbC5nb29nbGVhcGlzLmNvbWAuIGBhbGxTZXJ2aWNlc2AgaXMgYSBzcGVjaWFsIHZhbHVlIHRoYXQKICAgKiBjb3ZlcnMgYWxsIHNlcnZpY2VzLgogICAqIFRoZSB2YWx1ZSBtYXkgYmUge0Bjb2RlIG51bGx9LgogICAqLwogIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICBwcml2YXRlIGphdmEubGFuZy5TdHJpbmcgc2VydmljZTsKCiAgLyoqCiAgICogVGhlIGNvbmZpZ3VyYXRpb24gZm9yIGxvZ2dpbmcgb2YgZWFjaCB0eXBlIG9mIHBlcm1pc3Npb24uCiAgICogQHJldHVybiB2YWx1ZSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8QXVkaXRMb2dDb25maWc+IGdldEF1ZGl0TG9nQ29uZmlncygpIHsKICAgIHJldHVybiBhdWRpdExvZ0NvbmZpZ3M7CiAgfQoKICAvKioKICAgKiBUaGUgY29uZmlndXJhdGlvbiBmb3IgbG9nZ2luZyBvZiBlYWNoIHR5cGUgb2YgcGVybWlzc2lvbi4KICAgKiBAcGFyYW0gYXVkaXRMb2dDb25maWdzIGF1ZGl0TG9nQ29uZmlncyBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgQXVkaXRDb25maWcgc2V0QXVkaXRMb2dDb25maWdzKGphdmEudXRpbC5MaXN0PEF1ZGl0TG9nQ29uZmlnPiBhdWRpdExvZ0NvbmZpZ3MpIHsKICAgIHRoaXMuYXVkaXRMb2dDb25maWdzID0gYXVkaXRMb2dDb25maWdzOwogICAgcmV0dXJuIHRoaXM7CiAgfQoKICAvKioKICAgKiBTcGVjaWZpZXMgYSBzZXJ2aWNlIHRoYXQgd2lsbCBiZSBlbmFibGVkIGZvciBhdWRpdCBsb2dnaW5nLiBGb3IgZXhhbXBsZSwKICAgKiBgc3RvcmFnZS5nb29nbGVhcGlzLmNvbWAsIGBjbG91ZHNxbC5nb29nbGVhcGlzLmNvbWAuIGBhbGxTZXJ2aWNlc2AgaXMgYSBzcGVjaWFsIHZhbHVlIHRoYXQKICAgKiBjb3ZlcnMgYWxsIHNlcnZpY2VzLgogICAqIEByZXR1cm4gdmFsdWUgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0U2VydmljZSgpIHsKICAgIHJldHVybiBzZXJ2aWNlOwogIH0KCiAgLyoqCiAgICogU3BlY2lmaWVzIGEgc2VydmljZSB0aGF0IHdpbGwgYmUgZW5hYmxlZCBmb3IgYXVkaXQgbG9nZ2luZy4gRm9yIGV4YW1wbGUsCiAgICogYHN0b3JhZ2UuZ29vZ2xlYXBpcy5jb21gLCBgY2xvdWRzcWwuZ29vZ2xlYXBpcy5jb21gLiBgYWxsU2VydmljZXNgIGlzIGEgc3BlY2lhbCB2YWx1ZSB0aGF0CiAgICogY292ZXJzIGFsbCBzZXJ2aWNlcy4KICAgKiBAcGFyYW0gc2VydmljZSBzZXJ2aWNlIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBBdWRpdENvbmZpZyBzZXRTZXJ2aWNlKGphdmEubGFuZy5TdHJpbmcgc2VydmljZSkgewogICAgdGhpcy5zZXJ2aWNlID0gc2VydmljZTsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgQE92ZXJyaWRlCiAgcHVibGljIEF1ZGl0Q29uZmlnIHNldChTdHJpbmcgZmllbGROYW1lLCBPYmplY3QgdmFsdWUpIHsKICAgIHJldHVybiAoQXVkaXRDb25maWcpIHN1cGVyLnNldChmaWVsZE5hbWUsIHZhbHVlKTsKICB9CgogIEBPdmVycmlkZQogIHB1YmxpYyBBdWRpdENvbmZpZyBjbG9uZSgpIHsKICAgIHJldHVybiAoQXVkaXRDb25maWcpIHN1cGVyLmNsb25lKCk7CiAgfQoKfQpQSwMEFAAAAAAAAAAhAOdkkSdYCQAAWAkAADMAAABjb20vZ29vZ2xlL2FwaS9zZXJ2aWNlcy9pYW0vdjEvbW9kZWwvQXVkaXREYXRhLmphdmEvKgogKiBDb3B5cmlnaHQgMjAxMCBHb29nbGUgSW5jLgogKgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQKICogaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UKICogaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzCiAqIG9yIGltcGxpZWQuIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMgdW5kZXIKICogdGhlIExpY2Vuc2UuCiAqLwovKgogKiBUaGlzIGNvZGUgd2FzIGdlbmVyYXRlZCBieSBodHRwczovL2dpdGh1Yi5jb20vZ29vZ2xlL2FwaXMtY2xpZW50LWdlbmVyYXRvci8KICogKGJ1aWxkOiAyMDE4LTEwLTA4IDE3OjQ1OjM5IFVUQykKICogb24gMjAyMC0wMy0xOSBhdCAwMTo1Mjo0MSBVVEMgCiAqIE1vZGlmeSBhdCB5b3VyIG93biByaXNrLgogKi8KCnBhY2thZ2UgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuaWFtLnYxLm1vZGVsOwoKLyoqCiAqIEF1ZGl0IGxvZyBpbmZvcm1hdGlvbiBzcGVjaWZpYyB0byBDbG91ZCBJQU0uIFRoaXMgbWVzc2FnZSBpcyBzZXJpYWxpemVkIGFzIGFuIGBBbnlgIHR5cGUgaW4gdGhlCiAqIGBTZXJ2aWNlRGF0YWAgbWVzc2FnZSBvZiBhbiBgQXVkaXRMb2dgIG1lc3NhZ2UuCiAqCiAqIDxwPiBUaGlzIGlzIHRoZSBKYXZhIGRhdGEgbW9kZWwgY2xhc3MgdGhhdCBzcGVjaWZpZXMgaG93IHRvIHBhcnNlL3NlcmlhbGl6ZSBpbnRvIHRoZSBKU09OIHRoYXQgaXMKICogdHJhbnNtaXR0ZWQgb3ZlciBIVFRQIHdoZW4gd29ya2luZyB3aXRoIHRoZSBJZGVudGl0eSBhbmQgQWNjZXNzIE1hbmFnZW1lbnQgKElBTSkgQVBJLiBGb3IgYQogKiBkZXRhaWxlZCBleHBsYW5hdGlvbiBzZWU6CiAqIDxhIGhyZWY9Imh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL2FwaS1jbGllbnQtbGlicmFyeS9qYXZhL2dvb2dsZS1odHRwLWphdmEtY2xpZW50L2pzb24iPmh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL2FwaS1jbGllbnQtbGlicmFyeS9qYXZhL2dvb2dsZS1odHRwLWphdmEtY2xpZW50L2pzb248L2E+CiAqIDwvcD4KICoKICogQGF1dGhvciBHb29nbGUsIEluYy4KICovCkBTdXBwcmVzc1dhcm5pbmdzKCJqYXZhZG9jIikKcHVibGljIGZpbmFsIGNsYXNzIEF1ZGl0RGF0YSBleHRlbmRzIGNvbS5nb29nbGUuYXBpLmNsaWVudC5qc29uLkdlbmVyaWNKc29uIHsKCiAgLyoqCiAgICogUG9saWN5IGRlbHRhIGJldHdlZW4gdGhlIG9yaWdpbmFsIHBvbGljeSBhbmQgdGhlIG5ld2x5IHNldCBwb2xpY3kuCiAgICogVGhlIHZhbHVlIG1heSBiZSB7QGNvZGUgbnVsbH0uCiAgICovCiAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogIHByaXZhdGUgUG9saWN5RGVsdGEgcG9saWN5RGVsdGE7CgogIC8qKgogICAqIFBvbGljeSBkZWx0YSBiZXR3ZWVuIHRoZSBvcmlnaW5hbCBwb2xpY3kgYW5kIHRoZSBuZXdseSBzZXQgcG9saWN5LgogICAqIEByZXR1cm4gdmFsdWUgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIFBvbGljeURlbHRhIGdldFBvbGljeURlbHRhKCkgewogICAgcmV0dXJuIHBvbGljeURlbHRhOwogIH0KCiAgLyoqCiAgICogUG9saWN5IGRlbHRhIGJldHdlZW4gdGhlIG9yaWdpbmFsIHBvbGljeSBhbmQgdGhlIG5ld2x5IHNldCBwb2xpY3kuCiAgICogQHBhcmFtIHBvbGljeURlbHRhIHBvbGljeURlbHRhIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBBdWRpdERhdGEgc2V0UG9saWN5RGVsdGEoUG9saWN5RGVsdGEgcG9saWN5RGVsdGEpIHsKICAgIHRoaXMucG9saWN5RGVsdGEgPSBwb2xpY3lEZWx0YTsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgQE92ZXJyaWRlCiAgcHVibGljIEF1ZGl0RGF0YSBzZXQoU3RyaW5nIGZpZWxkTmFtZSwgT2JqZWN0IHZhbHVlKSB7CiAgICByZXR1cm4gKEF1ZGl0RGF0YSkgc3VwZXIuc2V0KGZpZWxkTmFtZSwgdmFsdWUpOwogIH0KCiAgQE92ZXJyaWRlCiAgcHVibGljIEF1ZGl0RGF0YSBjbG9uZSgpIHsKICAgIHJldHVybiAoQXVkaXREYXRhKSBzdXBlci5jbG9uZSgpOwogIH0KCn0KUEsDBBQAAAAAAAAAIQAYd3NYzA0AAMwNAAA4AAAAY29tL2dvb2dsZS9hcGkvc2VydmljZXMvaWFtL3YxL21vZGVsL0F1ZGl0TG9nQ29uZmlnLmphdmEvKgogKiBDb3B5cmlnaHQgMjAxMCBHb29nbGUgSW5jLgogKgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQKICogaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UKICogaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzCiAqIG9yIGltcGxpZWQuIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMgdW5kZXIKICogdGhlIExpY2Vuc2UuCiAqLwovKgogKiBUaGlzIGNvZGUgd2FzIGdlbmVyYXRlZCBieSBodHRwczovL2dpdGh1Yi5jb20vZ29vZ2xlL2FwaXMtY2xpZW50LWdlbmVyYXRvci8KICogKGJ1aWxkOiAyMDE4LTEwLTA4IDE3OjQ1OjM5IFVUQykKICogb24gMjAyMC0wMy0xOSBhdCAwMTo1Mjo0MSBVVEMgCiAqIE1vZGlmeSBhdCB5b3VyIG93biByaXNrLgogKi8KCnBhY2thZ2UgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuaWFtLnYxLm1vZGVsOwoKLyoqCiAqIFByb3ZpZGVzIHRoZSBjb25maWd1cmF0aW9uIGZvciBsb2dnaW5nIGEgdHlwZSBvZiBwZXJtaXNzaW9ucy4gRXhhbXBsZToKICoKICogICAgIHsgICAgICAgImF1ZGl0X2xvZ19jb25maWdzIjogWyAgICAgICAgIHsgICAgICAgICAgICJsb2dfdHlwZSI6ICJEQVRBX1JFQUQiLAogKiAiZXhlbXB0ZWRfbWVtYmVycyI6IFsgICAgICAgICAgICAgInVzZXI6am9zZUBleGFtcGxlLmNvbSIgICAgICAgICAgIF0gICAgICAgICB9LCAgICAgICAgIHsKICogImxvZ190eXBlIjogIkRBVEFfV1JJVEUiLCAgICAgICAgIH0gICAgICAgXSAgICAgfQogKgogKiBUaGlzIGVuYWJsZXMgJ0RBVEFfUkVBRCcgYW5kICdEQVRBX1dSSVRFJyBsb2dnaW5nLCB3aGlsZSBleGVtcHRpbmcgam9zZUBleGFtcGxlLmNvbSBmcm9tCiAqIERBVEFfUkVBRCBsb2dnaW5nLgogKgogKiA8cD4gVGhpcyBpcyB0aGUgSmF2YSBkYXRhIG1vZGVsIGNsYXNzIHRoYXQgc3BlY2lmaWVzIGhvdyB0byBwYXJzZS9zZXJpYWxpemUgaW50byB0aGUgSlNPTiB0aGF0IGlzCiAqIHRyYW5zbWl0dGVkIG92ZXIgSFRUUCB3aGVuIHdvcmtpbmcgd2l0aCB0aGUgSWRlbnRpdHkgYW5kIEFjY2VzcyBNYW5hZ2VtZW50IChJQU0pIEFQSS4gRm9yIGEKICogZGV0YWlsZWQgZXhwbGFuYXRpb24gc2VlOgogKiA8YSBocmVmPSJodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9hcGktY2xpZW50LWxpYnJhcnkvamF2YS9nb29nbGUtaHR0cC1qYXZhLWNsaWVudC9qc29uIj5odHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9hcGktY2xpZW50LWxpYnJhcnkvamF2YS9nb29nbGUtaHR0cC1qYXZhLWNsaWVudC9qc29uPC9hPgogKiA8L3A+CiAqCiAqIEBhdXRob3IgR29vZ2xlLCBJbmMuCiAqLwpAU3VwcHJlc3NXYXJuaW5ncygiamF2YWRvYyIpCnB1YmxpYyBmaW5hbCBjbGFzcyBBdWRpdExvZ0NvbmZpZyBleHRlbmRzIGNvbS5nb29nbGUuYXBpLmNsaWVudC5qc29uLkdlbmVyaWNKc29uIHsKCiAgLyoqCiAgICogU3BlY2lmaWVzIHRoZSBpZGVudGl0aWVzIHRoYXQgZG8gbm90IGNhdXNlIGxvZ2dpbmcgZm9yIHRoaXMgdHlwZSBvZiBwZXJtaXNzaW9uLiBGb2xsb3dzIHRoZQogICAqIHNhbWUgZm9ybWF0IG9mIEJpbmRpbmcubWVtYmVycy4KICAgKiBUaGUgdmFsdWUgbWF5IGJlIHtAY29kZSBudWxsfS4KICAgKi8KICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuU3RyaW5nPiBleGVtcHRlZE1lbWJlcnM7CgogIC8qKgogICAqIFRoZSBsb2cgdHlwZSB0aGF0IHRoaXMgY29uZmlnIGVuYWJsZXMuCiAgICogVGhlIHZhbHVlIG1heSBiZSB7QGNvZGUgbnVsbH0uCiAgICovCiAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogIHByaXZhdGUgamF2YS5sYW5nLlN0cmluZyBsb2dUeXBlOwoKICAvKioKICAgKiBTcGVjaWZpZXMgdGhlIGlkZW50aXRpZXMgdGhhdCBkbyBub3QgY2F1c2UgbG9nZ2luZyBmb3IgdGhpcyB0eXBlIG9mIHBlcm1pc3Npb24uIEZvbGxvd3MgdGhlCiAgICogc2FtZSBmb3JtYXQgb2YgQmluZGluZy5tZW1iZXJzLgogICAqIEByZXR1cm4gdmFsdWUgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5TdHJpbmc+IGdldEV4ZW1wdGVkTWVtYmVycygpIHsKICAgIHJldHVybiBleGVtcHRlZE1lbWJlcnM7CiAgfQoKICAvKioKICAgKiBTcGVjaWZpZXMgdGhlIGlkZW50aXRpZXMgdGhhdCBkbyBub3QgY2F1c2UgbG9nZ2luZyBmb3IgdGhpcyB0eXBlIG9mIHBlcm1pc3Npb24uIEZvbGxvd3MgdGhlCiAgICogc2FtZSBmb3JtYXQgb2YgQmluZGluZy5tZW1iZXJzLgogICAqIEBwYXJhbSBleGVtcHRlZE1lbWJlcnMgZXhlbXB0ZWRNZW1iZXJzIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBBdWRpdExvZ0NvbmZpZyBzZXRFeGVtcHRlZE1lbWJlcnMoamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLlN0cmluZz4gZXhlbXB0ZWRNZW1iZXJzKSB7CiAgICB0aGlzLmV4ZW1wdGVkTWVtYmVycyA9IGV4ZW1wdGVkTWVtYmVyczsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgLyoqCiAgICogVGhlIGxvZyB0eXBlIHRoYXQgdGhpcyBjb25maWcgZW5hYmxlcy4KICAgKiBAcmV0dXJuIHZhbHVlIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldExvZ1R5cGUoKSB7CiAgICByZXR1cm4gbG9nVHlwZTsKICB9CgogIC8qKgogICAqIFRoZSBsb2cgdHlwZSB0aGF0IHRoaXMgY29uZmlnIGVuYWJsZXMuCiAgICogQHBhcmFtIGxvZ1R5cGUgbG9nVHlwZSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgQXVkaXRMb2dDb25maWcgc2V0TG9nVHlwZShqYXZhLmxhbmcuU3RyaW5nIGxvZ1R5cGUpIHsKICAgIHRoaXMubG9nVHlwZSA9IGxvZ1R5cGU7CiAgICByZXR1cm4gdGhpczsKICB9CgogIEBPdmVycmlkZQogIHB1YmxpYyBBdWRpdExvZ0NvbmZpZyBzZXQoU3RyaW5nIGZpZWxkTmFtZSwgT2JqZWN0IHZhbHVlKSB7CiAgICByZXR1cm4gKEF1ZGl0TG9nQ29uZmlnKSBzdXBlci5zZXQoZmllbGROYW1lLCB2YWx1ZSk7CiAgfQoKICBAT3ZlcnJpZGUKICBwdWJsaWMgQXVkaXRMb2dDb25maWcgY2xvbmUoKSB7CiAgICByZXR1cm4gKEF1ZGl0TG9nQ29uZmlnKSBzdXBlci5jbG9uZSgpOwogIH0KCn0KUEsDBBQAAAAAAAAAIQARtrcYWQkAAFkJAAA6AAAAY29tL2dvb2dsZS9hcGkvc2VydmljZXMvaWFtL3YxL21vZGVsL0F1ZGl0YWJsZVNlcnZpY2UuamF2YS8qCiAqIENvcHlyaWdodCAyMDEwIEdvb2dsZSBJbmMuCiAqCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdAogKiBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZQogKiBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3MKICogb3IgaW1wbGllZC4gU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucyB1bmRlcgogKiB0aGUgTGljZW5zZS4KICovCi8qCiAqIFRoaXMgY29kZSB3YXMgZ2VuZXJhdGVkIGJ5IGh0dHBzOi8vZ2l0aHViLmNvbS9nb29nbGUvYXBpcy1jbGllbnQtZ2VuZXJhdG9yLwogKiAoYnVpbGQ6IDIwMTgtMTAtMDggMTc6NDU6MzkgVVRDKQogKiBvbiAyMDIwLTAzLTE5IGF0IDAxOjUyOjQxIFVUQyAKICogTW9kaWZ5IGF0IHlvdXIgb3duIHJpc2suCiAqLwoKcGFja2FnZSBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5pYW0udjEubW9kZWw7CgovKioKICogQ29udGFpbnMgaW5mb3JtYXRpb24gYWJvdXQgYW4gYXVkaXRhYmxlIHNlcnZpY2UuCiAqCiAqIDxwPiBUaGlzIGlzIHRoZSBKYXZhIGRhdGEgbW9kZWwgY2xhc3MgdGhhdCBzcGVjaWZpZXMgaG93IHRvIHBhcnNlL3NlcmlhbGl6ZSBpbnRvIHRoZSBKU09OIHRoYXQgaXMKICogdHJhbnNtaXR0ZWQgb3ZlciBIVFRQIHdoZW4gd29ya2luZyB3aXRoIHRoZSBJZGVudGl0eSBhbmQgQWNjZXNzIE1hbmFnZW1lbnQgKElBTSkgQVBJLiBGb3IgYQogKiBkZXRhaWxlZCBleHBsYW5hdGlvbiBzZWU6CiAqIDxhIGhyZWY9Imh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL2FwaS1jbGllbnQtbGlicmFyeS9qYXZhL2dvb2dsZS1odHRwLWphdmEtY2xpZW50L2pzb24iPmh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL2FwaS1jbGllbnQtbGlicmFyeS9qYXZhL2dvb2dsZS1odHRwLWphdmEtY2xpZW50L2pzb248L2E+CiAqIDwvcD4KICoKICogQGF1dGhvciBHb29nbGUsIEluYy4KICovCkBTdXBwcmVzc1dhcm5pbmdzKCJqYXZhZG9jIikKcHVibGljIGZpbmFsIGNsYXNzIEF1ZGl0YWJsZVNlcnZpY2UgZXh0ZW5kcyBjb20uZ29vZ2xlLmFwaS5jbGllbnQuanNvbi5HZW5lcmljSnNvbiB7CgogIC8qKgogICAqIFB1YmxpYyBuYW1lIG9mIHRoZSBzZXJ2aWNlLiBGb3IgZXhhbXBsZSwgdGhlIHNlcnZpY2UgbmFtZSBmb3IgQ2xvdWQgSUFNIGlzCiAgICogJ2lhbS5nb29nbGVhcGlzLmNvbScuCiAgICogVGhlIHZhbHVlIG1heSBiZSB7QGNvZGUgbnVsbH0uCiAgICovCiAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogIHByaXZhdGUgamF2YS5sYW5nLlN0cmluZyBuYW1lOwoKICAvKioKICAgKiBQdWJsaWMgbmFtZSBvZiB0aGUgc2VydmljZS4gRm9yIGV4YW1wbGUsIHRoZSBzZXJ2aWNlIG5hbWUgZm9yIENsb3VkIElBTSBpcwogICAqICdpYW0uZ29vZ2xlYXBpcy5jb20nLgogICAqIEByZXR1cm4gdmFsdWUgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TmFtZSgpIHsKICAgIHJldHVybiBuYW1lOwogIH0KCiAgLyoqCiAgICogUHVibGljIG5hbWUgb2YgdGhlIHNlcnZpY2UuIEZvciBleGFtcGxlLCB0aGUgc2VydmljZSBuYW1lIGZvciBDbG91ZCBJQU0gaXMKICAgKiAnaWFtLmdvb2dsZWFwaXMuY29tJy4KICAgKiBAcGFyYW0gbmFtZSBuYW1lIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBBdWRpdGFibGVTZXJ2aWNlIHNldE5hbWUoamF2YS5sYW5nLlN0cmluZyBuYW1lKSB7CiAgICB0aGlzLm5hbWUgPSBuYW1lOwogICAgcmV0dXJuIHRoaXM7CiAgfQoKICBAT3ZlcnJpZGUKICBwdWJsaWMgQXVkaXRhYmxlU2VydmljZSBzZXQoU3RyaW5nIGZpZWxkTmFtZSwgT2JqZWN0IHZhbHVlKSB7CiAgICByZXR1cm4gKEF1ZGl0YWJsZVNlcnZpY2UpIHN1cGVyLnNldChmaWVsZE5hbWUsIHZhbHVlKTsKICB9CgogIEBPdmVycmlkZQogIHB1YmxpYyBBdWRpdGFibGVTZXJ2aWNlIGNsb25lKCkgewogICAgcmV0dXJuIChBdWRpdGFibGVTZXJ2aWNlKSBzdXBlci5jbG9uZSgpOwogIH0KCn0KUEsDBBQAAAAAAAAAIQBGDf8hMigAADIoAAAxAAAAY29tL2dvb2dsZS9hcGkvc2VydmljZXMvaWFtL3YxL21vZGVsL0JpbmRpbmcuamF2YS8qCiAqIENvcHlyaWdodCAyMDEwIEdvb2dsZSBJbmMuCiAqCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdAogKiBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZQogKiBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3MKICogb3IgaW1wbGllZC4gU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucyB1bmRlcgogKiB0aGUgTGljZW5zZS4KICovCi8qCiAqIFRoaXMgY29kZSB3YXMgZ2VuZXJhdGVkIGJ5IGh0dHBzOi8vZ2l0aHViLmNvbS9nb29nbGUvYXBpcy1jbGllbnQtZ2VuZXJhdG9yLwogKiAoYnVpbGQ6IDIwMTgtMTAtMDggMTc6NDU6MzkgVVRDKQogKiBvbiAyMDIwLTAzLTE5IGF0IDAxOjUyOjQxIFVUQyAKICogTW9kaWZ5IGF0IHlvdXIgb3duIHJpc2suCiAqLwoKcGFja2FnZSBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5pYW0udjEubW9kZWw7CgovKioKICogQXNzb2NpYXRlcyBgbWVtYmVyc2Agd2l0aCBhIGByb2xlYC4KICoKICogPHA+IFRoaXMgaXMgdGhlIEphdmEgZGF0YSBtb2RlbCBjbGFzcyB0aGF0IHNwZWNpZmllcyBob3cgdG8gcGFyc2Uvc2VyaWFsaXplIGludG8gdGhlIEpTT04gdGhhdCBpcwogKiB0cmFuc21pdHRlZCBvdmVyIEhUVFAgd2hlbiB3b3JraW5nIHdpdGggdGhlIElkZW50aXR5IGFuZCBBY2Nlc3MgTWFuYWdlbWVudCAoSUFNKSBBUEkuIEZvciBhCiAqIGRldGFpbGVkIGV4cGxhbmF0aW9uIHNlZToKICogPGEgaHJlZj0iaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vYXBpLWNsaWVudC1saWJyYXJ5L2phdmEvZ29vZ2xlLWh0dHAtamF2YS1jbGllbnQvanNvbiI+aHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vYXBpLWNsaWVudC1saWJyYXJ5L2phdmEvZ29vZ2xlLWh0dHAtamF2YS1jbGllbnQvanNvbjwvYT4KICogPC9wPgogKgogKiBAYXV0aG9yIEdvb2dsZSwgSW5jLgogKi8KQFN1cHByZXNzV2FybmluZ3MoImphdmFkb2MiKQpwdWJsaWMgZmluYWwgY2xhc3MgQmluZGluZyBleHRlbmRzIGNvbS5nb29nbGUuYXBpLmNsaWVudC5qc29uLkdlbmVyaWNKc29uIHsKCiAgLyoqCiAgICogVGhlIGNvbmRpdGlvbiB0aGF0IGlzIGFzc29jaWF0ZWQgd2l0aCB0aGlzIGJpbmRpbmcuIE5PVEU6IEFuIHVuc2F0aXNmaWVkIGNvbmRpdGlvbiB3aWxsIG5vdAogICAqIGFsbG93IHVzZXIgYWNjZXNzIHZpYSBjdXJyZW50IGJpbmRpbmcuIERpZmZlcmVudCBiaW5kaW5ncywgaW5jbHVkaW5nIHRoZWlyIGNvbmRpdGlvbnMsIGFyZQogICAqIGV4YW1pbmVkIGluZGVwZW5kZW50bHkuCiAgICogVGhlIHZhbHVlIG1heSBiZSB7QGNvZGUgbnVsbH0uCiAgICovCiAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogIHByaXZhdGUgRXhwciBjb25kaXRpb247CgogIC8qKgogICAqIFNwZWNpZmllcyB0aGUgaWRlbnRpdGllcyByZXF1ZXN0aW5nIGFjY2VzcyBmb3IgYSBDbG91ZCBQbGF0Zm9ybSByZXNvdXJjZS4gYG1lbWJlcnNgIGNhbiBoYXZlCiAgICogdGhlIGZvbGxvd2luZyB2YWx1ZXM6CiAgICoKICAgKiAqIGBhbGxVc2Vyc2A6IEEgc3BlY2lhbCBpZGVudGlmaWVyIHRoYXQgcmVwcmVzZW50cyBhbnlvbmUgd2hvIGlzICAgIG9uIHRoZSBpbnRlcm5ldDsgd2l0aCBvcgogICAqIHdpdGhvdXQgYSBHb29nbGUgYWNjb3VudC4KICAgKgogICAqICogYGFsbEF1dGhlbnRpY2F0ZWRVc2Vyc2A6IEEgc3BlY2lhbCBpZGVudGlmaWVyIHRoYXQgcmVwcmVzZW50cyBhbnlvbmUgICAgd2hvIGlzIGF1dGhlbnRpY2F0ZWQKICAgKiB3aXRoIGEgR29vZ2xlIGFjY291bnQgb3IgYSBzZXJ2aWNlIGFjY291bnQuCiAgICoKICAgKiAqIGB1c2VyOntlbWFpbGlkfWA6IEFuIGVtYWlsIGFkZHJlc3MgdGhhdCByZXByZXNlbnRzIGEgc3BlY2lmaWMgR29vZ2xlICAgIGFjY291bnQuIEZvciBleGFtcGxlLAogICAqIGBhbGljZUBleGFtcGxlLmNvbWAgLgogICAqCiAgICogKiBgc2VydmljZUFjY291bnQ6e2VtYWlsaWR9YDogQW4gZW1haWwgYWRkcmVzcyB0aGF0IHJlcHJlc2VudHMgYSBzZXJ2aWNlICAgIGFjY291bnQuIEZvcgogICAqIGV4YW1wbGUsIGBteS1vdGhlci1hcHBAYXBwc3BvdC5nc2VydmljZWFjY291bnQuY29tYC4KICAgKgogICAqICogYGdyb3VwOntlbWFpbGlkfWA6IEFuIGVtYWlsIGFkZHJlc3MgdGhhdCByZXByZXNlbnRzIGEgR29vZ2xlIGdyb3VwLiAgICBGb3IgZXhhbXBsZSwKICAgKiBgYWRtaW5zQGV4YW1wbGUuY29tYC4KICAgKgogICAqICogYGRlbGV0ZWQ6dXNlcjp7ZW1haWxpZH0/dWlkPXt1bmlxdWVpZH1gOiBBbiBlbWFpbCBhZGRyZXNzIChwbHVzIHVuaXF1ZSAgICBpZGVudGlmaWVyKQogICAqIHJlcHJlc2VudGluZyBhIHVzZXIgdGhhdCBoYXMgYmVlbiByZWNlbnRseSBkZWxldGVkLiBGb3IgICAgZXhhbXBsZSwKICAgKiBgYWxpY2VAZXhhbXBsZS5jb20/dWlkPTEyMzQ1Njc4OTAxMjM0NTY3ODkwMWAuIElmIHRoZSB1c2VyIGlzICAgIHJlY292ZXJlZCwgdGhpcyB2YWx1ZSByZXZlcnRzCiAgICogdG8gYHVzZXI6e2VtYWlsaWR9YCBhbmQgdGhlIHJlY292ZXJlZCB1c2VyICAgIHJldGFpbnMgdGhlIHJvbGUgaW4gdGhlIGJpbmRpbmcuCiAgICoKICAgKiAqIGBkZWxldGVkOnNlcnZpY2VBY2NvdW50OntlbWFpbGlkfT91aWQ9e3VuaXF1ZWlkfWA6IEFuIGVtYWlsIGFkZHJlc3MgKHBsdXMgICAgdW5pcXVlCiAgICogaWRlbnRpZmllcikgcmVwcmVzZW50aW5nIGEgc2VydmljZSBhY2NvdW50IHRoYXQgaGFzIGJlZW4gcmVjZW50bHkgICAgZGVsZXRlZC4gRm9yIGV4YW1wbGUsCiAgICogYG15LW90aGVyLWFwcEBhcHBzcG90LmdzZXJ2aWNlYWNjb3VudC5jb20/dWlkPTEyMzQ1Njc4OTAxMjM0NTY3ODkwMWAuICAgIElmIHRoZSBzZXJ2aWNlIGFjY291bnQKICAgKiBpcyB1bmRlbGV0ZWQsIHRoaXMgdmFsdWUgcmV2ZXJ0cyB0byAgICBgc2VydmljZUFjY291bnQ6e2VtYWlsaWR9YCBhbmQgdGhlIHVuZGVsZXRlZCBzZXJ2aWNlCiAgICogYWNjb3VudCByZXRhaW5zIHRoZSAgICByb2xlIGluIHRoZSBiaW5kaW5nLgogICAqCiAgICogKiBgZGVsZXRlZDpncm91cDp7ZW1haWxpZH0/dWlkPXt1bmlxdWVpZH1gOiBBbiBlbWFpbCBhZGRyZXNzIChwbHVzIHVuaXF1ZSAgICBpZGVudGlmaWVyKQogICAqIHJlcHJlc2VudGluZyBhIEdvb2dsZSBncm91cCB0aGF0IGhhcyBiZWVuIHJlY2VudGx5ICAgIGRlbGV0ZWQuIEZvciBleGFtcGxlLAogICAqIGBhZG1pbnNAZXhhbXBsZS5jb20/dWlkPTEyMzQ1Njc4OTAxMjM0NTY3ODkwMWAuIElmICAgIHRoZSBncm91cCBpcyByZWNvdmVyZWQsIHRoaXMgdmFsdWUKICAgKiByZXZlcnRzIHRvIGBncm91cDp7ZW1haWxpZH1gIGFuZCB0aGUgICAgcmVjb3ZlcmVkIGdyb3VwIHJldGFpbnMgdGhlIHJvbGUgaW4gdGhlIGJpbmRpbmcuCiAgICoKICAgKiAqIGBkb21haW46e2RvbWFpbn1gOiBUaGUgRyBTdWl0ZSBkb21haW4gKHByaW1hcnkpIHRoYXQgcmVwcmVzZW50cyBhbGwgdGhlICAgIHVzZXJzIG9mIHRoYXQKICAgKiBkb21haW4uIEZvciBleGFtcGxlLCBgZ29vZ2xlLmNvbWAgb3IgYGV4YW1wbGUuY29tYC4KICAgKiBUaGUgdmFsdWUgbWF5IGJlIHtAY29kZSBudWxsfS4KICAgKi8KICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuU3RyaW5nPiBtZW1iZXJzOwoKICAvKioKICAgKiBSb2xlIHRoYXQgaXMgYXNzaWduZWQgdG8gYG1lbWJlcnNgLiBGb3IgZXhhbXBsZSwgYHJvbGVzL3ZpZXdlcmAsIGByb2xlcy9lZGl0b3JgLCBvcgogICAqIGByb2xlcy9vd25lcmAuCiAgICogVGhlIHZhbHVlIG1heSBiZSB7QGNvZGUgbnVsbH0uCiAgICovCiAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogIHByaXZhdGUgamF2YS5sYW5nLlN0cmluZyByb2xlOwoKICAvKioKICAgKiBUaGUgY29uZGl0aW9uIHRoYXQgaXMgYXNzb2NpYXRlZCB3aXRoIHRoaXMgYmluZGluZy4gTk9URTogQW4gdW5zYXRpc2ZpZWQgY29uZGl0aW9uIHdpbGwgbm90CiAgICogYWxsb3cgdXNlciBhY2Nlc3MgdmlhIGN1cnJlbnQgYmluZGluZy4gRGlmZmVyZW50IGJpbmRpbmdzLCBpbmNsdWRpbmcgdGhlaXIgY29uZGl0aW9ucywgYXJlCiAgICogZXhhbWluZWQgaW5kZXBlbmRlbnRseS4KICAgKiBAcmV0dXJuIHZhbHVlIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBFeHByIGdldENvbmRpdGlvbigpIHsKICAgIHJldHVybiBjb25kaXRpb247CiAgfQoKICAvKioKICAgKiBUaGUgY29uZGl0aW9uIHRoYXQgaXMgYXNzb2NpYXRlZCB3aXRoIHRoaXMgYmluZGluZy4gTk9URTogQW4gdW5zYXRpc2ZpZWQgY29uZGl0aW9uIHdpbGwgbm90CiAgICogYWxsb3cgdXNlciBhY2Nlc3MgdmlhIGN1cnJlbnQgYmluZGluZy4gRGlmZmVyZW50IGJpbmRpbmdzLCBpbmNsdWRpbmcgdGhlaXIgY29uZGl0aW9ucywgYXJlCiAgICogZXhhbWluZWQgaW5kZXBlbmRlbnRseS4KICAgKiBAcGFyYW0gY29uZGl0aW9uIGNvbmRpdGlvbiBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgQmluZGluZyBzZXRDb25kaXRpb24oRXhwciBjb25kaXRpb24pIHsKICAgIHRoaXMuY29uZGl0aW9uID0gY29uZGl0aW9uOwogICAgcmV0dXJuIHRoaXM7CiAgfQoKICAvKioKICAgKiBTcGVjaWZpZXMgdGhlIGlkZW50aXRpZXMgcmVxdWVzdGluZyBhY2Nlc3MgZm9yIGEgQ2xvdWQgUGxhdGZvcm0gcmVzb3VyY2UuIGBtZW1iZXJzYCBjYW4gaGF2ZQogICAqIHRoZSBmb2xsb3dpbmcgdmFsdWVzOgogICAqCiAgICogKiBgYWxsVXNlcnNgOiBBIHNwZWNpYWwgaWRlbnRpZmllciB0aGF0IHJlcHJlc2VudHMgYW55b25lIHdobyBpcyAgICBvbiB0aGUgaW50ZXJuZXQ7IHdpdGggb3IKICAgKiB3aXRob3V0IGEgR29vZ2xlIGFjY291bnQuCiAgICoKICAgKiAqIGBhbGxBdXRoZW50aWNhdGVkVXNlcnNgOiBBIHNwZWNpYWwgaWRlbnRpZmllciB0aGF0IHJlcHJlc2VudHMgYW55b25lICAgIHdobyBpcyBhdXRoZW50aWNhdGVkCiAgICogd2l0aCBhIEdvb2dsZSBhY2NvdW50IG9yIGEgc2VydmljZSBhY2NvdW50LgogICAqCiAgICogKiBgdXNlcjp7ZW1haWxpZH1gOiBBbiBlbWFpbCBhZGRyZXNzIHRoYXQgcmVwcmVzZW50cyBhIHNwZWNpZmljIEdvb2dsZSAgICBhY2NvdW50LiBGb3IgZXhhbXBsZSwKICAgKiBgYWxpY2VAZXhhbXBsZS5jb21gIC4KICAgKgogICAqICogYHNlcnZpY2VBY2NvdW50OntlbWFpbGlkfWA6IEFuIGVtYWlsIGFkZHJlc3MgdGhhdCByZXByZXNlbnRzIGEgc2VydmljZSAgICBhY2NvdW50LiBGb3IKICAgKiBleGFtcGxlLCBgbXktb3RoZXItYXBwQGFwcHNwb3QuZ3NlcnZpY2VhY2NvdW50LmNvbWAuCiAgICoKICAgKiAqIGBncm91cDp7ZW1haWxpZH1gOiBBbiBlbWFpbCBhZGRyZXNzIHRoYXQgcmVwcmVzZW50cyBhIEdvb2dsZSBncm91cC4gICAgRm9yIGV4YW1wbGUsCiAgICogYGFkbWluc0BleGFtcGxlLmNvbWAuCiAgICoKICAgKiAqIGBkZWxldGVkOnVzZXI6e2VtYWlsaWR9P3VpZD17dW5pcXVlaWR9YDogQW4gZW1haWwgYWRkcmVzcyAocGx1cyB1bmlxdWUgICAgaWRlbnRpZmllcikKICAgKiByZXByZXNlbnRpbmcgYSB1c2VyIHRoYXQgaGFzIGJlZW4gcmVjZW50bHkgZGVsZXRlZC4gRm9yICAgIGV4YW1wbGUsCiAgICogYGFsaWNlQGV4YW1wbGUuY29tP3VpZD0xMjM0NTY3ODkwMTIzNDU2Nzg5MDFgLiBJZiB0aGUgdXNlciBpcyAgICByZWNvdmVyZWQsIHRoaXMgdmFsdWUgcmV2ZXJ0cwogICAqIHRvIGB1c2VyOntlbWFpbGlkfWAgYW5kIHRoZSByZWNvdmVyZWQgdXNlciAgICByZXRhaW5zIHRoZSByb2xlIGluIHRoZSBiaW5kaW5nLgogICAqCiAgICogKiBgZGVsZXRlZDpzZXJ2aWNlQWNjb3VudDp7ZW1haWxpZH0/dWlkPXt1bmlxdWVpZH1gOiBBbiBlbWFpbCBhZGRyZXNzIChwbHVzICAgIHVuaXF1ZQogICAqIGlkZW50aWZpZXIpIHJlcHJlc2VudGluZyBhIHNlcnZpY2UgYWNjb3VudCB0aGF0IGhhcyBiZWVuIHJlY2VudGx5ICAgIGRlbGV0ZWQuIEZvciBleGFtcGxlLAogICAqIGBteS1vdGhlci1hcHBAYXBwc3BvdC5nc2VydmljZWFjY291bnQuY29tP3VpZD0xMjM0NTY3ODkwMTIzNDU2Nzg5MDFgLiAgICBJZiB0aGUgc2VydmljZSBhY2NvdW50CiAgICogaXMgdW5kZWxldGVkLCB0aGlzIHZhbHVlIHJldmVydHMgdG8gICAgYHNlcnZpY2VBY2NvdW50OntlbWFpbGlkfWAgYW5kIHRoZSB1bmRlbGV0ZWQgc2VydmljZQogICAqIGFjY291bnQgcmV0YWlucyB0aGUgICAgcm9sZSBpbiB0aGUgYmluZGluZy4KICAgKgogICAqICogYGRlbGV0ZWQ6Z3JvdXA6e2VtYWlsaWR9P3VpZD17dW5pcXVlaWR9YDogQW4gZW1haWwgYWRkcmVzcyAocGx1cyB1bmlxdWUgICAgaWRlbnRpZmllcikKICAgKiByZXByZXNlbnRpbmcgYSBHb29nbGUgZ3JvdXAgdGhhdCBoYXMgYmVlbiByZWNlbnRseSAgICBkZWxldGVkLiBGb3IgZXhhbXBsZSwKICAgKiBgYWRtaW5zQGV4YW1wbGUuY29tP3VpZD0xMjM0NTY3ODkwMTIzNDU2Nzg5MDFgLiBJZiAgICB0aGUgZ3JvdXAgaXMgcmVjb3ZlcmVkLCB0aGlzIHZhbHVlCiAgICogcmV2ZXJ0cyB0byBgZ3JvdXA6e2VtYWlsaWR9YCBhbmQgdGhlICAgIHJlY292ZXJlZCBncm91cCByZXRhaW5zIHRoZSByb2xlIGluIHRoZSBiaW5kaW5nLgogICAqCiAgICogKiBgZG9tYWluOntkb21haW59YDogVGhlIEcgU3VpdGUgZG9tYWluIChwcmltYXJ5KSB0aGF0IHJlcHJlc2VudHMgYWxsIHRoZSAgICB1c2VycyBvZiB0aGF0CiAgICogZG9tYWluLiBGb3IgZXhhbXBsZSwgYGdvb2dsZS5jb21gIG9yIGBleGFtcGxlLmNvbWAuCiAgICogQHJldHVybiB2YWx1ZSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLlN0cmluZz4gZ2V0TWVtYmVycygpIHsKICAgIHJldHVybiBtZW1iZXJzOwogIH0KCiAgLyoqCiAgICogU3BlY2lmaWVzIHRoZSBpZGVudGl0aWVzIHJlcXVlc3RpbmcgYWNjZXNzIGZvciBhIENsb3VkIFBsYXRmb3JtIHJlc291cmNlLiBgbWVtYmVyc2AgY2FuIGhhdmUKICAgKiB0aGUgZm9sbG93aW5nIHZhbHVlczoKICAgKgogICAqICogYGFsbFVzZXJzYDogQSBzcGVjaWFsIGlkZW50aWZpZXIgdGhhdCByZXByZXNlbnRzIGFueW9uZSB3aG8gaXMgICAgb24gdGhlIGludGVybmV0OyB3aXRoIG9yCiAgICogd2l0aG91dCBhIEdvb2dsZSBhY2NvdW50LgogICAqCiAgICogKiBgYWxsQXV0aGVudGljYXRlZFVzZXJzYDogQSBzcGVjaWFsIGlkZW50aWZpZXIgdGhhdCByZXByZXNlbnRzIGFueW9uZSAgICB3aG8gaXMgYXV0aGVudGljYXRlZAogICAqIHdpdGggYSBHb29nbGUgYWNjb3VudCBvciBhIHNlcnZpY2UgYWNjb3VudC4KICAgKgogICAqICogYHVzZXI6e2VtYWlsaWR9YDogQW4gZW1haWwgYWRkcmVzcyB0aGF0IHJlcHJlc2VudHMgYSBzcGVjaWZpYyBHb29nbGUgICAgYWNjb3VudC4gRm9yIGV4YW1wbGUsCiAgICogYGFsaWNlQGV4YW1wbGUuY29tYCAuCiAgICoKICAgKiAqIGBzZXJ2aWNlQWNjb3VudDp7ZW1haWxpZH1gOiBBbiBlbWFpbCBhZGRyZXNzIHRoYXQgcmVwcmVzZW50cyBhIHNlcnZpY2UgICAgYWNjb3VudC4gRm9yCiAgICogZXhhbXBsZSwgYG15LW90aGVyLWFwcEBhcHBzcG90LmdzZXJ2aWNlYWNjb3VudC5jb21gLgogICAqCiAgICogKiBgZ3JvdXA6e2VtYWlsaWR9YDogQW4gZW1haWwgYWRkcmVzcyB0aGF0IHJlcHJlc2VudHMgYSBHb29nbGUgZ3JvdXAuICAgIEZvciBleGFtcGxlLAogICAqIGBhZG1pbnNAZXhhbXBsZS5jb21gLgogICAqCiAgICogKiBgZGVsZXRlZDp1c2VyOntlbWFpbGlkfT91aWQ9e3VuaXF1ZWlkfWA6IEFuIGVtYWlsIGFkZHJlc3MgKHBsdXMgdW5pcXVlICAgIGlkZW50aWZpZXIpCiAgICogcmVwcmVzZW50aW5nIGEgdXNlciB0aGF0IGhhcyBiZWVuIHJlY2VudGx5IGRlbGV0ZWQuIEZvciAgICBleGFtcGxlLAogICAqIGBhbGljZUBleGFtcGxlLmNvbT91aWQ9MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxYC4gSWYgdGhlIHVzZXIgaXMgICAgcmVjb3ZlcmVkLCB0aGlzIHZhbHVlIHJldmVydHMKICAgKiB0byBgdXNlcjp7ZW1haWxpZH1gIGFuZCB0aGUgcmVjb3ZlcmVkIHVzZXIgICAgcmV0YWlucyB0aGUgcm9sZSBpbiB0aGUgYmluZGluZy4KICAgKgogICAqICogYGRlbGV0ZWQ6c2VydmljZUFjY291bnQ6e2VtYWlsaWR9P3VpZD17dW5pcXVlaWR9YDogQW4gZW1haWwgYWRkcmVzcyAocGx1cyAgICB1bmlxdWUKICAgKiBpZGVudGlmaWVyKSByZXByZXNlbnRpbmcgYSBzZXJ2aWNlIGFjY291bnQgdGhhdCBoYXMgYmVlbiByZWNlbnRseSAgICBkZWxldGVkLiBGb3IgZXhhbXBsZSwKICAgKiBgbXktb3RoZXItYXBwQGFwcHNwb3QuZ3NlcnZpY2VhY2NvdW50LmNvbT91aWQ9MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxYC4gICAgSWYgdGhlIHNlcnZpY2UgYWNjb3VudAogICAqIGlzIHVuZGVsZXRlZCwgdGhpcyB2YWx1ZSByZXZlcnRzIHRvICAgIGBzZXJ2aWNlQWNjb3VudDp7ZW1haWxpZH1gIGFuZCB0aGUgdW5kZWxldGVkIHNlcnZpY2UKICAgKiBhY2NvdW50IHJldGFpbnMgdGhlICAgIHJvbGUgaW4gdGhlIGJpbmRpbmcuCiAgICoKICAgKiAqIGBkZWxldGVkOmdyb3VwOntlbWFpbGlkfT91aWQ9e3VuaXF1ZWlkfWA6IEFuIGVtYWlsIGFkZHJlc3MgKHBsdXMgdW5pcXVlICAgIGlkZW50aWZpZXIpCiAgICogcmVwcmVzZW50aW5nIGEgR29vZ2xlIGdyb3VwIHRoYXQgaGFzIGJlZW4gcmVjZW50bHkgICAgZGVsZXRlZC4gRm9yIGV4YW1wbGUsCiAgICogYGFkbWluc0BleGFtcGxlLmNvbT91aWQ9MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxYC4gSWYgICAgdGhlIGdyb3VwIGlzIHJlY292ZXJlZCwgdGhpcyB2YWx1ZQogICAqIHJldmVydHMgdG8gYGdyb3VwOntlbWFpbGlkfWAgYW5kIHRoZSAgICByZWNvdmVyZWQgZ3JvdXAgcmV0YWlucyB0aGUgcm9sZSBpbiB0aGUgYmluZGluZy4KICAgKgogICAqICogYGRvbWFpbjp7ZG9tYWlufWA6IFRoZSBHIFN1aXRlIGRvbWFpbiAocHJpbWFyeSkgdGhhdCByZXByZXNlbnRzIGFsbCB0aGUgICAgdXNlcnMgb2YgdGhhdAogICAqIGRvbWFpbi4gRm9yIGV4YW1wbGUsIGBnb29nbGUuY29tYCBvciBgZXhhbXBsZS5jb21gLgogICAqIEBwYXJhbSBtZW1iZXJzIG1lbWJlcnMgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIEJpbmRpbmcgc2V0TWVtYmVycyhqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuU3RyaW5nPiBtZW1iZXJzKSB7CiAgICB0aGlzLm1lbWJlcnMgPSBtZW1iZXJzOwogICAgcmV0dXJuIHRoaXM7CiAgfQoKICAvKioKICAgKiBSb2xlIHRoYXQgaXMgYXNzaWduZWQgdG8gYG1lbWJlcnNgLiBGb3IgZXhhbXBsZSwgYHJvbGVzL3ZpZXdlcmAsIGByb2xlcy9lZGl0b3JgLCBvcgogICAqIGByb2xlcy9vd25lcmAuCiAgICogQHJldHVybiB2YWx1ZSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRSb2xlKCkgewogICAgcmV0dXJuIHJvbGU7CiAgfQoKICAvKioKICAgKiBSb2xlIHRoYXQgaXMgYXNzaWduZWQgdG8gYG1lbWJlcnNgLiBGb3IgZXhhbXBsZSwgYHJvbGVzL3ZpZXdlcmAsIGByb2xlcy9lZGl0b3JgLCBvcgogICAqIGByb2xlcy9vd25lcmAuCiAgICogQHBhcmFtIHJvbGUgcm9sZSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgQmluZGluZyBzZXRSb2xlKGphdmEubGFuZy5TdHJpbmcgcm9sZSkgewogICAgdGhpcy5yb2xlID0gcm9sZTsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgQE92ZXJyaWRlCiAgcHVibGljIEJpbmRpbmcgc2V0KFN0cmluZyBmaWVsZE5hbWUsIE9iamVjdCB2YWx1ZSkgewogICAgcmV0dXJuIChCaW5kaW5nKSBzdXBlci5zZXQoZmllbGROYW1lLCB2YWx1ZSk7CiAgfQoKICBAT3ZlcnJpZGUKICBwdWJsaWMgQmluZGluZyBjbG9uZSgpIHsKICAgIHJldHVybiAoQmluZGluZykgc3VwZXIuY2xvbmUoKTsKICB9Cgp9ClBLAwQUAAAAAAAAACEA3vDoiU0RAABNEQAANgAAAGNvbS9nb29nbGUvYXBpL3NlcnZpY2VzL2lhbS92MS9tb2RlbC9CaW5kaW5nRGVsdGEuamF2YS8qCiAqIENvcHlyaWdodCAyMDEwIEdvb2dsZSBJbmMuCiAqCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdAogKiBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZQogKiBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3MKICogb3IgaW1wbGllZC4gU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucyB1bmRlcgogKiB0aGUgTGljZW5zZS4KICovCi8qCiAqIFRoaXMgY29kZSB3YXMgZ2VuZXJhdGVkIGJ5IGh0dHBzOi8vZ2l0aHViLmNvbS9nb29nbGUvYXBpcy1jbGllbnQtZ2VuZXJhdG9yLwogKiAoYnVpbGQ6IDIwMTgtMTAtMDggMTc6NDU6MzkgVVRDKQogKiBvbiAyMDIwLTAzLTE5IGF0IDAxOjUyOjQxIFVUQyAKICogTW9kaWZ5IGF0IHlvdXIgb3duIHJpc2suCiAqLwoKcGFja2FnZSBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5pYW0udjEubW9kZWw7CgovKioKICogT25lIGRlbHRhIGVudHJ5IGZvciBCaW5kaW5nLiBFYWNoIGluZGl2aWR1YWwgY2hhbmdlIChvbmx5IG9uZSBtZW1iZXIgaW4gZWFjaCBlbnRyeSkgdG8gYSBiaW5kaW5nCiAqIHdpbGwgYmUgYSBzZXBhcmF0ZSBlbnRyeS4KICoKICogPHA+IFRoaXMgaXMgdGhlIEphdmEgZGF0YSBtb2RlbCBjbGFzcyB0aGF0IHNwZWNpZmllcyBob3cgdG8gcGFyc2Uvc2VyaWFsaXplIGludG8gdGhlIEpTT04gdGhhdCBpcwogKiB0cmFuc21pdHRlZCBvdmVyIEhUVFAgd2hlbiB3b3JraW5nIHdpdGggdGhlIElkZW50aXR5IGFuZCBBY2Nlc3MgTWFuYWdlbWVudCAoSUFNKSBBUEkuIEZvciBhCiAqIGRldGFpbGVkIGV4cGxhbmF0aW9uIHNlZToKICogPGEgaHJlZj0iaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vYXBpLWNsaWVudC1saWJyYXJ5L2phdmEvZ29vZ2xlLWh0dHAtamF2YS1jbGllbnQvanNvbiI+aHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vYXBpLWNsaWVudC1saWJyYXJ5L2phdmEvZ29vZ2xlLWh0dHAtamF2YS1jbGllbnQvanNvbjwvYT4KICogPC9wPgogKgogKiBAYXV0aG9yIEdvb2dsZSwgSW5jLgogKi8KQFN1cHByZXNzV2FybmluZ3MoImphdmFkb2MiKQpwdWJsaWMgZmluYWwgY2xhc3MgQmluZGluZ0RlbHRhIGV4dGVuZHMgY29tLmdvb2dsZS5hcGkuY2xpZW50Lmpzb24uR2VuZXJpY0pzb24gewoKICAvKioKICAgKiBUaGUgYWN0aW9uIHRoYXQgd2FzIHBlcmZvcm1lZCBvbiBhIEJpbmRpbmcuIFJlcXVpcmVkCiAgICogVGhlIHZhbHVlIG1heSBiZSB7QGNvZGUgbnVsbH0uCiAgICovCiAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogIHByaXZhdGUgamF2YS5sYW5nLlN0cmluZyBhY3Rpb247CgogIC8qKgogICAqIFRoZSBjb25kaXRpb24gdGhhdCBpcyBhc3NvY2lhdGVkIHdpdGggdGhpcyBiaW5kaW5nLgogICAqIFRoZSB2YWx1ZSBtYXkgYmUge0Bjb2RlIG51bGx9LgogICAqLwogIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICBwcml2YXRlIEV4cHIgY29uZGl0aW9uOwoKICAvKioKICAgKiBBIHNpbmdsZSBpZGVudGl0eSByZXF1ZXN0aW5nIGFjY2VzcyBmb3IgYSBDbG91ZCBQbGF0Zm9ybSByZXNvdXJjZS4gRm9sbG93cyB0aGUgc2FtZSBmb3JtYXQgb2YKICAgKiBCaW5kaW5nLm1lbWJlcnMuIFJlcXVpcmVkCiAgICogVGhlIHZhbHVlIG1heSBiZSB7QGNvZGUgbnVsbH0uCiAgICovCiAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogIHByaXZhdGUgamF2YS5sYW5nLlN0cmluZyBtZW1iZXI7CgogIC8qKgogICAqIFJvbGUgdGhhdCBpcyBhc3NpZ25lZCB0byBgbWVtYmVyc2AuIEZvciBleGFtcGxlLCBgcm9sZXMvdmlld2VyYCwgYHJvbGVzL2VkaXRvcmAsIG9yCiAgICogYHJvbGVzL293bmVyYC4gUmVxdWlyZWQKICAgKiBUaGUgdmFsdWUgbWF5IGJlIHtAY29kZSBudWxsfS4KICAgKi8KICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgcHJpdmF0ZSBqYXZhLmxhbmcuU3RyaW5nIHJvbGU7CgogIC8qKgogICAqIFRoZSBhY3Rpb24gdGhhdCB3YXMgcGVyZm9ybWVkIG9uIGEgQmluZGluZy4gUmVxdWlyZWQKICAgKiBAcmV0dXJuIHZhbHVlIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldEFjdGlvbigpIHsKICAgIHJldHVybiBhY3Rpb247CiAgfQoKICAvKioKICAgKiBUaGUgYWN0aW9uIHRoYXQgd2FzIHBlcmZvcm1lZCBvbiBhIEJpbmRpbmcuIFJlcXVpcmVkCiAgICogQHBhcmFtIGFjdGlvbiBhY3Rpb24gb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIEJpbmRpbmdEZWx0YSBzZXRBY3Rpb24oamF2YS5sYW5nLlN0cmluZyBhY3Rpb24pIHsKICAgIHRoaXMuYWN0aW9uID0gYWN0aW9uOwogICAgcmV0dXJuIHRoaXM7CiAgfQoKICAvKioKICAgKiBUaGUgY29uZGl0aW9uIHRoYXQgaXMgYXNzb2NpYXRlZCB3aXRoIHRoaXMgYmluZGluZy4KICAgKiBAcmV0dXJuIHZhbHVlIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBFeHByIGdldENvbmRpdGlvbigpIHsKICAgIHJldHVybiBjb25kaXRpb247CiAgfQoKICAvKioKICAgKiBUaGUgY29uZGl0aW9uIHRoYXQgaXMgYXNzb2NpYXRlZCB3aXRoIHRoaXMgYmluZGluZy4KICAgKiBAcGFyYW0gY29uZGl0aW9uIGNvbmRpdGlvbiBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgQmluZGluZ0RlbHRhIHNldENvbmRpdGlvbihFeHByIGNvbmRpdGlvbikgewogICAgdGhpcy5jb25kaXRpb24gPSBjb25kaXRpb247CiAgICByZXR1cm4gdGhpczsKICB9CgogIC8qKgogICAqIEEgc2luZ2xlIGlkZW50aXR5IHJlcXVlc3RpbmcgYWNjZXNzIGZvciBhIENsb3VkIFBsYXRmb3JtIHJlc291cmNlLiBGb2xsb3dzIHRoZSBzYW1lIGZvcm1hdCBvZgogICAqIEJpbmRpbmcubWVtYmVycy4gUmVxdWlyZWQKICAgKiBAcmV0dXJuIHZhbHVlIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldE1lbWJlcigpIHsKICAgIHJldHVybiBtZW1iZXI7CiAgfQoKICAvKioKICAgKiBBIHNpbmdsZSBpZGVudGl0eSByZXF1ZXN0aW5nIGFjY2VzcyBmb3IgYSBDbG91ZCBQbGF0Zm9ybSByZXNvdXJjZS4gRm9sbG93cyB0aGUgc2FtZSBmb3JtYXQgb2YKICAgKiBCaW5kaW5nLm1lbWJlcnMuIFJlcXVpcmVkCiAgICogQHBhcmFtIG1lbWJlciBtZW1iZXIgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIEJpbmRpbmdEZWx0YSBzZXRNZW1iZXIoamF2YS5sYW5nLlN0cmluZyBtZW1iZXIpIHsKICAgIHRoaXMubWVtYmVyID0gbWVtYmVyOwogICAgcmV0dXJuIHRoaXM7CiAgfQoKICAvKioKICAgKiBSb2xlIHRoYXQgaXMgYXNzaWduZWQgdG8gYG1lbWJlcnNgLiBGb3IgZXhhbXBsZSwgYHJvbGVzL3ZpZXdlcmAsIGByb2xlcy9lZGl0b3JgLCBvcgogICAqIGByb2xlcy9vd25lcmAuIFJlcXVpcmVkCiAgICogQHJldHVybiB2YWx1ZSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRSb2xlKCkgewogICAgcmV0dXJuIHJvbGU7CiAgfQoKICAvKioKICAgKiBSb2xlIHRoYXQgaXMgYXNzaWduZWQgdG8gYG1lbWJlcnNgLiBGb3IgZXhhbXBsZSwgYHJvbGVzL3ZpZXdlcmAsIGByb2xlcy9lZGl0b3JgLCBvcgogICAqIGByb2xlcy9vd25lcmAuIFJlcXVpcmVkCiAgICogQHBhcmFtIHJvbGUgcm9sZSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgQmluZGluZ0RlbHRhIHNldFJvbGUoamF2YS5sYW5nLlN0cmluZyByb2xlKSB7CiAgICB0aGlzLnJvbGUgPSByb2xlOwogICAgcmV0dXJuIHRoaXM7CiAgfQoKICBAT3ZlcnJpZGUKICBwdWJsaWMgQmluZGluZ0RlbHRhIHNldChTdHJpbmcgZmllbGROYW1lLCBPYmplY3QgdmFsdWUpIHsKICAgIHJldHVybiAoQmluZGluZ0RlbHRhKSBzdXBlci5zZXQoZmllbGROYW1lLCB2YWx1ZSk7CiAgfQoKICBAT3ZlcnJpZGUKICBwdWJsaWMgQmluZGluZ0RlbHRhIGNsb25lKCkgewogICAgcmV0dXJuIChCaW5kaW5nRGVsdGEpIHN1cGVyLmNsb25lKCk7CiAgfQoKfQpQSwMEFAAAAAAAAAAhAIQixUVjCgAAYwoAADsAAABjb20vZ29vZ2xlL2FwaS9zZXJ2aWNlcy9pYW0vdjEvbW9kZWwvQ3JlYXRlUm9sZVJlcXVlc3QuamF2YS8qCiAqIENvcHlyaWdodCAyMDEwIEdvb2dsZSBJbmMuCiAqCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdAogKiBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZQogKiBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3MKICogb3IgaW1wbGllZC4gU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucyB1bmRlcgogKiB0aGUgTGljZW5zZS4KICovCi8qCiAqIFRoaXMgY29kZSB3YXMgZ2VuZXJhdGVkIGJ5IGh0dHBzOi8vZ2l0aHViLmNvbS9nb29nbGUvYXBpcy1jbGllbnQtZ2VuZXJhdG9yLwogKiAoYnVpbGQ6IDIwMTgtMTAtMDggMTc6NDU6MzkgVVRDKQogKiBvbiAyMDIwLTAzLTE5IGF0IDAxOjUyOjQxIFVUQyAKICogTW9kaWZ5IGF0IHlvdXIgb3duIHJpc2suCiAqLwoKcGFja2FnZSBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5pYW0udjEubW9kZWw7CgovKioKICogVGhlIHJlcXVlc3QgdG8gY3JlYXRlIGEgbmV3IHJvbGUuCiAqCiAqIDxwPiBUaGlzIGlzIHRoZSBKYXZhIGRhdGEgbW9kZWwgY2xhc3MgdGhhdCBzcGVjaWZpZXMgaG93IHRvIHBhcnNlL3NlcmlhbGl6ZSBpbnRvIHRoZSBKU09OIHRoYXQgaXMKICogdHJhbnNtaXR0ZWQgb3ZlciBIVFRQIHdoZW4gd29ya2luZyB3aXRoIHRoZSBJZGVudGl0eSBhbmQgQWNjZXNzIE1hbmFnZW1lbnQgKElBTSkgQVBJLiBGb3IgYQogKiBkZXRhaWxlZCBleHBsYW5hdGlvbiBzZWU6CiAqIDxhIGhyZWY9Imh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL2FwaS1jbGllbnQtbGlicmFyeS9qYXZhL2dvb2dsZS1odHRwLWphdmEtY2xpZW50L2pzb24iPmh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL2FwaS1jbGllbnQtbGlicmFyeS9qYXZhL2dvb2dsZS1odHRwLWphdmEtY2xpZW50L2pzb248L2E+CiAqIDwvcD4KICoKICogQGF1dGhvciBHb29nbGUsIEluYy4KICovCkBTdXBwcmVzc1dhcm5pbmdzKCJqYXZhZG9jIikKcHVibGljIGZpbmFsIGNsYXNzIENyZWF0ZVJvbGVSZXF1ZXN0IGV4dGVuZHMgY29tLmdvb2dsZS5hcGkuY2xpZW50Lmpzb24uR2VuZXJpY0pzb24gewoKICAvKioKICAgKiBUaGUgUm9sZSByZXNvdXJjZSB0byBjcmVhdGUuCiAgICogVGhlIHZhbHVlIG1heSBiZSB7QGNvZGUgbnVsbH0uCiAgICovCiAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogIHByaXZhdGUgUm9sZSByb2xlOwoKICAvKioKICAgKiBUaGUgcm9sZSBJRCB0byB1c2UgZm9yIHRoaXMgcm9sZS4KICAgKiBUaGUgdmFsdWUgbWF5IGJlIHtAY29kZSBudWxsfS4KICAgKi8KICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgcHJpdmF0ZSBqYXZhLmxhbmcuU3RyaW5nIHJvbGVJZDsKCiAgLyoqCiAgICogVGhlIFJvbGUgcmVzb3VyY2UgdG8gY3JlYXRlLgogICAqIEByZXR1cm4gdmFsdWUgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIFJvbGUgZ2V0Um9sZSgpIHsKICAgIHJldHVybiByb2xlOwogIH0KCiAgLyoqCiAgICogVGhlIFJvbGUgcmVzb3VyY2UgdG8gY3JlYXRlLgogICAqIEBwYXJhbSByb2xlIHJvbGUgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIENyZWF0ZVJvbGVSZXF1ZXN0IHNldFJvbGUoUm9sZSByb2xlKSB7CiAgICB0aGlzLnJvbGUgPSByb2xlOwogICAgcmV0dXJuIHRoaXM7CiAgfQoKICAvKioKICAgKiBUaGUgcm9sZSBJRCB0byB1c2UgZm9yIHRoaXMgcm9sZS4KICAgKiBAcmV0dXJuIHZhbHVlIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFJvbGVJZCgpIHsKICAgIHJldHVybiByb2xlSWQ7CiAgfQoKICAvKioKICAgKiBUaGUgcm9sZSBJRCB0byB1c2UgZm9yIHRoaXMgcm9sZS4KICAgKiBAcGFyYW0gcm9sZUlkIHJvbGVJZCBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgQ3JlYXRlUm9sZVJlcXVlc3Qgc2V0Um9sZUlkKGphdmEubGFuZy5TdHJpbmcgcm9sZUlkKSB7CiAgICB0aGlzLnJvbGVJZCA9IHJvbGVJZDsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgQE92ZXJyaWRlCiAgcHVibGljIENyZWF0ZVJvbGVSZXF1ZXN0IHNldChTdHJpbmcgZmllbGROYW1lLCBPYmplY3QgdmFsdWUpIHsKICAgIHJldHVybiAoQ3JlYXRlUm9sZVJlcXVlc3QpIHN1cGVyLnNldChmaWVsZE5hbWUsIHZhbHVlKTsKICB9CgogIEBPdmVycmlkZQogIHB1YmxpYyBDcmVhdGVSb2xlUmVxdWVzdCBjbG9uZSgpIHsKICAgIHJldHVybiAoQ3JlYXRlUm9sZVJlcXVlc3QpIHN1cGVyLmNsb25lKCk7CiAgfQoKfQpQSwMEFAAAAAAAAAAhACypjaP3DQAA9w0AAEgAAABjb20vZ29vZ2xlL2FwaS9zZXJ2aWNlcy9pYW0vdjEvbW9kZWwvQ3JlYXRlU2VydmljZUFjY291bnRLZXlSZXF1ZXN0LmphdmEvKgogKiBDb3B5cmlnaHQgMjAxMCBHb29nbGUgSW5jLgogKgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQKICogaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UKICogaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzCiAqIG9yIGltcGxpZWQuIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMgdW5kZXIKICogdGhlIExpY2Vuc2UuCiAqLwovKgogKiBUaGlzIGNvZGUgd2FzIGdlbmVyYXRlZCBieSBodHRwczovL2dpdGh1Yi5jb20vZ29vZ2xlL2FwaXMtY2xpZW50LWdlbmVyYXRvci8KICogKGJ1aWxkOiAyMDE4LTEwLTA4IDE3OjQ1OjM5IFVUQykKICogb24gMjAyMC0wMy0xOSBhdCAwMTo1Mjo0MSBVVEMgCiAqIE1vZGlmeSBhdCB5b3VyIG93biByaXNrLgogKi8KCnBhY2thZ2UgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuaWFtLnYxLm1vZGVsOwoKLyoqCiAqIFRoZSBzZXJ2aWNlIGFjY291bnQga2V5IGNyZWF0ZSByZXF1ZXN0LgogKgogKiA8cD4gVGhpcyBpcyB0aGUgSmF2YSBkYXRhIG1vZGVsIGNsYXNzIHRoYXQgc3BlY2lmaWVzIGhvdyB0byBwYXJzZS9zZXJpYWxpemUgaW50byB0aGUgSlNPTiB0aGF0IGlzCiAqIHRyYW5zbWl0dGVkIG92ZXIgSFRUUCB3aGVuIHdvcmtpbmcgd2l0aCB0aGUgSWRlbnRpdHkgYW5kIEFjY2VzcyBNYW5hZ2VtZW50IChJQU0pIEFQSS4gRm9yIGEKICogZGV0YWlsZWQgZXhwbGFuYXRpb24gc2VlOgogKiA8YSBocmVmPSJodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9hcGktY2xpZW50LWxpYnJhcnkvamF2YS9nb29nbGUtaHR0cC1qYXZhLWNsaWVudC9qc29uIj5odHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9hcGktY2xpZW50LWxpYnJhcnkvamF2YS9nb29nbGUtaHR0cC1qYXZhLWNsaWVudC9qc29uPC9hPgogKiA8L3A+CiAqCiAqIEBhdXRob3IgR29vZ2xlLCBJbmMuCiAqLwpAU3VwcHJlc3NXYXJuaW5ncygiamF2YWRvYyIpCnB1YmxpYyBmaW5hbCBjbGFzcyBDcmVhdGVTZXJ2aWNlQWNjb3VudEtleVJlcXVlc3QgZXh0ZW5kcyBjb20uZ29vZ2xlLmFwaS5jbGllbnQuanNvbi5HZW5lcmljSnNvbiB7CgogIC8qKgogICAqIFdoaWNoIHR5cGUgb2Yga2V5IGFuZCBhbGdvcml0aG0gdG8gdXNlIGZvciB0aGUga2V5LiBUaGUgZGVmYXVsdCBpcyBjdXJyZW50bHkgYSAySyBSU0Ega2V5LgogICAqIEhvd2V2ZXIgdGhpcyBtYXkgY2hhbmdlIGluIHRoZSBmdXR1cmUuCiAgICogVGhlIHZhbHVlIG1heSBiZSB7QGNvZGUgbnVsbH0uCiAgICovCiAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogIHByaXZhdGUgamF2YS5sYW5nLlN0cmluZyBrZXlBbGdvcml0aG07CgogIC8qKgogICAqIFRoZSBvdXRwdXQgZm9ybWF0IG9mIHRoZSBwcml2YXRlIGtleS4gVGhlIGRlZmF1bHQgdmFsdWUgaXMgYFRZUEVfR09PR0xFX0NSRURFTlRJQUxTX0ZJTEVgLAogICAqIHdoaWNoIGlzIHRoZSBHb29nbGUgQ3JlZGVudGlhbHMgRmlsZSBmb3JtYXQuCiAgICogVGhlIHZhbHVlIG1heSBiZSB7QGNvZGUgbnVsbH0uCiAgICovCiAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogIHByaXZhdGUgamF2YS5sYW5nLlN0cmluZyBwcml2YXRlS2V5VHlwZTsKCiAgLyoqCiAgICogV2hpY2ggdHlwZSBvZiBrZXkgYW5kIGFsZ29yaXRobSB0byB1c2UgZm9yIHRoZSBrZXkuIFRoZSBkZWZhdWx0IGlzIGN1cnJlbnRseSBhIDJLIFJTQSBrZXkuCiAgICogSG93ZXZlciB0aGlzIG1heSBjaGFuZ2UgaW4gdGhlIGZ1dHVyZS4KICAgKiBAcmV0dXJuIHZhbHVlIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldEtleUFsZ29yaXRobSgpIHsKICAgIHJldHVybiBrZXlBbGdvcml0aG07CiAgfQoKICAvKioKICAgKiBXaGljaCB0eXBlIG9mIGtleSBhbmQgYWxnb3JpdGhtIHRvIHVzZSBmb3IgdGhlIGtleS4gVGhlIGRlZmF1bHQgaXMgY3VycmVudGx5IGEgMksgUlNBIGtleS4KICAgKiBIb3dldmVyIHRoaXMgbWF5IGNoYW5nZSBpbiB0aGUgZnV0dXJlLgogICAqIEBwYXJhbSBrZXlBbGdvcml0aG0ga2V5QWxnb3JpdGhtIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBDcmVhdGVTZXJ2aWNlQWNjb3VudEtleVJlcXVlc3Qgc2V0S2V5QWxnb3JpdGhtKGphdmEubGFuZy5TdHJpbmcga2V5QWxnb3JpdGhtKSB7CiAgICB0aGlzLmtleUFsZ29yaXRobSA9IGtleUFsZ29yaXRobTsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgLyoqCiAgICogVGhlIG91dHB1dCBmb3JtYXQgb2YgdGhlIHByaXZhdGUga2V5LiBUaGUgZGVmYXVsdCB2YWx1ZSBpcyBgVFlQRV9HT09HTEVfQ1JFREVOVElBTFNfRklMRWAsCiAgICogd2hpY2ggaXMgdGhlIEdvb2dsZSBDcmVkZW50aWFscyBGaWxlIGZvcm1hdC4KICAgKiBAcmV0dXJuIHZhbHVlIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFByaXZhdGVLZXlUeXBlKCkgewogICAgcmV0dXJuIHByaXZhdGVLZXlUeXBlOwogIH0KCiAgLyoqCiAgICogVGhlIG91dHB1dCBmb3JtYXQgb2YgdGhlIHByaXZhdGUga2V5LiBUaGUgZGVmYXVsdCB2YWx1ZSBpcyBgVFlQRV9HT09HTEVfQ1JFREVOVElBTFNfRklMRWAsCiAgICogd2hpY2ggaXMgdGhlIEdvb2dsZSBDcmVkZW50aWFscyBGaWxlIGZvcm1hdC4KICAgKiBAcGFyYW0gcHJpdmF0ZUtleVR5cGUgcHJpdmF0ZUtleVR5cGUgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIENyZWF0ZVNlcnZpY2VBY2NvdW50S2V5UmVxdWVzdCBzZXRQcml2YXRlS2V5VHlwZShqYXZhLmxhbmcuU3RyaW5nIHByaXZhdGVLZXlUeXBlKSB7CiAgICB0aGlzLnByaXZhdGVLZXlUeXBlID0gcHJpdmF0ZUtleVR5cGU7CiAgICByZXR1cm4gdGhpczsKICB9CgogIEBPdmVycmlkZQogIHB1YmxpYyBDcmVhdGVTZXJ2aWNlQWNjb3VudEtleVJlcXVlc3Qgc2V0KFN0cmluZyBmaWVsZE5hbWUsIE9iamVjdCB2YWx1ZSkgewogICAgcmV0dXJuIChDcmVhdGVTZXJ2aWNlQWNjb3VudEtleVJlcXVlc3QpIHN1cGVyLnNldChmaWVsZE5hbWUsIHZhbHVlKTsKICB9CgogIEBPdmVycmlkZQogIHB1YmxpYyBDcmVhdGVTZXJ2aWNlQWNjb3VudEtleVJlcXVlc3QgY2xvbmUoKSB7CiAgICByZXR1cm4gKENyZWF0ZVNlcnZpY2VBY2NvdW50S2V5UmVxdWVzdCkgc3VwZXIuY2xvbmUoKTsKICB9Cgp9ClBLAwQUAAAAAAAAACEAsenMKTEPAAAxDwAARQAAAGNvbS9nb29nbGUvYXBpL3NlcnZpY2VzL2lhbS92MS9tb2RlbC9DcmVhdGVTZXJ2aWNlQWNjb3VudFJlcXVlc3QuamF2YS8qCiAqIENvcHlyaWdodCAyMDEwIEdvb2dsZSBJbmMuCiAqCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdAogKiBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZQogKiBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3MKICogb3IgaW1wbGllZC4gU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucyB1bmRlcgogKiB0aGUgTGljZW5zZS4KICovCi8qCiAqIFRoaXMgY29kZSB3YXMgZ2VuZXJhdGVkIGJ5IGh0dHBzOi8vZ2l0aHViLmNvbS9nb29nbGUvYXBpcy1jbGllbnQtZ2VuZXJhdG9yLwogKiAoYnVpbGQ6IDIwMTgtMTAtMDggMTc6NDU6MzkgVVRDKQogKiBvbiAyMDIwLTAzLTE5IGF0IDAxOjUyOjQxIFVUQyAKICogTW9kaWZ5IGF0IHlvdXIgb3duIHJpc2suCiAqLwoKcGFja2FnZSBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5pYW0udjEubW9kZWw7CgovKioKICogVGhlIHNlcnZpY2UgYWNjb3VudCBjcmVhdGUgcmVxdWVzdC4KICoKICogPHA+IFRoaXMgaXMgdGhlIEphdmEgZGF0YSBtb2RlbCBjbGFzcyB0aGF0IHNwZWNpZmllcyBob3cgdG8gcGFyc2Uvc2VyaWFsaXplIGludG8gdGhlIEpTT04gdGhhdCBpcwogKiB0cmFuc21pdHRlZCBvdmVyIEhUVFAgd2hlbiB3b3JraW5nIHdpdGggdGhlIElkZW50aXR5IGFuZCBBY2Nlc3MgTWFuYWdlbWVudCAoSUFNKSBBUEkuIEZvciBhCiAqIGRldGFpbGVkIGV4cGxhbmF0aW9uIHNlZToKICogPGEgaHJlZj0iaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vYXBpLWNsaWVudC1saWJyYXJ5L2phdmEvZ29vZ2xlLWh0dHAtamF2YS1jbGllbnQvanNvbiI+aHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vYXBpLWNsaWVudC1saWJyYXJ5L2phdmEvZ29vZ2xlLWh0dHAtamF2YS1jbGllbnQvanNvbjwvYT4KICogPC9wPgogKgogKiBAYXV0aG9yIEdvb2dsZSwgSW5jLgogKi8KQFN1cHByZXNzV2FybmluZ3MoImphdmFkb2MiKQpwdWJsaWMgZmluYWwgY2xhc3MgQ3JlYXRlU2VydmljZUFjY291bnRSZXF1ZXN0IGV4dGVuZHMgY29tLmdvb2dsZS5hcGkuY2xpZW50Lmpzb24uR2VuZXJpY0pzb24gewoKICAvKioKICAgKiBSZXF1aXJlZC4gVGhlIGFjY291bnQgaWQgdGhhdCBpcyB1c2VkIHRvIGdlbmVyYXRlIHRoZSBzZXJ2aWNlIGFjY291bnQgZW1haWwgYWRkcmVzcyBhbmQgYQogICAqIHN0YWJsZSB1bmlxdWUgaWQuIEl0IGlzIHVuaXF1ZSB3aXRoaW4gYSBwcm9qZWN0LCBtdXN0IGJlIDYtMzAgY2hhcmFjdGVycyBsb25nLCBhbmQgbWF0Y2ggdGhlCiAgICogcmVndWxhciBleHByZXNzaW9uIGBbYS16XShbLWEtejAtOV0qW2EtejAtOV0pYCB0byBjb21wbHkgd2l0aCBSRkMxMDM1LgogICAqIFRoZSB2YWx1ZSBtYXkgYmUge0Bjb2RlIG51bGx9LgogICAqLwogIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICBwcml2YXRlIGphdmEubGFuZy5TdHJpbmcgYWNjb3VudElkOwoKICAvKioKICAgKiBUaGUgU2VydmljZUFjY291bnQgcmVzb3VyY2UgdG8gY3JlYXRlLiBDdXJyZW50bHksIG9ubHkgdGhlIGZvbGxvd2luZyB2YWx1ZXMgYXJlIHVzZXIKICAgKiBhc3NpZ25hYmxlOiBgZGlzcGxheV9uYW1lYCBhbmQgYGRlc2NyaXB0aW9uYC4KICAgKiBUaGUgdmFsdWUgbWF5IGJlIHtAY29kZSBudWxsfS4KICAgKi8KICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgcHJpdmF0ZSBTZXJ2aWNlQWNjb3VudCBzZXJ2aWNlQWNjb3VudDsKCiAgLyoqCiAgICogUmVxdWlyZWQuIFRoZSBhY2NvdW50IGlkIHRoYXQgaXMgdXNlZCB0byBnZW5lcmF0ZSB0aGUgc2VydmljZSBhY2NvdW50IGVtYWlsIGFkZHJlc3MgYW5kIGEKICAgKiBzdGFibGUgdW5pcXVlIGlkLiBJdCBpcyB1bmlxdWUgd2l0aGluIGEgcHJvamVjdCwgbXVzdCBiZSA2LTMwIGNoYXJhY3RlcnMgbG9uZywgYW5kIG1hdGNoIHRoZQogICAqIHJlZ3VsYXIgZXhwcmVzc2lvbiBgW2Etel0oWy1hLXowLTldKlthLXowLTldKWAgdG8gY29tcGx5IHdpdGggUkZDMTAzNS4KICAgKiBAcmV0dXJuIHZhbHVlIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldEFjY291bnRJZCgpIHsKICAgIHJldHVybiBhY2NvdW50SWQ7CiAgfQoKICAvKioKICAgKiBSZXF1aXJlZC4gVGhlIGFjY291bnQgaWQgdGhhdCBpcyB1c2VkIHRvIGdlbmVyYXRlIHRoZSBzZXJ2aWNlIGFjY291bnQgZW1haWwgYWRkcmVzcyBhbmQgYQogICAqIHN0YWJsZSB1bmlxdWUgaWQuIEl0IGlzIHVuaXF1ZSB3aXRoaW4gYSBwcm9qZWN0LCBtdXN0IGJlIDYtMzAgY2hhcmFjdGVycyBsb25nLCBhbmQgbWF0Y2ggdGhlCiAgICogcmVndWxhciBleHByZXNzaW9uIGBbYS16XShbLWEtejAtOV0qW2EtejAtOV0pYCB0byBjb21wbHkgd2l0aCBSRkMxMDM1LgogICAqIEBwYXJhbSBhY2NvdW50SWQgYWNjb3VudElkIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBDcmVhdGVTZXJ2aWNlQWNjb3VudFJlcXVlc3Qgc2V0QWNjb3VudElkKGphdmEubGFuZy5TdHJpbmcgYWNjb3VudElkKSB7CiAgICB0aGlzLmFjY291bnRJZCA9IGFjY291bnRJZDsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgLyoqCiAgICogVGhlIFNlcnZpY2VBY2NvdW50IHJlc291cmNlIHRvIGNyZWF0ZS4gQ3VycmVudGx5LCBvbmx5IHRoZSBmb2xsb3dpbmcgdmFsdWVzIGFyZSB1c2VyCiAgICogYXNzaWduYWJsZTogYGRpc3BsYXlfbmFtZWAgYW5kIGBkZXNjcmlwdGlvbmAuCiAgICogQHJldHVybiB2YWx1ZSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgU2VydmljZUFjY291bnQgZ2V0U2VydmljZUFjY291bnQoKSB7CiAgICByZXR1cm4gc2VydmljZUFjY291bnQ7CiAgfQoKICAvKioKICAgKiBUaGUgU2VydmljZUFjY291bnQgcmVzb3VyY2UgdG8gY3JlYXRlLiBDdXJyZW50bHksIG9ubHkgdGhlIGZvbGxvd2luZyB2YWx1ZXMgYXJlIHVzZXIKICAgKiBhc3NpZ25hYmxlOiBgZGlzcGxheV9uYW1lYCBhbmQgYGRlc2NyaXB0aW9uYC4KICAgKiBAcGFyYW0gc2VydmljZUFjY291bnQgc2VydmljZUFjY291bnQgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIENyZWF0ZVNlcnZpY2VBY2NvdW50UmVxdWVzdCBzZXRTZXJ2aWNlQWNjb3VudChTZXJ2aWNlQWNjb3VudCBzZXJ2aWNlQWNjb3VudCkgewogICAgdGhpcy5zZXJ2aWNlQWNjb3VudCA9IHNlcnZpY2VBY2NvdW50OwogICAgcmV0dXJuIHRoaXM7CiAgfQoKICBAT3ZlcnJpZGUKICBwdWJsaWMgQ3JlYXRlU2VydmljZUFjY291bnRSZXF1ZXN0IHNldChTdHJpbmcgZmllbGROYW1lLCBPYmplY3QgdmFsdWUpIHsKICAgIHJldHVybiAoQ3JlYXRlU2VydmljZUFjY291bnRSZXF1ZXN0KSBzdXBlci5zZXQoZmllbGROYW1lLCB2YWx1ZSk7CiAgfQoKICBAT3ZlcnJpZGUKICBwdWJsaWMgQ3JlYXRlU2VydmljZUFjY291bnRSZXF1ZXN0IGNsb25lKCkgewogICAgcmV0dXJuIChDcmVhdGVTZXJ2aWNlQWNjb3VudFJlcXVlc3QpIHN1cGVyLmNsb25lKCk7CiAgfQoKfQpQSwMEFAAAAAAAAAAhAMyFTzi+BgAAvgYAAEYAAABjb20vZ29vZ2xlL2FwaS9zZXJ2aWNlcy9pYW0vdjEvbW9kZWwvRGlzYWJsZVNlcnZpY2VBY2NvdW50UmVxdWVzdC5qYXZhLyoKICogQ29weXJpZ2h0IDIwMTAgR29vZ2xlIEluYy4KICoKICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0CiAqIGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4gWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlCiAqIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcwogKiBvciBpbXBsaWVkLiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zIHVuZGVyCiAqIHRoZSBMaWNlbnNlLgogKi8KLyoKICogVGhpcyBjb2RlIHdhcyBnZW5lcmF0ZWQgYnkgaHR0cHM6Ly9naXRodWIuY29tL2dvb2dsZS9hcGlzLWNsaWVudC1nZW5lcmF0b3IvCiAqIChidWlsZDogMjAxOC0xMC0wOCAxNzo0NTozOSBVVEMpCiAqIG9uIDIwMjAtMDMtMTkgYXQgMDE6NTI6NDEgVVRDIAogKiBNb2RpZnkgYXQgeW91ciBvd24gcmlzay4KICovCgpwYWNrYWdlIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmlhbS52MS5tb2RlbDsKCi8qKgogKiBUaGUgc2VydmljZSBhY2NvdW50IGRpc2FibGUgcmVxdWVzdC4KICoKICogPHA+IFRoaXMgaXMgdGhlIEphdmEgZGF0YSBtb2RlbCBjbGFzcyB0aGF0IHNwZWNpZmllcyBob3cgdG8gcGFyc2Uvc2VyaWFsaXplIGludG8gdGhlIEpTT04gdGhhdCBpcwogKiB0cmFuc21pdHRlZCBvdmVyIEhUVFAgd2hlbiB3b3JraW5nIHdpdGggdGhlIElkZW50aXR5IGFuZCBBY2Nlc3MgTWFuYWdlbWVudCAoSUFNKSBBUEkuIEZvciBhCiAqIGRldGFpbGVkIGV4cGxhbmF0aW9uIHNlZToKICogPGEgaHJlZj0iaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vYXBpLWNsaWVudC1saWJyYXJ5L2phdmEvZ29vZ2xlLWh0dHAtamF2YS1jbGllbnQvanNvbiI+aHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vYXBpLWNsaWVudC1saWJyYXJ5L2phdmEvZ29vZ2xlLWh0dHAtamF2YS1jbGllbnQvanNvbjwvYT4KICogPC9wPgogKgogKiBAYXV0aG9yIEdvb2dsZSwgSW5jLgogKi8KQFN1cHByZXNzV2FybmluZ3MoImphdmFkb2MiKQpwdWJsaWMgZmluYWwgY2xhc3MgRGlzYWJsZVNlcnZpY2VBY2NvdW50UmVxdWVzdCBleHRlbmRzIGNvbS5nb29nbGUuYXBpLmNsaWVudC5qc29uLkdlbmVyaWNKc29uIHsKCiAgQE92ZXJyaWRlCiAgcHVibGljIERpc2FibGVTZXJ2aWNlQWNjb3VudFJlcXVlc3Qgc2V0KFN0cmluZyBmaWVsZE5hbWUsIE9iamVjdCB2YWx1ZSkgewogICAgcmV0dXJuIChEaXNhYmxlU2VydmljZUFjY291bnRSZXF1ZXN0KSBzdXBlci5zZXQoZmllbGROYW1lLCB2YWx1ZSk7CiAgfQoKICBAT3ZlcnJpZGUKICBwdWJsaWMgRGlzYWJsZVNlcnZpY2VBY2NvdW50UmVxdWVzdCBjbG9uZSgpIHsKICAgIHJldHVybiAoRGlzYWJsZVNlcnZpY2VBY2NvdW50UmVxdWVzdCkgc3VwZXIuY2xvbmUoKTsKICB9Cgp9ClBLAwQUAAAAAAAAACEAxPJMm54HAACeBwAALwAAAGNvbS9nb29nbGUvYXBpL3NlcnZpY2VzL2lhbS92MS9tb2RlbC9FbXB0eS5qYXZhLyoKICogQ29weXJpZ2h0IDIwMTAgR29vZ2xlIEluYy4KICoKICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0CiAqIGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4gWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlCiAqIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcwogKiBvciBpbXBsaWVkLiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zIHVuZGVyCiAqIHRoZSBMaWNlbnNlLgogKi8KLyoKICogVGhpcyBjb2RlIHdhcyBnZW5lcmF0ZWQgYnkgaHR0cHM6Ly9naXRodWIuY29tL2dvb2dsZS9hcGlzLWNsaWVudC1nZW5lcmF0b3IvCiAqIChidWlsZDogMjAxOC0xMC0wOCAxNzo0NTozOSBVVEMpCiAqIG9uIDIwMjAtMDMtMTkgYXQgMDE6NTI6NDEgVVRDIAogKiBNb2RpZnkgYXQgeW91ciBvd24gcmlzay4KICovCgpwYWNrYWdlIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmlhbS52MS5tb2RlbDsKCi8qKgogKiBBIGdlbmVyaWMgZW1wdHkgbWVzc2FnZSB0aGF0IHlvdSBjYW4gcmUtdXNlIHRvIGF2b2lkIGRlZmluaW5nIGR1cGxpY2F0ZWQgZW1wdHkgbWVzc2FnZXMgaW4geW91cgogKiBBUElzLiBBIHR5cGljYWwgZXhhbXBsZSBpcyB0byB1c2UgaXQgYXMgdGhlIHJlcXVlc3Qgb3IgdGhlIHJlc3BvbnNlIHR5cGUgb2YgYW4gQVBJIG1ldGhvZC4gRm9yCiAqIGluc3RhbmNlOgogKgogKiAgICAgc2VydmljZSBGb28geyAgICAgICBycGMgQmFyKGdvb2dsZS5wcm90b2J1Zi5FbXB0eSkgcmV0dXJucyAoZ29vZ2xlLnByb3RvYnVmLkVtcHR5KTsgICAgIH0KICoKICogVGhlIEpTT04gcmVwcmVzZW50YXRpb24gZm9yIGBFbXB0eWAgaXMgZW1wdHkgSlNPTiBvYmplY3QgYHt9YC4KICoKICogPHA+IFRoaXMgaXMgdGhlIEphdmEgZGF0YSBtb2RlbCBjbGFzcyB0aGF0IHNwZWNpZmllcyBob3cgdG8gcGFyc2Uvc2VyaWFsaXplIGludG8gdGhlIEpTT04gdGhhdCBpcwogKiB0cmFuc21pdHRlZCBvdmVyIEhUVFAgd2hlbiB3b3JraW5nIHdpdGggdGhlIElkZW50aXR5IGFuZCBBY2Nlc3MgTWFuYWdlbWVudCAoSUFNKSBBUEkuIEZvciBhCiAqIGRldGFpbGVkIGV4cGxhbmF0aW9uIHNlZToKICogPGEgaHJlZj0iaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vYXBpLWNsaWVudC1saWJyYXJ5L2phdmEvZ29vZ2xlLWh0dHAtamF2YS1jbGllbnQvanNvbiI+aHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vYXBpLWNsaWVudC1saWJyYXJ5L2phdmEvZ29vZ2xlLWh0dHAtamF2YS1jbGllbnQvanNvbjwvYT4KICogPC9wPgogKgogKiBAYXV0aG9yIEdvb2dsZSwgSW5jLgogKi8KQFN1cHByZXNzV2FybmluZ3MoImphdmFkb2MiKQpwdWJsaWMgZmluYWwgY2xhc3MgRW1wdHkgZXh0ZW5kcyBjb20uZ29vZ2xlLmFwaS5jbGllbnQuanNvbi5HZW5lcmljSnNvbiB7CgogIEBPdmVycmlkZQogIHB1YmxpYyBFbXB0eSBzZXQoU3RyaW5nIGZpZWxkTmFtZSwgT2JqZWN0IHZhbHVlKSB7CiAgICByZXR1cm4gKEVtcHR5KSBzdXBlci5zZXQoZmllbGROYW1lLCB2YWx1ZSk7CiAgfQoKICBAT3ZlcnJpZGUKICBwdWJsaWMgRW1wdHkgY2xvbmUoKSB7CiAgICByZXR1cm4gKEVtcHR5KSBzdXBlci5jbG9uZSgpOwogIH0KCn0KUEsDBBQAAAAAAAAAIQAaPvikuAYAALgGAABFAAAAY29tL2dvb2dsZS9hcGkvc2VydmljZXMvaWFtL3YxL21vZGVsL0VuYWJsZVNlcnZpY2VBY2NvdW50UmVxdWVzdC5qYXZhLyoKICogQ29weXJpZ2h0IDIwMTAgR29vZ2xlIEluYy4KICoKICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0CiAqIGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4gWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlCiAqIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcwogKiBvciBpbXBsaWVkLiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zIHVuZGVyCiAqIHRoZSBMaWNlbnNlLgogKi8KLyoKICogVGhpcyBjb2RlIHdhcyBnZW5lcmF0ZWQgYnkgaHR0cHM6Ly9naXRodWIuY29tL2dvb2dsZS9hcGlzLWNsaWVudC1nZW5lcmF0b3IvCiAqIChidWlsZDogMjAxOC0xMC0wOCAxNzo0NTozOSBVVEMpCiAqIG9uIDIwMjAtMDMtMTkgYXQgMDE6NTI6NDEgVVRDIAogKiBNb2RpZnkgYXQgeW91ciBvd24gcmlzay4KICovCgpwYWNrYWdlIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmlhbS52MS5tb2RlbDsKCi8qKgogKiBUaGUgc2VydmljZSBhY2NvdW50IGVuYWJsZSByZXF1ZXN0LgogKgogKiA8cD4gVGhpcyBpcyB0aGUgSmF2YSBkYXRhIG1vZGVsIGNsYXNzIHRoYXQgc3BlY2lmaWVzIGhvdyB0byBwYXJzZS9zZXJpYWxpemUgaW50byB0aGUgSlNPTiB0aGF0IGlzCiAqIHRyYW5zbWl0dGVkIG92ZXIgSFRUUCB3aGVuIHdvcmtpbmcgd2l0aCB0aGUgSWRlbnRpdHkgYW5kIEFjY2VzcyBNYW5hZ2VtZW50IChJQU0pIEFQSS4gRm9yIGEKICogZGV0YWlsZWQgZXhwbGFuYXRpb24gc2VlOgogKiA8YSBocmVmPSJodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9hcGktY2xpZW50LWxpYnJhcnkvamF2YS9nb29nbGUtaHR0cC1qYXZhLWNsaWVudC9qc29uIj5odHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9hcGktY2xpZW50LWxpYnJhcnkvamF2YS9nb29nbGUtaHR0cC1qYXZhLWNsaWVudC9qc29uPC9hPgogKiA8L3A+CiAqCiAqIEBhdXRob3IgR29vZ2xlLCBJbmMuCiAqLwpAU3VwcHJlc3NXYXJuaW5ncygiamF2YWRvYyIpCnB1YmxpYyBmaW5hbCBjbGFzcyBFbmFibGVTZXJ2aWNlQWNjb3VudFJlcXVlc3QgZXh0ZW5kcyBjb20uZ29vZ2xlLmFwaS5jbGllbnQuanNvbi5HZW5lcmljSnNvbiB7CgogIEBPdmVycmlkZQogIHB1YmxpYyBFbmFibGVTZXJ2aWNlQWNjb3VudFJlcXVlc3Qgc2V0KFN0cmluZyBmaWVsZE5hbWUsIE9iamVjdCB2YWx1ZSkgewogICAgcmV0dXJuIChFbmFibGVTZXJ2aWNlQWNjb3VudFJlcXVlc3QpIHN1cGVyLnNldChmaWVsZE5hbWUsIHZhbHVlKTsKICB9CgogIEBPdmVycmlkZQogIHB1YmxpYyBFbmFibGVTZXJ2aWNlQWNjb3VudFJlcXVlc3QgY2xvbmUoKSB7CiAgICByZXR1cm4gKEVuYWJsZVNlcnZpY2VBY2NvdW50UmVxdWVzdCkgc3VwZXIuY2xvbmUoKTsKICB9Cgp9ClBLAwQUAAAAAAAAACEAx1I6S3gXAAB4FwAALgAAAGNvbS9nb29nbGUvYXBpL3NlcnZpY2VzL2lhbS92MS9tb2RlbC9FeHByLmphdmEvKgogKiBDb3B5cmlnaHQgMjAxMCBHb29nbGUgSW5jLgogKgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQKICogaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UKICogaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzCiAqIG9yIGltcGxpZWQuIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMgdW5kZXIKICogdGhlIExpY2Vuc2UuCiAqLwovKgogKiBUaGlzIGNvZGUgd2FzIGdlbmVyYXRlZCBieSBodHRwczovL2dpdGh1Yi5jb20vZ29vZ2xlL2FwaXMtY2xpZW50LWdlbmVyYXRvci8KICogKGJ1aWxkOiAyMDE4LTEwLTA4IDE3OjQ1OjM5IFVUQykKICogb24gMjAyMC0wMy0xOSBhdCAwMTo1Mjo0MSBVVEMgCiAqIE1vZGlmeSBhdCB5b3VyIG93biByaXNrLgogKi8KCnBhY2thZ2UgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuaWFtLnYxLm1vZGVsOwoKLyoqCiAqIFJlcHJlc2VudHMgYSB0ZXh0dWFsIGV4cHJlc3Npb24gaW4gdGhlIENvbW1vbiBFeHByZXNzaW9uIExhbmd1YWdlIChDRUwpIHN5bnRheC4gQ0VMIGlzIGEgQy1saWtlCiAqIGV4cHJlc3Npb24gbGFuZ3VhZ2UuIFRoZSBzeW50YXggYW5kIHNlbWFudGljcyBvZiBDRUwgYXJlIGRvY3VtZW50ZWQgYXQgaHR0cHM6Ly9naXRodWIuY29tL2dvb2dsZQogKiAvY2VsLXNwZWMuCiAqCiAqIEV4YW1wbGUgKENvbXBhcmlzb24pOgogKgogKiAgICAgdGl0bGU6ICJTdW1tYXJ5IHNpemUgbGltaXQiICAgICBkZXNjcmlwdGlvbjogIkRldGVybWluZXMgaWYgYSBzdW1tYXJ5IGlzIGxlc3MgdGhhbiAxMDAgY2hhcnMiCiAqIGV4cHJlc3Npb246ICJkb2N1bWVudC5zdW1tYXJ5LnNpemUoKSA8IDEwMCIKICoKICogRXhhbXBsZSAoRXF1YWxpdHkpOgogKgogKiAgICAgdGl0bGU6ICJSZXF1ZXN0b3IgaXMgb3duZXIiICAgICBkZXNjcmlwdGlvbjogIkRldGVybWluZXMgaWYgcmVxdWVzdG9yIGlzIHRoZSBkb2N1bWVudCBvd25lciIKICogZXhwcmVzc2lvbjogImRvY3VtZW50Lm93bmVyID09IHJlcXVlc3QuYXV0aC5jbGFpbXMuZW1haWwiCiAqCiAqIEV4YW1wbGUgKExvZ2ljKToKICoKICogICAgIHRpdGxlOiAiUHVibGljIGRvY3VtZW50cyIgICAgIGRlc2NyaXB0aW9uOiAiRGV0ZXJtaW5lIHdoZXRoZXIgdGhlIGRvY3VtZW50IHNob3VsZCBiZSBwdWJsaWNseQogKiB2aXNpYmxlIiAgICAgZXhwcmVzc2lvbjogImRvY3VtZW50LnR5cGUgIT0gJ3ByaXZhdGUnICYmIGRvY3VtZW50LnR5cGUgIT0gJ2ludGVybmFsJyIKICoKICogRXhhbXBsZSAoRGF0YSBNYW5pcHVsYXRpb24pOgogKgogKiAgICAgdGl0bGU6ICJOb3RpZmljYXRpb24gc3RyaW5nIiAgICAgZGVzY3JpcHRpb246ICJDcmVhdGUgYSBub3RpZmljYXRpb24gc3RyaW5nIHdpdGggYQogKiB0aW1lc3RhbXAuIiAgICAgZXhwcmVzc2lvbjogIidOZXcgbWVzc2FnZSByZWNlaXZlZCBhdCAnICsgc3RyaW5nKGRvY3VtZW50LmNyZWF0ZV90aW1lKSIKICoKICogVGhlIGV4YWN0IHZhcmlhYmxlcyBhbmQgZnVuY3Rpb25zIHRoYXQgbWF5IGJlIHJlZmVyZW5jZWQgd2l0aGluIGFuIGV4cHJlc3Npb24gYXJlIGRldGVybWluZWQgYnkKICogdGhlIHNlcnZpY2UgdGhhdCBldmFsdWF0ZXMgaXQuIFNlZSB0aGUgc2VydmljZSBkb2N1bWVudGF0aW9uIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uLgogKgogKiA8cD4gVGhpcyBpcyB0aGUgSmF2YSBkYXRhIG1vZGVsIGNsYXNzIHRoYXQgc3BlY2lmaWVzIGhvdyB0byBwYXJzZS9zZXJpYWxpemUgaW50byB0aGUgSlNPTiB0aGF0IGlzCiAqIHRyYW5zbWl0dGVkIG92ZXIgSFRUUCB3aGVuIHdvcmtpbmcgd2l0aCB0aGUgSWRlbnRpdHkgYW5kIEFjY2VzcyBNYW5hZ2VtZW50IChJQU0pIEFQSS4gRm9yIGEKICogZGV0YWlsZWQgZXhwbGFuYXRpb24gc2VlOgogKiA8YSBocmVmPSJodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9hcGktY2xpZW50LWxpYnJhcnkvamF2YS9nb29nbGUtaHR0cC1qYXZhLWNsaWVudC9qc29uIj5odHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9hcGktY2xpZW50LWxpYnJhcnkvamF2YS9nb29nbGUtaHR0cC1qYXZhLWNsaWVudC9qc29uPC9hPgogKiA8L3A+CiAqCiAqIEBhdXRob3IgR29vZ2xlLCBJbmMuCiAqLwpAU3VwcHJlc3NXYXJuaW5ncygiamF2YWRvYyIpCnB1YmxpYyBmaW5hbCBjbGFzcyBFeHByIGV4dGVuZHMgY29tLmdvb2dsZS5hcGkuY2xpZW50Lmpzb24uR2VuZXJpY0pzb24gewoKICAvKioKICAgKiBPcHRpb25hbC4gRGVzY3JpcHRpb24gb2YgdGhlIGV4cHJlc3Npb24uIFRoaXMgaXMgYSBsb25nZXIgdGV4dCB3aGljaCBkZXNjcmliZXMgdGhlIGV4cHJlc3Npb24sCiAgICogZS5nLiB3aGVuIGhvdmVyZWQgb3ZlciBpdCBpbiBhIFVJLgogICAqIFRoZSB2YWx1ZSBtYXkgYmUge0Bjb2RlIG51bGx9LgogICAqLwogIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICBwcml2YXRlIGphdmEubGFuZy5TdHJpbmcgZGVzY3JpcHRpb247CgogIC8qKgogICAqIFRleHR1YWwgcmVwcmVzZW50YXRpb24gb2YgYW4gZXhwcmVzc2lvbiBpbiBDb21tb24gRXhwcmVzc2lvbiBMYW5ndWFnZSBzeW50YXguCiAgICogVGhlIHZhbHVlIG1heSBiZSB7QGNvZGUgbnVsbH0uCiAgICovCiAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogIHByaXZhdGUgamF2YS5sYW5nLlN0cmluZyBleHByZXNzaW9uOwoKICAvKioKICAgKiBPcHRpb25hbC4gU3RyaW5nIGluZGljYXRpbmcgdGhlIGxvY2F0aW9uIG9mIHRoZSBleHByZXNzaW9uIGZvciBlcnJvciByZXBvcnRpbmcsIGUuZy4gYSBmaWxlCiAgICogbmFtZSBhbmQgYSBwb3NpdGlvbiBpbiB0aGUgZmlsZS4KICAgKiBUaGUgdmFsdWUgbWF5IGJlIHtAY29kZSBudWxsfS4KICAgKi8KICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgcHJpdmF0ZSBqYXZhLmxhbmcuU3RyaW5nIGxvY2F0aW9uOwoKICAvKioKICAgKiBPcHRpb25hbC4gVGl0bGUgZm9yIHRoZSBleHByZXNzaW9uLCBpLmUuIGEgc2hvcnQgc3RyaW5nIGRlc2NyaWJpbmcgaXRzIHB1cnBvc2UuIFRoaXMgY2FuIGJlCiAgICogdXNlZCBlLmcuIGluIFVJcyB3aGljaCBhbGxvdyB0byBlbnRlciB0aGUgZXhwcmVzc2lvbi4KICAgKiBUaGUgdmFsdWUgbWF5IGJlIHtAY29kZSBudWxsfS4KICAgKi8KICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgcHJpdmF0ZSBqYXZhLmxhbmcuU3RyaW5nIHRpdGxlOwoKICAvKioKICAgKiBPcHRpb25hbC4gRGVzY3JpcHRpb24gb2YgdGhlIGV4cHJlc3Npb24uIFRoaXMgaXMgYSBsb25nZXIgdGV4dCB3aGljaCBkZXNjcmliZXMgdGhlIGV4cHJlc3Npb24sCiAgICogZS5nLiB3aGVuIGhvdmVyZWQgb3ZlciBpdCBpbiBhIFVJLgogICAqIEByZXR1cm4gdmFsdWUgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0RGVzY3JpcHRpb24oKSB7CiAgICByZXR1cm4gZGVzY3JpcHRpb247CiAgfQoKICAvKioKICAgKiBPcHRpb25hbC4gRGVzY3JpcHRpb24gb2YgdGhlIGV4cHJlc3Npb24uIFRoaXMgaXMgYSBsb25nZXIgdGV4dCB3aGljaCBkZXNjcmliZXMgdGhlIGV4cHJlc3Npb24sCiAgICogZS5nLiB3aGVuIGhvdmVyZWQgb3ZlciBpdCBpbiBhIFVJLgogICAqIEBwYXJhbSBkZXNjcmlwdGlvbiBkZXNjcmlwdGlvbiBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgRXhwciBzZXREZXNjcmlwdGlvbihqYXZhLmxhbmcuU3RyaW5nIGRlc2NyaXB0aW9uKSB7CiAgICB0aGlzLmRlc2NyaXB0aW9uID0gZGVzY3JpcHRpb247CiAgICByZXR1cm4gdGhpczsKICB9CgogIC8qKgogICAqIFRleHR1YWwgcmVwcmVzZW50YXRpb24gb2YgYW4gZXhwcmVzc2lvbiBpbiBDb21tb24gRXhwcmVzc2lvbiBMYW5ndWFnZSBzeW50YXguCiAgICogQHJldHVybiB2YWx1ZSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRFeHByZXNzaW9uKCkgewogICAgcmV0dXJuIGV4cHJlc3Npb247CiAgfQoKICAvKioKICAgKiBUZXh0dWFsIHJlcHJlc2VudGF0aW9uIG9mIGFuIGV4cHJlc3Npb24gaW4gQ29tbW9uIEV4cHJlc3Npb24gTGFuZ3VhZ2Ugc3ludGF4LgogICAqIEBwYXJhbSBleHByZXNzaW9uIGV4cHJlc3Npb24gb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIEV4cHIgc2V0RXhwcmVzc2lvbihqYXZhLmxhbmcuU3RyaW5nIGV4cHJlc3Npb24pIHsKICAgIHRoaXMuZXhwcmVzc2lvbiA9IGV4cHJlc3Npb247CiAgICByZXR1cm4gdGhpczsKICB9CgogIC8qKgogICAqIE9wdGlvbmFsLiBTdHJpbmcgaW5kaWNhdGluZyB0aGUgbG9jYXRpb24gb2YgdGhlIGV4cHJlc3Npb24gZm9yIGVycm9yIHJlcG9ydGluZywgZS5nLiBhIGZpbGUKICAgKiBuYW1lIGFuZCBhIHBvc2l0aW9uIGluIHRoZSBmaWxlLgogICAqIEByZXR1cm4gdmFsdWUgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9jYXRpb24oKSB7CiAgICByZXR1cm4gbG9jYXRpb247CiAgfQoKICAvKioKICAgKiBPcHRpb25hbC4gU3RyaW5nIGluZGljYXRpbmcgdGhlIGxvY2F0aW9uIG9mIHRoZSBleHByZXNzaW9uIGZvciBlcnJvciByZXBvcnRpbmcsIGUuZy4gYSBmaWxlCiAgICogbmFtZSBhbmQgYSBwb3NpdGlvbiBpbiB0aGUgZmlsZS4KICAgKiBAcGFyYW0gbG9jYXRpb24gbG9jYXRpb24gb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIEV4cHIgc2V0TG9jYXRpb24oamF2YS5sYW5nLlN0cmluZyBsb2NhdGlvbikgewogICAgdGhpcy5sb2NhdGlvbiA9IGxvY2F0aW9uOwogICAgcmV0dXJuIHRoaXM7CiAgfQoKICAvKioKICAgKiBPcHRpb25hbC4gVGl0bGUgZm9yIHRoZSBleHByZXNzaW9uLCBpLmUuIGEgc2hvcnQgc3RyaW5nIGRlc2NyaWJpbmcgaXRzIHB1cnBvc2UuIFRoaXMgY2FuIGJlCiAgICogdXNlZCBlLmcuIGluIFVJcyB3aGljaCBhbGxvdyB0byBlbnRlciB0aGUgZXhwcmVzc2lvbi4KICAgKiBAcmV0dXJuIHZhbHVlIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFRpdGxlKCkgewogICAgcmV0dXJuIHRpdGxlOwogIH0KCiAgLyoqCiAgICogT3B0aW9uYWwuIFRpdGxlIGZvciB0aGUgZXhwcmVzc2lvbiwgaS5lLiBhIHNob3J0IHN0cmluZyBkZXNjcmliaW5nIGl0cyBwdXJwb3NlLiBUaGlzIGNhbiBiZQogICAqIHVzZWQgZS5nLiBpbiBVSXMgd2hpY2ggYWxsb3cgdG8gZW50ZXIgdGhlIGV4cHJlc3Npb24uCiAgICogQHBhcmFtIHRpdGxlIHRpdGxlIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBFeHByIHNldFRpdGxlKGphdmEubGFuZy5TdHJpbmcgdGl0bGUpIHsKICAgIHRoaXMudGl0bGUgPSB0aXRsZTsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgQE92ZXJyaWRlCiAgcHVibGljIEV4cHIgc2V0KFN0cmluZyBmaWVsZE5hbWUsIE9iamVjdCB2YWx1ZSkgewogICAgcmV0dXJuIChFeHByKSBzdXBlci5zZXQoZmllbGROYW1lLCB2YWx1ZSk7CiAgfQoKICBAT3ZlcnJpZGUKICBwdWJsaWMgRXhwciBjbG9uZSgpIHsKICAgIHJldHVybiAoRXhwcikgc3VwZXIuY2xvbmUoKTsKICB9Cgp9ClBLAwQUAAAAAAAAACEAPOhykRkQAAAZEAAAOwAAAGNvbS9nb29nbGUvYXBpL3NlcnZpY2VzL2lhbS92MS9tb2RlbC9MaW50UG9saWN5UmVxdWVzdC5qYXZhLyoKICogQ29weXJpZ2h0IDIwMTAgR29vZ2xlIEluYy4KICoKICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0CiAqIGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4gWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlCiAqIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcwogKiBvciBpbXBsaWVkLiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zIHVuZGVyCiAqIHRoZSBMaWNlbnNlLgogKi8KLyoKICogVGhpcyBjb2RlIHdhcyBnZW5lcmF0ZWQgYnkgaHR0cHM6Ly9naXRodWIuY29tL2dvb2dsZS9hcGlzLWNsaWVudC1nZW5lcmF0b3IvCiAqIChidWlsZDogMjAxOC0xMC0wOCAxNzo0NTozOSBVVEMpCiAqIG9uIDIwMjAtMDMtMTkgYXQgMDE6NTI6NDEgVVRDIAogKiBNb2RpZnkgYXQgeW91ciBvd24gcmlzay4KICovCgpwYWNrYWdlIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmlhbS52MS5tb2RlbDsKCi8qKgogKiBUaGUgcmVxdWVzdCB0byBsaW50IGEgQ2xvdWQgSUFNIHBvbGljeSBvYmplY3QuCiAqCiAqIDxwPiBUaGlzIGlzIHRoZSBKYXZhIGRhdGEgbW9kZWwgY2xhc3MgdGhhdCBzcGVjaWZpZXMgaG93IHRvIHBhcnNlL3NlcmlhbGl6ZSBpbnRvIHRoZSBKU09OIHRoYXQgaXMKICogdHJhbnNtaXR0ZWQgb3ZlciBIVFRQIHdoZW4gd29ya2luZyB3aXRoIHRoZSBJZGVudGl0eSBhbmQgQWNjZXNzIE1hbmFnZW1lbnQgKElBTSkgQVBJLiBGb3IgYQogKiBkZXRhaWxlZCBleHBsYW5hdGlvbiBzZWU6CiAqIDxhIGhyZWY9Imh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL2FwaS1jbGllbnQtbGlicmFyeS9qYXZhL2dvb2dsZS1odHRwLWphdmEtY2xpZW50L2pzb24iPmh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL2FwaS1jbGllbnQtbGlicmFyeS9qYXZhL2dvb2dsZS1odHRwLWphdmEtY2xpZW50L2pzb248L2E+CiAqIDwvcD4KICoKICogQGF1dGhvciBHb29nbGUsIEluYy4KICovCkBTdXBwcmVzc1dhcm5pbmdzKCJqYXZhZG9jIikKcHVibGljIGZpbmFsIGNsYXNzIExpbnRQb2xpY3lSZXF1ZXN0IGV4dGVuZHMgY29tLmdvb2dsZS5hcGkuY2xpZW50Lmpzb24uR2VuZXJpY0pzb24gewoKICAvKioKICAgKiBnb29nbGUuaWFtLnYxLkJpbmRpbmcuY29uZGl0aW9uIG9iamVjdCB0byBiZSBsaW50ZWQuCiAgICogVGhlIHZhbHVlIG1heSBiZSB7QGNvZGUgbnVsbH0uCiAgICovCiAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogIHByaXZhdGUgRXhwciBjb25kaXRpb247CgogIC8qKgogICAqIFRoZSBmdWxsIHJlc291cmNlIG5hbWUgb2YgdGhlIHBvbGljeSB0aGlzIGxpbnQgcmVxdWVzdCBpcyBhYm91dC4KICAgKgogICAqIFRoZSBuYW1lIGZvbGxvd3MgdGhlIEdvb2dsZSBDbG91ZCBQbGF0Zm9ybSAoR0NQKSByZXNvdXJjZSBmb3JtYXQuIEZvciBleGFtcGxlLCBhIEdDUCBwcm9qZWN0CiAgICogd2l0aCBJRCBgbXktcHJvamVjdGAgd2lsbCBiZSBuYW1lZCBgLy9jbG91ZHJlc291cmNlbWFuYWdlci5nb29nbGVhcGlzLmNvbS9wcm9qZWN0cy9teS1wcm9qZWN0YC4KICAgKgogICAqIFRoZSByZXNvdXJjZSBuYW1lIGlzIG5vdCB1c2VkIHRvIHJlYWQgdGhlIHBvbGljeSBpbnN0YW5jZSBmcm9tIHRoZSBDbG91ZCBJQU0gZGF0YWJhc2UuIFRoZQogICAqIGNhbmRpZGF0ZSBwb2xpY3kgZm9yIGxpbnQgaGFzIHRvIGJlIHByb3ZpZGVkIGluIHRoZSBzYW1lIHJlcXVlc3Qgb2JqZWN0LgogICAqIFRoZSB2YWx1ZSBtYXkgYmUge0Bjb2RlIG51bGx9LgogICAqLwogIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICBwcml2YXRlIGphdmEubGFuZy5TdHJpbmcgZnVsbFJlc291cmNlTmFtZTsKCiAgLyoqCiAgICogZ29vZ2xlLmlhbS52MS5CaW5kaW5nLmNvbmRpdGlvbiBvYmplY3QgdG8gYmUgbGludGVkLgogICAqIEByZXR1cm4gdmFsdWUgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIEV4cHIgZ2V0Q29uZGl0aW9uKCkgewogICAgcmV0dXJuIGNvbmRpdGlvbjsKICB9CgogIC8qKgogICAqIGdvb2dsZS5pYW0udjEuQmluZGluZy5jb25kaXRpb24gb2JqZWN0IHRvIGJlIGxpbnRlZC4KICAgKiBAcGFyYW0gY29uZGl0aW9uIGNvbmRpdGlvbiBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgTGludFBvbGljeVJlcXVlc3Qgc2V0Q29uZGl0aW9uKEV4cHIgY29uZGl0aW9uKSB7CiAgICB0aGlzLmNvbmRpdGlvbiA9IGNvbmRpdGlvbjsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgLyoqCiAgICogVGhlIGZ1bGwgcmVzb3VyY2UgbmFtZSBvZiB0aGUgcG9saWN5IHRoaXMgbGludCByZXF1ZXN0IGlzIGFib3V0LgogICAqCiAgICogVGhlIG5hbWUgZm9sbG93cyB0aGUgR29vZ2xlIENsb3VkIFBsYXRmb3JtIChHQ1ApIHJlc291cmNlIGZvcm1hdC4gRm9yIGV4YW1wbGUsIGEgR0NQIHByb2plY3QKICAgKiB3aXRoIElEIGBteS1wcm9qZWN0YCB3aWxsIGJlIG5hbWVkIGAvL2Nsb3VkcmVzb3VyY2VtYW5hZ2VyLmdvb2dsZWFwaXMuY29tL3Byb2plY3RzL215LXByb2plY3RgLgogICAqCiAgICogVGhlIHJlc291cmNlIG5hbWUgaXMgbm90IHVzZWQgdG8gcmVhZCB0aGUgcG9saWN5IGluc3RhbmNlIGZyb20gdGhlIENsb3VkIElBTSBkYXRhYmFzZS4gVGhlCiAgICogY2FuZGlkYXRlIHBvbGljeSBmb3IgbGludCBoYXMgdG8gYmUgcHJvdmlkZWQgaW4gdGhlIHNhbWUgcmVxdWVzdCBvYmplY3QuCiAgICogQHJldHVybiB2YWx1ZSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRGdWxsUmVzb3VyY2VOYW1lKCkgewogICAgcmV0dXJuIGZ1bGxSZXNvdXJjZU5hbWU7CiAgfQoKICAvKioKICAgKiBUaGUgZnVsbCByZXNvdXJjZSBuYW1lIG9mIHRoZSBwb2xpY3kgdGhpcyBsaW50IHJlcXVlc3QgaXMgYWJvdXQuCiAgICoKICAgKiBUaGUgbmFtZSBmb2xsb3dzIHRoZSBHb29nbGUgQ2xvdWQgUGxhdGZvcm0gKEdDUCkgcmVzb3VyY2UgZm9ybWF0LiBGb3IgZXhhbXBsZSwgYSBHQ1AgcHJvamVjdAogICAqIHdpdGggSUQgYG15LXByb2plY3RgIHdpbGwgYmUgbmFtZWQgYC8vY2xvdWRyZXNvdXJjZW1hbmFnZXIuZ29vZ2xlYXBpcy5jb20vcHJvamVjdHMvbXktcHJvamVjdGAuCiAgICoKICAgKiBUaGUgcmVzb3VyY2UgbmFtZSBpcyBub3QgdXNlZCB0byByZWFkIHRoZSBwb2xpY3kgaW5zdGFuY2UgZnJvbSB0aGUgQ2xvdWQgSUFNIGRhdGFiYXNlLiBUaGUKICAgKiBjYW5kaWRhdGUgcG9saWN5IGZvciBsaW50IGhhcyB0byBiZSBwcm92aWRlZCBpbiB0aGUgc2FtZSByZXF1ZXN0IG9iamVjdC4KICAgKiBAcGFyYW0gZnVsbFJlc291cmNlTmFtZSBmdWxsUmVzb3VyY2VOYW1lIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBMaW50UG9saWN5UmVxdWVzdCBzZXRGdWxsUmVzb3VyY2VOYW1lKGphdmEubGFuZy5TdHJpbmcgZnVsbFJlc291cmNlTmFtZSkgewogICAgdGhpcy5mdWxsUmVzb3VyY2VOYW1lID0gZnVsbFJlc291cmNlTmFtZTsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgQE92ZXJyaWRlCiAgcHVibGljIExpbnRQb2xpY3lSZXF1ZXN0IHNldChTdHJpbmcgZmllbGROYW1lLCBPYmplY3QgdmFsdWUpIHsKICAgIHJldHVybiAoTGludFBvbGljeVJlcXVlc3QpIHN1cGVyLnNldChmaWVsZE5hbWUsIHZhbHVlKTsKICB9CgogIEBPdmVycmlkZQogIHB1YmxpYyBMaW50UG9saWN5UmVxdWVzdCBjbG9uZSgpIHsKICAgIHJldHVybiAoTGludFBvbGljeVJlcXVlc3QpIHN1cGVyLmNsb25lKCk7CiAgfQoKfQpQSwMEFAAAAAAAAAAhANztu3KbCgAAmwoAADwAAABjb20vZ29vZ2xlL2FwaS9zZXJ2aWNlcy9pYW0vdjEvbW9kZWwvTGludFBvbGljeVJlc3BvbnNlLmphdmEvKgogKiBDb3B5cmlnaHQgMjAxMCBHb29nbGUgSW5jLgogKgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQKICogaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UKICogaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzCiAqIG9yIGltcGxpZWQuIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMgdW5kZXIKICogdGhlIExpY2Vuc2UuCiAqLwovKgogKiBUaGlzIGNvZGUgd2FzIGdlbmVyYXRlZCBieSBodHRwczovL2dpdGh1Yi5jb20vZ29vZ2xlL2FwaXMtY2xpZW50LWdlbmVyYXRvci8KICogKGJ1aWxkOiAyMDE4LTEwLTA4IDE3OjQ1OjM5IFVUQykKICogb24gMjAyMC0wMy0xOSBhdCAwMTo1Mjo0MSBVVEMgCiAqIE1vZGlmeSBhdCB5b3VyIG93biByaXNrLgogKi8KCnBhY2thZ2UgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuaWFtLnYxLm1vZGVsOwoKLyoqCiAqIFRoZSByZXNwb25zZSBvZiBhIGxpbnQgb3BlcmF0aW9uLiBBbiBlbXB0eSByZXNwb25zZSBpbmRpY2F0ZXMgdGhlIG9wZXJhdGlvbiB3YXMgYWJsZSB0byBmdWxseQogKiBleGVjdXRlIGFuZCBubyBsaW50IGlzc3VlIHdhcyBmb3VuZC4KICoKICogPHA+IFRoaXMgaXMgdGhlIEphdmEgZGF0YSBtb2RlbCBjbGFzcyB0aGF0IHNwZWNpZmllcyBob3cgdG8gcGFyc2Uvc2VyaWFsaXplIGludG8gdGhlIEpTT04gdGhhdCBpcwogKiB0cmFuc21pdHRlZCBvdmVyIEhUVFAgd2hlbiB3b3JraW5nIHdpdGggdGhlIElkZW50aXR5IGFuZCBBY2Nlc3MgTWFuYWdlbWVudCAoSUFNKSBBUEkuIEZvciBhCiAqIGRldGFpbGVkIGV4cGxhbmF0aW9uIHNlZToKICogPGEgaHJlZj0iaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vYXBpLWNsaWVudC1saWJyYXJ5L2phdmEvZ29vZ2xlLWh0dHAtamF2YS1jbGllbnQvanNvbiI+aHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vYXBpLWNsaWVudC1saWJyYXJ5L2phdmEvZ29vZ2xlLWh0dHAtamF2YS1jbGllbnQvanNvbjwvYT4KICogPC9wPgogKgogKiBAYXV0aG9yIEdvb2dsZSwgSW5jLgogKi8KQFN1cHByZXNzV2FybmluZ3MoImphdmFkb2MiKQpwdWJsaWMgZmluYWwgY2xhc3MgTGludFBvbGljeVJlc3BvbnNlIGV4dGVuZHMgY29tLmdvb2dsZS5hcGkuY2xpZW50Lmpzb24uR2VuZXJpY0pzb24gewoKICAvKioKICAgKiBMaXN0IG9mIGxpbnQgcmVzdWx0cyBzb3J0ZWQgYnkgYHNldmVyaXR5YCBpbiBkZXNjZW5kaW5nIG9yZGVyLgogICAqIFRoZSB2YWx1ZSBtYXkgYmUge0Bjb2RlIG51bGx9LgogICAqLwogIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICBwcml2YXRlIGphdmEudXRpbC5MaXN0PExpbnRSZXN1bHQ+IGxpbnRSZXN1bHRzOwoKICBzdGF0aWMgewogICAgLy8gaGFjayB0byBmb3JjZSBQcm9HdWFyZCB0byBjb25zaWRlciBMaW50UmVzdWx0IHVzZWQsIHNpbmNlIG90aGVyd2lzZSBpdCB3b3VsZCBiZSBzdHJpcHBlZCBvdXQKICAgIC8vIHNlZSBodHRwczovL2dpdGh1Yi5jb20vZ29vZ2xlL2dvb2dsZS1hcGktamF2YS1jbGllbnQvaXNzdWVzLzU0MwogICAgY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuRGF0YS5udWxsT2YoTGludFJlc3VsdC5jbGFzcyk7CiAgfQoKICAvKioKICAgKiBMaXN0IG9mIGxpbnQgcmVzdWx0cyBzb3J0ZWQgYnkgYHNldmVyaXR5YCBpbiBkZXNjZW5kaW5nIG9yZGVyLgogICAqIEByZXR1cm4gdmFsdWUgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIGphdmEudXRpbC5MaXN0PExpbnRSZXN1bHQ+IGdldExpbnRSZXN1bHRzKCkgewogICAgcmV0dXJuIGxpbnRSZXN1bHRzOwogIH0KCiAgLyoqCiAgICogTGlzdCBvZiBsaW50IHJlc3VsdHMgc29ydGVkIGJ5IGBzZXZlcml0eWAgaW4gZGVzY2VuZGluZyBvcmRlci4KICAgKiBAcGFyYW0gbGludFJlc3VsdHMgbGludFJlc3VsdHMgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIExpbnRQb2xpY3lSZXNwb25zZSBzZXRMaW50UmVzdWx0cyhqYXZhLnV0aWwuTGlzdDxMaW50UmVzdWx0PiBsaW50UmVzdWx0cykgewogICAgdGhpcy5saW50UmVzdWx0cyA9IGxpbnRSZXN1bHRzOwogICAgcmV0dXJuIHRoaXM7CiAgfQoKICBAT3ZlcnJpZGUKICBwdWJsaWMgTGludFBvbGljeVJlc3BvbnNlIHNldChTdHJpbmcgZmllbGROYW1lLCBPYmplY3QgdmFsdWUpIHsKICAgIHJldHVybiAoTGludFBvbGljeVJlc3BvbnNlKSBzdXBlci5zZXQoZmllbGROYW1lLCB2YWx1ZSk7CiAgfQoKICBAT3ZlcnJpZGUKICBwdWJsaWMgTGludFBvbGljeVJlc3BvbnNlIGNsb25lKCkgewogICAgcmV0dXJuIChMaW50UG9saWN5UmVzcG9uc2UpIHN1cGVyLmNsb25lKCk7CiAgfQoKfQpQSwMEFAAAAAAAAAAhAIxesnpBGgAAQRoAADQAAABjb20vZ29vZ2xlL2FwaS9zZXJ2aWNlcy9pYW0vdjEvbW9kZWwvTGludFJlc3VsdC5qYXZhLyoKICogQ29weXJpZ2h0IDIwMTAgR29vZ2xlIEluYy4KICoKICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0CiAqIGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4gWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlCiAqIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcwogKiBvciBpbXBsaWVkLiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zIHVuZGVyCiAqIHRoZSBMaWNlbnNlLgogKi8KLyoKICogVGhpcyBjb2RlIHdhcyBnZW5lcmF0ZWQgYnkgaHR0cHM6Ly9naXRodWIuY29tL2dvb2dsZS9hcGlzLWNsaWVudC1nZW5lcmF0b3IvCiAqIChidWlsZDogMjAxOC0xMC0wOCAxNzo0NTozOSBVVEMpCiAqIG9uIDIwMjAtMDMtMTkgYXQgMDE6NTI6NDEgVVRDIAogKiBNb2RpZnkgYXQgeW91ciBvd24gcmlzay4KICovCgpwYWNrYWdlIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmlhbS52MS5tb2RlbDsKCi8qKgogKiBTdHJ1Y3R1cmVkIHJlc3BvbnNlIG9mIGEgc2luZ2xlIHZhbGlkYXRpb24gdW5pdC4KICoKICogPHA+IFRoaXMgaXMgdGhlIEphdmEgZGF0YSBtb2RlbCBjbGFzcyB0aGF0IHNwZWNpZmllcyBob3cgdG8gcGFyc2Uvc2VyaWFsaXplIGludG8gdGhlIEpTT04gdGhhdCBpcwogKiB0cmFuc21pdHRlZCBvdmVyIEhUVFAgd2hlbiB3b3JraW5nIHdpdGggdGhlIElkZW50aXR5IGFuZCBBY2Nlc3MgTWFuYWdlbWVudCAoSUFNKSBBUEkuIEZvciBhCiAqIGRldGFpbGVkIGV4cGxhbmF0aW9uIHNlZToKICogPGEgaHJlZj0iaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vYXBpLWNsaWVudC1saWJyYXJ5L2phdmEvZ29vZ2xlLWh0dHAtamF2YS1jbGllbnQvanNvbiI+aHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vYXBpLWNsaWVudC1saWJyYXJ5L2phdmEvZ29vZ2xlLWh0dHAtamF2YS1jbGllbnQvanNvbjwvYT4KICogPC9wPgogKgogKiBAYXV0aG9yIEdvb2dsZSwgSW5jLgogKi8KQFN1cHByZXNzV2FybmluZ3MoImphdmFkb2MiKQpwdWJsaWMgZmluYWwgY2xhc3MgTGludFJlc3VsdCBleHRlbmRzIGNvbS5nb29nbGUuYXBpLmNsaWVudC5qc29uLkdlbmVyaWNKc29uIHsKCiAgLyoqCiAgICogSHVtYW4gcmVhZGFibGUgZGVidWcgbWVzc2FnZSBhc3NvY2lhdGVkIHdpdGggdGhlIGlzc3VlLgogICAqIFRoZSB2YWx1ZSBtYXkgYmUge0Bjb2RlIG51bGx9LgogICAqLwogIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICBwcml2YXRlIGphdmEubGFuZy5TdHJpbmcgZGVidWdNZXNzYWdlOwoKICAvKioKICAgKiBUaGUgbmFtZSBvZiB0aGUgZmllbGQgZm9yIHdoaWNoIHRoaXMgbGludCByZXN1bHQgaXMgYWJvdXQuCiAgICoKICAgKiBGb3IgbmVzdGVkIG1lc3NhZ2VzIGBmaWVsZF9uYW1lYCBjb25zaXN0cyBvZiBuYW1lcyBvZiB0aGUgZW1iZWRkZWQgZmllbGRzIHNlcGFyYXRlZCBieSBwZXJpb2QKICAgKiBjaGFyYWN0ZXIuIFRoZSB0b3AtbGV2ZWwgcXVhbGlmaWVyIGlzIHRoZSBpbnB1dCBvYmplY3QgdG8gbGludCBpbiB0aGUgcmVxdWVzdC4gRm9yIGV4YW1wbGUsIHRoZQogICAqIGBmaWVsZF9uYW1lYCB2YWx1ZSBgY29uZGl0aW9uLmV4cHJlc3Npb25gIGlkZW50aWZpZXMgYSBsaW50IHJlc3VsdCBmb3IgdGhlIGBleHByZXNzaW9uYCBmaWVsZAogICAqIG9mIHRoZSBwcm92aWRlZCBjb25kaXRpb24uCiAgICogVGhlIHZhbHVlIG1heSBiZSB7QGNvZGUgbnVsbH0uCiAgICovCiAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogIHByaXZhdGUgamF2YS5sYW5nLlN0cmluZyBmaWVsZE5hbWU7CgogIC8qKgogICAqIFRoZSB2YWxpZGF0aW9uIHVuaXQgbGV2ZWwuCiAgICogVGhlIHZhbHVlIG1heSBiZSB7QGNvZGUgbnVsbH0uCiAgICovCiAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogIHByaXZhdGUgamF2YS5sYW5nLlN0cmluZyBsZXZlbDsKCiAgLyoqCiAgICogMC1iYXNlZCBjaGFyYWN0ZXIgcG9zaXRpb24gb2YgcHJvYmxlbWF0aWMgY29uc3RydWN0IHdpdGhpbiB0aGUgb2JqZWN0IGlkZW50aWZpZWQgYnkKICAgKiBgZmllbGRfbmFtZWAuIEN1cnJlbnRseSwgdGhpcyBpcyBwb3B1bGF0ZWQgb25seSBmb3IgY29uZGl0aW9uIGV4cHJlc3Npb24uCiAgICogVGhlIHZhbHVlIG1heSBiZSB7QGNvZGUgbnVsbH0uCiAgICovCiAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogIHByaXZhdGUgamF2YS5sYW5nLkludGVnZXIgbG9jYXRpb25PZmZzZXQ7CgogIC8qKgogICAqIFRoZSB2YWxpZGF0aW9uIHVuaXQgc2V2ZXJpdHkuCiAgICogVGhlIHZhbHVlIG1heSBiZSB7QGNvZGUgbnVsbH0uCiAgICovCiAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogIHByaXZhdGUgamF2YS5sYW5nLlN0cmluZyBzZXZlcml0eTsKCiAgLyoqCiAgICogVGhlIHZhbGlkYXRpb24gdW5pdCBuYW1lLCBmb3IgaW5zdGFuY2UgImxpbnRWYWxpZGF0aW9uVW5pdHMvQ29uZGl0aW9uQ29tcGxleGl0eUNoZWNrIi4KICAgKiBUaGUgdmFsdWUgbWF5IGJlIHtAY29kZSBudWxsfS4KICAgKi8KICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgcHJpdmF0ZSBqYXZhLmxhbmcuU3RyaW5nIHZhbGlkYXRpb25Vbml0TmFtZTsKCiAgLyoqCiAgICogSHVtYW4gcmVhZGFibGUgZGVidWcgbWVzc2FnZSBhc3NvY2lhdGVkIHdpdGggdGhlIGlzc3VlLgogICAqIEByZXR1cm4gdmFsdWUgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0RGVidWdNZXNzYWdlKCkgewogICAgcmV0dXJuIGRlYnVnTWVzc2FnZTsKICB9CgogIC8qKgogICAqIEh1bWFuIHJlYWRhYmxlIGRlYnVnIG1lc3NhZ2UgYXNzb2NpYXRlZCB3aXRoIHRoZSBpc3N1ZS4KICAgKiBAcGFyYW0gZGVidWdNZXNzYWdlIGRlYnVnTWVzc2FnZSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgTGludFJlc3VsdCBzZXREZWJ1Z01lc3NhZ2UoamF2YS5sYW5nLlN0cmluZyBkZWJ1Z01lc3NhZ2UpIHsKICAgIHRoaXMuZGVidWdNZXNzYWdlID0gZGVidWdNZXNzYWdlOwogICAgcmV0dXJuIHRoaXM7CiAgfQoKICAvKioKICAgKiBUaGUgbmFtZSBvZiB0aGUgZmllbGQgZm9yIHdoaWNoIHRoaXMgbGludCByZXN1bHQgaXMgYWJvdXQuCiAgICoKICAgKiBGb3IgbmVzdGVkIG1lc3NhZ2VzIGBmaWVsZF9uYW1lYCBjb25zaXN0cyBvZiBuYW1lcyBvZiB0aGUgZW1iZWRkZWQgZmllbGRzIHNlcGFyYXRlZCBieSBwZXJpb2QKICAgKiBjaGFyYWN0ZXIuIFRoZSB0b3AtbGV2ZWwgcXVhbGlmaWVyIGlzIHRoZSBpbnB1dCBvYmplY3QgdG8gbGludCBpbiB0aGUgcmVxdWVzdC4gRm9yIGV4YW1wbGUsIHRoZQogICAqIGBmaWVsZF9uYW1lYCB2YWx1ZSBgY29uZGl0aW9uLmV4cHJlc3Npb25gIGlkZW50aWZpZXMgYSBsaW50IHJlc3VsdCBmb3IgdGhlIGBleHByZXNzaW9uYCBmaWVsZAogICAqIG9mIHRoZSBwcm92aWRlZCBjb25kaXRpb24uCiAgICogQHJldHVybiB2YWx1ZSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRGaWVsZE5hbWUoKSB7CiAgICByZXR1cm4gZmllbGROYW1lOwogIH0KCiAgLyoqCiAgICogVGhlIG5hbWUgb2YgdGhlIGZpZWxkIGZvciB3aGljaCB0aGlzIGxpbnQgcmVzdWx0IGlzIGFib3V0LgogICAqCiAgICogRm9yIG5lc3RlZCBtZXNzYWdlcyBgZmllbGRfbmFtZWAgY29uc2lzdHMgb2YgbmFtZXMgb2YgdGhlIGVtYmVkZGVkIGZpZWxkcyBzZXBhcmF0ZWQgYnkgcGVyaW9kCiAgICogY2hhcmFjdGVyLiBUaGUgdG9wLWxldmVsIHF1YWxpZmllciBpcyB0aGUgaW5wdXQgb2JqZWN0IHRvIGxpbnQgaW4gdGhlIHJlcXVlc3QuIEZvciBleGFtcGxlLCB0aGUKICAgKiBgZmllbGRfbmFtZWAgdmFsdWUgYGNvbmRpdGlvbi5leHByZXNzaW9uYCBpZGVudGlmaWVzIGEgbGludCByZXN1bHQgZm9yIHRoZSBgZXhwcmVzc2lvbmAgZmllbGQKICAgKiBvZiB0aGUgcHJvdmlkZWQgY29uZGl0aW9uLgogICAqIEBwYXJhbSBmaWVsZE5hbWUgZmllbGROYW1lIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBMaW50UmVzdWx0IHNldEZpZWxkTmFtZShqYXZhLmxhbmcuU3RyaW5nIGZpZWxkTmFtZSkgewogICAgdGhpcy5maWVsZE5hbWUgPSBmaWVsZE5hbWU7CiAgICByZXR1cm4gdGhpczsKICB9CgogIC8qKgogICAqIFRoZSB2YWxpZGF0aW9uIHVuaXQgbGV2ZWwuCiAgICogQHJldHVybiB2YWx1ZSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMZXZlbCgpIHsKICAgIHJldHVybiBsZXZlbDsKICB9CgogIC8qKgogICAqIFRoZSB2YWxpZGF0aW9uIHVuaXQgbGV2ZWwuCiAgICogQHBhcmFtIGxldmVsIGxldmVsIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBMaW50UmVzdWx0IHNldExldmVsKGphdmEubGFuZy5TdHJpbmcgbGV2ZWwpIHsKICAgIHRoaXMubGV2ZWwgPSBsZXZlbDsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgLyoqCiAgICogMC1iYXNlZCBjaGFyYWN0ZXIgcG9zaXRpb24gb2YgcHJvYmxlbWF0aWMgY29uc3RydWN0IHdpdGhpbiB0aGUgb2JqZWN0IGlkZW50aWZpZWQgYnkKICAgKiBgZmllbGRfbmFtZWAuIEN1cnJlbnRseSwgdGhpcyBpcyBwb3B1bGF0ZWQgb25seSBmb3IgY29uZGl0aW9uIGV4cHJlc3Npb24uCiAgICogQHJldHVybiB2YWx1ZSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgamF2YS5sYW5nLkludGVnZXIgZ2V0TG9jYXRpb25PZmZzZXQoKSB7CiAgICByZXR1cm4gbG9jYXRpb25PZmZzZXQ7CiAgfQoKICAvKioKICAgKiAwLWJhc2VkIGNoYXJhY3RlciBwb3NpdGlvbiBvZiBwcm9ibGVtYXRpYyBjb25zdHJ1Y3Qgd2l0aGluIHRoZSBvYmplY3QgaWRlbnRpZmllZCBieQogICAqIGBmaWVsZF9uYW1lYC4gQ3VycmVudGx5LCB0aGlzIGlzIHBvcHVsYXRlZCBvbmx5IGZvciBjb25kaXRpb24gZXhwcmVzc2lvbi4KICAgKiBAcGFyYW0gbG9jYXRpb25PZmZzZXQgbG9jYXRpb25PZmZzZXQgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIExpbnRSZXN1bHQgc2V0TG9jYXRpb25PZmZzZXQoamF2YS5sYW5nLkludGVnZXIgbG9jYXRpb25PZmZzZXQpIHsKICAgIHRoaXMubG9jYXRpb25PZmZzZXQgPSBsb2NhdGlvbk9mZnNldDsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgLyoqCiAgICogVGhlIHZhbGlkYXRpb24gdW5pdCBzZXZlcml0eS4KICAgKiBAcmV0dXJuIHZhbHVlIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFNldmVyaXR5KCkgewogICAgcmV0dXJuIHNldmVyaXR5OwogIH0KCiAgLyoqCiAgICogVGhlIHZhbGlkYXRpb24gdW5pdCBzZXZlcml0eS4KICAgKiBAcGFyYW0gc2V2ZXJpdHkgc2V2ZXJpdHkgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIExpbnRSZXN1bHQgc2V0U2V2ZXJpdHkoamF2YS5sYW5nLlN0cmluZyBzZXZlcml0eSkgewogICAgdGhpcy5zZXZlcml0eSA9IHNldmVyaXR5OwogICAgcmV0dXJuIHRoaXM7CiAgfQoKICAvKioKICAgKiBUaGUgdmFsaWRhdGlvbiB1bml0IG5hbWUsIGZvciBpbnN0YW5jZSAibGludFZhbGlkYXRpb25Vbml0cy9Db25kaXRpb25Db21wbGV4aXR5Q2hlY2siLgogICAqIEByZXR1cm4gdmFsdWUgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0VmFsaWRhdGlvblVuaXROYW1lKCkgewogICAgcmV0dXJuIHZhbGlkYXRpb25Vbml0TmFtZTsKICB9CgogIC8qKgogICAqIFRoZSB2YWxpZGF0aW9uIHVuaXQgbmFtZSwgZm9yIGluc3RhbmNlICJsaW50VmFsaWRhdGlvblVuaXRzL0NvbmRpdGlvbkNvbXBsZXhpdHlDaGVjayIuCiAgICogQHBhcmFtIHZhbGlkYXRpb25Vbml0TmFtZSB2YWxpZGF0aW9uVW5pdE5hbWUgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIExpbnRSZXN1bHQgc2V0VmFsaWRhdGlvblVuaXROYW1lKGphdmEubGFuZy5TdHJpbmcgdmFsaWRhdGlvblVuaXROYW1lKSB7CiAgICB0aGlzLnZhbGlkYXRpb25Vbml0TmFtZSA9IHZhbGlkYXRpb25Vbml0TmFtZTsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgQE92ZXJyaWRlCiAgcHVibGljIExpbnRSZXN1bHQgc2V0KFN0cmluZyBmaWVsZE5hbWUsIE9iamVjdCB2YWx1ZSkgewogICAgcmV0dXJuIChMaW50UmVzdWx0KSBzdXBlci5zZXQoZmllbGROYW1lLCB2YWx1ZSk7CiAgfQoKICBAT3ZlcnJpZGUKICBwdWJsaWMgTGludFJlc3VsdCBjbG9uZSgpIHsKICAgIHJldHVybiAoTGludFJlc3VsdCkgc3VwZXIuY2xvbmUoKTsKICB9Cgp9ClBLAwQUAAAAAAAAACEALmM7zKkLAACpCwAAOwAAAGNvbS9nb29nbGUvYXBpL3NlcnZpY2VzL2lhbS92MS9tb2RlbC9MaXN0Um9sZXNSZXNwb25zZS5qYXZhLyoKICogQ29weXJpZ2h0IDIwMTAgR29vZ2xlIEluYy4KICoKICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0CiAqIGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4gWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlCiAqIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcwogKiBvciBpbXBsaWVkLiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zIHVuZGVyCiAqIHRoZSBMaWNlbnNlLgogKi8KLyoKICogVGhpcyBjb2RlIHdhcyBnZW5lcmF0ZWQgYnkgaHR0cHM6Ly9naXRodWIuY29tL2dvb2dsZS9hcGlzLWNsaWVudC1nZW5lcmF0b3IvCiAqIChidWlsZDogMjAxOC0xMC0wOCAxNzo0NTozOSBVVEMpCiAqIG9uIDIwMjAtMDMtMTkgYXQgMDE6NTI6NDEgVVRDIAogKiBNb2RpZnkgYXQgeW91ciBvd24gcmlzay4KICovCgpwYWNrYWdlIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmlhbS52MS5tb2RlbDsKCi8qKgogKiBUaGUgcmVzcG9uc2UgY29udGFpbmluZyB0aGUgcm9sZXMgZGVmaW5lZCB1bmRlciBhIHJlc291cmNlLgogKgogKiA8cD4gVGhpcyBpcyB0aGUgSmF2YSBkYXRhIG1vZGVsIGNsYXNzIHRoYXQgc3BlY2lmaWVzIGhvdyB0byBwYXJzZS9zZXJpYWxpemUgaW50byB0aGUgSlNPTiB0aGF0IGlzCiAqIHRyYW5zbWl0dGVkIG92ZXIgSFRUUCB3aGVuIHdvcmtpbmcgd2l0aCB0aGUgSWRlbnRpdHkgYW5kIEFjY2VzcyBNYW5hZ2VtZW50IChJQU0pIEFQSS4gRm9yIGEKICogZGV0YWlsZWQgZXhwbGFuYXRpb24gc2VlOgogKiA8YSBocmVmPSJodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9hcGktY2xpZW50LWxpYnJhcnkvamF2YS9nb29nbGUtaHR0cC1qYXZhLWNsaWVudC9qc29uIj5odHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9hcGktY2xpZW50LWxpYnJhcnkvamF2YS9nb29nbGUtaHR0cC1qYXZhLWNsaWVudC9qc29uPC9hPgogKiA8L3A+CiAqCiAqIEBhdXRob3IgR29vZ2xlLCBJbmMuCiAqLwpAU3VwcHJlc3NXYXJuaW5ncygiamF2YWRvYyIpCnB1YmxpYyBmaW5hbCBjbGFzcyBMaXN0Um9sZXNSZXNwb25zZSBleHRlbmRzIGNvbS5nb29nbGUuYXBpLmNsaWVudC5qc29uLkdlbmVyaWNKc29uIHsKCiAgLyoqCiAgICogVG8gcmV0cmlldmUgdGhlIG5leHQgcGFnZSBvZiByZXN1bHRzLCBzZXQgYExpc3RSb2xlc1JlcXVlc3QucGFnZV90b2tlbmAgdG8gdGhpcyB2YWx1ZS4KICAgKiBUaGUgdmFsdWUgbWF5IGJlIHtAY29kZSBudWxsfS4KICAgKi8KICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgcHJpdmF0ZSBqYXZhLmxhbmcuU3RyaW5nIG5leHRQYWdlVG9rZW47CgogIC8qKgogICAqIFRoZSBSb2xlcyBkZWZpbmVkIG9uIHRoaXMgcmVzb3VyY2UuCiAgICogVGhlIHZhbHVlIG1heSBiZSB7QGNvZGUgbnVsbH0uCiAgICovCiAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8Um9sZT4gcm9sZXM7CgogIC8qKgogICAqIFRvIHJldHJpZXZlIHRoZSBuZXh0IHBhZ2Ugb2YgcmVzdWx0cywgc2V0IGBMaXN0Um9sZXNSZXF1ZXN0LnBhZ2VfdG9rZW5gIHRvIHRoaXMgdmFsdWUuCiAgICogQHJldHVybiB2YWx1ZSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXROZXh0UGFnZVRva2VuKCkgewogICAgcmV0dXJuIG5leHRQYWdlVG9rZW47CiAgfQoKICAvKioKICAgKiBUbyByZXRyaWV2ZSB0aGUgbmV4dCBwYWdlIG9mIHJlc3VsdHMsIHNldCBgTGlzdFJvbGVzUmVxdWVzdC5wYWdlX3Rva2VuYCB0byB0aGlzIHZhbHVlLgogICAqIEBwYXJhbSBuZXh0UGFnZVRva2VuIG5leHRQYWdlVG9rZW4gb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIExpc3RSb2xlc1Jlc3BvbnNlIHNldE5leHRQYWdlVG9rZW4oamF2YS5sYW5nLlN0cmluZyBuZXh0UGFnZVRva2VuKSB7CiAgICB0aGlzLm5leHRQYWdlVG9rZW4gPSBuZXh0UGFnZVRva2VuOwogICAgcmV0dXJuIHRoaXM7CiAgfQoKICAvKioKICAgKiBUaGUgUm9sZXMgZGVmaW5lZCBvbiB0aGlzIHJlc291cmNlLgogICAqIEByZXR1cm4gdmFsdWUgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIGphdmEudXRpbC5MaXN0PFJvbGU+IGdldFJvbGVzKCkgewogICAgcmV0dXJuIHJvbGVzOwogIH0KCiAgLyoqCiAgICogVGhlIFJvbGVzIGRlZmluZWQgb24gdGhpcyByZXNvdXJjZS4KICAgKiBAcGFyYW0gcm9sZXMgcm9sZXMgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIExpc3RSb2xlc1Jlc3BvbnNlIHNldFJvbGVzKGphdmEudXRpbC5MaXN0PFJvbGU+IHJvbGVzKSB7CiAgICB0aGlzLnJvbGVzID0gcm9sZXM7CiAgICByZXR1cm4gdGhpczsKICB9CgogIEBPdmVycmlkZQogIHB1YmxpYyBMaXN0Um9sZXNSZXNwb25zZSBzZXQoU3RyaW5nIGZpZWxkTmFtZSwgT2JqZWN0IHZhbHVlKSB7CiAgICByZXR1cm4gKExpc3RSb2xlc1Jlc3BvbnNlKSBzdXBlci5zZXQoZmllbGROYW1lLCB2YWx1ZSk7CiAgfQoKICBAT3ZlcnJpZGUKICBwdWJsaWMgTGlzdFJvbGVzUmVzcG9uc2UgY2xvbmUoKSB7CiAgICByZXR1cm4gKExpc3RSb2xlc1Jlc3BvbnNlKSBzdXBlci5jbG9uZSgpOwogIH0KCn0KUEsDBBQAAAAAAAAAIQDlacaZIAkAACAJAABIAAAAY29tL2dvb2dsZS9hcGkvc2VydmljZXMvaWFtL3YxL21vZGVsL0xpc3RTZXJ2aWNlQWNjb3VudEtleXNSZXNwb25zZS5qYXZhLyoKICogQ29weXJpZ2h0IDIwMTAgR29vZ2xlIEluYy4KICoKICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0CiAqIGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4gWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlCiAqIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcwogKiBvciBpbXBsaWVkLiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zIHVuZGVyCiAqIHRoZSBMaWNlbnNlLgogKi8KLyoKICogVGhpcyBjb2RlIHdhcyBnZW5lcmF0ZWQgYnkgaHR0cHM6Ly9naXRodWIuY29tL2dvb2dsZS9hcGlzLWNsaWVudC1nZW5lcmF0b3IvCiAqIChidWlsZDogMjAxOC0xMC0wOCAxNzo0NTozOSBVVEMpCiAqIG9uIDIwMjAtMDMtMTkgYXQgMDE6NTI6NDEgVVRDIAogKiBNb2RpZnkgYXQgeW91ciBvd24gcmlzay4KICovCgpwYWNrYWdlIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmlhbS52MS5tb2RlbDsKCi8qKgogKiBUaGUgc2VydmljZSBhY2NvdW50IGtleXMgbGlzdCByZXNwb25zZS4KICoKICogPHA+IFRoaXMgaXMgdGhlIEphdmEgZGF0YSBtb2RlbCBjbGFzcyB0aGF0IHNwZWNpZmllcyBob3cgdG8gcGFyc2Uvc2VyaWFsaXplIGludG8gdGhlIEpTT04gdGhhdCBpcwogKiB0cmFuc21pdHRlZCBvdmVyIEhUVFAgd2hlbiB3b3JraW5nIHdpdGggdGhlIElkZW50aXR5IGFuZCBBY2Nlc3MgTWFuYWdlbWVudCAoSUFNKSBBUEkuIEZvciBhCiAqIGRldGFpbGVkIGV4cGxhbmF0aW9uIHNlZToKICogPGEgaHJlZj0iaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vYXBpLWNsaWVudC1saWJyYXJ5L2phdmEvZ29vZ2xlLWh0dHAtamF2YS1jbGllbnQvanNvbiI+aHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vYXBpLWNsaWVudC1saWJyYXJ5L2phdmEvZ29vZ2xlLWh0dHAtamF2YS1jbGllbnQvanNvbjwvYT4KICogPC9wPgogKgogKiBAYXV0aG9yIEdvb2dsZSwgSW5jLgogKi8KQFN1cHByZXNzV2FybmluZ3MoImphdmFkb2MiKQpwdWJsaWMgZmluYWwgY2xhc3MgTGlzdFNlcnZpY2VBY2NvdW50S2V5c1Jlc3BvbnNlIGV4dGVuZHMgY29tLmdvb2dsZS5hcGkuY2xpZW50Lmpzb24uR2VuZXJpY0pzb24gewoKICAvKioKICAgKiBUaGUgcHVibGljIGtleXMgZm9yIHRoZSBzZXJ2aWNlIGFjY291bnQuCiAgICogVGhlIHZhbHVlIG1heSBiZSB7QGNvZGUgbnVsbH0uCiAgICovCiAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8U2VydmljZUFjY291bnRLZXk+IGtleXM7CgogIC8qKgogICAqIFRoZSBwdWJsaWMga2V5cyBmb3IgdGhlIHNlcnZpY2UgYWNjb3VudC4KICAgKiBAcmV0dXJuIHZhbHVlIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxTZXJ2aWNlQWNjb3VudEtleT4gZ2V0S2V5cygpIHsKICAgIHJldHVybiBrZXlzOwogIH0KCiAgLyoqCiAgICogVGhlIHB1YmxpYyBrZXlzIGZvciB0aGUgc2VydmljZSBhY2NvdW50LgogICAqIEBwYXJhbSBrZXlzIGtleXMgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIExpc3RTZXJ2aWNlQWNjb3VudEtleXNSZXNwb25zZSBzZXRLZXlzKGphdmEudXRpbC5MaXN0PFNlcnZpY2VBY2NvdW50S2V5PiBrZXlzKSB7CiAgICB0aGlzLmtleXMgPSBrZXlzOwogICAgcmV0dXJuIHRoaXM7CiAgfQoKICBAT3ZlcnJpZGUKICBwdWJsaWMgTGlzdFNlcnZpY2VBY2NvdW50S2V5c1Jlc3BvbnNlIHNldChTdHJpbmcgZmllbGROYW1lLCBPYmplY3QgdmFsdWUpIHsKICAgIHJldHVybiAoTGlzdFNlcnZpY2VBY2NvdW50S2V5c1Jlc3BvbnNlKSBzdXBlci5zZXQoZmllbGROYW1lLCB2YWx1ZSk7CiAgfQoKICBAT3ZlcnJpZGUKICBwdWJsaWMgTGlzdFNlcnZpY2VBY2NvdW50S2V5c1Jlc3BvbnNlIGNsb25lKCkgewogICAgcmV0dXJuIChMaXN0U2VydmljZUFjY291bnRLZXlzUmVzcG9uc2UpIHN1cGVyLmNsb25lKCk7CiAgfQoKfQpQSwMEFAAAAAAAAAAhAJPlKIUxDQAAMQ0AAEUAAABjb20vZ29vZ2xlL2FwaS9zZXJ2aWNlcy9pYW0vdjEvbW9kZWwvTGlzdFNlcnZpY2VBY2NvdW50c1Jlc3BvbnNlLmphdmEvKgogKiBDb3B5cmlnaHQgMjAxMCBHb29nbGUgSW5jLgogKgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQKICogaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UKICogaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzCiAqIG9yIGltcGxpZWQuIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMgdW5kZXIKICogdGhlIExpY2Vuc2UuCiAqLwovKgogKiBUaGlzIGNvZGUgd2FzIGdlbmVyYXRlZCBieSBodHRwczovL2dpdGh1Yi5jb20vZ29vZ2xlL2FwaXMtY2xpZW50LWdlbmVyYXRvci8KICogKGJ1aWxkOiAyMDE4LTEwLTA4IDE3OjQ1OjM5IFVUQykKICogb24gMjAyMC0wMy0xOSBhdCAwMTo1Mjo0MSBVVEMgCiAqIE1vZGlmeSBhdCB5b3VyIG93biByaXNrLgogKi8KCnBhY2thZ2UgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuaWFtLnYxLm1vZGVsOwoKLyoqCiAqIFRoZSBzZXJ2aWNlIGFjY291bnQgbGlzdCByZXNwb25zZS4KICoKICogPHA+IFRoaXMgaXMgdGhlIEphdmEgZGF0YSBtb2RlbCBjbGFzcyB0aGF0IHNwZWNpZmllcyBob3cgdG8gcGFyc2Uvc2VyaWFsaXplIGludG8gdGhlIEpTT04gdGhhdCBpcwogKiB0cmFuc21pdHRlZCBvdmVyIEhUVFAgd2hlbiB3b3JraW5nIHdpdGggdGhlIElkZW50aXR5IGFuZCBBY2Nlc3MgTWFuYWdlbWVudCAoSUFNKSBBUEkuIEZvciBhCiAqIGRldGFpbGVkIGV4cGxhbmF0aW9uIHNlZToKICogPGEgaHJlZj0iaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vYXBpLWNsaWVudC1saWJyYXJ5L2phdmEvZ29vZ2xlLWh0dHAtamF2YS1jbGllbnQvanNvbiI+aHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vYXBpLWNsaWVudC1saWJyYXJ5L2phdmEvZ29vZ2xlLWh0dHAtamF2YS1jbGllbnQvanNvbjwvYT4KICogPC9wPgogKgogKiBAYXV0aG9yIEdvb2dsZSwgSW5jLgogKi8KQFN1cHByZXNzV2FybmluZ3MoImphdmFkb2MiKQpwdWJsaWMgZmluYWwgY2xhc3MgTGlzdFNlcnZpY2VBY2NvdW50c1Jlc3BvbnNlIGV4dGVuZHMgY29tLmdvb2dsZS5hcGkuY2xpZW50Lmpzb24uR2VuZXJpY0pzb24gewoKICAvKioKICAgKiBUaGUgbGlzdCBvZiBtYXRjaGluZyBzZXJ2aWNlIGFjY291bnRzLgogICAqIFRoZSB2YWx1ZSBtYXkgYmUge0Bjb2RlIG51bGx9LgogICAqLwogIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICBwcml2YXRlIGphdmEudXRpbC5MaXN0PFNlcnZpY2VBY2NvdW50PiBhY2NvdW50czsKCiAgc3RhdGljIHsKICAgIC8vIGhhY2sgdG8gZm9yY2UgUHJvR3VhcmQgdG8gY29uc2lkZXIgU2VydmljZUFjY291bnQgdXNlZCwgc2luY2Ugb3RoZXJ3aXNlIGl0IHdvdWxkIGJlIHN0cmlwcGVkIG91dAogICAgLy8gc2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9nb29nbGUvZ29vZ2xlLWFwaS1qYXZhLWNsaWVudC9pc3N1ZXMvNTQzCiAgICBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5EYXRhLm51bGxPZihTZXJ2aWNlQWNjb3VudC5jbGFzcyk7CiAgfQoKICAvKioKICAgKiBUbyByZXRyaWV2ZSB0aGUgbmV4dCBwYWdlIG9mIHJlc3VsdHMsIHNldCBMaXN0U2VydmljZUFjY291bnRzUmVxdWVzdC5wYWdlX3Rva2VuIHRvIHRoaXMgdmFsdWUuCiAgICogVGhlIHZhbHVlIG1heSBiZSB7QGNvZGUgbnVsbH0uCiAgICovCiAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogIHByaXZhdGUgamF2YS5sYW5nLlN0cmluZyBuZXh0UGFnZVRva2VuOwoKICAvKioKICAgKiBUaGUgbGlzdCBvZiBtYXRjaGluZyBzZXJ2aWNlIGFjY291bnRzLgogICAqIEByZXR1cm4gdmFsdWUgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIGphdmEudXRpbC5MaXN0PFNlcnZpY2VBY2NvdW50PiBnZXRBY2NvdW50cygpIHsKICAgIHJldHVybiBhY2NvdW50czsKICB9CgogIC8qKgogICAqIFRoZSBsaXN0IG9mIG1hdGNoaW5nIHNlcnZpY2UgYWNjb3VudHMuCiAgICogQHBhcmFtIGFjY291bnRzIGFjY291bnRzIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBMaXN0U2VydmljZUFjY291bnRzUmVzcG9uc2Ugc2V0QWNjb3VudHMoamF2YS51dGlsLkxpc3Q8U2VydmljZUFjY291bnQ+IGFjY291bnRzKSB7CiAgICB0aGlzLmFjY291bnRzID0gYWNjb3VudHM7CiAgICByZXR1cm4gdGhpczsKICB9CgogIC8qKgogICAqIFRvIHJldHJpZXZlIHRoZSBuZXh0IHBhZ2Ugb2YgcmVzdWx0cywgc2V0IExpc3RTZXJ2aWNlQWNjb3VudHNSZXF1ZXN0LnBhZ2VfdG9rZW4gdG8gdGhpcyB2YWx1ZS4KICAgKiBAcmV0dXJuIHZhbHVlIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldE5leHRQYWdlVG9rZW4oKSB7CiAgICByZXR1cm4gbmV4dFBhZ2VUb2tlbjsKICB9CgogIC8qKgogICAqIFRvIHJldHJpZXZlIHRoZSBuZXh0IHBhZ2Ugb2YgcmVzdWx0cywgc2V0IExpc3RTZXJ2aWNlQWNjb3VudHNSZXF1ZXN0LnBhZ2VfdG9rZW4gdG8gdGhpcyB2YWx1ZS4KICAgKiBAcGFyYW0gbmV4dFBhZ2VUb2tlbiBuZXh0UGFnZVRva2VuIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBMaXN0U2VydmljZUFjY291bnRzUmVzcG9uc2Ugc2V0TmV4dFBhZ2VUb2tlbihqYXZhLmxhbmcuU3RyaW5nIG5leHRQYWdlVG9rZW4pIHsKICAgIHRoaXMubmV4dFBhZ2VUb2tlbiA9IG5leHRQYWdlVG9rZW47CiAgICByZXR1cm4gdGhpczsKICB9CgogIEBPdmVycmlkZQogIHB1YmxpYyBMaXN0U2VydmljZUFjY291bnRzUmVzcG9uc2Ugc2V0KFN0cmluZyBmaWVsZE5hbWUsIE9iamVjdCB2YWx1ZSkgewogICAgcmV0dXJuIChMaXN0U2VydmljZUFjY291bnRzUmVzcG9uc2UpIHN1cGVyLnNldChmaWVsZE5hbWUsIHZhbHVlKTsKICB9CgogIEBPdmVycmlkZQogIHB1YmxpYyBMaXN0U2VydmljZUFjY291bnRzUmVzcG9uc2UgY2xvbmUoKSB7CiAgICByZXR1cm4gKExpc3RTZXJ2aWNlQWNjb3VudHNSZXNwb25zZSkgc3VwZXIuY2xvbmUoKTsKICB9Cgp9ClBLAwQUAAAAAAAAACEAiHj+TkYKAABGCgAARAAAAGNvbS9nb29nbGUvYXBpL3NlcnZpY2VzL2lhbS92MS9tb2RlbC9QYXRjaFNlcnZpY2VBY2NvdW50UmVxdWVzdC5qYXZhLyoKICogQ29weXJpZ2h0IDIwMTAgR29vZ2xlIEluYy4KICoKICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0CiAqIGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4gWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlCiAqIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcwogKiBvciBpbXBsaWVkLiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zIHVuZGVyCiAqIHRoZSBMaWNlbnNlLgogKi8KLyoKICogVGhpcyBjb2RlIHdhcyBnZW5lcmF0ZWQgYnkgaHR0cHM6Ly9naXRodWIuY29tL2dvb2dsZS9hcGlzLWNsaWVudC1nZW5lcmF0b3IvCiAqIChidWlsZDogMjAxOC0xMC0wOCAxNzo0NTozOSBVVEMpCiAqIG9uIDIwMjAtMDMtMTkgYXQgMDE6NTI6NDEgVVRDIAogKiBNb2RpZnkgYXQgeW91ciBvd24gcmlzay4KICovCgpwYWNrYWdlIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmlhbS52MS5tb2RlbDsKCi8qKgogKiBUaGUgcGF0Y2ggc2VydmljZSBhY2NvdW50IHJlcXVlc3QuCiAqCiAqIDxwPiBUaGlzIGlzIHRoZSBKYXZhIGRhdGEgbW9kZWwgY2xhc3MgdGhhdCBzcGVjaWZpZXMgaG93IHRvIHBhcnNlL3NlcmlhbGl6ZSBpbnRvIHRoZSBKU09OIHRoYXQgaXMKICogdHJhbnNtaXR0ZWQgb3ZlciBIVFRQIHdoZW4gd29ya2luZyB3aXRoIHRoZSBJZGVudGl0eSBhbmQgQWNjZXNzIE1hbmFnZW1lbnQgKElBTSkgQVBJLiBGb3IgYQogKiBkZXRhaWxlZCBleHBsYW5hdGlvbiBzZWU6CiAqIDxhIGhyZWY9Imh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL2FwaS1jbGllbnQtbGlicmFyeS9qYXZhL2dvb2dsZS1odHRwLWphdmEtY2xpZW50L2pzb24iPmh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL2FwaS1jbGllbnQtbGlicmFyeS9qYXZhL2dvb2dsZS1odHRwLWphdmEtY2xpZW50L2pzb248L2E+CiAqIDwvcD4KICoKICogQGF1dGhvciBHb29nbGUsIEluYy4KICovCkBTdXBwcmVzc1dhcm5pbmdzKCJqYXZhZG9jIikKcHVibGljIGZpbmFsIGNsYXNzIFBhdGNoU2VydmljZUFjY291bnRSZXF1ZXN0IGV4dGVuZHMgY29tLmdvb2dsZS5hcGkuY2xpZW50Lmpzb24uR2VuZXJpY0pzb24gewoKICAvKioKICAgKiBUaGUgdmFsdWUgbWF5IGJlIHtAY29kZSBudWxsfS4KICAgKi8KICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgcHJpdmF0ZSBTZXJ2aWNlQWNjb3VudCBzZXJ2aWNlQWNjb3VudDsKCiAgLyoqCiAgICogVGhlIHZhbHVlIG1heSBiZSB7QGNvZGUgbnVsbH0uCiAgICovCiAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogIHByaXZhdGUgU3RyaW5nIHVwZGF0ZU1hc2s7CgogIC8qKgogICAqIEByZXR1cm4gdmFsdWUgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIFNlcnZpY2VBY2NvdW50IGdldFNlcnZpY2VBY2NvdW50KCkgewogICAgcmV0dXJuIHNlcnZpY2VBY2NvdW50OwogIH0KCiAgLyoqCiAgICogQHBhcmFtIHNlcnZpY2VBY2NvdW50IHNlcnZpY2VBY2NvdW50IG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBQYXRjaFNlcnZpY2VBY2NvdW50UmVxdWVzdCBzZXRTZXJ2aWNlQWNjb3VudChTZXJ2aWNlQWNjb3VudCBzZXJ2aWNlQWNjb3VudCkgewogICAgdGhpcy5zZXJ2aWNlQWNjb3VudCA9IHNlcnZpY2VBY2NvdW50OwogICAgcmV0dXJuIHRoaXM7CiAgfQoKICAvKioKICAgKiBAcmV0dXJuIHZhbHVlIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBTdHJpbmcgZ2V0VXBkYXRlTWFzaygpIHsKICAgIHJldHVybiB1cGRhdGVNYXNrOwogIH0KCiAgLyoqCiAgICogQHBhcmFtIHVwZGF0ZU1hc2sgdXBkYXRlTWFzayBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgUGF0Y2hTZXJ2aWNlQWNjb3VudFJlcXVlc3Qgc2V0VXBkYXRlTWFzayhTdHJpbmcgdXBkYXRlTWFzaykgewogICAgdGhpcy51cGRhdGVNYXNrID0gdXBkYXRlTWFzazsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgQE92ZXJyaWRlCiAgcHVibGljIFBhdGNoU2VydmljZUFjY291bnRSZXF1ZXN0IHNldChTdHJpbmcgZmllbGROYW1lLCBPYmplY3QgdmFsdWUpIHsKICAgIHJldHVybiAoUGF0Y2hTZXJ2aWNlQWNjb3VudFJlcXVlc3QpIHN1cGVyLnNldChmaWVsZE5hbWUsIHZhbHVlKTsKICB9CgogIEBPdmVycmlkZQogIHB1YmxpYyBQYXRjaFNlcnZpY2VBY2NvdW50UmVxdWVzdCBjbG9uZSgpIHsKICAgIHJldHVybiAoUGF0Y2hTZXJ2aWNlQWNjb3VudFJlcXVlc3QpIHN1cGVyLmNsb25lKCk7CiAgfQoKfQpQSwMEFAAAAAAAAAAhADzrNCS4GgAAuBoAADQAAABjb20vZ29vZ2xlL2FwaS9zZXJ2aWNlcy9pYW0vdjEvbW9kZWwvUGVybWlzc2lvbi5qYXZhLyoKICogQ29weXJpZ2h0IDIwMTAgR29vZ2xlIEluYy4KICoKICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0CiAqIGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4gWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlCiAqIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcwogKiBvciBpbXBsaWVkLiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zIHVuZGVyCiAqIHRoZSBMaWNlbnNlLgogKi8KLyoKICogVGhpcyBjb2RlIHdhcyBnZW5lcmF0ZWQgYnkgaHR0cHM6Ly9naXRodWIuY29tL2dvb2dsZS9hcGlzLWNsaWVudC1nZW5lcmF0b3IvCiAqIChidWlsZDogMjAxOC0xMC0wOCAxNzo0NTozOSBVVEMpCiAqIG9uIDIwMjAtMDMtMTkgYXQgMDE6NTI6NDEgVVRDIAogKiBNb2RpZnkgYXQgeW91ciBvd24gcmlzay4KICovCgpwYWNrYWdlIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmlhbS52MS5tb2RlbDsKCi8qKgogKiBBIHBlcm1pc3Npb24gd2hpY2ggY2FuIGJlIGluY2x1ZGVkIGJ5IGEgcm9sZS4KICoKICogPHA+IFRoaXMgaXMgdGhlIEphdmEgZGF0YSBtb2RlbCBjbGFzcyB0aGF0IHNwZWNpZmllcyBob3cgdG8gcGFyc2Uvc2VyaWFsaXplIGludG8gdGhlIEpTT04gdGhhdCBpcwogKiB0cmFuc21pdHRlZCBvdmVyIEhUVFAgd2hlbiB3b3JraW5nIHdpdGggdGhlIElkZW50aXR5IGFuZCBBY2Nlc3MgTWFuYWdlbWVudCAoSUFNKSBBUEkuIEZvciBhCiAqIGRldGFpbGVkIGV4cGxhbmF0aW9uIHNlZToKICogPGEgaHJlZj0iaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vYXBpLWNsaWVudC1saWJyYXJ5L2phdmEvZ29vZ2xlLWh0dHAtamF2YS1jbGllbnQvanNvbiI+aHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vYXBpLWNsaWVudC1saWJyYXJ5L2phdmEvZ29vZ2xlLWh0dHAtamF2YS1jbGllbnQvanNvbjwvYT4KICogPC9wPgogKgogKiBAYXV0aG9yIEdvb2dsZSwgSW5jLgogKi8KQFN1cHByZXNzV2FybmluZ3MoImphdmFkb2MiKQpwdWJsaWMgZmluYWwgY2xhc3MgUGVybWlzc2lvbiBleHRlbmRzIGNvbS5nb29nbGUuYXBpLmNsaWVudC5qc29uLkdlbmVyaWNKc29uIHsKCiAgLyoqCiAgICogVGhlIHNlcnZpY2UgQVBJIGFzc29jaWF0ZWQgd2l0aCB0aGUgcGVybWlzc2lvbiBpcyBub3QgZW5hYmxlZC4KICAgKiBUaGUgdmFsdWUgbWF5IGJlIHtAY29kZSBudWxsfS4KICAgKi8KICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgcHJpdmF0ZSBqYXZhLmxhbmcuQm9vbGVhbiBhcGlEaXNhYmxlZDsKCiAgLyoqCiAgICogVGhlIGN1cnJlbnQgY3VzdG9tIHJvbGUgc3VwcG9ydCBsZXZlbC4KICAgKiBUaGUgdmFsdWUgbWF5IGJlIHtAY29kZSBudWxsfS4KICAgKi8KICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgcHJpdmF0ZSBqYXZhLmxhbmcuU3RyaW5nIGN1c3RvbVJvbGVzU3VwcG9ydExldmVsOwoKICAvKioKICAgKiBBIGJyaWVmIGRlc2NyaXB0aW9uIG9mIHdoYXQgdGhpcyBQZXJtaXNzaW9uIGlzIHVzZWQgZm9yLiBUaGlzIHBlcm1pc3Npb24gY2FuIE9OTFkgYmUgdXNlZCBpbgogICAqIHByZWRlZmluZWQgcm9sZXMuCiAgICogVGhlIHZhbHVlIG1heSBiZSB7QGNvZGUgbnVsbH0uCiAgICovCiAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogIHByaXZhdGUgamF2YS5sYW5nLlN0cmluZyBkZXNjcmlwdGlvbjsKCiAgLyoqCiAgICogVGhlIG5hbWUgb2YgdGhpcyBQZXJtaXNzaW9uLgogICAqIFRoZSB2YWx1ZSBtYXkgYmUge0Bjb2RlIG51bGx9LgogICAqLwogIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICBwcml2YXRlIGphdmEubGFuZy5TdHJpbmcgbmFtZTsKCiAgLyoqCiAgICogVGhlIHZhbHVlIG1heSBiZSB7QGNvZGUgbnVsbH0uCiAgICovCiAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogIHByaXZhdGUgamF2YS5sYW5nLkJvb2xlYW4gb25seUluUHJlZGVmaW5lZFJvbGVzOwoKICAvKioKICAgKiBUaGUgcHJlZmVycmVkIG5hbWUgZm9yIHRoaXMgcGVybWlzc2lvbi4gSWYgcHJlc2VudCwgdGhlbiB0aGlzIHBlcm1pc3Npb24gaXMgYW4gYWxpYXMgb2YsIGFuZAogICAqIGVxdWl2YWxlbnQgdG8sIHRoZSBsaXN0ZWQgcHJpbWFyeV9wZXJtaXNzaW9uLgogICAqIFRoZSB2YWx1ZSBtYXkgYmUge0Bjb2RlIG51bGx9LgogICAqLwogIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICBwcml2YXRlIGphdmEubGFuZy5TdHJpbmcgcHJpbWFyeVBlcm1pc3Npb247CgogIC8qKgogICAqIFRoZSBjdXJyZW50IGxhdW5jaCBzdGFnZSBvZiB0aGUgcGVybWlzc2lvbi4KICAgKiBUaGUgdmFsdWUgbWF5IGJlIHtAY29kZSBudWxsfS4KICAgKi8KICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgcHJpdmF0ZSBqYXZhLmxhbmcuU3RyaW5nIHN0YWdlOwoKICAvKioKICAgKiBUaGUgdGl0bGUgb2YgdGhpcyBQZXJtaXNzaW9uLgogICAqIFRoZSB2YWx1ZSBtYXkgYmUge0Bjb2RlIG51bGx9LgogICAqLwogIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICBwcml2YXRlIGphdmEubGFuZy5TdHJpbmcgdGl0bGU7CgogIC8qKgogICAqIFRoZSBzZXJ2aWNlIEFQSSBhc3NvY2lhdGVkIHdpdGggdGhlIHBlcm1pc3Npb24gaXMgbm90IGVuYWJsZWQuCiAgICogQHJldHVybiB2YWx1ZSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgamF2YS5sYW5nLkJvb2xlYW4gZ2V0QXBpRGlzYWJsZWQoKSB7CiAgICByZXR1cm4gYXBpRGlzYWJsZWQ7CiAgfQoKICAvKioKICAgKiBUaGUgc2VydmljZSBBUEkgYXNzb2NpYXRlZCB3aXRoIHRoZSBwZXJtaXNzaW9uIGlzIG5vdCBlbmFibGVkLgogICAqIEBwYXJhbSBhcGlEaXNhYmxlZCBhcGlEaXNhYmxlZCBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgUGVybWlzc2lvbiBzZXRBcGlEaXNhYmxlZChqYXZhLmxhbmcuQm9vbGVhbiBhcGlEaXNhYmxlZCkgewogICAgdGhpcy5hcGlEaXNhYmxlZCA9IGFwaURpc2FibGVkOwogICAgcmV0dXJuIHRoaXM7CiAgfQoKICAvKioKICAgKiBUaGUgY3VycmVudCBjdXN0b20gcm9sZSBzdXBwb3J0IGxldmVsLgogICAqIEByZXR1cm4gdmFsdWUgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0Q3VzdG9tUm9sZXNTdXBwb3J0TGV2ZWwoKSB7CiAgICByZXR1cm4gY3VzdG9tUm9sZXNTdXBwb3J0TGV2ZWw7CiAgfQoKICAvKioKICAgKiBUaGUgY3VycmVudCBjdXN0b20gcm9sZSBzdXBwb3J0IGxldmVsLgogICAqIEBwYXJhbSBjdXN0b21Sb2xlc1N1cHBvcnRMZXZlbCBjdXN0b21Sb2xlc1N1cHBvcnRMZXZlbCBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgUGVybWlzc2lvbiBzZXRDdXN0b21Sb2xlc1N1cHBvcnRMZXZlbChqYXZhLmxhbmcuU3RyaW5nIGN1c3RvbVJvbGVzU3VwcG9ydExldmVsKSB7CiAgICB0aGlzLmN1c3RvbVJvbGVzU3VwcG9ydExldmVsID0gY3VzdG9tUm9sZXNTdXBwb3J0TGV2ZWw7CiAgICByZXR1cm4gdGhpczsKICB9CgogIC8qKgogICAqIEEgYnJpZWYgZGVzY3JpcHRpb24gb2Ygd2hhdCB0aGlzIFBlcm1pc3Npb24gaXMgdXNlZCBmb3IuIFRoaXMgcGVybWlzc2lvbiBjYW4gT05MWSBiZSB1c2VkIGluCiAgICogcHJlZGVmaW5lZCByb2xlcy4KICAgKiBAcmV0dXJuIHZhbHVlIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldERlc2NyaXB0aW9uKCkgewogICAgcmV0dXJuIGRlc2NyaXB0aW9uOwogIH0KCiAgLyoqCiAgICogQSBicmllZiBkZXNjcmlwdGlvbiBvZiB3aGF0IHRoaXMgUGVybWlzc2lvbiBpcyB1c2VkIGZvci4gVGhpcyBwZXJtaXNzaW9uIGNhbiBPTkxZIGJlIHVzZWQgaW4KICAgKiBwcmVkZWZpbmVkIHJvbGVzLgogICAqIEBwYXJhbSBkZXNjcmlwdGlvbiBkZXNjcmlwdGlvbiBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgUGVybWlzc2lvbiBzZXREZXNjcmlwdGlvbihqYXZhLmxhbmcuU3RyaW5nIGRlc2NyaXB0aW9uKSB7CiAgICB0aGlzLmRlc2NyaXB0aW9uID0gZGVzY3JpcHRpb247CiAgICByZXR1cm4gdGhpczsKICB9CgogIC8qKgogICAqIFRoZSBuYW1lIG9mIHRoaXMgUGVybWlzc2lvbi4KICAgKiBAcmV0dXJuIHZhbHVlIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldE5hbWUoKSB7CiAgICByZXR1cm4gbmFtZTsKICB9CgogIC8qKgogICAqIFRoZSBuYW1lIG9mIHRoaXMgUGVybWlzc2lvbi4KICAgKiBAcGFyYW0gbmFtZSBuYW1lIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBQZXJtaXNzaW9uIHNldE5hbWUoamF2YS5sYW5nLlN0cmluZyBuYW1lKSB7CiAgICB0aGlzLm5hbWUgPSBuYW1lOwogICAgcmV0dXJuIHRoaXM7CiAgfQoKICAvKioKICAgKiBAcmV0dXJuIHZhbHVlIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBqYXZhLmxhbmcuQm9vbGVhbiBnZXRPbmx5SW5QcmVkZWZpbmVkUm9sZXMoKSB7CiAgICByZXR1cm4gb25seUluUHJlZGVmaW5lZFJvbGVzOwogIH0KCiAgLyoqCiAgICogQHBhcmFtIG9ubHlJblByZWRlZmluZWRSb2xlcyBvbmx5SW5QcmVkZWZpbmVkUm9sZXMgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIFBlcm1pc3Npb24gc2V0T25seUluUHJlZGVmaW5lZFJvbGVzKGphdmEubGFuZy5Cb29sZWFuIG9ubHlJblByZWRlZmluZWRSb2xlcykgewogICAgdGhpcy5vbmx5SW5QcmVkZWZpbmVkUm9sZXMgPSBvbmx5SW5QcmVkZWZpbmVkUm9sZXM7CiAgICByZXR1cm4gdGhpczsKICB9CgogIC8qKgogICAqIFRoZSBwcmVmZXJyZWQgbmFtZSBmb3IgdGhpcyBwZXJtaXNzaW9uLiBJZiBwcmVzZW50LCB0aGVuIHRoaXMgcGVybWlzc2lvbiBpcyBhbiBhbGlhcyBvZiwgYW5kCiAgICogZXF1aXZhbGVudCB0bywgdGhlIGxpc3RlZCBwcmltYXJ5X3Blcm1pc3Npb24uCiAgICogQHJldHVybiB2YWx1ZSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRQcmltYXJ5UGVybWlzc2lvbigpIHsKICAgIHJldHVybiBwcmltYXJ5UGVybWlzc2lvbjsKICB9CgogIC8qKgogICAqIFRoZSBwcmVmZXJyZWQgbmFtZSBmb3IgdGhpcyBwZXJtaXNzaW9uLiBJZiBwcmVzZW50LCB0aGVuIHRoaXMgcGVybWlzc2lvbiBpcyBhbiBhbGlhcyBvZiwgYW5kCiAgICogZXF1aXZhbGVudCB0bywgdGhlIGxpc3RlZCBwcmltYXJ5X3Blcm1pc3Npb24uCiAgICogQHBhcmFtIHByaW1hcnlQZXJtaXNzaW9uIHByaW1hcnlQZXJtaXNzaW9uIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBQZXJtaXNzaW9uIHNldFByaW1hcnlQZXJtaXNzaW9uKGphdmEubGFuZy5TdHJpbmcgcHJpbWFyeVBlcm1pc3Npb24pIHsKICAgIHRoaXMucHJpbWFyeVBlcm1pc3Npb24gPSBwcmltYXJ5UGVybWlzc2lvbjsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgLyoqCiAgICogVGhlIGN1cnJlbnQgbGF1bmNoIHN0YWdlIG9mIHRoZSBwZXJtaXNzaW9uLgogICAqIEByZXR1cm4gdmFsdWUgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0U3RhZ2UoKSB7CiAgICByZXR1cm4gc3RhZ2U7CiAgfQoKICAvKioKICAgKiBUaGUgY3VycmVudCBsYXVuY2ggc3RhZ2Ugb2YgdGhlIHBlcm1pc3Npb24uCiAgICogQHBhcmFtIHN0YWdlIHN0YWdlIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBQZXJtaXNzaW9uIHNldFN0YWdlKGphdmEubGFuZy5TdHJpbmcgc3RhZ2UpIHsKICAgIHRoaXMuc3RhZ2UgPSBzdGFnZTsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgLyoqCiAgICogVGhlIHRpdGxlIG9mIHRoaXMgUGVybWlzc2lvbi4KICAgKiBAcmV0dXJuIHZhbHVlIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFRpdGxlKCkgewogICAgcmV0dXJuIHRpdGxlOwogIH0KCiAgLyoqCiAgICogVGhlIHRpdGxlIG9mIHRoaXMgUGVybWlzc2lvbi4KICAgKiBAcGFyYW0gdGl0bGUgdGl0bGUgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIFBlcm1pc3Npb24gc2V0VGl0bGUoamF2YS5sYW5nLlN0cmluZyB0aXRsZSkgewogICAgdGhpcy50aXRsZSA9IHRpdGxlOwogICAgcmV0dXJuIHRoaXM7CiAgfQoKICBAT3ZlcnJpZGUKICBwdWJsaWMgUGVybWlzc2lvbiBzZXQoU3RyaW5nIGZpZWxkTmFtZSwgT2JqZWN0IHZhbHVlKSB7CiAgICByZXR1cm4gKFBlcm1pc3Npb24pIHN1cGVyLnNldChmaWVsZE5hbWUsIHZhbHVlKTsKICB9CgogIEBPdmVycmlkZQogIHB1YmxpYyBQZXJtaXNzaW9uIGNsb25lKCkgewogICAgcmV0dXJuIChQZXJtaXNzaW9uKSBzdXBlci5jbG9uZSgpOwogIH0KCn0KUEsDBBQAAAAAAAAAIQAENAWNqwsAAKsLAAA5AAAAY29tL2dvb2dsZS9hcGkvc2VydmljZXMvaWFtL3YxL21vZGVsL1Blcm1pc3Npb25EZWx0YS5qYXZhLyoKICogQ29weXJpZ2h0IDIwMTAgR29vZ2xlIEluYy4KICoKICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0CiAqIGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4gWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlCiAqIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcwogKiBvciBpbXBsaWVkLiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zIHVuZGVyCiAqIHRoZSBMaWNlbnNlLgogKi8KLyoKICogVGhpcyBjb2RlIHdhcyBnZW5lcmF0ZWQgYnkgaHR0cHM6Ly9naXRodWIuY29tL2dvb2dsZS9hcGlzLWNsaWVudC1nZW5lcmF0b3IvCiAqIChidWlsZDogMjAxOC0xMC0wOCAxNzo0NTozOSBVVEMpCiAqIG9uIDIwMjAtMDMtMTkgYXQgMDE6NTI6NDEgVVRDIAogKiBNb2RpZnkgYXQgeW91ciBvd24gcmlzay4KICovCgpwYWNrYWdlIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmlhbS52MS5tb2RlbDsKCi8qKgogKiBBIFBlcm1pc3Npb25EZWx0YSBtZXNzYWdlIHRvIHJlY29yZCB0aGUgYWRkZWRfcGVybWlzc2lvbnMgYW5kIHJlbW92ZWRfcGVybWlzc2lvbnMgaW5zaWRlIGEgcm9sZS4KICoKICogPHA+IFRoaXMgaXMgdGhlIEphdmEgZGF0YSBtb2RlbCBjbGFzcyB0aGF0IHNwZWNpZmllcyBob3cgdG8gcGFyc2Uvc2VyaWFsaXplIGludG8gdGhlIEpTT04gdGhhdCBpcwogKiB0cmFuc21pdHRlZCBvdmVyIEhUVFAgd2hlbiB3b3JraW5nIHdpdGggdGhlIElkZW50aXR5IGFuZCBBY2Nlc3MgTWFuYWdlbWVudCAoSUFNKSBBUEkuIEZvciBhCiAqIGRldGFpbGVkIGV4cGxhbmF0aW9uIHNlZToKICogPGEgaHJlZj0iaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vYXBpLWNsaWVudC1saWJyYXJ5L2phdmEvZ29vZ2xlLWh0dHAtamF2YS1jbGllbnQvanNvbiI+aHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vYXBpLWNsaWVudC1saWJyYXJ5L2phdmEvZ29vZ2xlLWh0dHAtamF2YS1jbGllbnQvanNvbjwvYT4KICogPC9wPgogKgogKiBAYXV0aG9yIEdvb2dsZSwgSW5jLgogKi8KQFN1cHByZXNzV2FybmluZ3MoImphdmFkb2MiKQpwdWJsaWMgZmluYWwgY2xhc3MgUGVybWlzc2lvbkRlbHRhIGV4dGVuZHMgY29tLmdvb2dsZS5hcGkuY2xpZW50Lmpzb24uR2VuZXJpY0pzb24gewoKICAvKioKICAgKiBBZGRlZCBwZXJtaXNzaW9ucy4KICAgKiBUaGUgdmFsdWUgbWF5IGJlIHtAY29kZSBudWxsfS4KICAgKi8KICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuU3RyaW5nPiBhZGRlZFBlcm1pc3Npb25zOwoKICAvKioKICAgKiBSZW1vdmVkIHBlcm1pc3Npb25zLgogICAqIFRoZSB2YWx1ZSBtYXkgYmUge0Bjb2RlIG51bGx9LgogICAqLwogIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICBwcml2YXRlIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5TdHJpbmc+IHJlbW92ZWRQZXJtaXNzaW9uczsKCiAgLyoqCiAgICogQWRkZWQgcGVybWlzc2lvbnMuCiAgICogQHJldHVybiB2YWx1ZSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLlN0cmluZz4gZ2V0QWRkZWRQZXJtaXNzaW9ucygpIHsKICAgIHJldHVybiBhZGRlZFBlcm1pc3Npb25zOwogIH0KCiAgLyoqCiAgICogQWRkZWQgcGVybWlzc2lvbnMuCiAgICogQHBhcmFtIGFkZGVkUGVybWlzc2lvbnMgYWRkZWRQZXJtaXNzaW9ucyBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgUGVybWlzc2lvbkRlbHRhIHNldEFkZGVkUGVybWlzc2lvbnMoamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLlN0cmluZz4gYWRkZWRQZXJtaXNzaW9ucykgewogICAgdGhpcy5hZGRlZFBlcm1pc3Npb25zID0gYWRkZWRQZXJtaXNzaW9uczsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgLyoqCiAgICogUmVtb3ZlZCBwZXJtaXNzaW9ucy4KICAgKiBAcmV0dXJuIHZhbHVlIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuU3RyaW5nPiBnZXRSZW1vdmVkUGVybWlzc2lvbnMoKSB7CiAgICByZXR1cm4gcmVtb3ZlZFBlcm1pc3Npb25zOwogIH0KCiAgLyoqCiAgICogUmVtb3ZlZCBwZXJtaXNzaW9ucy4KICAgKiBAcGFyYW0gcmVtb3ZlZFBlcm1pc3Npb25zIHJlbW92ZWRQZXJtaXNzaW9ucyBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgUGVybWlzc2lvbkRlbHRhIHNldFJlbW92ZWRQZXJtaXNzaW9ucyhqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuU3RyaW5nPiByZW1vdmVkUGVybWlzc2lvbnMpIHsKICAgIHRoaXMucmVtb3ZlZFBlcm1pc3Npb25zID0gcmVtb3ZlZFBlcm1pc3Npb25zOwogICAgcmV0dXJuIHRoaXM7CiAgfQoKICBAT3ZlcnJpZGUKICBwdWJsaWMgUGVybWlzc2lvbkRlbHRhIHNldChTdHJpbmcgZmllbGROYW1lLCBPYmplY3QgdmFsdWUpIHsKICAgIHJldHVybiAoUGVybWlzc2lvbkRlbHRhKSBzdXBlci5zZXQoZmllbGROYW1lLCB2YWx1ZSk7CiAgfQoKICBAT3ZlcnJpZGUKICBwdWJsaWMgUGVybWlzc2lvbkRlbHRhIGNsb25lKCkgewogICAgcmV0dXJuIChQZXJtaXNzaW9uRGVsdGEpIHN1cGVyLmNsb25lKCk7CiAgfQoKfQpQSwMEFAAAAAAAAAAhAHxUODuUNgAAlDYAADAAAABjb20vZ29vZ2xlL2FwaS9zZXJ2aWNlcy9pYW0vdjEvbW9kZWwvUG9saWN5LmphdmEvKgogKiBDb3B5cmlnaHQgMjAxMCBHb29nbGUgSW5jLgogKgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQKICogaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UKICogaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzCiAqIG9yIGltcGxpZWQuIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMgdW5kZXIKICogdGhlIExpY2Vuc2UuCiAqLwovKgogKiBUaGlzIGNvZGUgd2FzIGdlbmVyYXRlZCBieSBodHRwczovL2dpdGh1Yi5jb20vZ29vZ2xlL2FwaXMtY2xpZW50LWdlbmVyYXRvci8KICogKGJ1aWxkOiAyMDE4LTEwLTA4IDE3OjQ1OjM5IFVUQykKICogb24gMjAyMC0wMy0xOSBhdCAwMTo1Mjo0MSBVVEMgCiAqIE1vZGlmeSBhdCB5b3VyIG93biByaXNrLgogKi8KCnBhY2thZ2UgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuaWFtLnYxLm1vZGVsOwoKLyoqCiAqIEFuIElkZW50aXR5IGFuZCBBY2Nlc3MgTWFuYWdlbWVudCAoSUFNKSBwb2xpY3ksIHdoaWNoIHNwZWNpZmllcyBhY2Nlc3MgY29udHJvbHMgZm9yIEdvb2dsZSBDbG91ZAogKiByZXNvdXJjZXMuCiAqCiAqIEEgYFBvbGljeWAgaXMgYSBjb2xsZWN0aW9uIG9mIGBiaW5kaW5nc2AuIEEgYGJpbmRpbmdgIGJpbmRzIG9uZSBvciBtb3JlIGBtZW1iZXJzYCB0byBhIHNpbmdsZQogKiBgcm9sZWAuIE1lbWJlcnMgY2FuIGJlIHVzZXIgYWNjb3VudHMsIHNlcnZpY2UgYWNjb3VudHMsIEdvb2dsZSBncm91cHMsIGFuZCBkb21haW5zIChzdWNoIGFzIEcKICogU3VpdGUpLiBBIGByb2xlYCBpcyBhIG5hbWVkIGxpc3Qgb2YgcGVybWlzc2lvbnM7IGVhY2ggYHJvbGVgIGNhbiBiZSBhbiBJQU0gcHJlZGVmaW5lZCByb2xlIG9yIGEKICogdXNlci1jcmVhdGVkIGN1c3RvbSByb2xlLgogKgogKiBPcHRpb25hbGx5LCBhIGBiaW5kaW5nYCBjYW4gc3BlY2lmeSBhIGBjb25kaXRpb25gLCB3aGljaCBpcyBhIGxvZ2ljYWwgZXhwcmVzc2lvbiB0aGF0IGFsbG93cwogKiBhY2Nlc3MgdG8gYSByZXNvdXJjZSBvbmx5IGlmIHRoZSBleHByZXNzaW9uIGV2YWx1YXRlcyB0byBgdHJ1ZWAuIEEgY29uZGl0aW9uIGNhbiBhZGQgY29uc3RyYWludHMKICogYmFzZWQgb24gYXR0cmlidXRlcyBvZiB0aGUgcmVxdWVzdCwgdGhlIHJlc291cmNlLCBvciBib3RoLgogKgogKiAqKkpTT04gZXhhbXBsZToqKgogKgogKiAgICAgeyAgICAgICAiYmluZGluZ3MiOiBbICAgICAgICAgeyAgICAgICAgICAgInJvbGUiOiAicm9sZXMvcmVzb3VyY2VtYW5hZ2VyLm9yZ2FuaXphdGlvbkFkbWluIiwKICogIm1lbWJlcnMiOiBbICAgICAgICAgICAgICJ1c2VyOm1pa2VAZXhhbXBsZS5jb20iLCAgICAgICAgICAgICAiZ3JvdXA6YWRtaW5zQGV4YW1wbGUuY29tIiwKICogImRvbWFpbjpnb29nbGUuY29tIiwgICAgICAgICAgICAgInNlcnZpY2VBY2NvdW50Om15LXByb2plY3QtaWRAYXBwc3BvdC5nc2VydmljZWFjY291bnQuY29tIgogKiBdICAgICAgICAgfSwgICAgICAgICB7ICAgICAgICAgICAicm9sZSI6ICJyb2xlcy9yZXNvdXJjZW1hbmFnZXIub3JnYW5pemF0aW9uVmlld2VyIiwKICogIm1lbWJlcnMiOiBbInVzZXI6ZXZlQGV4YW1wbGUuY29tIl0sICAgICAgICAgICAiY29uZGl0aW9uIjogeyAgICAgICAgICAgICAidGl0bGUiOiAiZXhwaXJhYmxlCiAqIGFjY2VzcyIsICAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJEb2VzIG5vdCBncmFudCBhY2Nlc3MgYWZ0ZXIgU2VwIDIwMjAiLAogKiAiZXhwcmVzc2lvbiI6ICJyZXF1ZXN0LnRpbWUgPCB0aW1lc3RhbXAoJzIwMjAtMTAtMDFUMDA6MDA6MDAuMDAwWicpIiwgICAgICAgICAgIH0gICAgICAgICB9CiAqIF0sICAgICAgICJldGFnIjogIkJ3V1dqYTBZZkpBPSIsICAgICAgICJ2ZXJzaW9uIjogMyAgICAgfQogKgogKiAqKllBTUwgZXhhbXBsZToqKgogKgogKiAgICAgYmluZGluZ3M6ICAgICAtIG1lbWJlcnM6ICAgICAgIC0gdXNlcjptaWtlQGV4YW1wbGUuY29tICAgICAgIC0gZ3JvdXA6YWRtaW5zQGV4YW1wbGUuY29tCiAqIC0gZG9tYWluOmdvb2dsZS5jb20gICAgICAgLSBzZXJ2aWNlQWNjb3VudDpteS1wcm9qZWN0LWlkQGFwcHNwb3QuZ3NlcnZpY2VhY2NvdW50LmNvbSAgICAgICByb2xlOgogKiByb2xlcy9yZXNvdXJjZW1hbmFnZXIub3JnYW5pemF0aW9uQWRtaW4gICAgIC0gbWVtYmVyczogICAgICAgLSB1c2VyOmV2ZUBleGFtcGxlLmNvbSAgICAgICByb2xlOgogKiByb2xlcy9yZXNvdXJjZW1hbmFnZXIub3JnYW5pemF0aW9uVmlld2VyICAgICAgIGNvbmRpdGlvbjogICAgICAgICB0aXRsZTogZXhwaXJhYmxlIGFjY2VzcwogKiBkZXNjcmlwdGlvbjogRG9lcyBub3QgZ3JhbnQgYWNjZXNzIGFmdGVyIFNlcCAyMDIwICAgICAgICAgZXhwcmVzc2lvbjogcmVxdWVzdC50aW1lIDwKICogdGltZXN0YW1wKCcyMDIwLTEwLTAxVDAwOjAwOjAwLjAwMFonKSAgICAgLSBldGFnOiBCd1dXamEwWWZKQT0gICAgIC0gdmVyc2lvbjogMwogKgogKiBGb3IgYSBkZXNjcmlwdGlvbiBvZiBJQU0gYW5kIGl0cyBmZWF0dXJlcywgc2VlIHRoZSBbSUFNCiAqIGRvY3VtZW50YXRpb25dKGh0dHBzOi8vY2xvdWQuZ29vZ2xlLmNvbS9pYW0vZG9jcy8pLgogKgogKiA8cD4gVGhpcyBpcyB0aGUgSmF2YSBkYXRhIG1vZGVsIGNsYXNzIHRoYXQgc3BlY2lmaWVzIGhvdyB0byBwYXJzZS9zZXJpYWxpemUgaW50byB0aGUgSlNPTiB0aGF0IGlzCiAqIHRyYW5zbWl0dGVkIG92ZXIgSFRUUCB3aGVuIHdvcmtpbmcgd2l0aCB0aGUgSWRlbnRpdHkgYW5kIEFjY2VzcyBNYW5hZ2VtZW50IChJQU0pIEFQSS4gRm9yIGEKICogZGV0YWlsZWQgZXhwbGFuYXRpb24gc2VlOgogKiA8YSBocmVmPSJodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9hcGktY2xpZW50LWxpYnJhcnkvamF2YS9nb29nbGUtaHR0cC1qYXZhLWNsaWVudC9qc29uIj5odHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9hcGktY2xpZW50LWxpYnJhcnkvamF2YS9nb29nbGUtaHR0cC1qYXZhLWNsaWVudC9qc29uPC9hPgogKiA8L3A+CiAqCiAqIEBhdXRob3IgR29vZ2xlLCBJbmMuCiAqLwpAU3VwcHJlc3NXYXJuaW5ncygiamF2YWRvYyIpCnB1YmxpYyBmaW5hbCBjbGFzcyBQb2xpY3kgZXh0ZW5kcyBjb20uZ29vZ2xlLmFwaS5jbGllbnQuanNvbi5HZW5lcmljSnNvbiB7CgogIC8qKgogICAqIFNwZWNpZmllcyBjbG91ZCBhdWRpdCBsb2dnaW5nIGNvbmZpZ3VyYXRpb24gZm9yIHRoaXMgcG9saWN5LgogICAqIFRoZSB2YWx1ZSBtYXkgYmUge0Bjb2RlIG51bGx9LgogICAqLwogIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICBwcml2YXRlIGphdmEudXRpbC5MaXN0PEF1ZGl0Q29uZmlnPiBhdWRpdENvbmZpZ3M7CgogIC8qKgogICAqIEFzc29jaWF0ZXMgYSBsaXN0IG9mIGBtZW1iZXJzYCB0byBhIGByb2xlYC4gT3B0aW9uYWxseSwgbWF5IHNwZWNpZnkgYSBgY29uZGl0aW9uYCB0aGF0CiAgICogZGV0ZXJtaW5lcyBob3cgYW5kIHdoZW4gdGhlIGBiaW5kaW5nc2AgYXJlIGFwcGxpZWQuIEVhY2ggb2YgdGhlIGBiaW5kaW5nc2AgbXVzdCBjb250YWluIGF0CiAgICogbGVhc3Qgb25lIG1lbWJlci4KICAgKiBUaGUgdmFsdWUgbWF5IGJlIHtAY29kZSBudWxsfS4KICAgKi8KICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxCaW5kaW5nPiBiaW5kaW5nczsKCiAgLyoqCiAgICogYGV0YWdgIGlzIHVzZWQgZm9yIG9wdGltaXN0aWMgY29uY3VycmVuY3kgY29udHJvbCBhcyBhIHdheSB0byBoZWxwIHByZXZlbnQgc2ltdWx0YW5lb3VzIHVwZGF0ZXMKICAgKiBvZiBhIHBvbGljeSBmcm9tIG92ZXJ3cml0aW5nIGVhY2ggb3RoZXIuIEl0IGlzIHN0cm9uZ2x5IHN1Z2dlc3RlZCB0aGF0IHN5c3RlbXMgbWFrZSB1c2Ugb2YgdGhlCiAgICogYGV0YWdgIGluIHRoZSByZWFkLW1vZGlmeS13cml0ZSBjeWNsZSB0byBwZXJmb3JtIHBvbGljeSB1cGRhdGVzIGluIG9yZGVyIHRvIGF2b2lkIHJhY2UKICAgKiBjb25kaXRpb25zOiBBbiBgZXRhZ2AgaXMgcmV0dXJuZWQgaW4gdGhlIHJlc3BvbnNlIHRvIGBnZXRJYW1Qb2xpY3lgLCBhbmQgc3lzdGVtcyBhcmUgZXhwZWN0ZWQKICAgKiB0byBwdXQgdGhhdCBldGFnIGluIHRoZSByZXF1ZXN0IHRvIGBzZXRJYW1Qb2xpY3lgIHRvIGVuc3VyZSB0aGF0IHRoZWlyIGNoYW5nZSB3aWxsIGJlIGFwcGxpZWQKICAgKiB0byB0aGUgc2FtZSB2ZXJzaW9uIG9mIHRoZSBwb2xpY3kuCiAgICoKICAgKiAqKkltcG9ydGFudDoqKiBJZiB5b3UgdXNlIElBTSBDb25kaXRpb25zLCB5b3UgbXVzdCBpbmNsdWRlIHRoZSBgZXRhZ2AgZmllbGQgd2hlbmV2ZXIgeW91IGNhbGwKICAgKiBgc2V0SWFtUG9saWN5YC4gSWYgeW91IG9taXQgdGhpcyBmaWVsZCwgdGhlbiBJQU0gYWxsb3dzIHlvdSB0byBvdmVyd3JpdGUgYSB2ZXJzaW9uIGAzYCBwb2xpY3kKICAgKiB3aXRoIGEgdmVyc2lvbiBgMWAgcG9saWN5LCBhbmQgYWxsIG9mIHRoZSBjb25kaXRpb25zIGluIHRoZSB2ZXJzaW9uIGAzYCBwb2xpY3kgYXJlIGxvc3QuCiAgICogVGhlIHZhbHVlIG1heSBiZSB7QGNvZGUgbnVsbH0uCiAgICovCiAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogIHByaXZhdGUgamF2YS5sYW5nLlN0cmluZyBldGFnOwoKICAvKioKICAgKiBTcGVjaWZpZXMgdGhlIGZvcm1hdCBvZiB0aGUgcG9saWN5LgogICAqCiAgICogVmFsaWQgdmFsdWVzIGFyZSBgMGAsIGAxYCwgYW5kIGAzYC4gUmVxdWVzdHMgdGhhdCBzcGVjaWZ5IGFuIGludmFsaWQgdmFsdWUgYXJlIHJlamVjdGVkLgogICAqCiAgICogQW55IG9wZXJhdGlvbiB0aGF0IGFmZmVjdHMgY29uZGl0aW9uYWwgcm9sZSBiaW5kaW5ncyBtdXN0IHNwZWNpZnkgdmVyc2lvbiBgM2AuIFRoaXMgcmVxdWlyZW1lbnQKICAgKiBhcHBsaWVzIHRvIHRoZSBmb2xsb3dpbmcgb3BlcmF0aW9uczoKICAgKgogICAqICogR2V0dGluZyBhIHBvbGljeSB0aGF0IGluY2x1ZGVzIGEgY29uZGl0aW9uYWwgcm9sZSBiaW5kaW5nICogQWRkaW5nIGEgY29uZGl0aW9uYWwgcm9sZSBiaW5kaW5nCiAgICogdG8gYSBwb2xpY3kgKiBDaGFuZ2luZyBhIGNvbmRpdGlvbmFsIHJvbGUgYmluZGluZyBpbiBhIHBvbGljeSAqIFJlbW92aW5nIGFueSByb2xlIGJpbmRpbmcsIHdpdGgKICAgKiBvciB3aXRob3V0IGEgY29uZGl0aW9uLCBmcm9tIGEgcG9saWN5ICAgdGhhdCBpbmNsdWRlcyBjb25kaXRpb25zCiAgICoKICAgKiAqKkltcG9ydGFudDoqKiBJZiB5b3UgdXNlIElBTSBDb25kaXRpb25zLCB5b3UgbXVzdCBpbmNsdWRlIHRoZSBgZXRhZ2AgZmllbGQgd2hlbmV2ZXIgeW91IGNhbGwKICAgKiBgc2V0SWFtUG9saWN5YC4gSWYgeW91IG9taXQgdGhpcyBmaWVsZCwgdGhlbiBJQU0gYWxsb3dzIHlvdSB0byBvdmVyd3JpdGUgYSB2ZXJzaW9uIGAzYCBwb2xpY3kKICAgKiB3aXRoIGEgdmVyc2lvbiBgMWAgcG9saWN5LCBhbmQgYWxsIG9mIHRoZSBjb25kaXRpb25zIGluIHRoZSB2ZXJzaW9uIGAzYCBwb2xpY3kgYXJlIGxvc3QuCiAgICoKICAgKiBJZiBhIHBvbGljeSBkb2VzIG5vdCBpbmNsdWRlIGFueSBjb25kaXRpb25zLCBvcGVyYXRpb25zIG9uIHRoYXQgcG9saWN5IG1heSBzcGVjaWZ5IGFueSB2YWxpZAogICAqIHZlcnNpb24gb3IgbGVhdmUgdGhlIGZpZWxkIHVuc2V0LgogICAqIFRoZSB2YWx1ZSBtYXkgYmUge0Bjb2RlIG51bGx9LgogICAqLwogIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICBwcml2YXRlIGphdmEubGFuZy5JbnRlZ2VyIHZlcnNpb247CgogIC8qKgogICAqIFNwZWNpZmllcyBjbG91ZCBhdWRpdCBsb2dnaW5nIGNvbmZpZ3VyYXRpb24gZm9yIHRoaXMgcG9saWN5LgogICAqIEByZXR1cm4gdmFsdWUgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIGphdmEudXRpbC5MaXN0PEF1ZGl0Q29uZmlnPiBnZXRBdWRpdENvbmZpZ3MoKSB7CiAgICByZXR1cm4gYXVkaXRDb25maWdzOwogIH0KCiAgLyoqCiAgICogU3BlY2lmaWVzIGNsb3VkIGF1ZGl0IGxvZ2dpbmcgY29uZmlndXJhdGlvbiBmb3IgdGhpcyBwb2xpY3kuCiAgICogQHBhcmFtIGF1ZGl0Q29uZmlncyBhdWRpdENvbmZpZ3Mgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIFBvbGljeSBzZXRBdWRpdENvbmZpZ3MoamF2YS51dGlsLkxpc3Q8QXVkaXRDb25maWc+IGF1ZGl0Q29uZmlncykgewogICAgdGhpcy5hdWRpdENvbmZpZ3MgPSBhdWRpdENvbmZpZ3M7CiAgICByZXR1cm4gdGhpczsKICB9CgogIC8qKgogICAqIEFzc29jaWF0ZXMgYSBsaXN0IG9mIGBtZW1iZXJzYCB0byBhIGByb2xlYC4gT3B0aW9uYWxseSwgbWF5IHNwZWNpZnkgYSBgY29uZGl0aW9uYCB0aGF0CiAgICogZGV0ZXJtaW5lcyBob3cgYW5kIHdoZW4gdGhlIGBiaW5kaW5nc2AgYXJlIGFwcGxpZWQuIEVhY2ggb2YgdGhlIGBiaW5kaW5nc2AgbXVzdCBjb250YWluIGF0CiAgICogbGVhc3Qgb25lIG1lbWJlci4KICAgKiBAcmV0dXJuIHZhbHVlIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxCaW5kaW5nPiBnZXRCaW5kaW5ncygpIHsKICAgIHJldHVybiBiaW5kaW5nczsKICB9CgogIC8qKgogICAqIEFzc29jaWF0ZXMgYSBsaXN0IG9mIGBtZW1iZXJzYCB0byBhIGByb2xlYC4gT3B0aW9uYWxseSwgbWF5IHNwZWNpZnkgYSBgY29uZGl0aW9uYCB0aGF0CiAgICogZGV0ZXJtaW5lcyBob3cgYW5kIHdoZW4gdGhlIGBiaW5kaW5nc2AgYXJlIGFwcGxpZWQuIEVhY2ggb2YgdGhlIGBiaW5kaW5nc2AgbXVzdCBjb250YWluIGF0CiAgICogbGVhc3Qgb25lIG1lbWJlci4KICAgKiBAcGFyYW0gYmluZGluZ3MgYmluZGluZ3Mgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIFBvbGljeSBzZXRCaW5kaW5ncyhqYXZhLnV0aWwuTGlzdDxCaW5kaW5nPiBiaW5kaW5ncykgewogICAgdGhpcy5iaW5kaW5ncyA9IGJpbmRpbmdzOwogICAgcmV0dXJuIHRoaXM7CiAgfQoKICAvKioKICAgKiBgZXRhZ2AgaXMgdXNlZCBmb3Igb3B0aW1pc3RpYyBjb25jdXJyZW5jeSBjb250cm9sIGFzIGEgd2F5IHRvIGhlbHAgcHJldmVudCBzaW11bHRhbmVvdXMgdXBkYXRlcwogICAqIG9mIGEgcG9saWN5IGZyb20gb3ZlcndyaXRpbmcgZWFjaCBvdGhlci4gSXQgaXMgc3Ryb25nbHkgc3VnZ2VzdGVkIHRoYXQgc3lzdGVtcyBtYWtlIHVzZSBvZiB0aGUKICAgKiBgZXRhZ2AgaW4gdGhlIHJlYWQtbW9kaWZ5LXdyaXRlIGN5Y2xlIHRvIHBlcmZvcm0gcG9saWN5IHVwZGF0ZXMgaW4gb3JkZXIgdG8gYXZvaWQgcmFjZQogICAqIGNvbmRpdGlvbnM6IEFuIGBldGFnYCBpcyByZXR1cm5lZCBpbiB0aGUgcmVzcG9uc2UgdG8gYGdldElhbVBvbGljeWAsIGFuZCBzeXN0ZW1zIGFyZSBleHBlY3RlZAogICAqIHRvIHB1dCB0aGF0IGV0YWcgaW4gdGhlIHJlcXVlc3QgdG8gYHNldElhbVBvbGljeWAgdG8gZW5zdXJlIHRoYXQgdGhlaXIgY2hhbmdlIHdpbGwgYmUgYXBwbGllZAogICAqIHRvIHRoZSBzYW1lIHZlcnNpb24gb2YgdGhlIHBvbGljeS4KICAgKgogICAqICoqSW1wb3J0YW50OioqIElmIHlvdSB1c2UgSUFNIENvbmRpdGlvbnMsIHlvdSBtdXN0IGluY2x1ZGUgdGhlIGBldGFnYCBmaWVsZCB3aGVuZXZlciB5b3UgY2FsbAogICAqIGBzZXRJYW1Qb2xpY3lgLiBJZiB5b3Ugb21pdCB0aGlzIGZpZWxkLCB0aGVuIElBTSBhbGxvd3MgeW91IHRvIG92ZXJ3cml0ZSBhIHZlcnNpb24gYDNgIHBvbGljeQogICAqIHdpdGggYSB2ZXJzaW9uIGAxYCBwb2xpY3ksIGFuZCBhbGwgb2YgdGhlIGNvbmRpdGlvbnMgaW4gdGhlIHZlcnNpb24gYDNgIHBvbGljeSBhcmUgbG9zdC4KICAgKiBAc2VlICNkZWNvZGVFdGFnKCkKICAgKiBAcmV0dXJuIHZhbHVlIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldEV0YWcoKSB7CiAgICByZXR1cm4gZXRhZzsKICB9CgogIC8qKgogICAqIGBldGFnYCBpcyB1c2VkIGZvciBvcHRpbWlzdGljIGNvbmN1cnJlbmN5IGNvbnRyb2wgYXMgYSB3YXkgdG8gaGVscCBwcmV2ZW50IHNpbXVsdGFuZW91cyB1cGRhdGVzCiAgICogb2YgYSBwb2xpY3kgZnJvbSBvdmVyd3JpdGluZyBlYWNoIG90aGVyLiBJdCBpcyBzdHJvbmdseSBzdWdnZXN0ZWQgdGhhdCBzeXN0ZW1zIG1ha2UgdXNlIG9mIHRoZQogICAqIGBldGFnYCBpbiB0aGUgcmVhZC1tb2RpZnktd3JpdGUgY3ljbGUgdG8gcGVyZm9ybSBwb2xpY3kgdXBkYXRlcyBpbiBvcmRlciB0byBhdm9pZCByYWNlCiAgICogY29uZGl0aW9uczogQW4gYGV0YWdgIGlzIHJldHVybmVkIGluIHRoZSByZXNwb25zZSB0byBgZ2V0SWFtUG9saWN5YCwgYW5kIHN5c3RlbXMgYXJlIGV4cGVjdGVkCiAgICogdG8gcHV0IHRoYXQgZXRhZyBpbiB0aGUgcmVxdWVzdCB0byBgc2V0SWFtUG9saWN5YCB0byBlbnN1cmUgdGhhdCB0aGVpciBjaGFuZ2Ugd2lsbCBiZSBhcHBsaWVkCiAgICogdG8gdGhlIHNhbWUgdmVyc2lvbiBvZiB0aGUgcG9saWN5LgogICAqCiAgICogKipJbXBvcnRhbnQ6KiogSWYgeW91IHVzZSBJQU0gQ29uZGl0aW9ucywgeW91IG11c3QgaW5jbHVkZSB0aGUgYGV0YWdgIGZpZWxkIHdoZW5ldmVyIHlvdSBjYWxsCiAgICogYHNldElhbVBvbGljeWAuIElmIHlvdSBvbWl0IHRoaXMgZmllbGQsIHRoZW4gSUFNIGFsbG93cyB5b3UgdG8gb3ZlcndyaXRlIGEgdmVyc2lvbiBgM2AgcG9saWN5CiAgICogd2l0aCBhIHZlcnNpb24gYDFgIHBvbGljeSwgYW5kIGFsbCBvZiB0aGUgY29uZGl0aW9ucyBpbiB0aGUgdmVyc2lvbiBgM2AgcG9saWN5IGFyZSBsb3N0LgogICAqIEBzZWUgI2dldEV0YWcoKQogICAqIEByZXR1cm4gQmFzZTY0IGRlY29kZWQgdmFsdWUgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICoKICAgKiBAc2luY2UgMS4xNAogICAqLwogIHB1YmxpYyBieXRlW10gZGVjb2RlRXRhZygpIHsKICAgIHJldHVybiBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5CYXNlNjQuZGVjb2RlQmFzZTY0KGV0YWcpOwogIH0KCiAgLyoqCiAgICogYGV0YWdgIGlzIHVzZWQgZm9yIG9wdGltaXN0aWMgY29uY3VycmVuY3kgY29udHJvbCBhcyBhIHdheSB0byBoZWxwIHByZXZlbnQgc2ltdWx0YW5lb3VzIHVwZGF0ZXMKICAgKiBvZiBhIHBvbGljeSBmcm9tIG92ZXJ3cml0aW5nIGVhY2ggb3RoZXIuIEl0IGlzIHN0cm9uZ2x5IHN1Z2dlc3RlZCB0aGF0IHN5c3RlbXMgbWFrZSB1c2Ugb2YgdGhlCiAgICogYGV0YWdgIGluIHRoZSByZWFkLW1vZGlmeS13cml0ZSBjeWNsZSB0byBwZXJmb3JtIHBvbGljeSB1cGRhdGVzIGluIG9yZGVyIHRvIGF2b2lkIHJhY2UKICAgKiBjb25kaXRpb25zOiBBbiBgZXRhZ2AgaXMgcmV0dXJuZWQgaW4gdGhlIHJlc3BvbnNlIHRvIGBnZXRJYW1Qb2xpY3lgLCBhbmQgc3lzdGVtcyBhcmUgZXhwZWN0ZWQKICAgKiB0byBwdXQgdGhhdCBldGFnIGluIHRoZSByZXF1ZXN0IHRvIGBzZXRJYW1Qb2xpY3lgIHRvIGVuc3VyZSB0aGF0IHRoZWlyIGNoYW5nZSB3aWxsIGJlIGFwcGxpZWQKICAgKiB0byB0aGUgc2FtZSB2ZXJzaW9uIG9mIHRoZSBwb2xpY3kuCiAgICoKICAgKiAqKkltcG9ydGFudDoqKiBJZiB5b3UgdXNlIElBTSBDb25kaXRpb25zLCB5b3UgbXVzdCBpbmNsdWRlIHRoZSBgZXRhZ2AgZmllbGQgd2hlbmV2ZXIgeW91IGNhbGwKICAgKiBgc2V0SWFtUG9saWN5YC4gSWYgeW91IG9taXQgdGhpcyBmaWVsZCwgdGhlbiBJQU0gYWxsb3dzIHlvdSB0byBvdmVyd3JpdGUgYSB2ZXJzaW9uIGAzYCBwb2xpY3kKICAgKiB3aXRoIGEgdmVyc2lvbiBgMWAgcG9saWN5LCBhbmQgYWxsIG9mIHRoZSBjb25kaXRpb25zIGluIHRoZSB2ZXJzaW9uIGAzYCBwb2xpY3kgYXJlIGxvc3QuCiAgICogQHNlZSAjZW5jb2RlRXRhZygpCiAgICogQHBhcmFtIGV0YWcgZXRhZyBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgUG9saWN5IHNldEV0YWcoamF2YS5sYW5nLlN0cmluZyBldGFnKSB7CiAgICB0aGlzLmV0YWcgPSBldGFnOwogICAgcmV0dXJuIHRoaXM7CiAgfQoKICAvKioKICAgKiBgZXRhZ2AgaXMgdXNlZCBmb3Igb3B0aW1pc3RpYyBjb25jdXJyZW5jeSBjb250cm9sIGFzIGEgd2F5IHRvIGhlbHAgcHJldmVudCBzaW11bHRhbmVvdXMgdXBkYXRlcwogICAqIG9mIGEgcG9saWN5IGZyb20gb3ZlcndyaXRpbmcgZWFjaCBvdGhlci4gSXQgaXMgc3Ryb25nbHkgc3VnZ2VzdGVkIHRoYXQgc3lzdGVtcyBtYWtlIHVzZSBvZiB0aGUKICAgKiBgZXRhZ2AgaW4gdGhlIHJlYWQtbW9kaWZ5LXdyaXRlIGN5Y2xlIHRvIHBlcmZvcm0gcG9saWN5IHVwZGF0ZXMgaW4gb3JkZXIgdG8gYXZvaWQgcmFjZQogICAqIGNvbmRpdGlvbnM6IEFuIGBldGFnYCBpcyByZXR1cm5lZCBpbiB0aGUgcmVzcG9uc2UgdG8gYGdldElhbVBvbGljeWAsIGFuZCBzeXN0ZW1zIGFyZSBleHBlY3RlZAogICAqIHRvIHB1dCB0aGF0IGV0YWcgaW4gdGhlIHJlcXVlc3QgdG8gYHNldElhbVBvbGljeWAgdG8gZW5zdXJlIHRoYXQgdGhlaXIgY2hhbmdlIHdpbGwgYmUgYXBwbGllZAogICAqIHRvIHRoZSBzYW1lIHZlcnNpb24gb2YgdGhlIHBvbGljeS4KICAgKgogICAqICoqSW1wb3J0YW50OioqIElmIHlvdSB1c2UgSUFNIENvbmRpdGlvbnMsIHlvdSBtdXN0IGluY2x1ZGUgdGhlIGBldGFnYCBmaWVsZCB3aGVuZXZlciB5b3UgY2FsbAogICAqIGBzZXRJYW1Qb2xpY3lgLiBJZiB5b3Ugb21pdCB0aGlzIGZpZWxkLCB0aGVuIElBTSBhbGxvd3MgeW91IHRvIG92ZXJ3cml0ZSBhIHZlcnNpb24gYDNgIHBvbGljeQogICAqIHdpdGggYSB2ZXJzaW9uIGAxYCBwb2xpY3ksIGFuZCBhbGwgb2YgdGhlIGNvbmRpdGlvbnMgaW4gdGhlIHZlcnNpb24gYDNgIHBvbGljeSBhcmUgbG9zdC4KICAgKiBAc2VlICNzZXRFdGFnKCkKICAgKgogICAqIDxwPgogICAqIFRoZSB2YWx1ZSBpcyBlbmNvZGVkIEJhc2U2NCBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUuCiAgICogPC9wPgogICAqCiAgICogQHNpbmNlIDEuMTQKICAgKi8KICBwdWJsaWMgUG9saWN5IGVuY29kZUV0YWcoYnl0ZVtdIGV0YWcpIHsKICAgIHRoaXMuZXRhZyA9IGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLkJhc2U2NC5lbmNvZGVCYXNlNjRVUkxTYWZlU3RyaW5nKGV0YWcpOwogICAgcmV0dXJuIHRoaXM7CiAgfQoKICAvKioKICAgKiBTcGVjaWZpZXMgdGhlIGZvcm1hdCBvZiB0aGUgcG9saWN5LgogICAqCiAgICogVmFsaWQgdmFsdWVzIGFyZSBgMGAsIGAxYCwgYW5kIGAzYC4gUmVxdWVzdHMgdGhhdCBzcGVjaWZ5IGFuIGludmFsaWQgdmFsdWUgYXJlIHJlamVjdGVkLgogICAqCiAgICogQW55IG9wZXJhdGlvbiB0aGF0IGFmZmVjdHMgY29uZGl0aW9uYWwgcm9sZSBiaW5kaW5ncyBtdXN0IHNwZWNpZnkgdmVyc2lvbiBgM2AuIFRoaXMgcmVxdWlyZW1lbnQKICAgKiBhcHBsaWVzIHRvIHRoZSBmb2xsb3dpbmcgb3BlcmF0aW9uczoKICAgKgogICAqICogR2V0dGluZyBhIHBvbGljeSB0aGF0IGluY2x1ZGVzIGEgY29uZGl0aW9uYWwgcm9sZSBiaW5kaW5nICogQWRkaW5nIGEgY29uZGl0aW9uYWwgcm9sZSBiaW5kaW5nCiAgICogdG8gYSBwb2xpY3kgKiBDaGFuZ2luZyBhIGNvbmRpdGlvbmFsIHJvbGUgYmluZGluZyBpbiBhIHBvbGljeSAqIFJlbW92aW5nIGFueSByb2xlIGJpbmRpbmcsIHdpdGgKICAgKiBvciB3aXRob3V0IGEgY29uZGl0aW9uLCBmcm9tIGEgcG9saWN5ICAgdGhhdCBpbmNsdWRlcyBjb25kaXRpb25zCiAgICoKICAgKiAqKkltcG9ydGFudDoqKiBJZiB5b3UgdXNlIElBTSBDb25kaXRpb25zLCB5b3UgbXVzdCBpbmNsdWRlIHRoZSBgZXRhZ2AgZmllbGQgd2hlbmV2ZXIgeW91IGNhbGwKICAgKiBgc2V0SWFtUG9saWN5YC4gSWYgeW91IG9taXQgdGhpcyBmaWVsZCwgdGhlbiBJQU0gYWxsb3dzIHlvdSB0byBvdmVyd3JpdGUgYSB2ZXJzaW9uIGAzYCBwb2xpY3kKICAgKiB3aXRoIGEgdmVyc2lvbiBgMWAgcG9saWN5LCBhbmQgYWxsIG9mIHRoZSBjb25kaXRpb25zIGluIHRoZSB2ZXJzaW9uIGAzYCBwb2xpY3kgYXJlIGxvc3QuCiAgICoKICAgKiBJZiBhIHBvbGljeSBkb2VzIG5vdCBpbmNsdWRlIGFueSBjb25kaXRpb25zLCBvcGVyYXRpb25zIG9uIHRoYXQgcG9saWN5IG1heSBzcGVjaWZ5IGFueSB2YWxpZAogICAqIHZlcnNpb24gb3IgbGVhdmUgdGhlIGZpZWxkIHVuc2V0LgogICAqIEByZXR1cm4gdmFsdWUgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIGphdmEubGFuZy5JbnRlZ2VyIGdldFZlcnNpb24oKSB7CiAgICByZXR1cm4gdmVyc2lvbjsKICB9CgogIC8qKgogICAqIFNwZWNpZmllcyB0aGUgZm9ybWF0IG9mIHRoZSBwb2xpY3kuCiAgICoKICAgKiBWYWxpZCB2YWx1ZXMgYXJlIGAwYCwgYDFgLCBhbmQgYDNgLiBSZXF1ZXN0cyB0aGF0IHNwZWNpZnkgYW4gaW52YWxpZCB2YWx1ZSBhcmUgcmVqZWN0ZWQuCiAgICoKICAgKiBBbnkgb3BlcmF0aW9uIHRoYXQgYWZmZWN0cyBjb25kaXRpb25hbCByb2xlIGJpbmRpbmdzIG11c3Qgc3BlY2lmeSB2ZXJzaW9uIGAzYC4gVGhpcyByZXF1aXJlbWVudAogICAqIGFwcGxpZXMgdG8gdGhlIGZvbGxvd2luZyBvcGVyYXRpb25zOgogICAqCiAgICogKiBHZXR0aW5nIGEgcG9saWN5IHRoYXQgaW5jbHVkZXMgYSBjb25kaXRpb25hbCByb2xlIGJpbmRpbmcgKiBBZGRpbmcgYSBjb25kaXRpb25hbCByb2xlIGJpbmRpbmcKICAgKiB0byBhIHBvbGljeSAqIENoYW5naW5nIGEgY29uZGl0aW9uYWwgcm9sZSBiaW5kaW5nIGluIGEgcG9saWN5ICogUmVtb3ZpbmcgYW55IHJvbGUgYmluZGluZywgd2l0aAogICAqIG9yIHdpdGhvdXQgYSBjb25kaXRpb24sIGZyb20gYSBwb2xpY3kgICB0aGF0IGluY2x1ZGVzIGNvbmRpdGlvbnMKICAgKgogICAqICoqSW1wb3J0YW50OioqIElmIHlvdSB1c2UgSUFNIENvbmRpdGlvbnMsIHlvdSBtdXN0IGluY2x1ZGUgdGhlIGBldGFnYCBmaWVsZCB3aGVuZXZlciB5b3UgY2FsbAogICAqIGBzZXRJYW1Qb2xpY3lgLiBJZiB5b3Ugb21pdCB0aGlzIGZpZWxkLCB0aGVuIElBTSBhbGxvd3MgeW91IHRvIG92ZXJ3cml0ZSBhIHZlcnNpb24gYDNgIHBvbGljeQogICAqIHdpdGggYSB2ZXJzaW9uIGAxYCBwb2xpY3ksIGFuZCBhbGwgb2YgdGhlIGNvbmRpdGlvbnMgaW4gdGhlIHZlcnNpb24gYDNgIHBvbGljeSBhcmUgbG9zdC4KICAgKgogICAqIElmIGEgcG9saWN5IGRvZXMgbm90IGluY2x1ZGUgYW55IGNvbmRpdGlvbnMsIG9wZXJhdGlvbnMgb24gdGhhdCBwb2xpY3kgbWF5IHNwZWNpZnkgYW55IHZhbGlkCiAgICogdmVyc2lvbiBvciBsZWF2ZSB0aGUgZmllbGQgdW5zZXQuCiAgICogQHBhcmFtIHZlcnNpb24gdmVyc2lvbiBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgUG9saWN5IHNldFZlcnNpb24oamF2YS5sYW5nLkludGVnZXIgdmVyc2lvbikgewogICAgdGhpcy52ZXJzaW9uID0gdmVyc2lvbjsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgQE92ZXJyaWRlCiAgcHVibGljIFBvbGljeSBzZXQoU3RyaW5nIGZpZWxkTmFtZSwgT2JqZWN0IHZhbHVlKSB7CiAgICByZXR1cm4gKFBvbGljeSkgc3VwZXIuc2V0KGZpZWxkTmFtZSwgdmFsdWUpOwogIH0KCiAgQE92ZXJyaWRlCiAgcHVibGljIFBvbGljeSBjbG9uZSgpIHsKICAgIHJldHVybiAoUG9saWN5KSBzdXBlci5jbG9uZSgpOwogIH0KCn0KUEsDBBQAAAAAAAAAIQCoAuUX/AkAAPwJAAA1AAAAY29tL2dvb2dsZS9hcGkvc2VydmljZXMvaWFtL3YxL21vZGVsL1BvbGljeURlbHRhLmphdmEvKgogKiBDb3B5cmlnaHQgMjAxMCBHb29nbGUgSW5jLgogKgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQKICogaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UKICogaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzCiAqIG9yIGltcGxpZWQuIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMgdW5kZXIKICogdGhlIExpY2Vuc2UuCiAqLwovKgogKiBUaGlzIGNvZGUgd2FzIGdlbmVyYXRlZCBieSBodHRwczovL2dpdGh1Yi5jb20vZ29vZ2xlL2FwaXMtY2xpZW50LWdlbmVyYXRvci8KICogKGJ1aWxkOiAyMDE4LTEwLTA4IDE3OjQ1OjM5IFVUQykKICogb24gMjAyMC0wMy0xOSBhdCAwMTo1Mjo0MSBVVEMgCiAqIE1vZGlmeSBhdCB5b3VyIG93biByaXNrLgogKi8KCnBhY2thZ2UgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuaWFtLnYxLm1vZGVsOwoKLyoqCiAqIFRoZSBkaWZmZXJlbmNlIGRlbHRhIGJldHdlZW4gdHdvIHBvbGljaWVzLgogKgogKiA8cD4gVGhpcyBpcyB0aGUgSmF2YSBkYXRhIG1vZGVsIGNsYXNzIHRoYXQgc3BlY2lmaWVzIGhvdyB0byBwYXJzZS9zZXJpYWxpemUgaW50byB0aGUgSlNPTiB0aGF0IGlzCiAqIHRyYW5zbWl0dGVkIG92ZXIgSFRUUCB3aGVuIHdvcmtpbmcgd2l0aCB0aGUgSWRlbnRpdHkgYW5kIEFjY2VzcyBNYW5hZ2VtZW50IChJQU0pIEFQSS4gRm9yIGEKICogZGV0YWlsZWQgZXhwbGFuYXRpb24gc2VlOgogKiA8YSBocmVmPSJodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9hcGktY2xpZW50LWxpYnJhcnkvamF2YS9nb29nbGUtaHR0cC1qYXZhLWNsaWVudC9qc29uIj5odHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9hcGktY2xpZW50LWxpYnJhcnkvamF2YS9nb29nbGUtaHR0cC1qYXZhLWNsaWVudC9qc29uPC9hPgogKiA8L3A+CiAqCiAqIEBhdXRob3IgR29vZ2xlLCBJbmMuCiAqLwpAU3VwcHJlc3NXYXJuaW5ncygiamF2YWRvYyIpCnB1YmxpYyBmaW5hbCBjbGFzcyBQb2xpY3lEZWx0YSBleHRlbmRzIGNvbS5nb29nbGUuYXBpLmNsaWVudC5qc29uLkdlbmVyaWNKc29uIHsKCiAgLyoqCiAgICogVGhlIGRlbHRhIGZvciBCaW5kaW5ncyBiZXR3ZWVuIHR3byBwb2xpY2llcy4KICAgKiBUaGUgdmFsdWUgbWF5IGJlIHtAY29kZSBudWxsfS4KICAgKi8KICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxCaW5kaW5nRGVsdGE+IGJpbmRpbmdEZWx0YXM7CgogIHN0YXRpYyB7CiAgICAvLyBoYWNrIHRvIGZvcmNlIFByb0d1YXJkIHRvIGNvbnNpZGVyIEJpbmRpbmdEZWx0YSB1c2VkLCBzaW5jZSBvdGhlcndpc2UgaXQgd291bGQgYmUgc3RyaXBwZWQgb3V0CiAgICAvLyBzZWUgaHR0cHM6Ly9naXRodWIuY29tL2dvb2dsZS9nb29nbGUtYXBpLWphdmEtY2xpZW50L2lzc3Vlcy81NDMKICAgIGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLkRhdGEubnVsbE9mKEJpbmRpbmdEZWx0YS5jbGFzcyk7CiAgfQoKICAvKioKICAgKiBUaGUgZGVsdGEgZm9yIEJpbmRpbmdzIGJldHdlZW4gdHdvIHBvbGljaWVzLgogICAqIEByZXR1cm4gdmFsdWUgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIGphdmEudXRpbC5MaXN0PEJpbmRpbmdEZWx0YT4gZ2V0QmluZGluZ0RlbHRhcygpIHsKICAgIHJldHVybiBiaW5kaW5nRGVsdGFzOwogIH0KCiAgLyoqCiAgICogVGhlIGRlbHRhIGZvciBCaW5kaW5ncyBiZXR3ZWVuIHR3byBwb2xpY2llcy4KICAgKiBAcGFyYW0gYmluZGluZ0RlbHRhcyBiaW5kaW5nRGVsdGFzIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBQb2xpY3lEZWx0YSBzZXRCaW5kaW5nRGVsdGFzKGphdmEudXRpbC5MaXN0PEJpbmRpbmdEZWx0YT4gYmluZGluZ0RlbHRhcykgewogICAgdGhpcy5iaW5kaW5nRGVsdGFzID0gYmluZGluZ0RlbHRhczsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgQE92ZXJyaWRlCiAgcHVibGljIFBvbGljeURlbHRhIHNldChTdHJpbmcgZmllbGROYW1lLCBPYmplY3QgdmFsdWUpIHsKICAgIHJldHVybiAoUG9saWN5RGVsdGEpIHN1cGVyLnNldChmaWVsZE5hbWUsIHZhbHVlKTsKICB9CgogIEBPdmVycmlkZQogIHB1YmxpYyBQb2xpY3lEZWx0YSBjbG9uZSgpIHsKICAgIHJldHVybiAoUG9saWN5RGVsdGEpIHN1cGVyLmNsb25lKCk7CiAgfQoKfQpQSwMEFAAAAAAAAAAhAI/1D+diDAAAYgwAAEcAAABjb20vZ29vZ2xlL2FwaS9zZXJ2aWNlcy9pYW0vdjEvbW9kZWwvUXVlcnlBdWRpdGFibGVTZXJ2aWNlc1JlcXVlc3QuamF2YS8qCiAqIENvcHlyaWdodCAyMDEwIEdvb2dsZSBJbmMuCiAqCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdAogKiBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZQogKiBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3MKICogb3IgaW1wbGllZC4gU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucyB1bmRlcgogKiB0aGUgTGljZW5zZS4KICovCi8qCiAqIFRoaXMgY29kZSB3YXMgZ2VuZXJhdGVkIGJ5IGh0dHBzOi8vZ2l0aHViLmNvbS9nb29nbGUvYXBpcy1jbGllbnQtZ2VuZXJhdG9yLwogKiAoYnVpbGQ6IDIwMTgtMTAtMDggMTc6NDU6MzkgVVRDKQogKiBvbiAyMDIwLTAzLTE5IGF0IDAxOjUyOjQxIFVUQyAKICogTW9kaWZ5IGF0IHlvdXIgb3duIHJpc2suCiAqLwoKcGFja2FnZSBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5pYW0udjEubW9kZWw7CgovKioKICogQSByZXF1ZXN0IHRvIGdldCB0aGUgbGlzdCBvZiBhdWRpdGFibGUgc2VydmljZXMgZm9yIGEgcmVzb3VyY2UuCiAqCiAqIDxwPiBUaGlzIGlzIHRoZSBKYXZhIGRhdGEgbW9kZWwgY2xhc3MgdGhhdCBzcGVjaWZpZXMgaG93IHRvIHBhcnNlL3NlcmlhbGl6ZSBpbnRvIHRoZSBKU09OIHRoYXQgaXMKICogdHJhbnNtaXR0ZWQgb3ZlciBIVFRQIHdoZW4gd29ya2luZyB3aXRoIHRoZSBJZGVudGl0eSBhbmQgQWNjZXNzIE1hbmFnZW1lbnQgKElBTSkgQVBJLiBGb3IgYQogKiBkZXRhaWxlZCBleHBsYW5hdGlvbiBzZWU6CiAqIDxhIGhyZWY9Imh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL2FwaS1jbGllbnQtbGlicmFyeS9qYXZhL2dvb2dsZS1odHRwLWphdmEtY2xpZW50L2pzb24iPmh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL2FwaS1jbGllbnQtbGlicmFyeS9qYXZhL2dvb2dsZS1odHRwLWphdmEtY2xpZW50L2pzb248L2E+CiAqIDwvcD4KICoKICogQGF1dGhvciBHb29nbGUsIEluYy4KICovCkBTdXBwcmVzc1dhcm5pbmdzKCJqYXZhZG9jIikKcHVibGljIGZpbmFsIGNsYXNzIFF1ZXJ5QXVkaXRhYmxlU2VydmljZXNSZXF1ZXN0IGV4dGVuZHMgY29tLmdvb2dsZS5hcGkuY2xpZW50Lmpzb24uR2VuZXJpY0pzb24gewoKICAvKioKICAgKiBSZXF1aXJlZC4gVGhlIGZ1bGwgcmVzb3VyY2UgbmFtZSB0byBxdWVyeSBmcm9tIHRoZSBsaXN0IG9mIGF1ZGl0YWJsZSBzZXJ2aWNlcy4KICAgKgogICAqIFRoZSBuYW1lIGZvbGxvd3MgdGhlIEdvb2dsZSBDbG91ZCBQbGF0Zm9ybSByZXNvdXJjZSBmb3JtYXQuIEZvciBleGFtcGxlLCBhIENsb3VkIFBsYXRmb3JtCiAgICogcHJvamVjdCB3aXRoIGlkIGBteS1wcm9qZWN0YCB3aWxsIGJlIG5hbWVkIGAvL2Nsb3VkcmVzb3VyY2VtYW5hZ2VyLmdvb2dsZWFwaXMuY29tL3Byb2plY3RzL215LQogICAqIHByb2plY3RgLgogICAqIFRoZSB2YWx1ZSBtYXkgYmUge0Bjb2RlIG51bGx9LgogICAqLwogIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICBwcml2YXRlIGphdmEubGFuZy5TdHJpbmcgZnVsbFJlc291cmNlTmFtZTsKCiAgLyoqCiAgICogUmVxdWlyZWQuIFRoZSBmdWxsIHJlc291cmNlIG5hbWUgdG8gcXVlcnkgZnJvbSB0aGUgbGlzdCBvZiBhdWRpdGFibGUgc2VydmljZXMuCiAgICoKICAgKiBUaGUgbmFtZSBmb2xsb3dzIHRoZSBHb29nbGUgQ2xvdWQgUGxhdGZvcm0gcmVzb3VyY2UgZm9ybWF0LiBGb3IgZXhhbXBsZSwgYSBDbG91ZCBQbGF0Zm9ybQogICAqIHByb2plY3Qgd2l0aCBpZCBgbXktcHJvamVjdGAgd2lsbCBiZSBuYW1lZCBgLy9jbG91ZHJlc291cmNlbWFuYWdlci5nb29nbGVhcGlzLmNvbS9wcm9qZWN0cy9teS0KICAgKiBwcm9qZWN0YC4KICAgKiBAcmV0dXJuIHZhbHVlIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldEZ1bGxSZXNvdXJjZU5hbWUoKSB7CiAgICByZXR1cm4gZnVsbFJlc291cmNlTmFtZTsKICB9CgogIC8qKgogICAqIFJlcXVpcmVkLiBUaGUgZnVsbCByZXNvdXJjZSBuYW1lIHRvIHF1ZXJ5IGZyb20gdGhlIGxpc3Qgb2YgYXVkaXRhYmxlIHNlcnZpY2VzLgogICAqCiAgICogVGhlIG5hbWUgZm9sbG93cyB0aGUgR29vZ2xlIENsb3VkIFBsYXRmb3JtIHJlc291cmNlIGZvcm1hdC4gRm9yIGV4YW1wbGUsIGEgQ2xvdWQgUGxhdGZvcm0KICAgKiBwcm9qZWN0IHdpdGggaWQgYG15LXByb2plY3RgIHdpbGwgYmUgbmFtZWQgYC8vY2xvdWRyZXNvdXJjZW1hbmFnZXIuZ29vZ2xlYXBpcy5jb20vcHJvamVjdHMvbXktCiAgICogcHJvamVjdGAuCiAgICogQHBhcmFtIGZ1bGxSZXNvdXJjZU5hbWUgZnVsbFJlc291cmNlTmFtZSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgUXVlcnlBdWRpdGFibGVTZXJ2aWNlc1JlcXVlc3Qgc2V0RnVsbFJlc291cmNlTmFtZShqYXZhLmxhbmcuU3RyaW5nIGZ1bGxSZXNvdXJjZU5hbWUpIHsKICAgIHRoaXMuZnVsbFJlc291cmNlTmFtZSA9IGZ1bGxSZXNvdXJjZU5hbWU7CiAgICByZXR1cm4gdGhpczsKICB9CgogIEBPdmVycmlkZQogIHB1YmxpYyBRdWVyeUF1ZGl0YWJsZVNlcnZpY2VzUmVxdWVzdCBzZXQoU3RyaW5nIGZpZWxkTmFtZSwgT2JqZWN0IHZhbHVlKSB7CiAgICByZXR1cm4gKFF1ZXJ5QXVkaXRhYmxlU2VydmljZXNSZXF1ZXN0KSBzdXBlci5zZXQoZmllbGROYW1lLCB2YWx1ZSk7CiAgfQoKICBAT3ZlcnJpZGUKICBwdWJsaWMgUXVlcnlBdWRpdGFibGVTZXJ2aWNlc1JlcXVlc3QgY2xvbmUoKSB7CiAgICByZXR1cm4gKFF1ZXJ5QXVkaXRhYmxlU2VydmljZXNSZXF1ZXN0KSBzdXBlci5jbG9uZSgpOwogIH0KCn0KUEsDBBQAAAAAAAAAIQDpKOK7VgkAAFYJAABIAAAAY29tL2dvb2dsZS9hcGkvc2VydmljZXMvaWFtL3YxL21vZGVsL1F1ZXJ5QXVkaXRhYmxlU2VydmljZXNSZXNwb25zZS5qYXZhLyoKICogQ29weXJpZ2h0IDIwMTAgR29vZ2xlIEluYy4KICoKICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0CiAqIGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4gWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlCiAqIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcwogKiBvciBpbXBsaWVkLiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zIHVuZGVyCiAqIHRoZSBMaWNlbnNlLgogKi8KLyoKICogVGhpcyBjb2RlIHdhcyBnZW5lcmF0ZWQgYnkgaHR0cHM6Ly9naXRodWIuY29tL2dvb2dsZS9hcGlzLWNsaWVudC1nZW5lcmF0b3IvCiAqIChidWlsZDogMjAxOC0xMC0wOCAxNzo0NTozOSBVVEMpCiAqIG9uIDIwMjAtMDMtMTkgYXQgMDE6NTI6NDEgVVRDIAogKiBNb2RpZnkgYXQgeW91ciBvd24gcmlzay4KICovCgpwYWNrYWdlIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmlhbS52MS5tb2RlbDsKCi8qKgogKiBBIHJlc3BvbnNlIGNvbnRhaW5pbmcgYSBsaXN0IG9mIGF1ZGl0YWJsZSBzZXJ2aWNlcyBmb3IgYSByZXNvdXJjZS4KICoKICogPHA+IFRoaXMgaXMgdGhlIEphdmEgZGF0YSBtb2RlbCBjbGFzcyB0aGF0IHNwZWNpZmllcyBob3cgdG8gcGFyc2Uvc2VyaWFsaXplIGludG8gdGhlIEpTT04gdGhhdCBpcwogKiB0cmFuc21pdHRlZCBvdmVyIEhUVFAgd2hlbiB3b3JraW5nIHdpdGggdGhlIElkZW50aXR5IGFuZCBBY2Nlc3MgTWFuYWdlbWVudCAoSUFNKSBBUEkuIEZvciBhCiAqIGRldGFpbGVkIGV4cGxhbmF0aW9uIHNlZToKICogPGEgaHJlZj0iaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vYXBpLWNsaWVudC1saWJyYXJ5L2phdmEvZ29vZ2xlLWh0dHAtamF2YS1jbGllbnQvanNvbiI+aHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vYXBpLWNsaWVudC1saWJyYXJ5L2phdmEvZ29vZ2xlLWh0dHAtamF2YS1jbGllbnQvanNvbjwvYT4KICogPC9wPgogKgogKiBAYXV0aG9yIEdvb2dsZSwgSW5jLgogKi8KQFN1cHByZXNzV2FybmluZ3MoImphdmFkb2MiKQpwdWJsaWMgZmluYWwgY2xhc3MgUXVlcnlBdWRpdGFibGVTZXJ2aWNlc1Jlc3BvbnNlIGV4dGVuZHMgY29tLmdvb2dsZS5hcGkuY2xpZW50Lmpzb24uR2VuZXJpY0pzb24gewoKICAvKioKICAgKiBUaGUgYXVkaXRhYmxlIHNlcnZpY2VzIGZvciBhIHJlc291cmNlLgogICAqIFRoZSB2YWx1ZSBtYXkgYmUge0Bjb2RlIG51bGx9LgogICAqLwogIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICBwcml2YXRlIGphdmEudXRpbC5MaXN0PEF1ZGl0YWJsZVNlcnZpY2U+IHNlcnZpY2VzOwoKICAvKioKICAgKiBUaGUgYXVkaXRhYmxlIHNlcnZpY2VzIGZvciBhIHJlc291cmNlLgogICAqIEByZXR1cm4gdmFsdWUgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIGphdmEudXRpbC5MaXN0PEF1ZGl0YWJsZVNlcnZpY2U+IGdldFNlcnZpY2VzKCkgewogICAgcmV0dXJuIHNlcnZpY2VzOwogIH0KCiAgLyoqCiAgICogVGhlIGF1ZGl0YWJsZSBzZXJ2aWNlcyBmb3IgYSByZXNvdXJjZS4KICAgKiBAcGFyYW0gc2VydmljZXMgc2VydmljZXMgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIFF1ZXJ5QXVkaXRhYmxlU2VydmljZXNSZXNwb25zZSBzZXRTZXJ2aWNlcyhqYXZhLnV0aWwuTGlzdDxBdWRpdGFibGVTZXJ2aWNlPiBzZXJ2aWNlcykgewogICAgdGhpcy5zZXJ2aWNlcyA9IHNlcnZpY2VzOwogICAgcmV0dXJuIHRoaXM7CiAgfQoKICBAT3ZlcnJpZGUKICBwdWJsaWMgUXVlcnlBdWRpdGFibGVTZXJ2aWNlc1Jlc3BvbnNlIHNldChTdHJpbmcgZmllbGROYW1lLCBPYmplY3QgdmFsdWUpIHsKICAgIHJldHVybiAoUXVlcnlBdWRpdGFibGVTZXJ2aWNlc1Jlc3BvbnNlKSBzdXBlci5zZXQoZmllbGROYW1lLCB2YWx1ZSk7CiAgfQoKICBAT3ZlcnJpZGUKICBwdWJsaWMgUXVlcnlBdWRpdGFibGVTZXJ2aWNlc1Jlc3BvbnNlIGNsb25lKCkgewogICAgcmV0dXJuIChRdWVyeUF1ZGl0YWJsZVNlcnZpY2VzUmVzcG9uc2UpIHN1cGVyLmNsb25lKCk7CiAgfQoKfQpQSwMEFAAAAAAAAAAhACORpwwHEwAABxMAAEQAAABjb20vZ29vZ2xlL2FwaS9zZXJ2aWNlcy9pYW0vdjEvbW9kZWwvUXVlcnlHcmFudGFibGVSb2xlc1JlcXVlc3QuamF2YS8qCiAqIENvcHlyaWdodCAyMDEwIEdvb2dsZSBJbmMuCiAqCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdAogKiBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZQogKiBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3MKICogb3IgaW1wbGllZC4gU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucyB1bmRlcgogKiB0aGUgTGljZW5zZS4KICovCi8qCiAqIFRoaXMgY29kZSB3YXMgZ2VuZXJhdGVkIGJ5IGh0dHBzOi8vZ2l0aHViLmNvbS9nb29nbGUvYXBpcy1jbGllbnQtZ2VuZXJhdG9yLwogKiAoYnVpbGQ6IDIwMTgtMTAtMDggMTc6NDU6MzkgVVRDKQogKiBvbiAyMDIwLTAzLTE5IGF0IDAxOjUyOjQxIFVUQyAKICogTW9kaWZ5IGF0IHlvdXIgb3duIHJpc2suCiAqLwoKcGFja2FnZSBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5pYW0udjEubW9kZWw7CgovKioKICogVGhlIGdyYW50YWJsZSByb2xlIHF1ZXJ5IHJlcXVlc3QuCiAqCiAqIDxwPiBUaGlzIGlzIHRoZSBKYXZhIGRhdGEgbW9kZWwgY2xhc3MgdGhhdCBzcGVjaWZpZXMgaG93IHRvIHBhcnNlL3NlcmlhbGl6ZSBpbnRvIHRoZSBKU09OIHRoYXQgaXMKICogdHJhbnNtaXR0ZWQgb3ZlciBIVFRQIHdoZW4gd29ya2luZyB3aXRoIHRoZSBJZGVudGl0eSBhbmQgQWNjZXNzIE1hbmFnZW1lbnQgKElBTSkgQVBJLiBGb3IgYQogKiBkZXRhaWxlZCBleHBsYW5hdGlvbiBzZWU6CiAqIDxhIGhyZWY9Imh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL2FwaS1jbGllbnQtbGlicmFyeS9qYXZhL2dvb2dsZS1odHRwLWphdmEtY2xpZW50L2pzb24iPmh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL2FwaS1jbGllbnQtbGlicmFyeS9qYXZhL2dvb2dsZS1odHRwLWphdmEtY2xpZW50L2pzb248L2E+CiAqIDwvcD4KICoKICogQGF1dGhvciBHb29nbGUsIEluYy4KICovCkBTdXBwcmVzc1dhcm5pbmdzKCJqYXZhZG9jIikKcHVibGljIGZpbmFsIGNsYXNzIFF1ZXJ5R3JhbnRhYmxlUm9sZXNSZXF1ZXN0IGV4dGVuZHMgY29tLmdvb2dsZS5hcGkuY2xpZW50Lmpzb24uR2VuZXJpY0pzb24gewoKICAvKioKICAgKiBSZXF1aXJlZC4gVGhlIGZ1bGwgcmVzb3VyY2UgbmFtZSB0byBxdWVyeSBmcm9tIHRoZSBsaXN0IG9mIGdyYW50YWJsZSByb2xlcy4KICAgKgogICAqIFRoZSBuYW1lIGZvbGxvd3MgdGhlIEdvb2dsZSBDbG91ZCBQbGF0Zm9ybSByZXNvdXJjZSBmb3JtYXQuIEZvciBleGFtcGxlLCBhIENsb3VkIFBsYXRmb3JtCiAgICogcHJvamVjdCB3aXRoIGlkIGBteS1wcm9qZWN0YCB3aWxsIGJlIG5hbWVkIGAvL2Nsb3VkcmVzb3VyY2VtYW5hZ2VyLmdvb2dsZWFwaXMuY29tL3Byb2plY3RzL215LQogICAqIHByb2plY3RgLgogICAqIFRoZSB2YWx1ZSBtYXkgYmUge0Bjb2RlIG51bGx9LgogICAqLwogIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICBwcml2YXRlIGphdmEubGFuZy5TdHJpbmcgZnVsbFJlc291cmNlTmFtZTsKCiAgLyoqCiAgICogT3B0aW9uYWwgbGltaXQgb24gdGhlIG51bWJlciBvZiByb2xlcyB0byBpbmNsdWRlIGluIHRoZSByZXNwb25zZS4KICAgKiBUaGUgdmFsdWUgbWF5IGJlIHtAY29kZSBudWxsfS4KICAgKi8KICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgcHJpdmF0ZSBqYXZhLmxhbmcuSW50ZWdlciBwYWdlU2l6ZTsKCiAgLyoqCiAgICogT3B0aW9uYWwgcGFnaW5hdGlvbiB0b2tlbiByZXR1cm5lZCBpbiBhbiBlYXJsaWVyIFF1ZXJ5R3JhbnRhYmxlUm9sZXNSZXNwb25zZS4KICAgKiBUaGUgdmFsdWUgbWF5IGJlIHtAY29kZSBudWxsfS4KICAgKi8KICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgcHJpdmF0ZSBqYXZhLmxhbmcuU3RyaW5nIHBhZ2VUb2tlbjsKCiAgLyoqCiAgICogVGhlIHZhbHVlIG1heSBiZSB7QGNvZGUgbnVsbH0uCiAgICovCiAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogIHByaXZhdGUgamF2YS5sYW5nLlN0cmluZyB2aWV3OwoKICAvKioKICAgKiBSZXF1aXJlZC4gVGhlIGZ1bGwgcmVzb3VyY2UgbmFtZSB0byBxdWVyeSBmcm9tIHRoZSBsaXN0IG9mIGdyYW50YWJsZSByb2xlcy4KICAgKgogICAqIFRoZSBuYW1lIGZvbGxvd3MgdGhlIEdvb2dsZSBDbG91ZCBQbGF0Zm9ybSByZXNvdXJjZSBmb3JtYXQuIEZvciBleGFtcGxlLCBhIENsb3VkIFBsYXRmb3JtCiAgICogcHJvamVjdCB3aXRoIGlkIGBteS1wcm9qZWN0YCB3aWxsIGJlIG5hbWVkIGAvL2Nsb3VkcmVzb3VyY2VtYW5hZ2VyLmdvb2dsZWFwaXMuY29tL3Byb2plY3RzL215LQogICAqIHByb2plY3RgLgogICAqIEByZXR1cm4gdmFsdWUgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0RnVsbFJlc291cmNlTmFtZSgpIHsKICAgIHJldHVybiBmdWxsUmVzb3VyY2VOYW1lOwogIH0KCiAgLyoqCiAgICogUmVxdWlyZWQuIFRoZSBmdWxsIHJlc291cmNlIG5hbWUgdG8gcXVlcnkgZnJvbSB0aGUgbGlzdCBvZiBncmFudGFibGUgcm9sZXMuCiAgICoKICAgKiBUaGUgbmFtZSBmb2xsb3dzIHRoZSBHb29nbGUgQ2xvdWQgUGxhdGZvcm0gcmVzb3VyY2UgZm9ybWF0LiBGb3IgZXhhbXBsZSwgYSBDbG91ZCBQbGF0Zm9ybQogICAqIHByb2plY3Qgd2l0aCBpZCBgbXktcHJvamVjdGAgd2lsbCBiZSBuYW1lZCBgLy9jbG91ZHJlc291cmNlbWFuYWdlci5nb29nbGVhcGlzLmNvbS9wcm9qZWN0cy9teS0KICAgKiBwcm9qZWN0YC4KICAgKiBAcGFyYW0gZnVsbFJlc291cmNlTmFtZSBmdWxsUmVzb3VyY2VOYW1lIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBRdWVyeUdyYW50YWJsZVJvbGVzUmVxdWVzdCBzZXRGdWxsUmVzb3VyY2VOYW1lKGphdmEubGFuZy5TdHJpbmcgZnVsbFJlc291cmNlTmFtZSkgewogICAgdGhpcy5mdWxsUmVzb3VyY2VOYW1lID0gZnVsbFJlc291cmNlTmFtZTsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgLyoqCiAgICogT3B0aW9uYWwgbGltaXQgb24gdGhlIG51bWJlciBvZiByb2xlcyB0byBpbmNsdWRlIGluIHRoZSByZXNwb25zZS4KICAgKiBAcmV0dXJuIHZhbHVlIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBqYXZhLmxhbmcuSW50ZWdlciBnZXRQYWdlU2l6ZSgpIHsKICAgIHJldHVybiBwYWdlU2l6ZTsKICB9CgogIC8qKgogICAqIE9wdGlvbmFsIGxpbWl0IG9uIHRoZSBudW1iZXIgb2Ygcm9sZXMgdG8gaW5jbHVkZSBpbiB0aGUgcmVzcG9uc2UuCiAgICogQHBhcmFtIHBhZ2VTaXplIHBhZ2VTaXplIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBRdWVyeUdyYW50YWJsZVJvbGVzUmVxdWVzdCBzZXRQYWdlU2l6ZShqYXZhLmxhbmcuSW50ZWdlciBwYWdlU2l6ZSkgewogICAgdGhpcy5wYWdlU2l6ZSA9IHBhZ2VTaXplOwogICAgcmV0dXJuIHRoaXM7CiAgfQoKICAvKioKICAgKiBPcHRpb25hbCBwYWdpbmF0aW9uIHRva2VuIHJldHVybmVkIGluIGFuIGVhcmxpZXIgUXVlcnlHcmFudGFibGVSb2xlc1Jlc3BvbnNlLgogICAqIEByZXR1cm4gdmFsdWUgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0UGFnZVRva2VuKCkgewogICAgcmV0dXJuIHBhZ2VUb2tlbjsKICB9CgogIC8qKgogICAqIE9wdGlvbmFsIHBhZ2luYXRpb24gdG9rZW4gcmV0dXJuZWQgaW4gYW4gZWFybGllciBRdWVyeUdyYW50YWJsZVJvbGVzUmVzcG9uc2UuCiAgICogQHBhcmFtIHBhZ2VUb2tlbiBwYWdlVG9rZW4gb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIFF1ZXJ5R3JhbnRhYmxlUm9sZXNSZXF1ZXN0IHNldFBhZ2VUb2tlbihqYXZhLmxhbmcuU3RyaW5nIHBhZ2VUb2tlbikgewogICAgdGhpcy5wYWdlVG9rZW4gPSBwYWdlVG9rZW47CiAgICByZXR1cm4gdGhpczsKICB9CgogIC8qKgogICAqIEByZXR1cm4gdmFsdWUgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0VmlldygpIHsKICAgIHJldHVybiB2aWV3OwogIH0KCiAgLyoqCiAgICogQHBhcmFtIHZpZXcgdmlldyBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgUXVlcnlHcmFudGFibGVSb2xlc1JlcXVlc3Qgc2V0VmlldyhqYXZhLmxhbmcuU3RyaW5nIHZpZXcpIHsKICAgIHRoaXMudmlldyA9IHZpZXc7CiAgICByZXR1cm4gdGhpczsKICB9CgogIEBPdmVycmlkZQogIHB1YmxpYyBRdWVyeUdyYW50YWJsZVJvbGVzUmVxdWVzdCBzZXQoU3RyaW5nIGZpZWxkTmFtZSwgT2JqZWN0IHZhbHVlKSB7CiAgICByZXR1cm4gKFF1ZXJ5R3JhbnRhYmxlUm9sZXNSZXF1ZXN0KSBzdXBlci5zZXQoZmllbGROYW1lLCB2YWx1ZSk7CiAgfQoKICBAT3ZlcnJpZGUKICBwdWJsaWMgUXVlcnlHcmFudGFibGVSb2xlc1JlcXVlc3QgY2xvbmUoKSB7CiAgICByZXR1cm4gKFF1ZXJ5R3JhbnRhYmxlUm9sZXNSZXF1ZXN0KSBzdXBlci5jbG9uZSgpOwogIH0KCn0KUEsDBBQAAAAAAAAAIQAL6zS46wsAAOsLAABFAAAAY29tL2dvb2dsZS9hcGkvc2VydmljZXMvaWFtL3YxL21vZGVsL1F1ZXJ5R3JhbnRhYmxlUm9sZXNSZXNwb25zZS5qYXZhLyoKICogQ29weXJpZ2h0IDIwMTAgR29vZ2xlIEluYy4KICoKICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0CiAqIGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4gWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlCiAqIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcwogKiBvciBpbXBsaWVkLiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zIHVuZGVyCiAqIHRoZSBMaWNlbnNlLgogKi8KLyoKICogVGhpcyBjb2RlIHdhcyBnZW5lcmF0ZWQgYnkgaHR0cHM6Ly9naXRodWIuY29tL2dvb2dsZS9hcGlzLWNsaWVudC1nZW5lcmF0b3IvCiAqIChidWlsZDogMjAxOC0xMC0wOCAxNzo0NTozOSBVVEMpCiAqIG9uIDIwMjAtMDMtMTkgYXQgMDE6NTI6NDEgVVRDIAogKiBNb2RpZnkgYXQgeW91ciBvd24gcmlzay4KICovCgpwYWNrYWdlIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmlhbS52MS5tb2RlbDsKCi8qKgogKiBUaGUgZ3JhbnRhYmxlIHJvbGUgcXVlcnkgcmVzcG9uc2UuCiAqCiAqIDxwPiBUaGlzIGlzIHRoZSBKYXZhIGRhdGEgbW9kZWwgY2xhc3MgdGhhdCBzcGVjaWZpZXMgaG93IHRvIHBhcnNlL3NlcmlhbGl6ZSBpbnRvIHRoZSBKU09OIHRoYXQgaXMKICogdHJhbnNtaXR0ZWQgb3ZlciBIVFRQIHdoZW4gd29ya2luZyB3aXRoIHRoZSBJZGVudGl0eSBhbmQgQWNjZXNzIE1hbmFnZW1lbnQgKElBTSkgQVBJLiBGb3IgYQogKiBkZXRhaWxlZCBleHBsYW5hdGlvbiBzZWU6CiAqIDxhIGhyZWY9Imh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL2FwaS1jbGllbnQtbGlicmFyeS9qYXZhL2dvb2dsZS1odHRwLWphdmEtY2xpZW50L2pzb24iPmh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL2FwaS1jbGllbnQtbGlicmFyeS9qYXZhL2dvb2dsZS1odHRwLWphdmEtY2xpZW50L2pzb248L2E+CiAqIDwvcD4KICoKICogQGF1dGhvciBHb29nbGUsIEluYy4KICovCkBTdXBwcmVzc1dhcm5pbmdzKCJqYXZhZG9jIikKcHVibGljIGZpbmFsIGNsYXNzIFF1ZXJ5R3JhbnRhYmxlUm9sZXNSZXNwb25zZSBleHRlbmRzIGNvbS5nb29nbGUuYXBpLmNsaWVudC5qc29uLkdlbmVyaWNKc29uIHsKCiAgLyoqCiAgICogVG8gcmV0cmlldmUgdGhlIG5leHQgcGFnZSBvZiByZXN1bHRzLCBzZXQgYFF1ZXJ5R3JhbnRhYmxlUm9sZXNSZXF1ZXN0LnBhZ2VfdG9rZW5gIHRvIHRoaXMKICAgKiB2YWx1ZS4KICAgKiBUaGUgdmFsdWUgbWF5IGJlIHtAY29kZSBudWxsfS4KICAgKi8KICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgcHJpdmF0ZSBqYXZhLmxhbmcuU3RyaW5nIG5leHRQYWdlVG9rZW47CgogIC8qKgogICAqIFRoZSBsaXN0IG9mIG1hdGNoaW5nIHJvbGVzLgogICAqIFRoZSB2YWx1ZSBtYXkgYmUge0Bjb2RlIG51bGx9LgogICAqLwogIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICBwcml2YXRlIGphdmEudXRpbC5MaXN0PFJvbGU+IHJvbGVzOwoKICAvKioKICAgKiBUbyByZXRyaWV2ZSB0aGUgbmV4dCBwYWdlIG9mIHJlc3VsdHMsIHNldCBgUXVlcnlHcmFudGFibGVSb2xlc1JlcXVlc3QucGFnZV90b2tlbmAgdG8gdGhpcwogICAqIHZhbHVlLgogICAqIEByZXR1cm4gdmFsdWUgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TmV4dFBhZ2VUb2tlbigpIHsKICAgIHJldHVybiBuZXh0UGFnZVRva2VuOwogIH0KCiAgLyoqCiAgICogVG8gcmV0cmlldmUgdGhlIG5leHQgcGFnZSBvZiByZXN1bHRzLCBzZXQgYFF1ZXJ5R3JhbnRhYmxlUm9sZXNSZXF1ZXN0LnBhZ2VfdG9rZW5gIHRvIHRoaXMKICAgKiB2YWx1ZS4KICAgKiBAcGFyYW0gbmV4dFBhZ2VUb2tlbiBuZXh0UGFnZVRva2VuIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBRdWVyeUdyYW50YWJsZVJvbGVzUmVzcG9uc2Ugc2V0TmV4dFBhZ2VUb2tlbihqYXZhLmxhbmcuU3RyaW5nIG5leHRQYWdlVG9rZW4pIHsKICAgIHRoaXMubmV4dFBhZ2VUb2tlbiA9IG5leHRQYWdlVG9rZW47CiAgICByZXR1cm4gdGhpczsKICB9CgogIC8qKgogICAqIFRoZSBsaXN0IG9mIG1hdGNoaW5nIHJvbGVzLgogICAqIEByZXR1cm4gdmFsdWUgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIGphdmEudXRpbC5MaXN0PFJvbGU+IGdldFJvbGVzKCkgewogICAgcmV0dXJuIHJvbGVzOwogIH0KCiAgLyoqCiAgICogVGhlIGxpc3Qgb2YgbWF0Y2hpbmcgcm9sZXMuCiAgICogQHBhcmFtIHJvbGVzIHJvbGVzIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBRdWVyeUdyYW50YWJsZVJvbGVzUmVzcG9uc2Ugc2V0Um9sZXMoamF2YS51dGlsLkxpc3Q8Um9sZT4gcm9sZXMpIHsKICAgIHRoaXMucm9sZXMgPSByb2xlczsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgQE92ZXJyaWRlCiAgcHVibGljIFF1ZXJ5R3JhbnRhYmxlUm9sZXNSZXNwb25zZSBzZXQoU3RyaW5nIGZpZWxkTmFtZSwgT2JqZWN0IHZhbHVlKSB7CiAgICByZXR1cm4gKFF1ZXJ5R3JhbnRhYmxlUm9sZXNSZXNwb25zZSkgc3VwZXIuc2V0KGZpZWxkTmFtZSwgdmFsdWUpOwogIH0KCiAgQE92ZXJyaWRlCiAgcHVibGljIFF1ZXJ5R3JhbnRhYmxlUm9sZXNSZXNwb25zZSBjbG9uZSgpIHsKICAgIHJldHVybiAoUXVlcnlHcmFudGFibGVSb2xlc1Jlc3BvbnNlKSBzdXBlci5jbG9uZSgpOwogIH0KCn0KUEsDBBQAAAAAAAAAIQCHh+AB5hEAAOYRAABJAAAAY29tL2dvb2dsZS9hcGkvc2VydmljZXMvaWFtL3YxL21vZGVsL1F1ZXJ5VGVzdGFibGVQZXJtaXNzaW9uc1JlcXVlc3QuamF2YS8qCiAqIENvcHlyaWdodCAyMDEwIEdvb2dsZSBJbmMuCiAqCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdAogKiBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZQogKiBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3MKICogb3IgaW1wbGllZC4gU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucyB1bmRlcgogKiB0aGUgTGljZW5zZS4KICovCi8qCiAqIFRoaXMgY29kZSB3YXMgZ2VuZXJhdGVkIGJ5IGh0dHBzOi8vZ2l0aHViLmNvbS9nb29nbGUvYXBpcy1jbGllbnQtZ2VuZXJhdG9yLwogKiAoYnVpbGQ6IDIwMTgtMTAtMDggMTc6NDU6MzkgVVRDKQogKiBvbiAyMDIwLTAzLTE5IGF0IDAxOjUyOjQxIFVUQyAKICogTW9kaWZ5IGF0IHlvdXIgb3duIHJpc2suCiAqLwoKcGFja2FnZSBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5pYW0udjEubW9kZWw7CgovKioKICogQSByZXF1ZXN0IHRvIGdldCBwZXJtaXNzaW9ucyB3aGljaCBjYW4gYmUgdGVzdGVkIG9uIGEgcmVzb3VyY2UuCiAqCiAqIDxwPiBUaGlzIGlzIHRoZSBKYXZhIGRhdGEgbW9kZWwgY2xhc3MgdGhhdCBzcGVjaWZpZXMgaG93IHRvIHBhcnNlL3NlcmlhbGl6ZSBpbnRvIHRoZSBKU09OIHRoYXQgaXMKICogdHJhbnNtaXR0ZWQgb3ZlciBIVFRQIHdoZW4gd29ya2luZyB3aXRoIHRoZSBJZGVudGl0eSBhbmQgQWNjZXNzIE1hbmFnZW1lbnQgKElBTSkgQVBJLiBGb3IgYQogKiBkZXRhaWxlZCBleHBsYW5hdGlvbiBzZWU6CiAqIDxhIGhyZWY9Imh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL2FwaS1jbGllbnQtbGlicmFyeS9qYXZhL2dvb2dsZS1odHRwLWphdmEtY2xpZW50L2pzb24iPmh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL2FwaS1jbGllbnQtbGlicmFyeS9qYXZhL2dvb2dsZS1odHRwLWphdmEtY2xpZW50L2pzb248L2E+CiAqIDwvcD4KICoKICogQGF1dGhvciBHb29nbGUsIEluYy4KICovCkBTdXBwcmVzc1dhcm5pbmdzKCJqYXZhZG9jIikKcHVibGljIGZpbmFsIGNsYXNzIFF1ZXJ5VGVzdGFibGVQZXJtaXNzaW9uc1JlcXVlc3QgZXh0ZW5kcyBjb20uZ29vZ2xlLmFwaS5jbGllbnQuanNvbi5HZW5lcmljSnNvbiB7CgogIC8qKgogICAqIFJlcXVpcmVkLiBUaGUgZnVsbCByZXNvdXJjZSBuYW1lIHRvIHF1ZXJ5IGZyb20gdGhlIGxpc3Qgb2YgdGVzdGFibGUgcGVybWlzc2lvbnMuCiAgICoKICAgKiBUaGUgbmFtZSBmb2xsb3dzIHRoZSBHb29nbGUgQ2xvdWQgUGxhdGZvcm0gcmVzb3VyY2UgZm9ybWF0LiBGb3IgZXhhbXBsZSwgYSBDbG91ZCBQbGF0Zm9ybQogICAqIHByb2plY3Qgd2l0aCBpZCBgbXktcHJvamVjdGAgd2lsbCBiZSBuYW1lZCBgLy9jbG91ZHJlc291cmNlbWFuYWdlci5nb29nbGVhcGlzLmNvbS9wcm9qZWN0cy9teS0KICAgKiBwcm9qZWN0YC4KICAgKiBUaGUgdmFsdWUgbWF5IGJlIHtAY29kZSBudWxsfS4KICAgKi8KICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgcHJpdmF0ZSBqYXZhLmxhbmcuU3RyaW5nIGZ1bGxSZXNvdXJjZU5hbWU7CgogIC8qKgogICAqIE9wdGlvbmFsIGxpbWl0IG9uIHRoZSBudW1iZXIgb2YgcGVybWlzc2lvbnMgdG8gaW5jbHVkZSBpbiB0aGUgcmVzcG9uc2UuCiAgICogVGhlIHZhbHVlIG1heSBiZSB7QGNvZGUgbnVsbH0uCiAgICovCiAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogIHByaXZhdGUgamF2YS5sYW5nLkludGVnZXIgcGFnZVNpemU7CgogIC8qKgogICAqIE9wdGlvbmFsIHBhZ2luYXRpb24gdG9rZW4gcmV0dXJuZWQgaW4gYW4gZWFybGllciBRdWVyeVRlc3RhYmxlUGVybWlzc2lvbnNSZXF1ZXN0LgogICAqIFRoZSB2YWx1ZSBtYXkgYmUge0Bjb2RlIG51bGx9LgogICAqLwogIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICBwcml2YXRlIGphdmEubGFuZy5TdHJpbmcgcGFnZVRva2VuOwoKICAvKioKICAgKiBSZXF1aXJlZC4gVGhlIGZ1bGwgcmVzb3VyY2UgbmFtZSB0byBxdWVyeSBmcm9tIHRoZSBsaXN0IG9mIHRlc3RhYmxlIHBlcm1pc3Npb25zLgogICAqCiAgICogVGhlIG5hbWUgZm9sbG93cyB0aGUgR29vZ2xlIENsb3VkIFBsYXRmb3JtIHJlc291cmNlIGZvcm1hdC4gRm9yIGV4YW1wbGUsIGEgQ2xvdWQgUGxhdGZvcm0KICAgKiBwcm9qZWN0IHdpdGggaWQgYG15LXByb2plY3RgIHdpbGwgYmUgbmFtZWQgYC8vY2xvdWRyZXNvdXJjZW1hbmFnZXIuZ29vZ2xlYXBpcy5jb20vcHJvamVjdHMvbXktCiAgICogcHJvamVjdGAuCiAgICogQHJldHVybiB2YWx1ZSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRGdWxsUmVzb3VyY2VOYW1lKCkgewogICAgcmV0dXJuIGZ1bGxSZXNvdXJjZU5hbWU7CiAgfQoKICAvKioKICAgKiBSZXF1aXJlZC4gVGhlIGZ1bGwgcmVzb3VyY2UgbmFtZSB0byBxdWVyeSBmcm9tIHRoZSBsaXN0IG9mIHRlc3RhYmxlIHBlcm1pc3Npb25zLgogICAqCiAgICogVGhlIG5hbWUgZm9sbG93cyB0aGUgR29vZ2xlIENsb3VkIFBsYXRmb3JtIHJlc291cmNlIGZvcm1hdC4gRm9yIGV4YW1wbGUsIGEgQ2xvdWQgUGxhdGZvcm0KICAgKiBwcm9qZWN0IHdpdGggaWQgYG15LXByb2plY3RgIHdpbGwgYmUgbmFtZWQgYC8vY2xvdWRyZXNvdXJjZW1hbmFnZXIuZ29vZ2xlYXBpcy5jb20vcHJvamVjdHMvbXktCiAgICogcHJvamVjdGAuCiAgICogQHBhcmFtIGZ1bGxSZXNvdXJjZU5hbWUgZnVsbFJlc291cmNlTmFtZSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgUXVlcnlUZXN0YWJsZVBlcm1pc3Npb25zUmVxdWVzdCBzZXRGdWxsUmVzb3VyY2VOYW1lKGphdmEubGFuZy5TdHJpbmcgZnVsbFJlc291cmNlTmFtZSkgewogICAgdGhpcy5mdWxsUmVzb3VyY2VOYW1lID0gZnVsbFJlc291cmNlTmFtZTsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgLyoqCiAgICogT3B0aW9uYWwgbGltaXQgb24gdGhlIG51bWJlciBvZiBwZXJtaXNzaW9ucyB0byBpbmNsdWRlIGluIHRoZSByZXNwb25zZS4KICAgKiBAcmV0dXJuIHZhbHVlIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBqYXZhLmxhbmcuSW50ZWdlciBnZXRQYWdlU2l6ZSgpIHsKICAgIHJldHVybiBwYWdlU2l6ZTsKICB9CgogIC8qKgogICAqIE9wdGlvbmFsIGxpbWl0IG9uIHRoZSBudW1iZXIgb2YgcGVybWlzc2lvbnMgdG8gaW5jbHVkZSBpbiB0aGUgcmVzcG9uc2UuCiAgICogQHBhcmFtIHBhZ2VTaXplIHBhZ2VTaXplIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBRdWVyeVRlc3RhYmxlUGVybWlzc2lvbnNSZXF1ZXN0IHNldFBhZ2VTaXplKGphdmEubGFuZy5JbnRlZ2VyIHBhZ2VTaXplKSB7CiAgICB0aGlzLnBhZ2VTaXplID0gcGFnZVNpemU7CiAgICByZXR1cm4gdGhpczsKICB9CgogIC8qKgogICAqIE9wdGlvbmFsIHBhZ2luYXRpb24gdG9rZW4gcmV0dXJuZWQgaW4gYW4gZWFybGllciBRdWVyeVRlc3RhYmxlUGVybWlzc2lvbnNSZXF1ZXN0LgogICAqIEByZXR1cm4gdmFsdWUgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0UGFnZVRva2VuKCkgewogICAgcmV0dXJuIHBhZ2VUb2tlbjsKICB9CgogIC8qKgogICAqIE9wdGlvbmFsIHBhZ2luYXRpb24gdG9rZW4gcmV0dXJuZWQgaW4gYW4gZWFybGllciBRdWVyeVRlc3RhYmxlUGVybWlzc2lvbnNSZXF1ZXN0LgogICAqIEBwYXJhbSBwYWdlVG9rZW4gcGFnZVRva2VuIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBRdWVyeVRlc3RhYmxlUGVybWlzc2lvbnNSZXF1ZXN0IHNldFBhZ2VUb2tlbihqYXZhLmxhbmcuU3RyaW5nIHBhZ2VUb2tlbikgewogICAgdGhpcy5wYWdlVG9rZW4gPSBwYWdlVG9rZW47CiAgICByZXR1cm4gdGhpczsKICB9CgogIEBPdmVycmlkZQogIHB1YmxpYyBRdWVyeVRlc3RhYmxlUGVybWlzc2lvbnNSZXF1ZXN0IHNldChTdHJpbmcgZmllbGROYW1lLCBPYmplY3QgdmFsdWUpIHsKICAgIHJldHVybiAoUXVlcnlUZXN0YWJsZVBlcm1pc3Npb25zUmVxdWVzdCkgc3VwZXIuc2V0KGZpZWxkTmFtZSwgdmFsdWUpOwogIH0KCiAgQE92ZXJyaWRlCiAgcHVibGljIFF1ZXJ5VGVzdGFibGVQZXJtaXNzaW9uc1JlcXVlc3QgY2xvbmUoKSB7CiAgICByZXR1cm4gKFF1ZXJ5VGVzdGFibGVQZXJtaXNzaW9uc1JlcXVlc3QpIHN1cGVyLmNsb25lKCk7CiAgfQoKfQpQSwMEFAAAAAAAAAAhAPC+IvmwDAAAsAwAAEoAAABjb20vZ29vZ2xlL2FwaS9zZXJ2aWNlcy9pYW0vdjEvbW9kZWwvUXVlcnlUZXN0YWJsZVBlcm1pc3Npb25zUmVzcG9uc2UuamF2YS8qCiAqIENvcHlyaWdodCAyMDEwIEdvb2dsZSBJbmMuCiAqCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdAogKiBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZQogKiBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3MKICogb3IgaW1wbGllZC4gU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucyB1bmRlcgogKiB0aGUgTGljZW5zZS4KICovCi8qCiAqIFRoaXMgY29kZSB3YXMgZ2VuZXJhdGVkIGJ5IGh0dHBzOi8vZ2l0aHViLmNvbS9nb29nbGUvYXBpcy1jbGllbnQtZ2VuZXJhdG9yLwogKiAoYnVpbGQ6IDIwMTgtMTAtMDggMTc6NDU6MzkgVVRDKQogKiBvbiAyMDIwLTAzLTE5IGF0IDAxOjUyOjQxIFVUQyAKICogTW9kaWZ5IGF0IHlvdXIgb3duIHJpc2suCiAqLwoKcGFja2FnZSBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5pYW0udjEubW9kZWw7CgovKioKICogVGhlIHJlc3BvbnNlIGNvbnRhaW5pbmcgcGVybWlzc2lvbnMgd2hpY2ggY2FuIGJlIHRlc3RlZCBvbiBhIHJlc291cmNlLgogKgogKiA8cD4gVGhpcyBpcyB0aGUgSmF2YSBkYXRhIG1vZGVsIGNsYXNzIHRoYXQgc3BlY2lmaWVzIGhvdyB0byBwYXJzZS9zZXJpYWxpemUgaW50byB0aGUgSlNPTiB0aGF0IGlzCiAqIHRyYW5zbWl0dGVkIG92ZXIgSFRUUCB3aGVuIHdvcmtpbmcgd2l0aCB0aGUgSWRlbnRpdHkgYW5kIEFjY2VzcyBNYW5hZ2VtZW50IChJQU0pIEFQSS4gRm9yIGEKICogZGV0YWlsZWQgZXhwbGFuYXRpb24gc2VlOgogKiA8YSBocmVmPSJodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9hcGktY2xpZW50LWxpYnJhcnkvamF2YS9nb29nbGUtaHR0cC1qYXZhLWNsaWVudC9qc29uIj5odHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9hcGktY2xpZW50LWxpYnJhcnkvamF2YS9nb29nbGUtaHR0cC1qYXZhLWNsaWVudC9qc29uPC9hPgogKiA8L3A+CiAqCiAqIEBhdXRob3IgR29vZ2xlLCBJbmMuCiAqLwpAU3VwcHJlc3NXYXJuaW5ncygiamF2YWRvYyIpCnB1YmxpYyBmaW5hbCBjbGFzcyBRdWVyeVRlc3RhYmxlUGVybWlzc2lvbnNSZXNwb25zZSBleHRlbmRzIGNvbS5nb29nbGUuYXBpLmNsaWVudC5qc29uLkdlbmVyaWNKc29uIHsKCiAgLyoqCiAgICogVG8gcmV0cmlldmUgdGhlIG5leHQgcGFnZSBvZiByZXN1bHRzLCBzZXQgYFF1ZXJ5VGVzdGFibGVSb2xlc1JlcXVlc3QucGFnZV90b2tlbmAgdG8gdGhpcyB2YWx1ZS4KICAgKiBUaGUgdmFsdWUgbWF5IGJlIHtAY29kZSBudWxsfS4KICAgKi8KICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgcHJpdmF0ZSBqYXZhLmxhbmcuU3RyaW5nIG5leHRQYWdlVG9rZW47CgogIC8qKgogICAqIFRoZSBQZXJtaXNzaW9ucyB0ZXN0YWJsZSBvbiB0aGUgcmVxdWVzdGVkIHJlc291cmNlLgogICAqIFRoZSB2YWx1ZSBtYXkgYmUge0Bjb2RlIG51bGx9LgogICAqLwogIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICBwcml2YXRlIGphdmEudXRpbC5MaXN0PFBlcm1pc3Npb24+IHBlcm1pc3Npb25zOwoKICAvKioKICAgKiBUbyByZXRyaWV2ZSB0aGUgbmV4dCBwYWdlIG9mIHJlc3VsdHMsIHNldCBgUXVlcnlUZXN0YWJsZVJvbGVzUmVxdWVzdC5wYWdlX3Rva2VuYCB0byB0aGlzIHZhbHVlLgogICAqIEByZXR1cm4gdmFsdWUgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TmV4dFBhZ2VUb2tlbigpIHsKICAgIHJldHVybiBuZXh0UGFnZVRva2VuOwogIH0KCiAgLyoqCiAgICogVG8gcmV0cmlldmUgdGhlIG5leHQgcGFnZSBvZiByZXN1bHRzLCBzZXQgYFF1ZXJ5VGVzdGFibGVSb2xlc1JlcXVlc3QucGFnZV90b2tlbmAgdG8gdGhpcyB2YWx1ZS4KICAgKiBAcGFyYW0gbmV4dFBhZ2VUb2tlbiBuZXh0UGFnZVRva2VuIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBRdWVyeVRlc3RhYmxlUGVybWlzc2lvbnNSZXNwb25zZSBzZXROZXh0UGFnZVRva2VuKGphdmEubGFuZy5TdHJpbmcgbmV4dFBhZ2VUb2tlbikgewogICAgdGhpcy5uZXh0UGFnZVRva2VuID0gbmV4dFBhZ2VUb2tlbjsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgLyoqCiAgICogVGhlIFBlcm1pc3Npb25zIHRlc3RhYmxlIG9uIHRoZSByZXF1ZXN0ZWQgcmVzb3VyY2UuCiAgICogQHJldHVybiB2YWx1ZSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8UGVybWlzc2lvbj4gZ2V0UGVybWlzc2lvbnMoKSB7CiAgICByZXR1cm4gcGVybWlzc2lvbnM7CiAgfQoKICAvKioKICAgKiBUaGUgUGVybWlzc2lvbnMgdGVzdGFibGUgb24gdGhlIHJlcXVlc3RlZCByZXNvdXJjZS4KICAgKiBAcGFyYW0gcGVybWlzc2lvbnMgcGVybWlzc2lvbnMgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIFF1ZXJ5VGVzdGFibGVQZXJtaXNzaW9uc1Jlc3BvbnNlIHNldFBlcm1pc3Npb25zKGphdmEudXRpbC5MaXN0PFBlcm1pc3Npb24+IHBlcm1pc3Npb25zKSB7CiAgICB0aGlzLnBlcm1pc3Npb25zID0gcGVybWlzc2lvbnM7CiAgICByZXR1cm4gdGhpczsKICB9CgogIEBPdmVycmlkZQogIHB1YmxpYyBRdWVyeVRlc3RhYmxlUGVybWlzc2lvbnNSZXNwb25zZSBzZXQoU3RyaW5nIGZpZWxkTmFtZSwgT2JqZWN0IHZhbHVlKSB7CiAgICByZXR1cm4gKFF1ZXJ5VGVzdGFibGVQZXJtaXNzaW9uc1Jlc3BvbnNlKSBzdXBlci5zZXQoZmllbGROYW1lLCB2YWx1ZSk7CiAgfQoKICBAT3ZlcnJpZGUKICBwdWJsaWMgUXVlcnlUZXN0YWJsZVBlcm1pc3Npb25zUmVzcG9uc2UgY2xvbmUoKSB7CiAgICByZXR1cm4gKFF1ZXJ5VGVzdGFibGVQZXJtaXNzaW9uc1Jlc3BvbnNlKSBzdXBlci5jbG9uZSgpOwogIH0KCn0KUEsDBBQAAAAAAAAAIQACrr2Onx8AAJ8fAAAuAAAAY29tL2dvb2dsZS9hcGkvc2VydmljZXMvaWFtL3YxL21vZGVsL1JvbGUuamF2YS8qCiAqIENvcHlyaWdodCAyMDEwIEdvb2dsZSBJbmMuCiAqCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdAogKiBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZQogKiBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3MKICogb3IgaW1wbGllZC4gU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucyB1bmRlcgogKiB0aGUgTGljZW5zZS4KICovCi8qCiAqIFRoaXMgY29kZSB3YXMgZ2VuZXJhdGVkIGJ5IGh0dHBzOi8vZ2l0aHViLmNvbS9nb29nbGUvYXBpcy1jbGllbnQtZ2VuZXJhdG9yLwogKiAoYnVpbGQ6IDIwMTgtMTAtMDggMTc6NDU6MzkgVVRDKQogKiBvbiAyMDIwLTAzLTE5IGF0IDAxOjUyOjQxIFVUQyAKICogTW9kaWZ5IGF0IHlvdXIgb3duIHJpc2suCiAqLwoKcGFja2FnZSBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5pYW0udjEubW9kZWw7CgovKioKICogQSByb2xlIGluIHRoZSBJZGVudGl0eSBhbmQgQWNjZXNzIE1hbmFnZW1lbnQgQVBJLgogKgogKiA8cD4gVGhpcyBpcyB0aGUgSmF2YSBkYXRhIG1vZGVsIGNsYXNzIHRoYXQgc3BlY2lmaWVzIGhvdyB0byBwYXJzZS9zZXJpYWxpemUgaW50byB0aGUgSlNPTiB0aGF0IGlzCiAqIHRyYW5zbWl0dGVkIG92ZXIgSFRUUCB3aGVuIHdvcmtpbmcgd2l0aCB0aGUgSWRlbnRpdHkgYW5kIEFjY2VzcyBNYW5hZ2VtZW50IChJQU0pIEFQSS4gRm9yIGEKICogZGV0YWlsZWQgZXhwbGFuYXRpb24gc2VlOgogKiA8YSBocmVmPSJodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9hcGktY2xpZW50LWxpYnJhcnkvamF2YS9nb29nbGUtaHR0cC1qYXZhLWNsaWVudC9qc29uIj5odHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9hcGktY2xpZW50LWxpYnJhcnkvamF2YS9nb29nbGUtaHR0cC1qYXZhLWNsaWVudC9qc29uPC9hPgogKiA8L3A+CiAqCiAqIEBhdXRob3IgR29vZ2xlLCBJbmMuCiAqLwpAU3VwcHJlc3NXYXJuaW5ncygiamF2YWRvYyIpCnB1YmxpYyBmaW5hbCBjbGFzcyBSb2xlIGV4dGVuZHMgY29tLmdvb2dsZS5hcGkuY2xpZW50Lmpzb24uR2VuZXJpY0pzb24gewoKICAvKioKICAgKiBUaGUgY3VycmVudCBkZWxldGVkIHN0YXRlIG9mIHRoZSByb2xlLiBUaGlzIGZpZWxkIGlzIHJlYWQgb25seS4gSXQgd2lsbCBiZSBpZ25vcmVkIGluIGNhbGxzIHRvCiAgICogQ3JlYXRlUm9sZSBhbmQgVXBkYXRlUm9sZS4KICAgKiBUaGUgdmFsdWUgbWF5IGJlIHtAY29kZSBudWxsfS4KICAgKi8KICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgcHJpdmF0ZSBqYXZhLmxhbmcuQm9vbGVhbiBkZWxldGVkOwoKICAvKioKICAgKiBPcHRpb25hbC4gQSBodW1hbi1yZWFkYWJsZSBkZXNjcmlwdGlvbiBmb3IgdGhlIHJvbGUuCiAgICogVGhlIHZhbHVlIG1heSBiZSB7QGNvZGUgbnVsbH0uCiAgICovCiAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogIHByaXZhdGUgamF2YS5sYW5nLlN0cmluZyBkZXNjcmlwdGlvbjsKCiAgLyoqCiAgICogVXNlZCB0byBwZXJmb3JtIGEgY29uc2lzdGVudCByZWFkLW1vZGlmeS13cml0ZS4KICAgKiBUaGUgdmFsdWUgbWF5IGJlIHtAY29kZSBudWxsfS4KICAgKi8KICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgcHJpdmF0ZSBqYXZhLmxhbmcuU3RyaW5nIGV0YWc7CgogIC8qKgogICAqIFRoZSBuYW1lcyBvZiB0aGUgcGVybWlzc2lvbnMgdGhpcyByb2xlIGdyYW50cyB3aGVuIGJvdW5kIGluIGFuIElBTSBwb2xpY3kuCiAgICogVGhlIHZhbHVlIG1heSBiZSB7QGNvZGUgbnVsbH0uCiAgICovCiAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLlN0cmluZz4gaW5jbHVkZWRQZXJtaXNzaW9uczsKCiAgLyoqCiAgICogVGhlIG5hbWUgb2YgdGhlIHJvbGUuCiAgICoKICAgKiBXaGVuIFJvbGUgaXMgdXNlZCBpbiBDcmVhdGVSb2xlLCB0aGUgcm9sZSBuYW1lIG11c3Qgbm90IGJlIHNldC4KICAgKgogICAqIFdoZW4gUm9sZSBpcyB1c2VkIGluIG91dHB1dCBhbmQgb3RoZXIgaW5wdXQgc3VjaCBhcyBVcGRhdGVSb2xlLCB0aGUgcm9sZSBuYW1lIGlzIHRoZSBjb21wbGV0ZQogICAqIHBhdGgsIGUuZy4sIHJvbGVzL2xvZ2dpbmcudmlld2VyIGZvciBwcmVkZWZpbmVkIHJvbGVzIGFuZAogICAqIG9yZ2FuaXphdGlvbnMve09SR0FOSVpBVElPTl9JRH0vcm9sZXMvbG9nZ2luZy52aWV3ZXIgZm9yIGN1c3RvbSByb2xlcy4KICAgKiBUaGUgdmFsdWUgbWF5IGJlIHtAY29kZSBudWxsfS4KICAgKi8KICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgcHJpdmF0ZSBqYXZhLmxhbmcuU3RyaW5nIG5hbWU7CgogIC8qKgogICAqIFRoZSBjdXJyZW50IGxhdW5jaCBzdGFnZSBvZiB0aGUgcm9sZS4gSWYgdGhlIGBBTFBIQWAgbGF1bmNoIHN0YWdlIGhhcyBiZWVuIHNlbGVjdGVkIGZvciBhIHJvbGUsCiAgICogdGhlIGBzdGFnZWAgZmllbGQgd2lsbCBub3QgYmUgaW5jbHVkZWQgaW4gdGhlIHJldHVybmVkIGRlZmluaXRpb24gZm9yIHRoZSByb2xlLgogICAqIFRoZSB2YWx1ZSBtYXkgYmUge0Bjb2RlIG51bGx9LgogICAqLwogIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICBwcml2YXRlIGphdmEubGFuZy5TdHJpbmcgc3RhZ2U7CgogIC8qKgogICAqIE9wdGlvbmFsLiBBIGh1bWFuLXJlYWRhYmxlIHRpdGxlIGZvciB0aGUgcm9sZS4gIFR5cGljYWxseSB0aGlzIGlzIGxpbWl0ZWQgdG8gMTAwIFVURi04IGJ5dGVzLgogICAqIFRoZSB2YWx1ZSBtYXkgYmUge0Bjb2RlIG51bGx9LgogICAqLwogIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICBwcml2YXRlIGphdmEubGFuZy5TdHJpbmcgdGl0bGU7CgogIC8qKgogICAqIFRoZSBjdXJyZW50IGRlbGV0ZWQgc3RhdGUgb2YgdGhlIHJvbGUuIFRoaXMgZmllbGQgaXMgcmVhZCBvbmx5LiBJdCB3aWxsIGJlIGlnbm9yZWQgaW4gY2FsbHMgdG8KICAgKiBDcmVhdGVSb2xlIGFuZCBVcGRhdGVSb2xlLgogICAqIEByZXR1cm4gdmFsdWUgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIGphdmEubGFuZy5Cb29sZWFuIGdldERlbGV0ZWQoKSB7CiAgICByZXR1cm4gZGVsZXRlZDsKICB9CgogIC8qKgogICAqIFRoZSBjdXJyZW50IGRlbGV0ZWQgc3RhdGUgb2YgdGhlIHJvbGUuIFRoaXMgZmllbGQgaXMgcmVhZCBvbmx5LiBJdCB3aWxsIGJlIGlnbm9yZWQgaW4gY2FsbHMgdG8KICAgKiBDcmVhdGVSb2xlIGFuZCBVcGRhdGVSb2xlLgogICAqIEBwYXJhbSBkZWxldGVkIGRlbGV0ZWQgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIFJvbGUgc2V0RGVsZXRlZChqYXZhLmxhbmcuQm9vbGVhbiBkZWxldGVkKSB7CiAgICB0aGlzLmRlbGV0ZWQgPSBkZWxldGVkOwogICAgcmV0dXJuIHRoaXM7CiAgfQoKICAvKioKICAgKiBPcHRpb25hbC4gQSBodW1hbi1yZWFkYWJsZSBkZXNjcmlwdGlvbiBmb3IgdGhlIHJvbGUuCiAgICogQHJldHVybiB2YWx1ZSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXREZXNjcmlwdGlvbigpIHsKICAgIHJldHVybiBkZXNjcmlwdGlvbjsKICB9CgogIC8qKgogICAqIE9wdGlvbmFsLiBBIGh1bWFuLXJlYWRhYmxlIGRlc2NyaXB0aW9uIGZvciB0aGUgcm9sZS4KICAgKiBAcGFyYW0gZGVzY3JpcHRpb24gZGVzY3JpcHRpb24gb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIFJvbGUgc2V0RGVzY3JpcHRpb24oamF2YS5sYW5nLlN0cmluZyBkZXNjcmlwdGlvbikgewogICAgdGhpcy5kZXNjcmlwdGlvbiA9IGRlc2NyaXB0aW9uOwogICAgcmV0dXJuIHRoaXM7CiAgfQoKICAvKioKICAgKiBVc2VkIHRvIHBlcmZvcm0gYSBjb25zaXN0ZW50IHJlYWQtbW9kaWZ5LXdyaXRlLgogICAqIEBzZWUgI2RlY29kZUV0YWcoKQogICAqIEByZXR1cm4gdmFsdWUgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0RXRhZygpIHsKICAgIHJldHVybiBldGFnOwogIH0KCiAgLyoqCiAgICogVXNlZCB0byBwZXJmb3JtIGEgY29uc2lzdGVudCByZWFkLW1vZGlmeS13cml0ZS4KICAgKiBAc2VlICNnZXRFdGFnKCkKICAgKiBAcmV0dXJuIEJhc2U2NCBkZWNvZGVkIHZhbHVlIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqCiAgICogQHNpbmNlIDEuMTQKICAgKi8KICBwdWJsaWMgYnl0ZVtdIGRlY29kZUV0YWcoKSB7CiAgICByZXR1cm4gY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuQmFzZTY0LmRlY29kZUJhc2U2NChldGFnKTsKICB9CgogIC8qKgogICAqIFVzZWQgdG8gcGVyZm9ybSBhIGNvbnNpc3RlbnQgcmVhZC1tb2RpZnktd3JpdGUuCiAgICogQHNlZSAjZW5jb2RlRXRhZygpCiAgICogQHBhcmFtIGV0YWcgZXRhZyBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgUm9sZSBzZXRFdGFnKGphdmEubGFuZy5TdHJpbmcgZXRhZykgewogICAgdGhpcy5ldGFnID0gZXRhZzsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgLyoqCiAgICogVXNlZCB0byBwZXJmb3JtIGEgY29uc2lzdGVudCByZWFkLW1vZGlmeS13cml0ZS4KICAgKiBAc2VlICNzZXRFdGFnKCkKICAgKgogICAqIDxwPgogICAqIFRoZSB2YWx1ZSBpcyBlbmNvZGVkIEJhc2U2NCBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUuCiAgICogPC9wPgogICAqCiAgICogQHNpbmNlIDEuMTQKICAgKi8KICBwdWJsaWMgUm9sZSBlbmNvZGVFdGFnKGJ5dGVbXSBldGFnKSB7CiAgICB0aGlzLmV0YWcgPSBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5CYXNlNjQuZW5jb2RlQmFzZTY0VVJMU2FmZVN0cmluZyhldGFnKTsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgLyoqCiAgICogVGhlIG5hbWVzIG9mIHRoZSBwZXJtaXNzaW9ucyB0aGlzIHJvbGUgZ3JhbnRzIHdoZW4gYm91bmQgaW4gYW4gSUFNIHBvbGljeS4KICAgKiBAcmV0dXJuIHZhbHVlIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuU3RyaW5nPiBnZXRJbmNsdWRlZFBlcm1pc3Npb25zKCkgewogICAgcmV0dXJuIGluY2x1ZGVkUGVybWlzc2lvbnM7CiAgfQoKICAvKioKICAgKiBUaGUgbmFtZXMgb2YgdGhlIHBlcm1pc3Npb25zIHRoaXMgcm9sZSBncmFudHMgd2hlbiBib3VuZCBpbiBhbiBJQU0gcG9saWN5LgogICAqIEBwYXJhbSBpbmNsdWRlZFBlcm1pc3Npb25zIGluY2x1ZGVkUGVybWlzc2lvbnMgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIFJvbGUgc2V0SW5jbHVkZWRQZXJtaXNzaW9ucyhqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuU3RyaW5nPiBpbmNsdWRlZFBlcm1pc3Npb25zKSB7CiAgICB0aGlzLmluY2x1ZGVkUGVybWlzc2lvbnMgPSBpbmNsdWRlZFBlcm1pc3Npb25zOwogICAgcmV0dXJuIHRoaXM7CiAgfQoKICAvKioKICAgKiBUaGUgbmFtZSBvZiB0aGUgcm9sZS4KICAgKgogICAqIFdoZW4gUm9sZSBpcyB1c2VkIGluIENyZWF0ZVJvbGUsIHRoZSByb2xlIG5hbWUgbXVzdCBub3QgYmUgc2V0LgogICAqCiAgICogV2hlbiBSb2xlIGlzIHVzZWQgaW4gb3V0cHV0IGFuZCBvdGhlciBpbnB1dCBzdWNoIGFzIFVwZGF0ZVJvbGUsIHRoZSByb2xlIG5hbWUgaXMgdGhlIGNvbXBsZXRlCiAgICogcGF0aCwgZS5nLiwgcm9sZXMvbG9nZ2luZy52aWV3ZXIgZm9yIHByZWRlZmluZWQgcm9sZXMgYW5kCiAgICogb3JnYW5pemF0aW9ucy97T1JHQU5JWkFUSU9OX0lEfS9yb2xlcy9sb2dnaW5nLnZpZXdlciBmb3IgY3VzdG9tIHJvbGVzLgogICAqIEByZXR1cm4gdmFsdWUgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TmFtZSgpIHsKICAgIHJldHVybiBuYW1lOwogIH0KCiAgLyoqCiAgICogVGhlIG5hbWUgb2YgdGhlIHJvbGUuCiAgICoKICAgKiBXaGVuIFJvbGUgaXMgdXNlZCBpbiBDcmVhdGVSb2xlLCB0aGUgcm9sZSBuYW1lIG11c3Qgbm90IGJlIHNldC4KICAgKgogICAqIFdoZW4gUm9sZSBpcyB1c2VkIGluIG91dHB1dCBhbmQgb3RoZXIgaW5wdXQgc3VjaCBhcyBVcGRhdGVSb2xlLCB0aGUgcm9sZSBuYW1lIGlzIHRoZSBjb21wbGV0ZQogICAqIHBhdGgsIGUuZy4sIHJvbGVzL2xvZ2dpbmcudmlld2VyIGZvciBwcmVkZWZpbmVkIHJvbGVzIGFuZAogICAqIG9yZ2FuaXphdGlvbnMve09SR0FOSVpBVElPTl9JRH0vcm9sZXMvbG9nZ2luZy52aWV3ZXIgZm9yIGN1c3RvbSByb2xlcy4KICAgKiBAcGFyYW0gbmFtZSBuYW1lIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBSb2xlIHNldE5hbWUoamF2YS5sYW5nLlN0cmluZyBuYW1lKSB7CiAgICB0aGlzLm5hbWUgPSBuYW1lOwogICAgcmV0dXJuIHRoaXM7CiAgfQoKICAvKioKICAgKiBUaGUgY3VycmVudCBsYXVuY2ggc3RhZ2Ugb2YgdGhlIHJvbGUuIElmIHRoZSBgQUxQSEFgIGxhdW5jaCBzdGFnZSBoYXMgYmVlbiBzZWxlY3RlZCBmb3IgYSByb2xlLAogICAqIHRoZSBgc3RhZ2VgIGZpZWxkIHdpbGwgbm90IGJlIGluY2x1ZGVkIGluIHRoZSByZXR1cm5lZCBkZWZpbml0aW9uIGZvciB0aGUgcm9sZS4KICAgKiBAcmV0dXJuIHZhbHVlIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFN0YWdlKCkgewogICAgcmV0dXJuIHN0YWdlOwogIH0KCiAgLyoqCiAgICogVGhlIGN1cnJlbnQgbGF1bmNoIHN0YWdlIG9mIHRoZSByb2xlLiBJZiB0aGUgYEFMUEhBYCBsYXVuY2ggc3RhZ2UgaGFzIGJlZW4gc2VsZWN0ZWQgZm9yIGEgcm9sZSwKICAgKiB0aGUgYHN0YWdlYCBmaWVsZCB3aWxsIG5vdCBiZSBpbmNsdWRlZCBpbiB0aGUgcmV0dXJuZWQgZGVmaW5pdGlvbiBmb3IgdGhlIHJvbGUuCiAgICogQHBhcmFtIHN0YWdlIHN0YWdlIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBSb2xlIHNldFN0YWdlKGphdmEubGFuZy5TdHJpbmcgc3RhZ2UpIHsKICAgIHRoaXMuc3RhZ2UgPSBzdGFnZTsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgLyoqCiAgICogT3B0aW9uYWwuIEEgaHVtYW4tcmVhZGFibGUgdGl0bGUgZm9yIHRoZSByb2xlLiAgVHlwaWNhbGx5IHRoaXMgaXMgbGltaXRlZCB0byAxMDAgVVRGLTggYnl0ZXMuCiAgICogQHJldHVybiB2YWx1ZSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRUaXRsZSgpIHsKICAgIHJldHVybiB0aXRsZTsKICB9CgogIC8qKgogICAqIE9wdGlvbmFsLiBBIGh1bWFuLXJlYWRhYmxlIHRpdGxlIGZvciB0aGUgcm9sZS4gIFR5cGljYWxseSB0aGlzIGlzIGxpbWl0ZWQgdG8gMTAwIFVURi04IGJ5dGVzLgogICAqIEBwYXJhbSB0aXRsZSB0aXRsZSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgUm9sZSBzZXRUaXRsZShqYXZhLmxhbmcuU3RyaW5nIHRpdGxlKSB7CiAgICB0aGlzLnRpdGxlID0gdGl0bGU7CiAgICByZXR1cm4gdGhpczsKICB9CgogIEBPdmVycmlkZQogIHB1YmxpYyBSb2xlIHNldChTdHJpbmcgZmllbGROYW1lLCBPYmplY3QgdmFsdWUpIHsKICAgIHJldHVybiAoUm9sZSkgc3VwZXIuc2V0KGZpZWxkTmFtZSwgdmFsdWUpOwogIH0KCiAgQE92ZXJyaWRlCiAgcHVibGljIFJvbGUgY2xvbmUoKSB7CiAgICByZXR1cm4gKFJvbGUpIHN1cGVyLmNsb25lKCk7CiAgfQoKfQpQSwMEFAAAAAAAAAAhAC3v7Y5VKwAAVSsAADgAAABjb20vZ29vZ2xlL2FwaS9zZXJ2aWNlcy9pYW0vdjEvbW9kZWwvU2VydmljZUFjY291bnQuamF2YS8qCiAqIENvcHlyaWdodCAyMDEwIEdvb2dsZSBJbmMuCiAqCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdAogKiBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZQogKiBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3MKICogb3IgaW1wbGllZC4gU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucyB1bmRlcgogKiB0aGUgTGljZW5zZS4KICovCi8qCiAqIFRoaXMgY29kZSB3YXMgZ2VuZXJhdGVkIGJ5IGh0dHBzOi8vZ2l0aHViLmNvbS9nb29nbGUvYXBpcy1jbGllbnQtZ2VuZXJhdG9yLwogKiAoYnVpbGQ6IDIwMTgtMTAtMDggMTc6NDU6MzkgVVRDKQogKiBvbiAyMDIwLTAzLTE5IGF0IDAxOjUyOjQxIFVUQyAKICogTW9kaWZ5IGF0IHlvdXIgb3duIHJpc2suCiAqLwoKcGFja2FnZSBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5pYW0udjEubW9kZWw7CgovKioKICogQSBzZXJ2aWNlIGFjY291bnQgaW4gdGhlIElkZW50aXR5IGFuZCBBY2Nlc3MgTWFuYWdlbWVudCBBUEkuCiAqCiAqIFRvIGNyZWF0ZSBhIHNlcnZpY2UgYWNjb3VudCwgc3BlY2lmeSB0aGUgYHByb2plY3RfaWRgIGFuZCB0aGUgYGFjY291bnRfaWRgIGZvciB0aGUgYWNjb3VudC4gIFRoZQogKiBgYWNjb3VudF9pZGAgaXMgdW5pcXVlIHdpdGhpbiB0aGUgcHJvamVjdCwgYW5kIGlzIHVzZWQgdG8gZ2VuZXJhdGUgdGhlIHNlcnZpY2UgYWNjb3VudCBlbWFpbAogKiBhZGRyZXNzIGFuZCBhIHN0YWJsZSBgdW5pcXVlX2lkYC4KICoKICogSWYgdGhlIGFjY291bnQgYWxyZWFkeSBleGlzdHMsIHRoZSBhY2NvdW50J3MgcmVzb3VyY2UgbmFtZSBpcyByZXR1cm5lZCBpbiB0aGUgZm9ybWF0IG9mCiAqIHByb2plY3RzL3tQUk9KRUNUX0lEfS9zZXJ2aWNlQWNjb3VudHMve0FDQ09VTlR9LiBUaGUgY2FsbGVyIGNhbiB1c2UgdGhlIG5hbWUgaW4gb3RoZXIgbWV0aG9kcyB0bwogKiBhY2Nlc3MgdGhlIGFjY291bnQuCiAqCiAqIEFsbCBvdGhlciBtZXRob2RzIGNhbiBpZGVudGlmeSB0aGUgc2VydmljZSBhY2NvdW50IHVzaW5nIHRoZSBmb3JtYXQKICogYHByb2plY3RzL3tQUk9KRUNUX0lEfS9zZXJ2aWNlQWNjb3VudHMve0FDQ09VTlR9YC4gVXNpbmcgYC1gIGFzIGEgd2lsZGNhcmQgZm9yIHRoZSBgUFJPSkVDVF9JRGAKICogd2lsbCBpbmZlciB0aGUgcHJvamVjdCBmcm9tIHRoZSBhY2NvdW50LiBUaGUgYEFDQ09VTlRgIHZhbHVlIGNhbiBiZSB0aGUgYGVtYWlsYCBhZGRyZXNzIG9yIHRoZQogKiBgdW5pcXVlX2lkYCBvZiB0aGUgc2VydmljZSBhY2NvdW50LgogKgogKiA8cD4gVGhpcyBpcyB0aGUgSmF2YSBkYXRhIG1vZGVsIGNsYXNzIHRoYXQgc3BlY2lmaWVzIGhvdyB0byBwYXJzZS9zZXJpYWxpemUgaW50byB0aGUgSlNPTiB0aGF0IGlzCiAqIHRyYW5zbWl0dGVkIG92ZXIgSFRUUCB3aGVuIHdvcmtpbmcgd2l0aCB0aGUgSWRlbnRpdHkgYW5kIEFjY2VzcyBNYW5hZ2VtZW50IChJQU0pIEFQSS4gRm9yIGEKICogZGV0YWlsZWQgZXhwbGFuYXRpb24gc2VlOgogKiA8YSBocmVmPSJodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9hcGktY2xpZW50LWxpYnJhcnkvamF2YS9nb29nbGUtaHR0cC1qYXZhLWNsaWVudC9qc29uIj5odHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9hcGktY2xpZW50LWxpYnJhcnkvamF2YS9nb29nbGUtaHR0cC1qYXZhLWNsaWVudC9qc29uPC9hPgogKiA8L3A+CiAqCiAqIEBhdXRob3IgR29vZ2xlLCBJbmMuCiAqLwpAU3VwcHJlc3NXYXJuaW5ncygiamF2YWRvYyIpCnB1YmxpYyBmaW5hbCBjbGFzcyBTZXJ2aWNlQWNjb3VudCBleHRlbmRzIGNvbS5nb29nbGUuYXBpLmNsaWVudC5qc29uLkdlbmVyaWNKc29uIHsKCiAgLyoqCiAgICogT3B0aW9uYWwuIEEgdXNlci1zcGVjaWZpZWQgb3BhcXVlIGRlc2NyaXB0aW9uIG9mIHRoZSBzZXJ2aWNlIGFjY291bnQuIE11c3QgYmUgbGVzcyB0aGFuIG9yCiAgICogZXF1YWwgdG8gMjU2IFVURi04IGJ5dGVzLgogICAqIFRoZSB2YWx1ZSBtYXkgYmUge0Bjb2RlIG51bGx9LgogICAqLwogIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICBwcml2YXRlIGphdmEubGFuZy5TdHJpbmcgZGVzY3JpcHRpb247CgogIC8qKgogICAqIEBPdXRwdXRPbmx5IEEgYm9vbCBpbmRpY2F0ZSBpZiB0aGUgc2VydmljZSBhY2NvdW50IGlzIGRpc2FibGVkLiBUaGUgZmllbGQgaXMgY3VycmVudGx5IGluIGFscGhhCiAgICogcGhhc2UuCiAgICogVGhlIHZhbHVlIG1heSBiZSB7QGNvZGUgbnVsbH0uCiAgICovCiAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogIHByaXZhdGUgamF2YS5sYW5nLkJvb2xlYW4gZGlzYWJsZWQ7CgogIC8qKgogICAqIE9wdGlvbmFsLiBBIHVzZXItc3BlY2lmaWVkIG5hbWUgZm9yIHRoZSBzZXJ2aWNlIGFjY291bnQuIE11c3QgYmUgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIDEwMAogICAqIFVURi04IGJ5dGVzLgogICAqIFRoZSB2YWx1ZSBtYXkgYmUge0Bjb2RlIG51bGx9LgogICAqLwogIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICBwcml2YXRlIGphdmEubGFuZy5TdHJpbmcgZGlzcGxheU5hbWU7CgogIC8qKgogICAqIEBPdXRwdXRPbmx5IFRoZSBlbWFpbCBhZGRyZXNzIG9mIHRoZSBzZXJ2aWNlIGFjY291bnQuCiAgICogVGhlIHZhbHVlIG1heSBiZSB7QGNvZGUgbnVsbH0uCiAgICovCiAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogIHByaXZhdGUgamF2YS5sYW5nLlN0cmluZyBlbWFpbDsKCiAgLyoqCiAgICogT3B0aW9uYWwuIE5vdGU6IGBldGFnYCBpcyBhbiBpbm9wZXJhYmxlIGxlZ2FjeSBmaWVsZCB0aGF0IGlzIG9ubHkgcmV0dXJuZWQgZm9yIGJhY2t3YXJkcwogICAqIGNvbXBhdGliaWxpdHkuCiAgICogVGhlIHZhbHVlIG1heSBiZSB7QGNvZGUgbnVsbH0uCiAgICovCiAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogIHByaXZhdGUgamF2YS5sYW5nLlN0cmluZyBldGFnOwoKICAvKioKICAgKiBUaGUgcmVzb3VyY2UgbmFtZSBvZiB0aGUgc2VydmljZSBhY2NvdW50IGluIHRoZSBmb2xsb3dpbmcgZm9ybWF0OgogICAqIGBwcm9qZWN0cy97UFJPSkVDVF9JRH0vc2VydmljZUFjY291bnRzL3tBQ0NPVU5UfWAuCiAgICoKICAgKiBSZXF1ZXN0cyB1c2luZyBgLWAgYXMgYSB3aWxkY2FyZCBmb3IgdGhlIGBQUk9KRUNUX0lEYCB3aWxsIGluZmVyIHRoZSBwcm9qZWN0IGZyb20gdGhlIGBhY2NvdW50YAogICAqIGFuZCB0aGUgYEFDQ09VTlRgIHZhbHVlIGNhbiBiZSB0aGUgYGVtYWlsYCBhZGRyZXNzIG9yIHRoZSBgdW5pcXVlX2lkYCBvZiB0aGUgc2VydmljZSBhY2NvdW50LgogICAqCiAgICogSW4gcmVzcG9uc2VzIHRoZSByZXNvdXJjZSBuYW1lIHdpbGwgYWx3YXlzIGJlIGluIHRoZSBmb3JtYXQKICAgKiBgcHJvamVjdHMve1BST0pFQ1RfSUR9L3NlcnZpY2VBY2NvdW50cy97QUNDT1VOVH1gLgogICAqIFRoZSB2YWx1ZSBtYXkgYmUge0Bjb2RlIG51bGx9LgogICAqLwogIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICBwcml2YXRlIGphdmEubGFuZy5TdHJpbmcgbmFtZTsKCiAgLyoqCiAgICogQE91dHB1dE9ubHkgVGhlIE9BdXRoMiBjbGllbnQgaWQgZm9yIHRoZSBzZXJ2aWNlIGFjY291bnQuIFRoaXMgaXMgdXNlZCBpbiBjb25qdW5jdGlvbiB3aXRoIHRoZQogICAqIE9BdXRoMiBjbGllbnRjb25maWcgQVBJIHRvIG1ha2UgdGhyZWUgbGVnZ2VkIE9BdXRoMiAoM0xPKSBmbG93cyB0byBhY2Nlc3MgdGhlIGRhdGEgb2YgR29vZ2xlCiAgICogdXNlcnMuCiAgICogVGhlIHZhbHVlIG1heSBiZSB7QGNvZGUgbnVsbH0uCiAgICovCiAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogIHByaXZhdGUgamF2YS5sYW5nLlN0cmluZyBvYXV0aDJDbGllbnRJZDsKCiAgLyoqCiAgICogQE91dHB1dE9ubHkgVGhlIGlkIG9mIHRoZSBwcm9qZWN0IHRoYXQgb3ducyB0aGUgc2VydmljZSBhY2NvdW50LgogICAqIFRoZSB2YWx1ZSBtYXkgYmUge0Bjb2RlIG51bGx9LgogICAqLwogIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICBwcml2YXRlIGphdmEubGFuZy5TdHJpbmcgcHJvamVjdElkOwoKICAvKioKICAgKiBAT3V0cHV0T25seSBUaGUgdW5pcXVlIGFuZCBzdGFibGUgaWQgb2YgdGhlIHNlcnZpY2UgYWNjb3VudC4KICAgKiBUaGUgdmFsdWUgbWF5IGJlIHtAY29kZSBudWxsfS4KICAgKi8KICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgcHJpdmF0ZSBqYXZhLmxhbmcuU3RyaW5nIHVuaXF1ZUlkOwoKICAvKioKICAgKiBPcHRpb25hbC4gQSB1c2VyLXNwZWNpZmllZCBvcGFxdWUgZGVzY3JpcHRpb24gb2YgdGhlIHNlcnZpY2UgYWNjb3VudC4gTXVzdCBiZSBsZXNzIHRoYW4gb3IKICAgKiBlcXVhbCB0byAyNTYgVVRGLTggYnl0ZXMuCiAgICogQHJldHVybiB2YWx1ZSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXREZXNjcmlwdGlvbigpIHsKICAgIHJldHVybiBkZXNjcmlwdGlvbjsKICB9CgogIC8qKgogICAqIE9wdGlvbmFsLiBBIHVzZXItc3BlY2lmaWVkIG9wYXF1ZSBkZXNjcmlwdGlvbiBvZiB0aGUgc2VydmljZSBhY2NvdW50LiBNdXN0IGJlIGxlc3MgdGhhbiBvcgogICAqIGVxdWFsIHRvIDI1NiBVVEYtOCBieXRlcy4KICAgKiBAcGFyYW0gZGVzY3JpcHRpb24gZGVzY3JpcHRpb24gb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIFNlcnZpY2VBY2NvdW50IHNldERlc2NyaXB0aW9uKGphdmEubGFuZy5TdHJpbmcgZGVzY3JpcHRpb24pIHsKICAgIHRoaXMuZGVzY3JpcHRpb24gPSBkZXNjcmlwdGlvbjsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgLyoqCiAgICogQE91dHB1dE9ubHkgQSBib29sIGluZGljYXRlIGlmIHRoZSBzZXJ2aWNlIGFjY291bnQgaXMgZGlzYWJsZWQuIFRoZSBmaWVsZCBpcyBjdXJyZW50bHkgaW4gYWxwaGEKICAgKiBwaGFzZS4KICAgKiBAcmV0dXJuIHZhbHVlIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBqYXZhLmxhbmcuQm9vbGVhbiBnZXREaXNhYmxlZCgpIHsKICAgIHJldHVybiBkaXNhYmxlZDsKICB9CgogIC8qKgogICAqIEBPdXRwdXRPbmx5IEEgYm9vbCBpbmRpY2F0ZSBpZiB0aGUgc2VydmljZSBhY2NvdW50IGlzIGRpc2FibGVkLiBUaGUgZmllbGQgaXMgY3VycmVudGx5IGluIGFscGhhCiAgICogcGhhc2UuCiAgICogQHBhcmFtIGRpc2FibGVkIGRpc2FibGVkIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBTZXJ2aWNlQWNjb3VudCBzZXREaXNhYmxlZChqYXZhLmxhbmcuQm9vbGVhbiBkaXNhYmxlZCkgewogICAgdGhpcy5kaXNhYmxlZCA9IGRpc2FibGVkOwogICAgcmV0dXJuIHRoaXM7CiAgfQoKICAvKioKICAgKiBPcHRpb25hbC4gQSB1c2VyLXNwZWNpZmllZCBuYW1lIGZvciB0aGUgc2VydmljZSBhY2NvdW50LiBNdXN0IGJlIGxlc3MgdGhhbiBvciBlcXVhbCB0byAxMDAKICAgKiBVVEYtOCBieXRlcy4KICAgKiBAcmV0dXJuIHZhbHVlIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldERpc3BsYXlOYW1lKCkgewogICAgcmV0dXJuIGRpc3BsYXlOYW1lOwogIH0KCiAgLyoqCiAgICogT3B0aW9uYWwuIEEgdXNlci1zcGVjaWZpZWQgbmFtZSBmb3IgdGhlIHNlcnZpY2UgYWNjb3VudC4gTXVzdCBiZSBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gMTAwCiAgICogVVRGLTggYnl0ZXMuCiAgICogQHBhcmFtIGRpc3BsYXlOYW1lIGRpc3BsYXlOYW1lIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBTZXJ2aWNlQWNjb3VudCBzZXREaXNwbGF5TmFtZShqYXZhLmxhbmcuU3RyaW5nIGRpc3BsYXlOYW1lKSB7CiAgICB0aGlzLmRpc3BsYXlOYW1lID0gZGlzcGxheU5hbWU7CiAgICByZXR1cm4gdGhpczsKICB9CgogIC8qKgogICAqIEBPdXRwdXRPbmx5IFRoZSBlbWFpbCBhZGRyZXNzIG9mIHRoZSBzZXJ2aWNlIGFjY291bnQuCiAgICogQHJldHVybiB2YWx1ZSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRFbWFpbCgpIHsKICAgIHJldHVybiBlbWFpbDsKICB9CgogIC8qKgogICAqIEBPdXRwdXRPbmx5IFRoZSBlbWFpbCBhZGRyZXNzIG9mIHRoZSBzZXJ2aWNlIGFjY291bnQuCiAgICogQHBhcmFtIGVtYWlsIGVtYWlsIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBTZXJ2aWNlQWNjb3VudCBzZXRFbWFpbChqYXZhLmxhbmcuU3RyaW5nIGVtYWlsKSB7CiAgICB0aGlzLmVtYWlsID0gZW1haWw7CiAgICByZXR1cm4gdGhpczsKICB9CgogIC8qKgogICAqIE9wdGlvbmFsLiBOb3RlOiBgZXRhZ2AgaXMgYW4gaW5vcGVyYWJsZSBsZWdhY3kgZmllbGQgdGhhdCBpcyBvbmx5IHJldHVybmVkIGZvciBiYWNrd2FyZHMKICAgKiBjb21wYXRpYmlsaXR5LgogICAqIEBzZWUgI2RlY29kZUV0YWcoKQogICAqIEByZXR1cm4gdmFsdWUgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0RXRhZygpIHsKICAgIHJldHVybiBldGFnOwogIH0KCiAgLyoqCiAgICogT3B0aW9uYWwuIE5vdGU6IGBldGFnYCBpcyBhbiBpbm9wZXJhYmxlIGxlZ2FjeSBmaWVsZCB0aGF0IGlzIG9ubHkgcmV0dXJuZWQgZm9yIGJhY2t3YXJkcwogICAqIGNvbXBhdGliaWxpdHkuCiAgICogQHNlZSAjZ2V0RXRhZygpCiAgICogQHJldHVybiBCYXNlNjQgZGVjb2RlZCB2YWx1ZSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKgogICAqIEBzaW5jZSAxLjE0CiAgICovCiAgcHVibGljIGJ5dGVbXSBkZWNvZGVFdGFnKCkgewogICAgcmV0dXJuIGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLkJhc2U2NC5kZWNvZGVCYXNlNjQoZXRhZyk7CiAgfQoKICAvKioKICAgKiBPcHRpb25hbC4gTm90ZTogYGV0YWdgIGlzIGFuIGlub3BlcmFibGUgbGVnYWN5IGZpZWxkIHRoYXQgaXMgb25seSByZXR1cm5lZCBmb3IgYmFja3dhcmRzCiAgICogY29tcGF0aWJpbGl0eS4KICAgKiBAc2VlICNlbmNvZGVFdGFnKCkKICAgKiBAcGFyYW0gZXRhZyBldGFnIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBTZXJ2aWNlQWNjb3VudCBzZXRFdGFnKGphdmEubGFuZy5TdHJpbmcgZXRhZykgewogICAgdGhpcy5ldGFnID0gZXRhZzsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgLyoqCiAgICogT3B0aW9uYWwuIE5vdGU6IGBldGFnYCBpcyBhbiBpbm9wZXJhYmxlIGxlZ2FjeSBmaWVsZCB0aGF0IGlzIG9ubHkgcmV0dXJuZWQgZm9yIGJhY2t3YXJkcwogICAqIGNvbXBhdGliaWxpdHkuCiAgICogQHNlZSAjc2V0RXRhZygpCiAgICoKICAgKiA8cD4KICAgKiBUaGUgdmFsdWUgaXMgZW5jb2RlZCBCYXNlNjQgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lLgogICAqIDwvcD4KICAgKgogICAqIEBzaW5jZSAxLjE0CiAgICovCiAgcHVibGljIFNlcnZpY2VBY2NvdW50IGVuY29kZUV0YWcoYnl0ZVtdIGV0YWcpIHsKICAgIHRoaXMuZXRhZyA9IGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLkJhc2U2NC5lbmNvZGVCYXNlNjRVUkxTYWZlU3RyaW5nKGV0YWcpOwogICAgcmV0dXJuIHRoaXM7CiAgfQoKICAvKioKICAgKiBUaGUgcmVzb3VyY2UgbmFtZSBvZiB0aGUgc2VydmljZSBhY2NvdW50IGluIHRoZSBmb2xsb3dpbmcgZm9ybWF0OgogICAqIGBwcm9qZWN0cy97UFJPSkVDVF9JRH0vc2VydmljZUFjY291bnRzL3tBQ0NPVU5UfWAuCiAgICoKICAgKiBSZXF1ZXN0cyB1c2luZyBgLWAgYXMgYSB3aWxkY2FyZCBmb3IgdGhlIGBQUk9KRUNUX0lEYCB3aWxsIGluZmVyIHRoZSBwcm9qZWN0IGZyb20gdGhlIGBhY2NvdW50YAogICAqIGFuZCB0aGUgYEFDQ09VTlRgIHZhbHVlIGNhbiBiZSB0aGUgYGVtYWlsYCBhZGRyZXNzIG9yIHRoZSBgdW5pcXVlX2lkYCBvZiB0aGUgc2VydmljZSBhY2NvdW50LgogICAqCiAgICogSW4gcmVzcG9uc2VzIHRoZSByZXNvdXJjZSBuYW1lIHdpbGwgYWx3YXlzIGJlIGluIHRoZSBmb3JtYXQKICAgKiBgcHJvamVjdHMve1BST0pFQ1RfSUR9L3NlcnZpY2VBY2NvdW50cy97QUNDT1VOVH1gLgogICAqIEByZXR1cm4gdmFsdWUgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TmFtZSgpIHsKICAgIHJldHVybiBuYW1lOwogIH0KCiAgLyoqCiAgICogVGhlIHJlc291cmNlIG5hbWUgb2YgdGhlIHNlcnZpY2UgYWNjb3VudCBpbiB0aGUgZm9sbG93aW5nIGZvcm1hdDoKICAgKiBgcHJvamVjdHMve1BST0pFQ1RfSUR9L3NlcnZpY2VBY2NvdW50cy97QUNDT1VOVH1gLgogICAqCiAgICogUmVxdWVzdHMgdXNpbmcgYC1gIGFzIGEgd2lsZGNhcmQgZm9yIHRoZSBgUFJPSkVDVF9JRGAgd2lsbCBpbmZlciB0aGUgcHJvamVjdCBmcm9tIHRoZSBgYWNjb3VudGAKICAgKiBhbmQgdGhlIGBBQ0NPVU5UYCB2YWx1ZSBjYW4gYmUgdGhlIGBlbWFpbGAgYWRkcmVzcyBvciB0aGUgYHVuaXF1ZV9pZGAgb2YgdGhlIHNlcnZpY2UgYWNjb3VudC4KICAgKgogICAqIEluIHJlc3BvbnNlcyB0aGUgcmVzb3VyY2UgbmFtZSB3aWxsIGFsd2F5cyBiZSBpbiB0aGUgZm9ybWF0CiAgICogYHByb2plY3RzL3tQUk9KRUNUX0lEfS9zZXJ2aWNlQWNjb3VudHMve0FDQ09VTlR9YC4KICAgKiBAcGFyYW0gbmFtZSBuYW1lIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBTZXJ2aWNlQWNjb3VudCBzZXROYW1lKGphdmEubGFuZy5TdHJpbmcgbmFtZSkgewogICAgdGhpcy5uYW1lID0gbmFtZTsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgLyoqCiAgICogQE91dHB1dE9ubHkgVGhlIE9BdXRoMiBjbGllbnQgaWQgZm9yIHRoZSBzZXJ2aWNlIGFjY291bnQuIFRoaXMgaXMgdXNlZCBpbiBjb25qdW5jdGlvbiB3aXRoIHRoZQogICAqIE9BdXRoMiBjbGllbnRjb25maWcgQVBJIHRvIG1ha2UgdGhyZWUgbGVnZ2VkIE9BdXRoMiAoM0xPKSBmbG93cyB0byBhY2Nlc3MgdGhlIGRhdGEgb2YgR29vZ2xlCiAgICogdXNlcnMuCiAgICogQHJldHVybiB2YWx1ZSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRPYXV0aDJDbGllbnRJZCgpIHsKICAgIHJldHVybiBvYXV0aDJDbGllbnRJZDsKICB9CgogIC8qKgogICAqIEBPdXRwdXRPbmx5IFRoZSBPQXV0aDIgY2xpZW50IGlkIGZvciB0aGUgc2VydmljZSBhY2NvdW50LiBUaGlzIGlzIHVzZWQgaW4gY29uanVuY3Rpb24gd2l0aCB0aGUKICAgKiBPQXV0aDIgY2xpZW50Y29uZmlnIEFQSSB0byBtYWtlIHRocmVlIGxlZ2dlZCBPQXV0aDIgKDNMTykgZmxvd3MgdG8gYWNjZXNzIHRoZSBkYXRhIG9mIEdvb2dsZQogICAqIHVzZXJzLgogICAqIEBwYXJhbSBvYXV0aDJDbGllbnRJZCBvYXV0aDJDbGllbnRJZCBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgU2VydmljZUFjY291bnQgc2V0T2F1dGgyQ2xpZW50SWQoamF2YS5sYW5nLlN0cmluZyBvYXV0aDJDbGllbnRJZCkgewogICAgdGhpcy5vYXV0aDJDbGllbnRJZCA9IG9hdXRoMkNsaWVudElkOwogICAgcmV0dXJuIHRoaXM7CiAgfQoKICAvKioKICAgKiBAT3V0cHV0T25seSBUaGUgaWQgb2YgdGhlIHByb2plY3QgdGhhdCBvd25zIHRoZSBzZXJ2aWNlIGFjY291bnQuCiAgICogQHJldHVybiB2YWx1ZSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRQcm9qZWN0SWQoKSB7CiAgICByZXR1cm4gcHJvamVjdElkOwogIH0KCiAgLyoqCiAgICogQE91dHB1dE9ubHkgVGhlIGlkIG9mIHRoZSBwcm9qZWN0IHRoYXQgb3ducyB0aGUgc2VydmljZSBhY2NvdW50LgogICAqIEBwYXJhbSBwcm9qZWN0SWQgcHJvamVjdElkIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBTZXJ2aWNlQWNjb3VudCBzZXRQcm9qZWN0SWQoamF2YS5sYW5nLlN0cmluZyBwcm9qZWN0SWQpIHsKICAgIHRoaXMucHJvamVjdElkID0gcHJvamVjdElkOwogICAgcmV0dXJuIHRoaXM7CiAgfQoKICAvKioKICAgKiBAT3V0cHV0T25seSBUaGUgdW5pcXVlIGFuZCBzdGFibGUgaWQgb2YgdGhlIHNlcnZpY2UgYWNjb3VudC4KICAgKiBAcmV0dXJuIHZhbHVlIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFVuaXF1ZUlkKCkgewogICAgcmV0dXJuIHVuaXF1ZUlkOwogIH0KCiAgLyoqCiAgICogQE91dHB1dE9ubHkgVGhlIHVuaXF1ZSBhbmQgc3RhYmxlIGlkIG9mIHRoZSBzZXJ2aWNlIGFjY291bnQuCiAgICogQHBhcmFtIHVuaXF1ZUlkIHVuaXF1ZUlkIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBTZXJ2aWNlQWNjb3VudCBzZXRVbmlxdWVJZChqYXZhLmxhbmcuU3RyaW5nIHVuaXF1ZUlkKSB7CiAgICB0aGlzLnVuaXF1ZUlkID0gdW5pcXVlSWQ7CiAgICByZXR1cm4gdGhpczsKICB9CgogIEBPdmVycmlkZQogIHB1YmxpYyBTZXJ2aWNlQWNjb3VudCBzZXQoU3RyaW5nIGZpZWxkTmFtZSwgT2JqZWN0IHZhbHVlKSB7CiAgICByZXR1cm4gKFNlcnZpY2VBY2NvdW50KSBzdXBlci5zZXQoZmllbGROYW1lLCB2YWx1ZSk7CiAgfQoKICBAT3ZlcnJpZGUKICBwdWJsaWMgU2VydmljZUFjY291bnQgY2xvbmUoKSB7CiAgICByZXR1cm4gKFNlcnZpY2VBY2NvdW50KSBzdXBlci5jbG9uZSgpOwogIH0KCn0KUEsDBBQAAAAAAAAAIQAZ08WN7DAAAOwwAAA7AAAAY29tL2dvb2dsZS9hcGkvc2VydmljZXMvaWFtL3YxL21vZGVsL1NlcnZpY2VBY2NvdW50S2V5LmphdmEvKgogKiBDb3B5cmlnaHQgMjAxMCBHb29nbGUgSW5jLgogKgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQKICogaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UKICogaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzCiAqIG9yIGltcGxpZWQuIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMgdW5kZXIKICogdGhlIExpY2Vuc2UuCiAqLwovKgogKiBUaGlzIGNvZGUgd2FzIGdlbmVyYXRlZCBieSBodHRwczovL2dpdGh1Yi5jb20vZ29vZ2xlL2FwaXMtY2xpZW50LWdlbmVyYXRvci8KICogKGJ1aWxkOiAyMDE4LTEwLTA4IDE3OjQ1OjM5IFVUQykKICogb24gMjAyMC0wMy0xOSBhdCAwMTo1Mjo0MSBVVEMgCiAqIE1vZGlmeSBhdCB5b3VyIG93biByaXNrLgogKi8KCnBhY2thZ2UgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuaWFtLnYxLm1vZGVsOwoKLyoqCiAqIFJlcHJlc2VudHMgYSBzZXJ2aWNlIGFjY291bnQga2V5LgogKgogKiBBIHNlcnZpY2UgYWNjb3VudCBoYXMgdHdvIHNldHMgb2Yga2V5LXBhaXJzOiB1c2VyLW1hbmFnZWQsIGFuZCBzeXN0ZW0tbWFuYWdlZC4KICoKICogVXNlci1tYW5hZ2VkIGtleS1wYWlycyBjYW4gYmUgY3JlYXRlZCBhbmQgZGVsZXRlZCBieSB1c2Vycy4gIFVzZXJzIGFyZSByZXNwb25zaWJsZSBmb3Igcm90YXRpbmcKICogdGhlc2Uga2V5cyBwZXJpb2RpY2FsbHkgdG8gZW5zdXJlIHNlY3VyaXR5IG9mIHRoZWlyIHNlcnZpY2UgYWNjb3VudHMuICBVc2VycyByZXRhaW4gdGhlIHByaXZhdGUKICoga2V5IG9mIHRoZXNlIGtleS1wYWlycywgYW5kIEdvb2dsZSByZXRhaW5zIE9OTFkgdGhlIHB1YmxpYyBrZXkuCiAqCiAqIFN5c3RlbS1tYW5hZ2VkIGtleXMgYXJlIGF1dG9tYXRpY2FsbHkgcm90YXRlZCBieSBHb29nbGUsIGFuZCBhcmUgdXNlZCBmb3Igc2lnbmluZyBmb3IgYSBtYXhpbXVtCiAqIG9mIHR3byB3ZWVrcy4gVGhlIHJvdGF0aW9uIHByb2Nlc3MgaXMgcHJvYmFiaWxpc3RpYywgYW5kIHVzYWdlIG9mIHRoZSBuZXcga2V5IHdpbGwgZ3JhZHVhbGx5IHJhbXAKICogdXAgYW5kIGRvd24gb3ZlciB0aGUga2V5J3MgbGlmZXRpbWUuIFdlIHJlY29tbWVuZCBjYWNoaW5nIHRoZSBwdWJsaWMga2V5IHNldCBmb3IgYSBzZXJ2aWNlCiAqIGFjY291bnQgZm9yIG5vIG1vcmUgdGhhbiAyNCBob3VycyB0byBlbnN1cmUgeW91IGhhdmUgYWNjZXNzIHRvIHRoZSBsYXRlc3Qga2V5cy4KICoKICogUHVibGljIGtleXMgZm9yIGFsbCBzZXJ2aWNlIGFjY291bnRzIGFyZSBhbHNvIHB1Ymxpc2hlZCBhdCB0aGUgT0F1dGgyIFNlcnZpY2UgQWNjb3VudCBBUEkuCiAqCiAqIDxwPiBUaGlzIGlzIHRoZSBKYXZhIGRhdGEgbW9kZWwgY2xhc3MgdGhhdCBzcGVjaWZpZXMgaG93IHRvIHBhcnNlL3NlcmlhbGl6ZSBpbnRvIHRoZSBKU09OIHRoYXQgaXMKICogdHJhbnNtaXR0ZWQgb3ZlciBIVFRQIHdoZW4gd29ya2luZyB3aXRoIHRoZSBJZGVudGl0eSBhbmQgQWNjZXNzIE1hbmFnZW1lbnQgKElBTSkgQVBJLiBGb3IgYQogKiBkZXRhaWxlZCBleHBsYW5hdGlvbiBzZWU6CiAqIDxhIGhyZWY9Imh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL2FwaS1jbGllbnQtbGlicmFyeS9qYXZhL2dvb2dsZS1odHRwLWphdmEtY2xpZW50L2pzb24iPmh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL2FwaS1jbGllbnQtbGlicmFyeS9qYXZhL2dvb2dsZS1odHRwLWphdmEtY2xpZW50L2pzb248L2E+CiAqIDwvcD4KICoKICogQGF1dGhvciBHb29nbGUsIEluYy4KICovCkBTdXBwcmVzc1dhcm5pbmdzKCJqYXZhZG9jIikKcHVibGljIGZpbmFsIGNsYXNzIFNlcnZpY2VBY2NvdW50S2V5IGV4dGVuZHMgY29tLmdvb2dsZS5hcGkuY2xpZW50Lmpzb24uR2VuZXJpY0pzb24gewoKICAvKioKICAgKiBTcGVjaWZpZXMgdGhlIGFsZ29yaXRobSAoYW5kIHBvc3NpYmx5IGtleSBzaXplKSBmb3IgdGhlIGtleS4KICAgKiBUaGUgdmFsdWUgbWF5IGJlIHtAY29kZSBudWxsfS4KICAgKi8KICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgcHJpdmF0ZSBqYXZhLmxhbmcuU3RyaW5nIGtleUFsZ29yaXRobTsKCiAgLyoqCiAgICogVGhlIGtleSBvcmlnaW4uCiAgICogVGhlIHZhbHVlIG1heSBiZSB7QGNvZGUgbnVsbH0uCiAgICovCiAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogIHByaXZhdGUgamF2YS5sYW5nLlN0cmluZyBrZXlPcmlnaW47CgogIC8qKgogICAqIFRoZSBrZXkgdHlwZS4KICAgKiBUaGUgdmFsdWUgbWF5IGJlIHtAY29kZSBudWxsfS4KICAgKi8KICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgcHJpdmF0ZSBqYXZhLmxhbmcuU3RyaW5nIGtleVR5cGU7CgogIC8qKgogICAqIFRoZSByZXNvdXJjZSBuYW1lIG9mIHRoZSBzZXJ2aWNlIGFjY291bnQga2V5IGluIHRoZSBmb2xsb3dpbmcgZm9ybWF0CiAgICogYHByb2plY3RzL3tQUk9KRUNUX0lEfS9zZXJ2aWNlQWNjb3VudHMve0FDQ09VTlR9L2tleXMve2tleX1gLgogICAqIFRoZSB2YWx1ZSBtYXkgYmUge0Bjb2RlIG51bGx9LgogICAqLwogIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICBwcml2YXRlIGphdmEubGFuZy5TdHJpbmcgbmFtZTsKCiAgLyoqCiAgICogVGhlIHByaXZhdGUga2V5IGRhdGEuIE9ubHkgcHJvdmlkZWQgaW4gYENyZWF0ZVNlcnZpY2VBY2NvdW50S2V5YCByZXNwb25zZXMuIE1ha2Ugc3VyZSB0byBrZWVwCiAgICogdGhlIHByaXZhdGUga2V5IGRhdGEgc2VjdXJlIGJlY2F1c2UgaXQgYWxsb3dzIGZvciB0aGUgYXNzZXJ0aW9uIG9mIHRoZSBzZXJ2aWNlIGFjY291bnQKICAgKiBpZGVudGl0eS4gV2hlbiBiYXNlNjQgZGVjb2RlZCwgdGhlIHByaXZhdGUga2V5IGRhdGEgY2FuIGJlIHVzZWQgdG8gYXV0aGVudGljYXRlIHdpdGggR29vZ2xlIEFQSQogICAqIGNsaWVudCBsaWJyYXJpZXMgYW5kIHdpdGggZ2Nsb3VkIGF1dGggYWN0aXZhdGUtc2VydmljZS1hY2NvdW50LgogICAqIFRoZSB2YWx1ZSBtYXkgYmUge0Bjb2RlIG51bGx9LgogICAqLwogIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICBwcml2YXRlIGphdmEubGFuZy5TdHJpbmcgcHJpdmF0ZUtleURhdGE7CgogIC8qKgogICAqIFRoZSBvdXRwdXQgZm9ybWF0IGZvciB0aGUgcHJpdmF0ZSBrZXkuIE9ubHkgcHJvdmlkZWQgaW4gYENyZWF0ZVNlcnZpY2VBY2NvdW50S2V5YCByZXNwb25zZXMsCiAgICogbm90IGluIGBHZXRTZXJ2aWNlQWNjb3VudEtleWAgb3IgYExpc3RTZXJ2aWNlQWNjb3VudEtleWAgcmVzcG9uc2VzLgogICAqCiAgICogR29vZ2xlIG5ldmVyIGV4cG9zZXMgc3lzdGVtLW1hbmFnZWQgcHJpdmF0ZSBrZXlzLCBhbmQgbmV2ZXIgcmV0YWlucyB1c2VyLW1hbmFnZWQgcHJpdmF0ZSBrZXlzLgogICAqIFRoZSB2YWx1ZSBtYXkgYmUge0Bjb2RlIG51bGx9LgogICAqLwogIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICBwcml2YXRlIGphdmEubGFuZy5TdHJpbmcgcHJpdmF0ZUtleVR5cGU7CgogIC8qKgogICAqIFRoZSBwdWJsaWMga2V5IGRhdGEuIE9ubHkgcHJvdmlkZWQgaW4gYEdldFNlcnZpY2VBY2NvdW50S2V5YCByZXNwb25zZXMuCiAgICogVGhlIHZhbHVlIG1heSBiZSB7QGNvZGUgbnVsbH0uCiAgICovCiAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogIHByaXZhdGUgamF2YS5sYW5nLlN0cmluZyBwdWJsaWNLZXlEYXRhOwoKICAvKioKICAgKiBUaGUga2V5IGNhbiBiZSB1c2VkIGFmdGVyIHRoaXMgdGltZXN0YW1wLgogICAqIFRoZSB2YWx1ZSBtYXkgYmUge0Bjb2RlIG51bGx9LgogICAqLwogIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICBwcml2YXRlIFN0cmluZyB2YWxpZEFmdGVyVGltZTsKCiAgLyoqCiAgICogVGhlIGtleSBjYW4gYmUgdXNlZCBiZWZvcmUgdGhpcyB0aW1lc3RhbXAuIEZvciBzeXN0ZW0tbWFuYWdlZCBrZXkgcGFpcnMsIHRoaXMgdGltZXN0YW1wIGlzIHRoZQogICAqIGVuZCB0aW1lIGZvciB0aGUgcHJpdmF0ZSBrZXkgc2lnbmluZyBvcGVyYXRpb24uIFRoZSBwdWJsaWMga2V5IGNvdWxkIHN0aWxsIGJlIHVzZWQgZm9yCiAgICogdmVyaWZpY2F0aW9uIGZvciBhIGZldyBob3VycyBhZnRlciB0aGlzIHRpbWUuCiAgICogVGhlIHZhbHVlIG1heSBiZSB7QGNvZGUgbnVsbH0uCiAgICovCiAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogIHByaXZhdGUgU3RyaW5nIHZhbGlkQmVmb3JlVGltZTsKCiAgLyoqCiAgICogU3BlY2lmaWVzIHRoZSBhbGdvcml0aG0gKGFuZCBwb3NzaWJseSBrZXkgc2l6ZSkgZm9yIHRoZSBrZXkuCiAgICogQHJldHVybiB2YWx1ZSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRLZXlBbGdvcml0aG0oKSB7CiAgICByZXR1cm4ga2V5QWxnb3JpdGhtOwogIH0KCiAgLyoqCiAgICogU3BlY2lmaWVzIHRoZSBhbGdvcml0aG0gKGFuZCBwb3NzaWJseSBrZXkgc2l6ZSkgZm9yIHRoZSBrZXkuCiAgICogQHBhcmFtIGtleUFsZ29yaXRobSBrZXlBbGdvcml0aG0gb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIFNlcnZpY2VBY2NvdW50S2V5IHNldEtleUFsZ29yaXRobShqYXZhLmxhbmcuU3RyaW5nIGtleUFsZ29yaXRobSkgewogICAgdGhpcy5rZXlBbGdvcml0aG0gPSBrZXlBbGdvcml0aG07CiAgICByZXR1cm4gdGhpczsKICB9CgogIC8qKgogICAqIFRoZSBrZXkgb3JpZ2luLgogICAqIEByZXR1cm4gdmFsdWUgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0S2V5T3JpZ2luKCkgewogICAgcmV0dXJuIGtleU9yaWdpbjsKICB9CgogIC8qKgogICAqIFRoZSBrZXkgb3JpZ2luLgogICAqIEBwYXJhbSBrZXlPcmlnaW4ga2V5T3JpZ2luIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBTZXJ2aWNlQWNjb3VudEtleSBzZXRLZXlPcmlnaW4oamF2YS5sYW5nLlN0cmluZyBrZXlPcmlnaW4pIHsKICAgIHRoaXMua2V5T3JpZ2luID0ga2V5T3JpZ2luOwogICAgcmV0dXJuIHRoaXM7CiAgfQoKICAvKioKICAgKiBUaGUga2V5IHR5cGUuCiAgICogQHJldHVybiB2YWx1ZSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRLZXlUeXBlKCkgewogICAgcmV0dXJuIGtleVR5cGU7CiAgfQoKICAvKioKICAgKiBUaGUga2V5IHR5cGUuCiAgICogQHBhcmFtIGtleVR5cGUga2V5VHlwZSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgU2VydmljZUFjY291bnRLZXkgc2V0S2V5VHlwZShqYXZhLmxhbmcuU3RyaW5nIGtleVR5cGUpIHsKICAgIHRoaXMua2V5VHlwZSA9IGtleVR5cGU7CiAgICByZXR1cm4gdGhpczsKICB9CgogIC8qKgogICAqIFRoZSByZXNvdXJjZSBuYW1lIG9mIHRoZSBzZXJ2aWNlIGFjY291bnQga2V5IGluIHRoZSBmb2xsb3dpbmcgZm9ybWF0CiAgICogYHByb2plY3RzL3tQUk9KRUNUX0lEfS9zZXJ2aWNlQWNjb3VudHMve0FDQ09VTlR9L2tleXMve2tleX1gLgogICAqIEByZXR1cm4gdmFsdWUgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TmFtZSgpIHsKICAgIHJldHVybiBuYW1lOwogIH0KCiAgLyoqCiAgICogVGhlIHJlc291cmNlIG5hbWUgb2YgdGhlIHNlcnZpY2UgYWNjb3VudCBrZXkgaW4gdGhlIGZvbGxvd2luZyBmb3JtYXQKICAgKiBgcHJvamVjdHMve1BST0pFQ1RfSUR9L3NlcnZpY2VBY2NvdW50cy97QUNDT1VOVH0va2V5cy97a2V5fWAuCiAgICogQHBhcmFtIG5hbWUgbmFtZSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgU2VydmljZUFjY291bnRLZXkgc2V0TmFtZShqYXZhLmxhbmcuU3RyaW5nIG5hbWUpIHsKICAgIHRoaXMubmFtZSA9IG5hbWU7CiAgICByZXR1cm4gdGhpczsKICB9CgogIC8qKgogICAqIFRoZSBwcml2YXRlIGtleSBkYXRhLiBPbmx5IHByb3ZpZGVkIGluIGBDcmVhdGVTZXJ2aWNlQWNjb3VudEtleWAgcmVzcG9uc2VzLiBNYWtlIHN1cmUgdG8ga2VlcAogICAqIHRoZSBwcml2YXRlIGtleSBkYXRhIHNlY3VyZSBiZWNhdXNlIGl0IGFsbG93cyBmb3IgdGhlIGFzc2VydGlvbiBvZiB0aGUgc2VydmljZSBhY2NvdW50CiAgICogaWRlbnRpdHkuIFdoZW4gYmFzZTY0IGRlY29kZWQsIHRoZSBwcml2YXRlIGtleSBkYXRhIGNhbiBiZSB1c2VkIHRvIGF1dGhlbnRpY2F0ZSB3aXRoIEdvb2dsZSBBUEkKICAgKiBjbGllbnQgbGlicmFyaWVzIGFuZCB3aXRoIGdjbG91ZCBhdXRoIGFjdGl2YXRlLXNlcnZpY2UtYWNjb3VudC4KICAgKiBAc2VlICNkZWNvZGVQcml2YXRlS2V5RGF0YSgpCiAgICogQHJldHVybiB2YWx1ZSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRQcml2YXRlS2V5RGF0YSgpIHsKICAgIHJldHVybiBwcml2YXRlS2V5RGF0YTsKICB9CgogIC8qKgogICAqIFRoZSBwcml2YXRlIGtleSBkYXRhLiBPbmx5IHByb3ZpZGVkIGluIGBDcmVhdGVTZXJ2aWNlQWNjb3VudEtleWAgcmVzcG9uc2VzLiBNYWtlIHN1cmUgdG8ga2VlcAogICAqIHRoZSBwcml2YXRlIGtleSBkYXRhIHNlY3VyZSBiZWNhdXNlIGl0IGFsbG93cyBmb3IgdGhlIGFzc2VydGlvbiBvZiB0aGUgc2VydmljZSBhY2NvdW50CiAgICogaWRlbnRpdHkuIFdoZW4gYmFzZTY0IGRlY29kZWQsIHRoZSBwcml2YXRlIGtleSBkYXRhIGNhbiBiZSB1c2VkIHRvIGF1dGhlbnRpY2F0ZSB3aXRoIEdvb2dsZSBBUEkKICAgKiBjbGllbnQgbGlicmFyaWVzIGFuZCB3aXRoIGdjbG91ZCBhdXRoIGFjdGl2YXRlLXNlcnZpY2UtYWNjb3VudC4KICAgKiBAc2VlICNnZXRQcml2YXRlS2V5RGF0YSgpCiAgICogQHJldHVybiBCYXNlNjQgZGVjb2RlZCB2YWx1ZSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKgogICAqIEBzaW5jZSAxLjE0CiAgICovCiAgcHVibGljIGJ5dGVbXSBkZWNvZGVQcml2YXRlS2V5RGF0YSgpIHsKICAgIHJldHVybiBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5CYXNlNjQuZGVjb2RlQmFzZTY0KHByaXZhdGVLZXlEYXRhKTsKICB9CgogIC8qKgogICAqIFRoZSBwcml2YXRlIGtleSBkYXRhLiBPbmx5IHByb3ZpZGVkIGluIGBDcmVhdGVTZXJ2aWNlQWNjb3VudEtleWAgcmVzcG9uc2VzLiBNYWtlIHN1cmUgdG8ga2VlcAogICAqIHRoZSBwcml2YXRlIGtleSBkYXRhIHNlY3VyZSBiZWNhdXNlIGl0IGFsbG93cyBmb3IgdGhlIGFzc2VydGlvbiBvZiB0aGUgc2VydmljZSBhY2NvdW50CiAgICogaWRlbnRpdHkuIFdoZW4gYmFzZTY0IGRlY29kZWQsIHRoZSBwcml2YXRlIGtleSBkYXRhIGNhbiBiZSB1c2VkIHRvIGF1dGhlbnRpY2F0ZSB3aXRoIEdvb2dsZSBBUEkKICAgKiBjbGllbnQgbGlicmFyaWVzIGFuZCB3aXRoIGdjbG91ZCBhdXRoIGFjdGl2YXRlLXNlcnZpY2UtYWNjb3VudC4KICAgKiBAc2VlICNlbmNvZGVQcml2YXRlS2V5RGF0YSgpCiAgICogQHBhcmFtIHByaXZhdGVLZXlEYXRhIHByaXZhdGVLZXlEYXRhIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBTZXJ2aWNlQWNjb3VudEtleSBzZXRQcml2YXRlS2V5RGF0YShqYXZhLmxhbmcuU3RyaW5nIHByaXZhdGVLZXlEYXRhKSB7CiAgICB0aGlzLnByaXZhdGVLZXlEYXRhID0gcHJpdmF0ZUtleURhdGE7CiAgICByZXR1cm4gdGhpczsKICB9CgogIC8qKgogICAqIFRoZSBwcml2YXRlIGtleSBkYXRhLiBPbmx5IHByb3ZpZGVkIGluIGBDcmVhdGVTZXJ2aWNlQWNjb3VudEtleWAgcmVzcG9uc2VzLiBNYWtlIHN1cmUgdG8ga2VlcAogICAqIHRoZSBwcml2YXRlIGtleSBkYXRhIHNlY3VyZSBiZWNhdXNlIGl0IGFsbG93cyBmb3IgdGhlIGFzc2VydGlvbiBvZiB0aGUgc2VydmljZSBhY2NvdW50CiAgICogaWRlbnRpdHkuIFdoZW4gYmFzZTY0IGRlY29kZWQsIHRoZSBwcml2YXRlIGtleSBkYXRhIGNhbiBiZSB1c2VkIHRvIGF1dGhlbnRpY2F0ZSB3aXRoIEdvb2dsZSBBUEkKICAgKiBjbGllbnQgbGlicmFyaWVzIGFuZCB3aXRoIGdjbG91ZCBhdXRoIGFjdGl2YXRlLXNlcnZpY2UtYWNjb3VudC4KICAgKiBAc2VlICNzZXRQcml2YXRlS2V5RGF0YSgpCiAgICoKICAgKiA8cD4KICAgKiBUaGUgdmFsdWUgaXMgZW5jb2RlZCBCYXNlNjQgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lLgogICAqIDwvcD4KICAgKgogICAqIEBzaW5jZSAxLjE0CiAgICovCiAgcHVibGljIFNlcnZpY2VBY2NvdW50S2V5IGVuY29kZVByaXZhdGVLZXlEYXRhKGJ5dGVbXSBwcml2YXRlS2V5RGF0YSkgewogICAgdGhpcy5wcml2YXRlS2V5RGF0YSA9IGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLkJhc2U2NC5lbmNvZGVCYXNlNjRVUkxTYWZlU3RyaW5nKHByaXZhdGVLZXlEYXRhKTsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgLyoqCiAgICogVGhlIG91dHB1dCBmb3JtYXQgZm9yIHRoZSBwcml2YXRlIGtleS4gT25seSBwcm92aWRlZCBpbiBgQ3JlYXRlU2VydmljZUFjY291bnRLZXlgIHJlc3BvbnNlcywKICAgKiBub3QgaW4gYEdldFNlcnZpY2VBY2NvdW50S2V5YCBvciBgTGlzdFNlcnZpY2VBY2NvdW50S2V5YCByZXNwb25zZXMuCiAgICoKICAgKiBHb29nbGUgbmV2ZXIgZXhwb3NlcyBzeXN0ZW0tbWFuYWdlZCBwcml2YXRlIGtleXMsIGFuZCBuZXZlciByZXRhaW5zIHVzZXItbWFuYWdlZCBwcml2YXRlIGtleXMuCiAgICogQHJldHVybiB2YWx1ZSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRQcml2YXRlS2V5VHlwZSgpIHsKICAgIHJldHVybiBwcml2YXRlS2V5VHlwZTsKICB9CgogIC8qKgogICAqIFRoZSBvdXRwdXQgZm9ybWF0IGZvciB0aGUgcHJpdmF0ZSBrZXkuIE9ubHkgcHJvdmlkZWQgaW4gYENyZWF0ZVNlcnZpY2VBY2NvdW50S2V5YCByZXNwb25zZXMsCiAgICogbm90IGluIGBHZXRTZXJ2aWNlQWNjb3VudEtleWAgb3IgYExpc3RTZXJ2aWNlQWNjb3VudEtleWAgcmVzcG9uc2VzLgogICAqCiAgICogR29vZ2xlIG5ldmVyIGV4cG9zZXMgc3lzdGVtLW1hbmFnZWQgcHJpdmF0ZSBrZXlzLCBhbmQgbmV2ZXIgcmV0YWlucyB1c2VyLW1hbmFnZWQgcHJpdmF0ZSBrZXlzLgogICAqIEBwYXJhbSBwcml2YXRlS2V5VHlwZSBwcml2YXRlS2V5VHlwZSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgU2VydmljZUFjY291bnRLZXkgc2V0UHJpdmF0ZUtleVR5cGUoamF2YS5sYW5nLlN0cmluZyBwcml2YXRlS2V5VHlwZSkgewogICAgdGhpcy5wcml2YXRlS2V5VHlwZSA9IHByaXZhdGVLZXlUeXBlOwogICAgcmV0dXJuIHRoaXM7CiAgfQoKICAvKioKICAgKiBUaGUgcHVibGljIGtleSBkYXRhLiBPbmx5IHByb3ZpZGVkIGluIGBHZXRTZXJ2aWNlQWNjb3VudEtleWAgcmVzcG9uc2VzLgogICAqIEBzZWUgI2RlY29kZVB1YmxpY0tleURhdGEoKQogICAqIEByZXR1cm4gdmFsdWUgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0UHVibGljS2V5RGF0YSgpIHsKICAgIHJldHVybiBwdWJsaWNLZXlEYXRhOwogIH0KCiAgLyoqCiAgICogVGhlIHB1YmxpYyBrZXkgZGF0YS4gT25seSBwcm92aWRlZCBpbiBgR2V0U2VydmljZUFjY291bnRLZXlgIHJlc3BvbnNlcy4KICAgKiBAc2VlICNnZXRQdWJsaWNLZXlEYXRhKCkKICAgKiBAcmV0dXJuIEJhc2U2NCBkZWNvZGVkIHZhbHVlIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqCiAgICogQHNpbmNlIDEuMTQKICAgKi8KICBwdWJsaWMgYnl0ZVtdIGRlY29kZVB1YmxpY0tleURhdGEoKSB7CiAgICByZXR1cm4gY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuQmFzZTY0LmRlY29kZUJhc2U2NChwdWJsaWNLZXlEYXRhKTsKICB9CgogIC8qKgogICAqIFRoZSBwdWJsaWMga2V5IGRhdGEuIE9ubHkgcHJvdmlkZWQgaW4gYEdldFNlcnZpY2VBY2NvdW50S2V5YCByZXNwb25zZXMuCiAgICogQHNlZSAjZW5jb2RlUHVibGljS2V5RGF0YSgpCiAgICogQHBhcmFtIHB1YmxpY0tleURhdGEgcHVibGljS2V5RGF0YSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgU2VydmljZUFjY291bnRLZXkgc2V0UHVibGljS2V5RGF0YShqYXZhLmxhbmcuU3RyaW5nIHB1YmxpY0tleURhdGEpIHsKICAgIHRoaXMucHVibGljS2V5RGF0YSA9IHB1YmxpY0tleURhdGE7CiAgICByZXR1cm4gdGhpczsKICB9CgogIC8qKgogICAqIFRoZSBwdWJsaWMga2V5IGRhdGEuIE9ubHkgcHJvdmlkZWQgaW4gYEdldFNlcnZpY2VBY2NvdW50S2V5YCByZXNwb25zZXMuCiAgICogQHNlZSAjc2V0UHVibGljS2V5RGF0YSgpCiAgICoKICAgKiA8cD4KICAgKiBUaGUgdmFsdWUgaXMgZW5jb2RlZCBCYXNlNjQgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lLgogICAqIDwvcD4KICAgKgogICAqIEBzaW5jZSAxLjE0CiAgICovCiAgcHVibGljIFNlcnZpY2VBY2NvdW50S2V5IGVuY29kZVB1YmxpY0tleURhdGEoYnl0ZVtdIHB1YmxpY0tleURhdGEpIHsKICAgIHRoaXMucHVibGljS2V5RGF0YSA9IGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLkJhc2U2NC5lbmNvZGVCYXNlNjRVUkxTYWZlU3RyaW5nKHB1YmxpY0tleURhdGEpOwogICAgcmV0dXJuIHRoaXM7CiAgfQoKICAvKioKICAgKiBUaGUga2V5IGNhbiBiZSB1c2VkIGFmdGVyIHRoaXMgdGltZXN0YW1wLgogICAqIEByZXR1cm4gdmFsdWUgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIFN0cmluZyBnZXRWYWxpZEFmdGVyVGltZSgpIHsKICAgIHJldHVybiB2YWxpZEFmdGVyVGltZTsKICB9CgogIC8qKgogICAqIFRoZSBrZXkgY2FuIGJlIHVzZWQgYWZ0ZXIgdGhpcyB0aW1lc3RhbXAuCiAgICogQHBhcmFtIHZhbGlkQWZ0ZXJUaW1lIHZhbGlkQWZ0ZXJUaW1lIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBTZXJ2aWNlQWNjb3VudEtleSBzZXRWYWxpZEFmdGVyVGltZShTdHJpbmcgdmFsaWRBZnRlclRpbWUpIHsKICAgIHRoaXMudmFsaWRBZnRlclRpbWUgPSB2YWxpZEFmdGVyVGltZTsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgLyoqCiAgICogVGhlIGtleSBjYW4gYmUgdXNlZCBiZWZvcmUgdGhpcyB0aW1lc3RhbXAuIEZvciBzeXN0ZW0tbWFuYWdlZCBrZXkgcGFpcnMsIHRoaXMgdGltZXN0YW1wIGlzIHRoZQogICAqIGVuZCB0aW1lIGZvciB0aGUgcHJpdmF0ZSBrZXkgc2lnbmluZyBvcGVyYXRpb24uIFRoZSBwdWJsaWMga2V5IGNvdWxkIHN0aWxsIGJlIHVzZWQgZm9yCiAgICogdmVyaWZpY2F0aW9uIGZvciBhIGZldyBob3VycyBhZnRlciB0aGlzIHRpbWUuCiAgICogQHJldHVybiB2YWx1ZSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgU3RyaW5nIGdldFZhbGlkQmVmb3JlVGltZSgpIHsKICAgIHJldHVybiB2YWxpZEJlZm9yZVRpbWU7CiAgfQoKICAvKioKICAgKiBUaGUga2V5IGNhbiBiZSB1c2VkIGJlZm9yZSB0aGlzIHRpbWVzdGFtcC4gRm9yIHN5c3RlbS1tYW5hZ2VkIGtleSBwYWlycywgdGhpcyB0aW1lc3RhbXAgaXMgdGhlCiAgICogZW5kIHRpbWUgZm9yIHRoZSBwcml2YXRlIGtleSBzaWduaW5nIG9wZXJhdGlvbi4gVGhlIHB1YmxpYyBrZXkgY291bGQgc3RpbGwgYmUgdXNlZCBmb3IKICAgKiB2ZXJpZmljYXRpb24gZm9yIGEgZmV3IGhvdXJzIGFmdGVyIHRoaXMgdGltZS4KICAgKiBAcGFyYW0gdmFsaWRCZWZvcmVUaW1lIHZhbGlkQmVmb3JlVGltZSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgU2VydmljZUFjY291bnRLZXkgc2V0VmFsaWRCZWZvcmVUaW1lKFN0cmluZyB2YWxpZEJlZm9yZVRpbWUpIHsKICAgIHRoaXMudmFsaWRCZWZvcmVUaW1lID0gdmFsaWRCZWZvcmVUaW1lOwogICAgcmV0dXJuIHRoaXM7CiAgfQoKICBAT3ZlcnJpZGUKICBwdWJsaWMgU2VydmljZUFjY291bnRLZXkgc2V0KFN0cmluZyBmaWVsZE5hbWUsIE9iamVjdCB2YWx1ZSkgewogICAgcmV0dXJuIChTZXJ2aWNlQWNjb3VudEtleSkgc3VwZXIuc2V0KGZpZWxkTmFtZSwgdmFsdWUpOwogIH0KCiAgQE92ZXJyaWRlCiAgcHVibGljIFNlcnZpY2VBY2NvdW50S2V5IGNsb25lKCkgewogICAgcmV0dXJuIChTZXJ2aWNlQWNjb3VudEtleSkgc3VwZXIuY2xvbmUoKTsKICB9Cgp9ClBLAwQUAAAAAAAAACEAkAEvT4cPAACHDwAAPQAAAGNvbS9nb29nbGUvYXBpL3NlcnZpY2VzL2lhbS92MS9tb2RlbC9TZXRJYW1Qb2xpY3lSZXF1ZXN0LmphdmEvKgogKiBDb3B5cmlnaHQgMjAxMCBHb29nbGUgSW5jLgogKgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQKICogaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UKICogaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzCiAqIG9yIGltcGxpZWQuIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMgdW5kZXIKICogdGhlIExpY2Vuc2UuCiAqLwovKgogKiBUaGlzIGNvZGUgd2FzIGdlbmVyYXRlZCBieSBodHRwczovL2dpdGh1Yi5jb20vZ29vZ2xlL2FwaXMtY2xpZW50LWdlbmVyYXRvci8KICogKGJ1aWxkOiAyMDE4LTEwLTA4IDE3OjQ1OjM5IFVUQykKICogb24gMjAyMC0wMy0xOSBhdCAwMTo1Mjo0MSBVVEMgCiAqIE1vZGlmeSBhdCB5b3VyIG93biByaXNrLgogKi8KCnBhY2thZ2UgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuaWFtLnYxLm1vZGVsOwoKLyoqCiAqIFJlcXVlc3QgbWVzc2FnZSBmb3IgYFNldElhbVBvbGljeWAgbWV0aG9kLgogKgogKiA8cD4gVGhpcyBpcyB0aGUgSmF2YSBkYXRhIG1vZGVsIGNsYXNzIHRoYXQgc3BlY2lmaWVzIGhvdyB0byBwYXJzZS9zZXJpYWxpemUgaW50byB0aGUgSlNPTiB0aGF0IGlzCiAqIHRyYW5zbWl0dGVkIG92ZXIgSFRUUCB3aGVuIHdvcmtpbmcgd2l0aCB0aGUgSWRlbnRpdHkgYW5kIEFjY2VzcyBNYW5hZ2VtZW50IChJQU0pIEFQSS4gRm9yIGEKICogZGV0YWlsZWQgZXhwbGFuYXRpb24gc2VlOgogKiA8YSBocmVmPSJodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9hcGktY2xpZW50LWxpYnJhcnkvamF2YS9nb29nbGUtaHR0cC1qYXZhLWNsaWVudC9qc29uIj5odHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9hcGktY2xpZW50LWxpYnJhcnkvamF2YS9nb29nbGUtaHR0cC1qYXZhLWNsaWVudC9qc29uPC9hPgogKiA8L3A+CiAqCiAqIEBhdXRob3IgR29vZ2xlLCBJbmMuCiAqLwpAU3VwcHJlc3NXYXJuaW5ncygiamF2YWRvYyIpCnB1YmxpYyBmaW5hbCBjbGFzcyBTZXRJYW1Qb2xpY3lSZXF1ZXN0IGV4dGVuZHMgY29tLmdvb2dsZS5hcGkuY2xpZW50Lmpzb24uR2VuZXJpY0pzb24gewoKICAvKioKICAgKiBSRVFVSVJFRDogVGhlIGNvbXBsZXRlIHBvbGljeSB0byBiZSBhcHBsaWVkIHRvIHRoZSBgcmVzb3VyY2VgLiBUaGUgc2l6ZSBvZiB0aGUgcG9saWN5IGlzCiAgICogbGltaXRlZCB0byBhIGZldyAxMHMgb2YgS0IuIEFuIGVtcHR5IHBvbGljeSBpcyBhIHZhbGlkIHBvbGljeSBidXQgY2VydGFpbiBDbG91ZCBQbGF0Zm9ybQogICAqIHNlcnZpY2VzIChzdWNoIGFzIFByb2plY3RzKSBtaWdodCByZWplY3QgdGhlbS4KICAgKiBUaGUgdmFsdWUgbWF5IGJlIHtAY29kZSBudWxsfS4KICAgKi8KICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgcHJpdmF0ZSBQb2xpY3kgcG9saWN5OwoKICAvKioKICAgKiBPUFRJT05BTDogQSBGaWVsZE1hc2sgc3BlY2lmeWluZyB3aGljaCBmaWVsZHMgb2YgdGhlIHBvbGljeSB0byBtb2RpZnkuIE9ubHkgdGhlIGZpZWxkcyBpbiB0aGUKICAgKiBtYXNrIHdpbGwgYmUgbW9kaWZpZWQuIElmIG5vIG1hc2sgaXMgcHJvdmlkZWQsIHRoZSBmb2xsb3dpbmcgZGVmYXVsdCBtYXNrIGlzIHVzZWQ6IHBhdGhzOgogICAqICJiaW5kaW5ncywgZXRhZyIgVGhpcyBmaWVsZCBpcyBvbmx5IHVzZWQgYnkgQ2xvdWQgSUFNLgogICAqIFRoZSB2YWx1ZSBtYXkgYmUge0Bjb2RlIG51bGx9LgogICAqLwogIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICBwcml2YXRlIFN0cmluZyB1cGRhdGVNYXNrOwoKICAvKioKICAgKiBSRVFVSVJFRDogVGhlIGNvbXBsZXRlIHBvbGljeSB0byBiZSBhcHBsaWVkIHRvIHRoZSBgcmVzb3VyY2VgLiBUaGUgc2l6ZSBvZiB0aGUgcG9saWN5IGlzCiAgICogbGltaXRlZCB0byBhIGZldyAxMHMgb2YgS0IuIEFuIGVtcHR5IHBvbGljeSBpcyBhIHZhbGlkIHBvbGljeSBidXQgY2VydGFpbiBDbG91ZCBQbGF0Zm9ybQogICAqIHNlcnZpY2VzIChzdWNoIGFzIFByb2plY3RzKSBtaWdodCByZWplY3QgdGhlbS4KICAgKiBAcmV0dXJuIHZhbHVlIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBQb2xpY3kgZ2V0UG9saWN5KCkgewogICAgcmV0dXJuIHBvbGljeTsKICB9CgogIC8qKgogICAqIFJFUVVJUkVEOiBUaGUgY29tcGxldGUgcG9saWN5IHRvIGJlIGFwcGxpZWQgdG8gdGhlIGByZXNvdXJjZWAuIFRoZSBzaXplIG9mIHRoZSBwb2xpY3kgaXMKICAgKiBsaW1pdGVkIHRvIGEgZmV3IDEwcyBvZiBLQi4gQW4gZW1wdHkgcG9saWN5IGlzIGEgdmFsaWQgcG9saWN5IGJ1dCBjZXJ0YWluIENsb3VkIFBsYXRmb3JtCiAgICogc2VydmljZXMgKHN1Y2ggYXMgUHJvamVjdHMpIG1pZ2h0IHJlamVjdCB0aGVtLgogICAqIEBwYXJhbSBwb2xpY3kgcG9saWN5IG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBTZXRJYW1Qb2xpY3lSZXF1ZXN0IHNldFBvbGljeShQb2xpY3kgcG9saWN5KSB7CiAgICB0aGlzLnBvbGljeSA9IHBvbGljeTsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgLyoqCiAgICogT1BUSU9OQUw6IEEgRmllbGRNYXNrIHNwZWNpZnlpbmcgd2hpY2ggZmllbGRzIG9mIHRoZSBwb2xpY3kgdG8gbW9kaWZ5LiBPbmx5IHRoZSBmaWVsZHMgaW4gdGhlCiAgICogbWFzayB3aWxsIGJlIG1vZGlmaWVkLiBJZiBubyBtYXNrIGlzIHByb3ZpZGVkLCB0aGUgZm9sbG93aW5nIGRlZmF1bHQgbWFzayBpcyB1c2VkOiBwYXRoczoKICAgKiAiYmluZGluZ3MsIGV0YWciIFRoaXMgZmllbGQgaXMgb25seSB1c2VkIGJ5IENsb3VkIElBTS4KICAgKiBAcmV0dXJuIHZhbHVlIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBTdHJpbmcgZ2V0VXBkYXRlTWFzaygpIHsKICAgIHJldHVybiB1cGRhdGVNYXNrOwogIH0KCiAgLyoqCiAgICogT1BUSU9OQUw6IEEgRmllbGRNYXNrIHNwZWNpZnlpbmcgd2hpY2ggZmllbGRzIG9mIHRoZSBwb2xpY3kgdG8gbW9kaWZ5LiBPbmx5IHRoZSBmaWVsZHMgaW4gdGhlCiAgICogbWFzayB3aWxsIGJlIG1vZGlmaWVkLiBJZiBubyBtYXNrIGlzIHByb3ZpZGVkLCB0aGUgZm9sbG93aW5nIGRlZmF1bHQgbWFzayBpcyB1c2VkOiBwYXRoczoKICAgKiAiYmluZGluZ3MsIGV0YWciIFRoaXMgZmllbGQgaXMgb25seSB1c2VkIGJ5IENsb3VkIElBTS4KICAgKiBAcGFyYW0gdXBkYXRlTWFzayB1cGRhdGVNYXNrIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBTZXRJYW1Qb2xpY3lSZXF1ZXN0IHNldFVwZGF0ZU1hc2soU3RyaW5nIHVwZGF0ZU1hc2spIHsKICAgIHRoaXMudXBkYXRlTWFzayA9IHVwZGF0ZU1hc2s7CiAgICByZXR1cm4gdGhpczsKICB9CgogIEBPdmVycmlkZQogIHB1YmxpYyBTZXRJYW1Qb2xpY3lSZXF1ZXN0IHNldChTdHJpbmcgZmllbGROYW1lLCBPYmplY3QgdmFsdWUpIHsKICAgIHJldHVybiAoU2V0SWFtUG9saWN5UmVxdWVzdCkgc3VwZXIuc2V0KGZpZWxkTmFtZSwgdmFsdWUpOwogIH0KCiAgQE92ZXJyaWRlCiAgcHVibGljIFNldElhbVBvbGljeVJlcXVlc3QgY2xvbmUoKSB7CiAgICByZXR1cm4gKFNldElhbVBvbGljeVJlcXVlc3QpIHN1cGVyLmNsb25lKCk7CiAgfQoKfQpQSwMEFAAAAAAAAAAhAKHoQ7dkCwAAZAsAADkAAABjb20vZ29vZ2xlL2FwaS9zZXJ2aWNlcy9pYW0vdjEvbW9kZWwvU2lnbkJsb2JSZXF1ZXN0LmphdmEvKgogKiBDb3B5cmlnaHQgMjAxMCBHb29nbGUgSW5jLgogKgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQKICogaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UKICogaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzCiAqIG9yIGltcGxpZWQuIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMgdW5kZXIKICogdGhlIExpY2Vuc2UuCiAqLwovKgogKiBUaGlzIGNvZGUgd2FzIGdlbmVyYXRlZCBieSBodHRwczovL2dpdGh1Yi5jb20vZ29vZ2xlL2FwaXMtY2xpZW50LWdlbmVyYXRvci8KICogKGJ1aWxkOiAyMDE4LTEwLTA4IDE3OjQ1OjM5IFVUQykKICogb24gMjAyMC0wMy0xOSBhdCAwMTo1Mjo0MSBVVEMgCiAqIE1vZGlmeSBhdCB5b3VyIG93biByaXNrLgogKi8KCnBhY2thZ2UgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuaWFtLnYxLm1vZGVsOwoKLyoqCiAqIFRoZSBzZXJ2aWNlIGFjY291bnQgc2lnbiBibG9iIHJlcXVlc3QuCiAqCiAqIDxwPiBUaGlzIGlzIHRoZSBKYXZhIGRhdGEgbW9kZWwgY2xhc3MgdGhhdCBzcGVjaWZpZXMgaG93IHRvIHBhcnNlL3NlcmlhbGl6ZSBpbnRvIHRoZSBKU09OIHRoYXQgaXMKICogdHJhbnNtaXR0ZWQgb3ZlciBIVFRQIHdoZW4gd29ya2luZyB3aXRoIHRoZSBJZGVudGl0eSBhbmQgQWNjZXNzIE1hbmFnZW1lbnQgKElBTSkgQVBJLiBGb3IgYQogKiBkZXRhaWxlZCBleHBsYW5hdGlvbiBzZWU6CiAqIDxhIGhyZWY9Imh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL2FwaS1jbGllbnQtbGlicmFyeS9qYXZhL2dvb2dsZS1odHRwLWphdmEtY2xpZW50L2pzb24iPmh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL2FwaS1jbGllbnQtbGlicmFyeS9qYXZhL2dvb2dsZS1odHRwLWphdmEtY2xpZW50L2pzb248L2E+CiAqIDwvcD4KICoKICogQGF1dGhvciBHb29nbGUsIEluYy4KICovCkBTdXBwcmVzc1dhcm5pbmdzKCJqYXZhZG9jIikKcHVibGljIGZpbmFsIGNsYXNzIFNpZ25CbG9iUmVxdWVzdCBleHRlbmRzIGNvbS5nb29nbGUuYXBpLmNsaWVudC5qc29uLkdlbmVyaWNKc29uIHsKCiAgLyoqCiAgICogUmVxdWlyZWQuIFRoZSBieXRlcyB0byBzaWduLgogICAqIFRoZSB2YWx1ZSBtYXkgYmUge0Bjb2RlIG51bGx9LgogICAqLwogIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICBwcml2YXRlIGphdmEubGFuZy5TdHJpbmcgYnl0ZXNUb1NpZ247CgogIC8qKgogICAqIFJlcXVpcmVkLiBUaGUgYnl0ZXMgdG8gc2lnbi4KICAgKiBAc2VlICNkZWNvZGVCeXRlc1RvU2lnbigpCiAgICogQHJldHVybiB2YWx1ZSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRCeXRlc1RvU2lnbigpIHsKICAgIHJldHVybiBieXRlc1RvU2lnbjsKICB9CgogIC8qKgogICAqIFJlcXVpcmVkLiBUaGUgYnl0ZXMgdG8gc2lnbi4KICAgKiBAc2VlICNnZXRCeXRlc1RvU2lnbigpCiAgICogQHJldHVybiBCYXNlNjQgZGVjb2RlZCB2YWx1ZSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKgogICAqIEBzaW5jZSAxLjE0CiAgICovCiAgcHVibGljIGJ5dGVbXSBkZWNvZGVCeXRlc1RvU2lnbigpIHsKICAgIHJldHVybiBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5CYXNlNjQuZGVjb2RlQmFzZTY0KGJ5dGVzVG9TaWduKTsKICB9CgogIC8qKgogICAqIFJlcXVpcmVkLiBUaGUgYnl0ZXMgdG8gc2lnbi4KICAgKiBAc2VlICNlbmNvZGVCeXRlc1RvU2lnbigpCiAgICogQHBhcmFtIGJ5dGVzVG9TaWduIGJ5dGVzVG9TaWduIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBTaWduQmxvYlJlcXVlc3Qgc2V0Qnl0ZXNUb1NpZ24oamF2YS5sYW5nLlN0cmluZyBieXRlc1RvU2lnbikgewogICAgdGhpcy5ieXRlc1RvU2lnbiA9IGJ5dGVzVG9TaWduOwogICAgcmV0dXJuIHRoaXM7CiAgfQoKICAvKioKICAgKiBSZXF1aXJlZC4gVGhlIGJ5dGVzIHRvIHNpZ24uCiAgICogQHNlZSAjc2V0Qnl0ZXNUb1NpZ24oKQogICAqCiAgICogPHA+CiAgICogVGhlIHZhbHVlIGlzIGVuY29kZWQgQmFzZTY0IG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZS4KICAgKiA8L3A+CiAgICoKICAgKiBAc2luY2UgMS4xNAogICAqLwogIHB1YmxpYyBTaWduQmxvYlJlcXVlc3QgZW5jb2RlQnl0ZXNUb1NpZ24oYnl0ZVtdIGJ5dGVzVG9TaWduKSB7CiAgICB0aGlzLmJ5dGVzVG9TaWduID0gY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuQmFzZTY0LmVuY29kZUJhc2U2NFVSTFNhZmVTdHJpbmcoYnl0ZXNUb1NpZ24pOwogICAgcmV0dXJuIHRoaXM7CiAgfQoKICBAT3ZlcnJpZGUKICBwdWJsaWMgU2lnbkJsb2JSZXF1ZXN0IHNldChTdHJpbmcgZmllbGROYW1lLCBPYmplY3QgdmFsdWUpIHsKICAgIHJldHVybiAoU2lnbkJsb2JSZXF1ZXN0KSBzdXBlci5zZXQoZmllbGROYW1lLCB2YWx1ZSk7CiAgfQoKICBAT3ZlcnJpZGUKICBwdWJsaWMgU2lnbkJsb2JSZXF1ZXN0IGNsb25lKCkgewogICAgcmV0dXJuIChTaWduQmxvYlJlcXVlc3QpIHN1cGVyLmNsb25lKCk7CiAgfQoKfQpQSwMEFAAAAAAAAAAhADA63UYnDQAAJw0AADoAAABjb20vZ29vZ2xlL2FwaS9zZXJ2aWNlcy9pYW0vdjEvbW9kZWwvU2lnbkJsb2JSZXNwb25zZS5qYXZhLyoKICogQ29weXJpZ2h0IDIwMTAgR29vZ2xlIEluYy4KICoKICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0CiAqIGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4gWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlCiAqIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcwogKiBvciBpbXBsaWVkLiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zIHVuZGVyCiAqIHRoZSBMaWNlbnNlLgogKi8KLyoKICogVGhpcyBjb2RlIHdhcyBnZW5lcmF0ZWQgYnkgaHR0cHM6Ly9naXRodWIuY29tL2dvb2dsZS9hcGlzLWNsaWVudC1nZW5lcmF0b3IvCiAqIChidWlsZDogMjAxOC0xMC0wOCAxNzo0NTozOSBVVEMpCiAqIG9uIDIwMjAtMDMtMTkgYXQgMDE6NTI6NDEgVVRDIAogKiBNb2RpZnkgYXQgeW91ciBvd24gcmlzay4KICovCgpwYWNrYWdlIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmlhbS52MS5tb2RlbDsKCi8qKgogKiBUaGUgc2VydmljZSBhY2NvdW50IHNpZ24gYmxvYiByZXNwb25zZS4KICoKICogPHA+IFRoaXMgaXMgdGhlIEphdmEgZGF0YSBtb2RlbCBjbGFzcyB0aGF0IHNwZWNpZmllcyBob3cgdG8gcGFyc2Uvc2VyaWFsaXplIGludG8gdGhlIEpTT04gdGhhdCBpcwogKiB0cmFuc21pdHRlZCBvdmVyIEhUVFAgd2hlbiB3b3JraW5nIHdpdGggdGhlIElkZW50aXR5IGFuZCBBY2Nlc3MgTWFuYWdlbWVudCAoSUFNKSBBUEkuIEZvciBhCiAqIGRldGFpbGVkIGV4cGxhbmF0aW9uIHNlZToKICogPGEgaHJlZj0iaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vYXBpLWNsaWVudC1saWJyYXJ5L2phdmEvZ29vZ2xlLWh0dHAtamF2YS1jbGllbnQvanNvbiI+aHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vYXBpLWNsaWVudC1saWJyYXJ5L2phdmEvZ29vZ2xlLWh0dHAtamF2YS1jbGllbnQvanNvbjwvYT4KICogPC9wPgogKgogKiBAYXV0aG9yIEdvb2dsZSwgSW5jLgogKi8KQFN1cHByZXNzV2FybmluZ3MoImphdmFkb2MiKQpwdWJsaWMgZmluYWwgY2xhc3MgU2lnbkJsb2JSZXNwb25zZSBleHRlbmRzIGNvbS5nb29nbGUuYXBpLmNsaWVudC5qc29uLkdlbmVyaWNKc29uIHsKCiAgLyoqCiAgICogVGhlIGlkIG9mIHRoZSBrZXkgdXNlZCB0byBzaWduIHRoZSBibG9iLgogICAqIFRoZSB2YWx1ZSBtYXkgYmUge0Bjb2RlIG51bGx9LgogICAqLwogIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICBwcml2YXRlIGphdmEubGFuZy5TdHJpbmcga2V5SWQ7CgogIC8qKgogICAqIFRoZSBzaWduZWQgYmxvYi4KICAgKiBUaGUgdmFsdWUgbWF5IGJlIHtAY29kZSBudWxsfS4KICAgKi8KICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgcHJpdmF0ZSBqYXZhLmxhbmcuU3RyaW5nIHNpZ25hdHVyZTsKCiAgLyoqCiAgICogVGhlIGlkIG9mIHRoZSBrZXkgdXNlZCB0byBzaWduIHRoZSBibG9iLgogICAqIEByZXR1cm4gdmFsdWUgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0S2V5SWQoKSB7CiAgICByZXR1cm4ga2V5SWQ7CiAgfQoKICAvKioKICAgKiBUaGUgaWQgb2YgdGhlIGtleSB1c2VkIHRvIHNpZ24gdGhlIGJsb2IuCiAgICogQHBhcmFtIGtleUlkIGtleUlkIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBTaWduQmxvYlJlc3BvbnNlIHNldEtleUlkKGphdmEubGFuZy5TdHJpbmcga2V5SWQpIHsKICAgIHRoaXMua2V5SWQgPSBrZXlJZDsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgLyoqCiAgICogVGhlIHNpZ25lZCBibG9iLgogICAqIEBzZWUgI2RlY29kZVNpZ25hdHVyZSgpCiAgICogQHJldHVybiB2YWx1ZSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRTaWduYXR1cmUoKSB7CiAgICByZXR1cm4gc2lnbmF0dXJlOwogIH0KCiAgLyoqCiAgICogVGhlIHNpZ25lZCBibG9iLgogICAqIEBzZWUgI2dldFNpZ25hdHVyZSgpCiAgICogQHJldHVybiBCYXNlNjQgZGVjb2RlZCB2YWx1ZSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKgogICAqIEBzaW5jZSAxLjE0CiAgICovCiAgcHVibGljIGJ5dGVbXSBkZWNvZGVTaWduYXR1cmUoKSB7CiAgICByZXR1cm4gY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuQmFzZTY0LmRlY29kZUJhc2U2NChzaWduYXR1cmUpOwogIH0KCiAgLyoqCiAgICogVGhlIHNpZ25lZCBibG9iLgogICAqIEBzZWUgI2VuY29kZVNpZ25hdHVyZSgpCiAgICogQHBhcmFtIHNpZ25hdHVyZSBzaWduYXR1cmUgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIFNpZ25CbG9iUmVzcG9uc2Ugc2V0U2lnbmF0dXJlKGphdmEubGFuZy5TdHJpbmcgc2lnbmF0dXJlKSB7CiAgICB0aGlzLnNpZ25hdHVyZSA9IHNpZ25hdHVyZTsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgLyoqCiAgICogVGhlIHNpZ25lZCBibG9iLgogICAqIEBzZWUgI3NldFNpZ25hdHVyZSgpCiAgICoKICAgKiA8cD4KICAgKiBUaGUgdmFsdWUgaXMgZW5jb2RlZCBCYXNlNjQgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lLgogICAqIDwvcD4KICAgKgogICAqIEBzaW5jZSAxLjE0CiAgICovCiAgcHVibGljIFNpZ25CbG9iUmVzcG9uc2UgZW5jb2RlU2lnbmF0dXJlKGJ5dGVbXSBzaWduYXR1cmUpIHsKICAgIHRoaXMuc2lnbmF0dXJlID0gY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuQmFzZTY0LmVuY29kZUJhc2U2NFVSTFNhZmVTdHJpbmcoc2lnbmF0dXJlKTsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgQE92ZXJyaWRlCiAgcHVibGljIFNpZ25CbG9iUmVzcG9uc2Ugc2V0KFN0cmluZyBmaWVsZE5hbWUsIE9iamVjdCB2YWx1ZSkgewogICAgcmV0dXJuIChTaWduQmxvYlJlc3BvbnNlKSBzdXBlci5zZXQoZmllbGROYW1lLCB2YWx1ZSk7CiAgfQoKICBAT3ZlcnJpZGUKICBwdWJsaWMgU2lnbkJsb2JSZXNwb25zZSBjbG9uZSgpIHsKICAgIHJldHVybiAoU2lnbkJsb2JSZXNwb25zZSkgc3VwZXIuY2xvbmUoKTsKICB9Cgp9ClBLAwQUAAAAAAAAACEA/AJCptYIAADWCAAAOAAAAGNvbS9nb29nbGUvYXBpL3NlcnZpY2VzL2lhbS92MS9tb2RlbC9TaWduSnd0UmVxdWVzdC5qYXZhLyoKICogQ29weXJpZ2h0IDIwMTAgR29vZ2xlIEluYy4KICoKICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0CiAqIGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4gWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlCiAqIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcwogKiBvciBpbXBsaWVkLiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zIHVuZGVyCiAqIHRoZSBMaWNlbnNlLgogKi8KLyoKICogVGhpcyBjb2RlIHdhcyBnZW5lcmF0ZWQgYnkgaHR0cHM6Ly9naXRodWIuY29tL2dvb2dsZS9hcGlzLWNsaWVudC1nZW5lcmF0b3IvCiAqIChidWlsZDogMjAxOC0xMC0wOCAxNzo0NTozOSBVVEMpCiAqIG9uIDIwMjAtMDMtMTkgYXQgMDE6NTI6NDEgVVRDIAogKiBNb2RpZnkgYXQgeW91ciBvd24gcmlzay4KICovCgpwYWNrYWdlIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmlhbS52MS5tb2RlbDsKCi8qKgogKiBUaGUgc2VydmljZSBhY2NvdW50IHNpZ24gSldUIHJlcXVlc3QuCiAqCiAqIDxwPiBUaGlzIGlzIHRoZSBKYXZhIGRhdGEgbW9kZWwgY2xhc3MgdGhhdCBzcGVjaWZpZXMgaG93IHRvIHBhcnNlL3NlcmlhbGl6ZSBpbnRvIHRoZSBKU09OIHRoYXQgaXMKICogdHJhbnNtaXR0ZWQgb3ZlciBIVFRQIHdoZW4gd29ya2luZyB3aXRoIHRoZSBJZGVudGl0eSBhbmQgQWNjZXNzIE1hbmFnZW1lbnQgKElBTSkgQVBJLiBGb3IgYQogKiBkZXRhaWxlZCBleHBsYW5hdGlvbiBzZWU6CiAqIDxhIGhyZWY9Imh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL2FwaS1jbGllbnQtbGlicmFyeS9qYXZhL2dvb2dsZS1odHRwLWphdmEtY2xpZW50L2pzb24iPmh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL2FwaS1jbGllbnQtbGlicmFyeS9qYXZhL2dvb2dsZS1odHRwLWphdmEtY2xpZW50L2pzb248L2E+CiAqIDwvcD4KICoKICogQGF1dGhvciBHb29nbGUsIEluYy4KICovCkBTdXBwcmVzc1dhcm5pbmdzKCJqYXZhZG9jIikKcHVibGljIGZpbmFsIGNsYXNzIFNpZ25Kd3RSZXF1ZXN0IGV4dGVuZHMgY29tLmdvb2dsZS5hcGkuY2xpZW50Lmpzb24uR2VuZXJpY0pzb24gewoKICAvKioKICAgKiBSZXF1aXJlZC4gVGhlIEpXVCBwYXlsb2FkIHRvIHNpZ24sIGEgSlNPTiBKV1QgQ2xhaW0gc2V0LgogICAqIFRoZSB2YWx1ZSBtYXkgYmUge0Bjb2RlIG51bGx9LgogICAqLwogIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICBwcml2YXRlIGphdmEubGFuZy5TdHJpbmcgcGF5bG9hZDsKCiAgLyoqCiAgICogUmVxdWlyZWQuIFRoZSBKV1QgcGF5bG9hZCB0byBzaWduLCBhIEpTT04gSldUIENsYWltIHNldC4KICAgKiBAcmV0dXJuIHZhbHVlIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFBheWxvYWQoKSB7CiAgICByZXR1cm4gcGF5bG9hZDsKICB9CgogIC8qKgogICAqIFJlcXVpcmVkLiBUaGUgSldUIHBheWxvYWQgdG8gc2lnbiwgYSBKU09OIEpXVCBDbGFpbSBzZXQuCiAgICogQHBhcmFtIHBheWxvYWQgcGF5bG9hZCBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgU2lnbkp3dFJlcXVlc3Qgc2V0UGF5bG9hZChqYXZhLmxhbmcuU3RyaW5nIHBheWxvYWQpIHsKICAgIHRoaXMucGF5bG9hZCA9IHBheWxvYWQ7CiAgICByZXR1cm4gdGhpczsKICB9CgogIEBPdmVycmlkZQogIHB1YmxpYyBTaWduSnd0UmVxdWVzdCBzZXQoU3RyaW5nIGZpZWxkTmFtZSwgT2JqZWN0IHZhbHVlKSB7CiAgICByZXR1cm4gKFNpZ25Kd3RSZXF1ZXN0KSBzdXBlci5zZXQoZmllbGROYW1lLCB2YWx1ZSk7CiAgfQoKICBAT3ZlcnJpZGUKICBwdWJsaWMgU2lnbkp3dFJlcXVlc3QgY2xvbmUoKSB7CiAgICByZXR1cm4gKFNpZ25Kd3RSZXF1ZXN0KSBzdXBlci5jbG9uZSgpOwogIH0KCn0KUEsDBBQAAAAAAAAAIQDSx4eJjQoAAI0KAAA5AAAAY29tL2dvb2dsZS9hcGkvc2VydmljZXMvaWFtL3YxL21vZGVsL1NpZ25Kd3RSZXNwb25zZS5qYXZhLyoKICogQ29weXJpZ2h0IDIwMTAgR29vZ2xlIEluYy4KICoKICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0CiAqIGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4gWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlCiAqIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcwogKiBvciBpbXBsaWVkLiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zIHVuZGVyCiAqIHRoZSBMaWNlbnNlLgogKi8KLyoKICogVGhpcyBjb2RlIHdhcyBnZW5lcmF0ZWQgYnkgaHR0cHM6Ly9naXRodWIuY29tL2dvb2dsZS9hcGlzLWNsaWVudC1nZW5lcmF0b3IvCiAqIChidWlsZDogMjAxOC0xMC0wOCAxNzo0NTozOSBVVEMpCiAqIG9uIDIwMjAtMDMtMTkgYXQgMDE6NTI6NDEgVVRDIAogKiBNb2RpZnkgYXQgeW91ciBvd24gcmlzay4KICovCgpwYWNrYWdlIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmlhbS52MS5tb2RlbDsKCi8qKgogKiBUaGUgc2VydmljZSBhY2NvdW50IHNpZ24gSldUIHJlc3BvbnNlLgogKgogKiA8cD4gVGhpcyBpcyB0aGUgSmF2YSBkYXRhIG1vZGVsIGNsYXNzIHRoYXQgc3BlY2lmaWVzIGhvdyB0byBwYXJzZS9zZXJpYWxpemUgaW50byB0aGUgSlNPTiB0aGF0IGlzCiAqIHRyYW5zbWl0dGVkIG92ZXIgSFRUUCB3aGVuIHdvcmtpbmcgd2l0aCB0aGUgSWRlbnRpdHkgYW5kIEFjY2VzcyBNYW5hZ2VtZW50IChJQU0pIEFQSS4gRm9yIGEKICogZGV0YWlsZWQgZXhwbGFuYXRpb24gc2VlOgogKiA8YSBocmVmPSJodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9hcGktY2xpZW50LWxpYnJhcnkvamF2YS9nb29nbGUtaHR0cC1qYXZhLWNsaWVudC9qc29uIj5odHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9hcGktY2xpZW50LWxpYnJhcnkvamF2YS9nb29nbGUtaHR0cC1qYXZhLWNsaWVudC9qc29uPC9hPgogKiA8L3A+CiAqCiAqIEBhdXRob3IgR29vZ2xlLCBJbmMuCiAqLwpAU3VwcHJlc3NXYXJuaW5ncygiamF2YWRvYyIpCnB1YmxpYyBmaW5hbCBjbGFzcyBTaWduSnd0UmVzcG9uc2UgZXh0ZW5kcyBjb20uZ29vZ2xlLmFwaS5jbGllbnQuanNvbi5HZW5lcmljSnNvbiB7CgogIC8qKgogICAqIFRoZSBpZCBvZiB0aGUga2V5IHVzZWQgdG8gc2lnbiB0aGUgSldULgogICAqIFRoZSB2YWx1ZSBtYXkgYmUge0Bjb2RlIG51bGx9LgogICAqLwogIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICBwcml2YXRlIGphdmEubGFuZy5TdHJpbmcga2V5SWQ7CgogIC8qKgogICAqIFRoZSBzaWduZWQgSldULgogICAqIFRoZSB2YWx1ZSBtYXkgYmUge0Bjb2RlIG51bGx9LgogICAqLwogIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICBwcml2YXRlIGphdmEubGFuZy5TdHJpbmcgc2lnbmVkSnd0OwoKICAvKioKICAgKiBUaGUgaWQgb2YgdGhlIGtleSB1c2VkIHRvIHNpZ24gdGhlIEpXVC4KICAgKiBAcmV0dXJuIHZhbHVlIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldEtleUlkKCkgewogICAgcmV0dXJuIGtleUlkOwogIH0KCiAgLyoqCiAgICogVGhlIGlkIG9mIHRoZSBrZXkgdXNlZCB0byBzaWduIHRoZSBKV1QuCiAgICogQHBhcmFtIGtleUlkIGtleUlkIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBTaWduSnd0UmVzcG9uc2Ugc2V0S2V5SWQoamF2YS5sYW5nLlN0cmluZyBrZXlJZCkgewogICAgdGhpcy5rZXlJZCA9IGtleUlkOwogICAgcmV0dXJuIHRoaXM7CiAgfQoKICAvKioKICAgKiBUaGUgc2lnbmVkIEpXVC4KICAgKiBAcmV0dXJuIHZhbHVlIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFNpZ25lZEp3dCgpIHsKICAgIHJldHVybiBzaWduZWRKd3Q7CiAgfQoKICAvKioKICAgKiBUaGUgc2lnbmVkIEpXVC4KICAgKiBAcGFyYW0gc2lnbmVkSnd0IHNpZ25lZEp3dCBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgU2lnbkp3dFJlc3BvbnNlIHNldFNpZ25lZEp3dChqYXZhLmxhbmcuU3RyaW5nIHNpZ25lZEp3dCkgewogICAgdGhpcy5zaWduZWRKd3QgPSBzaWduZWRKd3Q7CiAgICByZXR1cm4gdGhpczsKICB9CgogIEBPdmVycmlkZQogIHB1YmxpYyBTaWduSnd0UmVzcG9uc2Ugc2V0KFN0cmluZyBmaWVsZE5hbWUsIE9iamVjdCB2YWx1ZSkgewogICAgcmV0dXJuIChTaWduSnd0UmVzcG9uc2UpIHN1cGVyLnNldChmaWVsZE5hbWUsIHZhbHVlKTsKICB9CgogIEBPdmVycmlkZQogIHB1YmxpYyBTaWduSnd0UmVzcG9uc2UgY2xvbmUoKSB7CiAgICByZXR1cm4gKFNpZ25Kd3RSZXNwb25zZSkgc3VwZXIuY2xvbmUoKTsKICB9Cgp9ClBLAwQUAAAAAAAAACEAR6SVnoQLAACECwAAQwAAAGNvbS9nb29nbGUvYXBpL3NlcnZpY2VzL2lhbS92MS9tb2RlbC9UZXN0SWFtUGVybWlzc2lvbnNSZXF1ZXN0LmphdmEvKgogKiBDb3B5cmlnaHQgMjAxMCBHb29nbGUgSW5jLgogKgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQKICogaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UKICogaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzCiAqIG9yIGltcGxpZWQuIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMgdW5kZXIKICogdGhlIExpY2Vuc2UuCiAqLwovKgogKiBUaGlzIGNvZGUgd2FzIGdlbmVyYXRlZCBieSBodHRwczovL2dpdGh1Yi5jb20vZ29vZ2xlL2FwaXMtY2xpZW50LWdlbmVyYXRvci8KICogKGJ1aWxkOiAyMDE4LTEwLTA4IDE3OjQ1OjM5IFVUQykKICogb24gMjAyMC0wMy0xOSBhdCAwMTo1Mjo0MSBVVEMgCiAqIE1vZGlmeSBhdCB5b3VyIG93biByaXNrLgogKi8KCnBhY2thZ2UgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuaWFtLnYxLm1vZGVsOwoKLyoqCiAqIFJlcXVlc3QgbWVzc2FnZSBmb3IgYFRlc3RJYW1QZXJtaXNzaW9uc2AgbWV0aG9kLgogKgogKiA8cD4gVGhpcyBpcyB0aGUgSmF2YSBkYXRhIG1vZGVsIGNsYXNzIHRoYXQgc3BlY2lmaWVzIGhvdyB0byBwYXJzZS9zZXJpYWxpemUgaW50byB0aGUgSlNPTiB0aGF0IGlzCiAqIHRyYW5zbWl0dGVkIG92ZXIgSFRUUCB3aGVuIHdvcmtpbmcgd2l0aCB0aGUgSWRlbnRpdHkgYW5kIEFjY2VzcyBNYW5hZ2VtZW50IChJQU0pIEFQSS4gRm9yIGEKICogZGV0YWlsZWQgZXhwbGFuYXRpb24gc2VlOgogKiA8YSBocmVmPSJodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9hcGktY2xpZW50LWxpYnJhcnkvamF2YS9nb29nbGUtaHR0cC1qYXZhLWNsaWVudC9qc29uIj5odHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9hcGktY2xpZW50LWxpYnJhcnkvamF2YS9nb29nbGUtaHR0cC1qYXZhLWNsaWVudC9qc29uPC9hPgogKiA8L3A+CiAqCiAqIEBhdXRob3IgR29vZ2xlLCBJbmMuCiAqLwpAU3VwcHJlc3NXYXJuaW5ncygiamF2YWRvYyIpCnB1YmxpYyBmaW5hbCBjbGFzcyBUZXN0SWFtUGVybWlzc2lvbnNSZXF1ZXN0IGV4dGVuZHMgY29tLmdvb2dsZS5hcGkuY2xpZW50Lmpzb24uR2VuZXJpY0pzb24gewoKICAvKioKICAgKiBUaGUgc2V0IG9mIHBlcm1pc3Npb25zIHRvIGNoZWNrIGZvciB0aGUgYHJlc291cmNlYC4gUGVybWlzc2lvbnMgd2l0aCB3aWxkY2FyZHMgKHN1Y2ggYXMgJyonIG9yCiAgICogJ3N0b3JhZ2UuKicpIGFyZSBub3QgYWxsb3dlZC4gRm9yIG1vcmUgaW5mb3JtYXRpb24gc2VlIFtJQU0KICAgKiBPdmVydmlld10oaHR0cHM6Ly9jbG91ZC5nb29nbGUuY29tL2lhbS9kb2NzL292ZXJ2aWV3I3Blcm1pc3Npb25zKS4KICAgKiBUaGUgdmFsdWUgbWF5IGJlIHtAY29kZSBudWxsfS4KICAgKi8KICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuU3RyaW5nPiBwZXJtaXNzaW9uczsKCiAgLyoqCiAgICogVGhlIHNldCBvZiBwZXJtaXNzaW9ucyB0byBjaGVjayBmb3IgdGhlIGByZXNvdXJjZWAuIFBlcm1pc3Npb25zIHdpdGggd2lsZGNhcmRzIChzdWNoIGFzICcqJyBvcgogICAqICdzdG9yYWdlLionKSBhcmUgbm90IGFsbG93ZWQuIEZvciBtb3JlIGluZm9ybWF0aW9uIHNlZSBbSUFNCiAgICogT3ZlcnZpZXddKGh0dHBzOi8vY2xvdWQuZ29vZ2xlLmNvbS9pYW0vZG9jcy9vdmVydmlldyNwZXJtaXNzaW9ucykuCiAgICogQHJldHVybiB2YWx1ZSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLlN0cmluZz4gZ2V0UGVybWlzc2lvbnMoKSB7CiAgICByZXR1cm4gcGVybWlzc2lvbnM7CiAgfQoKICAvKioKICAgKiBUaGUgc2V0IG9mIHBlcm1pc3Npb25zIHRvIGNoZWNrIGZvciB0aGUgYHJlc291cmNlYC4gUGVybWlzc2lvbnMgd2l0aCB3aWxkY2FyZHMgKHN1Y2ggYXMgJyonIG9yCiAgICogJ3N0b3JhZ2UuKicpIGFyZSBub3QgYWxsb3dlZC4gRm9yIG1vcmUgaW5mb3JtYXRpb24gc2VlIFtJQU0KICAgKiBPdmVydmlld10oaHR0cHM6Ly9jbG91ZC5nb29nbGUuY29tL2lhbS9kb2NzL292ZXJ2aWV3I3Blcm1pc3Npb25zKS4KICAgKiBAcGFyYW0gcGVybWlzc2lvbnMgcGVybWlzc2lvbnMgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIFRlc3RJYW1QZXJtaXNzaW9uc1JlcXVlc3Qgc2V0UGVybWlzc2lvbnMoamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLlN0cmluZz4gcGVybWlzc2lvbnMpIHsKICAgIHRoaXMucGVybWlzc2lvbnMgPSBwZXJtaXNzaW9uczsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgQE92ZXJyaWRlCiAgcHVibGljIFRlc3RJYW1QZXJtaXNzaW9uc1JlcXVlc3Qgc2V0KFN0cmluZyBmaWVsZE5hbWUsIE9iamVjdCB2YWx1ZSkgewogICAgcmV0dXJuIChUZXN0SWFtUGVybWlzc2lvbnNSZXF1ZXN0KSBzdXBlci5zZXQoZmllbGROYW1lLCB2YWx1ZSk7CiAgfQoKICBAT3ZlcnJpZGUKICBwdWJsaWMgVGVzdElhbVBlcm1pc3Npb25zUmVxdWVzdCBjbG9uZSgpIHsKICAgIHJldHVybiAoVGVzdElhbVBlcm1pc3Npb25zUmVxdWVzdCkgc3VwZXIuY2xvbmUoKTsKICB9Cgp9ClBLAwQUAAAAAAAAACEAijQub7oJAAC6CQAARAAAAGNvbS9nb29nbGUvYXBpL3NlcnZpY2VzL2lhbS92MS9tb2RlbC9UZXN0SWFtUGVybWlzc2lvbnNSZXNwb25zZS5qYXZhLyoKICogQ29weXJpZ2h0IDIwMTAgR29vZ2xlIEluYy4KICoKICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0CiAqIGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4gWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlCiAqIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcwogKiBvciBpbXBsaWVkLiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zIHVuZGVyCiAqIHRoZSBMaWNlbnNlLgogKi8KLyoKICogVGhpcyBjb2RlIHdhcyBnZW5lcmF0ZWQgYnkgaHR0cHM6Ly9naXRodWIuY29tL2dvb2dsZS9hcGlzLWNsaWVudC1nZW5lcmF0b3IvCiAqIChidWlsZDogMjAxOC0xMC0wOCAxNzo0NTozOSBVVEMpCiAqIG9uIDIwMjAtMDMtMTkgYXQgMDE6NTI6NDEgVVRDIAogKiBNb2RpZnkgYXQgeW91ciBvd24gcmlzay4KICovCgpwYWNrYWdlIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmlhbS52MS5tb2RlbDsKCi8qKgogKiBSZXNwb25zZSBtZXNzYWdlIGZvciBgVGVzdElhbVBlcm1pc3Npb25zYCBtZXRob2QuCiAqCiAqIDxwPiBUaGlzIGlzIHRoZSBKYXZhIGRhdGEgbW9kZWwgY2xhc3MgdGhhdCBzcGVjaWZpZXMgaG93IHRvIHBhcnNlL3NlcmlhbGl6ZSBpbnRvIHRoZSBKU09OIHRoYXQgaXMKICogdHJhbnNtaXR0ZWQgb3ZlciBIVFRQIHdoZW4gd29ya2luZyB3aXRoIHRoZSBJZGVudGl0eSBhbmQgQWNjZXNzIE1hbmFnZW1lbnQgKElBTSkgQVBJLiBGb3IgYQogKiBkZXRhaWxlZCBleHBsYW5hdGlvbiBzZWU6CiAqIDxhIGhyZWY9Imh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL2FwaS1jbGllbnQtbGlicmFyeS9qYXZhL2dvb2dsZS1odHRwLWphdmEtY2xpZW50L2pzb24iPmh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL2FwaS1jbGllbnQtbGlicmFyeS9qYXZhL2dvb2dsZS1odHRwLWphdmEtY2xpZW50L2pzb248L2E+CiAqIDwvcD4KICoKICogQGF1dGhvciBHb29nbGUsIEluYy4KICovCkBTdXBwcmVzc1dhcm5pbmdzKCJqYXZhZG9jIikKcHVibGljIGZpbmFsIGNsYXNzIFRlc3RJYW1QZXJtaXNzaW9uc1Jlc3BvbnNlIGV4dGVuZHMgY29tLmdvb2dsZS5hcGkuY2xpZW50Lmpzb24uR2VuZXJpY0pzb24gewoKICAvKioKICAgKiBBIHN1YnNldCBvZiBgVGVzdFBlcm1pc3Npb25zUmVxdWVzdC5wZXJtaXNzaW9uc2AgdGhhdCB0aGUgY2FsbGVyIGlzIGFsbG93ZWQuCiAgICogVGhlIHZhbHVlIG1heSBiZSB7QGNvZGUgbnVsbH0uCiAgICovCiAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLlN0cmluZz4gcGVybWlzc2lvbnM7CgogIC8qKgogICAqIEEgc3Vic2V0IG9mIGBUZXN0UGVybWlzc2lvbnNSZXF1ZXN0LnBlcm1pc3Npb25zYCB0aGF0IHRoZSBjYWxsZXIgaXMgYWxsb3dlZC4KICAgKiBAcmV0dXJuIHZhbHVlIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuU3RyaW5nPiBnZXRQZXJtaXNzaW9ucygpIHsKICAgIHJldHVybiBwZXJtaXNzaW9uczsKICB9CgogIC8qKgogICAqIEEgc3Vic2V0IG9mIGBUZXN0UGVybWlzc2lvbnNSZXF1ZXN0LnBlcm1pc3Npb25zYCB0aGF0IHRoZSBjYWxsZXIgaXMgYWxsb3dlZC4KICAgKiBAcGFyYW0gcGVybWlzc2lvbnMgcGVybWlzc2lvbnMgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIFRlc3RJYW1QZXJtaXNzaW9uc1Jlc3BvbnNlIHNldFBlcm1pc3Npb25zKGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5TdHJpbmc+IHBlcm1pc3Npb25zKSB7CiAgICB0aGlzLnBlcm1pc3Npb25zID0gcGVybWlzc2lvbnM7CiAgICByZXR1cm4gdGhpczsKICB9CgogIEBPdmVycmlkZQogIHB1YmxpYyBUZXN0SWFtUGVybWlzc2lvbnNSZXNwb25zZSBzZXQoU3RyaW5nIGZpZWxkTmFtZSwgT2JqZWN0IHZhbHVlKSB7CiAgICByZXR1cm4gKFRlc3RJYW1QZXJtaXNzaW9uc1Jlc3BvbnNlKSBzdXBlci5zZXQoZmllbGROYW1lLCB2YWx1ZSk7CiAgfQoKICBAT3ZlcnJpZGUKICBwdWJsaWMgVGVzdElhbVBlcm1pc3Npb25zUmVzcG9uc2UgY2xvbmUoKSB7CiAgICByZXR1cm4gKFRlc3RJYW1QZXJtaXNzaW9uc1Jlc3BvbnNlKSBzdXBlci5jbG9uZSgpOwogIH0KCn0KUEsDBBQAAAAAAAAAIQCqb1d5XQsAAF0LAAA9AAAAY29tL2dvb2dsZS9hcGkvc2VydmljZXMvaWFtL3YxL21vZGVsL1VuZGVsZXRlUm9sZVJlcXVlc3QuamF2YS8qCiAqIENvcHlyaWdodCAyMDEwIEdvb2dsZSBJbmMuCiAqCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdAogKiBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZQogKiBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3MKICogb3IgaW1wbGllZC4gU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucyB1bmRlcgogKiB0aGUgTGljZW5zZS4KICovCi8qCiAqIFRoaXMgY29kZSB3YXMgZ2VuZXJhdGVkIGJ5IGh0dHBzOi8vZ2l0aHViLmNvbS9nb29nbGUvYXBpcy1jbGllbnQtZ2VuZXJhdG9yLwogKiAoYnVpbGQ6IDIwMTgtMTAtMDggMTc6NDU6MzkgVVRDKQogKiBvbiAyMDIwLTAzLTE5IGF0IDAxOjUyOjQxIFVUQyAKICogTW9kaWZ5IGF0IHlvdXIgb3duIHJpc2suCiAqLwoKcGFja2FnZSBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5pYW0udjEubW9kZWw7CgovKioKICogVGhlIHJlcXVlc3QgdG8gdW5kZWxldGUgYW4gZXhpc3Rpbmcgcm9sZS4KICoKICogPHA+IFRoaXMgaXMgdGhlIEphdmEgZGF0YSBtb2RlbCBjbGFzcyB0aGF0IHNwZWNpZmllcyBob3cgdG8gcGFyc2Uvc2VyaWFsaXplIGludG8gdGhlIEpTT04gdGhhdCBpcwogKiB0cmFuc21pdHRlZCBvdmVyIEhUVFAgd2hlbiB3b3JraW5nIHdpdGggdGhlIElkZW50aXR5IGFuZCBBY2Nlc3MgTWFuYWdlbWVudCAoSUFNKSBBUEkuIEZvciBhCiAqIGRldGFpbGVkIGV4cGxhbmF0aW9uIHNlZToKICogPGEgaHJlZj0iaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vYXBpLWNsaWVudC1saWJyYXJ5L2phdmEvZ29vZ2xlLWh0dHAtamF2YS1jbGllbnQvanNvbiI+aHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vYXBpLWNsaWVudC1saWJyYXJ5L2phdmEvZ29vZ2xlLWh0dHAtamF2YS1jbGllbnQvanNvbjwvYT4KICogPC9wPgogKgogKiBAYXV0aG9yIEdvb2dsZSwgSW5jLgogKi8KQFN1cHByZXNzV2FybmluZ3MoImphdmFkb2MiKQpwdWJsaWMgZmluYWwgY2xhc3MgVW5kZWxldGVSb2xlUmVxdWVzdCBleHRlbmRzIGNvbS5nb29nbGUuYXBpLmNsaWVudC5qc29uLkdlbmVyaWNKc29uIHsKCiAgLyoqCiAgICogVXNlZCB0byBwZXJmb3JtIGEgY29uc2lzdGVudCByZWFkLW1vZGlmeS13cml0ZS4KICAgKiBUaGUgdmFsdWUgbWF5IGJlIHtAY29kZSBudWxsfS4KICAgKi8KICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgcHJpdmF0ZSBqYXZhLmxhbmcuU3RyaW5nIGV0YWc7CgogIC8qKgogICAqIFVzZWQgdG8gcGVyZm9ybSBhIGNvbnNpc3RlbnQgcmVhZC1tb2RpZnktd3JpdGUuCiAgICogQHNlZSAjZGVjb2RlRXRhZygpCiAgICogQHJldHVybiB2YWx1ZSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRFdGFnKCkgewogICAgcmV0dXJuIGV0YWc7CiAgfQoKICAvKioKICAgKiBVc2VkIHRvIHBlcmZvcm0gYSBjb25zaXN0ZW50IHJlYWQtbW9kaWZ5LXdyaXRlLgogICAqIEBzZWUgI2dldEV0YWcoKQogICAqIEByZXR1cm4gQmFzZTY0IGRlY29kZWQgdmFsdWUgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICoKICAgKiBAc2luY2UgMS4xNAogICAqLwogIHB1YmxpYyBieXRlW10gZGVjb2RlRXRhZygpIHsKICAgIHJldHVybiBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5CYXNlNjQuZGVjb2RlQmFzZTY0KGV0YWcpOwogIH0KCiAgLyoqCiAgICogVXNlZCB0byBwZXJmb3JtIGEgY29uc2lzdGVudCByZWFkLW1vZGlmeS13cml0ZS4KICAgKiBAc2VlICNlbmNvZGVFdGFnKCkKICAgKiBAcGFyYW0gZXRhZyBldGFnIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBVbmRlbGV0ZVJvbGVSZXF1ZXN0IHNldEV0YWcoamF2YS5sYW5nLlN0cmluZyBldGFnKSB7CiAgICB0aGlzLmV0YWcgPSBldGFnOwogICAgcmV0dXJuIHRoaXM7CiAgfQoKICAvKioKICAgKiBVc2VkIHRvIHBlcmZvcm0gYSBjb25zaXN0ZW50IHJlYWQtbW9kaWZ5LXdyaXRlLgogICAqIEBzZWUgI3NldEV0YWcoKQogICAqCiAgICogPHA+CiAgICogVGhlIHZhbHVlIGlzIGVuY29kZWQgQmFzZTY0IG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZS4KICAgKiA8L3A+CiAgICoKICAgKiBAc2luY2UgMS4xNAogICAqLwogIHB1YmxpYyBVbmRlbGV0ZVJvbGVSZXF1ZXN0IGVuY29kZUV0YWcoYnl0ZVtdIGV0YWcpIHsKICAgIHRoaXMuZXRhZyA9IGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLkJhc2U2NC5lbmNvZGVCYXNlNjRVUkxTYWZlU3RyaW5nKGV0YWcpOwogICAgcmV0dXJuIHRoaXM7CiAgfQoKICBAT3ZlcnJpZGUKICBwdWJsaWMgVW5kZWxldGVSb2xlUmVxdWVzdCBzZXQoU3RyaW5nIGZpZWxkTmFtZSwgT2JqZWN0IHZhbHVlKSB7CiAgICByZXR1cm4gKFVuZGVsZXRlUm9sZVJlcXVlc3QpIHN1cGVyLnNldChmaWVsZE5hbWUsIHZhbHVlKTsKICB9CgogIEBPdmVycmlkZQogIHB1YmxpYyBVbmRlbGV0ZVJvbGVSZXF1ZXN0IGNsb25lKCkgewogICAgcmV0dXJuIChVbmRlbGV0ZVJvbGVSZXF1ZXN0KSBzdXBlci5jbG9uZSgpOwogIH0KCn0KUEsDBBQAAAAAAAAAIQDqLN2HxAYAAMQGAABHAAAAY29tL2dvb2dsZS9hcGkvc2VydmljZXMvaWFtL3YxL21vZGVsL1VuZGVsZXRlU2VydmljZUFjY291bnRSZXF1ZXN0LmphdmEvKgogKiBDb3B5cmlnaHQgMjAxMCBHb29nbGUgSW5jLgogKgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQKICogaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UKICogaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzCiAqIG9yIGltcGxpZWQuIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMgdW5kZXIKICogdGhlIExpY2Vuc2UuCiAqLwovKgogKiBUaGlzIGNvZGUgd2FzIGdlbmVyYXRlZCBieSBodHRwczovL2dpdGh1Yi5jb20vZ29vZ2xlL2FwaXMtY2xpZW50LWdlbmVyYXRvci8KICogKGJ1aWxkOiAyMDE4LTEwLTA4IDE3OjQ1OjM5IFVUQykKICogb24gMjAyMC0wMy0xOSBhdCAwMTo1Mjo0MSBVVEMgCiAqIE1vZGlmeSBhdCB5b3VyIG93biByaXNrLgogKi8KCnBhY2thZ2UgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuaWFtLnYxLm1vZGVsOwoKLyoqCiAqIFRoZSBzZXJ2aWNlIGFjY291bnQgdW5kZWxldGUgcmVxdWVzdC4KICoKICogPHA+IFRoaXMgaXMgdGhlIEphdmEgZGF0YSBtb2RlbCBjbGFzcyB0aGF0IHNwZWNpZmllcyBob3cgdG8gcGFyc2Uvc2VyaWFsaXplIGludG8gdGhlIEpTT04gdGhhdCBpcwogKiB0cmFuc21pdHRlZCBvdmVyIEhUVFAgd2hlbiB3b3JraW5nIHdpdGggdGhlIElkZW50aXR5IGFuZCBBY2Nlc3MgTWFuYWdlbWVudCAoSUFNKSBBUEkuIEZvciBhCiAqIGRldGFpbGVkIGV4cGxhbmF0aW9uIHNlZToKICogPGEgaHJlZj0iaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vYXBpLWNsaWVudC1saWJyYXJ5L2phdmEvZ29vZ2xlLWh0dHAtamF2YS1jbGllbnQvanNvbiI+aHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vYXBpLWNsaWVudC1saWJyYXJ5L2phdmEvZ29vZ2xlLWh0dHAtamF2YS1jbGllbnQvanNvbjwvYT4KICogPC9wPgogKgogKiBAYXV0aG9yIEdvb2dsZSwgSW5jLgogKi8KQFN1cHByZXNzV2FybmluZ3MoImphdmFkb2MiKQpwdWJsaWMgZmluYWwgY2xhc3MgVW5kZWxldGVTZXJ2aWNlQWNjb3VudFJlcXVlc3QgZXh0ZW5kcyBjb20uZ29vZ2xlLmFwaS5jbGllbnQuanNvbi5HZW5lcmljSnNvbiB7CgogIEBPdmVycmlkZQogIHB1YmxpYyBVbmRlbGV0ZVNlcnZpY2VBY2NvdW50UmVxdWVzdCBzZXQoU3RyaW5nIGZpZWxkTmFtZSwgT2JqZWN0IHZhbHVlKSB7CiAgICByZXR1cm4gKFVuZGVsZXRlU2VydmljZUFjY291bnRSZXF1ZXN0KSBzdXBlci5zZXQoZmllbGROYW1lLCB2YWx1ZSk7CiAgfQoKICBAT3ZlcnJpZGUKICBwdWJsaWMgVW5kZWxldGVTZXJ2aWNlQWNjb3VudFJlcXVlc3QgY2xvbmUoKSB7CiAgICByZXR1cm4gKFVuZGVsZXRlU2VydmljZUFjY291bnRSZXF1ZXN0KSBzdXBlci5jbG9uZSgpOwogIH0KCn0KUEsDBBQAAAAAAAAAIQC+X37SXQkAAF0JAABIAAAAY29tL2dvb2dsZS9hcGkvc2VydmljZXMvaWFtL3YxL21vZGVsL1VuZGVsZXRlU2VydmljZUFjY291bnRSZXNwb25zZS5qYXZhLyoKICogQ29weXJpZ2h0IDIwMTAgR29vZ2xlIEluYy4KICoKICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0CiAqIGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4gWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlCiAqIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcwogKiBvciBpbXBsaWVkLiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zIHVuZGVyCiAqIHRoZSBMaWNlbnNlLgogKi8KLyoKICogVGhpcyBjb2RlIHdhcyBnZW5lcmF0ZWQgYnkgaHR0cHM6Ly9naXRodWIuY29tL2dvb2dsZS9hcGlzLWNsaWVudC1nZW5lcmF0b3IvCiAqIChidWlsZDogMjAxOC0xMC0wOCAxNzo0NTozOSBVVEMpCiAqIG9uIDIwMjAtMDMtMTkgYXQgMDE6NTI6NDEgVVRDIAogKiBNb2RpZnkgYXQgeW91ciBvd24gcmlzay4KICovCgpwYWNrYWdlIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmlhbS52MS5tb2RlbDsKCi8qKgogKiBNb2RlbCBkZWZpbml0aW9uIGZvciBVbmRlbGV0ZVNlcnZpY2VBY2NvdW50UmVzcG9uc2UuCiAqCiAqIDxwPiBUaGlzIGlzIHRoZSBKYXZhIGRhdGEgbW9kZWwgY2xhc3MgdGhhdCBzcGVjaWZpZXMgaG93IHRvIHBhcnNlL3NlcmlhbGl6ZSBpbnRvIHRoZSBKU09OIHRoYXQgaXMKICogdHJhbnNtaXR0ZWQgb3ZlciBIVFRQIHdoZW4gd29ya2luZyB3aXRoIHRoZSBJZGVudGl0eSBhbmQgQWNjZXNzIE1hbmFnZW1lbnQgKElBTSkgQVBJLiBGb3IgYQogKiBkZXRhaWxlZCBleHBsYW5hdGlvbiBzZWU6CiAqIDxhIGhyZWY9Imh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL2FwaS1jbGllbnQtbGlicmFyeS9qYXZhL2dvb2dsZS1odHRwLWphdmEtY2xpZW50L2pzb24iPmh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL2FwaS1jbGllbnQtbGlicmFyeS9qYXZhL2dvb2dsZS1odHRwLWphdmEtY2xpZW50L2pzb248L2E+CiAqIDwvcD4KICoKICogQGF1dGhvciBHb29nbGUsIEluYy4KICovCkBTdXBwcmVzc1dhcm5pbmdzKCJqYXZhZG9jIikKcHVibGljIGZpbmFsIGNsYXNzIFVuZGVsZXRlU2VydmljZUFjY291bnRSZXNwb25zZSBleHRlbmRzIGNvbS5nb29nbGUuYXBpLmNsaWVudC5qc29uLkdlbmVyaWNKc29uIHsKCiAgLyoqCiAgICogTWV0YWRhdGEgZm9yIHRoZSByZXN0b3JlZCBzZXJ2aWNlIGFjY291bnQuCiAgICogVGhlIHZhbHVlIG1heSBiZSB7QGNvZGUgbnVsbH0uCiAgICovCiAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogIHByaXZhdGUgU2VydmljZUFjY291bnQgcmVzdG9yZWRBY2NvdW50OwoKICAvKioKICAgKiBNZXRhZGF0YSBmb3IgdGhlIHJlc3RvcmVkIHNlcnZpY2UgYWNjb3VudC4KICAgKiBAcmV0dXJuIHZhbHVlIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBTZXJ2aWNlQWNjb3VudCBnZXRSZXN0b3JlZEFjY291bnQoKSB7CiAgICByZXR1cm4gcmVzdG9yZWRBY2NvdW50OwogIH0KCiAgLyoqCiAgICogTWV0YWRhdGEgZm9yIHRoZSByZXN0b3JlZCBzZXJ2aWNlIGFjY291bnQuCiAgICogQHBhcmFtIHJlc3RvcmVkQWNjb3VudCByZXN0b3JlZEFjY291bnQgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIFVuZGVsZXRlU2VydmljZUFjY291bnRSZXNwb25zZSBzZXRSZXN0b3JlZEFjY291bnQoU2VydmljZUFjY291bnQgcmVzdG9yZWRBY2NvdW50KSB7CiAgICB0aGlzLnJlc3RvcmVkQWNjb3VudCA9IHJlc3RvcmVkQWNjb3VudDsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgQE92ZXJyaWRlCiAgcHVibGljIFVuZGVsZXRlU2VydmljZUFjY291bnRSZXNwb25zZSBzZXQoU3RyaW5nIGZpZWxkTmFtZSwgT2JqZWN0IHZhbHVlKSB7CiAgICByZXR1cm4gKFVuZGVsZXRlU2VydmljZUFjY291bnRSZXNwb25zZSkgc3VwZXIuc2V0KGZpZWxkTmFtZSwgdmFsdWUpOwogIH0KCiAgQE92ZXJyaWRlCiAgcHVibGljIFVuZGVsZXRlU2VydmljZUFjY291bnRSZXNwb25zZSBjbG9uZSgpIHsKICAgIHJldHVybiAoVW5kZWxldGVTZXJ2aWNlQWNjb3VudFJlc3BvbnNlKSBzdXBlci5jbG9uZSgpOwogIH0KCn0KUEsDBBQAAAAAAAAAIQDsa176vg8AAL4PAABIAAAAY29tL2dvb2dsZS9hcGkvc2VydmljZXMvaWFtL3YxL21vZGVsL1VwbG9hZFNlcnZpY2VBY2NvdW50S2V5UmVxdWVzdC5qYXZhLyoKICogQ29weXJpZ2h0IDIwMTAgR29vZ2xlIEluYy4KICoKICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0CiAqIGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4gWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlCiAqIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcwogKiBvciBpbXBsaWVkLiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zIHVuZGVyCiAqIHRoZSBMaWNlbnNlLgogKi8KLyoKICogVGhpcyBjb2RlIHdhcyBnZW5lcmF0ZWQgYnkgaHR0cHM6Ly9naXRodWIuY29tL2dvb2dsZS9hcGlzLWNsaWVudC1nZW5lcmF0b3IvCiAqIChidWlsZDogMjAxOC0xMC0wOCAxNzo0NTozOSBVVEMpCiAqIG9uIDIwMjAtMDMtMTkgYXQgMDE6NTI6NDEgVVRDIAogKiBNb2RpZnkgYXQgeW91ciBvd24gcmlzay4KICovCgpwYWNrYWdlIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmlhbS52MS5tb2RlbDsKCi8qKgogKiBUaGUgc2VydmljZSBhY2NvdW50IGtleSB1cGxvYWQgcmVxdWVzdC4KICoKICogPHA+IFRoaXMgaXMgdGhlIEphdmEgZGF0YSBtb2RlbCBjbGFzcyB0aGF0IHNwZWNpZmllcyBob3cgdG8gcGFyc2Uvc2VyaWFsaXplIGludG8gdGhlIEpTT04gdGhhdCBpcwogKiB0cmFuc21pdHRlZCBvdmVyIEhUVFAgd2hlbiB3b3JraW5nIHdpdGggdGhlIElkZW50aXR5IGFuZCBBY2Nlc3MgTWFuYWdlbWVudCAoSUFNKSBBUEkuIEZvciBhCiAqIGRldGFpbGVkIGV4cGxhbmF0aW9uIHNlZToKICogPGEgaHJlZj0iaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vYXBpLWNsaWVudC1saWJyYXJ5L2phdmEvZ29vZ2xlLWh0dHAtamF2YS1jbGllbnQvanNvbiI+aHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vYXBpLWNsaWVudC1saWJyYXJ5L2phdmEvZ29vZ2xlLWh0dHAtamF2YS1jbGllbnQvanNvbjwvYT4KICogPC9wPgogKgogKiBAYXV0aG9yIEdvb2dsZSwgSW5jLgogKi8KQFN1cHByZXNzV2FybmluZ3MoImphdmFkb2MiKQpwdWJsaWMgZmluYWwgY2xhc3MgVXBsb2FkU2VydmljZUFjY291bnRLZXlSZXF1ZXN0IGV4dGVuZHMgY29tLmdvb2dsZS5hcGkuY2xpZW50Lmpzb24uR2VuZXJpY0pzb24gewoKICAvKioKICAgKiBBIGZpZWxkIHRoYXQgYWxsb3dzIGNsaWVudHMgdG8gdXBsb2FkIHRoZWlyIG93biBwdWJsaWMga2V5LiBJZiBzZXQsIHVzZSB0aGlzIHB1YmxpYyBrZXkgZGF0YSB0bwogICAqIGNyZWF0ZSBhIHNlcnZpY2UgYWNjb3VudCBrZXkgZm9yIGdpdmVuIHNlcnZpY2UgYWNjb3VudC4gUGxlYXNlIG5vdGUsIHRoZSBleHBlY3RlZCBmb3JtYXQgZm9yCiAgICogdGhpcyBmaWVsZCBpcyBYNTA5X1BFTS4KICAgKiBUaGUgdmFsdWUgbWF5IGJlIHtAY29kZSBudWxsfS4KICAgKi8KICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgcHJpdmF0ZSBqYXZhLmxhbmcuU3RyaW5nIHB1YmxpY0tleURhdGE7CgogIC8qKgogICAqIEEgZmllbGQgdGhhdCBhbGxvd3MgY2xpZW50cyB0byB1cGxvYWQgdGhlaXIgb3duIHB1YmxpYyBrZXkuIElmIHNldCwgdXNlIHRoaXMgcHVibGljIGtleSBkYXRhIHRvCiAgICogY3JlYXRlIGEgc2VydmljZSBhY2NvdW50IGtleSBmb3IgZ2l2ZW4gc2VydmljZSBhY2NvdW50LiBQbGVhc2Ugbm90ZSwgdGhlIGV4cGVjdGVkIGZvcm1hdCBmb3IKICAgKiB0aGlzIGZpZWxkIGlzIFg1MDlfUEVNLgogICAqIEBzZWUgI2RlY29kZVB1YmxpY0tleURhdGEoKQogICAqIEByZXR1cm4gdmFsdWUgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0UHVibGljS2V5RGF0YSgpIHsKICAgIHJldHVybiBwdWJsaWNLZXlEYXRhOwogIH0KCiAgLyoqCiAgICogQSBmaWVsZCB0aGF0IGFsbG93cyBjbGllbnRzIHRvIHVwbG9hZCB0aGVpciBvd24gcHVibGljIGtleS4gSWYgc2V0LCB1c2UgdGhpcyBwdWJsaWMga2V5IGRhdGEgdG8KICAgKiBjcmVhdGUgYSBzZXJ2aWNlIGFjY291bnQga2V5IGZvciBnaXZlbiBzZXJ2aWNlIGFjY291bnQuIFBsZWFzZSBub3RlLCB0aGUgZXhwZWN0ZWQgZm9ybWF0IGZvcgogICAqIHRoaXMgZmllbGQgaXMgWDUwOV9QRU0uCiAgICogQHNlZSAjZ2V0UHVibGljS2V5RGF0YSgpCiAgICogQHJldHVybiBCYXNlNjQgZGVjb2RlZCB2YWx1ZSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKgogICAqIEBzaW5jZSAxLjE0CiAgICovCiAgcHVibGljIGJ5dGVbXSBkZWNvZGVQdWJsaWNLZXlEYXRhKCkgewogICAgcmV0dXJuIGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLkJhc2U2NC5kZWNvZGVCYXNlNjQocHVibGljS2V5RGF0YSk7CiAgfQoKICAvKioKICAgKiBBIGZpZWxkIHRoYXQgYWxsb3dzIGNsaWVudHMgdG8gdXBsb2FkIHRoZWlyIG93biBwdWJsaWMga2V5LiBJZiBzZXQsIHVzZSB0aGlzIHB1YmxpYyBrZXkgZGF0YSB0bwogICAqIGNyZWF0ZSBhIHNlcnZpY2UgYWNjb3VudCBrZXkgZm9yIGdpdmVuIHNlcnZpY2UgYWNjb3VudC4gUGxlYXNlIG5vdGUsIHRoZSBleHBlY3RlZCBmb3JtYXQgZm9yCiAgICogdGhpcyBmaWVsZCBpcyBYNTA5X1BFTS4KICAgKiBAc2VlICNlbmNvZGVQdWJsaWNLZXlEYXRhKCkKICAgKiBAcGFyYW0gcHVibGljS2V5RGF0YSBwdWJsaWNLZXlEYXRhIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBVcGxvYWRTZXJ2aWNlQWNjb3VudEtleVJlcXVlc3Qgc2V0UHVibGljS2V5RGF0YShqYXZhLmxhbmcuU3RyaW5nIHB1YmxpY0tleURhdGEpIHsKICAgIHRoaXMucHVibGljS2V5RGF0YSA9IHB1YmxpY0tleURhdGE7CiAgICByZXR1cm4gdGhpczsKICB9CgogIC8qKgogICAqIEEgZmllbGQgdGhhdCBhbGxvd3MgY2xpZW50cyB0byB1cGxvYWQgdGhlaXIgb3duIHB1YmxpYyBrZXkuIElmIHNldCwgdXNlIHRoaXMgcHVibGljIGtleSBkYXRhIHRvCiAgICogY3JlYXRlIGEgc2VydmljZSBhY2NvdW50IGtleSBmb3IgZ2l2ZW4gc2VydmljZSBhY2NvdW50LiBQbGVhc2Ugbm90ZSwgdGhlIGV4cGVjdGVkIGZvcm1hdCBmb3IKICAgKiB0aGlzIGZpZWxkIGlzIFg1MDlfUEVNLgogICAqIEBzZWUgI3NldFB1YmxpY0tleURhdGEoKQogICAqCiAgICogPHA+CiAgICogVGhlIHZhbHVlIGlzIGVuY29kZWQgQmFzZTY0IG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZS4KICAgKiA8L3A+CiAgICoKICAgKiBAc2luY2UgMS4xNAogICAqLwogIHB1YmxpYyBVcGxvYWRTZXJ2aWNlQWNjb3VudEtleVJlcXVlc3QgZW5jb2RlUHVibGljS2V5RGF0YShieXRlW10gcHVibGljS2V5RGF0YSkgewogICAgdGhpcy5wdWJsaWNLZXlEYXRhID0gY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuQmFzZTY0LmVuY29kZUJhc2U2NFVSTFNhZmVTdHJpbmcocHVibGljS2V5RGF0YSk7CiAgICByZXR1cm4gdGhpczsKICB9CgogIEBPdmVycmlkZQogIHB1YmxpYyBVcGxvYWRTZXJ2aWNlQWNjb3VudEtleVJlcXVlc3Qgc2V0KFN0cmluZyBmaWVsZE5hbWUsIE9iamVjdCB2YWx1ZSkgewogICAgcmV0dXJuIChVcGxvYWRTZXJ2aWNlQWNjb3VudEtleVJlcXVlc3QpIHN1cGVyLnNldChmaWVsZE5hbWUsIHZhbHVlKTsKICB9CgogIEBPdmVycmlkZQogIHB1YmxpYyBVcGxvYWRTZXJ2aWNlQWNjb3VudEtleVJlcXVlc3QgY2xvbmUoKSB7CiAgICByZXR1cm4gKFVwbG9hZFNlcnZpY2VBY2NvdW50S2V5UmVxdWVzdCkgc3VwZXIuY2xvbmUoKTsKICB9Cgp9ClBLAwQUAAAAAAAAACEAtoUfS1UNAABVDQAAOQAAAGNvbS9nb29nbGUvYXBpL3NlcnZpY2VzL2lhbS92MS9JYW1SZXF1ZXN0SW5pdGlhbGl6ZXIuamF2YS8qCiAqIENvcHlyaWdodCAyMDEwIEdvb2dsZSBJbmMuCiAqCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdAogKiBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZQogKiBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3MKICogb3IgaW1wbGllZC4gU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucyB1bmRlcgogKiB0aGUgTGljZW5zZS4KICovCi8qCiAqIFRoaXMgY29kZSB3YXMgZ2VuZXJhdGVkIGJ5IGh0dHBzOi8vZ2l0aHViLmNvbS9nb29nbGUvYXBpcy1jbGllbnQtZ2VuZXJhdG9yLwogKiAoYnVpbGQ6IDIwMTgtMTAtMDggMTc6NDU6MzkgVVRDKQogKiBvbiAyMDIwLTAzLTE5IGF0IDAxOjUyOjQxIFVUQyAKICogTW9kaWZ5IGF0IHlvdXIgb3duIHJpc2suCiAqLwoKcGFja2FnZSBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5pYW0udjE7CgovKioKICogSWFtIHJlcXVlc3QgaW5pdGlhbGl6ZXIgZm9yIHNldHRpbmcgcHJvcGVydGllcyBsaWtlIGtleSBhbmQgdXNlcklwLgogKgogKiA8cD4KICogVGhlIHNpbXBsZXN0IHVzYWdlIGlzIHRvIHVzZSBpdCB0byBzZXQgdGhlIGtleSBwYXJhbWV0ZXI6CiAqIDwvcD4KICoKICogPHByZT4KICBwdWJsaWMgc3RhdGljIGZpbmFsIEdvb2dsZUNsaWVudFJlcXVlc3RJbml0aWFsaXplciBLRVlfSU5JVElBTElaRVIgPQogICAgICBuZXcgSWFtUmVxdWVzdEluaXRpYWxpemVyKEtFWSk7CiAqIDwvcHJlPgogKgogKiA8cD4KICogVGhlcmUgaXMgYWxzbyBhIGNvbnN0cnVjdG9yIHRvIHNldCBib3RoIHRoZSBrZXkgYW5kIHVzZXJJcCBwYXJhbWV0ZXJzOgogKiA8L3A+CiAqCiAqIDxwcmU+CiAgcHVibGljIHN0YXRpYyBmaW5hbCBHb29nbGVDbGllbnRSZXF1ZXN0SW5pdGlhbGl6ZXIgSU5JVElBTElaRVIgPQogICAgICBuZXcgSWFtUmVxdWVzdEluaXRpYWxpemVyKEtFWSwgVVNFUl9JUCk7CiAqIDwvcHJlPgogKgogKiA8cD4KICogSWYgeW91IHdhbnQgdG8gaW1wbGVtZW50IGN1c3RvbSBsb2dpYywgZXh0ZW5kIGl0IGxpa2UgdGhpczoKICogPC9wPgogKgogKiA8cHJlPgogIHB1YmxpYyBzdGF0aWMgY2xhc3MgTXlSZXF1ZXN0SW5pdGlhbGl6ZXIgZXh0ZW5kcyBJYW1SZXF1ZXN0SW5pdGlhbGl6ZXIgewoKICAgIHtAbGl0ZXJhbCBAfU92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCBpbml0aWFsaXplSWFtUmVxdWVzdChJYW1SZXF1ZXN0e0BsaXRlcmFsIDx9P3tAbGl0ZXJhbCA+fSByZXF1ZXN0KQogICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CiAgICAgIC8vIGN1c3RvbSBsb2dpYwogICAgfQogIH0KICogPC9wcmU+CiAqCiAqIDxwPgogKiBGaW5hbGx5LCB0byBzZXQgdGhlIGtleSBhbmQgdXNlcklwIHBhcmFtZXRlcnMgYW5kIGluc2VydCBjdXN0b20gbG9naWMsIGV4dGVuZCBpdCBsaWtlIHRoaXM6CiAqIDwvcD4KICoKICogPHByZT4KICBwdWJsaWMgc3RhdGljIGNsYXNzIE15UmVxdWVzdEluaXRpYWxpemVyMiBleHRlbmRzIElhbVJlcXVlc3RJbml0aWFsaXplciB7CgogICAgcHVibGljIE15S2V5UmVxdWVzdEluaXRpYWxpemVyKCkgewogICAgICBzdXBlcihLRVksIFVTRVJfSVApOwogICAgfQoKICAgIHtAbGl0ZXJhbCBAfU92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCBpbml0aWFsaXplSWFtUmVxdWVzdChJYW1SZXF1ZXN0e0BsaXRlcmFsIDx9P3tAbGl0ZXJhbCA+fSByZXF1ZXN0KQogICAgICAgIHRocm93cyBJT0V4Y2VwdGlvbiB7CiAgICAgIC8vIGN1c3RvbSBsb2dpYwogICAgfQogIH0KICogPC9wcmU+CiAqCiAqIDxwPgogKiBTdWJjbGFzc2VzIHNob3VsZCBiZSB0aHJlYWQtc2FmZS4KICogPC9wPgogKgogKiBAc2luY2UgMS4xMgogKi8KcHVibGljIGNsYXNzIElhbVJlcXVlc3RJbml0aWFsaXplciBleHRlbmRzIGNvbS5nb29nbGUuYXBpLmNsaWVudC5nb29nbGVhcGlzLnNlcnZpY2VzLmpzb24uQ29tbW9uR29vZ2xlSnNvbkNsaWVudFJlcXVlc3RJbml0aWFsaXplciB7CgogIHB1YmxpYyBJYW1SZXF1ZXN0SW5pdGlhbGl6ZXIoKSB7CiAgICBzdXBlcigpOwogIH0KCiAgLyoqCiAgICogQHBhcmFtIGtleSBBUEkga2V5IG9yIHtAY29kZSBudWxsfSB0byBsZWF2ZSBpdCB1bmNoYW5nZWQKICAgKi8KICBwdWJsaWMgSWFtUmVxdWVzdEluaXRpYWxpemVyKFN0cmluZyBrZXkpIHsKICAgIHN1cGVyKGtleSk7CiAgfQoKICAvKioKICAgKiBAcGFyYW0ga2V5IEFQSSBrZXkgb3Ige0Bjb2RlIG51bGx9IHRvIGxlYXZlIGl0IHVuY2hhbmdlZAogICAqIEBwYXJhbSB1c2VySXAgdXNlciBJUCBvciB7QGNvZGUgbnVsbH0gdG8gbGVhdmUgaXQgdW5jaGFuZ2VkCiAgICovCiAgcHVibGljIElhbVJlcXVlc3RJbml0aWFsaXplcihTdHJpbmcga2V5LCBTdHJpbmcgdXNlcklwKSB7CiAgICBzdXBlcihrZXksIHVzZXJJcCk7CiAgfQoKICBAT3ZlcnJpZGUKICBwdWJsaWMgZmluYWwgdm9pZCBpbml0aWFsaXplSnNvblJlcXVlc3QoY29tLmdvb2dsZS5hcGkuY2xpZW50Lmdvb2dsZWFwaXMuc2VydmljZXMuanNvbi5BYnN0cmFjdEdvb2dsZUpzb25DbGllbnRSZXF1ZXN0PD8+IHJlcXVlc3QpIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgIHN1cGVyLmluaXRpYWxpemVKc29uUmVxdWVzdChyZXF1ZXN0KTsKICAgIGluaXRpYWxpemVJYW1SZXF1ZXN0KChJYW1SZXF1ZXN0PD8+KSByZXF1ZXN0KTsKICB9CgogIC8qKgogICAqIEluaXRpYWxpemVzIElhbSByZXF1ZXN0LgogICAqCiAgICogPHA+CiAgICogRGVmYXVsdCBpbXBsZW1lbnRhdGlvbiBkb2VzIG5vdGhpbmcuIENhbGxlZCBmcm9tCiAgICoge0BsaW5rICNpbml0aWFsaXplSnNvblJlcXVlc3QoY29tLmdvb2dsZS5hcGkuY2xpZW50Lmdvb2dsZWFwaXMuc2VydmljZXMuanNvbi5BYnN0cmFjdEdvb2dsZUpzb25DbGllbnRSZXF1ZXN0KX0uCiAgICogPC9wPgogICAqCiAgICogQHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIEkvTyBleGNlcHRpb24KICAgKi8KICBwcm90ZWN0ZWQgdm9pZCBpbml0aWFsaXplSWFtUmVxdWVzdChJYW1SZXF1ZXN0PD8+IHJlcXVlc3QpIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICB9Cn0KUEsDBBQAAAAAAAAAIQCh01adhgoAAIYKAAAHAAAAcG9tLnhtbDxwcm9qZWN0IHhtbG5zPSJodHRwOi8vbWF2ZW4uYXBhY2hlLm9yZy9QT00vNC4wLjAiIHhtbG5zOnhzaT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UiIHhzaTpzY2hlbWFMb2NhdGlvbj0iaHR0cDovL21hdmVuLmFwYWNoZS5vcmcvUE9NLzQuMC4wIGh0dHA6Ly9tYXZlbi5hcGFjaGUub3JnL21hdmVuLXY0XzBfMC54c2QiPgogIDxtb2RlbFZlcnNpb24+NC4wLjA8L21vZGVsVmVyc2lvbj4KICA8cGFyZW50PgogICAgPGdyb3VwSWQ+b3JnLnNvbmF0eXBlLm9zczwvZ3JvdXBJZD4KICAgIDxhcnRpZmFjdElkPm9zcy1wYXJlbnQ8L2FydGlmYWN0SWQ+CiAgICA8dmVyc2lvbj43PC92ZXJzaW9uPgogIDwvcGFyZW50PgoKICA8Z3JvdXBJZD5jb20uZ29vZ2xlLmFwaXM8L2dyb3VwSWQ+CiAgPGFydGlmYWN0SWQ+Z29vZ2xlLWFwaS1zZXJ2aWNlcy1pYW08L2FydGlmYWN0SWQ+CiAgPHZlcnNpb24+djEtcmV2MzE0LTEuMjUuMDwvdmVyc2lvbj4KICA8bmFtZT5JZGVudGl0eSBhbmQgQWNjZXNzIE1hbmFnZW1lbnQgKElBTSkgQVBJIHYxLXJldjMxNC0xLjI1LjA8L25hbWU+CiAgPHBhY2thZ2luZz5qYXI8L3BhY2thZ2luZz4KCiAgPGluY2VwdGlvblllYXI+MjAxMTwvaW5jZXB0aW9uWWVhcj4KCiAgPG9yZ2FuaXphdGlvbj4KICAgIDxuYW1lPkdvb2dsZTwvbmFtZT4KICAgIDx1cmw+aHR0cDovL3d3dy5nb29nbGUuY29tLzwvdXJsPgogIDwvb3JnYW5pemF0aW9uPgoKICA8bGljZW5zZXM+CiAgICA8bGljZW5zZT4KICAgICAgPG5hbWU+VGhlIEFwYWNoZSBTb2Z0d2FyZSBMaWNlbnNlLCBWZXJzaW9uIDIuMDwvbmFtZT4KICAgICAgPHVybD5odHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAudHh0PC91cmw+CiAgICAgIDxkaXN0cmlidXRpb24+cmVwbzwvZGlzdHJpYnV0aW9uPgogICAgPC9saWNlbnNlPgogIDwvbGljZW5zZXM+CgogIDxidWlsZD4KICAgIDxwbHVnaW5zPgogICAgICA8cGx1Z2luPgogICAgICAgIDxhcnRpZmFjdElkPm1hdmVuLWNvbXBpbGVyLXBsdWdpbjwvYXJ0aWZhY3RJZD4KICAgICAgICA8dmVyc2lvbj4yLjMuMjwvdmVyc2lvbj4KICAgICAgICA8Y29uZmlndXJhdGlvbj4KICAgICAgICAgIDxzb3VyY2U+MS41PC9zb3VyY2U+CiAgICAgICAgICA8dGFyZ2V0PjEuNTwvdGFyZ2V0PgogICAgICAgIDwvY29uZmlndXJhdGlvbj4KICAgICAgPC9wbHVnaW4+CiAgICAgIDxwbHVnaW4+CiAgICAgICAgPGFydGlmYWN0SWQ+bWF2ZW4tamFyLXBsdWdpbjwvYXJ0aWZhY3RJZD4KICAgICAgICA8dmVyc2lvbj4yLjMuMTwvdmVyc2lvbj4KICAgICAgICA8Y29uZmlndXJhdGlvbj4KICAgICAgICAgIDxhcmNoaXZlPgogICAgICAgICAgICA8bWFuaWZlc3RFbnRyaWVzPgogICAgICAgICAgICAgIDxCdWlsdC1CeT5Hb29nbGU8L0J1aWx0LUJ5PgogICAgICAgICAgICAgIDxCdWlsZC1KZGs+MS42Lng8L0J1aWxkLUpkaz4KICAgICAgICAgICAgPC9tYW5pZmVzdEVudHJpZXM+CiAgICAgICAgICA8L2FyY2hpdmU+CiAgICAgICAgPC9jb25maWd1cmF0aW9uPgogICAgICA8L3BsdWdpbj4KICAgICAgPHBsdWdpbj4KICAgICAgICA8YXJ0aWZhY3RJZD5tYXZlbi1qYXZhZG9jLXBsdWdpbjwvYXJ0aWZhY3RJZD4KICAgICAgICA8dmVyc2lvbj4yLjc8L3ZlcnNpb24+CiAgICAgICAgPGNvbmZpZ3VyYXRpb24+CiAgICAgICAgICA8ZG9jdGl0bGU+SWRlbnRpdHkgYW5kIEFjY2VzcyBNYW5hZ2VtZW50IChJQU0pIEFQSSAke3Byb2plY3QudmVyc2lvbn08L2RvY3RpdGxlPgogICAgICAgICAgPHdpbmRvd3RpdGxlPklkZW50aXR5IGFuZCBBY2Nlc3MgTWFuYWdlbWVudCAoSUFNKSBBUEkgJHtwcm9qZWN0LnZlcnNpb259PC93aW5kb3d0aXRsZT4KICAgICAgICAgIDxsaW5rcz4KICAgICAgICAgICAgPGxpbms+aHR0cDovL2RvY3Mub3JhY2xlLmNvbS9qYXZhc2UvNy9kb2NzL2FwaTwvbGluaz4KICAgICAgICAgIAogICAgICAgICAgICA8bGluaz5odHRwOi8vamF2YWRvYy5nb29nbGUtaHR0cC1qYXZhLWNsaWVudC5nb29nbGVjb2RlLmNvbS9oZy8xLjI1LjA8L2xpbms+CiAgICAgICAgICAKICAgICAgICAgICAgPGxpbms+aHR0cDovL2phdmFkb2MuZ29vZ2xlLW9hdXRoLWphdmEtY2xpZW50Lmdvb2dsZWNvZGUuY29tL2hnLzEuMjUuMDwvbGluaz4KICAgICAgICAgIAogICAgICAgICAgICA8bGluaz5odHRwOi8vamF2YWRvYy5nb29nbGUtYXBpLWphdmEtY2xpZW50Lmdvb2dsZWNvZGUuY29tL2hnLzEuMjUuMDwvbGluaz4KICAgICAgICAgIDwvbGlua3M+CiAgICAgICAgPC9jb25maWd1cmF0aW9uPgogICAgICA8L3BsdWdpbj4KICAgIDwvcGx1Z2lucz4KICAgIDxzb3VyY2VEaXJlY3Rvcnk+Ljwvc291cmNlRGlyZWN0b3J5PgogIDwvYnVpbGQ+CgogIDxkZXBlbmRlbmNpZXM+CiAgICA8ZGVwZW5kZW5jeT4KICAgICAgPGdyb3VwSWQ+Y29tLmdvb2dsZS5hcGktY2xpZW50PC9ncm91cElkPgogICAgICA8YXJ0aWZhY3RJZD5nb29nbGUtYXBpLWNsaWVudDwvYXJ0aWZhY3RJZD4KICAgICAgPHZlcnNpb24+MS4yNS4wPC92ZXJzaW9uPgogICAgPC9kZXBlbmRlbmN5PgogIDwvZGVwZW5kZW5jaWVzPgoKICA8cHJvcGVydGllcz4KICAgIDxwcm9qZWN0LmJ1aWxkLnNvdXJjZUVuY29kaW5nPlVURi04PC9wcm9qZWN0LmJ1aWxkLnNvdXJjZUVuY29kaW5nPgogIDwvcHJvcGVydGllcz4KPC9wcm9qZWN0PlBLAQIUAxQAAAAAAAAAIQAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAEADtQQAAAABjb20vUEsBAhQDFAAAAAAAAAAhAAAAAAAAAAAAAAAAAAsAAAAAAAAAAAAQAO1BIgAAAGNvbS9nb29nbGUvUEsBAhQDFAAAAAAAAAAhAAAAAAAAAAAAAAAAAA8AAAAAAAAAAAAQAO1BSwAAAGNvbS9nb29nbGUvYXBpL1BLAQIUAxQAAAAAAAAAIQAAAAAAAAAAAAAAAAAYAAAAAAAAAAAAEADtQXgAAABjb20vZ29vZ2xlL2FwaS9zZXJ2aWNlcy9QSwECFAMUAAAAAAAAACEAAAAAAAAAAAAAAAAAHAAAAAAAAAAAABAA7UGuAAAAY29tL2dvb2dsZS9hcGkvc2VydmljZXMvaWFtL1BLAQIUAxQAAAAAAAAAIQAAAAAAAAAAAAAAAAAfAAAAAAAAAAAAEADtQegAAABjb20vZ29vZ2xlL2FwaS9zZXJ2aWNlcy9pYW0vdjEvUEsBAhQDFAAAAAAAAAAhAIOvde+8BQAAvAUAAC0AAAAAAAAAAAAAAKQBJQEAAGNvbS9nb29nbGUvYXBpL3NlcnZpY2VzL2lhbS92MS9JYW1TY29wZXMuamF2YVBLAQIUAxQAAAAAAAAAIQBDDSEmFR4AABUeAAAuAAAAAAAAAAAAAACkASwHAABjb20vZ29vZ2xlL2FwaS9zZXJ2aWNlcy9pYW0vdjEvSWFtUmVxdWVzdC5qYXZhUEsBAhQDFAAAAAAAAAAhAL2qkEJCMQUAQjEFACcAAAAAAAAAAAAAAKQBjSUAAGNvbS9nb29nbGUvYXBpL3NlcnZpY2VzL2lhbS92MS9JYW0uamF2YVBLAQIUAxQAAAAAAAAAIQAAAAAAAAAAAAAAAAAlAAAAAAAAAAAAEADtQRRXBQBjb20vZ29vZ2xlL2FwaS9zZXJ2aWNlcy9pYW0vdjEvbW9kZWwvUEsBAhQDFAAAAAAAAAAhAKqhnC6cCQAAnAkAADgAAAAAAAAAAAAAAKQBV1cFAGNvbS9nb29nbGUvYXBpL3NlcnZpY2VzL2lhbS92MS9tb2RlbC9BZG1pbkF1ZGl0RGF0YS5qYXZhUEsBAhQDFAAAAAAAAAAhAKKa9HLZEwAA2RMAADUAAAAAAAAAAAAAAKQBSWEFAGNvbS9nb29nbGUvYXBpL3NlcnZpY2VzL2lhbS92MS9tb2RlbC9BdWRpdENvbmZpZy5qYXZhUEsBAhQDFAAAAAAAAAAhAOdkkSdYCQAAWAkAADMAAAAAAAAAAAAAAKQBdXUFAGNvbS9nb29nbGUvYXBpL3NlcnZpY2VzL2lhbS92MS9tb2RlbC9BdWRpdERhdGEuamF2YVBLAQIUAxQAAAAAAAAAIQAYd3NYzA0AAMwNAAA4AAAAAAAAAAAAAACkAR5/BQBjb20vZ29vZ2xlL2FwaS9zZXJ2aWNlcy9pYW0vdjEvbW9kZWwvQXVkaXRMb2dDb25maWcuamF2YVBLAQIUAxQAAAAAAAAAIQARtrcYWQkAAFkJAAA6AAAAAAAAAAAAAACkAUCNBQBjb20vZ29vZ2xlL2FwaS9zZXJ2aWNlcy9pYW0vdjEvbW9kZWwvQXVkaXRhYmxlU2VydmljZS5qYXZhUEsBAhQDFAAAAAAAAAAhAEYN/yEyKAAAMigAADEAAAAAAAAAAAAAAKQB8ZYFAGNvbS9nb29nbGUvYXBpL3NlcnZpY2VzL2lhbS92MS9tb2RlbC9CaW5kaW5nLmphdmFQSwECFAMUAAAAAAAAACEA3vDoiU0RAABNEQAANgAAAAAAAAAAAAAApAFyvwUAY29tL2dvb2dsZS9hcGkvc2VydmljZXMvaWFtL3YxL21vZGVsL0JpbmRpbmdEZWx0YS5qYXZhUEsBAhQDFAAAAAAAAAAhAIQixUVjCgAAYwoAADsAAAAAAAAAAAAAAKQBE9EFAGNvbS9nb29nbGUvYXBpL3NlcnZpY2VzL2lhbS92MS9tb2RlbC9DcmVhdGVSb2xlUmVxdWVzdC5qYXZhUEsBAhQDFAAAAAAAAAAhACypjaP3DQAA9w0AAEgAAAAAAAAAAAAAAKQBz9sFAGNvbS9nb29nbGUvYXBpL3NlcnZpY2VzL2lhbS92MS9tb2RlbC9DcmVhdGVTZXJ2aWNlQWNjb3VudEtleVJlcXVlc3QuamF2YVBLAQIUAxQAAAAAAAAAIQCx6cwpMQ8AADEPAABFAAAAAAAAAAAAAACkASzqBQBjb20vZ29vZ2xlL2FwaS9zZXJ2aWNlcy9pYW0vdjEvbW9kZWwvQ3JlYXRlU2VydmljZUFjY291bnRSZXF1ZXN0LmphdmFQSwECFAMUAAAAAAAAACEAzIVPOL4GAAC+BgAARgAAAAAAAAAAAAAApAHA+QUAY29tL2dvb2dsZS9hcGkvc2VydmljZXMvaWFtL3YxL21vZGVsL0Rpc2FibGVTZXJ2aWNlQWNjb3VudFJlcXVlc3QuamF2YVBLAQIUAxQAAAAAAAAAIQDE8kybngcAAJ4HAAAvAAAAAAAAAAAAAACkAeIABgBjb20vZ29vZ2xlL2FwaS9zZXJ2aWNlcy9pYW0vdjEvbW9kZWwvRW1wdHkuamF2YVBLAQIUAxQAAAAAAAAAIQAaPvikuAYAALgGAABFAAAAAAAAAAAAAACkAc0IBgBjb20vZ29vZ2xlL2FwaS9zZXJ2aWNlcy9pYW0vdjEvbW9kZWwvRW5hYmxlU2VydmljZUFjY291bnRSZXF1ZXN0LmphdmFQSwECFAMUAAAAAAAAACEAx1I6S3gXAAB4FwAALgAAAAAAAAAAAAAApAHoDwYAY29tL2dvb2dsZS9hcGkvc2VydmljZXMvaWFtL3YxL21vZGVsL0V4cHIuamF2YVBLAQIUAxQAAAAAAAAAIQA86HKRGRAAABkQAAA7AAAAAAAAAAAAAACkAawnBgBjb20vZ29vZ2xlL2FwaS9zZXJ2aWNlcy9pYW0vdjEvbW9kZWwvTGludFBvbGljeVJlcXVlc3QuamF2YVBLAQIUAxQAAAAAAAAAIQDc7btymwoAAJsKAAA8AAAAAAAAAAAAAACkAR44BgBjb20vZ29vZ2xlL2FwaS9zZXJ2aWNlcy9pYW0vdjEvbW9kZWwvTGludFBvbGljeVJlc3BvbnNlLmphdmFQSwECFAMUAAAAAAAAACEAjF6yekEaAABBGgAANAAAAAAAAAAAAAAApAETQwYAY29tL2dvb2dsZS9hcGkvc2VydmljZXMvaWFtL3YxL21vZGVsL0xpbnRSZXN1bHQuamF2YVBLAQIUAxQAAAAAAAAAIQAuYzvMqQsAAKkLAAA7AAAAAAAAAAAAAACkAaZdBgBjb20vZ29vZ2xlL2FwaS9zZXJ2aWNlcy9pYW0vdjEvbW9kZWwvTGlzdFJvbGVzUmVzcG9uc2UuamF2YVBLAQIUAxQAAAAAAAAAIQDlacaZIAkAACAJAABIAAAAAAAAAAAAAACkAahpBgBjb20vZ29vZ2xlL2FwaS9zZXJ2aWNlcy9pYW0vdjEvbW9kZWwvTGlzdFNlcnZpY2VBY2NvdW50S2V5c1Jlc3BvbnNlLmphdmFQSwECFAMUAAAAAAAAACEAk+UohTENAAAxDQAARQAAAAAAAAAAAAAApAEucwYAY29tL2dvb2dsZS9hcGkvc2VydmljZXMvaWFtL3YxL21vZGVsL0xpc3RTZXJ2aWNlQWNjb3VudHNSZXNwb25zZS5qYXZhUEsBAhQDFAAAAAAAAAAhAIh4/k5GCgAARgoAAEQAAAAAAAAAAAAAAKQBwoAGAGNvbS9nb29nbGUvYXBpL3NlcnZpY2VzL2lhbS92MS9tb2RlbC9QYXRjaFNlcnZpY2VBY2NvdW50UmVxdWVzdC5qYXZhUEsBAhQDFAAAAAAAAAAhADzrNCS4GgAAuBoAADQAAAAAAAAAAAAAAKQBaosGAGNvbS9nb29nbGUvYXBpL3NlcnZpY2VzL2lhbS92MS9tb2RlbC9QZXJtaXNzaW9uLmphdmFQSwECFAMUAAAAAAAAACEABDQFjasLAACrCwAAOQAAAAAAAAAAAAAApAF0pgYAY29tL2dvb2dsZS9hcGkvc2VydmljZXMvaWFtL3YxL21vZGVsL1Blcm1pc3Npb25EZWx0YS5qYXZhUEsBAhQDFAAAAAAAAAAhAHxUODuUNgAAlDYAADAAAAAAAAAAAAAAAKQBdrIGAGNvbS9nb29nbGUvYXBpL3NlcnZpY2VzL2lhbS92MS9tb2RlbC9Qb2xpY3kuamF2YVBLAQIUAxQAAAAAAAAAIQCoAuUX/AkAAPwJAAA1AAAAAAAAAAAAAACkAVjpBgBjb20vZ29vZ2xlL2FwaS9zZXJ2aWNlcy9pYW0vdjEvbW9kZWwvUG9saWN5RGVsdGEuamF2YVBLAQIUAxQAAAAAAAAAIQCP9Q/nYgwAAGIMAABHAAAAAAAAAAAAAACkAafzBgBjb20vZ29vZ2xlL2FwaS9zZXJ2aWNlcy9pYW0vdjEvbW9kZWwvUXVlcnlBdWRpdGFibGVTZXJ2aWNlc1JlcXVlc3QuamF2YVBLAQIUAxQAAAAAAAAAIQDpKOK7VgkAAFYJAABIAAAAAAAAAAAAAACkAW4ABwBjb20vZ29vZ2xlL2FwaS9zZXJ2aWNlcy9pYW0vdjEvbW9kZWwvUXVlcnlBdWRpdGFibGVTZXJ2aWNlc1Jlc3BvbnNlLmphdmFQSwECFAMUAAAAAAAAACEAI5GnDAcTAAAHEwAARAAAAAAAAAAAAAAApAEqCgcAY29tL2dvb2dsZS9hcGkvc2VydmljZXMvaWFtL3YxL21vZGVsL1F1ZXJ5R3JhbnRhYmxlUm9sZXNSZXF1ZXN0LmphdmFQSwECFAMUAAAAAAAAACEAC+s0uOsLAADrCwAARQAAAAAAAAAAAAAApAGTHQcAY29tL2dvb2dsZS9hcGkvc2VydmljZXMvaWFtL3YxL21vZGVsL1F1ZXJ5R3JhbnRhYmxlUm9sZXNSZXNwb25zZS5qYXZhUEsBAhQDFAAAAAAAAAAhAIeH4AHmEQAA5hEAAEkAAAAAAAAAAAAAAKQB4SkHAGNvbS9nb29nbGUvYXBpL3NlcnZpY2VzL2lhbS92MS9tb2RlbC9RdWVyeVRlc3RhYmxlUGVybWlzc2lvbnNSZXF1ZXN0LmphdmFQSwECFAMUAAAAAAAAACEA8L4i+bAMAACwDAAASgAAAAAAAAAAAAAApAEuPAcAY29tL2dvb2dsZS9hcGkvc2VydmljZXMvaWFtL3YxL21vZGVsL1F1ZXJ5VGVzdGFibGVQZXJtaXNzaW9uc1Jlc3BvbnNlLmphdmFQSwECFAMUAAAAAAAAACEAAq69jp8fAACfHwAALgAAAAAAAAAAAAAApAFGSQcAY29tL2dvb2dsZS9hcGkvc2VydmljZXMvaWFtL3YxL21vZGVsL1JvbGUuamF2YVBLAQIUAxQAAAAAAAAAIQAt7+2OVSsAAFUrAAA4AAAAAAAAAAAAAACkATFpBwBjb20vZ29vZ2xlL2FwaS9zZXJ2aWNlcy9pYW0vdjEvbW9kZWwvU2VydmljZUFjY291bnQuamF2YVBLAQIUAxQAAAAAAAAAIQAZ08WN7DAAAOwwAAA7AAAAAAAAAAAAAACkAdyUBwBjb20vZ29vZ2xlL2FwaS9zZXJ2aWNlcy9pYW0vdjEvbW9kZWwvU2VydmljZUFjY291bnRLZXkuamF2YVBLAQIUAxQAAAAAAAAAIQCQAS9Phw8AAIcPAAA9AAAAAAAAAAAAAACkASHGBwBjb20vZ29vZ2xlL2FwaS9zZXJ2aWNlcy9pYW0vdjEvbW9kZWwvU2V0SWFtUG9saWN5UmVxdWVzdC5qYXZhUEsBAhQDFAAAAAAAAAAhAKHoQ7dkCwAAZAsAADkAAAAAAAAAAAAAAKQBA9YHAGNvbS9nb29nbGUvYXBpL3NlcnZpY2VzL2lhbS92MS9tb2RlbC9TaWduQmxvYlJlcXVlc3QuamF2YVBLAQIUAxQAAAAAAAAAIQAwOt1GJw0AACcNAAA6AAAAAAAAAAAAAACkAb7hBwBjb20vZ29vZ2xlL2FwaS9zZXJ2aWNlcy9pYW0vdjEvbW9kZWwvU2lnbkJsb2JSZXNwb25zZS5qYXZhUEsBAhQDFAAAAAAAAAAhAPwCQqbWCAAA1ggAADgAAAAAAAAAAAAAAKQBPe8HAGNvbS9nb29nbGUvYXBpL3NlcnZpY2VzL2lhbS92MS9tb2RlbC9TaWduSnd0UmVxdWVzdC5qYXZhUEsBAhQDFAAAAAAAAAAhANLHh4mNCgAAjQoAADkAAAAAAAAAAAAAAKQBafgHAGNvbS9nb29nbGUvYXBpL3NlcnZpY2VzL2lhbS92MS9tb2RlbC9TaWduSnd0UmVzcG9uc2UuamF2YVBLAQIUAxQAAAAAAAAAIQBHpJWehAsAAIQLAABDAAAAAAAAAAAAAACkAU0DCABjb20vZ29vZ2xlL2FwaS9zZXJ2aWNlcy9pYW0vdjEvbW9kZWwvVGVzdElhbVBlcm1pc3Npb25zUmVxdWVzdC5qYXZhUEsBAhQDFAAAAAAAAAAhAIo0Lm+6CQAAugkAAEQAAAAAAAAAAAAAAKQBMg8IAGNvbS9nb29nbGUvYXBpL3NlcnZpY2VzL2lhbS92MS9tb2RlbC9UZXN0SWFtUGVybWlzc2lvbnNSZXNwb25zZS5qYXZhUEsBAhQDFAAAAAAAAAAhAKpvV3ldCwAAXQsAAD0AAAAAAAAAAAAAAKQBThkIAGNvbS9nb29nbGUvYXBpL3NlcnZpY2VzL2lhbS92MS9tb2RlbC9VbmRlbGV0ZVJvbGVSZXF1ZXN0LmphdmFQSwECFAMUAAAAAAAAACEA6izdh8QGAADEBgAARwAAAAAAAAAAAAAApAEGJQgAY29tL2dvb2dsZS9hcGkvc2VydmljZXMvaWFtL3YxL21vZGVsL1VuZGVsZXRlU2VydmljZUFjY291bnRSZXF1ZXN0LmphdmFQSwECFAMUAAAAAAAAACEAvl9+0l0JAABdCQAASAAAAAAAAAAAAAAApAEvLAgAY29tL2dvb2dsZS9hcGkvc2VydmljZXMvaWFtL3YxL21vZGVsL1VuZGVsZXRlU2VydmljZUFjY291bnRSZXNwb25zZS5qYXZhUEsBAhQDFAAAAAAAAAAhAOxrXvq+DwAAvg8AAEgAAAAAAAAAAAAAAKQB8jUIAGNvbS9nb29nbGUvYXBpL3NlcnZpY2VzL2lhbS92MS9tb2RlbC9VcGxvYWRTZXJ2aWNlQWNjb3VudEtleVJlcXVlc3QuamF2YVBLAQIUAxQAAAAAAAAAIQC2hR9LVQ0AAFUNAAA5AAAAAAAAAAAAAACkARZGCABjb20vZ29vZ2xlL2FwaS9zZXJ2aWNlcy9pYW0vdjEvSWFtUmVxdWVzdEluaXRpYWxpemVyLmphdmFQSwECFAMUAAAAAAAAACEAodNWnYYKAACGCgAABwAAAAAAAAAAAAAApAHCUwgAcG9tLnhtbFBLBQYAAAAAOQA5AFAWAABtXggAAAA=