LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChjKSAyMDEzLCAyMDE3IElCTSBDb3Jwb3JhdGlvbiBhbmQgb3RoZXJzLgogKgogKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzCiAqIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2UgMi4wCiAqIHdoaWNoIGFjY29tcGFuaWVzIHRoaXMgZGlzdHJpYnV0aW9uLCBhbmQgaXMgYXZhaWxhYmxlIGF0CiAqIGh0dHBzOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAvCiAqCiAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wCiAqIAogKiBDb250cmlidXRvcnM6CiAqICAgICBJQk0gQ29ycG9yYXRpb24gLSBpbml0aWFsIEFQSSBhbmQgaW1wbGVtZW50YXRpb24KICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnBhY2thZ2Ugb3JnLmVjbGlwc2Uub3NnaS50ZXN0cy5jb250YWluZXI7CgppbXBvcnQgc3RhdGljIGphdmEudXRpbC5qYXIuQXR0cmlidXRlcy5OYW1lLk1BTklGRVNUX1ZFUlNJT047CmltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnRFcXVhbHM7CmltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnROb3ROdWxsOwppbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0TnVsbDsKaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmFzc2VydFRydWU7CmltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5mYWlsOwoKaW1wb3J0IGphdmEuaW8uQnl0ZUFycmF5SW5wdXRTdHJlYW07CmltcG9ydCBqYXZhLmlvLkJ5dGVBcnJheU91dHB1dFN0cmVhbTsKaW1wb3J0IGphdmEuaW8uRGF0YUlucHV0U3RyZWFtOwppbXBvcnQgamF2YS5pby5EYXRhT3V0cHV0U3RyZWFtOwppbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKaW1wb3J0IGphdmEuaW8uUHJpbnRTdHJlYW07CmltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OwppbXBvcnQgamF2YS51dGlsLkFycmF5czsKaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uOwppbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb25zOwppbXBvcnQgamF2YS51dGlsLkRpY3Rpb25hcnk7CmltcG9ydCBqYXZhLnV0aWwuRW51bWVyYXRpb247CmltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKaW1wb3J0IGphdmEudXRpbC5IYXNoU2V0OwppbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOwppbXBvcnQgamF2YS51dGlsLkxpc3Q7CmltcG9ydCBqYXZhLnV0aWwuTWFwOwppbXBvcnQgamF2YS51dGlsLlNldDsKaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LkJsb2NraW5nUXVldWU7CmltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5Db25jdXJyZW50TGlua2VkUXVldWU7CmltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5FeGVjdXRvclNlcnZpY2U7CmltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5FeGVjdXRvcnM7CmltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5SZWplY3RlZEV4ZWN1dGlvbkhhbmRsZXI7CmltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5TY2hlZHVsZWRFeGVjdXRvclNlcnZpY2U7CmltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5TY2hlZHVsZWRUaHJlYWRQb29sRXhlY3V0b3I7CmltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5TeW5jaHJvbm91c1F1ZXVlOwppbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuVGhyZWFkRmFjdG9yeTsKaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LlRocmVhZFBvb2xFeGVjdXRvcjsKaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LlRpbWVVbml0OwppbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuYXRvbWljLkF0b21pY0ludGVnZXI7CmltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5hdG9taWMuQXRvbWljUmVmZXJlbmNlOwppbXBvcnQgamF2YS51dGlsLmphci5BdHRyaWJ1dGVzOwppbXBvcnQgamF2YS51dGlsLmphci5NYW5pZmVzdDsKaW1wb3J0IG9yZy5lY2xpcHNlLm9zZ2kuY29udGFpbmVyLk1vZHVsZTsKaW1wb3J0IG9yZy5lY2xpcHNlLm9zZ2kuY29udGFpbmVyLk1vZHVsZS5TdGFydE9wdGlvbnM7CmltcG9ydCBvcmcuZWNsaXBzZS5vc2dpLmNvbnRhaW5lci5Nb2R1bGUuU3RhdGU7CmltcG9ydCBvcmcuZWNsaXBzZS5vc2dpLmNvbnRhaW5lci5Nb2R1bGVDYXBhYmlsaXR5OwppbXBvcnQgb3JnLmVjbGlwc2Uub3NnaS5jb250YWluZXIuTW9kdWxlQ29udGFpbmVyOwppbXBvcnQgb3JnLmVjbGlwc2Uub3NnaS5jb250YWluZXIuTW9kdWxlQ29udGFpbmVyQWRhcHRvci5Db250YWluZXJFdmVudDsKaW1wb3J0IG9yZy5lY2xpcHNlLm9zZ2kuY29udGFpbmVyLk1vZHVsZUNvbnRhaW5lckFkYXB0b3IuTW9kdWxlRXZlbnQ7CmltcG9ydCBvcmcuZWNsaXBzZS5vc2dpLmNvbnRhaW5lci5Nb2R1bGVSZXF1aXJlbWVudDsKaW1wb3J0IG9yZy5lY2xpcHNlLm9zZ2kuY29udGFpbmVyLk1vZHVsZVJldmlzaW9uOwppbXBvcnQgb3JnLmVjbGlwc2Uub3NnaS5jb250YWluZXIuTW9kdWxlUmV2aXNpb25CdWlsZGVyOwppbXBvcnQgb3JnLmVjbGlwc2Uub3NnaS5jb250YWluZXIuTW9kdWxlV2lyZTsKaW1wb3J0IG9yZy5lY2xpcHNlLm9zZ2kuY29udGFpbmVyLk1vZHVsZVdpcmluZzsKaW1wb3J0IG9yZy5lY2xpcHNlLm9zZ2kuY29udGFpbmVyLmJ1aWxkZXJzLk9TR2lNYW5pZmVzdEJ1aWxkZXJGYWN0b3J5OwppbXBvcnQgb3JnLmVjbGlwc2Uub3NnaS5jb250YWluZXIubmFtZXNwYWNlcy5FY2xpcHNlUGxhdGZvcm1OYW1lc3BhY2U7CmltcG9ydCBvcmcuZWNsaXBzZS5vc2dpLmludGVybmFsLmRlYnVnLkRlYnVnOwppbXBvcnQgb3JnLmVjbGlwc2Uub3NnaS5pbnRlcm5hbC5mcmFtZXdvcmsuRXF1aW5veENvbmZpZ3VyYXRpb247CmltcG9ydCBvcmcuZWNsaXBzZS5vc2dpLnJlcG9ydC5yZXNvbHV0aW9uLlJlc29sdXRpb25SZXBvcnQ7CmltcG9ydCBvcmcuZWNsaXBzZS5vc2dpLnRlc3RzLmNvbnRhaW5lci5kdW1teXMuRHVtbXlDb2xsaXNpb25Ib29rOwppbXBvcnQgb3JnLmVjbGlwc2Uub3NnaS50ZXN0cy5jb250YWluZXIuZHVtbXlzLkR1bW15Q29udGFpbmVyQWRhcHRvcjsKaW1wb3J0IG9yZy5lY2xpcHNlLm9zZ2kudGVzdHMuY29udGFpbmVyLmR1bW15cy5EdW1teURlYnVnT3B0aW9uczsKaW1wb3J0IG9yZy5lY2xpcHNlLm9zZ2kudGVzdHMuY29udGFpbmVyLmR1bW15cy5EdW1teU1vZHVsZURhdGFiYXNlOwppbXBvcnQgb3JnLmVjbGlwc2Uub3NnaS50ZXN0cy5jb250YWluZXIuZHVtbXlzLkR1bW15TW9kdWxlRGF0YWJhc2UuRHVtbXlDb250YWluZXJFdmVudDsKaW1wb3J0IG9yZy5lY2xpcHNlLm9zZ2kudGVzdHMuY29udGFpbmVyLmR1bW15cy5EdW1teU1vZHVsZURhdGFiYXNlLkR1bW15TW9kdWxlRXZlbnQ7CmltcG9ydCBvcmcuZWNsaXBzZS5vc2dpLnRlc3RzLmNvbnRhaW5lci5kdW1teXMuRHVtbXlSZXNvbHZlckhvb2s7CmltcG9ydCBvcmcuZWNsaXBzZS5vc2dpLnRlc3RzLmNvbnRhaW5lci5kdW1teXMuRHVtbXlSZXNvbHZlckhvb2tGYWN0b3J5OwppbXBvcnQgb3JnLmVjbGlwc2Uub3NnaS51dGlsLk1hbmlmZXN0RWxlbWVudDsKaW1wb3J0IG9yZy5qdW5pdC5Bc3NlcnQ7CmltcG9ydCBvcmcuanVuaXQuVGVzdDsKaW1wb3J0IG9yZy5vc2dpLmZyYW1ld29yay5CdW5kbGU7CmltcG9ydCBvcmcub3NnaS5mcmFtZXdvcmsuQnVuZGxlQ29udGV4dDsKaW1wb3J0IG9yZy5vc2dpLmZyYW1ld29yay5CdW5kbGVFeGNlcHRpb247CmltcG9ydCBvcmcub3NnaS5mcmFtZXdvcmsuQnVuZGxlUmVmZXJlbmNlOwppbXBvcnQgb3JnLm9zZ2kuZnJhbWV3b3JrLkNvbnN0YW50czsKaW1wb3J0IG9yZy5vc2dpLmZyYW1ld29yay5WZXJzaW9uOwppbXBvcnQgb3JnLm9zZ2kuZnJhbWV3b3JrLmhvb2tzLnJlc29sdmVyLlJlc29sdmVySG9vazsKaW1wb3J0IG9yZy5vc2dpLmZyYW1ld29yay5ob29rcy5yZXNvbHZlci5SZXNvbHZlckhvb2tGYWN0b3J5OwppbXBvcnQgb3JnLm9zZ2kuZnJhbWV3b3JrLm5hbWVzcGFjZS5CdW5kbGVOYW1lc3BhY2U7CmltcG9ydCBvcmcub3NnaS5mcmFtZXdvcmsubmFtZXNwYWNlLkV4ZWN1dGlvbkVudmlyb25tZW50TmFtZXNwYWNlOwppbXBvcnQgb3JnLm9zZ2kuZnJhbWV3b3JrLm5hbWVzcGFjZS5Ib3N0TmFtZXNwYWNlOwppbXBvcnQgb3JnLm9zZ2kuZnJhbWV3b3JrLm5hbWVzcGFjZS5JZGVudGl0eU5hbWVzcGFjZTsKaW1wb3J0IG9yZy5vc2dpLmZyYW1ld29yay5uYW1lc3BhY2UuUGFja2FnZU5hbWVzcGFjZTsKaW1wb3J0IG9yZy5vc2dpLmZyYW1ld29yay53aXJpbmcuQnVuZGxlQ2FwYWJpbGl0eTsKaW1wb3J0IG9yZy5vc2dpLmZyYW1ld29yay53aXJpbmcuQnVuZGxlUmVxdWlyZW1lbnQ7CmltcG9ydCBvcmcub3NnaS5mcmFtZXdvcmsud2lyaW5nLkJ1bmRsZVJldmlzaW9uOwppbXBvcnQgb3JnLm9zZ2kuZnJhbWV3b3JrLndpcmluZy5CdW5kbGVXaXJlOwppbXBvcnQgb3JnLm9zZ2kucmVzb3VyY2UuTmFtZXNwYWNlOwoKcHVibGljIGNsYXNzIFRlc3RNb2R1bGVDb250YWluZXIgZXh0ZW5kcyBBYnN0cmFjdFRlc3QgewoKCXByaXZhdGUgc3RhdGljIER1bW15TW9kdWxlRGF0YWJhc2UgcmVzb2x2ZWRNb2R1bGVEYXRhYmFzZTsKCglwcml2YXRlIHZvaWQgc2V0dXBNb2R1bGVEYXRhYmFzZSgpIHRocm93cyBCdW5kbGVFeGNlcHRpb24gewoJCWlmIChyZXNvbHZlZE1vZHVsZURhdGFiYXNlID09IG51bGwpIHsKCQkJcmVzb2x2ZWRNb2R1bGVEYXRhYmFzZSA9IGdldERhdGFiYXNlKCk7CgkJfQoJfQoKCXByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBPU0dJX09TID0gIm9zZ2kub3MiOwoJcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIE9TR0lfV1MgPSAib3NnaS53cyI7Cglwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgT1NHSV9BUkNIID0gIm9zZ2kuYXJjaCI7CgoJcHJpdmF0ZSBEdW1teU1vZHVsZURhdGFiYXNlIGdldERhdGFiYXNlKCkgdGhyb3dzIEJ1bmRsZUV4Y2VwdGlvbiB7CgkJQnVuZGxlQ29udGV4dCBjb250ZXh0ID0gKChCdW5kbGVSZWZlcmVuY2UpIGdldENsYXNzKCkuZ2V0Q2xhc3NMb2FkZXIoKSkuZ2V0QnVuZGxlKCkuZ2V0QnVuZGxlQ29udGV4dCgpOwoKCQlEdW1teUNvbnRhaW5lckFkYXB0b3IgYWRhcHRvciA9IGNyZWF0ZUR1bW15QWRhcHRvcigpOwoJCWZpbmFsIE1vZHVsZUNvbnRhaW5lciBjb250YWluZXIgPSBhZGFwdG9yLmdldENvbnRhaW5lcigpOwoKCQlCdW5kbGUgc3lzdGVtQnVuZGxlID0gY29udGV4dC5nZXRCdW5kbGUoMCk7CgkJU3RyaW5nIGV4dHJhUGFja2FnZXMgPSBjb250ZXh0LmdldFByb3BlcnR5KENvbnN0YW50cy5GUkFNRVdPUktfU1lTVEVNUEFDS0FHRVMpOwoJCVN0cmluZyBleHRyYUNhcGFiaWxpdGllcyA9IGNvbnRleHQuZ2V0UHJvcGVydHkoQ29uc3RhbnRzLkZSQU1FV09SS19TWVNURU1DQVBBQklMSVRJRVMpOwoJCWV4dHJhQ2FwYWJpbGl0aWVzID0gKGV4dHJhQ2FwYWJpbGl0aWVzID09IG51bGwgPyAiIiA6IChleHRyYUNhcGFiaWxpdGllcyArICIsICIpKTsKCQlTdHJpbmcgb3NOYW1lID0gY29udGV4dC5nZXRQcm9wZXJ0eShPU0dJX09TKTsKCQlTdHJpbmcgd3NOYW1lID0gY29udGV4dC5nZXRQcm9wZXJ0eShPU0dJX1dTKTsKCQlTdHJpbmcgYXJjaE5hbWUgPSBjb250ZXh0LmdldFByb3BlcnR5KE9TR0lfQVJDSCk7CgkJZXh0cmFDYXBhYmlsaXRpZXMgKz0gRWNsaXBzZVBsYXRmb3JtTmFtZXNwYWNlLkVDTElQU0VfUExBVEZPUk1fTkFNRVNQQUNFICsgIjsgIiArIE9TR0lfT1MgKyAiPSIgKyBvc05hbWUgKyAiOyAiICsgT1NHSV9XUyArICI9IiArIHdzTmFtZSArICI7ICIgKyBPU0dJX0FSQ0ggKyAiPSIgKyBhcmNoTmFtZTsKCQlNb2R1bGVSZXZpc2lvbkJ1aWxkZXIgc3lzdGVtYnVpbGRlciA9IE9TR2lNYW5pZmVzdEJ1aWxkZXJGYWN0b3J5LmNyZWF0ZUJ1aWxkZXIoYXNNYXAoc3lzdGVtQnVuZGxlLmdldEhlYWRlcnMoIiIpKSwgQ29uc3RhbnRzLlNZU1RFTV9CVU5ETEVfU1lNQk9MSUNOQU1FLCBleHRyYVBhY2thZ2VzLCBleHRyYUNhcGFiaWxpdGllcyk7CgkJY29udGFpbmVyLmluc3RhbGwobnVsbCwgc3lzdGVtQnVuZGxlLmdldExvY2F0aW9uKCksIHN5c3RlbWJ1aWxkZXIsIG51bGwpOwoKCQlmaW5hbCBMaXN0PFRocm93YWJsZT4gaW5zdGFsbEVycm9ycyA9IG5ldyBBcnJheUxpc3Q8VGhyb3dhYmxlPigwKTsKCQkvLyBqdXN0IHRyeWluZyB0byBwb3VuZCB0aGUgY29udGFpbmVyIHdpdGggYSBidW5jaCBvZiBpbnN0YWxscwoJCUV4ZWN1dG9yU2VydmljZSBleGVjdXRvciA9IEV4ZWN1dG9ycy5uZXdGaXhlZFRocmVhZFBvb2woMTApOwoJCUJ1bmRsZVtdIGJ1bmRsZXMgPSBjb250ZXh0LmdldEJ1bmRsZXMoKTsKCQlmb3IgKGZpbmFsIEJ1bmRsZSBidW5kbGUgOiBidW5kbGVzKSB7CgkJCWlmIChidW5kbGUuZ2V0QnVuZGxlSWQoKSA9PSAwKQoJCQkJY29udGludWU7CgkJCWV4ZWN1dG9yLmV4ZWN1dGUobmV3IFJ1bm5hYmxlKCkgewoJCQkJQE92ZXJyaWRlCgkJCQlwdWJsaWMgdm9pZCBydW4oKSB7CgkJCQkJdHJ5IHsKCQkJCQkJTW9kdWxlUmV2aXNpb25CdWlsZGVyIGJ1aWxkZXIgPSBPU0dpTWFuaWZlc3RCdWlsZGVyRmFjdG9yeS5jcmVhdGVCdWlsZGVyKGFzTWFwKGJ1bmRsZS5nZXRIZWFkZXJzKCIiKSkpOwoJCQkJCQljb250YWluZXIuaW5zdGFsbChudWxsLCBidW5kbGUuZ2V0TG9jYXRpb24oKSwgYnVpbGRlciwgbnVsbCk7CgkJCQkJfSBjYXRjaCAoVGhyb3dhYmxlIHQpIHsKCQkJCQkJdC5wcmludFN0YWNrVHJhY2UoKTsKCQkJCQkJc3luY2hyb25pemVkIChpbnN0YWxsRXJyb3JzKSB7CgkJCQkJCQlpbnN0YWxsRXJyb3JzLmFkZCh0KTsKCQkJCQkJfQoJCQkJCX0KCQkJCX0KCQkJfSk7CgkJfQoJCWV4ZWN1dG9yLnNodXRkb3duKCk7CgkJdHJ5IHsKCQkJZXhlY3V0b3IuYXdhaXRUZXJtaW5hdGlvbigyLCBUaW1lVW5pdC5NSU5VVEVTKTsKCQl9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBlKSB7CgkJCWUucHJpbnRTdGFja1RyYWNlKCk7CgkJfQoJCXN5bmNocm9uaXplZCAoaW5zdGFsbEVycm9ycykgewoJCQlpZiAoIWluc3RhbGxFcnJvcnMuaXNFbXB0eSgpKSB7CgkJCQlBc3NlcnQuYXNzZXJ0TnVsbCgiVW5leHBlY3RlZCBpbnN0YWxsIGVycm9ycy4iLCBpbnN0YWxsRXJyb3JzKTsKCQkJfQoJCX0KCQljb250YWluZXIucmVzb2x2ZShuZXcgQXJyYXlMaXN0PE1vZHVsZT4oKSwgZmFsc2UpOwoJCUxpc3Q8TW9kdWxlPiBtb2R1bGVzID0gY29udGFpbmVyLmdldE1vZHVsZXMoKTsKCQlmb3IgKE1vZHVsZSBtb2R1bGUgOiBtb2R1bGVzKSB7CgkJCWlmIChtb2R1bGUuZ2V0Q3VycmVudFJldmlzaW9uKCkuZ2V0V2lyaW5nKCkgPT0gbnVsbCkgewoJCQkJU3lzdGVtLm91dC5wcmludGxuKCJDb3VsZCBub3QgcmVzb2x2ZSBtb2R1bGU6ICIgKyBtb2R1bGUuZ2V0Q3VycmVudFJldmlzaW9uKCkpOwoJCQl9CgkJfQoJCXJldHVybiBhZGFwdG9yLmdldERhdGFiYXNlKCk7Cgl9CgoJc3RhdGljIDxLLCBWPiBNYXA8SywgVj4gYXNNYXAoRGljdGlvbmFyeTxLLCBWPiBkaWN0aW9uYXJ5KSB7CgkJTWFwPEssIFY+IG1hcCA9IG5ldyBIYXNoTWFwPEssIFY+KCk7CgkJZm9yIChFbnVtZXJhdGlvbjxLPiBlS2V5cyA9IGRpY3Rpb25hcnkua2V5cygpOyBlS2V5cy5oYXNNb3JlRWxlbWVudHMoKTspIHsKCQkJSyBrZXkgPSBlS2V5cy5uZXh0RWxlbWVudCgpOwoJCQlWIHZhbHVlID0gZGljdGlvbmFyeS5nZXQoa2V5KTsKCQkJbWFwLnB1dChrZXksIHZhbHVlKTsKCQl9CgkJcmV0dXJuIG1hcDsKCX0KCglAVGVzdAoJcHVibGljIHZvaWQgdGVzdE1vZHVsZUNvbnRhaW5lckNyZWF0ZSgpIHsKCQljcmVhdGVEdW1teUFkYXB0b3IoKTsKCX0KCgkvLyBEaXNhYmxlZCBAVGVzdAoJcHVibGljIHZvaWQgdGVzdFJlc29sdmVJbnN0YWxsQnVuZGxlcygpIHRocm93cyBCdW5kbGVFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKCQlzZXR1cE1vZHVsZURhdGFiYXNlKCk7CgkJRHVtbXlDb250YWluZXJBZGFwdG9yIGFkYXB0b3IgPSBjcmVhdGVEdW1teUFkYXB0b3IoKTsKCQlCeXRlQXJyYXlPdXRwdXRTdHJlYW0gYnl0ZXMgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CgkJcmVzb2x2ZWRNb2R1bGVEYXRhYmFzZS5zdG9yZShuZXcgRGF0YU91dHB1dFN0cmVhbShieXRlcyksIGZhbHNlKTsKCQlieXRlcy5jbG9zZSgpOwoJCWFkYXB0b3IuZ2V0RGF0YWJhc2UoKS5sb2FkKG5ldyBEYXRhSW5wdXRTdHJlYW0obmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGJ5dGVzLnRvQnl0ZUFycmF5KCkpKSk7CgkJYWRhcHRvci5nZXRDb250YWluZXIoKS5yZXNvbHZlKG5ldyBBcnJheUxpc3Q8TW9kdWxlPigpLCBmYWxzZSk7Cgl9CgoJLy8gRGlzYWJsZWQgQFRlc3QKCXB1YmxpYyB2b2lkIHRlc3RSZXNvbHZlSW5zdGFsbEJ1bmRsZXMwMSgpIHRocm93cyBCdW5kbGVFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKCQlzZXR1cE1vZHVsZURhdGFiYXNlKCk7CgkJRHVtbXlDb250YWluZXJBZGFwdG9yIGFkYXB0b3IgPSBjcmVhdGVEdW1teUFkYXB0b3IoKTsKCQlCeXRlQXJyYXlPdXRwdXRTdHJlYW0gYnl0ZXMgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CgkJcmVzb2x2ZWRNb2R1bGVEYXRhYmFzZS5zdG9yZShuZXcgRGF0YU91dHB1dFN0cmVhbShieXRlcyksIGZhbHNlKTsKCQlieXRlcy5jbG9zZSgpOwoJCWFkYXB0b3IuZ2V0RGF0YWJhc2UoKS5sb2FkKG5ldyBEYXRhSW5wdXRTdHJlYW0obmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGJ5dGVzLnRvQnl0ZUFycmF5KCkpKSk7CgkJZm9yIChpbnQgaSA9IDA7IGkgPCA1MDsgaSsrKSB7CgkJCWFkYXB0b3IuZ2V0Q29udGFpbmVyKCkucmVmcmVzaChhZGFwdG9yLmdldENvbnRhaW5lcigpLmdldE1vZHVsZXMoKSk7CgkJfQoJfQoKCS8vIERpc2FibGVkIEBUZXN0CglwdWJsaWMgdm9pZCB0ZXN0UmVzb2x2ZUFscmVhZHlSZXNvbHZlZEJ1bmRsZXMoKSB0aHJvd3MgQnVuZGxlRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CgkJc2V0dXBNb2R1bGVEYXRhYmFzZSgpOwoJCUR1bW15Q29udGFpbmVyQWRhcHRvciBhZGFwdG9yID0gY3JlYXRlRHVtbXlBZGFwdG9yKCk7CgkJQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGJ5dGVzID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOwoJCXJlc29sdmVkTW9kdWxlRGF0YWJhc2Uuc3RvcmUobmV3IERhdGFPdXRwdXRTdHJlYW0oYnl0ZXMpLCB0cnVlKTsKCQlieXRlcy5jbG9zZSgpOwoJCWFkYXB0b3IuZ2V0RGF0YWJhc2UoKS5sb2FkKG5ldyBEYXRhSW5wdXRTdHJlYW0obmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGJ5dGVzLnRvQnl0ZUFycmF5KCkpKSk7CgkJYWRhcHRvci5nZXRDb250YWluZXIoKS5yZXNvbHZlKG5ldyBBcnJheUxpc3Q8TW9kdWxlPigpLCBmYWxzZSk7Cgl9CgoJLy8gRGlzYWJsZWQgQFRlc3QKCXB1YmxpYyB2b2lkIHRlc3RSZWZyZXNoU3lzdGVtQnVuZGxlKCkgdGhyb3dzIEJ1bmRsZUV4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewoJCXNldHVwTW9kdWxlRGF0YWJhc2UoKTsKCQlEdW1teUNvbnRhaW5lckFkYXB0b3IgYWRhcHRvciA9IGNyZWF0ZUR1bW15QWRhcHRvcigpOwoJCUJ5dGVBcnJheU91dHB1dFN0cmVhbSBieXRlcyA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKCQlyZXNvbHZlZE1vZHVsZURhdGFiYXNlLnN0b3JlKG5ldyBEYXRhT3V0cHV0U3RyZWFtKGJ5dGVzKSwgdHJ1ZSk7CgkJYnl0ZXMuY2xvc2UoKTsKCQlhZGFwdG9yLmdldERhdGFiYXNlKCkubG9hZChuZXcgRGF0YUlucHV0U3RyZWFtKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShieXRlcy50b0J5dGVBcnJheSgpKSkpOwoJCWFkYXB0b3IuZ2V0Q29udGFpbmVyKCkucmVmcmVzaChBcnJheXMuYXNMaXN0KGFkYXB0b3IuZ2V0Q29udGFpbmVyKCkuZ2V0TW9kdWxlKDApKSk7Cgl9CgoJLy8gZGlzYWJsZWQgQFRlc3QKCXB1YmxpYyB2b2lkIHRlc3RMb2FkUGVyZm9ybWFuY2UoKSB0aHJvd3MgQnVuZGxlRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CgkJc2V0dXBNb2R1bGVEYXRhYmFzZSgpOwoJCUJ5dGVBcnJheU91dHB1dFN0cmVhbSBieXRlcyA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKCQlyZXNvbHZlZE1vZHVsZURhdGFiYXNlLnN0b3JlKG5ldyBEYXRhT3V0cHV0U3RyZWFtKGJ5dGVzKSwgdHJ1ZSk7CgkJYnl0ZXMuY2xvc2UoKTsKCQlTeXN0ZW0ub3V0LnByaW50bG4oIlNJWkU6ICIgKyBieXRlcy5zaXplKCkpOwoJCWxvbmcgc3RhcnQgPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKTsKCQlmb3IgKGludCBpID0gMDsgaSA8IDEwMDA7IGkrKykgewoJCQlEdW1teUNvbnRhaW5lckFkYXB0b3IgYWRhcHRvciA9IGNyZWF0ZUR1bW15QWRhcHRvcigpOwoJCQlhZGFwdG9yLmdldERhdGFiYXNlKCkubG9hZChuZXcgRGF0YUlucHV0U3RyZWFtKG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShieXRlcy50b0J5dGVBcnJheSgpKSkpOwoJCX0KCQlTeXN0ZW0ub3V0LnByaW50bG4oIkVORDogIiArIChTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKSAtIHN0YXJ0KSk7Cgl9CgoJQFRlc3QKCXB1YmxpYyB2b2lkIHRlc3RTaW1wbGVSZXNvbHZlKCkgdGhyb3dzIEJ1bmRsZUV4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewoJCUR1bW15Q29udGFpbmVyQWRhcHRvciBhZGFwdG9yID0gY3JlYXRlRHVtbXlBZGFwdG9yKCk7CgkJTW9kdWxlQ29udGFpbmVyIGNvbnRhaW5lciA9IGFkYXB0b3IuZ2V0Q29udGFpbmVyKCk7CgoJCU1vZHVsZSBzeXN0ZW1CdW5kbGUgPSBpbnN0YWxsRHVtbXlNb2R1bGUoInN5c3RlbS5idW5kbGUuTUYiLCBDb25zdGFudHMuU1lTVEVNX0JVTkRMRV9MT0NBVElPTiwgY29udGFpbmVyKTsKCQlNb2R1bGVSZXZpc2lvbiBzeXN0ZW1SZXZpc2lvbiA9IHN5c3RlbUJ1bmRsZS5nZXRDdXJyZW50UmV2aXNpb24oKTsKCQljb250YWluZXIucmVzb2x2ZShBcnJheXMuYXNMaXN0KHN5c3RlbUJ1bmRsZSksIHRydWUpOwoJCU1vZHVsZVdpcmluZyBzeXN0ZW1XaXJpbmcgPSBzeXN0ZW1SZXZpc2lvbi5nZXRXaXJpbmcoKTsKCQlBc3NlcnQuYXNzZXJ0Tm90TnVsbCgic3lzdGVtIHdpcmluZyBpcyBudWxsIiwgc3lzdGVtV2lyaW5nKTsKCgkJTW9kdWxlIGIxID0gaW5zdGFsbER1bW15TW9kdWxlKCJiMV92MS5NRiIsICJiMSIsIGNvbnRhaW5lcik7CgkJTW9kdWxlUmV2aXNpb24gYjFSZXZpc2lvbiA9IGIxLmdldEN1cnJlbnRSZXZpc2lvbigpOwoJCWNvbnRhaW5lci5yZXNvbHZlKEFycmF5cy5hc0xpc3QoYjEpLCB0cnVlKTsKCQlNb2R1bGVXaXJpbmcgYjFXaXJpbmcgPSBiMVJldmlzaW9uLmdldFdpcmluZygpOwoJCUFzc2VydC5hc3NlcnROb3ROdWxsKCJiMSB3aXJpbmcgaXMgbnVsbCIsIGIxV2lyaW5nKTsKCX0KCglAVGVzdAoJcHVibGljIHZvaWQgdGVzdFNpbXBsZVVuUmVzb2x2ZWFibGUoKSB0aHJvd3MgQnVuZGxlRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CgkJRHVtbXlDb250YWluZXJBZGFwdG9yIGFkYXB0b3IgPSBjcmVhdGVEdW1teUFkYXB0b3IoKTsKCQlNb2R1bGVDb250YWluZXIgY29udGFpbmVyID0gYWRhcHRvci5nZXRDb250YWluZXIoKTsKCgkJTW9kdWxlIHN5c3RlbUJ1bmRsZSA9IGluc3RhbGxEdW1teU1vZHVsZSgic3lzdGVtLmJ1bmRsZS5NRiIsIENvbnN0YW50cy5TWVNURU1fQlVORExFX0xPQ0FUSU9OLCBjb250YWluZXIpOwoJCWNvbnRhaW5lci5yZXNvbHZlKEFycmF5cy5hc0xpc3Qoc3lzdGVtQnVuZGxlKSwgdHJ1ZSk7CgoJCU1vZHVsZSBjNyA9IGluc3RhbGxEdW1teU1vZHVsZSgiYzdfdjEuTUYiLCAiYzciLCBjb250YWluZXIpOwoJCWluc3RhbGxEdW1teU1vZHVsZSgiYzZfdjEuTUYiLCAiYzYiLCBjb250YWluZXIpOwoKCQlSZXNvbHV0aW9uUmVwb3J0IHJlcG9ydCA9IGNvbnRhaW5lci5yZXNvbHZlKEFycmF5cy5hc0xpc3QoYzcpLCB0cnVlKTsKCQlBc3NlcnQuYXNzZXJ0Tm90TnVsbCgiRXhwZWN0ZWQgYSByZXNvbHV0aW9uIGV4Y2VwdGlvbiIsIHJlcG9ydC5nZXRSZXNvbHV0aW9uRXhjZXB0aW9uKCkpOwoKCQkvLyBTaG91bGQgcmVzb2x2ZSBub3cKCQlpbnN0YWxsRHVtbXlNb2R1bGUoImM0X3YxLk1GIiwgImM0IiwgY29udGFpbmVyKTsKCQlyZXBvcnQgPSBjb250YWluZXIucmVzb2x2ZShBcnJheXMuYXNMaXN0KGM3KSwgdHJ1ZSk7CgkJQXNzZXJ0LmFzc2VydE51bGwoIlVuZXhwZWN0ZWQgcmVzb2x0dWlvbiBleGNlcHRpb24iLCByZXBvcnQuZ2V0UmVzb2x1dGlvbkV4Y2VwdGlvbigpKTsKCX0KCglAVGVzdAoJcHVibGljIHZvaWQgdGVzdE11bHRpSG9zdCgpIHRocm93cyBCdW5kbGVFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKCQlEdW1teUNvbnRhaW5lckFkYXB0b3IgYWRhcHRvciA9IGNyZWF0ZUR1bW15QWRhcHRvcigpOwoJCU1vZHVsZUNvbnRhaW5lciBjb250YWluZXIgPSBhZGFwdG9yLmdldENvbnRhaW5lcigpOwoJCWluc3RhbGxEdW1teU1vZHVsZSgic3lzdGVtLmJ1bmRsZS5NRiIsIENvbnN0YW50cy5TWVNURU1fQlVORExFX0xPQ0FUSU9OLCBjb250YWluZXIpOwoJCU1vZHVsZSBoMXYxID0gaW5zdGFsbER1bW15TW9kdWxlKCJoMV92MS5NRiIsICJoMV92MSIsIGNvbnRhaW5lcik7CgkJTW9kdWxlIGgxdjIgPSBpbnN0YWxsRHVtbXlNb2R1bGUoImgxX3YyLk1GIiwgImgxX3YyIiwgY29udGFpbmVyKTsKCQlNb2R1bGUgZjF2MSA9IGluc3RhbGxEdW1teU1vZHVsZSgiZjFfdjEuTUYiLCAiZjFfdjEiLCBjb250YWluZXIpOwoJCU1vZHVsZSBiMyA9IGluc3RhbGxEdW1teU1vZHVsZSgiYjNfdjEuTUYiLCAiYjNfdjEiLCBjb250YWluZXIpOwoJCVJlc29sdXRpb25SZXBvcnQgcmVwb3J0ID0gY29udGFpbmVyLnJlc29sdmUoQXJyYXlzLmFzTGlzdChoMXYxLCBoMXYyLCBmMXYxLCBiMyksIHRydWUpOwoJCUFzc2VydC5hc3NlcnROdWxsKCJFeHBlY3RlZCBubyByZXNvbHV0aW9uIGV4Y2VwdGlvbi4iLCByZXBvcnQuZ2V0UmVzb2x1dGlvbkV4Y2VwdGlvbigpKTsKCX0KCglAVGVzdAoJcHVibGljIHZvaWQgdGVzdE1pc3NpbmdIb3N0KCkgdGhyb3dzIEJ1bmRsZUV4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewoJCUR1bW15Q29udGFpbmVyQWRhcHRvciBhZGFwdG9yID0gY3JlYXRlRHVtbXlBZGFwdG9yKCk7CgkJTW9kdWxlQ29udGFpbmVyIGNvbnRhaW5lciA9IGFkYXB0b3IuZ2V0Q29udGFpbmVyKCk7CgkJaW5zdGFsbER1bW15TW9kdWxlKCJzeXN0ZW0uYnVuZGxlLk1GIiwgQ29uc3RhbnRzLlNZU1RFTV9CVU5ETEVfTE9DQVRJT04sIGNvbnRhaW5lcik7CgkJTW9kdWxlIGYxdjEgPSBpbnN0YWxsRHVtbXlNb2R1bGUoImYxX3YxLk1GIiwgImYxX3YxIiwgY29udGFpbmVyKTsKCQlNb2R1bGUgYjMgPSBpbnN0YWxsRHVtbXlNb2R1bGUoImIzX3YxLk1GIiwgImIzX3YxIiwgY29udGFpbmVyKTsKCQlSZXNvbHV0aW9uUmVwb3J0IHJlcG9ydCA9IGNvbnRhaW5lci5yZXNvbHZlKEFycmF5cy5hc0xpc3QoZjF2MSwgYjMpLCB0cnVlKTsKCQlBc3NlcnQuYXNzZXJ0Tm90TnVsbCgiRXhwZWN0ZWQgYSByZXNvbHV0aW9uIGV4Y2VwdGlvbi4iLCByZXBvcnQuZ2V0UmVzb2x1dGlvbkV4Y2VwdGlvbigpKTsKCgkJTW9kdWxlIGgxdjEgPSBpbnN0YWxsRHVtbXlNb2R1bGUoImgxX3YxLk1GIiwgImgxX3YxIiwgY29udGFpbmVyKTsKCQlyZXBvcnQgPSBjb250YWluZXIucmVzb2x2ZShBcnJheXMuYXNMaXN0KGIzKSwgdHJ1ZSk7CgkJQXNzZXJ0LmFzc2VydE51bGwoIkV4cGVjdGVkIG5vIHJlc29sdXRpb24gZXhjZXB0aW9uLiIsIHJlcG9ydC5nZXRSZXNvbHV0aW9uRXhjZXB0aW9uKCkpOwoJCU1vZHVsZVdpcmluZyB3aXJpbmcgPSBiMy5nZXRDdXJyZW50UmV2aXNpb24oKS5nZXRXaXJpbmcoKTsKCQlMaXN0PE1vZHVsZVdpcmU+IHBhY2thZ2VXaXJlcyA9IHdpcmluZy5nZXRSZXF1aXJlZE1vZHVsZVdpcmVzKFBhY2thZ2VOYW1lc3BhY2UuUEFDS0FHRV9OQU1FU1BBQ0UpOwoJCUFzc2VydC5hc3NlcnRFcXVhbHMoIkV4cGVjdGVkIDEgaW1wb3J0LiIsIDEsIHBhY2thZ2VXaXJlcy5zaXplKCkpOwoJCU1vZHVsZVdpcmUgcGtnV2lyZSA9IHBhY2thZ2VXaXJlcy5nZXQoMCk7CgkJQXNzZXJ0LmFzc2VydEVxdWFscygiV3JvbmcgaG9zdCBleHBvcnRlci4iLCBwa2dXaXJlLmdldFByb3ZpZGVyV2lyaW5nKCkuZ2V0UmV2aXNpb24oKSwgaDF2MS5nZXRDdXJyZW50UmV2aXNpb24oKSk7Cgl9CgoJQFRlc3QKCXB1YmxpYyB2b2lkIHRlc3RGcmFnbWVudHMwMSgpIHRocm93cyBCdW5kbGVFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKCQlEdW1teUNvbnRhaW5lckFkYXB0b3IgYWRhcHRvciA9IGNyZWF0ZUR1bW15QWRhcHRvcigpOwoJCU1vZHVsZUNvbnRhaW5lciBjb250YWluZXIgPSBhZGFwdG9yLmdldENvbnRhaW5lcigpOwoJCU1vZHVsZSBzeXN0ZW1Nb2R1bGUgPSBpbnN0YWxsRHVtbXlNb2R1bGUoInN5c3RlbS5idW5kbGUuTUYiLCBDb25zdGFudHMuU1lTVEVNX0JVTkRMRV9MT0NBVElPTiwgY29udGFpbmVyKTsKCQlNb2R1bGUgYzEgPSBpbnN0YWxsRHVtbXlNb2R1bGUoImMxX3YxLk1GIiwgImMxX3YxIiwgY29udGFpbmVyKTsKCQlNb2R1bGUgaDIgPSBpbnN0YWxsRHVtbXlNb2R1bGUoImgyX3YxLk1GIiwgImgyX3YxIiwgY29udGFpbmVyKTsKCQlNb2R1bGUgZjIgPSBpbnN0YWxsRHVtbXlNb2R1bGUoImYyX3YxLk1GIiwgImYyX3YxIiwgY29udGFpbmVyKTsKCQljb250YWluZXIucmVzb2x2ZShBcnJheXMuYXNMaXN0KHN5c3RlbU1vZHVsZSwgYzEsIGgyLCBmMiksIHRydWUpOwoKCQlNb2R1bGVXaXJpbmcgd2lyaW5nID0gaDIuZ2V0Q3VycmVudFJldmlzaW9uKCkuZ2V0V2lyaW5nKCk7CgkJTGlzdDxNb2R1bGVXaXJlPiByZXF1aXJlZFdpcmVzID0gd2lyaW5nLmdldFJlcXVpcmVkTW9kdWxlV2lyZXMobnVsbCk7CgkJQXNzZXJ0LmFzc2VydEVxdWFscygiV3JvbmcgbnVtYmVyIG9mIHJlcXVpcmVkIHdpcmVzLiIsIDMsIHJlcXVpcmVkV2lyZXMuc2l6ZSgpKTsKCQlmb3IgKE1vZHVsZVdpcmUgd2lyZSA6IHJlcXVpcmVkV2lyZXMpIHsKCQkJTW9kdWxlQ2FwYWJpbGl0eSBjYXBhYmlsaXR5ID0gd2lyZS5nZXRDYXBhYmlsaXR5KCk7CgkJCUFzc2VydC5hc3NlcnRFcXVhbHMoIldyb25nIG5hbWVzcGFjZS4iLCBQYWNrYWdlTmFtZXNwYWNlLlBBQ0tBR0VfTkFNRVNQQUNFLCBjYXBhYmlsaXR5LmdldE5hbWVzcGFjZSgpKTsKCgkJCUFzc2VydC5hc3NlcnRFcXVhbHMoIldyb25nIHJlcXVpcmVyLiIsIGgyLmdldEN1cnJlbnRSZXZpc2lvbigpLCB3aXJlLmdldFJlcXVpcmVyKCkpOwoKCQkJU3RyaW5nIHBrZ05hbWUgPSAoU3RyaW5nKSBjYXBhYmlsaXR5LmdldEF0dHJpYnV0ZXMoKS5nZXQoUGFja2FnZU5hbWVzcGFjZS5QQUNLQUdFX05BTUVTUEFDRSk7CgkJCUFzc2VydC5hc3NlcnROb3ROdWxsKCJObyBwYWNrYWdlIG5hbWUuIiwgcGtnTmFtZSk7CgkJCU1vZHVsZVJldmlzaW9uIGV4cGVjdGVkUmVxUmV2aXNpb247CgkJCWlmIChwa2dOYW1lLmVxdWFscygib3JnLm9zZ2kuZnJhbWV3b3JrIikpIHsKCQkJCWV4cGVjdGVkUmVxUmV2aXNpb24gPSBoMi5nZXRDdXJyZW50UmV2aXNpb24oKTsKCQkJfSBlbHNlIHsKCQkJCWV4cGVjdGVkUmVxUmV2aXNpb24gPSBmMi5nZXRDdXJyZW50UmV2aXNpb24oKTsKCQkJfQoJCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJXcm9uZyByZXF1aXJlbWVudCByZXZpc2lvbi4iLCBleHBlY3RlZFJlcVJldmlzaW9uLCB3aXJlLmdldFJlcXVpcmVtZW50KCkuZ2V0UmV2aXNpb24oKSk7CgkJfQoJfQoKCUBUZXN0CglwdWJsaWMgdm9pZCB0ZXN0RnJhZ21lbnRzMDIoKSB0aHJvd3MgQnVuZGxlRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CgkJRHVtbXlDb250YWluZXJBZGFwdG9yIGFkYXB0b3IgPSBjcmVhdGVEdW1teUFkYXB0b3IoKTsKCQlNb2R1bGVDb250YWluZXIgY29udGFpbmVyID0gYWRhcHRvci5nZXRDb250YWluZXIoKTsKCQlNb2R1bGUgc3lzdGVtTW9kdWxlID0gaW5zdGFsbER1bW15TW9kdWxlKCJzeXN0ZW0uYnVuZGxlLk1GIiwgQ29uc3RhbnRzLlNZU1RFTV9CVU5ETEVfTE9DQVRJT04sIGNvbnRhaW5lcik7CgkJTW9kdWxlIGMxID0gaW5zdGFsbER1bW15TW9kdWxlKCJjMV92MS5NRiIsICJjMV92MSIsIGNvbnRhaW5lcik7CgkJTW9kdWxlIGgyID0gaW5zdGFsbER1bW15TW9kdWxlKCJoMl92MS5NRiIsICJoMl92MSIsIGNvbnRhaW5lcik7CgoJCWNvbnRhaW5lci5yZXNvbHZlKEFycmF5cy5hc0xpc3Qoc3lzdGVtTW9kdWxlLCBjMSwgaDIpLCB0cnVlKTsKCgkJTW9kdWxlV2lyaW5nIGgyd2lyaW5nID0gaDIuZ2V0Q3VycmVudFJldmlzaW9uKCkuZ2V0V2lyaW5nKCk7CgkJQXNzZXJ0LmFzc2VydE5vdE51bGwoIldpcmluZyBpcyBudWxsLiIsIGgyd2lyaW5nKTsKCgkJTW9kdWxlIGYyID0gaW5zdGFsbER1bW15TW9kdWxlKCJmMl92MS5NRiIsICJmMl92MSIsIGNvbnRhaW5lcik7CgkJQXNzZXJ0LmFzc2VydEVxdWFscygiV3Jvbmcgc3RhdGUuIiwgU3RhdGUuSU5TVEFMTEVELCBmMi5nZXRTdGF0ZSgpKTsKCQljb250YWluZXIucmVzb2x2ZShBcnJheXMuYXNMaXN0KGYyKSwgZmFsc2UpOwoJCUFzc2VydC5hc3NlcnROdWxsKCJFeHBlY3RlZCB0byBub3QgYmUgYWJsZSB0byByZXNvbHZlIGYyLiIsIGYyLmdldEN1cnJlbnRSZXZpc2lvbigpLmdldFdpcmluZygpKTsKCX0KCglAVGVzdAoJcHVibGljIHZvaWQgdGVzdEV4ZWN1dGlvbkVudmlyb25tZW50KCkgdGhyb3dzIEJ1bmRsZUV4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewoJCUR1bW15Q29udGFpbmVyQWRhcHRvciBhZGFwdG9yID0gY3JlYXRlRHVtbXlBZGFwdG9yKCk7CgkJTW9kdWxlQ29udGFpbmVyIGNvbnRhaW5lciA9IGFkYXB0b3IuZ2V0Q29udGFpbmVyKCk7CgkJU3RyaW5nIGV4dHJhQ2FwYWJpbGl0aWVzID0gIm9zZ2kuZWU7IG9zZ2kuZWU9SmF2YVNFOyB2ZXJzaW9uOkxpc3Q8VmVyc2lvbj49XCIxLjMsIDEuNCwgMS41LCAxLjYsIDEuN1wiIjsKCQlpbnN0YWxsRHVtbXlNb2R1bGUoInN5c3RlbS5idW5kbGUuTUYiLCBDb25zdGFudHMuU1lTVEVNX0JVTkRMRV9MT0NBVElPTiwgbnVsbCwgbnVsbCwgZXh0cmFDYXBhYmlsaXRpZXMsIGNvbnRhaW5lcik7CgkJY29udGFpbmVyLnJlc29sdmUobnVsbCwgZmFsc2UpOwoKCQlNb2R1bGUgZWUxID0gaW5zdGFsbER1bW15TW9kdWxlKCJlZTFfdjEuTUYiLCAiZWUxIiwgY29udGFpbmVyKTsKCQlNb2R1bGUgZWUyID0gaW5zdGFsbER1bW15TW9kdWxlKCJlZTJfdjEuTUYiLCAiZWUyIiwgY29udGFpbmVyKTsKCQlNb2R1bGUgZWUzID0gaW5zdGFsbER1bW15TW9kdWxlKCJlZTNfdjEuTUYiLCAiZWUzIiwgY29udGFpbmVyKTsKCQljb250YWluZXIucmVzb2x2ZShBcnJheXMuYXNMaXN0KGVlMSwgZWUyKSwgdHJ1ZSk7CgkJY29udGFpbmVyLnJlc29sdmUoQXJyYXlzLmFzTGlzdChlZTMpLCBmYWxzZSk7CgoJCU1vZHVsZVdpcmluZyBlZTFXaXJpbmcgPSBlZTEuZ2V0Q3VycmVudFJldmlzaW9uKCkuZ2V0V2lyaW5nKCk7CgkJTW9kdWxlV2lyaW5nIGVlMldpcmluZyA9IGVlMi5nZXRDdXJyZW50UmV2aXNpb24oKS5nZXRXaXJpbmcoKTsKCQlNb2R1bGVXaXJpbmcgZWUzV2lyaW5nID0gZWUzLmdldEN1cnJlbnRSZXZpc2lvbigpLmdldFdpcmluZygpOwoJCUFzc2VydC5hc3NlcnROb3ROdWxsKCJlZTEgaXMgbm90IHJlc29sdmVkIiwgZWUxV2lyaW5nKTsKCQlBc3NlcnQuYXNzZXJ0Tm90TnVsbCgiZWUyIGlzIG5vdCByZXNvbHZlZCIsIGVlMldpcmluZyk7CgkJQXNzZXJ0LmFzc2VydE51bGwoImVlMyBpcyByZXNvbHZlZCIsIGVlM1dpcmluZyk7CgoJCS8vIG1ha2Ugc3VyZSB0aGUgZnJhZ21lbnQgZWUgcmVxdWlyZW1lbnQgZGlkIG5vdCBnZXQgbWVyZ2VkIGludG8gdGhlIGhvc3QKCQlMaXN0PE1vZHVsZVJlcXVpcmVtZW50PiBlZTFSZXF1aXJlbWVudHMgPSBlZTFXaXJpbmcuZ2V0TW9kdWxlUmVxdWlyZW1lbnRzKEV4ZWN1dGlvbkVudmlyb25tZW50TmFtZXNwYWNlLkVYRUNVVElPTl9FTlZJUk9OTUVOVF9OQU1FU1BBQ0UpOwoJCUFzc2VydC5hc3NlcnRFcXVhbHMoIldyb25nIG51bWJlciBvZiByZXF1aXJlbWVudHMiLCAxLCBlZTFSZXF1aXJlbWVudHMuc2l6ZSgpKTsKCQlMaXN0PE1vZHVsZVdpcmU+IGVlMVdpcmVzID0gZWUxV2lyaW5nLmdldFJlcXVpcmVkTW9kdWxlV2lyZXMoRXhlY3V0aW9uRW52aXJvbm1lbnROYW1lc3BhY2UuRVhFQ1VUSU9OX0VOVklST05NRU5UX05BTUVTUEFDRSk7CgkJQXNzZXJ0LmFzc2VydEVxdWFscygiV3JvbmcgbnVtYmVyIG9mIHdpcmVzIiwgMSwgZWUxV2lyZXMuc2l6ZSgpKTsKCgkJTGlzdDxNb2R1bGVSZXF1aXJlbWVudD4gZWUyUmVxdWlyZW1lbnRzID0gZWUyV2lyaW5nLmdldE1vZHVsZVJlcXVpcmVtZW50cyhFeGVjdXRpb25FbnZpcm9ubWVudE5hbWVzcGFjZS5FWEVDVVRJT05fRU5WSVJPTk1FTlRfTkFNRVNQQUNFKTsKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJXcm9uZyBudW1iZXIgb2YgcmVxdWlyZW1lbnRzIiwgMSwgZWUyUmVxdWlyZW1lbnRzLnNpemUoKSk7CgkJTGlzdDxNb2R1bGVXaXJlPiBlZTJXaXJlcyA9IGVlMldpcmluZy5nZXRSZXF1aXJlZE1vZHVsZVdpcmVzKEV4ZWN1dGlvbkVudmlyb25tZW50TmFtZXNwYWNlLkVYRUNVVElPTl9FTlZJUk9OTUVOVF9OQU1FU1BBQ0UpOwoJCUFzc2VydC5hc3NlcnRFcXVhbHMoIldyb25nIG51bWJlciBvZiB3aXJlcyIsIDEsIGVlMldpcmVzLnNpemUoKSk7Cgl9CgoJQFRlc3QKCXB1YmxpYyB2b2lkIHRlc3RQbGF0Zm9ybUZpbHRlcjAxKCkgdGhyb3dzIEJ1bmRsZUV4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewoJCUR1bW15Q29udGFpbmVyQWRhcHRvciBhZGFwdG9yID0gY3JlYXRlRHVtbXlBZGFwdG9yKCk7CgkJTW9kdWxlQ29udGFpbmVyIGNvbnRhaW5lciA9IGFkYXB0b3IuZ2V0Q29udGFpbmVyKCk7CgkJU3RyaW5nIGV4dHJhQ2FwYWJpbGl0aWVzID0gRWNsaXBzZVBsYXRmb3JtTmFtZXNwYWNlLkVDTElQU0VfUExBVEZPUk1fTkFNRVNQQUNFICsgIjsgb3NnaS5vcz1mb287IG9zZ2kuYXJjaD1iYXIiOwoJCWluc3RhbGxEdW1teU1vZHVsZSgic3lzdGVtLmJ1bmRsZS5NRiIsIENvbnN0YW50cy5TWVNURU1fQlVORExFX0xPQ0FUSU9OLCBudWxsLCBudWxsLCBleHRyYUNhcGFiaWxpdGllcywgY29udGFpbmVyKTsKCQljb250YWluZXIucmVzb2x2ZShudWxsLCBmYWxzZSk7CgoJCU1vZHVsZSBwbGF0Zm9ybUZpbHRlcjEgPSBpbnN0YWxsRHVtbXlNb2R1bGUoInBsYXRmb3JtRmlsdGVyMV92MS5NRiIsICJlZTEiLCBjb250YWluZXIpOwoJCWNvbnRhaW5lci5yZXNvbHZlKEFycmF5cy5hc0xpc3QocGxhdGZvcm1GaWx0ZXIxKSwgdHJ1ZSk7CgoJCU1vZHVsZVdpcmluZyBwbGF0Zm9ybUZpbHRlcjFXaXJpbmcgPSBwbGF0Zm9ybUZpbHRlcjEuZ2V0Q3VycmVudFJldmlzaW9uKCkuZ2V0V2lyaW5nKCk7CgkJQXNzZXJ0LmFzc2VydE5vdE51bGwoInBsYXRmb3JtRmlsdGVyMSBpcyBub3QgcmVzb2x2ZWQiLCBwbGF0Zm9ybUZpbHRlcjFXaXJpbmcpOwoJfQoKCUBUZXN0CglwdWJsaWMgdm9pZCB0ZXN0UGxhdGZvcm1GaWx0ZXIwMigpIHRocm93cyBCdW5kbGVFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKCQlEdW1teUNvbnRhaW5lckFkYXB0b3IgYWRhcHRvciA9IGNyZWF0ZUR1bW15QWRhcHRvcigpOwoJCU1vZHVsZUNvbnRhaW5lciBjb250YWluZXIgPSBhZGFwdG9yLmdldENvbnRhaW5lcigpOwoJCVN0cmluZyBleHRyYUNhcGFiaWxpdGllcyA9IEVjbGlwc2VQbGF0Zm9ybU5hbWVzcGFjZS5FQ0xJUFNFX1BMQVRGT1JNX05BTUVTUEFDRSArICI7IG9zZ2kub3M9YmF6OyBvc2dpLmFyY2g9Ym96IjsKCQlpbnN0YWxsRHVtbXlNb2R1bGUoInN5c3RlbS5idW5kbGUuTUYiLCBDb25zdGFudHMuU1lTVEVNX0JVTkRMRV9MT0NBVElPTiwgbnVsbCwgbnVsbCwgZXh0cmFDYXBhYmlsaXRpZXMsIGNvbnRhaW5lcik7CgkJY29udGFpbmVyLnJlc29sdmUobnVsbCwgZmFsc2UpOwoKCQlNb2R1bGUgcGxhdGZvcm1GaWx0ZXIxID0gaW5zdGFsbER1bW15TW9kdWxlKCJwbGF0Zm9ybUZpbHRlcjFfdjEuTUYiLCAiZWUxIiwgY29udGFpbmVyKTsKCQljb250YWluZXIucmVzb2x2ZShBcnJheXMuYXNMaXN0KHBsYXRmb3JtRmlsdGVyMSksIGZhbHNlKTsKCgkJTW9kdWxlV2lyaW5nIHBsYXRmb3JtRmlsdGVyMVdpcmluZyA9IHBsYXRmb3JtRmlsdGVyMS5nZXRDdXJyZW50UmV2aXNpb24oKS5nZXRXaXJpbmcoKTsKCQlBc3NlcnQuYXNzZXJ0TnVsbCgicGxhdGZvcm1GaWx0ZXIxIGlzIHJlc29sdmVkIiwgcGxhdGZvcm1GaWx0ZXIxV2lyaW5nKTsKCX0KCglAVGVzdAoJcHVibGljIHZvaWQgdGVzdEluc3RhbGxDb2xsaXNpb24wMSgpIHRocm93cyBCdW5kbGVFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKCQlEdW1teUNvbnRhaW5lckFkYXB0b3IgYWRhcHRvciA9IGNyZWF0ZUR1bW15QWRhcHRvcigpOwoJCU1vZHVsZUNvbnRhaW5lciBjb250YWluZXIgPSBhZGFwdG9yLmdldENvbnRhaW5lcigpOwoJCWluc3RhbGxEdW1teU1vZHVsZSgic3lzdGVtLmJ1bmRsZS5NRiIsIENvbnN0YW50cy5TWVNURU1fQlVORExFX0xPQ0FUSU9OLCBjb250YWluZXIpOwoJCWluc3RhbGxEdW1teU1vZHVsZSgiYjFfdjEuTUYiLCAiYjFfYSIsIGNvbnRhaW5lcik7CgkJdHJ5IHsKCQkJaW5zdGFsbER1bW15TW9kdWxlKCJiMV92MS5NRiIsICJiMV9iIiwgY29udGFpbmVyKTsKCQkJQXNzZXJ0LmZhaWwoIkV4cGVjdGVkIHRvIGZhaWwgaW5zdGFsbGF0aW9uIGJlY2F1c2Ugb2YgYSBjb2xsaXNpb24uIik7CgkJfSBjYXRjaCAoQnVuZGxlRXhjZXB0aW9uIGUpIHsKCQkJLy8gZXhwZWN0ZWQKCQkJQXNzZXJ0LmFzc2VydEVxdWFscygiV3JvbmcgZXhjZXB0aW9uIHR5cGUuIiwgQnVuZGxlRXhjZXB0aW9uLkRVUExJQ0FURV9CVU5ETEVfRVJST1IsIGUuZ2V0VHlwZSgpKTsKCQl9Cgl9CgoJQFRlc3QKCXB1YmxpYyB2b2lkIHRlc3RJbnN0YWxsQ29sbGlzaW9uMDIoKSB0aHJvd3MgQnVuZGxlRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CgkJRHVtbXlDb250YWluZXJBZGFwdG9yIGFkYXB0b3IgPSBuZXcgRHVtbXlDb250YWluZXJBZGFwdG9yKG5ldyBEdW1teUNvbGxpc2lvbkhvb2sodHJ1ZSksIENvbGxlY3Rpb25zLjxTdHJpbmcsIFN0cmluZz4gZW1wdHlNYXAoKSk7CgkJTW9kdWxlQ29udGFpbmVyIGNvbnRhaW5lciA9IGFkYXB0b3IuZ2V0Q29udGFpbmVyKCk7CgkJaW5zdGFsbER1bW15TW9kdWxlKCJzeXN0ZW0uYnVuZGxlLk1GIiwgQ29uc3RhbnRzLlNZU1RFTV9CVU5ETEVfTE9DQVRJT04sIGNvbnRhaW5lcik7CgkJaW5zdGFsbER1bW15TW9kdWxlKCJiMV92MS5NRiIsICJiMV9hIiwgY29udGFpbmVyKTsKCQlpbnN0YWxsRHVtbXlNb2R1bGUoImIxX3YxLk1GIiwgImIxX2IiLCBjb250YWluZXIpOwoJfQoKCUBUZXN0CglwdWJsaWMgdm9pZCB0ZXN0VXBkYXRlQ29sbGlzaW9uMDEoKSB0aHJvd3MgQnVuZGxlRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CgkJRHVtbXlDb250YWluZXJBZGFwdG9yIGFkYXB0b3IgPSBjcmVhdGVEdW1teUFkYXB0b3IoKTsKCQlNb2R1bGVDb250YWluZXIgY29udGFpbmVyID0gYWRhcHRvci5nZXRDb250YWluZXIoKTsKCQlNb2R1bGUgYjFfdjEgPSBpbnN0YWxsRHVtbXlNb2R1bGUoImIxX3YxLk1GIiwgImIxX3YxIiwgY29udGFpbmVyKTsKCQlpbnN0YWxsRHVtbXlNb2R1bGUoImIxX3YyLk1GIiwgImIxX3YyIiwgY29udGFpbmVyKTsKCQl0cnkgewoJCQljb250YWluZXIudXBkYXRlKGIxX3YxLCBPU0dpTWFuaWZlc3RCdWlsZGVyRmFjdG9yeS5jcmVhdGVCdWlsZGVyKGdldE1hbmlmZXN0KCJiMV92Mi5NRiIpKSwgbnVsbCk7CgkJCUFzc2VydC5mYWlsKCJFeHBlY3RlZCB0byBmYWlsIHVwZGF0ZSBiZWNhdXNlIG9mIGEgY29sbGlzaW9uLiIpOwoJCX0gY2F0Y2ggKEJ1bmRsZUV4Y2VwdGlvbiBlKSB7CgkJCS8vIGV4cGVjdGVkCgkJCUFzc2VydC5hc3NlcnRFcXVhbHMoIldyb25nIGV4Y2VwdGlvbiB0eXBlLiIsIEJ1bmRsZUV4Y2VwdGlvbi5EVVBMSUNBVEVfQlVORExFX0VSUk9SLCBlLmdldFR5cGUoKSk7CgkJfQoJfQoKCUBUZXN0CglwdWJsaWMgdm9pZCB0ZXN0VXBkYXRlQ29sbGlzaW9uMDIoKSB0aHJvd3MgQnVuZGxlRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CgkJRHVtbXlDb250YWluZXJBZGFwdG9yIGFkYXB0b3IgPSBjcmVhdGVEdW1teUFkYXB0b3IoKTsKCQlNb2R1bGVDb250YWluZXIgY29udGFpbmVyID0gYWRhcHRvci5nZXRDb250YWluZXIoKTsKCQlNb2R1bGUgYjFfdjEgPSBpbnN0YWxsRHVtbXlNb2R1bGUoImIxX3YxLk1GIiwgImIxX3YxIiwgY29udGFpbmVyKTsKCQl0cnkgewoJCQljb250YWluZXIudXBkYXRlKGIxX3YxLCBPU0dpTWFuaWZlc3RCdWlsZGVyRmFjdG9yeS5jcmVhdGVCdWlsZGVyKGdldE1hbmlmZXN0KCJiMV92MS5NRiIpKSwgbnVsbCk7CgkJfSBjYXRjaCAoQnVuZGxlRXhjZXB0aW9uIGUpIHsKCQkJQXNzZXJ0LmFzc2VydE51bGwoIkV4cGVjdGVkIHRvIHN1Y2NlZWQgdXBkYXRlIHRvIHNhbWUgcmV2aXNpb24uIiwgZSk7CgkJfQoJfQoKCUBUZXN0CglwdWJsaWMgdm9pZCB0ZXN0VXBkYXRlQ29sbGlzaW9uMDMoKSB0aHJvd3MgQnVuZGxlRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CgoJCUR1bW15Q29udGFpbmVyQWRhcHRvciBhZGFwdG9yID0gbmV3IER1bW15Q29udGFpbmVyQWRhcHRvcihuZXcgRHVtbXlDb2xsaXNpb25Ib29rKHRydWUpLCBDb2xsZWN0aW9ucy48U3RyaW5nLCBTdHJpbmc+IGVtcHR5TWFwKCkpOwoJCU1vZHVsZUNvbnRhaW5lciBjb250YWluZXIgPSBhZGFwdG9yLmdldENvbnRhaW5lcigpOwoJCU1vZHVsZSBiMV92MSA9IGluc3RhbGxEdW1teU1vZHVsZSgiYjFfdjEuTUYiLCAiYjFfdjEiLCBjb250YWluZXIpOwoJCWluc3RhbGxEdW1teU1vZHVsZSgiYjFfdjIuTUYiLCAiYjFfdjIiLCBjb250YWluZXIpOwoJCXRyeSB7CgkJCWNvbnRhaW5lci51cGRhdGUoYjFfdjEsIE9TR2lNYW5pZmVzdEJ1aWxkZXJGYWN0b3J5LmNyZWF0ZUJ1aWxkZXIoZ2V0TWFuaWZlc3QoImIxX3YyLk1GIikpLCBudWxsKTsKCQl9IGNhdGNoIChCdW5kbGVFeGNlcHRpb24gZSkgewoJCQlBc3NlcnQuYXNzZXJ0TnVsbCgiRXhwZWN0ZWQgdG8gc3VjY2VlZCB1cGRhdGUgdG8gc2FtZSByZXZpc2lvbi4iLCBlKTsKCQl9Cgl9CgoJQFRlc3QKCXB1YmxpYyB2b2lkIHRlc3RTaW5nbGV0b24wMSgpIHRocm93cyBCdW5kbGVFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKCQlEdW1teUNvbnRhaW5lckFkYXB0b3IgYWRhcHRvciA9IGNyZWF0ZUR1bW15QWRhcHRvcigpOwoJCU1vZHVsZUNvbnRhaW5lciBjb250YWluZXIgPSBhZGFwdG9yLmdldENvbnRhaW5lcigpOwoJCU1vZHVsZSBzMSA9IGluc3RhbGxEdW1teU1vZHVsZSgic2luZ2xldG9uMV92MS5NRiIsICJzMV92MSIsIGNvbnRhaW5lcik7CgkJTW9kdWxlIHMyID0gaW5zdGFsbER1bW15TW9kdWxlKCJzaW5nbGV0b24xX3YyLk1GIiwgInMxX3YyIiwgY29udGFpbmVyKTsKCQlNb2R1bGUgczMgPSBpbnN0YWxsRHVtbXlNb2R1bGUoInNpbmdsZXRvbjFfdjMuTUYiLCAiczFfdjMiLCBjb250YWluZXIpOwoKCQljb250YWluZXIucmVzb2x2ZShudWxsLCBmYWxzZSk7CgoJCUFzc2VydC5hc3NlcnRGYWxzZSgiU2luZ2xldG9uIHYxIGlzIHJlc29sdmVkLiIsIE1vZHVsZS5SRVNPTFZFRF9TRVQuY29udGFpbnMoczEuZ2V0U3RhdGUoKSkpOwoJCUFzc2VydC5hc3NlcnRGYWxzZSgiU2luZ2xldG9uIHYyIGlzIHJlc29sdmVkLiIsIE1vZHVsZS5SRVNPTFZFRF9TRVQuY29udGFpbnMoczIuZ2V0U3RhdGUoKSkpOwoJCUFzc2VydC5hc3NlcnRUcnVlKCJTaW5nbGV0b24gdjMgaXMgbm90IHJlc29sdmVkLiIsIE1vZHVsZS5SRVNPTFZFRF9TRVQuY29udGFpbnMoczMuZ2V0U3RhdGUoKSkpOwoJfQoKCUBUZXN0CglwdWJsaWMgdm9pZCB0ZXN0U2luZ2xldG9uMDIoKSB0aHJvd3MgQnVuZGxlRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CgkJUmVzb2x2ZXJIb29rRmFjdG9yeSByZXNvbHZlckhvb2tGYWN0b3J5ID0gbmV3IFJlc29sdmVySG9va0ZhY3RvcnkoKSB7CgoJCQlAT3ZlcnJpZGUKCQkJcHVibGljIFJlc29sdmVySG9vayBiZWdpbihDb2xsZWN0aW9uPEJ1bmRsZVJldmlzaW9uPiB0cmlnZ2VycykgewoJCQkJcmV0dXJuIG5ldyBSZXNvbHZlckhvb2soKSB7CgoJCQkJCUBPdmVycmlkZQoJCQkJCXB1YmxpYyB2b2lkIGZpbHRlclNpbmdsZXRvbkNvbGxpc2lvbnMoQnVuZGxlQ2FwYWJpbGl0eSBzaW5nbGV0b24sIENvbGxlY3Rpb248QnVuZGxlQ2FwYWJpbGl0eT4gY29sbGlzaW9uQ2FuZGlkYXRlcykgewoJCQkJCQljb2xsaXNpb25DYW5kaWRhdGVzLmNsZWFyKCk7CgkJCQkJfQoKCQkJCQlAT3ZlcnJpZGUKCQkJCQlwdWJsaWMgdm9pZCBmaWx0ZXJSZXNvbHZhYmxlKENvbGxlY3Rpb248QnVuZGxlUmV2aXNpb24+IGNhbmRpZGF0ZXMpIHsKCQkJCQkJLy8gbm90aGluZwoJCQkJCX0KCgkJCQkJQE92ZXJyaWRlCgkJCQkJcHVibGljIHZvaWQgZmlsdGVyTWF0Y2hlcyhCdW5kbGVSZXF1aXJlbWVudCByZXF1aXJlbWVudCwgQ29sbGVjdGlvbjxCdW5kbGVDYXBhYmlsaXR5PiBjYW5kaWRhdGVzKSB7CgkJCQkJCS8vIG5vdGhpbmcKCQkJCQl9CgoJCQkJCUBPdmVycmlkZQoJCQkJCXB1YmxpYyB2b2lkIGVuZCgpIHsKCQkJCQkJLy8gbm90aGluZwoJCQkJCX0KCQkJCX07CgkJCX0KCQl9OwoJCUR1bW15Q29udGFpbmVyQWRhcHRvciBhZGFwdG9yID0gbmV3IER1bW15Q29udGFpbmVyQWRhcHRvcihuZXcgRHVtbXlDb2xsaXNpb25Ib29rKGZhbHNlKSwgQ29sbGVjdGlvbnMuPFN0cmluZywgU3RyaW5nPiBlbXB0eU1hcCgpLCByZXNvbHZlckhvb2tGYWN0b3J5KTsKCQlNb2R1bGVDb250YWluZXIgY29udGFpbmVyID0gYWRhcHRvci5nZXRDb250YWluZXIoKTsKCgkJTW9kdWxlIHMxID0gaW5zdGFsbER1bW15TW9kdWxlKCJzaW5nbGV0b24xX3YxLk1GIiwgInMxX3YxIiwgY29udGFpbmVyKTsKCQlNb2R1bGUgczIgPSBpbnN0YWxsRHVtbXlNb2R1bGUoInNpbmdsZXRvbjFfdjIuTUYiLCAiczFfdjIiLCBjb250YWluZXIpOwoJCU1vZHVsZSBzMyA9IGluc3RhbGxEdW1teU1vZHVsZSgic2luZ2xldG9uMV92My5NRiIsICJzMV92MyIsIGNvbnRhaW5lcik7CgoJCWNvbnRhaW5lci5yZXNvbHZlKG51bGwsIGZhbHNlKTsKCgkJQXNzZXJ0LmFzc2VydFRydWUoIlNpbmdsZXRvbiB2MSBpcyBub3QgcmVzb2x2ZWQuIiwgTW9kdWxlLlJFU09MVkVEX1NFVC5jb250YWlucyhzMS5nZXRTdGF0ZSgpKSk7CgkJQXNzZXJ0LmFzc2VydFRydWUoIlNpbmdsZXRvbiB2MiBpcyBub3QgcmVzb2x2ZWQuIiwgTW9kdWxlLlJFU09MVkVEX1NFVC5jb250YWlucyhzMi5nZXRTdGF0ZSgpKSk7CgkJQXNzZXJ0LmFzc2VydFRydWUoIlNpbmdsZXRvbiB2MyBpcyBub3QgcmVzb2x2ZWQuIiwgTW9kdWxlLlJFU09MVkVEX1NFVC5jb250YWlucyhzMy5nZXRTdGF0ZSgpKSk7Cgl9CgoJQFRlc3QKCXB1YmxpYyB2b2lkIHRlc3RTaW5nbGV0b24wMygpIHRocm93cyBCdW5kbGVFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKCQlEdW1teUNvbnRhaW5lckFkYXB0b3IgYWRhcHRvciA9IGNyZWF0ZUR1bW15QWRhcHRvcigpOwoJCU1vZHVsZUNvbnRhaW5lciBjb250YWluZXIgPSBhZGFwdG9yLmdldENvbnRhaW5lcigpOwoJCU1vZHVsZSBzMSA9IGluc3RhbGxEdW1teU1vZHVsZSgic2luZ2xldG9uMV92MS5NRiIsICJzMV92MSIsIGNvbnRhaW5lcik7CgkJLy8gUmVzb2x2ZSBzMSBmaXJzdAoJCWNvbnRhaW5lci5yZXNvbHZlKG51bGwsIGZhbHNlKTsKCQlBc3NlcnQuYXNzZXJ0VHJ1ZSgiU2luZ2xldG9uIHYxIGlzIG5vdCByZXNvbHZlZC4iLCBNb2R1bGUuUkVTT0xWRURfU0VULmNvbnRhaW5zKHMxLmdldFN0YXRlKCkpKTsKCgkJTW9kdWxlIHMyID0gaW5zdGFsbER1bW15TW9kdWxlKCJzaW5nbGV0b24xX3YyLk1GIiwgInMxX3YyIiwgY29udGFpbmVyKTsKCQlNb2R1bGUgczMgPSBpbnN0YWxsRHVtbXlNb2R1bGUoInNpbmdsZXRvbjFfdjMuTUYiLCAiczFfdjMiLCBjb250YWluZXIpOwoKCQljb250YWluZXIucmVzb2x2ZShBcnJheXMuYXNMaXN0KHMyLCBzMyksIGZhbHNlKTsKCgkJLy8gTWFrZSBzdXJlIHMxIGlzIHRoZSBvbmx5IG9uIHJlc29sdmVkIGJlY2F1c2UgaXQgd2FzIGZpcnN0IHJlc29sdmVkCgkJQXNzZXJ0LmFzc2VydFRydWUoIlNpbmdsZXRvbiB2MSBpcyBub3QgcmVzb2x2ZWQuIiwgTW9kdWxlLlJFU09MVkVEX1NFVC5jb250YWlucyhzMS5nZXRTdGF0ZSgpKSk7CgkJQXNzZXJ0LmFzc2VydEZhbHNlKCJTaW5nbGV0b24gdjIgaXMgcmVzb2x2ZWQuIiwgTW9kdWxlLlJFU09MVkVEX1NFVC5jb250YWlucyhzMi5nZXRTdGF0ZSgpKSk7CgkJQXNzZXJ0LmFzc2VydEZhbHNlKCJTaW5nbGV0b24gdjMgaXMgcmVzb2x2ZWQuIiwgTW9kdWxlLlJFU09MVkVEX1NFVC5jb250YWlucyhzMy5nZXRTdGF0ZSgpKSk7Cgl9CgoJQFRlc3QKCXB1YmxpYyB2b2lkIHRlc3RTaW5nbGV0b24wNCgpIHRocm93cyBCdW5kbGVFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKCQlmaW5hbCBDb2xsZWN0aW9uPEJ1bmRsZVJldmlzaW9uPiBkaXNhYmxlZCA9IG5ldyBBcnJheUxpc3Q8QnVuZGxlUmV2aXNpb24+KCk7CgkJUmVzb2x2ZXJIb29rRmFjdG9yeSByZXNvbHZlckhvb2tGYWN0b3J5ID0gbmV3IFJlc29sdmVySG9va0ZhY3RvcnkoKSB7CgoJCQlAT3ZlcnJpZGUKCQkJcHVibGljIFJlc29sdmVySG9vayBiZWdpbihDb2xsZWN0aW9uPEJ1bmRsZVJldmlzaW9uPiB0cmlnZ2VycykgewoJCQkJcmV0dXJuIG5ldyBSZXNvbHZlckhvb2soKSB7CgoJCQkJCUBPdmVycmlkZQoJCQkJCXB1YmxpYyB2b2lkIGZpbHRlclNpbmdsZXRvbkNvbGxpc2lvbnMoQnVuZGxlQ2FwYWJpbGl0eSBzaW5nbGV0b24sIENvbGxlY3Rpb248QnVuZGxlQ2FwYWJpbGl0eT4gY29sbGlzaW9uQ2FuZGlkYXRlcykgewoJCQkJCQkvLyBub3RoaW5nCgkJCQkJfQoKCQkJCQlAT3ZlcnJpZGUKCQkJCQlwdWJsaWMgdm9pZCBmaWx0ZXJSZXNvbHZhYmxlKENvbGxlY3Rpb248QnVuZGxlUmV2aXNpb24+IGNhbmRpZGF0ZXMpIHsKCQkJCQkJY2FuZGlkYXRlcy5yZW1vdmVBbGwoZGlzYWJsZWQpOwoJCQkJCX0KCgkJCQkJQE92ZXJyaWRlCgkJCQkJcHVibGljIHZvaWQgZmlsdGVyTWF0Y2hlcyhCdW5kbGVSZXF1aXJlbWVudCByZXF1aXJlbWVudCwgQ29sbGVjdGlvbjxCdW5kbGVDYXBhYmlsaXR5PiBjYW5kaWRhdGVzKSB7CgkJCQkJCS8vIG5vdGhpbmcKCQkJCQl9CgoJCQkJCUBPdmVycmlkZQoJCQkJCXB1YmxpYyB2b2lkIGVuZCgpIHsKCQkJCQkJLy8gbm90aGluZwoJCQkJCX0KCQkJCX07CgkJCX0KCQl9OwoJCUR1bW15Q29udGFpbmVyQWRhcHRvciBhZGFwdG9yID0gbmV3IER1bW15Q29udGFpbmVyQWRhcHRvcihuZXcgRHVtbXlDb2xsaXNpb25Ib29rKGZhbHNlKSwgQ29sbGVjdGlvbnMuPFN0cmluZywgU3RyaW5nPiBlbXB0eU1hcCgpLCByZXNvbHZlckhvb2tGYWN0b3J5KTsKCQlNb2R1bGVDb250YWluZXIgY29udGFpbmVyID0gYWRhcHRvci5nZXRDb250YWluZXIoKTsKCgkJTW9kdWxlIHMxX3YxID0gaW5zdGFsbER1bW15TW9kdWxlKCJzaW5nbGV0b24xX3YxLk1GIiwgInMxX3YxIiwgY29udGFpbmVyKTsKCQlNb2R1bGUgczFfdjIgPSBpbnN0YWxsRHVtbXlNb2R1bGUoInNpbmdsZXRvbjFfdjIuTUYiLCAiczFfdjIiLCBjb250YWluZXIpOwoJCU1vZHVsZSBzMV92MyA9IGluc3RhbGxEdW1teU1vZHVsZSgic2luZ2xldG9uMV92My5NRiIsICJzMV92MyIsIGNvbnRhaW5lcik7CgoJCU1vZHVsZSBzMl92MSA9IGluc3RhbGxEdW1teU1vZHVsZSgic2luZ2xldG9uMl92MS5NRiIsICJzMV92MSIsIGNvbnRhaW5lcik7CgkJTW9kdWxlIHMyX3YyID0gaW5zdGFsbER1bW15TW9kdWxlKCJzaW5nbGV0b24yX3YyLk1GIiwgInMxX3YyIiwgY29udGFpbmVyKTsKCQlNb2R1bGUgczJfdjMgPSBpbnN0YWxsRHVtbXlNb2R1bGUoInNpbmdsZXRvbjJfdjMuTUYiLCAiczFfdjMiLCBjb250YWluZXIpOwoKCQljb250YWluZXIucmVzb2x2ZShudWxsLCBmYWxzZSk7CgoJCUFzc2VydC5hc3NlcnRGYWxzZSgiU2luZ2xldG9uIHYxIGlzIHJlc29sdmVkLiIsIE1vZHVsZS5SRVNPTFZFRF9TRVQuY29udGFpbnMoczFfdjEuZ2V0U3RhdGUoKSkpOwoJCUFzc2VydC5hc3NlcnRGYWxzZSgiU2luZ2xldG9uIHYyIGlzIHJlc29sdmVkLiIsIE1vZHVsZS5SRVNPTFZFRF9TRVQuY29udGFpbnMoczFfdjIuZ2V0U3RhdGUoKSkpOwoJCUFzc2VydC5hc3NlcnRUcnVlKCJTaW5nbGV0b24gdjMgaXMgbm90IHJlc29sdmVkLiIsIE1vZHVsZS5SRVNPTFZFRF9TRVQuY29udGFpbnMoczFfdjMuZ2V0U3RhdGUoKSkpOwoKCQlBc3NlcnQuYXNzZXJ0RmFsc2UoImNsaWVudCB2MSBpcyByZXNvbHZlZC4iLCBNb2R1bGUuUkVTT0xWRURfU0VULmNvbnRhaW5zKHMyX3YxLmdldFN0YXRlKCkpKTsKCQlBc3NlcnQuYXNzZXJ0RmFsc2UoImNsaWVudCB2MiBpcyByZXNvbHZlZC4iLCBNb2R1bGUuUkVTT0xWRURfU0VULmNvbnRhaW5zKHMyX3YyLmdldFN0YXRlKCkpKTsKCQlBc3NlcnQuYXNzZXJ0VHJ1ZSgiY2xpZW50IHYzIGlzIG5vdCByZXNvbHZlZC4iLCBNb2R1bGUuUkVTT0xWRURfU0VULmNvbnRhaW5zKHMyX3YzLmdldFN0YXRlKCkpKTsKCgkJLy8gbm93IGRpc2FibGUgczFfdjMKCQlkaXNhYmxlZC5hZGQoczFfdjMuZ2V0Q3VycmVudFJldmlzaW9uKCkpOwoJCWNvbnRhaW5lci5yZWZyZXNoKEFycmF5cy5hc0xpc3QoczFfdjMpKTsKCQlBc3NlcnQuYXNzZXJ0RmFsc2UoIlNpbmdsZXRvbiB2MSBpcyByZXNvbHZlZC4iLCBNb2R1bGUuUkVTT0xWRURfU0VULmNvbnRhaW5zKHMxX3YxLmdldFN0YXRlKCkpKTsKCQlBc3NlcnQuYXNzZXJ0VHJ1ZSgiU2luZ2xldG9uIHYyIGlzIG5vdCByZXNvbHZlZC4iLCBNb2R1bGUuUkVTT0xWRURfU0VULmNvbnRhaW5zKHMxX3YyLmdldFN0YXRlKCkpKTsKCQlBc3NlcnQuYXNzZXJ0RmFsc2UoIlNpbmdsZXRvbiB2MyBpcyByZXNvbHZlZC4iLCBNb2R1bGUuUkVTT0xWRURfU0VULmNvbnRhaW5zKHMxX3YzLmdldFN0YXRlKCkpKTsKCgkJQXNzZXJ0LmFzc2VydEZhbHNlKCJjbGllbnQgdjEgaXMgcmVzb2x2ZWQuIiwgTW9kdWxlLlJFU09MVkVEX1NFVC5jb250YWlucyhzMl92MS5nZXRTdGF0ZSgpKSk7CgkJQXNzZXJ0LmFzc2VydFRydWUoImNsaWVudCB2MiBpcyBub3QgcmVzb2x2ZWQuIiwgTW9kdWxlLlJFU09MVkVEX1NFVC5jb250YWlucyhzMl92Mi5nZXRTdGF0ZSgpKSk7CgkJQXNzZXJ0LmFzc2VydEZhbHNlKCJjbGllbnQgdjMgaXMgcmVzb2x2ZWQuIiwgTW9kdWxlLlJFU09MVkVEX1NFVC5jb250YWlucyhzMl92My5nZXRTdGF0ZSgpKSk7CgoJCS8vIG5vdyBkaXNhYmxlIHMxX3YyCgkJZGlzYWJsZWQuYWRkKHMxX3YyLmdldEN1cnJlbnRSZXZpc2lvbigpKTsKCQljb250YWluZXIucmVmcmVzaChBcnJheXMuYXNMaXN0KHMxX3YyKSk7CgkJQXNzZXJ0LmFzc2VydFRydWUoIlNpbmdsZXRvbiB2MSBpcyBub3QgcmVzb2x2ZWQuIiwgTW9kdWxlLlJFU09MVkVEX1NFVC5jb250YWlucyhzMV92MS5nZXRTdGF0ZSgpKSk7CgkJQXNzZXJ0LmFzc2VydEZhbHNlKCJTaW5nbGV0b24gdjIgaXMgcmVzb2x2ZWQuIiwgTW9kdWxlLlJFU09MVkVEX1NFVC5jb250YWlucyhzMV92Mi5nZXRTdGF0ZSgpKSk7CgkJQXNzZXJ0LmFzc2VydEZhbHNlKCJTaW5nbGV0b24gdjMgaXMgcmVzb2x2ZWQuIiwgTW9kdWxlLlJFU09MVkVEX1NFVC5jb250YWlucyhzMV92My5nZXRTdGF0ZSgpKSk7CgoJCUFzc2VydC5hc3NlcnRUcnVlKCJjbGllbnQgdjEgaXMgbm90IHJlc29sdmVkLiIsIE1vZHVsZS5SRVNPTFZFRF9TRVQuY29udGFpbnMoczJfdjEuZ2V0U3RhdGUoKSkpOwoJCUFzc2VydC5hc3NlcnRGYWxzZSgiY2xpZW50IHYyIGlzIHJlc29sdmVkLiIsIE1vZHVsZS5SRVNPTFZFRF9TRVQuY29udGFpbnMoczJfdjIuZ2V0U3RhdGUoKSkpOwoJCUFzc2VydC5hc3NlcnRGYWxzZSgiY2xpZW50IHYzIGlzIHJlc29sdmVkLiIsIE1vZHVsZS5SRVNPTFZFRF9TRVQuY29udGFpbnMoczJfdjMuZ2V0U3RhdGUoKSkpOwoKCX0KCglAVGVzdAoJcHVibGljIHZvaWQgdGVzdEV2ZW50c0luc3RhbGwoKSB0aHJvd3MgQnVuZGxlRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CgkJRHVtbXlDb250YWluZXJBZGFwdG9yIGFkYXB0b3IgPSBjcmVhdGVEdW1teUFkYXB0b3IoKTsKCQlNb2R1bGVDb250YWluZXIgY29udGFpbmVyID0gYWRhcHRvci5nZXRDb250YWluZXIoKTsKCQlNb2R1bGUgYzEgPSBpbnN0YWxsRHVtbXlNb2R1bGUoImMxX3YxLk1GIiwgImMxX3YxIiwgY29udGFpbmVyKTsKCQlNb2R1bGUgYzIgPSBpbnN0YWxsRHVtbXlNb2R1bGUoImMyX3YxLk1GIiwgImMyX3YxIiwgY29udGFpbmVyKTsKCQlNb2R1bGUgYzMgPSBpbnN0YWxsRHVtbXlNb2R1bGUoImMzX3YxLk1GIiwgImMzX3YxIiwgY29udGFpbmVyKTsKCQlNb2R1bGUgYzQgPSBpbnN0YWxsRHVtbXlNb2R1bGUoImM0X3YxLk1GIiwgImM0X3YxIiwgY29udGFpbmVyKTsKCQlNb2R1bGUgYzUgPSBpbnN0YWxsRHVtbXlNb2R1bGUoImM1X3YxLk1GIiwgImM1X3YxIiwgY29udGFpbmVyKTsKCQlNb2R1bGUgYzYgPSBpbnN0YWxsRHVtbXlNb2R1bGUoImM2X3YxLk1GIiwgImM2X3YxIiwgY29udGFpbmVyKTsKCQlNb2R1bGUgYzcgPSBpbnN0YWxsRHVtbXlNb2R1bGUoImM3X3YxLk1GIiwgImM3X3YxIiwgY29udGFpbmVyKTsKCgkJTGlzdDxEdW1teU1vZHVsZUV2ZW50PiBhY3R1YWwgPSBhZGFwdG9yLmdldERhdGFiYXNlKCkuZ2V0TW9kdWxlRXZlbnRzKCk7CgkJTGlzdDxEdW1teU1vZHVsZUV2ZW50PiBleHBlY3RlZCA9IEFycmF5cy5hc0xpc3QobmV3IER1bW15TW9kdWxlRXZlbnQoYzEsIE1vZHVsZUV2ZW50LklOU1RBTExFRCwgU3RhdGUuSU5TVEFMTEVEKSwgbmV3IER1bW15TW9kdWxlRXZlbnQoYzIsIE1vZHVsZUV2ZW50LklOU1RBTExFRCwgU3RhdGUuSU5TVEFMTEVEKSwgbmV3IER1bW15TW9kdWxlRXZlbnQoYzMsIE1vZHVsZUV2ZW50LklOU1RBTExFRCwgU3RhdGUuSU5TVEFMTEVEKSwgbmV3IER1bW15TW9kdWxlRXZlbnQoYzQsIE1vZHVsZUV2ZW50LklOU1RBTExFRCwgU3RhdGUuSU5TVEFMTEVEKSwgbmV3IER1bW15TW9kdWxlRXZlbnQoYzUsIE1vZHVsZUV2ZW50LklOU1RBTExFRCwgU3RhdGUuSU5TVEFMTEVEKSwgbmV3IER1bW15TW9kdWxlRXZlbnQoYzYsIE1vZHVsZUV2ZW50LklOU1RBTExFRCwgU3RhdGUuSU5TVEFMTEVEKSwgbmV3IER1bW15TW9kdWxlRXZlbnQoYzcsIE1vZHVsZUV2ZW50LklOU1RBTExFRCwgU3RhdGUuSU5TVEFMTEVEKSk7CgkJQXNzZXJ0LmFzc2VydEVxdWFscygiV3JvbmcgaW5zdGFsbCBldmVudHMuIiwgZXhwZWN0ZWQsIGFjdHVhbCk7Cgl9CgoJQFRlc3QKCXB1YmxpYyB2b2lkIHRlc3RFdmVudHNSZXNvbHZlZCgpIHRocm93cyBCdW5kbGVFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKCQlEdW1teUNvbnRhaW5lckFkYXB0b3IgYWRhcHRvciA9IGNyZWF0ZUR1bW15QWRhcHRvcigpOwoJCU1vZHVsZUNvbnRhaW5lciBjb250YWluZXIgPSBhZGFwdG9yLmdldENvbnRhaW5lcigpOwoJCUR1bW15TW9kdWxlRGF0YWJhc2UgZGF0YWJhc2UgPSBhZGFwdG9yLmdldERhdGFiYXNlKCk7CgoJCU1vZHVsZSBzeXN0ZW1CdW5kbGUgPSBpbnN0YWxsRHVtbXlNb2R1bGUoInN5c3RlbS5idW5kbGUuTUYiLCBDb25zdGFudHMuU1lTVEVNX0JVTkRMRV9MT0NBVElPTiwgY29udGFpbmVyKTsKCgkJY29udGFpbmVyLnJlc29sdmUoQXJyYXlzLmFzTGlzdChzeXN0ZW1CdW5kbGUpLCB0cnVlKTsKCgkJTW9kdWxlIGMxID0gaW5zdGFsbER1bW15TW9kdWxlKCJjMV92MS5NRiIsICJjMV92MSIsIGNvbnRhaW5lcik7CgkJTW9kdWxlIGMyID0gaW5zdGFsbER1bW15TW9kdWxlKCJjMl92MS5NRiIsICJjMl92MSIsIGNvbnRhaW5lcik7CgkJTW9kdWxlIGMzID0gaW5zdGFsbER1bW15TW9kdWxlKCJjM192MS5NRiIsICJjM192MSIsIGNvbnRhaW5lcik7CgkJTW9kdWxlIGM0ID0gaW5zdGFsbER1bW15TW9kdWxlKCJjNF92MS5NRiIsICJjNF92MSIsIGNvbnRhaW5lcik7CgkJTW9kdWxlIGM1ID0gaW5zdGFsbER1bW15TW9kdWxlKCJjNV92MS5NRiIsICJjNV92MSIsIGNvbnRhaW5lcik7CgkJTW9kdWxlIGM2ID0gaW5zdGFsbER1bW15TW9kdWxlKCJjNl92MS5NRiIsICJjNl92MSIsIGNvbnRhaW5lcik7CgkJTW9kdWxlIGM3ID0gaW5zdGFsbER1bW15TW9kdWxlKCJjN192MS5NRiIsICJjN192MSIsIGNvbnRhaW5lcik7CgkJLy8gdGhyb3cgYXdheSBpbnN0YWxsZWQgZXZlbnRzCgkJZGF0YWJhc2UuZ2V0TW9kdWxlRXZlbnRzKCk7CgoJCWNvbnRhaW5lci5yZXNvbHZlKEFycmF5cy5hc0xpc3QoYzEsIGMyLCBjMywgYzQsIGM1LCBjNiwgYzcpLCB0cnVlKTsKCQlMaXN0PER1bW15TW9kdWxlRXZlbnQ+IGFjdHVhbCA9IGRhdGFiYXNlLmdldE1vZHVsZUV2ZW50cygpOwoJCUxpc3Q8RHVtbXlNb2R1bGVFdmVudD4gZXhwZWN0ZWQgPSBuZXcgQXJyYXlMaXN0PER1bW15TW9kdWxlRXZlbnQ+KEFycmF5cy5hc0xpc3QobmV3IER1bW15TW9kdWxlRXZlbnQoYzEsIE1vZHVsZUV2ZW50LlJFU09MVkVELCBTdGF0ZS5SRVNPTFZFRCksIG5ldyBEdW1teU1vZHVsZUV2ZW50KGMyLCBNb2R1bGVFdmVudC5SRVNPTFZFRCwgU3RhdGUuUkVTT0xWRUQpLCBuZXcgRHVtbXlNb2R1bGVFdmVudChjMywgTW9kdWxlRXZlbnQuUkVTT0xWRUQsIFN0YXRlLlJFU09MVkVEKSwgbmV3IER1bW15TW9kdWxlRXZlbnQoYzQsIE1vZHVsZUV2ZW50LlJFU09MVkVELCBTdGF0ZS5SRVNPTFZFRCksIG5ldyBEdW1teU1vZHVsZUV2ZW50KGM1LCBNb2R1bGVFdmVudC5SRVNPTFZFRCwgU3RhdGUuUkVTT0xWRUQpLCBuZXcgRHVtbXlNb2R1bGVFdmVudChjNiwgTW9kdWxlRXZlbnQuUkVTT0xWRUQsIFN0YXRlLlJFU09MVkVEKSwgbmV3IER1bW15TW9kdWxlRXZlbnQoYzcsIE1vZHVsZUV2ZW50LlJFU09MVkVELCBTdGF0ZS5SRVNPTFZFRCkpKTsKCQlhc3NlcnRFdmVudHMoZXhwZWN0ZWQsIGFjdHVhbCwgZmFsc2UpOwoJfQoKCUBUZXN0CglwdWJsaWMgdm9pZCB0ZXN0RXZlbnRzUmVmcmVzaCgpIHRocm93cyBCdW5kbGVFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKCQlEdW1teUNvbnRhaW5lckFkYXB0b3IgYWRhcHRvciA9IGNyZWF0ZUR1bW15QWRhcHRvcigpOwoJCU1vZHVsZUNvbnRhaW5lciBjb250YWluZXIgPSBhZGFwdG9yLmdldENvbnRhaW5lcigpOwoJCUR1bW15TW9kdWxlRGF0YWJhc2UgZGF0YWJhc2UgPSBhZGFwdG9yLmdldERhdGFiYXNlKCk7CgoJCU1vZHVsZSBzeXN0ZW1CdW5kbGUgPSBpbnN0YWxsRHVtbXlNb2R1bGUoInN5c3RlbS5idW5kbGUuTUYiLCBDb25zdGFudHMuU1lTVEVNX0JVTkRMRV9MT0NBVElPTiwgY29udGFpbmVyKTsKCgkJY29udGFpbmVyLnJlc29sdmUoQXJyYXlzLmFzTGlzdChzeXN0ZW1CdW5kbGUpLCB0cnVlKTsKCgkJTW9kdWxlIGMxID0gaW5zdGFsbER1bW15TW9kdWxlKCJjMV92MS5NRiIsICJjMV92MSIsIGNvbnRhaW5lcik7CgkJTW9kdWxlIGMyID0gaW5zdGFsbER1bW15TW9kdWxlKCJjMl92MS5NRiIsICJjMl92MSIsIGNvbnRhaW5lcik7CgkJTW9kdWxlIGMzID0gaW5zdGFsbER1bW15TW9kdWxlKCJjM192MS5NRiIsICJjM192MSIsIGNvbnRhaW5lcik7CgkJTW9kdWxlIGM0ID0gaW5zdGFsbER1bW15TW9kdWxlKCJjNF92MS5NRiIsICJjNF92MSIsIGNvbnRhaW5lcik7CgkJTW9kdWxlIGM1ID0gaW5zdGFsbER1bW15TW9kdWxlKCJjNV92MS5NRiIsICJjNV92MSIsIGNvbnRhaW5lcik7CgkJTW9kdWxlIGM2ID0gaW5zdGFsbER1bW15TW9kdWxlKCJjNl92MS5NRiIsICJjNl92MSIsIGNvbnRhaW5lcik7CgkJTW9kdWxlIGM3ID0gaW5zdGFsbER1bW15TW9kdWxlKCJjN192MS5NRiIsICJjN192MSIsIGNvbnRhaW5lcik7CgoJCWNvbnRhaW5lci5yZXNvbHZlKEFycmF5cy5hc0xpc3QoYzEsIGMyLCBjMywgYzQsIGM1LCBjNiwgYzcpLCB0cnVlKTsKCQkvLyB0aHJvdyBhd2F5IGluc3RhbGxlZCBhbmQgcmVzb2x2ZWQgZXZlbnRzCgkJZGF0YWJhc2UuZ2V0TW9kdWxlRXZlbnRzKCk7CgoJCWNvbnRhaW5lci5yZWZyZXNoKEFycmF5cy5hc0xpc3Qoc3lzdGVtQnVuZGxlKSk7CgkJTGlzdDxEdW1teU1vZHVsZUV2ZW50PiBhY3R1YWwgPSBkYXRhYmFzZS5nZXRNb2R1bGVFdmVudHMoKTsKCQlMaXN0PER1bW15TW9kdWxlRXZlbnQ+IGV4cGVjdGVkID0gbmV3IEFycmF5TGlzdDxEdW1teU1vZHVsZUV2ZW50PihBcnJheXMuYXNMaXN0KG5ldyBEdW1teU1vZHVsZUV2ZW50KHN5c3RlbUJ1bmRsZSwgTW9kdWxlRXZlbnQuVU5SRVNPTFZFRCwgU3RhdGUuSU5TVEFMTEVEKSwgbmV3IER1bW15TW9kdWxlRXZlbnQoYzEsIE1vZHVsZUV2ZW50LlVOUkVTT0xWRUQsIFN0YXRlLklOU1RBTExFRCksIG5ldyBEdW1teU1vZHVsZUV2ZW50KGMyLCBNb2R1bGVFdmVudC5VTlJFU09MVkVELCBTdGF0ZS5JTlNUQUxMRUQpLCBuZXcgRHVtbXlNb2R1bGVFdmVudChjMywgTW9kdWxlRXZlbnQuVU5SRVNPTFZFRCwgU3RhdGUuSU5TVEFMTEVEKSwgbmV3IER1bW15TW9kdWxlRXZlbnQoYzQsIE1vZHVsZUV2ZW50LlVOUkVTT0xWRUQsIFN0YXRlLklOU1RBTExFRCksIG5ldyBEdW1teU1vZHVsZUV2ZW50KGM1LCBNb2R1bGVFdmVudC5VTlJFU09MVkVELCBTdGF0ZS5JTlNUQUxMRUQpLCBuZXcgRHVtbXlNb2R1bGVFdmVudChjNiwgTW9kdWxlRXZlbnQuVU5SRVNPTFZFRCwgU3RhdGUuSU5TVEFMTEVEKSwgbmV3IER1bW15TW9kdWxlRXZlbnQoYzcsIE1vZHVsZUV2ZW50LlVOUkVTT0xWRUQsIFN0YXRlLklOU1RBTExFRCksIG5ldyBEdW1teU1vZHVsZUV2ZW50KHN5c3RlbUJ1bmRsZSwgTW9kdWxlRXZlbnQuUkVTT0xWRUQsIFN0YXRlLlJFU09MVkVEKSwgbmV3IER1bW15TW9kdWxlRXZlbnQoYzEsIE1vZHVsZUV2ZW50LlJFU09MVkVELCBTdGF0ZS5SRVNPTFZFRCksCgkJCQluZXcgRHVtbXlNb2R1bGVFdmVudChjMiwgTW9kdWxlRXZlbnQuUkVTT0xWRUQsIFN0YXRlLlJFU09MVkVEKSwgbmV3IER1bW15TW9kdWxlRXZlbnQoYzMsIE1vZHVsZUV2ZW50LlJFU09MVkVELCBTdGF0ZS5SRVNPTFZFRCksIG5ldyBEdW1teU1vZHVsZUV2ZW50KGM0LCBNb2R1bGVFdmVudC5SRVNPTFZFRCwgU3RhdGUuUkVTT0xWRUQpLCBuZXcgRHVtbXlNb2R1bGVFdmVudChjNSwgTW9kdWxlRXZlbnQuUkVTT0xWRUQsIFN0YXRlLlJFU09MVkVEKSwgbmV3IER1bW15TW9kdWxlRXZlbnQoYzYsIE1vZHVsZUV2ZW50LlJFU09MVkVELCBTdGF0ZS5SRVNPTFZFRCksIG5ldyBEdW1teU1vZHVsZUV2ZW50KGM3LCBNb2R1bGVFdmVudC5SRVNPTFZFRCwgU3RhdGUuUkVTT0xWRUQpKSk7CgkJYXNzZXJ0RXZlbnRzKGV4cGVjdGVkLCBhY3R1YWwsIGZhbHNlKTsKCX0KCglAVGVzdAoJcHVibGljIHZvaWQgdGVzdEV2ZW50c1N0YXJ0KCkgdGhyb3dzIEJ1bmRsZUV4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewoJCUR1bW15Q29udGFpbmVyQWRhcHRvciBhZGFwdG9yID0gY3JlYXRlRHVtbXlBZGFwdG9yKCk7CgkJTW9kdWxlQ29udGFpbmVyIGNvbnRhaW5lciA9IGFkYXB0b3IuZ2V0Q29udGFpbmVyKCk7CgkJRHVtbXlNb2R1bGVEYXRhYmFzZSBkYXRhYmFzZSA9IGFkYXB0b3IuZ2V0RGF0YWJhc2UoKTsKCgkJTW9kdWxlIHN5c3RlbUJ1bmRsZSA9IGluc3RhbGxEdW1teU1vZHVsZSgic3lzdGVtLmJ1bmRsZS5NRiIsIENvbnN0YW50cy5TWVNURU1fQlVORExFX0xPQ0FUSU9OLCBjb250YWluZXIpOwoKCQljb250YWluZXIucmVzb2x2ZShBcnJheXMuYXNMaXN0KHN5c3RlbUJ1bmRsZSksIHRydWUpOwoKCQkvLyBhY3R1YWxseSBsYXVuY2ggdGhlIGNvbnRhaW5lcgoJCXN5c3RlbUJ1bmRsZS5zdGFydCgpOwoKCQlNb2R1bGUgYzEgPSBpbnN0YWxsRHVtbXlNb2R1bGUoImMxX3YxLk1GIiwgImMxX3YxIiwgY29udGFpbmVyKTsKCQlNb2R1bGUgYzIgPSBpbnN0YWxsRHVtbXlNb2R1bGUoImMyX3YxLk1GIiwgImMyX3YxIiwgY29udGFpbmVyKTsKCQlNb2R1bGUgYzMgPSBpbnN0YWxsRHVtbXlNb2R1bGUoImMzX3YxLk1GIiwgImMzX3YxIiwgY29udGFpbmVyKTsKCQlNb2R1bGUgYzQgPSBpbnN0YWxsRHVtbXlNb2R1bGUoImM0X3YxLk1GIiwgImM0X3YxIiwgY29udGFpbmVyKTsKCQlNb2R1bGUgYzUgPSBpbnN0YWxsRHVtbXlNb2R1bGUoImM1X3YxLk1GIiwgImM1X3YxIiwgY29udGFpbmVyKTsKCQlNb2R1bGUgYzYgPSBpbnN0YWxsRHVtbXlNb2R1bGUoImM2X3YxLk1GIiwgImM2X3YxIiwgY29udGFpbmVyKTsKCQlNb2R1bGUgYzcgPSBpbnN0YWxsRHVtbXlNb2R1bGUoImM3X3YxLk1GIiwgImM3X3YxIiwgY29udGFpbmVyKTsKCQkvLyB0aHJvdyBhd2F5IGluc3RhbGxlZCBldmVudHMKCQlkYXRhYmFzZS5nZXRNb2R1bGVFdmVudHMoKTsKCgkJYzcuc3RhcnQoKTsKCgkJTGlzdDxEdW1teU1vZHVsZUV2ZW50PiBhY3R1YWwgPSBkYXRhYmFzZS5nZXRNb2R1bGVFdmVudHMoKTsKCQlMaXN0PER1bW15TW9kdWxlRXZlbnQ+IGV4cGVjdGVkID0gbmV3IEFycmF5TGlzdDxEdW1teU1vZHVsZUV2ZW50PihBcnJheXMuYXNMaXN0KG5ldyBEdW1teU1vZHVsZUV2ZW50KGMxLCBNb2R1bGVFdmVudC5SRVNPTFZFRCwgU3RhdGUuUkVTT0xWRUQpLCBuZXcgRHVtbXlNb2R1bGVFdmVudChjMiwgTW9kdWxlRXZlbnQuUkVTT0xWRUQsIFN0YXRlLlJFU09MVkVEKSwgbmV3IER1bW15TW9kdWxlRXZlbnQoYzMsIE1vZHVsZUV2ZW50LlJFU09MVkVELCBTdGF0ZS5SRVNPTFZFRCksIG5ldyBEdW1teU1vZHVsZUV2ZW50KGM0LCBNb2R1bGVFdmVudC5SRVNPTFZFRCwgU3RhdGUuUkVTT0xWRUQpLCBuZXcgRHVtbXlNb2R1bGVFdmVudChjNSwgTW9kdWxlRXZlbnQuUkVTT0xWRUQsIFN0YXRlLlJFU09MVkVEKSwgbmV3IER1bW15TW9kdWxlRXZlbnQoYzYsIE1vZHVsZUV2ZW50LlJFU09MVkVELCBTdGF0ZS5SRVNPTFZFRCksIG5ldyBEdW1teU1vZHVsZUV2ZW50KGM3LCBNb2R1bGVFdmVudC5SRVNPTFZFRCwgU3RhdGUuUkVTT0xWRUQpLCBuZXcgRHVtbXlNb2R1bGVFdmVudChjNywgTW9kdWxlRXZlbnQuU1RBUlRJTkcsIFN0YXRlLlNUQVJUSU5HKSwgbmV3IER1bW15TW9kdWxlRXZlbnQoYzcsIE1vZHVsZUV2ZW50LlNUQVJURUQsIFN0YXRlLkFDVElWRSkpKTsKCQlhc3NlcnRFdmVudHMoZXhwZWN0ZWQsIGFjdHVhbCwgZmFsc2UpOwoJfQoKCUBUZXN0CglwdWJsaWMgdm9pZCB0ZXN0RXZlbnRzU3RhcnRSZWZyZXNoKCkgdGhyb3dzIEJ1bmRsZUV4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewoJCUR1bW15Q29udGFpbmVyQWRhcHRvciBhZGFwdG9yID0gY3JlYXRlRHVtbXlBZGFwdG9yKCk7CgkJTW9kdWxlQ29udGFpbmVyIGNvbnRhaW5lciA9IGFkYXB0b3IuZ2V0Q29udGFpbmVyKCk7CgkJRHVtbXlNb2R1bGVEYXRhYmFzZSBkYXRhYmFzZSA9IGFkYXB0b3IuZ2V0RGF0YWJhc2UoKTsKCgkJTW9kdWxlIHN5c3RlbUJ1bmRsZSA9IGluc3RhbGxEdW1teU1vZHVsZSgic3lzdGVtLmJ1bmRsZS5NRiIsIENvbnN0YW50cy5TWVNURU1fQlVORExFX0xPQ0FUSU9OLCBjb250YWluZXIpOwoKCQljb250YWluZXIucmVzb2x2ZShBcnJheXMuYXNMaXN0KHN5c3RlbUJ1bmRsZSksIHRydWUpOwoJCS8vIGFjdHVhbGx5IGxhdW5jaCB0aGUgY29udGFpbmVyCgkJc3lzdGVtQnVuZGxlLnN0YXJ0KCk7CgoJCU1vZHVsZSBjNCA9IGluc3RhbGxEdW1teU1vZHVsZSgiYzRfdjEuTUYiLCAiYzRfdjEiLCBjb250YWluZXIpOwoJCU1vZHVsZSBjNSA9IGluc3RhbGxEdW1teU1vZHVsZSgiYzVfdjEuTUYiLCAiYzVfdjEiLCBjb250YWluZXIpOwoJCU1vZHVsZSBjNiA9IGluc3RhbGxEdW1teU1vZHVsZSgiYzZfdjEuTUYiLCAiYzZfdjEiLCBjb250YWluZXIpOwoJCU1vZHVsZSBjNyA9IGluc3RhbGxEdW1teU1vZHVsZSgiYzdfdjEuTUYiLCAiYzdfdjEiLCBjb250YWluZXIpOwoKCQljNy5zdGFydCgpOwoJCS8vIGRpc2NhcmQgZXZlbnRzCgkJZGF0YWJhc2UuZ2V0TW9kdWxlRXZlbnRzKCk7CgkJY29udGFpbmVyLnJlZnJlc2goQXJyYXlzLmFzTGlzdChjNCkpOwoJCUxpc3Q8RHVtbXlNb2R1bGVFdmVudD4gYWN0dWFsID0gZGF0YWJhc2UuZ2V0TW9kdWxlRXZlbnRzKCk7CgkJTGlzdDxEdW1teU1vZHVsZUV2ZW50PiBleHBlY3RlZCA9IG5ldyBBcnJheUxpc3Q8RHVtbXlNb2R1bGVFdmVudD4oQXJyYXlzLmFzTGlzdChuZXcgRHVtbXlNb2R1bGVFdmVudChjNywgTW9kdWxlRXZlbnQuU1RPUFBJTkcsIFN0YXRlLlNUT1BQSU5HKSwgbmV3IER1bW15TW9kdWxlRXZlbnQoYzcsIE1vZHVsZUV2ZW50LlNUT1BQRUQsIFN0YXRlLlJFU09MVkVEKSwgbmV3IER1bW15TW9kdWxlRXZlbnQoYzQsIE1vZHVsZUV2ZW50LlVOUkVTT0xWRUQsIFN0YXRlLklOU1RBTExFRCksIG5ldyBEdW1teU1vZHVsZUV2ZW50KGM1LCBNb2R1bGVFdmVudC5VTlJFU09MVkVELCBTdGF0ZS5JTlNUQUxMRUQpLCBuZXcgRHVtbXlNb2R1bGVFdmVudChjNiwgTW9kdWxlRXZlbnQuVU5SRVNPTFZFRCwgU3RhdGUuSU5TVEFMTEVEKSwgbmV3IER1bW15TW9kdWxlRXZlbnQoYzcsIE1vZHVsZUV2ZW50LlVOUkVTT0xWRUQsIFN0YXRlLklOU1RBTExFRCksIG5ldyBEdW1teU1vZHVsZUV2ZW50KGM0LCBNb2R1bGVFdmVudC5SRVNPTFZFRCwgU3RhdGUuUkVTT0xWRUQpLCBuZXcgRHVtbXlNb2R1bGVFdmVudChjNSwgTW9kdWxlRXZlbnQuUkVTT0xWRUQsIFN0YXRlLlJFU09MVkVEKSwgbmV3IER1bW15TW9kdWxlRXZlbnQoYzYsIE1vZHVsZUV2ZW50LlJFU09MVkVELCBTdGF0ZS5SRVNPTFZFRCksIG5ldyBEdW1teU1vZHVsZUV2ZW50KGM3LCBNb2R1bGVFdmVudC5SRVNPTFZFRCwgU3RhdGUuUkVTT0xWRUQpLAoJCQkJbmV3IER1bW15TW9kdWxlRXZlbnQoYzcsIE1vZHVsZUV2ZW50LlNUQVJUSU5HLCBTdGF0ZS5TVEFSVElORyksIG5ldyBEdW1teU1vZHVsZUV2ZW50KGM3LCBNb2R1bGVFdmVudC5TVEFSVEVELCBTdGF0ZS5BQ1RJVkUpKSk7CgkJYXNzZXJ0RXZlbnRzKGV4cGVjdGVkLCBhY3R1YWwsIGZhbHNlKTsKCX0KCglAVGVzdAoJcHVibGljIHZvaWQgdGVzdFJlbW92YWxQZW5kaW5nKCkgdGhyb3dzIEJ1bmRsZUV4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewoJCUR1bW15Q29udGFpbmVyQWRhcHRvciBhZGFwdG9yID0gY3JlYXRlRHVtbXlBZGFwdG9yKCk7CgkJTW9kdWxlQ29udGFpbmVyIGNvbnRhaW5lciA9IGFkYXB0b3IuZ2V0Q29udGFpbmVyKCk7CgkJRHVtbXlNb2R1bGVEYXRhYmFzZSBkYXRhYmFzZSA9IGFkYXB0b3IuZ2V0RGF0YWJhc2UoKTsKCgkJTW9kdWxlIHN5c3RlbUJ1bmRsZSA9IGluc3RhbGxEdW1teU1vZHVsZSgic3lzdGVtLmJ1bmRsZS5NRiIsIENvbnN0YW50cy5TWVNURU1fQlVORExFX0xPQ0FUSU9OLCBjb250YWluZXIpOwoKCQljb250YWluZXIucmVzb2x2ZShBcnJheXMuYXNMaXN0KHN5c3RlbUJ1bmRsZSksIHRydWUpOwoKCQlNb2R1bGUgYzQgPSBpbnN0YWxsRHVtbXlNb2R1bGUoImM0X3YxLk1GIiwgImM0X3YxIiwgY29udGFpbmVyKTsKCQlNb2R1bGUgYzYgPSBpbnN0YWxsRHVtbXlNb2R1bGUoImM2X3YxLk1GIiwgImM2X3YxIiwgY29udGFpbmVyKTsKCQlNb2R1bGUgYzcgPSBpbnN0YWxsRHVtbXlNb2R1bGUoImM3X3YxLk1GIiwgImM3X3YxIiwgY29udGFpbmVyKTsKCgkJY29udGFpbmVyLnJlc29sdmUoQXJyYXlzLmFzTGlzdChjNyksIHRydWUpOwoJCS8vIHRocm93IG91dCBpbnN0YWxsZWQgYW5kIHJlc29sdmVkIGV2ZW50cwoJCWRhdGFiYXNlLmdldE1vZHVsZUV2ZW50cygpOwoKCQlNb2R1bGVSZXZpc2lvbiBjNFJldmlzaW9uMCA9IGM0LmdldEN1cnJlbnRSZXZpc2lvbigpOwoJCS8vIHVwZGF0aW5nIHRvIGlkZW50aWNhbCBjb250ZW50CgkJY29udGFpbmVyLnVwZGF0ZShjNCwgT1NHaU1hbmlmZXN0QnVpbGRlckZhY3RvcnkuY3JlYXRlQnVpbGRlcihnZXRNYW5pZmVzdCgiYzRfdjEuTUYiKSksIG51bGwpOwoJCWNvbnRhaW5lci5yZXNvbHZlKEFycmF5cy5hc0xpc3QoYzQpLCB0cnVlKTsKCgkJQ29sbGVjdGlvbjxNb2R1bGVSZXZpc2lvbj4gcmVtb3ZhbFBlbmRpbmcgPSBjb250YWluZXIuZ2V0UmVtb3ZhbFBlbmRpbmcoKTsKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJXcm9uZyBudW1iZXIgb2YgcmVtb3ZhbCBwZW5kaW5nIiwgMSwgcmVtb3ZhbFBlbmRpbmcuc2l6ZSgpKTsKCQlBc3NlcnQuYXNzZXJ0VHJ1ZSgiV3JvbmcgbW9kdWxlIHJlbW92YWxQZW5kaW5nOiAiICsgcmVtb3ZhbFBlbmRpbmcsIHJlbW92YWxQZW5kaW5nLmNvbnRhaW5zKGM0UmV2aXNpb24wKSk7CgoJCU1vZHVsZVJldmlzaW9uIGM2UmV2aXNpb24wID0gYzYuZ2V0Q3VycmVudFJldmlzaW9uKCk7CgkJLy8gdXBkYXRpbmcgdG8gaWRlbnRpY2FsIGNvbnRlbnQKCQljb250YWluZXIudXBkYXRlKGM2LCBPU0dpTWFuaWZlc3RCdWlsZGVyRmFjdG9yeS5jcmVhdGVCdWlsZGVyKGdldE1hbmlmZXN0KCJjNl92MS5NRiIpKSwgbnVsbCk7CgkJY29udGFpbmVyLnJlc29sdmUoQXJyYXlzLmFzTGlzdChjNiksIHRydWUpOwoKCQlyZW1vdmFsUGVuZGluZyA9IGNvbnRhaW5lci5nZXRSZW1vdmFsUGVuZGluZygpOwoJCUFzc2VydC5hc3NlcnRFcXVhbHMoIldyb25nIG51bWJlciBvZiByZW1vdmFsIHBlbmRpbmciLCAyLCByZW1vdmFsUGVuZGluZy5zaXplKCkpOwoJCUFzc2VydC5hc3NlcnRUcnVlKCJXcm9uZyBtb2R1bGUgcmVtb3ZhbFBlbmRpbmc6ICIgKyByZW1vdmFsUGVuZGluZywgcmVtb3ZhbFBlbmRpbmcuY29udGFpbnNBbGwoQXJyYXlzLmFzTGlzdChjNFJldmlzaW9uMCwgYzZSZXZpc2lvbjApKSk7CgoJCS8vIHVwZGF0ZSBhZ2FpbiB3aXRoIGlkZW50aWNhbCBjb250ZW50CgkJY29udGFpbmVyLnVwZGF0ZShjNCwgT1NHaU1hbmlmZXN0QnVpbGRlckZhY3RvcnkuY3JlYXRlQnVpbGRlcihnZXRNYW5pZmVzdCgiYzRfdjEuTUYiKSksIG51bGwpOwoJCWNvbnRhaW5lci51cGRhdGUoYzYsIE9TR2lNYW5pZmVzdEJ1aWxkZXJGYWN0b3J5LmNyZWF0ZUJ1aWxkZXIoZ2V0TWFuaWZlc3QoImM2X3YxLk1GIikpLCBudWxsKTsKCQljb250YWluZXIucmVzb2x2ZShBcnJheXMuYXNMaXN0KGM0LCBjNiksIHRydWUpOwoKCQkvLyBBZ2FpbiB3ZSBvbmx5IGhhdmUgdHdvIHNpbmNlIHRoZSBwcmV2aW91cyBjdXJyZW50IHJldmlzaW9ucyBkaWQgbm90IGhhdmUgYW55IGRlcGVuZGVudHMKCQlyZW1vdmFsUGVuZGluZyA9IGNvbnRhaW5lci5nZXRSZW1vdmFsUGVuZGluZygpOwoJCUFzc2VydC5hc3NlcnRFcXVhbHMoIldyb25nIG51bWJlciBvZiByZW1vdmFsIHBlbmRpbmciLCAyLCByZW1vdmFsUGVuZGluZy5zaXplKCkpOwoJCUFzc2VydC5hc3NlcnRUcnVlKCJXcm9uZyBtb2R1bGUgcmVtb3ZhbFBlbmRpbmc6ICIgKyByZW1vdmFsUGVuZGluZywgcmVtb3ZhbFBlbmRpbmcuY29udGFpbnNBbGwoQXJyYXlzLmFzTGlzdChjNFJldmlzaW9uMCwgYzZSZXZpc2lvbjApKSk7CgoJCWNvbnRhaW5lci5yZWZyZXNoKG51bGwpOwoKCQlyZW1vdmFsUGVuZGluZyA9IGNvbnRhaW5lci5nZXRSZW1vdmFsUGVuZGluZygpOwoJCUFzc2VydC5hc3NlcnRFcXVhbHMoIldyb25nIG51bWJlciBvZiByZW1vdmFsIHBlbmRpbmciLCAwLCByZW1vdmFsUGVuZGluZy5zaXplKCkpOwoKCQlMaXN0PER1bW15TW9kdWxlRXZlbnQ+IGFjdHVhbCA9IGRhdGFiYXNlLmdldE1vZHVsZUV2ZW50cygpOwoJCUxpc3Q8RHVtbXlNb2R1bGVFdmVudD4gZXhwZWN0ZWQgPSBuZXcgQXJyYXlMaXN0PER1bW15TW9kdWxlRXZlbnQ+KEFycmF5cy5hc0xpc3QobmV3IER1bW15TW9kdWxlRXZlbnQoYzQsIE1vZHVsZUV2ZW50LlVOUkVTT0xWRUQsIFN0YXRlLklOU1RBTExFRCksIG5ldyBEdW1teU1vZHVsZUV2ZW50KGM0LCBNb2R1bGVFdmVudC5VUERBVEVELCBTdGF0ZS5JTlNUQUxMRUQpLCBuZXcgRHVtbXlNb2R1bGVFdmVudChjNCwgTW9kdWxlRXZlbnQuUkVTT0xWRUQsIFN0YXRlLlJFU09MVkVEKSwKCgkJCQluZXcgRHVtbXlNb2R1bGVFdmVudChjNiwgTW9kdWxlRXZlbnQuVU5SRVNPTFZFRCwgU3RhdGUuSU5TVEFMTEVEKSwgbmV3IER1bW15TW9kdWxlRXZlbnQoYzYsIE1vZHVsZUV2ZW50LlVQREFURUQsIFN0YXRlLklOU1RBTExFRCksIG5ldyBEdW1teU1vZHVsZUV2ZW50KGM2LCBNb2R1bGVFdmVudC5SRVNPTFZFRCwgU3RhdGUuUkVTT0xWRUQpLAoKCQkJCW5ldyBEdW1teU1vZHVsZUV2ZW50KGM0LCBNb2R1bGVFdmVudC5VTlJFU09MVkVELCBTdGF0ZS5JTlNUQUxMRUQpLCBuZXcgRHVtbXlNb2R1bGVFdmVudChjNCwgTW9kdWxlRXZlbnQuVVBEQVRFRCwgU3RhdGUuSU5TVEFMTEVEKSwgbmV3IER1bW15TW9kdWxlRXZlbnQoYzYsIE1vZHVsZUV2ZW50LlVOUkVTT0xWRUQsIFN0YXRlLklOU1RBTExFRCksIG5ldyBEdW1teU1vZHVsZUV2ZW50KGM2LCBNb2R1bGVFdmVudC5VUERBVEVELCBTdGF0ZS5JTlNUQUxMRUQpLCBuZXcgRHVtbXlNb2R1bGVFdmVudChjNCwgTW9kdWxlRXZlbnQuUkVTT0xWRUQsIFN0YXRlLlJFU09MVkVEKSwgbmV3IER1bW15TW9kdWxlRXZlbnQoYzYsIE1vZHVsZUV2ZW50LlJFU09MVkVELCBTdGF0ZS5SRVNPTFZFRCksCgoJCQkJbmV3IER1bW15TW9kdWxlRXZlbnQoYzQsIE1vZHVsZUV2ZW50LlVOUkVTT0xWRUQsIFN0YXRlLklOU1RBTExFRCksIG5ldyBEdW1teU1vZHVsZUV2ZW50KGM2LCBNb2R1bGVFdmVudC5VTlJFU09MVkVELCBTdGF0ZS5JTlNUQUxMRUQpLCBuZXcgRHVtbXlNb2R1bGVFdmVudChjNywgTW9kdWxlRXZlbnQuVU5SRVNPTFZFRCwgU3RhdGUuSU5TVEFMTEVEKSwgbmV3IER1bW15TW9kdWxlRXZlbnQoYzQsIE1vZHVsZUV2ZW50LlJFU09MVkVELCBTdGF0ZS5SRVNPTFZFRCksIG5ldyBEdW1teU1vZHVsZUV2ZW50KGM2LCBNb2R1bGVFdmVudC5SRVNPTFZFRCwgU3RhdGUuUkVTT0xWRUQpLCBuZXcgRHVtbXlNb2R1bGVFdmVudChjNywgTW9kdWxlRXZlbnQuUkVTT0xWRUQsIFN0YXRlLlJFU09MVkVEKSkpOwoJCWFzc2VydEV2ZW50cyhleHBlY3RlZCwgYWN0dWFsLCBmYWxzZSk7CgoJCS8vIHVuaW5zdGFsbCBjNAoJCWM0UmV2aXNpb24wID0gYzQuZ2V0Q3VycmVudFJldmlzaW9uKCk7CgkJY29udGFpbmVyLnVuaW5zdGFsbChjNCk7CgkJcmVtb3ZhbFBlbmRpbmcgPSBjb250YWluZXIuZ2V0UmVtb3ZhbFBlbmRpbmcoKTsKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJXcm9uZyBudW1iZXIgb2YgcmVtb3ZhbCBwZW5kaW5nIiwgMSwgcmVtb3ZhbFBlbmRpbmcuc2l6ZSgpKTsKCQlBc3NlcnQuYXNzZXJ0VHJ1ZSgiV3JvbmcgbW9kdWxlIHJlbW92YWxQZW5kaW5nOiAiICsgcmVtb3ZhbFBlbmRpbmcsIHJlbW92YWxQZW5kaW5nLmNvbnRhaW5zQWxsKEFycmF5cy5hc0xpc3QoYzRSZXZpc2lvbjApKSk7CgoJCWNvbnRhaW5lci5yZWZyZXNoKG51bGwpOwoJCWFjdHVhbCA9IGRhdGFiYXNlLmdldE1vZHVsZUV2ZW50cygpOwoJCWV4cGVjdGVkID0gbmV3IEFycmF5TGlzdDxEdW1teU1vZHVsZUV2ZW50PihBcnJheXMuYXNMaXN0KG5ldyBEdW1teU1vZHVsZUV2ZW50KGM0LCBNb2R1bGVFdmVudC5VTlJFU09MVkVELCBTdGF0ZS5JTlNUQUxMRUQpLCBuZXcgRHVtbXlNb2R1bGVFdmVudChjNCwgTW9kdWxlRXZlbnQuVU5JTlNUQUxMRUQsIFN0YXRlLlVOSU5TVEFMTEVEKSwgbmV3IER1bW15TW9kdWxlRXZlbnQoYzYsIE1vZHVsZUV2ZW50LlVOUkVTT0xWRUQsIFN0YXRlLklOU1RBTExFRCksIG5ldyBEdW1teU1vZHVsZUV2ZW50KGM3LCBNb2R1bGVFdmVudC5VTlJFU09MVkVELCBTdGF0ZS5JTlNUQUxMRUQpKSk7CgkJYXNzZXJ0RXZlbnRzKGV4cGVjdGVkLCBhY3R1YWwsIGZhbHNlKTsKCgkJLy8gVGVzdCBidWcgNDExODMzCgkJLy8gaW5zdGFsbCBjNCBhZ2FpbiBhbmQgcmVzb2x2ZSBjNgoJCWM0ID0gaW5zdGFsbER1bW15TW9kdWxlKCJjNF92MS5NRiIsICJjNF92MSIsIGNvbnRhaW5lcik7CgkJY29udGFpbmVyLnJlc29sdmUoQXJyYXlzLmFzTGlzdChjNiksIHRydWUpOwoJCS8vIHRocm93IG91dCBpbnN0YWxsZWQgYW5kIHJlc29sdmVkIGV2ZW50cwoJCWRhdGFiYXNlLmdldE1vZHVsZUV2ZW50cygpOwoKCQlyZW1vdmFsUGVuZGluZyA9IGNvbnRhaW5lci5nZXRSZW1vdmFsUGVuZGluZygpOwoJCUFzc2VydC5hc3NlcnRFcXVhbHMoIldyb25nIG51bWJlciBvZiByZW1vdmFsIHBlbmRpbmciLCAwLCByZW1vdmFsUGVuZGluZy5zaXplKCkpOwoKCQljNFJldmlzaW9uMCA9IGM0LmdldEN1cnJlbnRSZXZpc2lvbigpOwoJCS8vIHVuaW5zdGFsbCBjNCwgYnV0IHJlZnJlc2ggYzYgaW5zdGVhZAoJCS8vIHRoaXMgc2hvdWxkIHJlc3VsdCBpbiByZW1vdmFsIHBlbmRpbmcgYzQgdG8gYmUgcmVtb3ZlZC4KCQljb250YWluZXIudW5pbnN0YWxsKGM0KTsKCQlyZW1vdmFsUGVuZGluZyA9IGNvbnRhaW5lci5nZXRSZW1vdmFsUGVuZGluZygpOwoJCUFzc2VydC5hc3NlcnRFcXVhbHMoIldyb25nIG51bWJlciBvZiByZW1vdmFsIHBlbmRpbmciLCAxLCByZW1vdmFsUGVuZGluZy5zaXplKCkpOwoJCUFzc2VydC5hc3NlcnRUcnVlKCJXcm9uZyBtb2R1bGUgcmVtb3ZhbFBlbmRpbmc6ICIgKyByZW1vdmFsUGVuZGluZywgcmVtb3ZhbFBlbmRpbmcuY29udGFpbnNBbGwoQXJyYXlzLmFzTGlzdChjNFJldmlzaW9uMCkpKTsKCgkJY29udGFpbmVyLnJlZnJlc2goQ29sbGVjdGlvbnMuc2luZ2xldG9uTGlzdChjNikpOwoJCWFjdHVhbCA9IGRhdGFiYXNlLmdldE1vZHVsZUV2ZW50cygpOwoJCWV4cGVjdGVkID0gbmV3IEFycmF5TGlzdDxEdW1teU1vZHVsZUV2ZW50PihBcnJheXMuYXNMaXN0KG5ldyBEdW1teU1vZHVsZUV2ZW50KGM0LCBNb2R1bGVFdmVudC5VTlJFU09MVkVELCBTdGF0ZS5JTlNUQUxMRUQpLCBuZXcgRHVtbXlNb2R1bGVFdmVudChjNCwgTW9kdWxlRXZlbnQuVU5JTlNUQUxMRUQsIFN0YXRlLlVOSU5TVEFMTEVEKSwgbmV3IER1bW15TW9kdWxlRXZlbnQoYzYsIE1vZHVsZUV2ZW50LlVOUkVTT0xWRUQsIFN0YXRlLklOU1RBTExFRCksIG5ldyBEdW1teU1vZHVsZUV2ZW50KGM3LCBNb2R1bGVFdmVudC5VTlJFU09MVkVELCBTdGF0ZS5JTlNUQUxMRUQpKSk7CgkJYXNzZXJ0RXZlbnRzKGV4cGVjdGVkLCBhY3R1YWwsIGZhbHNlKTsKCgkJcmVtb3ZhbFBlbmRpbmcgPSBjb250YWluZXIuZ2V0UmVtb3ZhbFBlbmRpbmcoKTsKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJXcm9uZyBudW1iZXIgb2YgcmVtb3ZhbCBwZW5kaW5nIiwgMCwgcmVtb3ZhbFBlbmRpbmcuc2l6ZSgpKTsKCX0KCglAVGVzdAoJcHVibGljIHZvaWQgdGVzdFN1YnN0aXR1dGFibGVFeHBvcnRzMDEoKSB0aHJvd3MgQnVuZGxlRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CgkJRHVtbXlDb250YWluZXJBZGFwdG9yIGFkYXB0b3IgPSBjcmVhdGVEdW1teUFkYXB0b3IoKTsKCQlNb2R1bGVDb250YWluZXIgY29udGFpbmVyID0gYWRhcHRvci5nZXRDb250YWluZXIoKTsKCgkJTW9kdWxlIHN5c3RlbUJ1bmRsZSA9IGluc3RhbGxEdW1teU1vZHVsZSgic3lzdGVtLmJ1bmRsZS5NRiIsIENvbnN0YW50cy5TWVNURU1fQlVORExFX0xPQ0FUSU9OLCBjb250YWluZXIpOwoKCQljb250YWluZXIucmVzb2x2ZShBcnJheXMuYXNMaXN0KHN5c3RlbUJ1bmRsZSksIHRydWUpOwoKCQlNb2R1bGUgc3ViMSA9IGluc3RhbGxEdW1teU1vZHVsZSgic3ViMV92MS5NRiIsICJzdWIxIiwgY29udGFpbmVyKTsKCQlNb2R1bGUgc3ViMiA9IGluc3RhbGxEdW1teU1vZHVsZSgic3ViMl92MS5NRiIsICJzdWIyIiwgY29udGFpbmVyKTsKCgkJTW9kdWxlUmV2aXNpb24gc3ViMVJldmlzaW9uMCA9IHN1YjEuZ2V0Q3VycmVudFJldmlzaW9uKCk7CgoJCWNvbnRhaW5lci5yZXNvbHZlKEFycmF5cy5hc0xpc3Qoc3ViMiksIHRydWUpOwoKCQljb250YWluZXIudXBkYXRlKHN1YjEsIE9TR2lNYW5pZmVzdEJ1aWxkZXJGYWN0b3J5LmNyZWF0ZUJ1aWxkZXIoZ2V0TWFuaWZlc3QoInN1YjFfdjIuTUYiKSksIG51bGwpOwoJCWNvbnRhaW5lci5yZXNvbHZlKEFycmF5cy5hc0xpc3Qoc3ViMSksIHRydWUpOwoKCQlNb2R1bGVXaXJpbmcgc3ViMVdpcmluZyA9IHN1YjEuZ2V0Q3VycmVudFJldmlzaW9uKCkuZ2V0V2lyaW5nKCk7CgkJTGlzdDxCdW5kbGVDYXBhYmlsaXR5PiBleHBvcnRlZFBhY2thZ2VzID0gc3ViMVdpcmluZy5nZXRDYXBhYmlsaXRpZXMoUGFja2FnZU5hbWVzcGFjZS5QQUNLQUdFX05BTUVTUEFDRSk7CgkJQXNzZXJ0LmFzc2VydEVxdWFscygiV3JvbmcgbnVtYmVyIG9mIGV4cG9ydGVkIHBhY2thZ2VzOiAiICsgZXhwb3J0ZWRQYWNrYWdlcywgMCwgZXhwb3J0ZWRQYWNrYWdlcy5zaXplKCkpOwoJCUxpc3Q8QnVuZGxlV2lyZT4gcmVxdWlyZWRXaXJlcyA9IHN1YjFXaXJpbmcuZ2V0UmVxdWlyZWRXaXJlcyhQYWNrYWdlTmFtZXNwYWNlLlBBQ0tBR0VfTkFNRVNQQUNFKTsKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJXcm9uZyBudW1iZXIgb2YgaW1wb3J0ZWQgcGFja2FnZXM6ICIsIDIsIHJlcXVpcmVkV2lyZXMuc2l6ZSgpKTsKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJXcm9uZyBwcm92aWRlciBmb3IgcGFja2FnZTogIiArIHJlcXVpcmVkV2lyZXMuZ2V0KDEpLmdldFByb3ZpZGVyKCksIHN1YjFSZXZpc2lvbjAsIHJlcXVpcmVkV2lyZXMuZ2V0KDEpLmdldFByb3ZpZGVyKCkpOwoKCQljb250YWluZXIucmVmcmVzaChBcnJheXMuYXNMaXN0KHN1YjEpKTsKCgkJc3ViMVdpcmluZyA9IHN1YjEuZ2V0Q3VycmVudFJldmlzaW9uKCkuZ2V0V2lyaW5nKCk7CgkJZXhwb3J0ZWRQYWNrYWdlcyA9IHN1YjFXaXJpbmcuZ2V0Q2FwYWJpbGl0aWVzKFBhY2thZ2VOYW1lc3BhY2UuUEFDS0FHRV9OQU1FU1BBQ0UpOwoJCUFzc2VydC5hc3NlcnRFcXVhbHMoIldyb25nIG51bWJlciBvZiBleHBvcnRlZCBwYWNrYWdlczogIiArIGV4cG9ydGVkUGFja2FnZXMsIDEsIGV4cG9ydGVkUGFja2FnZXMuc2l6ZSgpKTsKCQlyZXF1aXJlZFdpcmVzID0gc3ViMVdpcmluZy5nZXRSZXF1aXJlZFdpcmVzKFBhY2thZ2VOYW1lc3BhY2UuUEFDS0FHRV9OQU1FU1BBQ0UpOwoJCUFzc2VydC5hc3NlcnRFcXVhbHMoIldyb25nIG51bWJlciBvZiBpbXBvcnRlZCBwYWNrYWdlczogIiwgMSwgcmVxdWlyZWRXaXJlcy5zaXplKCkpOwoKCX0KCglAVGVzdAoJcHVibGljIHZvaWQgdGVzdFN1YnN0aXR1dGFibGVFeHBvcnRzMDIoKSB0aHJvd3MgQnVuZGxlRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CgkJRHVtbXlDb250YWluZXJBZGFwdG9yIGFkYXB0b3IgPSBjcmVhdGVEdW1teUFkYXB0b3IoKTsKCQlNb2R1bGVDb250YWluZXIgY29udGFpbmVyID0gYWRhcHRvci5nZXRDb250YWluZXIoKTsKCgkJTW9kdWxlIGEgPSBpbnN0YWxsRHVtbXlNb2R1bGUoInN1Yi5hLk1GIiwgImEiLCBjb250YWluZXIpOwoJCU1vZHVsZSBiID0gaW5zdGFsbER1bW15TW9kdWxlKCJzdWIuYi5NRiIsICJiIiwgY29udGFpbmVyKTsKCQlNb2R1bGUgYyA9IGluc3RhbGxEdW1teU1vZHVsZSgic3ViLmMuTUYiLCAiYyIsIGNvbnRhaW5lcik7CgoJCWNvbnRhaW5lci5yZXNvbHZlKEFycmF5cy5hc0xpc3QoYSwgYiwgYyksIHRydWUpOwoKCQlNb2R1bGVXaXJpbmcgd2lyaW5nQSA9IGEuZ2V0Q3VycmVudFJldmlzaW9uKCkuZ2V0V2lyaW5nKCk7CgkJTW9kdWxlV2lyaW5nIHdpcmluZ0IgPSBiLmdldEN1cnJlbnRSZXZpc2lvbigpLmdldFdpcmluZygpOwoJCU1vZHVsZVdpcmluZyB3aXJpbmdDID0gYy5nZXRDdXJyZW50UmV2aXNpb24oKS5nZXRXaXJpbmcoKTsKCgkJTGlzdDxNb2R1bGVXaXJlPiBwcm92aWRlZFdpcmVzQSA9IHdpcmluZ0EuZ2V0UHJvdmlkZWRNb2R1bGVXaXJlcyhQYWNrYWdlTmFtZXNwYWNlLlBBQ0tBR0VfTkFNRVNQQUNFKTsKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJXcm9uZyBudW1iZXIgb2YgcHJvdmlkZWQgd2lyZXMuIiwgMiwgcHJvdmlkZWRXaXJlc0Euc2l6ZSgpKTsKCgkJQ29sbGVjdGlvbjxNb2R1bGVSZXZpc2lvbj4gcmVxdWlyZXJzID0gbmV3IEFycmF5TGlzdDxNb2R1bGVSZXZpc2lvbj4oKTsKCQlmb3IgKE1vZHVsZVdpcmUgd2lyZSA6IHByb3ZpZGVkV2lyZXNBKSB7CgkJCXJlcXVpcmVycy5hZGQod2lyZS5nZXRSZXF1aXJlcigpKTsKCQl9CgkJQXNzZXJ0LmFzc2VydFRydWUoImIgZG9lcyBub3QgcmVxdWlyZS4iLCByZXF1aXJlcnMuY29udGFpbnMoYi5nZXRDdXJyZW50UmV2aXNpb24oKSkpOwoJCUFzc2VydC5hc3NlcnRUcnVlKCJjIGRvZXMgbm90IHJlcXVpcmUuIiwgcmVxdWlyZXJzLmNvbnRhaW5zKGMuZ2V0Q3VycmVudFJldmlzaW9uKCkpKTsKCgkJTGlzdDxNb2R1bGVXaXJlPiByZXF1aXJlZFdpcmVzQiA9IHdpcmluZ0IuZ2V0UmVxdWlyZWRNb2R1bGVXaXJlcyhQYWNrYWdlTmFtZXNwYWNlLlBBQ0tBR0VfTkFNRVNQQUNFKTsKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJXcm9uZyBudW1iZXIgb2YgcmVxdWlyZWQgd2lyZXMuIiwgMSwgcmVxdWlyZWRXaXJlc0Iuc2l6ZSgpKTsKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJVbmV4cGVjdGVkIHBhY2thZ2UgbmFtZS4iLCAiamF2YXguc2VydmxldCIsIHJlcXVpcmVkV2lyZXNCLml0ZXJhdG9yKCkubmV4dCgpLmdldENhcGFiaWxpdHkoKS5nZXRBdHRyaWJ1dGVzKCkuZ2V0KFBhY2thZ2VOYW1lc3BhY2UuUEFDS0FHRV9OQU1FU1BBQ0UpKTsKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJXcm9uZyBwcm92aWRlci4iLCBhLmdldEN1cnJlbnRSZXZpc2lvbigpLCByZXF1aXJlZFdpcmVzQi5pdGVyYXRvcigpLm5leHQoKS5nZXRQcm92aWRlcigpKTsKCgkJTGlzdDxNb2R1bGVXaXJlPiByZXF1aXJlZFdpcmVzQyA9IHdpcmluZ0MuZ2V0UmVxdWlyZWRNb2R1bGVXaXJlcyhQYWNrYWdlTmFtZXNwYWNlLlBBQ0tBR0VfTkFNRVNQQUNFKTsKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJXcm9uZyBudW1iZXIgb2YgcmVxdWlyZWQgd2lyZXMuIiwgMSwgcmVxdWlyZWRXaXJlc0Muc2l6ZSgpKTsKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJXcm9uZyBudW1iZXIgb2YgcmVxdWlyZWQgd2lyZXMuIiwgMSwgcmVxdWlyZWRXaXJlc0Muc2l6ZSgpKTsKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJVbmV4cGVjdGVkIHBhY2thZ2UgbmFtZS4iLCAiamF2YXguc2VydmxldCIsIHJlcXVpcmVkV2lyZXNDLml0ZXJhdG9yKCkubmV4dCgpLmdldENhcGFiaWxpdHkoKS5nZXRBdHRyaWJ1dGVzKCkuZ2V0KFBhY2thZ2VOYW1lc3BhY2UuUEFDS0FHRV9OQU1FU1BBQ0UpKTsKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJXcm9uZyBwcm92aWRlci4iLCBhLmdldEN1cnJlbnRSZXZpc2lvbigpLCByZXF1aXJlZFdpcmVzQy5pdGVyYXRvcigpLm5leHQoKS5nZXRQcm92aWRlcigpKTsKCgkJTW9kdWxlIGQgPSBpbnN0YWxsRHVtbXlNb2R1bGUoInN1Yi5kLk1GIiwgImQiLCBjb250YWluZXIpOwoKCQljb250YWluZXIucmVzb2x2ZShBcnJheXMuYXNMaXN0KGQpLCB0cnVlKTsKCgkJTW9kdWxlV2lyaW5nIHdpcmluZ0QgPSBkLmdldEN1cnJlbnRSZXZpc2lvbigpLmdldFdpcmluZygpOwoJCUxpc3Q8TW9kdWxlV2lyZT4gcmVxdWlyZWRXaXJlc0QgPSB3aXJpbmdELmdldFJlcXVpcmVkTW9kdWxlV2lyZXMoUGFja2FnZU5hbWVzcGFjZS5QQUNLQUdFX05BTUVTUEFDRSk7CgkJQXNzZXJ0LmFzc2VydEVxdWFscygiV3JvbmcgbnVtYmVyIG9mIHJlcXVpcmVkIHdpcmVzLiIsIDIsIHJlcXVpcmVkV2lyZXNELnNpemUoKSk7CgkJQXNzZXJ0LmFzc2VydEVxdWFscygiVW5leHBlY3RlZCBwYWNrYWdlIG5hbWUuIiwgIm9yZy5vcHM0ai5wYXgud2ViLnNlcnZpY2UiLCByZXF1aXJlZFdpcmVzRC5nZXQoMCkuZ2V0Q2FwYWJpbGl0eSgpLmdldEF0dHJpYnV0ZXMoKS5nZXQoUGFja2FnZU5hbWVzcGFjZS5QQUNLQUdFX05BTUVTUEFDRSkpOwoJCUFzc2VydC5hc3NlcnRFcXVhbHMoIldyb25nIHByb3ZpZGVyLiIsIGMuZ2V0Q3VycmVudFJldmlzaW9uKCksIHJlcXVpcmVkV2lyZXNELmdldCgwKS5nZXRQcm92aWRlcigpKTsKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJVbmV4cGVjdGVkIHBhY2thZ2UgbmFtZS4iLCAiamF2YXguc2VydmxldCIsIHJlcXVpcmVkV2lyZXNELmdldCgxKS5nZXRDYXBhYmlsaXR5KCkuZ2V0QXR0cmlidXRlcygpLmdldChQYWNrYWdlTmFtZXNwYWNlLlBBQ0tBR0VfTkFNRVNQQUNFKSk7CgkJQXNzZXJ0LmFzc2VydEVxdWFscygiV3JvbmcgcHJvdmlkZXIuIiwgYS5nZXRDdXJyZW50UmV2aXNpb24oKSwgcmVxdWlyZWRXaXJlc0QuZ2V0KDEpLmdldFByb3ZpZGVyKCkpOwoKCX0KCglAVGVzdAoJcHVibGljIHZvaWQgdGVzdFN1YnN0aXR1dGFibGVFeHBvcnRzMDMoKSB0aHJvd3MgQnVuZGxlRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CgkJRHVtbXlDb250YWluZXJBZGFwdG9yIGFkYXB0b3IgPSBjcmVhdGVEdW1teUFkYXB0b3IoKTsKCQlNb2R1bGVDb250YWluZXIgY29udGFpbmVyID0gYWRhcHRvci5nZXRDb250YWluZXIoKTsKCgkJLy8gaW5zdGFsbCBvcmRlciBkb2VzIG5vdCByZWFsbHkgbWF0dGVyCgkJTW9kdWxlIGcgPSBpbnN0YWxsRHVtbXlNb2R1bGUoInN1Yi5nLk1GIiwgImciLCBjb250YWluZXIpOwoJCU1vZHVsZSBmID0gaW5zdGFsbER1bW15TW9kdWxlKCJzdWIuZi5NRiIsICJmIiwgY29udGFpbmVyKTsKCQlNb2R1bGUgZSA9IGluc3RhbGxEdW1teU1vZHVsZSgic3ViLmUuTUYiLCAiZSIsIGNvbnRhaW5lcik7CgoJCS8vIHJlc29sdmUgb3JkZXIgZG9lcyBtYXR0ZXIgc28gdGhhdCB0cmFuc2l0aXZlIGRlcGVuZGVuY2llcyBhcmUgcHVsbGVkIGluIAoJCS8vIGFuZCBjYXVzZSBzdWJzdGl0dXRpb24gdG8gaGFwcGVuIGluIGEgY2VydGFpbiB3YXkKCQljb250YWluZXIucmVzb2x2ZShBcnJheXMuYXNMaXN0KGcsIGYsIGUpLCB0cnVlKTsKCgkJTW9kdWxlV2lyaW5nIHdpcmluZ0UgPSBlLmdldEN1cnJlbnRSZXZpc2lvbigpLmdldFdpcmluZygpOwoJCU1vZHVsZVdpcmluZyB3aXJpbmdGID0gZi5nZXRDdXJyZW50UmV2aXNpb24oKS5nZXRXaXJpbmcoKTsKCgkJTGlzdDxNb2R1bGVXaXJlPiBwcm92aWRlZFdpcmVzRSA9IHdpcmluZ0UuZ2V0UHJvdmlkZWRNb2R1bGVXaXJlcyhQYWNrYWdlTmFtZXNwYWNlLlBBQ0tBR0VfTkFNRVNQQUNFKTsKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJXcm9uZyBudW1iZXIgb2YgcHJvdmlkZWQgd2lyZXMuIiwgMywgcHJvdmlkZWRXaXJlc0Uuc2l6ZSgpKTsKCgkJQ29sbGVjdGlvbjxNb2R1bGVSZXZpc2lvbj4gcmVxdWlyZXJzID0gbmV3IEhhc2hTZXQ8TW9kdWxlUmV2aXNpb24+KCk7CgkJZm9yIChNb2R1bGVXaXJlIHdpcmUgOiBwcm92aWRlZFdpcmVzRSkgewoJCQlyZXF1aXJlcnMuYWRkKHdpcmUuZ2V0UmVxdWlyZXIoKSk7CgkJfQoJCUFzc2VydC5hc3NlcnRUcnVlKCJmIGRvZXMgbm90IHJlcXVpcmUuIiwgcmVxdWlyZXJzLnJlbW92ZShmLmdldEN1cnJlbnRSZXZpc2lvbigpKSk7CgkJQXNzZXJ0LmFzc2VydFRydWUoImcgZG9lcyBub3QgcmVxdWlyZS4iLCByZXF1aXJlcnMucmVtb3ZlKGcuZ2V0Q3VycmVudFJldmlzaW9uKCkpKTsKCQlBc3NlcnQuYXNzZXJ0VHJ1ZSgiTm8gcmVxdWlyZXJzIHNob3VsZCBiZSBsZWZ0OiAiICsgcmVxdWlyZXJzLCByZXF1aXJlcnMuaXNFbXB0eSgpKTsKCgkJTGlzdDxNb2R1bGVXaXJlPiBwcm92aWRlZFdpcmVzRiA9IHdpcmluZ0YuZ2V0UHJvdmlkZWRNb2R1bGVXaXJlcyhQYWNrYWdlTmFtZXNwYWNlLlBBQ0tBR0VfTkFNRVNQQUNFKTsKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJXcm9uZyBudW1iZXIgb2YgcHJvdmlkZWQgd2lyZXM6ICIgKyBwcm92aWRlZFdpcmVzRiwgMCwgcHJvdmlkZWRXaXJlc0Yuc2l6ZSgpKTsKCX0KCglAVGVzdAoJcHVibGljIHZvaWQgdGVzdFN1YnN0aXR1dGFibGVFeHBvcnRzMDQoKSB0aHJvd3MgQnVuZGxlRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CgkJRHVtbXlDb250YWluZXJBZGFwdG9yIGFkYXB0b3IgPSBjcmVhdGVEdW1teUFkYXB0b3IoKTsKCQlNb2R1bGVDb250YWluZXIgY29udGFpbmVyID0gYWRhcHRvci5nZXRDb250YWluZXIoKTsKCgkJLy8gaW5zdGFsbCBvcmRlciBkb2VzIG5vdCByZWFsbHkgbWF0dGVyCgkJaW5zdGFsbER1bW15TW9kdWxlKCJzdWIuaC5NRiIsICJoIiwgY29udGFpbmVyKTsKCQlNb2R1bGUgaSA9IGluc3RhbGxEdW1teU1vZHVsZSgic3ViLmkuTUYiLCAiaSIsIGNvbnRhaW5lcik7CgkJaW5zdGFsbER1bW15TW9kdWxlKCJzdWIuai5NRiIsICJqIiwgY29udGFpbmVyKTsKCQlNb2R1bGUgayA9IGluc3RhbGxEdW1teU1vZHVsZSgic3ViLmsuTUYiLCAiayIsIGNvbnRhaW5lcik7CgoJCS8vIHJlc29sdmUgb3JkZXIgZG9lcyBtYXR0ZXIgc28gdGhhdCB0cmFuc2l0aXZlIGRlcGVuZGVuY2llcyBhcmUgcHVsbGVkIGluIAoJCS8vIGFuZCBjYXVzZSBzdWJzdGl0dXRpb24gdG8gaGFwcGVuIGluIGEgY2VydGFpbiB3YXkKCQljb250YWluZXIucmVzb2x2ZShBcnJheXMuYXNMaXN0KGspLCB0cnVlKTsKCgkJTW9kdWxlV2lyaW5nIHdpcmluZ0kgPSBpLmdldEN1cnJlbnRSZXZpc2lvbigpLmdldFdpcmluZygpOwoJCU1vZHVsZVdpcmluZyB3aXJpbmdLID0gay5nZXRDdXJyZW50UmV2aXNpb24oKS5nZXRXaXJpbmcoKTsKCgkJTGlzdDxNb2R1bGVXaXJlPiByZXF1aXJlZFdpcmVzSyA9IHdpcmluZ0suZ2V0UmVxdWlyZWRNb2R1bGVXaXJlcyhQYWNrYWdlTmFtZXNwYWNlLlBBQ0tBR0VfTkFNRVNQQUNFKTsKCgkJLy8gSSBzaG91bGQgYmUgdGhlIHByb3ZpZGVyIGZvciBhbGwgb2YgSwoJCUFzc2VydC5hc3NlcnRFcXVhbHMoIldyb25nIG51bWJlciBvZiByZXF1aXJlZCB3aXJlczogIiArIHJlcXVpcmVkV2lyZXNLLCAyLCByZXF1aXJlZFdpcmVzSy5zaXplKCkpOwoJCWZvciAoTW9kdWxlV2lyZSBtb2R1bGVXaXJlIDogcmVxdWlyZWRXaXJlc0spIHsKCQkJQXNzZXJ0LmFzc2VydEVxdWFscygiV3JvbmcgcHJvdmlkZXI6ICIgKyBtb2R1bGVXaXJlLmdldFByb3ZpZGVyV2lyaW5nKCksIHdpcmluZ0ksIG1vZHVsZVdpcmUuZ2V0UHJvdmlkZXJXaXJpbmcoKSk7CgkJfQoJfQoKCUBUZXN0CglwdWJsaWMgdm9pZCB0ZXN0TGF6eTAxKCkgdGhyb3dzIEJ1bmRsZUV4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewoJCUR1bW15Q29udGFpbmVyQWRhcHRvciBhZGFwdG9yID0gY3JlYXRlRHVtbXlBZGFwdG9yKCk7CgkJTW9kdWxlQ29udGFpbmVyIGNvbnRhaW5lciA9IGFkYXB0b3IuZ2V0Q29udGFpbmVyKCk7CgkJRHVtbXlNb2R1bGVEYXRhYmFzZSBkYXRhYmFzZSA9IGFkYXB0b3IuZ2V0RGF0YWJhc2UoKTsKCgkJTW9kdWxlIHN5c3RlbUJ1bmRsZSA9IGluc3RhbGxEdW1teU1vZHVsZSgic3lzdGVtLmJ1bmRsZS5NRiIsIENvbnN0YW50cy5TWVNURU1fQlVORExFX0xPQ0FUSU9OLCBjb250YWluZXIpOwoKCQljb250YWluZXIucmVzb2x2ZShBcnJheXMuYXNMaXN0KHN5c3RlbUJ1bmRsZSksIHRydWUpOwoKCQkvLyBhY3R1YWxseSBsYXVuY2ggdGhlIGNvbnRhaW5lcgoJCXN5c3RlbUJ1bmRsZS5zdGFydCgpOwoKCQlNb2R1bGUgbGF6eTEgPSBpbnN0YWxsRHVtbXlNb2R1bGUoImxhenkxX3YxLk1GIiwgImxhenkxIiwgY29udGFpbmVyKTsKCgkJLy8gdGhyb3cgb3V0IGluc3RhbGxlZCBhbmQgcmVzb2x2ZWQgZXZlbnRzCgkJZGF0YWJhc2UuZ2V0TW9kdWxlRXZlbnRzKCk7CgoJCWxhenkxLnN0YXJ0KFN0YXJ0T3B0aW9ucy5VU0VfQUNUSVZBVElPTl9QT0xJQ1kpOwoKCQlMaXN0PER1bW15TW9kdWxlRXZlbnQ+IGFjdHVhbCA9IGRhdGFiYXNlLmdldE1vZHVsZUV2ZW50cygpOwoJCUxpc3Q8RHVtbXlNb2R1bGVFdmVudD4gZXhwZWN0ZWQgPSBuZXcgQXJyYXlMaXN0PER1bW15TW9kdWxlRXZlbnQ+KEFycmF5cy5hc0xpc3QobmV3IER1bW15TW9kdWxlRXZlbnQobGF6eTEsIE1vZHVsZUV2ZW50LlJFU09MVkVELCBTdGF0ZS5SRVNPTFZFRCksIG5ldyBEdW1teU1vZHVsZUV2ZW50KGxhenkxLCBNb2R1bGVFdmVudC5MQVpZX0FDVElWQVRJT04sIFN0YXRlLkxBWllfU1RBUlRJTkcpKSk7CgkJYXNzZXJ0RXZlbnRzKGV4cGVjdGVkLCBhY3R1YWwsIHRydWUpOwoKCQlsYXp5MS5zdGFydChTdGFydE9wdGlvbnMuTEFaWV9UUklHR0VSKTsKCgkJYWN0dWFsID0gZGF0YWJhc2UuZ2V0TW9kdWxlRXZlbnRzKCk7CgkJZXhwZWN0ZWQgPSBuZXcgQXJyYXlMaXN0PER1bW15TW9kdWxlRXZlbnQ+KEFycmF5cy5hc0xpc3QobmV3IER1bW15TW9kdWxlRXZlbnQobGF6eTEsIE1vZHVsZUV2ZW50LlNUQVJUSU5HLCBTdGF0ZS5TVEFSVElORyksIG5ldyBEdW1teU1vZHVsZUV2ZW50KGxhenkxLCBNb2R1bGVFdmVudC5TVEFSVEVELCBTdGF0ZS5BQ1RJVkUpKSk7CgkJYXNzZXJ0RXZlbnRzKGV4cGVjdGVkLCBhY3R1YWwsIHRydWUpOwoKCQljb250YWluZXIucmVmcmVzaChBcnJheXMuYXNMaXN0KGxhenkxKSk7CgoJCWFjdHVhbCA9IGRhdGFiYXNlLmdldE1vZHVsZUV2ZW50cygpOwoJCWV4cGVjdGVkID0gbmV3IEFycmF5TGlzdDxEdW1teU1vZHVsZUV2ZW50PihBcnJheXMuYXNMaXN0KG5ldyBEdW1teU1vZHVsZUV2ZW50KGxhenkxLCBNb2R1bGVFdmVudC5TVE9QUElORywgU3RhdGUuU1RPUFBJTkcpLCBuZXcgRHVtbXlNb2R1bGVFdmVudChsYXp5MSwgTW9kdWxlRXZlbnQuU1RPUFBFRCwgU3RhdGUuUkVTT0xWRUQpLCBuZXcgRHVtbXlNb2R1bGVFdmVudChsYXp5MSwgTW9kdWxlRXZlbnQuVU5SRVNPTFZFRCwgU3RhdGUuSU5TVEFMTEVEKSwgbmV3IER1bW15TW9kdWxlRXZlbnQobGF6eTEsIE1vZHVsZUV2ZW50LlJFU09MVkVELCBTdGF0ZS5SRVNPTFZFRCksIG5ldyBEdW1teU1vZHVsZUV2ZW50KGxhenkxLCBNb2R1bGVFdmVudC5MQVpZX0FDVElWQVRJT04sIFN0YXRlLkxBWllfU1RBUlRJTkcpKSk7CgkJYXNzZXJ0RXZlbnRzKGV4cGVjdGVkLCBhY3R1YWwsIHRydWUpOwoKCQljb250YWluZXIudXBkYXRlKGxhenkxLCBPU0dpTWFuaWZlc3RCdWlsZGVyRmFjdG9yeS5jcmVhdGVCdWlsZGVyKGdldE1hbmlmZXN0KCJsYXp5MV92MS5NRiIpKSwgbnVsbCk7CgkJYWN0dWFsID0gZGF0YWJhc2UuZ2V0TW9kdWxlRXZlbnRzKCk7CgkJZXhwZWN0ZWQgPSBuZXcgQXJyYXlMaXN0PER1bW15TW9kdWxlRXZlbnQ+KEFycmF5cy5hc0xpc3QobmV3IER1bW15TW9kdWxlRXZlbnQobGF6eTEsIE1vZHVsZUV2ZW50LlNUT1BQSU5HLCBTdGF0ZS5TVE9QUElORyksIG5ldyBEdW1teU1vZHVsZUV2ZW50KGxhenkxLCBNb2R1bGVFdmVudC5TVE9QUEVELCBTdGF0ZS5SRVNPTFZFRCksIG5ldyBEdW1teU1vZHVsZUV2ZW50KGxhenkxLCBNb2R1bGVFdmVudC5VTlJFU09MVkVELCBTdGF0ZS5JTlNUQUxMRUQpLCBuZXcgRHVtbXlNb2R1bGVFdmVudChsYXp5MSwgTW9kdWxlRXZlbnQuVVBEQVRFRCwgU3RhdGUuSU5TVEFMTEVEKSwgbmV3IER1bW15TW9kdWxlRXZlbnQobGF6eTEsIE1vZHVsZUV2ZW50LlJFU09MVkVELCBTdGF0ZS5SRVNPTFZFRCksIG5ldyBEdW1teU1vZHVsZUV2ZW50KGxhenkxLCBNb2R1bGVFdmVudC5MQVpZX0FDVElWQVRJT04sIFN0YXRlLkxBWllfU1RBUlRJTkcpKSk7CgkJYXNzZXJ0RXZlbnRzKGV4cGVjdGVkLCBhY3R1YWwsIHRydWUpOwoKCQljb250YWluZXIucmVmcmVzaChBcnJheXMuYXNMaXN0KGxhenkxKSk7CgkJYWN0dWFsID0gZGF0YWJhc2UuZ2V0TW9kdWxlRXZlbnRzKCk7CgkJZXhwZWN0ZWQgPSBuZXcgQXJyYXlMaXN0PER1bW15TW9kdWxlRXZlbnQ+KEFycmF5cy5hc0xpc3QobmV3IER1bW15TW9kdWxlRXZlbnQobGF6eTEsIE1vZHVsZUV2ZW50LlNUT1BQSU5HLCBTdGF0ZS5TVE9QUElORyksIG5ldyBEdW1teU1vZHVsZUV2ZW50KGxhenkxLCBNb2R1bGVFdmVudC5TVE9QUEVELCBTdGF0ZS5SRVNPTFZFRCksIG5ldyBEdW1teU1vZHVsZUV2ZW50KGxhenkxLCBNb2R1bGVFdmVudC5VTlJFU09MVkVELCBTdGF0ZS5JTlNUQUxMRUQpLCBuZXcgRHVtbXlNb2R1bGVFdmVudChsYXp5MSwgTW9kdWxlRXZlbnQuUkVTT0xWRUQsIFN0YXRlLlJFU09MVkVEKSwgbmV3IER1bW15TW9kdWxlRXZlbnQobGF6eTEsIE1vZHVsZUV2ZW50LkxBWllfQUNUSVZBVElPTiwgU3RhdGUuTEFaWV9TVEFSVElORykpKTsKCQlhc3NlcnRFdmVudHMoZXhwZWN0ZWQsIGFjdHVhbCwgdHJ1ZSk7Cgl9CgoJQFRlc3QKCXB1YmxpYyB2b2lkIHRlc3RTZXR0aW5nczAxKCkgdGhyb3dzIEJ1bmRsZUV4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewoJCUR1bW15Q29udGFpbmVyQWRhcHRvciBhZGFwdG9yID0gY3JlYXRlRHVtbXlBZGFwdG9yKCk7CgkJTW9kdWxlQ29udGFpbmVyIGNvbnRhaW5lciA9IGFkYXB0b3IuZ2V0Q29udGFpbmVyKCk7CgkJRHVtbXlNb2R1bGVEYXRhYmFzZSBkYXRhYmFzZSA9IGFkYXB0b3IuZ2V0RGF0YWJhc2UoKTsKCgkJTW9kdWxlIHN5c3RlbUJ1bmRsZSA9IGluc3RhbGxEdW1teU1vZHVsZSgic3lzdGVtLmJ1bmRsZS5NRiIsIENvbnN0YW50cy5TWVNURU1fQlVORExFX0xPQ0FUSU9OLCBjb250YWluZXIpOwoKCQljb250YWluZXIucmVzb2x2ZShBcnJheXMuYXNMaXN0KHN5c3RlbUJ1bmRsZSksIHRydWUpOwoKCQkvLyBhY3R1YWxseSBsYXVuY2ggdGhlIGNvbnRhaW5lcgoJCXN5c3RlbUJ1bmRsZS5zdGFydCgpOwoKCQljb250YWluZXIuZ2V0RnJhbWV3b3JrU3RhcnRMZXZlbCgpLnNldEluaXRpYWxCdW5kbGVTdGFydExldmVsKDIpOwoJCU1vZHVsZSBjNCA9IGluc3RhbGxEdW1teU1vZHVsZSgiYzRfdjEuTUYiLCAiYzRfdjEiLCBjb250YWluZXIpOwoJCU1vZHVsZSBsYXp5MSA9IGluc3RhbGxEdW1teU1vZHVsZSgibGF6eTFfdjEuTUYiLCAibGF6eTEiLCBjb250YWluZXIpOwoKCQljb250YWluZXIucmVzb2x2ZShBcnJheXMuYXNMaXN0KGM0LCBsYXp5MSksIHRydWUpOwoKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJXcm9uZyBzdGFydGxldmVsLiIsIDIsIGM0LmdldFN0YXJ0TGV2ZWwoKSk7CgkJQXNzZXJ0LmFzc2VydEVxdWFscygiV3Jvbmcgc3RhcnRsZXZlbC4iLCAyLCBsYXp5MS5nZXRTdGFydExldmVsKCkpOwoKCQljNC5zZXRTdGFydExldmVsKDMpOwoJCWxhenkxLnNldFN0YXJ0TGV2ZWwoMyk7CgoJCUFzc2VydC5hc3NlcnRFcXVhbHMoIldyb25nIHN0YXJ0bGV2ZWwuIiwgMywgYzQuZ2V0U3RhcnRMZXZlbCgpKTsKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJXcm9uZyBzdGFydGxldmVsLiIsIDMsIGxhenkxLmdldFN0YXJ0TGV2ZWwoKSk7CgoJCWRhdGFiYXNlLmdldE1vZHVsZUV2ZW50cygpOwoKCQljNC5zdGFydCgpOwoJCWxhenkxLnN0YXJ0KFN0YXJ0T3B0aW9ucy5VU0VfQUNUSVZBVElPTl9QT0xJQ1kpOwoKCQlMaXN0PER1bW15TW9kdWxlRXZlbnQ+IGFjdHVhbCA9IGRhdGFiYXNlLmdldE1vZHVsZUV2ZW50cygpOwoJCUFzc2VydC5hc3NlcnRFcXVhbHMoIkRpZCBub3QgZXhwZWN0IGFueSBldmVudHMuIiwgMCwgYWN0dWFsLnNpemUoKSk7CgoJCWRhdGFiYXNlLmdldENvbnRhaW5lckV2ZW50cygpOwoJCWNvbnRhaW5lci5nZXRGcmFtZXdvcmtTdGFydExldmVsKCkuc2V0U3RhcnRMZXZlbCgzKTsKCgkJTGlzdDxEdW1teUNvbnRhaW5lckV2ZW50PiBhY3R1YWxDb250YWluZXJFdmVudHMgPSBkYXRhYmFzZS5nZXRDb250YWluZXJFdmVudHMoMSk7CgkJTGlzdDxEdW1teUNvbnRhaW5lckV2ZW50PiBleHBlY3RlZENvbnRhaW5lckV2ZW50cyA9IG5ldyBBcnJheUxpc3Q8RHVtbXlDb250YWluZXJFdmVudD4oQXJyYXlzLmFzTGlzdChuZXcgRHVtbXlDb250YWluZXJFdmVudChDb250YWluZXJFdmVudC5TVEFSVF9MRVZFTCwgc3lzdGVtQnVuZGxlLCBudWxsKSkpOwoJCUFzc2VydC5hc3NlcnRFcXVhbHMoIldyb25nIGNvbnRhaW5lciBldmVudHMuIiwgZXhwZWN0ZWRDb250YWluZXJFdmVudHMsIGFjdHVhbENvbnRhaW5lckV2ZW50cyk7CgoJCWFjdHVhbCA9IGRhdGFiYXNlLmdldE1vZHVsZUV2ZW50cygzKTsKCQlMaXN0PER1bW15TW9kdWxlRXZlbnQ+IGV4cGVjdGVkID0gbmV3IEFycmF5TGlzdDxEdW1teU1vZHVsZUV2ZW50PihBcnJheXMuYXNMaXN0KG5ldyBEdW1teU1vZHVsZUV2ZW50KGxhenkxLCBNb2R1bGVFdmVudC5MQVpZX0FDVElWQVRJT04sIFN0YXRlLkxBWllfU1RBUlRJTkcpLCBuZXcgRHVtbXlNb2R1bGVFdmVudChjNCwgTW9kdWxlRXZlbnQuU1RBUlRJTkcsIFN0YXRlLlNUQVJUSU5HKSwgbmV3IER1bW15TW9kdWxlRXZlbnQoYzQsIE1vZHVsZUV2ZW50LlNUQVJURUQsIFN0YXRlLkFDVElWRSkpKTsKCQlhc3NlcnRFdmVudHMoZXhwZWN0ZWQsIGFjdHVhbCwgdHJ1ZSk7CgoJCUJ5dGVBcnJheU91dHB1dFN0cmVhbSBieXRlcyA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKCQlEYXRhT3V0cHV0U3RyZWFtIGRhdGEgPSBuZXcgRGF0YU91dHB1dFN0cmVhbShieXRlcyk7CgkJZGF0YWJhc2Uuc3RvcmUoZGF0YSwgdHJ1ZSk7CgoJCXN5c3RlbUJ1bmRsZS5zdG9wKCk7CgoJCS8vIHJlbG9hZCBpbnRvIGEgbmV3IGNvbnRhaW5lcgoJCWFkYXB0b3IgPSBjcmVhdGVEdW1teUFkYXB0b3IoKTsKCQljb250YWluZXIgPSBhZGFwdG9yLmdldENvbnRhaW5lcigpOwoJCWRhdGFiYXNlID0gYWRhcHRvci5nZXREYXRhYmFzZSgpOwoJCWRhdGFiYXNlLmxvYWQobmV3IERhdGFJbnB1dFN0cmVhbShuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oYnl0ZXMudG9CeXRlQXJyYXkoKSkpKTsKCgkJc3lzdGVtQnVuZGxlID0gY29udGFpbmVyLmdldE1vZHVsZSgwKTsKCQlBc3NlcnQuYXNzZXJ0Tm90TnVsbCgiU3lzdGVtIGJ1bmRsZSBpcyBudWxsLiIsIHN5c3RlbUJ1bmRsZSk7CgkJQXNzZXJ0LmFzc2VydFRydWUoIlN5c3RlbSBidW5kbGUgc2hvdWxkIGFsd2F5cyB1c2UgYWN0aXZhdGlvbiBwb2xpY3kuIiwgc3lzdGVtQnVuZGxlLmlzQWN0aXZhdGlvblBvbGljeVVzZWQoKSk7CgkJQXNzZXJ0LmFzc2VydFRydWUoIlN5c3RlbSBidW5kbGUgc2hvdWxkIGFsd2F5cyBoYXZlIGl0cyBhdXRvLXN0YXJ0IGZsYWcgc2V0LiIsIHN5c3RlbUJ1bmRsZS5pc1BlcnNpc3RlbnRseVN0YXJ0ZWQoKSk7CgoJCWM0ID0gY29udGFpbmVyLmdldE1vZHVsZShjNC5nZXRJZCgpKTsKCQlBc3NlcnQuYXNzZXJ0Tm90TnVsbCgiYzQgaXMgbnVsbCIsIGM0KTsKCQlsYXp5MSA9IGNvbnRhaW5lci5nZXRNb2R1bGUobGF6eTEuZ2V0SWQoKSk7CgkJQXNzZXJ0LmFzc2VydE5vdE51bGwoImxhenkxIGlzIG51bGwiLCBsYXp5MSk7CgoJCUFzc2VydC5hc3NlcnRGYWxzZSgiYzQgaGFzIGFjdGl2YXRpb24gcG9saWN5IHNldC4iLCBjNC5pc0FjdGl2YXRpb25Qb2xpY3lVc2VkKCkpOwoJCUFzc2VydC5hc3NlcnRUcnVlKCJjNCBpcyBub3QgYXV0byBzdGFydGVkLiIsIGM0LmlzUGVyc2lzdGVudGx5U3RhcnRlZCgpKTsKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJjNCBoYXMgd3Jvbmcgc3RhcnQtbGV2ZWwiLCAzLCBjNC5nZXRTdGFydExldmVsKCkpOwoJCUFzc2VydC5hc3NlcnRUcnVlKCJsYXp5MSBpcyB1c2luZyBhY3RpdmF0aW9uIHBvbGljeS4iLCBsYXp5MS5pc0FjdGl2YXRpb25Qb2xpY3lVc2VkKCkpOwoJCUFzc2VydC5hc3NlcnRUcnVlKCJsYXp5MSBpcyBub3QgYXV0byBzdGFydGVkLiIsIGxhenkxLmlzUGVyc2lzdGVudGx5U3RhcnRlZCgpKTsKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJsYXp5MSBoYXMgd3Jvbmcgc3RhcnQtbGV2ZWwiLCAzLCBsYXp5MS5nZXRTdGFydExldmVsKCkpOwoKCQkvLyByZWxhdW5jaCB0aGUgY29udGFpbmVyCgkJc3lzdGVtQnVuZGxlLnN0YXJ0KCk7CgoJCWFjdHVhbENvbnRhaW5lckV2ZW50cyA9IGRhdGFiYXNlLmdldENvbnRhaW5lckV2ZW50cygpOwoJCWV4cGVjdGVkQ29udGFpbmVyRXZlbnRzID0gbmV3IEFycmF5TGlzdDxEdW1teUNvbnRhaW5lckV2ZW50PihBcnJheXMuYXNMaXN0KG5ldyBEdW1teUNvbnRhaW5lckV2ZW50KENvbnRhaW5lckV2ZW50LlNUQVJUX0xFVkVMLCBzeXN0ZW1CdW5kbGUsIG51bGwpLCBuZXcgRHVtbXlDb250YWluZXJFdmVudChDb250YWluZXJFdmVudC5TVEFSVEVELCBzeXN0ZW1CdW5kbGUsIG51bGwpKSk7CgoJCWFjdHVhbCA9IGRhdGFiYXNlLmdldE1vZHVsZUV2ZW50cygyKTsKCQlleHBlY3RlZCA9IG5ldyBBcnJheUxpc3Q8RHVtbXlNb2R1bGVFdmVudD4oQXJyYXlzLmFzTGlzdChuZXcgRHVtbXlNb2R1bGVFdmVudChzeXN0ZW1CdW5kbGUsIE1vZHVsZUV2ZW50LlNUQVJUSU5HLCBTdGF0ZS5TVEFSVElORyksIG5ldyBEdW1teU1vZHVsZUV2ZW50KHN5c3RlbUJ1bmRsZSwgTW9kdWxlRXZlbnQuU1RBUlRFRCwgU3RhdGUuQUNUSVZFKSkpOwoJCWFzc2VydEV2ZW50cyhleHBlY3RlZCwgYWN0dWFsLCB0cnVlKTsKCgkJY29udGFpbmVyLmdldEZyYW1ld29ya1N0YXJ0TGV2ZWwoKS5zZXRTdGFydExldmVsKDMpOwoKCQlhY3R1YWxDb250YWluZXJFdmVudHMgPSBkYXRhYmFzZS5nZXRDb250YWluZXJFdmVudHMoMSk7CgkJZXhwZWN0ZWRDb250YWluZXJFdmVudHMgPSBuZXcgQXJyYXlMaXN0PER1bW15Q29udGFpbmVyRXZlbnQ+KEFycmF5cy5hc0xpc3QobmV3IER1bW15Q29udGFpbmVyRXZlbnQoQ29udGFpbmVyRXZlbnQuU1RBUlRfTEVWRUwsIHN5c3RlbUJ1bmRsZSwgbnVsbCkpKTsKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJXcm9uZyBjb250YWluZXIgZXZlbnRzLiIsIGV4cGVjdGVkQ29udGFpbmVyRXZlbnRzLCBhY3R1YWxDb250YWluZXJFdmVudHMpOwoKCQlhY3R1YWwgPSBkYXRhYmFzZS5nZXRNb2R1bGVFdmVudHMoMyk7CgkJZXhwZWN0ZWQgPSBuZXcgQXJyYXlMaXN0PER1bW15TW9kdWxlRXZlbnQ+KEFycmF5cy5hc0xpc3QobmV3IER1bW15TW9kdWxlRXZlbnQobGF6eTEsIE1vZHVsZUV2ZW50LkxBWllfQUNUSVZBVElPTiwgU3RhdGUuTEFaWV9TVEFSVElORyksIG5ldyBEdW1teU1vZHVsZUV2ZW50KGM0LCBNb2R1bGVFdmVudC5TVEFSVElORywgU3RhdGUuU1RBUlRJTkcpLCBuZXcgRHVtbXlNb2R1bGVFdmVudChjNCwgTW9kdWxlRXZlbnQuU1RBUlRFRCwgU3RhdGUuQUNUSVZFKSkpOwoJCWFzc2VydEV2ZW50cyhleHBlY3RlZCwgYWN0dWFsLCB0cnVlKTsKCX0KCglAVGVzdAoJcHVibGljIHZvaWQgdGVzdFRpbWVzdGFtcFNlZWRpbmcoKSB0aHJvd3MgQnVuZGxlRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiwgSW50ZXJydXB0ZWRFeGNlcHRpb24gewoJCUFzc2VydC5hc3NlcnROb3RFcXVhbHMoIlRoZSB0aW1lc3RhbXBzIGFyZSB0aGUgc2FtZSEiLCBjcmVhdGVUZXN0Q29udGFpbmVyQW5kR2V0VGltZXN0YW1wKCksIGNyZWF0ZVRlc3RDb250YWluZXJBbmRHZXRUaW1lc3RhbXAoKSk7Cgl9CgoJcHJpdmF0ZSBsb25nIGNyZWF0ZVRlc3RDb250YWluZXJBbmRHZXRUaW1lc3RhbXAoKSB0aHJvd3MgQnVuZGxlRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiwgSW50ZXJydXB0ZWRFeGNlcHRpb24gewoJCS8vIHdhaXQgaGVyZSB0byBlbnN1cmUgY3VycmVudCB0aW1lIHJlYWxseSBoYXMgaW5jcmVhc2VkCgkJVGhyZWFkLnNsZWVwKDEwMCk7CgkJRHVtbXlDb250YWluZXJBZGFwdG9yIGFkYXB0b3IgPSBjcmVhdGVEdW1teUFkYXB0b3IoKTsKCQlNb2R1bGVDb250YWluZXIgY29udGFpbmVyID0gYWRhcHRvci5nZXRDb250YWluZXIoKTsKCQlEdW1teU1vZHVsZURhdGFiYXNlIGRhdGFiYXNlID0gYWRhcHRvci5nZXREYXRhYmFzZSgpOwoKCQlNb2R1bGUgc3lzdGVtQnVuZGxlID0gaW5zdGFsbER1bW15TW9kdWxlKCJzeXN0ZW0uYnVuZGxlLk1GIiwgQ29uc3RhbnRzLlNZU1RFTV9CVU5ETEVfTE9DQVRJT04sIGNvbnRhaW5lcik7CgoJCWNvbnRhaW5lci5yZXNvbHZlKEFycmF5cy5hc0xpc3Qoc3lzdGVtQnVuZGxlKSwgdHJ1ZSk7CgoJCS8vIGFjdHVhbGx5IGxhdW5jaCB0aGUgY29udGFpbmVyCgkJc3lzdGVtQnVuZGxlLnN0YXJ0KCk7CgoJCS8vIGluc3RhbGwgc29tZSBidW5kbGVzIGFuZCBzZXQgc29tZSBzZXR0aW5ncwoJCWNvbnRhaW5lci5nZXRGcmFtZXdvcmtTdGFydExldmVsKCkuc2V0SW5pdGlhbEJ1bmRsZVN0YXJ0TGV2ZWwoMik7CgkJTW9kdWxlIGM0ID0gaW5zdGFsbER1bW15TW9kdWxlKCJjNF92MS5NRiIsICJjNF92MSIsIGNvbnRhaW5lcik7CgkJTW9kdWxlIGxhenkxID0gaW5zdGFsbER1bW15TW9kdWxlKCJsYXp5MV92MS5NRiIsICJsYXp5MSIsIGNvbnRhaW5lcik7CgoJCWNvbnRhaW5lci5yZXNvbHZlKEFycmF5cy5hc0xpc3QoYzQsIGxhenkxKSwgdHJ1ZSk7CgoJCS8vIHNldCBzb21lIHNldHRpbmdzCgkJQXNzZXJ0LmFzc2VydEVxdWFscygiV3Jvbmcgc3RhcnRsZXZlbC4iLCAyLCBjNC5nZXRTdGFydExldmVsKCkpOwoJCUFzc2VydC5hc3NlcnRFcXVhbHMoIldyb25nIHN0YXJ0bGV2ZWwuIiwgMiwgbGF6eTEuZ2V0U3RhcnRMZXZlbCgpKTsKCQlyZXR1cm4gZGF0YWJhc2UuZ2V0VGltZXN0YW1wKCk7Cgl9CgoJQFRlc3QKCXB1YmxpYyB2b2lkIHRlc3RFdmVudHNTdGFydExldmVsQmVnaW5uaW5nQXQxMDAoKSB0aHJvd3MgQnVuZGxlRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CgkJZG9UZXN0RXZlbnRzU3RhcnRMZXZlbCgxMDApOwoJfQoKCUBUZXN0CglwdWJsaWMgdm9pZCB0ZXN0RXZlbnRzU3RhcnRMZXZlbEJlZ2lubmluZ0F0MSgpIHRocm93cyBCdW5kbGVFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKCQlkb1Rlc3RFdmVudHNTdGFydExldmVsKDEpOwoJfQoKCXByaXZhdGUgdm9pZCBkb1Rlc3RFdmVudHNTdGFydExldmVsKGludCBiZWdpbm5pbmdTdGFydExldmVsKSB0aHJvd3MgQnVuZGxlRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CgkJTWFwPFN0cmluZywgU3RyaW5nPiBjb25maWd1cmF0aW9uID0gbmV3IEhhc2hNYXA8U3RyaW5nLCBTdHJpbmc+KCk7CgkJY29uZmlndXJhdGlvbi5wdXQoQ29uc3RhbnRzLkZSQU1FV09SS19CRUdJTk5JTkdfU1RBUlRMRVZFTCwgU3RyaW5nLnZhbHVlT2YoYmVnaW5uaW5nU3RhcnRMZXZlbCkpOwoKCQlEdW1teUNvbnRhaW5lckFkYXB0b3IgYWRhcHRvciA9IG5ldyBEdW1teUNvbnRhaW5lckFkYXB0b3IobmV3IER1bW15Q29sbGlzaW9uSG9vayhmYWxzZSksIGNvbmZpZ3VyYXRpb24pOwoJCU1vZHVsZUNvbnRhaW5lciBjb250YWluZXIgPSBhZGFwdG9yLmdldENvbnRhaW5lcigpOwoJCUR1bW15TW9kdWxlRGF0YWJhc2UgZGF0YWJhc2UgPSBhZGFwdG9yLmdldERhdGFiYXNlKCk7CgoJCU1vZHVsZSBzeXN0ZW1CdW5kbGUgPSBpbnN0YWxsRHVtbXlNb2R1bGUoInN5c3RlbS5idW5kbGUuTUYiLCBDb25zdGFudHMuU1lTVEVNX0JVTkRMRV9MT0NBVElPTiwgY29udGFpbmVyKTsKCgkJY29udGFpbmVyLnJlc29sdmUoQXJyYXlzLmFzTGlzdChzeXN0ZW1CdW5kbGUpLCB0cnVlKTsKCgkJTW9kdWxlIGMxID0gaW5zdGFsbER1bW15TW9kdWxlKCJjMV92MS5NRiIsICJjMV92MSIsIGNvbnRhaW5lcik7CgkJTW9kdWxlIGMyID0gaW5zdGFsbER1bW15TW9kdWxlKCJjMl92MS5NRiIsICJjMl92MSIsIGNvbnRhaW5lcik7CgkJTW9kdWxlIGMzID0gaW5zdGFsbER1bW15TW9kdWxlKCJjM192MS5NRiIsICJjM192MSIsIGNvbnRhaW5lcik7CgkJTW9kdWxlIGM0ID0gaW5zdGFsbER1bW15TW9kdWxlKCJjNF92MS5NRiIsICJjNF92MSIsIGNvbnRhaW5lcik7CgkJTW9kdWxlIGM1ID0gaW5zdGFsbER1bW15TW9kdWxlKCJjNV92MS5NRiIsICJjNV92MSIsIGNvbnRhaW5lcik7CgkJTW9kdWxlIGM2ID0gaW5zdGFsbER1bW15TW9kdWxlKCJjNl92MS5NRiIsICJjNl92MSIsIGNvbnRhaW5lcik7CgkJTW9kdWxlIGM3ID0gaW5zdGFsbER1bW15TW9kdWxlKCJjN192MS5NRiIsICJjN192MSIsIGNvbnRhaW5lcik7CgkJY29udGFpbmVyLnJlc29sdmUoQXJyYXlzLmFzTGlzdChjMSwgYzIsIGMzLCBjNCwgYzUsIGM2LCBjNyksIHRydWUpOwoJCWRhdGFiYXNlLmdldE1vZHVsZUV2ZW50cygpOwoKCQljMS5zZXRTdGFydExldmVsKDcwKTsKCQljMi5zZXRTdGFydExldmVsKDYwKTsKCQljMy5zZXRTdGFydExldmVsKDUwKTsKCQljNC5zZXRTdGFydExldmVsKDQwKTsKCQljNS5zZXRTdGFydExldmVsKDMwKTsKCQljNi5zZXRTdGFydExldmVsKDIwKTsKCQljNy5zZXRTdGFydExldmVsKDEwKTsKCgkJYzEuc3RhcnQoKTsKCQljMi5zdGFydCgpOwoJCWMzLnN0YXJ0KCk7CgkJYzQuc3RhcnQoKTsKCQljNS5zdGFydCgpOwoJCWM2LnN0YXJ0KCk7CgkJYzcuc3RhcnQoKTsKCgkJTGlzdDxEdW1teU1vZHVsZUV2ZW50PiBhY3R1YWxNb2R1bGVFdmVudHMgPSBkYXRhYmFzZS5nZXRNb2R1bGVFdmVudHMoKTsKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJFeHBlY3Rpbmcgbm8gZXZlbnRzLiIsIDAsIGFjdHVhbE1vZHVsZUV2ZW50cy5zaXplKCkpOwoKCQlzeXN0ZW1CdW5kbGUuc3RhcnQoKTsKCgkJaWYgKGJlZ2lubmluZ1N0YXJ0TGV2ZWwgPT0gMSkgewoJCQlhY3R1YWxNb2R1bGVFdmVudHMgPSBkYXRhYmFzZS5nZXRNb2R1bGVFdmVudHMoMik7CgkJCUxpc3Q8RHVtbXlNb2R1bGVFdmVudD4gZXhwZWN0ZWRNb2R1bGVFdmVudHMgPSBuZXcgQXJyYXlMaXN0PER1bW15TW9kdWxlRXZlbnQ+KEFycmF5cy5hc0xpc3QobmV3IER1bW15TW9kdWxlRXZlbnQoc3lzdGVtQnVuZGxlLCBNb2R1bGVFdmVudC5TVEFSVElORywgU3RhdGUuU1RBUlRJTkcpLCBuZXcgRHVtbXlNb2R1bGVFdmVudChzeXN0ZW1CdW5kbGUsIE1vZHVsZUV2ZW50LlNUQVJURUQsIFN0YXRlLkFDVElWRSkpKTsKCQkJYXNzZXJ0RXZlbnRzKGV4cGVjdGVkTW9kdWxlRXZlbnRzLCBhY3R1YWxNb2R1bGVFdmVudHMsIHRydWUpOwoKCQkJTGlzdDxEdW1teUNvbnRhaW5lckV2ZW50PiBhY3R1YWxDb250YWluZXJFdmVudHMgPSBkYXRhYmFzZS5nZXRDb250YWluZXJFdmVudHMoKTsKCQkJTGlzdDxEdW1teUNvbnRhaW5lckV2ZW50PiBleHBlY3RlZENvbnRhaW5lckV2ZW50cyA9IG5ldyBBcnJheUxpc3Q8RHVtbXlDb250YWluZXJFdmVudD4oQXJyYXlzLmFzTGlzdChuZXcgRHVtbXlDb250YWluZXJFdmVudChDb250YWluZXJFdmVudC5TVEFSVEVELCBzeXN0ZW1CdW5kbGUsIG51bGwpKSk7CgkJCUFzc2VydC5hc3NlcnRFcXVhbHMoIldyb25nIGNvbnRhaW5lciBldmVudHMuIiwgZXhwZWN0ZWRDb250YWluZXJFdmVudHMsIGFjdHVhbENvbnRhaW5lckV2ZW50cyk7CgoJCQljb250YWluZXIuZ2V0RnJhbWV3b3JrU3RhcnRMZXZlbCgpLnNldFN0YXJ0TGV2ZWwoMTAwKTsKCQkJYWN0dWFsTW9kdWxlRXZlbnRzID0gZGF0YWJhc2UuZ2V0TW9kdWxlRXZlbnRzKDE0KTsKCQkJZXhwZWN0ZWRNb2R1bGVFdmVudHMgPSBuZXcgQXJyYXlMaXN0PER1bW15TW9kdWxlRXZlbnQ+KEFycmF5cy5hc0xpc3QobmV3IER1bW15TW9kdWxlRXZlbnQoYzcsIE1vZHVsZUV2ZW50LlNUQVJUSU5HLCBTdGF0ZS5TVEFSVElORyksIG5ldyBEdW1teU1vZHVsZUV2ZW50KGM3LCBNb2R1bGVFdmVudC5TVEFSVEVELCBTdGF0ZS5BQ1RJVkUpLCBuZXcgRHVtbXlNb2R1bGVFdmVudChjNiwgTW9kdWxlRXZlbnQuU1RBUlRJTkcsIFN0YXRlLlNUQVJUSU5HKSwgbmV3IER1bW15TW9kdWxlRXZlbnQoYzYsIE1vZHVsZUV2ZW50LlNUQVJURUQsIFN0YXRlLkFDVElWRSksIG5ldyBEdW1teU1vZHVsZUV2ZW50KGM1LCBNb2R1bGVFdmVudC5TVEFSVElORywgU3RhdGUuU1RBUlRJTkcpLCBuZXcgRHVtbXlNb2R1bGVFdmVudChjNSwgTW9kdWxlRXZlbnQuU1RBUlRFRCwgU3RhdGUuQUNUSVZFKSwgbmV3IER1bW15TW9kdWxlRXZlbnQoYzQsIE1vZHVsZUV2ZW50LlNUQVJUSU5HLCBTdGF0ZS5TVEFSVElORyksIG5ldyBEdW1teU1vZHVsZUV2ZW50KGM0LCBNb2R1bGVFdmVudC5TVEFSVEVELCBTdGF0ZS5BQ1RJVkUpLCBuZXcgRHVtbXlNb2R1bGVFdmVudChjMywgTW9kdWxlRXZlbnQuU1RBUlRJTkcsIFN0YXRlLlNUQVJUSU5HKSwgbmV3IER1bW15TW9kdWxlRXZlbnQoYzMsIE1vZHVsZUV2ZW50LlNUQVJURUQsIFN0YXRlLkFDVElWRSksIG5ldyBEdW1teU1vZHVsZUV2ZW50KGMyLCBNb2R1bGVFdmVudC5TVEFSVElORywgU3RhdGUuU1RBUlRJTkcpLAoJCQkJCW5ldyBEdW1teU1vZHVsZUV2ZW50KGMyLCBNb2R1bGVFdmVudC5TVEFSVEVELCBTdGF0ZS5BQ1RJVkUpLCBuZXcgRHVtbXlNb2R1bGVFdmVudChjMSwgTW9kdWxlRXZlbnQuU1RBUlRJTkcsIFN0YXRlLlNUQVJUSU5HKSwgbmV3IER1bW15TW9kdWxlRXZlbnQoYzEsIE1vZHVsZUV2ZW50LlNUQVJURUQsIFN0YXRlLkFDVElWRSkpKTsKCgkJCWFjdHVhbENvbnRhaW5lckV2ZW50cyA9IGRhdGFiYXNlLmdldENvbnRhaW5lckV2ZW50cygxKTsKCQkJZXhwZWN0ZWRDb250YWluZXJFdmVudHMgPSBuZXcgQXJyYXlMaXN0PER1bW15Q29udGFpbmVyRXZlbnQ+KEFycmF5cy5hc0xpc3QobmV3IER1bW15Q29udGFpbmVyRXZlbnQoQ29udGFpbmVyRXZlbnQuU1RBUlRfTEVWRUwsIHN5c3RlbUJ1bmRsZSwgbnVsbCkpKTsKCQkJQXNzZXJ0LmFzc2VydEVxdWFscygiV3JvbmcgY29udGFpbmVyIGV2ZW50cy4iLCBleHBlY3RlZENvbnRhaW5lckV2ZW50cywgYWN0dWFsQ29udGFpbmVyRXZlbnRzKTsKCQl9IGVsc2UgewoJCQlhY3R1YWxNb2R1bGVFdmVudHMgPSBkYXRhYmFzZS5nZXRNb2R1bGVFdmVudHMoMTYpOwoJCQlMaXN0PER1bW15TW9kdWxlRXZlbnQ+IGV4cGVjdGVkTW9kdWxlRXZlbnRzID0gbmV3IEFycmF5TGlzdDxEdW1teU1vZHVsZUV2ZW50PihBcnJheXMuYXNMaXN0KG5ldyBEdW1teU1vZHVsZUV2ZW50KHN5c3RlbUJ1bmRsZSwgTW9kdWxlRXZlbnQuU1RBUlRJTkcsIFN0YXRlLlNUQVJUSU5HKSwgbmV3IER1bW15TW9kdWxlRXZlbnQoYzcsIE1vZHVsZUV2ZW50LlNUQVJUSU5HLCBTdGF0ZS5TVEFSVElORyksIG5ldyBEdW1teU1vZHVsZUV2ZW50KGM3LCBNb2R1bGVFdmVudC5TVEFSVEVELCBTdGF0ZS5BQ1RJVkUpLCBuZXcgRHVtbXlNb2R1bGVFdmVudChjNiwgTW9kdWxlRXZlbnQuU1RBUlRJTkcsIFN0YXRlLlNUQVJUSU5HKSwgbmV3IER1bW15TW9kdWxlRXZlbnQoYzYsIE1vZHVsZUV2ZW50LlNUQVJURUQsIFN0YXRlLkFDVElWRSksIG5ldyBEdW1teU1vZHVsZUV2ZW50KGM1LCBNb2R1bGVFdmVudC5TVEFSVElORywgU3RhdGUuU1RBUlRJTkcpLCBuZXcgRHVtbXlNb2R1bGVFdmVudChjNSwgTW9kdWxlRXZlbnQuU1RBUlRFRCwgU3RhdGUuQUNUSVZFKSwgbmV3IER1bW15TW9kdWxlRXZlbnQoYzQsIE1vZHVsZUV2ZW50LlNUQVJUSU5HLCBTdGF0ZS5TVEFSVElORyksIG5ldyBEdW1teU1vZHVsZUV2ZW50KGM0LCBNb2R1bGVFdmVudC5TVEFSVEVELCBTdGF0ZS5BQ1RJVkUpLCBuZXcgRHVtbXlNb2R1bGVFdmVudChjMywgTW9kdWxlRXZlbnQuU1RBUlRJTkcsIFN0YXRlLlNUQVJUSU5HKSwKCQkJCQluZXcgRHVtbXlNb2R1bGVFdmVudChjMywgTW9kdWxlRXZlbnQuU1RBUlRFRCwgU3RhdGUuQUNUSVZFKSwgbmV3IER1bW15TW9kdWxlRXZlbnQoYzIsIE1vZHVsZUV2ZW50LlNUQVJUSU5HLCBTdGF0ZS5TVEFSVElORyksIG5ldyBEdW1teU1vZHVsZUV2ZW50KGMyLCBNb2R1bGVFdmVudC5TVEFSVEVELCBTdGF0ZS5BQ1RJVkUpLCBuZXcgRHVtbXlNb2R1bGVFdmVudChjMSwgTW9kdWxlRXZlbnQuU1RBUlRJTkcsIFN0YXRlLlNUQVJUSU5HKSwgbmV3IER1bW15TW9kdWxlRXZlbnQoYzEsIE1vZHVsZUV2ZW50LlNUQVJURUQsIFN0YXRlLkFDVElWRSksIG5ldyBEdW1teU1vZHVsZUV2ZW50KHN5c3RlbUJ1bmRsZSwgTW9kdWxlRXZlbnQuU1RBUlRFRCwgU3RhdGUuQUNUSVZFKSkpOwoJCQlhc3NlcnRFdmVudHMoZXhwZWN0ZWRNb2R1bGVFdmVudHMsIGFjdHVhbE1vZHVsZUV2ZW50cywgdHJ1ZSk7CgoJCQlMaXN0PER1bW15Q29udGFpbmVyRXZlbnQ+IGFjdHVhbENvbnRhaW5lckV2ZW50cyA9IGRhdGFiYXNlLmdldENvbnRhaW5lckV2ZW50cygpOwoJCQlMaXN0PER1bW15Q29udGFpbmVyRXZlbnQ+IGV4cGVjdGVkQ29udGFpbmVyRXZlbnRzID0gbmV3IEFycmF5TGlzdDxEdW1teUNvbnRhaW5lckV2ZW50PihBcnJheXMuYXNMaXN0KG5ldyBEdW1teUNvbnRhaW5lckV2ZW50KENvbnRhaW5lckV2ZW50LlNUQVJURUQsIHN5c3RlbUJ1bmRsZSwgbnVsbCkpKTsKCQkJQXNzZXJ0LmFzc2VydEVxdWFscygiV3JvbmcgY29udGFpbmVyIGV2ZW50cy4iLCBleHBlY3RlZENvbnRhaW5lckV2ZW50cywgYWN0dWFsQ29udGFpbmVyRXZlbnRzKTsKCQl9CgoJCWlmIChiZWdpbm5pbmdTdGFydExldmVsID09IDEpIHsKCQkJY29udGFpbmVyLmdldEZyYW1ld29ya1N0YXJ0TGV2ZWwoKS5zZXRTdGFydExldmVsKDEpOwoJCQlhY3R1YWxNb2R1bGVFdmVudHMgPSBkYXRhYmFzZS5nZXRNb2R1bGVFdmVudHMoMTQpOwoJCQlMaXN0PER1bW15TW9kdWxlRXZlbnQ+IGV4cGVjdGVkTW9kdWxlRXZlbnRzID0gbmV3IEFycmF5TGlzdDxEdW1teU1vZHVsZUV2ZW50PihBcnJheXMuYXNMaXN0KG5ldyBEdW1teU1vZHVsZUV2ZW50KGMxLCBNb2R1bGVFdmVudC5TVE9QUElORywgU3RhdGUuU1RPUFBJTkcpLCBuZXcgRHVtbXlNb2R1bGVFdmVudChjMSwgTW9kdWxlRXZlbnQuU1RPUFBFRCwgU3RhdGUuUkVTT0xWRUQpLCBuZXcgRHVtbXlNb2R1bGVFdmVudChjMiwgTW9kdWxlRXZlbnQuU1RPUFBJTkcsIFN0YXRlLlNUT1BQSU5HKSwgbmV3IER1bW15TW9kdWxlRXZlbnQoYzIsIE1vZHVsZUV2ZW50LlNUT1BQRUQsIFN0YXRlLlJFU09MVkVEKSwgbmV3IER1bW15TW9kdWxlRXZlbnQoYzMsIE1vZHVsZUV2ZW50LlNUT1BQSU5HLCBTdGF0ZS5TVE9QUElORyksIG5ldyBEdW1teU1vZHVsZUV2ZW50KGMzLCBNb2R1bGVFdmVudC5TVE9QUEVELCBTdGF0ZS5SRVNPTFZFRCksIG5ldyBEdW1teU1vZHVsZUV2ZW50KGM0LCBNb2R1bGVFdmVudC5TVE9QUElORywgU3RhdGUuU1RPUFBJTkcpLCBuZXcgRHVtbXlNb2R1bGVFdmVudChjNCwgTW9kdWxlRXZlbnQuU1RPUFBFRCwgU3RhdGUuUkVTT0xWRUQpLCBuZXcgRHVtbXlNb2R1bGVFdmVudChjNSwgTW9kdWxlRXZlbnQuU1RPUFBJTkcsIFN0YXRlLlNUT1BQSU5HKSwgbmV3IER1bW15TW9kdWxlRXZlbnQoYzUsIE1vZHVsZUV2ZW50LlNUT1BQRUQsIFN0YXRlLlJFU09MVkVEKSwKCQkJCQluZXcgRHVtbXlNb2R1bGVFdmVudChjNiwgTW9kdWxlRXZlbnQuU1RPUFBJTkcsIFN0YXRlLlNUT1BQSU5HKSwgbmV3IER1bW15TW9kdWxlRXZlbnQoYzYsIE1vZHVsZUV2ZW50LlNUT1BQRUQsIFN0YXRlLlJFU09MVkVEKSwgbmV3IER1bW15TW9kdWxlRXZlbnQoYzcsIE1vZHVsZUV2ZW50LlNUT1BQSU5HLCBTdGF0ZS5TVE9QUElORyksIG5ldyBEdW1teU1vZHVsZUV2ZW50KGM3LCBNb2R1bGVFdmVudC5TVE9QUEVELCBTdGF0ZS5SRVNPTFZFRCkpKTsKCQkJYXNzZXJ0RXZlbnRzKGV4cGVjdGVkTW9kdWxlRXZlbnRzLCBhY3R1YWxNb2R1bGVFdmVudHMsIHRydWUpOwoKCQkJTGlzdDxEdW1teUNvbnRhaW5lckV2ZW50PiBhY3R1YWxDb250YWluZXJFdmVudHMgPSBkYXRhYmFzZS5nZXRDb250YWluZXJFdmVudHMoMSk7CgkJCUxpc3Q8RHVtbXlDb250YWluZXJFdmVudD4gZXhwZWN0ZWRDb250YWluZXJFdmVudHMgPSBuZXcgQXJyYXlMaXN0PER1bW15Q29udGFpbmVyRXZlbnQ+KEFycmF5cy5hc0xpc3QobmV3IER1bW15Q29udGFpbmVyRXZlbnQoQ29udGFpbmVyRXZlbnQuU1RBUlRfTEVWRUwsIHN5c3RlbUJ1bmRsZSwgbnVsbCkpKTsKCQkJQXNzZXJ0LmFzc2VydEVxdWFscygiV3JvbmcgY29udGFpbmVyIGV2ZW50cy4iLCBleHBlY3RlZENvbnRhaW5lckV2ZW50cywgYWN0dWFsQ29udGFpbmVyRXZlbnRzKTsKCQl9CgoJCXN5c3RlbUJ1bmRsZS5zdG9wKCk7CgoJCWlmIChiZWdpbm5pbmdTdGFydExldmVsID09IDEpIHsKCQkJYWN0dWFsTW9kdWxlRXZlbnRzID0gZGF0YWJhc2UuZ2V0TW9kdWxlRXZlbnRzKDIpOwoJCQlMaXN0PER1bW15TW9kdWxlRXZlbnQ+IGV4cGVjdGVkTW9kdWxlRXZlbnRzID0gbmV3IEFycmF5TGlzdDxEdW1teU1vZHVsZUV2ZW50PihBcnJheXMuYXNMaXN0KG5ldyBEdW1teU1vZHVsZUV2ZW50KHN5c3RlbUJ1bmRsZSwgTW9kdWxlRXZlbnQuU1RPUFBJTkcsIFN0YXRlLlNUT1BQSU5HKSwgbmV3IER1bW15TW9kdWxlRXZlbnQoc3lzdGVtQnVuZGxlLCBNb2R1bGVFdmVudC5TVE9QUEVELCBTdGF0ZS5SRVNPTFZFRCkpKTsKCQkJYXNzZXJ0RXZlbnRzKGV4cGVjdGVkTW9kdWxlRXZlbnRzLCBhY3R1YWxNb2R1bGVFdmVudHMsIHRydWUpOwoJCX0gZWxzZSB7CgkJCWFjdHVhbE1vZHVsZUV2ZW50cyA9IGRhdGFiYXNlLmdldE1vZHVsZUV2ZW50cygxNik7CgkJCUxpc3Q8RHVtbXlNb2R1bGVFdmVudD4gZXhwZWN0ZWRNb2R1bGVFdmVudHMgPSBuZXcgQXJyYXlMaXN0PER1bW15TW9kdWxlRXZlbnQ+KEFycmF5cy5hc0xpc3QobmV3IER1bW15TW9kdWxlRXZlbnQoc3lzdGVtQnVuZGxlLCBNb2R1bGVFdmVudC5TVE9QUElORywgU3RhdGUuU1RPUFBJTkcpLCBuZXcgRHVtbXlNb2R1bGVFdmVudChjMSwgTW9kdWxlRXZlbnQuU1RPUFBJTkcsIFN0YXRlLlNUT1BQSU5HKSwgbmV3IER1bW15TW9kdWxlRXZlbnQoYzEsIE1vZHVsZUV2ZW50LlNUT1BQRUQsIFN0YXRlLlJFU09MVkVEKSwgbmV3IER1bW15TW9kdWxlRXZlbnQoYzIsIE1vZHVsZUV2ZW50LlNUT1BQSU5HLCBTdGF0ZS5TVE9QUElORyksIG5ldyBEdW1teU1vZHVsZUV2ZW50KGMyLCBNb2R1bGVFdmVudC5TVE9QUEVELCBTdGF0ZS5SRVNPTFZFRCksIG5ldyBEdW1teU1vZHVsZUV2ZW50KGMzLCBNb2R1bGVFdmVudC5TVE9QUElORywgU3RhdGUuU1RPUFBJTkcpLCBuZXcgRHVtbXlNb2R1bGVFdmVudChjMywgTW9kdWxlRXZlbnQuU1RPUFBFRCwgU3RhdGUuUkVTT0xWRUQpLCBuZXcgRHVtbXlNb2R1bGVFdmVudChjNCwgTW9kdWxlRXZlbnQuU1RPUFBJTkcsIFN0YXRlLlNUT1BQSU5HKSwgbmV3IER1bW15TW9kdWxlRXZlbnQoYzQsIE1vZHVsZUV2ZW50LlNUT1BQRUQsIFN0YXRlLlJFU09MVkVEKSwgbmV3IER1bW15TW9kdWxlRXZlbnQoYzUsIE1vZHVsZUV2ZW50LlNUT1BQSU5HLCBTdGF0ZS5TVE9QUElORyksCgkJCQkJbmV3IER1bW15TW9kdWxlRXZlbnQoYzUsIE1vZHVsZUV2ZW50LlNUT1BQRUQsIFN0YXRlLlJFU09MVkVEKSwgbmV3IER1bW15TW9kdWxlRXZlbnQoYzYsIE1vZHVsZUV2ZW50LlNUT1BQSU5HLCBTdGF0ZS5TVE9QUElORyksIG5ldyBEdW1teU1vZHVsZUV2ZW50KGM2LCBNb2R1bGVFdmVudC5TVE9QUEVELCBTdGF0ZS5SRVNPTFZFRCksIG5ldyBEdW1teU1vZHVsZUV2ZW50KGM3LCBNb2R1bGVFdmVudC5TVE9QUElORywgU3RhdGUuU1RPUFBJTkcpLCBuZXcgRHVtbXlNb2R1bGVFdmVudChjNywgTW9kdWxlRXZlbnQuU1RPUFBFRCwgU3RhdGUuUkVTT0xWRUQpLCBuZXcgRHVtbXlNb2R1bGVFdmVudChzeXN0ZW1CdW5kbGUsIE1vZHVsZUV2ZW50LlNUT1BQRUQsIFN0YXRlLlJFU09MVkVEKSkpOwoJCQlhc3NlcnRFdmVudHMoZXhwZWN0ZWRNb2R1bGVFdmVudHMsIGFjdHVhbE1vZHVsZUV2ZW50cywgdHJ1ZSk7CgkJfQoJCUxpc3Q8RHVtbXlDb250YWluZXJFdmVudD4gYWN0dWFsQ29udGFpbmVyRXZlbnRzID0gZGF0YWJhc2UuZ2V0Q29udGFpbmVyRXZlbnRzKCk7CgkJTGlzdDxEdW1teUNvbnRhaW5lckV2ZW50PiBleHBlY3RlZENvbnRhaW5lckV2ZW50cyA9IG5ldyBBcnJheUxpc3Q8RHVtbXlDb250YWluZXJFdmVudD4oQXJyYXlzLmFzTGlzdChuZXcgRHVtbXlDb250YWluZXJFdmVudChDb250YWluZXJFdmVudC5TVE9QUEVELCBzeXN0ZW1CdW5kbGUsIG51bGwpKSk7CgkJQXNzZXJ0LmFzc2VydEVxdWFscygiV3JvbmcgY29udGFpbmVyIGV2ZW50cy4iLCBleHBlY3RlZENvbnRhaW5lckV2ZW50cywgYWN0dWFsQ29udGFpbmVyRXZlbnRzKTsKCX0KCglAVGVzdAoJcHVibGljIHZvaWQgdGVzdER5bmFtaWNJbXBvcnQwMSgpIHRocm93cyBCdW5kbGVFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKCQlEdW1teUNvbnRhaW5lckFkYXB0b3IgYWRhcHRvciA9IGNyZWF0ZUR1bW15QWRhcHRvcigpOwoJCU1vZHVsZUNvbnRhaW5lciBjb250YWluZXIgPSBhZGFwdG9yLmdldENvbnRhaW5lcigpOwoKCQlNb2R1bGUgc3lzdGVtQnVuZGxlID0gaW5zdGFsbER1bW15TW9kdWxlKCJzeXN0ZW0uYnVuZGxlLk1GIiwgQ29uc3RhbnRzLlNZU1RFTV9CVU5ETEVfTE9DQVRJT04sIG51bGwsIG51bGwsICJvc2dpLmVlOyBvc2dpLmVlPUphdmFTRTsgdmVyc2lvbjpWZXJzaW9uPVwiMS41LjBcIiIsIGNvbnRhaW5lcik7CgoJCWNvbnRhaW5lci5yZXNvbHZlKEFycmF5cy5hc0xpc3Qoc3lzdGVtQnVuZGxlKSwgdHJ1ZSk7CgoJCU1vZHVsZSBjMSA9IGluc3RhbGxEdW1teU1vZHVsZSgiYzFfdjEuTUYiLCAiYzFfdjEiLCBjb250YWluZXIpOwoJCU1vZHVsZSBkeW5hbWljMSA9IGluc3RhbGxEdW1teU1vZHVsZSgiZHluYW1pYzFfdjEuTUYiLCAiZHluYW1pYzFfdjEiLCBjb250YWluZXIpOwoKCQljb250YWluZXIucmVzb2x2ZShBcnJheXMuYXNMaXN0KGMxLCBkeW5hbWljMSksIHRydWUpOwoKCQlNb2R1bGVXaXJlIGR5bmFtaWNXaXJlID0gY29udGFpbmVyLnJlc29sdmVEeW5hbWljKCJvcmcub3NnaS5mcmFtZXdvcmsiLCBkeW5hbWljMS5nZXRDdXJyZW50UmV2aXNpb24oKSk7CgkJQXNzZXJ0LmFzc2VydE5vdE51bGwoIk5vIGR5bmFtaWMgd2lyZSBmb3VuZC4iLCBkeW5hbWljV2lyZSk7CgkJQXNzZXJ0LmFzc2VydEVxdWFscygiV3JvbmcgcGFja2FnZSBmb3VuZC4iLCAib3JnLm9zZ2kuZnJhbWV3b3JrIiwgZHluYW1pY1dpcmUuZ2V0Q2FwYWJpbGl0eSgpLmdldEF0dHJpYnV0ZXMoKS5nZXQoUGFja2FnZU5hbWVzcGFjZS5QQUNLQUdFX05BTUVTUEFDRSkpOwoJCUFzc2VydC5hc3NlcnRFcXVhbHMoIldyb25nIHByb3ZpZGVyIGZvciB0aGUgd2lyZSBmb3VuZC4iLCBzeXN0ZW1CdW5kbGUuZ2V0Q3VycmVudFJldmlzaW9uKCksIGR5bmFtaWNXaXJlLmdldFByb3ZpZGVyKCkpOwoKCQlkeW5hbWljV2lyZSA9IGNvbnRhaW5lci5yZXNvbHZlRHluYW1pYygib3JnLm9zZ2kuZnJhbWV3b3JrLndpcmluZyIsIGR5bmFtaWMxLmdldEN1cnJlbnRSZXZpc2lvbigpKTsKCQlBc3NlcnQuYXNzZXJ0Tm90TnVsbCgiTm8gZHluYW1pYyB3aXJlIGZvdW5kLiIsIGR5bmFtaWNXaXJlKTsKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJXcm9uZyBwYWNrYWdlIGZvdW5kLiIsICJvcmcub3NnaS5mcmFtZXdvcmsud2lyaW5nIiwgZHluYW1pY1dpcmUuZ2V0Q2FwYWJpbGl0eSgpLmdldEF0dHJpYnV0ZXMoKS5nZXQoUGFja2FnZU5hbWVzcGFjZS5QQUNLQUdFX05BTUVTUEFDRSkpOwoJCUFzc2VydC5hc3NlcnRFcXVhbHMoIldyb25nIHByb3ZpZGVyIGZvciB0aGUgd2lyZSBmb3VuZC4iLCBzeXN0ZW1CdW5kbGUuZ2V0Q3VycmVudFJldmlzaW9uKCksIGR5bmFtaWNXaXJlLmdldFByb3ZpZGVyKCkpOwoKCQlkeW5hbWljV2lyZSA9IGNvbnRhaW5lci5yZXNvbHZlRHluYW1pYygiYzEuYiIsIGR5bmFtaWMxLmdldEN1cnJlbnRSZXZpc2lvbigpKTsKCQlBc3NlcnQuYXNzZXJ0Tm90TnVsbCgiTm8gZHluYW1pYyB3aXJlIGZvdW5kLiIsIGR5bmFtaWNXaXJlKTsKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJXcm9uZyBwYWNrYWdlIGZvdW5kLiIsICJjMS5iIiwgZHluYW1pY1dpcmUuZ2V0Q2FwYWJpbGl0eSgpLmdldEF0dHJpYnV0ZXMoKS5nZXQoUGFja2FnZU5hbWVzcGFjZS5QQUNLQUdFX05BTUVTUEFDRSkpOwoJCUFzc2VydC5hc3NlcnRFcXVhbHMoIldyb25nIHByb3ZpZGVyIGZvciB0aGUgd2lyZSBmb3VuZC4iLCBjMS5nZXRDdXJyZW50UmV2aXNpb24oKSwgZHluYW1pY1dpcmUuZ2V0UHJvdmlkZXIoKSk7Cgl9CgoJQFRlc3QKCXB1YmxpYyB2b2lkIHRlc3REeW5hbWljSW1wb3J0MDIoKSB0aHJvd3MgQnVuZGxlRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CgkJRHVtbXlDb250YWluZXJBZGFwdG9yIGFkYXB0b3IgPSBjcmVhdGVEdW1teUFkYXB0b3IoKTsKCQlNb2R1bGVDb250YWluZXIgY29udGFpbmVyID0gYWRhcHRvci5nZXRDb250YWluZXIoKTsKCgkJTW9kdWxlIHN5c3RlbUJ1bmRsZSA9IGluc3RhbGxEdW1teU1vZHVsZSgic3lzdGVtLmJ1bmRsZS5NRiIsIENvbnN0YW50cy5TWVNURU1fQlVORExFX0xPQ0FUSU9OLCBudWxsLCBudWxsLCAib3NnaS5lZTsgb3NnaS5lZT1KYXZhU0U7IHZlcnNpb246VmVyc2lvbj1cIjEuNS4wXCIiLCBjb250YWluZXIpOwoKCQljb250YWluZXIucmVzb2x2ZShBcnJheXMuYXNMaXN0KHN5c3RlbUJ1bmRsZSksIHRydWUpOwoKCQlNb2R1bGUgYzEgPSBpbnN0YWxsRHVtbXlNb2R1bGUoImMxX3YxLk1GIiwgImMxX3YxIiwgY29udGFpbmVyKTsKCQlNb2R1bGUgYzQgPSBpbnN0YWxsRHVtbXlNb2R1bGUoImM0X3YxLk1GIiwgImM0X3YxIiwgY29udGFpbmVyKTsKCQlNb2R1bGUgZHluYW1pYzEgPSBpbnN0YWxsRHVtbXlNb2R1bGUoImR5bmFtaWMxX3YxLk1GIiwgImR5bmFtaWMxX3YxIiwgY29udGFpbmVyKTsKCQlNb2R1bGUgZHluYW1pYzFGcmFnID0gaW5zdGFsbER1bW15TW9kdWxlKCJkeW5hbWljMS5mcmFnX3YxLk1GIiwgImR5bmFtaWMxLmZyYWdfdjEiLCBjb250YWluZXIpOwoKCQljb250YWluZXIucmVzb2x2ZShBcnJheXMuYXNMaXN0KGMxLCBjNCwgZHluYW1pYzEsIGR5bmFtaWMxRnJhZyksIHRydWUpOwoKCQlNb2R1bGVXaXJlIGR5bmFtaWNXaXJlID0gY29udGFpbmVyLnJlc29sdmVEeW5hbWljKCJjMS5iIiwgZHluYW1pYzEuZ2V0Q3VycmVudFJldmlzaW9uKCkpOwoJCUFzc2VydC5hc3NlcnROb3ROdWxsKCJObyBkeW5hbWljIHdpcmUgZm91bmQuIiwgZHluYW1pY1dpcmUpOwoJCUFzc2VydC5hc3NlcnRFcXVhbHMoIldyb25nIHBhY2thZ2UgZm91bmQuIiwgImMxLmIiLCBkeW5hbWljV2lyZS5nZXRDYXBhYmlsaXR5KCkuZ2V0QXR0cmlidXRlcygpLmdldChQYWNrYWdlTmFtZXNwYWNlLlBBQ0tBR0VfTkFNRVNQQUNFKSk7CgkJQXNzZXJ0LmFzc2VydEVxdWFscygiV3JvbmcgcHJvdmlkZXIgZm9yIHRoZSB3aXJlIGZvdW5kLiIsIGMxLmdldEN1cnJlbnRSZXZpc2lvbigpLCBkeW5hbWljV2lyZS5nZXRQcm92aWRlcigpKTsKCgkJZHluYW1pY1dpcmUgPSBjb250YWluZXIucmVzb2x2ZUR5bmFtaWMoImM0LmEiLCBkeW5hbWljMS5nZXRDdXJyZW50UmV2aXNpb24oKSk7CgkJQXNzZXJ0LmFzc2VydE5vdE51bGwoIk5vIGR5bmFtaWMgd2lyZSBmb3VuZC4iLCBkeW5hbWljV2lyZSk7CgkJQXNzZXJ0LmFzc2VydEVxdWFscygiV3JvbmcgcGFja2FnZSBmb3VuZC4iLCAiYzQuYSIsIGR5bmFtaWNXaXJlLmdldENhcGFiaWxpdHkoKS5nZXRBdHRyaWJ1dGVzKCkuZ2V0KFBhY2thZ2VOYW1lc3BhY2UuUEFDS0FHRV9OQU1FU1BBQ0UpKTsKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJXcm9uZyBwcm92aWRlciBmb3IgdGhlIHdpcmUgZm91bmQuIiwgYzQuZ2V0Q3VycmVudFJldmlzaW9uKCksIGR5bmFtaWNXaXJlLmdldFByb3ZpZGVyKCkpOwoKCQlkeW5hbWljV2lyZSA9IGNvbnRhaW5lci5yZXNvbHZlRHluYW1pYygiYzQuYiIsIGR5bmFtaWMxLmdldEN1cnJlbnRSZXZpc2lvbigpKTsKCQlBc3NlcnQuYXNzZXJ0Tm90TnVsbCgiTm8gZHluYW1pYyB3aXJlIGZvdW5kLiIsIGR5bmFtaWNXaXJlKTsKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJXcm9uZyBwYWNrYWdlIGZvdW5kLiIsICJjNC5iIiwgZHluYW1pY1dpcmUuZ2V0Q2FwYWJpbGl0eSgpLmdldEF0dHJpYnV0ZXMoKS5nZXQoUGFja2FnZU5hbWVzcGFjZS5QQUNLQUdFX05BTUVTUEFDRSkpOwoJCUFzc2VydC5hc3NlcnRFcXVhbHMoIldyb25nIHByb3ZpZGVyIGZvciB0aGUgd2lyZSBmb3VuZC4iLCBjNC5nZXRDdXJyZW50UmV2aXNpb24oKSwgZHluYW1pY1dpcmUuZ2V0UHJvdmlkZXIoKSk7Cgl9CgoJQFRlc3QKCXB1YmxpYyB2b2lkIHRlc3REeW5hbWljSW1wb3J0MDMoKSB0aHJvd3MgQnVuZGxlRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CgkJRHVtbXlDb250YWluZXJBZGFwdG9yIGFkYXB0b3IgPSBjcmVhdGVEdW1teUFkYXB0b3IoKTsKCQlNb2R1bGVDb250YWluZXIgY29udGFpbmVyID0gYWRhcHRvci5nZXRDb250YWluZXIoKTsKCQlEdW1teU1vZHVsZURhdGFiYXNlIGRhdGFiYXNlID0gYWRhcHRvci5nZXREYXRhYmFzZSgpOwoJCU1vZHVsZSBzeXN0ZW1CdW5kbGUgPSBpbnN0YWxsRHVtbXlNb2R1bGUoInN5c3RlbS5idW5kbGUuTUYiLCBDb25zdGFudHMuU1lTVEVNX0JVTkRMRV9MT0NBVElPTiwgY29udGFpbmVyKTsKCgkJY29udGFpbmVyLnJlc29sdmUoQXJyYXlzLmFzTGlzdChzeXN0ZW1CdW5kbGUpLCB0cnVlKTsKCgkJTW9kdWxlIGR5bmFtaWMzID0gaW5zdGFsbER1bW15TW9kdWxlKCJkeW5hbWljMl92MS5NRiIsICJkeW5hbWljMl92MSIsIGNvbnRhaW5lcik7CgoJCWNvbnRhaW5lci5yZXNvbHZlKEFycmF5cy5hc0xpc3Qoc3lzdGVtQnVuZGxlLCBkeW5hbWljMyksIHRydWUpOwoKCQlNb2R1bGVXaXJlIGR5bmFtaWNXaXJlID0gY29udGFpbmVyLnJlc29sdmVEeW5hbWljKCJjMS5hIiwgZHluYW1pYzMuZ2V0Q3VycmVudFJldmlzaW9uKCkpOwoJCUFzc2VydC5hc3NlcnROdWxsKCJEeW5hbWljIHdpcmUgZm91bmQuIiwgZHluYW1pY1dpcmUpOwoKCQlNb2R1bGUgYzF2MSA9IGluc3RhbGxEdW1teU1vZHVsZSgiYzFfdjEuTUYiLCAiYzFfdjEiLCBjb250YWluZXIpOwoJCWRhdGFiYXNlLmdldE1vZHVsZUV2ZW50cygpOwoKCQlkeW5hbWljV2lyZSA9IGNvbnRhaW5lci5yZXNvbHZlRHluYW1pYygiYzEuYSIsIGR5bmFtaWMzLmdldEN1cnJlbnRSZXZpc2lvbigpKTsKCQlBc3NlcnQuYXNzZXJ0Tm90TnVsbCgiRHluYW1pYyB3aXJlIG5vdCBmb3VuZC4iLCBkeW5hbWljV2lyZSk7CgkJQXNzZXJ0LmFzc2VydEVxdWFscygiV3JvbmcgcGFja2FnZSBmb3VuZC4iLCAiYzEuYSIsIGR5bmFtaWNXaXJlLmdldENhcGFiaWxpdHkoKS5nZXRBdHRyaWJ1dGVzKCkuZ2V0KFBhY2thZ2VOYW1lc3BhY2UuUEFDS0FHRV9OQU1FU1BBQ0UpKTsKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJXcm9uZyBwcm92aWRlciBmb3IgdGhlIHdpcmUgZm91bmQuIiwgYzF2MS5nZXRDdXJyZW50UmV2aXNpb24oKSwgZHluYW1pY1dpcmUuZ2V0UHJvdmlkZXIoKSk7CgoJCU1vZHVsZVdpcmluZyBjMXYxV2lyaW5nID0gYzF2MS5nZXRDdXJyZW50UmV2aXNpb24oKS5nZXRXaXJpbmcoKTsKCQlBc3NlcnQuYXNzZXJ0Tm90TnVsbCgiYzEgd2lyaW5nIGlzIG51bGwuIiwgYzF2MVdpcmluZyk7CgoJCU1vZHVsZSBjMXYyID0gaW5zdGFsbER1bW15TW9kdWxlKCJjMV92Mi5NRiIsICJjMV92MiIsIGNvbnRhaW5lcik7CgkJY29udGFpbmVyLnJlc29sdmUoQXJyYXlzLmFzTGlzdChjMXYyKSwgdHJ1ZSk7CgkJZGF0YWJhc2UuZ2V0TW9kdWxlRXZlbnRzKCk7CgoJCWR5bmFtaWNXaXJlID0gY29udGFpbmVyLnJlc29sdmVEeW5hbWljKCJjMS5iIiwgZHluYW1pYzMuZ2V0Q3VycmVudFJldmlzaW9uKCkpOwoJCUFzc2VydC5hc3NlcnROb3ROdWxsKCJEeW5hbWljIHdpcmUgbm90IGZvdW5kLiIsIGR5bmFtaWNXaXJlKTsKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJXcm9uZyBwYWNrYWdlIGZvdW5kLiIsICJjMS5iIiwgZHluYW1pY1dpcmUuZ2V0Q2FwYWJpbGl0eSgpLmdldEF0dHJpYnV0ZXMoKS5nZXQoUGFja2FnZU5hbWVzcGFjZS5QQUNLQUdFX05BTUVTUEFDRSkpOwoJCUFzc2VydC5hc3NlcnRFcXVhbHMoIldyb25nIHByb3ZpZGVyLiIsIGMxdjEuZ2V0Q3VycmVudFJldmlzaW9uKCksIGR5bmFtaWNXaXJlLmdldFByb3ZpZGVyKCkpOwoJfQoKCUBUZXN0CglwdWJsaWMgdm9pZCB0ZXN0RHluYW1pY0ltcG9ydDA0KCkgdGhyb3dzIEJ1bmRsZUV4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewoJCUR1bW15Q29udGFpbmVyQWRhcHRvciBhZGFwdG9yID0gY3JlYXRlRHVtbXlBZGFwdG9yKCk7CgkJTW9kdWxlQ29udGFpbmVyIGNvbnRhaW5lciA9IGFkYXB0b3IuZ2V0Q29udGFpbmVyKCk7CgkJRHVtbXlNb2R1bGVEYXRhYmFzZSBkYXRhYmFzZSA9IGFkYXB0b3IuZ2V0RGF0YWJhc2UoKTsKCQlNb2R1bGUgc3lzdGVtQnVuZGxlID0gaW5zdGFsbER1bW15TW9kdWxlKCJzeXN0ZW0uYnVuZGxlLk1GIiwgQ29uc3RhbnRzLlNZU1RFTV9CVU5ETEVfTE9DQVRJT04sIGNvbnRhaW5lcik7CgoJCWNvbnRhaW5lci5yZXNvbHZlKEFycmF5cy5hc0xpc3Qoc3lzdGVtQnVuZGxlKSwgdHJ1ZSk7CgoJCU1vZHVsZSBkeW5hbWljMyA9IGluc3RhbGxEdW1teU1vZHVsZSgiZHluYW1pYzJfdjEuTUYiLCAiZHluYW1pYzJfdjEiLCBjb250YWluZXIpOwoKCQljb250YWluZXIucmVzb2x2ZShBcnJheXMuYXNMaXN0KHN5c3RlbUJ1bmRsZSwgZHluYW1pYzMpLCB0cnVlKTsKCgkJTW9kdWxlV2lyZSBkeW5hbWljV2lyZSA9IGNvbnRhaW5lci5yZXNvbHZlRHluYW1pYygiaDEuYSIsIGR5bmFtaWMzLmdldEN1cnJlbnRSZXZpc2lvbigpKTsKCQlBc3NlcnQuYXNzZXJ0TnVsbCgiRHluYW1pYyB3aXJlIGZvdW5kLiIsIGR5bmFtaWNXaXJlKTsKCgkJTW9kdWxlIGgxID0gaW5zdGFsbER1bW15TW9kdWxlKCJoMV92MS5NRiIsICJoMV92MSIsIGNvbnRhaW5lcik7CgkJTW9kdWxlIGYxID0gaW5zdGFsbER1bW15TW9kdWxlKCJmMV92MS5NRiIsICJmMV92MSIsIGNvbnRhaW5lcik7CgkJZGF0YWJhc2UuZ2V0TW9kdWxlRXZlbnRzKCk7CgoJCWR5bmFtaWNXaXJlID0gY29udGFpbmVyLnJlc29sdmVEeW5hbWljKCJoMS5hIiwgZHluYW1pYzMuZ2V0Q3VycmVudFJldmlzaW9uKCkpOwoJCUFzc2VydC5hc3NlcnROb3ROdWxsKCJEeW5hbWljIHdpcmUgbm90IGZvdW5kLiIsIGR5bmFtaWNXaXJlKTsKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJXcm9uZyBwYWNrYWdlIGZvdW5kLiIsICJoMS5hIiwgZHluYW1pY1dpcmUuZ2V0Q2FwYWJpbGl0eSgpLmdldEF0dHJpYnV0ZXMoKS5nZXQoUGFja2FnZU5hbWVzcGFjZS5QQUNLQUdFX05BTUVTUEFDRSkpOwoJCUFzc2VydC5hc3NlcnRFcXVhbHMoIldyb25nIHByb3ZpZGVyIGZvciB0aGUgd2lyZSBmb3VuZC4iLCBoMS5nZXRDdXJyZW50UmV2aXNpb24oKSwgZHluYW1pY1dpcmUuZ2V0UHJvdmlkZXIoKSk7CgoJCWR5bmFtaWNXaXJlID0gY29udGFpbmVyLnJlc29sdmVEeW5hbWljKCJmMS5hIiwgZHluYW1pYzMuZ2V0Q3VycmVudFJldmlzaW9uKCkpOwoJCUFzc2VydC5hc3NlcnROb3ROdWxsKCJEeW5hbWljIHdpcmUgbm90IGZvdW5kLiIsIGR5bmFtaWNXaXJlKTsKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJXcm9uZyBwYWNrYWdlIGZvdW5kLiIsICJmMS5hIiwgZHluYW1pY1dpcmUuZ2V0Q2FwYWJpbGl0eSgpLmdldEF0dHJpYnV0ZXMoKS5nZXQoUGFja2FnZU5hbWVzcGFjZS5QQUNLQUdFX05BTUVTUEFDRSkpOwoJCUFzc2VydC5hc3NlcnRFcXVhbHMoIldyb25nIHByb3ZpZGVyIGZvciB0aGUgd2lyZSBmb3VuZC4iLCBoMS5nZXRDdXJyZW50UmV2aXNpb24oKSwgZHluYW1pY1dpcmUuZ2V0UHJvdmlkZXIoKSk7CgoJCU1vZHVsZVdpcmluZyBoMVdpcmluZyA9IGgxLmdldEN1cnJlbnRSZXZpc2lvbigpLmdldFdpcmluZygpOwoJCUFzc2VydC5hc3NlcnROb3ROdWxsKCJoMSB3aXJpbmcgaXMgbnVsbC4iLCBoMVdpcmluZyk7CgoJCU1vZHVsZVdpcmluZyBmMVdpcmluZyA9IGYxLmdldEN1cnJlbnRSZXZpc2lvbigpLmdldFdpcmluZygpOwoJCUFzc2VydC5hc3NlcnROb3ROdWxsKCJmMSB3aXJpbmcgaXMgbnVsbC4iLCBmMVdpcmluZyk7Cgl9CgoJQFRlc3QKCXB1YmxpYyB2b2lkIHRlc3REeW5hbWljSW1wb3J0MDUoKSB0aHJvd3MgQnVuZGxlRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CgkJRHVtbXlDb250YWluZXJBZGFwdG9yIGFkYXB0b3IgPSBjcmVhdGVEdW1teUFkYXB0b3IoKTsKCQlNb2R1bGVDb250YWluZXIgY29udGFpbmVyID0gYWRhcHRvci5nZXRDb250YWluZXIoKTsKCgkJTW9kdWxlIHN5c3RlbUJ1bmRsZSA9IGluc3RhbGxEdW1teU1vZHVsZSgic3lzdGVtLmJ1bmRsZS5NRiIsIENvbnN0YW50cy5TWVNURU1fQlVORExFX0xPQ0FUSU9OLCBudWxsLCBudWxsLCAib3NnaS5lZTsgb3NnaS5lZT1KYXZhU0U7IHZlcnNpb246VmVyc2lvbj1cIjEuNS4wXCIiLCBjb250YWluZXIpOwoKCQljb250YWluZXIucmVzb2x2ZShBcnJheXMuYXNMaXN0KHN5c3RlbUJ1bmRsZSksIHRydWUpOwoKCQlNb2R1bGUgYzEgPSBpbnN0YWxsRHVtbXlNb2R1bGUoImMxX3YxLk1GIiwgImMxX3YxIiwgY29udGFpbmVyKTsKCQlNb2R1bGUgYzQgPSBpbnN0YWxsRHVtbXlNb2R1bGUoImM0X3YxLk1GIiwgImM0X3YxIiwgY29udGFpbmVyKTsKCQlNb2R1bGUgZHluYW1pYzMgPSBpbnN0YWxsRHVtbXlNb2R1bGUoImR5bmFtaWMzX3YxLk1GIiwgImR5bmFtaWMzX3YxIiwgY29udGFpbmVyKTsKCQlNb2R1bGUgZHluYW1pYzNGcmFnID0gaW5zdGFsbER1bW15TW9kdWxlKCJkeW5hbWljMy5mcmFnX3YxLk1GIiwgImR5bmFtaWMzLmZyYWdfdjEiLCBjb250YWluZXIpOwoKCQljb250YWluZXIucmVzb2x2ZShBcnJheXMuYXNMaXN0KGMxLCBjNCwgZHluYW1pYzMsIGR5bmFtaWMzRnJhZyksIHRydWUpOwoKCQlNb2R1bGVXaXJlIGR5bmFtaWNXaXJlID0gY29udGFpbmVyLnJlc29sdmVEeW5hbWljKCJjNC5hIiwgZHluYW1pYzMuZ2V0Q3VycmVudFJldmlzaW9uKCkpOwoJCUFzc2VydC5hc3NlcnROb3ROdWxsKCJObyBkeW5hbWljIHdpcmUgZm91bmQuIiwgZHluYW1pY1dpcmUpOwoJCUFzc2VydC5hc3NlcnRFcXVhbHMoIldyb25nIHBhY2thZ2UgZm91bmQuIiwgImM0LmEiLCBkeW5hbWljV2lyZS5nZXRDYXBhYmlsaXR5KCkuZ2V0QXR0cmlidXRlcygpLmdldChQYWNrYWdlTmFtZXNwYWNlLlBBQ0tBR0VfTkFNRVNQQUNFKSk7CgkJQXNzZXJ0LmFzc2VydEVxdWFscygiV3JvbmcgcHJvdmlkZXIgZm9yIHRoZSB3aXJlIGZvdW5kLiIsIGM0LmdldEN1cnJlbnRSZXZpc2lvbigpLCBkeW5hbWljV2lyZS5nZXRQcm92aWRlcigpKTsKCgkJZHluYW1pY1dpcmUgPSBjb250YWluZXIucmVzb2x2ZUR5bmFtaWMoImM0LmIiLCBkeW5hbWljMy5nZXRDdXJyZW50UmV2aXNpb24oKSk7CgkJQXNzZXJ0LmFzc2VydE5vdE51bGwoIk5vIGR5bmFtaWMgd2lyZSBmb3VuZC4iLCBkeW5hbWljV2lyZSk7CgkJQXNzZXJ0LmFzc2VydEVxdWFscygiV3JvbmcgcGFja2FnZSBmb3VuZC4iLCAiYzQuYiIsIGR5bmFtaWNXaXJlLmdldENhcGFiaWxpdHkoKS5nZXRBdHRyaWJ1dGVzKCkuZ2V0KFBhY2thZ2VOYW1lc3BhY2UuUEFDS0FHRV9OQU1FU1BBQ0UpKTsKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJXcm9uZyBwcm92aWRlciBmb3IgdGhlIHdpcmUgZm91bmQuIiwgYzQuZ2V0Q3VycmVudFJldmlzaW9uKCksIGR5bmFtaWNXaXJlLmdldFByb3ZpZGVyKCkpOwoJfQoKCUBUZXN0CglwdWJsaWMgdm9pZCB0ZXN0RHluYW1pY0ltcG9ydDA2KCkgdGhyb3dzIEJ1bmRsZUV4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewoJCUR1bW15Q29udGFpbmVyQWRhcHRvciBhZGFwdG9yID0gY3JlYXRlRHVtbXlBZGFwdG9yKCk7CgkJTW9kdWxlQ29udGFpbmVyIGNvbnRhaW5lciA9IGFkYXB0b3IuZ2V0Q29udGFpbmVyKCk7CgkJTW9kdWxlIHN5c3RlbUJ1bmRsZSA9IGluc3RhbGxEdW1teU1vZHVsZSgic3lzdGVtLmJ1bmRsZS5NRiIsIENvbnN0YW50cy5TWVNURU1fQlVORExFX0xPQ0FUSU9OLCBjb250YWluZXIpOwoKCQljb250YWluZXIucmVzb2x2ZShBcnJheXMuYXNMaXN0KHN5c3RlbUJ1bmRsZSksIHRydWUpOwoKCQlNb2R1bGUgZHluYW1pYzMgPSBpbnN0YWxsRHVtbXlNb2R1bGUoImR5bmFtaWMyX3YxLk1GIiwgImR5bmFtaWMyX3YxIiwgY29udGFpbmVyKTsKCgkJY29udGFpbmVyLnJlc29sdmUoQXJyYXlzLmFzTGlzdChzeXN0ZW1CdW5kbGUsIGR5bmFtaWMzKSwgdHJ1ZSk7CgoJCU1vZHVsZSBmMSA9IGluc3RhbGxEdW1teU1vZHVsZSgiZjFfdjEuTUYiLCAiZjFfdjEiLCBjb250YWluZXIpOwoKCQlNb2R1bGVXaXJlIGR5bmFtaWNXaXJlOwoJCWR5bmFtaWNXaXJlID0gY29udGFpbmVyLnJlc29sdmVEeW5hbWljKCJoMS5hIiwgZHluYW1pYzMuZ2V0Q3VycmVudFJldmlzaW9uKCkpOwoJCUFzc2VydC5hc3NlcnROdWxsKCJEeW5hbWljIHdpcmUgZm91bmQuIiwgZHluYW1pY1dpcmUpOwoJCWR5bmFtaWNXaXJlID0gY29udGFpbmVyLnJlc29sdmVEeW5hbWljKCJmMS5hIiwgZHluYW1pYzMuZ2V0Q3VycmVudFJldmlzaW9uKCkpOwoJCUFzc2VydC5hc3NlcnROdWxsKCJEeW5hbWljIHdpcmUgZm91bmQuIiwgZHluYW1pY1dpcmUpOwoKCQlNb2R1bGUgaDEgPSBpbnN0YWxsRHVtbXlNb2R1bGUoImgxX3YxLk1GIiwgImgxX3YxIiwgY29udGFpbmVyKTsKCgkJZHluYW1pY1dpcmUgPSBjb250YWluZXIucmVzb2x2ZUR5bmFtaWMoImgxLmEiLCBkeW5hbWljMy5nZXRDdXJyZW50UmV2aXNpb24oKSk7CgkJQXNzZXJ0LmFzc2VydE5vdE51bGwoIkR5bmFtaWMgd2lyZSBub3QgZm91bmQuIiwgZHluYW1pY1dpcmUpOwoJCUFzc2VydC5hc3NlcnRFcXVhbHMoIldyb25nIHBhY2thZ2UgZm91bmQuIiwgImgxLmEiLCBkeW5hbWljV2lyZS5nZXRDYXBhYmlsaXR5KCkuZ2V0QXR0cmlidXRlcygpLmdldChQYWNrYWdlTmFtZXNwYWNlLlBBQ0tBR0VfTkFNRVNQQUNFKSk7CgkJQXNzZXJ0LmFzc2VydEVxdWFscygiV3JvbmcgaG9zdCByZXZpc2lvbiBmb3VuZC4iLCBoMS5nZXRDdXJyZW50UmV2aXNpb24oKSwgZHluYW1pY1dpcmUuZ2V0UHJvdmlkZXIoKSk7CgoJCWR5bmFtaWNXaXJlID0gY29udGFpbmVyLnJlc29sdmVEeW5hbWljKCJmMS5hIiwgZHluYW1pYzMuZ2V0Q3VycmVudFJldmlzaW9uKCkpOwoJCUFzc2VydC5hc3NlcnROb3ROdWxsKCJEeW5hbWljIHdpcmUgbm90IGZvdW5kLiIsIGR5bmFtaWNXaXJlKTsKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJXcm9uZyBwYWNrYWdlIGZvdW5kLiIsICJmMS5hIiwgZHluYW1pY1dpcmUuZ2V0Q2FwYWJpbGl0eSgpLmdldEF0dHJpYnV0ZXMoKS5nZXQoUGFja2FnZU5hbWVzcGFjZS5QQUNLQUdFX05BTUVTUEFDRSkpOwoJCUFzc2VydC5hc3NlcnRFcXVhbHMoIldyb25nIGhvc3QgcmV2aXNpb24gZm91bmQuIiwgaDEuZ2V0Q3VycmVudFJldmlzaW9uKCksIGR5bmFtaWNXaXJlLmdldFByb3ZpZGVyKCkpOwoKCQlNb2R1bGVXaXJpbmcgaDFXaXJpbmcgPSBoMS5nZXRDdXJyZW50UmV2aXNpb24oKS5nZXRXaXJpbmcoKTsKCQlBc3NlcnQuYXNzZXJ0Tm90TnVsbCgiaDEgd2lyaW5nIGlzIG51bGwuIiwgaDFXaXJpbmcpOwoKCQlNb2R1bGVXaXJpbmcgZjFXaXJpbmcgPSBmMS5nZXRDdXJyZW50UmV2aXNpb24oKS5nZXRXaXJpbmcoKTsKCQlBc3NlcnQuYXNzZXJ0Tm90TnVsbCgiZjEgd2lyaW5nIGlzIG51bGwuIiwgZjFXaXJpbmcpOwoJfQoKCUBUZXN0CglwdWJsaWMgdm9pZCB0ZXN0RHluYW1pY0ltcG9ydDA3KCkgdGhyb3dzIEJ1bmRsZUV4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewoJCUR1bW15Q29udGFpbmVyQWRhcHRvciBhZGFwdG9yID0gY3JlYXRlRHVtbXlBZGFwdG9yKCk7CgkJTW9kdWxlQ29udGFpbmVyIGNvbnRhaW5lciA9IGFkYXB0b3IuZ2V0Q29udGFpbmVyKCk7CgkJTW9kdWxlIHN5c3RlbUJ1bmRsZSA9IGluc3RhbGxEdW1teU1vZHVsZSgic3lzdGVtLmJ1bmRsZS5NRiIsIENvbnN0YW50cy5TWVNURU1fQlVORExFX0xPQ0FUSU9OLCBjb250YWluZXIpOwoKCQljb250YWluZXIucmVzb2x2ZShBcnJheXMuYXNMaXN0KHN5c3RlbUJ1bmRsZSksIHRydWUpOwoKCQlNb2R1bGUgZHluYW1pYzMgPSBpbnN0YWxsRHVtbXlNb2R1bGUoImR5bmFtaWMyX3YxLk1GIiwgImR5bmFtaWMyX3YxIiwgY29udGFpbmVyKTsKCgkJQXNzZXJ0LmFzc2VydE51bGwoIkV4cGVjdGVkIG5vIHJlc29sdXRpb24gZXhjZXB0aW9uLiIsIGNvbnRhaW5lci5yZXNvbHZlKEFycmF5cy5hc0xpc3Qoc3lzdGVtQnVuZGxlLCBkeW5hbWljMyksIHRydWUpLmdldFJlc29sdXRpb25FeGNlcHRpb24oKSk7CgoJCWluc3RhbGxEdW1teU1vZHVsZSgiYzZfdjEuTUYiLCAiYzZfdjEiLCBjb250YWluZXIpOwoKCQlNb2R1bGVXaXJlIGR5bmFtaWNXaXJlID0gY29udGFpbmVyLnJlc29sdmVEeW5hbWljKCJjNiIsIGR5bmFtaWMzLmdldEN1cnJlbnRSZXZpc2lvbigpKTsKCQlBc3NlcnQuYXNzZXJ0TnVsbCgiRHluYW1pYyB3aXJlIGZvdW5kLiIsIGR5bmFtaWNXaXJlKTsKCX0KCglAVGVzdAoJcHVibGljIHZvaWQgdGVzdER5bmFtaWNJbXBvcnQwOCgpIHRocm93cyBCdW5kbGVFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKCQlEdW1teUNvbnRhaW5lckFkYXB0b3IgYWRhcHRvciA9IGNyZWF0ZUR1bW15QWRhcHRvcigpOwoJCU1vZHVsZUNvbnRhaW5lciBjb250YWluZXIgPSBhZGFwdG9yLmdldENvbnRhaW5lcigpOwoJCUR1bW15TW9kdWxlRGF0YWJhc2UgZGF0YWJhc2UgPSBhZGFwdG9yLmdldERhdGFiYXNlKCk7CgkJTW9kdWxlIHN5c3RlbUJ1bmRsZSA9IGluc3RhbGxEdW1teU1vZHVsZSgic3lzdGVtLmJ1bmRsZS5NRiIsIENvbnN0YW50cy5TWVNURU1fQlVORExFX0xPQ0FUSU9OLCBjb250YWluZXIpOwoKCQljb250YWluZXIucmVzb2x2ZShBcnJheXMuYXNMaXN0KHN5c3RlbUJ1bmRsZSksIHRydWUpOwoKCQlNb2R1bGUgZHluYW1pYzIgPSBpbnN0YWxsRHVtbXlNb2R1bGUoImR5bmFtaWMyX3YxLk1GIiwgImR5bmFtaWMyX3YxIiwgY29udGFpbmVyKTsKCgkJY29udGFpbmVyLnJlc29sdmUoQXJyYXlzLmFzTGlzdChzeXN0ZW1CdW5kbGUsIGR5bmFtaWMyKSwgdHJ1ZSk7CgoJCU1vZHVsZSBoMSA9IGluc3RhbGxEdW1teU1vZHVsZSgiaDFfdjEuTUYiLCAiaDFfdjEiLCBjb250YWluZXIpOwoJCU1vZHVsZSBmMSA9IGluc3RhbGxEdW1teU1vZHVsZSgiZjFfdjEuTUYiLCAiZjFfdjEiLCBjb250YWluZXIpOwoJCWRhdGFiYXNlLmdldE1vZHVsZUV2ZW50cygpOwoJCS8vIG1ha2Ugc3VyZSBoMSBpcyBub3QgcmVzb2x2ZWQKCQlNb2R1bGVXaXJpbmcgaDFXaXJpbmcgPSBoMS5nZXRDdXJyZW50UmV2aXNpb24oKS5nZXRXaXJpbmcoKTsKCQlBc3NlcnQuYXNzZXJ0TnVsbCgiaDEgZ290IHJlc29sdmVkIHNvbWVob3cuIiwgaDFXaXJpbmcpOwoJCS8vIGRvIG5vdCByZXNvbHZlIHRoZSBob3N0IGZpcnN0OyBtYWtlIHN1cmUgaXQgZ2V0cyBwdWxsZWQgaW4gd2hpbGUgYXR0ZW1wdGluZyB0byByZXNvbHZlIAoJCS8vIHRvIGEgZnJhZ21lbnQgY2FwYWJpbGl0eS4KCQlNb2R1bGVXaXJlIGR5bmFtaWNXaXJlID0gY29udGFpbmVyLnJlc29sdmVEeW5hbWljKCJmMS5hIiwgZHluYW1pYzIuZ2V0Q3VycmVudFJldmlzaW9uKCkpOwoJCUFzc2VydC5hc3NlcnROb3ROdWxsKCJEeW5hbWljIHdpcmUgbm90IGZvdW5kLiIsIGR5bmFtaWNXaXJlKTsKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJXcm9uZyBwYWNrYWdlIGZvdW5kLiIsICJmMS5hIiwgZHluYW1pY1dpcmUuZ2V0Q2FwYWJpbGl0eSgpLmdldEF0dHJpYnV0ZXMoKS5nZXQoUGFja2FnZU5hbWVzcGFjZS5QQUNLQUdFX05BTUVTUEFDRSkpOwoJCUFzc2VydC5hc3NlcnRFcXVhbHMoIldyb25nIHByb3ZpZGVyIGZvciB0aGUgd2lyZSBmb3VuZC4iLCBoMS5nZXRDdXJyZW50UmV2aXNpb24oKSwgZHluYW1pY1dpcmUuZ2V0UHJvdmlkZXIoKSk7CgoJCWgxV2lyaW5nID0gaDEuZ2V0Q3VycmVudFJldmlzaW9uKCkuZ2V0V2lyaW5nKCk7CgkJQXNzZXJ0LmFzc2VydE5vdE51bGwoImgxIHdpcmluZyBpcyBudWxsLiIsIGgxV2lyaW5nKTsKCgkJTW9kdWxlV2lyaW5nIGYxV2lyaW5nID0gZjEuZ2V0Q3VycmVudFJldmlzaW9uKCkuZ2V0V2lyaW5nKCk7CgkJQXNzZXJ0LmFzc2VydE5vdE51bGwoImYxIHdpcmluZyBpcyBudWxsLiIsIGYxV2lyaW5nKTsKCX0KCglAVGVzdAoJcHVibGljIHZvaWQgdGVzdER5bmFtaWNJbXBvcnRNaXNzMDEoKSB0aHJvd3MgQnVuZGxlRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CgkJRHVtbXlDb250YWluZXJBZGFwdG9yIGFkYXB0b3IgPSBjcmVhdGVEdW1teUFkYXB0b3IoKTsKCQlNb2R1bGVDb250YWluZXIgY29udGFpbmVyID0gYWRhcHRvci5nZXRDb250YWluZXIoKTsKCgkJTW9kdWxlIHN5c3RlbUJ1bmRsZSA9IGluc3RhbGxEdW1teU1vZHVsZSgic3lzdGVtLmJ1bmRsZS5NRiIsIENvbnN0YW50cy5TWVNURU1fQlVORExFX0xPQ0FUSU9OLCBudWxsLCBudWxsLCAib3NnaS5lZTsgb3NnaS5lZT1KYXZhU0U7IHZlcnNpb246VmVyc2lvbj1cIjEuNS4wXCIiLCBjb250YWluZXIpOwoKCQljb250YWluZXIucmVzb2x2ZShBcnJheXMuYXNMaXN0KHN5c3RlbUJ1bmRsZSksIHRydWUpOwoJCU1vZHVsZSBjMSA9IGluc3RhbGxEdW1teU1vZHVsZSgiYzFfdjEuTUYiLCAiYzFfdjEiLCBjb250YWluZXIpOwoJCU1vZHVsZSBkeW5hbWljMSA9IGluc3RhbGxEdW1teU1vZHVsZSgiZHluYW1pYzFfdjEuTUYiLCAiZHluYW1pYzFfdjEiLCBjb250YWluZXIpOwoKCQljb250YWluZXIucmVzb2x2ZShBcnJheXMuYXNMaXN0KGMxLCBkeW5hbWljMSksIHRydWUpOwoKCQlEdW1teVJlc29sdmVySG9va0ZhY3RvcnkgZmFjdG9yeSA9IChEdW1teVJlc29sdmVySG9va0ZhY3RvcnkpIGFkYXB0b3IuZ2V0UmVzb2x2ZXJIb29rRmFjdG9yeSgpOwoJCUR1bW15UmVzb2x2ZXJIb29rIGhvb2sgPSAoRHVtbXlSZXNvbHZlckhvb2spIGZhY3RvcnkuZ2V0SG9vaygpOwoJCWhvb2suZ2V0UmVzb2x1dGlvblJlcG9ydHMoKS5jbGVhcigpOwoJCU1vZHVsZVdpcmUgZHluYW1pY1dpcmUgPSBjb250YWluZXIucmVzb2x2ZUR5bmFtaWMoIm9yZy5vc2dpLmZyYW1ld29yayIsIGR5bmFtaWMxLmdldEN1cnJlbnRSZXZpc2lvbigpKTsKCQlBc3NlcnQuYXNzZXJ0Tm90TnVsbCgiTm8gZHluYW1pYyB3aXJlIGZvdW5kLiIsIGR5bmFtaWNXaXJlKTsKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJXcm9uZyBwYWNrYWdlIGZvdW5kLiIsICJvcmcub3NnaS5mcmFtZXdvcmsiLCBkeW5hbWljV2lyZS5nZXRDYXBhYmlsaXR5KCkuZ2V0QXR0cmlidXRlcygpLmdldChQYWNrYWdlTmFtZXNwYWNlLlBBQ0tBR0VfTkFNRVNQQUNFKSk7CgkJQXNzZXJ0LmFzc2VydEVxdWFscygiV3JvbmcgcHJvdmlkZXIgZm9yIHRoZSB3aXJlIGZvdW5kLiIsIHN5c3RlbUJ1bmRsZS5nZXRDdXJyZW50UmV2aXNpb24oKSwgZHluYW1pY1dpcmUuZ2V0UHJvdmlkZXIoKSk7CgoJCUFzc2VydC5hc3NlcnRFcXVhbHMoIldyb25nIG51bWJlciBvZiByZXBvcnRzLiIsIDEsIGhvb2suZ2V0UmVzb2x1dGlvblJlcG9ydHMoKS5zaXplKCkpOwoJCWhvb2suZ2V0UmVzb2x1dGlvblJlcG9ydHMoKS5jbGVhcigpOwoKCQlkeW5hbWljV2lyZSA9IGNvbnRhaW5lci5yZXNvbHZlRHluYW1pYygiZG9lcy5ub3QuZXhpc3QiLCBkeW5hbWljMS5nZXRDdXJyZW50UmV2aXNpb24oKSk7CgkJQXNzZXJ0LmFzc2VydE51bGwoIlVuZXhwZWN0ZWQgRHluYW1pYyB3aXJlIGZvdW5kLiIsIGR5bmFtaWNXaXJlKTsKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJXcm9uZyBudW1iZXIgb2YgcmVwb3J0cy4iLCAxLCBob29rLmdldFJlc29sdXRpb25SZXBvcnRzKCkuc2l6ZSgpKTsKCgkJLy8gVHJ5IGFnYWluOyBubyByZXBvcnQgc2hvdWxkIGJlIGdlbmVyYXRlZCBhIHNlY29uZCB0aW1lCgkJaG9vay5nZXRSZXNvbHV0aW9uUmVwb3J0cygpLmNsZWFyKCk7CgkJZHluYW1pY1dpcmUgPSBjb250YWluZXIucmVzb2x2ZUR5bmFtaWMoImRvZXMubm90LmV4aXN0IiwgZHluYW1pYzEuZ2V0Q3VycmVudFJldmlzaW9uKCkpOwoJCUFzc2VydC5hc3NlcnROdWxsKCJVbmV4cGVjdGVkIER5bmFtaWMgd2lyZSBmb3VuZC4iLCBkeW5hbWljV2lyZSk7CgkJQXNzZXJ0LmFzc2VydEVxdWFscygiV3JvbmcgbnVtYmVyIG9mIHJlcG9ydHMuIiwgMCwgaG9vay5nZXRSZXNvbHV0aW9uUmVwb3J0cygpLnNpemUoKSk7Cgl9CgoJQFRlc3QKCXB1YmxpYyB2b2lkIHRlc3RSZXF1aXJlQnVuZGxlVXNlcygpIHRocm93cyBCdW5kbGVFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKCQlEdW1teUNvbnRhaW5lckFkYXB0b3IgYWRhcHRvciA9IGNyZWF0ZUR1bW15QWRhcHRvcigpOwoJCU1vZHVsZUNvbnRhaW5lciBjb250YWluZXIgPSBhZGFwdG9yLmdldENvbnRhaW5lcigpOwoKCQlNb2R1bGUgc3lzdGVtQnVuZGxlID0gaW5zdGFsbER1bW15TW9kdWxlKCJzeXN0ZW0uYnVuZGxlLk1GIiwgQ29uc3RhbnRzLlNZU1RFTV9CVU5ETEVfTE9DQVRJT04sIGNvbnRhaW5lcik7CgoJCWNvbnRhaW5lci5yZXNvbHZlKEFycmF5cy5hc0xpc3Qoc3lzdGVtQnVuZGxlKSwgdHJ1ZSk7CgkJTW9kdWxlIGIxID0gaW5zdGFsbER1bW15TW9kdWxlKCJyZXF1aXJlLmIxLk1GIiwgImIxIiwgY29udGFpbmVyKTsKCQlpbnN0YWxsRHVtbXlNb2R1bGUoInJlcXVpcmUuYjIuTUYiLCAiYjIiLCBjb250YWluZXIpOwoJCWluc3RhbGxEdW1teU1vZHVsZSgicmVxdWlyZS5iMy5NRiIsICJiMyIsIGNvbnRhaW5lcik7CgkJaW5zdGFsbER1bW15TW9kdWxlKCJyZXF1aXJlLmI0Lk1GIiwgImI0IiwgY29udGFpbmVyKTsKCgkJY29udGFpbmVyLnJlc29sdmUobnVsbCwgZmFsc2UpOwoKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJiMSBzaG91bGQgbm90IHJlc29sdmUuIiwgU3RhdGUuSU5TVEFMTEVELCBiMS5nZXRTdGF0ZSgpKTsKCX0KCgkvKgoJICogVGVzdCB0aGF0IGEgcmVzb2x2ZSBwcm9jZXNzIGRvZXMgbm90IGJsb3cgdXAgYmVjYXVzZSBvZiBvbmUgdW5yZXNvbHZhYmxlIHVzZXMgY29uc3RyYWludCBpc3N1ZQoJICovCglAVGVzdAoJcHVibGljIHZvaWQgdGVzdFVzZXMxKCkgdGhyb3dzIEJ1bmRsZUV4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewoJCUR1bW15Q29udGFpbmVyQWRhcHRvciBhZGFwdG9yID0gY3JlYXRlRHVtbXlBZGFwdG9yKCk7CgkJTW9kdWxlQ29udGFpbmVyIGNvbnRhaW5lciA9IGFkYXB0b3IuZ2V0Q29udGFpbmVyKCk7CgoJCU1vZHVsZSBzeXN0ZW1CdW5kbGUgPSBpbnN0YWxsRHVtbXlNb2R1bGUoInN5c3RlbS5idW5kbGUuTUYiLCBDb25zdGFudHMuU1lTVEVNX0JVTkRMRV9MT0NBVElPTiwgY29udGFpbmVyKTsKCgkJY29udGFpbmVyLnJlc29sdmUoQXJyYXlzLmFzTGlzdChzeXN0ZW1CdW5kbGUpLCB0cnVlKTsKCQlNb2R1bGUgdXNlc19hID0gaW5zdGFsbER1bW15TW9kdWxlKCJ1c2VzLmEuTUYiLCAiYSIsIGNvbnRhaW5lcik7CgkJTW9kdWxlIHVzZXNfYiA9IGluc3RhbGxEdW1teU1vZHVsZSgidXNlcy5iLk1GIiwgImIiLCBjb250YWluZXIpOwoJCU1vZHVsZSB1c2VzX2MgPSBpbnN0YWxsRHVtbXlNb2R1bGUoInVzZXMuYy5NRiIsICJjIiwgY29udGFpbmVyKTsKCgkJY29udGFpbmVyLnJlc29sdmUobnVsbCwgZmFsc2UpOwoKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJhIHNob3VsZCByZXNvbHZlLiIsIFN0YXRlLlJFU09MVkVELCB1c2VzX2EuZ2V0U3RhdGUoKSk7CgkJQXNzZXJ0LmFzc2VydEVxdWFscygiYiBzaG91bGQgcmVzb2x2ZS4iLCBTdGF0ZS5SRVNPTFZFRCwgdXNlc19iLmdldFN0YXRlKCkpOwoJCUFzc2VydC5hc3NlcnRFcXVhbHMoImMgc2hvdWxkIG5vdCByZXNvbHZlLiIsIFN0YXRlLklOU1RBTExFRCwgdXNlc19jLmdldFN0YXRlKCkpOwoJfQoKCUBUZXN0CglwdWJsaWMgdm9pZCB0ZXN0VXNlczFEeW5hbWljKCkgdGhyb3dzIEJ1bmRsZUV4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewoJCUR1bW15Q29udGFpbmVyQWRhcHRvciBhZGFwdG9yID0gY3JlYXRlRHVtbXlBZGFwdG9yKG5ldyBEdW1teURlYnVnT3B0aW9ucyhDb2xsZWN0aW9ucy5zaW5nbGV0b25NYXAoIm9yZy5lY2xpcHNlLm9zZ2kvcmVzb2x2ZXIvcmVwb3J0IiwgInRydWUiKSkpOwoJCU1vZHVsZUNvbnRhaW5lciBjb250YWluZXIgPSBhZGFwdG9yLmdldENvbnRhaW5lcigpOwoKCQlNb2R1bGUgc3lzdGVtQnVuZGxlID0gaW5zdGFsbER1bW15TW9kdWxlKCJzeXN0ZW0uYnVuZGxlLk1GIiwgQ29uc3RhbnRzLlNZU1RFTV9CVU5ETEVfTE9DQVRJT04sIGNvbnRhaW5lcik7CgoJCWNvbnRhaW5lci5yZXNvbHZlKEFycmF5cy5hc0xpc3Qoc3lzdGVtQnVuZGxlKSwgdHJ1ZSk7CgkJTW9kdWxlIHVzZXNfYSA9IGluc3RhbGxEdW1teU1vZHVsZSgidXNlcy5hLk1GIiwgImEiLCBjb250YWluZXIpOwoJCU1vZHVsZSB1c2VzX2IgPSBpbnN0YWxsRHVtbXlNb2R1bGUoInVzZXMuYi5NRiIsICJiIiwgY29udGFpbmVyKTsKCQlNb2R1bGUgdXNlc19jX2R5bmFtaWMgPSBpbnN0YWxsRHVtbXlNb2R1bGUoInVzZXMuYy5keW5hbWljLk1GIiwgImMiLCBjb250YWluZXIpOwoKCQljb250YWluZXIucmVzb2x2ZShudWxsLCBmYWxzZSk7CgoJCUFzc2VydC5hc3NlcnRFcXVhbHMoImEgc2hvdWxkIHJlc29sdmUuIiwgU3RhdGUuUkVTT0xWRUQsIHVzZXNfYS5nZXRTdGF0ZSgpKTsKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJiIHNob3VsZCByZXNvbHZlLiIsIFN0YXRlLlJFU09MVkVELCB1c2VzX2IuZ2V0U3RhdGUoKSk7CgkJQXNzZXJ0LmFzc2VydEVxdWFscygiYyBzaG91bGQgcmVzb2x2ZS4iLCBTdGF0ZS5SRVNPTFZFRCwgdXNlc19jX2R5bmFtaWMuZ2V0U3RhdGUoKSk7CgoJCU1vZHVsZVdpcmUgZHluYW1pY1dpcmUgPSBjb250YWluZXIucmVzb2x2ZUR5bmFtaWMoInVzZXMxIiwgdXNlc19jX2R5bmFtaWMuZ2V0Q3VycmVudFJldmlzaW9uKCkpOwoJCUFzc2VydC5hc3NlcnROb3ROdWxsKCJObyBkeW5hbWljIHdpcmUuIiwgZHluYW1pY1dpcmUpOwoKCQlQcmludFN0cmVhbSBvcmlnaW5hbE91dCA9IERlYnVnLm91dDsKCQlCeXRlQXJyYXlPdXRwdXRTdHJlYW0gYnl0ZXNPdXQgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CgkJUHJpbnRTdHJlYW0gdGVzdE91dCA9IG5ldyBQcmludFN0cmVhbShieXRlc091dCk7CgkJRGVidWcub3V0ID0gdGVzdE91dDsKCQl0cnkgewoJCQlkeW5hbWljV2lyZSA9IGNvbnRhaW5lci5yZXNvbHZlRHluYW1pYygidXNlczIiLCB1c2VzX2NfZHluYW1pYy5nZXRDdXJyZW50UmV2aXNpb24oKSk7CgkJCUFzc2VydC5hc3NlcnROdWxsKCJEeW5hbWljIHdpcmUgZm91bmQuIiwgZHluYW1pY1dpcmUpOwoJCX0gZmluYWxseSB7CgkJCURlYnVnLm91dCA9IG9yaWdpbmFsT3V0OwoJCQl0ZXN0T3V0LmNsb3NlKCk7CgkJfQoJCVN0cmluZyB0cmFjZU91dHB1dCA9IGJ5dGVzT3V0LnRvU3RyaW5nKCk7CgkJQXNzZXJ0LmFzc2VydFRydWUoIldyb25nIHRyYWNlT3V0cHV0OiAiICsgdHJhY2VPdXRwdXQsIHRyYWNlT3V0cHV0LnN0YXJ0c1dpdGgoIm9yZy5hcGFjaGUuZmVsaXgucmVzb2x2ZXIucmVhc29uLlJlYXNvbkV4Y2VwdGlvbiIpKTsKCX0KCgkvKgoJICogVGVzdCB0aGF0IHNwbGl0IHBhY2thZ2VzIGFyZSBoYW5kbGVkIG9rIHdpdGggdXNlcyBjb25zdHJhaW50cwoJICovCglAVGVzdAoJcHVibGljIHZvaWQgdGVzdFVzZXMyKCkgdGhyb3dzIEJ1bmRsZUV4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewoJCUR1bW15Q29udGFpbmVyQWRhcHRvciBhZGFwdG9yID0gY3JlYXRlRHVtbXlBZGFwdG9yKCk7CgkJTW9kdWxlQ29udGFpbmVyIGNvbnRhaW5lciA9IGFkYXB0b3IuZ2V0Q29udGFpbmVyKCk7CgoJCU1vZHVsZSBzeXN0ZW1CdW5kbGUgPSBpbnN0YWxsRHVtbXlNb2R1bGUoInN5c3RlbS5idW5kbGUuTUYiLCBDb25zdGFudHMuU1lTVEVNX0JVTkRMRV9MT0NBVElPTiwgY29udGFpbmVyKTsKCgkJY29udGFpbmVyLnJlc29sdmUoQXJyYXlzLmFzTGlzdChzeXN0ZW1CdW5kbGUpLCB0cnVlKTsKCQlNb2R1bGUgdXNlc19hID0gaW5zdGFsbER1bW15TW9kdWxlKCJ1c2VzLmEuTUYiLCAiYSIsIGNvbnRhaW5lcik7CgkJTW9kdWxlIHVzZXNfYiA9IGluc3RhbGxEdW1teU1vZHVsZSgidXNlcy5iLk1GIiwgImIiLCBjb250YWluZXIpOwoJCU1vZHVsZSB1c2VzX2QgPSBpbnN0YWxsRHVtbXlNb2R1bGUoInVzZXMuZC5NRiIsICJkIiwgY29udGFpbmVyKTsKCgkJY29udGFpbmVyLnJlc29sdmUobnVsbCwgZmFsc2UpOwoKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJhIHNob3VsZCByZXNvbHZlLiIsIFN0YXRlLlJFU09MVkVELCB1c2VzX2EuZ2V0U3RhdGUoKSk7CgkJQXNzZXJ0LmFzc2VydEVxdWFscygiYiBzaG91bGQgcmVzb2x2ZS4iLCBTdGF0ZS5SRVNPTFZFRCwgdXNlc19iLmdldFN0YXRlKCkpOwoJCUFzc2VydC5hc3NlcnRFcXVhbHMoImQgc2hvdWxkIHJlc29sdmUuIiwgU3RhdGUuUkVTT0xWRUQsIHVzZXNfZC5nZXRTdGF0ZSgpKTsKCX0KCgkvKgoJICogVGVzdCB0aGF0IHNwbGl0IHBhY2thZ2VzIGFyZSBoYW5kbGVkIG9rIHdpdGggdXNlcyBjb25zdHJhaW50cwoJICovCglAVGVzdAoJcHVibGljIHZvaWQgdGVzdFVzZXMzKCkgdGhyb3dzIEJ1bmRsZUV4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewoJCUR1bW15Q29udGFpbmVyQWRhcHRvciBhZGFwdG9yID0gY3JlYXRlRHVtbXlBZGFwdG9yKCk7CgkJTW9kdWxlQ29udGFpbmVyIGNvbnRhaW5lciA9IGFkYXB0b3IuZ2V0Q29udGFpbmVyKCk7CgoJCU1vZHVsZSBzeXN0ZW1CdW5kbGUgPSBpbnN0YWxsRHVtbXlNb2R1bGUoInN5c3RlbS5idW5kbGUuTUYiLCBDb25zdGFudHMuU1lTVEVNX0JVTkRMRV9MT0NBVElPTiwgY29udGFpbmVyKTsKCgkJY29udGFpbmVyLnJlc29sdmUoQXJyYXlzLmFzTGlzdChzeXN0ZW1CdW5kbGUpLCB0cnVlKTsKCQlNb2R1bGUgdXNlc19hID0gaW5zdGFsbER1bW15TW9kdWxlKCJ1c2VzLmEuTUYiLCAiYSIsIGNvbnRhaW5lcik7CgkJTW9kdWxlIHVzZXNfYiA9IGluc3RhbGxEdW1teU1vZHVsZSgidXNlcy5iLk1GIiwgImIiLCBjb250YWluZXIpOwoJCU1vZHVsZSB1c2VzX2UgPSBpbnN0YWxsRHVtbXlNb2R1bGUoInVzZXMuZS5NRiIsICJlIiwgY29udGFpbmVyKTsKCQlNb2R1bGUgdXNlc19mID0gaW5zdGFsbER1bW15TW9kdWxlKCJ1c2VzLmYuTUYiLCAiZiIsIGNvbnRhaW5lcik7CgkJTW9kdWxlIHVzZXNfZyA9IGluc3RhbGxEdW1teU1vZHVsZSgidXNlcy5nLk1GIiwgImciLCBjb250YWluZXIpOwoKCQljb250YWluZXIucmVzb2x2ZShudWxsLCBmYWxzZSk7CgoJCUFzc2VydC5hc3NlcnRFcXVhbHMoImEgc2hvdWxkIHJlc29sdmUuIiwgU3RhdGUuUkVTT0xWRUQsIHVzZXNfYS5nZXRTdGF0ZSgpKTsKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJiIHNob3VsZCByZXNvbHZlLiIsIFN0YXRlLlJFU09MVkVELCB1c2VzX2IuZ2V0U3RhdGUoKSk7CgkJQXNzZXJ0LmFzc2VydEVxdWFscygiZSBzaG91bGQgcmVzb2x2ZS4iLCBTdGF0ZS5SRVNPTFZFRCwgdXNlc19lLmdldFN0YXRlKCkpOwoJCUFzc2VydC5hc3NlcnRFcXVhbHMoImYgc2hvdWxkIHJlc29sdmUuIiwgU3RhdGUuUkVTT0xWRUQsIHVzZXNfZi5nZXRTdGF0ZSgpKTsKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJnIHNob3VsZCBub3QgcmVzb2x2ZS4iLCBTdGF0ZS5JTlNUQUxMRUQsIHVzZXNfZy5nZXRTdGF0ZSgpKTsKCX0KCgkvKgoJICogVGVzdCB0aGF0IGZyYWdtZW50cyBhbmQgdXNlcyBjb25zdHJhaW50cwoJICovCglAVGVzdAoJcHVibGljIHZvaWQgdGVzdFVzZXM0KCkgdGhyb3dzIEJ1bmRsZUV4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewoJCUR1bW15Q29udGFpbmVyQWRhcHRvciBhZGFwdG9yID0gY3JlYXRlRHVtbXlBZGFwdG9yKCk7CgkJTW9kdWxlQ29udGFpbmVyIGNvbnRhaW5lciA9IGFkYXB0b3IuZ2V0Q29udGFpbmVyKCk7CgoJCU1vZHVsZSBzeXN0ZW1CdW5kbGUgPSBpbnN0YWxsRHVtbXlNb2R1bGUoInN5c3RlbS5idW5kbGUuTUYiLCBDb25zdGFudHMuU1lTVEVNX0JVTkRMRV9MT0NBVElPTiwgY29udGFpbmVyKTsKCgkJY29udGFpbmVyLnJlc29sdmUoQXJyYXlzLmFzTGlzdChzeXN0ZW1CdW5kbGUpLCB0cnVlKTsKCQlNb2R1bGUgdXNlc19oID0gaW5zdGFsbER1bW15TW9kdWxlKCJ1c2VzLmguTUYiLCAiaCIsIGNvbnRhaW5lcik7CgkJTW9kdWxlIHVzZXNfaF9mcmFnID0gaW5zdGFsbER1bW15TW9kdWxlKCJ1c2VzLmguZnJhZy5NRiIsICJoLmZyYWciLCBjb250YWluZXIpOwoKCQljb250YWluZXIucmVzb2x2ZShudWxsLCBmYWxzZSk7CgoJCUFzc2VydC5hc3NlcnRFcXVhbHMoImggc2hvdWxkIHJlc29sdmUuIiwgU3RhdGUuUkVTT0xWRUQsIHVzZXNfaC5nZXRTdGF0ZSgpKTsKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJoLmZyYWcgc2hvdWxkIHJlc29sdmUuIiwgU3RhdGUuUkVTT0xWRUQsIHVzZXNfaF9mcmFnLmdldFN0YXRlKCkpOwoKCQlNb2R1bGUgdXNlc19pID0gaW5zdGFsbER1bW15TW9kdWxlKCJ1c2VzLmkuTUYiLCAiaSIsIGNvbnRhaW5lcik7CgkJTW9kdWxlIHVzZXNfaiA9IGluc3RhbGxEdW1teU1vZHVsZSgidXNlcy5qLk1GIiwgImoiLCBjb250YWluZXIpOwoKCQljb250YWluZXIucmVzb2x2ZShudWxsLCBmYWxzZSk7CgoJCUFzc2VydC5hc3NlcnRFcXVhbHMoImkgc2hvdWxkIHJlc29sdmUuIiwgU3RhdGUuUkVTT0xWRUQsIHVzZXNfaS5nZXRTdGF0ZSgpKTsKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJqIHNob3VsZCByZXNvbHZlLiIsIFN0YXRlLlJFU09MVkVELCB1c2VzX2ouZ2V0U3RhdGUoKSk7CgoJCUxpc3Q8QnVuZGxlV2lyZT4gcmVxdWlyZWRXaXJlcyA9IHVzZXNfai5nZXRDdXJyZW50UmV2aXNpb24oKS5nZXRXaXJpbmcoKS5nZXRSZXF1aXJlZFdpcmVzKG51bGwpOwoJCUFzc2VydC5hc3NlcnRFcXVhbHMoIldyb25nIG51bWJlciBvZiB3aXJlcyBmb3IgaiIsIDIsIHJlcXVpcmVkV2lyZXMuc2l6ZSgpKTsKCQlmb3IgKEJ1bmRsZVdpcmUgd2lyZSA6IHJlcXVpcmVkV2lyZXMpIHsKCQkJQXNzZXJ0LmFzc2VydEVxdWFscygiV3JvbmcgcHJvdmlkZXIiLCB1c2VzX2kuZ2V0Q3VycmVudFJldmlzaW9uKCksIHdpcmUuZ2V0UHJvdmlkZXIoKSk7CgkJfQoKCQlNb2R1bGUgdXNlc19qX2R5bmFtaWMgPSBpbnN0YWxsRHVtbXlNb2R1bGUoInVzZXMuai5keW5hbWljLk1GIiwgImouZHluYW1pYyIsIGNvbnRhaW5lcik7CgkJY29udGFpbmVyLnJlc29sdmUobnVsbCwgZmFsc2UpOwoJCU1vZHVsZVdpcmUgZHluYW1pY1dpcmUgPSBjb250YWluZXIucmVzb2x2ZUR5bmFtaWMoInVzZXMyIiwgdXNlc19qX2R5bmFtaWMuZ2V0Q3VycmVudFJldmlzaW9uKCkpOwoJCUFzc2VydC5hc3NlcnROb3ROdWxsKCJOdWxsIGR5bmFtaWMgd2lyZS4iLCBkeW5hbWljV2lyZSk7CgkJQXNzZXJ0LmFzc2VydEVxdWFscygiV3JvbmcgcHJvdmlkZXIiLCB1c2VzX2kuZ2V0Q3VycmVudFJldmlzaW9uKCksIGR5bmFtaWNXaXJlLmdldFByb3ZpZGVyKCkpOwoJfQoKCS8qKgoJICogVGVzdCBvcHRpb25hbCBjb25zdHJhaW50cwoJICogQHRocm93cyBCdW5kbGVFeGNlcHRpb24KCSAqIEB0aHJvd3MgSU9FeGNlcHRpb24KCSAqLwoJQFRlc3QKCXB1YmxpYyB2b2lkIHRlc3RVc2VzNUltcG9ydGVyKCkgdGhyb3dzIEJ1bmRsZUV4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewoJCWRvVGVzdFVzZXM1KCJ1c2VzLmsuaW1wb3J0ZXIuTUYiKTsKCX0KCglAVGVzdAoJcHVibGljIHZvaWQgdGVzdFVzZXM1UmVxQ2FwKCkgdGhyb3dzIEJ1bmRsZUV4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewoJCWRvVGVzdFVzZXM1KCJ1c2VzLmsucmVxQ2FwLk1GIik7Cgl9CgoJQFRlc3QKCXB1YmxpYyB2b2lkIHRlc3RVc2VzNVJlcXVpcmVyKCkgdGhyb3dzIEJ1bmRsZUV4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewoJCWRvVGVzdFVzZXM1KCJ1c2VzLmsucmVxdWlyZXIuTUYiKTsKCX0KCglwdWJsaWMgdm9pZCBkb1Rlc3RVc2VzNShTdHJpbmcga01hbmlmZXN0KSB0aHJvd3MgQnVuZGxlRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CgkJRHVtbXlDb250YWluZXJBZGFwdG9yIGFkYXB0b3IgPSBjcmVhdGVEdW1teUFkYXB0b3IoKTsKCQlNb2R1bGVDb250YWluZXIgY29udGFpbmVyID0gYWRhcHRvci5nZXRDb250YWluZXIoKTsKCgkJTW9kdWxlIHN5c3RlbUJ1bmRsZSA9IGluc3RhbGxEdW1teU1vZHVsZSgic3lzdGVtLmJ1bmRsZS5NRiIsIENvbnN0YW50cy5TWVNURU1fQlVORExFX0xPQ0FUSU9OLCBjb250YWluZXIpOwoKCQljb250YWluZXIucmVzb2x2ZShBcnJheXMuYXNMaXN0KHN5c3RlbUJ1bmRsZSksIHRydWUpOwoJCU1vZHVsZSB1c2VzX2sgPSBpbnN0YWxsRHVtbXlNb2R1bGUoa01hbmlmZXN0LCAiayIsIGNvbnRhaW5lcik7CgkJTW9kdWxlIHVzZXNfbCA9IGluc3RhbGxEdW1teU1vZHVsZSgidXNlcy5sLk1GIiwgImwiLCBjb250YWluZXIpOwoJCU1vZHVsZSB1c2VzX21fY29uZmxpY3QxID0gaW5zdGFsbER1bW15TW9kdWxlKCJ1c2VzLm0uY29uZmxpY3QxLk1GIiwgIm0uY29uZmxpY3QxIiwgY29udGFpbmVyKTsKCQlNb2R1bGUgdXNlc19tX2NvbmZsaWN0MiA9IGluc3RhbGxEdW1teU1vZHVsZSgidXNlcy5tLmNvbmZsaWN0Mi5NRiIsICJtLmNvbmZsaWN0MiIsIGNvbnRhaW5lcik7CgoJCWNvbnRhaW5lci5yZXNvbHZlKG51bGwsIGZhbHNlKTsKCgkJQXNzZXJ0LmFzc2VydEVxdWFscygiayBzaG91bGQgcmVzb2x2ZS4iLCBTdGF0ZS5SRVNPTFZFRCwgdXNlc19rLmdldFN0YXRlKCkpOwoJCUFzc2VydC5hc3NlcnRFcXVhbHMoImwgc2hvdWxkIHJlc29sdmUuIiwgU3RhdGUuUkVTT0xWRUQsIHVzZXNfbC5nZXRTdGF0ZSgpKTsKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJtLmNvbmZsaWN0MSBzaG91bGQgcmVzb2x2ZS4iLCBTdGF0ZS5SRVNPTFZFRCwgdXNlc19tX2NvbmZsaWN0MS5nZXRTdGF0ZSgpKTsKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJtLmNvbmZsaWN0MiBzaG91bGQgcmVzb2x2ZS4iLCBTdGF0ZS5SRVNPTFZFRCwgdXNlc19tX2NvbmZsaWN0Mi5nZXRTdGF0ZSgpKTsKCX0KCglAVGVzdAoJcHVibGljIHZvaWQgdGVzdFVzZXM2RnJhZ0NvbmZsaWN0cygpIHRocm93cyBCdW5kbGVFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKCQlEdW1teUNvbnRhaW5lckFkYXB0b3IgYWRhcHRvciA9IGNyZWF0ZUR1bW15QWRhcHRvcigpOwoJCU1vZHVsZUNvbnRhaW5lciBjb250YWluZXIgPSBhZGFwdG9yLmdldENvbnRhaW5lcigpOwoKCQlNb2R1bGUgc3lzdGVtQnVuZGxlID0gaW5zdGFsbER1bW15TW9kdWxlKCJzeXN0ZW0uYnVuZGxlLk1GIiwgQ29uc3RhbnRzLlNZU1RFTV9CVU5ETEVfTE9DQVRJT04sIGNvbnRhaW5lcik7CgoJCWNvbnRhaW5lci5yZXNvbHZlKEFycmF5cy5hc0xpc3Qoc3lzdGVtQnVuZGxlKSwgdHJ1ZSk7CgkJTW9kdWxlIHVzZXNfbjEgPSBpbnN0YWxsRHVtbXlNb2R1bGUoInVzZXMubjEuTUYiLCAibjEiLCBjb250YWluZXIpOwoJCWluc3RhbGxEdW1teU1vZHVsZSgidXNlcy5uMi5NRiIsICJuMiIsIGNvbnRhaW5lcik7CgkJTW9kdWxlIHVzZXNfbjJfZnJhZyA9IGluc3RhbGxEdW1teU1vZHVsZSgidXNlcy5uMi5mcmFnLk1GIiwgIm4yLmZyYWciLCBjb250YWluZXIpOwoJCU1vZHVsZSB1c2VzX24zID0gaW5zdGFsbER1bW15TW9kdWxlKCJ1c2VzLm4zLk1GIiwgIm4zIiwgY29udGFpbmVyKTsKCQlSZXNvbHV0aW9uUmVwb3J0IHJlcG9ydCA9IGNvbnRhaW5lci5yZXNvbHZlKG51bGwsIGZhbHNlKTsKCQlBc3NlcnQuYXNzZXJ0TnVsbCgicmVzb2x1dGlvbiByZXBvcnQgaGFzIGEgcmVzb2x1dGlvbiBleGNlcHRpb24uIiwgcmVwb3J0LmdldFJlc29sdXRpb25FeGNlcHRpb24oKSk7CgoJCUFzc2VydC5hc3NlcnRFcXVhbHMoIm4xIHNob3VsZCByZXNvbHZlLiIsIFN0YXRlLlJFU09MVkVELCB1c2VzX24xLmdldFN0YXRlKCkpOwoJCS8vIFRPRE8gVGhlIGZvbGxvd2luZyBzaG91bGQgYmUgdHJ1ZSwgYnV0IG9uIHRoZSBjdXJyZW50IHJlc29sdmVyIGluIE1hcnMgdGhlIGhvc3QgaXMgdGhyb3duIGF3YXkgYWxzbwoJCS8vQXNzZXJ0LmFzc2VydEVxdWFscygibjIgc2hvdWxkIHJlc29sdmUuIiwgU3RhdGUuUkVTT0xWRUQsIHVzZXNfbjIuZ2V0U3RhdGUoKSk7CgkJQXNzZXJ0LmFzc2VydEVxdWFscygibjIuZnJhZyBzaG91bGQgbm90IHJlc29sdmUuIiwgU3RhdGUuSU5TVEFMTEVELCB1c2VzX24yX2ZyYWcuZ2V0U3RhdGUoKSk7CgkJQXNzZXJ0LmFzc2VydEVxdWFscygibjMgc2hvdWxkIHJlc29sdmUuIiwgU3RhdGUuUkVTT0xWRUQsIHVzZXNfbjMuZ2V0U3RhdGUoKSk7Cgl9CgoJLy8gRElTQUJMRSBzZWUgYnVnIDQ5ODA2NCBAVGVzdAoJcHVibGljIHZvaWQgdGVzdFVzZXNUaW1lb3V0KCkgdGhyb3dzIEJ1bmRsZUV4Y2VwdGlvbiB7CgkJLy8gQWx3YXlzIHdhbnQgdG8gZ28gdG8gemVybyB0aHJlYWRzIHdoZW4gaWRsZQoJCWludCBjb3JlVGhyZWFkcyA9IDA7CgkJLy8gdXNlIHRoZSBudW1iZXIgb2YgcHJvY2Vzc29ycyAtIDEgYmVjYXVzZSB3ZSB1c2UgdGhlIGN1cnJlbnQgdGhyZWFkIHdoZW4gcmVqZWN0ZWQKCQlpbnQgbWF4VGhyZWFkcyA9IE1hdGgubWF4KFJ1bnRpbWUuZ2V0UnVudGltZSgpLmF2YWlsYWJsZVByb2Nlc3NvcnMoKSAtIDEsIDEpOwoJCS8vIGlkbGUgdGltZW91dDsgbWFrZSBpdCBzaG9ydCB0byBnZXQgcmlkIG9mIHRocmVhZHMgcXVpY2tseSBhZnRlciByZXNvbHZlCgkJaW50IGlkbGVUaW1lb3V0ID0gNTsKCQkvLyB1c2Ugc3luYyBxdWV1ZSB0byBmb3JjZSB0aHJlYWQgY3JlYXRpb24KCQlCbG9ja2luZ1F1ZXVlPFJ1bm5hYmxlPiBxdWV1ZSA9IG5ldyBTeW5jaHJvbm91c1F1ZXVlPFJ1bm5hYmxlPigpOwoJCS8vIHRyeSB0byBuYW1lIHRoZSB0aHJlYWRzIHdpdGggdXNlZnVsIG5hbWUKCQlUaHJlYWRGYWN0b3J5IHRocmVhZEZhY3RvcnkgPSBuZXcgVGhyZWFkRmFjdG9yeSgpIHsKCQkJQE92ZXJyaWRlCgkJCXB1YmxpYyBUaHJlYWQgbmV3VGhyZWFkKFJ1bm5hYmxlIHIpIHsKCQkJCVRocmVhZCB0ID0gbmV3IFRocmVhZChyLCAiUmVzb2x2ZXIgdGhyZWFkIC0gVU5JVCBURVNUIik7IC8vJE5PTi1OTFMtMSQKCQkJCXQuc2V0RGFlbW9uKHRydWUpOwoJCQkJcmV0dXJuIHQ7CgkJCX0KCQl9OwoJCS8vIHVzZSBhIHJlamVjdGlvbiBwb2xpY3kgdGhhdCBzaW1wbHkgcnVucyB0aGUgdGFzayBpbiB0aGUgY3VycmVudCB0aHJlYWQgb25jZSB0aGUgbWF4IHRocmVhZHMgaXMgcmVhY2hlZAoJCVJlamVjdGVkRXhlY3V0aW9uSGFuZGxlciByZWplY3RIYW5kbGVyID0gbmV3IFJlamVjdGVkRXhlY3V0aW9uSGFuZGxlcigpIHsKCQkJQE92ZXJyaWRlCgkJCXB1YmxpYyB2b2lkIHJlamVjdGVkRXhlY3V0aW9uKFJ1bm5hYmxlIHIsIFRocmVhZFBvb2xFeGVjdXRvciBleGUpIHsKCQkJCXIucnVuKCk7CgkJCX0KCQl9OwoJCUV4ZWN1dG9yU2VydmljZSBleGVjdXRvciA9IG5ldyBUaHJlYWRQb29sRXhlY3V0b3IoY29yZVRocmVhZHMsIG1heFRocmVhZHMsIGlkbGVUaW1lb3V0LCBUaW1lVW5pdC5TRUNPTkRTLCBxdWV1ZSwgdGhyZWFkRmFjdG9yeSwgcmVqZWN0SGFuZGxlcik7CgkJU2NoZWR1bGVkRXhlY3V0b3JTZXJ2aWNlIHRpbWVvdXRFeGVjdXRvciA9IG5ldyBTY2hlZHVsZWRUaHJlYWRQb29sRXhlY3V0b3IoMSk7CgoJCU1hcDxTdHJpbmcsIFN0cmluZz4gY29uZmlndXJhdGlvbiA9IG5ldyBIYXNoTWFwPFN0cmluZywgU3RyaW5nPigpOwoJCWNvbmZpZ3VyYXRpb24ucHV0KEVxdWlub3hDb25maWd1cmF0aW9uLlBST1BfUkVTT0xWRVJfQkFUQ0hfVElNRU9VVCwgIjUwMDAiKTsKCQlNYXA8U3RyaW5nLCBTdHJpbmc+IGRlYnVnT3B0cyA9IENvbGxlY3Rpb25zLmVtcHR5TWFwKCk7CgkJRHVtbXlDb250YWluZXJBZGFwdG9yIGFkYXB0b3IgPSBuZXcgRHVtbXlDb250YWluZXJBZGFwdG9yKG5ldyBEdW1teUNvbGxpc2lvbkhvb2soZmFsc2UpLCBjb25maWd1cmF0aW9uLCBuZXcgRHVtbXlSZXNvbHZlckhvb2tGYWN0b3J5KCksIG5ldyBEdW1teURlYnVnT3B0aW9ucyhkZWJ1Z09wdHMpKTsKCQlhZGFwdG9yLnNldFJlc29sdmVyRXhlY3V0b3IoZXhlY3V0b3IpOwoJCWFkYXB0b3Iuc2V0VGltZW91dEV4ZWN1dG9yKHRpbWVvdXRFeGVjdXRvcik7CgkJTW9kdWxlQ29udGFpbmVyIGNvbnRhaW5lciA9IGFkYXB0b3IuZ2V0Q29udGFpbmVyKCk7CgkJZm9yIChpbnQgaSA9IDE7IGkgPD0gMTAwMDsgaSsrKSB7CgkJCWZvciAoTWFwPFN0cmluZywgU3RyaW5nPiBtYW5pZmVzdCA6IGdldFVzZXNUaW1lb3V0TWFuaWZlc3RzKCJ0ZXN0IiArIGkpKSB7CgkJCQlpbnN0YWxsRHVtbXlNb2R1bGUobWFuaWZlc3QsIG1hbmlmZXN0LmdldChDb25zdGFudHMuQlVORExFX1NZTUJPTElDTkFNRSksIGNvbnRhaW5lcik7CgkJCX0KCQl9CgkJUmVzb2x1dGlvblJlcG9ydCByZXBvcnQgPSBjb250YWluZXIucmVzb2x2ZShjb250YWluZXIuZ2V0TW9kdWxlcygpLCB0cnVlKTsKCQlBc3NlcnQuYXNzZXJ0TnVsbCgiRm91bmQgcmVzb2x1dGlvbiBlcnJvcnMuIiwgcmVwb3J0LmdldFJlc29sdXRpb25FeGNlcHRpb24oKSk7CgkJZm9yIChNb2R1bGUgbW9kdWxlIDogY29udGFpbmVyLmdldE1vZHVsZXMoKSkgewoJCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJXcm9uZyBzdGF0ZSBvZiBtb2R1bGU6ICIgKyBtb2R1bGUsIFN0YXRlLlJFU09MVkVELCBtb2R1bGUuZ2V0U3RhdGUoKSk7CgkJfQoJCWV4ZWN1dG9yLnNodXRkb3duKCk7CgkJdGltZW91dEV4ZWN1dG9yLnNodXRkb3duKCk7CgkJU3lzdGVtLmdjKCk7CgkJU3lzdGVtLmdjKCk7CgkJU3lzdGVtLmdjKCk7Cgl9CgoJcHJpdmF0ZSBMaXN0PE1hcDxTdHJpbmcsIFN0cmluZz4+IGdldFVzZXNUaW1lb3V0TWFuaWZlc3RzKFN0cmluZyBwcmVmaXgpIHsKCQlMaXN0PE1hcDxTdHJpbmcsIFN0cmluZz4+IHJlc3VsdCA9IG5ldyBBcnJheUxpc3Q8TWFwPFN0cmluZywgU3RyaW5nPj4oKTsKCQkvLyB4MSBidW5kbGUKCQlNYXA8U3RyaW5nLCBTdHJpbmc+IHgxTWFuaWZlc3QgPSBuZXcgSGFzaE1hcDxTdHJpbmcsIFN0cmluZz4oKTsKCQl4MU1hbmlmZXN0LnB1dChDb25zdGFudHMuQlVORExFX01BTklGRVNUVkVSU0lPTiwgIjIiKTsKCQl4MU1hbmlmZXN0LnB1dChDb25zdGFudHMuQlVORExFX1NZTUJPTElDTkFNRSwgcHJlZml4ICsgIi54MSIpOwoJCXgxTWFuaWZlc3QucHV0KENvbnN0YW50cy5FWFBPUlRfUEFDS0FHRSwgcHJlZml4ICsgIi5hOyB2ZXJzaW9uPTEuMDsgdXNlczo9IiArIHByZWZpeCArICIuYiIpOwoJCXgxTWFuaWZlc3QucHV0KENvbnN0YW50cy5JTVBPUlRfUEFDS0FHRSwgcHJlZml4ICsgIi5iOyB2ZXJzaW9uPVwiWzEuMSwxLjIpXCIiKTsKCQlyZXN1bHQuYWRkKHgxTWFuaWZlc3QpOwoJCS8vIHgyIGJ1bmRsZQoJCU1hcDxTdHJpbmcsIFN0cmluZz4geDJNYW5pZmVzdCA9IG5ldyBIYXNoTWFwPFN0cmluZywgU3RyaW5nPigpOwoJCXgyTWFuaWZlc3QucHV0KENvbnN0YW50cy5CVU5ETEVfTUFOSUZFU1RWRVJTSU9OLCAiMiIpOwoJCXgyTWFuaWZlc3QucHV0KENvbnN0YW50cy5CVU5ETEVfU1lNQk9MSUNOQU1FLCBwcmVmaXggKyAiLngyIik7CgkJeDJNYW5pZmVzdC5wdXQoQ29uc3RhbnRzLkVYUE9SVF9QQUNLQUdFLCBwcmVmaXggKyAiLmE7IHZlcnNpb249MS4xOyB1c2VzOj0iICsgcHJlZml4ICsgIi5iIik7CgkJeDJNYW5pZmVzdC5wdXQoQ29uc3RhbnRzLklNUE9SVF9QQUNLQUdFLCBwcmVmaXggKyAiLmI7IHZlcnNpb249XCJbMS4wLDEuMSlcIiIpOwoJCXJlc3VsdC5hZGQoeDJNYW5pZmVzdCk7CgkJLy8geTEgYnVuZGxlCgkJTWFwPFN0cmluZywgU3RyaW5nPiB5MU1hbmlmZXN0ID0gbmV3IEhhc2hNYXA8U3RyaW5nLCBTdHJpbmc+KCk7CgkJeTFNYW5pZmVzdC5wdXQoQ29uc3RhbnRzLkJVTkRMRV9NQU5JRkVTVFZFUlNJT04sICIyIik7CgkJeTFNYW5pZmVzdC5wdXQoQ29uc3RhbnRzLkJVTkRMRV9TWU1CT0xJQ05BTUUsIHByZWZpeCArICIueTEiKTsKCQl5MU1hbmlmZXN0LnB1dChDb25zdGFudHMuRVhQT1JUX1BBQ0tBR0UsIHByZWZpeCArICIuYjsgdmVyc2lvbj0xLjAiKTsKCQlyZXN1bHQuYWRkKHkxTWFuaWZlc3QpOwoJCS8vIHkxIGJ1bmRsZQoJCU1hcDxTdHJpbmcsIFN0cmluZz4geTJNYW5pZmVzdCA9IG5ldyBIYXNoTWFwPFN0cmluZywgU3RyaW5nPigpOwoJCXkyTWFuaWZlc3QucHV0KENvbnN0YW50cy5CVU5ETEVfTUFOSUZFU1RWRVJTSU9OLCAiMiIpOwoJCXkyTWFuaWZlc3QucHV0KENvbnN0YW50cy5CVU5ETEVfU1lNQk9MSUNOQU1FLCBwcmVmaXggKyAiLnkyIik7CgkJeTJNYW5pZmVzdC5wdXQoQ29uc3RhbnRzLkVYUE9SVF9QQUNLQUdFLCBwcmVmaXggKyAiLmI7IHZlcnNpb249MS4xIik7CgkJcmVzdWx0LmFkZCh5Mk1hbmlmZXN0KTsKCQkvLyB6MSBidW5kbGUKCQlNYXA8U3RyaW5nLCBTdHJpbmc+IHoxTWFuaWZlc3QgPSBuZXcgSGFzaE1hcDxTdHJpbmcsIFN0cmluZz4oKTsKCQl6MU1hbmlmZXN0LnB1dChDb25zdGFudHMuQlVORExFX01BTklGRVNUVkVSU0lPTiwgIjIiKTsKCQl6MU1hbmlmZXN0LnB1dChDb25zdGFudHMuQlVORExFX1NZTUJPTElDTkFNRSwgcHJlZml4ICsgIi56MSIpOwoJCXoxTWFuaWZlc3QucHV0KENvbnN0YW50cy5JTVBPUlRfUEFDS0FHRSwgcHJlZml4ICsgIi5hLCAiICsgcHJlZml4ICsgIi5iIik7CgkJcmVzdWx0LmFkZCh6MU1hbmlmZXN0KTsKCQlyZXR1cm4gcmVzdWx0OwoJfQoKCUBUZXN0CglwdWJsaWMgdm9pZCB0ZXN0T3B0aW9uYWxTdWJzdGl0dXRlZCgpIHRocm93cyBCdW5kbGVFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKCQlEdW1teUNvbnRhaW5lckFkYXB0b3IgYWRhcHRvciA9IGNyZWF0ZUR1bW15QWRhcHRvcigpOwoJCU1vZHVsZUNvbnRhaW5lciBjb250YWluZXIgPSBhZGFwdG9yLmdldENvbnRhaW5lcigpOwoKCQlNb2R1bGUgc3lzdGVtQnVuZGxlID0gaW5zdGFsbER1bW15TW9kdWxlKCJzeXN0ZW0uYnVuZGxlLk1GIiwgQ29uc3RhbnRzLlNZU1RFTV9CVU5ETEVfTE9DQVRJT04sIGNvbnRhaW5lcik7CgoJCWNvbnRhaW5lci5yZXNvbHZlKEFycmF5cy5hc0xpc3Qoc3lzdGVtQnVuZGxlKSwgdHJ1ZSk7CgkJTW9kdWxlIHN1Yl9uID0gaW5zdGFsbER1bW15TW9kdWxlKCJzdWIubi5NRiIsICJuIiwgY29udGFpbmVyKTsKCQlNb2R1bGUgc3ViX2wgPSBpbnN0YWxsRHVtbXlNb2R1bGUoInN1Yi5sLk1GIiwgImwiLCBjb250YWluZXIpOwoJCU1vZHVsZSBzdWJfbSA9IGluc3RhbGxEdW1teU1vZHVsZSgic3ViLm0uTUYiLCAibSIsIGNvbnRhaW5lcik7CgoJCWNvbnRhaW5lci5yZXNvbHZlKG51bGwsIGZhbHNlKTsKCgkJQXNzZXJ0LmFzc2VydEVxdWFscygibCBzaG91bGQgcmVzb2x2ZS4iLCBTdGF0ZS5SRVNPTFZFRCwgc3ViX2wuZ2V0U3RhdGUoKSk7CgkJQXNzZXJ0LmFzc2VydEVxdWFscygibSBzaG91bGQgcmVzb2x2ZS4iLCBTdGF0ZS5SRVNPTFZFRCwgc3ViX20uZ2V0U3RhdGUoKSk7CgkJQXNzZXJ0LmFzc2VydEVxdWFscygibiBzaG91bGQgcmVzb2x2ZS4iLCBTdGF0ZS5SRVNPTFZFRCwgc3ViX24uZ2V0U3RhdGUoKSk7Cgl9CgoJQFRlc3QKCXB1YmxpYyB2b2lkIHRlc3RTdGF0aWNTdWJzdGl0dXRlZCgpIHRocm93cyBCdW5kbGVFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKCQlEdW1teUNvbnRhaW5lckFkYXB0b3IgYWRhcHRvciA9IGNyZWF0ZUR1bW15QWRhcHRvcigpOwoJCU1vZHVsZUNvbnRhaW5lciBjb250YWluZXIgPSBhZGFwdG9yLmdldENvbnRhaW5lcigpOwoKCQlNb2R1bGUgc3lzdGVtQnVuZGxlID0gaW5zdGFsbER1bW15TW9kdWxlKCJzeXN0ZW0uYnVuZGxlLk1GIiwgQ29uc3RhbnRzLlNZU1RFTV9CVU5ETEVfTE9DQVRJT04sIGNvbnRhaW5lcik7CgoJCWNvbnRhaW5lci5yZXNvbHZlKEFycmF5cy5hc0xpc3Qoc3lzdGVtQnVuZGxlKSwgdHJ1ZSk7CgkJTW9kdWxlIHN1Yl9uID0gaW5zdGFsbER1bW15TW9kdWxlKCJzdWIubi5zdGF0aWMuTUYiLCAibiIsIGNvbnRhaW5lcik7CgkJTW9kdWxlIHN1Yl9sID0gaW5zdGFsbER1bW15TW9kdWxlKCJzdWIubC5NRiIsICJsIiwgY29udGFpbmVyKTsKCQlNb2R1bGUgc3ViX20gPSBpbnN0YWxsRHVtbXlNb2R1bGUoInN1Yi5tLk1GIiwgIm0iLCBjb250YWluZXIpOwoKCQljb250YWluZXIucmVzb2x2ZShudWxsLCBmYWxzZSk7CgoJCUFzc2VydC5hc3NlcnRFcXVhbHMoImwgc2hvdWxkIHJlc29sdmUuIiwgU3RhdGUuUkVTT0xWRUQsIHN1Yl9sLmdldFN0YXRlKCkpOwoJCUFzc2VydC5hc3NlcnRFcXVhbHMoIm0gc2hvdWxkIHJlc29sdmUuIiwgU3RhdGUuUkVTT0xWRUQsIHN1Yl9tLmdldFN0YXRlKCkpOwoJCUFzc2VydC5hc3NlcnRFcXVhbHMoIm4gc2hvdWxkIHJlc29sdmUuIiwgU3RhdGUuUkVTT0xWRUQsIHN1Yl9uLmdldFN0YXRlKCkpOwoJfQoKCUBUZXN0CglwdWJsaWMgdm9pZCB0ZXN0TXVsdGlDYXJkaW5hbGl0eVVzZXMoKSB0aHJvd3MgQnVuZGxlRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CgkJRHVtbXlDb250YWluZXJBZGFwdG9yIGFkYXB0b3IgPSBjcmVhdGVEdW1teUFkYXB0b3IoKTsKCQlNb2R1bGVDb250YWluZXIgY29udGFpbmVyID0gYWRhcHRvci5nZXRDb250YWluZXIoKTsKCgkJTW9kdWxlIHN5c3RlbUJ1bmRsZSA9IGluc3RhbGxEdW1teU1vZHVsZSgic3lzdGVtLmJ1bmRsZS5NRiIsIENvbnN0YW50cy5TWVNURU1fQlVORExFX0xPQ0FUSU9OLCBjb250YWluZXIpOwoKCQljb250YWluZXIucmVzb2x2ZShBcnJheXMuYXNMaXN0KHN5c3RlbUJ1bmRsZSksIHRydWUpOwoKCQlNb2R1bGUgcDV2MTAwID0gaW5zdGFsbER1bW15TW9kdWxlKCJwNV92MTAwLk1GIiwgInA1X3YxMDAiLCBjb250YWluZXIpOwoJCU1vZHVsZSBwNXYxMDEgPSBpbnN0YWxsRHVtbXlNb2R1bGUoInA1X3YxMDEuTUYiLCAicDVfdjEwMSIsIGNvbnRhaW5lcik7CgkJTW9kdWxlIHA1djExMCA9IGluc3RhbGxEdW1teU1vZHVsZSgicDVfdjExMC5NRiIsICJwNV92MTEwIiwgY29udGFpbmVyKTsKCQlNb2R1bGUgcDV2MTExID0gaW5zdGFsbER1bW15TW9kdWxlKCJwNV92MTExLk1GIiwgInA1X3YxMTEiLCBjb250YWluZXIpOwoJCWluc3RhbGxEdW1teU1vZHVsZSgicDZfdjEwMC5NRiIsICJwNl92MTAwIiwgY29udGFpbmVyKTsKCQlpbnN0YWxsRHVtbXlNb2R1bGUoInA2X3YxMTAuTUYiLCAicDZfdjExMCIsIGNvbnRhaW5lcik7CgkJaW5zdGFsbER1bW15TW9kdWxlKCJwN192MTAwLk1GIiwgInA3X3YxMDAiLCBjb250YWluZXIpOwoJCWluc3RhbGxEdW1teU1vZHVsZSgicDdfdjExMC5NRiIsICJwN192MTEwIiwgY29udGFpbmVyKTsKCgkJY29udGFpbmVyLnJlc29sdmUobnVsbCwgZmFsc2UpOwoKCQlNb2R1bGUgYzZ2MTAwID0gaW5zdGFsbER1bW15TW9kdWxlKCJjNl92MTAwLk1GIiwgImM2X3YxMDAiLCBjb250YWluZXIpOwoJCU1vZHVsZSBjNnYxMTAgPSBpbnN0YWxsRHVtbXlNb2R1bGUoImM2X3YxMTAuTUYiLCAiYzZfdjExMCIsIGNvbnRhaW5lcik7CgkJTW9kdWxlIGM2djEzMCA9IGluc3RhbGxEdW1teU1vZHVsZSgiYzZfdjEzMC5NRiIsICJjNl92MTMwIiwgY29udGFpbmVyKTsKCQlNb2R1bGUgYzZ2MTQwID0gaW5zdGFsbER1bW15TW9kdWxlKCJjNl92MTQwLk1GIiwgImM2X3YxNDAiLCBjb250YWluZXIpOwoJCU1vZHVsZSBjNnYxNTAgPSBpbnN0YWxsRHVtbXlNb2R1bGUoImM2X3YxNTAuTUYiLCAiYzZfdjE1MCIsIGNvbnRhaW5lcik7CgkJTW9kdWxlIGM2djE3MCA9IGluc3RhbGxEdW1teU1vZHVsZSgiYzZfdjE3MC5NRiIsICJjNl92MTcwIiwgY29udGFpbmVyKTsKCgkJLy8JCU1vZHVsZSBjNnYxODAgPSBpbnN0YWxsRHVtbXlNb2R1bGUoImM2X3YxODAuTUYiLCAiYzZfdjE4MCIsIGNvbnRhaW5lcik7CgkJLy8JCU1vZHVsZSBjNnYxMjAgPSBpbnN0YWxsRHVtbXlNb2R1bGUoImM2X3YxMjAuTUYiLCAiYzZfdjEyMCIsIGNvbnRhaW5lcik7CgoJCWNvbnRhaW5lci5yZXNvbHZlKG51bGwsIGZhbHNlKTsKCgkJZmluYWwgU3RyaW5nIG5hbWVzcGFjZTUgPSAibmFtZXNwYWNlLjUiOwoJCUxpc3Q8TW9kdWxlV2lyZT4gcDV2MTAwUHJvdmlkZWQgPSBwNXYxMDAuZ2V0Q3VycmVudFJldmlzaW9uKCkuZ2V0V2lyaW5nKCkuZ2V0UHJvdmlkZWRNb2R1bGVXaXJlcyhuYW1lc3BhY2U1KTsKCQlMaXN0PE1vZHVsZVdpcmU+IHA1djEwMVByb3ZpZGVkID0gcDV2MTAxLmdldEN1cnJlbnRSZXZpc2lvbigpLmdldFdpcmluZygpLmdldFByb3ZpZGVkTW9kdWxlV2lyZXMobmFtZXNwYWNlNSk7CgkJTGlzdDxNb2R1bGVXaXJlPiBwNXYxMTBQcm92aWRlZCA9IHA1djExMC5nZXRDdXJyZW50UmV2aXNpb24oKS5nZXRXaXJpbmcoKS5nZXRQcm92aWRlZE1vZHVsZVdpcmVzKG5hbWVzcGFjZTUpOwoJCUxpc3Q8TW9kdWxlV2lyZT4gcDV2MTExUHJvdmlkZWQgPSBwNXYxMTEuZ2V0Q3VycmVudFJldmlzaW9uKCkuZ2V0V2lyaW5nKCkuZ2V0UHJvdmlkZWRNb2R1bGVXaXJlcyhuYW1lc3BhY2U1KTsKCgkJTW9kdWxlV2lyaW5nIGM2djEwMFdpcmluZyA9IGM2djEwMC5nZXRDdXJyZW50UmV2aXNpb24oKS5nZXRXaXJpbmcoKTsKCQlMaXN0PE1vZHVsZVdpcmU+IGM2djEwMFJlcXVpcmVkID0gYzZ2MTAwV2lyaW5nLmdldFJlcXVpcmVkTW9kdWxlV2lyZXMobmFtZXNwYWNlNSk7CgkJQXNzZXJ0LmFzc2VydEVxdWFscygiV3JvbmcgbnVtYmVyIG9mIGNhcGFiaWxpdGllcyIsIDIsIGM2djEwMFJlcXVpcmVkLnNpemUoKSk7CgkJYXNzZXJ0V2lyZXMoYzZ2MTAwUmVxdWlyZWQsIHA1djEwMFByb3ZpZGVkLCBwNXYxMDFQcm92aWRlZCk7CgoJCU1vZHVsZVdpcmluZyBjNnYxMTBXaXJpbmcgPSBjNnYxMTAuZ2V0Q3VycmVudFJldmlzaW9uKCkuZ2V0V2lyaW5nKCk7CgkJTGlzdDxNb2R1bGVXaXJlPiBjNnYxMTBSZXF1aXJlZCA9IGM2djExMFdpcmluZy5nZXRSZXF1aXJlZE1vZHVsZVdpcmVzKG5hbWVzcGFjZTUpOwoJCUFzc2VydC5hc3NlcnRFcXVhbHMoIldyb25nIG51bWJlciBvZiBjYXBhYmlsaXRpZXMiLCAyLCBjNnYxMTBSZXF1aXJlZC5zaXplKCkpOwoJCWFzc2VydFdpcmVzKGM2djExMFJlcXVpcmVkLCBwNXYxMDBQcm92aWRlZCwgcDV2MTAxUHJvdmlkZWQpOwoKCQlNb2R1bGVXaXJpbmcgYzZ2MTMwV2lyaW5nID0gYzZ2MTMwLmdldEN1cnJlbnRSZXZpc2lvbigpLmdldFdpcmluZygpOwoJCUxpc3Q8TW9kdWxlV2lyZT4gYzZ2MTMwUmVxdWlyZWQgPSBjNnYxMzBXaXJpbmcuZ2V0UmVxdWlyZWRNb2R1bGVXaXJlcyhuYW1lc3BhY2U1KTsKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJXcm9uZyBudW1iZXIgb2YgY2FwYWJpbGl0aWVzIiwgMiwgYzZ2MTMwUmVxdWlyZWQuc2l6ZSgpKTsKCQlhc3NlcnRXaXJlcyhjNnYxMzBSZXF1aXJlZCwgcDV2MTAwUHJvdmlkZWQsIHA1djEwMVByb3ZpZGVkKTsKCgkJTW9kdWxlV2lyaW5nIGM2djE0MFdpcmluZyA9IGM2djE0MC5nZXRDdXJyZW50UmV2aXNpb24oKS5nZXRXaXJpbmcoKTsKCQlMaXN0PE1vZHVsZVdpcmU+IGM2djE0MFJlcXVpcmVkID0gYzZ2MTQwV2lyaW5nLmdldFJlcXVpcmVkTW9kdWxlV2lyZXMobmFtZXNwYWNlNSk7CgkJQXNzZXJ0LmFzc2VydEVxdWFscygiV3JvbmcgbnVtYmVyIG9mIGNhcGFiaWxpdGllcyIsIDIsIGM2djE0MFJlcXVpcmVkLnNpemUoKSk7CgkJYXNzZXJ0V2lyZXMoYzZ2MTQwUmVxdWlyZWQsIHA1djEwMFByb3ZpZGVkLCBwNXYxMDFQcm92aWRlZCk7CgoJCU1vZHVsZVdpcmluZyBjNnYxNTBXaXJpbmcgPSBjNnYxNTAuZ2V0Q3VycmVudFJldmlzaW9uKCkuZ2V0V2lyaW5nKCk7CgkJTGlzdDxNb2R1bGVXaXJlPiBjNnYxNTBSZXF1aXJlZCA9IGM2djE1MFdpcmluZy5nZXRSZXF1aXJlZE1vZHVsZVdpcmVzKG5hbWVzcGFjZTUpOwoJCUFzc2VydC5hc3NlcnRFcXVhbHMoIldyb25nIG51bWJlciBvZiBjYXBhYmlsaXRpZXMiLCAyLCBjNnYxNTBSZXF1aXJlZC5zaXplKCkpOwoJCWFzc2VydFdpcmVzKGM2djE1MFJlcXVpcmVkLCBwNXYxMTBQcm92aWRlZCwgcDV2MTExUHJvdmlkZWQpOwoKCQlNb2R1bGVXaXJpbmcgYzZ2MTcwV2lyaW5nID0gYzZ2MTcwLmdldEN1cnJlbnRSZXZpc2lvbigpLmdldFdpcmluZygpOwoJCUxpc3Q8TW9kdWxlV2lyZT4gYzZ2MTcwUmVxdWlyZWQgPSBjNnYxNzBXaXJpbmcuZ2V0UmVxdWlyZWRNb2R1bGVXaXJlcyhuYW1lc3BhY2U1KTsKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJXcm9uZyBudW1iZXIgb2YgY2FwYWJpbGl0aWVzIiwgMiwgYzZ2MTcwUmVxdWlyZWQuc2l6ZSgpKTsKCQlhc3NlcnRXaXJlcyhjNnYxNzBSZXF1aXJlZCwgcDV2MTEwUHJvdmlkZWQsIHA1djExMVByb3ZpZGVkKTsKCgkJTW9kdWxlIGM2djE2MCA9IGluc3RhbGxEdW1teU1vZHVsZSgiYzZfdjE2MC5NRiIsICJjNl92MTYwIiwgY29udGFpbmVyKTsKCgkJY29udGFpbmVyLnJlc29sdmUobnVsbCwgZmFsc2UpOwoKCQlBc3NlcnQuYXNzZXJ0TnVsbCgiQnVuZGxlIHNob3VsZCBub3QgYmUgcmVzb2x2ZWQ6ICIgKyBjNnYxNjAsIGM2djE2MC5nZXRDdXJyZW50UmV2aXNpb24oKS5nZXRXaXJpbmcoKSk7CgoJCWNvbnRhaW5lci51bmluc3RhbGwoYzZ2MTYwKTsKCgkJTW9kdWxlIGM2djE4MCA9IGluc3RhbGxEdW1teU1vZHVsZSgiYzZfdjE4MC5NRiIsICJjNl92MTgwIiwgY29udGFpbmVyKTsKCgkJY29udGFpbmVyLnJlc29sdmUobnVsbCwgZmFsc2UpOwoKCQlBc3NlcnQuYXNzZXJ0TnVsbCgiQnVuZGxlIHNob3VsZCBub3QgYmUgcmVzb2x2ZWQ6ICIgKyBjNnYxODAsIGM2djE4MC5nZXRDdXJyZW50UmV2aXNpb24oKS5nZXRXaXJpbmcoKSk7CgoJCWNvbnRhaW5lci51bmluc3RhbGwoYzZ2MTgwKTsKCX0KCglAVGVzdAoJcHVibGljIHZvaWQgdGVzdENvbXBhdFNpbmdsZXRvbigpIHRocm93cyBCdW5kbGVFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKCQlEdW1teUNvbnRhaW5lckFkYXB0b3IgYWRhcHRvciA9IGNyZWF0ZUR1bW15QWRhcHRvcigpOwoJCU1vZHVsZUNvbnRhaW5lciBjb250YWluZXIgPSBhZGFwdG9yLmdldENvbnRhaW5lcigpOwoJCU1vZHVsZSBzMSA9IGluc3RhbGxEdW1teU1vZHVsZSgiY29tcGF0U2luZ2xldG9uMS5NRiIsICJzMSIsIGNvbnRhaW5lcik7CgkJTW9kdWxlIHMyID0gaW5zdGFsbER1bW15TW9kdWxlKCJjb21wYXRTaW5nbGV0b24yLk1GIiwgInMyIiwgY29udGFpbmVyKTsKCQlNb2R1bGUgczMgPSBpbnN0YWxsRHVtbXlNb2R1bGUoImNvbXBhdFNpbmdsZXRvbjMuTUYiLCAiczMiLCBjb250YWluZXIpOwoKCQlTdHJpbmcgczFTaW5nbGV0b24gPSBzMS5nZXRDdXJyZW50UmV2aXNpb24oKS5nZXRDYXBhYmlsaXRpZXMoSWRlbnRpdHlOYW1lc3BhY2UuSURFTlRJVFlfTkFNRVNQQUNFKS5pdGVyYXRvcigpLm5leHQoKS5nZXREaXJlY3RpdmVzKCkuZ2V0KElkZW50aXR5TmFtZXNwYWNlLkNBUEFCSUxJVFlfU0lOR0xFVE9OX0RJUkVDVElWRSk7CgkJU3RyaW5nIHMyU2luZ2xldG9uID0gczIuZ2V0Q3VycmVudFJldmlzaW9uKCkuZ2V0Q2FwYWJpbGl0aWVzKElkZW50aXR5TmFtZXNwYWNlLklERU5USVRZX05BTUVTUEFDRSkuaXRlcmF0b3IoKS5uZXh0KCkuZ2V0RGlyZWN0aXZlcygpLmdldChJZGVudGl0eU5hbWVzcGFjZS5DQVBBQklMSVRZX1NJTkdMRVRPTl9ESVJFQ1RJVkUpOwoJCVN0cmluZyBzM1NpbmdsZXRvbiA9IHMzLmdldEN1cnJlbnRSZXZpc2lvbigpLmdldENhcGFiaWxpdGllcyhJZGVudGl0eU5hbWVzcGFjZS5JREVOVElUWV9OQU1FU1BBQ0UpLml0ZXJhdG9yKCkubmV4dCgpLmdldERpcmVjdGl2ZXMoKS5nZXQoSWRlbnRpdHlOYW1lc3BhY2UuQ0FQQUJJTElUWV9TSU5HTEVUT05fRElSRUNUSVZFKTsKCgkJQXNzZXJ0LmFzc2VydEVxdWFscygiV3Jvbmcgc2luZ2xldG9uIGRpcmVjdGl2ZTogIiArIHMxLCAidHJ1ZSIsIHMxU2luZ2xldG9uKTsKCQlBc3NlcnQuYXNzZXJ0TnVsbCgiV3Jvbmcgc2luZ2xldG9uIGRpcmVjdGl2ZTogIiArIHMyLCBzMlNpbmdsZXRvbik7CgkJQXNzZXJ0LmFzc2VydEVxdWFscygiV3Jvbmcgc2luZ2xldG9uIGRpcmVjdGl2ZTogIiArIHMzLCAidHJ1ZSIsIHMzU2luZ2xldG9uKTsKCX0KCglAVGVzdAoJcHVibGljIHZvaWQgdGVzdENvbXBhdFJlcHJvdmlkZSgpIHRocm93cyBCdW5kbGVFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKCQlEdW1teUNvbnRhaW5lckFkYXB0b3IgYWRhcHRvciA9IGNyZWF0ZUR1bW15QWRhcHRvcigpOwoJCU1vZHVsZUNvbnRhaW5lciBjb250YWluZXIgPSBhZGFwdG9yLmdldENvbnRhaW5lcigpOwoJCU1vZHVsZSBiMSA9IGluc3RhbGxEdW1teU1vZHVsZSgiY29tcGF0UmVwcm92aWRlMS5NRiIsICJiMSIsIGNvbnRhaW5lcik7CgkJTW9kdWxlIGIyID0gaW5zdGFsbER1bW15TW9kdWxlKCJjb21wYXRSZXByb3ZpZGUyLk1GIiwgImIyIiwgY29udGFpbmVyKTsKCQlNb2R1bGUgYjMgPSBpbnN0YWxsRHVtbXlNb2R1bGUoImNvbXBhdFJlcHJvdmlkZTMuTUYiLCAiYjMiLCBjb250YWluZXIpOwoKCQlTdHJpbmcgYjFWaXNpYmlsaXR5ID0gYjEuZ2V0Q3VycmVudFJldmlzaW9uKCkuZ2V0UmVxdWlyZW1lbnRzKEJ1bmRsZU5hbWVzcGFjZS5CVU5ETEVfTkFNRVNQQUNFKS5pdGVyYXRvcigpLm5leHQoKS5nZXREaXJlY3RpdmVzKCkuZ2V0KEJ1bmRsZU5hbWVzcGFjZS5SRVFVSVJFTUVOVF9WSVNJQklMSVRZX0RJUkVDVElWRSk7CgkJU3RyaW5nIGIyVmlzaWJpbGl0eSA9IGIyLmdldEN1cnJlbnRSZXZpc2lvbigpLmdldFJlcXVpcmVtZW50cyhCdW5kbGVOYW1lc3BhY2UuQlVORExFX05BTUVTUEFDRSkuaXRlcmF0b3IoKS5uZXh0KCkuZ2V0RGlyZWN0aXZlcygpLmdldChCdW5kbGVOYW1lc3BhY2UuUkVRVUlSRU1FTlRfVklTSUJJTElUWV9ESVJFQ1RJVkUpOwoJCVN0cmluZyBiM1Zpc2liaWxpdHkgPSBiMy5nZXRDdXJyZW50UmV2aXNpb24oKS5nZXRSZXF1aXJlbWVudHMoQnVuZGxlTmFtZXNwYWNlLkJVTkRMRV9OQU1FU1BBQ0UpLml0ZXJhdG9yKCkubmV4dCgpLmdldERpcmVjdGl2ZXMoKS5nZXQoQnVuZGxlTmFtZXNwYWNlLlJFUVVJUkVNRU5UX1ZJU0lCSUxJVFlfRElSRUNUSVZFKTsKCgkJQXNzZXJ0LmFzc2VydEVxdWFscygiV3JvbmcgdmlzaWJpbGl0eSBkaXJlY3RpdmU6ICIgKyBiMSwgQnVuZGxlTmFtZXNwYWNlLlZJU0lCSUxJVFlfUkVFWFBPUlQsIGIxVmlzaWJpbGl0eSk7CgkJQXNzZXJ0LmFzc2VydE51bGwoIldyb25nIHZpc2liaWxpdHkgZGlyZWN0aXZlOiAiLCBiMlZpc2liaWxpdHkpOwoJCUFzc2VydC5hc3NlcnRFcXVhbHMoIldyb25nIHZpc2liaWxpdHkgZGlyZWN0aXZlOiAiICsgYjIsIEJ1bmRsZU5hbWVzcGFjZS5WSVNJQklMSVRZX1JFRVhQT1JULCBiM1Zpc2liaWxpdHkpOwoJfQoKCUBUZXN0CglwdWJsaWMgdm9pZCB0ZXN0Q29tcGF0T3B0aW9uYWwoKSB0aHJvd3MgQnVuZGxlRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CgkJRHVtbXlDb250YWluZXJBZGFwdG9yIGFkYXB0b3IgPSBjcmVhdGVEdW1teUFkYXB0b3IoKTsKCQlNb2R1bGVDb250YWluZXIgY29udGFpbmVyID0gYWRhcHRvci5nZXRDb250YWluZXIoKTsKCQlNb2R1bGUgYjEgPSBpbnN0YWxsRHVtbXlNb2R1bGUoImNvbXBhdE9wdGlvbmFsMS5NRiIsICJiMSIsIGNvbnRhaW5lcik7CgkJTW9kdWxlIGIyID0gaW5zdGFsbER1bW15TW9kdWxlKCJjb21wYXRPcHRpb25hbDIuTUYiLCAiYjIiLCBjb250YWluZXIpOwoJCU1vZHVsZSBiMyA9IGluc3RhbGxEdW1teU1vZHVsZSgiY29tcGF0T3B0aW9uYWwzLk1GIiwgImIzIiwgY29udGFpbmVyKTsKCgkJU3RyaW5nIGIxQnVuZGxlUmVzb2x1dGlvbiA9IGIxLmdldEN1cnJlbnRSZXZpc2lvbigpLmdldFJlcXVpcmVtZW50cyhCdW5kbGVOYW1lc3BhY2UuQlVORExFX05BTUVTUEFDRSkuaXRlcmF0b3IoKS5uZXh0KCkuZ2V0RGlyZWN0aXZlcygpLmdldChOYW1lc3BhY2UuUkVRVUlSRU1FTlRfUkVTT0xVVElPTl9ESVJFQ1RJVkUpOwoJCVN0cmluZyBiMkJ1bmRsZVJlc29sdXRpb24gPSBiMi5nZXRDdXJyZW50UmV2aXNpb24oKS5nZXRSZXF1aXJlbWVudHMoQnVuZGxlTmFtZXNwYWNlLkJVTkRMRV9OQU1FU1BBQ0UpLml0ZXJhdG9yKCkubmV4dCgpLmdldERpcmVjdGl2ZXMoKS5nZXQoTmFtZXNwYWNlLlJFUVVJUkVNRU5UX1JFU09MVVRJT05fRElSRUNUSVZFKTsKCQlTdHJpbmcgYjNCdW5kbGVSZXNvbHV0aW9uID0gYjMuZ2V0Q3VycmVudFJldmlzaW9uKCkuZ2V0UmVxdWlyZW1lbnRzKEJ1bmRsZU5hbWVzcGFjZS5CVU5ETEVfTkFNRVNQQUNFKS5pdGVyYXRvcigpLm5leHQoKS5nZXREaXJlY3RpdmVzKCkuZ2V0KE5hbWVzcGFjZS5SRVFVSVJFTUVOVF9SRVNPTFVUSU9OX0RJUkVDVElWRSk7CgoJCVN0cmluZyBiMVBhY2thZ2VSZXNvbHV0aW9uID0gYjEuZ2V0Q3VycmVudFJldmlzaW9uKCkuZ2V0UmVxdWlyZW1lbnRzKFBhY2thZ2VOYW1lc3BhY2UuUEFDS0FHRV9OQU1FU1BBQ0UpLml0ZXJhdG9yKCkubmV4dCgpLmdldERpcmVjdGl2ZXMoKS5nZXQoTmFtZXNwYWNlLlJFUVVJUkVNRU5UX1JFU09MVVRJT05fRElSRUNUSVZFKTsKCQlTdHJpbmcgYjJQYWNrYWdlUmVzb2x1dGlvbiA9IGIyLmdldEN1cnJlbnRSZXZpc2lvbigpLmdldFJlcXVpcmVtZW50cyhQYWNrYWdlTmFtZXNwYWNlLlBBQ0tBR0VfTkFNRVNQQUNFKS5pdGVyYXRvcigpLm5leHQoKS5nZXREaXJlY3RpdmVzKCkuZ2V0KE5hbWVzcGFjZS5SRVFVSVJFTUVOVF9SRVNPTFVUSU9OX0RJUkVDVElWRSk7CgkJU3RyaW5nIGIzUGFja2FnZVJlc29sdXRpb24gPSBiMy5nZXRDdXJyZW50UmV2aXNpb24oKS5nZXRSZXF1aXJlbWVudHMoUGFja2FnZU5hbWVzcGFjZS5QQUNLQUdFX05BTUVTUEFDRSkuaXRlcmF0b3IoKS5uZXh0KCkuZ2V0RGlyZWN0aXZlcygpLmdldChOYW1lc3BhY2UuUkVRVUlSRU1FTlRfUkVTT0xVVElPTl9ESVJFQ1RJVkUpOwoKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJXcm9uZyByZXNvbHV0aW9uIGRpcmVjdGl2ZTogIiArIGIxLCBOYW1lc3BhY2UuUkVTT0xVVElPTl9PUFRJT05BTCwgYjFCdW5kbGVSZXNvbHV0aW9uKTsKCQlBc3NlcnQuYXNzZXJ0TnVsbCgiV3JvbmcgcmVzb2x1dGlvbiBkaXJlY3RpdmU6ICIsIGIyQnVuZGxlUmVzb2x1dGlvbik7CgkJQXNzZXJ0LmFzc2VydEVxdWFscygiV3JvbmcgcmVzb2x1dGlvbiBkaXJlY3RpdmU6ICIgKyBiMiwgTmFtZXNwYWNlLlJFU09MVVRJT05fT1BUSU9OQUwsIGIzQnVuZGxlUmVzb2x1dGlvbik7CgoJCUFzc2VydC5hc3NlcnRFcXVhbHMoIldyb25nIHJlc29sdXRpb24gZGlyZWN0aXZlOiAiICsgYjEsIE5hbWVzcGFjZS5SRVNPTFVUSU9OX09QVElPTkFMLCBiMVBhY2thZ2VSZXNvbHV0aW9uKTsKCQlBc3NlcnQuYXNzZXJ0TnVsbCgiV3JvbmcgcmVzb2x1dGlvbiBkaXJlY3RpdmU6ICIsIGIyUGFja2FnZVJlc29sdXRpb24pOwoJCUFzc2VydC5hc3NlcnRFcXVhbHMoIldyb25nIHJlc29sdXRpb24gZGlyZWN0aXZlOiAiICsgYjIsIE5hbWVzcGFjZS5SRVNPTFVUSU9OX09QVElPTkFMLCBiM1BhY2thZ2VSZXNvbHV0aW9uKTsKCX0KCglAVGVzdAoJcHVibGljIHZvaWQgdGVzdENvbXBhdFByb3ZpZGVQYWNrYWdlKCkgdGhyb3dzIEJ1bmRsZUV4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewoJCUR1bW15Q29udGFpbmVyQWRhcHRvciBhZGFwdG9yID0gY3JlYXRlRHVtbXlBZGFwdG9yKCk7CgkJTW9kdWxlQ29udGFpbmVyIGNvbnRhaW5lciA9IGFkYXB0b3IuZ2V0Q29udGFpbmVyKCk7CgkJTW9kdWxlIGIxID0gaW5zdGFsbER1bW15TW9kdWxlKCJjb21wYXRQcm92aWRlUGFja2FnZTEuTUYiLCAiYjEiLCBjb250YWluZXIpOwoKCQlMaXN0PE1vZHVsZUNhcGFiaWxpdHk+IHBhY2thZ2VDYXBzID0gYjEuZ2V0Q3VycmVudFJldmlzaW9uKCkuZ2V0TW9kdWxlQ2FwYWJpbGl0aWVzKFBhY2thZ2VOYW1lc3BhY2UuUEFDS0FHRV9OQU1FU1BBQ0UpOwoJCUFzc2VydC5hc3NlcnRFcXVhbHMoIldyb25nIG51bWJlciBvZiBleHBvcnRzIiwgNSwgcGFja2FnZUNhcHMuc2l6ZSgpKTsKCgkJQXNzZXJ0LmFzc2VydEVxdWFscygiV3JvbmcgcGFja2FnZSBuYW1lLiIsICJmb28iLCBwYWNrYWdlQ2Fwcy5nZXQoMCkuZ2V0QXR0cmlidXRlcygpLmdldChQYWNrYWdlTmFtZXNwYWNlLlBBQ0tBR0VfTkFNRVNQQUNFKSk7CgkJQXNzZXJ0LmFzc2VydEVxdWFscygiV3JvbmcgcGFja2FnZSBuYW1lLiIsICJmYWEiLCBwYWNrYWdlQ2Fwcy5nZXQoMSkuZ2V0QXR0cmlidXRlcygpLmdldChQYWNrYWdlTmFtZXNwYWNlLlBBQ0tBR0VfTkFNRVNQQUNFKSk7CgkJQXNzZXJ0LmFzc2VydEVxdWFscygiV3JvbmcgcGFja2FnZSBuYW1lLiIsICJiYXIiLCBwYWNrYWdlQ2Fwcy5nZXQoMikuZ2V0QXR0cmlidXRlcygpLmdldChQYWNrYWdlTmFtZXNwYWNlLlBBQ0tBR0VfTkFNRVNQQUNFKSk7CgkJQXNzZXJ0LmFzc2VydEVxdWFscygiV3JvbmcgcGFja2FnZSBuYW1lLiIsICJiYXoiLCBwYWNrYWdlQ2Fwcy5nZXQoMykuZ2V0QXR0cmlidXRlcygpLmdldChQYWNrYWdlTmFtZXNwYWNlLlBBQ0tBR0VfTkFNRVNQQUNFKSk7CgkJQXNzZXJ0LmFzc2VydEVxdWFscygiV3JvbmcgcGFja2FnZSBuYW1lLiIsICJiaXoiLCBwYWNrYWdlQ2Fwcy5nZXQoNCkuZ2V0QXR0cmlidXRlcygpLmdldChQYWNrYWdlTmFtZXNwYWNlLlBBQ0tBR0VfTkFNRVNQQUNFKSk7Cgl9CgoJQFRlc3QKCXB1YmxpYyB2b2lkIHRlc3RCdWc0NTcxMTgoKSB0aHJvd3MgQnVuZGxlRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CgkJRHVtbXlDb250YWluZXJBZGFwdG9yIGFkYXB0b3IgPSBjcmVhdGVEdW1teUFkYXB0b3IoKTsKCQlNb2R1bGVDb250YWluZXIgY29udGFpbmVyID0gYWRhcHRvci5nZXRDb250YWluZXIoKTsKCgkJTW9kdWxlIHN5c3RlbUJ1bmRsZSA9IGluc3RhbGxEdW1teU1vZHVsZSgic3lzdGVtLmJ1bmRsZS5NRiIsIENvbnN0YW50cy5TWVNURU1fQlVORExFX0xPQ0FUSU9OLCBjb250YWluZXIpOwoKCQljb250YWluZXIucmVzb2x2ZShBcnJheXMuYXNMaXN0KHN5c3RlbUJ1bmRsZSksIHRydWUpOwoJCU1vZHVsZSBlID0gaW5zdGFsbER1bW15TW9kdWxlKCJidWc0NTcxMTguZS5NRiIsICJlIiwgY29udGFpbmVyKTsKCQlNb2R1bGUgYSA9IGluc3RhbGxEdW1teU1vZHVsZSgiYnVnNDU3MTE4LmEuTUYiLCAiYSIsIGNvbnRhaW5lcik7CgkJTW9kdWxlIGIgPSBpbnN0YWxsRHVtbXlNb2R1bGUoImJ1ZzQ1NzExOC5iLk1GIiwgImIiLCBjb250YWluZXIpOwoJCU1vZHVsZSBjID0gaW5zdGFsbER1bW15TW9kdWxlKCJidWc0NTcxMTguYy5NRiIsICJjIiwgY29udGFpbmVyKTsKCQlNb2R1bGUgZCA9IGluc3RhbGxEdW1teU1vZHVsZSgiYnVnNDU3MTE4LmQuTUYiLCAiZCIsIGNvbnRhaW5lcik7CgoJCWluc3RhbGxEdW1teU1vZHVsZSgiYnVnNDU3MTE4LmEyLk1GIiwgImEyIiwgY29udGFpbmVyKTsKCQlpbnN0YWxsRHVtbXlNb2R1bGUoImJ1ZzQ1NzExOC5iMi5NRiIsICJiMiIsIGNvbnRhaW5lcik7CgkJaW5zdGFsbER1bW15TW9kdWxlKCJidWc0NTcxMTguYzIuTUYiLCAiYzIiLCBjb250YWluZXIpOwoJCWluc3RhbGxEdW1teU1vZHVsZSgiYnVnNDU3MTE4LmQyLk1GIiwgImQyIiwgY29udGFpbmVyKTsKCgkJY29udGFpbmVyLnJlc29sdmUobnVsbCwgdHJ1ZSk7CgoJCUFzc2VydC5hc3NlcnRFcXVhbHMoImUgc2hvdWxkIHJlc29sdmUuIiwgU3RhdGUuUkVTT0xWRUQsIGUuZ2V0U3RhdGUoKSk7CgkJQXNzZXJ0LmFzc2VydEVxdWFscygiYSBzaG91bGQgcmVzb2x2ZS4iLCBTdGF0ZS5SRVNPTFZFRCwgYS5nZXRTdGF0ZSgpKTsKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJiIHNob3VsZCByZXNvbHZlLiIsIFN0YXRlLlJFU09MVkVELCBiLmdldFN0YXRlKCkpOwoJCUFzc2VydC5hc3NlcnRFcXVhbHMoImMgc2hvdWxkIHJlc29sdmUuIiwgU3RhdGUuUkVTT0xWRUQsIGMuZ2V0U3RhdGUoKSk7CgkJQXNzZXJ0LmFzc2VydEVxdWFscygiZCBzaG91bGQgcmVzb2x2ZS4iLCBTdGF0ZS5SRVNPTFZFRCwgZC5nZXRTdGF0ZSgpKTsKCgkJTGlzdDxNb2R1bGVXaXJlPiBidW5kbGVXaXJlcyA9IGUuZ2V0Q3VycmVudFJldmlzaW9uKCkuZ2V0V2lyaW5nKCkuZ2V0UmVxdWlyZWRNb2R1bGVXaXJlcyhCdW5kbGVOYW1lc3BhY2UuQlVORExFX05BTUVTUEFDRSk7CgkJQXNzZXJ0LmFzc2VydEVxdWFscygiV3JvbmcgbnVtYmVyIG9mIGJ1bmRsZSB3aXJlczogIiArIGJ1bmRsZVdpcmVzLCAxLCBidW5kbGVXaXJlcy5zaXplKCkpOwoJCUFzc2VydC5hc3NlcnRFcXVhbHMoIldyb25nIGJ1bmRsZSBwcm92aWRlciIsIGEuZ2V0Q3VycmVudFJldmlzaW9uKCksIGJ1bmRsZVdpcmVzLmdldCgwKS5nZXRQcm92aWRlcigpKTsKCX0KCglAVGVzdAoJcHVibGljIHZvaWQgdGVzdEJhZE5hdGl2ZUNvZGUoKSB0aHJvd3MgSU9FeGNlcHRpb24gewoJCXRyeSB7CgkJCU9TR2lNYW5pZmVzdEJ1aWxkZXJGYWN0b3J5LmNyZWF0ZUJ1aWxkZXIoZ2V0TWFuaWZlc3QoImJhZC5uYXRpdmUuY29kZS5NRiIpKTsKCQl9IGNhdGNoIChCdW5kbGVFeGNlcHRpb24gZSkgewoJCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJXcm9uZyBleGNlcHRpb24gdHlwZS4iLCBCdW5kbGVFeGNlcHRpb24uTUFOSUZFU1RfRVJST1IsIGUuZ2V0VHlwZSgpKTsKCQl9CgoJfQoKCUBUZXN0CglwdWJsaWMgdm9pZCB0ZXN0TmF0aXZlV2l0aEZpbHRlckNoYXJzKCkgdGhyb3dzIEJ1bmRsZUV4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewoJCUR1bW15Q29udGFpbmVyQWRhcHRvciBhZGFwdG9yID0gY3JlYXRlRHVtbXlBZGFwdG9yKCk7CgkJTW9kdWxlQ29udGFpbmVyIGNvbnRhaW5lciA9IGFkYXB0b3IuZ2V0Q29udGFpbmVyKCk7CgoJCS8vIGluc3RhbGwgdGhlIHN5c3RlbS5idW5kbGUKCQlTdHJpbmcgZXh0cmFDYXBhYmlsaXRpZXMgPSAib3NnaS5uYXRpdmU7IG9zZ2kubmF0aXZlLm9zbmFtZT1cIldpbmRvd3MgTlQgKHVua25vd24pXCIiOwoJCU1vZHVsZSBzeXN0ZW1CdW5kbGUgPSBpbnN0YWxsRHVtbXlNb2R1bGUoInN5c3RlbS5idW5kbGUuTUYiLCBDb25zdGFudHMuU1lTVEVNX0JVTkRMRV9MT0NBVElPTiwgQ29uc3RhbnRzLlNZU1RFTV9CVU5ETEVfU1lNQk9MSUNOQU1FLCBudWxsLCBleHRyYUNhcGFiaWxpdGllcywgY29udGFpbmVyKTsKCQlSZXNvbHV0aW9uUmVwb3J0IHJlcG9ydCA9IGNvbnRhaW5lci5yZXNvbHZlKEFycmF5cy5hc0xpc3Qoc3lzdGVtQnVuZGxlKSwgdHJ1ZSk7CgkJQXNzZXJ0LmFzc2VydE51bGwoIkZhaWxlZCB0byByZXNvbHZlIHN5c3RlbS5idW5kbGUuIiwgcmVwb3J0LmdldFJlc29sdXRpb25FeGNlcHRpb24oKSk7CgoJCS8vIGluc3RhbGwgYnVuZGxlIHdpdGggQnVuZGxlLU5hdGl2ZUNvZGUKCQlNYXA8U3RyaW5nLCBTdHJpbmc+IG5hdGl2ZUNvZGVNYW5pZmVzdCA9IG5ldyBIYXNoTWFwPFN0cmluZywgU3RyaW5nPigpOwoJCW5hdGl2ZUNvZGVNYW5pZmVzdC5wdXQoQ29uc3RhbnRzLkJVTkRMRV9NQU5JRkVTVFZFUlNJT04sICIyIik7CgkJbmF0aXZlQ29kZU1hbmlmZXN0LnB1dChDb25zdGFudHMuQlVORExFX1NZTUJPTElDTkFNRSwgImltcG9ydGVyIik7CgkJbmF0aXZlQ29kZU1hbmlmZXN0LnB1dChDb25zdGFudHMuQlVORExFX05BVElWRUNPREUsIC8vIAoJCQkJIi9saWIvbXlsaWIuZGxsOyBvc25hbWU9XCJ3aW4zMlwiOyBvc25hbWU9XCJXaW5kb3dzIE5UICh1bmtub3duKVwiLCIgKyAvLwoJCQkJCQkiL2xpYi9teWxpYi5saWI7IG9zbmFtZT1cIkxpbnV4XCIiKTsKCgkJTW9kdWxlIG5hdGl2ZUNvZGVNb2R1bGUgPSBpbnN0YWxsRHVtbXlNb2R1bGUobmF0aXZlQ29kZU1hbmlmZXN0LCAibmF0aXZlQ29kZUJ1bmRsZSIsIGNvbnRhaW5lcik7CgoJCS8vIHVuc2F0aXNmaWVkIG9wdGlvbmFsIGFuZCBkeW5hbWljIGltcG9ydHMgZG8gbm90IGZhaWwgYSByZXNvbHZlLiAKCQlyZXBvcnQgPSBjb250YWluZXIucmVzb2x2ZShBcnJheXMuYXNMaXN0KG5hdGl2ZUNvZGVNb2R1bGUpLCB0cnVlKTsKCQlBc3NlcnQuYXNzZXJ0TnVsbCgiRmFpbGVkIHRvIHJlc29sdmUgbmF0aXZlQ29kZUJ1bmRsZS4iLCByZXBvcnQuZ2V0UmVzb2x1dGlvbkV4Y2VwdGlvbigpKTsKCX0KCglAVGVzdAoJcHVibGljIHZvaWQgdGVzdFVURjhMaW5lQ29udGludWF0aW9uKCkgdGhyb3dzIEJ1bmRsZUV4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewoJCUR1bW15Q29udGFpbmVyQWRhcHRvciBhZGFwdG9yID0gY3JlYXRlRHVtbXlBZGFwdG9yKCk7CgkJTW9kdWxlQ29udGFpbmVyIGNvbnRhaW5lciA9IGFkYXB0b3IuZ2V0Q29udGFpbmVyKCk7CgkJU3RyaW5nIHV0ZlN0cmluZyA9ICJhLndpdGgu6S5tdWx0aWJ5dGUiOwoJCXdoaWxlICh1dGZTdHJpbmcuZ2V0Qnl0ZXMoIlVURjgiKS5sZW5ndGggPCA1MDApIHsKCQkJTWFwPFN0cmluZywgU3RyaW5nPiBtYW5pZmVzdCA9IGdldFVURk1hbmlmZXN0KHV0ZlN0cmluZyk7CgkJCU1vZHVsZSB0ZXN0TW9kdWxlID0gaW5zdGFsbER1bW15TW9kdWxlKG1hbmlmZXN0LCBtYW5pZmVzdC5nZXQoQ29uc3RhbnRzLkJVTkRMRV9TWU1CT0xJQ05BTUUpLCBjb250YWluZXIpOwoJCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJXcm9uZyBibnMgZm9yIHRoZSBidW5kbGUuIiwgdXRmU3RyaW5nLCB0ZXN0TW9kdWxlLmdldEN1cnJlbnRSZXZpc2lvbigpLmdldFN5bWJvbGljTmFtZSgpKTsKCgkJCU1vZHVsZUNhcGFiaWxpdHkgZXhwb3J0UGFja2FnZSA9IHRlc3RNb2R1bGUuZ2V0Q3VycmVudFJldmlzaW9uKCkuZ2V0TW9kdWxlQ2FwYWJpbGl0aWVzKFBhY2thZ2VOYW1lc3BhY2UuUEFDS0FHRV9OQU1FU1BBQ0UpLmdldCgwKTsKCQkJTW9kdWxlUmVxdWlyZW1lbnQgaW1wb3J0UGFja2FnZSA9IHRlc3RNb2R1bGUuZ2V0Q3VycmVudFJldmlzaW9uKCkuZ2V0TW9kdWxlUmVxdWlyZW1lbnRzKFBhY2thZ2VOYW1lc3BhY2UuUEFDS0FHRV9OQU1FU1BBQ0UpLmdldCgwKTsKCgkJCVN0cmluZyBhY3R1YWxQYWNrYWdlTmFtZSA9IChTdHJpbmcpIGV4cG9ydFBhY2thZ2UuZ2V0QXR0cmlidXRlcygpLmdldChQYWNrYWdlTmFtZXNwYWNlLlBBQ0tBR0VfTkFNRVNQQUNFKTsKCQkJQXNzZXJ0LmFzc2VydEVxdWFscygiV3JvbmcgZXhwb3J0ZWQgcGFja2FnZSBuYW1lLiIsIHV0ZlN0cmluZywgYWN0dWFsUGFja2FnZU5hbWUpOwoKCQkJQXNzZXJ0LmFzc2VydFRydWUoImltcG9ydCBkb2VzIG5vdCBtYXRjaCBleHBvcnQ6ICIgKyBpbXBvcnRQYWNrYWdlLCBpbXBvcnRQYWNrYWdlLm1hdGNoZXMoZXhwb3J0UGFja2FnZSkpOwoKCQkJdXRmU3RyaW5nID0gImEiICsgdXRmU3RyaW5nOwoJCX0KCX0KCglAVGVzdAoJcHVibGljIHZvaWQgdGVzdER5bmFtaWNXaXRoT3B0aW9uYWxJbXBvcnQoKSB0aHJvd3MgQnVuZGxlRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CgkJRHVtbXlDb250YWluZXJBZGFwdG9yIGFkYXB0b3IgPSBjcmVhdGVEdW1teUFkYXB0b3IoKTsKCQlNb2R1bGVDb250YWluZXIgY29udGFpbmVyID0gYWRhcHRvci5nZXRDb250YWluZXIoKTsKCgkJLy8gaW5zdGFsbCB0aGUgc3lzdGVtLmJ1bmRsZQoJCU1vZHVsZSBzeXN0ZW1CdW5kbGUgPSBpbnN0YWxsRHVtbXlNb2R1bGUoInN5c3RlbS5idW5kbGUuTUYiLCBDb25zdGFudHMuU1lTVEVNX0JVTkRMRV9MT0NBVElPTiwgQ29uc3RhbnRzLlNZU1RFTV9CVU5ETEVfU1lNQk9MSUNOQU1FLCBudWxsLCBudWxsLCBjb250YWluZXIpOwoJCVJlc29sdXRpb25SZXBvcnQgcmVwb3J0ID0gY29udGFpbmVyLnJlc29sdmUoQXJyYXlzLmFzTGlzdChzeXN0ZW1CdW5kbGUpLCB0cnVlKTsKCQlBc3NlcnQuYXNzZXJ0TnVsbCgiRmFpbGVkIHRvIHJlc29sdmUgc3lzdGVtLmJ1bmRsZS4iLCByZXBvcnQuZ2V0UmVzb2x1dGlvbkV4Y2VwdGlvbigpKTsKCgkJLy8gaW5zdGFsbCBhbiBpbXBvcnRlcgoJCU1hcDxTdHJpbmcsIFN0cmluZz4gb3B0aW9uYWxJbXBvcnRlck1hbmlmZXN0ID0gbmV3IEhhc2hNYXA8U3RyaW5nLCBTdHJpbmc+KCk7CgkJb3B0aW9uYWxJbXBvcnRlck1hbmlmZXN0LnB1dChDb25zdGFudHMuQlVORExFX01BTklGRVNUVkVSU0lPTiwgIjIiKTsKCQlvcHRpb25hbEltcG9ydGVyTWFuaWZlc3QucHV0KENvbnN0YW50cy5CVU5ETEVfU1lNQk9MSUNOQU1FLCAiaW1wb3J0ZXIiKTsKCQlvcHRpb25hbEltcG9ydGVyTWFuaWZlc3QucHV0KENvbnN0YW50cy5JTVBPUlRfUEFDS0FHRSwgImV4cG9ydGVyOyByZXNvbHV0aW9uOj1vcHRpb25hbCIpOwoJCW9wdGlvbmFsSW1wb3J0ZXJNYW5pZmVzdC5wdXQoQ29uc3RhbnRzLkRZTkFNSUNJTVBPUlRfUEFDS0FHRSwgImV4cG9ydGVyIik7CgkJTW9kdWxlIG9wdGlvbmFsSW1wb3J0ZXJNb2R1bGUgPSBpbnN0YWxsRHVtbXlNb2R1bGUob3B0aW9uYWxJbXBvcnRlck1hbmlmZXN0LCAib3B0aW9uYWxJbXBvcnRlciIsIGNvbnRhaW5lcik7CgoJCS8vIHVuc2F0aXNmaWVkIG9wdGlvbmFsIGFuZCBkeW5hbWljIGltcG9ydHMgZG8gbm90IGZhaWwgYSByZXNvbHZlLiAKCQlyZXBvcnQgPSBjb250YWluZXIucmVzb2x2ZShBcnJheXMuYXNMaXN0KG9wdGlvbmFsSW1wb3J0ZXJNb2R1bGUpLCB0cnVlKTsKCQlBc3NlcnQuYXNzZXJ0TnVsbCgiRmFpbGVkIHRvIHJlc29sdmUgc3lzdGVtLmJ1bmRsZS4iLCByZXBvcnQuZ2V0UmVzb2x1dGlvbkV4Y2VwdGlvbigpKTsKCgkJLy9keW5hbWljIGFuZCBvcHRpb25hbCBpbXBvcnRzIGFyZSBzYW1lLiBPcHRpb25hbCBpbXBvcnQgaXMgbm90IHNhdGlzZmllZCB3ZSBzaG91bGQgb25seSBzZWUgdGhlIGR5bmFtaWMgaW1wb3J0CgkJTGlzdDxCdW5kbGVSZXF1aXJlbWVudD4gaW1wb3J0UmVxc0xpc3QgPSBvcHRpb25hbEltcG9ydGVyTW9kdWxlLmdldEN1cnJlbnRSZXZpc2lvbigpLmdldFdpcmluZygpLmdldFJlcXVpcmVtZW50cyhQYWNrYWdlTmFtZXNwYWNlLlBBQ0tBR0VfTkFNRVNQQUNFKTsKCQlhc3NlcnRFcXVhbHMoIldyb25nIG51bWJlciBvZiBpbXBvcnRzLiIsIDEsIGltcG9ydFJlcXNMaXN0LnNpemUoKSk7CgkJYXNzZXJ0RXF1YWxzKCJJbXBvcnQgd2FzIG5vdCBkeW5hbWljIiwgUGFja2FnZU5hbWVzcGFjZS5SRVNPTFVUSU9OX0RZTkFNSUMsIGltcG9ydFJlcXNMaXN0LmdldCgwKS5nZXREaXJlY3RpdmVzKCkuZ2V0KE5hbWVzcGFjZS5SRVFVSVJFTUVOVF9SRVNPTFVUSU9OX0RJUkVDVElWRSkpOwoKCQkvLyBpbnN0YWxsIGEgZXhwb3J0ZXIgdG8gc2F0aXNmeSBleGlzdGluZyBvcHRpb25hbCBpbXBvcnQKCQlNYXA8U3RyaW5nLCBTdHJpbmc+IGV4cG9ydGVyTWFuaWZlc3QgPSBuZXcgSGFzaE1hcDxTdHJpbmcsIFN0cmluZz4oKTsKCQlleHBvcnRlck1hbmlmZXN0LnB1dChDb25zdGFudHMuQlVORExFX01BTklGRVNUVkVSU0lPTiwgIjIiKTsKCQlleHBvcnRlck1hbmlmZXN0LnB1dChDb25zdGFudHMuQlVORExFX1NZTUJPTElDTkFNRSwgImV4cG9ydGVyIik7CgkJZXhwb3J0ZXJNYW5pZmVzdC5wdXQoQ29uc3RhbnRzLkVYUE9SVF9QQUNLQUdFLCAiZXhwb3J0ZXIiKTsKCQlpbnN0YWxsRHVtbXlNb2R1bGUoZXhwb3J0ZXJNYW5pZmVzdCwgImV4cG9ydGVyIiwgY29udGFpbmVyKTsKCgkJTW9kdWxlV2lyZSBkeW5hbWljV2lyZSA9IGNvbnRhaW5lci5yZXNvbHZlRHluYW1pYygiZXhwb3J0ZXIiLCBvcHRpb25hbEltcG9ydGVyTW9kdWxlLmdldEN1cnJlbnRSZXZpc2lvbigpKTsKCQlBc3NlcnQuYXNzZXJ0Tm90TnVsbCgiRXhwZWN0ZWQgdG8gZmluZCBhIGR5bmFtaWMgd2lyZS4iLCBkeW5hbWljV2lyZSk7CgoJCS8vIHJlLXJlc29sdmUgaW1wb3J0ZXIKCQljb250YWluZXIucmVmcmVzaChDb2xsZWN0aW9ucy5zaW5nbGV0b24ob3B0aW9uYWxJbXBvcnRlck1vZHVsZSkpOwoKCQlyZXBvcnQgPSBjb250YWluZXIucmVzb2x2ZShBcnJheXMuYXNMaXN0KG9wdGlvbmFsSW1wb3J0ZXJNb2R1bGUpLCB0cnVlKTsKCQlBc3NlcnQuYXNzZXJ0TnVsbCgiRmFpbGVkIHRvIHJlc29sdmUgc3lzdGVtLmJ1bmRsZS4iLCByZXBvcnQuZ2V0UmVzb2x1dGlvbkV4Y2VwdGlvbigpKTsKCgkJaW1wb3J0UmVxc0xpc3QgPSBvcHRpb25hbEltcG9ydGVyTW9kdWxlLmdldEN1cnJlbnRSZXZpc2lvbigpLmdldFdpcmluZygpLmdldFJlcXVpcmVtZW50cyhQYWNrYWdlTmFtZXNwYWNlLlBBQ0tBR0VfTkFNRVNQQUNFKTsKCQlhc3NlcnRFcXVhbHMoIldyb25nIG51bWJlciBvZiBpbXBvcnRzLiIsIDIsIGltcG9ydFJlcXNMaXN0LnNpemUoKSk7Cgl9CgoJQFRlc3QKCXB1YmxpYyB2b2lkIHRlc3REeW5hbWljV2l0aEV4cG9ydCgpIHRocm93cyBCdW5kbGVFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKCQlEdW1teUNvbnRhaW5lckFkYXB0b3IgYWRhcHRvciA9IGNyZWF0ZUR1bW15QWRhcHRvcigpOwoJCU1vZHVsZUNvbnRhaW5lciBjb250YWluZXIgPSBhZGFwdG9yLmdldENvbnRhaW5lcigpOwoKCQkvLyBpbnN0YWxsIHRoZSBzeXN0ZW0uYnVuZGxlCgkJTW9kdWxlIHN5c3RlbUJ1bmRsZSA9IGluc3RhbGxEdW1teU1vZHVsZSgic3lzdGVtLmJ1bmRsZS5NRiIsIENvbnN0YW50cy5TWVNURU1fQlVORExFX0xPQ0FUSU9OLCBDb25zdGFudHMuU1lTVEVNX0JVTkRMRV9TWU1CT0xJQ05BTUUsIG51bGwsIG51bGwsIGNvbnRhaW5lcik7CgkJUmVzb2x1dGlvblJlcG9ydCByZXBvcnQgPSBjb250YWluZXIucmVzb2x2ZShBcnJheXMuYXNMaXN0KHN5c3RlbUJ1bmRsZSksIHRydWUpOwoJCUFzc2VydC5hc3NlcnROdWxsKCJGYWlsZWQgdG8gcmVzb2x2ZSBzeXN0ZW0uYnVuZGxlLiIsIHJlcG9ydC5nZXRSZXNvbHV0aW9uRXhjZXB0aW9uKCkpOwoKCQkvLyBpbnN0YWxsIGFuIGltcG9ydGVyCgkJTWFwPFN0cmluZywgU3RyaW5nPiBvcHRpb25hbEltcG9ydGVyTWFuaWZlc3QgPSBuZXcgSGFzaE1hcDxTdHJpbmcsIFN0cmluZz4oKTsKCQlvcHRpb25hbEltcG9ydGVyTWFuaWZlc3QucHV0KENvbnN0YW50cy5CVU5ETEVfTUFOSUZFU1RWRVJTSU9OLCAiMiIpOwoJCW9wdGlvbmFsSW1wb3J0ZXJNYW5pZmVzdC5wdXQoQ29uc3RhbnRzLkJVTkRMRV9TWU1CT0xJQ05BTUUsICJpbXBvcnRlciIpOwoJCW9wdGlvbmFsSW1wb3J0ZXJNYW5pZmVzdC5wdXQoQ29uc3RhbnRzLkVYUE9SVF9QQUNLQUdFLCAiZXhwb3J0ZXIiKTsKCQlvcHRpb25hbEltcG9ydGVyTWFuaWZlc3QucHV0KENvbnN0YW50cy5EWU5BTUlDSU1QT1JUX1BBQ0tBR0UsICJleHBvcnRlciIpOwoJCU1vZHVsZSBvcHRpb25hbEltcG9ydGVyTW9kdWxlID0gaW5zdGFsbER1bW15TW9kdWxlKG9wdGlvbmFsSW1wb3J0ZXJNYW5pZmVzdCwgIm9wdGlvbmFsSW1wb3J0ZXIiLCBjb250YWluZXIpOwoKCQkvLyB1bnNhdGlzZmllZCBvcHRpb25hbCBhbmQgZHluYW1pYyBpbXBvcnRzIGRvIG5vdCBmYWlsIGEgcmVzb2x2ZS4gCgkJcmVwb3J0ID0gY29udGFpbmVyLnJlc29sdmUoQXJyYXlzLmFzTGlzdChvcHRpb25hbEltcG9ydGVyTW9kdWxlKSwgdHJ1ZSk7CgkJQXNzZXJ0LmFzc2VydE51bGwoIkZhaWxlZCB0byByZXNvbHZlIHN5c3RlbS5idW5kbGUuIiwgcmVwb3J0LmdldFJlc29sdXRpb25FeGNlcHRpb24oKSk7CgoJCS8vZHluYW1pYyBhbmQgb3B0aW9uYWwgaW1wb3J0cyBhcmUgc2FtZS4gT3B0aW9uYWwgaW1wb3J0IGlzIG5vdCBzYXRpc2ZpZWQgd2Ugc2hvdWxkIG9ubHkgc2VlIHRoZSBkeW5hbWljIGltcG9ydAoJCUxpc3Q8QnVuZGxlUmVxdWlyZW1lbnQ+IGltcG9ydFJlcXNMaXN0ID0gb3B0aW9uYWxJbXBvcnRlck1vZHVsZS5nZXRDdXJyZW50UmV2aXNpb24oKS5nZXRXaXJpbmcoKS5nZXRSZXF1aXJlbWVudHMoUGFja2FnZU5hbWVzcGFjZS5QQUNLQUdFX05BTUVTUEFDRSk7CgkJYXNzZXJ0RXF1YWxzKCJXcm9uZyBudW1iZXIgb2YgaW1wb3J0cy4iLCAxLCBpbXBvcnRSZXFzTGlzdC5zaXplKCkpOwoJCWFzc2VydEVxdWFscygiSW1wb3J0IHdhcyBub3QgZHluYW1pYyIsIFBhY2thZ2VOYW1lc3BhY2UuUkVTT0xVVElPTl9EWU5BTUlDLCBpbXBvcnRSZXFzTGlzdC5nZXQoMCkuZ2V0RGlyZWN0aXZlcygpLmdldChOYW1lc3BhY2UuUkVRVUlSRU1FTlRfUkVTT0xVVElPTl9ESVJFQ1RJVkUpKTsKCgkJTW9kdWxlV2lyZSBkeW5hbWljV2lyZSA9IGNvbnRhaW5lci5yZXNvbHZlRHluYW1pYygiZXhwb3J0ZXIiLCBvcHRpb25hbEltcG9ydGVyTW9kdWxlLmdldEN1cnJlbnRSZXZpc2lvbigpKTsKCQlBc3NlcnQuYXNzZXJ0TnVsbCgiRXhwZWN0ZWQgbm8gZHluYW1pYyB3aXJlLiIsIGR5bmFtaWNXaXJlKTsKCX0KCglAVGVzdAoJcHVibGljIHZvaWQgdGVzdFN1YnN0aXR1dGFibGVFeHBvcnQoKSB0aHJvd3MgQnVuZGxlRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CgkJRHVtbXlDb250YWluZXJBZGFwdG9yIGFkYXB0b3IgPSBjcmVhdGVEdW1teUFkYXB0b3IoKTsKCQlNb2R1bGVDb250YWluZXIgY29udGFpbmVyID0gYWRhcHRvci5nZXRDb250YWluZXIoKTsKCgkJLy8gaW5zdGFsbCB0aGUgc3lzdGVtLmJ1bmRsZQoJCU1vZHVsZSBzeXN0ZW1CdW5kbGUgPSBpbnN0YWxsRHVtbXlNb2R1bGUoInN5c3RlbS5idW5kbGUuTUYiLCBDb25zdGFudHMuU1lTVEVNX0JVTkRMRV9MT0NBVElPTiwgQ29uc3RhbnRzLlNZU1RFTV9CVU5ETEVfU1lNQk9MSUNOQU1FLCBudWxsLCBudWxsLCBjb250YWluZXIpOwoJCVJlc29sdXRpb25SZXBvcnQgcmVwb3J0ID0gY29udGFpbmVyLnJlc29sdmUoQXJyYXlzLmFzTGlzdChzeXN0ZW1CdW5kbGUpLCB0cnVlKTsKCQlBc3NlcnQuYXNzZXJ0TnVsbCgiRmFpbGVkIHRvIHJlc29sdmUgc3lzdGVtLmJ1bmRsZS4iLCByZXBvcnQuZ2V0UmVzb2x1dGlvbkV4Y2VwdGlvbigpKTsKCgkJLy8gaW5zdGFsbCBhbiBleHBvcnRlciB3aXRoIHN1YnN0aXR1dGFibGUgZXhwb3J0LgoJCU1hcDxTdHJpbmcsIFN0cmluZz4gZXhwb3J0ZXJNYW5pZmVzdCA9IG5ldyBIYXNoTWFwPFN0cmluZywgU3RyaW5nPigpOwoJCWV4cG9ydGVyTWFuaWZlc3QucHV0KENvbnN0YW50cy5CVU5ETEVfTUFOSUZFU1RWRVJTSU9OLCAiMiIpOwoJCWV4cG9ydGVyTWFuaWZlc3QucHV0KENvbnN0YW50cy5CVU5ETEVfU1lNQk9MSUNOQU1FLCAiZXhwb3J0ZXIiKTsKCQlleHBvcnRlck1hbmlmZXN0LnB1dChDb25zdGFudHMuRVhQT1JUX1BBQ0tBR0UsICJleHBvcnRlciIpOwoJCWV4cG9ydGVyTWFuaWZlc3QucHV0KENvbnN0YW50cy5JTVBPUlRfUEFDS0FHRSwgImV4cG9ydGVyIik7CgkJTW9kdWxlIG1vZHVsZVN1YnNFeHBvcnQgPSBpbnN0YWxsRHVtbXlNb2R1bGUoZXhwb3J0ZXJNYW5pZmVzdCwgImV4cG9ydGVyIiwgY29udGFpbmVyKTsKCQlyZXBvcnQgPSBjb250YWluZXIucmVzb2x2ZShBcnJheXMuYXNMaXN0KG1vZHVsZVN1YnNFeHBvcnQpLCB0cnVlKTsKCQlBc3NlcnQuYXNzZXJ0TnVsbCgiRmFpbGVkIHRvIHJlc29sdmUiLCByZXBvcnQuZ2V0UmVzb2x1dGlvbkV4Y2VwdGlvbigpKTsKCQlMaXN0PEJ1bmRsZVJlcXVpcmVtZW50PiByZXFzID0gbW9kdWxlU3Vic0V4cG9ydC5nZXRDdXJyZW50UmV2aXNpb24oKS5nZXRXaXJpbmcoKS5nZXRSZXF1aXJlbWVudHMoUGFja2FnZU5hbWVzcGFjZS5QQUNLQUdFX05BTUVTUEFDRSk7CgkJYXNzZXJ0RXF1YWxzKCJXcm9uZyBudW1iZXIgb2YgaW1wb3J0cy4iLCAwLCByZXFzLnNpemUoKSk7CgoJCWNvbnRhaW5lci51bmluc3RhbGwobW9kdWxlU3Vic0V4cG9ydCk7CgoJCWV4cG9ydGVyTWFuaWZlc3QgPSBuZXcgSGFzaE1hcDxTdHJpbmcsIFN0cmluZz4oKTsKCQlleHBvcnRlck1hbmlmZXN0LnB1dChDb25zdGFudHMuQlVORExFX01BTklGRVNUVkVSU0lPTiwgIjIiKTsKCQlleHBvcnRlck1hbmlmZXN0LnB1dChDb25zdGFudHMuQlVORExFX1NZTUJPTElDTkFNRSwgInN1YnN0aXR1dGFibGVFeHBvcnRlciIpOwoJCWV4cG9ydGVyTWFuaWZlc3QucHV0KENvbnN0YW50cy5FWFBPUlRfUEFDS0FHRSwgImV4cG9ydGVyIik7CgkJZXhwb3J0ZXJNYW5pZmVzdC5wdXQoQ29uc3RhbnRzLklNUE9SVF9QQUNLQUdFLCAiZXhwb3J0ZXI7IHBpY2ttZT10cnVlIik7CgoJCW1vZHVsZVN1YnNFeHBvcnQgPSBpbnN0YWxsRHVtbXlNb2R1bGUoZXhwb3J0ZXJNYW5pZmVzdCwgInN1YnN0aXR1dGFibGVFeHBvcnRlciIsIGNvbnRhaW5lcik7CgoJCWV4cG9ydGVyTWFuaWZlc3QgPSBuZXcgSGFzaE1hcDxTdHJpbmcsIFN0cmluZz4oKTsKCQlleHBvcnRlck1hbmlmZXN0LnB1dChDb25zdGFudHMuQlVORExFX01BTklGRVNUVkVSU0lPTiwgIjIiKTsKCQlleHBvcnRlck1hbmlmZXN0LnB1dChDb25zdGFudHMuQlVORExFX1NZTUJPTElDTkFNRSwgImV4cG9ydGVyIik7CgkJZXhwb3J0ZXJNYW5pZmVzdC5wdXQoQ29uc3RhbnRzLkVYUE9SVF9QQUNLQUdFLCAiZXhwb3J0ZXI7IHBpY2ttZT10cnVlIik7CgoJCU1vZHVsZSBtb2R1bGVFeHBvcnQgPSBpbnN0YWxsRHVtbXlNb2R1bGUoZXhwb3J0ZXJNYW5pZmVzdCwgImV4cG9ydGVyIiwgY29udGFpbmVyKTsKCQlyZXBvcnQgPSBjb250YWluZXIucmVzb2x2ZShBcnJheXMuYXNMaXN0KG1vZHVsZVN1YnNFeHBvcnQvKiAsbW9kdWxlRXhwb3J0ICovKSwgdHJ1ZSk7CgkJQXNzZXJ0LmFzc2VydE51bGwoIkZhaWxlZCB0byByZXNvbHZlIiwgcmVwb3J0LmdldFJlc29sdXRpb25FeGNlcHRpb24oKSk7CgoJCUxpc3Q8QnVuZGxlQ2FwYWJpbGl0eT4gY2FwcyA9IG1vZHVsZVN1YnNFeHBvcnQuZ2V0Q3VycmVudFJldmlzaW9uKCkuZ2V0V2lyaW5nKCkuZ2V0Q2FwYWJpbGl0aWVzKFBhY2thZ2VOYW1lc3BhY2UuUEFDS0FHRV9OQU1FU1BBQ0UpOwoJCWFzc2VydEVxdWFscygiV3JvbmcgbnVtYmVyIG9mIGNhcGFiaWxpdGllcy4iLCAwLCBjYXBzLnNpemUoKSk7CgoJCXJlcXMgPSBtb2R1bGVTdWJzRXhwb3J0LmdldEN1cnJlbnRSZXZpc2lvbigpLmdldFdpcmluZygpLmdldFJlcXVpcmVtZW50cyhQYWNrYWdlTmFtZXNwYWNlLlBBQ0tBR0VfTkFNRVNQQUNFKTsKCQlhc3NlcnRFcXVhbHMoIldyb25nIG51bWJlciBvZiBpbXBvcnRzLiIsIDEsIHJlcXMuc2l6ZSgpKTsKCgkJTW9kdWxlV2lyaW5nIHdpcmluZyA9IG1vZHVsZVN1YnNFeHBvcnQuZ2V0Q3VycmVudFJldmlzaW9uKCkuZ2V0V2lyaW5nKCk7CgkJTGlzdDxNb2R1bGVXaXJlPiBwYWNrYWdlV2lyZXMgPSB3aXJpbmcuZ2V0UmVxdWlyZWRNb2R1bGVXaXJlcyhQYWNrYWdlTmFtZXNwYWNlLlBBQ0tBR0VfTkFNRVNQQUNFKTsKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJVbmV4cGVjdGVkIG51bWJlciBvZiB3aXJlcyIsIDEsIHBhY2thZ2VXaXJlcy5zaXplKCkpOwoJCUFzc2VydC5hc3NlcnRFcXVhbHMoIldyb25nIGV4cG9ydGVyIiwgcGFja2FnZVdpcmVzLmdldCgwKS5nZXRQcm92aWRlcldpcmluZygpLmdldFJldmlzaW9uKCksIG1vZHVsZUV4cG9ydC5nZXRDdXJyZW50UmV2aXNpb24oKSk7Cgl9CgoJQFRlc3QKCXB1YmxpYyB2b2lkIHRlc3RSMygpIHRocm93cyBCdW5kbGVFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKCQlEdW1teUNvbnRhaW5lckFkYXB0b3IgYWRhcHRvciA9IGNyZWF0ZUR1bW15QWRhcHRvcigpOwoJCU1vZHVsZUNvbnRhaW5lciBjb250YWluZXIgPSBhZGFwdG9yLmdldENvbnRhaW5lcigpOwoJCS8vIGluc3RhbGwgdGhlIHN5c3RlbS5idW5kbGUKCQlNb2R1bGUgc3lzdGVtQnVuZGxlID0gaW5zdGFsbER1bW15TW9kdWxlKCJzeXN0ZW0uYnVuZGxlLk1GIiwgQ29uc3RhbnRzLlNZU1RFTV9CVU5ETEVfTE9DQVRJT04sIENvbnN0YW50cy5TWVNURU1fQlVORExFX1NZTUJPTElDTkFNRSwgbnVsbCwgbnVsbCwgY29udGFpbmVyKTsKCQlSZXNvbHV0aW9uUmVwb3J0IHJlcG9ydCA9IGNvbnRhaW5lci5yZXNvbHZlKEFycmF5cy5hc0xpc3Qoc3lzdGVtQnVuZGxlKSwgdHJ1ZSk7CgkJQXNzZXJ0LmFzc2VydE51bGwoIkZhaWxlZCB0byByZXNvbHZlIHN5c3RlbS5idW5kbGUuIiwgcmVwb3J0LmdldFJlc29sdXRpb25FeGNlcHRpb24oKSk7CgoJCS8vUjMgYnVuZGxlCgkJTWFwPFN0cmluZywgU3RyaW5nPiBleHBvcnRlck1hbmlmZXN0ID0gbmV3IEhhc2hNYXA8U3RyaW5nLCBTdHJpbmc+KCk7CgkJZXhwb3J0ZXJNYW5pZmVzdCA9IG5ldyBIYXNoTWFwPFN0cmluZywgU3RyaW5nPigpOwoJCWV4cG9ydGVyTWFuaWZlc3QucHV0KENvbnN0YW50cy5CVU5ETEVfU1lNQk9MSUNOQU1FLCAiZXhwb3J0ZXIiKTsKCQlleHBvcnRlck1hbmlmZXN0LnB1dChDb25zdGFudHMuRVhQT1JUX1BBQ0tBR0UsICJleHBvcnRlcjsgdmVyc2lvbj1cIjEuMVwiIik7CgoJCU1vZHVsZSBtb2R1bGVFeHBvcnQgPSBpbnN0YWxsRHVtbXlNb2R1bGUoZXhwb3J0ZXJNYW5pZmVzdCwgImV4cG9ydGVyIiwgY29udGFpbmVyKTsKCQlyZXBvcnQgPSBjb250YWluZXIucmVzb2x2ZShBcnJheXMuYXNMaXN0KG1vZHVsZUV4cG9ydCwgbW9kdWxlRXhwb3J0KSwgdHJ1ZSk7CgkJQXNzZXJ0LmFzc2VydE51bGwoIkZhaWxlZCB0byByZXNvbHZlIiwgcmVwb3J0LmdldFJlc29sdXRpb25FeGNlcHRpb24oKSk7CgkJTGlzdDxCdW5kbGVSZXF1aXJlbWVudD4gcmVxcyA9IG1vZHVsZUV4cG9ydC5nZXRDdXJyZW50UmV2aXNpb24oKS5nZXRXaXJpbmcoKS5nZXRSZXF1aXJlbWVudHMoUGFja2FnZU5hbWVzcGFjZS5QQUNLQUdFX05BTUVTUEFDRSk7CgkJYXNzZXJ0RXF1YWxzKCJXcm9uZyBudW1iZXIgb2YgaW1wb3J0cy4iLCAwLCByZXFzLnNpemUoKSk7CgoJCS8vUjMgYnVuZGxlCgkJZXhwb3J0ZXJNYW5pZmVzdC5jbGVhcigpOwoJCWV4cG9ydGVyTWFuaWZlc3QucHV0KENvbnN0YW50cy5CVU5ETEVfU1lNQk9MSUNOQU1FLCAiZHluYW1pY0V4cG9ydGVyIik7CgkJZXhwb3J0ZXJNYW5pZmVzdC5wdXQoQ29uc3RhbnRzLkVYUE9SVF9QQUNLQUdFLCAiZXhwb3J0ZXI7IHZlcnNpb249XCIxLjBcIiIpOwoJCWV4cG9ydGVyTWFuaWZlc3QucHV0KENvbnN0YW50cy5EWU5BTUlDSU1QT1JUX1BBQ0tBR0UsICJleHBvcnRlciIpOwoJCU1vZHVsZSBtb2R1bGVXaXRoRHluRXhwb3J0ID0gaW5zdGFsbER1bW15TW9kdWxlKGV4cG9ydGVyTWFuaWZlc3QsICJkeW5hbWljRXhwb3J0ZXIiLCBjb250YWluZXIpOwoJCXJlcG9ydCA9IGNvbnRhaW5lci5yZXNvbHZlKEFycmF5cy5hc0xpc3QobW9kdWxlV2l0aER5bkV4cG9ydCksIHRydWUpOwoJCUFzc2VydC5hc3NlcnROdWxsKCJGYWlsZWQgdG8gcmVzb2x2ZSIsIHJlcG9ydC5nZXRSZXNvbHV0aW9uRXhjZXB0aW9uKCkpOwoJCXJlcXMgPSBtb2R1bGVXaXRoRHluRXhwb3J0LmdldEN1cnJlbnRSZXZpc2lvbigpLmdldFdpcmluZygpLmdldFJlcXVpcmVtZW50cyhQYWNrYWdlTmFtZXNwYWNlLlBBQ0tBR0VfTkFNRVNQQUNFKTsKCQlhc3NlcnRFcXVhbHMoIldyb25nIG51bWJlciBvZiBpbXBvcnRzLiIsIDIsIHJlcXMuc2l6ZSgpKTsKCgkJcmVwb3J0ID0gY29udGFpbmVyLnJlc29sdmUoQXJyYXlzLmFzTGlzdChtb2R1bGVXaXRoRHluRXhwb3J0KSwgdHJ1ZSk7CgkJQXNzZXJ0LmFzc2VydE51bGwoIkZhaWxlZCB0byByZXNvbHZlIiwgcmVwb3J0LmdldFJlc29sdXRpb25FeGNlcHRpb24oKSk7CgkJcmVxcyA9IG1vZHVsZVdpdGhEeW5FeHBvcnQuZ2V0Q3VycmVudFJldmlzaW9uKCkuZ2V0V2lyaW5nKCkuZ2V0UmVxdWlyZW1lbnRzKFBhY2thZ2VOYW1lc3BhY2UuUEFDS0FHRV9OQU1FU1BBQ0UpOwoJCWFzc2VydEVxdWFscygiV3JvbmcgbnVtYmVyIG9mIGltcG9ydHMuIiwgMiwgcmVxcy5zaXplKCkpOwoJCU1vZHVsZVdpcmluZyB3aXJpbmcgPSBtb2R1bGVXaXRoRHluRXhwb3J0LmdldEN1cnJlbnRSZXZpc2lvbigpLmdldFdpcmluZygpOwoJCUxpc3Q8TW9kdWxlV2lyZT4gcGFja2FnZVdpcmVzID0gd2lyaW5nLmdldFJlcXVpcmVkTW9kdWxlV2lyZXMoUGFja2FnZU5hbWVzcGFjZS5QQUNLQUdFX05BTUVTUEFDRSk7CgkJQXNzZXJ0LmFzc2VydEVxdWFscygiVW5leHBlY3RlZCBudW1iZXIgb2Ygd2lyZXMiLCAxLCBwYWNrYWdlV2lyZXMuc2l6ZSgpKTsKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJXcm9uZyBleHBvcnRlciIsIHBhY2thZ2VXaXJlcy5nZXQoMCkuZ2V0UHJvdmlkZXJXaXJpbmcoKS5nZXRSZXZpc2lvbigpLCBtb2R1bGVFeHBvcnQuZ2V0Q3VycmVudFJldmlzaW9uKCkpOwoJfQoKCXByaXZhdGUgc3RhdGljIE1hcDxTdHJpbmcsIFN0cmluZz4gZ2V0VVRGTWFuaWZlc3QoU3RyaW5nIHBhY2thZ2VOYW1lKSB0aHJvd3MgSU9FeGNlcHRpb24sIEJ1bmRsZUV4Y2VwdGlvbiB7CgkJLy8gdXNpbmcgbWFuaWZlc3QgY2xhc3MgdG8gZm9yY2UgYSBzcGxpdCBsaW5lIHJpZ2h0IGluIHRoZSBtaWRkbGUgb2YgYSBkb3VibGUgYnl0ZSBVVEYtOCBjaGFyYWN0ZXIKCQlCeXRlQXJyYXlPdXRwdXRTdHJlYW0gb3V0ID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOwoJCXsKCQkJTWFuaWZlc3QgbSA9IG5ldyBNYW5pZmVzdCgpOwoJCQlBdHRyaWJ1dGVzIGEgPSBtLmdldE1haW5BdHRyaWJ1dGVzKCk7CgkJCWEucHV0KE1BTklGRVNUX1ZFUlNJT04sICIxLjAiKTsKCQkJYS5wdXRWYWx1ZShDb25zdGFudHMuQlVORExFX01BTklGRVNUVkVSU0lPTiwgIjIiKTsKCQkJYS5wdXRWYWx1ZShDb25zdGFudHMuQlVORExFX1NZTUJPTElDTkFNRSwgcGFja2FnZU5hbWUpOwoJCQlhLnB1dFZhbHVlKENvbnN0YW50cy5FWFBPUlRfUEFDS0FHRSwgcGFja2FnZU5hbWUpOwoJCQlhLnB1dFZhbHVlKENvbnN0YW50cy5JTVBPUlRfUEFDS0FHRSwgcGFja2FnZU5hbWUpOwoJCQltLndyaXRlKG91dCk7CgkJfQoJCXJldHVybiBNYW5pZmVzdEVsZW1lbnQucGFyc2VCdW5kbGVNYW5pZmVzdChuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0ob3V0LnRvQnl0ZUFycmF5KCkpLCBudWxsKTsKCX0KCglAVGVzdAoJcHVibGljIHZvaWQgdGVzdFBlcnNpc3RlbmNlKCkgdGhyb3dzIEJ1bmRsZUV4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewoJCUR1bW15Q29udGFpbmVyQWRhcHRvciBhZGFwdG9yID0gY3JlYXRlRHVtbXlBZGFwdG9yKCk7CgkJTW9kdWxlQ29udGFpbmVyIGNvbnRhaW5lciA9IGFkYXB0b3IuZ2V0Q29udGFpbmVyKCk7CgoJCS8vIGluc3RhbGwgdGhlIHN5c3RlbS5idW5kbGUKCQlpbnN0YWxsRHVtbXlNb2R1bGUoInN5c3RlbS5idW5kbGUuTUYiLCBDb25zdGFudHMuU1lTVEVNX0JVTkRMRV9MT0NBVElPTiwgQ29uc3RhbnRzLlNZU1RFTV9CVU5ETEVfU1lNQk9MSUNOQU1FLCBudWxsLCBudWxsLCBjb250YWluZXIpOwoKCQlNYXA8U3RyaW5nLCBPYmplY3Q+IGF0dHJzID0gbmV3IEhhc2hNYXA8U3RyaW5nLCBPYmplY3Q+KCk7CgkJYXR0cnMucHV0KCJzdHJpbmciLCAic1ZhbHVlIik7CgkJYXR0cnMucHV0KCJzdHJpbmcubGlzdDEiLCBBcnJheXMuYXNMaXN0KCJ2MSIsICJ2MiIsICJ2MyIpKTsKCQlhdHRycy5wdXQoInN0cmluZy5saXN0MiIsIEFycmF5cy5hc0xpc3QoInY0IiwgInY1IiwgInY2IikpOwoJCWF0dHJzLnB1dCgidmVyc2lvbiIsIFZlcnNpb24udmFsdWVPZigiMS4xIikpOwoJCWF0dHJzLnB1dCgidmVyc2lvbi5saXN0IiwgQXJyYXlzLmFzTGlzdChWZXJzaW9uLnZhbHVlT2YoIjEuMCIpLCBWZXJzaW9uLnZhbHVlT2YoIjIuMCIpLCBWZXJzaW9uLnZhbHVlT2YoIjMuMCIpKSk7CgkJYXR0cnMucHV0KCJsb25nIiwgTG9uZy52YWx1ZU9mKDEyMzQ1KSk7CgkJYXR0cnMucHV0KCJsb25nLmxpc3QiLCBBcnJheXMuYXNMaXN0KExvbmcudmFsdWVPZigxKSwgTG9uZy52YWx1ZU9mKDIpLCBMb25nLnZhbHVlT2YoMykpKTsKCQlhdHRycy5wdXQoImRvdWJsZSIsIERvdWJsZS52YWx1ZU9mKDEuMjM0NSkpOwoJCWF0dHJzLnB1dCgiZG91YmxlLmxpc3QiLCBBcnJheXMuYXNMaXN0KERvdWJsZS52YWx1ZU9mKDEuMSksIERvdWJsZS52YWx1ZU9mKDEuMiksIERvdWJsZS52YWx1ZU9mKDEuMykpKTsKCQlhdHRycy5wdXQoInVyaSIsICJzb21lLnVyaSIpOwoJCWF0dHJzLnB1dCgic2V0IiwgQXJyYXlzLmFzTGlzdCgiczEiLCAiczIiLCAiczMiKSk7CgoJCS8vIHByb3ZpZGVyIHdpdGggYWxsIHN1cHBvcnRlZCB0eXBlcwoJCU1hcDxTdHJpbmcsIFN0cmluZz4gcHJvdmlkZXJNYW5pZmVzdCA9IG5ldyBIYXNoTWFwPFN0cmluZywgU3RyaW5nPigpOwoJCXByb3ZpZGVyTWFuaWZlc3QucHV0KENvbnN0YW50cy5CVU5ETEVfTUFOSUZFU1RWRVJTSU9OLCAiMiIpOwoJCXByb3ZpZGVyTWFuaWZlc3QucHV0KENvbnN0YW50cy5CVU5ETEVfU1lNQk9MSUNOQU1FLCAicHJvdmlkZXIiKTsKCQlwcm92aWRlck1hbmlmZXN0LnB1dChDb25zdGFudHMuRVhQT1JUX1BBQ0tBR0UsICJwcm92aWRlcjsgdmVyc2lvbj0xLjE7IGF0dHIxPWF0dHIxOyBhdHRyMj1hdHRyMjsgZGlyMTo9ZGlyMTsgZGlyMjo9ZGlyMiIpOwoJCXByb3ZpZGVyTWFuaWZlc3QucHV0KENvbnN0YW50cy5QUk9WSURFX0NBUEFCSUxJVFksICJwcm92aWRlci5jYXA7Ii8vCgkJCQkrICIgc3RyaW5nPXNWYWx1ZTsiLy8KCQkJCSsgIiBzdHJpbmcubGlzdDE6TGlzdD1cInYxLHYyLHYzXCI7Ii8vCgkJCQkrICIgc3RyaW5nLmxpc3QyOkxpc3Q8U3RyaW5nPj1cInY0LHY1LHY2XCI7Ii8vCgkJCQkrICIgdmVyc2lvbjpWZXJzaW9uPTEuMTsiLy8KCQkJCSsgIiB2ZXJzaW9uLmxpc3Q6TGlzdDxWZXJzaW9uPj1cIjEuMCwyLjAsMy4wXCI7Ii8vCgkJCQkrICIgbG9uZzpMb25nPTEyMzQ1OyIvLwoJCQkJKyAiIGxvbmcubGlzdDpMaXN0PExvbmc+PVwiMSwyLDNcIjsiLy8KCQkJCSsgIiBkb3VibGU6RG91YmxlPTEuMjM0NTsiLy8KCQkJCSsgIiBkb3VibGUubGlzdDpMaXN0PERvdWJsZT49XCIxLjEsMS4yLDEuM1wiOyIvLwoJCQkJKyAiIHVyaTp1cmk9c29tZS51cmk7IiAvLwoJCQkJKyAiIHNldDpzZXQ9XCJzMSxzMixzM1wiIik7CgkJTW9kdWxlIHByb3ZpZGVyTW9kdWxlID0gaW5zdGFsbER1bW15TW9kdWxlKHByb3ZpZGVyTWFuaWZlc3QsICJwcm92aWRlciIsIGNvbnRhaW5lcik7CgkJTWFwPFN0cmluZywgT2JqZWN0PiBwcm92aWRlckF0dHJzID0gcHJvdmlkZXJNb2R1bGUuZ2V0Q3VycmVudFJldmlzaW9uKCkuZ2V0Q2FwYWJpbGl0aWVzKCJwcm92aWRlci5jYXAiKS5nZXQoMCkuZ2V0QXR0cmlidXRlcygpOwoJCWFzc2VydEVxdWFscygiV3JvbmcgcHJvdmlkZXIgYXR0cnMiLCBhdHRycywgcHJvdmlkZXJBdHRycyk7CgoJCU1hcDxTdHJpbmcsIFN0cmluZz4gcmVxdWlyZXJNYW5pZmVzdCA9IG5ldyBIYXNoTWFwPFN0cmluZywgU3RyaW5nPigpOwoJCXJlcXVpcmVyTWFuaWZlc3QucHV0KENvbnN0YW50cy5CVU5ETEVfTUFOSUZFU1RWRVJTSU9OLCAiMiIpOwoJCXJlcXVpcmVyTWFuaWZlc3QucHV0KENvbnN0YW50cy5CVU5ETEVfU1lNQk9MSUNOQU1FLCAicmVxdWlyZXIiKTsKCQlyZXF1aXJlck1hbmlmZXN0LnB1dChDb25zdGFudHMuSU1QT1JUX1BBQ0tBR0UsICJwcm92aWRlcjsgdmVyc2lvbj0xLjE7IGF0dHIxPWF0dHIxOyBhdHRyMj1hdHRyMjsgZGlyMTo9ZGlyMTsgZGlyMjo9ZGlyMiIpOwoJCXJlcXVpcmVyTWFuaWZlc3QucHV0KENvbnN0YW50cy5SRVFVSVJFX0NBUEFCSUxJVFksICJvcHRpb25hbDsiLy8KCQkJCSsgIiByZXNvbHV0aW9uOj1vcHRpb25hbDsgIiAvLwoJCQkJKyAiIHN0cmluZz1zVmFsdWU7Ii8vCgkJCQkrICIgc3RyaW5nLmxpc3QxOkxpc3Q9XCJ2MSx2Mix2M1wiOyIvLwoJCQkJKyAiIHN0cmluZy5saXN0MjpMaXN0PFN0cmluZz49XCJ2NCx2NSx2NlwiOyIvLwoJCQkJKyAiIHZlcnNpb246VmVyc2lvbj0xLjE7Ii8vCgkJCQkrICIgdmVyc2lvbi5saXN0Okxpc3Q8VmVyc2lvbj49XCIxLjAsMi4wLDMuMFwiOyIvLwoJCQkJKyAiIGxvbmc6TG9uZz0xMjM0NTsiLy8KCQkJCSsgIiBsb25nLmxpc3Q6TGlzdDxMb25nPj1cIjEsMiwzXCI7Ii8vCgkJCQkrICIgZG91YmxlOkRvdWJsZT0xLjIzNDU7Ii8vCgkJCQkrICIgZG91YmxlLmxpc3Q6TGlzdDxEb3VibGU+PVwiMS4xLDEuMiwxLjNcIjsiLy8KCQkJCSsgIiB1cmk6dXJpPXNvbWUudXJpOyIgLy8KCQkJCSsgIiBzZXQ6c2V0PVwiczEsczIsczNcIiwiIC8vCgkJCQkrICJwcm92aWRlci5jYXA7IGZpbHRlcjo9XCIoc3RyaW5nPXNWYWx1ZSlcIiwiIC8vCgkJCQkrICJwcm92aWRlci5jYXA7IGZpbHRlcjo9XCIoc3RyaW5nLmxpc3QxPXYyKVwiLCIgLy8KCQkJCSsgInByb3ZpZGVyLmNhcDsgZmlsdGVyOj1cIihzdHJpbmcubGlzdDI9djUpXCIsIiAvLwoJCQkJKyAicHJvdmlkZXIuY2FwOyBmaWx0ZXI6PVwiKHN0cmluZy5saXN0Mj12NSlcIiwiIC8vCgkJCQkrICJwcm92aWRlci5jYXA7IGZpbHRlcjo9XCIoJih2ZXJzaW9uPj0xLjEpKHZlcnNpb248PTEuMS4xKSlcIiwiIC8vCgkJCQkrICJwcm92aWRlci5jYXA7IGZpbHRlcjo9XCIoJih2ZXJzaW9uLmxpc3Q9MSkodmVyc2lvbi5saXN0PTIpKVwiLCIgLy8KCQkJCSsgInByb3ZpZGVyLmNhcDsgZmlsdGVyOj1cIihsb25nPj0xMjM0NClcIiwiIC8vCgkJCQkrICJwcm92aWRlci5jYXA7IGZpbHRlcjo9XCIobG9uZy5saXN0PTIpXCIsIiAvLwoJCQkJKyAicHJvdmlkZXIuY2FwOyBmaWx0ZXI6PVwiKGRvdWJsZT49MS4yKVwiLCIgLy8KCQkJCSsgInByb3ZpZGVyLmNhcDsgZmlsdGVyOj1cIihkb3VibGUubGlzdD0xLjIpXCIsIiAvLwoJCQkJKyAicHJvdmlkZXIuY2FwOyBmaWx0ZXI6PVwiKHVyaT1zb21lLnVyaSlcIiwiIC8vCgkJCQkrICJwcm92aWRlci5jYXA7IGZpbHRlcjo9XCIoc2V0PXMyKVwiIiAvLwoJCQkJKyAiIik7CgkJTW9kdWxlIHJlcXVpcmVyTW9kdWxlID0gaW5zdGFsbER1bW15TW9kdWxlKHJlcXVpcmVyTWFuaWZlc3QsICJyZXF1aXJlciIsIGNvbnRhaW5lcik7CgkJTWFwPFN0cmluZywgT2JqZWN0PiByZXF1aXJlckF0dHJzID0gcmVxdWlyZXJNb2R1bGUuZ2V0Q3VycmVudFJldmlzaW9uKCkuZ2V0UmVxdWlyZW1lbnRzKCJvcHRpb25hbCIpLmdldCgwKS5nZXRBdHRyaWJ1dGVzKCk7CgkJYXNzZXJ0RXF1YWxzKCJXcm9uZyByZXF1aXJlciBhdHRycyIsIGF0dHJzLCByZXF1aXJlckF0dHJzKTsKCQlSZXNvbHV0aW9uUmVwb3J0IHJlcG9ydCA9IGNvbnRhaW5lci5yZXNvbHZlKENvbGxlY3Rpb25zLnNpbmdsZXRvbihyZXF1aXJlck1vZHVsZSksIHRydWUpOwoJCWFzc2VydE51bGwoIkVycm9yIHJlc29sdmluZy4iLCByZXBvcnQuZ2V0UmVzb2x1dGlvbkV4Y2VwdGlvbigpKTsKCgkJQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGJ5dGVzID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOwoJCURhdGFPdXRwdXRTdHJlYW0gZGF0YSA9IG5ldyBEYXRhT3V0cHV0U3RyZWFtKGJ5dGVzKTsKCQlhZGFwdG9yLmdldERhdGFiYXNlKCkuc3RvcmUoZGF0YSwgdHJ1ZSk7CgoJCS8vIHJlbG9hZCBpbnRvIGEgbmV3IGNvbnRhaW5lcgoJCWFkYXB0b3IgPSBjcmVhdGVEdW1teUFkYXB0b3IoKTsKCQljb250YWluZXIgPSBhZGFwdG9yLmdldENvbnRhaW5lcigpOwoJCWFkYXB0b3IuZ2V0RGF0YWJhc2UoKS5sb2FkKG5ldyBEYXRhSW5wdXRTdHJlYW0obmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGJ5dGVzLnRvQnl0ZUFycmF5KCkpKSk7CgoJCXByb3ZpZGVyTW9kdWxlID0gY29udGFpbmVyLmdldE1vZHVsZSgicHJvdmlkZXIiKTsKCQlwcm92aWRlckF0dHJzID0gcHJvdmlkZXJNb2R1bGUuZ2V0Q3VycmVudFJldmlzaW9uKCkuZ2V0Q2FwYWJpbGl0aWVzKCJwcm92aWRlci5jYXAiKS5nZXQoMCkuZ2V0QXR0cmlidXRlcygpOwoJCWFzc2VydEVxdWFscygiV3JvbmcgcHJvdmlkZXIgYXR0cnMiLCBhdHRycywgcHJvdmlkZXJBdHRycyk7CgkJYXNzZXJ0Tm90TnVsbCgiTm8gcHJvdmlkZXIgZm91bmQuIiwgcHJvdmlkZXJNb2R1bGUpOwoKCQlyZXF1aXJlck1vZHVsZSA9IGNvbnRhaW5lci5nZXRNb2R1bGUoInJlcXVpcmVyIik7CgkJYXNzZXJ0Tm90TnVsbCgiTm8gcmVxdWlyZXIgZm91bmQuIiwgcmVxdWlyZXJNb2R1bGUpOwoJCXJlcXVpcmVyQXR0cnMgPSByZXF1aXJlck1vZHVsZS5nZXRDdXJyZW50UmV2aXNpb24oKS5nZXRSZXF1aXJlbWVudHMoIm9wdGlvbmFsIikuZ2V0KDApLmdldEF0dHJpYnV0ZXMoKTsKCQlhc3NlcnRFcXVhbHMoIldyb25nIHJlcXVpcmVyIGF0dHJzIiwgYXR0cnMsIHJlcXVpcmVyQXR0cnMpOwoJfQoKCUBUZXN0CglwdWJsaWMgdm9pZCB0ZXN0SW52YWxpZEF0dHJpYnV0ZXMoKSB0aHJvd3MgSU9FeGNlcHRpb24sIEJ1bmRsZUV4Y2VwdGlvbiB7CgkJRHVtbXlDb250YWluZXJBZGFwdG9yIGFkYXB0b3IgPSBjcmVhdGVEdW1teUFkYXB0b3IoKTsKCQlNb2R1bGVDb250YWluZXIgY29udGFpbmVyID0gYWRhcHRvci5nZXRDb250YWluZXIoKTsKCgkJLy8gaW5zdGFsbCB0aGUgc3lzdGVtLmJ1bmRsZQoJCWluc3RhbGxEdW1teU1vZHVsZSgic3lzdGVtLmJ1bmRsZS5NRiIsIENvbnN0YW50cy5TWVNURU1fQlVORExFX0xPQ0FUSU9OLCBDb25zdGFudHMuU1lTVEVNX0JVTkRMRV9TWU1CT0xJQ05BTUUsIG51bGwsIG51bGwsIGNvbnRhaW5lcik7CgoJCS8vIHByb3ZpZGVyIHdpdGggYWxsIHN1cHBvcnRlZCB0eXBlcwoJCU1hcDxTdHJpbmcsIFN0cmluZz4gaW52YWxpZEF0dHJNYW5pZmVzdCA9IG5ldyBIYXNoTWFwPFN0cmluZywgU3RyaW5nPigpOwoJCWludmFsaWRBdHRyTWFuaWZlc3QucHV0KENvbnN0YW50cy5CVU5ETEVfTUFOSUZFU1RWRVJTSU9OLCAiMiIpOwoJCWludmFsaWRBdHRyTWFuaWZlc3QucHV0KENvbnN0YW50cy5CVU5ETEVfU1lNQk9MSUNOQU1FLCAiaW52YWxpZCIpOwoKCQlpbnZhbGlkQXR0ck1hbmlmZXN0LnB1dChDb25zdGFudHMuUFJPVklERV9DQVBBQklMSVRZLCAicHJvdmlkZXIuY2FwOyBpbnZhbGlkOkJvb2xlYW49dHJ1ZSIpOwoJCWNoZWNrSW52YWxpZE1hbmlmZXN0KGludmFsaWRBdHRyTWFuaWZlc3QsIGNvbnRhaW5lcik7CgoJCWludmFsaWRBdHRyTWFuaWZlc3QucHV0KENvbnN0YW50cy5QUk9WSURFX0NBUEFCSUxJVFksICJwcm92aWRlci5jYXA7IGludmFsaWQ6SW50ZWdlcj0xIik7CgkJY2hlY2tJbnZhbGlkTWFuaWZlc3QoaW52YWxpZEF0dHJNYW5pZmVzdCwgY29udGFpbmVyKTsKCgkJaW52YWxpZEF0dHJNYW5pZmVzdC5wdXQoQ29uc3RhbnRzLlBST1ZJREVfQ0FQQUJJTElUWSwgInByb3ZpZGVyLmNhcDsgaW52YWxpZDpMaXN0PEJvb2xlYW4+PXRydWUiKTsKCQljaGVja0ludmFsaWRNYW5pZmVzdChpbnZhbGlkQXR0ck1hbmlmZXN0LCBjb250YWluZXIpOwoKCQlpbnZhbGlkQXR0ck1hbmlmZXN0LnB1dChDb25zdGFudHMuUFJPVklERV9DQVBBQklMSVRZLCAicHJvdmlkZXIuY2FwOyBpbnZhbGlkOkxpc3Q8SW50ZWdlcj49MSIpOwoJCWNoZWNrSW52YWxpZE1hbmlmZXN0KGludmFsaWRBdHRyTWFuaWZlc3QsIGNvbnRhaW5lcik7Cgl9CgoJcHJpdmF0ZSB2b2lkIGNoZWNrSW52YWxpZE1hbmlmZXN0KE1hcDxTdHJpbmcsIFN0cmluZz4gaW52YWxpZEF0dHJNYW5pZmVzdCwgTW9kdWxlQ29udGFpbmVyIGNvbnRhaW5lcikgewoJCXRyeSB7CgkJCWluc3RhbGxEdW1teU1vZHVsZShpbnZhbGlkQXR0ck1hbmlmZXN0LCAiaW52YWxpZCIsIGNvbnRhaW5lcik7CgkJCWZhaWwoIkV4cGVjdGVkIHRvIGdldCBhIEJ1bmRsZUV4Y2VwdGlvbiB3aXRoIE1BTklGRVNUX0VSUk9SIik7CgkJfSBjYXRjaCAoQnVuZGxlRXhjZXB0aW9uIGUpIHsKCQkJLy8gZmluZCBleHBlY3RlZCB0eXBlCgkJCWFzc2VydEVxdWFscygiV3JvbmcgdHlwZS4iLCBCdW5kbGVFeGNlcHRpb24uTUFOSUZFU1RfRVJST1IsIGUuZ2V0VHlwZSgpKTsKCQl9Cgl9CgoJQFRlc3QKCXB1YmxpYyB2b2lkIHRlc3RTdG9yZUludmFsaWRBdHRyaWJ1dGVzKCkgdGhyb3dzIEJ1bmRsZUV4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewoJCUR1bW15Q29udGFpbmVyQWRhcHRvciBhZGFwdG9yID0gY3JlYXRlRHVtbXlBZGFwdG9yKCk7CgkJTW9kdWxlQ29udGFpbmVyIGNvbnRhaW5lciA9IGFkYXB0b3IuZ2V0Q29udGFpbmVyKCk7CgoJCS8vIGluc3RhbGwgdGhlIHN5c3RlbS5idW5kbGUKCQlpbnN0YWxsRHVtbXlNb2R1bGUoInN5c3RlbS5idW5kbGUuTUYiLCBDb25zdGFudHMuU1lTVEVNX0JVTkRMRV9MT0NBVElPTiwgQ29uc3RhbnRzLlNZU1RFTV9CVU5ETEVfU1lNQk9MSUNOQU1FLCBudWxsLCBudWxsLCBjb250YWluZXIpOwoKCQlJbnRlZ2VyIHRlc3RJbnQgPSBJbnRlZ2VyLnZhbHVlT2YoMSk7CgkJTGlzdDxJbnRlZ2VyPiB0ZXN0SW50TGlzdCA9IENvbGxlY3Rpb25zLnNpbmdsZXRvbkxpc3QodGVzdEludCk7CgkJTW9kdWxlUmV2aXNpb25CdWlsZGVyIGJ1aWxkZXIgPSBuZXcgTW9kdWxlUmV2aXNpb25CdWlsZGVyKCk7CgkJYnVpbGRlci5zZXRTeW1ib2xpY05hbWUoImludmFsaWQuYXR0ciIpOwoJCWJ1aWxkZXIuc2V0VmVyc2lvbihWZXJzaW9uLnZhbHVlT2YoIjEuMC4wIikpOwoJCWJ1aWxkZXIuYWRkQ2FwYWJpbGl0eSgidGVzdCIsIENvbGxlY3Rpb25zLjxTdHJpbmcsIFN0cmluZz4gZW1wdHlNYXAoKSwgQ29sbGVjdGlvbnMuc2luZ2xldG9uTWFwKCJ0ZXN0IiwgKE9iamVjdCkgdGVzdEludCkpOwoJCWJ1aWxkZXIuYWRkQ2FwYWJpbGl0eSgidGVzdC5saXN0IiwgQ29sbGVjdGlvbnMuPFN0cmluZywgU3RyaW5nPiBlbXB0eU1hcCgpLCBDb2xsZWN0aW9ucy5zaW5nbGV0b25NYXAoInRlc3QubGlzdCIsIChPYmplY3QpIHRlc3RJbnRMaXN0KSk7CgkJTW9kdWxlIGludmFsaWQgPSBjb250YWluZXIuaW5zdGFsbChudWxsLCBidWlsZGVyLmdldFN5bWJvbGljTmFtZSgpLCBidWlsZGVyLCBudWxsKTsKCgkJT2JqZWN0IHRlc3RBdHRyID0gaW52YWxpZC5nZXRDdXJyZW50UmV2aXNpb24oKS5nZXRDYXBhYmlsaXRpZXMoInRlc3QiKS5nZXQoMCkuZ2V0QXR0cmlidXRlcygpLmdldCgidGVzdCIpOwoJCWFzc2VydEVxdWFscygiV3JvbmcgdGVzdCBhdHRyIiwgdGVzdEludCwgdGVzdEF0dHIpOwoKCQlPYmplY3QgdGVzdEF0dHJMaXN0ID0gaW52YWxpZC5nZXRDdXJyZW50UmV2aXNpb24oKS5nZXRDYXBhYmlsaXRpZXMoInRlc3QubGlzdCIpLmdldCgwKS5nZXRBdHRyaWJ1dGVzKCkuZ2V0KCJ0ZXN0Lmxpc3QiKTsKCQlhc3NlcnRFcXVhbHMoIldyb25nIHRlc3QgbGlzdCBhdHRyIiwgdGVzdEludExpc3QsIHRlc3RBdHRyTGlzdCk7CgoJCUJ5dGVBcnJheU91dHB1dFN0cmVhbSBieXRlcyA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKCQlEYXRhT3V0cHV0U3RyZWFtIGRhdGEgPSBuZXcgRGF0YU91dHB1dFN0cmVhbShieXRlcyk7CgkJYWRhcHRvci5nZXREYXRhYmFzZSgpLnN0b3JlKGRhdGEsIHRydWUpOwoKCQlMaXN0PER1bW15Q29udGFpbmVyRXZlbnQ+IGV2ZW50cyA9IGFkYXB0b3IuZ2V0RGF0YWJhc2UoKS5nZXRDb250YWluZXJFdmVudHMoKTsKCQkvLyBtYWtlIHN1cmUgd2Ugc2VlIHRoZSBlcnJvcnMKCQlhc3NlcnRFcXVhbHMoIldyb25nIG51bWJlciBvZiBldmVudHMuIiwgMiwgZXZlbnRzLnNpemUoKSk7CgkJZm9yIChEdW1teUNvbnRhaW5lckV2ZW50IGV2ZW50IDogZXZlbnRzKSB7CgkJCWFzc2VydEVxdWFscygiV3JvbmcgdHlwZSBvZiBldmVudC4iLCBDb250YWluZXJFdmVudC5FUlJPUiwgZXZlbnQudHlwZSk7CgkJCWFzc2VydFRydWUoIldyb25nIHR5cGUgb2YgZXhjZXB0aW9uLiIsIGV2ZW50LmVycm9yIGluc3RhbmNlb2YgQnVuZGxlRXhjZXB0aW9uKTsKCQl9CgoJCS8vIHJlbG9hZCBpbnRvIGEgbmV3IGNvbnRhaW5lcgoJCWFkYXB0b3IgPSBjcmVhdGVEdW1teUFkYXB0b3IoKTsKCQljb250YWluZXIgPSBhZGFwdG9yLmdldENvbnRhaW5lcigpOwoJCWFkYXB0b3IuZ2V0RGF0YWJhc2UoKS5sb2FkKG5ldyBEYXRhSW5wdXRTdHJlYW0obmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKGJ5dGVzLnRvQnl0ZUFycmF5KCkpKSk7CgoJCWludmFsaWQgPSBjb250YWluZXIuZ2V0TW9kdWxlKCJpbnZhbGlkLmF0dHIiKTsKCQlhc3NlcnROb3ROdWxsKCJDb3VsZCBub3QgZmluZCBtb2R1bGUuIiwgaW52YWxpZCk7CgoJCVN0cmluZyB0ZXN0SW50U3RyaW5nID0gU3RyaW5nLnZhbHVlT2YodGVzdEludCk7CgkJTGlzdDxTdHJpbmc+IHRlc3RJbnRTdHJpbmdMaXN0ID0gQ29sbGVjdGlvbnMuc2luZ2xldG9uTGlzdCh0ZXN0SW50U3RyaW5nKTsKCQl0ZXN0QXR0ciA9IGludmFsaWQuZ2V0Q3VycmVudFJldmlzaW9uKCkuZ2V0Q2FwYWJpbGl0aWVzKCJ0ZXN0IikuZ2V0KDApLmdldEF0dHJpYnV0ZXMoKS5nZXQoInRlc3QiKTsKCQlhc3NlcnRFcXVhbHMoIldyb25nIHRlc3QgYXR0ciIsIHRlc3RJbnRTdHJpbmcsIHRlc3RBdHRyKTsKCgkJdGVzdEF0dHJMaXN0ID0gaW52YWxpZC5nZXRDdXJyZW50UmV2aXNpb24oKS5nZXRDYXBhYmlsaXRpZXMoInRlc3QubGlzdCIpLmdldCgwKS5nZXRBdHRyaWJ1dGVzKCkuZ2V0KCJ0ZXN0Lmxpc3QiKTsKCQlhc3NlcnRFcXVhbHMoIldyb25nIHRlc3QgbGlzdCBhdHRyIiwgdGVzdEludFN0cmluZ0xpc3QsIHRlc3RBdHRyTGlzdCk7Cgl9CgoJQFRlc3QKCXB1YmxpYyB2b2lkIHRlc3RCdWc0ODM4NDkoKSB0aHJvd3MgQnVuZGxlRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CgkJRHVtbXlDb250YWluZXJBZGFwdG9yIGFkYXB0b3IgPSBjcmVhdGVEdW1teUFkYXB0b3IoKTsKCQlNb2R1bGVDb250YWluZXIgY29udGFpbmVyID0gYWRhcHRvci5nZXRDb250YWluZXIoKTsKCgkJLy8gaW5zdGFsbCBhbmQgcmVzb2x2ZSBob3N0IGJ1bmRsZQoJCU1vZHVsZSBob3N0ID0gaW5zdGFsbER1bW15TW9kdWxlKCJidWc0ODM4NDkuaG9zdC5NRiIsICJob3N0IiwgY29udGFpbmVyKTsKCQlSZXNvbHV0aW9uUmVwb3J0IHJlcG9ydCA9IGNvbnRhaW5lci5yZXNvbHZlKEFycmF5cy5hc0xpc3QoaG9zdCksIHRydWUpOwoJCUFzc2VydC5hc3NlcnROdWxsKCJGYWlsZWQgdG8gcmVzb2x2ZSBob3N0LiIsIHJlcG9ydC5nZXRSZXNvbHV0aW9uRXhjZXB0aW9uKCkpOwoKCQkvLyBpbnN0YWxsIGFuZCBkeW5hbWljYWxseSBhdHRhY2ggYSBmcmFnbWVudCB0aGF0IGV4cG9ydHMgYSBwYWNrYWdlIGFuZCByZXNvbHZlIGFuIGltcG9ydGVyCgkJTW9kdWxlIGZyYWcgPSBpbnN0YWxsRHVtbXlNb2R1bGUoImJ1ZzQ4Mzg0OS5mcmFnLk1GIiwgImZyYWciLCBjb250YWluZXIpOwoJCU1vZHVsZSBpbXBvcnRlciA9IGluc3RhbGxEdW1teU1vZHVsZSgiYnVnNDgzODQ5LmltcG9ydGVyLk1GIiwgImltcG9ydGVyIiwgY29udGFpbmVyKTsKCQlyZXBvcnQgPSBjb250YWluZXIucmVzb2x2ZShBcnJheXMuYXNMaXN0KGZyYWcsIGltcG9ydGVyKSwgdHJ1ZSk7CgkJQXNzZXJ0LmFzc2VydE51bGwoIkZhaWxlZCB0byByZXNvbHZlIHRlc3QgZnJhZ21lbnQgYW5kIGltcG9ydGVyLiIsIHJlcG9ydC5nZXRSZXNvbHV0aW9uRXhjZXB0aW9uKCkpOwoJCS8vIGdldCB0aGUgY291bnQgb2YgcGFja2FnZSBleHBvcnRzCgkJTW9kdWxlV2lyaW5nIHdpcmluZyA9IGhvc3QuZ2V0Q3VycmVudFJldmlzaW9uKCkuZ2V0V2lyaW5nKCk7CgkJaW50IG9yaWdpbmFsUGFja2FnZUNudCA9IHdpcmluZy5nZXRDYXBhYmlsaXRpZXMoUGFja2FnZU5hbWVzcGFjZS5QQUNLQUdFX05BTUVTUEFDRSkuc2l6ZSgpOwoKCQkvLyB1cGRhdGUgdGhlIGhvc3QgdG8gZ2VuZXJhdGUgYSBuZXcgcmV2aXNpb24KCQlNYXA8U3RyaW5nLCBTdHJpbmc+IHVwZGF0ZU1hbmlmZXN0ID0gZ2V0TWFuaWZlc3QoImJ1ZzQ4Mzg0OS5ob3N0Lk1GIik7CgkJTW9kdWxlUmV2aXNpb25CdWlsZGVyIHVwZGF0ZUJ1aWxkZXIgPSBPU0dpTWFuaWZlc3RCdWlsZGVyRmFjdG9yeS5jcmVhdGVCdWlsZGVyKHVwZGF0ZU1hbmlmZXN0KTsKCQljb250YWluZXIudXBkYXRlKGhvc3QsIHVwZGF0ZUJ1aWxkZXIsIG51bGwpOwoJCS8vIHJlZnJlc2ggaG9zdCB3aGljaCBzaG91bGQgZm9yY2UgdGhlIGltcG9ydGVyIHRvIHJlLXJlc29sdmUgdG8gdGhlIG5ldyByZXZpc2lvbgoJCXJlcG9ydCA9IGNvbnRhaW5lci5yZWZyZXNoKENvbGxlY3Rpb25zLnNpbmdsZXRvbihob3N0KSk7CgoJCU1vZHVsZVdpcmluZyBpbXBvcnRlcldpcmluZyA9IGltcG9ydGVyLmdldEN1cnJlbnRSZXZpc2lvbigpLmdldFdpcmluZygpOwoJCUFzc2VydC5hc3NlcnROb3ROdWxsKCJObyB3aXJpbmcgZm9yIGltcG9ydGVyLiIsIGltcG9ydGVyV2lyaW5nKTsKCQlMaXN0PE1vZHVsZVdpcmU+IGltcG9ydGVyUGFja2FnZVdpcmVzID0gaW1wb3J0ZXJXaXJpbmcuZ2V0UmVxdWlyZWRNb2R1bGVXaXJlcyhQYWNrYWdlTmFtZXNwYWNlLlBBQ0tBR0VfTkFNRVNQQUNFKTsKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJXcm9uZyBudW1iZXIgb2YgaW1wb3J0ZXIgcGFja2FnZSBXaXJlcy4iLCAxLCBpbXBvcnRlclBhY2thZ2VXaXJlcy5zaXplKCkpOwoKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJXcm9uZyBwcm92aWRlciB3aXJpbmcuIiwgaG9zdC5nZXRDdXJyZW50UmV2aXNpb24oKS5nZXRXaXJpbmcoKSwgaW1wb3J0ZXJQYWNrYWdlV2lyZXMuaXRlcmF0b3IoKS5uZXh0KCkuZ2V0UHJvdmlkZXJXaXJpbmcoKSk7CgkJQXNzZXJ0LmFzc2VydEVxdWFscygiV3JvbmcgcHJvdmlkZXIgcmV2aXNpb24uIiwgaG9zdC5nZXRDdXJyZW50UmV2aXNpb24oKSwgaW1wb3J0ZXJQYWNrYWdlV2lyZXMuaXRlcmF0b3IoKS5uZXh0KCkuZ2V0UHJvdmlkZXJXaXJpbmcoKS5nZXRSZXZpc2lvbigpKTsKCgkJd2lyaW5nID0gaG9zdC5nZXRDdXJyZW50UmV2aXNpb24oKS5nZXRXaXJpbmcoKTsKCQlMaXN0PEJ1bmRsZUNhcGFiaWxpdHk+IHBhY2thZ2VzID0gd2lyaW5nLmdldENhcGFiaWxpdGllcyhQYWNrYWdlTmFtZXNwYWNlLlBBQ0tBR0VfTkFNRVNQQUNFKTsKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJXcm9uZyBudW1iZXIgb2YgaG9zdCBwYWNrYWdlcy4iLCBvcmlnaW5hbFBhY2thZ2VDbnQsIHBhY2thZ2VzLnNpemUoKSk7Cgl9CgoJQFRlc3QKCXB1YmxpYyB2b2lkIHRlc3RTdGFydExldmVsRGVhZGxvY2soKSB0aHJvd3MgQnVuZGxlRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CgkJRHVtbXlDb250YWluZXJBZGFwdG9yIGFkYXB0b3IgPSBjcmVhdGVEdW1teUFkYXB0b3IoKTsKCQlNb2R1bGVDb250YWluZXIgY29udGFpbmVyID0gYWRhcHRvci5nZXRDb250YWluZXIoKTsKCQljb250YWluZXIuZ2V0RnJhbWV3b3JrU3RhcnRMZXZlbCgpLnNldEluaXRpYWxCdW5kbGVTdGFydExldmVsKDIpOwoKCQkvLyBpbnN0YWxsIHRoZSBzeXN0ZW0uYnVuZGxlCgkJTW9kdWxlIHN5c3RlbUJ1bmRsZSA9IGluc3RhbGxEdW1teU1vZHVsZSgic3lzdGVtLmJ1bmRsZS5NRiIsIENvbnN0YW50cy5TWVNURU1fQlVORExFX0xPQ0FUSU9OLCBDb25zdGFudHMuU1lTVEVNX0JVTkRMRV9TWU1CT0xJQ05BTUUsIG51bGwsIG51bGwsIGNvbnRhaW5lcik7CgkJUmVzb2x1dGlvblJlcG9ydCByZXBvcnQgPSBjb250YWluZXIucmVzb2x2ZShBcnJheXMuYXNMaXN0KHN5c3RlbUJ1bmRsZSksIHRydWUpOwoJCUFzc2VydC5hc3NlcnROdWxsKCJGYWlsZWQgdG8gcmVzb2x2ZSBzeXN0ZW0uYnVuZGxlLiIsIHJlcG9ydC5nZXRSZXNvbHV0aW9uRXhjZXB0aW9uKCkpOwoJCXN5c3RlbUJ1bmRsZS5zdGFydCgpOwoKCQkvLyBpbnN0YWxsIGEgbW9kdWxlCgkJTWFwPFN0cmluZywgU3RyaW5nPiBtYW5pZmVzdCA9IG5ldyBIYXNoTWFwPFN0cmluZywgU3RyaW5nPigpOwoJCW1hbmlmZXN0LnB1dChDb25zdGFudHMuQlVORExFX01BTklGRVNUVkVSU0lPTiwgIjIiKTsKCQltYW5pZmVzdC5wdXQoQ29uc3RhbnRzLkJVTkRMRV9TWU1CT0xJQ05BTUUsICJtb2R1bGUudGVzdCIpOwoJCU1vZHVsZSBtb2R1bGUgPSBpbnN0YWxsRHVtbXlNb2R1bGUobWFuaWZlc3QsIG1hbmlmZXN0LmdldChDb25zdGFudHMuQlVORExFX1NZTUJPTElDTkFNRSksIGNvbnRhaW5lcik7CgkJYWRhcHRvci5zZXRTbG93ZG93bkV2ZW50cyh0cnVlKTsKCQltb2R1bGUuc2V0U3RhcnRMZXZlbCgxKTsKCQltb2R1bGUuc3RhcnQoKTsKCgkJTGlzdDxEdW1teUNvbnRhaW5lckV2ZW50PiBldmVudHMgPSBhZGFwdG9yLmdldERhdGFiYXNlKCkuZ2V0Q29udGFpbmVyRXZlbnRzKCk7CgkJZm9yIChEdW1teUNvbnRhaW5lckV2ZW50IGV2ZW50IDogZXZlbnRzKSB7CgkJCUFzc2VydC5hc3NlcnROb3RFcXVhbHMoIkZvdW5kIGFuIGVycm9yOiAiICsgZXZlbnQuZXJyb3IsIENvbnRhaW5lckV2ZW50LkVSUk9SLCBldmVudC50eXBlKTsKCQl9Cgl9CgoJQFRlc3QKCXB1YmxpYyB2b2lkIHRlc3RTeXN0ZW1CdW5kbGVPbkRlbWFuZEZyYWdtZW50cygpIHRocm93cyBCdW5kbGVFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKCQlEdW1teUNvbnRhaW5lckFkYXB0b3IgYWRhcHRvciA9IGNyZWF0ZUR1bW15QWRhcHRvcigpOwoJCU1vZHVsZUNvbnRhaW5lciBjb250YWluZXIgPSBhZGFwdG9yLmdldENvbnRhaW5lcigpOwoKCQkvLyBpbnN0YWxsIHRoZSBzeXN0ZW0uYnVuZGxlCgkJTW9kdWxlIHN5c3RlbUJ1bmRsZSA9IGluc3RhbGxEdW1teU1vZHVsZSgic3lzdGVtLmJ1bmRsZS5NRiIsIENvbnN0YW50cy5TWVNURU1fQlVORExFX0xPQ0FUSU9OLCBDb25zdGFudHMuU1lTVEVNX0JVTkRMRV9TWU1CT0xJQ05BTUUsIG51bGwsIG51bGwsIGNvbnRhaW5lcik7CgoJCS8vIGluc3RhbGwgYW4gZXF1aW5veCBmcmFnbWVudAoJCU1hcDxTdHJpbmcsIFN0cmluZz4gZXF1aW5veEZyYWdNYW5pZmVzdCA9IG5ldyBIYXNoTWFwPFN0cmluZywgU3RyaW5nPigpOwoJCWVxdWlub3hGcmFnTWFuaWZlc3QucHV0KENvbnN0YW50cy5CVU5ETEVfTUFOSUZFU1RWRVJTSU9OLCAiMiIpOwoJCWVxdWlub3hGcmFnTWFuaWZlc3QucHV0KENvbnN0YW50cy5CVU5ETEVfU1lNQk9MSUNOQU1FLCAiZXF1aW5veEZyYWciKTsKCQllcXVpbm94RnJhZ01hbmlmZXN0LnB1dChDb25zdGFudHMuRlJBR01FTlRfSE9TVCwgIm9yZy5lY2xpcHNlLm9zZ2kiKTsKCQlNb2R1bGUgZXF1aW5veEZyYWcgPSBpbnN0YWxsRHVtbXlNb2R1bGUoZXF1aW5veEZyYWdNYW5pZmVzdCwgImVxdWlub3hGcmFnIiwgY29udGFpbmVyKTsKCgkJLy8gaW5zdGFsbCBhIHN5c3RlbS5idW5kbGUgZnJhZ21lbnQKCQlNYXA8U3RyaW5nLCBTdHJpbmc+IHN5c3RlbUZyYWdNYW5pZmVzdCA9IG5ldyBIYXNoTWFwPFN0cmluZywgU3RyaW5nPigpOwoJCXN5c3RlbUZyYWdNYW5pZmVzdC5wdXQoQ29uc3RhbnRzLkJVTkRMRV9NQU5JRkVTVFZFUlNJT04sICIyIik7CgkJc3lzdGVtRnJhZ01hbmlmZXN0LnB1dChDb25zdGFudHMuQlVORExFX1NZTUJPTElDTkFNRSwgInN5c3RlbUZyYWciKTsKCQlzeXN0ZW1GcmFnTWFuaWZlc3QucHV0KENvbnN0YW50cy5GUkFHTUVOVF9IT1NULCAic3lzdGVtLmJ1bmRsZSIpOwoJCU1vZHVsZSBzeXN0ZW1GcmFnID0gaW5zdGFsbER1bW15TW9kdWxlKHN5c3RlbUZyYWdNYW5pZmVzdCwgInN5c3RlbUZyYWciLCBjb250YWluZXIpOwoKCQlSZXNvbHV0aW9uUmVwb3J0IHJlcG9ydCA9IGNvbnRhaW5lci5yZXNvbHZlKEFycmF5cy5hc0xpc3Qoc3lzdGVtQnVuZGxlKSwgdHJ1ZSk7CgkJQXNzZXJ0LmFzc2VydE51bGwoIkZhaWxlZCB0byByZXNvbHZlIHN5c3RlbS5idW5kbGUuIiwgcmVwb3J0LmdldFJlc29sdXRpb25FeGNlcHRpb24oKSk7CgoJCUxpc3Q8TW9kdWxlV2lyZT4gaG9zdFdpcmVzID0gc3lzdGVtQnVuZGxlLmdldEN1cnJlbnRSZXZpc2lvbigpLmdldFdpcmluZygpLmdldFByb3ZpZGVkTW9kdWxlV2lyZXMoSG9zdE5hbWVzcGFjZS5IT1NUX05BTUVTUEFDRSk7CgkJYXNzZXJ0RXF1YWxzKCJXcm9uZyBudW1iZXIgb2YgZnJhZ21lbnRzLiIsIDIsIGhvc3RXaXJlcy5zaXplKCkpOwoJCVNldDxNb2R1bGVSZXZpc2lvbj4gZnJhZ21lbnRSZXZpc2lvbnMgPSBuZXcgSGFzaFNldChBcnJheXMuYXNMaXN0KGVxdWlub3hGcmFnLmdldEN1cnJlbnRSZXZpc2lvbigpLCBzeXN0ZW1GcmFnLmdldEN1cnJlbnRSZXZpc2lvbigpKSk7CgkJZm9yIChNb2R1bGVXaXJlIGhvc3RXaXJlIDogaG9zdFdpcmVzKSB7CgkJCWlmICghZnJhZ21lbnRSZXZpc2lvbnMucmVtb3ZlKGhvc3RXaXJlLmdldFJlcXVpcmVyKCkpKSB7CgkJCQlBc3NlcnQuZmFpbCgiVW5leHBlY3RlZCBmcmFnbWVudCByZXZpc2lvbjogIiArIGhvc3RXaXJlLmdldFJlcXVpcmVyKCkpOwoJCQl9CgkJfQoJfQoKCUBUZXN0CglwdWJsaWMgdm9pZCB0ZXN0VW5yZXNvbHZlZEhvc3RXaXRoRnJhZ21lbnRDeWNsZSgpIHRocm93cyBCdW5kbGVFeGNlcHRpb24gewoJCUR1bW15Q29udGFpbmVyQWRhcHRvciBhZGFwdG9yID0gY3JlYXRlRHVtbXlBZGFwdG9yKCk7CgkJTW9kdWxlQ29udGFpbmVyIGNvbnRhaW5lciA9IGFkYXB0b3IuZ2V0Q29udGFpbmVyKCk7CgoJCS8vIGluc3RhbGwgYSBob3N0CgkJTWFwPFN0cmluZywgU3RyaW5nPiBob3N0TWFuaWZlc3QgPSBuZXcgSGFzaE1hcDxTdHJpbmcsIFN0cmluZz4oKTsKCQlob3N0TWFuaWZlc3QucHV0KENvbnN0YW50cy5CVU5ETEVfTUFOSUZFU1RWRVJTSU9OLCAiMiIpOwoJCWhvc3RNYW5pZmVzdC5wdXQoQ29uc3RhbnRzLkJVTkRMRV9TWU1CT0xJQ05BTUUsICJob3N0Iik7CgkJaG9zdE1hbmlmZXN0LnB1dChDb25zdGFudHMuQlVORExFX1ZFUlNJT04sICIxLjAiKTsKCQlob3N0TWFuaWZlc3QucHV0KENvbnN0YW50cy5FWFBPUlRfUEFDS0FHRSwgImhvc3QiKTsKCQlob3N0TWFuaWZlc3QucHV0KENvbnN0YW50cy5JTVBPUlRfUEFDS0FHRSwgImhvc3QuaW1wbCIpOwoJCWluc3RhbGxEdW1teU1vZHVsZShob3N0TWFuaWZlc3QsICJob3N0MTAiLCBjb250YWluZXIpOwoJCWhvc3RNYW5pZmVzdC5wdXQoQ29uc3RhbnRzLkJVTkRMRV9WRVJTSU9OLCAiMS4xIik7CgkJaW5zdGFsbER1bW15TW9kdWxlKGhvc3RNYW5pZmVzdCwgImhvc3QxMSIsIGNvbnRhaW5lcik7CgkJaG9zdE1hbmlmZXN0LnB1dChDb25zdGFudHMuQlVORExFX1ZFUlNJT04sICIxLjIiKTsKCQlpbnN0YWxsRHVtbXlNb2R1bGUoaG9zdE1hbmlmZXN0LCAiaG9zdDEyIiwgY29udGFpbmVyKTsKCQkvL2hvc3RNYW5pZmVzdC5wdXQoQ29uc3RhbnRzLkJVTkRMRV9WRVJTSU9OLCAiMS4zIik7CgkJLy9pbnN0YWxsRHVtbXlNb2R1bGUoaG9zdE1hbmlmZXN0LCAiaG9zdDEzIiwgY29udGFpbmVyKTsKCgkJLy8gaW5zdGFsbCBhIGhvc3QuaW1wbCBmcmFnbWVudAoJCU1hcDxTdHJpbmcsIFN0cmluZz4gaG9zdEltcGxNYW5pZmVzdCA9IG5ldyBIYXNoTWFwPFN0cmluZywgU3RyaW5nPigpOwoJCWhvc3RJbXBsTWFuaWZlc3QucHV0KENvbnN0YW50cy5CVU5ETEVfTUFOSUZFU1RWRVJTSU9OLCAiMiIpOwoJCWhvc3RJbXBsTWFuaWZlc3QucHV0KENvbnN0YW50cy5CVU5ETEVfU1lNQk9MSUNOQU1FLCAiaG9zdC5pbXBsIik7CgkJaG9zdEltcGxNYW5pZmVzdC5wdXQoQ29uc3RhbnRzLkVYUE9SVF9QQUNLQUdFLCAiaG9zdC5pbXBsIik7CgkJaG9zdEltcGxNYW5pZmVzdC5wdXQoQ29uc3RhbnRzLklNUE9SVF9QQUNLQUdFLCAiaG9zdCIpOwoJCWhvc3RJbXBsTWFuaWZlc3QucHV0KENvbnN0YW50cy5GUkFHTUVOVF9IT1NULCAiaG9zdCIpOwoJCWluc3RhbGxEdW1teU1vZHVsZShob3N0SW1wbE1hbmlmZXN0LCAiaG9zdEltcGwiLCBjb250YWluZXIpOwoKCQkvLyBpbnN0YWxsIGFuIGltcG9ydGVyIG9mIGhvc3QgcGFja2FnZQoJCU1hcDxTdHJpbmcsIFN0cmluZz4gaG9zdEltcG9ydGVyTWFuaWZlc3QgPSBuZXcgSGFzaE1hcDxTdHJpbmcsIFN0cmluZz4oKTsKCQlob3N0SW1wb3J0ZXJNYW5pZmVzdC5wdXQoQ29uc3RhbnRzLkJVTkRMRV9NQU5JRkVTVFZFUlNJT04sICIyIik7CgkJaG9zdEltcG9ydGVyTWFuaWZlc3QucHV0KENvbnN0YW50cy5CVU5ETEVfU1lNQk9MSUNOQU1FLCAiaG9zdC5pbXBvcnRlciIpOwoJCWhvc3RJbXBvcnRlck1hbmlmZXN0LnB1dChDb25zdGFudHMuSU1QT1JUX1BBQ0tBR0UsICJob3N0Iik7CgkJTW9kdWxlIGhvc3RJbXBvcnRlciA9IGluc3RhbGxEdW1teU1vZHVsZShob3N0SW1wb3J0ZXJNYW5pZmVzdCwgImhvc3RJbXBvcnRlciIsIGNvbnRhaW5lcik7CgoJCVJlc29sdXRpb25SZXBvcnQgcmVwb3J0ID0gY29udGFpbmVyLnJlc29sdmUoQXJyYXlzLmFzTGlzdChob3N0SW1wb3J0ZXIpLCB0cnVlKTsKCQlBc3NlcnQuYXNzZXJ0TnVsbCgiRmFpbGVkIHRvIHJlc29sdmUgdGVzdC4iLCByZXBvcnQuZ2V0UmVzb2x1dGlvbkV4Y2VwdGlvbigpKTsKCX0KCglAVGVzdAoJcHVibGljIHZvaWQgdGVzdE11bHRpSG9zdEZyYWdtZW50V2l0aE92ZXJsYXBJbXBvcnQoKSB0aHJvd3MgQnVuZGxlRXhjZXB0aW9uIHsKCQlEdW1teUNvbnRhaW5lckFkYXB0b3IgYWRhcHRvciA9IGNyZWF0ZUR1bW15QWRhcHRvcigpOwoJCU1vZHVsZUNvbnRhaW5lciBjb250YWluZXIgPSBhZGFwdG9yLmdldENvbnRhaW5lcigpOwoKCQkvLyBpbnN0YWxsIGFuIGV4cG9ydGVyCgkJTWFwPFN0cmluZywgU3RyaW5nPiBleHBvcnRlck1hbmlmZXN0ID0gbmV3IEhhc2hNYXA8U3RyaW5nLCBTdHJpbmc+KCk7CgkJZXhwb3J0ZXJNYW5pZmVzdC5wdXQoQ29uc3RhbnRzLkJVTkRMRV9NQU5JRkVTVFZFUlNJT04sICIyIik7CgkJZXhwb3J0ZXJNYW5pZmVzdC5wdXQoQ29uc3RhbnRzLkJVTkRMRV9TWU1CT0xJQ05BTUUsICJleHBvcnRlciIpOwoJCWV4cG9ydGVyTWFuaWZlc3QucHV0KENvbnN0YW50cy5CVU5ETEVfVkVSU0lPTiwgIjEuMCIpOwoJCWV4cG9ydGVyTWFuaWZlc3QucHV0KENvbnN0YW50cy5FWFBPUlRfUEFDS0FHRSwgImV4cG9ydGVyIik7CgkJaW5zdGFsbER1bW15TW9kdWxlKGV4cG9ydGVyTWFuaWZlc3QsICJleHBvcnRlciIsIGNvbnRhaW5lcik7CgoJCS8vIGluc3RhbGwgYSBmcmFnbWVudCB0byB0aGUgZXhwb3J0ZXIKCQlNYXA8U3RyaW5nLCBTdHJpbmc+IGV4cG9ydGVyRnJhZ01hbmlmZXN0ID0gbmV3IEhhc2hNYXA8U3RyaW5nLCBTdHJpbmc+KCk7CgkJZXhwb3J0ZXJGcmFnTWFuaWZlc3QucHV0KENvbnN0YW50cy5CVU5ETEVfTUFOSUZFU1RWRVJTSU9OLCAiMiIpOwoJCWV4cG9ydGVyRnJhZ01hbmlmZXN0LnB1dChDb25zdGFudHMuQlVORExFX1NZTUJPTElDTkFNRSwgImV4cG9ydGVyLmZyYWciKTsKCQlleHBvcnRlckZyYWdNYW5pZmVzdC5wdXQoQ29uc3RhbnRzLkVYUE9SVF9QQUNLQUdFLCAiZXhwb3J0ZXIuZnJhZyIpOwoJCWV4cG9ydGVyRnJhZ01hbmlmZXN0LnB1dChDb25zdGFudHMuRlJBR01FTlRfSE9TVCwgImV4cG9ydGVyIik7CgkJaW5zdGFsbER1bW15TW9kdWxlKGV4cG9ydGVyRnJhZ01hbmlmZXN0LCAiZXhwb3J0ZXIuZnJhZyIsIGNvbnRhaW5lcik7CgoJCS8vIGluc3RhbGwgYSBob3N0IHRoYXQgaW1wb3J0cyB0aGUgZXhwb3J0ZXIKCQlNYXA8U3RyaW5nLCBTdHJpbmc+IGhvc3RNYW5pZmVzdCA9IG5ldyBIYXNoTWFwPFN0cmluZywgU3RyaW5nPigpOwoJCWhvc3RNYW5pZmVzdC5wdXQoQ29uc3RhbnRzLkJVTkRMRV9NQU5JRkVTVFZFUlNJT04sICIyIik7CgkJaG9zdE1hbmlmZXN0LnB1dChDb25zdGFudHMuQlVORExFX1NZTUJPTElDTkFNRSwgImhvc3QiKTsKCQlob3N0TWFuaWZlc3QucHV0KENvbnN0YW50cy5CVU5ETEVfVkVSU0lPTiwgIjEuMCIpOwoJCWhvc3RNYW5pZmVzdC5wdXQoQ29uc3RhbnRzLklNUE9SVF9QQUNLQUdFLCAiZXhwb3J0ZXIiKTsKCQlpbnN0YWxsRHVtbXlNb2R1bGUoaG9zdE1hbmlmZXN0LCAiaG9zdDEwIiwgY29udGFpbmVyKTsKCQlob3N0TWFuaWZlc3QucHV0KENvbnN0YW50cy5CVU5ETEVfVkVSU0lPTiwgIjEuMSIpOwoJCWluc3RhbGxEdW1teU1vZHVsZShob3N0TWFuaWZlc3QsICJob3N0MTEiLCBjb250YWluZXIpOwoJCWhvc3RNYW5pZmVzdC5wdXQoQ29uc3RhbnRzLkJVTkRMRV9WRVJTSU9OLCAiMS4yIik7CgkJaW5zdGFsbER1bW15TW9kdWxlKGhvc3RNYW5pZmVzdCwgImhvc3QxMiIsIGNvbnRhaW5lcik7CgoJCS8vIGluc3RhbGwgYSBmcmFnbWVudCB0aGF0IGFsc28gaW1wb3J0cyB0aGUgZXhwb3J0ZXIKCQlNYXA8U3RyaW5nLCBTdHJpbmc+IGhvc3RGcmFnTWFuaWZlc3QgPSBuZXcgSGFzaE1hcDxTdHJpbmcsIFN0cmluZz4oKTsKCQlob3N0RnJhZ01hbmlmZXN0LnB1dChDb25zdGFudHMuQlVORExFX01BTklGRVNUVkVSU0lPTiwgIjIiKTsKCQlob3N0RnJhZ01hbmlmZXN0LnB1dChDb25zdGFudHMuQlVORExFX1NZTUJPTElDTkFNRSwgImhvc3QuZnJhZyIpOwoJCWhvc3RGcmFnTWFuaWZlc3QucHV0KENvbnN0YW50cy5GUkFHTUVOVF9IT1NULCAiaG9zdCIpOwoJCWhvc3RGcmFnTWFuaWZlc3QucHV0KENvbnN0YW50cy5JTVBPUlRfUEFDS0FHRSwgImV4cG9ydGVyOyB2ZXJzaW9uPTAuMCIpOwoJCU1vZHVsZSBob3N0RnJhZyA9IGluc3RhbGxEdW1teU1vZHVsZShob3N0RnJhZ01hbmlmZXN0LCAiaG9zdC5mcmFnIiwgY29udGFpbmVyKTsKCgkJUmVzb2x1dGlvblJlcG9ydCByZXBvcnQgPSBjb250YWluZXIucmVzb2x2ZShBcnJheXMuYXNMaXN0KGhvc3RGcmFnKSwgdHJ1ZSk7CgkJQXNzZXJ0LmFzc2VydE51bGwoIkZhaWxlZCB0byByZXNvbHZlIHRlc3QuIiwgcmVwb3J0LmdldFJlc29sdXRpb25FeGNlcHRpb24oKSk7Cgl9CgoJQFRlc3QKCXB1YmxpYyB2b2lkIHRlc3RNb2R1bGVXaXJpbmdUb1N0cmluZygpIHRocm93cyBCdW5kbGVFeGNlcHRpb24gewoJCUR1bW15Q29udGFpbmVyQWRhcHRvciBhZGFwdG9yID0gY3JlYXRlRHVtbXlBZGFwdG9yKCk7CgkJTW9kdWxlQ29udGFpbmVyIGNvbnRhaW5lciA9IGFkYXB0b3IuZ2V0Q29udGFpbmVyKCk7CgoJCS8vIGluc3RhbGwgYSB0ZXN0IG1vZHVsZQoJCU1hcDxTdHJpbmcsIFN0cmluZz4gdGVzdE1hbmlmZXN0ID0gbmV3IEhhc2hNYXA8U3RyaW5nLCBTdHJpbmc+KCk7CgkJdGVzdE1hbmlmZXN0LnB1dChDb25zdGFudHMuQlVORExFX01BTklGRVNUVkVSU0lPTiwgIjIiKTsKCQl0ZXN0TWFuaWZlc3QucHV0KENvbnN0YW50cy5CVU5ETEVfU1lNQk9MSUNOQU1FLCAidGVzdC5uYW1lIik7CgkJdGVzdE1hbmlmZXN0LnB1dChDb25zdGFudHMuQlVORExFX1ZFUlNJT04sICIxLjAiKTsKCQlNb2R1bGUgdGVzdE1vZHVsZSA9IGluc3RhbGxEdW1teU1vZHVsZSh0ZXN0TWFuaWZlc3QsICJob3N0MTAiLCBjb250YWluZXIpOwoKCQlSZXNvbHV0aW9uUmVwb3J0IHJlcG9ydCA9IGNvbnRhaW5lci5yZXNvbHZlKEFycmF5cy5hc0xpc3QodGVzdE1vZHVsZSksIHRydWUpOwoJCUFzc2VydC5hc3NlcnROdWxsKCJGYWlsZWQgdG8gcmVzb2x2ZSB0ZXN0LiIsIHJlcG9ydC5nZXRSZXNvbHV0aW9uRXhjZXB0aW9uKCkpOwoKCQlNb2R1bGVSZXZpc2lvbiByZXZpc2lvbiA9IHRlc3RNb2R1bGUuZ2V0Q3VycmVudFJldmlzaW9uKCk7CgkJTW9kdWxlV2lyaW5nIHdpcmluZyA9IHJldmlzaW9uLmdldFdpcmluZygpOwoJCUFzc2VydC5hc3NlcnRFcXVhbHMoIlVuZXhwZWN0ZWQgd2lyaW5nLnRvU3RyaW5nKCkiLCByZXZpc2lvbi50b1N0cmluZygpLCB3aXJpbmcudG9TdHJpbmcoKSk7Cgl9CgoJQFRlc3QKCXB1YmxpYyB2b2lkIHRlc3RTdGFydE9uUmVzb2x2ZSgpIHRocm93cyBCdW5kbGVFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKCQlkb1Rlc3RTdGFydE9uUmVzb2x2ZSh0cnVlKTsKCX0KCglAVGVzdAoJcHVibGljIHZvaWQgdGVzdERpc2FibGVTdGFydE9uUmVzb2x2ZSgpIHRocm93cyBCdW5kbGVFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKCQlkb1Rlc3RTdGFydE9uUmVzb2x2ZShmYWxzZSk7Cgl9CgoJcHJpdmF0ZSB2b2lkIGRvVGVzdFN0YXJ0T25SZXNvbHZlKGJvb2xlYW4gZW5hYmxlZCkgdGhyb3dzIEJ1bmRsZUV4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewoJCU1hcDxTdHJpbmcsIFN0cmluZz4gY29uZmlndXJhdGlvbiA9IG5ldyBIYXNoTWFwPFN0cmluZywgU3RyaW5nPigpOwoJCWlmICghZW5hYmxlZCkgewoJCQljb25maWd1cmF0aW9uLnB1dChFcXVpbm94Q29uZmlndXJhdGlvbi5QUk9QX01PRFVMRV9BVVRPX1NUQVJUX09OX1JFU09MVkUsIEJvb2xlYW4udG9TdHJpbmcoZmFsc2UpKTsKCQl9CgkJRHVtbXlDb250YWluZXJBZGFwdG9yIGFkYXB0b3IgPSBuZXcgRHVtbXlDb250YWluZXJBZGFwdG9yKG5ldyBEdW1teUNvbGxpc2lvbkhvb2soZmFsc2UpLCBjb25maWd1cmF0aW9uKTsKCQlNb2R1bGVDb250YWluZXIgY29udGFpbmVyID0gYWRhcHRvci5nZXRDb250YWluZXIoKTsKCgkJLy8gaW5zdGFsbCB0aGUgc3lzdGVtLmJ1bmRsZQoJCU1vZHVsZSBzeXN0ZW1CdW5kbGUgPSBpbnN0YWxsRHVtbXlNb2R1bGUoInN5c3RlbS5idW5kbGUuTUYiLCBDb25zdGFudHMuU1lTVEVNX0JVTkRMRV9MT0NBVElPTiwgQ29uc3RhbnRzLlNZU1RFTV9CVU5ETEVfU1lNQk9MSUNOQU1FLCBudWxsLCBudWxsLCBjb250YWluZXIpOwoJCVJlc29sdXRpb25SZXBvcnQgcmVwb3J0ID0gY29udGFpbmVyLnJlc29sdmUoQXJyYXlzLmFzTGlzdChzeXN0ZW1CdW5kbGUpLCB0cnVlKTsKCQlBc3NlcnQuYXNzZXJ0TnVsbCgiRmFpbGVkIHRvIHJlc29sdmUgc3lzdGVtLmJ1bmRsZS4iLCByZXBvcnQuZ2V0UmVzb2x1dGlvbkV4Y2VwdGlvbigpKTsKCQlzeXN0ZW1CdW5kbGUuc3RhcnQoKTsKCgkJLy8gaW5zdGFsbCBhIGJ1bmNoIG9mIG1vZHVsZXMKCQlNYXA8U3RyaW5nLCBTdHJpbmc+IG1hbmlmZXN0ID0gbmV3IEhhc2hNYXA8U3RyaW5nLCBTdHJpbmc+KCk7CgkJTGlzdDxNb2R1bGU+IG1vZHVsZXMgPSBuZXcgQXJyYXlMaXN0PE1vZHVsZT4oKTsKCQlmb3IgKGludCBpID0gMDsgaSA8IDU7IGkrKykgewoJCQltYW5pZmVzdC5jbGVhcigpOwoJCQltYW5pZmVzdC5wdXQoQ29uc3RhbnRzLkJVTkRMRV9NQU5JRkVTVFZFUlNJT04sICIyIik7CgkJCW1hbmlmZXN0LnB1dChDb25zdGFudHMuQlVORExFX1NZTUJPTElDTkFNRSwgIm1vZHVsZS4iICsgaSk7CgkJCW1hbmlmZXN0LnB1dChDb25zdGFudHMuSU1QT1JUX1BBQ0tBR0UsICJleHBvcnQiKTsKCQkJTW9kdWxlIG1vZHVsZSA9IGluc3RhbGxEdW1teU1vZHVsZShtYW5pZmVzdCwgbWFuaWZlc3QuZ2V0KENvbnN0YW50cy5CVU5ETEVfU1lNQk9MSUNOQU1FKSwgY29udGFpbmVyKTsKCQkJdHJ5IHsKCQkJCW1vZHVsZS5zdGFydCgpOwoJCQkJZmFpbCgiZXhwZWN0ZWQgYSBidW5kbGUgZXhjZXB0aW9uLiIpOwoJCQl9IGNhdGNoIChCdW5kbGVFeGNlcHRpb24gZSkgewoJCQkJLy8gZG8gbm90aGluZwoJCQl9CgkJCW1vZHVsZXMuYWRkKG1vZHVsZSk7CgkJfQoKCQltYW5pZmVzdC5jbGVhcigpOwoJCW1hbmlmZXN0LnB1dChDb25zdGFudHMuQlVORExFX01BTklGRVNUVkVSU0lPTiwgIjIiKTsKCQltYW5pZmVzdC5wdXQoQ29uc3RhbnRzLkJVTkRMRV9TWU1CT0xJQ05BTUUsICJleHBvcnRlciIpOwoJCW1hbmlmZXN0LnB1dChDb25zdGFudHMuRVhQT1JUX1BBQ0tBR0UsICJleHBvcnQiKTsKCQlpbnN0YWxsRHVtbXlNb2R1bGUobWFuaWZlc3QsIG1hbmlmZXN0LmdldChDb25zdGFudHMuQlVORExFX1NZTUJPTElDTkFNRSksIGNvbnRhaW5lcik7CgoJCXJlcG9ydCA9IGNvbnRhaW5lci5yZXNvbHZlKENvbGxlY3Rpb25zLjxNb2R1bGU+IGVtcHR5U2V0KCksIGZhbHNlKTsKCQlBc3NlcnQuYXNzZXJ0TnVsbCgiRm91bmQgYSBlcnJvci4iLCByZXBvcnQuZ2V0UmVzb2x1dGlvbkV4Y2VwdGlvbigpKTsKCgkJU3RhdGUgZXhwZWN0ZWRTdGF0ZSA9IGVuYWJsZWQgPyBTdGF0ZS5BQ1RJVkUgOiBTdGF0ZS5SRVNPTFZFRDsKCQlmb3IgKE1vZHVsZSBtb2R1bGUgOiBtb2R1bGVzKSB7CgkJCUFzc2VydC5hc3NlcnRFcXVhbHMoIldyb25nIHN0YXRlLiIsIGV4cGVjdGVkU3RhdGUsIG1vZHVsZS5nZXRTdGF0ZSgpKTsKCQl9Cgl9CgoJQFRlc3QKCXB1YmxpYyB2b2lkIHRlc3RSZXNvbHZlRGVhZGxvY2soKSB0aHJvd3MgQnVuZGxlRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiwgSW50ZXJydXB0ZWRFeGNlcHRpb24gewoJCUR1bW15Q29udGFpbmVyQWRhcHRvciBhZGFwdG9yID0gY3JlYXRlRHVtbXlBZGFwdG9yKCk7CgkJTW9kdWxlQ29udGFpbmVyIGNvbnRhaW5lciA9IGFkYXB0b3IuZ2V0Q29udGFpbmVyKCk7CgoJCS8vIGluc3RhbGwgdGhlIHN5c3RlbS5idW5kbGUKCQlNb2R1bGUgc3lzdGVtQnVuZGxlID0gaW5zdGFsbER1bW15TW9kdWxlKCJzeXN0ZW0uYnVuZGxlLk1GIiwgQ29uc3RhbnRzLlNZU1RFTV9CVU5ETEVfTE9DQVRJT04sIENvbnN0YW50cy5TWVNURU1fQlVORExFX1NZTUJPTElDTkFNRSwgbnVsbCwgbnVsbCwgY29udGFpbmVyKTsKCQlSZXNvbHV0aW9uUmVwb3J0IHJlcG9ydCA9IGNvbnRhaW5lci5yZXNvbHZlKEFycmF5cy5hc0xpc3Qoc3lzdGVtQnVuZGxlKSwgdHJ1ZSk7CgkJQXNzZXJ0LmFzc2VydE51bGwoIkZhaWxlZCB0byByZXNvbHZlIHN5c3RlbS5idW5kbGUuIiwgcmVwb3J0LmdldFJlc29sdXRpb25FeGNlcHRpb24oKSk7CgkJc3lzdGVtQnVuZGxlLnN0YXJ0KCk7CgoJCS8vIGluc3RhbGwgYSBidW5jaCBvZiBtb2R1bGVzCgkJTWFwPFN0cmluZywgU3RyaW5nPiBtYW5pZmVzdCA9IG5ldyBIYXNoTWFwPFN0cmluZywgU3RyaW5nPigpOwoJCUxpc3Q8TW9kdWxlPiBtb2R1bGVzID0gbmV3IEFycmF5TGlzdDxNb2R1bGU+KCk7CgkJZm9yIChpbnQgaSA9IDA7IGkgPCA1OyBpKyspIHsKCQkJbWFuaWZlc3QuY2xlYXIoKTsKCQkJbWFuaWZlc3QucHV0KENvbnN0YW50cy5CVU5ETEVfTUFOSUZFU1RWRVJTSU9OLCAiMiIpOwoJCQltYW5pZmVzdC5wdXQoQ29uc3RhbnRzLkJVTkRMRV9TWU1CT0xJQ05BTUUsICJtb2R1bGUuIiArIGkpOwoJCQltb2R1bGVzLmFkZChpbnN0YWxsRHVtbXlNb2R1bGUobWFuaWZlc3QsIG1hbmlmZXN0LmdldChDb25zdGFudHMuQlVORExFX1NZTUJPTElDTkFNRSksIGNvbnRhaW5lcikpOwoJCX0KCQlhZGFwdG9yLnNldFNsb3dkb3duRXZlbnRzKHRydWUpOwoJCWZpbmFsIENvbmN1cnJlbnRMaW5rZWRRdWV1ZTxCdW5kbGVFeGNlcHRpb24+IHN0YXJ0RXJyb3JzID0gbmV3IENvbmN1cnJlbnRMaW5rZWRRdWV1ZTxCdW5kbGVFeGNlcHRpb24+KCk7CgkJZmluYWwgRXhlY3V0b3JTZXJ2aWNlIGV4ZWN1dG9yID0gRXhlY3V0b3JzLm5ld0ZpeGVkVGhyZWFkUG9vbCg1KTsKCQl0cnkgewoJCQlmb3IgKGZpbmFsIE1vZHVsZSBtb2R1bGUgOiBtb2R1bGVzKSB7CgoJCQkJZXhlY3V0b3IuZXhlY3V0ZShuZXcgUnVubmFibGUoKSB7CgoJCQkJCUBPdmVycmlkZQoJCQkJCXB1YmxpYyB2b2lkIHJ1bigpIHsKCQkJCQkJdHJ5IHsKCQkJCQkJCW1vZHVsZS5zdGFydCgpOwoJCQkJCQl9IGNhdGNoIChCdW5kbGVFeGNlcHRpb24gZSkgewoJCQkJCQkJc3RhcnRFcnJvcnMub2ZmZXIoZSk7CgkJCQkJCQllLnByaW50U3RhY2tUcmFjZSgpOwoJCQkJCQl9CgkJCQkJfQoJCQkJfSk7CgkJCX0KCQl9IGZpbmFsbHkgewoJCQlleGVjdXRvci5zaHV0ZG93bigpOwoJCQlleGVjdXRvci5hd2FpdFRlcm1pbmF0aW9uKDUsIFRpbWVVbml0Lk1JTlVURVMpOwoJCQlzeXN0ZW1CdW5kbGUuc3RvcCgpOwoJCX0KCgkJQXNzZXJ0LmFzc2VydE51bGwoIkZvdW5kIGEgZXJyb3IuIiwgc3RhcnRFcnJvcnMucG9sbCgpKTsKCQlMaXN0PER1bW15Q29udGFpbmVyRXZlbnQ+IGV2ZW50cyA9IGFkYXB0b3IuZ2V0RGF0YWJhc2UoKS5nZXRDb250YWluZXJFdmVudHMoKTsKCQlmb3IgKER1bW15Q29udGFpbmVyRXZlbnQgZXZlbnQgOiBldmVudHMpIHsKCQkJQXNzZXJ0LmFzc2VydE5vdEVxdWFscygiRm91bmQgYW4gZXJyb3IuIiwgQ29udGFpbmVyRXZlbnQuRVJST1IsIGV2ZW50LnR5cGUpOwoJCX0KCX0KCgljbGFzcyBSZWN1cnNlUmVzb2x2ZXJIb29rIGltcGxlbWVudHMgUmVzb2x2ZXJIb29rIHsKCQl2b2xhdGlsZSBNb2R1bGVDb250YWluZXIgY29udGFpbmVyOwoJCXZvbGF0aWxlIE1vZHVsZSBkeW5hbWljSW1wb3J0OwoJCWZpbmFsIEF0b21pY0ludGVnZXIgaWQgPSBuZXcgQXRvbWljSW50ZWdlcigpOwoJCUxpc3Q8SWxsZWdhbFN0YXRlRXhjZXB0aW9uPiBleHBlY3RlZEVycm9ycyA9IENvbGxlY3Rpb25zLnN5bmNocm9uaXplZExpc3QobmV3IEFycmF5TGlzdDxJbGxlZ2FsU3RhdGVFeGNlcHRpb24+KCkpOwoKCQlAT3ZlcnJpZGUKCQlwdWJsaWMgdm9pZCBmaWx0ZXJSZXNvbHZhYmxlKENvbGxlY3Rpb248QnVuZGxlUmV2aXNpb24+IGNhbmRpZGF0ZXMpIHsKCQkJTW9kdWxlQ29udGFpbmVyIGN1cnJlbnQgPSBjb250YWluZXI7CgkJCWlmIChjdXJyZW50ICE9IG51bGwpIHsKCQkJCWludCBuZXh0SWQgPSBpZC5pbmNyZW1lbnRBbmRHZXQoKTsKCQkJCWlmIChuZXh0SWQgPj0gMikgewoJCQkJCS8vIERvbid0IGRvIHRoaXMgYWdhaW4KCQkJCQlyZXR1cm47CgkJCQl9CgkJCQlNYXA8U3RyaW5nLCBTdHJpbmc+IG1hbmlmZXN0ID0gbmV3IEhhc2hNYXA8U3RyaW5nLCBTdHJpbmc+KCk7CgkJCQltYW5pZmVzdC5wdXQoQ29uc3RhbnRzLkJVTkRMRV9NQU5JRkVTVFZFUlNJT04sICIyIik7CgkJCQltYW5pZmVzdC5wdXQoQ29uc3RhbnRzLkJVTkRMRV9TWU1CT0xJQ05BTUUsICJtb2R1bGUucmVjdXJzZS4iICsgbmV4dElkKTsKCQkJCXRyeSB7CgkJCQkJTW9kdWxlIG0gPSBpbnN0YWxsRHVtbXlNb2R1bGUobWFuaWZlc3QsIG1hbmlmZXN0LmdldChDb25zdGFudHMuQlVORExFX1NZTUJPTElDTkFNRSksIGN1cnJlbnQpOwoJCQkJCVJlc29sdXRpb25SZXBvcnQgcmVwb3J0ID0gY3VycmVudC5yZXNvbHZlKENvbGxlY3Rpb25zLnNpbmdsZXRvbihtKSwgZmFsc2UpOwoJCQkJCXJlcG9ydC5nZXRSZXNvbHV0aW9uRXhjZXB0aW9uKCk7CgkJCQl9IGNhdGNoIChJbGxlZ2FsU3RhdGVFeGNlcHRpb24gZSkgewoJCQkJCWV4cGVjdGVkRXJyb3JzLmFkZChlKTsKCQkJCX0gY2F0Y2ggKEJ1bmRsZUV4Y2VwdGlvbiBlKSB7CgkJCQkJLy8gVE9ETyBBdXRvLWdlbmVyYXRlZCBjYXRjaCBibG9jawoJCQkJCWUucHJpbnRTdGFja1RyYWNlKCk7CgkJCQl9CgoJCQkJTW9kdWxlIGN1ckR5bmFtaWNJbXBvcnQgPSBkeW5hbWljSW1wb3J0OwoJCQkJaWYgKGN1ckR5bmFtaWNJbXBvcnQgIT0gbnVsbCkgewoJCQkJCXRyeSB7CgkJCQkJCWN1cnJlbnQucmVzb2x2ZUR5bmFtaWMoIm9yZy5vc2dpLmZyYW1ld29yayIsIGN1ckR5bmFtaWNJbXBvcnQuZ2V0Q3VycmVudFJldmlzaW9uKCkpOwoJCQkJCX0gY2F0Y2ggKElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBlKSB7CgkJCQkJCWV4cGVjdGVkRXJyb3JzLmFkZChlKTsKCQkJCQl9CgkJCQl9CgkJCX0KCQl9CgoJCUBPdmVycmlkZQoJCXB1YmxpYyB2b2lkIGZpbHRlclNpbmdsZXRvbkNvbGxpc2lvbnMoQnVuZGxlQ2FwYWJpbGl0eSBzaW5nbGV0b24sIENvbGxlY3Rpb248QnVuZGxlQ2FwYWJpbGl0eT4gY29sbGlzaW9uQ2FuZGlkYXRlcykgewoJCQkvLyBub3RoaW5nCgkJfQoKCQlAT3ZlcnJpZGUKCQlwdWJsaWMgdm9pZCBmaWx0ZXJNYXRjaGVzKEJ1bmRsZVJlcXVpcmVtZW50IHJlcXVpcmVtZW50LCBDb2xsZWN0aW9uPEJ1bmRsZUNhcGFiaWxpdHk+IGNhbmRpZGF0ZXMpIHsKCQkJLy8gbm90aGluZwoJCX0KCgkJQE92ZXJyaWRlCgkJcHVibGljIHZvaWQgZW5kKCkgewoJCQkvLyBub3RoaW5nCgkJfQoKCQlMaXN0PElsbGVnYWxTdGF0ZUV4Y2VwdGlvbj4gZ2V0RXhwZWN0ZWRFcnJvcnMoKSB7CgkJCXJldHVybiBuZXcgQXJyYXlMaXN0PD4oZXhwZWN0ZWRFcnJvcnMpOwoJCX0KCX0KCglAVGVzdAoJcHVibGljIHZvaWQgdGVzdFJlY3Vyc2VSZXNvbHV0aW9uUGVybWl0cygpIHRocm93cyBCdW5kbGVFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKCQlSZWN1cnNlUmVzb2x2ZXJIb29rIHJlc29sdmVySG9vayA9IG5ldyBSZWN1cnNlUmVzb2x2ZXJIb29rKCk7CgkJRHVtbXlDb250YWluZXJBZGFwdG9yIGFkYXB0b3IgPSBjcmVhdGVEdW1teUFkYXB0b3IocmVzb2x2ZXJIb29rKTsKCQlmaW5hbCBNb2R1bGVDb250YWluZXIgY29udGFpbmVyID0gYWRhcHRvci5nZXRDb250YWluZXIoKTsKCgkJLy8gaW5zdGFsbCB0aGUgc3lzdGVtLmJ1bmRsZQoJCU1vZHVsZSBzeXN0ZW1CdW5kbGUgPSBpbnN0YWxsRHVtbXlNb2R1bGUoInN5c3RlbS5idW5kbGUuTUYiLCBDb25zdGFudHMuU1lTVEVNX0JVTkRMRV9MT0NBVElPTiwgQ29uc3RhbnRzLlNZU1RFTV9CVU5ETEVfU1lNQk9MSUNOQU1FLCBudWxsLCBudWxsLCBjb250YWluZXIpOwoJCVJlc29sdXRpb25SZXBvcnQgcmVwb3J0ID0gY29udGFpbmVyLnJlc29sdmUoQXJyYXlzLmFzTGlzdChzeXN0ZW1CdW5kbGUpLCB0cnVlKTsKCQlBc3NlcnQuYXNzZXJ0TnVsbCgiRmFpbGVkIHRvIHJlc29sdmUgc3lzdGVtLmJ1bmRsZS4iLCByZXBvcnQuZ2V0UmVzb2x1dGlvbkV4Y2VwdGlvbigpKTsKCQlzeXN0ZW1CdW5kbGUuc3RhcnQoKTsKCgkJLy8gaW5zdGFsbCBhIGJ1bmRsZSB0byBkbyBkeW5hbWljIHJlc29sdXRpb24gZnJvbQoJCU1hcDxTdHJpbmcsIFN0cmluZz4gbWFuaWZlc3QgPSBuZXcgSGFzaE1hcDxTdHJpbmcsIFN0cmluZz4oKTsKCQltYW5pZmVzdC5wdXQoQ29uc3RhbnRzLkJVTkRMRV9NQU5JRkVTVFZFUlNJT04sICIyIik7CgkJbWFuaWZlc3QucHV0KENvbnN0YW50cy5CVU5ETEVfU1lNQk9MSUNOQU1FLCAiZHluYW1pY0ltcG9ydCIpOwoJCW1hbmlmZXN0LnB1dChDb25zdGFudHMuRFlOQU1JQ0lNUE9SVF9QQUNLQUdFLCAiKiIpOwoJCWZpbmFsIE1vZHVsZSBkeW5hbWljSW1wb3J0ID0gaW5zdGFsbER1bW15TW9kdWxlKG1hbmlmZXN0LCBtYW5pZmVzdC5nZXQoQ29uc3RhbnRzLkJVTkRMRV9TWU1CT0xJQ05BTUUpLCBjb250YWluZXIpOwoJCWR5bmFtaWNJbXBvcnQuc3RhcnQoKTsKCQlyZXNvbHZlckhvb2suZHluYW1pY0ltcG9ydCA9IGR5bmFtaWNJbXBvcnQ7CgkJcmVzb2x2ZXJIb29rLmNvbnRhaW5lciA9IGNvbnRhaW5lcjsKCgkJZmluYWwgQXRvbWljUmVmZXJlbmNlPE1vZHVsZVdpcmU+IGR5bmFtaWNXaXJlID0gbmV3IEF0b21pY1JlZmVyZW5jZTw+KCk7CgkJUnVubmFibGUgcnVuRm9yRXZlbnRzID0gbmV3IFJ1bm5hYmxlKCkgewoJCQlAT3ZlcnJpZGUKCQkJcHVibGljIHZvaWQgcnVuKCkgewoJCQkJZHluYW1pY1dpcmUuc2V0KGNvbnRhaW5lci5yZXNvbHZlRHluYW1pYygib3JnLm9zZ2kuZnJhbWV3b3JrIiwgZHluYW1pY0ltcG9ydC5nZXRDdXJyZW50UmV2aXNpb24oKSkpOwoJCQl9CgkJfTsKCQlhZGFwdG9yLnNldFJ1bkZvckV2ZW50cyhydW5Gb3JFdmVudHMpOwoJCS8vIGluc3RhbGwgYSBidW5kbGUgdG8gcmVzb2x2ZQoJCW1hbmlmZXN0LmNsZWFyKCk7CgkJbWFuaWZlc3QucHV0KENvbnN0YW50cy5CVU5ETEVfTUFOSUZFU1RWRVJTSU9OLCAiMiIpOwoJCW1hbmlmZXN0LnB1dChDb25zdGFudHMuQlVORExFX1NZTUJPTElDTkFNRSwgImluaXRpYWwiKTsKCQlNb2R1bGUgbSA9IGluc3RhbGxEdW1teU1vZHVsZShtYW5pZmVzdCwgbWFuaWZlc3QuZ2V0KENvbnN0YW50cy5CVU5ETEVfU1lNQk9MSUNOQU1FKSwgY29udGFpbmVyKTsKCQltLnN0YXJ0KCk7CgoJCWFzc2VydE5vdE51bGwoIk5vIER5bmFtaWMgV2lyZSIsIGR5bmFtaWNXaXJlLmdldCgpKTsKCQlhc3NlcnRFcXVhbHMoIldyb25nIG51bWJlciBvZiBleGVjdGVkIGVycm9ycy4iLCAyLCByZXNvbHZlckhvb2suZ2V0RXhwZWN0ZWRFcnJvcnMoKS5zaXplKCkpOwoJfQoKCUBUZXN0CglwdWJsaWMgdm9pZCB0ZXN0U3lzdGVtQnVuZGxlRnJhZ21lbnRzUGFja2FnZUltcG9ydCgpIHRocm93cyBCdW5kbGVFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKCQkvLyBpbnN0YWxsIHRoZSBzeXN0ZW0uYnVuZGxlCgkJTW9kdWxlIHN5c3RlbUJ1bmRsZSA9IGNyZWF0ZUNvbnRhaW5lcldpdGhTeXN0ZW1CdW5kbGUodHJ1ZSk7CgkJTW9kdWxlQ29udGFpbmVyIGNvbnRhaW5lciA9IHN5c3RlbUJ1bmRsZS5nZXRDb250YWluZXIoKTsKCgkJLy8gaW5zdGFsbCBhbiBzeXN0ZW0uYnVuZGxlIGZyYWdtZW50IHRoYXQgaW1wb3J0cyBmcmFtZXdvcmsgcGFja2FnZQoJCU1hcDxTdHJpbmcsIFN0cmluZz4gc3lzdGVtRnJhZ01hbmlmZXN0ID0gbmV3IEhhc2hNYXA8U3RyaW5nLCBTdHJpbmc+KCk7CgkJc3lzdGVtRnJhZ01hbmlmZXN0LnB1dChDb25zdGFudHMuQlVORExFX01BTklGRVNUVkVSU0lPTiwgIjIiKTsKCQlzeXN0ZW1GcmFnTWFuaWZlc3QucHV0KENvbnN0YW50cy5CVU5ETEVfU1lNQk9MSUNOQU1FLCAic3lzdGVtRnJhZyIpOwoJCXN5c3RlbUZyYWdNYW5pZmVzdC5wdXQoQ29uc3RhbnRzLkZSQUdNRU5UX0hPU1QsIENvbnN0YW50cy5TWVNURU1fQlVORExFX1NZTUJPTElDTkFNRSk7CgkJc3lzdGVtRnJhZ01hbmlmZXN0LnB1dChDb25zdGFudHMuSU1QT1JUX1BBQ0tBR0UsICJvcmcub3NnaS5mcmFtZXdvcmsiKTsKCgkJTW9kdWxlIHN5c3RlbUZyYWcgPSBpbnN0YWxsRHVtbXlNb2R1bGUoc3lzdGVtRnJhZ01hbmlmZXN0LCAic3lzdGVtRnJhZyIsIGNvbnRhaW5lcik7CgoJCVJlc29sdXRpb25SZXBvcnQgcmVwb3J0ID0gY29udGFpbmVyLnJlc29sdmUoQXJyYXlzLmFzTGlzdChzeXN0ZW1GcmFnKSwgdHJ1ZSk7CgkJQXNzZXJ0LmFzc2VydE51bGwoIkZhaWxlZCB0byByZXNvbHZlIHN5c3RlbS5idW5kbGUuIiwgcmVwb3J0LmdldFJlc29sdXRpb25FeGNlcHRpb24oKSk7CgoJCUxpc3Q8TW9kdWxlV2lyZT4gaG9zdFdpcmVzID0gc3lzdGVtQnVuZGxlLmdldEN1cnJlbnRSZXZpc2lvbigpLmdldFdpcmluZygpLmdldFByb3ZpZGVkTW9kdWxlV2lyZXMoSG9zdE5hbWVzcGFjZS5IT1NUX05BTUVTUEFDRSk7CgkJYXNzZXJ0RXF1YWxzKCJXcm9uZyBudW1iZXIgb2YgZnJhZ21lbnRzLiIsIDEsIGhvc3RXaXJlcy5zaXplKCkpOwoJCUFzc2VydC5hc3NlcnRFcXVhbHMoIlVuZXhwZWN0ZWQgZnJhZ21lbnQgcmV2aXNpb246ICIgKyBob3N0V2lyZXMsIHN5c3RlbUZyYWcuZ2V0Q3VycmVudFJldmlzaW9uKCksIGhvc3RXaXJlcy5nZXQoMCkuZ2V0UmVxdWlyZXIoKSk7CgoJCUxpc3Q8TW9kdWxlV2lyZT4gc3lzdGVtQnVuZGxlUmVxdWlyZWRXaXJlcyA9IHN5c3RlbUJ1bmRsZS5nZXRDdXJyZW50UmV2aXNpb24oKS5nZXRXaXJpbmcoKS5nZXRSZXF1aXJlZE1vZHVsZVdpcmVzKG51bGwpOwoJCWFzc2VydEVxdWFscygiTm8gcmVxdWlyZWQgd2lyZXMgZXhwZWN0ZWQuIiwgMCwgc3lzdGVtQnVuZGxlUmVxdWlyZWRXaXJlcy5zaXplKCkpOwoJfQoKCUBUZXN0CglwdWJsaWMgdm9pZCB0ZXN0U3lzdGVtQnVuZGxlRnJhZ21lbnRzTm9uUGF5bG9hZFJlcXVpcmVtZW50cygpIHRocm93cyBCdW5kbGVFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKCQkvLyBpbnN0YWxsIHRoZSBzeXN0ZW0uYnVuZGxlCgkJTW9kdWxlIHN5c3RlbUJ1bmRsZSA9IGNyZWF0ZUNvbnRhaW5lcldpdGhTeXN0ZW1CdW5kbGUodHJ1ZSk7CgkJTW9kdWxlQ29udGFpbmVyIGNvbnRhaW5lciA9IHN5c3RlbUJ1bmRsZS5nZXRDb250YWluZXIoKTsKCgkJLy8gaW5zdGFsbCBhbiBzeXN0ZW0uYnVuZGxlIGZyYWdtZW50IHRoYXQgaW1wb3J0cyBmcmFtZXdvcmsgcGFja2FnZQoJCU1hcDxTdHJpbmcsIFN0cmluZz4gc3lzdGVtRnJhZ01hbmlmZXN0ID0gbmV3IEhhc2hNYXA8U3RyaW5nLCBTdHJpbmc+KCk7CgkJc3lzdGVtRnJhZ01hbmlmZXN0LnB1dChDb25zdGFudHMuQlVORExFX01BTklGRVNUVkVSU0lPTiwgIjIiKTsKCQlzeXN0ZW1GcmFnTWFuaWZlc3QucHV0KENvbnN0YW50cy5CVU5ETEVfU1lNQk9MSUNOQU1FLCAic3lzdGVtRnJhZyIpOwoJCXN5c3RlbUZyYWdNYW5pZmVzdC5wdXQoQ29uc3RhbnRzLkZSQUdNRU5UX0hPU1QsIENvbnN0YW50cy5TWVNURU1fQlVORExFX1NZTUJPTElDTkFNRSk7CgkJc3lzdGVtRnJhZ01hbmlmZXN0LnB1dChDb25zdGFudHMuUkVRVUlSRV9DQVBBQklMSVRZLCAib3NnaS5lZTsgZmlsdGVyOj1cIihvc2dpLmVlPUphdmFTRSlcIiIpOwoKCQlNb2R1bGUgc3lzdGVtRnJhZyA9IGluc3RhbGxEdW1teU1vZHVsZShzeXN0ZW1GcmFnTWFuaWZlc3QsICJzeXN0ZW1GcmFnIiwgY29udGFpbmVyKTsKCgkJUmVzb2x1dGlvblJlcG9ydCByZXBvcnQgPSBjb250YWluZXIucmVzb2x2ZShBcnJheXMuYXNMaXN0KHN5c3RlbUZyYWcpLCB0cnVlKTsKCQlBc3NlcnQuYXNzZXJ0TnVsbCgiRmFpbGVkIHRvIHJlc29sdmUgc3lzdGVtLmJ1bmRsZS4iLCByZXBvcnQuZ2V0UmVzb2x1dGlvbkV4Y2VwdGlvbigpKTsKCgkJTGlzdDxNb2R1bGVXaXJlPiBob3N0V2lyZXMgPSBzeXN0ZW1CdW5kbGUuZ2V0Q3VycmVudFJldmlzaW9uKCkuZ2V0V2lyaW5nKCkuZ2V0UHJvdmlkZWRNb2R1bGVXaXJlcyhIb3N0TmFtZXNwYWNlLkhPU1RfTkFNRVNQQUNFKTsKCQlhc3NlcnRFcXVhbHMoIldyb25nIG51bWJlciBvZiBmcmFnbWVudHMuIiwgMSwgaG9zdFdpcmVzLnNpemUoKSk7CgkJQXNzZXJ0LmFzc2VydEVxdWFscygiVW5leHBlY3RlZCBmcmFnbWVudCByZXZpc2lvbjogIiArIGhvc3RXaXJlcywgc3lzdGVtRnJhZy5nZXRDdXJyZW50UmV2aXNpb24oKSwgaG9zdFdpcmVzLmdldCgwKS5nZXRSZXF1aXJlcigpKTsKCgkJTGlzdDxNb2R1bGVXaXJlPiBzeXN0ZW1CdW5kbGVSZXF1aXJlZFdpcmVzID0gc3lzdGVtQnVuZGxlLmdldEN1cnJlbnRSZXZpc2lvbigpLmdldFdpcmluZygpLmdldFJlcXVpcmVkTW9kdWxlV2lyZXMobnVsbCk7CgkJYXNzZXJ0RXF1YWxzKCJObyByZXF1aXJlZCB3aXJlcyBleHBlY3RlZC4iLCAwLCBzeXN0ZW1CdW5kbGVSZXF1aXJlZFdpcmVzLnNpemUoKSk7CgoJCUxpc3Q8TW9kdWxlV2lyZT4gZnJhZ1JlcXVpcmVkV2lyZXMgPSBzeXN0ZW1GcmFnLmdldEN1cnJlbnRSZXZpc2lvbigpLmdldFdpcmluZygpLmdldFJlcXVpcmVkTW9kdWxlV2lyZXMobnVsbCk7CgkJYXNzZXJ0RXF1YWxzKCJXcm9uZyBudW1iZXIgb2YgcmVxdWlyZWQgd2lyZXMuIiwgMiwgZnJhZ1JlcXVpcmVkV2lyZXMuc2l6ZSgpKTsKCQlhc3NlcnRXaXJlcyhmcmFnUmVxdWlyZWRXaXJlcywgc3lzdGVtQnVuZGxlLmdldEN1cnJlbnRSZXZpc2lvbigpLmdldFdpcmluZygpLmdldFByb3ZpZGVkTW9kdWxlV2lyZXMobnVsbCkpOwoJfQoKCUBUZXN0CglwdWJsaWMgdm9pZCB0ZXN0U3lzdGVtQnVuZGxlRnJhZ21lbnRzV2l0aFBheWxvYWRSZXF1aXJlbWVudHMoKSB0aHJvd3MgQnVuZGxlRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CgkJLy8gaW5zdGFsbCB0aGUgc3lzdGVtLmJ1bmRsZQoJCU1vZHVsZSBzeXN0ZW1CdW5kbGUgPSBjcmVhdGVDb250YWluZXJXaXRoU3lzdGVtQnVuZGxlKHRydWUpOwoJCU1vZHVsZUNvbnRhaW5lciBjb250YWluZXIgPSBzeXN0ZW1CdW5kbGUuZ2V0Q29udGFpbmVyKCk7CgoJCS8vIGluc3RhbGwgYW4gc3lzdGVtLmJ1bmRsZSBmcmFnbWVudCB0aGF0IHJlcXVpcmVzIGEgcGF5bG9hZCByZXF1aXJlbWVudCBmcm9tIHN5c3RlbS5idW5kbGUKCQlNYXA8U3RyaW5nLCBTdHJpbmc+IHN5c3RlbUZyYWdNYW5pZmVzdCA9IG5ldyBIYXNoTWFwPFN0cmluZywgU3RyaW5nPigpOwoJCXN5c3RlbUZyYWdNYW5pZmVzdC5wdXQoQ29uc3RhbnRzLkJVTkRMRV9NQU5JRkVTVFZFUlNJT04sICIyIik7CgkJc3lzdGVtRnJhZ01hbmlmZXN0LnB1dChDb25zdGFudHMuQlVORExFX1NZTUJPTElDTkFNRSwgInN5c3RlbUZyYWciKTsKCQlzeXN0ZW1GcmFnTWFuaWZlc3QucHV0KENvbnN0YW50cy5GUkFHTUVOVF9IT1NULCBDb25zdGFudHMuU1lTVEVNX0JVTkRMRV9TWU1CT0xJQ05BTUUpOwoJCXN5c3RlbUZyYWdNYW5pZmVzdC5wdXQoQ29uc3RhbnRzLlJFUVVJUkVfQ0FQQUJJTElUWSwgImVxdWlub3gudGVzdDsgZmlsdGVyOj1cIihlcXVpbm94LnRlc3Q9c3lzdGVtKVwiIik7CgoJCU1vZHVsZSBzeXN0ZW1GcmFnID0gaW5zdGFsbER1bW15TW9kdWxlKHN5c3RlbUZyYWdNYW5pZmVzdCwgInN5c3RlbUZyYWciLCBjb250YWluZXIpOwoKCQlSZXNvbHV0aW9uUmVwb3J0IHJlcG9ydCA9IGNvbnRhaW5lci5yZXNvbHZlKEFycmF5cy5hc0xpc3Qoc3lzdGVtRnJhZyksIHRydWUpOwoJCUFzc2VydC5hc3NlcnROdWxsKCJGYWlsZWQgdG8gcmVzb2x2ZSBzeXN0ZW0uYnVuZGxlLiIsIHJlcG9ydC5nZXRSZXNvbHV0aW9uRXhjZXB0aW9uKCkpOwoKCQlMaXN0PE1vZHVsZVdpcmU+IGhvc3RXaXJlcyA9IHN5c3RlbUJ1bmRsZS5nZXRDdXJyZW50UmV2aXNpb24oKS5nZXRXaXJpbmcoKS5nZXRQcm92aWRlZE1vZHVsZVdpcmVzKEhvc3ROYW1lc3BhY2UuSE9TVF9OQU1FU1BBQ0UpOwoJCWFzc2VydEVxdWFscygiV3JvbmcgbnVtYmVyIG9mIGZyYWdtZW50cy4iLCAxLCBob3N0V2lyZXMuc2l6ZSgpKTsKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJVbmV4cGVjdGVkIGZyYWdtZW50IHJldmlzaW9uOiAiICsgaG9zdFdpcmVzLCBzeXN0ZW1GcmFnLmdldEN1cnJlbnRSZXZpc2lvbigpLCBob3N0V2lyZXMuZ2V0KDApLmdldFJlcXVpcmVyKCkpOwoKCQlMaXN0PE1vZHVsZVdpcmU+IHN5c3RlbUJ1bmRsZVJlcXVpcmVkV2lyZXMgPSBzeXN0ZW1CdW5kbGUuZ2V0Q3VycmVudFJldmlzaW9uKCkuZ2V0V2lyaW5nKCkuZ2V0UmVxdWlyZWRNb2R1bGVXaXJlcyhudWxsKTsKCQlhc3NlcnRFcXVhbHMoIldyb25nIG51bWJlciBvZiB3aXJlcy4iLCAxLCBzeXN0ZW1CdW5kbGVSZXF1aXJlZFdpcmVzLnNpemUoKSk7CgkJYXNzZXJ0RXF1YWxzKCJXcm9uZyByZXF1aXJlci4iLCBzeXN0ZW1CdW5kbGUuZ2V0Q3VycmVudFJldmlzaW9uKCksIHN5c3RlbUJ1bmRsZVJlcXVpcmVkV2lyZXMuZ2V0KDApLmdldFJlcXVpcmVyKCkpOwoJCWFzc2VydEVxdWFscygiV3JvbmcgcmVxdWlyZW1lbnQuIiwgc3lzdGVtRnJhZy5nZXRDdXJyZW50UmV2aXNpb24oKSwgc3lzdGVtQnVuZGxlUmVxdWlyZWRXaXJlcy5nZXQoMCkuZ2V0UmVxdWlyZW1lbnQoKS5nZXRSZXZpc2lvbigpKTsKCgkJTGlzdDxNb2R1bGVXaXJlPiBmcmFnUmVxdWlyZWRXaXJlcyA9IHN5c3RlbUZyYWcuZ2V0Q3VycmVudFJldmlzaW9uKCkuZ2V0V2lyaW5nKCkuZ2V0UmVxdWlyZWRNb2R1bGVXaXJlcyhudWxsKTsKCQlhc3NlcnRFcXVhbHMoIldyb25nIG51bWJlciBvZiByZXF1aXJlZCB3aXJlcy4iLCAxLCBmcmFnUmVxdWlyZWRXaXJlcy5zaXplKCkpOwoJCWFzc2VydFdpcmVzKGZyYWdSZXF1aXJlZFdpcmVzLCBob3N0V2lyZXMpOwoJfQoKCUBUZXN0CglwdWJsaWMgdm9pZCB0ZXN0U3lzdGVtQnVuZGxlRnJhZ21lbnRSZXF1aXJlc090aGVyRnJhZ21lbnQoKSB0aHJvd3MgQnVuZGxlRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CgkJLy8gaW5zdGFsbCB0aGUgc3lzdGVtLmJ1bmRsZQoJCU1vZHVsZSBzeXN0ZW1CdW5kbGUgPSBjcmVhdGVDb250YWluZXJXaXRoU3lzdGVtQnVuZGxlKHRydWUpOwoJCU1vZHVsZUNvbnRhaW5lciBjb250YWluZXIgPSBzeXN0ZW1CdW5kbGUuZ2V0Q29udGFpbmVyKCk7CgoJCS8vIGluc3RhbGwgYW4gc3lzdGVtLmJ1bmRsZSBmcmFnbWVudCB0aGF0IHByb3ZpZGVzIGEgY2FwYWJpbGl0eQoJCU1hcDxTdHJpbmcsIFN0cmluZz4gc3lzdGVtRnJhZ01hbmlmZXN0MSA9IG5ldyBIYXNoTWFwPFN0cmluZywgU3RyaW5nPigpOwoJCXN5c3RlbUZyYWdNYW5pZmVzdDEucHV0KENvbnN0YW50cy5CVU5ETEVfTUFOSUZFU1RWRVJTSU9OLCAiMiIpOwoJCXN5c3RlbUZyYWdNYW5pZmVzdDEucHV0KENvbnN0YW50cy5CVU5ETEVfU1lNQk9MSUNOQU1FLCAic3lzdGVtRnJhZzEiKTsKCQlzeXN0ZW1GcmFnTWFuaWZlc3QxLnB1dChDb25zdGFudHMuRlJBR01FTlRfSE9TVCwgQ29uc3RhbnRzLlNZU1RFTV9CVU5ETEVfU1lNQk9MSUNOQU1FKTsKCQlzeXN0ZW1GcmFnTWFuaWZlc3QxLnB1dChDb25zdGFudHMuUFJPVklERV9DQVBBQklMSVRZLCAiZnJhZ21lbnQuY2FwYWJpbGl0eTsgZnJhZ21lbnQuY2FwYWJpbGl0eT10ZXN0Iik7CgkJTW9kdWxlIHN5c3RlbUZyYWcxID0gaW5zdGFsbER1bW15TW9kdWxlKHN5c3RlbUZyYWdNYW5pZmVzdDEsICJzeXN0ZW1GcmFnMSIsIGNvbnRhaW5lcik7CgoJCS8vIGluc3RhbGwgYW4gc3lzdGVtLmJ1bmRsZSBmcmFnbWVudCB0aGF0IHJlcXVpcmVzIGEgZnJhZ21lbnQgY2FwYWJpbGl0eQoJCU1hcDxTdHJpbmcsIFN0cmluZz4gc3lzdGVtRnJhZ01hbmlmZXN0MiA9IG5ldyBIYXNoTWFwPFN0cmluZywgU3RyaW5nPigpOwoJCXN5c3RlbUZyYWdNYW5pZmVzdDIucHV0KENvbnN0YW50cy5CVU5ETEVfTUFOSUZFU1RWRVJTSU9OLCAiMiIpOwoJCXN5c3RlbUZyYWdNYW5pZmVzdDIucHV0KENvbnN0YW50cy5CVU5ETEVfU1lNQk9MSUNOQU1FLCAic3lzdGVtRnJhZzIiKTsKCQlzeXN0ZW1GcmFnTWFuaWZlc3QyLnB1dChDb25zdGFudHMuRlJBR01FTlRfSE9TVCwgQ29uc3RhbnRzLlNZU1RFTV9CVU5ETEVfU1lNQk9MSUNOQU1FKTsKCQlzeXN0ZW1GcmFnTWFuaWZlc3QyLnB1dChDb25zdGFudHMuUkVRVUlSRV9DQVBBQklMSVRZLCAiZnJhZ21lbnQuY2FwYWJpbGl0eTsgZmlsdGVyOj1cIihmcmFnbWVudC5jYXBhYmlsaXR5PXRlc3QpXCIiKTsKCQlNb2R1bGUgc3lzdGVtRnJhZzIgPSBpbnN0YWxsRHVtbXlNb2R1bGUoc3lzdGVtRnJhZ01hbmlmZXN0MiwgInN5c3RlbUZyYWcyIiwgY29udGFpbmVyKTsKCgkJUmVzb2x1dGlvblJlcG9ydCByZXBvcnQgPSBjb250YWluZXIucmVzb2x2ZShBcnJheXMuYXNMaXN0KHN5c3RlbUZyYWcyKSwgdHJ1ZSk7CgkJQXNzZXJ0LmFzc2VydE51bGwoIkZhaWxlZCB0byByZXNvbHZlIHN5c3RlbS5idW5kbGUuIiwgcmVwb3J0LmdldFJlc29sdXRpb25FeGNlcHRpb24oKSk7CgoJCUxpc3Q8TW9kdWxlV2lyZT4gaG9zdFdpcmVzID0gc3lzdGVtQnVuZGxlLmdldEN1cnJlbnRSZXZpc2lvbigpLmdldFdpcmluZygpLmdldFByb3ZpZGVkTW9kdWxlV2lyZXMoSG9zdE5hbWVzcGFjZS5IT1NUX05BTUVTUEFDRSk7CgkJYXNzZXJ0RXF1YWxzKCJXcm9uZyBudW1iZXIgb2YgZnJhZ21lbnRzLiIsIDIsIGhvc3RXaXJlcy5zaXplKCkpOwoKCQlMaXN0PE1vZHVsZVdpcmU+IHN5c3RlbUJ1bmRsZVJlcXVpcmVkV2lyZXMgPSBzeXN0ZW1CdW5kbGUuZ2V0Q3VycmVudFJldmlzaW9uKCkuZ2V0V2lyaW5nKCkuZ2V0UmVxdWlyZWRNb2R1bGVXaXJlcyhudWxsKTsKCQlhc3NlcnRFcXVhbHMoIldyb25nIG51bWJlciBvZiB3aXJlcy4iLCAxLCBzeXN0ZW1CdW5kbGVSZXF1aXJlZFdpcmVzLnNpemUoKSk7CgkJYXNzZXJ0RXF1YWxzKCJXcm9uZyByZXF1aXJlci4iLCBzeXN0ZW1CdW5kbGUuZ2V0Q3VycmVudFJldmlzaW9uKCksIHN5c3RlbUJ1bmRsZVJlcXVpcmVkV2lyZXMuZ2V0KDApLmdldFJlcXVpcmVyKCkpOwoJCWFzc2VydEVxdWFscygiV3JvbmcgcmVxdWlyZW1lbnQuIiwgc3lzdGVtRnJhZzIuZ2V0Q3VycmVudFJldmlzaW9uKCksIHN5c3RlbUJ1bmRsZVJlcXVpcmVkV2lyZXMuZ2V0KDApLmdldFJlcXVpcmVtZW50KCkuZ2V0UmV2aXNpb24oKSk7CgkJYXNzZXJ0RXF1YWxzKCJXcm9uZyBwcm92aWRlci4iLCBzeXN0ZW1CdW5kbGUuZ2V0Q3VycmVudFJldmlzaW9uKCksIHN5c3RlbUJ1bmRsZVJlcXVpcmVkV2lyZXMuZ2V0KDApLmdldFByb3ZpZGVyKCkpOwoJCWFzc2VydEVxdWFscygiV3JvbmcgY2FwYWJpbGl0eS4iLCBzeXN0ZW1GcmFnMS5nZXRDdXJyZW50UmV2aXNpb24oKSwgc3lzdGVtQnVuZGxlUmVxdWlyZWRXaXJlcy5nZXQoMCkuZ2V0Q2FwYWJpbGl0eSgpLmdldFJldmlzaW9uKCkpOwoKCQlMaXN0PE1vZHVsZVdpcmU+IGZyYWdSZXF1aXJlZFdpcmVzID0gc3lzdGVtRnJhZzIuZ2V0Q3VycmVudFJldmlzaW9uKCkuZ2V0V2lyaW5nKCkuZ2V0UmVxdWlyZWRNb2R1bGVXaXJlcyhudWxsKTsKCQlhc3NlcnRFcXVhbHMoIldyb25nIG51bWJlciBvZiByZXF1aXJlZCB3aXJlcy4iLCAxLCBmcmFnUmVxdWlyZWRXaXJlcy5zaXplKCkpOwoJCWFzc2VydFdpcmVzKGZyYWdSZXF1aXJlZFdpcmVzLCBob3N0V2lyZXMpOwoJfQoKCUBUZXN0CglwdWJsaWMgdm9pZCB0ZXN0U3lzdGVtQnVuZGxlRnJhZ21lbnRSZXF1aXJlc090aGVyRnJhZ21lbnRGYWlsUmVzb2x1dGlvbigpIHRocm93cyBCdW5kbGVFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKCQkvLyBpbnN0YWxsIHRoZSBzeXN0ZW0uYnVuZGxlCgkJTW9kdWxlIHN5c3RlbUJ1bmRsZSA9IGNyZWF0ZUNvbnRhaW5lcldpdGhTeXN0ZW1CdW5kbGUodHJ1ZSk7CgkJTW9kdWxlQ29udGFpbmVyIGNvbnRhaW5lciA9IHN5c3RlbUJ1bmRsZS5nZXRDb250YWluZXIoKTsKCgkJLy8gaW5zdGFsbCBhbiBzeXN0ZW0uYnVuZGxlIGZyYWdtZW50IHRoYXQgcHJvdmlkZXMgYSBjYXBhYmlsaXR5CgkJTWFwPFN0cmluZywgU3RyaW5nPiBzeXN0ZW1GcmFnTWFuaWZlc3QxID0gbmV3IEhhc2hNYXA8U3RyaW5nLCBTdHJpbmc+KCk7CgkJc3lzdGVtRnJhZ01hbmlmZXN0MS5wdXQoQ29uc3RhbnRzLkJVTkRMRV9NQU5JRkVTVFZFUlNJT04sICIyIik7CgkJc3lzdGVtRnJhZ01hbmlmZXN0MS5wdXQoQ29uc3RhbnRzLkJVTkRMRV9TWU1CT0xJQ05BTUUsICJzeXN0ZW1GcmFnMSIpOwoJCXN5c3RlbUZyYWdNYW5pZmVzdDEucHV0KENvbnN0YW50cy5GUkFHTUVOVF9IT1NULCBDb25zdGFudHMuU1lTVEVNX0JVTkRMRV9TWU1CT0xJQ05BTUUpOwoJCXN5c3RlbUZyYWdNYW5pZmVzdDEucHV0KENvbnN0YW50cy5QUk9WSURFX0NBUEFCSUxJVFksICJmcmFnbWVudC5jYXBhYmlsaXR5OyBmcmFnbWVudC5jYXBhYmlsaXR5PXRlc3QxIik7CgkJTW9kdWxlIHN5c3RlbUZyYWcxID0gaW5zdGFsbER1bW15TW9kdWxlKHN5c3RlbUZyYWdNYW5pZmVzdDEsICJzeXN0ZW1GcmFnMSIsIGNvbnRhaW5lcik7CgoJCS8vIGluc3RhbGwgYW4gc3lzdGVtLmJ1bmRsZSBmcmFnbWVudCB0aGF0IHJlcXVpcmVzIGEgZnJhZ21lbnQgY2FwYWJpbGl0eSwgYnV0IGZhaWxzIHRvIG1hdGNoCgkJTWFwPFN0cmluZywgU3RyaW5nPiBzeXN0ZW1GcmFnTWFuaWZlc3QyID0gbmV3IEhhc2hNYXA8U3RyaW5nLCBTdHJpbmc+KCk7CgkJc3lzdGVtRnJhZ01hbmlmZXN0Mi5wdXQoQ29uc3RhbnRzLkJVTkRMRV9NQU5JRkVTVFZFUlNJT04sICIyIik7CgkJc3lzdGVtRnJhZ01hbmlmZXN0Mi5wdXQoQ29uc3RhbnRzLkJVTkRMRV9TWU1CT0xJQ05BTUUsICJzeXN0ZW1GcmFnMiIpOwoJCXN5c3RlbUZyYWdNYW5pZmVzdDIucHV0KENvbnN0YW50cy5GUkFHTUVOVF9IT1NULCBDb25zdGFudHMuU1lTVEVNX0JVTkRMRV9TWU1CT0xJQ05BTUUpOwoJCXN5c3RlbUZyYWdNYW5pZmVzdDIucHV0KENvbnN0YW50cy5SRVFVSVJFX0NBUEFCSUxJVFksICJmcmFnbWVudC5jYXBhYmlsaXR5OyBmaWx0ZXI6PVwiKGZyYWdtZW50LmNhcGFiaWxpdHk9dGVzdDQpXCIiKTsKCQlzeXN0ZW1GcmFnTWFuaWZlc3QyLnB1dChDb25zdGFudHMuUFJPVklERV9DQVBBQklMSVRZLCAiZnJhZ21lbnQuY2FwYWJpbGl0eTsgZnJhZ21lbnQuY2FwYWJpbGl0eT10ZXN0MiIpOwoJCU1vZHVsZSBzeXN0ZW1GcmFnMiA9IGluc3RhbGxEdW1teU1vZHVsZShzeXN0ZW1GcmFnTWFuaWZlc3QyLCAic3lzdGVtRnJhZzIiLCBjb250YWluZXIpOwoKCQkvLyBpbnN0YWxsIGFuIHN5c3RlbS5idW5kbGUgZnJhZ21lbnQgdGhhdCByZXF1aXJlcyBhIGZyYWdtZW50IGNhcGFiaWxpdHkgZnJvbSBhIGZyYWdtZW50IHRoYXQgZmFpbHMgdG8gcmVzb2x2ZQoJCU1hcDxTdHJpbmcsIFN0cmluZz4gc3lzdGVtRnJhZ01hbmlmZXN0MyA9IG5ldyBIYXNoTWFwPFN0cmluZywgU3RyaW5nPigpOwoJCXN5c3RlbUZyYWdNYW5pZmVzdDMucHV0KENvbnN0YW50cy5CVU5ETEVfTUFOSUZFU1RWRVJTSU9OLCAiMiIpOwoJCXN5c3RlbUZyYWdNYW5pZmVzdDMucHV0KENvbnN0YW50cy5CVU5ETEVfU1lNQk9MSUNOQU1FLCAic3lzdGVtRnJhZzMiKTsKCQlzeXN0ZW1GcmFnTWFuaWZlc3QzLnB1dChDb25zdGFudHMuRlJBR01FTlRfSE9TVCwgQ29uc3RhbnRzLlNZU1RFTV9CVU5ETEVfU1lNQk9MSUNOQU1FKTsKCQlzeXN0ZW1GcmFnTWFuaWZlc3QzLnB1dChDb25zdGFudHMuUkVRVUlSRV9DQVBBQklMSVRZLCAiZnJhZ21lbnQuY2FwYWJpbGl0eTsgZmlsdGVyOj1cIihmcmFnbWVudC5jYXBhYmlsaXR5PXRlc3QyKVwiIik7CgkJc3lzdGVtRnJhZ01hbmlmZXN0My5wdXQoQ29uc3RhbnRzLlBST1ZJREVfQ0FQQUJJTElUWSwgImZyYWdtZW50LmNhcGFiaWxpdHk7IGZyYWdtZW50LmNhcGFiaWxpdHk9dGVzdDMiKTsKCQlNb2R1bGUgc3lzdGVtRnJhZzMgPSBpbnN0YWxsRHVtbXlNb2R1bGUoc3lzdGVtRnJhZ01hbmlmZXN0MywgInN5c3RlbUZyYWczIiwgY29udGFpbmVyKTsKCgkJUmVzb2x1dGlvblJlcG9ydCByZXBvcnQgPSBjb250YWluZXIucmVzb2x2ZShBcnJheXMuYXNMaXN0KHN5c3RlbUZyYWczKSwgdHJ1ZSk7CgkJQXNzZXJ0LmFzc2VydE5vdE51bGwoIkV4cGVjdGVkIGZhaWx1cmUgbWVzc2FnZSIsIHJlcG9ydC5nZXRSZXNvbHV0aW9uRXhjZXB0aW9uKCkpOwoKCQlMaXN0PE1vZHVsZVdpcmU+IGhvc3RXaXJlcyA9IHN5c3RlbUJ1bmRsZS5nZXRDdXJyZW50UmV2aXNpb24oKS5nZXRXaXJpbmcoKS5nZXRQcm92aWRlZE1vZHVsZVdpcmVzKEhvc3ROYW1lc3BhY2UuSE9TVF9OQU1FU1BBQ0UpOwoJCWFzc2VydEVxdWFscygiV3JvbmcgbnVtYmVyIG9mIGZyYWdtZW50cy4iLCAxLCBob3N0V2lyZXMuc2l6ZSgpKTsKCQlMaXN0PE1vZHVsZVdpcmU+IHN5c3RlbUZyYWcxSG9zdFdpcmVzID0gc3lzdGVtRnJhZzEuZ2V0Q3VycmVudFJldmlzaW9uKCkuZ2V0V2lyaW5nKCkuZ2V0UmVxdWlyZWRNb2R1bGVXaXJlcyhIb3N0TmFtZXNwYWNlLkhPU1RfTkFNRVNQQUNFKTsKCQlhc3NlcnRXaXJlcyhzeXN0ZW1GcmFnMUhvc3RXaXJlcywgaG9zdFdpcmVzKTsKCgkJLy8gaW5zdGFsbCBhIGJ1bmRsZSB0aGF0IGNhbiBzYXRpc2Z5IHRoZSBmYWlsZWQgcmVxdWlyZW1lbnQsIGJ1dCBpdCBzaG91bGQgbm90IGJlIGFsbG93ZWQgc2luY2UgaXQgaXMgbm90IGEgZnJhZ21lbnQKCQlNYXA8U3RyaW5nLCBTdHJpbmc+IHByb3ZpZGVDYXBhYmlsaXR5TWFuaWZlc3QxID0gbmV3IEhhc2hNYXA8U3RyaW5nLCBTdHJpbmc+KCk7CgkJcHJvdmlkZUNhcGFiaWxpdHlNYW5pZmVzdDEucHV0KENvbnN0YW50cy5CVU5ETEVfTUFOSUZFU1RWRVJTSU9OLCAiMiIpOwoJCXByb3ZpZGVDYXBhYmlsaXR5TWFuaWZlc3QxLnB1dChDb25zdGFudHMuQlVORExFX1NZTUJPTElDTkFNRSwgInByb3ZpZGVDYXBhYmlsaXR5QnVuZGxlMSIpOwoJCXByb3ZpZGVDYXBhYmlsaXR5TWFuaWZlc3QxLnB1dChDb25zdGFudHMuUFJPVklERV9DQVBBQklMSVRZLCAiZnJhZ21lbnQuY2FwYWJpbGl0eTsgZnJhZ21lbnQuY2FwYWJpbGl0eT10ZXN0NCIpOwoJCWluc3RhbGxEdW1teU1vZHVsZShwcm92aWRlQ2FwYWJpbGl0eU1hbmlmZXN0MSwgInByb3ZpZGVDYXBhYmlsaXR5QnVuZGxlMSIsIGNvbnRhaW5lcik7CgoJCWhvc3RXaXJlcyA9IHN5c3RlbUJ1bmRsZS5nZXRDdXJyZW50UmV2aXNpb24oKS5nZXRXaXJpbmcoKS5nZXRQcm92aWRlZE1vZHVsZVdpcmVzKEhvc3ROYW1lc3BhY2UuSE9TVF9OQU1FU1BBQ0UpOwoJCWFzc2VydEVxdWFscygiV3JvbmcgbnVtYmVyIG9mIGZyYWdtZW50cy4iLCAxLCBob3N0V2lyZXMuc2l6ZSgpKTsKCQlzeXN0ZW1GcmFnMUhvc3RXaXJlcyA9IHN5c3RlbUZyYWcxLmdldEN1cnJlbnRSZXZpc2lvbigpLmdldFdpcmluZygpLmdldFJlcXVpcmVkTW9kdWxlV2lyZXMoSG9zdE5hbWVzcGFjZS5IT1NUX05BTUVTUEFDRSk7CgkJYXNzZXJ0V2lyZXMoc3lzdGVtRnJhZzFIb3N0V2lyZXMsIGhvc3RXaXJlcyk7CgoJCS8vIGluc3RhbGwgYSBmcmFnbWVudCB0aGF0IHNhdGlzZmllcyB0aGUgZmFpbGVkIHJlcXVpcmVtZW50CgkJTWFwPFN0cmluZywgU3RyaW5nPiBzeXN0ZW1GcmFnTWFuaWZlc3Q0ID0gbmV3IEhhc2hNYXA8U3RyaW5nLCBTdHJpbmc+KCk7CgkJc3lzdGVtRnJhZ01hbmlmZXN0NC5wdXQoQ29uc3RhbnRzLkJVTkRMRV9NQU5JRkVTVFZFUlNJT04sICIyIik7CgkJc3lzdGVtRnJhZ01hbmlmZXN0NC5wdXQoQ29uc3RhbnRzLkJVTkRMRV9TWU1CT0xJQ05BTUUsICJzeXN0ZW1GcmFnNCIpOwoJCXN5c3RlbUZyYWdNYW5pZmVzdDQucHV0KENvbnN0YW50cy5GUkFHTUVOVF9IT1NULCBDb25zdGFudHMuU1lTVEVNX0JVTkRMRV9TWU1CT0xJQ05BTUUpOwoJCXN5c3RlbUZyYWdNYW5pZmVzdDQucHV0KENvbnN0YW50cy5QUk9WSURFX0NBUEFCSUxJVFksICJmcmFnbWVudC5jYXBhYmlsaXR5OyBmcmFnbWVudC5jYXBhYmlsaXR5PXRlc3Q0Iik7CgkJTW9kdWxlIHN5c3RlbUZyYWc0ID0gaW5zdGFsbER1bW15TW9kdWxlKHN5c3RlbUZyYWdNYW5pZmVzdDQsICJzeXN0ZW1GcmFnNCIsIGNvbnRhaW5lcik7CgoJCXJlcG9ydCA9IGNvbnRhaW5lci5yZXNvbHZlKEFycmF5cy5hc0xpc3Qoc3lzdGVtRnJhZzMpLCB0cnVlKTsKCQlBc3NlcnQuYXNzZXJ0TnVsbCgiRmFpbGVkIHRvIHJlc29sdmUuIiwgcmVwb3J0LmdldFJlc29sdXRpb25FeGNlcHRpb24oKSk7CgoJCWhvc3RXaXJlcyA9IHN5c3RlbUJ1bmRsZS5nZXRDdXJyZW50UmV2aXNpb24oKS5nZXRXaXJpbmcoKS5nZXRQcm92aWRlZE1vZHVsZVdpcmVzKEhvc3ROYW1lc3BhY2UuSE9TVF9OQU1FU1BBQ0UpOwoJCWFzc2VydEVxdWFscygiV3JvbmcgbnVtYmVyIG9mIGZyYWdtZW50cy4iLCA0LCBob3N0V2lyZXMuc2l6ZSgpKTsKCQlzeXN0ZW1GcmFnMUhvc3RXaXJlcyA9IHN5c3RlbUZyYWcxLmdldEN1cnJlbnRSZXZpc2lvbigpLmdldFdpcmluZygpLmdldFJlcXVpcmVkTW9kdWxlV2lyZXMoSG9zdE5hbWVzcGFjZS5IT1NUX05BTUVTUEFDRSk7CgkJTGlzdDxNb2R1bGVXaXJlPiBzeXN0ZW1GcmFnMkhvc3RXaXJlcyA9IHN5c3RlbUZyYWcyLmdldEN1cnJlbnRSZXZpc2lvbigpLmdldFdpcmluZygpLmdldFJlcXVpcmVkTW9kdWxlV2lyZXMoSG9zdE5hbWVzcGFjZS5IT1NUX05BTUVTUEFDRSk7CgkJTGlzdDxNb2R1bGVXaXJlPiBzeXN0ZW1GcmFnM0hvc3RXaXJlcyA9IHN5c3RlbUZyYWczLmdldEN1cnJlbnRSZXZpc2lvbigpLmdldFdpcmluZygpLmdldFJlcXVpcmVkTW9kdWxlV2lyZXMoSG9zdE5hbWVzcGFjZS5IT1NUX05BTUVTUEFDRSk7CgkJTGlzdDxNb2R1bGVXaXJlPiBzeXN0ZW1GcmFnNEhvc3RXaXJlcyA9IHN5c3RlbUZyYWc0LmdldEN1cnJlbnRSZXZpc2lvbigpLmdldFdpcmluZygpLmdldFJlcXVpcmVkTW9kdWxlV2lyZXMoSG9zdE5hbWVzcGFjZS5IT1NUX05BTUVTUEFDRSk7CgkJYXNzZXJ0V2lyZXMoc3lzdGVtRnJhZzFIb3N0V2lyZXMsIGhvc3RXaXJlcyk7CgkJYXNzZXJ0V2lyZXMoc3lzdGVtRnJhZzJIb3N0V2lyZXMsIGhvc3RXaXJlcyk7CgkJYXNzZXJ0V2lyZXMoc3lzdGVtRnJhZzNIb3N0V2lyZXMsIGhvc3RXaXJlcyk7CgkJYXNzZXJ0V2lyZXMoc3lzdGVtRnJhZzRIb3N0V2lyZXMsIGhvc3RXaXJlcyk7CgoJCUxpc3Q8TW9kdWxlQ2FwYWJpbGl0eT4gZnJhZ21lbnRDYXBhYmlsaXRpZXMgPSBzeXN0ZW1CdW5kbGUuZ2V0Q3VycmVudFJldmlzaW9uKCkuZ2V0V2lyaW5nKCkuZ2V0TW9kdWxlQ2FwYWJpbGl0aWVzKCJmcmFnbWVudC5jYXBhYmlsaXR5Iik7CgkJYXNzZXJ0RXF1YWxzKCJXcm9uZyBudW1iZXIgb2YgZnJhZ21lbnQgY2FwYWJpbGl0aWVzLiIsIDQsIGZyYWdtZW50Q2FwYWJpbGl0aWVzLnNpemUoKSk7CgkJLy8gVXNlIHNldCBzaW5jZSB0aGUgb3JkZXIgb2YgcmVxdWlyZWQgYW5kIHByb3ZpZGVkIHdpcmVzIHdpbGwgYmUgZGlmZmVyZW50CgkJU2V0PE1vZHVsZVdpcmU+IGhvc3RSZXF1aXJlZEZyYWdtZW50Q2FwV2lyZXMgPSBuZXcgSGFzaFNldDxNb2R1bGVXaXJlPihzeXN0ZW1CdW5kbGUuZ2V0Q3VycmVudFJldmlzaW9uKCkuZ2V0V2lyaW5nKCkuZ2V0UmVxdWlyZWRNb2R1bGVXaXJlcygiZnJhZ21lbnQuY2FwYWJpbGl0eSIpKTsKCQlTZXQ8TW9kdWxlV2lyZT4gaG9zdFByb3ZpZGVkRnJhZ21lbnRDYXBXaXJlcyA9IG5ldyBIYXNoU2V0PE1vZHVsZVdpcmU+KHN5c3RlbUJ1bmRsZS5nZXRDdXJyZW50UmV2aXNpb24oKS5nZXRXaXJpbmcoKS5nZXRQcm92aWRlZE1vZHVsZVdpcmVzKCJmcmFnbWVudC5jYXBhYmlsaXR5IikpOwoJCWFzc2VydEVxdWFscygiV3JvbmcgbnVtYmVyIG9mIHdpcmVzLiIsIDIsIGhvc3RQcm92aWRlZEZyYWdtZW50Q2FwV2lyZXMuc2l6ZSgpKTsKCQlhc3NlcnRFcXVhbHMoIldyb25nIHdpcmVzIGZvdW5kIGZyb20gaG9zdC4iLCBob3N0UmVxdWlyZWRGcmFnbWVudENhcFdpcmVzLCBob3N0UHJvdmlkZWRGcmFnbWVudENhcFdpcmVzKTsKCX0KCglAVGVzdAoJcHVibGljIHZvaWQgdGVzdE11bHRpcGxlU3lzdGVtQnVuZGxlRnJhZ21lbnRzV2l0aFNhbWVOYW1lKCkgdGhyb3dzIEJ1bmRsZUV4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewoJCS8vIGluc3RhbGwgdGhlIHN5c3RlbS5idW5kbGUKCQlNb2R1bGUgc3lzdGVtQnVuZGxlID0gY3JlYXRlQ29udGFpbmVyV2l0aFN5c3RlbUJ1bmRsZSh0cnVlKTsKCQlNb2R1bGVDb250YWluZXIgY29udGFpbmVyID0gc3lzdGVtQnVuZGxlLmdldENvbnRhaW5lcigpOwoKCQkvLyBpbnN0YWxsIG11bHRpcGxlIHZlcnNpb25zIG9mIHRoZSBzYW1lIGZyYWdtZW50CgkJTWFwPFN0cmluZywgU3RyaW5nPiBzeXN0ZW1GcmFnTWFuaWZlc3QxID0gbmV3IEhhc2hNYXA8U3RyaW5nLCBTdHJpbmc+KCk7CgkJc3lzdGVtRnJhZ01hbmlmZXN0MS5wdXQoQ29uc3RhbnRzLkJVTkRMRV9NQU5JRkVTVFZFUlNJT04sICIyIik7CgkJc3lzdGVtRnJhZ01hbmlmZXN0MS5wdXQoQ29uc3RhbnRzLkJVTkRMRV9TWU1CT0xJQ05BTUUsICJzeXN0ZW1GcmFnIik7CgkJc3lzdGVtRnJhZ01hbmlmZXN0MS5wdXQoQ29uc3RhbnRzLkJVTkRMRV9WRVJTSU9OLCAiMS4wIik7CgkJc3lzdGVtRnJhZ01hbmlmZXN0MS5wdXQoQ29uc3RhbnRzLkZSQUdNRU5UX0hPU1QsIENvbnN0YW50cy5TWVNURU1fQlVORExFX1NZTUJPTElDTkFNRSk7CgkJTW9kdWxlIHN5c3RlbUZyYWcxID0gaW5zdGFsbER1bW15TW9kdWxlKHN5c3RlbUZyYWdNYW5pZmVzdDEsICJzeXN0ZW1GcmFnMSIsIGNvbnRhaW5lcik7CgoJCS8vIGZpcnN0IGF0dGVtcHQgdG8gcmVzb2x2ZSB0aGUgbG93ZXN0IHZlcnNpb24gYmVmb3JlIGluc3RhbGxpbmcgdGhlIG90aGVycwoJCVJlc29sdXRpb25SZXBvcnQgcmVwb3J0ID0gY29udGFpbmVyLnJlc29sdmUoQXJyYXlzLmFzTGlzdChzeXN0ZW1GcmFnMSksIHRydWUpOwoJCUFzc2VydC5hc3NlcnROdWxsKCJVbmV4cGVjdGVkIGZhaWx1cmUgbWVzc2FnZSIsIHJlcG9ydC5nZXRSZXNvbHV0aW9uRXhjZXB0aW9uKCkpOwoKCQlMaXN0PE1vZHVsZVdpcmU+IGhvc3RXaXJlcyA9IHN5c3RlbUJ1bmRsZS5nZXRDdXJyZW50UmV2aXNpb24oKS5nZXRXaXJpbmcoKS5nZXRQcm92aWRlZE1vZHVsZVdpcmVzKEhvc3ROYW1lc3BhY2UuSE9TVF9OQU1FU1BBQ0UpOwoJCWFzc2VydEVxdWFscygiV3JvbmcgbnVtYmVyIG9mIGZyYWdtZW50cy4iLCAxLCBob3N0V2lyZXMuc2l6ZSgpKTsKCQlMaXN0PE1vZHVsZVdpcmU+IHN5c3RlbUZyYWcxSG9zdFdpcmVzID0gc3lzdGVtRnJhZzEuZ2V0Q3VycmVudFJldmlzaW9uKCkuZ2V0V2lyaW5nKCkuZ2V0UmVxdWlyZWRNb2R1bGVXaXJlcyhIb3N0TmFtZXNwYWNlLkhPU1RfTkFNRVNQQUNFKTsKCQlhc3NlcnRXaXJlcyhzeXN0ZW1GcmFnMUhvc3RXaXJlcywgaG9zdFdpcmVzKTsKCgkJTWFwPFN0cmluZywgU3RyaW5nPiBzeXN0ZW1GcmFnTWFuaWZlc3QyID0gbmV3IEhhc2hNYXA8U3RyaW5nLCBTdHJpbmc+KCk7CgkJc3lzdGVtRnJhZ01hbmlmZXN0Mi5wdXQoQ29uc3RhbnRzLkJVTkRMRV9NQU5JRkVTVFZFUlNJT04sICIyIik7CgkJc3lzdGVtRnJhZ01hbmlmZXN0Mi5wdXQoQ29uc3RhbnRzLkJVTkRMRV9TWU1CT0xJQ05BTUUsICJzeXN0ZW1GcmFnIik7CgkJc3lzdGVtRnJhZ01hbmlmZXN0Mi5wdXQoQ29uc3RhbnRzLkJVTkRMRV9WRVJTSU9OLCAiMi4wIik7CgkJc3lzdGVtRnJhZ01hbmlmZXN0Mi5wdXQoQ29uc3RhbnRzLkZSQUdNRU5UX0hPU1QsIENvbnN0YW50cy5TWVNURU1fQlVORExFX1NZTUJPTElDTkFNRSk7CgkJTW9kdWxlIHN5c3RlbUZyYWcyID0gaW5zdGFsbER1bW15TW9kdWxlKHN5c3RlbUZyYWdNYW5pZmVzdDIsICJzeXN0ZW1GcmFnMiIsIGNvbnRhaW5lcik7CgoJCU1hcDxTdHJpbmcsIFN0cmluZz4gc3lzdGVtRnJhZ01hbmlmZXN0MyA9IG5ldyBIYXNoTWFwPFN0cmluZywgU3RyaW5nPigpOwoJCXN5c3RlbUZyYWdNYW5pZmVzdDMucHV0KENvbnN0YW50cy5CVU5ETEVfTUFOSUZFU1RWRVJTSU9OLCAiMiIpOwoJCXN5c3RlbUZyYWdNYW5pZmVzdDMucHV0KENvbnN0YW50cy5CVU5ETEVfU1lNQk9MSUNOQU1FLCAic3lzdGVtRnJhZyIpOwoJCXN5c3RlbUZyYWdNYW5pZmVzdDMucHV0KENvbnN0YW50cy5CVU5ETEVfVkVSU0lPTiwgIjMuMCIpOwoJCXN5c3RlbUZyYWdNYW5pZmVzdDMucHV0KENvbnN0YW50cy5GUkFHTUVOVF9IT1NULCBDb25zdGFudHMuU1lTVEVNX0JVTkRMRV9TWU1CT0xJQ05BTUUpOwoJCU1vZHVsZSBzeXN0ZW1GcmFnMyA9IGluc3RhbGxEdW1teU1vZHVsZShzeXN0ZW1GcmFnTWFuaWZlc3QzLCAic3lzdGVtRnJhZzMiLCBjb250YWluZXIpOwoKCQlyZXBvcnQgPSBjb250YWluZXIucmVzb2x2ZShBcnJheXMuYXNMaXN0KHN5c3RlbUZyYWcyKSwgdHJ1ZSk7CgkJQXNzZXJ0LmFzc2VydE5vdE51bGwoIkV4cGVjdGVkIGZhaWx1cmUgbWVzc2FnZSIsIHJlcG9ydC5nZXRSZXNvbHV0aW9uRXhjZXB0aW9uKCkpOwoJCXJlcG9ydCA9IGNvbnRhaW5lci5yZXNvbHZlKEFycmF5cy5hc0xpc3Qoc3lzdGVtRnJhZzMpLCB0cnVlKTsKCQlBc3NlcnQuYXNzZXJ0Tm90TnVsbCgiRXhwZWN0ZWQgZmFpbHVyZSBtZXNzYWdlIiwgcmVwb3J0LmdldFJlc29sdXRpb25FeGNlcHRpb24oKSk7CgoJCWhvc3RXaXJlcyA9IHN5c3RlbUJ1bmRsZS5nZXRDdXJyZW50UmV2aXNpb24oKS5nZXRXaXJpbmcoKS5nZXRQcm92aWRlZE1vZHVsZVdpcmVzKEhvc3ROYW1lc3BhY2UuSE9TVF9OQU1FU1BBQ0UpOwoJCWFzc2VydEVxdWFscygiV3JvbmcgbnVtYmVyIG9mIGZyYWdtZW50cy4iLCAxLCBob3N0V2lyZXMuc2l6ZSgpKTsKCQlzeXN0ZW1GcmFnMUhvc3RXaXJlcyA9IHN5c3RlbUZyYWcxLmdldEN1cnJlbnRSZXZpc2lvbigpLmdldFdpcmluZygpLmdldFJlcXVpcmVkTW9kdWxlV2lyZXMoSG9zdE5hbWVzcGFjZS5IT1NUX05BTUVTUEFDRSk7CgkJYXNzZXJ0V2lyZXMoc3lzdGVtRnJhZzFIb3N0V2lyZXMsIGhvc3RXaXJlcyk7CgoJCS8vIHVuaW5zdGFsbCB0aGUgZnJhZ21lbnRzIHNvIHdlIGNhbiBzdGFydCBvdmVyCgkJY29udGFpbmVyLnVuaW5zdGFsbChzeXN0ZW1GcmFnMSk7CgkJY29udGFpbmVyLnVuaW5zdGFsbChzeXN0ZW1GcmFnMik7CgkJY29udGFpbmVyLnVuaW5zdGFsbChzeXN0ZW1GcmFnMyk7CgoJCS8vIHJlZnJlc2ggdGhlIHN5c3RlbSBidW5kbGUgdG8gZ2V0IG9ubHkgaXQgcmVzb2x2ZWQKCQlyZXBvcnQgPSBjb250YWluZXIucmVmcmVzaChDb2xsZWN0aW9ucy5zaW5nbGV0b24oc3lzdGVtQnVuZGxlKSk7CgkJQXNzZXJ0LmFzc2VydE51bGwoIlVuZXhwZWN0ZWQgZmFpbHVyZSBtZXNzYWdlIiwgcmVwb3J0LmdldFJlc29sdXRpb25FeGNlcHRpb24oKSk7CgkJaG9zdFdpcmVzID0gc3lzdGVtQnVuZGxlLmdldEN1cnJlbnRSZXZpc2lvbigpLmdldFdpcmluZygpLmdldFByb3ZpZGVkTW9kdWxlV2lyZXMoSG9zdE5hbWVzcGFjZS5IT1NUX05BTUVTUEFDRSk7CgkJYXNzZXJ0RXF1YWxzKCJXcm9uZyBudW1iZXIgb2YgZnJhZ21lbnRzLiIsIDAsIGhvc3RXaXJlcy5zaXplKCkpOwoKCQkvLyBpbnN0YWxsIHRoZSBmcmFnbWVudHMgYWdhaW4KCQlzeXN0ZW1GcmFnMSA9IGluc3RhbGxEdW1teU1vZHVsZShzeXN0ZW1GcmFnTWFuaWZlc3QxLCAic3lzdGVtRnJhZzEiLCBjb250YWluZXIpOwoJCXN5c3RlbUZyYWcyID0gaW5zdGFsbER1bW15TW9kdWxlKHN5c3RlbUZyYWdNYW5pZmVzdDIsICJzeXN0ZW1GcmFnMiIsIGNvbnRhaW5lcik7CgkJc3lzdGVtRnJhZzMgPSBpbnN0YWxsRHVtbXlNb2R1bGUoc3lzdGVtRnJhZ01hbmlmZXN0MywgInN5c3RlbUZyYWczIiwgY29udGFpbmVyKTsKCgkJcmVwb3J0ID0gY29udGFpbmVyLnJlc29sdmUoQXJyYXlzLmFzTGlzdChzeXN0ZW1GcmFnMSksIHRydWUpOwoJCUFzc2VydC5hc3NlcnROb3ROdWxsKCJFeHBlY3RlZCBmYWlsdXJlIG1lc3NhZ2UiLCByZXBvcnQuZ2V0UmVzb2x1dGlvbkV4Y2VwdGlvbigpKTsKCQlyZXBvcnQgPSBjb250YWluZXIucmVzb2x2ZShBcnJheXMuYXNMaXN0KHN5c3RlbUZyYWcyKSwgdHJ1ZSk7CgkJQXNzZXJ0LmFzc2VydE5vdE51bGwoIkV4cGVjdGVkIGZhaWx1cmUgbWVzc2FnZSIsIHJlcG9ydC5nZXRSZXNvbHV0aW9uRXhjZXB0aW9uKCkpOwoJCXJlcG9ydCA9IGNvbnRhaW5lci5yZXNvbHZlKEFycmF5cy5hc0xpc3Qoc3lzdGVtRnJhZzMpLCB0cnVlKTsKCQlBc3NlcnQuYXNzZXJ0TnVsbCgiVW5leHBlY3RlZCBmYWlsdXJlIG1lc3NhZ2UiLCByZXBvcnQuZ2V0UmVzb2x1dGlvbkV4Y2VwdGlvbigpKTsKCgkJaG9zdFdpcmVzID0gc3lzdGVtQnVuZGxlLmdldEN1cnJlbnRSZXZpc2lvbigpLmdldFdpcmluZygpLmdldFByb3ZpZGVkTW9kdWxlV2lyZXMoSG9zdE5hbWVzcGFjZS5IT1NUX05BTUVTUEFDRSk7CgkJTGlzdDxNb2R1bGVXaXJlPiBzeXN0ZW1GcmFnM0hvc3RXaXJlcyA9IHN5c3RlbUZyYWczLmdldEN1cnJlbnRSZXZpc2lvbigpLmdldFdpcmluZygpLmdldFJlcXVpcmVkTW9kdWxlV2lyZXMoSG9zdE5hbWVzcGFjZS5IT1NUX05BTUVTUEFDRSk7CgkJYXNzZXJ0V2lyZXMoc3lzdGVtRnJhZzNIb3N0V2lyZXMsIGhvc3RXaXJlcyk7Cgl9CgoJcHJpdmF0ZSBNb2R1bGUgY3JlYXRlQ29udGFpbmVyV2l0aFN5c3RlbUJ1bmRsZShib29sZWFuIHJlc29sdmVTeXN0ZW1CdW5kbGUpIHRocm93cyBCdW5kbGVFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKCQlEdW1teUNvbnRhaW5lckFkYXB0b3IgYWRhcHRvciA9IGNyZWF0ZUR1bW15QWRhcHRvcigpOwoJCU1vZHVsZUNvbnRhaW5lciBjb250YWluZXIgPSBhZGFwdG9yLmdldENvbnRhaW5lcigpOwoKCQkvLyBpbnN0YWxsIHRoZSBzeXN0ZW0uYnVuZGxlCgkJU3RyaW5nIHN5c3RlbUNhcGFiaWxpdHkgPSAib3NnaS5lZTsgb3NnaS5lZT1cIkphdmFTRVwiOyB2ZXJzaW9uOkxpc3Q8VmVyc2lvbj49XCIxLjAsIDEuMSwgMS4yLCAxLjMsIDEuNCwgMS41LCAxLjZcIiwgZXF1aW5veC50ZXN0OyBlcXVpbm94LnRlc3Q9c3lzdGVtLCBvc2dpLm5hdGl2ZTsgb3NnaS5uYXRpdmUub3NuYW1lPXRlc3QiOwoJCU1vZHVsZSBzeXN0ZW1CdW5kbGUgPSBpbnN0YWxsRHVtbXlNb2R1bGUoInN5c3RlbS5idW5kbGUuTUYiLCBDb25zdGFudHMuU1lTVEVNX0JVTkRMRV9MT0NBVElPTiwgQ29uc3RhbnRzLlNZU1RFTV9CVU5ETEVfU1lNQk9MSUNOQU1FLCBudWxsLCBzeXN0ZW1DYXBhYmlsaXR5LCBjb250YWluZXIpOwoJCWlmIChyZXNvbHZlU3lzdGVtQnVuZGxlKSB7CgkJCVJlc29sdXRpb25SZXBvcnQgcmVwb3J0ID0gY29udGFpbmVyLnJlc29sdmUoQ29sbGVjdGlvbnMuc2luZ2xldG9uKHN5c3RlbUJ1bmRsZSksIHRydWUpOwoJCQlBc3NlcnQuYXNzZXJ0TnVsbCgiRm91bmQgcmVzb2x1dGlvbiBleGNlcHRpb24uIiwgcmVwb3J0LmdldFJlc29sdXRpb25FeGNlcHRpb24oKSk7CgkJCUFzc2VydC5hc3NlcnRFcXVhbHMoIlN5c3RlbSBpcyBub3QgcmVzb2x2ZWQuIiwgU3RhdGUuUkVTT0xWRUQsIHN5c3RlbUJ1bmRsZS5nZXRTdGF0ZSgpKTsKCQl9CgoJCXJldHVybiBzeXN0ZW1CdW5kbGU7Cgl9CgoJQFRlc3QKCXB1YmxpYyB2b2lkIHRlc3RTcGxpdFBhY2thZ2VVc2VzMDEoKSB0aHJvd3MgQnVuZGxlRXhjZXB0aW9uIHsKCQlEdW1teUNvbnRhaW5lckFkYXB0b3IgYWRhcHRvciA9IGNyZWF0ZUR1bW15QWRhcHRvcigpOwoJCU1vZHVsZUNvbnRhaW5lciBjb250YWluZXIgPSBhZGFwdG9yLmdldENvbnRhaW5lcigpOwoKCQkvLyBpbnN0YWxsIGEgc3BsaXQgZXhwb3J0ZXIgY29yZSB0aGF0IHN1YnN0aXR1dGVzCgkJTWFwPFN0cmluZywgU3RyaW5nPiBjb3JlTWFuaWZlc3QgPSBuZXcgSGFzaE1hcDxTdHJpbmcsIFN0cmluZz4oKTsKCQljb3JlTWFuaWZlc3QucHV0KENvbnN0YW50cy5CVU5ETEVfTUFOSUZFU1RWRVJTSU9OLCAiMiIpOwoJCWNvcmVNYW5pZmVzdC5wdXQoQ29uc3RhbnRzLkJVTkRMRV9TWU1CT0xJQ05BTUUsICJjb3JlIik7CgkJY29yZU1hbmlmZXN0LnB1dChDb25zdGFudHMuRVhQT1JUX1BBQ0tBR0UsICJwa2cxOyBjb3JlPXNwbGl0OyBtYW5kYXRvcnk6PWNvcmUiKTsKCQljb3JlTWFuaWZlc3QucHV0KENvbnN0YW50cy5JTVBPUlRfUEFDS0FHRSwgInBrZzE7IGNvcmU9c3BsaXQiKTsKCgkJLy8gaW5zdGFsbCBhIHNwbGl0IGV4cG9ydGVyIG1pc2MgdGhhdCByZXF1aXJlcyBjb3JlIGFuZCBzdWJzdGl0dXRlcwoJCU1hcDxTdHJpbmcsIFN0cmluZz4gbWlzY01hbmlmZXN0ID0gbmV3IEhhc2hNYXA8U3RyaW5nLCBTdHJpbmc+KCk7CgkJbWlzY01hbmlmZXN0LnB1dChDb25zdGFudHMuQlVORExFX01BTklGRVNUVkVSU0lPTiwgIjIiKTsKCQltaXNjTWFuaWZlc3QucHV0KENvbnN0YW50cy5CVU5ETEVfU1lNQk9MSUNOQU1FLCAibWlzYyIpOwoJCW1pc2NNYW5pZmVzdC5wdXQoQ29uc3RhbnRzLkVYUE9SVF9QQUNLQUdFLCAicGtnMTsgbWlzYz1zcGxpdDsgbWFuZGF0b3J5Oj1taXNjIik7CgkJbWlzY01hbmlmZXN0LnB1dChDb25zdGFudHMuUkVRVUlSRV9CVU5ETEUsICJjb3JlIik7CgoJCS8vIGluc3RhbGwgYSBidW5kbGUgdGhhdCBpbXBvcnRzIGNvcmUgYW5kIGV4cG9ydHMgcGtnMiB0aGF0IHVzZXMgcGtnMSBmcm9tIGNvcmUKCQlNYXA8U3RyaW5nLCBTdHJpbmc+IGltcG9ydHNDb3JlTWFuaWZlc3QgPSBuZXcgSGFzaE1hcDxTdHJpbmcsIFN0cmluZz4oKTsKCQlpbXBvcnRzQ29yZU1hbmlmZXN0LnB1dChDb25zdGFudHMuQlVORExFX01BTklGRVNUVkVSU0lPTiwgIjIiKTsKCQlpbXBvcnRzQ29yZU1hbmlmZXN0LnB1dChDb25zdGFudHMuQlVORExFX1NZTUJPTElDTkFNRSwgImltcG9ydHNDb3JlIik7CgkJaW1wb3J0c0NvcmVNYW5pZmVzdC5wdXQoQ29uc3RhbnRzLkVYUE9SVF9QQUNLQUdFLCAicGtnMjsgdXNlczo9cGtnMSIpOwoJCWltcG9ydHNDb3JlTWFuaWZlc3QucHV0KENvbnN0YW50cy5JTVBPUlRfUEFDS0FHRSwgInBrZzE7IGNvcmU9c3BsaXQiKTsKCgkJLy8gaW5zdGFsbCBhIGJ1bmRsZSB0aGF0IGltcG9ydHMgcGtnMiwgYnV0IHJlcXVpcmVzIG1pc2MKCQlNYXA8U3RyaW5nLCBTdHJpbmc+IHJlcXVpcmVzTWlzY01hbmlmZXN0ID0gbmV3IEhhc2hNYXA8U3RyaW5nLCBTdHJpbmc+KCk7CgkJcmVxdWlyZXNNaXNjTWFuaWZlc3QucHV0KENvbnN0YW50cy5CVU5ETEVfTUFOSUZFU1RWRVJTSU9OLCAiMiIpOwoJCXJlcXVpcmVzTWlzY01hbmlmZXN0LnB1dChDb25zdGFudHMuQlVORExFX1NZTUJPTElDTkFNRSwgInJlcXVpcmVzTWlzYyIpOwoJCXJlcXVpcmVzTWlzY01hbmlmZXN0LnB1dChDb25zdGFudHMuSU1QT1JUX1BBQ0tBR0UsICJwa2cyIik7CgkJcmVxdWlyZXNNaXNjTWFuaWZlc3QucHV0KENvbnN0YW50cy5SRVFVSVJFX0JVTkRMRSwgIm1pc2MiKTsKCgkJaW5zdGFsbER1bW15TW9kdWxlKGNvcmVNYW5pZmVzdCwgImNvcmUiLCBjb250YWluZXIpOwoJCWluc3RhbGxEdW1teU1vZHVsZShtaXNjTWFuaWZlc3QsICJtaXNjIiwgY29udGFpbmVyKTsKCQlpbnN0YWxsRHVtbXlNb2R1bGUoaW1wb3J0c0NvcmVNYW5pZmVzdCwgImltcG9ydHNDb3JlIiwgY29udGFpbmVyKTsKCQlNb2R1bGUgcmVxdWlyZU1pc2MgPSBpbnN0YWxsRHVtbXlNb2R1bGUocmVxdWlyZXNNaXNjTWFuaWZlc3QsICJyZXF1aXJlTWlzYyIsIGNvbnRhaW5lcik7CgoJCVJlc29sdXRpb25SZXBvcnQgcmVwb3J0ID0gY29udGFpbmVyLnJlc29sdmUoQXJyYXlzLmFzTGlzdChyZXF1aXJlTWlzYyksIHRydWUpOwoJCUFzc2VydC5hc3NlcnROdWxsKCJGYWlsZWQgdG8gcmVzb2x2ZSB0ZXN0LiIsIHJlcG9ydC5nZXRSZXNvbHV0aW9uRXhjZXB0aW9uKCkpOwoKCQkvLyBub3cgdGVzdCBieSByZXNvbHZpbmcgdGhlIHNwbGl0IGV4cG9ydGVycyBmaXJzdAoJCWFkYXB0b3IgPSBjcmVhdGVEdW1teUFkYXB0b3IoKTsKCQljb250YWluZXIgPSBhZGFwdG9yLmdldENvbnRhaW5lcigpOwoKCQlpbnN0YWxsRHVtbXlNb2R1bGUoY29yZU1hbmlmZXN0LCAiY29yZSIsIGNvbnRhaW5lcik7CgkJTW9kdWxlIG1pc2MgPSBpbnN0YWxsRHVtbXlNb2R1bGUobWlzY01hbmlmZXN0LCAibWlzYyIsIGNvbnRhaW5lcik7CgkJcmVwb3J0ID0gY29udGFpbmVyLnJlc29sdmUoQXJyYXlzLmFzTGlzdChtaXNjKSwgdHJ1ZSk7CgkJQXNzZXJ0LmFzc2VydE51bGwoIkZhaWxlZCB0byByZXNvbHZlIHRlc3QuIiwgcmVwb3J0LmdldFJlc29sdXRpb25FeGNlcHRpb24oKSk7CgoJCWluc3RhbGxEdW1teU1vZHVsZShpbXBvcnRzQ29yZU1hbmlmZXN0LCAiaW1wb3J0c0NvcmUiLCBjb250YWluZXIpOwoJCXJlcXVpcmVNaXNjID0gaW5zdGFsbER1bW15TW9kdWxlKHJlcXVpcmVzTWlzY01hbmlmZXN0LCAicmVxdWlyZU1pc2MiLCBjb250YWluZXIpOwoJCXJlcG9ydCA9IGNvbnRhaW5lci5yZXNvbHZlKEFycmF5cy5hc0xpc3QocmVxdWlyZU1pc2MpLCB0cnVlKTsKCQlBc3NlcnQuYXNzZXJ0TnVsbCgiRmFpbGVkIHRvIHJlc29sdmUgdGVzdC4iLCByZXBvcnQuZ2V0UmVzb2x1dGlvbkV4Y2VwdGlvbigpKTsKCgkJLy8gbm93IHRlc3QgYnkgcmVzb2x2aW5nIHRoZSBzcGxpdCBleHBvcnRlcnMgZmlyc3Qgd2l0aCBhIHJlYWwgc3Vic3RpdHV0aW9uCgkJYWRhcHRvciA9IGNyZWF0ZUR1bW15QWRhcHRvcigpOwoJCWNvbnRhaW5lciA9IGFkYXB0b3IuZ2V0Q29udGFpbmVyKCk7CgoJCS8vIGluc3RhbGwgYSBleHBvcnRlciB0aGF0IHN1YnN0aXR1dGVzIGNvcmUncyBleHBvcnQKCQlNYXA8U3RyaW5nLCBTdHJpbmc+IHN1YnN0aXR1dGVzQ29yZU1hbmlmZXN0ID0gbmV3IEhhc2hNYXA8U3RyaW5nLCBTdHJpbmc+KCk7CgkJc3Vic3RpdHV0ZXNDb3JlTWFuaWZlc3QucHV0KENvbnN0YW50cy5CVU5ETEVfTUFOSUZFU1RWRVJTSU9OLCAiMiIpOwoJCXN1YnN0aXR1dGVzQ29yZU1hbmlmZXN0LnB1dChDb25zdGFudHMuQlVORExFX1NZTUJPTElDTkFNRSwgInN1YnN0aXR1dGVzQ29yZSIpOwoJCXN1YnN0aXR1dGVzQ29yZU1hbmlmZXN0LnB1dChDb25zdGFudHMuRVhQT1JUX1BBQ0tBR0UsICJwa2cxOyBzdWJzdGl0dXRlc0NvcmU9dHJ1ZTsgbWFuZGF0b3J5Oj1zdWJzdGl0dXRlc0NvcmUiKTsKCgkJLy8gY2hhbmdlIGNvcmUncyBpbXBvcnQgdG8gZm9yY2UgaXQgdG8gdGhlIHN1YnN0aXR1dGUKCQljb3JlTWFuaWZlc3QucHV0KENvbnN0YW50cy5JTVBPUlRfUEFDS0FHRSwgInBrZzE7IHN1YnN0aXR1dGVzQ29yZT10cnVlIik7CgkJaW1wb3J0c0NvcmVNYW5pZmVzdC5wdXQoQ29uc3RhbnRzLklNUE9SVF9QQUNLQUdFLCAicGtnMTsgc3Vic3RpdHV0ZXNDb3JlPXRydWUiKTsKCgkJaW5zdGFsbER1bW15TW9kdWxlKHN1YnN0aXR1dGVzQ29yZU1hbmlmZXN0LCAic3Vic3RpdHV0ZXNDb3JlIiwgY29udGFpbmVyKTsKCQlpbnN0YWxsRHVtbXlNb2R1bGUoY29yZU1hbmlmZXN0LCAiY29yZSIsIGNvbnRhaW5lcik7CgkJbWlzYyA9IGluc3RhbGxEdW1teU1vZHVsZShtaXNjTWFuaWZlc3QsICJtaXNjIiwgY29udGFpbmVyKTsKCQlyZXBvcnQgPSBjb250YWluZXIucmVzb2x2ZShBcnJheXMuYXNMaXN0KG1pc2MpLCB0cnVlKTsKCQlBc3NlcnQuYXNzZXJ0TnVsbCgiRmFpbGVkIHRvIHJlc29sdmUgdGVzdC4iLCByZXBvcnQuZ2V0UmVzb2x1dGlvbkV4Y2VwdGlvbigpKTsKCgkJaW5zdGFsbER1bW15TW9kdWxlKGltcG9ydHNDb3JlTWFuaWZlc3QsICJpbXBvcnRzQ29yZSIsIGNvbnRhaW5lcik7CgkJcmVxdWlyZU1pc2MgPSBpbnN0YWxsRHVtbXlNb2R1bGUocmVxdWlyZXNNaXNjTWFuaWZlc3QsICJyZXF1aXJlTWlzYyIsIGNvbnRhaW5lcik7CgkJcmVwb3J0ID0gY29udGFpbmVyLnJlc29sdmUoQXJyYXlzLmFzTGlzdChyZXF1aXJlTWlzYyksIHRydWUpOwoJCUFzc2VydC5hc3NlcnROdWxsKCJGYWlsZWQgdG8gcmVzb2x2ZSB0ZXN0LiIsIHJlcG9ydC5nZXRSZXNvbHV0aW9uRXhjZXB0aW9uKCkpOwoKCQkvLyBub3QgdGVzdCBieSBkb2luZyBhIGZ1bGwgcmVzb2x2ZSB3aXRoIHJlYWwgc3Vic3RpdHV0aW9uCgkJYWRhcHRvciA9IGNyZWF0ZUR1bW15QWRhcHRvcigpOwoJCWNvbnRhaW5lciA9IGFkYXB0b3IuZ2V0Q29udGFpbmVyKCk7CgoJCWluc3RhbGxEdW1teU1vZHVsZShzdWJzdGl0dXRlc0NvcmVNYW5pZmVzdCwgInN1YnN0aXR1dGVzQ29yZSIsIGNvbnRhaW5lcik7CgkJaW5zdGFsbER1bW15TW9kdWxlKGNvcmVNYW5pZmVzdCwgImNvcmUiLCBjb250YWluZXIpOwoJCWluc3RhbGxEdW1teU1vZHVsZShtaXNjTWFuaWZlc3QsICJtaXNjIiwgY29udGFpbmVyKTsKCQlpbnN0YWxsRHVtbXlNb2R1bGUoaW1wb3J0c0NvcmVNYW5pZmVzdCwgImltcG9ydHNDb3JlIiwgY29udGFpbmVyKTsKCQlyZXF1aXJlTWlzYyA9IGluc3RhbGxEdW1teU1vZHVsZShyZXF1aXJlc01pc2NNYW5pZmVzdCwgInJlcXVpcmVNaXNjIiwgY29udGFpbmVyKTsKCgkJcmVwb3J0ID0gY29udGFpbmVyLnJlc29sdmUoQXJyYXlzLmFzTGlzdChyZXF1aXJlTWlzYyksIHRydWUpOwoJCUFzc2VydC5hc3NlcnROdWxsKCJGYWlsZWQgdG8gcmVzb2x2ZSB0ZXN0LiIsIHJlcG9ydC5nZXRSZXNvbHV0aW9uRXhjZXB0aW9uKCkpOwoJfQoKCUxpc3Q8U3RyaW5nPiBIVFRQQ09NUFNfQU5EX0VBVEhFUiA9IEFycmF5cy5hc0xpc3QoIC8vCgkJCSJvcmcuYXBhY2hlLmNvbW1vbnMuY29kZWNfMS45LjAudjIwMTcwMjA4LTE2MTQuTUYiLCAvLwoJCQkib3JnLmFwYWNoZS5jb21tb25zLmxvZ2dpbmdfMS4xLjEudjIwMTEwMTIxMTcyMS5NRiIsIC8vCgkJCSJvcmcuYXBhY2hlLmh0dHBjb21wb25lbnRzLmh0dHBjbGllbnRfNC4zLjYudjIwMTUxMTE3MTU0MC5NRiIsIC8vCgkJCSJvcmcuYXBhY2hlLmh0dHBjb21wb25lbnRzLmh0dHBjbGllbnRfNC41LjIudjIwMTcwMjA4LTE2MTQuTUYiLCAvLwoJCQkib3JnLmFwYWNoZS5odHRwY29tcG9uZW50cy5odHRwY2xpZW50XzQuNS4yLnYyMDE3MDIxMC0wOTI1Lk1GIiwgLy8KCQkJIm9yZy5hcGFjaGUuaHR0cGNvbXBvbmVudHMuaHR0cGNvcmVfNC4zLjMudjIwMTQxMTI5MDcxNS5NRiIsIC8vCgkJCSJvcmcuYXBhY2hlLmh0dHBjb21wb25lbnRzLmh0dHBjb3JlXzQuNC40LnYyMDE2MTExNS0xNjQzLk1GIiwgLy8KCQkJIm9yZy5hcGFjaGUuaHR0cGNvbXBvbmVudHMuaHR0cGNvcmVfNC40LjYudjIwMTcwMjEwLTA5MjUuTUYiLCAvLwoJCQkib3JnLmVjbGlwc2UuYWV0aGVyLmFwaV8xLjAuMS52MjAxNDExMTEuTUYiLCAvLwoJCQkib3JnLmVjbGlwc2UuYWV0aGVyLnNwaV8xLjAuMS52MjAxNDExMTEuTUYiLCAvLwoJCQkib3JnLmVjbGlwc2UuYWV0aGVyLnRyYW5zcG9ydC5odHRwXzEuMC4xLnYyMDE0MTExMS5NRiIsIC8vCgkJCSJvcmcuZWNsaXBzZS5hZXRoZXIudXRpbF8xLjAuMS52MjAxNDExMTEuTUYiKTsKCglAVGVzdAoJcHVibGljIHZvaWQgdGVzdFN1YnN0aXR1dGlvbldpdGhNb3JlVGhhbjJQcm92aWRlcnMoKSB0aHJvd3MgQnVuZGxlRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CgkJRHVtbXlDb250YWluZXJBZGFwdG9yIGFkYXB0b3IgPSBjcmVhdGVEdW1teUFkYXB0b3IoKTsKCQlNb2R1bGVDb250YWluZXIgY29udGFpbmVyID0gYWRhcHRvci5nZXRDb250YWluZXIoKTsKCgkJTW9kdWxlIHN5c3RlbUJ1bmRsZSA9IGluc3RhbGxEdW1teU1vZHVsZSggLy8KCQkJCSJzeXN0ZW0uYnVuZGxlLk1GIiwgLy8KCQkJCUNvbnN0YW50cy5TWVNURU1fQlVORExFX0xPQ0FUSU9OLCAvLwoJCQkJQ29uc3RhbnRzLlNZU1RFTV9CVU5ETEVfU1lNQk9MSUNOQU1FLCAvLwoJCQkJImphdmF4LmNyeXB0bywgamF2YXguY3J5cHRvLnNwZWMsIGphdmF4Lm5ldCwgamF2YXgubmV0LnNzbCwgamF2YXguc2VjdXJpdHkuYXV0aC54NTAwLCBvcmcuaWV0Zi5qZ3NzIiwgLy8KCQkJCSJvc2dpLmVlOyBvc2dpLmVlPUphdmFTRTsgdmVyc2lvbjpMaXN0PFZlcnNpb24+PVwiMS4zLCAxLjQsIDEuNSwgMS42LCAxLjdcIiIsIC8vCgkJCQljb250YWluZXIpOwoJCVJlc29sdXRpb25SZXBvcnQgcmVwb3J0ID0gY29udGFpbmVyLnJlc29sdmUoQXJyYXlzLmFzTGlzdChzeXN0ZW1CdW5kbGUpLCB0cnVlKTsKCQlBc3NlcnQuYXNzZXJ0TnVsbCgiRmFpbGVkIHRvIHJlc29sdmUgdGVzdC4iLCByZXBvcnQuZ2V0UmVzb2x1dGlvbkV4Y2VwdGlvbigpKTsKCgkJTGlzdDxNb2R1bGU+IG1vZHVsZXMgPSBuZXcgQXJyYXlMaXN0PE1vZHVsZT4oKTsKCQlmb3IgKFN0cmluZyBtYW5pZmVzdCA6IEhUVFBDT01QU19BTkRfRUFUSEVSKSB7CgkJCW1vZHVsZXMuYWRkKGluc3RhbGxEdW1teU1vZHVsZShtYW5pZmVzdCwgbWFuaWZlc3QsIGNvbnRhaW5lcikpOwoJCX0KCQlyZXBvcnQgPSBjb250YWluZXIucmVzb2x2ZShtb2R1bGVzLCB0cnVlKTsKCQlBc3NlcnQuYXNzZXJ0TnVsbCgiRmFpbGVkIHRvIHJlc29sdmUgdGVzdC4iLCByZXBvcnQuZ2V0UmVzb2x1dGlvbkV4Y2VwdGlvbigpKTsKCX0KCglAVGVzdAoJcHVibGljIHZvaWQgdGVzdE1vZHVsZUlEU2V0dGluZygpIHRocm93cyBCdW5kbGVFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKCQlEdW1teUNvbnRhaW5lckFkYXB0b3IgYWRhcHRvciA9IGNyZWF0ZUR1bW15QWRhcHRvcigpOwoJCU1vZHVsZUNvbnRhaW5lciBjb250YWluZXIgPSBhZGFwdG9yLmdldENvbnRhaW5lcigpOwoKCQkvLyBpbnN0YWxsIHRoZSBzeXN0ZW0uYnVuZGxlCgkJTW9kdWxlIHN5c3RlbUJ1bmRsZSA9IGluc3RhbGxEdW1teU1vZHVsZSgic3lzdGVtLmJ1bmRsZS5NRiIsIENvbnN0YW50cy5TWVNURU1fQlVORExFX0xPQ0FUSU9OLCBDb25zdGFudHMuU1lTVEVNX0JVTkRMRV9TWU1CT0xJQ05BTUUsIG51bGwsIG51bGwsIGNvbnRhaW5lcik7CgkJUmVzb2x1dGlvblJlcG9ydCByZXBvcnQgPSBjb250YWluZXIucmVzb2x2ZShBcnJheXMuYXNMaXN0KHN5c3RlbUJ1bmRsZSksIHRydWUpOwoJCUFzc2VydC5hc3NlcnROdWxsKCJGYWlsZWQgdG8gcmVzb2x2ZSBzeXN0ZW0uYnVuZGxlLiIsIHJlcG9ydC5nZXRSZXNvbHV0aW9uRXhjZXB0aW9uKCkpOwoKCQlNYXA8U3RyaW5nLCBTdHJpbmc+IG1hbmlmZXN0ID0gbmV3IEhhc2hNYXA8U3RyaW5nLCBTdHJpbmc+KCk7CgoJCS8vIHRlc3QgYnkgaW5zdGFsbGluZyBidW5kbGVzIHdpdGggZGVjcmVhc2luZyBJRHMKCQlMaXN0PE1vZHVsZT4gbW9kdWxlcyA9IG5ldyBBcnJheUxpc3Q8TW9kdWxlPigpOwoJCWZvciAoaW50IGkgPSA1OyBpID4gMDsgaS0tKSB7CgkJCW1hbmlmZXN0LmNsZWFyKCk7CgkJCW1hbmlmZXN0LnB1dChDb25zdGFudHMuQlVORExFX01BTklGRVNUVkVSU0lPTiwgIjIiKTsKCQkJbWFuaWZlc3QucHV0KENvbnN0YW50cy5CVU5ETEVfU1lNQk9MSUNOQU1FLCBTdHJpbmcudmFsdWVPZihpKSk7CgkJCW1vZHVsZXMuYWRkKGluc3RhbGxEdW1teU1vZHVsZShtYW5pZmVzdCwgaSwgbWFuaWZlc3QuZ2V0KENvbnN0YW50cy5CVU5ETEVfU1lNQk9MSUNOQU1FKSwgY29udGFpbmVyKSk7CgkJfQoKCQkvLyB0ZXN0IHRoYXQgdGhlIG1vZHVsZXMgaGF2ZSBkZWNyZWFzaW5nIElEIHN0YXJ0aW5nIGF0IDUKCQlsb25nIGlkID0gNTsKCQlmb3IgKE1vZHVsZSBtb2R1bGUgOiBtb2R1bGVzKSB7CgkJCUFzc2VydC5hc3NlcnRFcXVhbHMoIldyb25nIElEIGZvdW5kLiIsIGlkLS0sIG1vZHVsZS5nZXRJZCgpLmxvbmdWYWx1ZSgpKTsKCQl9CgoJCS8vIHRlc3QgdGhhdCBlcnJvciBvY2N1cnMgd2hlbiB0cnlpbmcgdG8gdXNlIGFuIGV4aXN0aW5nIElECgkJbWFuaWZlc3QuY2xlYXIoKTsKCQltYW5pZmVzdC5wdXQoQ29uc3RhbnRzLkJVTkRMRV9NQU5JRkVTVFZFUlNJT04sICIyIik7CgkJbWFuaWZlc3QucHV0KENvbnN0YW50cy5CVU5ETEVfU1lNQk9MSUNOQU1FLCBTdHJpbmcudmFsdWVPZigidGVzdC5kdXAuaWQiKSk7CgkJdHJ5IHsKCQkJaW5zdGFsbER1bW15TW9kdWxlKG1hbmlmZXN0LCA1LCBtYW5pZmVzdC5nZXQoQ29uc3RhbnRzLkJVTkRMRV9TWU1CT0xJQ05BTUUpLCBjb250YWluZXIpOwoJCQlmYWlsKCJFeHBlY3RlZCB0byBmYWlsIGluc3RhbGxhdGlvbiB3aXRoIGR1cGxpY2F0ZSBJRC4iKTsKCQl9IGNhdGNoIChJbGxlZ2FsU3RhdGVFeGNlcHRpb24gZSkgewoJCQkvLyBleHBlY3RlZAoJCX0KCX0KCglwcml2YXRlIHN0YXRpYyB2b2lkIGFzc2VydFdpcmVzKExpc3Q8TW9kdWxlV2lyZT4gcmVxdWlyZWQsIExpc3Q8TW9kdWxlV2lyZT4uLi4gcHJvdmlkZWQpIHsKCQlmb3IgKE1vZHVsZVdpcmUgcmVxdWlyZWRXaXJlIDogcmVxdWlyZWQpIHsKCQkJZm9yIChMaXN0PE1vZHVsZVdpcmU+IHByb3ZpZGVkTGlzdCA6IHByb3ZpZGVkKSB7CgkJCQlpZiAocHJvdmlkZWRMaXN0LmNvbnRhaW5zKHJlcXVpcmVkV2lyZSkpIHsKCQkJCQlyZXR1cm47CgkJCQl9CgkJCX0KCQkJQXNzZXJ0LmZhaWwoIkNvdWxkIG5vdCBmaW5kIHJlcXVpcmVkIHdpcmUgaW4gZXhwZWN0ZWQgcHJvdmlkZXIgd2lyZXM6ICIgKyByZXF1aXJlZFdpcmUpOwoJCX0KCX0KCglwcml2YXRlIHZvaWQgYXNzZXJ0RXZlbnRzKExpc3Q8RHVtbXlNb2R1bGVFdmVudD4gZXhwZWN0ZWQsIExpc3Q8RHVtbXlNb2R1bGVFdmVudD4gYWN0dWFsLCBib29sZWFuIG9yZGVyTWF0dGVycykgewoJCWZvciAoTGlzdDxEdW1teU1vZHVsZUV2ZW50PiBleHBlY3RlZENvbW1vbiA9IHJlbW92ZUZpcnN0TGlzdE9mQ29tbW9uRXZlbnRzKGV4cGVjdGVkKTsgIWV4cGVjdGVkQ29tbW9uLmlzRW1wdHkoKTsgZXhwZWN0ZWRDb21tb24gPSByZW1vdmVGaXJzdExpc3RPZkNvbW1vbkV2ZW50cyhleHBlY3RlZCkpIHsKCQkJTGlzdDxEdW1teU1vZHVsZUV2ZW50PiBhY3R1YWxDb21tb24gPSByZW1vdmVGaXJzdExpc3RPZkNvbW1vbkV2ZW50cyhhY3R1YWwpOwoJCQlpZiAoZXhwZWN0ZWRDb21tb24uc2l6ZSgpICE9IGFjdHVhbENvbW1vbi5zaXplKCkpIHsKCQkJCUFzc2VydC5hc3NlcnRFcXVhbHMoIldyb25nIG51bWJlciBvZiBldmVudHMgZm91bmQgaW46ICIgKyBhY3R1YWxDb21tb24sIGV4cGVjdGVkQ29tbW9uLnNpemUoKSwgYWN0dWFsQ29tbW9uLnNpemUoKSk7CgkJCX0KCQkJaWYgKG9yZGVyTWF0dGVycykgewoJCQkJQXNzZXJ0LmFzc2VydEVxdWFscygiV3JvbmcgZXZlbnRzIGZvdW5kLiIsIGV4cGVjdGVkQ29tbW9uLCBhY3R1YWxDb21tb24pOwoJCQl9IGVsc2UgewoJCQkJZm9yIChEdW1teU1vZHVsZUV2ZW50IGV4cGVjdGVkRXZlbnQgOiBleHBlY3RlZENvbW1vbikgewoJCQkJCUFzc2VydC5hc3NlcnRUcnVlKCJNaXNzaW5nIGV4cGVjdGVkIGV2ZW50OiAiICsgZXhwZWN0ZWRFdmVudCArICIgOiBmcm9tICIgKyBhY3R1YWxDb21tb24sIGFjdHVhbENvbW1vbi5jb250YWlucyhleHBlY3RlZEV2ZW50KSk7CgkJCQl9CgkJCQlmb3IgKER1bW15TW9kdWxlRXZlbnQgYWN0dWFsRXZlbnQgOiBhY3R1YWxDb21tb24pIHsKCQkJCQlBc3NlcnQuYXNzZXJ0VHJ1ZSgiRm91bmQgdW5leHBlY3RlZCBldmVudDogIiArIGFjdHVhbEV2ZW50ICsgIiA6IGZyb20gIiArIGFjdHVhbENvbW1vbiwgZXhwZWN0ZWRDb21tb24uY29udGFpbnMoYWN0dWFsRXZlbnQpKTsKCQkJCX0KCQkJfQoJCX0KCX0KCglwcml2YXRlIExpc3Q8RHVtbXlNb2R1bGVFdmVudD4gcmVtb3ZlRmlyc3RMaXN0T2ZDb21tb25FdmVudHMoTGlzdDxEdW1teU1vZHVsZUV2ZW50PiBldmVudHMpIHsKCQlMaXN0PER1bW15TW9kdWxlRXZlbnQ+IHJlc3VsdCA9IG5ldyBBcnJheUxpc3Q8RHVtbXlNb2R1bGVEYXRhYmFzZS5EdW1teU1vZHVsZUV2ZW50PigpOwoJCWlmIChldmVudHMuaXNFbXB0eSgpKSB7CgkJCXJldHVybiByZXN1bHQ7CgkJfQoJCU1vZHVsZUV2ZW50IGNvbW1vbkV2ZW50ID0gZXZlbnRzLmdldCgwKS5ldmVudDsKCQlmb3IgKEl0ZXJhdG9yPER1bW15TW9kdWxlRXZlbnQ+IGlFdmVudHMgPSBldmVudHMuaXRlcmF0b3IoKTsgaUV2ZW50cy5oYXNOZXh0KCk7KSB7CgkJCUR1bW15TW9kdWxlRXZlbnQgY3VycmVudCA9IGlFdmVudHMubmV4dCgpOwoJCQlpZiAoY29tbW9uRXZlbnQuZXF1YWxzKGN1cnJlbnQuZXZlbnQpKSB7CgkJCQlpRXZlbnRzLnJlbW92ZSgpOwoJCQkJcmVzdWx0LmFkZChjdXJyZW50KTsKCQkJfSBlbHNlIHsKCQkJCWJyZWFrOwoJCQl9CgkJfQoJCXJldHVybiByZXN1bHQ7Cgl9Cn0K