LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChjKSAyMDEzLCAyMDE2IElCTSBDb3Jwb3JhdGlvbiBhbmQgb3RoZXJzLgogKiBBbGwgcmlnaHRzIHJlc2VydmVkLiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzCiAqIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2UgdjEuMAogKiB3aGljaCBhY2NvbXBhbmllcyB0aGlzIGRpc3RyaWJ1dGlvbiwgYW5kIGlzIGF2YWlsYWJsZSBhdAogKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC12MTAuaHRtbAogKiAKICogQ29udHJpYnV0b3JzOgogKiAgICAgSUJNIENvcnBvcmF0aW9uIC0gaW5pdGlhbCBBUEkgYW5kIGltcGxlbWVudGF0aW9uCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpwYWNrYWdlIG9yZy5lY2xpcHNlLm9zZ2kudGVzdHMuY29udGFpbmVyOwoKaW1wb3J0IHN0YXRpYyBqYXZhLnV0aWwuamFyLkF0dHJpYnV0ZXMuTmFtZS5NQU5JRkVTVF9WRVJTSU9OOwppbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0RXF1YWxzOwppbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuYXNzZXJ0Tm90TnVsbDsKaW1wb3J0IHN0YXRpYyBvcmcuanVuaXQuQXNzZXJ0LmFzc2VydE51bGw7CmltcG9ydCBzdGF0aWMgb3JnLmp1bml0LkFzc2VydC5hc3NlcnRUcnVlOwppbXBvcnQgc3RhdGljIG9yZy5qdW5pdC5Bc3NlcnQuZmFpbDsKCmltcG9ydCBqYXZhLmlvLio7CmltcG9ydCBqYXZhLnV0aWwuKjsKaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50Lio7CmltcG9ydCBqYXZhLnV0aWwuamFyLkF0dHJpYnV0ZXM7CmltcG9ydCBqYXZhLnV0aWwuamFyLk1hbmlmZXN0OwppbXBvcnQgb3JnLmVjbGlwc2Uub3NnaS5jb250YWluZXIuKjsKaW1wb3J0IG9yZy5lY2xpcHNlLm9zZ2kuY29udGFpbmVyLk1vZHVsZS5TdGFydE9wdGlvbnM7CmltcG9ydCBvcmcuZWNsaXBzZS5vc2dpLmNvbnRhaW5lci5Nb2R1bGUuU3RhdGU7CmltcG9ydCBvcmcuZWNsaXBzZS5vc2dpLmNvbnRhaW5lci5Nb2R1bGVDb250YWluZXJBZGFwdG9yLkNvbnRhaW5lckV2ZW50OwppbXBvcnQgb3JnLmVjbGlwc2Uub3NnaS5jb250YWluZXIuTW9kdWxlQ29udGFpbmVyQWRhcHRvci5Nb2R1bGVFdmVudDsKaW1wb3J0IG9yZy5lY2xpcHNlLm9zZ2kuY29udGFpbmVyLmJ1aWxkZXJzLk9TR2lNYW5pZmVzdEJ1aWxkZXJGYWN0b3J5OwppbXBvcnQgb3JnLmVjbGlwc2Uub3NnaS5jb250YWluZXIubmFtZXNwYWNlcy5FY2xpcHNlUGxhdGZvcm1OYW1lc3BhY2U7CmltcG9ydCBvcmcuZWNsaXBzZS5vc2dpLmludGVybmFsLmRlYnVnLkRlYnVnOwppbXBvcnQgb3JnLmVjbGlwc2Uub3NnaS5pbnRlcm5hbC5mcmFtZXdvcmsuRXF1aW5veENvbmZpZ3VyYXRpb247CmltcG9ydCBvcmcuZWNsaXBzZS5vc2dpLnJlcG9ydC5yZXNvbHV0aW9uLlJlc29sdXRpb25SZXBvcnQ7CmltcG9ydCBvcmcuZWNsaXBzZS5vc2dpLnRlc3RzLmNvbnRhaW5lci5kdW1teXMuKjsKaW1wb3J0IG9yZy5lY2xpcHNlLm9zZ2kudGVzdHMuY29udGFpbmVyLmR1bW15cy5EdW1teU1vZHVsZURhdGFiYXNlLkR1bW15Q29udGFpbmVyRXZlbnQ7CmltcG9ydCBvcmcuZWNsaXBzZS5vc2dpLnRlc3RzLmNvbnRhaW5lci5kdW1teXMuRHVtbXlNb2R1bGVEYXRhYmFzZS5EdW1teU1vZHVsZUV2ZW50OwppbXBvcnQgb3JnLmVjbGlwc2Uub3NnaS51dGlsLk1hbmlmZXN0RWxlbWVudDsKaW1wb3J0IG9yZy5qdW5pdC5Bc3NlcnQ7CmltcG9ydCBvcmcuanVuaXQuVGVzdDsKaW1wb3J0IG9yZy5vc2dpLmZyYW1ld29yay4qOwppbXBvcnQgb3JnLm9zZ2kuZnJhbWV3b3JrLmhvb2tzLnJlc29sdmVyLlJlc29sdmVySG9vazsKaW1wb3J0IG9yZy5vc2dpLmZyYW1ld29yay5ob29rcy5yZXNvbHZlci5SZXNvbHZlckhvb2tGYWN0b3J5OwppbXBvcnQgb3JnLm9zZ2kuZnJhbWV3b3JrLm5hbWVzcGFjZS4qOwppbXBvcnQgb3JnLm9zZ2kuZnJhbWV3b3JrLndpcmluZy4qOwppbXBvcnQgb3JnLm9zZ2kucmVzb3VyY2UuTmFtZXNwYWNlOwoKcHVibGljIGNsYXNzIFRlc3RNb2R1bGVDb250YWluZXIgZXh0ZW5kcyBBYnN0cmFjdFRlc3QgewoKCXByaXZhdGUgc3RhdGljIER1bW15TW9kdWxlRGF0YWJhc2UgcmVzb2x2ZWRNb2R1bGVEYXRhYmFzZTsKCglwcml2YXRlIHZvaWQgc2V0dXBNb2R1bGVEYXRhYmFzZSgpIHRocm93cyBCdW5kbGVFeGNlcHRpb24gewoJCWlmIChyZXNvbHZlZE1vZHVsZURhdGFiYXNlID09IG51bGwpIHsKCQkJcmVzb2x2ZWRNb2R1bGVEYXRhYmFzZSA9IGdldERhdGFiYXNlKCk7CgkJfQoJfQoKCXByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBPU0dJX09TID0gIm9zZ2kub3MiOwoJcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIE9TR0lfV1MgPSAib3NnaS53cyI7Cglwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgT1NHSV9BUkNIID0gIm9zZ2kuYXJjaCI7CgoJcHJpdmF0ZSBEdW1teU1vZHVsZURhdGFiYXNlIGdldERhdGFiYXNlKCkgdGhyb3dzIEJ1bmRsZUV4Y2VwdGlvbiB7CgkJQnVuZGxlQ29udGV4dCBjb250ZXh0ID0gKChCdW5kbGVSZWZlcmVuY2UpIGdldENsYXNzKCkuZ2V0Q2xhc3NMb2FkZXIoKSkuZ2V0QnVuZGxlKCkuZ2V0QnVuZGxlQ29udGV4dCgpOwoKCQlEdW1teUNvbnRhaW5lckFkYXB0b3IgYWRhcHRvciA9IGNyZWF0ZUR1bW15QWRhcHRvcigpOwoJCWZpbmFsIE1vZHVsZUNvbnRhaW5lciBjb250YWluZXIgPSBhZGFwdG9yLmdldENvbnRhaW5lcigpOwoKCQlCdW5kbGUgc3lzdGVtQnVuZGxlID0gY29udGV4dC5nZXRCdW5kbGUoMCk7CgkJU3RyaW5nIGV4dHJhUGFja2FnZXMgPSBjb250ZXh0LmdldFByb3BlcnR5KENvbnN0YW50cy5GUkFNRVdPUktfU1lTVEVNUEFDS0FHRVMpOwoJCVN0cmluZyBleHRyYUNhcGFiaWxpdGllcyA9IGNvbnRleHQuZ2V0UHJvcGVydHkoQ29uc3RhbnRzLkZSQU1FV09SS19TWVNURU1DQVBBQklMSVRJRVMpOwoJCWV4dHJhQ2FwYWJpbGl0aWVzID0gKGV4dHJhQ2FwYWJpbGl0aWVzID09IG51bGwgPyAiIiA6IChleHRyYUNhcGFiaWxpdGllcyArICIsICIpKTsKCQlTdHJpbmcgb3NOYW1lID0gY29udGV4dC5nZXRQcm9wZXJ0eShPU0dJX09TKTsKCQlTdHJpbmcgd3NOYW1lID0gY29udGV4dC5nZXRQcm9wZXJ0eShPU0dJX1dTKTsKCQlTdHJpbmcgYXJjaE5hbWUgPSBjb250ZXh0LmdldFByb3BlcnR5KE9TR0lfQVJDSCk7CgkJZXh0cmFDYXBhYmlsaXRpZXMgKz0gRWNsaXBzZVBsYXRmb3JtTmFtZXNwYWNlLkVDTElQU0VfUExBVEZPUk1fTkFNRVNQQUNFICsgIjsgIiArIE9TR0lfT1MgKyAiPSIgKyBvc05hbWUgKyAiOyAiICsgT1NHSV9XUyArICI9IiArIHdzTmFtZSArICI7ICIgKyBPU0dJX0FSQ0ggKyAiPSIgKyBhcmNoTmFtZTsKCQlNb2R1bGVSZXZpc2lvbkJ1aWxkZXIgc3lzdGVtYnVpbGRlciA9IE9TR2lNYW5pZmVzdEJ1aWxkZXJGYWN0b3J5LmNyZWF0ZUJ1aWxkZXIoYXNNYXAoc3lzdGVtQnVuZGxlLmdldEhlYWRlcnMoIiIpKSwgQ29uc3RhbnRzLlNZU1RFTV9CVU5ETEVfU1lNQk9MSUNOQU1FLCBleHRyYVBhY2thZ2VzLCBleHRyYUNhcGFiaWxpdGllcyk7CgkJY29udGFpbmVyLmluc3RhbGwobnVsbCwgc3lzdGVtQnVuZGxlLmdldExvY2F0aW9uKCksIHN5c3RlbWJ1aWxkZXIsIG51bGwpOwoKCQlmaW5hbCBMaXN0PFRocm93YWJsZT4gaW5zdGFsbEVycm9ycyA9IG5ldyBBcnJheUxpc3Q8VGhyb3dhYmxlPigwKTsKCQkvLyBqdXN0IHRyeWluZyB0byBwb3VuZCB0aGUgY29udGFpbmVyIHdpdGggYSBidW5jaCBvZiBpbnN0YWxscwoJCUV4ZWN1dG9yU2VydmljZSBleGVjdXRvciA9IEV4ZWN1dG9ycy5uZXdGaXhlZFRocmVhZFBvb2woMTApOwoJCUJ1bmRsZVtdIGJ1bmRsZXMgPSBjb250ZXh0LmdldEJ1bmRsZXMoKTsKCQlmb3IgKGZpbmFsIEJ1bmRsZSBidW5kbGUgOiBidW5kbGVzKSB7CgkJCWlmIChidW5kbGUuZ2V0QnVuZGxlSWQoKSA9PSAwKQoJCQkJY29udGludWU7CgkJCWV4ZWN1dG9yLmV4ZWN1dGUobmV3IFJ1bm5hYmxlKCkgewoJCQkJQE92ZXJyaWRlCgkJCQlwdWJsaWMgdm9pZCBydW4oKSB7CgkJCQkJdHJ5IHsKCQkJCQkJTW9kdWxlUmV2aXNpb25CdWlsZGVyIGJ1aWxkZXIgPSBPU0dpTWFuaWZlc3RCdWlsZGVyRmFjdG9yeS5jcmVhdGVCdWlsZGVyKGFzTWFwKGJ1bmRsZS5nZXRIZWFkZXJzKCIiKSkpOwoJCQkJCQljb250YWluZXIuaW5zdGFsbChudWxsLCBidW5kbGUuZ2V0TG9jYXRpb24oKSwgYnVpbGRlciwgbnVsbCk7CgkJCQkJfSBjYXRjaCAoVGhyb3dhYmxlIHQpIHsKCQkJCQkJdC5wcmludFN0YWNrVHJhY2UoKTsKCQkJCQkJc3luY2hyb25pemVkIChpbnN0YWxsRXJyb3JzKSB7CgkJCQkJCQlpbnN0YWxsRXJyb3JzLmFkZCh0KTsKCQkJCQkJfQoJCQkJCX0KCQkJCX0KCQkJfSk7CgkJfQoJCWV4ZWN1dG9yLnNodXRkb3duKCk7CgkJdHJ5IHsKCQkJZXhlY3V0b3IuYXdhaXRUZXJtaW5hdGlvbigyLCBUaW1lVW5pdC5NSU5VVEVTKTsKCQl9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBlKSB7CgkJCWUucHJpbnRTdGFja1RyYWNlKCk7CgkJfQoJCXN5bmNocm9uaXplZCAoaW5zdGFsbEVycm9ycykgewoJCQlpZiAoIWluc3RhbGxFcnJvcnMuaXNFbXB0eSgpKSB7CgkJCQlBc3NlcnQuYXNzZXJ0TnVsbCgiVW5leHBlY3RlZCBpbnN0YWxsIGVycm9ycy4iLCBpbnN0YWxsRXJyb3JzKTsKCQkJfQoJCX0KCQljb250YWluZXIucmVzb2x2ZShuZXcgQXJyYXlMaXN0PE1vZHVsZT4oKSwgZmFsc2UpOwoJCUxpc3Q8TW9kdWxlPiBtb2R1bGVzID0gY29udGFpbmVyLmdldE1vZHVsZXMoKTsKCQlmb3IgKE1vZHVsZSBtb2R1bGUgOiBtb2R1bGVzKSB7CgkJCWlmIChtb2R1bGUuZ2V0Q3VycmVudFJldmlzaW9uKCkuZ2V0V2lyaW5nKCkgPT0gbnVsbCkgewoJCQkJU3lzdGVtLm91dC5wcmludGxuKCJDb3VsZCBub3QgcmVzb2x2ZSBtb2R1bGU6ICIgKyBtb2R1bGUuZ2V0Q3VycmVudFJldmlzaW9uKCkpOwoJCQl9CgkJfQoJCXJldHVybiBhZGFwdG9yLmdldERhdGFiYXNlKCk7Cgl9CgoJc3RhdGljIDxLLCBWPiBNYXA8SywgVj4gYXNNYXAoRGljdGlvbmFyeTxLLCBWPiBkaWN0aW9uYXJ5KSB7CgkJTWFwPEssIFY+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+KEFycmF5cy5hc0xpc3QobmV3IER1bW15TW9kdWxlRXZlbnQoc3lzdGVtQnVuZGxlLCBNb2R1bGVFdmVudC5TVE9QUElORywgU3RhdGUuU1RPUFBJTkcpLCBuZXcgRHVtbXlNb2R1bGVFdmVudChjMSwgTW9kdWxlRXZlbnQuU1RPUFBJTkcsIFN0YXRlLlNUT1BQSU5HKSwgbmV3IER1bW15TW9kdWxlRXZlbnQoYzEsIE1vZHVsZUV2ZW50LlNUT1BQRUQsIFN0YXRlLlJFU09MVkVEKSwgbmV3IER1bW15TW9kdWxlRXZlbnQoYzIsIE1vZHVsZUV2ZW50LlNUT1BQSU5HLCBTdGF0ZS5TVE9QUElORyksIG5ldyBEdW1teU1vZHVsZUV2ZW50KGMyLCBNb2R1bGVFdmVudC5TVE9QUEVELCBTdGF0ZS5SRVNPTFZFRCksIG5ldyBEdW1teU1vZHVsZUV2ZW50KGMzLCBNb2R1bGVFdmVudC5TVE9QUElORywgU3RhdGUuU1RPUFBJTkcpLCBuZXcgRHVtbXlNb2R1bGVFdmVudChjMywgTW9kdWxlRXZlbnQuU1RPUFBFRCwgU3RhdGUuUkVTT0xWRUQpLCBuZXcgRHVtbXlNb2R1bGVFdmVudChjNCwgTW9kdWxlRXZlbnQuU1RPUFBJTkcsIFN0YXRlLlNUT1BQSU5HKSwgbmV3IER1bW15TW9kdWxlRXZlbnQoYzQsIE1vZHVsZUV2ZW50LlNUT1BQRUQsIFN0YXRlLlJFU09MVkVEKSwgbmV3IER1bW15TW9kdWxlRXZlbnQoYzUsIE1vZHVsZUV2ZW50LlNUT1BQSU5HLCBTdGF0ZS5TVE9QUElORyksCgkJCQkJbmV3IER1bW15TW9kdWxlRXZlbnQoYzUsIE1vZHVsZUV2ZW50LlNUT1BQRUQsIFN0YXRlLlJFU09MVkVEKSwgbmV3IER1bW15TW9kdWxlRXZlbnQoYzYsIE1vZHVsZUV2ZW50LlNUT1BQSU5HLCBTdGF0ZS5TVE9QUElORyksIG5ldyBEdW1teU1vZHVsZUV2ZW50KGM2LCBNb2R1bGVFdmVudC5TVE9QUEVELCBTdGF0ZS5SRVNPTFZFRCksIG5ldyBEdW1teU1vZHVsZUV2ZW50KGM3LCBNb2R1bGVFdmVudC5TVE9QUElORywgU3RhdGUuU1RPUFBJTkcpLCBuZXcgRHVtbXlNb2R1bGVFdmVudChjNywgTW9kdWxlRXZlbnQuU1RPUFBFRCwgU3RhdGUuUkVTT0xWRUQpLCBuZXcgRHVtbXlNb2R1bGVFdmVudChzeXN0ZW1CdW5kbGUsIE1vZHVsZUV2ZW50LlNUT1BQRUQsIFN0YXRlLlJFU09MVkVEKSkpOwoJCQlhc3NlcnRFdmVudHMoZXhwZWN0ZWRNb2R1bGVFdmVudHMsIGFjdHVhbE1vZHVsZUV2ZW50cywgdHJ1ZSk7CgkJfQoJCUxpc3Q8RHVtbXlDb250YWluZXJFdmVudD4gYWN0dWFsQ29udGFpbmVyRXZlbnRzID0gZGF0YWJhc2UuZ2V0Q29udGFpbmVyRXZlbnRzKCk7CgkJTGlzdDxEdW1teUNvbnRhaW5lckV2ZW50PiBleHBlY3RlZENvbnRhaW5lckV2ZW50cyA9IG5ldyBBcnJheUxpc3Q8RHVtbXlDb250YWluZXJFdmVudD4oQXJyYXlzLmFzTGlzdChuZXcgRHVtbXlDb250YWluZXJFdmVudChDb250YWluZXJFdmVudC5TVE9QUEVELCBzeXN0ZW1CdW5kbGUsIG51bGwpKSk7CgkJQXNzZXJ0LmFzc2VydEVxdWFscygiV3JvbmcgY29udGFpbmVyIGV2ZW50cy4iLCBleHBlY3RlZENvbnRhaW5lckV2ZW50cywgYWN0dWFsQ29udGFpbmVyRXZlbnRzKTsKCX0KCglAVGVzdAoJcHVibGljIHZvaWQgdGVzdER5bmFtaWNJbXBvcnQwMSgpIHRocm93cyBCdW5kbGVFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKCQlEdW1teUNvbnRhaW5lckFkYXB0b3IgYWRhcHRvciA9IGNyZWF0ZUR1bW15QWRhcHRvcigpOwoJCU1vZHVsZUNvbnRhaW5lciBjb250YWluZXIgPSBhZGFwdG9yLmdldENvbnRhaW5lcigpOwoKCQlNb2R1bGUgc3lzdGVtQnVuZGxlID0gaW5zdGFsbER1bW15TW9kdWxlKCJzeXN0ZW0uYnVuZGxlLk1GIiwgQ29uc3RhbnRzLlNZU1RFTV9CVU5ETEVfTE9DQVRJT04sIG51bGwsIG51bGwsICJvc2dpLmVlOyBvc2dpLmVlPUphdmFTRTsgdmVyc2lvbjpWZXJzaW9uPVwiMS41LjBcIiIsIGNvbnRhaW5lcik7CgoJCWNvbnRhaW5lci5yZXNvbHZlKEFycmF5cy5hc0xpc3Qoc3lzdGVtQnVuZGxlKSwgdHJ1ZSk7CgoJCU1vZHVsZSBjMSA9IGluc3RhbGxEdW1teU1vZHVsZSgiYzFfdjEuTUYiLCAiYzFfdjEiLCBjb250YWluZXIpOwoJCU1vZHVsZSBkeW5hbWljMSA9IGluc3RhbGxEdW1teU1vZHVsZSgiZHluYW1pYzFfdjEuTUYiLCAiZHluYW1pYzFfdjEiLCBjb250YWluZXIpOwoKCQljb250YWluZXIucmVzb2x2ZShBcnJheXMuYXNMaXN0KGMxLCBkeW5hbWljMSksIHRydWUpOwoKCQlNb2R1bGVXaXJlIGR5bmFtaWNXaXJlID0gY29udGFpbmVyLnJlc29sdmVEeW5hbWljKCJvcmcub3NnaS5mcmFtZXdvcmsiLCBkeW5hbWljMS5nZXRDdXJyZW50UmV2aXNpb24oKSk7CgkJQXNzZXJ0LmFzc2VydE5vdE51bGwoIk5vIGR5bmFtaWMgd2lyZSBmb3VuZC4iLCBkeW5hbWljV2lyZSk7CgkJQXNzZXJ0LmFzc2VydEVxdWFscygiV3JvbmcgcGFja2FnZSBmb3VuZC4iLCAib3JnLm9zZ2kuZnJhbWV3b3JrIiwgZHluYW1pY1dpcmUuZ2V0Q2FwYWJpbGl0eSgpLmdldEF0dHJpYnV0ZXMoKS5nZXQoUGFja2FnZU5hbWVzcGFjZS5QQUNLQUdFX05BTUVTUEFDRSkpOwoJCUFzc2VydC5hc3NlcnRFcXVhbHMoIldyb25nIHByb3ZpZGVyIGZvciB0aGUgd2lyZSBmb3VuZC4iLCBzeXN0ZW1CdW5kbGUuZ2V0Q3VycmVudFJldmlzaW9uKCksIGR5bmFtaWNXaXJlLmdldFByb3ZpZGVyKCkpOwoKCQlkeW5hbWljV2lyZSA9IGNvbnRhaW5lci5yZXNvbHZlRHluYW1pYygib3JnLm9zZ2kuZnJhbWV3b3JrLndpcmluZyIsIGR5bmFtaWMxLmdldEN1cnJlbnRSZXZpc2lvbigpKTsKCQlBc3NlcnQuYXNzZXJ0Tm90TnVsbCgiTm8gZHluYW1pYyB3aXJlIGZvdW5kLiIsIGR5bmFtaWNXaXJlKTsKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJXcm9uZyBwYWNrYWdlIGZvdW5kLiIsICJvcmcub3NnaS5mcmFtZXdvcmsud2lyaW5nIiwgZHluYW1pY1dpcmUuZ2V0Q2FwYWJpbGl0eSgpLmdldEF0dHJpYnV0ZXMoKS5nZXQoUGFja2FnZU5hbWVzcGFjZS5QQUNLQUdFX05BTUVTUEFDRSkpOwoJCUFzc2VydC5hc3NlcnRFcXVhbHMoIldyb25nIHByb3ZpZGVyIGZvciB0aGUgd2lyZSBmb3VuZC4iLCBzeXN0ZW1CdW5kbGUuZ2V0Q3VycmVudFJldmlzaW9uKCksIGR5bmFtaWNXaXJlLmdldFByb3ZpZGVyKCkpOwoKCQlkeW5hbWljV2lyZSA9IGNvbnRhaW5lci5yZXNvbHZlRHluYW1pYygiYzEuYiIsIGR5bmFtaWMxLmdldEN1cnJlbnRSZXZpc2lvbigpKTsKCQlBc3NlcnQuYXNzZXJ0Tm90TnVsbCgiTm8gZHluYW1pYyB3aXJlIGZvdW5kLiIsIGR5bmFtaWNXaXJlKTsKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJXcm9uZyBwYWNrYWdlIGZvdW5kLiIsICJjMS5iIiwgZHluYW1pY1dpcmUuZ2V0Q2FwYWJpbGl0eSgpLmdldEF0dHJpYnV0ZXMoKS5nZXQoUGFja2FnZU5hbWVzcGFjZS5QQUNLQUdFX05BTUVTUEFDRSkpOwoJCUFzc2VydC5hc3NlcnRFcXVhbHMoIldyb25nIHByb3ZpZGVyIGZvciB0aGUgd2lyZSBmb3VuZC4iLCBjMS5nZXRDdXJyZW50UmV2aXNpb24oKSwgZHluYW1pY1dpcmUuZ2V0UHJvdmlkZXIoKSk7Cgl9CgoJQFRlc3QKCXB1YmxpYyB2b2lkIHRlc3REeW5hbWljSW1wb3J0MDIoKSB0aHJvd3MgQnVuZGxlRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CgkJRHVtbXlDb250YWluZXJBZGFwdG9yIGFkYXB0b3IgPSBjcmVhdGVEdW1teUFkYXB0b3IoKTsKCQlNb2R1bGVDb250YWluZXIgY29udGFpbmVyID0gYWRhcHRvci5nZXRDb250YWluZXIoKTsKCgkJTW9kdWxlIHN5c3RlbUJ1bmRsZSA9IGluc3RhbGxEdW1teU1vZHVsZSgic3lzdGVtLmJ1bmRsZS5NRiIsIENvbnN0YW50cy5TWVNURU1fQlVORExFX0xPQ0FUSU9OLCBudWxsLCBudWxsLCAib3NnaS5lZTsgb3NnaS5lZT1KYXZhU0U7IHZlcnNpb246VmVyc2lvbj1cIjEuNS4wXCIiLCBjb250YWluZXIpOwoKCQljb250YWluZXIucmVzb2x2ZShBcnJheXMuYXNMaXN0KHN5c3RlbUJ1bmRsZSksIHRydWUpOwoKCQlNb2R1bGUgYzEgPSBpbnN0YWxsRHVtbXlNb2R1bGUoImMxX3YxLk1GIiwgImMxX3YxIiwgY29udGFpbmVyKTsKCQlNb2R1bGUgYzQgPSBpbnN0YWxsRHVtbXlNb2R1bGUoImM0X3YxLk1GIiwgImM0X3YxIiwgY29udGFpbmVyKTsKCQlNb2R1bGUgZHluYW1pYzEgPSBpbnN0YWxsRHVtbXlNb2R1bGUoImR5bmFtaWMxX3YxLk1GIiwgImR5bmFtaWMxX3YxIiwgY29udGFpbmVyKTsKCQlNb2R1bGUgZHluYW1pYzFGcmFnID0gaW5zdGFsbER1bW15TW9kdWxlKCJkeW5hbWljMS5mcmFnX3YxLk1GIiwgImR5bmFtaWMxLmZyYWdfdjEiLCBjb250YWluZXIpOwoKCQljb250YWluZXIucmVzb2x2ZShBcnJheXMuYXNMaXN0KGMxLCBjNCwgZHluYW1pYzEsIGR5bmFtaWMxRnJhZyksIHRydWUpOwoKCQlNb2R1bGVXaXJlIGR5bmFtaWNXaXJlID0gY29udGFpbmVyLnJlc29sdmVEeW5hbWljKCJjMS5iIiwgZHluYW1pYzEuZ2V0Q3VycmVudFJldmlzaW9uKCkpOwoJCUFzc2VydC5hc3NlcnROb3ROdWxsKCJObyBkeW5hbWljIHdpcmUgZm91bmQuIiwgZHluYW1pY1dpcmUpOwoJCUFzc2VydC5hc3NlcnRFcXVhbHMoIldyb25nIHBhY2thZ2UgZm91bmQuIiwgImMxLmIiLCBkeW5hbWljV2lyZS5nZXRDYXBhYmlsaXR5KCkuZ2V0QXR0cmlidXRlcygpLmdldChQYWNrYWdlTmFtZXNwYWNlLlBBQ0tBR0VfTkFNRVNQQUNFKSk7CgkJQXNzZXJ0LmFzc2VydEVxdWFscygiV3JvbmcgcHJvdmlkZXIgZm9yIHRoZSB3aXJlIGZvdW5kLiIsIGMxLmdldEN1cnJlbnRSZXZpc2lvbigpLCBkeW5hbWljV2lyZS5nZXRQcm92aWRlcigpKTsKCgkJZHluYW1pY1dpcmUgPSBjb250YWluZXIucmVzb2x2ZUR5bmFtaWMoImM0LmEiLCBkeW5hbWljMS5nZXRDdXJyZW50UmV2aXNpb24oKSk7CgkJQXNzZXJ0LmFzc2VydE5vdE51bGwoIk5vIGR5bmFtaWMgd2lyZSBmb3VuZC4iLCBkeW5hbWljV2lyZSk7CgkJQXNzZXJ0LmFzc2VydEVxdWFscygiV3JvbmcgcGFja2FnZSBmb3VuZC4iLCAiYzQuYSIsIGR5bmFtaWNXaXJlLmdldENhcGFiaWxpdHkoKS5nZXRBdHRyaWJ1dGVzKCkuZ2V0KFBhY2thZ2VOYW1lc3BhY2UuUEFDS0FHRV9OQU1FU1BBQ0UpKTsKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJXcm9uZyBwcm92aWRlciBmb3IgdGhlIHdpcmUgZm91bmQuIiwgYzQuZ2V0Q3VycmVudFJldmlzaW9uKCksIGR5bmFtaWNXaXJlLmdldFByb3ZpZGVyKCkpOwoKCQlkeW5hbWljV2lyZSA9IGNvbnRhaW5lci5yZXNvbHZlRHluYW1pYygiYzQuYiIsIGR5bmFtaWMxLmdldEN1cnJlbnRSZXZpc2lvbigpKTsKCQlBc3NlcnQuYXNzZXJ0Tm90TnVsbCgiTm8gZHluYW1pYyB3aXJlIGZvdW5kLiIsIGR5bmFtaWNXaXJlKTsKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJXcm9uZyBwYWNrYWdlIGZvdW5kLiIsICJjNC5iIiwgZHluYW1pY1dpcmUuZ2V0Q2FwYWJpbGl0eSgpLmdldEF0dHJpYnV0ZXMoKS5nZXQoUGFja2FnZU5hbWVzcGFjZS5QQUNLQUdFX05BTUVTUEFDRSkpOwoJCUFzc2VydC5hc3NlcnRFcXVhbHMoIldyb25nIHByb3ZpZGVyIGZvciB0aGUgd2lyZSBmb3VuZC4iLCBjNC5nZXRDdXJyZW50UmV2aXNpb24oKSwgZHluYW1pY1dpcmUuZ2V0UHJvdmlkZXIoKSk7Cgl9CgoJQFRlc3QKCXB1YmxpYyB2b2lkIHRlc3REeW5hbWljSW1wb3J0MDMoKSB0aHJvd3MgQnVuZGxlRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CgkJRHVtbXlDb250YWluZXJBZGFwdG9yIGFkYXB0b3IgPSBjcmVhdGVEdW1teUFkYXB0b3IoKTsKCQlNb2R1bGVDb250YWluZXIgY29udGFpbmVyID0gYWRhcHRvci5nZXRDb250YWluZXIoKTsKCQlEdW1teU1vZHVsZURhdGFiYXNlIGRhdGFiYXNlID0gYWRhcHRvci5nZXREYXRhYmFzZSgpOwoJCU1vZHVsZSBzeXN0ZW1CdW5kbGUgPSBpbnN0YWxsRHVtbXlNb2R1bGUoInN5c3RlbS5idW5kbGUuTUYiLCBDb25zdGFudHMuU1lTVEVNX0JVTkRMRV9MT0NBVElPTiwgY29udGFpbmVyKTsKCgkJY29udGFpbmVyLnJlc29sdmUoQXJyYXlzLmFzTGlzdChzeXN0ZW1CdW5kbGUpLCB0cnVlKTsKCgkJTW9kdWxlIGR5bmFtaWMzID0gaW5zdGFsbER1bW15TW9kdWxlKCJkeW5hbWljMl92MS5NRiIsICJkeW5hbWljMl92MSIsIGNvbnRhaW5lcik7CgoJCWNvbnRhaW5lci5yZXNvbHZlKEFycmF5cy5hc0xpc3Qoc3lzdGVtQnVuZGxlLCBkeW5hbWljMyksIHRydWUpOwoKCQlNb2R1bGVXaXJlIGR5bmFtaWNXaXJlID0gY29udGFpbmVyLnJlc29sdmVEeW5hbWljKCJjMS5hIiwgZHluYW1pYzMuZ2V0Q3VycmVudFJldmlzaW9uKCkpOwoJCUFzc2VydC5hc3NlcnROdWxsKCJEeW5hbWljIHdpcmUgZm91bmQuIiwgZHluYW1pY1dpcmUpOwoKCQlNb2R1bGUgYzF2MSA9IGluc3RhbGxEdW1teU1vZHVsZSgiYzFfdjEuTUYiLCAiYzFfdjEiLCBjb250YWluZXIpOwoJCWRhdGFiYXNlLmdldE1vZHVsZUV2ZW50cygpOwoKCQlkeW5hbWljV2lyZSA9IGNvbnRhaW5lci5yZXNvbHZlRHluYW1pYygiYzEuYSIsIGR5bmFtaWMzLmdldEN1cnJlbnRSZXZpc2lvbigpKTsKCQlBc3NlcnQuYXNzZXJ0Tm90TnVsbCgiRHluYW1pYyB3aXJlIG5vdCBmb3VuZC4iLCBkeW5hbWljV2lyZSk7CgkJQXNzZXJ0LmFzc2VydEVxdWFscygiV3JvbmcgcGFja2FnZSBmb3VuZC4iLCAiYzEuYSIsIGR5bmFtaWNXaXJlLmdldENhcGFiaWxpdHkoKS5nZXRBdHRyaWJ1dGVzKCkuZ2V0KFBhY2thZ2VOYW1lc3BhY2UuUEFDS0FHRV9OQU1FU1BBQ0UpKTsKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJXcm9uZyBwcm92aWRlciBmb3IgdGhlIHdpcmUgZm91bmQuIiwgYzF2MS5nZXRDdXJyZW50UmV2aXNpb24oKSwgZHluYW1pY1dpcmUuZ2V0UHJvdmlkZXIoKSk7CgoJCU1vZHVsZVdpcmluZyBjMXYxV2lyaW5nID0gYzF2MS5nZXRDdXJyZW50UmV2aXNpb24oKS5nZXRXaXJpbmcoKTsKCQlBc3NlcnQuYXNzZXJ0Tm90TnVsbCgiYzEgd2lyaW5nIGlzIG51bGwuIiwgYzF2MVdpcmluZyk7CgoJCU1vZHVsZSBjMXYyID0gaW5zdGFsbER1bW15TW9kdWxlKCJjMV92Mi5NRiIsICJjMV92MiIsIGNvbnRhaW5lcik7CgkJY29udGFpbmVyLnJlc29sdmUoQXJyYXlzLmFzTGlzdChjMXYyKSwgdHJ1ZSk7CgkJZGF0YWJhc2UuZ2V0TW9kdWxlRXZlbnRzKCk7CgoJCWR5bmFtaWNXaXJlID0gY29udGFpbmVyLnJlc29sdmVEeW5hbWljKCJjMS5iIiwgZHluYW1pYzMuZ2V0Q3VycmVudFJldmlzaW9uKCkpOwoJCUFzc2VydC5hc3NlcnROb3ROdWxsKCJEeW5hbWljIHdpcmUgbm90IGZvdW5kLiIsIGR5bmFtaWNXaXJlKTsKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJXcm9uZyBwYWNrYWdlIGZvdW5kLiIsICJjMS5iIiwgZHluYW1pY1dpcmUuZ2V0Q2FwYWJpbGl0eSgpLmdldEF0dHJpYnV0ZXMoKS5nZXQoUGFja2FnZU5hbWVzcGFjZS5QQUNLQUdFX05BTUVTUEFDRSkpOwoJCUFzc2VydC5hc3NlcnRFcXVhbHMoIldyb25nIHByb3ZpZGVyLiIsIGMxdjEuZ2V0Q3VycmVudFJldmlzaW9uKCksIGR5bmFtaWNXaXJlLmdldFByb3ZpZGVyKCkpOwoJfQoKCUBUZXN0CglwdWJsaWMgdm9pZCB0ZXN0RHluYW1pY0ltcG9ydDA0KCkgdGhyb3dzIEJ1bmRsZUV4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewoJCUR1bW15Q29udGFpbmVyQWRhcHRvciBhZGFwdG9yID0gY3JlYXRlRHVtbXlBZGFwdG9yKCk7CgkJTW9kdWxlQ29udGFpbmVyIGNvbnRhaW5lciA9IGFkYXB0b3IuZ2V0Q29udGFpbmVyKCk7CgkJRHVtbXlNb2R1bGVEYXRhYmFzZSBkYXRhYmFzZSA9IGFkYXB0b3IuZ2V0RGF0YWJhc2UoKTsKCQlNb2R1bGUgc3lzdGVtQnVuZGxlID0gaW5zdGFsbER1bW15TW9kdWxlKCJzeXN0ZW0uYnVuZGxlLk1GIiwgQ29uc3RhbnRzLlNZU1RFTV9CVU5ETEVfTE9DQVRJT04sIGNvbnRhaW5lcik7CgoJCWNvbnRhaW5lci5yZXNvbHZlKEFycmF5cy5hc0xpc3Qoc3lzdGVtQnVuZGxlKSwgdHJ1ZSk7CgoJCU1vZHVsZSBkeW5hbWljMyA9IGluc3RhbGxEdW1teU1vZHVsZSgiZHluYW1pYzJfdjEuTUYiLCAiZHluYW1pYzJfdjEiLCBjb250YWluZXIpOwoKCQljb250YWluZXIucmVzb2x2ZShBcnJheXMuYXNMaXN0KHN5c3RlbUJ1bmRsZSwgZHluYW1pYzMpLCB0cnVlKTsKCgkJTW9kdWxlV2lyZSBkeW5hbWljV2lyZSA9IGNvbnRhaW5lci5yZXNvbHZlRHluYW1pYygiaDEuYSIsIGR5bmFtaWMzLmdldEN1cnJlbnRSZXZpc2lvbigpKTsKCQlBc3NlcnQuYXNzZXJ0TnVsbCgiRHluYW1pYyB3aXJlIGZvdW5kLiIsIGR5bmFtaWNXaXJlKTsKCgkJTW9kdWxlIGgxID0gaW5zdGFsbER1bW15TW9kdWxlKCJoMV92MS5NRiIsICJoMV92MSIsIGNvbnRhaW5lcik7CgkJTW9kdWxlIGYxID0gaW5zdGFsbER1bW15TW9kdWxlKCJmMV92MS5NRiIsICJmMV92MSIsIGNvbnRhaW5lcik7CgkJZGF0YWJhc2UuZ2V0TW9kdWxlRXZlbnRzKCk7CgoJCWR5bmFtaWNXaXJlID0gY29udGFpbmVyLnJlc29sdmVEeW5hbWljKCJoMS5hIiwgZHluYW1pYzMuZ2V0Q3VycmVudFJldmlzaW9uKCkpOwoJCUFzc2VydC5hc3NlcnROb3ROdWxsKCJEeW5hbWljIHdpcmUgbm90IGZvdW5kLiIsIGR5bmFtaWNXaXJlKTsKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJXcm9uZyBwYWNrYWdlIGZvdW5kLiIsICJoMS5hIiwgZHluYW1pY1dpcmUuZ2V0Q2FwYWJpbGl0eSgpLmdldEF0dHJpYnV0ZXMoKS5nZXQoUGFja2FnZU5hbWVzcGFjZS5QQUNLQUdFX05BTUVTUEFDRSkpOwoJCUFzc2VydC5hc3NlcnRFcXVhbHMoIldyb25nIHByb3ZpZGVyIGZvciB0aGUgd2lyZSBmb3VuZC4iLCBoMS5nZXRDdXJyZW50UmV2aXNpb24oKSwgZHluYW1pY1dpcmUuZ2V0UHJvdmlkZXIoKSk7CgoJCWR5bmFtaWNXaXJlID0gY29udGFpbmVyLnJlc29sdmVEeW5hbWljKCJmMS5hIiwgZHluYW1pYzMuZ2V0Q3VycmVudFJldmlzaW9uKCkpOwoJCUFzc2VydC5hc3NlcnROb3ROdWxsKCJEeW5hbWljIHdpcmUgbm90IGZvdW5kLiIsIGR5bmFtaWNXaXJlKTsKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJXcm9uZyBwYWNrYWdlIGZvdW5kLiIsICJmMS5hIiwgZHluYW1pY1dpcmUuZ2V0Q2FwYWJpbGl0eSgpLmdldEF0dHJpYnV0ZXMoKS5nZXQoUGFja2FnZU5hbWVzcGFjZS5QQUNLQUdFX05BTUVTUEFDRSkpOwoJCUFzc2VydC5hc3NlcnRFcXVhbHMoIldyb25nIHByb3ZpZGVyIGZvciB0aGUgd2lyZSBmb3VuZC4iLCBoMS5nZXRDdXJyZW50UmV2aXNpb24oKSwgZHluYW1pY1dpcmUuZ2V0UHJvdmlkZXIoKSk7CgoJCU1vZHVsZVdpcmluZyBoMVdpcmluZyA9IGgxLmdldEN1cnJlbnRSZXZpc2lvbigpLmdldFdpcmluZygpOwoJCUFzc2VydC5hc3NlcnROb3ROdWxsKCJoMSB3aXJpbmcgaXMgbnVsbC4iLCBoMVdpcmluZyk7CgoJCU1vZHVsZVdpcmluZyBmMVdpcmluZyA9IGYxLmdldEN1cnJlbnRSZXZpc2lvbigpLmdldFdpcmluZygpOwoJCUFzc2VydC5hc3NlcnROb3ROdWxsKCJmMSB3aXJpbmcgaXMgbnVsbC4iLCBmMVdpcmluZyk7Cgl9CgoJQFRlc3QKCXB1YmxpYyB2b2lkIHRlc3REeW5hbWljSW1wb3J0MDUoKSB0aHJvd3MgQnVuZGxlRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CgkJRHVtbXlDb250YWluZXJBZGFwdG9yIGFkYXB0b3IgPSBjcmVhdGVEdW1teUFkYXB0b3IoKTsKCQlNb2R1bGVDb250YWluZXIgY29udGFpbmVyID0gYWRhcHRvci5nZXRDb250YWluZXIoKTsKCgkJTW9kdWxlIHN5c3RlbUJ1bmRsZSA9IGluc3RhbGxEdW1teU1vZHVsZSgic3lzdGVtLmJ1bmRsZS5NRiIsIENvbnN0YW50cy5TWVNURU1fQlVORExFX0xPQ0FUSU9OLCBudWxsLCBudWxsLCAib3NnaS5lZTsgb3NnaS5lZT1KYXZhU0U7IHZlcnNpb246VmVyc2lvbj1cIjEuNS4wXCIiLCBjb250YWluZXIpOwoKCQljb250YWluZXIucmVzb2x2ZShBcnJheXMuYXNMaXN0KHN5c3RlbUJ1bmRsZSksIHRydWUpOwoKCQlNb2R1bGUgYzEgPSBpbnN0YWxsRHVtbXlNb2R1bGUoImMxX3YxLk1GIiwgImMxX3YxIiwgY29udGFpbmVyKTsKCQlNb2R1bGUgYzQgPSBpbnN0YWxsRHVtbXlNb2R1bGUoImM0X3YxLk1GIiwgImM0X3YxIiwgY29udGFpbmVyKTsKCQlNb2R1bGUgZHluYW1pYzMgPSBpbnN0YWxsRHVtbXlNb2R1bGUoImR5bmFtaWMzX3YxLk1GIiwgImR5bmFtaWMzX3YxIiwgY29udGFpbmVyKTsKCQlNb2R1bGUgZHluYW1pYzNGcmFnID0gaW5zdGFsbER1bW15TW9kdWxlKCJkeW5hbWljMy5mcmFnX3YxLk1GIiwgImR5bmFtaWMzLmZyYWdfdjEiLCBjb250YWluZXIpOwoKCQljb250YWluZXIucmVzb2x2ZShBcnJheXMuYXNMaXN0KGMxLCBjNCwgZHluYW1pYzMsIGR5bmFtaWMzRnJhZyksIHRydWUpOwoKCQlNb2R1bGVXaXJlIGR5bmFtaWNXaXJlID0gY29udGFpbmVyLnJlc29sdmVEeW5hbWljKCJjNC5hIiwgZHluYW1pYzMuZ2V0Q3VycmVudFJldmlzaW9uKCkpOwoJCUFzc2VydC5hc3NlcnROb3ROdWxsKCJObyBkeW5hbWljIHdpcmUgZm91bmQuIiwgZHluYW1pY1dpcmUpOwoJCUFzc2VydC5hc3NlcnRFcXVhbHMoIldyb25nIHBhY2thZ2UgZm91bmQuIiwgImM0LmEiLCBkeW5hbWljV2lyZS5nZXRDYXBhYmlsaXR5KCkuZ2V0QXR0cmlidXRlcygpLmdldChQYWNrYWdlTmFtZXNwYWNlLlBBQ0tBR0VfTkFNRVNQQUNFKSk7CgkJQXNzZXJ0LmFzc2VydEVxdWFscygiV3JvbmcgcHJvdmlkZXIgZm9yIHRoZSB3aXJlIGZvdW5kLiIsIGM0LmdldEN1cnJlbnRSZXZpc2lvbigpLCBkeW5hbWljV2lyZS5nZXRQcm92aWRlcigpKTsKCgkJZHluYW1pY1dpcmUgPSBjb250YWluZXIucmVzb2x2ZUR5bmFtaWMoImM0LmIiLCBkeW5hbWljMy5nZXRDdXJyZW50UmV2aXNpb24oKSk7CgkJQXNzZXJ0LmFzc2VydE5vdE51bGwoIk5vIGR5bmFtaWMgd2lyZSBmb3VuZC4iLCBkeW5hbWljV2lyZSk7CgkJQXNzZXJ0LmFzc2VydEVxdWFscygiV3JvbmcgcGFja2FnZSBmb3VuZC4iLCAiYzQuYiIsIGR5bmFtaWNXaXJlLmdldENhcGFiaWxpdHkoKS5nZXRBdHRyaWJ1dGVzKCkuZ2V0KFBhY2thZ2VOYW1lc3BhY2UuUEFDS0FHRV9OQU1FU1BBQ0UpKTsKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJXcm9uZyBwcm92aWRlciBmb3IgdGhlIHdpcmUgZm91bmQuIiwgYzQuZ2V0Q3VycmVudFJldmlzaW9uKCksIGR5bmFtaWNXaXJlLmdldFByb3ZpZGVyKCkpOwoJfQoKCUBUZXN0CglwdWJsaWMgdm9pZCB0ZXN0RHluYW1pY0ltcG9ydDA2KCkgdGhyb3dzIEJ1bmRsZUV4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewoJCUR1bW15Q29udGFpbmVyQWRhcHRvciBhZGFwdG9yID0gY3JlYXRlRHVtbXlBZGFwdG9yKCk7CgkJTW9kdWxlQ29udGFpbmVyIGNvbnRhaW5lciA9IGFkYXB0b3IuZ2V0Q29udGFpbmVyKCk7CgkJTW9kdWxlIHN5c3RlbUJ1bmRsZSA9IGluc3RhbGxEdW1teU1vZHVsZSgic3lzdGVtLmJ1bmRsZS5NRiIsIENvbnN0YW50cy5TWVNURU1fQlVORExFX0xPQ0FUSU9OLCBjb250YWluZXIpOwoKCQljb250YWluZXIucmVzb2x2ZShBcnJheXMuYXNMaXN0KHN5c3RlbUJ1bmRsZSksIHRydWUpOwoKCQlNb2R1bGUgZHluYW1pYzMgPSBpbnN0YWxsRHVtbXlNb2R1bGUoImR5bmFtaWMyX3YxLk1GIiwgImR5bmFtaWMyX3YxIiwgY29udGFpbmVyKTsKCgkJY29udGFpbmVyLnJlc29sdmUoQXJyYXlzLmFzTGlzdChzeXN0ZW1CdW5kbGUsIGR5bmFtaWMzKSwgdHJ1ZSk7CgoJCU1vZHVsZSBmMSA9IGluc3RhbGxEdW1teU1vZHVsZSgiZjFfdjEuTUYiLCAiZjFfdjEiLCBjb250YWluZXIpOwoKCQlNb2R1bGVXaXJlIGR5bmFtaWNXaXJlOwoJCWR5bmFtaWNXaXJlID0gY29udGFpbmVyLnJlc29sdmVEeW5hbWljKCJoMS5hIiwgZHluYW1pYzMuZ2V0Q3VycmVudFJldmlzaW9uKCkpOwoJCUFzc2VydC5hc3NlcnROdWxsKCJEeW5hbWljIHdpcmUgZm91bmQuIiwgZHluYW1pY1dpcmUpOwoJCWR5bmFtaWNXaXJlID0gY29udGFpbmVyLnJlc29sdmVEeW5hbWljKCJmMS5hIiwgZHluYW1pYzMuZ2V0Q3VycmVudFJldmlzaW9uKCkpOwoJCUFzc2VydC5hc3NlcnROdWxsKCJEeW5hbWljIHdpcmUgZm91bmQuIiwgZHluYW1pY1dpcmUpOwoKCQlNb2R1bGUgaDEgPSBpbnN0YWxsRHVtbXlNb2R1bGUoImgxX3YxLk1GIiwgImgxX3YxIiwgY29udGFpbmVyKTsKCgkJZHluYW1pY1dpcmUgPSBjb250YWluZXIucmVzb2x2ZUR5bmFtaWMoImgxLmEiLCBkeW5hbWljMy5nZXRDdXJyZW50UmV2aXNpb24oKSk7CgkJQXNzZXJ0LmFzc2VydE5vdE51bGwoIkR5bmFtaWMgd2lyZSBub3QgZm91bmQuIiwgZHluYW1pY1dpcmUpOwoJCUFzc2VydC5hc3NlcnRFcXVhbHMoIldyb25nIHBhY2thZ2UgZm91bmQuIiwgImgxLmEiLCBkeW5hbWljV2lyZS5nZXRDYXBhYmlsaXR5KCkuZ2V0QXR0cmlidXRlcygpLmdldChQYWNrYWdlTmFtZXNwYWNlLlBBQ0tBR0VfTkFNRVNQQUNFKSk7CgkJQXNzZXJ0LmFzc2VydEVxdWFscygiV3JvbmcgaG9zdCByZXZpc2lvbiBmb3VuZC4iLCBoMS5nZXRDdXJyZW50UmV2aXNpb24oKSwgZHluYW1pY1dpcmUuZ2V0UHJvdmlkZXIoKSk7CgoJCWR5bmFtaWNXaXJlID0gY29udGFpbmVyLnJlc29sdmVEeW5hbWljKCJmMS5hIiwgZHluYW1pYzMuZ2V0Q3VycmVudFJldmlzaW9uKCkpOwoJCUFzc2VydC5hc3NlcnROb3ROdWxsKCJEeW5hbWljIHdpcmUgbm90IGZvdW5kLiIsIGR5bmFtaWNXaXJlKTsKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJXcm9uZyBwYWNrYWdlIGZvdW5kLiIsICJmMS5hIiwgZHluYW1pY1dpcmUuZ2V0Q2FwYWJpbGl0eSgpLmdldEF0dHJpYnV0ZXMoKS5nZXQoUGFja2FnZU5hbWVzcGFjZS5QQUNLQUdFX05BTUVTUEFDRSkpOwoJCUFzc2VydC5hc3NlcnRFcXVhbHMoIldyb25nIGhvc3QgcmV2aXNpb24gZm91bmQuIiwgaDEuZ2V0Q3VycmVudFJldmlzaW9uKCksIGR5bmFtaWNXaXJlLmdldFByb3ZpZGVyKCkpOwoKCQlNb2R1bGVXaXJpbmcgaDFXaXJpbmcgPSBoMS5nZXRDdXJyZW50UmV2aXNpb24oKS5nZXRXaXJpbmcoKTsKCQlBc3NlcnQuYXNzZXJ0Tm90TnVsbCgiaDEgd2lyaW5nIGlzIG51bGwuIiwgaDFXaXJpbmcpOwoKCQlNb2R1bGVXaXJpbmcgZjFXaXJpbmcgPSBmMS5nZXRDdXJyZW50UmV2aXNpb24oKS5nZXRXaXJpbmcoKTsKCQlBc3NlcnQuYXNzZXJ0Tm90TnVsbCgiZjEgd2lyaW5nIGlzIG51bGwuIiwgZjFXaXJpbmcpOwoJfQoKCUBUZXN0CglwdWJsaWMgdm9pZCB0ZXN0RHluYW1pY0ltcG9ydDA3KCkgdGhyb3dzIEJ1bmRsZUV4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewoJCUR1bW15Q29udGFpbmVyQWRhcHRvciBhZGFwdG9yID0gY3JlYXRlRHVtbXlBZGFwdG9yKCk7CgkJTW9kdWxlQ29udGFpbmVyIGNvbnRhaW5lciA9IGFkYXB0b3IuZ2V0Q29udGFpbmVyKCk7CgkJTW9kdWxlIHN5c3RlbUJ1bmRsZSA9IGluc3RhbGxEdW1teU1vZHVsZSgic3lzdGVtLmJ1bmRsZS5NRiIsIENvbnN0YW50cy5TWVNURU1fQlVORExFX0xPQ0FUSU9OLCBjb250YWluZXIpOwoKCQljb250YWluZXIucmVzb2x2ZShBcnJheXMuYXNMaXN0KHN5c3RlbUJ1bmRsZSksIHRydWUpOwoKCQlNb2R1bGUgZHluYW1pYzMgPSBpbnN0YWxsRHVtbXlNb2R1bGUoImR5bmFtaWMyX3YxLk1GIiwgImR5bmFtaWMyX3YxIiwgY29udGFpbmVyKTsKCgkJQXNzZXJ0LmFzc2VydE51bGwoIkV4cGVjdGVkIG5vIHJlc29sdXRpb24gZXhjZXB0aW9uLiIsIGNvbnRhaW5lci5yZXNvbHZlKEFycmF5cy5hc0xpc3Qoc3lzdGVtQnVuZGxlLCBkeW5hbWljMyksIHRydWUpLmdldFJlc29sdXRpb25FeGNlcHRpb24oKSk7CgoJCWluc3RhbGxEdW1teU1vZHVsZSgiYzZfdjEuTUYiLCAiYzZfdjEiLCBjb250YWluZXIpOwoKCQlNb2R1bGVXaXJlIGR5bmFtaWNXaXJlID0gY29udGFpbmVyLnJlc29sdmVEeW5hbWljKCJjNiIsIGR5bmFtaWMzLmdldEN1cnJlbnRSZXZpc2lvbigpKTsKCQlBc3NlcnQuYXNzZXJ0TnVsbCgiRHluYW1pYyB3aXJlIGZvdW5kLiIsIGR5bmFtaWNXaXJlKTsKCX0KCglAVGVzdAoJcHVibGljIHZvaWQgdGVzdER5bmFtaWNJbXBvcnQwOCgpIHRocm93cyBCdW5kbGVFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKCQlEdW1teUNvbnRhaW5lckFkYXB0b3IgYWRhcHRvciA9IGNyZWF0ZUR1bW15QWRhcHRvcigpOwoJCU1vZHVsZUNvbnRhaW5lciBjb250YWluZXIgPSBhZGFwdG9yLmdldENvbnRhaW5lcigpOwoJCUR1bW15TW9kdWxlRGF0YWJhc2UgZGF0YWJhc2UgPSBhZGFwdG9yLmdldERhdGFiYXNlKCk7CgkJTW9kdWxlIHN5c3RlbUJ1bmRsZSA9IGluc3RhbGxEdW1teU1vZHVsZSgic3lzdGVtLmJ1bmRsZS5NRiIsIENvbnN0YW50cy5TWVNURU1fQlVORExFX0xPQ0FUSU9OLCBjb250YWluZXIpOwoKCQljb250YWluZXIucmVzb2x2ZShBcnJheXMuYXNMaXN0KHN5c3RlbUJ1bmRsZSksIHRydWUpOwoKCQlNb2R1bGUgZHluYW1pYzIgPSBpbnN0YWxsRHVtbXlNb2R1bGUoImR5bmFtaWMyX3YxLk1GIiwgImR5bmFtaWMyX3YxIiwgY29udGFpbmVyKTsKCgkJY29udGFpbmVyLnJlc29sdmUoQXJyYXlzLmFzTGlzdChzeXN0ZW1CdW5kbGUsIGR5bmFtaWMyKSwgdHJ1ZSk7CgoJCU1vZHVsZSBoMSA9IGluc3RhbGxEdW1teU1vZHVsZSgiaDFfdjEuTUYiLCAiaDFfdjEiLCBjb250YWluZXIpOwoJCU1vZHVsZSBmMSA9IGluc3RhbGxEdW1teU1vZHVsZSgiZjFfdjEuTUYiLCAiZjFfdjEiLCBjb250YWluZXIpOwoJCWRhdGFiYXNlLmdldE1vZHVsZUV2ZW50cygpOwoJCS8vIG1ha2Ugc3VyZSBoMSBpcyBub3QgcmVzb2x2ZWQKCQlNb2R1bGVXaXJpbmcgaDFXaXJpbmcgPSBoMS5nZXRDdXJyZW50UmV2aXNpb24oKS5nZXRXaXJpbmcoKTsKCQlBc3NlcnQuYXNzZXJ0TnVsbCgiaDEgZ290IHJlc29sdmVkIHNvbWVob3cuIiwgaDFXaXJpbmcpOwoJCS8vIGRvIG5vdCByZXNvbHZlIHRoZSBob3N0IGZpcnN0OyBtYWtlIHN1cmUgaXQgZ2V0cyBwdWxsZWQgaW4gd2hpbGUgYXR0ZW1wdGluZyB0byByZXNvbHZlIAoJCS8vIHRvIGEgZnJhZ21lbnQgY2FwYWJpbGl0eS4KCQlNb2R1bGVXaXJlIGR5bmFtaWNXaXJlID0gY29udGFpbmVyLnJlc29sdmVEeW5hbWljKCJmMS5hIiwgZHluYW1pYzIuZ2V0Q3VycmVudFJldmlzaW9uKCkpOwoJCUFzc2VydC5hc3NlcnROb3ROdWxsKCJEeW5hbWljIHdpcmUgbm90IGZvdW5kLiIsIGR5bmFtaWNXaXJlKTsKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJXcm9uZyBwYWNrYWdlIGZvdW5kLiIsICJmMS5hIiwgZHluYW1pY1dpcmUuZ2V0Q2FwYWJpbGl0eSgpLmdldEF0dHJpYnV0ZXMoKS5nZXQoUGFja2FnZU5hbWVzcGFjZS5QQUNLQUdFX05BTUVTUEFDRSkpOwoJCUFzc2VydC5hc3NlcnRFcXVhbHMoIldyb25nIHByb3ZpZGVyIGZvciB0aGUgd2lyZSBmb3VuZC4iLCBoMS5nZXRDdXJyZW50UmV2aXNpb24oKSwgZHluYW1pY1dpcmUuZ2V0UHJvdmlkZXIoKSk7CgoJCWgxV2lyaW5nID0gaDEuZ2V0Q3VycmVudFJldmlzaW9uKCkuZ2V0V2lyaW5nKCk7CgkJQXNzZXJ0LmFzc2VydE5vdE51bGwoImgxIHdpcmluZyBpcyBudWxsLiIsIGgxV2lyaW5nKTsKCgkJTW9kdWxlV2lyaW5nIGYxV2lyaW5nID0gZjEuZ2V0Q3VycmVudFJldmlzaW9uKCkuZ2V0V2lyaW5nKCk7CgkJQXNzZXJ0LmFzc2VydE5vdE51bGwoImYxIHdpcmluZyBpcyBudWxsLiIsIGYxV2lyaW5nKTsKCX0KCglAVGVzdAoJcHVibGljIHZvaWQgdGVzdER5bmFtaWNJbXBvcnRNaXNzMDEoKSB0aHJvd3MgQnVuZGxlRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CgkJRHVtbXlDb250YWluZXJBZGFwdG9yIGFkYXB0b3IgPSBjcmVhdGVEdW1teUFkYXB0b3IoKTsKCQlNb2R1bGVDb250YWluZXIgY29udGFpbmVyID0gYWRhcHRvci5nZXRDb250YWluZXIoKTsKCgkJTW9kdWxlIHN5c3RlbUJ1bmRsZSA9IGluc3RhbGxEdW1teU1vZHVsZSgic3lzdGVtLmJ1bmRsZS5NRiIsIENvbnN0YW50cy5TWVNURU1fQlVORExFX0xPQ0FUSU9OLCBudWxsLCBudWxsLCAib3NnaS5lZTsgb3NnaS5lZT1KYXZhU0U7IHZlcnNpb246VmVyc2lvbj1cIjEuNS4wXCIiLCBjb250YWluZXIpOwoKCQljb250YWluZXIucmVzb2x2ZShBcnJheXMuYXNMaXN0KHN5c3RlbUJ1bmRsZSksIHRydWUpOwoJCU1vZHVsZSBjMSA9IGluc3RhbGxEdW1teU1vZHVsZSgiYzFfdjEuTUYiLCAiYzFfdjEiLCBjb250YWluZXIpOwoJCU1vZHVsZSBkeW5hbWljMSA9IGluc3RhbGxEdW1teU1vZHVsZSgiZHluYW1pYzFfdjEuTUYiLCAiZHluYW1pYzFfdjEiLCBjb250YWluZXIpOwoKCQljb250YWluZXIucmVzb2x2ZShBcnJheXMuYXNMaXN0KGMxLCBkeW5hbWljMSksIHRydWUpOwoKCQlEdW1teVJlc29sdmVySG9va0ZhY3RvcnkgZmFjdG9yeSA9IChEdW1teVJlc29sdmVySG9va0ZhY3RvcnkpIGFkYXB0b3IuZ2V0UmVzb2x2ZXJIb29rRmFjdG9yeSgpOwoJCUR1bW15UmVzb2x2ZXJIb29rIGhvb2sgPSAoRHVtbXlSZXNvbHZlckhvb2spIGZhY3RvcnkuZ2V0SG9vaygpOwoJCWhvb2suZ2V0UmVzb2x1dGlvblJlcG9ydHMoKS5jbGVhcigpOwoJCU1vZHVsZVdpcmUgZHluYW1pY1dpcmUgPSBjb250YWluZXIucmVzb2x2ZUR5bmFtaWMoIm9yZy5vc2dpLmZyYW1ld29yayIsIGR5bmFtaWMxLmdldEN1cnJlbnRSZXZpc2lvbigpKTsKCQlBc3NlcnQuYXNzZXJ0Tm90TnVsbCgiTm8gZHluYW1pYyB3aXJlIGZvdW5kLiIsIGR5bmFtaWNXaXJlKTsKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJXcm9uZyBwYWNrYWdlIGZvdW5kLiIsICJvcmcub3NnaS5mcmFtZXdvcmsiLCBkeW5hbWljV2lyZS5nZXRDYXBhYmlsaXR5KCkuZ2V0QXR0cmlidXRlcygpLmdldChQYWNrYWdlTmFtZXNwYWNlLlBBQ0tBR0VfTkFNRVNQQUNFKSk7CgkJQXNzZXJ0LmFzc2VydEVxdWFscygiV3JvbmcgcHJvdmlkZXIgZm9yIHRoZSB3aXJlIGZvdW5kLiIsIHN5c3RlbUJ1bmRsZS5nZXRDdXJyZW50UmV2aXNpb24oKSwgZHluYW1pY1dpcmUuZ2V0UHJvdmlkZXIoKSk7CgoJCUFzc2VydC5hc3NlcnRFcXVhbHMoIldyb25nIG51bWJlciBvZiByZXBvcnRzLiIsIDEsIGhvb2suZ2V0UmVzb2x1dGlvblJlcG9ydHMoKS5zaXplKCkpOwoJCWhvb2suZ2V0UmVzb2x1dGlvblJlcG9ydHMoKS5jbGVhcigpOwoKCQlkeW5hbWljV2lyZSA9IGNvbnRhaW5lci5yZXNvbHZlRHluYW1pYygiZG9lcy5ub3QuZXhpc3QiLCBkeW5hbWljMS5nZXRDdXJyZW50UmV2aXNpb24oKSk7CgkJQXNzZXJ0LmFzc2VydE51bGwoIlVuZXhwZWN0ZWQgRHluYW1pYyB3aXJlIGZvdW5kLiIsIGR5bmFtaWNXaXJlKTsKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJXcm9uZyBudW1iZXIgb2YgcmVwb3J0cy4iLCAxLCBob29rLmdldFJlc29sdXRpb25SZXBvcnRzKCkuc2l6ZSgpKTsKCgkJLy8gVHJ5IGFnYWluOyBubyByZXBvcnQgc2hvdWxkIGJlIGdlbmVyYXRlZCBhIHNlY29uZCB0aW1lCgkJaG9vay5nZXRSZXNvbHV0aW9uUmVwb3J0cygpLmNsZWFyKCk7CgkJZHluYW1pY1dpcmUgPSBjb250YWluZXIucmVzb2x2ZUR5bmFtaWMoImRvZXMubm90LmV4aXN0IiwgZHluYW1pYzEuZ2V0Q3VycmVudFJldmlzaW9uKCkpOwoJCUFzc2VydC5hc3NlcnROdWxsKCJVbmV4cGVjdGVkIER5bmFtaWMgd2lyZSBmb3VuZC4iLCBkeW5hbWljV2lyZSk7CgkJQXNzZXJ0LmFzc2VydEVxdWFscygiV3JvbmcgbnVtYmVyIG9mIHJlcG9ydHMuIiwgMCwgaG9vay5nZXRSZXNvbHV0aW9uUmVwb3J0cygpLnNpemUoKSk7Cgl9CgoJQFRlc3QKCXB1YmxpYyB2b2lkIHRlc3RSZXF1aXJlQnVuZGxlVXNlcygpIHRocm93cyBCdW5kbGVFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKCQlEdW1teUNvbnRhaW5lckFkYXB0b3IgYWRhcHRvciA9IGNyZWF0ZUR1bW15QWRhcHRvcigpOwoJCU1vZHVsZUNvbnRhaW5lciBjb250YWluZXIgPSBhZGFwdG9yLmdldENvbnRhaW5lcigpOwoKCQlNb2R1bGUgc3lzdGVtQnVuZGxlID0gaW5zdGFsbER1bW15TW9kdWxlKCJzeXN0ZW0uYnVuZGxlLk1GIiwgQ29uc3RhbnRzLlNZU1RFTV9CVU5ETEVfTE9DQVRJT04sIGNvbnRhaW5lcik7CgoJCWNvbnRhaW5lci5yZXNvbHZlKEFycmF5cy5hc0xpc3Qoc3lzdGVtQnVuZGxlKSwgdHJ1ZSk7CgkJTW9kdWxlIGIxID0gaW5zdGFsbER1bW15TW9kdWxlKCJyZXF1aXJlLmIxLk1GIiwgImIxIiwgY29udGFpbmVyKTsKCQlpbnN0YWxsRHVtbXlNb2R1bGUoInJlcXVpcmUuYjIuTUYiLCAiYjIiLCBjb250YWluZXIpOwoJCWluc3RhbGxEdW1teU1vZHVsZSgicmVxdWlyZS5iMy5NRiIsICJiMyIsIGNvbnRhaW5lcik7CgkJaW5zdGFsbER1bW15TW9kdWxlKCJyZXF1aXJlLmI0Lk1GIiwgImI0IiwgY29udGFpbmVyKTsKCgkJY29udGFpbmVyLnJlc29sdmUobnVsbCwgZmFsc2UpOwoKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJiMSBzaG91bGQgbm90IHJlc29sdmUuIiwgU3RhdGUuSU5TVEFMTEVELCBiMS5nZXRTdGF0ZSgpKTsKCX0KCgkvKgoJICogVGVzdCB0aGF0IGEgcmVzb2x2ZSBwcm9jZXNzIGRvZXMgbm90IGJsb3cgdXAgYmVjYXVzZSBvZiBvbmUgdW5yZXNvbHZhYmxlIHVzZXMgY29uc3RyYWludCBpc3N1ZQoJICovCglAVGVzdAoJcHVibGljIHZvaWQgdGVzdFVzZXMxKCkgdGhyb3dzIEJ1bmRsZUV4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewoJCUR1bW15Q29udGFpbmVyQWRhcHRvciBhZGFwdG9yID0gY3JlYXRlRHVtbXlBZGFwdG9yKCk7CgkJTW9kdWxlQ29udGFpbmVyIGNvbnRhaW5lciA9IGFkYXB0b3IuZ2V0Q29udGFpbmVyKCk7CgoJCU1vZHVsZSBzeXN0ZW1CdW5kbGUgPSBpbnN0YWxsRHVtbXlNb2R1bGUoInN5c3RlbS5idW5kbGUuTUYiLCBDb25zdGFudHMuU1lTVEVNX0JVTkRMRV9MT0NBVElPTiwgY29udGFpbmVyKTsKCgkJY29udGFpbmVyLnJlc29sdmUoQXJyYXlzLmFzTGlzdChzeXN0ZW1CdW5kbGUpLCB0cnVlKTsKCQlNb2R1bGUgdXNlc19hID0gaW5zdGFsbER1bW15TW9kdWxlKCJ1c2VzLmEuTUYiLCAiYSIsIGNvbnRhaW5lcik7CgkJTW9kdWxlIHVzZXNfYiA9IGluc3RhbGxEdW1teU1vZHVsZSgidXNlcy5iLk1GIiwgImIiLCBjb250YWluZXIpOwoJCU1vZHVsZSB1c2VzX2MgPSBpbnN0YWxsRHVtbXlNb2R1bGUoInVzZXMuYy5NRiIsICJjIiwgY29udGFpbmVyKTsKCgkJY29udGFpbmVyLnJlc29sdmUobnVsbCwgZmFsc2UpOwoKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJhIHNob3VsZCByZXNvbHZlLiIsIFN0YXRlLlJFU09MVkVELCB1c2VzX2EuZ2V0U3RhdGUoKSk7CgkJQXNzZXJ0LmFzc2VydEVxdWFscygiYiBzaG91bGQgcmVzb2x2ZS4iLCBTdGF0ZS5SRVNPTFZFRCwgdXNlc19iLmdldFN0YXRlKCkpOwoJCUFzc2VydC5hc3NlcnRFcXVhbHMoImMgc2hvdWxkIG5vdCByZXNvbHZlLiIsIFN0YXRlLklOU1RBTExFRCwgdXNlc19jLmdldFN0YXRlKCkpOwoJfQoKCUBUZXN0CglwdWJsaWMgdm9pZCB0ZXN0VXNlczFEeW5hbWljKCkgdGhyb3dzIEJ1bmRsZUV4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewoJCUR1bW15Q29udGFpbmVyQWRhcHRvciBhZGFwdG9yID0gY3JlYXRlRHVtbXlBZGFwdG9yKG5ldyBEdW1teURlYnVnT3B0aW9ucyhDb2xsZWN0aW9ucy5zaW5nbGV0b25NYXAoIm9yZy5lY2xpcHNlLm9zZ2kvcmVzb2x2ZXIvcmVwb3J0IiwgInRydWUiKSkpOwoJCU1vZHVsZUNvbnRhaW5lciBjb250YWluZXIgPSBhZGFwdG9yLmdldENvbnRhaW5lcigpOwoKCQlNb2R1bGUgc3lzdGVtQnVuZGxlID0gaW5zdGFsbER1bW15TW9kdWxlKCJzeXN0ZW0uYnVuZGxlLk1GIiwgQ29uc3RhbnRzLlNZU1RFTV9CVU5ETEVfTE9DQVRJT04sIGNvbnRhaW5lcik7CgoJCWNvbnRhaW5lci5yZXNvbHZlKEFycmF5cy5hc0xpc3Qoc3lzdGVtQnVuZGxlKSwgdHJ1ZSk7CgkJTW9kdWxlIHVzZXNfYSA9IGluc3RhbGxEdW1teU1vZHVsZSgidXNlcy5hLk1GIiwgImEiLCBjb250YWluZXIpOwoJCU1vZHVsZSB1c2VzX2IgPSBpbnN0YWxsRHVtbXlNb2R1bGUoInVzZXMuYi5NRiIsICJiIiwgY29udGFpbmVyKTsKCQlNb2R1bGUgdXNlc19jX2R5bmFtaWMgPSBpbnN0YWxsRHVtbXlNb2R1bGUoInVzZXMuYy5keW5hbWljLk1GIiwgImMiLCBjb250YWluZXIpOwoKCQljb250YWluZXIucmVzb2x2ZShudWxsLCBmYWxzZSk7CgoJCUFzc2VydC5hc3NlcnRFcXVhbHMoImEgc2hvdWxkIHJlc29sdmUuIiwgU3RhdGUuUkVTT0xWRUQsIHVzZXNfYS5nZXRTdGF0ZSgpKTsKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJiIHNob3VsZCByZXNvbHZlLiIsIFN0YXRlLlJFU09MVkVELCB1c2VzX2IuZ2V0U3RhdGUoKSk7CgkJQXNzZXJ0LmFzc2VydEVxdWFscygiYyBzaG91bGQgcmVzb2x2ZS4iLCBTdGF0ZS5SRVNPTFZFRCwgdXNlc19jX2R5bmFtaWMuZ2V0U3RhdGUoKSk7CgoJCU1vZHVsZVdpcmUgZHluYW1pY1dpcmUgPSBjb250YWluZXIucmVzb2x2ZUR5bmFtaWMoInVzZXMxIiwgdXNlc19jX2R5bmFtaWMuZ2V0Q3VycmVudFJldmlzaW9uKCkpOwoJCUFzc2VydC5hc3NlcnROb3ROdWxsKCJObyBkeW5hbWljIHdpcmUuIiwgZHluYW1pY1dpcmUpOwoKCQlQcmludFN0cmVhbSBvcmlnaW5hbE91dCA9IERlYnVnLm91dDsKCQlCeXRlQXJyYXlPdXRwdXRTdHJlYW0gYnl0ZXNPdXQgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CgkJUHJpbnRTdHJlYW0gdGVzdE91dCA9IG5ldyBQcmludFN0cmVhbShieXRlc091dCk7CgkJRGVidWcub3V0ID0gdGVzdE91dDsKCQl0cnkgewoJCQlkeW5hbWljV2lyZSA9IGNvbnRhaW5lci5yZXNvbHZlRHluYW1pYygidXNlczIiLCB1c2VzX2NfZHluYW1pYy5nZXRDdXJyZW50UmV2aXNpb24oKSk7CgkJCUFzc2VydC5hc3NlcnROdWxsKCJEeW5hbWljIHdpcmUgZm91bmQuIiwgZHluYW1pY1dpcmUpOwoJCX0gZmluYWxseSB7CgkJCURlYnVnLm91dCA9IG9yaWdpbmFsT3V0OwoJCQl0ZXN0T3V0LmNsb3NlKCk7CgkJfQoJCVN0cmluZyB0cmFjZU91dHB1dCA9IGJ5dGVzT3V0LnRvU3RyaW5nKCk7CgkJQXNzZXJ0LmFzc2VydFRydWUoIldyb25nIHRyYWNlT3V0cHV0OiAiICsgdHJhY2VPdXRwdXQsIHRyYWNlT3V0cHV0LnN0YXJ0c1dpdGgoIm9yZy5vc2dpLnNlcnZpY2UucmVzb2x2ZXIuUmVzb2x1dGlvbkV4Y2VwdGlvbiIpKTsKCX0KCgkvKgoJICogVGVzdCB0aGF0IHNwbGl0IHBhY2thZ2VzIGFyZSBoYW5kbGVkIG9rIHdpdGggdXNlcyBjb25zdHJhaW50cwoJICovCglAVGVzdAoJcHVibGljIHZvaWQgdGVzdFVzZXMyKCkgdGhyb3dzIEJ1bmRsZUV4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewoJCUR1bW15Q29udGFpbmVyQWRhcHRvciBhZGFwdG9yID0gY3JlYXRlRHVtbXlBZGFwdG9yKCk7CgkJTW9kdWxlQ29udGFpbmVyIGNvbnRhaW5lciA9IGFkYXB0b3IuZ2V0Q29udGFpbmVyKCk7CgoJCU1vZHVsZSBzeXN0ZW1CdW5kbGUgPSBpbnN0YWxsRHVtbXlNb2R1bGUoInN5c3RlbS5idW5kbGUuTUYiLCBDb25zdGFudHMuU1lTVEVNX0JVTkRMRV9MT0NBVElPTiwgY29udGFpbmVyKTsKCgkJY29udGFpbmVyLnJlc29sdmUoQXJyYXlzLmFzTGlzdChzeXN0ZW1CdW5kbGUpLCB0cnVlKTsKCQlNb2R1bGUgdXNlc19hID0gaW5zdGFsbER1bW15TW9kdWxlKCJ1c2VzLmEuTUYiLCAiYSIsIGNvbnRhaW5lcik7CgkJTW9kdWxlIHVzZXNfYiA9IGluc3RhbGxEdW1teU1vZHVsZSgidXNlcy5iLk1GIiwgImIiLCBjb250YWluZXIpOwoJCU1vZHVsZSB1c2VzX2QgPSBpbnN0YWxsRHVtbXlNb2R1bGUoInVzZXMuZC5NRiIsICJkIiwgY29udGFpbmVyKTsKCgkJY29udGFpbmVyLnJlc29sdmUobnVsbCwgZmFsc2UpOwoKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJhIHNob3VsZCByZXNvbHZlLiIsIFN0YXRlLlJFU09MVkVELCB1c2VzX2EuZ2V0U3RhdGUoKSk7CgkJQXNzZXJ0LmFzc2VydEVxdWFscygiYiBzaG91bGQgcmVzb2x2ZS4iLCBTdGF0ZS5SRVNPTFZFRCwgdXNlc19iLmdldFN0YXRlKCkpOwoJCUFzc2VydC5hc3NlcnRFcXVhbHMoImQgc2hvdWxkIHJlc29sdmUuIiwgU3RhdGUuUkVTT0xWRUQsIHVzZXNfZC5nZXRTdGF0ZSgpKTsKCX0KCgkvKgoJICogVGVzdCB0aGF0IHNwbGl0IHBhY2thZ2VzIGFyZSBoYW5kbGVkIG9rIHdpdGggdXNlcyBjb25zdHJhaW50cwoJICovCglAVGVzdAoJcHVibGljIHZvaWQgdGVzdFVzZXMzKCkgdGhyb3dzIEJ1bmRsZUV4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewoJCUR1bW15Q29udGFpbmVyQWRhcHRvciBhZGFwdG9yID0gY3JlYXRlRHVtbXlBZGFwdG9yKCk7CgkJTW9kdWxlQ29udGFpbmVyIGNvbnRhaW5lciA9IGFkYXB0b3IuZ2V0Q29udGFpbmVyKCk7CgoJCU1vZHVsZSBzeXN0ZW1CdW5kbGUgPSBpbnN0YWxsRHVtbXlNb2R1bGUoInN5c3RlbS5idW5kbGUuTUYiLCBDb25zdGFudHMuU1lTVEVNX0JVTkRMRV9MT0NBVElPTiwgY29udGFpbmVyKTsKCgkJY29udGFpbmVyLnJlc29sdmUoQXJyYXlzLmFzTGlzdChzeXN0ZW1CdW5kbGUpLCB0cnVlKTsKCQlNb2R1bGUgdXNlc19hID0gaW5zdGFsbER1bW15TW9kdWxlKCJ1c2VzLmEuTUYiLCAiYSIsIGNvbnRhaW5lcik7CgkJTW9kdWxlIHVzZXNfYiA9IGluc3RhbGxEdW1teU1vZHVsZSgidXNlcy5iLk1GIiwgImIiLCBjb250YWluZXIpOwoJCU1vZHVsZSB1c2VzX2UgPSBpbnN0YWxsRHVtbXlNb2R1bGUoInVzZXMuZS5NRiIsICJlIiwgY29udGFpbmVyKTsKCQlNb2R1bGUgdXNlc19mID0gaW5zdGFsbER1bW15TW9kdWxlKCJ1c2VzLmYuTUYiLCAiZiIsIGNvbnRhaW5lcik7CgkJTW9kdWxlIHVzZXNfZyA9IGluc3RhbGxEdW1teU1vZHVsZSgidXNlcy5nLk1GIiwgImciLCBjb250YWluZXIpOwoKCQljb250YWluZXIucmVzb2x2ZShudWxsLCBmYWxzZSk7CgoJCUFzc2VydC5hc3NlcnRFcXVhbHMoImEgc2hvdWxkIHJlc29sdmUuIiwgU3RhdGUuUkVTT0xWRUQsIHVzZXNfYS5nZXRTdGF0ZSgpKTsKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJiIHNob3VsZCByZXNvbHZlLiIsIFN0YXRlLlJFU09MVkVELCB1c2VzX2IuZ2V0U3RhdGUoKSk7CgkJQXNzZXJ0LmFzc2VydEVxdWFscygiZSBzaG91bGQgcmVzb2x2ZS4iLCBTdGF0ZS5SRVNPTFZFRCwgdXNlc19lLmdldFN0YXRlKCkpOwoJCUFzc2VydC5hc3NlcnRFcXVhbHMoImYgc2hvdWxkIHJlc29sdmUuIiwgU3RhdGUuUkVTT0xWRUQsIHVzZXNfZi5nZXRTdGF0ZSgpKTsKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJnIHNob3VsZCBub3QgcmVzb2x2ZS4iLCBTdGF0ZS5JTlNUQUxMRUQsIHVzZXNfZy5nZXRTdGF0ZSgpKTsKCX0KCgkvKgoJICogVGVzdCB0aGF0IGZyYWdtZW50cyBhbmQgdXNlcyBjb25zdHJhaW50cwoJICovCglAVGVzdAoJcHVibGljIHZvaWQgdGVzdFVzZXM0KCkgdGhyb3dzIEJ1bmRsZUV4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewoJCUR1bW15Q29udGFpbmVyQWRhcHRvciBhZGFwdG9yID0gY3JlYXRlRHVtbXlBZGFwdG9yKCk7CgkJTW9kdWxlQ29udGFpbmVyIGNvbnRhaW5lciA9IGFkYXB0b3IuZ2V0Q29udGFpbmVyKCk7CgoJCU1vZHVsZSBzeXN0ZW1CdW5kbGUgPSBpbnN0YWxsRHVtbXlNb2R1bGUoInN5c3RlbS5idW5kbGUuTUYiLCBDb25zdGFudHMuU1lTVEVNX0JVTkRMRV9MT0NBVElPTiwgY29udGFpbmVyKTsKCgkJY29udGFpbmVyLnJlc29sdmUoQXJyYXlzLmFzTGlzdChzeXN0ZW1CdW5kbGUpLCB0cnVlKTsKCQlNb2R1bGUgdXNlc19oID0gaW5zdGFsbER1bW15TW9kdWxlKCJ1c2VzLmguTUYiLCAiaCIsIGNvbnRhaW5lcik7CgkJTW9kdWxlIHVzZXNfaF9mcmFnID0gaW5zdGFsbER1bW15TW9kdWxlKCJ1c2VzLmguZnJhZy5NRiIsICJoLmZyYWciLCBjb250YWluZXIpOwoKCQljb250YWluZXIucmVzb2x2ZShudWxsLCBmYWxzZSk7CgoJCUFzc2VydC5hc3NlcnRFcXVhbHMoImggc2hvdWxkIHJlc29sdmUuIiwgU3RhdGUuUkVTT0xWRUQsIHVzZXNfaC5nZXRTdGF0ZSgpKTsKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJoLmZyYWcgc2hvdWxkIHJlc29sdmUuIiwgU3RhdGUuUkVTT0xWRUQsIHVzZXNfaF9mcmFnLmdldFN0YXRlKCkpOwoKCQlNb2R1bGUgdXNlc19pID0gaW5zdGFsbER1bW15TW9kdWxlKCJ1c2VzLmkuTUYiLCAiaSIsIGNvbnRhaW5lcik7CgkJTW9kdWxlIHVzZXNfaiA9IGluc3RhbGxEdW1teU1vZHVsZSgidXNlcy5qLk1GIiwgImoiLCBjb250YWluZXIpOwoKCQljb250YWluZXIucmVzb2x2ZShudWxsLCBmYWxzZSk7CgoJCUFzc2VydC5hc3NlcnRFcXVhbHMoImkgc2hvdWxkIHJlc29sdmUuIiwgU3RhdGUuUkVTT0xWRUQsIHVzZXNfaS5nZXRTdGF0ZSgpKTsKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJqIHNob3VsZCByZXNvbHZlLiIsIFN0YXRlLlJFU09MVkVELCB1c2VzX2ouZ2V0U3RhdGUoKSk7CgoJCUxpc3Q8QnVuZGxlV2lyZT4gcmVxdWlyZWRXaXJlcyA9IHVzZXNfai5nZXRDdXJyZW50UmV2aXNpb24oKS5nZXRXaXJpbmcoKS5nZXRSZXF1aXJlZFdpcmVzKG51bGwpOwoJCUFzc2VydC5hc3NlcnRFcXVhbHMoIldyb25nIG51bWJlciBvZiB3aXJlcyBmb3IgaiIsIDIsIHJlcXVpcmVkV2lyZXMuc2l6ZSgpKTsKCQlmb3IgKEJ1bmRsZVdpcmUgd2lyZSA6IHJlcXVpcmVkV2lyZXMpIHsKCQkJQXNzZXJ0LmFzc2VydEVxdWFscygiV3JvbmcgcHJvdmlkZXIiLCB1c2VzX2kuZ2V0Q3VycmVudFJldmlzaW9uKCksIHdpcmUuZ2V0UHJvdmlkZXIoKSk7CgkJfQoKCQlNb2R1bGUgdXNlc19qX2R5bmFtaWMgPSBpbnN0YWxsRHVtbXlNb2R1bGUoInVzZXMuai5keW5hbWljLk1GIiwgImouZHluYW1pYyIsIGNvbnRhaW5lcik7CgkJY29udGFpbmVyLnJlc29sdmUobnVsbCwgZmFsc2UpOwoJCU1vZHVsZVdpcmUgZHluYW1pY1dpcmUgPSBjb250YWluZXIucmVzb2x2ZUR5bmFtaWMoInVzZXMyIiwgdXNlc19qX2R5bmFtaWMuZ2V0Q3VycmVudFJldmlzaW9uKCkpOwoJCUFzc2VydC5hc3NlcnROb3ROdWxsKCJOdWxsIGR5bmFtaWMgd2lyZS4iLCBkeW5hbWljV2lyZSk7CgkJQXNzZXJ0LmFzc2VydEVxdWFscygiV3JvbmcgcHJvdmlkZXIiLCB1c2VzX2kuZ2V0Q3VycmVudFJldmlzaW9uKCksIGR5bmFtaWNXaXJlLmdldFByb3ZpZGVyKCkpOwoJfQoKCS8qKgoJICogVGVzdCBvcHRpb25hbCBjb25zdHJhaW50cwoJICogQHRocm93cyBCdW5kbGVFeGNlcHRpb24KCSAqIEB0aHJvd3MgSU9FeGNlcHRpb24KCSAqLwoJQFRlc3QKCXB1YmxpYyB2b2lkIHRlc3RVc2VzNUltcG9ydGVyKCkgdGhyb3dzIEJ1bmRsZUV4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewoJCWRvVGVzdFVzZXM1KCJ1c2VzLmsuaW1wb3J0ZXIuTUYiKTsKCX0KCglAVGVzdAoJcHVibGljIHZvaWQgdGVzdFVzZXM1UmVxQ2FwKCkgdGhyb3dzIEJ1bmRsZUV4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewoJCWRvVGVzdFVzZXM1KCJ1c2VzLmsucmVxQ2FwLk1GIik7Cgl9CgoJQFRlc3QKCXB1YmxpYyB2b2lkIHRlc3RVc2VzNVJlcXVpcmVyKCkgdGhyb3dzIEJ1bmRsZUV4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewoJCWRvVGVzdFVzZXM1KCJ1c2VzLmsucmVxdWlyZXIuTUYiKTsKCX0KCglwdWJsaWMgdm9pZCBkb1Rlc3RVc2VzNShTdHJpbmcga01hbmlmZXN0KSB0aHJvd3MgQnVuZGxlRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CgkJRHVtbXlDb250YWluZXJBZGFwdG9yIGFkYXB0b3IgPSBjcmVhdGVEdW1teUFkYXB0b3IoKTsKCQlNb2R1bGVDb250YWluZXIgY29udGFpbmVyID0gYWRhcHRvci5nZXRDb250YWluZXIoKTsKCgkJTW9kdWxlIHN5c3RlbUJ1bmRsZSA9IGluc3RhbGxEdW1teU1vZHVsZSgic3lzdGVtLmJ1bmRsZS5NRiIsIENvbnN0YW50cy5TWVNURU1fQlVORExFX0xPQ0FUSU9OLCBjb250YWluZXIpOwoKCQljb250YWluZXIucmVzb2x2ZShBcnJheXMuYXNMaXN0KHN5c3RlbUJ1bmRsZSksIHRydWUpOwoJCU1vZHVsZSB1c2VzX2sgPSBpbnN0YWxsRHVtbXlNb2R1bGUoa01hbmlmZXN0LCAiayIsIGNvbnRhaW5lcik7CgkJTW9kdWxlIHVzZXNfbCA9IGluc3RhbGxEdW1teU1vZHVsZSgidXNlcy5sLk1GIiwgImwiLCBjb250YWluZXIpOwoJCU1vZHVsZSB1c2VzX21fY29uZmxpY3QxID0gaW5zdGFsbER1bW15TW9kdWxlKCJ1c2VzLm0uY29uZmxpY3QxLk1GIiwgIm0uY29uZmxpY3QxIiwgY29udGFpbmVyKTsKCQlNb2R1bGUgdXNlc19tX2NvbmZsaWN0MiA9IGluc3RhbGxEdW1teU1vZHVsZSgidXNlcy5tLmNvbmZsaWN0Mi5NRiIsICJtLmNvbmZsaWN0MiIsIGNvbnRhaW5lcik7CgoJCWNvbnRhaW5lci5yZXNvbHZlKG51bGwsIGZhbHNlKTsKCgkJQXNzZXJ0LmFzc2VydEVxdWFscygiayBzaG91bGQgcmVzb2x2ZS4iLCBTdGF0ZS5SRVNPTFZFRCwgdXNlc19rLmdldFN0YXRlKCkpOwoJCUFzc2VydC5hc3NlcnRFcXVhbHMoImwgc2hvdWxkIHJlc29sdmUuIiwgU3RhdGUuUkVTT0xWRUQsIHVzZXNfbC5nZXRTdGF0ZSgpKTsKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJtLmNvbmZsaWN0MSBzaG91bGQgcmVzb2x2ZS4iLCBTdGF0ZS5SRVNPTFZFRCwgdXNlc19tX2NvbmZsaWN0MS5nZXRTdGF0ZSgpKTsKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJtLmNvbmZsaWN0MiBzaG91bGQgcmVzb2x2ZS4iLCBTdGF0ZS5SRVNPTFZFRCwgdXNlc19tX2NvbmZsaWN0Mi5nZXRTdGF0ZSgpKTsKCX0KCglAVGVzdAoJcHVibGljIHZvaWQgdGVzdFVzZXM2RnJhZ0NvbmZsaWN0cygpIHRocm93cyBCdW5kbGVFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKCQlEdW1teUNvbnRhaW5lckFkYXB0b3IgYWRhcHRvciA9IGNyZWF0ZUR1bW15QWRhcHRvcigpOwoJCU1vZHVsZUNvbnRhaW5lciBjb250YWluZXIgPSBhZGFwdG9yLmdldENvbnRhaW5lcigpOwoKCQlNb2R1bGUgc3lzdGVtQnVuZGxlID0gaW5zdGFsbER1bW15TW9kdWxlKCJzeXN0ZW0uYnVuZGxlLk1GIiwgQ29uc3RhbnRzLlNZU1RFTV9CVU5ETEVfTE9DQVRJT04sIGNvbnRhaW5lcik7CgoJCWNvbnRhaW5lci5yZXNvbHZlKEFycmF5cy5hc0xpc3Qoc3lzdGVtQnVuZGxlKSwgdHJ1ZSk7CgkJTW9kdWxlIHVzZXNfbjEgPSBpbnN0YWxsRHVtbXlNb2R1bGUoInVzZXMubjEuTUYiLCAibjEiLCBjb250YWluZXIpOwoJCWluc3RhbGxEdW1teU1vZHVsZSgidXNlcy5uMi5NRiIsICJuMiIsIGNvbnRhaW5lcik7CgkJTW9kdWxlIHVzZXNfbjJfZnJhZyA9IGluc3RhbGxEdW1teU1vZHVsZSgidXNlcy5uMi5mcmFnLk1GIiwgIm4yLmZyYWciLCBjb250YWluZXIpOwoJCU1vZHVsZSB1c2VzX24zID0gaW5zdGFsbER1bW15TW9kdWxlKCJ1c2VzLm4zLk1GIiwgIm4zIiwgY29udGFpbmVyKTsKCQlSZXNvbHV0aW9uUmVwb3J0IHJlcG9ydCA9IGNvbnRhaW5lci5yZXNvbHZlKG51bGwsIGZhbHNlKTsKCQlBc3NlcnQuYXNzZXJ0TnVsbCgicmVzb2x1dGlvbiByZXBvcnQgaGFzIGEgcmVzb2x1dGlvbiBleGNlcHRpb24uIiwgcmVwb3J0LmdldFJlc29sdXRpb25FeGNlcHRpb24oKSk7CgoJCUFzc2VydC5hc3NlcnRFcXVhbHMoIm4xIHNob3VsZCByZXNvbHZlLiIsIFN0YXRlLlJFU09MVkVELCB1c2VzX24xLmdldFN0YXRlKCkpOwoJCS8vIFRPRE8gVGhlIGZvbGxvd2luZyBzaG91bGQgYmUgdHJ1ZSwgYnV0IG9uIHRoZSBjdXJyZW50IHJlc29sdmVyIGluIE1hcnMgdGhlIGhvc3QgaXMgdGhyb3duIGF3YXkgYWxzbwoJCS8vQXNzZXJ0LmFzc2VydEVxdWFscygibjIgc2hvdWxkIHJlc29sdmUuIiwgU3RhdGUuUkVTT0xWRUQsIHVzZXNfbjIuZ2V0U3RhdGUoKSk7CgkJQXNzZXJ0LmFzc2VydEVxdWFscygibjIuZnJhZyBzaG91bGQgbm90IHJlc29sdmUuIiwgU3RhdGUuSU5TVEFMTEVELCB1c2VzX24yX2ZyYWcuZ2V0U3RhdGUoKSk7CgkJQXNzZXJ0LmFzc2VydEVxdWFscygibjMgc2hvdWxkIHJlc29sdmUuIiwgU3RhdGUuUkVTT0xWRUQsIHVzZXNfbjMuZ2V0U3RhdGUoKSk7Cgl9CgoJQFRlc3QKCXB1YmxpYyB2b2lkIHRlc3RVc2VzVGltZW91dCgpIHRocm93cyBCdW5kbGVFeGNlcHRpb24gewoJCS8vIEFsd2F5cyB3YW50IHRvIGdvIHRvIHplcm8gdGhyZWFkcyB3aGVuIGlkbGUKCQlpbnQgY29yZVRocmVhZHMgPSAwOwoJCS8vIHVzZSB0aGUgbnVtYmVyIG9mIHByb2Nlc3NvcnMgLSAxIGJlY2F1c2Ugd2UgdXNlIHRoZSBjdXJyZW50IHRocmVhZCB3aGVuIHJlamVjdGVkCgkJaW50IG1heFRocmVhZHMgPSBNYXRoLm1heChSdW50aW1lLmdldFJ1bnRpbWUoKS5hdmFpbGFibGVQcm9jZXNzb3JzKCkgLSAxLCAxKTsKCQkvLyBpZGxlIHRpbWVvdXQ7IG1ha2UgaXQgc2hvcnQgdG8gZ2V0IHJpZCBvZiB0aHJlYWRzIHF1aWNrbHkgYWZ0ZXIgcmVzb2x2ZQoJCWludCBpZGxlVGltZW91dCA9IDU7CgkJLy8gdXNlIHN5bmMgcXVldWUgdG8gZm9yY2UgdGhyZWFkIGNyZWF0aW9uCgkJQmxvY2tpbmdRdWV1ZTxSdW5uYWJsZT4gcXVldWUgPSBuZXcgU3luY2hyb25vdXNRdWV1ZTxSdW5uYWJsZT4oKTsKCQkvLyB0cnkgdG8gbmFtZSB0aGUgdGhyZWFkcyB3aXRoIHVzZWZ1bCBuYW1lCgkJVGhyZWFkRmFjdG9yeSB0aHJlYWRGYWN0b3J5ID0gbmV3IFRocmVhZEZhY3RvcnkoKSB7CgkJCUBPdmVycmlkZQoJCQlwdWJsaWMgVGhyZWFkIG5ld1RocmVhZChSdW5uYWJsZSByKSB7CgkJCQlUaHJlYWQgdCA9IG5ldyBUaHJlYWQociwgIlJlc29sdmVyIHRocmVhZCAtIFVOSVQgVEVTVCIpOyAvLyROT04tTkxTLTEkCgkJCQl0LnNldERhZW1vbih0cnVlKTsKCQkJCXJldHVybiB0OwoJCQl9CgkJfTsKCQkvLyB1c2UgYSByZWplY3Rpb24gcG9saWN5IHRoYXQgc2ltcGx5IHJ1bnMgdGhlIHRhc2sgaW4gdGhlIGN1cnJlbnQgdGhyZWFkIG9uY2UgdGhlIG1heCB0aHJlYWRzIGlzIHJlYWNoZWQKCQlSZWplY3RlZEV4ZWN1dGlvbkhhbmRsZXIgcmVqZWN0SGFuZGxlciA9IG5ldyBSZWplY3RlZEV4ZWN1dGlvbkhhbmRsZXIoKSB7CgkJCUBPdmVycmlkZQoJCQlwdWJsaWMgdm9pZCByZWplY3RlZEV4ZWN1dGlvbihSdW5uYWJsZSByLCBUaHJlYWRQb29sRXhlY3V0b3IgZXhlKSB7CgkJCQlyLnJ1bigpOwoJCQl9CgkJfTsKCQlFeGVjdXRvclNlcnZpY2UgZXhlY3V0b3IgPSBuZXcgVGhyZWFkUG9vbEV4ZWN1dG9yKGNvcmVUaHJlYWRzLCBtYXhUaHJlYWRzLCBpZGxlVGltZW91dCwgVGltZVVuaXQuU0VDT05EUywgcXVldWUsIHRocmVhZEZhY3RvcnksIHJlamVjdEhhbmRsZXIpOwoKCQlNYXA8U3RyaW5nLCBTdHJpbmc+IGNvbmZpZ3VyYXRpb24gPSBuZXcgSGFzaE1hcDxTdHJpbmcsIFN0cmluZz4oKTsKCQljb25maWd1cmF0aW9uLnB1dChFcXVpbm94Q29uZmlndXJhdGlvbi5QUk9QX1JFU09MVkVSX0JBVENIX1RJTUVPVVQsICI1MDAwIik7CgkJTWFwPFN0cmluZywgU3RyaW5nPiBkZWJ1Z09wdHMgPSBDb2xsZWN0aW9ucy5lbXB0eU1hcCgpOwoJCUR1bW15Q29udGFpbmVyQWRhcHRvciBhZGFwdG9yID0gbmV3IER1bW15Q29udGFpbmVyQWRhcHRvcihuZXcgRHVtbXlDb2xsaXNpb25Ib29rKGZhbHNlKSwgY29uZmlndXJhdGlvbiwgbmV3IER1bW15UmVzb2x2ZXJIb29rRmFjdG9yeSgpLCBuZXcgRHVtbXlEZWJ1Z09wdGlvbnMoZGVidWdPcHRzKSk7CgkJYWRhcHRvci5zZXRSZXNvbHZlckV4ZWN1dG9yKGV4ZWN1dG9yKTsKCQlNb2R1bGVDb250YWluZXIgY29udGFpbmVyID0gYWRhcHRvci5nZXRDb250YWluZXIoKTsKCQlmb3IgKGludCBpID0gMTsgaSA8PSAxMDAwOyBpKyspIHsKCQkJZm9yIChNYXA8U3RyaW5nLCBTdHJpbmc+IG1hbmlmZXN0IDogZ2V0VXNlc1RpbWVvdXRNYW5pZmVzdHMoInRlc3QiICsgaSkpIHsKCQkJCWluc3RhbGxEdW1teU1vZHVsZShtYW5pZmVzdCwgbWFuaWZlc3QuZ2V0KENvbnN0YW50cy5CVU5ETEVfU1lNQk9MSUNOQU1FKSwgY29udGFpbmVyKTsKCQkJfQoJCX0KCQlSZXNvbHV0aW9uUmVwb3J0IHJlcG9ydCA9IGNvbnRhaW5lci5yZXNvbHZlKGNvbnRhaW5lci5nZXRNb2R1bGVzKCksIHRydWUpOwoJCUFzc2VydC5hc3NlcnROdWxsKCJGb3VuZCByZXNvbHV0aW9uIGVycm9ycy4iLCByZXBvcnQuZ2V0UmVzb2x1dGlvbkV4Y2VwdGlvbigpKTsKCQlmb3IgKE1vZHVsZSBtb2R1bGUgOiBjb250YWluZXIuZ2V0TW9kdWxlcygpKSB7CgkJCUFzc2VydC5hc3NlcnRFcXVhbHMoIldyb25nIHN0YXRlIG9mIG1vZHVsZTogIiArIG1vZHVsZSwgU3RhdGUuUkVTT0xWRUQsIG1vZHVsZS5nZXRTdGF0ZSgpKTsKCQl9CgkJZXhlY3V0b3Iuc2h1dGRvd24oKTsKCQlTeXN0ZW0uZ2MoKTsKCQlTeXN0ZW0uZ2MoKTsKCQlTeXN0ZW0uZ2MoKTsKCX0KCglwcml2YXRlIExpc3Q8TWFwPFN0cmluZywgU3RyaW5nPj4gZ2V0VXNlc1RpbWVvdXRNYW5pZmVzdHMoU3RyaW5nIHByZWZpeCkgewoJCUxpc3Q8TWFwPFN0cmluZywgU3RyaW5nPj4gcmVzdWx0ID0gbmV3IEFycmF5TGlzdDxNYXA8U3RyaW5nLCBTdHJpbmc+PigpOwoJCS8vIHgxIGJ1bmRsZQoJCU1hcDxTdHJpbmcsIFN0cmluZz4geDFNYW5pZmVzdCA9IG5ldyBIYXNoTWFwPFN0cmluZywgU3RyaW5nPigpOwoJCXgxTWFuaWZlc3QucHV0KENvbnN0YW50cy5CVU5ETEVfTUFOSUZFU1RWRVJTSU9OLCAiMiIpOwoJCXgxTWFuaWZlc3QucHV0KENvbnN0YW50cy5CVU5ETEVfU1lNQk9MSUNOQU1FLCBwcmVmaXggKyAiLngxIik7CgkJeDFNYW5pZmVzdC5wdXQoQ29uc3RhbnRzLkVYUE9SVF9QQUNLQUdFLCBwcmVmaXggKyAiLmE7IHZlcnNpb249MS4wOyB1c2VzOj0iICsgcHJlZml4ICsgIi5iIik7CgkJeDFNYW5pZmVzdC5wdXQoQ29uc3RhbnRzLklNUE9SVF9QQUNLQUdFLCBwcmVmaXggKyAiLmI7IHZlcnNpb249XCJbMS4xLDEuMilcIiIpOwoJCXJlc3VsdC5hZGQoeDFNYW5pZmVzdCk7CgkJLy8geDIgYnVuZGxlCgkJTWFwPFN0cmluZywgU3RyaW5nPiB4Mk1hbmlmZXN0ID0gbmV3IEhhc2hNYXA8U3RyaW5nLCBTdHJpbmc+KCk7CgkJeDJNYW5pZmVzdC5wdXQoQ29uc3RhbnRzLkJVTkRMRV9NQU5JRkVTVFZFUlNJT04sICIyIik7CgkJeDJNYW5pZmVzdC5wdXQoQ29uc3RhbnRzLkJVTkRMRV9TWU1CT0xJQ05BTUUsIHByZWZpeCArICIueDIiKTsKCQl4Mk1hbmlmZXN0LnB1dChDb25zdGFudHMuRVhQT1JUX1BBQ0tBR0UsIHByZWZpeCArICIuYTsgdmVyc2lvbj0xLjE7IHVzZXM6PSIgKyBwcmVmaXggKyAiLmIiKTsKCQl4Mk1hbmlmZXN0LnB1dChDb25zdGFudHMuSU1QT1JUX1BBQ0tBR0UsIHByZWZpeCArICIuYjsgdmVyc2lvbj1cIlsxLjAsMS4xKVwiIik7CgkJcmVzdWx0LmFkZCh4Mk1hbmlmZXN0KTsKCQkvLyB5MSBidW5kbGUKCQlNYXA8U3RyaW5nLCBTdHJpbmc+IHkxTWFuaWZlc3QgPSBuZXcgSGFzaE1hcDxTdHJpbmcsIFN0cmluZz4oKTsKCQl5MU1hbmlmZXN0LnB1dChDb25zdGFudHMuQlVORExFX01BTklGRVNUVkVSU0lPTiwgIjIiKTsKCQl5MU1hbmlmZXN0LnB1dChDb25zdGFudHMuQlVORExFX1NZTUJPTElDTkFNRSwgcHJlZml4ICsgIi55MSIpOwoJCXkxTWFuaWZlc3QucHV0KENvbnN0YW50cy5FWFBPUlRfUEFDS0FHRSwgcHJlZml4ICsgIi5iOyB2ZXJzaW9uPTEuMCIpOwoJCXJlc3VsdC5hZGQoeTFNYW5pZmVzdCk7CgkJLy8geTEgYnVuZGxlCgkJTWFwPFN0cmluZywgU3RyaW5nPiB5Mk1hbmlmZXN0ID0gbmV3IEhhc2hNYXA8U3RyaW5nLCBTdHJpbmc+KCk7CgkJeTJNYW5pZmVzdC5wdXQoQ29uc3RhbnRzLkJVTkRMRV9NQU5JRkVTVFZFUlNJT04sICIyIik7CgkJeTJNYW5pZmVzdC5wdXQoQ29uc3RhbnRzLkJVTkRMRV9TWU1CT0xJQ05BTUUsIHByZWZpeCArICIueTIiKTsKCQl5Mk1hbmlmZXN0LnB1dChDb25zdGFudHMuRVhQT1JUX1BBQ0tBR0UsIHByZWZpeCArICIuYjsgdmVyc2lvbj0xLjEiKTsKCQlyZXN1bHQuYWRkKHkyTWFuaWZlc3QpOwoJCS8vIHoxIGJ1bmRsZQoJCU1hcDxTdHJpbmcsIFN0cmluZz4gejFNYW5pZmVzdCA9IG5ldyBIYXNoTWFwPFN0cmluZywgU3RyaW5nPigpOwoJCXoxTWFuaWZlc3QucHV0KENvbnN0YW50cy5CVU5ETEVfTUFOSUZFU1RWRVJTSU9OLCAiMiIpOwoJCXoxTWFuaWZlc3QucHV0KENvbnN0YW50cy5CVU5ETEVfU1lNQk9MSUNOQU1FLCBwcmVmaXggKyAiLnoxIik7CgkJejFNYW5pZmVzdC5wdXQoQ29uc3RhbnRzLklNUE9SVF9QQUNLQUdFLCBwcmVmaXggKyAiLmEsICIgKyBwcmVmaXggKyAiLmIiKTsKCQlyZXN1bHQuYWRkKHoxTWFuaWZlc3QpOwoJCXJldHVybiByZXN1bHQ7Cgl9CgoJQFRlc3QKCXB1YmxpYyB2b2lkIHRlc3RPcHRpb25hbFN1YnN0aXR1dGVkKCkgdGhyb3dzIEJ1bmRsZUV4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewoJCUR1bW15Q29udGFpbmVyQWRhcHRvciBhZGFwdG9yID0gY3JlYXRlRHVtbXlBZGFwdG9yKCk7CgkJTW9kdWxlQ29udGFpbmVyIGNvbnRhaW5lciA9IGFkYXB0b3IuZ2V0Q29udGFpbmVyKCk7CgoJCU1vZHVsZSBzeXN0ZW1CdW5kbGUgPSBpbnN0YWxsRHVtbXlNb2R1bGUoInN5c3RlbS5idW5kbGUuTUYiLCBDb25zdGFudHMuU1lTVEVNX0JVTkRMRV9MT0NBVElPTiwgY29udGFpbmVyKTsKCgkJY29udGFpbmVyLnJlc29sdmUoQXJyYXlzLmFzTGlzdChzeXN0ZW1CdW5kbGUpLCB0cnVlKTsKCQlNb2R1bGUgc3ViX24gPSBpbnN0YWxsRHVtbXlNb2R1bGUoInN1Yi5uLk1GIiwgIm4iLCBjb250YWluZXIpOwoJCU1vZHVsZSBzdWJfbCA9IGluc3RhbGxEdW1teU1vZHVsZSgic3ViLmwuTUYiLCAibCIsIGNvbnRhaW5lcik7CgkJTW9kdWxlIHN1Yl9tID0gaW5zdGFsbER1bW15TW9kdWxlKCJzdWIubS5NRiIsICJtIiwgY29udGFpbmVyKTsKCgkJY29udGFpbmVyLnJlc29sdmUobnVsbCwgZmFsc2UpOwoKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJsIHNob3VsZCByZXNvbHZlLiIsIFN0YXRlLlJFU09MVkVELCBzdWJfbC5nZXRTdGF0ZSgpKTsKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJtIHNob3VsZCByZXNvbHZlLiIsIFN0YXRlLlJFU09MVkVELCBzdWJfbS5nZXRTdGF0ZSgpKTsKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJuIHNob3VsZCByZXNvbHZlLiIsIFN0YXRlLlJFU09MVkVELCBzdWJfbi5nZXRTdGF0ZSgpKTsKCX0KCglAVGVzdAoJcHVibGljIHZvaWQgdGVzdFN0YXRpY1N1YnN0aXR1dGVkKCkgdGhyb3dzIEJ1bmRsZUV4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewoJCUR1bW15Q29udGFpbmVyQWRhcHRvciBhZGFwdG9yID0gY3JlYXRlRHVtbXlBZGFwdG9yKCk7CgkJTW9kdWxlQ29udGFpbmVyIGNvbnRhaW5lciA9IGFkYXB0b3IuZ2V0Q29udGFpbmVyKCk7CgoJCU1vZHVsZSBzeXN0ZW1CdW5kbGUgPSBpbnN0YWxsRHVtbXlNb2R1bGUoInN5c3RlbS5idW5kbGUuTUYiLCBDb25zdGFudHMuU1lTVEVNX0JVTkRMRV9MT0NBVElPTiwgY29udGFpbmVyKTsKCgkJY29udGFpbmVyLnJlc29sdmUoQXJyYXlzLmFzTGlzdChzeXN0ZW1CdW5kbGUpLCB0cnVlKTsKCQlNb2R1bGUgc3ViX24gPSBpbnN0YWxsRHVtbXlNb2R1bGUoInN1Yi5uLnN0YXRpYy5NRiIsICJuIiwgY29udGFpbmVyKTsKCQlNb2R1bGUgc3ViX2wgPSBpbnN0YWxsRHVtbXlNb2R1bGUoInN1Yi5sLk1GIiwgImwiLCBjb250YWluZXIpOwoJCU1vZHVsZSBzdWJfbSA9IGluc3RhbGxEdW1teU1vZHVsZSgic3ViLm0uTUYiLCAibSIsIGNvbnRhaW5lcik7CgoJCWNvbnRhaW5lci5yZXNvbHZlKG51bGwsIGZhbHNlKTsKCgkJQXNzZXJ0LmFzc2VydEVxdWFscygibCBzaG91bGQgcmVzb2x2ZS4iLCBTdGF0ZS5SRVNPTFZFRCwgc3ViX2wuZ2V0U3RhdGUoKSk7CgkJQXNzZXJ0LmFzc2VydEVxdWFscygibSBzaG91bGQgcmVzb2x2ZS4iLCBTdGF0ZS5SRVNPTFZFRCwgc3ViX20uZ2V0U3RhdGUoKSk7CgkJQXNzZXJ0LmFzc2VydEVxdWFscygibiBzaG91bGQgcmVzb2x2ZS4iLCBTdGF0ZS5SRVNPTFZFRCwgc3ViX24uZ2V0U3RhdGUoKSk7Cgl9CgoJQFRlc3QKCXB1YmxpYyB2b2lkIHRlc3RNdWx0aUNhcmRpbmFsaXR5VXNlcygpIHRocm93cyBCdW5kbGVFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKCQlEdW1teUNvbnRhaW5lckFkYXB0b3IgYWRhcHRvciA9IGNyZWF0ZUR1bW15QWRhcHRvcigpOwoJCU1vZHVsZUNvbnRhaW5lciBjb250YWluZXIgPSBhZGFwdG9yLmdldENvbnRhaW5lcigpOwoKCQlNb2R1bGUgc3lzdGVtQnVuZGxlID0gaW5zdGFsbER1bW15TW9kdWxlKCJzeXN0ZW0uYnVuZGxlLk1GIiwgQ29uc3RhbnRzLlNZU1RFTV9CVU5ETEVfTE9DQVRJT04sIGNvbnRhaW5lcik7CgoJCWNvbnRhaW5lci5yZXNvbHZlKEFycmF5cy5hc0xpc3Qoc3lzdGVtQnVuZGxlKSwgdHJ1ZSk7CgoJCU1vZHVsZSBwNXYxMDAgPSBpbnN0YWxsRHVtbXlNb2R1bGUoInA1X3YxMDAuTUYiLCAicDVfdjEwMCIsIGNvbnRhaW5lcik7CgkJTW9kdWxlIHA1djEwMSA9IGluc3RhbGxEdW1teU1vZHVsZSgicDVfdjEwMS5NRiIsICJwNV92MTAxIiwgY29udGFpbmVyKTsKCQlNb2R1bGUgcDV2MTEwID0gaW5zdGFsbER1bW15TW9kdWxlKCJwNV92MTEwLk1GIiwgInA1X3YxMTAiLCBjb250YWluZXIpOwoJCU1vZHVsZSBwNXYxMTEgPSBpbnN0YWxsRHVtbXlNb2R1bGUoInA1X3YxMTEuTUYiLCAicDVfdjExMSIsIGNvbnRhaW5lcik7CgkJaW5zdGFsbER1bW15TW9kdWxlKCJwNl92MTAwLk1GIiwgInA2X3YxMDAiLCBjb250YWluZXIpOwoJCWluc3RhbGxEdW1teU1vZHVsZSgicDZfdjExMC5NRiIsICJwNl92MTEwIiwgY29udGFpbmVyKTsKCQlpbnN0YWxsRHVtbXlNb2R1bGUoInA3X3YxMDAuTUYiLCAicDdfdjEwMCIsIGNvbnRhaW5lcik7CgkJaW5zdGFsbER1bW15TW9kdWxlKCJwN192MTEwLk1GIiwgInA3X3YxMTAiLCBjb250YWluZXIpOwoKCQljb250YWluZXIucmVzb2x2ZShudWxsLCBmYWxzZSk7CgoJCU1vZHVsZSBjNnYxMDAgPSBpbnN0YWxsRHVtbXlNb2R1bGUoImM2X3YxMDAuTUYiLCAiYzZfdjEwMCIsIGNvbnRhaW5lcik7CgkJTW9kdWxlIGM2djExMCA9IGluc3RhbGxEdW1teU1vZHVsZSgiYzZfdjExMC5NRiIsICJjNl92MTEwIiwgY29udGFpbmVyKTsKCQlNb2R1bGUgYzZ2MTMwID0gaW5zdGFsbER1bW15TW9kdWxlKCJjNl92MTMwLk1GIiwgImM2X3YxMzAiLCBjb250YWluZXIpOwoJCU1vZHVsZSBjNnYxNDAgPSBpbnN0YWxsRHVtbXlNb2R1bGUoImM2X3YxNDAuTUYiLCAiYzZfdjE0MCIsIGNvbnRhaW5lcik7CgkJTW9kdWxlIGM2djE1MCA9IGluc3RhbGxEdW1teU1vZHVsZSgiYzZfdjE1MC5NRiIsICJjNl92MTUwIiwgY29udGFpbmVyKTsKCQlNb2R1bGUgYzZ2MTcwID0gaW5zdGFsbER1bW15TW9kdWxlKCJjNl92MTcwLk1GIiwgImM2X3YxNzAiLCBjb250YWluZXIpOwoKCQkvLwkJTW9kdWxlIGM2djE4MCA9IGluc3RhbGxEdW1teU1vZHVsZSgiYzZfdjE4MC5NRiIsICJjNl92MTgwIiwgY29udGFpbmVyKTsKCQkvLwkJTW9kdWxlIGM2djEyMCA9IGluc3RhbGxEdW1teU1vZHVsZSgiYzZfdjEyMC5NRiIsICJjNl92MTIwIiwgY29udGFpbmVyKTsKCgkJY29udGFpbmVyLnJlc29sdmUobnVsbCwgZmFsc2UpOwoKCQlmaW5hbCBTdHJpbmcgbmFtZXNwYWNlNSA9ICJuYW1lc3BhY2UuNSI7CgkJTGlzdDxNb2R1bGVXaXJlPiBwNXYxMDBQcm92aWRlZCA9IHA1djEwMC5nZXRDdXJyZW50UmV2aXNpb24oKS5nZXRXaXJpbmcoKS5nZXRQcm92aWRlZE1vZHVsZVdpcmVzKG5hbWVzcGFjZTUpOwoJCUxpc3Q8TW9kdWxlV2lyZT4gcDV2MTAxUHJvdmlkZWQgPSBwNXYxMDEuZ2V0Q3VycmVudFJldmlzaW9uKCkuZ2V0V2lyaW5nKCkuZ2V0UHJvdmlkZWRNb2R1bGVXaXJlcyhuYW1lc3BhY2U1KTsKCQlMaXN0PE1vZHVsZVdpcmU+IHA1djExMFByb3ZpZGVkID0gcDV2MTEwLmdldEN1cnJlbnRSZXZpc2lvbigpLmdldFdpcmluZygpLmdldFByb3ZpZGVkTW9kdWxlV2lyZXMobmFtZXNwYWNlNSk7CgkJTGlzdDxNb2R1bGVXaXJlPiBwNXYxMTFQcm92aWRlZCA9IHA1djExMS5nZXRDdXJyZW50UmV2aXNpb24oKS5nZXRXaXJpbmcoKS5nZXRQcm92aWRlZE1vZHVsZVdpcmVzKG5hbWVzcGFjZTUpOwoKCQlNb2R1bGVXaXJpbmcgYzZ2MTAwV2lyaW5nID0gYzZ2MTAwLmdldEN1cnJlbnRSZXZpc2lvbigpLmdldFdpcmluZygpOwoJCUxpc3Q8TW9kdWxlV2lyZT4gYzZ2MTAwUmVxdWlyZWQgPSBjNnYxMDBXaXJpbmcuZ2V0UmVxdWlyZWRNb2R1bGVXaXJlcyhuYW1lc3BhY2U1KTsKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJXcm9uZyBudW1iZXIgb2YgY2FwYWJpbGl0aWVzIiwgMiwgYzZ2MTAwUmVxdWlyZWQuc2l6ZSgpKTsKCQlhc3NlcnRXaXJlcyhjNnYxMDBSZXF1aXJlZCwgcDV2MTAwUHJvdmlkZWQsIHA1djEwMVByb3ZpZGVkKTsKCgkJTW9kdWxlV2lyaW5nIGM2djExMFdpcmluZyA9IGM2djExMC5nZXRDdXJyZW50UmV2aXNpb24oKS5nZXRXaXJpbmcoKTsKCQlMaXN0PE1vZHVsZVdpcmU+IGM2djExMFJlcXVpcmVkID0gYzZ2MTEwV2lyaW5nLmdldFJlcXVpcmVkTW9kdWxlV2lyZXMobmFtZXNwYWNlNSk7CgkJQXNzZXJ0LmFzc2VydEVxdWFscygiV3JvbmcgbnVtYmVyIG9mIGNhcGFiaWxpdGllcyIsIDIsIGM2djExMFJlcXVpcmVkLnNpemUoKSk7CgkJYXNzZXJ0V2lyZXMoYzZ2MTEwUmVxdWlyZWQsIHA1djEwMFByb3ZpZGVkLCBwNXYxMDFQcm92aWRlZCk7CgoJCU1vZHVsZVdpcmluZyBjNnYxMzBXaXJpbmcgPSBjNnYxMzAuZ2V0Q3VycmVudFJldmlzaW9uKCkuZ2V0V2lyaW5nKCk7CgkJTGlzdDxNb2R1bGVXaXJlPiBjNnYxMzBSZXF1aXJlZCA9IGM2djEzMFdpcmluZy5nZXRSZXF1aXJlZE1vZHVsZVdpcmVzKG5hbWVzcGFjZTUpOwoJCUFzc2VydC5hc3NlcnRFcXVhbHMoIldyb25nIG51bWJlciBvZiBjYXBhYmlsaXRpZXMiLCAyLCBjNnYxMzBSZXF1aXJlZC5zaXplKCkpOwoJCWFzc2VydFdpcmVzKGM2djEzMFJlcXVpcmVkLCBwNXYxMDBQcm92aWRlZCwgcDV2MTAxUHJvdmlkZWQpOwoKCQlNb2R1bGVXaXJpbmcgYzZ2MTQwV2lyaW5nID0gYzZ2MTQwLmdldEN1cnJlbnRSZXZpc2lvbigpLmdldFdpcmluZygpOwoJCUxpc3Q8TW9kdWxlV2lyZT4gYzZ2MTQwUmVxdWlyZWQgPSBjNnYxNDBXaXJpbmcuZ2V0UmVxdWlyZWRNb2R1bGVXaXJlcyhuYW1lc3BhY2U1KTsKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJXcm9uZyBudW1iZXIgb2YgY2FwYWJpbGl0aWVzIiwgMiwgYzZ2MTQwUmVxdWlyZWQuc2l6ZSgpKTsKCQlhc3NlcnRXaXJlcyhjNnYxNDBSZXF1aXJlZCwgcDV2MTAwUHJvdmlkZWQsIHA1djEwMVByb3ZpZGVkKTsKCgkJTW9kdWxlV2lyaW5nIGM2djE1MFdpcmluZyA9IGM2djE1MC5nZXRDdXJyZW50UmV2aXNpb24oKS5nZXRXaXJpbmcoKTsKCQlMaXN0PE1vZHVsZVdpcmU+IGM2djE1MFJlcXVpcmVkID0gYzZ2MTUwV2lyaW5nLmdldFJlcXVpcmVkTW9kdWxlV2lyZXMobmFtZXNwYWNlNSk7CgkJQXNzZXJ0LmFzc2VydEVxdWFscygiV3JvbmcgbnVtYmVyIG9mIGNhcGFiaWxpdGllcyIsIDIsIGM2djE1MFJlcXVpcmVkLnNpemUoKSk7CgkJYXNzZXJ0V2lyZXMoYzZ2MTUwUmVxdWlyZWQsIHA1djExMFByb3ZpZGVkLCBwNXYxMTFQcm92aWRlZCk7CgoJCU1vZHVsZVdpcmluZyBjNnYxNzBXaXJpbmcgPSBjNnYxNzAuZ2V0Q3VycmVudFJldmlzaW9uKCkuZ2V0V2lyaW5nKCk7CgkJTGlzdDxNb2R1bGVXaXJlPiBjNnYxNzBSZXF1aXJlZCA9IGM2djE3MFdpcmluZy5nZXRSZXF1aXJlZE1vZHVsZVdpcmVzKG5hbWVzcGFjZTUpOwoJCUFzc2VydC5hc3NlcnRFcXVhbHMoIldyb25nIG51bWJlciBvZiBjYXBhYmlsaXRpZXMiLCAyLCBjNnYxNzBSZXF1aXJlZC5zaXplKCkpOwoJCWFzc2VydFdpcmVzKGM2djE3MFJlcXVpcmVkLCBwNXYxMTBQcm92aWRlZCwgcDV2MTExUHJvdmlkZWQpOwoKCQlNb2R1bGUgYzZ2MTYwID0gaW5zdGFsbER1bW15TW9kdWxlKCJjNl92MTYwLk1GIiwgImM2X3YxNjAiLCBjb250YWluZXIpOwoKCQljb250YWluZXIucmVzb2x2ZShudWxsLCBmYWxzZSk7CgoJCUFzc2VydC5hc3NlcnROdWxsKCJCdW5kbGUgc2hvdWxkIG5vdCBiZSByZXNvbHZlZDogIiArIGM2djE2MCwgYzZ2MTYwLmdldEN1cnJlbnRSZXZpc2lvbigpLmdldFdpcmluZygpKTsKCgkJY29udGFpbmVyLnVuaW5zdGFsbChjNnYxNjApOwoKCQlNb2R1bGUgYzZ2MTgwID0gaW5zdGFsbER1bW15TW9kdWxlKCJjNl92MTgwLk1GIiwgImM2X3YxODAiLCBjb250YWluZXIpOwoKCQljb250YWluZXIucmVzb2x2ZShudWxsLCBmYWxzZSk7CgoJCUFzc2VydC5hc3NlcnROdWxsKCJCdW5kbGUgc2hvdWxkIG5vdCBiZSByZXNvbHZlZDogIiArIGM2djE4MCwgYzZ2MTgwLmdldEN1cnJlbnRSZXZpc2lvbigpLmdldFdpcmluZygpKTsKCgkJY29udGFpbmVyLnVuaW5zdGFsbChjNnYxODApOwoJfQoKCUBUZXN0CglwdWJsaWMgdm9pZCB0ZXN0Q29tcGF0U2luZ2xldG9uKCkgdGhyb3dzIEJ1bmRsZUV4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewoJCUR1bW15Q29udGFpbmVyQWRhcHRvciBhZGFwdG9yID0gY3JlYXRlRHVtbXlBZGFwdG9yKCk7CgkJTW9kdWxlQ29udGFpbmVyIGNvbnRhaW5lciA9IGFkYXB0b3IuZ2V0Q29udGFpbmVyKCk7CgkJTW9kdWxlIHMxID0gaW5zdGFsbER1bW15TW9kdWxlKCJjb21wYXRTaW5nbGV0b24xLk1GIiwgInMxIiwgY29udGFpbmVyKTsKCQlNb2R1bGUgczIgPSBpbnN0YWxsRHVtbXlNb2R1bGUoImNvbXBhdFNpbmdsZXRvbjIuTUYiLCAiczIiLCBjb250YWluZXIpOwoJCU1vZHVsZSBzMyA9IGluc3RhbGxEdW1teU1vZHVsZSgiY29tcGF0U2luZ2xldG9uMy5NRiIsICJzMyIsIGNvbnRhaW5lcik7CgoJCVN0cmluZyBzMVNpbmdsZXRvbiA9IHMxLmdldEN1cnJlbnRSZXZpc2lvbigpLmdldENhcGFiaWxpdGllcyhJZGVudGl0eU5hbWVzcGFjZS5JREVOVElUWV9OQU1FU1BBQ0UpLml0ZXJhdG9yKCkubmV4dCgpLmdldERpcmVjdGl2ZXMoKS5nZXQoSWRlbnRpdHlOYW1lc3BhY2UuQ0FQQUJJTElUWV9TSU5HTEVUT05fRElSRUNUSVZFKTsKCQlTdHJpbmcgczJTaW5nbGV0b24gPSBzMi5nZXRDdXJyZW50UmV2aXNpb24oKS5nZXRDYXBhYmlsaXRpZXMoSWRlbnRpdHlOYW1lc3BhY2UuSURFTlRJVFlfTkFNRVNQQUNFKS5pdGVyYXRvcigpLm5leHQoKS5nZXREaXJlY3RpdmVzKCkuZ2V0KElkZW50aXR5TmFtZXNwYWNlLkNBUEFCSUxJVFlfU0lOR0xFVE9OX0RJUkVDVElWRSk7CgkJU3RyaW5nIHMzU2luZ2xldG9uID0gczMuZ2V0Q3VycmVudFJldmlzaW9uKCkuZ2V0Q2FwYWJpbGl0aWVzKElkZW50aXR5TmFtZXNwYWNlLklERU5USVRZX05BTUVTUEFDRSkuaXRlcmF0b3IoKS5uZXh0KCkuZ2V0RGlyZWN0aXZlcygpLmdldChJZGVudGl0eU5hbWVzcGFjZS5DQVBBQklMSVRZX1NJTkdMRVRPTl9ESVJFQ1RJVkUpOwoKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJXcm9uZyBzaW5nbGV0b24gZGlyZWN0aXZlOiAiICsgczEsICJ0cnVlIiwgczFTaW5nbGV0b24pOwoJCUFzc2VydC5hc3NlcnROdWxsKCJXcm9uZyBzaW5nbGV0b24gZGlyZWN0aXZlOiAiICsgczIsIHMyU2luZ2xldG9uKTsKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJXcm9uZyBzaW5nbGV0b24gZGlyZWN0aXZlOiAiICsgczMsICJ0cnVlIiwgczNTaW5nbGV0b24pOwoJfQoKCUBUZXN0CglwdWJsaWMgdm9pZCB0ZXN0Q29tcGF0UmVwcm92aWRlKCkgdGhyb3dzIEJ1bmRsZUV4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewoJCUR1bW15Q29udGFpbmVyQWRhcHRvciBhZGFwdG9yID0gY3JlYXRlRHVtbXlBZGFwdG9yKCk7CgkJTW9kdWxlQ29udGFpbmVyIGNvbnRhaW5lciA9IGFkYXB0b3IuZ2V0Q29udGFpbmVyKCk7CgkJTW9kdWxlIGIxID0gaW5zdGFsbER1bW15TW9kdWxlKCJjb21wYXRSZXByb3ZpZGUxLk1GIiwgImIxIiwgY29udGFpbmVyKTsKCQlNb2R1bGUgYjIgPSBpbnN0YWxsRHVtbXlNb2R1bGUoImNvbXBhdFJlcHJvdmlkZTIuTUYiLCAiYjIiLCBjb250YWluZXIpOwoJCU1vZHVsZSBiMyA9IGluc3RhbGxEdW1teU1vZHVsZSgiY29tcGF0UmVwcm92aWRlMy5NRiIsICJiMyIsIGNvbnRhaW5lcik7CgoJCVN0cmluZyBiMVZpc2liaWxpdHkgPSBiMS5nZXRDdXJyZW50UmV2aXNpb24oKS5nZXRSZXF1aXJlbWVudHMoQnVuZGxlTmFtZXNwYWNlLkJVTkRMRV9OQU1FU1BBQ0UpLml0ZXJhdG9yKCkubmV4dCgpLmdldERpcmVjdGl2ZXMoKS5nZXQoQnVuZGxlTmFtZXNwYWNlLlJFUVVJUkVNRU5UX1ZJU0lCSUxJVFlfRElSRUNUSVZFKTsKCQlTdHJpbmcgYjJWaXNpYmlsaXR5ID0gYjIuZ2V0Q3VycmVudFJldmlzaW9uKCkuZ2V0UmVxdWlyZW1lbnRzKEJ1bmRsZU5hbWVzcGFjZS5CVU5ETEVfTkFNRVNQQUNFKS5pdGVyYXRvcigpLm5leHQoKS5nZXREaXJlY3RpdmVzKCkuZ2V0KEJ1bmRsZU5hbWVzcGFjZS5SRVFVSVJFTUVOVF9WSVNJQklMSVRZX0RJUkVDVElWRSk7CgkJU3RyaW5nIGIzVmlzaWJpbGl0eSA9IGIzLmdldEN1cnJlbnRSZXZpc2lvbigpLmdldFJlcXVpcmVtZW50cyhCdW5kbGVOYW1lc3BhY2UuQlVORExFX05BTUVTUEFDRSkuaXRlcmF0b3IoKS5uZXh0KCkuZ2V0RGlyZWN0aXZlcygpLmdldChCdW5kbGVOYW1lc3BhY2UuUkVRVUlSRU1FTlRfVklTSUJJTElUWV9ESVJFQ1RJVkUpOwoKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJXcm9uZyB2aXNpYmlsaXR5IGRpcmVjdGl2ZTogIiArIGIxLCBCdW5kbGVOYW1lc3BhY2UuVklTSUJJTElUWV9SRUVYUE9SVCwgYjFWaXNpYmlsaXR5KTsKCQlBc3NlcnQuYXNzZXJ0TnVsbCgiV3JvbmcgdmlzaWJpbGl0eSBkaXJlY3RpdmU6ICIsIGIyVmlzaWJpbGl0eSk7CgkJQXNzZXJ0LmFzc2VydEVxdWFscygiV3JvbmcgdmlzaWJpbGl0eSBkaXJlY3RpdmU6ICIgKyBiMiwgQnVuZGxlTmFtZXNwYWNlLlZJU0lCSUxJVFlfUkVFWFBPUlQsIGIzVmlzaWJpbGl0eSk7Cgl9CgoJQFRlc3QKCXB1YmxpYyB2b2lkIHRlc3RDb21wYXRPcHRpb25hbCgpIHRocm93cyBCdW5kbGVFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKCQlEdW1teUNvbnRhaW5lckFkYXB0b3IgYWRhcHRvciA9IGNyZWF0ZUR1bW15QWRhcHRvcigpOwoJCU1vZHVsZUNvbnRhaW5lciBjb250YWluZXIgPSBhZGFwdG9yLmdldENvbnRhaW5lcigpOwoJCU1vZHVsZSBiMSA9IGluc3RhbGxEdW1teU1vZHVsZSgiY29tcGF0T3B0aW9uYWwxLk1GIiwgImIxIiwgY29udGFpbmVyKTsKCQlNb2R1bGUgYjIgPSBpbnN0YWxsRHVtbXlNb2R1bGUoImNvbXBhdE9wdGlvbmFsMi5NRiIsICJiMiIsIGNvbnRhaW5lcik7CgkJTW9kdWxlIGIzID0gaW5zdGFsbER1bW15TW9kdWxlKCJjb21wYXRPcHRpb25hbDMuTUYiLCAiYjMiLCBjb250YWluZXIpOwoKCQlTdHJpbmcgYjFCdW5kbGVSZXNvbHV0aW9uID0gYjEuZ2V0Q3VycmVudFJldmlzaW9uKCkuZ2V0UmVxdWlyZW1lbnRzKEJ1bmRsZU5hbWVzcGFjZS5CVU5ETEVfTkFNRVNQQUNFKS5pdGVyYXRvcigpLm5leHQoKS5nZXREaXJlY3RpdmVzKCkuZ2V0KE5hbWVzcGFjZS5SRVFVSVJFTUVOVF9SRVNPTFVUSU9OX0RJUkVDVElWRSk7CgkJU3RyaW5nIGIyQnVuZGxlUmVzb2x1dGlvbiA9IGIyLmdldEN1cnJlbnRSZXZpc2lvbigpLmdldFJlcXVpcmVtZW50cyhCdW5kbGVOYW1lc3BhY2UuQlVORExFX05BTUVTUEFDRSkuaXRlcmF0b3IoKS5uZXh0KCkuZ2V0RGlyZWN0aXZlcygpLmdldChOYW1lc3BhY2UuUkVRVUlSRU1FTlRfUkVTT0xVVElPTl9ESVJFQ1RJVkUpOwoJCVN0cmluZyBiM0J1bmRsZVJlc29sdXRpb24gPSBiMy5nZXRDdXJyZW50UmV2aXNpb24oKS5nZXRSZXF1aXJlbWVudHMoQnVuZGxlTmFtZXNwYWNlLkJVTkRMRV9OQU1FU1BBQ0UpLml0ZXJhdG9yKCkubmV4dCgpLmdldERpcmVjdGl2ZXMoKS5nZXQoTmFtZXNwYWNlLlJFUVVJUkVNRU5UX1JFU09MVVRJT05fRElSRUNUSVZFKTsKCgkJU3RyaW5nIGIxUGFja2FnZVJlc29sdXRpb24gPSBiMS5nZXRDdXJyZW50UmV2aXNpb24oKS5nZXRSZXF1aXJlbWVudHMoUGFja2FnZU5hbWVzcGFjZS5QQUNLQUdFX05BTUVTUEFDRSkuaXRlcmF0b3IoKS5uZXh0KCkuZ2V0RGlyZWN0aXZlcygpLmdldChOYW1lc3BhY2UuUkVRVUlSRU1FTlRfUkVTT0xVVElPTl9ESVJFQ1RJVkUpOwoJCVN0cmluZyBiMlBhY2thZ2VSZXNvbHV0aW9uID0gYjIuZ2V0Q3VycmVudFJldmlzaW9uKCkuZ2V0UmVxdWlyZW1lbnRzKFBhY2thZ2VOYW1lc3BhY2UuUEFDS0FHRV9OQU1FU1BBQ0UpLml0ZXJhdG9yKCkubmV4dCgpLmdldERpcmVjdGl2ZXMoKS5nZXQoTmFtZXNwYWNlLlJFUVVJUkVNRU5UX1JFU09MVVRJT05fRElSRUNUSVZFKTsKCQlTdHJpbmcgYjNQYWNrYWdlUmVzb2x1dGlvbiA9IGIzLmdldEN1cnJlbnRSZXZpc2lvbigpLmdldFJlcXVpcmVtZW50cyhQYWNrYWdlTmFtZXNwYWNlLlBBQ0tBR0VfTkFNRVNQQUNFKS5pdGVyYXRvcigpLm5leHQoKS5nZXREaXJlY3RpdmVzKCkuZ2V0KE5hbWVzcGFjZS5SRVFVSVJFTUVOVF9SRVNPTFVUSU9OX0RJUkVDVElWRSk7CgoJCUFzc2VydC5hc3NlcnRFcXVhbHMoIldyb25nIHJlc29sdXRpb24gZGlyZWN0aXZlOiAiICsgYjEsIE5hbWVzcGFjZS5SRVNPTFVUSU9OX09QVElPTkFMLCBiMUJ1bmRsZVJlc29sdXRpb24pOwoJCUFzc2VydC5hc3NlcnROdWxsKCJXcm9uZyByZXNvbHV0aW9uIGRpcmVjdGl2ZTogIiwgYjJCdW5kbGVSZXNvbHV0aW9uKTsKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJXcm9uZyByZXNvbHV0aW9uIGRpcmVjdGl2ZTogIiArIGIyLCBOYW1lc3BhY2UuUkVTT0xVVElPTl9PUFRJT05BTCwgYjNCdW5kbGVSZXNvbHV0aW9uKTsKCgkJQXNzZXJ0LmFzc2VydEVxdWFscygiV3JvbmcgcmVzb2x1dGlvbiBkaXJlY3RpdmU6ICIgKyBiMSwgTmFtZXNwYWNlLlJFU09MVVRJT05fT1BUSU9OQUwsIGIxUGFja2FnZVJlc29sdXRpb24pOwoJCUFzc2VydC5hc3NlcnROdWxsKCJXcm9uZyByZXNvbHV0aW9uIGRpcmVjdGl2ZTogIiwgYjJQYWNrYWdlUmVzb2x1dGlvbik7CgkJQXNzZXJ0LmFzc2VydEVxdWFscygiV3JvbmcgcmVzb2x1dGlvbiBkaXJlY3RpdmU6ICIgKyBiMiwgTmFtZXNwYWNlLlJFU09MVVRJT05fT1BUSU9OQUwsIGIzUGFja2FnZVJlc29sdXRpb24pOwoJfQoKCUBUZXN0CglwdWJsaWMgdm9pZCB0ZXN0Q29tcGF0UHJvdmlkZVBhY2thZ2UoKSB0aHJvd3MgQnVuZGxlRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CgkJRHVtbXlDb250YWluZXJBZGFwdG9yIGFkYXB0b3IgPSBjcmVhdGVEdW1teUFkYXB0b3IoKTsKCQlNb2R1bGVDb250YWluZXIgY29udGFpbmVyID0gYWRhcHRvci5nZXRDb250YWluZXIoKTsKCQlNb2R1bGUgYjEgPSBpbnN0YWxsRHVtbXlNb2R1bGUoImNvbXBhdFByb3ZpZGVQYWNrYWdlMS5NRiIsICJiMSIsIGNvbnRhaW5lcik7CgoJCUxpc3Q8TW9kdWxlQ2FwYWJpbGl0eT4gcGFja2FnZUNhcHMgPSBiMS5nZXRDdXJyZW50UmV2aXNpb24oKS5nZXRNb2R1bGVDYXBhYmlsaXRpZXMoUGFja2FnZU5hbWVzcGFjZS5QQUNLQUdFX05BTUVTUEFDRSk7CgkJQXNzZXJ0LmFzc2VydEVxdWFscygiV3JvbmcgbnVtYmVyIG9mIGV4cG9ydHMiLCA1LCBwYWNrYWdlQ2Fwcy5zaXplKCkpOwoKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJXcm9uZyBwYWNrYWdlIG5hbWUuIiwgImZvbyIsIHBhY2thZ2VDYXBzLmdldCgwKS5nZXRBdHRyaWJ1dGVzKCkuZ2V0KFBhY2thZ2VOYW1lc3BhY2UuUEFDS0FHRV9OQU1FU1BBQ0UpKTsKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJXcm9uZyBwYWNrYWdlIG5hbWUuIiwgImZhYSIsIHBhY2thZ2VDYXBzLmdldCgxKS5nZXRBdHRyaWJ1dGVzKCkuZ2V0KFBhY2thZ2VOYW1lc3BhY2UuUEFDS0FHRV9OQU1FU1BBQ0UpKTsKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJXcm9uZyBwYWNrYWdlIG5hbWUuIiwgImJhciIsIHBhY2thZ2VDYXBzLmdldCgyKS5nZXRBdHRyaWJ1dGVzKCkuZ2V0KFBhY2thZ2VOYW1lc3BhY2UuUEFDS0FHRV9OQU1FU1BBQ0UpKTsKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJXcm9uZyBwYWNrYWdlIG5hbWUuIiwgImJheiIsIHBhY2thZ2VDYXBzLmdldCgzKS5nZXRBdHRyaWJ1dGVzKCkuZ2V0KFBhY2thZ2VOYW1lc3BhY2UuUEFDS0FHRV9OQU1FU1BBQ0UpKTsKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJXcm9uZyBwYWNrYWdlIG5hbWUuIiwgImJpeiIsIHBhY2thZ2VDYXBzLmdldCg0KS5nZXRBdHRyaWJ1dGVzKCkuZ2V0KFBhY2thZ2VOYW1lc3BhY2UuUEFDS0FHRV9OQU1FU1BBQ0UpKTsKCX0KCglAVGVzdAoJcHVibGljIHZvaWQgdGVzdEJ1ZzQ1NzExOCgpIHRocm93cyBCdW5kbGVFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKCQlEdW1teUNvbnRhaW5lckFkYXB0b3IgYWRhcHRvciA9IGNyZWF0ZUR1bW15QWRhcHRvcigpOwoJCU1vZHVsZUNvbnRhaW5lciBjb250YWluZXIgPSBhZGFwdG9yLmdldENvbnRhaW5lcigpOwoKCQlNb2R1bGUgc3lzdGVtQnVuZGxlID0gaW5zdGFsbER1bW15TW9kdWxlKCJzeXN0ZW0uYnVuZGxlLk1GIiwgQ29uc3RhbnRzLlNZU1RFTV9CVU5ETEVfTE9DQVRJT04sIGNvbnRhaW5lcik7CgoJCWNvbnRhaW5lci5yZXNvbHZlKEFycmF5cy5hc0xpc3Qoc3lzdGVtQnVuZGxlKSwgdHJ1ZSk7CgkJTW9kdWxlIGUgPSBpbnN0YWxsRHVtbXlNb2R1bGUoImJ1ZzQ1NzExOC5lLk1GIiwgImUiLCBjb250YWluZXIpOwoJCU1vZHVsZSBhID0gaW5zdGFsbER1bW15TW9kdWxlKCJidWc0NTcxMTguYS5NRiIsICJhIiwgY29udGFpbmVyKTsKCQlNb2R1bGUgYiA9IGluc3RhbGxEdW1teU1vZHVsZSgiYnVnNDU3MTE4LmIuTUYiLCAiYiIsIGNvbnRhaW5lcik7CgkJTW9kdWxlIGMgPSBpbnN0YWxsRHVtbXlNb2R1bGUoImJ1ZzQ1NzExOC5jLk1GIiwgImMiLCBjb250YWluZXIpOwoJCU1vZHVsZSBkID0gaW5zdGFsbER1bW15TW9kdWxlKCJidWc0NTcxMTguZC5NRiIsICJkIiwgY29udGFpbmVyKTsKCgkJaW5zdGFsbER1bW15TW9kdWxlKCJidWc0NTcxMTguYTIuTUYiLCAiYTIiLCBjb250YWluZXIpOwoJCWluc3RhbGxEdW1teU1vZHVsZSgiYnVnNDU3MTE4LmIyLk1GIiwgImIyIiwgY29udGFpbmVyKTsKCQlpbnN0YWxsRHVtbXlNb2R1bGUoImJ1ZzQ1NzExOC5jMi5NRiIsICJjMiIsIGNvbnRhaW5lcik7CgkJaW5zdGFsbER1bW15TW9kdWxlKCJidWc0NTcxMTguZDIuTUYiLCAiZDIiLCBjb250YWluZXIpOwoKCQljb250YWluZXIucmVzb2x2ZShudWxsLCB0cnVlKTsKCgkJQXNzZXJ0LmFzc2VydEVxdWFscygiZSBzaG91bGQgcmVzb2x2ZS4iLCBTdGF0ZS5SRVNPTFZFRCwgZS5nZXRTdGF0ZSgpKTsKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJhIHNob3VsZCByZXNvbHZlLiIsIFN0YXRlLlJFU09MVkVELCBhLmdldFN0YXRlKCkpOwoJCUFzc2VydC5hc3NlcnRFcXVhbHMoImIgc2hvdWxkIHJlc29sdmUuIiwgU3RhdGUuUkVTT0xWRUQsIGIuZ2V0U3RhdGUoKSk7CgkJQXNzZXJ0LmFzc2VydEVxdWFscygiYyBzaG91bGQgcmVzb2x2ZS4iLCBTdGF0ZS5SRVNPTFZFRCwgYy5nZXRTdGF0ZSgpKTsKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJkIHNob3VsZCByZXNvbHZlLiIsIFN0YXRlLlJFU09MVkVELCBkLmdldFN0YXRlKCkpOwoKCQlMaXN0PE1vZHVsZVdpcmU+IGJ1bmRsZVdpcmVzID0gZS5nZXRDdXJyZW50UmV2aXNpb24oKS5nZXRXaXJpbmcoKS5nZXRSZXF1aXJlZE1vZHVsZVdpcmVzKEJ1bmRsZU5hbWVzcGFjZS5CVU5ETEVfTkFNRVNQQUNFKTsKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJXcm9uZyBudW1iZXIgb2YgYnVuZGxlIHdpcmVzOiAiICsgYnVuZGxlV2lyZXMsIDEsIGJ1bmRsZVdpcmVzLnNpemUoKSk7CgkJQXNzZXJ0LmFzc2VydEVxdWFscygiV3JvbmcgYnVuZGxlIHByb3ZpZGVyIiwgYS5nZXRDdXJyZW50UmV2aXNpb24oKSwgYnVuZGxlV2lyZXMuZ2V0KDApLmdldFByb3ZpZGVyKCkpOwoJfQoKCUBUZXN0CglwdWJsaWMgdm9pZCB0ZXN0QmFkTmF0aXZlQ29kZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CgkJdHJ5IHsKCQkJT1NHaU1hbmlmZXN0QnVpbGRlckZhY3RvcnkuY3JlYXRlQnVpbGRlcihnZXRNYW5pZmVzdCgiYmFkLm5hdGl2ZS5jb2RlLk1GIikpOwoJCX0gY2F0Y2ggKEJ1bmRsZUV4Y2VwdGlvbiBlKSB7CgkJCUFzc2VydC5hc3NlcnRFcXVhbHMoIldyb25nIGV4Y2VwdGlvbiB0eXBlLiIsIEJ1bmRsZUV4Y2VwdGlvbi5NQU5JRkVTVF9FUlJPUiwgZS5nZXRUeXBlKCkpOwoJCX0KCgl9CgoJQFRlc3QKCXB1YmxpYyB2b2lkIHRlc3ROYXRpdmVXaXRoRmlsdGVyQ2hhcnMoKSB0aHJvd3MgQnVuZGxlRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CgkJRHVtbXlDb250YWluZXJBZGFwdG9yIGFkYXB0b3IgPSBjcmVhdGVEdW1teUFkYXB0b3IoKTsKCQlNb2R1bGVDb250YWluZXIgY29udGFpbmVyID0gYWRhcHRvci5nZXRDb250YWluZXIoKTsKCgkJLy8gaW5zdGFsbCB0aGUgc3lzdGVtLmJ1bmRsZQoJCVN0cmluZyBleHRyYUNhcGFiaWxpdGllcyA9ICJvc2dpLm5hdGl2ZTsgb3NnaS5uYXRpdmUub3NuYW1lPVwiV2luZG93cyBOVCAodW5rbm93bilcIiI7CgkJTW9kdWxlIHN5c3RlbUJ1bmRsZSA9IGluc3RhbGxEdW1teU1vZHVsZSgic3lzdGVtLmJ1bmRsZS5NRiIsIENvbnN0YW50cy5TWVNURU1fQlVORExFX0xPQ0FUSU9OLCBDb25zdGFudHMuU1lTVEVNX0JVTkRMRV9TWU1CT0xJQ05BTUUsIG51bGwsIGV4dHJhQ2FwYWJpbGl0aWVzLCBjb250YWluZXIpOwoJCVJlc29sdXRpb25SZXBvcnQgcmVwb3J0ID0gY29udGFpbmVyLnJlc29sdmUoQXJyYXlzLmFzTGlzdChzeXN0ZW1CdW5kbGUpLCB0cnVlKTsKCQlBc3NlcnQuYXNzZXJ0TnVsbCgiRmFpbGVkIHRvIHJlc29sdmUgc3lzdGVtLmJ1bmRsZS4iLCByZXBvcnQuZ2V0UmVzb2x1dGlvbkV4Y2VwdGlvbigpKTsKCgkJLy8gaW5zdGFsbCBidW5kbGUgd2l0aCBCdW5kbGUtTmF0aXZlQ29kZQoJCU1hcDxTdHJpbmcsIFN0cmluZz4gbmF0aXZlQ29kZU1hbmlmZXN0ID0gbmV3IEhhc2hNYXA8U3RyaW5nLCBTdHJpbmc+KCk7CgkJbmF0aXZlQ29kZU1hbmlmZXN0LnB1dChDb25zdGFudHMuQlVORExFX01BTklGRVNUVkVSU0lPTiwgIjIiKTsKCQluYXRpdmVDb2RlTWFuaWZlc3QucHV0KENvbnN0YW50cy5CVU5ETEVfU1lNQk9MSUNOQU1FLCAiaW1wb3J0ZXIiKTsKCQluYXRpdmVDb2RlTWFuaWZlc3QucHV0KENvbnN0YW50cy5CVU5ETEVfTkFUSVZFQ09ERSwgLy8gCgkJCQkiL2xpYi9teWxpYi5kbGw7IG9zbmFtZT1cIndpbjMyXCI7IG9zbmFtZT1cIldpbmRvd3MgTlQgKHVua25vd24pXCIsIiArIC8vCgkJCQkJCSIvbGliL215bGliLmxpYjsgb3NuYW1lPVwiTGludXhcIiIpOwoKCQlNb2R1bGUgbmF0aXZlQ29kZU1vZHVsZSA9IGluc3RhbGxEdW1teU1vZHVsZShuYXRpdmVDb2RlTWFuaWZlc3QsICJuYXRpdmVDb2RlQnVuZGxlIiwgY29udGFpbmVyKTsKCgkJLy8gdW5zYXRpc2ZpZWQgb3B0aW9uYWwgYW5kIGR5bmFtaWMgaW1wb3J0cyBkbyBub3QgZmFpbCBhIHJlc29sdmUuIAoJCXJlcG9ydCA9IGNvbnRhaW5lci5yZXNvbHZlKEFycmF5cy5hc0xpc3QobmF0aXZlQ29kZU1vZHVsZSksIHRydWUpOwoJCUFzc2VydC5hc3NlcnROdWxsKCJGYWlsZWQgdG8gcmVzb2x2ZSBuYXRpdmVDb2RlQnVuZGxlLiIsIHJlcG9ydC5nZXRSZXNvbHV0aW9uRXhjZXB0aW9uKCkpOwoJfQoKCUBUZXN0CglwdWJsaWMgdm9pZCB0ZXN0VVRGOExpbmVDb250aW51YXRpb24oKSB0aHJvd3MgQnVuZGxlRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CgkJRHVtbXlDb250YWluZXJBZGFwdG9yIGFkYXB0b3IgPSBjcmVhdGVEdW1teUFkYXB0b3IoKTsKCQlNb2R1bGVDb250YWluZXIgY29udGFpbmVyID0gYWRhcHRvci5nZXRDb250YWluZXIoKTsKCQlTdHJpbmcgdXRmU3RyaW5nID0gImEud2l0aC7pLm11bHRpYnl0ZSI7CgkJd2hpbGUgKHV0ZlN0cmluZy5nZXRCeXRlcygiVVRGOCIpLmxlbmd0aCA8IDUwMCkgewoJCQlNYXA8U3RyaW5nLCBTdHJpbmc+IG1hbmlmZXN0ID0gZ2V0VVRGTWFuaWZlc3QodXRmU3RyaW5nKTsKCQkJTW9kdWxlIHRlc3RNb2R1bGUgPSBpbnN0YWxsRHVtbXlNb2R1bGUobWFuaWZlc3QsIG1hbmlmZXN0LmdldChDb25zdGFudHMuQlVORExFX1NZTUJPTElDTkFNRSksIGNvbnRhaW5lcik7CgkJCUFzc2VydC5hc3NlcnRFcXVhbHMoIldyb25nIGJucyBmb3IgdGhlIGJ1bmRsZS4iLCB1dGZTdHJpbmcsIHRlc3RNb2R1bGUuZ2V0Q3VycmVudFJldmlzaW9uKCkuZ2V0U3ltYm9saWNOYW1lKCkpOwoKCQkJTW9kdWxlQ2FwYWJpbGl0eSBleHBvcnRQYWNrYWdlID0gdGVzdE1vZHVsZS5nZXRDdXJyZW50UmV2aXNpb24oKS5nZXRNb2R1bGVDYXBhYmlsaXRpZXMoUGFja2FnZU5hbWVzcGFjZS5QQUNLQUdFX05BTUVTUEFDRSkuZ2V0KDApOwoJCQlNb2R1bGVSZXF1aXJlbWVudCBpbXBvcnRQYWNrYWdlID0gdGVzdE1vZHVsZS5nZXRDdXJyZW50UmV2aXNpb24oKS5nZXRNb2R1bGVSZXF1aXJlbWVudHMoUGFja2FnZU5hbWVzcGFjZS5QQUNLQUdFX05BTUVTUEFDRSkuZ2V0KDApOwoKCQkJU3RyaW5nIGFjdHVhbFBhY2thZ2VOYW1lID0gKFN0cmluZykgZXhwb3J0UGFja2FnZS5nZXRBdHRyaWJ1dGVzKCkuZ2V0KFBhY2thZ2VOYW1lc3BhY2UuUEFDS0FHRV9OQU1FU1BBQ0UpOwoJCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJXcm9uZyBleHBvcnRlZCBwYWNrYWdlIG5hbWUuIiwgdXRmU3RyaW5nLCBhY3R1YWxQYWNrYWdlTmFtZSk7CgoJCQlBc3NlcnQuYXNzZXJ0VHJ1ZSgiaW1wb3J0IGRvZXMgbm90IG1hdGNoIGV4cG9ydDogIiArIGltcG9ydFBhY2thZ2UsIGltcG9ydFBhY2thZ2UubWF0Y2hlcyhleHBvcnRQYWNrYWdlKSk7CgoJCQl1dGZTdHJpbmcgPSAiYSIgKyB1dGZTdHJpbmc7CgkJfQoJfQoKCUBUZXN0CglwdWJsaWMgdm9pZCB0ZXN0RHluYW1pY1dpdGhPcHRpb25hbEltcG9ydCgpIHRocm93cyBCdW5kbGVFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKCQlEdW1teUNvbnRhaW5lckFkYXB0b3IgYWRhcHRvciA9IGNyZWF0ZUR1bW15QWRhcHRvcigpOwoJCU1vZHVsZUNvbnRhaW5lciBjb250YWluZXIgPSBhZGFwdG9yLmdldENvbnRhaW5lcigpOwoKCQkvLyBpbnN0YWxsIHRoZSBzeXN0ZW0uYnVuZGxlCgkJTW9kdWxlIHN5c3RlbUJ1bmRsZSA9IGluc3RhbGxEdW1teU1vZHVsZSgic3lzdGVtLmJ1bmRsZS5NRiIsIENvbnN0YW50cy5TWVNURU1fQlVORExFX0xPQ0FUSU9OLCBDb25zdGFudHMuU1lTVEVNX0JVTkRMRV9TWU1CT0xJQ05BTUUsIG51bGwsIG51bGwsIGNvbnRhaW5lcik7CgkJUmVzb2x1dGlvblJlcG9ydCByZXBvcnQgPSBjb250YWluZXIucmVzb2x2ZShBcnJheXMuYXNMaXN0KHN5c3RlbUJ1bmRsZSksIHRydWUpOwoJCUFzc2VydC5hc3NlcnROdWxsKCJGYWlsZWQgdG8gcmVzb2x2ZSBzeXN0ZW0uYnVuZGxlLiIsIHJlcG9ydC5nZXRSZXNvbHV0aW9uRXhjZXB0aW9uKCkpOwoKCQkvLyBpbnN0YWxsIGFuIGltcG9ydGVyCgkJTWFwPFN0cmluZywgU3RyaW5nPiBvcHRpb25hbEltcG9ydGVyTWFuaWZlc3QgPSBuZXcgSGFzaE1hcDxTdHJpbmcsIFN0cmluZz4oKTsKCQlvcHRpb25hbEltcG9ydGVyTWFuaWZlc3QucHV0KENvbnN0YW50cy5CVU5ETEVfTUFOSUZFU1RWRVJTSU9OLCAiMiIpOwoJCW9wdGlvbmFsSW1wb3J0ZXJNYW5pZmVzdC5wdXQoQ29uc3RhbnRzLkJVTkRMRV9TWU1CT0xJQ05BTUUsICJpbXBvcnRlciIpOwoJCW9wdGlvbmFsSW1wb3J0ZXJNYW5pZmVzdC5wdXQoQ29uc3RhbnRzLklNUE9SVF9QQUNLQUdFLCAiZXhwb3J0ZXI7IHJlc29sdXRpb246PW9wdGlvbmFsIik7CgkJb3B0aW9uYWxJbXBvcnRlck1hbmlmZXN0LnB1dChDb25zdGFudHMuRFlOQU1JQ0lNUE9SVF9QQUNLQUdFLCAiZXhwb3J0ZXIiKTsKCQlNb2R1bGUgb3B0aW9uYWxJbXBvcnRlck1vZHVsZSA9IGluc3RhbGxEdW1teU1vZHVsZShvcHRpb25hbEltcG9ydGVyTWFuaWZlc3QsICJvcHRpb25hbEltcG9ydGVyIiwgY29udGFpbmVyKTsKCgkJLy8gdW5zYXRpc2ZpZWQgb3B0aW9uYWwgYW5kIGR5bmFtaWMgaW1wb3J0cyBkbyBub3QgZmFpbCBhIHJlc29sdmUuIAoJCXJlcG9ydCA9IGNvbnRhaW5lci5yZXNvbHZlKEFycmF5cy5hc0xpc3Qob3B0aW9uYWxJbXBvcnRlck1vZHVsZSksIHRydWUpOwoJCUFzc2VydC5hc3NlcnROdWxsKCJGYWlsZWQgdG8gcmVzb2x2ZSBzeXN0ZW0uYnVuZGxlLiIsIHJlcG9ydC5nZXRSZXNvbHV0aW9uRXhjZXB0aW9uKCkpOwoKCQkvL2R5bmFtaWMgYW5kIG9wdGlvbmFsIGltcG9ydHMgYXJlIHNhbWUuIE9wdGlvbmFsIGltcG9ydCBpcyBub3Qgc2F0aXNmaWVkIHdlIHNob3VsZCBvbmx5IHNlZSB0aGUgZHluYW1pYyBpbXBvcnQKCQlMaXN0PEJ1bmRsZVJlcXVpcmVtZW50PiBpbXBvcnRSZXFzTGlzdCA9IG9wdGlvbmFsSW1wb3J0ZXJNb2R1bGUuZ2V0Q3VycmVudFJldmlzaW9uKCkuZ2V0V2lyaW5nKCkuZ2V0UmVxdWlyZW1lbnRzKFBhY2thZ2VOYW1lc3BhY2UuUEFDS0FHRV9OQU1FU1BBQ0UpOwoJCWFzc2VydEVxdWFscygiV3JvbmcgbnVtYmVyIG9mIGltcG9ydHMuIiwgMSwgaW1wb3J0UmVxc0xpc3Quc2l6ZSgpKTsKCQlhc3NlcnRFcXVhbHMoIkltcG9ydCB3YXMgbm90IGR5bmFtaWMiLCBQYWNrYWdlTmFtZXNwYWNlLlJFU09MVVRJT05fRFlOQU1JQywgaW1wb3J0UmVxc0xpc3QuZ2V0KDApLmdldERpcmVjdGl2ZXMoKS5nZXQoTmFtZXNwYWNlLlJFUVVJUkVNRU5UX1JFU09MVVRJT05fRElSRUNUSVZFKSk7CgoJCS8vIGluc3RhbGwgYSBleHBvcnRlciB0byBzYXRpc2Z5IGV4aXN0aW5nIG9wdGlvbmFsIGltcG9ydAoJCU1hcDxTdHJpbmcsIFN0cmluZz4gZXhwb3J0ZXJNYW5pZmVzdCA9IG5ldyBIYXNoTWFwPFN0cmluZywgU3RyaW5nPigpOwoJCWV4cG9ydGVyTWFuaWZlc3QucHV0KENvbnN0YW50cy5CVU5ETEVfTUFOSUZFU1RWRVJTSU9OLCAiMiIpOwoJCWV4cG9ydGVyTWFuaWZlc3QucHV0KENvbnN0YW50cy5CVU5ETEVfU1lNQk9MSUNOQU1FLCAiZXhwb3J0ZXIiKTsKCQlleHBvcnRlck1hbmlmZXN0LnB1dChDb25zdGFudHMuRVhQT1JUX1BBQ0tBR0UsICJleHBvcnRlciIpOwoJCWluc3RhbGxEdW1teU1vZHVsZShleHBvcnRlck1hbmlmZXN0LCAiZXhwb3J0ZXIiLCBjb250YWluZXIpOwoKCQlNb2R1bGVXaXJlIGR5bmFtaWNXaXJlID0gY29udGFpbmVyLnJlc29sdmVEeW5hbWljKCJleHBvcnRlciIsIG9wdGlvbmFsSW1wb3J0ZXJNb2R1bGUuZ2V0Q3VycmVudFJldmlzaW9uKCkpOwoJCUFzc2VydC5hc3NlcnROb3ROdWxsKCJFeHBlY3RlZCB0byBmaW5kIGEgZHluYW1pYyB3aXJlLiIsIGR5bmFtaWNXaXJlKTsKCgkJLy8gcmUtcmVzb2x2ZSBpbXBvcnRlcgoJCWNvbnRhaW5lci5yZWZyZXNoKENvbGxlY3Rpb25zLnNpbmdsZXRvbihvcHRpb25hbEltcG9ydGVyTW9kdWxlKSk7CgoJCXJlcG9ydCA9IGNvbnRhaW5lci5yZXNvbHZlKEFycmF5cy5hc0xpc3Qob3B0aW9uYWxJbXBvcnRlck1vZHVsZSksIHRydWUpOwoJCUFzc2VydC5hc3NlcnROdWxsKCJGYWlsZWQgdG8gcmVzb2x2ZSBzeXN0ZW0uYnVuZGxlLiIsIHJlcG9ydC5nZXRSZXNvbHV0aW9uRXhjZXB0aW9uKCkpOwoKCQlpbXBvcnRSZXFzTGlzdCA9IG9wdGlvbmFsSW1wb3J0ZXJNb2R1bGUuZ2V0Q3VycmVudFJldmlzaW9uKCkuZ2V0V2lyaW5nKCkuZ2V0UmVxdWlyZW1lbnRzKFBhY2thZ2VOYW1lc3BhY2UuUEFDS0FHRV9OQU1FU1BBQ0UpOwoJCWFzc2VydEVxdWFscygiV3JvbmcgbnVtYmVyIG9mIGltcG9ydHMuIiwgMiwgaW1wb3J0UmVxc0xpc3Quc2l6ZSgpKTsKCX0KCglAVGVzdAoJcHVibGljIHZvaWQgdGVzdER5bmFtaWNXaXRoRXhwb3J0KCkgdGhyb3dzIEJ1bmRsZUV4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewoJCUR1bW15Q29udGFpbmVyQWRhcHRvciBhZGFwdG9yID0gY3JlYXRlRHVtbXlBZGFwdG9yKCk7CgkJTW9kdWxlQ29udGFpbmVyIGNvbnRhaW5lciA9IGFkYXB0b3IuZ2V0Q29udGFpbmVyKCk7CgoJCS8vIGluc3RhbGwgdGhlIHN5c3RlbS5idW5kbGUKCQlNb2R1bGUgc3lzdGVtQnVuZGxlID0gaW5zdGFsbER1bW15TW9kdWxlKCJzeXN0ZW0uYnVuZGxlLk1GIiwgQ29uc3RhbnRzLlNZU1RFTV9CVU5ETEVfTE9DQVRJT04sIENvbnN0YW50cy5TWVNURU1fQlVORExFX1NZTUJPTElDTkFNRSwgbnVsbCwgbnVsbCwgY29udGFpbmVyKTsKCQlSZXNvbHV0aW9uUmVwb3J0IHJlcG9ydCA9IGNvbnRhaW5lci5yZXNvbHZlKEFycmF5cy5hc0xpc3Qoc3lzdGVtQnVuZGxlKSwgdHJ1ZSk7CgkJQXNzZXJ0LmFzc2VydE51bGwoIkZhaWxlZCB0byByZXNvbHZlIHN5c3RlbS5idW5kbGUuIiwgcmVwb3J0LmdldFJlc29sdXRpb25FeGNlcHRpb24oKSk7CgoJCS8vIGluc3RhbGwgYW4gaW1wb3J0ZXIKCQlNYXA8U3RyaW5nLCBTdHJpbmc+IG9wdGlvbmFsSW1wb3J0ZXJNYW5pZmVzdCA9IG5ldyBIYXNoTWFwPFN0cmluZywgU3RyaW5nPigpOwoJCW9wdGlvbmFsSW1wb3J0ZXJNYW5pZmVzdC5wdXQoQ29uc3RhbnRzLkJVTkRMRV9NQU5JRkVTVFZFUlNJT04sICIyIik7CgkJb3B0aW9uYWxJbXBvcnRlck1hbmlmZXN0LnB1dChDb25zdGFudHMuQlVORExFX1NZTUJPTElDTkFNRSwgImltcG9ydGVyIik7CgkJb3B0aW9uYWxJbXBvcnRlck1hbmlmZXN0LnB1dChDb25zdGFudHMuRVhQT1JUX1BBQ0tBR0UsICJleHBvcnRlciIpOwoJCW9wdGlvbmFsSW1wb3J0ZXJNYW5pZmVzdC5wdXQoQ29uc3RhbnRzLkRZTkFNSUNJTVBPUlRfUEFDS0FHRSwgImV4cG9ydGVyIik7CgkJTW9kdWxlIG9wdGlvbmFsSW1wb3J0ZXJNb2R1bGUgPSBpbnN0YWxsRHVtbXlNb2R1bGUob3B0aW9uYWxJbXBvcnRlck1hbmlmZXN0LCAib3B0aW9uYWxJbXBvcnRlciIsIGNvbnRhaW5lcik7CgoJCS8vIHVuc2F0aXNmaWVkIG9wdGlvbmFsIGFuZCBkeW5hbWljIGltcG9ydHMgZG8gbm90IGZhaWwgYSByZXNvbHZlLiAKCQlyZXBvcnQgPSBjb250YWluZXIucmVzb2x2ZShBcnJheXMuYXNMaXN0KG9wdGlvbmFsSW1wb3J0ZXJNb2R1bGUpLCB0cnVlKTsKCQlBc3NlcnQuYXNzZXJ0TnVsbCgiRmFpbGVkIHRvIHJlc29sdmUgc3lzdGVtLmJ1bmRsZS4iLCByZXBvcnQuZ2V0UmVzb2x1dGlvbkV4Y2VwdGlvbigpKTsKCgkJLy9keW5hbWljIGFuZCBvcHRpb25hbCBpbXBvcnRzIGFyZSBzYW1lLiBPcHRpb25hbCBpbXBvcnQgaXMgbm90IHNhdGlzZmllZCB3ZSBzaG91bGQgb25seSBzZWUgdGhlIGR5bmFtaWMgaW1wb3J0CgkJTGlzdDxCdW5kbGVSZXF1aXJlbWVudD4gaW1wb3J0UmVxc0xpc3QgPSBvcHRpb25hbEltcG9ydGVyTW9kdWxlLmdldEN1cnJlbnRSZXZpc2lvbigpLmdldFdpcmluZygpLmdldFJlcXVpcmVtZW50cyhQYWNrYWdlTmFtZXNwYWNlLlBBQ0tBR0VfTkFNRVNQQUNFKTsKCQlhc3NlcnRFcXVhbHMoIldyb25nIG51bWJlciBvZiBpbXBvcnRzLiIsIDEsIGltcG9ydFJlcXNMaXN0LnNpemUoKSk7CgkJYXNzZXJ0RXF1YWxzKCJJbXBvcnQgd2FzIG5vdCBkeW5hbWljIiwgUGFja2FnZU5hbWVzcGFjZS5SRVNPTFVUSU9OX0RZTkFNSUMsIGltcG9ydFJlcXNMaXN0LmdldCgwKS5nZXREaXJlY3RpdmVzKCkuZ2V0KE5hbWVzcGFjZS5SRVFVSVJFTUVOVF9SRVNPTFVUSU9OX0RJUkVDVElWRSkpOwoKCQlNb2R1bGVXaXJlIGR5bmFtaWNXaXJlID0gY29udGFpbmVyLnJlc29sdmVEeW5hbWljKCJleHBvcnRlciIsIG9wdGlvbmFsSW1wb3J0ZXJNb2R1bGUuZ2V0Q3VycmVudFJldmlzaW9uKCkpOwoJCUFzc2VydC5hc3NlcnROdWxsKCJFeHBlY3RlZCBubyBkeW5hbWljIHdpcmUuIiwgZHluYW1pY1dpcmUpOwoJfQoKCUBUZXN0CglwdWJsaWMgdm9pZCB0ZXN0U3Vic3RpdHV0YWJsZUV4cG9ydCgpIHRocm93cyBCdW5kbGVFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKCQlEdW1teUNvbnRhaW5lckFkYXB0b3IgYWRhcHRvciA9IGNyZWF0ZUR1bW15QWRhcHRvcigpOwoJCU1vZHVsZUNvbnRhaW5lciBjb250YWluZXIgPSBhZGFwdG9yLmdldENvbnRhaW5lcigpOwoKCQkvLyBpbnN0YWxsIHRoZSBzeXN0ZW0uYnVuZGxlCgkJTW9kdWxlIHN5c3RlbUJ1bmRsZSA9IGluc3RhbGxEdW1teU1vZHVsZSgic3lzdGVtLmJ1bmRsZS5NRiIsIENvbnN0YW50cy5TWVNURU1fQlVORExFX0xPQ0FUSU9OLCBDb25zdGFudHMuU1lTVEVNX0JVTkRMRV9TWU1CT0xJQ05BTUUsIG51bGwsIG51bGwsIGNvbnRhaW5lcik7CgkJUmVzb2x1dGlvblJlcG9ydCByZXBvcnQgPSBjb250YWluZXIucmVzb2x2ZShBcnJheXMuYXNMaXN0KHN5c3RlbUJ1bmRsZSksIHRydWUpOwoJCUFzc2VydC5hc3NlcnROdWxsKCJGYWlsZWQgdG8gcmVzb2x2ZSBzeXN0ZW0uYnVuZGxlLiIsIHJlcG9ydC5nZXRSZXNvbHV0aW9uRXhjZXB0aW9uKCkpOwoKCQkvLyBpbnN0YWxsIGFuIGV4cG9ydGVyIHdpdGggc3Vic3RpdHV0YWJsZSBleHBvcnQuCgkJTWFwPFN0cmluZywgU3RyaW5nPiBleHBvcnRlck1hbmlmZXN0ID0gbmV3IEhhc2hNYXA8U3RyaW5nLCBTdHJpbmc+KCk7CgkJZXhwb3J0ZXJNYW5pZmVzdC5wdXQoQ29uc3RhbnRzLkJVTkRMRV9NQU5JRkVTVFZFUlNJT04sICIyIik7CgkJZXhwb3J0ZXJNYW5pZmVzdC5wdXQoQ29uc3RhbnRzLkJVTkRMRV9TWU1CT0xJQ05BTUUsICJleHBvcnRlciIpOwoJCWV4cG9ydGVyTWFuaWZlc3QucHV0KENvbnN0YW50cy5FWFBPUlRfUEFDS0FHRSwgImV4cG9ydGVyIik7CgkJZXhwb3J0ZXJNYW5pZmVzdC5wdXQoQ29uc3RhbnRzLklNUE9SVF9QQUNLQUdFLCAiZXhwb3J0ZXIiKTsKCQlNb2R1bGUgbW9kdWxlU3Vic0V4cG9ydCA9IGluc3RhbGxEdW1teU1vZHVsZShleHBvcnRlck1hbmlmZXN0LCAiZXhwb3J0ZXIiLCBjb250YWluZXIpOwoJCXJlcG9ydCA9IGNvbnRhaW5lci5yZXNvbHZlKEFycmF5cy5hc0xpc3QobW9kdWxlU3Vic0V4cG9ydCksIHRydWUpOwoJCUFzc2VydC5hc3NlcnROdWxsKCJGYWlsZWQgdG8gcmVzb2x2ZSIsIHJlcG9ydC5nZXRSZXNvbHV0aW9uRXhjZXB0aW9uKCkpOwoJCUxpc3Q8QnVuZGxlUmVxdWlyZW1lbnQ+IHJlcXMgPSBtb2R1bGVTdWJzRXhwb3J0LmdldEN1cnJlbnRSZXZpc2lvbigpLmdldFdpcmluZygpLmdldFJlcXVpcmVtZW50cyhQYWNrYWdlTmFtZXNwYWNlLlBBQ0tBR0VfTkFNRVNQQUNFKTsKCQlhc3NlcnRFcXVhbHMoIldyb25nIG51bWJlciBvZiBpbXBvcnRzLiIsIDAsIHJlcXMuc2l6ZSgpKTsKCgkJY29udGFpbmVyLnVuaW5zdGFsbChtb2R1bGVTdWJzRXhwb3J0KTsKCgkJZXhwb3J0ZXJNYW5pZmVzdCA9IG5ldyBIYXNoTWFwPFN0cmluZywgU3RyaW5nPigpOwoJCWV4cG9ydGVyTWFuaWZlc3QucHV0KENvbnN0YW50cy5CVU5ETEVfTUFOSUZFU1RWRVJTSU9OLCAiMiIpOwoJCWV4cG9ydGVyTWFuaWZlc3QucHV0KENvbnN0YW50cy5CVU5ETEVfU1lNQk9MSUNOQU1FLCAic3Vic3RpdHV0YWJsZUV4cG9ydGVyIik7CgkJZXhwb3J0ZXJNYW5pZmVzdC5wdXQoQ29uc3RhbnRzLkVYUE9SVF9QQUNLQUdFLCAiZXhwb3J0ZXIiKTsKCQlleHBvcnRlck1hbmlmZXN0LnB1dChDb25zdGFudHMuSU1QT1JUX1BBQ0tBR0UsICJleHBvcnRlcjsgcGlja21lPXRydWUiKTsKCgkJbW9kdWxlU3Vic0V4cG9ydCA9IGluc3RhbGxEdW1teU1vZHVsZShleHBvcnRlck1hbmlmZXN0LCAic3Vic3RpdHV0YWJsZUV4cG9ydGVyIiwgY29udGFpbmVyKTsKCgkJZXhwb3J0ZXJNYW5pZmVzdCA9IG5ldyBIYXNoTWFwPFN0cmluZywgU3RyaW5nPigpOwoJCWV4cG9ydGVyTWFuaWZlc3QucHV0KENvbnN0YW50cy5CVU5ETEVfTUFOSUZFU1RWRVJTSU9OLCAiMiIpOwoJCWV4cG9ydGVyTWFuaWZlc3QucHV0KENvbnN0YW50cy5CVU5ETEVfU1lNQk9MSUNOQU1FLCAiZXhwb3J0ZXIiKTsKCQlleHBvcnRlck1hbmlmZXN0LnB1dChDb25zdGFudHMuRVhQT1JUX1BBQ0tBR0UsICJleHBvcnRlcjsgcGlja21lPXRydWUiKTsKCgkJTW9kdWxlIG1vZHVsZUV4cG9ydCA9IGluc3RhbGxEdW1teU1vZHVsZShleHBvcnRlck1hbmlmZXN0LCAiZXhwb3J0ZXIiLCBjb250YWluZXIpOwoJCXJlcG9ydCA9IGNvbnRhaW5lci5yZXNvbHZlKEFycmF5cy5hc0xpc3QobW9kdWxlU3Vic0V4cG9ydC8qICxtb2R1bGVFeHBvcnQgKi8pLCB0cnVlKTsKCQlBc3NlcnQuYXNzZXJ0TnVsbCgiRmFpbGVkIHRvIHJlc29sdmUiLCByZXBvcnQuZ2V0UmVzb2x1dGlvbkV4Y2VwdGlvbigpKTsKCgkJTGlzdDxCdW5kbGVDYXBhYmlsaXR5PiBjYXBzID0gbW9kdWxlU3Vic0V4cG9ydC5nZXRDdXJyZW50UmV2aXNpb24oKS5nZXRXaXJpbmcoKS5nZXRDYXBhYmlsaXRpZXMoUGFja2FnZU5hbWVzcGFjZS5QQUNLQUdFX05BTUVTUEFDRSk7CgkJYXNzZXJ0RXF1YWxzKCJXcm9uZyBudW1iZXIgb2YgY2FwYWJpbGl0aWVzLiIsIDAsIGNhcHMuc2l6ZSgpKTsKCgkJcmVxcyA9IG1vZHVsZVN1YnNFeHBvcnQuZ2V0Q3VycmVudFJldmlzaW9uKCkuZ2V0V2lyaW5nKCkuZ2V0UmVxdWlyZW1lbnRzKFBhY2thZ2VOYW1lc3BhY2UuUEFDS0FHRV9OQU1FU1BBQ0UpOwoJCWFzc2VydEVxdWFscygiV3JvbmcgbnVtYmVyIG9mIGltcG9ydHMuIiwgMSwgcmVxcy5zaXplKCkpOwoKCQlNb2R1bGVXaXJpbmcgd2lyaW5nID0gbW9kdWxlU3Vic0V4cG9ydC5nZXRDdXJyZW50UmV2aXNpb24oKS5nZXRXaXJpbmcoKTsKCQlMaXN0PE1vZHVsZVdpcmU+IHBhY2thZ2VXaXJlcyA9IHdpcmluZy5nZXRSZXF1aXJlZE1vZHVsZVdpcmVzKFBhY2thZ2VOYW1lc3BhY2UuUEFDS0FHRV9OQU1FU1BBQ0UpOwoJCUFzc2VydC5hc3NlcnRFcXVhbHMoIlVuZXhwZWN0ZWQgbnVtYmVyIG9mIHdpcmVzIiwgMSwgcGFja2FnZVdpcmVzLnNpemUoKSk7CgkJQXNzZXJ0LmFzc2VydEVxdWFscygiV3JvbmcgZXhwb3J0ZXIiLCBwYWNrYWdlV2lyZXMuZ2V0KDApLmdldFByb3ZpZGVyV2lyaW5nKCkuZ2V0UmV2aXNpb24oKSwgbW9kdWxlRXhwb3J0LmdldEN1cnJlbnRSZXZpc2lvbigpKTsKCX0KCglAVGVzdAoJcHVibGljIHZvaWQgdGVzdFIzKCkgdGhyb3dzIEJ1bmRsZUV4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewoJCUR1bW15Q29udGFpbmVyQWRhcHRvciBhZGFwdG9yID0gY3JlYXRlRHVtbXlBZGFwdG9yKCk7CgkJTW9kdWxlQ29udGFpbmVyIGNvbnRhaW5lciA9IGFkYXB0b3IuZ2V0Q29udGFpbmVyKCk7CgkJLy8gaW5zdGFsbCB0aGUgc3lzdGVtLmJ1bmRsZQoJCU1vZHVsZSBzeXN0ZW1CdW5kbGUgPSBpbnN0YWxsRHVtbXlNb2R1bGUoInN5c3RlbS5idW5kbGUuTUYiLCBDb25zdGFudHMuU1lTVEVNX0JVTkRMRV9MT0NBVElPTiwgQ29uc3RhbnRzLlNZU1RFTV9CVU5ETEVfU1lNQk9MSUNOQU1FLCBudWxsLCBudWxsLCBjb250YWluZXIpOwoJCVJlc29sdXRpb25SZXBvcnQgcmVwb3J0ID0gY29udGFpbmVyLnJlc29sdmUoQXJyYXlzLmFzTGlzdChzeXN0ZW1CdW5kbGUpLCB0cnVlKTsKCQlBc3NlcnQuYXNzZXJ0TnVsbCgiRmFpbGVkIHRvIHJlc29sdmUgc3lzdGVtLmJ1bmRsZS4iLCByZXBvcnQuZ2V0UmVzb2x1dGlvbkV4Y2VwdGlvbigpKTsKCgkJLy9SMyBidW5kbGUKCQlNYXA8U3RyaW5nLCBTdHJpbmc+IGV4cG9ydGVyTWFuaWZlc3QgPSBuZXcgSGFzaE1hcDxTdHJpbmcsIFN0cmluZz4oKTsKCQlleHBvcnRlck1hbmlmZXN0ID0gbmV3IEhhc2hNYXA8U3RyaW5nLCBTdHJpbmc+KCk7CgkJZXhwb3J0ZXJNYW5pZmVzdC5wdXQoQ29uc3RhbnRzLkJVTkRMRV9TWU1CT0xJQ05BTUUsICJleHBvcnRlciIpOwoJCWV4cG9ydGVyTWFuaWZlc3QucHV0KENvbnN0YW50cy5FWFBPUlRfUEFDS0FHRSwgImV4cG9ydGVyOyB2ZXJzaW9uPVwiMS4xXCIiKTsKCgkJTW9kdWxlIG1vZHVsZUV4cG9ydCA9IGluc3RhbGxEdW1teU1vZHVsZShleHBvcnRlck1hbmlmZXN0LCAiZXhwb3J0ZXIiLCBjb250YWluZXIpOwoJCXJlcG9ydCA9IGNvbnRhaW5lci5yZXNvbHZlKEFycmF5cy5hc0xpc3QobW9kdWxlRXhwb3J0LCBtb2R1bGVFeHBvcnQpLCB0cnVlKTsKCQlBc3NlcnQuYXNzZXJ0TnVsbCgiRmFpbGVkIHRvIHJlc29sdmUiLCByZXBvcnQuZ2V0UmVzb2x1dGlvbkV4Y2VwdGlvbigpKTsKCQlMaXN0PEJ1bmRsZVJlcXVpcmVtZW50PiByZXFzID0gbW9kdWxlRXhwb3J0LmdldEN1cnJlbnRSZXZpc2lvbigpLmdldFdpcmluZygpLmdldFJlcXVpcmVtZW50cyhQYWNrYWdlTmFtZXNwYWNlLlBBQ0tBR0VfTkFNRVNQQUNFKTsKCQlhc3NlcnRFcXVhbHMoIldyb25nIG51bWJlciBvZiBpbXBvcnRzLiIsIDAsIHJlcXMuc2l6ZSgpKTsKCgkJLy9SMyBidW5kbGUKCQlleHBvcnRlck1hbmlmZXN0LmNsZWFyKCk7CgkJZXhwb3J0ZXJNYW5pZmVzdC5wdXQoQ29uc3RhbnRzLkJVTkRMRV9TWU1CT0xJQ05BTUUsICJkeW5hbWljRXhwb3J0ZXIiKTsKCQlleHBvcnRlck1hbmlmZXN0LnB1dChDb25zdGFudHMuRVhQT1JUX1BBQ0tBR0UsICJleHBvcnRlcjsgdmVyc2lvbj1cIjEuMFwiIik7CgkJZXhwb3J0ZXJNYW5pZmVzdC5wdXQoQ29uc3RhbnRzLkRZTkFNSUNJTVBPUlRfUEFDS0FHRSwgImV4cG9ydGVyIik7CgkJTW9kdWxlIG1vZHVsZVdpdGhEeW5FeHBvcnQgPSBpbnN0YWxsRHVtbXlNb2R1bGUoZXhwb3J0ZXJNYW5pZmVzdCwgImR5bmFtaWNFeHBvcnRlciIsIGNvbnRhaW5lcik7CgkJcmVwb3J0ID0gY29udGFpbmVyLnJlc29sdmUoQXJyYXlzLmFzTGlzdChtb2R1bGVXaXRoRHluRXhwb3J0KSwgdHJ1ZSk7CgkJQXNzZXJ0LmFzc2VydE51bGwoIkZhaWxlZCB0byByZXNvbHZlIiwgcmVwb3J0LmdldFJlc29sdXRpb25FeGNlcHRpb24oKSk7CgkJcmVxcyA9IG1vZHVsZVdpdGhEeW5FeHBvcnQuZ2V0Q3VycmVudFJldmlzaW9uKCkuZ2V0V2lyaW5nKCkuZ2V0UmVxdWlyZW1lbnRzKFBhY2thZ2VOYW1lc3BhY2UuUEFDS0FHRV9OQU1FU1BBQ0UpOwoJCWFzc2VydEVxdWFscygiV3JvbmcgbnVtYmVyIG9mIGltcG9ydHMuIiwgMiwgcmVxcy5zaXplKCkpOwoKCQlyZXBvcnQgPSBjb250YWluZXIucmVzb2x2ZShBcnJheXMuYXNMaXN0KG1vZHVsZVdpdGhEeW5FeHBvcnQpLCB0cnVlKTsKCQlBc3NlcnQuYXNzZXJ0TnVsbCgiRmFpbGVkIHRvIHJlc29sdmUiLCByZXBvcnQuZ2V0UmVzb2x1dGlvbkV4Y2VwdGlvbigpKTsKCQlyZXFzID0gbW9kdWxlV2l0aER5bkV4cG9ydC5nZXRDdXJyZW50UmV2aXNpb24oKS5nZXRXaXJpbmcoKS5nZXRSZXF1aXJlbWVudHMoUGFja2FnZU5hbWVzcGFjZS5QQUNLQUdFX05BTUVTUEFDRSk7CgkJYXNzZXJ0RXF1YWxzKCJXcm9uZyBudW1iZXIgb2YgaW1wb3J0cy4iLCAyLCByZXFzLnNpemUoKSk7CgkJTW9kdWxlV2lyaW5nIHdpcmluZyA9IG1vZHVsZVdpdGhEeW5FeHBvcnQuZ2V0Q3VycmVudFJldmlzaW9uKCkuZ2V0V2lyaW5nKCk7CgkJTGlzdDxNb2R1bGVXaXJlPiBwYWNrYWdlV2lyZXMgPSB3aXJpbmcuZ2V0UmVxdWlyZWRNb2R1bGVXaXJlcyhQYWNrYWdlTmFtZXNwYWNlLlBBQ0tBR0VfTkFNRVNQQUNFKTsKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJVbmV4cGVjdGVkIG51bWJlciBvZiB3aXJlcyIsIDEsIHBhY2thZ2VXaXJlcy5zaXplKCkpOwoJCUFzc2VydC5hc3NlcnRFcXVhbHMoIldyb25nIGV4cG9ydGVyIiwgcGFja2FnZVdpcmVzLmdldCgwKS5nZXRQcm92aWRlcldpcmluZygpLmdldFJldmlzaW9uKCksIG1vZHVsZUV4cG9ydC5nZXRDdXJyZW50UmV2aXNpb24oKSk7Cgl9CgoJcHJpdmF0ZSBzdGF0aWMgTWFwPFN0cmluZywgU3RyaW5nPiBnZXRVVEZNYW5pZmVzdChTdHJpbmcgcGFja2FnZU5hbWUpIHRocm93cyBJT0V4Y2VwdGlvbiwgQnVuZGxlRXhjZXB0aW9uIHsKCQkvLyB1c2luZyBtYW5pZmVzdCBjbGFzcyB0byBmb3JjZSBhIHNwbGl0IGxpbmUgcmlnaHQgaW4gdGhlIG1pZGRsZSBvZiBhIGRvdWJsZSBieXRlIFVURi04IGNoYXJhY3RlcgoJCUJ5dGVBcnJheU91dHB1dFN0cmVhbSBvdXQgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CgkJewoJCQlNYW5pZmVzdCBtID0gbmV3IE1hbmlmZXN0KCk7CgkJCUF0dHJpYnV0ZXMgYSA9IG0uZ2V0TWFpbkF0dHJpYnV0ZXMoKTsKCQkJYS5wdXQoTUFOSUZFU1RfVkVSU0lPTiwgIjEuMCIpOwoJCQlhLnB1dFZhbHVlKENvbnN0YW50cy5CVU5ETEVfTUFOSUZFU1RWRVJTSU9OLCAiMiIpOwoJCQlhLnB1dFZhbHVlKENvbnN0YW50cy5CVU5ETEVfU1lNQk9MSUNOQU1FLCBwYWNrYWdlTmFtZSk7CgkJCWEucHV0VmFsdWUoQ29uc3RhbnRzLkVYUE9SVF9QQUNLQUdFLCBwYWNrYWdlTmFtZSk7CgkJCWEucHV0VmFsdWUoQ29uc3RhbnRzLklNUE9SVF9QQUNLQUdFLCBwYWNrYWdlTmFtZSk7CgkJCW0ud3JpdGUob3V0KTsKCQl9CgkJcmV0dXJuIE1hbmlmZXN0RWxlbWVudC5wYXJzZUJ1bmRsZU1hbmlmZXN0KG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShvdXQudG9CeXRlQXJyYXkoKSksIG51bGwpOwoJfQoKCUBUZXN0CglwdWJsaWMgdm9pZCB0ZXN0UGVyc2lzdGVuY2UoKSB0aHJvd3MgQnVuZGxlRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CgkJRHVtbXlDb250YWluZXJBZGFwdG9yIGFkYXB0b3IgPSBjcmVhdGVEdW1teUFkYXB0b3IoKTsKCQlNb2R1bGVDb250YWluZXIgY29udGFpbmVyID0gYWRhcHRvci5nZXRDb250YWluZXIoKTsKCgkJLy8gaW5zdGFsbCB0aGUgc3lzdGVtLmJ1bmRsZQoJCWluc3RhbGxEdW1teU1vZHVsZSgic3lzdGVtLmJ1bmRsZS5NRiIsIENvbnN0YW50cy5TWVNURU1fQlVORExFX0xPQ0FUSU9OLCBDb25zdGFudHMuU1lTVEVNX0JVTkRMRV9TWU1CT0xJQ05BTUUsIG51bGwsIG51bGwsIGNvbnRhaW5lcik7CgoJCU1hcDxTdHJpbmcsIE9iamVjdD4gYXR0cnMgPSBuZXcgSGFzaE1hcDxTdHJpbmcsIE9iamVjdD4oKTsKCQlhdHRycy5wdXQoInN0cmluZyIsICJzVmFsdWUiKTsKCQlhdHRycy5wdXQoInN0cmluZy5saXN0MSIsIEFycmF5cy5hc0xpc3QoInYxIiwgInYyIiwgInYzIikpOwoJCWF0dHJzLnB1dCgic3RyaW5nLmxpc3QyIiwgQXJyYXlzLmFzTGlzdCgidjQiLCAidjUiLCAidjYiKSk7CgkJYXR0cnMucHV0KCJ2ZXJzaW9uIiwgVmVyc2lvbi52YWx1ZU9mKCIxLjEiKSk7CgkJYXR0cnMucHV0KCJ2ZXJzaW9uLmxpc3QiLCBBcnJheXMuYXNMaXN0KFZlcnNpb24udmFsdWVPZigiMS4wIiksIFZlcnNpb24udmFsdWVPZigiMi4wIiksIFZlcnNpb24udmFsdWVPZigiMy4wIikpKTsKCQlhdHRycy5wdXQoImxvbmciLCBMb25nLnZhbHVlT2YoMTIzNDUpKTsKCQlhdHRycy5wdXQoImxvbmcubGlzdCIsIEFycmF5cy5hc0xpc3QoTG9uZy52YWx1ZU9mKDEpLCBMb25nLnZhbHVlT2YoMiksIExvbmcudmFsdWVPZigzKSkpOwoJCWF0dHJzLnB1dCgiZG91YmxlIiwgRG91YmxlLnZhbHVlT2YoMS4yMzQ1KSk7CgkJYXR0cnMucHV0KCJkb3VibGUubGlzdCIsIEFycmF5cy5hc0xpc3QoRG91YmxlLnZhbHVlT2YoMS4xKSwgRG91YmxlLnZhbHVlT2YoMS4yKSwgRG91YmxlLnZhbHVlT2YoMS4zKSkpOwoJCWF0dHJzLnB1dCgidXJpIiwgInNvbWUudXJpIik7CgkJYXR0cnMucHV0KCJzZXQiLCBBcnJheXMuYXNMaXN0KCJzMSIsICJzMiIsICJzMyIpKTsKCgkJLy8gcHJvdmlkZXIgd2l0aCBhbGwgc3VwcG9ydGVkIHR5cGVzCgkJTWFwPFN0cmluZywgU3RyaW5nPiBwcm92aWRlck1hbmlmZXN0ID0gbmV3IEhhc2hNYXA8U3RyaW5nLCBTdHJpbmc+KCk7CgkJcHJvdmlkZXJNYW5pZmVzdC5wdXQoQ29uc3RhbnRzLkJVTkRMRV9NQU5JRkVTVFZFUlNJT04sICIyIik7CgkJcHJvdmlkZXJNYW5pZmVzdC5wdXQoQ29uc3RhbnRzLkJVTkRMRV9TWU1CT0xJQ05BTUUsICJwcm92aWRlciIpOwoJCXByb3ZpZGVyTWFuaWZlc3QucHV0KENvbnN0YW50cy5FWFBPUlRfUEFDS0FHRSwgInByb3ZpZGVyOyB2ZXJzaW9uPTEuMTsgYXR0cjE9YXR0cjE7IGF0dHIyPWF0dHIyOyBkaXIxOj1kaXIxOyBkaXIyOj1kaXIyIik7CgkJcHJvdmlkZXJNYW5pZmVzdC5wdXQoQ29uc3RhbnRzLlBST1ZJREVfQ0FQQUJJTElUWSwgInByb3ZpZGVyLmNhcDsiLy8KCQkJCSsgIiBzdHJpbmc9c1ZhbHVlOyIvLwoJCQkJKyAiIHN0cmluZy5saXN0MTpMaXN0PVwidjEsdjIsdjNcIjsiLy8KCQkJCSsgIiBzdHJpbmcubGlzdDI6TGlzdDxTdHJpbmc+PVwidjQsdjUsdjZcIjsiLy8KCQkJCSsgIiB2ZXJzaW9uOlZlcnNpb249MS4xOyIvLwoJCQkJKyAiIHZlcnNpb24ubGlzdDpMaXN0PFZlcnNpb24+PVwiMS4wLDIuMCwzLjBcIjsiLy8KCQkJCSsgIiBsb25nOkxvbmc9MTIzNDU7Ii8vCgkJCQkrICIgbG9uZy5saXN0Okxpc3Q8TG9uZz49XCIxLDIsM1wiOyIvLwoJCQkJKyAiIGRvdWJsZTpEb3VibGU9MS4yMzQ1OyIvLwoJCQkJKyAiIGRvdWJsZS5saXN0Okxpc3Q8RG91YmxlPj1cIjEuMSwxLjIsMS4zXCI7Ii8vCgkJCQkrICIgdXJpOnVyaT1zb21lLnVyaTsiIC8vCgkJCQkrICIgc2V0OnNldD1cInMxLHMyLHMzXCIiKTsKCQlNb2R1bGUgcHJvdmlkZXJNb2R1bGUgPSBpbnN0YWxsRHVtbXlNb2R1bGUocHJvdmlkZXJNYW5pZmVzdCwgInByb3ZpZGVyIiwgY29udGFpbmVyKTsKCQlNYXA8U3RyaW5nLCBPYmplY3Q+IHByb3ZpZGVyQXR0cnMgPSBwcm92aWRlck1vZHVsZS5nZXRDdXJyZW50UmV2aXNpb24oKS5nZXRDYXBhYmlsaXRpZXMoInByb3ZpZGVyLmNhcCIpLmdldCgwKS5nZXRBdHRyaWJ1dGVzKCk7CgkJYXNzZXJ0RXF1YWxzKCJXcm9uZyBwcm92aWRlciBhdHRycyIsIGF0dHJzLCBwcm92aWRlckF0dHJzKTsKCgkJTWFwPFN0cmluZywgU3RyaW5nPiByZXF1aXJlck1hbmlmZXN0ID0gbmV3IEhhc2hNYXA8U3RyaW5nLCBTdHJpbmc+KCk7CgkJcmVxdWlyZXJNYW5pZmVzdC5wdXQoQ29uc3RhbnRzLkJVTkRMRV9NQU5JRkVTVFZFUlNJT04sICIyIik7CgkJcmVxdWlyZXJNYW5pZmVzdC5wdXQoQ29uc3RhbnRzLkJVTkRMRV9TWU1CT0xJQ05BTUUsICJyZXF1aXJlciIpOwoJCXJlcXVpcmVyTWFuaWZlc3QucHV0KENvbnN0YW50cy5JTVBPUlRfUEFDS0FHRSwgInByb3ZpZGVyOyB2ZXJzaW9uPTEuMTsgYXR0cjE9YXR0cjE7IGF0dHIyPWF0dHIyOyBkaXIxOj1kaXIxOyBkaXIyOj1kaXIyIik7CgkJcmVxdWlyZXJNYW5pZmVzdC5wdXQoQ29uc3RhbnRzLlJFUVVJUkVfQ0FQQUJJTElUWSwgIm9wdGlvbmFsOyIvLwoJCQkJKyAiIHJlc29sdXRpb246PW9wdGlvbmFsOyAiIC8vCgkJCQkrICIgc3RyaW5nPXNWYWx1ZTsiLy8KCQkJCSsgIiBzdHJpbmcubGlzdDE6TGlzdD1cInYxLHYyLHYzXCI7Ii8vCgkJCQkrICIgc3RyaW5nLmxpc3QyOkxpc3Q8U3RyaW5nPj1cInY0LHY1LHY2XCI7Ii8vCgkJCQkrICIgdmVyc2lvbjpWZXJzaW9uPTEuMTsiLy8KCQkJCSsgIiB2ZXJzaW9uLmxpc3Q6TGlzdDxWZXJzaW9uPj1cIjEuMCwyLjAsMy4wXCI7Ii8vCgkJCQkrICIgbG9uZzpMb25nPTEyMzQ1OyIvLwoJCQkJKyAiIGxvbmcubGlzdDpMaXN0PExvbmc+PVwiMSwyLDNcIjsiLy8KCQkJCSsgIiBkb3VibGU6RG91YmxlPTEuMjM0NTsiLy8KCQkJCSsgIiBkb3VibGUubGlzdDpMaXN0PERvdWJsZT49XCIxLjEsMS4yLDEuM1wiOyIvLwoJCQkJKyAiIHVyaTp1cmk9c29tZS51cmk7IiAvLwoJCQkJKyAiIHNldDpzZXQ9XCJzMSxzMixzM1wiLCIgLy8KCQkJCSsgInByb3ZpZGVyLmNhcDsgZmlsdGVyOj1cIihzdHJpbmc9c1ZhbHVlKVwiLCIgLy8KCQkJCSsgInByb3ZpZGVyLmNhcDsgZmlsdGVyOj1cIihzdHJpbmcubGlzdDE9djIpXCIsIiAvLwoJCQkJKyAicHJvdmlkZXIuY2FwOyBmaWx0ZXI6PVwiKHN0cmluZy5saXN0Mj12NSlcIiwiIC8vCgkJCQkrICJwcm92aWRlci5jYXA7IGZpbHRlcjo9XCIoc3RyaW5nLmxpc3QyPXY1KVwiLCIgLy8KCQkJCSsgInByb3ZpZGVyLmNhcDsgZmlsdGVyOj1cIigmKHZlcnNpb24+PTEuMSkodmVyc2lvbjw9MS4xLjEpKVwiLCIgLy8KCQkJCSsgInByb3ZpZGVyLmNhcDsgZmlsdGVyOj1cIigmKHZlcnNpb24ubGlzdD0xKSh2ZXJzaW9uLmxpc3Q9MikpXCIsIiAvLwoJCQkJKyAicHJvdmlkZXIuY2FwOyBmaWx0ZXI6PVwiKGxvbmc+PTEyMzQ0KVwiLCIgLy8KCQkJCSsgInByb3ZpZGVyLmNhcDsgZmlsdGVyOj1cIihsb25nLmxpc3Q9MilcIiwiIC8vCgkJCQkrICJwcm92aWRlci5jYXA7IGZpbHRlcjo9XCIoZG91YmxlPj0xLjIpXCIsIiAvLwoJCQkJKyAicHJvdmlkZXIuY2FwOyBmaWx0ZXI6PVwiKGRvdWJsZS5saXN0PTEuMilcIiwiIC8vCgkJCQkrICJwcm92aWRlci5jYXA7IGZpbHRlcjo9XCIodXJpPXNvbWUudXJpKVwiLCIgLy8KCQkJCSsgInByb3ZpZGVyLmNhcDsgZmlsdGVyOj1cIihzZXQ9czIpXCIiIC8vCgkJCQkrICIiKTsKCQlNb2R1bGUgcmVxdWlyZXJNb2R1bGUgPSBpbnN0YWxsRHVtbXlNb2R1bGUocmVxdWlyZXJNYW5pZmVzdCwgInJlcXVpcmVyIiwgY29udGFpbmVyKTsKCQlNYXA8U3RyaW5nLCBPYmplY3Q+IHJlcXVpcmVyQXR0cnMgPSByZXF1aXJlck1vZHVsZS5nZXRDdXJyZW50UmV2aXNpb24oKS5nZXRSZXF1aXJlbWVudHMoIm9wdGlvbmFsIikuZ2V0KDApLmdldEF0dHJpYnV0ZXMoKTsKCQlhc3NlcnRFcXVhbHMoIldyb25nIHJlcXVpcmVyIGF0dHJzIiwgYXR0cnMsIHJlcXVpcmVyQXR0cnMpOwoJCVJlc29sdXRpb25SZXBvcnQgcmVwb3J0ID0gY29udGFpbmVyLnJlc29sdmUoQ29sbGVjdGlvbnMuc2luZ2xldG9uKHJlcXVpcmVyTW9kdWxlKSwgdHJ1ZSk7CgkJYXNzZXJ0TnVsbCgiRXJyb3IgcmVzb2x2aW5nLiIsIHJlcG9ydC5nZXRSZXNvbHV0aW9uRXhjZXB0aW9uKCkpOwoKCQlCeXRlQXJyYXlPdXRwdXRTdHJlYW0gYnl0ZXMgPSBuZXcgQnl0ZUFycmF5T3V0cHV0U3RyZWFtKCk7CgkJRGF0YU91dHB1dFN0cmVhbSBkYXRhID0gbmV3IERhdGFPdXRwdXRTdHJlYW0oYnl0ZXMpOwoJCWFkYXB0b3IuZ2V0RGF0YWJhc2UoKS5zdG9yZShkYXRhLCB0cnVlKTsKCgkJLy8gcmVsb2FkIGludG8gYSBuZXcgY29udGFpbmVyCgkJYWRhcHRvciA9IGNyZWF0ZUR1bW15QWRhcHRvcigpOwoJCWNvbnRhaW5lciA9IGFkYXB0b3IuZ2V0Q29udGFpbmVyKCk7CgkJYWRhcHRvci5nZXREYXRhYmFzZSgpLmxvYWQobmV3IERhdGFJbnB1dFN0cmVhbShuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oYnl0ZXMudG9CeXRlQXJyYXkoKSkpKTsKCgkJcHJvdmlkZXJNb2R1bGUgPSBjb250YWluZXIuZ2V0TW9kdWxlKCJwcm92aWRlciIpOwoJCXByb3ZpZGVyQXR0cnMgPSBwcm92aWRlck1vZHVsZS5nZXRDdXJyZW50UmV2aXNpb24oKS5nZXRDYXBhYmlsaXRpZXMoInByb3ZpZGVyLmNhcCIpLmdldCgwKS5nZXRBdHRyaWJ1dGVzKCk7CgkJYXNzZXJ0RXF1YWxzKCJXcm9uZyBwcm92aWRlciBhdHRycyIsIGF0dHJzLCBwcm92aWRlckF0dHJzKTsKCQlhc3NlcnROb3ROdWxsKCJObyBwcm92aWRlciBmb3VuZC4iLCBwcm92aWRlck1vZHVsZSk7CgoJCXJlcXVpcmVyTW9kdWxlID0gY29udGFpbmVyLmdldE1vZHVsZSgicmVxdWlyZXIiKTsKCQlhc3NlcnROb3ROdWxsKCJObyByZXF1aXJlciBmb3VuZC4iLCByZXF1aXJlck1vZHVsZSk7CgkJcmVxdWlyZXJBdHRycyA9IHJlcXVpcmVyTW9kdWxlLmdldEN1cnJlbnRSZXZpc2lvbigpLmdldFJlcXVpcmVtZW50cygib3B0aW9uYWwiKS5nZXQoMCkuZ2V0QXR0cmlidXRlcygpOwoJCWFzc2VydEVxdWFscygiV3JvbmcgcmVxdWlyZXIgYXR0cnMiLCBhdHRycywgcmVxdWlyZXJBdHRycyk7Cgl9CgoJQFRlc3QKCXB1YmxpYyB2b2lkIHRlc3RJbnZhbGlkQXR0cmlidXRlcygpIHRocm93cyBJT0V4Y2VwdGlvbiwgQnVuZGxlRXhjZXB0aW9uIHsKCQlEdW1teUNvbnRhaW5lckFkYXB0b3IgYWRhcHRvciA9IGNyZWF0ZUR1bW15QWRhcHRvcigpOwoJCU1vZHVsZUNvbnRhaW5lciBjb250YWluZXIgPSBhZGFwdG9yLmdldENvbnRhaW5lcigpOwoKCQkvLyBpbnN0YWxsIHRoZSBzeXN0ZW0uYnVuZGxlCgkJaW5zdGFsbER1bW15TW9kdWxlKCJzeXN0ZW0uYnVuZGxlLk1GIiwgQ29uc3RhbnRzLlNZU1RFTV9CVU5ETEVfTE9DQVRJT04sIENvbnN0YW50cy5TWVNURU1fQlVORExFX1NZTUJPTElDTkFNRSwgbnVsbCwgbnVsbCwgY29udGFpbmVyKTsKCgkJLy8gcHJvdmlkZXIgd2l0aCBhbGwgc3VwcG9ydGVkIHR5cGVzCgkJTWFwPFN0cmluZywgU3RyaW5nPiBpbnZhbGlkQXR0ck1hbmlmZXN0ID0gbmV3IEhhc2hNYXA8U3RyaW5nLCBTdHJpbmc+KCk7CgkJaW52YWxpZEF0dHJNYW5pZmVzdC5wdXQoQ29uc3RhbnRzLkJVTkRMRV9NQU5JRkVTVFZFUlNJT04sICIyIik7CgkJaW52YWxpZEF0dHJNYW5pZmVzdC5wdXQoQ29uc3RhbnRzLkJVTkRMRV9TWU1CT0xJQ05BTUUsICJpbnZhbGlkIik7CgoJCWludmFsaWRBdHRyTWFuaWZlc3QucHV0KENvbnN0YW50cy5QUk9WSURFX0NBUEFCSUxJVFksICJwcm92aWRlci5jYXA7IGludmFsaWQ6Qm9vbGVhbj10cnVlIik7CgkJY2hlY2tJbnZhbGlkTWFuaWZlc3QoaW52YWxpZEF0dHJNYW5pZmVzdCwgY29udGFpbmVyKTsKCgkJaW52YWxpZEF0dHJNYW5pZmVzdC5wdXQoQ29uc3RhbnRzLlBST1ZJREVfQ0FQQUJJTElUWSwgInByb3ZpZGVyLmNhcDsgaW52YWxpZDpJbnRlZ2VyPTEiKTsKCQljaGVja0ludmFsaWRNYW5pZmVzdChpbnZhbGlkQXR0ck1hbmlmZXN0LCBjb250YWluZXIpOwoKCQlpbnZhbGlkQXR0ck1hbmlmZXN0LnB1dChDb25zdGFudHMuUFJPVklERV9DQVBBQklMSVRZLCAicHJvdmlkZXIuY2FwOyBpbnZhbGlkOkxpc3Q8Qm9vbGVhbj49dHJ1ZSIpOwoJCWNoZWNrSW52YWxpZE1hbmlmZXN0KGludmFsaWRBdHRyTWFuaWZlc3QsIGNvbnRhaW5lcik7CgoJCWludmFsaWRBdHRyTWFuaWZlc3QucHV0KENvbnN0YW50cy5QUk9WSURFX0NBUEFCSUxJVFksICJwcm92aWRlci5jYXA7IGludmFsaWQ6TGlzdDxJbnRlZ2VyPj0xIik7CgkJY2hlY2tJbnZhbGlkTWFuaWZlc3QoaW52YWxpZEF0dHJNYW5pZmVzdCwgY29udGFpbmVyKTsKCX0KCglwcml2YXRlIHZvaWQgY2hlY2tJbnZhbGlkTWFuaWZlc3QoTWFwPFN0cmluZywgU3RyaW5nPiBpbnZhbGlkQXR0ck1hbmlmZXN0LCBNb2R1bGVDb250YWluZXIgY29udGFpbmVyKSB7CgkJdHJ5IHsKCQkJaW5zdGFsbER1bW15TW9kdWxlKGludmFsaWRBdHRyTWFuaWZlc3QsICJpbnZhbGlkIiwgY29udGFpbmVyKTsKCQkJZmFpbCgiRXhwZWN0ZWQgdG8gZ2V0IGEgQnVuZGxlRXhjZXB0aW9uIHdpdGggTUFOSUZFU1RfRVJST1IiKTsKCQl9IGNhdGNoIChCdW5kbGVFeGNlcHRpb24gZSkgewoJCQkvLyBmaW5kIGV4cGVjdGVkIHR5cGUKCQkJYXNzZXJ0RXF1YWxzKCJXcm9uZyB0eXBlLiIsIEJ1bmRsZUV4Y2VwdGlvbi5NQU5JRkVTVF9FUlJPUiwgZS5nZXRUeXBlKCkpOwoJCX0KCX0KCglAVGVzdAoJcHVibGljIHZvaWQgdGVzdFN0b3JlSW52YWxpZEF0dHJpYnV0ZXMoKSB0aHJvd3MgQnVuZGxlRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CgkJRHVtbXlDb250YWluZXJBZGFwdG9yIGFkYXB0b3IgPSBjcmVhdGVEdW1teUFkYXB0b3IoKTsKCQlNb2R1bGVDb250YWluZXIgY29udGFpbmVyID0gYWRhcHRvci5nZXRDb250YWluZXIoKTsKCgkJLy8gaW5zdGFsbCB0aGUgc3lzdGVtLmJ1bmRsZQoJCWluc3RhbGxEdW1teU1vZHVsZSgic3lzdGVtLmJ1bmRsZS5NRiIsIENvbnN0YW50cy5TWVNURU1fQlVORExFX0xPQ0FUSU9OLCBDb25zdGFudHMuU1lTVEVNX0JVTkRMRV9TWU1CT0xJQ05BTUUsIG51bGwsIG51bGwsIGNvbnRhaW5lcik7CgoJCUludGVnZXIgdGVzdEludCA9IEludGVnZXIudmFsdWVPZigxKTsKCQlMaXN0PEludGVnZXI+IHRlc3RJbnRMaXN0ID0gQ29sbGVjdGlvbnMuc2luZ2xldG9uTGlzdCh0ZXN0SW50KTsKCQlNb2R1bGVSZXZpc2lvbkJ1aWxkZXIgYnVpbGRlciA9IG5ldyBNb2R1bGVSZXZpc2lvbkJ1aWxkZXIoKTsKCQlidWlsZGVyLnNldFN5bWJvbGljTmFtZSgiaW52YWxpZC5hdHRyIik7CgkJYnVpbGRlci5zZXRWZXJzaW9uKFZlcnNpb24udmFsdWVPZigiMS4wLjAiKSk7CgkJYnVpbGRlci5hZGRDYXBhYmlsaXR5KCJ0ZXN0IiwgQ29sbGVjdGlvbnMuPFN0cmluZywgU3RyaW5nPiBlbXB0eU1hcCgpLCBDb2xsZWN0aW9ucy5zaW5nbGV0b25NYXAoInRlc3QiLCAoT2JqZWN0KSB0ZXN0SW50KSk7CgkJYnVpbGRlci5hZGRDYXBhYmlsaXR5KCJ0ZXN0Lmxpc3QiLCBDb2xsZWN0aW9ucy48U3RyaW5nLCBTdHJpbmc+IGVtcHR5TWFwKCksIENvbGxlY3Rpb25zLnNpbmdsZXRvbk1hcCgidGVzdC5saXN0IiwgKE9iamVjdCkgdGVzdEludExpc3QpKTsKCQlNb2R1bGUgaW52YWxpZCA9IGNvbnRhaW5lci5pbnN0YWxsKG51bGwsIGJ1aWxkZXIuZ2V0U3ltYm9saWNOYW1lKCksIGJ1aWxkZXIsIG51bGwpOwoKCQlPYmplY3QgdGVzdEF0dHIgPSBpbnZhbGlkLmdldEN1cnJlbnRSZXZpc2lvbigpLmdldENhcGFiaWxpdGllcygidGVzdCIpLmdldCgwKS5nZXRBdHRyaWJ1dGVzKCkuZ2V0KCJ0ZXN0Iik7CgkJYXNzZXJ0RXF1YWxzKCJXcm9uZyB0ZXN0IGF0dHIiLCB0ZXN0SW50LCB0ZXN0QXR0cik7CgoJCU9iamVjdCB0ZXN0QXR0ckxpc3QgPSBpbnZhbGlkLmdldEN1cnJlbnRSZXZpc2lvbigpLmdldENhcGFiaWxpdGllcygidGVzdC5saXN0IikuZ2V0KDApLmdldEF0dHJpYnV0ZXMoKS5nZXQoInRlc3QubGlzdCIpOwoJCWFzc2VydEVxdWFscygiV3JvbmcgdGVzdCBsaXN0IGF0dHIiLCB0ZXN0SW50TGlzdCwgdGVzdEF0dHJMaXN0KTsKCgkJQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGJ5dGVzID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOwoJCURhdGFPdXRwdXRTdHJlYW0gZGF0YSA9IG5ldyBEYXRhT3V0cHV0U3RyZWFtKGJ5dGVzKTsKCQlhZGFwdG9yLmdldERhdGFiYXNlKCkuc3RvcmUoZGF0YSwgdHJ1ZSk7CgoJCUxpc3Q8RHVtbXlDb250YWluZXJFdmVudD4gZXZlbnRzID0gYWRhcHRvci5nZXREYXRhYmFzZSgpLmdldENvbnRhaW5lckV2ZW50cygpOwoJCS8vIG1ha2Ugc3VyZSB3ZSBzZWUgdGhlIGVycm9ycwoJCWFzc2VydEVxdWFscygiV3JvbmcgbnVtYmVyIG9mIGV2ZW50cy4iLCAyLCBldmVudHMuc2l6ZSgpKTsKCQlmb3IgKER1bW15Q29udGFpbmVyRXZlbnQgZXZlbnQgOiBldmVudHMpIHsKCQkJYXNzZXJ0RXF1YWxzKCJXcm9uZyB0eXBlIG9mIGV2ZW50LiIsIENvbnRhaW5lckV2ZW50LkVSUk9SLCBldmVudC50eXBlKTsKCQkJYXNzZXJ0VHJ1ZSgiV3JvbmcgdHlwZSBvZiBleGNlcHRpb24uIiwgZXZlbnQuZXJyb3IgaW5zdGFuY2VvZiBCdW5kbGVFeGNlcHRpb24pOwoJCX0KCgkJLy8gcmVsb2FkIGludG8gYSBuZXcgY29udGFpbmVyCgkJYWRhcHRvciA9IGNyZWF0ZUR1bW15QWRhcHRvcigpOwoJCWNvbnRhaW5lciA9IGFkYXB0b3IuZ2V0Q29udGFpbmVyKCk7CgkJYWRhcHRvci5nZXREYXRhYmFzZSgpLmxvYWQobmV3IERhdGFJbnB1dFN0cmVhbShuZXcgQnl0ZUFycmF5SW5wdXRTdHJlYW0oYnl0ZXMudG9CeXRlQXJyYXkoKSkpKTsKCgkJaW52YWxpZCA9IGNvbnRhaW5lci5nZXRNb2R1bGUoImludmFsaWQuYXR0ciIpOwoJCWFzc2VydE5vdE51bGwoIkNvdWxkIG5vdCBmaW5kIG1vZHVsZS4iLCBpbnZhbGlkKTsKCgkJU3RyaW5nIHRlc3RJbnRTdHJpbmcgPSBTdHJpbmcudmFsdWVPZih0ZXN0SW50KTsKCQlMaXN0PFN0cmluZz4gdGVzdEludFN0cmluZ0xpc3QgPSBDb2xsZWN0aW9ucy5zaW5nbGV0b25MaXN0KHRlc3RJbnRTdHJpbmcpOwoJCXRlc3RBdHRyID0gaW52YWxpZC5nZXRDdXJyZW50UmV2aXNpb24oKS5nZXRDYXBhYmlsaXRpZXMoInRlc3QiKS5nZXQoMCkuZ2V0QXR0cmlidXRlcygpLmdldCgidGVzdCIpOwoJCWFzc2VydEVxdWFscygiV3JvbmcgdGVzdCBhdHRyIiwgdGVzdEludFN0cmluZywgdGVzdEF0dHIpOwoKCQl0ZXN0QXR0ckxpc3QgPSBpbnZhbGlkLmdldEN1cnJlbnRSZXZpc2lvbigpLmdldENhcGFiaWxpdGllcygidGVzdC5saXN0IikuZ2V0KDApLmdldEF0dHJpYnV0ZXMoKS5nZXQoInRlc3QubGlzdCIpOwoJCWFzc2VydEVxdWFscygiV3JvbmcgdGVzdCBsaXN0IGF0dHIiLCB0ZXN0SW50U3RyaW5nTGlzdCwgdGVzdEF0dHJMaXN0KTsKCX0KCglAVGVzdAoJcHVibGljIHZvaWQgdGVzdEJ1ZzQ4Mzg0OSgpIHRocm93cyBCdW5kbGVFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKCQlEdW1teUNvbnRhaW5lckFkYXB0b3IgYWRhcHRvciA9IGNyZWF0ZUR1bW15QWRhcHRvcigpOwoJCU1vZHVsZUNvbnRhaW5lciBjb250YWluZXIgPSBhZGFwdG9yLmdldENvbnRhaW5lcigpOwoKCQkvLyBpbnN0YWxsIGFuZCByZXNvbHZlIGhvc3QgYnVuZGxlCgkJTW9kdWxlIGhvc3QgPSBpbnN0YWxsRHVtbXlNb2R1bGUoImJ1ZzQ4Mzg0OS5ob3N0Lk1GIiwgImhvc3QiLCBjb250YWluZXIpOwoJCVJlc29sdXRpb25SZXBvcnQgcmVwb3J0ID0gY29udGFpbmVyLnJlc29sdmUoQXJyYXlzLmFzTGlzdChob3N0KSwgdHJ1ZSk7CgkJQXNzZXJ0LmFzc2VydE51bGwoIkZhaWxlZCB0byByZXNvbHZlIGhvc3QuIiwgcmVwb3J0LmdldFJlc29sdXRpb25FeGNlcHRpb24oKSk7CgoJCS8vIGluc3RhbGwgYW5kIGR5bmFtaWNhbGx5IGF0dGFjaCBhIGZyYWdtZW50IHRoYXQgZXhwb3J0cyBhIHBhY2thZ2UgYW5kIHJlc29sdmUgYW4gaW1wb3J0ZXIKCQlNb2R1bGUgZnJhZyA9IGluc3RhbGxEdW1teU1vZHVsZSgiYnVnNDgzODQ5LmZyYWcuTUYiLCAiZnJhZyIsIGNvbnRhaW5lcik7CgkJTW9kdWxlIGltcG9ydGVyID0gaW5zdGFsbER1bW15TW9kdWxlKCJidWc0ODM4NDkuaW1wb3J0ZXIuTUYiLCAiaW1wb3J0ZXIiLCBjb250YWluZXIpOwoJCXJlcG9ydCA9IGNvbnRhaW5lci5yZXNvbHZlKEFycmF5cy5hc0xpc3QoZnJhZywgaW1wb3J0ZXIpLCB0cnVlKTsKCQlBc3NlcnQuYXNzZXJ0TnVsbCgiRmFpbGVkIHRvIHJlc29sdmUgdGVzdCBmcmFnbWVudCBhbmQgaW1wb3J0ZXIuIiwgcmVwb3J0LmdldFJlc29sdXRpb25FeGNlcHRpb24oKSk7CgkJLy8gZ2V0IHRoZSBjb3VudCBvZiBwYWNrYWdlIGV4cG9ydHMKCQlNb2R1bGVXaXJpbmcgd2lyaW5nID0gaG9zdC5nZXRDdXJyZW50UmV2aXNpb24oKS5nZXRXaXJpbmcoKTsKCQlpbnQgb3JpZ2luYWxQYWNrYWdlQ250ID0gd2lyaW5nLmdldENhcGFiaWxpdGllcyhQYWNrYWdlTmFtZXNwYWNlLlBBQ0tBR0VfTkFNRVNQQUNFKS5zaXplKCk7CgoJCS8vIHVwZGF0ZSB0aGUgaG9zdCB0byBnZW5lcmF0ZSBhIG5ldyByZXZpc2lvbgoJCU1hcDxTdHJpbmcsIFN0cmluZz4gdXBkYXRlTWFuaWZlc3QgPSBnZXRNYW5pZmVzdCgiYnVnNDgzODQ5Lmhvc3QuTUYiKTsKCQlNb2R1bGVSZXZpc2lvbkJ1aWxkZXIgdXBkYXRlQnVpbGRlciA9IE9TR2lNYW5pZmVzdEJ1aWxkZXJGYWN0b3J5LmNyZWF0ZUJ1aWxkZXIodXBkYXRlTWFuaWZlc3QpOwoJCWNvbnRhaW5lci51cGRhdGUoaG9zdCwgdXBkYXRlQnVpbGRlciwgbnVsbCk7CgkJLy8gcmVmcmVzaCBob3N0IHdoaWNoIHNob3VsZCBmb3JjZSB0aGUgaW1wb3J0ZXIgdG8gcmUtcmVzb2x2ZSB0byB0aGUgbmV3IHJldmlzaW9uCgkJcmVwb3J0ID0gY29udGFpbmVyLnJlZnJlc2goQ29sbGVjdGlvbnMuc2luZ2xldG9uKGhvc3QpKTsKCgkJTW9kdWxlV2lyaW5nIGltcG9ydGVyV2lyaW5nID0gaW1wb3J0ZXIuZ2V0Q3VycmVudFJldmlzaW9uKCkuZ2V0V2lyaW5nKCk7CgkJQXNzZXJ0LmFzc2VydE5vdE51bGwoIk5vIHdpcmluZyBmb3IgaW1wb3J0ZXIuIiwgaW1wb3J0ZXJXaXJpbmcpOwoJCUxpc3Q8TW9kdWxlV2lyZT4gaW1wb3J0ZXJQYWNrYWdlV2lyZXMgPSBpbXBvcnRlcldpcmluZy5nZXRSZXF1aXJlZE1vZHVsZVdpcmVzKFBhY2thZ2VOYW1lc3BhY2UuUEFDS0FHRV9OQU1FU1BBQ0UpOwoJCUFzc2VydC5hc3NlcnRFcXVhbHMoIldyb25nIG51bWJlciBvZiBpbXBvcnRlciBwYWNrYWdlIFdpcmVzLiIsIDEsIGltcG9ydGVyUGFja2FnZVdpcmVzLnNpemUoKSk7CgoJCUFzc2VydC5hc3NlcnRFcXVhbHMoIldyb25nIHByb3ZpZGVyIHdpcmluZy4iLCBob3N0LmdldEN1cnJlbnRSZXZpc2lvbigpLmdldFdpcmluZygpLCBpbXBvcnRlclBhY2thZ2VXaXJlcy5pdGVyYXRvcigpLm5leHQoKS5nZXRQcm92aWRlcldpcmluZygpKTsKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJXcm9uZyBwcm92aWRlciByZXZpc2lvbi4iLCBob3N0LmdldEN1cnJlbnRSZXZpc2lvbigpLCBpbXBvcnRlclBhY2thZ2VXaXJlcy5pdGVyYXRvcigpLm5leHQoKS5nZXRQcm92aWRlcldpcmluZygpLmdldFJldmlzaW9uKCkpOwoKCQl3aXJpbmcgPSBob3N0LmdldEN1cnJlbnRSZXZpc2lvbigpLmdldFdpcmluZygpOwoJCUxpc3Q8QnVuZGxlQ2FwYWJpbGl0eT4gcGFja2FnZXMgPSB3aXJpbmcuZ2V0Q2FwYWJpbGl0aWVzKFBhY2thZ2VOYW1lc3BhY2UuUEFDS0FHRV9OQU1FU1BBQ0UpOwoJCUFzc2VydC5hc3NlcnRFcXVhbHMoIldyb25nIG51bWJlciBvZiBob3N0IHBhY2thZ2VzLiIsIG9yaWdpbmFsUGFja2FnZUNudCwgcGFja2FnZXMuc2l6ZSgpKTsKCX0KCglAVGVzdAoJcHVibGljIHZvaWQgdGVzdFN0YXJ0TGV2ZWxEZWFkbG9jaygpIHRocm93cyBCdW5kbGVFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKCQlEdW1teUNvbnRhaW5lckFkYXB0b3IgYWRhcHRvciA9IGNyZWF0ZUR1bW15QWRhcHRvcigpOwoJCU1vZHVsZUNvbnRhaW5lciBjb250YWluZXIgPSBhZGFwdG9yLmdldENvbnRhaW5lcigpOwoJCWNvbnRhaW5lci5nZXRGcmFtZXdvcmtTdGFydExldmVsKCkuc2V0SW5pdGlhbEJ1bmRsZVN0YXJ0TGV2ZWwoMik7CgoJCS8vIGluc3RhbGwgdGhlIHN5c3RlbS5idW5kbGUKCQlNb2R1bGUgc3lzdGVtQnVuZGxlID0gaW5zdGFsbER1bW15TW9kdWxlKCJzeXN0ZW0uYnVuZGxlLk1GIiwgQ29uc3RhbnRzLlNZU1RFTV9CVU5ETEVfTE9DQVRJT04sIENvbnN0YW50cy5TWVNURU1fQlVORExFX1NZTUJPTElDTkFNRSwgbnVsbCwgbnVsbCwgY29udGFpbmVyKTsKCQlSZXNvbHV0aW9uUmVwb3J0IHJlcG9ydCA9IGNvbnRhaW5lci5yZXNvbHZlKEFycmF5cy5hc0xpc3Qoc3lzdGVtQnVuZGxlKSwgdHJ1ZSk7CgkJQXNzZXJ0LmFzc2VydE51bGwoIkZhaWxlZCB0byByZXNvbHZlIHN5c3RlbS5idW5kbGUuIiwgcmVwb3J0LmdldFJlc29sdXRpb25FeGNlcHRpb24oKSk7CgkJc3lzdGVtQnVuZGxlLnN0YXJ0KCk7CgoJCS8vIGluc3RhbGwgYSBtb2R1bGUKCQlNYXA8U3RyaW5nLCBTdHJpbmc+IG1hbmlmZXN0ID0gbmV3IEhhc2hNYXA8U3RyaW5nLCBTdHJpbmc+KCk7CgkJbWFuaWZlc3QucHV0KENvbnN0YW50cy5CVU5ETEVfTUFOSUZFU1RWRVJTSU9OLCAiMiIpOwoJCW1hbmlmZXN0LnB1dChDb25zdGFudHMuQlVORExFX1NZTUJPTElDTkFNRSwgIm1vZHVsZS50ZXN0Iik7CgkJTW9kdWxlIG1vZHVsZSA9IGluc3RhbGxEdW1teU1vZHVsZShtYW5pZmVzdCwgbWFuaWZlc3QuZ2V0KENvbnN0YW50cy5CVU5ETEVfU1lNQk9MSUNOQU1FKSwgY29udGFpbmVyKTsKCQlhZGFwdG9yLnNldFNsb3dkb3duRXZlbnRzKHRydWUpOwoJCW1vZHVsZS5zZXRTdGFydExldmVsKDEpOwoJCW1vZHVsZS5zdGFydCgpOwoKCQlMaXN0PER1bW15Q29udGFpbmVyRXZlbnQ+IGV2ZW50cyA9IGFkYXB0b3IuZ2V0RGF0YWJhc2UoKS5nZXRDb250YWluZXJFdmVudHMoKTsKCQlmb3IgKER1bW15Q29udGFpbmVyRXZlbnQgZXZlbnQgOiBldmVudHMpIHsKCQkJQXNzZXJ0LmFzc2VydE5vdEVxdWFscygiRm91bmQgYW4gZXJyb3I6ICIgKyBldmVudC5lcnJvciwgQ29udGFpbmVyRXZlbnQuRVJST1IsIGV2ZW50LnR5cGUpOwoJCX0KCX0KCglAVGVzdAoJcHVibGljIHZvaWQgdGVzdFN5c3RlbUJ1bmRsZU9uRGVtYW5kRnJhZ21lbnRzKCkgdGhyb3dzIEJ1bmRsZUV4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewoJCUR1bW15Q29udGFpbmVyQWRhcHRvciBhZGFwdG9yID0gY3JlYXRlRHVtbXlBZGFwdG9yKCk7CgkJTW9kdWxlQ29udGFpbmVyIGNvbnRhaW5lciA9IGFkYXB0b3IuZ2V0Q29udGFpbmVyKCk7CgoJCS8vIGluc3RhbGwgdGhlIHN5c3RlbS5idW5kbGUKCQlNb2R1bGUgc3lzdGVtQnVuZGxlID0gaW5zdGFsbER1bW15TW9kdWxlKCJzeXN0ZW0uYnVuZGxlLk1GIiwgQ29uc3RhbnRzLlNZU1RFTV9CVU5ETEVfTE9DQVRJT04sIENvbnN0YW50cy5TWVNURU1fQlVORExFX1NZTUJPTElDTkFNRSwgbnVsbCwgbnVsbCwgY29udGFpbmVyKTsKCgkJLy8gaW5zdGFsbCBhbiBlcXVpbm94IGZyYWdtZW50CgkJTWFwPFN0cmluZywgU3RyaW5nPiBlcXVpbm94RnJhZ01hbmlmZXN0ID0gbmV3IEhhc2hNYXA8U3RyaW5nLCBTdHJpbmc+KCk7CgkJZXF1aW5veEZyYWdNYW5pZmVzdC5wdXQoQ29uc3RhbnRzLkJVTkRMRV9NQU5JRkVTVFZFUlNJT04sICIyIik7CgkJZXF1aW5veEZyYWdNYW5pZmVzdC5wdXQoQ29uc3RhbnRzLkJVTkRMRV9TWU1CT0xJQ05BTUUsICJlcXVpbm94RnJhZyIpOwoJCWVxdWlub3hGcmFnTWFuaWZlc3QucHV0KENvbnN0YW50cy5GUkFHTUVOVF9IT1NULCAib3JnLmVjbGlwc2Uub3NnaSIpOwoJCU1vZHVsZSBlcXVpbm94RnJhZyA9IGluc3RhbGxEdW1teU1vZHVsZShlcXVpbm94RnJhZ01hbmlmZXN0LCAiZXF1aW5veEZyYWciLCBjb250YWluZXIpOwoKCQkvLyBpbnN0YWxsIGEgc3lzdGVtLmJ1bmRsZSBmcmFnbWVudAoJCU1hcDxTdHJpbmcsIFN0cmluZz4gc3lzdGVtRnJhZ01hbmlmZXN0ID0gbmV3IEhhc2hNYXA8U3RyaW5nLCBTdHJpbmc+KCk7CgkJc3lzdGVtRnJhZ01hbmlmZXN0LnB1dChDb25zdGFudHMuQlVORExFX01BTklGRVNUVkVSU0lPTiwgIjIiKTsKCQlzeXN0ZW1GcmFnTWFuaWZlc3QucHV0KENvbnN0YW50cy5CVU5ETEVfU1lNQk9MSUNOQU1FLCAic3lzdGVtRnJhZyIpOwoJCXN5c3RlbUZyYWdNYW5pZmVzdC5wdXQoQ29uc3RhbnRzLkZSQUdNRU5UX0hPU1QsICJzeXN0ZW0uYnVuZGxlIik7CgkJTW9kdWxlIHN5c3RlbUZyYWcgPSBpbnN0YWxsRHVtbXlNb2R1bGUoc3lzdGVtRnJhZ01hbmlmZXN0LCAic3lzdGVtRnJhZyIsIGNvbnRhaW5lcik7CgoJCVJlc29sdXRpb25SZXBvcnQgcmVwb3J0ID0gY29udGFpbmVyLnJlc29sdmUoQXJyYXlzLmFzTGlzdChzeXN0ZW1CdW5kbGUpLCB0cnVlKTsKCQlBc3NlcnQuYXNzZXJ0TnVsbCgiRmFpbGVkIHRvIHJlc29sdmUgc3lzdGVtLmJ1bmRsZS4iLCByZXBvcnQuZ2V0UmVzb2x1dGlvbkV4Y2VwdGlvbigpKTsKCgkJTGlzdDxNb2R1bGVXaXJlPiBob3N0V2lyZXMgPSBzeXN0ZW1CdW5kbGUuZ2V0Q3VycmVudFJldmlzaW9uKCkuZ2V0V2lyaW5nKCkuZ2V0UHJvdmlkZWRNb2R1bGVXaXJlcyhIb3N0TmFtZXNwYWNlLkhPU1RfTkFNRVNQQUNFKTsKCQlhc3NlcnRFcXVhbHMoIldyb25nIG51bWJlciBvZiBmcmFnbWVudHMuIiwgMiwgaG9zdFdpcmVzLnNpemUoKSk7CgkJU2V0PE1vZHVsZVJldmlzaW9uPiBmcmFnbWVudFJldmlzaW9ucyA9IG5ldyBIYXNoU2V0KEFycmF5cy5hc0xpc3QoZXF1aW5veEZyYWcuZ2V0Q3VycmVudFJldmlzaW9uKCksIHN5c3RlbUZyYWcuZ2V0Q3VycmVudFJldmlzaW9uKCkpKTsKCQlmb3IgKE1vZHVsZVdpcmUgaG9zdFdpcmUgOiBob3N0V2lyZXMpIHsKCQkJaWYgKCFmcmFnbWVudFJldmlzaW9ucy5yZW1vdmUoaG9zdFdpcmUuZ2V0UmVxdWlyZXIoKSkpIHsKCQkJCUFzc2VydC5mYWlsKCJVbmV4cGVjdGVkIGZyYWdtZW50IHJldmlzaW9uOiAiICsgaG9zdFdpcmUuZ2V0UmVxdWlyZXIoKSk7CgkJCX0KCQl9Cgl9CgoJQFRlc3QKCXB1YmxpYyB2b2lkIHRlc3RVbnJlc29sdmVkSG9zdFdpdGhGcmFnbWVudEN5Y2xlKCkgdGhyb3dzIEJ1bmRsZUV4Y2VwdGlvbiB7CgkJRHVtbXlDb250YWluZXJBZGFwdG9yIGFkYXB0b3IgPSBjcmVhdGVEdW1teUFkYXB0b3IoKTsKCQlNb2R1bGVDb250YWluZXIgY29udGFpbmVyID0gYWRhcHRvci5nZXRDb250YWluZXIoKTsKCgkJLy8gaW5zdGFsbCBhIGhvc3QKCQlNYXA8U3RyaW5nLCBTdHJpbmc+IGhvc3RNYW5pZmVzdCA9IG5ldyBIYXNoTWFwPFN0cmluZywgU3RyaW5nPigpOwoJCWhvc3RNYW5pZmVzdC5wdXQoQ29uc3RhbnRzLkJVTkRMRV9NQU5JRkVTVFZFUlNJT04sICIyIik7CgkJaG9zdE1hbmlmZXN0LnB1dChDb25zdGFudHMuQlVORExFX1NZTUJPTElDTkFNRSwgImhvc3QiKTsKCQlob3N0TWFuaWZlc3QucHV0KENvbnN0YW50cy5CVU5ETEVfVkVSU0lPTiwgIjEuMCIpOwoJCWhvc3RNYW5pZmVzdC5wdXQoQ29uc3RhbnRzLkVYUE9SVF9QQUNLQUdFLCAiaG9zdCIpOwoJCWhvc3RNYW5pZmVzdC5wdXQoQ29uc3RhbnRzLklNUE9SVF9QQUNLQUdFLCAiaG9zdC5pbXBsIik7CgkJaW5zdGFsbER1bW15TW9kdWxlKGhvc3RNYW5pZmVzdCwgImhvc3QxMCIsIGNvbnRhaW5lcik7CgkJaG9zdE1hbmlmZXN0LnB1dChDb25zdGFudHMuQlVORExFX1ZFUlNJT04sICIxLjEiKTsKCQlpbnN0YWxsRHVtbXlNb2R1bGUoaG9zdE1hbmlmZXN0LCAiaG9zdDExIiwgY29udGFpbmVyKTsKCQlob3N0TWFuaWZlc3QucHV0KENvbnN0YW50cy5CVU5ETEVfVkVSU0lPTiwgIjEuMiIpOwoJCWluc3RhbGxEdW1teU1vZHVsZShob3N0TWFuaWZlc3QsICJob3N0MTIiLCBjb250YWluZXIpOwoJCS8vaG9zdE1hbmlmZXN0LnB1dChDb25zdGFudHMuQlVORExFX1ZFUlNJT04sICIxLjMiKTsKCQkvL2luc3RhbGxEdW1teU1vZHVsZShob3N0TWFuaWZlc3QsICJob3N0MTMiLCBjb250YWluZXIpOwoKCQkvLyBpbnN0YWxsIGEgaG9zdC5pbXBsIGZyYWdtZW50CgkJTWFwPFN0cmluZywgU3RyaW5nPiBob3N0SW1wbE1hbmlmZXN0ID0gbmV3IEhhc2hNYXA8U3RyaW5nLCBTdHJpbmc+KCk7CgkJaG9zdEltcGxNYW5pZmVzdC5wdXQoQ29uc3RhbnRzLkJVTkRMRV9NQU5JRkVTVFZFUlNJT04sICIyIik7CgkJaG9zdEltcGxNYW5pZmVzdC5wdXQoQ29uc3RhbnRzLkJVTkRMRV9TWU1CT0xJQ05BTUUsICJob3N0LmltcGwiKTsKCQlob3N0SW1wbE1hbmlmZXN0LnB1dChDb25zdGFudHMuRVhQT1JUX1BBQ0tBR0UsICJob3N0LmltcGwiKTsKCQlob3N0SW1wbE1hbmlmZXN0LnB1dChDb25zdGFudHMuSU1QT1JUX1BBQ0tBR0UsICJob3N0Iik7CgkJaG9zdEltcGxNYW5pZmVzdC5wdXQoQ29uc3RhbnRzLkZSQUdNRU5UX0hPU1QsICJob3N0Iik7CgkJaW5zdGFsbER1bW15TW9kdWxlKGhvc3RJbXBsTWFuaWZlc3QsICJob3N0SW1wbCIsIGNvbnRhaW5lcik7CgoJCS8vIGluc3RhbGwgYW4gaW1wb3J0ZXIgb2YgaG9zdCBwYWNrYWdlCgkJTWFwPFN0cmluZywgU3RyaW5nPiBob3N0SW1wb3J0ZXJNYW5pZmVzdCA9IG5ldyBIYXNoTWFwPFN0cmluZywgU3RyaW5nPigpOwoJCWhvc3RJbXBvcnRlck1hbmlmZXN0LnB1dChDb25zdGFudHMuQlVORExFX01BTklGRVNUVkVSU0lPTiwgIjIiKTsKCQlob3N0SW1wb3J0ZXJNYW5pZmVzdC5wdXQoQ29uc3RhbnRzLkJVTkRMRV9TWU1CT0xJQ05BTUUsICJob3N0LmltcG9ydGVyIik7CgkJaG9zdEltcG9ydGVyTWFuaWZlc3QucHV0KENvbnN0YW50cy5JTVBPUlRfUEFDS0FHRSwgImhvc3QiKTsKCQlNb2R1bGUgaG9zdEltcG9ydGVyID0gaW5zdGFsbER1bW15TW9kdWxlKGhvc3RJbXBvcnRlck1hbmlmZXN0LCAiaG9zdEltcG9ydGVyIiwgY29udGFpbmVyKTsKCgkJUmVzb2x1dGlvblJlcG9ydCByZXBvcnQgPSBjb250YWluZXIucmVzb2x2ZShBcnJheXMuYXNMaXN0KGhvc3RJbXBvcnRlciksIHRydWUpOwoJCUFzc2VydC5hc3NlcnROdWxsKCJGYWlsZWQgdG8gcmVzb2x2ZSB0ZXN0LiIsIHJlcG9ydC5nZXRSZXNvbHV0aW9uRXhjZXB0aW9uKCkpOwoJfQoKCUBUZXN0CglwdWJsaWMgdm9pZCB0ZXN0TW9kdWxlV2lyaW5nVG9TdHJpbmcoKSB0aHJvd3MgQnVuZGxlRXhjZXB0aW9uIHsKCQlEdW1teUNvbnRhaW5lckFkYXB0b3IgYWRhcHRvciA9IGNyZWF0ZUR1bW15QWRhcHRvcigpOwoJCU1vZHVsZUNvbnRhaW5lciBjb250YWluZXIgPSBhZGFwdG9yLmdldENvbnRhaW5lcigpOwoKCQkvLyBpbnN0YWxsIGEgdGVzdCBtb2R1bGUKCQlNYXA8U3RyaW5nLCBTdHJpbmc+IHRlc3RNYW5pZmVzdCA9IG5ldyBIYXNoTWFwPFN0cmluZywgU3RyaW5nPigpOwoJCXRlc3RNYW5pZmVzdC5wdXQoQ29uc3RhbnRzLkJVTkRMRV9NQU5JRkVTVFZFUlNJT04sICIyIik7CgkJdGVzdE1hbmlmZXN0LnB1dChDb25zdGFudHMuQlVORExFX1NZTUJPTElDTkFNRSwgInRlc3QubmFtZSIpOwoJCXRlc3RNYW5pZmVzdC5wdXQoQ29uc3RhbnRzLkJVTkRMRV9WRVJTSU9OLCAiMS4wIik7CgkJTW9kdWxlIHRlc3RNb2R1bGUgPSBpbnN0YWxsRHVtbXlNb2R1bGUodGVzdE1hbmlmZXN0LCAiaG9zdDEwIiwgY29udGFpbmVyKTsKCgkJUmVzb2x1dGlvblJlcG9ydCByZXBvcnQgPSBjb250YWluZXIucmVzb2x2ZShBcnJheXMuYXNMaXN0KHRlc3RNb2R1bGUpLCB0cnVlKTsKCQlBc3NlcnQuYXNzZXJ0TnVsbCgiRmFpbGVkIHRvIHJlc29sdmUgdGVzdC4iLCByZXBvcnQuZ2V0UmVzb2x1dGlvbkV4Y2VwdGlvbigpKTsKCgkJTW9kdWxlUmV2aXNpb24gcmV2aXNpb24gPSB0ZXN0TW9kdWxlLmdldEN1cnJlbnRSZXZpc2lvbigpOwoJCU1vZHVsZVdpcmluZyB3aXJpbmcgPSByZXZpc2lvbi5nZXRXaXJpbmcoKTsKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJVbmV4cGVjdGVkIHdpcmluZy50b1N0cmluZygpIiwgcmV2aXNpb24udG9TdHJpbmcoKSwgd2lyaW5nLnRvU3RyaW5nKCkpOwoJfQoKCUBUZXN0CglwdWJsaWMgdm9pZCB0ZXN0U3RhcnRPblJlc29sdmUoKSB0aHJvd3MgQnVuZGxlRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CgkJZG9UZXN0U3RhcnRPblJlc29sdmUodHJ1ZSk7Cgl9CgoJQFRlc3QKCXB1YmxpYyB2b2lkIHRlc3REaXNhYmxlU3RhcnRPblJlc29sdmUoKSB0aHJvd3MgQnVuZGxlRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CgkJZG9UZXN0U3RhcnRPblJlc29sdmUoZmFsc2UpOwoJfQoKCXByaXZhdGUgdm9pZCBkb1Rlc3RTdGFydE9uUmVzb2x2ZShib29sZWFuIGVuYWJsZWQpIHRocm93cyBCdW5kbGVFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKCQlNYXA8U3RyaW5nLCBTdHJpbmc+IGNvbmZpZ3VyYXRpb24gPSBuZXcgSGFzaE1hcDxTdHJpbmcsIFN0cmluZz4oKTsKCQlpZiAoIWVuYWJsZWQpIHsKCQkJY29uZmlndXJhdGlvbi5wdXQoRXF1aW5veENvbmZpZ3VyYXRpb24uUFJPUF9NT0RVTEVfQVVUT19TVEFSVF9PTl9SRVNPTFZFLCBCb29sZWFuLnRvU3RyaW5nKGZhbHNlKSk7CgkJfQoJCUR1bW15Q29udGFpbmVyQWRhcHRvciBhZGFwdG9yID0gbmV3IER1bW15Q29udGFpbmVyQWRhcHRvcihuZXcgRHVtbXlDb2xsaXNpb25Ib29rKGZhbHNlKSwgY29uZmlndXJhdGlvbik7CgkJTW9kdWxlQ29udGFpbmVyIGNvbnRhaW5lciA9IGFkYXB0b3IuZ2V0Q29udGFpbmVyKCk7CgoJCS8vIGluc3RhbGwgdGhlIHN5c3RlbS5idW5kbGUKCQlNb2R1bGUgc3lzdGVtQnVuZGxlID0gaW5zdGFsbER1bW15TW9kdWxlKCJzeXN0ZW0uYnVuZGxlLk1GIiwgQ29uc3RhbnRzLlNZU1RFTV9CVU5ETEVfTE9DQVRJT04sIENvbnN0YW50cy5TWVNURU1fQlVORExFX1NZTUJPTElDTkFNRSwgbnVsbCwgbnVsbCwgY29udGFpbmVyKTsKCQlSZXNvbHV0aW9uUmVwb3J0IHJlcG9ydCA9IGNvbnRhaW5lci5yZXNvbHZlKEFycmF5cy5hc0xpc3Qoc3lzdGVtQnVuZGxlKSwgdHJ1ZSk7CgkJQXNzZXJ0LmFzc2VydE51bGwoIkZhaWxlZCB0byByZXNvbHZlIHN5c3RlbS5idW5kbGUuIiwgcmVwb3J0LmdldFJlc29sdXRpb25FeGNlcHRpb24oKSk7CgkJc3lzdGVtQnVuZGxlLnN0YXJ0KCk7CgoJCS8vIGluc3RhbGwgYSBidW5jaCBvZiBtb2R1bGVzCgkJTWFwPFN0cmluZywgU3RyaW5nPiBtYW5pZmVzdCA9IG5ldyBIYXNoTWFwPFN0cmluZywgU3RyaW5nPigpOwoJCUxpc3Q8TW9kdWxlPiBtb2R1bGVzID0gbmV3IEFycmF5TGlzdDxNb2R1bGU+KCk7CgkJZm9yIChpbnQgaSA9IDA7IGkgPCA1OyBpKyspIHsKCQkJbWFuaWZlc3QuY2xlYXIoKTsKCQkJbWFuaWZlc3QucHV0KENvbnN0YW50cy5CVU5ETEVfTUFOSUZFU1RWRVJTSU9OLCAiMiIpOwoJCQltYW5pZmVzdC5wdXQoQ29uc3RhbnRzLkJVTkRMRV9TWU1CT0xJQ05BTUUsICJtb2R1bGUuIiArIGkpOwoJCQltYW5pZmVzdC5wdXQoQ29uc3RhbnRzLklNUE9SVF9QQUNLQUdFLCAiZXhwb3J0Iik7CgkJCU1vZHVsZSBtb2R1bGUgPSBpbnN0YWxsRHVtbXlNb2R1bGUobWFuaWZlc3QsIG1hbmlmZXN0LmdldChDb25zdGFudHMuQlVORExFX1NZTUJPTElDTkFNRSksIGNvbnRhaW5lcik7CgkJCXRyeSB7CgkJCQltb2R1bGUuc3RhcnQoKTsKCQkJCWZhaWwoImV4cGVjdGVkIGEgYnVuZGxlIGV4Y2VwdGlvbi4iKTsKCQkJfSBjYXRjaCAoQnVuZGxlRXhjZXB0aW9uIGUpIHsKCQkJCS8vIGRvIG5vdGhpbmcKCQkJfQoJCQltb2R1bGVzLmFkZChtb2R1bGUpOwoJCX0KCgkJbWFuaWZlc3QuY2xlYXIoKTsKCQltYW5pZmVzdC5wdXQoQ29uc3RhbnRzLkJVTkRMRV9NQU5JRkVTVFZFUlNJT04sICIyIik7CgkJbWFuaWZlc3QucHV0KENvbnN0YW50cy5CVU5ETEVfU1lNQk9MSUNOQU1FLCAiZXhwb3J0ZXIiKTsKCQltYW5pZmVzdC5wdXQoQ29uc3RhbnRzLkVYUE9SVF9QQUNLQUdFLCAiZXhwb3J0Iik7CgkJaW5zdGFsbER1bW15TW9kdWxlKG1hbmlmZXN0LCBtYW5pZmVzdC5nZXQoQ29uc3RhbnRzLkJVTkRMRV9TWU1CT0xJQ05BTUUpLCBjb250YWluZXIpOwoKCQlyZXBvcnQgPSBjb250YWluZXIucmVzb2x2ZShDb2xsZWN0aW9ucy48TW9kdWxlPiBlbXB0eVNldCgpLCBmYWxzZSk7CgkJQXNzZXJ0LmFzc2VydE51bGwoIkZvdW5kIGEgZXJyb3IuIiwgcmVwb3J0LmdldFJlc29sdXRpb25FeGNlcHRpb24oKSk7CgoJCVN0YXRlIGV4cGVjdGVkU3RhdGUgPSBlbmFibGVkID8gU3RhdGUuQUNUSVZFIDogU3RhdGUuUkVTT0xWRUQ7CgkJZm9yIChNb2R1bGUgbW9kdWxlIDogbW9kdWxlcykgewoJCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJXcm9uZyBzdGF0ZS4iLCBleHBlY3RlZFN0YXRlLCBtb2R1bGUuZ2V0U3RhdGUoKSk7CgkJfQoJfQoKCUBUZXN0CglwdWJsaWMgdm9pZCB0ZXN0UmVzb2x2ZURlYWRsb2NrKCkgdGhyb3dzIEJ1bmRsZUV4Y2VwdGlvbiwgSU9FeGNlcHRpb24sIEludGVycnVwdGVkRXhjZXB0aW9uIHsKCQlEdW1teUNvbnRhaW5lckFkYXB0b3IgYWRhcHRvciA9IGNyZWF0ZUR1bW15QWRhcHRvcigpOwoJCU1vZHVsZUNvbnRhaW5lciBjb250YWluZXIgPSBhZGFwdG9yLmdldENvbnRhaW5lcigpOwoKCQkvLyBpbnN0YWxsIHRoZSBzeXN0ZW0uYnVuZGxlCgkJTW9kdWxlIHN5c3RlbUJ1bmRsZSA9IGluc3RhbGxEdW1teU1vZHVsZSgic3lzdGVtLmJ1bmRsZS5NRiIsIENvbnN0YW50cy5TWVNURU1fQlVORExFX0xPQ0FUSU9OLCBDb25zdGFudHMuU1lTVEVNX0JVTkRMRV9TWU1CT0xJQ05BTUUsIG51bGwsIG51bGwsIGNvbnRhaW5lcik7CgkJUmVzb2x1dGlvblJlcG9ydCByZXBvcnQgPSBjb250YWluZXIucmVzb2x2ZShBcnJheXMuYXNMaXN0KHN5c3RlbUJ1bmRsZSksIHRydWUpOwoJCUFzc2VydC5hc3NlcnROdWxsKCJGYWlsZWQgdG8gcmVzb2x2ZSBzeXN0ZW0uYnVuZGxlLiIsIHJlcG9ydC5nZXRSZXNvbHV0aW9uRXhjZXB0aW9uKCkpOwoJCXN5c3RlbUJ1bmRsZS5zdGFydCgpOwoKCQkvLyBpbnN0YWxsIGEgYnVuY2ggb2YgbW9kdWxlcwoJCU1hcDxTdHJpbmcsIFN0cmluZz4gbWFuaWZlc3QgPSBuZXcgSGFzaE1hcDxTdHJpbmcsIFN0cmluZz4oKTsKCQlMaXN0PE1vZHVsZT4gbW9kdWxlcyA9IG5ldyBBcnJheUxpc3Q8TW9kdWxlPigpOwoJCWZvciAoaW50IGkgPSAwOyBpIDwgNTsgaSsrKSB7CgkJCW1hbmlmZXN0LmNsZWFyKCk7CgkJCW1hbmlmZXN0LnB1dChDb25zdGFudHMuQlVORExFX01BTklGRVNUVkVSU0lPTiwgIjIiKTsKCQkJbWFuaWZlc3QucHV0KENvbnN0YW50cy5CVU5ETEVfU1lNQk9MSUNOQU1FLCAibW9kdWxlLiIgKyBpKTsKCQkJbW9kdWxlcy5hZGQoaW5zdGFsbER1bW15TW9kdWxlKG1hbmlmZXN0LCBtYW5pZmVzdC5nZXQoQ29uc3RhbnRzLkJVTkRMRV9TWU1CT0xJQ05BTUUpLCBjb250YWluZXIpKTsKCQl9CgkJYWRhcHRvci5zZXRTbG93ZG93bkV2ZW50cyh0cnVlKTsKCQlmaW5hbCBDb25jdXJyZW50TGlua2VkUXVldWU8QnVuZGxlRXhjZXB0aW9uPiBzdGFydEVycm9ycyA9IG5ldyBDb25jdXJyZW50TGlua2VkUXVldWU8QnVuZGxlRXhjZXB0aW9uPigpOwoJCWZpbmFsIEV4ZWN1dG9yU2VydmljZSBleGVjdXRvciA9IEV4ZWN1dG9ycy5uZXdGaXhlZFRocmVhZFBvb2woMTApOwoJCXRyeSB7CgkJCWZvciAoZmluYWwgTW9kdWxlIG1vZHVsZSA6IG1vZHVsZXMpIHsKCgkJCQlleGVjdXRvci5leGVjdXRlKG5ldyBSdW5uYWJsZSgpIHsKCgkJCQkJQE92ZXJyaWRlCgkJCQkJcHVibGljIHZvaWQgcnVuKCkgewoJCQkJCQl0cnkgewoJCQkJCQkJbW9kdWxlLnN0YXJ0KCk7CgkJCQkJCX0gY2F0Y2ggKEJ1bmRsZUV4Y2VwdGlvbiBlKSB7CgkJCQkJCQlzdGFydEVycm9ycy5vZmZlcihlKTsKCQkJCQkJCWUucHJpbnRTdGFja1RyYWNlKCk7CgkJCQkJCX0KCQkJCQl9CgkJCQl9KTsKCQkJfQoJCX0gZmluYWxseSB7CgkJCWV4ZWN1dG9yLnNodXRkb3duKCk7CgkJCWV4ZWN1dG9yLmF3YWl0VGVybWluYXRpb24oNSwgVGltZVVuaXQuTUlOVVRFUyk7CgkJCXN5c3RlbUJ1bmRsZS5zdG9wKCk7CgkJfQoKCQlBc3NlcnQuYXNzZXJ0TnVsbCgiRm91bmQgYSBlcnJvci4iLCBzdGFydEVycm9ycy5wb2xsKCkpOwoJCUxpc3Q8RHVtbXlDb250YWluZXJFdmVudD4gZXZlbnRzID0gYWRhcHRvci5nZXREYXRhYmFzZSgpLmdldENvbnRhaW5lckV2ZW50cygpOwoJCWZvciAoRHVtbXlDb250YWluZXJFdmVudCBldmVudCA6IGV2ZW50cykgewoJCQlBc3NlcnQuYXNzZXJ0Tm90RXF1YWxzKCJGb3VuZCBhbiBlcnJvci4iLCBDb250YWluZXJFdmVudC5FUlJPUiwgZXZlbnQudHlwZSk7CgkJfQoJfQoKCXByaXZhdGUgc3RhdGljIHZvaWQgYXNzZXJ0V2lyZXMoTGlzdDxNb2R1bGVXaXJlPiByZXF1aXJlZCwgTGlzdDxNb2R1bGVXaXJlPi4uLiBwcm92aWRlZCkgewoJCWZvciAoTW9kdWxlV2lyZSByZXF1aXJlZFdpcmUgOiByZXF1aXJlZCkgewoJCQlmb3IgKExpc3Q8TW9kdWxlV2lyZT4gcHJvdmlkZWRMaXN0IDogcHJvdmlkZWQpIHsKCQkJCWlmIChwcm92aWRlZExpc3QuY29udGFpbnMocmVxdWlyZWRXaXJlKSkgewoJCQkJCXJldHVybjsKCQkJCX0KCQkJfQoJCQlBc3NlcnQuZmFpbCgiQ291bGQgbm90IGZpbmQgcmVxdWlyZWQgd2lyZSBpbiBleHBlY3RlZCBwcm92aWRlciB3aXJlczogIiArIHJlcXVpcmVkV2lyZSk7CgkJfQoJfQoKCXByaXZhdGUgdm9pZCBhc3NlcnRFdmVudHMoTGlzdDxEdW1teU1vZHVsZUV2ZW50PiBleHBlY3RlZCwgTGlzdDxEdW1teU1vZHVsZUV2ZW50PiBhY3R1YWwsIGJvb2xlYW4gb3JkZXJNYXR0ZXJzKSB7CgkJZm9yIChMaXN0PER1bW15TW9kdWxlRXZlbnQ+IGV4cGVjdGVkQ29tbW9uID0gcmVtb3ZlRmlyc3RMaXN0T2ZDb21tb25FdmVudHMoZXhwZWN0ZWQpOyAhZXhwZWN0ZWRDb21tb24uaXNFbXB0eSgpOyBleHBlY3RlZENvbW1vbiA9IHJlbW92ZUZpcnN0TGlzdE9mQ29tbW9uRXZlbnRzKGV4cGVjdGVkKSkgewoJCQlMaXN0PER1bW15TW9kdWxlRXZlbnQ+IGFjdHVhbENvbW1vbiA9IHJlbW92ZUZpcnN0TGlzdE9mQ29tbW9uRXZlbnRzKGFjdHVhbCk7CgkJCWlmIChleHBlY3RlZENvbW1vbi5zaXplKCkgIT0gYWN0dWFsQ29tbW9uLnNpemUoKSkgewoJCQkJQXNzZXJ0LmFzc2VydEVxdWFscygiV3JvbmcgbnVtYmVyIG9mIGV2ZW50cyBmb3VuZCBpbjogIiArIGFjdHVhbENvbW1vbiwgZXhwZWN0ZWRDb21tb24uc2l6ZSgpLCBhY3R1YWxDb21tb24uc2l6ZSgpKTsKCQkJfQoJCQlpZiAob3JkZXJNYXR0ZXJzKSB7CgkJCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJXcm9uZyBldmVudHMgZm91bmQuIiwgZXhwZWN0ZWRDb21tb24sIGFjdHVhbENvbW1vbik7CgkJCX0gZWxzZSB7CgkJCQlmb3IgKER1bW15TW9kdWxlRXZlbnQgZXhwZWN0ZWRFdmVudCA6IGV4cGVjdGVkQ29tbW9uKSB7CgkJCQkJQXNzZXJ0LmFzc2VydFRydWUoIk1pc3NpbmcgZXhwZWN0ZWQgZXZlbnQ6ICIgKyBleHBlY3RlZEV2ZW50ICsgIiA6IGZyb20gIiArIGFjdHVhbENvbW1vbiwgYWN0dWFsQ29tbW9uLmNvbnRhaW5zKGV4cGVjdGVkRXZlbnQpKTsKCQkJCX0KCQkJCWZvciAoRHVtbXlNb2R1bGVFdmVudCBhY3R1YWxFdmVudCA6IGFjdHVhbENvbW1vbikgewoJCQkJCUFzc2VydC5hc3NlcnRUcnVlKCJGb3VuZCB1bmV4cGVjdGVkIGV2ZW50OiAiICsgYWN0dWFsRXZlbnQgKyAiIDogZnJvbSAiICsgYWN0dWFsQ29tbW9uLCBleHBlY3RlZENvbW1vbi5jb250YWlucyhhY3R1YWxFdmVudCkpOwoJCQkJfQoJCQl9CgkJfQoJfQoKCXByaXZhdGUgTGlzdDxEdW1teU1vZHVsZUV2ZW50PiByZW1vdmVGaXJzdExpc3RPZkNvbW1vbkV2ZW50cyhMaXN0PER1bW15TW9kdWxlRXZlbnQ+IGV2ZW50cykgewoJCUxpc3Q8RHVtbXlNb2R1bGVFdmVudD4gcmVzdWx0ID0gbmV3IEFycmF5TGlzdDxEdW1teU1vZHVsZURhdGFiYXNlLkR1bW15TW9kdWxlRXZlbnQ+KCk7CgkJaWYgKGV2ZW50cy5pc0VtcHR5KCkpIHsKCQkJcmV0dXJuIHJlc3VsdDsKCQl9CgkJTW9kdWxlRXZlbnQgY29tbW9uRXZlbnQgPSBldmVudHMuZ2V0KDApLmV2ZW50OwoJCWZvciAoSXRlcmF0b3I8RHVtbXlNb2R1bGVFdmVudD4gaUV2ZW50cyA9IGV2ZW50cy5pdGVyYXRvcigpOyBpRXZlbnRzLmhhc05leHQoKTspIHsKCQkJRHVtbXlNb2R1bGVFdmVudCBjdXJyZW50ID0gaUV2ZW50cy5uZXh0KCk7CgkJCWlmIChjb21tb25FdmVudC5lcXVhbHMoY3VycmVudC5ldmVudCkpIHsKCQkJCWlFdmVudHMucmVtb3ZlKCk7CgkJCQlyZXN1bHQuYWRkKGN1cnJlbnQpOwoJCQl9IGVsc2UgewoJCQkJYnJlYWs7CgkJCX0KCQl9CgkJcmV0dXJuIHJlc3VsdDsKCX0KfQo=