UEsDBBQAAAAAAAAAIQAAAAAAAAAAAAAAAAAEAAAAY29tL1BLAwQUAAAAAAAAACEAAAAAAAAAAAAAAAAACwAAAGNvbS9nb29nbGUvUEsDBBQAAAAAAAAAIQAAAAAAAAAAAAAAAAAPAAAAY29tL2dvb2dsZS9hcGkvUEsDBBQAAAAAAAAAIQAAAAAAAAAAAAAAAAAYAAAAY29tL2dvb2dsZS9hcGkvc2VydmljZXMvUEsDBBQAAAAAAAAAIQAAAAAAAAAAAAAAAAAtAAAAY29tL2dvb2dsZS9hcGkvc2VydmljZXMvY2xvdWRyZXNvdXJjZW1hbmFnZXIvUEsDBBQAAAAAAAAAIQCPdaE9uQYAALkGAABMAAAAY29tL2dvb2dsZS9hcGkvc2VydmljZXMvY2xvdWRyZXNvdXJjZW1hbmFnZXIvQ2xvdWRSZXNvdXJjZU1hbmFnZXJTY29wZXMuamF2YS8qCiAqIENvcHlyaWdodCAyMDEwIEdvb2dsZSBJbmMuCiAqCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdAogKiBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZQogKiBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3MKICogb3IgaW1wbGllZC4gU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucyB1bmRlcgogKiB0aGUgTGljZW5zZS4KICovCi8qCiAqIFRoaXMgY29kZSB3YXMgZ2VuZXJhdGVkIGJ5IGh0dHBzOi8vZ2l0aHViLmNvbS9nb29nbGUvYXBpcy1jbGllbnQtZ2VuZXJhdG9yLwogKiAoYnVpbGQ6IDIwMTgtMTAtMDggMTc6NDU6MzkgVVRDKQogKiBvbiAyMDIwLTAzLTE5IGF0IDAyOjM4OjMwIFVUQyAKICogTW9kaWZ5IGF0IHlvdXIgb3duIHJpc2suCiAqLwoKcGFja2FnZSBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5jbG91ZHJlc291cmNlbWFuYWdlcjsKCi8qKgogKiBBdmFpbGFibGUgT0F1dGggMi4wIHNjb3BlcyBmb3IgdXNlIHdpdGggdGhlIENsb3VkIFJlc291cmNlIE1hbmFnZXIgQVBJLgogKgogKiBAc2luY2UgMS40CiAqLwpwdWJsaWMgY2xhc3MgQ2xvdWRSZXNvdXJjZU1hbmFnZXJTY29wZXMgewoKICAvKiogVmlldyBhbmQgbWFuYWdlIHlvdXIgZGF0YSBhY3Jvc3MgR29vZ2xlIENsb3VkIFBsYXRmb3JtIHNlcnZpY2VzLiAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIENMT1VEX1BMQVRGT1JNID0gImh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL2F1dGgvY2xvdWQtcGxhdGZvcm0iOwoKICAvKiogVmlldyB5b3VyIGRhdGEgYWNyb3NzIEdvb2dsZSBDbG91ZCBQbGF0Zm9ybSBzZXJ2aWNlcy4gKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBDTE9VRF9QTEFURk9STV9SRUFEX09OTFkgPSAiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vYXV0aC9jbG91ZC1wbGF0Zm9ybS5yZWFkLW9ubHkiOwoKICAvKioKICAgKiBSZXR1cm5zIGFuIHVubW9kaWZpYWJsZSBzZXQgdGhhdCBjb250YWlucyBhbGwgc2NvcGVzIGRlY2xhcmVkIGJ5IHRoaXMgY2xhc3MuCiAgICoKICAgKiBAc2luY2UgMS4xNgogICAqLwogIHB1YmxpYyBzdGF0aWMgamF2YS51dGlsLlNldDxTdHJpbmc+IGFsbCgpIHsKICAgIGphdmEudXRpbC5TZXQ8U3RyaW5nPiBzZXQgPSBuZXcgamF2YS51dGlsLkhhc2hTZXQ8U3RyaW5nPigpOwogICAgc2V0LmFkZChDTE9VRF9QTEFURk9STSk7CiAgICBzZXQuYWRkKENMT1VEX1BMQVRGT1JNX1JFQURfT05MWSk7CiAgICByZXR1cm4gamF2YS51dGlsLkNvbGxlY3Rpb25zLnVubW9kaWZpYWJsZVNldChzZXQpOwogIH0KCiAgcHJpdmF0ZSBDbG91ZFJlc291cmNlTWFuYWdlclNjb3BlcygpIHsKICB9Cn0KUEsDBBQAAAAAAAAAIQCtqbKEqh8AAKofAABNAAAAY29tL2dvb2dsZS9hcGkvc2VydmljZXMvY2xvdWRyZXNvdXJjZW1hbmFnZXIvQ2xvdWRSZXNvdXJjZU1hbmFnZXJSZXF1ZXN0LmphdmEvKgogKiBDb3B5cmlnaHQgMjAxMCBHb29nbGUgSW5jLgogKgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQKICogaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UKICogaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzCiAqIG9yIGltcGxpZWQuIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMgdW5kZXIKICogdGhlIExpY2Vuc2UuCiAqLwovKgogKiBUaGlzIGNvZGUgd2FzIGdlbmVyYXRlZCBieSBodHRwczovL2dpdGh1Yi5jb20vZ29vZ2xlL2FwaXMtY2xpZW50LWdlbmVyYXRvci8KICogKGJ1aWxkOiAyMDE4LTEwLTA4IDE3OjQ1OjM5IFVUQykKICogb24gMjAyMC0wMy0xOSBhdCAwMjozODozMCBVVEMgCiAqIE1vZGlmeSBhdCB5b3VyIG93biByaXNrLgogKi8KCnBhY2thZ2UgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuY2xvdWRyZXNvdXJjZW1hbmFnZXI7CgovKioKICogQ2xvdWRSZXNvdXJjZU1hbmFnZXIgcmVxdWVzdC4KICoKICogQHNpbmNlIDEuMwogKi8KQFN1cHByZXNzV2FybmluZ3MoImphdmFkb2MiKQpwdWJsaWMgYWJzdHJhY3QgY2xhc3MgQ2xvdWRSZXNvdXJjZU1hbmFnZXJSZXF1ZXN0PFQ+IGV4dGVuZHMgY29tLmdvb2dsZS5hcGkuY2xpZW50Lmdvb2dsZWFwaXMuc2VydmljZXMuanNvbi5BYnN0cmFjdEdvb2dsZUpzb25DbGllbnRSZXF1ZXN0PFQ+IHsKCiAgLyoqCiAgICogQHBhcmFtIGNsaWVudCBHb29nbGUgY2xpZW50CiAgICogQHBhcmFtIG1ldGhvZCBIVFRQIE1ldGhvZAogICAqIEBwYXJhbSB1cmlUZW1wbGF0ZSBVUkkgdGVtcGxhdGUgZm9yIHRoZSBwYXRoIHJlbGF0aXZlIHRvIHRoZSBiYXNlIFVSTC4gSWYgaXQgc3RhcnRzIHdpdGggYSAiLyIKICAgKiAgICAgICAgdGhlIGJhc2UgcGF0aCBmcm9tIHRoZSBiYXNlIFVSTCB3aWxsIGJlIHN0cmlwcGVkIG91dC4gVGhlIFVSSSB0ZW1wbGF0ZSBjYW4gYWxzbyBiZSBhCiAgICogICAgICAgIGZ1bGwgVVJMLiBVUkkgdGVtcGxhdGUgZXhwYW5zaW9uIGlzIGRvbmUgdXNpbmcKICAgKiAgICAgICAge0BsaW5rIGNvbS5nb29nbGUuYXBpLmNsaWVudC5odHRwLlVyaVRlbXBsYXRlI2V4cGFuZChTdHJpbmcsIFN0cmluZywgT2JqZWN0LCBib29sZWFuKX0KICAgKiBAcGFyYW0gY29udGVudCBBIFBPSk8gdGhhdCBjYW4gYmUgc2VyaWFsaXplZCBpbnRvIEpTT04gb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICogQHBhcmFtIHJlc3BvbnNlQ2xhc3MgcmVzcG9uc2UgY2xhc3MgdG8gcGFyc2UgaW50bwogICAqLwogIHB1YmxpYyBDbG91ZFJlc291cmNlTWFuYWdlclJlcXVlc3QoCiAgICAgIENsb3VkUmVzb3VyY2VNYW5hZ2VyIGNsaWVudCwgU3RyaW5nIG1ldGhvZCwgU3RyaW5nIHVyaVRlbXBsYXRlLCBPYmplY3QgY29udGVudCwgQ2xhc3M8VD4gcmVzcG9uc2VDbGFzcykgewogICAgc3VwZXIoCiAgICAgICAgY2xpZW50LAogICAgICAgIG1ldGhvZCwKICAgICAgICB1cmlUZW1wbGF0ZSwKICAgICAgICBjb250ZW50LAogICAgICAgIHJlc3BvbnNlQ2xhc3MpOwogIH0KCiAgLyoqIFYxIGVycm9yIGZvcm1hdC4gKi8KICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5KCIkLnhnYWZ2IikKICBwcml2YXRlIGphdmEubGFuZy5TdHJpbmcgJFhnYWZ2OwoKICAvKioKICAgKiBWMSBlcnJvciBmb3JtYXQuCiAgICovCiAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0JFhnYWZ2KCkgewogICAgcmV0dXJuICRYZ2FmdjsKICB9CgogIC8qKiBWMSBlcnJvciBmb3JtYXQuICovCiAgcHVibGljIENsb3VkUmVzb3VyY2VNYW5hZ2VyUmVxdWVzdDxUPiBzZXQkWGdhZnYoamF2YS5sYW5nLlN0cmluZyAkWGdhZnYpIHsKICAgIHRoaXMuJFhnYWZ2ID0gJFhnYWZ2OwogICAgcmV0dXJuIHRoaXM7CiAgfQoKICAvKiogT0F1dGggYWNjZXNzIHRva2VuLiAqLwogIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkoImFjY2Vzc190b2tlbiIpCiAgcHJpdmF0ZSBqYXZhLmxhbmcuU3RyaW5nIGFjY2Vzc1Rva2VuOwoKICAvKioKICAgKiBPQXV0aCBhY2Nlc3MgdG9rZW4uCiAgICovCiAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0QWNjZXNzVG9rZW4oKSB7CiAgICByZXR1cm4gYWNjZXNzVG9rZW47CiAgfQoKICAvKiogT0F1dGggYWNjZXNzIHRva2VuLiAqLwogIHB1YmxpYyBDbG91ZFJlc291cmNlTWFuYWdlclJlcXVlc3Q8VD4gc2V0QWNjZXNzVG9rZW4oamF2YS5sYW5nLlN0cmluZyBhY2Nlc3NUb2tlbikgewogICAgdGhpcy5hY2Nlc3NUb2tlbiA9IGFjY2Vzc1Rva2VuOwogICAgcmV0dXJuIHRoaXM7CiAgfQoKICAvKiogRGF0YSBmb3JtYXQgZm9yIHJlc3BvbnNlLiAqLwogIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICBwcml2YXRlIGphdmEubGFuZy5TdHJpbmcgYWx0OwoKICAvKioKICAgKiBEYXRhIGZvcm1hdCBmb3IgcmVzcG9uc2UuIFtkZWZhdWx0OiBqc29uXQogICAqLwogIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldEFsdCgpIHsKICAgIHJldHVybiBhbHQ7CiAgfQoKICAvKiogRGF0YSBmb3JtYXQgZm9yIHJlc3BvbnNlLiAqLwogIHB1YmxpYyBDbG91ZFJlc291cmNlTWFuYWdlclJlcXVlc3Q8VD4gc2V0QWx0KGphdmEubGFuZy5TdHJpbmcgYWx0KSB7CiAgICB0aGlzLmFsdCA9IGFsdDsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgLyoqIEpTT05QICovCiAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogIHByaXZhdGUgamF2YS5sYW5nLlN0cmluZyBjYWxsYmFjazsKCiAgLyoqCiAgICogSlNPTlAKICAgKi8KICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRDYWxsYmFjaygpIHsKICAgIHJldHVybiBjYWxsYmFjazsKICB9CgogIC8qKiBKU09OUCAqLwogIHB1YmxpYyBDbG91ZFJlc291cmNlTWFuYWdlclJlcXVlc3Q8VD4gc2V0Q2FsbGJhY2soamF2YS5sYW5nLlN0cmluZyBjYWxsYmFjaykgewogICAgdGhpcy5jYWxsYmFjayA9IGNhbGxiYWNrOwogICAgcmV0dXJuIHRoaXM7CiAgfQoKICAvKiogU2VsZWN0b3Igc3BlY2lmeWluZyB3aGljaCBmaWVsZHMgdG8gaW5jbHVkZSBpbiBhIHBhcnRpYWwgcmVzcG9uc2UuICovCiAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogIHByaXZhdGUgamF2YS5sYW5nLlN0cmluZyBmaWVsZHM7CgogIC8qKgogICAqIFNlbGVjdG9yIHNwZWNpZnlpbmcgd2hpY2ggZmllbGRzIHRvIGluY2x1ZGUgaW4gYSBwYXJ0aWFsIHJlc3BvbnNlLgogICAqLwogIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldEZpZWxkcygpIHsKICAgIHJldHVybiBmaWVsZHM7CiAgfQoKICAvKiogU2VsZWN0b3Igc3BlY2lmeWluZyB3aGljaCBmaWVsZHMgdG8gaW5jbHVkZSBpbiBhIHBhcnRpYWwgcmVzcG9uc2UuICovCiAgcHVibGljIENsb3VkUmVzb3VyY2VNYW5hZ2VyUmVxdWVzdDxUPiBzZXRGaWVsZHMoamF2YS5sYW5nLlN0cmluZyBmaWVsZHMpIHsKICAgIHRoaXMuZmllbGRzID0gZmllbGRzOwogICAgcmV0dXJuIHRoaXM7CiAgfQoKICAvKioKICAgKiBBUEkga2V5LiBZb3VyIEFQSSBrZXkgaWRlbnRpZmllcyB5b3VyIHByb2plY3QgYW5kIHByb3ZpZGVzIHlvdSB3aXRoIEFQSSBhY2Nlc3MsIHF1b3RhLCBhbmQKICAgKiByZXBvcnRzLiBSZXF1aXJlZCB1bmxlc3MgeW91IHByb3ZpZGUgYW4gT0F1dGggMi4wIHRva2VuLgogICAqLwogIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICBwcml2YXRlIGphdmEubGFuZy5TdHJpbmcga2V5OwoKICAvKioKICAgKiBBUEkga2V5LiBZb3VyIEFQSSBrZXkgaWRlbnRpZmllcyB5b3VyIHByb2plY3QgYW5kIHByb3ZpZGVzIHlvdSB3aXRoIEFQSSBhY2Nlc3MsIHF1b3RhLCBhbmQKICAgKiByZXBvcnRzLiBSZXF1aXJlZCB1bmxlc3MgeW91IHByb3ZpZGUgYW4gT0F1dGggMi4wIHRva2VuLgogICAqLwogIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldEtleSgpIHsKICAgIHJldHVybiBrZXk7CiAgfQoKICAvKioKICAgKiBBUEkga2V5LiBZb3VyIEFQSSBrZXkgaWRlbnRpZmllcyB5b3VyIHByb2plY3QgYW5kIHByb3ZpZGVzIHlvdSB3aXRoIEFQSSBhY2Nlc3MsIHF1b3RhLCBhbmQKICAgKiByZXBvcnRzLiBSZXF1aXJlZCB1bmxlc3MgeW91IHByb3ZpZGUgYW4gT0F1dGggMi4wIHRva2VuLgogICAqLwogIHB1YmxpYyBDbG91ZFJlc291cmNlTWFuYWdlclJlcXVlc3Q8VD4gc2V0S2V5KGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICB0aGlzLmtleSA9IGtleTsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgLyoqIE9BdXRoIDIuMCB0b2tlbiBmb3IgdGhlIGN1cnJlbnQgdXNlci4gKi8KICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5KCJvYXV0aF90b2tlbiIpCiAgcHJpdmF0ZSBqYXZhLmxhbmcuU3RyaW5nIG9hdXRoVG9rZW47CgogIC8qKgogICAqIE9BdXRoIDIuMCB0b2tlbiBmb3IgdGhlIGN1cnJlbnQgdXNlci4KICAgKi8KICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRPYXV0aFRva2VuKCkgewogICAgcmV0dXJuIG9hdXRoVG9rZW47CiAgfQoKICAvKiogT0F1dGggMi4wIHRva2VuIGZvciB0aGUgY3VycmVudCB1c2VyLiAqLwogIHB1YmxpYyBDbG91ZFJlc291cmNlTWFuYWdlclJlcXVlc3Q8VD4gc2V0T2F1dGhUb2tlbihqYXZhLmxhbmcuU3RyaW5nIG9hdXRoVG9rZW4pIHsKICAgIHRoaXMub2F1dGhUb2tlbiA9IG9hdXRoVG9rZW47CiAgICByZXR1cm4gdGhpczsKICB9CgogIC8qKiBSZXR1cm5zIHJlc3BvbnNlIHdpdGggaW5kZW50YXRpb25zIGFuZCBsaW5lIGJyZWFrcy4gKi8KICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgcHJpdmF0ZSBqYXZhLmxhbmcuQm9vbGVhbiBwcmV0dHlQcmludDsKCiAgLyoqCiAgICogUmV0dXJucyByZXNwb25zZSB3aXRoIGluZGVudGF0aW9ucyBhbmQgbGluZSBicmVha3MuIFtkZWZhdWx0OiB0cnVlXQogICAqLwogIHB1YmxpYyBqYXZhLmxhbmcuQm9vbGVhbiBnZXRQcmV0dHlQcmludCgpIHsKICAgIHJldHVybiBwcmV0dHlQcmludDsKICB9CgogIC8qKiBSZXR1cm5zIHJlc3BvbnNlIHdpdGggaW5kZW50YXRpb25zIGFuZCBsaW5lIGJyZWFrcy4gKi8KICBwdWJsaWMgQ2xvdWRSZXNvdXJjZU1hbmFnZXJSZXF1ZXN0PFQ+IHNldFByZXR0eVByaW50KGphdmEubGFuZy5Cb29sZWFuIHByZXR0eVByaW50KSB7CiAgICB0aGlzLnByZXR0eVByaW50ID0gcHJldHR5UHJpbnQ7CiAgICByZXR1cm4gdGhpczsKICB9CgogIC8qKgogICAqIEF2YWlsYWJsZSB0byB1c2UgZm9yIHF1b3RhIHB1cnBvc2VzIGZvciBzZXJ2ZXItc2lkZSBhcHBsaWNhdGlvbnMuIENhbiBiZSBhbnkgYXJiaXRyYXJ5IHN0cmluZwogICAqIGFzc2lnbmVkIHRvIGEgdXNlciwgYnV0IHNob3VsZCBub3QgZXhjZWVkIDQwIGNoYXJhY3RlcnMuCiAgICovCiAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogIHByaXZhdGUgamF2YS5sYW5nLlN0cmluZyBxdW90YVVzZXI7CgogIC8qKgogICAqIEF2YWlsYWJsZSB0byB1c2UgZm9yIHF1b3RhIHB1cnBvc2VzIGZvciBzZXJ2ZXItc2lkZSBhcHBsaWNhdGlvbnMuIENhbiBiZSBhbnkgYXJiaXRyYXJ5IHN0cmluZwogICAqIGFzc2lnbmVkIHRvIGEgdXNlciwgYnV0IHNob3VsZCBub3QgZXhjZWVkIDQwIGNoYXJhY3RlcnMuCiAgICovCiAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0UXVvdGFVc2VyKCkgewogICAgcmV0dXJuIHF1b3RhVXNlcjsKICB9CgogIC8qKgogICAqIEF2YWlsYWJsZSB0byB1c2UgZm9yIHF1b3RhIHB1cnBvc2VzIGZvciBzZXJ2ZXItc2lkZSBhcHBsaWNhdGlvbnMuIENhbiBiZSBhbnkgYXJiaXRyYXJ5IHN0cmluZwogICAqIGFzc2lnbmVkIHRvIGEgdXNlciwgYnV0IHNob3VsZCBub3QgZXhjZWVkIDQwIGNoYXJhY3RlcnMuCiAgICovCiAgcHVibGljIENsb3VkUmVzb3VyY2VNYW5hZ2VyUmVxdWVzdDxUPiBzZXRRdW90YVVzZXIoamF2YS5sYW5nLlN0cmluZyBxdW90YVVzZXIpIHsKICAgIHRoaXMucXVvdGFVc2VyID0gcXVvdGFVc2VyOwogICAgcmV0dXJuIHRoaXM7CiAgfQoKICAvKiogTGVnYWN5IHVwbG9hZCBwcm90b2NvbCBmb3IgbWVkaWEgKGUuZy4gIm1lZGlhIiwgIm11bHRpcGFydCIpLiAqLwogIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICBwcml2YXRlIGphdmEubGFuZy5TdHJpbmcgdXBsb2FkVHlwZTsKCiAgLyoqCiAgICogTGVnYWN5IHVwbG9hZCBwcm90b2NvbCBmb3IgbWVkaWEgKGUuZy4gIm1lZGlhIiwgIm11bHRpcGFydCIpLgogICAqLwogIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFVwbG9hZFR5cGUoKSB7CiAgICByZXR1cm4gdXBsb2FkVHlwZTsKICB9CgogIC8qKiBMZWdhY3kgdXBsb2FkIHByb3RvY29sIGZvciBtZWRpYSAoZS5nLiAibWVkaWEiLCAibXVsdGlwYXJ0IikuICovCiAgcHVibGljIENsb3VkUmVzb3VyY2VNYW5hZ2VyUmVxdWVzdDxUPiBzZXRVcGxvYWRUeXBlKGphdmEubGFuZy5TdHJpbmcgdXBsb2FkVHlwZSkgewogICAgdGhpcy51cGxvYWRUeXBlID0gdXBsb2FkVHlwZTsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgLyoqIFVwbG9hZCBwcm90b2NvbCBmb3IgbWVkaWEgKGUuZy4gInJhdyIsICJtdWx0aXBhcnQiKS4gKi8KICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5KCJ1cGxvYWRfcHJvdG9jb2wiKQogIHByaXZhdGUgamF2YS5sYW5nLlN0cmluZyB1cGxvYWRQcm90b2NvbDsKCiAgLyoqCiAgICogVXBsb2FkIHByb3RvY29sIGZvciBtZWRpYSAoZS5nLiAicmF3IiwgIm11bHRpcGFydCIpLgogICAqLwogIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFVwbG9hZFByb3RvY29sKCkgewogICAgcmV0dXJuIHVwbG9hZFByb3RvY29sOwogIH0KCiAgLyoqIFVwbG9hZCBwcm90b2NvbCBmb3IgbWVkaWEgKGUuZy4gInJhdyIsICJtdWx0aXBhcnQiKS4gKi8KICBwdWJsaWMgQ2xvdWRSZXNvdXJjZU1hbmFnZXJSZXF1ZXN0PFQ+IHNldFVwbG9hZFByb3RvY29sKGphdmEubGFuZy5TdHJpbmcgdXBsb2FkUHJvdG9jb2wpIHsKICAgIHRoaXMudXBsb2FkUHJvdG9jb2wgPSB1cGxvYWRQcm90b2NvbDsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgQE92ZXJyaWRlCiAgcHVibGljIGZpbmFsIENsb3VkUmVzb3VyY2VNYW5hZ2VyIGdldEFic3RyYWN0R29vZ2xlQ2xpZW50KCkgewogICAgcmV0dXJuIChDbG91ZFJlc291cmNlTWFuYWdlcikgc3VwZXIuZ2V0QWJzdHJhY3RHb29nbGVDbGllbnQoKTsKICB9CgogIEBPdmVycmlkZQogIHB1YmxpYyBDbG91ZFJlc291cmNlTWFuYWdlclJlcXVlc3Q8VD4gc2V0RGlzYWJsZUdaaXBDb250ZW50KGJvb2xlYW4gZGlzYWJsZUdaaXBDb250ZW50KSB7CiAgICByZXR1cm4gKENsb3VkUmVzb3VyY2VNYW5hZ2VyUmVxdWVzdDxUPikgc3VwZXIuc2V0RGlzYWJsZUdaaXBDb250ZW50KGRpc2FibGVHWmlwQ29udGVudCk7CiAgfQoKICBAT3ZlcnJpZGUKICBwdWJsaWMgQ2xvdWRSZXNvdXJjZU1hbmFnZXJSZXF1ZXN0PFQ+IHNldFJlcXVlc3RIZWFkZXJzKGNvbS5nb29nbGUuYXBpLmNsaWVudC5odHRwLkh0dHBIZWFkZXJzIGhlYWRlcnMpIHsKICAgIHJldHVybiAoQ2xvdWRSZXNvdXJjZU1hbmFnZXJSZXF1ZXN0PFQ+KSBzdXBlci5zZXRSZXF1ZXN0SGVhZGVycyhoZWFkZXJzKTsKICB9CgogIEBPdmVycmlkZQogIHB1YmxpYyBDbG91ZFJlc291cmNlTWFuYWdlclJlcXVlc3Q8VD4gc2V0KFN0cmluZyBwYXJhbWV0ZXJOYW1lLCBPYmplY3QgdmFsdWUpIHsKICAgIHJldHVybiAoQ2xvdWRSZXNvdXJjZU1hbmFnZXJSZXF1ZXN0PFQ+KSBzdXBlci5zZXQocGFyYW1ldGVyTmFtZSwgdmFsdWUpOwogIH0KfQpQSwMEFAAAAAAAAAAhADAWWkOcmgMAnJoDAEYAAABjb20vZ29vZ2xlL2FwaS9zZXJ2aWNlcy9jbG91ZHJlc291cmNlbWFuYWdlci9DbG91ZFJlc291cmNlTWFuYWdlci5qYXZhLyoKICogQ29weXJpZ2h0IDIwMTAgR29vZ2xlIEluYy4KICoKICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0CiAqIGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4gWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlCiAqIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcwogKiBvciBpbXBsaWVkLiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zIHVuZGVyCiAqIHRoZSBMaWNlbnNlLgogKi8KLyoKICogVGhpcyBjb2RlIHdhcyBnZW5lcmF0ZWQgYnkgaHR0cHM6Ly9naXRodWIuY29tL2dvb2dsZS9hcGlzLWNsaWVudC1nZW5lcmF0b3IvCiAqIChidWlsZDogMjAxOC0xMC0wOCAxNzo0NTozOSBVVEMpCiAqIG9uIDIwMjAtMDMtMTkgYXQgMDI6Mzg6MzAgVVRDIAogKiBNb2RpZnkgYXQgeW91ciBvd24gcmlzay4KICovCgpwYWNrYWdlIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmNsb3VkcmVzb3VyY2VtYW5hZ2VyOwoKLyoqCiAqIFNlcnZpY2UgZGVmaW5pdGlvbiBmb3IgQ2xvdWRSZXNvdXJjZU1hbmFnZXIgKHYxKS4KICoKICogPHA+CiAqIENyZWF0ZXMsIHJlYWRzLCBhbmQgdXBkYXRlcyBtZXRhZGF0YSBmb3IgR29vZ2xlIENsb3VkIFBsYXRmb3JtIHJlc291cmNlIGNvbnRhaW5lcnMuCiAqIDwvcD4KICoKICogPHA+CiAqIEZvciBtb3JlIGluZm9ybWF0aW9uIGFib3V0IHRoaXMgc2VydmljZSwgc2VlIHRoZQogKiA8YSBocmVmPSJodHRwczovL2Nsb3VkLmdvb2dsZS5jb20vcmVzb3VyY2UtbWFuYWdlciIgdGFyZ2V0PSJfYmxhbmsiPkFQSSBEb2N1bWVudGF0aW9uPC9hPgogKiA8L3A+CiAqCiAqIDxwPgogKiBUaGlzIHNlcnZpY2UgdXNlcyB7QGxpbmsgQ2xvdWRSZXNvdXJjZU1hbmFnZXJSZXF1ZXN0SW5pdGlhbGl6ZXJ9IHRvIGluaXRpYWxpemUgZ2xvYmFsIHBhcmFtZXRlcnMgdmlhIGl0cwogKiB7QGxpbmsgQnVpbGRlcn0uCiAqIDwvcD4KICoKICogQHNpbmNlIDEuMwogKiBAYXV0aG9yIEdvb2dsZSwgSW5jLgogKi8KQFN1cHByZXNzV2FybmluZ3MoImphdmFkb2MiKQpwdWJsaWMgY2xhc3MgQ2xvdWRSZXNvdXJjZU1hbmFnZXIgZXh0ZW5kcyBjb20uZ29vZ2xlLmFwaS5jbGllbnQuZ29vZ2xlYXBpcy5zZXJ2aWNlcy5qc29uLkFic3RyYWN0R29vZ2xlSnNvbkNsaWVudCB7CgogIC8vIE5vdGU6IExlYXZlIHRoaXMgc3RhdGljIGluaXRpYWxpemVyIGF0IHRoZSB0b3Agb2YgdGhlIGZpbGUuCiAgc3RhdGljIHsKICAgIGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLlByZWNvbmRpdGlvbnMuY2hlY2tTdGF0ZSgKICAgICAgICBjb20uZ29vZ2xlLmFwaS5jbGllbnQuZ29vZ2xlYXBpcy5Hb29nbGVVdGlscy5NQUpPUl9WRVJTSU9OID09IDEgJiYKICAgICAgICBjb20uZ29vZ2xlLmFwaS5jbGllbnQuZ29vZ2xlYXBpcy5Hb29nbGVVdGlscy5NSU5PUl9WRVJTSU9OID49IDE1LAogICAgICAgICJZb3UgYXJlIGN1cnJlbnRseSBydW5uaW5nIHdpdGggdmVyc2lvbiAlcyBvZiBnb29nbGUtYXBpLWNsaWVudC4gIiArCiAgICAgICAgIllvdSBuZWVkIGF0IGxlYXN0IHZlcnNpb24gMS4xNSBvZiBnb29nbGUtYXBpLWNsaWVudCB0byBydW4gdmVyc2lvbiAiICsKICAgICAgICAiMS4yNS4wIG9mIHRoZSBDbG91ZCBSZXNvdXJjZSBNYW5hZ2VyIEFQSSBsaWJyYXJ5LiIsIGNvbS5nb29nbGUuYXBpLmNsaWVudC5nb29nbGVhcGlzLkdvb2dsZVV0aWxzLlZFUlNJT04pOwogIH0KCiAgLyoqCiAgICogVGhlIGRlZmF1bHQgZW5jb2RlZCByb290IFVSTCBvZiB0aGUgc2VydmljZS4gVGhpcyBpcyBkZXRlcm1pbmVkIHdoZW4gdGhlIGxpYnJhcnkgaXMgZ2VuZXJhdGVkCiAgICogYW5kIG5vcm1hbGx5IHNob3VsZCBub3QgYmUgY2hhbmdlZC4KICAgKgogICAqIEBzaW5jZSAxLjcKICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBERUZBVUxUX1JPT1RfVVJMID0gImh0dHBzOi8vY2xvdWRyZXNvdXJjZW1hbmFnZXIuZ29vZ2xlYXBpcy5jb20vIjsKCiAgLyoqCiAgICogVGhlIGRlZmF1bHQgZW5jb2RlZCBzZXJ2aWNlIHBhdGggb2YgdGhlIHNlcnZpY2UuIFRoaXMgaXMgZGV0ZXJtaW5lZCB3aGVuIHRoZSBsaWJyYXJ5IGlzCiAgICogZ2VuZXJhdGVkIGFuZCBub3JtYWxseSBzaG91bGQgbm90IGJlIGNoYW5nZWQuCiAgICoKICAgKiBAc2luY2UgMS43CiAgICovCiAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgREVGQVVMVF9TRVJWSUNFX1BBVEggPSAiIjsKCiAgLyoqCiAgICogVGhlIGRlZmF1bHQgZW5jb2RlZCBiYXRjaCBwYXRoIG9mIHRoZSBzZXJ2aWNlLiBUaGlzIGlzIGRldGVybWluZWQgd2hlbiB0aGUgbGlicmFyeSBpcwogICAqIGdlbmVyYXRlZCBhbmQgbm9ybWFsbHkgc2hvdWxkIG5vdCBiZSBjaGFuZ2VkLgogICAqCiAgICogQHNpbmNlIDEuMjMKICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBERUZBVUxUX0JBVENIX1BBVEggPSAiYmF0Y2giOwoKICAvKioKICAgKiBUaGUgZGVmYXVsdCBlbmNvZGVkIGJhc2UgVVJMIG9mIHRoZSBzZXJ2aWNlLiBUaGlzIGlzIGRldGVybWluZWQgd2hlbiB0aGUgbGlicmFyeSBpcyBnZW5lcmF0ZWQKICAgKiBhbmQgbm9ybWFsbHkgc2hvdWxkIG5vdCBiZSBjaGFuZ2VkLgogICAqLwogIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIERFRkFVTFRfQkFTRV9VUkwgPSBERUZBVUxUX1JPT1RfVVJMICsgREVGQVVMVF9TRVJWSUNFX1BBVEg7CgogIC8qKgogICAqIENvbnN0cnVjdG9yLgogICAqCiAgICogPHA+CiAgICogVXNlIHtAbGluayBCdWlsZGVyfSBpZiB5b3UgbmVlZCB0byBzcGVjaWZ5IGFueSBvZiB0aGUgb3B0aW9uYWwgcGFyYW1ldGVycy4KICAgKiA8L3A+CiAgICoKICAgKiBAcGFyYW0gdHJhbnNwb3J0IEhUVFAgdHJhbnNwb3J0LCB3aGljaCBzaG91bGQgbm9ybWFsbHkgYmU6CiAgICogICAgICAgIDx1bD4KICAgKiAgICAgICAgPGxpPkdvb2dsZSBBcHAgRW5naW5lOgogICAqICAgICAgICB7QGNvZGUgY29tLmdvb2dsZS5hcGkuY2xpZW50LmV4dGVuc2lvbnMuYXBwZW5naW5lLmh0dHAuVXJsRmV0Y2hUcmFuc3BvcnR9PC9saT4KICAgKiAgICAgICAgPGxpPkFuZHJvaWQ6IHtAY29kZSBuZXdDb21wYXRpYmxlVHJhbnNwb3J0fSBmcm9tCiAgICogICAgICAgIHtAY29kZSBjb20uZ29vZ2xlLmFwaS5jbGllbnQuZXh0ZW5zaW9ucy5hbmRyb2lkLmh0dHAuQW5kcm9pZEh0dHB9PC9saT4KICAgKiAgICAgICAgPGxpPkphdmE6IHtAbGluayBjb20uZ29vZ2xlLmFwaS5jbGllbnQuZ29vZ2xlYXBpcy5qYXZhbmV0Lkdvb2dsZU5ldEh0dHBUcmFuc3BvcnQjbmV3VHJ1c3RlZFRyYW5zcG9ydCgpfQogICAqICAgICAgICA8L2xpPgogICAqICAgICAgICA8L3VsPgogICAqIEBwYXJhbSBqc29uRmFjdG9yeSBKU09OIGZhY3RvcnksIHdoaWNoIG1heSBiZToKICAgKiAgICAgICAgPHVsPgogICAqICAgICAgICA8bGk+SmFja3Nvbjoge0Bjb2RlIGNvbS5nb29nbGUuYXBpLmNsaWVudC5qc29uLmphY2tzb24yLkphY2tzb25GYWN0b3J5fTwvbGk+CiAgICogICAgICAgIDxsaT5Hb29nbGUgR1NPTjoge0Bjb2RlIGNvbS5nb29nbGUuYXBpLmNsaWVudC5qc29uLmdzb24uR3NvbkZhY3Rvcnl9PC9saT4KICAgKiAgICAgICAgPGxpPkFuZHJvaWQgSG9uZXljb21iIG9yIGhpZ2hlcjoKICAgKiAgICAgICAge0Bjb2RlIGNvbS5nb29nbGUuYXBpLmNsaWVudC5leHRlbnNpb25zLmFuZHJvaWQuanNvbi5BbmRyb2lkSnNvbkZhY3Rvcnl9PC9saT4KICAgKiAgICAgICAgPC91bD4KICAgKiBAcGFyYW0gaHR0cFJlcXVlc3RJbml0aWFsaXplciBIVFRQIHJlcXVlc3QgaW5pdGlhbGl6ZXIgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICogQHNpbmNlIDEuNwogICAqLwogIHB1YmxpYyBDbG91ZFJlc291cmNlTWFuYWdlcihjb20uZ29vZ2xlLmFwaS5jbGllbnQuaHR0cC5IdHRwVHJhbnNwb3J0IHRyYW5zcG9ydCwgY29tLmdvb2dsZS5hcGkuY2xpZW50Lmpzb24uSnNvbkZhY3RvcnkganNvbkZhY3RvcnksCiAgICAgIGNvbS5nb29nbGUuYXBpLmNsaWVudC5odHRwLkh0dHBSZXF1ZXN0SW5pdGlhbGl6ZXIgaHR0cFJlcXVlc3RJbml0aWFsaXplcikgewogICAgdGhpcyhuZXcgQnVpbGRlcih0cmFuc3BvcnQsIGpzb25GYWN0b3J5LCBodHRwUmVxdWVzdEluaXRpYWxpemVyKSk7CiAgfQoKICAvKioKICAgKiBAcGFyYW0gYnVpbGRlciBidWlsZGVyCiAgICovCiAgQ2xvdWRSZXNvdXJjZU1hbmFnZXIoQnVpbGRlciBidWlsZGVyKSB7CiAgICBzdXBlcihidWlsZGVyKTsKICB9CgogIEBPdmVycmlkZQogIHByb3RlY3RlZCB2b2lkIGluaXRpYWxpemUoY29tLmdvb2dsZS5hcGkuY2xpZW50Lmdvb2dsZWFwaXMuc2VydmljZXMuQWJzdHJhY3RHb29nbGVDbGllbnRSZXF1ZXN0PD8+IGh0dHBDbGllbnRSZXF1ZXN0KSB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICBzdXBlci5pbml0aWFsaXplKGh0dHBDbGllbnRSZXF1ZXN0KTsKICB9CgogIC8qKgogICAqIEFuIGFjY2Vzc29yIGZvciBjcmVhdGluZyByZXF1ZXN0cyBmcm9tIHRoZSBGb2xkZXJzIGNvbGxlY3Rpb24uCiAgICoKICAgKiA8cD5UaGUgdHlwaWNhbCB1c2UgaXM6PC9wPgogICAqIDxwcmU+CiAgICogICB7QGNvZGUgQ2xvdWRSZXNvdXJjZU1hbmFnZXIgY2xvdWRyZXNvdXJjZW1hbmFnZXIgPSBuZXcgQ2xvdWRSZXNvdXJjZU1hbmFnZXIoLi4uKTt9CiAgICogICB7QGNvZGUgQ2xvdWRSZXNvdXJjZU1hbmFnZXIuRm9sZGVycy5MaXN0IHJlcXVlc3QgPSBjbG91ZHJlc291cmNlbWFuYWdlci5mb2xkZXJzKCkubGlzdChwYXJhbWV0ZXJzIC4uLil9CiAgICogPC9wcmU+CiAgICoKICAgKiBAcmV0dXJuIHRoZSByZXNvdXJjZSBjb2xsZWN0aW9uCiAgICovCiAgcHVibGljIEZvbGRlcnMgZm9sZGVycygpIHsKICAgIHJldHVybiBuZXcgRm9sZGVycygpOwogIH0KCiAgLyoqCiAgICogVGhlICJmb2xkZXJzIiBjb2xsZWN0aW9uIG9mIG1ldGhvZHMuCiAgICovCiAgcHVibGljIGNsYXNzIEZvbGRlcnMgewoKICAgIC8qKgogICAgICogQ2xlYXJzIGEgYFBvbGljeWAgZnJvbSBhIHJlc291cmNlLgogICAgICoKICAgICAqIENyZWF0ZSBhIHJlcXVlc3QgZm9yIHRoZSBtZXRob2QgImZvbGRlcnMuY2xlYXJPcmdQb2xpY3kiLgogICAgICoKICAgICAqIFRoaXMgcmVxdWVzdCBob2xkcyB0aGUgcGFyYW1ldGVycyBuZWVkZWQgYnkgdGhlIGNsb3VkcmVzb3VyY2VtYW5hZ2VyIHNlcnZlci4gIEFmdGVyIHNldHRpbmcgYW55CiAgICAgKiBvcHRpb25hbCBwYXJhbWV0ZXJzLCBjYWxsIHRoZSB7QGxpbmsgQ2xlYXJPcmdQb2xpY3kjZXhlY3V0ZSgpfSBtZXRob2QgdG8gaW52b2tlIHRoZSByZW1vdGUKICAgICAqIG9wZXJhdGlvbi4KICAgICAqCiAgICAgKiBAcGFyYW0gcmVzb3VyY2UgTmFtZSBvZiB0aGUgcmVzb3VyY2UgZm9yIHRoZSBgUG9saWN5YCB0byBjbGVhci4KICAgICAqIEBwYXJhbSBjb250ZW50IHRoZSB7QGxpbmsgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuY2xvdWRyZXNvdXJjZW1hbmFnZXIubW9kZWwuQ2xlYXJPcmdQb2xpY3lSZXF1ZXN0fQogICAgICogQHJldHVybiB0aGUgcmVxdWVzdAogICAgICovCiAgICBwdWJsaWMgQ2xlYXJPcmdQb2xpY3kgY2xlYXJPcmdQb2xpY3koamF2YS5sYW5nLlN0cmluZyByZXNvdXJjZSwgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuY2xvdWRyZXNvdXJjZW1hbmFnZXIubW9kZWwuQ2xlYXJPcmdQb2xpY3lSZXF1ZXN0IGNvbnRlbnQpIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgQ2xlYXJPcmdQb2xpY3kgcmVzdWx0ID0gbmV3IENsZWFyT3JnUG9saWN5KHJlc291cmNlLCBjb250ZW50KTsKICAgICAgaW5pdGlhbGl6ZShyZXN1bHQpOwogICAgICByZXR1cm4gcmVzdWx0OwogICAgfQoKICAgIHB1YmxpYyBjbGFzcyBDbGVhck9yZ1BvbGljeSBleHRlbmRzIENsb3VkUmVzb3VyY2VNYW5hZ2VyUmVxdWVzdDxjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5jbG91ZHJlc291cmNlbWFuYWdlci5tb2RlbC5FbXB0eT4gewoKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFJFU1RfUEFUSCA9ICJ2MS97K3Jlc291cmNlfTpjbGVhck9yZ1BvbGljeSI7CgogICAgICBwcml2YXRlIGZpbmFsIGphdmEudXRpbC5yZWdleC5QYXR0ZXJuIFJFU09VUkNFX1BBVFRFUk4gPQogICAgICAgICAgamF2YS51dGlsLnJlZ2V4LlBhdHRlcm4uY29tcGlsZSgiXmZvbGRlcnMvW14vXSskIik7CgogICAgICAvKioKICAgICAgICogQ2xlYXJzIGEgYFBvbGljeWAgZnJvbSBhIHJlc291cmNlLgogICAgICAgKgogICAgICAgKiBDcmVhdGUgYSByZXF1ZXN0IGZvciB0aGUgbWV0aG9kICJmb2xkZXJzLmNsZWFyT3JnUG9saWN5Ii4KICAgICAgICoKICAgICAgICogVGhpcyByZXF1ZXN0IGhvbGRzIHRoZSBwYXJhbWV0ZXJzIG5lZWRlZCBieSB0aGUgdGhlIGNsb3VkcmVzb3VyY2VtYW5hZ2VyIHNlcnZlci4gIEFmdGVyIHNldHRpbmcKICAgICAgICogYW55IG9wdGlvbmFsIHBhcmFtZXRlcnMsIGNhbGwgdGhlIHtAbGluayBDbGVhck9yZ1BvbGljeSNleGVjdXRlKCl9IG1ldGhvZCB0byBpbnZva2UgdGhlIHJlbW90ZQogICAgICAgKiBvcGVyYXRpb24uIDxwPiB7QGxpbmsgQ2xlYXJPcmdQb2xpY3kjaW5pdGlhbGl6ZShjb20uZ29vZ2xlLmFwaS5jbGllbnQuZ29vZ2xlYXBpcy5zZXJ2aWNlcy5BYnN0cgogICAgICAgKiBhY3RHb29nbGVDbGllbnRSZXF1ZXN0KX0gbXVzdCBiZSBjYWxsZWQgdG8gaW5pdGlhbGl6ZSB0aGlzIGluc3RhbmNlIGltbWVkaWF0ZWx5IGFmdGVyIGludm9raW5nCiAgICAgICAqIHRoZSBjb25zdHJ1Y3Rvci4gPC9wPgogICAgICAgKgogICAgICAgKiBAcGFyYW0gcmVzb3VyY2UgTmFtZSBvZiB0aGUgcmVzb3VyY2UgZm9yIHRoZSBgUG9saWN5YCB0byBjbGVhci4KICAgICAgICogQHBhcmFtIGNvbnRlbnQgdGhlIHtAbGluayBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5jbG91ZHJlc291cmNlbWFuYWdlci5tb2RlbC5DbGVhck9yZ1BvbGljeVJlcXVlc3R9CiAgICAgICAqIEBzaW5jZSAxLjEzCiAgICAgICAqLwogICAgICBwcm90ZWN0ZWQgQ2xlYXJPcmdQb2xpY3koamF2YS5sYW5nLlN0cmluZyByZXNvdXJjZSwgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuY2xvdWRyZXNvdXJjZW1hbmFnZXIubW9kZWwuQ2xlYXJPcmdQb2xpY3lSZXF1ZXN0IGNvbnRlbnQpIHsKICAgICAgICBzdXBlcihDbG91ZFJlc291cmNlTWFuYWdlci50aGlzLCAiUE9TVCIsIFJFU1RfUEFUSCwgY29udGVudCwgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuY2xvdWRyZXNvdXJjZW1hbmFnZXIubW9kZWwuRW1wdHkuY2xhc3MpOwogICAgICAgIHRoaXMucmVzb3VyY2UgPSBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5QcmVjb25kaXRpb25zLmNoZWNrTm90TnVsbChyZXNvdXJjZSwgIlJlcXVpcmVkIHBhcmFtZXRlciByZXNvdXJjZSBtdXN0IGJlIHNwZWNpZmllZC4iKTsKICAgICAgICBpZiAoIWdldFN1cHByZXNzUGF0dGVybkNoZWNrcygpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5QcmVjb25kaXRpb25zLmNoZWNrQXJndW1lbnQoUkVTT1VSQ0VfUEFUVEVSTi5tYXRjaGVyKHJlc291cmNlKS5tYXRjaGVzKCksCiAgICAgICAgICAgICAgIlBhcmFtZXRlciByZXNvdXJjZSBtdXN0IGNvbmZvcm0gdG8gdGhlIHBhdHRlcm4gIiArCiAgICAgICAgICAgICAgIl5mb2xkZXJzL1teL10rJCIpOwogICAgICAgIH0KICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBDbGVhck9yZ1BvbGljeSBzZXQkWGdhZnYoamF2YS5sYW5nLlN0cmluZyAkWGdhZnYpIHsKICAgICAgICByZXR1cm4gKENsZWFyT3JnUG9saWN5KSBzdXBlci5zZXQkWGdhZnYoJFhnYWZ2KTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBDbGVhck9yZ1BvbGljeSBzZXRBY2Nlc3NUb2tlbihqYXZhLmxhbmcuU3RyaW5nIGFjY2Vzc1Rva2VuKSB7CiAgICAgICAgcmV0dXJuIChDbGVhck9yZ1BvbGljeSkgc3VwZXIuc2V0QWNjZXNzVG9rZW4oYWNjZXNzVG9rZW4pOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIENsZWFyT3JnUG9saWN5IHNldEFsdChqYXZhLmxhbmcuU3RyaW5nIGFsdCkgewogICAgICAgIHJldHVybiAoQ2xlYXJPcmdQb2xpY3kpIHN1cGVyLnNldEFsdChhbHQpOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIENsZWFyT3JnUG9saWN5IHNldENhbGxiYWNrKGphdmEubGFuZy5TdHJpbmcgY2FsbGJhY2spIHsKICAgICAgICByZXR1cm4gKENsZWFyT3JnUG9saWN5KSBzdXBlci5zZXRDYWxsYmFjayhjYWxsYmFjayk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgQ2xlYXJPcmdQb2xpY3kgc2V0RmllbGRzKGphdmEubGFuZy5TdHJpbmcgZmllbGRzKSB7CiAgICAgICAgcmV0dXJuIChDbGVhck9yZ1BvbGljeSkgc3VwZXIuc2V0RmllbGRzKGZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgQ2xlYXJPcmdQb2xpY3kgc2V0S2V5KGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgcmV0dXJuIChDbGVhck9yZ1BvbGljeSkgc3VwZXIuc2V0S2V5KGtleSk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgQ2xlYXJPcmdQb2xpY3kgc2V0T2F1dGhUb2tlbihqYXZhLmxhbmcuU3RyaW5nIG9hdXRoVG9rZW4pIHsKICAgICAgICByZXR1cm4gKENsZWFyT3JnUG9saWN5KSBzdXBlci5zZXRPYXV0aFRva2VuKG9hdXRoVG9rZW4pOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIENsZWFyT3JnUG9saWN5IHNldFByZXR0eVByaW50KGphdmEubGFuZy5Cb29sZWFuIHByZXR0eVByaW50KSB7CiAgICAgICAgcmV0dXJuIChDbGVhck9yZ1BvbGljeSkgc3VwZXIuc2V0UHJldHR5UHJpbnQocHJldHR5UHJpbnQpOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIENsZWFyT3JnUG9saWN5IHNldFF1b3RhVXNlcihqYXZhLmxhbmcuU3RyaW5nIHF1b3RhVXNlcikgewogICAgICAgIHJldHVybiAoQ2xlYXJPcmdQb2xpY3kpIHN1cGVyLnNldFF1b3RhVXNlcihxdW90YVVzZXIpOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIENsZWFyT3JnUG9saWN5IHNldFVwbG9hZFR5cGUoamF2YS5sYW5nLlN0cmluZyB1cGxvYWRUeXBlKSB7CiAgICAgICAgcmV0dXJuIChDbGVhck9yZ1BvbGljeSkgc3VwZXIuc2V0VXBsb2FkVHlwZSh1cGxvYWRUeXBlKTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBDbGVhck9yZ1BvbGljeSBzZXRVcGxvYWRQcm90b2NvbChqYXZhLmxhbmcuU3RyaW5nIHVwbG9hZFByb3RvY29sKSB7CiAgICAgICAgcmV0dXJuIChDbGVhck9yZ1BvbGljeSkgc3VwZXIuc2V0VXBsb2FkUHJvdG9jb2wodXBsb2FkUHJvdG9jb2wpOwogICAgICB9CgogICAgICAvKiogTmFtZSBvZiB0aGUgcmVzb3VyY2UgZm9yIHRoZSBgUG9saWN5YCB0byBjbGVhci4gKi8KICAgICAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogICAgICBwcml2YXRlIGphdmEubGFuZy5TdHJpbmcgcmVzb3VyY2U7CgogICAgICAvKiogTmFtZSBvZiB0aGUgcmVzb3VyY2UgZm9yIHRoZSBgUG9saWN5YCB0byBjbGVhci4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFJlc291cmNlKCkgewogICAgICAgIHJldHVybiByZXNvdXJjZTsKICAgICAgfQoKICAgICAgLyoqIE5hbWUgb2YgdGhlIHJlc291cmNlIGZvciB0aGUgYFBvbGljeWAgdG8gY2xlYXIuICovCiAgICAgIHB1YmxpYyBDbGVhck9yZ1BvbGljeSBzZXRSZXNvdXJjZShqYXZhLmxhbmcuU3RyaW5nIHJlc291cmNlKSB7CiAgICAgICAgaWYgKCFnZXRTdXBwcmVzc1BhdHRlcm5DaGVja3MoKSkgewogICAgICAgICAgY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuUHJlY29uZGl0aW9ucy5jaGVja0FyZ3VtZW50KFJFU09VUkNFX1BBVFRFUk4ubWF0Y2hlcihyZXNvdXJjZSkubWF0Y2hlcygpLAogICAgICAgICAgICAgICJQYXJhbWV0ZXIgcmVzb3VyY2UgbXVzdCBjb25mb3JtIHRvIHRoZSBwYXR0ZXJuICIgKwogICAgICAgICAgICAgICJeZm9sZGVycy9bXi9dKyQiKTsKICAgICAgICB9CiAgICAgICAgdGhpcy5yZXNvdXJjZSA9IHJlc291cmNlOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIENsZWFyT3JnUG9saWN5IHNldChTdHJpbmcgcGFyYW1ldGVyTmFtZSwgT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIChDbGVhck9yZ1BvbGljeSkgc3VwZXIuc2V0KHBhcmFtZXRlck5hbWUsIHZhbHVlKTsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiBHZXRzIHRoZSBlZmZlY3RpdmUgYFBvbGljeWAgb24gYSByZXNvdXJjZS4gVGhpcyBpcyB0aGUgcmVzdWx0IG9mIG1lcmdpbmcgYFBvbGljaWVzYCBpbiB0aGUKICAgICAqIHJlc291cmNlIGhpZXJhcmNoeS4gVGhlIHJldHVybmVkIGBQb2xpY3lgIHdpbGwgbm90IGhhdmUgYW4gYGV0YWdgc2V0IGJlY2F1c2UgaXQgaXMgYSBjb21wdXRlZAogICAgICogYFBvbGljeWAgYWNyb3NzIG11bHRpcGxlIHJlc291cmNlcy4gU3VidHJlZXMgb2YgUmVzb3VyY2UgTWFuYWdlciByZXNvdXJjZSBoaWVyYXJjaHkgd2l0aCAndW5kZXI6JwogICAgICogcHJlZml4IHdpbGwgbm90IGJlIGV4cGFuZGVkLgogICAgICoKICAgICAqIENyZWF0ZSBhIHJlcXVlc3QgZm9yIHRoZSBtZXRob2QgImZvbGRlcnMuZ2V0RWZmZWN0aXZlT3JnUG9saWN5Ii4KICAgICAqCiAgICAgKiBUaGlzIHJlcXVlc3QgaG9sZHMgdGhlIHBhcmFtZXRlcnMgbmVlZGVkIGJ5IHRoZSBjbG91ZHJlc291cmNlbWFuYWdlciBzZXJ2ZXIuICBBZnRlciBzZXR0aW5nIGFueQogICAgICogb3B0aW9uYWwgcGFyYW1ldGVycywgY2FsbCB0aGUge0BsaW5rIEdldEVmZmVjdGl2ZU9yZ1BvbGljeSNleGVjdXRlKCl9IG1ldGhvZCB0byBpbnZva2UgdGhlIHJlbW90ZQogICAgICogb3BlcmF0aW9uLgogICAgICoKICAgICAqIEBwYXJhbSByZXNvdXJjZSBUaGUgbmFtZSBvZiB0aGUgcmVzb3VyY2UgdG8gc3RhcnQgY29tcHV0aW5nIHRoZSBlZmZlY3RpdmUgYFBvbGljeWAuCiAgICAgKiBAcGFyYW0gY29udGVudCB0aGUge0BsaW5rIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmNsb3VkcmVzb3VyY2VtYW5hZ2VyLm1vZGVsLkdldEVmZmVjdGl2ZU9yZ1BvbGljeVJlcXVlc3R9CiAgICAgKiBAcmV0dXJuIHRoZSByZXF1ZXN0CiAgICAgKi8KICAgIHB1YmxpYyBHZXRFZmZlY3RpdmVPcmdQb2xpY3kgZ2V0RWZmZWN0aXZlT3JnUG9saWN5KGphdmEubGFuZy5TdHJpbmcgcmVzb3VyY2UsIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmNsb3VkcmVzb3VyY2VtYW5hZ2VyLm1vZGVsLkdldEVmZmVjdGl2ZU9yZ1BvbGljeVJlcXVlc3QgY29udGVudCkgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBHZXRFZmZlY3RpdmVPcmdQb2xpY3kgcmVzdWx0ID0gbmV3IEdldEVmZmVjdGl2ZU9yZ1BvbGljeShyZXNvdXJjZSwgY29udGVudCk7CiAgICAgIGluaXRpYWxpemUocmVzdWx0KTsKICAgICAgcmV0dXJuIHJlc3VsdDsKICAgIH0KCiAgICBwdWJsaWMgY2xhc3MgR2V0RWZmZWN0aXZlT3JnUG9saWN5IGV4dGVuZHMgQ2xvdWRSZXNvdXJjZU1hbmFnZXJSZXF1ZXN0PGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmNsb3VkcmVzb3VyY2VtYW5hZ2VyLm1vZGVsLk9yZ1BvbGljeT4gewoKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFJFU1RfUEFUSCA9ICJ2MS97K3Jlc291cmNlfTpnZXRFZmZlY3RpdmVPcmdQb2xpY3kiOwoKICAgICAgcHJpdmF0ZSBmaW5hbCBqYXZhLnV0aWwucmVnZXguUGF0dGVybiBSRVNPVVJDRV9QQVRURVJOID0KICAgICAgICAgIGphdmEudXRpbC5yZWdleC5QYXR0ZXJuLmNvbXBpbGUoIl5mb2xkZXJzL1teL10rJCIpOwoKICAgICAgLyoqCiAgICAgICAqIEdldHMgdGhlIGVmZmVjdGl2ZSBgUG9saWN5YCBvbiBhIHJlc291cmNlLiBUaGlzIGlzIHRoZSByZXN1bHQgb2YgbWVyZ2luZyBgUG9saWNpZXNgIGluIHRoZQogICAgICAgKiByZXNvdXJjZSBoaWVyYXJjaHkuIFRoZSByZXR1cm5lZCBgUG9saWN5YCB3aWxsIG5vdCBoYXZlIGFuIGBldGFnYHNldCBiZWNhdXNlIGl0IGlzIGEgY29tcHV0ZWQKICAgICAgICogYFBvbGljeWAgYWNyb3NzIG11bHRpcGxlIHJlc291cmNlcy4gU3VidHJlZXMgb2YgUmVzb3VyY2UgTWFuYWdlciByZXNvdXJjZSBoaWVyYXJjaHkgd2l0aAogICAgICAgKiAndW5kZXI6JyBwcmVmaXggd2lsbCBub3QgYmUgZXhwYW5kZWQuCiAgICAgICAqCiAgICAgICAqIENyZWF0ZSBhIHJlcXVlc3QgZm9yIHRoZSBtZXRob2QgImZvbGRlcnMuZ2V0RWZmZWN0aXZlT3JnUG9saWN5Ii4KICAgICAgICoKICAgICAgICogVGhpcyByZXF1ZXN0IGhvbGRzIHRoZSBwYXJhbWV0ZXJzIG5lZWRlZCBieSB0aGUgdGhlIGNsb3VkcmVzb3VyY2VtYW5hZ2VyIHNlcnZlci4gIEFmdGVyIHNldHRpbmcKICAgICAgICogYW55IG9wdGlvbmFsIHBhcmFtZXRlcnMsIGNhbGwgdGhlIHtAbGluayBHZXRFZmZlY3RpdmVPcmdQb2xpY3kjZXhlY3V0ZSgpfSBtZXRob2QgdG8gaW52b2tlIHRoZQogICAgICAgKiByZW1vdGUgb3BlcmF0aW9uLiA8cD4ge0BsaW5rIEdldEVmZmVjdGl2ZU9yZ1BvbGljeSNpbml0aWFsaXplKGNvbS5nb29nbGUuYXBpLmNsaWVudC5nb29nbGVhcGlzLgogICAgICAgKiBzZXJ2aWNlcy5BYnN0cmFjdEdvb2dsZUNsaWVudFJlcXVlc3QpfSBtdXN0IGJlIGNhbGxlZCB0byBpbml0aWFsaXplIHRoaXMgaW5zdGFuY2UgaW1tZWRpYXRlbHkKICAgICAgICogYWZ0ZXIgaW52b2tpbmcgdGhlIGNvbnN0cnVjdG9yLiA8L3A+CiAgICAgICAqCiAgICAgICAqIEBwYXJhbSByZXNvdXJjZSBUaGUgbmFtZSBvZiB0aGUgcmVzb3VyY2UgdG8gc3RhcnQgY29tcHV0aW5nIHRoZSBlZmZlY3RpdmUgYFBvbGljeWAuCiAgICAgICAqIEBwYXJhbSBjb250ZW50IHRoZSB7QGxpbmsgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuY2xvdWRyZXNvdXJjZW1hbmFnZXIubW9kZWwuR2V0RWZmZWN0aXZlT3JnUG9saWN5UmVxdWVzdH0KICAgICAgICogQHNpbmNlIDEuMTMKICAgICAgICovCiAgICAgIHByb3RlY3RlZCBHZXRFZmZlY3RpdmVPcmdQb2xpY3koamF2YS5sYW5nLlN0cmluZyByZXNvdXJjZSwgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuY2xvdWRyZXNvdXJjZW1hbmFnZXIubW9kZWwuR2V0RWZmZWN0aXZlT3JnUG9saWN5UmVxdWVzdCBjb250ZW50KSB7CiAgICAgICAgc3VwZXIoQ2xvdWRSZXNvdXJjZU1hbmFnZXIudGhpcywgIlBPU1QiLCBSRVNUX1BBVEgsIGNvbnRlbnQsIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmNsb3VkcmVzb3VyY2VtYW5hZ2VyLm1vZGVsLk9yZ1BvbGljeS5jbGFzcyk7CiAgICAgICAgdGhpcy5yZXNvdXJjZSA9IGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLlByZWNvbmRpdGlvbnMuY2hlY2tOb3ROdWxsKHJlc291cmNlLCAiUmVxdWlyZWQgcGFyYW1ldGVyIHJlc291cmNlIG11c3QgYmUgc3BlY2lmaWVkLiIpOwogICAgICAgIGlmICghZ2V0U3VwcHJlc3NQYXR0ZXJuQ2hlY2tzKCkpIHsKICAgICAgICAgIGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLlByZWNvbmRpdGlvbnMuY2hlY2tBcmd1bWVudChSRVNPVVJDRV9QQVRURVJOLm1hdGNoZXIocmVzb3VyY2UpLm1hdGNoZXMoKSwKICAgICAgICAgICAgICAiUGFyYW1ldGVyIHJlc291cmNlIG11c3QgY29uZm9ybSB0byB0aGUgcGF0dGVybiAiICsKICAgICAgICAgICAgICAiXmZvbGRlcnMvW14vXSskIik7CiAgICAgICAgfQogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIEdldEVmZmVjdGl2ZU9yZ1BvbGljeSBzZXQkWGdhZnYoamF2YS5sYW5nLlN0cmluZyAkWGdhZnYpIHsKICAgICAgICByZXR1cm4gKEdldEVmZmVjdGl2ZU9yZ1BvbGljeSkgc3VwZXIuc2V0JFhnYWZ2KCRYZ2Fmdik7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgR2V0RWZmZWN0aXZlT3JnUG9saWN5IHNldEFjY2Vzc1Rva2VuKGphdmEubGFuZy5TdHJpbmcgYWNjZXNzVG9rZW4pIHsKICAgICAgICByZXR1cm4gKEdldEVmZmVjdGl2ZU9yZ1BvbGljeSkgc3VwZXIuc2V0QWNjZXNzVG9rZW4oYWNjZXNzVG9rZW4pOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIEdldEVmZmVjdGl2ZU9yZ1BvbGljeSBzZXRBbHQoamF2YS5sYW5nLlN0cmluZyBhbHQpIHsKICAgICAgICByZXR1cm4gKEdldEVmZmVjdGl2ZU9yZ1BvbGljeSkgc3VwZXIuc2V0QWx0KGFsdCk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgR2V0RWZmZWN0aXZlT3JnUG9saWN5IHNldENhbGxiYWNrKGphdmEubGFuZy5TdHJpbmcgY2FsbGJhY2spIHsKICAgICAgICByZXR1cm4gKEdldEVmZmVjdGl2ZU9yZ1BvbGljeSkgc3VwZXIuc2V0Q2FsbGJhY2soY2FsbGJhY2spOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIEdldEVmZmVjdGl2ZU9yZ1BvbGljeSBzZXRGaWVsZHMoamF2YS5sYW5nLlN0cmluZyBmaWVsZHMpIHsKICAgICAgICByZXR1cm4gKEdldEVmZmVjdGl2ZU9yZ1BvbGljeSkgc3VwZXIuc2V0RmllbGRzKGZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgR2V0RWZmZWN0aXZlT3JnUG9saWN5IHNldEtleShqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIHJldHVybiAoR2V0RWZmZWN0aXZlT3JnUG9saWN5KSBzdXBlci5zZXRLZXkoa2V5KTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBHZXRFZmZlY3RpdmVPcmdQb2xpY3kgc2V0T2F1dGhUb2tlbihqYXZhLmxhbmcuU3RyaW5nIG9hdXRoVG9rZW4pIHsKICAgICAgICByZXR1cm4gKEdldEVmZmVjdGl2ZU9yZ1BvbGljeSkgc3VwZXIuc2V0T2F1dGhUb2tlbihvYXV0aFRva2VuKTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBHZXRFZmZlY3RpdmVPcmdQb2xpY3kgc2V0UHJldHR5UHJpbnQoamF2YS5sYW5nLkJvb2xlYW4gcHJldHR5UHJpbnQpIHsKICAgICAgICByZXR1cm4gKEdldEVmZmVjdGl2ZU9yZ1BvbGljeSkgc3VwZXIuc2V0UHJldHR5UHJpbnQocHJldHR5UHJpbnQpOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIEdldEVmZmVjdGl2ZU9yZ1BvbGljeSBzZXRRdW90YVVzZXIoamF2YS5sYW5nLlN0cmluZyBxdW90YVVzZXIpIHsKICAgICAgICByZXR1cm4gKEdldEVmZmVjdGl2ZU9yZ1BvbGljeSkgc3VwZXIuc2V0UXVvdGFVc2VyKHF1b3RhVXNlcik7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgR2V0RWZmZWN0aXZlT3JnUG9saWN5IHNldFVwbG9hZFR5cGUoamF2YS5sYW5nLlN0cmluZyB1cGxvYWRUeXBlKSB7CiAgICAgICAgcmV0dXJuIChHZXRFZmZlY3RpdmVPcmdQb2xpY3kpIHN1cGVyLnNldFVwbG9hZFR5cGUodXBsb2FkVHlwZSk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgR2V0RWZmZWN0aXZlT3JnUG9saWN5IHNldFVwbG9hZFByb3RvY29sKGphdmEubGFuZy5TdHJpbmcgdXBsb2FkUHJvdG9jb2wpIHsKICAgICAgICByZXR1cm4gKEdldEVmZmVjdGl2ZU9yZ1BvbGljeSkgc3VwZXIuc2V0VXBsb2FkUHJvdG9jb2wodXBsb2FkUHJvdG9jb2wpOwogICAgICB9CgogICAgICAvKiogVGhlIG5hbWUgb2YgdGhlIHJlc291cmNlIHRvIHN0YXJ0IGNvbXB1dGluZyB0aGUgZWZmZWN0aXZlIGBQb2xpY3lgLiAqLwogICAgICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgICAgIHByaXZhdGUgamF2YS5sYW5nLlN0cmluZyByZXNvdXJjZTsKCiAgICAgIC8qKiBUaGUgbmFtZSBvZiB0aGUgcmVzb3VyY2UgdG8gc3RhcnQgY29tcHV0aW5nIHRoZSBlZmZlY3RpdmUgYFBvbGljeWAuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRSZXNvdXJjZSgpIHsKICAgICAgICByZXR1cm4gcmVzb3VyY2U7CiAgICAgIH0KCiAgICAgIC8qKiBUaGUgbmFtZSBvZiB0aGUgcmVzb3VyY2UgdG8gc3RhcnQgY29tcHV0aW5nIHRoZSBlZmZlY3RpdmUgYFBvbGljeWAuICovCiAgICAgIHB1YmxpYyBHZXRFZmZlY3RpdmVPcmdQb2xpY3kgc2V0UmVzb3VyY2UoamF2YS5sYW5nLlN0cmluZyByZXNvdXJjZSkgewogICAgICAgIGlmICghZ2V0U3VwcHJlc3NQYXR0ZXJuQ2hlY2tzKCkpIHsKICAgICAgICAgIGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLlByZWNvbmRpdGlvbnMuY2hlY2tBcmd1bWVudChSRVNPVVJDRV9QQVRURVJOLm1hdGNoZXIocmVzb3VyY2UpLm1hdGNoZXMoKSwKICAgICAgICAgICAgICAiUGFyYW1ldGVyIHJlc291cmNlIG11c3QgY29uZm9ybSB0byB0aGUgcGF0dGVybiAiICsKICAgICAgICAgICAgICAiXmZvbGRlcnMvW14vXSskIik7CiAgICAgICAgfQogICAgICAgIHRoaXMucmVzb3VyY2UgPSByZXNvdXJjZTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBHZXRFZmZlY3RpdmVPcmdQb2xpY3kgc2V0KFN0cmluZyBwYXJhbWV0ZXJOYW1lLCBPYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gKEdldEVmZmVjdGl2ZU9yZ1BvbGljeSkgc3VwZXIuc2V0KHBhcmFtZXRlck5hbWUsIHZhbHVlKTsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiBHZXRzIGEgYFBvbGljeWAgb24gYSByZXNvdXJjZS4KICAgICAqCiAgICAgKiBJZiBubyBgUG9saWN5YCBpcyBzZXQgb24gdGhlIHJlc291cmNlLCBhIGBQb2xpY3lgIGlzIHJldHVybmVkIHdpdGggZGVmYXVsdCB2YWx1ZXMgaW5jbHVkaW5nCiAgICAgKiBgUE9MSUNZX1RZUEVfTk9UX1NFVGAgZm9yIHRoZSBgcG9saWN5X3R5cGUgb25lb2ZgLiBUaGUgYGV0YWdgIHZhbHVlIGNhbiBiZSB1c2VkIHdpdGgKICAgICAqIGBTZXRPcmdQb2xpY3koKWAgdG8gY3JlYXRlIG9yIHVwZGF0ZSBhIGBQb2xpY3lgIGR1cmluZyByZWFkLW1vZGlmeS13cml0ZS4KICAgICAqCiAgICAgKiBDcmVhdGUgYSByZXF1ZXN0IGZvciB0aGUgbWV0aG9kICJmb2xkZXJzLmdldE9yZ1BvbGljeSIuCiAgICAgKgogICAgICogVGhpcyByZXF1ZXN0IGhvbGRzIHRoZSBwYXJhbWV0ZXJzIG5lZWRlZCBieSB0aGUgY2xvdWRyZXNvdXJjZW1hbmFnZXIgc2VydmVyLiAgQWZ0ZXIgc2V0dGluZyBhbnkKICAgICAqIG9wdGlvbmFsIHBhcmFtZXRlcnMsIGNhbGwgdGhlIHtAbGluayBHZXRPcmdQb2xpY3kjZXhlY3V0ZSgpfSBtZXRob2QgdG8gaW52b2tlIHRoZSByZW1vdGUKICAgICAqIG9wZXJhdGlvbi4KICAgICAqCiAgICAgKiBAcGFyYW0gcmVzb3VyY2UgTmFtZSBvZiB0aGUgcmVzb3VyY2UgdGhlIGBQb2xpY3lgIGlzIHNldCBvbi4KICAgICAqIEBwYXJhbSBjb250ZW50IHRoZSB7QGxpbmsgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuY2xvdWRyZXNvdXJjZW1hbmFnZXIubW9kZWwuR2V0T3JnUG9saWN5UmVxdWVzdH0KICAgICAqIEByZXR1cm4gdGhlIHJlcXVlc3QKICAgICAqLwogICAgcHVibGljIEdldE9yZ1BvbGljeSBnZXRPcmdQb2xpY3koamF2YS5sYW5nLlN0cmluZyByZXNvdXJjZSwgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuY2xvdWRyZXNvdXJjZW1hbmFnZXIubW9kZWwuR2V0T3JnUG9saWN5UmVxdWVzdCBjb250ZW50KSB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIEdldE9yZ1BvbGljeSByZXN1bHQgPSBuZXcgR2V0T3JnUG9saWN5KHJlc291cmNlLCBjb250ZW50KTsKICAgICAgaW5pdGlhbGl6ZShyZXN1bHQpOwogICAgICByZXR1cm4gcmVzdWx0OwogICAgfQoKICAgIHB1YmxpYyBjbGFzcyBHZXRPcmdQb2xpY3kgZXh0ZW5kcyBDbG91ZFJlc291cmNlTWFuYWdlclJlcXVlc3Q8Y29tLmdvb2dsZS5hcGkuc2VydmljZXMuY2xvdWRyZXNvdXJjZW1hbmFnZXIubW9kZWwuT3JnUG9saWN5PiB7CgogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgUkVTVF9QQVRIID0gInYxL3srcmVzb3VyY2V9OmdldE9yZ1BvbGljeSI7CgogICAgICBwcml2YXRlIGZpbmFsIGphdmEudXRpbC5yZWdleC5QYXR0ZXJuIFJFU09VUkNFX1BBVFRFUk4gPQogICAgICAgICAgamF2YS51dGlsLnJlZ2V4LlBhdHRlcm4uY29tcGlsZSgiXmZvbGRlcnMvW14vXSskIik7CgogICAgICAvKioKICAgICAgICogR2V0cyBhIGBQb2xpY3lgIG9uIGEgcmVzb3VyY2UuCiAgICAgICAqCiAgICAgICAqIElmIG5vIGBQb2xpY3lgIGlzIHNldCBvbiB0aGUgcmVzb3VyY2UsIGEgYFBvbGljeWAgaXMgcmV0dXJuZWQgd2l0aCBkZWZhdWx0IHZhbHVlcyBpbmNsdWRpbmcKICAgICAgICogYFBPTElDWV9UWVBFX05PVF9TRVRgIGZvciB0aGUgYHBvbGljeV90eXBlIG9uZW9mYC4gVGhlIGBldGFnYCB2YWx1ZSBjYW4gYmUgdXNlZCB3aXRoCiAgICAgICAqIGBTZXRPcmdQb2xpY3koKWAgdG8gY3JlYXRlIG9yIHVwZGF0ZSBhIGBQb2xpY3lgIGR1cmluZyByZWFkLW1vZGlmeS13cml0ZS4KICAgICAgICoKICAgICAgICogQ3JlYXRlIGEgcmVxdWVzdCBmb3IgdGhlIG1ldGhvZCAiZm9sZGVycy5nZXRPcmdQb2xpY3kiLgogICAgICAgKgogICAgICAgKiBUaGlzIHJlcXVlc3QgaG9sZHMgdGhlIHBhcmFtZXRlcnMgbmVlZGVkIGJ5IHRoZSB0aGUgY2xvdWRyZXNvdXJjZW1hbmFnZXIgc2VydmVyLiAgQWZ0ZXIgc2V0dGluZwogICAgICAgKiBhbnkgb3B0aW9uYWwgcGFyYW1ldGVycywgY2FsbCB0aGUge0BsaW5rIEdldE9yZ1BvbGljeSNleGVjdXRlKCl9IG1ldGhvZCB0byBpbnZva2UgdGhlIHJlbW90ZQogICAgICAgKiBvcGVyYXRpb24uIDxwPiB7QGxpbmsKICAgICAgICogR2V0T3JnUG9saWN5I2luaXRpYWxpemUoY29tLmdvb2dsZS5hcGkuY2xpZW50Lmdvb2dsZWFwaXMuc2VydmljZXMuQWJzdHJhY3RHb29nbGVDbGllbnRSZXF1ZXN0KX0KICAgICAgICogbXVzdCBiZSBjYWxsZWQgdG8gaW5pdGlhbGl6ZSB0aGlzIGluc3RhbmNlIGltbWVkaWF0ZWx5IGFmdGVyIGludm9raW5nIHRoZSBjb25zdHJ1Y3Rvci4gPC9wPgogICAgICAgKgogICAgICAgKiBAcGFyYW0gcmVzb3VyY2UgTmFtZSBvZiB0aGUgcmVzb3VyY2UgdGhlIGBQb2xpY3lgIGlzIHNldCBvbi4KICAgICAgICogQHBhcmFtIGNvbnRlbnQgdGhlIHtAbGluayBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5jbG91ZHJlc291cmNlbWFuYWdlci5tb2RlbC5HZXRPcmdQb2xpY3lSZXF1ZXN0fQogICAgICAgKiBAc2luY2UgMS4xMwogICAgICAgKi8KICAgICAgcHJvdGVjdGVkIEdldE9yZ1BvbGljeShqYXZhLmxhbmcuU3RyaW5nIHJlc291cmNlLCBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5jbG91ZHJlc291cmNlbWFuYWdlci5tb2RlbC5HZXRPcmdQb2xpY3lSZXF1ZXN0IGNvbnRlbnQpIHsKICAgICAgICBzdXBlcihDbG91ZFJlc291cmNlTWFuYWdlci50aGlzLCAiUE9TVCIsIFJFU1RfUEFUSCwgY29udGVudCwgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuY2xvdWRyZXNvdXJjZW1hbmFnZXIubW9kZWwuT3JnUG9saWN5LmNsYXNzKTsKICAgICAgICB0aGlzLnJlc291cmNlID0gY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuUHJlY29uZGl0aW9ucy5jaGVja05vdE51bGwocmVzb3VyY2UsICJSZXF1aXJlZCBwYXJhbWV0ZXIgcmVzb3VyY2UgbXVzdCBiZSBzcGVjaWZpZWQuIik7CiAgICAgICAgaWYgKCFnZXRTdXBwcmVzc1BhdHRlcm5DaGVja3MoKSkgewogICAgICAgICAgY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuUHJlY29uZGl0aW9ucy5jaGVja0FyZ3VtZW50KFJFU09VUkNFX1BBVFRFUk4ubWF0Y2hlcihyZXNvdXJjZSkubWF0Y2hlcygpLAogICAgICAgICAgICAgICJQYXJhbWV0ZXIgcmVzb3VyY2UgbXVzdCBjb25mb3JtIHRvIHRoZSBwYXR0ZXJuICIgKwogICAgICAgICAgICAgICJeZm9sZGVycy9bXi9dKyQiKTsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgR2V0T3JnUG9saWN5IHNldCRYZ2FmdihqYXZhLmxhbmcuU3RyaW5nICRYZ2FmdikgewogICAgICAgIHJldHVybiAoR2V0T3JnUG9saWN5KSBzdXBlci5zZXQkWGdhZnYoJFhnYWZ2KTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBHZXRPcmdQb2xpY3kgc2V0QWNjZXNzVG9rZW4oamF2YS5sYW5nLlN0cmluZyBhY2Nlc3NUb2tlbikgewogICAgICAgIHJldHVybiAoR2V0T3JnUG9saWN5KSBzdXBlci5zZXRBY2Nlc3NUb2tlbihhY2Nlc3NUb2tlbik7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgR2V0T3JnUG9saWN5IHNldEFsdChqYXZhLmxhbmcuU3RyaW5nIGFsdCkgewogICAgICAgIHJldHVybiAoR2V0T3JnUG9saWN5KSBzdXBlci5zZXRBbHQoYWx0KTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBHZXRPcmdQb2xpY3kgc2V0Q2FsbGJhY2soamF2YS5sYW5nLlN0cmluZyBjYWxsYmFjaykgewogICAgICAgIHJldHVybiAoR2V0T3JnUG9saWN5KSBzdXBlci5zZXRDYWxsYmFjayhjYWxsYmFjayk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgR2V0T3JnUG9saWN5IHNldEZpZWxkcyhqYXZhLmxhbmcuU3RyaW5nIGZpZWxkcykgewogICAgICAgIHJldHVybiAoR2V0T3JnUG9saWN5KSBzdXBlci5zZXRGaWVsZHMoZmllbGRzKTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBHZXRPcmdQb2xpY3kgc2V0S2V5KGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgcmV0dXJuIChHZXRPcmdQb2xpY3kpIHN1cGVyLnNldEtleShrZXkpOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIEdldE9yZ1BvbGljeSBzZXRPYXV0aFRva2VuKGphdmEubGFuZy5TdHJpbmcgb2F1dGhUb2tlbikgewogICAgICAgIHJldHVybiAoR2V0T3JnUG9saWN5KSBzdXBlci5zZXRPYXV0aFRva2VuKG9hdXRoVG9rZW4pOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIEdldE9yZ1BvbGljeSBzZXRQcmV0dHlQcmludChqYXZhLmxhbmcuQm9vbGVhbiBwcmV0dHlQcmludCkgewogICAgICAgIHJldHVybiAoR2V0T3JnUG9saWN5KSBzdXBlci5zZXRQcmV0dHlQcmludChwcmV0dHlQcmludCk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgR2V0T3JnUG9saWN5IHNldFF1b3RhVXNlcihqYXZhLmxhbmcuU3RyaW5nIHF1b3RhVXNlcikgewogICAgICAgIHJldHVybiAoR2V0T3JnUG9saWN5KSBzdXBlci5zZXRRdW90YVVzZXIocXVvdGFVc2VyKTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBHZXRPcmdQb2xpY3kgc2V0VXBsb2FkVHlwZShqYXZhLmxhbmcuU3RyaW5nIHVwbG9hZFR5cGUpIHsKICAgICAgICByZXR1cm4gKEdldE9yZ1BvbGljeSkgc3VwZXIuc2V0VXBsb2FkVHlwZSh1cGxvYWRUeXBlKTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBHZXRPcmdQb2xpY3kgc2V0VXBsb2FkUHJvdG9jb2woamF2YS5sYW5nLlN0cmluZyB1cGxvYWRQcm90b2NvbCkgewogICAgICAgIHJldHVybiAoR2V0T3JnUG9saWN5KSBzdXBlci5zZXRVcGxvYWRQcm90b2NvbCh1cGxvYWRQcm90b2NvbCk7CiAgICAgIH0KCiAgICAgIC8qKiBOYW1lIG9mIHRoZSByZXNvdXJjZSB0aGUgYFBvbGljeWAgaXMgc2V0IG9uLiAqLwogICAgICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgICAgIHByaXZhdGUgamF2YS5sYW5nLlN0cmluZyByZXNvdXJjZTsKCiAgICAgIC8qKiBOYW1lIG9mIHRoZSByZXNvdXJjZSB0aGUgYFBvbGljeWAgaXMgc2V0IG9uLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0UmVzb3VyY2UoKSB7CiAgICAgICAgcmV0dXJuIHJlc291cmNlOwogICAgICB9CgogICAgICAvKiogTmFtZSBvZiB0aGUgcmVzb3VyY2UgdGhlIGBQb2xpY3lgIGlzIHNldCBvbi4gKi8KICAgICAgcHVibGljIEdldE9yZ1BvbGljeSBzZXRSZXNvdXJjZShqYXZhLmxhbmcuU3RyaW5nIHJlc291cmNlKSB7CiAgICAgICAgaWYgKCFnZXRTdXBwcmVzc1BhdHRlcm5DaGVja3MoKSkgewogICAgICAgICAgY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuUHJlY29uZGl0aW9ucy5jaGVja0FyZ3VtZW50KFJFU09VUkNFX1BBVFRFUk4ubWF0Y2hlcihyZXNvdXJjZSkubWF0Y2hlcygpLAogICAgICAgICAgICAgICJQYXJhbWV0ZXIgcmVzb3VyY2UgbXVzdCBjb25mb3JtIHRvIHRoZSBwYXR0ZXJuICIgKwogICAgICAgICAgICAgICJeZm9sZGVycy9bXi9dKyQiKTsKICAgICAgICB9CiAgICAgICAgdGhpcy5yZXNvdXJjZSA9IHJlc291cmNlOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIEdldE9yZ1BvbGljeSBzZXQoU3RyaW5nIHBhcmFtZXRlck5hbWUsIE9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiAoR2V0T3JnUG9saWN5KSBzdXBlci5zZXQocGFyYW1ldGVyTmFtZSwgdmFsdWUpOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIExpc3RzIGBDb25zdHJhaW50c2AgdGhhdCBjb3VsZCBiZSBhcHBsaWVkIG9uIHRoZSBzcGVjaWZpZWQgcmVzb3VyY2UuCiAgICAgKgogICAgICogQ3JlYXRlIGEgcmVxdWVzdCBmb3IgdGhlIG1ldGhvZCAiZm9sZGVycy5saXN0QXZhaWxhYmxlT3JnUG9saWN5Q29uc3RyYWludHMiLgogICAgICoKICAgICAqIFRoaXMgcmVxdWVzdCBob2xkcyB0aGUgcGFyYW1ldGVycyBuZWVkZWQgYnkgdGhlIGNsb3VkcmVzb3VyY2VtYW5hZ2VyIHNlcnZlci4gIEFmdGVyIHNldHRpbmcgYW55CiAgICAgKiBvcHRpb25hbCBwYXJhbWV0ZXJzLCBjYWxsIHRoZSB7QGxpbmsgTGlzdEF2YWlsYWJsZU9yZ1BvbGljeUNvbnN0cmFpbnRzI2V4ZWN1dGUoKX0gbWV0aG9kIHRvCiAgICAgKiBpbnZva2UgdGhlIHJlbW90ZSBvcGVyYXRpb24uCiAgICAgKgogICAgICogQHBhcmFtIHJlc291cmNlIE5hbWUgb2YgdGhlIHJlc291cmNlIHRvIGxpc3QgYENvbnN0cmFpbnRzYCBmb3IuCiAgICAgKiBAcGFyYW0gY29udGVudCB0aGUge0BsaW5rIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmNsb3VkcmVzb3VyY2VtYW5hZ2VyLm1vZGVsLkxpc3RBdmFpbGFibGVPcmdQb2xpY3lDb25zdHJhaW50c1JlcXVlc3R9CiAgICAgKiBAcmV0dXJuIHRoZSByZXF1ZXN0CiAgICAgKi8KICAgIHB1YmxpYyBMaXN0QXZhaWxhYmxlT3JnUG9saWN5Q29uc3RyYWludHMgbGlzdEF2YWlsYWJsZU9yZ1BvbGljeUNvbnN0cmFpbnRzKGphdmEubGFuZy5TdHJpbmcgcmVzb3VyY2UsIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmNsb3VkcmVzb3VyY2VtYW5hZ2VyLm1vZGVsLkxpc3RBdmFpbGFibGVPcmdQb2xpY3lDb25zdHJhaW50c1JlcXVlc3QgY29udGVudCkgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBMaXN0QXZhaWxhYmxlT3JnUG9saWN5Q29uc3RyYWludHMgcmVzdWx0ID0gbmV3IExpc3RBdmFpbGFibGVPcmdQb2xpY3lDb25zdHJhaW50cyhyZXNvdXJjZSwgY29udGVudCk7CiAgICAgIGluaXRpYWxpemUocmVzdWx0KTsKICAgICAgcmV0dXJuIHJlc3VsdDsKICAgIH0KCiAgICBwdWJsaWMgY2xhc3MgTGlzdEF2YWlsYWJsZU9yZ1BvbGljeUNvbnN0cmFpbnRzIGV4dGVuZHMgQ2xvdWRSZXNvdXJjZU1hbmFnZXJSZXF1ZXN0PGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmNsb3VkcmVzb3VyY2VtYW5hZ2VyLm1vZGVsLkxpc3RBdmFpbGFibGVPcmdQb2xpY3lDb25zdHJhaW50c1Jlc3BvbnNlPiB7CgogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgUkVTVF9QQVRIID0gInYxL3srcmVzb3VyY2V9Omxpc3RBdmFpbGFibGVPcmdQb2xpY3lDb25zdHJhaW50cyI7CgogICAgICBwcml2YXRlIGZpbmFsIGphdmEudXRpbC5yZWdleC5QYXR0ZXJuIFJFU09VUkNFX1BBVFRFUk4gPQogICAgICAgICAgamF2YS51dGlsLnJlZ2V4LlBhdHRlcm4uY29tcGlsZSgiXmZvbGRlcnMvW14vXSskIik7CgogICAgICAvKioKICAgICAgICogTGlzdHMgYENvbnN0cmFpbnRzYCB0aGF0IGNvdWxkIGJlIGFwcGxpZWQgb24gdGhlIHNwZWNpZmllZCByZXNvdXJjZS4KICAgICAgICoKICAgICAgICogQ3JlYXRlIGEgcmVxdWVzdCBmb3IgdGhlIG1ldGhvZCAiZm9sZGVycy5saXN0QXZhaWxhYmxlT3JnUG9saWN5Q29uc3RyYWludHMiLgogICAgICAgKgogICAgICAgKiBUaGlzIHJlcXVlc3QgaG9sZHMgdGhlIHBhcmFtZXRlcnMgbmVlZGVkIGJ5IHRoZSB0aGUgY2xvdWRyZXNvdXJjZW1hbmFnZXIgc2VydmVyLiAgQWZ0ZXIgc2V0dGluZwogICAgICAgKiBhbnkgb3B0aW9uYWwgcGFyYW1ldGVycywgY2FsbCB0aGUge0BsaW5rIExpc3RBdmFpbGFibGVPcmdQb2xpY3lDb25zdHJhaW50cyNleGVjdXRlKCl9IG1ldGhvZCB0bwogICAgICAgKiBpbnZva2UgdGhlIHJlbW90ZSBvcGVyYXRpb24uIDxwPiB7QGxpbmsgTGlzdEF2YWlsYWJsZU9yZ1BvbGljeUNvbnN0cmFpbnRzI2luaXRpYWxpemUoY29tLmdvb2dsZQogICAgICAgKiAuYXBpLmNsaWVudC5nb29nbGVhcGlzLnNlcnZpY2VzLkFic3RyYWN0R29vZ2xlQ2xpZW50UmVxdWVzdCl9IG11c3QgYmUgY2FsbGVkIHRvIGluaXRpYWxpemUgdGhpcwogICAgICAgKiBpbnN0YW5jZSBpbW1lZGlhdGVseSBhZnRlciBpbnZva2luZyB0aGUgY29uc3RydWN0b3IuIDwvcD4KICAgICAgICoKICAgICAgICogQHBhcmFtIHJlc291cmNlIE5hbWUgb2YgdGhlIHJlc291cmNlIHRvIGxpc3QgYENvbnN0cmFpbnRzYCBmb3IuCiAgICAgICAqIEBwYXJhbSBjb250ZW50IHRoZSB7QGxpbmsgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuY2xvdWRyZXNvdXJjZW1hbmFnZXIubW9kZWwuTGlzdEF2YWlsYWJsZU9yZ1BvbGljeUNvbnN0cmFpbnRzUmVxdWVzdH0KICAgICAgICogQHNpbmNlIDEuMTMKICAgICAgICovCiAgICAgIHByb3RlY3RlZCBMaXN0QXZhaWxhYmxlT3JnUG9saWN5Q29uc3RyYWludHMoamF2YS5sYW5nLlN0cmluZyByZXNvdXJjZSwgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuY2xvdWRyZXNvdXJjZW1hbmFnZXIubW9kZWwuTGlzdEF2YWlsYWJsZU9yZ1BvbGljeUNvbnN0cmFpbnRzUmVxdWVzdCBjb250ZW50KSB7CiAgICAgICAgc3VwZXIoQ2xvdWRSZXNvdXJjZU1hbmFnZXIudGhpcywgIlBPU1QiLCBSRVNUX1BBVEgsIGNvbnRlbnQsIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmNsb3VkcmVzb3VyY2VtYW5hZ2VyLm1vZGVsLkxpc3RBdmFpbGFibGVPcmdQb2xpY3lDb25zdHJhaW50c1Jlc3BvbnNlLmNsYXNzKTsKICAgICAgICB0aGlzLnJlc291cmNlID0gY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuUHJlY29uZGl0aW9ucy5jaGVja05vdE51bGwocmVzb3VyY2UsICJSZXF1aXJlZCBwYXJhbWV0ZXIgcmVzb3VyY2UgbXVzdCBiZSBzcGVjaWZpZWQuIik7CiAgICAgICAgaWYgKCFnZXRTdXBwcmVzc1BhdHRlcm5DaGVja3MoKSkgewogICAgICAgICAgY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuUHJlY29uZGl0aW9ucy5jaGVja0FyZ3VtZW50KFJFU09VUkNFX1BBVFRFUk4ubWF0Y2hlcihyZXNvdXJjZSkubWF0Y2hlcygpLAogICAgICAgICAgICAgICJQYXJhbWV0ZXIgcmVzb3VyY2UgbXVzdCBjb25mb3JtIHRvIHRoZSBwYXR0ZXJuICIgKwogICAgICAgICAgICAgICJeZm9sZGVycy9bXi9dKyQiKTsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgTGlzdEF2YWlsYWJsZU9yZ1BvbGljeUNvbnN0cmFpbnRzIHNldCRYZ2FmdihqYXZhLmxhbmcuU3RyaW5nICRYZ2FmdikgewogICAgICAgIHJldHVybiAoTGlzdEF2YWlsYWJsZU9yZ1BvbGljeUNvbnN0cmFpbnRzKSBzdXBlci5zZXQkWGdhZnYoJFhnYWZ2KTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBMaXN0QXZhaWxhYmxlT3JnUG9saWN5Q29uc3RyYWludHMgc2V0QWNjZXNzVG9rZW4oamF2YS5sYW5nLlN0cmluZyBhY2Nlc3NUb2tlbikgewogICAgICAgIHJldHVybiAoTGlzdEF2YWlsYWJsZU9yZ1BvbGljeUNvbnN0cmFpbnRzKSBzdXBlci5zZXRBY2Nlc3NUb2tlbihhY2Nlc3NUb2tlbik7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgTGlzdEF2YWlsYWJsZU9yZ1BvbGljeUNvbnN0cmFpbnRzIHNldEFsdChqYXZhLmxhbmcuU3RyaW5nIGFsdCkgewogICAgICAgIHJldHVybiAoTGlzdEF2YWlsYWJsZU9yZ1BvbGljeUNvbnN0cmFpbnRzKSBzdXBlci5zZXRBbHQoYWx0KTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBMaXN0QXZhaWxhYmxlT3JnUG9saWN5Q29uc3RyYWludHMgc2V0Q2FsbGJhY2soamF2YS5sYW5nLlN0cmluZyBjYWxsYmFjaykgewogICAgICAgIHJldHVybiAoTGlzdEF2YWlsYWJsZU9yZ1BvbGljeUNvbnN0cmFpbnRzKSBzdXBlci5zZXRDYWxsYmFjayhjYWxsYmFjayk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgTGlzdEF2YWlsYWJsZU9yZ1BvbGljeUNvbnN0cmFpbnRzIHNldEZpZWxkcyhqYXZhLmxhbmcuU3RyaW5nIGZpZWxkcykgewogICAgICAgIHJldHVybiAoTGlzdEF2YWlsYWJsZU9yZ1BvbGljeUNvbnN0cmFpbnRzKSBzdXBlci5zZXRGaWVsZHMoZmllbGRzKTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBMaXN0QXZhaWxhYmxlT3JnUG9saWN5Q29uc3RyYWludHMgc2V0S2V5KGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgcmV0dXJuIChMaXN0QXZhaWxhYmxlT3JnUG9saWN5Q29uc3RyYWludHMpIHN1cGVyLnNldEtleShrZXkpOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIExpc3RBdmFpbGFibGVPcmdQb2xpY3lDb25zdHJhaW50cyBzZXRPYXV0aFRva2VuKGphdmEubGFuZy5TdHJpbmcgb2F1dGhUb2tlbikgewogICAgICAgIHJldHVybiAoTGlzdEF2YWlsYWJsZU9yZ1BvbGljeUNvbnN0cmFpbnRzKSBzdXBlci5zZXRPYXV0aFRva2VuKG9hdXRoVG9rZW4pOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIExpc3RBdmFpbGFibGVPcmdQb2xpY3lDb25zdHJhaW50cyBzZXRQcmV0dHlQcmludChqYXZhLmxhbmcuQm9vbGVhbiBwcmV0dHlQcmludCkgewogICAgICAgIHJldHVybiAoTGlzdEF2YWlsYWJsZU9yZ1BvbGljeUNvbnN0cmFpbnRzKSBzdXBlci5zZXRQcmV0dHlQcmludChwcmV0dHlQcmludCk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgTGlzdEF2YWlsYWJsZU9yZ1BvbGljeUNvbnN0cmFpbnRzIHNldFF1b3RhVXNlcihqYXZhLmxhbmcuU3RyaW5nIHF1b3RhVXNlcikgewogICAgICAgIHJldHVybiAoTGlzdEF2YWlsYWJsZU9yZ1BvbGljeUNvbnN0cmFpbnRzKSBzdXBlci5zZXRRdW90YVVzZXIocXVvdGFVc2VyKTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBMaXN0QXZhaWxhYmxlT3JnUG9saWN5Q29uc3RyYWludHMgc2V0VXBsb2FkVHlwZShqYXZhLmxhbmcuU3RyaW5nIHVwbG9hZFR5cGUpIHsKICAgICAgICByZXR1cm4gKExpc3RBdmFpbGFibGVPcmdQb2xpY3lDb25zdHJhaW50cykgc3VwZXIuc2V0VXBsb2FkVHlwZSh1cGxvYWRUeXBlKTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBMaXN0QXZhaWxhYmxlT3JnUG9saWN5Q29uc3RyYWludHMgc2V0VXBsb2FkUHJvdG9jb2woamF2YS5sYW5nLlN0cmluZyB1cGxvYWRQcm90b2NvbCkgewogICAgICAgIHJldHVybiAoTGlzdEF2YWlsYWJsZU9yZ1BvbGljeUNvbnN0cmFpbnRzKSBzdXBlci5zZXRVcGxvYWRQcm90b2NvbCh1cGxvYWRQcm90b2NvbCk7CiAgICAgIH0KCiAgICAgIC8qKiBOYW1lIG9mIHRoZSByZXNvdXJjZSB0byBsaXN0IGBDb25zdHJhaW50c2AgZm9yLiAqLwogICAgICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgICAgIHByaXZhdGUgamF2YS5sYW5nLlN0cmluZyByZXNvdXJjZTsKCiAgICAgIC8qKiBOYW1lIG9mIHRoZSByZXNvdXJjZSB0byBsaXN0IGBDb25zdHJhaW50c2AgZm9yLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0UmVzb3VyY2UoKSB7CiAgICAgICAgcmV0dXJuIHJlc291cmNlOwogICAgICB9CgogICAgICAvKiogTmFtZSBvZiB0aGUgcmVzb3VyY2UgdG8gbGlzdCBgQ29uc3RyYWludHNgIGZvci4gKi8KICAgICAgcHVibGljIExpc3RBdmFpbGFibGVPcmdQb2xpY3lDb25zdHJhaW50cyBzZXRSZXNvdXJjZShqYXZhLmxhbmcuU3RyaW5nIHJlc291cmNlKSB7CiAgICAgICAgaWYgKCFnZXRTdXBwcmVzc1BhdHRlcm5DaGVja3MoKSkgewogICAgICAgICAgY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuUHJlY29uZGl0aW9ucy5jaGVja0FyZ3VtZW50KFJFU09VUkNFX1BBVFRFUk4ubWF0Y2hlcihyZXNvdXJjZSkubWF0Y2hlcygpLAogICAgICAgICAgICAgICJQYXJhbWV0ZXIgcmVzb3VyY2UgbXVzdCBjb25mb3JtIHRvIHRoZSBwYXR0ZXJuICIgKwogICAgICAgICAgICAgICJeZm9sZGVycy9bXi9dKyQiKTsKICAgICAgICB9CiAgICAgICAgdGhpcy5yZXNvdXJjZSA9IHJlc291cmNlOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIExpc3RBdmFpbGFibGVPcmdQb2xpY3lDb25zdHJhaW50cyBzZXQoU3RyaW5nIHBhcmFtZXRlck5hbWUsIE9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiAoTGlzdEF2YWlsYWJsZU9yZ1BvbGljeUNvbnN0cmFpbnRzKSBzdXBlci5zZXQocGFyYW1ldGVyTmFtZSwgdmFsdWUpOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIExpc3RzIGFsbCB0aGUgYFBvbGljaWVzYCBzZXQgZm9yIGEgcGFydGljdWxhciByZXNvdXJjZS4KICAgICAqCiAgICAgKiBDcmVhdGUgYSByZXF1ZXN0IGZvciB0aGUgbWV0aG9kICJmb2xkZXJzLmxpc3RPcmdQb2xpY2llcyIuCiAgICAgKgogICAgICogVGhpcyByZXF1ZXN0IGhvbGRzIHRoZSBwYXJhbWV0ZXJzIG5lZWRlZCBieSB0aGUgY2xvdWRyZXNvdXJjZW1hbmFnZXIgc2VydmVyLiAgQWZ0ZXIgc2V0dGluZyBhbnkKICAgICAqIG9wdGlvbmFsIHBhcmFtZXRlcnMsIGNhbGwgdGhlIHtAbGluayBMaXN0T3JnUG9saWNpZXMjZXhlY3V0ZSgpfSBtZXRob2QgdG8gaW52b2tlIHRoZSByZW1vdGUKICAgICAqIG9wZXJhdGlvbi4KICAgICAqCiAgICAgKiBAcGFyYW0gcmVzb3VyY2UgTmFtZSBvZiB0aGUgcmVzb3VyY2UgdG8gbGlzdCBQb2xpY2llcyBmb3IuCiAgICAgKiBAcGFyYW0gY29udGVudCB0aGUge0BsaW5rIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmNsb3VkcmVzb3VyY2VtYW5hZ2VyLm1vZGVsLkxpc3RPcmdQb2xpY2llc1JlcXVlc3R9CiAgICAgKiBAcmV0dXJuIHRoZSByZXF1ZXN0CiAgICAgKi8KICAgIHB1YmxpYyBMaXN0T3JnUG9saWNpZXMgbGlzdE9yZ1BvbGljaWVzKGphdmEubGFuZy5TdHJpbmcgcmVzb3VyY2UsIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmNsb3VkcmVzb3VyY2VtYW5hZ2VyLm1vZGVsLkxpc3RPcmdQb2xpY2llc1JlcXVlc3QgY29udGVudCkgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBMaXN0T3JnUG9saWNpZXMgcmVzdWx0ID0gbmV3IExpc3RPcmdQb2xpY2llcyhyZXNvdXJjZSwgY29udGVudCk7CiAgICAgIGluaXRpYWxpemUocmVzdWx0KTsKICAgICAgcmV0dXJuIHJlc3VsdDsKICAgIH0KCiAgICBwdWJsaWMgY2xhc3MgTGlzdE9yZ1BvbGljaWVzIGV4dGVuZHMgQ2xvdWRSZXNvdXJjZU1hbmFnZXJSZXF1ZXN0PGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmNsb3VkcmVzb3VyY2VtYW5hZ2VyLm1vZGVsLkxpc3RPcmdQb2xpY2llc1Jlc3BvbnNlPiB7CgogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgUkVTVF9QQVRIID0gInYxL3srcmVzb3VyY2V9Omxpc3RPcmdQb2xpY2llcyI7CgogICAgICBwcml2YXRlIGZpbmFsIGphdmEudXRpbC5yZWdleC5QYXR0ZXJuIFJFU09VUkNFX1BBVFRFUk4gPQogICAgICAgICAgamF2YS51dGlsLnJlZ2V4LlBhdHRlcm4uY29tcGlsZSgiXmZvbGRlcnMvW14vXSskIik7CgogICAgICAvKioKICAgICAgICogTGlzdHMgYWxsIHRoZSBgUG9saWNpZXNgIHNldCBmb3IgYSBwYXJ0aWN1bGFyIHJlc291cmNlLgogICAgICAgKgogICAgICAgKiBDcmVhdGUgYSByZXF1ZXN0IGZvciB0aGUgbWV0aG9kICJmb2xkZXJzLmxpc3RPcmdQb2xpY2llcyIuCiAgICAgICAqCiAgICAgICAqIFRoaXMgcmVxdWVzdCBob2xkcyB0aGUgcGFyYW1ldGVycyBuZWVkZWQgYnkgdGhlIHRoZSBjbG91ZHJlc291cmNlbWFuYWdlciBzZXJ2ZXIuICBBZnRlciBzZXR0aW5nCiAgICAgICAqIGFueSBvcHRpb25hbCBwYXJhbWV0ZXJzLCBjYWxsIHRoZSB7QGxpbmsgTGlzdE9yZ1BvbGljaWVzI2V4ZWN1dGUoKX0gbWV0aG9kIHRvIGludm9rZSB0aGUgcmVtb3RlCiAgICAgICAqIG9wZXJhdGlvbi4gPHA+IHtAbGluayBMaXN0T3JnUG9saWNpZXMjaW5pdGlhbGl6ZShjb20uZ29vZ2xlLmFwaS5jbGllbnQuZ29vZ2xlYXBpcy5zZXJ2aWNlcy5BYnN0CiAgICAgICAqIHJhY3RHb29nbGVDbGllbnRSZXF1ZXN0KX0gbXVzdCBiZSBjYWxsZWQgdG8gaW5pdGlhbGl6ZSB0aGlzIGluc3RhbmNlIGltbWVkaWF0ZWx5IGFmdGVyIGludm9raW5nCiAgICAgICAqIHRoZSBjb25zdHJ1Y3Rvci4gPC9wPgogICAgICAgKgogICAgICAgKiBAcGFyYW0gcmVzb3VyY2UgTmFtZSBvZiB0aGUgcmVzb3VyY2UgdG8gbGlzdCBQb2xpY2llcyBmb3IuCiAgICAgICAqIEBwYXJhbSBjb250ZW50IHRoZSB7QGxpbmsgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuY2xvdWRyZXNvdXJjZW1hbmFnZXIubW9kZWwuTGlzdE9yZ1BvbGljaWVzUmVxdWVzdH0KICAgICAgICogQHNpbmNlIDEuMTMKICAgICAgICovCiAgICAgIHByb3RlY3RlZCBMaXN0T3JnUG9saWNpZXMoamF2YS5sYW5nLlN0cmluZyByZXNvdXJjZSwgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuY2xvdWRyZXNvdXJjZW1hbmFnZXIubW9kZWwuTGlzdE9yZ1BvbGljaWVzUmVxdWVzdCBjb250ZW50KSB7CiAgICAgICAgc3VwZXIoQ2xvdWRSZXNvdXJjZU1hbmFnZXIudGhpcywgIlBPU1QiLCBSRVNUX1BBVEgsIGNvbnRlbnQsIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmNsb3VkcmVzb3VyY2VtYW5hZ2VyLm1vZGVsLkxpc3RPcmdQb2xpY2llc1Jlc3BvbnNlLmNsYXNzKTsKICAgICAgICB0aGlzLnJlc291cmNlID0gY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuUHJlY29uZGl0aW9ucy5jaGVja05vdE51bGwocmVzb3VyY2UsICJSZXF1aXJlZCBwYXJhbWV0ZXIgcmVzb3VyY2UgbXVzdCBiZSBzcGVjaWZpZWQuIik7CiAgICAgICAgaWYgKCFnZXRTdXBwcmVzc1BhdHRlcm5DaGVja3MoKSkgewogICAgICAgICAgY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuUHJlY29uZGl0aW9ucy5jaGVja0FyZ3VtZW50KFJFU09VUkNFX1BBVFRFUk4ubWF0Y2hlcihyZXNvdXJjZSkubWF0Y2hlcygpLAogICAgICAgICAgICAgICJQYXJhbWV0ZXIgcmVzb3VyY2UgbXVzdCBjb25mb3JtIHRvIHRoZSBwYXR0ZXJuICIgKwogICAgICAgICAgICAgICJeZm9sZGVycy9bXi9dKyQiKTsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgTGlzdE9yZ1BvbGljaWVzIHNldCRYZ2FmdihqYXZhLmxhbmcuU3RyaW5nICRYZ2FmdikgewogICAgICAgIHJldHVybiAoTGlzdE9yZ1BvbGljaWVzKSBzdXBlci5zZXQkWGdhZnYoJFhnYWZ2KTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBMaXN0T3JnUG9saWNpZXMgc2V0QWNjZXNzVG9rZW4oamF2YS5sYW5nLlN0cmluZyBhY2Nlc3NUb2tlbikgewogICAgICAgIHJldHVybiAoTGlzdE9yZ1BvbGljaWVzKSBzdXBlci5zZXRBY2Nlc3NUb2tlbihhY2Nlc3NUb2tlbik7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgTGlzdE9yZ1BvbGljaWVzIHNldEFsdChqYXZhLmxhbmcuU3RyaW5nIGFsdCkgewogICAgICAgIHJldHVybiAoTGlzdE9yZ1BvbGljaWVzKSBzdXBlci5zZXRBbHQoYWx0KTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBMaXN0T3JnUG9saWNpZXMgc2V0Q2FsbGJhY2soamF2YS5sYW5nLlN0cmluZyBjYWxsYmFjaykgewogICAgICAgIHJldHVybiAoTGlzdE9yZ1BvbGljaWVzKSBzdXBlci5zZXRDYWxsYmFjayhjYWxsYmFjayk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgTGlzdE9yZ1BvbGljaWVzIHNldEZpZWxkcyhqYXZhLmxhbmcuU3RyaW5nIGZpZWxkcykgewogICAgICAgIHJldHVybiAoTGlzdE9yZ1BvbGljaWVzKSBzdXBlci5zZXRGaWVsZHMoZmllbGRzKTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBMaXN0T3JnUG9saWNpZXMgc2V0S2V5KGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgcmV0dXJuIChMaXN0T3JnUG9saWNpZXMpIHN1cGVyLnNldEtleShrZXkpOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIExpc3RPcmdQb2xpY2llcyBzZXRPYXV0aFRva2VuKGphdmEubGFuZy5TdHJpbmcgb2F1dGhUb2tlbikgewogICAgICAgIHJldHVybiAoTGlzdE9yZ1BvbGljaWVzKSBzdXBlci5zZXRPYXV0aFRva2VuKG9hdXRoVG9rZW4pOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIExpc3RPcmdQb2xpY2llcyBzZXRQcmV0dHlQcmludChqYXZhLmxhbmcuQm9vbGVhbiBwcmV0dHlQcmludCkgewogICAgICAgIHJldHVybiAoTGlzdE9yZ1BvbGljaWVzKSBzdXBlci5zZXRQcmV0dHlQcmludChwcmV0dHlQcmludCk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgTGlzdE9yZ1BvbGljaWVzIHNldFF1b3RhVXNlcihqYXZhLmxhbmcuU3RyaW5nIHF1b3RhVXNlcikgewogICAgICAgIHJldHVybiAoTGlzdE9yZ1BvbGljaWVzKSBzdXBlci5zZXRRdW90YVVzZXIocXVvdGFVc2VyKTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBMaXN0T3JnUG9saWNpZXMgc2V0VXBsb2FkVHlwZShqYXZhLmxhbmcuU3RyaW5nIHVwbG9hZFR5cGUpIHsKICAgICAgICByZXR1cm4gKExpc3RPcmdQb2xpY2llcykgc3VwZXIuc2V0VXBsb2FkVHlwZSh1cGxvYWRUeXBlKTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBMaXN0T3JnUG9saWNpZXMgc2V0VXBsb2FkUHJvdG9jb2woamF2YS5sYW5nLlN0cmluZyB1cGxvYWRQcm90b2NvbCkgewogICAgICAgIHJldHVybiAoTGlzdE9yZ1BvbGljaWVzKSBzdXBlci5zZXRVcGxvYWRQcm90b2NvbCh1cGxvYWRQcm90b2NvbCk7CiAgICAgIH0KCiAgICAgIC8qKiBOYW1lIG9mIHRoZSByZXNvdXJjZSB0byBsaXN0IFBvbGljaWVzIGZvci4gKi8KICAgICAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogICAgICBwcml2YXRlIGphdmEubGFuZy5TdHJpbmcgcmVzb3VyY2U7CgogICAgICAvKiogTmFtZSBvZiB0aGUgcmVzb3VyY2UgdG8gbGlzdCBQb2xpY2llcyBmb3IuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRSZXNvdXJjZSgpIHsKICAgICAgICByZXR1cm4gcmVzb3VyY2U7CiAgICAgIH0KCiAgICAgIC8qKiBOYW1lIG9mIHRoZSByZXNvdXJjZSB0byBsaXN0IFBvbGljaWVzIGZvci4gKi8KICAgICAgcHVibGljIExpc3RPcmdQb2xpY2llcyBzZXRSZXNvdXJjZShqYXZhLmxhbmcuU3RyaW5nIHJlc291cmNlKSB7CiAgICAgICAgaWYgKCFnZXRTdXBwcmVzc1BhdHRlcm5DaGVja3MoKSkgewogICAgICAgICAgY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuUHJlY29uZGl0aW9ucy5jaGVja0FyZ3VtZW50KFJFU09VUkNFX1BBVFRFUk4ubWF0Y2hlcihyZXNvdXJjZSkubWF0Y2hlcygpLAogICAgICAgICAgICAgICJQYXJhbWV0ZXIgcmVzb3VyY2UgbXVzdCBjb25mb3JtIHRvIHRoZSBwYXR0ZXJuICIgKwogICAgICAgICAgICAgICJeZm9sZGVycy9bXi9dKyQiKTsKICAgICAgICB9CiAgICAgICAgdGhpcy5yZXNvdXJjZSA9IHJlc291cmNlOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIExpc3RPcmdQb2xpY2llcyBzZXQoU3RyaW5nIHBhcmFtZXRlck5hbWUsIE9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiAoTGlzdE9yZ1BvbGljaWVzKSBzdXBlci5zZXQocGFyYW1ldGVyTmFtZSwgdmFsdWUpOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIFVwZGF0ZXMgdGhlIHNwZWNpZmllZCBgUG9saWN5YCBvbiB0aGUgcmVzb3VyY2UuIENyZWF0ZXMgYSBuZXcgYFBvbGljeWAgZm9yIHRoYXQgYENvbnN0cmFpbnRgIG9uCiAgICAgKiB0aGUgcmVzb3VyY2UgaWYgb25lIGRvZXMgbm90IGV4aXN0LgogICAgICoKICAgICAqIE5vdCBzdXBwbHlpbmcgYW4gYGV0YWdgIG9uIHRoZSByZXF1ZXN0IGBQb2xpY3lgIHJlc3VsdHMgaW4gYW4gdW5jb25kaXRpb25hbCB3cml0ZSBvZiB0aGUKICAgICAqIGBQb2xpY3lgLgogICAgICoKICAgICAqIENyZWF0ZSBhIHJlcXVlc3QgZm9yIHRoZSBtZXRob2QgImZvbGRlcnMuc2V0T3JnUG9saWN5Ii4KICAgICAqCiAgICAgKiBUaGlzIHJlcXVlc3QgaG9sZHMgdGhlIHBhcmFtZXRlcnMgbmVlZGVkIGJ5IHRoZSBjbG91ZHJlc291cmNlbWFuYWdlciBzZXJ2ZXIuICBBZnRlciBzZXR0aW5nIGFueQogICAgICogb3B0aW9uYWwgcGFyYW1ldGVycywgY2FsbCB0aGUge0BsaW5rIFNldE9yZ1BvbGljeSNleGVjdXRlKCl9IG1ldGhvZCB0byBpbnZva2UgdGhlIHJlbW90ZQogICAgICogb3BlcmF0aW9uLgogICAgICoKICAgICAqIEBwYXJhbSByZXNvdXJjZSBSZXNvdXJjZSBuYW1lIG9mIHRoZSByZXNvdXJjZSB0byBhdHRhY2ggdGhlIGBQb2xpY3lgLgogICAgICogQHBhcmFtIGNvbnRlbnQgdGhlIHtAbGluayBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5jbG91ZHJlc291cmNlbWFuYWdlci5tb2RlbC5TZXRPcmdQb2xpY3lSZXF1ZXN0fQogICAgICogQHJldHVybiB0aGUgcmVxdWVzdAogICAgICovCiAgICBwdWJsaWMgU2V0T3JnUG9saWN5IHNldE9yZ1BvbGljeShqYXZhLmxhbmcuU3RyaW5nIHJlc291cmNlLCBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5jbG91ZHJlc291cmNlbWFuYWdlci5tb2RlbC5TZXRPcmdQb2xpY3lSZXF1ZXN0IGNvbnRlbnQpIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgU2V0T3JnUG9saWN5IHJlc3VsdCA9IG5ldyBTZXRPcmdQb2xpY3kocmVzb3VyY2UsIGNvbnRlbnQpOwogICAgICBpbml0aWFsaXplKHJlc3VsdCk7CiAgICAgIHJldHVybiByZXN1bHQ7CiAgICB9CgogICAgcHVibGljIGNsYXNzIFNldE9yZ1BvbGljeSBleHRlbmRzIENsb3VkUmVzb3VyY2VNYW5hZ2VyUmVxdWVzdDxjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5jbG91ZHJlc291cmNlbWFuYWdlci5tb2RlbC5PcmdQb2xpY3k+IHsKCiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBSRVNUX1BBVEggPSAidjEveytyZXNvdXJjZX06c2V0T3JnUG9saWN5IjsKCiAgICAgIHByaXZhdGUgZmluYWwgamF2YS51dGlsLnJlZ2V4LlBhdHRlcm4gUkVTT1VSQ0VfUEFUVEVSTiA9CiAgICAgICAgICBqYXZhLnV0aWwucmVnZXguUGF0dGVybi5jb21waWxlKCJeZm9sZGVycy9bXi9dKyQiKTsKCiAgICAgIC8qKgogICAgICAgKiBVcGRhdGVzIHRoZSBzcGVjaWZpZWQgYFBvbGljeWAgb24gdGhlIHJlc291cmNlLiBDcmVhdGVzIGEgbmV3IGBQb2xpY3lgIGZvciB0aGF0IGBDb25zdHJhaW50YCBvbgogICAgICAgKiB0aGUgcmVzb3VyY2UgaWYgb25lIGRvZXMgbm90IGV4aXN0LgogICAgICAgKgogICAgICAgKiBOb3Qgc3VwcGx5aW5nIGFuIGBldGFnYCBvbiB0aGUgcmVxdWVzdCBgUG9saWN5YCByZXN1bHRzIGluIGFuIHVuY29uZGl0aW9uYWwgd3JpdGUgb2YgdGhlCiAgICAgICAqIGBQb2xpY3lgLgogICAgICAgKgogICAgICAgKiBDcmVhdGUgYSByZXF1ZXN0IGZvciB0aGUgbWV0aG9kICJmb2xkZXJzLnNldE9yZ1BvbGljeSIuCiAgICAgICAqCiAgICAgICAqIFRoaXMgcmVxdWVzdCBob2xkcyB0aGUgcGFyYW1ldGVycyBuZWVkZWQgYnkgdGhlIHRoZSBjbG91ZHJlc291cmNlbWFuYWdlciBzZXJ2ZXIuICBBZnRlciBzZXR0aW5nCiAgICAgICAqIGFueSBvcHRpb25hbCBwYXJhbWV0ZXJzLCBjYWxsIHRoZSB7QGxpbmsgU2V0T3JnUG9saWN5I2V4ZWN1dGUoKX0gbWV0aG9kIHRvIGludm9rZSB0aGUgcmVtb3RlCiAgICAgICAqIG9wZXJhdGlvbi4gPHA+IHtAbGluawogICAgICAgKiBTZXRPcmdQb2xpY3kjaW5pdGlhbGl6ZShjb20uZ29vZ2xlLmFwaS5jbGllbnQuZ29vZ2xlYXBpcy5zZXJ2aWNlcy5BYnN0cmFjdEdvb2dsZUNsaWVudFJlcXVlc3QpfQogICAgICAgKiBtdXN0IGJlIGNhbGxlZCB0byBpbml0aWFsaXplIHRoaXMgaW5zdGFuY2UgaW1tZWRpYXRlbHkgYWZ0ZXIgaW52b2tpbmcgdGhlIGNvbnN0cnVjdG9yLiA8L3A+CiAgICAgICAqCiAgICAgICAqIEBwYXJhbSByZXNvdXJjZSBSZXNvdXJjZSBuYW1lIG9mIHRoZSByZXNvdXJjZSB0byBhdHRhY2ggdGhlIGBQb2xpY3lgLgogICAgICAgKiBAcGFyYW0gY29udGVudCB0aGUge0BsaW5rIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmNsb3VkcmVzb3VyY2VtYW5hZ2VyLm1vZGVsLlNldE9yZ1BvbGljeVJlcXVlc3R9CiAgICAgICAqIEBzaW5jZSAxLjEzCiAgICAgICAqLwogICAgICBwcm90ZWN0ZWQgU2V0T3JnUG9saWN5KGphdmEubGFuZy5TdHJpbmcgcmVzb3VyY2UsIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmNsb3VkcmVzb3VyY2VtYW5hZ2VyLm1vZGVsLlNldE9yZ1BvbGljeVJlcXVlc3QgY29udGVudCkgewogICAgICAgIHN1cGVyKENsb3VkUmVzb3VyY2VNYW5hZ2VyLnRoaXMsICJQT1NUIiwgUkVTVF9QQVRILCBjb250ZW50LCBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5jbG91ZHJlc291cmNlbWFuYWdlci5tb2RlbC5PcmdQb2xpY3kuY2xhc3MpOwogICAgICAgIHRoaXMucmVzb3VyY2UgPSBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5QcmVjb25kaXRpb25zLmNoZWNrTm90TnVsbChyZXNvdXJjZSwgIlJlcXVpcmVkIHBhcmFtZXRlciByZXNvdXJjZSBtdXN0IGJlIHNwZWNpZmllZC4iKTsKICAgICAgICBpZiAoIWdldFN1cHByZXNzUGF0dGVybkNoZWNrcygpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5QcmVjb25kaXRpb25zLmNoZWNrQXJndW1lbnQoUkVTT1VSQ0VfUEFUVEVSTi5tYXRjaGVyKHJlc291cmNlKS5tYXRjaGVzKCksCiAgICAgICAgICAgICAgIlBhcmFtZXRlciByZXNvdXJjZSBtdXN0IGNvbmZvcm0gdG8gdGhlIHBhdHRlcm4gIiArCiAgICAgICAgICAgICAgIl5mb2xkZXJzL1teL10rJCIpOwogICAgICAgIH0KICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBTZXRPcmdQb2xpY3kgc2V0JFhnYWZ2KGphdmEubGFuZy5TdHJpbmcgJFhnYWZ2KSB7CiAgICAgICAgcmV0dXJuIChTZXRPcmdQb2xpY3kpIHN1cGVyLnNldCRYZ2FmdigkWGdhZnYpOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIFNldE9yZ1BvbGljeSBzZXRBY2Nlc3NUb2tlbihqYXZhLmxhbmcuU3RyaW5nIGFjY2Vzc1Rva2VuKSB7CiAgICAgICAgcmV0dXJuIChTZXRPcmdQb2xpY3kpIHN1cGVyLnNldEFjY2Vzc1Rva2VuKGFjY2Vzc1Rva2VuKTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBTZXRPcmdQb2xpY3kgc2V0QWx0KGphdmEubGFuZy5TdHJpbmcgYWx0KSB7CiAgICAgICAgcmV0dXJuIChTZXRPcmdQb2xpY3kpIHN1cGVyLnNldEFsdChhbHQpOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIFNldE9yZ1BvbGljeSBzZXRDYWxsYmFjayhqYXZhLmxhbmcuU3RyaW5nIGNhbGxiYWNrKSB7CiAgICAgICAgcmV0dXJuIChTZXRPcmdQb2xpY3kpIHN1cGVyLnNldENhbGxiYWNrKGNhbGxiYWNrKTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBTZXRPcmdQb2xpY3kgc2V0RmllbGRzKGphdmEubGFuZy5TdHJpbmcgZmllbGRzKSB7CiAgICAgICAgcmV0dXJuIChTZXRPcmdQb2xpY3kpIHN1cGVyLnNldEZpZWxkcyhmaWVsZHMpOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIFNldE9yZ1BvbGljeSBzZXRLZXkoamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICByZXR1cm4gKFNldE9yZ1BvbGljeSkgc3VwZXIuc2V0S2V5KGtleSk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgU2V0T3JnUG9saWN5IHNldE9hdXRoVG9rZW4oamF2YS5sYW5nLlN0cmluZyBvYXV0aFRva2VuKSB7CiAgICAgICAgcmV0dXJuIChTZXRPcmdQb2xpY3kpIHN1cGVyLnNldE9hdXRoVG9rZW4ob2F1dGhUb2tlbik7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgU2V0T3JnUG9saWN5IHNldFByZXR0eVByaW50KGphdmEubGFuZy5Cb29sZWFuIHByZXR0eVByaW50KSB7CiAgICAgICAgcmV0dXJuIChTZXRPcmdQb2xpY3kpIHN1cGVyLnNldFByZXR0eVByaW50KHByZXR0eVByaW50KTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBTZXRPcmdQb2xpY3kgc2V0UXVvdGFVc2VyKGphdmEubGFuZy5TdHJpbmcgcXVvdGFVc2VyKSB7CiAgICAgICAgcmV0dXJuIChTZXRPcmdQb2xpY3kpIHN1cGVyLnNldFF1b3RhVXNlcihxdW90YVVzZXIpOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIFNldE9yZ1BvbGljeSBzZXRVcGxvYWRUeXBlKGphdmEubGFuZy5TdHJpbmcgdXBsb2FkVHlwZSkgewogICAgICAgIHJldHVybiAoU2V0T3JnUG9saWN5KSBzdXBlci5zZXRVcGxvYWRUeXBlKHVwbG9hZFR5cGUpOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIFNldE9yZ1BvbGljeSBzZXRVcGxvYWRQcm90b2NvbChqYXZhLmxhbmcuU3RyaW5nIHVwbG9hZFByb3RvY29sKSB7CiAgICAgICAgcmV0dXJuIChTZXRPcmdQb2xpY3kpIHN1cGVyLnNldFVwbG9hZFByb3RvY29sKHVwbG9hZFByb3RvY29sKTsKICAgICAgfQoKICAgICAgLyoqIFJlc291cmNlIG5hbWUgb2YgdGhlIHJlc291cmNlIHRvIGF0dGFjaCB0aGUgYFBvbGljeWAuICovCiAgICAgIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuU3RyaW5nIHJlc291cmNlOwoKICAgICAgLyoqIFJlc291cmNlIG5hbWUgb2YgdGhlIHJlc291cmNlIHRvIGF0dGFjaCB0aGUgYFBvbGljeWAuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRSZXNvdXJjZSgpIHsKICAgICAgICByZXR1cm4gcmVzb3VyY2U7CiAgICAgIH0KCiAgICAgIC8qKiBSZXNvdXJjZSBuYW1lIG9mIHRoZSByZXNvdXJjZSB0byBhdHRhY2ggdGhlIGBQb2xpY3lgLiAqLwogICAgICBwdWJsaWMgU2V0T3JnUG9saWN5IHNldFJlc291cmNlKGphdmEubGFuZy5TdHJpbmcgcmVzb3VyY2UpIHsKICAgICAgICBpZiAoIWdldFN1cHByZXNzUGF0dGVybkNoZWNrcygpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5QcmVjb25kaXRpb25zLmNoZWNrQXJndW1lbnQoUkVTT1VSQ0VfUEFUVEVSTi5tYXRjaGVyKHJlc291cmNlKS5tYXRjaGVzKCksCiAgICAgICAgICAgICAgIlBhcmFtZXRlciByZXNvdXJjZSBtdXN0IGNvbmZvcm0gdG8gdGhlIHBhdHRlcm4gIiArCiAgICAgICAgICAgICAgIl5mb2xkZXJzL1teL10rJCIpOwogICAgICAgIH0KICAgICAgICB0aGlzLnJlc291cmNlID0gcmVzb3VyY2U7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgU2V0T3JnUG9saWN5IHNldChTdHJpbmcgcGFyYW1ldGVyTmFtZSwgT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIChTZXRPcmdQb2xpY3kpIHN1cGVyLnNldChwYXJhbWV0ZXJOYW1lLCB2YWx1ZSk7CiAgICAgIH0KICAgIH0KCiAgfQoKICAvKioKICAgKiBBbiBhY2Nlc3NvciBmb3IgY3JlYXRpbmcgcmVxdWVzdHMgZnJvbSB0aGUgTGllbnMgY29sbGVjdGlvbi4KICAgKgogICAqIDxwPlRoZSB0eXBpY2FsIHVzZSBpczo8L3A+CiAgICogPHByZT4KICAgKiAgIHtAY29kZSBDbG91ZFJlc291cmNlTWFuYWdlciBjbG91ZHJlc291cmNlbWFuYWdlciA9IG5ldyBDbG91ZFJlc291cmNlTWFuYWdlciguLi4pO30KICAgKiAgIHtAY29kZSBDbG91ZFJlc291cmNlTWFuYWdlci5MaWVucy5MaXN0IHJlcXVlc3QgPSBjbG91ZHJlc291cmNlbWFuYWdlci5saWVucygpLmxpc3QocGFyYW1ldGVycyAuLi4pfQogICAqIDwvcHJlPgogICAqCiAgICogQHJldHVybiB0aGUgcmVzb3VyY2UgY29sbGVjdGlvbgogICAqLwogIHB1YmxpYyBMaWVucyBsaWVucygpIHsKICAgIHJldHVybiBuZXcgTGllbnMoKTsKICB9CgogIC8qKgogICAqIFRoZSAibGllbnMiIGNvbGxlY3Rpb24gb2YgbWV0aG9kcy4KICAgKi8KICBwdWJsaWMgY2xhc3MgTGllbnMgewoKICAgIC8qKgogICAgICogQ3JlYXRlIGEgTGllbiB3aGljaCBhcHBsaWVzIHRvIHRoZSByZXNvdXJjZSBkZW5vdGVkIGJ5IHRoZSBgcGFyZW50YCBmaWVsZC4KICAgICAqCiAgICAgKiBDYWxsZXJzIG9mIHRoaXMgbWV0aG9kIHdpbGwgcmVxdWlyZSBwZXJtaXNzaW9uIG9uIHRoZSBgcGFyZW50YCByZXNvdXJjZS4gRm9yIGV4YW1wbGUsIGFwcGx5aW5nIHRvCiAgICAgKiBgcHJvamVjdHMvMTIzNGAgcmVxdWlyZXMgcGVybWlzc2lvbiBgcmVzb3VyY2VtYW5hZ2VyLnByb2plY3RzLnVwZGF0ZUxpZW5zYC4KICAgICAqCiAgICAgKiBOT1RFOiBTb21lIHJlc291cmNlcyBtYXkgbGltaXQgdGhlIG51bWJlciBvZiBMaWVucyB3aGljaCBtYXkgYmUgYXBwbGllZC4KICAgICAqCiAgICAgKiBDcmVhdGUgYSByZXF1ZXN0IGZvciB0aGUgbWV0aG9kICJsaWVucy5jcmVhdGUiLgogICAgICoKICAgICAqIFRoaXMgcmVxdWVzdCBob2xkcyB0aGUgcGFyYW1ldGVycyBuZWVkZWQgYnkgdGhlIGNsb3VkcmVzb3VyY2VtYW5hZ2VyIHNlcnZlci4gIEFmdGVyIHNldHRpbmcgYW55CiAgICAgKiBvcHRpb25hbCBwYXJhbWV0ZXJzLCBjYWxsIHRoZSB7QGxpbmsgQ3JlYXRlI2V4ZWN1dGUoKX0gbWV0aG9kIHRvIGludm9rZSB0aGUgcmVtb3RlIG9wZXJhdGlvbi4KICAgICAqCiAgICAgKiBAcGFyYW0gY29udGVudCB0aGUge0BsaW5rIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmNsb3VkcmVzb3VyY2VtYW5hZ2VyLm1vZGVsLkxpZW59CiAgICAgKiBAcmV0dXJuIHRoZSByZXF1ZXN0CiAgICAgKi8KICAgIHB1YmxpYyBDcmVhdGUgY3JlYXRlKGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmNsb3VkcmVzb3VyY2VtYW5hZ2VyLm1vZGVsLkxpZW4gY29udGVudCkgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBDcmVhdGUgcmVzdWx0ID0gbmV3IENyZWF0ZShjb250ZW50KTsKICAgICAgaW5pdGlhbGl6ZShyZXN1bHQpOwogICAgICByZXR1cm4gcmVzdWx0OwogICAgfQoKICAgIHB1YmxpYyBjbGFzcyBDcmVhdGUgZXh0ZW5kcyBDbG91ZFJlc291cmNlTWFuYWdlclJlcXVlc3Q8Y29tLmdvb2dsZS5hcGkuc2VydmljZXMuY2xvdWRyZXNvdXJjZW1hbmFnZXIubW9kZWwuTGllbj4gewoKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFJFU1RfUEFUSCA9ICJ2MS9saWVucyI7CgogICAgICAvKioKICAgICAgICogQ3JlYXRlIGEgTGllbiB3aGljaCBhcHBsaWVzIHRvIHRoZSByZXNvdXJjZSBkZW5vdGVkIGJ5IHRoZSBgcGFyZW50YCBmaWVsZC4KICAgICAgICoKICAgICAgICogQ2FsbGVycyBvZiB0aGlzIG1ldGhvZCB3aWxsIHJlcXVpcmUgcGVybWlzc2lvbiBvbiB0aGUgYHBhcmVudGAgcmVzb3VyY2UuIEZvciBleGFtcGxlLCBhcHBseWluZwogICAgICAgKiB0byBgcHJvamVjdHMvMTIzNGAgcmVxdWlyZXMgcGVybWlzc2lvbiBgcmVzb3VyY2VtYW5hZ2VyLnByb2plY3RzLnVwZGF0ZUxpZW5zYC4KICAgICAgICoKICAgICAgICogTk9URTogU29tZSByZXNvdXJjZXMgbWF5IGxpbWl0IHRoZSBudW1iZXIgb2YgTGllbnMgd2hpY2ggbWF5IGJlIGFwcGxpZWQuCiAgICAgICAqCiAgICAgICAqIENyZWF0ZSBhIHJlcXVlc3QgZm9yIHRoZSBtZXRob2QgImxpZW5zLmNyZWF0ZSIuCiAgICAgICAqCiAgICAgICAqIFRoaXMgcmVxdWVzdCBob2xkcyB0aGUgcGFyYW1ldGVycyBuZWVkZWQgYnkgdGhlIHRoZSBjbG91ZHJlc291cmNlbWFuYWdlciBzZXJ2ZXIuICBBZnRlciBzZXR0aW5nCiAgICAgICAqIGFueSBvcHRpb25hbCBwYXJhbWV0ZXJzLCBjYWxsIHRoZSB7QGxpbmsgQ3JlYXRlI2V4ZWN1dGUoKX0gbWV0aG9kIHRvIGludm9rZSB0aGUgcmVtb3RlCiAgICAgICAqIG9wZXJhdGlvbi4gPHA+IHtAbGluawogICAgICAgKiBDcmVhdGUjaW5pdGlhbGl6ZShjb20uZ29vZ2xlLmFwaS5jbGllbnQuZ29vZ2xlYXBpcy5zZXJ2aWNlcy5BYnN0cmFjdEdvb2dsZUNsaWVudFJlcXVlc3QpfSBtdXN0CiAgICAgICAqIGJlIGNhbGxlZCB0byBpbml0aWFsaXplIHRoaXMgaW5zdGFuY2UgaW1tZWRpYXRlbHkgYWZ0ZXIgaW52b2tpbmcgdGhlIGNvbnN0cnVjdG9yLiA8L3A+CiAgICAgICAqCiAgICAgICAqIEBwYXJhbSBjb250ZW50IHRoZSB7QGxpbmsgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuY2xvdWRyZXNvdXJjZW1hbmFnZXIubW9kZWwuTGllbn0KICAgICAgICogQHNpbmNlIDEuMTMKICAgICAgICovCiAgICAgIHByb3RlY3RlZCBDcmVhdGUoY29tLmdvb2dsZS5hcGkuc2VydmljZXMuY2xvdWRyZXNvdXJjZW1hbmFnZXIubW9kZWwuTGllbiBjb250ZW50KSB7CiAgICAgICAgc3VwZXIoQ2xvdWRSZXNvdXJjZU1hbmFnZXIudGhpcywgIlBPU1QiLCBSRVNUX1BBVEgsIGNvbnRlbnQsIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmNsb3VkcmVzb3VyY2VtYW5hZ2VyLm1vZGVsLkxpZW4uY2xhc3MpOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIENyZWF0ZSBzZXQkWGdhZnYoamF2YS5sYW5nLlN0cmluZyAkWGdhZnYpIHsKICAgICAgICByZXR1cm4gKENyZWF0ZSkgc3VwZXIuc2V0JFhnYWZ2KCRYZ2Fmdik7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgQ3JlYXRlIHNldEFjY2Vzc1Rva2VuKGphdmEubGFuZy5TdHJpbmcgYWNjZXNzVG9rZW4pIHsKICAgICAgICByZXR1cm4gKENyZWF0ZSkgc3VwZXIuc2V0QWNjZXNzVG9rZW4oYWNjZXNzVG9rZW4pOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIENyZWF0ZSBzZXRBbHQoamF2YS5sYW5nLlN0cmluZyBhbHQpIHsKICAgICAgICByZXR1cm4gKENyZWF0ZSkgc3VwZXIuc2V0QWx0KGFsdCk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgQ3JlYXRlIHNldENhbGxiYWNrKGphdmEubGFuZy5TdHJpbmcgY2FsbGJhY2spIHsKICAgICAgICByZXR1cm4gKENyZWF0ZSkgc3VwZXIuc2V0Q2FsbGJhY2soY2FsbGJhY2spOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIENyZWF0ZSBzZXRGaWVsZHMoamF2YS5sYW5nLlN0cmluZyBmaWVsZHMpIHsKICAgICAgICByZXR1cm4gKENyZWF0ZSkgc3VwZXIuc2V0RmllbGRzKGZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgQ3JlYXRlIHNldEtleShqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIHJldHVybiAoQ3JlYXRlKSBzdXBlci5zZXRLZXkoa2V5KTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBDcmVhdGUgc2V0T2F1dGhUb2tlbihqYXZhLmxhbmcuU3RyaW5nIG9hdXRoVG9rZW4pIHsKICAgICAgICByZXR1cm4gKENyZWF0ZSkgc3VwZXIuc2V0T2F1dGhUb2tlbihvYXV0aFRva2VuKTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBDcmVhdGUgc2V0UHJldHR5UHJpbnQoamF2YS5sYW5nLkJvb2xlYW4gcHJldHR5UHJpbnQpIHsKICAgICAgICByZXR1cm4gKENyZWF0ZSkgc3VwZXIuc2V0UHJldHR5UHJpbnQocHJldHR5UHJpbnQpOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIENyZWF0ZSBzZXRRdW90YVVzZXIoamF2YS5sYW5nLlN0cmluZyBxdW90YVVzZXIpIHsKICAgICAgICByZXR1cm4gKENyZWF0ZSkgc3VwZXIuc2V0UXVvdGFVc2VyKHF1b3RhVXNlcik7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgQ3JlYXRlIHNldFVwbG9hZFR5cGUoamF2YS5sYW5nLlN0cmluZyB1cGxvYWRUeXBlKSB7CiAgICAgICAgcmV0dXJuIChDcmVhdGUpIHN1cGVyLnNldFVwbG9hZFR5cGUodXBsb2FkVHlwZSk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgQ3JlYXRlIHNldFVwbG9hZFByb3RvY29sKGphdmEubGFuZy5TdHJpbmcgdXBsb2FkUHJvdG9jb2wpIHsKICAgICAgICByZXR1cm4gKENyZWF0ZSkgc3VwZXIuc2V0VXBsb2FkUHJvdG9jb2wodXBsb2FkUHJvdG9jb2wpOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIENyZWF0ZSBzZXQoU3RyaW5nIHBhcmFtZXRlck5hbWUsIE9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiAoQ3JlYXRlKSBzdXBlci5zZXQocGFyYW1ldGVyTmFtZSwgdmFsdWUpOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIERlbGV0ZSBhIExpZW4gYnkgYG5hbWVgLgogICAgICoKICAgICAqIENhbGxlcnMgb2YgdGhpcyBtZXRob2Qgd2lsbCByZXF1aXJlIHBlcm1pc3Npb24gb24gdGhlIGBwYXJlbnRgIHJlc291cmNlLiBGb3IgZXhhbXBsZSwgYSBMaWVuIHdpdGgKICAgICAqIGEgYHBhcmVudGAgb2YgYHByb2plY3RzLzEyMzRgIHJlcXVpcmVzIHBlcm1pc3Npb24gYHJlc291cmNlbWFuYWdlci5wcm9qZWN0cy51cGRhdGVMaWVuc2AuCiAgICAgKgogICAgICogQ3JlYXRlIGEgcmVxdWVzdCBmb3IgdGhlIG1ldGhvZCAibGllbnMuZGVsZXRlIi4KICAgICAqCiAgICAgKiBUaGlzIHJlcXVlc3QgaG9sZHMgdGhlIHBhcmFtZXRlcnMgbmVlZGVkIGJ5IHRoZSBjbG91ZHJlc291cmNlbWFuYWdlciBzZXJ2ZXIuICBBZnRlciBzZXR0aW5nIGFueQogICAgICogb3B0aW9uYWwgcGFyYW1ldGVycywgY2FsbCB0aGUge0BsaW5rIERlbGV0ZSNleGVjdXRlKCl9IG1ldGhvZCB0byBpbnZva2UgdGhlIHJlbW90ZSBvcGVyYXRpb24uCiAgICAgKgogICAgICogQHBhcmFtIG5hbWUgUmVxdWlyZWQuIFRoZSBuYW1lL2lkZW50aWZpZXIgb2YgdGhlIExpZW4gdG8gZGVsZXRlLgogICAgICogQHJldHVybiB0aGUgcmVxdWVzdAogICAgICovCiAgICBwdWJsaWMgRGVsZXRlIGRlbGV0ZShqYXZhLmxhbmcuU3RyaW5nIG5hbWUpIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgRGVsZXRlIHJlc3VsdCA9IG5ldyBEZWxldGUobmFtZSk7CiAgICAgIGluaXRpYWxpemUocmVzdWx0KTsKICAgICAgcmV0dXJuIHJlc3VsdDsKICAgIH0KCiAgICBwdWJsaWMgY2xhc3MgRGVsZXRlIGV4dGVuZHMgQ2xvdWRSZXNvdXJjZU1hbmFnZXJSZXF1ZXN0PGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmNsb3VkcmVzb3VyY2VtYW5hZ2VyLm1vZGVsLkVtcHR5PiB7CgogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgUkVTVF9QQVRIID0gInYxL3srbmFtZX0iOwoKICAgICAgcHJpdmF0ZSBmaW5hbCBqYXZhLnV0aWwucmVnZXguUGF0dGVybiBOQU1FX1BBVFRFUk4gPQogICAgICAgICAgamF2YS51dGlsLnJlZ2V4LlBhdHRlcm4uY29tcGlsZSgiXmxpZW5zLy4qJCIpOwoKICAgICAgLyoqCiAgICAgICAqIERlbGV0ZSBhIExpZW4gYnkgYG5hbWVgLgogICAgICAgKgogICAgICAgKiBDYWxsZXJzIG9mIHRoaXMgbWV0aG9kIHdpbGwgcmVxdWlyZSBwZXJtaXNzaW9uIG9uIHRoZSBgcGFyZW50YCByZXNvdXJjZS4gRm9yIGV4YW1wbGUsIGEgTGllbgogICAgICAgKiB3aXRoIGEgYHBhcmVudGAgb2YgYHByb2plY3RzLzEyMzRgIHJlcXVpcmVzIHBlcm1pc3Npb24gYHJlc291cmNlbWFuYWdlci5wcm9qZWN0cy51cGRhdGVMaWVuc2AuCiAgICAgICAqCiAgICAgICAqIENyZWF0ZSBhIHJlcXVlc3QgZm9yIHRoZSBtZXRob2QgImxpZW5zLmRlbGV0ZSIuCiAgICAgICAqCiAgICAgICAqIFRoaXMgcmVxdWVzdCBob2xkcyB0aGUgcGFyYW1ldGVycyBuZWVkZWQgYnkgdGhlIHRoZSBjbG91ZHJlc291cmNlbWFuYWdlciBzZXJ2ZXIuICBBZnRlciBzZXR0aW5nCiAgICAgICAqIGFueSBvcHRpb25hbCBwYXJhbWV0ZXJzLCBjYWxsIHRoZSB7QGxpbmsgRGVsZXRlI2V4ZWN1dGUoKX0gbWV0aG9kIHRvIGludm9rZSB0aGUgcmVtb3RlCiAgICAgICAqIG9wZXJhdGlvbi4gPHA+IHtAbGluawogICAgICAgKiBEZWxldGUjaW5pdGlhbGl6ZShjb20uZ29vZ2xlLmFwaS5jbGllbnQuZ29vZ2xlYXBpcy5zZXJ2aWNlcy5BYnN0cmFjdEdvb2dsZUNsaWVudFJlcXVlc3QpfSBtdXN0CiAgICAgICAqIGJlIGNhbGxlZCB0byBpbml0aWFsaXplIHRoaXMgaW5zdGFuY2UgaW1tZWRpYXRlbHkgYWZ0ZXIgaW52b2tpbmcgdGhlIGNvbnN0cnVjdG9yLiA8L3A+CiAgICAgICAqCiAgICAgICAqIEBwYXJhbSBuYW1lIFJlcXVpcmVkLiBUaGUgbmFtZS9pZGVudGlmaWVyIG9mIHRoZSBMaWVuIHRvIGRlbGV0ZS4KICAgICAgICogQHNpbmNlIDEuMTMKICAgICAgICovCiAgICAgIHByb3RlY3RlZCBEZWxldGUoamF2YS5sYW5nLlN0cmluZyBuYW1lKSB7CiAgICAgICAgc3VwZXIoQ2xvdWRSZXNvdXJjZU1hbmFnZXIudGhpcywgIkRFTEVURSIsIFJFU1RfUEFUSCwgbnVsbCwgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuY2xvdWRyZXNvdXJjZW1hbmFnZXIubW9kZWwuRW1wdHkuY2xhc3MpOwogICAgICAgIHRoaXMubmFtZSA9IGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLlByZWNvbmRpdGlvbnMuY2hlY2tOb3ROdWxsKG5hbWUsICJSZXF1aXJlZCBwYXJhbWV0ZXIgbmFtZSBtdXN0IGJlIHNwZWNpZmllZC4iKTsKICAgICAgICBpZiAoIWdldFN1cHByZXNzUGF0dGVybkNoZWNrcygpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5QcmVjb25kaXRpb25zLmNoZWNrQXJndW1lbnQoTkFNRV9QQVRURVJOLm1hdGNoZXIobmFtZSkubWF0Y2hlcygpLAogICAgICAgICAgICAgICJQYXJhbWV0ZXIgbmFtZSBtdXN0IGNvbmZvcm0gdG8gdGhlIHBhdHRlcm4gIiArCiAgICAgICAgICAgICAgIl5saWVucy8uKiQiKTsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgRGVsZXRlIHNldCRYZ2FmdihqYXZhLmxhbmcuU3RyaW5nICRYZ2FmdikgewogICAgICAgIHJldHVybiAoRGVsZXRlKSBzdXBlci5zZXQkWGdhZnYoJFhnYWZ2KTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBEZWxldGUgc2V0QWNjZXNzVG9rZW4oamF2YS5sYW5nLlN0cmluZyBhY2Nlc3NUb2tlbikgewogICAgICAgIHJldHVybiAoRGVsZXRlKSBzdXBlci5zZXRBY2Nlc3NUb2tlbihhY2Nlc3NUb2tlbik7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgRGVsZXRlIHNldEFsdChqYXZhLmxhbmcuU3RyaW5nIGFsdCkgewogICAgICAgIHJldHVybiAoRGVsZXRlKSBzdXBlci5zZXRBbHQoYWx0KTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBEZWxldGUgc2V0Q2FsbGJhY2soamF2YS5sYW5nLlN0cmluZyBjYWxsYmFjaykgewogICAgICAgIHJldHVybiAoRGVsZXRlKSBzdXBlci5zZXRDYWxsYmFjayhjYWxsYmFjayk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgRGVsZXRlIHNldEZpZWxkcyhqYXZhLmxhbmcuU3RyaW5nIGZpZWxkcykgewogICAgICAgIHJldHVybiAoRGVsZXRlKSBzdXBlci5zZXRGaWVsZHMoZmllbGRzKTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBEZWxldGUgc2V0S2V5KGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgcmV0dXJuIChEZWxldGUpIHN1cGVyLnNldEtleShrZXkpOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIERlbGV0ZSBzZXRPYXV0aFRva2VuKGphdmEubGFuZy5TdHJpbmcgb2F1dGhUb2tlbikgewogICAgICAgIHJldHVybiAoRGVsZXRlKSBzdXBlci5zZXRPYXV0aFRva2VuKG9hdXRoVG9rZW4pOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIERlbGV0ZSBzZXRQcmV0dHlQcmludChqYXZhLmxhbmcuQm9vbGVhbiBwcmV0dHlQcmludCkgewogICAgICAgIHJldHVybiAoRGVsZXRlKSBzdXBlci5zZXRQcmV0dHlQcmludChwcmV0dHlQcmludCk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgRGVsZXRlIHNldFF1b3RhVXNlcihqYXZhLmxhbmcuU3RyaW5nIHF1b3RhVXNlcikgewogICAgICAgIHJldHVybiAoRGVsZXRlKSBzdXBlci5zZXRRdW90YVVzZXIocXVvdGFVc2VyKTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBEZWxldGUgc2V0VXBsb2FkVHlwZShqYXZhLmxhbmcuU3RyaW5nIHVwbG9hZFR5cGUpIHsKICAgICAgICByZXR1cm4gKERlbGV0ZSkgc3VwZXIuc2V0VXBsb2FkVHlwZSh1cGxvYWRUeXBlKTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBEZWxldGUgc2V0VXBsb2FkUHJvdG9jb2woamF2YS5sYW5nLlN0cmluZyB1cGxvYWRQcm90b2NvbCkgewogICAgICAgIHJldHVybiAoRGVsZXRlKSBzdXBlci5zZXRVcGxvYWRQcm90b2NvbCh1cGxvYWRQcm90b2NvbCk7CiAgICAgIH0KCiAgICAgIC8qKiBSZXF1aXJlZC4gVGhlIG5hbWUvaWRlbnRpZmllciBvZiB0aGUgTGllbiB0byBkZWxldGUuICovCiAgICAgIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuU3RyaW5nIG5hbWU7CgogICAgICAvKiogUmVxdWlyZWQuIFRoZSBuYW1lL2lkZW50aWZpZXIgb2YgdGhlIExpZW4gdG8gZGVsZXRlLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TmFtZSgpIHsKICAgICAgICByZXR1cm4gbmFtZTsKICAgICAgfQoKICAgICAgLyoqIFJlcXVpcmVkLiBUaGUgbmFtZS9pZGVudGlmaWVyIG9mIHRoZSBMaWVuIHRvIGRlbGV0ZS4gKi8KICAgICAgcHVibGljIERlbGV0ZSBzZXROYW1lKGphdmEubGFuZy5TdHJpbmcgbmFtZSkgewogICAgICAgIGlmICghZ2V0U3VwcHJlc3NQYXR0ZXJuQ2hlY2tzKCkpIHsKICAgICAgICAgIGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLlByZWNvbmRpdGlvbnMuY2hlY2tBcmd1bWVudChOQU1FX1BBVFRFUk4ubWF0Y2hlcihuYW1lKS5tYXRjaGVzKCksCiAgICAgICAgICAgICAgIlBhcmFtZXRlciBuYW1lIG11c3QgY29uZm9ybSB0byB0aGUgcGF0dGVybiAiICsKICAgICAgICAgICAgICAiXmxpZW5zLy4qJCIpOwogICAgICAgIH0KICAgICAgICB0aGlzLm5hbWUgPSBuYW1lOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIERlbGV0ZSBzZXQoU3RyaW5nIHBhcmFtZXRlck5hbWUsIE9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiAoRGVsZXRlKSBzdXBlci5zZXQocGFyYW1ldGVyTmFtZSwgdmFsdWUpOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIFJldHJpZXZlIGEgTGllbiBieSBgbmFtZWAuCiAgICAgKgogICAgICogQ2FsbGVycyBvZiB0aGlzIG1ldGhvZCB3aWxsIHJlcXVpcmUgcGVybWlzc2lvbiBvbiB0aGUgYHBhcmVudGAgcmVzb3VyY2UuIEZvciBleGFtcGxlLCBhIExpZW4gd2l0aAogICAgICogYSBgcGFyZW50YCBvZiBgcHJvamVjdHMvMTIzNGAgcmVxdWlyZXMgcGVybWlzc2lvbiByZXF1aXJlcyBwZXJtaXNzaW9uCiAgICAgKiBgcmVzb3VyY2VtYW5hZ2VyLnByb2plY3RzLmdldGAgb3IgYHJlc291cmNlbWFuYWdlci5wcm9qZWN0cy51cGRhdGVMaWVuc2AuCiAgICAgKgogICAgICogQ3JlYXRlIGEgcmVxdWVzdCBmb3IgdGhlIG1ldGhvZCAibGllbnMuZ2V0Ii4KICAgICAqCiAgICAgKiBUaGlzIHJlcXVlc3QgaG9sZHMgdGhlIHBhcmFtZXRlcnMgbmVlZGVkIGJ5IHRoZSBjbG91ZHJlc291cmNlbWFuYWdlciBzZXJ2ZXIuICBBZnRlciBzZXR0aW5nIGFueQogICAgICogb3B0aW9uYWwgcGFyYW1ldGVycywgY2FsbCB0aGUge0BsaW5rIEdldCNleGVjdXRlKCl9IG1ldGhvZCB0byBpbnZva2UgdGhlIHJlbW90ZSBvcGVyYXRpb24uCiAgICAgKgogICAgICogQHBhcmFtIG5hbWUgUmVxdWlyZWQuIFRoZSBuYW1lL2lkZW50aWZpZXIgb2YgdGhlIExpZW4uCiAgICAgKiBAcmV0dXJuIHRoZSByZXF1ZXN0CiAgICAgKi8KICAgIHB1YmxpYyBHZXQgZ2V0KGphdmEubGFuZy5TdHJpbmcgbmFtZSkgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBHZXQgcmVzdWx0ID0gbmV3IEdldChuYW1lKTsKICAgICAgaW5pdGlhbGl6ZShyZXN1bHQpOwogICAgICByZXR1cm4gcmVzdWx0OwogICAgfQoKICAgIHB1YmxpYyBjbGFzcyBHZXQgZXh0ZW5kcyBDbG91ZFJlc291cmNlTWFuYWdlclJlcXVlc3Q8Y29tLmdvb2dsZS5hcGkuc2VydmljZXMuY2xvdWRyZXNvdXJjZW1hbmFnZXIubW9kZWwuTGllbj4gewoKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFJFU1RfUEFUSCA9ICJ2MS97K25hbWV9IjsKCiAgICAgIHByaXZhdGUgZmluYWwgamF2YS51dGlsLnJlZ2V4LlBhdHRlcm4gTkFNRV9QQVRURVJOID0KICAgICAgICAgIGphdmEudXRpbC5yZWdleC5QYXR0ZXJuLmNvbXBpbGUoIl5saWVucy8uKiQiKTsKCiAgICAgIC8qKgogICAgICAgKiBSZXRyaWV2ZSBhIExpZW4gYnkgYG5hbWVgLgogICAgICAgKgogICAgICAgKiBDYWxsZXJzIG9mIHRoaXMgbWV0aG9kIHdpbGwgcmVxdWlyZSBwZXJtaXNzaW9uIG9uIHRoZSBgcGFyZW50YCByZXNvdXJjZS4gRm9yIGV4YW1wbGUsIGEgTGllbgogICAgICAgKiB3aXRoIGEgYHBhcmVudGAgb2YgYHByb2plY3RzLzEyMzRgIHJlcXVpcmVzIHBlcm1pc3Npb24gcmVxdWlyZXMgcGVybWlzc2lvbgogICAgICAgKiBgcmVzb3VyY2VtYW5hZ2VyLnByb2plY3RzLmdldGAgb3IgYHJlc291cmNlbWFuYWdlci5wcm9qZWN0cy51cGRhdGVMaWVuc2AuCiAgICAgICAqCiAgICAgICAqIENyZWF0ZSBhIHJlcXVlc3QgZm9yIHRoZSBtZXRob2QgImxpZW5zLmdldCIuCiAgICAgICAqCiAgICAgICAqIFRoaXMgcmVxdWVzdCBob2xkcyB0aGUgcGFyYW1ldGVycyBuZWVkZWQgYnkgdGhlIHRoZSBjbG91ZHJlc291cmNlbWFuYWdlciBzZXJ2ZXIuICBBZnRlciBzZXR0aW5nCiAgICAgICAqIGFueSBvcHRpb25hbCBwYXJhbWV0ZXJzLCBjYWxsIHRoZSB7QGxpbmsgR2V0I2V4ZWN1dGUoKX0gbWV0aG9kIHRvIGludm9rZSB0aGUgcmVtb3RlIG9wZXJhdGlvbi4KICAgICAgICogPHA+IHtAbGluawogICAgICAgKiBHZXQjaW5pdGlhbGl6ZShjb20uZ29vZ2xlLmFwaS5jbGllbnQuZ29vZ2xlYXBpcy5zZXJ2aWNlcy5BYnN0cmFjdEdvb2dsZUNsaWVudFJlcXVlc3QpfSBtdXN0IGJlCiAgICAgICAqIGNhbGxlZCB0byBpbml0aWFsaXplIHRoaXMgaW5zdGFuY2UgaW1tZWRpYXRlbHkgYWZ0ZXIgaW52b2tpbmcgdGhlIGNvbnN0cnVjdG9yLiA8L3A+CiAgICAgICAqCiAgICAgICAqIEBwYXJhbSBuYW1lIFJlcXVpcmVkLiBUaGUgbmFtZS9pZGVudGlmaWVyIG9mIHRoZSBMaWVuLgogICAgICAgKiBAc2luY2UgMS4xMwogICAgICAgKi8KICAgICAgcHJvdGVjdGVkIEdldChqYXZhLmxhbmcuU3RyaW5nIG5hbWUpIHsKICAgICAgICBzdXBlcihDbG91ZFJlc291cmNlTWFuYWdlci50aGlzLCAiR0VUIiwgUkVTVF9QQVRILCBudWxsLCBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5jbG91ZHJlc291cmNlbWFuYWdlci5tb2RlbC5MaWVuLmNsYXNzKTsKICAgICAgICB0aGlzLm5hbWUgPSBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5QcmVjb25kaXRpb25zLmNoZWNrTm90TnVsbChuYW1lLCAiUmVxdWlyZWQgcGFyYW1ldGVyIG5hbWUgbXVzdCBiZSBzcGVjaWZpZWQuIik7CiAgICAgICAgaWYgKCFnZXRTdXBwcmVzc1BhdHRlcm5DaGVja3MoKSkgewogICAgICAgICAgY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuUHJlY29uZGl0aW9ucy5jaGVja0FyZ3VtZW50KE5BTUVfUEFUVEVSTi5tYXRjaGVyKG5hbWUpLm1hdGNoZXMoKSwKICAgICAgICAgICAgICAiUGFyYW1ldGVyIG5hbWUgbXVzdCBjb25mb3JtIHRvIHRoZSBwYXR0ZXJuICIgKwogICAgICAgICAgICAgICJebGllbnMvLiokIik7CiAgICAgICAgfQogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUuYXBpLmNsaWVudC5odHRwLkh0dHBSZXNwb25zZSBleGVjdXRlVXNpbmdIZWFkKCkgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBzdXBlci5leGVjdXRlVXNpbmdIZWFkKCk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5hcGkuY2xpZW50Lmh0dHAuSHR0cFJlcXVlc3QgYnVpbGRIdHRwUmVxdWVzdFVzaW5nSGVhZCgpIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gc3VwZXIuYnVpbGRIdHRwUmVxdWVzdFVzaW5nSGVhZCgpOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIEdldCBzZXQkWGdhZnYoamF2YS5sYW5nLlN0cmluZyAkWGdhZnYpIHsKICAgICAgICByZXR1cm4gKEdldCkgc3VwZXIuc2V0JFhnYWZ2KCRYZ2Fmdik7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgR2V0IHNldEFjY2Vzc1Rva2VuKGphdmEubGFuZy5TdHJpbmcgYWNjZXNzVG9rZW4pIHsKICAgICAgICByZXR1cm4gKEdldCkgc3VwZXIuc2V0QWNjZXNzVG9rZW4oYWNjZXNzVG9rZW4pOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIEdldCBzZXRBbHQoamF2YS5sYW5nLlN0cmluZyBhbHQpIHsKICAgICAgICByZXR1cm4gKEdldCkgc3VwZXIuc2V0QWx0KGFsdCk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgR2V0IHNldENhbGxiYWNrKGphdmEubGFuZy5TdHJpbmcgY2FsbGJhY2spIHsKICAgICAgICByZXR1cm4gKEdldCkgc3VwZXIuc2V0Q2FsbGJhY2soY2FsbGJhY2spOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIEdldCBzZXRGaWVsZHMoamF2YS5sYW5nLlN0cmluZyBmaWVsZHMpIHsKICAgICAgICByZXR1cm4gKEdldCkgc3VwZXIuc2V0RmllbGRzKGZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgR2V0IHNldEtleShqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIHJldHVybiAoR2V0KSBzdXBlci5zZXRLZXkoa2V5KTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBHZXQgc2V0T2F1dGhUb2tlbihqYXZhLmxhbmcuU3RyaW5nIG9hdXRoVG9rZW4pIHsKICAgICAgICByZXR1cm4gKEdldCkgc3VwZXIuc2V0T2F1dGhUb2tlbihvYXV0aFRva2VuKTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBHZXQgc2V0UHJldHR5UHJpbnQoamF2YS5sYW5nLkJvb2xlYW4gcHJldHR5UHJpbnQpIHsKICAgICAgICByZXR1cm4gKEdldCkgc3VwZXIuc2V0UHJldHR5UHJpbnQocHJldHR5UHJpbnQpOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIEdldCBzZXRRdW90YVVzZXIoamF2YS5sYW5nLlN0cmluZyBxdW90YVVzZXIpIHsKICAgICAgICByZXR1cm4gKEdldCkgc3VwZXIuc2V0UXVvdGFVc2VyKHF1b3RhVXNlcik7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgR2V0IHNldFVwbG9hZFR5cGUoamF2YS5sYW5nLlN0cmluZyB1cGxvYWRUeXBlKSB7CiAgICAgICAgcmV0dXJuIChHZXQpIHN1cGVyLnNldFVwbG9hZFR5cGUodXBsb2FkVHlwZSk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgR2V0IHNldFVwbG9hZFByb3RvY29sKGphdmEubGFuZy5TdHJpbmcgdXBsb2FkUHJvdG9jb2wpIHsKICAgICAgICByZXR1cm4gKEdldCkgc3VwZXIuc2V0VXBsb2FkUHJvdG9jb2wodXBsb2FkUHJvdG9jb2wpOwogICAgICB9CgogICAgICAvKiogUmVxdWlyZWQuIFRoZSBuYW1lL2lkZW50aWZpZXIgb2YgdGhlIExpZW4uICovCiAgICAgIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuU3RyaW5nIG5hbWU7CgogICAgICAvKiogUmVxdWlyZWQuIFRoZSBuYW1lL2lkZW50aWZpZXIgb2YgdGhlIExpZW4uCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXROYW1lKCkgewogICAgICAgIHJldHVybiBuYW1lOwogICAgICB9CgogICAgICAvKiogUmVxdWlyZWQuIFRoZSBuYW1lL2lkZW50aWZpZXIgb2YgdGhlIExpZW4uICovCiAgICAgIHB1YmxpYyBHZXQgc2V0TmFtZShqYXZhLmxhbmcuU3RyaW5nIG5hbWUpIHsKICAgICAgICBpZiAoIWdldFN1cHByZXNzUGF0dGVybkNoZWNrcygpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5QcmVjb25kaXRpb25zLmNoZWNrQXJndW1lbnQoTkFNRV9QQVRURVJOLm1hdGNoZXIobmFtZSkubWF0Y2hlcygpLAogICAgICAgICAgICAgICJQYXJhbWV0ZXIgbmFtZSBtdXN0IGNvbmZvcm0gdG8gdGhlIHBhdHRlcm4gIiArCiAgICAgICAgICAgICAgIl5saWVucy8uKiQiKTsKICAgICAgICB9CiAgICAgICAgdGhpcy5uYW1lID0gbmFtZTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBHZXQgc2V0KFN0cmluZyBwYXJhbWV0ZXJOYW1lLCBPYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gKEdldCkgc3VwZXIuc2V0KHBhcmFtZXRlck5hbWUsIHZhbHVlKTsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiBMaXN0IGFsbCBMaWVucyBhcHBsaWVkIHRvIHRoZSBgcGFyZW50YCByZXNvdXJjZS4KICAgICAqCiAgICAgKiBDYWxsZXJzIG9mIHRoaXMgbWV0aG9kIHdpbGwgcmVxdWlyZSBwZXJtaXNzaW9uIG9uIHRoZSBgcGFyZW50YCByZXNvdXJjZS4gRm9yIGV4YW1wbGUsIGEgTGllbiB3aXRoCiAgICAgKiBhIGBwYXJlbnRgIG9mIGBwcm9qZWN0cy8xMjM0YCByZXF1aXJlcyBwZXJtaXNzaW9uIGByZXNvdXJjZW1hbmFnZXIucHJvamVjdHMuZ2V0YC4KICAgICAqCiAgICAgKiBDcmVhdGUgYSByZXF1ZXN0IGZvciB0aGUgbWV0aG9kICJsaWVucy5saXN0Ii4KICAgICAqCiAgICAgKiBUaGlzIHJlcXVlc3QgaG9sZHMgdGhlIHBhcmFtZXRlcnMgbmVlZGVkIGJ5IHRoZSBjbG91ZHJlc291cmNlbWFuYWdlciBzZXJ2ZXIuICBBZnRlciBzZXR0aW5nIGFueQogICAgICogb3B0aW9uYWwgcGFyYW1ldGVycywgY2FsbCB0aGUge0BsaW5rIExpc3QjZXhlY3V0ZSgpfSBtZXRob2QgdG8gaW52b2tlIHRoZSByZW1vdGUgb3BlcmF0aW9uLgogICAgICoKICAgICAqIEByZXR1cm4gdGhlIHJlcXVlc3QKICAgICAqLwogICAgcHVibGljIExpc3QgbGlzdCgpIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgTGlzdCByZXN1bHQgPSBuZXcgTGlzdCgpOwogICAgICBpbml0aWFsaXplKHJlc3VsdCk7CiAgICAgIHJldHVybiByZXN1bHQ7CiAgICB9CgogICAgcHVibGljIGNsYXNzIExpc3QgZXh0ZW5kcyBDbG91ZFJlc291cmNlTWFuYWdlclJlcXVlc3Q8Y29tLmdvb2dsZS5hcGkuc2VydmljZXMuY2xvdWRyZXNvdXJjZW1hbmFnZXIubW9kZWwuTGlzdExpZW5zUmVzcG9uc2U+IHsKCiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBSRVNUX1BBVEggPSAidjEvbGllbnMiOwoKICAgICAgLyoqCiAgICAgICAqIExpc3QgYWxsIExpZW5zIGFwcGxpZWQgdG8gdGhlIGBwYXJlbnRgIHJlc291cmNlLgogICAgICAgKgogICAgICAgKiBDYWxsZXJzIG9mIHRoaXMgbWV0aG9kIHdpbGwgcmVxdWlyZSBwZXJtaXNzaW9uIG9uIHRoZSBgcGFyZW50YCByZXNvdXJjZS4gRm9yIGV4YW1wbGUsIGEgTGllbgogICAgICAgKiB3aXRoIGEgYHBhcmVudGAgb2YgYHByb2plY3RzLzEyMzRgIHJlcXVpcmVzIHBlcm1pc3Npb24gYHJlc291cmNlbWFuYWdlci5wcm9qZWN0cy5nZXRgLgogICAgICAgKgogICAgICAgKiBDcmVhdGUgYSByZXF1ZXN0IGZvciB0aGUgbWV0aG9kICJsaWVucy5saXN0Ii4KICAgICAgICoKICAgICAgICogVGhpcyByZXF1ZXN0IGhvbGRzIHRoZSBwYXJhbWV0ZXJzIG5lZWRlZCBieSB0aGUgdGhlIGNsb3VkcmVzb3VyY2VtYW5hZ2VyIHNlcnZlci4gIEFmdGVyIHNldHRpbmcKICAgICAgICogYW55IG9wdGlvbmFsIHBhcmFtZXRlcnMsIGNhbGwgdGhlIHtAbGluayBMaXN0I2V4ZWN1dGUoKX0gbWV0aG9kIHRvIGludm9rZSB0aGUgcmVtb3RlIG9wZXJhdGlvbi4KICAgICAgICogPHA+IHtAbGluawogICAgICAgKiBMaXN0I2luaXRpYWxpemUoY29tLmdvb2dsZS5hcGkuY2xpZW50Lmdvb2dsZWFwaXMuc2VydmljZXMuQWJzdHJhY3RHb29nbGVDbGllbnRSZXF1ZXN0KX0gbXVzdCBiZQogICAgICAgKiBjYWxsZWQgdG8gaW5pdGlhbGl6ZSB0aGlzIGluc3RhbmNlIGltbWVkaWF0ZWx5IGFmdGVyIGludm9raW5nIHRoZSBjb25zdHJ1Y3Rvci4gPC9wPgogICAgICAgKgogICAgICAgKiBAc2luY2UgMS4xMwogICAgICAgKi8KICAgICAgcHJvdGVjdGVkIExpc3QoKSB7CiAgICAgICAgc3VwZXIoQ2xvdWRSZXNvdXJjZU1hbmFnZXIudGhpcywgIkdFVCIsIFJFU1RfUEFUSCwgbnVsbCwgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuY2xvdWRyZXNvdXJjZW1hbmFnZXIubW9kZWwuTGlzdExpZW5zUmVzcG9uc2UuY2xhc3MpOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUuYXBpLmNsaWVudC5odHRwLkh0dHBSZXNwb25zZSBleGVjdXRlVXNpbmdIZWFkKCkgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBzdXBlci5leGVjdXRlVXNpbmdIZWFkKCk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5hcGkuY2xpZW50Lmh0dHAuSHR0cFJlcXVlc3QgYnVpbGRIdHRwUmVxdWVzdFVzaW5nSGVhZCgpIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gc3VwZXIuYnVpbGRIdHRwUmVxdWVzdFVzaW5nSGVhZCgpOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIExpc3Qgc2V0JFhnYWZ2KGphdmEubGFuZy5TdHJpbmcgJFhnYWZ2KSB7CiAgICAgICAgcmV0dXJuIChMaXN0KSBzdXBlci5zZXQkWGdhZnYoJFhnYWZ2KTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBMaXN0IHNldEFjY2Vzc1Rva2VuKGphdmEubGFuZy5TdHJpbmcgYWNjZXNzVG9rZW4pIHsKICAgICAgICByZXR1cm4gKExpc3QpIHN1cGVyLnNldEFjY2Vzc1Rva2VuKGFjY2Vzc1Rva2VuKTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBMaXN0IHNldEFsdChqYXZhLmxhbmcuU3RyaW5nIGFsdCkgewogICAgICAgIHJldHVybiAoTGlzdCkgc3VwZXIuc2V0QWx0KGFsdCk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgTGlzdCBzZXRDYWxsYmFjayhqYXZhLmxhbmcuU3RyaW5nIGNhbGxiYWNrKSB7CiAgICAgICAgcmV0dXJuIChMaXN0KSBzdXBlci5zZXRDYWxsYmFjayhjYWxsYmFjayk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgTGlzdCBzZXRGaWVsZHMoamF2YS5sYW5nLlN0cmluZyBmaWVsZHMpIHsKICAgICAgICByZXR1cm4gKExpc3QpIHN1cGVyLnNldEZpZWxkcyhmaWVsZHMpOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIExpc3Qgc2V0S2V5KGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgcmV0dXJuIChMaXN0KSBzdXBlci5zZXRLZXkoa2V5KTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBMaXN0IHNldE9hdXRoVG9rZW4oamF2YS5sYW5nLlN0cmluZyBvYXV0aFRva2VuKSB7CiAgICAgICAgcmV0dXJuIChMaXN0KSBzdXBlci5zZXRPYXV0aFRva2VuKG9hdXRoVG9rZW4pOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIExpc3Qgc2V0UHJldHR5UHJpbnQoamF2YS5sYW5nLkJvb2xlYW4gcHJldHR5UHJpbnQpIHsKICAgICAgICByZXR1cm4gKExpc3QpIHN1cGVyLnNldFByZXR0eVByaW50KHByZXR0eVByaW50KTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBMaXN0IHNldFF1b3RhVXNlcihqYXZhLmxhbmcuU3RyaW5nIHF1b3RhVXNlcikgewogICAgICAgIHJldHVybiAoTGlzdCkgc3VwZXIuc2V0UXVvdGFVc2VyKHF1b3RhVXNlcik7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgTGlzdCBzZXRVcGxvYWRUeXBlKGphdmEubGFuZy5TdHJpbmcgdXBsb2FkVHlwZSkgewogICAgICAgIHJldHVybiAoTGlzdCkgc3VwZXIuc2V0VXBsb2FkVHlwZSh1cGxvYWRUeXBlKTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBMaXN0IHNldFVwbG9hZFByb3RvY29sKGphdmEubGFuZy5TdHJpbmcgdXBsb2FkUHJvdG9jb2wpIHsKICAgICAgICByZXR1cm4gKExpc3QpIHN1cGVyLnNldFVwbG9hZFByb3RvY29sKHVwbG9hZFByb3RvY29sKTsKICAgICAgfQoKICAgICAgLyoqIFRoZSBtYXhpbXVtIG51bWJlciBvZiBpdGVtcyB0byByZXR1cm4uIFRoaXMgaXMgYSBzdWdnZXN0aW9uIGZvciB0aGUgc2VydmVyLiAqLwogICAgICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgICAgIHByaXZhdGUgamF2YS5sYW5nLkludGVnZXIgcGFnZVNpemU7CgogICAgICAvKiogVGhlIG1heGltdW0gbnVtYmVyIG9mIGl0ZW1zIHRvIHJldHVybi4gVGhpcyBpcyBhIHN1Z2dlc3Rpb24gZm9yIHRoZSBzZXJ2ZXIuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLkludGVnZXIgZ2V0UGFnZVNpemUoKSB7CiAgICAgICAgcmV0dXJuIHBhZ2VTaXplOwogICAgICB9CgogICAgICAvKiogVGhlIG1heGltdW0gbnVtYmVyIG9mIGl0ZW1zIHRvIHJldHVybi4gVGhpcyBpcyBhIHN1Z2dlc3Rpb24gZm9yIHRoZSBzZXJ2ZXIuICovCiAgICAgIHB1YmxpYyBMaXN0IHNldFBhZ2VTaXplKGphdmEubGFuZy5JbnRlZ2VyIHBhZ2VTaXplKSB7CiAgICAgICAgdGhpcy5wYWdlU2l6ZSA9IHBhZ2VTaXplOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICAvKioKICAgICAgICogUmVxdWlyZWQuIFRoZSBuYW1lIG9mIHRoZSByZXNvdXJjZSB0byBsaXN0IGFsbCBhdHRhY2hlZCBMaWVucy4gRm9yIGV4YW1wbGUsCiAgICAgICAqIGBwcm9qZWN0cy8xMjM0YC4KICAgICAgICoKICAgICAgICogKGdvb2dsZS5hcGkuZmllbGRfcG9saWN5KS5yZXNvdXJjZV90eXBlIGFubm90YXRpb24gaXMgbm90IHNldCBzaW5jZSB0aGUgcGFyZW50IGRlcGVuZHMgb24KICAgICAgICogdGhlIG1ldGEgYXBpIGltcGxlbWVudGF0aW9uLiBUaGlzIGZpZWxkIGNvdWxkIGJlIGEgcHJvamVjdCBvciBvdGhlciBzdWIgcHJvamVjdCByZXNvdXJjZXMuCiAgICAgICAqLwogICAgICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgICAgIHByaXZhdGUgamF2YS5sYW5nLlN0cmluZyBwYXJlbnQ7CgogICAgICAvKiogUmVxdWlyZWQuIFRoZSBuYW1lIG9mIHRoZSByZXNvdXJjZSB0byBsaXN0IGFsbCBhdHRhY2hlZCBMaWVucy4gRm9yIGV4YW1wbGUsIGBwcm9qZWN0cy8xMjM0YC4KCiAgICAgKGdvb2dsZS5hcGkuZmllbGRfcG9saWN5KS5yZXNvdXJjZV90eXBlIGFubm90YXRpb24gaXMgbm90IHNldCBzaW5jZSB0aGUgcGFyZW50IGRlcGVuZHMgb24gdGhlIG1ldGEKICAgICBhcGkgaW1wbGVtZW50YXRpb24uIFRoaXMgZmllbGQgY291bGQgYmUgYSBwcm9qZWN0IG9yIG90aGVyIHN1YiBwcm9qZWN0IHJlc291cmNlcy4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFBhcmVudCgpIHsKICAgICAgICByZXR1cm4gcGFyZW50OwogICAgICB9CgogICAgICAvKioKICAgICAgICogUmVxdWlyZWQuIFRoZSBuYW1lIG9mIHRoZSByZXNvdXJjZSB0byBsaXN0IGFsbCBhdHRhY2hlZCBMaWVucy4gRm9yIGV4YW1wbGUsCiAgICAgICAqIGBwcm9qZWN0cy8xMjM0YC4KICAgICAgICoKICAgICAgICogKGdvb2dsZS5hcGkuZmllbGRfcG9saWN5KS5yZXNvdXJjZV90eXBlIGFubm90YXRpb24gaXMgbm90IHNldCBzaW5jZSB0aGUgcGFyZW50IGRlcGVuZHMgb24KICAgICAgICogdGhlIG1ldGEgYXBpIGltcGxlbWVudGF0aW9uLiBUaGlzIGZpZWxkIGNvdWxkIGJlIGEgcHJvamVjdCBvciBvdGhlciBzdWIgcHJvamVjdCByZXNvdXJjZXMuCiAgICAgICAqLwogICAgICBwdWJsaWMgTGlzdCBzZXRQYXJlbnQoamF2YS5sYW5nLlN0cmluZyBwYXJlbnQpIHsKICAgICAgICB0aGlzLnBhcmVudCA9IHBhcmVudDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgLyoqIFRoZSBgbmV4dF9wYWdlX3Rva2VuYCB2YWx1ZSByZXR1cm5lZCBmcm9tIGEgcHJldmlvdXMgTGlzdCByZXF1ZXN0LCBpZiBhbnkuICovCiAgICAgIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuU3RyaW5nIHBhZ2VUb2tlbjsKCiAgICAgIC8qKiBUaGUgYG5leHRfcGFnZV90b2tlbmAgdmFsdWUgcmV0dXJuZWQgZnJvbSBhIHByZXZpb3VzIExpc3QgcmVxdWVzdCwgaWYgYW55LgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0UGFnZVRva2VuKCkgewogICAgICAgIHJldHVybiBwYWdlVG9rZW47CiAgICAgIH0KCiAgICAgIC8qKiBUaGUgYG5leHRfcGFnZV90b2tlbmAgdmFsdWUgcmV0dXJuZWQgZnJvbSBhIHByZXZpb3VzIExpc3QgcmVxdWVzdCwgaWYgYW55LiAqLwogICAgICBwdWJsaWMgTGlzdCBzZXRQYWdlVG9rZW4oamF2YS5sYW5nLlN0cmluZyBwYWdlVG9rZW4pIHsKICAgICAgICB0aGlzLnBhZ2VUb2tlbiA9IHBhZ2VUb2tlbjsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBMaXN0IHNldChTdHJpbmcgcGFyYW1ldGVyTmFtZSwgT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIChMaXN0KSBzdXBlci5zZXQocGFyYW1ldGVyTmFtZSwgdmFsdWUpOwogICAgICB9CiAgICB9CgogIH0KCiAgLyoqCiAgICogQW4gYWNjZXNzb3IgZm9yIGNyZWF0aW5nIHJlcXVlc3RzIGZyb20gdGhlIE9wZXJhdGlvbnMgY29sbGVjdGlvbi4KICAgKgogICAqIDxwPlRoZSB0eXBpY2FsIHVzZSBpczo8L3A+CiAgICogPHByZT4KICAgKiAgIHtAY29kZSBDbG91ZFJlc291cmNlTWFuYWdlciBjbG91ZHJlc291cmNlbWFuYWdlciA9IG5ldyBDbG91ZFJlc291cmNlTWFuYWdlciguLi4pO30KICAgKiAgIHtAY29kZSBDbG91ZFJlc291cmNlTWFuYWdlci5PcGVyYXRpb25zLkxpc3QgcmVxdWVzdCA9IGNsb3VkcmVzb3VyY2VtYW5hZ2VyLm9wZXJhdGlvbnMoKS5saXN0KHBhcmFtZXRlcnMgLi4uKX0KICAgKiA8L3ByZT4KICAgKgogICAqIEByZXR1cm4gdGhlIHJlc291cmNlIGNvbGxlY3Rpb24KICAgKi8KICBwdWJsaWMgT3BlcmF0aW9ucyBvcGVyYXRpb25zKCkgewogICAgcmV0dXJuIG5ldyBPcGVyYXRpb25zKCk7CiAgfQoKICAvKioKICAgKiBUaGUgIm9wZXJhdGlvbnMiIGNvbGxlY3Rpb24gb2YgbWV0aG9kcy4KICAgKi8KICBwdWJsaWMgY2xhc3MgT3BlcmF0aW9ucyB7CgogICAgLyoqCiAgICAgKiBHZXRzIHRoZSBsYXRlc3Qgc3RhdGUgb2YgYSBsb25nLXJ1bm5pbmcgb3BlcmF0aW9uLiAgQ2xpZW50cyBjYW4gdXNlIHRoaXMgbWV0aG9kIHRvIHBvbGwgdGhlCiAgICAgKiBvcGVyYXRpb24gcmVzdWx0IGF0IGludGVydmFscyBhcyByZWNvbW1lbmRlZCBieSB0aGUgQVBJIHNlcnZpY2UuCiAgICAgKgogICAgICogQ3JlYXRlIGEgcmVxdWVzdCBmb3IgdGhlIG1ldGhvZCAib3BlcmF0aW9ucy5nZXQiLgogICAgICoKICAgICAqIFRoaXMgcmVxdWVzdCBob2xkcyB0aGUgcGFyYW1ldGVycyBuZWVkZWQgYnkgdGhlIGNsb3VkcmVzb3VyY2VtYW5hZ2VyIHNlcnZlci4gIEFmdGVyIHNldHRpbmcgYW55CiAgICAgKiBvcHRpb25hbCBwYXJhbWV0ZXJzLCBjYWxsIHRoZSB7QGxpbmsgR2V0I2V4ZWN1dGUoKX0gbWV0aG9kIHRvIGludm9rZSB0aGUgcmVtb3RlIG9wZXJhdGlvbi4KICAgICAqCiAgICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSBvZiB0aGUgb3BlcmF0aW9uIHJlc291cmNlLgogICAgICogQHJldHVybiB0aGUgcmVxdWVzdAogICAgICovCiAgICBwdWJsaWMgR2V0IGdldChqYXZhLmxhbmcuU3RyaW5nIG5hbWUpIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgR2V0IHJlc3VsdCA9IG5ldyBHZXQobmFtZSk7CiAgICAgIGluaXRpYWxpemUocmVzdWx0KTsKICAgICAgcmV0dXJuIHJlc3VsdDsKICAgIH0KCiAgICBwdWJsaWMgY2xhc3MgR2V0IGV4dGVuZHMgQ2xvdWRSZXNvdXJjZU1hbmFnZXJSZXF1ZXN0PGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmNsb3VkcmVzb3VyY2VtYW5hZ2VyLm1vZGVsLk9wZXJhdGlvbj4gewoKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFJFU1RfUEFUSCA9ICJ2MS97K25hbWV9IjsKCiAgICAgIHByaXZhdGUgZmluYWwgamF2YS51dGlsLnJlZ2V4LlBhdHRlcm4gTkFNRV9QQVRURVJOID0KICAgICAgICAgIGphdmEudXRpbC5yZWdleC5QYXR0ZXJuLmNvbXBpbGUoIl5vcGVyYXRpb25zLy4qJCIpOwoKICAgICAgLyoqCiAgICAgICAqIEdldHMgdGhlIGxhdGVzdCBzdGF0ZSBvZiBhIGxvbmctcnVubmluZyBvcGVyYXRpb24uICBDbGllbnRzIGNhbiB1c2UgdGhpcyBtZXRob2QgdG8gcG9sbCB0aGUKICAgICAgICogb3BlcmF0aW9uIHJlc3VsdCBhdCBpbnRlcnZhbHMgYXMgcmVjb21tZW5kZWQgYnkgdGhlIEFQSSBzZXJ2aWNlLgogICAgICAgKgogICAgICAgKiBDcmVhdGUgYSByZXF1ZXN0IGZvciB0aGUgbWV0aG9kICJvcGVyYXRpb25zLmdldCIuCiAgICAgICAqCiAgICAgICAqIFRoaXMgcmVxdWVzdCBob2xkcyB0aGUgcGFyYW1ldGVycyBuZWVkZWQgYnkgdGhlIHRoZSBjbG91ZHJlc291cmNlbWFuYWdlciBzZXJ2ZXIuICBBZnRlciBzZXR0aW5nCiAgICAgICAqIGFueSBvcHRpb25hbCBwYXJhbWV0ZXJzLCBjYWxsIHRoZSB7QGxpbmsgR2V0I2V4ZWN1dGUoKX0gbWV0aG9kIHRvIGludm9rZSB0aGUgcmVtb3RlIG9wZXJhdGlvbi4KICAgICAgICogPHA+IHtAbGluawogICAgICAgKiBHZXQjaW5pdGlhbGl6ZShjb20uZ29vZ2xlLmFwaS5jbGllbnQuZ29vZ2xlYXBpcy5zZXJ2aWNlcy5BYnN0cmFjdEdvb2dsZUNsaWVudFJlcXVlc3QpfSBtdXN0IGJlCiAgICAgICAqIGNhbGxlZCB0byBpbml0aWFsaXplIHRoaXMgaW5zdGFuY2UgaW1tZWRpYXRlbHkgYWZ0ZXIgaW52b2tpbmcgdGhlIGNvbnN0cnVjdG9yLiA8L3A+CiAgICAgICAqCiAgICAgICAqIEBwYXJhbSBuYW1lIFRoZSBuYW1lIG9mIHRoZSBvcGVyYXRpb24gcmVzb3VyY2UuCiAgICAgICAqIEBzaW5jZSAxLjEzCiAgICAgICAqLwogICAgICBwcm90ZWN0ZWQgR2V0KGphdmEubGFuZy5TdHJpbmcgbmFtZSkgewogICAgICAgIHN1cGVyKENsb3VkUmVzb3VyY2VNYW5hZ2VyLnRoaXMsICJHRVQiLCBSRVNUX1BBVEgsIG51bGwsIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmNsb3VkcmVzb3VyY2VtYW5hZ2VyLm1vZGVsLk9wZXJhdGlvbi5jbGFzcyk7CiAgICAgICAgdGhpcy5uYW1lID0gY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuUHJlY29uZGl0aW9ucy5jaGVja05vdE51bGwobmFtZSwgIlJlcXVpcmVkIHBhcmFtZXRlciBuYW1lIG11c3QgYmUgc3BlY2lmaWVkLiIpOwogICAgICAgIGlmICghZ2V0U3VwcHJlc3NQYXR0ZXJuQ2hlY2tzKCkpIHsKICAgICAgICAgIGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLlByZWNvbmRpdGlvbnMuY2hlY2tBcmd1bWVudChOQU1FX1BBVFRFUk4ubWF0Y2hlcihuYW1lKS5tYXRjaGVzKCksCiAgICAgICAgICAgICAgIlBhcmFtZXRlciBuYW1lIG11c3QgY29uZm9ybSB0byB0aGUgcGF0dGVybiAiICsKICAgICAgICAgICAgICAiXm9wZXJhdGlvbnMvLiokIik7CiAgICAgICAgfQogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUuYXBpLmNsaWVudC5odHRwLkh0dHBSZXNwb25zZSBleGVjdXRlVXNpbmdIZWFkKCkgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBzdXBlci5leGVjdXRlVXNpbmdIZWFkKCk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5hcGkuY2xpZW50Lmh0dHAuSHR0cFJlcXVlc3QgYnVpbGRIdHRwUmVxdWVzdFVzaW5nSGVhZCgpIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gc3VwZXIuYnVpbGRIdHRwUmVxdWVzdFVzaW5nSGVhZCgpOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIEdldCBzZXQkWGdhZnYoamF2YS5sYW5nLlN0cmluZyAkWGdhZnYpIHsKICAgICAgICByZXR1cm4gKEdldCkgc3VwZXIuc2V0JFhnYWZ2KCRYZ2Fmdik7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgR2V0IHNldEFjY2Vzc1Rva2VuKGphdmEubGFuZy5TdHJpbmcgYWNjZXNzVG9rZW4pIHsKICAgICAgICByZXR1cm4gKEdldCkgc3VwZXIuc2V0QWNjZXNzVG9rZW4oYWNjZXNzVG9rZW4pOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIEdldCBzZXRBbHQoamF2YS5sYW5nLlN0cmluZyBhbHQpIHsKICAgICAgICByZXR1cm4gKEdldCkgc3VwZXIuc2V0QWx0KGFsdCk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgR2V0IHNldENhbGxiYWNrKGphdmEubGFuZy5TdHJpbmcgY2FsbGJhY2spIHsKICAgICAgICByZXR1cm4gKEdldCkgc3VwZXIuc2V0Q2FsbGJhY2soY2FsbGJhY2spOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIEdldCBzZXRGaWVsZHMoamF2YS5sYW5nLlN0cmluZyBmaWVsZHMpIHsKICAgICAgICByZXR1cm4gKEdldCkgc3VwZXIuc2V0RmllbGRzKGZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgR2V0IHNldEtleShqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIHJldHVybiAoR2V0KSBzdXBlci5zZXRLZXkoa2V5KTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBHZXQgc2V0T2F1dGhUb2tlbihqYXZhLmxhbmcuU3RyaW5nIG9hdXRoVG9rZW4pIHsKICAgICAgICByZXR1cm4gKEdldCkgc3VwZXIuc2V0T2F1dGhUb2tlbihvYXV0aFRva2VuKTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBHZXQgc2V0UHJldHR5UHJpbnQoamF2YS5sYW5nLkJvb2xlYW4gcHJldHR5UHJpbnQpIHsKICAgICAgICByZXR1cm4gKEdldCkgc3VwZXIuc2V0UHJldHR5UHJpbnQocHJldHR5UHJpbnQpOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIEdldCBzZXRRdW90YVVzZXIoamF2YS5sYW5nLlN0cmluZyBxdW90YVVzZXIpIHsKICAgICAgICByZXR1cm4gKEdldCkgc3VwZXIuc2V0UXVvdGFVc2VyKHF1b3RhVXNlcik7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgR2V0IHNldFVwbG9hZFR5cGUoamF2YS5sYW5nLlN0cmluZyB1cGxvYWRUeXBlKSB7CiAgICAgICAgcmV0dXJuIChHZXQpIHN1cGVyLnNldFVwbG9hZFR5cGUodXBsb2FkVHlwZSk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgR2V0IHNldFVwbG9hZFByb3RvY29sKGphdmEubGFuZy5TdHJpbmcgdXBsb2FkUHJvdG9jb2wpIHsKICAgICAgICByZXR1cm4gKEdldCkgc3VwZXIuc2V0VXBsb2FkUHJvdG9jb2wodXBsb2FkUHJvdG9jb2wpOwogICAgICB9CgogICAgICAvKiogVGhlIG5hbWUgb2YgdGhlIG9wZXJhdGlvbiByZXNvdXJjZS4gKi8KICAgICAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogICAgICBwcml2YXRlIGphdmEubGFuZy5TdHJpbmcgbmFtZTsKCiAgICAgIC8qKiBUaGUgbmFtZSBvZiB0aGUgb3BlcmF0aW9uIHJlc291cmNlLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TmFtZSgpIHsKICAgICAgICByZXR1cm4gbmFtZTsKICAgICAgfQoKICAgICAgLyoqIFRoZSBuYW1lIG9mIHRoZSBvcGVyYXRpb24gcmVzb3VyY2UuICovCiAgICAgIHB1YmxpYyBHZXQgc2V0TmFtZShqYXZhLmxhbmcuU3RyaW5nIG5hbWUpIHsKICAgICAgICBpZiAoIWdldFN1cHByZXNzUGF0dGVybkNoZWNrcygpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5QcmVjb25kaXRpb25zLmNoZWNrQXJndW1lbnQoTkFNRV9QQVRURVJOLm1hdGNoZXIobmFtZSkubWF0Y2hlcygpLAogICAgICAgICAgICAgICJQYXJhbWV0ZXIgbmFtZSBtdXN0IGNvbmZvcm0gdG8gdGhlIHBhdHRlcm4gIiArCiAgICAgICAgICAgICAgIl5vcGVyYXRpb25zLy4qJCIpOwogICAgICAgIH0KICAgICAgICB0aGlzLm5hbWUgPSBuYW1lOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIEdldCBzZXQoU3RyaW5nIHBhcmFtZXRlck5hbWUsIE9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiAoR2V0KSBzdXBlci5zZXQocGFyYW1ldGVyTmFtZSwgdmFsdWUpOwogICAgICB9CiAgICB9CgogIH0KCiAgLyoqCiAgICogQW4gYWNjZXNzb3IgZm9yIGNyZWF0aW5nIHJlcXVlc3RzIGZyb20gdGhlIE9yZ2FuaXphdGlvbnMgY29sbGVjdGlvbi4KICAgKgogICAqIDxwPlRoZSB0eXBpY2FsIHVzZSBpczo8L3A+CiAgICogPHByZT4KICAgKiAgIHtAY29kZSBDbG91ZFJlc291cmNlTWFuYWdlciBjbG91ZHJlc291cmNlbWFuYWdlciA9IG5ldyBDbG91ZFJlc291cmNlTWFuYWdlciguLi4pO30KICAgKiAgIHtAY29kZSBDbG91ZFJlc291cmNlTWFuYWdlci5Pcmdhbml6YXRpb25zLkxpc3QgcmVxdWVzdCA9IGNsb3VkcmVzb3VyY2VtYW5hZ2VyLm9yZ2FuaXphdGlvbnMoKS5saXN0KHBhcmFtZXRlcnMgLi4uKX0KICAgKiA8L3ByZT4KICAgKgogICAqIEByZXR1cm4gdGhlIHJlc291cmNlIGNvbGxlY3Rpb24KICAgKi8KICBwdWJsaWMgT3JnYW5pemF0aW9ucyBvcmdhbml6YXRpb25zKCkgewogICAgcmV0dXJuIG5ldyBPcmdhbml6YXRpb25zKCk7CiAgfQoKICAvKioKICAgKiBUaGUgIm9yZ2FuaXphdGlvbnMiIGNvbGxlY3Rpb24gb2YgbWV0aG9kcy4KICAgKi8KICBwdWJsaWMgY2xhc3MgT3JnYW5pemF0aW9ucyB7CgogICAgLyoqCiAgICAgKiBDbGVhcnMgYSBgUG9saWN5YCBmcm9tIGEgcmVzb3VyY2UuCiAgICAgKgogICAgICogQ3JlYXRlIGEgcmVxdWVzdCBmb3IgdGhlIG1ldGhvZCAib3JnYW5pemF0aW9ucy5jbGVhck9yZ1BvbGljeSIuCiAgICAgKgogICAgICogVGhpcyByZXF1ZXN0IGhvbGRzIHRoZSBwYXJhbWV0ZXJzIG5lZWRlZCBieSB0aGUgY2xvdWRyZXNvdXJjZW1hbmFnZXIgc2VydmVyLiAgQWZ0ZXIgc2V0dGluZyBhbnkKICAgICAqIG9wdGlvbmFsIHBhcmFtZXRlcnMsIGNhbGwgdGhlIHtAbGluayBDbGVhck9yZ1BvbGljeSNleGVjdXRlKCl9IG1ldGhvZCB0byBpbnZva2UgdGhlIHJlbW90ZQogICAgICogb3BlcmF0aW9uLgogICAgICoKICAgICAqIEBwYXJhbSByZXNvdXJjZSBOYW1lIG9mIHRoZSByZXNvdXJjZSBmb3IgdGhlIGBQb2xpY3lgIHRvIGNsZWFyLgogICAgICogQHBhcmFtIGNvbnRlbnQgdGhlIHtAbGluayBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5jbG91ZHJlc291cmNlbWFuYWdlci5tb2RlbC5DbGVhck9yZ1BvbGljeVJlcXVlc3R9CiAgICAgKiBAcmV0dXJuIHRoZSByZXF1ZXN0CiAgICAgKi8KICAgIHB1YmxpYyBDbGVhck9yZ1BvbGljeSBjbGVhck9yZ1BvbGljeShqYXZhLmxhbmcuU3RyaW5nIHJlc291cmNlLCBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5jbG91ZHJlc291cmNlbWFuYWdlci5tb2RlbC5DbGVhck9yZ1BvbGljeVJlcXVlc3QgY29udGVudCkgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBDbGVhck9yZ1BvbGljeSByZXN1bHQgPSBuZXcgQ2xlYXJPcmdQb2xpY3kocmVzb3VyY2UsIGNvbnRlbnQpOwogICAgICBpbml0aWFsaXplKHJlc3VsdCk7CiAgICAgIHJldHVybiByZXN1bHQ7CiAgICB9CgogICAgcHVibGljIGNsYXNzIENsZWFyT3JnUG9saWN5IGV4dGVuZHMgQ2xvdWRSZXNvdXJjZU1hbmFnZXJSZXF1ZXN0PGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmNsb3VkcmVzb3VyY2VtYW5hZ2VyLm1vZGVsLkVtcHR5PiB7CgogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgUkVTVF9QQVRIID0gInYxL3srcmVzb3VyY2V9OmNsZWFyT3JnUG9saWN5IjsKCiAgICAgIHByaXZhdGUgZmluYWwgamF2YS51dGlsLnJlZ2V4LlBhdHRlcm4gUkVTT1VSQ0VfUEFUVEVSTiA9CiAgICAgICAgICBqYXZhLnV0aWwucmVnZXguUGF0dGVybi5jb21waWxlKCJeb3JnYW5pemF0aW9ucy9bXi9dKyQiKTsKCiAgICAgIC8qKgogICAgICAgKiBDbGVhcnMgYSBgUG9saWN5YCBmcm9tIGEgcmVzb3VyY2UuCiAgICAgICAqCiAgICAgICAqIENyZWF0ZSBhIHJlcXVlc3QgZm9yIHRoZSBtZXRob2QgIm9yZ2FuaXphdGlvbnMuY2xlYXJPcmdQb2xpY3kiLgogICAgICAgKgogICAgICAgKiBUaGlzIHJlcXVlc3QgaG9sZHMgdGhlIHBhcmFtZXRlcnMgbmVlZGVkIGJ5IHRoZSB0aGUgY2xvdWRyZXNvdXJjZW1hbmFnZXIgc2VydmVyLiAgQWZ0ZXIgc2V0dGluZwogICAgICAgKiBhbnkgb3B0aW9uYWwgcGFyYW1ldGVycywgY2FsbCB0aGUge0BsaW5rIENsZWFyT3JnUG9saWN5I2V4ZWN1dGUoKX0gbWV0aG9kIHRvIGludm9rZSB0aGUgcmVtb3RlCiAgICAgICAqIG9wZXJhdGlvbi4gPHA+IHtAbGluayBDbGVhck9yZ1BvbGljeSNpbml0aWFsaXplKGNvbS5nb29nbGUuYXBpLmNsaWVudC5nb29nbGVhcGlzLnNlcnZpY2VzLkFic3RyCiAgICAgICAqIGFjdEdvb2dsZUNsaWVudFJlcXVlc3QpfSBtdXN0IGJlIGNhbGxlZCB0byBpbml0aWFsaXplIHRoaXMgaW5zdGFuY2UgaW1tZWRpYXRlbHkgYWZ0ZXIgaW52b2tpbmcKICAgICAgICogdGhlIGNvbnN0cnVjdG9yLiA8L3A+CiAgICAgICAqCiAgICAgICAqIEBwYXJhbSByZXNvdXJjZSBOYW1lIG9mIHRoZSByZXNvdXJjZSBmb3IgdGhlIGBQb2xpY3lgIHRvIGNsZWFyLgogICAgICAgKiBAcGFyYW0gY29udGVudCB0aGUge0BsaW5rIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmNsb3VkcmVzb3VyY2VtYW5hZ2VyLm1vZGVsLkNsZWFyT3JnUG9saWN5UmVxdWVzdH0KICAgICAgICogQHNpbmNlIDEuMTMKICAgICAgICovCiAgICAgIHByb3RlY3RlZCBDbGVhck9yZ1BvbGljeShqYXZhLmxhbmcuU3RyaW5nIHJlc291cmNlLCBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5jbG91ZHJlc291cmNlbWFuYWdlci5tb2RlbC5DbGVhck9yZ1BvbGljeVJlcXVlc3QgY29udGVudCkgewogICAgICAgIHN1cGVyKENsb3VkUmVzb3VyY2VNYW5hZ2VyLnRoaXMsICJQT1NUIiwgUkVTVF9QQVRILCBjb250ZW50LCBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5jbG91ZHJlc291cmNlbWFuYWdlci5tb2RlbC5FbXB0eS5jbGFzcyk7CiAgICAgICAgdGhpcy5yZXNvdXJjZSA9IGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLlByZWNvbmRpdGlvbnMuY2hlY2tOb3ROdWxsKHJlc291cmNlLCAiUmVxdWlyZWQgcGFyYW1ldGVyIHJlc291cmNlIG11c3QgYmUgc3BlY2lmaWVkLiIpOwogICAgICAgIGlmICghZ2V0U3VwcHJlc3NQYXR0ZXJuQ2hlY2tzKCkpIHsKICAgICAgICAgIGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLlByZWNvbmRpdGlvbnMuY2hlY2tBcmd1bWVudChSRVNPVVJDRV9QQVRURVJOLm1hdGNoZXIocmVzb3VyY2UpLm1hdGNoZXMoKSwKICAgICAgICAgICAgICAiUGFyYW1ldGVyIHJlc291cmNlIG11c3QgY29uZm9ybSB0byB0aGUgcGF0dGVybiAiICsKICAgICAgICAgICAgICAiXm9yZ2FuaXphdGlvbnMvW14vXSskIik7CiAgICAgICAgfQogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIENsZWFyT3JnUG9saWN5IHNldCRYZ2FmdihqYXZhLmxhbmcuU3RyaW5nICRYZ2FmdikgewogICAgICAgIHJldHVybiAoQ2xlYXJPcmdQb2xpY3kpIHN1cGVyLnNldCRYZ2FmdigkWGdhZnYpOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIENsZWFyT3JnUG9saWN5IHNldEFjY2Vzc1Rva2VuKGphdmEubGFuZy5TdHJpbmcgYWNjZXNzVG9rZW4pIHsKICAgICAgICByZXR1cm4gKENsZWFyT3JnUG9saWN5KSBzdXBlci5zZXRBY2Nlc3NUb2tlbihhY2Nlc3NUb2tlbik7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgQ2xlYXJPcmdQb2xpY3kgc2V0QWx0KGphdmEubGFuZy5TdHJpbmcgYWx0KSB7CiAgICAgICAgcmV0dXJuIChDbGVhck9yZ1BvbGljeSkgc3VwZXIuc2V0QWx0KGFsdCk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgQ2xlYXJPcmdQb2xpY3kgc2V0Q2FsbGJhY2soamF2YS5sYW5nLlN0cmluZyBjYWxsYmFjaykgewogICAgICAgIHJldHVybiAoQ2xlYXJPcmdQb2xpY3kpIHN1cGVyLnNldENhbGxiYWNrKGNhbGxiYWNrKTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBDbGVhck9yZ1BvbGljeSBzZXRGaWVsZHMoamF2YS5sYW5nLlN0cmluZyBmaWVsZHMpIHsKICAgICAgICByZXR1cm4gKENsZWFyT3JnUG9saWN5KSBzdXBlci5zZXRGaWVsZHMoZmllbGRzKTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBDbGVhck9yZ1BvbGljeSBzZXRLZXkoamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICByZXR1cm4gKENsZWFyT3JnUG9saWN5KSBzdXBlci5zZXRLZXkoa2V5KTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBDbGVhck9yZ1BvbGljeSBzZXRPYXV0aFRva2VuKGphdmEubGFuZy5TdHJpbmcgb2F1dGhUb2tlbikgewogICAgICAgIHJldHVybiAoQ2xlYXJPcmdQb2xpY3kpIHN1cGVyLnNldE9hdXRoVG9rZW4ob2F1dGhUb2tlbik7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgQ2xlYXJPcmdQb2xpY3kgc2V0UHJldHR5UHJpbnQoamF2YS5sYW5nLkJvb2xlYW4gcHJldHR5UHJpbnQpIHsKICAgICAgICByZXR1cm4gKENsZWFyT3JnUG9saWN5KSBzdXBlci5zZXRQcmV0dHlQcmludChwcmV0dHlQcmludCk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgQ2xlYXJPcmdQb2xpY3kgc2V0UXVvdGFVc2VyKGphdmEubGFuZy5TdHJpbmcgcXVvdGFVc2VyKSB7CiAgICAgICAgcmV0dXJuIChDbGVhck9yZ1BvbGljeSkgc3VwZXIuc2V0UXVvdGFVc2VyKHF1b3RhVXNlcik7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgQ2xlYXJPcmdQb2xpY3kgc2V0VXBsb2FkVHlwZShqYXZhLmxhbmcuU3RyaW5nIHVwbG9hZFR5cGUpIHsKICAgICAgICByZXR1cm4gKENsZWFyT3JnUG9saWN5KSBzdXBlci5zZXRVcGxvYWRUeXBlKHVwbG9hZFR5cGUpOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIENsZWFyT3JnUG9saWN5IHNldFVwbG9hZFByb3RvY29sKGphdmEubGFuZy5TdHJpbmcgdXBsb2FkUHJvdG9jb2wpIHsKICAgICAgICByZXR1cm4gKENsZWFyT3JnUG9saWN5KSBzdXBlci5zZXRVcGxvYWRQcm90b2NvbCh1cGxvYWRQcm90b2NvbCk7CiAgICAgIH0KCiAgICAgIC8qKiBOYW1lIG9mIHRoZSByZXNvdXJjZSBmb3IgdGhlIGBQb2xpY3lgIHRvIGNsZWFyLiAqLwogICAgICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgICAgIHByaXZhdGUgamF2YS5sYW5nLlN0cmluZyByZXNvdXJjZTsKCiAgICAgIC8qKiBOYW1lIG9mIHRoZSByZXNvdXJjZSBmb3IgdGhlIGBQb2xpY3lgIHRvIGNsZWFyLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0UmVzb3VyY2UoKSB7CiAgICAgICAgcmV0dXJuIHJlc291cmNlOwogICAgICB9CgogICAgICAvKiogTmFtZSBvZiB0aGUgcmVzb3VyY2UgZm9yIHRoZSBgUG9saWN5YCB0byBjbGVhci4gKi8KICAgICAgcHVibGljIENsZWFyT3JnUG9saWN5IHNldFJlc291cmNlKGphdmEubGFuZy5TdHJpbmcgcmVzb3VyY2UpIHsKICAgICAgICBpZiAoIWdldFN1cHByZXNzUGF0dGVybkNoZWNrcygpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5QcmVjb25kaXRpb25zLmNoZWNrQXJndW1lbnQoUkVTT1VSQ0VfUEFUVEVSTi5tYXRjaGVyKHJlc291cmNlKS5tYXRjaGVzKCksCiAgICAgICAgICAgICAgIlBhcmFtZXRlciByZXNvdXJjZSBtdXN0IGNvbmZvcm0gdG8gdGhlIHBhdHRlcm4gIiArCiAgICAgICAgICAgICAgIl5vcmdhbml6YXRpb25zL1teL10rJCIpOwogICAgICAgIH0KICAgICAgICB0aGlzLnJlc291cmNlID0gcmVzb3VyY2U7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgQ2xlYXJPcmdQb2xpY3kgc2V0KFN0cmluZyBwYXJhbWV0ZXJOYW1lLCBPYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gKENsZWFyT3JnUG9saWN5KSBzdXBlci5zZXQocGFyYW1ldGVyTmFtZSwgdmFsdWUpOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIEZldGNoZXMgYW4gT3JnYW5pemF0aW9uIHJlc291cmNlIGlkZW50aWZpZWQgYnkgdGhlIHNwZWNpZmllZCByZXNvdXJjZSBuYW1lLgogICAgICoKICAgICAqIENyZWF0ZSBhIHJlcXVlc3QgZm9yIHRoZSBtZXRob2QgIm9yZ2FuaXphdGlvbnMuZ2V0Ii4KICAgICAqCiAgICAgKiBUaGlzIHJlcXVlc3QgaG9sZHMgdGhlIHBhcmFtZXRlcnMgbmVlZGVkIGJ5IHRoZSBjbG91ZHJlc291cmNlbWFuYWdlciBzZXJ2ZXIuICBBZnRlciBzZXR0aW5nIGFueQogICAgICogb3B0aW9uYWwgcGFyYW1ldGVycywgY2FsbCB0aGUge0BsaW5rIEdldCNleGVjdXRlKCl9IG1ldGhvZCB0byBpbnZva2UgdGhlIHJlbW90ZSBvcGVyYXRpb24uCiAgICAgKgogICAgICogQHBhcmFtIG5hbWUgVGhlIHJlc291cmNlIG5hbWUgb2YgdGhlIE9yZ2FuaXphdGlvbiB0byBmZXRjaC4gVGhpcyBpcyB0aGUgb3JnYW5pemF0aW9uJ3MKICAgIHJlbGF0aXZlIHBhdGggaW4gdGhlIEFQSSwKICAgICAqICAgICAgICBmb3JtYXR0ZWQgYXMgIm9yZ2FuaXphdGlvbnMvW29yZ2FuaXphdGlvbklkXSIuCiAgICBGb3IgZXhhbXBsZSwgIm9yZ2FuaXphdGlvbnMvMTIzNCIuCiAgICAgKiBAcmV0dXJuIHRoZSByZXF1ZXN0CiAgICAgKi8KICAgIHB1YmxpYyBHZXQgZ2V0KGphdmEubGFuZy5TdHJpbmcgbmFtZSkgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBHZXQgcmVzdWx0ID0gbmV3IEdldChuYW1lKTsKICAgICAgaW5pdGlhbGl6ZShyZXN1bHQpOwogICAgICByZXR1cm4gcmVzdWx0OwogICAgfQoKICAgIHB1YmxpYyBjbGFzcyBHZXQgZXh0ZW5kcyBDbG91ZFJlc291cmNlTWFuYWdlclJlcXVlc3Q8Y29tLmdvb2dsZS5hcGkuc2VydmljZXMuY2xvdWRyZXNvdXJjZW1hbmFnZXIubW9kZWwuT3JnYW5pemF0aW9uPiB7CgogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgUkVTVF9QQVRIID0gInYxL3srbmFtZX0iOwoKICAgICAgcHJpdmF0ZSBmaW5hbCBqYXZhLnV0aWwucmVnZXguUGF0dGVybiBOQU1FX1BBVFRFUk4gPQogICAgICAgICAgamF2YS51dGlsLnJlZ2V4LlBhdHRlcm4uY29tcGlsZSgiXm9yZ2FuaXphdGlvbnMvW14vXSskIik7CgogICAgICAvKioKICAgICAgICogRmV0Y2hlcyBhbiBPcmdhbml6YXRpb24gcmVzb3VyY2UgaWRlbnRpZmllZCBieSB0aGUgc3BlY2lmaWVkIHJlc291cmNlIG5hbWUuCiAgICAgICAqCiAgICAgICAqIENyZWF0ZSBhIHJlcXVlc3QgZm9yIHRoZSBtZXRob2QgIm9yZ2FuaXphdGlvbnMuZ2V0Ii4KICAgICAgICoKICAgICAgICogVGhpcyByZXF1ZXN0IGhvbGRzIHRoZSBwYXJhbWV0ZXJzIG5lZWRlZCBieSB0aGUgdGhlIGNsb3VkcmVzb3VyY2VtYW5hZ2VyIHNlcnZlci4gIEFmdGVyIHNldHRpbmcKICAgICAgICogYW55IG9wdGlvbmFsIHBhcmFtZXRlcnMsIGNhbGwgdGhlIHtAbGluayBHZXQjZXhlY3V0ZSgpfSBtZXRob2QgdG8gaW52b2tlIHRoZSByZW1vdGUgb3BlcmF0aW9uLgogICAgICAgKiA8cD4ge0BsaW5rCiAgICAgICAqIEdldCNpbml0aWFsaXplKGNvbS5nb29nbGUuYXBpLmNsaWVudC5nb29nbGVhcGlzLnNlcnZpY2VzLkFic3RyYWN0R29vZ2xlQ2xpZW50UmVxdWVzdCl9IG11c3QgYmUKICAgICAgICogY2FsbGVkIHRvIGluaXRpYWxpemUgdGhpcyBpbnN0YW5jZSBpbW1lZGlhdGVseSBhZnRlciBpbnZva2luZyB0aGUgY29uc3RydWN0b3IuIDwvcD4KICAgICAgICoKICAgICAgICogQHBhcmFtIG5hbWUgVGhlIHJlc291cmNlIG5hbWUgb2YgdGhlIE9yZ2FuaXphdGlvbiB0byBmZXRjaC4gVGhpcyBpcyB0aGUgb3JnYW5pemF0aW9uJ3MKICAgIHJlbGF0aXZlIHBhdGggaW4gdGhlIEFQSSwKICAgICAqICAgICAgICBmb3JtYXR0ZWQgYXMgIm9yZ2FuaXphdGlvbnMvW29yZ2FuaXphdGlvbklkXSIuCiAgICBGb3IgZXhhbXBsZSwgIm9yZ2FuaXphdGlvbnMvMTIzNCIuCiAgICAgICAqIEBzaW5jZSAxLjEzCiAgICAgICAqLwogICAgICBwcm90ZWN0ZWQgR2V0KGphdmEubGFuZy5TdHJpbmcgbmFtZSkgewogICAgICAgIHN1cGVyKENsb3VkUmVzb3VyY2VNYW5hZ2VyLnRoaXMsICJHRVQiLCBSRVNUX1BBVEgsIG51bGwsIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmNsb3VkcmVzb3VyY2VtYW5hZ2VyLm1vZGVsLk9yZ2FuaXphdGlvbi5jbGFzcyk7CiAgICAgICAgdGhpcy5uYW1lID0gY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuUHJlY29uZGl0aW9ucy5jaGVja05vdE51bGwobmFtZSwgIlJlcXVpcmVkIHBhcmFtZXRlciBuYW1lIG11c3QgYmUgc3BlY2lmaWVkLiIpOwogICAgICAgIGlmICghZ2V0U3VwcHJlc3NQYXR0ZXJuQ2hlY2tzKCkpIHsKICAgICAgICAgIGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLlByZWNvbmRpdGlvbnMuY2hlY2tBcmd1bWVudChOQU1FX1BBVFRFUk4ubWF0Y2hlcihuYW1lKS5tYXRjaGVzKCksCiAgICAgICAgICAgICAgIlBhcmFtZXRlciBuYW1lIG11c3QgY29uZm9ybSB0byB0aGUgcGF0dGVybiAiICsKICAgICAgICAgICAgICAiXm9yZ2FuaXphdGlvbnMvW14vXSskIik7CiAgICAgICAgfQogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUuYXBpLmNsaWVudC5odHRwLkh0dHBSZXNwb25zZSBleGVjdXRlVXNpbmdIZWFkKCkgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBzdXBlci5leGVjdXRlVXNpbmdIZWFkKCk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5hcGkuY2xpZW50Lmh0dHAuSHR0cFJlcXVlc3QgYnVpbGRIdHRwUmVxdWVzdFVzaW5nSGVhZCgpIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gc3VwZXIuYnVpbGRIdHRwUmVxdWVzdFVzaW5nSGVhZCgpOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIEdldCBzZXQkWGdhZnYoamF2YS5sYW5nLlN0cmluZyAkWGdhZnYpIHsKICAgICAgICByZXR1cm4gKEdldCkgc3VwZXIuc2V0JFhnYWZ2KCRYZ2Fmdik7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgR2V0IHNldEFjY2Vzc1Rva2VuKGphdmEubGFuZy5TdHJpbmcgYWNjZXNzVG9rZW4pIHsKICAgICAgICByZXR1cm4gKEdldCkgc3VwZXIuc2V0QWNjZXNzVG9rZW4oYWNjZXNzVG9rZW4pOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIEdldCBzZXRBbHQoamF2YS5sYW5nLlN0cmluZyBhbHQpIHsKICAgICAgICByZXR1cm4gKEdldCkgc3VwZXIuc2V0QWx0KGFsdCk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgR2V0IHNldENhbGxiYWNrKGphdmEubGFuZy5TdHJpbmcgY2FsbGJhY2spIHsKICAgICAgICByZXR1cm4gKEdldCkgc3VwZXIuc2V0Q2FsbGJhY2soY2FsbGJhY2spOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIEdldCBzZXRGaWVsZHMoamF2YS5sYW5nLlN0cmluZyBmaWVsZHMpIHsKICAgICAgICByZXR1cm4gKEdldCkgc3VwZXIuc2V0RmllbGRzKGZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgR2V0IHNldEtleShqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIHJldHVybiAoR2V0KSBzdXBlci5zZXRLZXkoa2V5KTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBHZXQgc2V0T2F1dGhUb2tlbihqYXZhLmxhbmcuU3RyaW5nIG9hdXRoVG9rZW4pIHsKICAgICAgICByZXR1cm4gKEdldCkgc3VwZXIuc2V0T2F1dGhUb2tlbihvYXV0aFRva2VuKTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBHZXQgc2V0UHJldHR5UHJpbnQoamF2YS5sYW5nLkJvb2xlYW4gcHJldHR5UHJpbnQpIHsKICAgICAgICByZXR1cm4gKEdldCkgc3VwZXIuc2V0UHJldHR5UHJpbnQocHJldHR5UHJpbnQpOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIEdldCBzZXRRdW90YVVzZXIoamF2YS5sYW5nLlN0cmluZyBxdW90YVVzZXIpIHsKICAgICAgICByZXR1cm4gKEdldCkgc3VwZXIuc2V0UXVvdGFVc2VyKHF1b3RhVXNlcik7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgR2V0IHNldFVwbG9hZFR5cGUoamF2YS5sYW5nLlN0cmluZyB1cGxvYWRUeXBlKSB7CiAgICAgICAgcmV0dXJuIChHZXQpIHN1cGVyLnNldFVwbG9hZFR5cGUodXBsb2FkVHlwZSk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgR2V0IHNldFVwbG9hZFByb3RvY29sKGphdmEubGFuZy5TdHJpbmcgdXBsb2FkUHJvdG9jb2wpIHsKICAgICAgICByZXR1cm4gKEdldCkgc3VwZXIuc2V0VXBsb2FkUHJvdG9jb2wodXBsb2FkUHJvdG9jb2wpOwogICAgICB9CgogICAgICAvKioKICAgICAgICogVGhlIHJlc291cmNlIG5hbWUgb2YgdGhlIE9yZ2FuaXphdGlvbiB0byBmZXRjaC4gVGhpcyBpcyB0aGUgb3JnYW5pemF0aW9uJ3MgcmVsYXRpdmUgcGF0aCBpbgogICAgICAgKiB0aGUgQVBJLCBmb3JtYXR0ZWQgYXMgIm9yZ2FuaXphdGlvbnMvW29yZ2FuaXphdGlvbklkXSIuIEZvciBleGFtcGxlLCAib3JnYW5pemF0aW9ucy8xMjM0Ii4KICAgICAgICovCiAgICAgIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuU3RyaW5nIG5hbWU7CgogICAgICAvKiogVGhlIHJlc291cmNlIG5hbWUgb2YgdGhlIE9yZ2FuaXphdGlvbiB0byBmZXRjaC4gVGhpcyBpcyB0aGUgb3JnYW5pemF0aW9uJ3MgcmVsYXRpdmUgcGF0aCBpbiB0aGUKICAgICBBUEksIGZvcm1hdHRlZCBhcyAib3JnYW5pemF0aW9ucy9bb3JnYW5pemF0aW9uSWRdIi4gRm9yIGV4YW1wbGUsICJvcmdhbml6YXRpb25zLzEyMzQiLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TmFtZSgpIHsKICAgICAgICByZXR1cm4gbmFtZTsKICAgICAgfQoKICAgICAgLyoqCiAgICAgICAqIFRoZSByZXNvdXJjZSBuYW1lIG9mIHRoZSBPcmdhbml6YXRpb24gdG8gZmV0Y2guIFRoaXMgaXMgdGhlIG9yZ2FuaXphdGlvbidzIHJlbGF0aXZlIHBhdGggaW4KICAgICAgICogdGhlIEFQSSwgZm9ybWF0dGVkIGFzICJvcmdhbml6YXRpb25zL1tvcmdhbml6YXRpb25JZF0iLiBGb3IgZXhhbXBsZSwgIm9yZ2FuaXphdGlvbnMvMTIzNCIuCiAgICAgICAqLwogICAgICBwdWJsaWMgR2V0IHNldE5hbWUoamF2YS5sYW5nLlN0cmluZyBuYW1lKSB7CiAgICAgICAgaWYgKCFnZXRTdXBwcmVzc1BhdHRlcm5DaGVja3MoKSkgewogICAgICAgICAgY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuUHJlY29uZGl0aW9ucy5jaGVja0FyZ3VtZW50KE5BTUVfUEFUVEVSTi5tYXRjaGVyKG5hbWUpLm1hdGNoZXMoKSwKICAgICAgICAgICAgICAiUGFyYW1ldGVyIG5hbWUgbXVzdCBjb25mb3JtIHRvIHRoZSBwYXR0ZXJuICIgKwogICAgICAgICAgICAgICJeb3JnYW5pemF0aW9ucy9bXi9dKyQiKTsKICAgICAgICB9CiAgICAgICAgdGhpcy5uYW1lID0gbmFtZTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBHZXQgc2V0KFN0cmluZyBwYXJhbWV0ZXJOYW1lLCBPYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gKEdldCkgc3VwZXIuc2V0KHBhcmFtZXRlck5hbWUsIHZhbHVlKTsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiBHZXRzIHRoZSBlZmZlY3RpdmUgYFBvbGljeWAgb24gYSByZXNvdXJjZS4gVGhpcyBpcyB0aGUgcmVzdWx0IG9mIG1lcmdpbmcgYFBvbGljaWVzYCBpbiB0aGUKICAgICAqIHJlc291cmNlIGhpZXJhcmNoeS4gVGhlIHJldHVybmVkIGBQb2xpY3lgIHdpbGwgbm90IGhhdmUgYW4gYGV0YWdgc2V0IGJlY2F1c2UgaXQgaXMgYSBjb21wdXRlZAogICAgICogYFBvbGljeWAgYWNyb3NzIG11bHRpcGxlIHJlc291cmNlcy4gU3VidHJlZXMgb2YgUmVzb3VyY2UgTWFuYWdlciByZXNvdXJjZSBoaWVyYXJjaHkgd2l0aCAndW5kZXI6JwogICAgICogcHJlZml4IHdpbGwgbm90IGJlIGV4cGFuZGVkLgogICAgICoKICAgICAqIENyZWF0ZSBhIHJlcXVlc3QgZm9yIHRoZSBtZXRob2QgIm9yZ2FuaXphdGlvbnMuZ2V0RWZmZWN0aXZlT3JnUG9saWN5Ii4KICAgICAqCiAgICAgKiBUaGlzIHJlcXVlc3QgaG9sZHMgdGhlIHBhcmFtZXRlcnMgbmVlZGVkIGJ5IHRoZSBjbG91ZHJlc291cmNlbWFuYWdlciBzZXJ2ZXIuICBBZnRlciBzZXR0aW5nIGFueQogICAgICogb3B0aW9uYWwgcGFyYW1ldGVycywgY2FsbCB0aGUge0BsaW5rIEdldEVmZmVjdGl2ZU9yZ1BvbGljeSNleGVjdXRlKCl9IG1ldGhvZCB0byBpbnZva2UgdGhlIHJlbW90ZQogICAgICogb3BlcmF0aW9uLgogICAgICoKICAgICAqIEBwYXJhbSByZXNvdXJjZSBUaGUgbmFtZSBvZiB0aGUgcmVzb3VyY2UgdG8gc3RhcnQgY29tcHV0aW5nIHRoZSBlZmZlY3RpdmUgYFBvbGljeWAuCiAgICAgKiBAcGFyYW0gY29udGVudCB0aGUge0BsaW5rIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmNsb3VkcmVzb3VyY2VtYW5hZ2VyLm1vZGVsLkdldEVmZmVjdGl2ZU9yZ1BvbGljeVJlcXVlc3R9CiAgICAgKiBAcmV0dXJuIHRoZSByZXF1ZXN0CiAgICAgKi8KICAgIHB1YmxpYyBHZXRFZmZlY3RpdmVPcmdQb2xpY3kgZ2V0RWZmZWN0aXZlT3JnUG9saWN5KGphdmEubGFuZy5TdHJpbmcgcmVzb3VyY2UsIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmNsb3VkcmVzb3VyY2VtYW5hZ2VyLm1vZGVsLkdldEVmZmVjdGl2ZU9yZ1BvbGljeVJlcXVlc3QgY29udGVudCkgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBHZXRFZmZlY3RpdmVPcmdQb2xpY3kgcmVzdWx0ID0gbmV3IEdldEVmZmVjdGl2ZU9yZ1BvbGljeShyZXNvdXJjZSwgY29udGVudCk7CiAgICAgIGluaXRpYWxpemUocmVzdWx0KTsKICAgICAgcmV0dXJuIHJlc3VsdDsKICAgIH0KCiAgICBwdWJsaWMgY2xhc3MgR2V0RWZmZWN0aXZlT3JnUG9saWN5IGV4dGVuZHMgQ2xvdWRSZXNvdXJjZU1hbmFnZXJSZXF1ZXN0PGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmNsb3VkcmVzb3VyY2VtYW5hZ2VyLm1vZGVsLk9yZ1BvbGljeT4gewoKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFJFU1RfUEFUSCA9ICJ2MS97K3Jlc291cmNlfTpnZXRFZmZlY3RpdmVPcmdQb2xpY3kiOwoKICAgICAgcHJpdmF0ZSBmaW5hbCBqYXZhLnV0aWwucmVnZXguUGF0dGVybiBSRVNPVVJDRV9QQVRURVJOID0KICAgICAgICAgIGphdmEudXRpbC5yZWdleC5QYXR0ZXJuLmNvbXBpbGUoIl5vcmdhbml6YXRpb25zL1teL10rJCIpOwoKICAgICAgLyoqCiAgICAgICAqIEdldHMgdGhlIGVmZmVjdGl2ZSBgUG9saWN5YCBvbiBhIHJlc291cmNlLiBUaGlzIGlzIHRoZSByZXN1bHQgb2YgbWVyZ2luZyBgUG9saWNpZXNgIGluIHRoZQogICAgICAgKiByZXNvdXJjZSBoaWVyYXJjaHkuIFRoZSByZXR1cm5lZCBgUG9saWN5YCB3aWxsIG5vdCBoYXZlIGFuIGBldGFnYHNldCBiZWNhdXNlIGl0IGlzIGEgY29tcHV0ZWQKICAgICAgICogYFBvbGljeWAgYWNyb3NzIG11bHRpcGxlIHJlc291cmNlcy4gU3VidHJlZXMgb2YgUmVzb3VyY2UgTWFuYWdlciByZXNvdXJjZSBoaWVyYXJjaHkgd2l0aAogICAgICAgKiAndW5kZXI6JyBwcmVmaXggd2lsbCBub3QgYmUgZXhwYW5kZWQuCiAgICAgICAqCiAgICAgICAqIENyZWF0ZSBhIHJlcXVlc3QgZm9yIHRoZSBtZXRob2QgIm9yZ2FuaXphdGlvbnMuZ2V0RWZmZWN0aXZlT3JnUG9saWN5Ii4KICAgICAgICoKICAgICAgICogVGhpcyByZXF1ZXN0IGhvbGRzIHRoZSBwYXJhbWV0ZXJzIG5lZWRlZCBieSB0aGUgdGhlIGNsb3VkcmVzb3VyY2VtYW5hZ2VyIHNlcnZlci4gIEFmdGVyIHNldHRpbmcKICAgICAgICogYW55IG9wdGlvbmFsIHBhcmFtZXRlcnMsIGNhbGwgdGhlIHtAbGluayBHZXRFZmZlY3RpdmVPcmdQb2xpY3kjZXhlY3V0ZSgpfSBtZXRob2QgdG8gaW52b2tlIHRoZQogICAgICAgKiByZW1vdGUgb3BlcmF0aW9uLiA8cD4ge0BsaW5rIEdldEVmZmVjdGl2ZU9yZ1BvbGljeSNpbml0aWFsaXplKGNvbS5nb29nbGUuYXBpLmNsaWVudC5nb29nbGVhcGlzLgogICAgICAgKiBzZXJ2aWNlcy5BYnN0cmFjdEdvb2dsZUNsaWVudFJlcXVlc3QpfSBtdXN0IGJlIGNhbGxlZCB0byBpbml0aWFsaXplIHRoaXMgaW5zdGFuY2UgaW1tZWRpYXRlbHkKICAgICAgICogYWZ0ZXIgaW52b2tpbmcgdGhlIGNvbnN0cnVjdG9yLiA8L3A+CiAgICAgICAqCiAgICAgICAqIEBwYXJhbSByZXNvdXJjZSBUaGUgbmFtZSBvZiB0aGUgcmVzb3VyY2UgdG8gc3RhcnQgY29tcHV0aW5nIHRoZSBlZmZlY3RpdmUgYFBvbGljeWAuCiAgICAgICAqIEBwYXJhbSBjb250ZW50IHRoZSB7QGxpbmsgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuY2xvdWRyZXNvdXJjZW1hbmFnZXIubW9kZWwuR2V0RWZmZWN0aXZlT3JnUG9saWN5UmVxdWVzdH0KICAgICAgICogQHNpbmNlIDEuMTMKICAgICAgICovCiAgICAgIHByb3RlY3RlZCBHZXRFZmZlY3RpdmVPcmdQb2xpY3koamF2YS5sYW5nLlN0cmluZyByZXNvdXJjZSwgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuY2xvdWRyZXNvdXJjZW1hbmFnZXIubW9kZWwuR2V0RWZmZWN0aXZlT3JnUG9saWN5UmVxdWVzdCBjb250ZW50KSB7CiAgICAgICAgc3VwZXIoQ2xvdWRSZXNvdXJjZU1hbmFnZXIudGhpcywgIlBPU1QiLCBSRVNUX1BBVEgsIGNvbnRlbnQsIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmNsb3VkcmVzb3VyY2VtYW5hZ2VyLm1vZGVsLk9yZ1BvbGljeS5jbGFzcyk7CiAgICAgICAgdGhpcy5yZXNvdXJjZSA9IGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLlByZWNvbmRpdGlvbnMuY2hlY2tOb3ROdWxsKHJlc291cmNlLCAiUmVxdWlyZWQgcGFyYW1ldGVyIHJlc291cmNlIG11c3QgYmUgc3BlY2lmaWVkLiIpOwogICAgICAgIGlmICghZ2V0U3VwcHJlc3NQYXR0ZXJuQ2hlY2tzKCkpIHsKICAgICAgICAgIGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLlByZWNvbmRpdGlvbnMuY2hlY2tBcmd1bWVudChSRVNPVVJDRV9QQVRURVJOLm1hdGNoZXIocmVzb3VyY2UpLm1hdGNoZXMoKSwKICAgICAgICAgICAgICAiUGFyYW1ldGVyIHJlc291cmNlIG11c3QgY29uZm9ybSB0byB0aGUgcGF0dGVybiAiICsKICAgICAgICAgICAgICAiXm9yZ2FuaXphdGlvbnMvW14vXSskIik7CiAgICAgICAgfQogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIEdldEVmZmVjdGl2ZU9yZ1BvbGljeSBzZXQkWGdhZnYoamF2YS5sYW5nLlN0cmluZyAkWGdhZnYpIHsKICAgICAgICByZXR1cm4gKEdldEVmZmVjdGl2ZU9yZ1BvbGljeSkgc3VwZXIuc2V0JFhnYWZ2KCRYZ2Fmdik7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgR2V0RWZmZWN0aXZlT3JnUG9saWN5IHNldEFjY2Vzc1Rva2VuKGphdmEubGFuZy5TdHJpbmcgYWNjZXNzVG9rZW4pIHsKICAgICAgICByZXR1cm4gKEdldEVmZmVjdGl2ZU9yZ1BvbGljeSkgc3VwZXIuc2V0QWNjZXNzVG9rZW4oYWNjZXNzVG9rZW4pOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIEdldEVmZmVjdGl2ZU9yZ1BvbGljeSBzZXRBbHQoamF2YS5sYW5nLlN0cmluZyBhbHQpIHsKICAgICAgICByZXR1cm4gKEdldEVmZmVjdGl2ZU9yZ1BvbGljeSkgc3VwZXIuc2V0QWx0KGFsdCk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgR2V0RWZmZWN0aXZlT3JnUG9saWN5IHNldENhbGxiYWNrKGphdmEubGFuZy5TdHJpbmcgY2FsbGJhY2spIHsKICAgICAgICByZXR1cm4gKEdldEVmZmVjdGl2ZU9yZ1BvbGljeSkgc3VwZXIuc2V0Q2FsbGJhY2soY2FsbGJhY2spOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIEdldEVmZmVjdGl2ZU9yZ1BvbGljeSBzZXRGaWVsZHMoamF2YS5sYW5nLlN0cmluZyBmaWVsZHMpIHsKICAgICAgICByZXR1cm4gKEdldEVmZmVjdGl2ZU9yZ1BvbGljeSkgc3VwZXIuc2V0RmllbGRzKGZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgR2V0RWZmZWN0aXZlT3JnUG9saWN5IHNldEtleShqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIHJldHVybiAoR2V0RWZmZWN0aXZlT3JnUG9saWN5KSBzdXBlci5zZXRLZXkoa2V5KTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBHZXRFZmZlY3RpdmVPcmdQb2xpY3kgc2V0T2F1dGhUb2tlbihqYXZhLmxhbmcuU3RyaW5nIG9hdXRoVG9rZW4pIHsKICAgICAgICByZXR1cm4gKEdldEVmZmVjdGl2ZU9yZ1BvbGljeSkgc3VwZXIuc2V0T2F1dGhUb2tlbihvYXV0aFRva2VuKTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBHZXRFZmZlY3RpdmVPcmdQb2xpY3kgc2V0UHJldHR5UHJpbnQoamF2YS5sYW5nLkJvb2xlYW4gcHJldHR5UHJpbnQpIHsKICAgICAgICByZXR1cm4gKEdldEVmZmVjdGl2ZU9yZ1BvbGljeSkgc3VwZXIuc2V0UHJldHR5UHJpbnQocHJldHR5UHJpbnQpOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIEdldEVmZmVjdGl2ZU9yZ1BvbGljeSBzZXRRdW90YVVzZXIoamF2YS5sYW5nLlN0cmluZyBxdW90YVVzZXIpIHsKICAgICAgICByZXR1cm4gKEdldEVmZmVjdGl2ZU9yZ1BvbGljeSkgc3VwZXIuc2V0UXVvdGFVc2VyKHF1b3RhVXNlcik7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgR2V0RWZmZWN0aXZlT3JnUG9saWN5IHNldFVwbG9hZFR5cGUoamF2YS5sYW5nLlN0cmluZyB1cGxvYWRUeXBlKSB7CiAgICAgICAgcmV0dXJuIChHZXRFZmZlY3RpdmVPcmdQb2xpY3kpIHN1cGVyLnNldFVwbG9hZFR5cGUodXBsb2FkVHlwZSk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgR2V0RWZmZWN0aXZlT3JnUG9saWN5IHNldFVwbG9hZFByb3RvY29sKGphdmEubGFuZy5TdHJpbmcgdXBsb2FkUHJvdG9jb2wpIHsKICAgICAgICByZXR1cm4gKEdldEVmZmVjdGl2ZU9yZ1BvbGljeSkgc3VwZXIuc2V0VXBsb2FkUHJvdG9jb2wodXBsb2FkUHJvdG9jb2wpOwogICAgICB9CgogICAgICAvKiogVGhlIG5hbWUgb2YgdGhlIHJlc291cmNlIHRvIHN0YXJ0IGNvbXB1dGluZyB0aGUgZWZmZWN0aXZlIGBQb2xpY3lgLiAqLwogICAgICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgICAgIHByaXZhdGUgamF2YS5sYW5nLlN0cmluZyByZXNvdXJjZTsKCiAgICAgIC8qKiBUaGUgbmFtZSBvZiB0aGUgcmVzb3VyY2UgdG8gc3RhcnQgY29tcHV0aW5nIHRoZSBlZmZlY3RpdmUgYFBvbGljeWAuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRSZXNvdXJjZSgpIHsKICAgICAgICByZXR1cm4gcmVzb3VyY2U7CiAgICAgIH0KCiAgICAgIC8qKiBUaGUgbmFtZSBvZiB0aGUgcmVzb3VyY2UgdG8gc3RhcnQgY29tcHV0aW5nIHRoZSBlZmZlY3RpdmUgYFBvbGljeWAuICovCiAgICAgIHB1YmxpYyBHZXRFZmZlY3RpdmVPcmdQb2xpY3kgc2V0UmVzb3VyY2UoamF2YS5sYW5nLlN0cmluZyByZXNvdXJjZSkgewogICAgICAgIGlmICghZ2V0U3VwcHJlc3NQYXR0ZXJuQ2hlY2tzKCkpIHsKICAgICAgICAgIGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLlByZWNvbmRpdGlvbnMuY2hlY2tBcmd1bWVudChSRVNPVVJDRV9QQVRURVJOLm1hdGNoZXIocmVzb3VyY2UpLm1hdGNoZXMoKSwKICAgICAgICAgICAgICAiUGFyYW1ldGVyIHJlc291cmNlIG11c3QgY29uZm9ybSB0byB0aGUgcGF0dGVybiAiICsKICAgICAgICAgICAgICAiXm9yZ2FuaXphdGlvbnMvW14vXSskIik7CiAgICAgICAgfQogICAgICAgIHRoaXMucmVzb3VyY2UgPSByZXNvdXJjZTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBHZXRFZmZlY3RpdmVPcmdQb2xpY3kgc2V0KFN0cmluZyBwYXJhbWV0ZXJOYW1lLCBPYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gKEdldEVmZmVjdGl2ZU9yZ1BvbGljeSkgc3VwZXIuc2V0KHBhcmFtZXRlck5hbWUsIHZhbHVlKTsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiBHZXRzIHRoZSBhY2Nlc3MgY29udHJvbCBwb2xpY3kgZm9yIGFuIE9yZ2FuaXphdGlvbiByZXNvdXJjZS4gTWF5IGJlIGVtcHR5IGlmIG5vIHN1Y2ggcG9saWN5IG9yCiAgICAgKiByZXNvdXJjZSBleGlzdHMuIFRoZSBgcmVzb3VyY2VgIGZpZWxkIHNob3VsZCBiZSB0aGUgb3JnYW5pemF0aW9uJ3MgcmVzb3VyY2UgbmFtZSwgZS5nLgogICAgICogIm9yZ2FuaXphdGlvbnMvMTIzIi4KICAgICAqCiAgICAgKiBBdXRob3JpemF0aW9uIHJlcXVpcmVzIHRoZSBHb29nbGUgSUFNIHBlcm1pc3Npb24gYHJlc291cmNlbWFuYWdlci5vcmdhbml6YXRpb25zLmdldElhbVBvbGljeWAgb24KICAgICAqIHRoZSBzcGVjaWZpZWQgb3JnYW5pemF0aW9uCiAgICAgKgogICAgICogQ3JlYXRlIGEgcmVxdWVzdCBmb3IgdGhlIG1ldGhvZCAib3JnYW5pemF0aW9ucy5nZXRJYW1Qb2xpY3kiLgogICAgICoKICAgICAqIFRoaXMgcmVxdWVzdCBob2xkcyB0aGUgcGFyYW1ldGVycyBuZWVkZWQgYnkgdGhlIGNsb3VkcmVzb3VyY2VtYW5hZ2VyIHNlcnZlci4gIEFmdGVyIHNldHRpbmcgYW55CiAgICAgKiBvcHRpb25hbCBwYXJhbWV0ZXJzLCBjYWxsIHRoZSB7QGxpbmsgR2V0SWFtUG9saWN5I2V4ZWN1dGUoKX0gbWV0aG9kIHRvIGludm9rZSB0aGUgcmVtb3RlCiAgICAgKiBvcGVyYXRpb24uCiAgICAgKgogICAgICogQHBhcmFtIHJlc291cmNlIFJFUVVJUkVEOiBUaGUgcmVzb3VyY2UgZm9yIHdoaWNoIHRoZSBwb2xpY3kgaXMgYmVpbmcgcmVxdWVzdGVkLgogICAgU2VlIHRoZSBvcGVyYXRpb24gZG9jdW1lbnRhdGlvbiBmb3IKICAgICAqICAgICAgICB0aGUgYXBwcm9wcmlhdGUgdmFsdWUgZm9yIHRoaXMgZmllbGQuCiAgICAgKiBAcGFyYW0gY29udGVudCB0aGUge0BsaW5rIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmNsb3VkcmVzb3VyY2VtYW5hZ2VyLm1vZGVsLkdldElhbVBvbGljeVJlcXVlc3R9CiAgICAgKiBAcmV0dXJuIHRoZSByZXF1ZXN0CiAgICAgKi8KICAgIHB1YmxpYyBHZXRJYW1Qb2xpY3kgZ2V0SWFtUG9saWN5KGphdmEubGFuZy5TdHJpbmcgcmVzb3VyY2UsIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmNsb3VkcmVzb3VyY2VtYW5hZ2VyLm1vZGVsLkdldElhbVBvbGljeVJlcXVlc3QgY29udGVudCkgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBHZXRJYW1Qb2xpY3kgcmVzdWx0ID0gbmV3IEdldElhbVBvbGljeShyZXNvdXJjZSwgY29udGVudCk7CiAgICAgIGluaXRpYWxpemUocmVzdWx0KTsKICAgICAgcmV0dXJuIHJlc3VsdDsKICAgIH0KCiAgICBwdWJsaWMgY2xhc3MgR2V0SWFtUG9saWN5IGV4dGVuZHMgQ2xvdWRSZXNvdXJjZU1hbmFnZXJSZXF1ZXN0PGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmNsb3VkcmVzb3VyY2VtYW5hZ2VyLm1vZGVsLlBvbGljeT4gewoKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFJFU1RfUEFUSCA9ICJ2MS97K3Jlc291cmNlfTpnZXRJYW1Qb2xpY3kiOwoKICAgICAgcHJpdmF0ZSBmaW5hbCBqYXZhLnV0aWwucmVnZXguUGF0dGVybiBSRVNPVVJDRV9QQVRURVJOID0KICAgICAgICAgIGphdmEudXRpbC5yZWdleC5QYXR0ZXJuLmNvbXBpbGUoIl5vcmdhbml6YXRpb25zL1teL10rJCIpOwoKICAgICAgLyoqCiAgICAgICAqIEdldHMgdGhlIGFjY2VzcyBjb250cm9sIHBvbGljeSBmb3IgYW4gT3JnYW5pemF0aW9uIHJlc291cmNlLiBNYXkgYmUgZW1wdHkgaWYgbm8gc3VjaCBwb2xpY3kgb3IKICAgICAgICogcmVzb3VyY2UgZXhpc3RzLiBUaGUgYHJlc291cmNlYCBmaWVsZCBzaG91bGQgYmUgdGhlIG9yZ2FuaXphdGlvbidzIHJlc291cmNlIG5hbWUsIGUuZy4KICAgICAgICogIm9yZ2FuaXphdGlvbnMvMTIzIi4KICAgICAgICoKICAgICAgICogQXV0aG9yaXphdGlvbiByZXF1aXJlcyB0aGUgR29vZ2xlIElBTSBwZXJtaXNzaW9uIGByZXNvdXJjZW1hbmFnZXIub3JnYW5pemF0aW9ucy5nZXRJYW1Qb2xpY3lgCiAgICAgICAqIG9uIHRoZSBzcGVjaWZpZWQgb3JnYW5pemF0aW9uCiAgICAgICAqCiAgICAgICAqIENyZWF0ZSBhIHJlcXVlc3QgZm9yIHRoZSBtZXRob2QgIm9yZ2FuaXphdGlvbnMuZ2V0SWFtUG9saWN5Ii4KICAgICAgICoKICAgICAgICogVGhpcyByZXF1ZXN0IGhvbGRzIHRoZSBwYXJhbWV0ZXJzIG5lZWRlZCBieSB0aGUgdGhlIGNsb3VkcmVzb3VyY2VtYW5hZ2VyIHNlcnZlci4gIEFmdGVyIHNldHRpbmcKICAgICAgICogYW55IG9wdGlvbmFsIHBhcmFtZXRlcnMsIGNhbGwgdGhlIHtAbGluayBHZXRJYW1Qb2xpY3kjZXhlY3V0ZSgpfSBtZXRob2QgdG8gaW52b2tlIHRoZSByZW1vdGUKICAgICAgICogb3BlcmF0aW9uLiA8cD4ge0BsaW5rCiAgICAgICAqIEdldElhbVBvbGljeSNpbml0aWFsaXplKGNvbS5nb29nbGUuYXBpLmNsaWVudC5nb29nbGVhcGlzLnNlcnZpY2VzLkFic3RyYWN0R29vZ2xlQ2xpZW50UmVxdWVzdCl9CiAgICAgICAqIG11c3QgYmUgY2FsbGVkIHRvIGluaXRpYWxpemUgdGhpcyBpbnN0YW5jZSBpbW1lZGlhdGVseSBhZnRlciBpbnZva2luZyB0aGUgY29uc3RydWN0b3IuIDwvcD4KICAgICAgICoKICAgICAgICogQHBhcmFtIHJlc291cmNlIFJFUVVJUkVEOiBUaGUgcmVzb3VyY2UgZm9yIHdoaWNoIHRoZSBwb2xpY3kgaXMgYmVpbmcgcmVxdWVzdGVkLgogICAgU2VlIHRoZSBvcGVyYXRpb24gZG9jdW1lbnRhdGlvbiBmb3IKICAgICAqICAgICAgICB0aGUgYXBwcm9wcmlhdGUgdmFsdWUgZm9yIHRoaXMgZmllbGQuCiAgICAgICAqIEBwYXJhbSBjb250ZW50IHRoZSB7QGxpbmsgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuY2xvdWRyZXNvdXJjZW1hbmFnZXIubW9kZWwuR2V0SWFtUG9saWN5UmVxdWVzdH0KICAgICAgICogQHNpbmNlIDEuMTMKICAgICAgICovCiAgICAgIHByb3RlY3RlZCBHZXRJYW1Qb2xpY3koamF2YS5sYW5nLlN0cmluZyByZXNvdXJjZSwgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuY2xvdWRyZXNvdXJjZW1hbmFnZXIubW9kZWwuR2V0SWFtUG9saWN5UmVxdWVzdCBjb250ZW50KSB7CiAgICAgICAgc3VwZXIoQ2xvdWRSZXNvdXJjZU1hbmFnZXIudGhpcywgIlBPU1QiLCBSRVNUX1BBVEgsIGNvbnRlbnQsIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmNsb3VkcmVzb3VyY2VtYW5hZ2VyLm1vZGVsLlBvbGljeS5jbGFzcyk7CiAgICAgICAgdGhpcy5yZXNvdXJjZSA9IGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLlByZWNvbmRpdGlvbnMuY2hlY2tOb3ROdWxsKHJlc291cmNlLCAiUmVxdWlyZWQgcGFyYW1ldGVyIHJlc291cmNlIG11c3QgYmUgc3BlY2lmaWVkLiIpOwogICAgICAgIGlmICghZ2V0U3VwcHJlc3NQYXR0ZXJuQ2hlY2tzKCkpIHsKICAgICAgICAgIGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLlByZWNvbmRpdGlvbnMuY2hlY2tBcmd1bWVudChSRVNPVVJDRV9QQVRURVJOLm1hdGNoZXIocmVzb3VyY2UpLm1hdGNoZXMoKSwKICAgICAgICAgICAgICAiUGFyYW1ldGVyIHJlc291cmNlIG11c3QgY29uZm9ybSB0byB0aGUgcGF0dGVybiAiICsKICAgICAgICAgICAgICAiXm9yZ2FuaXphdGlvbnMvW14vXSskIik7CiAgICAgICAgfQogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIEdldElhbVBvbGljeSBzZXQkWGdhZnYoamF2YS5sYW5nLlN0cmluZyAkWGdhZnYpIHsKICAgICAgICByZXR1cm4gKEdldElhbVBvbGljeSkgc3VwZXIuc2V0JFhnYWZ2KCRYZ2Fmdik7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgR2V0SWFtUG9saWN5IHNldEFjY2Vzc1Rva2VuKGphdmEubGFuZy5TdHJpbmcgYWNjZXNzVG9rZW4pIHsKICAgICAgICByZXR1cm4gKEdldElhbVBvbGljeSkgc3VwZXIuc2V0QWNjZXNzVG9rZW4oYWNjZXNzVG9rZW4pOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIEdldElhbVBvbGljeSBzZXRBbHQoamF2YS5sYW5nLlN0cmluZyBhbHQpIHsKICAgICAgICByZXR1cm4gKEdldElhbVBvbGljeSkgc3VwZXIuc2V0QWx0KGFsdCk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgR2V0SWFtUG9saWN5IHNldENhbGxiYWNrKGphdmEubGFuZy5TdHJpbmcgY2FsbGJhY2spIHsKICAgICAgICByZXR1cm4gKEdldElhbVBvbGljeSkgc3VwZXIuc2V0Q2FsbGJhY2soY2FsbGJhY2spOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIEdldElhbVBvbGljeSBzZXRGaWVsZHMoamF2YS5sYW5nLlN0cmluZyBmaWVsZHMpIHsKICAgICAgICByZXR1cm4gKEdldElhbVBvbGljeSkgc3VwZXIuc2V0RmllbGRzKGZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgR2V0SWFtUG9saWN5IHNldEtleShqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIHJldHVybiAoR2V0SWFtUG9saWN5KSBzdXBlci5zZXRLZXkoa2V5KTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBHZXRJYW1Qb2xpY3kgc2V0T2F1dGhUb2tlbihqYXZhLmxhbmcuU3RyaW5nIG9hdXRoVG9rZW4pIHsKICAgICAgICByZXR1cm4gKEdldElhbVBvbGljeSkgc3VwZXIuc2V0T2F1dGhUb2tlbihvYXV0aFRva2VuKTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBHZXRJYW1Qb2xpY3kgc2V0UHJldHR5UHJpbnQoamF2YS5sYW5nLkJvb2xlYW4gcHJldHR5UHJpbnQpIHsKICAgICAgICByZXR1cm4gKEdldElhbVBvbGljeSkgc3VwZXIuc2V0UHJldHR5UHJpbnQocHJldHR5UHJpbnQpOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIEdldElhbVBvbGljeSBzZXRRdW90YVVzZXIoamF2YS5sYW5nLlN0cmluZyBxdW90YVVzZXIpIHsKICAgICAgICByZXR1cm4gKEdldElhbVBvbGljeSkgc3VwZXIuc2V0UXVvdGFVc2VyKHF1b3RhVXNlcik7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgR2V0SWFtUG9saWN5IHNldFVwbG9hZFR5cGUoamF2YS5sYW5nLlN0cmluZyB1cGxvYWRUeXBlKSB7CiAgICAgICAgcmV0dXJuIChHZXRJYW1Qb2xpY3kpIHN1cGVyLnNldFVwbG9hZFR5cGUodXBsb2FkVHlwZSk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgR2V0SWFtUG9saWN5IHNldFVwbG9hZFByb3RvY29sKGphdmEubGFuZy5TdHJpbmcgdXBsb2FkUHJvdG9jb2wpIHsKICAgICAgICByZXR1cm4gKEdldElhbVBvbGljeSkgc3VwZXIuc2V0VXBsb2FkUHJvdG9jb2wodXBsb2FkUHJvdG9jb2wpOwogICAgICB9CgogICAgICAvKioKICAgICAgICogUkVRVUlSRUQ6IFRoZSByZXNvdXJjZSBmb3Igd2hpY2ggdGhlIHBvbGljeSBpcyBiZWluZyByZXF1ZXN0ZWQuIFNlZSB0aGUgb3BlcmF0aW9uCiAgICAgICAqIGRvY3VtZW50YXRpb24gZm9yIHRoZSBhcHByb3ByaWF0ZSB2YWx1ZSBmb3IgdGhpcyBmaWVsZC4KICAgICAgICovCiAgICAgIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuU3RyaW5nIHJlc291cmNlOwoKICAgICAgLyoqIFJFUVVJUkVEOiBUaGUgcmVzb3VyY2UgZm9yIHdoaWNoIHRoZSBwb2xpY3kgaXMgYmVpbmcgcmVxdWVzdGVkLiBTZWUgdGhlIG9wZXJhdGlvbiBkb2N1bWVudGF0aW9uIGZvcgogICAgIHRoZSBhcHByb3ByaWF0ZSB2YWx1ZSBmb3IgdGhpcyBmaWVsZC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFJlc291cmNlKCkgewogICAgICAgIHJldHVybiByZXNvdXJjZTsKICAgICAgfQoKICAgICAgLyoqCiAgICAgICAqIFJFUVVJUkVEOiBUaGUgcmVzb3VyY2UgZm9yIHdoaWNoIHRoZSBwb2xpY3kgaXMgYmVpbmcgcmVxdWVzdGVkLiBTZWUgdGhlIG9wZXJhdGlvbgogICAgICAgKiBkb2N1bWVudGF0aW9uIGZvciB0aGUgYXBwcm9wcmlhdGUgdmFsdWUgZm9yIHRoaXMgZmllbGQuCiAgICAgICAqLwogICAgICBwdWJsaWMgR2V0SWFtUG9saWN5IHNldFJlc291cmNlKGphdmEubGFuZy5TdHJpbmcgcmVzb3VyY2UpIHsKICAgICAgICBpZiAoIWdldFN1cHByZXNzUGF0dGVybkNoZWNrcygpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5QcmVjb25kaXRpb25zLmNoZWNrQXJndW1lbnQoUkVTT1VSQ0VfUEFUVEVSTi5tYXRjaGVyKHJlc291cmNlKS5tYXRjaGVzKCksCiAgICAgICAgICAgICAgIlBhcmFtZXRlciByZXNvdXJjZSBtdXN0IGNvbmZvcm0gdG8gdGhlIHBhdHRlcm4gIiArCiAgICAgICAgICAgICAgIl5vcmdhbml6YXRpb25zL1teL10rJCIpOwogICAgICAgIH0KICAgICAgICB0aGlzLnJlc291cmNlID0gcmVzb3VyY2U7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgR2V0SWFtUG9saWN5IHNldChTdHJpbmcgcGFyYW1ldGVyTmFtZSwgT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIChHZXRJYW1Qb2xpY3kpIHN1cGVyLnNldChwYXJhbWV0ZXJOYW1lLCB2YWx1ZSk7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogR2V0cyBhIGBQb2xpY3lgIG9uIGEgcmVzb3VyY2UuCiAgICAgKgogICAgICogSWYgbm8gYFBvbGljeWAgaXMgc2V0IG9uIHRoZSByZXNvdXJjZSwgYSBgUG9saWN5YCBpcyByZXR1cm5lZCB3aXRoIGRlZmF1bHQgdmFsdWVzIGluY2x1ZGluZwogICAgICogYFBPTElDWV9UWVBFX05PVF9TRVRgIGZvciB0aGUgYHBvbGljeV90eXBlIG9uZW9mYC4gVGhlIGBldGFnYCB2YWx1ZSBjYW4gYmUgdXNlZCB3aXRoCiAgICAgKiBgU2V0T3JnUG9saWN5KClgIHRvIGNyZWF0ZSBvciB1cGRhdGUgYSBgUG9saWN5YCBkdXJpbmcgcmVhZC1tb2RpZnktd3JpdGUuCiAgICAgKgogICAgICogQ3JlYXRlIGEgcmVxdWVzdCBmb3IgdGhlIG1ldGhvZCAib3JnYW5pemF0aW9ucy5nZXRPcmdQb2xpY3kiLgogICAgICoKICAgICAqIFRoaXMgcmVxdWVzdCBob2xkcyB0aGUgcGFyYW1ldGVycyBuZWVkZWQgYnkgdGhlIGNsb3VkcmVzb3VyY2VtYW5hZ2VyIHNlcnZlci4gIEFmdGVyIHNldHRpbmcgYW55CiAgICAgKiBvcHRpb25hbCBwYXJhbWV0ZXJzLCBjYWxsIHRoZSB7QGxpbmsgR2V0T3JnUG9saWN5I2V4ZWN1dGUoKX0gbWV0aG9kIHRvIGludm9rZSB0aGUgcmVtb3RlCiAgICAgKiBvcGVyYXRpb24uCiAgICAgKgogICAgICogQHBhcmFtIHJlc291cmNlIE5hbWUgb2YgdGhlIHJlc291cmNlIHRoZSBgUG9saWN5YCBpcyBzZXQgb24uCiAgICAgKiBAcGFyYW0gY29udGVudCB0aGUge0BsaW5rIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmNsb3VkcmVzb3VyY2VtYW5hZ2VyLm1vZGVsLkdldE9yZ1BvbGljeVJlcXVlc3R9CiAgICAgKiBAcmV0dXJuIHRoZSByZXF1ZXN0CiAgICAgKi8KICAgIHB1YmxpYyBHZXRPcmdQb2xpY3kgZ2V0T3JnUG9saWN5KGphdmEubGFuZy5TdHJpbmcgcmVzb3VyY2UsIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmNsb3VkcmVzb3VyY2VtYW5hZ2VyLm1vZGVsLkdldE9yZ1BvbGljeVJlcXVlc3QgY29udGVudCkgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBHZXRPcmdQb2xpY3kgcmVzdWx0ID0gbmV3IEdldE9yZ1BvbGljeShyZXNvdXJjZSwgY29udGVudCk7CiAgICAgIGluaXRpYWxpemUocmVzdWx0KTsKICAgICAgcmV0dXJuIHJlc3VsdDsKICAgIH0KCiAgICBwdWJsaWMgY2xhc3MgR2V0T3JnUG9saWN5IGV4dGVuZHMgQ2xvdWRSZXNvdXJjZU1hbmFnZXJSZXF1ZXN0PGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmNsb3VkcmVzb3VyY2VtYW5hZ2VyLm1vZGVsLk9yZ1BvbGljeT4gewoKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFJFU1RfUEFUSCA9ICJ2MS97K3Jlc291cmNlfTpnZXRPcmdQb2xpY3kiOwoKICAgICAgcHJpdmF0ZSBmaW5hbCBqYXZhLnV0aWwucmVnZXguUGF0dGVybiBSRVNPVVJDRV9QQVRURVJOID0KICAgICAgICAgIGphdmEudXRpbC5yZWdleC5QYXR0ZXJuLmNvbXBpbGUoIl5vcmdhbml6YXRpb25zL1teL10rJCIpOwoKICAgICAgLyoqCiAgICAgICAqIEdldHMgYSBgUG9saWN5YCBvbiBhIHJlc291cmNlLgogICAgICAgKgogICAgICAgKiBJZiBubyBgUG9saWN5YCBpcyBzZXQgb24gdGhlIHJlc291cmNlLCBhIGBQb2xpY3lgIGlzIHJldHVybmVkIHdpdGggZGVmYXVsdCB2YWx1ZXMgaW5jbHVkaW5nCiAgICAgICAqIGBQT0xJQ1lfVFlQRV9OT1RfU0VUYCBmb3IgdGhlIGBwb2xpY3lfdHlwZSBvbmVvZmAuIFRoZSBgZXRhZ2AgdmFsdWUgY2FuIGJlIHVzZWQgd2l0aAogICAgICAgKiBgU2V0T3JnUG9saWN5KClgIHRvIGNyZWF0ZSBvciB1cGRhdGUgYSBgUG9saWN5YCBkdXJpbmcgcmVhZC1tb2RpZnktd3JpdGUuCiAgICAgICAqCiAgICAgICAqIENyZWF0ZSBhIHJlcXVlc3QgZm9yIHRoZSBtZXRob2QgIm9yZ2FuaXphdGlvbnMuZ2V0T3JnUG9saWN5Ii4KICAgICAgICoKICAgICAgICogVGhpcyByZXF1ZXN0IGhvbGRzIHRoZSBwYXJhbWV0ZXJzIG5lZWRlZCBieSB0aGUgdGhlIGNsb3VkcmVzb3VyY2VtYW5hZ2VyIHNlcnZlci4gIEFmdGVyIHNldHRpbmcKICAgICAgICogYW55IG9wdGlvbmFsIHBhcmFtZXRlcnMsIGNhbGwgdGhlIHtAbGluayBHZXRPcmdQb2xpY3kjZXhlY3V0ZSgpfSBtZXRob2QgdG8gaW52b2tlIHRoZSByZW1vdGUKICAgICAgICogb3BlcmF0aW9uLiA8cD4ge0BsaW5rCiAgICAgICAqIEdldE9yZ1BvbGljeSNpbml0aWFsaXplKGNvbS5nb29nbGUuYXBpLmNsaWVudC5nb29nbGVhcGlzLnNlcnZpY2VzLkFic3RyYWN0R29vZ2xlQ2xpZW50UmVxdWVzdCl9CiAgICAgICAqIG11c3QgYmUgY2FsbGVkIHRvIGluaXRpYWxpemUgdGhpcyBpbnN0YW5jZSBpbW1lZGlhdGVseSBhZnRlciBpbnZva2luZyB0aGUgY29uc3RydWN0b3IuIDwvcD4KICAgICAgICoKICAgICAgICogQHBhcmFtIHJlc291cmNlIE5hbWUgb2YgdGhlIHJlc291cmNlIHRoZSBgUG9saWN5YCBpcyBzZXQgb24uCiAgICAgICAqIEBwYXJhbSBjb250ZW50IHRoZSB7QGxpbmsgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuY2xvdWRyZXNvdXJjZW1hbmFnZXIubW9kZWwuR2V0T3JnUG9saWN5UmVxdWVzdH0KICAgICAgICogQHNpbmNlIDEuMTMKICAgICAgICovCiAgICAgIHByb3RlY3RlZCBHZXRPcmdQb2xpY3koamF2YS5sYW5nLlN0cmluZyByZXNvdXJjZSwgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuY2xvdWRyZXNvdXJjZW1hbmFnZXIubW9kZWwuR2V0T3JnUG9saWN5UmVxdWVzdCBjb250ZW50KSB7CiAgICAgICAgc3VwZXIoQ2xvdWRSZXNvdXJjZU1hbmFnZXIudGhpcywgIlBPU1QiLCBSRVNUX1BBVEgsIGNvbnRlbnQsIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmNsb3VkcmVzb3VyY2VtYW5hZ2VyLm1vZGVsLk9yZ1BvbGljeS5jbGFzcyk7CiAgICAgICAgdGhpcy5yZXNvdXJjZSA9IGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLlByZWNvbmRpdGlvbnMuY2hlY2tOb3ROdWxsKHJlc291cmNlLCAiUmVxdWlyZWQgcGFyYW1ldGVyIHJlc291cmNlIG11c3QgYmUgc3BlY2lmaWVkLiIpOwogICAgICAgIGlmICghZ2V0U3VwcHJlc3NQYXR0ZXJuQ2hlY2tzKCkpIHsKICAgICAgICAgIGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLlByZWNvbmRpdGlvbnMuY2hlY2tBcmd1bWVudChSRVNPVVJDRV9QQVRURVJOLm1hdGNoZXIocmVzb3VyY2UpLm1hdGNoZXMoKSwKICAgICAgICAgICAgICAiUGFyYW1ldGVyIHJlc291cmNlIG11c3QgY29uZm9ybSB0byB0aGUgcGF0dGVybiAiICsKICAgICAgICAgICAgICAiXm9yZ2FuaXphdGlvbnMvW14vXSskIik7CiAgICAgICAgfQogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIEdldE9yZ1BvbGljeSBzZXQkWGdhZnYoamF2YS5sYW5nLlN0cmluZyAkWGdhZnYpIHsKICAgICAgICByZXR1cm4gKEdldE9yZ1BvbGljeSkgc3VwZXIuc2V0JFhnYWZ2KCRYZ2Fmdik7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgR2V0T3JnUG9saWN5IHNldEFjY2Vzc1Rva2VuKGphdmEubGFuZy5TdHJpbmcgYWNjZXNzVG9rZW4pIHsKICAgICAgICByZXR1cm4gKEdldE9yZ1BvbGljeSkgc3VwZXIuc2V0QWNjZXNzVG9rZW4oYWNjZXNzVG9rZW4pOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIEdldE9yZ1BvbGljeSBzZXRBbHQoamF2YS5sYW5nLlN0cmluZyBhbHQpIHsKICAgICAgICByZXR1cm4gKEdldE9yZ1BvbGljeSkgc3VwZXIuc2V0QWx0KGFsdCk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgR2V0T3JnUG9saWN5IHNldENhbGxiYWNrKGphdmEubGFuZy5TdHJpbmcgY2FsbGJhY2spIHsKICAgICAgICByZXR1cm4gKEdldE9yZ1BvbGljeSkgc3VwZXIuc2V0Q2FsbGJhY2soY2FsbGJhY2spOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIEdldE9yZ1BvbGljeSBzZXRGaWVsZHMoamF2YS5sYW5nLlN0cmluZyBmaWVsZHMpIHsKICAgICAgICByZXR1cm4gKEdldE9yZ1BvbGljeSkgc3VwZXIuc2V0RmllbGRzKGZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgR2V0T3JnUG9saWN5IHNldEtleShqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIHJldHVybiAoR2V0T3JnUG9saWN5KSBzdXBlci5zZXRLZXkoa2V5KTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBHZXRPcmdQb2xpY3kgc2V0T2F1dGhUb2tlbihqYXZhLmxhbmcuU3RyaW5nIG9hdXRoVG9rZW4pIHsKICAgICAgICByZXR1cm4gKEdldE9yZ1BvbGljeSkgc3VwZXIuc2V0T2F1dGhUb2tlbihvYXV0aFRva2VuKTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBHZXRPcmdQb2xpY3kgc2V0UHJldHR5UHJpbnQoamF2YS5sYW5nLkJvb2xlYW4gcHJldHR5UHJpbnQpIHsKICAgICAgICByZXR1cm4gKEdldE9yZ1BvbGljeSkgc3VwZXIuc2V0UHJldHR5UHJpbnQocHJldHR5UHJpbnQpOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIEdldE9yZ1BvbGljeSBzZXRRdW90YVVzZXIoamF2YS5sYW5nLlN0cmluZyBxdW90YVVzZXIpIHsKICAgICAgICByZXR1cm4gKEdldE9yZ1BvbGljeSkgc3VwZXIuc2V0UXVvdGFVc2VyKHF1b3RhVXNlcik7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgR2V0T3JnUG9saWN5IHNldFVwbG9hZFR5cGUoamF2YS5sYW5nLlN0cmluZyB1cGxvYWRUeXBlKSB7CiAgICAgICAgcmV0dXJuIChHZXRPcmdQb2xpY3kpIHN1cGVyLnNldFVwbG9hZFR5cGUodXBsb2FkVHlwZSk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgR2V0T3JnUG9saWN5IHNldFVwbG9hZFByb3RvY29sKGphdmEubGFuZy5TdHJpbmcgdXBsb2FkUHJvdG9jb2wpIHsKICAgICAgICByZXR1cm4gKEdldE9yZ1BvbGljeSkgc3VwZXIuc2V0VXBsb2FkUHJvdG9jb2wodXBsb2FkUHJvdG9jb2wpOwogICAgICB9CgogICAgICAvKiogTmFtZSBvZiB0aGUgcmVzb3VyY2UgdGhlIGBQb2xpY3lgIGlzIHNldCBvbi4gKi8KICAgICAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogICAgICBwcml2YXRlIGphdmEubGFuZy5TdHJpbmcgcmVzb3VyY2U7CgogICAgICAvKiogTmFtZSBvZiB0aGUgcmVzb3VyY2UgdGhlIGBQb2xpY3lgIGlzIHNldCBvbi4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFJlc291cmNlKCkgewogICAgICAgIHJldHVybiByZXNvdXJjZTsKICAgICAgfQoKICAgICAgLyoqIE5hbWUgb2YgdGhlIHJlc291cmNlIHRoZSBgUG9saWN5YCBpcyBzZXQgb24uICovCiAgICAgIHB1YmxpYyBHZXRPcmdQb2xpY3kgc2V0UmVzb3VyY2UoamF2YS5sYW5nLlN0cmluZyByZXNvdXJjZSkgewogICAgICAgIGlmICghZ2V0U3VwcHJlc3NQYXR0ZXJuQ2hlY2tzKCkpIHsKICAgICAgICAgIGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLlByZWNvbmRpdGlvbnMuY2hlY2tBcmd1bWVudChSRVNPVVJDRV9QQVRURVJOLm1hdGNoZXIocmVzb3VyY2UpLm1hdGNoZXMoKSwKICAgICAgICAgICAgICAiUGFyYW1ldGVyIHJlc291cmNlIG11c3QgY29uZm9ybSB0byB0aGUgcGF0dGVybiAiICsKICAgICAgICAgICAgICAiXm9yZ2FuaXphdGlvbnMvW14vXSskIik7CiAgICAgICAgfQogICAgICAgIHRoaXMucmVzb3VyY2UgPSByZXNvdXJjZTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBHZXRPcmdQb2xpY3kgc2V0KFN0cmluZyBwYXJhbWV0ZXJOYW1lLCBPYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gKEdldE9yZ1BvbGljeSkgc3VwZXIuc2V0KHBhcmFtZXRlck5hbWUsIHZhbHVlKTsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiBMaXN0cyBgQ29uc3RyYWludHNgIHRoYXQgY291bGQgYmUgYXBwbGllZCBvbiB0aGUgc3BlY2lmaWVkIHJlc291cmNlLgogICAgICoKICAgICAqIENyZWF0ZSBhIHJlcXVlc3QgZm9yIHRoZSBtZXRob2QgIm9yZ2FuaXphdGlvbnMubGlzdEF2YWlsYWJsZU9yZ1BvbGljeUNvbnN0cmFpbnRzIi4KICAgICAqCiAgICAgKiBUaGlzIHJlcXVlc3QgaG9sZHMgdGhlIHBhcmFtZXRlcnMgbmVlZGVkIGJ5IHRoZSBjbG91ZHJlc291cmNlbWFuYWdlciBzZXJ2ZXIuICBBZnRlciBzZXR0aW5nIGFueQogICAgICogb3B0aW9uYWwgcGFyYW1ldGVycywgY2FsbCB0aGUge0BsaW5rIExpc3RBdmFpbGFibGVPcmdQb2xpY3lDb25zdHJhaW50cyNleGVjdXRlKCl9IG1ldGhvZCB0bwogICAgICogaW52b2tlIHRoZSByZW1vdGUgb3BlcmF0aW9uLgogICAgICoKICAgICAqIEBwYXJhbSByZXNvdXJjZSBOYW1lIG9mIHRoZSByZXNvdXJjZSB0byBsaXN0IGBDb25zdHJhaW50c2AgZm9yLgogICAgICogQHBhcmFtIGNvbnRlbnQgdGhlIHtAbGluayBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5jbG91ZHJlc291cmNlbWFuYWdlci5tb2RlbC5MaXN0QXZhaWxhYmxlT3JnUG9saWN5Q29uc3RyYWludHNSZXF1ZXN0fQogICAgICogQHJldHVybiB0aGUgcmVxdWVzdAogICAgICovCiAgICBwdWJsaWMgTGlzdEF2YWlsYWJsZU9yZ1BvbGljeUNvbnN0cmFpbnRzIGxpc3RBdmFpbGFibGVPcmdQb2xpY3lDb25zdHJhaW50cyhqYXZhLmxhbmcuU3RyaW5nIHJlc291cmNlLCBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5jbG91ZHJlc291cmNlbWFuYWdlci5tb2RlbC5MaXN0QXZhaWxhYmxlT3JnUG9saWN5Q29uc3RyYWludHNSZXF1ZXN0IGNvbnRlbnQpIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgTGlzdEF2YWlsYWJsZU9yZ1BvbGljeUNvbnN0cmFpbnRzIHJlc3VsdCA9IG5ldyBMaXN0QXZhaWxhYmxlT3JnUG9saWN5Q29uc3RyYWludHMocmVzb3VyY2UsIGNvbnRlbnQpOwogICAgICBpbml0aWFsaXplKHJlc3VsdCk7CiAgICAgIHJldHVybiByZXN1bHQ7CiAgICB9CgogICAgcHVibGljIGNsYXNzIExpc3RBdmFpbGFibGVPcmdQb2xpY3lDb25zdHJhaW50cyBleHRlbmRzIENsb3VkUmVzb3VyY2VNYW5hZ2VyUmVxdWVzdDxjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5jbG91ZHJlc291cmNlbWFuYWdlci5tb2RlbC5MaXN0QXZhaWxhYmxlT3JnUG9saWN5Q29uc3RyYWludHNSZXNwb25zZT4gewoKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFJFU1RfUEFUSCA9ICJ2MS97K3Jlc291cmNlfTpsaXN0QXZhaWxhYmxlT3JnUG9saWN5Q29uc3RyYWludHMiOwoKICAgICAgcHJpdmF0ZSBmaW5hbCBqYXZhLnV0aWwucmVnZXguUGF0dGVybiBSRVNPVVJDRV9QQVRURVJOID0KICAgICAgICAgIGphdmEudXRpbC5yZWdleC5QYXR0ZXJuLmNvbXBpbGUoIl5vcmdhbml6YXRpb25zL1teL10rJCIpOwoKICAgICAgLyoqCiAgICAgICAqIExpc3RzIGBDb25zdHJhaW50c2AgdGhhdCBjb3VsZCBiZSBhcHBsaWVkIG9uIHRoZSBzcGVjaWZpZWQgcmVzb3VyY2UuCiAgICAgICAqCiAgICAgICAqIENyZWF0ZSBhIHJlcXVlc3QgZm9yIHRoZSBtZXRob2QgIm9yZ2FuaXphdGlvbnMubGlzdEF2YWlsYWJsZU9yZ1BvbGljeUNvbnN0cmFpbnRzIi4KICAgICAgICoKICAgICAgICogVGhpcyByZXF1ZXN0IGhvbGRzIHRoZSBwYXJhbWV0ZXJzIG5lZWRlZCBieSB0aGUgdGhlIGNsb3VkcmVzb3VyY2VtYW5hZ2VyIHNlcnZlci4gIEFmdGVyIHNldHRpbmcKICAgICAgICogYW55IG9wdGlvbmFsIHBhcmFtZXRlcnMsIGNhbGwgdGhlIHtAbGluayBMaXN0QXZhaWxhYmxlT3JnUG9saWN5Q29uc3RyYWludHMjZXhlY3V0ZSgpfSBtZXRob2QgdG8KICAgICAgICogaW52b2tlIHRoZSByZW1vdGUgb3BlcmF0aW9uLiA8cD4ge0BsaW5rIExpc3RBdmFpbGFibGVPcmdQb2xpY3lDb25zdHJhaW50cyNpbml0aWFsaXplKGNvbS5nb29nbGUKICAgICAgICogLmFwaS5jbGllbnQuZ29vZ2xlYXBpcy5zZXJ2aWNlcy5BYnN0cmFjdEdvb2dsZUNsaWVudFJlcXVlc3QpfSBtdXN0IGJlIGNhbGxlZCB0byBpbml0aWFsaXplIHRoaXMKICAgICAgICogaW5zdGFuY2UgaW1tZWRpYXRlbHkgYWZ0ZXIgaW52b2tpbmcgdGhlIGNvbnN0cnVjdG9yLiA8L3A+CiAgICAgICAqCiAgICAgICAqIEBwYXJhbSByZXNvdXJjZSBOYW1lIG9mIHRoZSByZXNvdXJjZSB0byBsaXN0IGBDb25zdHJhaW50c2AgZm9yLgogICAgICAgKiBAcGFyYW0gY29udGVudCB0aGUge0BsaW5rIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmNsb3VkcmVzb3VyY2VtYW5hZ2VyLm1vZGVsLkxpc3RBdmFpbGFibGVPcmdQb2xpY3lDb25zdHJhaW50c1JlcXVlc3R9CiAgICAgICAqIEBzaW5jZSAxLjEzCiAgICAgICAqLwogICAgICBwcm90ZWN0ZWQgTGlzdEF2YWlsYWJsZU9yZ1BvbGljeUNvbnN0cmFpbnRzKGphdmEubGFuZy5TdHJpbmcgcmVzb3VyY2UsIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmNsb3VkcmVzb3VyY2VtYW5hZ2VyLm1vZGVsLkxpc3RBdmFpbGFibGVPcmdQb2xpY3lDb25zdHJhaW50c1JlcXVlc3QgY29udGVudCkgewogICAgICAgIHN1cGVyKENsb3VkUmVzb3VyY2VNYW5hZ2VyLnRoaXMsICJQT1NUIiwgUkVTVF9QQVRILCBjb250ZW50LCBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5jbG91ZHJlc291cmNlbWFuYWdlci5tb2RlbC5MaXN0QXZhaWxhYmxlT3JnUG9saWN5Q29uc3RyYWludHNSZXNwb25zZS5jbGFzcyk7CiAgICAgICAgdGhpcy5yZXNvdXJjZSA9IGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLlByZWNvbmRpdGlvbnMuY2hlY2tOb3ROdWxsKHJlc291cmNlLCAiUmVxdWlyZWQgcGFyYW1ldGVyIHJlc291cmNlIG11c3QgYmUgc3BlY2lmaWVkLiIpOwogICAgICAgIGlmICghZ2V0U3VwcHJlc3NQYXR0ZXJuQ2hlY2tzKCkpIHsKICAgICAgICAgIGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLlByZWNvbmRpdGlvbnMuY2hlY2tBcmd1bWVudChSRVNPVVJDRV9QQVRURVJOLm1hdGNoZXIocmVzb3VyY2UpLm1hdGNoZXMoKSwKICAgICAgICAgICAgICAiUGFyYW1ldGVyIHJlc291cmNlIG11c3QgY29uZm9ybSB0byB0aGUgcGF0dGVybiAiICsKICAgICAgICAgICAgICAiXm9yZ2FuaXphdGlvbnMvW14vXSskIik7CiAgICAgICAgfQogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIExpc3RBdmFpbGFibGVPcmdQb2xpY3lDb25zdHJhaW50cyBzZXQkWGdhZnYoamF2YS5sYW5nLlN0cmluZyAkWGdhZnYpIHsKICAgICAgICByZXR1cm4gKExpc3RBdmFpbGFibGVPcmdQb2xpY3lDb25zdHJhaW50cykgc3VwZXIuc2V0JFhnYWZ2KCRYZ2Fmdik7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgTGlzdEF2YWlsYWJsZU9yZ1BvbGljeUNvbnN0cmFpbnRzIHNldEFjY2Vzc1Rva2VuKGphdmEubGFuZy5TdHJpbmcgYWNjZXNzVG9rZW4pIHsKICAgICAgICByZXR1cm4gKExpc3RBdmFpbGFibGVPcmdQb2xpY3lDb25zdHJhaW50cykgc3VwZXIuc2V0QWNjZXNzVG9rZW4oYWNjZXNzVG9rZW4pOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIExpc3RBdmFpbGFibGVPcmdQb2xpY3lDb25zdHJhaW50cyBzZXRBbHQoamF2YS5sYW5nLlN0cmluZyBhbHQpIHsKICAgICAgICByZXR1cm4gKExpc3RBdmFpbGFibGVPcmdQb2xpY3lDb25zdHJhaW50cykgc3VwZXIuc2V0QWx0KGFsdCk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgTGlzdEF2YWlsYWJsZU9yZ1BvbGljeUNvbnN0cmFpbnRzIHNldENhbGxiYWNrKGphdmEubGFuZy5TdHJpbmcgY2FsbGJhY2spIHsKICAgICAgICByZXR1cm4gKExpc3RBdmFpbGFibGVPcmdQb2xpY3lDb25zdHJhaW50cykgc3VwZXIuc2V0Q2FsbGJhY2soY2FsbGJhY2spOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIExpc3RBdmFpbGFibGVPcmdQb2xpY3lDb25zdHJhaW50cyBzZXRGaWVsZHMoamF2YS5sYW5nLlN0cmluZyBmaWVsZHMpIHsKICAgICAgICByZXR1cm4gKExpc3RBdmFpbGFibGVPcmdQb2xpY3lDb25zdHJhaW50cykgc3VwZXIuc2V0RmllbGRzKGZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgTGlzdEF2YWlsYWJsZU9yZ1BvbGljeUNvbnN0cmFpbnRzIHNldEtleShqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIHJldHVybiAoTGlzdEF2YWlsYWJsZU9yZ1BvbGljeUNvbnN0cmFpbnRzKSBzdXBlci5zZXRLZXkoa2V5KTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBMaXN0QXZhaWxhYmxlT3JnUG9saWN5Q29uc3RyYWludHMgc2V0T2F1dGhUb2tlbihqYXZhLmxhbmcuU3RyaW5nIG9hdXRoVG9rZW4pIHsKICAgICAgICByZXR1cm4gKExpc3RBdmFpbGFibGVPcmdQb2xpY3lDb25zdHJhaW50cykgc3VwZXIuc2V0T2F1dGhUb2tlbihvYXV0aFRva2VuKTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBMaXN0QXZhaWxhYmxlT3JnUG9saWN5Q29uc3RyYWludHMgc2V0UHJldHR5UHJpbnQoamF2YS5sYW5nLkJvb2xlYW4gcHJldHR5UHJpbnQpIHsKICAgICAgICByZXR1cm4gKExpc3RBdmFpbGFibGVPcmdQb2xpY3lDb25zdHJhaW50cykgc3VwZXIuc2V0UHJldHR5UHJpbnQocHJldHR5UHJpbnQpOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIExpc3RBdmFpbGFibGVPcmdQb2xpY3lDb25zdHJhaW50cyBzZXRRdW90YVVzZXIoamF2YS5sYW5nLlN0cmluZyBxdW90YVVzZXIpIHsKICAgICAgICByZXR1cm4gKExpc3RBdmFpbGFibGVPcmdQb2xpY3lDb25zdHJhaW50cykgc3VwZXIuc2V0UXVvdGFVc2VyKHF1b3RhVXNlcik7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgTGlzdEF2YWlsYWJsZU9yZ1BvbGljeUNvbnN0cmFpbnRzIHNldFVwbG9hZFR5cGUoamF2YS5sYW5nLlN0cmluZyB1cGxvYWRUeXBlKSB7CiAgICAgICAgcmV0dXJuIChMaXN0QXZhaWxhYmxlT3JnUG9saWN5Q29uc3RyYWludHMpIHN1cGVyLnNldFVwbG9hZFR5cGUodXBsb2FkVHlwZSk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgTGlzdEF2YWlsYWJsZU9yZ1BvbGljeUNvbnN0cmFpbnRzIHNldFVwbG9hZFByb3RvY29sKGphdmEubGFuZy5TdHJpbmcgdXBsb2FkUHJvdG9jb2wpIHsKICAgICAgICByZXR1cm4gKExpc3RBdmFpbGFibGVPcmdQb2xpY3lDb25zdHJhaW50cykgc3VwZXIuc2V0VXBsb2FkUHJvdG9jb2wodXBsb2FkUHJvdG9jb2wpOwogICAgICB9CgogICAgICAvKiogTmFtZSBvZiB0aGUgcmVzb3VyY2UgdG8gbGlzdCBgQ29uc3RyYWludHNgIGZvci4gKi8KICAgICAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogICAgICBwcml2YXRlIGphdmEubGFuZy5TdHJpbmcgcmVzb3VyY2U7CgogICAgICAvKiogTmFtZSBvZiB0aGUgcmVzb3VyY2UgdG8gbGlzdCBgQ29uc3RyYWludHNgIGZvci4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFJlc291cmNlKCkgewogICAgICAgIHJldHVybiByZXNvdXJjZTsKICAgICAgfQoKICAgICAgLyoqIE5hbWUgb2YgdGhlIHJlc291cmNlIHRvIGxpc3QgYENvbnN0cmFpbnRzYCBmb3IuICovCiAgICAgIHB1YmxpYyBMaXN0QXZhaWxhYmxlT3JnUG9saWN5Q29uc3RyYWludHMgc2V0UmVzb3VyY2UoamF2YS5sYW5nLlN0cmluZyByZXNvdXJjZSkgewogICAgICAgIGlmICghZ2V0U3VwcHJlc3NQYXR0ZXJuQ2hlY2tzKCkpIHsKICAgICAgICAgIGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLlByZWNvbmRpdGlvbnMuY2hlY2tBcmd1bWVudChSRVNPVVJDRV9QQVRURVJOLm1hdGNoZXIocmVzb3VyY2UpLm1hdGNoZXMoKSwKICAgICAgICAgICAgICAiUGFyYW1ldGVyIHJlc291cmNlIG11c3QgY29uZm9ybSB0byB0aGUgcGF0dGVybiAiICsKICAgICAgICAgICAgICAiXm9yZ2FuaXphdGlvbnMvW14vXSskIik7CiAgICAgICAgfQogICAgICAgIHRoaXMucmVzb3VyY2UgPSByZXNvdXJjZTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBMaXN0QXZhaWxhYmxlT3JnUG9saWN5Q29uc3RyYWludHMgc2V0KFN0cmluZyBwYXJhbWV0ZXJOYW1lLCBPYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gKExpc3RBdmFpbGFibGVPcmdQb2xpY3lDb25zdHJhaW50cykgc3VwZXIuc2V0KHBhcmFtZXRlck5hbWUsIHZhbHVlKTsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiBMaXN0cyBhbGwgdGhlIGBQb2xpY2llc2Agc2V0IGZvciBhIHBhcnRpY3VsYXIgcmVzb3VyY2UuCiAgICAgKgogICAgICogQ3JlYXRlIGEgcmVxdWVzdCBmb3IgdGhlIG1ldGhvZCAib3JnYW5pemF0aW9ucy5saXN0T3JnUG9saWNpZXMiLgogICAgICoKICAgICAqIFRoaXMgcmVxdWVzdCBob2xkcyB0aGUgcGFyYW1ldGVycyBuZWVkZWQgYnkgdGhlIGNsb3VkcmVzb3VyY2VtYW5hZ2VyIHNlcnZlci4gIEFmdGVyIHNldHRpbmcgYW55CiAgICAgKiBvcHRpb25hbCBwYXJhbWV0ZXJzLCBjYWxsIHRoZSB7QGxpbmsgTGlzdE9yZ1BvbGljaWVzI2V4ZWN1dGUoKX0gbWV0aG9kIHRvIGludm9rZSB0aGUgcmVtb3RlCiAgICAgKiBvcGVyYXRpb24uCiAgICAgKgogICAgICogQHBhcmFtIHJlc291cmNlIE5hbWUgb2YgdGhlIHJlc291cmNlIHRvIGxpc3QgUG9saWNpZXMgZm9yLgogICAgICogQHBhcmFtIGNvbnRlbnQgdGhlIHtAbGluayBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5jbG91ZHJlc291cmNlbWFuYWdlci5tb2RlbC5MaXN0T3JnUG9saWNpZXNSZXF1ZXN0fQogICAgICogQHJldHVybiB0aGUgcmVxdWVzdAogICAgICovCiAgICBwdWJsaWMgTGlzdE9yZ1BvbGljaWVzIGxpc3RPcmdQb2xpY2llcyhqYXZhLmxhbmcuU3RyaW5nIHJlc291cmNlLCBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5jbG91ZHJlc291cmNlbWFuYWdlci5tb2RlbC5MaXN0T3JnUG9saWNpZXNSZXF1ZXN0IGNvbnRlbnQpIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgTGlzdE9yZ1BvbGljaWVzIHJlc3VsdCA9IG5ldyBMaXN0T3JnUG9saWNpZXMocmVzb3VyY2UsIGNvbnRlbnQpOwogICAgICBpbml0aWFsaXplKHJlc3VsdCk7CiAgICAgIHJldHVybiByZXN1bHQ7CiAgICB9CgogICAgcHVibGljIGNsYXNzIExpc3RPcmdQb2xpY2llcyBleHRlbmRzIENsb3VkUmVzb3VyY2VNYW5hZ2VyUmVxdWVzdDxjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5jbG91ZHJlc291cmNlbWFuYWdlci5tb2RlbC5MaXN0T3JnUG9saWNpZXNSZXNwb25zZT4gewoKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFJFU1RfUEFUSCA9ICJ2MS97K3Jlc291cmNlfTpsaXN0T3JnUG9saWNpZXMiOwoKICAgICAgcHJpdmF0ZSBmaW5hbCBqYXZhLnV0aWwucmVnZXguUGF0dGVybiBSRVNPVVJDRV9QQVRURVJOID0KICAgICAgICAgIGphdmEudXRpbC5yZWdleC5QYXR0ZXJuLmNvbXBpbGUoIl5vcmdhbml6YXRpb25zL1teL10rJCIpOwoKICAgICAgLyoqCiAgICAgICAqIExpc3RzIGFsbCB0aGUgYFBvbGljaWVzYCBzZXQgZm9yIGEgcGFydGljdWxhciByZXNvdXJjZS4KICAgICAgICoKICAgICAgICogQ3JlYXRlIGEgcmVxdWVzdCBmb3IgdGhlIG1ldGhvZCAib3JnYW5pemF0aW9ucy5saXN0T3JnUG9saWNpZXMiLgogICAgICAgKgogICAgICAgKiBUaGlzIHJlcXVlc3QgaG9sZHMgdGhlIHBhcmFtZXRlcnMgbmVlZGVkIGJ5IHRoZSB0aGUgY2xvdWRyZXNvdXJjZW1hbmFnZXIgc2VydmVyLiAgQWZ0ZXIgc2V0dGluZwogICAgICAgKiBhbnkgb3B0aW9uYWwgcGFyYW1ldGVycywgY2FsbCB0aGUge0BsaW5rIExpc3RPcmdQb2xpY2llcyNleGVjdXRlKCl9IG1ldGhvZCB0byBpbnZva2UgdGhlIHJlbW90ZQogICAgICAgKiBvcGVyYXRpb24uIDxwPiB7QGxpbmsgTGlzdE9yZ1BvbGljaWVzI2luaXRpYWxpemUoY29tLmdvb2dsZS5hcGkuY2xpZW50Lmdvb2dsZWFwaXMuc2VydmljZXMuQWJzdAogICAgICAgKiByYWN0R29vZ2xlQ2xpZW50UmVxdWVzdCl9IG11c3QgYmUgY2FsbGVkIHRvIGluaXRpYWxpemUgdGhpcyBpbnN0YW5jZSBpbW1lZGlhdGVseSBhZnRlciBpbnZva2luZwogICAgICAgKiB0aGUgY29uc3RydWN0b3IuIDwvcD4KICAgICAgICoKICAgICAgICogQHBhcmFtIHJlc291cmNlIE5hbWUgb2YgdGhlIHJlc291cmNlIHRvIGxpc3QgUG9saWNpZXMgZm9yLgogICAgICAgKiBAcGFyYW0gY29udGVudCB0aGUge0BsaW5rIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmNsb3VkcmVzb3VyY2VtYW5hZ2VyLm1vZGVsLkxpc3RPcmdQb2xpY2llc1JlcXVlc3R9CiAgICAgICAqIEBzaW5jZSAxLjEzCiAgICAgICAqLwogICAgICBwcm90ZWN0ZWQgTGlzdE9yZ1BvbGljaWVzKGphdmEubGFuZy5TdHJpbmcgcmVzb3VyY2UsIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmNsb3VkcmVzb3VyY2VtYW5hZ2VyLm1vZGVsLkxpc3RPcmdQb2xpY2llc1JlcXVlc3QgY29udGVudCkgewogICAgICAgIHN1cGVyKENsb3VkUmVzb3VyY2VNYW5hZ2VyLnRoaXMsICJQT1NUIiwgUkVTVF9QQVRILCBjb250ZW50LCBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5jbG91ZHJlc291cmNlbWFuYWdlci5tb2RlbC5MaXN0T3JnUG9saWNpZXNSZXNwb25zZS5jbGFzcyk7CiAgICAgICAgdGhpcy5yZXNvdXJjZSA9IGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLlByZWNvbmRpdGlvbnMuY2hlY2tOb3ROdWxsKHJlc291cmNlLCAiUmVxdWlyZWQgcGFyYW1ldGVyIHJlc291cmNlIG11c3QgYmUgc3BlY2lmaWVkLiIpOwogICAgICAgIGlmICghZ2V0U3VwcHJlc3NQYXR0ZXJuQ2hlY2tzKCkpIHsKICAgICAgICAgIGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLlByZWNvbmRpdGlvbnMuY2hlY2tBcmd1bWVudChSRVNPVVJDRV9QQVRURVJOLm1hdGNoZXIocmVzb3VyY2UpLm1hdGNoZXMoKSwKICAgICAgICAgICAgICAiUGFyYW1ldGVyIHJlc291cmNlIG11c3QgY29uZm9ybSB0byB0aGUgcGF0dGVybiAiICsKICAgICAgICAgICAgICAiXm9yZ2FuaXphdGlvbnMvW14vXSskIik7CiAgICAgICAgfQogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIExpc3RPcmdQb2xpY2llcyBzZXQkWGdhZnYoamF2YS5sYW5nLlN0cmluZyAkWGdhZnYpIHsKICAgICAgICByZXR1cm4gKExpc3RPcmdQb2xpY2llcykgc3VwZXIuc2V0JFhnYWZ2KCRYZ2Fmdik7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgTGlzdE9yZ1BvbGljaWVzIHNldEFjY2Vzc1Rva2VuKGphdmEubGFuZy5TdHJpbmcgYWNjZXNzVG9rZW4pIHsKICAgICAgICByZXR1cm4gKExpc3RPcmdQb2xpY2llcykgc3VwZXIuc2V0QWNjZXNzVG9rZW4oYWNjZXNzVG9rZW4pOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIExpc3RPcmdQb2xpY2llcyBzZXRBbHQoamF2YS5sYW5nLlN0cmluZyBhbHQpIHsKICAgICAgICByZXR1cm4gKExpc3RPcmdQb2xpY2llcykgc3VwZXIuc2V0QWx0KGFsdCk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgTGlzdE9yZ1BvbGljaWVzIHNldENhbGxiYWNrKGphdmEubGFuZy5TdHJpbmcgY2FsbGJhY2spIHsKICAgICAgICByZXR1cm4gKExpc3RPcmdQb2xpY2llcykgc3VwZXIuc2V0Q2FsbGJhY2soY2FsbGJhY2spOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIExpc3RPcmdQb2xpY2llcyBzZXRGaWVsZHMoamF2YS5sYW5nLlN0cmluZyBmaWVsZHMpIHsKICAgICAgICByZXR1cm4gKExpc3RPcmdQb2xpY2llcykgc3VwZXIuc2V0RmllbGRzKGZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgTGlzdE9yZ1BvbGljaWVzIHNldEtleShqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIHJldHVybiAoTGlzdE9yZ1BvbGljaWVzKSBzdXBlci5zZXRLZXkoa2V5KTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBMaXN0T3JnUG9saWNpZXMgc2V0T2F1dGhUb2tlbihqYXZhLmxhbmcuU3RyaW5nIG9hdXRoVG9rZW4pIHsKICAgICAgICByZXR1cm4gKExpc3RPcmdQb2xpY2llcykgc3VwZXIuc2V0T2F1dGhUb2tlbihvYXV0aFRva2VuKTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBMaXN0T3JnUG9saWNpZXMgc2V0UHJldHR5UHJpbnQoamF2YS5sYW5nLkJvb2xlYW4gcHJldHR5UHJpbnQpIHsKICAgICAgICByZXR1cm4gKExpc3RPcmdQb2xpY2llcykgc3VwZXIuc2V0UHJldHR5UHJpbnQocHJldHR5UHJpbnQpOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIExpc3RPcmdQb2xpY2llcyBzZXRRdW90YVVzZXIoamF2YS5sYW5nLlN0cmluZyBxdW90YVVzZXIpIHsKICAgICAgICByZXR1cm4gKExpc3RPcmdQb2xpY2llcykgc3VwZXIuc2V0UXVvdGFVc2VyKHF1b3RhVXNlcik7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgTGlzdE9yZ1BvbGljaWVzIHNldFVwbG9hZFR5cGUoamF2YS5sYW5nLlN0cmluZyB1cGxvYWRUeXBlKSB7CiAgICAgICAgcmV0dXJuIChMaXN0T3JnUG9saWNpZXMpIHN1cGVyLnNldFVwbG9hZFR5cGUodXBsb2FkVHlwZSk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgTGlzdE9yZ1BvbGljaWVzIHNldFVwbG9hZFByb3RvY29sKGphdmEubGFuZy5TdHJpbmcgdXBsb2FkUHJvdG9jb2wpIHsKICAgICAgICByZXR1cm4gKExpc3RPcmdQb2xpY2llcykgc3VwZXIuc2V0VXBsb2FkUHJvdG9jb2wodXBsb2FkUHJvdG9jb2wpOwogICAgICB9CgogICAgICAvKiogTmFtZSBvZiB0aGUgcmVzb3VyY2UgdG8gbGlzdCBQb2xpY2llcyBmb3IuICovCiAgICAgIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuU3RyaW5nIHJlc291cmNlOwoKICAgICAgLyoqIE5hbWUgb2YgdGhlIHJlc291cmNlIHRvIGxpc3QgUG9saWNpZXMgZm9yLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0UmVzb3VyY2UoKSB7CiAgICAgICAgcmV0dXJuIHJlc291cmNlOwogICAgICB9CgogICAgICAvKiogTmFtZSBvZiB0aGUgcmVzb3VyY2UgdG8gbGlzdCBQb2xpY2llcyBmb3IuICovCiAgICAgIHB1YmxpYyBMaXN0T3JnUG9saWNpZXMgc2V0UmVzb3VyY2UoamF2YS5sYW5nLlN0cmluZyByZXNvdXJjZSkgewogICAgICAgIGlmICghZ2V0U3VwcHJlc3NQYXR0ZXJuQ2hlY2tzKCkpIHsKICAgICAgICAgIGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLlByZWNvbmRpdGlvbnMuY2hlY2tBcmd1bWVudChSRVNPVVJDRV9QQVRURVJOLm1hdGNoZXIocmVzb3VyY2UpLm1hdGNoZXMoKSwKICAgICAgICAgICAgICAiUGFyYW1ldGVyIHJlc291cmNlIG11c3QgY29uZm9ybSB0byB0aGUgcGF0dGVybiAiICsKICAgICAgICAgICAgICAiXm9yZ2FuaXphdGlvbnMvW14vXSskIik7CiAgICAgICAgfQogICAgICAgIHRoaXMucmVzb3VyY2UgPSByZXNvdXJjZTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBMaXN0T3JnUG9saWNpZXMgc2V0KFN0cmluZyBwYXJhbWV0ZXJOYW1lLCBPYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gKExpc3RPcmdQb2xpY2llcykgc3VwZXIuc2V0KHBhcmFtZXRlck5hbWUsIHZhbHVlKTsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiBTZWFyY2hlcyBPcmdhbml6YXRpb24gcmVzb3VyY2VzIHRoYXQgYXJlIHZpc2libGUgdG8gdGhlIHVzZXIgYW5kIHNhdGlzZnkgdGhlIHNwZWNpZmllZCBmaWx0ZXIuCiAgICAgKiBUaGlzIG1ldGhvZCByZXR1cm5zIE9yZ2FuaXphdGlvbnMgaW4gYW4gdW5zcGVjaWZpZWQgb3JkZXIuIE5ldyBPcmdhbml6YXRpb25zIGRvIG5vdCBuZWNlc3NhcmlseQogICAgICogYXBwZWFyIGF0IHRoZSBlbmQgb2YgdGhlIHJlc3VsdHMuCiAgICAgKgogICAgICogU2VhcmNoIHdpbGwgb25seSByZXR1cm4gb3JnYW5pemF0aW9ucyBvbiB3aGljaCB0aGUgdXNlciBoYXMgdGhlIHBlcm1pc3Npb24KICAgICAqIGByZXNvdXJjZW1hbmFnZXIub3JnYW5pemF0aW9ucy5nZXRgCiAgICAgKgogICAgICogQ3JlYXRlIGEgcmVxdWVzdCBmb3IgdGhlIG1ldGhvZCAib3JnYW5pemF0aW9ucy5zZWFyY2giLgogICAgICoKICAgICAqIFRoaXMgcmVxdWVzdCBob2xkcyB0aGUgcGFyYW1ldGVycyBuZWVkZWQgYnkgdGhlIGNsb3VkcmVzb3VyY2VtYW5hZ2VyIHNlcnZlci4gIEFmdGVyIHNldHRpbmcgYW55CiAgICAgKiBvcHRpb25hbCBwYXJhbWV0ZXJzLCBjYWxsIHRoZSB7QGxpbmsgU2VhcmNoI2V4ZWN1dGUoKX0gbWV0aG9kIHRvIGludm9rZSB0aGUgcmVtb3RlIG9wZXJhdGlvbi4KICAgICAqCiAgICAgKiBAcGFyYW0gY29udGVudCB0aGUge0BsaW5rIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmNsb3VkcmVzb3VyY2VtYW5hZ2VyLm1vZGVsLlNlYXJjaE9yZ2FuaXphdGlvbnNSZXF1ZXN0fQogICAgICogQHJldHVybiB0aGUgcmVxdWVzdAogICAgICovCiAgICBwdWJsaWMgU2VhcmNoIHNlYXJjaChjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5jbG91ZHJlc291cmNlbWFuYWdlci5tb2RlbC5TZWFyY2hPcmdhbml6YXRpb25zUmVxdWVzdCBjb250ZW50KSB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIFNlYXJjaCByZXN1bHQgPSBuZXcgU2VhcmNoKGNvbnRlbnQpOwogICAgICBpbml0aWFsaXplKHJlc3VsdCk7CiAgICAgIHJldHVybiByZXN1bHQ7CiAgICB9CgogICAgcHVibGljIGNsYXNzIFNlYXJjaCBleHRlbmRzIENsb3VkUmVzb3VyY2VNYW5hZ2VyUmVxdWVzdDxjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5jbG91ZHJlc291cmNlbWFuYWdlci5tb2RlbC5TZWFyY2hPcmdhbml6YXRpb25zUmVzcG9uc2U+IHsKCiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBSRVNUX1BBVEggPSAidjEvb3JnYW5pemF0aW9uczpzZWFyY2giOwoKICAgICAgLyoqCiAgICAgICAqIFNlYXJjaGVzIE9yZ2FuaXphdGlvbiByZXNvdXJjZXMgdGhhdCBhcmUgdmlzaWJsZSB0byB0aGUgdXNlciBhbmQgc2F0aXNmeSB0aGUgc3BlY2lmaWVkIGZpbHRlci4KICAgICAgICogVGhpcyBtZXRob2QgcmV0dXJucyBPcmdhbml6YXRpb25zIGluIGFuIHVuc3BlY2lmaWVkIG9yZGVyLiBOZXcgT3JnYW5pemF0aW9ucyBkbyBub3QgbmVjZXNzYXJpbHkKICAgICAgICogYXBwZWFyIGF0IHRoZSBlbmQgb2YgdGhlIHJlc3VsdHMuCiAgICAgICAqCiAgICAgICAqIFNlYXJjaCB3aWxsIG9ubHkgcmV0dXJuIG9yZ2FuaXphdGlvbnMgb24gd2hpY2ggdGhlIHVzZXIgaGFzIHRoZSBwZXJtaXNzaW9uCiAgICAgICAqIGByZXNvdXJjZW1hbmFnZXIub3JnYW5pemF0aW9ucy5nZXRgCiAgICAgICAqCiAgICAgICAqIENyZWF0ZSBhIHJlcXVlc3QgZm9yIHRoZSBtZXRob2QgIm9yZ2FuaXphdGlvbnMuc2VhcmNoIi4KICAgICAgICoKICAgICAgICogVGhpcyByZXF1ZXN0IGhvbGRzIHRoZSBwYXJhbWV0ZXJzIG5lZWRlZCBieSB0aGUgdGhlIGNsb3VkcmVzb3VyY2VtYW5hZ2VyIHNlcnZlci4gIEFmdGVyIHNldHRpbmcKICAgICAgICogYW55IG9wdGlvbmFsIHBhcmFtZXRlcnMsIGNhbGwgdGhlIHtAbGluayBTZWFyY2gjZXhlY3V0ZSgpfSBtZXRob2QgdG8gaW52b2tlIHRoZSByZW1vdGUKICAgICAgICogb3BlcmF0aW9uLiA8cD4ge0BsaW5rCiAgICAgICAqIFNlYXJjaCNpbml0aWFsaXplKGNvbS5nb29nbGUuYXBpLmNsaWVudC5nb29nbGVhcGlzLnNlcnZpY2VzLkFic3RyYWN0R29vZ2xlQ2xpZW50UmVxdWVzdCl9IG11c3QKICAgICAgICogYmUgY2FsbGVkIHRvIGluaXRpYWxpemUgdGhpcyBpbnN0YW5jZSBpbW1lZGlhdGVseSBhZnRlciBpbnZva2luZyB0aGUgY29uc3RydWN0b3IuIDwvcD4KICAgICAgICoKICAgICAgICogQHBhcmFtIGNvbnRlbnQgdGhlIHtAbGluayBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5jbG91ZHJlc291cmNlbWFuYWdlci5tb2RlbC5TZWFyY2hPcmdhbml6YXRpb25zUmVxdWVzdH0KICAgICAgICogQHNpbmNlIDEuMTMKICAgICAgICovCiAgICAgIHByb3RlY3RlZCBTZWFyY2goY29tLmdvb2dsZS5hcGkuc2VydmljZXMuY2xvdWRyZXNvdXJjZW1hbmFnZXIubW9kZWwuU2VhcmNoT3JnYW5pemF0aW9uc1JlcXVlc3QgY29udGVudCkgewogICAgICAgIHN1cGVyKENsb3VkUmVzb3VyY2VNYW5hZ2VyLnRoaXMsICJQT1NUIiwgUkVTVF9QQVRILCBjb250ZW50LCBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5jbG91ZHJlc291cmNlbWFuYWdlci5tb2RlbC5TZWFyY2hPcmdhbml6YXRpb25zUmVzcG9uc2UuY2xhc3MpOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIFNlYXJjaCBzZXQkWGdhZnYoamF2YS5sYW5nLlN0cmluZyAkWGdhZnYpIHsKICAgICAgICByZXR1cm4gKFNlYXJjaCkgc3VwZXIuc2V0JFhnYWZ2KCRYZ2Fmdik7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgU2VhcmNoIHNldEFjY2Vzc1Rva2VuKGphdmEubGFuZy5TdHJpbmcgYWNjZXNzVG9rZW4pIHsKICAgICAgICByZXR1cm4gKFNlYXJjaCkgc3VwZXIuc2V0QWNjZXNzVG9rZW4oYWNjZXNzVG9rZW4pOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIFNlYXJjaCBzZXRBbHQoamF2YS5sYW5nLlN0cmluZyBhbHQpIHsKICAgICAgICByZXR1cm4gKFNlYXJjaCkgc3VwZXIuc2V0QWx0KGFsdCk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgU2VhcmNoIHNldENhbGxiYWNrKGphdmEubGFuZy5TdHJpbmcgY2FsbGJhY2spIHsKICAgICAgICByZXR1cm4gKFNlYXJjaCkgc3VwZXIuc2V0Q2FsbGJhY2soY2FsbGJhY2spOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIFNlYXJjaCBzZXRGaWVsZHMoamF2YS5sYW5nLlN0cmluZyBmaWVsZHMpIHsKICAgICAgICByZXR1cm4gKFNlYXJjaCkgc3VwZXIuc2V0RmllbGRzKGZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgU2VhcmNoIHNldEtleShqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIHJldHVybiAoU2VhcmNoKSBzdXBlci5zZXRLZXkoa2V5KTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBTZWFyY2ggc2V0T2F1dGhUb2tlbihqYXZhLmxhbmcuU3RyaW5nIG9hdXRoVG9rZW4pIHsKICAgICAgICByZXR1cm4gKFNlYXJjaCkgc3VwZXIuc2V0T2F1dGhUb2tlbihvYXV0aFRva2VuKTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBTZWFyY2ggc2V0UHJldHR5UHJpbnQoamF2YS5sYW5nLkJvb2xlYW4gcHJldHR5UHJpbnQpIHsKICAgICAgICByZXR1cm4gKFNlYXJjaCkgc3VwZXIuc2V0UHJldHR5UHJpbnQocHJldHR5UHJpbnQpOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIFNlYXJjaCBzZXRRdW90YVVzZXIoamF2YS5sYW5nLlN0cmluZyBxdW90YVVzZXIpIHsKICAgICAgICByZXR1cm4gKFNlYXJjaCkgc3VwZXIuc2V0UXVvdGFVc2VyKHF1b3RhVXNlcik7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgU2VhcmNoIHNldFVwbG9hZFR5cGUoamF2YS5sYW5nLlN0cmluZyB1cGxvYWRUeXBlKSB7CiAgICAgICAgcmV0dXJuIChTZWFyY2gpIHN1cGVyLnNldFVwbG9hZFR5cGUodXBsb2FkVHlwZSk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgU2VhcmNoIHNldFVwbG9hZFByb3RvY29sKGphdmEubGFuZy5TdHJpbmcgdXBsb2FkUHJvdG9jb2wpIHsKICAgICAgICByZXR1cm4gKFNlYXJjaCkgc3VwZXIuc2V0VXBsb2FkUHJvdG9jb2wodXBsb2FkUHJvdG9jb2wpOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIFNlYXJjaCBzZXQoU3RyaW5nIHBhcmFtZXRlck5hbWUsIE9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiAoU2VhcmNoKSBzdXBlci5zZXQocGFyYW1ldGVyTmFtZSwgdmFsdWUpOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIFNldHMgdGhlIGFjY2VzcyBjb250cm9sIHBvbGljeSBvbiBhbiBPcmdhbml6YXRpb24gcmVzb3VyY2UuIFJlcGxhY2VzIGFueSBleGlzdGluZyBwb2xpY3kuIFRoZQogICAgICogYHJlc291cmNlYCBmaWVsZCBzaG91bGQgYmUgdGhlIG9yZ2FuaXphdGlvbidzIHJlc291cmNlIG5hbWUsIGUuZy4gIm9yZ2FuaXphdGlvbnMvMTIzIi4KICAgICAqCiAgICAgKiBBdXRob3JpemF0aW9uIHJlcXVpcmVzIHRoZSBHb29nbGUgSUFNIHBlcm1pc3Npb24gYHJlc291cmNlbWFuYWdlci5vcmdhbml6YXRpb25zLnNldElhbVBvbGljeWAgb24KICAgICAqIHRoZSBzcGVjaWZpZWQgb3JnYW5pemF0aW9uCiAgICAgKgogICAgICogQ3JlYXRlIGEgcmVxdWVzdCBmb3IgdGhlIG1ldGhvZCAib3JnYW5pemF0aW9ucy5zZXRJYW1Qb2xpY3kiLgogICAgICoKICAgICAqIFRoaXMgcmVxdWVzdCBob2xkcyB0aGUgcGFyYW1ldGVycyBuZWVkZWQgYnkgdGhlIGNsb3VkcmVzb3VyY2VtYW5hZ2VyIHNlcnZlci4gIEFmdGVyIHNldHRpbmcgYW55CiAgICAgKiBvcHRpb25hbCBwYXJhbWV0ZXJzLCBjYWxsIHRoZSB7QGxpbmsgU2V0SWFtUG9saWN5I2V4ZWN1dGUoKX0gbWV0aG9kIHRvIGludm9rZSB0aGUgcmVtb3RlCiAgICAgKiBvcGVyYXRpb24uCiAgICAgKgogICAgICogQHBhcmFtIHJlc291cmNlIFJFUVVJUkVEOiBUaGUgcmVzb3VyY2UgZm9yIHdoaWNoIHRoZSBwb2xpY3kgaXMgYmVpbmcgc3BlY2lmaWVkLgogICAgU2VlIHRoZSBvcGVyYXRpb24gZG9jdW1lbnRhdGlvbiBmb3IKICAgICAqICAgICAgICB0aGUgYXBwcm9wcmlhdGUgdmFsdWUgZm9yIHRoaXMgZmllbGQuCiAgICAgKiBAcGFyYW0gY29udGVudCB0aGUge0BsaW5rIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmNsb3VkcmVzb3VyY2VtYW5hZ2VyLm1vZGVsLlNldElhbVBvbGljeVJlcXVlc3R9CiAgICAgKiBAcmV0dXJuIHRoZSByZXF1ZXN0CiAgICAgKi8KICAgIHB1YmxpYyBTZXRJYW1Qb2xpY3kgc2V0SWFtUG9saWN5KGphdmEubGFuZy5TdHJpbmcgcmVzb3VyY2UsIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmNsb3VkcmVzb3VyY2VtYW5hZ2VyLm1vZGVsLlNldElhbVBvbGljeVJlcXVlc3QgY29udGVudCkgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBTZXRJYW1Qb2xpY3kgcmVzdWx0ID0gbmV3IFNldElhbVBvbGljeShyZXNvdXJjZSwgY29udGVudCk7CiAgICAgIGluaXRpYWxpemUocmVzdWx0KTsKICAgICAgcmV0dXJuIHJlc3VsdDsKICAgIH0KCiAgICBwdWJsaWMgY2xhc3MgU2V0SWFtUG9saWN5IGV4dGVuZHMgQ2xvdWRSZXNvdXJjZU1hbmFnZXJSZXF1ZXN0PGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmNsb3VkcmVzb3VyY2VtYW5hZ2VyLm1vZGVsLlBvbGljeT4gewoKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFJFU1RfUEFUSCA9ICJ2MS97K3Jlc291cmNlfTpzZXRJYW1Qb2xpY3kiOwoKICAgICAgcHJpdmF0ZSBmaW5hbCBqYXZhLnV0aWwucmVnZXguUGF0dGVybiBSRVNPVVJDRV9QQVRURVJOID0KICAgICAgICAgIGphdmEudXRpbC5yZWdleC5QYXR0ZXJuLmNvbXBpbGUoIl5vcmdhbml6YXRpb25zL1teL10rJCIpOwoKICAgICAgLyoqCiAgICAgICAqIFNldHMgdGhlIGFjY2VzcyBjb250cm9sIHBvbGljeSBvbiBhbiBPcmdhbml6YXRpb24gcmVzb3VyY2UuIFJlcGxhY2VzIGFueSBleGlzdGluZyBwb2xpY3kuIFRoZQogICAgICAgKiBgcmVzb3VyY2VgIGZpZWxkIHNob3VsZCBiZSB0aGUgb3JnYW5pemF0aW9uJ3MgcmVzb3VyY2UgbmFtZSwgZS5nLiAib3JnYW5pemF0aW9ucy8xMjMiLgogICAgICAgKgogICAgICAgKiBBdXRob3JpemF0aW9uIHJlcXVpcmVzIHRoZSBHb29nbGUgSUFNIHBlcm1pc3Npb24gYHJlc291cmNlbWFuYWdlci5vcmdhbml6YXRpb25zLnNldElhbVBvbGljeWAKICAgICAgICogb24gdGhlIHNwZWNpZmllZCBvcmdhbml6YXRpb24KICAgICAgICoKICAgICAgICogQ3JlYXRlIGEgcmVxdWVzdCBmb3IgdGhlIG1ldGhvZCAib3JnYW5pemF0aW9ucy5zZXRJYW1Qb2xpY3kiLgogICAgICAgKgogICAgICAgKiBUaGlzIHJlcXVlc3QgaG9sZHMgdGhlIHBhcmFtZXRlcnMgbmVlZGVkIGJ5IHRoZSB0aGUgY2xvdWRyZXNvdXJjZW1hbmFnZXIgc2VydmVyLiAgQWZ0ZXIgc2V0dGluZwogICAgICAgKiBhbnkgb3B0aW9uYWwgcGFyYW1ldGVycywgY2FsbCB0aGUge0BsaW5rIFNldElhbVBvbGljeSNleGVjdXRlKCl9IG1ldGhvZCB0byBpbnZva2UgdGhlIHJlbW90ZQogICAgICAgKiBvcGVyYXRpb24uIDxwPiB7QGxpbmsKICAgICAgICogU2V0SWFtUG9saWN5I2luaXRpYWxpemUoY29tLmdvb2dsZS5hcGkuY2xpZW50Lmdvb2dsZWFwaXMuc2VydmljZXMuQWJzdHJhY3RHb29nbGVDbGllbnRSZXF1ZXN0KX0KICAgICAgICogbXVzdCBiZSBjYWxsZWQgdG8gaW5pdGlhbGl6ZSB0aGlzIGluc3RhbmNlIGltbWVkaWF0ZWx5IGFmdGVyIGludm9raW5nIHRoZSBjb25zdHJ1Y3Rvci4gPC9wPgogICAgICAgKgogICAgICAgKiBAcGFyYW0gcmVzb3VyY2UgUkVRVUlSRUQ6IFRoZSByZXNvdXJjZSBmb3Igd2hpY2ggdGhlIHBvbGljeSBpcyBiZWluZyBzcGVjaWZpZWQuCiAgICBTZWUgdGhlIG9wZXJhdGlvbiBkb2N1bWVudGF0aW9uIGZvcgogICAgICogICAgICAgIHRoZSBhcHByb3ByaWF0ZSB2YWx1ZSBmb3IgdGhpcyBmaWVsZC4KICAgICAgICogQHBhcmFtIGNvbnRlbnQgdGhlIHtAbGluayBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5jbG91ZHJlc291cmNlbWFuYWdlci5tb2RlbC5TZXRJYW1Qb2xpY3lSZXF1ZXN0fQogICAgICAgKiBAc2luY2UgMS4xMwogICAgICAgKi8KICAgICAgcHJvdGVjdGVkIFNldElhbVBvbGljeShqYXZhLmxhbmcuU3RyaW5nIHJlc291cmNlLCBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5jbG91ZHJlc291cmNlbWFuYWdlci5tb2RlbC5TZXRJYW1Qb2xpY3lSZXF1ZXN0IGNvbnRlbnQpIHsKICAgICAgICBzdXBlcihDbG91ZFJlc291cmNlTWFuYWdlci50aGlzLCAiUE9TVCIsIFJFU1RfUEFUSCwgY29udGVudCwgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuY2xvdWRyZXNvdXJjZW1hbmFnZXIubW9kZWwuUG9saWN5LmNsYXNzKTsKICAgICAgICB0aGlzLnJlc291cmNlID0gY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuUHJlY29uZGl0aW9ucy5jaGVja05vdE51bGwocmVzb3VyY2UsICJSZXF1aXJlZCBwYXJhbWV0ZXIgcmVzb3VyY2UgbXVzdCBiZSBzcGVjaWZpZWQuIik7CiAgICAgICAgaWYgKCFnZXRTdXBwcmVzc1BhdHRlcm5DaGVja3MoKSkgewogICAgICAgICAgY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuUHJlY29uZGl0aW9ucy5jaGVja0FyZ3VtZW50KFJFU09VUkNFX1BBVFRFUk4ubWF0Y2hlcihyZXNvdXJjZSkubWF0Y2hlcygpLAogICAgICAgICAgICAgICJQYXJhbWV0ZXIgcmVzb3VyY2UgbXVzdCBjb25mb3JtIHRvIHRoZSBwYXR0ZXJuICIgKwogICAgICAgICAgICAgICJeb3JnYW5pemF0aW9ucy9bXi9dKyQiKTsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgU2V0SWFtUG9saWN5IHNldCRYZ2FmdihqYXZhLmxhbmcuU3RyaW5nICRYZ2FmdikgewogICAgICAgIHJldHVybiAoU2V0SWFtUG9saWN5KSBzdXBlci5zZXQkWGdhZnYoJFhnYWZ2KTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBTZXRJYW1Qb2xpY3kgc2V0QWNjZXNzVG9rZW4oamF2YS5sYW5nLlN0cmluZyBhY2Nlc3NUb2tlbikgewogICAgICAgIHJldHVybiAoU2V0SWFtUG9saWN5KSBzdXBlci5zZXRBY2Nlc3NUb2tlbihhY2Nlc3NUb2tlbik7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgU2V0SWFtUG9saWN5IHNldEFsdChqYXZhLmxhbmcuU3RyaW5nIGFsdCkgewogICAgICAgIHJldHVybiAoU2V0SWFtUG9saWN5KSBzdXBlci5zZXRBbHQoYWx0KTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBTZXRJYW1Qb2xpY3kgc2V0Q2FsbGJhY2soamF2YS5sYW5nLlN0cmluZyBjYWxsYmFjaykgewogICAgICAgIHJldHVybiAoU2V0SWFtUG9saWN5KSBzdXBlci5zZXRDYWxsYmFjayhjYWxsYmFjayk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgU2V0SWFtUG9saWN5IHNldEZpZWxkcyhqYXZhLmxhbmcuU3RyaW5nIGZpZWxkcykgewogICAgICAgIHJldHVybiAoU2V0SWFtUG9saWN5KSBzdXBlci5zZXRGaWVsZHMoZmllbGRzKTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBTZXRJYW1Qb2xpY3kgc2V0S2V5KGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgcmV0dXJuIChTZXRJYW1Qb2xpY3kpIHN1cGVyLnNldEtleShrZXkpOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIFNldElhbVBvbGljeSBzZXRPYXV0aFRva2VuKGphdmEubGFuZy5TdHJpbmcgb2F1dGhUb2tlbikgewogICAgICAgIHJldHVybiAoU2V0SWFtUG9saWN5KSBzdXBlci5zZXRPYXV0aFRva2VuKG9hdXRoVG9rZW4pOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIFNldElhbVBvbGljeSBzZXRQcmV0dHlQcmludChqYXZhLmxhbmcuQm9vbGVhbiBwcmV0dHlQcmludCkgewogICAgICAgIHJldHVybiAoU2V0SWFtUG9saWN5KSBzdXBlci5zZXRQcmV0dHlQcmludChwcmV0dHlQcmludCk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgU2V0SWFtUG9saWN5IHNldFF1b3RhVXNlcihqYXZhLmxhbmcuU3RyaW5nIHF1b3RhVXNlcikgewogICAgICAgIHJldHVybiAoU2V0SWFtUG9saWN5KSBzdXBlci5zZXRRdW90YVVzZXIocXVvdGFVc2VyKTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBTZXRJYW1Qb2xpY3kgc2V0VXBsb2FkVHlwZShqYXZhLmxhbmcuU3RyaW5nIHVwbG9hZFR5cGUpIHsKICAgICAgICByZXR1cm4gKFNldElhbVBvbGljeSkgc3VwZXIuc2V0VXBsb2FkVHlwZSh1cGxvYWRUeXBlKTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBTZXRJYW1Qb2xpY3kgc2V0VXBsb2FkUHJvdG9jb2woamF2YS5sYW5nLlN0cmluZyB1cGxvYWRQcm90b2NvbCkgewogICAgICAgIHJldHVybiAoU2V0SWFtUG9saWN5KSBzdXBlci5zZXRVcGxvYWRQcm90b2NvbCh1cGxvYWRQcm90b2NvbCk7CiAgICAgIH0KCiAgICAgIC8qKgogICAgICAgKiBSRVFVSVJFRDogVGhlIHJlc291cmNlIGZvciB3aGljaCB0aGUgcG9saWN5IGlzIGJlaW5nIHNwZWNpZmllZC4gU2VlIHRoZSBvcGVyYXRpb24KICAgICAgICogZG9jdW1lbnRhdGlvbiBmb3IgdGhlIGFwcHJvcHJpYXRlIHZhbHVlIGZvciB0aGlzIGZpZWxkLgogICAgICAgKi8KICAgICAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogICAgICBwcml2YXRlIGphdmEubGFuZy5TdHJpbmcgcmVzb3VyY2U7CgogICAgICAvKiogUkVRVUlSRUQ6IFRoZSByZXNvdXJjZSBmb3Igd2hpY2ggdGhlIHBvbGljeSBpcyBiZWluZyBzcGVjaWZpZWQuIFNlZSB0aGUgb3BlcmF0aW9uIGRvY3VtZW50YXRpb24gZm9yCiAgICAgdGhlIGFwcHJvcHJpYXRlIHZhbHVlIGZvciB0aGlzIGZpZWxkLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0UmVzb3VyY2UoKSB7CiAgICAgICAgcmV0dXJuIHJlc291cmNlOwogICAgICB9CgogICAgICAvKioKICAgICAgICogUkVRVUlSRUQ6IFRoZSByZXNvdXJjZSBmb3Igd2hpY2ggdGhlIHBvbGljeSBpcyBiZWluZyBzcGVjaWZpZWQuIFNlZSB0aGUgb3BlcmF0aW9uCiAgICAgICAqIGRvY3VtZW50YXRpb24gZm9yIHRoZSBhcHByb3ByaWF0ZSB2YWx1ZSBmb3IgdGhpcyBmaWVsZC4KICAgICAgICovCiAgICAgIHB1YmxpYyBTZXRJYW1Qb2xpY3kgc2V0UmVzb3VyY2UoamF2YS5sYW5nLlN0cmluZyByZXNvdXJjZSkgewogICAgICAgIGlmICghZ2V0U3VwcHJlc3NQYXR0ZXJuQ2hlY2tzKCkpIHsKICAgICAgICAgIGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLlByZWNvbmRpdGlvbnMuY2hlY2tBcmd1bWVudChSRVNPVVJDRV9QQVRURVJOLm1hdGNoZXIocmVzb3VyY2UpLm1hdGNoZXMoKSwKICAgICAgICAgICAgICAiUGFyYW1ldGVyIHJlc291cmNlIG11c3QgY29uZm9ybSB0byB0aGUgcGF0dGVybiAiICsKICAgICAgICAgICAgICAiXm9yZ2FuaXphdGlvbnMvW14vXSskIik7CiAgICAgICAgfQogICAgICAgIHRoaXMucmVzb3VyY2UgPSByZXNvdXJjZTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBTZXRJYW1Qb2xpY3kgc2V0KFN0cmluZyBwYXJhbWV0ZXJOYW1lLCBPYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gKFNldElhbVBvbGljeSkgc3VwZXIuc2V0KHBhcmFtZXRlck5hbWUsIHZhbHVlKTsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiBVcGRhdGVzIHRoZSBzcGVjaWZpZWQgYFBvbGljeWAgb24gdGhlIHJlc291cmNlLiBDcmVhdGVzIGEgbmV3IGBQb2xpY3lgIGZvciB0aGF0IGBDb25zdHJhaW50YCBvbgogICAgICogdGhlIHJlc291cmNlIGlmIG9uZSBkb2VzIG5vdCBleGlzdC4KICAgICAqCiAgICAgKiBOb3Qgc3VwcGx5aW5nIGFuIGBldGFnYCBvbiB0aGUgcmVxdWVzdCBgUG9saWN5YCByZXN1bHRzIGluIGFuIHVuY29uZGl0aW9uYWwgd3JpdGUgb2YgdGhlCiAgICAgKiBgUG9saWN5YC4KICAgICAqCiAgICAgKiBDcmVhdGUgYSByZXF1ZXN0IGZvciB0aGUgbWV0aG9kICJvcmdhbml6YXRpb25zLnNldE9yZ1BvbGljeSIuCiAgICAgKgogICAgICogVGhpcyByZXF1ZXN0IGhvbGRzIHRoZSBwYXJhbWV0ZXJzIG5lZWRlZCBieSB0aGUgY2xvdWRyZXNvdXJjZW1hbmFnZXIgc2VydmVyLiAgQWZ0ZXIgc2V0dGluZyBhbnkKICAgICAqIG9wdGlvbmFsIHBhcmFtZXRlcnMsIGNhbGwgdGhlIHtAbGluayBTZXRPcmdQb2xpY3kjZXhlY3V0ZSgpfSBtZXRob2QgdG8gaW52b2tlIHRoZSByZW1vdGUKICAgICAqIG9wZXJhdGlvbi4KICAgICAqCiAgICAgKiBAcGFyYW0gcmVzb3VyY2UgUmVzb3VyY2UgbmFtZSBvZiB0aGUgcmVzb3VyY2UgdG8gYXR0YWNoIHRoZSBgUG9saWN5YC4KICAgICAqIEBwYXJhbSBjb250ZW50IHRoZSB7QGxpbmsgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuY2xvdWRyZXNvdXJjZW1hbmFnZXIubW9kZWwuU2V0T3JnUG9saWN5UmVxdWVzdH0KICAgICAqIEByZXR1cm4gdGhlIHJlcXVlc3QKICAgICAqLwogICAgcHVibGljIFNldE9yZ1BvbGljeSBzZXRPcmdQb2xpY3koamF2YS5sYW5nLlN0cmluZyByZXNvdXJjZSwgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuY2xvdWRyZXNvdXJjZW1hbmFnZXIubW9kZWwuU2V0T3JnUG9saWN5UmVxdWVzdCBjb250ZW50KSB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIFNldE9yZ1BvbGljeSByZXN1bHQgPSBuZXcgU2V0T3JnUG9saWN5KHJlc291cmNlLCBjb250ZW50KTsKICAgICAgaW5pdGlhbGl6ZShyZXN1bHQpOwogICAgICByZXR1cm4gcmVzdWx0OwogICAgfQoKICAgIHB1YmxpYyBjbGFzcyBTZXRPcmdQb2xpY3kgZXh0ZW5kcyBDbG91ZFJlc291cmNlTWFuYWdlclJlcXVlc3Q8Y29tLmdvb2dsZS5hcGkuc2VydmljZXMuY2xvdWRyZXNvdXJjZW1hbmFnZXIubW9kZWwuT3JnUG9saWN5PiB7CgogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgUkVTVF9QQVRIID0gInYxL3srcmVzb3VyY2V9OnNldE9yZ1BvbGljeSI7CgogICAgICBwcml2YXRlIGZpbmFsIGphdmEudXRpbC5yZWdleC5QYXR0ZXJuIFJFU09VUkNFX1BBVFRFUk4gPQogICAgICAgICAgamF2YS51dGlsLnJlZ2V4LlBhdHRlcm4uY29tcGlsZSgiXm9yZ2FuaXphdGlvbnMvW14vXSskIik7CgogICAgICAvKioKICAgICAgICogVXBkYXRlcyB0aGUgc3BlY2lmaWVkIGBQb2xpY3lgIG9uIHRoZSByZXNvdXJjZS4gQ3JlYXRlcyBhIG5ldyBgUG9saWN5YCBmb3IgdGhhdCBgQ29uc3RyYWludGAgb24KICAgICAgICogdGhlIHJlc291cmNlIGlmIG9uZSBkb2VzIG5vdCBleGlzdC4KICAgICAgICoKICAgICAgICogTm90IHN1cHBseWluZyBhbiBgZXRhZ2Agb24gdGhlIHJlcXVlc3QgYFBvbGljeWAgcmVzdWx0cyBpbiBhbiB1bmNvbmRpdGlvbmFsIHdyaXRlIG9mIHRoZQogICAgICAgKiBgUG9saWN5YC4KICAgICAgICoKICAgICAgICogQ3JlYXRlIGEgcmVxdWVzdCBmb3IgdGhlIG1ldGhvZCAib3JnYW5pemF0aW9ucy5zZXRPcmdQb2xpY3kiLgogICAgICAgKgogICAgICAgKiBUaGlzIHJlcXVlc3QgaG9sZHMgdGhlIHBhcmFtZXRlcnMgbmVlZGVkIGJ5IHRoZSB0aGUgY2xvdWRyZXNvdXJjZW1hbmFnZXIgc2VydmVyLiAgQWZ0ZXIgc2V0dGluZwogICAgICAgKiBhbnkgb3B0aW9uYWwgcGFyYW1ldGVycywgY2FsbCB0aGUge0BsaW5rIFNldE9yZ1BvbGljeSNleGVjdXRlKCl9IG1ldGhvZCB0byBpbnZva2UgdGhlIHJlbW90ZQogICAgICAgKiBvcGVyYXRpb24uIDxwPiB7QGxpbmsKICAgICAgICogU2V0T3JnUG9saWN5I2luaXRpYWxpemUoY29tLmdvb2dsZS5hcGkuY2xpZW50Lmdvb2dsZWFwaXMuc2VydmljZXMuQWJzdHJhY3RHb29nbGVDbGllbnRSZXF1ZXN0KX0KICAgICAgICogbXVzdCBiZSBjYWxsZWQgdG8gaW5pdGlhbGl6ZSB0aGlzIGluc3RhbmNlIGltbWVkaWF0ZWx5IGFmdGVyIGludm9raW5nIHRoZSBjb25zdHJ1Y3Rvci4gPC9wPgogICAgICAgKgogICAgICAgKiBAcGFyYW0gcmVzb3VyY2UgUmVzb3VyY2UgbmFtZSBvZiB0aGUgcmVzb3VyY2UgdG8gYXR0YWNoIHRoZSBgUG9saWN5YC4KICAgICAgICogQHBhcmFtIGNvbnRlbnQgdGhlIHtAbGluayBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5jbG91ZHJlc291cmNlbWFuYWdlci5tb2RlbC5TZXRPcmdQb2xpY3lSZXF1ZXN0fQogICAgICAgKiBAc2luY2UgMS4xMwogICAgICAgKi8KICAgICAgcHJvdGVjdGVkIFNldE9yZ1BvbGljeShqYXZhLmxhbmcuU3RyaW5nIHJlc291cmNlLCBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5jbG91ZHJlc291cmNlbWFuYWdlci5tb2RlbC5TZXRPcmdQb2xpY3lSZXF1ZXN0IGNvbnRlbnQpIHsKICAgICAgICBzdXBlcihDbG91ZFJlc291cmNlTWFuYWdlci50aGlzLCAiUE9TVCIsIFJFU1RfUEFUSCwgY29udGVudCwgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuY2xvdWRyZXNvdXJjZW1hbmFnZXIubW9kZWwuT3JnUG9saWN5LmNsYXNzKTsKICAgICAgICB0aGlzLnJlc291cmNlID0gY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuUHJlY29uZGl0aW9ucy5jaGVja05vdE51bGwocmVzb3VyY2UsICJSZXF1aXJlZCBwYXJhbWV0ZXIgcmVzb3VyY2UgbXVzdCBiZSBzcGVjaWZpZWQuIik7CiAgICAgICAgaWYgKCFnZXRTdXBwcmVzc1BhdHRlcm5DaGVja3MoKSkgewogICAgICAgICAgY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuUHJlY29uZGl0aW9ucy5jaGVja0FyZ3VtZW50KFJFU09VUkNFX1BBVFRFUk4ubWF0Y2hlcihyZXNvdXJjZSkubWF0Y2hlcygpLAogICAgICAgICAgICAgICJQYXJhbWV0ZXIgcmVzb3VyY2UgbXVzdCBjb25mb3JtIHRvIHRoZSBwYXR0ZXJuICIgKwogICAgICAgICAgICAgICJeb3JnYW5pemF0aW9ucy9bXi9dKyQiKTsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgU2V0T3JnUG9saWN5IHNldCRYZ2FmdihqYXZhLmxhbmcuU3RyaW5nICRYZ2FmdikgewogICAgICAgIHJldHVybiAoU2V0T3JnUG9saWN5KSBzdXBlci5zZXQkWGdhZnYoJFhnYWZ2KTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBTZXRPcmdQb2xpY3kgc2V0QWNjZXNzVG9rZW4oamF2YS5sYW5nLlN0cmluZyBhY2Nlc3NUb2tlbikgewogICAgICAgIHJldHVybiAoU2V0T3JnUG9saWN5KSBzdXBlci5zZXRBY2Nlc3NUb2tlbihhY2Nlc3NUb2tlbik7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgU2V0T3JnUG9saWN5IHNldEFsdChqYXZhLmxhbmcuU3RyaW5nIGFsdCkgewogICAgICAgIHJldHVybiAoU2V0T3JnUG9saWN5KSBzdXBlci5zZXRBbHQoYWx0KTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBTZXRPcmdQb2xpY3kgc2V0Q2FsbGJhY2soamF2YS5sYW5nLlN0cmluZyBjYWxsYmFjaykgewogICAgICAgIHJldHVybiAoU2V0T3JnUG9saWN5KSBzdXBlci5zZXRDYWxsYmFjayhjYWxsYmFjayk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgU2V0T3JnUG9saWN5IHNldEZpZWxkcyhqYXZhLmxhbmcuU3RyaW5nIGZpZWxkcykgewogICAgICAgIHJldHVybiAoU2V0T3JnUG9saWN5KSBzdXBlci5zZXRGaWVsZHMoZmllbGRzKTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBTZXRPcmdQb2xpY3kgc2V0S2V5KGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgcmV0dXJuIChTZXRPcmdQb2xpY3kpIHN1cGVyLnNldEtleShrZXkpOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIFNldE9yZ1BvbGljeSBzZXRPYXV0aFRva2VuKGphdmEubGFuZy5TdHJpbmcgb2F1dGhUb2tlbikgewogICAgICAgIHJldHVybiAoU2V0T3JnUG9saWN5KSBzdXBlci5zZXRPYXV0aFRva2VuKG9hdXRoVG9rZW4pOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIFNldE9yZ1BvbGljeSBzZXRQcmV0dHlQcmludChqYXZhLmxhbmcuQm9vbGVhbiBwcmV0dHlQcmludCkgewogICAgICAgIHJldHVybiAoU2V0T3JnUG9saWN5KSBzdXBlci5zZXRQcmV0dHlQcmludChwcmV0dHlQcmludCk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgU2V0T3JnUG9saWN5IHNldFF1b3RhVXNlcihqYXZhLmxhbmcuU3RyaW5nIHF1b3RhVXNlcikgewogICAgICAgIHJldHVybiAoU2V0T3JnUG9saWN5KSBzdXBlci5zZXRRdW90YVVzZXIocXVvdGFVc2VyKTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBTZXRPcmdQb2xpY3kgc2V0VXBsb2FkVHlwZShqYXZhLmxhbmcuU3RyaW5nIHVwbG9hZFR5cGUpIHsKICAgICAgICByZXR1cm4gKFNldE9yZ1BvbGljeSkgc3VwZXIuc2V0VXBsb2FkVHlwZSh1cGxvYWRUeXBlKTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBTZXRPcmdQb2xpY3kgc2V0VXBsb2FkUHJvdG9jb2woamF2YS5sYW5nLlN0cmluZyB1cGxvYWRQcm90b2NvbCkgewogICAgICAgIHJldHVybiAoU2V0T3JnUG9saWN5KSBzdXBlci5zZXRVcGxvYWRQcm90b2NvbCh1cGxvYWRQcm90b2NvbCk7CiAgICAgIH0KCiAgICAgIC8qKiBSZXNvdXJjZSBuYW1lIG9mIHRoZSByZXNvdXJjZSB0byBhdHRhY2ggdGhlIGBQb2xpY3lgLiAqLwogICAgICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgICAgIHByaXZhdGUgamF2YS5sYW5nLlN0cmluZyByZXNvdXJjZTsKCiAgICAgIC8qKiBSZXNvdXJjZSBuYW1lIG9mIHRoZSByZXNvdXJjZSB0byBhdHRhY2ggdGhlIGBQb2xpY3lgLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0UmVzb3VyY2UoKSB7CiAgICAgICAgcmV0dXJuIHJlc291cmNlOwogICAgICB9CgogICAgICAvKiogUmVzb3VyY2UgbmFtZSBvZiB0aGUgcmVzb3VyY2UgdG8gYXR0YWNoIHRoZSBgUG9saWN5YC4gKi8KICAgICAgcHVibGljIFNldE9yZ1BvbGljeSBzZXRSZXNvdXJjZShqYXZhLmxhbmcuU3RyaW5nIHJlc291cmNlKSB7CiAgICAgICAgaWYgKCFnZXRTdXBwcmVzc1BhdHRlcm5DaGVja3MoKSkgewogICAgICAgICAgY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuUHJlY29uZGl0aW9ucy5jaGVja0FyZ3VtZW50KFJFU09VUkNFX1BBVFRFUk4ubWF0Y2hlcihyZXNvdXJjZSkubWF0Y2hlcygpLAogICAgICAgICAgICAgICJQYXJhbWV0ZXIgcmVzb3VyY2UgbXVzdCBjb25mb3JtIHRvIHRoZSBwYXR0ZXJuICIgKwogICAgICAgICAgICAgICJeb3JnYW5pemF0aW9ucy9bXi9dKyQiKTsKICAgICAgICB9CiAgICAgICAgdGhpcy5yZXNvdXJjZSA9IHJlc291cmNlOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIFNldE9yZ1BvbGljeSBzZXQoU3RyaW5nIHBhcmFtZXRlck5hbWUsIE9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiAoU2V0T3JnUG9saWN5KSBzdXBlci5zZXQocGFyYW1ldGVyTmFtZSwgdmFsdWUpOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIFJldHVybnMgcGVybWlzc2lvbnMgdGhhdCBhIGNhbGxlciBoYXMgb24gdGhlIHNwZWNpZmllZCBPcmdhbml6YXRpb24uIFRoZSBgcmVzb3VyY2VgIGZpZWxkIHNob3VsZAogICAgICogYmUgdGhlIG9yZ2FuaXphdGlvbidzIHJlc291cmNlIG5hbWUsIGUuZy4gIm9yZ2FuaXphdGlvbnMvMTIzIi4KICAgICAqCiAgICAgKiBUaGVyZSBhcmUgbm8gcGVybWlzc2lvbnMgcmVxdWlyZWQgZm9yIG1ha2luZyB0aGlzIEFQSSBjYWxsLgogICAgICoKICAgICAqIENyZWF0ZSBhIHJlcXVlc3QgZm9yIHRoZSBtZXRob2QgIm9yZ2FuaXphdGlvbnMudGVzdElhbVBlcm1pc3Npb25zIi4KICAgICAqCiAgICAgKiBUaGlzIHJlcXVlc3QgaG9sZHMgdGhlIHBhcmFtZXRlcnMgbmVlZGVkIGJ5IHRoZSBjbG91ZHJlc291cmNlbWFuYWdlciBzZXJ2ZXIuICBBZnRlciBzZXR0aW5nIGFueQogICAgICogb3B0aW9uYWwgcGFyYW1ldGVycywgY2FsbCB0aGUge0BsaW5rIFRlc3RJYW1QZXJtaXNzaW9ucyNleGVjdXRlKCl9IG1ldGhvZCB0byBpbnZva2UgdGhlIHJlbW90ZQogICAgICogb3BlcmF0aW9uLgogICAgICoKICAgICAqIEBwYXJhbSByZXNvdXJjZSBSRVFVSVJFRDogVGhlIHJlc291cmNlIGZvciB3aGljaCB0aGUgcG9saWN5IGRldGFpbCBpcyBiZWluZyByZXF1ZXN0ZWQuCiAgICBTZWUgdGhlIG9wZXJhdGlvbgogICAgICogICAgICAgIGRvY3VtZW50YXRpb24gZm9yIHRoZSBhcHByb3ByaWF0ZSB2YWx1ZSBmb3IgdGhpcyBmaWVsZC4KICAgICAqIEBwYXJhbSBjb250ZW50IHRoZSB7QGxpbmsgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuY2xvdWRyZXNvdXJjZW1hbmFnZXIubW9kZWwuVGVzdElhbVBlcm1pc3Npb25zUmVxdWVzdH0KICAgICAqIEByZXR1cm4gdGhlIHJlcXVlc3QKICAgICAqLwogICAgcHVibGljIFRlc3RJYW1QZXJtaXNzaW9ucyB0ZXN0SWFtUGVybWlzc2lvbnMoamF2YS5sYW5nLlN0cmluZyByZXNvdXJjZSwgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuY2xvdWRyZXNvdXJjZW1hbmFnZXIubW9kZWwuVGVzdElhbVBlcm1pc3Npb25zUmVxdWVzdCBjb250ZW50KSB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIFRlc3RJYW1QZXJtaXNzaW9ucyByZXN1bHQgPSBuZXcgVGVzdElhbVBlcm1pc3Npb25zKHJlc291cmNlLCBjb250ZW50KTsKICAgICAgaW5pdGlhbGl6ZShyZXN1bHQpOwogICAgICByZXR1cm4gcmVzdWx0OwogICAgfQoKICAgIHB1YmxpYyBjbGFzcyBUZXN0SWFtUGVybWlzc2lvbnMgZXh0ZW5kcyBDbG91ZFJlc291cmNlTWFuYWdlclJlcXVlc3Q8Y29tLmdvb2dsZS5hcGkuc2VydmljZXMuY2xvdWRyZXNvdXJjZW1hbmFnZXIubW9kZWwuVGVzdElhbVBlcm1pc3Npb25zUmVzcG9uc2U+IHsKCiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBSRVNUX1BBVEggPSAidjEveytyZXNvdXJjZX06dGVzdElhbVBlcm1pc3Npb25zIjsKCiAgICAgIHByaXZhdGUgZmluYWwgamF2YS51dGlsLnJlZ2V4LlBhdHRlcm4gUkVTT1VSQ0VfUEFUVEVSTiA9CiAgICAgICAgICBqYXZhLnV0aWwucmVnZXguUGF0dGVybi5jb21waWxlKCJeb3JnYW5pemF0aW9ucy9bXi9dKyQiKTsKCiAgICAgIC8qKgogICAgICAgKiBSZXR1cm5zIHBlcm1pc3Npb25zIHRoYXQgYSBjYWxsZXIgaGFzIG9uIHRoZSBzcGVjaWZpZWQgT3JnYW5pemF0aW9uLiBUaGUgYHJlc291cmNlYCBmaWVsZAogICAgICAgKiBzaG91bGQgYmUgdGhlIG9yZ2FuaXphdGlvbidzIHJlc291cmNlIG5hbWUsIGUuZy4gIm9yZ2FuaXphdGlvbnMvMTIzIi4KICAgICAgICoKICAgICAgICogVGhlcmUgYXJlIG5vIHBlcm1pc3Npb25zIHJlcXVpcmVkIGZvciBtYWtpbmcgdGhpcyBBUEkgY2FsbC4KICAgICAgICoKICAgICAgICogQ3JlYXRlIGEgcmVxdWVzdCBmb3IgdGhlIG1ldGhvZCAib3JnYW5pemF0aW9ucy50ZXN0SWFtUGVybWlzc2lvbnMiLgogICAgICAgKgogICAgICAgKiBUaGlzIHJlcXVlc3QgaG9sZHMgdGhlIHBhcmFtZXRlcnMgbmVlZGVkIGJ5IHRoZSB0aGUgY2xvdWRyZXNvdXJjZW1hbmFnZXIgc2VydmVyLiAgQWZ0ZXIgc2V0dGluZwogICAgICAgKiBhbnkgb3B0aW9uYWwgcGFyYW1ldGVycywgY2FsbCB0aGUge0BsaW5rIFRlc3RJYW1QZXJtaXNzaW9ucyNleGVjdXRlKCl9IG1ldGhvZCB0byBpbnZva2UgdGhlCiAgICAgICAqIHJlbW90ZSBvcGVyYXRpb24uIDxwPiB7QGxpbmsgVGVzdElhbVBlcm1pc3Npb25zI2luaXRpYWxpemUoY29tLmdvb2dsZS5hcGkuY2xpZW50Lmdvb2dsZWFwaXMuc2VyCiAgICAgICAqIHZpY2VzLkFic3RyYWN0R29vZ2xlQ2xpZW50UmVxdWVzdCl9IG11c3QgYmUgY2FsbGVkIHRvIGluaXRpYWxpemUgdGhpcyBpbnN0YW5jZSBpbW1lZGlhdGVseQogICAgICAgKiBhZnRlciBpbnZva2luZyB0aGUgY29uc3RydWN0b3IuIDwvcD4KICAgICAgICoKICAgICAgICogQHBhcmFtIHJlc291cmNlIFJFUVVJUkVEOiBUaGUgcmVzb3VyY2UgZm9yIHdoaWNoIHRoZSBwb2xpY3kgZGV0YWlsIGlzIGJlaW5nIHJlcXVlc3RlZC4KICAgIFNlZSB0aGUgb3BlcmF0aW9uCiAgICAgKiAgICAgICAgZG9jdW1lbnRhdGlvbiBmb3IgdGhlIGFwcHJvcHJpYXRlIHZhbHVlIGZvciB0aGlzIGZpZWxkLgogICAgICAgKiBAcGFyYW0gY29udGVudCB0aGUge0BsaW5rIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmNsb3VkcmVzb3VyY2VtYW5hZ2VyLm1vZGVsLlRlc3RJYW1QZXJtaXNzaW9uc1JlcXVlc3R9CiAgICAgICAqIEBzaW5jZSAxLjEzCiAgICAgICAqLwogICAgICBwcm90ZWN0ZWQgVGVzdElhbVBlcm1pc3Npb25zKGphdmEubGFuZy5TdHJpbmcgcmVzb3VyY2UsIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmNsb3VkcmVzb3VyY2VtYW5hZ2VyLm1vZGVsLlRlc3RJYW1QZXJtaXNzaW9uc1JlcXVlc3QgY29udGVudCkgewogICAgICAgIHN1cGVyKENsb3VkUmVzb3VyY2VNYW5hZ2VyLnRoaXMsICJQT1NUIiwgUkVTVF9QQVRILCBjb250ZW50LCBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5jbG91ZHJlc291cmNlbWFuYWdlci5tb2RlbC5UZXN0SWFtUGVybWlzc2lvbnNSZXNwb25zZS5jbGFzcyk7CiAgICAgICAgdGhpcy5yZXNvdXJjZSA9IGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLlByZWNvbmRpdGlvbnMuY2hlY2tOb3ROdWxsKHJlc291cmNlLCAiUmVxdWlyZWQgcGFyYW1ldGVyIHJlc291cmNlIG11c3QgYmUgc3BlY2lmaWVkLiIpOwogICAgICAgIGlmICghZ2V0U3VwcHJlc3NQYXR0ZXJuQ2hlY2tzKCkpIHsKICAgICAgICAgIGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLlByZWNvbmRpdGlvbnMuY2hlY2tBcmd1bWVudChSRVNPVVJDRV9QQVRURVJOLm1hdGNoZXIocmVzb3VyY2UpLm1hdGNoZXMoKSwKICAgICAgICAgICAgICAiUGFyYW1ldGVyIHJlc291cmNlIG11c3QgY29uZm9ybSB0byB0aGUgcGF0dGVybiAiICsKICAgICAgICAgICAgICAiXm9yZ2FuaXphdGlvbnMvW14vXSskIik7CiAgICAgICAgfQogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIFRlc3RJYW1QZXJtaXNzaW9ucyBzZXQkWGdhZnYoamF2YS5sYW5nLlN0cmluZyAkWGdhZnYpIHsKICAgICAgICByZXR1cm4gKFRlc3RJYW1QZXJtaXNzaW9ucykgc3VwZXIuc2V0JFhnYWZ2KCRYZ2Fmdik7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgVGVzdElhbVBlcm1pc3Npb25zIHNldEFjY2Vzc1Rva2VuKGphdmEubGFuZy5TdHJpbmcgYWNjZXNzVG9rZW4pIHsKICAgICAgICByZXR1cm4gKFRlc3RJYW1QZXJtaXNzaW9ucykgc3VwZXIuc2V0QWNjZXNzVG9rZW4oYWNjZXNzVG9rZW4pOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIFRlc3RJYW1QZXJtaXNzaW9ucyBzZXRBbHQoamF2YS5sYW5nLlN0cmluZyBhbHQpIHsKICAgICAgICByZXR1cm4gKFRlc3RJYW1QZXJtaXNzaW9ucykgc3VwZXIuc2V0QWx0KGFsdCk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgVGVzdElhbVBlcm1pc3Npb25zIHNldENhbGxiYWNrKGphdmEubGFuZy5TdHJpbmcgY2FsbGJhY2spIHsKICAgICAgICByZXR1cm4gKFRlc3RJYW1QZXJtaXNzaW9ucykgc3VwZXIuc2V0Q2FsbGJhY2soY2FsbGJhY2spOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIFRlc3RJYW1QZXJtaXNzaW9ucyBzZXRGaWVsZHMoamF2YS5sYW5nLlN0cmluZyBmaWVsZHMpIHsKICAgICAgICByZXR1cm4gKFRlc3RJYW1QZXJtaXNzaW9ucykgc3VwZXIuc2V0RmllbGRzKGZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgVGVzdElhbVBlcm1pc3Npb25zIHNldEtleShqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIHJldHVybiAoVGVzdElhbVBlcm1pc3Npb25zKSBzdXBlci5zZXRLZXkoa2V5KTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBUZXN0SWFtUGVybWlzc2lvbnMgc2V0T2F1dGhUb2tlbihqYXZhLmxhbmcuU3RyaW5nIG9hdXRoVG9rZW4pIHsKICAgICAgICByZXR1cm4gKFRlc3RJYW1QZXJtaXNzaW9ucykgc3VwZXIuc2V0T2F1dGhUb2tlbihvYXV0aFRva2VuKTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBUZXN0SWFtUGVybWlzc2lvbnMgc2V0UHJldHR5UHJpbnQoamF2YS5sYW5nLkJvb2xlYW4gcHJldHR5UHJpbnQpIHsKICAgICAgICByZXR1cm4gKFRlc3RJYW1QZXJtaXNzaW9ucykgc3VwZXIuc2V0UHJldHR5UHJpbnQocHJldHR5UHJpbnQpOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIFRlc3RJYW1QZXJtaXNzaW9ucyBzZXRRdW90YVVzZXIoamF2YS5sYW5nLlN0cmluZyBxdW90YVVzZXIpIHsKICAgICAgICByZXR1cm4gKFRlc3RJYW1QZXJtaXNzaW9ucykgc3VwZXIuc2V0UXVvdGFVc2VyKHF1b3RhVXNlcik7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgVGVzdElhbVBlcm1pc3Npb25zIHNldFVwbG9hZFR5cGUoamF2YS5sYW5nLlN0cmluZyB1cGxvYWRUeXBlKSB7CiAgICAgICAgcmV0dXJuIChUZXN0SWFtUGVybWlzc2lvbnMpIHN1cGVyLnNldFVwbG9hZFR5cGUodXBsb2FkVHlwZSk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgVGVzdElhbVBlcm1pc3Npb25zIHNldFVwbG9hZFByb3RvY29sKGphdmEubGFuZy5TdHJpbmcgdXBsb2FkUHJvdG9jb2wpIHsKICAgICAgICByZXR1cm4gKFRlc3RJYW1QZXJtaXNzaW9ucykgc3VwZXIuc2V0VXBsb2FkUHJvdG9jb2wodXBsb2FkUHJvdG9jb2wpOwogICAgICB9CgogICAgICAvKioKICAgICAgICogUkVRVUlSRUQ6IFRoZSByZXNvdXJjZSBmb3Igd2hpY2ggdGhlIHBvbGljeSBkZXRhaWwgaXMgYmVpbmcgcmVxdWVzdGVkLiBTZWUgdGhlIG9wZXJhdGlvbgogICAgICAgKiBkb2N1bWVudGF0aW9uIGZvciB0aGUgYXBwcm9wcmlhdGUgdmFsdWUgZm9yIHRoaXMgZmllbGQuCiAgICAgICAqLwogICAgICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgICAgIHByaXZhdGUgamF2YS5sYW5nLlN0cmluZyByZXNvdXJjZTsKCiAgICAgIC8qKiBSRVFVSVJFRDogVGhlIHJlc291cmNlIGZvciB3aGljaCB0aGUgcG9saWN5IGRldGFpbCBpcyBiZWluZyByZXF1ZXN0ZWQuIFNlZSB0aGUgb3BlcmF0aW9uCiAgICAgZG9jdW1lbnRhdGlvbiBmb3IgdGhlIGFwcHJvcHJpYXRlIHZhbHVlIGZvciB0aGlzIGZpZWxkLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0UmVzb3VyY2UoKSB7CiAgICAgICAgcmV0dXJuIHJlc291cmNlOwogICAgICB9CgogICAgICAvKioKICAgICAgICogUkVRVUlSRUQ6IFRoZSByZXNvdXJjZSBmb3Igd2hpY2ggdGhlIHBvbGljeSBkZXRhaWwgaXMgYmVpbmcgcmVxdWVzdGVkLiBTZWUgdGhlIG9wZXJhdGlvbgogICAgICAgKiBkb2N1bWVudGF0aW9uIGZvciB0aGUgYXBwcm9wcmlhdGUgdmFsdWUgZm9yIHRoaXMgZmllbGQuCiAgICAgICAqLwogICAgICBwdWJsaWMgVGVzdElhbVBlcm1pc3Npb25zIHNldFJlc291cmNlKGphdmEubGFuZy5TdHJpbmcgcmVzb3VyY2UpIHsKICAgICAgICBpZiAoIWdldFN1cHByZXNzUGF0dGVybkNoZWNrcygpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5QcmVjb25kaXRpb25zLmNoZWNrQXJndW1lbnQoUkVTT1VSQ0VfUEFUVEVSTi5tYXRjaGVyKHJlc291cmNlKS5tYXRjaGVzKCksCiAgICAgICAgICAgICAgIlBhcmFtZXRlciByZXNvdXJjZSBtdXN0IGNvbmZvcm0gdG8gdGhlIHBhdHRlcm4gIiArCiAgICAgICAgICAgICAgIl5vcmdhbml6YXRpb25zL1teL10rJCIpOwogICAgICAgIH0KICAgICAgICB0aGlzLnJlc291cmNlID0gcmVzb3VyY2U7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgVGVzdElhbVBlcm1pc3Npb25zIHNldChTdHJpbmcgcGFyYW1ldGVyTmFtZSwgT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIChUZXN0SWFtUGVybWlzc2lvbnMpIHN1cGVyLnNldChwYXJhbWV0ZXJOYW1lLCB2YWx1ZSk7CiAgICAgIH0KICAgIH0KCiAgfQoKICAvKioKICAgKiBBbiBhY2Nlc3NvciBmb3IgY3JlYXRpbmcgcmVxdWVzdHMgZnJvbSB0aGUgUHJvamVjdHMgY29sbGVjdGlvbi4KICAgKgogICAqIDxwPlRoZSB0eXBpY2FsIHVzZSBpczo8L3A+CiAgICogPHByZT4KICAgKiAgIHtAY29kZSBDbG91ZFJlc291cmNlTWFuYWdlciBjbG91ZHJlc291cmNlbWFuYWdlciA9IG5ldyBDbG91ZFJlc291cmNlTWFuYWdlciguLi4pO30KICAgKiAgIHtAY29kZSBDbG91ZFJlc291cmNlTWFuYWdlci5Qcm9qZWN0cy5MaXN0IHJlcXVlc3QgPSBjbG91ZHJlc291cmNlbWFuYWdlci5wcm9qZWN0cygpLmxpc3QocGFyYW1ldGVycyAuLi4pfQogICAqIDwvcHJlPgogICAqCiAgICogQHJldHVybiB0aGUgcmVzb3VyY2UgY29sbGVjdGlvbgogICAqLwogIHB1YmxpYyBQcm9qZWN0cyBwcm9qZWN0cygpIHsKICAgIHJldHVybiBuZXcgUHJvamVjdHMoKTsKICB9CgogIC8qKgogICAqIFRoZSAicHJvamVjdHMiIGNvbGxlY3Rpb24gb2YgbWV0aG9kcy4KICAgKi8KICBwdWJsaWMgY2xhc3MgUHJvamVjdHMgewoKICAgIC8qKgogICAgICogQ2xlYXJzIGEgYFBvbGljeWAgZnJvbSBhIHJlc291cmNlLgogICAgICoKICAgICAqIENyZWF0ZSBhIHJlcXVlc3QgZm9yIHRoZSBtZXRob2QgInByb2plY3RzLmNsZWFyT3JnUG9saWN5Ii4KICAgICAqCiAgICAgKiBUaGlzIHJlcXVlc3QgaG9sZHMgdGhlIHBhcmFtZXRlcnMgbmVlZGVkIGJ5IHRoZSBjbG91ZHJlc291cmNlbWFuYWdlciBzZXJ2ZXIuICBBZnRlciBzZXR0aW5nIGFueQogICAgICogb3B0aW9uYWwgcGFyYW1ldGVycywgY2FsbCB0aGUge0BsaW5rIENsZWFyT3JnUG9saWN5I2V4ZWN1dGUoKX0gbWV0aG9kIHRvIGludm9rZSB0aGUgcmVtb3RlCiAgICAgKiBvcGVyYXRpb24uCiAgICAgKgogICAgICogQHBhcmFtIHJlc291cmNlIE5hbWUgb2YgdGhlIHJlc291cmNlIGZvciB0aGUgYFBvbGljeWAgdG8gY2xlYXIuCiAgICAgKiBAcGFyYW0gY29udGVudCB0aGUge0BsaW5rIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmNsb3VkcmVzb3VyY2VtYW5hZ2VyLm1vZGVsLkNsZWFyT3JnUG9saWN5UmVxdWVzdH0KICAgICAqIEByZXR1cm4gdGhlIHJlcXVlc3QKICAgICAqLwogICAgcHVibGljIENsZWFyT3JnUG9saWN5IGNsZWFyT3JnUG9saWN5KGphdmEubGFuZy5TdHJpbmcgcmVzb3VyY2UsIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmNsb3VkcmVzb3VyY2VtYW5hZ2VyLm1vZGVsLkNsZWFyT3JnUG9saWN5UmVxdWVzdCBjb250ZW50KSB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIENsZWFyT3JnUG9saWN5IHJlc3VsdCA9IG5ldyBDbGVhck9yZ1BvbGljeShyZXNvdXJjZSwgY29udGVudCk7CiAgICAgIGluaXRpYWxpemUocmVzdWx0KTsKICAgICAgcmV0dXJuIHJlc3VsdDsKICAgIH0KCiAgICBwdWJsaWMgY2xhc3MgQ2xlYXJPcmdQb2xpY3kgZXh0ZW5kcyBDbG91ZFJlc291cmNlTWFuYWdlclJlcXVlc3Q8Y29tLmdvb2dsZS5hcGkuc2VydmljZXMuY2xvdWRyZXNvdXJjZW1hbmFnZXIubW9kZWwuRW1wdHk+IHsKCiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBSRVNUX1BBVEggPSAidjEveytyZXNvdXJjZX06Y2xlYXJPcmdQb2xpY3kiOwoKICAgICAgcHJpdmF0ZSBmaW5hbCBqYXZhLnV0aWwucmVnZXguUGF0dGVybiBSRVNPVVJDRV9QQVRURVJOID0KICAgICAgICAgIGphdmEudXRpbC5yZWdleC5QYXR0ZXJuLmNvbXBpbGUoIl5wcm9qZWN0cy9bXi9dKyQiKTsKCiAgICAgIC8qKgogICAgICAgKiBDbGVhcnMgYSBgUG9saWN5YCBmcm9tIGEgcmVzb3VyY2UuCiAgICAgICAqCiAgICAgICAqIENyZWF0ZSBhIHJlcXVlc3QgZm9yIHRoZSBtZXRob2QgInByb2plY3RzLmNsZWFyT3JnUG9saWN5Ii4KICAgICAgICoKICAgICAgICogVGhpcyByZXF1ZXN0IGhvbGRzIHRoZSBwYXJhbWV0ZXJzIG5lZWRlZCBieSB0aGUgdGhlIGNsb3VkcmVzb3VyY2VtYW5hZ2VyIHNlcnZlci4gIEFmdGVyIHNldHRpbmcKICAgICAgICogYW55IG9wdGlvbmFsIHBhcmFtZXRlcnMsIGNhbGwgdGhlIHtAbGluayBDbGVhck9yZ1BvbGljeSNleGVjdXRlKCl9IG1ldGhvZCB0byBpbnZva2UgdGhlIHJlbW90ZQogICAgICAgKiBvcGVyYXRpb24uIDxwPiB7QGxpbmsgQ2xlYXJPcmdQb2xpY3kjaW5pdGlhbGl6ZShjb20uZ29vZ2xlLmFwaS5jbGllbnQuZ29vZ2xlYXBpcy5zZXJ2aWNlcy5BYnN0cgogICAgICAgKiBhY3RHb29nbGVDbGllbnRSZXF1ZXN0KX0gbXVzdCBiZSBjYWxsZWQgdG8gaW5pdGlhbGl6ZSB0aGlzIGluc3RhbmNlIGltbWVkaWF0ZWx5IGFmdGVyIGludm9raW5nCiAgICAgICAqIHRoZSBjb25zdHJ1Y3Rvci4gPC9wPgogICAgICAgKgogICAgICAgKiBAcGFyYW0gcmVzb3VyY2UgTmFtZSBvZiB0aGUgcmVzb3VyY2UgZm9yIHRoZSBgUG9saWN5YCB0byBjbGVhci4KICAgICAgICogQHBhcmFtIGNvbnRlbnQgdGhlIHtAbGluayBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5jbG91ZHJlc291cmNlbWFuYWdlci5tb2RlbC5DbGVhck9yZ1BvbGljeVJlcXVlc3R9CiAgICAgICAqIEBzaW5jZSAxLjEzCiAgICAgICAqLwogICAgICBwcm90ZWN0ZWQgQ2xlYXJPcmdQb2xpY3koamF2YS5sYW5nLlN0cmluZyByZXNvdXJjZSwgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuY2xvdWRyZXNvdXJjZW1hbmFnZXIubW9kZWwuQ2xlYXJPcmdQb2xpY3lSZXF1ZXN0IGNvbnRlbnQpIHsKICAgICAgICBzdXBlcihDbG91ZFJlc291cmNlTWFuYWdlci50aGlzLCAiUE9TVCIsIFJFU1RfUEFUSCwgY29udGVudCwgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuY2xvdWRyZXNvdXJjZW1hbmFnZXIubW9kZWwuRW1wdHkuY2xhc3MpOwogICAgICAgIHRoaXMucmVzb3VyY2UgPSBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5QcmVjb25kaXRpb25zLmNoZWNrTm90TnVsbChyZXNvdXJjZSwgIlJlcXVpcmVkIHBhcmFtZXRlciByZXNvdXJjZSBtdXN0IGJlIHNwZWNpZmllZC4iKTsKICAgICAgICBpZiAoIWdldFN1cHByZXNzUGF0dGVybkNoZWNrcygpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5QcmVjb25kaXRpb25zLmNoZWNrQXJndW1lbnQoUkVTT1VSQ0VfUEFUVEVSTi5tYXRjaGVyKHJlc291cmNlKS5tYXRjaGVzKCksCiAgICAgICAgICAgICAgIlBhcmFtZXRlciByZXNvdXJjZSBtdXN0IGNvbmZvcm0gdG8gdGhlIHBhdHRlcm4gIiArCiAgICAgICAgICAgICAgIl5wcm9qZWN0cy9bXi9dKyQiKTsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgQ2xlYXJPcmdQb2xpY3kgc2V0JFhnYWZ2KGphdmEubGFuZy5TdHJpbmcgJFhnYWZ2KSB7CiAgICAgICAgcmV0dXJuIChDbGVhck9yZ1BvbGljeSkgc3VwZXIuc2V0JFhnYWZ2KCRYZ2Fmdik7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgQ2xlYXJPcmdQb2xpY3kgc2V0QWNjZXNzVG9rZW4oamF2YS5sYW5nLlN0cmluZyBhY2Nlc3NUb2tlbikgewogICAgICAgIHJldHVybiAoQ2xlYXJPcmdQb2xpY3kpIHN1cGVyLnNldEFjY2Vzc1Rva2VuKGFjY2Vzc1Rva2VuKTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBDbGVhck9yZ1BvbGljeSBzZXRBbHQoamF2YS5sYW5nLlN0cmluZyBhbHQpIHsKICAgICAgICByZXR1cm4gKENsZWFyT3JnUG9saWN5KSBzdXBlci5zZXRBbHQoYWx0KTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBDbGVhck9yZ1BvbGljeSBzZXRDYWxsYmFjayhqYXZhLmxhbmcuU3RyaW5nIGNhbGxiYWNrKSB7CiAgICAgICAgcmV0dXJuIChDbGVhck9yZ1BvbGljeSkgc3VwZXIuc2V0Q2FsbGJhY2soY2FsbGJhY2spOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIENsZWFyT3JnUG9saWN5IHNldEZpZWxkcyhqYXZhLmxhbmcuU3RyaW5nIGZpZWxkcykgewogICAgICAgIHJldHVybiAoQ2xlYXJPcmdQb2xpY3kpIHN1cGVyLnNldEZpZWxkcyhmaWVsZHMpOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIENsZWFyT3JnUG9saWN5IHNldEtleShqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIHJldHVybiAoQ2xlYXJPcmdQb2xpY3kpIHN1cGVyLnNldEtleShrZXkpOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIENsZWFyT3JnUG9saWN5IHNldE9hdXRoVG9rZW4oamF2YS5sYW5nLlN0cmluZyBvYXV0aFRva2VuKSB7CiAgICAgICAgcmV0dXJuIChDbGVhck9yZ1BvbGljeSkgc3VwZXIuc2V0T2F1dGhUb2tlbihvYXV0aFRva2VuKTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBDbGVhck9yZ1BvbGljeSBzZXRQcmV0dHlQcmludChqYXZhLmxhbmcuQm9vbGVhbiBwcmV0dHlQcmludCkgewogICAgICAgIHJldHVybiAoQ2xlYXJPcmdQb2xpY3kpIHN1cGVyLnNldFByZXR0eVByaW50KHByZXR0eVByaW50KTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBDbGVhck9yZ1BvbGljeSBzZXRRdW90YVVzZXIoamF2YS5sYW5nLlN0cmluZyBxdW90YVVzZXIpIHsKICAgICAgICByZXR1cm4gKENsZWFyT3JnUG9saWN5KSBzdXBlci5zZXRRdW90YVVzZXIocXVvdGFVc2VyKTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBDbGVhck9yZ1BvbGljeSBzZXRVcGxvYWRUeXBlKGphdmEubGFuZy5TdHJpbmcgdXBsb2FkVHlwZSkgewogICAgICAgIHJldHVybiAoQ2xlYXJPcmdQb2xpY3kpIHN1cGVyLnNldFVwbG9hZFR5cGUodXBsb2FkVHlwZSk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgQ2xlYXJPcmdQb2xpY3kgc2V0VXBsb2FkUHJvdG9jb2woamF2YS5sYW5nLlN0cmluZyB1cGxvYWRQcm90b2NvbCkgewogICAgICAgIHJldHVybiAoQ2xlYXJPcmdQb2xpY3kpIHN1cGVyLnNldFVwbG9hZFByb3RvY29sKHVwbG9hZFByb3RvY29sKTsKICAgICAgfQoKICAgICAgLyoqIE5hbWUgb2YgdGhlIHJlc291cmNlIGZvciB0aGUgYFBvbGljeWAgdG8gY2xlYXIuICovCiAgICAgIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuU3RyaW5nIHJlc291cmNlOwoKICAgICAgLyoqIE5hbWUgb2YgdGhlIHJlc291cmNlIGZvciB0aGUgYFBvbGljeWAgdG8gY2xlYXIuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRSZXNvdXJjZSgpIHsKICAgICAgICByZXR1cm4gcmVzb3VyY2U7CiAgICAgIH0KCiAgICAgIC8qKiBOYW1lIG9mIHRoZSByZXNvdXJjZSBmb3IgdGhlIGBQb2xpY3lgIHRvIGNsZWFyLiAqLwogICAgICBwdWJsaWMgQ2xlYXJPcmdQb2xpY3kgc2V0UmVzb3VyY2UoamF2YS5sYW5nLlN0cmluZyByZXNvdXJjZSkgewogICAgICAgIGlmICghZ2V0U3VwcHJlc3NQYXR0ZXJuQ2hlY2tzKCkpIHsKICAgICAgICAgIGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLlByZWNvbmRpdGlvbnMuY2hlY2tBcmd1bWVudChSRVNPVVJDRV9QQVRURVJOLm1hdGNoZXIocmVzb3VyY2UpLm1hdGNoZXMoKSwKICAgICAgICAgICAgICAiUGFyYW1ldGVyIHJlc291cmNlIG11c3QgY29uZm9ybSB0byB0aGUgcGF0dGVybiAiICsKICAgICAgICAgICAgICAiXnByb2plY3RzL1teL10rJCIpOwogICAgICAgIH0KICAgICAgICB0aGlzLnJlc291cmNlID0gcmVzb3VyY2U7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgQ2xlYXJPcmdQb2xpY3kgc2V0KFN0cmluZyBwYXJhbWV0ZXJOYW1lLCBPYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gKENsZWFyT3JnUG9saWN5KSBzdXBlci5zZXQocGFyYW1ldGVyTmFtZSwgdmFsdWUpOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIFJlcXVlc3QgdGhhdCBhIG5ldyBQcm9qZWN0IGJlIGNyZWF0ZWQuIFRoZSByZXN1bHQgaXMgYW4gT3BlcmF0aW9uIHdoaWNoIGNhbiBiZSB1c2VkIHRvIHRyYWNrIHRoZQogICAgICogY3JlYXRpb24gcHJvY2Vzcy4gVGhpcyBwcm9jZXNzIHVzdWFsbHkgdGFrZXMgYSBmZXcgc2Vjb25kcywgYnV0IGNhbiBzb21ldGltZXMgdGFrZSBtdWNoIGxvbmdlci4KICAgICAqIFRoZSB0cmFja2luZyBPcGVyYXRpb24gaXMgYXV0b21hdGljYWxseSBkZWxldGVkIGFmdGVyIGEgZmV3IGhvdXJzLCBzbyB0aGVyZSBpcyBubyBuZWVkIHRvIGNhbGwKICAgICAqIERlbGV0ZU9wZXJhdGlvbi4KICAgICAqCiAgICAgKiBBdXRob3JpemF0aW9uIHJlcXVpcmVzIHRoZSBHb29nbGUgSUFNIHBlcm1pc3Npb24gYHJlc291cmNlbWFuYWdlci5wcm9qZWN0cy5jcmVhdGVgIG9uIHRoZQogICAgICogc3BlY2lmaWVkIHBhcmVudCBmb3IgdGhlIG5ldyBwcm9qZWN0LiBUaGUgcGFyZW50IGlzIGlkZW50aWZpZWQgYnkgYSBzcGVjaWZpZWQgUmVzb3VyY2VJZCwgd2hpY2gKICAgICAqIG11c3QgaW5jbHVkZSBib3RoIGFuIElEIGFuZCBhIHR5cGUsIHN1Y2ggYXMgb3JnYW5pemF0aW9uLgogICAgICoKICAgICAqIFRoaXMgbWV0aG9kIGRvZXMgbm90IGFzc29jaWF0ZSB0aGUgbmV3IHByb2plY3Qgd2l0aCBhIGJpbGxpbmcgYWNjb3VudC4gWW91IGNhbiBzZXQgb3IgdXBkYXRlIHRoZQogICAgICogYmlsbGluZyBhY2NvdW50IGFzc29jaWF0ZWQgd2l0aCBhIHByb2plY3QgdXNpbmcgdGhlIFtgcHJvamVjdHMudXBkYXRlQmlsbGluZ0luZm9gXQogICAgICogKC9iaWxsaW5nL3JlZmVyZW5jZS9yZXN0L3YxL3Byb2plY3RzL3VwZGF0ZUJpbGxpbmdJbmZvKSBtZXRob2QuCiAgICAgKgogICAgICogQ3JlYXRlIGEgcmVxdWVzdCBmb3IgdGhlIG1ldGhvZCAicHJvamVjdHMuY3JlYXRlIi4KICAgICAqCiAgICAgKiBUaGlzIHJlcXVlc3QgaG9sZHMgdGhlIHBhcmFtZXRlcnMgbmVlZGVkIGJ5IHRoZSBjbG91ZHJlc291cmNlbWFuYWdlciBzZXJ2ZXIuICBBZnRlciBzZXR0aW5nIGFueQogICAgICogb3B0aW9uYWwgcGFyYW1ldGVycywgY2FsbCB0aGUge0BsaW5rIENyZWF0ZSNleGVjdXRlKCl9IG1ldGhvZCB0byBpbnZva2UgdGhlIHJlbW90ZSBvcGVyYXRpb24uCiAgICAgKgogICAgICogQHBhcmFtIGNvbnRlbnQgdGhlIHtAbGluayBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5jbG91ZHJlc291cmNlbWFuYWdlci5tb2RlbC5Qcm9qZWN0fQogICAgICogQHJldHVybiB0aGUgcmVxdWVzdAogICAgICovCiAgICBwdWJsaWMgQ3JlYXRlIGNyZWF0ZShjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5jbG91ZHJlc291cmNlbWFuYWdlci5tb2RlbC5Qcm9qZWN0IGNvbnRlbnQpIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgQ3JlYXRlIHJlc3VsdCA9IG5ldyBDcmVhdGUoY29udGVudCk7CiAgICAgIGluaXRpYWxpemUocmVzdWx0KTsKICAgICAgcmV0dXJuIHJlc3VsdDsKICAgIH0KCiAgICBwdWJsaWMgY2xhc3MgQ3JlYXRlIGV4dGVuZHMgQ2xvdWRSZXNvdXJjZU1hbmFnZXJSZXF1ZXN0PGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmNsb3VkcmVzb3VyY2VtYW5hZ2VyLm1vZGVsLk9wZXJhdGlvbj4gewoKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFJFU1RfUEFUSCA9ICJ2MS9wcm9qZWN0cyI7CgogICAgICAvKioKICAgICAgICogUmVxdWVzdCB0aGF0IGEgbmV3IFByb2plY3QgYmUgY3JlYXRlZC4gVGhlIHJlc3VsdCBpcyBhbiBPcGVyYXRpb24gd2hpY2ggY2FuIGJlIHVzZWQgdG8gdHJhY2sKICAgICAgICogdGhlIGNyZWF0aW9uIHByb2Nlc3MuIFRoaXMgcHJvY2VzcyB1c3VhbGx5IHRha2VzIGEgZmV3IHNlY29uZHMsIGJ1dCBjYW4gc29tZXRpbWVzIHRha2UgbXVjaAogICAgICAgKiBsb25nZXIuIFRoZSB0cmFja2luZyBPcGVyYXRpb24gaXMgYXV0b21hdGljYWxseSBkZWxldGVkIGFmdGVyIGEgZmV3IGhvdXJzLCBzbyB0aGVyZSBpcyBubyBuZWVkCiAgICAgICAqIHRvIGNhbGwgRGVsZXRlT3BlcmF0aW9uLgogICAgICAgKgogICAgICAgKiBBdXRob3JpemF0aW9uIHJlcXVpcmVzIHRoZSBHb29nbGUgSUFNIHBlcm1pc3Npb24gYHJlc291cmNlbWFuYWdlci5wcm9qZWN0cy5jcmVhdGVgIG9uIHRoZQogICAgICAgKiBzcGVjaWZpZWQgcGFyZW50IGZvciB0aGUgbmV3IHByb2plY3QuIFRoZSBwYXJlbnQgaXMgaWRlbnRpZmllZCBieSBhIHNwZWNpZmllZCBSZXNvdXJjZUlkLCB3aGljaAogICAgICAgKiBtdXN0IGluY2x1ZGUgYm90aCBhbiBJRCBhbmQgYSB0eXBlLCBzdWNoIGFzIG9yZ2FuaXphdGlvbi4KICAgICAgICoKICAgICAgICogVGhpcyBtZXRob2QgZG9lcyBub3QgYXNzb2NpYXRlIHRoZSBuZXcgcHJvamVjdCB3aXRoIGEgYmlsbGluZyBhY2NvdW50LiBZb3UgY2FuIHNldCBvciB1cGRhdGUKICAgICAgICogdGhlIGJpbGxpbmcgYWNjb3VudCBhc3NvY2lhdGVkIHdpdGggYSBwcm9qZWN0IHVzaW5nIHRoZSBbYHByb2plY3RzLnVwZGF0ZUJpbGxpbmdJbmZvYF0KICAgICAgICogKC9iaWxsaW5nL3JlZmVyZW5jZS9yZXN0L3YxL3Byb2plY3RzL3VwZGF0ZUJpbGxpbmdJbmZvKSBtZXRob2QuCiAgICAgICAqCiAgICAgICAqIENyZWF0ZSBhIHJlcXVlc3QgZm9yIHRoZSBtZXRob2QgInByb2plY3RzLmNyZWF0ZSIuCiAgICAgICAqCiAgICAgICAqIFRoaXMgcmVxdWVzdCBob2xkcyB0aGUgcGFyYW1ldGVycyBuZWVkZWQgYnkgdGhlIHRoZSBjbG91ZHJlc291cmNlbWFuYWdlciBzZXJ2ZXIuICBBZnRlciBzZXR0aW5nCiAgICAgICAqIGFueSBvcHRpb25hbCBwYXJhbWV0ZXJzLCBjYWxsIHRoZSB7QGxpbmsgQ3JlYXRlI2V4ZWN1dGUoKX0gbWV0aG9kIHRvIGludm9rZSB0aGUgcmVtb3RlCiAgICAgICAqIG9wZXJhdGlvbi4gPHA+IHtAbGluawogICAgICAgKiBDcmVhdGUjaW5pdGlhbGl6ZShjb20uZ29vZ2xlLmFwaS5jbGllbnQuZ29vZ2xlYXBpcy5zZXJ2aWNlcy5BYnN0cmFjdEdvb2dsZUNsaWVudFJlcXVlc3QpfSBtdXN0CiAgICAgICAqIGJlIGNhbGxlZCB0byBpbml0aWFsaXplIHRoaXMgaW5zdGFuY2UgaW1tZWRpYXRlbHkgYWZ0ZXIgaW52b2tpbmcgdGhlIGNvbnN0cnVjdG9yLiA8L3A+CiAgICAgICAqCiAgICAgICAqIEBwYXJhbSBjb250ZW50IHRoZSB7QGxpbmsgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuY2xvdWRyZXNvdXJjZW1hbmFnZXIubW9kZWwuUHJvamVjdH0KICAgICAgICogQHNpbmNlIDEuMTMKICAgICAgICovCiAgICAgIHByb3RlY3RlZCBDcmVhdGUoY29tLmdvb2dsZS5hcGkuc2VydmljZXMuY2xvdWRyZXNvdXJjZW1hbmFnZXIubW9kZWwuUHJvamVjdCBjb250ZW50KSB7CiAgICAgICAgc3VwZXIoQ2xvdWRSZXNvdXJjZU1hbmFnZXIudGhpcywgIlBPU1QiLCBSRVNUX1BBVEgsIGNvbnRlbnQsIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmNsb3VkcmVzb3VyY2VtYW5hZ2VyLm1vZGVsLk9wZXJhdGlvbi5jbGFzcyk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgQ3JlYXRlIHNldCRYZ2FmdihqYXZhLmxhbmcuU3RyaW5nICRYZ2FmdikgewogICAgICAgIHJldHVybiAoQ3JlYXRlKSBzdXBlci5zZXQkWGdhZnYoJFhnYWZ2KTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBDcmVhdGUgc2V0QWNjZXNzVG9rZW4oamF2YS5sYW5nLlN0cmluZyBhY2Nlc3NUb2tlbikgewogICAgICAgIHJldHVybiAoQ3JlYXRlKSBzdXBlci5zZXRBY2Nlc3NUb2tlbihhY2Nlc3NUb2tlbik7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgQ3JlYXRlIHNldEFsdChqYXZhLmxhbmcuU3RyaW5nIGFsdCkgewogICAgICAgIHJldHVybiAoQ3JlYXRlKSBzdXBlci5zZXRBbHQoYWx0KTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBDcmVhdGUgc2V0Q2FsbGJhY2soamF2YS5sYW5nLlN0cmluZyBjYWxsYmFjaykgewogICAgICAgIHJldHVybiAoQ3JlYXRlKSBzdXBlci5zZXRDYWxsYmFjayhjYWxsYmFjayk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgQ3JlYXRlIHNldEZpZWxkcyhqYXZhLmxhbmcuU3RyaW5nIGZpZWxkcykgewogICAgICAgIHJldHVybiAoQ3JlYXRlKSBzdXBlci5zZXRGaWVsZHMoZmllbGRzKTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBDcmVhdGUgc2V0S2V5KGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgcmV0dXJuIChDcmVhdGUpIHN1cGVyLnNldEtleShrZXkpOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIENyZWF0ZSBzZXRPYXV0aFRva2VuKGphdmEubGFuZy5TdHJpbmcgb2F1dGhUb2tlbikgewogICAgICAgIHJldHVybiAoQ3JlYXRlKSBzdXBlci5zZXRPYXV0aFRva2VuKG9hdXRoVG9rZW4pOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIENyZWF0ZSBzZXRQcmV0dHlQcmludChqYXZhLmxhbmcuQm9vbGVhbiBwcmV0dHlQcmludCkgewogICAgICAgIHJldHVybiAoQ3JlYXRlKSBzdXBlci5zZXRQcmV0dHlQcmludChwcmV0dHlQcmludCk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgQ3JlYXRlIHNldFF1b3RhVXNlcihqYXZhLmxhbmcuU3RyaW5nIHF1b3RhVXNlcikgewogICAgICAgIHJldHVybiAoQ3JlYXRlKSBzdXBlci5zZXRRdW90YVVzZXIocXVvdGFVc2VyKTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBDcmVhdGUgc2V0VXBsb2FkVHlwZShqYXZhLmxhbmcuU3RyaW5nIHVwbG9hZFR5cGUpIHsKICAgICAgICByZXR1cm4gKENyZWF0ZSkgc3VwZXIuc2V0VXBsb2FkVHlwZSh1cGxvYWRUeXBlKTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBDcmVhdGUgc2V0VXBsb2FkUHJvdG9jb2woamF2YS5sYW5nLlN0cmluZyB1cGxvYWRQcm90b2NvbCkgewogICAgICAgIHJldHVybiAoQ3JlYXRlKSBzdXBlci5zZXRVcGxvYWRQcm90b2NvbCh1cGxvYWRQcm90b2NvbCk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgQ3JlYXRlIHNldChTdHJpbmcgcGFyYW1ldGVyTmFtZSwgT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIChDcmVhdGUpIHN1cGVyLnNldChwYXJhbWV0ZXJOYW1lLCB2YWx1ZSk7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogTWFya3MgdGhlIFByb2plY3QgaWRlbnRpZmllZCBieSB0aGUgc3BlY2lmaWVkIGBwcm9qZWN0X2lkYCAoZm9yIGV4YW1wbGUsIGBteS1wcm9qZWN0LTEyM2ApIGZvcgogICAgICogZGVsZXRpb24uIFRoaXMgbWV0aG9kIHdpbGwgb25seSBhZmZlY3QgdGhlIFByb2plY3QgaWYgaXQgaGFzIGEgbGlmZWN5Y2xlIHN0YXRlIG9mIEFDVElWRS4KICAgICAqCiAgICAgKiBUaGlzIG1ldGhvZCBjaGFuZ2VzIHRoZSBQcm9qZWN0J3MgbGlmZWN5Y2xlIHN0YXRlIGZyb20gQUNUSVZFIHRvIERFTEVURV9SRVFVRVNURUQuIFRoZSBkZWxldGlvbgogICAgICogc3RhcnRzIGF0IGFuIHVuc3BlY2lmaWVkIHRpbWUsIGF0IHdoaWNoIHBvaW50IHRoZSBQcm9qZWN0IGlzIG5vIGxvbmdlciBhY2Nlc3NpYmxlLgogICAgICoKICAgICAqIFVudGlsIHRoZSBkZWxldGlvbiBjb21wbGV0ZXMsIHlvdSBjYW4gY2hlY2sgdGhlIGxpZmVjeWNsZSBzdGF0ZSBjaGVja2VkIGJ5IHJldHJpZXZpbmcgdGhlIFByb2plY3QKICAgICAqIHdpdGggR2V0UHJvamVjdCwgYW5kIHRoZSBQcm9qZWN0IHJlbWFpbnMgdmlzaWJsZSB0byBMaXN0UHJvamVjdHMuIEhvd2V2ZXIsIHlvdSBjYW5ub3QgdXBkYXRlIHRoZQogICAgICogcHJvamVjdC4KICAgICAqCiAgICAgKiBBZnRlciB0aGUgZGVsZXRpb24gY29tcGxldGVzLCB0aGUgUHJvamVjdCBpcyBub3QgcmV0cmlldmFibGUgYnkgdGhlICBHZXRQcm9qZWN0IGFuZCBMaXN0UHJvamVjdHMKICAgICAqIG1ldGhvZHMuCiAgICAgKgogICAgICogVGhlIGNhbGxlciBtdXN0IGhhdmUgbW9kaWZ5IHBlcm1pc3Npb25zIGZvciB0aGlzIFByb2plY3QuCiAgICAgKgogICAgICogQ3JlYXRlIGEgcmVxdWVzdCBmb3IgdGhlIG1ldGhvZCAicHJvamVjdHMuZGVsZXRlIi4KICAgICAqCiAgICAgKiBUaGlzIHJlcXVlc3QgaG9sZHMgdGhlIHBhcmFtZXRlcnMgbmVlZGVkIGJ5IHRoZSBjbG91ZHJlc291cmNlbWFuYWdlciBzZXJ2ZXIuICBBZnRlciBzZXR0aW5nIGFueQogICAgICogb3B0aW9uYWwgcGFyYW1ldGVycywgY2FsbCB0aGUge0BsaW5rIERlbGV0ZSNleGVjdXRlKCl9IG1ldGhvZCB0byBpbnZva2UgdGhlIHJlbW90ZSBvcGVyYXRpb24uCiAgICAgKgogICAgICogQHBhcmFtIHByb2plY3RJZCBUaGUgUHJvamVjdCBJRCAoZm9yIGV4YW1wbGUsIGBmb28tYmFyLTEyM2ApLgogICAgUmVxdWlyZWQuCiAgICAgKiBAcmV0dXJuIHRoZSByZXF1ZXN0CiAgICAgKi8KICAgIHB1YmxpYyBEZWxldGUgZGVsZXRlKGphdmEubGFuZy5TdHJpbmcgcHJvamVjdElkKSB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIERlbGV0ZSByZXN1bHQgPSBuZXcgRGVsZXRlKHByb2plY3RJZCk7CiAgICAgIGluaXRpYWxpemUocmVzdWx0KTsKICAgICAgcmV0dXJuIHJlc3VsdDsKICAgIH0KCiAgICBwdWJsaWMgY2xhc3MgRGVsZXRlIGV4dGVuZHMgQ2xvdWRSZXNvdXJjZU1hbmFnZXJSZXF1ZXN0PGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmNsb3VkcmVzb3VyY2VtYW5hZ2VyLm1vZGVsLkVtcHR5PiB7CgogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgUkVTVF9QQVRIID0gInYxL3Byb2plY3RzL3twcm9qZWN0SWR9IjsKCiAgICAgIC8qKgogICAgICAgKiBNYXJrcyB0aGUgUHJvamVjdCBpZGVudGlmaWVkIGJ5IHRoZSBzcGVjaWZpZWQgYHByb2plY3RfaWRgIChmb3IgZXhhbXBsZSwgYG15LXByb2plY3QtMTIzYCkgZm9yCiAgICAgICAqIGRlbGV0aW9uLiBUaGlzIG1ldGhvZCB3aWxsIG9ubHkgYWZmZWN0IHRoZSBQcm9qZWN0IGlmIGl0IGhhcyBhIGxpZmVjeWNsZSBzdGF0ZSBvZiBBQ1RJVkUuCiAgICAgICAqCiAgICAgICAqIFRoaXMgbWV0aG9kIGNoYW5nZXMgdGhlIFByb2plY3QncyBsaWZlY3ljbGUgc3RhdGUgZnJvbSBBQ1RJVkUgdG8gREVMRVRFX1JFUVVFU1RFRC4gVGhlIGRlbGV0aW9uCiAgICAgICAqIHN0YXJ0cyBhdCBhbiB1bnNwZWNpZmllZCB0aW1lLCBhdCB3aGljaCBwb2ludCB0aGUgUHJvamVjdCBpcyBubyBsb25nZXIgYWNjZXNzaWJsZS4KICAgICAgICoKICAgICAgICogVW50aWwgdGhlIGRlbGV0aW9uIGNvbXBsZXRlcywgeW91IGNhbiBjaGVjayB0aGUgbGlmZWN5Y2xlIHN0YXRlIGNoZWNrZWQgYnkgcmV0cmlldmluZyB0aGUKICAgICAgICogUHJvamVjdCB3aXRoIEdldFByb2plY3QsIGFuZCB0aGUgUHJvamVjdCByZW1haW5zIHZpc2libGUgdG8gTGlzdFByb2plY3RzLiBIb3dldmVyLCB5b3UgY2Fubm90CiAgICAgICAqIHVwZGF0ZSB0aGUgcHJvamVjdC4KICAgICAgICoKICAgICAgICogQWZ0ZXIgdGhlIGRlbGV0aW9uIGNvbXBsZXRlcywgdGhlIFByb2plY3QgaXMgbm90IHJldHJpZXZhYmxlIGJ5IHRoZSAgR2V0UHJvamVjdCBhbmQKICAgICAgICogTGlzdFByb2plY3RzIG1ldGhvZHMuCiAgICAgICAqCiAgICAgICAqIFRoZSBjYWxsZXIgbXVzdCBoYXZlIG1vZGlmeSBwZXJtaXNzaW9ucyBmb3IgdGhpcyBQcm9qZWN0LgogICAgICAgKgogICAgICAgKiBDcmVhdGUgYSByZXF1ZXN0IGZvciB0aGUgbWV0aG9kICJwcm9qZWN0cy5kZWxldGUiLgogICAgICAgKgogICAgICAgKiBUaGlzIHJlcXVlc3QgaG9sZHMgdGhlIHBhcmFtZXRlcnMgbmVlZGVkIGJ5IHRoZSB0aGUgY2xvdWRyZXNvdXJjZW1hbmFnZXIgc2VydmVyLiAgQWZ0ZXIgc2V0dGluZwogICAgICAgKiBhbnkgb3B0aW9uYWwgcGFyYW1ldGVycywgY2FsbCB0aGUge0BsaW5rIERlbGV0ZSNleGVjdXRlKCl9IG1ldGhvZCB0byBpbnZva2UgdGhlIHJlbW90ZQogICAgICAgKiBvcGVyYXRpb24uIDxwPiB7QGxpbmsKICAgICAgICogRGVsZXRlI2luaXRpYWxpemUoY29tLmdvb2dsZS5hcGkuY2xpZW50Lmdvb2dsZWFwaXMuc2VydmljZXMuQWJzdHJhY3RHb29nbGVDbGllbnRSZXF1ZXN0KX0gbXVzdAogICAgICAgKiBiZSBjYWxsZWQgdG8gaW5pdGlhbGl6ZSB0aGlzIGluc3RhbmNlIGltbWVkaWF0ZWx5IGFmdGVyIGludm9raW5nIHRoZSBjb25zdHJ1Y3Rvci4gPC9wPgogICAgICAgKgogICAgICAgKiBAcGFyYW0gcHJvamVjdElkIFRoZSBQcm9qZWN0IElEIChmb3IgZXhhbXBsZSwgYGZvby1iYXItMTIzYCkuCiAgICBSZXF1aXJlZC4KICAgICAgICogQHNpbmNlIDEuMTMKICAgICAgICovCiAgICAgIHByb3RlY3RlZCBEZWxldGUoamF2YS5sYW5nLlN0cmluZyBwcm9qZWN0SWQpIHsKICAgICAgICBzdXBlcihDbG91ZFJlc291cmNlTWFuYWdlci50aGlzLCAiREVMRVRFIiwgUkVTVF9QQVRILCBudWxsLCBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5jbG91ZHJlc291cmNlbWFuYWdlci5tb2RlbC5FbXB0eS5jbGFzcyk7CiAgICAgICAgdGhpcy5wcm9qZWN0SWQgPSBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5QcmVjb25kaXRpb25zLmNoZWNrTm90TnVsbChwcm9qZWN0SWQsICJSZXF1aXJlZCBwYXJhbWV0ZXIgcHJvamVjdElkIG11c3QgYmUgc3BlY2lmaWVkLiIpOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIERlbGV0ZSBzZXQkWGdhZnYoamF2YS5sYW5nLlN0cmluZyAkWGdhZnYpIHsKICAgICAgICByZXR1cm4gKERlbGV0ZSkgc3VwZXIuc2V0JFhnYWZ2KCRYZ2Fmdik7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgRGVsZXRlIHNldEFjY2Vzc1Rva2VuKGphdmEubGFuZy5TdHJpbmcgYWNjZXNzVG9rZW4pIHsKICAgICAgICByZXR1cm4gKERlbGV0ZSkgc3VwZXIuc2V0QWNjZXNzVG9rZW4oYWNjZXNzVG9rZW4pOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIERlbGV0ZSBzZXRBbHQoamF2YS5sYW5nLlN0cmluZyBhbHQpIHsKICAgICAgICByZXR1cm4gKERlbGV0ZSkgc3VwZXIuc2V0QWx0KGFsdCk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgRGVsZXRlIHNldENhbGxiYWNrKGphdmEubGFuZy5TdHJpbmcgY2FsbGJhY2spIHsKICAgICAgICByZXR1cm4gKERlbGV0ZSkgc3VwZXIuc2V0Q2FsbGJhY2soY2FsbGJhY2spOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIERlbGV0ZSBzZXRGaWVsZHMoamF2YS5sYW5nLlN0cmluZyBmaWVsZHMpIHsKICAgICAgICByZXR1cm4gKERlbGV0ZSkgc3VwZXIuc2V0RmllbGRzKGZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgRGVsZXRlIHNldEtleShqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIHJldHVybiAoRGVsZXRlKSBzdXBlci5zZXRLZXkoa2V5KTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBEZWxldGUgc2V0T2F1dGhUb2tlbihqYXZhLmxhbmcuU3RyaW5nIG9hdXRoVG9rZW4pIHsKICAgICAgICByZXR1cm4gKERlbGV0ZSkgc3VwZXIuc2V0T2F1dGhUb2tlbihvYXV0aFRva2VuKTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBEZWxldGUgc2V0UHJldHR5UHJpbnQoamF2YS5sYW5nLkJvb2xlYW4gcHJldHR5UHJpbnQpIHsKICAgICAgICByZXR1cm4gKERlbGV0ZSkgc3VwZXIuc2V0UHJldHR5UHJpbnQocHJldHR5UHJpbnQpOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIERlbGV0ZSBzZXRRdW90YVVzZXIoamF2YS5sYW5nLlN0cmluZyBxdW90YVVzZXIpIHsKICAgICAgICByZXR1cm4gKERlbGV0ZSkgc3VwZXIuc2V0UXVvdGFVc2VyKHF1b3RhVXNlcik7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgRGVsZXRlIHNldFVwbG9hZFR5cGUoamF2YS5sYW5nLlN0cmluZyB1cGxvYWRUeXBlKSB7CiAgICAgICAgcmV0dXJuIChEZWxldGUpIHN1cGVyLnNldFVwbG9hZFR5cGUodXBsb2FkVHlwZSk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgRGVsZXRlIHNldFVwbG9hZFByb3RvY29sKGphdmEubGFuZy5TdHJpbmcgdXBsb2FkUHJvdG9jb2wpIHsKICAgICAgICByZXR1cm4gKERlbGV0ZSkgc3VwZXIuc2V0VXBsb2FkUHJvdG9jb2wodXBsb2FkUHJvdG9jb2wpOwogICAgICB9CgogICAgICAvKioKICAgICAgICogVGhlIFByb2plY3QgSUQgKGZvciBleGFtcGxlLCBgZm9vLWJhci0xMjNgKS4KICAgICAgICoKICAgICAgICogUmVxdWlyZWQuCiAgICAgICAqLwogICAgICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgICAgIHByaXZhdGUgamF2YS5sYW5nLlN0cmluZyBwcm9qZWN0SWQ7CgogICAgICAvKiogVGhlIFByb2plY3QgSUQgKGZvciBleGFtcGxlLCBgZm9vLWJhci0xMjNgKS4KCiAgICAgUmVxdWlyZWQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRQcm9qZWN0SWQoKSB7CiAgICAgICAgcmV0dXJuIHByb2plY3RJZDsKICAgICAgfQoKICAgICAgLyoqCiAgICAgICAqIFRoZSBQcm9qZWN0IElEIChmb3IgZXhhbXBsZSwgYGZvby1iYXItMTIzYCkuCiAgICAgICAqCiAgICAgICAqIFJlcXVpcmVkLgogICAgICAgKi8KICAgICAgcHVibGljIERlbGV0ZSBzZXRQcm9qZWN0SWQoamF2YS5sYW5nLlN0cmluZyBwcm9qZWN0SWQpIHsKICAgICAgICB0aGlzLnByb2plY3RJZCA9IHByb2plY3RJZDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBEZWxldGUgc2V0KFN0cmluZyBwYXJhbWV0ZXJOYW1lLCBPYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gKERlbGV0ZSkgc3VwZXIuc2V0KHBhcmFtZXRlck5hbWUsIHZhbHVlKTsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiBSZXRyaWV2ZXMgdGhlIFByb2plY3QgaWRlbnRpZmllZCBieSB0aGUgc3BlY2lmaWVkIGBwcm9qZWN0X2lkYCAoZm9yIGV4YW1wbGUsIGBteS1wcm9qZWN0LTEyM2ApLgogICAgICoKICAgICAqIFRoZSBjYWxsZXIgbXVzdCBoYXZlIHJlYWQgcGVybWlzc2lvbnMgZm9yIHRoaXMgUHJvamVjdC4KICAgICAqCiAgICAgKiBDcmVhdGUgYSByZXF1ZXN0IGZvciB0aGUgbWV0aG9kICJwcm9qZWN0cy5nZXQiLgogICAgICoKICAgICAqIFRoaXMgcmVxdWVzdCBob2xkcyB0aGUgcGFyYW1ldGVycyBuZWVkZWQgYnkgdGhlIGNsb3VkcmVzb3VyY2VtYW5hZ2VyIHNlcnZlci4gIEFmdGVyIHNldHRpbmcgYW55CiAgICAgKiBvcHRpb25hbCBwYXJhbWV0ZXJzLCBjYWxsIHRoZSB7QGxpbmsgR2V0I2V4ZWN1dGUoKX0gbWV0aG9kIHRvIGludm9rZSB0aGUgcmVtb3RlIG9wZXJhdGlvbi4KICAgICAqCiAgICAgKiBAcGFyYW0gcHJvamVjdElkIFRoZSBQcm9qZWN0IElEIChmb3IgZXhhbXBsZSwgYG15LXByb2plY3QtMTIzYCkuCiAgICBSZXF1aXJlZC4KICAgICAqIEByZXR1cm4gdGhlIHJlcXVlc3QKICAgICAqLwogICAgcHVibGljIEdldCBnZXQoamF2YS5sYW5nLlN0cmluZyBwcm9qZWN0SWQpIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgR2V0IHJlc3VsdCA9IG5ldyBHZXQocHJvamVjdElkKTsKICAgICAgaW5pdGlhbGl6ZShyZXN1bHQpOwogICAgICByZXR1cm4gcmVzdWx0OwogICAgfQoKICAgIHB1YmxpYyBjbGFzcyBHZXQgZXh0ZW5kcyBDbG91ZFJlc291cmNlTWFuYWdlclJlcXVlc3Q8Y29tLmdvb2dsZS5hcGkuc2VydmljZXMuY2xvdWRyZXNvdXJjZW1hbmFnZXIubW9kZWwuUHJvamVjdD4gewoKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFJFU1RfUEFUSCA9ICJ2MS9wcm9qZWN0cy97cHJvamVjdElkfSI7CgogICAgICAvKioKICAgICAgICogUmV0cmlldmVzIHRoZSBQcm9qZWN0IGlkZW50aWZpZWQgYnkgdGhlIHNwZWNpZmllZCBgcHJvamVjdF9pZGAgKGZvciBleGFtcGxlLCBgbXktcHJvamVjdC0xMjNgKS4KICAgICAgICoKICAgICAgICogVGhlIGNhbGxlciBtdXN0IGhhdmUgcmVhZCBwZXJtaXNzaW9ucyBmb3IgdGhpcyBQcm9qZWN0LgogICAgICAgKgogICAgICAgKiBDcmVhdGUgYSByZXF1ZXN0IGZvciB0aGUgbWV0aG9kICJwcm9qZWN0cy5nZXQiLgogICAgICAgKgogICAgICAgKiBUaGlzIHJlcXVlc3QgaG9sZHMgdGhlIHBhcmFtZXRlcnMgbmVlZGVkIGJ5IHRoZSB0aGUgY2xvdWRyZXNvdXJjZW1hbmFnZXIgc2VydmVyLiAgQWZ0ZXIgc2V0dGluZwogICAgICAgKiBhbnkgb3B0aW9uYWwgcGFyYW1ldGVycywgY2FsbCB0aGUge0BsaW5rIEdldCNleGVjdXRlKCl9IG1ldGhvZCB0byBpbnZva2UgdGhlIHJlbW90ZSBvcGVyYXRpb24uCiAgICAgICAqIDxwPiB7QGxpbmsKICAgICAgICogR2V0I2luaXRpYWxpemUoY29tLmdvb2dsZS5hcGkuY2xpZW50Lmdvb2dsZWFwaXMuc2VydmljZXMuQWJzdHJhY3RHb29nbGVDbGllbnRSZXF1ZXN0KX0gbXVzdCBiZQogICAgICAgKiBjYWxsZWQgdG8gaW5pdGlhbGl6ZSB0aGlzIGluc3RhbmNlIGltbWVkaWF0ZWx5IGFmdGVyIGludm9raW5nIHRoZSBjb25zdHJ1Y3Rvci4gPC9wPgogICAgICAgKgogICAgICAgKiBAcGFyYW0gcHJvamVjdElkIFRoZSBQcm9qZWN0IElEIChmb3IgZXhhbXBsZSwgYG15LXByb2plY3QtMTIzYCkuCiAgICBSZXF1aXJlZC4KICAgICAgICogQHNpbmNlIDEuMTMKICAgICAgICovCiAgICAgIHByb3RlY3RlZCBHZXQoamF2YS5sYW5nLlN0cmluZyBwcm9qZWN0SWQpIHsKICAgICAgICBzdXBlcihDbG91ZFJlc291cmNlTWFuYWdlci50aGlzLCAiR0VUIiwgUkVTVF9QQVRILCBudWxsLCBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5jbG91ZHJlc291cmNlbWFuYWdlci5tb2RlbC5Qcm9qZWN0LmNsYXNzKTsKICAgICAgICB0aGlzLnByb2plY3RJZCA9IGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLlByZWNvbmRpdGlvbnMuY2hlY2tOb3ROdWxsKHByb2plY3RJZCwgIlJlcXVpcmVkIHBhcmFtZXRlciBwcm9qZWN0SWQgbXVzdCBiZSBzcGVjaWZpZWQuIik7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgY29tLmdvb2dsZS5hcGkuY2xpZW50Lmh0dHAuSHR0cFJlc3BvbnNlIGV4ZWN1dGVVc2luZ0hlYWQoKSB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmV4ZWN1dGVVc2luZ0hlYWQoKTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLmFwaS5jbGllbnQuaHR0cC5IdHRwUmVxdWVzdCBidWlsZEh0dHBSZXF1ZXN0VXNpbmdIZWFkKCkgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBzdXBlci5idWlsZEh0dHBSZXF1ZXN0VXNpbmdIZWFkKCk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgR2V0IHNldCRYZ2FmdihqYXZhLmxhbmcuU3RyaW5nICRYZ2FmdikgewogICAgICAgIHJldHVybiAoR2V0KSBzdXBlci5zZXQkWGdhZnYoJFhnYWZ2KTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBHZXQgc2V0QWNjZXNzVG9rZW4oamF2YS5sYW5nLlN0cmluZyBhY2Nlc3NUb2tlbikgewogICAgICAgIHJldHVybiAoR2V0KSBzdXBlci5zZXRBY2Nlc3NUb2tlbihhY2Nlc3NUb2tlbik7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgR2V0IHNldEFsdChqYXZhLmxhbmcuU3RyaW5nIGFsdCkgewogICAgICAgIHJldHVybiAoR2V0KSBzdXBlci5zZXRBbHQoYWx0KTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBHZXQgc2V0Q2FsbGJhY2soamF2YS5sYW5nLlN0cmluZyBjYWxsYmFjaykgewogICAgICAgIHJldHVybiAoR2V0KSBzdXBlci5zZXRDYWxsYmFjayhjYWxsYmFjayk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgR2V0IHNldEZpZWxkcyhqYXZhLmxhbmcuU3RyaW5nIGZpZWxkcykgewogICAgICAgIHJldHVybiAoR2V0KSBzdXBlci5zZXRGaWVsZHMoZmllbGRzKTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBHZXQgc2V0S2V5KGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgcmV0dXJuIChHZXQpIHN1cGVyLnNldEtleShrZXkpOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIEdldCBzZXRPYXV0aFRva2VuKGphdmEubGFuZy5TdHJpbmcgb2F1dGhUb2tlbikgewogICAgICAgIHJldHVybiAoR2V0KSBzdXBlci5zZXRPYXV0aFRva2VuKG9hdXRoVG9rZW4pOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIEdldCBzZXRQcmV0dHlQcmludChqYXZhLmxhbmcuQm9vbGVhbiBwcmV0dHlQcmludCkgewogICAgICAgIHJldHVybiAoR2V0KSBzdXBlci5zZXRQcmV0dHlQcmludChwcmV0dHlQcmludCk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgR2V0IHNldFF1b3RhVXNlcihqYXZhLmxhbmcuU3RyaW5nIHF1b3RhVXNlcikgewogICAgICAgIHJldHVybiAoR2V0KSBzdXBlci5zZXRRdW90YVVzZXIocXVvdGFVc2VyKTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBHZXQgc2V0VXBsb2FkVHlwZShqYXZhLmxhbmcuU3RyaW5nIHVwbG9hZFR5cGUpIHsKICAgICAgICByZXR1cm4gKEdldCkgc3VwZXIuc2V0VXBsb2FkVHlwZSh1cGxvYWRUeXBlKTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBHZXQgc2V0VXBsb2FkUHJvdG9jb2woamF2YS5sYW5nLlN0cmluZyB1cGxvYWRQcm90b2NvbCkgewogICAgICAgIHJldHVybiAoR2V0KSBzdXBlci5zZXRVcGxvYWRQcm90b2NvbCh1cGxvYWRQcm90b2NvbCk7CiAgICAgIH0KCiAgICAgIC8qKgogICAgICAgKiBUaGUgUHJvamVjdCBJRCAoZm9yIGV4YW1wbGUsIGBteS1wcm9qZWN0LTEyM2ApLgogICAgICAgKgogICAgICAgKiBSZXF1aXJlZC4KICAgICAgICovCiAgICAgIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuU3RyaW5nIHByb2plY3RJZDsKCiAgICAgIC8qKiBUaGUgUHJvamVjdCBJRCAoZm9yIGV4YW1wbGUsIGBteS1wcm9qZWN0LTEyM2ApLgoKICAgICBSZXF1aXJlZC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFByb2plY3RJZCgpIHsKICAgICAgICByZXR1cm4gcHJvamVjdElkOwogICAgICB9CgogICAgICAvKioKICAgICAgICogVGhlIFByb2plY3QgSUQgKGZvciBleGFtcGxlLCBgbXktcHJvamVjdC0xMjNgKS4KICAgICAgICoKICAgICAgICogUmVxdWlyZWQuCiAgICAgICAqLwogICAgICBwdWJsaWMgR2V0IHNldFByb2plY3RJZChqYXZhLmxhbmcuU3RyaW5nIHByb2plY3RJZCkgewogICAgICAgIHRoaXMucHJvamVjdElkID0gcHJvamVjdElkOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIEdldCBzZXQoU3RyaW5nIHBhcmFtZXRlck5hbWUsIE9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiAoR2V0KSBzdXBlci5zZXQocGFyYW1ldGVyTmFtZSwgdmFsdWUpOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIEdldHMgYSBsaXN0IG9mIGFuY2VzdG9ycyBpbiB0aGUgcmVzb3VyY2UgaGllcmFyY2h5IGZvciB0aGUgUHJvamVjdCBpZGVudGlmaWVkIGJ5IHRoZSBzcGVjaWZpZWQKICAgICAqIGBwcm9qZWN0X2lkYCAoZm9yIGV4YW1wbGUsIGBteS1wcm9qZWN0LTEyM2ApLgogICAgICoKICAgICAqIFRoZSBjYWxsZXIgbXVzdCBoYXZlIHJlYWQgcGVybWlzc2lvbnMgZm9yIHRoaXMgUHJvamVjdC4KICAgICAqCiAgICAgKiBDcmVhdGUgYSByZXF1ZXN0IGZvciB0aGUgbWV0aG9kICJwcm9qZWN0cy5nZXRBbmNlc3RyeSIuCiAgICAgKgogICAgICogVGhpcyByZXF1ZXN0IGhvbGRzIHRoZSBwYXJhbWV0ZXJzIG5lZWRlZCBieSB0aGUgY2xvdWRyZXNvdXJjZW1hbmFnZXIgc2VydmVyLiAgQWZ0ZXIgc2V0dGluZyBhbnkKICAgICAqIG9wdGlvbmFsIHBhcmFtZXRlcnMsIGNhbGwgdGhlIHtAbGluayBHZXRBbmNlc3RyeSNleGVjdXRlKCl9IG1ldGhvZCB0byBpbnZva2UgdGhlIHJlbW90ZQogICAgICogb3BlcmF0aW9uLgogICAgICoKICAgICAqIEBwYXJhbSBwcm9qZWN0SWQgVGhlIFByb2plY3QgSUQgKGZvciBleGFtcGxlLCBgbXktcHJvamVjdC0xMjNgKS4KICAgIFJlcXVpcmVkLgogICAgICogQHBhcmFtIGNvbnRlbnQgdGhlIHtAbGluayBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5jbG91ZHJlc291cmNlbWFuYWdlci5tb2RlbC5HZXRBbmNlc3RyeVJlcXVlc3R9CiAgICAgKiBAcmV0dXJuIHRoZSByZXF1ZXN0CiAgICAgKi8KICAgIHB1YmxpYyBHZXRBbmNlc3RyeSBnZXRBbmNlc3RyeShqYXZhLmxhbmcuU3RyaW5nIHByb2plY3RJZCwgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuY2xvdWRyZXNvdXJjZW1hbmFnZXIubW9kZWwuR2V0QW5jZXN0cnlSZXF1ZXN0IGNvbnRlbnQpIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgR2V0QW5jZXN0cnkgcmVzdWx0ID0gbmV3IEdldEFuY2VzdHJ5KHByb2plY3RJZCwgY29udGVudCk7CiAgICAgIGluaXRpYWxpemUocmVzdWx0KTsKICAgICAgcmV0dXJuIHJlc3VsdDsKICAgIH0KCiAgICBwdWJsaWMgY2xhc3MgR2V0QW5jZXN0cnkgZXh0ZW5kcyBDbG91ZFJlc291cmNlTWFuYWdlclJlcXVlc3Q8Y29tLmdvb2dsZS5hcGkuc2VydmljZXMuY2xvdWRyZXNvdXJjZW1hbmFnZXIubW9kZWwuR2V0QW5jZXN0cnlSZXNwb25zZT4gewoKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFJFU1RfUEFUSCA9ICJ2MS9wcm9qZWN0cy97cHJvamVjdElkfTpnZXRBbmNlc3RyeSI7CgogICAgICAvKioKICAgICAgICogR2V0cyBhIGxpc3Qgb2YgYW5jZXN0b3JzIGluIHRoZSByZXNvdXJjZSBoaWVyYXJjaHkgZm9yIHRoZSBQcm9qZWN0IGlkZW50aWZpZWQgYnkgdGhlIHNwZWNpZmllZAogICAgICAgKiBgcHJvamVjdF9pZGAgKGZvciBleGFtcGxlLCBgbXktcHJvamVjdC0xMjNgKS4KICAgICAgICoKICAgICAgICogVGhlIGNhbGxlciBtdXN0IGhhdmUgcmVhZCBwZXJtaXNzaW9ucyBmb3IgdGhpcyBQcm9qZWN0LgogICAgICAgKgogICAgICAgKiBDcmVhdGUgYSByZXF1ZXN0IGZvciB0aGUgbWV0aG9kICJwcm9qZWN0cy5nZXRBbmNlc3RyeSIuCiAgICAgICAqCiAgICAgICAqIFRoaXMgcmVxdWVzdCBob2xkcyB0aGUgcGFyYW1ldGVycyBuZWVkZWQgYnkgdGhlIHRoZSBjbG91ZHJlc291cmNlbWFuYWdlciBzZXJ2ZXIuICBBZnRlciBzZXR0aW5nCiAgICAgICAqIGFueSBvcHRpb25hbCBwYXJhbWV0ZXJzLCBjYWxsIHRoZSB7QGxpbmsgR2V0QW5jZXN0cnkjZXhlY3V0ZSgpfSBtZXRob2QgdG8gaW52b2tlIHRoZSByZW1vdGUKICAgICAgICogb3BlcmF0aW9uLiA8cD4ge0BsaW5rCiAgICAgICAqIEdldEFuY2VzdHJ5I2luaXRpYWxpemUoY29tLmdvb2dsZS5hcGkuY2xpZW50Lmdvb2dsZWFwaXMuc2VydmljZXMuQWJzdHJhY3RHb29nbGVDbGllbnRSZXF1ZXN0KX0KICAgICAgICogbXVzdCBiZSBjYWxsZWQgdG8gaW5pdGlhbGl6ZSB0aGlzIGluc3RhbmNlIGltbWVkaWF0ZWx5IGFmdGVyIGludm9raW5nIHRoZSBjb25zdHJ1Y3Rvci4gPC9wPgogICAgICAgKgogICAgICAgKiBAcGFyYW0gcHJvamVjdElkIFRoZSBQcm9qZWN0IElEIChmb3IgZXhhbXBsZSwgYG15LXByb2plY3QtMTIzYCkuCiAgICBSZXF1aXJlZC4KICAgICAgICogQHBhcmFtIGNvbnRlbnQgdGhlIHtAbGluayBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5jbG91ZHJlc291cmNlbWFuYWdlci5tb2RlbC5HZXRBbmNlc3RyeVJlcXVlc3R9CiAgICAgICAqIEBzaW5jZSAxLjEzCiAgICAgICAqLwogICAgICBwcm90ZWN0ZWQgR2V0QW5jZXN0cnkoamF2YS5sYW5nLlN0cmluZyBwcm9qZWN0SWQsIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmNsb3VkcmVzb3VyY2VtYW5hZ2VyLm1vZGVsLkdldEFuY2VzdHJ5UmVxdWVzdCBjb250ZW50KSB7CiAgICAgICAgc3VwZXIoQ2xvdWRSZXNvdXJjZU1hbmFnZXIudGhpcywgIlBPU1QiLCBSRVNUX1BBVEgsIGNvbnRlbnQsIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmNsb3VkcmVzb3VyY2VtYW5hZ2VyLm1vZGVsLkdldEFuY2VzdHJ5UmVzcG9uc2UuY2xhc3MpOwogICAgICAgIHRoaXMucHJvamVjdElkID0gY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuUHJlY29uZGl0aW9ucy5jaGVja05vdE51bGwocHJvamVjdElkLCAiUmVxdWlyZWQgcGFyYW1ldGVyIHByb2plY3RJZCBtdXN0IGJlIHNwZWNpZmllZC4iKTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBHZXRBbmNlc3RyeSBzZXQkWGdhZnYoamF2YS5sYW5nLlN0cmluZyAkWGdhZnYpIHsKICAgICAgICByZXR1cm4gKEdldEFuY2VzdHJ5KSBzdXBlci5zZXQkWGdhZnYoJFhnYWZ2KTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBHZXRBbmNlc3RyeSBzZXRBY2Nlc3NUb2tlbihqYXZhLmxhbmcuU3RyaW5nIGFjY2Vzc1Rva2VuKSB7CiAgICAgICAgcmV0dXJuIChHZXRBbmNlc3RyeSkgc3VwZXIuc2V0QWNjZXNzVG9rZW4oYWNjZXNzVG9rZW4pOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIEdldEFuY2VzdHJ5IHNldEFsdChqYXZhLmxhbmcuU3RyaW5nIGFsdCkgewogICAgICAgIHJldHVybiAoR2V0QW5jZXN0cnkpIHN1cGVyLnNldEFsdChhbHQpOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIEdldEFuY2VzdHJ5IHNldENhbGxiYWNrKGphdmEubGFuZy5TdHJpbmcgY2FsbGJhY2spIHsKICAgICAgICByZXR1cm4gKEdldEFuY2VzdHJ5KSBzdXBlci5zZXRDYWxsYmFjayhjYWxsYmFjayk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgR2V0QW5jZXN0cnkgc2V0RmllbGRzKGphdmEubGFuZy5TdHJpbmcgZmllbGRzKSB7CiAgICAgICAgcmV0dXJuIChHZXRBbmNlc3RyeSkgc3VwZXIuc2V0RmllbGRzKGZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgR2V0QW5jZXN0cnkgc2V0S2V5KGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgcmV0dXJuIChHZXRBbmNlc3RyeSkgc3VwZXIuc2V0S2V5KGtleSk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgR2V0QW5jZXN0cnkgc2V0T2F1dGhUb2tlbihqYXZhLmxhbmcuU3RyaW5nIG9hdXRoVG9rZW4pIHsKICAgICAgICByZXR1cm4gKEdldEFuY2VzdHJ5KSBzdXBlci5zZXRPYXV0aFRva2VuKG9hdXRoVG9rZW4pOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIEdldEFuY2VzdHJ5IHNldFByZXR0eVByaW50KGphdmEubGFuZy5Cb29sZWFuIHByZXR0eVByaW50KSB7CiAgICAgICAgcmV0dXJuIChHZXRBbmNlc3RyeSkgc3VwZXIuc2V0UHJldHR5UHJpbnQocHJldHR5UHJpbnQpOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIEdldEFuY2VzdHJ5IHNldFF1b3RhVXNlcihqYXZhLmxhbmcuU3RyaW5nIHF1b3RhVXNlcikgewogICAgICAgIHJldHVybiAoR2V0QW5jZXN0cnkpIHN1cGVyLnNldFF1b3RhVXNlcihxdW90YVVzZXIpOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIEdldEFuY2VzdHJ5IHNldFVwbG9hZFR5cGUoamF2YS5sYW5nLlN0cmluZyB1cGxvYWRUeXBlKSB7CiAgICAgICAgcmV0dXJuIChHZXRBbmNlc3RyeSkgc3VwZXIuc2V0VXBsb2FkVHlwZSh1cGxvYWRUeXBlKTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBHZXRBbmNlc3RyeSBzZXRVcGxvYWRQcm90b2NvbChqYXZhLmxhbmcuU3RyaW5nIHVwbG9hZFByb3RvY29sKSB7CiAgICAgICAgcmV0dXJuIChHZXRBbmNlc3RyeSkgc3VwZXIuc2V0VXBsb2FkUHJvdG9jb2wodXBsb2FkUHJvdG9jb2wpOwogICAgICB9CgogICAgICAvKioKICAgICAgICogVGhlIFByb2plY3QgSUQgKGZvciBleGFtcGxlLCBgbXktcHJvamVjdC0xMjNgKS4KICAgICAgICoKICAgICAgICogUmVxdWlyZWQuCiAgICAgICAqLwogICAgICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgICAgIHByaXZhdGUgamF2YS5sYW5nLlN0cmluZyBwcm9qZWN0SWQ7CgogICAgICAvKiogVGhlIFByb2plY3QgSUQgKGZvciBleGFtcGxlLCBgbXktcHJvamVjdC0xMjNgKS4KCiAgICAgUmVxdWlyZWQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRQcm9qZWN0SWQoKSB7CiAgICAgICAgcmV0dXJuIHByb2plY3RJZDsKICAgICAgfQoKICAgICAgLyoqCiAgICAgICAqIFRoZSBQcm9qZWN0IElEIChmb3IgZXhhbXBsZSwgYG15LXByb2plY3QtMTIzYCkuCiAgICAgICAqCiAgICAgICAqIFJlcXVpcmVkLgogICAgICAgKi8KICAgICAgcHVibGljIEdldEFuY2VzdHJ5IHNldFByb2plY3RJZChqYXZhLmxhbmcuU3RyaW5nIHByb2plY3RJZCkgewogICAgICAgIHRoaXMucHJvamVjdElkID0gcHJvamVjdElkOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIEdldEFuY2VzdHJ5IHNldChTdHJpbmcgcGFyYW1ldGVyTmFtZSwgT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIChHZXRBbmNlc3RyeSkgc3VwZXIuc2V0KHBhcmFtZXRlck5hbWUsIHZhbHVlKTsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiBHZXRzIHRoZSBlZmZlY3RpdmUgYFBvbGljeWAgb24gYSByZXNvdXJjZS4gVGhpcyBpcyB0aGUgcmVzdWx0IG9mIG1lcmdpbmcgYFBvbGljaWVzYCBpbiB0aGUKICAgICAqIHJlc291cmNlIGhpZXJhcmNoeS4gVGhlIHJldHVybmVkIGBQb2xpY3lgIHdpbGwgbm90IGhhdmUgYW4gYGV0YWdgc2V0IGJlY2F1c2UgaXQgaXMgYSBjb21wdXRlZAogICAgICogYFBvbGljeWAgYWNyb3NzIG11bHRpcGxlIHJlc291cmNlcy4gU3VidHJlZXMgb2YgUmVzb3VyY2UgTWFuYWdlciByZXNvdXJjZSBoaWVyYXJjaHkgd2l0aCAndW5kZXI6JwogICAgICogcHJlZml4IHdpbGwgbm90IGJlIGV4cGFuZGVkLgogICAgICoKICAgICAqIENyZWF0ZSBhIHJlcXVlc3QgZm9yIHRoZSBtZXRob2QgInByb2plY3RzLmdldEVmZmVjdGl2ZU9yZ1BvbGljeSIuCiAgICAgKgogICAgICogVGhpcyByZXF1ZXN0IGhvbGRzIHRoZSBwYXJhbWV0ZXJzIG5lZWRlZCBieSB0aGUgY2xvdWRyZXNvdXJjZW1hbmFnZXIgc2VydmVyLiAgQWZ0ZXIgc2V0dGluZyBhbnkKICAgICAqIG9wdGlvbmFsIHBhcmFtZXRlcnMsIGNhbGwgdGhlIHtAbGluayBHZXRFZmZlY3RpdmVPcmdQb2xpY3kjZXhlY3V0ZSgpfSBtZXRob2QgdG8gaW52b2tlIHRoZSByZW1vdGUKICAgICAqIG9wZXJhdGlvbi4KICAgICAqCiAgICAgKiBAcGFyYW0gcmVzb3VyY2UgVGhlIG5hbWUgb2YgdGhlIHJlc291cmNlIHRvIHN0YXJ0IGNvbXB1dGluZyB0aGUgZWZmZWN0aXZlIGBQb2xpY3lgLgogICAgICogQHBhcmFtIGNvbnRlbnQgdGhlIHtAbGluayBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5jbG91ZHJlc291cmNlbWFuYWdlci5tb2RlbC5HZXRFZmZlY3RpdmVPcmdQb2xpY3lSZXF1ZXN0fQogICAgICogQHJldHVybiB0aGUgcmVxdWVzdAogICAgICovCiAgICBwdWJsaWMgR2V0RWZmZWN0aXZlT3JnUG9saWN5IGdldEVmZmVjdGl2ZU9yZ1BvbGljeShqYXZhLmxhbmcuU3RyaW5nIHJlc291cmNlLCBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5jbG91ZHJlc291cmNlbWFuYWdlci5tb2RlbC5HZXRFZmZlY3RpdmVPcmdQb2xpY3lSZXF1ZXN0IGNvbnRlbnQpIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgR2V0RWZmZWN0aXZlT3JnUG9saWN5IHJlc3VsdCA9IG5ldyBHZXRFZmZlY3RpdmVPcmdQb2xpY3kocmVzb3VyY2UsIGNvbnRlbnQpOwogICAgICBpbml0aWFsaXplKHJlc3VsdCk7CiAgICAgIHJldHVybiByZXN1bHQ7CiAgICB9CgogICAgcHVibGljIGNsYXNzIEdldEVmZmVjdGl2ZU9yZ1BvbGljeSBleHRlbmRzIENsb3VkUmVzb3VyY2VNYW5hZ2VyUmVxdWVzdDxjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5jbG91ZHJlc291cmNlbWFuYWdlci5tb2RlbC5PcmdQb2xpY3k+IHsKCiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBSRVNUX1BBVEggPSAidjEveytyZXNvdXJjZX06Z2V0RWZmZWN0aXZlT3JnUG9saWN5IjsKCiAgICAgIHByaXZhdGUgZmluYWwgamF2YS51dGlsLnJlZ2V4LlBhdHRlcm4gUkVTT1VSQ0VfUEFUVEVSTiA9CiAgICAgICAgICBqYXZhLnV0aWwucmVnZXguUGF0dGVybi5jb21waWxlKCJecHJvamVjdHMvW14vXSskIik7CgogICAgICAvKioKICAgICAgICogR2V0cyB0aGUgZWZmZWN0aXZlIGBQb2xpY3lgIG9uIGEgcmVzb3VyY2UuIFRoaXMgaXMgdGhlIHJlc3VsdCBvZiBtZXJnaW5nIGBQb2xpY2llc2AgaW4gdGhlCiAgICAgICAqIHJlc291cmNlIGhpZXJhcmNoeS4gVGhlIHJldHVybmVkIGBQb2xpY3lgIHdpbGwgbm90IGhhdmUgYW4gYGV0YWdgc2V0IGJlY2F1c2UgaXQgaXMgYSBjb21wdXRlZAogICAgICAgKiBgUG9saWN5YCBhY3Jvc3MgbXVsdGlwbGUgcmVzb3VyY2VzLiBTdWJ0cmVlcyBvZiBSZXNvdXJjZSBNYW5hZ2VyIHJlc291cmNlIGhpZXJhcmNoeSB3aXRoCiAgICAgICAqICd1bmRlcjonIHByZWZpeCB3aWxsIG5vdCBiZSBleHBhbmRlZC4KICAgICAgICoKICAgICAgICogQ3JlYXRlIGEgcmVxdWVzdCBmb3IgdGhlIG1ldGhvZCAicHJvamVjdHMuZ2V0RWZmZWN0aXZlT3JnUG9saWN5Ii4KICAgICAgICoKICAgICAgICogVGhpcyByZXF1ZXN0IGhvbGRzIHRoZSBwYXJhbWV0ZXJzIG5lZWRlZCBieSB0aGUgdGhlIGNsb3VkcmVzb3VyY2VtYW5hZ2VyIHNlcnZlci4gIEFmdGVyIHNldHRpbmcKICAgICAgICogYW55IG9wdGlvbmFsIHBhcmFtZXRlcnMsIGNhbGwgdGhlIHtAbGluayBHZXRFZmZlY3RpdmVPcmdQb2xpY3kjZXhlY3V0ZSgpfSBtZXRob2QgdG8gaW52b2tlIHRoZQogICAgICAgKiByZW1vdGUgb3BlcmF0aW9uLiA8cD4ge0BsaW5rIEdldEVmZmVjdGl2ZU9yZ1BvbGljeSNpbml0aWFsaXplKGNvbS5nb29nbGUuYXBpLmNsaWVudC5nb29nbGVhcGlzLgogICAgICAgKiBzZXJ2aWNlcy5BYnN0cmFjdEdvb2dsZUNsaWVudFJlcXVlc3QpfSBtdXN0IGJlIGNhbGxlZCB0byBpbml0aWFsaXplIHRoaXMgaW5zdGFuY2UgaW1tZWRpYXRlbHkKICAgICAgICogYWZ0ZXIgaW52b2tpbmcgdGhlIGNvbnN0cnVjdG9yLiA8L3A+CiAgICAgICAqCiAgICAgICAqIEBwYXJhbSByZXNvdXJjZSBUaGUgbmFtZSBvZiB0aGUgcmVzb3VyY2UgdG8gc3RhcnQgY29tcHV0aW5nIHRoZSBlZmZlY3RpdmUgYFBvbGljeWAuCiAgICAgICAqIEBwYXJhbSBjb250ZW50IHRoZSB7QGxpbmsgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuY2xvdWRyZXNvdXJjZW1hbmFnZXIubW9kZWwuR2V0RWZmZWN0aXZlT3JnUG9saWN5UmVxdWVzdH0KICAgICAgICogQHNpbmNlIDEuMTMKICAgICAgICovCiAgICAgIHByb3RlY3RlZCBHZXRFZmZlY3RpdmVPcmdQb2xpY3koamF2YS5sYW5nLlN0cmluZyByZXNvdXJjZSwgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuY2xvdWRyZXNvdXJjZW1hbmFnZXIubW9kZWwuR2V0RWZmZWN0aXZlT3JnUG9saWN5UmVxdWVzdCBjb250ZW50KSB7CiAgICAgICAgc3VwZXIoQ2xvdWRSZXNvdXJjZU1hbmFnZXIudGhpcywgIlBPU1QiLCBSRVNUX1BBVEgsIGNvbnRlbnQsIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmNsb3VkcmVzb3VyY2VtYW5hZ2VyLm1vZGVsLk9yZ1BvbGljeS5jbGFzcyk7CiAgICAgICAgdGhpcy5yZXNvdXJjZSA9IGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLlByZWNvbmRpdGlvbnMuY2hlY2tOb3ROdWxsKHJlc291cmNlLCAiUmVxdWlyZWQgcGFyYW1ldGVyIHJlc291cmNlIG11c3QgYmUgc3BlY2lmaWVkLiIpOwogICAgICAgIGlmICghZ2V0U3VwcHJlc3NQYXR0ZXJuQ2hlY2tzKCkpIHsKICAgICAgICAgIGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLlByZWNvbmRpdGlvbnMuY2hlY2tBcmd1bWVudChSRVNPVVJDRV9QQVRURVJOLm1hdGNoZXIocmVzb3VyY2UpLm1hdGNoZXMoKSwKICAgICAgICAgICAgICAiUGFyYW1ldGVyIHJlc291cmNlIG11c3QgY29uZm9ybSB0byB0aGUgcGF0dGVybiAiICsKICAgICAgICAgICAgICAiXnByb2plY3RzL1teL10rJCIpOwogICAgICAgIH0KICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBHZXRFZmZlY3RpdmVPcmdQb2xpY3kgc2V0JFhnYWZ2KGphdmEubGFuZy5TdHJpbmcgJFhnYWZ2KSB7CiAgICAgICAgcmV0dXJuIChHZXRFZmZlY3RpdmVPcmdQb2xpY3kpIHN1cGVyLnNldCRYZ2FmdigkWGdhZnYpOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIEdldEVmZmVjdGl2ZU9yZ1BvbGljeSBzZXRBY2Nlc3NUb2tlbihqYXZhLmxhbmcuU3RyaW5nIGFjY2Vzc1Rva2VuKSB7CiAgICAgICAgcmV0dXJuIChHZXRFZmZlY3RpdmVPcmdQb2xpY3kpIHN1cGVyLnNldEFjY2Vzc1Rva2VuKGFjY2Vzc1Rva2VuKTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBHZXRFZmZlY3RpdmVPcmdQb2xpY3kgc2V0QWx0KGphdmEubGFuZy5TdHJpbmcgYWx0KSB7CiAgICAgICAgcmV0dXJuIChHZXRFZmZlY3RpdmVPcmdQb2xpY3kpIHN1cGVyLnNldEFsdChhbHQpOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIEdldEVmZmVjdGl2ZU9yZ1BvbGljeSBzZXRDYWxsYmFjayhqYXZhLmxhbmcuU3RyaW5nIGNhbGxiYWNrKSB7CiAgICAgICAgcmV0dXJuIChHZXRFZmZlY3RpdmVPcmdQb2xpY3kpIHN1cGVyLnNldENhbGxiYWNrKGNhbGxiYWNrKTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBHZXRFZmZlY3RpdmVPcmdQb2xpY3kgc2V0RmllbGRzKGphdmEubGFuZy5TdHJpbmcgZmllbGRzKSB7CiAgICAgICAgcmV0dXJuIChHZXRFZmZlY3RpdmVPcmdQb2xpY3kpIHN1cGVyLnNldEZpZWxkcyhmaWVsZHMpOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIEdldEVmZmVjdGl2ZU9yZ1BvbGljeSBzZXRLZXkoamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICByZXR1cm4gKEdldEVmZmVjdGl2ZU9yZ1BvbGljeSkgc3VwZXIuc2V0S2V5KGtleSk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgR2V0RWZmZWN0aXZlT3JnUG9saWN5IHNldE9hdXRoVG9rZW4oamF2YS5sYW5nLlN0cmluZyBvYXV0aFRva2VuKSB7CiAgICAgICAgcmV0dXJuIChHZXRFZmZlY3RpdmVPcmdQb2xpY3kpIHN1cGVyLnNldE9hdXRoVG9rZW4ob2F1dGhUb2tlbik7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgR2V0RWZmZWN0aXZlT3JnUG9saWN5IHNldFByZXR0eVByaW50KGphdmEubGFuZy5Cb29sZWFuIHByZXR0eVByaW50KSB7CiAgICAgICAgcmV0dXJuIChHZXRFZmZlY3RpdmVPcmdQb2xpY3kpIHN1cGVyLnNldFByZXR0eVByaW50KHByZXR0eVByaW50KTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBHZXRFZmZlY3RpdmVPcmdQb2xpY3kgc2V0UXVvdGFVc2VyKGphdmEubGFuZy5TdHJpbmcgcXVvdGFVc2VyKSB7CiAgICAgICAgcmV0dXJuIChHZXRFZmZlY3RpdmVPcmdQb2xpY3kpIHN1cGVyLnNldFF1b3RhVXNlcihxdW90YVVzZXIpOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIEdldEVmZmVjdGl2ZU9yZ1BvbGljeSBzZXRVcGxvYWRUeXBlKGphdmEubGFuZy5TdHJpbmcgdXBsb2FkVHlwZSkgewogICAgICAgIHJldHVybiAoR2V0RWZmZWN0aXZlT3JnUG9saWN5KSBzdXBlci5zZXRVcGxvYWRUeXBlKHVwbG9hZFR5cGUpOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIEdldEVmZmVjdGl2ZU9yZ1BvbGljeSBzZXRVcGxvYWRQcm90b2NvbChqYXZhLmxhbmcuU3RyaW5nIHVwbG9hZFByb3RvY29sKSB7CiAgICAgICAgcmV0dXJuIChHZXRFZmZlY3RpdmVPcmdQb2xpY3kpIHN1cGVyLnNldFVwbG9hZFByb3RvY29sKHVwbG9hZFByb3RvY29sKTsKICAgICAgfQoKICAgICAgLyoqIFRoZSBuYW1lIG9mIHRoZSByZXNvdXJjZSB0byBzdGFydCBjb21wdXRpbmcgdGhlIGVmZmVjdGl2ZSBgUG9saWN5YC4gKi8KICAgICAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogICAgICBwcml2YXRlIGphdmEubGFuZy5TdHJpbmcgcmVzb3VyY2U7CgogICAgICAvKiogVGhlIG5hbWUgb2YgdGhlIHJlc291cmNlIHRvIHN0YXJ0IGNvbXB1dGluZyB0aGUgZWZmZWN0aXZlIGBQb2xpY3lgLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0UmVzb3VyY2UoKSB7CiAgICAgICAgcmV0dXJuIHJlc291cmNlOwogICAgICB9CgogICAgICAvKiogVGhlIG5hbWUgb2YgdGhlIHJlc291cmNlIHRvIHN0YXJ0IGNvbXB1dGluZyB0aGUgZWZmZWN0aXZlIGBQb2xpY3lgLiAqLwogICAgICBwdWJsaWMgR2V0RWZmZWN0aXZlT3JnUG9saWN5IHNldFJlc291cmNlKGphdmEubGFuZy5TdHJpbmcgcmVzb3VyY2UpIHsKICAgICAgICBpZiAoIWdldFN1cHByZXNzUGF0dGVybkNoZWNrcygpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5QcmVjb25kaXRpb25zLmNoZWNrQXJndW1lbnQoUkVTT1VSQ0VfUEFUVEVSTi5tYXRjaGVyKHJlc291cmNlKS5tYXRjaGVzKCksCiAgICAgICAgICAgICAgIlBhcmFtZXRlciByZXNvdXJjZSBtdXN0IGNvbmZvcm0gdG8gdGhlIHBhdHRlcm4gIiArCiAgICAgICAgICAgICAgIl5wcm9qZWN0cy9bXi9dKyQiKTsKICAgICAgICB9CiAgICAgICAgdGhpcy5yZXNvdXJjZSA9IHJlc291cmNlOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIEdldEVmZmVjdGl2ZU9yZ1BvbGljeSBzZXQoU3RyaW5nIHBhcmFtZXRlck5hbWUsIE9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiAoR2V0RWZmZWN0aXZlT3JnUG9saWN5KSBzdXBlci5zZXQocGFyYW1ldGVyTmFtZSwgdmFsdWUpOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIElBTSBhY2Nlc3MgY29udHJvbCBwb2xpY3kgZm9yIHRoZSBzcGVjaWZpZWQgUHJvamVjdC4gUGVybWlzc2lvbiBpcyBkZW5pZWQgaWYgdGhlCiAgICAgKiBwb2xpY3kgb3IgdGhlIHJlc291cmNlIGRvZXMgbm90IGV4aXN0LgogICAgICoKICAgICAqIEF1dGhvcml6YXRpb24gcmVxdWlyZXMgdGhlIEdvb2dsZSBJQU0gcGVybWlzc2lvbiBgcmVzb3VyY2VtYW5hZ2VyLnByb2plY3RzLmdldElhbVBvbGljeWAgb24gdGhlCiAgICAgKiBwcm9qZWN0LgogICAgICoKICAgICAqIEZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIGFib3V0IHJlc291cmNlIHN0cnVjdHVyZSBhbmQgaWRlbnRpZmljYXRpb24sIHNlZSBbUmVzb3VyY2UKICAgICAqIE5hbWVzXSgvYXBpcy9kZXNpZ24vcmVzb3VyY2VfbmFtZXMpLgogICAgICoKICAgICAqIENyZWF0ZSBhIHJlcXVlc3QgZm9yIHRoZSBtZXRob2QgInByb2plY3RzLmdldElhbVBvbGljeSIuCiAgICAgKgogICAgICogVGhpcyByZXF1ZXN0IGhvbGRzIHRoZSBwYXJhbWV0ZXJzIG5lZWRlZCBieSB0aGUgY2xvdWRyZXNvdXJjZW1hbmFnZXIgc2VydmVyLiAgQWZ0ZXIgc2V0dGluZyBhbnkKICAgICAqIG9wdGlvbmFsIHBhcmFtZXRlcnMsIGNhbGwgdGhlIHtAbGluayBHZXRJYW1Qb2xpY3kjZXhlY3V0ZSgpfSBtZXRob2QgdG8gaW52b2tlIHRoZSByZW1vdGUKICAgICAqIG9wZXJhdGlvbi4KICAgICAqCiAgICAgKiBAcGFyYW0gcmVzb3VyY2UgUkVRVUlSRUQ6IFRoZSByZXNvdXJjZSBmb3Igd2hpY2ggdGhlIHBvbGljeSBpcyBiZWluZyByZXF1ZXN0ZWQuCiAgICBTZWUgdGhlIG9wZXJhdGlvbiBkb2N1bWVudGF0aW9uIGZvcgogICAgICogICAgICAgIHRoZSBhcHByb3ByaWF0ZSB2YWx1ZSBmb3IgdGhpcyBmaWVsZC4KICAgICAqIEBwYXJhbSBjb250ZW50IHRoZSB7QGxpbmsgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuY2xvdWRyZXNvdXJjZW1hbmFnZXIubW9kZWwuR2V0SWFtUG9saWN5UmVxdWVzdH0KICAgICAqIEByZXR1cm4gdGhlIHJlcXVlc3QKICAgICAqLwogICAgcHVibGljIEdldElhbVBvbGljeSBnZXRJYW1Qb2xpY3koamF2YS5sYW5nLlN0cmluZyByZXNvdXJjZSwgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuY2xvdWRyZXNvdXJjZW1hbmFnZXIubW9kZWwuR2V0SWFtUG9saWN5UmVxdWVzdCBjb250ZW50KSB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIEdldElhbVBvbGljeSByZXN1bHQgPSBuZXcgR2V0SWFtUG9saWN5KHJlc291cmNlLCBjb250ZW50KTsKICAgICAgaW5pdGlhbGl6ZShyZXN1bHQpOwogICAgICByZXR1cm4gcmVzdWx0OwogICAgfQoKICAgIHB1YmxpYyBjbGFzcyBHZXRJYW1Qb2xpY3kgZXh0ZW5kcyBDbG91ZFJlc291cmNlTWFuYWdlclJlcXVlc3Q8Y29tLmdvb2dsZS5hcGkuc2VydmljZXMuY2xvdWRyZXNvdXJjZW1hbmFnZXIubW9kZWwuUG9saWN5PiB7CgogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgUkVTVF9QQVRIID0gInYxL3Byb2plY3RzL3tyZXNvdXJjZX06Z2V0SWFtUG9saWN5IjsKCiAgICAgIC8qKgogICAgICAgKiBSZXR1cm5zIHRoZSBJQU0gYWNjZXNzIGNvbnRyb2wgcG9saWN5IGZvciB0aGUgc3BlY2lmaWVkIFByb2plY3QuIFBlcm1pc3Npb24gaXMgZGVuaWVkIGlmIHRoZQogICAgICAgKiBwb2xpY3kgb3IgdGhlIHJlc291cmNlIGRvZXMgbm90IGV4aXN0LgogICAgICAgKgogICAgICAgKiBBdXRob3JpemF0aW9uIHJlcXVpcmVzIHRoZSBHb29nbGUgSUFNIHBlcm1pc3Npb24gYHJlc291cmNlbWFuYWdlci5wcm9qZWN0cy5nZXRJYW1Qb2xpY3lgIG9uIHRoZQogICAgICAgKiBwcm9qZWN0LgogICAgICAgKgogICAgICAgKiBGb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBhYm91dCByZXNvdXJjZSBzdHJ1Y3R1cmUgYW5kIGlkZW50aWZpY2F0aW9uLCBzZWUgW1Jlc291cmNlCiAgICAgICAqIE5hbWVzXSgvYXBpcy9kZXNpZ24vcmVzb3VyY2VfbmFtZXMpLgogICAgICAgKgogICAgICAgKiBDcmVhdGUgYSByZXF1ZXN0IGZvciB0aGUgbWV0aG9kICJwcm9qZWN0cy5nZXRJYW1Qb2xpY3kiLgogICAgICAgKgogICAgICAgKiBUaGlzIHJlcXVlc3QgaG9sZHMgdGhlIHBhcmFtZXRlcnMgbmVlZGVkIGJ5IHRoZSB0aGUgY2xvdWRyZXNvdXJjZW1hbmFnZXIgc2VydmVyLiAgQWZ0ZXIgc2V0dGluZwogICAgICAgKiBhbnkgb3B0aW9uYWwgcGFyYW1ldGVycywgY2FsbCB0aGUge0BsaW5rIEdldElhbVBvbGljeSNleGVjdXRlKCl9IG1ldGhvZCB0byBpbnZva2UgdGhlIHJlbW90ZQogICAgICAgKiBvcGVyYXRpb24uIDxwPiB7QGxpbmsKICAgICAgICogR2V0SWFtUG9saWN5I2luaXRpYWxpemUoY29tLmdvb2dsZS5hcGkuY2xpZW50Lmdvb2dsZWFwaXMuc2VydmljZXMuQWJzdHJhY3RHb29nbGVDbGllbnRSZXF1ZXN0KX0KICAgICAgICogbXVzdCBiZSBjYWxsZWQgdG8gaW5pdGlhbGl6ZSB0aGlzIGluc3RhbmNlIGltbWVkaWF0ZWx5IGFmdGVyIGludm9raW5nIHRoZSBjb25zdHJ1Y3Rvci4gPC9wPgogICAgICAgKgogICAgICAgKiBAcGFyYW0gcmVzb3VyY2UgUkVRVUlSRUQ6IFRoZSByZXNvdXJjZSBmb3Igd2hpY2ggdGhlIHBvbGljeSBpcyBiZWluZyByZXF1ZXN0ZWQuCiAgICBTZWUgdGhlIG9wZXJhdGlvbiBkb2N1bWVudGF0aW9uIGZvcgogICAgICogICAgICAgIHRoZSBhcHByb3ByaWF0ZSB2YWx1ZSBmb3IgdGhpcyBmaWVsZC4KICAgICAgICogQHBhcmFtIGNvbnRlbnQgdGhlIHtAbGluayBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5jbG91ZHJlc291cmNlbWFuYWdlci5tb2RlbC5HZXRJYW1Qb2xpY3lSZXF1ZXN0fQogICAgICAgKiBAc2luY2UgMS4xMwogICAgICAgKi8KICAgICAgcHJvdGVjdGVkIEdldElhbVBvbGljeShqYXZhLmxhbmcuU3RyaW5nIHJlc291cmNlLCBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5jbG91ZHJlc291cmNlbWFuYWdlci5tb2RlbC5HZXRJYW1Qb2xpY3lSZXF1ZXN0IGNvbnRlbnQpIHsKICAgICAgICBzdXBlcihDbG91ZFJlc291cmNlTWFuYWdlci50aGlzLCAiUE9TVCIsIFJFU1RfUEFUSCwgY29udGVudCwgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuY2xvdWRyZXNvdXJjZW1hbmFnZXIubW9kZWwuUG9saWN5LmNsYXNzKTsKICAgICAgICB0aGlzLnJlc291cmNlID0gY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuUHJlY29uZGl0aW9ucy5jaGVja05vdE51bGwocmVzb3VyY2UsICJSZXF1aXJlZCBwYXJhbWV0ZXIgcmVzb3VyY2UgbXVzdCBiZSBzcGVjaWZpZWQuIik7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgR2V0SWFtUG9saWN5IHNldCRYZ2FmdihqYXZhLmxhbmcuU3RyaW5nICRYZ2FmdikgewogICAgICAgIHJldHVybiAoR2V0SWFtUG9saWN5KSBzdXBlci5zZXQkWGdhZnYoJFhnYWZ2KTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBHZXRJYW1Qb2xpY3kgc2V0QWNjZXNzVG9rZW4oamF2YS5sYW5nLlN0cmluZyBhY2Nlc3NUb2tlbikgewogICAgICAgIHJldHVybiAoR2V0SWFtUG9saWN5KSBzdXBlci5zZXRBY2Nlc3NUb2tlbihhY2Nlc3NUb2tlbik7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgR2V0SWFtUG9saWN5IHNldEFsdChqYXZhLmxhbmcuU3RyaW5nIGFsdCkgewogICAgICAgIHJldHVybiAoR2V0SWFtUG9saWN5KSBzdXBlci5zZXRBbHQoYWx0KTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBHZXRJYW1Qb2xpY3kgc2V0Q2FsbGJhY2soamF2YS5sYW5nLlN0cmluZyBjYWxsYmFjaykgewogICAgICAgIHJldHVybiAoR2V0SWFtUG9saWN5KSBzdXBlci5zZXRDYWxsYmFjayhjYWxsYmFjayk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgR2V0SWFtUG9saWN5IHNldEZpZWxkcyhqYXZhLmxhbmcuU3RyaW5nIGZpZWxkcykgewogICAgICAgIHJldHVybiAoR2V0SWFtUG9saWN5KSBzdXBlci5zZXRGaWVsZHMoZmllbGRzKTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBHZXRJYW1Qb2xpY3kgc2V0S2V5KGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgcmV0dXJuIChHZXRJYW1Qb2xpY3kpIHN1cGVyLnNldEtleShrZXkpOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIEdldElhbVBvbGljeSBzZXRPYXV0aFRva2VuKGphdmEubGFuZy5TdHJpbmcgb2F1dGhUb2tlbikgewogICAgICAgIHJldHVybiAoR2V0SWFtUG9saWN5KSBzdXBlci5zZXRPYXV0aFRva2VuKG9hdXRoVG9rZW4pOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIEdldElhbVBvbGljeSBzZXRQcmV0dHlQcmludChqYXZhLmxhbmcuQm9vbGVhbiBwcmV0dHlQcmludCkgewogICAgICAgIHJldHVybiAoR2V0SWFtUG9saWN5KSBzdXBlci5zZXRQcmV0dHlQcmludChwcmV0dHlQcmludCk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgR2V0SWFtUG9saWN5IHNldFF1b3RhVXNlcihqYXZhLmxhbmcuU3RyaW5nIHF1b3RhVXNlcikgewogICAgICAgIHJldHVybiAoR2V0SWFtUG9saWN5KSBzdXBlci5zZXRRdW90YVVzZXIocXVvdGFVc2VyKTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBHZXRJYW1Qb2xpY3kgc2V0VXBsb2FkVHlwZShqYXZhLmxhbmcuU3RyaW5nIHVwbG9hZFR5cGUpIHsKICAgICAgICByZXR1cm4gKEdldElhbVBvbGljeSkgc3VwZXIuc2V0VXBsb2FkVHlwZSh1cGxvYWRUeXBlKTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBHZXRJYW1Qb2xpY3kgc2V0VXBsb2FkUHJvdG9jb2woamF2YS5sYW5nLlN0cmluZyB1cGxvYWRQcm90b2NvbCkgewogICAgICAgIHJldHVybiAoR2V0SWFtUG9saWN5KSBzdXBlci5zZXRVcGxvYWRQcm90b2NvbCh1cGxvYWRQcm90b2NvbCk7CiAgICAgIH0KCiAgICAgIC8qKgogICAgICAgKiBSRVFVSVJFRDogVGhlIHJlc291cmNlIGZvciB3aGljaCB0aGUgcG9saWN5IGlzIGJlaW5nIHJlcXVlc3RlZC4gU2VlIHRoZSBvcGVyYXRpb24KICAgICAgICogZG9jdW1lbnRhdGlvbiBmb3IgdGhlIGFwcHJvcHJpYXRlIHZhbHVlIGZvciB0aGlzIGZpZWxkLgogICAgICAgKi8KICAgICAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogICAgICBwcml2YXRlIGphdmEubGFuZy5TdHJpbmcgcmVzb3VyY2U7CgogICAgICAvKiogUkVRVUlSRUQ6IFRoZSByZXNvdXJjZSBmb3Igd2hpY2ggdGhlIHBvbGljeSBpcyBiZWluZyByZXF1ZXN0ZWQuIFNlZSB0aGUgb3BlcmF0aW9uIGRvY3VtZW50YXRpb24gZm9yCiAgICAgdGhlIGFwcHJvcHJpYXRlIHZhbHVlIGZvciB0aGlzIGZpZWxkLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0UmVzb3VyY2UoKSB7CiAgICAgICAgcmV0dXJuIHJlc291cmNlOwogICAgICB9CgogICAgICAvKioKICAgICAgICogUkVRVUlSRUQ6IFRoZSByZXNvdXJjZSBmb3Igd2hpY2ggdGhlIHBvbGljeSBpcyBiZWluZyByZXF1ZXN0ZWQuIFNlZSB0aGUgb3BlcmF0aW9uCiAgICAgICAqIGRvY3VtZW50YXRpb24gZm9yIHRoZSBhcHByb3ByaWF0ZSB2YWx1ZSBmb3IgdGhpcyBmaWVsZC4KICAgICAgICovCiAgICAgIHB1YmxpYyBHZXRJYW1Qb2xpY3kgc2V0UmVzb3VyY2UoamF2YS5sYW5nLlN0cmluZyByZXNvdXJjZSkgewogICAgICAgIHRoaXMucmVzb3VyY2UgPSByZXNvdXJjZTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBHZXRJYW1Qb2xpY3kgc2V0KFN0cmluZyBwYXJhbWV0ZXJOYW1lLCBPYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gKEdldElhbVBvbGljeSkgc3VwZXIuc2V0KHBhcmFtZXRlck5hbWUsIHZhbHVlKTsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiBHZXRzIGEgYFBvbGljeWAgb24gYSByZXNvdXJjZS4KICAgICAqCiAgICAgKiBJZiBubyBgUG9saWN5YCBpcyBzZXQgb24gdGhlIHJlc291cmNlLCBhIGBQb2xpY3lgIGlzIHJldHVybmVkIHdpdGggZGVmYXVsdCB2YWx1ZXMgaW5jbHVkaW5nCiAgICAgKiBgUE9MSUNZX1RZUEVfTk9UX1NFVGAgZm9yIHRoZSBgcG9saWN5X3R5cGUgb25lb2ZgLiBUaGUgYGV0YWdgIHZhbHVlIGNhbiBiZSB1c2VkIHdpdGgKICAgICAqIGBTZXRPcmdQb2xpY3koKWAgdG8gY3JlYXRlIG9yIHVwZGF0ZSBhIGBQb2xpY3lgIGR1cmluZyByZWFkLW1vZGlmeS13cml0ZS4KICAgICAqCiAgICAgKiBDcmVhdGUgYSByZXF1ZXN0IGZvciB0aGUgbWV0aG9kICJwcm9qZWN0cy5nZXRPcmdQb2xpY3kiLgogICAgICoKICAgICAqIFRoaXMgcmVxdWVzdCBob2xkcyB0aGUgcGFyYW1ldGVycyBuZWVkZWQgYnkgdGhlIGNsb3VkcmVzb3VyY2VtYW5hZ2VyIHNlcnZlci4gIEFmdGVyIHNldHRpbmcgYW55CiAgICAgKiBvcHRpb25hbCBwYXJhbWV0ZXJzLCBjYWxsIHRoZSB7QGxpbmsgR2V0T3JnUG9saWN5I2V4ZWN1dGUoKX0gbWV0aG9kIHRvIGludm9rZSB0aGUgcmVtb3RlCiAgICAgKiBvcGVyYXRpb24uCiAgICAgKgogICAgICogQHBhcmFtIHJlc291cmNlIE5hbWUgb2YgdGhlIHJlc291cmNlIHRoZSBgUG9saWN5YCBpcyBzZXQgb24uCiAgICAgKiBAcGFyYW0gY29udGVudCB0aGUge0BsaW5rIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmNsb3VkcmVzb3VyY2VtYW5hZ2VyLm1vZGVsLkdldE9yZ1BvbGljeVJlcXVlc3R9CiAgICAgKiBAcmV0dXJuIHRoZSByZXF1ZXN0CiAgICAgKi8KICAgIHB1YmxpYyBHZXRPcmdQb2xpY3kgZ2V0T3JnUG9saWN5KGphdmEubGFuZy5TdHJpbmcgcmVzb3VyY2UsIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmNsb3VkcmVzb3VyY2VtYW5hZ2VyLm1vZGVsLkdldE9yZ1BvbGljeVJlcXVlc3QgY29udGVudCkgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBHZXRPcmdQb2xpY3kgcmVzdWx0ID0gbmV3IEdldE9yZ1BvbGljeShyZXNvdXJjZSwgY29udGVudCk7CiAgICAgIGluaXRpYWxpemUocmVzdWx0KTsKICAgICAgcmV0dXJuIHJlc3VsdDsKICAgIH0KCiAgICBwdWJsaWMgY2xhc3MgR2V0T3JnUG9saWN5IGV4dGVuZHMgQ2xvdWRSZXNvdXJjZU1hbmFnZXJSZXF1ZXN0PGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmNsb3VkcmVzb3VyY2VtYW5hZ2VyLm1vZGVsLk9yZ1BvbGljeT4gewoKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFJFU1RfUEFUSCA9ICJ2MS97K3Jlc291cmNlfTpnZXRPcmdQb2xpY3kiOwoKICAgICAgcHJpdmF0ZSBmaW5hbCBqYXZhLnV0aWwucmVnZXguUGF0dGVybiBSRVNPVVJDRV9QQVRURVJOID0KICAgICAgICAgIGphdmEudXRpbC5yZWdleC5QYXR0ZXJuLmNvbXBpbGUoIl5wcm9qZWN0cy9bXi9dKyQiKTsKCiAgICAgIC8qKgogICAgICAgKiBHZXRzIGEgYFBvbGljeWAgb24gYSByZXNvdXJjZS4KICAgICAgICoKICAgICAgICogSWYgbm8gYFBvbGljeWAgaXMgc2V0IG9uIHRoZSByZXNvdXJjZSwgYSBgUG9saWN5YCBpcyByZXR1cm5lZCB3aXRoIGRlZmF1bHQgdmFsdWVzIGluY2x1ZGluZwogICAgICAgKiBgUE9MSUNZX1RZUEVfTk9UX1NFVGAgZm9yIHRoZSBgcG9saWN5X3R5cGUgb25lb2ZgLiBUaGUgYGV0YWdgIHZhbHVlIGNhbiBiZSB1c2VkIHdpdGgKICAgICAgICogYFNldE9yZ1BvbGljeSgpYCB0byBjcmVhdGUgb3IgdXBkYXRlIGEgYFBvbGljeWAgZHVyaW5nIHJlYWQtbW9kaWZ5LXdyaXRlLgogICAgICAgKgogICAgICAgKiBDcmVhdGUgYSByZXF1ZXN0IGZvciB0aGUgbWV0aG9kICJwcm9qZWN0cy5nZXRPcmdQb2xpY3kiLgogICAgICAgKgogICAgICAgKiBUaGlzIHJlcXVlc3QgaG9sZHMgdGhlIHBhcmFtZXRlcnMgbmVlZGVkIGJ5IHRoZSB0aGUgY2xvdWRyZXNvdXJjZW1hbmFnZXIgc2VydmVyLiAgQWZ0ZXIgc2V0dGluZwogICAgICAgKiBhbnkgb3B0aW9uYWwgcGFyYW1ldGVycywgY2FsbCB0aGUge0BsaW5rIEdldE9yZ1BvbGljeSNleGVjdXRlKCl9IG1ldGhvZCB0byBpbnZva2UgdGhlIHJlbW90ZQogICAgICAgKiBvcGVyYXRpb24uIDxwPiB7QGxpbmsKICAgICAgICogR2V0T3JnUG9saWN5I2luaXRpYWxpemUoY29tLmdvb2dsZS5hcGkuY2xpZW50Lmdvb2dsZWFwaXMuc2VydmljZXMuQWJzdHJhY3RHb29nbGVDbGllbnRSZXF1ZXN0KX0KICAgICAgICogbXVzdCBiZSBjYWxsZWQgdG8gaW5pdGlhbGl6ZSB0aGlzIGluc3RhbmNlIGltbWVkaWF0ZWx5IGFmdGVyIGludm9raW5nIHRoZSBjb25zdHJ1Y3Rvci4gPC9wPgogICAgICAgKgogICAgICAgKiBAcGFyYW0gcmVzb3VyY2UgTmFtZSBvZiB0aGUgcmVzb3VyY2UgdGhlIGBQb2xpY3lgIGlzIHNldCBvbi4KICAgICAgICogQHBhcmFtIGNvbnRlbnQgdGhlIHtAbGluayBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5jbG91ZHJlc291cmNlbWFuYWdlci5tb2RlbC5HZXRPcmdQb2xpY3lSZXF1ZXN0fQogICAgICAgKiBAc2luY2UgMS4xMwogICAgICAgKi8KICAgICAgcHJvdGVjdGVkIEdldE9yZ1BvbGljeShqYXZhLmxhbmcuU3RyaW5nIHJlc291cmNlLCBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5jbG91ZHJlc291cmNlbWFuYWdlci5tb2RlbC5HZXRPcmdQb2xpY3lSZXF1ZXN0IGNvbnRlbnQpIHsKICAgICAgICBzdXBlcihDbG91ZFJlc291cmNlTWFuYWdlci50aGlzLCAiUE9TVCIsIFJFU1RfUEFUSCwgY29udGVudCwgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuY2xvdWRyZXNvdXJjZW1hbmFnZXIubW9kZWwuT3JnUG9saWN5LmNsYXNzKTsKICAgICAgICB0aGlzLnJlc291cmNlID0gY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuUHJlY29uZGl0aW9ucy5jaGVja05vdE51bGwocmVzb3VyY2UsICJSZXF1aXJlZCBwYXJhbWV0ZXIgcmVzb3VyY2UgbXVzdCBiZSBzcGVjaWZpZWQuIik7CiAgICAgICAgaWYgKCFnZXRTdXBwcmVzc1BhdHRlcm5DaGVja3MoKSkgewogICAgICAgICAgY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuUHJlY29uZGl0aW9ucy5jaGVja0FyZ3VtZW50KFJFU09VUkNFX1BBVFRFUk4ubWF0Y2hlcihyZXNvdXJjZSkubWF0Y2hlcygpLAogICAgICAgICAgICAgICJQYXJhbWV0ZXIgcmVzb3VyY2UgbXVzdCBjb25mb3JtIHRvIHRoZSBwYXR0ZXJuICIgKwogICAgICAgICAgICAgICJecHJvamVjdHMvW14vXSskIik7CiAgICAgICAgfQogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIEdldE9yZ1BvbGljeSBzZXQkWGdhZnYoamF2YS5sYW5nLlN0cmluZyAkWGdhZnYpIHsKICAgICAgICByZXR1cm4gKEdldE9yZ1BvbGljeSkgc3VwZXIuc2V0JFhnYWZ2KCRYZ2Fmdik7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgR2V0T3JnUG9saWN5IHNldEFjY2Vzc1Rva2VuKGphdmEubGFuZy5TdHJpbmcgYWNjZXNzVG9rZW4pIHsKICAgICAgICByZXR1cm4gKEdldE9yZ1BvbGljeSkgc3VwZXIuc2V0QWNjZXNzVG9rZW4oYWNjZXNzVG9rZW4pOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIEdldE9yZ1BvbGljeSBzZXRBbHQoamF2YS5sYW5nLlN0cmluZyBhbHQpIHsKICAgICAgICByZXR1cm4gKEdldE9yZ1BvbGljeSkgc3VwZXIuc2V0QWx0KGFsdCk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgR2V0T3JnUG9saWN5IHNldENhbGxiYWNrKGphdmEubGFuZy5TdHJpbmcgY2FsbGJhY2spIHsKICAgICAgICByZXR1cm4gKEdldE9yZ1BvbGljeSkgc3VwZXIuc2V0Q2FsbGJhY2soY2FsbGJhY2spOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIEdldE9yZ1BvbGljeSBzZXRGaWVsZHMoamF2YS5sYW5nLlN0cmluZyBmaWVsZHMpIHsKICAgICAgICByZXR1cm4gKEdldE9yZ1BvbGljeSkgc3VwZXIuc2V0RmllbGRzKGZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgR2V0T3JnUG9saWN5IHNldEtleShqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIHJldHVybiAoR2V0T3JnUG9saWN5KSBzdXBlci5zZXRLZXkoa2V5KTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBHZXRPcmdQb2xpY3kgc2V0T2F1dGhUb2tlbihqYXZhLmxhbmcuU3RyaW5nIG9hdXRoVG9rZW4pIHsKICAgICAgICByZXR1cm4gKEdldE9yZ1BvbGljeSkgc3VwZXIuc2V0T2F1dGhUb2tlbihvYXV0aFRva2VuKTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBHZXRPcmdQb2xpY3kgc2V0UHJldHR5UHJpbnQoamF2YS5sYW5nLkJvb2xlYW4gcHJldHR5UHJpbnQpIHsKICAgICAgICByZXR1cm4gKEdldE9yZ1BvbGljeSkgc3VwZXIuc2V0UHJldHR5UHJpbnQocHJldHR5UHJpbnQpOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIEdldE9yZ1BvbGljeSBzZXRRdW90YVVzZXIoamF2YS5sYW5nLlN0cmluZyBxdW90YVVzZXIpIHsKICAgICAgICByZXR1cm4gKEdldE9yZ1BvbGljeSkgc3VwZXIuc2V0UXVvdGFVc2VyKHF1b3RhVXNlcik7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgR2V0T3JnUG9saWN5IHNldFVwbG9hZFR5cGUoamF2YS5sYW5nLlN0cmluZyB1cGxvYWRUeXBlKSB7CiAgICAgICAgcmV0dXJuIChHZXRPcmdQb2xpY3kpIHN1cGVyLnNldFVwbG9hZFR5cGUodXBsb2FkVHlwZSk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgR2V0T3JnUG9saWN5IHNldFVwbG9hZFByb3RvY29sKGphdmEubGFuZy5TdHJpbmcgdXBsb2FkUHJvdG9jb2wpIHsKICAgICAgICByZXR1cm4gKEdldE9yZ1BvbGljeSkgc3VwZXIuc2V0VXBsb2FkUHJvdG9jb2wodXBsb2FkUHJvdG9jb2wpOwogICAgICB9CgogICAgICAvKiogTmFtZSBvZiB0aGUgcmVzb3VyY2UgdGhlIGBQb2xpY3lgIGlzIHNldCBvbi4gKi8KICAgICAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogICAgICBwcml2YXRlIGphdmEubGFuZy5TdHJpbmcgcmVzb3VyY2U7CgogICAgICAvKiogTmFtZSBvZiB0aGUgcmVzb3VyY2UgdGhlIGBQb2xpY3lgIGlzIHNldCBvbi4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFJlc291cmNlKCkgewogICAgICAgIHJldHVybiByZXNvdXJjZTsKICAgICAgfQoKICAgICAgLyoqIE5hbWUgb2YgdGhlIHJlc291cmNlIHRoZSBgUG9saWN5YCBpcyBzZXQgb24uICovCiAgICAgIHB1YmxpYyBHZXRPcmdQb2xpY3kgc2V0UmVzb3VyY2UoamF2YS5sYW5nLlN0cmluZyByZXNvdXJjZSkgewogICAgICAgIGlmICghZ2V0U3VwcHJlc3NQYXR0ZXJuQ2hlY2tzKCkpIHsKICAgICAgICAgIGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLlByZWNvbmRpdGlvbnMuY2hlY2tBcmd1bWVudChSRVNPVVJDRV9QQVRURVJOLm1hdGNoZXIocmVzb3VyY2UpLm1hdGNoZXMoKSwKICAgICAgICAgICAgICAiUGFyYW1ldGVyIHJlc291cmNlIG11c3QgY29uZm9ybSB0byB0aGUgcGF0dGVybiAiICsKICAgICAgICAgICAgICAiXnByb2plY3RzL1teL10rJCIpOwogICAgICAgIH0KICAgICAgICB0aGlzLnJlc291cmNlID0gcmVzb3VyY2U7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgR2V0T3JnUG9saWN5IHNldChTdHJpbmcgcGFyYW1ldGVyTmFtZSwgT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIChHZXRPcmdQb2xpY3kpIHN1cGVyLnNldChwYXJhbWV0ZXJOYW1lLCB2YWx1ZSk7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogTGlzdHMgUHJvamVjdHMgdGhhdCB0aGUgY2FsbGVyIGhhcyB0aGUgYHJlc291cmNlbWFuYWdlci5wcm9qZWN0cy5nZXRgIHBlcm1pc3Npb24gb24gYW5kIHNhdGlzZnkKICAgICAqIHRoZSBzcGVjaWZpZWQgZmlsdGVyLgogICAgICoKICAgICAqIFRoaXMgbWV0aG9kIHJldHVybnMgUHJvamVjdHMgaW4gYW4gdW5zcGVjaWZpZWQgb3JkZXIuIFRoaXMgbWV0aG9kIGlzIGV2ZW50dWFsbHkgY29uc2lzdGVudCB3aXRoCiAgICAgKiBwcm9qZWN0IG11dGF0aW9uczsgdGhpcyBtZWFucyB0aGF0IGEgbmV3bHkgY3JlYXRlZCBwcm9qZWN0IG1heSBub3QgYXBwZWFyIGluIHRoZSByZXN1bHRzIG9yCiAgICAgKiByZWNlbnQgdXBkYXRlcyB0byBhbiBleGlzdGluZyBwcm9qZWN0IG1heSBub3QgYmUgcmVmbGVjdGVkIGluIHRoZSByZXN1bHRzLiBUbyByZXRyaWV2ZSB0aGUgbGF0ZXN0CiAgICAgKiBzdGF0ZSBvZiBhIHByb2plY3QsIHVzZSB0aGUgR2V0UHJvamVjdCBtZXRob2QuCiAgICAgKgogICAgICogTk9URTogSWYgdGhlIHJlcXVlc3QgZmlsdGVyIGNvbnRhaW5zIGEgYHBhcmVudC50eXBlYCBhbmQgYHBhcmVudC5pZGAgYW5kIHRoZSBjYWxsZXIgaGFzIHRoZQogICAgICogYHJlc291cmNlbWFuYWdlci5wcm9qZWN0cy5saXN0YCBwZXJtaXNzaW9uIG9uIHRoZSBwYXJlbnQsIHRoZSByZXN1bHRzIHdpbGwgYmUgZHJhd24gZnJvbSBhbgogICAgICogYWx0ZXJuYXRlIGluZGV4IHdoaWNoIHByb3ZpZGVzIG1vcmUgY29uc2lzdGVudCByZXN1bHRzLiBJbiBmdXR1cmUgdmVyc2lvbnMgb2YgdGhpcyBBUEksIHRoaXMgTGlzdAogICAgICogbWV0aG9kIHdpbGwgYmUgc3BsaXQgaW50byBMaXN0IGFuZCBTZWFyY2ggdG8gcHJvcGVybHkgY2FwdHVyZSB0aGUgYmVoYXZvcmlhbCBkaWZmZXJlbmNlLgogICAgICoKICAgICAqIENyZWF0ZSBhIHJlcXVlc3QgZm9yIHRoZSBtZXRob2QgInByb2plY3RzLmxpc3QiLgogICAgICoKICAgICAqIFRoaXMgcmVxdWVzdCBob2xkcyB0aGUgcGFyYW1ldGVycyBuZWVkZWQgYnkgdGhlIGNsb3VkcmVzb3VyY2VtYW5hZ2VyIHNlcnZlci4gIEFmdGVyIHNldHRpbmcgYW55CiAgICAgKiBvcHRpb25hbCBwYXJhbWV0ZXJzLCBjYWxsIHRoZSB7QGxpbmsgTGlzdCNleGVjdXRlKCl9IG1ldGhvZCB0byBpbnZva2UgdGhlIHJlbW90ZSBvcGVyYXRpb24uCiAgICAgKgogICAgICogQHJldHVybiB0aGUgcmVxdWVzdAogICAgICovCiAgICBwdWJsaWMgTGlzdCBsaXN0KCkgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBMaXN0IHJlc3VsdCA9IG5ldyBMaXN0KCk7CiAgICAgIGluaXRpYWxpemUocmVzdWx0KTsKICAgICAgcmV0dXJuIHJlc3VsdDsKICAgIH0KCiAgICBwdWJsaWMgY2xhc3MgTGlzdCBleHRlbmRzIENsb3VkUmVzb3VyY2VNYW5hZ2VyUmVxdWVzdDxjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5jbG91ZHJlc291cmNlbWFuYWdlci5tb2RlbC5MaXN0UHJvamVjdHNSZXNwb25zZT4gewoKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFJFU1RfUEFUSCA9ICJ2MS9wcm9qZWN0cyI7CgogICAgICAvKioKICAgICAgICogTGlzdHMgUHJvamVjdHMgdGhhdCB0aGUgY2FsbGVyIGhhcyB0aGUgYHJlc291cmNlbWFuYWdlci5wcm9qZWN0cy5nZXRgIHBlcm1pc3Npb24gb24gYW5kIHNhdGlzZnkKICAgICAgICogdGhlIHNwZWNpZmllZCBmaWx0ZXIuCiAgICAgICAqCiAgICAgICAqIFRoaXMgbWV0aG9kIHJldHVybnMgUHJvamVjdHMgaW4gYW4gdW5zcGVjaWZpZWQgb3JkZXIuIFRoaXMgbWV0aG9kIGlzIGV2ZW50dWFsbHkgY29uc2lzdGVudCB3aXRoCiAgICAgICAqIHByb2plY3QgbXV0YXRpb25zOyB0aGlzIG1lYW5zIHRoYXQgYSBuZXdseSBjcmVhdGVkIHByb2plY3QgbWF5IG5vdCBhcHBlYXIgaW4gdGhlIHJlc3VsdHMgb3IKICAgICAgICogcmVjZW50IHVwZGF0ZXMgdG8gYW4gZXhpc3RpbmcgcHJvamVjdCBtYXkgbm90IGJlIHJlZmxlY3RlZCBpbiB0aGUgcmVzdWx0cy4gVG8gcmV0cmlldmUgdGhlCiAgICAgICAqIGxhdGVzdCBzdGF0ZSBvZiBhIHByb2plY3QsIHVzZSB0aGUgR2V0UHJvamVjdCBtZXRob2QuCiAgICAgICAqCiAgICAgICAqIE5PVEU6IElmIHRoZSByZXF1ZXN0IGZpbHRlciBjb250YWlucyBhIGBwYXJlbnQudHlwZWAgYW5kIGBwYXJlbnQuaWRgIGFuZCB0aGUgY2FsbGVyIGhhcyB0aGUKICAgICAgICogYHJlc291cmNlbWFuYWdlci5wcm9qZWN0cy5saXN0YCBwZXJtaXNzaW9uIG9uIHRoZSBwYXJlbnQsIHRoZSByZXN1bHRzIHdpbGwgYmUgZHJhd24gZnJvbSBhbgogICAgICAgKiBhbHRlcm5hdGUgaW5kZXggd2hpY2ggcHJvdmlkZXMgbW9yZSBjb25zaXN0ZW50IHJlc3VsdHMuIEluIGZ1dHVyZSB2ZXJzaW9ucyBvZiB0aGlzIEFQSSwgdGhpcwogICAgICAgKiBMaXN0IG1ldGhvZCB3aWxsIGJlIHNwbGl0IGludG8gTGlzdCBhbmQgU2VhcmNoIHRvIHByb3Blcmx5IGNhcHR1cmUgdGhlIGJlaGF2b3JpYWwgZGlmZmVyZW5jZS4KICAgICAgICoKICAgICAgICogQ3JlYXRlIGEgcmVxdWVzdCBmb3IgdGhlIG1ldGhvZCAicHJvamVjdHMubGlzdCIuCiAgICAgICAqCiAgICAgICAqIFRoaXMgcmVxdWVzdCBob2xkcyB0aGUgcGFyYW1ldGVycyBuZWVkZWQgYnkgdGhlIHRoZSBjbG91ZHJlc291cmNlbWFuYWdlciBzZXJ2ZXIuICBBZnRlciBzZXR0aW5nCiAgICAgICAqIGFueSBvcHRpb25hbCBwYXJhbWV0ZXJzLCBjYWxsIHRoZSB7QGxpbmsgTGlzdCNleGVjdXRlKCl9IG1ldGhvZCB0byBpbnZva2UgdGhlIHJlbW90ZSBvcGVyYXRpb24uCiAgICAgICAqIDxwPiB7QGxpbmsKICAgICAgICogTGlzdCNpbml0aWFsaXplKGNvbS5nb29nbGUuYXBpLmNsaWVudC5nb29nbGVhcGlzLnNlcnZpY2VzLkFic3RyYWN0R29vZ2xlQ2xpZW50UmVxdWVzdCl9IG11c3QgYmUKICAgICAgICogY2FsbGVkIHRvIGluaXRpYWxpemUgdGhpcyBpbnN0YW5jZSBpbW1lZGlhdGVseSBhZnRlciBpbnZva2luZyB0aGUgY29uc3RydWN0b3IuIDwvcD4KICAgICAgICoKICAgICAgICogQHNpbmNlIDEuMTMKICAgICAgICovCiAgICAgIHByb3RlY3RlZCBMaXN0KCkgewogICAgICAgIHN1cGVyKENsb3VkUmVzb3VyY2VNYW5hZ2VyLnRoaXMsICJHRVQiLCBSRVNUX1BBVEgsIG51bGwsIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmNsb3VkcmVzb3VyY2VtYW5hZ2VyLm1vZGVsLkxpc3RQcm9qZWN0c1Jlc3BvbnNlLmNsYXNzKTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBjb20uZ29vZ2xlLmFwaS5jbGllbnQuaHR0cC5IdHRwUmVzcG9uc2UgZXhlY3V0ZVVzaW5nSGVhZCgpIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgICByZXR1cm4gc3VwZXIuZXhlY3V0ZVVzaW5nSGVhZCgpOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIGNvbS5nb29nbGUuYXBpLmNsaWVudC5odHRwLkh0dHBSZXF1ZXN0IGJ1aWxkSHR0cFJlcXVlc3RVc2luZ0hlYWQoKSB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIHN1cGVyLmJ1aWxkSHR0cFJlcXVlc3RVc2luZ0hlYWQoKTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBMaXN0IHNldCRYZ2FmdihqYXZhLmxhbmcuU3RyaW5nICRYZ2FmdikgewogICAgICAgIHJldHVybiAoTGlzdCkgc3VwZXIuc2V0JFhnYWZ2KCRYZ2Fmdik7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgTGlzdCBzZXRBY2Nlc3NUb2tlbihqYXZhLmxhbmcuU3RyaW5nIGFjY2Vzc1Rva2VuKSB7CiAgICAgICAgcmV0dXJuIChMaXN0KSBzdXBlci5zZXRBY2Nlc3NUb2tlbihhY2Nlc3NUb2tlbik7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgTGlzdCBzZXRBbHQoamF2YS5sYW5nLlN0cmluZyBhbHQpIHsKICAgICAgICByZXR1cm4gKExpc3QpIHN1cGVyLnNldEFsdChhbHQpOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIExpc3Qgc2V0Q2FsbGJhY2soamF2YS5sYW5nLlN0cmluZyBjYWxsYmFjaykgewogICAgICAgIHJldHVybiAoTGlzdCkgc3VwZXIuc2V0Q2FsbGJhY2soY2FsbGJhY2spOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIExpc3Qgc2V0RmllbGRzKGphdmEubGFuZy5TdHJpbmcgZmllbGRzKSB7CiAgICAgICAgcmV0dXJuIChMaXN0KSBzdXBlci5zZXRGaWVsZHMoZmllbGRzKTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBMaXN0IHNldEtleShqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIHJldHVybiAoTGlzdCkgc3VwZXIuc2V0S2V5KGtleSk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgTGlzdCBzZXRPYXV0aFRva2VuKGphdmEubGFuZy5TdHJpbmcgb2F1dGhUb2tlbikgewogICAgICAgIHJldHVybiAoTGlzdCkgc3VwZXIuc2V0T2F1dGhUb2tlbihvYXV0aFRva2VuKTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBMaXN0IHNldFByZXR0eVByaW50KGphdmEubGFuZy5Cb29sZWFuIHByZXR0eVByaW50KSB7CiAgICAgICAgcmV0dXJuIChMaXN0KSBzdXBlci5zZXRQcmV0dHlQcmludChwcmV0dHlQcmludCk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgTGlzdCBzZXRRdW90YVVzZXIoamF2YS5sYW5nLlN0cmluZyBxdW90YVVzZXIpIHsKICAgICAgICByZXR1cm4gKExpc3QpIHN1cGVyLnNldFF1b3RhVXNlcihxdW90YVVzZXIpOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIExpc3Qgc2V0VXBsb2FkVHlwZShqYXZhLmxhbmcuU3RyaW5nIHVwbG9hZFR5cGUpIHsKICAgICAgICByZXR1cm4gKExpc3QpIHN1cGVyLnNldFVwbG9hZFR5cGUodXBsb2FkVHlwZSk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgTGlzdCBzZXRVcGxvYWRQcm90b2NvbChqYXZhLmxhbmcuU3RyaW5nIHVwbG9hZFByb3RvY29sKSB7CiAgICAgICAgcmV0dXJuIChMaXN0KSBzdXBlci5zZXRVcGxvYWRQcm90b2NvbCh1cGxvYWRQcm90b2NvbCk7CiAgICAgIH0KCiAgICAgIC8qKgogICAgICAgKiBBbiBleHByZXNzaW9uIGZvciBmaWx0ZXJpbmcgdGhlIHJlc3VsdHMgb2YgdGhlIHJlcXVlc3QuICBGaWx0ZXIgcnVsZXMgYXJlIGNhc2UgaW5zZW5zaXRpdmUuCiAgICAgICAqIFRoZSBmaWVsZHMgZWxpZ2libGUgZm9yIGZpbHRlcmluZyBhcmU6CiAgICAgICAqCiAgICAgICAqICsgYG5hbWVgICsgYGlkYCArIGBsYWJlbHMuYCAod2hlcmUgKmtleSogaXMgdGhlIG5hbWUgb2YgYSBsYWJlbCkgKyBgcGFyZW50LnR5cGVgICsKICAgICAgICogYHBhcmVudC5pZGAKICAgICAgICoKICAgICAgICogU29tZSBleGFtcGxlcyBvZiB1c2luZyBsYWJlbHMgYXMgZmlsdGVyczoKICAgICAgICoKICAgICAgICogfCBGaWx0ZXIgICAgICAgICAgIHwgRGVzY3JpcHRpb24gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwKICAgICAgICogfC0tLS0tLS0tLS0tLS0tLS0tLXwtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLXwgfCBuYW1lOmhvdyoKICAgICAgICogfCBUaGUgcHJvamVjdCdzIG5hbWUgc3RhcnRzIHdpdGggImhvdyIuICAgICAgICAgICAgICAgfCB8IG5hbWU6SG93bCAgICAgICAgfCBUaGUgcHJvamVjdCdzCiAgICAgICAqIG5hbWUgaXMgYEhvd2xgIG9yIGBob3dsYC4gICAgICAgICAgICAgfCB8IG5hbWU6SE9XTCAgICAgICAgfCBFcXVpdmFsZW50IHRvIGFib3ZlLgogICAgICAgKiB8IHwgTkFNRTpob3dsICAgICAgICB8IEVxdWl2YWxlbnQgdG8gYWJvdmUuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IHwKICAgICAgICogbGFiZWxzLmNvbG9yOiogICB8IFRoZSBwcm9qZWN0IGhhcyB0aGUgbGFiZWwgYGNvbG9yYC4gICAgICAgICAgICAgICAgICB8IHwgbGFiZWxzLmNvbG9yOnJlZAogICAgICAgKiB8IFRoZSBwcm9qZWN0J3MgbGFiZWwgYGNvbG9yYCBoYXMgdGhlIHZhbHVlIGByZWRgLiAgICB8IHwgbGFiZWxzLmNvbG9yOnJlZGxhYmVscy5zaXplOmJpZwogICAgICAgKiB8VGhlIHByb2plY3QncyBsYWJlbCBgY29sb3JgIGhhcyB0aGUgdmFsdWUgYHJlZGAgYW5kIGl0cyBsYWJlbCBgc2l6ZWAgaGFzIHRoZSB2YWx1ZSBgYmlnYC4KICAgICAgICogfAogICAgICAgKgogICAgICAgKiBJZiBubyBmaWx0ZXIgaXMgc3BlY2lmaWVkLCB0aGUgY2FsbCB3aWxsIHJldHVybiBwcm9qZWN0cyBmb3Igd2hpY2ggdGhlIHVzZXIgaGFzIHRoZQogICAgICAgKiBgcmVzb3VyY2VtYW5hZ2VyLnByb2plY3RzLmdldGAgcGVybWlzc2lvbi4KICAgICAgICoKICAgICAgICogTk9URTogVG8gcGVyZm9ybSBhIGJ5LXBhcmVudCBxdWVyeSAoZWcuLCB3aGF0IHByb2plY3RzIGFyZSBkaXJlY3RseSBpbiBhIEZvbGRlciksIHRoZQogICAgICAgKiBjYWxsZXIgbXVzdCBoYXZlIHRoZSBgcmVzb3VyY2VtYW5hZ2VyLnByb2plY3RzLmxpc3RgIHBlcm1pc3Npb24gb24gdGhlIHBhcmVudCBhbmQgdGhlCiAgICAgICAqIGZpbHRlciBtdXN0IGNvbnRhaW4gYm90aCBhIGBwYXJlbnQudHlwZWAgYW5kIGEgYHBhcmVudC5pZGAgcmVzdHJpY3Rpb24gKGV4YW1wbGU6CiAgICAgICAqICJwYXJlbnQudHlwZTpmb2xkZXIgcGFyZW50LmlkOjEyMyIpLiBJbiB0aGlzIGNhc2UgYW4gYWx0ZXJuYXRlIHNlYXJjaCBpbmRleCBpcyB1c2VkIHdoaWNoCiAgICAgICAqIHByb3ZpZGVzIG1vcmUgY29uc2lzdGVudCByZXN1bHRzLgogICAgICAgKgogICAgICAgKiBPcHRpb25hbC4KICAgICAgICovCiAgICAgIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuU3RyaW5nIGZpbHRlcjsKCiAgICAgIC8qKiBBbiBleHByZXNzaW9uIGZvciBmaWx0ZXJpbmcgdGhlIHJlc3VsdHMgb2YgdGhlIHJlcXVlc3QuICBGaWx0ZXIgcnVsZXMgYXJlIGNhc2UgaW5zZW5zaXRpdmUuIFRoZQogICAgIGZpZWxkcyBlbGlnaWJsZSBmb3IgZmlsdGVyaW5nIGFyZToKCiAgICAgKyBgbmFtZWAgKyBgaWRgICsgYGxhYmVscy5gICh3aGVyZSAqa2V5KiBpcyB0aGUgbmFtZSBvZiBhIGxhYmVsKSArIGBwYXJlbnQudHlwZWAgKyBgcGFyZW50LmlkYAoKICAgICBTb21lIGV4YW1wbGVzIG9mIHVzaW5nIGxhYmVscyBhcyBmaWx0ZXJzOgoKICAgICB8IEZpbHRlciAgICAgICAgICAgfCBEZXNjcmlwdGlvbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfAogICAgIHwtLS0tLS0tLS0tLS0tLS0tLS18LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS18IHwgbmFtZTpob3cqICAgICAgICB8IFRoZQogICAgIHByb2plY3QncyBuYW1lIHN0YXJ0cyB3aXRoICJob3ciLiAgICAgICAgICAgICAgIHwgfCBuYW1lOkhvd2wgICAgICAgIHwgVGhlIHByb2plY3QncyBuYW1lIGlzIGBIb3dsYAogICAgIG9yIGBob3dsYC4gICAgICAgICAgICAgfCB8IG5hbWU6SE9XTCAgICAgICAgfCBFcXVpdmFsZW50IHRvIGFib3ZlLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfAogICAgIHwgTkFNRTpob3dsICAgICAgICB8IEVxdWl2YWxlbnQgdG8gYWJvdmUuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IHwgbGFiZWxzLmNvbG9yOiogICB8IFRoZQogICAgIHByb2plY3QgaGFzIHRoZSBsYWJlbCBgY29sb3JgLiAgICAgICAgICAgICAgICAgIHwgfCBsYWJlbHMuY29sb3I6cmVkIHwgVGhlIHByb2plY3QncyBsYWJlbCBgY29sb3JgCiAgICAgaGFzIHRoZSB2YWx1ZSBgcmVkYC4gICAgfCB8IGxhYmVscy5jb2xvcjpyZWRsYWJlbHMuc2l6ZTpiaWcgfFRoZSBwcm9qZWN0J3MgbGFiZWwgYGNvbG9yYCBoYXMgdGhlCiAgICAgdmFsdWUgYHJlZGAgYW5kIGl0cyBsYWJlbCBgc2l6ZWAgaGFzIHRoZSB2YWx1ZSBgYmlnYC4gICAgICAgICAgICAgIHwKCiAgICAgSWYgbm8gZmlsdGVyIGlzIHNwZWNpZmllZCwgdGhlIGNhbGwgd2lsbCByZXR1cm4gcHJvamVjdHMgZm9yIHdoaWNoIHRoZSB1c2VyIGhhcyB0aGUKICAgICBgcmVzb3VyY2VtYW5hZ2VyLnByb2plY3RzLmdldGAgcGVybWlzc2lvbi4KCiAgICAgTk9URTogVG8gcGVyZm9ybSBhIGJ5LXBhcmVudCBxdWVyeSAoZWcuLCB3aGF0IHByb2plY3RzIGFyZSBkaXJlY3RseSBpbiBhIEZvbGRlciksIHRoZSBjYWxsZXIgbXVzdAogICAgIGhhdmUgdGhlIGByZXNvdXJjZW1hbmFnZXIucHJvamVjdHMubGlzdGAgcGVybWlzc2lvbiBvbiB0aGUgcGFyZW50IGFuZCB0aGUgZmlsdGVyIG11c3QgY29udGFpbiBib3RoCiAgICAgYSBgcGFyZW50LnR5cGVgIGFuZCBhIGBwYXJlbnQuaWRgIHJlc3RyaWN0aW9uIChleGFtcGxlOiAicGFyZW50LnR5cGU6Zm9sZGVyIHBhcmVudC5pZDoxMjMiKS4gSW4KICAgICB0aGlzIGNhc2UgYW4gYWx0ZXJuYXRlIHNlYXJjaCBpbmRleCBpcyB1c2VkIHdoaWNoIHByb3ZpZGVzIG1vcmUgY29uc2lzdGVudCByZXN1bHRzLgoKICAgICBPcHRpb25hbC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldEZpbHRlcigpIHsKICAgICAgICByZXR1cm4gZmlsdGVyOwogICAgICB9CgogICAgICAvKioKICAgICAgICogQW4gZXhwcmVzc2lvbiBmb3IgZmlsdGVyaW5nIHRoZSByZXN1bHRzIG9mIHRoZSByZXF1ZXN0LiAgRmlsdGVyIHJ1bGVzIGFyZSBjYXNlIGluc2Vuc2l0aXZlLgogICAgICAgKiBUaGUgZmllbGRzIGVsaWdpYmxlIGZvciBmaWx0ZXJpbmcgYXJlOgogICAgICAgKgogICAgICAgKiArIGBuYW1lYCArIGBpZGAgKyBgbGFiZWxzLmAgKHdoZXJlICprZXkqIGlzIHRoZSBuYW1lIG9mIGEgbGFiZWwpICsgYHBhcmVudC50eXBlYCArCiAgICAgICAqIGBwYXJlbnQuaWRgCiAgICAgICAqCiAgICAgICAqIFNvbWUgZXhhbXBsZXMgb2YgdXNpbmcgbGFiZWxzIGFzIGZpbHRlcnM6CiAgICAgICAqCiAgICAgICAqIHwgRmlsdGVyICAgICAgICAgICB8IERlc2NyaXB0aW9uICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8CiAgICAgICAqIHwtLS0tLS0tLS0tLS0tLS0tLS18LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS18IHwgbmFtZTpob3cqCiAgICAgICAqIHwgVGhlIHByb2plY3QncyBuYW1lIHN0YXJ0cyB3aXRoICJob3ciLiAgICAgICAgICAgICAgIHwgfCBuYW1lOkhvd2wgICAgICAgIHwgVGhlIHByb2plY3QncwogICAgICAgKiBuYW1lIGlzIGBIb3dsYCBvciBgaG93bGAuICAgICAgICAgICAgIHwgfCBuYW1lOkhPV0wgICAgICAgIHwgRXF1aXZhbGVudCB0byBhYm92ZS4KICAgICAgICogfCB8IE5BTUU6aG93bCAgICAgICAgfCBFcXVpdmFsZW50IHRvIGFib3ZlLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCB8CiAgICAgICAqIGxhYmVscy5jb2xvcjoqICAgfCBUaGUgcHJvamVjdCBoYXMgdGhlIGxhYmVsIGBjb2xvcmAuICAgICAgICAgICAgICAgICAgfCB8IGxhYmVscy5jb2xvcjpyZWQKICAgICAgICogfCBUaGUgcHJvamVjdCdzIGxhYmVsIGBjb2xvcmAgaGFzIHRoZSB2YWx1ZSBgcmVkYC4gICAgfCB8IGxhYmVscy5jb2xvcjpyZWRsYWJlbHMuc2l6ZTpiaWcKICAgICAgICogfFRoZSBwcm9qZWN0J3MgbGFiZWwgYGNvbG9yYCBoYXMgdGhlIHZhbHVlIGByZWRgIGFuZCBpdHMgbGFiZWwgYHNpemVgIGhhcyB0aGUgdmFsdWUgYGJpZ2AuCiAgICAgICAqIHwKICAgICAgICoKICAgICAgICogSWYgbm8gZmlsdGVyIGlzIHNwZWNpZmllZCwgdGhlIGNhbGwgd2lsbCByZXR1cm4gcHJvamVjdHMgZm9yIHdoaWNoIHRoZSB1c2VyIGhhcyB0aGUKICAgICAgICogYHJlc291cmNlbWFuYWdlci5wcm9qZWN0cy5nZXRgIHBlcm1pc3Npb24uCiAgICAgICAqCiAgICAgICAqIE5PVEU6IFRvIHBlcmZvcm0gYSBieS1wYXJlbnQgcXVlcnkgKGVnLiwgd2hhdCBwcm9qZWN0cyBhcmUgZGlyZWN0bHkgaW4gYSBGb2xkZXIpLCB0aGUKICAgICAgICogY2FsbGVyIG11c3QgaGF2ZSB0aGUgYHJlc291cmNlbWFuYWdlci5wcm9qZWN0cy5saXN0YCBwZXJtaXNzaW9uIG9uIHRoZSBwYXJlbnQgYW5kIHRoZQogICAgICAgKiBmaWx0ZXIgbXVzdCBjb250YWluIGJvdGggYSBgcGFyZW50LnR5cGVgIGFuZCBhIGBwYXJlbnQuaWRgIHJlc3RyaWN0aW9uIChleGFtcGxlOgogICAgICAgKiAicGFyZW50LnR5cGU6Zm9sZGVyIHBhcmVudC5pZDoxMjMiKS4gSW4gdGhpcyBjYXNlIGFuIGFsdGVybmF0ZSBzZWFyY2ggaW5kZXggaXMgdXNlZCB3aGljaAogICAgICAgKiBwcm92aWRlcyBtb3JlIGNvbnNpc3RlbnQgcmVzdWx0cy4KICAgICAgICoKICAgICAgICogT3B0aW9uYWwuCiAgICAgICAqLwogICAgICBwdWJsaWMgTGlzdCBzZXRGaWx0ZXIoamF2YS5sYW5nLlN0cmluZyBmaWx0ZXIpIHsKICAgICAgICB0aGlzLmZpbHRlciA9IGZpbHRlcjsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgLyoqCiAgICAgICAqIEEgcGFnaW5hdGlvbiB0b2tlbiByZXR1cm5lZCBmcm9tIGEgcHJldmlvdXMgY2FsbCB0byBMaXN0UHJvamVjdHMgdGhhdCBpbmRpY2F0ZXMgZnJvbSB3aGVyZQogICAgICAgKiBsaXN0aW5nIHNob3VsZCBjb250aW51ZS4KICAgICAgICoKICAgICAgICogT3B0aW9uYWwuCiAgICAgICAqLwogICAgICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgICAgIHByaXZhdGUgamF2YS5sYW5nLlN0cmluZyBwYWdlVG9rZW47CgogICAgICAvKiogQSBwYWdpbmF0aW9uIHRva2VuIHJldHVybmVkIGZyb20gYSBwcmV2aW91cyBjYWxsIHRvIExpc3RQcm9qZWN0cyB0aGF0IGluZGljYXRlcyBmcm9tIHdoZXJlIGxpc3RpbmcKICAgICBzaG91bGQgY29udGludWUuCgogICAgIE9wdGlvbmFsLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0UGFnZVRva2VuKCkgewogICAgICAgIHJldHVybiBwYWdlVG9rZW47CiAgICAgIH0KCiAgICAgIC8qKgogICAgICAgKiBBIHBhZ2luYXRpb24gdG9rZW4gcmV0dXJuZWQgZnJvbSBhIHByZXZpb3VzIGNhbGwgdG8gTGlzdFByb2plY3RzIHRoYXQgaW5kaWNhdGVzIGZyb20gd2hlcmUKICAgICAgICogbGlzdGluZyBzaG91bGQgY29udGludWUuCiAgICAgICAqCiAgICAgICAqIE9wdGlvbmFsLgogICAgICAgKi8KICAgICAgcHVibGljIExpc3Qgc2V0UGFnZVRva2VuKGphdmEubGFuZy5TdHJpbmcgcGFnZVRva2VuKSB7CiAgICAgICAgdGhpcy5wYWdlVG9rZW4gPSBwYWdlVG9rZW47CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIC8qKgogICAgICAgKiBUaGUgbWF4aW11bSBudW1iZXIgb2YgUHJvamVjdHMgdG8gcmV0dXJuIGluIHRoZSByZXNwb25zZS4gVGhlIHNlcnZlciBjYW4gcmV0dXJuIGZld2VyCiAgICAgICAqIFByb2plY3RzIHRoYW4gcmVxdWVzdGVkLiBJZiB1bnNwZWNpZmllZCwgc2VydmVyIHBpY2tzIGFuIGFwcHJvcHJpYXRlIGRlZmF1bHQuCiAgICAgICAqCiAgICAgICAqIE9wdGlvbmFsLgogICAgICAgKi8KICAgICAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogICAgICBwcml2YXRlIGphdmEubGFuZy5JbnRlZ2VyIHBhZ2VTaXplOwoKICAgICAgLyoqIFRoZSBtYXhpbXVtIG51bWJlciBvZiBQcm9qZWN0cyB0byByZXR1cm4gaW4gdGhlIHJlc3BvbnNlLiBUaGUgc2VydmVyIGNhbiByZXR1cm4gZmV3ZXIgUHJvamVjdHMgdGhhbgogICAgIHJlcXVlc3RlZC4gSWYgdW5zcGVjaWZpZWQsIHNlcnZlciBwaWNrcyBhbiBhcHByb3ByaWF0ZSBkZWZhdWx0LgoKICAgICBPcHRpb25hbC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuSW50ZWdlciBnZXRQYWdlU2l6ZSgpIHsKICAgICAgICByZXR1cm4gcGFnZVNpemU7CiAgICAgIH0KCiAgICAgIC8qKgogICAgICAgKiBUaGUgbWF4aW11bSBudW1iZXIgb2YgUHJvamVjdHMgdG8gcmV0dXJuIGluIHRoZSByZXNwb25zZS4gVGhlIHNlcnZlciBjYW4gcmV0dXJuIGZld2VyCiAgICAgICAqIFByb2plY3RzIHRoYW4gcmVxdWVzdGVkLiBJZiB1bnNwZWNpZmllZCwgc2VydmVyIHBpY2tzIGFuIGFwcHJvcHJpYXRlIGRlZmF1bHQuCiAgICAgICAqCiAgICAgICAqIE9wdGlvbmFsLgogICAgICAgKi8KICAgICAgcHVibGljIExpc3Qgc2V0UGFnZVNpemUoamF2YS5sYW5nLkludGVnZXIgcGFnZVNpemUpIHsKICAgICAgICB0aGlzLnBhZ2VTaXplID0gcGFnZVNpemU7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgTGlzdCBzZXQoU3RyaW5nIHBhcmFtZXRlck5hbWUsIE9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiAoTGlzdCkgc3VwZXIuc2V0KHBhcmFtZXRlck5hbWUsIHZhbHVlKTsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiBMaXN0cyBgQ29uc3RyYWludHNgIHRoYXQgY291bGQgYmUgYXBwbGllZCBvbiB0aGUgc3BlY2lmaWVkIHJlc291cmNlLgogICAgICoKICAgICAqIENyZWF0ZSBhIHJlcXVlc3QgZm9yIHRoZSBtZXRob2QgInByb2plY3RzLmxpc3RBdmFpbGFibGVPcmdQb2xpY3lDb25zdHJhaW50cyIuCiAgICAgKgogICAgICogVGhpcyByZXF1ZXN0IGhvbGRzIHRoZSBwYXJhbWV0ZXJzIG5lZWRlZCBieSB0aGUgY2xvdWRyZXNvdXJjZW1hbmFnZXIgc2VydmVyLiAgQWZ0ZXIgc2V0dGluZyBhbnkKICAgICAqIG9wdGlvbmFsIHBhcmFtZXRlcnMsIGNhbGwgdGhlIHtAbGluayBMaXN0QXZhaWxhYmxlT3JnUG9saWN5Q29uc3RyYWludHMjZXhlY3V0ZSgpfSBtZXRob2QgdG8KICAgICAqIGludm9rZSB0aGUgcmVtb3RlIG9wZXJhdGlvbi4KICAgICAqCiAgICAgKiBAcGFyYW0gcmVzb3VyY2UgTmFtZSBvZiB0aGUgcmVzb3VyY2UgdG8gbGlzdCBgQ29uc3RyYWludHNgIGZvci4KICAgICAqIEBwYXJhbSBjb250ZW50IHRoZSB7QGxpbmsgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuY2xvdWRyZXNvdXJjZW1hbmFnZXIubW9kZWwuTGlzdEF2YWlsYWJsZU9yZ1BvbGljeUNvbnN0cmFpbnRzUmVxdWVzdH0KICAgICAqIEByZXR1cm4gdGhlIHJlcXVlc3QKICAgICAqLwogICAgcHVibGljIExpc3RBdmFpbGFibGVPcmdQb2xpY3lDb25zdHJhaW50cyBsaXN0QXZhaWxhYmxlT3JnUG9saWN5Q29uc3RyYWludHMoamF2YS5sYW5nLlN0cmluZyByZXNvdXJjZSwgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuY2xvdWRyZXNvdXJjZW1hbmFnZXIubW9kZWwuTGlzdEF2YWlsYWJsZU9yZ1BvbGljeUNvbnN0cmFpbnRzUmVxdWVzdCBjb250ZW50KSB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgICAgIExpc3RBdmFpbGFibGVPcmdQb2xpY3lDb25zdHJhaW50cyByZXN1bHQgPSBuZXcgTGlzdEF2YWlsYWJsZU9yZ1BvbGljeUNvbnN0cmFpbnRzKHJlc291cmNlLCBjb250ZW50KTsKICAgICAgaW5pdGlhbGl6ZShyZXN1bHQpOwogICAgICByZXR1cm4gcmVzdWx0OwogICAgfQoKICAgIHB1YmxpYyBjbGFzcyBMaXN0QXZhaWxhYmxlT3JnUG9saWN5Q29uc3RyYWludHMgZXh0ZW5kcyBDbG91ZFJlc291cmNlTWFuYWdlclJlcXVlc3Q8Y29tLmdvb2dsZS5hcGkuc2VydmljZXMuY2xvdWRyZXNvdXJjZW1hbmFnZXIubW9kZWwuTGlzdEF2YWlsYWJsZU9yZ1BvbGljeUNvbnN0cmFpbnRzUmVzcG9uc2U+IHsKCiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBSRVNUX1BBVEggPSAidjEveytyZXNvdXJjZX06bGlzdEF2YWlsYWJsZU9yZ1BvbGljeUNvbnN0cmFpbnRzIjsKCiAgICAgIHByaXZhdGUgZmluYWwgamF2YS51dGlsLnJlZ2V4LlBhdHRlcm4gUkVTT1VSQ0VfUEFUVEVSTiA9CiAgICAgICAgICBqYXZhLnV0aWwucmVnZXguUGF0dGVybi5jb21waWxlKCJecHJvamVjdHMvW14vXSskIik7CgogICAgICAvKioKICAgICAgICogTGlzdHMgYENvbnN0cmFpbnRzYCB0aGF0IGNvdWxkIGJlIGFwcGxpZWQgb24gdGhlIHNwZWNpZmllZCByZXNvdXJjZS4KICAgICAgICoKICAgICAgICogQ3JlYXRlIGEgcmVxdWVzdCBmb3IgdGhlIG1ldGhvZCAicHJvamVjdHMubGlzdEF2YWlsYWJsZU9yZ1BvbGljeUNvbnN0cmFpbnRzIi4KICAgICAgICoKICAgICAgICogVGhpcyByZXF1ZXN0IGhvbGRzIHRoZSBwYXJhbWV0ZXJzIG5lZWRlZCBieSB0aGUgdGhlIGNsb3VkcmVzb3VyY2VtYW5hZ2VyIHNlcnZlci4gIEFmdGVyIHNldHRpbmcKICAgICAgICogYW55IG9wdGlvbmFsIHBhcmFtZXRlcnMsIGNhbGwgdGhlIHtAbGluayBMaXN0QXZhaWxhYmxlT3JnUG9saWN5Q29uc3RyYWludHMjZXhlY3V0ZSgpfSBtZXRob2QgdG8KICAgICAgICogaW52b2tlIHRoZSByZW1vdGUgb3BlcmF0aW9uLiA8cD4ge0BsaW5rIExpc3RBdmFpbGFibGVPcmdQb2xpY3lDb25zdHJhaW50cyNpbml0aWFsaXplKGNvbS5nb29nbGUKICAgICAgICogLmFwaS5jbGllbnQuZ29vZ2xlYXBpcy5zZXJ2aWNlcy5BYnN0cmFjdEdvb2dsZUNsaWVudFJlcXVlc3QpfSBtdXN0IGJlIGNhbGxlZCB0byBpbml0aWFsaXplIHRoaXMKICAgICAgICogaW5zdGFuY2UgaW1tZWRpYXRlbHkgYWZ0ZXIgaW52b2tpbmcgdGhlIGNvbnN0cnVjdG9yLiA8L3A+CiAgICAgICAqCiAgICAgICAqIEBwYXJhbSByZXNvdXJjZSBOYW1lIG9mIHRoZSByZXNvdXJjZSB0byBsaXN0IGBDb25zdHJhaW50c2AgZm9yLgogICAgICAgKiBAcGFyYW0gY29udGVudCB0aGUge0BsaW5rIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmNsb3VkcmVzb3VyY2VtYW5hZ2VyLm1vZGVsLkxpc3RBdmFpbGFibGVPcmdQb2xpY3lDb25zdHJhaW50c1JlcXVlc3R9CiAgICAgICAqIEBzaW5jZSAxLjEzCiAgICAgICAqLwogICAgICBwcm90ZWN0ZWQgTGlzdEF2YWlsYWJsZU9yZ1BvbGljeUNvbnN0cmFpbnRzKGphdmEubGFuZy5TdHJpbmcgcmVzb3VyY2UsIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmNsb3VkcmVzb3VyY2VtYW5hZ2VyLm1vZGVsLkxpc3RBdmFpbGFibGVPcmdQb2xpY3lDb25zdHJhaW50c1JlcXVlc3QgY29udGVudCkgewogICAgICAgIHN1cGVyKENsb3VkUmVzb3VyY2VNYW5hZ2VyLnRoaXMsICJQT1NUIiwgUkVTVF9QQVRILCBjb250ZW50LCBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5jbG91ZHJlc291cmNlbWFuYWdlci5tb2RlbC5MaXN0QXZhaWxhYmxlT3JnUG9saWN5Q29uc3RyYWludHNSZXNwb25zZS5jbGFzcyk7CiAgICAgICAgdGhpcy5yZXNvdXJjZSA9IGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLlByZWNvbmRpdGlvbnMuY2hlY2tOb3ROdWxsKHJlc291cmNlLCAiUmVxdWlyZWQgcGFyYW1ldGVyIHJlc291cmNlIG11c3QgYmUgc3BlY2lmaWVkLiIpOwogICAgICAgIGlmICghZ2V0U3VwcHJlc3NQYXR0ZXJuQ2hlY2tzKCkpIHsKICAgICAgICAgIGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLlByZWNvbmRpdGlvbnMuY2hlY2tBcmd1bWVudChSRVNPVVJDRV9QQVRURVJOLm1hdGNoZXIocmVzb3VyY2UpLm1hdGNoZXMoKSwKICAgICAgICAgICAgICAiUGFyYW1ldGVyIHJlc291cmNlIG11c3QgY29uZm9ybSB0byB0aGUgcGF0dGVybiAiICsKICAgICAgICAgICAgICAiXnByb2plY3RzL1teL10rJCIpOwogICAgICAgIH0KICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBMaXN0QXZhaWxhYmxlT3JnUG9saWN5Q29uc3RyYWludHMgc2V0JFhnYWZ2KGphdmEubGFuZy5TdHJpbmcgJFhnYWZ2KSB7CiAgICAgICAgcmV0dXJuIChMaXN0QXZhaWxhYmxlT3JnUG9saWN5Q29uc3RyYWludHMpIHN1cGVyLnNldCRYZ2FmdigkWGdhZnYpOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIExpc3RBdmFpbGFibGVPcmdQb2xpY3lDb25zdHJhaW50cyBzZXRBY2Nlc3NUb2tlbihqYXZhLmxhbmcuU3RyaW5nIGFjY2Vzc1Rva2VuKSB7CiAgICAgICAgcmV0dXJuIChMaXN0QXZhaWxhYmxlT3JnUG9saWN5Q29uc3RyYWludHMpIHN1cGVyLnNldEFjY2Vzc1Rva2VuKGFjY2Vzc1Rva2VuKTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBMaXN0QXZhaWxhYmxlT3JnUG9saWN5Q29uc3RyYWludHMgc2V0QWx0KGphdmEubGFuZy5TdHJpbmcgYWx0KSB7CiAgICAgICAgcmV0dXJuIChMaXN0QXZhaWxhYmxlT3JnUG9saWN5Q29uc3RyYWludHMpIHN1cGVyLnNldEFsdChhbHQpOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIExpc3RBdmFpbGFibGVPcmdQb2xpY3lDb25zdHJhaW50cyBzZXRDYWxsYmFjayhqYXZhLmxhbmcuU3RyaW5nIGNhbGxiYWNrKSB7CiAgICAgICAgcmV0dXJuIChMaXN0QXZhaWxhYmxlT3JnUG9saWN5Q29uc3RyYWludHMpIHN1cGVyLnNldENhbGxiYWNrKGNhbGxiYWNrKTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBMaXN0QXZhaWxhYmxlT3JnUG9saWN5Q29uc3RyYWludHMgc2V0RmllbGRzKGphdmEubGFuZy5TdHJpbmcgZmllbGRzKSB7CiAgICAgICAgcmV0dXJuIChMaXN0QXZhaWxhYmxlT3JnUG9saWN5Q29uc3RyYWludHMpIHN1cGVyLnNldEZpZWxkcyhmaWVsZHMpOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIExpc3RBdmFpbGFibGVPcmdQb2xpY3lDb25zdHJhaW50cyBzZXRLZXkoamF2YS5sYW5nLlN0cmluZyBrZXkpIHsKICAgICAgICByZXR1cm4gKExpc3RBdmFpbGFibGVPcmdQb2xpY3lDb25zdHJhaW50cykgc3VwZXIuc2V0S2V5KGtleSk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgTGlzdEF2YWlsYWJsZU9yZ1BvbGljeUNvbnN0cmFpbnRzIHNldE9hdXRoVG9rZW4oamF2YS5sYW5nLlN0cmluZyBvYXV0aFRva2VuKSB7CiAgICAgICAgcmV0dXJuIChMaXN0QXZhaWxhYmxlT3JnUG9saWN5Q29uc3RyYWludHMpIHN1cGVyLnNldE9hdXRoVG9rZW4ob2F1dGhUb2tlbik7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgTGlzdEF2YWlsYWJsZU9yZ1BvbGljeUNvbnN0cmFpbnRzIHNldFByZXR0eVByaW50KGphdmEubGFuZy5Cb29sZWFuIHByZXR0eVByaW50KSB7CiAgICAgICAgcmV0dXJuIChMaXN0QXZhaWxhYmxlT3JnUG9saWN5Q29uc3RyYWludHMpIHN1cGVyLnNldFByZXR0eVByaW50KHByZXR0eVByaW50KTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBMaXN0QXZhaWxhYmxlT3JnUG9saWN5Q29uc3RyYWludHMgc2V0UXVvdGFVc2VyKGphdmEubGFuZy5TdHJpbmcgcXVvdGFVc2VyKSB7CiAgICAgICAgcmV0dXJuIChMaXN0QXZhaWxhYmxlT3JnUG9saWN5Q29uc3RyYWludHMpIHN1cGVyLnNldFF1b3RhVXNlcihxdW90YVVzZXIpOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIExpc3RBdmFpbGFibGVPcmdQb2xpY3lDb25zdHJhaW50cyBzZXRVcGxvYWRUeXBlKGphdmEubGFuZy5TdHJpbmcgdXBsb2FkVHlwZSkgewogICAgICAgIHJldHVybiAoTGlzdEF2YWlsYWJsZU9yZ1BvbGljeUNvbnN0cmFpbnRzKSBzdXBlci5zZXRVcGxvYWRUeXBlKHVwbG9hZFR5cGUpOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIExpc3RBdmFpbGFibGVPcmdQb2xpY3lDb25zdHJhaW50cyBzZXRVcGxvYWRQcm90b2NvbChqYXZhLmxhbmcuU3RyaW5nIHVwbG9hZFByb3RvY29sKSB7CiAgICAgICAgcmV0dXJuIChMaXN0QXZhaWxhYmxlT3JnUG9saWN5Q29uc3RyYWludHMpIHN1cGVyLnNldFVwbG9hZFByb3RvY29sKHVwbG9hZFByb3RvY29sKTsKICAgICAgfQoKICAgICAgLyoqIE5hbWUgb2YgdGhlIHJlc291cmNlIHRvIGxpc3QgYENvbnN0cmFpbnRzYCBmb3IuICovCiAgICAgIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuU3RyaW5nIHJlc291cmNlOwoKICAgICAgLyoqIE5hbWUgb2YgdGhlIHJlc291cmNlIHRvIGxpc3QgYENvbnN0cmFpbnRzYCBmb3IuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRSZXNvdXJjZSgpIHsKICAgICAgICByZXR1cm4gcmVzb3VyY2U7CiAgICAgIH0KCiAgICAgIC8qKiBOYW1lIG9mIHRoZSByZXNvdXJjZSB0byBsaXN0IGBDb25zdHJhaW50c2AgZm9yLiAqLwogICAgICBwdWJsaWMgTGlzdEF2YWlsYWJsZU9yZ1BvbGljeUNvbnN0cmFpbnRzIHNldFJlc291cmNlKGphdmEubGFuZy5TdHJpbmcgcmVzb3VyY2UpIHsKICAgICAgICBpZiAoIWdldFN1cHByZXNzUGF0dGVybkNoZWNrcygpKSB7CiAgICAgICAgICBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5QcmVjb25kaXRpb25zLmNoZWNrQXJndW1lbnQoUkVTT1VSQ0VfUEFUVEVSTi5tYXRjaGVyKHJlc291cmNlKS5tYXRjaGVzKCksCiAgICAgICAgICAgICAgIlBhcmFtZXRlciByZXNvdXJjZSBtdXN0IGNvbmZvcm0gdG8gdGhlIHBhdHRlcm4gIiArCiAgICAgICAgICAgICAgIl5wcm9qZWN0cy9bXi9dKyQiKTsKICAgICAgICB9CiAgICAgICAgdGhpcy5yZXNvdXJjZSA9IHJlc291cmNlOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIExpc3RBdmFpbGFibGVPcmdQb2xpY3lDb25zdHJhaW50cyBzZXQoU3RyaW5nIHBhcmFtZXRlck5hbWUsIE9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiAoTGlzdEF2YWlsYWJsZU9yZ1BvbGljeUNvbnN0cmFpbnRzKSBzdXBlci5zZXQocGFyYW1ldGVyTmFtZSwgdmFsdWUpOwogICAgICB9CiAgICB9CiAgICAvKioKICAgICAqIExpc3RzIGFsbCB0aGUgYFBvbGljaWVzYCBzZXQgZm9yIGEgcGFydGljdWxhciByZXNvdXJjZS4KICAgICAqCiAgICAgKiBDcmVhdGUgYSByZXF1ZXN0IGZvciB0aGUgbWV0aG9kICJwcm9qZWN0cy5saXN0T3JnUG9saWNpZXMiLgogICAgICoKICAgICAqIFRoaXMgcmVxdWVzdCBob2xkcyB0aGUgcGFyYW1ldGVycyBuZWVkZWQgYnkgdGhlIGNsb3VkcmVzb3VyY2VtYW5hZ2VyIHNlcnZlci4gIEFmdGVyIHNldHRpbmcgYW55CiAgICAgKiBvcHRpb25hbCBwYXJhbWV0ZXJzLCBjYWxsIHRoZSB7QGxpbmsgTGlzdE9yZ1BvbGljaWVzI2V4ZWN1dGUoKX0gbWV0aG9kIHRvIGludm9rZSB0aGUgcmVtb3RlCiAgICAgKiBvcGVyYXRpb24uCiAgICAgKgogICAgICogQHBhcmFtIHJlc291cmNlIE5hbWUgb2YgdGhlIHJlc291cmNlIHRvIGxpc3QgUG9saWNpZXMgZm9yLgogICAgICogQHBhcmFtIGNvbnRlbnQgdGhlIHtAbGluayBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5jbG91ZHJlc291cmNlbWFuYWdlci5tb2RlbC5MaXN0T3JnUG9saWNpZXNSZXF1ZXN0fQogICAgICogQHJldHVybiB0aGUgcmVxdWVzdAogICAgICovCiAgICBwdWJsaWMgTGlzdE9yZ1BvbGljaWVzIGxpc3RPcmdQb2xpY2llcyhqYXZhLmxhbmcuU3RyaW5nIHJlc291cmNlLCBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5jbG91ZHJlc291cmNlbWFuYWdlci5tb2RlbC5MaXN0T3JnUG9saWNpZXNSZXF1ZXN0IGNvbnRlbnQpIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgTGlzdE9yZ1BvbGljaWVzIHJlc3VsdCA9IG5ldyBMaXN0T3JnUG9saWNpZXMocmVzb3VyY2UsIGNvbnRlbnQpOwogICAgICBpbml0aWFsaXplKHJlc3VsdCk7CiAgICAgIHJldHVybiByZXN1bHQ7CiAgICB9CgogICAgcHVibGljIGNsYXNzIExpc3RPcmdQb2xpY2llcyBleHRlbmRzIENsb3VkUmVzb3VyY2VNYW5hZ2VyUmVxdWVzdDxjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5jbG91ZHJlc291cmNlbWFuYWdlci5tb2RlbC5MaXN0T3JnUG9saWNpZXNSZXNwb25zZT4gewoKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFJFU1RfUEFUSCA9ICJ2MS97K3Jlc291cmNlfTpsaXN0T3JnUG9saWNpZXMiOwoKICAgICAgcHJpdmF0ZSBmaW5hbCBqYXZhLnV0aWwucmVnZXguUGF0dGVybiBSRVNPVVJDRV9QQVRURVJOID0KICAgICAgICAgIGphdmEudXRpbC5yZWdleC5QYXR0ZXJuLmNvbXBpbGUoIl5wcm9qZWN0cy9bXi9dKyQiKTsKCiAgICAgIC8qKgogICAgICAgKiBMaXN0cyBhbGwgdGhlIGBQb2xpY2llc2Agc2V0IGZvciBhIHBhcnRpY3VsYXIgcmVzb3VyY2UuCiAgICAgICAqCiAgICAgICAqIENyZWF0ZSBhIHJlcXVlc3QgZm9yIHRoZSBtZXRob2QgInByb2plY3RzLmxpc3RPcmdQb2xpY2llcyIuCiAgICAgICAqCiAgICAgICAqIFRoaXMgcmVxdWVzdCBob2xkcyB0aGUgcGFyYW1ldGVycyBuZWVkZWQgYnkgdGhlIHRoZSBjbG91ZHJlc291cmNlbWFuYWdlciBzZXJ2ZXIuICBBZnRlciBzZXR0aW5nCiAgICAgICAqIGFueSBvcHRpb25hbCBwYXJhbWV0ZXJzLCBjYWxsIHRoZSB7QGxpbmsgTGlzdE9yZ1BvbGljaWVzI2V4ZWN1dGUoKX0gbWV0aG9kIHRvIGludm9rZSB0aGUgcmVtb3RlCiAgICAgICAqIG9wZXJhdGlvbi4gPHA+IHtAbGluayBMaXN0T3JnUG9saWNpZXMjaW5pdGlhbGl6ZShjb20uZ29vZ2xlLmFwaS5jbGllbnQuZ29vZ2xlYXBpcy5zZXJ2aWNlcy5BYnN0CiAgICAgICAqIHJhY3RHb29nbGVDbGllbnRSZXF1ZXN0KX0gbXVzdCBiZSBjYWxsZWQgdG8gaW5pdGlhbGl6ZSB0aGlzIGluc3RhbmNlIGltbWVkaWF0ZWx5IGFmdGVyIGludm9raW5nCiAgICAgICAqIHRoZSBjb25zdHJ1Y3Rvci4gPC9wPgogICAgICAgKgogICAgICAgKiBAcGFyYW0gcmVzb3VyY2UgTmFtZSBvZiB0aGUgcmVzb3VyY2UgdG8gbGlzdCBQb2xpY2llcyBmb3IuCiAgICAgICAqIEBwYXJhbSBjb250ZW50IHRoZSB7QGxpbmsgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuY2xvdWRyZXNvdXJjZW1hbmFnZXIubW9kZWwuTGlzdE9yZ1BvbGljaWVzUmVxdWVzdH0KICAgICAgICogQHNpbmNlIDEuMTMKICAgICAgICovCiAgICAgIHByb3RlY3RlZCBMaXN0T3JnUG9saWNpZXMoamF2YS5sYW5nLlN0cmluZyByZXNvdXJjZSwgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuY2xvdWRyZXNvdXJjZW1hbmFnZXIubW9kZWwuTGlzdE9yZ1BvbGljaWVzUmVxdWVzdCBjb250ZW50KSB7CiAgICAgICAgc3VwZXIoQ2xvdWRSZXNvdXJjZU1hbmFnZXIudGhpcywgIlBPU1QiLCBSRVNUX1BBVEgsIGNvbnRlbnQsIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmNsb3VkcmVzb3VyY2VtYW5hZ2VyLm1vZGVsLkxpc3RPcmdQb2xpY2llc1Jlc3BvbnNlLmNsYXNzKTsKICAgICAgICB0aGlzLnJlc291cmNlID0gY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuUHJlY29uZGl0aW9ucy5jaGVja05vdE51bGwocmVzb3VyY2UsICJSZXF1aXJlZCBwYXJhbWV0ZXIgcmVzb3VyY2UgbXVzdCBiZSBzcGVjaWZpZWQuIik7CiAgICAgICAgaWYgKCFnZXRTdXBwcmVzc1BhdHRlcm5DaGVja3MoKSkgewogICAgICAgICAgY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuUHJlY29uZGl0aW9ucy5jaGVja0FyZ3VtZW50KFJFU09VUkNFX1BBVFRFUk4ubWF0Y2hlcihyZXNvdXJjZSkubWF0Y2hlcygpLAogICAgICAgICAgICAgICJQYXJhbWV0ZXIgcmVzb3VyY2UgbXVzdCBjb25mb3JtIHRvIHRoZSBwYXR0ZXJuICIgKwogICAgICAgICAgICAgICJecHJvamVjdHMvW14vXSskIik7CiAgICAgICAgfQogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIExpc3RPcmdQb2xpY2llcyBzZXQkWGdhZnYoamF2YS5sYW5nLlN0cmluZyAkWGdhZnYpIHsKICAgICAgICByZXR1cm4gKExpc3RPcmdQb2xpY2llcykgc3VwZXIuc2V0JFhnYWZ2KCRYZ2Fmdik7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgTGlzdE9yZ1BvbGljaWVzIHNldEFjY2Vzc1Rva2VuKGphdmEubGFuZy5TdHJpbmcgYWNjZXNzVG9rZW4pIHsKICAgICAgICByZXR1cm4gKExpc3RPcmdQb2xpY2llcykgc3VwZXIuc2V0QWNjZXNzVG9rZW4oYWNjZXNzVG9rZW4pOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIExpc3RPcmdQb2xpY2llcyBzZXRBbHQoamF2YS5sYW5nLlN0cmluZyBhbHQpIHsKICAgICAgICByZXR1cm4gKExpc3RPcmdQb2xpY2llcykgc3VwZXIuc2V0QWx0KGFsdCk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgTGlzdE9yZ1BvbGljaWVzIHNldENhbGxiYWNrKGphdmEubGFuZy5TdHJpbmcgY2FsbGJhY2spIHsKICAgICAgICByZXR1cm4gKExpc3RPcmdQb2xpY2llcykgc3VwZXIuc2V0Q2FsbGJhY2soY2FsbGJhY2spOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIExpc3RPcmdQb2xpY2llcyBzZXRGaWVsZHMoamF2YS5sYW5nLlN0cmluZyBmaWVsZHMpIHsKICAgICAgICByZXR1cm4gKExpc3RPcmdQb2xpY2llcykgc3VwZXIuc2V0RmllbGRzKGZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgTGlzdE9yZ1BvbGljaWVzIHNldEtleShqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIHJldHVybiAoTGlzdE9yZ1BvbGljaWVzKSBzdXBlci5zZXRLZXkoa2V5KTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBMaXN0T3JnUG9saWNpZXMgc2V0T2F1dGhUb2tlbihqYXZhLmxhbmcuU3RyaW5nIG9hdXRoVG9rZW4pIHsKICAgICAgICByZXR1cm4gKExpc3RPcmdQb2xpY2llcykgc3VwZXIuc2V0T2F1dGhUb2tlbihvYXV0aFRva2VuKTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBMaXN0T3JnUG9saWNpZXMgc2V0UHJldHR5UHJpbnQoamF2YS5sYW5nLkJvb2xlYW4gcHJldHR5UHJpbnQpIHsKICAgICAgICByZXR1cm4gKExpc3RPcmdQb2xpY2llcykgc3VwZXIuc2V0UHJldHR5UHJpbnQocHJldHR5UHJpbnQpOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIExpc3RPcmdQb2xpY2llcyBzZXRRdW90YVVzZXIoamF2YS5sYW5nLlN0cmluZyBxdW90YVVzZXIpIHsKICAgICAgICByZXR1cm4gKExpc3RPcmdQb2xpY2llcykgc3VwZXIuc2V0UXVvdGFVc2VyKHF1b3RhVXNlcik7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgTGlzdE9yZ1BvbGljaWVzIHNldFVwbG9hZFR5cGUoamF2YS5sYW5nLlN0cmluZyB1cGxvYWRUeXBlKSB7CiAgICAgICAgcmV0dXJuIChMaXN0T3JnUG9saWNpZXMpIHN1cGVyLnNldFVwbG9hZFR5cGUodXBsb2FkVHlwZSk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgTGlzdE9yZ1BvbGljaWVzIHNldFVwbG9hZFByb3RvY29sKGphdmEubGFuZy5TdHJpbmcgdXBsb2FkUHJvdG9jb2wpIHsKICAgICAgICByZXR1cm4gKExpc3RPcmdQb2xpY2llcykgc3VwZXIuc2V0VXBsb2FkUHJvdG9jb2wodXBsb2FkUHJvdG9jb2wpOwogICAgICB9CgogICAgICAvKiogTmFtZSBvZiB0aGUgcmVzb3VyY2UgdG8gbGlzdCBQb2xpY2llcyBmb3IuICovCiAgICAgIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuU3RyaW5nIHJlc291cmNlOwoKICAgICAgLyoqIE5hbWUgb2YgdGhlIHJlc291cmNlIHRvIGxpc3QgUG9saWNpZXMgZm9yLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0UmVzb3VyY2UoKSB7CiAgICAgICAgcmV0dXJuIHJlc291cmNlOwogICAgICB9CgogICAgICAvKiogTmFtZSBvZiB0aGUgcmVzb3VyY2UgdG8gbGlzdCBQb2xpY2llcyBmb3IuICovCiAgICAgIHB1YmxpYyBMaXN0T3JnUG9saWNpZXMgc2V0UmVzb3VyY2UoamF2YS5sYW5nLlN0cmluZyByZXNvdXJjZSkgewogICAgICAgIGlmICghZ2V0U3VwcHJlc3NQYXR0ZXJuQ2hlY2tzKCkpIHsKICAgICAgICAgIGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLlByZWNvbmRpdGlvbnMuY2hlY2tBcmd1bWVudChSRVNPVVJDRV9QQVRURVJOLm1hdGNoZXIocmVzb3VyY2UpLm1hdGNoZXMoKSwKICAgICAgICAgICAgICAiUGFyYW1ldGVyIHJlc291cmNlIG11c3QgY29uZm9ybSB0byB0aGUgcGF0dGVybiAiICsKICAgICAgICAgICAgICAiXnByb2plY3RzL1teL10rJCIpOwogICAgICAgIH0KICAgICAgICB0aGlzLnJlc291cmNlID0gcmVzb3VyY2U7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgTGlzdE9yZ1BvbGljaWVzIHNldChTdHJpbmcgcGFyYW1ldGVyTmFtZSwgT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIChMaXN0T3JnUG9saWNpZXMpIHN1cGVyLnNldChwYXJhbWV0ZXJOYW1lLCB2YWx1ZSk7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogU2V0cyB0aGUgSUFNIGFjY2VzcyBjb250cm9sIHBvbGljeSBmb3IgdGhlIHNwZWNpZmllZCBQcm9qZWN0LiBPdmVyd3JpdGVzIGFueSBleGlzdGluZyBwb2xpY3kuCiAgICAgKgogICAgICogVGhlIGZvbGxvd2luZyBjb25zdHJhaW50cyBhcHBseSB3aGVuIHVzaW5nIGBzZXRJYW1Qb2xpY3koKWA6CiAgICAgKgogICAgICogKyBQcm9qZWN0IGRvZXMgbm90IHN1cHBvcnQgYGFsbFVzZXJzYCBhbmQgYGFsbEF1dGhlbnRpY2F0ZWRVc2Vyc2AgYXMgYG1lbWJlcnNgIGluIGEgYEJpbmRpbmdgIG9mCiAgICAgKiBhIGBQb2xpY3lgLgogICAgICoKICAgICAqICsgVGhlIG93bmVyIHJvbGUgY2FuIGJlIGdyYW50ZWQgdG8gYSBgdXNlcmAsIGBzZXJ2aWNlQWNjb3VudGAsIG9yIGEgZ3JvdXAgdGhhdCBpcyBwYXJ0IG9mIGFuCiAgICAgKiBvcmdhbml6YXRpb24uIEZvciBleGFtcGxlLCBncm91cEBteW93bnBlcnNvbmFsZG9tYWluLmNvbSBjb3VsZCBiZSBhZGRlZCBhcyBhbiBvd25lciB0byBhIHByb2plY3QKICAgICAqIGluIHRoZSBteW93bnBlcnNvbmFsZG9tYWluLmNvbSBvcmdhbml6YXRpb24sIGJ1dCBub3QgdGhlIGV4YW1wbGVwZXRzdG9yZS5jb20gb3JnYW5pemF0aW9uLgogICAgICoKICAgICAqICsgU2VydmljZSBhY2NvdW50cyBjYW4gYmUgbWFkZSBvd25lcnMgb2YgYSBwcm9qZWN0IGRpcmVjdGx5IHdpdGhvdXQgYW55IHJlc3RyaWN0aW9ucy4gSG93ZXZlciwgdG8KICAgICAqIGJlIGFkZGVkIGFzIGFuIG93bmVyLCBhIHVzZXIgbXVzdCBiZSBpbnZpdGVkIHZpYSBDbG91ZCBQbGF0Zm9ybSBjb25zb2xlIGFuZCBtdXN0IGFjY2VwdCB0aGUKICAgICAqIGludml0YXRpb24uCiAgICAgKgogICAgICogKyBBIHVzZXIgY2Fubm90IGJlIGdyYW50ZWQgdGhlIG93bmVyIHJvbGUgdXNpbmcgYHNldElhbVBvbGljeSgpYC4gVGhlIHVzZXIgbXVzdCBiZSBncmFudGVkIHRoZQogICAgICogb3duZXIgcm9sZSB1c2luZyB0aGUgQ2xvdWQgUGxhdGZvcm0gQ29uc29sZSBhbmQgbXVzdCBleHBsaWNpdGx5IGFjY2VwdCB0aGUgaW52aXRhdGlvbi4KICAgICAqCiAgICAgKiArIFlvdSBjYW4gb25seSBncmFudCBvd25lcnNoaXAgb2YgYSBwcm9qZWN0IHRvIGEgbWVtYmVyIGJ5IHVzaW5nIHRoZSBHQ1AgQ29uc29sZS4gSW52aXRpbmcgYQogICAgICogbWVtYmVyIHdpbGwgZGVsaXZlciBhbiBpbnZpdGF0aW9uIGVtYWlsIHRoYXQgdGhleSBtdXN0IGFjY2VwdC4gQW4gaW52aXRhdGlvbiBlbWFpbCBpcyBub3QKICAgICAqIGdlbmVyYXRlZCBpZiB5b3UgYXJlIGdyYW50aW5nIGEgcm9sZSBvdGhlciB0aGFuIG93bmVyLCBvciBpZiBib3RoIHRoZSBtZW1iZXIgeW91IGFyZSBpbnZpdGluZyBhbmQKICAgICAqIHRoZSBwcm9qZWN0IGFyZSBwYXJ0IG9mIHlvdXIgb3JnYW5pemF0aW9uLgogICAgICoKICAgICAqICsgTWVtYmVyc2hpcCBjaGFuZ2VzIHRoYXQgbGVhdmUgdGhlIHByb2plY3Qgd2l0aG91dCBhbnkgb3duZXJzIHRoYXQgaGF2ZSBhY2NlcHRlZCB0aGUgVGVybXMgb2YKICAgICAqIFNlcnZpY2UgKFRvUykgd2lsbCBiZSByZWplY3RlZC4KICAgICAqCiAgICAgKiArIElmIHRoZSBwcm9qZWN0IGlzIG5vdCBwYXJ0IG9mIGFuIG9yZ2FuaXphdGlvbiwgdGhlcmUgbXVzdCBiZSBhdCBsZWFzdCBvbmUgb3duZXIgd2hvIGhhcwogICAgICogYWNjZXB0ZWQgdGhlIFRlcm1zIG9mIFNlcnZpY2UgKFRvUykgYWdyZWVtZW50IGluIHRoZSBwb2xpY3kuIENhbGxpbmcgYHNldElhbVBvbGljeSgpYCB0byByZW1vdmUKICAgICAqIHRoZSBsYXN0IFRvUy1hY2NlcHRlZCBvd25lciBmcm9tIHRoZSBwb2xpY3kgd2lsbCBmYWlsLiBUaGlzIHJlc3RyaWN0aW9uIGFsc28gYXBwbGllcyB0byBsZWdhY3kKICAgICAqIHByb2plY3RzIHRoYXQgbm8gbG9uZ2VyIGhhdmUgb3duZXJzIHdobyBoYXZlIGFjY2VwdGVkIHRoZSBUb1MuIEVkaXRzIHRvIElBTSBwb2xpY2llcyB3aWxsIGJlCiAgICAgKiByZWplY3RlZCB1bnRpbCB0aGUgbGFjayBvZiBhIFRvUy1hY2NlcHRpbmcgb3duZXIgaXMgcmVjdGlmaWVkLgogICAgICoKICAgICAqICsgVGhpcyBtZXRob2Qgd2lsbCByZXBsYWNlIHRoZSBleGlzdGluZyBwb2xpY3ksIGFuZCBjYW5ub3QgYmUgdXNlZCB0byBhcHBlbmQgYWRkaXRpb25hbCBJQU0KICAgICAqIHNldHRpbmdzLgogICAgICoKICAgICAqIE5vdGU6IFJlbW92aW5nIHNlcnZpY2UgYWNjb3VudHMgZnJvbSBwb2xpY2llcyBvciBjaGFuZ2luZyB0aGVpciByb2xlcyBjYW4gcmVuZGVyIHNlcnZpY2VzCiAgICAgKiBjb21wbGV0ZWx5IGlub3BlcmFibGUuIEl0IGlzIGltcG9ydGFudCB0byB1bmRlcnN0YW5kIGhvdyB0aGUgc2VydmljZSBhY2NvdW50IGlzIGJlaW5nIHVzZWQgYmVmb3JlCiAgICAgKiByZW1vdmluZyBvciB1cGRhdGluZyBpdHMgcm9sZXMuCiAgICAgKgogICAgICogQXV0aG9yaXphdGlvbiByZXF1aXJlcyB0aGUgR29vZ2xlIElBTSBwZXJtaXNzaW9uIGByZXNvdXJjZW1hbmFnZXIucHJvamVjdHMuc2V0SWFtUG9saWN5YCBvbiB0aGUKICAgICAqIHByb2plY3QKICAgICAqCiAgICAgKiBDcmVhdGUgYSByZXF1ZXN0IGZvciB0aGUgbWV0aG9kICJwcm9qZWN0cy5zZXRJYW1Qb2xpY3kiLgogICAgICoKICAgICAqIFRoaXMgcmVxdWVzdCBob2xkcyB0aGUgcGFyYW1ldGVycyBuZWVkZWQgYnkgdGhlIGNsb3VkcmVzb3VyY2VtYW5hZ2VyIHNlcnZlci4gIEFmdGVyIHNldHRpbmcgYW55CiAgICAgKiBvcHRpb25hbCBwYXJhbWV0ZXJzLCBjYWxsIHRoZSB7QGxpbmsgU2V0SWFtUG9saWN5I2V4ZWN1dGUoKX0gbWV0aG9kIHRvIGludm9rZSB0aGUgcmVtb3RlCiAgICAgKiBvcGVyYXRpb24uCiAgICAgKgogICAgICogQHBhcmFtIHJlc291cmNlIFJFUVVJUkVEOiBUaGUgcmVzb3VyY2UgZm9yIHdoaWNoIHRoZSBwb2xpY3kgaXMgYmVpbmcgc3BlY2lmaWVkLgogICAgU2VlIHRoZSBvcGVyYXRpb24gZG9jdW1lbnRhdGlvbiBmb3IKICAgICAqICAgICAgICB0aGUgYXBwcm9wcmlhdGUgdmFsdWUgZm9yIHRoaXMgZmllbGQuCiAgICAgKiBAcGFyYW0gY29udGVudCB0aGUge0BsaW5rIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmNsb3VkcmVzb3VyY2VtYW5hZ2VyLm1vZGVsLlNldElhbVBvbGljeVJlcXVlc3R9CiAgICAgKiBAcmV0dXJuIHRoZSByZXF1ZXN0CiAgICAgKi8KICAgIHB1YmxpYyBTZXRJYW1Qb2xpY3kgc2V0SWFtUG9saWN5KGphdmEubGFuZy5TdHJpbmcgcmVzb3VyY2UsIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmNsb3VkcmVzb3VyY2VtYW5hZ2VyLm1vZGVsLlNldElhbVBvbGljeVJlcXVlc3QgY29udGVudCkgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBTZXRJYW1Qb2xpY3kgcmVzdWx0ID0gbmV3IFNldElhbVBvbGljeShyZXNvdXJjZSwgY29udGVudCk7CiAgICAgIGluaXRpYWxpemUocmVzdWx0KTsKICAgICAgcmV0dXJuIHJlc3VsdDsKICAgIH0KCiAgICBwdWJsaWMgY2xhc3MgU2V0SWFtUG9saWN5IGV4dGVuZHMgQ2xvdWRSZXNvdXJjZU1hbmFnZXJSZXF1ZXN0PGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmNsb3VkcmVzb3VyY2VtYW5hZ2VyLm1vZGVsLlBvbGljeT4gewoKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFJFU1RfUEFUSCA9ICJ2MS9wcm9qZWN0cy97cmVzb3VyY2V9OnNldElhbVBvbGljeSI7CgogICAgICAvKioKICAgICAgICogU2V0cyB0aGUgSUFNIGFjY2VzcyBjb250cm9sIHBvbGljeSBmb3IgdGhlIHNwZWNpZmllZCBQcm9qZWN0LiBPdmVyd3JpdGVzIGFueSBleGlzdGluZyBwb2xpY3kuCiAgICAgICAqCiAgICAgICAqIFRoZSBmb2xsb3dpbmcgY29uc3RyYWludHMgYXBwbHkgd2hlbiB1c2luZyBgc2V0SWFtUG9saWN5KClgOgogICAgICAgKgogICAgICAgKiArIFByb2plY3QgZG9lcyBub3Qgc3VwcG9ydCBgYWxsVXNlcnNgIGFuZCBgYWxsQXV0aGVudGljYXRlZFVzZXJzYCBhcyBgbWVtYmVyc2AgaW4gYSBgQmluZGluZ2AKICAgICAgICogb2YgYSBgUG9saWN5YC4KICAgICAgICoKICAgICAgICogKyBUaGUgb3duZXIgcm9sZSBjYW4gYmUgZ3JhbnRlZCB0byBhIGB1c2VyYCwgYHNlcnZpY2VBY2NvdW50YCwgb3IgYSBncm91cCB0aGF0IGlzIHBhcnQgb2YgYW4KICAgICAgICogb3JnYW5pemF0aW9uLiBGb3IgZXhhbXBsZSwgZ3JvdXBAbXlvd25wZXJzb25hbGRvbWFpbi5jb20gY291bGQgYmUgYWRkZWQgYXMgYW4gb3duZXIgdG8gYQogICAgICAgKiBwcm9qZWN0IGluIHRoZSBteW93bnBlcnNvbmFsZG9tYWluLmNvbSBvcmdhbml6YXRpb24sIGJ1dCBub3QgdGhlIGV4YW1wbGVwZXRzdG9yZS5jb20KICAgICAgICogb3JnYW5pemF0aW9uLgogICAgICAgKgogICAgICAgKiArIFNlcnZpY2UgYWNjb3VudHMgY2FuIGJlIG1hZGUgb3duZXJzIG9mIGEgcHJvamVjdCBkaXJlY3RseSB3aXRob3V0IGFueSByZXN0cmljdGlvbnMuIEhvd2V2ZXIsCiAgICAgICAqIHRvIGJlIGFkZGVkIGFzIGFuIG93bmVyLCBhIHVzZXIgbXVzdCBiZSBpbnZpdGVkIHZpYSBDbG91ZCBQbGF0Zm9ybSBjb25zb2xlIGFuZCBtdXN0IGFjY2VwdCB0aGUKICAgICAgICogaW52aXRhdGlvbi4KICAgICAgICoKICAgICAgICogKyBBIHVzZXIgY2Fubm90IGJlIGdyYW50ZWQgdGhlIG93bmVyIHJvbGUgdXNpbmcgYHNldElhbVBvbGljeSgpYC4gVGhlIHVzZXIgbXVzdCBiZSBncmFudGVkIHRoZQogICAgICAgKiBvd25lciByb2xlIHVzaW5nIHRoZSBDbG91ZCBQbGF0Zm9ybSBDb25zb2xlIGFuZCBtdXN0IGV4cGxpY2l0bHkgYWNjZXB0IHRoZSBpbnZpdGF0aW9uLgogICAgICAgKgogICAgICAgKiArIFlvdSBjYW4gb25seSBncmFudCBvd25lcnNoaXAgb2YgYSBwcm9qZWN0IHRvIGEgbWVtYmVyIGJ5IHVzaW5nIHRoZSBHQ1AgQ29uc29sZS4gSW52aXRpbmcgYQogICAgICAgKiBtZW1iZXIgd2lsbCBkZWxpdmVyIGFuIGludml0YXRpb24gZW1haWwgdGhhdCB0aGV5IG11c3QgYWNjZXB0LiBBbiBpbnZpdGF0aW9uIGVtYWlsIGlzIG5vdAogICAgICAgKiBnZW5lcmF0ZWQgaWYgeW91IGFyZSBncmFudGluZyBhIHJvbGUgb3RoZXIgdGhhbiBvd25lciwgb3IgaWYgYm90aCB0aGUgbWVtYmVyIHlvdSBhcmUgaW52aXRpbmcKICAgICAgICogYW5kIHRoZSBwcm9qZWN0IGFyZSBwYXJ0IG9mIHlvdXIgb3JnYW5pemF0aW9uLgogICAgICAgKgogICAgICAgKiArIE1lbWJlcnNoaXAgY2hhbmdlcyB0aGF0IGxlYXZlIHRoZSBwcm9qZWN0IHdpdGhvdXQgYW55IG93bmVycyB0aGF0IGhhdmUgYWNjZXB0ZWQgdGhlIFRlcm1zIG9mCiAgICAgICAqIFNlcnZpY2UgKFRvUykgd2lsbCBiZSByZWplY3RlZC4KICAgICAgICoKICAgICAgICogKyBJZiB0aGUgcHJvamVjdCBpcyBub3QgcGFydCBvZiBhbiBvcmdhbml6YXRpb24sIHRoZXJlIG11c3QgYmUgYXQgbGVhc3Qgb25lIG93bmVyIHdobyBoYXMKICAgICAgICogYWNjZXB0ZWQgdGhlIFRlcm1zIG9mIFNlcnZpY2UgKFRvUykgYWdyZWVtZW50IGluIHRoZSBwb2xpY3kuIENhbGxpbmcgYHNldElhbVBvbGljeSgpYCB0byByZW1vdmUKICAgICAgICogdGhlIGxhc3QgVG9TLWFjY2VwdGVkIG93bmVyIGZyb20gdGhlIHBvbGljeSB3aWxsIGZhaWwuIFRoaXMgcmVzdHJpY3Rpb24gYWxzbyBhcHBsaWVzIHRvIGxlZ2FjeQogICAgICAgKiBwcm9qZWN0cyB0aGF0IG5vIGxvbmdlciBoYXZlIG93bmVycyB3aG8gaGF2ZSBhY2NlcHRlZCB0aGUgVG9TLiBFZGl0cyB0byBJQU0gcG9saWNpZXMgd2lsbCBiZQogICAgICAgKiByZWplY3RlZCB1bnRpbCB0aGUgbGFjayBvZiBhIFRvUy1hY2NlcHRpbmcgb3duZXIgaXMgcmVjdGlmaWVkLgogICAgICAgKgogICAgICAgKiArIFRoaXMgbWV0aG9kIHdpbGwgcmVwbGFjZSB0aGUgZXhpc3RpbmcgcG9saWN5LCBhbmQgY2Fubm90IGJlIHVzZWQgdG8gYXBwZW5kIGFkZGl0aW9uYWwgSUFNCiAgICAgICAqIHNldHRpbmdzLgogICAgICAgKgogICAgICAgKiBOb3RlOiBSZW1vdmluZyBzZXJ2aWNlIGFjY291bnRzIGZyb20gcG9saWNpZXMgb3IgY2hhbmdpbmcgdGhlaXIgcm9sZXMgY2FuIHJlbmRlciBzZXJ2aWNlcwogICAgICAgKiBjb21wbGV0ZWx5IGlub3BlcmFibGUuIEl0IGlzIGltcG9ydGFudCB0byB1bmRlcnN0YW5kIGhvdyB0aGUgc2VydmljZSBhY2NvdW50IGlzIGJlaW5nIHVzZWQKICAgICAgICogYmVmb3JlIHJlbW92aW5nIG9yIHVwZGF0aW5nIGl0cyByb2xlcy4KICAgICAgICoKICAgICAgICogQXV0aG9yaXphdGlvbiByZXF1aXJlcyB0aGUgR29vZ2xlIElBTSBwZXJtaXNzaW9uIGByZXNvdXJjZW1hbmFnZXIucHJvamVjdHMuc2V0SWFtUG9saWN5YCBvbiB0aGUKICAgICAgICogcHJvamVjdAogICAgICAgKgogICAgICAgKiBDcmVhdGUgYSByZXF1ZXN0IGZvciB0aGUgbWV0aG9kICJwcm9qZWN0cy5zZXRJYW1Qb2xpY3kiLgogICAgICAgKgogICAgICAgKiBUaGlzIHJlcXVlc3QgaG9sZHMgdGhlIHBhcmFtZXRlcnMgbmVlZGVkIGJ5IHRoZSB0aGUgY2xvdWRyZXNvdXJjZW1hbmFnZXIgc2VydmVyLiAgQWZ0ZXIgc2V0dGluZwogICAgICAgKiBhbnkgb3B0aW9uYWwgcGFyYW1ldGVycywgY2FsbCB0aGUge0BsaW5rIFNldElhbVBvbGljeSNleGVjdXRlKCl9IG1ldGhvZCB0byBpbnZva2UgdGhlIHJlbW90ZQogICAgICAgKiBvcGVyYXRpb24uIDxwPiB7QGxpbmsKICAgICAgICogU2V0SWFtUG9saWN5I2luaXRpYWxpemUoY29tLmdvb2dsZS5hcGkuY2xpZW50Lmdvb2dsZWFwaXMuc2VydmljZXMuQWJzdHJhY3RHb29nbGVDbGllbnRSZXF1ZXN0KX0KICAgICAgICogbXVzdCBiZSBjYWxsZWQgdG8gaW5pdGlhbGl6ZSB0aGlzIGluc3RhbmNlIGltbWVkaWF0ZWx5IGFmdGVyIGludm9raW5nIHRoZSBjb25zdHJ1Y3Rvci4gPC9wPgogICAgICAgKgogICAgICAgKiBAcGFyYW0gcmVzb3VyY2UgUkVRVUlSRUQ6IFRoZSByZXNvdXJjZSBmb3Igd2hpY2ggdGhlIHBvbGljeSBpcyBiZWluZyBzcGVjaWZpZWQuCiAgICBTZWUgdGhlIG9wZXJhdGlvbiBkb2N1bWVudGF0aW9uIGZvcgogICAgICogICAgICAgIHRoZSBhcHByb3ByaWF0ZSB2YWx1ZSBmb3IgdGhpcyBmaWVsZC4KICAgICAgICogQHBhcmFtIGNvbnRlbnQgdGhlIHtAbGluayBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5jbG91ZHJlc291cmNlbWFuYWdlci5tb2RlbC5TZXRJYW1Qb2xpY3lSZXF1ZXN0fQogICAgICAgKiBAc2luY2UgMS4xMwogICAgICAgKi8KICAgICAgcHJvdGVjdGVkIFNldElhbVBvbGljeShqYXZhLmxhbmcuU3RyaW5nIHJlc291cmNlLCBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5jbG91ZHJlc291cmNlbWFuYWdlci5tb2RlbC5TZXRJYW1Qb2xpY3lSZXF1ZXN0IGNvbnRlbnQpIHsKICAgICAgICBzdXBlcihDbG91ZFJlc291cmNlTWFuYWdlci50aGlzLCAiUE9TVCIsIFJFU1RfUEFUSCwgY29udGVudCwgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuY2xvdWRyZXNvdXJjZW1hbmFnZXIubW9kZWwuUG9saWN5LmNsYXNzKTsKICAgICAgICB0aGlzLnJlc291cmNlID0gY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuUHJlY29uZGl0aW9ucy5jaGVja05vdE51bGwocmVzb3VyY2UsICJSZXF1aXJlZCBwYXJhbWV0ZXIgcmVzb3VyY2UgbXVzdCBiZSBzcGVjaWZpZWQuIik7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgU2V0SWFtUG9saWN5IHNldCRYZ2FmdihqYXZhLmxhbmcuU3RyaW5nICRYZ2FmdikgewogICAgICAgIHJldHVybiAoU2V0SWFtUG9saWN5KSBzdXBlci5zZXQkWGdhZnYoJFhnYWZ2KTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBTZXRJYW1Qb2xpY3kgc2V0QWNjZXNzVG9rZW4oamF2YS5sYW5nLlN0cmluZyBhY2Nlc3NUb2tlbikgewogICAgICAgIHJldHVybiAoU2V0SWFtUG9saWN5KSBzdXBlci5zZXRBY2Nlc3NUb2tlbihhY2Nlc3NUb2tlbik7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgU2V0SWFtUG9saWN5IHNldEFsdChqYXZhLmxhbmcuU3RyaW5nIGFsdCkgewogICAgICAgIHJldHVybiAoU2V0SWFtUG9saWN5KSBzdXBlci5zZXRBbHQoYWx0KTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBTZXRJYW1Qb2xpY3kgc2V0Q2FsbGJhY2soamF2YS5sYW5nLlN0cmluZyBjYWxsYmFjaykgewogICAgICAgIHJldHVybiAoU2V0SWFtUG9saWN5KSBzdXBlci5zZXRDYWxsYmFjayhjYWxsYmFjayk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgU2V0SWFtUG9saWN5IHNldEZpZWxkcyhqYXZhLmxhbmcuU3RyaW5nIGZpZWxkcykgewogICAgICAgIHJldHVybiAoU2V0SWFtUG9saWN5KSBzdXBlci5zZXRGaWVsZHMoZmllbGRzKTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBTZXRJYW1Qb2xpY3kgc2V0S2V5KGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgcmV0dXJuIChTZXRJYW1Qb2xpY3kpIHN1cGVyLnNldEtleShrZXkpOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIFNldElhbVBvbGljeSBzZXRPYXV0aFRva2VuKGphdmEubGFuZy5TdHJpbmcgb2F1dGhUb2tlbikgewogICAgICAgIHJldHVybiAoU2V0SWFtUG9saWN5KSBzdXBlci5zZXRPYXV0aFRva2VuKG9hdXRoVG9rZW4pOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIFNldElhbVBvbGljeSBzZXRQcmV0dHlQcmludChqYXZhLmxhbmcuQm9vbGVhbiBwcmV0dHlQcmludCkgewogICAgICAgIHJldHVybiAoU2V0SWFtUG9saWN5KSBzdXBlci5zZXRQcmV0dHlQcmludChwcmV0dHlQcmludCk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgU2V0SWFtUG9saWN5IHNldFF1b3RhVXNlcihqYXZhLmxhbmcuU3RyaW5nIHF1b3RhVXNlcikgewogICAgICAgIHJldHVybiAoU2V0SWFtUG9saWN5KSBzdXBlci5zZXRRdW90YVVzZXIocXVvdGFVc2VyKTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBTZXRJYW1Qb2xpY3kgc2V0VXBsb2FkVHlwZShqYXZhLmxhbmcuU3RyaW5nIHVwbG9hZFR5cGUpIHsKICAgICAgICByZXR1cm4gKFNldElhbVBvbGljeSkgc3VwZXIuc2V0VXBsb2FkVHlwZSh1cGxvYWRUeXBlKTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBTZXRJYW1Qb2xpY3kgc2V0VXBsb2FkUHJvdG9jb2woamF2YS5sYW5nLlN0cmluZyB1cGxvYWRQcm90b2NvbCkgewogICAgICAgIHJldHVybiAoU2V0SWFtUG9saWN5KSBzdXBlci5zZXRVcGxvYWRQcm90b2NvbCh1cGxvYWRQcm90b2NvbCk7CiAgICAgIH0KCiAgICAgIC8qKgogICAgICAgKiBSRVFVSVJFRDogVGhlIHJlc291cmNlIGZvciB3aGljaCB0aGUgcG9saWN5IGlzIGJlaW5nIHNwZWNpZmllZC4gU2VlIHRoZSBvcGVyYXRpb24KICAgICAgICogZG9jdW1lbnRhdGlvbiBmb3IgdGhlIGFwcHJvcHJpYXRlIHZhbHVlIGZvciB0aGlzIGZpZWxkLgogICAgICAgKi8KICAgICAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogICAgICBwcml2YXRlIGphdmEubGFuZy5TdHJpbmcgcmVzb3VyY2U7CgogICAgICAvKiogUkVRVUlSRUQ6IFRoZSByZXNvdXJjZSBmb3Igd2hpY2ggdGhlIHBvbGljeSBpcyBiZWluZyBzcGVjaWZpZWQuIFNlZSB0aGUgb3BlcmF0aW9uIGRvY3VtZW50YXRpb24gZm9yCiAgICAgdGhlIGFwcHJvcHJpYXRlIHZhbHVlIGZvciB0aGlzIGZpZWxkLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0UmVzb3VyY2UoKSB7CiAgICAgICAgcmV0dXJuIHJlc291cmNlOwogICAgICB9CgogICAgICAvKioKICAgICAgICogUkVRVUlSRUQ6IFRoZSByZXNvdXJjZSBmb3Igd2hpY2ggdGhlIHBvbGljeSBpcyBiZWluZyBzcGVjaWZpZWQuIFNlZSB0aGUgb3BlcmF0aW9uCiAgICAgICAqIGRvY3VtZW50YXRpb24gZm9yIHRoZSBhcHByb3ByaWF0ZSB2YWx1ZSBmb3IgdGhpcyBmaWVsZC4KICAgICAgICovCiAgICAgIHB1YmxpYyBTZXRJYW1Qb2xpY3kgc2V0UmVzb3VyY2UoamF2YS5sYW5nLlN0cmluZyByZXNvdXJjZSkgewogICAgICAgIHRoaXMucmVzb3VyY2UgPSByZXNvdXJjZTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBTZXRJYW1Qb2xpY3kgc2V0KFN0cmluZyBwYXJhbWV0ZXJOYW1lLCBPYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gKFNldElhbVBvbGljeSkgc3VwZXIuc2V0KHBhcmFtZXRlck5hbWUsIHZhbHVlKTsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiBVcGRhdGVzIHRoZSBzcGVjaWZpZWQgYFBvbGljeWAgb24gdGhlIHJlc291cmNlLiBDcmVhdGVzIGEgbmV3IGBQb2xpY3lgIGZvciB0aGF0IGBDb25zdHJhaW50YCBvbgogICAgICogdGhlIHJlc291cmNlIGlmIG9uZSBkb2VzIG5vdCBleGlzdC4KICAgICAqCiAgICAgKiBOb3Qgc3VwcGx5aW5nIGFuIGBldGFnYCBvbiB0aGUgcmVxdWVzdCBgUG9saWN5YCByZXN1bHRzIGluIGFuIHVuY29uZGl0aW9uYWwgd3JpdGUgb2YgdGhlCiAgICAgKiBgUG9saWN5YC4KICAgICAqCiAgICAgKiBDcmVhdGUgYSByZXF1ZXN0IGZvciB0aGUgbWV0aG9kICJwcm9qZWN0cy5zZXRPcmdQb2xpY3kiLgogICAgICoKICAgICAqIFRoaXMgcmVxdWVzdCBob2xkcyB0aGUgcGFyYW1ldGVycyBuZWVkZWQgYnkgdGhlIGNsb3VkcmVzb3VyY2VtYW5hZ2VyIHNlcnZlci4gIEFmdGVyIHNldHRpbmcgYW55CiAgICAgKiBvcHRpb25hbCBwYXJhbWV0ZXJzLCBjYWxsIHRoZSB7QGxpbmsgU2V0T3JnUG9saWN5I2V4ZWN1dGUoKX0gbWV0aG9kIHRvIGludm9rZSB0aGUgcmVtb3RlCiAgICAgKiBvcGVyYXRpb24uCiAgICAgKgogICAgICogQHBhcmFtIHJlc291cmNlIFJlc291cmNlIG5hbWUgb2YgdGhlIHJlc291cmNlIHRvIGF0dGFjaCB0aGUgYFBvbGljeWAuCiAgICAgKiBAcGFyYW0gY29udGVudCB0aGUge0BsaW5rIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmNsb3VkcmVzb3VyY2VtYW5hZ2VyLm1vZGVsLlNldE9yZ1BvbGljeVJlcXVlc3R9CiAgICAgKiBAcmV0dXJuIHRoZSByZXF1ZXN0CiAgICAgKi8KICAgIHB1YmxpYyBTZXRPcmdQb2xpY3kgc2V0T3JnUG9saWN5KGphdmEubGFuZy5TdHJpbmcgcmVzb3VyY2UsIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmNsb3VkcmVzb3VyY2VtYW5hZ2VyLm1vZGVsLlNldE9yZ1BvbGljeVJlcXVlc3QgY29udGVudCkgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBTZXRPcmdQb2xpY3kgcmVzdWx0ID0gbmV3IFNldE9yZ1BvbGljeShyZXNvdXJjZSwgY29udGVudCk7CiAgICAgIGluaXRpYWxpemUocmVzdWx0KTsKICAgICAgcmV0dXJuIHJlc3VsdDsKICAgIH0KCiAgICBwdWJsaWMgY2xhc3MgU2V0T3JnUG9saWN5IGV4dGVuZHMgQ2xvdWRSZXNvdXJjZU1hbmFnZXJSZXF1ZXN0PGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmNsb3VkcmVzb3VyY2VtYW5hZ2VyLm1vZGVsLk9yZ1BvbGljeT4gewoKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFJFU1RfUEFUSCA9ICJ2MS97K3Jlc291cmNlfTpzZXRPcmdQb2xpY3kiOwoKICAgICAgcHJpdmF0ZSBmaW5hbCBqYXZhLnV0aWwucmVnZXguUGF0dGVybiBSRVNPVVJDRV9QQVRURVJOID0KICAgICAgICAgIGphdmEudXRpbC5yZWdleC5QYXR0ZXJuLmNvbXBpbGUoIl5wcm9qZWN0cy9bXi9dKyQiKTsKCiAgICAgIC8qKgogICAgICAgKiBVcGRhdGVzIHRoZSBzcGVjaWZpZWQgYFBvbGljeWAgb24gdGhlIHJlc291cmNlLiBDcmVhdGVzIGEgbmV3IGBQb2xpY3lgIGZvciB0aGF0IGBDb25zdHJhaW50YCBvbgogICAgICAgKiB0aGUgcmVzb3VyY2UgaWYgb25lIGRvZXMgbm90IGV4aXN0LgogICAgICAgKgogICAgICAgKiBOb3Qgc3VwcGx5aW5nIGFuIGBldGFnYCBvbiB0aGUgcmVxdWVzdCBgUG9saWN5YCByZXN1bHRzIGluIGFuIHVuY29uZGl0aW9uYWwgd3JpdGUgb2YgdGhlCiAgICAgICAqIGBQb2xpY3lgLgogICAgICAgKgogICAgICAgKiBDcmVhdGUgYSByZXF1ZXN0IGZvciB0aGUgbWV0aG9kICJwcm9qZWN0cy5zZXRPcmdQb2xpY3kiLgogICAgICAgKgogICAgICAgKiBUaGlzIHJlcXVlc3QgaG9sZHMgdGhlIHBhcmFtZXRlcnMgbmVlZGVkIGJ5IHRoZSB0aGUgY2xvdWRyZXNvdXJjZW1hbmFnZXIgc2VydmVyLiAgQWZ0ZXIgc2V0dGluZwogICAgICAgKiBhbnkgb3B0aW9uYWwgcGFyYW1ldGVycywgY2FsbCB0aGUge0BsaW5rIFNldE9yZ1BvbGljeSNleGVjdXRlKCl9IG1ldGhvZCB0byBpbnZva2UgdGhlIHJlbW90ZQogICAgICAgKiBvcGVyYXRpb24uIDxwPiB7QGxpbmsKICAgICAgICogU2V0T3JnUG9saWN5I2luaXRpYWxpemUoY29tLmdvb2dsZS5hcGkuY2xpZW50Lmdvb2dsZWFwaXMuc2VydmljZXMuQWJzdHJhY3RHb29nbGVDbGllbnRSZXF1ZXN0KX0KICAgICAgICogbXVzdCBiZSBjYWxsZWQgdG8gaW5pdGlhbGl6ZSB0aGlzIGluc3RhbmNlIGltbWVkaWF0ZWx5IGFmdGVyIGludm9raW5nIHRoZSBjb25zdHJ1Y3Rvci4gPC9wPgogICAgICAgKgogICAgICAgKiBAcGFyYW0gcmVzb3VyY2UgUmVzb3VyY2UgbmFtZSBvZiB0aGUgcmVzb3VyY2UgdG8gYXR0YWNoIHRoZSBgUG9saWN5YC4KICAgICAgICogQHBhcmFtIGNvbnRlbnQgdGhlIHtAbGluayBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5jbG91ZHJlc291cmNlbWFuYWdlci5tb2RlbC5TZXRPcmdQb2xpY3lSZXF1ZXN0fQogICAgICAgKiBAc2luY2UgMS4xMwogICAgICAgKi8KICAgICAgcHJvdGVjdGVkIFNldE9yZ1BvbGljeShqYXZhLmxhbmcuU3RyaW5nIHJlc291cmNlLCBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5jbG91ZHJlc291cmNlbWFuYWdlci5tb2RlbC5TZXRPcmdQb2xpY3lSZXF1ZXN0IGNvbnRlbnQpIHsKICAgICAgICBzdXBlcihDbG91ZFJlc291cmNlTWFuYWdlci50aGlzLCAiUE9TVCIsIFJFU1RfUEFUSCwgY29udGVudCwgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuY2xvdWRyZXNvdXJjZW1hbmFnZXIubW9kZWwuT3JnUG9saWN5LmNsYXNzKTsKICAgICAgICB0aGlzLnJlc291cmNlID0gY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuUHJlY29uZGl0aW9ucy5jaGVja05vdE51bGwocmVzb3VyY2UsICJSZXF1aXJlZCBwYXJhbWV0ZXIgcmVzb3VyY2UgbXVzdCBiZSBzcGVjaWZpZWQuIik7CiAgICAgICAgaWYgKCFnZXRTdXBwcmVzc1BhdHRlcm5DaGVja3MoKSkgewogICAgICAgICAgY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuUHJlY29uZGl0aW9ucy5jaGVja0FyZ3VtZW50KFJFU09VUkNFX1BBVFRFUk4ubWF0Y2hlcihyZXNvdXJjZSkubWF0Y2hlcygpLAogICAgICAgICAgICAgICJQYXJhbWV0ZXIgcmVzb3VyY2UgbXVzdCBjb25mb3JtIHRvIHRoZSBwYXR0ZXJuICIgKwogICAgICAgICAgICAgICJecHJvamVjdHMvW14vXSskIik7CiAgICAgICAgfQogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIFNldE9yZ1BvbGljeSBzZXQkWGdhZnYoamF2YS5sYW5nLlN0cmluZyAkWGdhZnYpIHsKICAgICAgICByZXR1cm4gKFNldE9yZ1BvbGljeSkgc3VwZXIuc2V0JFhnYWZ2KCRYZ2Fmdik7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgU2V0T3JnUG9saWN5IHNldEFjY2Vzc1Rva2VuKGphdmEubGFuZy5TdHJpbmcgYWNjZXNzVG9rZW4pIHsKICAgICAgICByZXR1cm4gKFNldE9yZ1BvbGljeSkgc3VwZXIuc2V0QWNjZXNzVG9rZW4oYWNjZXNzVG9rZW4pOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIFNldE9yZ1BvbGljeSBzZXRBbHQoamF2YS5sYW5nLlN0cmluZyBhbHQpIHsKICAgICAgICByZXR1cm4gKFNldE9yZ1BvbGljeSkgc3VwZXIuc2V0QWx0KGFsdCk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgU2V0T3JnUG9saWN5IHNldENhbGxiYWNrKGphdmEubGFuZy5TdHJpbmcgY2FsbGJhY2spIHsKICAgICAgICByZXR1cm4gKFNldE9yZ1BvbGljeSkgc3VwZXIuc2V0Q2FsbGJhY2soY2FsbGJhY2spOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIFNldE9yZ1BvbGljeSBzZXRGaWVsZHMoamF2YS5sYW5nLlN0cmluZyBmaWVsZHMpIHsKICAgICAgICByZXR1cm4gKFNldE9yZ1BvbGljeSkgc3VwZXIuc2V0RmllbGRzKGZpZWxkcyk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgU2V0T3JnUG9saWN5IHNldEtleShqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIHJldHVybiAoU2V0T3JnUG9saWN5KSBzdXBlci5zZXRLZXkoa2V5KTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBTZXRPcmdQb2xpY3kgc2V0T2F1dGhUb2tlbihqYXZhLmxhbmcuU3RyaW5nIG9hdXRoVG9rZW4pIHsKICAgICAgICByZXR1cm4gKFNldE9yZ1BvbGljeSkgc3VwZXIuc2V0T2F1dGhUb2tlbihvYXV0aFRva2VuKTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBTZXRPcmdQb2xpY3kgc2V0UHJldHR5UHJpbnQoamF2YS5sYW5nLkJvb2xlYW4gcHJldHR5UHJpbnQpIHsKICAgICAgICByZXR1cm4gKFNldE9yZ1BvbGljeSkgc3VwZXIuc2V0UHJldHR5UHJpbnQocHJldHR5UHJpbnQpOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIFNldE9yZ1BvbGljeSBzZXRRdW90YVVzZXIoamF2YS5sYW5nLlN0cmluZyBxdW90YVVzZXIpIHsKICAgICAgICByZXR1cm4gKFNldE9yZ1BvbGljeSkgc3VwZXIuc2V0UXVvdGFVc2VyKHF1b3RhVXNlcik7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgU2V0T3JnUG9saWN5IHNldFVwbG9hZFR5cGUoamF2YS5sYW5nLlN0cmluZyB1cGxvYWRUeXBlKSB7CiAgICAgICAgcmV0dXJuIChTZXRPcmdQb2xpY3kpIHN1cGVyLnNldFVwbG9hZFR5cGUodXBsb2FkVHlwZSk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgU2V0T3JnUG9saWN5IHNldFVwbG9hZFByb3RvY29sKGphdmEubGFuZy5TdHJpbmcgdXBsb2FkUHJvdG9jb2wpIHsKICAgICAgICByZXR1cm4gKFNldE9yZ1BvbGljeSkgc3VwZXIuc2V0VXBsb2FkUHJvdG9jb2wodXBsb2FkUHJvdG9jb2wpOwogICAgICB9CgogICAgICAvKiogUmVzb3VyY2UgbmFtZSBvZiB0aGUgcmVzb3VyY2UgdG8gYXR0YWNoIHRoZSBgUG9saWN5YC4gKi8KICAgICAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogICAgICBwcml2YXRlIGphdmEubGFuZy5TdHJpbmcgcmVzb3VyY2U7CgogICAgICAvKiogUmVzb3VyY2UgbmFtZSBvZiB0aGUgcmVzb3VyY2UgdG8gYXR0YWNoIHRoZSBgUG9saWN5YC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFJlc291cmNlKCkgewogICAgICAgIHJldHVybiByZXNvdXJjZTsKICAgICAgfQoKICAgICAgLyoqIFJlc291cmNlIG5hbWUgb2YgdGhlIHJlc291cmNlIHRvIGF0dGFjaCB0aGUgYFBvbGljeWAuICovCiAgICAgIHB1YmxpYyBTZXRPcmdQb2xpY3kgc2V0UmVzb3VyY2UoamF2YS5sYW5nLlN0cmluZyByZXNvdXJjZSkgewogICAgICAgIGlmICghZ2V0U3VwcHJlc3NQYXR0ZXJuQ2hlY2tzKCkpIHsKICAgICAgICAgIGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLlByZWNvbmRpdGlvbnMuY2hlY2tBcmd1bWVudChSRVNPVVJDRV9QQVRURVJOLm1hdGNoZXIocmVzb3VyY2UpLm1hdGNoZXMoKSwKICAgICAgICAgICAgICAiUGFyYW1ldGVyIHJlc291cmNlIG11c3QgY29uZm9ybSB0byB0aGUgcGF0dGVybiAiICsKICAgICAgICAgICAgICAiXnByb2plY3RzL1teL10rJCIpOwogICAgICAgIH0KICAgICAgICB0aGlzLnJlc291cmNlID0gcmVzb3VyY2U7CiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgU2V0T3JnUG9saWN5IHNldChTdHJpbmcgcGFyYW1ldGVyTmFtZSwgT2JqZWN0IHZhbHVlKSB7CiAgICAgICAgcmV0dXJuIChTZXRPcmdQb2xpY3kpIHN1cGVyLnNldChwYXJhbWV0ZXJOYW1lLCB2YWx1ZSk7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogUmV0dXJucyBwZXJtaXNzaW9ucyB0aGF0IGEgY2FsbGVyIGhhcyBvbiB0aGUgc3BlY2lmaWVkIFByb2plY3QuCiAgICAgKgogICAgICogVGhlcmUgYXJlIG5vIHBlcm1pc3Npb25zIHJlcXVpcmVkIGZvciBtYWtpbmcgdGhpcyBBUEkgY2FsbC4KICAgICAqCiAgICAgKiBDcmVhdGUgYSByZXF1ZXN0IGZvciB0aGUgbWV0aG9kICJwcm9qZWN0cy50ZXN0SWFtUGVybWlzc2lvbnMiLgogICAgICoKICAgICAqIFRoaXMgcmVxdWVzdCBob2xkcyB0aGUgcGFyYW1ldGVycyBuZWVkZWQgYnkgdGhlIGNsb3VkcmVzb3VyY2VtYW5hZ2VyIHNlcnZlci4gIEFmdGVyIHNldHRpbmcgYW55CiAgICAgKiBvcHRpb25hbCBwYXJhbWV0ZXJzLCBjYWxsIHRoZSB7QGxpbmsgVGVzdElhbVBlcm1pc3Npb25zI2V4ZWN1dGUoKX0gbWV0aG9kIHRvIGludm9rZSB0aGUgcmVtb3RlCiAgICAgKiBvcGVyYXRpb24uCiAgICAgKgogICAgICogQHBhcmFtIHJlc291cmNlIFJFUVVJUkVEOiBUaGUgcmVzb3VyY2UgZm9yIHdoaWNoIHRoZSBwb2xpY3kgZGV0YWlsIGlzIGJlaW5nIHJlcXVlc3RlZC4KICAgIFNlZSB0aGUgb3BlcmF0aW9uCiAgICAgKiAgICAgICAgZG9jdW1lbnRhdGlvbiBmb3IgdGhlIGFwcHJvcHJpYXRlIHZhbHVlIGZvciB0aGlzIGZpZWxkLgogICAgICogQHBhcmFtIGNvbnRlbnQgdGhlIHtAbGluayBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5jbG91ZHJlc291cmNlbWFuYWdlci5tb2RlbC5UZXN0SWFtUGVybWlzc2lvbnNSZXF1ZXN0fQogICAgICogQHJldHVybiB0aGUgcmVxdWVzdAogICAgICovCiAgICBwdWJsaWMgVGVzdElhbVBlcm1pc3Npb25zIHRlc3RJYW1QZXJtaXNzaW9ucyhqYXZhLmxhbmcuU3RyaW5nIHJlc291cmNlLCBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5jbG91ZHJlc291cmNlbWFuYWdlci5tb2RlbC5UZXN0SWFtUGVybWlzc2lvbnNSZXF1ZXN0IGNvbnRlbnQpIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgVGVzdElhbVBlcm1pc3Npb25zIHJlc3VsdCA9IG5ldyBUZXN0SWFtUGVybWlzc2lvbnMocmVzb3VyY2UsIGNvbnRlbnQpOwogICAgICBpbml0aWFsaXplKHJlc3VsdCk7CiAgICAgIHJldHVybiByZXN1bHQ7CiAgICB9CgogICAgcHVibGljIGNsYXNzIFRlc3RJYW1QZXJtaXNzaW9ucyBleHRlbmRzIENsb3VkUmVzb3VyY2VNYW5hZ2VyUmVxdWVzdDxjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5jbG91ZHJlc291cmNlbWFuYWdlci5tb2RlbC5UZXN0SWFtUGVybWlzc2lvbnNSZXNwb25zZT4gewoKICAgICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFJFU1RfUEFUSCA9ICJ2MS9wcm9qZWN0cy97cmVzb3VyY2V9OnRlc3RJYW1QZXJtaXNzaW9ucyI7CgogICAgICAvKioKICAgICAgICogUmV0dXJucyBwZXJtaXNzaW9ucyB0aGF0IGEgY2FsbGVyIGhhcyBvbiB0aGUgc3BlY2lmaWVkIFByb2plY3QuCiAgICAgICAqCiAgICAgICAqIFRoZXJlIGFyZSBubyBwZXJtaXNzaW9ucyByZXF1aXJlZCBmb3IgbWFraW5nIHRoaXMgQVBJIGNhbGwuCiAgICAgICAqCiAgICAgICAqIENyZWF0ZSBhIHJlcXVlc3QgZm9yIHRoZSBtZXRob2QgInByb2plY3RzLnRlc3RJYW1QZXJtaXNzaW9ucyIuCiAgICAgICAqCiAgICAgICAqIFRoaXMgcmVxdWVzdCBob2xkcyB0aGUgcGFyYW1ldGVycyBuZWVkZWQgYnkgdGhlIHRoZSBjbG91ZHJlc291cmNlbWFuYWdlciBzZXJ2ZXIuICBBZnRlciBzZXR0aW5nCiAgICAgICAqIGFueSBvcHRpb25hbCBwYXJhbWV0ZXJzLCBjYWxsIHRoZSB7QGxpbmsgVGVzdElhbVBlcm1pc3Npb25zI2V4ZWN1dGUoKX0gbWV0aG9kIHRvIGludm9rZSB0aGUKICAgICAgICogcmVtb3RlIG9wZXJhdGlvbi4gPHA+IHtAbGluayBUZXN0SWFtUGVybWlzc2lvbnMjaW5pdGlhbGl6ZShjb20uZ29vZ2xlLmFwaS5jbGllbnQuZ29vZ2xlYXBpcy5zZXIKICAgICAgICogdmljZXMuQWJzdHJhY3RHb29nbGVDbGllbnRSZXF1ZXN0KX0gbXVzdCBiZSBjYWxsZWQgdG8gaW5pdGlhbGl6ZSB0aGlzIGluc3RhbmNlIGltbWVkaWF0ZWx5CiAgICAgICAqIGFmdGVyIGludm9raW5nIHRoZSBjb25zdHJ1Y3Rvci4gPC9wPgogICAgICAgKgogICAgICAgKiBAcGFyYW0gcmVzb3VyY2UgUkVRVUlSRUQ6IFRoZSByZXNvdXJjZSBmb3Igd2hpY2ggdGhlIHBvbGljeSBkZXRhaWwgaXMgYmVpbmcgcmVxdWVzdGVkLgogICAgU2VlIHRoZSBvcGVyYXRpb24KICAgICAqICAgICAgICBkb2N1bWVudGF0aW9uIGZvciB0aGUgYXBwcm9wcmlhdGUgdmFsdWUgZm9yIHRoaXMgZmllbGQuCiAgICAgICAqIEBwYXJhbSBjb250ZW50IHRoZSB7QGxpbmsgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuY2xvdWRyZXNvdXJjZW1hbmFnZXIubW9kZWwuVGVzdElhbVBlcm1pc3Npb25zUmVxdWVzdH0KICAgICAgICogQHNpbmNlIDEuMTMKICAgICAgICovCiAgICAgIHByb3RlY3RlZCBUZXN0SWFtUGVybWlzc2lvbnMoamF2YS5sYW5nLlN0cmluZyByZXNvdXJjZSwgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuY2xvdWRyZXNvdXJjZW1hbmFnZXIubW9kZWwuVGVzdElhbVBlcm1pc3Npb25zUmVxdWVzdCBjb250ZW50KSB7CiAgICAgICAgc3VwZXIoQ2xvdWRSZXNvdXJjZU1hbmFnZXIudGhpcywgIlBPU1QiLCBSRVNUX1BBVEgsIGNvbnRlbnQsIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmNsb3VkcmVzb3VyY2VtYW5hZ2VyLm1vZGVsLlRlc3RJYW1QZXJtaXNzaW9uc1Jlc3BvbnNlLmNsYXNzKTsKICAgICAgICB0aGlzLnJlc291cmNlID0gY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuUHJlY29uZGl0aW9ucy5jaGVja05vdE51bGwocmVzb3VyY2UsICJSZXF1aXJlZCBwYXJhbWV0ZXIgcmVzb3VyY2UgbXVzdCBiZSBzcGVjaWZpZWQuIik7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgVGVzdElhbVBlcm1pc3Npb25zIHNldCRYZ2FmdihqYXZhLmxhbmcuU3RyaW5nICRYZ2FmdikgewogICAgICAgIHJldHVybiAoVGVzdElhbVBlcm1pc3Npb25zKSBzdXBlci5zZXQkWGdhZnYoJFhnYWZ2KTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBUZXN0SWFtUGVybWlzc2lvbnMgc2V0QWNjZXNzVG9rZW4oamF2YS5sYW5nLlN0cmluZyBhY2Nlc3NUb2tlbikgewogICAgICAgIHJldHVybiAoVGVzdElhbVBlcm1pc3Npb25zKSBzdXBlci5zZXRBY2Nlc3NUb2tlbihhY2Nlc3NUb2tlbik7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgVGVzdElhbVBlcm1pc3Npb25zIHNldEFsdChqYXZhLmxhbmcuU3RyaW5nIGFsdCkgewogICAgICAgIHJldHVybiAoVGVzdElhbVBlcm1pc3Npb25zKSBzdXBlci5zZXRBbHQoYWx0KTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBUZXN0SWFtUGVybWlzc2lvbnMgc2V0Q2FsbGJhY2soamF2YS5sYW5nLlN0cmluZyBjYWxsYmFjaykgewogICAgICAgIHJldHVybiAoVGVzdElhbVBlcm1pc3Npb25zKSBzdXBlci5zZXRDYWxsYmFjayhjYWxsYmFjayk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgVGVzdElhbVBlcm1pc3Npb25zIHNldEZpZWxkcyhqYXZhLmxhbmcuU3RyaW5nIGZpZWxkcykgewogICAgICAgIHJldHVybiAoVGVzdElhbVBlcm1pc3Npb25zKSBzdXBlci5zZXRGaWVsZHMoZmllbGRzKTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBUZXN0SWFtUGVybWlzc2lvbnMgc2V0S2V5KGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgcmV0dXJuIChUZXN0SWFtUGVybWlzc2lvbnMpIHN1cGVyLnNldEtleShrZXkpOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIFRlc3RJYW1QZXJtaXNzaW9ucyBzZXRPYXV0aFRva2VuKGphdmEubGFuZy5TdHJpbmcgb2F1dGhUb2tlbikgewogICAgICAgIHJldHVybiAoVGVzdElhbVBlcm1pc3Npb25zKSBzdXBlci5zZXRPYXV0aFRva2VuKG9hdXRoVG9rZW4pOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIFRlc3RJYW1QZXJtaXNzaW9ucyBzZXRQcmV0dHlQcmludChqYXZhLmxhbmcuQm9vbGVhbiBwcmV0dHlQcmludCkgewogICAgICAgIHJldHVybiAoVGVzdElhbVBlcm1pc3Npb25zKSBzdXBlci5zZXRQcmV0dHlQcmludChwcmV0dHlQcmludCk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgVGVzdElhbVBlcm1pc3Npb25zIHNldFF1b3RhVXNlcihqYXZhLmxhbmcuU3RyaW5nIHF1b3RhVXNlcikgewogICAgICAgIHJldHVybiAoVGVzdElhbVBlcm1pc3Npb25zKSBzdXBlci5zZXRRdW90YVVzZXIocXVvdGFVc2VyKTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBUZXN0SWFtUGVybWlzc2lvbnMgc2V0VXBsb2FkVHlwZShqYXZhLmxhbmcuU3RyaW5nIHVwbG9hZFR5cGUpIHsKICAgICAgICByZXR1cm4gKFRlc3RJYW1QZXJtaXNzaW9ucykgc3VwZXIuc2V0VXBsb2FkVHlwZSh1cGxvYWRUeXBlKTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBUZXN0SWFtUGVybWlzc2lvbnMgc2V0VXBsb2FkUHJvdG9jb2woamF2YS5sYW5nLlN0cmluZyB1cGxvYWRQcm90b2NvbCkgewogICAgICAgIHJldHVybiAoVGVzdElhbVBlcm1pc3Npb25zKSBzdXBlci5zZXRVcGxvYWRQcm90b2NvbCh1cGxvYWRQcm90b2NvbCk7CiAgICAgIH0KCiAgICAgIC8qKgogICAgICAgKiBSRVFVSVJFRDogVGhlIHJlc291cmNlIGZvciB3aGljaCB0aGUgcG9saWN5IGRldGFpbCBpcyBiZWluZyByZXF1ZXN0ZWQuIFNlZSB0aGUgb3BlcmF0aW9uCiAgICAgICAqIGRvY3VtZW50YXRpb24gZm9yIHRoZSBhcHByb3ByaWF0ZSB2YWx1ZSBmb3IgdGhpcyBmaWVsZC4KICAgICAgICovCiAgICAgIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuU3RyaW5nIHJlc291cmNlOwoKICAgICAgLyoqIFJFUVVJUkVEOiBUaGUgcmVzb3VyY2UgZm9yIHdoaWNoIHRoZSBwb2xpY3kgZGV0YWlsIGlzIGJlaW5nIHJlcXVlc3RlZC4gU2VlIHRoZSBvcGVyYXRpb24KICAgICBkb2N1bWVudGF0aW9uIGZvciB0aGUgYXBwcm9wcmlhdGUgdmFsdWUgZm9yIHRoaXMgZmllbGQuCiAgICAgICAqLwogICAgICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRSZXNvdXJjZSgpIHsKICAgICAgICByZXR1cm4gcmVzb3VyY2U7CiAgICAgIH0KCiAgICAgIC8qKgogICAgICAgKiBSRVFVSVJFRDogVGhlIHJlc291cmNlIGZvciB3aGljaCB0aGUgcG9saWN5IGRldGFpbCBpcyBiZWluZyByZXF1ZXN0ZWQuIFNlZSB0aGUgb3BlcmF0aW9uCiAgICAgICAqIGRvY3VtZW50YXRpb24gZm9yIHRoZSBhcHByb3ByaWF0ZSB2YWx1ZSBmb3IgdGhpcyBmaWVsZC4KICAgICAgICovCiAgICAgIHB1YmxpYyBUZXN0SWFtUGVybWlzc2lvbnMgc2V0UmVzb3VyY2UoamF2YS5sYW5nLlN0cmluZyByZXNvdXJjZSkgewogICAgICAgIHRoaXMucmVzb3VyY2UgPSByZXNvdXJjZTsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBUZXN0SWFtUGVybWlzc2lvbnMgc2V0KFN0cmluZyBwYXJhbWV0ZXJOYW1lLCBPYmplY3QgdmFsdWUpIHsKICAgICAgICByZXR1cm4gKFRlc3RJYW1QZXJtaXNzaW9ucykgc3VwZXIuc2V0KHBhcmFtZXRlck5hbWUsIHZhbHVlKTsKICAgICAgfQogICAgfQogICAgLyoqCiAgICAgKiBSZXN0b3JlcyB0aGUgUHJvamVjdCBpZGVudGlmaWVkIGJ5IHRoZSBzcGVjaWZpZWQgYHByb2plY3RfaWRgIChmb3IgZXhhbXBsZSwgYG15LXByb2plY3QtMTIzYCkuCiAgICAgKiBZb3UgY2FuIG9ubHkgdXNlIHRoaXMgbWV0aG9kIGZvciBhIFByb2plY3QgdGhhdCBoYXMgYSBsaWZlY3ljbGUgc3RhdGUgb2YgREVMRVRFX1JFUVVFU1RFRC4gQWZ0ZXIKICAgICAqIGRlbGV0aW9uIHN0YXJ0cywgdGhlIFByb2plY3QgY2Fubm90IGJlIHJlc3RvcmVkLgogICAgICoKICAgICAqIFRoZSBjYWxsZXIgbXVzdCBoYXZlIG1vZGlmeSBwZXJtaXNzaW9ucyBmb3IgdGhpcyBQcm9qZWN0LgogICAgICoKICAgICAqIENyZWF0ZSBhIHJlcXVlc3QgZm9yIHRoZSBtZXRob2QgInByb2plY3RzLnVuZGVsZXRlIi4KICAgICAqCiAgICAgKiBUaGlzIHJlcXVlc3QgaG9sZHMgdGhlIHBhcmFtZXRlcnMgbmVlZGVkIGJ5IHRoZSBjbG91ZHJlc291cmNlbWFuYWdlciBzZXJ2ZXIuICBBZnRlciBzZXR0aW5nIGFueQogICAgICogb3B0aW9uYWwgcGFyYW1ldGVycywgY2FsbCB0aGUge0BsaW5rIFVuZGVsZXRlI2V4ZWN1dGUoKX0gbWV0aG9kIHRvIGludm9rZSB0aGUgcmVtb3RlIG9wZXJhdGlvbi4KICAgICAqCiAgICAgKiBAcGFyYW0gcHJvamVjdElkIFRoZSBwcm9qZWN0IElEIChmb3IgZXhhbXBsZSwgYGZvby1iYXItMTIzYCkuCiAgICBSZXF1aXJlZC4KICAgICAqIEBwYXJhbSBjb250ZW50IHRoZSB7QGxpbmsgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuY2xvdWRyZXNvdXJjZW1hbmFnZXIubW9kZWwuVW5kZWxldGVQcm9qZWN0UmVxdWVzdH0KICAgICAqIEByZXR1cm4gdGhlIHJlcXVlc3QKICAgICAqLwogICAgcHVibGljIFVuZGVsZXRlIHVuZGVsZXRlKGphdmEubGFuZy5TdHJpbmcgcHJvamVjdElkLCBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5jbG91ZHJlc291cmNlbWFuYWdlci5tb2RlbC5VbmRlbGV0ZVByb2plY3RSZXF1ZXN0IGNvbnRlbnQpIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgICAgVW5kZWxldGUgcmVzdWx0ID0gbmV3IFVuZGVsZXRlKHByb2plY3RJZCwgY29udGVudCk7CiAgICAgIGluaXRpYWxpemUocmVzdWx0KTsKICAgICAgcmV0dXJuIHJlc3VsdDsKICAgIH0KCiAgICBwdWJsaWMgY2xhc3MgVW5kZWxldGUgZXh0ZW5kcyBDbG91ZFJlc291cmNlTWFuYWdlclJlcXVlc3Q8Y29tLmdvb2dsZS5hcGkuc2VydmljZXMuY2xvdWRyZXNvdXJjZW1hbmFnZXIubW9kZWwuRW1wdHk+IHsKCiAgICAgIHByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBSRVNUX1BBVEggPSAidjEvcHJvamVjdHMve3Byb2plY3RJZH06dW5kZWxldGUiOwoKICAgICAgLyoqCiAgICAgICAqIFJlc3RvcmVzIHRoZSBQcm9qZWN0IGlkZW50aWZpZWQgYnkgdGhlIHNwZWNpZmllZCBgcHJvamVjdF9pZGAgKGZvciBleGFtcGxlLCBgbXktcHJvamVjdC0xMjNgKS4KICAgICAgICogWW91IGNhbiBvbmx5IHVzZSB0aGlzIG1ldGhvZCBmb3IgYSBQcm9qZWN0IHRoYXQgaGFzIGEgbGlmZWN5Y2xlIHN0YXRlIG9mIERFTEVURV9SRVFVRVNURUQuCiAgICAgICAqIEFmdGVyIGRlbGV0aW9uIHN0YXJ0cywgdGhlIFByb2plY3QgY2Fubm90IGJlIHJlc3RvcmVkLgogICAgICAgKgogICAgICAgKiBUaGUgY2FsbGVyIG11c3QgaGF2ZSBtb2RpZnkgcGVybWlzc2lvbnMgZm9yIHRoaXMgUHJvamVjdC4KICAgICAgICoKICAgICAgICogQ3JlYXRlIGEgcmVxdWVzdCBmb3IgdGhlIG1ldGhvZCAicHJvamVjdHMudW5kZWxldGUiLgogICAgICAgKgogICAgICAgKiBUaGlzIHJlcXVlc3QgaG9sZHMgdGhlIHBhcmFtZXRlcnMgbmVlZGVkIGJ5IHRoZSB0aGUgY2xvdWRyZXNvdXJjZW1hbmFnZXIgc2VydmVyLiAgQWZ0ZXIgc2V0dGluZwogICAgICAgKiBhbnkgb3B0aW9uYWwgcGFyYW1ldGVycywgY2FsbCB0aGUge0BsaW5rIFVuZGVsZXRlI2V4ZWN1dGUoKX0gbWV0aG9kIHRvIGludm9rZSB0aGUgcmVtb3RlCiAgICAgICAqIG9wZXJhdGlvbi4gPHA+IHtAbGluawogICAgICAgKiBVbmRlbGV0ZSNpbml0aWFsaXplKGNvbS5nb29nbGUuYXBpLmNsaWVudC5nb29nbGVhcGlzLnNlcnZpY2VzLkFic3RyYWN0R29vZ2xlQ2xpZW50UmVxdWVzdCl9CiAgICAgICAqIG11c3QgYmUgY2FsbGVkIHRvIGluaXRpYWxpemUgdGhpcyBpbnN0YW5jZSBpbW1lZGlhdGVseSBhZnRlciBpbnZva2luZyB0aGUgY29uc3RydWN0b3IuIDwvcD4KICAgICAgICoKICAgICAgICogQHBhcmFtIHByb2plY3RJZCBUaGUgcHJvamVjdCBJRCAoZm9yIGV4YW1wbGUsIGBmb28tYmFyLTEyM2ApLgogICAgUmVxdWlyZWQuCiAgICAgICAqIEBwYXJhbSBjb250ZW50IHRoZSB7QGxpbmsgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuY2xvdWRyZXNvdXJjZW1hbmFnZXIubW9kZWwuVW5kZWxldGVQcm9qZWN0UmVxdWVzdH0KICAgICAgICogQHNpbmNlIDEuMTMKICAgICAgICovCiAgICAgIHByb3RlY3RlZCBVbmRlbGV0ZShqYXZhLmxhbmcuU3RyaW5nIHByb2plY3RJZCwgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuY2xvdWRyZXNvdXJjZW1hbmFnZXIubW9kZWwuVW5kZWxldGVQcm9qZWN0UmVxdWVzdCBjb250ZW50KSB7CiAgICAgICAgc3VwZXIoQ2xvdWRSZXNvdXJjZU1hbmFnZXIudGhpcywgIlBPU1QiLCBSRVNUX1BBVEgsIGNvbnRlbnQsIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmNsb3VkcmVzb3VyY2VtYW5hZ2VyLm1vZGVsLkVtcHR5LmNsYXNzKTsKICAgICAgICB0aGlzLnByb2plY3RJZCA9IGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLlByZWNvbmRpdGlvbnMuY2hlY2tOb3ROdWxsKHByb2plY3RJZCwgIlJlcXVpcmVkIHBhcmFtZXRlciBwcm9qZWN0SWQgbXVzdCBiZSBzcGVjaWZpZWQuIik7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgVW5kZWxldGUgc2V0JFhnYWZ2KGphdmEubGFuZy5TdHJpbmcgJFhnYWZ2KSB7CiAgICAgICAgcmV0dXJuIChVbmRlbGV0ZSkgc3VwZXIuc2V0JFhnYWZ2KCRYZ2Fmdik7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgVW5kZWxldGUgc2V0QWNjZXNzVG9rZW4oamF2YS5sYW5nLlN0cmluZyBhY2Nlc3NUb2tlbikgewogICAgICAgIHJldHVybiAoVW5kZWxldGUpIHN1cGVyLnNldEFjY2Vzc1Rva2VuKGFjY2Vzc1Rva2VuKTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBVbmRlbGV0ZSBzZXRBbHQoamF2YS5sYW5nLlN0cmluZyBhbHQpIHsKICAgICAgICByZXR1cm4gKFVuZGVsZXRlKSBzdXBlci5zZXRBbHQoYWx0KTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBVbmRlbGV0ZSBzZXRDYWxsYmFjayhqYXZhLmxhbmcuU3RyaW5nIGNhbGxiYWNrKSB7CiAgICAgICAgcmV0dXJuIChVbmRlbGV0ZSkgc3VwZXIuc2V0Q2FsbGJhY2soY2FsbGJhY2spOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIFVuZGVsZXRlIHNldEZpZWxkcyhqYXZhLmxhbmcuU3RyaW5nIGZpZWxkcykgewogICAgICAgIHJldHVybiAoVW5kZWxldGUpIHN1cGVyLnNldEZpZWxkcyhmaWVsZHMpOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIFVuZGVsZXRlIHNldEtleShqYXZhLmxhbmcuU3RyaW5nIGtleSkgewogICAgICAgIHJldHVybiAoVW5kZWxldGUpIHN1cGVyLnNldEtleShrZXkpOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIFVuZGVsZXRlIHNldE9hdXRoVG9rZW4oamF2YS5sYW5nLlN0cmluZyBvYXV0aFRva2VuKSB7CiAgICAgICAgcmV0dXJuIChVbmRlbGV0ZSkgc3VwZXIuc2V0T2F1dGhUb2tlbihvYXV0aFRva2VuKTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBVbmRlbGV0ZSBzZXRQcmV0dHlQcmludChqYXZhLmxhbmcuQm9vbGVhbiBwcmV0dHlQcmludCkgewogICAgICAgIHJldHVybiAoVW5kZWxldGUpIHN1cGVyLnNldFByZXR0eVByaW50KHByZXR0eVByaW50KTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBVbmRlbGV0ZSBzZXRRdW90YVVzZXIoamF2YS5sYW5nLlN0cmluZyBxdW90YVVzZXIpIHsKICAgICAgICByZXR1cm4gKFVuZGVsZXRlKSBzdXBlci5zZXRRdW90YVVzZXIocXVvdGFVc2VyKTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBVbmRlbGV0ZSBzZXRVcGxvYWRUeXBlKGphdmEubGFuZy5TdHJpbmcgdXBsb2FkVHlwZSkgewogICAgICAgIHJldHVybiAoVW5kZWxldGUpIHN1cGVyLnNldFVwbG9hZFR5cGUodXBsb2FkVHlwZSk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgVW5kZWxldGUgc2V0VXBsb2FkUHJvdG9jb2woamF2YS5sYW5nLlN0cmluZyB1cGxvYWRQcm90b2NvbCkgewogICAgICAgIHJldHVybiAoVW5kZWxldGUpIHN1cGVyLnNldFVwbG9hZFByb3RvY29sKHVwbG9hZFByb3RvY29sKTsKICAgICAgfQoKICAgICAgLyoqCiAgICAgICAqIFRoZSBwcm9qZWN0IElEIChmb3IgZXhhbXBsZSwgYGZvby1iYXItMTIzYCkuCiAgICAgICAqCiAgICAgICAqIFJlcXVpcmVkLgogICAgICAgKi8KICAgICAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogICAgICBwcml2YXRlIGphdmEubGFuZy5TdHJpbmcgcHJvamVjdElkOwoKICAgICAgLyoqIFRoZSBwcm9qZWN0IElEIChmb3IgZXhhbXBsZSwgYGZvby1iYXItMTIzYCkuCgogICAgIFJlcXVpcmVkLgogICAgICAgKi8KICAgICAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0UHJvamVjdElkKCkgewogICAgICAgIHJldHVybiBwcm9qZWN0SWQ7CiAgICAgIH0KCiAgICAgIC8qKgogICAgICAgKiBUaGUgcHJvamVjdCBJRCAoZm9yIGV4YW1wbGUsIGBmb28tYmFyLTEyM2ApLgogICAgICAgKgogICAgICAgKiBSZXF1aXJlZC4KICAgICAgICovCiAgICAgIHB1YmxpYyBVbmRlbGV0ZSBzZXRQcm9qZWN0SWQoamF2YS5sYW5nLlN0cmluZyBwcm9qZWN0SWQpIHsKICAgICAgICB0aGlzLnByb2plY3RJZCA9IHByb2plY3RJZDsKICAgICAgICByZXR1cm4gdGhpczsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBVbmRlbGV0ZSBzZXQoU3RyaW5nIHBhcmFtZXRlck5hbWUsIE9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiAoVW5kZWxldGUpIHN1cGVyLnNldChwYXJhbWV0ZXJOYW1lLCB2YWx1ZSk7CiAgICAgIH0KICAgIH0KICAgIC8qKgogICAgICogVXBkYXRlcyB0aGUgYXR0cmlidXRlcyBvZiB0aGUgUHJvamVjdCBpZGVudGlmaWVkIGJ5IHRoZSBzcGVjaWZpZWQgYHByb2plY3RfaWRgIChmb3IgZXhhbXBsZSwgYG15LQogICAgICogcHJvamVjdC0xMjNgKS4KICAgICAqCiAgICAgKiBUaGUgY2FsbGVyIG11c3QgaGF2ZSBtb2RpZnkgcGVybWlzc2lvbnMgZm9yIHRoaXMgUHJvamVjdC4KICAgICAqCiAgICAgKiBDcmVhdGUgYSByZXF1ZXN0IGZvciB0aGUgbWV0aG9kICJwcm9qZWN0cy51cGRhdGUiLgogICAgICoKICAgICAqIFRoaXMgcmVxdWVzdCBob2xkcyB0aGUgcGFyYW1ldGVycyBuZWVkZWQgYnkgdGhlIGNsb3VkcmVzb3VyY2VtYW5hZ2VyIHNlcnZlci4gIEFmdGVyIHNldHRpbmcgYW55CiAgICAgKiBvcHRpb25hbCBwYXJhbWV0ZXJzLCBjYWxsIHRoZSB7QGxpbmsgVXBkYXRlI2V4ZWN1dGUoKX0gbWV0aG9kIHRvIGludm9rZSB0aGUgcmVtb3RlIG9wZXJhdGlvbi4KICAgICAqCiAgICAgKiBAcGFyYW0gcHJvamVjdElkIFRoZSBwcm9qZWN0IElEIChmb3IgZXhhbXBsZSwgYG15LXByb2plY3QtMTIzYCkuCiAgICBSZXF1aXJlZC4KICAgICAqIEBwYXJhbSBjb250ZW50IHRoZSB7QGxpbmsgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuY2xvdWRyZXNvdXJjZW1hbmFnZXIubW9kZWwuUHJvamVjdH0KICAgICAqIEByZXR1cm4gdGhlIHJlcXVlc3QKICAgICAqLwogICAgcHVibGljIFVwZGF0ZSB1cGRhdGUoamF2YS5sYW5nLlN0cmluZyBwcm9qZWN0SWQsIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmNsb3VkcmVzb3VyY2VtYW5hZ2VyLm1vZGVsLlByb2plY3QgY29udGVudCkgdGhyb3dzIGphdmEuaW8uSU9FeGNlcHRpb24gewogICAgICBVcGRhdGUgcmVzdWx0ID0gbmV3IFVwZGF0ZShwcm9qZWN0SWQsIGNvbnRlbnQpOwogICAgICBpbml0aWFsaXplKHJlc3VsdCk7CiAgICAgIHJldHVybiByZXN1bHQ7CiAgICB9CgogICAgcHVibGljIGNsYXNzIFVwZGF0ZSBleHRlbmRzIENsb3VkUmVzb3VyY2VNYW5hZ2VyUmVxdWVzdDxjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5jbG91ZHJlc291cmNlbWFuYWdlci5tb2RlbC5Qcm9qZWN0PiB7CgogICAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgUkVTVF9QQVRIID0gInYxL3Byb2plY3RzL3twcm9qZWN0SWR9IjsKCiAgICAgIC8qKgogICAgICAgKiBVcGRhdGVzIHRoZSBhdHRyaWJ1dGVzIG9mIHRoZSBQcm9qZWN0IGlkZW50aWZpZWQgYnkgdGhlIHNwZWNpZmllZCBgcHJvamVjdF9pZGAgKGZvciBleGFtcGxlLAogICAgICAgKiBgbXktcHJvamVjdC0xMjNgKS4KICAgICAgICoKICAgICAgICogVGhlIGNhbGxlciBtdXN0IGhhdmUgbW9kaWZ5IHBlcm1pc3Npb25zIGZvciB0aGlzIFByb2plY3QuCiAgICAgICAqCiAgICAgICAqIENyZWF0ZSBhIHJlcXVlc3QgZm9yIHRoZSBtZXRob2QgInByb2plY3RzLnVwZGF0ZSIuCiAgICAgICAqCiAgICAgICAqIFRoaXMgcmVxdWVzdCBob2xkcyB0aGUgcGFyYW1ldGVycyBuZWVkZWQgYnkgdGhlIHRoZSBjbG91ZHJlc291cmNlbWFuYWdlciBzZXJ2ZXIuICBBZnRlciBzZXR0aW5nCiAgICAgICAqIGFueSBvcHRpb25hbCBwYXJhbWV0ZXJzLCBjYWxsIHRoZSB7QGxpbmsgVXBkYXRlI2V4ZWN1dGUoKX0gbWV0aG9kIHRvIGludm9rZSB0aGUgcmVtb3RlCiAgICAgICAqIG9wZXJhdGlvbi4gPHA+IHtAbGluawogICAgICAgKiBVcGRhdGUjaW5pdGlhbGl6ZShjb20uZ29vZ2xlLmFwaS5jbGllbnQuZ29vZ2xlYXBpcy5zZXJ2aWNlcy5BYnN0cmFjdEdvb2dsZUNsaWVudFJlcXVlc3QpfSBtdXN0CiAgICAgICAqIGJlIGNhbGxlZCB0byBpbml0aWFsaXplIHRoaXMgaW5zdGFuY2UgaW1tZWRpYXRlbHkgYWZ0ZXIgaW52b2tpbmcgdGhlIGNvbnN0cnVjdG9yLiA8L3A+CiAgICAgICAqCiAgICAgICAqIEBwYXJhbSBwcm9qZWN0SWQgVGhlIHByb2plY3QgSUQgKGZvciBleGFtcGxlLCBgbXktcHJvamVjdC0xMjNgKS4KICAgIFJlcXVpcmVkLgogICAgICAgKiBAcGFyYW0gY29udGVudCB0aGUge0BsaW5rIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmNsb3VkcmVzb3VyY2VtYW5hZ2VyLm1vZGVsLlByb2plY3R9CiAgICAgICAqIEBzaW5jZSAxLjEzCiAgICAgICAqLwogICAgICBwcm90ZWN0ZWQgVXBkYXRlKGphdmEubGFuZy5TdHJpbmcgcHJvamVjdElkLCBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5jbG91ZHJlc291cmNlbWFuYWdlci5tb2RlbC5Qcm9qZWN0IGNvbnRlbnQpIHsKICAgICAgICBzdXBlcihDbG91ZFJlc291cmNlTWFuYWdlci50aGlzLCAiUFVUIiwgUkVTVF9QQVRILCBjb250ZW50LCBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5jbG91ZHJlc291cmNlbWFuYWdlci5tb2RlbC5Qcm9qZWN0LmNsYXNzKTsKICAgICAgICB0aGlzLnByb2plY3RJZCA9IGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLlByZWNvbmRpdGlvbnMuY2hlY2tOb3ROdWxsKHByb2plY3RJZCwgIlJlcXVpcmVkIHBhcmFtZXRlciBwcm9qZWN0SWQgbXVzdCBiZSBzcGVjaWZpZWQuIik7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgVXBkYXRlIHNldCRYZ2FmdihqYXZhLmxhbmcuU3RyaW5nICRYZ2FmdikgewogICAgICAgIHJldHVybiAoVXBkYXRlKSBzdXBlci5zZXQkWGdhZnYoJFhnYWZ2KTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBVcGRhdGUgc2V0QWNjZXNzVG9rZW4oamF2YS5sYW5nLlN0cmluZyBhY2Nlc3NUb2tlbikgewogICAgICAgIHJldHVybiAoVXBkYXRlKSBzdXBlci5zZXRBY2Nlc3NUb2tlbihhY2Nlc3NUb2tlbik7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgVXBkYXRlIHNldEFsdChqYXZhLmxhbmcuU3RyaW5nIGFsdCkgewogICAgICAgIHJldHVybiAoVXBkYXRlKSBzdXBlci5zZXRBbHQoYWx0KTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBVcGRhdGUgc2V0Q2FsbGJhY2soamF2YS5sYW5nLlN0cmluZyBjYWxsYmFjaykgewogICAgICAgIHJldHVybiAoVXBkYXRlKSBzdXBlci5zZXRDYWxsYmFjayhjYWxsYmFjayk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgVXBkYXRlIHNldEZpZWxkcyhqYXZhLmxhbmcuU3RyaW5nIGZpZWxkcykgewogICAgICAgIHJldHVybiAoVXBkYXRlKSBzdXBlci5zZXRGaWVsZHMoZmllbGRzKTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBVcGRhdGUgc2V0S2V5KGphdmEubGFuZy5TdHJpbmcga2V5KSB7CiAgICAgICAgcmV0dXJuIChVcGRhdGUpIHN1cGVyLnNldEtleShrZXkpOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIFVwZGF0ZSBzZXRPYXV0aFRva2VuKGphdmEubGFuZy5TdHJpbmcgb2F1dGhUb2tlbikgewogICAgICAgIHJldHVybiAoVXBkYXRlKSBzdXBlci5zZXRPYXV0aFRva2VuKG9hdXRoVG9rZW4pOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIFVwZGF0ZSBzZXRQcmV0dHlQcmludChqYXZhLmxhbmcuQm9vbGVhbiBwcmV0dHlQcmludCkgewogICAgICAgIHJldHVybiAoVXBkYXRlKSBzdXBlci5zZXRQcmV0dHlQcmludChwcmV0dHlQcmludCk7CiAgICAgIH0KCiAgICAgIEBPdmVycmlkZQogICAgICBwdWJsaWMgVXBkYXRlIHNldFF1b3RhVXNlcihqYXZhLmxhbmcuU3RyaW5nIHF1b3RhVXNlcikgewogICAgICAgIHJldHVybiAoVXBkYXRlKSBzdXBlci5zZXRRdW90YVVzZXIocXVvdGFVc2VyKTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBVcGRhdGUgc2V0VXBsb2FkVHlwZShqYXZhLmxhbmcuU3RyaW5nIHVwbG9hZFR5cGUpIHsKICAgICAgICByZXR1cm4gKFVwZGF0ZSkgc3VwZXIuc2V0VXBsb2FkVHlwZSh1cGxvYWRUeXBlKTsKICAgICAgfQoKICAgICAgQE92ZXJyaWRlCiAgICAgIHB1YmxpYyBVcGRhdGUgc2V0VXBsb2FkUHJvdG9jb2woamF2YS5sYW5nLlN0cmluZyB1cGxvYWRQcm90b2NvbCkgewogICAgICAgIHJldHVybiAoVXBkYXRlKSBzdXBlci5zZXRVcGxvYWRQcm90b2NvbCh1cGxvYWRQcm90b2NvbCk7CiAgICAgIH0KCiAgICAgIC8qKgogICAgICAgKiBUaGUgcHJvamVjdCBJRCAoZm9yIGV4YW1wbGUsIGBteS1wcm9qZWN0LTEyM2ApLgogICAgICAgKgogICAgICAgKiBSZXF1aXJlZC4KICAgICAgICovCiAgICAgIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICAgICAgcHJpdmF0ZSBqYXZhLmxhbmcuU3RyaW5nIHByb2plY3RJZDsKCiAgICAgIC8qKiBUaGUgcHJvamVjdCBJRCAoZm9yIGV4YW1wbGUsIGBteS1wcm9qZWN0LTEyM2ApLgoKICAgICBSZXF1aXJlZC4KICAgICAgICovCiAgICAgIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFByb2plY3RJZCgpIHsKICAgICAgICByZXR1cm4gcHJvamVjdElkOwogICAgICB9CgogICAgICAvKioKICAgICAgICogVGhlIHByb2plY3QgSUQgKGZvciBleGFtcGxlLCBgbXktcHJvamVjdC0xMjNgKS4KICAgICAgICoKICAgICAgICogUmVxdWlyZWQuCiAgICAgICAqLwogICAgICBwdWJsaWMgVXBkYXRlIHNldFByb2plY3RJZChqYXZhLmxhbmcuU3RyaW5nIHByb2plY3RJZCkgewogICAgICAgIHRoaXMucHJvamVjdElkID0gcHJvamVjdElkOwogICAgICAgIHJldHVybiB0aGlzOwogICAgICB9CgogICAgICBAT3ZlcnJpZGUKICAgICAgcHVibGljIFVwZGF0ZSBzZXQoU3RyaW5nIHBhcmFtZXRlck5hbWUsIE9iamVjdCB2YWx1ZSkgewogICAgICAgIHJldHVybiAoVXBkYXRlKSBzdXBlci5zZXQocGFyYW1ldGVyTmFtZSwgdmFsdWUpOwogICAgICB9CiAgICB9CgogIH0KCiAgLyoqCiAgICogQnVpbGRlciBmb3Ige0BsaW5rIENsb3VkUmVzb3VyY2VNYW5hZ2VyfS4KICAgKgogICAqIDxwPgogICAqIEltcGxlbWVudGF0aW9uIGlzIG5vdCB0aHJlYWQtc2FmZS4KICAgKiA8L3A+CiAgICoKICAgKiBAc2luY2UgMS4zLjAKICAgKi8KICBwdWJsaWMgc3RhdGljIGZpbmFsIGNsYXNzIEJ1aWxkZXIgZXh0ZW5kcyBjb20uZ29vZ2xlLmFwaS5jbGllbnQuZ29vZ2xlYXBpcy5zZXJ2aWNlcy5qc29uLkFic3RyYWN0R29vZ2xlSnNvbkNsaWVudC5CdWlsZGVyIHsKCiAgICAvKioKICAgICAqIFJldHVybnMgYW4gaW5zdGFuY2Ugb2YgYSBuZXcgYnVpbGRlci4KICAgICAqCiAgICAgKiBAcGFyYW0gdHJhbnNwb3J0IEhUVFAgdHJhbnNwb3J0LCB3aGljaCBzaG91bGQgbm9ybWFsbHkgYmU6CiAgICAgKiAgICAgICAgPHVsPgogICAgICogICAgICAgIDxsaT5Hb29nbGUgQXBwIEVuZ2luZToKICAgICAqICAgICAgICB7QGNvZGUgY29tLmdvb2dsZS5hcGkuY2xpZW50LmV4dGVuc2lvbnMuYXBwZW5naW5lLmh0dHAuVXJsRmV0Y2hUcmFuc3BvcnR9PC9saT4KICAgICAqICAgICAgICA8bGk+QW5kcm9pZDoge0Bjb2RlIG5ld0NvbXBhdGlibGVUcmFuc3BvcnR9IGZyb20KICAgICAqICAgICAgICB7QGNvZGUgY29tLmdvb2dsZS5hcGkuY2xpZW50LmV4dGVuc2lvbnMuYW5kcm9pZC5odHRwLkFuZHJvaWRIdHRwfTwvbGk+CiAgICAgKiAgICAgICAgPGxpPkphdmE6IHtAbGluayBjb20uZ29vZ2xlLmFwaS5jbGllbnQuZ29vZ2xlYXBpcy5qYXZhbmV0Lkdvb2dsZU5ldEh0dHBUcmFuc3BvcnQjbmV3VHJ1c3RlZFRyYW5zcG9ydCgpfQogICAgICogICAgICAgIDwvbGk+CiAgICAgKiAgICAgICAgPC91bD4KICAgICAqIEBwYXJhbSBqc29uRmFjdG9yeSBKU09OIGZhY3RvcnksIHdoaWNoIG1heSBiZToKICAgICAqICAgICAgICA8dWw+CiAgICAgKiAgICAgICAgPGxpPkphY2tzb246IHtAY29kZSBjb20uZ29vZ2xlLmFwaS5jbGllbnQuanNvbi5qYWNrc29uMi5KYWNrc29uRmFjdG9yeX08L2xpPgogICAgICogICAgICAgIDxsaT5Hb29nbGUgR1NPTjoge0Bjb2RlIGNvbS5nb29nbGUuYXBpLmNsaWVudC5qc29uLmdzb24uR3NvbkZhY3Rvcnl9PC9saT4KICAgICAqICAgICAgICA8bGk+QW5kcm9pZCBIb25leWNvbWIgb3IgaGlnaGVyOgogICAgICogICAgICAgIHtAY29kZSBjb20uZ29vZ2xlLmFwaS5jbGllbnQuZXh0ZW5zaW9ucy5hbmRyb2lkLmpzb24uQW5kcm9pZEpzb25GYWN0b3J5fTwvbGk+CiAgICAgKiAgICAgICAgPC91bD4KICAgICAqIEBwYXJhbSBodHRwUmVxdWVzdEluaXRpYWxpemVyIEhUVFAgcmVxdWVzdCBpbml0aWFsaXplciBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgICAqIEBzaW5jZSAxLjcKICAgICAqLwogICAgcHVibGljIEJ1aWxkZXIoY29tLmdvb2dsZS5hcGkuY2xpZW50Lmh0dHAuSHR0cFRyYW5zcG9ydCB0cmFuc3BvcnQsIGNvbS5nb29nbGUuYXBpLmNsaWVudC5qc29uLkpzb25GYWN0b3J5IGpzb25GYWN0b3J5LAogICAgICAgIGNvbS5nb29nbGUuYXBpLmNsaWVudC5odHRwLkh0dHBSZXF1ZXN0SW5pdGlhbGl6ZXIgaHR0cFJlcXVlc3RJbml0aWFsaXplcikgewogICAgICBzdXBlcigKICAgICAgICAgIHRyYW5zcG9ydCwKICAgICAgICAgIGpzb25GYWN0b3J5LAogICAgICAgICAgREVGQVVMVF9ST09UX1VSTCwKICAgICAgICAgIERFRkFVTFRfU0VSVklDRV9QQVRILAogICAgICAgICAgaHR0cFJlcXVlc3RJbml0aWFsaXplciwKICAgICAgICAgIGZhbHNlKTsKICAgICAgc2V0QmF0Y2hQYXRoKERFRkFVTFRfQkFUQ0hfUEFUSCk7CiAgICB9CgogICAgLyoqIEJ1aWxkcyBhIG5ldyBpbnN0YW5jZSBvZiB7QGxpbmsgQ2xvdWRSZXNvdXJjZU1hbmFnZXJ9LiAqLwogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgQ2xvdWRSZXNvdXJjZU1hbmFnZXIgYnVpbGQoKSB7CiAgICAgIHJldHVybiBuZXcgQ2xvdWRSZXNvdXJjZU1hbmFnZXIodGhpcyk7CiAgICB9CgogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBzZXRSb290VXJsKFN0cmluZyByb290VXJsKSB7CiAgICAgIHJldHVybiAoQnVpbGRlcikgc3VwZXIuc2V0Um9vdFVybChyb290VXJsKTsKICAgIH0KCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHNldFNlcnZpY2VQYXRoKFN0cmluZyBzZXJ2aWNlUGF0aCkgewogICAgICByZXR1cm4gKEJ1aWxkZXIpIHN1cGVyLnNldFNlcnZpY2VQYXRoKHNlcnZpY2VQYXRoKTsKICAgIH0KCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHNldEJhdGNoUGF0aChTdHJpbmcgYmF0Y2hQYXRoKSB7CiAgICAgIHJldHVybiAoQnVpbGRlcikgc3VwZXIuc2V0QmF0Y2hQYXRoKGJhdGNoUGF0aCk7CiAgICB9CgogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBzZXRIdHRwUmVxdWVzdEluaXRpYWxpemVyKGNvbS5nb29nbGUuYXBpLmNsaWVudC5odHRwLkh0dHBSZXF1ZXN0SW5pdGlhbGl6ZXIgaHR0cFJlcXVlc3RJbml0aWFsaXplcikgewogICAgICByZXR1cm4gKEJ1aWxkZXIpIHN1cGVyLnNldEh0dHBSZXF1ZXN0SW5pdGlhbGl6ZXIoaHR0cFJlcXVlc3RJbml0aWFsaXplcik7CiAgICB9CgogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBzZXRBcHBsaWNhdGlvbk5hbWUoU3RyaW5nIGFwcGxpY2F0aW9uTmFtZSkgewogICAgICByZXR1cm4gKEJ1aWxkZXIpIHN1cGVyLnNldEFwcGxpY2F0aW9uTmFtZShhcHBsaWNhdGlvbk5hbWUpOwogICAgfQoKICAgIEBPdmVycmlkZQogICAgcHVibGljIEJ1aWxkZXIgc2V0U3VwcHJlc3NQYXR0ZXJuQ2hlY2tzKGJvb2xlYW4gc3VwcHJlc3NQYXR0ZXJuQ2hlY2tzKSB7CiAgICAgIHJldHVybiAoQnVpbGRlcikgc3VwZXIuc2V0U3VwcHJlc3NQYXR0ZXJuQ2hlY2tzKHN1cHByZXNzUGF0dGVybkNoZWNrcyk7CiAgICB9CgogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBzZXRTdXBwcmVzc1JlcXVpcmVkUGFyYW1ldGVyQ2hlY2tzKGJvb2xlYW4gc3VwcHJlc3NSZXF1aXJlZFBhcmFtZXRlckNoZWNrcykgewogICAgICByZXR1cm4gKEJ1aWxkZXIpIHN1cGVyLnNldFN1cHByZXNzUmVxdWlyZWRQYXJhbWV0ZXJDaGVja3Moc3VwcHJlc3NSZXF1aXJlZFBhcmFtZXRlckNoZWNrcyk7CiAgICB9CgogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgQnVpbGRlciBzZXRTdXBwcmVzc0FsbENoZWNrcyhib29sZWFuIHN1cHByZXNzQWxsQ2hlY2tzKSB7CiAgICAgIHJldHVybiAoQnVpbGRlcikgc3VwZXIuc2V0U3VwcHJlc3NBbGxDaGVja3Moc3VwcHJlc3NBbGxDaGVja3MpOwogICAgfQoKICAgIC8qKgogICAgICogU2V0IHRoZSB7QGxpbmsgQ2xvdWRSZXNvdXJjZU1hbmFnZXJSZXF1ZXN0SW5pdGlhbGl6ZXJ9LgogICAgICoKICAgICAqIEBzaW5jZSAxLjEyCiAgICAgKi8KICAgIHB1YmxpYyBCdWlsZGVyIHNldENsb3VkUmVzb3VyY2VNYW5hZ2VyUmVxdWVzdEluaXRpYWxpemVyKAogICAgICAgIENsb3VkUmVzb3VyY2VNYW5hZ2VyUmVxdWVzdEluaXRpYWxpemVyIGNsb3VkcmVzb3VyY2VtYW5hZ2VyUmVxdWVzdEluaXRpYWxpemVyKSB7CiAgICAgIHJldHVybiAoQnVpbGRlcikgc3VwZXIuc2V0R29vZ2xlQ2xpZW50UmVxdWVzdEluaXRpYWxpemVyKGNsb3VkcmVzb3VyY2VtYW5hZ2VyUmVxdWVzdEluaXRpYWxpemVyKTsKICAgIH0KCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBCdWlsZGVyIHNldEdvb2dsZUNsaWVudFJlcXVlc3RJbml0aWFsaXplcigKICAgICAgICBjb20uZ29vZ2xlLmFwaS5jbGllbnQuZ29vZ2xlYXBpcy5zZXJ2aWNlcy5Hb29nbGVDbGllbnRSZXF1ZXN0SW5pdGlhbGl6ZXIgZ29vZ2xlQ2xpZW50UmVxdWVzdEluaXRpYWxpemVyKSB7CiAgICAgIHJldHVybiAoQnVpbGRlcikgc3VwZXIuc2V0R29vZ2xlQ2xpZW50UmVxdWVzdEluaXRpYWxpemVyKGdvb2dsZUNsaWVudFJlcXVlc3RJbml0aWFsaXplcik7CiAgICB9CiAgfQp9ClBLAwQUAAAAAAAAACEAAAAAAAAAAAAAAAAAMwAAAGNvbS9nb29nbGUvYXBpL3NlcnZpY2VzL2Nsb3VkcmVzb3VyY2VtYW5hZ2VyL21vZGVsL1BLAwQUAAAAAAAAACEAHlelN30IAAB9CAAAQAAAAGNvbS9nb29nbGUvYXBpL3NlcnZpY2VzL2Nsb3VkcmVzb3VyY2VtYW5hZ2VyL21vZGVsL0FuY2VzdG9yLmphdmEvKgogKiBDb3B5cmlnaHQgMjAxMCBHb29nbGUgSW5jLgogKgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQKICogaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UKICogaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzCiAqIG9yIGltcGxpZWQuIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMgdW5kZXIKICogdGhlIExpY2Vuc2UuCiAqLwovKgogKiBUaGlzIGNvZGUgd2FzIGdlbmVyYXRlZCBieSBodHRwczovL2dpdGh1Yi5jb20vZ29vZ2xlL2FwaXMtY2xpZW50LWdlbmVyYXRvci8KICogKGJ1aWxkOiAyMDE4LTEwLTA4IDE3OjQ1OjM5IFVUQykKICogb24gMjAyMC0wMy0xOSBhdCAwMjozODozMCBVVEMgCiAqIE1vZGlmeSBhdCB5b3VyIG93biByaXNrLgogKi8KCnBhY2thZ2UgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuY2xvdWRyZXNvdXJjZW1hbmFnZXIubW9kZWw7CgovKioKICogSWRlbnRpZnlpbmcgaW5mb3JtYXRpb24gZm9yIGEgc2luZ2xlIGFuY2VzdG9yIG9mIGEgcHJvamVjdC4KICoKICogPHA+IFRoaXMgaXMgdGhlIEphdmEgZGF0YSBtb2RlbCBjbGFzcyB0aGF0IHNwZWNpZmllcyBob3cgdG8gcGFyc2Uvc2VyaWFsaXplIGludG8gdGhlIEpTT04gdGhhdCBpcwogKiB0cmFuc21pdHRlZCBvdmVyIEhUVFAgd2hlbiB3b3JraW5nIHdpdGggdGhlIENsb3VkIFJlc291cmNlIE1hbmFnZXIgQVBJLiBGb3IgYSBkZXRhaWxlZAogKiBleHBsYW5hdGlvbiBzZWU6CiAqIDxhIGhyZWY9Imh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL2FwaS1jbGllbnQtbGlicmFyeS9qYXZhL2dvb2dsZS1odHRwLWphdmEtY2xpZW50L2pzb24iPmh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL2FwaS1jbGllbnQtbGlicmFyeS9qYXZhL2dvb2dsZS1odHRwLWphdmEtY2xpZW50L2pzb248L2E+CiAqIDwvcD4KICoKICogQGF1dGhvciBHb29nbGUsIEluYy4KICovCkBTdXBwcmVzc1dhcm5pbmdzKCJqYXZhZG9jIikKcHVibGljIGZpbmFsIGNsYXNzIEFuY2VzdG9yIGV4dGVuZHMgY29tLmdvb2dsZS5hcGkuY2xpZW50Lmpzb24uR2VuZXJpY0pzb24gewoKICAvKioKICAgKiBSZXNvdXJjZSBpZCBvZiB0aGUgYW5jZXN0b3IuCiAgICogVGhlIHZhbHVlIG1heSBiZSB7QGNvZGUgbnVsbH0uCiAgICovCiAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogIHByaXZhdGUgUmVzb3VyY2VJZCByZXNvdXJjZUlkOwoKICAvKioKICAgKiBSZXNvdXJjZSBpZCBvZiB0aGUgYW5jZXN0b3IuCiAgICogQHJldHVybiB2YWx1ZSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgUmVzb3VyY2VJZCBnZXRSZXNvdXJjZUlkKCkgewogICAgcmV0dXJuIHJlc291cmNlSWQ7CiAgfQoKICAvKioKICAgKiBSZXNvdXJjZSBpZCBvZiB0aGUgYW5jZXN0b3IuCiAgICogQHBhcmFtIHJlc291cmNlSWQgcmVzb3VyY2VJZCBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgQW5jZXN0b3Igc2V0UmVzb3VyY2VJZChSZXNvdXJjZUlkIHJlc291cmNlSWQpIHsKICAgIHRoaXMucmVzb3VyY2VJZCA9IHJlc291cmNlSWQ7CiAgICByZXR1cm4gdGhpczsKICB9CgogIEBPdmVycmlkZQogIHB1YmxpYyBBbmNlc3RvciBzZXQoU3RyaW5nIGZpZWxkTmFtZSwgT2JqZWN0IHZhbHVlKSB7CiAgICByZXR1cm4gKEFuY2VzdG9yKSBzdXBlci5zZXQoZmllbGROYW1lLCB2YWx1ZSk7CiAgfQoKICBAT3ZlcnJpZGUKICBwdWJsaWMgQW5jZXN0b3IgY2xvbmUoKSB7CiAgICByZXR1cm4gKEFuY2VzdG9yKSBzdXBlci5jbG9uZSgpOwogIH0KCn0KUEsDBBQAAAAAAAAAIQA4IRBW2RMAANkTAABDAAAAY29tL2dvb2dsZS9hcGkvc2VydmljZXMvY2xvdWRyZXNvdXJjZW1hbmFnZXIvbW9kZWwvQXVkaXRDb25maWcuamF2YS8qCiAqIENvcHlyaWdodCAyMDEwIEdvb2dsZSBJbmMuCiAqCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdAogKiBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZQogKiBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3MKICogb3IgaW1wbGllZC4gU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucyB1bmRlcgogKiB0aGUgTGljZW5zZS4KICovCi8qCiAqIFRoaXMgY29kZSB3YXMgZ2VuZXJhdGVkIGJ5IGh0dHBzOi8vZ2l0aHViLmNvbS9nb29nbGUvYXBpcy1jbGllbnQtZ2VuZXJhdG9yLwogKiAoYnVpbGQ6IDIwMTgtMTAtMDggMTc6NDU6MzkgVVRDKQogKiBvbiAyMDIwLTAzLTE5IGF0IDAyOjM4OjMwIFVUQyAKICogTW9kaWZ5IGF0IHlvdXIgb3duIHJpc2suCiAqLwoKcGFja2FnZSBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5jbG91ZHJlc291cmNlbWFuYWdlci5tb2RlbDsKCi8qKgogKiBTcGVjaWZpZXMgdGhlIGF1ZGl0IGNvbmZpZ3VyYXRpb24gZm9yIGEgc2VydmljZS4gVGhlIGNvbmZpZ3VyYXRpb24gZGV0ZXJtaW5lcyB3aGljaCBwZXJtaXNzaW9uCiAqIHR5cGVzIGFyZSBsb2dnZWQsIGFuZCB3aGF0IGlkZW50aXRpZXMsIGlmIGFueSwgYXJlIGV4ZW1wdGVkIGZyb20gbG9nZ2luZy4gQW4gQXVkaXRDb25maWcgbXVzdAogKiBoYXZlIG9uZSBvciBtb3JlIEF1ZGl0TG9nQ29uZmlncy4KICoKICogSWYgdGhlcmUgYXJlIEF1ZGl0Q29uZmlncyBmb3IgYm90aCBgYWxsU2VydmljZXNgIGFuZCBhIHNwZWNpZmljIHNlcnZpY2UsIHRoZSB1bmlvbiBvZiB0aGUgdHdvCiAqIEF1ZGl0Q29uZmlncyBpcyB1c2VkIGZvciB0aGF0IHNlcnZpY2U6IHRoZSBsb2dfdHlwZXMgc3BlY2lmaWVkIGluIGVhY2ggQXVkaXRDb25maWcgYXJlIGVuYWJsZWQsCiAqIGFuZCB0aGUgZXhlbXB0ZWRfbWVtYmVycyBpbiBlYWNoIEF1ZGl0TG9nQ29uZmlnIGFyZSBleGVtcHRlZC4KICoKICogRXhhbXBsZSBQb2xpY3kgd2l0aCBtdWx0aXBsZSBBdWRpdENvbmZpZ3M6CiAqCiAqICAgICB7ICAgICAgICJhdWRpdF9jb25maWdzIjogWyAgICAgICAgIHsgICAgICAgICAgICJzZXJ2aWNlIjogImFsbFNlcnZpY2VzIgogKiAiYXVkaXRfbG9nX2NvbmZpZ3MiOiBbICAgICAgICAgICAgIHsgICAgICAgICAgICAgICAibG9nX3R5cGUiOiAiREFUQV9SRUFEIiwKICogImV4ZW1wdGVkX21lbWJlcnMiOiBbICAgICAgICAgICAgICAgICAidXNlcjpqb3NlQGV4YW1wbGUuY29tIiAgICAgICAgICAgICAgIF0gICAgICAgICAgICAgfSwKICogeyAgICAgICAgICAgICAgICJsb2dfdHlwZSI6ICJEQVRBX1dSSVRFIiwgICAgICAgICAgICAgfSwgICAgICAgICAgICAgeyAgICAgICAgICAgICAgICJsb2dfdHlwZSI6CiAqICJBRE1JTl9SRUFEIiwgICAgICAgICAgICAgfSAgICAgICAgICAgXSAgICAgICAgIH0sICAgICAgICAgeyAgICAgICAgICAgInNlcnZpY2UiOgogKiAic2FtcGxlc2VydmljZS5nb29nbGVhcGlzLmNvbSIgICAgICAgICAgICJhdWRpdF9sb2dfY29uZmlncyI6IFsgICAgICAgICAgICAgewogKiAibG9nX3R5cGUiOiAiREFUQV9SRUFEIiwgICAgICAgICAgICAgfSwgICAgICAgICAgICAgeyAgICAgICAgICAgICAgICJsb2dfdHlwZSI6ICJEQVRBX1dSSVRFIiwKICogImV4ZW1wdGVkX21lbWJlcnMiOiBbICAgICAgICAgICAgICAgICAidXNlcjphbGl5YUBleGFtcGxlLmNvbSIgICAgICAgICAgICAgICBdICAgICAgICAgICAgIH0KICogXSAgICAgICAgIH0gICAgICAgXSAgICAgfQogKgogKiBGb3Igc2FtcGxlc2VydmljZSwgdGhpcyBwb2xpY3kgZW5hYmxlcyBEQVRBX1JFQUQsIERBVEFfV1JJVEUgYW5kIEFETUlOX1JFQUQgbG9nZ2luZy4gSXQgYWxzbwogKiBleGVtcHRzIGpvc2VAZXhhbXBsZS5jb20gZnJvbSBEQVRBX1JFQUQgbG9nZ2luZywgYW5kIGFsaXlhQGV4YW1wbGUuY29tIGZyb20gREFUQV9XUklURSBsb2dnaW5nLgogKgogKiA8cD4gVGhpcyBpcyB0aGUgSmF2YSBkYXRhIG1vZGVsIGNsYXNzIHRoYXQgc3BlY2lmaWVzIGhvdyB0byBwYXJzZS9zZXJpYWxpemUgaW50byB0aGUgSlNPTiB0aGF0IGlzCiAqIHRyYW5zbWl0dGVkIG92ZXIgSFRUUCB3aGVuIHdvcmtpbmcgd2l0aCB0aGUgQ2xvdWQgUmVzb3VyY2UgTWFuYWdlciBBUEkuIEZvciBhIGRldGFpbGVkCiAqIGV4cGxhbmF0aW9uIHNlZToKICogPGEgaHJlZj0iaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vYXBpLWNsaWVudC1saWJyYXJ5L2phdmEvZ29vZ2xlLWh0dHAtamF2YS1jbGllbnQvanNvbiI+aHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vYXBpLWNsaWVudC1saWJyYXJ5L2phdmEvZ29vZ2xlLWh0dHAtamF2YS1jbGllbnQvanNvbjwvYT4KICogPC9wPgogKgogKiBAYXV0aG9yIEdvb2dsZSwgSW5jLgogKi8KQFN1cHByZXNzV2FybmluZ3MoImphdmFkb2MiKQpwdWJsaWMgZmluYWwgY2xhc3MgQXVkaXRDb25maWcgZXh0ZW5kcyBjb20uZ29vZ2xlLmFwaS5jbGllbnQuanNvbi5HZW5lcmljSnNvbiB7CgogIC8qKgogICAqIFRoZSBjb25maWd1cmF0aW9uIGZvciBsb2dnaW5nIG9mIGVhY2ggdHlwZSBvZiBwZXJtaXNzaW9uLgogICAqIFRoZSB2YWx1ZSBtYXkgYmUge0Bjb2RlIG51bGx9LgogICAqLwogIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICBwcml2YXRlIGphdmEudXRpbC5MaXN0PEF1ZGl0TG9nQ29uZmlnPiBhdWRpdExvZ0NvbmZpZ3M7CgogIHN0YXRpYyB7CiAgICAvLyBoYWNrIHRvIGZvcmNlIFByb0d1YXJkIHRvIGNvbnNpZGVyIEF1ZGl0TG9nQ29uZmlnIHVzZWQsIHNpbmNlIG90aGVyd2lzZSBpdCB3b3VsZCBiZSBzdHJpcHBlZCBvdXQKICAgIC8vIHNlZSBodHRwczovL2dpdGh1Yi5jb20vZ29vZ2xlL2dvb2dsZS1hcGktamF2YS1jbGllbnQvaXNzdWVzLzU0MwogICAgY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuRGF0YS5udWxsT2YoQXVkaXRMb2dDb25maWcuY2xhc3MpOwogIH0KCiAgLyoqCiAgICogU3BlY2lmaWVzIGEgc2VydmljZSB0aGF0IHdpbGwgYmUgZW5hYmxlZCBmb3IgYXVkaXQgbG9nZ2luZy4gRm9yIGV4YW1wbGUsCiAgICogYHN0b3JhZ2UuZ29vZ2xlYXBpcy5jb21gLCBgY2xvdWRzcWwuZ29vZ2xlYXBpcy5jb21gLiBgYWxsU2VydmljZXNgIGlzIGEgc3BlY2lhbCB2YWx1ZSB0aGF0CiAgICogY292ZXJzIGFsbCBzZXJ2aWNlcy4KICAgKiBUaGUgdmFsdWUgbWF5IGJlIHtAY29kZSBudWxsfS4KICAgKi8KICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgcHJpdmF0ZSBqYXZhLmxhbmcuU3RyaW5nIHNlcnZpY2U7CgogIC8qKgogICAqIFRoZSBjb25maWd1cmF0aW9uIGZvciBsb2dnaW5nIG9mIGVhY2ggdHlwZSBvZiBwZXJtaXNzaW9uLgogICAqIEByZXR1cm4gdmFsdWUgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIGphdmEudXRpbC5MaXN0PEF1ZGl0TG9nQ29uZmlnPiBnZXRBdWRpdExvZ0NvbmZpZ3MoKSB7CiAgICByZXR1cm4gYXVkaXRMb2dDb25maWdzOwogIH0KCiAgLyoqCiAgICogVGhlIGNvbmZpZ3VyYXRpb24gZm9yIGxvZ2dpbmcgb2YgZWFjaCB0eXBlIG9mIHBlcm1pc3Npb24uCiAgICogQHBhcmFtIGF1ZGl0TG9nQ29uZmlncyBhdWRpdExvZ0NvbmZpZ3Mgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIEF1ZGl0Q29uZmlnIHNldEF1ZGl0TG9nQ29uZmlncyhqYXZhLnV0aWwuTGlzdDxBdWRpdExvZ0NvbmZpZz4gYXVkaXRMb2dDb25maWdzKSB7CiAgICB0aGlzLmF1ZGl0TG9nQ29uZmlncyA9IGF1ZGl0TG9nQ29uZmlnczsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgLyoqCiAgICogU3BlY2lmaWVzIGEgc2VydmljZSB0aGF0IHdpbGwgYmUgZW5hYmxlZCBmb3IgYXVkaXQgbG9nZ2luZy4gRm9yIGV4YW1wbGUsCiAgICogYHN0b3JhZ2UuZ29vZ2xlYXBpcy5jb21gLCBgY2xvdWRzcWwuZ29vZ2xlYXBpcy5jb21gLiBgYWxsU2VydmljZXNgIGlzIGEgc3BlY2lhbCB2YWx1ZSB0aGF0CiAgICogY292ZXJzIGFsbCBzZXJ2aWNlcy4KICAgKiBAcmV0dXJuIHZhbHVlIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFNlcnZpY2UoKSB7CiAgICByZXR1cm4gc2VydmljZTsKICB9CgogIC8qKgogICAqIFNwZWNpZmllcyBhIHNlcnZpY2UgdGhhdCB3aWxsIGJlIGVuYWJsZWQgZm9yIGF1ZGl0IGxvZ2dpbmcuIEZvciBleGFtcGxlLAogICAqIGBzdG9yYWdlLmdvb2dsZWFwaXMuY29tYCwgYGNsb3Vkc3FsLmdvb2dsZWFwaXMuY29tYC4gYGFsbFNlcnZpY2VzYCBpcyBhIHNwZWNpYWwgdmFsdWUgdGhhdAogICAqIGNvdmVycyBhbGwgc2VydmljZXMuCiAgICogQHBhcmFtIHNlcnZpY2Ugc2VydmljZSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgQXVkaXRDb25maWcgc2V0U2VydmljZShqYXZhLmxhbmcuU3RyaW5nIHNlcnZpY2UpIHsKICAgIHRoaXMuc2VydmljZSA9IHNlcnZpY2U7CiAgICByZXR1cm4gdGhpczsKICB9CgogIEBPdmVycmlkZQogIHB1YmxpYyBBdWRpdENvbmZpZyBzZXQoU3RyaW5nIGZpZWxkTmFtZSwgT2JqZWN0IHZhbHVlKSB7CiAgICByZXR1cm4gKEF1ZGl0Q29uZmlnKSBzdXBlci5zZXQoZmllbGROYW1lLCB2YWx1ZSk7CiAgfQoKICBAT3ZlcnJpZGUKICBwdWJsaWMgQXVkaXRDb25maWcgY2xvbmUoKSB7CiAgICByZXR1cm4gKEF1ZGl0Q29uZmlnKSBzdXBlci5jbG9uZSgpOwogIH0KCn0KUEsDBBQAAAAAAAAAIQA07l57zA0AAMwNAABGAAAAY29tL2dvb2dsZS9hcGkvc2VydmljZXMvY2xvdWRyZXNvdXJjZW1hbmFnZXIvbW9kZWwvQXVkaXRMb2dDb25maWcuamF2YS8qCiAqIENvcHlyaWdodCAyMDEwIEdvb2dsZSBJbmMuCiAqCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdAogKiBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZQogKiBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3MKICogb3IgaW1wbGllZC4gU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucyB1bmRlcgogKiB0aGUgTGljZW5zZS4KICovCi8qCiAqIFRoaXMgY29kZSB3YXMgZ2VuZXJhdGVkIGJ5IGh0dHBzOi8vZ2l0aHViLmNvbS9nb29nbGUvYXBpcy1jbGllbnQtZ2VuZXJhdG9yLwogKiAoYnVpbGQ6IDIwMTgtMTAtMDggMTc6NDU6MzkgVVRDKQogKiBvbiAyMDIwLTAzLTE5IGF0IDAyOjM4OjMwIFVUQyAKICogTW9kaWZ5IGF0IHlvdXIgb3duIHJpc2suCiAqLwoKcGFja2FnZSBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5jbG91ZHJlc291cmNlbWFuYWdlci5tb2RlbDsKCi8qKgogKiBQcm92aWRlcyB0aGUgY29uZmlndXJhdGlvbiBmb3IgbG9nZ2luZyBhIHR5cGUgb2YgcGVybWlzc2lvbnMuIEV4YW1wbGU6CiAqCiAqICAgICB7ICAgICAgICJhdWRpdF9sb2dfY29uZmlncyI6IFsgICAgICAgICB7ICAgICAgICAgICAibG9nX3R5cGUiOiAiREFUQV9SRUFEIiwKICogImV4ZW1wdGVkX21lbWJlcnMiOiBbICAgICAgICAgICAgICJ1c2VyOmpvc2VAZXhhbXBsZS5jb20iICAgICAgICAgICBdICAgICAgICAgfSwgICAgICAgICB7CiAqICJsb2dfdHlwZSI6ICJEQVRBX1dSSVRFIiwgICAgICAgICB9ICAgICAgIF0gICAgIH0KICoKICogVGhpcyBlbmFibGVzICdEQVRBX1JFQUQnIGFuZCAnREFUQV9XUklURScgbG9nZ2luZywgd2hpbGUgZXhlbXB0aW5nIGpvc2VAZXhhbXBsZS5jb20gZnJvbQogKiBEQVRBX1JFQUQgbG9nZ2luZy4KICoKICogPHA+IFRoaXMgaXMgdGhlIEphdmEgZGF0YSBtb2RlbCBjbGFzcyB0aGF0IHNwZWNpZmllcyBob3cgdG8gcGFyc2Uvc2VyaWFsaXplIGludG8gdGhlIEpTT04gdGhhdCBpcwogKiB0cmFuc21pdHRlZCBvdmVyIEhUVFAgd2hlbiB3b3JraW5nIHdpdGggdGhlIENsb3VkIFJlc291cmNlIE1hbmFnZXIgQVBJLiBGb3IgYSBkZXRhaWxlZAogKiBleHBsYW5hdGlvbiBzZWU6CiAqIDxhIGhyZWY9Imh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL2FwaS1jbGllbnQtbGlicmFyeS9qYXZhL2dvb2dsZS1odHRwLWphdmEtY2xpZW50L2pzb24iPmh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL2FwaS1jbGllbnQtbGlicmFyeS9qYXZhL2dvb2dsZS1odHRwLWphdmEtY2xpZW50L2pzb248L2E+CiAqIDwvcD4KICoKICogQGF1dGhvciBHb29nbGUsIEluYy4KICovCkBTdXBwcmVzc1dhcm5pbmdzKCJqYXZhZG9jIikKcHVibGljIGZpbmFsIGNsYXNzIEF1ZGl0TG9nQ29uZmlnIGV4dGVuZHMgY29tLmdvb2dsZS5hcGkuY2xpZW50Lmpzb24uR2VuZXJpY0pzb24gewoKICAvKioKICAgKiBTcGVjaWZpZXMgdGhlIGlkZW50aXRpZXMgdGhhdCBkbyBub3QgY2F1c2UgbG9nZ2luZyBmb3IgdGhpcyB0eXBlIG9mIHBlcm1pc3Npb24uIEZvbGxvd3MgdGhlCiAgICogc2FtZSBmb3JtYXQgb2YgQmluZGluZy5tZW1iZXJzLgogICAqIFRoZSB2YWx1ZSBtYXkgYmUge0Bjb2RlIG51bGx9LgogICAqLwogIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICBwcml2YXRlIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5TdHJpbmc+IGV4ZW1wdGVkTWVtYmVyczsKCiAgLyoqCiAgICogVGhlIGxvZyB0eXBlIHRoYXQgdGhpcyBjb25maWcgZW5hYmxlcy4KICAgKiBUaGUgdmFsdWUgbWF5IGJlIHtAY29kZSBudWxsfS4KICAgKi8KICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgcHJpdmF0ZSBqYXZhLmxhbmcuU3RyaW5nIGxvZ1R5cGU7CgogIC8qKgogICAqIFNwZWNpZmllcyB0aGUgaWRlbnRpdGllcyB0aGF0IGRvIG5vdCBjYXVzZSBsb2dnaW5nIGZvciB0aGlzIHR5cGUgb2YgcGVybWlzc2lvbi4gRm9sbG93cyB0aGUKICAgKiBzYW1lIGZvcm1hdCBvZiBCaW5kaW5nLm1lbWJlcnMuCiAgICogQHJldHVybiB2YWx1ZSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLlN0cmluZz4gZ2V0RXhlbXB0ZWRNZW1iZXJzKCkgewogICAgcmV0dXJuIGV4ZW1wdGVkTWVtYmVyczsKICB9CgogIC8qKgogICAqIFNwZWNpZmllcyB0aGUgaWRlbnRpdGllcyB0aGF0IGRvIG5vdCBjYXVzZSBsb2dnaW5nIGZvciB0aGlzIHR5cGUgb2YgcGVybWlzc2lvbi4gRm9sbG93cyB0aGUKICAgKiBzYW1lIGZvcm1hdCBvZiBCaW5kaW5nLm1lbWJlcnMuCiAgICogQHBhcmFtIGV4ZW1wdGVkTWVtYmVycyBleGVtcHRlZE1lbWJlcnMgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIEF1ZGl0TG9nQ29uZmlnIHNldEV4ZW1wdGVkTWVtYmVycyhqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuU3RyaW5nPiBleGVtcHRlZE1lbWJlcnMpIHsKICAgIHRoaXMuZXhlbXB0ZWRNZW1iZXJzID0gZXhlbXB0ZWRNZW1iZXJzOwogICAgcmV0dXJuIHRoaXM7CiAgfQoKICAvKioKICAgKiBUaGUgbG9nIHR5cGUgdGhhdCB0aGlzIGNvbmZpZyBlbmFibGVzLgogICAqIEByZXR1cm4gdmFsdWUgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9nVHlwZSgpIHsKICAgIHJldHVybiBsb2dUeXBlOwogIH0KCiAgLyoqCiAgICogVGhlIGxvZyB0eXBlIHRoYXQgdGhpcyBjb25maWcgZW5hYmxlcy4KICAgKiBAcGFyYW0gbG9nVHlwZSBsb2dUeXBlIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBBdWRpdExvZ0NvbmZpZyBzZXRMb2dUeXBlKGphdmEubGFuZy5TdHJpbmcgbG9nVHlwZSkgewogICAgdGhpcy5sb2dUeXBlID0gbG9nVHlwZTsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgQE92ZXJyaWRlCiAgcHVibGljIEF1ZGl0TG9nQ29uZmlnIHNldChTdHJpbmcgZmllbGROYW1lLCBPYmplY3QgdmFsdWUpIHsKICAgIHJldHVybiAoQXVkaXRMb2dDb25maWcpIHN1cGVyLnNldChmaWVsZE5hbWUsIHZhbHVlKTsKICB9CgogIEBPdmVycmlkZQogIHB1YmxpYyBBdWRpdExvZ0NvbmZpZyBjbG9uZSgpIHsKICAgIHJldHVybiAoQXVkaXRMb2dDb25maWcpIHN1cGVyLmNsb25lKCk7CiAgfQoKfQpQSwMEFAAAAAAAAAAhAEZEXKYyKAAAMigAAD8AAABjb20vZ29vZ2xlL2FwaS9zZXJ2aWNlcy9jbG91ZHJlc291cmNlbWFuYWdlci9tb2RlbC9CaW5kaW5nLmphdmEvKgogKiBDb3B5cmlnaHQgMjAxMCBHb29nbGUgSW5jLgogKgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQKICogaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UKICogaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzCiAqIG9yIGltcGxpZWQuIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMgdW5kZXIKICogdGhlIExpY2Vuc2UuCiAqLwovKgogKiBUaGlzIGNvZGUgd2FzIGdlbmVyYXRlZCBieSBodHRwczovL2dpdGh1Yi5jb20vZ29vZ2xlL2FwaXMtY2xpZW50LWdlbmVyYXRvci8KICogKGJ1aWxkOiAyMDE4LTEwLTA4IDE3OjQ1OjM5IFVUQykKICogb24gMjAyMC0wMy0xOSBhdCAwMjozODozMCBVVEMgCiAqIE1vZGlmeSBhdCB5b3VyIG93biByaXNrLgogKi8KCnBhY2thZ2UgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuY2xvdWRyZXNvdXJjZW1hbmFnZXIubW9kZWw7CgovKioKICogQXNzb2NpYXRlcyBgbWVtYmVyc2Agd2l0aCBhIGByb2xlYC4KICoKICogPHA+IFRoaXMgaXMgdGhlIEphdmEgZGF0YSBtb2RlbCBjbGFzcyB0aGF0IHNwZWNpZmllcyBob3cgdG8gcGFyc2Uvc2VyaWFsaXplIGludG8gdGhlIEpTT04gdGhhdCBpcwogKiB0cmFuc21pdHRlZCBvdmVyIEhUVFAgd2hlbiB3b3JraW5nIHdpdGggdGhlIENsb3VkIFJlc291cmNlIE1hbmFnZXIgQVBJLiBGb3IgYSBkZXRhaWxlZAogKiBleHBsYW5hdGlvbiBzZWU6CiAqIDxhIGhyZWY9Imh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL2FwaS1jbGllbnQtbGlicmFyeS9qYXZhL2dvb2dsZS1odHRwLWphdmEtY2xpZW50L2pzb24iPmh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL2FwaS1jbGllbnQtbGlicmFyeS9qYXZhL2dvb2dsZS1odHRwLWphdmEtY2xpZW50L2pzb248L2E+CiAqIDwvcD4KICoKICogQGF1dGhvciBHb29nbGUsIEluYy4KICovCkBTdXBwcmVzc1dhcm5pbmdzKCJqYXZhZG9jIikKcHVibGljIGZpbmFsIGNsYXNzIEJpbmRpbmcgZXh0ZW5kcyBjb20uZ29vZ2xlLmFwaS5jbGllbnQuanNvbi5HZW5lcmljSnNvbiB7CgogIC8qKgogICAqIFRoZSBjb25kaXRpb24gdGhhdCBpcyBhc3NvY2lhdGVkIHdpdGggdGhpcyBiaW5kaW5nLiBOT1RFOiBBbiB1bnNhdGlzZmllZCBjb25kaXRpb24gd2lsbCBub3QKICAgKiBhbGxvdyB1c2VyIGFjY2VzcyB2aWEgY3VycmVudCBiaW5kaW5nLiBEaWZmZXJlbnQgYmluZGluZ3MsIGluY2x1ZGluZyB0aGVpciBjb25kaXRpb25zLCBhcmUKICAgKiBleGFtaW5lZCBpbmRlcGVuZGVudGx5LgogICAqIFRoZSB2YWx1ZSBtYXkgYmUge0Bjb2RlIG51bGx9LgogICAqLwogIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICBwcml2YXRlIEV4cHIgY29uZGl0aW9uOwoKICAvKioKICAgKiBTcGVjaWZpZXMgdGhlIGlkZW50aXRpZXMgcmVxdWVzdGluZyBhY2Nlc3MgZm9yIGEgQ2xvdWQgUGxhdGZvcm0gcmVzb3VyY2UuIGBtZW1iZXJzYCBjYW4gaGF2ZQogICAqIHRoZSBmb2xsb3dpbmcgdmFsdWVzOgogICAqCiAgICogKiBgYWxsVXNlcnNgOiBBIHNwZWNpYWwgaWRlbnRpZmllciB0aGF0IHJlcHJlc2VudHMgYW55b25lIHdobyBpcyAgICBvbiB0aGUgaW50ZXJuZXQ7IHdpdGggb3IKICAgKiB3aXRob3V0IGEgR29vZ2xlIGFjY291bnQuCiAgICoKICAgKiAqIGBhbGxBdXRoZW50aWNhdGVkVXNlcnNgOiBBIHNwZWNpYWwgaWRlbnRpZmllciB0aGF0IHJlcHJlc2VudHMgYW55b25lICAgIHdobyBpcyBhdXRoZW50aWNhdGVkCiAgICogd2l0aCBhIEdvb2dsZSBhY2NvdW50IG9yIGEgc2VydmljZSBhY2NvdW50LgogICAqCiAgICogKiBgdXNlcjp7ZW1haWxpZH1gOiBBbiBlbWFpbCBhZGRyZXNzIHRoYXQgcmVwcmVzZW50cyBhIHNwZWNpZmljIEdvb2dsZSAgICBhY2NvdW50LiBGb3IgZXhhbXBsZSwKICAgKiBgYWxpY2VAZXhhbXBsZS5jb21gIC4KICAgKgogICAqICogYHNlcnZpY2VBY2NvdW50OntlbWFpbGlkfWA6IEFuIGVtYWlsIGFkZHJlc3MgdGhhdCByZXByZXNlbnRzIGEgc2VydmljZSAgICBhY2NvdW50LiBGb3IKICAgKiBleGFtcGxlLCBgbXktb3RoZXItYXBwQGFwcHNwb3QuZ3NlcnZpY2VhY2NvdW50LmNvbWAuCiAgICoKICAgKiAqIGBncm91cDp7ZW1haWxpZH1gOiBBbiBlbWFpbCBhZGRyZXNzIHRoYXQgcmVwcmVzZW50cyBhIEdvb2dsZSBncm91cC4gICAgRm9yIGV4YW1wbGUsCiAgICogYGFkbWluc0BleGFtcGxlLmNvbWAuCiAgICoKICAgKiAqIGBkZWxldGVkOnVzZXI6e2VtYWlsaWR9P3VpZD17dW5pcXVlaWR9YDogQW4gZW1haWwgYWRkcmVzcyAocGx1cyB1bmlxdWUgICAgaWRlbnRpZmllcikKICAgKiByZXByZXNlbnRpbmcgYSB1c2VyIHRoYXQgaGFzIGJlZW4gcmVjZW50bHkgZGVsZXRlZC4gRm9yICAgIGV4YW1wbGUsCiAgICogYGFsaWNlQGV4YW1wbGUuY29tP3VpZD0xMjM0NTY3ODkwMTIzNDU2Nzg5MDFgLiBJZiB0aGUgdXNlciBpcyAgICByZWNvdmVyZWQsIHRoaXMgdmFsdWUgcmV2ZXJ0cwogICAqIHRvIGB1c2VyOntlbWFpbGlkfWAgYW5kIHRoZSByZWNvdmVyZWQgdXNlciAgICByZXRhaW5zIHRoZSByb2xlIGluIHRoZSBiaW5kaW5nLgogICAqCiAgICogKiBgZGVsZXRlZDpzZXJ2aWNlQWNjb3VudDp7ZW1haWxpZH0/dWlkPXt1bmlxdWVpZH1gOiBBbiBlbWFpbCBhZGRyZXNzIChwbHVzICAgIHVuaXF1ZQogICAqIGlkZW50aWZpZXIpIHJlcHJlc2VudGluZyBhIHNlcnZpY2UgYWNjb3VudCB0aGF0IGhhcyBiZWVuIHJlY2VudGx5ICAgIGRlbGV0ZWQuIEZvciBleGFtcGxlLAogICAqIGBteS1vdGhlci1hcHBAYXBwc3BvdC5nc2VydmljZWFjY291bnQuY29tP3VpZD0xMjM0NTY3ODkwMTIzNDU2Nzg5MDFgLiAgICBJZiB0aGUgc2VydmljZSBhY2NvdW50CiAgICogaXMgdW5kZWxldGVkLCB0aGlzIHZhbHVlIHJldmVydHMgdG8gICAgYHNlcnZpY2VBY2NvdW50OntlbWFpbGlkfWAgYW5kIHRoZSB1bmRlbGV0ZWQgc2VydmljZQogICAqIGFjY291bnQgcmV0YWlucyB0aGUgICAgcm9sZSBpbiB0aGUgYmluZGluZy4KICAgKgogICAqICogYGRlbGV0ZWQ6Z3JvdXA6e2VtYWlsaWR9P3VpZD17dW5pcXVlaWR9YDogQW4gZW1haWwgYWRkcmVzcyAocGx1cyB1bmlxdWUgICAgaWRlbnRpZmllcikKICAgKiByZXByZXNlbnRpbmcgYSBHb29nbGUgZ3JvdXAgdGhhdCBoYXMgYmVlbiByZWNlbnRseSAgICBkZWxldGVkLiBGb3IgZXhhbXBsZSwKICAgKiBgYWRtaW5zQGV4YW1wbGUuY29tP3VpZD0xMjM0NTY3ODkwMTIzNDU2Nzg5MDFgLiBJZiAgICB0aGUgZ3JvdXAgaXMgcmVjb3ZlcmVkLCB0aGlzIHZhbHVlCiAgICogcmV2ZXJ0cyB0byBgZ3JvdXA6e2VtYWlsaWR9YCBhbmQgdGhlICAgIHJlY292ZXJlZCBncm91cCByZXRhaW5zIHRoZSByb2xlIGluIHRoZSBiaW5kaW5nLgogICAqCiAgICogKiBgZG9tYWluOntkb21haW59YDogVGhlIEcgU3VpdGUgZG9tYWluIChwcmltYXJ5KSB0aGF0IHJlcHJlc2VudHMgYWxsIHRoZSAgICB1c2VycyBvZiB0aGF0CiAgICogZG9tYWluLiBGb3IgZXhhbXBsZSwgYGdvb2dsZS5jb21gIG9yIGBleGFtcGxlLmNvbWAuCiAgICogVGhlIHZhbHVlIG1heSBiZSB7QGNvZGUgbnVsbH0uCiAgICovCiAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLlN0cmluZz4gbWVtYmVyczsKCiAgLyoqCiAgICogUm9sZSB0aGF0IGlzIGFzc2lnbmVkIHRvIGBtZW1iZXJzYC4gRm9yIGV4YW1wbGUsIGByb2xlcy92aWV3ZXJgLCBgcm9sZXMvZWRpdG9yYCwgb3IKICAgKiBgcm9sZXMvb3duZXJgLgogICAqIFRoZSB2YWx1ZSBtYXkgYmUge0Bjb2RlIG51bGx9LgogICAqLwogIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICBwcml2YXRlIGphdmEubGFuZy5TdHJpbmcgcm9sZTsKCiAgLyoqCiAgICogVGhlIGNvbmRpdGlvbiB0aGF0IGlzIGFzc29jaWF0ZWQgd2l0aCB0aGlzIGJpbmRpbmcuIE5PVEU6IEFuIHVuc2F0aXNmaWVkIGNvbmRpdGlvbiB3aWxsIG5vdAogICAqIGFsbG93IHVzZXIgYWNjZXNzIHZpYSBjdXJyZW50IGJpbmRpbmcuIERpZmZlcmVudCBiaW5kaW5ncywgaW5jbHVkaW5nIHRoZWlyIGNvbmRpdGlvbnMsIGFyZQogICAqIGV4YW1pbmVkIGluZGVwZW5kZW50bHkuCiAgICogQHJldHVybiB2YWx1ZSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgRXhwciBnZXRDb25kaXRpb24oKSB7CiAgICByZXR1cm4gY29uZGl0aW9uOwogIH0KCiAgLyoqCiAgICogVGhlIGNvbmRpdGlvbiB0aGF0IGlzIGFzc29jaWF0ZWQgd2l0aCB0aGlzIGJpbmRpbmcuIE5PVEU6IEFuIHVuc2F0aXNmaWVkIGNvbmRpdGlvbiB3aWxsIG5vdAogICAqIGFsbG93IHVzZXIgYWNjZXNzIHZpYSBjdXJyZW50IGJpbmRpbmcuIERpZmZlcmVudCBiaW5kaW5ncywgaW5jbHVkaW5nIHRoZWlyIGNvbmRpdGlvbnMsIGFyZQogICAqIGV4YW1pbmVkIGluZGVwZW5kZW50bHkuCiAgICogQHBhcmFtIGNvbmRpdGlvbiBjb25kaXRpb24gb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIEJpbmRpbmcgc2V0Q29uZGl0aW9uKEV4cHIgY29uZGl0aW9uKSB7CiAgICB0aGlzLmNvbmRpdGlvbiA9IGNvbmRpdGlvbjsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgLyoqCiAgICogU3BlY2lmaWVzIHRoZSBpZGVudGl0aWVzIHJlcXVlc3RpbmcgYWNjZXNzIGZvciBhIENsb3VkIFBsYXRmb3JtIHJlc291cmNlLiBgbWVtYmVyc2AgY2FuIGhhdmUKICAgKiB0aGUgZm9sbG93aW5nIHZhbHVlczoKICAgKgogICAqICogYGFsbFVzZXJzYDogQSBzcGVjaWFsIGlkZW50aWZpZXIgdGhhdCByZXByZXNlbnRzIGFueW9uZSB3aG8gaXMgICAgb24gdGhlIGludGVybmV0OyB3aXRoIG9yCiAgICogd2l0aG91dCBhIEdvb2dsZSBhY2NvdW50LgogICAqCiAgICogKiBgYWxsQXV0aGVudGljYXRlZFVzZXJzYDogQSBzcGVjaWFsIGlkZW50aWZpZXIgdGhhdCByZXByZXNlbnRzIGFueW9uZSAgICB3aG8gaXMgYXV0aGVudGljYXRlZAogICAqIHdpdGggYSBHb29nbGUgYWNjb3VudCBvciBhIHNlcnZpY2UgYWNjb3VudC4KICAgKgogICAqICogYHVzZXI6e2VtYWlsaWR9YDogQW4gZW1haWwgYWRkcmVzcyB0aGF0IHJlcHJlc2VudHMgYSBzcGVjaWZpYyBHb29nbGUgICAgYWNjb3VudC4gRm9yIGV4YW1wbGUsCiAgICogYGFsaWNlQGV4YW1wbGUuY29tYCAuCiAgICoKICAgKiAqIGBzZXJ2aWNlQWNjb3VudDp7ZW1haWxpZH1gOiBBbiBlbWFpbCBhZGRyZXNzIHRoYXQgcmVwcmVzZW50cyBhIHNlcnZpY2UgICAgYWNjb3VudC4gRm9yCiAgICogZXhhbXBsZSwgYG15LW90aGVyLWFwcEBhcHBzcG90LmdzZXJ2aWNlYWNjb3VudC5jb21gLgogICAqCiAgICogKiBgZ3JvdXA6e2VtYWlsaWR9YDogQW4gZW1haWwgYWRkcmVzcyB0aGF0IHJlcHJlc2VudHMgYSBHb29nbGUgZ3JvdXAuICAgIEZvciBleGFtcGxlLAogICAqIGBhZG1pbnNAZXhhbXBsZS5jb21gLgogICAqCiAgICogKiBgZGVsZXRlZDp1c2VyOntlbWFpbGlkfT91aWQ9e3VuaXF1ZWlkfWA6IEFuIGVtYWlsIGFkZHJlc3MgKHBsdXMgdW5pcXVlICAgIGlkZW50aWZpZXIpCiAgICogcmVwcmVzZW50aW5nIGEgdXNlciB0aGF0IGhhcyBiZWVuIHJlY2VudGx5IGRlbGV0ZWQuIEZvciAgICBleGFtcGxlLAogICAqIGBhbGljZUBleGFtcGxlLmNvbT91aWQ9MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxYC4gSWYgdGhlIHVzZXIgaXMgICAgcmVjb3ZlcmVkLCB0aGlzIHZhbHVlIHJldmVydHMKICAgKiB0byBgdXNlcjp7ZW1haWxpZH1gIGFuZCB0aGUgcmVjb3ZlcmVkIHVzZXIgICAgcmV0YWlucyB0aGUgcm9sZSBpbiB0aGUgYmluZGluZy4KICAgKgogICAqICogYGRlbGV0ZWQ6c2VydmljZUFjY291bnQ6e2VtYWlsaWR9P3VpZD17dW5pcXVlaWR9YDogQW4gZW1haWwgYWRkcmVzcyAocGx1cyAgICB1bmlxdWUKICAgKiBpZGVudGlmaWVyKSByZXByZXNlbnRpbmcgYSBzZXJ2aWNlIGFjY291bnQgdGhhdCBoYXMgYmVlbiByZWNlbnRseSAgICBkZWxldGVkLiBGb3IgZXhhbXBsZSwKICAgKiBgbXktb3RoZXItYXBwQGFwcHNwb3QuZ3NlcnZpY2VhY2NvdW50LmNvbT91aWQ9MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxYC4gICAgSWYgdGhlIHNlcnZpY2UgYWNjb3VudAogICAqIGlzIHVuZGVsZXRlZCwgdGhpcyB2YWx1ZSByZXZlcnRzIHRvICAgIGBzZXJ2aWNlQWNjb3VudDp7ZW1haWxpZH1gIGFuZCB0aGUgdW5kZWxldGVkIHNlcnZpY2UKICAgKiBhY2NvdW50IHJldGFpbnMgdGhlICAgIHJvbGUgaW4gdGhlIGJpbmRpbmcuCiAgICoKICAgKiAqIGBkZWxldGVkOmdyb3VwOntlbWFpbGlkfT91aWQ9e3VuaXF1ZWlkfWA6IEFuIGVtYWlsIGFkZHJlc3MgKHBsdXMgdW5pcXVlICAgIGlkZW50aWZpZXIpCiAgICogcmVwcmVzZW50aW5nIGEgR29vZ2xlIGdyb3VwIHRoYXQgaGFzIGJlZW4gcmVjZW50bHkgICAgZGVsZXRlZC4gRm9yIGV4YW1wbGUsCiAgICogYGFkbWluc0BleGFtcGxlLmNvbT91aWQ9MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxYC4gSWYgICAgdGhlIGdyb3VwIGlzIHJlY292ZXJlZCwgdGhpcyB2YWx1ZQogICAqIHJldmVydHMgdG8gYGdyb3VwOntlbWFpbGlkfWAgYW5kIHRoZSAgICByZWNvdmVyZWQgZ3JvdXAgcmV0YWlucyB0aGUgcm9sZSBpbiB0aGUgYmluZGluZy4KICAgKgogICAqICogYGRvbWFpbjp7ZG9tYWlufWA6IFRoZSBHIFN1aXRlIGRvbWFpbiAocHJpbWFyeSkgdGhhdCByZXByZXNlbnRzIGFsbCB0aGUgICAgdXNlcnMgb2YgdGhhdAogICAqIGRvbWFpbi4gRm9yIGV4YW1wbGUsIGBnb29nbGUuY29tYCBvciBgZXhhbXBsZS5jb21gLgogICAqIEByZXR1cm4gdmFsdWUgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5TdHJpbmc+IGdldE1lbWJlcnMoKSB7CiAgICByZXR1cm4gbWVtYmVyczsKICB9CgogIC8qKgogICAqIFNwZWNpZmllcyB0aGUgaWRlbnRpdGllcyByZXF1ZXN0aW5nIGFjY2VzcyBmb3IgYSBDbG91ZCBQbGF0Zm9ybSByZXNvdXJjZS4gYG1lbWJlcnNgIGNhbiBoYXZlCiAgICogdGhlIGZvbGxvd2luZyB2YWx1ZXM6CiAgICoKICAgKiAqIGBhbGxVc2Vyc2A6IEEgc3BlY2lhbCBpZGVudGlmaWVyIHRoYXQgcmVwcmVzZW50cyBhbnlvbmUgd2hvIGlzICAgIG9uIHRoZSBpbnRlcm5ldDsgd2l0aCBvcgogICAqIHdpdGhvdXQgYSBHb29nbGUgYWNjb3VudC4KICAgKgogICAqICogYGFsbEF1dGhlbnRpY2F0ZWRVc2Vyc2A6IEEgc3BlY2lhbCBpZGVudGlmaWVyIHRoYXQgcmVwcmVzZW50cyBhbnlvbmUgICAgd2hvIGlzIGF1dGhlbnRpY2F0ZWQKICAgKiB3aXRoIGEgR29vZ2xlIGFjY291bnQgb3IgYSBzZXJ2aWNlIGFjY291bnQuCiAgICoKICAgKiAqIGB1c2VyOntlbWFpbGlkfWA6IEFuIGVtYWlsIGFkZHJlc3MgdGhhdCByZXByZXNlbnRzIGEgc3BlY2lmaWMgR29vZ2xlICAgIGFjY291bnQuIEZvciBleGFtcGxlLAogICAqIGBhbGljZUBleGFtcGxlLmNvbWAgLgogICAqCiAgICogKiBgc2VydmljZUFjY291bnQ6e2VtYWlsaWR9YDogQW4gZW1haWwgYWRkcmVzcyB0aGF0IHJlcHJlc2VudHMgYSBzZXJ2aWNlICAgIGFjY291bnQuIEZvcgogICAqIGV4YW1wbGUsIGBteS1vdGhlci1hcHBAYXBwc3BvdC5nc2VydmljZWFjY291bnQuY29tYC4KICAgKgogICAqICogYGdyb3VwOntlbWFpbGlkfWA6IEFuIGVtYWlsIGFkZHJlc3MgdGhhdCByZXByZXNlbnRzIGEgR29vZ2xlIGdyb3VwLiAgICBGb3IgZXhhbXBsZSwKICAgKiBgYWRtaW5zQGV4YW1wbGUuY29tYC4KICAgKgogICAqICogYGRlbGV0ZWQ6dXNlcjp7ZW1haWxpZH0/dWlkPXt1bmlxdWVpZH1gOiBBbiBlbWFpbCBhZGRyZXNzIChwbHVzIHVuaXF1ZSAgICBpZGVudGlmaWVyKQogICAqIHJlcHJlc2VudGluZyBhIHVzZXIgdGhhdCBoYXMgYmVlbiByZWNlbnRseSBkZWxldGVkLiBGb3IgICAgZXhhbXBsZSwKICAgKiBgYWxpY2VAZXhhbXBsZS5jb20/dWlkPTEyMzQ1Njc4OTAxMjM0NTY3ODkwMWAuIElmIHRoZSB1c2VyIGlzICAgIHJlY292ZXJlZCwgdGhpcyB2YWx1ZSByZXZlcnRzCiAgICogdG8gYHVzZXI6e2VtYWlsaWR9YCBhbmQgdGhlIHJlY292ZXJlZCB1c2VyICAgIHJldGFpbnMgdGhlIHJvbGUgaW4gdGhlIGJpbmRpbmcuCiAgICoKICAgKiAqIGBkZWxldGVkOnNlcnZpY2VBY2NvdW50OntlbWFpbGlkfT91aWQ9e3VuaXF1ZWlkfWA6IEFuIGVtYWlsIGFkZHJlc3MgKHBsdXMgICAgdW5pcXVlCiAgICogaWRlbnRpZmllcikgcmVwcmVzZW50aW5nIGEgc2VydmljZSBhY2NvdW50IHRoYXQgaGFzIGJlZW4gcmVjZW50bHkgICAgZGVsZXRlZC4gRm9yIGV4YW1wbGUsCiAgICogYG15LW90aGVyLWFwcEBhcHBzcG90LmdzZXJ2aWNlYWNjb3VudC5jb20/dWlkPTEyMzQ1Njc4OTAxMjM0NTY3ODkwMWAuICAgIElmIHRoZSBzZXJ2aWNlIGFjY291bnQKICAgKiBpcyB1bmRlbGV0ZWQsIHRoaXMgdmFsdWUgcmV2ZXJ0cyB0byAgICBgc2VydmljZUFjY291bnQ6e2VtYWlsaWR9YCBhbmQgdGhlIHVuZGVsZXRlZCBzZXJ2aWNlCiAgICogYWNjb3VudCByZXRhaW5zIHRoZSAgICByb2xlIGluIHRoZSBiaW5kaW5nLgogICAqCiAgICogKiBgZGVsZXRlZDpncm91cDp7ZW1haWxpZH0/dWlkPXt1bmlxdWVpZH1gOiBBbiBlbWFpbCBhZGRyZXNzIChwbHVzIHVuaXF1ZSAgICBpZGVudGlmaWVyKQogICAqIHJlcHJlc2VudGluZyBhIEdvb2dsZSBncm91cCB0aGF0IGhhcyBiZWVuIHJlY2VudGx5ICAgIGRlbGV0ZWQuIEZvciBleGFtcGxlLAogICAqIGBhZG1pbnNAZXhhbXBsZS5jb20/dWlkPTEyMzQ1Njc4OTAxMjM0NTY3ODkwMWAuIElmICAgIHRoZSBncm91cCBpcyByZWNvdmVyZWQsIHRoaXMgdmFsdWUKICAgKiByZXZlcnRzIHRvIGBncm91cDp7ZW1haWxpZH1gIGFuZCB0aGUgICAgcmVjb3ZlcmVkIGdyb3VwIHJldGFpbnMgdGhlIHJvbGUgaW4gdGhlIGJpbmRpbmcuCiAgICoKICAgKiAqIGBkb21haW46e2RvbWFpbn1gOiBUaGUgRyBTdWl0ZSBkb21haW4gKHByaW1hcnkpIHRoYXQgcmVwcmVzZW50cyBhbGwgdGhlICAgIHVzZXJzIG9mIHRoYXQKICAgKiBkb21haW4uIEZvciBleGFtcGxlLCBgZ29vZ2xlLmNvbWAgb3IgYGV4YW1wbGUuY29tYC4KICAgKiBAcGFyYW0gbWVtYmVycyBtZW1iZXJzIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBCaW5kaW5nIHNldE1lbWJlcnMoamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLlN0cmluZz4gbWVtYmVycykgewogICAgdGhpcy5tZW1iZXJzID0gbWVtYmVyczsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgLyoqCiAgICogUm9sZSB0aGF0IGlzIGFzc2lnbmVkIHRvIGBtZW1iZXJzYC4gRm9yIGV4YW1wbGUsIGByb2xlcy92aWV3ZXJgLCBgcm9sZXMvZWRpdG9yYCwgb3IKICAgKiBgcm9sZXMvb3duZXJgLgogICAqIEByZXR1cm4gdmFsdWUgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0Um9sZSgpIHsKICAgIHJldHVybiByb2xlOwogIH0KCiAgLyoqCiAgICogUm9sZSB0aGF0IGlzIGFzc2lnbmVkIHRvIGBtZW1iZXJzYC4gRm9yIGV4YW1wbGUsIGByb2xlcy92aWV3ZXJgLCBgcm9sZXMvZWRpdG9yYCwgb3IKICAgKiBgcm9sZXMvb3duZXJgLgogICAqIEBwYXJhbSByb2xlIHJvbGUgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIEJpbmRpbmcgc2V0Um9sZShqYXZhLmxhbmcuU3RyaW5nIHJvbGUpIHsKICAgIHRoaXMucm9sZSA9IHJvbGU7CiAgICByZXR1cm4gdGhpczsKICB9CgogIEBPdmVycmlkZQogIHB1YmxpYyBCaW5kaW5nIHNldChTdHJpbmcgZmllbGROYW1lLCBPYmplY3QgdmFsdWUpIHsKICAgIHJldHVybiAoQmluZGluZykgc3VwZXIuc2V0KGZpZWxkTmFtZSwgdmFsdWUpOwogIH0KCiAgQE92ZXJyaWRlCiAgcHVibGljIEJpbmRpbmcgY2xvbmUoKSB7CiAgICByZXR1cm4gKEJpbmRpbmcpIHN1cGVyLmNsb25lKCk7CiAgfQoKfQpQSwMEFAAAAAAAAAAhAGR2ZBZDBwAAQwcAAEkAAABjb20vZ29vZ2xlL2FwaS9zZXJ2aWNlcy9jbG91ZHJlc291cmNlbWFuYWdlci9tb2RlbC9Cb29sZWFuQ29uc3RyYWludC5qYXZhLyoKICogQ29weXJpZ2h0IDIwMTAgR29vZ2xlIEluYy4KICoKICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0CiAqIGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4gWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlCiAqIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcwogKiBvciBpbXBsaWVkLiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zIHVuZGVyCiAqIHRoZSBMaWNlbnNlLgogKi8KLyoKICogVGhpcyBjb2RlIHdhcyBnZW5lcmF0ZWQgYnkgaHR0cHM6Ly9naXRodWIuY29tL2dvb2dsZS9hcGlzLWNsaWVudC1nZW5lcmF0b3IvCiAqIChidWlsZDogMjAxOC0xMC0wOCAxNzo0NTozOSBVVEMpCiAqIG9uIDIwMjAtMDMtMTkgYXQgMDI6Mzg6MzAgVVRDIAogKiBNb2RpZnkgYXQgeW91ciBvd24gcmlzay4KICovCgpwYWNrYWdlIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmNsb3VkcmVzb3VyY2VtYW5hZ2VyLm1vZGVsOwoKLyoqCiAqIEEgYENvbnN0cmFpbnRgIHRoYXQgaXMgZWl0aGVyIGVuZm9yY2VkIG9yIG5vdC4KICoKICogRm9yIGV4YW1wbGUgYSBjb25zdHJhaW50IGBjb25zdHJhaW50cy9jb21wdXRlLmRpc2FibGVTZXJpYWxQb3J0QWNjZXNzYC4gSWYgaXQgaXMgZW5mb3JjZWQgb24gYSBWTQogKiBpbnN0YW5jZSwgc2VyaWFsIHBvcnQgY29ubmVjdGlvbnMgd2lsbCBub3QgYmUgb3BlbmVkIHRvIHRoYXQgaW5zdGFuY2UuCiAqCiAqIDxwPiBUaGlzIGlzIHRoZSBKYXZhIGRhdGEgbW9kZWwgY2xhc3MgdGhhdCBzcGVjaWZpZXMgaG93IHRvIHBhcnNlL3NlcmlhbGl6ZSBpbnRvIHRoZSBKU09OIHRoYXQgaXMKICogdHJhbnNtaXR0ZWQgb3ZlciBIVFRQIHdoZW4gd29ya2luZyB3aXRoIHRoZSBDbG91ZCBSZXNvdXJjZSBNYW5hZ2VyIEFQSS4gRm9yIGEgZGV0YWlsZWQKICogZXhwbGFuYXRpb24gc2VlOgogKiA8YSBocmVmPSJodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9hcGktY2xpZW50LWxpYnJhcnkvamF2YS9nb29nbGUtaHR0cC1qYXZhLWNsaWVudC9qc29uIj5odHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9hcGktY2xpZW50LWxpYnJhcnkvamF2YS9nb29nbGUtaHR0cC1qYXZhLWNsaWVudC9qc29uPC9hPgogKiA8L3A+CiAqCiAqIEBhdXRob3IgR29vZ2xlLCBJbmMuCiAqLwpAU3VwcHJlc3NXYXJuaW5ncygiamF2YWRvYyIpCnB1YmxpYyBmaW5hbCBjbGFzcyBCb29sZWFuQ29uc3RyYWludCBleHRlbmRzIGNvbS5nb29nbGUuYXBpLmNsaWVudC5qc29uLkdlbmVyaWNKc29uIHsKCiAgQE92ZXJyaWRlCiAgcHVibGljIEJvb2xlYW5Db25zdHJhaW50IHNldChTdHJpbmcgZmllbGROYW1lLCBPYmplY3QgdmFsdWUpIHsKICAgIHJldHVybiAoQm9vbGVhbkNvbnN0cmFpbnQpIHN1cGVyLnNldChmaWVsZE5hbWUsIHZhbHVlKTsKICB9CgogIEBPdmVycmlkZQogIHB1YmxpYyBCb29sZWFuQ29uc3RyYWludCBjbG9uZSgpIHsKICAgIHJldHVybiAoQm9vbGVhbkNvbnN0cmFpbnQpIHN1cGVyLmNsb25lKCk7CiAgfQoKfQpQSwMEFAAAAAAAAAAhAFqci6rlHgAA5R4AAEUAAABjb20vZ29vZ2xlL2FwaS9zZXJ2aWNlcy9jbG91ZHJlc291cmNlbWFuYWdlci9tb2RlbC9Cb29sZWFuUG9saWN5LmphdmEvKgogKiBDb3B5cmlnaHQgMjAxMCBHb29nbGUgSW5jLgogKgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQKICogaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UKICogaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzCiAqIG9yIGltcGxpZWQuIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMgdW5kZXIKICogdGhlIExpY2Vuc2UuCiAqLwovKgogKiBUaGlzIGNvZGUgd2FzIGdlbmVyYXRlZCBieSBodHRwczovL2dpdGh1Yi5jb20vZ29vZ2xlL2FwaXMtY2xpZW50LWdlbmVyYXRvci8KICogKGJ1aWxkOiAyMDE4LTEwLTA4IDE3OjQ1OjM5IFVUQykKICogb24gMjAyMC0wMy0xOSBhdCAwMjozODozMCBVVEMgCiAqIE1vZGlmeSBhdCB5b3VyIG93biByaXNrLgogKi8KCnBhY2thZ2UgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuY2xvdWRyZXNvdXJjZW1hbmFnZXIubW9kZWw7CgovKioKICogVXNlZCBpbiBgcG9saWN5X3R5cGVgIHRvIHNwZWNpZnkgaG93IGBib29sZWFuX3BvbGljeWAgd2lsbCBiZWhhdmUgYXQgdGhpcyByZXNvdXJjZS4KICoKICogPHA+IFRoaXMgaXMgdGhlIEphdmEgZGF0YSBtb2RlbCBjbGFzcyB0aGF0IHNwZWNpZmllcyBob3cgdG8gcGFyc2Uvc2VyaWFsaXplIGludG8gdGhlIEpTT04gdGhhdCBpcwogKiB0cmFuc21pdHRlZCBvdmVyIEhUVFAgd2hlbiB3b3JraW5nIHdpdGggdGhlIENsb3VkIFJlc291cmNlIE1hbmFnZXIgQVBJLiBGb3IgYSBkZXRhaWxlZAogKiBleHBsYW5hdGlvbiBzZWU6CiAqIDxhIGhyZWY9Imh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL2FwaS1jbGllbnQtbGlicmFyeS9qYXZhL2dvb2dsZS1odHRwLWphdmEtY2xpZW50L2pzb24iPmh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL2FwaS1jbGllbnQtbGlicmFyeS9qYXZhL2dvb2dsZS1odHRwLWphdmEtY2xpZW50L2pzb248L2E+CiAqIDwvcD4KICoKICogQGF1dGhvciBHb29nbGUsIEluYy4KICovCkBTdXBwcmVzc1dhcm5pbmdzKCJqYXZhZG9jIikKcHVibGljIGZpbmFsIGNsYXNzIEJvb2xlYW5Qb2xpY3kgZXh0ZW5kcyBjb20uZ29vZ2xlLmFwaS5jbGllbnQuanNvbi5HZW5lcmljSnNvbiB7CgogIC8qKgogICAqIElmIGB0cnVlYCwgdGhlbiB0aGUgYFBvbGljeWAgaXMgZW5mb3JjZWQuIElmIGBmYWxzZWAsIHRoZW4gYW55IGNvbmZpZ3VyYXRpb24gaXMgYWNjZXB0YWJsZS4KICAgKgogICAqIFN1cHBvc2UgeW91IGhhdmUgYSBgQ29uc3RyYWludGAgYGNvbnN0cmFpbnRzL2NvbXB1dGUuZGlzYWJsZVNlcmlhbFBvcnRBY2Nlc3NgIHdpdGgKICAgKiBgY29uc3RyYWludF9kZWZhdWx0YCBzZXQgdG8gYEFMTE9XYC4gQSBgUG9saWN5YCBmb3IgdGhhdCBgQ29uc3RyYWludGAgZXhoaWJpdHMgdGhlIGZvbGxvd2luZwogICAqIGJlaGF2aW9yOiAgIC0gSWYgdGhlIGBQb2xpY3lgIGF0IHRoaXMgcmVzb3VyY2UgaGFzIGVuZm9yY2VkIHNldCB0byBgZmFsc2VgLCBzZXJpYWwgICAgIHBvcnQKICAgKiBjb25uZWN0aW9uIGF0dGVtcHRzIHdpbGwgYmUgYWxsb3dlZC4gICAtIElmIHRoZSBgUG9saWN5YCBhdCB0aGlzIHJlc291cmNlIGhhcyBlbmZvcmNlZCBzZXQgdG8KICAgKiBgdHJ1ZWAsIHNlcmlhbCAgICAgcG9ydCBjb25uZWN0aW9uIGF0dGVtcHRzIHdpbGwgYmUgcmVmdXNlZC4gICAtIElmIHRoZSBgUG9saWN5YCBhdCB0aGlzCiAgICogcmVzb3VyY2UgaXMgYFJlc3RvcmVEZWZhdWx0YCwgc2VyaWFsIHBvcnQgICAgIGNvbm5lY3Rpb24gYXR0ZW1wdHMgd2lsbCBiZSBhbGxvd2VkLiAgIC0gSWYgbm8KICAgKiBgUG9saWN5YCBpcyBzZXQgYXQgdGhpcyByZXNvdXJjZSBvciBhbnl3aGVyZSBoaWdoZXIgaW4gdGhlICAgICByZXNvdXJjZSBoaWVyYXJjaHksIHNlcmlhbCBwb3J0CiAgICogY29ubmVjdGlvbiBhdHRlbXB0cyB3aWxsIGJlIGFsbG93ZWQuICAgLSBJZiBubyBgUG9saWN5YCBpcyBzZXQgYXQgdGhpcyByZXNvdXJjZSwgYnV0IG9uZSBleGlzdHMKICAgKiBoaWdoZXIgaW4gdGhlICAgICByZXNvdXJjZSBoaWVyYXJjaHksIHRoZSBiZWhhdmlvciBpcyBhcyBpZiB0aGVgUG9saWN5YCB3ZXJlIHNldCBhdCAgICAgdGhpcwogICAqIHJlc291cmNlLgogICAqCiAgICogVGhlIGZvbGxvd2luZyBleGFtcGxlcyBkZW1vbnN0cmF0ZSB0aGUgZGlmZmVyZW50IHBvc3NpYmxlIGxheWVyaW5nczoKICAgKgogICAqIEV4YW1wbGUgMSAobmVhcmVzdCBgQ29uc3RyYWludGAgd2lucyk6ICAgYG9yZ2FuaXphdGlvbnMvZm9vYCBoYXMgYSBgUG9saWN5YCB3aXRoOgogICAqIHtlbmZvcmNlZDogZmFsc2V9ICAgYHByb2plY3RzL2JhcmAgaGFzIG5vIGBQb2xpY3lgIHNldC4gVGhlIGNvbnN0cmFpbnQgYXQgYHByb2plY3RzL2JhcmAgYW5kCiAgICogYG9yZ2FuaXphdGlvbnMvZm9vYCB3aWxsIG5vdCBiZSBlbmZvcmNlZC4KICAgKgogICAqIEV4YW1wbGUgMiAoZW5mb3JjZW1lbnQgZ2V0cyByZXBsYWNlZCk6ICAgYG9yZ2FuaXphdGlvbnMvZm9vYCBoYXMgYSBgUG9saWN5YCB3aXRoOgogICAqIHtlbmZvcmNlZDogZmFsc2V9ICAgYHByb2plY3RzL2JhcmAgaGFzIGEgYFBvbGljeWAgd2l0aDogICAgIHtlbmZvcmNlZDogdHJ1ZX0gVGhlIGNvbnN0cmFpbnQgYXQKICAgKiBgb3JnYW5pemF0aW9ucy9mb29gIGlzIG5vdCBlbmZvcmNlZC4gVGhlIGNvbnN0cmFpbnQgYXQgYHByb2plY3RzL2JhcmAgaXMgZW5mb3JjZWQuCiAgICoKICAgKiBFeGFtcGxlIDMgKFJlc3RvcmVEZWZhdWx0KTogICBgb3JnYW5pemF0aW9ucy9mb29gIGhhcyBhIGBQb2xpY3lgIHdpdGg6ICAgICB7ZW5mb3JjZWQ6IHRydWV9CiAgICogYHByb2plY3RzL2JhcmAgaGFzIGEgYFBvbGljeWAgd2l0aDogICAgIHtSZXN0b3JlRGVmYXVsdDoge319IFRoZSBjb25zdHJhaW50IGF0CiAgICogYG9yZ2FuaXphdGlvbnMvZm9vYCBpcyBlbmZvcmNlZC4gVGhlIGNvbnN0cmFpbnQgYXQgYHByb2plY3RzL2JhcmAgaXMgbm90IGVuZm9yY2VkLCBiZWNhdXNlCiAgICogYGNvbnN0cmFpbnRfZGVmYXVsdGAgZm9yIHRoZSBgQ29uc3RyYWludGAgaXMgYEFMTE9XYC4KICAgKiBUaGUgdmFsdWUgbWF5IGJlIHtAY29kZSBudWxsfS4KICAgKi8KICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgcHJpdmF0ZSBqYXZhLmxhbmcuQm9vbGVhbiBlbmZvcmNlZDsKCiAgLyoqCiAgICogSWYgYHRydWVgLCB0aGVuIHRoZSBgUG9saWN5YCBpcyBlbmZvcmNlZC4gSWYgYGZhbHNlYCwgdGhlbiBhbnkgY29uZmlndXJhdGlvbiBpcyBhY2NlcHRhYmxlLgogICAqCiAgICogU3VwcG9zZSB5b3UgaGF2ZSBhIGBDb25zdHJhaW50YCBgY29uc3RyYWludHMvY29tcHV0ZS5kaXNhYmxlU2VyaWFsUG9ydEFjY2Vzc2Agd2l0aAogICAqIGBjb25zdHJhaW50X2RlZmF1bHRgIHNldCB0byBgQUxMT1dgLiBBIGBQb2xpY3lgIGZvciB0aGF0IGBDb25zdHJhaW50YCBleGhpYml0cyB0aGUgZm9sbG93aW5nCiAgICogYmVoYXZpb3I6ICAgLSBJZiB0aGUgYFBvbGljeWAgYXQgdGhpcyByZXNvdXJjZSBoYXMgZW5mb3JjZWQgc2V0IHRvIGBmYWxzZWAsIHNlcmlhbCAgICAgcG9ydAogICAqIGNvbm5lY3Rpb24gYXR0ZW1wdHMgd2lsbCBiZSBhbGxvd2VkLiAgIC0gSWYgdGhlIGBQb2xpY3lgIGF0IHRoaXMgcmVzb3VyY2UgaGFzIGVuZm9yY2VkIHNldCB0bwogICAqIGB0cnVlYCwgc2VyaWFsICAgICBwb3J0IGNvbm5lY3Rpb24gYXR0ZW1wdHMgd2lsbCBiZSByZWZ1c2VkLiAgIC0gSWYgdGhlIGBQb2xpY3lgIGF0IHRoaXMKICAgKiByZXNvdXJjZSBpcyBgUmVzdG9yZURlZmF1bHRgLCBzZXJpYWwgcG9ydCAgICAgY29ubmVjdGlvbiBhdHRlbXB0cyB3aWxsIGJlIGFsbG93ZWQuICAgLSBJZiBubwogICAqIGBQb2xpY3lgIGlzIHNldCBhdCB0aGlzIHJlc291cmNlIG9yIGFueXdoZXJlIGhpZ2hlciBpbiB0aGUgICAgIHJlc291cmNlIGhpZXJhcmNoeSwgc2VyaWFsIHBvcnQKICAgKiBjb25uZWN0aW9uIGF0dGVtcHRzIHdpbGwgYmUgYWxsb3dlZC4gICAtIElmIG5vIGBQb2xpY3lgIGlzIHNldCBhdCB0aGlzIHJlc291cmNlLCBidXQgb25lIGV4aXN0cwogICAqIGhpZ2hlciBpbiB0aGUgICAgIHJlc291cmNlIGhpZXJhcmNoeSwgdGhlIGJlaGF2aW9yIGlzIGFzIGlmIHRoZWBQb2xpY3lgIHdlcmUgc2V0IGF0ICAgICB0aGlzCiAgICogcmVzb3VyY2UuCiAgICoKICAgKiBUaGUgZm9sbG93aW5nIGV4YW1wbGVzIGRlbW9uc3RyYXRlIHRoZSBkaWZmZXJlbnQgcG9zc2libGUgbGF5ZXJpbmdzOgogICAqCiAgICogRXhhbXBsZSAxIChuZWFyZXN0IGBDb25zdHJhaW50YCB3aW5zKTogICBgb3JnYW5pemF0aW9ucy9mb29gIGhhcyBhIGBQb2xpY3lgIHdpdGg6CiAgICoge2VuZm9yY2VkOiBmYWxzZX0gICBgcHJvamVjdHMvYmFyYCBoYXMgbm8gYFBvbGljeWAgc2V0LiBUaGUgY29uc3RyYWludCBhdCBgcHJvamVjdHMvYmFyYCBhbmQKICAgKiBgb3JnYW5pemF0aW9ucy9mb29gIHdpbGwgbm90IGJlIGVuZm9yY2VkLgogICAqCiAgICogRXhhbXBsZSAyIChlbmZvcmNlbWVudCBnZXRzIHJlcGxhY2VkKTogICBgb3JnYW5pemF0aW9ucy9mb29gIGhhcyBhIGBQb2xpY3lgIHdpdGg6CiAgICoge2VuZm9yY2VkOiBmYWxzZX0gICBgcHJvamVjdHMvYmFyYCBoYXMgYSBgUG9saWN5YCB3aXRoOiAgICAge2VuZm9yY2VkOiB0cnVlfSBUaGUgY29uc3RyYWludCBhdAogICAqIGBvcmdhbml6YXRpb25zL2Zvb2AgaXMgbm90IGVuZm9yY2VkLiBUaGUgY29uc3RyYWludCBhdCBgcHJvamVjdHMvYmFyYCBpcyBlbmZvcmNlZC4KICAgKgogICAqIEV4YW1wbGUgMyAoUmVzdG9yZURlZmF1bHQpOiAgIGBvcmdhbml6YXRpb25zL2Zvb2AgaGFzIGEgYFBvbGljeWAgd2l0aDogICAgIHtlbmZvcmNlZDogdHJ1ZX0KICAgKiBgcHJvamVjdHMvYmFyYCBoYXMgYSBgUG9saWN5YCB3aXRoOiAgICAge1Jlc3RvcmVEZWZhdWx0OiB7fX0gVGhlIGNvbnN0cmFpbnQgYXQKICAgKiBgb3JnYW5pemF0aW9ucy9mb29gIGlzIGVuZm9yY2VkLiBUaGUgY29uc3RyYWludCBhdCBgcHJvamVjdHMvYmFyYCBpcyBub3QgZW5mb3JjZWQsIGJlY2F1c2UKICAgKiBgY29uc3RyYWludF9kZWZhdWx0YCBmb3IgdGhlIGBDb25zdHJhaW50YCBpcyBgQUxMT1dgLgogICAqIEByZXR1cm4gdmFsdWUgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIGphdmEubGFuZy5Cb29sZWFuIGdldEVuZm9yY2VkKCkgewogICAgcmV0dXJuIGVuZm9yY2VkOwogIH0KCiAgLyoqCiAgICogSWYgYHRydWVgLCB0aGVuIHRoZSBgUG9saWN5YCBpcyBlbmZvcmNlZC4gSWYgYGZhbHNlYCwgdGhlbiBhbnkgY29uZmlndXJhdGlvbiBpcyBhY2NlcHRhYmxlLgogICAqCiAgICogU3VwcG9zZSB5b3UgaGF2ZSBhIGBDb25zdHJhaW50YCBgY29uc3RyYWludHMvY29tcHV0ZS5kaXNhYmxlU2VyaWFsUG9ydEFjY2Vzc2Agd2l0aAogICAqIGBjb25zdHJhaW50X2RlZmF1bHRgIHNldCB0byBgQUxMT1dgLiBBIGBQb2xpY3lgIGZvciB0aGF0IGBDb25zdHJhaW50YCBleGhpYml0cyB0aGUgZm9sbG93aW5nCiAgICogYmVoYXZpb3I6ICAgLSBJZiB0aGUgYFBvbGljeWAgYXQgdGhpcyByZXNvdXJjZSBoYXMgZW5mb3JjZWQgc2V0IHRvIGBmYWxzZWAsIHNlcmlhbCAgICAgcG9ydAogICAqIGNvbm5lY3Rpb24gYXR0ZW1wdHMgd2lsbCBiZSBhbGxvd2VkLiAgIC0gSWYgdGhlIGBQb2xpY3lgIGF0IHRoaXMgcmVzb3VyY2UgaGFzIGVuZm9yY2VkIHNldCB0bwogICAqIGB0cnVlYCwgc2VyaWFsICAgICBwb3J0IGNvbm5lY3Rpb24gYXR0ZW1wdHMgd2lsbCBiZSByZWZ1c2VkLiAgIC0gSWYgdGhlIGBQb2xpY3lgIGF0IHRoaXMKICAgKiByZXNvdXJjZSBpcyBgUmVzdG9yZURlZmF1bHRgLCBzZXJpYWwgcG9ydCAgICAgY29ubmVjdGlvbiBhdHRlbXB0cyB3aWxsIGJlIGFsbG93ZWQuICAgLSBJZiBubwogICAqIGBQb2xpY3lgIGlzIHNldCBhdCB0aGlzIHJlc291cmNlIG9yIGFueXdoZXJlIGhpZ2hlciBpbiB0aGUgICAgIHJlc291cmNlIGhpZXJhcmNoeSwgc2VyaWFsIHBvcnQKICAgKiBjb25uZWN0aW9uIGF0dGVtcHRzIHdpbGwgYmUgYWxsb3dlZC4gICAtIElmIG5vIGBQb2xpY3lgIGlzIHNldCBhdCB0aGlzIHJlc291cmNlLCBidXQgb25lIGV4aXN0cwogICAqIGhpZ2hlciBpbiB0aGUgICAgIHJlc291cmNlIGhpZXJhcmNoeSwgdGhlIGJlaGF2aW9yIGlzIGFzIGlmIHRoZWBQb2xpY3lgIHdlcmUgc2V0IGF0ICAgICB0aGlzCiAgICogcmVzb3VyY2UuCiAgICoKICAgKiBUaGUgZm9sbG93aW5nIGV4YW1wbGVzIGRlbW9uc3RyYXRlIHRoZSBkaWZmZXJlbnQgcG9zc2libGUgbGF5ZXJpbmdzOgogICAqCiAgICogRXhhbXBsZSAxIChuZWFyZXN0IGBDb25zdHJhaW50YCB3aW5zKTogICBgb3JnYW5pemF0aW9ucy9mb29gIGhhcyBhIGBQb2xpY3lgIHdpdGg6CiAgICoge2VuZm9yY2VkOiBmYWxzZX0gICBgcHJvamVjdHMvYmFyYCBoYXMgbm8gYFBvbGljeWAgc2V0LiBUaGUgY29uc3RyYWludCBhdCBgcHJvamVjdHMvYmFyYCBhbmQKICAgKiBgb3JnYW5pemF0aW9ucy9mb29gIHdpbGwgbm90IGJlIGVuZm9yY2VkLgogICAqCiAgICogRXhhbXBsZSAyIChlbmZvcmNlbWVudCBnZXRzIHJlcGxhY2VkKTogICBgb3JnYW5pemF0aW9ucy9mb29gIGhhcyBhIGBQb2xpY3lgIHdpdGg6CiAgICoge2VuZm9yY2VkOiBmYWxzZX0gICBgcHJvamVjdHMvYmFyYCBoYXMgYSBgUG9saWN5YCB3aXRoOiAgICAge2VuZm9yY2VkOiB0cnVlfSBUaGUgY29uc3RyYWludCBhdAogICAqIGBvcmdhbml6YXRpb25zL2Zvb2AgaXMgbm90IGVuZm9yY2VkLiBUaGUgY29uc3RyYWludCBhdCBgcHJvamVjdHMvYmFyYCBpcyBlbmZvcmNlZC4KICAgKgogICAqIEV4YW1wbGUgMyAoUmVzdG9yZURlZmF1bHQpOiAgIGBvcmdhbml6YXRpb25zL2Zvb2AgaGFzIGEgYFBvbGljeWAgd2l0aDogICAgIHtlbmZvcmNlZDogdHJ1ZX0KICAgKiBgcHJvamVjdHMvYmFyYCBoYXMgYSBgUG9saWN5YCB3aXRoOiAgICAge1Jlc3RvcmVEZWZhdWx0OiB7fX0gVGhlIGNvbnN0cmFpbnQgYXQKICAgKiBgb3JnYW5pemF0aW9ucy9mb29gIGlzIGVuZm9yY2VkLiBUaGUgY29uc3RyYWludCBhdCBgcHJvamVjdHMvYmFyYCBpcyBub3QgZW5mb3JjZWQsIGJlY2F1c2UKICAgKiBgY29uc3RyYWludF9kZWZhdWx0YCBmb3IgdGhlIGBDb25zdHJhaW50YCBpcyBgQUxMT1dgLgogICAqIEBwYXJhbSBlbmZvcmNlZCBlbmZvcmNlZCBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgQm9vbGVhblBvbGljeSBzZXRFbmZvcmNlZChqYXZhLmxhbmcuQm9vbGVhbiBlbmZvcmNlZCkgewogICAgdGhpcy5lbmZvcmNlZCA9IGVuZm9yY2VkOwogICAgcmV0dXJuIHRoaXM7CiAgfQoKICBAT3ZlcnJpZGUKICBwdWJsaWMgQm9vbGVhblBvbGljeSBzZXQoU3RyaW5nIGZpZWxkTmFtZSwgT2JqZWN0IHZhbHVlKSB7CiAgICByZXR1cm4gKEJvb2xlYW5Qb2xpY3kpIHN1cGVyLnNldChmaWVsZE5hbWUsIHZhbHVlKTsKICB9CgogIEBPdmVycmlkZQogIHB1YmxpYyBCb29sZWFuUG9saWN5IGNsb25lKCkgewogICAgcmV0dXJuIChCb29sZWFuUG9saWN5KSBzdXBlci5jbG9uZSgpOwogIH0KCn0KUEsDBBQAAAAAAAAAIQAIYyLoRQ8AAEUPAABNAAAAY29tL2dvb2dsZS9hcGkvc2VydmljZXMvY2xvdWRyZXNvdXJjZW1hbmFnZXIvbW9kZWwvQ2xlYXJPcmdQb2xpY3lSZXF1ZXN0LmphdmEvKgogKiBDb3B5cmlnaHQgMjAxMCBHb29nbGUgSW5jLgogKgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQKICogaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UKICogaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzCiAqIG9yIGltcGxpZWQuIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMgdW5kZXIKICogdGhlIExpY2Vuc2UuCiAqLwovKgogKiBUaGlzIGNvZGUgd2FzIGdlbmVyYXRlZCBieSBodHRwczovL2dpdGh1Yi5jb20vZ29vZ2xlL2FwaXMtY2xpZW50LWdlbmVyYXRvci8KICogKGJ1aWxkOiAyMDE4LTEwLTA4IDE3OjQ1OjM5IFVUQykKICogb24gMjAyMC0wMy0xOSBhdCAwMjozODozMCBVVEMgCiAqIE1vZGlmeSBhdCB5b3VyIG93biByaXNrLgogKi8KCnBhY2thZ2UgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuY2xvdWRyZXNvdXJjZW1hbmFnZXIubW9kZWw7CgovKioKICogVGhlIHJlcXVlc3Qgc2VudCB0byB0aGUgQ2xlYXJPcmdQb2xpY3kgbWV0aG9kLgogKgogKiA8cD4gVGhpcyBpcyB0aGUgSmF2YSBkYXRhIG1vZGVsIGNsYXNzIHRoYXQgc3BlY2lmaWVzIGhvdyB0byBwYXJzZS9zZXJpYWxpemUgaW50byB0aGUgSlNPTiB0aGF0IGlzCiAqIHRyYW5zbWl0dGVkIG92ZXIgSFRUUCB3aGVuIHdvcmtpbmcgd2l0aCB0aGUgQ2xvdWQgUmVzb3VyY2UgTWFuYWdlciBBUEkuIEZvciBhIGRldGFpbGVkCiAqIGV4cGxhbmF0aW9uIHNlZToKICogPGEgaHJlZj0iaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vYXBpLWNsaWVudC1saWJyYXJ5L2phdmEvZ29vZ2xlLWh0dHAtamF2YS1jbGllbnQvanNvbiI+aHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vYXBpLWNsaWVudC1saWJyYXJ5L2phdmEvZ29vZ2xlLWh0dHAtamF2YS1jbGllbnQvanNvbjwvYT4KICogPC9wPgogKgogKiBAYXV0aG9yIEdvb2dsZSwgSW5jLgogKi8KQFN1cHByZXNzV2FybmluZ3MoImphdmFkb2MiKQpwdWJsaWMgZmluYWwgY2xhc3MgQ2xlYXJPcmdQb2xpY3lSZXF1ZXN0IGV4dGVuZHMgY29tLmdvb2dsZS5hcGkuY2xpZW50Lmpzb24uR2VuZXJpY0pzb24gewoKICAvKioKICAgKiBOYW1lIG9mIHRoZSBgQ29uc3RyYWludGAgb2YgdGhlIGBQb2xpY3lgIHRvIGNsZWFyLgogICAqIFRoZSB2YWx1ZSBtYXkgYmUge0Bjb2RlIG51bGx9LgogICAqLwogIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICBwcml2YXRlIGphdmEubGFuZy5TdHJpbmcgY29uc3RyYWludDsKCiAgLyoqCiAgICogVGhlIGN1cnJlbnQgdmVyc2lvbiwgZm9yIGNvbmN1cnJlbmN5IGNvbnRyb2wuIE5vdCBzZW5kaW5nIGFuIGBldGFnYCB3aWxsIGNhdXNlIHRoZSBgUG9saWN5YCB0bwogICAqIGJlIGNsZWFyZWQgYmxpbmRseS4KICAgKiBUaGUgdmFsdWUgbWF5IGJlIHtAY29kZSBudWxsfS4KICAgKi8KICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgcHJpdmF0ZSBqYXZhLmxhbmcuU3RyaW5nIGV0YWc7CgogIC8qKgogICAqIE5hbWUgb2YgdGhlIGBDb25zdHJhaW50YCBvZiB0aGUgYFBvbGljeWAgdG8gY2xlYXIuCiAgICogQHJldHVybiB2YWx1ZSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRDb25zdHJhaW50KCkgewogICAgcmV0dXJuIGNvbnN0cmFpbnQ7CiAgfQoKICAvKioKICAgKiBOYW1lIG9mIHRoZSBgQ29uc3RyYWludGAgb2YgdGhlIGBQb2xpY3lgIHRvIGNsZWFyLgogICAqIEBwYXJhbSBjb25zdHJhaW50IGNvbnN0cmFpbnQgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIENsZWFyT3JnUG9saWN5UmVxdWVzdCBzZXRDb25zdHJhaW50KGphdmEubGFuZy5TdHJpbmcgY29uc3RyYWludCkgewogICAgdGhpcy5jb25zdHJhaW50ID0gY29uc3RyYWludDsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgLyoqCiAgICogVGhlIGN1cnJlbnQgdmVyc2lvbiwgZm9yIGNvbmN1cnJlbmN5IGNvbnRyb2wuIE5vdCBzZW5kaW5nIGFuIGBldGFnYCB3aWxsIGNhdXNlIHRoZSBgUG9saWN5YCB0bwogICAqIGJlIGNsZWFyZWQgYmxpbmRseS4KICAgKiBAc2VlICNkZWNvZGVFdGFnKCkKICAgKiBAcmV0dXJuIHZhbHVlIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldEV0YWcoKSB7CiAgICByZXR1cm4gZXRhZzsKICB9CgogIC8qKgogICAqIFRoZSBjdXJyZW50IHZlcnNpb24sIGZvciBjb25jdXJyZW5jeSBjb250cm9sLiBOb3Qgc2VuZGluZyBhbiBgZXRhZ2Agd2lsbCBjYXVzZSB0aGUgYFBvbGljeWAgdG8KICAgKiBiZSBjbGVhcmVkIGJsaW5kbHkuCiAgICogQHNlZSAjZ2V0RXRhZygpCiAgICogQHJldHVybiBCYXNlNjQgZGVjb2RlZCB2YWx1ZSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKgogICAqIEBzaW5jZSAxLjE0CiAgICovCiAgcHVibGljIGJ5dGVbXSBkZWNvZGVFdGFnKCkgewogICAgcmV0dXJuIGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLkJhc2U2NC5kZWNvZGVCYXNlNjQoZXRhZyk7CiAgfQoKICAvKioKICAgKiBUaGUgY3VycmVudCB2ZXJzaW9uLCBmb3IgY29uY3VycmVuY3kgY29udHJvbC4gTm90IHNlbmRpbmcgYW4gYGV0YWdgIHdpbGwgY2F1c2UgdGhlIGBQb2xpY3lgIHRvCiAgICogYmUgY2xlYXJlZCBibGluZGx5LgogICAqIEBzZWUgI2VuY29kZUV0YWcoKQogICAqIEBwYXJhbSBldGFnIGV0YWcgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIENsZWFyT3JnUG9saWN5UmVxdWVzdCBzZXRFdGFnKGphdmEubGFuZy5TdHJpbmcgZXRhZykgewogICAgdGhpcy5ldGFnID0gZXRhZzsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgLyoqCiAgICogVGhlIGN1cnJlbnQgdmVyc2lvbiwgZm9yIGNvbmN1cnJlbmN5IGNvbnRyb2wuIE5vdCBzZW5kaW5nIGFuIGBldGFnYCB3aWxsIGNhdXNlIHRoZSBgUG9saWN5YCB0bwogICAqIGJlIGNsZWFyZWQgYmxpbmRseS4KICAgKiBAc2VlICNzZXRFdGFnKCkKICAgKgogICAqIDxwPgogICAqIFRoZSB2YWx1ZSBpcyBlbmNvZGVkIEJhc2U2NCBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUuCiAgICogPC9wPgogICAqCiAgICogQHNpbmNlIDEuMTQKICAgKi8KICBwdWJsaWMgQ2xlYXJPcmdQb2xpY3lSZXF1ZXN0IGVuY29kZUV0YWcoYnl0ZVtdIGV0YWcpIHsKICAgIHRoaXMuZXRhZyA9IGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLkJhc2U2NC5lbmNvZGVCYXNlNjRVUkxTYWZlU3RyaW5nKGV0YWcpOwogICAgcmV0dXJuIHRoaXM7CiAgfQoKICBAT3ZlcnJpZGUKICBwdWJsaWMgQ2xlYXJPcmdQb2xpY3lSZXF1ZXN0IHNldChTdHJpbmcgZmllbGROYW1lLCBPYmplY3QgdmFsdWUpIHsKICAgIHJldHVybiAoQ2xlYXJPcmdQb2xpY3lSZXF1ZXN0KSBzdXBlci5zZXQoZmllbGROYW1lLCB2YWx1ZSk7CiAgfQoKICBAT3ZlcnJpZGUKICBwdWJsaWMgQ2xlYXJPcmdQb2xpY3lSZXF1ZXN0IGNsb25lKCkgewogICAgcmV0dXJuIChDbGVhck9yZ1BvbGljeVJlcXVlc3QpIHN1cGVyLmNsb25lKCk7CiAgfQoKfQpQSwMEFAAAAAAAAAAhAN4UuyxeHAAAXhwAAEIAAABjb20vZ29vZ2xlL2FwaS9zZXJ2aWNlcy9jbG91ZHJlc291cmNlbWFuYWdlci9tb2RlbC9Db25zdHJhaW50LmphdmEvKgogKiBDb3B5cmlnaHQgMjAxMCBHb29nbGUgSW5jLgogKgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQKICogaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UKICogaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzCiAqIG9yIGltcGxpZWQuIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMgdW5kZXIKICogdGhlIExpY2Vuc2UuCiAqLwovKgogKiBUaGlzIGNvZGUgd2FzIGdlbmVyYXRlZCBieSBodHRwczovL2dpdGh1Yi5jb20vZ29vZ2xlL2FwaXMtY2xpZW50LWdlbmVyYXRvci8KICogKGJ1aWxkOiAyMDE4LTEwLTA4IDE3OjQ1OjM5IFVUQykKICogb24gMjAyMC0wMy0xOSBhdCAwMjozODozMCBVVEMgCiAqIE1vZGlmeSBhdCB5b3VyIG93biByaXNrLgogKi8KCnBhY2thZ2UgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuY2xvdWRyZXNvdXJjZW1hbmFnZXIubW9kZWw7CgovKioKICogQSBgQ29uc3RyYWludGAgZGVzY3JpYmVzIGEgd2F5IGluIHdoaWNoIGEgcmVzb3VyY2UncyBjb25maWd1cmF0aW9uIGNhbiBiZSByZXN0cmljdGVkLiBGb3IKICogZXhhbXBsZSwgaXQgY29udHJvbHMgd2hpY2ggY2xvdWQgc2VydmljZXMgY2FuIGJlIGFjdGl2YXRlZCBhY3Jvc3MgYW4gb3JnYW5pemF0aW9uLCBvciB3aGV0aGVyIGEKICogQ29tcHV0ZSBFbmdpbmUgaW5zdGFuY2UgY2FuIGhhdmUgc2VyaWFsIHBvcnQgY29ubmVjdGlvbnMgZXN0YWJsaXNoZWQuIGBDb25zdHJhaW50c2AgY2FuIGJlCiAqIGNvbmZpZ3VyZWQgYnkgdGhlIG9yZ2FuaXphdGlvbidzIHBvbGljeSBhZG1pbnN0cmF0b3IgdG8gZml0IHRoZSBuZWVkcyBvZiB0aGUgb3JnYW56YXRpb24gYnkKICogc2V0dGluZyBQb2xpY2llcyBmb3IgYENvbnN0cmFpbnRzYCBhdCBkaWZmZXJlbnQgbG9jYXRpb25zIGluIHRoZSBvcmdhbml6YXRpb24ncyByZXNvdXJjZQogKiBoaWVyYXJjaHkuIFBvbGljaWVzIGFyZSBpbmhlcml0ZWQgZG93biB0aGUgcmVzb3VyY2UgaGllcmFyY2h5IGZyb20gaGlnaGVyIGxldmVscywgYnV0IGNhbiBhbHNvIGJlCiAqIG92ZXJyaWRkZW4uIEZvciBkZXRhaWxzIGFib3V0IHRoZSBpbmhlcml0YW5jZSBydWxlcyBwbGVhc2UgcmVhZCBhYm91dCBQb2xpY2llcy4KICoKICogYENvbnN0cmFpbnRzYCBoYXZlIGEgZGVmYXVsdCBiZWhhdmlvciBkZXRlcm1pbmVkIGJ5IHRoZSBgY29uc3RyYWludF9kZWZhdWx0YCBmaWVsZCwgd2hpY2ggaXMgdGhlCiAqIGVuZm9yY2VtZW50IGJlaGF2aW9yIHRoYXQgaXMgdXNlZCBpbiB0aGUgYWJzZW5jZSBvZiBhIGBQb2xpY3lgIGJlaW5nIGRlZmluZWQgb3IgaW5oZXJpdGVkIGZvciB0aGUKICogcmVzb3VyY2UgaW4gcXVlc3Rpb24uCiAqCiAqIDxwPiBUaGlzIGlzIHRoZSBKYXZhIGRhdGEgbW9kZWwgY2xhc3MgdGhhdCBzcGVjaWZpZXMgaG93IHRvIHBhcnNlL3NlcmlhbGl6ZSBpbnRvIHRoZSBKU09OIHRoYXQgaXMKICogdHJhbnNtaXR0ZWQgb3ZlciBIVFRQIHdoZW4gd29ya2luZyB3aXRoIHRoZSBDbG91ZCBSZXNvdXJjZSBNYW5hZ2VyIEFQSS4gRm9yIGEgZGV0YWlsZWQKICogZXhwbGFuYXRpb24gc2VlOgogKiA8YSBocmVmPSJodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9hcGktY2xpZW50LWxpYnJhcnkvamF2YS9nb29nbGUtaHR0cC1qYXZhLWNsaWVudC9qc29uIj5odHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9hcGktY2xpZW50LWxpYnJhcnkvamF2YS9nb29nbGUtaHR0cC1qYXZhLWNsaWVudC9qc29uPC9hPgogKiA8L3A+CiAqCiAqIEBhdXRob3IgR29vZ2xlLCBJbmMuCiAqLwpAU3VwcHJlc3NXYXJuaW5ncygiamF2YWRvYyIpCnB1YmxpYyBmaW5hbCBjbGFzcyBDb25zdHJhaW50IGV4dGVuZHMgY29tLmdvb2dsZS5hcGkuY2xpZW50Lmpzb24uR2VuZXJpY0pzb24gewoKICAvKioKICAgKiBEZWZpbmVzIHRoaXMgY29uc3RyYWludCBhcyBiZWluZyBhIEJvb2xlYW5Db25zdHJhaW50LgogICAqIFRoZSB2YWx1ZSBtYXkgYmUge0Bjb2RlIG51bGx9LgogICAqLwogIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICBwcml2YXRlIEJvb2xlYW5Db25zdHJhaW50IGJvb2xlYW5Db25zdHJhaW50OwoKICAvKioKICAgKiBUaGUgZXZhbHVhdGlvbiBiZWhhdmlvciBvZiB0aGlzIGNvbnN0cmFpbnQgaW4gdGhlIGFic2Vuc2Ugb2YgJ1BvbGljeScuCiAgICogVGhlIHZhbHVlIG1heSBiZSB7QGNvZGUgbnVsbH0uCiAgICovCiAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogIHByaXZhdGUgamF2YS5sYW5nLlN0cmluZyBjb25zdHJhaW50RGVmYXVsdDsKCiAgLyoqCiAgICogRGV0YWlsZWQgZGVzY3JpcHRpb24gb2Ygd2hhdCB0aGlzIGBDb25zdHJhaW50YCBjb250cm9scyBhcyB3ZWxsIGFzIGhvdyBhbmQgd2hlcmUgaXQgaXMKICAgKiBlbmZvcmNlZC4KICAgKgogICAqIE11dGFibGUuCiAgICogVGhlIHZhbHVlIG1heSBiZSB7QGNvZGUgbnVsbH0uCiAgICovCiAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogIHByaXZhdGUgamF2YS5sYW5nLlN0cmluZyBkZXNjcmlwdGlvbjsKCiAgLyoqCiAgICogVGhlIGh1bWFuIHJlYWRhYmxlIG5hbWUuCiAgICoKICAgKiBNdXRhYmxlLgogICAqIFRoZSB2YWx1ZSBtYXkgYmUge0Bjb2RlIG51bGx9LgogICAqLwogIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICBwcml2YXRlIGphdmEubGFuZy5TdHJpbmcgZGlzcGxheU5hbWU7CgogIC8qKgogICAqIERlZmluZXMgdGhpcyBjb25zdHJhaW50IGFzIGJlaW5nIGEgTGlzdENvbnN0cmFpbnQuCiAgICogVGhlIHZhbHVlIG1heSBiZSB7QGNvZGUgbnVsbH0uCiAgICovCiAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogIHByaXZhdGUgTGlzdENvbnN0cmFpbnQgbGlzdENvbnN0cmFpbnQ7CgogIC8qKgogICAqIEltbXV0YWJsZSB2YWx1ZSwgcmVxdWlyZWQgdG8gZ2xvYmFsbHkgYmUgdW5pcXVlLiBGb3IgZXhhbXBsZSwKICAgKiBgY29uc3RyYWludHMvc2VydmljZXVzZXIuc2VydmljZXNgCiAgICogVGhlIHZhbHVlIG1heSBiZSB7QGNvZGUgbnVsbH0uCiAgICovCiAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogIHByaXZhdGUgamF2YS5sYW5nLlN0cmluZyBuYW1lOwoKICAvKioKICAgKiBWZXJzaW9uIG9mIHRoZSBgQ29uc3RyYWludGAuIERlZmF1bHQgdmVyc2lvbiBpcyAwOwogICAqIFRoZSB2YWx1ZSBtYXkgYmUge0Bjb2RlIG51bGx9LgogICAqLwogIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICBwcml2YXRlIGphdmEubGFuZy5JbnRlZ2VyIHZlcnNpb247CgogIC8qKgogICAqIERlZmluZXMgdGhpcyBjb25zdHJhaW50IGFzIGJlaW5nIGEgQm9vbGVhbkNvbnN0cmFpbnQuCiAgICogQHJldHVybiB2YWx1ZSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgQm9vbGVhbkNvbnN0cmFpbnQgZ2V0Qm9vbGVhbkNvbnN0cmFpbnQoKSB7CiAgICByZXR1cm4gYm9vbGVhbkNvbnN0cmFpbnQ7CiAgfQoKICAvKioKICAgKiBEZWZpbmVzIHRoaXMgY29uc3RyYWludCBhcyBiZWluZyBhIEJvb2xlYW5Db25zdHJhaW50LgogICAqIEBwYXJhbSBib29sZWFuQ29uc3RyYWludCBib29sZWFuQ29uc3RyYWludCBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgQ29uc3RyYWludCBzZXRCb29sZWFuQ29uc3RyYWludChCb29sZWFuQ29uc3RyYWludCBib29sZWFuQ29uc3RyYWludCkgewogICAgdGhpcy5ib29sZWFuQ29uc3RyYWludCA9IGJvb2xlYW5Db25zdHJhaW50OwogICAgcmV0dXJuIHRoaXM7CiAgfQoKICAvKioKICAgKiBUaGUgZXZhbHVhdGlvbiBiZWhhdmlvciBvZiB0aGlzIGNvbnN0cmFpbnQgaW4gdGhlIGFic2Vuc2Ugb2YgJ1BvbGljeScuCiAgICogQHJldHVybiB2YWx1ZSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRDb25zdHJhaW50RGVmYXVsdCgpIHsKICAgIHJldHVybiBjb25zdHJhaW50RGVmYXVsdDsKICB9CgogIC8qKgogICAqIFRoZSBldmFsdWF0aW9uIGJlaGF2aW9yIG9mIHRoaXMgY29uc3RyYWludCBpbiB0aGUgYWJzZW5zZSBvZiAnUG9saWN5Jy4KICAgKiBAcGFyYW0gY29uc3RyYWludERlZmF1bHQgY29uc3RyYWludERlZmF1bHQgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIENvbnN0cmFpbnQgc2V0Q29uc3RyYWludERlZmF1bHQoamF2YS5sYW5nLlN0cmluZyBjb25zdHJhaW50RGVmYXVsdCkgewogICAgdGhpcy5jb25zdHJhaW50RGVmYXVsdCA9IGNvbnN0cmFpbnREZWZhdWx0OwogICAgcmV0dXJuIHRoaXM7CiAgfQoKICAvKioKICAgKiBEZXRhaWxlZCBkZXNjcmlwdGlvbiBvZiB3aGF0IHRoaXMgYENvbnN0cmFpbnRgIGNvbnRyb2xzIGFzIHdlbGwgYXMgaG93IGFuZCB3aGVyZSBpdCBpcwogICAqIGVuZm9yY2VkLgogICAqCiAgICogTXV0YWJsZS4KICAgKiBAcmV0dXJuIHZhbHVlIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldERlc2NyaXB0aW9uKCkgewogICAgcmV0dXJuIGRlc2NyaXB0aW9uOwogIH0KCiAgLyoqCiAgICogRGV0YWlsZWQgZGVzY3JpcHRpb24gb2Ygd2hhdCB0aGlzIGBDb25zdHJhaW50YCBjb250cm9scyBhcyB3ZWxsIGFzIGhvdyBhbmQgd2hlcmUgaXQgaXMKICAgKiBlbmZvcmNlZC4KICAgKgogICAqIE11dGFibGUuCiAgICogQHBhcmFtIGRlc2NyaXB0aW9uIGRlc2NyaXB0aW9uIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBDb25zdHJhaW50IHNldERlc2NyaXB0aW9uKGphdmEubGFuZy5TdHJpbmcgZGVzY3JpcHRpb24pIHsKICAgIHRoaXMuZGVzY3JpcHRpb24gPSBkZXNjcmlwdGlvbjsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgLyoqCiAgICogVGhlIGh1bWFuIHJlYWRhYmxlIG5hbWUuCiAgICoKICAgKiBNdXRhYmxlLgogICAqIEByZXR1cm4gdmFsdWUgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0RGlzcGxheU5hbWUoKSB7CiAgICByZXR1cm4gZGlzcGxheU5hbWU7CiAgfQoKICAvKioKICAgKiBUaGUgaHVtYW4gcmVhZGFibGUgbmFtZS4KICAgKgogICAqIE11dGFibGUuCiAgICogQHBhcmFtIGRpc3BsYXlOYW1lIGRpc3BsYXlOYW1lIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBDb25zdHJhaW50IHNldERpc3BsYXlOYW1lKGphdmEubGFuZy5TdHJpbmcgZGlzcGxheU5hbWUpIHsKICAgIHRoaXMuZGlzcGxheU5hbWUgPSBkaXNwbGF5TmFtZTsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgLyoqCiAgICogRGVmaW5lcyB0aGlzIGNvbnN0cmFpbnQgYXMgYmVpbmcgYSBMaXN0Q29uc3RyYWludC4KICAgKiBAcmV0dXJuIHZhbHVlIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBMaXN0Q29uc3RyYWludCBnZXRMaXN0Q29uc3RyYWludCgpIHsKICAgIHJldHVybiBsaXN0Q29uc3RyYWludDsKICB9CgogIC8qKgogICAqIERlZmluZXMgdGhpcyBjb25zdHJhaW50IGFzIGJlaW5nIGEgTGlzdENvbnN0cmFpbnQuCiAgICogQHBhcmFtIGxpc3RDb25zdHJhaW50IGxpc3RDb25zdHJhaW50IG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBDb25zdHJhaW50IHNldExpc3RDb25zdHJhaW50KExpc3RDb25zdHJhaW50IGxpc3RDb25zdHJhaW50KSB7CiAgICB0aGlzLmxpc3RDb25zdHJhaW50ID0gbGlzdENvbnN0cmFpbnQ7CiAgICByZXR1cm4gdGhpczsKICB9CgogIC8qKgogICAqIEltbXV0YWJsZSB2YWx1ZSwgcmVxdWlyZWQgdG8gZ2xvYmFsbHkgYmUgdW5pcXVlLiBGb3IgZXhhbXBsZSwKICAgKiBgY29uc3RyYWludHMvc2VydmljZXVzZXIuc2VydmljZXNgCiAgICogQHJldHVybiB2YWx1ZSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXROYW1lKCkgewogICAgcmV0dXJuIG5hbWU7CiAgfQoKICAvKioKICAgKiBJbW11dGFibGUgdmFsdWUsIHJlcXVpcmVkIHRvIGdsb2JhbGx5IGJlIHVuaXF1ZS4gRm9yIGV4YW1wbGUsCiAgICogYGNvbnN0cmFpbnRzL3NlcnZpY2V1c2VyLnNlcnZpY2VzYAogICAqIEBwYXJhbSBuYW1lIG5hbWUgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIENvbnN0cmFpbnQgc2V0TmFtZShqYXZhLmxhbmcuU3RyaW5nIG5hbWUpIHsKICAgIHRoaXMubmFtZSA9IG5hbWU7CiAgICByZXR1cm4gdGhpczsKICB9CgogIC8qKgogICAqIFZlcnNpb24gb2YgdGhlIGBDb25zdHJhaW50YC4gRGVmYXVsdCB2ZXJzaW9uIGlzIDA7CiAgICogQHJldHVybiB2YWx1ZSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgamF2YS5sYW5nLkludGVnZXIgZ2V0VmVyc2lvbigpIHsKICAgIHJldHVybiB2ZXJzaW9uOwogIH0KCiAgLyoqCiAgICogVmVyc2lvbiBvZiB0aGUgYENvbnN0cmFpbnRgLiBEZWZhdWx0IHZlcnNpb24gaXMgMDsKICAgKiBAcGFyYW0gdmVyc2lvbiB2ZXJzaW9uIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBDb25zdHJhaW50IHNldFZlcnNpb24oamF2YS5sYW5nLkludGVnZXIgdmVyc2lvbikgewogICAgdGhpcy52ZXJzaW9uID0gdmVyc2lvbjsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgQE92ZXJyaWRlCiAgcHVibGljIENvbnN0cmFpbnQgc2V0KFN0cmluZyBmaWVsZE5hbWUsIE9iamVjdCB2YWx1ZSkgewogICAgcmV0dXJuIChDb25zdHJhaW50KSBzdXBlci5zZXQoZmllbGROYW1lLCB2YWx1ZSk7CiAgfQoKICBAT3ZlcnJpZGUKICBwdWJsaWMgQ29uc3RyYWludCBjbG9uZSgpIHsKICAgIHJldHVybiAoQ29uc3RyYWludCkgc3VwZXIuY2xvbmUoKTsKICB9Cgp9ClBLAwQUAAAAAAAAACEAkLUwc54HAACeBwAAPQAAAGNvbS9nb29nbGUvYXBpL3NlcnZpY2VzL2Nsb3VkcmVzb3VyY2VtYW5hZ2VyL21vZGVsL0VtcHR5LmphdmEvKgogKiBDb3B5cmlnaHQgMjAxMCBHb29nbGUgSW5jLgogKgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQKICogaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UKICogaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzCiAqIG9yIGltcGxpZWQuIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMgdW5kZXIKICogdGhlIExpY2Vuc2UuCiAqLwovKgogKiBUaGlzIGNvZGUgd2FzIGdlbmVyYXRlZCBieSBodHRwczovL2dpdGh1Yi5jb20vZ29vZ2xlL2FwaXMtY2xpZW50LWdlbmVyYXRvci8KICogKGJ1aWxkOiAyMDE4LTEwLTA4IDE3OjQ1OjM5IFVUQykKICogb24gMjAyMC0wMy0xOSBhdCAwMjozODozMCBVVEMgCiAqIE1vZGlmeSBhdCB5b3VyIG93biByaXNrLgogKi8KCnBhY2thZ2UgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuY2xvdWRyZXNvdXJjZW1hbmFnZXIubW9kZWw7CgovKioKICogQSBnZW5lcmljIGVtcHR5IG1lc3NhZ2UgdGhhdCB5b3UgY2FuIHJlLXVzZSB0byBhdm9pZCBkZWZpbmluZyBkdXBsaWNhdGVkIGVtcHR5IG1lc3NhZ2VzIGluIHlvdXIKICogQVBJcy4gQSB0eXBpY2FsIGV4YW1wbGUgaXMgdG8gdXNlIGl0IGFzIHRoZSByZXF1ZXN0IG9yIHRoZSByZXNwb25zZSB0eXBlIG9mIGFuIEFQSSBtZXRob2QuIEZvcgogKiBpbnN0YW5jZToKICoKICogICAgIHNlcnZpY2UgRm9vIHsgICAgICAgcnBjIEJhcihnb29nbGUucHJvdG9idWYuRW1wdHkpIHJldHVybnMgKGdvb2dsZS5wcm90b2J1Zi5FbXB0eSk7ICAgICB9CiAqCiAqIFRoZSBKU09OIHJlcHJlc2VudGF0aW9uIGZvciBgRW1wdHlgIGlzIGVtcHR5IEpTT04gb2JqZWN0IGB7fWAuCiAqCiAqIDxwPiBUaGlzIGlzIHRoZSBKYXZhIGRhdGEgbW9kZWwgY2xhc3MgdGhhdCBzcGVjaWZpZXMgaG93IHRvIHBhcnNlL3NlcmlhbGl6ZSBpbnRvIHRoZSBKU09OIHRoYXQgaXMKICogdHJhbnNtaXR0ZWQgb3ZlciBIVFRQIHdoZW4gd29ya2luZyB3aXRoIHRoZSBDbG91ZCBSZXNvdXJjZSBNYW5hZ2VyIEFQSS4gRm9yIGEgZGV0YWlsZWQKICogZXhwbGFuYXRpb24gc2VlOgogKiA8YSBocmVmPSJodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9hcGktY2xpZW50LWxpYnJhcnkvamF2YS9nb29nbGUtaHR0cC1qYXZhLWNsaWVudC9qc29uIj5odHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9hcGktY2xpZW50LWxpYnJhcnkvamF2YS9nb29nbGUtaHR0cC1qYXZhLWNsaWVudC9qc29uPC9hPgogKiA8L3A+CiAqCiAqIEBhdXRob3IgR29vZ2xlLCBJbmMuCiAqLwpAU3VwcHJlc3NXYXJuaW5ncygiamF2YWRvYyIpCnB1YmxpYyBmaW5hbCBjbGFzcyBFbXB0eSBleHRlbmRzIGNvbS5nb29nbGUuYXBpLmNsaWVudC5qc29uLkdlbmVyaWNKc29uIHsKCiAgQE92ZXJyaWRlCiAgcHVibGljIEVtcHR5IHNldChTdHJpbmcgZmllbGROYW1lLCBPYmplY3QgdmFsdWUpIHsKICAgIHJldHVybiAoRW1wdHkpIHN1cGVyLnNldChmaWVsZE5hbWUsIHZhbHVlKTsKICB9CgogIEBPdmVycmlkZQogIHB1YmxpYyBFbXB0eSBjbG9uZSgpIHsKICAgIHJldHVybiAoRW1wdHkpIHN1cGVyLmNsb25lKCk7CiAgfQoKfQpQSwMEFAAAAAAAAAAhADucKol4FwAAeBcAADwAAABjb20vZ29vZ2xlL2FwaS9zZXJ2aWNlcy9jbG91ZHJlc291cmNlbWFuYWdlci9tb2RlbC9FeHByLmphdmEvKgogKiBDb3B5cmlnaHQgMjAxMCBHb29nbGUgSW5jLgogKgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQKICogaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UKICogaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzCiAqIG9yIGltcGxpZWQuIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMgdW5kZXIKICogdGhlIExpY2Vuc2UuCiAqLwovKgogKiBUaGlzIGNvZGUgd2FzIGdlbmVyYXRlZCBieSBodHRwczovL2dpdGh1Yi5jb20vZ29vZ2xlL2FwaXMtY2xpZW50LWdlbmVyYXRvci8KICogKGJ1aWxkOiAyMDE4LTEwLTA4IDE3OjQ1OjM5IFVUQykKICogb24gMjAyMC0wMy0xOSBhdCAwMjozODozMCBVVEMgCiAqIE1vZGlmeSBhdCB5b3VyIG93biByaXNrLgogKi8KCnBhY2thZ2UgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuY2xvdWRyZXNvdXJjZW1hbmFnZXIubW9kZWw7CgovKioKICogUmVwcmVzZW50cyBhIHRleHR1YWwgZXhwcmVzc2lvbiBpbiB0aGUgQ29tbW9uIEV4cHJlc3Npb24gTGFuZ3VhZ2UgKENFTCkgc3ludGF4LiBDRUwgaXMgYSBDLWxpa2UKICogZXhwcmVzc2lvbiBsYW5ndWFnZS4gVGhlIHN5bnRheCBhbmQgc2VtYW50aWNzIG9mIENFTCBhcmUgZG9jdW1lbnRlZCBhdCBodHRwczovL2dpdGh1Yi5jb20vZ29vZ2xlCiAqIC9jZWwtc3BlYy4KICoKICogRXhhbXBsZSAoQ29tcGFyaXNvbik6CiAqCiAqICAgICB0aXRsZTogIlN1bW1hcnkgc2l6ZSBsaW1pdCIgICAgIGRlc2NyaXB0aW9uOiAiRGV0ZXJtaW5lcyBpZiBhIHN1bW1hcnkgaXMgbGVzcyB0aGFuIDEwMCBjaGFycyIKICogZXhwcmVzc2lvbjogImRvY3VtZW50LnN1bW1hcnkuc2l6ZSgpIDwgMTAwIgogKgogKiBFeGFtcGxlIChFcXVhbGl0eSk6CiAqCiAqICAgICB0aXRsZTogIlJlcXVlc3RvciBpcyBvd25lciIgICAgIGRlc2NyaXB0aW9uOiAiRGV0ZXJtaW5lcyBpZiByZXF1ZXN0b3IgaXMgdGhlIGRvY3VtZW50IG93bmVyIgogKiBleHByZXNzaW9uOiAiZG9jdW1lbnQub3duZXIgPT0gcmVxdWVzdC5hdXRoLmNsYWltcy5lbWFpbCIKICoKICogRXhhbXBsZSAoTG9naWMpOgogKgogKiAgICAgdGl0bGU6ICJQdWJsaWMgZG9jdW1lbnRzIiAgICAgZGVzY3JpcHRpb246ICJEZXRlcm1pbmUgd2hldGhlciB0aGUgZG9jdW1lbnQgc2hvdWxkIGJlIHB1YmxpY2x5CiAqIHZpc2libGUiICAgICBleHByZXNzaW9uOiAiZG9jdW1lbnQudHlwZSAhPSAncHJpdmF0ZScgJiYgZG9jdW1lbnQudHlwZSAhPSAnaW50ZXJuYWwnIgogKgogKiBFeGFtcGxlIChEYXRhIE1hbmlwdWxhdGlvbik6CiAqCiAqICAgICB0aXRsZTogIk5vdGlmaWNhdGlvbiBzdHJpbmciICAgICBkZXNjcmlwdGlvbjogIkNyZWF0ZSBhIG5vdGlmaWNhdGlvbiBzdHJpbmcgd2l0aCBhCiAqIHRpbWVzdGFtcC4iICAgICBleHByZXNzaW9uOiAiJ05ldyBtZXNzYWdlIHJlY2VpdmVkIGF0ICcgKyBzdHJpbmcoZG9jdW1lbnQuY3JlYXRlX3RpbWUpIgogKgogKiBUaGUgZXhhY3QgdmFyaWFibGVzIGFuZCBmdW5jdGlvbnMgdGhhdCBtYXkgYmUgcmVmZXJlbmNlZCB3aXRoaW4gYW4gZXhwcmVzc2lvbiBhcmUgZGV0ZXJtaW5lZCBieQogKiB0aGUgc2VydmljZSB0aGF0IGV2YWx1YXRlcyBpdC4gU2VlIHRoZSBzZXJ2aWNlIGRvY3VtZW50YXRpb24gZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24uCiAqCiAqIDxwPiBUaGlzIGlzIHRoZSBKYXZhIGRhdGEgbW9kZWwgY2xhc3MgdGhhdCBzcGVjaWZpZXMgaG93IHRvIHBhcnNlL3NlcmlhbGl6ZSBpbnRvIHRoZSBKU09OIHRoYXQgaXMKICogdHJhbnNtaXR0ZWQgb3ZlciBIVFRQIHdoZW4gd29ya2luZyB3aXRoIHRoZSBDbG91ZCBSZXNvdXJjZSBNYW5hZ2VyIEFQSS4gRm9yIGEgZGV0YWlsZWQKICogZXhwbGFuYXRpb24gc2VlOgogKiA8YSBocmVmPSJodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9hcGktY2xpZW50LWxpYnJhcnkvamF2YS9nb29nbGUtaHR0cC1qYXZhLWNsaWVudC9qc29uIj5odHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9hcGktY2xpZW50LWxpYnJhcnkvamF2YS9nb29nbGUtaHR0cC1qYXZhLWNsaWVudC9qc29uPC9hPgogKiA8L3A+CiAqCiAqIEBhdXRob3IgR29vZ2xlLCBJbmMuCiAqLwpAU3VwcHJlc3NXYXJuaW5ncygiamF2YWRvYyIpCnB1YmxpYyBmaW5hbCBjbGFzcyBFeHByIGV4dGVuZHMgY29tLmdvb2dsZS5hcGkuY2xpZW50Lmpzb24uR2VuZXJpY0pzb24gewoKICAvKioKICAgKiBPcHRpb25hbC4gRGVzY3JpcHRpb24gb2YgdGhlIGV4cHJlc3Npb24uIFRoaXMgaXMgYSBsb25nZXIgdGV4dCB3aGljaCBkZXNjcmliZXMgdGhlIGV4cHJlc3Npb24sCiAgICogZS5nLiB3aGVuIGhvdmVyZWQgb3ZlciBpdCBpbiBhIFVJLgogICAqIFRoZSB2YWx1ZSBtYXkgYmUge0Bjb2RlIG51bGx9LgogICAqLwogIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICBwcml2YXRlIGphdmEubGFuZy5TdHJpbmcgZGVzY3JpcHRpb247CgogIC8qKgogICAqIFRleHR1YWwgcmVwcmVzZW50YXRpb24gb2YgYW4gZXhwcmVzc2lvbiBpbiBDb21tb24gRXhwcmVzc2lvbiBMYW5ndWFnZSBzeW50YXguCiAgICogVGhlIHZhbHVlIG1heSBiZSB7QGNvZGUgbnVsbH0uCiAgICovCiAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogIHByaXZhdGUgamF2YS5sYW5nLlN0cmluZyBleHByZXNzaW9uOwoKICAvKioKICAgKiBPcHRpb25hbC4gU3RyaW5nIGluZGljYXRpbmcgdGhlIGxvY2F0aW9uIG9mIHRoZSBleHByZXNzaW9uIGZvciBlcnJvciByZXBvcnRpbmcsIGUuZy4gYSBmaWxlCiAgICogbmFtZSBhbmQgYSBwb3NpdGlvbiBpbiB0aGUgZmlsZS4KICAgKiBUaGUgdmFsdWUgbWF5IGJlIHtAY29kZSBudWxsfS4KICAgKi8KICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgcHJpdmF0ZSBqYXZhLmxhbmcuU3RyaW5nIGxvY2F0aW9uOwoKICAvKioKICAgKiBPcHRpb25hbC4gVGl0bGUgZm9yIHRoZSBleHByZXNzaW9uLCBpLmUuIGEgc2hvcnQgc3RyaW5nIGRlc2NyaWJpbmcgaXRzIHB1cnBvc2UuIFRoaXMgY2FuIGJlCiAgICogdXNlZCBlLmcuIGluIFVJcyB3aGljaCBhbGxvdyB0byBlbnRlciB0aGUgZXhwcmVzc2lvbi4KICAgKiBUaGUgdmFsdWUgbWF5IGJlIHtAY29kZSBudWxsfS4KICAgKi8KICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgcHJpdmF0ZSBqYXZhLmxhbmcuU3RyaW5nIHRpdGxlOwoKICAvKioKICAgKiBPcHRpb25hbC4gRGVzY3JpcHRpb24gb2YgdGhlIGV4cHJlc3Npb24uIFRoaXMgaXMgYSBsb25nZXIgdGV4dCB3aGljaCBkZXNjcmliZXMgdGhlIGV4cHJlc3Npb24sCiAgICogZS5nLiB3aGVuIGhvdmVyZWQgb3ZlciBpdCBpbiBhIFVJLgogICAqIEByZXR1cm4gdmFsdWUgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0RGVzY3JpcHRpb24oKSB7CiAgICByZXR1cm4gZGVzY3JpcHRpb247CiAgfQoKICAvKioKICAgKiBPcHRpb25hbC4gRGVzY3JpcHRpb24gb2YgdGhlIGV4cHJlc3Npb24uIFRoaXMgaXMgYSBsb25nZXIgdGV4dCB3aGljaCBkZXNjcmliZXMgdGhlIGV4cHJlc3Npb24sCiAgICogZS5nLiB3aGVuIGhvdmVyZWQgb3ZlciBpdCBpbiBhIFVJLgogICAqIEBwYXJhbSBkZXNjcmlwdGlvbiBkZXNjcmlwdGlvbiBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgRXhwciBzZXREZXNjcmlwdGlvbihqYXZhLmxhbmcuU3RyaW5nIGRlc2NyaXB0aW9uKSB7CiAgICB0aGlzLmRlc2NyaXB0aW9uID0gZGVzY3JpcHRpb247CiAgICByZXR1cm4gdGhpczsKICB9CgogIC8qKgogICAqIFRleHR1YWwgcmVwcmVzZW50YXRpb24gb2YgYW4gZXhwcmVzc2lvbiBpbiBDb21tb24gRXhwcmVzc2lvbiBMYW5ndWFnZSBzeW50YXguCiAgICogQHJldHVybiB2YWx1ZSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRFeHByZXNzaW9uKCkgewogICAgcmV0dXJuIGV4cHJlc3Npb247CiAgfQoKICAvKioKICAgKiBUZXh0dWFsIHJlcHJlc2VudGF0aW9uIG9mIGFuIGV4cHJlc3Npb24gaW4gQ29tbW9uIEV4cHJlc3Npb24gTGFuZ3VhZ2Ugc3ludGF4LgogICAqIEBwYXJhbSBleHByZXNzaW9uIGV4cHJlc3Npb24gb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIEV4cHIgc2V0RXhwcmVzc2lvbihqYXZhLmxhbmcuU3RyaW5nIGV4cHJlc3Npb24pIHsKICAgIHRoaXMuZXhwcmVzc2lvbiA9IGV4cHJlc3Npb247CiAgICByZXR1cm4gdGhpczsKICB9CgogIC8qKgogICAqIE9wdGlvbmFsLiBTdHJpbmcgaW5kaWNhdGluZyB0aGUgbG9jYXRpb24gb2YgdGhlIGV4cHJlc3Npb24gZm9yIGVycm9yIHJlcG9ydGluZywgZS5nLiBhIGZpbGUKICAgKiBuYW1lIGFuZCBhIHBvc2l0aW9uIGluIHRoZSBmaWxlLgogICAqIEByZXR1cm4gdmFsdWUgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TG9jYXRpb24oKSB7CiAgICByZXR1cm4gbG9jYXRpb247CiAgfQoKICAvKioKICAgKiBPcHRpb25hbC4gU3RyaW5nIGluZGljYXRpbmcgdGhlIGxvY2F0aW9uIG9mIHRoZSBleHByZXNzaW9uIGZvciBlcnJvciByZXBvcnRpbmcsIGUuZy4gYSBmaWxlCiAgICogbmFtZSBhbmQgYSBwb3NpdGlvbiBpbiB0aGUgZmlsZS4KICAgKiBAcGFyYW0gbG9jYXRpb24gbG9jYXRpb24gb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIEV4cHIgc2V0TG9jYXRpb24oamF2YS5sYW5nLlN0cmluZyBsb2NhdGlvbikgewogICAgdGhpcy5sb2NhdGlvbiA9IGxvY2F0aW9uOwogICAgcmV0dXJuIHRoaXM7CiAgfQoKICAvKioKICAgKiBPcHRpb25hbC4gVGl0bGUgZm9yIHRoZSBleHByZXNzaW9uLCBpLmUuIGEgc2hvcnQgc3RyaW5nIGRlc2NyaWJpbmcgaXRzIHB1cnBvc2UuIFRoaXMgY2FuIGJlCiAgICogdXNlZCBlLmcuIGluIFVJcyB3aGljaCBhbGxvdyB0byBlbnRlciB0aGUgZXhwcmVzc2lvbi4KICAgKiBAcmV0dXJuIHZhbHVlIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFRpdGxlKCkgewogICAgcmV0dXJuIHRpdGxlOwogIH0KCiAgLyoqCiAgICogT3B0aW9uYWwuIFRpdGxlIGZvciB0aGUgZXhwcmVzc2lvbiwgaS5lLiBhIHNob3J0IHN0cmluZyBkZXNjcmliaW5nIGl0cyBwdXJwb3NlLiBUaGlzIGNhbiBiZQogICAqIHVzZWQgZS5nLiBpbiBVSXMgd2hpY2ggYWxsb3cgdG8gZW50ZXIgdGhlIGV4cHJlc3Npb24uCiAgICogQHBhcmFtIHRpdGxlIHRpdGxlIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBFeHByIHNldFRpdGxlKGphdmEubGFuZy5TdHJpbmcgdGl0bGUpIHsKICAgIHRoaXMudGl0bGUgPSB0aXRsZTsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgQE92ZXJyaWRlCiAgcHVibGljIEV4cHIgc2V0KFN0cmluZyBmaWVsZE5hbWUsIE9iamVjdCB2YWx1ZSkgewogICAgcmV0dXJuIChFeHByKSBzdXBlci5zZXQoZmllbGROYW1lLCB2YWx1ZSk7CiAgfQoKICBAT3ZlcnJpZGUKICBwdWJsaWMgRXhwciBjbG9uZSgpIHsKICAgIHJldHVybiAoRXhwcikgc3VwZXIuY2xvbmUoKTsKICB9Cgp9ClBLAwQUAAAAAAAAACEAR0dsaWARAABgEQAARwAAAGNvbS9nb29nbGUvYXBpL3NlcnZpY2VzL2Nsb3VkcmVzb3VyY2VtYW5hZ2VyL21vZGVsL0ZvbGRlck9wZXJhdGlvbi5qYXZhLyoKICogQ29weXJpZ2h0IDIwMTAgR29vZ2xlIEluYy4KICoKICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0CiAqIGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4gWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlCiAqIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcwogKiBvciBpbXBsaWVkLiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zIHVuZGVyCiAqIHRoZSBMaWNlbnNlLgogKi8KLyoKICogVGhpcyBjb2RlIHdhcyBnZW5lcmF0ZWQgYnkgaHR0cHM6Ly9naXRodWIuY29tL2dvb2dsZS9hcGlzLWNsaWVudC1nZW5lcmF0b3IvCiAqIChidWlsZDogMjAxOC0xMC0wOCAxNzo0NTozOSBVVEMpCiAqIG9uIDIwMjAtMDMtMTkgYXQgMDI6Mzg6MzAgVVRDIAogKiBNb2RpZnkgYXQgeW91ciBvd24gcmlzay4KICovCgpwYWNrYWdlIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmNsb3VkcmVzb3VyY2VtYW5hZ2VyLm1vZGVsOwoKLyoqCiAqIE1ldGFkYXRhIGRlc2NyaWJpbmcgYSBsb25nIHJ1bm5pbmcgZm9sZGVyIG9wZXJhdGlvbgogKgogKiA8cD4gVGhpcyBpcyB0aGUgSmF2YSBkYXRhIG1vZGVsIGNsYXNzIHRoYXQgc3BlY2lmaWVzIGhvdyB0byBwYXJzZS9zZXJpYWxpemUgaW50byB0aGUgSlNPTiB0aGF0IGlzCiAqIHRyYW5zbWl0dGVkIG92ZXIgSFRUUCB3aGVuIHdvcmtpbmcgd2l0aCB0aGUgQ2xvdWQgUmVzb3VyY2UgTWFuYWdlciBBUEkuIEZvciBhIGRldGFpbGVkCiAqIGV4cGxhbmF0aW9uIHNlZToKICogPGEgaHJlZj0iaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vYXBpLWNsaWVudC1saWJyYXJ5L2phdmEvZ29vZ2xlLWh0dHAtamF2YS1jbGllbnQvanNvbiI+aHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vYXBpLWNsaWVudC1saWJyYXJ5L2phdmEvZ29vZ2xlLWh0dHAtamF2YS1jbGllbnQvanNvbjwvYT4KICogPC9wPgogKgogKiBAYXV0aG9yIEdvb2dsZSwgSW5jLgogKi8KQFN1cHByZXNzV2FybmluZ3MoImphdmFkb2MiKQpwdWJsaWMgZmluYWwgY2xhc3MgRm9sZGVyT3BlcmF0aW9uIGV4dGVuZHMgY29tLmdvb2dsZS5hcGkuY2xpZW50Lmpzb24uR2VuZXJpY0pzb24gewoKICAvKioKICAgKiBUaGUgcmVzb3VyY2UgbmFtZSBvZiB0aGUgZm9sZGVyIG9yIG9yZ2FuaXphdGlvbiB3ZSBhcmUgZWl0aGVyIGNyZWF0aW5nIHRoZSBmb2xkZXIgdW5kZXIgb3IKICAgKiBtb3ZpbmcgdGhlIGZvbGRlciB0by4KICAgKiBUaGUgdmFsdWUgbWF5IGJlIHtAY29kZSBudWxsfS4KICAgKi8KICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgcHJpdmF0ZSBqYXZhLmxhbmcuU3RyaW5nIGRlc3RpbmF0aW9uUGFyZW50OwoKICAvKioKICAgKiBUaGUgZGlzcGxheSBuYW1lIG9mIHRoZSBmb2xkZXIuCiAgICogVGhlIHZhbHVlIG1heSBiZSB7QGNvZGUgbnVsbH0uCiAgICovCiAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogIHByaXZhdGUgamF2YS5sYW5nLlN0cmluZyBkaXNwbGF5TmFtZTsKCiAgLyoqCiAgICogVGhlIHR5cGUgb2YgdGhpcyBvcGVyYXRpb24uCiAgICogVGhlIHZhbHVlIG1heSBiZSB7QGNvZGUgbnVsbH0uCiAgICovCiAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogIHByaXZhdGUgamF2YS5sYW5nLlN0cmluZyBvcGVyYXRpb25UeXBlOwoKICAvKioKICAgKiBUaGUgcmVzb3VyY2UgbmFtZSBvZiB0aGUgZm9sZGVyJ3MgcGFyZW50LiBPbmx5IGFwcGxpY2FibGUgd2hlbiB0aGUgb3BlcmF0aW9uX3R5cGUgaXMgTU9WRS4KICAgKiBUaGUgdmFsdWUgbWF5IGJlIHtAY29kZSBudWxsfS4KICAgKi8KICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgcHJpdmF0ZSBqYXZhLmxhbmcuU3RyaW5nIHNvdXJjZVBhcmVudDsKCiAgLyoqCiAgICogVGhlIHJlc291cmNlIG5hbWUgb2YgdGhlIGZvbGRlciBvciBvcmdhbml6YXRpb24gd2UgYXJlIGVpdGhlciBjcmVhdGluZyB0aGUgZm9sZGVyIHVuZGVyIG9yCiAgICogbW92aW5nIHRoZSBmb2xkZXIgdG8uCiAgICogQHJldHVybiB2YWx1ZSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXREZXN0aW5hdGlvblBhcmVudCgpIHsKICAgIHJldHVybiBkZXN0aW5hdGlvblBhcmVudDsKICB9CgogIC8qKgogICAqIFRoZSByZXNvdXJjZSBuYW1lIG9mIHRoZSBmb2xkZXIgb3Igb3JnYW5pemF0aW9uIHdlIGFyZSBlaXRoZXIgY3JlYXRpbmcgdGhlIGZvbGRlciB1bmRlciBvcgogICAqIG1vdmluZyB0aGUgZm9sZGVyIHRvLgogICAqIEBwYXJhbSBkZXN0aW5hdGlvblBhcmVudCBkZXN0aW5hdGlvblBhcmVudCBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgRm9sZGVyT3BlcmF0aW9uIHNldERlc3RpbmF0aW9uUGFyZW50KGphdmEubGFuZy5TdHJpbmcgZGVzdGluYXRpb25QYXJlbnQpIHsKICAgIHRoaXMuZGVzdGluYXRpb25QYXJlbnQgPSBkZXN0aW5hdGlvblBhcmVudDsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgLyoqCiAgICogVGhlIGRpc3BsYXkgbmFtZSBvZiB0aGUgZm9sZGVyLgogICAqIEByZXR1cm4gdmFsdWUgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0RGlzcGxheU5hbWUoKSB7CiAgICByZXR1cm4gZGlzcGxheU5hbWU7CiAgfQoKICAvKioKICAgKiBUaGUgZGlzcGxheSBuYW1lIG9mIHRoZSBmb2xkZXIuCiAgICogQHBhcmFtIGRpc3BsYXlOYW1lIGRpc3BsYXlOYW1lIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBGb2xkZXJPcGVyYXRpb24gc2V0RGlzcGxheU5hbWUoamF2YS5sYW5nLlN0cmluZyBkaXNwbGF5TmFtZSkgewogICAgdGhpcy5kaXNwbGF5TmFtZSA9IGRpc3BsYXlOYW1lOwogICAgcmV0dXJuIHRoaXM7CiAgfQoKICAvKioKICAgKiBUaGUgdHlwZSBvZiB0aGlzIG9wZXJhdGlvbi4KICAgKiBAcmV0dXJuIHZhbHVlIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldE9wZXJhdGlvblR5cGUoKSB7CiAgICByZXR1cm4gb3BlcmF0aW9uVHlwZTsKICB9CgogIC8qKgogICAqIFRoZSB0eXBlIG9mIHRoaXMgb3BlcmF0aW9uLgogICAqIEBwYXJhbSBvcGVyYXRpb25UeXBlIG9wZXJhdGlvblR5cGUgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIEZvbGRlck9wZXJhdGlvbiBzZXRPcGVyYXRpb25UeXBlKGphdmEubGFuZy5TdHJpbmcgb3BlcmF0aW9uVHlwZSkgewogICAgdGhpcy5vcGVyYXRpb25UeXBlID0gb3BlcmF0aW9uVHlwZTsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgLyoqCiAgICogVGhlIHJlc291cmNlIG5hbWUgb2YgdGhlIGZvbGRlcidzIHBhcmVudC4gT25seSBhcHBsaWNhYmxlIHdoZW4gdGhlIG9wZXJhdGlvbl90eXBlIGlzIE1PVkUuCiAgICogQHJldHVybiB2YWx1ZSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRTb3VyY2VQYXJlbnQoKSB7CiAgICByZXR1cm4gc291cmNlUGFyZW50OwogIH0KCiAgLyoqCiAgICogVGhlIHJlc291cmNlIG5hbWUgb2YgdGhlIGZvbGRlcidzIHBhcmVudC4gT25seSBhcHBsaWNhYmxlIHdoZW4gdGhlIG9wZXJhdGlvbl90eXBlIGlzIE1PVkUuCiAgICogQHBhcmFtIHNvdXJjZVBhcmVudCBzb3VyY2VQYXJlbnQgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIEZvbGRlck9wZXJhdGlvbiBzZXRTb3VyY2VQYXJlbnQoamF2YS5sYW5nLlN0cmluZyBzb3VyY2VQYXJlbnQpIHsKICAgIHRoaXMuc291cmNlUGFyZW50ID0gc291cmNlUGFyZW50OwogICAgcmV0dXJuIHRoaXM7CiAgfQoKICBAT3ZlcnJpZGUKICBwdWJsaWMgRm9sZGVyT3BlcmF0aW9uIHNldChTdHJpbmcgZmllbGROYW1lLCBPYmplY3QgdmFsdWUpIHsKICAgIHJldHVybiAoRm9sZGVyT3BlcmF0aW9uKSBzdXBlci5zZXQoZmllbGROYW1lLCB2YWx1ZSk7CiAgfQoKICBAT3ZlcnJpZGUKICBwdWJsaWMgRm9sZGVyT3BlcmF0aW9uIGNsb25lKCkgewogICAgcmV0dXJuIChGb2xkZXJPcGVyYXRpb24pIHN1cGVyLmNsb25lKCk7CiAgfQoKfQpQSwMEFAAAAAAAAAAhAI2rV+YTCQAAEwkAAEwAAABjb20vZ29vZ2xlL2FwaS9zZXJ2aWNlcy9jbG91ZHJlc291cmNlbWFuYWdlci9tb2RlbC9Gb2xkZXJPcGVyYXRpb25FcnJvci5qYXZhLyoKICogQ29weXJpZ2h0IDIwMTAgR29vZ2xlIEluYy4KICoKICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0CiAqIGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4gWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlCiAqIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcwogKiBvciBpbXBsaWVkLiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zIHVuZGVyCiAqIHRoZSBMaWNlbnNlLgogKi8KLyoKICogVGhpcyBjb2RlIHdhcyBnZW5lcmF0ZWQgYnkgaHR0cHM6Ly9naXRodWIuY29tL2dvb2dsZS9hcGlzLWNsaWVudC1nZW5lcmF0b3IvCiAqIChidWlsZDogMjAxOC0xMC0wOCAxNzo0NTozOSBVVEMpCiAqIG9uIDIwMjAtMDMtMTkgYXQgMDI6Mzg6MzAgVVRDIAogKiBNb2RpZnkgYXQgeW91ciBvd24gcmlzay4KICovCgpwYWNrYWdlIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmNsb3VkcmVzb3VyY2VtYW5hZ2VyLm1vZGVsOwoKLyoqCiAqIEEgY2xhc3NpZmljYXRpb24gb2YgdGhlIEZvbGRlciBPcGVyYXRpb24gZXJyb3IuCiAqCiAqIDxwPiBUaGlzIGlzIHRoZSBKYXZhIGRhdGEgbW9kZWwgY2xhc3MgdGhhdCBzcGVjaWZpZXMgaG93IHRvIHBhcnNlL3NlcmlhbGl6ZSBpbnRvIHRoZSBKU09OIHRoYXQgaXMKICogdHJhbnNtaXR0ZWQgb3ZlciBIVFRQIHdoZW4gd29ya2luZyB3aXRoIHRoZSBDbG91ZCBSZXNvdXJjZSBNYW5hZ2VyIEFQSS4gRm9yIGEgZGV0YWlsZWQKICogZXhwbGFuYXRpb24gc2VlOgogKiA8YSBocmVmPSJodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9hcGktY2xpZW50LWxpYnJhcnkvamF2YS9nb29nbGUtaHR0cC1qYXZhLWNsaWVudC9qc29uIj5odHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9hcGktY2xpZW50LWxpYnJhcnkvamF2YS9nb29nbGUtaHR0cC1qYXZhLWNsaWVudC9qc29uPC9hPgogKiA8L3A+CiAqCiAqIEBhdXRob3IgR29vZ2xlLCBJbmMuCiAqLwpAU3VwcHJlc3NXYXJuaW5ncygiamF2YWRvYyIpCnB1YmxpYyBmaW5hbCBjbGFzcyBGb2xkZXJPcGVyYXRpb25FcnJvciBleHRlbmRzIGNvbS5nb29nbGUuYXBpLmNsaWVudC5qc29uLkdlbmVyaWNKc29uIHsKCiAgLyoqCiAgICogVGhlIHR5cGUgb2Ygb3BlcmF0aW9uIGVycm9yIGV4cGVyaWVuY2VkLgogICAqIFRoZSB2YWx1ZSBtYXkgYmUge0Bjb2RlIG51bGx9LgogICAqLwogIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICBwcml2YXRlIGphdmEubGFuZy5TdHJpbmcgZXJyb3JNZXNzYWdlSWQ7CgogIC8qKgogICAqIFRoZSB0eXBlIG9mIG9wZXJhdGlvbiBlcnJvciBleHBlcmllbmNlZC4KICAgKiBAcmV0dXJuIHZhbHVlIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldEVycm9yTWVzc2FnZUlkKCkgewogICAgcmV0dXJuIGVycm9yTWVzc2FnZUlkOwogIH0KCiAgLyoqCiAgICogVGhlIHR5cGUgb2Ygb3BlcmF0aW9uIGVycm9yIGV4cGVyaWVuY2VkLgogICAqIEBwYXJhbSBlcnJvck1lc3NhZ2VJZCBlcnJvck1lc3NhZ2VJZCBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgRm9sZGVyT3BlcmF0aW9uRXJyb3Igc2V0RXJyb3JNZXNzYWdlSWQoamF2YS5sYW5nLlN0cmluZyBlcnJvck1lc3NhZ2VJZCkgewogICAgdGhpcy5lcnJvck1lc3NhZ2VJZCA9IGVycm9yTWVzc2FnZUlkOwogICAgcmV0dXJuIHRoaXM7CiAgfQoKICBAT3ZlcnJpZGUKICBwdWJsaWMgRm9sZGVyT3BlcmF0aW9uRXJyb3Igc2V0KFN0cmluZyBmaWVsZE5hbWUsIE9iamVjdCB2YWx1ZSkgewogICAgcmV0dXJuIChGb2xkZXJPcGVyYXRpb25FcnJvcikgc3VwZXIuc2V0KGZpZWxkTmFtZSwgdmFsdWUpOwogIH0KCiAgQE92ZXJyaWRlCiAgcHVibGljIEZvbGRlck9wZXJhdGlvbkVycm9yIGNsb25lKCkgewogICAgcmV0dXJuIChGb2xkZXJPcGVyYXRpb25FcnJvcikgc3VwZXIuY2xvbmUoKTsKICB9Cgp9ClBLAwQUAAAAAAAAACEACqyWNJMGAACTBgAASgAAAGNvbS9nb29nbGUvYXBpL3NlcnZpY2VzL2Nsb3VkcmVzb3VyY2VtYW5hZ2VyL21vZGVsL0dldEFuY2VzdHJ5UmVxdWVzdC5qYXZhLyoKICogQ29weXJpZ2h0IDIwMTAgR29vZ2xlIEluYy4KICoKICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0CiAqIGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4gWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlCiAqIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcwogKiBvciBpbXBsaWVkLiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zIHVuZGVyCiAqIHRoZSBMaWNlbnNlLgogKi8KLyoKICogVGhpcyBjb2RlIHdhcyBnZW5lcmF0ZWQgYnkgaHR0cHM6Ly9naXRodWIuY29tL2dvb2dsZS9hcGlzLWNsaWVudC1nZW5lcmF0b3IvCiAqIChidWlsZDogMjAxOC0xMC0wOCAxNzo0NTozOSBVVEMpCiAqIG9uIDIwMjAtMDMtMTkgYXQgMDI6Mzg6MzAgVVRDIAogKiBNb2RpZnkgYXQgeW91ciBvd24gcmlzay4KICovCgpwYWNrYWdlIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmNsb3VkcmVzb3VyY2VtYW5hZ2VyLm1vZGVsOwoKLyoqCiAqIFRoZSByZXF1ZXN0IHNlbnQgdG8gdGhlIEdldEFuY2VzdHJ5IG1ldGhvZC4KICoKICogPHA+IFRoaXMgaXMgdGhlIEphdmEgZGF0YSBtb2RlbCBjbGFzcyB0aGF0IHNwZWNpZmllcyBob3cgdG8gcGFyc2Uvc2VyaWFsaXplIGludG8gdGhlIEpTT04gdGhhdCBpcwogKiB0cmFuc21pdHRlZCBvdmVyIEhUVFAgd2hlbiB3b3JraW5nIHdpdGggdGhlIENsb3VkIFJlc291cmNlIE1hbmFnZXIgQVBJLiBGb3IgYSBkZXRhaWxlZAogKiBleHBsYW5hdGlvbiBzZWU6CiAqIDxhIGhyZWY9Imh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL2FwaS1jbGllbnQtbGlicmFyeS9qYXZhL2dvb2dsZS1odHRwLWphdmEtY2xpZW50L2pzb24iPmh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL2FwaS1jbGllbnQtbGlicmFyeS9qYXZhL2dvb2dsZS1odHRwLWphdmEtY2xpZW50L2pzb248L2E+CiAqIDwvcD4KICoKICogQGF1dGhvciBHb29nbGUsIEluYy4KICovCkBTdXBwcmVzc1dhcm5pbmdzKCJqYXZhZG9jIikKcHVibGljIGZpbmFsIGNsYXNzIEdldEFuY2VzdHJ5UmVxdWVzdCBleHRlbmRzIGNvbS5nb29nbGUuYXBpLmNsaWVudC5qc29uLkdlbmVyaWNKc29uIHsKCiAgQE92ZXJyaWRlCiAgcHVibGljIEdldEFuY2VzdHJ5UmVxdWVzdCBzZXQoU3RyaW5nIGZpZWxkTmFtZSwgT2JqZWN0IHZhbHVlKSB7CiAgICByZXR1cm4gKEdldEFuY2VzdHJ5UmVxdWVzdCkgc3VwZXIuc2V0KGZpZWxkTmFtZSwgdmFsdWUpOwogIH0KCiAgQE92ZXJyaWRlCiAgcHVibGljIEdldEFuY2VzdHJ5UmVxdWVzdCBjbG9uZSgpIHsKICAgIHJldHVybiAoR2V0QW5jZXN0cnlSZXF1ZXN0KSBzdXBlci5jbG9uZSgpOwogIH0KCn0KUEsDBBQAAAAAAAAAIQCTF8kUMAsAADALAABLAAAAY29tL2dvb2dsZS9hcGkvc2VydmljZXMvY2xvdWRyZXNvdXJjZW1hbmFnZXIvbW9kZWwvR2V0QW5jZXN0cnlSZXNwb25zZS5qYXZhLyoKICogQ29weXJpZ2h0IDIwMTAgR29vZ2xlIEluYy4KICoKICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0CiAqIGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4gWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlCiAqIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcwogKiBvciBpbXBsaWVkLiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zIHVuZGVyCiAqIHRoZSBMaWNlbnNlLgogKi8KLyoKICogVGhpcyBjb2RlIHdhcyBnZW5lcmF0ZWQgYnkgaHR0cHM6Ly9naXRodWIuY29tL2dvb2dsZS9hcGlzLWNsaWVudC1nZW5lcmF0b3IvCiAqIChidWlsZDogMjAxOC0xMC0wOCAxNzo0NTozOSBVVEMpCiAqIG9uIDIwMjAtMDMtMTkgYXQgMDI6Mzg6MzAgVVRDIAogKiBNb2RpZnkgYXQgeW91ciBvd24gcmlzay4KICovCgpwYWNrYWdlIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmNsb3VkcmVzb3VyY2VtYW5hZ2VyLm1vZGVsOwoKLyoqCiAqIFJlc3BvbnNlIGZyb20gdGhlIEdldEFuY2VzdHJ5IG1ldGhvZC4KICoKICogPHA+IFRoaXMgaXMgdGhlIEphdmEgZGF0YSBtb2RlbCBjbGFzcyB0aGF0IHNwZWNpZmllcyBob3cgdG8gcGFyc2Uvc2VyaWFsaXplIGludG8gdGhlIEpTT04gdGhhdCBpcwogKiB0cmFuc21pdHRlZCBvdmVyIEhUVFAgd2hlbiB3b3JraW5nIHdpdGggdGhlIENsb3VkIFJlc291cmNlIE1hbmFnZXIgQVBJLiBGb3IgYSBkZXRhaWxlZAogKiBleHBsYW5hdGlvbiBzZWU6CiAqIDxhIGhyZWY9Imh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL2FwaS1jbGllbnQtbGlicmFyeS9qYXZhL2dvb2dsZS1odHRwLWphdmEtY2xpZW50L2pzb24iPmh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL2FwaS1jbGllbnQtbGlicmFyeS9qYXZhL2dvb2dsZS1odHRwLWphdmEtY2xpZW50L2pzb248L2E+CiAqIDwvcD4KICoKICogQGF1dGhvciBHb29nbGUsIEluYy4KICovCkBTdXBwcmVzc1dhcm5pbmdzKCJqYXZhZG9jIikKcHVibGljIGZpbmFsIGNsYXNzIEdldEFuY2VzdHJ5UmVzcG9uc2UgZXh0ZW5kcyBjb20uZ29vZ2xlLmFwaS5jbGllbnQuanNvbi5HZW5lcmljSnNvbiB7CgogIC8qKgogICAqIEFuY2VzdG9ycyBhcmUgb3JkZXJlZCBmcm9tIGJvdHRvbSB0byB0b3Agb2YgdGhlIHJlc291cmNlIGhpZXJhcmNoeS4gVGhlIGZpcnN0IGFuY2VzdG9yIGlzIHRoZQogICAqIHByb2plY3QgaXRzZWxmLCBmb2xsb3dlZCBieSB0aGUgcHJvamVjdCdzIHBhcmVudCwgZXRjLi4KICAgKiBUaGUgdmFsdWUgbWF5IGJlIHtAY29kZSBudWxsfS4KICAgKi8KICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxBbmNlc3Rvcj4gYW5jZXN0b3I7CgogIHN0YXRpYyB7CiAgICAvLyBoYWNrIHRvIGZvcmNlIFByb0d1YXJkIHRvIGNvbnNpZGVyIEFuY2VzdG9yIHVzZWQsIHNpbmNlIG90aGVyd2lzZSBpdCB3b3VsZCBiZSBzdHJpcHBlZCBvdXQKICAgIC8vIHNlZSBodHRwczovL2dpdGh1Yi5jb20vZ29vZ2xlL2dvb2dsZS1hcGktamF2YS1jbGllbnQvaXNzdWVzLzU0MwogICAgY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuRGF0YS5udWxsT2YoQW5jZXN0b3IuY2xhc3MpOwogIH0KCiAgLyoqCiAgICogQW5jZXN0b3JzIGFyZSBvcmRlcmVkIGZyb20gYm90dG9tIHRvIHRvcCBvZiB0aGUgcmVzb3VyY2UgaGllcmFyY2h5LiBUaGUgZmlyc3QgYW5jZXN0b3IgaXMgdGhlCiAgICogcHJvamVjdCBpdHNlbGYsIGZvbGxvd2VkIGJ5IHRoZSBwcm9qZWN0J3MgcGFyZW50LCBldGMuLgogICAqIEByZXR1cm4gdmFsdWUgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIGphdmEudXRpbC5MaXN0PEFuY2VzdG9yPiBnZXRBbmNlc3RvcigpIHsKICAgIHJldHVybiBhbmNlc3RvcjsKICB9CgogIC8qKgogICAqIEFuY2VzdG9ycyBhcmUgb3JkZXJlZCBmcm9tIGJvdHRvbSB0byB0b3Agb2YgdGhlIHJlc291cmNlIGhpZXJhcmNoeS4gVGhlIGZpcnN0IGFuY2VzdG9yIGlzIHRoZQogICAqIHByb2plY3QgaXRzZWxmLCBmb2xsb3dlZCBieSB0aGUgcHJvamVjdCdzIHBhcmVudCwgZXRjLi4KICAgKiBAcGFyYW0gYW5jZXN0b3IgYW5jZXN0b3Igb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIEdldEFuY2VzdHJ5UmVzcG9uc2Ugc2V0QW5jZXN0b3IoamF2YS51dGlsLkxpc3Q8QW5jZXN0b3I+IGFuY2VzdG9yKSB7CiAgICB0aGlzLmFuY2VzdG9yID0gYW5jZXN0b3I7CiAgICByZXR1cm4gdGhpczsKICB9CgogIEBPdmVycmlkZQogIHB1YmxpYyBHZXRBbmNlc3RyeVJlc3BvbnNlIHNldChTdHJpbmcgZmllbGROYW1lLCBPYmplY3QgdmFsdWUpIHsKICAgIHJldHVybiAoR2V0QW5jZXN0cnlSZXNwb25zZSkgc3VwZXIuc2V0KGZpZWxkTmFtZSwgdmFsdWUpOwogIH0KCiAgQE92ZXJyaWRlCiAgcHVibGljIEdldEFuY2VzdHJ5UmVzcG9uc2UgY2xvbmUoKSB7CiAgICByZXR1cm4gKEdldEFuY2VzdHJ5UmVzcG9uc2UpIHN1cGVyLmNsb25lKCk7CiAgfQoKfQpQSwMEFAAAAAAAAAAhAEoQvalqCQAAagkAAFQAAABjb20vZ29vZ2xlL2FwaS9zZXJ2aWNlcy9jbG91ZHJlc291cmNlbWFuYWdlci9tb2RlbC9HZXRFZmZlY3RpdmVPcmdQb2xpY3lSZXF1ZXN0LmphdmEvKgogKiBDb3B5cmlnaHQgMjAxMCBHb29nbGUgSW5jLgogKgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQKICogaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UKICogaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzCiAqIG9yIGltcGxpZWQuIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMgdW5kZXIKICogdGhlIExpY2Vuc2UuCiAqLwovKgogKiBUaGlzIGNvZGUgd2FzIGdlbmVyYXRlZCBieSBodHRwczovL2dpdGh1Yi5jb20vZ29vZ2xlL2FwaXMtY2xpZW50LWdlbmVyYXRvci8KICogKGJ1aWxkOiAyMDE4LTEwLTA4IDE3OjQ1OjM5IFVUQykKICogb24gMjAyMC0wMy0xOSBhdCAwMjozODozMCBVVEMgCiAqIE1vZGlmeSBhdCB5b3VyIG93biByaXNrLgogKi8KCnBhY2thZ2UgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuY2xvdWRyZXNvdXJjZW1hbmFnZXIubW9kZWw7CgovKioKICogVGhlIHJlcXVlc3Qgc2VudCB0byB0aGUgR2V0RWZmZWN0aXZlT3JnUG9saWN5IG1ldGhvZC4KICoKICogPHA+IFRoaXMgaXMgdGhlIEphdmEgZGF0YSBtb2RlbCBjbGFzcyB0aGF0IHNwZWNpZmllcyBob3cgdG8gcGFyc2Uvc2VyaWFsaXplIGludG8gdGhlIEpTT04gdGhhdCBpcwogKiB0cmFuc21pdHRlZCBvdmVyIEhUVFAgd2hlbiB3b3JraW5nIHdpdGggdGhlIENsb3VkIFJlc291cmNlIE1hbmFnZXIgQVBJLiBGb3IgYSBkZXRhaWxlZAogKiBleHBsYW5hdGlvbiBzZWU6CiAqIDxhIGhyZWY9Imh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL2FwaS1jbGllbnQtbGlicmFyeS9qYXZhL2dvb2dsZS1odHRwLWphdmEtY2xpZW50L2pzb24iPmh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL2FwaS1jbGllbnQtbGlicmFyeS9qYXZhL2dvb2dsZS1odHRwLWphdmEtY2xpZW50L2pzb248L2E+CiAqIDwvcD4KICoKICogQGF1dGhvciBHb29nbGUsIEluYy4KICovCkBTdXBwcmVzc1dhcm5pbmdzKCJqYXZhZG9jIikKcHVibGljIGZpbmFsIGNsYXNzIEdldEVmZmVjdGl2ZU9yZ1BvbGljeVJlcXVlc3QgZXh0ZW5kcyBjb20uZ29vZ2xlLmFwaS5jbGllbnQuanNvbi5HZW5lcmljSnNvbiB7CgogIC8qKgogICAqIFRoZSBuYW1lIG9mIHRoZSBgQ29uc3RyYWludGAgdG8gY29tcHV0ZSB0aGUgZWZmZWN0aXZlIGBQb2xpY3lgLgogICAqIFRoZSB2YWx1ZSBtYXkgYmUge0Bjb2RlIG51bGx9LgogICAqLwogIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICBwcml2YXRlIGphdmEubGFuZy5TdHJpbmcgY29uc3RyYWludDsKCiAgLyoqCiAgICogVGhlIG5hbWUgb2YgdGhlIGBDb25zdHJhaW50YCB0byBjb21wdXRlIHRoZSBlZmZlY3RpdmUgYFBvbGljeWAuCiAgICogQHJldHVybiB2YWx1ZSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRDb25zdHJhaW50KCkgewogICAgcmV0dXJuIGNvbnN0cmFpbnQ7CiAgfQoKICAvKioKICAgKiBUaGUgbmFtZSBvZiB0aGUgYENvbnN0cmFpbnRgIHRvIGNvbXB1dGUgdGhlIGVmZmVjdGl2ZSBgUG9saWN5YC4KICAgKiBAcGFyYW0gY29uc3RyYWludCBjb25zdHJhaW50IG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBHZXRFZmZlY3RpdmVPcmdQb2xpY3lSZXF1ZXN0IHNldENvbnN0cmFpbnQoamF2YS5sYW5nLlN0cmluZyBjb25zdHJhaW50KSB7CiAgICB0aGlzLmNvbnN0cmFpbnQgPSBjb25zdHJhaW50OwogICAgcmV0dXJuIHRoaXM7CiAgfQoKICBAT3ZlcnJpZGUKICBwdWJsaWMgR2V0RWZmZWN0aXZlT3JnUG9saWN5UmVxdWVzdCBzZXQoU3RyaW5nIGZpZWxkTmFtZSwgT2JqZWN0IHZhbHVlKSB7CiAgICByZXR1cm4gKEdldEVmZmVjdGl2ZU9yZ1BvbGljeVJlcXVlc3QpIHN1cGVyLnNldChmaWVsZE5hbWUsIHZhbHVlKTsKICB9CgogIEBPdmVycmlkZQogIHB1YmxpYyBHZXRFZmZlY3RpdmVPcmdQb2xpY3lSZXF1ZXN0IGNsb25lKCkgewogICAgcmV0dXJuIChHZXRFZmZlY3RpdmVPcmdQb2xpY3lSZXF1ZXN0KSBzdXBlci5jbG9uZSgpOwogIH0KCn0KUEsDBBQAAAAAAAAAIQB6cB1zvwkAAL8JAABLAAAAY29tL2dvb2dsZS9hcGkvc2VydmljZXMvY2xvdWRyZXNvdXJjZW1hbmFnZXIvbW9kZWwvR2V0SWFtUG9saWN5UmVxdWVzdC5qYXZhLyoKICogQ29weXJpZ2h0IDIwMTAgR29vZ2xlIEluYy4KICoKICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0CiAqIGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4gWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlCiAqIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcwogKiBvciBpbXBsaWVkLiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zIHVuZGVyCiAqIHRoZSBMaWNlbnNlLgogKi8KLyoKICogVGhpcyBjb2RlIHdhcyBnZW5lcmF0ZWQgYnkgaHR0cHM6Ly9naXRodWIuY29tL2dvb2dsZS9hcGlzLWNsaWVudC1nZW5lcmF0b3IvCiAqIChidWlsZDogMjAxOC0xMC0wOCAxNzo0NTozOSBVVEMpCiAqIG9uIDIwMjAtMDMtMTkgYXQgMDI6Mzg6MzAgVVRDIAogKiBNb2RpZnkgYXQgeW91ciBvd24gcmlzay4KICovCgpwYWNrYWdlIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmNsb3VkcmVzb3VyY2VtYW5hZ2VyLm1vZGVsOwoKLyoqCiAqIFJlcXVlc3QgbWVzc2FnZSBmb3IgYEdldElhbVBvbGljeWAgbWV0aG9kLgogKgogKiA8cD4gVGhpcyBpcyB0aGUgSmF2YSBkYXRhIG1vZGVsIGNsYXNzIHRoYXQgc3BlY2lmaWVzIGhvdyB0byBwYXJzZS9zZXJpYWxpemUgaW50byB0aGUgSlNPTiB0aGF0IGlzCiAqIHRyYW5zbWl0dGVkIG92ZXIgSFRUUCB3aGVuIHdvcmtpbmcgd2l0aCB0aGUgQ2xvdWQgUmVzb3VyY2UgTWFuYWdlciBBUEkuIEZvciBhIGRldGFpbGVkCiAqIGV4cGxhbmF0aW9uIHNlZToKICogPGEgaHJlZj0iaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vYXBpLWNsaWVudC1saWJyYXJ5L2phdmEvZ29vZ2xlLWh0dHAtamF2YS1jbGllbnQvanNvbiI+aHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vYXBpLWNsaWVudC1saWJyYXJ5L2phdmEvZ29vZ2xlLWh0dHAtamF2YS1jbGllbnQvanNvbjwvYT4KICogPC9wPgogKgogKiBAYXV0aG9yIEdvb2dsZSwgSW5jLgogKi8KQFN1cHByZXNzV2FybmluZ3MoImphdmFkb2MiKQpwdWJsaWMgZmluYWwgY2xhc3MgR2V0SWFtUG9saWN5UmVxdWVzdCBleHRlbmRzIGNvbS5nb29nbGUuYXBpLmNsaWVudC5qc29uLkdlbmVyaWNKc29uIHsKCiAgLyoqCiAgICogT1BUSU9OQUw6IEEgYEdldFBvbGljeU9wdGlvbnNgIG9iamVjdCBmb3Igc3BlY2lmeWluZyBvcHRpb25zIHRvIGBHZXRJYW1Qb2xpY3lgLiBUaGlzIGZpZWxkIGlzCiAgICogb25seSB1c2VkIGJ5IENsb3VkIElBTS4KICAgKiBUaGUgdmFsdWUgbWF5IGJlIHtAY29kZSBudWxsfS4KICAgKi8KICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgcHJpdmF0ZSBHZXRQb2xpY3lPcHRpb25zIG9wdGlvbnM7CgogIC8qKgogICAqIE9QVElPTkFMOiBBIGBHZXRQb2xpY3lPcHRpb25zYCBvYmplY3QgZm9yIHNwZWNpZnlpbmcgb3B0aW9ucyB0byBgR2V0SWFtUG9saWN5YC4gVGhpcyBmaWVsZCBpcwogICAqIG9ubHkgdXNlZCBieSBDbG91ZCBJQU0uCiAgICogQHJldHVybiB2YWx1ZSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgR2V0UG9saWN5T3B0aW9ucyBnZXRPcHRpb25zKCkgewogICAgcmV0dXJuIG9wdGlvbnM7CiAgfQoKICAvKioKICAgKiBPUFRJT05BTDogQSBgR2V0UG9saWN5T3B0aW9uc2Agb2JqZWN0IGZvciBzcGVjaWZ5aW5nIG9wdGlvbnMgdG8gYEdldElhbVBvbGljeWAuIFRoaXMgZmllbGQgaXMKICAgKiBvbmx5IHVzZWQgYnkgQ2xvdWQgSUFNLgogICAqIEBwYXJhbSBvcHRpb25zIG9wdGlvbnMgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIEdldElhbVBvbGljeVJlcXVlc3Qgc2V0T3B0aW9ucyhHZXRQb2xpY3lPcHRpb25zIG9wdGlvbnMpIHsKICAgIHRoaXMub3B0aW9ucyA9IG9wdGlvbnM7CiAgICByZXR1cm4gdGhpczsKICB9CgogIEBPdmVycmlkZQogIHB1YmxpYyBHZXRJYW1Qb2xpY3lSZXF1ZXN0IHNldChTdHJpbmcgZmllbGROYW1lLCBPYmplY3QgdmFsdWUpIHsKICAgIHJldHVybiAoR2V0SWFtUG9saWN5UmVxdWVzdCkgc3VwZXIuc2V0KGZpZWxkTmFtZSwgdmFsdWUpOwogIH0KCiAgQE92ZXJyaWRlCiAgcHVibGljIEdldElhbVBvbGljeVJlcXVlc3QgY2xvbmUoKSB7CiAgICByZXR1cm4gKEdldElhbVBvbGljeVJlcXVlc3QpIHN1cGVyLmNsb25lKCk7CiAgfQoKfQpQSwMEFAAAAAAAAAAhAJnP0Kf1CAAA9QgAAEsAAABjb20vZ29vZ2xlL2FwaS9zZXJ2aWNlcy9jbG91ZHJlc291cmNlbWFuYWdlci9tb2RlbC9HZXRPcmdQb2xpY3lSZXF1ZXN0LmphdmEvKgogKiBDb3B5cmlnaHQgMjAxMCBHb29nbGUgSW5jLgogKgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQKICogaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UKICogaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzCiAqIG9yIGltcGxpZWQuIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMgdW5kZXIKICogdGhlIExpY2Vuc2UuCiAqLwovKgogKiBUaGlzIGNvZGUgd2FzIGdlbmVyYXRlZCBieSBodHRwczovL2dpdGh1Yi5jb20vZ29vZ2xlL2FwaXMtY2xpZW50LWdlbmVyYXRvci8KICogKGJ1aWxkOiAyMDE4LTEwLTA4IDE3OjQ1OjM5IFVUQykKICogb24gMjAyMC0wMy0xOSBhdCAwMjozODozMCBVVEMgCiAqIE1vZGlmeSBhdCB5b3VyIG93biByaXNrLgogKi8KCnBhY2thZ2UgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuY2xvdWRyZXNvdXJjZW1hbmFnZXIubW9kZWw7CgovKioKICogVGhlIHJlcXVlc3Qgc2VudCB0byB0aGUgR2V0T3JnUG9saWN5IG1ldGhvZC4KICoKICogPHA+IFRoaXMgaXMgdGhlIEphdmEgZGF0YSBtb2RlbCBjbGFzcyB0aGF0IHNwZWNpZmllcyBob3cgdG8gcGFyc2Uvc2VyaWFsaXplIGludG8gdGhlIEpTT04gdGhhdCBpcwogKiB0cmFuc21pdHRlZCBvdmVyIEhUVFAgd2hlbiB3b3JraW5nIHdpdGggdGhlIENsb3VkIFJlc291cmNlIE1hbmFnZXIgQVBJLiBGb3IgYSBkZXRhaWxlZAogKiBleHBsYW5hdGlvbiBzZWU6CiAqIDxhIGhyZWY9Imh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL2FwaS1jbGllbnQtbGlicmFyeS9qYXZhL2dvb2dsZS1odHRwLWphdmEtY2xpZW50L2pzb24iPmh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL2FwaS1jbGllbnQtbGlicmFyeS9qYXZhL2dvb2dsZS1odHRwLWphdmEtY2xpZW50L2pzb248L2E+CiAqIDwvcD4KICoKICogQGF1dGhvciBHb29nbGUsIEluYy4KICovCkBTdXBwcmVzc1dhcm5pbmdzKCJqYXZhZG9jIikKcHVibGljIGZpbmFsIGNsYXNzIEdldE9yZ1BvbGljeVJlcXVlc3QgZXh0ZW5kcyBjb20uZ29vZ2xlLmFwaS5jbGllbnQuanNvbi5HZW5lcmljSnNvbiB7CgogIC8qKgogICAqIE5hbWUgb2YgdGhlIGBDb25zdHJhaW50YCB0byBnZXQgdGhlIGBQb2xpY3lgLgogICAqIFRoZSB2YWx1ZSBtYXkgYmUge0Bjb2RlIG51bGx9LgogICAqLwogIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICBwcml2YXRlIGphdmEubGFuZy5TdHJpbmcgY29uc3RyYWludDsKCiAgLyoqCiAgICogTmFtZSBvZiB0aGUgYENvbnN0cmFpbnRgIHRvIGdldCB0aGUgYFBvbGljeWAuCiAgICogQHJldHVybiB2YWx1ZSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRDb25zdHJhaW50KCkgewogICAgcmV0dXJuIGNvbnN0cmFpbnQ7CiAgfQoKICAvKioKICAgKiBOYW1lIG9mIHRoZSBgQ29uc3RyYWludGAgdG8gZ2V0IHRoZSBgUG9saWN5YC4KICAgKiBAcGFyYW0gY29uc3RyYWludCBjb25zdHJhaW50IG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBHZXRPcmdQb2xpY3lSZXF1ZXN0IHNldENvbnN0cmFpbnQoamF2YS5sYW5nLlN0cmluZyBjb25zdHJhaW50KSB7CiAgICB0aGlzLmNvbnN0cmFpbnQgPSBjb25zdHJhaW50OwogICAgcmV0dXJuIHRoaXM7CiAgfQoKICBAT3ZlcnJpZGUKICBwdWJsaWMgR2V0T3JnUG9saWN5UmVxdWVzdCBzZXQoU3RyaW5nIGZpZWxkTmFtZSwgT2JqZWN0IHZhbHVlKSB7CiAgICByZXR1cm4gKEdldE9yZ1BvbGljeVJlcXVlc3QpIHN1cGVyLnNldChmaWVsZE5hbWUsIHZhbHVlKTsKICB9CgogIEBPdmVycmlkZQogIHB1YmxpYyBHZXRPcmdQb2xpY3lSZXF1ZXN0IGNsb25lKCkgewogICAgcmV0dXJuIChHZXRPcmdQb2xpY3lSZXF1ZXN0KSBzdXBlci5jbG9uZSgpOwogIH0KCn0KUEsDBBQAAAAAAAAAIQCofwIttQwAALUMAABIAAAAY29tL2dvb2dsZS9hcGkvc2VydmljZXMvY2xvdWRyZXNvdXJjZW1hbmFnZXIvbW9kZWwvR2V0UG9saWN5T3B0aW9ucy5qYXZhLyoKICogQ29weXJpZ2h0IDIwMTAgR29vZ2xlIEluYy4KICoKICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0CiAqIGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4gWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlCiAqIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcwogKiBvciBpbXBsaWVkLiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zIHVuZGVyCiAqIHRoZSBMaWNlbnNlLgogKi8KLyoKICogVGhpcyBjb2RlIHdhcyBnZW5lcmF0ZWQgYnkgaHR0cHM6Ly9naXRodWIuY29tL2dvb2dsZS9hcGlzLWNsaWVudC1nZW5lcmF0b3IvCiAqIChidWlsZDogMjAxOC0xMC0wOCAxNzo0NTozOSBVVEMpCiAqIG9uIDIwMjAtMDMtMTkgYXQgMDI6Mzg6MzAgVVRDIAogKiBNb2RpZnkgYXQgeW91ciBvd24gcmlzay4KICovCgpwYWNrYWdlIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmNsb3VkcmVzb3VyY2VtYW5hZ2VyLm1vZGVsOwoKLyoqCiAqIEVuY2Fwc3VsYXRlcyBzZXR0aW5ncyBwcm92aWRlZCB0byBHZXRJYW1Qb2xpY3kuCiAqCiAqIDxwPiBUaGlzIGlzIHRoZSBKYXZhIGRhdGEgbW9kZWwgY2xhc3MgdGhhdCBzcGVjaWZpZXMgaG93IHRvIHBhcnNlL3NlcmlhbGl6ZSBpbnRvIHRoZSBKU09OIHRoYXQgaXMKICogdHJhbnNtaXR0ZWQgb3ZlciBIVFRQIHdoZW4gd29ya2luZyB3aXRoIHRoZSBDbG91ZCBSZXNvdXJjZSBNYW5hZ2VyIEFQSS4gRm9yIGEgZGV0YWlsZWQKICogZXhwbGFuYXRpb24gc2VlOgogKiA8YSBocmVmPSJodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9hcGktY2xpZW50LWxpYnJhcnkvamF2YS9nb29nbGUtaHR0cC1qYXZhLWNsaWVudC9qc29uIj5odHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9hcGktY2xpZW50LWxpYnJhcnkvamF2YS9nb29nbGUtaHR0cC1qYXZhLWNsaWVudC9qc29uPC9hPgogKiA8L3A+CiAqCiAqIEBhdXRob3IgR29vZ2xlLCBJbmMuCiAqLwpAU3VwcHJlc3NXYXJuaW5ncygiamF2YWRvYyIpCnB1YmxpYyBmaW5hbCBjbGFzcyBHZXRQb2xpY3lPcHRpb25zIGV4dGVuZHMgY29tLmdvb2dsZS5hcGkuY2xpZW50Lmpzb24uR2VuZXJpY0pzb24gewoKICAvKioKICAgKiBPcHRpb25hbC4gVGhlIHBvbGljeSBmb3JtYXQgdmVyc2lvbiB0byBiZSByZXR1cm5lZC4KICAgKgogICAqIFZhbGlkIHZhbHVlcyBhcmUgMCwgMSwgYW5kIDMuIFJlcXVlc3RzIHNwZWNpZnlpbmcgYW4gaW52YWxpZCB2YWx1ZSB3aWxsIGJlIHJlamVjdGVkLgogICAqCiAgICogUmVxdWVzdHMgZm9yIHBvbGljaWVzIHdpdGggYW55IGNvbmRpdGlvbmFsIGJpbmRpbmdzIG11c3Qgc3BlY2lmeSB2ZXJzaW9uIDMuIFBvbGljaWVzIHdpdGhvdXQKICAgKiBhbnkgY29uZGl0aW9uYWwgYmluZGluZ3MgbWF5IHNwZWNpZnkgYW55IHZhbGlkIHZhbHVlIG9yIGxlYXZlIHRoZSBmaWVsZCB1bnNldC4KICAgKiBUaGUgdmFsdWUgbWF5IGJlIHtAY29kZSBudWxsfS4KICAgKi8KICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgcHJpdmF0ZSBqYXZhLmxhbmcuSW50ZWdlciByZXF1ZXN0ZWRQb2xpY3lWZXJzaW9uOwoKICAvKioKICAgKiBPcHRpb25hbC4gVGhlIHBvbGljeSBmb3JtYXQgdmVyc2lvbiB0byBiZSByZXR1cm5lZC4KICAgKgogICAqIFZhbGlkIHZhbHVlcyBhcmUgMCwgMSwgYW5kIDMuIFJlcXVlc3RzIHNwZWNpZnlpbmcgYW4gaW52YWxpZCB2YWx1ZSB3aWxsIGJlIHJlamVjdGVkLgogICAqCiAgICogUmVxdWVzdHMgZm9yIHBvbGljaWVzIHdpdGggYW55IGNvbmRpdGlvbmFsIGJpbmRpbmdzIG11c3Qgc3BlY2lmeSB2ZXJzaW9uIDMuIFBvbGljaWVzIHdpdGhvdXQKICAgKiBhbnkgY29uZGl0aW9uYWwgYmluZGluZ3MgbWF5IHNwZWNpZnkgYW55IHZhbGlkIHZhbHVlIG9yIGxlYXZlIHRoZSBmaWVsZCB1bnNldC4KICAgKiBAcmV0dXJuIHZhbHVlIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBqYXZhLmxhbmcuSW50ZWdlciBnZXRSZXF1ZXN0ZWRQb2xpY3lWZXJzaW9uKCkgewogICAgcmV0dXJuIHJlcXVlc3RlZFBvbGljeVZlcnNpb247CiAgfQoKICAvKioKICAgKiBPcHRpb25hbC4gVGhlIHBvbGljeSBmb3JtYXQgdmVyc2lvbiB0byBiZSByZXR1cm5lZC4KICAgKgogICAqIFZhbGlkIHZhbHVlcyBhcmUgMCwgMSwgYW5kIDMuIFJlcXVlc3RzIHNwZWNpZnlpbmcgYW4gaW52YWxpZCB2YWx1ZSB3aWxsIGJlIHJlamVjdGVkLgogICAqCiAgICogUmVxdWVzdHMgZm9yIHBvbGljaWVzIHdpdGggYW55IGNvbmRpdGlvbmFsIGJpbmRpbmdzIG11c3Qgc3BlY2lmeSB2ZXJzaW9uIDMuIFBvbGljaWVzIHdpdGhvdXQKICAgKiBhbnkgY29uZGl0aW9uYWwgYmluZGluZ3MgbWF5IHNwZWNpZnkgYW55IHZhbGlkIHZhbHVlIG9yIGxlYXZlIHRoZSBmaWVsZCB1bnNldC4KICAgKiBAcGFyYW0gcmVxdWVzdGVkUG9saWN5VmVyc2lvbiByZXF1ZXN0ZWRQb2xpY3lWZXJzaW9uIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBHZXRQb2xpY3lPcHRpb25zIHNldFJlcXVlc3RlZFBvbGljeVZlcnNpb24oamF2YS5sYW5nLkludGVnZXIgcmVxdWVzdGVkUG9saWN5VmVyc2lvbikgewogICAgdGhpcy5yZXF1ZXN0ZWRQb2xpY3lWZXJzaW9uID0gcmVxdWVzdGVkUG9saWN5VmVyc2lvbjsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgQE92ZXJyaWRlCiAgcHVibGljIEdldFBvbGljeU9wdGlvbnMgc2V0KFN0cmluZyBmaWVsZE5hbWUsIE9iamVjdCB2YWx1ZSkgewogICAgcmV0dXJuIChHZXRQb2xpY3lPcHRpb25zKSBzdXBlci5zZXQoZmllbGROYW1lLCB2YWx1ZSk7CiAgfQoKICBAT3ZlcnJpZGUKICBwdWJsaWMgR2V0UG9saWN5T3B0aW9ucyBjbG9uZSgpIHsKICAgIHJldHVybiAoR2V0UG9saWN5T3B0aW9ucykgc3VwZXIuY2xvbmUoKTsKICB9Cgp9ClBLAwQUAAAAAAAAACEAHdJRol0cAABdHAAAPAAAAGNvbS9nb29nbGUvYXBpL3NlcnZpY2VzL2Nsb3VkcmVzb3VyY2VtYW5hZ2VyL21vZGVsL0xpZW4uamF2YS8qCiAqIENvcHlyaWdodCAyMDEwIEdvb2dsZSBJbmMuCiAqCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdAogKiBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZQogKiBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3MKICogb3IgaW1wbGllZC4gU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucyB1bmRlcgogKiB0aGUgTGljZW5zZS4KICovCi8qCiAqIFRoaXMgY29kZSB3YXMgZ2VuZXJhdGVkIGJ5IGh0dHBzOi8vZ2l0aHViLmNvbS9nb29nbGUvYXBpcy1jbGllbnQtZ2VuZXJhdG9yLwogKiAoYnVpbGQ6IDIwMTgtMTAtMDggMTc6NDU6MzkgVVRDKQogKiBvbiAyMDIwLTAzLTE5IGF0IDAyOjM4OjMwIFVUQyAKICogTW9kaWZ5IGF0IHlvdXIgb3duIHJpc2suCiAqLwoKcGFja2FnZSBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5jbG91ZHJlc291cmNlbWFuYWdlci5tb2RlbDsKCi8qKgogKiBBIExpZW4gcmVwcmVzZW50cyBhbiBlbmN1bWJyYW5jZSBvbiB0aGUgYWN0aW9ucyB0aGF0IGNhbiBiZSBwZXJmb3JtZWQgb24gYSByZXNvdXJjZS4KICoKICogPHA+IFRoaXMgaXMgdGhlIEphdmEgZGF0YSBtb2RlbCBjbGFzcyB0aGF0IHNwZWNpZmllcyBob3cgdG8gcGFyc2Uvc2VyaWFsaXplIGludG8gdGhlIEpTT04gdGhhdCBpcwogKiB0cmFuc21pdHRlZCBvdmVyIEhUVFAgd2hlbiB3b3JraW5nIHdpdGggdGhlIENsb3VkIFJlc291cmNlIE1hbmFnZXIgQVBJLiBGb3IgYSBkZXRhaWxlZAogKiBleHBsYW5hdGlvbiBzZWU6CiAqIDxhIGhyZWY9Imh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL2FwaS1jbGllbnQtbGlicmFyeS9qYXZhL2dvb2dsZS1odHRwLWphdmEtY2xpZW50L2pzb24iPmh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL2FwaS1jbGllbnQtbGlicmFyeS9qYXZhL2dvb2dsZS1odHRwLWphdmEtY2xpZW50L2pzb248L2E+CiAqIDwvcD4KICoKICogQGF1dGhvciBHb29nbGUsIEluYy4KICovCkBTdXBwcmVzc1dhcm5pbmdzKCJqYXZhZG9jIikKcHVibGljIGZpbmFsIGNsYXNzIExpZW4gZXh0ZW5kcyBjb20uZ29vZ2xlLmFwaS5jbGllbnQuanNvbi5HZW5lcmljSnNvbiB7CgogIC8qKgogICAqIFRoZSBjcmVhdGlvbiB0aW1lIG9mIHRoaXMgTGllbi4KICAgKiBUaGUgdmFsdWUgbWF5IGJlIHtAY29kZSBudWxsfS4KICAgKi8KICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgcHJpdmF0ZSBTdHJpbmcgY3JlYXRlVGltZTsKCiAgLyoqCiAgICogQSBzeXN0ZW0tZ2VuZXJhdGVkIHVuaXF1ZSBpZGVudGlmaWVyIGZvciB0aGlzIExpZW4uCiAgICoKICAgKiBFeGFtcGxlOiBgbGllbnMvMTIzNGFiY2RgCiAgICogVGhlIHZhbHVlIG1heSBiZSB7QGNvZGUgbnVsbH0uCiAgICovCiAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogIHByaXZhdGUgamF2YS5sYW5nLlN0cmluZyBuYW1lOwoKICAvKioKICAgKiBBIHN0YWJsZSwgdXNlci12aXNpYmxlL21lYW5pbmdmdWwgc3RyaW5nIGlkZW50aWZ5aW5nIHRoZSBvcmlnaW4gb2YgdGhlIExpZW4sIGludGVuZGVkIHRvIGJlCiAgICogaW5zcGVjdGVkIHByb2dyYW1tYXRpY2FsbHkuIE1heGltdW0gbGVuZ3RoIG9mIDIwMCBjaGFyYWN0ZXJzLgogICAqCiAgICogRXhhbXBsZTogJ2NvbXB1dGUuZ29vZ2xlYXBpcy5jb20nCiAgICogVGhlIHZhbHVlIG1heSBiZSB7QGNvZGUgbnVsbH0uCiAgICovCiAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogIHByaXZhdGUgamF2YS5sYW5nLlN0cmluZyBvcmlnaW47CgogIC8qKgogICAqIEEgcmVmZXJlbmNlIHRvIHRoZSByZXNvdXJjZSB0aGlzIExpZW4gaXMgYXR0YWNoZWQgdG8uIFRoZSBzZXJ2ZXIgd2lsbCB2YWxpZGF0ZSB0aGUgcGFyZW50CiAgICogYWdhaW5zdCB0aG9zZSBmb3Igd2hpY2ggTGllbnMgYXJlIHN1cHBvcnRlZC4KICAgKgogICAqIEV4YW1wbGU6IGBwcm9qZWN0cy8xMjM0YAogICAqIFRoZSB2YWx1ZSBtYXkgYmUge0Bjb2RlIG51bGx9LgogICAqLwogIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICBwcml2YXRlIGphdmEubGFuZy5TdHJpbmcgcGFyZW50OwoKICAvKioKICAgKiBDb25jaXNlIHVzZXItdmlzaWJsZSBzdHJpbmdzIGluZGljYXRpbmcgd2h5IGFuIGFjdGlvbiBjYW5ub3QgYmUgcGVyZm9ybWVkIG9uIGEgcmVzb3VyY2UuCiAgICogTWF4aW11bSBsZW5ndGggb2YgMjAwIGNoYXJhY3RlcnMuCiAgICoKICAgKiBFeGFtcGxlOiAnSG9sZHMgcHJvZHVjdGlvbiBBUEkga2V5JwogICAqIFRoZSB2YWx1ZSBtYXkgYmUge0Bjb2RlIG51bGx9LgogICAqLwogIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICBwcml2YXRlIGphdmEubGFuZy5TdHJpbmcgcmVhc29uOwoKICAvKioKICAgKiBUaGUgdHlwZXMgb2Ygb3BlcmF0aW9ucyB3aGljaCBzaG91bGQgYmUgYmxvY2tlZCBhcyBhIHJlc3VsdCBvZiB0aGlzIExpZW4uIEVhY2ggdmFsdWUgc2hvdWxkCiAgICogY29ycmVzcG9uZCB0byBhbiBJQU0gcGVybWlzc2lvbi4gVGhlIHNlcnZlciB3aWxsIHZhbGlkYXRlIHRoZSBwZXJtaXNzaW9ucyBhZ2FpbnN0IHRob3NlIGZvcgogICAqIHdoaWNoIExpZW5zIGFyZSBzdXBwb3J0ZWQuCiAgICoKICAgKiBBbiBlbXB0eSBsaXN0IGlzIG1lYW5pbmdsZXNzIGFuZCB3aWxsIGJlIHJlamVjdGVkLgogICAqCiAgICogRXhhbXBsZTogWydyZXNvdXJjZW1hbmFnZXIucHJvamVjdHMuZGVsZXRlJ10KICAgKiBUaGUgdmFsdWUgbWF5IGJlIHtAY29kZSBudWxsfS4KICAgKi8KICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuU3RyaW5nPiByZXN0cmljdGlvbnM7CgogIC8qKgogICAqIFRoZSBjcmVhdGlvbiB0aW1lIG9mIHRoaXMgTGllbi4KICAgKiBAcmV0dXJuIHZhbHVlIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBTdHJpbmcgZ2V0Q3JlYXRlVGltZSgpIHsKICAgIHJldHVybiBjcmVhdGVUaW1lOwogIH0KCiAgLyoqCiAgICogVGhlIGNyZWF0aW9uIHRpbWUgb2YgdGhpcyBMaWVuLgogICAqIEBwYXJhbSBjcmVhdGVUaW1lIGNyZWF0ZVRpbWUgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIExpZW4gc2V0Q3JlYXRlVGltZShTdHJpbmcgY3JlYXRlVGltZSkgewogICAgdGhpcy5jcmVhdGVUaW1lID0gY3JlYXRlVGltZTsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgLyoqCiAgICogQSBzeXN0ZW0tZ2VuZXJhdGVkIHVuaXF1ZSBpZGVudGlmaWVyIGZvciB0aGlzIExpZW4uCiAgICoKICAgKiBFeGFtcGxlOiBgbGllbnMvMTIzNGFiY2RgCiAgICogQHJldHVybiB2YWx1ZSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXROYW1lKCkgewogICAgcmV0dXJuIG5hbWU7CiAgfQoKICAvKioKICAgKiBBIHN5c3RlbS1nZW5lcmF0ZWQgdW5pcXVlIGlkZW50aWZpZXIgZm9yIHRoaXMgTGllbi4KICAgKgogICAqIEV4YW1wbGU6IGBsaWVucy8xMjM0YWJjZGAKICAgKiBAcGFyYW0gbmFtZSBuYW1lIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBMaWVuIHNldE5hbWUoamF2YS5sYW5nLlN0cmluZyBuYW1lKSB7CiAgICB0aGlzLm5hbWUgPSBuYW1lOwogICAgcmV0dXJuIHRoaXM7CiAgfQoKICAvKioKICAgKiBBIHN0YWJsZSwgdXNlci12aXNpYmxlL21lYW5pbmdmdWwgc3RyaW5nIGlkZW50aWZ5aW5nIHRoZSBvcmlnaW4gb2YgdGhlIExpZW4sIGludGVuZGVkIHRvIGJlCiAgICogaW5zcGVjdGVkIHByb2dyYW1tYXRpY2FsbHkuIE1heGltdW0gbGVuZ3RoIG9mIDIwMCBjaGFyYWN0ZXJzLgogICAqCiAgICogRXhhbXBsZTogJ2NvbXB1dGUuZ29vZ2xlYXBpcy5jb20nCiAgICogQHJldHVybiB2YWx1ZSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRPcmlnaW4oKSB7CiAgICByZXR1cm4gb3JpZ2luOwogIH0KCiAgLyoqCiAgICogQSBzdGFibGUsIHVzZXItdmlzaWJsZS9tZWFuaW5nZnVsIHN0cmluZyBpZGVudGlmeWluZyB0aGUgb3JpZ2luIG9mIHRoZSBMaWVuLCBpbnRlbmRlZCB0byBiZQogICAqIGluc3BlY3RlZCBwcm9ncmFtbWF0aWNhbGx5LiBNYXhpbXVtIGxlbmd0aCBvZiAyMDAgY2hhcmFjdGVycy4KICAgKgogICAqIEV4YW1wbGU6ICdjb21wdXRlLmdvb2dsZWFwaXMuY29tJwogICAqIEBwYXJhbSBvcmlnaW4gb3JpZ2luIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBMaWVuIHNldE9yaWdpbihqYXZhLmxhbmcuU3RyaW5nIG9yaWdpbikgewogICAgdGhpcy5vcmlnaW4gPSBvcmlnaW47CiAgICByZXR1cm4gdGhpczsKICB9CgogIC8qKgogICAqIEEgcmVmZXJlbmNlIHRvIHRoZSByZXNvdXJjZSB0aGlzIExpZW4gaXMgYXR0YWNoZWQgdG8uIFRoZSBzZXJ2ZXIgd2lsbCB2YWxpZGF0ZSB0aGUgcGFyZW50CiAgICogYWdhaW5zdCB0aG9zZSBmb3Igd2hpY2ggTGllbnMgYXJlIHN1cHBvcnRlZC4KICAgKgogICAqIEV4YW1wbGU6IGBwcm9qZWN0cy8xMjM0YAogICAqIEByZXR1cm4gdmFsdWUgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0UGFyZW50KCkgewogICAgcmV0dXJuIHBhcmVudDsKICB9CgogIC8qKgogICAqIEEgcmVmZXJlbmNlIHRvIHRoZSByZXNvdXJjZSB0aGlzIExpZW4gaXMgYXR0YWNoZWQgdG8uIFRoZSBzZXJ2ZXIgd2lsbCB2YWxpZGF0ZSB0aGUgcGFyZW50CiAgICogYWdhaW5zdCB0aG9zZSBmb3Igd2hpY2ggTGllbnMgYXJlIHN1cHBvcnRlZC4KICAgKgogICAqIEV4YW1wbGU6IGBwcm9qZWN0cy8xMjM0YAogICAqIEBwYXJhbSBwYXJlbnQgcGFyZW50IG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBMaWVuIHNldFBhcmVudChqYXZhLmxhbmcuU3RyaW5nIHBhcmVudCkgewogICAgdGhpcy5wYXJlbnQgPSBwYXJlbnQ7CiAgICByZXR1cm4gdGhpczsKICB9CgogIC8qKgogICAqIENvbmNpc2UgdXNlci12aXNpYmxlIHN0cmluZ3MgaW5kaWNhdGluZyB3aHkgYW4gYWN0aW9uIGNhbm5vdCBiZSBwZXJmb3JtZWQgb24gYSByZXNvdXJjZS4KICAgKiBNYXhpbXVtIGxlbmd0aCBvZiAyMDAgY2hhcmFjdGVycy4KICAgKgogICAqIEV4YW1wbGU6ICdIb2xkcyBwcm9kdWN0aW9uIEFQSSBrZXknCiAgICogQHJldHVybiB2YWx1ZSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRSZWFzb24oKSB7CiAgICByZXR1cm4gcmVhc29uOwogIH0KCiAgLyoqCiAgICogQ29uY2lzZSB1c2VyLXZpc2libGUgc3RyaW5ncyBpbmRpY2F0aW5nIHdoeSBhbiBhY3Rpb24gY2Fubm90IGJlIHBlcmZvcm1lZCBvbiBhIHJlc291cmNlLgogICAqIE1heGltdW0gbGVuZ3RoIG9mIDIwMCBjaGFyYWN0ZXJzLgogICAqCiAgICogRXhhbXBsZTogJ0hvbGRzIHByb2R1Y3Rpb24gQVBJIGtleScKICAgKiBAcGFyYW0gcmVhc29uIHJlYXNvbiBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgTGllbiBzZXRSZWFzb24oamF2YS5sYW5nLlN0cmluZyByZWFzb24pIHsKICAgIHRoaXMucmVhc29uID0gcmVhc29uOwogICAgcmV0dXJuIHRoaXM7CiAgfQoKICAvKioKICAgKiBUaGUgdHlwZXMgb2Ygb3BlcmF0aW9ucyB3aGljaCBzaG91bGQgYmUgYmxvY2tlZCBhcyBhIHJlc3VsdCBvZiB0aGlzIExpZW4uIEVhY2ggdmFsdWUgc2hvdWxkCiAgICogY29ycmVzcG9uZCB0byBhbiBJQU0gcGVybWlzc2lvbi4gVGhlIHNlcnZlciB3aWxsIHZhbGlkYXRlIHRoZSBwZXJtaXNzaW9ucyBhZ2FpbnN0IHRob3NlIGZvcgogICAqIHdoaWNoIExpZW5zIGFyZSBzdXBwb3J0ZWQuCiAgICoKICAgKiBBbiBlbXB0eSBsaXN0IGlzIG1lYW5pbmdsZXNzIGFuZCB3aWxsIGJlIHJlamVjdGVkLgogICAqCiAgICogRXhhbXBsZTogWydyZXNvdXJjZW1hbmFnZXIucHJvamVjdHMuZGVsZXRlJ10KICAgKiBAcmV0dXJuIHZhbHVlIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuU3RyaW5nPiBnZXRSZXN0cmljdGlvbnMoKSB7CiAgICByZXR1cm4gcmVzdHJpY3Rpb25zOwogIH0KCiAgLyoqCiAgICogVGhlIHR5cGVzIG9mIG9wZXJhdGlvbnMgd2hpY2ggc2hvdWxkIGJlIGJsb2NrZWQgYXMgYSByZXN1bHQgb2YgdGhpcyBMaWVuLiBFYWNoIHZhbHVlIHNob3VsZAogICAqIGNvcnJlc3BvbmQgdG8gYW4gSUFNIHBlcm1pc3Npb24uIFRoZSBzZXJ2ZXIgd2lsbCB2YWxpZGF0ZSB0aGUgcGVybWlzc2lvbnMgYWdhaW5zdCB0aG9zZSBmb3IKICAgKiB3aGljaCBMaWVucyBhcmUgc3VwcG9ydGVkLgogICAqCiAgICogQW4gZW1wdHkgbGlzdCBpcyBtZWFuaW5nbGVzcyBhbmQgd2lsbCBiZSByZWplY3RlZC4KICAgKgogICAqIEV4YW1wbGU6IFsncmVzb3VyY2VtYW5hZ2VyLnByb2plY3RzLmRlbGV0ZSddCiAgICogQHBhcmFtIHJlc3RyaWN0aW9ucyByZXN0cmljdGlvbnMgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIExpZW4gc2V0UmVzdHJpY3Rpb25zKGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5TdHJpbmc+IHJlc3RyaWN0aW9ucykgewogICAgdGhpcy5yZXN0cmljdGlvbnMgPSByZXN0cmljdGlvbnM7CiAgICByZXR1cm4gdGhpczsKICB9CgogIEBPdmVycmlkZQogIHB1YmxpYyBMaWVuIHNldChTdHJpbmcgZmllbGROYW1lLCBPYmplY3QgdmFsdWUpIHsKICAgIHJldHVybiAoTGllbikgc3VwZXIuc2V0KGZpZWxkTmFtZSwgdmFsdWUpOwogIH0KCiAgQE92ZXJyaWRlCiAgcHVibGljIExpZW4gY2xvbmUoKSB7CiAgICByZXR1cm4gKExpZW4pIHN1cGVyLmNsb25lKCk7CiAgfQoKfQpQSwMEFAAAAAAAAAAhADwEZLW3DgAAtw4AAGAAAABjb20vZ29vZ2xlL2FwaS9zZXJ2aWNlcy9jbG91ZHJlc291cmNlbWFuYWdlci9tb2RlbC9MaXN0QXZhaWxhYmxlT3JnUG9saWN5Q29uc3RyYWludHNSZXF1ZXN0LmphdmEvKgogKiBDb3B5cmlnaHQgMjAxMCBHb29nbGUgSW5jLgogKgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQKICogaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UKICogaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzCiAqIG9yIGltcGxpZWQuIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMgdW5kZXIKICogdGhlIExpY2Vuc2UuCiAqLwovKgogKiBUaGlzIGNvZGUgd2FzIGdlbmVyYXRlZCBieSBodHRwczovL2dpdGh1Yi5jb20vZ29vZ2xlL2FwaXMtY2xpZW50LWdlbmVyYXRvci8KICogKGJ1aWxkOiAyMDE4LTEwLTA4IDE3OjQ1OjM5IFVUQykKICogb24gMjAyMC0wMy0xOSBhdCAwMjozODozMCBVVEMgCiAqIE1vZGlmeSBhdCB5b3VyIG93biByaXNrLgogKi8KCnBhY2thZ2UgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuY2xvdWRyZXNvdXJjZW1hbmFnZXIubW9kZWw7CgovKioKICogVGhlIHJlcXVlc3Qgc2VudCB0byB0aGUgW0xpc3RBdmFpbGFibGVPcmdQb2xpY3lDb25zdHJhaW50c10KICogZ29vZ2xlLmNsb3VkLk9yZ1BvbGljeS52MS5MaXN0QXZhaWxhYmxlT3JnUG9saWN5Q29uc3RyYWludHNdIG1ldGhvZC4KICoKICogPHA+IFRoaXMgaXMgdGhlIEphdmEgZGF0YSBtb2RlbCBjbGFzcyB0aGF0IHNwZWNpZmllcyBob3cgdG8gcGFyc2Uvc2VyaWFsaXplIGludG8gdGhlIEpTT04gdGhhdCBpcwogKiB0cmFuc21pdHRlZCBvdmVyIEhUVFAgd2hlbiB3b3JraW5nIHdpdGggdGhlIENsb3VkIFJlc291cmNlIE1hbmFnZXIgQVBJLiBGb3IgYSBkZXRhaWxlZAogKiBleHBsYW5hdGlvbiBzZWU6CiAqIDxhIGhyZWY9Imh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL2FwaS1jbGllbnQtbGlicmFyeS9qYXZhL2dvb2dsZS1odHRwLWphdmEtY2xpZW50L2pzb24iPmh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL2FwaS1jbGllbnQtbGlicmFyeS9qYXZhL2dvb2dsZS1odHRwLWphdmEtY2xpZW50L2pzb248L2E+CiAqIDwvcD4KICoKICogQGF1dGhvciBHb29nbGUsIEluYy4KICovCkBTdXBwcmVzc1dhcm5pbmdzKCJqYXZhZG9jIikKcHVibGljIGZpbmFsIGNsYXNzIExpc3RBdmFpbGFibGVPcmdQb2xpY3lDb25zdHJhaW50c1JlcXVlc3QgZXh0ZW5kcyBjb20uZ29vZ2xlLmFwaS5jbGllbnQuanNvbi5HZW5lcmljSnNvbiB7CgogIC8qKgogICAqIFNpemUgb2YgdGhlIHBhZ2VzIHRvIGJlIHJldHVybmVkLiBUaGlzIGlzIGN1cnJlbnRseSB1bnN1cHBvcnRlZCBhbmQgd2lsbCBiZSBpZ25vcmVkLiBUaGUgc2VydmVyCiAgICogbWF5IGF0IGFueSBwb2ludCBzdGFydCB1c2luZyB0aGlzIGZpZWxkIHRvIGxpbWl0IHBhZ2Ugc2l6ZS4KICAgKiBUaGUgdmFsdWUgbWF5IGJlIHtAY29kZSBudWxsfS4KICAgKi8KICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgcHJpdmF0ZSBqYXZhLmxhbmcuSW50ZWdlciBwYWdlU2l6ZTsKCiAgLyoqCiAgICogUGFnZSB0b2tlbiB1c2VkIHRvIHJldHJpZXZlIHRoZSBuZXh0IHBhZ2UuIFRoaXMgaXMgY3VycmVudGx5IHVuc3VwcG9ydGVkIGFuZCB3aWxsIGJlIGlnbm9yZWQuCiAgICogVGhlIHNlcnZlciBtYXkgYXQgYW55IHBvaW50IHN0YXJ0IHVzaW5nIHRoaXMgZmllbGQuCiAgICogVGhlIHZhbHVlIG1heSBiZSB7QGNvZGUgbnVsbH0uCiAgICovCiAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogIHByaXZhdGUgamF2YS5sYW5nLlN0cmluZyBwYWdlVG9rZW47CgogIC8qKgogICAqIFNpemUgb2YgdGhlIHBhZ2VzIHRvIGJlIHJldHVybmVkLiBUaGlzIGlzIGN1cnJlbnRseSB1bnN1cHBvcnRlZCBhbmQgd2lsbCBiZSBpZ25vcmVkLiBUaGUgc2VydmVyCiAgICogbWF5IGF0IGFueSBwb2ludCBzdGFydCB1c2luZyB0aGlzIGZpZWxkIHRvIGxpbWl0IHBhZ2Ugc2l6ZS4KICAgKiBAcmV0dXJuIHZhbHVlIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBqYXZhLmxhbmcuSW50ZWdlciBnZXRQYWdlU2l6ZSgpIHsKICAgIHJldHVybiBwYWdlU2l6ZTsKICB9CgogIC8qKgogICAqIFNpemUgb2YgdGhlIHBhZ2VzIHRvIGJlIHJldHVybmVkLiBUaGlzIGlzIGN1cnJlbnRseSB1bnN1cHBvcnRlZCBhbmQgd2lsbCBiZSBpZ25vcmVkLiBUaGUgc2VydmVyCiAgICogbWF5IGF0IGFueSBwb2ludCBzdGFydCB1c2luZyB0aGlzIGZpZWxkIHRvIGxpbWl0IHBhZ2Ugc2l6ZS4KICAgKiBAcGFyYW0gcGFnZVNpemUgcGFnZVNpemUgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIExpc3RBdmFpbGFibGVPcmdQb2xpY3lDb25zdHJhaW50c1JlcXVlc3Qgc2V0UGFnZVNpemUoamF2YS5sYW5nLkludGVnZXIgcGFnZVNpemUpIHsKICAgIHRoaXMucGFnZVNpemUgPSBwYWdlU2l6ZTsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgLyoqCiAgICogUGFnZSB0b2tlbiB1c2VkIHRvIHJldHJpZXZlIHRoZSBuZXh0IHBhZ2UuIFRoaXMgaXMgY3VycmVudGx5IHVuc3VwcG9ydGVkIGFuZCB3aWxsIGJlIGlnbm9yZWQuCiAgICogVGhlIHNlcnZlciBtYXkgYXQgYW55IHBvaW50IHN0YXJ0IHVzaW5nIHRoaXMgZmllbGQuCiAgICogQHJldHVybiB2YWx1ZSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRQYWdlVG9rZW4oKSB7CiAgICByZXR1cm4gcGFnZVRva2VuOwogIH0KCiAgLyoqCiAgICogUGFnZSB0b2tlbiB1c2VkIHRvIHJldHJpZXZlIHRoZSBuZXh0IHBhZ2UuIFRoaXMgaXMgY3VycmVudGx5IHVuc3VwcG9ydGVkIGFuZCB3aWxsIGJlIGlnbm9yZWQuCiAgICogVGhlIHNlcnZlciBtYXkgYXQgYW55IHBvaW50IHN0YXJ0IHVzaW5nIHRoaXMgZmllbGQuCiAgICogQHBhcmFtIHBhZ2VUb2tlbiBwYWdlVG9rZW4gb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIExpc3RBdmFpbGFibGVPcmdQb2xpY3lDb25zdHJhaW50c1JlcXVlc3Qgc2V0UGFnZVRva2VuKGphdmEubGFuZy5TdHJpbmcgcGFnZVRva2VuKSB7CiAgICB0aGlzLnBhZ2VUb2tlbiA9IHBhZ2VUb2tlbjsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgQE92ZXJyaWRlCiAgcHVibGljIExpc3RBdmFpbGFibGVPcmdQb2xpY3lDb25zdHJhaW50c1JlcXVlc3Qgc2V0KFN0cmluZyBmaWVsZE5hbWUsIE9iamVjdCB2YWx1ZSkgewogICAgcmV0dXJuIChMaXN0QXZhaWxhYmxlT3JnUG9saWN5Q29uc3RyYWludHNSZXF1ZXN0KSBzdXBlci5zZXQoZmllbGROYW1lLCB2YWx1ZSk7CiAgfQoKICBAT3ZlcnJpZGUKICBwdWJsaWMgTGlzdEF2YWlsYWJsZU9yZ1BvbGljeUNvbnN0cmFpbnRzUmVxdWVzdCBjbG9uZSgpIHsKICAgIHJldHVybiAoTGlzdEF2YWlsYWJsZU9yZ1BvbGljeUNvbnN0cmFpbnRzUmVxdWVzdCkgc3VwZXIuY2xvbmUoKTsKICB9Cgp9ClBLAwQUAAAAAAAAACEARaCp7IsOAACLDgAAYQAAAGNvbS9nb29nbGUvYXBpL3NlcnZpY2VzL2Nsb3VkcmVzb3VyY2VtYW5hZ2VyL21vZGVsL0xpc3RBdmFpbGFibGVPcmdQb2xpY3lDb25zdHJhaW50c1Jlc3BvbnNlLmphdmEvKgogKiBDb3B5cmlnaHQgMjAxMCBHb29nbGUgSW5jLgogKgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQKICogaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UKICogaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzCiAqIG9yIGltcGxpZWQuIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMgdW5kZXIKICogdGhlIExpY2Vuc2UuCiAqLwovKgogKiBUaGlzIGNvZGUgd2FzIGdlbmVyYXRlZCBieSBodHRwczovL2dpdGh1Yi5jb20vZ29vZ2xlL2FwaXMtY2xpZW50LWdlbmVyYXRvci8KICogKGJ1aWxkOiAyMDE4LTEwLTA4IDE3OjQ1OjM5IFVUQykKICogb24gMjAyMC0wMy0xOSBhdCAwMjozODozMCBVVEMgCiAqIE1vZGlmeSBhdCB5b3VyIG93biByaXNrLgogKi8KCnBhY2thZ2UgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuY2xvdWRyZXNvdXJjZW1hbmFnZXIubW9kZWw7CgovKioKICogVGhlIHJlc3BvbnNlIHJldHVybmVkIGZyb20gdGhlIExpc3RBdmFpbGFibGVPcmdQb2xpY3lDb25zdHJhaW50cyBtZXRob2QuIFJldHVybnMgYWxsCiAqIGBDb25zdHJhaW50c2AgdGhhdCBjb3VsZCBiZSBzZXQgYXQgdGhpcyBsZXZlbCBvZiB0aGUgaGllcmFyY2h5IChjb250cmFzdCB3aXRoIHRoZSByZXNwb25zZSBmcm9tCiAqIGBMaXN0UG9saWNpZXNgLCB3aGljaCByZXR1cm5zIGFsbCBwb2xpY2llcyB3aGljaCBhcmUgc2V0KS4KICoKICogPHA+IFRoaXMgaXMgdGhlIEphdmEgZGF0YSBtb2RlbCBjbGFzcyB0aGF0IHNwZWNpZmllcyBob3cgdG8gcGFyc2Uvc2VyaWFsaXplIGludG8gdGhlIEpTT04gdGhhdCBpcwogKiB0cmFuc21pdHRlZCBvdmVyIEhUVFAgd2hlbiB3b3JraW5nIHdpdGggdGhlIENsb3VkIFJlc291cmNlIE1hbmFnZXIgQVBJLiBGb3IgYSBkZXRhaWxlZAogKiBleHBsYW5hdGlvbiBzZWU6CiAqIDxhIGhyZWY9Imh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL2FwaS1jbGllbnQtbGlicmFyeS9qYXZhL2dvb2dsZS1odHRwLWphdmEtY2xpZW50L2pzb24iPmh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL2FwaS1jbGllbnQtbGlicmFyeS9qYXZhL2dvb2dsZS1odHRwLWphdmEtY2xpZW50L2pzb248L2E+CiAqIDwvcD4KICoKICogQGF1dGhvciBHb29nbGUsIEluYy4KICovCkBTdXBwcmVzc1dhcm5pbmdzKCJqYXZhZG9jIikKcHVibGljIGZpbmFsIGNsYXNzIExpc3RBdmFpbGFibGVPcmdQb2xpY3lDb25zdHJhaW50c1Jlc3BvbnNlIGV4dGVuZHMgY29tLmdvb2dsZS5hcGkuY2xpZW50Lmpzb24uR2VuZXJpY0pzb24gewoKICAvKioKICAgKiBUaGUgY29sbGVjdGlvbiBvZiBjb25zdHJhaW50cyB0aGF0IGFyZSBzZXR0YWJsZSBvbiB0aGUgcmVxdWVzdCByZXNvdXJjZS4KICAgKiBUaGUgdmFsdWUgbWF5IGJlIHtAY29kZSBudWxsfS4KICAgKi8KICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxDb25zdHJhaW50PiBjb25zdHJhaW50czsKCiAgc3RhdGljIHsKICAgIC8vIGhhY2sgdG8gZm9yY2UgUHJvR3VhcmQgdG8gY29uc2lkZXIgQ29uc3RyYWludCB1c2VkLCBzaW5jZSBvdGhlcndpc2UgaXQgd291bGQgYmUgc3RyaXBwZWQgb3V0CiAgICAvLyBzZWUgaHR0cHM6Ly9naXRodWIuY29tL2dvb2dsZS9nb29nbGUtYXBpLWphdmEtY2xpZW50L2lzc3Vlcy81NDMKICAgIGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLkRhdGEubnVsbE9mKENvbnN0cmFpbnQuY2xhc3MpOwogIH0KCiAgLyoqCiAgICogUGFnZSB0b2tlbiB1c2VkIHRvIHJldHJpZXZlIHRoZSBuZXh0IHBhZ2UuIFRoaXMgaXMgY3VycmVudGx5IG5vdCB1c2VkLgogICAqIFRoZSB2YWx1ZSBtYXkgYmUge0Bjb2RlIG51bGx9LgogICAqLwogIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICBwcml2YXRlIGphdmEubGFuZy5TdHJpbmcgbmV4dFBhZ2VUb2tlbjsKCiAgLyoqCiAgICogVGhlIGNvbGxlY3Rpb24gb2YgY29uc3RyYWludHMgdGhhdCBhcmUgc2V0dGFibGUgb24gdGhlIHJlcXVlc3QgcmVzb3VyY2UuCiAgICogQHJldHVybiB2YWx1ZSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8Q29uc3RyYWludD4gZ2V0Q29uc3RyYWludHMoKSB7CiAgICByZXR1cm4gY29uc3RyYWludHM7CiAgfQoKICAvKioKICAgKiBUaGUgY29sbGVjdGlvbiBvZiBjb25zdHJhaW50cyB0aGF0IGFyZSBzZXR0YWJsZSBvbiB0aGUgcmVxdWVzdCByZXNvdXJjZS4KICAgKiBAcGFyYW0gY29uc3RyYWludHMgY29uc3RyYWludHMgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIExpc3RBdmFpbGFibGVPcmdQb2xpY3lDb25zdHJhaW50c1Jlc3BvbnNlIHNldENvbnN0cmFpbnRzKGphdmEudXRpbC5MaXN0PENvbnN0cmFpbnQ+IGNvbnN0cmFpbnRzKSB7CiAgICB0aGlzLmNvbnN0cmFpbnRzID0gY29uc3RyYWludHM7CiAgICByZXR1cm4gdGhpczsKICB9CgogIC8qKgogICAqIFBhZ2UgdG9rZW4gdXNlZCB0byByZXRyaWV2ZSB0aGUgbmV4dCBwYWdlLiBUaGlzIGlzIGN1cnJlbnRseSBub3QgdXNlZC4KICAgKiBAcmV0dXJuIHZhbHVlIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldE5leHRQYWdlVG9rZW4oKSB7CiAgICByZXR1cm4gbmV4dFBhZ2VUb2tlbjsKICB9CgogIC8qKgogICAqIFBhZ2UgdG9rZW4gdXNlZCB0byByZXRyaWV2ZSB0aGUgbmV4dCBwYWdlLiBUaGlzIGlzIGN1cnJlbnRseSBub3QgdXNlZC4KICAgKiBAcGFyYW0gbmV4dFBhZ2VUb2tlbiBuZXh0UGFnZVRva2VuIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBMaXN0QXZhaWxhYmxlT3JnUG9saWN5Q29uc3RyYWludHNSZXNwb25zZSBzZXROZXh0UGFnZVRva2VuKGphdmEubGFuZy5TdHJpbmcgbmV4dFBhZ2VUb2tlbikgewogICAgdGhpcy5uZXh0UGFnZVRva2VuID0gbmV4dFBhZ2VUb2tlbjsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgQE92ZXJyaWRlCiAgcHVibGljIExpc3RBdmFpbGFibGVPcmdQb2xpY3lDb25zdHJhaW50c1Jlc3BvbnNlIHNldChTdHJpbmcgZmllbGROYW1lLCBPYmplY3QgdmFsdWUpIHsKICAgIHJldHVybiAoTGlzdEF2YWlsYWJsZU9yZ1BvbGljeUNvbnN0cmFpbnRzUmVzcG9uc2UpIHN1cGVyLnNldChmaWVsZE5hbWUsIHZhbHVlKTsKICB9CgogIEBPdmVycmlkZQogIHB1YmxpYyBMaXN0QXZhaWxhYmxlT3JnUG9saWN5Q29uc3RyYWludHNSZXNwb25zZSBjbG9uZSgpIHsKICAgIHJldHVybiAoTGlzdEF2YWlsYWJsZU9yZ1BvbGljeUNvbnN0cmFpbnRzUmVzcG9uc2UpIHN1cGVyLmNsb25lKCk7CiAgfQoKfQpQSwMEFAAAAAAAAAAhACF9M4koDwAAKA8AAEYAAABjb20vZ29vZ2xlL2FwaS9zZXJ2aWNlcy9jbG91ZHJlc291cmNlbWFuYWdlci9tb2RlbC9MaXN0Q29uc3RyYWludC5qYXZhLyoKICogQ29weXJpZ2h0IDIwMTAgR29vZ2xlIEluYy4KICoKICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0CiAqIGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4gWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlCiAqIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcwogKiBvciBpbXBsaWVkLiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zIHVuZGVyCiAqIHRoZSBMaWNlbnNlLgogKi8KLyoKICogVGhpcyBjb2RlIHdhcyBnZW5lcmF0ZWQgYnkgaHR0cHM6Ly9naXRodWIuY29tL2dvb2dsZS9hcGlzLWNsaWVudC1nZW5lcmF0b3IvCiAqIChidWlsZDogMjAxOC0xMC0wOCAxNzo0NTozOSBVVEMpCiAqIG9uIDIwMjAtMDMtMTkgYXQgMDI6Mzg6MzAgVVRDIAogKiBNb2RpZnkgYXQgeW91ciBvd24gcmlzay4KICovCgpwYWNrYWdlIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmNsb3VkcmVzb3VyY2VtYW5hZ2VyLm1vZGVsOwoKLyoqCiAqIEEgYENvbnN0cmFpbnRgIHRoYXQgYWxsb3dzIG9yIGRpc2FsbG93cyBhIGxpc3Qgb2Ygc3RyaW5nIHZhbHVlcywgd2hpY2ggYXJlIGNvbmZpZ3VyZWQgYnkgYW4KICogT3JnYW5pemF0aW9uJ3MgcG9saWN5IGFkbWluaXN0cmF0b3Igd2l0aCBhIGBQb2xpY3lgLgogKgogKiA8cD4gVGhpcyBpcyB0aGUgSmF2YSBkYXRhIG1vZGVsIGNsYXNzIHRoYXQgc3BlY2lmaWVzIGhvdyB0byBwYXJzZS9zZXJpYWxpemUgaW50byB0aGUgSlNPTiB0aGF0IGlzCiAqIHRyYW5zbWl0dGVkIG92ZXIgSFRUUCB3aGVuIHdvcmtpbmcgd2l0aCB0aGUgQ2xvdWQgUmVzb3VyY2UgTWFuYWdlciBBUEkuIEZvciBhIGRldGFpbGVkCiAqIGV4cGxhbmF0aW9uIHNlZToKICogPGEgaHJlZj0iaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vYXBpLWNsaWVudC1saWJyYXJ5L2phdmEvZ29vZ2xlLWh0dHAtamF2YS1jbGllbnQvanNvbiI+aHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vYXBpLWNsaWVudC1saWJyYXJ5L2phdmEvZ29vZ2xlLWh0dHAtamF2YS1jbGllbnQvanNvbjwvYT4KICogPC9wPgogKgogKiBAYXV0aG9yIEdvb2dsZSwgSW5jLgogKi8KQFN1cHByZXNzV2FybmluZ3MoImphdmFkb2MiKQpwdWJsaWMgZmluYWwgY2xhc3MgTGlzdENvbnN0cmFpbnQgZXh0ZW5kcyBjb20uZ29vZ2xlLmFwaS5jbGllbnQuanNvbi5HZW5lcmljSnNvbiB7CgogIC8qKgogICAqIE9wdGlvbmFsLiBUaGUgR29vZ2xlIENsb3VkIENvbnNvbGUgd2lsbCB0cnkgdG8gZGVmYXVsdCB0byBhIGNvbmZpZ3VyYXRpb24gdGhhdCBtYXRjaGVzIHRoZQogICAqIHZhbHVlIHNwZWNpZmllZCBpbiB0aGlzIGBDb25zdHJhaW50YC4KICAgKiBUaGUgdmFsdWUgbWF5IGJlIHtAY29kZSBudWxsfS4KICAgKi8KICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgcHJpdmF0ZSBqYXZhLmxhbmcuU3RyaW5nIHN1Z2dlc3RlZFZhbHVlOwoKICAvKioKICAgKiBJbmRpY2F0ZXMgd2hldGhlciBzdWJ0cmVlcyBvZiBDbG91ZCBSZXNvdXJjZSBNYW5hZ2VyIHJlc291cmNlIGhpZXJhcmNoeSBjYW4gYmUgdXNlZCBpbgogICAqIGBQb2xpY3kuYWxsb3dlZF92YWx1ZXNgIGFuZCBgUG9saWN5LmRlbmllZF92YWx1ZXNgLiBGb3IgZXhhbXBsZSwgYCJ1bmRlcjpmb2xkZXJzLzEyMyJgIHdvdWxkCiAgICogbWF0Y2ggYW55IHJlc291cmNlIHVuZGVyIHRoZSAnZm9sZGVycy8xMjMnIGZvbGRlci4KICAgKiBUaGUgdmFsdWUgbWF5IGJlIHtAY29kZSBudWxsfS4KICAgKi8KICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgcHJpdmF0ZSBqYXZhLmxhbmcuQm9vbGVhbiBzdXBwb3J0c1VuZGVyOwoKICAvKioKICAgKiBPcHRpb25hbC4gVGhlIEdvb2dsZSBDbG91ZCBDb25zb2xlIHdpbGwgdHJ5IHRvIGRlZmF1bHQgdG8gYSBjb25maWd1cmF0aW9uIHRoYXQgbWF0Y2hlcyB0aGUKICAgKiB2YWx1ZSBzcGVjaWZpZWQgaW4gdGhpcyBgQ29uc3RyYWludGAuCiAgICogQHJldHVybiB2YWx1ZSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRTdWdnZXN0ZWRWYWx1ZSgpIHsKICAgIHJldHVybiBzdWdnZXN0ZWRWYWx1ZTsKICB9CgogIC8qKgogICAqIE9wdGlvbmFsLiBUaGUgR29vZ2xlIENsb3VkIENvbnNvbGUgd2lsbCB0cnkgdG8gZGVmYXVsdCB0byBhIGNvbmZpZ3VyYXRpb24gdGhhdCBtYXRjaGVzIHRoZQogICAqIHZhbHVlIHNwZWNpZmllZCBpbiB0aGlzIGBDb25zdHJhaW50YC4KICAgKiBAcGFyYW0gc3VnZ2VzdGVkVmFsdWUgc3VnZ2VzdGVkVmFsdWUgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIExpc3RDb25zdHJhaW50IHNldFN1Z2dlc3RlZFZhbHVlKGphdmEubGFuZy5TdHJpbmcgc3VnZ2VzdGVkVmFsdWUpIHsKICAgIHRoaXMuc3VnZ2VzdGVkVmFsdWUgPSBzdWdnZXN0ZWRWYWx1ZTsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgLyoqCiAgICogSW5kaWNhdGVzIHdoZXRoZXIgc3VidHJlZXMgb2YgQ2xvdWQgUmVzb3VyY2UgTWFuYWdlciByZXNvdXJjZSBoaWVyYXJjaHkgY2FuIGJlIHVzZWQgaW4KICAgKiBgUG9saWN5LmFsbG93ZWRfdmFsdWVzYCBhbmQgYFBvbGljeS5kZW5pZWRfdmFsdWVzYC4gRm9yIGV4YW1wbGUsIGAidW5kZXI6Zm9sZGVycy8xMjMiYCB3b3VsZAogICAqIG1hdGNoIGFueSByZXNvdXJjZSB1bmRlciB0aGUgJ2ZvbGRlcnMvMTIzJyBmb2xkZXIuCiAgICogQHJldHVybiB2YWx1ZSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgamF2YS5sYW5nLkJvb2xlYW4gZ2V0U3VwcG9ydHNVbmRlcigpIHsKICAgIHJldHVybiBzdXBwb3J0c1VuZGVyOwogIH0KCiAgLyoqCiAgICogSW5kaWNhdGVzIHdoZXRoZXIgc3VidHJlZXMgb2YgQ2xvdWQgUmVzb3VyY2UgTWFuYWdlciByZXNvdXJjZSBoaWVyYXJjaHkgY2FuIGJlIHVzZWQgaW4KICAgKiBgUG9saWN5LmFsbG93ZWRfdmFsdWVzYCBhbmQgYFBvbGljeS5kZW5pZWRfdmFsdWVzYC4gRm9yIGV4YW1wbGUsIGAidW5kZXI6Zm9sZGVycy8xMjMiYCB3b3VsZAogICAqIG1hdGNoIGFueSByZXNvdXJjZSB1bmRlciB0aGUgJ2ZvbGRlcnMvMTIzJyBmb2xkZXIuCiAgICogQHBhcmFtIHN1cHBvcnRzVW5kZXIgc3VwcG9ydHNVbmRlciBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgTGlzdENvbnN0cmFpbnQgc2V0U3VwcG9ydHNVbmRlcihqYXZhLmxhbmcuQm9vbGVhbiBzdXBwb3J0c1VuZGVyKSB7CiAgICB0aGlzLnN1cHBvcnRzVW5kZXIgPSBzdXBwb3J0c1VuZGVyOwogICAgcmV0dXJuIHRoaXM7CiAgfQoKICBAT3ZlcnJpZGUKICBwdWJsaWMgTGlzdENvbnN0cmFpbnQgc2V0KFN0cmluZyBmaWVsZE5hbWUsIE9iamVjdCB2YWx1ZSkgewogICAgcmV0dXJuIChMaXN0Q29uc3RyYWludCkgc3VwZXIuc2V0KGZpZWxkTmFtZSwgdmFsdWUpOwogIH0KCiAgQE92ZXJyaWRlCiAgcHVibGljIExpc3RDb25zdHJhaW50IGNsb25lKCkgewogICAgcmV0dXJuIChMaXN0Q29uc3RyYWludCkgc3VwZXIuY2xvbmUoKTsKICB9Cgp9ClBLAwQUAAAAAAAAACEACLfSjXYLAAB2CwAASQAAAGNvbS9nb29nbGUvYXBpL3NlcnZpY2VzL2Nsb3VkcmVzb3VyY2VtYW5hZ2VyL21vZGVsL0xpc3RMaWVuc1Jlc3BvbnNlLmphdmEvKgogKiBDb3B5cmlnaHQgMjAxMCBHb29nbGUgSW5jLgogKgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQKICogaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UKICogaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzCiAqIG9yIGltcGxpZWQuIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMgdW5kZXIKICogdGhlIExpY2Vuc2UuCiAqLwovKgogKiBUaGlzIGNvZGUgd2FzIGdlbmVyYXRlZCBieSBodHRwczovL2dpdGh1Yi5jb20vZ29vZ2xlL2FwaXMtY2xpZW50LWdlbmVyYXRvci8KICogKGJ1aWxkOiAyMDE4LTEwLTA4IDE3OjQ1OjM5IFVUQykKICogb24gMjAyMC0wMy0xOSBhdCAwMjozODozMCBVVEMgCiAqIE1vZGlmeSBhdCB5b3VyIG93biByaXNrLgogKi8KCnBhY2thZ2UgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuY2xvdWRyZXNvdXJjZW1hbmFnZXIubW9kZWw7CgovKioKICogVGhlIHJlc3BvbnNlIG1lc3NhZ2UgZm9yIExpZW5zLkxpc3RMaWVucy4KICoKICogPHA+IFRoaXMgaXMgdGhlIEphdmEgZGF0YSBtb2RlbCBjbGFzcyB0aGF0IHNwZWNpZmllcyBob3cgdG8gcGFyc2Uvc2VyaWFsaXplIGludG8gdGhlIEpTT04gdGhhdCBpcwogKiB0cmFuc21pdHRlZCBvdmVyIEhUVFAgd2hlbiB3b3JraW5nIHdpdGggdGhlIENsb3VkIFJlc291cmNlIE1hbmFnZXIgQVBJLiBGb3IgYSBkZXRhaWxlZAogKiBleHBsYW5hdGlvbiBzZWU6CiAqIDxhIGhyZWY9Imh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL2FwaS1jbGllbnQtbGlicmFyeS9qYXZhL2dvb2dsZS1odHRwLWphdmEtY2xpZW50L2pzb24iPmh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL2FwaS1jbGllbnQtbGlicmFyeS9qYXZhL2dvb2dsZS1odHRwLWphdmEtY2xpZW50L2pzb248L2E+CiAqIDwvcD4KICoKICogQGF1dGhvciBHb29nbGUsIEluYy4KICovCkBTdXBwcmVzc1dhcm5pbmdzKCJqYXZhZG9jIikKcHVibGljIGZpbmFsIGNsYXNzIExpc3RMaWVuc1Jlc3BvbnNlIGV4dGVuZHMgY29tLmdvb2dsZS5hcGkuY2xpZW50Lmpzb24uR2VuZXJpY0pzb24gewoKICAvKioKICAgKiBBIGxpc3Qgb2YgTGllbnMuCiAgICogVGhlIHZhbHVlIG1heSBiZSB7QGNvZGUgbnVsbH0uCiAgICovCiAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8TGllbj4gbGllbnM7CgogIC8qKgogICAqIFRva2VuIHRvIHJldHJpZXZlIHRoZSBuZXh0IHBhZ2Ugb2YgcmVzdWx0cywgb3IgZW1wdHkgaWYgdGhlcmUgYXJlIG5vIG1vcmUgcmVzdWx0cyBpbiB0aGUgbGlzdC4KICAgKiBUaGUgdmFsdWUgbWF5IGJlIHtAY29kZSBudWxsfS4KICAgKi8KICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgcHJpdmF0ZSBqYXZhLmxhbmcuU3RyaW5nIG5leHRQYWdlVG9rZW47CgogIC8qKgogICAqIEEgbGlzdCBvZiBMaWVucy4KICAgKiBAcmV0dXJuIHZhbHVlIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxMaWVuPiBnZXRMaWVucygpIHsKICAgIHJldHVybiBsaWVuczsKICB9CgogIC8qKgogICAqIEEgbGlzdCBvZiBMaWVucy4KICAgKiBAcGFyYW0gbGllbnMgbGllbnMgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIExpc3RMaWVuc1Jlc3BvbnNlIHNldExpZW5zKGphdmEudXRpbC5MaXN0PExpZW4+IGxpZW5zKSB7CiAgICB0aGlzLmxpZW5zID0gbGllbnM7CiAgICByZXR1cm4gdGhpczsKICB9CgogIC8qKgogICAqIFRva2VuIHRvIHJldHJpZXZlIHRoZSBuZXh0IHBhZ2Ugb2YgcmVzdWx0cywgb3IgZW1wdHkgaWYgdGhlcmUgYXJlIG5vIG1vcmUgcmVzdWx0cyBpbiB0aGUgbGlzdC4KICAgKiBAcmV0dXJuIHZhbHVlIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldE5leHRQYWdlVG9rZW4oKSB7CiAgICByZXR1cm4gbmV4dFBhZ2VUb2tlbjsKICB9CgogIC8qKgogICAqIFRva2VuIHRvIHJldHJpZXZlIHRoZSBuZXh0IHBhZ2Ugb2YgcmVzdWx0cywgb3IgZW1wdHkgaWYgdGhlcmUgYXJlIG5vIG1vcmUgcmVzdWx0cyBpbiB0aGUgbGlzdC4KICAgKiBAcGFyYW0gbmV4dFBhZ2VUb2tlbiBuZXh0UGFnZVRva2VuIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBMaXN0TGllbnNSZXNwb25zZSBzZXROZXh0UGFnZVRva2VuKGphdmEubGFuZy5TdHJpbmcgbmV4dFBhZ2VUb2tlbikgewogICAgdGhpcy5uZXh0UGFnZVRva2VuID0gbmV4dFBhZ2VUb2tlbjsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgQE92ZXJyaWRlCiAgcHVibGljIExpc3RMaWVuc1Jlc3BvbnNlIHNldChTdHJpbmcgZmllbGROYW1lLCBPYmplY3QgdmFsdWUpIHsKICAgIHJldHVybiAoTGlzdExpZW5zUmVzcG9uc2UpIHN1cGVyLnNldChmaWVsZE5hbWUsIHZhbHVlKTsKICB9CgogIEBPdmVycmlkZQogIHB1YmxpYyBMaXN0TGllbnNSZXNwb25zZSBjbG9uZSgpIHsKICAgIHJldHVybiAoTGlzdExpZW5zUmVzcG9uc2UpIHN1cGVyLmNsb25lKCk7CiAgfQoKfQpQSwMEFAAAAAAAAAAhAFvDE9zlDQAA5Q0AAE4AAABjb20vZ29vZ2xlL2FwaS9zZXJ2aWNlcy9jbG91ZHJlc291cmNlbWFuYWdlci9tb2RlbC9MaXN0T3JnUG9saWNpZXNSZXF1ZXN0LmphdmEvKgogKiBDb3B5cmlnaHQgMjAxMCBHb29nbGUgSW5jLgogKgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQKICogaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UKICogaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzCiAqIG9yIGltcGxpZWQuIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMgdW5kZXIKICogdGhlIExpY2Vuc2UuCiAqLwovKgogKiBUaGlzIGNvZGUgd2FzIGdlbmVyYXRlZCBieSBodHRwczovL2dpdGh1Yi5jb20vZ29vZ2xlL2FwaXMtY2xpZW50LWdlbmVyYXRvci8KICogKGJ1aWxkOiAyMDE4LTEwLTA4IDE3OjQ1OjM5IFVUQykKICogb24gMjAyMC0wMy0xOSBhdCAwMjozODozMCBVVEMgCiAqIE1vZGlmeSBhdCB5b3VyIG93biByaXNrLgogKi8KCnBhY2thZ2UgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuY2xvdWRyZXNvdXJjZW1hbmFnZXIubW9kZWw7CgovKioKICogVGhlIHJlcXVlc3Qgc2VudCB0byB0aGUgTGlzdE9yZ1BvbGljaWVzIG1ldGhvZC4KICoKICogPHA+IFRoaXMgaXMgdGhlIEphdmEgZGF0YSBtb2RlbCBjbGFzcyB0aGF0IHNwZWNpZmllcyBob3cgdG8gcGFyc2Uvc2VyaWFsaXplIGludG8gdGhlIEpTT04gdGhhdCBpcwogKiB0cmFuc21pdHRlZCBvdmVyIEhUVFAgd2hlbiB3b3JraW5nIHdpdGggdGhlIENsb3VkIFJlc291cmNlIE1hbmFnZXIgQVBJLiBGb3IgYSBkZXRhaWxlZAogKiBleHBsYW5hdGlvbiBzZWU6CiAqIDxhIGhyZWY9Imh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL2FwaS1jbGllbnQtbGlicmFyeS9qYXZhL2dvb2dsZS1odHRwLWphdmEtY2xpZW50L2pzb24iPmh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL2FwaS1jbGllbnQtbGlicmFyeS9qYXZhL2dvb2dsZS1odHRwLWphdmEtY2xpZW50L2pzb248L2E+CiAqIDwvcD4KICoKICogQGF1dGhvciBHb29nbGUsIEluYy4KICovCkBTdXBwcmVzc1dhcm5pbmdzKCJqYXZhZG9jIikKcHVibGljIGZpbmFsIGNsYXNzIExpc3RPcmdQb2xpY2llc1JlcXVlc3QgZXh0ZW5kcyBjb20uZ29vZ2xlLmFwaS5jbGllbnQuanNvbi5HZW5lcmljSnNvbiB7CgogIC8qKgogICAqIFNpemUgb2YgdGhlIHBhZ2VzIHRvIGJlIHJldHVybmVkLiBUaGlzIGlzIGN1cnJlbnRseSB1bnN1cHBvcnRlZCBhbmQgd2lsbCBiZSBpZ25vcmVkLiBUaGUgc2VydmVyCiAgICogbWF5IGF0IGFueSBwb2ludCBzdGFydCB1c2luZyB0aGlzIGZpZWxkIHRvIGxpbWl0IHBhZ2Ugc2l6ZS4KICAgKiBUaGUgdmFsdWUgbWF5IGJlIHtAY29kZSBudWxsfS4KICAgKi8KICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgcHJpdmF0ZSBqYXZhLmxhbmcuSW50ZWdlciBwYWdlU2l6ZTsKCiAgLyoqCiAgICogUGFnZSB0b2tlbiB1c2VkIHRvIHJldHJpZXZlIHRoZSBuZXh0IHBhZ2UuIFRoaXMgaXMgY3VycmVudGx5IHVuc3VwcG9ydGVkIGFuZCB3aWxsIGJlIGlnbm9yZWQuCiAgICogVGhlIHNlcnZlciBtYXkgYXQgYW55IHBvaW50IHN0YXJ0IHVzaW5nIHRoaXMgZmllbGQuCiAgICogVGhlIHZhbHVlIG1heSBiZSB7QGNvZGUgbnVsbH0uCiAgICovCiAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogIHByaXZhdGUgamF2YS5sYW5nLlN0cmluZyBwYWdlVG9rZW47CgogIC8qKgogICAqIFNpemUgb2YgdGhlIHBhZ2VzIHRvIGJlIHJldHVybmVkLiBUaGlzIGlzIGN1cnJlbnRseSB1bnN1cHBvcnRlZCBhbmQgd2lsbCBiZSBpZ25vcmVkLiBUaGUgc2VydmVyCiAgICogbWF5IGF0IGFueSBwb2ludCBzdGFydCB1c2luZyB0aGlzIGZpZWxkIHRvIGxpbWl0IHBhZ2Ugc2l6ZS4KICAgKiBAcmV0dXJuIHZhbHVlIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBqYXZhLmxhbmcuSW50ZWdlciBnZXRQYWdlU2l6ZSgpIHsKICAgIHJldHVybiBwYWdlU2l6ZTsKICB9CgogIC8qKgogICAqIFNpemUgb2YgdGhlIHBhZ2VzIHRvIGJlIHJldHVybmVkLiBUaGlzIGlzIGN1cnJlbnRseSB1bnN1cHBvcnRlZCBhbmQgd2lsbCBiZSBpZ25vcmVkLiBUaGUgc2VydmVyCiAgICogbWF5IGF0IGFueSBwb2ludCBzdGFydCB1c2luZyB0aGlzIGZpZWxkIHRvIGxpbWl0IHBhZ2Ugc2l6ZS4KICAgKiBAcGFyYW0gcGFnZVNpemUgcGFnZVNpemUgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIExpc3RPcmdQb2xpY2llc1JlcXVlc3Qgc2V0UGFnZVNpemUoamF2YS5sYW5nLkludGVnZXIgcGFnZVNpemUpIHsKICAgIHRoaXMucGFnZVNpemUgPSBwYWdlU2l6ZTsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgLyoqCiAgICogUGFnZSB0b2tlbiB1c2VkIHRvIHJldHJpZXZlIHRoZSBuZXh0IHBhZ2UuIFRoaXMgaXMgY3VycmVudGx5IHVuc3VwcG9ydGVkIGFuZCB3aWxsIGJlIGlnbm9yZWQuCiAgICogVGhlIHNlcnZlciBtYXkgYXQgYW55IHBvaW50IHN0YXJ0IHVzaW5nIHRoaXMgZmllbGQuCiAgICogQHJldHVybiB2YWx1ZSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRQYWdlVG9rZW4oKSB7CiAgICByZXR1cm4gcGFnZVRva2VuOwogIH0KCiAgLyoqCiAgICogUGFnZSB0b2tlbiB1c2VkIHRvIHJldHJpZXZlIHRoZSBuZXh0IHBhZ2UuIFRoaXMgaXMgY3VycmVudGx5IHVuc3VwcG9ydGVkIGFuZCB3aWxsIGJlIGlnbm9yZWQuCiAgICogVGhlIHNlcnZlciBtYXkgYXQgYW55IHBvaW50IHN0YXJ0IHVzaW5nIHRoaXMgZmllbGQuCiAgICogQHBhcmFtIHBhZ2VUb2tlbiBwYWdlVG9rZW4gb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIExpc3RPcmdQb2xpY2llc1JlcXVlc3Qgc2V0UGFnZVRva2VuKGphdmEubGFuZy5TdHJpbmcgcGFnZVRva2VuKSB7CiAgICB0aGlzLnBhZ2VUb2tlbiA9IHBhZ2VUb2tlbjsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgQE92ZXJyaWRlCiAgcHVibGljIExpc3RPcmdQb2xpY2llc1JlcXVlc3Qgc2V0KFN0cmluZyBmaWVsZE5hbWUsIE9iamVjdCB2YWx1ZSkgewogICAgcmV0dXJuIChMaXN0T3JnUG9saWNpZXNSZXF1ZXN0KSBzdXBlci5zZXQoZmllbGROYW1lLCB2YWx1ZSk7CiAgfQoKICBAT3ZlcnJpZGUKICBwdWJsaWMgTGlzdE9yZ1BvbGljaWVzUmVxdWVzdCBjbG9uZSgpIHsKICAgIHJldHVybiAoTGlzdE9yZ1BvbGljaWVzUmVxdWVzdCkgc3VwZXIuY2xvbmUoKTsKICB9Cgp9ClBLAwQUAAAAAAAAACEAZXRFwG4NAABuDQAATwAAAGNvbS9nb29nbGUvYXBpL3NlcnZpY2VzL2Nsb3VkcmVzb3VyY2VtYW5hZ2VyL21vZGVsL0xpc3RPcmdQb2xpY2llc1Jlc3BvbnNlLmphdmEvKgogKiBDb3B5cmlnaHQgMjAxMCBHb29nbGUgSW5jLgogKgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQKICogaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UKICogaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzCiAqIG9yIGltcGxpZWQuIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMgdW5kZXIKICogdGhlIExpY2Vuc2UuCiAqLwovKgogKiBUaGlzIGNvZGUgd2FzIGdlbmVyYXRlZCBieSBodHRwczovL2dpdGh1Yi5jb20vZ29vZ2xlL2FwaXMtY2xpZW50LWdlbmVyYXRvci8KICogKGJ1aWxkOiAyMDE4LTEwLTA4IDE3OjQ1OjM5IFVUQykKICogb24gMjAyMC0wMy0xOSBhdCAwMjozODozMCBVVEMgCiAqIE1vZGlmeSBhdCB5b3VyIG93biByaXNrLgogKi8KCnBhY2thZ2UgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuY2xvdWRyZXNvdXJjZW1hbmFnZXIubW9kZWw7CgovKioKICogVGhlIHJlc3BvbnNlIHJldHVybmVkIGZyb20gdGhlIExpc3RPcmdQb2xpY2llcyBtZXRob2QuIEl0IHdpbGwgYmUgZW1wdHkgaWYgbm8gYFBvbGljaWVzYCBhcmUgc2V0CiAqIG9uIHRoZSByZXNvdXJjZS4KICoKICogPHA+IFRoaXMgaXMgdGhlIEphdmEgZGF0YSBtb2RlbCBjbGFzcyB0aGF0IHNwZWNpZmllcyBob3cgdG8gcGFyc2Uvc2VyaWFsaXplIGludG8gdGhlIEpTT04gdGhhdCBpcwogKiB0cmFuc21pdHRlZCBvdmVyIEhUVFAgd2hlbiB3b3JraW5nIHdpdGggdGhlIENsb3VkIFJlc291cmNlIE1hbmFnZXIgQVBJLiBGb3IgYSBkZXRhaWxlZAogKiBleHBsYW5hdGlvbiBzZWU6CiAqIDxhIGhyZWY9Imh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL2FwaS1jbGllbnQtbGlicmFyeS9qYXZhL2dvb2dsZS1odHRwLWphdmEtY2xpZW50L2pzb24iPmh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL2FwaS1jbGllbnQtbGlicmFyeS9qYXZhL2dvb2dsZS1odHRwLWphdmEtY2xpZW50L2pzb248L2E+CiAqIDwvcD4KICoKICogQGF1dGhvciBHb29nbGUsIEluYy4KICovCkBTdXBwcmVzc1dhcm5pbmdzKCJqYXZhZG9jIikKcHVibGljIGZpbmFsIGNsYXNzIExpc3RPcmdQb2xpY2llc1Jlc3BvbnNlIGV4dGVuZHMgY29tLmdvb2dsZS5hcGkuY2xpZW50Lmpzb24uR2VuZXJpY0pzb24gewoKICAvKioKICAgKiBQYWdlIHRva2VuIHVzZWQgdG8gcmV0cmlldmUgdGhlIG5leHQgcGFnZS4gVGhpcyBpcyBjdXJyZW50bHkgbm90IHVzZWQsIGJ1dCB0aGUgc2VydmVyIG1heSBhdAogICAqIGFueSBwb2ludCBzdGFydCBzdXBwbHlpbmcgYSB2YWxpZCB0b2tlbi4KICAgKiBUaGUgdmFsdWUgbWF5IGJlIHtAY29kZSBudWxsfS4KICAgKi8KICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgcHJpdmF0ZSBqYXZhLmxhbmcuU3RyaW5nIG5leHRQYWdlVG9rZW47CgogIC8qKgogICAqIFRoZSBgUG9saWNpZXNgIHRoYXQgYXJlIHNldCBvbiB0aGUgcmVzb3VyY2UuIEl0IHdpbGwgYmUgZW1wdHkgaWYgbm8gYFBvbGljaWVzYCBhcmUgc2V0LgogICAqIFRoZSB2YWx1ZSBtYXkgYmUge0Bjb2RlIG51bGx9LgogICAqLwogIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICBwcml2YXRlIGphdmEudXRpbC5MaXN0PE9yZ1BvbGljeT4gcG9saWNpZXM7CgogIC8qKgogICAqIFBhZ2UgdG9rZW4gdXNlZCB0byByZXRyaWV2ZSB0aGUgbmV4dCBwYWdlLiBUaGlzIGlzIGN1cnJlbnRseSBub3QgdXNlZCwgYnV0IHRoZSBzZXJ2ZXIgbWF5IGF0CiAgICogYW55IHBvaW50IHN0YXJ0IHN1cHBseWluZyBhIHZhbGlkIHRva2VuLgogICAqIEByZXR1cm4gdmFsdWUgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TmV4dFBhZ2VUb2tlbigpIHsKICAgIHJldHVybiBuZXh0UGFnZVRva2VuOwogIH0KCiAgLyoqCiAgICogUGFnZSB0b2tlbiB1c2VkIHRvIHJldHJpZXZlIHRoZSBuZXh0IHBhZ2UuIFRoaXMgaXMgY3VycmVudGx5IG5vdCB1c2VkLCBidXQgdGhlIHNlcnZlciBtYXkgYXQKICAgKiBhbnkgcG9pbnQgc3RhcnQgc3VwcGx5aW5nIGEgdmFsaWQgdG9rZW4uCiAgICogQHBhcmFtIG5leHRQYWdlVG9rZW4gbmV4dFBhZ2VUb2tlbiBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgTGlzdE9yZ1BvbGljaWVzUmVzcG9uc2Ugc2V0TmV4dFBhZ2VUb2tlbihqYXZhLmxhbmcuU3RyaW5nIG5leHRQYWdlVG9rZW4pIHsKICAgIHRoaXMubmV4dFBhZ2VUb2tlbiA9IG5leHRQYWdlVG9rZW47CiAgICByZXR1cm4gdGhpczsKICB9CgogIC8qKgogICAqIFRoZSBgUG9saWNpZXNgIHRoYXQgYXJlIHNldCBvbiB0aGUgcmVzb3VyY2UuIEl0IHdpbGwgYmUgZW1wdHkgaWYgbm8gYFBvbGljaWVzYCBhcmUgc2V0LgogICAqIEByZXR1cm4gdmFsdWUgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIGphdmEudXRpbC5MaXN0PE9yZ1BvbGljeT4gZ2V0UG9saWNpZXMoKSB7CiAgICByZXR1cm4gcG9saWNpZXM7CiAgfQoKICAvKioKICAgKiBUaGUgYFBvbGljaWVzYCB0aGF0IGFyZSBzZXQgb24gdGhlIHJlc291cmNlLiBJdCB3aWxsIGJlIGVtcHR5IGlmIG5vIGBQb2xpY2llc2AgYXJlIHNldC4KICAgKiBAcGFyYW0gcG9saWNpZXMgcG9saWNpZXMgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIExpc3RPcmdQb2xpY2llc1Jlc3BvbnNlIHNldFBvbGljaWVzKGphdmEudXRpbC5MaXN0PE9yZ1BvbGljeT4gcG9saWNpZXMpIHsKICAgIHRoaXMucG9saWNpZXMgPSBwb2xpY2llczsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgQE92ZXJyaWRlCiAgcHVibGljIExpc3RPcmdQb2xpY2llc1Jlc3BvbnNlIHNldChTdHJpbmcgZmllbGROYW1lLCBPYmplY3QgdmFsdWUpIHsKICAgIHJldHVybiAoTGlzdE9yZ1BvbGljaWVzUmVzcG9uc2UpIHN1cGVyLnNldChmaWVsZE5hbWUsIHZhbHVlKTsKICB9CgogIEBPdmVycmlkZQogIHB1YmxpYyBMaXN0T3JnUG9saWNpZXNSZXNwb25zZSBjbG9uZSgpIHsKICAgIHJldHVybiAoTGlzdE9yZ1BvbGljaWVzUmVzcG9uc2UpIHN1cGVyLmNsb25lKCk7CiAgfQoKfQpQSwMEFAAAAAAAAAAhAPFm6GDPUAAAz1AAAEIAAABjb20vZ29vZ2xlL2FwaS9zZXJ2aWNlcy9jbG91ZHJlc291cmNlbWFuYWdlci9tb2RlbC9MaXN0UG9saWN5LmphdmEvKgogKiBDb3B5cmlnaHQgMjAxMCBHb29nbGUgSW5jLgogKgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQKICogaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UKICogaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzCiAqIG9yIGltcGxpZWQuIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMgdW5kZXIKICogdGhlIExpY2Vuc2UuCiAqLwovKgogKiBUaGlzIGNvZGUgd2FzIGdlbmVyYXRlZCBieSBodHRwczovL2dpdGh1Yi5jb20vZ29vZ2xlL2FwaXMtY2xpZW50LWdlbmVyYXRvci8KICogKGJ1aWxkOiAyMDE4LTEwLTA4IDE3OjQ1OjM5IFVUQykKICogb24gMjAyMC0wMy0xOSBhdCAwMjozODozMCBVVEMgCiAqIE1vZGlmeSBhdCB5b3VyIG93biByaXNrLgogKi8KCnBhY2thZ2UgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuY2xvdWRyZXNvdXJjZW1hbmFnZXIubW9kZWw7CgovKioKICogVXNlZCBpbiBgcG9saWN5X3R5cGVgIHRvIHNwZWNpZnkgaG93IGBsaXN0X3BvbGljeWAgYmVoYXZlcyBhdCB0aGlzIHJlc291cmNlLgogKgogKiBgTGlzdFBvbGljeWAgY2FuIGRlZmluZSBzcGVjaWZpYyB2YWx1ZXMgYW5kIHN1YnRyZWVzIG9mIENsb3VkIFJlc291cmNlIE1hbmFnZXIgcmVzb3VyY2UgaGllcmFyY2h5CiAqIChgT3JnYW5pemF0aW9uc2AsIGBGb2xkZXJzYCwgYFByb2plY3RzYCkgdGhhdCBhcmUgYWxsb3dlZCBvciBkZW5pZWQgYnkgc2V0dGluZyB0aGUKICogYGFsbG93ZWRfdmFsdWVzYCBhbmQgYGRlbmllZF92YWx1ZXNgIGZpZWxkcy4gVGhpcyBpcyBhY2hpZXZlZCBieSB1c2luZyB0aGUgYHVuZGVyOmAgYW5kIG9wdGlvbmFsCiAqIGBpczpgIHByZWZpeGVzLiBUaGUgYHVuZGVyOmAgcHJlZml4IGlzIHVzZWQgdG8gZGVub3RlIHJlc291cmNlIHN1YnRyZWUgdmFsdWVzLiBUaGUgYGlzOmAgcHJlZml4CiAqIGlzIHVzZWQgdG8gZGVub3RlIHNwZWNpZmljIHZhbHVlcywgYW5kIGlzIHJlcXVpcmVkIG9ubHkgaWYgdGhlIHZhbHVlIGNvbnRhaW5zIGEgIjoiLiBWYWx1ZXMKICogcHJlZml4ZWQgd2l0aCAiaXM6IiBhcmUgdHJlYXRlZCB0aGUgc2FtZSBhcyB2YWx1ZXMgd2l0aCBubyBwcmVmaXguIEFuY2VzdHJ5IHN1YnRyZWVzIG11c3QgYmUgaW4KICogb25lIG9mIHRoZSBmb2xsb3dpbmcgZm9ybWF0czogICAgIC0gInByb2plY3RzLyIsIGUuZy4gInByb2plY3RzL3Rva3lvLXJhaW4tMTIzIiAgICAgLSAiZm9sZGVycy8iLAogKiBlLmcuICJmb2xkZXJzLzEyMzQiICAgICAtICJvcmdhbml6YXRpb25zLyIsIGUuZy4gIm9yZ2FuaXphdGlvbnMvMTIzNCIgVGhlIGBzdXBwb3J0c191bmRlcmAgZmllbGQKICogb2YgdGhlIGFzc29jaWF0ZWQgYENvbnN0cmFpbnRgICBkZWZpbmVzIHdoZXRoZXIgYW5jZXN0cnkgcHJlZml4ZXMgY2FuIGJlIHVzZWQuIFlvdSBjYW4gc2V0CiAqIGBhbGxvd2VkX3ZhbHVlc2AgYW5kIGBkZW5pZWRfdmFsdWVzYCBpbiB0aGUgc2FtZSBgUG9saWN5YCBpZiBgYWxsX3ZhbHVlc2AgaXMKICogYEFMTF9WQUxVRVNfVU5TUEVDSUZJRURgLiBgQUxMT1dgIG9yIGBERU5ZYCBhcmUgdXNlZCB0byBhbGxvdyBvciBkZW55IGFsbCB2YWx1ZXMuIElmIGBhbGxfdmFsdWVzYAogKiBpcyBzZXQgdG8gZWl0aGVyIGBBTExPV2Agb3IgYERFTllgLCBgYWxsb3dlZF92YWx1ZXNgIGFuZCBgZGVuaWVkX3ZhbHVlc2AgbXVzdCBiZSB1bnNldC4KICoKICogPHA+IFRoaXMgaXMgdGhlIEphdmEgZGF0YSBtb2RlbCBjbGFzcyB0aGF0IHNwZWNpZmllcyBob3cgdG8gcGFyc2Uvc2VyaWFsaXplIGludG8gdGhlIEpTT04gdGhhdCBpcwogKiB0cmFuc21pdHRlZCBvdmVyIEhUVFAgd2hlbiB3b3JraW5nIHdpdGggdGhlIENsb3VkIFJlc291cmNlIE1hbmFnZXIgQVBJLiBGb3IgYSBkZXRhaWxlZAogKiBleHBsYW5hdGlvbiBzZWU6CiAqIDxhIGhyZWY9Imh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL2FwaS1jbGllbnQtbGlicmFyeS9qYXZhL2dvb2dsZS1odHRwLWphdmEtY2xpZW50L2pzb24iPmh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL2FwaS1jbGllbnQtbGlicmFyeS9qYXZhL2dvb2dsZS1odHRwLWphdmEtY2xpZW50L2pzb248L2E+CiAqIDwvcD4KICoKICogQGF1dGhvciBHb29nbGUsIEluYy4KICovCkBTdXBwcmVzc1dhcm5pbmdzKCJqYXZhZG9jIikKcHVibGljIGZpbmFsIGNsYXNzIExpc3RQb2xpY3kgZXh0ZW5kcyBjb20uZ29vZ2xlLmFwaS5jbGllbnQuanNvbi5HZW5lcmljSnNvbiB7CgogIC8qKgogICAqIFRoZSBwb2xpY3kgYWxsX3ZhbHVlcyBzdGF0ZS4KICAgKiBUaGUgdmFsdWUgbWF5IGJlIHtAY29kZSBudWxsfS4KICAgKi8KICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgcHJpdmF0ZSBqYXZhLmxhbmcuU3RyaW5nIGFsbFZhbHVlczsKCiAgLyoqCiAgICogTGlzdCBvZiB2YWx1ZXMgYWxsb3dlZCAgYXQgdGhpcyByZXNvdXJjZS4gQ2FuIG9ubHkgYmUgc2V0IGlmIGBhbGxfdmFsdWVzYCBpcyBzZXQgdG8KICAgKiBgQUxMX1ZBTFVFU19VTlNQRUNJRklFRGAuCiAgICogVGhlIHZhbHVlIG1heSBiZSB7QGNvZGUgbnVsbH0uCiAgICovCiAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLlN0cmluZz4gYWxsb3dlZFZhbHVlczsKCiAgLyoqCiAgICogTGlzdCBvZiB2YWx1ZXMgZGVuaWVkIGF0IHRoaXMgcmVzb3VyY2UuIENhbiBvbmx5IGJlIHNldCBpZiBgYWxsX3ZhbHVlc2AgaXMgc2V0IHRvCiAgICogYEFMTF9WQUxVRVNfVU5TUEVDSUZJRURgLgogICAqIFRoZSB2YWx1ZSBtYXkgYmUge0Bjb2RlIG51bGx9LgogICAqLwogIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICBwcml2YXRlIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5TdHJpbmc+IGRlbmllZFZhbHVlczsKCiAgLyoqCiAgICogRGV0ZXJtaW5lcyB0aGUgaW5oZXJpdGFuY2UgYmVoYXZpb3IgZm9yIHRoaXMgYFBvbGljeWAuCiAgICoKICAgKiBCeSBkZWZhdWx0LCBhIGBMaXN0UG9saWN5YCBzZXQgYXQgYSByZXNvdXJjZSBzdXBlcmNlZGVzIGFueSBgUG9saWN5YCBzZXQgYW55d2hlcmUgdXAgdGhlCiAgICogcmVzb3VyY2UgaGllcmFyY2h5LiBIb3dldmVyLCBpZiBgaW5oZXJpdF9mcm9tX3BhcmVudGAgaXMgc2V0IHRvIGB0cnVlYCwgdGhlbiB0aGUgdmFsdWVzIGZyb20KICAgKiB0aGUgZWZmZWN0aXZlIGBQb2xpY3lgIG9mIHRoZSBwYXJlbnQgcmVzb3VyY2UgYXJlIGluaGVyaXRlZCwgbWVhbmluZyB0aGUgdmFsdWVzIHNldCBpbiB0aGlzCiAgICogYFBvbGljeWAgYXJlIGFkZGVkIHRvIHRoZSB2YWx1ZXMgaW5oZXJpdGVkIHVwIHRoZSBoaWVyYXJjaHkuCiAgICoKICAgKiBTZXR0aW5nIGBQb2xpY3lgIGhpZXJhcmNoaWVzIHRoYXQgaW5oZXJpdCBib3RoIGFsbG93ZWQgdmFsdWVzIGFuZCBkZW5pZWQgdmFsdWVzIGlzbid0CiAgICogcmVjb21tZW5kZWQgaW4gbW9zdCBjaXJjdW1zdGFuY2VzIHRvIGtlZXAgdGhlIGNvbmZpZ3VyYXRpb24gc2ltcGxlIGFuZCB1bmRlcnN0YW5kYWJsZS4gSG93ZXZlciwKICAgKiBpdCBpcyBwb3NzaWJsZSB0byBzZXQgYSBgUG9saWN5YCB3aXRoIGBhbGxvd2VkX3ZhbHVlc2Agc2V0IHRoYXQgaW5oZXJpdHMgYSBgUG9saWN5YCB3aXRoCiAgICogYGRlbmllZF92YWx1ZXNgIHNldC4gSW4gdGhpcyBjYXNlLCB0aGUgdmFsdWVzIHRoYXQgYXJlIGFsbG93ZWQgbXVzdCBiZSBpbiBgYWxsb3dlZF92YWx1ZXNgIGFuZAogICAqIG5vdCBwcmVzZW50IGluIGBkZW5pZWRfdmFsdWVzYC4KICAgKgogICAqIEZvciBleGFtcGxlLCBzdXBwb3NlIHlvdSBoYXZlIGEgYENvbnN0cmFpbnRgIGBjb25zdHJhaW50cy9zZXJ2aWNldXNlci5zZXJ2aWNlc2AsIHdoaWNoIGhhcyBhCiAgICogYGNvbnN0cmFpbnRfdHlwZWAgb2YgYGxpc3RfY29uc3RyYWludGAsIGFuZCB3aXRoIGBjb25zdHJhaW50X2RlZmF1bHRgIHNldCB0byBgQUxMT1dgLiBTdXBwb3NlCiAgICogdGhhdCBhdCB0aGUgT3JnYW5pemF0aW9uIGxldmVsLCBhIGBQb2xpY3lgIGlzIGFwcGxpZWQgdGhhdCByZXN0cmljdHMgdGhlIGFsbG93ZWQgQVBJCiAgICogYWN0aXZhdGlvbnMgdG8ge2BFMWAsIGBFMmB9LiBUaGVuLCBpZiBhIGBQb2xpY3lgIGlzIGFwcGxpZWQgdG8gYSBwcm9qZWN0IGJlbG93IHRoZSBPcmdhbml6YXRpb24KICAgKiB0aGF0IGhhcyBgaW5oZXJpdF9mcm9tX3BhcmVudGAgc2V0IHRvIGBmYWxzZWAgYW5kIGZpZWxkIGFsbF92YWx1ZXMgc2V0IHRvIERFTlksIHRoZW4gYW4gYXR0ZW1wdAogICAqIHRvIGFjdGl2YXRlIGFueSBBUEkgd2lsbCBiZSBkZW5pZWQuCiAgICoKICAgKiBUaGUgZm9sbG93aW5nIGV4YW1wbGVzIGRlbW9uc3RyYXRlIGRpZmZlcmVudCBwb3NzaWJsZSBsYXllcmluZ3MgZm9yIGBwcm9qZWN0cy9iYXJgIHBhcmVudGVkIGJ5CiAgICogYG9yZ2FuaXphdGlvbnMvZm9vYDoKICAgKgogICAqIEV4YW1wbGUgMSAobm8gaW5oZXJpdGVkIHZhbHVlcyk6ICAgYG9yZ2FuaXphdGlvbnMvZm9vYCBoYXMgYSBgUG9saWN5YCB3aXRoIHZhbHVlczoKICAgKiB7YWxsb3dlZF92YWx1ZXM6ICJFMSIgYWxsb3dlZF92YWx1ZXM6IkUyIn0gICBgcHJvamVjdHMvYmFyYCBoYXMgYGluaGVyaXRfZnJvbV9wYXJlbnRgIGBmYWxzZWAKICAgKiBhbmQgdmFsdWVzOiAgICAge2FsbG93ZWRfdmFsdWVzOiAiRTMiIGFsbG93ZWRfdmFsdWVzOiAiRTQifSBUaGUgYWNjZXB0ZWQgdmFsdWVzIGF0CiAgICogYG9yZ2FuaXphdGlvbnMvZm9vYCBhcmUgYEUxYCwgYEUyYC4gVGhlIGFjY2VwdGVkIHZhbHVlcyBhdCBgcHJvamVjdHMvYmFyYCBhcmUgYEUzYCwgYW5kIGBFNGAuCiAgICoKICAgKiBFeGFtcGxlIDIgKGluaGVyaXRlZCB2YWx1ZXMpOiAgIGBvcmdhbml6YXRpb25zL2Zvb2AgaGFzIGEgYFBvbGljeWAgd2l0aCB2YWx1ZXM6CiAgICoge2FsbG93ZWRfdmFsdWVzOiAiRTEiIGFsbG93ZWRfdmFsdWVzOiJFMiJ9ICAgYHByb2plY3RzL2JhcmAgaGFzIGEgYFBvbGljeWAgd2l0aCB2YWx1ZXM6CiAgICoge3ZhbHVlOiAiRTMiIHZhbHVlOiAiRTQiIGluaGVyaXRfZnJvbV9wYXJlbnQ6IHRydWV9IFRoZSBhY2NlcHRlZCB2YWx1ZXMgYXQgYG9yZ2FuaXphdGlvbnMvZm9vYAogICAqIGFyZSBgRTFgLCBgRTJgLiBUaGUgYWNjZXB0ZWQgdmFsdWVzIGF0IGBwcm9qZWN0cy9iYXJgIGFyZSBgRTFgLCBgRTJgLCBgRTNgLCBhbmQgYEU0YC4KICAgKgogICAqIEV4YW1wbGUgMyAoaW5oZXJpdGluZyBib3RoIGFsbG93ZWQgYW5kIGRlbmllZCB2YWx1ZXMpOiAgIGBvcmdhbml6YXRpb25zL2Zvb2AgaGFzIGEgYFBvbGljeWAKICAgKiB3aXRoIHZhbHVlczogICAgIHthbGxvd2VkX3ZhbHVlczogIkUxIiBhbGxvd2VkX3ZhbHVlczogIkUyIn0gICBgcHJvamVjdHMvYmFyYCBoYXMgYSBgUG9saWN5YAogICAqIHdpdGg6ICAgICB7ZGVuaWVkX3ZhbHVlczogIkUxIn0gVGhlIGFjY2VwdGVkIHZhbHVlcyBhdCBgb3JnYW5pemF0aW9ucy9mb29gIGFyZSBgRTFgLCBgRTJgLiBUaGUKICAgKiB2YWx1ZSBhY2NlcHRlZCBhdCBgcHJvamVjdHMvYmFyYCBpcyBgRTJgLgogICAqCiAgICogRXhhbXBsZSA0IChSZXN0b3JlRGVmYXVsdCk6ICAgYG9yZ2FuaXphdGlvbnMvZm9vYCBoYXMgYSBgUG9saWN5YCB3aXRoIHZhbHVlczoKICAgKiB7YWxsb3dlZF92YWx1ZXM6ICJFMSIgYWxsb3dlZF92YWx1ZXM6IkUyIn0gICBgcHJvamVjdHMvYmFyYCBoYXMgYSBgUG9saWN5YCB3aXRoIHZhbHVlczoKICAgKiB7UmVzdG9yZURlZmF1bHQ6IHt9fSBUaGUgYWNjZXB0ZWQgdmFsdWVzIGF0IGBvcmdhbml6YXRpb25zL2Zvb2AgYXJlIGBFMWAsIGBFMmAuIFRoZSBhY2NlcHRlZAogICAqIHZhbHVlcyBhdCBgcHJvamVjdHMvYmFyYCBhcmUgZWl0aGVyIGFsbCBvciBub25lIGRlcGVuZGluZyBvbiB0aGUgdmFsdWUgb2YgYGNvbnN0cmFpbnRfZGVmYXVsdGAKICAgKiAoaWYgYEFMTE9XYCwgYWxsOyBpZiBgREVOWWAsIG5vbmUpLgogICAqCiAgICogRXhhbXBsZSA1IChubyBwb2xpY3kgaW5oZXJpdHMgcGFyZW50IHBvbGljeSk6ICAgYG9yZ2FuaXphdGlvbnMvZm9vYCBoYXMgbm8gYFBvbGljeWAgc2V0LgogICAqIGBwcm9qZWN0cy9iYXJgIGhhcyBubyBgUG9saWN5YCBzZXQuIFRoZSBhY2NlcHRlZCB2YWx1ZXMgYXQgYm90aCBsZXZlbHMgYXJlIGVpdGhlciBhbGwgb3Igbm9uZQogICAqIGRlcGVuZGluZyBvbiB0aGUgdmFsdWUgb2YgYGNvbnN0cmFpbnRfZGVmYXVsdGAgKGlmIGBBTExPV2AsIGFsbDsgaWYgYERFTllgLCBub25lKS4KICAgKgogICAqIEV4YW1wbGUgNiAoTGlzdENvbnN0cmFpbnQgYWxsb3dpbmcgYWxsKTogICBgb3JnYW5pemF0aW9ucy9mb29gIGhhcyBhIGBQb2xpY3lgIHdpdGggdmFsdWVzOgogICAqIHthbGxvd2VkX3ZhbHVlczogIkUxIiBhbGxvd2VkX3ZhbHVlczogIkUyIn0gICBgcHJvamVjdHMvYmFyYCBoYXMgYSBgUG9saWN5YCB3aXRoOiAgICAge2FsbDoKICAgKiBBTExPV30gVGhlIGFjY2VwdGVkIHZhbHVlcyBhdCBgb3JnYW5pemF0aW9ucy9mb29gIGFyZSBgRTFgLCBFMmAuIEFueSB2YWx1ZSBpcyBhY2NlcHRlZCBhdAogICAqIGBwcm9qZWN0cy9iYXJgLgogICAqCiAgICogRXhhbXBsZSA3IChMaXN0Q29uc3RyYWludCBhbGxvd2luZyBub25lKTogICBgb3JnYW5pemF0aW9ucy9mb29gIGhhcyBhIGBQb2xpY3lgIHdpdGggdmFsdWVzOgogICAqIHthbGxvd2VkX3ZhbHVlczogIkUxIiBhbGxvd2VkX3ZhbHVlczogIkUyIn0gICBgcHJvamVjdHMvYmFyYCBoYXMgYSBgUG9saWN5YCB3aXRoOiAgICAge2FsbDoKICAgKiBERU5ZfSBUaGUgYWNjZXB0ZWQgdmFsdWVzIGF0IGBvcmdhbml6YXRpb25zL2Zvb2AgYXJlIGBFMWAsIEUyYC4gTm8gdmFsdWUgaXMgYWNjZXB0ZWQgYXQKICAgKiBgcHJvamVjdHMvYmFyYC4KICAgKgogICAqIEV4YW1wbGUgMTAgKGFsbG93ZWQgYW5kIGRlbmllZCBzdWJ0cmVlcyBvZiBSZXNvdXJjZSBNYW5hZ2VyIGhpZXJhcmNoeSk6IEdpdmVuIHRoZSBmb2xsb3dpbmcKICAgKiByZXNvdXJjZSBoaWVyYXJjaHkgICBPMS0+e0YxLCBGMn07IEYxLT57UDF9OyBGMi0+e1AyLCBQM30sICAgYG9yZ2FuaXphdGlvbnMvZm9vYCBoYXMgYSBgUG9saWN5YAogICAqIHdpdGggdmFsdWVzOiAgICAge2FsbG93ZWRfdmFsdWVzOiAidW5kZXI6b3JnYW5pemF0aW9ucy9PMSJ9ICAgYHByb2plY3RzL2JhcmAgaGFzIGEgYFBvbGljeWAKICAgKiB3aXRoOiAgICAge2FsbG93ZWRfdmFsdWVzOiAidW5kZXI6cHJvamVjdHMvUDMifSAgICAge2RlbmllZF92YWx1ZXM6ICJ1bmRlcjpmb2xkZXJzL0YyIn0gVGhlCiAgICogYWNjZXB0ZWQgdmFsdWVzIGF0IGBvcmdhbml6YXRpb25zL2Zvb2AgYXJlIGBvcmdhbml6YXRpb25zL08xYCwgICBgZm9sZGVycy9GMWAsIGBmb2xkZXJzL0YyYCwKICAgKiBgcHJvamVjdHMvUDFgLCBgcHJvamVjdHMvUDJgLCAgIGBwcm9qZWN0cy9QM2AuIFRoZSBhY2NlcHRlZCB2YWx1ZXMgYXQgYHByb2plY3RzL2JhcmAgYXJlCiAgICogYG9yZ2FuaXphdGlvbnMvTzFgLCAgIGBmb2xkZXJzL0YxYCwgYHByb2plY3RzL1AxYC4KICAgKiBUaGUgdmFsdWUgbWF5IGJlIHtAY29kZSBudWxsfS4KICAgKi8KICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgcHJpdmF0ZSBqYXZhLmxhbmcuQm9vbGVhbiBpbmhlcml0RnJvbVBhcmVudDsKCiAgLyoqCiAgICogT3B0aW9uYWwuIFRoZSBHb29nbGUgQ2xvdWQgQ29uc29sZSB3aWxsIHRyeSB0byBkZWZhdWx0IHRvIGEgY29uZmlndXJhdGlvbiB0aGF0IG1hdGNoZXMgdGhlCiAgICogdmFsdWUgc3BlY2lmaWVkIGluIHRoaXMgYFBvbGljeWAuIElmIGBzdWdnZXN0ZWRfdmFsdWVgIGlzIG5vdCBzZXQsIGl0IHdpbGwgaW5oZXJpdCB0aGUgdmFsdWUKICAgKiBzcGVjaWZpZWQgaGlnaGVyIGluIHRoZSBoaWVyYXJjaHksIHVubGVzcyBgaW5oZXJpdF9mcm9tX3BhcmVudGAgaXMgYGZhbHNlYC4KICAgKiBUaGUgdmFsdWUgbWF5IGJlIHtAY29kZSBudWxsfS4KICAgKi8KICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgcHJpdmF0ZSBqYXZhLmxhbmcuU3RyaW5nIHN1Z2dlc3RlZFZhbHVlOwoKICAvKioKICAgKiBUaGUgcG9saWN5IGFsbF92YWx1ZXMgc3RhdGUuCiAgICogQHJldHVybiB2YWx1ZSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRBbGxWYWx1ZXMoKSB7CiAgICByZXR1cm4gYWxsVmFsdWVzOwogIH0KCiAgLyoqCiAgICogVGhlIHBvbGljeSBhbGxfdmFsdWVzIHN0YXRlLgogICAqIEBwYXJhbSBhbGxWYWx1ZXMgYWxsVmFsdWVzIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBMaXN0UG9saWN5IHNldEFsbFZhbHVlcyhqYXZhLmxhbmcuU3RyaW5nIGFsbFZhbHVlcykgewogICAgdGhpcy5hbGxWYWx1ZXMgPSBhbGxWYWx1ZXM7CiAgICByZXR1cm4gdGhpczsKICB9CgogIC8qKgogICAqIExpc3Qgb2YgdmFsdWVzIGFsbG93ZWQgIGF0IHRoaXMgcmVzb3VyY2UuIENhbiBvbmx5IGJlIHNldCBpZiBgYWxsX3ZhbHVlc2AgaXMgc2V0IHRvCiAgICogYEFMTF9WQUxVRVNfVU5TUEVDSUZJRURgLgogICAqIEByZXR1cm4gdmFsdWUgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5TdHJpbmc+IGdldEFsbG93ZWRWYWx1ZXMoKSB7CiAgICByZXR1cm4gYWxsb3dlZFZhbHVlczsKICB9CgogIC8qKgogICAqIExpc3Qgb2YgdmFsdWVzIGFsbG93ZWQgIGF0IHRoaXMgcmVzb3VyY2UuIENhbiBvbmx5IGJlIHNldCBpZiBgYWxsX3ZhbHVlc2AgaXMgc2V0IHRvCiAgICogYEFMTF9WQUxVRVNfVU5TUEVDSUZJRURgLgogICAqIEBwYXJhbSBhbGxvd2VkVmFsdWVzIGFsbG93ZWRWYWx1ZXMgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIExpc3RQb2xpY3kgc2V0QWxsb3dlZFZhbHVlcyhqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuU3RyaW5nPiBhbGxvd2VkVmFsdWVzKSB7CiAgICB0aGlzLmFsbG93ZWRWYWx1ZXMgPSBhbGxvd2VkVmFsdWVzOwogICAgcmV0dXJuIHRoaXM7CiAgfQoKICAvKioKICAgKiBMaXN0IG9mIHZhbHVlcyBkZW5pZWQgYXQgdGhpcyByZXNvdXJjZS4gQ2FuIG9ubHkgYmUgc2V0IGlmIGBhbGxfdmFsdWVzYCBpcyBzZXQgdG8KICAgKiBgQUxMX1ZBTFVFU19VTlNQRUNJRklFRGAuCiAgICogQHJldHVybiB2YWx1ZSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLlN0cmluZz4gZ2V0RGVuaWVkVmFsdWVzKCkgewogICAgcmV0dXJuIGRlbmllZFZhbHVlczsKICB9CgogIC8qKgogICAqIExpc3Qgb2YgdmFsdWVzIGRlbmllZCBhdCB0aGlzIHJlc291cmNlLiBDYW4gb25seSBiZSBzZXQgaWYgYGFsbF92YWx1ZXNgIGlzIHNldCB0bwogICAqIGBBTExfVkFMVUVTX1VOU1BFQ0lGSUVEYC4KICAgKiBAcGFyYW0gZGVuaWVkVmFsdWVzIGRlbmllZFZhbHVlcyBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgTGlzdFBvbGljeSBzZXREZW5pZWRWYWx1ZXMoamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLlN0cmluZz4gZGVuaWVkVmFsdWVzKSB7CiAgICB0aGlzLmRlbmllZFZhbHVlcyA9IGRlbmllZFZhbHVlczsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgLyoqCiAgICogRGV0ZXJtaW5lcyB0aGUgaW5oZXJpdGFuY2UgYmVoYXZpb3IgZm9yIHRoaXMgYFBvbGljeWAuCiAgICoKICAgKiBCeSBkZWZhdWx0LCBhIGBMaXN0UG9saWN5YCBzZXQgYXQgYSByZXNvdXJjZSBzdXBlcmNlZGVzIGFueSBgUG9saWN5YCBzZXQgYW55d2hlcmUgdXAgdGhlCiAgICogcmVzb3VyY2UgaGllcmFyY2h5LiBIb3dldmVyLCBpZiBgaW5oZXJpdF9mcm9tX3BhcmVudGAgaXMgc2V0IHRvIGB0cnVlYCwgdGhlbiB0aGUgdmFsdWVzIGZyb20KICAgKiB0aGUgZWZmZWN0aXZlIGBQb2xpY3lgIG9mIHRoZSBwYXJlbnQgcmVzb3VyY2UgYXJlIGluaGVyaXRlZCwgbWVhbmluZyB0aGUgdmFsdWVzIHNldCBpbiB0aGlzCiAgICogYFBvbGljeWAgYXJlIGFkZGVkIHRvIHRoZSB2YWx1ZXMgaW5oZXJpdGVkIHVwIHRoZSBoaWVyYXJjaHkuCiAgICoKICAgKiBTZXR0aW5nIGBQb2xpY3lgIGhpZXJhcmNoaWVzIHRoYXQgaW5oZXJpdCBib3RoIGFsbG93ZWQgdmFsdWVzIGFuZCBkZW5pZWQgdmFsdWVzIGlzbid0CiAgICogcmVjb21tZW5kZWQgaW4gbW9zdCBjaXJjdW1zdGFuY2VzIHRvIGtlZXAgdGhlIGNvbmZpZ3VyYXRpb24gc2ltcGxlIGFuZCB1bmRlcnN0YW5kYWJsZS4gSG93ZXZlciwKICAgKiBpdCBpcyBwb3NzaWJsZSB0byBzZXQgYSBgUG9saWN5YCB3aXRoIGBhbGxvd2VkX3ZhbHVlc2Agc2V0IHRoYXQgaW5oZXJpdHMgYSBgUG9saWN5YCB3aXRoCiAgICogYGRlbmllZF92YWx1ZXNgIHNldC4gSW4gdGhpcyBjYXNlLCB0aGUgdmFsdWVzIHRoYXQgYXJlIGFsbG93ZWQgbXVzdCBiZSBpbiBgYWxsb3dlZF92YWx1ZXNgIGFuZAogICAqIG5vdCBwcmVzZW50IGluIGBkZW5pZWRfdmFsdWVzYC4KICAgKgogICAqIEZvciBleGFtcGxlLCBzdXBwb3NlIHlvdSBoYXZlIGEgYENvbnN0cmFpbnRgIGBjb25zdHJhaW50cy9zZXJ2aWNldXNlci5zZXJ2aWNlc2AsIHdoaWNoIGhhcyBhCiAgICogYGNvbnN0cmFpbnRfdHlwZWAgb2YgYGxpc3RfY29uc3RyYWludGAsIGFuZCB3aXRoIGBjb25zdHJhaW50X2RlZmF1bHRgIHNldCB0byBgQUxMT1dgLiBTdXBwb3NlCiAgICogdGhhdCBhdCB0aGUgT3JnYW5pemF0aW9uIGxldmVsLCBhIGBQb2xpY3lgIGlzIGFwcGxpZWQgdGhhdCByZXN0cmljdHMgdGhlIGFsbG93ZWQgQVBJCiAgICogYWN0aXZhdGlvbnMgdG8ge2BFMWAsIGBFMmB9LiBUaGVuLCBpZiBhIGBQb2xpY3lgIGlzIGFwcGxpZWQgdG8gYSBwcm9qZWN0IGJlbG93IHRoZSBPcmdhbml6YXRpb24KICAgKiB0aGF0IGhhcyBgaW5oZXJpdF9mcm9tX3BhcmVudGAgc2V0IHRvIGBmYWxzZWAgYW5kIGZpZWxkIGFsbF92YWx1ZXMgc2V0IHRvIERFTlksIHRoZW4gYW4gYXR0ZW1wdAogICAqIHRvIGFjdGl2YXRlIGFueSBBUEkgd2lsbCBiZSBkZW5pZWQuCiAgICoKICAgKiBUaGUgZm9sbG93aW5nIGV4YW1wbGVzIGRlbW9uc3RyYXRlIGRpZmZlcmVudCBwb3NzaWJsZSBsYXllcmluZ3MgZm9yIGBwcm9qZWN0cy9iYXJgIHBhcmVudGVkIGJ5CiAgICogYG9yZ2FuaXphdGlvbnMvZm9vYDoKICAgKgogICAqIEV4YW1wbGUgMSAobm8gaW5oZXJpdGVkIHZhbHVlcyk6ICAgYG9yZ2FuaXphdGlvbnMvZm9vYCBoYXMgYSBgUG9saWN5YCB3aXRoIHZhbHVlczoKICAgKiB7YWxsb3dlZF92YWx1ZXM6ICJFMSIgYWxsb3dlZF92YWx1ZXM6IkUyIn0gICBgcHJvamVjdHMvYmFyYCBoYXMgYGluaGVyaXRfZnJvbV9wYXJlbnRgIGBmYWxzZWAKICAgKiBhbmQgdmFsdWVzOiAgICAge2FsbG93ZWRfdmFsdWVzOiAiRTMiIGFsbG93ZWRfdmFsdWVzOiAiRTQifSBUaGUgYWNjZXB0ZWQgdmFsdWVzIGF0CiAgICogYG9yZ2FuaXphdGlvbnMvZm9vYCBhcmUgYEUxYCwgYEUyYC4gVGhlIGFjY2VwdGVkIHZhbHVlcyBhdCBgcHJvamVjdHMvYmFyYCBhcmUgYEUzYCwgYW5kIGBFNGAuCiAgICoKICAgKiBFeGFtcGxlIDIgKGluaGVyaXRlZCB2YWx1ZXMpOiAgIGBvcmdhbml6YXRpb25zL2Zvb2AgaGFzIGEgYFBvbGljeWAgd2l0aCB2YWx1ZXM6CiAgICoge2FsbG93ZWRfdmFsdWVzOiAiRTEiIGFsbG93ZWRfdmFsdWVzOiJFMiJ9ICAgYHByb2plY3RzL2JhcmAgaGFzIGEgYFBvbGljeWAgd2l0aCB2YWx1ZXM6CiAgICoge3ZhbHVlOiAiRTMiIHZhbHVlOiAiRTQiIGluaGVyaXRfZnJvbV9wYXJlbnQ6IHRydWV9IFRoZSBhY2NlcHRlZCB2YWx1ZXMgYXQgYG9yZ2FuaXphdGlvbnMvZm9vYAogICAqIGFyZSBgRTFgLCBgRTJgLiBUaGUgYWNjZXB0ZWQgdmFsdWVzIGF0IGBwcm9qZWN0cy9iYXJgIGFyZSBgRTFgLCBgRTJgLCBgRTNgLCBhbmQgYEU0YC4KICAgKgogICAqIEV4YW1wbGUgMyAoaW5oZXJpdGluZyBib3RoIGFsbG93ZWQgYW5kIGRlbmllZCB2YWx1ZXMpOiAgIGBvcmdhbml6YXRpb25zL2Zvb2AgaGFzIGEgYFBvbGljeWAKICAgKiB3aXRoIHZhbHVlczogICAgIHthbGxvd2VkX3ZhbHVlczogIkUxIiBhbGxvd2VkX3ZhbHVlczogIkUyIn0gICBgcHJvamVjdHMvYmFyYCBoYXMgYSBgUG9saWN5YAogICAqIHdpdGg6ICAgICB7ZGVuaWVkX3ZhbHVlczogIkUxIn0gVGhlIGFjY2VwdGVkIHZhbHVlcyBhdCBgb3JnYW5pemF0aW9ucy9mb29gIGFyZSBgRTFgLCBgRTJgLiBUaGUKICAgKiB2YWx1ZSBhY2NlcHRlZCBhdCBgcHJvamVjdHMvYmFyYCBpcyBgRTJgLgogICAqCiAgICogRXhhbXBsZSA0IChSZXN0b3JlRGVmYXVsdCk6ICAgYG9yZ2FuaXphdGlvbnMvZm9vYCBoYXMgYSBgUG9saWN5YCB3aXRoIHZhbHVlczoKICAgKiB7YWxsb3dlZF92YWx1ZXM6ICJFMSIgYWxsb3dlZF92YWx1ZXM6IkUyIn0gICBgcHJvamVjdHMvYmFyYCBoYXMgYSBgUG9saWN5YCB3aXRoIHZhbHVlczoKICAgKiB7UmVzdG9yZURlZmF1bHQ6IHt9fSBUaGUgYWNjZXB0ZWQgdmFsdWVzIGF0IGBvcmdhbml6YXRpb25zL2Zvb2AgYXJlIGBFMWAsIGBFMmAuIFRoZSBhY2NlcHRlZAogICAqIHZhbHVlcyBhdCBgcHJvamVjdHMvYmFyYCBhcmUgZWl0aGVyIGFsbCBvciBub25lIGRlcGVuZGluZyBvbiB0aGUgdmFsdWUgb2YgYGNvbnN0cmFpbnRfZGVmYXVsdGAKICAgKiAoaWYgYEFMTE9XYCwgYWxsOyBpZiBgREVOWWAsIG5vbmUpLgogICAqCiAgICogRXhhbXBsZSA1IChubyBwb2xpY3kgaW5oZXJpdHMgcGFyZW50IHBvbGljeSk6ICAgYG9yZ2FuaXphdGlvbnMvZm9vYCBoYXMgbm8gYFBvbGljeWAgc2V0LgogICAqIGBwcm9qZWN0cy9iYXJgIGhhcyBubyBgUG9saWN5YCBzZXQuIFRoZSBhY2NlcHRlZCB2YWx1ZXMgYXQgYm90aCBsZXZlbHMgYXJlIGVpdGhlciBhbGwgb3Igbm9uZQogICAqIGRlcGVuZGluZyBvbiB0aGUgdmFsdWUgb2YgYGNvbnN0cmFpbnRfZGVmYXVsdGAgKGlmIGBBTExPV2AsIGFsbDsgaWYgYERFTllgLCBub25lKS4KICAgKgogICAqIEV4YW1wbGUgNiAoTGlzdENvbnN0cmFpbnQgYWxsb3dpbmcgYWxsKTogICBgb3JnYW5pemF0aW9ucy9mb29gIGhhcyBhIGBQb2xpY3lgIHdpdGggdmFsdWVzOgogICAqIHthbGxvd2VkX3ZhbHVlczogIkUxIiBhbGxvd2VkX3ZhbHVlczogIkUyIn0gICBgcHJvamVjdHMvYmFyYCBoYXMgYSBgUG9saWN5YCB3aXRoOiAgICAge2FsbDoKICAgKiBBTExPV30gVGhlIGFjY2VwdGVkIHZhbHVlcyBhdCBgb3JnYW5pemF0aW9ucy9mb29gIGFyZSBgRTFgLCBFMmAuIEFueSB2YWx1ZSBpcyBhY2NlcHRlZCBhdAogICAqIGBwcm9qZWN0cy9iYXJgLgogICAqCiAgICogRXhhbXBsZSA3IChMaXN0Q29uc3RyYWludCBhbGxvd2luZyBub25lKTogICBgb3JnYW5pemF0aW9ucy9mb29gIGhhcyBhIGBQb2xpY3lgIHdpdGggdmFsdWVzOgogICAqIHthbGxvd2VkX3ZhbHVlczogIkUxIiBhbGxvd2VkX3ZhbHVlczogIkUyIn0gICBgcHJvamVjdHMvYmFyYCBoYXMgYSBgUG9saWN5YCB3aXRoOiAgICAge2FsbDoKICAgKiBERU5ZfSBUaGUgYWNjZXB0ZWQgdmFsdWVzIGF0IGBvcmdhbml6YXRpb25zL2Zvb2AgYXJlIGBFMWAsIEUyYC4gTm8gdmFsdWUgaXMgYWNjZXB0ZWQgYXQKICAgKiBgcHJvamVjdHMvYmFyYC4KICAgKgogICAqIEV4YW1wbGUgMTAgKGFsbG93ZWQgYW5kIGRlbmllZCBzdWJ0cmVlcyBvZiBSZXNvdXJjZSBNYW5hZ2VyIGhpZXJhcmNoeSk6IEdpdmVuIHRoZSBmb2xsb3dpbmcKICAgKiByZXNvdXJjZSBoaWVyYXJjaHkgICBPMS0+e0YxLCBGMn07IEYxLT57UDF9OyBGMi0+e1AyLCBQM30sICAgYG9yZ2FuaXphdGlvbnMvZm9vYCBoYXMgYSBgUG9saWN5YAogICAqIHdpdGggdmFsdWVzOiAgICAge2FsbG93ZWRfdmFsdWVzOiAidW5kZXI6b3JnYW5pemF0aW9ucy9PMSJ9ICAgYHByb2plY3RzL2JhcmAgaGFzIGEgYFBvbGljeWAKICAgKiB3aXRoOiAgICAge2FsbG93ZWRfdmFsdWVzOiAidW5kZXI6cHJvamVjdHMvUDMifSAgICAge2RlbmllZF92YWx1ZXM6ICJ1bmRlcjpmb2xkZXJzL0YyIn0gVGhlCiAgICogYWNjZXB0ZWQgdmFsdWVzIGF0IGBvcmdhbml6YXRpb25zL2Zvb2AgYXJlIGBvcmdhbml6YXRpb25zL08xYCwgICBgZm9sZGVycy9GMWAsIGBmb2xkZXJzL0YyYCwKICAgKiBgcHJvamVjdHMvUDFgLCBgcHJvamVjdHMvUDJgLCAgIGBwcm9qZWN0cy9QM2AuIFRoZSBhY2NlcHRlZCB2YWx1ZXMgYXQgYHByb2plY3RzL2JhcmAgYXJlCiAgICogYG9yZ2FuaXphdGlvbnMvTzFgLCAgIGBmb2xkZXJzL0YxYCwgYHByb2plY3RzL1AxYC4KICAgKiBAcmV0dXJuIHZhbHVlIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBqYXZhLmxhbmcuQm9vbGVhbiBnZXRJbmhlcml0RnJvbVBhcmVudCgpIHsKICAgIHJldHVybiBpbmhlcml0RnJvbVBhcmVudDsKICB9CgogIC8qKgogICAqIERldGVybWluZXMgdGhlIGluaGVyaXRhbmNlIGJlaGF2aW9yIGZvciB0aGlzIGBQb2xpY3lgLgogICAqCiAgICogQnkgZGVmYXVsdCwgYSBgTGlzdFBvbGljeWAgc2V0IGF0IGEgcmVzb3VyY2Ugc3VwZXJjZWRlcyBhbnkgYFBvbGljeWAgc2V0IGFueXdoZXJlIHVwIHRoZQogICAqIHJlc291cmNlIGhpZXJhcmNoeS4gSG93ZXZlciwgaWYgYGluaGVyaXRfZnJvbV9wYXJlbnRgIGlzIHNldCB0byBgdHJ1ZWAsIHRoZW4gdGhlIHZhbHVlcyBmcm9tCiAgICogdGhlIGVmZmVjdGl2ZSBgUG9saWN5YCBvZiB0aGUgcGFyZW50IHJlc291cmNlIGFyZSBpbmhlcml0ZWQsIG1lYW5pbmcgdGhlIHZhbHVlcyBzZXQgaW4gdGhpcwogICAqIGBQb2xpY3lgIGFyZSBhZGRlZCB0byB0aGUgdmFsdWVzIGluaGVyaXRlZCB1cCB0aGUgaGllcmFyY2h5LgogICAqCiAgICogU2V0dGluZyBgUG9saWN5YCBoaWVyYXJjaGllcyB0aGF0IGluaGVyaXQgYm90aCBhbGxvd2VkIHZhbHVlcyBhbmQgZGVuaWVkIHZhbHVlcyBpc24ndAogICAqIHJlY29tbWVuZGVkIGluIG1vc3QgY2lyY3Vtc3RhbmNlcyB0byBrZWVwIHRoZSBjb25maWd1cmF0aW9uIHNpbXBsZSBhbmQgdW5kZXJzdGFuZGFibGUuIEhvd2V2ZXIsCiAgICogaXQgaXMgcG9zc2libGUgdG8gc2V0IGEgYFBvbGljeWAgd2l0aCBgYWxsb3dlZF92YWx1ZXNgIHNldCB0aGF0IGluaGVyaXRzIGEgYFBvbGljeWAgd2l0aAogICAqIGBkZW5pZWRfdmFsdWVzYCBzZXQuIEluIHRoaXMgY2FzZSwgdGhlIHZhbHVlcyB0aGF0IGFyZSBhbGxvd2VkIG11c3QgYmUgaW4gYGFsbG93ZWRfdmFsdWVzYCBhbmQKICAgKiBub3QgcHJlc2VudCBpbiBgZGVuaWVkX3ZhbHVlc2AuCiAgICoKICAgKiBGb3IgZXhhbXBsZSwgc3VwcG9zZSB5b3UgaGF2ZSBhIGBDb25zdHJhaW50YCBgY29uc3RyYWludHMvc2VydmljZXVzZXIuc2VydmljZXNgLCB3aGljaCBoYXMgYQogICAqIGBjb25zdHJhaW50X3R5cGVgIG9mIGBsaXN0X2NvbnN0cmFpbnRgLCBhbmQgd2l0aCBgY29uc3RyYWludF9kZWZhdWx0YCBzZXQgdG8gYEFMTE9XYC4gU3VwcG9zZQogICAqIHRoYXQgYXQgdGhlIE9yZ2FuaXphdGlvbiBsZXZlbCwgYSBgUG9saWN5YCBpcyBhcHBsaWVkIHRoYXQgcmVzdHJpY3RzIHRoZSBhbGxvd2VkIEFQSQogICAqIGFjdGl2YXRpb25zIHRvIHtgRTFgLCBgRTJgfS4gVGhlbiwgaWYgYSBgUG9saWN5YCBpcyBhcHBsaWVkIHRvIGEgcHJvamVjdCBiZWxvdyB0aGUgT3JnYW5pemF0aW9uCiAgICogdGhhdCBoYXMgYGluaGVyaXRfZnJvbV9wYXJlbnRgIHNldCB0byBgZmFsc2VgIGFuZCBmaWVsZCBhbGxfdmFsdWVzIHNldCB0byBERU5ZLCB0aGVuIGFuIGF0dGVtcHQKICAgKiB0byBhY3RpdmF0ZSBhbnkgQVBJIHdpbGwgYmUgZGVuaWVkLgogICAqCiAgICogVGhlIGZvbGxvd2luZyBleGFtcGxlcyBkZW1vbnN0cmF0ZSBkaWZmZXJlbnQgcG9zc2libGUgbGF5ZXJpbmdzIGZvciBgcHJvamVjdHMvYmFyYCBwYXJlbnRlZCBieQogICAqIGBvcmdhbml6YXRpb25zL2Zvb2A6CiAgICoKICAgKiBFeGFtcGxlIDEgKG5vIGluaGVyaXRlZCB2YWx1ZXMpOiAgIGBvcmdhbml6YXRpb25zL2Zvb2AgaGFzIGEgYFBvbGljeWAgd2l0aCB2YWx1ZXM6CiAgICoge2FsbG93ZWRfdmFsdWVzOiAiRTEiIGFsbG93ZWRfdmFsdWVzOiJFMiJ9ICAgYHByb2plY3RzL2JhcmAgaGFzIGBpbmhlcml0X2Zyb21fcGFyZW50YCBgZmFsc2VgCiAgICogYW5kIHZhbHVlczogICAgIHthbGxvd2VkX3ZhbHVlczogIkUzIiBhbGxvd2VkX3ZhbHVlczogIkU0In0gVGhlIGFjY2VwdGVkIHZhbHVlcyBhdAogICAqIGBvcmdhbml6YXRpb25zL2Zvb2AgYXJlIGBFMWAsIGBFMmAuIFRoZSBhY2NlcHRlZCB2YWx1ZXMgYXQgYHByb2plY3RzL2JhcmAgYXJlIGBFM2AsIGFuZCBgRTRgLgogICAqCiAgICogRXhhbXBsZSAyIChpbmhlcml0ZWQgdmFsdWVzKTogICBgb3JnYW5pemF0aW9ucy9mb29gIGhhcyBhIGBQb2xpY3lgIHdpdGggdmFsdWVzOgogICAqIHthbGxvd2VkX3ZhbHVlczogIkUxIiBhbGxvd2VkX3ZhbHVlczoiRTIifSAgIGBwcm9qZWN0cy9iYXJgIGhhcyBhIGBQb2xpY3lgIHdpdGggdmFsdWVzOgogICAqIHt2YWx1ZTogIkUzIiB2YWx1ZTogIkU0IiBpbmhlcml0X2Zyb21fcGFyZW50OiB0cnVlfSBUaGUgYWNjZXB0ZWQgdmFsdWVzIGF0IGBvcmdhbml6YXRpb25zL2Zvb2AKICAgKiBhcmUgYEUxYCwgYEUyYC4gVGhlIGFjY2VwdGVkIHZhbHVlcyBhdCBgcHJvamVjdHMvYmFyYCBhcmUgYEUxYCwgYEUyYCwgYEUzYCwgYW5kIGBFNGAuCiAgICoKICAgKiBFeGFtcGxlIDMgKGluaGVyaXRpbmcgYm90aCBhbGxvd2VkIGFuZCBkZW5pZWQgdmFsdWVzKTogICBgb3JnYW5pemF0aW9ucy9mb29gIGhhcyBhIGBQb2xpY3lgCiAgICogd2l0aCB2YWx1ZXM6ICAgICB7YWxsb3dlZF92YWx1ZXM6ICJFMSIgYWxsb3dlZF92YWx1ZXM6ICJFMiJ9ICAgYHByb2plY3RzL2JhcmAgaGFzIGEgYFBvbGljeWAKICAgKiB3aXRoOiAgICAge2RlbmllZF92YWx1ZXM6ICJFMSJ9IFRoZSBhY2NlcHRlZCB2YWx1ZXMgYXQgYG9yZ2FuaXphdGlvbnMvZm9vYCBhcmUgYEUxYCwgYEUyYC4gVGhlCiAgICogdmFsdWUgYWNjZXB0ZWQgYXQgYHByb2plY3RzL2JhcmAgaXMgYEUyYC4KICAgKgogICAqIEV4YW1wbGUgNCAoUmVzdG9yZURlZmF1bHQpOiAgIGBvcmdhbml6YXRpb25zL2Zvb2AgaGFzIGEgYFBvbGljeWAgd2l0aCB2YWx1ZXM6CiAgICoge2FsbG93ZWRfdmFsdWVzOiAiRTEiIGFsbG93ZWRfdmFsdWVzOiJFMiJ9ICAgYHByb2plY3RzL2JhcmAgaGFzIGEgYFBvbGljeWAgd2l0aCB2YWx1ZXM6CiAgICoge1Jlc3RvcmVEZWZhdWx0OiB7fX0gVGhlIGFjY2VwdGVkIHZhbHVlcyBhdCBgb3JnYW5pemF0aW9ucy9mb29gIGFyZSBgRTFgLCBgRTJgLiBUaGUgYWNjZXB0ZWQKICAgKiB2YWx1ZXMgYXQgYHByb2plY3RzL2JhcmAgYXJlIGVpdGhlciBhbGwgb3Igbm9uZSBkZXBlbmRpbmcgb24gdGhlIHZhbHVlIG9mIGBjb25zdHJhaW50X2RlZmF1bHRgCiAgICogKGlmIGBBTExPV2AsIGFsbDsgaWYgYERFTllgLCBub25lKS4KICAgKgogICAqIEV4YW1wbGUgNSAobm8gcG9saWN5IGluaGVyaXRzIHBhcmVudCBwb2xpY3kpOiAgIGBvcmdhbml6YXRpb25zL2Zvb2AgaGFzIG5vIGBQb2xpY3lgIHNldC4KICAgKiBgcHJvamVjdHMvYmFyYCBoYXMgbm8gYFBvbGljeWAgc2V0LiBUaGUgYWNjZXB0ZWQgdmFsdWVzIGF0IGJvdGggbGV2ZWxzIGFyZSBlaXRoZXIgYWxsIG9yIG5vbmUKICAgKiBkZXBlbmRpbmcgb24gdGhlIHZhbHVlIG9mIGBjb25zdHJhaW50X2RlZmF1bHRgIChpZiBgQUxMT1dgLCBhbGw7IGlmIGBERU5ZYCwgbm9uZSkuCiAgICoKICAgKiBFeGFtcGxlIDYgKExpc3RDb25zdHJhaW50IGFsbG93aW5nIGFsbCk6ICAgYG9yZ2FuaXphdGlvbnMvZm9vYCBoYXMgYSBgUG9saWN5YCB3aXRoIHZhbHVlczoKICAgKiB7YWxsb3dlZF92YWx1ZXM6ICJFMSIgYWxsb3dlZF92YWx1ZXM6ICJFMiJ9ICAgYHByb2plY3RzL2JhcmAgaGFzIGEgYFBvbGljeWAgd2l0aDogICAgIHthbGw6CiAgICogQUxMT1d9IFRoZSBhY2NlcHRlZCB2YWx1ZXMgYXQgYG9yZ2FuaXphdGlvbnMvZm9vYCBhcmUgYEUxYCwgRTJgLiBBbnkgdmFsdWUgaXMgYWNjZXB0ZWQgYXQKICAgKiBgcHJvamVjdHMvYmFyYC4KICAgKgogICAqIEV4YW1wbGUgNyAoTGlzdENvbnN0cmFpbnQgYWxsb3dpbmcgbm9uZSk6ICAgYG9yZ2FuaXphdGlvbnMvZm9vYCBoYXMgYSBgUG9saWN5YCB3aXRoIHZhbHVlczoKICAgKiB7YWxsb3dlZF92YWx1ZXM6ICJFMSIgYWxsb3dlZF92YWx1ZXM6ICJFMiJ9ICAgYHByb2plY3RzL2JhcmAgaGFzIGEgYFBvbGljeWAgd2l0aDogICAgIHthbGw6CiAgICogREVOWX0gVGhlIGFjY2VwdGVkIHZhbHVlcyBhdCBgb3JnYW5pemF0aW9ucy9mb29gIGFyZSBgRTFgLCBFMmAuIE5vIHZhbHVlIGlzIGFjY2VwdGVkIGF0CiAgICogYHByb2plY3RzL2JhcmAuCiAgICoKICAgKiBFeGFtcGxlIDEwIChhbGxvd2VkIGFuZCBkZW5pZWQgc3VidHJlZXMgb2YgUmVzb3VyY2UgTWFuYWdlciBoaWVyYXJjaHkpOiBHaXZlbiB0aGUgZm9sbG93aW5nCiAgICogcmVzb3VyY2UgaGllcmFyY2h5ICAgTzEtPntGMSwgRjJ9OyBGMS0+e1AxfTsgRjItPntQMiwgUDN9LCAgIGBvcmdhbml6YXRpb25zL2Zvb2AgaGFzIGEgYFBvbGljeWAKICAgKiB3aXRoIHZhbHVlczogICAgIHthbGxvd2VkX3ZhbHVlczogInVuZGVyOm9yZ2FuaXphdGlvbnMvTzEifSAgIGBwcm9qZWN0cy9iYXJgIGhhcyBhIGBQb2xpY3lgCiAgICogd2l0aDogICAgIHthbGxvd2VkX3ZhbHVlczogInVuZGVyOnByb2plY3RzL1AzIn0gICAgIHtkZW5pZWRfdmFsdWVzOiAidW5kZXI6Zm9sZGVycy9GMiJ9IFRoZQogICAqIGFjY2VwdGVkIHZhbHVlcyBhdCBgb3JnYW5pemF0aW9ucy9mb29gIGFyZSBgb3JnYW5pemF0aW9ucy9PMWAsICAgYGZvbGRlcnMvRjFgLCBgZm9sZGVycy9GMmAsCiAgICogYHByb2plY3RzL1AxYCwgYHByb2plY3RzL1AyYCwgICBgcHJvamVjdHMvUDNgLiBUaGUgYWNjZXB0ZWQgdmFsdWVzIGF0IGBwcm9qZWN0cy9iYXJgIGFyZQogICAqIGBvcmdhbml6YXRpb25zL08xYCwgICBgZm9sZGVycy9GMWAsIGBwcm9qZWN0cy9QMWAuCiAgICogQHBhcmFtIGluaGVyaXRGcm9tUGFyZW50IGluaGVyaXRGcm9tUGFyZW50IG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBMaXN0UG9saWN5IHNldEluaGVyaXRGcm9tUGFyZW50KGphdmEubGFuZy5Cb29sZWFuIGluaGVyaXRGcm9tUGFyZW50KSB7CiAgICB0aGlzLmluaGVyaXRGcm9tUGFyZW50ID0gaW5oZXJpdEZyb21QYXJlbnQ7CiAgICByZXR1cm4gdGhpczsKICB9CgogIC8qKgogICAqIE9wdGlvbmFsLiBUaGUgR29vZ2xlIENsb3VkIENvbnNvbGUgd2lsbCB0cnkgdG8gZGVmYXVsdCB0byBhIGNvbmZpZ3VyYXRpb24gdGhhdCBtYXRjaGVzIHRoZQogICAqIHZhbHVlIHNwZWNpZmllZCBpbiB0aGlzIGBQb2xpY3lgLiBJZiBgc3VnZ2VzdGVkX3ZhbHVlYCBpcyBub3Qgc2V0LCBpdCB3aWxsIGluaGVyaXQgdGhlIHZhbHVlCiAgICogc3BlY2lmaWVkIGhpZ2hlciBpbiB0aGUgaGllcmFyY2h5LCB1bmxlc3MgYGluaGVyaXRfZnJvbV9wYXJlbnRgIGlzIGBmYWxzZWAuCiAgICogQHJldHVybiB2YWx1ZSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRTdWdnZXN0ZWRWYWx1ZSgpIHsKICAgIHJldHVybiBzdWdnZXN0ZWRWYWx1ZTsKICB9CgogIC8qKgogICAqIE9wdGlvbmFsLiBUaGUgR29vZ2xlIENsb3VkIENvbnNvbGUgd2lsbCB0cnkgdG8gZGVmYXVsdCB0byBhIGNvbmZpZ3VyYXRpb24gdGhhdCBtYXRjaGVzIHRoZQogICAqIHZhbHVlIHNwZWNpZmllZCBpbiB0aGlzIGBQb2xpY3lgLiBJZiBgc3VnZ2VzdGVkX3ZhbHVlYCBpcyBub3Qgc2V0LCBpdCB3aWxsIGluaGVyaXQgdGhlIHZhbHVlCiAgICogc3BlY2lmaWVkIGhpZ2hlciBpbiB0aGUgaGllcmFyY2h5LCB1bmxlc3MgYGluaGVyaXRfZnJvbV9wYXJlbnRgIGlzIGBmYWxzZWAuCiAgICogQHBhcmFtIHN1Z2dlc3RlZFZhbHVlIHN1Z2dlc3RlZFZhbHVlIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBMaXN0UG9saWN5IHNldFN1Z2dlc3RlZFZhbHVlKGphdmEubGFuZy5TdHJpbmcgc3VnZ2VzdGVkVmFsdWUpIHsKICAgIHRoaXMuc3VnZ2VzdGVkVmFsdWUgPSBzdWdnZXN0ZWRWYWx1ZTsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgQE92ZXJyaWRlCiAgcHVibGljIExpc3RQb2xpY3kgc2V0KFN0cmluZyBmaWVsZE5hbWUsIE9iamVjdCB2YWx1ZSkgewogICAgcmV0dXJuIChMaXN0UG9saWN5KSBzdXBlci5zZXQoZmllbGROYW1lLCB2YWx1ZSk7CiAgfQoKICBAT3ZlcnJpZGUKICBwdWJsaWMgTGlzdFBvbGljeSBjbG9uZSgpIHsKICAgIHJldHVybiAoTGlzdFBvbGljeSkgc3VwZXIuY2xvbmUoKTsKICB9Cgp9ClBLAwQUAAAAAAAAACEAn4HNjZ4RAACeEQAATAAAAGNvbS9nb29nbGUvYXBpL3NlcnZpY2VzL2Nsb3VkcmVzb3VyY2VtYW5hZ2VyL21vZGVsL0xpc3RQcm9qZWN0c1Jlc3BvbnNlLmphdmEvKgogKiBDb3B5cmlnaHQgMjAxMCBHb29nbGUgSW5jLgogKgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQKICogaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UKICogaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzCiAqIG9yIGltcGxpZWQuIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMgdW5kZXIKICogdGhlIExpY2Vuc2UuCiAqLwovKgogKiBUaGlzIGNvZGUgd2FzIGdlbmVyYXRlZCBieSBodHRwczovL2dpdGh1Yi5jb20vZ29vZ2xlL2FwaXMtY2xpZW50LWdlbmVyYXRvci8KICogKGJ1aWxkOiAyMDE4LTEwLTA4IDE3OjQ1OjM5IFVUQykKICogb24gMjAyMC0wMy0xOSBhdCAwMjozODozMCBVVEMgCiAqIE1vZGlmeSBhdCB5b3VyIG93biByaXNrLgogKi8KCnBhY2thZ2UgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuY2xvdWRyZXNvdXJjZW1hbmFnZXIubW9kZWw7CgovKioKICogQSBwYWdlIG9mIHRoZSByZXNwb25zZSByZWNlaXZlZCBmcm9tIHRoZSBMaXN0UHJvamVjdHMgbWV0aG9kLgogKgogKiBBIHBhZ2luYXRlZCByZXNwb25zZSB3aGVyZSBtb3JlIHBhZ2VzIGFyZSBhdmFpbGFibGUgaGFzIGBuZXh0X3BhZ2VfdG9rZW5gIHNldC4gVGhpcyB0b2tlbiBjYW4gYmUKICogdXNlZCBpbiBhIHN1YnNlcXVlbnQgcmVxdWVzdCB0byByZXRyaWV2ZSB0aGUgbmV4dCByZXF1ZXN0IHBhZ2UuCiAqCiAqIDxwPiBUaGlzIGlzIHRoZSBKYXZhIGRhdGEgbW9kZWwgY2xhc3MgdGhhdCBzcGVjaWZpZXMgaG93IHRvIHBhcnNlL3NlcmlhbGl6ZSBpbnRvIHRoZSBKU09OIHRoYXQgaXMKICogdHJhbnNtaXR0ZWQgb3ZlciBIVFRQIHdoZW4gd29ya2luZyB3aXRoIHRoZSBDbG91ZCBSZXNvdXJjZSBNYW5hZ2VyIEFQSS4gRm9yIGEgZGV0YWlsZWQKICogZXhwbGFuYXRpb24gc2VlOgogKiA8YSBocmVmPSJodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9hcGktY2xpZW50LWxpYnJhcnkvamF2YS9nb29nbGUtaHR0cC1qYXZhLWNsaWVudC9qc29uIj5odHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9hcGktY2xpZW50LWxpYnJhcnkvamF2YS9nb29nbGUtaHR0cC1qYXZhLWNsaWVudC9qc29uPC9hPgogKiA8L3A+CiAqCiAqIEBhdXRob3IgR29vZ2xlLCBJbmMuCiAqLwpAU3VwcHJlc3NXYXJuaW5ncygiamF2YWRvYyIpCnB1YmxpYyBmaW5hbCBjbGFzcyBMaXN0UHJvamVjdHNSZXNwb25zZSBleHRlbmRzIGNvbS5nb29nbGUuYXBpLmNsaWVudC5qc29uLkdlbmVyaWNKc29uIHsKCiAgLyoqCiAgICogUGFnaW5hdGlvbiB0b2tlbi4KICAgKgogICAqIElmIHRoZSByZXN1bHQgc2V0IGlzIHRvbyBsYXJnZSB0byBmaXQgaW4gYSBzaW5nbGUgcmVzcG9uc2UsIHRoaXMgdG9rZW4gaXMgcmV0dXJuZWQuIEl0IGVuY29kZXMKICAgKiB0aGUgcG9zaXRpb24gb2YgdGhlIGN1cnJlbnQgcmVzdWx0IGN1cnNvci4gRmVlZGluZyB0aGlzIHZhbHVlIGludG8gYSBuZXcgbGlzdCByZXF1ZXN0IHdpdGggdGhlCiAgICogYHBhZ2VfdG9rZW5gIHBhcmFtZXRlciBnaXZlcyB0aGUgbmV4dCBwYWdlIG9mIHRoZSByZXN1bHRzLgogICAqCiAgICogV2hlbiBgbmV4dF9wYWdlX3Rva2VuYCBpcyBub3QgZmlsbGVkIGluLCB0aGVyZSBpcyBubyBuZXh0IHBhZ2UgYW5kIHRoZSBsaXN0IHJldHVybmVkIGlzIHRoZQogICAqIGxhc3QgcGFnZSBpbiB0aGUgcmVzdWx0IHNldC4KICAgKgogICAqIFBhZ2luYXRpb24gdG9rZW5zIGhhdmUgYSBsaW1pdGVkIGxpZmV0aW1lLgogICAqIFRoZSB2YWx1ZSBtYXkgYmUge0Bjb2RlIG51bGx9LgogICAqLwogIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICBwcml2YXRlIGphdmEubGFuZy5TdHJpbmcgbmV4dFBhZ2VUb2tlbjsKCiAgLyoqCiAgICogVGhlIGxpc3Qgb2YgUHJvamVjdHMgdGhhdCBtYXRjaGVkIHRoZSBsaXN0IGZpbHRlci4gVGhpcyBsaXN0IGNhbiBiZSBwYWdpbmF0ZWQuCiAgICogVGhlIHZhbHVlIG1heSBiZSB7QGNvZGUgbnVsbH0uCiAgICovCiAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8UHJvamVjdD4gcHJvamVjdHM7CgogIC8qKgogICAqIFBhZ2luYXRpb24gdG9rZW4uCiAgICoKICAgKiBJZiB0aGUgcmVzdWx0IHNldCBpcyB0b28gbGFyZ2UgdG8gZml0IGluIGEgc2luZ2xlIHJlc3BvbnNlLCB0aGlzIHRva2VuIGlzIHJldHVybmVkLiBJdCBlbmNvZGVzCiAgICogdGhlIHBvc2l0aW9uIG9mIHRoZSBjdXJyZW50IHJlc3VsdCBjdXJzb3IuIEZlZWRpbmcgdGhpcyB2YWx1ZSBpbnRvIGEgbmV3IGxpc3QgcmVxdWVzdCB3aXRoIHRoZQogICAqIGBwYWdlX3Rva2VuYCBwYXJhbWV0ZXIgZ2l2ZXMgdGhlIG5leHQgcGFnZSBvZiB0aGUgcmVzdWx0cy4KICAgKgogICAqIFdoZW4gYG5leHRfcGFnZV90b2tlbmAgaXMgbm90IGZpbGxlZCBpbiwgdGhlcmUgaXMgbm8gbmV4dCBwYWdlIGFuZCB0aGUgbGlzdCByZXR1cm5lZCBpcyB0aGUKICAgKiBsYXN0IHBhZ2UgaW4gdGhlIHJlc3VsdCBzZXQuCiAgICoKICAgKiBQYWdpbmF0aW9uIHRva2VucyBoYXZlIGEgbGltaXRlZCBsaWZldGltZS4KICAgKiBAcmV0dXJuIHZhbHVlIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldE5leHRQYWdlVG9rZW4oKSB7CiAgICByZXR1cm4gbmV4dFBhZ2VUb2tlbjsKICB9CgogIC8qKgogICAqIFBhZ2luYXRpb24gdG9rZW4uCiAgICoKICAgKiBJZiB0aGUgcmVzdWx0IHNldCBpcyB0b28gbGFyZ2UgdG8gZml0IGluIGEgc2luZ2xlIHJlc3BvbnNlLCB0aGlzIHRva2VuIGlzIHJldHVybmVkLiBJdCBlbmNvZGVzCiAgICogdGhlIHBvc2l0aW9uIG9mIHRoZSBjdXJyZW50IHJlc3VsdCBjdXJzb3IuIEZlZWRpbmcgdGhpcyB2YWx1ZSBpbnRvIGEgbmV3IGxpc3QgcmVxdWVzdCB3aXRoIHRoZQogICAqIGBwYWdlX3Rva2VuYCBwYXJhbWV0ZXIgZ2l2ZXMgdGhlIG5leHQgcGFnZSBvZiB0aGUgcmVzdWx0cy4KICAgKgogICAqIFdoZW4gYG5leHRfcGFnZV90b2tlbmAgaXMgbm90IGZpbGxlZCBpbiwgdGhlcmUgaXMgbm8gbmV4dCBwYWdlIGFuZCB0aGUgbGlzdCByZXR1cm5lZCBpcyB0aGUKICAgKiBsYXN0IHBhZ2UgaW4gdGhlIHJlc3VsdCBzZXQuCiAgICoKICAgKiBQYWdpbmF0aW9uIHRva2VucyBoYXZlIGEgbGltaXRlZCBsaWZldGltZS4KICAgKiBAcGFyYW0gbmV4dFBhZ2VUb2tlbiBuZXh0UGFnZVRva2VuIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBMaXN0UHJvamVjdHNSZXNwb25zZSBzZXROZXh0UGFnZVRva2VuKGphdmEubGFuZy5TdHJpbmcgbmV4dFBhZ2VUb2tlbikgewogICAgdGhpcy5uZXh0UGFnZVRva2VuID0gbmV4dFBhZ2VUb2tlbjsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgLyoqCiAgICogVGhlIGxpc3Qgb2YgUHJvamVjdHMgdGhhdCBtYXRjaGVkIHRoZSBsaXN0IGZpbHRlci4gVGhpcyBsaXN0IGNhbiBiZSBwYWdpbmF0ZWQuCiAgICogQHJldHVybiB2YWx1ZSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8UHJvamVjdD4gZ2V0UHJvamVjdHMoKSB7CiAgICByZXR1cm4gcHJvamVjdHM7CiAgfQoKICAvKioKICAgKiBUaGUgbGlzdCBvZiBQcm9qZWN0cyB0aGF0IG1hdGNoZWQgdGhlIGxpc3QgZmlsdGVyLiBUaGlzIGxpc3QgY2FuIGJlIHBhZ2luYXRlZC4KICAgKiBAcGFyYW0gcHJvamVjdHMgcHJvamVjdHMgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIExpc3RQcm9qZWN0c1Jlc3BvbnNlIHNldFByb2plY3RzKGphdmEudXRpbC5MaXN0PFByb2plY3Q+IHByb2plY3RzKSB7CiAgICB0aGlzLnByb2plY3RzID0gcHJvamVjdHM7CiAgICByZXR1cm4gdGhpczsKICB9CgogIEBPdmVycmlkZQogIHB1YmxpYyBMaXN0UHJvamVjdHNSZXNwb25zZSBzZXQoU3RyaW5nIGZpZWxkTmFtZSwgT2JqZWN0IHZhbHVlKSB7CiAgICByZXR1cm4gKExpc3RQcm9qZWN0c1Jlc3BvbnNlKSBzdXBlci5zZXQoZmllbGROYW1lLCB2YWx1ZSk7CiAgfQoKICBAT3ZlcnJpZGUKICBwdWJsaWMgTGlzdFByb2plY3RzUmVzcG9uc2UgY2xvbmUoKSB7CiAgICByZXR1cm4gKExpc3RQcm9qZWN0c1Jlc3BvbnNlKSBzdXBlci5jbG9uZSgpOwogIH0KCn0KUEsDBBQAAAAAAAAAIQC9zlW/CR4AAAkeAABBAAAAY29tL2dvb2dsZS9hcGkvc2VydmljZXMvY2xvdWRyZXNvdXJjZW1hbmFnZXIvbW9kZWwvT3BlcmF0aW9uLmphdmEvKgogKiBDb3B5cmlnaHQgMjAxMCBHb29nbGUgSW5jLgogKgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQKICogaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UKICogaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzCiAqIG9yIGltcGxpZWQuIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMgdW5kZXIKICogdGhlIExpY2Vuc2UuCiAqLwovKgogKiBUaGlzIGNvZGUgd2FzIGdlbmVyYXRlZCBieSBodHRwczovL2dpdGh1Yi5jb20vZ29vZ2xlL2FwaXMtY2xpZW50LWdlbmVyYXRvci8KICogKGJ1aWxkOiAyMDE4LTEwLTA4IDE3OjQ1OjM5IFVUQykKICogb24gMjAyMC0wMy0xOSBhdCAwMjozODozMCBVVEMgCiAqIE1vZGlmeSBhdCB5b3VyIG93biByaXNrLgogKi8KCnBhY2thZ2UgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuY2xvdWRyZXNvdXJjZW1hbmFnZXIubW9kZWw7CgovKioKICogVGhpcyByZXNvdXJjZSByZXByZXNlbnRzIGEgbG9uZy1ydW5uaW5nIG9wZXJhdGlvbiB0aGF0IGlzIHRoZSByZXN1bHQgb2YgYSBuZXR3b3JrIEFQSSBjYWxsLgogKgogKiA8cD4gVGhpcyBpcyB0aGUgSmF2YSBkYXRhIG1vZGVsIGNsYXNzIHRoYXQgc3BlY2lmaWVzIGhvdyB0byBwYXJzZS9zZXJpYWxpemUgaW50byB0aGUgSlNPTiB0aGF0IGlzCiAqIHRyYW5zbWl0dGVkIG92ZXIgSFRUUCB3aGVuIHdvcmtpbmcgd2l0aCB0aGUgQ2xvdWQgUmVzb3VyY2UgTWFuYWdlciBBUEkuIEZvciBhIGRldGFpbGVkCiAqIGV4cGxhbmF0aW9uIHNlZToKICogPGEgaHJlZj0iaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vYXBpLWNsaWVudC1saWJyYXJ5L2phdmEvZ29vZ2xlLWh0dHAtamF2YS1jbGllbnQvanNvbiI+aHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vYXBpLWNsaWVudC1saWJyYXJ5L2phdmEvZ29vZ2xlLWh0dHAtamF2YS1jbGllbnQvanNvbjwvYT4KICogPC9wPgogKgogKiBAYXV0aG9yIEdvb2dsZSwgSW5jLgogKi8KQFN1cHByZXNzV2FybmluZ3MoImphdmFkb2MiKQpwdWJsaWMgZmluYWwgY2xhc3MgT3BlcmF0aW9uIGV4dGVuZHMgY29tLmdvb2dsZS5hcGkuY2xpZW50Lmpzb24uR2VuZXJpY0pzb24gewoKICAvKioKICAgKiBJZiB0aGUgdmFsdWUgaXMgYGZhbHNlYCwgaXQgbWVhbnMgdGhlIG9wZXJhdGlvbiBpcyBzdGlsbCBpbiBwcm9ncmVzcy4gSWYgYHRydWVgLCB0aGUgb3BlcmF0aW9uCiAgICogaXMgY29tcGxldGVkLCBhbmQgZWl0aGVyIGBlcnJvcmAgb3IgYHJlc3BvbnNlYCBpcyBhdmFpbGFibGUuCiAgICogVGhlIHZhbHVlIG1heSBiZSB7QGNvZGUgbnVsbH0uCiAgICovCiAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogIHByaXZhdGUgamF2YS5sYW5nLkJvb2xlYW4gZG9uZTsKCiAgLyoqCiAgICogVGhlIGVycm9yIHJlc3VsdCBvZiB0aGUgb3BlcmF0aW9uIGluIGNhc2Ugb2YgZmFpbHVyZSBvciBjYW5jZWxsYXRpb24uCiAgICogVGhlIHZhbHVlIG1heSBiZSB7QGNvZGUgbnVsbH0uCiAgICovCiAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogIHByaXZhdGUgU3RhdHVzIGVycm9yOwoKICAvKioKICAgKiBTZXJ2aWNlLXNwZWNpZmljIG1ldGFkYXRhIGFzc29jaWF0ZWQgd2l0aCB0aGUgb3BlcmF0aW9uLiAgSXQgdHlwaWNhbGx5IGNvbnRhaW5zIHByb2dyZXNzCiAgICogaW5mb3JtYXRpb24gYW5kIGNvbW1vbiBtZXRhZGF0YSBzdWNoIGFzIGNyZWF0ZSB0aW1lLiBTb21lIHNlcnZpY2VzIG1pZ2h0IG5vdCBwcm92aWRlIHN1Y2gKICAgKiBtZXRhZGF0YS4gIEFueSBtZXRob2QgdGhhdCByZXR1cm5zIGEgbG9uZy1ydW5uaW5nIG9wZXJhdGlvbiBzaG91bGQgZG9jdW1lbnQgdGhlIG1ldGFkYXRhIHR5cGUsCiAgICogaWYgYW55LgogICAqIFRoZSB2YWx1ZSBtYXkgYmUge0Bjb2RlIG51bGx9LgogICAqLwogIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICBwcml2YXRlIGphdmEudXRpbC5NYXA8U3RyaW5nLCBqYXZhLmxhbmcuT2JqZWN0PiBtZXRhZGF0YTsKCiAgLyoqCiAgICogVGhlIHNlcnZlci1hc3NpZ25lZCBuYW1lLCB3aGljaCBpcyBvbmx5IHVuaXF1ZSB3aXRoaW4gdGhlIHNhbWUgc2VydmljZSB0aGF0IG9yaWdpbmFsbHkgcmV0dXJucwogICAqIGl0LiBJZiB5b3UgdXNlIHRoZSBkZWZhdWx0IEhUVFAgbWFwcGluZywgdGhlIGBuYW1lYCBzaG91bGQgYmUgYSByZXNvdXJjZSBuYW1lIGVuZGluZyB3aXRoCiAgICogYG9wZXJhdGlvbnMve3VuaXF1ZV9pZH1gLgogICAqIFRoZSB2YWx1ZSBtYXkgYmUge0Bjb2RlIG51bGx9LgogICAqLwogIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICBwcml2YXRlIGphdmEubGFuZy5TdHJpbmcgbmFtZTsKCiAgLyoqCiAgICogVGhlIG5vcm1hbCByZXNwb25zZSBvZiB0aGUgb3BlcmF0aW9uIGluIGNhc2Ugb2Ygc3VjY2Vzcy4gIElmIHRoZSBvcmlnaW5hbCBtZXRob2QgcmV0dXJucyBubwogICAqIGRhdGEgb24gc3VjY2Vzcywgc3VjaCBhcyBgRGVsZXRlYCwgdGhlIHJlc3BvbnNlIGlzIGBnb29nbGUucHJvdG9idWYuRW1wdHlgLiAgSWYgdGhlIG9yaWdpbmFsCiAgICogbWV0aG9kIGlzIHN0YW5kYXJkIGBHZXRgL2BDcmVhdGVgL2BVcGRhdGVgLCB0aGUgcmVzcG9uc2Ugc2hvdWxkIGJlIHRoZSByZXNvdXJjZS4gIEZvciBvdGhlcgogICAqIG1ldGhvZHMsIHRoZSByZXNwb25zZSBzaG91bGQgaGF2ZSB0aGUgdHlwZSBgWHh4UmVzcG9uc2VgLCB3aGVyZSBgWHh4YCBpcyB0aGUgb3JpZ2luYWwgbWV0aG9kCiAgICogbmFtZS4gIEZvciBleGFtcGxlLCBpZiB0aGUgb3JpZ2luYWwgbWV0aG9kIG5hbWUgaXMgYFRha2VTbmFwc2hvdCgpYCwgdGhlIGluZmVycmVkIHJlc3BvbnNlIHR5cGUKICAgKiBpcyBgVGFrZVNuYXBzaG90UmVzcG9uc2VgLgogICAqIFRoZSB2YWx1ZSBtYXkgYmUge0Bjb2RlIG51bGx9LgogICAqLwogIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICBwcml2YXRlIGphdmEudXRpbC5NYXA8U3RyaW5nLCBqYXZhLmxhbmcuT2JqZWN0PiByZXNwb25zZTsKCiAgLyoqCiAgICogSWYgdGhlIHZhbHVlIGlzIGBmYWxzZWAsIGl0IG1lYW5zIHRoZSBvcGVyYXRpb24gaXMgc3RpbGwgaW4gcHJvZ3Jlc3MuIElmIGB0cnVlYCwgdGhlIG9wZXJhdGlvbgogICAqIGlzIGNvbXBsZXRlZCwgYW5kIGVpdGhlciBgZXJyb3JgIG9yIGByZXNwb25zZWAgaXMgYXZhaWxhYmxlLgogICAqIEByZXR1cm4gdmFsdWUgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIGphdmEubGFuZy5Cb29sZWFuIGdldERvbmUoKSB7CiAgICByZXR1cm4gZG9uZTsKICB9CgogIC8qKgogICAqIElmIHRoZSB2YWx1ZSBpcyBgZmFsc2VgLCBpdCBtZWFucyB0aGUgb3BlcmF0aW9uIGlzIHN0aWxsIGluIHByb2dyZXNzLiBJZiBgdHJ1ZWAsIHRoZSBvcGVyYXRpb24KICAgKiBpcyBjb21wbGV0ZWQsIGFuZCBlaXRoZXIgYGVycm9yYCBvciBgcmVzcG9uc2VgIGlzIGF2YWlsYWJsZS4KICAgKiBAcGFyYW0gZG9uZSBkb25lIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBPcGVyYXRpb24gc2V0RG9uZShqYXZhLmxhbmcuQm9vbGVhbiBkb25lKSB7CiAgICB0aGlzLmRvbmUgPSBkb25lOwogICAgcmV0dXJuIHRoaXM7CiAgfQoKICAvKioKICAgKiBUaGUgZXJyb3IgcmVzdWx0IG9mIHRoZSBvcGVyYXRpb24gaW4gY2FzZSBvZiBmYWlsdXJlIG9yIGNhbmNlbGxhdGlvbi4KICAgKiBAcmV0dXJuIHZhbHVlIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBTdGF0dXMgZ2V0RXJyb3IoKSB7CiAgICByZXR1cm4gZXJyb3I7CiAgfQoKICAvKioKICAgKiBUaGUgZXJyb3IgcmVzdWx0IG9mIHRoZSBvcGVyYXRpb24gaW4gY2FzZSBvZiBmYWlsdXJlIG9yIGNhbmNlbGxhdGlvbi4KICAgKiBAcGFyYW0gZXJyb3IgZXJyb3Igb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIE9wZXJhdGlvbiBzZXRFcnJvcihTdGF0dXMgZXJyb3IpIHsKICAgIHRoaXMuZXJyb3IgPSBlcnJvcjsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgLyoqCiAgICogU2VydmljZS1zcGVjaWZpYyBtZXRhZGF0YSBhc3NvY2lhdGVkIHdpdGggdGhlIG9wZXJhdGlvbi4gIEl0IHR5cGljYWxseSBjb250YWlucyBwcm9ncmVzcwogICAqIGluZm9ybWF0aW9uIGFuZCBjb21tb24gbWV0YWRhdGEgc3VjaCBhcyBjcmVhdGUgdGltZS4gU29tZSBzZXJ2aWNlcyBtaWdodCBub3QgcHJvdmlkZSBzdWNoCiAgICogbWV0YWRhdGEuICBBbnkgbWV0aG9kIHRoYXQgcmV0dXJucyBhIGxvbmctcnVubmluZyBvcGVyYXRpb24gc2hvdWxkIGRvY3VtZW50IHRoZSBtZXRhZGF0YSB0eXBlLAogICAqIGlmIGFueS4KICAgKiBAcmV0dXJuIHZhbHVlIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBqYXZhLnV0aWwuTWFwPFN0cmluZywgamF2YS5sYW5nLk9iamVjdD4gZ2V0TWV0YWRhdGEoKSB7CiAgICByZXR1cm4gbWV0YWRhdGE7CiAgfQoKICAvKioKICAgKiBTZXJ2aWNlLXNwZWNpZmljIG1ldGFkYXRhIGFzc29jaWF0ZWQgd2l0aCB0aGUgb3BlcmF0aW9uLiAgSXQgdHlwaWNhbGx5IGNvbnRhaW5zIHByb2dyZXNzCiAgICogaW5mb3JtYXRpb24gYW5kIGNvbW1vbiBtZXRhZGF0YSBzdWNoIGFzIGNyZWF0ZSB0aW1lLiBTb21lIHNlcnZpY2VzIG1pZ2h0IG5vdCBwcm92aWRlIHN1Y2gKICAgKiBtZXRhZGF0YS4gIEFueSBtZXRob2QgdGhhdCByZXR1cm5zIGEgbG9uZy1ydW5uaW5nIG9wZXJhdGlvbiBzaG91bGQgZG9jdW1lbnQgdGhlIG1ldGFkYXRhIHR5cGUsCiAgICogaWYgYW55LgogICAqIEBwYXJhbSBtZXRhZGF0YSBtZXRhZGF0YSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgT3BlcmF0aW9uIHNldE1ldGFkYXRhKGphdmEudXRpbC5NYXA8U3RyaW5nLCBqYXZhLmxhbmcuT2JqZWN0PiBtZXRhZGF0YSkgewogICAgdGhpcy5tZXRhZGF0YSA9IG1ldGFkYXRhOwogICAgcmV0dXJuIHRoaXM7CiAgfQoKICAvKioKICAgKiBUaGUgc2VydmVyLWFzc2lnbmVkIG5hbWUsIHdoaWNoIGlzIG9ubHkgdW5pcXVlIHdpdGhpbiB0aGUgc2FtZSBzZXJ2aWNlIHRoYXQgb3JpZ2luYWxseSByZXR1cm5zCiAgICogaXQuIElmIHlvdSB1c2UgdGhlIGRlZmF1bHQgSFRUUCBtYXBwaW5nLCB0aGUgYG5hbWVgIHNob3VsZCBiZSBhIHJlc291cmNlIG5hbWUgZW5kaW5nIHdpdGgKICAgKiBgb3BlcmF0aW9ucy97dW5pcXVlX2lkfWAuCiAgICogQHJldHVybiB2YWx1ZSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXROYW1lKCkgewogICAgcmV0dXJuIG5hbWU7CiAgfQoKICAvKioKICAgKiBUaGUgc2VydmVyLWFzc2lnbmVkIG5hbWUsIHdoaWNoIGlzIG9ubHkgdW5pcXVlIHdpdGhpbiB0aGUgc2FtZSBzZXJ2aWNlIHRoYXQgb3JpZ2luYWxseSByZXR1cm5zCiAgICogaXQuIElmIHlvdSB1c2UgdGhlIGRlZmF1bHQgSFRUUCBtYXBwaW5nLCB0aGUgYG5hbWVgIHNob3VsZCBiZSBhIHJlc291cmNlIG5hbWUgZW5kaW5nIHdpdGgKICAgKiBgb3BlcmF0aW9ucy97dW5pcXVlX2lkfWAuCiAgICogQHBhcmFtIG5hbWUgbmFtZSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgT3BlcmF0aW9uIHNldE5hbWUoamF2YS5sYW5nLlN0cmluZyBuYW1lKSB7CiAgICB0aGlzLm5hbWUgPSBuYW1lOwogICAgcmV0dXJuIHRoaXM7CiAgfQoKICAvKioKICAgKiBUaGUgbm9ybWFsIHJlc3BvbnNlIG9mIHRoZSBvcGVyYXRpb24gaW4gY2FzZSBvZiBzdWNjZXNzLiAgSWYgdGhlIG9yaWdpbmFsIG1ldGhvZCByZXR1cm5zIG5vCiAgICogZGF0YSBvbiBzdWNjZXNzLCBzdWNoIGFzIGBEZWxldGVgLCB0aGUgcmVzcG9uc2UgaXMgYGdvb2dsZS5wcm90b2J1Zi5FbXB0eWAuICBJZiB0aGUgb3JpZ2luYWwKICAgKiBtZXRob2QgaXMgc3RhbmRhcmQgYEdldGAvYENyZWF0ZWAvYFVwZGF0ZWAsIHRoZSByZXNwb25zZSBzaG91bGQgYmUgdGhlIHJlc291cmNlLiAgRm9yIG90aGVyCiAgICogbWV0aG9kcywgdGhlIHJlc3BvbnNlIHNob3VsZCBoYXZlIHRoZSB0eXBlIGBYeHhSZXNwb25zZWAsIHdoZXJlIGBYeHhgIGlzIHRoZSBvcmlnaW5hbCBtZXRob2QKICAgKiBuYW1lLiAgRm9yIGV4YW1wbGUsIGlmIHRoZSBvcmlnaW5hbCBtZXRob2QgbmFtZSBpcyBgVGFrZVNuYXBzaG90KClgLCB0aGUgaW5mZXJyZWQgcmVzcG9uc2UgdHlwZQogICAqIGlzIGBUYWtlU25hcHNob3RSZXNwb25zZWAuCiAgICogQHJldHVybiB2YWx1ZSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgamF2YS51dGlsLk1hcDxTdHJpbmcsIGphdmEubGFuZy5PYmplY3Q+IGdldFJlc3BvbnNlKCkgewogICAgcmV0dXJuIHJlc3BvbnNlOwogIH0KCiAgLyoqCiAgICogVGhlIG5vcm1hbCByZXNwb25zZSBvZiB0aGUgb3BlcmF0aW9uIGluIGNhc2Ugb2Ygc3VjY2Vzcy4gIElmIHRoZSBvcmlnaW5hbCBtZXRob2QgcmV0dXJucyBubwogICAqIGRhdGEgb24gc3VjY2Vzcywgc3VjaCBhcyBgRGVsZXRlYCwgdGhlIHJlc3BvbnNlIGlzIGBnb29nbGUucHJvdG9idWYuRW1wdHlgLiAgSWYgdGhlIG9yaWdpbmFsCiAgICogbWV0aG9kIGlzIHN0YW5kYXJkIGBHZXRgL2BDcmVhdGVgL2BVcGRhdGVgLCB0aGUgcmVzcG9uc2Ugc2hvdWxkIGJlIHRoZSByZXNvdXJjZS4gIEZvciBvdGhlcgogICAqIG1ldGhvZHMsIHRoZSByZXNwb25zZSBzaG91bGQgaGF2ZSB0aGUgdHlwZSBgWHh4UmVzcG9uc2VgLCB3aGVyZSBgWHh4YCBpcyB0aGUgb3JpZ2luYWwgbWV0aG9kCiAgICogbmFtZS4gIEZvciBleGFtcGxlLCBpZiB0aGUgb3JpZ2luYWwgbWV0aG9kIG5hbWUgaXMgYFRha2VTbmFwc2hvdCgpYCwgdGhlIGluZmVycmVkIHJlc3BvbnNlIHR5cGUKICAgKiBpcyBgVGFrZVNuYXBzaG90UmVzcG9uc2VgLgogICAqIEBwYXJhbSByZXNwb25zZSByZXNwb25zZSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgT3BlcmF0aW9uIHNldFJlc3BvbnNlKGphdmEudXRpbC5NYXA8U3RyaW5nLCBqYXZhLmxhbmcuT2JqZWN0PiByZXNwb25zZSkgewogICAgdGhpcy5yZXNwb25zZSA9IHJlc3BvbnNlOwogICAgcmV0dXJuIHRoaXM7CiAgfQoKICBAT3ZlcnJpZGUKICBwdWJsaWMgT3BlcmF0aW9uIHNldChTdHJpbmcgZmllbGROYW1lLCBPYmplY3QgdmFsdWUpIHsKICAgIHJldHVybiAoT3BlcmF0aW9uKSBzdXBlci5zZXQoZmllbGROYW1lLCB2YWx1ZSk7CiAgfQoKICBAT3ZlcnJpZGUKICBwdWJsaWMgT3BlcmF0aW9uIGNsb25lKCkgewogICAgcmV0dXJuIChPcGVyYXRpb24pIHN1cGVyLmNsb25lKCk7CiAgfQoKfQpQSwMEFAAAAAAAAAAhALSxTkGnKgAApyoAAEEAAABjb20vZ29vZ2xlL2FwaS9zZXJ2aWNlcy9jbG91ZHJlc291cmNlbWFuYWdlci9tb2RlbC9PcmdQb2xpY3kuamF2YS8qCiAqIENvcHlyaWdodCAyMDEwIEdvb2dsZSBJbmMuCiAqCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdAogKiBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZQogKiBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3MKICogb3IgaW1wbGllZC4gU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucyB1bmRlcgogKiB0aGUgTGljZW5zZS4KICovCi8qCiAqIFRoaXMgY29kZSB3YXMgZ2VuZXJhdGVkIGJ5IGh0dHBzOi8vZ2l0aHViLmNvbS9nb29nbGUvYXBpcy1jbGllbnQtZ2VuZXJhdG9yLwogKiAoYnVpbGQ6IDIwMTgtMTAtMDggMTc6NDU6MzkgVVRDKQogKiBvbiAyMDIwLTAzLTE5IGF0IDAyOjM4OjMwIFVUQyAKICogTW9kaWZ5IGF0IHlvdXIgb3duIHJpc2suCiAqLwoKcGFja2FnZSBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5jbG91ZHJlc291cmNlbWFuYWdlci5tb2RlbDsKCi8qKgogKiBEZWZpbmVzIGEgQ2xvdWQgT3JnYW5pemF0aW9uIGBQb2xpY3lgIHdoaWNoIGlzIHVzZWQgdG8gc3BlY2lmeSBgQ29uc3RyYWludHNgIGZvciBjb25maWd1cmF0aW9ucwogKiBvZiBDbG91ZCBQbGF0Zm9ybSByZXNvdXJjZXMuCiAqCiAqIDxwPiBUaGlzIGlzIHRoZSBKYXZhIGRhdGEgbW9kZWwgY2xhc3MgdGhhdCBzcGVjaWZpZXMgaG93IHRvIHBhcnNlL3NlcmlhbGl6ZSBpbnRvIHRoZSBKU09OIHRoYXQgaXMKICogdHJhbnNtaXR0ZWQgb3ZlciBIVFRQIHdoZW4gd29ya2luZyB3aXRoIHRoZSBDbG91ZCBSZXNvdXJjZSBNYW5hZ2VyIEFQSS4gRm9yIGEgZGV0YWlsZWQKICogZXhwbGFuYXRpb24gc2VlOgogKiA8YSBocmVmPSJodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9hcGktY2xpZW50LWxpYnJhcnkvamF2YS9nb29nbGUtaHR0cC1qYXZhLWNsaWVudC9qc29uIj5odHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9hcGktY2xpZW50LWxpYnJhcnkvamF2YS9nb29nbGUtaHR0cC1qYXZhLWNsaWVudC9qc29uPC9hPgogKiA8L3A+CiAqCiAqIEBhdXRob3IgR29vZ2xlLCBJbmMuCiAqLwpAU3VwcHJlc3NXYXJuaW5ncygiamF2YWRvYyIpCnB1YmxpYyBmaW5hbCBjbGFzcyBPcmdQb2xpY3kgZXh0ZW5kcyBjb20uZ29vZ2xlLmFwaS5jbGllbnQuanNvbi5HZW5lcmljSnNvbiB7CgogIC8qKgogICAqIEZvciBib29sZWFuIGBDb25zdHJhaW50c2AsIHdoZXRoZXIgdG8gZW5mb3JjZSB0aGUgYENvbnN0cmFpbnRgIG9yIG5vdC4KICAgKiBUaGUgdmFsdWUgbWF5IGJlIHtAY29kZSBudWxsfS4KICAgKi8KICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgcHJpdmF0ZSBCb29sZWFuUG9saWN5IGJvb2xlYW5Qb2xpY3k7CgogIC8qKgogICAqIFRoZSBuYW1lIG9mIHRoZSBgQ29uc3RyYWludGAgdGhlIGBQb2xpY3lgIGlzIGNvbmZpZ3VyaW5nLCBmb3IgZXhhbXBsZSwKICAgKiBgY29uc3RyYWludHMvc2VydmljZXVzZXIuc2VydmljZXNgLgogICAqCiAgICogSW1tdXRhYmxlIGFmdGVyIGNyZWF0aW9uLgogICAqIFRoZSB2YWx1ZSBtYXkgYmUge0Bjb2RlIG51bGx9LgogICAqLwogIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICBwcml2YXRlIGphdmEubGFuZy5TdHJpbmcgY29uc3RyYWludDsKCiAgLyoqCiAgICogQW4gb3BhcXVlIHRhZyBpbmRpY2F0aW5nIHRoZSBjdXJyZW50IHZlcnNpb24gb2YgdGhlIGBQb2xpY3lgLCB1c2VkIGZvciBjb25jdXJyZW5jeSBjb250cm9sLgogICAqCiAgICogV2hlbiB0aGUgYFBvbGljeWAgaXMgcmV0dXJuZWQgZnJvbSBlaXRoZXIgYSBgR2V0UG9saWN5YCBvciBhIGBMaXN0T3JnUG9saWN5YCByZXF1ZXN0LCB0aGlzCiAgICogYGV0YWdgIGluZGljYXRlcyB0aGUgdmVyc2lvbiBvZiB0aGUgY3VycmVudCBgUG9saWN5YCB0byB1c2Ugd2hlbiBleGVjdXRpbmcgYSByZWFkLW1vZGlmeS13cml0ZQogICAqIGxvb3AuCiAgICoKICAgKiBXaGVuIHRoZSBgUG9saWN5YCBpcyByZXR1cm5lZCBmcm9tIGEgYEdldEVmZmVjdGl2ZVBvbGljeWAgcmVxdWVzdCwgdGhlIGBldGFnYCB3aWxsIGJlIHVuc2V0LgogICAqCiAgICogV2hlbiB0aGUgYFBvbGljeWAgaXMgdXNlZCBpbiBhIGBTZXRPcmdQb2xpY3lgIG1ldGhvZCwgdXNlIHRoZSBgZXRhZ2AgdmFsdWUgdGhhdCB3YXMgcmV0dXJuZWQKICAgKiBmcm9tIGEgYEdldE9yZ1BvbGljeWAgcmVxdWVzdCBhcyBwYXJ0IG9mIGEgcmVhZC1tb2RpZnktd3JpdGUgbG9vcCBmb3IgY29uY3VycmVuY3kgY29udHJvbC4gTm90CiAgICogc2V0dGluZyB0aGUgYGV0YWdgaW4gYSBgU2V0T3JnUG9saWN5YCByZXF1ZXN0IHdpbGwgcmVzdWx0IGluIGFuIHVuY29uZGl0aW9uYWwgd3JpdGUgb2YgdGhlCiAgICogYFBvbGljeWAuCiAgICogVGhlIHZhbHVlIG1heSBiZSB7QGNvZGUgbnVsbH0uCiAgICovCiAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogIHByaXZhdGUgamF2YS5sYW5nLlN0cmluZyBldGFnOwoKICAvKioKICAgKiBMaXN0IG9mIHZhbHVlcyBlaXRoZXIgYWxsb3dlZCBvciBkaXNhbGxvd2VkLgogICAqIFRoZSB2YWx1ZSBtYXkgYmUge0Bjb2RlIG51bGx9LgogICAqLwogIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICBwcml2YXRlIExpc3RQb2xpY3kgbGlzdFBvbGljeTsKCiAgLyoqCiAgICogUmVzdG9yZXMgdGhlIGRlZmF1bHQgYmVoYXZpb3Igb2YgdGhlIGNvbnN0cmFpbnQ7IGluZGVwZW5kZW50IG9mIGBDb25zdHJhaW50YCB0eXBlLgogICAqIFRoZSB2YWx1ZSBtYXkgYmUge0Bjb2RlIG51bGx9LgogICAqLwogIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICBwcml2YXRlIFJlc3RvcmVEZWZhdWx0IHJlc3RvcmVEZWZhdWx0OwoKICAvKioKICAgKiBUaGUgdGltZSBzdGFtcCB0aGUgYFBvbGljeWAgd2FzIHByZXZpb3VzbHkgdXBkYXRlZC4gVGhpcyBpcyBzZXQgYnkgdGhlIHNlcnZlciwgbm90IHNwZWNpZmllZCBieQogICAqIHRoZSBjYWxsZXIsIGFuZCByZXByZXNlbnRzIHRoZSBsYXN0IHRpbWUgYSBjYWxsIHRvIGBTZXRPcmdQb2xpY3lgIHdhcyBtYWRlIGZvciB0aGF0IGBQb2xpY3lgLgogICAqIEFueSB2YWx1ZSBzZXQgYnkgdGhlIGNsaWVudCB3aWxsIGJlIGlnbm9yZWQuCiAgICogVGhlIHZhbHVlIG1heSBiZSB7QGNvZGUgbnVsbH0uCiAgICovCiAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogIHByaXZhdGUgU3RyaW5nIHVwZGF0ZVRpbWU7CgogIC8qKgogICAqIFZlcnNpb24gb2YgdGhlIGBQb2xpY3lgLiBEZWZhdWx0IHZlcnNpb24gaXMgMDsKICAgKiBUaGUgdmFsdWUgbWF5IGJlIHtAY29kZSBudWxsfS4KICAgKi8KICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgcHJpdmF0ZSBqYXZhLmxhbmcuSW50ZWdlciB2ZXJzaW9uOwoKICAvKioKICAgKiBGb3IgYm9vbGVhbiBgQ29uc3RyYWludHNgLCB3aGV0aGVyIHRvIGVuZm9yY2UgdGhlIGBDb25zdHJhaW50YCBvciBub3QuCiAgICogQHJldHVybiB2YWx1ZSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgQm9vbGVhblBvbGljeSBnZXRCb29sZWFuUG9saWN5KCkgewogICAgcmV0dXJuIGJvb2xlYW5Qb2xpY3k7CiAgfQoKICAvKioKICAgKiBGb3IgYm9vbGVhbiBgQ29uc3RyYWludHNgLCB3aGV0aGVyIHRvIGVuZm9yY2UgdGhlIGBDb25zdHJhaW50YCBvciBub3QuCiAgICogQHBhcmFtIGJvb2xlYW5Qb2xpY3kgYm9vbGVhblBvbGljeSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgT3JnUG9saWN5IHNldEJvb2xlYW5Qb2xpY3koQm9vbGVhblBvbGljeSBib29sZWFuUG9saWN5KSB7CiAgICB0aGlzLmJvb2xlYW5Qb2xpY3kgPSBib29sZWFuUG9saWN5OwogICAgcmV0dXJuIHRoaXM7CiAgfQoKICAvKioKICAgKiBUaGUgbmFtZSBvZiB0aGUgYENvbnN0cmFpbnRgIHRoZSBgUG9saWN5YCBpcyBjb25maWd1cmluZywgZm9yIGV4YW1wbGUsCiAgICogYGNvbnN0cmFpbnRzL3NlcnZpY2V1c2VyLnNlcnZpY2VzYC4KICAgKgogICAqIEltbXV0YWJsZSBhZnRlciBjcmVhdGlvbi4KICAgKiBAcmV0dXJuIHZhbHVlIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldENvbnN0cmFpbnQoKSB7CiAgICByZXR1cm4gY29uc3RyYWludDsKICB9CgogIC8qKgogICAqIFRoZSBuYW1lIG9mIHRoZSBgQ29uc3RyYWludGAgdGhlIGBQb2xpY3lgIGlzIGNvbmZpZ3VyaW5nLCBmb3IgZXhhbXBsZSwKICAgKiBgY29uc3RyYWludHMvc2VydmljZXVzZXIuc2VydmljZXNgLgogICAqCiAgICogSW1tdXRhYmxlIGFmdGVyIGNyZWF0aW9uLgogICAqIEBwYXJhbSBjb25zdHJhaW50IGNvbnN0cmFpbnQgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIE9yZ1BvbGljeSBzZXRDb25zdHJhaW50KGphdmEubGFuZy5TdHJpbmcgY29uc3RyYWludCkgewogICAgdGhpcy5jb25zdHJhaW50ID0gY29uc3RyYWludDsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgLyoqCiAgICogQW4gb3BhcXVlIHRhZyBpbmRpY2F0aW5nIHRoZSBjdXJyZW50IHZlcnNpb24gb2YgdGhlIGBQb2xpY3lgLCB1c2VkIGZvciBjb25jdXJyZW5jeSBjb250cm9sLgogICAqCiAgICogV2hlbiB0aGUgYFBvbGljeWAgaXMgcmV0dXJuZWQgZnJvbSBlaXRoZXIgYSBgR2V0UG9saWN5YCBvciBhIGBMaXN0T3JnUG9saWN5YCByZXF1ZXN0LCB0aGlzCiAgICogYGV0YWdgIGluZGljYXRlcyB0aGUgdmVyc2lvbiBvZiB0aGUgY3VycmVudCBgUG9saWN5YCB0byB1c2Ugd2hlbiBleGVjdXRpbmcgYSByZWFkLW1vZGlmeS13cml0ZQogICAqIGxvb3AuCiAgICoKICAgKiBXaGVuIHRoZSBgUG9saWN5YCBpcyByZXR1cm5lZCBmcm9tIGEgYEdldEVmZmVjdGl2ZVBvbGljeWAgcmVxdWVzdCwgdGhlIGBldGFnYCB3aWxsIGJlIHVuc2V0LgogICAqCiAgICogV2hlbiB0aGUgYFBvbGljeWAgaXMgdXNlZCBpbiBhIGBTZXRPcmdQb2xpY3lgIG1ldGhvZCwgdXNlIHRoZSBgZXRhZ2AgdmFsdWUgdGhhdCB3YXMgcmV0dXJuZWQKICAgKiBmcm9tIGEgYEdldE9yZ1BvbGljeWAgcmVxdWVzdCBhcyBwYXJ0IG9mIGEgcmVhZC1tb2RpZnktd3JpdGUgbG9vcCBmb3IgY29uY3VycmVuY3kgY29udHJvbC4gTm90CiAgICogc2V0dGluZyB0aGUgYGV0YWdgaW4gYSBgU2V0T3JnUG9saWN5YCByZXF1ZXN0IHdpbGwgcmVzdWx0IGluIGFuIHVuY29uZGl0aW9uYWwgd3JpdGUgb2YgdGhlCiAgICogYFBvbGljeWAuCiAgICogQHNlZSAjZGVjb2RlRXRhZygpCiAgICogQHJldHVybiB2YWx1ZSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRFdGFnKCkgewogICAgcmV0dXJuIGV0YWc7CiAgfQoKICAvKioKICAgKiBBbiBvcGFxdWUgdGFnIGluZGljYXRpbmcgdGhlIGN1cnJlbnQgdmVyc2lvbiBvZiB0aGUgYFBvbGljeWAsIHVzZWQgZm9yIGNvbmN1cnJlbmN5IGNvbnRyb2wuCiAgICoKICAgKiBXaGVuIHRoZSBgUG9saWN5YCBpcyByZXR1cm5lZCBmcm9tIGVpdGhlciBhIGBHZXRQb2xpY3lgIG9yIGEgYExpc3RPcmdQb2xpY3lgIHJlcXVlc3QsIHRoaXMKICAgKiBgZXRhZ2AgaW5kaWNhdGVzIHRoZSB2ZXJzaW9uIG9mIHRoZSBjdXJyZW50IGBQb2xpY3lgIHRvIHVzZSB3aGVuIGV4ZWN1dGluZyBhIHJlYWQtbW9kaWZ5LXdyaXRlCiAgICogbG9vcC4KICAgKgogICAqIFdoZW4gdGhlIGBQb2xpY3lgIGlzIHJldHVybmVkIGZyb20gYSBgR2V0RWZmZWN0aXZlUG9saWN5YCByZXF1ZXN0LCB0aGUgYGV0YWdgIHdpbGwgYmUgdW5zZXQuCiAgICoKICAgKiBXaGVuIHRoZSBgUG9saWN5YCBpcyB1c2VkIGluIGEgYFNldE9yZ1BvbGljeWAgbWV0aG9kLCB1c2UgdGhlIGBldGFnYCB2YWx1ZSB0aGF0IHdhcyByZXR1cm5lZAogICAqIGZyb20gYSBgR2V0T3JnUG9saWN5YCByZXF1ZXN0IGFzIHBhcnQgb2YgYSByZWFkLW1vZGlmeS13cml0ZSBsb29wIGZvciBjb25jdXJyZW5jeSBjb250cm9sLiBOb3QKICAgKiBzZXR0aW5nIHRoZSBgZXRhZ2BpbiBhIGBTZXRPcmdQb2xpY3lgIHJlcXVlc3Qgd2lsbCByZXN1bHQgaW4gYW4gdW5jb25kaXRpb25hbCB3cml0ZSBvZiB0aGUKICAgKiBgUG9saWN5YC4KICAgKiBAc2VlICNnZXRFdGFnKCkKICAgKiBAcmV0dXJuIEJhc2U2NCBkZWNvZGVkIHZhbHVlIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqCiAgICogQHNpbmNlIDEuMTQKICAgKi8KICBwdWJsaWMgYnl0ZVtdIGRlY29kZUV0YWcoKSB7CiAgICByZXR1cm4gY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuQmFzZTY0LmRlY29kZUJhc2U2NChldGFnKTsKICB9CgogIC8qKgogICAqIEFuIG9wYXF1ZSB0YWcgaW5kaWNhdGluZyB0aGUgY3VycmVudCB2ZXJzaW9uIG9mIHRoZSBgUG9saWN5YCwgdXNlZCBmb3IgY29uY3VycmVuY3kgY29udHJvbC4KICAgKgogICAqIFdoZW4gdGhlIGBQb2xpY3lgIGlzIHJldHVybmVkIGZyb20gZWl0aGVyIGEgYEdldFBvbGljeWAgb3IgYSBgTGlzdE9yZ1BvbGljeWAgcmVxdWVzdCwgdGhpcwogICAqIGBldGFnYCBpbmRpY2F0ZXMgdGhlIHZlcnNpb24gb2YgdGhlIGN1cnJlbnQgYFBvbGljeWAgdG8gdXNlIHdoZW4gZXhlY3V0aW5nIGEgcmVhZC1tb2RpZnktd3JpdGUKICAgKiBsb29wLgogICAqCiAgICogV2hlbiB0aGUgYFBvbGljeWAgaXMgcmV0dXJuZWQgZnJvbSBhIGBHZXRFZmZlY3RpdmVQb2xpY3lgIHJlcXVlc3QsIHRoZSBgZXRhZ2Agd2lsbCBiZSB1bnNldC4KICAgKgogICAqIFdoZW4gdGhlIGBQb2xpY3lgIGlzIHVzZWQgaW4gYSBgU2V0T3JnUG9saWN5YCBtZXRob2QsIHVzZSB0aGUgYGV0YWdgIHZhbHVlIHRoYXQgd2FzIHJldHVybmVkCiAgICogZnJvbSBhIGBHZXRPcmdQb2xpY3lgIHJlcXVlc3QgYXMgcGFydCBvZiBhIHJlYWQtbW9kaWZ5LXdyaXRlIGxvb3AgZm9yIGNvbmN1cnJlbmN5IGNvbnRyb2wuIE5vdAogICAqIHNldHRpbmcgdGhlIGBldGFnYGluIGEgYFNldE9yZ1BvbGljeWAgcmVxdWVzdCB3aWxsIHJlc3VsdCBpbiBhbiB1bmNvbmRpdGlvbmFsIHdyaXRlIG9mIHRoZQogICAqIGBQb2xpY3lgLgogICAqIEBzZWUgI2VuY29kZUV0YWcoKQogICAqIEBwYXJhbSBldGFnIGV0YWcgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIE9yZ1BvbGljeSBzZXRFdGFnKGphdmEubGFuZy5TdHJpbmcgZXRhZykgewogICAgdGhpcy5ldGFnID0gZXRhZzsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgLyoqCiAgICogQW4gb3BhcXVlIHRhZyBpbmRpY2F0aW5nIHRoZSBjdXJyZW50IHZlcnNpb24gb2YgdGhlIGBQb2xpY3lgLCB1c2VkIGZvciBjb25jdXJyZW5jeSBjb250cm9sLgogICAqCiAgICogV2hlbiB0aGUgYFBvbGljeWAgaXMgcmV0dXJuZWQgZnJvbSBlaXRoZXIgYSBgR2V0UG9saWN5YCBvciBhIGBMaXN0T3JnUG9saWN5YCByZXF1ZXN0LCB0aGlzCiAgICogYGV0YWdgIGluZGljYXRlcyB0aGUgdmVyc2lvbiBvZiB0aGUgY3VycmVudCBgUG9saWN5YCB0byB1c2Ugd2hlbiBleGVjdXRpbmcgYSByZWFkLW1vZGlmeS13cml0ZQogICAqIGxvb3AuCiAgICoKICAgKiBXaGVuIHRoZSBgUG9saWN5YCBpcyByZXR1cm5lZCBmcm9tIGEgYEdldEVmZmVjdGl2ZVBvbGljeWAgcmVxdWVzdCwgdGhlIGBldGFnYCB3aWxsIGJlIHVuc2V0LgogICAqCiAgICogV2hlbiB0aGUgYFBvbGljeWAgaXMgdXNlZCBpbiBhIGBTZXRPcmdQb2xpY3lgIG1ldGhvZCwgdXNlIHRoZSBgZXRhZ2AgdmFsdWUgdGhhdCB3YXMgcmV0dXJuZWQKICAgKiBmcm9tIGEgYEdldE9yZ1BvbGljeWAgcmVxdWVzdCBhcyBwYXJ0IG9mIGEgcmVhZC1tb2RpZnktd3JpdGUgbG9vcCBmb3IgY29uY3VycmVuY3kgY29udHJvbC4gTm90CiAgICogc2V0dGluZyB0aGUgYGV0YWdgaW4gYSBgU2V0T3JnUG9saWN5YCByZXF1ZXN0IHdpbGwgcmVzdWx0IGluIGFuIHVuY29uZGl0aW9uYWwgd3JpdGUgb2YgdGhlCiAgICogYFBvbGljeWAuCiAgICogQHNlZSAjc2V0RXRhZygpCiAgICoKICAgKiA8cD4KICAgKiBUaGUgdmFsdWUgaXMgZW5jb2RlZCBCYXNlNjQgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lLgogICAqIDwvcD4KICAgKgogICAqIEBzaW5jZSAxLjE0CiAgICovCiAgcHVibGljIE9yZ1BvbGljeSBlbmNvZGVFdGFnKGJ5dGVbXSBldGFnKSB7CiAgICB0aGlzLmV0YWcgPSBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5CYXNlNjQuZW5jb2RlQmFzZTY0VVJMU2FmZVN0cmluZyhldGFnKTsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgLyoqCiAgICogTGlzdCBvZiB2YWx1ZXMgZWl0aGVyIGFsbG93ZWQgb3IgZGlzYWxsb3dlZC4KICAgKiBAcmV0dXJuIHZhbHVlIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBMaXN0UG9saWN5IGdldExpc3RQb2xpY3koKSB7CiAgICByZXR1cm4gbGlzdFBvbGljeTsKICB9CgogIC8qKgogICAqIExpc3Qgb2YgdmFsdWVzIGVpdGhlciBhbGxvd2VkIG9yIGRpc2FsbG93ZWQuCiAgICogQHBhcmFtIGxpc3RQb2xpY3kgbGlzdFBvbGljeSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgT3JnUG9saWN5IHNldExpc3RQb2xpY3koTGlzdFBvbGljeSBsaXN0UG9saWN5KSB7CiAgICB0aGlzLmxpc3RQb2xpY3kgPSBsaXN0UG9saWN5OwogICAgcmV0dXJuIHRoaXM7CiAgfQoKICAvKioKICAgKiBSZXN0b3JlcyB0aGUgZGVmYXVsdCBiZWhhdmlvciBvZiB0aGUgY29uc3RyYWludDsgaW5kZXBlbmRlbnQgb2YgYENvbnN0cmFpbnRgIHR5cGUuCiAgICogQHJldHVybiB2YWx1ZSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgUmVzdG9yZURlZmF1bHQgZ2V0UmVzdG9yZURlZmF1bHQoKSB7CiAgICByZXR1cm4gcmVzdG9yZURlZmF1bHQ7CiAgfQoKICAvKioKICAgKiBSZXN0b3JlcyB0aGUgZGVmYXVsdCBiZWhhdmlvciBvZiB0aGUgY29uc3RyYWludDsgaW5kZXBlbmRlbnQgb2YgYENvbnN0cmFpbnRgIHR5cGUuCiAgICogQHBhcmFtIHJlc3RvcmVEZWZhdWx0IHJlc3RvcmVEZWZhdWx0IG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBPcmdQb2xpY3kgc2V0UmVzdG9yZURlZmF1bHQoUmVzdG9yZURlZmF1bHQgcmVzdG9yZURlZmF1bHQpIHsKICAgIHRoaXMucmVzdG9yZURlZmF1bHQgPSByZXN0b3JlRGVmYXVsdDsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgLyoqCiAgICogVGhlIHRpbWUgc3RhbXAgdGhlIGBQb2xpY3lgIHdhcyBwcmV2aW91c2x5IHVwZGF0ZWQuIFRoaXMgaXMgc2V0IGJ5IHRoZSBzZXJ2ZXIsIG5vdCBzcGVjaWZpZWQgYnkKICAgKiB0aGUgY2FsbGVyLCBhbmQgcmVwcmVzZW50cyB0aGUgbGFzdCB0aW1lIGEgY2FsbCB0byBgU2V0T3JnUG9saWN5YCB3YXMgbWFkZSBmb3IgdGhhdCBgUG9saWN5YC4KICAgKiBBbnkgdmFsdWUgc2V0IGJ5IHRoZSBjbGllbnQgd2lsbCBiZSBpZ25vcmVkLgogICAqIEByZXR1cm4gdmFsdWUgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIFN0cmluZyBnZXRVcGRhdGVUaW1lKCkgewogICAgcmV0dXJuIHVwZGF0ZVRpbWU7CiAgfQoKICAvKioKICAgKiBUaGUgdGltZSBzdGFtcCB0aGUgYFBvbGljeWAgd2FzIHByZXZpb3VzbHkgdXBkYXRlZC4gVGhpcyBpcyBzZXQgYnkgdGhlIHNlcnZlciwgbm90IHNwZWNpZmllZCBieQogICAqIHRoZSBjYWxsZXIsIGFuZCByZXByZXNlbnRzIHRoZSBsYXN0IHRpbWUgYSBjYWxsIHRvIGBTZXRPcmdQb2xpY3lgIHdhcyBtYWRlIGZvciB0aGF0IGBQb2xpY3lgLgogICAqIEFueSB2YWx1ZSBzZXQgYnkgdGhlIGNsaWVudCB3aWxsIGJlIGlnbm9yZWQuCiAgICogQHBhcmFtIHVwZGF0ZVRpbWUgdXBkYXRlVGltZSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgT3JnUG9saWN5IHNldFVwZGF0ZVRpbWUoU3RyaW5nIHVwZGF0ZVRpbWUpIHsKICAgIHRoaXMudXBkYXRlVGltZSA9IHVwZGF0ZVRpbWU7CiAgICByZXR1cm4gdGhpczsKICB9CgogIC8qKgogICAqIFZlcnNpb24gb2YgdGhlIGBQb2xpY3lgLiBEZWZhdWx0IHZlcnNpb24gaXMgMDsKICAgKiBAcmV0dXJuIHZhbHVlIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBqYXZhLmxhbmcuSW50ZWdlciBnZXRWZXJzaW9uKCkgewogICAgcmV0dXJuIHZlcnNpb247CiAgfQoKICAvKioKICAgKiBWZXJzaW9uIG9mIHRoZSBgUG9saWN5YC4gRGVmYXVsdCB2ZXJzaW9uIGlzIDA7CiAgICogQHBhcmFtIHZlcnNpb24gdmVyc2lvbiBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgT3JnUG9saWN5IHNldFZlcnNpb24oamF2YS5sYW5nLkludGVnZXIgdmVyc2lvbikgewogICAgdGhpcy52ZXJzaW9uID0gdmVyc2lvbjsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgQE92ZXJyaWRlCiAgcHVibGljIE9yZ1BvbGljeSBzZXQoU3RyaW5nIGZpZWxkTmFtZSwgT2JqZWN0IHZhbHVlKSB7CiAgICByZXR1cm4gKE9yZ1BvbGljeSkgc3VwZXIuc2V0KGZpZWxkTmFtZSwgdmFsdWUpOwogIH0KCiAgQE92ZXJyaWRlCiAgcHVibGljIE9yZ1BvbGljeSBjbG9uZSgpIHsKICAgIHJldHVybiAoT3JnUG9saWN5KSBzdXBlci5jbG9uZSgpOwogIH0KCn0KUEsDBBQAAAAAAAAAIQC73p6wEBgAABAYAABEAAAAY29tL2dvb2dsZS9hcGkvc2VydmljZXMvY2xvdWRyZXNvdXJjZW1hbmFnZXIvbW9kZWwvT3JnYW5pemF0aW9uLmphdmEvKgogKiBDb3B5cmlnaHQgMjAxMCBHb29nbGUgSW5jLgogKgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQKICogaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UKICogaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzCiAqIG9yIGltcGxpZWQuIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMgdW5kZXIKICogdGhlIExpY2Vuc2UuCiAqLwovKgogKiBUaGlzIGNvZGUgd2FzIGdlbmVyYXRlZCBieSBodHRwczovL2dpdGh1Yi5jb20vZ29vZ2xlL2FwaXMtY2xpZW50LWdlbmVyYXRvci8KICogKGJ1aWxkOiAyMDE4LTEwLTA4IDE3OjQ1OjM5IFVUQykKICogb24gMjAyMC0wMy0xOSBhdCAwMjozODozMCBVVEMgCiAqIE1vZGlmeSBhdCB5b3VyIG93biByaXNrLgogKi8KCnBhY2thZ2UgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuY2xvdWRyZXNvdXJjZW1hbmFnZXIubW9kZWw7CgovKioKICogVGhlIHJvb3Qgbm9kZSBpbiB0aGUgcmVzb3VyY2UgaGllcmFyY2h5IHRvIHdoaWNoIGEgcGFydGljdWxhciBlbnRpdHkncyAoZS5nLiwgY29tcGFueSkgcmVzb3VyY2VzCiAqIGJlbG9uZy4KICoKICogPHA+IFRoaXMgaXMgdGhlIEphdmEgZGF0YSBtb2RlbCBjbGFzcyB0aGF0IHNwZWNpZmllcyBob3cgdG8gcGFyc2Uvc2VyaWFsaXplIGludG8gdGhlIEpTT04gdGhhdCBpcwogKiB0cmFuc21pdHRlZCBvdmVyIEhUVFAgd2hlbiB3b3JraW5nIHdpdGggdGhlIENsb3VkIFJlc291cmNlIE1hbmFnZXIgQVBJLiBGb3IgYSBkZXRhaWxlZAogKiBleHBsYW5hdGlvbiBzZWU6CiAqIDxhIGhyZWY9Imh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL2FwaS1jbGllbnQtbGlicmFyeS9qYXZhL2dvb2dsZS1odHRwLWphdmEtY2xpZW50L2pzb24iPmh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL2FwaS1jbGllbnQtbGlicmFyeS9qYXZhL2dvb2dsZS1odHRwLWphdmEtY2xpZW50L2pzb248L2E+CiAqIDwvcD4KICoKICogQGF1dGhvciBHb29nbGUsIEluYy4KICovCkBTdXBwcmVzc1dhcm5pbmdzKCJqYXZhZG9jIikKcHVibGljIGZpbmFsIGNsYXNzIE9yZ2FuaXphdGlvbiBleHRlbmRzIGNvbS5nb29nbGUuYXBpLmNsaWVudC5qc29uLkdlbmVyaWNKc29uIHsKCiAgLyoqCiAgICogVGltZXN0YW1wIHdoZW4gdGhlIE9yZ2FuaXphdGlvbiB3YXMgY3JlYXRlZC4gQXNzaWduZWQgYnkgdGhlIHNlcnZlci4KICAgKiBUaGUgdmFsdWUgbWF5IGJlIHtAY29kZSBudWxsfS4KICAgKi8KICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgcHJpdmF0ZSBTdHJpbmcgY3JlYXRpb25UaW1lOwoKICAvKioKICAgKiBBIGh1bWFuLXJlYWRhYmxlIHN0cmluZyB0aGF0IHJlZmVycyB0byB0aGUgT3JnYW5pemF0aW9uIGluIHRoZSBHQ1AgQ29uc29sZSBVSS4gVGhpcyBzdHJpbmcgaXMKICAgKiBzZXQgYnkgdGhlIHNlcnZlciBhbmQgY2Fubm90IGJlIGNoYW5nZWQuIFRoZSBzdHJpbmcgd2lsbCBiZSBzZXQgdG8gdGhlIHByaW1hcnkgZG9tYWluIChmb3IKICAgKiBleGFtcGxlLCAiZ29vZ2xlLmNvbSIpIG9mIHRoZSBHIFN1aXRlIGN1c3RvbWVyIHRoYXQgb3ducyB0aGUgb3JnYW5pemF0aW9uLgogICAqIFRoZSB2YWx1ZSBtYXkgYmUge0Bjb2RlIG51bGx9LgogICAqLwogIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICBwcml2YXRlIGphdmEubGFuZy5TdHJpbmcgZGlzcGxheU5hbWU7CgogIC8qKgogICAqIFRoZSBvcmdhbml6YXRpb24ncyBjdXJyZW50IGxpZmVjeWNsZSBzdGF0ZS4gQXNzaWduZWQgYnkgdGhlIHNlcnZlci4KICAgKiBUaGUgdmFsdWUgbWF5IGJlIHtAY29kZSBudWxsfS4KICAgKi8KICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgcHJpdmF0ZSBqYXZhLmxhbmcuU3RyaW5nIGxpZmVjeWNsZVN0YXRlOwoKICAvKioKICAgKiBPdXRwdXQgb25seS4gVGhlIHJlc291cmNlIG5hbWUgb2YgdGhlIG9yZ2FuaXphdGlvbi4gVGhpcyBpcyB0aGUgb3JnYW5pemF0aW9uJ3MgcmVsYXRpdmUgcGF0aCBpbgogICAqIHRoZSBBUEkuIEl0cyBmb3JtYXQgaXMgIm9yZ2FuaXphdGlvbnMvW29yZ2FuaXphdGlvbl9pZF0iLiBGb3IgZXhhbXBsZSwgIm9yZ2FuaXphdGlvbnMvMTIzNCIuCiAgICogVGhlIHZhbHVlIG1heSBiZSB7QGNvZGUgbnVsbH0uCiAgICovCiAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogIHByaXZhdGUgamF2YS5sYW5nLlN0cmluZyBuYW1lOwoKICAvKioKICAgKiBUaGUgb3duZXIgb2YgdGhpcyBPcmdhbml6YXRpb24uIFRoZSBvd25lciBzaG91bGQgYmUgc3BlY2lmaWVkIG9uIGNyZWF0aW9uLiBPbmNlIHNldCwgaXQgY2Fubm90CiAgICogYmUgY2hhbmdlZC4gVGhpcyBmaWVsZCBpcyByZXF1aXJlZC4KICAgKiBUaGUgdmFsdWUgbWF5IGJlIHtAY29kZSBudWxsfS4KICAgKi8KICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgcHJpdmF0ZSBPcmdhbml6YXRpb25Pd25lciBvd25lcjsKCiAgLyoqCiAgICogVGltZXN0YW1wIHdoZW4gdGhlIE9yZ2FuaXphdGlvbiB3YXMgY3JlYXRlZC4gQXNzaWduZWQgYnkgdGhlIHNlcnZlci4KICAgKiBAcmV0dXJuIHZhbHVlIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBTdHJpbmcgZ2V0Q3JlYXRpb25UaW1lKCkgewogICAgcmV0dXJuIGNyZWF0aW9uVGltZTsKICB9CgogIC8qKgogICAqIFRpbWVzdGFtcCB3aGVuIHRoZSBPcmdhbml6YXRpb24gd2FzIGNyZWF0ZWQuIEFzc2lnbmVkIGJ5IHRoZSBzZXJ2ZXIuCiAgICogQHBhcmFtIGNyZWF0aW9uVGltZSBjcmVhdGlvblRpbWUgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIE9yZ2FuaXphdGlvbiBzZXRDcmVhdGlvblRpbWUoU3RyaW5nIGNyZWF0aW9uVGltZSkgewogICAgdGhpcy5jcmVhdGlvblRpbWUgPSBjcmVhdGlvblRpbWU7CiAgICByZXR1cm4gdGhpczsKICB9CgogIC8qKgogICAqIEEgaHVtYW4tcmVhZGFibGUgc3RyaW5nIHRoYXQgcmVmZXJzIHRvIHRoZSBPcmdhbml6YXRpb24gaW4gdGhlIEdDUCBDb25zb2xlIFVJLiBUaGlzIHN0cmluZyBpcwogICAqIHNldCBieSB0aGUgc2VydmVyIGFuZCBjYW5ub3QgYmUgY2hhbmdlZC4gVGhlIHN0cmluZyB3aWxsIGJlIHNldCB0byB0aGUgcHJpbWFyeSBkb21haW4gKGZvcgogICAqIGV4YW1wbGUsICJnb29nbGUuY29tIikgb2YgdGhlIEcgU3VpdGUgY3VzdG9tZXIgdGhhdCBvd25zIHRoZSBvcmdhbml6YXRpb24uCiAgICogQHJldHVybiB2YWx1ZSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXREaXNwbGF5TmFtZSgpIHsKICAgIHJldHVybiBkaXNwbGF5TmFtZTsKICB9CgogIC8qKgogICAqIEEgaHVtYW4tcmVhZGFibGUgc3RyaW5nIHRoYXQgcmVmZXJzIHRvIHRoZSBPcmdhbml6YXRpb24gaW4gdGhlIEdDUCBDb25zb2xlIFVJLiBUaGlzIHN0cmluZyBpcwogICAqIHNldCBieSB0aGUgc2VydmVyIGFuZCBjYW5ub3QgYmUgY2hhbmdlZC4gVGhlIHN0cmluZyB3aWxsIGJlIHNldCB0byB0aGUgcHJpbWFyeSBkb21haW4gKGZvcgogICAqIGV4YW1wbGUsICJnb29nbGUuY29tIikgb2YgdGhlIEcgU3VpdGUgY3VzdG9tZXIgdGhhdCBvd25zIHRoZSBvcmdhbml6YXRpb24uCiAgICogQHBhcmFtIGRpc3BsYXlOYW1lIGRpc3BsYXlOYW1lIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBPcmdhbml6YXRpb24gc2V0RGlzcGxheU5hbWUoamF2YS5sYW5nLlN0cmluZyBkaXNwbGF5TmFtZSkgewogICAgdGhpcy5kaXNwbGF5TmFtZSA9IGRpc3BsYXlOYW1lOwogICAgcmV0dXJuIHRoaXM7CiAgfQoKICAvKioKICAgKiBUaGUgb3JnYW5pemF0aW9uJ3MgY3VycmVudCBsaWZlY3ljbGUgc3RhdGUuIEFzc2lnbmVkIGJ5IHRoZSBzZXJ2ZXIuCiAgICogQHJldHVybiB2YWx1ZSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRMaWZlY3ljbGVTdGF0ZSgpIHsKICAgIHJldHVybiBsaWZlY3ljbGVTdGF0ZTsKICB9CgogIC8qKgogICAqIFRoZSBvcmdhbml6YXRpb24ncyBjdXJyZW50IGxpZmVjeWNsZSBzdGF0ZS4gQXNzaWduZWQgYnkgdGhlIHNlcnZlci4KICAgKiBAcGFyYW0gbGlmZWN5Y2xlU3RhdGUgbGlmZWN5Y2xlU3RhdGUgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIE9yZ2FuaXphdGlvbiBzZXRMaWZlY3ljbGVTdGF0ZShqYXZhLmxhbmcuU3RyaW5nIGxpZmVjeWNsZVN0YXRlKSB7CiAgICB0aGlzLmxpZmVjeWNsZVN0YXRlID0gbGlmZWN5Y2xlU3RhdGU7CiAgICByZXR1cm4gdGhpczsKICB9CgogIC8qKgogICAqIE91dHB1dCBvbmx5LiBUaGUgcmVzb3VyY2UgbmFtZSBvZiB0aGUgb3JnYW5pemF0aW9uLiBUaGlzIGlzIHRoZSBvcmdhbml6YXRpb24ncyByZWxhdGl2ZSBwYXRoIGluCiAgICogdGhlIEFQSS4gSXRzIGZvcm1hdCBpcyAib3JnYW5pemF0aW9ucy9bb3JnYW5pemF0aW9uX2lkXSIuIEZvciBleGFtcGxlLCAib3JnYW5pemF0aW9ucy8xMjM0Ii4KICAgKiBAcmV0dXJuIHZhbHVlIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldE5hbWUoKSB7CiAgICByZXR1cm4gbmFtZTsKICB9CgogIC8qKgogICAqIE91dHB1dCBvbmx5LiBUaGUgcmVzb3VyY2UgbmFtZSBvZiB0aGUgb3JnYW5pemF0aW9uLiBUaGlzIGlzIHRoZSBvcmdhbml6YXRpb24ncyByZWxhdGl2ZSBwYXRoIGluCiAgICogdGhlIEFQSS4gSXRzIGZvcm1hdCBpcyAib3JnYW5pemF0aW9ucy9bb3JnYW5pemF0aW9uX2lkXSIuIEZvciBleGFtcGxlLCAib3JnYW5pemF0aW9ucy8xMjM0Ii4KICAgKiBAcGFyYW0gbmFtZSBuYW1lIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBPcmdhbml6YXRpb24gc2V0TmFtZShqYXZhLmxhbmcuU3RyaW5nIG5hbWUpIHsKICAgIHRoaXMubmFtZSA9IG5hbWU7CiAgICByZXR1cm4gdGhpczsKICB9CgogIC8qKgogICAqIFRoZSBvd25lciBvZiB0aGlzIE9yZ2FuaXphdGlvbi4gVGhlIG93bmVyIHNob3VsZCBiZSBzcGVjaWZpZWQgb24gY3JlYXRpb24uIE9uY2Ugc2V0LCBpdCBjYW5ub3QKICAgKiBiZSBjaGFuZ2VkLiBUaGlzIGZpZWxkIGlzIHJlcXVpcmVkLgogICAqIEByZXR1cm4gdmFsdWUgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIE9yZ2FuaXphdGlvbk93bmVyIGdldE93bmVyKCkgewogICAgcmV0dXJuIG93bmVyOwogIH0KCiAgLyoqCiAgICogVGhlIG93bmVyIG9mIHRoaXMgT3JnYW5pemF0aW9uLiBUaGUgb3duZXIgc2hvdWxkIGJlIHNwZWNpZmllZCBvbiBjcmVhdGlvbi4gT25jZSBzZXQsIGl0IGNhbm5vdAogICAqIGJlIGNoYW5nZWQuIFRoaXMgZmllbGQgaXMgcmVxdWlyZWQuCiAgICogQHBhcmFtIG93bmVyIG93bmVyIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBPcmdhbml6YXRpb24gc2V0T3duZXIoT3JnYW5pemF0aW9uT3duZXIgb3duZXIpIHsKICAgIHRoaXMub3duZXIgPSBvd25lcjsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgQE92ZXJyaWRlCiAgcHVibGljIE9yZ2FuaXphdGlvbiBzZXQoU3RyaW5nIGZpZWxkTmFtZSwgT2JqZWN0IHZhbHVlKSB7CiAgICByZXR1cm4gKE9yZ2FuaXphdGlvbikgc3VwZXIuc2V0KGZpZWxkTmFtZSwgdmFsdWUpOwogIH0KCiAgQE92ZXJyaWRlCiAgcHVibGljIE9yZ2FuaXphdGlvbiBjbG9uZSgpIHsKICAgIHJldHVybiAoT3JnYW5pemF0aW9uKSBzdXBlci5jbG9uZSgpOwogIH0KCn0KUEsDBBQAAAAAAAAAIQApuzfRCwoAAAsKAABJAAAAY29tL2dvb2dsZS9hcGkvc2VydmljZXMvY2xvdWRyZXNvdXJjZW1hbmFnZXIvbW9kZWwvT3JnYW5pemF0aW9uT3duZXIuamF2YS8qCiAqIENvcHlyaWdodCAyMDEwIEdvb2dsZSBJbmMuCiAqCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdAogKiBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZQogKiBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3MKICogb3IgaW1wbGllZC4gU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucyB1bmRlcgogKiB0aGUgTGljZW5zZS4KICovCi8qCiAqIFRoaXMgY29kZSB3YXMgZ2VuZXJhdGVkIGJ5IGh0dHBzOi8vZ2l0aHViLmNvbS9nb29nbGUvYXBpcy1jbGllbnQtZ2VuZXJhdG9yLwogKiAoYnVpbGQ6IDIwMTgtMTAtMDggMTc6NDU6MzkgVVRDKQogKiBvbiAyMDIwLTAzLTE5IGF0IDAyOjM4OjMwIFVUQyAKICogTW9kaWZ5IGF0IHlvdXIgb3duIHJpc2suCiAqLwoKcGFja2FnZSBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5jbG91ZHJlc291cmNlbWFuYWdlci5tb2RlbDsKCi8qKgogKiBUaGUgZW50aXR5IHRoYXQgb3ducyBhbiBPcmdhbml6YXRpb24uIFRoZSBsaWZldGltZSBvZiB0aGUgT3JnYW5pemF0aW9uIGFuZCBhbGwgb2YgaXRzIGRlc2NlbmRhbnRzCiAqIGFyZSBib3VuZCB0byB0aGUgYE9yZ2FuaXphdGlvbk93bmVyYC4gSWYgdGhlIGBPcmdhbml6YXRpb25Pd25lcmAgaXMgZGVsZXRlZCwgdGhlIE9yZ2FuaXphdGlvbiBhbmQKICogYWxsIGl0cyBkZXNjZW5kYW50cyB3aWxsIGJlIGRlbGV0ZWQuCiAqCiAqIDxwPiBUaGlzIGlzIHRoZSBKYXZhIGRhdGEgbW9kZWwgY2xhc3MgdGhhdCBzcGVjaWZpZXMgaG93IHRvIHBhcnNlL3NlcmlhbGl6ZSBpbnRvIHRoZSBKU09OIHRoYXQgaXMKICogdHJhbnNtaXR0ZWQgb3ZlciBIVFRQIHdoZW4gd29ya2luZyB3aXRoIHRoZSBDbG91ZCBSZXNvdXJjZSBNYW5hZ2VyIEFQSS4gRm9yIGEgZGV0YWlsZWQKICogZXhwbGFuYXRpb24gc2VlOgogKiA8YSBocmVmPSJodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9hcGktY2xpZW50LWxpYnJhcnkvamF2YS9nb29nbGUtaHR0cC1qYXZhLWNsaWVudC9qc29uIj5odHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9hcGktY2xpZW50LWxpYnJhcnkvamF2YS9nb29nbGUtaHR0cC1qYXZhLWNsaWVudC9qc29uPC9hPgogKiA8L3A+CiAqCiAqIEBhdXRob3IgR29vZ2xlLCBJbmMuCiAqLwpAU3VwcHJlc3NXYXJuaW5ncygiamF2YWRvYyIpCnB1YmxpYyBmaW5hbCBjbGFzcyBPcmdhbml6YXRpb25Pd25lciBleHRlbmRzIGNvbS5nb29nbGUuYXBpLmNsaWVudC5qc29uLkdlbmVyaWNKc29uIHsKCiAgLyoqCiAgICogVGhlIEcgU3VpdGUgY3VzdG9tZXIgaWQgdXNlZCBpbiB0aGUgRGlyZWN0b3J5IEFQSS4KICAgKiBUaGUgdmFsdWUgbWF5IGJlIHtAY29kZSBudWxsfS4KICAgKi8KICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgcHJpdmF0ZSBqYXZhLmxhbmcuU3RyaW5nIGRpcmVjdG9yeUN1c3RvbWVySWQ7CgogIC8qKgogICAqIFRoZSBHIFN1aXRlIGN1c3RvbWVyIGlkIHVzZWQgaW4gdGhlIERpcmVjdG9yeSBBUEkuCiAgICogQHJldHVybiB2YWx1ZSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXREaXJlY3RvcnlDdXN0b21lcklkKCkgewogICAgcmV0dXJuIGRpcmVjdG9yeUN1c3RvbWVySWQ7CiAgfQoKICAvKioKICAgKiBUaGUgRyBTdWl0ZSBjdXN0b21lciBpZCB1c2VkIGluIHRoZSBEaXJlY3RvcnkgQVBJLgogICAqIEBwYXJhbSBkaXJlY3RvcnlDdXN0b21lcklkIGRpcmVjdG9yeUN1c3RvbWVySWQgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIE9yZ2FuaXphdGlvbk93bmVyIHNldERpcmVjdG9yeUN1c3RvbWVySWQoamF2YS5sYW5nLlN0cmluZyBkaXJlY3RvcnlDdXN0b21lcklkKSB7CiAgICB0aGlzLmRpcmVjdG9yeUN1c3RvbWVySWQgPSBkaXJlY3RvcnlDdXN0b21lcklkOwogICAgcmV0dXJuIHRoaXM7CiAgfQoKICBAT3ZlcnJpZGUKICBwdWJsaWMgT3JnYW5pemF0aW9uT3duZXIgc2V0KFN0cmluZyBmaWVsZE5hbWUsIE9iamVjdCB2YWx1ZSkgewogICAgcmV0dXJuIChPcmdhbml6YXRpb25Pd25lcikgc3VwZXIuc2V0KGZpZWxkTmFtZSwgdmFsdWUpOwogIH0KCiAgQE92ZXJyaWRlCiAgcHVibGljIE9yZ2FuaXphdGlvbk93bmVyIGNsb25lKCkgewogICAgcmV0dXJuIChPcmdhbml6YXRpb25Pd25lcikgc3VwZXIuY2xvbmUoKTsKICB9Cgp9ClBLAwQUAAAAAAAAACEAmkaQwYc3AACHNwAAPgAAAGNvbS9nb29nbGUvYXBpL3NlcnZpY2VzL2Nsb3VkcmVzb3VyY2VtYW5hZ2VyL21vZGVsL1BvbGljeS5qYXZhLyoKICogQ29weXJpZ2h0IDIwMTAgR29vZ2xlIEluYy4KICoKICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0CiAqIGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4gWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlCiAqIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcwogKiBvciBpbXBsaWVkLiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zIHVuZGVyCiAqIHRoZSBMaWNlbnNlLgogKi8KLyoKICogVGhpcyBjb2RlIHdhcyBnZW5lcmF0ZWQgYnkgaHR0cHM6Ly9naXRodWIuY29tL2dvb2dsZS9hcGlzLWNsaWVudC1nZW5lcmF0b3IvCiAqIChidWlsZDogMjAxOC0xMC0wOCAxNzo0NTozOSBVVEMpCiAqIG9uIDIwMjAtMDMtMTkgYXQgMDI6Mzg6MzAgVVRDIAogKiBNb2RpZnkgYXQgeW91ciBvd24gcmlzay4KICovCgpwYWNrYWdlIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmNsb3VkcmVzb3VyY2VtYW5hZ2VyLm1vZGVsOwoKLyoqCiAqIEFuIElkZW50aXR5IGFuZCBBY2Nlc3MgTWFuYWdlbWVudCAoSUFNKSBwb2xpY3ksIHdoaWNoIHNwZWNpZmllcyBhY2Nlc3MgY29udHJvbHMgZm9yIEdvb2dsZSBDbG91ZAogKiByZXNvdXJjZXMuCiAqCiAqIEEgYFBvbGljeWAgaXMgYSBjb2xsZWN0aW9uIG9mIGBiaW5kaW5nc2AuIEEgYGJpbmRpbmdgIGJpbmRzIG9uZSBvciBtb3JlIGBtZW1iZXJzYCB0byBhIHNpbmdsZQogKiBgcm9sZWAuIE1lbWJlcnMgY2FuIGJlIHVzZXIgYWNjb3VudHMsIHNlcnZpY2UgYWNjb3VudHMsIEdvb2dsZSBncm91cHMsIGFuZCBkb21haW5zIChzdWNoIGFzIEcKICogU3VpdGUpLiBBIGByb2xlYCBpcyBhIG5hbWVkIGxpc3Qgb2YgcGVybWlzc2lvbnM7IGVhY2ggYHJvbGVgIGNhbiBiZSBhbiBJQU0gcHJlZGVmaW5lZCByb2xlIG9yIGEKICogdXNlci1jcmVhdGVkIGN1c3RvbSByb2xlLgogKgogKiBPcHRpb25hbGx5LCBhIGBiaW5kaW5nYCBjYW4gc3BlY2lmeSBhIGBjb25kaXRpb25gLCB3aGljaCBpcyBhIGxvZ2ljYWwgZXhwcmVzc2lvbiB0aGF0IGFsbG93cwogKiBhY2Nlc3MgdG8gYSByZXNvdXJjZSBvbmx5IGlmIHRoZSBleHByZXNzaW9uIGV2YWx1YXRlcyB0byBgdHJ1ZWAuIEEgY29uZGl0aW9uIGNhbiBhZGQgY29uc3RyYWludHMKICogYmFzZWQgb24gYXR0cmlidXRlcyBvZiB0aGUgcmVxdWVzdCwgdGhlIHJlc291cmNlLCBvciBib3RoLgogKgogKiAqKkpTT04gZXhhbXBsZToqKgogKgogKiAgICAgeyAgICAgICAiYmluZGluZ3MiOiBbICAgICAgICAgeyAgICAgICAgICAgInJvbGUiOiAicm9sZXMvcmVzb3VyY2VtYW5hZ2VyLm9yZ2FuaXphdGlvbkFkbWluIiwKICogIm1lbWJlcnMiOiBbICAgICAgICAgICAgICJ1c2VyOm1pa2VAZXhhbXBsZS5jb20iLCAgICAgICAgICAgICAiZ3JvdXA6YWRtaW5zQGV4YW1wbGUuY29tIiwKICogImRvbWFpbjpnb29nbGUuY29tIiwgICAgICAgICAgICAgInNlcnZpY2VBY2NvdW50Om15LXByb2plY3QtaWRAYXBwc3BvdC5nc2VydmljZWFjY291bnQuY29tIgogKiBdICAgICAgICAgfSwgICAgICAgICB7ICAgICAgICAgICAicm9sZSI6ICJyb2xlcy9yZXNvdXJjZW1hbmFnZXIub3JnYW5pemF0aW9uVmlld2VyIiwKICogIm1lbWJlcnMiOiBbInVzZXI6ZXZlQGV4YW1wbGUuY29tIl0sICAgICAgICAgICAiY29uZGl0aW9uIjogeyAgICAgICAgICAgICAidGl0bGUiOiAiZXhwaXJhYmxlCiAqIGFjY2VzcyIsICAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJEb2VzIG5vdCBncmFudCBhY2Nlc3MgYWZ0ZXIgU2VwIDIwMjAiLAogKiAiZXhwcmVzc2lvbiI6ICJyZXF1ZXN0LnRpbWUgPCB0aW1lc3RhbXAoJzIwMjAtMTAtMDFUMDA6MDA6MDAuMDAwWicpIiwgICAgICAgICAgIH0gICAgICAgICB9CiAqIF0sICAgICAgICJldGFnIjogIkJ3V1dqYTBZZkpBPSIsICAgICAgICJ2ZXJzaW9uIjogMyAgICAgfQogKgogKiAqKllBTUwgZXhhbXBsZToqKgogKgogKiAgICAgYmluZGluZ3M6ICAgICAtIG1lbWJlcnM6ICAgICAgIC0gdXNlcjptaWtlQGV4YW1wbGUuY29tICAgICAgIC0gZ3JvdXA6YWRtaW5zQGV4YW1wbGUuY29tCiAqIC0gZG9tYWluOmdvb2dsZS5jb20gICAgICAgLSBzZXJ2aWNlQWNjb3VudDpteS1wcm9qZWN0LWlkQGFwcHNwb3QuZ3NlcnZpY2VhY2NvdW50LmNvbSAgICAgICByb2xlOgogKiByb2xlcy9yZXNvdXJjZW1hbmFnZXIub3JnYW5pemF0aW9uQWRtaW4gICAgIC0gbWVtYmVyczogICAgICAgLSB1c2VyOmV2ZUBleGFtcGxlLmNvbSAgICAgICByb2xlOgogKiByb2xlcy9yZXNvdXJjZW1hbmFnZXIub3JnYW5pemF0aW9uVmlld2VyICAgICAgIGNvbmRpdGlvbjogICAgICAgICB0aXRsZTogZXhwaXJhYmxlIGFjY2VzcwogKiBkZXNjcmlwdGlvbjogRG9lcyBub3QgZ3JhbnQgYWNjZXNzIGFmdGVyIFNlcCAyMDIwICAgICAgICAgZXhwcmVzc2lvbjogcmVxdWVzdC50aW1lIDwKICogdGltZXN0YW1wKCcyMDIwLTEwLTAxVDAwOjAwOjAwLjAwMFonKSAgICAgLSBldGFnOiBCd1dXamEwWWZKQT0gICAgIC0gdmVyc2lvbjogMwogKgogKiBGb3IgYSBkZXNjcmlwdGlvbiBvZiBJQU0gYW5kIGl0cyBmZWF0dXJlcywgc2VlIHRoZSBbSUFNCiAqIGRvY3VtZW50YXRpb25dKGh0dHBzOi8vY2xvdWQuZ29vZ2xlLmNvbS9pYW0vZG9jcy8pLgogKgogKiA8cD4gVGhpcyBpcyB0aGUgSmF2YSBkYXRhIG1vZGVsIGNsYXNzIHRoYXQgc3BlY2lmaWVzIGhvdyB0byBwYXJzZS9zZXJpYWxpemUgaW50byB0aGUgSlNPTiB0aGF0IGlzCiAqIHRyYW5zbWl0dGVkIG92ZXIgSFRUUCB3aGVuIHdvcmtpbmcgd2l0aCB0aGUgQ2xvdWQgUmVzb3VyY2UgTWFuYWdlciBBUEkuIEZvciBhIGRldGFpbGVkCiAqIGV4cGxhbmF0aW9uIHNlZToKICogPGEgaHJlZj0iaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vYXBpLWNsaWVudC1saWJyYXJ5L2phdmEvZ29vZ2xlLWh0dHAtamF2YS1jbGllbnQvanNvbiI+aHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vYXBpLWNsaWVudC1saWJyYXJ5L2phdmEvZ29vZ2xlLWh0dHAtamF2YS1jbGllbnQvanNvbjwvYT4KICogPC9wPgogKgogKiBAYXV0aG9yIEdvb2dsZSwgSW5jLgogKi8KQFN1cHByZXNzV2FybmluZ3MoImphdmFkb2MiKQpwdWJsaWMgZmluYWwgY2xhc3MgUG9saWN5IGV4dGVuZHMgY29tLmdvb2dsZS5hcGkuY2xpZW50Lmpzb24uR2VuZXJpY0pzb24gewoKICAvKioKICAgKiBTcGVjaWZpZXMgY2xvdWQgYXVkaXQgbG9nZ2luZyBjb25maWd1cmF0aW9uIGZvciB0aGlzIHBvbGljeS4KICAgKiBUaGUgdmFsdWUgbWF5IGJlIHtAY29kZSBudWxsfS4KICAgKi8KICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxBdWRpdENvbmZpZz4gYXVkaXRDb25maWdzOwoKICAvKioKICAgKiBBc3NvY2lhdGVzIGEgbGlzdCBvZiBgbWVtYmVyc2AgdG8gYSBgcm9sZWAuIE9wdGlvbmFsbHksIG1heSBzcGVjaWZ5IGEgYGNvbmRpdGlvbmAgdGhhdAogICAqIGRldGVybWluZXMgaG93IGFuZCB3aGVuIHRoZSBgYmluZGluZ3NgIGFyZSBhcHBsaWVkLiBFYWNoIG9mIHRoZSBgYmluZGluZ3NgIG11c3QgY29udGFpbiBhdAogICAqIGxlYXN0IG9uZSBtZW1iZXIuCiAgICogVGhlIHZhbHVlIG1heSBiZSB7QGNvZGUgbnVsbH0uCiAgICovCiAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8QmluZGluZz4gYmluZGluZ3M7CgogIHN0YXRpYyB7CiAgICAvLyBoYWNrIHRvIGZvcmNlIFByb0d1YXJkIHRvIGNvbnNpZGVyIEJpbmRpbmcgdXNlZCwgc2luY2Ugb3RoZXJ3aXNlIGl0IHdvdWxkIGJlIHN0cmlwcGVkIG91dAogICAgLy8gc2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9nb29nbGUvZ29vZ2xlLWFwaS1qYXZhLWNsaWVudC9pc3N1ZXMvNTQzCiAgICBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5EYXRhLm51bGxPZihCaW5kaW5nLmNsYXNzKTsKICB9CgogIC8qKgogICAqIGBldGFnYCBpcyB1c2VkIGZvciBvcHRpbWlzdGljIGNvbmN1cnJlbmN5IGNvbnRyb2wgYXMgYSB3YXkgdG8gaGVscCBwcmV2ZW50IHNpbXVsdGFuZW91cyB1cGRhdGVzCiAgICogb2YgYSBwb2xpY3kgZnJvbSBvdmVyd3JpdGluZyBlYWNoIG90aGVyLiBJdCBpcyBzdHJvbmdseSBzdWdnZXN0ZWQgdGhhdCBzeXN0ZW1zIG1ha2UgdXNlIG9mIHRoZQogICAqIGBldGFnYCBpbiB0aGUgcmVhZC1tb2RpZnktd3JpdGUgY3ljbGUgdG8gcGVyZm9ybSBwb2xpY3kgdXBkYXRlcyBpbiBvcmRlciB0byBhdm9pZCByYWNlCiAgICogY29uZGl0aW9uczogQW4gYGV0YWdgIGlzIHJldHVybmVkIGluIHRoZSByZXNwb25zZSB0byBgZ2V0SWFtUG9saWN5YCwgYW5kIHN5c3RlbXMgYXJlIGV4cGVjdGVkCiAgICogdG8gcHV0IHRoYXQgZXRhZyBpbiB0aGUgcmVxdWVzdCB0byBgc2V0SWFtUG9saWN5YCB0byBlbnN1cmUgdGhhdCB0aGVpciBjaGFuZ2Ugd2lsbCBiZSBhcHBsaWVkCiAgICogdG8gdGhlIHNhbWUgdmVyc2lvbiBvZiB0aGUgcG9saWN5LgogICAqCiAgICogKipJbXBvcnRhbnQ6KiogSWYgeW91IHVzZSBJQU0gQ29uZGl0aW9ucywgeW91IG11c3QgaW5jbHVkZSB0aGUgYGV0YWdgIGZpZWxkIHdoZW5ldmVyIHlvdSBjYWxsCiAgICogYHNldElhbVBvbGljeWAuIElmIHlvdSBvbWl0IHRoaXMgZmllbGQsIHRoZW4gSUFNIGFsbG93cyB5b3UgdG8gb3ZlcndyaXRlIGEgdmVyc2lvbiBgM2AgcG9saWN5CiAgICogd2l0aCBhIHZlcnNpb24gYDFgIHBvbGljeSwgYW5kIGFsbCBvZiB0aGUgY29uZGl0aW9ucyBpbiB0aGUgdmVyc2lvbiBgM2AgcG9saWN5IGFyZSBsb3N0LgogICAqIFRoZSB2YWx1ZSBtYXkgYmUge0Bjb2RlIG51bGx9LgogICAqLwogIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICBwcml2YXRlIGphdmEubGFuZy5TdHJpbmcgZXRhZzsKCiAgLyoqCiAgICogU3BlY2lmaWVzIHRoZSBmb3JtYXQgb2YgdGhlIHBvbGljeS4KICAgKgogICAqIFZhbGlkIHZhbHVlcyBhcmUgYDBgLCBgMWAsIGFuZCBgM2AuIFJlcXVlc3RzIHRoYXQgc3BlY2lmeSBhbiBpbnZhbGlkIHZhbHVlIGFyZSByZWplY3RlZC4KICAgKgogICAqIEFueSBvcGVyYXRpb24gdGhhdCBhZmZlY3RzIGNvbmRpdGlvbmFsIHJvbGUgYmluZGluZ3MgbXVzdCBzcGVjaWZ5IHZlcnNpb24gYDNgLiBUaGlzIHJlcXVpcmVtZW50CiAgICogYXBwbGllcyB0byB0aGUgZm9sbG93aW5nIG9wZXJhdGlvbnM6CiAgICoKICAgKiAqIEdldHRpbmcgYSBwb2xpY3kgdGhhdCBpbmNsdWRlcyBhIGNvbmRpdGlvbmFsIHJvbGUgYmluZGluZyAqIEFkZGluZyBhIGNvbmRpdGlvbmFsIHJvbGUgYmluZGluZwogICAqIHRvIGEgcG9saWN5ICogQ2hhbmdpbmcgYSBjb25kaXRpb25hbCByb2xlIGJpbmRpbmcgaW4gYSBwb2xpY3kgKiBSZW1vdmluZyBhbnkgcm9sZSBiaW5kaW5nLCB3aXRoCiAgICogb3Igd2l0aG91dCBhIGNvbmRpdGlvbiwgZnJvbSBhIHBvbGljeSAgIHRoYXQgaW5jbHVkZXMgY29uZGl0aW9ucwogICAqCiAgICogKipJbXBvcnRhbnQ6KiogSWYgeW91IHVzZSBJQU0gQ29uZGl0aW9ucywgeW91IG11c3QgaW5jbHVkZSB0aGUgYGV0YWdgIGZpZWxkIHdoZW5ldmVyIHlvdSBjYWxsCiAgICogYHNldElhbVBvbGljeWAuIElmIHlvdSBvbWl0IHRoaXMgZmllbGQsIHRoZW4gSUFNIGFsbG93cyB5b3UgdG8gb3ZlcndyaXRlIGEgdmVyc2lvbiBgM2AgcG9saWN5CiAgICogd2l0aCBhIHZlcnNpb24gYDFgIHBvbGljeSwgYW5kIGFsbCBvZiB0aGUgY29uZGl0aW9ucyBpbiB0aGUgdmVyc2lvbiBgM2AgcG9saWN5IGFyZSBsb3N0LgogICAqCiAgICogSWYgYSBwb2xpY3kgZG9lcyBub3QgaW5jbHVkZSBhbnkgY29uZGl0aW9ucywgb3BlcmF0aW9ucyBvbiB0aGF0IHBvbGljeSBtYXkgc3BlY2lmeSBhbnkgdmFsaWQKICAgKiB2ZXJzaW9uIG9yIGxlYXZlIHRoZSBmaWVsZCB1bnNldC4KICAgKiBUaGUgdmFsdWUgbWF5IGJlIHtAY29kZSBudWxsfS4KICAgKi8KICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgcHJpdmF0ZSBqYXZhLmxhbmcuSW50ZWdlciB2ZXJzaW9uOwoKICAvKioKICAgKiBTcGVjaWZpZXMgY2xvdWQgYXVkaXQgbG9nZ2luZyBjb25maWd1cmF0aW9uIGZvciB0aGlzIHBvbGljeS4KICAgKiBAcmV0dXJuIHZhbHVlIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBqYXZhLnV0aWwuTGlzdDxBdWRpdENvbmZpZz4gZ2V0QXVkaXRDb25maWdzKCkgewogICAgcmV0dXJuIGF1ZGl0Q29uZmlnczsKICB9CgogIC8qKgogICAqIFNwZWNpZmllcyBjbG91ZCBhdWRpdCBsb2dnaW5nIGNvbmZpZ3VyYXRpb24gZm9yIHRoaXMgcG9saWN5LgogICAqIEBwYXJhbSBhdWRpdENvbmZpZ3MgYXVkaXRDb25maWdzIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBQb2xpY3kgc2V0QXVkaXRDb25maWdzKGphdmEudXRpbC5MaXN0PEF1ZGl0Q29uZmlnPiBhdWRpdENvbmZpZ3MpIHsKICAgIHRoaXMuYXVkaXRDb25maWdzID0gYXVkaXRDb25maWdzOwogICAgcmV0dXJuIHRoaXM7CiAgfQoKICAvKioKICAgKiBBc3NvY2lhdGVzIGEgbGlzdCBvZiBgbWVtYmVyc2AgdG8gYSBgcm9sZWAuIE9wdGlvbmFsbHksIG1heSBzcGVjaWZ5IGEgYGNvbmRpdGlvbmAgdGhhdAogICAqIGRldGVybWluZXMgaG93IGFuZCB3aGVuIHRoZSBgYmluZGluZ3NgIGFyZSBhcHBsaWVkLiBFYWNoIG9mIHRoZSBgYmluZGluZ3NgIG11c3QgY29udGFpbiBhdAogICAqIGxlYXN0IG9uZSBtZW1iZXIuCiAgICogQHJldHVybiB2YWx1ZSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8QmluZGluZz4gZ2V0QmluZGluZ3MoKSB7CiAgICByZXR1cm4gYmluZGluZ3M7CiAgfQoKICAvKioKICAgKiBBc3NvY2lhdGVzIGEgbGlzdCBvZiBgbWVtYmVyc2AgdG8gYSBgcm9sZWAuIE9wdGlvbmFsbHksIG1heSBzcGVjaWZ5IGEgYGNvbmRpdGlvbmAgdGhhdAogICAqIGRldGVybWluZXMgaG93IGFuZCB3aGVuIHRoZSBgYmluZGluZ3NgIGFyZSBhcHBsaWVkLiBFYWNoIG9mIHRoZSBgYmluZGluZ3NgIG11c3QgY29udGFpbiBhdAogICAqIGxlYXN0IG9uZSBtZW1iZXIuCiAgICogQHBhcmFtIGJpbmRpbmdzIGJpbmRpbmdzIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBQb2xpY3kgc2V0QmluZGluZ3MoamF2YS51dGlsLkxpc3Q8QmluZGluZz4gYmluZGluZ3MpIHsKICAgIHRoaXMuYmluZGluZ3MgPSBiaW5kaW5nczsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgLyoqCiAgICogYGV0YWdgIGlzIHVzZWQgZm9yIG9wdGltaXN0aWMgY29uY3VycmVuY3kgY29udHJvbCBhcyBhIHdheSB0byBoZWxwIHByZXZlbnQgc2ltdWx0YW5lb3VzIHVwZGF0ZXMKICAgKiBvZiBhIHBvbGljeSBmcm9tIG92ZXJ3cml0aW5nIGVhY2ggb3RoZXIuIEl0IGlzIHN0cm9uZ2x5IHN1Z2dlc3RlZCB0aGF0IHN5c3RlbXMgbWFrZSB1c2Ugb2YgdGhlCiAgICogYGV0YWdgIGluIHRoZSByZWFkLW1vZGlmeS13cml0ZSBjeWNsZSB0byBwZXJmb3JtIHBvbGljeSB1cGRhdGVzIGluIG9yZGVyIHRvIGF2b2lkIHJhY2UKICAgKiBjb25kaXRpb25zOiBBbiBgZXRhZ2AgaXMgcmV0dXJuZWQgaW4gdGhlIHJlc3BvbnNlIHRvIGBnZXRJYW1Qb2xpY3lgLCBhbmQgc3lzdGVtcyBhcmUgZXhwZWN0ZWQKICAgKiB0byBwdXQgdGhhdCBldGFnIGluIHRoZSByZXF1ZXN0IHRvIGBzZXRJYW1Qb2xpY3lgIHRvIGVuc3VyZSB0aGF0IHRoZWlyIGNoYW5nZSB3aWxsIGJlIGFwcGxpZWQKICAgKiB0byB0aGUgc2FtZSB2ZXJzaW9uIG9mIHRoZSBwb2xpY3kuCiAgICoKICAgKiAqKkltcG9ydGFudDoqKiBJZiB5b3UgdXNlIElBTSBDb25kaXRpb25zLCB5b3UgbXVzdCBpbmNsdWRlIHRoZSBgZXRhZ2AgZmllbGQgd2hlbmV2ZXIgeW91IGNhbGwKICAgKiBgc2V0SWFtUG9saWN5YC4gSWYgeW91IG9taXQgdGhpcyBmaWVsZCwgdGhlbiBJQU0gYWxsb3dzIHlvdSB0byBvdmVyd3JpdGUgYSB2ZXJzaW9uIGAzYCBwb2xpY3kKICAgKiB3aXRoIGEgdmVyc2lvbiBgMWAgcG9saWN5LCBhbmQgYWxsIG9mIHRoZSBjb25kaXRpb25zIGluIHRoZSB2ZXJzaW9uIGAzYCBwb2xpY3kgYXJlIGxvc3QuCiAgICogQHNlZSAjZGVjb2RlRXRhZygpCiAgICogQHJldHVybiB2YWx1ZSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgamF2YS5sYW5nLlN0cmluZyBnZXRFdGFnKCkgewogICAgcmV0dXJuIGV0YWc7CiAgfQoKICAvKioKICAgKiBgZXRhZ2AgaXMgdXNlZCBmb3Igb3B0aW1pc3RpYyBjb25jdXJyZW5jeSBjb250cm9sIGFzIGEgd2F5IHRvIGhlbHAgcHJldmVudCBzaW11bHRhbmVvdXMgdXBkYXRlcwogICAqIG9mIGEgcG9saWN5IGZyb20gb3ZlcndyaXRpbmcgZWFjaCBvdGhlci4gSXQgaXMgc3Ryb25nbHkgc3VnZ2VzdGVkIHRoYXQgc3lzdGVtcyBtYWtlIHVzZSBvZiB0aGUKICAgKiBgZXRhZ2AgaW4gdGhlIHJlYWQtbW9kaWZ5LXdyaXRlIGN5Y2xlIHRvIHBlcmZvcm0gcG9saWN5IHVwZGF0ZXMgaW4gb3JkZXIgdG8gYXZvaWQgcmFjZQogICAqIGNvbmRpdGlvbnM6IEFuIGBldGFnYCBpcyByZXR1cm5lZCBpbiB0aGUgcmVzcG9uc2UgdG8gYGdldElhbVBvbGljeWAsIGFuZCBzeXN0ZW1zIGFyZSBleHBlY3RlZAogICAqIHRvIHB1dCB0aGF0IGV0YWcgaW4gdGhlIHJlcXVlc3QgdG8gYHNldElhbVBvbGljeWAgdG8gZW5zdXJlIHRoYXQgdGhlaXIgY2hhbmdlIHdpbGwgYmUgYXBwbGllZAogICAqIHRvIHRoZSBzYW1lIHZlcnNpb24gb2YgdGhlIHBvbGljeS4KICAgKgogICAqICoqSW1wb3J0YW50OioqIElmIHlvdSB1c2UgSUFNIENvbmRpdGlvbnMsIHlvdSBtdXN0IGluY2x1ZGUgdGhlIGBldGFnYCBmaWVsZCB3aGVuZXZlciB5b3UgY2FsbAogICAqIGBzZXRJYW1Qb2xpY3lgLiBJZiB5b3Ugb21pdCB0aGlzIGZpZWxkLCB0aGVuIElBTSBhbGxvd3MgeW91IHRvIG92ZXJ3cml0ZSBhIHZlcnNpb24gYDNgIHBvbGljeQogICAqIHdpdGggYSB2ZXJzaW9uIGAxYCBwb2xpY3ksIGFuZCBhbGwgb2YgdGhlIGNvbmRpdGlvbnMgaW4gdGhlIHZlcnNpb24gYDNgIHBvbGljeSBhcmUgbG9zdC4KICAgKiBAc2VlICNnZXRFdGFnKCkKICAgKiBAcmV0dXJuIEJhc2U2NCBkZWNvZGVkIHZhbHVlIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqCiAgICogQHNpbmNlIDEuMTQKICAgKi8KICBwdWJsaWMgYnl0ZVtdIGRlY29kZUV0YWcoKSB7CiAgICByZXR1cm4gY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuQmFzZTY0LmRlY29kZUJhc2U2NChldGFnKTsKICB9CgogIC8qKgogICAqIGBldGFnYCBpcyB1c2VkIGZvciBvcHRpbWlzdGljIGNvbmN1cnJlbmN5IGNvbnRyb2wgYXMgYSB3YXkgdG8gaGVscCBwcmV2ZW50IHNpbXVsdGFuZW91cyB1cGRhdGVzCiAgICogb2YgYSBwb2xpY3kgZnJvbSBvdmVyd3JpdGluZyBlYWNoIG90aGVyLiBJdCBpcyBzdHJvbmdseSBzdWdnZXN0ZWQgdGhhdCBzeXN0ZW1zIG1ha2UgdXNlIG9mIHRoZQogICAqIGBldGFnYCBpbiB0aGUgcmVhZC1tb2RpZnktd3JpdGUgY3ljbGUgdG8gcGVyZm9ybSBwb2xpY3kgdXBkYXRlcyBpbiBvcmRlciB0byBhdm9pZCByYWNlCiAgICogY29uZGl0aW9uczogQW4gYGV0YWdgIGlzIHJldHVybmVkIGluIHRoZSByZXNwb25zZSB0byBgZ2V0SWFtUG9saWN5YCwgYW5kIHN5c3RlbXMgYXJlIGV4cGVjdGVkCiAgICogdG8gcHV0IHRoYXQgZXRhZyBpbiB0aGUgcmVxdWVzdCB0byBgc2V0SWFtUG9saWN5YCB0byBlbnN1cmUgdGhhdCB0aGVpciBjaGFuZ2Ugd2lsbCBiZSBhcHBsaWVkCiAgICogdG8gdGhlIHNhbWUgdmVyc2lvbiBvZiB0aGUgcG9saWN5LgogICAqCiAgICogKipJbXBvcnRhbnQ6KiogSWYgeW91IHVzZSBJQU0gQ29uZGl0aW9ucywgeW91IG11c3QgaW5jbHVkZSB0aGUgYGV0YWdgIGZpZWxkIHdoZW5ldmVyIHlvdSBjYWxsCiAgICogYHNldElhbVBvbGljeWAuIElmIHlvdSBvbWl0IHRoaXMgZmllbGQsIHRoZW4gSUFNIGFsbG93cyB5b3UgdG8gb3ZlcndyaXRlIGEgdmVyc2lvbiBgM2AgcG9saWN5CiAgICogd2l0aCBhIHZlcnNpb24gYDFgIHBvbGljeSwgYW5kIGFsbCBvZiB0aGUgY29uZGl0aW9ucyBpbiB0aGUgdmVyc2lvbiBgM2AgcG9saWN5IGFyZSBsb3N0LgogICAqIEBzZWUgI2VuY29kZUV0YWcoKQogICAqIEBwYXJhbSBldGFnIGV0YWcgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIFBvbGljeSBzZXRFdGFnKGphdmEubGFuZy5TdHJpbmcgZXRhZykgewogICAgdGhpcy5ldGFnID0gZXRhZzsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgLyoqCiAgICogYGV0YWdgIGlzIHVzZWQgZm9yIG9wdGltaXN0aWMgY29uY3VycmVuY3kgY29udHJvbCBhcyBhIHdheSB0byBoZWxwIHByZXZlbnQgc2ltdWx0YW5lb3VzIHVwZGF0ZXMKICAgKiBvZiBhIHBvbGljeSBmcm9tIG92ZXJ3cml0aW5nIGVhY2ggb3RoZXIuIEl0IGlzIHN0cm9uZ2x5IHN1Z2dlc3RlZCB0aGF0IHN5c3RlbXMgbWFrZSB1c2Ugb2YgdGhlCiAgICogYGV0YWdgIGluIHRoZSByZWFkLW1vZGlmeS13cml0ZSBjeWNsZSB0byBwZXJmb3JtIHBvbGljeSB1cGRhdGVzIGluIG9yZGVyIHRvIGF2b2lkIHJhY2UKICAgKiBjb25kaXRpb25zOiBBbiBgZXRhZ2AgaXMgcmV0dXJuZWQgaW4gdGhlIHJlc3BvbnNlIHRvIGBnZXRJYW1Qb2xpY3lgLCBhbmQgc3lzdGVtcyBhcmUgZXhwZWN0ZWQKICAgKiB0byBwdXQgdGhhdCBldGFnIGluIHRoZSByZXF1ZXN0IHRvIGBzZXRJYW1Qb2xpY3lgIHRvIGVuc3VyZSB0aGF0IHRoZWlyIGNoYW5nZSB3aWxsIGJlIGFwcGxpZWQKICAgKiB0byB0aGUgc2FtZSB2ZXJzaW9uIG9mIHRoZSBwb2xpY3kuCiAgICoKICAgKiAqKkltcG9ydGFudDoqKiBJZiB5b3UgdXNlIElBTSBDb25kaXRpb25zLCB5b3UgbXVzdCBpbmNsdWRlIHRoZSBgZXRhZ2AgZmllbGQgd2hlbmV2ZXIgeW91IGNhbGwKICAgKiBgc2V0SWFtUG9saWN5YC4gSWYgeW91IG9taXQgdGhpcyBmaWVsZCwgdGhlbiBJQU0gYWxsb3dzIHlvdSB0byBvdmVyd3JpdGUgYSB2ZXJzaW9uIGAzYCBwb2xpY3kKICAgKiB3aXRoIGEgdmVyc2lvbiBgMWAgcG9saWN5LCBhbmQgYWxsIG9mIHRoZSBjb25kaXRpb25zIGluIHRoZSB2ZXJzaW9uIGAzYCBwb2xpY3kgYXJlIGxvc3QuCiAgICogQHNlZSAjc2V0RXRhZygpCiAgICoKICAgKiA8cD4KICAgKiBUaGUgdmFsdWUgaXMgZW5jb2RlZCBCYXNlNjQgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lLgogICAqIDwvcD4KICAgKgogICAqIEBzaW5jZSAxLjE0CiAgICovCiAgcHVibGljIFBvbGljeSBlbmNvZGVFdGFnKGJ5dGVbXSBldGFnKSB7CiAgICB0aGlzLmV0YWcgPSBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5CYXNlNjQuZW5jb2RlQmFzZTY0VVJMU2FmZVN0cmluZyhldGFnKTsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgLyoqCiAgICogU3BlY2lmaWVzIHRoZSBmb3JtYXQgb2YgdGhlIHBvbGljeS4KICAgKgogICAqIFZhbGlkIHZhbHVlcyBhcmUgYDBgLCBgMWAsIGFuZCBgM2AuIFJlcXVlc3RzIHRoYXQgc3BlY2lmeSBhbiBpbnZhbGlkIHZhbHVlIGFyZSByZWplY3RlZC4KICAgKgogICAqIEFueSBvcGVyYXRpb24gdGhhdCBhZmZlY3RzIGNvbmRpdGlvbmFsIHJvbGUgYmluZGluZ3MgbXVzdCBzcGVjaWZ5IHZlcnNpb24gYDNgLiBUaGlzIHJlcXVpcmVtZW50CiAgICogYXBwbGllcyB0byB0aGUgZm9sbG93aW5nIG9wZXJhdGlvbnM6CiAgICoKICAgKiAqIEdldHRpbmcgYSBwb2xpY3kgdGhhdCBpbmNsdWRlcyBhIGNvbmRpdGlvbmFsIHJvbGUgYmluZGluZyAqIEFkZGluZyBhIGNvbmRpdGlvbmFsIHJvbGUgYmluZGluZwogICAqIHRvIGEgcG9saWN5ICogQ2hhbmdpbmcgYSBjb25kaXRpb25hbCByb2xlIGJpbmRpbmcgaW4gYSBwb2xpY3kgKiBSZW1vdmluZyBhbnkgcm9sZSBiaW5kaW5nLCB3aXRoCiAgICogb3Igd2l0aG91dCBhIGNvbmRpdGlvbiwgZnJvbSBhIHBvbGljeSAgIHRoYXQgaW5jbHVkZXMgY29uZGl0aW9ucwogICAqCiAgICogKipJbXBvcnRhbnQ6KiogSWYgeW91IHVzZSBJQU0gQ29uZGl0aW9ucywgeW91IG11c3QgaW5jbHVkZSB0aGUgYGV0YWdgIGZpZWxkIHdoZW5ldmVyIHlvdSBjYWxsCiAgICogYHNldElhbVBvbGljeWAuIElmIHlvdSBvbWl0IHRoaXMgZmllbGQsIHRoZW4gSUFNIGFsbG93cyB5b3UgdG8gb3ZlcndyaXRlIGEgdmVyc2lvbiBgM2AgcG9saWN5CiAgICogd2l0aCBhIHZlcnNpb24gYDFgIHBvbGljeSwgYW5kIGFsbCBvZiB0aGUgY29uZGl0aW9ucyBpbiB0aGUgdmVyc2lvbiBgM2AgcG9saWN5IGFyZSBsb3N0LgogICAqCiAgICogSWYgYSBwb2xpY3kgZG9lcyBub3QgaW5jbHVkZSBhbnkgY29uZGl0aW9ucywgb3BlcmF0aW9ucyBvbiB0aGF0IHBvbGljeSBtYXkgc3BlY2lmeSBhbnkgdmFsaWQKICAgKiB2ZXJzaW9uIG9yIGxlYXZlIHRoZSBmaWVsZCB1bnNldC4KICAgKiBAcmV0dXJuIHZhbHVlIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBqYXZhLmxhbmcuSW50ZWdlciBnZXRWZXJzaW9uKCkgewogICAgcmV0dXJuIHZlcnNpb247CiAgfQoKICAvKioKICAgKiBTcGVjaWZpZXMgdGhlIGZvcm1hdCBvZiB0aGUgcG9saWN5LgogICAqCiAgICogVmFsaWQgdmFsdWVzIGFyZSBgMGAsIGAxYCwgYW5kIGAzYC4gUmVxdWVzdHMgdGhhdCBzcGVjaWZ5IGFuIGludmFsaWQgdmFsdWUgYXJlIHJlamVjdGVkLgogICAqCiAgICogQW55IG9wZXJhdGlvbiB0aGF0IGFmZmVjdHMgY29uZGl0aW9uYWwgcm9sZSBiaW5kaW5ncyBtdXN0IHNwZWNpZnkgdmVyc2lvbiBgM2AuIFRoaXMgcmVxdWlyZW1lbnQKICAgKiBhcHBsaWVzIHRvIHRoZSBmb2xsb3dpbmcgb3BlcmF0aW9uczoKICAgKgogICAqICogR2V0dGluZyBhIHBvbGljeSB0aGF0IGluY2x1ZGVzIGEgY29uZGl0aW9uYWwgcm9sZSBiaW5kaW5nICogQWRkaW5nIGEgY29uZGl0aW9uYWwgcm9sZSBiaW5kaW5nCiAgICogdG8gYSBwb2xpY3kgKiBDaGFuZ2luZyBhIGNvbmRpdGlvbmFsIHJvbGUgYmluZGluZyBpbiBhIHBvbGljeSAqIFJlbW92aW5nIGFueSByb2xlIGJpbmRpbmcsIHdpdGgKICAgKiBvciB3aXRob3V0IGEgY29uZGl0aW9uLCBmcm9tIGEgcG9saWN5ICAgdGhhdCBpbmNsdWRlcyBjb25kaXRpb25zCiAgICoKICAgKiAqKkltcG9ydGFudDoqKiBJZiB5b3UgdXNlIElBTSBDb25kaXRpb25zLCB5b3UgbXVzdCBpbmNsdWRlIHRoZSBgZXRhZ2AgZmllbGQgd2hlbmV2ZXIgeW91IGNhbGwKICAgKiBgc2V0SWFtUG9saWN5YC4gSWYgeW91IG9taXQgdGhpcyBmaWVsZCwgdGhlbiBJQU0gYWxsb3dzIHlvdSB0byBvdmVyd3JpdGUgYSB2ZXJzaW9uIGAzYCBwb2xpY3kKICAgKiB3aXRoIGEgdmVyc2lvbiBgMWAgcG9saWN5LCBhbmQgYWxsIG9mIHRoZSBjb25kaXRpb25zIGluIHRoZSB2ZXJzaW9uIGAzYCBwb2xpY3kgYXJlIGxvc3QuCiAgICoKICAgKiBJZiBhIHBvbGljeSBkb2VzIG5vdCBpbmNsdWRlIGFueSBjb25kaXRpb25zLCBvcGVyYXRpb25zIG9uIHRoYXQgcG9saWN5IG1heSBzcGVjaWZ5IGFueSB2YWxpZAogICAqIHZlcnNpb24gb3IgbGVhdmUgdGhlIGZpZWxkIHVuc2V0LgogICAqIEBwYXJhbSB2ZXJzaW9uIHZlcnNpb24gb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIFBvbGljeSBzZXRWZXJzaW9uKGphdmEubGFuZy5JbnRlZ2VyIHZlcnNpb24pIHsKICAgIHRoaXMudmVyc2lvbiA9IHZlcnNpb247CiAgICByZXR1cm4gdGhpczsKICB9CgogIEBPdmVycmlkZQogIHB1YmxpYyBQb2xpY3kgc2V0KFN0cmluZyBmaWVsZE5hbWUsIE9iamVjdCB2YWx1ZSkgewogICAgcmV0dXJuIChQb2xpY3kpIHN1cGVyLnNldChmaWVsZE5hbWUsIHZhbHVlKTsKICB9CgogIEBPdmVycmlkZQogIHB1YmxpYyBQb2xpY3kgY2xvbmUoKSB7CiAgICByZXR1cm4gKFBvbGljeSkgc3VwZXIuY2xvbmUoKTsKICB9Cgp9ClBLAwQUAAAAAAAAACEAZQ5J5t0mAADdJgAAPwAAAGNvbS9nb29nbGUvYXBpL3NlcnZpY2VzL2Nsb3VkcmVzb3VyY2VtYW5hZ2VyL21vZGVsL1Byb2plY3QuamF2YS8qCiAqIENvcHlyaWdodCAyMDEwIEdvb2dsZSBJbmMuCiAqCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdAogKiBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZQogKiBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3MKICogb3IgaW1wbGllZC4gU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucyB1bmRlcgogKiB0aGUgTGljZW5zZS4KICovCi8qCiAqIFRoaXMgY29kZSB3YXMgZ2VuZXJhdGVkIGJ5IGh0dHBzOi8vZ2l0aHViLmNvbS9nb29nbGUvYXBpcy1jbGllbnQtZ2VuZXJhdG9yLwogKiAoYnVpbGQ6IDIwMTgtMTAtMDggMTc6NDU6MzkgVVRDKQogKiBvbiAyMDIwLTAzLTE5IGF0IDAyOjM4OjMwIFVUQyAKICogTW9kaWZ5IGF0IHlvdXIgb3duIHJpc2suCiAqLwoKcGFja2FnZSBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5jbG91ZHJlc291cmNlbWFuYWdlci5tb2RlbDsKCi8qKgogKiBBIFByb2plY3QgaXMgYSBoaWdoLWxldmVsIEdvb2dsZSBDbG91ZCBQbGF0Zm9ybSBlbnRpdHkuICBJdCBpcyBhIGNvbnRhaW5lciBmb3IgQUNMcywgQVBJcywgQXBwCiAqIEVuZ2luZSBBcHBzLCBWTXMsIGFuZCBvdGhlciBHb29nbGUgQ2xvdWQgUGxhdGZvcm0gcmVzb3VyY2VzLgogKgogKiA8cD4gVGhpcyBpcyB0aGUgSmF2YSBkYXRhIG1vZGVsIGNsYXNzIHRoYXQgc3BlY2lmaWVzIGhvdyB0byBwYXJzZS9zZXJpYWxpemUgaW50byB0aGUgSlNPTiB0aGF0IGlzCiAqIHRyYW5zbWl0dGVkIG92ZXIgSFRUUCB3aGVuIHdvcmtpbmcgd2l0aCB0aGUgQ2xvdWQgUmVzb3VyY2UgTWFuYWdlciBBUEkuIEZvciBhIGRldGFpbGVkCiAqIGV4cGxhbmF0aW9uIHNlZToKICogPGEgaHJlZj0iaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vYXBpLWNsaWVudC1saWJyYXJ5L2phdmEvZ29vZ2xlLWh0dHAtamF2YS1jbGllbnQvanNvbiI+aHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vYXBpLWNsaWVudC1saWJyYXJ5L2phdmEvZ29vZ2xlLWh0dHAtamF2YS1jbGllbnQvanNvbjwvYT4KICogPC9wPgogKgogKiBAYXV0aG9yIEdvb2dsZSwgSW5jLgogKi8KQFN1cHByZXNzV2FybmluZ3MoImphdmFkb2MiKQpwdWJsaWMgZmluYWwgY2xhc3MgUHJvamVjdCBleHRlbmRzIGNvbS5nb29nbGUuYXBpLmNsaWVudC5qc29uLkdlbmVyaWNKc29uIHsKCiAgLyoqCiAgICogQ3JlYXRpb24gdGltZS4KICAgKgogICAqIFJlYWQtb25seS4KICAgKiBUaGUgdmFsdWUgbWF5IGJlIHtAY29kZSBudWxsfS4KICAgKi8KICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgcHJpdmF0ZSBTdHJpbmcgY3JlYXRlVGltZTsKCiAgLyoqCiAgICogVGhlIGxhYmVscyBhc3NvY2lhdGVkIHdpdGggdGhpcyBQcm9qZWN0LgogICAqCiAgICogTGFiZWwga2V5cyBtdXN0IGJlIGJldHdlZW4gMSBhbmQgNjMgY2hhcmFjdGVycyBsb25nIGFuZCBtdXN0IGNvbmZvcm0gdG8gdGhlIGZvbGxvd2luZyByZWd1bGFyCiAgICogZXhwcmVzc2lvbjogXFthLXpcXShcWy1hLXowLTlcXSpcW2EtejAtOVxdKT8uCiAgICoKICAgKiBMYWJlbCB2YWx1ZXMgbXVzdCBiZSBiZXR3ZWVuIDAgYW5kIDYzIGNoYXJhY3RlcnMgbG9uZyBhbmQgbXVzdCBjb25mb3JtIHRvIHRoZSByZWd1bGFyCiAgICogZXhwcmVzc2lvbiAoXFthLXpcXShcWy1hLXowLTlcXSpcW2EtejAtOVxdKT8pPy4gQSBsYWJlbCB2YWx1ZSBjYW4gYmUgZW1wdHkuCiAgICoKICAgKiBObyBtb3JlIHRoYW4gMjU2IGxhYmVscyBjYW4gYmUgYXNzb2NpYXRlZCB3aXRoIGEgZ2l2ZW4gcmVzb3VyY2UuCiAgICoKICAgKiBDbGllbnRzIHNob3VsZCBzdG9yZSBsYWJlbHMgaW4gYSByZXByZXNlbnRhdGlvbiBzdWNoIGFzIEpTT04gdGhhdCBkb2VzIG5vdCBkZXBlbmQgb24gc3BlY2lmaWMKICAgKiBjaGFyYWN0ZXJzIGJlaW5nIGRpc2FsbG93ZWQuCiAgICoKICAgKiBFeGFtcGxlOiAiZW52aXJvbm1lbnQiIDogImRldiIgUmVhZC13cml0ZS4KICAgKiBUaGUgdmFsdWUgbWF5IGJlIHtAY29kZSBudWxsfS4KICAgKi8KICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgcHJpdmF0ZSBqYXZhLnV0aWwuTWFwPFN0cmluZywgamF2YS5sYW5nLlN0cmluZz4gbGFiZWxzOwoKICAvKioKICAgKiBUaGUgUHJvamVjdCBsaWZlY3ljbGUgc3RhdGUuCiAgICoKICAgKiBSZWFkLW9ubHkuCiAgICogVGhlIHZhbHVlIG1heSBiZSB7QGNvZGUgbnVsbH0uCiAgICovCiAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogIHByaXZhdGUgamF2YS5sYW5nLlN0cmluZyBsaWZlY3ljbGVTdGF0ZTsKCiAgLyoqCiAgICogVGhlIG9wdGlvbmFsIHVzZXItYXNzaWduZWQgZGlzcGxheSBuYW1lIG9mIHRoZSBQcm9qZWN0LiBXaGVuIHByZXNlbnQgaXQgbXVzdCBiZSBiZXR3ZWVuIDQgdG8gMzAKICAgKiBjaGFyYWN0ZXJzLiBBbGxvd2VkIGNoYXJhY3RlcnMgYXJlOiBsb3dlcmNhc2UgYW5kIHVwcGVyY2FzZSBsZXR0ZXJzLCBudW1iZXJzLCBoeXBoZW4sIHNpbmdsZS0KICAgKiBxdW90ZSwgZG91YmxlLXF1b3RlLCBzcGFjZSwgYW5kIGV4Y2xhbWF0aW9uIHBvaW50LgogICAqCiAgICogRXhhbXBsZTogTXkgUHJvamVjdCBSZWFkLXdyaXRlLgogICAqIFRoZSB2YWx1ZSBtYXkgYmUge0Bjb2RlIG51bGx9LgogICAqLwogIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICBwcml2YXRlIGphdmEubGFuZy5TdHJpbmcgbmFtZTsKCiAgLyoqCiAgICogQW4gb3B0aW9uYWwgcmVmZXJlbmNlIHRvIGEgcGFyZW50IFJlc291cmNlLgogICAqCiAgICogU3VwcG9ydGVkIHBhcmVudCB0eXBlcyBpbmNsdWRlICJvcmdhbml6YXRpb24iIGFuZCAiZm9sZGVyIi4gT25jZSBzZXQsIHRoZSBwYXJlbnQgY2Fubm90IGJlCiAgICogY2xlYXJlZC4gVGhlIGBwYXJlbnRgIGNhbiBiZSBzZXQgb24gY3JlYXRpb24gb3IgdXNpbmcgdGhlIGBVcGRhdGVQcm9qZWN0YCBtZXRob2Q7IHRoZSBlbmQgdXNlcgogICAqIG11c3QgaGF2ZSB0aGUgYHJlc291cmNlbWFuYWdlci5wcm9qZWN0cy5jcmVhdGVgIHBlcm1pc3Npb24gb24gdGhlIHBhcmVudC4KICAgKgogICAqIFJlYWQtd3JpdGUuCiAgICogVGhlIHZhbHVlIG1heSBiZSB7QGNvZGUgbnVsbH0uCiAgICovCiAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogIHByaXZhdGUgUmVzb3VyY2VJZCBwYXJlbnQ7CgogIC8qKgogICAqIFRoZSB1bmlxdWUsIHVzZXItYXNzaWduZWQgSUQgb2YgdGhlIFByb2plY3QuIEl0IG11c3QgYmUgNiB0byAzMCBsb3dlcmNhc2UgbGV0dGVycywgZGlnaXRzLCBvcgogICAqIGh5cGhlbnMuIEl0IG11c3Qgc3RhcnQgd2l0aCBhIGxldHRlci4gVHJhaWxpbmcgaHlwaGVucyBhcmUgcHJvaGliaXRlZC4KICAgKgogICAqIEV4YW1wbGU6IHRva3lvLXJhaW4tMTIzIFJlYWQtb25seSBhZnRlciBjcmVhdGlvbi4KICAgKiBUaGUgdmFsdWUgbWF5IGJlIHtAY29kZSBudWxsfS4KICAgKi8KICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgcHJpdmF0ZSBqYXZhLmxhbmcuU3RyaW5nIHByb2plY3RJZDsKCiAgLyoqCiAgICogVGhlIG51bWJlciB1bmlxdWVseSBpZGVudGlmeWluZyB0aGUgcHJvamVjdC4KICAgKgogICAqIEV4YW1wbGU6IDQxNTEwNDA0MTI2MiBSZWFkLW9ubHkuCiAgICogVGhlIHZhbHVlIG1heSBiZSB7QGNvZGUgbnVsbH0uCiAgICovCiAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleSBAY29tLmdvb2dsZS5hcGkuY2xpZW50Lmpzb24uSnNvblN0cmluZwogIHByaXZhdGUgamF2YS5sYW5nLkxvbmcgcHJvamVjdE51bWJlcjsKCiAgLyoqCiAgICogQ3JlYXRpb24gdGltZS4KICAgKgogICAqIFJlYWQtb25seS4KICAgKiBAcmV0dXJuIHZhbHVlIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBTdHJpbmcgZ2V0Q3JlYXRlVGltZSgpIHsKICAgIHJldHVybiBjcmVhdGVUaW1lOwogIH0KCiAgLyoqCiAgICogQ3JlYXRpb24gdGltZS4KICAgKgogICAqIFJlYWQtb25seS4KICAgKiBAcGFyYW0gY3JlYXRlVGltZSBjcmVhdGVUaW1lIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBQcm9qZWN0IHNldENyZWF0ZVRpbWUoU3RyaW5nIGNyZWF0ZVRpbWUpIHsKICAgIHRoaXMuY3JlYXRlVGltZSA9IGNyZWF0ZVRpbWU7CiAgICByZXR1cm4gdGhpczsKICB9CgogIC8qKgogICAqIFRoZSBsYWJlbHMgYXNzb2NpYXRlZCB3aXRoIHRoaXMgUHJvamVjdC4KICAgKgogICAqIExhYmVsIGtleXMgbXVzdCBiZSBiZXR3ZWVuIDEgYW5kIDYzIGNoYXJhY3RlcnMgbG9uZyBhbmQgbXVzdCBjb25mb3JtIHRvIHRoZSBmb2xsb3dpbmcgcmVndWxhcgogICAqIGV4cHJlc3Npb246IFxbYS16XF0oXFstYS16MC05XF0qXFthLXowLTlcXSk/LgogICAqCiAgICogTGFiZWwgdmFsdWVzIG11c3QgYmUgYmV0d2VlbiAwIGFuZCA2MyBjaGFyYWN0ZXJzIGxvbmcgYW5kIG11c3QgY29uZm9ybSB0byB0aGUgcmVndWxhcgogICAqIGV4cHJlc3Npb24gKFxbYS16XF0oXFstYS16MC05XF0qXFthLXowLTlcXSk/KT8uIEEgbGFiZWwgdmFsdWUgY2FuIGJlIGVtcHR5LgogICAqCiAgICogTm8gbW9yZSB0aGFuIDI1NiBsYWJlbHMgY2FuIGJlIGFzc29jaWF0ZWQgd2l0aCBhIGdpdmVuIHJlc291cmNlLgogICAqCiAgICogQ2xpZW50cyBzaG91bGQgc3RvcmUgbGFiZWxzIGluIGEgcmVwcmVzZW50YXRpb24gc3VjaCBhcyBKU09OIHRoYXQgZG9lcyBub3QgZGVwZW5kIG9uIHNwZWNpZmljCiAgICogY2hhcmFjdGVycyBiZWluZyBkaXNhbGxvd2VkLgogICAqCiAgICogRXhhbXBsZTogImVudmlyb25tZW50IiA6ICJkZXYiIFJlYWQtd3JpdGUuCiAgICogQHJldHVybiB2YWx1ZSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgamF2YS51dGlsLk1hcDxTdHJpbmcsIGphdmEubGFuZy5TdHJpbmc+IGdldExhYmVscygpIHsKICAgIHJldHVybiBsYWJlbHM7CiAgfQoKICAvKioKICAgKiBUaGUgbGFiZWxzIGFzc29jaWF0ZWQgd2l0aCB0aGlzIFByb2plY3QuCiAgICoKICAgKiBMYWJlbCBrZXlzIG11c3QgYmUgYmV0d2VlbiAxIGFuZCA2MyBjaGFyYWN0ZXJzIGxvbmcgYW5kIG11c3QgY29uZm9ybSB0byB0aGUgZm9sbG93aW5nIHJlZ3VsYXIKICAgKiBleHByZXNzaW9uOiBcW2EtelxdKFxbLWEtejAtOVxdKlxbYS16MC05XF0pPy4KICAgKgogICAqIExhYmVsIHZhbHVlcyBtdXN0IGJlIGJldHdlZW4gMCBhbmQgNjMgY2hhcmFjdGVycyBsb25nIGFuZCBtdXN0IGNvbmZvcm0gdG8gdGhlIHJlZ3VsYXIKICAgKiBleHByZXNzaW9uIChcW2EtelxdKFxbLWEtejAtOVxdKlxbYS16MC05XF0pPyk/LiBBIGxhYmVsIHZhbHVlIGNhbiBiZSBlbXB0eS4KICAgKgogICAqIE5vIG1vcmUgdGhhbiAyNTYgbGFiZWxzIGNhbiBiZSBhc3NvY2lhdGVkIHdpdGggYSBnaXZlbiByZXNvdXJjZS4KICAgKgogICAqIENsaWVudHMgc2hvdWxkIHN0b3JlIGxhYmVscyBpbiBhIHJlcHJlc2VudGF0aW9uIHN1Y2ggYXMgSlNPTiB0aGF0IGRvZXMgbm90IGRlcGVuZCBvbiBzcGVjaWZpYwogICAqIGNoYXJhY3RlcnMgYmVpbmcgZGlzYWxsb3dlZC4KICAgKgogICAqIEV4YW1wbGU6ICJlbnZpcm9ubWVudCIgOiAiZGV2IiBSZWFkLXdyaXRlLgogICAqIEBwYXJhbSBsYWJlbHMgbGFiZWxzIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBQcm9qZWN0IHNldExhYmVscyhqYXZhLnV0aWwuTWFwPFN0cmluZywgamF2YS5sYW5nLlN0cmluZz4gbGFiZWxzKSB7CiAgICB0aGlzLmxhYmVscyA9IGxhYmVsczsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgLyoqCiAgICogVGhlIFByb2plY3QgbGlmZWN5Y2xlIHN0YXRlLgogICAqCiAgICogUmVhZC1vbmx5LgogICAqIEByZXR1cm4gdmFsdWUgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TGlmZWN5Y2xlU3RhdGUoKSB7CiAgICByZXR1cm4gbGlmZWN5Y2xlU3RhdGU7CiAgfQoKICAvKioKICAgKiBUaGUgUHJvamVjdCBsaWZlY3ljbGUgc3RhdGUuCiAgICoKICAgKiBSZWFkLW9ubHkuCiAgICogQHBhcmFtIGxpZmVjeWNsZVN0YXRlIGxpZmVjeWNsZVN0YXRlIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBQcm9qZWN0IHNldExpZmVjeWNsZVN0YXRlKGphdmEubGFuZy5TdHJpbmcgbGlmZWN5Y2xlU3RhdGUpIHsKICAgIHRoaXMubGlmZWN5Y2xlU3RhdGUgPSBsaWZlY3ljbGVTdGF0ZTsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgLyoqCiAgICogVGhlIG9wdGlvbmFsIHVzZXItYXNzaWduZWQgZGlzcGxheSBuYW1lIG9mIHRoZSBQcm9qZWN0LiBXaGVuIHByZXNlbnQgaXQgbXVzdCBiZSBiZXR3ZWVuIDQgdG8gMzAKICAgKiBjaGFyYWN0ZXJzLiBBbGxvd2VkIGNoYXJhY3RlcnMgYXJlOiBsb3dlcmNhc2UgYW5kIHVwcGVyY2FzZSBsZXR0ZXJzLCBudW1iZXJzLCBoeXBoZW4sIHNpbmdsZS0KICAgKiBxdW90ZSwgZG91YmxlLXF1b3RlLCBzcGFjZSwgYW5kIGV4Y2xhbWF0aW9uIHBvaW50LgogICAqCiAgICogRXhhbXBsZTogTXkgUHJvamVjdCBSZWFkLXdyaXRlLgogICAqIEByZXR1cm4gdmFsdWUgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TmFtZSgpIHsKICAgIHJldHVybiBuYW1lOwogIH0KCiAgLyoqCiAgICogVGhlIG9wdGlvbmFsIHVzZXItYXNzaWduZWQgZGlzcGxheSBuYW1lIG9mIHRoZSBQcm9qZWN0LiBXaGVuIHByZXNlbnQgaXQgbXVzdCBiZSBiZXR3ZWVuIDQgdG8gMzAKICAgKiBjaGFyYWN0ZXJzLiBBbGxvd2VkIGNoYXJhY3RlcnMgYXJlOiBsb3dlcmNhc2UgYW5kIHVwcGVyY2FzZSBsZXR0ZXJzLCBudW1iZXJzLCBoeXBoZW4sIHNpbmdsZS0KICAgKiBxdW90ZSwgZG91YmxlLXF1b3RlLCBzcGFjZSwgYW5kIGV4Y2xhbWF0aW9uIHBvaW50LgogICAqCiAgICogRXhhbXBsZTogTXkgUHJvamVjdCBSZWFkLXdyaXRlLgogICAqIEBwYXJhbSBuYW1lIG5hbWUgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIFByb2plY3Qgc2V0TmFtZShqYXZhLmxhbmcuU3RyaW5nIG5hbWUpIHsKICAgIHRoaXMubmFtZSA9IG5hbWU7CiAgICByZXR1cm4gdGhpczsKICB9CgogIC8qKgogICAqIEFuIG9wdGlvbmFsIHJlZmVyZW5jZSB0byBhIHBhcmVudCBSZXNvdXJjZS4KICAgKgogICAqIFN1cHBvcnRlZCBwYXJlbnQgdHlwZXMgaW5jbHVkZSAib3JnYW5pemF0aW9uIiBhbmQgImZvbGRlciIuIE9uY2Ugc2V0LCB0aGUgcGFyZW50IGNhbm5vdCBiZQogICAqIGNsZWFyZWQuIFRoZSBgcGFyZW50YCBjYW4gYmUgc2V0IG9uIGNyZWF0aW9uIG9yIHVzaW5nIHRoZSBgVXBkYXRlUHJvamVjdGAgbWV0aG9kOyB0aGUgZW5kIHVzZXIKICAgKiBtdXN0IGhhdmUgdGhlIGByZXNvdXJjZW1hbmFnZXIucHJvamVjdHMuY3JlYXRlYCBwZXJtaXNzaW9uIG9uIHRoZSBwYXJlbnQuCiAgICoKICAgKiBSZWFkLXdyaXRlLgogICAqIEByZXR1cm4gdmFsdWUgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIFJlc291cmNlSWQgZ2V0UGFyZW50KCkgewogICAgcmV0dXJuIHBhcmVudDsKICB9CgogIC8qKgogICAqIEFuIG9wdGlvbmFsIHJlZmVyZW5jZSB0byBhIHBhcmVudCBSZXNvdXJjZS4KICAgKgogICAqIFN1cHBvcnRlZCBwYXJlbnQgdHlwZXMgaW5jbHVkZSAib3JnYW5pemF0aW9uIiBhbmQgImZvbGRlciIuIE9uY2Ugc2V0LCB0aGUgcGFyZW50IGNhbm5vdCBiZQogICAqIGNsZWFyZWQuIFRoZSBgcGFyZW50YCBjYW4gYmUgc2V0IG9uIGNyZWF0aW9uIG9yIHVzaW5nIHRoZSBgVXBkYXRlUHJvamVjdGAgbWV0aG9kOyB0aGUgZW5kIHVzZXIKICAgKiBtdXN0IGhhdmUgdGhlIGByZXNvdXJjZW1hbmFnZXIucHJvamVjdHMuY3JlYXRlYCBwZXJtaXNzaW9uIG9uIHRoZSBwYXJlbnQuCiAgICoKICAgKiBSZWFkLXdyaXRlLgogICAqIEBwYXJhbSBwYXJlbnQgcGFyZW50IG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBQcm9qZWN0IHNldFBhcmVudChSZXNvdXJjZUlkIHBhcmVudCkgewogICAgdGhpcy5wYXJlbnQgPSBwYXJlbnQ7CiAgICByZXR1cm4gdGhpczsKICB9CgogIC8qKgogICAqIFRoZSB1bmlxdWUsIHVzZXItYXNzaWduZWQgSUQgb2YgdGhlIFByb2plY3QuIEl0IG11c3QgYmUgNiB0byAzMCBsb3dlcmNhc2UgbGV0dGVycywgZGlnaXRzLCBvcgogICAqIGh5cGhlbnMuIEl0IG11c3Qgc3RhcnQgd2l0aCBhIGxldHRlci4gVHJhaWxpbmcgaHlwaGVucyBhcmUgcHJvaGliaXRlZC4KICAgKgogICAqIEV4YW1wbGU6IHRva3lvLXJhaW4tMTIzIFJlYWQtb25seSBhZnRlciBjcmVhdGlvbi4KICAgKiBAcmV0dXJuIHZhbHVlIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFByb2plY3RJZCgpIHsKICAgIHJldHVybiBwcm9qZWN0SWQ7CiAgfQoKICAvKioKICAgKiBUaGUgdW5pcXVlLCB1c2VyLWFzc2lnbmVkIElEIG9mIHRoZSBQcm9qZWN0LiBJdCBtdXN0IGJlIDYgdG8gMzAgbG93ZXJjYXNlIGxldHRlcnMsIGRpZ2l0cywgb3IKICAgKiBoeXBoZW5zLiBJdCBtdXN0IHN0YXJ0IHdpdGggYSBsZXR0ZXIuIFRyYWlsaW5nIGh5cGhlbnMgYXJlIHByb2hpYml0ZWQuCiAgICoKICAgKiBFeGFtcGxlOiB0b2t5by1yYWluLTEyMyBSZWFkLW9ubHkgYWZ0ZXIgY3JlYXRpb24uCiAgICogQHBhcmFtIHByb2plY3RJZCBwcm9qZWN0SWQgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIFByb2plY3Qgc2V0UHJvamVjdElkKGphdmEubGFuZy5TdHJpbmcgcHJvamVjdElkKSB7CiAgICB0aGlzLnByb2plY3RJZCA9IHByb2plY3RJZDsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgLyoqCiAgICogVGhlIG51bWJlciB1bmlxdWVseSBpZGVudGlmeWluZyB0aGUgcHJvamVjdC4KICAgKgogICAqIEV4YW1wbGU6IDQxNTEwNDA0MTI2MiBSZWFkLW9ubHkuCiAgICogQHJldHVybiB2YWx1ZSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgamF2YS5sYW5nLkxvbmcgZ2V0UHJvamVjdE51bWJlcigpIHsKICAgIHJldHVybiBwcm9qZWN0TnVtYmVyOwogIH0KCiAgLyoqCiAgICogVGhlIG51bWJlciB1bmlxdWVseSBpZGVudGlmeWluZyB0aGUgcHJvamVjdC4KICAgKgogICAqIEV4YW1wbGU6IDQxNTEwNDA0MTI2MiBSZWFkLW9ubHkuCiAgICogQHBhcmFtIHByb2plY3ROdW1iZXIgcHJvamVjdE51bWJlciBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgUHJvamVjdCBzZXRQcm9qZWN0TnVtYmVyKGphdmEubGFuZy5Mb25nIHByb2plY3ROdW1iZXIpIHsKICAgIHRoaXMucHJvamVjdE51bWJlciA9IHByb2plY3ROdW1iZXI7CiAgICByZXR1cm4gdGhpczsKICB9CgogIEBPdmVycmlkZQogIHB1YmxpYyBQcm9qZWN0IHNldChTdHJpbmcgZmllbGROYW1lLCBPYmplY3QgdmFsdWUpIHsKICAgIHJldHVybiAoUHJvamVjdCkgc3VwZXIuc2V0KGZpZWxkTmFtZSwgdmFsdWUpOwogIH0KCiAgQE92ZXJyaWRlCiAgcHVibGljIFByb2plY3QgY2xvbmUoKSB7CiAgICByZXR1cm4gKFByb2plY3QpIHN1cGVyLmNsb25lKCk7CiAgfQoKfQpQSwMEFAAAAAAAAAAhAD6vjONYDwAAWA8AAE0AAABjb20vZ29vZ2xlL2FwaS9zZXJ2aWNlcy9jbG91ZHJlc291cmNlbWFuYWdlci9tb2RlbC9Qcm9qZWN0Q3JlYXRpb25TdGF0dXMuamF2YS8qCiAqIENvcHlyaWdodCAyMDEwIEdvb2dsZSBJbmMuCiAqCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdAogKiBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZQogKiBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3MKICogb3IgaW1wbGllZC4gU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucyB1bmRlcgogKiB0aGUgTGljZW5zZS4KICovCi8qCiAqIFRoaXMgY29kZSB3YXMgZ2VuZXJhdGVkIGJ5IGh0dHBzOi8vZ2l0aHViLmNvbS9nb29nbGUvYXBpcy1jbGllbnQtZ2VuZXJhdG9yLwogKiAoYnVpbGQ6IDIwMTgtMTAtMDggMTc6NDU6MzkgVVRDKQogKiBvbiAyMDIwLTAzLTE5IGF0IDAyOjM4OjMwIFVUQyAKICogTW9kaWZ5IGF0IHlvdXIgb3duIHJpc2suCiAqLwoKcGFja2FnZSBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5jbG91ZHJlc291cmNlbWFuYWdlci5tb2RlbDsKCi8qKgogKiBBIHN0YXR1cyBvYmplY3Qgd2hpY2ggaXMgdXNlZCBhcyB0aGUgYG1ldGFkYXRhYCBmaWVsZCBmb3IgdGhlIE9wZXJhdGlvbiByZXR1cm5lZCBieQogKiBDcmVhdGVQcm9qZWN0LiBJdCBwcm92aWRlcyBpbnNpZ2h0IGZvciB3aGVuIHNpZ25pZmljYW50IHBoYXNlcyBvZiBQcm9qZWN0IGNyZWF0aW9uIGhhdmUKICogY29tcGxldGVkLgogKgogKiA8cD4gVGhpcyBpcyB0aGUgSmF2YSBkYXRhIG1vZGVsIGNsYXNzIHRoYXQgc3BlY2lmaWVzIGhvdyB0byBwYXJzZS9zZXJpYWxpemUgaW50byB0aGUgSlNPTiB0aGF0IGlzCiAqIHRyYW5zbWl0dGVkIG92ZXIgSFRUUCB3aGVuIHdvcmtpbmcgd2l0aCB0aGUgQ2xvdWQgUmVzb3VyY2UgTWFuYWdlciBBUEkuIEZvciBhIGRldGFpbGVkCiAqIGV4cGxhbmF0aW9uIHNlZToKICogPGEgaHJlZj0iaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vYXBpLWNsaWVudC1saWJyYXJ5L2phdmEvZ29vZ2xlLWh0dHAtamF2YS1jbGllbnQvanNvbiI+aHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vYXBpLWNsaWVudC1saWJyYXJ5L2phdmEvZ29vZ2xlLWh0dHAtamF2YS1jbGllbnQvanNvbjwvYT4KICogPC9wPgogKgogKiBAYXV0aG9yIEdvb2dsZSwgSW5jLgogKi8KQFN1cHByZXNzV2FybmluZ3MoImphdmFkb2MiKQpwdWJsaWMgZmluYWwgY2xhc3MgUHJvamVjdENyZWF0aW9uU3RhdHVzIGV4dGVuZHMgY29tLmdvb2dsZS5hcGkuY2xpZW50Lmpzb24uR2VuZXJpY0pzb24gewoKICAvKioKICAgKiBDcmVhdGlvbiB0aW1lIG9mIHRoZSBwcm9qZWN0IGNyZWF0aW9uIHdvcmtmbG93LgogICAqIFRoZSB2YWx1ZSBtYXkgYmUge0Bjb2RlIG51bGx9LgogICAqLwogIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICBwcml2YXRlIFN0cmluZyBjcmVhdGVUaW1lOwoKICAvKioKICAgKiBUcnVlIGlmIHRoZSBwcm9qZWN0IGNhbiBiZSByZXRyaWV2ZWQgdXNpbmcgR2V0UHJvamVjdC4gTm8gb3RoZXIgb3BlcmF0aW9ucyBvbiB0aGUgcHJvamVjdCBhcmUKICAgKiBndWFyYW50ZWVkIHRvIHdvcmsgdW50aWwgdGhlIHByb2plY3QgY3JlYXRpb24gaXMgY29tcGxldGUuCiAgICogVGhlIHZhbHVlIG1heSBiZSB7QGNvZGUgbnVsbH0uCiAgICovCiAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogIHByaXZhdGUgamF2YS5sYW5nLkJvb2xlYW4gZ2V0dGFibGU7CgogIC8qKgogICAqIFRydWUgaWYgdGhlIHByb2plY3QgY3JlYXRpb24gcHJvY2VzcyBpcyBjb21wbGV0ZS4KICAgKiBUaGUgdmFsdWUgbWF5IGJlIHtAY29kZSBudWxsfS4KICAgKi8KICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgcHJpdmF0ZSBqYXZhLmxhbmcuQm9vbGVhbiByZWFkeTsKCiAgLyoqCiAgICogQ3JlYXRpb24gdGltZSBvZiB0aGUgcHJvamVjdCBjcmVhdGlvbiB3b3JrZmxvdy4KICAgKiBAcmV0dXJuIHZhbHVlIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBTdHJpbmcgZ2V0Q3JlYXRlVGltZSgpIHsKICAgIHJldHVybiBjcmVhdGVUaW1lOwogIH0KCiAgLyoqCiAgICogQ3JlYXRpb24gdGltZSBvZiB0aGUgcHJvamVjdCBjcmVhdGlvbiB3b3JrZmxvdy4KICAgKiBAcGFyYW0gY3JlYXRlVGltZSBjcmVhdGVUaW1lIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBQcm9qZWN0Q3JlYXRpb25TdGF0dXMgc2V0Q3JlYXRlVGltZShTdHJpbmcgY3JlYXRlVGltZSkgewogICAgdGhpcy5jcmVhdGVUaW1lID0gY3JlYXRlVGltZTsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgLyoqCiAgICogVHJ1ZSBpZiB0aGUgcHJvamVjdCBjYW4gYmUgcmV0cmlldmVkIHVzaW5nIEdldFByb2plY3QuIE5vIG90aGVyIG9wZXJhdGlvbnMgb24gdGhlIHByb2plY3QgYXJlCiAgICogZ3VhcmFudGVlZCB0byB3b3JrIHVudGlsIHRoZSBwcm9qZWN0IGNyZWF0aW9uIGlzIGNvbXBsZXRlLgogICAqIEByZXR1cm4gdmFsdWUgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIGphdmEubGFuZy5Cb29sZWFuIGdldEdldHRhYmxlKCkgewogICAgcmV0dXJuIGdldHRhYmxlOwogIH0KCiAgLyoqCiAgICogVHJ1ZSBpZiB0aGUgcHJvamVjdCBjYW4gYmUgcmV0cmlldmVkIHVzaW5nIEdldFByb2plY3QuIE5vIG90aGVyIG9wZXJhdGlvbnMgb24gdGhlIHByb2plY3QgYXJlCiAgICogZ3VhcmFudGVlZCB0byB3b3JrIHVudGlsIHRoZSBwcm9qZWN0IGNyZWF0aW9uIGlzIGNvbXBsZXRlLgogICAqIEBwYXJhbSBnZXR0YWJsZSBnZXR0YWJsZSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgUHJvamVjdENyZWF0aW9uU3RhdHVzIHNldEdldHRhYmxlKGphdmEubGFuZy5Cb29sZWFuIGdldHRhYmxlKSB7CiAgICB0aGlzLmdldHRhYmxlID0gZ2V0dGFibGU7CiAgICByZXR1cm4gdGhpczsKICB9CgogIC8qKgogICAqIFRydWUgaWYgdGhlIHByb2plY3QgY3JlYXRpb24gcHJvY2VzcyBpcyBjb21wbGV0ZS4KICAgKiBAcmV0dXJuIHZhbHVlIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBqYXZhLmxhbmcuQm9vbGVhbiBnZXRSZWFkeSgpIHsKICAgIHJldHVybiByZWFkeTsKICB9CgogIC8qKgogICAqIFRydWUgaWYgdGhlIHByb2plY3QgY3JlYXRpb24gcHJvY2VzcyBpcyBjb21wbGV0ZS4KICAgKiBAcGFyYW0gcmVhZHkgcmVhZHkgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIFByb2plY3RDcmVhdGlvblN0YXR1cyBzZXRSZWFkeShqYXZhLmxhbmcuQm9vbGVhbiByZWFkeSkgewogICAgdGhpcy5yZWFkeSA9IHJlYWR5OwogICAgcmV0dXJuIHRoaXM7CiAgfQoKICBAT3ZlcnJpZGUKICBwdWJsaWMgUHJvamVjdENyZWF0aW9uU3RhdHVzIHNldChTdHJpbmcgZmllbGROYW1lLCBPYmplY3QgdmFsdWUpIHsKICAgIHJldHVybiAoUHJvamVjdENyZWF0aW9uU3RhdHVzKSBzdXBlci5zZXQoZmllbGROYW1lLCB2YWx1ZSk7CiAgfQoKICBAT3ZlcnJpZGUKICBwdWJsaWMgUHJvamVjdENyZWF0aW9uU3RhdHVzIGNsb25lKCkgewogICAgcmV0dXJuIChQcm9qZWN0Q3JlYXRpb25TdGF0dXMpIHN1cGVyLmNsb25lKCk7CiAgfQoKfQpQSwMEFAAAAAAAAAAhAC+NAsR2DQAAdg0AAEIAAABjb20vZ29vZ2xlL2FwaS9zZXJ2aWNlcy9jbG91ZHJlc291cmNlbWFuYWdlci9tb2RlbC9SZXNvdXJjZUlkLmphdmEvKgogKiBDb3B5cmlnaHQgMjAxMCBHb29nbGUgSW5jLgogKgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQKICogaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UKICogaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzCiAqIG9yIGltcGxpZWQuIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMgdW5kZXIKICogdGhlIExpY2Vuc2UuCiAqLwovKgogKiBUaGlzIGNvZGUgd2FzIGdlbmVyYXRlZCBieSBodHRwczovL2dpdGh1Yi5jb20vZ29vZ2xlL2FwaXMtY2xpZW50LWdlbmVyYXRvci8KICogKGJ1aWxkOiAyMDE4LTEwLTA4IDE3OjQ1OjM5IFVUQykKICogb24gMjAyMC0wMy0xOSBhdCAwMjozODozMCBVVEMgCiAqIE1vZGlmeSBhdCB5b3VyIG93biByaXNrLgogKi8KCnBhY2thZ2UgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuY2xvdWRyZXNvdXJjZW1hbmFnZXIubW9kZWw7CgovKioKICogQSBjb250YWluZXIgdG8gcmVmZXJlbmNlIGFuIGlkIGZvciBhbnkgcmVzb3VyY2UgdHlwZS4gQSBgcmVzb3VyY2VgIGluIEdvb2dsZSBDbG91ZCBQbGF0Zm9ybSBpcyBhCiAqIGdlbmVyaWMgdGVybSBmb3Igc29tZXRoaW5nIHlvdSAoYSBkZXZlbG9wZXIpIG1heSB3YW50IHRvIGludGVyYWN0IHdpdGggdGhyb3VnaCBvbmUgb2Ygb3VyIEFQSSdzLgogKiBTb21lIGV4YW1wbGVzIGFyZSBhbiBBcHAgRW5naW5lIGFwcCwgYSBDb21wdXRlIEVuZ2luZSBpbnN0YW5jZSwgYSBDbG91ZCBTUUwgZGF0YWJhc2UsIGFuZCBzbyBvbi4KICoKICogPHA+IFRoaXMgaXMgdGhlIEphdmEgZGF0YSBtb2RlbCBjbGFzcyB0aGF0IHNwZWNpZmllcyBob3cgdG8gcGFyc2Uvc2VyaWFsaXplIGludG8gdGhlIEpTT04gdGhhdCBpcwogKiB0cmFuc21pdHRlZCBvdmVyIEhUVFAgd2hlbiB3b3JraW5nIHdpdGggdGhlIENsb3VkIFJlc291cmNlIE1hbmFnZXIgQVBJLiBGb3IgYSBkZXRhaWxlZAogKiBleHBsYW5hdGlvbiBzZWU6CiAqIDxhIGhyZWY9Imh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL2FwaS1jbGllbnQtbGlicmFyeS9qYXZhL2dvb2dsZS1odHRwLWphdmEtY2xpZW50L2pzb24iPmh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL2FwaS1jbGllbnQtbGlicmFyeS9qYXZhL2dvb2dsZS1odHRwLWphdmEtY2xpZW50L2pzb248L2E+CiAqIDwvcD4KICoKICogQGF1dGhvciBHb29nbGUsIEluYy4KICovCkBTdXBwcmVzc1dhcm5pbmdzKCJqYXZhZG9jIikKcHVibGljIGZpbmFsIGNsYXNzIFJlc291cmNlSWQgZXh0ZW5kcyBjb20uZ29vZ2xlLmFwaS5jbGllbnQuanNvbi5HZW5lcmljSnNvbiB7CgogIC8qKgogICAqIFJlcXVpcmVkIGZpZWxkIGZvciB0aGUgdHlwZS1zcGVjaWZpYyBpZC4gVGhpcyBzaG91bGQgY29ycmVzcG9uZCB0byB0aGUgaWQgdXNlZCBpbiB0aGUgdHlwZS0KICAgKiBzcGVjaWZpYyBBUEkncy4KICAgKiBUaGUgdmFsdWUgbWF5IGJlIHtAY29kZSBudWxsfS4KICAgKi8KICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgcHJpdmF0ZSBqYXZhLmxhbmcuU3RyaW5nIGlkOwoKICAvKioKICAgKiBSZXF1aXJlZCBmaWVsZCByZXByZXNlbnRpbmcgdGhlIHJlc291cmNlIHR5cGUgdGhpcyBpZCBpcyBmb3IuIEF0IHByZXNlbnQsIHRoZSB2YWxpZCB0eXBlcyBhcmU6CiAgICogIm9yZ2FuaXphdGlvbiIsICJmb2xkZXIiLCBhbmQgInByb2plY3QiLgogICAqIFRoZSB2YWx1ZSBtYXkgYmUge0Bjb2RlIG51bGx9LgogICAqLwogIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICBwcml2YXRlIGphdmEubGFuZy5TdHJpbmcgdHlwZTsKCiAgLyoqCiAgICogUmVxdWlyZWQgZmllbGQgZm9yIHRoZSB0eXBlLXNwZWNpZmljIGlkLiBUaGlzIHNob3VsZCBjb3JyZXNwb25kIHRvIHRoZSBpZCB1c2VkIGluIHRoZSB0eXBlLQogICAqIHNwZWNpZmljIEFQSSdzLgogICAqIEByZXR1cm4gdmFsdWUgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0SWQoKSB7CiAgICByZXR1cm4gaWQ7CiAgfQoKICAvKioKICAgKiBSZXF1aXJlZCBmaWVsZCBmb3IgdGhlIHR5cGUtc3BlY2lmaWMgaWQuIFRoaXMgc2hvdWxkIGNvcnJlc3BvbmQgdG8gdGhlIGlkIHVzZWQgaW4gdGhlIHR5cGUtCiAgICogc3BlY2lmaWMgQVBJJ3MuCiAgICogQHBhcmFtIGlkIGlkIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBSZXNvdXJjZUlkIHNldElkKGphdmEubGFuZy5TdHJpbmcgaWQpIHsKICAgIHRoaXMuaWQgPSBpZDsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgLyoqCiAgICogUmVxdWlyZWQgZmllbGQgcmVwcmVzZW50aW5nIHRoZSByZXNvdXJjZSB0eXBlIHRoaXMgaWQgaXMgZm9yLiBBdCBwcmVzZW50LCB0aGUgdmFsaWQgdHlwZXMgYXJlOgogICAqICJvcmdhbml6YXRpb24iLCAiZm9sZGVyIiwgYW5kICJwcm9qZWN0Ii4KICAgKiBAcmV0dXJuIHZhbHVlIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFR5cGUoKSB7CiAgICByZXR1cm4gdHlwZTsKICB9CgogIC8qKgogICAqIFJlcXVpcmVkIGZpZWxkIHJlcHJlc2VudGluZyB0aGUgcmVzb3VyY2UgdHlwZSB0aGlzIGlkIGlzIGZvci4gQXQgcHJlc2VudCwgdGhlIHZhbGlkIHR5cGVzIGFyZToKICAgKiAib3JnYW5pemF0aW9uIiwgImZvbGRlciIsIGFuZCAicHJvamVjdCIuCiAgICogQHBhcmFtIHR5cGUgdHlwZSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgUmVzb3VyY2VJZCBzZXRUeXBlKGphdmEubGFuZy5TdHJpbmcgdHlwZSkgewogICAgdGhpcy50eXBlID0gdHlwZTsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgQE92ZXJyaWRlCiAgcHVibGljIFJlc291cmNlSWQgc2V0KFN0cmluZyBmaWVsZE5hbWUsIE9iamVjdCB2YWx1ZSkgewogICAgcmV0dXJuIChSZXNvdXJjZUlkKSBzdXBlci5zZXQoZmllbGROYW1lLCB2YWx1ZSk7CiAgfQoKICBAT3ZlcnJpZGUKICBwdWJsaWMgUmVzb3VyY2VJZCBjbG9uZSgpIHsKICAgIHJldHVybiAoUmVzb3VyY2VJZCkgc3VwZXIuY2xvbmUoKTsKICB9Cgp9ClBLAwQUAAAAAAAAACEA3rhVdw8JAAAPCQAARgAAAGNvbS9nb29nbGUvYXBpL3NlcnZpY2VzL2Nsb3VkcmVzb3VyY2VtYW5hZ2VyL21vZGVsL1Jlc3RvcmVEZWZhdWx0LmphdmEvKgogKiBDb3B5cmlnaHQgMjAxMCBHb29nbGUgSW5jLgogKgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQKICogaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UKICogaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzCiAqIG9yIGltcGxpZWQuIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMgdW5kZXIKICogdGhlIExpY2Vuc2UuCiAqLwovKgogKiBUaGlzIGNvZGUgd2FzIGdlbmVyYXRlZCBieSBodHRwczovL2dpdGh1Yi5jb20vZ29vZ2xlL2FwaXMtY2xpZW50LWdlbmVyYXRvci8KICogKGJ1aWxkOiAyMDE4LTEwLTA4IDE3OjQ1OjM5IFVUQykKICogb24gMjAyMC0wMy0xOSBhdCAwMjozODozMCBVVEMgCiAqIE1vZGlmeSBhdCB5b3VyIG93biByaXNrLgogKi8KCnBhY2thZ2UgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuY2xvdWRyZXNvdXJjZW1hbmFnZXIubW9kZWw7CgovKioKICogSWdub3JlcyBwb2xpY2llcyBzZXQgYWJvdmUgdGhpcyByZXNvdXJjZSBhbmQgcmVzdG9yZXMgdGhlIGBjb25zdHJhaW50X2RlZmF1bHRgIGVuZm9yY2VtZW50CiAqIGJlaGF2aW9yIG9mIHRoZSBzcGVjaWZpYyBgQ29uc3RyYWludGAgYXQgdGhpcyByZXNvdXJjZS4KICoKICogU3VwcG9zZSB0aGF0IGBjb25zdHJhaW50X2RlZmF1bHRgIGlzIHNldCB0byBgQUxMT1dgIGZvciB0aGUgYENvbnN0cmFpbnRgCiAqIGBjb25zdHJhaW50cy9zZXJ2aWNldXNlci5zZXJ2aWNlc2AuIFN1cHBvc2UgdGhhdCBvcmdhbml6YXRpb24gZm9vLmNvbSBzZXRzIGEgYFBvbGljeWAgYXQgdGhlaXIKICogT3JnYW5pemF0aW9uIHJlc291cmNlIG5vZGUgdGhhdCByZXN0cmljdHMgdGhlIGFsbG93ZWQgc2VydmljZSBhY3RpdmF0aW9ucyB0byBkZW55IGFsbCBzZXJ2aWNlCiAqIGFjdGl2YXRpb25zLiBUaGV5IGNvdWxkIHRoZW4gc2V0IGEgYFBvbGljeWAgd2l0aCB0aGUgYHBvbGljeV90eXBlYCBgcmVzdG9yZV9kZWZhdWx0YCBvbiBzZXZlcmFsCiAqIGV4cGVyaW1lbnRhbCBwcm9qZWN0cywgcmVzdG9yaW5nIHRoZSBgY29uc3RyYWludF9kZWZhdWx0YCBlbmZvcmNlbWVudCBvZiB0aGUgYENvbnN0cmFpbnRgIGZvcgogKiBvbmx5IHRob3NlIHByb2plY3RzLCBhbGxvd2luZyB0aG9zZSBwcm9qZWN0cyB0byBoYXZlIGFsbCBzZXJ2aWNlcyBhY3RpdmF0ZWQuCiAqCiAqIDxwPiBUaGlzIGlzIHRoZSBKYXZhIGRhdGEgbW9kZWwgY2xhc3MgdGhhdCBzcGVjaWZpZXMgaG93IHRvIHBhcnNlL3NlcmlhbGl6ZSBpbnRvIHRoZSBKU09OIHRoYXQgaXMKICogdHJhbnNtaXR0ZWQgb3ZlciBIVFRQIHdoZW4gd29ya2luZyB3aXRoIHRoZSBDbG91ZCBSZXNvdXJjZSBNYW5hZ2VyIEFQSS4gRm9yIGEgZGV0YWlsZWQKICogZXhwbGFuYXRpb24gc2VlOgogKiA8YSBocmVmPSJodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9hcGktY2xpZW50LWxpYnJhcnkvamF2YS9nb29nbGUtaHR0cC1qYXZhLWNsaWVudC9qc29uIj5odHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9hcGktY2xpZW50LWxpYnJhcnkvamF2YS9nb29nbGUtaHR0cC1qYXZhLWNsaWVudC9qc29uPC9hPgogKiA8L3A+CiAqCiAqIEBhdXRob3IgR29vZ2xlLCBJbmMuCiAqLwpAU3VwcHJlc3NXYXJuaW5ncygiamF2YWRvYyIpCnB1YmxpYyBmaW5hbCBjbGFzcyBSZXN0b3JlRGVmYXVsdCBleHRlbmRzIGNvbS5nb29nbGUuYXBpLmNsaWVudC5qc29uLkdlbmVyaWNKc29uIHsKCiAgQE92ZXJyaWRlCiAgcHVibGljIFJlc3RvcmVEZWZhdWx0IHNldChTdHJpbmcgZmllbGROYW1lLCBPYmplY3QgdmFsdWUpIHsKICAgIHJldHVybiAoUmVzdG9yZURlZmF1bHQpIHN1cGVyLnNldChmaWVsZE5hbWUsIHZhbHVlKTsKICB9CgogIEBPdmVycmlkZQogIHB1YmxpYyBSZXN0b3JlRGVmYXVsdCBjbG9uZSgpIHsKICAgIHJldHVybiAoUmVzdG9yZURlZmF1bHQpIHN1cGVyLmNsb25lKCk7CiAgfQoKfQpQSwMEFAAAAAAAAAAhAF5iCYh0FQAAdBUAAFIAAABjb20vZ29vZ2xlL2FwaS9zZXJ2aWNlcy9jbG91ZHJlc291cmNlbWFuYWdlci9tb2RlbC9TZWFyY2hPcmdhbml6YXRpb25zUmVxdWVzdC5qYXZhLyoKICogQ29weXJpZ2h0IDIwMTAgR29vZ2xlIEluYy4KICoKICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0CiAqIGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4gWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlCiAqIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcwogKiBvciBpbXBsaWVkLiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zIHVuZGVyCiAqIHRoZSBMaWNlbnNlLgogKi8KLyoKICogVGhpcyBjb2RlIHdhcyBnZW5lcmF0ZWQgYnkgaHR0cHM6Ly9naXRodWIuY29tL2dvb2dsZS9hcGlzLWNsaWVudC1nZW5lcmF0b3IvCiAqIChidWlsZDogMjAxOC0xMC0wOCAxNzo0NTozOSBVVEMpCiAqIG9uIDIwMjAtMDMtMTkgYXQgMDI6Mzg6MzAgVVRDIAogKiBNb2RpZnkgYXQgeW91ciBvd24gcmlzay4KICovCgpwYWNrYWdlIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmNsb3VkcmVzb3VyY2VtYW5hZ2VyLm1vZGVsOwoKLyoqCiAqIFRoZSByZXF1ZXN0IHNlbnQgdG8gdGhlIGBTZWFyY2hPcmdhbml6YXRpb25zYCBtZXRob2QuCiAqCiAqIDxwPiBUaGlzIGlzIHRoZSBKYXZhIGRhdGEgbW9kZWwgY2xhc3MgdGhhdCBzcGVjaWZpZXMgaG93IHRvIHBhcnNlL3NlcmlhbGl6ZSBpbnRvIHRoZSBKU09OIHRoYXQgaXMKICogdHJhbnNtaXR0ZWQgb3ZlciBIVFRQIHdoZW4gd29ya2luZyB3aXRoIHRoZSBDbG91ZCBSZXNvdXJjZSBNYW5hZ2VyIEFQSS4gRm9yIGEgZGV0YWlsZWQKICogZXhwbGFuYXRpb24gc2VlOgogKiA8YSBocmVmPSJodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9hcGktY2xpZW50LWxpYnJhcnkvamF2YS9nb29nbGUtaHR0cC1qYXZhLWNsaWVudC9qc29uIj5odHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9hcGktY2xpZW50LWxpYnJhcnkvamF2YS9nb29nbGUtaHR0cC1qYXZhLWNsaWVudC9qc29uPC9hPgogKiA8L3A+CiAqCiAqIEBhdXRob3IgR29vZ2xlLCBJbmMuCiAqLwpAU3VwcHJlc3NXYXJuaW5ncygiamF2YWRvYyIpCnB1YmxpYyBmaW5hbCBjbGFzcyBTZWFyY2hPcmdhbml6YXRpb25zUmVxdWVzdCBleHRlbmRzIGNvbS5nb29nbGUuYXBpLmNsaWVudC5qc29uLkdlbmVyaWNKc29uIHsKCiAgLyoqCiAgICogQW4gb3B0aW9uYWwgcXVlcnkgc3RyaW5nIHVzZWQgdG8gZmlsdGVyIHRoZSBPcmdhbml6YXRpb25zIHRvIHJldHVybiBpbiB0aGUgcmVzcG9uc2UuIEZpbHRlcgogICAqIHJ1bGVzIGFyZSBjYXNlLWluc2Vuc2l0aXZlLgogICAqCiAgICogT3JnYW5pemF0aW9ucyBtYXkgYmUgZmlsdGVyZWQgYnkgYG93bmVyLmRpcmVjdG9yeUN1c3RvbWVySWRgIG9yIGJ5IGBkb21haW5gLCB3aGVyZSB0aGUgZG9tYWluCiAgICogaXMgYSBHIFN1aXRlIGRvbWFpbiwgZm9yIGV4YW1wbGU6CiAgICoKICAgKiAqIEZpbHRlciBgb3duZXIuZGlyZWN0b3J5Y3VzdG9tZXJpZDoxMjM0NTY3ODlgIHJldHVybnMgT3JnYW5pemF0aW9uIHJlc291cmNlcyB3aXRoCiAgICogYG93bmVyLmRpcmVjdG9yeV9jdXN0b21lcl9pZGAgZXF1YWwgdG8gYDEyMzQ1Njc4OWAuICogRmlsdGVyIGBkb21haW46Z29vZ2xlLmNvbWAgcmV0dXJucwogICAqIE9yZ2FuaXphdGlvbiByZXNvdXJjZXMgY29ycmVzcG9uZGluZyB0byB0aGUgZG9tYWluIGBnb29nbGUuY29tYC4KICAgKgogICAqIFRoaXMgZmllbGQgaXMgb3B0aW9uYWwuCiAgICogVGhlIHZhbHVlIG1heSBiZSB7QGNvZGUgbnVsbH0uCiAgICovCiAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogIHByaXZhdGUgamF2YS5sYW5nLlN0cmluZyBmaWx0ZXI7CgogIC8qKgogICAqIFRoZSBtYXhpbXVtIG51bWJlciBvZiBPcmdhbml6YXRpb25zIHRvIHJldHVybiBpbiB0aGUgcmVzcG9uc2UuIFRoaXMgZmllbGQgaXMgb3B0aW9uYWwuCiAgICogVGhlIHZhbHVlIG1heSBiZSB7QGNvZGUgbnVsbH0uCiAgICovCiAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogIHByaXZhdGUgamF2YS5sYW5nLkludGVnZXIgcGFnZVNpemU7CgogIC8qKgogICAqIEEgcGFnaW5hdGlvbiB0b2tlbiByZXR1cm5lZCBmcm9tIGEgcHJldmlvdXMgY2FsbCB0byBgU2VhcmNoT3JnYW5pemF0aW9uc2AgdGhhdCBpbmRpY2F0ZXMgZnJvbQogICAqIHdoZXJlIGxpc3Rpbmcgc2hvdWxkIGNvbnRpbnVlLiBUaGlzIGZpZWxkIGlzIG9wdGlvbmFsLgogICAqIFRoZSB2YWx1ZSBtYXkgYmUge0Bjb2RlIG51bGx9LgogICAqLwogIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICBwcml2YXRlIGphdmEubGFuZy5TdHJpbmcgcGFnZVRva2VuOwoKICAvKioKICAgKiBBbiBvcHRpb25hbCBxdWVyeSBzdHJpbmcgdXNlZCB0byBmaWx0ZXIgdGhlIE9yZ2FuaXphdGlvbnMgdG8gcmV0dXJuIGluIHRoZSByZXNwb25zZS4gRmlsdGVyCiAgICogcnVsZXMgYXJlIGNhc2UtaW5zZW5zaXRpdmUuCiAgICoKICAgKiBPcmdhbml6YXRpb25zIG1heSBiZSBmaWx0ZXJlZCBieSBgb3duZXIuZGlyZWN0b3J5Q3VzdG9tZXJJZGAgb3IgYnkgYGRvbWFpbmAsIHdoZXJlIHRoZSBkb21haW4KICAgKiBpcyBhIEcgU3VpdGUgZG9tYWluLCBmb3IgZXhhbXBsZToKICAgKgogICAqICogRmlsdGVyIGBvd25lci5kaXJlY3RvcnljdXN0b21lcmlkOjEyMzQ1Njc4OWAgcmV0dXJucyBPcmdhbml6YXRpb24gcmVzb3VyY2VzIHdpdGgKICAgKiBgb3duZXIuZGlyZWN0b3J5X2N1c3RvbWVyX2lkYCBlcXVhbCB0byBgMTIzNDU2Nzg5YC4gKiBGaWx0ZXIgYGRvbWFpbjpnb29nbGUuY29tYCByZXR1cm5zCiAgICogT3JnYW5pemF0aW9uIHJlc291cmNlcyBjb3JyZXNwb25kaW5nIHRvIHRoZSBkb21haW4gYGdvb2dsZS5jb21gLgogICAqCiAgICogVGhpcyBmaWVsZCBpcyBvcHRpb25hbC4KICAgKiBAcmV0dXJuIHZhbHVlIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldEZpbHRlcigpIHsKICAgIHJldHVybiBmaWx0ZXI7CiAgfQoKICAvKioKICAgKiBBbiBvcHRpb25hbCBxdWVyeSBzdHJpbmcgdXNlZCB0byBmaWx0ZXIgdGhlIE9yZ2FuaXphdGlvbnMgdG8gcmV0dXJuIGluIHRoZSByZXNwb25zZS4gRmlsdGVyCiAgICogcnVsZXMgYXJlIGNhc2UtaW5zZW5zaXRpdmUuCiAgICoKICAgKiBPcmdhbml6YXRpb25zIG1heSBiZSBmaWx0ZXJlZCBieSBgb3duZXIuZGlyZWN0b3J5Q3VzdG9tZXJJZGAgb3IgYnkgYGRvbWFpbmAsIHdoZXJlIHRoZSBkb21haW4KICAgKiBpcyBhIEcgU3VpdGUgZG9tYWluLCBmb3IgZXhhbXBsZToKICAgKgogICAqICogRmlsdGVyIGBvd25lci5kaXJlY3RvcnljdXN0b21lcmlkOjEyMzQ1Njc4OWAgcmV0dXJucyBPcmdhbml6YXRpb24gcmVzb3VyY2VzIHdpdGgKICAgKiBgb3duZXIuZGlyZWN0b3J5X2N1c3RvbWVyX2lkYCBlcXVhbCB0byBgMTIzNDU2Nzg5YC4gKiBGaWx0ZXIgYGRvbWFpbjpnb29nbGUuY29tYCByZXR1cm5zCiAgICogT3JnYW5pemF0aW9uIHJlc291cmNlcyBjb3JyZXNwb25kaW5nIHRvIHRoZSBkb21haW4gYGdvb2dsZS5jb21gLgogICAqCiAgICogVGhpcyBmaWVsZCBpcyBvcHRpb25hbC4KICAgKiBAcGFyYW0gZmlsdGVyIGZpbHRlciBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgU2VhcmNoT3JnYW5pemF0aW9uc1JlcXVlc3Qgc2V0RmlsdGVyKGphdmEubGFuZy5TdHJpbmcgZmlsdGVyKSB7CiAgICB0aGlzLmZpbHRlciA9IGZpbHRlcjsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgLyoqCiAgICogVGhlIG1heGltdW0gbnVtYmVyIG9mIE9yZ2FuaXphdGlvbnMgdG8gcmV0dXJuIGluIHRoZSByZXNwb25zZS4gVGhpcyBmaWVsZCBpcyBvcHRpb25hbC4KICAgKiBAcmV0dXJuIHZhbHVlIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBqYXZhLmxhbmcuSW50ZWdlciBnZXRQYWdlU2l6ZSgpIHsKICAgIHJldHVybiBwYWdlU2l6ZTsKICB9CgogIC8qKgogICAqIFRoZSBtYXhpbXVtIG51bWJlciBvZiBPcmdhbml6YXRpb25zIHRvIHJldHVybiBpbiB0aGUgcmVzcG9uc2UuIFRoaXMgZmllbGQgaXMgb3B0aW9uYWwuCiAgICogQHBhcmFtIHBhZ2VTaXplIHBhZ2VTaXplIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBTZWFyY2hPcmdhbml6YXRpb25zUmVxdWVzdCBzZXRQYWdlU2l6ZShqYXZhLmxhbmcuSW50ZWdlciBwYWdlU2l6ZSkgewogICAgdGhpcy5wYWdlU2l6ZSA9IHBhZ2VTaXplOwogICAgcmV0dXJuIHRoaXM7CiAgfQoKICAvKioKICAgKiBBIHBhZ2luYXRpb24gdG9rZW4gcmV0dXJuZWQgZnJvbSBhIHByZXZpb3VzIGNhbGwgdG8gYFNlYXJjaE9yZ2FuaXphdGlvbnNgIHRoYXQgaW5kaWNhdGVzIGZyb20KICAgKiB3aGVyZSBsaXN0aW5nIHNob3VsZCBjb250aW51ZS4gVGhpcyBmaWVsZCBpcyBvcHRpb25hbC4KICAgKiBAcmV0dXJuIHZhbHVlIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldFBhZ2VUb2tlbigpIHsKICAgIHJldHVybiBwYWdlVG9rZW47CiAgfQoKICAvKioKICAgKiBBIHBhZ2luYXRpb24gdG9rZW4gcmV0dXJuZWQgZnJvbSBhIHByZXZpb3VzIGNhbGwgdG8gYFNlYXJjaE9yZ2FuaXphdGlvbnNgIHRoYXQgaW5kaWNhdGVzIGZyb20KICAgKiB3aGVyZSBsaXN0aW5nIHNob3VsZCBjb250aW51ZS4gVGhpcyBmaWVsZCBpcyBvcHRpb25hbC4KICAgKiBAcGFyYW0gcGFnZVRva2VuIHBhZ2VUb2tlbiBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgU2VhcmNoT3JnYW5pemF0aW9uc1JlcXVlc3Qgc2V0UGFnZVRva2VuKGphdmEubGFuZy5TdHJpbmcgcGFnZVRva2VuKSB7CiAgICB0aGlzLnBhZ2VUb2tlbiA9IHBhZ2VUb2tlbjsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgQE92ZXJyaWRlCiAgcHVibGljIFNlYXJjaE9yZ2FuaXphdGlvbnNSZXF1ZXN0IHNldChTdHJpbmcgZmllbGROYW1lLCBPYmplY3QgdmFsdWUpIHsKICAgIHJldHVybiAoU2VhcmNoT3JnYW5pemF0aW9uc1JlcXVlc3QpIHN1cGVyLnNldChmaWVsZE5hbWUsIHZhbHVlKTsKICB9CgogIEBPdmVycmlkZQogIHB1YmxpYyBTZWFyY2hPcmdhbml6YXRpb25zUmVxdWVzdCBjbG9uZSgpIHsKICAgIHJldHVybiAoU2VhcmNoT3JnYW5pemF0aW9uc1JlcXVlc3QpIHN1cGVyLmNsb25lKCk7CiAgfQoKfQpQSwMEFAAAAAAAAAAhAOwusyDLDwAAyw8AAFMAAABjb20vZ29vZ2xlL2FwaS9zZXJ2aWNlcy9jbG91ZHJlc291cmNlbWFuYWdlci9tb2RlbC9TZWFyY2hPcmdhbml6YXRpb25zUmVzcG9uc2UuamF2YS8qCiAqIENvcHlyaWdodCAyMDEwIEdvb2dsZSBJbmMuCiAqCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdAogKiBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZQogKiBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3MKICogb3IgaW1wbGllZC4gU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucyB1bmRlcgogKiB0aGUgTGljZW5zZS4KICovCi8qCiAqIFRoaXMgY29kZSB3YXMgZ2VuZXJhdGVkIGJ5IGh0dHBzOi8vZ2l0aHViLmNvbS9nb29nbGUvYXBpcy1jbGllbnQtZ2VuZXJhdG9yLwogKiAoYnVpbGQ6IDIwMTgtMTAtMDggMTc6NDU6MzkgVVRDKQogKiBvbiAyMDIwLTAzLTE5IGF0IDAyOjM4OjMwIFVUQyAKICogTW9kaWZ5IGF0IHlvdXIgb3duIHJpc2suCiAqLwoKcGFja2FnZSBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5jbG91ZHJlc291cmNlbWFuYWdlci5tb2RlbDsKCi8qKgogKiBUaGUgcmVzcG9uc2UgcmV0dXJuZWQgZnJvbSB0aGUgYFNlYXJjaE9yZ2FuaXphdGlvbnNgIG1ldGhvZC4KICoKICogPHA+IFRoaXMgaXMgdGhlIEphdmEgZGF0YSBtb2RlbCBjbGFzcyB0aGF0IHNwZWNpZmllcyBob3cgdG8gcGFyc2Uvc2VyaWFsaXplIGludG8gdGhlIEpTT04gdGhhdCBpcwogKiB0cmFuc21pdHRlZCBvdmVyIEhUVFAgd2hlbiB3b3JraW5nIHdpdGggdGhlIENsb3VkIFJlc291cmNlIE1hbmFnZXIgQVBJLiBGb3IgYSBkZXRhaWxlZAogKiBleHBsYW5hdGlvbiBzZWU6CiAqIDxhIGhyZWY9Imh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL2FwaS1jbGllbnQtbGlicmFyeS9qYXZhL2dvb2dsZS1odHRwLWphdmEtY2xpZW50L2pzb24iPmh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL2FwaS1jbGllbnQtbGlicmFyeS9qYXZhL2dvb2dsZS1odHRwLWphdmEtY2xpZW50L2pzb248L2E+CiAqIDwvcD4KICoKICogQGF1dGhvciBHb29nbGUsIEluYy4KICovCkBTdXBwcmVzc1dhcm5pbmdzKCJqYXZhZG9jIikKcHVibGljIGZpbmFsIGNsYXNzIFNlYXJjaE9yZ2FuaXphdGlvbnNSZXNwb25zZSBleHRlbmRzIGNvbS5nb29nbGUuYXBpLmNsaWVudC5qc29uLkdlbmVyaWNKc29uIHsKCiAgLyoqCiAgICogQSBwYWdpbmF0aW9uIHRva2VuIHRvIGJlIHVzZWQgdG8gcmV0cmlldmUgdGhlIG5leHQgcGFnZSBvZiByZXN1bHRzLiBJZiB0aGUgcmVzdWx0IGlzIHRvbyBsYXJnZQogICAqIHRvIGZpdCB3aXRoaW4gdGhlIHBhZ2Ugc2l6ZSBzcGVjaWZpZWQgaW4gdGhlIHJlcXVlc3QsIHRoaXMgZmllbGQgd2lsbCBiZSBzZXQgd2l0aCBhIHRva2VuIHRoYXQKICAgKiBjYW4gYmUgdXNlZCB0byBmZXRjaCB0aGUgbmV4dCBwYWdlIG9mIHJlc3VsdHMuIElmIHRoaXMgZmllbGQgaXMgZW1wdHksIGl0IGluZGljYXRlcyB0aGF0IHRoaXMKICAgKiByZXNwb25zZSBjb250YWlucyB0aGUgbGFzdCBwYWdlIG9mIHJlc3VsdHMuCiAgICogVGhlIHZhbHVlIG1heSBiZSB7QGNvZGUgbnVsbH0uCiAgICovCiAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogIHByaXZhdGUgamF2YS5sYW5nLlN0cmluZyBuZXh0UGFnZVRva2VuOwoKICAvKioKICAgKiBUaGUgbGlzdCBvZiBPcmdhbml6YXRpb25zIHRoYXQgbWF0Y2hlZCB0aGUgc2VhcmNoIHF1ZXJ5LCBwb3NzaWJseSBwYWdpbmF0ZWQuCiAgICogVGhlIHZhbHVlIG1heSBiZSB7QGNvZGUgbnVsbH0uCiAgICovCiAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogIHByaXZhdGUgamF2YS51dGlsLkxpc3Q8T3JnYW5pemF0aW9uPiBvcmdhbml6YXRpb25zOwoKICAvKioKICAgKiBBIHBhZ2luYXRpb24gdG9rZW4gdG8gYmUgdXNlZCB0byByZXRyaWV2ZSB0aGUgbmV4dCBwYWdlIG9mIHJlc3VsdHMuIElmIHRoZSByZXN1bHQgaXMgdG9vIGxhcmdlCiAgICogdG8gZml0IHdpdGhpbiB0aGUgcGFnZSBzaXplIHNwZWNpZmllZCBpbiB0aGUgcmVxdWVzdCwgdGhpcyBmaWVsZCB3aWxsIGJlIHNldCB3aXRoIGEgdG9rZW4gdGhhdAogICAqIGNhbiBiZSB1c2VkIHRvIGZldGNoIHRoZSBuZXh0IHBhZ2Ugb2YgcmVzdWx0cy4gSWYgdGhpcyBmaWVsZCBpcyBlbXB0eSwgaXQgaW5kaWNhdGVzIHRoYXQgdGhpcwogICAqIHJlc3BvbnNlIGNvbnRhaW5zIHRoZSBsYXN0IHBhZ2Ugb2YgcmVzdWx0cy4KICAgKiBAcmV0dXJuIHZhbHVlIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBqYXZhLmxhbmcuU3RyaW5nIGdldE5leHRQYWdlVG9rZW4oKSB7CiAgICByZXR1cm4gbmV4dFBhZ2VUb2tlbjsKICB9CgogIC8qKgogICAqIEEgcGFnaW5hdGlvbiB0b2tlbiB0byBiZSB1c2VkIHRvIHJldHJpZXZlIHRoZSBuZXh0IHBhZ2Ugb2YgcmVzdWx0cy4gSWYgdGhlIHJlc3VsdCBpcyB0b28gbGFyZ2UKICAgKiB0byBmaXQgd2l0aGluIHRoZSBwYWdlIHNpemUgc3BlY2lmaWVkIGluIHRoZSByZXF1ZXN0LCB0aGlzIGZpZWxkIHdpbGwgYmUgc2V0IHdpdGggYSB0b2tlbiB0aGF0CiAgICogY2FuIGJlIHVzZWQgdG8gZmV0Y2ggdGhlIG5leHQgcGFnZSBvZiByZXN1bHRzLiBJZiB0aGlzIGZpZWxkIGlzIGVtcHR5LCBpdCBpbmRpY2F0ZXMgdGhhdCB0aGlzCiAgICogcmVzcG9uc2UgY29udGFpbnMgdGhlIGxhc3QgcGFnZSBvZiByZXN1bHRzLgogICAqIEBwYXJhbSBuZXh0UGFnZVRva2VuIG5leHRQYWdlVG9rZW4gb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIFNlYXJjaE9yZ2FuaXphdGlvbnNSZXNwb25zZSBzZXROZXh0UGFnZVRva2VuKGphdmEubGFuZy5TdHJpbmcgbmV4dFBhZ2VUb2tlbikgewogICAgdGhpcy5uZXh0UGFnZVRva2VuID0gbmV4dFBhZ2VUb2tlbjsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgLyoqCiAgICogVGhlIGxpc3Qgb2YgT3JnYW5pemF0aW9ucyB0aGF0IG1hdGNoZWQgdGhlIHNlYXJjaCBxdWVyeSwgcG9zc2libHkgcGFnaW5hdGVkLgogICAqIEByZXR1cm4gdmFsdWUgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIGphdmEudXRpbC5MaXN0PE9yZ2FuaXphdGlvbj4gZ2V0T3JnYW5pemF0aW9ucygpIHsKICAgIHJldHVybiBvcmdhbml6YXRpb25zOwogIH0KCiAgLyoqCiAgICogVGhlIGxpc3Qgb2YgT3JnYW5pemF0aW9ucyB0aGF0IG1hdGNoZWQgdGhlIHNlYXJjaCBxdWVyeSwgcG9zc2libHkgcGFnaW5hdGVkLgogICAqIEBwYXJhbSBvcmdhbml6YXRpb25zIG9yZ2FuaXphdGlvbnMgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIFNlYXJjaE9yZ2FuaXphdGlvbnNSZXNwb25zZSBzZXRPcmdhbml6YXRpb25zKGphdmEudXRpbC5MaXN0PE9yZ2FuaXphdGlvbj4gb3JnYW5pemF0aW9ucykgewogICAgdGhpcy5vcmdhbml6YXRpb25zID0gb3JnYW5pemF0aW9uczsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgQE92ZXJyaWRlCiAgcHVibGljIFNlYXJjaE9yZ2FuaXphdGlvbnNSZXNwb25zZSBzZXQoU3RyaW5nIGZpZWxkTmFtZSwgT2JqZWN0IHZhbHVlKSB7CiAgICByZXR1cm4gKFNlYXJjaE9yZ2FuaXphdGlvbnNSZXNwb25zZSkgc3VwZXIuc2V0KGZpZWxkTmFtZSwgdmFsdWUpOwogIH0KCiAgQE92ZXJyaWRlCiAgcHVibGljIFNlYXJjaE9yZ2FuaXphdGlvbnNSZXNwb25zZSBjbG9uZSgpIHsKICAgIHJldHVybiAoU2VhcmNoT3JnYW5pemF0aW9uc1Jlc3BvbnNlKSBzdXBlci5jbG9uZSgpOwogIH0KCn0KUEsDBBQAAAAAAAAAIQCjxha2hw8AAIcPAABLAAAAY29tL2dvb2dsZS9hcGkvc2VydmljZXMvY2xvdWRyZXNvdXJjZW1hbmFnZXIvbW9kZWwvU2V0SWFtUG9saWN5UmVxdWVzdC5qYXZhLyoKICogQ29weXJpZ2h0IDIwMTAgR29vZ2xlIEluYy4KICoKICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0CiAqIGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4gWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlCiAqIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcwogKiBvciBpbXBsaWVkLiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zIHVuZGVyCiAqIHRoZSBMaWNlbnNlLgogKi8KLyoKICogVGhpcyBjb2RlIHdhcyBnZW5lcmF0ZWQgYnkgaHR0cHM6Ly9naXRodWIuY29tL2dvb2dsZS9hcGlzLWNsaWVudC1nZW5lcmF0b3IvCiAqIChidWlsZDogMjAxOC0xMC0wOCAxNzo0NTozOSBVVEMpCiAqIG9uIDIwMjAtMDMtMTkgYXQgMDI6Mzg6MzAgVVRDIAogKiBNb2RpZnkgYXQgeW91ciBvd24gcmlzay4KICovCgpwYWNrYWdlIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmNsb3VkcmVzb3VyY2VtYW5hZ2VyLm1vZGVsOwoKLyoqCiAqIFJlcXVlc3QgbWVzc2FnZSBmb3IgYFNldElhbVBvbGljeWAgbWV0aG9kLgogKgogKiA8cD4gVGhpcyBpcyB0aGUgSmF2YSBkYXRhIG1vZGVsIGNsYXNzIHRoYXQgc3BlY2lmaWVzIGhvdyB0byBwYXJzZS9zZXJpYWxpemUgaW50byB0aGUgSlNPTiB0aGF0IGlzCiAqIHRyYW5zbWl0dGVkIG92ZXIgSFRUUCB3aGVuIHdvcmtpbmcgd2l0aCB0aGUgQ2xvdWQgUmVzb3VyY2UgTWFuYWdlciBBUEkuIEZvciBhIGRldGFpbGVkCiAqIGV4cGxhbmF0aW9uIHNlZToKICogPGEgaHJlZj0iaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vYXBpLWNsaWVudC1saWJyYXJ5L2phdmEvZ29vZ2xlLWh0dHAtamF2YS1jbGllbnQvanNvbiI+aHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vYXBpLWNsaWVudC1saWJyYXJ5L2phdmEvZ29vZ2xlLWh0dHAtamF2YS1jbGllbnQvanNvbjwvYT4KICogPC9wPgogKgogKiBAYXV0aG9yIEdvb2dsZSwgSW5jLgogKi8KQFN1cHByZXNzV2FybmluZ3MoImphdmFkb2MiKQpwdWJsaWMgZmluYWwgY2xhc3MgU2V0SWFtUG9saWN5UmVxdWVzdCBleHRlbmRzIGNvbS5nb29nbGUuYXBpLmNsaWVudC5qc29uLkdlbmVyaWNKc29uIHsKCiAgLyoqCiAgICogUkVRVUlSRUQ6IFRoZSBjb21wbGV0ZSBwb2xpY3kgdG8gYmUgYXBwbGllZCB0byB0aGUgYHJlc291cmNlYC4gVGhlIHNpemUgb2YgdGhlIHBvbGljeSBpcwogICAqIGxpbWl0ZWQgdG8gYSBmZXcgMTBzIG9mIEtCLiBBbiBlbXB0eSBwb2xpY3kgaXMgYSB2YWxpZCBwb2xpY3kgYnV0IGNlcnRhaW4gQ2xvdWQgUGxhdGZvcm0KICAgKiBzZXJ2aWNlcyAoc3VjaCBhcyBQcm9qZWN0cykgbWlnaHQgcmVqZWN0IHRoZW0uCiAgICogVGhlIHZhbHVlIG1heSBiZSB7QGNvZGUgbnVsbH0uCiAgICovCiAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogIHByaXZhdGUgUG9saWN5IHBvbGljeTsKCiAgLyoqCiAgICogT1BUSU9OQUw6IEEgRmllbGRNYXNrIHNwZWNpZnlpbmcgd2hpY2ggZmllbGRzIG9mIHRoZSBwb2xpY3kgdG8gbW9kaWZ5LiBPbmx5IHRoZSBmaWVsZHMgaW4gdGhlCiAgICogbWFzayB3aWxsIGJlIG1vZGlmaWVkLiBJZiBubyBtYXNrIGlzIHByb3ZpZGVkLCB0aGUgZm9sbG93aW5nIGRlZmF1bHQgbWFzayBpcyB1c2VkOiBwYXRoczoKICAgKiAiYmluZGluZ3MsIGV0YWciIFRoaXMgZmllbGQgaXMgb25seSB1c2VkIGJ5IENsb3VkIElBTS4KICAgKiBUaGUgdmFsdWUgbWF5IGJlIHtAY29kZSBudWxsfS4KICAgKi8KICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgcHJpdmF0ZSBTdHJpbmcgdXBkYXRlTWFzazsKCiAgLyoqCiAgICogUkVRVUlSRUQ6IFRoZSBjb21wbGV0ZSBwb2xpY3kgdG8gYmUgYXBwbGllZCB0byB0aGUgYHJlc291cmNlYC4gVGhlIHNpemUgb2YgdGhlIHBvbGljeSBpcwogICAqIGxpbWl0ZWQgdG8gYSBmZXcgMTBzIG9mIEtCLiBBbiBlbXB0eSBwb2xpY3kgaXMgYSB2YWxpZCBwb2xpY3kgYnV0IGNlcnRhaW4gQ2xvdWQgUGxhdGZvcm0KICAgKiBzZXJ2aWNlcyAoc3VjaCBhcyBQcm9qZWN0cykgbWlnaHQgcmVqZWN0IHRoZW0uCiAgICogQHJldHVybiB2YWx1ZSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgUG9saWN5IGdldFBvbGljeSgpIHsKICAgIHJldHVybiBwb2xpY3k7CiAgfQoKICAvKioKICAgKiBSRVFVSVJFRDogVGhlIGNvbXBsZXRlIHBvbGljeSB0byBiZSBhcHBsaWVkIHRvIHRoZSBgcmVzb3VyY2VgLiBUaGUgc2l6ZSBvZiB0aGUgcG9saWN5IGlzCiAgICogbGltaXRlZCB0byBhIGZldyAxMHMgb2YgS0IuIEFuIGVtcHR5IHBvbGljeSBpcyBhIHZhbGlkIHBvbGljeSBidXQgY2VydGFpbiBDbG91ZCBQbGF0Zm9ybQogICAqIHNlcnZpY2VzIChzdWNoIGFzIFByb2plY3RzKSBtaWdodCByZWplY3QgdGhlbS4KICAgKiBAcGFyYW0gcG9saWN5IHBvbGljeSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgU2V0SWFtUG9saWN5UmVxdWVzdCBzZXRQb2xpY3koUG9saWN5IHBvbGljeSkgewogICAgdGhpcy5wb2xpY3kgPSBwb2xpY3k7CiAgICByZXR1cm4gdGhpczsKICB9CgogIC8qKgogICAqIE9QVElPTkFMOiBBIEZpZWxkTWFzayBzcGVjaWZ5aW5nIHdoaWNoIGZpZWxkcyBvZiB0aGUgcG9saWN5IHRvIG1vZGlmeS4gT25seSB0aGUgZmllbGRzIGluIHRoZQogICAqIG1hc2sgd2lsbCBiZSBtb2RpZmllZC4gSWYgbm8gbWFzayBpcyBwcm92aWRlZCwgdGhlIGZvbGxvd2luZyBkZWZhdWx0IG1hc2sgaXMgdXNlZDogcGF0aHM6CiAgICogImJpbmRpbmdzLCBldGFnIiBUaGlzIGZpZWxkIGlzIG9ubHkgdXNlZCBieSBDbG91ZCBJQU0uCiAgICogQHJldHVybiB2YWx1ZSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgU3RyaW5nIGdldFVwZGF0ZU1hc2soKSB7CiAgICByZXR1cm4gdXBkYXRlTWFzazsKICB9CgogIC8qKgogICAqIE9QVElPTkFMOiBBIEZpZWxkTWFzayBzcGVjaWZ5aW5nIHdoaWNoIGZpZWxkcyBvZiB0aGUgcG9saWN5IHRvIG1vZGlmeS4gT25seSB0aGUgZmllbGRzIGluIHRoZQogICAqIG1hc2sgd2lsbCBiZSBtb2RpZmllZC4gSWYgbm8gbWFzayBpcyBwcm92aWRlZCwgdGhlIGZvbGxvd2luZyBkZWZhdWx0IG1hc2sgaXMgdXNlZDogcGF0aHM6CiAgICogImJpbmRpbmdzLCBldGFnIiBUaGlzIGZpZWxkIGlzIG9ubHkgdXNlZCBieSBDbG91ZCBJQU0uCiAgICogQHBhcmFtIHVwZGF0ZU1hc2sgdXBkYXRlTWFzayBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgU2V0SWFtUG9saWN5UmVxdWVzdCBzZXRVcGRhdGVNYXNrKFN0cmluZyB1cGRhdGVNYXNrKSB7CiAgICB0aGlzLnVwZGF0ZU1hc2sgPSB1cGRhdGVNYXNrOwogICAgcmV0dXJuIHRoaXM7CiAgfQoKICBAT3ZlcnJpZGUKICBwdWJsaWMgU2V0SWFtUG9saWN5UmVxdWVzdCBzZXQoU3RyaW5nIGZpZWxkTmFtZSwgT2JqZWN0IHZhbHVlKSB7CiAgICByZXR1cm4gKFNldElhbVBvbGljeVJlcXVlc3QpIHN1cGVyLnNldChmaWVsZE5hbWUsIHZhbHVlKTsKICB9CgogIEBPdmVycmlkZQogIHB1YmxpYyBTZXRJYW1Qb2xpY3lSZXF1ZXN0IGNsb25lKCkgewogICAgcmV0dXJuIChTZXRJYW1Qb2xpY3lSZXF1ZXN0KSBzdXBlci5jbG9uZSgpOwogIH0KCn0KUEsDBBQAAAAAAAAAIQDk2/JOnAgAAJwIAABLAAAAY29tL2dvb2dsZS9hcGkvc2VydmljZXMvY2xvdWRyZXNvdXJjZW1hbmFnZXIvbW9kZWwvU2V0T3JnUG9saWN5UmVxdWVzdC5qYXZhLyoKICogQ29weXJpZ2h0IDIwMTAgR29vZ2xlIEluYy4KICoKICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0CiAqIGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4gWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlCiAqIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcwogKiBvciBpbXBsaWVkLiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zIHVuZGVyCiAqIHRoZSBMaWNlbnNlLgogKi8KLyoKICogVGhpcyBjb2RlIHdhcyBnZW5lcmF0ZWQgYnkgaHR0cHM6Ly9naXRodWIuY29tL2dvb2dsZS9hcGlzLWNsaWVudC1nZW5lcmF0b3IvCiAqIChidWlsZDogMjAxOC0xMC0wOCAxNzo0NTozOSBVVEMpCiAqIG9uIDIwMjAtMDMtMTkgYXQgMDI6Mzg6MzAgVVRDIAogKiBNb2RpZnkgYXQgeW91ciBvd24gcmlzay4KICovCgpwYWNrYWdlIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmNsb3VkcmVzb3VyY2VtYW5hZ2VyLm1vZGVsOwoKLyoqCiAqIFRoZSByZXF1ZXN0IHNlbnQgdG8gdGhlIFNldE9yZ1BvbGljeVJlcXVlc3QgbWV0aG9kLgogKgogKiA8cD4gVGhpcyBpcyB0aGUgSmF2YSBkYXRhIG1vZGVsIGNsYXNzIHRoYXQgc3BlY2lmaWVzIGhvdyB0byBwYXJzZS9zZXJpYWxpemUgaW50byB0aGUgSlNPTiB0aGF0IGlzCiAqIHRyYW5zbWl0dGVkIG92ZXIgSFRUUCB3aGVuIHdvcmtpbmcgd2l0aCB0aGUgQ2xvdWQgUmVzb3VyY2UgTWFuYWdlciBBUEkuIEZvciBhIGRldGFpbGVkCiAqIGV4cGxhbmF0aW9uIHNlZToKICogPGEgaHJlZj0iaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vYXBpLWNsaWVudC1saWJyYXJ5L2phdmEvZ29vZ2xlLWh0dHAtamF2YS1jbGllbnQvanNvbiI+aHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vYXBpLWNsaWVudC1saWJyYXJ5L2phdmEvZ29vZ2xlLWh0dHAtamF2YS1jbGllbnQvanNvbjwvYT4KICogPC9wPgogKgogKiBAYXV0aG9yIEdvb2dsZSwgSW5jLgogKi8KQFN1cHByZXNzV2FybmluZ3MoImphdmFkb2MiKQpwdWJsaWMgZmluYWwgY2xhc3MgU2V0T3JnUG9saWN5UmVxdWVzdCBleHRlbmRzIGNvbS5nb29nbGUuYXBpLmNsaWVudC5qc29uLkdlbmVyaWNKc29uIHsKCiAgLyoqCiAgICogYFBvbGljeWAgdG8gc2V0IG9uIHRoZSByZXNvdXJjZS4KICAgKiBUaGUgdmFsdWUgbWF5IGJlIHtAY29kZSBudWxsfS4KICAgKi8KICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgcHJpdmF0ZSBPcmdQb2xpY3kgcG9saWN5OwoKICAvKioKICAgKiBgUG9saWN5YCB0byBzZXQgb24gdGhlIHJlc291cmNlLgogICAqIEByZXR1cm4gdmFsdWUgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIE9yZ1BvbGljeSBnZXRQb2xpY3koKSB7CiAgICByZXR1cm4gcG9saWN5OwogIH0KCiAgLyoqCiAgICogYFBvbGljeWAgdG8gc2V0IG9uIHRoZSByZXNvdXJjZS4KICAgKiBAcGFyYW0gcG9saWN5IHBvbGljeSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgU2V0T3JnUG9saWN5UmVxdWVzdCBzZXRQb2xpY3koT3JnUG9saWN5IHBvbGljeSkgewogICAgdGhpcy5wb2xpY3kgPSBwb2xpY3k7CiAgICByZXR1cm4gdGhpczsKICB9CgogIEBPdmVycmlkZQogIHB1YmxpYyBTZXRPcmdQb2xpY3lSZXF1ZXN0IHNldChTdHJpbmcgZmllbGROYW1lLCBPYmplY3QgdmFsdWUpIHsKICAgIHJldHVybiAoU2V0T3JnUG9saWN5UmVxdWVzdCkgc3VwZXIuc2V0KGZpZWxkTmFtZSwgdmFsdWUpOwogIH0KCiAgQE92ZXJyaWRlCiAgcHVibGljIFNldE9yZ1BvbGljeVJlcXVlc3QgY2xvbmUoKSB7CiAgICByZXR1cm4gKFNldE9yZ1BvbGljeVJlcXVlc3QpIHN1cGVyLmNsb25lKCk7CiAgfQoKfQpQSwMEFAAAAAAAAAAhAJmVP02tEQAArREAAD4AAABjb20vZ29vZ2xlL2FwaS9zZXJ2aWNlcy9jbG91ZHJlc291cmNlbWFuYWdlci9tb2RlbC9TdGF0dXMuamF2YS8qCiAqIENvcHlyaWdodCAyMDEwIEdvb2dsZSBJbmMuCiAqCiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdAogKiBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAogKgogKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZQogKiBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3MKICogb3IgaW1wbGllZC4gU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucyB1bmRlcgogKiB0aGUgTGljZW5zZS4KICovCi8qCiAqIFRoaXMgY29kZSB3YXMgZ2VuZXJhdGVkIGJ5IGh0dHBzOi8vZ2l0aHViLmNvbS9nb29nbGUvYXBpcy1jbGllbnQtZ2VuZXJhdG9yLwogKiAoYnVpbGQ6IDIwMTgtMTAtMDggMTc6NDU6MzkgVVRDKQogKiBvbiAyMDIwLTAzLTE5IGF0IDAyOjM4OjMwIFVUQyAKICogTW9kaWZ5IGF0IHlvdXIgb3duIHJpc2suCiAqLwoKcGFja2FnZSBjb20uZ29vZ2xlLmFwaS5zZXJ2aWNlcy5jbG91ZHJlc291cmNlbWFuYWdlci5tb2RlbDsKCi8qKgogKiBUaGUgYFN0YXR1c2AgdHlwZSBkZWZpbmVzIGEgbG9naWNhbCBlcnJvciBtb2RlbCB0aGF0IGlzIHN1aXRhYmxlIGZvciBkaWZmZXJlbnQgcHJvZ3JhbW1pbmcKICogZW52aXJvbm1lbnRzLCBpbmNsdWRpbmcgUkVTVCBBUElzIGFuZCBSUEMgQVBJcy4gSXQgaXMgdXNlZCBieSBbZ1JQQ10oaHR0cHM6Ly9naXRodWIuY29tL2dycGMpLgogKiBFYWNoIGBTdGF0dXNgIG1lc3NhZ2UgY29udGFpbnMgdGhyZWUgcGllY2VzIG9mIGRhdGE6IGVycm9yIGNvZGUsIGVycm9yIG1lc3NhZ2UsIGFuZCBlcnJvcgogKiBkZXRhaWxzLgogKgogKiBZb3UgY2FuIGZpbmQgb3V0IG1vcmUgYWJvdXQgdGhpcyBlcnJvciBtb2RlbCBhbmQgaG93IHRvIHdvcmsgd2l0aCBpdCBpbiB0aGUgW0FQSSBEZXNpZ24KICogR3VpZGVdKGh0dHBzOi8vY2xvdWQuZ29vZ2xlLmNvbS9hcGlzL2Rlc2lnbi9lcnJvcnMpLgogKgogKiA8cD4gVGhpcyBpcyB0aGUgSmF2YSBkYXRhIG1vZGVsIGNsYXNzIHRoYXQgc3BlY2lmaWVzIGhvdyB0byBwYXJzZS9zZXJpYWxpemUgaW50byB0aGUgSlNPTiB0aGF0IGlzCiAqIHRyYW5zbWl0dGVkIG92ZXIgSFRUUCB3aGVuIHdvcmtpbmcgd2l0aCB0aGUgQ2xvdWQgUmVzb3VyY2UgTWFuYWdlciBBUEkuIEZvciBhIGRldGFpbGVkCiAqIGV4cGxhbmF0aW9uIHNlZToKICogPGEgaHJlZj0iaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vYXBpLWNsaWVudC1saWJyYXJ5L2phdmEvZ29vZ2xlLWh0dHAtamF2YS1jbGllbnQvanNvbiI+aHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vYXBpLWNsaWVudC1saWJyYXJ5L2phdmEvZ29vZ2xlLWh0dHAtamF2YS1jbGllbnQvanNvbjwvYT4KICogPC9wPgogKgogKiBAYXV0aG9yIEdvb2dsZSwgSW5jLgogKi8KQFN1cHByZXNzV2FybmluZ3MoImphdmFkb2MiKQpwdWJsaWMgZmluYWwgY2xhc3MgU3RhdHVzIGV4dGVuZHMgY29tLmdvb2dsZS5hcGkuY2xpZW50Lmpzb24uR2VuZXJpY0pzb24gewoKICAvKioKICAgKiBUaGUgc3RhdHVzIGNvZGUsIHdoaWNoIHNob3VsZCBiZSBhbiBlbnVtIHZhbHVlIG9mIGdvb2dsZS5ycGMuQ29kZS4KICAgKiBUaGUgdmFsdWUgbWF5IGJlIHtAY29kZSBudWxsfS4KICAgKi8KICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgcHJpdmF0ZSBqYXZhLmxhbmcuSW50ZWdlciBjb2RlOwoKICAvKioKICAgKiBBIGxpc3Qgb2YgbWVzc2FnZXMgdGhhdCBjYXJyeSB0aGUgZXJyb3IgZGV0YWlscy4gIFRoZXJlIGlzIGEgY29tbW9uIHNldCBvZiBtZXNzYWdlIHR5cGVzIGZvcgogICAqIEFQSXMgdG8gdXNlLgogICAqIFRoZSB2YWx1ZSBtYXkgYmUge0Bjb2RlIG51bGx9LgogICAqLwogIEBjb20uZ29vZ2xlLmFwaS5jbGllbnQudXRpbC5LZXkKICBwcml2YXRlIGphdmEudXRpbC5MaXN0PGphdmEudXRpbC5NYXA8U3RyaW5nLCBqYXZhLmxhbmcuT2JqZWN0Pj4gZGV0YWlsczsKCiAgLyoqCiAgICogQSBkZXZlbG9wZXItZmFjaW5nIGVycm9yIG1lc3NhZ2UsIHdoaWNoIHNob3VsZCBiZSBpbiBFbmdsaXNoLiBBbnkgdXNlci1mYWNpbmcgZXJyb3IgbWVzc2FnZQogICAqIHNob3VsZCBiZSBsb2NhbGl6ZWQgYW5kIHNlbnQgaW4gdGhlIGdvb2dsZS5ycGMuU3RhdHVzLmRldGFpbHMgZmllbGQsIG9yIGxvY2FsaXplZCBieSB0aGUKICAgKiBjbGllbnQuCiAgICogVGhlIHZhbHVlIG1heSBiZSB7QGNvZGUgbnVsbH0uCiAgICovCiAgQGNvbS5nb29nbGUuYXBpLmNsaWVudC51dGlsLktleQogIHByaXZhdGUgamF2YS5sYW5nLlN0cmluZyBtZXNzYWdlOwoKICAvKioKICAgKiBUaGUgc3RhdHVzIGNvZGUsIHdoaWNoIHNob3VsZCBiZSBhbiBlbnVtIHZhbHVlIG9mIGdvb2dsZS5ycGMuQ29kZS4KICAgKiBAcmV0dXJuIHZhbHVlIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBqYXZhLmxhbmcuSW50ZWdlciBnZXRDb2RlKCkgewogICAgcmV0dXJuIGNvZGU7CiAgfQoKICAvKioKICAgKiBUaGUgc3RhdHVzIGNvZGUsIHdoaWNoIHNob3VsZCBiZSBhbiBlbnVtIHZhbHVlIG9mIGdvb2dsZS5ycGMuQ29kZS4KICAgKiBAcGFyYW0gY29kZSBjb2RlIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBTdGF0dXMgc2V0Q29kZShqYXZhLmxhbmcuSW50ZWdlciBjb2RlKSB7CiAgICB0aGlzLmNvZGUgPSBjb2RlOwogICAgcmV0dXJuIHRoaXM7CiAgfQoKICAvKioKICAgKiBBIGxpc3Qgb2YgbWVzc2FnZXMgdGhhdCBjYXJyeSB0aGUgZXJyb3IgZGV0YWlscy4gIFRoZXJlIGlzIGEgY29tbW9uIHNldCBvZiBtZXNzYWdlIHR5cGVzIGZvcgogICAqIEFQSXMgdG8gdXNlLgogICAqIEByZXR1cm4gdmFsdWUgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEudXRpbC5NYXA8U3RyaW5nLCBqYXZhLmxhbmcuT2JqZWN0Pj4gZ2V0RGV0YWlscygpIHsKICAgIHJldHVybiBkZXRhaWxzOwogIH0KCiAgLyoqCiAgICogQSBsaXN0IG9mIG1lc3NhZ2VzIHRoYXQgY2FycnkgdGhlIGVycm9yIGRldGFpbHMuICBUaGVyZSBpcyBhIGNvbW1vbiBzZXQgb2YgbWVzc2FnZSB0eXBlcyBmb3IKICAgKiBBUElzIHRvIHVzZS4KICAgKiBAcGFyYW0gZGV0YWlscyBkZXRhaWxzIG9yIHtAY29kZSBudWxsfSBmb3Igbm9uZQogICAqLwogIHB1YmxpYyBTdGF0dXMgc2V0RGV0YWlscyhqYXZhLnV0aWwuTGlzdDxqYXZhLnV0aWwuTWFwPFN0cmluZywgamF2YS5sYW5nLk9iamVjdD4+IGRldGFpbHMpIHsKICAgIHRoaXMuZGV0YWlscyA9IGRldGFpbHM7CiAgICByZXR1cm4gdGhpczsKICB9CgogIC8qKgogICAqIEEgZGV2ZWxvcGVyLWZhY2luZyBlcnJvciBtZXNzYWdlLCB3aGljaCBzaG91bGQgYmUgaW4gRW5nbGlzaC4gQW55IHVzZXItZmFjaW5nIGVycm9yIG1lc3NhZ2UKICAgKiBzaG91bGQgYmUgbG9jYWxpemVkIGFuZCBzZW50IGluIHRoZSBnb29nbGUucnBjLlN0YXR1cy5kZXRhaWxzIGZpZWxkLCBvciBsb2NhbGl6ZWQgYnkgdGhlCiAgICogY2xpZW50LgogICAqIEByZXR1cm4gdmFsdWUgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIGphdmEubGFuZy5TdHJpbmcgZ2V0TWVzc2FnZSgpIHsKICAgIHJldHVybiBtZXNzYWdlOwogIH0KCiAgLyoqCiAgICogQSBkZXZlbG9wZXItZmFjaW5nIGVycm9yIG1lc3NhZ2UsIHdoaWNoIHNob3VsZCBiZSBpbiBFbmdsaXNoLiBBbnkgdXNlci1mYWNpbmcgZXJyb3IgbWVzc2FnZQogICAqIHNob3VsZCBiZSBsb2NhbGl6ZWQgYW5kIHNlbnQgaW4gdGhlIGdvb2dsZS5ycGMuU3RhdHVzLmRldGFpbHMgZmllbGQsIG9yIGxvY2FsaXplZCBieSB0aGUKICAgKiBjbGllbnQuCiAgICogQHBhcmFtIG1lc3NhZ2UgbWVzc2FnZSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgU3RhdHVzIHNldE1lc3NhZ2UoamF2YS5sYW5nLlN0cmluZyBtZXNzYWdlKSB7CiAgICB0aGlzLm1lc3NhZ2UgPSBtZXNzYWdlOwogICAgcmV0dXJuIHRoaXM7CiAgfQoKICBAT3ZlcnJpZGUKICBwdWJsaWMgU3RhdHVzIHNldChTdHJpbmcgZmllbGROYW1lLCBPYmplY3QgdmFsdWUpIHsKICAgIHJldHVybiAoU3RhdHVzKSBzdXBlci5zZXQoZmllbGROYW1lLCB2YWx1ZSk7CiAgfQoKICBAT3ZlcnJpZGUKICBwdWJsaWMgU3RhdHVzIGNsb25lKCkgewogICAgcmV0dXJuIChTdGF0dXMpIHN1cGVyLmNsb25lKCk7CiAgfQoKfQpQSwMEFAAAAAAAAAAhAI41TUqECwAAhAsAAFEAAABjb20vZ29vZ2xlL2FwaS9zZXJ2aWNlcy9jbG91ZHJlc291cmNlbWFuYWdlci9tb2RlbC9UZXN0SWFtUGVybWlzc2lvbnNSZXF1ZXN0LmphdmEvKgogKiBDb3B5cmlnaHQgMjAxMCBHb29nbGUgSW5jLgogKgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQKICogaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UKICogaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzCiAqIG9yIGltcGxpZWQuIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMgdW5kZXIKICogdGhlIExpY2Vuc2UuCiAqLwovKgogKiBUaGlzIGNvZGUgd2FzIGdlbmVyYXRlZCBieSBodHRwczovL2dpdGh1Yi5jb20vZ29vZ2xlL2FwaXMtY2xpZW50LWdlbmVyYXRvci8KICogKGJ1aWxkOiAyMDE4LTEwLTA4IDE3OjQ1OjM5IFVUQykKICogb24gMjAyMC0wMy0xOSBhdCAwMjozODozMCBVVEMgCiAqIE1vZGlmeSBhdCB5b3VyIG93biByaXNrLgogKi8KCnBhY2thZ2UgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuY2xvdWRyZXNvdXJjZW1hbmFnZXIubW9kZWw7CgovKioKICogUmVxdWVzdCBtZXNzYWdlIGZvciBgVGVzdElhbVBlcm1pc3Npb25zYCBtZXRob2QuCiAqCiAqIDxwPiBUaGlzIGlzIHRoZSBKYXZhIGRhdGEgbW9kZWwgY2xhc3MgdGhhdCBzcGVjaWZpZXMgaG93IHRvIHBhcnNlL3NlcmlhbGl6ZSBpbnRvIHRoZSBKU09OIHRoYXQgaXMKICogdHJhbnNtaXR0ZWQgb3ZlciBIVFRQIHdoZW4gd29ya2luZyB3aXRoIHRoZSBDbG91ZCBSZXNvdXJjZSBNYW5hZ2VyIEFQSS4gRm9yIGEgZGV0YWlsZWQKICogZXhwbGFuYXRpb24gc2VlOgogKiA8YSBocmVmPSJodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9hcGktY2xpZW50LWxpYnJhcnkvamF2YS9nb29nbGUtaHR0cC1qYXZhLWNsaWVudC9qc29uIj5odHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9hcGktY2xpZW50LWxpYnJhcnkvamF2YS9nb29nbGUtaHR0cC1qYXZhLWNsaWVudC9qc29uPC9hPgogKiA8L3A+CiAqCiAqIEBhdXRob3IgR29vZ2xlLCBJbmMuCiAqLwpAU3VwcHJlc3NXYXJuaW5ncygiamF2YWRvYyIpCnB1YmxpYyBmaW5hbCBjbGFzcyBUZXN0SWFtUGVybWlzc2lvbnNSZXF1ZXN0IGV4dGVuZHMgY29tLmdvb2dsZS5hcGkuY2xpZW50Lmpzb24uR2VuZXJpY0pzb24gewoKICAvKioKICAgKiBUaGUgc2V0IG9mIHBlcm1pc3Npb25zIHRvIGNoZWNrIGZvciB0aGUgYHJlc291cmNlYC4gUGVybWlzc2lvbnMgd2l0aCB3aWxkY2FyZHMgKHN1Y2ggYXMgJyonIG9yCiAgICogJ3N0b3JhZ2UuKicpIGFyZSBub3QgYWxsb3dlZC4gRm9yIG1vcmUgaW5mb3JtYXRpb24gc2VlIFtJQU0KICAgKiBPdmVydmlld10oaHR0cHM6Ly9jbG91ZC5nb29nbGUuY29tL2lhbS9kb2NzL292ZXJ2aWV3I3Blcm1pc3Npb25zKS4KICAgKiBUaGUgdmFsdWUgbWF5IGJlIHtAY29kZSBudWxsfS4KICAgKi8KICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuU3RyaW5nPiBwZXJtaXNzaW9uczsKCiAgLyoqCiAgICogVGhlIHNldCBvZiBwZXJtaXNzaW9ucyB0byBjaGVjayBmb3IgdGhlIGByZXNvdXJjZWAuIFBlcm1pc3Npb25zIHdpdGggd2lsZGNhcmRzIChzdWNoIGFzICcqJyBvcgogICAqICdzdG9yYWdlLionKSBhcmUgbm90IGFsbG93ZWQuIEZvciBtb3JlIGluZm9ybWF0aW9uIHNlZSBbSUFNCiAgICogT3ZlcnZpZXddKGh0dHBzOi8vY2xvdWQuZ29vZ2xlLmNvbS9pYW0vZG9jcy9vdmVydmlldyNwZXJtaXNzaW9ucykuCiAgICogQHJldHVybiB2YWx1ZSBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLlN0cmluZz4gZ2V0UGVybWlzc2lvbnMoKSB7CiAgICByZXR1cm4gcGVybWlzc2lvbnM7CiAgfQoKICAvKioKICAgKiBUaGUgc2V0IG9mIHBlcm1pc3Npb25zIHRvIGNoZWNrIGZvciB0aGUgYHJlc291cmNlYC4gUGVybWlzc2lvbnMgd2l0aCB3aWxkY2FyZHMgKHN1Y2ggYXMgJyonIG9yCiAgICogJ3N0b3JhZ2UuKicpIGFyZSBub3QgYWxsb3dlZC4gRm9yIG1vcmUgaW5mb3JtYXRpb24gc2VlIFtJQU0KICAgKiBPdmVydmlld10oaHR0cHM6Ly9jbG91ZC5nb29nbGUuY29tL2lhbS9kb2NzL292ZXJ2aWV3I3Blcm1pc3Npb25zKS4KICAgKiBAcGFyYW0gcGVybWlzc2lvbnMgcGVybWlzc2lvbnMgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIFRlc3RJYW1QZXJtaXNzaW9uc1JlcXVlc3Qgc2V0UGVybWlzc2lvbnMoamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLlN0cmluZz4gcGVybWlzc2lvbnMpIHsKICAgIHRoaXMucGVybWlzc2lvbnMgPSBwZXJtaXNzaW9uczsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgQE92ZXJyaWRlCiAgcHVibGljIFRlc3RJYW1QZXJtaXNzaW9uc1JlcXVlc3Qgc2V0KFN0cmluZyBmaWVsZE5hbWUsIE9iamVjdCB2YWx1ZSkgewogICAgcmV0dXJuIChUZXN0SWFtUGVybWlzc2lvbnNSZXF1ZXN0KSBzdXBlci5zZXQoZmllbGROYW1lLCB2YWx1ZSk7CiAgfQoKICBAT3ZlcnJpZGUKICBwdWJsaWMgVGVzdElhbVBlcm1pc3Npb25zUmVxdWVzdCBjbG9uZSgpIHsKICAgIHJldHVybiAoVGVzdElhbVBlcm1pc3Npb25zUmVxdWVzdCkgc3VwZXIuY2xvbmUoKTsKICB9Cgp9ClBLAwQUAAAAAAAAACEAuJckY7oJAAC6CQAAUgAAAGNvbS9nb29nbGUvYXBpL3NlcnZpY2VzL2Nsb3VkcmVzb3VyY2VtYW5hZ2VyL21vZGVsL1Rlc3RJYW1QZXJtaXNzaW9uc1Jlc3BvbnNlLmphdmEvKgogKiBDb3B5cmlnaHQgMjAxMCBHb29nbGUgSW5jLgogKgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQKICogaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UKICogaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzCiAqIG9yIGltcGxpZWQuIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMgdW5kZXIKICogdGhlIExpY2Vuc2UuCiAqLwovKgogKiBUaGlzIGNvZGUgd2FzIGdlbmVyYXRlZCBieSBodHRwczovL2dpdGh1Yi5jb20vZ29vZ2xlL2FwaXMtY2xpZW50LWdlbmVyYXRvci8KICogKGJ1aWxkOiAyMDE4LTEwLTA4IDE3OjQ1OjM5IFVUQykKICogb24gMjAyMC0wMy0xOSBhdCAwMjozODozMCBVVEMgCiAqIE1vZGlmeSBhdCB5b3VyIG93biByaXNrLgogKi8KCnBhY2thZ2UgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuY2xvdWRyZXNvdXJjZW1hbmFnZXIubW9kZWw7CgovKioKICogUmVzcG9uc2UgbWVzc2FnZSBmb3IgYFRlc3RJYW1QZXJtaXNzaW9uc2AgbWV0aG9kLgogKgogKiA8cD4gVGhpcyBpcyB0aGUgSmF2YSBkYXRhIG1vZGVsIGNsYXNzIHRoYXQgc3BlY2lmaWVzIGhvdyB0byBwYXJzZS9zZXJpYWxpemUgaW50byB0aGUgSlNPTiB0aGF0IGlzCiAqIHRyYW5zbWl0dGVkIG92ZXIgSFRUUCB3aGVuIHdvcmtpbmcgd2l0aCB0aGUgQ2xvdWQgUmVzb3VyY2UgTWFuYWdlciBBUEkuIEZvciBhIGRldGFpbGVkCiAqIGV4cGxhbmF0aW9uIHNlZToKICogPGEgaHJlZj0iaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vYXBpLWNsaWVudC1saWJyYXJ5L2phdmEvZ29vZ2xlLWh0dHAtamF2YS1jbGllbnQvanNvbiI+aHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vYXBpLWNsaWVudC1saWJyYXJ5L2phdmEvZ29vZ2xlLWh0dHAtamF2YS1jbGllbnQvanNvbjwvYT4KICogPC9wPgogKgogKiBAYXV0aG9yIEdvb2dsZSwgSW5jLgogKi8KQFN1cHByZXNzV2FybmluZ3MoImphdmFkb2MiKQpwdWJsaWMgZmluYWwgY2xhc3MgVGVzdElhbVBlcm1pc3Npb25zUmVzcG9uc2UgZXh0ZW5kcyBjb20uZ29vZ2xlLmFwaS5jbGllbnQuanNvbi5HZW5lcmljSnNvbiB7CgogIC8qKgogICAqIEEgc3Vic2V0IG9mIGBUZXN0UGVybWlzc2lvbnNSZXF1ZXN0LnBlcm1pc3Npb25zYCB0aGF0IHRoZSBjYWxsZXIgaXMgYWxsb3dlZC4KICAgKiBUaGUgdmFsdWUgbWF5IGJlIHtAY29kZSBudWxsfS4KICAgKi8KICBAY29tLmdvb2dsZS5hcGkuY2xpZW50LnV0aWwuS2V5CiAgcHJpdmF0ZSBqYXZhLnV0aWwuTGlzdDxqYXZhLmxhbmcuU3RyaW5nPiBwZXJtaXNzaW9uczsKCiAgLyoqCiAgICogQSBzdWJzZXQgb2YgYFRlc3RQZXJtaXNzaW9uc1JlcXVlc3QucGVybWlzc2lvbnNgIHRoYXQgdGhlIGNhbGxlciBpcyBhbGxvd2VkLgogICAqIEByZXR1cm4gdmFsdWUgb3Ige0Bjb2RlIG51bGx9IGZvciBub25lCiAgICovCiAgcHVibGljIGphdmEudXRpbC5MaXN0PGphdmEubGFuZy5TdHJpbmc+IGdldFBlcm1pc3Npb25zKCkgewogICAgcmV0dXJuIHBlcm1pc3Npb25zOwogIH0KCiAgLyoqCiAgICogQSBzdWJzZXQgb2YgYFRlc3RQZXJtaXNzaW9uc1JlcXVlc3QucGVybWlzc2lvbnNgIHRoYXQgdGhlIGNhbGxlciBpcyBhbGxvd2VkLgogICAqIEBwYXJhbSBwZXJtaXNzaW9ucyBwZXJtaXNzaW9ucyBvciB7QGNvZGUgbnVsbH0gZm9yIG5vbmUKICAgKi8KICBwdWJsaWMgVGVzdElhbVBlcm1pc3Npb25zUmVzcG9uc2Ugc2V0UGVybWlzc2lvbnMoamF2YS51dGlsLkxpc3Q8amF2YS5sYW5nLlN0cmluZz4gcGVybWlzc2lvbnMpIHsKICAgIHRoaXMucGVybWlzc2lvbnMgPSBwZXJtaXNzaW9uczsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgQE92ZXJyaWRlCiAgcHVibGljIFRlc3RJYW1QZXJtaXNzaW9uc1Jlc3BvbnNlIHNldChTdHJpbmcgZmllbGROYW1lLCBPYmplY3QgdmFsdWUpIHsKICAgIHJldHVybiAoVGVzdElhbVBlcm1pc3Npb25zUmVzcG9uc2UpIHN1cGVyLnNldChmaWVsZE5hbWUsIHZhbHVlKTsKICB9CgogIEBPdmVycmlkZQogIHB1YmxpYyBUZXN0SWFtUGVybWlzc2lvbnNSZXNwb25zZSBjbG9uZSgpIHsKICAgIHJldHVybiAoVGVzdElhbVBlcm1pc3Npb25zUmVzcG9uc2UpIHN1cGVyLmNsb25lKCk7CiAgfQoKfQpQSwMEFAAAAAAAAAAhAL5BIVyrBgAAqwYAAE4AAABjb20vZ29vZ2xlL2FwaS9zZXJ2aWNlcy9jbG91ZHJlc291cmNlbWFuYWdlci9tb2RlbC9VbmRlbGV0ZVByb2plY3RSZXF1ZXN0LmphdmEvKgogKiBDb3B5cmlnaHQgMjAxMCBHb29nbGUgSW5jLgogKgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQKICogaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UKICogaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzCiAqIG9yIGltcGxpZWQuIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMgdW5kZXIKICogdGhlIExpY2Vuc2UuCiAqLwovKgogKiBUaGlzIGNvZGUgd2FzIGdlbmVyYXRlZCBieSBodHRwczovL2dpdGh1Yi5jb20vZ29vZ2xlL2FwaXMtY2xpZW50LWdlbmVyYXRvci8KICogKGJ1aWxkOiAyMDE4LTEwLTA4IDE3OjQ1OjM5IFVUQykKICogb24gMjAyMC0wMy0xOSBhdCAwMjozODozMCBVVEMgCiAqIE1vZGlmeSBhdCB5b3VyIG93biByaXNrLgogKi8KCnBhY2thZ2UgY29tLmdvb2dsZS5hcGkuc2VydmljZXMuY2xvdWRyZXNvdXJjZW1hbmFnZXIubW9kZWw7CgovKioKICogVGhlIHJlcXVlc3Qgc2VudCB0byB0aGUgVW5kZWxldGVQcm9qZWN0IG1ldGhvZC4KICoKICogPHA+IFRoaXMgaXMgdGhlIEphdmEgZGF0YSBtb2RlbCBjbGFzcyB0aGF0IHNwZWNpZmllcyBob3cgdG8gcGFyc2Uvc2VyaWFsaXplIGludG8gdGhlIEpTT04gdGhhdCBpcwogKiB0cmFuc21pdHRlZCBvdmVyIEhUVFAgd2hlbiB3b3JraW5nIHdpdGggdGhlIENsb3VkIFJlc291cmNlIE1hbmFnZXIgQVBJLiBGb3IgYSBkZXRhaWxlZAogKiBleHBsYW5hdGlvbiBzZWU6CiAqIDxhIGhyZWY9Imh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL2FwaS1jbGllbnQtbGlicmFyeS9qYXZhL2dvb2dsZS1odHRwLWphdmEtY2xpZW50L2pzb24iPmh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL2FwaS1jbGllbnQtbGlicmFyeS9qYXZhL2dvb2dsZS1odHRwLWphdmEtY2xpZW50L2pzb248L2E+CiAqIDwvcD4KICoKICogQGF1dGhvciBHb29nbGUsIEluYy4KICovCkBTdXBwcmVzc1dhcm5pbmdzKCJqYXZhZG9jIikKcHVibGljIGZpbmFsIGNsYXNzIFVuZGVsZXRlUHJvamVjdFJlcXVlc3QgZXh0ZW5kcyBjb20uZ29vZ2xlLmFwaS5jbGllbnQuanNvbi5HZW5lcmljSnNvbiB7CgogIEBPdmVycmlkZQogIHB1YmxpYyBVbmRlbGV0ZVByb2plY3RSZXF1ZXN0IHNldChTdHJpbmcgZmllbGROYW1lLCBPYmplY3QgdmFsdWUpIHsKICAgIHJldHVybiAoVW5kZWxldGVQcm9qZWN0UmVxdWVzdCkgc3VwZXIuc2V0KGZpZWxkTmFtZSwgdmFsdWUpOwogIH0KCiAgQE92ZXJyaWRlCiAgcHVibGljIFVuZGVsZXRlUHJvamVjdFJlcXVlc3QgY2xvbmUoKSB7CiAgICByZXR1cm4gKFVuZGVsZXRlUHJvamVjdFJlcXVlc3QpIHN1cGVyLmNsb25lKCk7CiAgfQoKfQpQSwMEFAAAAAAAAAAhAHZkSreVDgAAlQ4AAFgAAABjb20vZ29vZ2xlL2FwaS9zZXJ2aWNlcy9jbG91ZHJlc291cmNlbWFuYWdlci9DbG91ZFJlc291cmNlTWFuYWdlclJlcXVlc3RJbml0aWFsaXplci5qYXZhLyoKICogQ29weXJpZ2h0IDIwMTAgR29vZ2xlIEluYy4KICoKICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0CiAqIGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4gWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKgogKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlCiAqIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcwogKiBvciBpbXBsaWVkLiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zIHVuZGVyCiAqIHRoZSBMaWNlbnNlLgogKi8KLyoKICogVGhpcyBjb2RlIHdhcyBnZW5lcmF0ZWQgYnkgaHR0cHM6Ly9naXRodWIuY29tL2dvb2dsZS9hcGlzLWNsaWVudC1nZW5lcmF0b3IvCiAqIChidWlsZDogMjAxOC0xMC0wOCAxNzo0NTozOSBVVEMpCiAqIG9uIDIwMjAtMDMtMTkgYXQgMDI6Mzg6MzAgVVRDIAogKiBNb2RpZnkgYXQgeW91ciBvd24gcmlzay4KICovCgpwYWNrYWdlIGNvbS5nb29nbGUuYXBpLnNlcnZpY2VzLmNsb3VkcmVzb3VyY2VtYW5hZ2VyOwoKLyoqCiAqIENsb3VkUmVzb3VyY2VNYW5hZ2VyIHJlcXVlc3QgaW5pdGlhbGl6ZXIgZm9yIHNldHRpbmcgcHJvcGVydGllcyBsaWtlIGtleSBhbmQgdXNlcklwLgogKgogKiA8cD4KICogVGhlIHNpbXBsZXN0IHVzYWdlIGlzIHRvIHVzZSBpdCB0byBzZXQgdGhlIGtleSBwYXJhbWV0ZXI6CiAqIDwvcD4KICoKICogPHByZT4KICBwdWJsaWMgc3RhdGljIGZpbmFsIEdvb2dsZUNsaWVudFJlcXVlc3RJbml0aWFsaXplciBLRVlfSU5JVElBTElaRVIgPQogICAgICBuZXcgQ2xvdWRSZXNvdXJjZU1hbmFnZXJSZXF1ZXN0SW5pdGlhbGl6ZXIoS0VZKTsKICogPC9wcmU+CiAqCiAqIDxwPgogKiBUaGVyZSBpcyBhbHNvIGEgY29uc3RydWN0b3IgdG8gc2V0IGJvdGggdGhlIGtleSBhbmQgdXNlcklwIHBhcmFtZXRlcnM6CiAqIDwvcD4KICoKICogPHByZT4KICBwdWJsaWMgc3RhdGljIGZpbmFsIEdvb2dsZUNsaWVudFJlcXVlc3RJbml0aWFsaXplciBJTklUSUFMSVpFUiA9CiAgICAgIG5ldyBDbG91ZFJlc291cmNlTWFuYWdlclJlcXVlc3RJbml0aWFsaXplcihLRVksIFVTRVJfSVApOwogKiA8L3ByZT4KICoKICogPHA+CiAqIElmIHlvdSB3YW50IHRvIGltcGxlbWVudCBjdXN0b20gbG9naWMsIGV4dGVuZCBpdCBsaWtlIHRoaXM6CiAqIDwvcD4KICoKICogPHByZT4KICBwdWJsaWMgc3RhdGljIGNsYXNzIE15UmVxdWVzdEluaXRpYWxpemVyIGV4dGVuZHMgQ2xvdWRSZXNvdXJjZU1hbmFnZXJSZXF1ZXN0SW5pdGlhbGl6ZXIgewoKICAgIHtAbGl0ZXJhbCBAfU92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCBpbml0aWFsaXplQ2xvdWRSZXNvdXJjZU1hbmFnZXJSZXF1ZXN0KENsb3VkUmVzb3VyY2VNYW5hZ2VyUmVxdWVzdHtAbGl0ZXJhbCA8fT97QGxpdGVyYWwgPn0gcmVxdWVzdCkKICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24gewogICAgICAvLyBjdXN0b20gbG9naWMKICAgIH0KICB9CiAqIDwvcHJlPgogKgogKiA8cD4KICogRmluYWxseSwgdG8gc2V0IHRoZSBrZXkgYW5kIHVzZXJJcCBwYXJhbWV0ZXJzIGFuZCBpbnNlcnQgY3VzdG9tIGxvZ2ljLCBleHRlbmQgaXQgbGlrZSB0aGlzOgogKiA8L3A+CiAqCiAqIDxwcmU+CiAgcHVibGljIHN0YXRpYyBjbGFzcyBNeVJlcXVlc3RJbml0aWFsaXplcjIgZXh0ZW5kcyBDbG91ZFJlc291cmNlTWFuYWdlclJlcXVlc3RJbml0aWFsaXplciB7CgogICAgcHVibGljIE15S2V5UmVxdWVzdEluaXRpYWxpemVyKCkgewogICAgICBzdXBlcihLRVksIFVTRVJfSVApOwogICAgfQoKICAgIHtAbGl0ZXJhbCBAfU92ZXJyaWRlCiAgICBwdWJsaWMgdm9pZCBpbml0aWFsaXplQ2xvdWRSZXNvdXJjZU1hbmFnZXJSZXF1ZXN0KENsb3VkUmVzb3VyY2VNYW5hZ2VyUmVxdWVzdHtAbGl0ZXJhbCA8fT97QGxpdGVyYWwgPn0gcmVxdWVzdCkKICAgICAgICB0aHJvd3MgSU9FeGNlcHRpb24gewogICAgICAvLyBjdXN0b20gbG9naWMKICAgIH0KICB9CiAqIDwvcHJlPgogKgogKiA8cD4KICogU3ViY2xhc3NlcyBzaG91bGQgYmUgdGhyZWFkLXNhZmUuCiAqIDwvcD4KICoKICogQHNpbmNlIDEuMTIKICovCnB1YmxpYyBjbGFzcyBDbG91ZFJlc291cmNlTWFuYWdlclJlcXVlc3RJbml0aWFsaXplciBleHRlbmRzIGNvbS5nb29nbGUuYXBpLmNsaWVudC5nb29nbGVhcGlzLnNlcnZpY2VzLmpzb24uQ29tbW9uR29vZ2xlSnNvbkNsaWVudFJlcXVlc3RJbml0aWFsaXplciB7CgogIHB1YmxpYyBDbG91ZFJlc291cmNlTWFuYWdlclJlcXVlc3RJbml0aWFsaXplcigpIHsKICAgIHN1cGVyKCk7CiAgfQoKICAvKioKICAgKiBAcGFyYW0ga2V5IEFQSSBrZXkgb3Ige0Bjb2RlIG51bGx9IHRvIGxlYXZlIGl0IHVuY2hhbmdlZAogICAqLwogIHB1YmxpYyBDbG91ZFJlc291cmNlTWFuYWdlclJlcXVlc3RJbml0aWFsaXplcihTdHJpbmcga2V5KSB7CiAgICBzdXBlcihrZXkpOwogIH0KCiAgLyoqCiAgICogQHBhcmFtIGtleSBBUEkga2V5IG9yIHtAY29kZSBudWxsfSB0byBsZWF2ZSBpdCB1bmNoYW5nZWQKICAgKiBAcGFyYW0gdXNlcklwIHVzZXIgSVAgb3Ige0Bjb2RlIG51bGx9IHRvIGxlYXZlIGl0IHVuY2hhbmdlZAogICAqLwogIHB1YmxpYyBDbG91ZFJlc291cmNlTWFuYWdlclJlcXVlc3RJbml0aWFsaXplcihTdHJpbmcga2V5LCBTdHJpbmcgdXNlcklwKSB7CiAgICBzdXBlcihrZXksIHVzZXJJcCk7CiAgfQoKICBAT3ZlcnJpZGUKICBwdWJsaWMgZmluYWwgdm9pZCBpbml0aWFsaXplSnNvblJlcXVlc3QoY29tLmdvb2dsZS5hcGkuY2xpZW50Lmdvb2dsZWFwaXMuc2VydmljZXMuanNvbi5BYnN0cmFjdEdvb2dsZUpzb25DbGllbnRSZXF1ZXN0PD8+IHJlcXVlc3QpIHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIHsKICAgIHN1cGVyLmluaXRpYWxpemVKc29uUmVxdWVzdChyZXF1ZXN0KTsKICAgIGluaXRpYWxpemVDbG91ZFJlc291cmNlTWFuYWdlclJlcXVlc3QoKENsb3VkUmVzb3VyY2VNYW5hZ2VyUmVxdWVzdDw/PikgcmVxdWVzdCk7CiAgfQoKICAvKioKICAgKiBJbml0aWFsaXplcyBDbG91ZFJlc291cmNlTWFuYWdlciByZXF1ZXN0LgogICAqCiAgICogPHA+CiAgICogRGVmYXVsdCBpbXBsZW1lbnRhdGlvbiBkb2VzIG5vdGhpbmcuIENhbGxlZCBmcm9tCiAgICoge0BsaW5rICNpbml0aWFsaXplSnNvblJlcXVlc3QoY29tLmdvb2dsZS5hcGkuY2xpZW50Lmdvb2dsZWFwaXMuc2VydmljZXMuanNvbi5BYnN0cmFjdEdvb2dsZUpzb25DbGllbnRSZXF1ZXN0KX0uCiAgICogPC9wPgogICAqCiAgICogQHRocm93cyBqYXZhLmlvLklPRXhjZXB0aW9uIEkvTyBleGNlcHRpb24KICAgKi8KICBwcm90ZWN0ZWQgdm9pZCBpbml0aWFsaXplQ2xvdWRSZXNvdXJjZU1hbmFnZXJSZXF1ZXN0KENsb3VkUmVzb3VyY2VNYW5hZ2VyUmVxdWVzdDw/PiByZXF1ZXN0KSB0aHJvd3MgamF2YS5pby5JT0V4Y2VwdGlvbiB7CiAgfQp9ClBLAwQUAAAAAAAAACEAoYGga20KAABtCgAABwAAAHBvbS54bWw8cHJvamVjdCB4bWxucz0iaHR0cDovL21hdmVuLmFwYWNoZS5vcmcvUE9NLzQuMC4wIiB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiB4c2k6c2NoZW1hTG9jYXRpb249Imh0dHA6Ly9tYXZlbi5hcGFjaGUub3JnL1BPTS80LjAuMCBodHRwOi8vbWF2ZW4uYXBhY2hlLm9yZy9tYXZlbi12NF8wXzAueHNkIj4KICA8bW9kZWxWZXJzaW9uPjQuMC4wPC9tb2RlbFZlcnNpb24+CiAgPHBhcmVudD4KICAgIDxncm91cElkPm9yZy5zb25hdHlwZS5vc3M8L2dyb3VwSWQ+CiAgICA8YXJ0aWZhY3RJZD5vc3MtcGFyZW50PC9hcnRpZmFjdElkPgogICAgPHZlcnNpb24+NzwvdmVyc2lvbj4KICA8L3BhcmVudD4KCiAgPGdyb3VwSWQ+Y29tLmdvb2dsZS5hcGlzPC9ncm91cElkPgogIDxhcnRpZmFjdElkPmdvb2dsZS1hcGktc2VydmljZXMtY2xvdWRyZXNvdXJjZW1hbmFnZXI8L2FydGlmYWN0SWQ+CiAgPHZlcnNpb24+djEtcmV2NTcyLTEuMjUuMDwvdmVyc2lvbj4KICA8bmFtZT5DbG91ZCBSZXNvdXJjZSBNYW5hZ2VyIEFQSSB2MS1yZXY1NzItMS4yNS4wPC9uYW1lPgogIDxwYWNrYWdpbmc+amFyPC9wYWNrYWdpbmc+CgogIDxpbmNlcHRpb25ZZWFyPjIwMTE8L2luY2VwdGlvblllYXI+CgogIDxvcmdhbml6YXRpb24+CiAgICA8bmFtZT5Hb29nbGU8L25hbWU+CiAgICA8dXJsPmh0dHA6Ly93d3cuZ29vZ2xlLmNvbS88L3VybD4KICA8L29yZ2FuaXphdGlvbj4KCiAgPGxpY2Vuc2VzPgogICAgPGxpY2Vuc2U+CiAgICAgIDxuYW1lPlRoZSBBcGFjaGUgU29mdHdhcmUgTGljZW5zZSwgVmVyc2lvbiAyLjA8L25hbWU+CiAgICAgIDx1cmw+aHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wLnR4dDwvdXJsPgogICAgICA8ZGlzdHJpYnV0aW9uPnJlcG88L2Rpc3RyaWJ1dGlvbj4KICAgIDwvbGljZW5zZT4KICA8L2xpY2Vuc2VzPgoKICA8YnVpbGQ+CiAgICA8cGx1Z2lucz4KICAgICAgPHBsdWdpbj4KICAgICAgICA8YXJ0aWZhY3RJZD5tYXZlbi1jb21waWxlci1wbHVnaW48L2FydGlmYWN0SWQ+CiAgICAgICAgPHZlcnNpb24+Mi4zLjI8L3ZlcnNpb24+CiAgICAgICAgPGNvbmZpZ3VyYXRpb24+CiAgICAgICAgICA8c291cmNlPjEuNTwvc291cmNlPgogICAgICAgICAgPHRhcmdldD4xLjU8L3RhcmdldD4KICAgICAgICA8L2NvbmZpZ3VyYXRpb24+CiAgICAgIDwvcGx1Z2luPgogICAgICA8cGx1Z2luPgogICAgICAgIDxhcnRpZmFjdElkPm1hdmVuLWphci1wbHVnaW48L2FydGlmYWN0SWQ+CiAgICAgICAgPHZlcnNpb24+Mi4zLjE8L3ZlcnNpb24+CiAgICAgICAgPGNvbmZpZ3VyYXRpb24+CiAgICAgICAgICA8YXJjaGl2ZT4KICAgICAgICAgICAgPG1hbmlmZXN0RW50cmllcz4KICAgICAgICAgICAgICA8QnVpbHQtQnk+R29vZ2xlPC9CdWlsdC1CeT4KICAgICAgICAgICAgICA8QnVpbGQtSmRrPjEuNi54PC9CdWlsZC1KZGs+CiAgICAgICAgICAgIDwvbWFuaWZlc3RFbnRyaWVzPgogICAgICAgICAgPC9hcmNoaXZlPgogICAgICAgIDwvY29uZmlndXJhdGlvbj4KICAgICAgPC9wbHVnaW4+CiAgICAgIDxwbHVnaW4+CiAgICAgICAgPGFydGlmYWN0SWQ+bWF2ZW4tamF2YWRvYy1wbHVnaW48L2FydGlmYWN0SWQ+CiAgICAgICAgPHZlcnNpb24+Mi43PC92ZXJzaW9uPgogICAgICAgIDxjb25maWd1cmF0aW9uPgogICAgICAgICAgPGRvY3RpdGxlPkNsb3VkIFJlc291cmNlIE1hbmFnZXIgQVBJICR7cHJvamVjdC52ZXJzaW9ufTwvZG9jdGl0bGU+CiAgICAgICAgICA8d2luZG93dGl0bGU+Q2xvdWQgUmVzb3VyY2UgTWFuYWdlciBBUEkgJHtwcm9qZWN0LnZlcnNpb259PC93aW5kb3d0aXRsZT4KICAgICAgICAgIDxsaW5rcz4KICAgICAgICAgICAgPGxpbms+aHR0cDovL2RvY3Mub3JhY2xlLmNvbS9qYXZhc2UvNy9kb2NzL2FwaTwvbGluaz4KICAgICAgICAgIAogICAgICAgICAgICA8bGluaz5odHRwOi8vamF2YWRvYy5nb29nbGUtaHR0cC1qYXZhLWNsaWVudC5nb29nbGVjb2RlLmNvbS9oZy8xLjI1LjA8L2xpbms+CiAgICAgICAgICAKICAgICAgICAgICAgPGxpbms+aHR0cDovL2phdmFkb2MuZ29vZ2xlLW9hdXRoLWphdmEtY2xpZW50Lmdvb2dsZWNvZGUuY29tL2hnLzEuMjUuMDwvbGluaz4KICAgICAgICAgIAogICAgICAgICAgICA8bGluaz5odHRwOi8vamF2YWRvYy5nb29nbGUtYXBpLWphdmEtY2xpZW50Lmdvb2dsZWNvZGUuY29tL2hnLzEuMjUuMDwvbGluaz4KICAgICAgICAgIDwvbGlua3M+CiAgICAgICAgPC9jb25maWd1cmF0aW9uPgogICAgICA8L3BsdWdpbj4KICAgIDwvcGx1Z2lucz4KICAgIDxzb3VyY2VEaXJlY3Rvcnk+Ljwvc291cmNlRGlyZWN0b3J5PgogIDwvYnVpbGQ+CgogIDxkZXBlbmRlbmNpZXM+CiAgICA8ZGVwZW5kZW5jeT4KICAgICAgPGdyb3VwSWQ+Y29tLmdvb2dsZS5hcGktY2xpZW50PC9ncm91cElkPgogICAgICA8YXJ0aWZhY3RJZD5nb29nbGUtYXBpLWNsaWVudDwvYXJ0aWZhY3RJZD4KICAgICAgPHZlcnNpb24+MS4yNS4wPC92ZXJzaW9uPgogICAgPC9kZXBlbmRlbmN5PgogIDwvZGVwZW5kZW5jaWVzPgoKICA8cHJvcGVydGllcz4KICAgIDxwcm9qZWN0LmJ1aWxkLnNvdXJjZUVuY29kaW5nPlVURi04PC9wcm9qZWN0LmJ1aWxkLnNvdXJjZUVuY29kaW5nPgogIDwvcHJvcGVydGllcz4KPC9wcm9qZWN0PlBLAQIUAxQAAAAAAAAAIQAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAEADtQQAAAABjb20vUEsBAhQDFAAAAAAAAAAhAAAAAAAAAAAAAAAAAAsAAAAAAAAAAAAQAO1BIgAAAGNvbS9nb29nbGUvUEsBAhQDFAAAAAAAAAAhAAAAAAAAAAAAAAAAAA8AAAAAAAAAAAAQAO1BSwAAAGNvbS9nb29nbGUvYXBpL1BLAQIUAxQAAAAAAAAAIQAAAAAAAAAAAAAAAAAYAAAAAAAAAAAAEADtQXgAAABjb20vZ29vZ2xlL2FwaS9zZXJ2aWNlcy9QSwECFAMUAAAAAAAAACEAAAAAAAAAAAAAAAAALQAAAAAAAAAAABAA7UGuAAAAY29tL2dvb2dsZS9hcGkvc2VydmljZXMvY2xvdWRyZXNvdXJjZW1hbmFnZXIvUEsBAhQDFAAAAAAAAAAhAI91oT25BgAAuQYAAEwAAAAAAAAAAAAAAKQB+QAAAGNvbS9nb29nbGUvYXBpL3NlcnZpY2VzL2Nsb3VkcmVzb3VyY2VtYW5hZ2VyL0Nsb3VkUmVzb3VyY2VNYW5hZ2VyU2NvcGVzLmphdmFQSwECFAMUAAAAAAAAACEAramyhKofAACqHwAATQAAAAAAAAAAAAAApAEcCAAAY29tL2dvb2dsZS9hcGkvc2VydmljZXMvY2xvdWRyZXNvdXJjZW1hbmFnZXIvQ2xvdWRSZXNvdXJjZU1hbmFnZXJSZXF1ZXN0LmphdmFQSwECFAMUAAAAAAAAACEAMBZaQ5yaAwCcmgMARgAAAAAAAAAAAAAApAExKAAAY29tL2dvb2dsZS9hcGkvc2VydmljZXMvY2xvdWRyZXNvdXJjZW1hbmFnZXIvQ2xvdWRSZXNvdXJjZU1hbmFnZXIuamF2YVBLAQIUAxQAAAAAAAAAIQAAAAAAAAAAAAAAAAAzAAAAAAAAAAAAEADtQTHDAwBjb20vZ29vZ2xlL2FwaS9zZXJ2aWNlcy9jbG91ZHJlc291cmNlbWFuYWdlci9tb2RlbC9QSwECFAMUAAAAAAAAACEAHlelN30IAAB9CAAAQAAAAAAAAAAAAAAApAGCwwMAY29tL2dvb2dsZS9hcGkvc2VydmljZXMvY2xvdWRyZXNvdXJjZW1hbmFnZXIvbW9kZWwvQW5jZXN0b3IuamF2YVBLAQIUAxQAAAAAAAAAIQA4IRBW2RMAANkTAABDAAAAAAAAAAAAAACkAV3MAwBjb20vZ29vZ2xlL2FwaS9zZXJ2aWNlcy9jbG91ZHJlc291cmNlbWFuYWdlci9tb2RlbC9BdWRpdENvbmZpZy5qYXZhUEsBAhQDFAAAAAAAAAAhADTuXnvMDQAAzA0AAEYAAAAAAAAAAAAAAKQBl+ADAGNvbS9nb29nbGUvYXBpL3NlcnZpY2VzL2Nsb3VkcmVzb3VyY2VtYW5hZ2VyL21vZGVsL0F1ZGl0TG9nQ29uZmlnLmphdmFQSwECFAMUAAAAAAAAACEARkRcpjIoAAAyKAAAPwAAAAAAAAAAAAAApAHH7gMAY29tL2dvb2dsZS9hcGkvc2VydmljZXMvY2xvdWRyZXNvdXJjZW1hbmFnZXIvbW9kZWwvQmluZGluZy5qYXZhUEsBAhQDFAAAAAAAAAAhAGR2ZBZDBwAAQwcAAEkAAAAAAAAAAAAAAKQBVhcEAGNvbS9nb29nbGUvYXBpL3NlcnZpY2VzL2Nsb3VkcmVzb3VyY2VtYW5hZ2VyL21vZGVsL0Jvb2xlYW5Db25zdHJhaW50LmphdmFQSwECFAMUAAAAAAAAACEAWpyLquUeAADlHgAARQAAAAAAAAAAAAAApAEAHwQAY29tL2dvb2dsZS9hcGkvc2VydmljZXMvY2xvdWRyZXNvdXJjZW1hbmFnZXIvbW9kZWwvQm9vbGVhblBvbGljeS5qYXZhUEsBAhQDFAAAAAAAAAAhAAhjIuhFDwAARQ8AAE0AAAAAAAAAAAAAAKQBSD4EAGNvbS9nb29nbGUvYXBpL3NlcnZpY2VzL2Nsb3VkcmVzb3VyY2VtYW5hZ2VyL21vZGVsL0NsZWFyT3JnUG9saWN5UmVxdWVzdC5qYXZhUEsBAhQDFAAAAAAAAAAhAN4UuyxeHAAAXhwAAEIAAAAAAAAAAAAAAKQB+E0EAGNvbS9nb29nbGUvYXBpL3NlcnZpY2VzL2Nsb3VkcmVzb3VyY2VtYW5hZ2VyL21vZGVsL0NvbnN0cmFpbnQuamF2YVBLAQIUAxQAAAAAAAAAIQCQtTBzngcAAJ4HAAA9AAAAAAAAAAAAAACkAbZqBABjb20vZ29vZ2xlL2FwaS9zZXJ2aWNlcy9jbG91ZHJlc291cmNlbWFuYWdlci9tb2RlbC9FbXB0eS5qYXZhUEsBAhQDFAAAAAAAAAAhADucKol4FwAAeBcAADwAAAAAAAAAAAAAAKQBr3IEAGNvbS9nb29nbGUvYXBpL3NlcnZpY2VzL2Nsb3VkcmVzb3VyY2VtYW5hZ2VyL21vZGVsL0V4cHIuamF2YVBLAQIUAxQAAAAAAAAAIQBHR2xpYBEAAGARAABHAAAAAAAAAAAAAACkAYGKBABjb20vZ29vZ2xlL2FwaS9zZXJ2aWNlcy9jbG91ZHJlc291cmNlbWFuYWdlci9tb2RlbC9Gb2xkZXJPcGVyYXRpb24uamF2YVBLAQIUAxQAAAAAAAAAIQCNq1fmEwkAABMJAABMAAAAAAAAAAAAAACkAUacBABjb20vZ29vZ2xlL2FwaS9zZXJ2aWNlcy9jbG91ZHJlc291cmNlbWFuYWdlci9tb2RlbC9Gb2xkZXJPcGVyYXRpb25FcnJvci5qYXZhUEsBAhQDFAAAAAAAAAAhAAqsljSTBgAAkwYAAEoAAAAAAAAAAAAAAKQBw6UEAGNvbS9nb29nbGUvYXBpL3NlcnZpY2VzL2Nsb3VkcmVzb3VyY2VtYW5hZ2VyL21vZGVsL0dldEFuY2VzdHJ5UmVxdWVzdC5qYXZhUEsBAhQDFAAAAAAAAAAhAJMXyRQwCwAAMAsAAEsAAAAAAAAAAAAAAKQBvqwEAGNvbS9nb29nbGUvYXBpL3NlcnZpY2VzL2Nsb3VkcmVzb3VyY2VtYW5hZ2VyL21vZGVsL0dldEFuY2VzdHJ5UmVzcG9uc2UuamF2YVBLAQIUAxQAAAAAAAAAIQBKEL2pagkAAGoJAABUAAAAAAAAAAAAAACkAVe4BABjb20vZ29vZ2xlL2FwaS9zZXJ2aWNlcy9jbG91ZHJlc291cmNlbWFuYWdlci9tb2RlbC9HZXRFZmZlY3RpdmVPcmdQb2xpY3lSZXF1ZXN0LmphdmFQSwECFAMUAAAAAAAAACEAenAdc78JAAC/CQAASwAAAAAAAAAAAAAApAEzwgQAY29tL2dvb2dsZS9hcGkvc2VydmljZXMvY2xvdWRyZXNvdXJjZW1hbmFnZXIvbW9kZWwvR2V0SWFtUG9saWN5UmVxdWVzdC5qYXZhUEsBAhQDFAAAAAAAAAAhAJnP0Kf1CAAA9QgAAEsAAAAAAAAAAAAAAKQBW8wEAGNvbS9nb29nbGUvYXBpL3NlcnZpY2VzL2Nsb3VkcmVzb3VyY2VtYW5hZ2VyL21vZGVsL0dldE9yZ1BvbGljeVJlcXVlc3QuamF2YVBLAQIUAxQAAAAAAAAAIQCofwIttQwAALUMAABIAAAAAAAAAAAAAACkAbnVBABjb20vZ29vZ2xlL2FwaS9zZXJ2aWNlcy9jbG91ZHJlc291cmNlbWFuYWdlci9tb2RlbC9HZXRQb2xpY3lPcHRpb25zLmphdmFQSwECFAMUAAAAAAAAACEAHdJRol0cAABdHAAAPAAAAAAAAAAAAAAApAHU4gQAY29tL2dvb2dsZS9hcGkvc2VydmljZXMvY2xvdWRyZXNvdXJjZW1hbmFnZXIvbW9kZWwvTGllbi5qYXZhUEsBAhQDFAAAAAAAAAAhADwEZLW3DgAAtw4AAGAAAAAAAAAAAAAAAKQBi/8EAGNvbS9nb29nbGUvYXBpL3NlcnZpY2VzL2Nsb3VkcmVzb3VyY2VtYW5hZ2VyL21vZGVsL0xpc3RBdmFpbGFibGVPcmdQb2xpY3lDb25zdHJhaW50c1JlcXVlc3QuamF2YVBLAQIUAxQAAAAAAAAAIQBFoKnsiw4AAIsOAABhAAAAAAAAAAAAAACkAcAOBQBjb20vZ29vZ2xlL2FwaS9zZXJ2aWNlcy9jbG91ZHJlc291cmNlbWFuYWdlci9tb2RlbC9MaXN0QXZhaWxhYmxlT3JnUG9saWN5Q29uc3RyYWludHNSZXNwb25zZS5qYXZhUEsBAhQDFAAAAAAAAAAhACF9M4koDwAAKA8AAEYAAAAAAAAAAAAAAKQByh0FAGNvbS9nb29nbGUvYXBpL3NlcnZpY2VzL2Nsb3VkcmVzb3VyY2VtYW5hZ2VyL21vZGVsL0xpc3RDb25zdHJhaW50LmphdmFQSwECFAMUAAAAAAAAACEACLfSjXYLAAB2CwAASQAAAAAAAAAAAAAApAFWLQUAY29tL2dvb2dsZS9hcGkvc2VydmljZXMvY2xvdWRyZXNvdXJjZW1hbmFnZXIvbW9kZWwvTGlzdExpZW5zUmVzcG9uc2UuamF2YVBLAQIUAxQAAAAAAAAAIQBbwxPc5Q0AAOUNAABOAAAAAAAAAAAAAACkATM5BQBjb20vZ29vZ2xlL2FwaS9zZXJ2aWNlcy9jbG91ZHJlc291cmNlbWFuYWdlci9tb2RlbC9MaXN0T3JnUG9saWNpZXNSZXF1ZXN0LmphdmFQSwECFAMUAAAAAAAAACEAZXRFwG4NAABuDQAATwAAAAAAAAAAAAAApAGERwUAY29tL2dvb2dsZS9hcGkvc2VydmljZXMvY2xvdWRyZXNvdXJjZW1hbmFnZXIvbW9kZWwvTGlzdE9yZ1BvbGljaWVzUmVzcG9uc2UuamF2YVBLAQIUAxQAAAAAAAAAIQDxZuhgz1AAAM9QAABCAAAAAAAAAAAAAACkAV9VBQBjb20vZ29vZ2xlL2FwaS9zZXJ2aWNlcy9jbG91ZHJlc291cmNlbWFuYWdlci9tb2RlbC9MaXN0UG9saWN5LmphdmFQSwECFAMUAAAAAAAAACEAn4HNjZ4RAACeEQAATAAAAAAAAAAAAAAApAGOpgUAY29tL2dvb2dsZS9hcGkvc2VydmljZXMvY2xvdWRyZXNvdXJjZW1hbmFnZXIvbW9kZWwvTGlzdFByb2plY3RzUmVzcG9uc2UuamF2YVBLAQIUAxQAAAAAAAAAIQC9zlW/CR4AAAkeAABBAAAAAAAAAAAAAACkAZa4BQBjb20vZ29vZ2xlL2FwaS9zZXJ2aWNlcy9jbG91ZHJlc291cmNlbWFuYWdlci9tb2RlbC9PcGVyYXRpb24uamF2YVBLAQIUAxQAAAAAAAAAIQC0sU5BpyoAAKcqAABBAAAAAAAAAAAAAACkAf7WBQBjb20vZ29vZ2xlL2FwaS9zZXJ2aWNlcy9jbG91ZHJlc291cmNlbWFuYWdlci9tb2RlbC9PcmdQb2xpY3kuamF2YVBLAQIUAxQAAAAAAAAAIQC73p6wEBgAABAYAABEAAAAAAAAAAAAAACkAQQCBgBjb20vZ29vZ2xlL2FwaS9zZXJ2aWNlcy9jbG91ZHJlc291cmNlbWFuYWdlci9tb2RlbC9Pcmdhbml6YXRpb24uamF2YVBLAQIUAxQAAAAAAAAAIQApuzfRCwoAAAsKAABJAAAAAAAAAAAAAACkAXYaBgBjb20vZ29vZ2xlL2FwaS9zZXJ2aWNlcy9jbG91ZHJlc291cmNlbWFuYWdlci9tb2RlbC9Pcmdhbml6YXRpb25Pd25lci5qYXZhUEsBAhQDFAAAAAAAAAAhAJpGkMGHNwAAhzcAAD4AAAAAAAAAAAAAAKQB6CQGAGNvbS9nb29nbGUvYXBpL3NlcnZpY2VzL2Nsb3VkcmVzb3VyY2VtYW5hZ2VyL21vZGVsL1BvbGljeS5qYXZhUEsBAhQDFAAAAAAAAAAhAGUOSebdJgAA3SYAAD8AAAAAAAAAAAAAAKQBy1wGAGNvbS9nb29nbGUvYXBpL3NlcnZpY2VzL2Nsb3VkcmVzb3VyY2VtYW5hZ2VyL21vZGVsL1Byb2plY3QuamF2YVBLAQIUAxQAAAAAAAAAIQA+r4zjWA8AAFgPAABNAAAAAAAAAAAAAACkAQWEBgBjb20vZ29vZ2xlL2FwaS9zZXJ2aWNlcy9jbG91ZHJlc291cmNlbWFuYWdlci9tb2RlbC9Qcm9qZWN0Q3JlYXRpb25TdGF0dXMuamF2YVBLAQIUAxQAAAAAAAAAIQAvjQLEdg0AAHYNAABCAAAAAAAAAAAAAACkAciTBgBjb20vZ29vZ2xlL2FwaS9zZXJ2aWNlcy9jbG91ZHJlc291cmNlbWFuYWdlci9tb2RlbC9SZXNvdXJjZUlkLmphdmFQSwECFAMUAAAAAAAAACEA3rhVdw8JAAAPCQAARgAAAAAAAAAAAAAApAGeoQYAY29tL2dvb2dsZS9hcGkvc2VydmljZXMvY2xvdWRyZXNvdXJjZW1hbmFnZXIvbW9kZWwvUmVzdG9yZURlZmF1bHQuamF2YVBLAQIUAxQAAAAAAAAAIQBeYgmIdBUAAHQVAABSAAAAAAAAAAAAAACkARGrBgBjb20vZ29vZ2xlL2FwaS9zZXJ2aWNlcy9jbG91ZHJlc291cmNlbWFuYWdlci9tb2RlbC9TZWFyY2hPcmdhbml6YXRpb25zUmVxdWVzdC5qYXZhUEsBAhQDFAAAAAAAAAAhAOwusyDLDwAAyw8AAFMAAAAAAAAAAAAAAKQB9cAGAGNvbS9nb29nbGUvYXBpL3NlcnZpY2VzL2Nsb3VkcmVzb3VyY2VtYW5hZ2VyL21vZGVsL1NlYXJjaE9yZ2FuaXphdGlvbnNSZXNwb25zZS5qYXZhUEsBAhQDFAAAAAAAAAAhAKPGFraHDwAAhw8AAEsAAAAAAAAAAAAAAKQBMdEGAGNvbS9nb29nbGUvYXBpL3NlcnZpY2VzL2Nsb3VkcmVzb3VyY2VtYW5hZ2VyL21vZGVsL1NldElhbVBvbGljeVJlcXVlc3QuamF2YVBLAQIUAxQAAAAAAAAAIQDk2/JOnAgAAJwIAABLAAAAAAAAAAAAAACkASHhBgBjb20vZ29vZ2xlL2FwaS9zZXJ2aWNlcy9jbG91ZHJlc291cmNlbWFuYWdlci9tb2RlbC9TZXRPcmdQb2xpY3lSZXF1ZXN0LmphdmFQSwECFAMUAAAAAAAAACEAmZU/Ta0RAACtEQAAPgAAAAAAAAAAAAAApAEm6gYAY29tL2dvb2dsZS9hcGkvc2VydmljZXMvY2xvdWRyZXNvdXJjZW1hbmFnZXIvbW9kZWwvU3RhdHVzLmphdmFQSwECFAMUAAAAAAAAACEAjjVNSoQLAACECwAAUQAAAAAAAAAAAAAApAEv/AYAY29tL2dvb2dsZS9hcGkvc2VydmljZXMvY2xvdWRyZXNvdXJjZW1hbmFnZXIvbW9kZWwvVGVzdElhbVBlcm1pc3Npb25zUmVxdWVzdC5qYXZhUEsBAhQDFAAAAAAAAAAhALiXJGO6CQAAugkAAFIAAAAAAAAAAAAAAKQBIggHAGNvbS9nb29nbGUvYXBpL3NlcnZpY2VzL2Nsb3VkcmVzb3VyY2VtYW5hZ2VyL21vZGVsL1Rlc3RJYW1QZXJtaXNzaW9uc1Jlc3BvbnNlLmphdmFQSwECFAMUAAAAAAAAACEAvkEhXKsGAACrBgAATgAAAAAAAAAAAAAApAFMEgcAY29tL2dvb2dsZS9hcGkvc2VydmljZXMvY2xvdWRyZXNvdXJjZW1hbmFnZXIvbW9kZWwvVW5kZWxldGVQcm9qZWN0UmVxdWVzdC5qYXZhUEsBAhQDFAAAAAAAAAAhAHZkSreVDgAAlQ4AAFgAAAAAAAAAAAAAAKQBYxkHAGNvbS9nb29nbGUvYXBpL3NlcnZpY2VzL2Nsb3VkcmVzb3VyY2VtYW5hZ2VyL0Nsb3VkUmVzb3VyY2VNYW5hZ2VyUmVxdWVzdEluaXRpYWxpemVyLmphdmFQSwECFAMUAAAAAAAAACEAoYGga20KAABtCgAABwAAAAAAAAAAAAAApAFuKAcAcG9tLnhtbFBLBQYAAAAANwA3ADAYAAAAMwcAAAA=