LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogDQogKiBDb3B5cmlnaHQgKGMpIDIwMTIgQnVuZGVzaW5zdGl0dXQgZvxyIFJpc2lrb2Jld2VydHVuZy4gDQogKiBBbGwgcmlnaHRzIHJlc2VydmVkLiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIA0KICogYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2MS4wIA0KICogd2hpY2ggYWNjb21wYW5pZXMgdGhpcyBkaXN0cmlidXRpb24sIGFuZCBpcyBhdmFpbGFibGUgYXQgDQogKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC12MTAuaHRtbCANCiAqIA0KICogQ29udHJpYnV0b3JzOiANCiAqICAgICBCdW5kZXNpbnN0aXR1dCBm/HIgUmlzaWtvYmV3ZXJ0dW5nIC0gaW5pdGlhbCBBUEkgYW5kIGltcGxlbWVudGF0aW9uIA0KICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovDQoNCnBhY2thZ2Ugb3JnLmVjbGlwc2Uuc3RlbS51aS5ncmFwaGVkaXRvcjsNCg0KaW1wb3J0IGphdmEuYXd0Lmdlb20uUG9pbnQyRDsNCmltcG9ydCBqYXZhLmF3dC5nZW9tLlJlY3RhbmdsZTJEOw0KaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247DQppbXBvcnQgamF2YS50ZXh0LkRlY2ltYWxGb3JtYXQ7DQppbXBvcnQgamF2YS50ZXh0LkRlY2ltYWxGb3JtYXRTeW1ib2xzOw0KaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7DQppbXBvcnQgamF2YS51dGlsLkFycmF5czsNCmltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsNCmltcG9ydCBqYXZhLnV0aWwuSGFzaFNldDsNCmltcG9ydCBqYXZhLnV0aWwuTGlzdDsNCmltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOw0KaW1wb3J0IGphdmEudXRpbC5NYXA7DQppbXBvcnQgamF2YS51dGlsLlNldDsNCg0KaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucmVzb3VyY2VzLklGaWxlOw0KaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucmVzb3VyY2VzLklQcm9qZWN0Ow0KaW1wb3J0IG9yZy5lY2xpcHNlLmNvcmUucmVzb3VyY2VzLklSZXNvdXJjZTsNCmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJlc291cmNlcy5SZXNvdXJjZXNQbHVnaW47DQppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5ydW50aW1lLkNvcmVFeGNlcHRpb247DQppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5ydW50aW1lLklQcm9ncmVzc01vbml0b3I7DQppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5ydW50aW1lLk51bGxQcm9ncmVzc01vbml0b3I7DQppbXBvcnQgb3JnLmVjbGlwc2UuZHJhdzJkLkNvbG9yQ29uc3RhbnRzOw0KaW1wb3J0IG9yZy5lY2xpcHNlLmRyYXcyZC5JRmlndXJlOw0KaW1wb3J0IG9yZy5lY2xpcHNlLmVtZi5jb21tb24udXRpbC5FTGlzdDsNCmltcG9ydCBvcmcuZWNsaXBzZS5lbWYuY29tbW9uLnV0aWwuVVJJOw0KaW1wb3J0IG9yZy5lY2xpcHNlLmVtZi5lY29yZS5FQ2xhc3M7DQppbXBvcnQgb3JnLmVjbGlwc2UuZW1mLmVjb3JlLnV0aWwuRWNvcmVVdGlsOw0KaW1wb3J0IG9yZy5lY2xpcHNlLnN0ZW0uY29yZS5TVEVNVVJJOw0KaW1wb3J0IG9yZy5lY2xpcHNlLnN0ZW0uY29yZS5VdGlsaXR5Ow0KaW1wb3J0IG9yZy5lY2xpcHNlLnN0ZW0uY29yZS5jb21tb24uSWRlbnRpZmlhYmxlOw0KaW1wb3J0IG9yZy5lY2xpcHNlLnN0ZW0uY29yZS5ncmFwaC5FZGdlOw0KaW1wb3J0IG9yZy5lY2xpcHNlLnN0ZW0uY29yZS5ncmFwaC5FZGdlTGFiZWw7DQppbXBvcnQgb3JnLmVjbGlwc2Uuc3RlbS5jb3JlLmdyYXBoLkdyYXBoOw0KaW1wb3J0IG9yZy5lY2xpcHNlLnN0ZW0uY29yZS5ncmFwaC5Ob2RlOw0KaW1wb3J0IG9yZy5lY2xpcHNlLnN0ZW0uY29yZS5ncmFwaC5Ob2RlTGFiZWw7DQppbXBvcnQgb3JnLmVjbGlwc2Uuc3RlbS5jb3JlLmdyYXBoLmltcGwuRWRnZUltcGw7DQppbXBvcnQgb3JnLmVjbGlwc2Uuc3RlbS5jb3JlLm1vZGVsLk1vZGVsOw0KaW1wb3J0IG9yZy5lY2xpcHNlLnN0ZW0uZGVmaW5pdGlvbnMuYWRhcHRlcnMuc3BhdGlhbC5TcGF0aWFsUHJvdmlkZXJBZGFwdGVyOw0KaW1wb3J0IG9yZy5lY2xpcHNlLnN0ZW0uZGVmaW5pdGlvbnMuYWRhcHRlcnMuc3BhdGlhbC5nZW8uSW5saW5lTGF0TG9uZ0RhdGFQcm92aWRlcjsNCmltcG9ydCBvcmcuZWNsaXBzZS5zdGVtLmRlZmluaXRpb25zLmFkYXB0ZXJzLnNwYXRpYWwuZ2VvLkxhdExvbmc7DQppbXBvcnQgb3JnLmVjbGlwc2Uuc3RlbS5kZWZpbml0aW9ucy5hZGFwdGVycy5zcGF0aWFsLmdlby5MYXRMb25nLlNlZ21lbnQ7DQppbXBvcnQgb3JnLmVjbGlwc2Uuc3RlbS5kZWZpbml0aW9ucy5hZGFwdGVycy5zcGF0aWFsLmdlby5MYXRMb25nLlNlZ21lbnRCdWlsZGVyOw0KaW1wb3J0IG9yZy5lY2xpcHNlLnN0ZW0uZGVmaW5pdGlvbnMuYWRhcHRlcnMuc3BhdGlhbC5nZW8uTGF0TG9uZ1Byb3ZpZGVyOw0KaW1wb3J0IG9yZy5lY2xpcHNlLnN0ZW0uZGVmaW5pdGlvbnMuYWRhcHRlcnMuc3BhdGlhbC5nZW8uTGF0TG9uZ1Byb3ZpZGVyQWRhcHRlckZhY3Rvcnk7DQppbXBvcnQgb3JnLmVjbGlwc2Uuc3RlbS5kZWZpbml0aW9ucy5lZGdlcy5FZGdlc0ZhY3Rvcnk7DQppbXBvcnQgb3JnLmVjbGlwc2Uuc3RlbS5kZWZpbml0aW9ucy5lZGdlcy5FZGdlc1BhY2thZ2U7DQppbXBvcnQgb3JnLmVjbGlwc2Uuc3RlbS5kZWZpbml0aW9ucy5lZGdlcy5NaWdyYXRpb25FZGdlOw0KaW1wb3J0IG9yZy5lY2xpcHNlLnN0ZW0uZGVmaW5pdGlvbnMuZWRnZXMuTWlncmF0aW9uRWRnZUxhYmVsOw0KaW1wb3J0IG9yZy5lY2xpcHNlLnN0ZW0uZGVmaW5pdGlvbnMuZWRnZXMuTWlncmF0aW9uRWRnZUxhYmVsVmFsdWU7DQppbXBvcnQgb3JnLmVjbGlwc2Uuc3RlbS5kZWZpbml0aW9ucy5sYWJlbHMuQXJlYUxhYmVsOw0KaW1wb3J0IG9yZy5lY2xpcHNlLnN0ZW0uZGVmaW5pdGlvbnMubGFiZWxzLkNvbW1vbkJvcmRlclJlbGF0aW9uc2hpcExhYmVsOw0KaW1wb3J0IG9yZy5lY2xpcHNlLnN0ZW0uZGVmaW5pdGlvbnMubGFiZWxzLkNvbW1vbkJvcmRlclJlbGF0aW9uc2hpcExhYmVsVmFsdWU7DQppbXBvcnQgb3JnLmVjbGlwc2Uuc3RlbS5kZWZpbml0aW9ucy5sYWJlbHMuTGFiZWxzRmFjdG9yeTsNCmltcG9ydCBvcmcuZWNsaXBzZS5zdGVtLmRlZmluaXRpb25zLmxhYmVscy5MYWJlbHNQYWNrYWdlOw0KaW1wb3J0IG9yZy5lY2xpcHNlLnN0ZW0uZGVmaW5pdGlvbnMubGFiZWxzLlBvcHVsYXRpb25MYWJlbDsNCmltcG9ydCBvcmcuZWNsaXBzZS5zdGVtLmRlZmluaXRpb25zLmxhYmVscy5SZWxhdGl2ZVBoeXNpY2FsUmVsYXRpb25zaGlwTGFiZWw7DQppbXBvcnQgb3JnLmVjbGlwc2Uuc3RlbS5kZWZpbml0aW9ucy5sYWJlbHMuUm9hZFRyYW5zcG9ydFJlbGF0aW9uc2hpcExhYmVsOw0KaW1wb3J0IG9yZy5lY2xpcHNlLnN0ZW0uZGVmaW5pdGlvbnMubGFiZWxzLlJvYWRUcmFuc3BvcnRSZWxhdGlvbnNoaXBMYWJlbFZhbHVlOw0KaW1wb3J0IG9yZy5lY2xpcHNlLnN0ZW0uZGVmaW5pdGlvbnMubGFiZWxzLmltcGwuUm9hZFRyYW5zcG9ydFJlbGF0aW9uc2hpcExhYmVsSW1wbDsNCmltcG9ydCBvcmcuZWNsaXBzZS5zdGVtLmRlZmluaXRpb25zLm5vZGVzLk5vZGVzRmFjdG9yeTsNCmltcG9ydCBvcmcuZWNsaXBzZS5zdGVtLmRlZmluaXRpb25zLm5vZGVzLlJlZ2lvbjsNCmltcG9ydCBvcmcuZWNsaXBzZS5zdGVtLmRlZmluaXRpb25zLnRyYW5zcG9ydC5QaXBlVHJhbnNwb3J0RWRnZTsNCmltcG9ydCBvcmcuZWNsaXBzZS5zdGVtLmRlZmluaXRpb25zLnRyYW5zcG9ydC5QaXBlVHJhbnNwb3J0RWRnZUxhYmVsOw0KaW1wb3J0IG9yZy5lY2xpcHNlLnN0ZW0uZGVmaW5pdGlvbnMudHJhbnNwb3J0LlBpcGVUcmFuc3BvcnRFZGdlTGFiZWxWYWx1ZTsNCmltcG9ydCBvcmcuZWNsaXBzZS5zdGVtLmRlZmluaXRpb25zLnRyYW5zcG9ydC5UcmFuc3BvcnRGYWN0b3J5Ow0KaW1wb3J0IG9yZy5lY2xpcHNlLnN0ZW0uZGVmaW5pdGlvbnMudHJhbnNwb3J0LlRyYW5zcG9ydFBhY2thZ2U7DQppbXBvcnQgb3JnLmVjbGlwc2Uuc3RlbS5kZWZpbml0aW9ucy50cmFuc3BvcnQuaW1wbC5QaXBlVHJhbnNwb3J0RWRnZUltcGw7DQppbXBvcnQgb3JnLmVjbGlwc2Uuc3RlbS51aS5BY3RpdmF0b3I7DQppbXBvcnQgb3JnLmVjbGlwc2Uuc3RlbS51aS5ncmFwaGVkaXRvci5oYW5kbGVycy5OZXdOb2RlRGlhbG9nOw0KaW1wb3J0IG9yZy5lY2xpcHNlLnN0ZW0udWkuZ3JhcGhlZGl0b3IuaGFuZGxlcnMuU2F2ZUluUHJvamVjdERpYWxvZzsNCmltcG9ydCBvcmcuZWNsaXBzZS5zd3QuU1dUOw0KaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5ldmVudHMuTW91c2VFdmVudDsNCmltcG9ydCBvcmcuZWNsaXBzZS5zd3QuZXZlbnRzLk1vdXNlTGlzdGVuZXI7DQppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmV2ZW50cy5Nb3VzZU1vdmVMaXN0ZW5lcjsNCmltcG9ydCBvcmcuZWNsaXBzZS5zd3QuZXZlbnRzLk1vdXNlV2hlZWxMaXN0ZW5lcjsNCmltcG9ydCBvcmcuZWNsaXBzZS5zd3QuZXZlbnRzLlBhaW50RXZlbnQ7DQppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmV2ZW50cy5QYWludExpc3RlbmVyOw0KaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5ldmVudHMuU2VsZWN0aW9uRXZlbnQ7DQppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmV2ZW50cy5TZWxlY3Rpb25MaXN0ZW5lcjsNCmltcG9ydCBvcmcuZWNsaXBzZS5zd3QuZ3JhcGhpY3MuUG9pbnQ7DQppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LmdyYXBoaWNzLlJlY3RhbmdsZTsNCmltcG9ydCBvcmcuZWNsaXBzZS5zd3QubGF5b3V0LkdyaWREYXRhOw0KaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC5sYXlvdXQuR3JpZExheW91dDsNCmltcG9ydCBvcmcuZWNsaXBzZS5zd3QubGF5b3V0LlJvd0xheW91dDsNCmltcG9ydCBvcmcuZWNsaXBzZS5zd3Qud2lkZ2V0cy5CdXR0b247DQppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LndpZGdldHMuQ29tYm87DQppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LndpZGdldHMuQ29tcG9zaXRlOw0KaW1wb3J0IG9yZy5lY2xpcHNlLnN3dC53aWRnZXRzLkRpc3BsYXk7DQppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LndpZGdldHMuRXZlbnQ7DQppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LndpZGdldHMuR3JvdXA7DQppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LndpZGdldHMuTGFiZWw7DQppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LndpZGdldHMuTGlzdGVuZXI7DQppbXBvcnQgb3JnLmVjbGlwc2Uuc3d0LndpZGdldHMuTWVudTsNCmltcG9ydCBvcmcuZWNsaXBzZS5zd3Qud2lkZ2V0cy5NZW51SXRlbTsNCmltcG9ydCBvcmcuZWNsaXBzZS5zd3Qud2lkZ2V0cy5TaGVsbDsNCmltcG9ydCBvcmcuZWNsaXBzZS56ZXN0LmNvcmUud2lkZ2V0cy5HcmFwaENvbm5lY3Rpb247DQppbXBvcnQgb3JnLmVjbGlwc2UuemVzdC5jb3JlLndpZGdldHMuR3JhcGhJdGVtOw0KaW1wb3J0IG9yZy5lY2xpcHNlLnplc3QuY29yZS53aWRnZXRzLkdyYXBoTm9kZTsNCg0KcHVibGljIGNsYXNzIEdyYXBoQ2FudmFzIHsNCg0KCXByaXZhdGUgZmluYWwgaW50IE5PREVfU0laRSA9IDEwOw0KCXByaXZhdGUgZmluYWwgZG91YmxlIElOSVRJQUxfU0NBTEVfRkFDVE9SID0gMC45NTsNCg0KCXByaXZhdGUgSVByb2plY3QgcHJvamVjdDsNCglwcml2YXRlIExpc3Q8R3JhcGg+IGdyYXBoTGlzdDsNCglwcml2YXRlIExpc3Q8TW9kZWw+IG1vZGVsTGlzdDsNCg0KCXByaXZhdGUgU2hlbGwgc2hlbGw7DQoNCglwcml2YXRlIEdyYXBoIHN0ZW1HcmFwaDsNCglwcml2YXRlIG9yZy5lY2xpcHNlLnplc3QuY29yZS53aWRnZXRzLkdyYXBoIHplc3RHcmFwaDsNCg0KCXByaXZhdGUgZG91YmxlIHNjYWxlWDsNCglwcml2YXRlIGRvdWJsZSBzY2FsZVk7DQoJcHJpdmF0ZSBkb3VibGUgeFRyYW5zbGF0aW9uOw0KCXByaXZhdGUgZG91YmxlIHlUcmFuc2xhdGlvbjsNCg0KCXByaXZhdGUgZG91YmxlIHpvb21GYWN0b3I7DQoJcHJpdmF0ZSBpbnQgbGFzdEN1cnNvclg7DQoJcHJpdmF0ZSBpbnQgbGFzdEN1cnNvclk7DQoJcHJpdmF0ZSBib29sZWFuIG1vdXNlQnV0dG9uUHJlc3NlZDsJDQoNCglwcml2YXRlIE1hcDxVUkksIEdyYXBoTm9kZT4gZ3JhcGhOb2RlczsNCglwcml2YXRlIE1hcDxVUkksIEdyYXBoQ29ubmVjdGlvbj4gZ3JhcGhDb25uZWN0aW9uczsNCglwcml2YXRlIE1hcDxVUkksIFNldDxQb2x5Z29uPj4gZ3JhcGhQb2x5Z29uczsNCg0KCXByaXZhdGUgRHluYW1pY1RleHQgbm9kZVhZX2VkaXQ7DQoJcHJpdmF0ZSBEeW5hbWljVGV4dCBjb29yZGluYXRlX3RyYW5zOw0KCXByaXZhdGUgRHluYW1pY1RleHQgem9vbUVkaXQ7DQoNCglwdWJsaWMgR3JhcGhDYW52YXMoU3RyaW5nIHRpdGxlLCBJUHJvamVjdCBwcm9qZWN0LCBMaXN0PEdyYXBoPiBncmFwaExpc3QsDQoJCQlMaXN0PE1vZGVsPiBtb2RlbExpc3QpIHsNCgkJdGhpcy5wcm9qZWN0ID0gcHJvamVjdDsNCgkJdGhpcy5ncmFwaExpc3QgPSBuZXcgQXJyYXlMaXN0PEdyYXBoPigpOw0KCQl0aGlzLm1vZGVsTGlzdCA9IG1vZGVsTGlzdDsNCgkJc3RlbUdyYXBoID0gbnVsbDsNCgkJem9vbUZhY3RvciA9IDEuMDsNCgkJbW91c2VCdXR0b25QcmVzc2VkID0gZmFsc2U7CQ0KCQlncmFwaE5vZGVzID0gbmV3IEhhc2hNYXA8VVJJLCBHcmFwaE5vZGU+KCk7DQoJCWdyYXBoQ29ubmVjdGlvbnMgPSBuZXcgSGFzaE1hcDxVUkksIEdyYXBoQ29ubmVjdGlvbj4oKTsNCgkJZ3JhcGhQb2x5Z29ucyA9IG5ldyBIYXNoTWFwPFVSSSwgU2V0PFBvbHlnb24+PigpOw0KDQoJCWZvciAoR3JhcGggZ3JhcGggOiBncmFwaExpc3QpIHsNCgkJCXRoaXMuZ3JhcGhMaXN0LmFkZCgoR3JhcGgpIEVjb3JlVXRpbC5jb3B5KGdyYXBoKSk7DQoJCX0NCg0KCQlmb3IgKEdyYXBoIGdyYXBoIDogZ3JhcGhMaXN0KSB7DQoJCQlpZiAoc3RlbUdyYXBoID09IG51bGwpIHsNCgkJCQlzdGVtR3JhcGggPSAoR3JhcGgpIEVjb3JlVXRpbC5jb3B5KGdyYXBoKTsNCgkJCX0gZWxzZSB7DQoJCQkJc3RlbUdyYXBoLmFkZEdyYXBoKChHcmFwaCkgRWNvcmVVdGlsLmNvcHkoZ3JhcGgpLCBudWxsKTsNCgkJCX0NCgkJfQ0KDQoJCWZvciAoTm9kZUxhYmVsIG5vZGVMYWJlbCA6IHN0ZW1HcmFwaC5nZXROb2RlTGFiZWxzKCkudmFsdWVzKCkpIHsNCgkJCU5vZGUgbm9kZSA9IHN0ZW1HcmFwaC5nZXROb2RlKG5vZGVMYWJlbA0KCQkJCQkuZ2V0VVJJT2ZJZGVudGlmaWFibGVUb0JlTGFiZWxlZCgpKTsNCg0KCQkJaWYgKCFub2RlLmdldExhYmVscygpLmNvbnRhaW5zKG5vZGVMYWJlbCkpIHsNCgkJCQlub2RlLmdldExhYmVscygpLmFkZChub2RlTGFiZWwpOw0KCQkJfQ0KCQl9DQoNCgkJY3JlYXRlU2hlbGwodGl0bGUpOw0KDQoJCWZvciAoTm9kZSBub2RlIDogc3RlbUdyYXBoLmdldE5vZGVzKCkudmFsdWVzKCkpIHsNCgkJCXByb2Nlc3NOb2RlKG5vZGUpOw0KCQl9DQoNCgkJZm9yIChFZGdlIGVkZ2UgOiBzdGVtR3JhcGguZ2V0RWRnZXMoKS52YWx1ZXMoKSkgew0KCQkJcHJvY2Vzc0VkZ2UoZWRnZSk7DQoJCX0NCg0KCQlpZiAoZ3JhcGhOb2Rlcy5pc0VtcHR5KCkpIHsNCgkJCXJldHVybjsNCgkJfQ0KDQoJCXNldEluaXRpYWxUcmFuc2Zvcm0oKTsNCgkJcmVkcmF3KCk7DQoJCXNoZWxsLm9wZW4oKTsNCg0KCQl3aGlsZSAoIXNoZWxsLmlzRGlzcG9zZWQoKSkgew0KCQkJd2hpbGUgKCFBY3RpdmF0b3IuZ2V0RGVmYXVsdCgpLmdldFdvcmtiZW5jaCgpLmdldERpc3BsYXkoKQ0KCQkJCQkucmVhZEFuZERpc3BhdGNoKCkpIHsNCgkJCQlBY3RpdmF0b3IuZ2V0RGVmYXVsdCgpLmdldFdvcmtiZW5jaCgpLmdldERpc3BsYXkoKS5zbGVlcCgpOw0KCQkJfQ0KCQl9DQoJfQ0KDQoJcHJpdmF0ZSB2b2lkIGNyZWF0ZVNoZWxsKFN0cmluZyB0aXRsZSkgew0KCQlzaGVsbCA9IG5ldyBTaGVsbChBY3RpdmF0b3IuZ2V0RGVmYXVsdCgpLmdldFdvcmtiZW5jaCgpLmdldERpc3BsYXkoKSk7DQoJCXNoZWxsLnNldFRleHQodGl0bGUpOw0KCQlzaGVsbC5zZXRMYXlvdXQobmV3IEdyaWRMYXlvdXQoMSwgdHJ1ZSkpOw0KDQoJCXplc3RHcmFwaCA9IG5ldyBvcmcuZWNsaXBzZS56ZXN0LmNvcmUud2lkZ2V0cy5HcmFwaChzaGVsbCwgU1dULk5PTkUpOw0KCQl6ZXN0R3JhcGguc2V0TGF5b3V0RGF0YShuZXcgR3JpZERhdGEoU1dULkZJTEwsIFNXVC5GSUxMLCB0cnVlLCB0cnVlKSk7DQoJCXplc3RHcmFwaA0KCQkJCS5zZXRWZXJ0aWNhbFNjcm9sbEJhclZpc2liaWxpdHkob3JnLmVjbGlwc2UuemVzdC5jb3JlLndpZGdldHMuR3JhcGguTkVWRVIpOw0KCQl6ZXN0R3JhcGgNCgkJCQkuc2V0SG9yaXpvbnRhbFNjcm9sbEJhclZpc2liaWxpdHkob3JnLmVjbGlwc2UuemVzdC5jb3JlLndpZGdldHMuR3JhcGguTkVWRVIpOw0KCQl6ZXN0R3JhcGguZ2V0Vmlld3BvcnQoKS5zZXRJZ25vcmVTY3JvbGwodHJ1ZSk7DQoJCXplc3RHcmFwaC5hZGRQYWludExpc3RlbmVyKG5ldyBQYWludExpc3RlbmVyKCkgew0KDQoJCQlwdWJsaWMgdm9pZCBwYWludENvbnRyb2woUGFpbnRFdmVudCBlKSB7DQoJCQkJZS5nYy5zZXRMaW5lV2lkdGgoMCk7DQoJCQkJZS5nYy5zZXRDbGlwcGluZyh6ZXN0R3JhcGguZ2V0Qm91bmRzKCkpOw0KCQkJCWUuZ2Muc2V0Rm9yZWdyb3VuZChDb2xvckNvbnN0YW50cy5saWdodEdyYXkpOw0KDQoJCQkJZm9yIChTZXQ8UG9seWdvbj4gcG9seVNldCA6IGdyYXBoUG9seWdvbnMudmFsdWVzKCkpIHsNCgkJCQkJZm9yIChQb2x5Z29uIGRpc3BsYXlQb2x5Z29uIDogcG9seVNldCkgew0KCQkJCQkJZS5nYy5kcmF3UG9seWdvbihwb2x5Z29uMkludEFycmF5KGRpc3BsYXlQb2x5Z29uKSk7DQoJCQkJCX0NCgkJCQl9DQoJCQl9DQoJCX0pOw0KDQoJCWZvciAoTGlzdGVuZXIgbCA6IHplc3RHcmFwaC5nZXRWZXJ0aWNhbEJhcigpDQoJCQkJLmdldExpc3RlbmVycyhTV1QuU2VsZWN0aW9uKSkgew0KCQkJemVzdEdyYXBoLmdldFZlcnRpY2FsQmFyKCkucmVtb3ZlTGlzdGVuZXIoU1dULlNlbGVjdGlvbiwgbCk7DQoJCQl6ZXN0R3JhcGguZ2V0VmVydGljYWxCYXIoKS5yZW1vdmVMaXN0ZW5lcihTV1QuU2VsZWN0aW9uLCBsKTsNCgkJfQ0KDQoJCWZvciAoTGlzdGVuZXIgbCA6IHplc3RHcmFwaC5nZXRIb3Jpem9udGFsQmFyKCkuZ2V0TGlzdGVuZXJzKA0KCQkJCVNXVC5TZWxlY3Rpb24pKSB7DQoJCQl6ZXN0R3JhcGguZ2V0SG9yaXpvbnRhbEJhcigpLnJlbW92ZUxpc3RlbmVyKFNXVC5TZWxlY3Rpb24sIGwpOw0KCQkJemVzdEdyYXBoLmdldEhvcml6b250YWxCYXIoKS5yZW1vdmVMaXN0ZW5lcihTV1QuU2VsZWN0aW9uLCBsKTsNCgkJfQ0KDQoJCUNvbXBvc2l0ZSBkYXRhQ29tcG9zaXRlID0gbmV3IENvbXBvc2l0ZShzaGVsbCwgU1dULkNFTlRFUik7DQoJCUNvbXBvc2l0ZSBpbmZvQ29tcG9zaXRlID0gY3JlYXRlSW5mb0NvbXBvc2l0ZShkYXRhQ29tcG9zaXRlKTsNCgkJQ29tcG9zaXRlIGJvdHRvbUNvbXBvc2l0ZSA9IGNyZWF0ZUJ1dHRvbnNDb21wb3NpdGUoZGF0YUNvbXBvc2l0ZSk7DQoNCgkJZGF0YUNvbXBvc2l0ZS5zZXRMYXlvdXREYXRhKG5ldyBHcmlkRGF0YShTV1QuRklMTCwgU1dULkZJTEwsIHRydWUsDQoJCQkJZmFsc2UpKTsNCgkJZGF0YUNvbXBvc2l0ZS5zZXRMYXlvdXQobmV3IEdyaWRMYXlvdXQoMSwgdHJ1ZSkpOw0KCQlpbmZvQ29tcG9zaXRlDQoJCQkJLnNldExheW91dERhdGEobmV3IEdyaWREYXRhKFNXVC5GSUxMLCBTV1QuRklMTCwgdHJ1ZSwgdHJ1ZSkpOw0KCQlib3R0b21Db21wb3NpdGUuc2V0TGF5b3V0RGF0YShuZXcgR3JpZERhdGEoU1dULkZJTEwsIFNXVC5GSUxMLCB0cnVlLA0KCQkJCXRydWUpKTsNCg0KCQlhZGRaZXN0R3JhcGhMaXN0ZW5lcnMoKTsNCgkJYWRkWmVzdEdyYXBoQ29udGV4dE1lbnUoKTsNCg0KCQlzaGVsbC5wYWNrKCk7DQoJCXNoZWxsLnNldFNpemUoODAwLCA2MDApOw0KCX0NCg0KCXByaXZhdGUgdm9pZCB1cGRhdGVTaGVsbCgpIHsNCgkJdXBkYXRlU2hlbGwoMCk7DQoJfQ0KDQoJcHJpdmF0ZSB2b2lkIHVwZGF0ZVNoZWxsKGludCBzZWxlY3RlZE5vZGVMYWJlbCkgew0KCQlib29sZWFuIHNob3dOb2RlQ29tcG9zaXRlID0gZmFsc2U7DQoJCWJvb2xlYW4gc2hvd0VkZ2VDb21wb3NpdGUgPSBmYWxzZTsNCg0KCQlpZiAoemVzdEdyYXBoLmdldFNlbGVjdGlvbigpLnNpemUoKSA9PSAxKSB7DQoJCQlpZiAoemVzdEdyYXBoLmdldFNlbGVjdGlvbigpLmdldCgwKSBpbnN0YW5jZW9mIEdyYXBoTm9kZSkgew0KCQkJCXNob3dOb2RlQ29tcG9zaXRlID0gdHJ1ZTsNCgkJCX0gZWxzZSBpZiAoemVzdEdyYXBoLmdldFNlbGVjdGlvbigpLmdldCgwKSBpbnN0YW5jZW9mIEdyYXBoQ29ubmVjdGlvbikgew0KCQkJCXNob3dFZGdlQ29tcG9zaXRlID0gdHJ1ZTsNCgkJCX0NCgkJfQ0KDQoJCXNoZWxsLmdldENoaWxkcmVuKClbMV0uZGlzcG9zZSgpOw0KDQoJCUNvbXBvc2l0ZSBkYXRhQ29tcG9zaXRlID0gbmV3IENvbXBvc2l0ZShzaGVsbCwgU1dULkNFTlRFUik7DQoJCWRhdGFDb21wb3NpdGUuc2V0TGF5b3V0RGF0YShuZXcgR3JpZERhdGEoU1dULkZJTEwsIFNXVC5GSUxMLCB0cnVlLA0KCQkJCWZhbHNlKSk7DQoJCWRhdGFDb21wb3NpdGUuc2V0TGF5b3V0KG5ldyBHcmlkTGF5b3V0KDEsIHRydWUpKTsNCg0KCQlpZiAoc2hvd05vZGVDb21wb3NpdGUpIHsNCgkJCUdyYXBoTm9kZSBzZWxlY3RlZE5vZGUgPSAoR3JhcGhOb2RlKSB6ZXN0R3JhcGguZ2V0U2VsZWN0aW9uKCkNCgkJCQkJLmdldCgwKTsNCgkJCU5vZGVEYXRhIG5vZGVEYXRhID0gKE5vZGVEYXRhKSBzZWxlY3RlZE5vZGUuZ2V0RGF0YSgpOw0KCQkJQ29tcG9zaXRlIHByb3BlcnRpZXNDb21wb3NpdGVfbm9kZXMgPSBjcmVhdGVOb2RlRGF0YUNvbXBvc2l0ZShkYXRhQ29tcG9zaXRlKTsNCg0KCQkJbm9kZURhdGEuc2V0QWN0aXZlTGFiZWwoc2VsZWN0ZWROb2RlTGFiZWwpOw0KCQkJcHJvcGVydGllc0NvbXBvc2l0ZV9ub2Rlcy5zZXRMYXlvdXREYXRhKG5ldyBHcmlkRGF0YShTV1QuRklMTCwNCgkJCQkJU1dULkZJTEwsIHRydWUsIHRydWUpKTsNCg0KCQkJaWYgKCFub2RlRGF0YS5nZXROb2RlTGFiZWxzKCkuaXNFbXB0eSgpKSB7DQoJCQkJQ29tcG9zaXRlIHByb3BlcnRpZXNDb21wb3NpdGVfbGFiZWxzID0gY3JlYXRlTm9kZUxhYmVsQ29tcG9zaXRlKGRhdGFDb21wb3NpdGUpOw0KDQoJCQkJcHJvcGVydGllc0NvbXBvc2l0ZV9sYWJlbHMuc2V0TGF5b3V0RGF0YShuZXcgR3JpZERhdGEoU1dULkZJTEwsDQoJCQkJCQlTV1QuRklMTCwgdHJ1ZSwgdHJ1ZSkpOw0KCQkJfQ0KCQl9DQoNCgkJaWYgKHNob3dFZGdlQ29tcG9zaXRlKSB7DQoJCQlDb21wb3NpdGUgcHJvcGVydGllc0NvbXBvc2l0ZV9lZGdlcyA9IGNyZWF0ZUVkZ2VDb21wb3NpdGUoZGF0YUNvbXBvc2l0ZSk7DQoJCQlDb21wb3NpdGUgZWRnZUxhYmVsQ29tcG9zaXRlID0gY3JlYXRlRWRnZUxhYmVsQ29tcG9zaXRlKGRhdGFDb21wb3NpdGUpOw0KDQoJCQlwcm9wZXJ0aWVzQ29tcG9zaXRlX2VkZ2VzLnNldExheW91dERhdGEobmV3IEdyaWREYXRhKFNXVC5GSUxMLA0KCQkJCQlTV1QuRklMTCwgdHJ1ZSwgdHJ1ZSkpOw0KCQkJZWRnZUxhYmVsQ29tcG9zaXRlLnNldExheW91dERhdGEobmV3IEdyaWREYXRhKFNXVC5GSUxMLCBTV1QuRklMTCwNCgkJCQkJdHJ1ZSwgdHJ1ZSkpOw0KCQl9DQoNCgkJQ29tcG9zaXRlIGluZm9Db21wb3NpdGUgPSBjcmVhdGVJbmZvQ29tcG9zaXRlKGRhdGFDb21wb3NpdGUpOw0KCQlDb21wb3NpdGUgYm90dG9tQ29tcG9zaXRlID0gY3JlYXRlQnV0dG9uc0NvbXBvc2l0ZShkYXRhQ29tcG9zaXRlKTsNCg0KCQlpbmZvQ29tcG9zaXRlDQoJCQkJLnNldExheW91dERhdGEobmV3IEdyaWREYXRhKFNXVC5GSUxMLCBTV1QuRklMTCwgdHJ1ZSwgdHJ1ZSkpOw0KCQlib3R0b21Db21wb3NpdGUuc2V0TGF5b3V0RGF0YShuZXcgR3JpZERhdGEoU1dULkZJTEwsIFNXVC5GSUxMLCB0cnVlLA0KCQkJCXRydWUpKTsNCgkJYWRkWmVzdEdyYXBoQ29udGV4dE1lbnUoKTsNCgkJc2hlbGwubGF5b3V0KHRydWUpOw0KDQoJCWlmIChzaG93Tm9kZUNvbXBvc2l0ZSB8fCBzaG93RWRnZUNvbXBvc2l0ZSkgew0KCQkJY2hlY2tTZWxlY3Rpb25WaXNpYmxlKCk7DQoJCX0NCgl9DQoNCglwcml2YXRlIENvbXBvc2l0ZSBjcmVhdGVOb2RlRGF0YUNvbXBvc2l0ZShDb21wb3NpdGUgcGFyZW50KSB7DQoJCUdyYXBoTm9kZSBzZWxlY3RlZE5vZGUgPSAoR3JhcGhOb2RlKSB6ZXN0R3JhcGguZ2V0U2VsZWN0aW9uKCkuZ2V0KDApOw0KCQlOb2RlRGF0YSBub2RlRGF0YSA9IChOb2RlRGF0YSkgc2VsZWN0ZWROb2RlLmdldERhdGEoKTsNCgkJR3JvdXAgcHJvcGVydGllc0NvbXBvc2l0ZV9ub2RlcyA9IG5ldyBHcm91cChwYXJlbnQsIFNXVC5DRU5URVIpOw0KDQoJCXByb3BlcnRpZXNDb21wb3NpdGVfbm9kZXMNCgkJCQkuc2V0VGV4dChHcmFwaEVkaXRvck1lc3NhZ2VzLmdldFN0cmluZygibm9kZSIpKTsNCgkJcHJvcGVydGllc0NvbXBvc2l0ZV9ub2Rlcy5zZXRMYXlvdXQobmV3IFJvd0xheW91dChTV1QuSE9SSVpPTlRBTCkpOw0KDQoJCUxhYmVsIG5vZGVUaXRsZSA9IG5ldyBMYWJlbChwcm9wZXJ0aWVzQ29tcG9zaXRlX25vZGVzLCBTV1QuTk9ORSk7DQoJCW5vZGVUaXRsZS5zZXRUZXh0KEdyYXBoRWRpdG9yTWVzc2FnZXMuZ2V0U3RyaW5nKCJ0aXRsZSIpICsgIjoiKTsNCgkJRHluYW1pY1RleHQgbm9kZVRpdGxlX2VkaXQgPSBuZXcgRHluYW1pY1RleHQocHJvcGVydGllc0NvbXBvc2l0ZV9ub2RlcywNCgkJCQl0cnVlKTsNCgkJbm9kZVRpdGxlX2VkaXQuc2V0VGV4dChub2RlRGF0YS5nZXROb2RlVGl0bGUoKSk7DQoJCW5vZGVUaXRsZV9lZGl0LmFkZE1vZGlmeUxpc3RlbmVyKG5ldyBUZXh0QW5kQnV0dG9uTW9kaWZ5TGlzdGVuZXIoDQoJCQkJemVzdEdyYXBoLCBUZXh0QW5kQnV0dG9uTW9kaWZ5TGlzdGVuZXIuTk9ERV9USVRMRSkpOw0KDQoJCUxhYmVsIG5vZGVVUkkgPSBuZXcgTGFiZWwocHJvcGVydGllc0NvbXBvc2l0ZV9ub2RlcywgU1dULk5PTkUpOw0KCQlub2RlVVJJLnNldFRleHQoR3JhcGhFZGl0b3JNZXNzYWdlcy5nZXRTdHJpbmcoInVyaSIpICsgIjoiKTsNCgkJRHluYW1pY1RleHQgbm9kZVVSSV9lZGl0ID0gbmV3IER5bmFtaWNUZXh0KHByb3BlcnRpZXNDb21wb3NpdGVfbm9kZXMsDQoJCQkJZmFsc2UpOw0KCQlub2RlVVJJX2VkaXQuc2V0VGV4dChub2RlRGF0YS5nZXROb2RlVVJJKCkudG9TdHJpbmcoKSk7DQoNCgkJTGFiZWwgbm9kZVhZID0gbmV3IExhYmVsKHByb3BlcnRpZXNDb21wb3NpdGVfbm9kZXMsIFNXVC5OT05FKTsNCgkJbm9kZVhZLnNldFRleHQoR3JhcGhFZGl0b3JNZXNzYWdlcy5nZXRTdHJpbmcoImNvb3JkaW5hdGVzIikgKyAiOiIpOw0KCQlub2RlWFlfZWRpdCA9IG5ldyBEeW5hbWljVGV4dChwcm9wZXJ0aWVzQ29tcG9zaXRlX25vZGVzLCBmYWxzZSk7DQoJCW5vZGVYWV9lZGl0LnNldFRleHQoZm9ybWF0TGF0TG9uKG5vZGVEYXRhLmdldE9yaWdZKCksDQoJCQkJbm9kZURhdGEuZ2V0T3JpZ1goKSkpOw0KDQoJCXJldHVybiBwcm9wZXJ0aWVzQ29tcG9zaXRlX25vZGVzOw0KCX0NCg0KCXByaXZhdGUgQ29tcG9zaXRlIGNyZWF0ZU5vZGVMYWJlbENvbXBvc2l0ZShDb21wb3NpdGUgcGFyZW50KSB7DQoJCUdyYXBoTm9kZSBzZWxlY3RlZE5vZGUgPSAoR3JhcGhOb2RlKSB6ZXN0R3JhcGguZ2V0U2VsZWN0aW9uKCkuZ2V0KDApOw0KCQlOb2RlRGF0YSBub2RlRGF0YSA9IChOb2RlRGF0YSkgc2VsZWN0ZWROb2RlLmdldERhdGEoKTsNCgkJTGlzdDxOb2RlTGFiZWw+IG5vZGVMYWJlbHMgPSBub2RlRGF0YS5nZXROb2RlTGFiZWxzKCk7DQoJCU5vZGVMYWJlbCBub2RlTGFiZWwgPSBub2RlTGFiZWxzLmdldChub2RlRGF0YS5nZXRBY3RpdmVMYWJlbCgpKTsNCgkJR3JvdXAgbm9kZUxhYmVsQ29tcG9zaXRlID0gbmV3IEdyb3VwKHBhcmVudCwgU1dULkNFTlRFUik7DQoNCgkJbm9kZUxhYmVsQ29tcG9zaXRlLnNldFRleHQoR3JhcGhFZGl0b3JNZXNzYWdlcy5nZXRTdHJpbmcoIm5vZGVMYWJlbCIpKTsNCgkJbm9kZUxhYmVsQ29tcG9zaXRlLnNldExheW91dChuZXcgUm93TGF5b3V0KFNXVC5IT1JJWk9OVEFMKSk7DQoNCgkJTGFiZWwgbm9kZUxhYmVsVHlwZSA9IG5ldyBMYWJlbChub2RlTGFiZWxDb21wb3NpdGUsIFNXVC5OT05FKTsNCgkJbm9kZUxhYmVsVHlwZS5zZXRUZXh0KEdyYXBoRWRpdG9yTWVzc2FnZXMuZ2V0U3RyaW5nKCJsYWJlbFR5cGUiKSArICI6Iik7DQoJCUNvbWJvIG5vZGVMYWJlbFR5cGVfZWRpdCA9IG5ldyBDb21ibyhub2RlTGFiZWxDb21wb3NpdGUsIFNXVC5SRUFEX09OTFkpOw0KCQlub2RlTGFiZWxUeXBlX2VkaXQuYWRkU2VsZWN0aW9uTGlzdGVuZXIobmV3IFNlbGVjdGlvbkxpc3RlbmVyKCkgew0KDQoJCQlwdWJsaWMgdm9pZCB3aWRnZXRTZWxlY3RlZChTZWxlY3Rpb25FdmVudCBlKSB7DQoJCQkJdXBkYXRlU2hlbGwoKChDb21ibykgZS5nZXRTb3VyY2UoKSkuZ2V0U2VsZWN0aW9uSW5kZXgoKSk7DQoJCQl9DQoNCgkJCXB1YmxpYyB2b2lkIHdpZGdldERlZmF1bHRTZWxlY3RlZChTZWxlY3Rpb25FdmVudCBlKSB7DQoJCQl9DQoJCX0pOw0KDQoJCWZvciAoTm9kZUxhYmVsIGxhYmVsIDogbm9kZUxhYmVscykgew0KCQkJaWYgKGxhYmVsIGluc3RhbmNlb2YgQXJlYUxhYmVsKSB7DQoJCQkJbm9kZUxhYmVsVHlwZV9lZGl0LmFkZChHcmFwaEVkaXRvck1lc3NhZ2VzDQoJCQkJCQkuZ2V0U3RyaW5nKCJhcmVhTGFiZWwiKSk7DQoJCQl9IGVsc2UgaWYgKGxhYmVsIGluc3RhbmNlb2YgUG9wdWxhdGlvbkxhYmVsKSB7DQoJCQkJbm9kZUxhYmVsVHlwZV9lZGl0LmFkZChHcmFwaEVkaXRvck1lc3NhZ2VzDQoJCQkJCQkuZ2V0U3RyaW5nKCJwb3B1bGF0aW9uTGFiZWwiKSk7DQoJCQl9DQoJCX0NCg0KCQlub2RlTGFiZWxUeXBlX2VkaXQuc2VsZWN0KG5vZGVEYXRhLmdldEFjdGl2ZUxhYmVsKCkpOw0KDQoJCWlmIChub2RlTGFiZWwgaW5zdGFuY2VvZiBBcmVhTGFiZWwpIHsNCgkJCUFyZWFMYWJlbCBhcmVhTGFiZWwgPSAoQXJlYUxhYmVsKSBub2RlTGFiZWw7DQoNCgkJCUxhYmVsIGxhYmVsQXJlYSA9IG5ldyBMYWJlbChub2RlTGFiZWxDb21wb3NpdGUsIFNXVC5OT05FKTsNCgkJCWxhYmVsQXJlYS5zZXRUZXh0KEdyYXBoRWRpdG9yTWVzc2FnZXMuZ2V0U3RyaW5nKCJhcmVhS00iKSArICI6Iik7DQoJCQlEeW5hbWljVGV4dCBsYWJlbEFyZWFFZGl0ID0gbmV3IER5bmFtaWNUZXh0KG5vZGVMYWJlbENvbXBvc2l0ZSwNCgkJCQkJdHJ1ZSk7DQoJCQlsYWJlbEFyZWFFZGl0LnNldFRleHQoIiINCgkJCQkJKyBhcmVhTGFiZWwuZ2V0Q3VycmVudEFyZWFWYWx1ZSgpLmdldEFyZWEoKSk7DQoJCQlsYWJlbEFyZWFFZGl0LmFkZE1vZGlmeUxpc3RlbmVyKG5ldyBUZXh0QW5kQnV0dG9uTW9kaWZ5TGlzdGVuZXIoDQoJCQkJCXplc3RHcmFwaCwgVGV4dEFuZEJ1dHRvbk1vZGlmeUxpc3RlbmVyLkFSRUFfTEFCRUxfVkFMVUUpKTsNCgkJfSBlbHNlIGlmIChub2RlTGFiZWwgaW5zdGFuY2VvZiBQb3B1bGF0aW9uTGFiZWwpIHsNCgkJCVBvcHVsYXRpb25MYWJlbCBwb3B1bGF0aW9uTGFiZWwgPSAoUG9wdWxhdGlvbkxhYmVsKSBub2RlTGFiZWw7DQoNCgkJCUxhYmVsIGxhYmVsUG9wdWxhdGlvbiA9IG5ldyBMYWJlbChub2RlTGFiZWxDb21wb3NpdGUsIFNXVC5OT05FKTsNCgkJCWxhYmVsUG9wdWxhdGlvbi5zZXRUZXh0KEdyYXBoRWRpdG9yTWVzc2FnZXMuZ2V0U3RyaW5nKCJwb3B1bGF0aW9uIikNCgkJCQkJKyAiOiIpOw0KCQkJRHluYW1pY1RleHQgbGFiZWxQb3B1bGF0aW9uRWRpdCA9IG5ldyBEeW5hbWljVGV4dCgNCgkJCQkJbm9kZUxhYmVsQ29tcG9zaXRlLCB0cnVlKTsNCgkJCWxhYmVsUG9wdWxhdGlvbkVkaXQuc2V0VGV4dChwb3B1bGF0aW9uTGFiZWwNCgkJCQkJLmdldFBvcHVsYXRpb25JZGVudGlmaWVyKCkpOw0KCQkJbGFiZWxQb3B1bGF0aW9uRWRpdA0KCQkJCQkuYWRkTW9kaWZ5TGlzdGVuZXIobmV3IFRleHRBbmRCdXR0b25Nb2RpZnlMaXN0ZW5lcigNCgkJCQkJCQl6ZXN0R3JhcGgsDQoJCQkJCQkJVGV4dEFuZEJ1dHRvbk1vZGlmeUxpc3RlbmVyLlBPUFVMQVRJT05fTEFCRUxfUE9QVUxBVElPTikpOw0KDQoJCQlMYWJlbCBsYWJlbFBvcHVsYXRpb25Db3VudCA9IG5ldyBMYWJlbChub2RlTGFiZWxDb21wb3NpdGUsIFNXVC5OT05FKTsNCgkJCWxhYmVsUG9wdWxhdGlvbkNvdW50LnNldFRleHQoR3JhcGhFZGl0b3JNZXNzYWdlcw0KCQkJCQkuZ2V0U3RyaW5nKCJwb3B1bGF0aW9uQ291bnQiKSArICI6Iik7DQoJCQlEeW5hbWljVGV4dCBsYWJlbFBvcHVsYXRpb25Db3VudEVkaXQgPSBuZXcgRHluYW1pY1RleHQoDQoJCQkJCW5vZGVMYWJlbENvbXBvc2l0ZSwgdHJ1ZSk7DQoJCQlsYWJlbFBvcHVsYXRpb25Db3VudEVkaXQuc2V0VGV4dCgiIg0KCQkJCQkrIHBvcHVsYXRpb25MYWJlbC5nZXRDdXJyZW50UG9wdWxhdGlvblZhbHVlKCkuZ2V0Q291bnQoKSk7DQoJCQlsYWJlbFBvcHVsYXRpb25Db3VudEVkaXQNCgkJCQkJLmFkZE1vZGlmeUxpc3RlbmVyKG5ldyBUZXh0QW5kQnV0dG9uTW9kaWZ5TGlzdGVuZXIoDQoJCQkJCQkJemVzdEdyYXBoLA0KCQkJCQkJCVRleHRBbmRCdXR0b25Nb2RpZnlMaXN0ZW5lci5QT1BVTEFUSU9OX0xBQkVMX0NPVU5UKSk7DQoNCgkJCUxhYmVsIGxhYmVsUG9wdWxhdGVkQXJlYSA9IG5ldyBMYWJlbChub2RlTGFiZWxDb21wb3NpdGUsIFNXVC5OT05FKTsNCgkJCWxhYmVsUG9wdWxhdGVkQXJlYS5zZXRUZXh0KEdyYXBoRWRpdG9yTWVzc2FnZXMNCgkJCQkJLmdldFN0cmluZygicG9wdWxhdGVkQXJlYSIpICsgIjoiKTsNCgkJCUR5bmFtaWNUZXh0IGxhYmVsUG9wdWxhdGVkQXJlYUVkaXQgPSBuZXcgRHluYW1pY1RleHQoDQoJCQkJCW5vZGVMYWJlbENvbXBvc2l0ZSwgdHJ1ZSk7DQoJCQlsYWJlbFBvcHVsYXRlZEFyZWFFZGl0LnNldFRleHQoIiINCgkJCQkJKyBwb3B1bGF0aW9uTGFiZWwuZ2V0UG9wdWxhdGVkQXJlYSgpKTsNCgkJCWxhYmVsUG9wdWxhdGVkQXJlYUVkaXQNCgkJCQkJLmFkZE1vZGlmeUxpc3RlbmVyKG5ldyBUZXh0QW5kQnV0dG9uTW9kaWZ5TGlzdGVuZXIoDQoJCQkJCQkJemVzdEdyYXBoLA0KCQkJCQkJCVRleHRBbmRCdXR0b25Nb2RpZnlMaXN0ZW5lci5QT1BVTEFUSU9OX0xBQkVMX0FSRUEpKTsNCgkJfQ0KDQoJCXJldHVybiBub2RlTGFiZWxDb21wb3NpdGU7DQoJfQ0KDQoJcHJpdmF0ZSBDb21wb3NpdGUgY3JlYXRlRWRnZUNvbXBvc2l0ZShDb21wb3NpdGUgcGFyZW50KSB7DQoJCUdyYXBoQ29ubmVjdGlvbiBzZWxlY3RlZEVkZ2UgPSAoR3JhcGhDb25uZWN0aW9uKSB6ZXN0R3JhcGgNCgkJCQkuZ2V0U2VsZWN0aW9uKCkuZ2V0KDApOw0KCQlDb25uZWN0aW9uRGF0YSBlZGdlRGF0YSA9IChDb25uZWN0aW9uRGF0YSkgc2VsZWN0ZWRFZGdlLmdldERhdGEoKTsNCgkJR3JvdXAgcHJvcGVydGllc0NvbXBvc2l0ZV9lZGdlcyA9IG5ldyBHcm91cChwYXJlbnQsIFNXVC5DRU5URVIpOw0KDQoJCXByb3BlcnRpZXNDb21wb3NpdGVfZWRnZXMNCgkJCQkuc2V0VGV4dChHcmFwaEVkaXRvck1lc3NhZ2VzLmdldFN0cmluZygiZWRnZSIpKTsNCgkJcHJvcGVydGllc0NvbXBvc2l0ZV9lZGdlcy5zZXRMYXlvdXQobmV3IFJvd0xheW91dChTV1QuSE9SSVpPTlRBTCkpOw0KDQoJCUxhYmVsIGVkZ2VUaXRsZSA9IG5ldyBMYWJlbChwcm9wZXJ0aWVzQ29tcG9zaXRlX2VkZ2VzLCBTV1QuTk9ORSk7DQoJCWVkZ2VUaXRsZS5zZXRUZXh0KEdyYXBoRWRpdG9yTWVzc2FnZXMuZ2V0U3RyaW5nKCJ0aXRsZSIpICsgIjoiKTsNCgkJRHluYW1pY1RleHQgZWRnZVRpdGxlX2VkaXQgPSBuZXcgRHluYW1pY1RleHQocHJvcGVydGllc0NvbXBvc2l0ZV9lZGdlcywNCgkJCQl0cnVlKTsNCgkJZWRnZVRpdGxlX2VkaXQuc2V0VGV4dChlZGdlRGF0YS5nZXRFZGdlVGl0bGUoKSk7DQoJCWVkZ2VUaXRsZV9lZGl0LmFkZE1vZGlmeUxpc3RlbmVyKG5ldyBUZXh0QW5kQnV0dG9uTW9kaWZ5TGlzdGVuZXIoDQoJCQkJemVzdEdyYXBoLCBUZXh0QW5kQnV0dG9uTW9kaWZ5TGlzdGVuZXIuRURHRV9USVRMRSkpOw0KDQoJCUxhYmVsIG5vZGVBVVJJID0gbmV3IExhYmVsKHByb3BlcnRpZXNDb21wb3NpdGVfZWRnZXMsIFNXVC5OT05FKTsNCgkJbm9kZUFVUkkuc2V0VGV4dChHcmFwaEVkaXRvck1lc3NhZ2VzLmdldFN0cmluZygibm9kZUEiKSArICI6Iik7DQoJCUR5bmFtaWNUZXh0IG5vZGVBVVJJX2VkaXQgPSBuZXcgRHluYW1pY1RleHQocHJvcGVydGllc0NvbXBvc2l0ZV9lZGdlcywNCgkJCQlmYWxzZSk7DQoJCW5vZGVBVVJJX2VkaXQuc2V0VGV4dChlZGdlRGF0YS5nZXROb2RlQVVSSSgpLmxhc3RTZWdtZW50KCkpOw0KDQoJCUxhYmVsIG5vZGVCVVJJID0gbmV3IExhYmVsKHByb3BlcnRpZXNDb21wb3NpdGVfZWRnZXMsIFNXVC5OT05FKTsNCgkJbm9kZUJVUkkuc2V0VGV4dChHcmFwaEVkaXRvck1lc3NhZ2VzLmdldFN0cmluZygibm9kZUIiKSArICI6Iik7DQoJCUR5bmFtaWNUZXh0IG5vZGVCVVJJX2VkaXQgPSBuZXcgRHluYW1pY1RleHQocHJvcGVydGllc0NvbXBvc2l0ZV9lZGdlcywNCgkJCQlmYWxzZSk7DQoJCW5vZGVCVVJJX2VkaXQuc2V0VGV4dChlZGdlRGF0YS5nZXROb2RlQlVSSSgpLmxhc3RTZWdtZW50KCkpOw0KDQoJCXJldHVybiBwcm9wZXJ0aWVzQ29tcG9zaXRlX2VkZ2VzOw0KCX0NCg0KCXByaXZhdGUgQ29tcG9zaXRlIGNyZWF0ZUVkZ2VMYWJlbENvbXBvc2l0ZShDb21wb3NpdGUgcGFyZW50KSB7DQoJCUdyYXBoQ29ubmVjdGlvbiBzZWxlY3RlZEVkZ2UgPSAoR3JhcGhDb25uZWN0aW9uKSB6ZXN0R3JhcGgNCgkJCQkuZ2V0U2VsZWN0aW9uKCkuZ2V0KDApOw0KCQlDb25uZWN0aW9uRGF0YSBlZGdlRGF0YSA9IChDb25uZWN0aW9uRGF0YSkgc2VsZWN0ZWRFZGdlLmdldERhdGEoKTsNCgkJRWRnZUxhYmVsIGVkZ2VMYWJlbCA9IGVkZ2VEYXRhLmdldEVkZ2VMYWJlbCgpOw0KCQlHcm91cCBlZGdlTGFiZWxDb21wb3NpdGUgPSBuZXcgR3JvdXAocGFyZW50LCBTV1QuQ0VOVEVSKTsNCg0KCQllZGdlTGFiZWxDb21wb3NpdGUuc2V0VGV4dChHcmFwaEVkaXRvck1lc3NhZ2VzLmdldFN0cmluZygiZWRnZUxhYmVsIikpOw0KCQllZGdlTGFiZWxDb21wb3NpdGUuc2V0TGF5b3V0KG5ldyBSb3dMYXlvdXQoU1dULkhPUklaT05UQUwpKTsNCg0KCQlpZiAoZWRnZUxhYmVsIGluc3RhbmNlb2YgTWlncmF0aW9uRWRnZUxhYmVsKSB7DQoJCQlMYWJlbCBlZGdlTGFiZWxUeXBlID0gbmV3IExhYmVsKGVkZ2VMYWJlbENvbXBvc2l0ZSwgU1dULk5PTkUpOw0KCQkJZWRnZUxhYmVsVHlwZS5zZXRUZXh0KEdyYXBoRWRpdG9yTWVzc2FnZXMuZ2V0U3RyaW5nKCJlZGdlVHlwZSIpDQoJCQkJCSsgIjoiKTsNCgkJCUR5bmFtaWNUZXh0IGVkZ2VMYWJlbFR5cGVfZWRpdCA9IG5ldyBEeW5hbWljVGV4dCgNCgkJCQkJZWRnZUxhYmVsQ29tcG9zaXRlLCB0cnVlKTsNCgkJCWVkZ2VMYWJlbFR5cGVfZWRpdC5zZXRUZXh0KEdyYXBoRWRpdG9yTWVzc2FnZXMNCgkJCQkJLmdldFN0cmluZygibWlncmF0aW9uRWRnZSIpKTsNCgkJCWVkZ2VMYWJlbFR5cGVfZWRpdC5zZXRFZGl0YWJsZShmYWxzZSk7DQoJCQllZGdlTGFiZWxUeXBlX2VkaXQuc2V0QmFja2dyb3VuZChDb2xvckNvbnN0YW50cy53aGl0ZSk7DQoNCgkJCUxhYmVsIGVkZ2VMYWJlbFZhbHVlID0gbmV3IExhYmVsKGVkZ2VMYWJlbENvbXBvc2l0ZSwgU1dULk5PTkUpOw0KCQkJZWRnZUxhYmVsVmFsdWUuc2V0VGV4dChHcmFwaEVkaXRvck1lc3NhZ2VzDQoJCQkJCS5nZXRTdHJpbmcoIm1pZ3JhdGlvblJhdGUiKSArICI6Iik7DQoJCQlEeW5hbWljVGV4dCBlZGdlTGFiZWxWYWx1ZV9lZGl0ID0gbmV3IER5bmFtaWNUZXh0KA0KCQkJCQllZGdlTGFiZWxDb21wb3NpdGUsIHRydWUpOw0KCQkJZWRnZUxhYmVsVmFsdWVfZWRpdC5zZXRUZXh0KCIiICsgZWRnZURhdGEuZ2V0TWlncmF0aW9uUmF0ZSgpKTsNCgkJCWVkZ2VMYWJlbFZhbHVlX2VkaXQNCgkJCQkJLmFkZE1vZGlmeUxpc3RlbmVyKG5ldyBUZXh0QW5kQnV0dG9uTW9kaWZ5TGlzdGVuZXIoDQoJCQkJCQkJemVzdEdyYXBoLA0KCQkJCQkJCVRleHRBbmRCdXR0b25Nb2RpZnlMaXN0ZW5lci5NSUdSQVRJT05fTEFCRUxfUkFURSkpOw0KDQoJCQlMYWJlbCBlZGdlTGFiZWxQZXJpb2QgPSBuZXcgTGFiZWwoZWRnZUxhYmVsQ29tcG9zaXRlLCBTV1QuTk9ORSk7DQoJCQllZGdlTGFiZWxQZXJpb2Quc2V0VGV4dChHcmFwaEVkaXRvck1lc3NhZ2VzLmdldFN0cmluZygicGVyaW9kIikNCgkJCQkJKyAiOiIpOw0KCQkJRHluYW1pY1RleHQgZWRnZUxhYmVsUGVyaW9kX2VkaXQgPSBuZXcgRHluYW1pY1RleHQoDQoJCQkJCWVkZ2VMYWJlbENvbXBvc2l0ZSwgdHJ1ZSk7DQoJCQllZGdlTGFiZWxQZXJpb2RfZWRpdC5zZXRUZXh0KCIiICsgZWRnZURhdGEuZ2V0TWlncmF0aW9uUGVyaW9kKCkpOw0KCQkJZWRnZUxhYmVsUGVyaW9kX2VkaXQNCgkJCQkJLmFkZE1vZGlmeUxpc3RlbmVyKG5ldyBUZXh0QW5kQnV0dG9uTW9kaWZ5TGlzdGVuZXIoDQoJCQkJCQkJemVzdEdyYXBoLA0KCQkJCQkJCVRleHRBbmRCdXR0b25Nb2RpZnlMaXN0ZW5lci5NSUdSQVRJT05fTEFCRUxfUEVSSU9EKSk7DQoNCgkJCUxhYmVsIGVkZ2VQb3AgPSBuZXcgTGFiZWwoZWRnZUxhYmVsQ29tcG9zaXRlLCBTV1QuTk9ORSk7DQoJCQllZGdlUG9wLnNldFRleHQoR3JhcGhFZGl0b3JNZXNzYWdlcy5nZXRTdHJpbmcoInBvcHVsYXRpb24iKSArICI6Iik7DQoJCQlEeW5hbWljVGV4dCBlZGdlUG9wX2VkaXQgPSBuZXcgRHluYW1pY1RleHQoZWRnZUxhYmVsQ29tcG9zaXRlLCB0cnVlKTsNCgkJCWVkZ2VQb3BfZWRpdC5zZXRUZXh0KGVkZ2VEYXRhLmdldE1pZ3JhdGlvblBvcHVsYXRpb24oKSk7DQoJCQllZGdlUG9wX2VkaXQuYWRkTW9kaWZ5TGlzdGVuZXIobmV3IFRleHRBbmRCdXR0b25Nb2RpZnlMaXN0ZW5lcigNCgkJCQkJemVzdEdyYXBoLA0KCQkJCQlUZXh0QW5kQnV0dG9uTW9kaWZ5TGlzdGVuZXIuTUlHUkFUSU9OX0xBQkVMX1BPUFVMQVRJT04pKTsNCg0KCQkJQnV0dG9uIGVkZ2VBYnNvbHV0ZV9lZGl0ID0gbmV3IEJ1dHRvbihlZGdlTGFiZWxDb21wb3NpdGUsIFNXVC5DSEVDSyk7DQoJCQllZGdlQWJzb2x1dGVfZWRpdC5zZXRUZXh0KEdyYXBoRWRpdG9yTWVzc2FnZXMNCgkJCQkJLmdldFN0cmluZygibWlncmF0aW9uQWJzb2x1dGUiKSk7DQoJCQllZGdlQWJzb2x1dGVfZWRpdC5zZXRTZWxlY3Rpb24oZWRnZURhdGEuZ2V0TWlncmF0aW9uQWJzb2x1dGUoKSk7DQoJCQllZGdlQWJzb2x1dGVfZWRpdA0KCQkJCQkuYWRkU2VsZWN0aW9uTGlzdGVuZXIobmV3IFRleHRBbmRCdXR0b25Nb2RpZnlMaXN0ZW5lcigNCgkJCQkJCQl6ZXN0R3JhcGgsDQoJCQkJCQkJVGV4dEFuZEJ1dHRvbk1vZGlmeUxpc3RlbmVyLk1JR1JBVElPTl9MQUJFTF9BQlNPTFVURSkpOw0KCQl9IGVsc2UgaWYgKGVkZ2VMYWJlbCBpbnN0YW5jZW9mIENvbW1vbkJvcmRlclJlbGF0aW9uc2hpcExhYmVsKSB7DQoJCQlMYWJlbCBlZGdlTGFiZWxUeXBlID0gbmV3IExhYmVsKGVkZ2VMYWJlbENvbXBvc2l0ZSwgU1dULk5PTkUpOw0KCQkJZWRnZUxhYmVsVHlwZS5zZXRUZXh0KEdyYXBoRWRpdG9yTWVzc2FnZXMuZ2V0U3RyaW5nKCJlZGdlVHlwZSIpDQoJCQkJCSsgIjoiKTsNCgkJCUR5bmFtaWNUZXh0IGVkZ2VMYWJlbFR5cGVfZWRpdCA9IG5ldyBEeW5hbWljVGV4dCgNCgkJCQkJZWRnZUxhYmVsQ29tcG9zaXRlLCBmYWxzZSk7DQoJCQllZGdlTGFiZWxUeXBlX2VkaXQuc2V0VGV4dChHcmFwaEVkaXRvck1lc3NhZ2VzDQoJCQkJCS5nZXRTdHJpbmcoImNvbW1vbkJvcmRlckVkZ2UiKSk7DQoNCgkJCUxhYmVsIGVkZ2VMYWJlbFZhbHVlID0gbmV3IExhYmVsKGVkZ2VMYWJlbENvbXBvc2l0ZSwgU1dULk5PTkUpOw0KCQkJZWRnZUxhYmVsVmFsdWUuc2V0VGV4dChHcmFwaEVkaXRvck1lc3NhZ2VzDQoJCQkJCS5nZXRTdHJpbmcoImJvcmRlckxlbmd0aCIpICsgIjoiKTsNCgkJCUR5bmFtaWNUZXh0IGVkZ2VMYWJlbFZhbHVlX2VkaXQgPSBuZXcgRHluYW1pY1RleHQoDQoJCQkJCWVkZ2VMYWJlbENvbXBvc2l0ZSwgdHJ1ZSk7DQoJCQllZGdlTGFiZWxWYWx1ZV9lZGl0LnNldFRleHQoIiIgKyBlZGdlRGF0YS5nZXRDb21tb25Cb3JkZXJMZW5ndGgoKSk7DQoJCQllZGdlTGFiZWxWYWx1ZV9lZGl0DQoJCQkJCS5hZGRNb2RpZnlMaXN0ZW5lcihuZXcgVGV4dEFuZEJ1dHRvbk1vZGlmeUxpc3RlbmVyKA0KCQkJCQkJCXplc3RHcmFwaCwNCgkJCQkJCQlUZXh0QW5kQnV0dG9uTW9kaWZ5TGlzdGVuZXIuQ09NTU9OX0JPUkRFUl9MQUJFTF9MRU5HVEgpKTsNCgkJfSBlbHNlIGlmIChlZGdlTGFiZWwgaW5zdGFuY2VvZiBSb2FkVHJhbnNwb3J0UmVsYXRpb25zaGlwTGFiZWwpIHsNCgkJCUxhYmVsIGVkZ2VMYWJlbFR5cGUgPSBuZXcgTGFiZWwoZWRnZUxhYmVsQ29tcG9zaXRlLCBTV1QuTk9ORSk7DQoJCQllZGdlTGFiZWxUeXBlLnNldFRleHQoR3JhcGhFZGl0b3JNZXNzYWdlcy5nZXRTdHJpbmcoImVkZ2VUeXBlIikNCgkJCQkJKyAiOiIpOw0KCQkJRHluYW1pY1RleHQgZWRnZUxhYmVsVHlwZV9lZGl0ID0gbmV3IER5bmFtaWNUZXh0KA0KCQkJCQllZGdlTGFiZWxDb21wb3NpdGUsIGZhbHNlKTsNCgkJCWVkZ2VMYWJlbFR5cGVfZWRpdC5zZXRUZXh0KEdyYXBoRWRpdG9yTWVzc2FnZXMNCgkJCQkJLmdldFN0cmluZygicm9hZEVkZ2UiKSk7DQoNCgkJCUxhYmVsIGVkZ2VMYWJlbE5hbWUgPSBuZXcgTGFiZWwoZWRnZUxhYmVsQ29tcG9zaXRlLCBTV1QuTk9ORSk7DQoJCQllZGdlTGFiZWxOYW1lLnNldFRleHQoR3JhcGhFZGl0b3JNZXNzYWdlcy5nZXRTdHJpbmcoInJvYWROYW1lIikNCgkJCQkJKyAiOiIpOw0KCQkJRHluYW1pY1RleHQgZWRnZUxhYmVsTmFtZV9lZGl0ID0gbmV3IER5bmFtaWNUZXh0KA0KCQkJCQllZGdlTGFiZWxDb21wb3NpdGUsIHRydWUpOw0KCQkJZWRnZUxhYmVsTmFtZV9lZGl0LnNldFRleHQoZWRnZURhdGEuZ2V0Um9hZE5hbWUoKSk7DQoJCQllZGdlTGFiZWxOYW1lX2VkaXQNCgkJCQkJLmFkZE1vZGlmeUxpc3RlbmVyKG5ldyBUZXh0QW5kQnV0dG9uTW9kaWZ5TGlzdGVuZXIoDQoJCQkJCQkJemVzdEdyYXBoLA0KCQkJCQkJCVRleHRBbmRCdXR0b25Nb2RpZnlMaXN0ZW5lci5ST0FEX0xBQkVMX05BTUUpKTsNCg0KCQkJTGFiZWwgZWRnZUxhYmVsQ2xhc3MgPSBuZXcgTGFiZWwoZWRnZUxhYmVsQ29tcG9zaXRlLCBTV1QuTk9ORSk7DQoJCQllZGdlTGFiZWxDbGFzcy5zZXRUZXh0KEdyYXBoRWRpdG9yTWVzc2FnZXMuZ2V0U3RyaW5nKCJyb2FkQ2xhc3MiKQ0KCQkJCQkrICI6Iik7DQoJCQlEeW5hbWljVGV4dCBlZGdlTGFiZWxDbGFzc19lZGl0ID0gbmV3IER5bmFtaWNUZXh0KA0KCQkJCQllZGdlTGFiZWxDb21wb3NpdGUsIHRydWUpOw0KCQkJZWRnZUxhYmVsQ2xhc3NfZWRpdC5zZXRUZXh0KGVkZ2VEYXRhLmdldFJvYWRDbGFzcygpKTsNCgkJCWVkZ2VMYWJlbENsYXNzX2VkaXQNCgkJCQkJLmFkZE1vZGlmeUxpc3RlbmVyKG5ldyBUZXh0QW5kQnV0dG9uTW9kaWZ5TGlzdGVuZXIoDQoJCQkJCQkJemVzdEdyYXBoLA0KCQkJCQkJCVRleHRBbmRCdXR0b25Nb2RpZnlMaXN0ZW5lci5ST0FEX0xBQkVMX0NMQVNTKSk7DQoNCgkJCUxhYmVsIGVkZ2VMYWJlbENyb3NzaW5ncyA9IG5ldyBMYWJlbChlZGdlTGFiZWxDb21wb3NpdGUsIFNXVC5OT05FKTsNCgkJCWVkZ2VMYWJlbENyb3NzaW5ncy5zZXRUZXh0KEdyYXBoRWRpdG9yTWVzc2FnZXMNCgkJCQkJLmdldFN0cmluZygibnVtYmVyQ3Jvc3NpbmciKSArICI6Iik7DQoJCQlEeW5hbWljVGV4dCBlZGdlTGFiZWxDcm9zc2luZ3NfZWRpdCA9IG5ldyBEeW5hbWljVGV4dCgNCgkJCQkJZWRnZUxhYmVsQ29tcG9zaXRlLCB0cnVlKTsNCgkJCWVkZ2VMYWJlbENyb3NzaW5nc19lZGl0LnNldFRleHQoIiIgKyBlZGdlRGF0YS5nZXRSb2FkQ3Jvc3NpbmdzKCkpOw0KCQkJZWRnZUxhYmVsQ3Jvc3NpbmdzX2VkaXQNCgkJCQkJLmFkZE1vZGlmeUxpc3RlbmVyKG5ldyBUZXh0QW5kQnV0dG9uTW9kaWZ5TGlzdGVuZXIoDQoJCQkJCQkJemVzdEdyYXBoLA0KCQkJCQkJCVRleHRBbmRCdXR0b25Nb2RpZnlMaXN0ZW5lci5ST0FEX0xBQkVMX0NST1NTSU5HUykpOw0KCQl9IGVsc2UgaWYgKGVkZ2VMYWJlbCBpbnN0YW5jZW9mIFBpcGVUcmFuc3BvcnRFZGdlTGFiZWwpIHsNCgkJCUxhYmVsIGVkZ2VMYWJlbFR5cGUgPSBuZXcgTGFiZWwoZWRnZUxhYmVsQ29tcG9zaXRlLCBTV1QuTk9ORSk7DQoJCQllZGdlTGFiZWxUeXBlLnNldFRleHQoR3JhcGhFZGl0b3JNZXNzYWdlcy5nZXRTdHJpbmcoImVkZ2VUeXBlIikNCgkJCQkJKyAiOiIpOw0KCQkJRHluYW1pY1RleHQgZWRnZUxhYmVsVHlwZV9lZGl0ID0gbmV3IER5bmFtaWNUZXh0KA0KCQkJCQllZGdlTGFiZWxDb21wb3NpdGUsIGZhbHNlKTsNCgkJCWVkZ2VMYWJlbFR5cGVfZWRpdC5zZXRUZXh0KEdyYXBoRWRpdG9yTWVzc2FnZXMNCgkJCQkJLmdldFN0cmluZygicGlwZUVkZ2UiKSk7DQoNCgkJCUxhYmVsIGVkZ2VQb3AgPSBuZXcgTGFiZWwoZWRnZUxhYmVsQ29tcG9zaXRlLCBTV1QuTk9ORSk7DQoJCQllZGdlUG9wLnNldFRleHQoR3JhcGhFZGl0b3JNZXNzYWdlcy5nZXRTdHJpbmcoInBvcHVsYXRpb24iKSArICI6Iik7DQoJCQlEeW5hbWljVGV4dCBlZGdlUG9wX2VkaXQgPSBuZXcgRHluYW1pY1RleHQoZWRnZUxhYmVsQ29tcG9zaXRlLCB0cnVlKTsNCgkJCWVkZ2VQb3BfZWRpdC5zZXRUZXh0KGVkZ2VEYXRhLmdldFBpcGVQb3B1bGF0aW9uKCkpOw0KCQkJZWRnZVBvcF9lZGl0LmFkZE1vZGlmeUxpc3RlbmVyKG5ldyBUZXh0QW5kQnV0dG9uTW9kaWZ5TGlzdGVuZXIoDQoJCQkJCXplc3RHcmFwaCwNCgkJCQkJVGV4dEFuZEJ1dHRvbk1vZGlmeUxpc3RlbmVyLlBJUEVfTEFCRUxfUE9QVUxBVElPTikpOw0KDQoJCQlMYWJlbCBlZGdlTGFiZWxGbG93ID0gbmV3IExhYmVsKGVkZ2VMYWJlbENvbXBvc2l0ZSwgU1dULk5PTkUpOw0KCQkJZWRnZUxhYmVsRmxvdy5zZXRUZXh0KEdyYXBoRWRpdG9yTWVzc2FnZXMuZ2V0U3RyaW5nKCJwaXBlRmxvdyIpDQoJCQkJCSsgIjoiKTsNCgkJCUR5bmFtaWNUZXh0IGVkZ2VMYWJlbEZsb3dfZWRpdCA9IG5ldyBEeW5hbWljVGV4dCgNCgkJCQkJZWRnZUxhYmVsQ29tcG9zaXRlLCB0cnVlKTsNCgkJCWVkZ2VMYWJlbEZsb3dfZWRpdC5zZXRUZXh0KCIiICsgZWRnZURhdGEuZ2V0UGlwZUZsb3coKSk7DQoJCQllZGdlTGFiZWxGbG93X2VkaXQNCgkJCQkJLmFkZE1vZGlmeUxpc3RlbmVyKG5ldyBUZXh0QW5kQnV0dG9uTW9kaWZ5TGlzdGVuZXIoDQoJCQkJCQkJemVzdEdyYXBoLA0KCQkJCQkJCVRleHRBbmRCdXR0b25Nb2RpZnlMaXN0ZW5lci5QSVBFX0xBQkVMX0ZMT1cpKTsNCg0KCQkJTGFiZWwgZWRnZUxhYmVsUGVyaW9kID0gbmV3IExhYmVsKGVkZ2VMYWJlbENvbXBvc2l0ZSwgU1dULk5PTkUpOw0KCQkJZWRnZUxhYmVsUGVyaW9kLnNldFRleHQoR3JhcGhFZGl0b3JNZXNzYWdlcy5nZXRTdHJpbmcoInBlcmlvZCIpDQoJCQkJCSsgIjoiKTsNCgkJCUR5bmFtaWNUZXh0IGVkZ2VMYWJlbFBlcmlvZF9lZGl0ID0gbmV3IER5bmFtaWNUZXh0KA0KCQkJCQllZGdlTGFiZWxDb21wb3NpdGUsIHRydWUpOw0KCQkJZWRnZUxhYmVsUGVyaW9kX2VkaXQuc2V0VGV4dCgiIiArIGVkZ2VEYXRhLmdldFBpcGVQZXJpb2QoKSk7DQoJCQllZGdlTGFiZWxQZXJpb2RfZWRpdA0KCQkJCQkuYWRkTW9kaWZ5TGlzdGVuZXIobmV3IFRleHRBbmRCdXR0b25Nb2RpZnlMaXN0ZW5lcigNCgkJCQkJCQl6ZXN0R3JhcGgsDQoJCQkJCQkJVGV4dEFuZEJ1dHRvbk1vZGlmeUxpc3RlbmVyLlBJUEVfTEFCRUxfUEVSSU9EKSk7DQoJCX0gZWxzZSBpZiAoZWRnZUxhYmVsIGluc3RhbmNlb2YgUmVsYXRpdmVQaHlzaWNhbFJlbGF0aW9uc2hpcExhYmVsKSB7DQoJCQlMYWJlbCBlZGdlTGFiZWxUeXBlID0gbmV3IExhYmVsKGVkZ2VMYWJlbENvbXBvc2l0ZSwgU1dULk5PTkUpOw0KCQkJZWRnZUxhYmVsVHlwZS5zZXRUZXh0KEdyYXBoRWRpdG9yTWVzc2FnZXMuZ2V0U3RyaW5nKCJlZGdlVHlwZSIpDQoJCQkJCSsgIjoiKTsNCgkJCUR5bmFtaWNUZXh0IGVkZ2VMYWJlbFR5cGVfZWRpdCA9IG5ldyBEeW5hbWljVGV4dCgNCgkJCQkJZWRnZUxhYmVsQ29tcG9zaXRlLCBmYWxzZSk7DQoJCQllZGdlTGFiZWxUeXBlX2VkaXQuc2V0VGV4dChHcmFwaEVkaXRvck1lc3NhZ2VzDQoJCQkJCS5nZXRTdHJpbmcoImNvbnRhaW5tZW50RWRnZSIpICsgIjoiKTsNCgkJfQ0KDQoJCXJldHVybiBlZGdlTGFiZWxDb21wb3NpdGU7DQoJfQ0KDQoJcHJpdmF0ZSBDb21wb3NpdGUgY3JlYXRlSW5mb0NvbXBvc2l0ZShDb21wb3NpdGUgcGFyZW50KSB7DQoJCUdyb3VwIGluZm9Db21wb3NpdGUgPSBuZXcgR3JvdXAocGFyZW50LCBTV1QuQ0VOVEVSKTsNCgkJUG9pbnQyRC5Eb3VibGUgeHlfdHJhbnMgPSBnZXRDb29yZGluYXRlc0Zyb21DdXJzb3JMb2NhdGlvbih6ZXN0R3JhcGgNCgkJCQkudG9Db250cm9sKERpc3BsYXkuZ2V0Q3VycmVudCgpLmdldEN1cnNvckxvY2F0aW9uKCkpKTsNCg0KCQlpbmZvQ29tcG9zaXRlLnNldFRleHQoR3JhcGhFZGl0b3JNZXNzYWdlcw0KCQkJCS5nZXRTdHJpbmcoImRpc3BsYXlJbmZvcm1hdGlvbiIpKTsNCgkJaW5mb0NvbXBvc2l0ZS5zZXRMYXlvdXQobmV3IFJvd0xheW91dChTV1QuSE9SSVpPTlRBTCkpOw0KDQoJCUxhYmVsIGNvb3JkaW5hdGUgPSBuZXcgTGFiZWwoaW5mb0NvbXBvc2l0ZSwgU1dULk5PTkUpOw0KCQljb29yZGluYXRlLnNldFRleHQoR3JhcGhFZGl0b3JNZXNzYWdlcy5nZXRTdHJpbmcoImNvb3JkaW5hdGVzIikgKyAiOiIpOw0KCQljb29yZGluYXRlX3RyYW5zID0gbmV3IER5bmFtaWNUZXh0KGluZm9Db21wb3NpdGUsIGZhbHNlKTsNCgkJY29vcmRpbmF0ZV90cmFucy5zZXRUZXh0KGZvcm1hdExhdExvbih4eV90cmFucy55LCB4eV90cmFucy54KSk7DQoNCgkJTGFiZWwgem9vbSA9IG5ldyBMYWJlbChpbmZvQ29tcG9zaXRlLCBTV1QuTk9ORSk7DQoJCXpvb20uc2V0VGV4dChHcmFwaEVkaXRvck1lc3NhZ2VzLmdldFN0cmluZygiem9vbSIpICsgIjoiKTsNCgkJem9vbUVkaXQgPSBuZXcgRHluYW1pY1RleHQoaW5mb0NvbXBvc2l0ZSwgZmFsc2UpOw0KCQl6b29tRWRpdC5zZXRUZXh0KGZvcm1hdERvdWJsZSh6b29tRmFjdG9yKSk7DQoNCgkJcmV0dXJuIGluZm9Db21wb3NpdGU7DQoJfQ0KDQoJcHJpdmF0ZSBDb21wb3NpdGUgY3JlYXRlQnV0dG9uc0NvbXBvc2l0ZShDb21wb3NpdGUgcGFyZW50KSB7DQoJCUNvbXBvc2l0ZSB0b29sQmFyID0gbmV3IENvbXBvc2l0ZShwYXJlbnQsIFNXVC5OT05FKTsNCgkJQnV0dG9uIHNhdmVCdXR0b24gPSBuZXcgQnV0dG9uKHRvb2xCYXIsIFNXVC5QVVNIKTsNCgkJQnV0dG9uIHNhdmVBc0J1dHRvbiA9IG5ldyBCdXR0b24odG9vbEJhciwgU1dULlBVU0gpOw0KCQlCdXR0b24gcXVpdEJ1dHRvbiA9IG5ldyBCdXR0b24odG9vbEJhciwgU1dULlBVU0gpOw0KDQoJCXRvb2xCYXIuc2V0TGF5b3V0KG5ldyBSb3dMYXlvdXQoU1dULkhPUklaT05UQUwpKTsNCg0KCQlzYXZlQnV0dG9uLnNldFRleHQoR3JhcGhFZGl0b3JNZXNzYWdlcy5nZXRTdHJpbmcoInNhdmVBbmRRdWl0IikpOw0KCQlzYXZlQXNCdXR0b24uc2V0VGV4dChHcmFwaEVkaXRvck1lc3NhZ2VzLmdldFN0cmluZygic2F2ZUdyYXBoQXMiKSk7DQoJCXF1aXRCdXR0b24uc2V0VGV4dChHcmFwaEVkaXRvck1lc3NhZ2VzLmdldFN0cmluZygicXVpdCIpKTsNCg0KCQlzYXZlQnV0dG9uLmFkZFNlbGVjdGlvbkxpc3RlbmVyKG5ldyBTZWxlY3Rpb25MaXN0ZW5lcigpIHsNCg0KCQkJcHVibGljIHZvaWQgd2lkZ2V0U2VsZWN0ZWQoU2VsZWN0aW9uRXZlbnQgZSkgew0KCQkJCXNhdmVHcmFwaExpc3QoKTsNCgkJCQlBY3RpdmF0b3IuZ2V0RGVmYXVsdCgpLmdldFdvcmtiZW5jaCgpLmdldERpc3BsYXkoKQ0KCQkJCQkJLmdldEFjdGl2ZVNoZWxsKCkuZGlzcG9zZSgpOw0KCQkJfQ0KDQoJCQlwdWJsaWMgdm9pZCB3aWRnZXREZWZhdWx0U2VsZWN0ZWQoU2VsZWN0aW9uRXZlbnQgZSkgew0KCQkJfQ0KCQl9KTsNCg0KCQlzYXZlQXNCdXR0b24uYWRkU2VsZWN0aW9uTGlzdGVuZXIobmV3IFNlbGVjdGlvbkxpc3RlbmVyKCkgew0KDQoJCQlwdWJsaWMgdm9pZCB3aWRnZXRTZWxlY3RlZChTZWxlY3Rpb25FdmVudCBlKSB7DQoJCQkJc2F2ZVN0ZW1HcmFwaEFzKCk7DQoJCQl9DQoNCgkJCXB1YmxpYyB2b2lkIHdpZGdldERlZmF1bHRTZWxlY3RlZChTZWxlY3Rpb25FdmVudCBlKSB7DQoJCQl9DQoJCX0pOw0KDQoJCXF1aXRCdXR0b24uYWRkU2VsZWN0aW9uTGlzdGVuZXIobmV3IFNlbGVjdGlvbkxpc3RlbmVyKCkgew0KDQoJCQlwdWJsaWMgdm9pZCB3aWRnZXRTZWxlY3RlZChTZWxlY3Rpb25FdmVudCBlKSB7DQoJCQkJQWN0aXZhdG9yLmdldERlZmF1bHQoKS5nZXRXb3JrYmVuY2goKS5nZXREaXNwbGF5KCkNCgkJCQkJCS5nZXRBY3RpdmVTaGVsbCgpLmRpc3Bvc2UoKTsNCgkJCX0NCg0KCQkJcHVibGljIHZvaWQgd2lkZ2V0RGVmYXVsdFNlbGVjdGVkKFNlbGVjdGlvbkV2ZW50IGUpIHsNCgkJCX0NCgkJfSk7DQoNCgkJcmV0dXJuIHRvb2xCYXI7DQoJfQ0KDQoJcHJpdmF0ZSB2b2lkIGFkZFplc3RHcmFwaExpc3RlbmVycygpIHsNCgkJemVzdEdyYXBoLmdldExpZ2h0d2VpZ2h0U3lzdGVtKCkuZ2V0Um9vdEZpZ3VyZSgpDQoJCQkJLmFkZE1vdXNlTGlzdGVuZXIobmV3IG9yZy5lY2xpcHNlLmRyYXcyZC5Nb3VzZUxpc3RlbmVyKCkgew0KDQoJCQkJCUBPdmVycmlkZQ0KCQkJCQlwdWJsaWMgdm9pZCBtb3VzZVByZXNzZWQob3JnLmVjbGlwc2UuZHJhdzJkLk1vdXNlRXZlbnQgbWUpIHsNCgkJCQkJCW9yZy5lY2xpcHNlLmRyYXcyZC5nZW9tZXRyeS5Qb2ludCBtb3VzZVBvaW50ID0gbmV3IG9yZy5lY2xpcHNlLmRyYXcyZC5nZW9tZXRyeS5Qb2ludCgNCgkJCQkJCQkJbWUueCwgbWUueSk7DQoJCQkJCQl6ZXN0R3JhcGguZ2V0Um9vdExheWVyKCkNCgkJCQkJCQkJLnRyYW5zbGF0ZVRvUmVsYXRpdmUobW91c2VQb2ludCk7DQoJCQkJCQlJRmlndXJlIGZpZ3VyZVVuZGVyTW91c2UgPSB6ZXN0R3JhcGguZ2V0RmlndXJlQXQoDQoJCQkJCQkJCW1vdXNlUG9pbnQueCwgbW91c2VQb2ludC55KTsNCg0KCQkJCQkJaWYgKGZpZ3VyZVVuZGVyTW91c2UgPT0gbnVsbCAmJiBtZS5idXR0b24gPT0gMSkgew0KCQkJCQkJCXplc3RHcmFwaC5zZXRTZWxlY3Rpb24obmV3IEdyYXBoSXRlbVswXSk7DQoJCQkJCQkJemVzdEdyYXBoLm5vdGlmeUxpc3RlbmVycyhTV1QuU2VsZWN0aW9uLA0KCQkJCQkJCQkJbmV3IEV2ZW50KCkpOw0KCQkJCQkJfQ0KCQkJCQl9DQoNCgkJCQkJQE92ZXJyaWRlDQoJCQkJCXB1YmxpYyB2b2lkIG1vdXNlUmVsZWFzZWQob3JnLmVjbGlwc2UuZHJhdzJkLk1vdXNlRXZlbnQgbWUpIHsNCgkJCQkJfQ0KDQoJCQkJCUBPdmVycmlkZQ0KCQkJCQlwdWJsaWMgdm9pZCBtb3VzZURvdWJsZUNsaWNrZWQoDQoJCQkJCQkJb3JnLmVjbGlwc2UuZHJhdzJkLk1vdXNlRXZlbnQgbWUpIHsNCgkJCQkJfQ0KCQkJCX0pOw0KDQoJCXplc3RHcmFwaC5hZGRNb3VzZUxpc3RlbmVyKG5ldyBNb3VzZUxpc3RlbmVyKCkgew0KDQoJCQlwdWJsaWMgdm9pZCBtb3VzZURvd24oTW91c2VFdmVudCBlKSB7DQoJCQkJbGFzdEN1cnNvclggPSBEaXNwbGF5LmdldEN1cnJlbnQoKS5nZXRDdXJzb3JMb2NhdGlvbigpLng7DQoJCQkJbGFzdEN1cnNvclkgPSBEaXNwbGF5LmdldEN1cnJlbnQoKS5nZXRDdXJzb3JMb2NhdGlvbigpLnk7DQoJCQkJbW91c2VCdXR0b25QcmVzc2VkID0gdHJ1ZTsJCQkJDQoJCQl9DQoNCgkJCXB1YmxpYyB2b2lkIG1vdXNlVXAoTW91c2VFdmVudCBlKSB7DQoJCQkJbW91c2VCdXR0b25QcmVzc2VkID0gZmFsc2U7DQoJCQl9DQoNCgkJCXB1YmxpYyB2b2lkIG1vdXNlRG91YmxlQ2xpY2soTW91c2VFdmVudCBlKSB7DQoJCQl9DQoJCX0pOw0KDQoJCXplc3RHcmFwaC5hZGRNb3VzZU1vdmVMaXN0ZW5lcihuZXcgTW91c2VNb3ZlTGlzdGVuZXIoKSB7DQoNCgkJCXB1YmxpYyB2b2lkIG1vdXNlTW92ZShNb3VzZUV2ZW50IGUpIHsNCgkJCQlQb2ludCB4eSA9IHplc3RHcmFwaC50b0NvbnRyb2woRGlzcGxheS5nZXRDdXJyZW50KCkNCgkJCQkJCS5nZXRDdXJzb3JMb2NhdGlvbigpKTsNCgkJCQlQb2ludDJELkRvdWJsZSB4eV90cmFucyA9IGdldENvb3JkaW5hdGVzRnJvbUN1cnNvckxvY2F0aW9uKHh5KTsNCg0KCQkJCWNvb3JkaW5hdGVfdHJhbnMuc2V0VGV4dChmb3JtYXRMYXRMb24oeHlfdHJhbnMueSwgeHlfdHJhbnMueCkpOw0KDQoJCQkJaWYgKCFtb3VzZUJ1dHRvblByZXNzZWQpIHsNCgkJCQkJcmV0dXJuOw0KCQkJCX0NCg0KCQkJCWludCB4ID0gRGlzcGxheS5nZXRDdXJyZW50KCkuZ2V0Q3Vyc29yTG9jYXRpb24oKS54Ow0KCQkJCWludCB5ID0gRGlzcGxheS5nZXRDdXJyZW50KCkuZ2V0Q3Vyc29yTG9jYXRpb24oKS55Ow0KCQkJCWludCBkaWZmWCA9IHggLSBsYXN0Q3Vyc29yWDsNCgkJCQlpbnQgZGlmZlkgPSB5IC0gbGFzdEN1cnNvclk7DQoNCgkJCQlsYXN0Q3Vyc29yWCA9IHg7DQoJCQkJbGFzdEN1cnNvclkgPSB5Ow0KDQoJCQkJaWYgKHplc3RHcmFwaC5nZXRTZWxlY3Rpb24oKS5pc0VtcHR5KCkpIHsNCgkJCQkJaWYgKGRpZmZYICE9IDAgfHwgZGlmZlkgIT0gMCkgew0KCQkJCQkJeFRyYW5zbGF0aW9uICs9IGRpZmZYOw0KCQkJCQkJeVRyYW5zbGF0aW9uICs9IGRpZmZZOw0KCQkJCQkJemVzdEdyYXBoLnJlZHJhdygpOw0KCQkJCQkJcmVkcmF3KCk7DQoJCQkJCX0NCgkJCQl9IGVsc2Ugew0KCQkJCQlmb3IgKE9iamVjdCBzZWxlY3RlZEl0ZW0gOiB6ZXN0R3JhcGguZ2V0U2VsZWN0aW9uKCkpIHsNCgkJCQkJCWlmICghKHNlbGVjdGVkSXRlbSBpbnN0YW5jZW9mIEdyYXBoTm9kZSkpIHsNCgkJCQkJCQljb250aW51ZTsNCgkJCQkJCX0NCg0KCQkJCQkJR3JhcGhOb2RlIHNlbGVjdGVkTm9kZSA9IChHcmFwaE5vZGUpIHNlbGVjdGVkSXRlbTsNCgkJCQkJCU5vZGVEYXRhIG5vZGVEYXRhID0gKE5vZGVEYXRhKSBzZWxlY3RlZE5vZGUuZ2V0RGF0YSgpOw0KDQoJCQkJCQlpZiAoZGlmZlggIT0gMCB8fCBkaWZmWSAhPSAwKSB7DQoJCQkJCQkJYWRkVHJhbnNsYXRpb25Ub05vZGUobm9kZURhdGEsIGRpZmZYLCBkaWZmWSk7DQoJCQkJCQkJemVzdEdyYXBoLnJlZHJhdygpOw0KCQkJCQkJfQ0KCQkJCQl9DQoNCgkJCQkJaWYgKHplc3RHcmFwaC5nZXRTZWxlY3Rpb24oKS5zaXplKCkgPT0gMQ0KCQkJCQkJCSYmIHplc3RHcmFwaC5nZXRTZWxlY3Rpb24oKS5nZXQoMCkgaW5zdGFuY2VvZiBHcmFwaE5vZGUpIHsNCgkJCQkJCUdyYXBoTm9kZSBzZWxlY3RlZE5vZGUgPSAoR3JhcGhOb2RlKSB6ZXN0R3JhcGgNCgkJCQkJCQkJLmdldFNlbGVjdGlvbigpLmdldCgwKTsNCgkJCQkJCU5vZGVEYXRhIG5vZGVEYXRhID0gKE5vZGVEYXRhKSBzZWxlY3RlZE5vZGUuZ2V0RGF0YSgpOw0KDQoJCQkJCQlub2RlWFlfZWRpdC5zZXRUZXh0KGZvcm1hdExhdExvbihub2RlRGF0YS5nZXRPcmlnWSgpLA0KCQkJCQkJCQlub2RlRGF0YS5nZXRPcmlnWCgpKSk7DQoJCQkJCX0NCgkJCQl9DQoJCQl9DQoJCX0pOw0KDQoJCXplc3RHcmFwaC5hZGRTZWxlY3Rpb25MaXN0ZW5lcihuZXcgU2VsZWN0aW9uTGlzdGVuZXIoKSB7DQoNCgkJCXB1YmxpYyB2b2lkIHdpZGdldFNlbGVjdGVkKFNlbGVjdGlvbkV2ZW50IGUpIHsNCgkJCQl1cGRhdGVTaGVsbCgpOwkJCQkNCgkJCX0NCg0KCQkJcHVibGljIHZvaWQgd2lkZ2V0RGVmYXVsdFNlbGVjdGVkKFNlbGVjdGlvbkV2ZW50IGUpIHsNCgkJCX0NCgkJfSk7DQoNCgkJemVzdEdyYXBoLmFkZE1vdXNlV2hlZWxMaXN0ZW5lcihuZXcgTW91c2VXaGVlbExpc3RlbmVyKCkgew0KDQoJCQlwdWJsaWMgdm9pZCBtb3VzZVNjcm9sbGVkKE1vdXNlRXZlbnQgZSkgew0KCQkJCVBvaW50MkQuRG91YmxlIHAgPSBnZXRDb29yZGluYXRlc0Zyb21DdXJzb3JMb2NhdGlvbih6ZXN0R3JhcGgNCgkJCQkJCS50b0NvbnRyb2woRGlzcGxheS5nZXRDdXJyZW50KCkuZ2V0Q3Vyc29yTG9jYXRpb24oKSkpOw0KDQoJCQkJaWYgKGUuY291bnQgPj0gMCkgew0KCQkJCQl4VHJhbnNsYXRpb24gLT0gMC4xICogc2NhbGVYICogcC54Ow0KCQkJCQl5VHJhbnNsYXRpb24gLT0gMC4xICogc2NhbGVZICogcC55Ow0KCQkJCQlzY2FsZVggKj0gMS4xOw0KCQkJCQlzY2FsZVkgKj0gMS4xOw0KDQoJCQkJCXpvb21GYWN0b3IgKj0gMS4xOw0KCQkJCX0gZWxzZSB7DQoJCQkJCXNjYWxlWCAvPSAxLjE7DQoJCQkJCXNjYWxlWSAvPSAxLjE7DQoJCQkJCXhUcmFuc2xhdGlvbiArPSAwLjEgKiBzY2FsZVggKiBwLng7DQoJCQkJCXlUcmFuc2xhdGlvbiArPSAwLjEgKiBzY2FsZVkgKiBwLnk7DQoNCgkJCQkJem9vbUZhY3RvciAvPSAxLjE7DQoJCQkJfQ0KDQoJCQkJUG9pbnQgeHkgPSB6ZXN0R3JhcGgudG9Db250cm9sKERpc3BsYXkuZ2V0Q3VycmVudCgpDQoJCQkJCQkuZ2V0Q3Vyc29yTG9jYXRpb24oKSk7DQoJCQkJUG9pbnQyRC5Eb3VibGUgeHlfdHJhbnMgPSBnZXRDb29yZGluYXRlc0Zyb21DdXJzb3JMb2NhdGlvbih4eSk7DQoNCgkJCQljb29yZGluYXRlX3RyYW5zLnNldFRleHQoZm9ybWF0TGF0TG9uKHh5X3RyYW5zLnksIHh5X3RyYW5zLngpKTsNCgkJCQl6b29tRWRpdC5zZXRUZXh0KGZvcm1hdERvdWJsZSh6b29tRmFjdG9yKSk7DQoJCQkJemVzdEdyYXBoLnJlZHJhdygpOw0KCQkJCXJlZHJhdygpOw0KCQkJfQ0KCQl9KTsNCgl9DQoNCglwcml2YXRlIHZvaWQgYWRkWmVzdEdyYXBoQ29udGV4dE1lbnUoKSB7DQoJCUxpc3Q8Pz4gc2VsZWN0aW9uID0gemVzdEdyYXBoLmdldFNlbGVjdGlvbigpOw0KCQlNZW51IG1lbnUgPSBuZXcgTWVudSh6ZXN0R3JhcGguZ2V0U2hlbGwoKSwgU1dULlBPUF9VUCk7DQoNCgkJaWYgKHNlbGVjdGlvbi5pc0VtcHR5KCkpIHsNCgkJCWNyZWF0ZUFkZE5vZGVJdGVtKG1lbnUpOw0KCQl9DQoNCgkJaWYgKHNlbGVjdGlvbi5zaXplKCkgPT0gMSAmJiBzZWxlY3Rpb24uZ2V0KDApIGluc3RhbmNlb2YgR3JhcGhOb2RlKSB7DQoJCQljcmVhdGVSZW1vdmVOb2RlSXRlbShtZW51KTsNCgkJCWNyZWF0ZUFkZExhYmVsSXRlbShtZW51KTsNCgkJCWNyZWF0ZVJlbW92ZUxhYmVsSXRlbShtZW51KTsNCgkJfQ0KDQoJCWlmIChzZWxlY3Rpb24uc2l6ZSgpID09IDIgJiYgc2VsZWN0aW9uLmdldCgwKSBpbnN0YW5jZW9mIEdyYXBoTm9kZQ0KCQkJCSYmIHNlbGVjdGlvbi5nZXQoMSkgaW5zdGFuY2VvZiBHcmFwaE5vZGUpIHsNCgkJCWNyZWF0ZUFkZEVkZ2VJdGVtKG1lbnUpOw0KCQl9DQoNCgkJaWYgKHNlbGVjdGlvbi5zaXplKCkgPT0gMQ0KCQkJCSYmIHNlbGVjdGlvbi5nZXQoMCkgaW5zdGFuY2VvZiBHcmFwaENvbm5lY3Rpb24pIHsNCgkJCWNyZWF0ZVJlbW92ZUVkZ2VJdGVtKG1lbnUpOw0KCQl9DQoNCgkJemVzdEdyYXBoLnNldE1lbnUobWVudSk7DQoJfQ0KDQoJcHJpdmF0ZSB2b2lkIGNyZWF0ZUFkZE5vZGVJdGVtKE1lbnUgbWVudSkgew0KCQlNZW51SXRlbSBhZGROb2RlID0gbmV3IE1lbnVJdGVtKG1lbnUsIFNXVC5QVVNIKTsNCg0KCQlhZGROb2RlLnNldFRleHQoR3JhcGhFZGl0b3JNZXNzYWdlcy5nZXRTdHJpbmcoImFkZE5vZGUiKSk7DQoNCgkJYWRkTm9kZS5hZGRTZWxlY3Rpb25MaXN0ZW5lcihuZXcgU2VsZWN0aW9uTGlzdGVuZXIoKSB7DQoNCgkJCXB1YmxpYyB2b2lkIHdpZGdldFNlbGVjdGVkKFNlbGVjdGlvbkV2ZW50IGUpIHsNCgkJCQlQb2ludDJELkRvdWJsZSBwID0gZ2V0Q29vcmRpbmF0ZXNGcm9tQ3Vyc29yTG9jYXRpb24oemVzdEdyYXBoDQoJCQkJCQkudG9Db250cm9sKERpc3BsYXkuZ2V0Q3VycmVudCgpLmdldEN1cnNvckxvY2F0aW9uKCkpKTsNCgkJCQlOZXdOb2RlRGlhbG9nIGRpYWxvZyA9IG5ldyBOZXdOb2RlRGlhbG9nKHNoZWxsKTsNCg0KCQkJCWlmICghZGlhbG9nLmhhc1Jlc3VsdCgpKSB7DQoJCQkJCXJldHVybjsNCgkJCQl9DQoNCgkJCQlTdHJpbmcgaWRlbnRpZmllciA9IGRpYWxvZy5nZXRJZGVudGlmaWVyKCk7DQoJCQkJZG91YmxlIHNpemUgPSBkaWFsb2cuZ2V0U2l6ZSgpOw0KCQkJCU5vZGUgbm9kZSA9IE5vZGVzRmFjdG9yeS5lSU5TVEFOQ0UuY3JlYXRlUmVnaW9uKCk7DQoJCQkJTGF0TG9uZyBsYXRsb24gPSBuZXcgTGF0TG9uZygpOw0KCQkJCVNlZ21lbnRCdWlsZGVyIGJ1aWxkZXIgPSBuZXcgU2VnbWVudEJ1aWxkZXIoKTsNCg0KCQkJCWJ1aWxkZXIuYWRkKHAueSAtIHNpemUgLyAyLCBwLnggLSBzaXplIC8gMik7DQoJCQkJYnVpbGRlci5hZGQocC55ICsgc2l6ZSAvIDIsIHAueCAtIHNpemUgLyAyKTsNCgkJCQlidWlsZGVyLmFkZChwLnkgKyBzaXplIC8gMiwgcC54ICsgc2l6ZSAvIDIpOw0KCQkJCWJ1aWxkZXIuYWRkKHAueSAtIHNpemUgLyAyLCBwLnggKyBzaXplIC8gMik7DQoJCQkJYnVpbGRlci5hZGQocC55IC0gc2l6ZSAvIDIsIHAueCAtIHNpemUgLyAyKTsNCgkJCQlsYXRsb24uYWRkKGJ1aWxkZXIudG9TZWdtZW50KCkpOw0KCQkJCW5vZGUuZ2V0RHVibGluQ29yZSgpLnNldFRpdGxlKCIiKTsNCgkJCQlub2RlLnNldFVSSShTVEVNVVJJDQoJCQkJCQkuY3JlYXRlVVJJKFJlZ2lvbi5VUklfVFlQRV9SRUdJT05fTk9ERV9TRUdNRU5UICsgIi8iDQoJCQkJCQkJCSsgaWRlbnRpZmllcikpOw0KCQkJCW5vZGUuZ2V0RHVibGluQ29yZSgpLnNldFNwYXRpYWwoDQoJCQkJCQlJbmxpbmVMYXRMb25nRGF0YVByb3ZpZGVyDQoJCQkJCQkJCS5jcmVhdGVTcGF0aWFsSW5saW5lVVJJU3RyaW5nKGxhdGxvbikpOw0KDQoJCQkJR3JhcGhOb2RlIGduID0gcHJvY2Vzc05vZGUobm9kZSk7DQoNCgkJCQlhZGROb2RlVG9TdGVtR3JhcGgobm9kZSk7DQoJCQkJemVzdEdyYXBoLnNldFNlbGVjdGlvbihuZXcgR3JhcGhJdGVtW10geyBnbiB9KTsNCgkJCQl6ZXN0R3JhcGgucmVkcmF3KCk7DQoJCQkJcmVkcmF3KCk7DQoJCQkJdXBkYXRlU2hlbGwoKTsNCgkJCX0NCg0KCQkJcHVibGljIHZvaWQgd2lkZ2V0RGVmYXVsdFNlbGVjdGVkKFNlbGVjdGlvbkV2ZW50IGUpIHsNCgkJCX0NCgkJfSk7DQoJfQ0KDQoJcHJpdmF0ZSB2b2lkIGNyZWF0ZUFkZExhYmVsSXRlbShNZW51IG1lbnUpIHsNCgkJTWVudUl0ZW0gYWRkTGFiZWxJdGVtID0gbmV3IE1lbnVJdGVtKG1lbnUsIFNXVC5DQVNDQURFKTsNCgkJTWVudSBhZGRMYWJlbE1lbnUgPSBuZXcgTWVudSh6ZXN0R3JhcGguZ2V0U2hlbGwoKSwgU1dULkRST1BfRE9XTik7DQoJCU1lbnVJdGVtIGFkZEFyZWFMYWJlbEl0ZW0gPSBuZXcgTWVudUl0ZW0oYWRkTGFiZWxNZW51LCBTV1QuUFVTSCk7DQoJCU1lbnVJdGVtIGFkZFBvcHVsYXRpb25MYWJlbEl0ZW0gPSBuZXcgTWVudUl0ZW0oYWRkTGFiZWxNZW51LCBTV1QuUFVTSCk7DQoNCgkJYWRkTGFiZWxJdGVtLnNldFRleHQoR3JhcGhFZGl0b3JNZXNzYWdlcy5nZXRTdHJpbmcoImFkZExhYmVsIikpOw0KCQlhZGRBcmVhTGFiZWxJdGVtLnNldFRleHQoR3JhcGhFZGl0b3JNZXNzYWdlcy5nZXRTdHJpbmcoImFkZEFyZWFMYWJlbCIpKTsNCgkJYWRkUG9wdWxhdGlvbkxhYmVsSXRlbS5zZXRUZXh0KEdyYXBoRWRpdG9yTWVzc2FnZXMNCgkJCQkuZ2V0U3RyaW5nKCJhZGRQb3B1bGF0aW9uTGFiZWwiKSk7DQoJCWFkZExhYmVsSXRlbS5zZXRNZW51KGFkZExhYmVsTWVudSk7DQoNCgkJYWRkQXJlYUxhYmVsSXRlbS5hZGRTZWxlY3Rpb25MaXN0ZW5lcihuZXcgU2VsZWN0aW9uTGlzdGVuZXIoKSB7DQoJCQlwdWJsaWMgdm9pZCB3aWRnZXRTZWxlY3RlZChTZWxlY3Rpb25FdmVudCBlKSB7DQoJCQkJYWRkTm9kZUxhYmVsKExhYmVsc1BhY2thZ2UuTGl0ZXJhbHMuQVJFQV9MQUJFTCk7DQoJCQl9DQoNCgkJCXB1YmxpYyB2b2lkIHdpZGdldERlZmF1bHRTZWxlY3RlZChTZWxlY3Rpb25FdmVudCBlKSB7DQoJCQl9DQoJCX0pOw0KDQoJCWFkZFBvcHVsYXRpb25MYWJlbEl0ZW0uYWRkU2VsZWN0aW9uTGlzdGVuZXIobmV3IFNlbGVjdGlvbkxpc3RlbmVyKCkgew0KCQkJcHVibGljIHZvaWQgd2lkZ2V0U2VsZWN0ZWQoU2VsZWN0aW9uRXZlbnQgZSkgew0KCQkJCWFkZE5vZGVMYWJlbChMYWJlbHNQYWNrYWdlLkxpdGVyYWxzLlBPUFVMQVRJT05fTEFCRUwpOw0KCQkJfQ0KDQoJCQlwdWJsaWMgdm9pZCB3aWRnZXREZWZhdWx0U2VsZWN0ZWQoU2VsZWN0aW9uRXZlbnQgZSkgew0KCQkJfQ0KCQl9KTsNCgl9DQoNCglwcml2YXRlIHZvaWQgY3JlYXRlQWRkRWRnZUl0ZW0oTWVudSBtZW51KSB7DQoJCU1lbnVJdGVtIGFkZEVkZ2VJdGVtID0gbmV3IE1lbnVJdGVtKG1lbnUsIFNXVC5DQVNDQURFKTsNCgkJTWVudSBhZGRFZGdlTWVudSA9IG5ldyBNZW51KHplc3RHcmFwaC5nZXRTaGVsbCgpLCBTV1QuRFJPUF9ET1dOKTsNCgkJTWVudUl0ZW0gYWRkTWlncmF0aW9uRWRnZSA9IG5ldyBNZW51SXRlbShhZGRFZGdlTWVudSwgU1dULlBVU0gpOw0KCQlNZW51SXRlbSBhZGRDb21tb25Cb3JkZXJFZGdlID0gbmV3IE1lbnVJdGVtKGFkZEVkZ2VNZW51LCBTV1QuUFVTSCk7DQoJCU1lbnVJdGVtIGFkZFJvYWRUcmFuc3BvcnRFZGdlID0gbmV3IE1lbnVJdGVtKGFkZEVkZ2VNZW51LCBTV1QuUFVTSCk7DQoJCU1lbnVJdGVtIGFkZFBpcGVUcmFuc3BvcnRFZGdlID0gbmV3IE1lbnVJdGVtKGFkZEVkZ2VNZW51LCBTV1QuUFVTSCk7DQoNCgkJYWRkRWRnZUl0ZW0uc2V0VGV4dChHcmFwaEVkaXRvck1lc3NhZ2VzLmdldFN0cmluZygiYWRkRWRnZSIpKTsNCgkJYWRkTWlncmF0aW9uRWRnZS5zZXRUZXh0KEdyYXBoRWRpdG9yTWVzc2FnZXMNCgkJCQkuZ2V0U3RyaW5nKCJhZGRNaWdyYXRpb25FZGdlIikpOw0KCQlhZGRDb21tb25Cb3JkZXJFZGdlLnNldFRleHQoR3JhcGhFZGl0b3JNZXNzYWdlcw0KCQkJCS5nZXRTdHJpbmcoImFkZENvbW1vbkJvcmRlckVkZ2UiKSk7DQoJCWFkZFJvYWRUcmFuc3BvcnRFZGdlLnNldFRleHQoR3JhcGhFZGl0b3JNZXNzYWdlcw0KCQkJCS5nZXRTdHJpbmcoImFkZFJvYWRFZGdlIikpOw0KCQlhZGRQaXBlVHJhbnNwb3J0RWRnZS5zZXRUZXh0KEdyYXBoRWRpdG9yTWVzc2FnZXMNCgkJCQkuZ2V0U3RyaW5nKCJhZGRQaXBlRWRnZSIpKTsNCgkJYWRkRWRnZUl0ZW0uc2V0TWVudShhZGRFZGdlTWVudSk7DQoNCgkJYWRkQ29tbW9uQm9yZGVyRWRnZS5hZGRTZWxlY3Rpb25MaXN0ZW5lcihuZXcgU2VsZWN0aW9uTGlzdGVuZXIoKSB7DQoJCQlwdWJsaWMgdm9pZCB3aWRnZXRTZWxlY3RlZChTZWxlY3Rpb25FdmVudCBlKSB7DQoJCQkJYWRkRWRnZShMYWJlbHNQYWNrYWdlLkxpdGVyYWxzLkNPTU1PTl9CT1JERVJfUkVMQVRJT05TSElQX0xBQkVMKTsNCgkJCX0NCg0KCQkJcHVibGljIHZvaWQgd2lkZ2V0RGVmYXVsdFNlbGVjdGVkKFNlbGVjdGlvbkV2ZW50IGUpIHsNCgkJCX0NCgkJfSk7DQoNCgkJYWRkTWlncmF0aW9uRWRnZS5hZGRTZWxlY3Rpb25MaXN0ZW5lcihuZXcgU2VsZWN0aW9uTGlzdGVuZXIoKSB7DQoJCQlwdWJsaWMgdm9pZCB3aWRnZXRTZWxlY3RlZChTZWxlY3Rpb25FdmVudCBlKSB7DQoJCQkJYWRkRWRnZShFZGdlc1BhY2thZ2UuTGl0ZXJhbHMuTUlHUkFUSU9OX0VER0VfTEFCRUwpOw0KCQkJfQ0KDQoJCQlwdWJsaWMgdm9pZCB3aWRnZXREZWZhdWx0U2VsZWN0ZWQoU2VsZWN0aW9uRXZlbnQgZSkgew0KCQkJfQ0KCQl9KTsNCg0KCQlhZGRSb2FkVHJhbnNwb3J0RWRnZS5hZGRTZWxlY3Rpb25MaXN0ZW5lcihuZXcgU2VsZWN0aW9uTGlzdGVuZXIoKSB7DQoJCQlwdWJsaWMgdm9pZCB3aWRnZXRTZWxlY3RlZChTZWxlY3Rpb25FdmVudCBlKSB7DQoJCQkJYWRkRWRnZShMYWJlbHNQYWNrYWdlLkxpdGVyYWxzLlJPQURfVFJBTlNQT1JUX1JFTEFUSU9OU0hJUF9MQUJFTCk7DQoJCQl9DQoNCgkJCXB1YmxpYyB2b2lkIHdpZGdldERlZmF1bHRTZWxlY3RlZChTZWxlY3Rpb25FdmVudCBlKSB7DQoJCQl9DQoJCX0pOw0KDQoJCWFkZFBpcGVUcmFuc3BvcnRFZGdlLmFkZFNlbGVjdGlvbkxpc3RlbmVyKG5ldyBTZWxlY3Rpb25MaXN0ZW5lcigpIHsNCgkJCXB1YmxpYyB2b2lkIHdpZGdldFNlbGVjdGVkKFNlbGVjdGlvbkV2ZW50IGUpIHsNCgkJCQlhZGRFZGdlKFRyYW5zcG9ydFBhY2thZ2UuTGl0ZXJhbHMuUElQRV9UUkFOU1BPUlRfRURHRV9MQUJFTCk7DQoJCQl9DQoNCgkJCXB1YmxpYyB2b2lkIHdpZGdldERlZmF1bHRTZWxlY3RlZChTZWxlY3Rpb25FdmVudCBlKSB7DQoJCQl9DQoJCX0pOw0KCX0NCg0KCXByaXZhdGUgdm9pZCBjcmVhdGVSZW1vdmVOb2RlSXRlbShNZW51IG1lbnUpIHsNCgkJTWVudUl0ZW0gcmVtb3ZlTm9kZSA9IG5ldyBNZW51SXRlbShtZW51LCBTV1QuUFVTSCk7DQoNCgkJcmVtb3ZlTm9kZS5zZXRUZXh0KEdyYXBoRWRpdG9yTWVzc2FnZXMuZ2V0U3RyaW5nKCJyZW1vdmVOb2RlIikpOw0KDQoJCXJlbW92ZU5vZGUuYWRkU2VsZWN0aW9uTGlzdGVuZXIobmV3IFNlbGVjdGlvbkxpc3RlbmVyKCkgew0KDQoJCQlwdWJsaWMgdm9pZCB3aWRnZXRTZWxlY3RlZChTZWxlY3Rpb25FdmVudCBlKSB7DQoJCQkJR3JhcGhOb2RlIHNlbGVjdGVkTm9kZSA9IChHcmFwaE5vZGUpIHplc3RHcmFwaC5nZXRTZWxlY3Rpb24oKQ0KCQkJCQkJLmdldCgwKTsNCgkJCQlOb2RlRGF0YSBub2RlRGF0YSA9IChOb2RlRGF0YSkgc2VsZWN0ZWROb2RlLmdldERhdGEoKTsNCgkJCQlMaXN0PFVSST4gZWRnZXNUb1JlbW92ZSA9IG5ldyBBcnJheUxpc3Q8VVJJPigpOw0KDQoJCQkJZm9yIChNYXAuRW50cnk8VVJJLCBHcmFwaENvbm5lY3Rpb24+IGVudHJ5IDogZ3JhcGhDb25uZWN0aW9ucw0KCQkJCQkJLmVudHJ5U2V0KCkpIHsNCgkJCQkJaWYgKHNlbGVjdGVkTm9kZSA9PSBlbnRyeS5nZXRWYWx1ZSgpLmdldFNvdXJjZSgpDQoJCQkJCQkJfHwgc2VsZWN0ZWROb2RlID09IGVudHJ5LmdldFZhbHVlKCkNCgkJCQkJCQkJCS5nZXREZXN0aW5hdGlvbigpKSB7DQoJCQkJCQllbnRyeS5nZXRWYWx1ZSgpLmRpc3Bvc2UoKTsNCgkJCQkJCWVkZ2VzVG9SZW1vdmUuYWRkKGVudHJ5LmdldEtleSgpKTsNCgkJCQkJfQ0KCQkJCX0NCg0KCQkJCWZvciAoVVJJIGVkZ2VVUkkgOiBlZGdlc1RvUmVtb3ZlKSB7DQoJCQkJCWdyYXBoQ29ubmVjdGlvbnMucmVtb3ZlKGVkZ2VVUkkpOw0KCQkJCX0NCg0KCQkJCXplc3RHcmFwaC5zZXRTZWxlY3Rpb24obmV3IEdyYXBoSXRlbVtdIHt9KTsNCgkJCQlncmFwaE5vZGVzLnJlbW92ZShub2RlRGF0YS5nZXROb2RlVVJJKCkpOw0KCQkJCWdyYXBoUG9seWdvbnMucmVtb3ZlKG5vZGVEYXRhLmdldE5vZGVVUkkoKSk7DQoJCQkJc2VsZWN0ZWROb2RlLmRpc3Bvc2UoKTsNCgkJCQlyZW1vdmVOb2RlRnJvbVN0ZW1HcmFwaChub2RlRGF0YS5nZXROb2RlKCkpOw0KCQkJCXVwZGF0ZVNoZWxsKCk7DQoJCQl9DQoNCgkJCXB1YmxpYyB2b2lkIHdpZGdldERlZmF1bHRTZWxlY3RlZChTZWxlY3Rpb25FdmVudCBlKSB7DQoJCQl9DQoJCX0pOw0KCX0NCg0KCXByaXZhdGUgdm9pZCBjcmVhdGVSZW1vdmVMYWJlbEl0ZW0oTWVudSBtZW51KSB7DQoJCU1lbnVJdGVtIHJlbW92ZUxhYmVsSXRlbSA9IG5ldyBNZW51SXRlbShtZW51LCBTV1QuQ0FTQ0FERSk7DQoJCU1lbnUgcmVtb3ZlTGFiZWxNZW51ID0gbmV3IE1lbnUoemVzdEdyYXBoLmdldFNoZWxsKCksIFNXVC5EUk9QX0RPV04pOw0KCQlHcmFwaE5vZGUgc2VsZWN0ZWROb2RlID0gKEdyYXBoTm9kZSkgemVzdEdyYXBoLmdldFNlbGVjdGlvbigpLmdldCgwKTsNCgkJTm9kZURhdGEgbm9kZURhdGEgPSAoTm9kZURhdGEpIHNlbGVjdGVkTm9kZS5nZXREYXRhKCk7DQoNCgkJcmVtb3ZlTGFiZWxJdGVtLnNldFRleHQoR3JhcGhFZGl0b3JNZXNzYWdlcy5nZXRTdHJpbmcoInJlbW92ZUxhYmVsIikpOw0KCQlyZW1vdmVMYWJlbEl0ZW0uc2V0TWVudShyZW1vdmVMYWJlbE1lbnUpOw0KDQoJCWZvciAoTm9kZUxhYmVsIGxhYmVsIDogbm9kZURhdGEuZ2V0Tm9kZUxhYmVscygpKSB7DQoJCQlNZW51SXRlbSBpdGVtID0gbmV3IE1lbnVJdGVtKHJlbW92ZUxhYmVsTWVudSwgU1dULlBVU0gpOw0KDQoJCQlpZiAobGFiZWwgaW5zdGFuY2VvZiBBcmVhTGFiZWwpIHsNCgkJCQlpdGVtLnNldFRleHQoR3JhcGhFZGl0b3JNZXNzYWdlcy5nZXRTdHJpbmcoImFyZWFMYWJlbCIpKTsNCgkJCX0gZWxzZSBpZiAobGFiZWwgaW5zdGFuY2VvZiBQb3B1bGF0aW9uTGFiZWwpIHsNCgkJCQlpdGVtLnNldFRleHQoR3JhcGhFZGl0b3JNZXNzYWdlcy5nZXRTdHJpbmcoInBvcHVsYXRpb25MYWJlbCIpKTsNCgkJCX0NCg0KCQkJaXRlbS5hZGRTZWxlY3Rpb25MaXN0ZW5lcihuZXcgU2VsZWN0aW9uTGlzdGVuZXIoKSB7DQoNCgkJCQlwdWJsaWMgdm9pZCB3aWRnZXRTZWxlY3RlZChTZWxlY3Rpb25FdmVudCBlKSB7DQoJCQkJCU1lbnVJdGVtIGl0ZW0gPSAoTWVudUl0ZW0pIGUuZ2V0U291cmNlKCk7DQoJCQkJCU1lbnUgbWVudSA9IGl0ZW0uZ2V0UGFyZW50KCk7DQoJCQkJCUxpc3Q8TWVudUl0ZW0+IGFsbEl0ZW1zID0gQXJyYXlzLmFzTGlzdChtZW51LmdldEl0ZW1zKCkpOw0KCQkJCQlpbnQgaW5kZXggPSBhbGxJdGVtcy5pbmRleE9mKGl0ZW0pOw0KCQkJCQlMaXN0PD8+IHNlbGVjdGlvbiA9IHplc3RHcmFwaC5nZXRTZWxlY3Rpb24oKTsNCgkJCQkJR3JhcGhOb2RlIHNlbGVjdGVkTm9kZSA9IChHcmFwaE5vZGUpIHNlbGVjdGlvbi5nZXQoMCk7DQoJCQkJCU5vZGVEYXRhIG5vZGVEYXRhID0gKE5vZGVEYXRhKSBzZWxlY3RlZE5vZGUuZ2V0RGF0YSgpOw0KCQkJCQlOb2RlTGFiZWwgbGFiZWwgPSBub2RlRGF0YS5nZXROb2RlTGFiZWxzKCkuZ2V0KGluZGV4KTsNCg0KCQkJCQlyZW1vdmVOb2RlTGFiZWxGcm9tU3RlbUdyYXBoKGxhYmVsKTsNCgkJCQkJdXBkYXRlU2hlbGwoKTsNCgkJCQl9DQoNCgkJCQlwdWJsaWMgdm9pZCB3aWRnZXREZWZhdWx0U2VsZWN0ZWQoU2VsZWN0aW9uRXZlbnQgZSkgew0KCQkJCX0NCgkJCX0pOw0KCQl9DQoJfQ0KDQoJcHJpdmF0ZSB2b2lkIGNyZWF0ZVJlbW92ZUVkZ2VJdGVtKE1lbnUgbWVudSkgew0KCQlNZW51SXRlbSByZW1vdmVFZGdlID0gbmV3IE1lbnVJdGVtKG1lbnUsIFNXVC5QVVNIKTsNCg0KCQlyZW1vdmVFZGdlLnNldFRleHQoR3JhcGhFZGl0b3JNZXNzYWdlcy5nZXRTdHJpbmcoInJlbW92ZUVkZ2UiKSk7DQoNCgkJcmVtb3ZlRWRnZS5hZGRTZWxlY3Rpb25MaXN0ZW5lcihuZXcgU2VsZWN0aW9uTGlzdGVuZXIoKSB7DQoNCgkJCXB1YmxpYyB2b2lkIHdpZGdldFNlbGVjdGVkKFNlbGVjdGlvbkV2ZW50IGUpIHsNCgkJCQlMaXN0PD8+IHNlbGVjdGVkSXRlbXMgPSB6ZXN0R3JhcGguZ2V0U2VsZWN0aW9uKCk7DQoJCQkJR3JhcGhDb25uZWN0aW9uIHNlbGVjdGVkRWRnZSA9IChHcmFwaENvbm5lY3Rpb24pIHNlbGVjdGVkSXRlbXMNCgkJCQkJCS5nZXQoMCk7DQoJCQkJQ29ubmVjdGlvbkRhdGEgZWRnZURhdGEgPSAoQ29ubmVjdGlvbkRhdGEpIHNlbGVjdGVkRWRnZQ0KCQkJCQkJLmdldERhdGEoKTsNCg0KCQkJCXplc3RHcmFwaC5zZXRTZWxlY3Rpb24obmV3IEdyYXBoSXRlbVtdIHt9KTsNCgkJCQlzZWxlY3RlZEVkZ2UuZGlzcG9zZSgpOw0KCQkJCXJlbW92ZUVkZ2VGcm9tU3RlbUdyYXBoKGVkZ2VEYXRhLmdldEVkZ2UoKSk7DQoJCQkJdXBkYXRlU2hlbGwoKTsNCgkJCX0NCg0KCQkJcHVibGljIHZvaWQgd2lkZ2V0RGVmYXVsdFNlbGVjdGVkKFNlbGVjdGlvbkV2ZW50IGUpIHsNCgkJCX0NCgkJfSk7DQoJfQ0KDQoJcHJpdmF0ZSBHcmFwaE5vZGUgcHJvY2Vzc05vZGUoTm9kZSBub2RlKSB7DQoJCUxhdExvbmdQcm92aWRlciBsYXRMb25nUHJvdmlkZXIgPSAoTGF0TG9uZ1Byb3ZpZGVyKSBMYXRMb25nUHJvdmlkZXJBZGFwdGVyRmFjdG9yeS5JTlNUQU5DRQ0KCQkJCS5hZGFwdE5ldyhub2RlLCBMYXRMb25nUHJvdmlkZXIuY2xhc3MpOw0KCQlMaXN0PFNlZ21lbnQ+IHNlZ21lbnRzID0gbGF0TG9uZ1Byb3ZpZGVyLmdldExhdExvbmcoKS5nZXRTZWdtZW50cygpOw0KCQlTZXQ8UG9seWdvbj4gZGlzcGxheVBvbHlzID0gbmV3IEhhc2hTZXQ8UG9seWdvbj4oKTsNCgkJaW50IGdyYXBoTGlzdEluZGV4ID0gMDsNCgkJZG91YmxlIGxhcmdlc3RQb2x5Z29uQXJlYSA9IDAuMDsNCgkJUG9pbnQyRC5Eb3VibGUgY2VudGVyID0gbnVsbDsNCg0KCQlmb3IgKGludCBpID0gMDsgaSA8IGdyYXBoTGlzdC5zaXplKCk7IGkrKykgew0KCQkJaWYgKGdyYXBoTGlzdC5nZXQoaSkuZ2V0Tm9kZXMoKS5nZXQobm9kZS5nZXRVUkkoKSkgIT0gbnVsbCkgew0KCQkJCWdyYXBoTGlzdEluZGV4ID0gaTsNCgkJCQlicmVhazsNCgkJCX0NCgkJfQ0KDQoJCWZvciAoU2VnbWVudCBzZWdtZW50X3RtcCA6IHNlZ21lbnRzKSB7DQoJCQlQb2x5Z29uIGRQb2x5Z29uID0gbmV3IFBvbHlnb24oc2VnbWVudF90bXApOw0KDQoJCQlkaXNwbGF5UG9seXMuYWRkKGRQb2x5Z29uKTsNCg0KCQkJaWYgKGRQb2x5Z29uLmdldEFyZWEoKSA+IGxhcmdlc3RQb2x5Z29uQXJlYSkgew0KCQkJCWxhcmdlc3RQb2x5Z29uQXJlYSA9IGRQb2x5Z29uLmdldEFyZWEoKTsNCgkJCQljZW50ZXIgPSBkUG9seWdvbi5nZXRDZW50cm9pZCgpOw0KCQkJfQ0KCQl9DQoNCgkJbm9kZS5lQWRhcHRlcnMoKS5yZW1vdmUobGF0TG9uZ1Byb3ZpZGVyKTsNCg0KCQlpZiAoY2VudGVyICE9IG51bGwpIHsNCgkJCUdyYXBoTm9kZSBncmFwaENlbnRlck5vZGUgPSBuZXcgR3JhcGhOb2RlKHplc3RHcmFwaCwgU1dULk5PTkUsICIiKTsNCg0KCQkJZ3JhcGhDZW50ZXJOb2RlLnNldERhdGEobmV3IE5vZGVEYXRhKG5vZGUsIGNlbnRlci54LCBjZW50ZXIueSwgMCwNCgkJCQkJZ3JhcGhMaXN0SW5kZXgpKTsNCgkJCXNldE5vZGVDb2xvcihncmFwaENlbnRlck5vZGUpOw0KCQkJZ3JhcGhQb2x5Z29ucy5wdXQobm9kZS5nZXRVUkkoKSwgZGlzcGxheVBvbHlzKTsNCgkJCWdyYXBoTm9kZXMucHV0KG5vZGUuZ2V0VVJJKCksIGdyYXBoQ2VudGVyTm9kZSk7DQoNCgkJCXJldHVybiBncmFwaENlbnRlck5vZGU7DQoJCX0NCg0KCQlyZXR1cm4gbnVsbDsNCgl9DQoNCglwcml2YXRlIEdyYXBoQ29ubmVjdGlvbiBwcm9jZXNzRWRnZShFZGdlIGVkZ2UpIHsNCgkJVVJJIG5vZGVBVVJJID0gZWRnZS5nZXROb2RlQVVSSSgpOw0KCQlVUkkgbm9kZUJVUkkgPSBlZGdlLmdldE5vZGVCVVJJKCk7DQoJCVVSSSBlZGdlVVJJID0gZWRnZS5nZXRVUkkoKTsNCg0KCQlpZiAobm9kZUFVUkkudG9TdHJpbmcoKS5jb21wYXJlVG8obm9kZUJVUkkudG9TdHJpbmcoKSkgPiAwKSB7DQoJCQlVUkkgbWVtID0gbm9kZUFVUkk7DQoNCgkJCW5vZGVBVVJJID0gbm9kZUJVUkk7DQoJCQlub2RlQlVSSSA9IG1lbTsNCgkJfQ0KDQoJCWlmICgoZ3JhcGhOb2Rlcy5nZXQobm9kZUFVUkkpICE9IG51bGwpDQoJCQkJJiYgKGdyYXBoTm9kZXMuZ2V0KG5vZGVCVVJJKSAhPSBudWxsKSkgew0KCQkJR3JhcGhDb25uZWN0aW9uIGdjID0gbmV3IEdyYXBoQ29ubmVjdGlvbih6ZXN0R3JhcGgsIFNXVC5OT05FLA0KCQkJCQlncmFwaE5vZGVzLmdldChub2RlQVVSSSksIGdyYXBoTm9kZXMuZ2V0KG5vZGVCVVJJKSk7DQoNCgkJCWdjLnNldERhdGEobmV3IENvbm5lY3Rpb25EYXRhKGVkZ2UsIDApKTsNCgkJCXNldEVkZ2VDb2xvcihnYyk7DQoJCQlwcmV2ZW50T3ZlcmxheShnYyk7DQoJCQlncmFwaENvbm5lY3Rpb25zLnB1dChlZGdlVVJJLCBnYyk7DQoNCgkJCXJldHVybiBnYzsNCgkJfQ0KDQoJCXJldHVybiBudWxsOw0KCX0NCg0KCXByaXZhdGUgdm9pZCBhZGROb2RlTGFiZWwoRUNsYXNzIGxhYmVsQ2xhc3MpIHsNCgkJTGlzdDw/PiBzZWxlY3RlZEl0ZW1zID0gemVzdEdyYXBoLmdldFNlbGVjdGlvbigpOw0KCQlHcmFwaEl0ZW0gc2VsZWN0ZWROb2RlID0gKEdyYXBoSXRlbSkgc2VsZWN0ZWRJdGVtcy5nZXQoMCk7DQoJCU5vZGVEYXRhIG5vZGVEYXRhID0gKE5vZGVEYXRhKSBzZWxlY3RlZE5vZGUuZ2V0RGF0YSgpOw0KCQlOb2RlTGFiZWwgbGFiZWwgPSBudWxsOw0KDQoJCWlmIChsYWJlbENsYXNzID09IExhYmVsc1BhY2thZ2UuTGl0ZXJhbHMuQVJFQV9MQUJFTCkgew0KCQkJbGFiZWwgPSBMYWJlbHNGYWN0b3J5LmVJTlNUQU5DRS5jcmVhdGVBcmVhTGFiZWwoKTsNCgkJCSgoQXJlYUxhYmVsKSBsYWJlbCkuZ2V0Q3VycmVudEFyZWFWYWx1ZSgpLnNldEFyZWEoMC4wKTsNCgkJCWxhYmVsLnNldFVSSU9mSWRlbnRpZmlhYmxlVG9CZUxhYmVsZWQobm9kZURhdGEuZ2V0Tm9kZVVSSSgpKTsNCgkJCWxhYmVsLnNldE5vZGUobm9kZURhdGEuZ2V0Tm9kZSgpKTsNCgkJfSBlbHNlIGlmIChsYWJlbENsYXNzID09IExhYmVsc1BhY2thZ2UuTGl0ZXJhbHMuUE9QVUxBVElPTl9MQUJFTCkgew0KCQkJbGFiZWwgPSBMYWJlbHNGYWN0b3J5LmVJTlNUQU5DRS5jcmVhdGVQb3B1bGF0aW9uTGFiZWwoKTsNCgkJCSgoUG9wdWxhdGlvbkxhYmVsKSBsYWJlbCkuc2V0UG9wdWxhdGlvbklkZW50aWZpZXIoIiIpOw0KCQkJKChQb3B1bGF0aW9uTGFiZWwpIGxhYmVsKS5zZXRQb3B1bGF0ZWRBcmVhKDAuMCk7DQoJCQkoKFBvcHVsYXRpb25MYWJlbCkgbGFiZWwpLmdldEN1cnJlbnRQb3B1bGF0aW9uVmFsdWUoKS5zZXRDb3VudCgwKTsNCgkJCWxhYmVsLnNldFVSSU9mSWRlbnRpZmlhYmxlVG9CZUxhYmVsZWQobm9kZURhdGEuZ2V0Tm9kZVVSSSgpKTsNCgkJCWxhYmVsLnNldE5vZGUobm9kZURhdGEuZ2V0Tm9kZSgpKTsNCgkJfQ0KDQoJCWFkZE5vZGVMYWJlbFRvU3RlbUdyYXBoKGxhYmVsKTsNCgkJdXBkYXRlU2hlbGwobm9kZURhdGEuZ2V0Tm9kZUxhYmVscygpLnNpemUoKSAtIDEpOw0KCX0NCg0KCXByaXZhdGUgdm9pZCBhZGRFZGdlKEVDbGFzcyBsYWJlbENsYXNzKSB7DQoJCUxpc3Q8Pz4gc2VsZWN0ZWRJdGVtcyA9IHplc3RHcmFwaC5nZXRTZWxlY3Rpb24oKTsNCgkJR3JhcGhOb2RlIHNlbGVjdGVkTm9kZUEgPSAoR3JhcGhOb2RlKSBzZWxlY3RlZEl0ZW1zLmdldCgwKTsNCgkJR3JhcGhOb2RlIHNlbGVjdGVkTm9kZUIgPSAoR3JhcGhOb2RlKSBzZWxlY3RlZEl0ZW1zLmdldCgxKTsNCgkJTm9kZURhdGEgbm9kZURhdGFBID0gKE5vZGVEYXRhKSBzZWxlY3RlZE5vZGVBLmdldERhdGEoKTsNCgkJTm9kZURhdGEgbm9kZURhdGFCID0gKE5vZGVEYXRhKSBzZWxlY3RlZE5vZGVCLmdldERhdGEoKTsNCgkJTm9kZSBub2RlQSA9IG5vZGVEYXRhQS5nZXROb2RlKCk7DQoJCU5vZGUgbm9kZUIgPSBub2RlRGF0YUIuZ2V0Tm9kZSgpOw0KCQlFZGdlIGVkZ2UgPSBudWxsOw0KDQoJCWlmIChsYWJlbENsYXNzID09IEVkZ2VzUGFja2FnZS5MaXRlcmFscy5NSUdSQVRJT05fRURHRV9MQUJFTCkgew0KCQkJZWRnZSA9IGNyZWF0ZU1pZ3JhdGlvbkVkZ2Uobm9kZUEsIG5vZGVCKTsNCgkJfSBlbHNlIGlmIChsYWJlbENsYXNzID09IExhYmVsc1BhY2thZ2UuTGl0ZXJhbHMuQ09NTU9OX0JPUkRFUl9SRUxBVElPTlNISVBfTEFCRUwpIHsNCgkJCWVkZ2UgPSBjcmVhdGVDb21tb25Cb3JkZXJFZGdlKG5vZGVBLCBub2RlQik7DQoJCX0gZWxzZSBpZiAobGFiZWxDbGFzcyA9PSBMYWJlbHNQYWNrYWdlLkxpdGVyYWxzLlJPQURfVFJBTlNQT1JUX1JFTEFUSU9OU0hJUF9MQUJFTCkgew0KCQkJZWRnZSA9IGNyZWF0ZVJvYWRUcmFuc3BvcnRFZGdlKG5vZGVBLCBub2RlQik7DQoJCX0gZWxzZSBpZiAobGFiZWxDbGFzcyA9PSBUcmFuc3BvcnRQYWNrYWdlLkxpdGVyYWxzLlBJUEVfVFJBTlNQT1JUX0VER0VfTEFCRUwpIHsNCgkJCWVkZ2UgPSBjcmVhdGVQaXBlVHJhbnNwb3J0RWRnZShub2RlQSwgbm9kZUIpOw0KCQl9DQoNCgkJR3JhcGhDb25uZWN0aW9uIGdjID0gcHJvY2Vzc0VkZ2UoZWRnZSk7DQoNCgkJYWRkRWRnZVRvU3RlbUdyYXBoKGVkZ2UpOw0KCQl6ZXN0R3JhcGguc2V0U2VsZWN0aW9uKG5ldyBHcmFwaEl0ZW1bXSB7IGdjIH0pOw0KCQl1cGRhdGVTaGVsbCgpOw0KCX0NCg0KCXByaXZhdGUgRWRnZSBjcmVhdGVDb21tb25Cb3JkZXJFZGdlKE5vZGUgbm9kZUEsIE5vZGUgbm9kZUIpIHsNCgkJRWRnZSBjYnJFZGdlID0gRWRnZUltcGwuY3JlYXRlRWRnZShub2RlQSwgbm9kZUIpOw0KCQlDb21tb25Cb3JkZXJSZWxhdGlvbnNoaXBMYWJlbCBjYnJMYWJlbCA9IExhYmVsc0ZhY3RvcnkuZUlOU1RBTkNFDQoJCQkJLmNyZWF0ZUNvbW1vbkJvcmRlclJlbGF0aW9uc2hpcExhYmVsKCk7DQoJCUNvbW1vbkJvcmRlclJlbGF0aW9uc2hpcExhYmVsVmFsdWUgY2JyTGFiZWxWYWx1ZSA9IChDb21tb25Cb3JkZXJSZWxhdGlvbnNoaXBMYWJlbFZhbHVlKSBjYnJMYWJlbA0KCQkJCS5nZXRDdXJyZW50VmFsdWUoKTsNCg0KCQljYnJFZGdlLnNldFVSSShnZXRSYW5kb21VUkkoRWRnZS5VUklfVFlQRV9FREdFX1NFR01FTlQNCgkJCQkrICIvcmVsYXRpb25zaGlwL2NvbW1vbmJvcmRlciIpKTsNCgkJY2JyRWRnZS5zZXRMYWJlbChjYnJMYWJlbCk7DQoJCWNickVkZ2UuZ2V0RHVibGluQ29yZSgpLnNldFRpdGxlKA0KCQkJCWNyZWF0ZUVkZ2VUaXRsZShub2RlQSwgbm9kZUIsICJFZGdlIiwgZmFsc2UpKTsNCgkJY2JyTGFiZWwuc2V0VVJJT2ZJZGVudGlmaWFibGVUb0JlTGFiZWxlZChjYnJFZGdlLmdldFVSSSgpKTsNCgkJY2JyTGFiZWxWYWx1ZS5zZXRCb3JkZXJMZW5ndGgoMC4wKTsNCg0KCQlyZXR1cm4gY2JyRWRnZTsNCgl9DQoNCglwcml2YXRlIE1pZ3JhdGlvbkVkZ2UgY3JlYXRlTWlncmF0aW9uRWRnZShOb2RlIG5vZGVBLCBOb2RlIG5vZGVCKSB7DQoJCU1pZ3JhdGlvbkVkZ2UgbUVkZ2UgPSBFZGdlc0ZhY3RvcnkuZUlOU1RBTkNFLmNyZWF0ZU1pZ3JhdGlvbkVkZ2UoKTsNCg0KCQltRWRnZS5zZXRVUkkoZ2V0UmFuZG9tVVJJKE1pZ3JhdGlvbkVkZ2UuVVJJX1RZUEVfTUlHUkFUSU9OX0VER0VfU0VHTUVOVCkpOw0KCQltRWRnZS5zZXROb2RlQVVSSShub2RlQS5nZXRVUkkoKSk7DQoJCW1FZGdlLnNldE5vZGVCVVJJKG5vZGVCLmdldFVSSSgpKTsNCgkJbUVkZ2UuZ2V0TGFiZWwoKS5zZXRVUklPZklkZW50aWZpYWJsZVRvQmVMYWJlbGVkKG1FZGdlLmdldFVSSSgpKTsNCgkJbUVkZ2UuZ2V0TGFiZWwoKS5nZXRDdXJyZW50VmFsdWUoKS5zZXRNaWdyYXRpb25SYXRlKDAuMCk7DQoJCW1FZGdlLmdldER1YmxpbkNvcmUoKS5zZXRUaXRsZSgNCgkJCQljcmVhdGVFZGdlVGl0bGUobm9kZUEsIG5vZGVCLCAiTWlncmF0aW9uRWRnZSIsIHRydWUpKTsNCgkJbUVkZ2Uuc2V0UG9wdWxhdGlvbklkZW50aWZpZXIoIiIpOw0KDQoJCXJldHVybiBtRWRnZTsNCgl9DQoNCglwcml2YXRlIEVkZ2UgY3JlYXRlUm9hZFRyYW5zcG9ydEVkZ2UoTm9kZSBub2RlQSwgTm9kZSBub2RlQikgew0KCQlFZGdlIGVkZ2UgPSBSb2FkVHJhbnNwb3J0UmVsYXRpb25zaGlwTGFiZWxJbXBsDQoJCQkJLmNyZWF0ZVJvYWRUcmFuc3BvcnRSZWxhdGlvbnNoaXAobm9kZUEsIG5vZGVCLCAiIiwgIiIsIDApOw0KDQoJCWVkZ2Uuc2V0VVJJKGdldFJhbmRvbVVSSShFZGdlLlVSSV9UWVBFX0VER0VfU0VHTUVOVCArICIvcm9hZCIpKTsNCgkJZWRnZS5nZXRMYWJlbCgpLnNldFVSSU9mSWRlbnRpZmlhYmxlVG9CZUxhYmVsZWQoZWRnZS5nZXRVUkkoKSk7DQoJCWVkZ2UuZ2V0RHVibGluQ29yZSgpLnNldFRpdGxlKA0KCQkJCWNyZWF0ZUVkZ2VUaXRsZShub2RlQSwgbm9kZUIsICJSb2FkRWRnZSIsIGZhbHNlKSk7DQoNCgkJcmV0dXJuIGVkZ2U7DQoJfQ0KDQoJcHJpdmF0ZSBFZGdlIGNyZWF0ZVBpcGVUcmFuc3BvcnRFZGdlKE5vZGUgbm9kZUEsIE5vZGUgbm9kZUIpIHsNCgkJUGlwZVRyYW5zcG9ydEVkZ2UgZWRnZSA9IFRyYW5zcG9ydEZhY3RvcnkuZUlOU1RBTkNFDQoJCQkJLmNyZWF0ZVBpcGVUcmFuc3BvcnRFZGdlKCk7DQoJCVBpcGVUcmFuc3BvcnRFZGdlTGFiZWxWYWx1ZSBlZGdlVmFsdWUgPSBUcmFuc3BvcnRGYWN0b3J5LmVJTlNUQU5DRQ0KCQkJCS5jcmVhdGVQaXBlVHJhbnNwb3J0RWRnZUxhYmVsVmFsdWUoKTsNCg0KCQllZGdlLnNldFVSSShnZXRSYW5kb21VUkkoUGlwZVRyYW5zcG9ydEVkZ2VJbXBsLlVSSV9UWVBFX1BJUEVfVFJBTlNQT1JUX0VER0VfU0VHTUVOVCkpOw0KCQllZGdlLnNldEEobm9kZUEpOw0KCQllZGdlLnNldEIobm9kZUIpOw0KCQllZGdlLnNldE5vZGVBVVJJKG5vZGVBLmdldFVSSSgpKTsNCgkJZWRnZS5zZXROb2RlQlVSSShub2RlQi5nZXRVUkkoKSk7DQoJCWVkZ2UuZ2V0TGFiZWwoKS5zZXRVUklPZklkZW50aWZpYWJsZVRvQmVMYWJlbGVkKGVkZ2UuZ2V0VVJJKCkpOw0KCQllZGdlLmdldExhYmVsKCkuc2V0Q3VycmVudFZhbHVlKGVkZ2VWYWx1ZSk7DQoJCWVkZ2UuZ2V0RHVibGluQ29yZSgpLnNldFRpdGxlKA0KCQkJCWNyZWF0ZUVkZ2VUaXRsZShub2RlQSwgbm9kZUIsICJQaXBlIiwgdHJ1ZSkpOw0KCQllZGdlLnNldFBvcHVsYXRpb25JZGVudGlmaWVyKCIiKTsNCgkJZWRnZVZhbHVlLnNldE1heEZsb3coMC4wKTsNCgkJZWRnZVZhbHVlLnNldFRpbWVQZXJpb2QoODY0MDAwMDApOw0KDQoJCXJldHVybiBlZGdlOw0KCX0NCg0KCXByaXZhdGUgdm9pZCBhZGROb2RlVG9TdGVtR3JhcGgoTm9kZSBub2RlKSB7DQoJCXN0ZW1HcmFwaC5nZXROb2RlcygpLnB1dChub2RlLmdldFVSSSgpLCBub2RlKTsNCgkJZ3JhcGhMaXN0LmdldCgwKS5nZXROb2RlcygpDQoJCQkJLnB1dChub2RlLmdldFVSSSgpLCAoTm9kZSkgRWNvcmVVdGlsLmNvcHkobm9kZSkpOw0KCX0NCg0KCXByaXZhdGUgdm9pZCBhZGRFZGdlVG9TdGVtR3JhcGgoRWRnZSBlZGdlKSB7DQoJCXN0ZW1HcmFwaC5nZXRFZGdlcygpLnB1dChlZGdlLmdldFVSSSgpLCBlZGdlKTsNCg0KCQlmb3IgKEdyYXBoIGdyYXBoIDogZ3JhcGhMaXN0KSB7DQoJCQlpZiAoZ3JhcGguZ2V0Tm9kZShlZGdlLmdldE5vZGVBVVJJKCkpICE9IG51bGwpIHsNCgkJCQlncmFwaC5nZXRFZGdlcygpLnB1dChlZGdlLmdldFVSSSgpLCBFY29yZVV0aWwuY29weShlZGdlKSk7DQoJCQl9DQoJCX0NCgl9DQoNCglwcml2YXRlIHZvaWQgYWRkTm9kZUxhYmVsVG9TdGVtR3JhcGgoTm9kZUxhYmVsIG5vZGVMYWJlbCkgew0KCQlOb2RlTGFiZWwgbm9kZUxhYmVsQ29weSA9IEVjb3JlVXRpbC5jb3B5KG5vZGVMYWJlbCk7DQoJCVVSSSBub2RlVVJJID0gbm9kZUxhYmVsLmdldFVSSU9mSWRlbnRpZmlhYmxlVG9CZUxhYmVsZWQoKTsNCg0KCQlzdGVtR3JhcGguZ2V0Tm9kZUxhYmVscygpLnB1dChub2RlTGFiZWwuZ2V0VVJJKCksIG5vZGVMYWJlbCk7DQoJCXN0ZW1HcmFwaC5nZXROb2RlKG5vZGVVUkkpLmdldExhYmVscygpLmFkZChub2RlTGFiZWwpOw0KDQoJCWZvciAoR3JhcGggZ3JhcGggOiBncmFwaExpc3QpIHsNCgkJCWlmIChncmFwaC5nZXROb2RlKG5vZGVVUkkpICE9IG51bGwpIHsNCgkJCQlncmFwaC5nZXROb2RlTGFiZWxzKCkucHV0KG5vZGVMYWJlbC5nZXRVUkkoKSwgbm9kZUxhYmVsQ29weSk7DQoJCQkJZ3JhcGguZ2V0Tm9kZShub2RlVVJJKS5nZXRMYWJlbHMoKS5hZGQobm9kZUxhYmVsQ29weSk7DQoJCQl9DQoJCX0NCgl9DQoNCglwcml2YXRlIHZvaWQgcmVtb3ZlTm9kZUZyb21TdGVtR3JhcGgoTm9kZSBub2RlKSB7DQoJCVVSSSBub2RlVVJJID0gbm9kZS5nZXRVUkkoKTsNCgkJTGlzdDxVUkk+IG5vZGVMYWJlbHNUb1JlbW92ZSA9IG5ldyBBcnJheUxpc3Q8VVJJPigpOw0KCQlMaXN0PFVSST4gZWRnZXNUb1JlbW92ZSA9IG5ldyBBcnJheUxpc3Q8VVJJPigpOw0KDQoJCWZvciAoTm9kZUxhYmVsIG5vZGVMYWJlbCA6IG5vZGUuZ2V0TGFiZWxzKCkpIHsNCgkJCW5vZGVMYWJlbHNUb1JlbW92ZS5hZGQobm9kZUxhYmVsLmdldFVSSSgpKTsNCgkJfQ0KDQoJCWZvciAoRWRnZSBlZGdlIDogc3RlbUdyYXBoLmdldEVkZ2VzKCkudmFsdWVzKCkpIHsNCgkJCWlmIChlZGdlLmdldE5vZGVBVVJJKCkuZXF1YWxzKG5vZGVVUkkpDQoJCQkJCXx8IGVkZ2UuZ2V0Tm9kZUJVUkkoKS5lcXVhbHMobm9kZVVSSSkpIHsNCgkJCQllZGdlc1RvUmVtb3ZlLmFkZChlZGdlLmdldFVSSSgpKTsNCgkJCX0NCgkJfQ0KDQoJCWZvciAoVVJJIG5vZGVMYWJlbFVSSSA6IG5vZGVMYWJlbHNUb1JlbW92ZSkgew0KCQkJc3RlbUdyYXBoLmdldE5vZGVMYWJlbHMoKS5yZW1vdmVLZXkobm9kZUxhYmVsVVJJKTsNCgkJfQ0KDQoJCWZvciAoVVJJIGVkZ2VVUkkgOiBlZGdlc1RvUmVtb3ZlKSB7DQoJCQlzdGVtR3JhcGguZ2V0RWRnZXMoKS5yZW1vdmVLZXkoZWRnZVVSSSk7DQoJCX0NCg0KCQlzdGVtR3JhcGguZ2V0Tm9kZXMoKS5yZW1vdmVLZXkobm9kZVVSSSk7DQoNCgkJZm9yIChHcmFwaCBncmFwaCA6IGdyYXBoTGlzdCkgew0KCQkJZm9yIChVUkkgbm9kZUxhYmVsVVJJIDogbm9kZUxhYmVsc1RvUmVtb3ZlKSB7DQoJCQkJZ3JhcGguZ2V0Tm9kZUxhYmVscygpLnJlbW92ZUtleShub2RlTGFiZWxVUkkpOw0KCQkJfQ0KDQoJCQlmb3IgKFVSSSBlZGdlVVJJIDogZWRnZXNUb1JlbW92ZSkgew0KCQkJCWdyYXBoLmdldEVkZ2VzKCkucmVtb3ZlS2V5KGVkZ2VVUkkpOw0KCQkJfQ0KDQoJCQlncmFwaC5nZXROb2RlcygpLnJlbW92ZUtleShub2RlVVJJKTsNCgkJfQ0KCX0NCg0KCXByaXZhdGUgdm9pZCByZW1vdmVFZGdlRnJvbVN0ZW1HcmFwaChFZGdlIGVkZ2UpIHsNCgkJVVJJIGVkZ2VVUkkgPSBlZGdlLmdldFVSSSgpOw0KDQoJCXN0ZW1HcmFwaC5nZXRFZGdlcygpLnJlbW92ZUtleShlZGdlVVJJKTsNCg0KCQlmb3IgKEdyYXBoIGdyYXBoIDogZ3JhcGhMaXN0KSB7DQoJCQlncmFwaC5nZXRFZGdlcygpLnJlbW92ZUtleShlZGdlVVJJKTsNCgkJfQ0KCX0NCg0KCXByaXZhdGUgdm9pZCByZW1vdmVOb2RlTGFiZWxGcm9tU3RlbUdyYXBoKE5vZGVMYWJlbCBub2RlTGFiZWwpIHsNCgkJVVJJIGxhYmVsVVJJID0gbm9kZUxhYmVsLmdldFVSSSgpOw0KCQlVUkkgbm9kZVVSSSA9IG5vZGVMYWJlbC5nZXRVUklPZklkZW50aWZpYWJsZVRvQmVMYWJlbGVkKCk7DQoNCgkJc3RlbUdyYXBoLmdldE5vZGUobm9kZVVSSSkuZ2V0TGFiZWxzKCkNCgkJCQkucmVtb3ZlKHN0ZW1HcmFwaC5nZXROb2RlTGFiZWwobGFiZWxVUkkpKTsNCgkJc3RlbUdyYXBoLmdldE5vZGVMYWJlbHMoKS5yZW1vdmVLZXkobGFiZWxVUkkpOw0KDQoJCU5vZGVMYWJlbCBsYWJlbFRvUmVtb3ZlID0gbnVsbDsNCg0KCQlmb3IgKEdyYXBoIGdyYXBoIDogZ3JhcGhMaXN0KSB7DQoJCQlsYWJlbFRvUmVtb3ZlID0gZ3JhcGguZ2V0Tm9kZUxhYmVscygpLnJlbW92ZUtleShsYWJlbFVSSSk7DQoJCX0NCg0KCQlmb3IgKEdyYXBoIGdyYXBoIDogZ3JhcGhMaXN0KSB7DQoJCQlpZiAoZ3JhcGguZ2V0Tm9kZXMoKS5jb250YWluc0tleShub2RlVVJJKSkgew0KCQkJCWdyYXBoLmdldE5vZGUobm9kZVVSSSkuZ2V0TGFiZWxzKCkucmVtb3ZlKGxhYmVsVG9SZW1vdmUpOw0KCQkJfQ0KCQl9DQoJfQ0KDQoJcHJpdmF0ZSB2b2lkIHNhdmVTdGVtR3JhcGhBcygpIHsNCgkJU2F2ZUluUHJvamVjdERpYWxvZyBzYXZlQXNEaWFsb2cgPSBuZXcgU2F2ZUluUHJvamVjdERpYWxvZyhBY3RpdmF0b3INCgkJCQkuZ2V0RGVmYXVsdCgpLmdldFdvcmtiZW5jaCgpLmdldERpc3BsYXkoKS5nZXRBY3RpdmVTaGVsbCgpKTsNCg0KCQlzYXZlQXNEaWFsb2cub3BlbigpOw0KDQoJCWlmIChzYXZlQXNEaWFsb2cuZ2V0UmVzdWx0KCkgPT0gbnVsbCkgew0KCQkJcmV0dXJuOw0KCQl9DQoNCgkJSUZpbGUgc2F2ZUFzRmlsZSA9IFJlc291cmNlc1BsdWdpbi5nZXRXb3Jrc3BhY2UoKS5nZXRSb290KCkNCgkJCQkuZ2V0RmlsZShzYXZlQXNEaWFsb2cuZ2V0UmVzdWx0KCkpOw0KDQoJCXNhdmVHcmFwaChzdGVtR3JhcGgsIHNhdmVBc0ZpbGUuZ2V0UHJvamVjdCgpLA0KCQkJCVVSSS5jcmVhdGVQbGF0Zm9ybVJlc291cmNlVVJJKHNhdmVBc0ZpbGUuZ2V0RnVsbFBhdGgoKQ0KCQkJCQkJLnRvU3RyaW5nKCksIGZhbHNlKSk7DQoNCgkJdHJ5IHsNCgkJCXByb2plY3QucmVmcmVzaExvY2FsKElSZXNvdXJjZS5ERVBUSF9JTkZJTklURSwgbnVsbCk7DQoJCX0gY2F0Y2ggKENvcmVFeGNlcHRpb24gZSkgew0KCQkJQWN0aXZhdG9yLmxvZ0Vycm9yKGUuZ2V0TWVzc2FnZSgpLCBlKTsNCgkJfQ0KCX0NCg0KCXByaXZhdGUgdm9pZCBzYXZlR3JhcGhMaXN0KCkgew0KCQlmb3IgKE1vZGVsIG1vZGVsIDogbW9kZWxMaXN0KSB7DQoJCQlFTGlzdDxHcmFwaD4gbW9kZWxHcmFwaHMgPSBtb2RlbC5nZXRHcmFwaHMoKTsNCg0KCQkJZm9yIChpbnQgaSA9IDA7IGkgPCBtb2RlbEdyYXBocy5zaXplKCk7IGkrKykgew0KCQkJCVVSSSBncmFwaFVSSSA9IG1vZGVsR3JhcGhzLmdldChpKS5nZXRVUkkoKTsNCg0KCQkJCWZvciAoR3JhcGggZ3JhcGggOiBncmFwaExpc3QpIHsNCgkJCQkJaWYgKGdyYXBoLmdldFVSSSgpLmVxdWFscyhncmFwaFVSSSkpIHsNCgkJCQkJCW1vZGVsR3JhcGhzLnNldChpLCBncmFwaCk7DQoJCQkJCQlicmVhazsNCgkJCQkJfQ0KCQkJCX0NCgkJCX0NCgkJfQ0KDQoJCWZvciAoR3JhcGggZ3JhcGggOiBncmFwaExpc3QpIHsNCgkJCXNhdmVHcmFwaChncmFwaCwgcHJvamVjdCwgZ3JhcGguZ2V0VVJJKCkpOw0KCQl9DQoNCgkJZm9yIChNb2RlbCBtb2RlbCA6IG1vZGVsTGlzdCkgew0KCQkJaWYgKG1vZGVsLmdldFVSSSgpLmlzUGxhdGZvcm1SZXNvdXJjZSgpKSB7DQoJCQkJTGlzdDxJZGVudGlmaWFibGU+IGlkZW50aWZpYWJsZXMgPSBuZXcgQXJyYXlMaXN0PElkZW50aWZpYWJsZT4oKTsNCgkJCQlVUkkgdXJpID0gbW9kZWwuZ2V0VVJJKCk7DQoNCgkJCQlpZGVudGlmaWFibGVzLmFkZChtb2RlbCk7DQoJCQkJYWRkQ29udGFpbm1lbnRzKGlkZW50aWZpYWJsZXMsIG1vZGVsKTsNCg0KCQkJCXRyeSB7DQoJCQkJCVV0aWxpdHkuc2VyaWFsaXplSWRlbnRpZmlhYmxlcyhpZGVudGlmaWFibGVzLCB1cmkpOw0KCQkJCX0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsNCgkJCQkJQWN0aXZhdG9yLmxvZ0Vycm9yKGUuZ2V0TWVzc2FnZSgpLCBlKTsNCgkJCQl9DQoJCQl9DQoJCX0NCg0KCQl0cnkgew0KCQkJcHJvamVjdC5yZWZyZXNoTG9jYWwoSVJlc291cmNlLkRFUFRIX0lORklOSVRFLCBudWxsKTsNCgkJfSBjYXRjaCAoQ29yZUV4Y2VwdGlvbiBlKSB7DQoJCQlBY3RpdmF0b3IubG9nRXJyb3IoZS5nZXRNZXNzYWdlKCksIGUpOw0KCQl9DQoJfQ0KDQoJcHJpdmF0ZSB2b2lkIGFkZENvbnRhaW5tZW50cyhMaXN0PElkZW50aWZpYWJsZT4gaWRlbnRpZmlhYmxlcywgTW9kZWwgbW9kZWwpIHsNCgkJZm9yIChHcmFwaCBzdWJHcmFwaCA6IG1vZGVsLmdldEdyYXBocygpKSB7DQoJCQlpZiAoIXN1YkdyYXBoLmdldFVSSSgpLmlzUGxhdGZvcm1SZXNvdXJjZSgpKSB7DQoJCQkJaWRlbnRpZmlhYmxlcy5hZGQoc3ViR3JhcGgpOw0KCQkJfQ0KCQl9DQoNCgkJZm9yIChNb2RlbCBzdWJNb2RlbCA6IG1vZGVsLmdldE1vZGVscygpKSB7DQoJCQlpZiAoIXN1Yk1vZGVsLmdldFVSSSgpLmlzUGxhdGZvcm1SZXNvdXJjZSgpKSB7DQoJCQkJaWRlbnRpZmlhYmxlcy5hZGQoc3ViTW9kZWwpOw0KCQkJCWFkZENvbnRhaW5tZW50cyhpZGVudGlmaWFibGVzLCBzdWJNb2RlbCk7DQoJCQl9DQoJCX0NCgl9DQoNCglwcml2YXRlIHZvaWQgc2F2ZUdyYXBoKEdyYXBoIGdyYXBoLCBJUHJvamVjdCBwcm9qZWN0LCBVUkkgbmV3VVJJKSB7DQoJCWdyYXBoLnNldFVSSShuZXdVUkkpOw0KCQl1cGRhdGVHcmFwaChncmFwaCk7DQoJCWdyYXBoLmdldER1YmxpbkNvcmUoKS5zZXRUaXRsZSgiIik7DQoNCgkJU3RyaW5nIGZpbGVCYXNlTmFtZSA9IGdyYXBoLmdldFVSSSgpLmxhc3RTZWdtZW50KCkNCgkJCQkuc3Vic3RyaW5nKDAsIGdyYXBoLmdldFVSSSgpLmxhc3RTZWdtZW50KCkubGFzdEluZGV4T2YoIi4iKSk7DQoJCVN0cmluZyB0YWlsID0gcHJvamVjdC5nZXROYW1lKCkgKyAiLy5nbWwvIiArIGZpbGVCYXNlTmFtZSArICJfTUFQLnhtbCI7DQoJCU1hcDxVUkksIFNldDxQb2x5Z29uPj4gY3VycmVudEdyYXBoUG9seWdvbnMgPSBuZXcgSGFzaE1hcDxVUkksIFNldDxQb2x5Z29uPj4oKTsNCg0KCQlpZiAoIXByb2plY3QuZ2V0Rm9sZGVyKCIuZ21sIikuZXhpc3RzKCkpIHsNCgkJCUlQcm9ncmVzc01vbml0b3IgbW9uaXRvciA9IG5ldyBOdWxsUHJvZ3Jlc3NNb25pdG9yKCk7DQoNCgkJCXRyeSB7DQoJCQkJcHJvamVjdC5nZXRGb2xkZXIoIi5nbWwiKS5jcmVhdGUoZmFsc2UsIHRydWUsIG1vbml0b3IpOw0KCQkJfSBjYXRjaCAoQ29yZUV4Y2VwdGlvbiBlKSB7DQoJCQkJQWN0aXZhdG9yLmxvZ0Vycm9yKGUuZ2V0TWVzc2FnZSgpLCBlKTsNCgkJCX0gZmluYWxseSB7DQoJCQkJbW9uaXRvci5kb25lKCk7DQoJCQl9DQoJCX0NCg0KCQlmb3IgKE5vZGUgbiA6IGdyYXBoLmdldE5vZGVzKCkudmFsdWVzKCkpIHsNCgkJCVNldDxQb2x5Z29uPiBkaXNwbGF5UG9seWdvbnMgPSBncmFwaFBvbHlnb25zLmdldChuLmdldFVSSSgpKTsNCgkJCVN0cmluZyBzcGF0aWFsU3RyaW5nID0gbi5nZXREdWJsaW5Db3JlKCkuZ2V0U3BhdGlhbCgpOw0KDQoJCQlpZiAoc3BhdGlhbFN0cmluZw0KCQkJCQkuY29udGFpbnMoU3BhdGlhbFByb3ZpZGVyQWRhcHRlci5TVEVNX1NQQVRJQUxfU0NIRU1FX1BSRUZJWA0KCQkJCQkJCSsgImlubGluZSIpKSB7DQoJCQkJTGF0TG9uZyBsYXRsb24gPSBuZXcgTGF0TG9uZygpOw0KDQoJCQkJZm9yIChQb2x5Z29uIHAgOiBkaXNwbGF5UG9seWdvbnMpIHsNCgkJCQkJU2VnbWVudEJ1aWxkZXIgc2IgPSBuZXcgU2VnbWVudEJ1aWxkZXIoKTsNCg0KCQkJCQlmb3IgKGludCBpID0gMDsgaSA8IHAubnBvaW50czsgaSsrKSB7DQoJCQkJCQlzYi5hZGQocC55W2ldLCBwLnhbaV0pOw0KCQkJCQl9DQoNCgkJCQkJbGF0bG9uLmFkZChzYi50b1NlZ21lbnQoKSk7DQoJCQkJfQ0KDQoJCQkJbi5nZXREdWJsaW5Db3JlKCkuc2V0U3BhdGlhbCgNCgkJCQkJCUlubGluZUxhdExvbmdEYXRhUHJvdmlkZXINCgkJCQkJCQkJLmNyZWF0ZVNwYXRpYWxJbmxpbmVVUklTdHJpbmcobGF0bG9uKSk7DQoJCQl9IGVsc2UgaWYgKHNwYXRpYWxTdHJpbmcNCgkJCQkJLmNvbnRhaW5zKFNwYXRpYWxQcm92aWRlckFkYXB0ZXIuU1RFTV9TUEFUSUFMX1NDSEVNRV9QUkVGSVgNCgkJCQkJCQkrICJwbGF0Zm9ybSIpKSB7DQoJCQkJU3RyaW5nIG5ld1NwYXRpYWxTdHJpbmcgPSBTcGF0aWFsUHJvdmlkZXJBZGFwdGVyLlNURU1fU1BBVElBTF9TQ0hFTUVfUFJFRklYDQoJCQkJCQkrICJwbGF0Zm9ybTovcmVzb3VyY2UvIg0KCQkJCQkJKyB0YWlsDQoJCQkJCQkrICIjIg0KCQkJCQkJKyBuLmdldFVSSSgpLmxhc3RTZWdtZW50KCk7DQoNCgkJCQluLmdldER1YmxpbkNvcmUoKS5zZXRTcGF0aWFsKG5ld1NwYXRpYWxTdHJpbmcpOw0KCQkJCWN1cnJlbnRHcmFwaFBvbHlnb25zLnB1dChuLmdldFVSSSgpLA0KCQkJCQkJZ3JhcGhQb2x5Z29ucy5nZXQobi5nZXRVUkkoKSkpOw0KCQkJfQ0KCQl9DQoNCgkJaWYgKCFjdXJyZW50R3JhcGhQb2x5Z29ucy5pc0VtcHR5KCkpIHsNCgkJCVN0cmluZyBzcGF0aWFsU3RyaW5nID0gU3BhdGlhbFByb3ZpZGVyQWRhcHRlci5TVEVNX1NQQVRJQUxfU0NIRU1FX1BSRUZJWA0KCQkJCQkrICJwbGF0Zm9ybTovcmVzb3VyY2UvIiArIHRhaWw7DQoJCQlTdHJpbmcgZmlsZU5hbWUgPSBSZXNvdXJjZXNQbHVnaW4uZ2V0V29ya3NwYWNlKCkuZ2V0Um9vdCgpDQoJCQkJCS5nZXRMb2NhdGlvbigpLnRvU3RyaW5nKCkuY29uY2F0KCIvIiArIHRhaWwpOw0KDQoJCQlTcGF0aWFsR21sRXhwb3J0ZXIud3JpdGVHTUwoZmlsZU5hbWUsIGdyYXBoLmdldFVSSSgpLA0KCQkJCQljdXJyZW50R3JhcGhQb2x5Z29ucyk7DQoJCQlncmFwaC5nZXREdWJsaW5Db3JlKCkuc2V0U3BhdGlhbChzcGF0aWFsU3RyaW5nKTsNCgkJfQ0KDQoJCWlmIChncmFwaC5nZXRVUkkoKS5pc1BsYXRmb3JtUmVzb3VyY2UoKSkgew0KCQkJdHJ5IHsNCgkJCQlVdGlsaXR5LnNlcmlhbGl6ZUlkZW50aWZpYWJsZShncmFwaCwgZ3JhcGguZ2V0VVJJKCkpOw0KCQkJfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgew0KCQkJCUFjdGl2YXRvci5sb2dFcnJvcihlLmdldE1lc3NhZ2UoKSwgZSk7DQoJCQl9DQoJCX0NCgl9DQoNCglwcml2YXRlIHZvaWQgcmVkcmF3KCkgew0KCQlmb3IgKEdyYXBoTm9kZSBnbiA6IGdyYXBoTm9kZXMudmFsdWVzKCkpIHsNCgkJCU5vZGVEYXRhIG5vZGVEYXRhID0gKE5vZGVEYXRhKSBnbi5nZXREYXRhKCk7DQoJCQlkb3VibGUgb3JpZ1ggPSBub2RlRGF0YS5nZXRPcmlnWCgpOw0KCQkJZG91YmxlIG9yaWdZID0gbm9kZURhdGEuZ2V0T3JpZ1koKTsNCgkJCWRvdWJsZSBkaXNwbGF5WCA9IG9yaWdYICogc2NhbGVYICsgeFRyYW5zbGF0aW9uOw0KCQkJZG91YmxlIGRpc3BsYXlZID0gb3JpZ1kgKiBzY2FsZVkgKyB5VHJhbnNsYXRpb247DQoNCgkJCWduLnNldFNpemUoTk9ERV9TSVpFLCBOT0RFX1NJWkUpOw0KCQkJZ24uc2V0TG9jYXRpb24oZGlzcGxheVggLSBOT0RFX1NJWkUgLyAyLCBkaXNwbGF5WSAtIE5PREVfU0laRSAvIDIpOw0KCQl9DQoJfQ0KDQoJcHJpdmF0ZSB2b2lkIHNldEluaXRpYWxUcmFuc2Zvcm0oKSB7DQoJCVJlY3RhbmdsZSB6ZXN0Qm91bmRzID0gemVzdEdyYXBoLmdldENsaWVudEFyZWEoKTsNCgkJUmVjdGFuZ2xlMkQuRG91YmxlIHN0ZW1Cb3VuZHMgPSBudWxsOw0KDQoJCWZvciAoU2V0PFBvbHlnb24+IHBvbHlnb25zIDogZ3JhcGhQb2x5Z29ucy52YWx1ZXMoKSkgew0KCQkJZm9yIChQb2x5Z29uIHAgOiBwb2x5Z29ucykgew0KCQkJCWlmIChzdGVtQm91bmRzID09IG51bGwpIHsNCgkJCQkJc3RlbUJvdW5kcyA9IHAuZ2V0Qm91bmRzKCk7DQoJCQkJfSBlbHNlIHsNCgkJCQkJc3RlbUJvdW5kcyA9IChSZWN0YW5nbGUyRC5Eb3VibGUpIHN0ZW1Cb3VuZHMuY3JlYXRlVW5pb24ocA0KCQkJCQkJCS5nZXRCb3VuZHMoKSk7DQoJCQkJfQ0KCQkJfQ0KCQl9DQoNCgkJZG91YmxlIHNjYWxlRmFjdG9yID0gTWF0aC5taW4oemVzdEJvdW5kcy53aWR0aCAvIHN0ZW1Cb3VuZHMud2lkdGgsDQoJCQkJemVzdEJvdW5kcy5oZWlnaHQgLyBzdGVtQm91bmRzLmhlaWdodCkgKiBJTklUSUFMX1NDQUxFX0ZBQ1RPUjsNCgkJZG91YmxlIHplc3RDZW50ZXJYID0gemVzdEJvdW5kcy54ICsgemVzdEJvdW5kcy53aWR0aCAvIDI7DQoJCWRvdWJsZSB6ZXN0Q2VudGVyWSA9IHplc3RCb3VuZHMueSArIHplc3RCb3VuZHMuaGVpZ2h0IC8gMjsNCgkJZG91YmxlIHN0ZW1DZW50ZXJYID0gc3RlbUJvdW5kcy5nZXRDZW50ZXJYKCk7DQoJCWRvdWJsZSBzdGVtQ2VudGVyWSA9IHN0ZW1Cb3VuZHMuZ2V0Q2VudGVyWSgpOw0KDQoJCXNjYWxlWCA9IHNjYWxlRmFjdG9yOw0KCQlzY2FsZVkgPSAtc2NhbGVGYWN0b3I7IC8vIHktYXhpcyBwb2ludHMgaW4gb3Bwb3NpdGUgZGlyZWN0aW9uDQoJCXhUcmFuc2xhdGlvbiA9IHplc3RDZW50ZXJYIC0gc2NhbGVYICogc3RlbUNlbnRlclg7DQoJCXlUcmFuc2xhdGlvbiA9IHplc3RDZW50ZXJZIC0gc2NhbGVZICogc3RlbUNlbnRlclk7DQoJfQ0KDQoJcHJpdmF0ZSB2b2lkIHVwZGF0ZUdyYXBoKEdyYXBoIGdyYXBoKSB7DQoJCWZvciAoTm9kZSBncmFwaE5vZGUgOiBncmFwaC5nZXROb2RlcygpLnZhbHVlcygpKSB7DQoJCQlOb2RlIHN0ZW1HcmFwaE5vZGUgPSBzdGVtR3JhcGguZ2V0Tm9kZShncmFwaE5vZGUuZ2V0VVJJKCkpOw0KDQoJCQlncmFwaE5vZGUuZ2V0RHVibGluQ29yZSgpLnNldFRpdGxlKA0KCQkJCQlzdGVtR3JhcGhOb2RlLmdldER1YmxpbkNvcmUoKS5nZXRUaXRsZSgpKTsNCgkJfQ0KDQoJCWZvciAoRWRnZSBncmFwaEVkZ2UgOiBncmFwaC5nZXRFZGdlcygpLnZhbHVlcygpKSB7DQoJCQlFZGdlIHN0ZW1HcmFwaEVkZ2UgPSBzdGVtR3JhcGguZ2V0RWRnZShncmFwaEVkZ2UuZ2V0VVJJKCkpOw0KCQkJRWRnZUxhYmVsIGdyYXBoTGFiZWwgPSBncmFwaEVkZ2UuZ2V0TGFiZWwoKTsNCgkJCUVkZ2VMYWJlbCBzdGVtR3JhcGhMYWJlbCA9IHN0ZW1HcmFwaEVkZ2UuZ2V0TGFiZWwoKTsNCg0KCQkJZ3JhcGhFZGdlLmdldER1YmxpbkNvcmUoKS5zZXRUaXRsZSgNCgkJCQkJc3RlbUdyYXBoRWRnZS5nZXREdWJsaW5Db3JlKCkuZ2V0VGl0bGUoKSk7DQoNCgkJCWlmIChncmFwaExhYmVsIGluc3RhbmNlb2YgQ29tbW9uQm9yZGVyUmVsYXRpb25zaGlwTGFiZWwpIHsNCgkJCQlDb21tb25Cb3JkZXJSZWxhdGlvbnNoaXBMYWJlbFZhbHVlIGdyYXBoTGFiZWxWYWx1ZSA9IChDb21tb25Cb3JkZXJSZWxhdGlvbnNoaXBMYWJlbFZhbHVlKSBncmFwaExhYmVsDQoJCQkJCQkuZ2V0Q3VycmVudFZhbHVlKCk7DQoJCQkJQ29tbW9uQm9yZGVyUmVsYXRpb25zaGlwTGFiZWxWYWx1ZSBzdGVtR3JhcGhMYWJlbFZhbHVlID0gKENvbW1vbkJvcmRlclJlbGF0aW9uc2hpcExhYmVsVmFsdWUpIHN0ZW1HcmFwaExhYmVsDQoJCQkJCQkuZ2V0Q3VycmVudFZhbHVlKCk7DQoNCgkJCQlncmFwaExhYmVsVmFsdWUuc2V0Qm9yZGVyTGVuZ3RoKHN0ZW1HcmFwaExhYmVsVmFsdWUNCgkJCQkJCS5nZXRCb3JkZXJMZW5ndGgoKSk7DQoJCQl9IGVsc2UgaWYgKGdyYXBoTGFiZWwgaW5zdGFuY2VvZiBNaWdyYXRpb25FZGdlTGFiZWwpIHsNCgkJCQlNaWdyYXRpb25FZGdlIGdyYXBoTWlncmF0aW9uID0gKE1pZ3JhdGlvbkVkZ2UpIGdyYXBoRWRnZTsNCgkJCQlNaWdyYXRpb25FZGdlIHN0ZW1HcmFwaE1pZ3JhdGlvbiA9IChNaWdyYXRpb25FZGdlKSBzdGVtR3JhcGhFZGdlOw0KCQkJCU1pZ3JhdGlvbkVkZ2VMYWJlbFZhbHVlIGdyYXBoTGFiZWxWYWx1ZSA9IChNaWdyYXRpb25FZGdlTGFiZWxWYWx1ZSkgZ3JhcGhFZGdlDQoJCQkJCQkuZ2V0TGFiZWwoKS5nZXRDdXJyZW50VmFsdWUoKTsNCgkJCQlNaWdyYXRpb25FZGdlTGFiZWxWYWx1ZSBzdGVtR3JhcGhMYWJlbFZhbHVlID0gKE1pZ3JhdGlvbkVkZ2VMYWJlbFZhbHVlKSBzdGVtR3JhcGhFZGdlDQoJCQkJCQkuZ2V0TGFiZWwoKS5nZXRDdXJyZW50VmFsdWUoKTsNCg0KCQkJCWdyYXBoTWlncmF0aW9uLnNldFBvcHVsYXRpb25JZGVudGlmaWVyKHN0ZW1HcmFwaE1pZ3JhdGlvbg0KCQkJCQkJLmdldFBvcHVsYXRpb25JZGVudGlmaWVyKCkpOw0KCQkJCWdyYXBoTWlncmF0aW9uLnNldFVzZUFic29sdXRlVmFsdWVzKHN0ZW1HcmFwaE1pZ3JhdGlvbg0KCQkJCQkJLmlzVXNlQWJzb2x1dGVWYWx1ZXMoKSk7DQoJCQkJZ3JhcGhMYWJlbFZhbHVlLnNldE1pZ3JhdGlvblJhdGUoc3RlbUdyYXBoTGFiZWxWYWx1ZQ0KCQkJCQkJLmdldE1pZ3JhdGlvblJhdGUoKSk7DQoJCQkJZ3JhcGhMYWJlbFZhbHVlLnNldFRpbWVQZXJpb2Qoc3RlbUdyYXBoTGFiZWxWYWx1ZQ0KCQkJCQkJLmdldFRpbWVQZXJpb2QoKSk7DQoJCQl9IGVsc2UgaWYgKGdyYXBoTGFiZWwgaW5zdGFuY2VvZiBSb2FkVHJhbnNwb3J0UmVsYXRpb25zaGlwTGFiZWwpIHsNCgkJCQlSb2FkVHJhbnNwb3J0UmVsYXRpb25zaGlwTGFiZWxWYWx1ZSBncmFwaExhYmVsVmFsdWUgPSAoUm9hZFRyYW5zcG9ydFJlbGF0aW9uc2hpcExhYmVsVmFsdWUpIGdyYXBoTGFiZWwNCgkJCQkJCS5nZXRDdXJyZW50VmFsdWUoKTsNCgkJCQlSb2FkVHJhbnNwb3J0UmVsYXRpb25zaGlwTGFiZWxWYWx1ZSBzdGVtR3JhcGhMYWJlbFZhbHVlID0gKFJvYWRUcmFuc3BvcnRSZWxhdGlvbnNoaXBMYWJlbFZhbHVlKSBzdGVtR3JhcGhMYWJlbA0KCQkJCQkJLmdldEN1cnJlbnRWYWx1ZSgpOw0KDQoJCQkJZ3JhcGhMYWJlbFZhbHVlLnNldFJvYWROYW1lKHN0ZW1HcmFwaExhYmVsVmFsdWUuZ2V0Um9hZE5hbWUoKSk7DQoJCQkJZ3JhcGhMYWJlbFZhbHVlDQoJCQkJCQkuc2V0Um9hZENsYXNzKHN0ZW1HcmFwaExhYmVsVmFsdWUuZ2V0Um9hZENsYXNzKCkpOw0KCQkJCWdyYXBoTGFiZWxWYWx1ZS5zZXROdW1iZXJDcm9zc2luZ3Moc3RlbUdyYXBoTGFiZWxWYWx1ZQ0KCQkJCQkJLmdldE51bWJlckNyb3NzaW5ncygpKTsNCgkJCX0gZWxzZSBpZiAoZ3JhcGhMYWJlbCBpbnN0YW5jZW9mIFBpcGVUcmFuc3BvcnRFZGdlTGFiZWwpIHsNCgkJCQlQaXBlVHJhbnNwb3J0RWRnZSBncmFwaFBpcGUgPSAoUGlwZVRyYW5zcG9ydEVkZ2UpIGdyYXBoRWRnZTsNCgkJCQlQaXBlVHJhbnNwb3J0RWRnZSBzdGVtR3JhcGhQaXBlID0gKFBpcGVUcmFuc3BvcnRFZGdlKSBzdGVtR3JhcGhFZGdlOw0KCQkJCVBpcGVUcmFuc3BvcnRFZGdlTGFiZWxWYWx1ZSBncmFwaExhYmVsVmFsdWUgPSAoUGlwZVRyYW5zcG9ydEVkZ2VMYWJlbFZhbHVlKSBncmFwaEVkZ2UNCgkJCQkJCS5nZXRMYWJlbCgpLmdldEN1cnJlbnRWYWx1ZSgpOw0KCQkJCVBpcGVUcmFuc3BvcnRFZGdlTGFiZWxWYWx1ZSBzdGVtR3JhcGhMYWJlbFZhbHVlID0gKFBpcGVUcmFuc3BvcnRFZGdlTGFiZWxWYWx1ZSkgc3RlbUdyYXBoRWRnZQ0KCQkJCQkJLmdldExhYmVsKCkuZ2V0Q3VycmVudFZhbHVlKCk7DQoNCgkJCQlncmFwaFBpcGUuc2V0UG9wdWxhdGlvbklkZW50aWZpZXIoc3RlbUdyYXBoUGlwZQ0KCQkJCQkJLmdldFBvcHVsYXRpb25JZGVudGlmaWVyKCkpOw0KCQkJCWdyYXBoTGFiZWxWYWx1ZS5zZXRNYXhGbG93KHN0ZW1HcmFwaExhYmVsVmFsdWUuZ2V0TWF4RmxvdygpKTsNCgkJCQlncmFwaExhYmVsVmFsdWUuc2V0VGltZVBlcmlvZChzdGVtR3JhcGhMYWJlbFZhbHVlDQoJCQkJCQkuZ2V0VGltZVBlcmlvZCgpKTsNCgkJCX0NCgkJfQ0KDQoJCWZvciAoTm9kZUxhYmVsIGdyYXBoTGFiZWwgOiBncmFwaC5nZXROb2RlTGFiZWxzKCkudmFsdWVzKCkpIHsNCgkJCU5vZGVMYWJlbCBzdGVtR3JhcGhMYWJlbCA9IHN0ZW1HcmFwaC5nZXROb2RlTGFiZWwoZ3JhcGhMYWJlbA0KCQkJCQkuZ2V0VVJJKCkpOw0KDQoJCQlpZiAoZ3JhcGhMYWJlbCBpbnN0YW5jZW9mIFBvcHVsYXRpb25MYWJlbCkgew0KCQkJCVBvcHVsYXRpb25MYWJlbCBncmFwaFBvcExhYmVsID0gKFBvcHVsYXRpb25MYWJlbCkgZ3JhcGhMYWJlbDsNCgkJCQlQb3B1bGF0aW9uTGFiZWwgc3RlbUdyYXBoUG9wTGFiZWwgPSAoUG9wdWxhdGlvbkxhYmVsKSBzdGVtR3JhcGhMYWJlbDsNCg0KCQkJCWdyYXBoUG9wTGFiZWwuc2V0UG9wdWxhdGlvbklkZW50aWZpZXIoc3RlbUdyYXBoUG9wTGFiZWwNCgkJCQkJCS5nZXRQb3B1bGF0aW9uSWRlbnRpZmllcigpKTsNCgkJCQlncmFwaFBvcExhYmVsLmdldEN1cnJlbnRQb3B1bGF0aW9uVmFsdWUoKS5zZXRDb3VudCgNCgkJCQkJCXN0ZW1HcmFwaFBvcExhYmVsLmdldEN1cnJlbnRQb3B1bGF0aW9uVmFsdWUoKQ0KCQkJCQkJCQkuZ2V0Q291bnQoKSk7DQoJCQkJZ3JhcGhQb3BMYWJlbC5zZXRQb3B1bGF0ZWRBcmVhKHN0ZW1HcmFwaFBvcExhYmVsDQoJCQkJCQkuZ2V0UG9wdWxhdGVkQXJlYSgpKTsNCgkJCX0gZWxzZSBpZiAoZ3JhcGhMYWJlbCBpbnN0YW5jZW9mIEFyZWFMYWJlbCkgew0KCQkJCUFyZWFMYWJlbCBncmFwaEFyZWFMYWJlbCA9IChBcmVhTGFiZWwpIGdyYXBoTGFiZWw7DQoJCQkJQXJlYUxhYmVsIHN0ZW1HcmFwaEFyZWFMYWJlbCA9IChBcmVhTGFiZWwpIHN0ZW1HcmFwaExhYmVsOw0KDQoJCQkJZ3JhcGhBcmVhTGFiZWwuZ2V0Q3VycmVudEFyZWFWYWx1ZSgpLnNldEFyZWEoDQoJCQkJCQlzdGVtR3JhcGhBcmVhTGFiZWwuZ2V0Q3VycmVudEFyZWFWYWx1ZSgpLmdldEFyZWEoKSk7DQoJCQl9DQoJCX0NCgl9DQoNCglwcml2YXRlIHZvaWQgYWRkVHJhbnNsYXRpb25Ub05vZGUoTm9kZURhdGEgbm9kZURhdGEsIGludCB4VHJhbnNsYXRpb24sDQoJCQlpbnQgeVRyYW5zbGF0aW9uKSB7DQoJCVNldDxQb2x5Z29uPiBkaXNwbGF5UG9seWdvbnMgPSBncmFwaFBvbHlnb25zLmdldChub2RlRGF0YS5nZXROb2RlVVJJKCkpOw0KCQlkb3VibGUgZHggPSB4VHJhbnNsYXRpb24gLyBzY2FsZVg7DQoJCWRvdWJsZSBkeSA9IHlUcmFuc2xhdGlvbiAvIHNjYWxlWTsNCg0KCQlub2RlRGF0YS5zZXRPcmlnWChub2RlRGF0YS5nZXRPcmlnWCgpICsgZHgpOw0KCQlub2RlRGF0YS5zZXRPcmlnWShub2RlRGF0YS5nZXRPcmlnWSgpICsgZHkpOw0KDQoJCWZvciAoUG9seWdvbiBwb2x5Z29uIDogZGlzcGxheVBvbHlnb25zKSB7DQoJCQlmb3IgKGludCBpID0gMDsgaSA8IHBvbHlnb24ubnBvaW50czsgaSsrKSB7DQoJCQkJcG9seWdvbi54W2ldICs9IGR4Ow0KCQkJCXBvbHlnb24ueVtpXSArPSBkeTsNCgkJCX0NCgkJfQ0KCX0NCg0KCXByaXZhdGUgaW50W10gcG9seWdvbjJJbnRBcnJheShQb2x5Z29uIHBvbHkpIHsNCgkJaWYgKHBvbHkubnBvaW50cyA9PSAwKSB7DQoJCQlyZXR1cm4gbmV3IGludFtdIHsgMCwgMCB9Ow0KCQl9DQoNCgkJaW50W10gcG9pbnRzID0gbmV3IGludFtwb2x5Lm5wb2ludHMgKiAyXTsNCg0KCQlmb3IgKGludCBpID0gMDsgaSA8IHBvbHkubnBvaW50czsgaSsrKSB7DQoJCQlwb2ludHNbaSAqIDJdID0gKGludCkgTWF0aC5yb3VuZChwb2x5LnhbaV0gKiBzY2FsZVggKyB4VHJhbnNsYXRpb24pOw0KCQkJcG9pbnRzW2kgKiAyICsgMV0gPSAoaW50KSBNYXRoLnJvdW5kKHBvbHkueVtpXSAqIHNjYWxlWQ0KCQkJCQkrIHlUcmFuc2xhdGlvbik7DQoJCX0NCg0KCQlyZXR1cm4gcG9pbnRzOw0KCX0NCg0KCXByaXZhdGUgU3RyaW5nIGNyZWF0ZUVkZ2VUaXRsZShOb2RlIG5vZGVBLCBOb2RlIG5vZGVCLCBTdHJpbmcgdHlwZU5hbWUsDQoJCQlib29sZWFuIGRpcmVjdGVkKSB7DQoJCVN0cmluZyBuQSA9IG5vZGVBLmdldER1YmxpbkNvcmUoKS5nZXRUaXRsZSgpOw0KCQlTdHJpbmcgbkIgPSBub2RlQi5nZXREdWJsaW5Db3JlKCkuZ2V0VGl0bGUoKTsNCgkJU3RyaW5nIHRpdGxlID0gbnVsbDsNCg0KCQlpZiAoZGlyZWN0ZWQpIHsNCgkJCXRpdGxlID0gdHlwZU5hbWUgKyAiWygiICsgbkEgKyAiKS0+KCIgKyBuQiArICIpXSI7DQoJCX0gZWxzZSB7DQoJCQl0aXRsZSA9IHR5cGVOYW1lICsgIlsoIiArIG5BICsgIik8LT4oIiArIG5CICsgIildIjsNCgkJfQ0KDQoJCXJldHVybiB0aXRsZTsNCgl9DQoNCglwcml2YXRlIFVSSSBnZXRSYW5kb21VUkkoU3RyaW5nIHNlZ21lbnQpIHsNCgkJVVJJIHVyaSA9IG51bGw7DQoJCWJvb2xlYW4gaXNEdXBsaWNhdGUgPSB0cnVlOw0KDQoJCXdoaWxlIChpc0R1cGxpY2F0ZSkgew0KCQkJdXJpID0gU1RFTVVSSS5jcmVhdGVVUkkoc2VnbWVudCArICIvIg0KCQkJCQkrIFNURU1VUkkuZ2VuZXJhdGVVbmlxdWVQYXJ0KCkpOw0KCQkJaXNEdXBsaWNhdGUgPSBzdGVtR3JhcGguZ2V0Tm9kZXMoKS5jb250YWluc0tleSh1cmkpDQoJCQkJCXx8IHN0ZW1HcmFwaC5nZXRFZGdlcygpLmNvbnRhaW5zKHVyaSk7DQoJCX0NCg0KCQlyZXR1cm4gdXJpOw0KCX0NCg0KCXByaXZhdGUgdm9pZCBwcmV2ZW50T3ZlcmxheShHcmFwaENvbm5lY3Rpb24gY29ubmVjdGlvbikgew0KCQlDb25uZWN0aW9uRGF0YSBlZGdlRGF0YSA9IChDb25uZWN0aW9uRGF0YSkgY29ubmVjdGlvbi5nZXREYXRhKCk7DQoJCUxpc3Q8R3JhcGhDb25uZWN0aW9uPiBzYW1lQ29ubmVjdGlvbnMgPSBuZXcgQXJyYXlMaXN0PEdyYXBoQ29ubmVjdGlvbj4oKTsNCgkJaW50IGN1cnZlRGVwdGggPSAwOw0KDQoJCWZvciAoR3JhcGhDb25uZWN0aW9uIGMgOiBncmFwaENvbm5lY3Rpb25zLnZhbHVlcygpKSB7DQoJCQlHcmFwaE5vZGUgc291cmNlMSA9IGNvbm5lY3Rpb24uZ2V0U291cmNlKCk7DQoJCQlHcmFwaE5vZGUgZGVzdGluYXRpb24xID0gY29ubmVjdGlvbi5nZXREZXN0aW5hdGlvbigpOw0KCQkJR3JhcGhOb2RlIHNvdXJjZTIgPSBjLmdldFNvdXJjZSgpOw0KCQkJR3JhcGhOb2RlIGRlc3RpbmF0aW9uMiA9IGMuZ2V0RGVzdGluYXRpb24oKTsNCg0KCQkJaWYgKHNvdXJjZTEgPT0gc291cmNlMiAmJiBkZXN0aW5hdGlvbjEgPT0gZGVzdGluYXRpb24yKSB7DQoJCQkJaWYgKCEoYy5lcXVhbHMoY29ubmVjdGlvbikpKSB7DQoJCQkJCXNhbWVDb25uZWN0aW9ucy5hZGQoYyk7DQoJCQkJfQ0KCQkJfQ0KCQl9DQoNCgkJZm9yIChpbnQgaSA9IDA7IGkgPCBzYW1lQ29ubmVjdGlvbnMuc2l6ZSgpOyBpKyspIHsNCgkJCWJvb2xlYW4gZXhpc3RzID0gZmFsc2U7DQoNCgkJCWZvciAoR3JhcGhDb25uZWN0aW9uIGMgOiBzYW1lQ29ubmVjdGlvbnMpIHsNCgkJCQlpZiAoKChDb25uZWN0aW9uRGF0YSkgYy5nZXREYXRhKCkpLmdldEN1cnZlRGVwdGgoKSA9PSBjdXJ2ZURlcHRoKSB7DQoJCQkJCWV4aXN0cyA9IHRydWU7DQoJCQkJCWJyZWFrOw0KCQkJCX0NCgkJCX0NCg0KCQkJaWYgKCFleGlzdHMpIHsNCgkJCQlicmVhazsNCgkJCX0NCg0KCQkJY3VydmVEZXB0aCA9IE5PREVfU0laRSAqIChpbnQpIE1hdGguY2VpbCgoaSArIDEuMCkgLyAyLjApDQoJCQkJCSogKGludCkgTWF0aC5wb3coLTEsIGkpOw0KCQl9DQoNCgkJZWRnZURhdGEuc2V0Q3VydmVEZXB0aChjdXJ2ZURlcHRoKTsNCgkJY29ubmVjdGlvbi5zZXRDdXJ2ZURlcHRoKGN1cnZlRGVwdGgpOw0KCX0NCg0KCXByaXZhdGUgUG9pbnQyRC5Eb3VibGUgZ2V0Q29vcmRpbmF0ZXNGcm9tQ3Vyc29yTG9jYXRpb24oUG9pbnQgeHkpIHsNCgkJZG91YmxlIHhfYmFjayA9ICh4eS54IC0geFRyYW5zbGF0aW9uKSAvIHNjYWxlWDsNCgkJZG91YmxlIHlfYmFjayA9ICh4eS55IC0geVRyYW5zbGF0aW9uKSAvIHNjYWxlWTsNCg0KCQlyZXR1cm4gbmV3IFBvaW50MkQuRG91YmxlKHhfYmFjaywgeV9iYWNrKTsNCgl9DQoNCglwcml2YXRlIFN0cmluZyBmb3JtYXRMYXRMb24oZG91YmxlIGxhdCwgZG91YmxlIGxvbikgew0KCQlEZWNpbWFsRm9ybWF0IGRmID0gbmV3IERlY2ltYWxGb3JtYXQoIjAuMDAiLA0KCQkJCURlY2ltYWxGb3JtYXRTeW1ib2xzLmdldEluc3RhbmNlKExvY2FsZS5VUykpOw0KDQoJCXJldHVybiBkZi5mb3JtYXQobGF0KSArICIgIiArIGRmLmZvcm1hdChsb24pOw0KCX0NCg0KCXByaXZhdGUgU3RyaW5nIGZvcm1hdERvdWJsZShkb3VibGUgdmFsdWUpIHsNCgkJRGVjaW1hbEZvcm1hdCBkZiA9IG5ldyBEZWNpbWFsRm9ybWF0KCIwLjAwIiwNCgkJCQlEZWNpbWFsRm9ybWF0U3ltYm9scy5nZXRJbnN0YW5jZShMb2NhbGUuVVMpKTsNCg0KCQlyZXR1cm4gZGYuZm9ybWF0KHZhbHVlKTsNCgl9DQoNCglwcml2YXRlIHZvaWQgY2hlY2tTZWxlY3Rpb25WaXNpYmxlKCkgew0KCQlPYmplY3Qgc2VsZWN0ZWRJdGVtID0gemVzdEdyYXBoLmdldFNlbGVjdGlvbigpLmdldCgwKTsNCgkJaW50IHlNYXggPSB6ZXN0R3JhcGguZ2V0U2l6ZSgpLnk7DQoJCWludCB5UG9zID0gMDsNCg0KCQlpZiAoc2VsZWN0ZWRJdGVtIGluc3RhbmNlb2YgR3JhcGhOb2RlKSB7DQoJCQlHcmFwaE5vZGUgbm9kZSA9IChHcmFwaE5vZGUpIHNlbGVjdGVkSXRlbTsNCg0KCQkJeVBvcyA9IG5vZGUuZ2V0TG9jYXRpb24oKS55Ow0KCQl9IGVsc2UgaWYgKHNlbGVjdGVkSXRlbSBpbnN0YW5jZW9mIEdyYXBoQ29ubmVjdGlvbikgew0KCQkJR3JhcGhDb25uZWN0aW9uIGNvbm5lY3Rpb24gPSAoR3JhcGhDb25uZWN0aW9uKSBzZWxlY3RlZEl0ZW07DQoJCQlHcmFwaE5vZGUgbm9kZTEgPSBjb25uZWN0aW9uLmdldFNvdXJjZSgpOw0KCQkJR3JhcGhOb2RlIG5vZGUyID0gY29ubmVjdGlvbi5nZXREZXN0aW5hdGlvbigpOw0KDQoJCQl5UG9zID0gKG5vZGUxLmdldExvY2F0aW9uKCkueSArIG5vZGUyLmdldExvY2F0aW9uKCkueSkgLyAyOw0KCQl9DQoNCgkJaWYgKHlQb3MgKyBOT0RFX1NJWkUgPiB5TWF4KSB7DQoJCQl5VHJhbnNsYXRpb24gKz0gKHlNYXggLSBOT0RFX1NJWkUgLSB5UG9zKTsNCgkJCXplc3RHcmFwaC5yZWRyYXcoKTsNCgkJCXJlZHJhdygpOw0KCQl9DQoJfQ0KDQoJcHJpdmF0ZSB2b2lkIHNldE5vZGVDb2xvcihHcmFwaE5vZGUgZ24pIHsNCgkJTm9kZURhdGEgZGF0YSA9IChOb2RlRGF0YSkgZ24uZ2V0RGF0YSgpOw0KDQoJCXN3aXRjaCAoZGF0YS5nZXRHcmFwaExpc3RJbmRleCgpKSB7DQoJCWNhc2UgMDoNCgkJCWduLnNldEJhY2tncm91bmRDb2xvcihDb2xvckNvbnN0YW50cy5ibGFjayk7DQoJCQlyZXR1cm47DQoJCWNhc2UgMToNCgkJCWduLnNldEJhY2tncm91bmRDb2xvcihDb2xvckNvbnN0YW50cy5yZWQpOw0KCQkJcmV0dXJuOw0KCQljYXNlIDI6DQoJCQlnbi5zZXRCYWNrZ3JvdW5kQ29sb3IoQ29sb3JDb25zdGFudHMuZ3JlZW4pOw0KCQkJcmV0dXJuOw0KCQljYXNlIDM6DQoJCQlnbi5zZXRCYWNrZ3JvdW5kQ29sb3IoQ29sb3JDb25zdGFudHMuYmx1ZSk7DQoJCQlyZXR1cm47DQoJCWNhc2UgNDoNCgkJCWduLnNldEJhY2tncm91bmRDb2xvcihDb2xvckNvbnN0YW50cy55ZWxsb3cpOw0KCQkJcmV0dXJuOw0KCQljYXNlIDU6DQoJCQlnbi5zZXRCYWNrZ3JvdW5kQ29sb3IoQ29sb3JDb25zdGFudHMub3JhbmdlKTsNCgkJCXJldHVybjsNCgkJY2FzZSA2Og0KCQkJZ24uc2V0QmFja2dyb3VuZENvbG9yKENvbG9yQ29uc3RhbnRzLmN5YW4pOw0KCQkJcmV0dXJuOw0KCQl9DQoNCgkJZ24uc2V0QmFja2dyb3VuZENvbG9yKENvbG9yQ29uc3RhbnRzLmJsYWNrKTsNCgl9DQoNCglwcml2YXRlIHZvaWQgc2V0RWRnZUNvbG9yKEdyYXBoQ29ubmVjdGlvbiBnYykgew0KCQlDb25uZWN0aW9uRGF0YSBjZCA9IChDb25uZWN0aW9uRGF0YSkgZ2MuZ2V0RGF0YSgpOw0KCQlFZGdlTGFiZWwgbGFiZWwgPSBjZC5nZXRFZGdlTGFiZWwoKTsNCg0KCQlpZiAobGFiZWwgaW5zdGFuY2VvZiBNaWdyYXRpb25FZGdlTGFiZWwpIHsNCgkJCWdjLnNldExpbmVTdHlsZShTV1QuTElORV9TT0xJRCk7DQoJCX0gZWxzZSBpZiAobGFiZWwgaW5zdGFuY2VvZiBDb21tb25Cb3JkZXJSZWxhdGlvbnNoaXBMYWJlbCkgew0KCQkJZ2Muc2V0TGluZVN0eWxlKFNXVC5MSU5FX0RPVCk7DQoJCX0gZWxzZSBpZiAobGFiZWwgaW5zdGFuY2VvZiBSb2FkVHJhbnNwb3J0UmVsYXRpb25zaGlwTGFiZWwpIHsNCgkJCWdjLnNldExpbmVTdHlsZShTV1QuTElORV9EQVNIKTsNCgkJfSBlbHNlIGlmIChsYWJlbCBpbnN0YW5jZW9mIFBpcGVUcmFuc3BvcnRFZGdlTGFiZWwpIHsNCgkJCWdjLnNldExpbmVTdHlsZShTV1QuTElORV9EQVNIRE9UKTsNCgkJfQ0KCX0NCg0KfQ0K