ZGlmZiAtLWdpdCBhL2RvY3MvQUFGLUFQSS1Eb2N1bWVudGF0aW9uL0Nvbm5lY3RpbmctdG8tQUFGLnJzdCBiL2RvY3MvQUFGLUFQSS1Eb2N1bWVudGF0aW9uL0Nvbm5lY3RpbmctdG8tQUFGLnJzdApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yYzEzZjNlCi0tLSAvZGV2L251bGwKKysrIGIvZG9jcy9BQUYtQVBJLURvY3VtZW50YXRpb24vQ29ubmVjdGluZy10by1BQUYucnN0CkBAIC0wLDAgKzEsMzUzIEBACis9PT09PT09PT09PT09PT09PQ0KK0Nvbm5lY3RpbmcgdG8gQUFGDQorPT09PT09PT09PT09PT09PT0NCisNCitNZXRob2RzIHRvIENvbm5lY3QNCis9PT09PT09PT09PT09PT09PT0NCisNCiuVCUlmIHlvdSBhcmUgYSBTZXJ2bGV0IGluIGEgQ29udGFpbmVyLCB1c2UgQ0FESSBGcmFtZXdvcmsgd2l0aCBBQUYgUGx1Z2luLiAgSXQncyB2ZXJ5IGVhc3ksIGFuZCBpbmNsdWRlcyBCYXNpY0F1dGggZm9yIFNlcnZpY2VzLiAgDQorlQlKYXZhIFRlY2hub2xvZ2llcw0KK5UJVGVjaG5vbG9naWVzIHVzaW5nIFNlcnZsZXQgRmlsdGVycw0KK5UJRE1FMiAoYW5kIG90aGVyIFNlcnZsZXQgQ29udGFpbmVycykgY2FuIHVzZSBTZXJ2bGV0IEZpbHRlcnMNCiuVCUFueSBXZWJBcHAgY2FuIHBsdWcgaW4gQ0FESSBhcyBhIFNlcnZsZXQgRmlsdGVyDQorlQlKZXR0eSBjYW4gYXR0YWNoIGEgU2VydmxldCBGaWx0ZXIgd2l0aCBDb2RlLCBvciBhcyBXZWJBcHANCiuVCVRvbWNhdCA3IGhhcyBhICJWYWx2ZSIgcGx1Z2luLCB3aGljaCBpcyBzaW1pbGFyIGFuZCBzdXBwb3J0ZWQNCiuVCVVzZSB0aGUgQUFGTHVyIENvZGUgZGlyZWN0bHkgKHNob3duKQ0KK5UJQWxsIEphdmEgVGVjaG5vbG9naWVzIHV0aWxpemUgQ29uZmlndXJhdGlvbiB0byBzZXQgd2hhdCBTZWN1cml0eSBlbGVtZW50cyBhcmUgcmVxdWlyZWQNCiuVCWV4YW1wbGU6IEdsb2JhbCBMb2dpbiBjYW4gYmUgdHVybmVkIG9uL29mZiwgQUFGIENsaWVudCBuZWVkcyBpbmZvcm1hdGlvbiB0byBjb25uZWN0IHRvIEFBRiBTZXJ2aWNlDQorlQlUaGVyZSBhcmUgc2V2ZXJhbCBzcGVjaWFsdHkgY2FzZXMsIHdoaWNoIEFBRiBjYW4gd29yayB3aXRoLCBpbmNsdWRpbmcgZW1iZWRkaW5nIGFsbCBwcm9wZXJ0aWVzIGluIGEgV2ViLnhtbCwgYnV0IHRoZSBlc3NlbnRpYWxzIG5lZWRlZCBhcmU6DQorlQlDQURJIEphcnMNCiuVCWNhZGkucHJvcGVydGllcyBmaWxlIChjb25maWd1cmVkIHRoZSBzYW1lIGZvciBhbGwgdGVjaG5vbG9naWVzKQ0KK5UJRW5jcnlwdCBwYXNzd29yZHMgd2l0aCBpbmNsdWRlZCBDQURJIHRlY2hub2xvZ3ksIHNvIHRoYXQgdGhlcmUgYXJlIG5vIENsZWFyIFRleHQgUGFzc3dvcmRzIGluIENvbmZpZyBGaWxlcyAoQVNQUikNCiuVCVNlZSBDQURJIERlcGxveW1lbnQgb24gaG93IHRvIHBlcmZvcm0gdGhpcyB3aXRoIHNldmVyYWwgZGlmZmVyZW50IHRlY2hub2xvZ2llcy4NCiuVCUFBRiBSZXN0ZnVsbHkgKHNlZSBSRVNURnVsIEFQSVMpDQorDQorSU1QT1JUQU5UOiBJZiBEaXJlY3QgUkVTVEZ1bCBBUEkgaXMgdXNlZCwgdGhlbiBpdCBpcyB0aGUgQ2xpZW50J3MgcmVzcG9uc2liaWxpdHkgdG8gQ2FjaGUgYW5kIGF2b2lkIG1ha2luZyBhbiBBQUYgU2VydmljZSBDYWxscyB0b28gb2Z0ZW4NCitFeGFtcGxlOiBBIFRvb2wgbGlrZSBDYXNzYW5kcmEgd2lsbCBhc2sgZm9yIEF1dGhlbnRpY2F0aW9uIGh1bmRyZWRzIG9mIHRpbWVzIGEgc2Vjb25kIGZvciB0aGUgc2FtZSBpZGVudGl0eSBkdXJpbmcgYSB0cmFuc2FjdGlvbi4gIENhbGxpbmcgdGhlIEFBRiBTZXJ2aWNlIGZvciBlYWNoIHdvdWxkIGJlIHNsb3cgZm9yIHRoZSBjbGllbnQsIGFuZCB3YXN0ZWZ1bCBvZiBOZXR3b3JrIGFuZCBBQUYgU2VydmljZSBDYXBhY2l0aWVzLiAgDQorUm9ndWUgQ2xpZW50cyBjYW4gYW5kIHdpbGwgYmUgZGVuaWVkIGFjY2VzcyB0byBBQUYuDQorDQorDQorSjJFRSAoU2VydmxldCBGaWx0ZXIpIE1ldGhvZA0KKz09PT09PT09PT09PT09PT09PT09PT09PT09PT0NCisNCisxLglQZXIgSjJFRSBkZXNpZ24sIHRoZSBGaWx0ZXIgd2lsbCBkZW55IGFueSB1bmF1dGhlbnRpY2F0ZWQgSFRUUC9TIGNhbGw7IHRoZSBTZXJ2bGV0IHdpbGwgbm90IGV2ZW4gYmUgaW52b2tlZC4NCithLglUaGVyZWZvcmUsIHRoZSBTZXJ2bGV0IGNhbiBkZXBlbmQgb24gYW55IHRyYW5zYWN0aW9uIG1ha2luZyBpdCB0byB0aGVpciBjb2RlIHNldCBpcyBBdXRoZW50aWNhdGVkLg0KK2IuCUlkZW50aXR5IGNhbiBiZSB2aWV3ZWQgYmFzZWQgb24gdGhlIEh0dHBTZXJ2bGV0UmVxdWVzdCBPYmplY3QgKHJlcXVlc3QuZ2V0VXNlclByaW5jaXBhbCgpICkNCisyLglQZXIgSjJFRSBkZXNpZ24sIEFBRiBGaWx0ZXIgb3ZlcmxvYWRzIHRoZSBIdHRwU2VydmxldFJlcXVlc3QgZm9yIGEgU3RyaW5nIHJlbGF0ZWQgdG8gIlJvbGUiLiAgKHJlcXVlc3QuaXNVc2VySW5Sb2xlKCIuLi4iKSApDQorYS4JRm9yIEFBRiwgZG8gbm90IHB1dCBpbiAiUm9sZSIsIGJ1dCB0aGUgdGhyZWUgcGFydHMgb2YgcmVxdWVzdGVkICJQZXJtaXNzaW9uIiwgc2VwYXJhdGVkIGJ5ICJ8IiwgaS5lLiAgIm9yZy5vbmFwLmFhZi5teWFwcC5teXBlcm18bXlJbnN0YW5jZXxteUFjdGlvbiIuDQorMy4JTk9UIFJFUVVJUkVEOiBBbiBhZGRlZCBiZW5lZml0LCBidXQgbm90IHJlcXVpcmVkLCBpcyBhIEpBU1BJIGxpa2UgaW50ZXJmYWNlLCB3aGVyZSB5b3UgY2FuIGFkZCBhbiBBbm5vdGF0aW9uIHRvIHlvdXIgU2VydmxldC4gDQorYS4JV2hlbiB1c2VkLCBubyB0cmFuc2FjdGlvbiB3aWxsIGNvbWUgaW50byB5b3VyIGNvZGUgaWYgdGhlIGxpc3RlZCBQZXJtaXNzaW9ucyBhcmUgbm90IEdyYW50ZWQgdG8gdGhlIEluY29taW5nIFRyYW5zYWN0aW9uLiAgDQorYi4JVGhpcyBtaWdodCBiZSBoZWxwZnVsIGZvciBjb3ZlcmluZyBzZXBhcmF0ZSBNYW5hZ2VtZW50IFNlcnZsZXQgaW1wbGVtZW50YXRpb25zLg0KKw0KKw0KKw0KK1NlcnZsZXQgQ29kZSBTbmlwcGV0DQorPT09PT09PT09PT09PT09PT09PT09PT09PQ0KKw0KK3B1YmxpYyB2b2lkIHNlcnZpY2UoU2VydmxldFJlcXVlc3QgcmVxLCBTZXJ2bGV0UmVzcG9uc2UgcmVzKSB0aHJvd3MgU2VydmxldEV4Y2VwdGlvbiwgSU9FeGNlcHRpb24gew0KKyAgICBIdHRwU2VydmxldFJlcXVlc3QgcmVxdWVzdDsNCisgICAgdHJ5IHsNCisgICAgICAgIHJlcXVlc3QgPSAoSHR0cFNlcnZsZXRSZXF1ZXN0KXJlcTsNCisgICAgfSBjYXRjaCAoQ2xhc3NDYXN0RXhjZXB0aW9uIGUpIHsNCisgICAgICAgIHRocm93IG5ldyBTZXJ2bGV0RXhjZXB0aW9uKCJPbmx5IHNlcnZpbmcgSFRUUCB0b2RheSIsZSk7DQorICAgIH0NCisgICAgIA0KKyAgICAvLyBOb3RlOiBDQURJIGlzIE9WRVJMT0FESU5HIHRoZSBjb25jZXB0IG9mICJpc1VzZXJJblJvbGUiLi4gWW91IG5lZWQgdG8gdGhpbmsgImRvZXNVc2VySGF2ZVBlcm1zc2lvbigpIg0KKyAgICAvLyBBc3N1bWUgdGhhdCB5b3UgaGF2ZSBDUkVBVEVEIGFuZCBHUkFOVEVEIEFuIEFBRiBQZXJtaXNzaW9uIGluIFlPVVIgTmFtZXNwYWNlDQorICAgIC8vIEV4YW1wbGUgUGVybWlzc2lvbjogICAib3JnLm9uYXAuYWFmLm15YXBwLm15UGVybSAqIHdyaXRlIg0KKyANCisgICAgLy8gVGhpbmsgaW4geW91ciBoZWFkLCAiRG9lcyB1c2VyIGhhdmUgd3JpdGUgcGVybWlzc2lvbiBvbiBhbnkgaW5zdGFuY2Ugb2Ygb3JnLm9uYXAuYWFmLm15YXBwLm15UGVybQ0KKyAgICBpZihyZXF1ZXN0LmlzVXNlckluUm9sZSgib3JnLm9uYXAuYWFmLm15YXBwLm15UGVybXwqfHdyaXRlIikpIHsgDQorICAgICAgICAvLyAqKiogRG8gc29tZXRoaW5nIGhlcmUgdGhhdCBzb21lb25lIHdpdGggIm15UGVybSB3cml0ZSIgcGVybWlzc2lvbnMgaXMgYWxsb3dlZCB0byBkbw0KKyAgICB9IGVsc2Ugew0KKyAgICAgICAgLy8gKioqIERvIHNvbWV0aGluZyByZWFzb25hYmxlIGlmIHVzZXIgaXMgZGVuaWVkLCBsaWtlIGFuIEVycm9yIE1lc3NhZ2UNCisgICAgfQ0KKyANCit9DQorDQorSGVyZSBpcyBhIHdvcmtpbmcgVGVzdFNlcnZsZXQsIHdoZXJlIHlvdSBjYW4gcGxheSB3aXRoIGRpZmZlcmVudCBQZXJtaXNzaW9ucyB0aGF0IHlvdSBvd24gb24gdGhlIFVSTCwgaS5lLjoNCitodHRwczovLzx5b3VyIG1hY2hpbmU6cG9ydD4vY2FkaXRlc3QvdGVzdG1lP1BFUk09b3JnLm9uYXAuYWFmLm15YXBwLm15UGVybXwqfHdyaXRlDQorDQorU2FtcGxlIFNlcnZsZXQgKFdvcmtpbmcgZXhhbXBsZSkNCis9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQ0KK3BhY2thZ2Ugb3JnLm9uYXAuYWFmLmNhZGkuZGVidWc7DQoraW1wb3J0IGphdmEuaW8uRmlsZUlucHV0U3RyZWFtOw0KK2ltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOw0KK2ltcG9ydCBqYXZhLm5ldC5JbmV0QWRkcmVzczsNCitpbXBvcnQgamF2YS5uZXQuVW5rbm93bkhvc3RFeGNlcHRpb247DQoraW1wb3J0IGphdmEudXRpbC5IYXNoTWFwOw0KK2ltcG9ydCBqYXZhLnV0aWwuTWFwOw0KK2ltcG9ydCBqYXZhLnV0aWwuTWFwLkVudHJ5Ow0KK2ltcG9ydCBqYXZhLnV0aWwuUHJvcGVydGllczsNCitpbXBvcnQgamF2YXguc2VydmxldC5TZXJ2bGV0Ow0KK2ltcG9ydCBqYXZheC5zZXJ2bGV0LlNlcnZsZXRDb25maWc7DQoraW1wb3J0IGphdmF4LnNlcnZsZXQuU2VydmxldEV4Y2VwdGlvbjsNCitpbXBvcnQgamF2YXguc2VydmxldC5TZXJ2bGV0UmVxdWVzdDsNCitpbXBvcnQgamF2YXguc2VydmxldC5TZXJ2bGV0UmVzcG9uc2U7DQoraW1wb3J0IGphdmF4LnNlcnZsZXQuaHR0cC5IdHRwU2VydmxldFJlcXVlc3Q7DQoraW1wb3J0IG9yZy5lY2xpcHNlLmpldHR5LnNlcnZlci5TZXJ2ZXI7DQoraW1wb3J0IG9yZy5lY2xpcHNlLmpldHR5LnNlcnZlci5TZXJ2ZXJDb25uZWN0b3I7DQoraW1wb3J0IG9yZy5lY2xpcHNlLmpldHR5LnNlcnZlci5oYW5kbGVyLkNvbnRleHRIYW5kbGVyOw0KK2ltcG9ydCBvcmcuZWNsaXBzZS5qZXR0eS5zZXJ2bGV0LkZpbHRlckhvbGRlcjsNCitpbXBvcnQgb3JnLmVjbGlwc2UuamV0dHkuc2VydmxldC5GaWx0ZXJNYXBwaW5nOw0KK2ltcG9ydCBvcmcuZWNsaXBzZS5qZXR0eS5zZXJ2bGV0LlNlcnZsZXRDb250ZXh0SGFuZGxlcjsNCitpbXBvcnQgb3JnLmVjbGlwc2UuamV0dHkuc2VydmxldC5TZXJ2bGV0SGFuZGxlcjsNCitpbXBvcnQgb3JnLm9uYXAuYWFmLmNhZGkuZmlsdGVyLkNhZGlGaWx0ZXI7DQoraW1wb3J0IG9yZy5vbmFwLmFhZi5jYWRpLmZpbHRlci5Sb2xlc0FsbG93ZWQ7DQoraW1wb3J0IG9yZy5vbmFwLmFhZi5jYWRpLmpldHR5Lk1pbmlKQVNQSVdyYXA7DQorIA0KK3B1YmxpYyBjbGFzcyBDU1BTZXJ2bGV0VGVzdCB7DQorICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKFN0cmluZ1tdIGFyZ3MpIHsNCisgICAgICAgIC8vIEdvIGFoZWFkIGFuZCBwcmludCBUZXN0IHJlcG9ydHMgaW4gY2FkaS1jb3JlIGZpcnN0DQorICAgICAgICBUZXN0Lm1haW4oYXJncyk7DQorICAgICAgICBTdHJpbmcgaG9zdG5hbWU9bnVsbDsNCisgICAgICAgIHRyeSB7DQorICAgICAgICAgICAgaG9zdG5hbWUgPSBJbmV0QWRkcmVzcy5nZXRMb2NhbEhvc3QoKS5nZXRIb3N0TmFtZSgpOw0KKyAgICAgICAgfSBjYXRjaCAoVW5rbm93bkhvc3RFeGNlcHRpb24gZSkgew0KKyAgICAgICAgICAgIGUucHJpbnRTdGFja1RyYWNlKCk7DQorICAgICAgICAgICAgU3lzdGVtLmV4aXQoMSk7DQorICAgICAgICB9DQorICAgICAgICBQcm9wZXJ0aWVzIHByb3BzID0gbmV3IFByb3BlcnRpZXMoKTsNCisgICAgICAgIE1hcDxTdHJpbmcsU3RyaW5nPiBtYXAgPSBuZXcgSGFzaE1hcDxTdHJpbmcsU3RyaW5nPigpOw0KKyAgICAgICAgdHJ5IHsNCisgICAgICAgICAgICBGaWxlSW5wdXRTdHJlYW0gZmlzID0gbmV3IEZpbGVJbnB1dFN0cmVhbSgicnVuL2NhZGkucHJvcGVydGllcyIpOw0KKyAgICAgICAgICAgIHRyeSB7DQorICAgICAgICAgICAgICAgIHByb3BzLmxvYWQoZmlzKTsNCisgICAgICAgICAgICAgICAgU3RyaW5nIGtleSx2YWx1ZTsNCisgICAgICAgICAgICAgICAgZm9yKCBFbnRyeTxPYmplY3QsIE9iamVjdD4gZXMgIDogcHJvcHMuZW50cnlTZXQoKSkgew0KKyAgICAgICAgICAgICAgICAgICAga2V5ID0gZXMuZ2V0S2V5KCkudG9TdHJpbmcoKTsNCisgICAgICAgICAgICAgICAgICAgIHZhbHVlID0gZXMuZ2V0VmFsdWUoKS50b1N0cmluZygpOw0KKyAgICAgICAgICAgICAgICAgICAgbWFwLnB1dChrZXksdmFsdWUpOw0KKyAgICAgICAgICAgICAgICAgICAgaWYoa2V5LnN0YXJ0c1dpdGgoIkFGVF8iKSB8fCBrZXkuc3RhcnRzV2l0aCgiRE1FMiIpKSB7DQorICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtLnNldFByb3BlcnR5KGtleSx2YWx1ZSk7DQorICAgICAgICAgICAgICAgICAgICB9DQorICAgICAgICAgICAgICAgIH0NCisgICAgICAgICAgICB9IGZpbmFsbHkgew0KKyAgICAgICAgICAgICAgICBmaXMuY2xvc2UoKTsNCisgICAgICAgICAgICB9DQorICAgICAgICB9IGNhdGNoKElPRXhjZXB0aW9uIGUpIHsNCisgICAgICAgICAgICBTeXN0ZW0uZXJyLnByaW50bG4oIkNhbm5vdCBsb2FkIHJ1bi9jYWRpLnByb3BlcnRpZXMiKTsNCisgICAgICAgICAgICBTeXN0ZW0uZXhpdCgxKTsNCisgICAgICAgIH0NCisgICAgICAgIFN0cmluZyBwb3J0U3RyID0gU3lzdGVtLmdldFByb3BlcnR5KCJwb3J0Iik7DQorICAgICAgICBpbnQgcG9ydCA9IHBvcnRTdHI9PW51bGw/ODA4MDpJbnRlZ2VyLnBhcnNlSW50KHBvcnRTdHIpOw0KKyAgICAgICAgdHJ5IHsNCisgICAgICAgICAgICAvLyBBZGQgU2VydmxldEhvbGRlcihzKSBhbmQgRmlsdGVyKHMpIHRvIGEgU2VydmxldEhhbmRsZXINCisgICAgICAgICAgICBTZXJ2bGV0SGFuZGxlciBzaGFuZCA9IG5ldyBTZXJ2bGV0SGFuZGxlcigpOw0KKyAgICAgICAgICAgICANCisgICAgICAgICAgICBGaWx0ZXJIb2xkZXIgY2ZoID0gbmV3IEZpbHRlckhvbGRlcihDYWRpRmlsdGVyLmNsYXNzKTsNCisgICAgICAgICAgICBjZmguc2V0SW5pdFBhcmFtZXRlcnMobWFwKTsNCisgICAgICAgICAgICAgDQorICAgICAgICAgICAgc2hhbmQuYWRkRmlsdGVyV2l0aE1hcHBpbmcoY2ZoLCAiLyoiLCBGaWx0ZXJNYXBwaW5nLkFMTCk7DQorICAgICAgICAgICAgc2hhbmQuYWRkU2VydmxldFdpdGhNYXBwaW5nKG5ldyBNaW5pSkFTUElXcmFwKE15U2VydmxldC5jbGFzcyksIi8qIik7DQorICAgICAgICAgICAgLy8gY2FsbCBpbml0aWFsaXplIGFmdGVyIHN0YXJ0DQorICAgICAgICAgICAgIA0KKyAgICAgICAgICAgIENvbnRleHRIYW5kbGVyIGNoID0gbmV3IFNlcnZsZXRDb250ZXh0SGFuZGxlcigpOw0KKyAgICAgICAgICAgIGNoLnNldENvbnRleHRQYXRoKCIvY2FkaXRlc3QiKTsNCisgICAgICAgICAgICBjaC5zZXRIYW5kbGVyKHNoYW5kKTsNCisgICAgICAgICAgICBmb3IoIEVudHJ5PE9iamVjdCxPYmplY3Q+IGVzIDogcHJvcHMuZW50cnlTZXQoKSkgew0KKyAgICAgICAgICAgICAgICBjaC5nZXRJbml0UGFyYW1zKCkucHV0KGVzLmdldEtleSgpLnRvU3RyaW5nKCksIGVzLmdldFZhbHVlKCkudG9TdHJpbmcoKSk7DQorICAgICAgICAgICAgfQ0KKyAgICAgICAgICAgIC8vY2guc2V0RXJyb3JIYW5kbGVyKG5ldyBNeUVycm9ySGFuZGxlcigpKTsNCisgICAgICAgICAgICAgDQorICAgICAgICAgICAgLy8gQ3JlYXRlIFNlcnZlciBhbmQgQWRkIENvbnRleHQgSGFuZGxlcg0KKyAgICAgICAgICAgIGZpbmFsIFNlcnZlciBzZXJ2ZXIgPSBuZXcgU2VydmVyKCk7DQorICAgICAgICAgICAgU2VydmVyQ29ubmVjdG9yIGh0dHAgPSBuZXcgU2VydmVyQ29ubmVjdG9yKHNlcnZlcik7DQorICAgICAgICAgICAgaHR0cC5zZXRQb3J0KHBvcnQpOw0KKyAgICAgICAgICAgIHNlcnZlci5hZGRDb25uZWN0b3IoaHR0cCk7DQorICAgICAgICAgICAgc2VydmVyLnNldEhhbmRsZXIoY2gpOw0KKyAgICAgICAgIA0KKyAgICAgICAgICAgIC8vIFN0YXJ0DQorICAgICAgICAgICAgc2VydmVyLnN0YXJ0KCk7DQorICAgICAgICAgICAgc2hhbmQuaW5pdGlhbGl6ZSgpOw0KKyAgICAgICAgICAgICANCisgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlRvIHRlc3QsIHB1dCBodHRwOi8vIisgaG9zdG5hbWUgKyAnOicgKyBwb3J0ICsgIi9jYWRpdGVzdC90ZXN0bWUgaW4gYSBicm93c2VyIG9yICdjdXJsJyIpOw0KKyAgICAgICAgICAgIC8vIGlmIHdlIHdlcmUgcmVhbGx5IGEgc2VydmVyLCB3ZSdkIGJsb2NrIHRoZSBtYWluIHRocmVhZCB3aXRoIHRoaXMgam9pbi4uLg0KKyAgICAgICAgICAgIC8vIHNlcnZlci5qb2luKCk7DQorICAgICAgICAgICAgLy8gQnV0Li4uIHNpbmNlIHdlJ3JlIGEgdGVzdCBzZXJ2aWNlLCB3ZSdsbCBibG9jayBvbiBTdGRJbg0KKyAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiUHJlc3MgPFJldHVybj4gdG8gZW5kIHNlcnZpY2UuLi4iKTsNCisgICAgICAgICAgICBTeXN0ZW0uaW4ucmVhZCgpOw0KKyAgICAgICAgICAgIHNlcnZlci5zdG9wKCk7DQorICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJBbGwgZG9uZSwgaGF2ZSBhIGdvb2QgZGF5ISIpOw0KKyAgICAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsNCisgICAgICAgICAgICBlLnByaW50U3RhY2tUcmFjZSgpOw0KKyAgICAgICAgICAgIFN5c3RlbS5leGl0KDEpOw0KKyAgICAgICAgfQ0KKyAgICB9DQorICAgIEBSb2xlc0FsbG93ZWQoeyJvcmcub25hcC5hYWYubXlhcHAubXlQZXJtfG15SW5zdGFuY2V8bXlBY3Rpb24ifSkNCisgICAgcHVibGljIHN0YXRpYyBjbGFzcyBNeVNlcnZsZXQgaW1wbGVtZW50cyBTZXJ2bGV0IHsNCisgICAgICAgIHByaXZhdGUgU2VydmxldENvbmZpZyBzZXJ2bGV0Q29uZmlnOw0KKyAgICAgDQorICAgICAgICBwdWJsaWMgdm9pZCBpbml0KFNlcnZsZXRDb25maWcgY29uZmlnKSB0aHJvd3MgU2VydmxldEV4Y2VwdGlvbiB7DQorICAgICAgICAgICAgc2VydmxldENvbmZpZyA9IGNvbmZpZzsNCisgICAgICAgIH0NCisgICAgIA0KKyAgICAgICAgcHVibGljIFNlcnZsZXRDb25maWcgZ2V0U2VydmxldENvbmZpZygpIHsNCisgICAgICAgICAgICByZXR1cm4gc2VydmxldENvbmZpZzsNCisgICAgICAgIH0NCisgICAgIA0KKyAgICAgICAgcHVibGljIHZvaWQgc2VydmljZShTZXJ2bGV0UmVxdWVzdCByZXEsIFNlcnZsZXRSZXNwb25zZSByZXMpIHRocm93cyBTZXJ2bGV0RXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7DQorICAgICAgICAgICAgSHR0cFNlcnZsZXRSZXF1ZXN0IHJlcXVlc3Q7DQorICAgICAgICAgICAgdHJ5IHsNCisgICAgICAgICAgICAgICAgcmVxdWVzdCA9IChIdHRwU2VydmxldFJlcXVlc3QpcmVxOw0KKyAgICAgICAgICAgIH0gY2F0Y2ggKENsYXNzQ2FzdEV4Y2VwdGlvbiBlKSB7DQorICAgICAgICAgICAgICAgIHRocm93IG5ldyBTZXJ2bGV0RXhjZXB0aW9uKCJPbmx5IHNlcnZpbmcgSFRUUCB0b2RheSIsZSk7DQorICAgICAgICAgICAgfQ0KKyAgICAgICAgICAgICANCisgICAgICAgICAgICByZXMuZ2V0T3V0cHV0U3RyZWFtKCkucHJpbnQoIjxodG1sPjxoZWFkZXI+PHRpdGxlPkNTUCBTZXJ2bGV0IFRlc3Q8L3RpdGxlPjwvaGVhZGVyPjxib2R5PjxoMT5Zb3UncmUgZ29vZCB0byBnbyE8L2gxPjxwcmU+IiArDQorICAgICAgICAgICAgICAgICAgICByZXF1ZXN0LmdldFVzZXJQcmluY2lwYWwoKSk7DQorICAgICAgICAgICAgIA0KKyAgICAgICAgICAgIFN0cmluZyBwZXJtID0gcmVxdWVzdC5nZXRQYXJhbWV0ZXIoIlBFUk0iKTsNCisgICAgICAgICAgICBpZihwZXJtIT1udWxsKQ0KKyAgICAgICAgICAgICAgICBpZihyZXF1ZXN0LmlzVXNlckluUm9sZShwZXJtKSkgew0KKyAgICAgICAgICAgICAgICAgICAgaWYocGVybS5pbmRleE9mKCd8Jyk8MCkgDQorICAgICAgICAgICAgICAgICAgICAgICAgcmVzLmdldE91dHB1dFN0cmVhbSgpLnByaW50KCJcbkNvbmdyYXRzISwgWW91IGFyZSBpbiBSb2xlICIgKyBwZXJtKTsNCisgICAgICAgICAgICAgICAgICAgICAgZWxzZQ0KKyAgICAgICAgICAgICAgICAgICAgICAgIHJlcy5nZXRPdXRwdXRTdHJlYW0oKS5wcmludCgiXG5Db25ncmF0cyEsIFlvdSBoYXZlIFBlcm1pc3Npb24gIiArIHBlcm0pOw0KKyAgICAgICAgICAgICAgICB9IGVsc2Ugew0KKyAgICAgICAgICAgICAgICAgICAgaWYocGVybS5pbmRleE9mKCd8Jyk8MCkgDQorICAgICAgICAgICAgICAgICAgICAgICAgcmVzLmdldE91dHB1dFN0cmVhbSgpLnByaW50KCJcblNvcnJ5LCB5b3UgYXJlIE5PVCBpbiBSb2xlICIgKyBwZXJtKTsNCisgICAgICAgICAgICAgICAgICAgICAgZWxzZQ0KKyAgICAgICAgICAgICAgICAgICAgICAgIHJlcy5nZXRPdXRwdXRTdHJlYW0oKS5wcmludCgiXG5Tb3JyeSwgeW91IGRvIE5PVCBoYXZlIFBlcm1pc3Npb24gIiArIHBlcm0pOw0KKyAgICAgICAgICAgICAgICB9DQorICAgICAgICAgICAgIA0KKyAgICAgICAgICAgIHJlcy5nZXRPdXRwdXRTdHJlYW0oKS5wcmludCgiPC9wcmU+PC9ib2R5PjwvaHRtbD4iKTsNCisgICAgICAgICAgICAgDQorICAgICAgICB9DQorICAgICANCisgICAgICAgIHB1YmxpYyBTdHJpbmcgZ2V0U2VydmxldEluZm8oKSB7DQorICAgICAgICAgICAgcmV0dXJuICJNeVNlcnZsZXQiOw0KKyAgICAgICAgfQ0KKyAgICAgDQorICAgICAgICBwdWJsaWMgdm9pZCBkZXN0cm95KCkgew0KKyAgICAgICAgfQ0KKyAgICB9DQorfQ0KKyANCitKYXZhIERpcmVjdCAoQUFGTHVyKSBNZXRob2QNCis9PT09PT09PT09PT09PT09PT09PT09PT09PT0NCitUaGUgQUFGTHVyIGlzIHRoZSBleGFjdCBjb21wb25lbnQgdXNlZCB3aXRoaW4gYWxsIHRoZSBQbHVnaW5zIG1lbnRpb25lZCBhYm92ZS4gIEl0IGlzIHdyaXR0ZW4gc28gdGhhdCBpdCBjYW4gYmUgY2FsbGVkIHN0YW5kYWxvbmUgYXMgd2VsbCwgc2VlIHRoZSBFeGFtcGxlIGFzIGZvbGxvd3MNCitwYWNrYWdlIG9yZy5vbmFwLmFhZi5leGFtcGxlOw0KKw0KK2ltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0Ow0KK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsNCitpbXBvcnQgamF2YS51dGlsLlByb3BlcnRpZXM7DQorDQoraW1wb3J0IG9yZy5vbmFwLmFhZi5jYWRpLkFjY2VzczsNCitpbXBvcnQgb3JnLm9uYXAuYWFmLmNhZGkuUGVybWlzc2lvbjsNCitpbXBvcnQgb3JnLm9uYXAuYWFmLmNhZGkuYWFmLnYyXzAuQUFGQXV0aG47DQoraW1wb3J0IG9yZy5vbmFwLmFhZi5jYWRpLmFhZi52Ml8wLkFBRkNvbjsNCitpbXBvcnQgb3JnLm9uYXAuYWFmLmNhZGkuYWFmLnYyXzAuQUFGTHVyUGVybTsNCitpbXBvcnQgb3JnLm9uYXAuYWFmLmNhZGkuY29uZmlnLkNvbmZpZzsNCitpbXBvcnQgb3JnLm9uYXAuYWFmLmNhZGkubHVyLmFhZi5BQUZQZXJtaXNzaW9uOw0KK2ltcG9ydCBvcmcub25hcC5hYWYuY2FkaS5sdXIuYWFmLnRlc3QuVGVzdEFjY2VzczsNCisNCitwdWJsaWMgY2xhc3MgRXhhbXBsZVBlcm0yXzAgew0KKwlwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihTdHJpbmcgYXJnc1tdKSB7DQorCQkvLyBOb3JtYWxseSwgdGhlc2Ugc2hvdWxkIGJlIHNldCBpbiBlbnZpcm9ubWVudC4gIFNldHRpbmcgaGVyZSBmb3IgY2xhcml0eQ0KKwkJUHJvcGVydGllcyBwcm9wcyA9IFN5c3RlbS5nZXRQcm9wZXJ0aWVzKCk7DQorCQlwcm9wcy5zZXRQcm9wZXJ0eSgiQUZUX0xBVElUVURFIiwgIjMyLjc4MDE0MCIpOw0KKwkJcHJvcHMuc2V0UHJvcGVydHkoIkFGVF9MT05HSVRVREUiLCAiLTk2LjgwMDQ1MSIpOw0KKwkJcHJvcHMuc2V0UHJvcGVydHkoIkFGVF9FTlZJUk9OTUVOVCIsICJBRlRVQVQiKTsNCisJCXByb3BzLnNldFByb3BlcnR5KENvbmZpZy5BQUZfVVJMLA0KKwkJImh0dHBzOi8vRE1FMlJFU09MVkUvc2VydmljZT1vcmcub25hcC5hYWYuYXV0aHouQXV0aG9yaXphdGlvblNlcnZpY2UvdmVyc2lvbj0yLjAvZW52Q29udGV4dD1URVNUL3JvdXRlT2ZmZXI9QkFVX1NFIg0KKwkJCQkpOw0KKwkJcHJvcHMuc2V0UHJvcGVydHkoQ29uZmlnLkFBRl9VU0VSX0VYUElSRVMsSW50ZWdlci50b1N0cmluZyg1KjYwMDAwKSk7CS8vIDUgbWludXRlcyBmb3IgZm91bmQgaXRlbXMgdG8gbGl2ZSBpbiBjYWNoZQ0KKwkJcHJvcHMuc2V0UHJvcGVydHkoQ29uZmlnLkFBRl9ISUdIX0NPVU5ULEludGVnZXIudG9TdHJpbmcoNDAwKSk7CQkvLyBNYXhpbXVtIG51bWJlciBvZiBpdGVtcyBpbiBDYWNoZSk7DQorCQlwcm9wcy5zZXRQcm9wZXJ0eShDb25maWcuQ0FESV9LRVlGSUxFLCJrZXlmaWxlIik7IC8vTm90ZTogQmUgc3VyZSB0byBnZW5lcmF0ZSB3aXRoIGphdmEgLWphciA8Y2FkaV9wYXRoPi9saWIvY2FkaS1jb3JlKi5qYXIga2V5Z2VuIGtleWZpbGUNCisvLwkJcHJvcHMuc2V0UHJvcGVydHkoIkRNRTJfRVBfUkVHSVNUUllfQ0xBU1MiLCJETUUyRlMiKTsNCisvLwkJcHJvcHMuc2V0UHJvcGVydHkoIkFGVF9ETUUyX0VQX1JFR0lTVFJZX0ZTX0RJUiIsIi4uLy4uL2F1dGh6L2RtZTJyZWciKTsNCisNCisJCQ0KKwkJLy8gTGluayBvciByZXVzZSB0byB5b3VyIExvZ2dpbmcgbWVjaGFuaXNtDQorCQlBY2Nlc3MgbXlBY2Nlc3MgPSBuZXcgVGVzdEFjY2VzcygpOyAvLyANCisJCQ0KKwkJLy8gDQorCQl0cnkgew0KKwkJCUFBRkNvbjw/PiBjb24gPSBuZXcgQUFGQ29uRE1FMihteUFjY2Vzcyk7DQorCQkJDQorCQkJLy8gQUFGTHVyIGhhcyBwb29sIG9mIERNRSBjbGllbnRzIGFzIG5lZWRlZCwgYW5kIENhY2hlcyBDbGllbnQgbG9va3Vwcw0KKwkJCUFBRkx1clBlcm0gYWFmTHVyID0gY29uLm5ld0x1cigpOw0KKwkJCS8vIE5vdGU6IElmIHlvdSBuZWVkIGJvdGggQXV0aG4gYW5kIEF1dGh6IGNvbnN0cnVjdCB0aGUgZm9sbG93aW5nOg0KKwkJCUFBRkF1dGhuPD8+IGFhZkF1dGhuID0gY29uLm5ld0F1dGhuKGFhZkx1cik7DQorDQorCQkJLy8gRG8gbm90IHNldCBNZWNoIElEIHVudGlsIGFmdGVyIHlvdSBjb25zdHJ1Y3QgQUFGQXV0aG4sDQorCQkJLy8gYmVjYXVzZSB3ZSBpbml0aWF0ZSAgIjQwMSIgaW5mbyB0byBkZXRlcm1pbmUgdGhlIFJlYWxtIG9mIA0KKwkJCS8vIG9mIHRoZSBzZXJ2aWNlIHdlJ3JlIGFmdGVyLg0KKwkJCWNvbi5iYXNpY0F1dGgoInh4eHhAYWFmLmFiYy5jb20iLCAiWFhYWFhYIik7DQorDQorCQkJdHJ5IHsNCisJCQkJDQorCQkJCS8vIE5vcm1hbGx5LCB5b3Ugb2J0YWluIFByaW5jaXBhbCBmcm9tIEF1dGhlbnRpY2F0aW9uIFN5c3RlbS4NCisJCQkJLy8gRm9yIEoyRUUsIHlvdSBjYW4gYXNrIHRoZSBIdHRwU2VydmxldFJlcXVlc3QgZm9yIGdldFVzZXJQcmluY2lwYWwoKQ0KKwkJCQkvLyBJZiB5b3UgdXNlIENBREkgYXMgQXV0aGVudGljYXRvciwgaXQgd2lsbCBnZXQgeW91IHRoZXNlIFByaW5jaXBhbHMgZnJvbQ0KKwkJCQkvLyBDU1Agb3IgQmFzaWNBdXRoIG1lY2hhbmlzbXMuDQorCQkJCVN0cmluZyBpZCA9ICJ4eHh4QGFhZi5hYmMuY29tIjsgLy8iY2x1c3Rlcl9hZG1pbkBncmlkY29yZS5hYmMuY29tIjsNCisNCisJCQkJLy8gSWYgVmFsaWRhdGUgc3VjY2VlZHMsIHlvdSB3aWxsIGdldCBhIE51bGwsIG90aGVyd2lzZSwgeW91IHdpbGwgYSBTdHJpbmcgZm9yIHRoZSByZWFzb24uDQorCQkJCVN0cmluZyBvayA9IGFhZkF1dGhuLnZhbGlkYXRlKGlkLCAiWFhYWFhYIik7DQorCQkJCWlmKG9rIT1udWxsKVN5c3RlbS5vdXQucHJpbnRsbihvayk7DQorCQkJCQ0KKwkJCQlvayA9IGFhZkF1dGhuLnZhbGlkYXRlKGlkLCAid3JvbmdQYXNzIik7DQorCQkJCWlmKG9rIT1udWxsKVN5c3RlbS5vdXQucHJpbnRsbihvayk7DQorDQorDQorCQkJCS8vIEFBRiBTdHlsZSBwZXJtaXNzaW9ucyBhcmUgaW4gdGhlIGZvcm0NCisJCQkJLy8gVHlwZSwgSW5zdGFuY2UsIEFjdGlvbiANCisJCQkJQUFGUGVybWlzc2lvbiBwZXJtID0gbmV3IEFBRlBlcm1pc3Npb24oIm9yZy5vbmFwLmFhZi5ncmlkLmNvcmUuY29oIiwiOmRldl9jbHVzdGVyIiwgIldSSVRFIik7DQorCQkJCQ0KKwkJCQkvLyBOb3cgeW91IGNhbiBhc2sgdGhlIExVUiAoTG9jYWwgUmVwcmVzZW50YXRpdmUgb2YgdGhlIFVzZXIgUmVwb3NpdG9yeSBhYm91dCBBdXRob3JpemF0aW9uDQorCQkJCS8vIFdpdGggQ0FESSwgaW4gSjJFRSwgeW91IGNhbiBjYWxsIGlzVXNlckluUm9sZSgib3JnLm9uYXAuYWFmLm15Z3JvdXB8bXl0eXBlfHdyaXRlIikgb24gdGhlIFJlcXVlc3QgT2JqZWN0IA0KKwkJCQkvLyBpbnN0ZWFkIG9mIGNyZWF0aW5nIHlvdXIgb3duIExVUg0KKwkJCQlTeXN0ZW0ub3V0LnByaW50bG4oIkRvZXMgIiArIGlkICsgIiBoYXZlICIgKyBwZXJtKTsNCisJCQkJaWYoYWFmTHVyLmZpc2goaWQsIHBlcm0pKSB7DQorCQkJCQlTeXN0ZW0ub3V0LnByaW50bG4oIlllcywgeW91IGhhdmUgcGVybWlzc2lvbiIpOw0KKwkJCQl9IGVsc2Ugew0KKwkJCQkJU3lzdGVtLm91dC5wcmludGxuKCJObywgeW91IGRvbid0IGhhdmUgcGVybWlzc2lvbiIpOw0KKwkJCQl9DQorDQorCQkJCVN5c3RlbS5vdXQucHJpbnRsbigiRG9lcyBCb2d1cyBoYXZlICIgKyBwZXJtKTsNCisJCQkJaWYoYWFmTHVyLmZpc2goIkJvZ3VzIiwgcGVybSkpIHsNCisJCQkJCVN5c3RlbS5vdXQucHJpbnRsbigiWWVzLCB5b3UgaGF2ZSBwZXJtaXNzaW9uIik7DQorCQkJCX0gZWxzZSB7DQorCQkJCQlTeXN0ZW0ub3V0LnByaW50bG4oIk5vLCB5b3UgZG9uJ3QgaGF2ZSBwZXJtaXNzaW9uIik7DQorCQkJCX0NCisNCisJCQkJLy8gT3IgeW91IGNhbiBhbGwgZm9yIGFsbCB0aGUgUGVybWlzc2lvbnMgYXZhaWxhYmxlDQorCQkJCUxpc3Q8UGVybWlzc2lvbj4gcGVybXMgPSBuZXcgQXJyYXlMaXN0PFBlcm1pc3Npb24+KCk7DQorCQkJCQ0KKwkJCQlhYWZMdXIuZmlzaEFsbChpZCxwZXJtcyk7DQorCQkJCWZvcihQZXJtaXNzaW9uIHBybSA6IHBlcm1zKSB7DQorCQkJCQlTeXN0ZW0ub3V0LnByaW50bG4ocHJtLmdldEtleSgpKTsNCisJCQkJfQ0KKwkJCQkNCisJCQkJLy8gSXQgbWlnaHQgYmUgaGVscGZ1bCBpbiBzb21lIGNhc2VzIHRvIGNsZWFyIHRoZSBVc2VyJ3MgaWRlbnRpdHkgZnJvbSB0aGUgQ2FjaGUNCisJCQkJYWFmTHVyLnJlbW92ZShpZCk7DQorCQkJfSBmaW5hbGx5IHsNCisJCQkJYWFmTHVyLmRlc3Ryb3koKTsNCisJCQl9DQorCQl9IGNhdGNoIChFeGNlcHRpb24gZSkgew0KKwkJCWUucHJpbnRTdGFja1RyYWNlKCk7DQorCQl9DQorDQorCX0NCit9DQorDQorVGhlcmUgYXJlIHR3byBjdXJyZW50IEFBRiBMdXJzIHdoaWNoIHlvdSBjYW4gdXRpbGl6ZToNCiuVCU9yZy5vbmFwLmFhZi5jYWRpLmFhZi52Ml8wLkFBRkx1clBlcm0gaXMgdGhlIGRlZmF1bHQsIGFuZCB3aWxsIGZpc2ggYmFzZWQgb24gdGhlIFRocmVlLWZvbGQgIlBlcm1pc3Npb24iIHN0YW5kYXJkIGluIEFBRg0KK1RvIHJ1biB0aGlzIGNvZGUsIHlvdSB3aWxsIG5lZWQgZnJvbSBhIFNXTSBkZXBsb3ltZW50IChvcmcub25hcC5hYWYuY2FkaTpjYWRpLCB0aGVuIHNvZnQgbGluayB0byBqYXJzIG5lZWRlZCk6DQorlQljYWRpLWNvcmUtPHZlcnNpb24+Lmphcg0KK5UJY2FkaS1hYWYtPHZlcnNpb24+LWZ1bGwuamFyDQorICAgb3IgYnkgTWF2ZW4NCis8ZGVwZW5kZW5jeT4NCis8Z3JvdXBJZD5vcmcub25hcC5hYWYuY2FkaTwvZ3JvdXBJZD4NCis8YXJ0aWZhY3RJZD5jYWRpLWFhZjwvYXJ0aWZhY3RJZD4NCis8dmVyc2lvbj5USEVfTEFURVNUX1ZFUlNJT048L3ZlcnNpb24+DQorPGNsYXNzaWZpZXI+ZnVsbDwvY2xhc3NpZmllcj4gDQorPC9kZXBlbmRlbmN5Pg0KKyAgIElmIHlvdSBuZWVkIHRoZSBKYXZhIENsaWVudCBkZWZpbml0aW9ucyBvbmx5LCANCisgDQorICAgQWxzbyBuZWVkZWQgYXJlIHRoZSBETUUyIENsaWVudCBsaWJyYXJpZXM6DQorlQlkbWUyLTx2ZXJzaW9uPi5qYXINCiuVCWRpc2NvdmVyeS1jbHQtPHZlcnNpb24+Lmphcg0KKw0K