LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChjKSAyMDE0LCAyMDE2IFJheW1vbmQgQXVn6S4KICogQWxsIHJpZ2h0cyByZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscwogKiBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYxLjAKICogd2hpY2ggYWNjb21wYW5pZXMgdGhpcyBkaXN0cmlidXRpb24sIGFuZCBpcyBhdmFpbGFibGUgYXQKICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtdjEwLmh0bWwKICoKICogQ29udHJpYnV0b3JzOgogKiAgICAgUmF5bW9uZCBBdWfpIDxyYXltb25kLmF1Z2VAbGlmZXJheS5jb20+IC0gaW5pdGlhbCBpbXBsZW1lbnRhdGlvbgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKcGFja2FnZSBvcmcuZWNsaXBzZS5lcXVpbm94Lmh0dHAuc2VydmxldC50ZXN0czsKCmltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwppbXBvcnQgamF2YS5pby5QcmludFdyaXRlcjsKaW1wb3J0IGphdmEuaW8uU3RyaW5nV3JpdGVyOwppbXBvcnQgamF2YS50ZXh0LlNpbXBsZURhdGVGb3JtYXQ7CmltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOwppbXBvcnQgamF2YS51dGlsLkRhdGU7CmltcG9ydCBqYXZhLnV0aWwuRGljdGlvbmFyeTsKaW1wb3J0IGphdmEudXRpbC5IYXNodGFibGU7CmltcG9ydCBqYXZhLnV0aWwuTGlzdDsKaW1wb3J0IGphdmEudXRpbC5Mb2NhbGU7CmltcG9ydCBqYXZhLnV0aWwuTWFwOwppbXBvcnQgamF2YS51dGlsLlRpbWVab25lOwppbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuYXRvbWljLkF0b21pY0Jvb2xlYW47CmltcG9ydCBqYXZhLnV0aWwuY29uY3VycmVudC5hdG9taWMuQXRvbWljSW50ZWdlcjsKaW1wb3J0IGphdmEudXRpbC5jb25jdXJyZW50LmF0b21pYy5BdG9taWNMb25nOwppbXBvcnQgamF2YS51dGlsLmNvbmN1cnJlbnQuYXRvbWljLkF0b21pY1JlZmVyZW5jZTsKCmltcG9ydCBqYXZheC5zZXJ2bGV0LkRpc3BhdGNoZXJUeXBlOwppbXBvcnQgamF2YXguc2VydmxldC5GaWx0ZXI7CmltcG9ydCBqYXZheC5zZXJ2bGV0LkZpbHRlckNoYWluOwppbXBvcnQgamF2YXguc2VydmxldC5SZXF1ZXN0RGlzcGF0Y2hlcjsKaW1wb3J0IGphdmF4LnNlcnZsZXQuU2VydmxldDsKaW1wb3J0IGphdmF4LnNlcnZsZXQuU2VydmxldENvbnRleHQ7CmltcG9ydCBqYXZheC5zZXJ2bGV0LlNlcnZsZXRPdXRwdXRTdHJlYW07CmltcG9ydCBqYXZheC5zZXJ2bGV0LlNlcnZsZXRFeGNlcHRpb247CmltcG9ydCBqYXZheC5zZXJ2bGV0LlNlcnZsZXRSZXF1ZXN0OwppbXBvcnQgamF2YXguc2VydmxldC5TZXJ2bGV0UmVzcG9uc2U7CmltcG9ydCBqYXZheC5zZXJ2bGV0Lmh0dHAuQ29va2llOwppbXBvcnQgamF2YXguc2VydmxldC5odHRwLkh0dHBTZXJ2bGV0OwppbXBvcnQgamF2YXguc2VydmxldC5odHRwLkh0dHBTZXJ2bGV0UmVxdWVzdDsKaW1wb3J0IGphdmF4LnNlcnZsZXQuaHR0cC5IdHRwU2VydmxldFJlc3BvbnNlOwoKaW1wb3J0IG9yZy5lY2xpcHNlLmVxdWlub3guaHR0cC5zZXJ2bGV0LnRlc3RiYXNlLkJhc2VUZXN0OwppbXBvcnQgb3JnLmVjbGlwc2UuZXF1aW5veC5odHRwLnNlcnZsZXQudGVzdHMudXRpbC5CYXNlU2VydmxldDsKaW1wb3J0IG9yZy5lY2xpcHNlLmVxdWlub3guaHR0cC5zZXJ2bGV0LnRlc3RzLnV0aWwuRGlzcGF0Y2hSZXN1bHRTZXJ2bGV0OwppbXBvcnQgb3JnLmVjbGlwc2UuZXF1aW5veC5odHRwLnNlcnZsZXQudGVzdHMudXRpbC5FdmVudEhhbmRsZXI7CmltcG9ydCBvcmcuanVuaXQuQXNzZXJ0OwppbXBvcnQgb3JnLmp1bml0LlRlc3Q7CmltcG9ydCBvcmcub3NnaS5zZXJ2aWNlLmh0dHAuSHR0cENvbnRleHQ7CmltcG9ydCBvcmcub3NnaS5zZXJ2aWNlLmh0dHAuSHR0cFNlcnZpY2U7CmltcG9ydCBvcmcub3NnaS5zZXJ2aWNlLmh0dHAuY29udGV4dC5TZXJ2bGV0Q29udGV4dEhlbHBlcjsKaW1wb3J0IG9yZy5vc2dpLnNlcnZpY2UuaHR0cC53aGl0ZWJvYXJkLkh0dHBXaGl0ZWJvYXJkQ29uc3RhbnRzOwoKcHVibGljIGNsYXNzIERpc3BhdGNoaW5nVGVzdCBleHRlbmRzIEJhc2VUZXN0IHsKCglAVGVzdAoJcHVibGljIHZvaWQgdGVzdF9jcm9zc0NvbnRleHREaXNwYXRjaDEoKSB0aHJvd3MgRXhjZXB0aW9uIHsKCQlTZXJ2bGV0IHNlcnZsZXQxID0gbmV3IEJhc2VTZXJ2bGV0KCkgewoJCQlwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAxTDsKCgkJCUBPdmVycmlkZQoJCQlwcm90ZWN0ZWQgdm9pZCBzZXJ2aWNlKEh0dHBTZXJ2bGV0UmVxdWVzdCByZXF1ZXN0LCBIdHRwU2VydmxldFJlc3BvbnNlIHJlc3BvbnNlKQoJCQkJCXRocm93cyBTZXJ2bGV0RXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CgoJCQkJU3RyaW5nV3JpdGVyIHdyaXRlciA9IG5ldyBTdHJpbmdXcml0ZXIoKTsKCgkJCQl3cml0ZXIud3JpdGUocmVxdWVzdC5nZXRDb250ZXh0UGF0aCgpKTsKCQkJCXdyaXRlci53cml0ZSgifCIpOwoKCQkJCVNlcnZsZXRDb250ZXh0IHNlcnZsZXRDb250ZXh0ID0gZ2V0U2VydmxldENvbnRleHQoKS5nZXRDb250ZXh0KCIvIik7CgoJCQkJd3JpdGVyLndyaXRlKHNlcnZsZXRDb250ZXh0LmdldENvbnRleHRQYXRoKCkpOwoKCQkJCXJlc3BvbnNlLmdldFdyaXRlcigpLndyaXRlKHdyaXRlci50b1N0cmluZygpKTsKCQkJfQoJCX07CgoJCURpY3Rpb25hcnk8U3RyaW5nLCBPYmplY3Q+IHByb3BzID0gbmV3IEhhc2h0YWJsZTxTdHJpbmcsIE9iamVjdD4oKTsKCQlwcm9wcy5wdXQoSHR0cFdoaXRlYm9hcmRDb25zdGFudHMuSFRUUF9XSElURUJPQVJEX0NPTlRFWFRfTkFNRSwgImEiKTsKCQlwcm9wcy5wdXQoSHR0cFdoaXRlYm9hcmRDb25zdGFudHMuSFRUUF9XSElURUJPQVJEX0NPTlRFWFRfUEFUSCwgIi9hIik7CgkJcmVnaXN0cmF0aW9ucy5hZGQoZ2V0QnVuZGxlQ29udGV4dCgpLnJlZ2lzdGVyU2VydmljZShTZXJ2bGV0Q29udGV4dEhlbHBlci5jbGFzcywgbmV3IFNlcnZsZXRDb250ZXh0SGVscGVyKCkge30sIHByb3BzKSk7CgoJCXByb3BzID0gbmV3IEhhc2h0YWJsZTxTdHJpbmcsIE9iamVjdD4oKTsKCQlwcm9wcy5wdXQoSHR0cFdoaXRlYm9hcmRDb25zdGFudHMuSFRUUF9XSElURUJPQVJEX1NFUlZMRVRfUEFUVEVSTiwgIi9zMS8qIik7CgkJcHJvcHMucHV0KEh0dHBXaGl0ZWJvYXJkQ29uc3RhbnRzLkhUVFBfV0hJVEVCT0FSRF9DT05URVhUX1NFTEVDVCwgIigiICsgSHR0cFdoaXRlYm9hcmRDb25zdGFudHMuSFRUUF9XSElURUJPQVJEX0NPTlRFWFRfTkFNRSArICI9YSkiKTsKCQlyZWdpc3RyYXRpb25zLmFkZChnZXRCdW5kbGVDb250ZXh0KCkucmVnaXN0ZXJTZXJ2aWNlKFNlcnZsZXQuY2xhc3MsIHNlcnZsZXQxLCBwcm9wcykpOwoKCQlTdHJpbmcgcmVzcG9uc2UgPSByZXF1ZXN0QWR2aXNvci5yZXF1ZXN0KCJhL3MxL2QiKTsKCgkJQXNzZXJ0LmFzc2VydEVxdWFscygiL2F8IiwgcmVzcG9uc2UpOwoJfQoKCUBUZXN0CglwdWJsaWMgdm9pZCB0ZXN0X2ZvcndhcmREZXB0aDEoKSB0aHJvd3MgRXhjZXB0aW9uIHsKCQlTZXJ2bGV0IHNlcnZsZXQxID0gbmV3IEJhc2VTZXJ2bGV0KCkgewoJCQlwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAxTDsKCgkJCUBPdmVycmlkZQoJCQlwcm90ZWN0ZWQgdm9pZCBzZXJ2aWNlKEh0dHBTZXJ2bGV0UmVxdWVzdCByZXF1ZXN0LCBIdHRwU2VydmxldFJlc3BvbnNlIHJlc3BvbnNlKQoJCQkJCXRocm93cyBTZXJ2bGV0RXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CgkJCQlyZXF1ZXN0LmdldFJlcXVlc3REaXNwYXRjaGVyKCIvczIvYj91PTUiKS5mb3J3YXJkKHJlcXVlc3QsIHJlc3BvbnNlKTsKCQkJfQoJCX07CgoJCURpY3Rpb25hcnk8U3RyaW5nLCBPYmplY3Q+IHByb3BzID0gbmV3IEhhc2h0YWJsZTxTdHJpbmcsIE9iamVjdD4oKTsKCQlwcm9wcy5wdXQoSHR0cFdoaXRlYm9hcmRDb25zdGFudHMuSFRUUF9XSElURUJPQVJEX0NPTlRFWFRfTkFNRSwgImEiKTsKCQlwcm9wcy5wdXQoSHR0cFdoaXRlYm9hcmRDb25zdGFudHMuSFRUUF9XSElURUJPQVJEX0NPTlRFWFRfUEFUSCwgIi9hIik7CgkJcmVnaXN0cmF0aW9ucy5hZGQoZ2V0QnVuZGxlQ29udGV4dCgpLnJlZ2lzdGVyU2VydmljZShTZXJ2bGV0Q29udGV4dEhlbHBlci5jbGFzcywgbmV3IFNlcnZsZXRDb250ZXh0SGVscGVyKCkge30sIHByb3BzKSk7CgoJCXByb3BzID0gbmV3IEhhc2h0YWJsZTxTdHJpbmcsIE9iamVjdD4oKTsKCQlwcm9wcy5wdXQoSHR0cFdoaXRlYm9hcmRDb25zdGFudHMuSFRUUF9XSElURUJPQVJEX1NFUlZMRVRfUEFUVEVSTiwgIi9zMS8qIik7CgkJcHJvcHMucHV0KEh0dHBXaGl0ZWJvYXJkQ29uc3RhbnRzLkhUVFBfV0hJVEVCT0FSRF9DT05URVhUX1NFTEVDVCwgIigiICsgSHR0cFdoaXRlYm9hcmRDb25zdGFudHMuSFRUUF9XSElURUJPQVJEX0NPTlRFWFRfTkFNRSArICI9YSkiKTsKCQlyZWdpc3RyYXRpb25zLmFkZChnZXRCdW5kbGVDb250ZXh0KCkucmVnaXN0ZXJTZXJ2aWNlKFNlcnZsZXQuY2xhc3MsIHNlcnZsZXQxLCBwcm9wcykpOwoKCQlwcm9wcyA9IG5ldyBIYXNodGFibGU8U3RyaW5nLCBPYmplY3Q+KCk7CgkJcHJvcHMucHV0KEh0dHBXaGl0ZWJvYXJkQ29uc3RhbnRzLkhUVFBfV0hJVEVCT0FSRF9TRVJWTEVUX1BBVFRFUk4sICIvczIvKiIpOwoJCXByb3BzLnB1dChIdHRwV2hpdGVib2FyZENvbnN0YW50cy5IVFRQX1dISVRFQk9BUkRfQ09OVEVYVF9TRUxFQ1QsICIoIiArIEh0dHBXaGl0ZWJvYXJkQ29uc3RhbnRzLkhUVFBfV0hJVEVCT0FSRF9DT05URVhUX05BTUUgKyAiPWEpIik7CgkJcmVnaXN0cmF0aW9ucy5hZGQoZ2V0QnVuZGxlQ29udGV4dCgpLnJlZ2lzdGVyU2VydmljZShTZXJ2bGV0LmNsYXNzLCBuZXcgRGlzcGF0Y2hSZXN1bHRTZXJ2bGV0KCksIHByb3BzKSk7CgoJCVN0cmluZyByZXNwb25zZSA9IHJlcXVlc3RBZHZpc29yLnJlcXVlc3QoImEvczEvZD9wPTEiKTsKCgkJQXNzZXJ0LmFzc2VydEVxdWFscygiL2F8L2J8dT01fC9hL3MyL2J8L3MyfC9hfC9kfHA9MXwvYS9zMS9kfC9zMSIsIHJlc3BvbnNlKTsKCX0KCglAVGVzdAoJcHVibGljIHZvaWQgdGVzdF9mb3J3YXJkRGVwdGgxX1dpdGhSZXF1ZXN0RmlsdGVyKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CgkJU2VydmxldCBzZXJ2bGV0MSA9IG5ldyBCYXNlU2VydmxldCgpIHsKCQkJcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMUw7CgoJCQlAT3ZlcnJpZGUKCQkJcHJvdGVjdGVkIHZvaWQgc2VydmljZShIdHRwU2VydmxldFJlcXVlc3QgcmVxdWVzdCwgSHR0cFNlcnZsZXRSZXNwb25zZSByZXNwb25zZSkKCQkJCQl0aHJvd3MgU2VydmxldEV4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewoJCQkJcmVxdWVzdC5nZXRSZXF1ZXN0RGlzcGF0Y2hlcigiL3MyL2I/dT01IikuZm9yd2FyZChyZXF1ZXN0LCByZXNwb25zZSk7CgkJCX0KCQl9OwoKCQlUZXN0RmlsdGVyIGZpbHRlciA9IG5ldyBUZXN0RmlsdGVyKCkgewoKCQkJQE92ZXJyaWRlCgkJCXB1YmxpYyB2b2lkIGRvRmlsdGVyKAoJCQkJCVNlcnZsZXRSZXF1ZXN0IHJlcXVlc3QsIFNlcnZsZXRSZXNwb25zZSByZXNwb25zZSwgRmlsdGVyQ2hhaW4gY2hhaW4pCgkJCQl0aHJvd3MgSU9FeGNlcHRpb24sIFNlcnZsZXRFeGNlcHRpb24gewoKCQkJCXJlc3BvbnNlLmdldFdyaXRlcigpLndyaXRlKCdiJyk7CgoJCQkJc3VwZXIuZG9GaWx0ZXIocmVxdWVzdCwgcmVzcG9uc2UsIGNoYWluKTsKCgkJCQlyZXNwb25zZS5nZXRXcml0ZXIoKS53cml0ZSgnYicpOwoJCQl9CgoJCX07CgoJCURpY3Rpb25hcnk8U3RyaW5nLCBPYmplY3Q+IHByb3BzID0gbmV3IEhhc2h0YWJsZTxTdHJpbmcsIE9iamVjdD4oKTsKCQlwcm9wcy5wdXQoSHR0cFdoaXRlYm9hcmRDb25zdGFudHMuSFRUUF9XSElURUJPQVJEX0NPTlRFWFRfTkFNRSwgImEiKTsKCQlwcm9wcy5wdXQoSHR0cFdoaXRlYm9hcmRDb25zdGFudHMuSFRUUF9XSElURUJPQVJEX0NPTlRFWFRfUEFUSCwgIi9hIik7CgkJcmVnaXN0cmF0aW9ucy5hZGQoZ2V0QnVuZGxlQ29udGV4dCgpLnJlZ2lzdGVyU2VydmljZShTZXJ2bGV0Q29udGV4dEhlbHBlci5jbGFzcywgbmV3IFNlcnZsZXRDb250ZXh0SGVscGVyKCkge30sIHByb3BzKSk7CgoJCXByb3BzID0gbmV3IEhhc2h0YWJsZTxTdHJpbmcsIE9iamVjdD4oKTsKCQlwcm9wcy5wdXQoSHR0cFdoaXRlYm9hcmRDb25zdGFudHMuSFRUUF9XSElURUJPQVJEX1NFUlZMRVRfUEFUVEVSTiwgIi9zMS8qIik7CgkJcHJvcHMucHV0KEh0dHBXaGl0ZWJvYXJkQ29uc3RhbnRzLkhUVFBfV0hJVEVCT0FSRF9DT05URVhUX1NFTEVDVCwgIigiICsgSHR0cFdoaXRlYm9hcmRDb25zdGFudHMuSFRUUF9XSElURUJPQVJEX0NPTlRFWFRfTkFNRSArICI9YSkiKTsKCQlyZWdpc3RyYXRpb25zLmFkZChnZXRCdW5kbGVDb250ZXh0KCkucmVnaXN0ZXJTZXJ2aWNlKFNlcnZsZXQuY2xhc3MsIHNlcnZsZXQxLCBwcm9wcykpOwoKCQlwcm9wcyA9IG5ldyBIYXNodGFibGU8U3RyaW5nLCBPYmplY3Q+KCk7CgkJcHJvcHMucHV0KEh0dHBXaGl0ZWJvYXJkQ29uc3RhbnRzLkhUVFBfV0hJVEVCT0FSRF9TRVJWTEVUX1BBVFRFUk4sICIvczIvKiIpOwoJCXByb3BzLnB1dChIdHRwV2hpdGVib2FyZENvbnN0YW50cy5IVFRQX1dISVRFQk9BUkRfQ09OVEVYVF9TRUxFQ1QsICIoIiArIEh0dHBXaGl0ZWJvYXJkQ29uc3RhbnRzLkhUVFBfV0hJVEVCT0FSRF9DT05URVhUX05BTUUgKyAiPWEpIik7CgkJcmVnaXN0cmF0aW9ucy5hZGQoZ2V0QnVuZGxlQ29udGV4dCgpLnJlZ2lzdGVyU2VydmljZShTZXJ2bGV0LmNsYXNzLCBuZXcgRGlzcGF0Y2hSZXN1bHRTZXJ2bGV0KCksIHByb3BzKSk7CgoJCXByb3BzID0gbmV3IEhhc2h0YWJsZTxTdHJpbmcsIE9iamVjdD4oKTsKCQlwcm9wcy5wdXQoSHR0cFdoaXRlYm9hcmRDb25zdGFudHMuSFRUUF9XSElURUJPQVJEX0NPTlRFWFRfU0VMRUNULCAiKCIgKyBIdHRwV2hpdGVib2FyZENvbnN0YW50cy5IVFRQX1dISVRFQk9BUkRfQ09OVEVYVF9OQU1FICsgIj1hKSIpOwoJCXByb3BzLnB1dChIdHRwV2hpdGVib2FyZENvbnN0YW50cy5IVFRQX1dISVRFQk9BUkRfRklMVEVSX05BTUUsICJGMSIpOwoJCXByb3BzLnB1dChIdHRwV2hpdGVib2FyZENvbnN0YW50cy5IVFRQX1dISVRFQk9BUkRfRklMVEVSX0RJU1BBVENIRVIsIG5ldyBTdHJpbmdbXSB7RGlzcGF0Y2hlclR5cGUuUkVRVUVTVC50b1N0cmluZygpfSk7CgkJcHJvcHMucHV0KEh0dHBXaGl0ZWJvYXJkQ29uc3RhbnRzLkhUVFBfV0hJVEVCT0FSRF9GSUxURVJfUEFUVEVSTiwgIi8qIik7CgkJcmVnaXN0cmF0aW9ucy5hZGQoZ2V0QnVuZGxlQ29udGV4dCgpLnJlZ2lzdGVyU2VydmljZShGaWx0ZXIuY2xhc3MsIGZpbHRlciwgcHJvcHMpKTsKCgkJU3RyaW5nIHJlc3BvbnNlID0gcmVxdWVzdEFkdmlzb3IucmVxdWVzdCgiYS9zMS9kP3A9MSIpOwoKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCIvYXwvYnx1PTV8L2EvczIvYnwvczJ8L2F8L2R8cD0xfC9hL3MxL2R8L3MxIiwgcmVzcG9uc2UpOwoJCUFzc2VydC5hc3NlcnRUcnVlKGZpbHRlci5nZXRDYWxsZWQoKSk7Cgl9CgoJQFRlc3QKCXB1YmxpYyB2b2lkIHRlc3RfZm9yd2FyZERlcHRoMV9XaXRoUmVxdWVzdEFuZEZvcndhcmRGaWx0ZXIoKSB0aHJvd3MgRXhjZXB0aW9uIHsKCQlTZXJ2bGV0IHNlcnZsZXQxID0gbmV3IEJhc2VTZXJ2bGV0KCkgewoJCQlwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAxTDsKCgkJCUBPdmVycmlkZQoJCQlwcm90ZWN0ZWQgdm9pZCBzZXJ2aWNlKEh0dHBTZXJ2bGV0UmVxdWVzdCByZXF1ZXN0LCBIdHRwU2VydmxldFJlc3BvbnNlIHJlc3BvbnNlKQoJCQkJCXRocm93cyBTZXJ2bGV0RXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CgkJCQlyZXF1ZXN0LmdldFJlcXVlc3REaXNwYXRjaGVyKCIvczIvaTQ/dT01IikuZm9yd2FyZChyZXF1ZXN0LCByZXNwb25zZSk7CgkJCX0KCQl9OwoKCQlUZXN0RmlsdGVyIGZpbHRlciA9IG5ldyBUZXN0RmlsdGVyKCkgewoKCQkJQE92ZXJyaWRlCgkJCXB1YmxpYyB2b2lkIGRvRmlsdGVyKAoJCQkJCVNlcnZsZXRSZXF1ZXN0IHJlcXVlc3QsIFNlcnZsZXRSZXNwb25zZSByZXNwb25zZSwgRmlsdGVyQ2hhaW4gY2hhaW4pCgkJCQl0aHJvd3MgSU9FeGNlcHRpb24sIFNlcnZsZXRFeGNlcHRpb24gewoKCQkJCXJlc3BvbnNlLmdldFdyaXRlcigpLndyaXRlKCdiJyk7CgoJCQkJc3VwZXIuZG9GaWx0ZXIocmVxdWVzdCwgcmVzcG9uc2UsIGNoYWluKTsKCgkJCQlyZXNwb25zZS5nZXRXcml0ZXIoKS53cml0ZSgnYicpOwoJCQl9CgoJCX07CgoJCURpY3Rpb25hcnk8U3RyaW5nLCBPYmplY3Q+IHByb3BzID0gbmV3IEhhc2h0YWJsZTxTdHJpbmcsIE9iamVjdD4oKTsKCQlwcm9wcy5wdXQoSHR0cFdoaXRlYm9hcmRDb25zdGFudHMuSFRUUF9XSElURUJPQVJEX0NPTlRFWFRfTkFNRSwgImEiKTsKCQlwcm9wcy5wdXQoSHR0cFdoaXRlYm9hcmRDb25zdGFudHMuSFRUUF9XSElURUJPQVJEX0NPTlRFWFRfUEFUSCwgIi9hIik7CgkJcmVnaXN0cmF0aW9ucy5hZGQoZ2V0QnVuZGxlQ29udGV4dCgpLnJlZ2lzdGVyU2VydmljZShTZXJ2bGV0Q29udGV4dEhlbHBlci5jbGFzcywgbmV3IFNlcnZsZXRDb250ZXh0SGVscGVyKCkge30sIHByb3BzKSk7CgoJCXByb3BzID0gbmV3IEhhc2h0YWJsZTxTdHJpbmcsIE9iamVjdD4oKTsKCQlwcm9wcy5wdXQoSHR0cFdoaXRlYm9hcmRDb25zdGFudHMuSFRUUF9XSElURUJPQVJEX1NFUlZMRVRfUEFUVEVSTiwgIi9zMS8qIik7CgkJcHJvcHMucHV0KEh0dHBXaGl0ZWJvYXJkQ29uc3RhbnRzLkhUVFBfV0hJVEVCT0FSRF9DT05URVhUX1NFTEVDVCwgIigiICsgSHR0cFdoaXRlYm9hcmRDb25zdGFudHMuSFRUUF9XSElURUJPQVJEX0NPTlRFWFRfTkFNRSArICI9YSkiKTsKCQlyZWdpc3RyYXRpb25zLmFkZChnZXRCdW5kbGVDb250ZXh0KCkucmVnaXN0ZXJTZXJ2aWNlKFNlcnZsZXQuY2xhc3MsIHNlcnZsZXQxLCBwcm9wcykpOwoKCQlwcm9wcyA9IG5ldyBIYXNodGFibGU8U3RyaW5nLCBPYmplY3Q+KCk7CgkJcHJvcHMucHV0KEh0dHBXaGl0ZWJvYXJkQ29uc3RhbnRzLkhUVFBfV0hJVEVCT0FSRF9TRVJWTEVUX1BBVFRFUk4sICIvczIvKiIpOwoJCXByb3BzLnB1dChIdHRwV2hpdGVib2FyZENvbnN0YW50cy5IVFRQX1dISVRFQk9BUkRfQ09OVEVYVF9TRUxFQ1QsICIoIiArIEh0dHBXaGl0ZWJvYXJkQ29uc3RhbnRzLkhUVFBfV0hJVEVCT0FSRF9DT05URVhUX05BTUUgKyAiPWEpIik7CgkJcmVnaXN0cmF0aW9ucy5hZGQoZ2V0QnVuZGxlQ29udGV4dCgpLnJlZ2lzdGVyU2VydmljZShTZXJ2bGV0LmNsYXNzLCBuZXcgRGlzcGF0Y2hSZXN1bHRTZXJ2bGV0KCksIHByb3BzKSk7CgoJCXByb3BzID0gbmV3IEhhc2h0YWJsZTxTdHJpbmcsIE9iamVjdD4oKTsKCQlwcm9wcy5wdXQoSHR0cFdoaXRlYm9hcmRDb25zdGFudHMuSFRUUF9XSElURUJPQVJEX0NPTlRFWFRfU0VMRUNULCAiKCIgKyBIdHRwV2hpdGVib2FyZENvbnN0YW50cy5IVFRQX1dISVRFQk9BUkRfQ09OVEVYVF9OQU1FICsgIj1hKSIpOwoJCXByb3BzLnB1dChIdHRwV2hpdGVib2FyZENvbnN0YW50cy5IVFRQX1dISVRFQk9BUkRfRklMVEVSX05BTUUsICJGMSIpOwoJCXByb3BzLnB1dChIdHRwV2hpdGVib2FyZENvbnN0YW50cy5IVFRQX1dISVRFQk9BUkRfRklMVEVSX0RJU1BBVENIRVIsIG5ldyBTdHJpbmdbXSB7RGlzcGF0Y2hlclR5cGUuRk9SV0FSRC50b1N0cmluZygpLERpc3BhdGNoZXJUeXBlLlJFUVVFU1QudG9TdHJpbmcoKX0pOwoJCXByb3BzLnB1dChIdHRwV2hpdGVib2FyZENvbnN0YW50cy5IVFRQX1dISVRFQk9BUkRfRklMVEVSX1BBVFRFUk4sICIvKiIpOwoJCXJlZ2lzdHJhdGlvbnMuYWRkKGdldEJ1bmRsZUNvbnRleHQoKS5yZWdpc3RlclNlcnZpY2UoRmlsdGVyLmNsYXNzLCBmaWx0ZXIsIHByb3BzKSk7CgoJCVN0cmluZyByZXNwb25zZSA9IHJlcXVlc3RBZHZpc29yLnJlcXVlc3QoImEvczEvZD9wPTEiKTsKCgkJQXNzZXJ0LmFzc2VydEVxdWFscygiYi9hfC9pNHx1PTV8L2EvczIvaTR8L3MyfC9hfC9kfHA9MXwvYS9zMS9kfC9zMWIiLCByZXNwb25zZSk7CgkJQXNzZXJ0LmFzc2VydEVxdWFscygyLCBmaWx0ZXIuZ2V0Q291bnQoKSk7Cgl9CgoJQFRlc3QKCXB1YmxpYyB2b2lkIHRlc3RfZm9yd2FyZERlcHRoMigpIHRocm93cyBFeGNlcHRpb24gewoJCVNlcnZsZXQgc2VydmxldDEgPSBuZXcgQmFzZVNlcnZsZXQoKSB7CgkJCXByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDFMOwoKCQkJQE92ZXJyaWRlCgkJCXByb3RlY3RlZCB2b2lkIHNlcnZpY2UoSHR0cFNlcnZsZXRSZXF1ZXN0IHJlcXVlc3QsIEh0dHBTZXJ2bGV0UmVzcG9uc2UgcmVzcG9uc2UpCgkJCQkJdGhyb3dzIFNlcnZsZXRFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKCQkJCXJlcXVlc3QuZ2V0UmVxdWVzdERpc3BhdGNoZXIoIi9zMi9pMj9wMj0yIikuZm9yd2FyZChyZXF1ZXN0LCByZXNwb25zZSk7CgkJCX0KCQl9OwoKCQlTZXJ2bGV0IHNlcnZsZXQyID0gbmV3IEJhc2VTZXJ2bGV0KCkgewoJCQlwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAxTDsKCgkJCUBPdmVycmlkZQoJCQlwcm90ZWN0ZWQgdm9pZCBzZXJ2aWNlKEh0dHBTZXJ2bGV0UmVxdWVzdCByZXF1ZXN0LCBIdHRwU2VydmxldFJlc3BvbnNlIHJlc3BvbnNlKQoJCQkJCXRocm93cyBTZXJ2bGV0RXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CgkJCQlyZXF1ZXN0LmdldFJlcXVlc3REaXNwYXRjaGVyKCIvczMvaTM/cDM9MyIpLmZvcndhcmQocmVxdWVzdCwgcmVzcG9uc2UpOwoJCQl9CgkJfTsKCgkJRGljdGlvbmFyeTxTdHJpbmcsIE9iamVjdD4gcHJvcHMgPSBuZXcgSGFzaHRhYmxlPFN0cmluZywgT2JqZWN0PigpOwoJCXByb3BzLnB1dChIdHRwV2hpdGVib2FyZENvbnN0YW50cy5IVFRQX1dISVRFQk9BUkRfQ09OVEVYVF9OQU1FLCAiYzEiKTsKCQlwcm9wcy5wdXQoSHR0cFdoaXRlYm9hcmRDb25zdGFudHMuSFRUUF9XSElURUJPQVJEX0NPTlRFWFRfUEFUSCwgIi9jMSIpOwoJCXJlZ2lzdHJhdGlvbnMuYWRkKGdldEJ1bmRsZUNvbnRleHQoKS5yZWdpc3RlclNlcnZpY2UoU2VydmxldENvbnRleHRIZWxwZXIuY2xhc3MsIG5ldyBTZXJ2bGV0Q29udGV4dEhlbHBlcigpIHt9LCBwcm9wcykpOwoKCQlwcm9wcyA9IG5ldyBIYXNodGFibGU8U3RyaW5nLCBPYmplY3Q+KCk7CgkJcHJvcHMucHV0KEh0dHBXaGl0ZWJvYXJkQ29uc3RhbnRzLkhUVFBfV0hJVEVCT0FSRF9TRVJWTEVUX1BBVFRFUk4sICIvczEvKiIpOwoJCXByb3BzLnB1dChIdHRwV2hpdGVib2FyZENvbnN0YW50cy5IVFRQX1dISVRFQk9BUkRfQ09OVEVYVF9TRUxFQ1QsICIoIiArIEh0dHBXaGl0ZWJvYXJkQ29uc3RhbnRzLkhUVFBfV0hJVEVCT0FSRF9DT05URVhUX05BTUUgKyAiPWMxKSIpOwoJCXJlZ2lzdHJhdGlvbnMuYWRkKGdldEJ1bmRsZUNvbnRleHQoKS5yZWdpc3RlclNlcnZpY2UoU2VydmxldC5jbGFzcywgc2VydmxldDEsIHByb3BzKSk7CgoJCXByb3BzID0gbmV3IEhhc2h0YWJsZTxTdHJpbmcsIE9iamVjdD4oKTsKCQlwcm9wcy5wdXQoSHR0cFdoaXRlYm9hcmRDb25zdGFudHMuSFRUUF9XSElURUJPQVJEX1NFUlZMRVRfUEFUVEVSTiwgIi9zMi8qIik7CgkJcHJvcHMucHV0KEh0dHBXaGl0ZWJvYXJkQ29uc3RhbnRzLkhUVFBfV0hJVEVCT0FSRF9DT05URVhUX1NFTEVDVCwgIigiICsgSHR0cFdoaXRlYm9hcmRDb25zdGFudHMuSFRUUF9XSElURUJPQVJEX0NPTlRFWFRfTkFNRSArICI9YzEpIik7CgkJcmVnaXN0cmF0aW9ucy5hZGQoZ2V0QnVuZGxlQ29udGV4dCgpLnJlZ2lzdGVyU2VydmljZShTZXJ2bGV0LmNsYXNzLCBzZXJ2bGV0MiwgcHJvcHMpKTsKCgkJcHJvcHMgPSBuZXcgSGFzaHRhYmxlPFN0cmluZywgT2JqZWN0PigpOwoJCXByb3BzLnB1dChIdHRwV2hpdGVib2FyZENvbnN0YW50cy5IVFRQX1dISVRFQk9BUkRfU0VSVkxFVF9QQVRURVJOLCAiL3MzLyoiKTsKCQlwcm9wcy5wdXQoSHR0cFdoaXRlYm9hcmRDb25zdGFudHMuSFRUUF9XSElURUJPQVJEX0NPTlRFWFRfU0VMRUNULCAiKCIgKyBIdHRwV2hpdGVib2FyZENvbnN0YW50cy5IVFRQX1dISVRFQk9BUkRfQ09OVEVYVF9OQU1FICsgIj1jMSkiKTsKCQlyZWdpc3RyYXRpb25zLmFkZChnZXRCdW5kbGVDb250ZXh0KCkucmVnaXN0ZXJTZXJ2aWNlKFNlcnZsZXQuY2xhc3MsIG5ldyBEaXNwYXRjaFJlc3VsdFNlcnZsZXQoKSwgcHJvcHMpKTsKCgkJU3RyaW5nIHJlc3BvbnNlID0gcmVxdWVzdEFkdmlzb3IucmVxdWVzdCgiYzEvczEvaTE/cDE9MSIpOwoKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCIvYzF8L2kzfHAzPTN8L2MxL3MzL2kzfC9zM3wvYzF8L2kxfHAxPTF8L2MxL3MxL2kxfC9zMSIsIHJlc3BvbnNlKTsKCX0KCglAVGVzdAoJcHVibGljIHZvaWQgdGVzdF9mb3J3YXJkRGVwdGgzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CgkJU2VydmxldCBzZXJ2bGV0MSA9IG5ldyBCYXNlU2VydmxldCgpIHsKCQkJcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMUw7CgoJCQlAT3ZlcnJpZGUKCQkJcHJvdGVjdGVkIHZvaWQgc2VydmljZShIdHRwU2VydmxldFJlcXVlc3QgcmVxdWVzdCwgSHR0cFNlcnZsZXRSZXNwb25zZSByZXNwb25zZSkKCQkJCQl0aHJvd3MgU2VydmxldEV4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewoJCQkJcmVxdWVzdC5nZXRSZXF1ZXN0RGlzcGF0Y2hlcigiL3MyL2kyP3AyPTIiKS5mb3J3YXJkKHJlcXVlc3QsIHJlc3BvbnNlKTsKCQkJfQoJCX07CgoJCVNlcnZsZXQgc2VydmxldDIgPSBuZXcgQmFzZVNlcnZsZXQoKSB7CgkJCXByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDFMOwoKCQkJQE92ZXJyaWRlCgkJCXByb3RlY3RlZCB2b2lkIHNlcnZpY2UoSHR0cFNlcnZsZXRSZXF1ZXN0IHJlcXVlc3QsIEh0dHBTZXJ2bGV0UmVzcG9uc2UgcmVzcG9uc2UpCgkJCQkJdGhyb3dzIFNlcnZsZXRFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKCQkJCXJlcXVlc3QuZ2V0UmVxdWVzdERpc3BhdGNoZXIoIi9zMy9pMz9wMz0zIikuZm9yd2FyZChyZXF1ZXN0LCByZXNwb25zZSk7CgkJCX0KCQl9OwoKCQlTZXJ2bGV0IHNlcnZsZXQzID0gbmV3IEJhc2VTZXJ2bGV0KCkgewoJCQlwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAxTDsKCgkJCUBPdmVycmlkZQoJCQlwcm90ZWN0ZWQgdm9pZCBzZXJ2aWNlKEh0dHBTZXJ2bGV0UmVxdWVzdCByZXF1ZXN0LCBIdHRwU2VydmxldFJlc3BvbnNlIHJlc3BvbnNlKQoJCQkJCXRocm93cyBTZXJ2bGV0RXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CgkJCQlyZXF1ZXN0LmdldFJlcXVlc3REaXNwYXRjaGVyKCIvczQvaTQ/cDQ9NCIpLmZvcndhcmQocmVxdWVzdCwgcmVzcG9uc2UpOwoJCQl9CgkJfTsKCgkJRGljdGlvbmFyeTxTdHJpbmcsIE9iamVjdD4gcHJvcHMgPSBuZXcgSGFzaHRhYmxlPFN0cmluZywgT2JqZWN0PigpOwoJCXByb3BzLnB1dChIdHRwV2hpdGVib2FyZENvbnN0YW50cy5IVFRQX1dISVRFQk9BUkRfQ09OVEVYVF9OQU1FLCAiYzEiKTsKCQlwcm9wcy5wdXQoSHR0cFdoaXRlYm9hcmRDb25zdGFudHMuSFRUUF9XSElURUJPQVJEX0NPTlRFWFRfUEFUSCwgIi9jMSIpOwoJCXJlZ2lzdHJhdGlvbnMuYWRkKGdldEJ1bmRsZUNvbnRleHQoKS5yZWdpc3RlclNlcnZpY2UoU2VydmxldENvbnRleHRIZWxwZXIuY2xhc3MsIG5ldyBTZXJ2bGV0Q29udGV4dEhlbHBlcigpIHt9LCBwcm9wcykpOwoKCQlwcm9wcyA9IG5ldyBIYXNodGFibGU8U3RyaW5nLCBPYmplY3Q+KCk7CgkJcHJvcHMucHV0KEh0dHBXaGl0ZWJvYXJkQ29uc3RhbnRzLkhUVFBfV0hJVEVCT0FSRF9TRVJWTEVUX1BBVFRFUk4sICIvczEvKiIpOwoJCXByb3BzLnB1dChIdHRwV2hpdGVib2FyZENvbnN0YW50cy5IVFRQX1dISVRFQk9BUkRfQ09OVEVYVF9TRUxFQ1QsICIoIiArIEh0dHBXaGl0ZWJvYXJkQ29uc3RhbnRzLkhUVFBfV0hJVEVCT0FSRF9DT05URVhUX05BTUUgKyAiPWMxKSIpOwoJCXJlZ2lzdHJhdGlvbnMuYWRkKGdldEJ1bmRsZUNvbnRleHQoKS5yZWdpc3RlclNlcnZpY2UoU2VydmxldC5jbGFzcywgc2VydmxldDEsIHByb3BzKSk7CgoJCXByb3BzID0gbmV3IEhhc2h0YWJsZTxTdHJpbmcsIE9iamVjdD4oKTsKCQlwcm9wcy5wdXQoSHR0cFdoaXRlYm9hcmRDb25zdGFudHMuSFRUUF9XSElURUJPQVJEX1NFUlZMRVRfUEFUVEVSTiwgIi9zMi8qIik7CgkJcHJvcHMucHV0KEh0dHBXaGl0ZWJvYXJkQ29uc3RhbnRzLkhUVFBfV0hJVEVCT0FSRF9DT05URVhUX1NFTEVDVCwgIigiICsgSHR0cFdoaXRlYm9hcmRDb25zdGFudHMuSFRUUF9XSElURUJPQVJEX0NPTlRFWFRfTkFNRSArICI9YzEpIik7CgkJcmVnaXN0cmF0aW9ucy5hZGQoZ2V0QnVuZGxlQ29udGV4dCgpLnJlZ2lzdGVyU2VydmljZShTZXJ2bGV0LmNsYXNzLCBzZXJ2bGV0MiwgcHJvcHMpKTsKCgkJcHJvcHMgPSBuZXcgSGFzaHRhYmxlPFN0cmluZywgT2JqZWN0PigpOwoJCXByb3BzLnB1dChIdHRwV2hpdGVib2FyZENvbnN0YW50cy5IVFRQX1dISVRFQk9BUkRfU0VSVkxFVF9QQVRURVJOLCAiL3MzLyoiKTsKCQlwcm9wcy5wdXQoSHR0cFdoaXRlYm9hcmRDb25zdGFudHMuSFRUUF9XSElURUJPQVJEX0NPTlRFWFRfU0VMRUNULCAiKCIgKyBIdHRwV2hpdGVib2FyZENvbnN0YW50cy5IVFRQX1dISVRFQk9BUkRfQ09OVEVYVF9OQU1FICsgIj1jMSkiKTsKCQlyZWdpc3RyYXRpb25zLmFkZChnZXRCdW5kbGVDb250ZXh0KCkucmVnaXN0ZXJTZXJ2aWNlKFNlcnZsZXQuY2xhc3MsIHNlcnZsZXQzLCBwcm9wcykpOwoKCQlwcm9wcyA9IG5ldyBIYXNodGFibGU8U3RyaW5nLCBPYmplY3Q+KCk7CgkJcHJvcHMucHV0KEh0dHBXaGl0ZWJvYXJkQ29uc3RhbnRzLkhUVFBfV0hJVEVCT0FSRF9TRVJWTEVUX1BBVFRFUk4sICIvczQvKiIpOwoJCXByb3BzLnB1dChIdHRwV2hpdGVib2FyZENvbnN0YW50cy5IVFRQX1dISVRFQk9BUkRfQ09OVEVYVF9TRUxFQ1QsICIoIiArIEh0dHBXaGl0ZWJvYXJkQ29uc3RhbnRzLkhUVFBfV0hJVEVCT0FSRF9DT05URVhUX05BTUUgKyAiPWMxKSIpOwoJCXJlZ2lzdHJhdGlvbnMuYWRkKGdldEJ1bmRsZUNvbnRleHQoKS5yZWdpc3RlclNlcnZpY2UoU2VydmxldC5jbGFzcywgbmV3IERpc3BhdGNoUmVzdWx0U2VydmxldCgpLCBwcm9wcykpOwoKCQlTdHJpbmcgcmVzcG9uc2UgPSByZXF1ZXN0QWR2aXNvci5yZXF1ZXN0KCJjMS9zMS9pMT9wMT0xIik7CgoJCUFzc2VydC5hc3NlcnRFcXVhbHMoIi9jMXwvaTR8cDQ9NHwvYzEvczQvaTR8L3M0fC9jMXwvaTF8cDE9MXwvYzEvczEvaTF8L3MxIiwgcmVzcG9uc2UpOwoJfQoKCUBUZXN0CglwdWJsaWMgdm9pZCB0ZXN0X2ZvcndhcmROYW1lZFBhcmFtZXRlckFnZ3JlZ2F0aW9uQW5kUHJlY2VkZW5jZSgpIHRocm93cyBFeGNlcHRpb24gewoJCVNlcnZsZXQgc0EgPSBuZXcgSHR0cFNlcnZsZXQoKSB7CgkJCXByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDFMOwoKCQkJQE92ZXJyaWRlCgkJCXByb3RlY3RlZCB2b2lkIGRvR2V0KAoJCQkJSHR0cFNlcnZsZXRSZXF1ZXN0IHJlcSwgSHR0cFNlcnZsZXRSZXNwb25zZSByZXNwKQoJCQkJdGhyb3dzIFNlcnZsZXRFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKCgkJCQlTZXJ2bGV0Q29udGV4dCBzZXJ2bGV0Q29udGV4dCA9IGdldFNlcnZsZXRDb250ZXh0KCk7CgoJCQkJUmVxdWVzdERpc3BhdGNoZXIgcmVxdWVzdERpc3BhdGNoZXIgPSBzZXJ2bGV0Q29udGV4dC5nZXROYW1lZERpc3BhdGNoZXIoInMyIik7CgoJCQkJcmVxdWVzdERpc3BhdGNoZXIuZm9yd2FyZChyZXEsIHJlc3ApOwoJCQl9CgkJfTsKCQlTZXJ2bGV0IHNCID0gbmV3IEh0dHBTZXJ2bGV0KCkgewoJCQlwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAxTDsKCgkJCUBPdmVycmlkZQoJCQlwcm90ZWN0ZWQgdm9pZCBkb0dldCgKCQkJCUh0dHBTZXJ2bGV0UmVxdWVzdCByZXEsIEh0dHBTZXJ2bGV0UmVzcG9uc2UgcmVzcCkKCQkJCXRocm93cyBTZXJ2bGV0RXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CgoJCQkJUHJpbnRXcml0ZXIgd3JpdGVyID0gcmVzcC5nZXRXcml0ZXIoKTsKCQkJCXdyaXRlci53cml0ZShTdHJpbmcudmFsdWVPZihyZXEuZ2V0UXVlcnlTdHJpbmcoKSkpOwoJCQkJd3JpdGVyLndyaXRlKCJ8Iik7CgkJCQl3cml0ZXIud3JpdGUoU3RyaW5nLnZhbHVlT2YocmVxLmdldEF0dHJpYnV0ZShSZXF1ZXN0RGlzcGF0Y2hlci5JTkNMVURFX1FVRVJZX1NUUklORykpKTsKCQkJCXdyaXRlci53cml0ZSgifCIpOwoJCQkJd3JpdGVyLndyaXRlKHJlcS5nZXRQYXJhbWV0ZXIoInAiKSk7CgkJCQl3cml0ZXIud3JpdGUoInwiKTsKCQkJCXdyaXRlci53cml0ZShBcnJheXMudG9TdHJpbmcocmVxLmdldFBhcmFtZXRlclZhbHVlcygicCIpKSk7CgkJCX0KCQl9OwoKCQlEaWN0aW9uYXJ5PFN0cmluZywgT2JqZWN0PiBwcm9wcyA9IG5ldyBIYXNodGFibGU8U3RyaW5nLCBPYmplY3Q+KCk7CgkJcHJvcHMucHV0KEh0dHBXaGl0ZWJvYXJkQ29uc3RhbnRzLkhUVFBfV0hJVEVCT0FSRF9DT05URVhUX05BTUUsICJjMSIpOwoJCXByb3BzLnB1dChIdHRwV2hpdGVib2FyZENvbnN0YW50cy5IVFRQX1dISVRFQk9BUkRfQ09OVEVYVF9QQVRILCAiL2MxIik7CgkJcmVnaXN0cmF0aW9ucy5hZGQoZ2V0QnVuZGxlQ29udGV4dCgpLnJlZ2lzdGVyU2VydmljZShTZXJ2bGV0Q29udGV4dEhlbHBlci5jbGFzcywgbmV3IFNlcnZsZXRDb250ZXh0SGVscGVyKCkge30sIHByb3BzKSk7CgoJCXByb3BzID0gbmV3IEhhc2h0YWJsZTxTdHJpbmcsIE9iamVjdD4oKTsKCQlwcm9wcy5wdXQoSHR0cFdoaXRlYm9hcmRDb25zdGFudHMuSFRUUF9XSElURUJPQVJEX1NFUlZMRVRfTkFNRSwgInMxIik7CgkJcHJvcHMucHV0KEh0dHBXaGl0ZWJvYXJkQ29uc3RhbnRzLkhUVFBfV0hJVEVCT0FSRF9DT05URVhUX1NFTEVDVCwgIigiICsgSHR0cFdoaXRlYm9hcmRDb25zdGFudHMuSFRUUF9XSElURUJPQVJEX0NPTlRFWFRfTkFNRSArICI9YzEpIik7CgkJcHJvcHMucHV0KEh0dHBXaGl0ZWJvYXJkQ29uc3RhbnRzLkhUVFBfV0hJVEVCT0FSRF9TRVJWTEVUX1BBVFRFUk4sICIvczEvKiIpOwoJCXJlZ2lzdHJhdGlvbnMuYWRkKGdldEJ1bmRsZUNvbnRleHQoKS5yZWdpc3RlclNlcnZpY2UoU2VydmxldC5jbGFzcywgc0EsIHByb3BzKSk7CgoJCXByb3BzID0gbmV3IEhhc2h0YWJsZTxTdHJpbmcsIE9iamVjdD4oKTsKCQlwcm9wcy5wdXQoSHR0cFdoaXRlYm9hcmRDb25zdGFudHMuSFRUUF9XSElURUJPQVJEX1NFUlZMRVRfTkFNRSwgInMyIik7CgkJcHJvcHMucHV0KEh0dHBXaGl0ZWJvYXJkQ29uc3RhbnRzLkhUVFBfV0hJVEVCT0FSRF9DT05URVhUX1NFTEVDVCwgIigiICsgSHR0cFdoaXRlYm9hcmRDb25zdGFudHMuSFRUUF9XSElURUJPQVJEX0NPTlRFWFRfTkFNRSArICI9YzEpIik7CgkJcHJvcHMucHV0KEh0dHBXaGl0ZWJvYXJkQ29uc3RhbnRzLkhUVFBfV0hJVEVCT0FSRF9TRVJWTEVUX1BBVFRFUk4sICIvczIvKiIpOwoJCXJlZ2lzdHJhdGlvbnMuYWRkKGdldEJ1bmRsZUNvbnRleHQoKS5yZWdpc3RlclNlcnZpY2UoU2VydmxldC5jbGFzcywgc0IsIHByb3BzKSk7CgoJCVN0cmluZyByZXN1bHQgPSByZXF1ZXN0QWR2aXNvci5yZXF1ZXN0KCJjMS9zMS9hP3A9MSZwPTIiKTsKCgkJQXNzZXJ0LmFzc2VydEVxdWFscygicD0xJnA9MnxudWxsfDF8WzEsIDJdIiwgcmVzdWx0KTsKCX0KCglAVGVzdAoJcHVibGljIHZvaWQgdGVzdF9mb3J3YXJkTmFtZWQoKSB0aHJvd3MgRXhjZXB0aW9uIHsKCQlTZXJ2bGV0IHNBID0gbmV3IEh0dHBTZXJ2bGV0KCkgewoJCQlwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAxTDsKCgkJCUBPdmVycmlkZQoJCQlwcm90ZWN0ZWQgdm9pZCBkb0dldCgKCQkJCUh0dHBTZXJ2bGV0UmVxdWVzdCByZXEsIEh0dHBTZXJ2bGV0UmVzcG9uc2UgcmVzcCkKCQkJCXRocm93cyBTZXJ2bGV0RXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CgoJCQkJU2VydmxldENvbnRleHQgc2VydmxldENvbnRleHQgPSBnZXRTZXJ2bGV0Q29udGV4dCgpOwoKCQkJCVJlcXVlc3REaXNwYXRjaGVyIHJlcXVlc3REaXNwYXRjaGVyID0gc2VydmxldENvbnRleHQuZ2V0TmFtZWREaXNwYXRjaGVyKCJzMiIpOwoKCQkJCXJlcXVlc3REaXNwYXRjaGVyLmZvcndhcmQocmVxLCByZXNwKTsKCQkJfQoJCX07CgoJCURpY3Rpb25hcnk8U3RyaW5nLCBPYmplY3Q+IHByb3BzID0gbmV3IEhhc2h0YWJsZTxTdHJpbmcsIE9iamVjdD4oKTsKCQlwcm9wcy5wdXQoSHR0cFdoaXRlYm9hcmRDb25zdGFudHMuSFRUUF9XSElURUJPQVJEX0NPTlRFWFRfTkFNRSwgImMxIik7CgkJcHJvcHMucHV0KEh0dHBXaGl0ZWJvYXJkQ29uc3RhbnRzLkhUVFBfV0hJVEVCT0FSRF9DT05URVhUX1BBVEgsICIvYzEiKTsKCQlyZWdpc3RyYXRpb25zLmFkZChnZXRCdW5kbGVDb250ZXh0KCkucmVnaXN0ZXJTZXJ2aWNlKFNlcnZsZXRDb250ZXh0SGVscGVyLmNsYXNzLCBuZXcgU2VydmxldENvbnRleHRIZWxwZXIoKSB7fSwgcHJvcHMpKTsKCgkJcHJvcHMgPSBuZXcgSGFzaHRhYmxlPFN0cmluZywgT2JqZWN0PigpOwoJCXByb3BzLnB1dChIdHRwV2hpdGVib2FyZENvbnN0YW50cy5IVFRQX1dISVRFQk9BUkRfU0VSVkxFVF9OQU1FLCAiczEiKTsKCQlwcm9wcy5wdXQoSHR0cFdoaXRlYm9hcmRDb25zdGFudHMuSFRUUF9XSElURUJPQVJEX0NPTlRFWFRfU0VMRUNULCAiKCIgKyBIdHRwV2hpdGVib2FyZENvbnN0YW50cy5IVFRQX1dISVRFQk9BUkRfQ09OVEVYVF9OQU1FICsgIj1jMSkiKTsKCQlwcm9wcy5wdXQoSHR0cFdoaXRlYm9hcmRDb25zdGFudHMuSFRUUF9XSElURUJPQVJEX1NFUlZMRVRfUEFUVEVSTiwgIi9zMS8qIik7CgkJcmVnaXN0cmF0aW9ucy5hZGQoZ2V0QnVuZGxlQ29udGV4dCgpLnJlZ2lzdGVyU2VydmljZShTZXJ2bGV0LmNsYXNzLCBzQSwgcHJvcHMpKTsKCgkJcHJvcHMgPSBuZXcgSGFzaHRhYmxlPFN0cmluZywgT2JqZWN0PigpOwoJCXByb3BzLnB1dChIdHRwV2hpdGVib2FyZENvbnN0YW50cy5IVFRQX1dISVRFQk9BUkRfU0VSVkxFVF9OQU1FLCAiczIiKTsKCQlwcm9wcy5wdXQoSHR0cFdoaXRlYm9hcmRDb25zdGFudHMuSFRUUF9XSElURUJPQVJEX0NPTlRFWFRfU0VMRUNULCAiKCIgKyBIdHRwV2hpdGVib2FyZENvbnN0YW50cy5IVFRQX1dISVRFQk9BUkRfQ09OVEVYVF9OQU1FICsgIj1jMSkiKTsKCQlwcm9wcy5wdXQoSHR0cFdoaXRlYm9hcmRDb25zdGFudHMuSFRUUF9XSElURUJPQVJEX1NFUlZMRVRfUEFUVEVSTiwgIi9zMi8qIik7CgkJcmVnaXN0cmF0aW9ucy5hZGQoZ2V0QnVuZGxlQ29udGV4dCgpLnJlZ2lzdGVyU2VydmljZShTZXJ2bGV0LmNsYXNzLCBuZXcgRGlzcGF0Y2hSZXN1bHRTZXJ2bGV0KCksIHByb3BzKSk7CgoJCVN0cmluZyByZXN1bHQgPSByZXF1ZXN0QWR2aXNvci5yZXF1ZXN0KCJjMS9zMS9hP3A9MSZwPTIiKTsKCgkJQXNzZXJ0LmFzc2VydEVxdWFscygiL2MxfC9hfHA9MSZwPTJ8L2MxL3MxL2F8L3MxfG51bGx8bnVsbHxudWxsfG51bGx8bnVsbCIsIHJlc3VsdCk7Cgl9CgoJQFRlc3QKCXB1YmxpYyB2b2lkIHRlc3RfZm9yd2FyZFBhcmFtZXRlckFnZ3JlZ2F0aW9uQW5kUHJlY2VkZW5jZSgpIHRocm93cyBFeGNlcHRpb24gewoJCVNlcnZsZXQgc0EgPSBuZXcgSHR0cFNlcnZsZXQoKSB7CgkJCXByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDFMOwoKCQkJQE92ZXJyaWRlCgkJCXByb3RlY3RlZCB2b2lkIGRvR2V0KAoJCQkJSHR0cFNlcnZsZXRSZXF1ZXN0IHJlcSwgSHR0cFNlcnZsZXRSZXNwb25zZSByZXNwKQoJCQkJdGhyb3dzIFNlcnZsZXRFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKCgkJCQlSZXF1ZXN0RGlzcGF0Y2hlciByZXF1ZXN0RGlzcGF0Y2hlciA9IHJlcS5nZXRSZXF1ZXN0RGlzcGF0Y2hlcigiL1NlcnZsZXQxM0IvYT9wPTMmcD00Iik7CgoJCQkJcmVxdWVzdERpc3BhdGNoZXIuZm9yd2FyZChyZXEsIHJlc3ApOwoJCQl9CgkJfTsKCQlTZXJ2bGV0IHNCID0gbmV3IEh0dHBTZXJ2bGV0KCkgewoJCQlwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAxTDsKCgkJCUBPdmVycmlkZQoJCQlwcm90ZWN0ZWQgdm9pZCBkb0dldCgKCQkJCUh0dHBTZXJ2bGV0UmVxdWVzdCByZXEsIEh0dHBTZXJ2bGV0UmVzcG9uc2UgcmVzcCkKCQkJCXRocm93cyBTZXJ2bGV0RXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CgoJCQkJUHJpbnRXcml0ZXIgd3JpdGVyID0gcmVzcC5nZXRXcml0ZXIoKTsKCQkJCXdyaXRlci53cml0ZShyZXEuZ2V0UXVlcnlTdHJpbmcoKSk7CgkJCQl3cml0ZXIud3JpdGUoInwiKTsKCQkJCXdyaXRlci53cml0ZSgoU3RyaW5nKXJlcS5nZXRBdHRyaWJ1dGUoUmVxdWVzdERpc3BhdGNoZXIuRk9SV0FSRF9RVUVSWV9TVFJJTkcpKTsKCQkJCXdyaXRlci53cml0ZSgifCIpOwoJCQkJd3JpdGVyLndyaXRlKHJlcS5nZXRQYXJhbWV0ZXIoInAiKSk7CgkJCQl3cml0ZXIud3JpdGUoInwiKTsKCQkJCXdyaXRlci53cml0ZShBcnJheXMudG9TdHJpbmcocmVxLmdldFBhcmFtZXRlclZhbHVlcygicCIpKSk7CgkJCX0KCQl9OwoKCQlEaWN0aW9uYXJ5PFN0cmluZywgT2JqZWN0PiBwcm9wcyA9IG5ldyBIYXNodGFibGU8U3RyaW5nLCBPYmplY3Q+KCk7CgkJcHJvcHMucHV0KEh0dHBXaGl0ZWJvYXJkQ29uc3RhbnRzLkhUVFBfV0hJVEVCT0FSRF9TRVJWTEVUX05BTUUsICJTMTNBIik7CgkJcHJvcHMucHV0KEh0dHBXaGl0ZWJvYXJkQ29uc3RhbnRzLkhUVFBfV0hJVEVCT0FSRF9TRVJWTEVUX1BBVFRFUk4sICIvU2VydmxldDEzQS8qIik7CgkJcmVnaXN0cmF0aW9ucy5hZGQoZ2V0QnVuZGxlQ29udGV4dCgpLnJlZ2lzdGVyU2VydmljZShTZXJ2bGV0LmNsYXNzLCBzQSwgcHJvcHMpKTsKCgkJcHJvcHMgPSBuZXcgSGFzaHRhYmxlPFN0cmluZywgT2JqZWN0PigpOwoJCXByb3BzLnB1dChIdHRwV2hpdGVib2FyZENvbnN0YW50cy5IVFRQX1dISVRFQk9BUkRfU0VSVkxFVF9OQU1FLCAiUzEzQiIpOwoJCXByb3BzLnB1dChIdHRwV2hpdGVib2FyZENvbnN0YW50cy5IVFRQX1dISVRFQk9BUkRfU0VSVkxFVF9QQVRURVJOLCAiL1NlcnZsZXQxM0IvKiIpOwoJCXJlZ2lzdHJhdGlvbnMuYWRkKGdldEJ1bmRsZUNvbnRleHQoKS5yZWdpc3RlclNlcnZpY2UoU2VydmxldC5jbGFzcywgc0IsIHByb3BzKSk7CgoJCVN0cmluZyByZXN1bHQgPSByZXF1ZXN0QWR2aXNvci5yZXF1ZXN0KCJTZXJ2bGV0MTNBL2E/cD0xJnA9MiIpOwoKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJwPTMmcD00fHA9MSZwPTJ8M3xbMywgNCwgMSwgMl0iLCByZXN1bHQpOwoJfQoKCUBUZXN0CglwdWJsaWMgdm9pZCB0ZXN0X2ZvcndhcmRTdHJlYW1lZCgpIHRocm93cyBFeGNlcHRpb24gewoJCVNlcnZsZXQgc2VydmxldDEgPSBuZXcgQmFzZVNlcnZsZXQoKSB7CgkJCXByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDFMOwoKCQkJQE92ZXJyaWRlCgkJCXByb3RlY3RlZCB2b2lkIHNlcnZpY2UoSHR0cFNlcnZsZXRSZXF1ZXN0IHJlcXVlc3QsIEh0dHBTZXJ2bGV0UmVzcG9uc2UgcmVzcG9uc2UpCgkJCQkJdGhyb3dzIFNlcnZsZXRFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKCQkJCXJlcXVlc3QuZ2V0UmVxdWVzdERpc3BhdGNoZXIoIi9zMi9iP3U9NSIpLmZvcndhcmQocmVxdWVzdCwgcmVzcG9uc2UpOwoJCQl9CgkJfTsKCgkJRGljdGlvbmFyeTxTdHJpbmcsIE9iamVjdD4gcHJvcHMgPSBuZXcgSGFzaHRhYmxlPFN0cmluZywgT2JqZWN0PigpOwoJCXByb3BzLnB1dChIdHRwV2hpdGVib2FyZENvbnN0YW50cy5IVFRQX1dISVRFQk9BUkRfQ09OVEVYVF9OQU1FLCAiYSIpOwoJCXByb3BzLnB1dChIdHRwV2hpdGVib2FyZENvbnN0YW50cy5IVFRQX1dISVRFQk9BUkRfQ09OVEVYVF9QQVRILCAiL2EiKTsKCQlyZWdpc3RyYXRpb25zLmFkZChnZXRCdW5kbGVDb250ZXh0KCkucmVnaXN0ZXJTZXJ2aWNlKFNlcnZsZXRDb250ZXh0SGVscGVyLmNsYXNzLCBuZXcgU2VydmxldENvbnRleHRIZWxwZXIoKSB7fSwgcHJvcHMpKTsKCgkJcHJvcHMgPSBuZXcgSGFzaHRhYmxlPFN0cmluZywgT2JqZWN0PigpOwoJCXByb3BzLnB1dChIdHRwV2hpdGVib2FyZENvbnN0YW50cy5IVFRQX1dISVRFQk9BUkRfU0VSVkxFVF9QQVRURVJOLCAiL3MxLyoiKTsKCQlwcm9wcy5wdXQoSHR0cFdoaXRlYm9hcmRDb25zdGFudHMuSFRUUF9XSElURUJPQVJEX0NPTlRFWFRfU0VMRUNULCAiKCIgKyBIdHRwV2hpdGVib2FyZENvbnN0YW50cy5IVFRQX1dISVRFQk9BUkRfQ09OVEVYVF9OQU1FICsgIj1hKSIpOwoJCXJlZ2lzdHJhdGlvbnMuYWRkKGdldEJ1bmRsZUNvbnRleHQoKS5yZWdpc3RlclNlcnZpY2UoU2VydmxldC5jbGFzcywgc2VydmxldDEsIHByb3BzKSk7CgoJCXByb3BzID0gbmV3IEhhc2h0YWJsZTxTdHJpbmcsIE9iamVjdD4oKTsKCQlwcm9wcy5wdXQoSHR0cFdoaXRlYm9hcmRDb25zdGFudHMuSFRUUF9XSElURUJPQVJEX1NFUlZMRVRfUEFUVEVSTiwgIi9zMi8qIik7CgkJcHJvcHMucHV0KEh0dHBXaGl0ZWJvYXJkQ29uc3RhbnRzLkhUVFBfV0hJVEVCT0FSRF9DT05URVhUX1NFTEVDVCwgIigiICsgSHR0cFdoaXRlYm9hcmRDb25zdGFudHMuSFRUUF9XSElURUJPQVJEX0NPTlRFWFRfTkFNRSArICI9YSkiKTsKCQlyZWdpc3RyYXRpb25zLmFkZChnZXRCdW5kbGVDb250ZXh0KCkucmVnaXN0ZXJTZXJ2aWNlKFNlcnZsZXQuY2xhc3MsIG5ldyBEaXNwYXRjaFJlc3VsdFNlcnZsZXQoKSwgcHJvcHMpKTsKCgkJU3RyaW5nIHJlc3BvbnNlID0gcmVxdWVzdEFkdmlzb3IucmVxdWVzdCgiYS9zMS9kP3A9MSIpOwoKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCIvYXwvYnx1PTV8L2EvczIvYnwvczJ8L2F8L2R8cD0xfC9hL3MxL2R8L3MxIiwgcmVzcG9uc2UpOwoJfQoKCUBUZXN0CglwdWJsaWMgdm9pZCB0ZXN0X2ZvcndhcmRTdHJlYW1lZF9XaXRoUmVxdWVzdEZpbHRlcigpIHRocm93cyBFeGNlcHRpb24gewoJCVNlcnZsZXQgc2VydmxldDEgPSBuZXcgQmFzZVNlcnZsZXQoKSB7CgkJCXByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDFMOwoKCQkJQE92ZXJyaWRlCgkJCXByb3RlY3RlZCB2b2lkIHNlcnZpY2UoSHR0cFNlcnZsZXRSZXF1ZXN0IHJlcXVlc3QsIEh0dHBTZXJ2bGV0UmVzcG9uc2UgcmVzcG9uc2UpCgkJCQkJdGhyb3dzIFNlcnZsZXRFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKCQkJCXJlcXVlc3QuZ2V0UmVxdWVzdERpc3BhdGNoZXIoIi9zMi9iP3U9NSIpLmZvcndhcmQocmVxdWVzdCwgcmVzcG9uc2UpOwoJCQl9CgkJfTsKCgkJVGVzdEZpbHRlciBmaWx0ZXIgPSBuZXcgVGVzdEZpbHRlcigpIHsKCgkJCUBPdmVycmlkZQoJCQlwdWJsaWMgdm9pZCBkb0ZpbHRlcigKCQkJCQlTZXJ2bGV0UmVxdWVzdCByZXF1ZXN0LCBTZXJ2bGV0UmVzcG9uc2UgcmVzcG9uc2UsIEZpbHRlckNoYWluIGNoYWluKQoJCQkJdGhyb3dzIElPRXhjZXB0aW9uLCBTZXJ2bGV0RXhjZXB0aW9uIHsKCgkJCQl3cml0ZShyZXNwb25zZS5nZXRPdXRwdXRTdHJlYW0oKSwgImIiKTsKCgkJCQlzdXBlci5kb0ZpbHRlcihyZXF1ZXN0LCByZXNwb25zZSwgY2hhaW4pOwoKCQkJCXdyaXRlKHJlc3BvbnNlLmdldE91dHB1dFN0cmVhbSgpLCAiYiIpOwoJCQl9CgoJCX07CgoJCURpY3Rpb25hcnk8U3RyaW5nLCBPYmplY3Q+IHByb3BzID0gbmV3IEhhc2h0YWJsZTxTdHJpbmcsIE9iamVjdD4oKTsKCQlwcm9wcy5wdXQoSHR0cFdoaXRlYm9hcmRDb25zdGFudHMuSFRUUF9XSElURUJPQVJEX0NPTlRFWFRfTkFNRSwgImEiKTsKCQlwcm9wcy5wdXQoSHR0cFdoaXRlYm9hcmRDb25zdGFudHMuSFRUUF9XSElURUJPQVJEX0NPTlRFWFRfUEFUSCwgIi9hIik7CgkJcmVnaXN0cmF0aW9ucy5hZGQoZ2V0QnVuZGxlQ29udGV4dCgpLnJlZ2lzdGVyU2VydmljZShTZXJ2bGV0Q29udGV4dEhlbHBlci5jbGFzcywgbmV3IFNlcnZsZXRDb250ZXh0SGVscGVyKCkge30sIHByb3BzKSk7CgoJCXByb3BzID0gbmV3IEhhc2h0YWJsZTxTdHJpbmcsIE9iamVjdD4oKTsKCQlwcm9wcy5wdXQoSHR0cFdoaXRlYm9hcmRDb25zdGFudHMuSFRUUF9XSElURUJPQVJEX1NFUlZMRVRfUEFUVEVSTiwgIi9zMS8qIik7CgkJcHJvcHMucHV0KEh0dHBXaGl0ZWJvYXJkQ29uc3RhbnRzLkhUVFBfV0hJVEVCT0FSRF9DT05URVhUX1NFTEVDVCwgIigiICsgSHR0cFdoaXRlYm9hcmRDb25zdGFudHMuSFRUUF9XSElURUJPQVJEX0NPTlRFWFRfTkFNRSArICI9YSkiKTsKCQlyZWdpc3RyYXRpb25zLmFkZChnZXRCdW5kbGVDb250ZXh0KCkucmVnaXN0ZXJTZXJ2aWNlKFNlcnZsZXQuY2xhc3MsIHNlcnZsZXQxLCBwcm9wcykpOwoKCQlwcm9wcyA9IG5ldyBIYXNodGFibGU8U3RyaW5nLCBPYmplY3Q+KCk7CgkJcHJvcHMucHV0KEh0dHBXaGl0ZWJvYXJkQ29uc3RhbnRzLkhUVFBfV0hJVEVCT0FSRF9TRVJWTEVUX1BBVFRFUk4sICIvczIvKiIpOwoJCXByb3BzLnB1dChIdHRwV2hpdGVib2FyZENvbnN0YW50cy5IVFRQX1dISVRFQk9BUkRfQ09OVEVYVF9TRUxFQ1QsICIoIiArIEh0dHBXaGl0ZWJvYXJkQ29uc3RhbnRzLkhUVFBfV0hJVEVCT0FSRF9DT05URVhUX05BTUUgKyAiPWEpIik7CgkJcmVnaXN0cmF0aW9ucy5hZGQoZ2V0QnVuZGxlQ29udGV4dCgpLnJlZ2lzdGVyU2VydmljZShTZXJ2bGV0LmNsYXNzLCBuZXcgRGlzcGF0Y2hSZXN1bHRTZXJ2bGV0KCksIHByb3BzKSk7CgoJCXByb3BzID0gbmV3IEhhc2h0YWJsZTxTdHJpbmcsIE9iamVjdD4oKTsKCQlwcm9wcy5wdXQoSHR0cFdoaXRlYm9hcmRDb25zdGFudHMuSFRUUF9XSElURUJPQVJEX0NPTlRFWFRfU0VMRUNULCAiKCIgKyBIdHRwV2hpdGVib2FyZENvbnN0YW50cy5IVFRQX1dISVRFQk9BUkRfQ09OVEVYVF9OQU1FICsgIj1hKSIpOwoJCXByb3BzLnB1dChIdHRwV2hpdGVib2FyZENvbnN0YW50cy5IVFRQX1dISVRFQk9BUkRfRklMVEVSX05BTUUsICJGMSIpOwoJCXByb3BzLnB1dChIdHRwV2hpdGVib2FyZENvbnN0YW50cy5IVFRQX1dISVRFQk9BUkRfRklMVEVSX0RJU1BBVENIRVIsIG5ldyBTdHJpbmdbXSB7RGlzcGF0Y2hlclR5cGUuUkVRVUVTVC50b1N0cmluZygpfSk7CgkJcHJvcHMucHV0KEh0dHBXaGl0ZWJvYXJkQ29uc3RhbnRzLkhUVFBfV0hJVEVCT0FSRF9GSUxURVJfUEFUVEVSTiwgIi8qIik7CgkJcmVnaXN0cmF0aW9ucy5hZGQoZ2V0QnVuZGxlQ29udGV4dCgpLnJlZ2lzdGVyU2VydmljZShGaWx0ZXIuY2xhc3MsIGZpbHRlciwgcHJvcHMpKTsKCgkJU3RyaW5nIHJlc3BvbnNlID0gcmVxdWVzdEFkdmlzb3IucmVxdWVzdCgiYS9zMS9kP3A9MSIpOwoKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCIvYXwvYnx1PTV8L2EvczIvYnwvczJ8L2F8L2R8cD0xfC9hL3MxL2R8L3MxIiwgcmVzcG9uc2UpOwoJCUFzc2VydC5hc3NlcnRUcnVlKGZpbHRlci5nZXRDYWxsZWQoKSk7Cgl9CgoJQFRlc3QKCXB1YmxpYyB2b2lkIHRlc3RfZm9yd2FyZFN0cmVhbWVkX1dpdGhSZXF1ZXN0QW5kRm9yd2FyZEZpbHRlcigpIHRocm93cyBFeGNlcHRpb24gewoJCVNlcnZsZXQgc2VydmxldDEgPSBuZXcgQmFzZVNlcnZsZXQoKSB7CgkJCXByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDFMOwoKCQkJQE92ZXJyaWRlCgkJCXByb3RlY3RlZCB2b2lkIHNlcnZpY2UoSHR0cFNlcnZsZXRSZXF1ZXN0IHJlcXVlc3QsIEh0dHBTZXJ2bGV0UmVzcG9uc2UgcmVzcG9uc2UpCgkJCQkJdGhyb3dzIFNlcnZsZXRFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKCQkJCXJlcXVlc3QuZ2V0UmVxdWVzdERpc3BhdGNoZXIoIi9zMi9iP3U9NSIpLmZvcndhcmQocmVxdWVzdCwgcmVzcG9uc2UpOwoJCQl9CgkJfTsKCgkJVGVzdEZpbHRlciBmaWx0ZXIgPSBuZXcgVGVzdEZpbHRlcigpIHsKCgkJCUBPdmVycmlkZQoJCQlwdWJsaWMgdm9pZCBkb0ZpbHRlcigKCQkJCQlTZXJ2bGV0UmVxdWVzdCByZXF1ZXN0LCBTZXJ2bGV0UmVzcG9uc2UgcmVzcG9uc2UsIEZpbHRlckNoYWluIGNoYWluKQoJCQkJdGhyb3dzIElPRXhjZXB0aW9uLCBTZXJ2bGV0RXhjZXB0aW9uIHsKCgkJCQl3cml0ZShyZXNwb25zZS5nZXRPdXRwdXRTdHJlYW0oKSwgImIiKTsKCgkJCQlzdXBlci5kb0ZpbHRlcihyZXF1ZXN0LCByZXNwb25zZSwgY2hhaW4pOwoKCQkJCXdyaXRlKHJlc3BvbnNlLmdldE91dHB1dFN0cmVhbSgpLCAiYiIpOwoJCQl9CgoJCX07CgoJCURpY3Rpb25hcnk8U3RyaW5nLCBPYmplY3Q+IHByb3BzID0gbmV3IEhhc2h0YWJsZTxTdHJpbmcsIE9iamVjdD4oKTsKCQlwcm9wcy5wdXQoSHR0cFdoaXRlYm9hcmRDb25zdGFudHMuSFRUUF9XSElURUJPQVJEX0NPTlRFWFRfTkFNRSwgImEiKTsKCQlwcm9wcy5wdXQoSHR0cFdoaXRlYm9hcmRDb25zdGFudHMuSFRUUF9XSElURUJPQVJEX0NPTlRFWFRfUEFUSCwgIi9hIik7CgkJcmVnaXN0cmF0aW9ucy5hZGQoZ2V0QnVuZGxlQ29udGV4dCgpLnJlZ2lzdGVyU2VydmljZShTZXJ2bGV0Q29udGV4dEhlbHBlci5jbGFzcywgbmV3IFNlcnZsZXRDb250ZXh0SGVscGVyKCkge30sIHByb3BzKSk7CgoJCXByb3BzID0gbmV3IEhhc2h0YWJsZTxTdHJpbmcsIE9iamVjdD4oKTsKCQlwcm9wcy5wdXQoSHR0cFdoaXRlYm9hcmRDb25zdGFudHMuSFRUUF9XSElURUJPQVJEX1NFUlZMRVRfUEFUVEVSTiwgIi9zMS8qIik7CgkJcHJvcHMucHV0KEh0dHBXaGl0ZWJvYXJkQ29uc3RhbnRzLkhUVFBfV0hJVEVCT0FSRF9DT05URVhUX1NFTEVDVCwgIigiICsgSHR0cFdoaXRlYm9hcmRDb25zdGFudHMuSFRUUF9XSElURUJPQVJEX0NPTlRFWFRfTkFNRSArICI9YSkiKTsKCQlyZWdpc3RyYXRpb25zLmFkZChnZXRCdW5kbGVDb250ZXh0KCkucmVnaXN0ZXJTZXJ2aWNlKFNlcnZsZXQuY2xhc3MsIHNlcnZsZXQxLCBwcm9wcykpOwoKCQlwcm9wcyA9IG5ldyBIYXNodGFibGU8U3RyaW5nLCBPYmplY3Q+KCk7CgkJcHJvcHMucHV0KEh0dHBXaGl0ZWJvYXJkQ29uc3RhbnRzLkhUVFBfV0hJVEVCT0FSRF9TRVJWTEVUX1BBVFRFUk4sICIvczIvKiIpOwoJCXByb3BzLnB1dChIdHRwV2hpdGVib2FyZENvbnN0YW50cy5IVFRQX1dISVRFQk9BUkRfQ09OVEVYVF9TRUxFQ1QsICIoIiArIEh0dHBXaGl0ZWJvYXJkQ29uc3RhbnRzLkhUVFBfV0hJVEVCT0FSRF9DT05URVhUX05BTUUgKyAiPWEpIik7CgkJcmVnaXN0cmF0aW9ucy5hZGQoZ2V0QnVuZGxlQ29udGV4dCgpLnJlZ2lzdGVyU2VydmljZShTZXJ2bGV0LmNsYXNzLCBuZXcgRGlzcGF0Y2hSZXN1bHRTZXJ2bGV0KCksIHByb3BzKSk7CgoJCXByb3BzID0gbmV3IEhhc2h0YWJsZTxTdHJpbmcsIE9iamVjdD4oKTsKCQlwcm9wcy5wdXQoSHR0cFdoaXRlYm9hcmRDb25zdGFudHMuSFRUUF9XSElURUJPQVJEX0NPTlRFWFRfU0VMRUNULCAiKCIgKyBIdHRwV2hpdGVib2FyZENvbnN0YW50cy5IVFRQX1dISVRFQk9BUkRfQ09OVEVYVF9OQU1FICsgIj1hKSIpOwoJCXByb3BzLnB1dChIdHRwV2hpdGVib2FyZENvbnN0YW50cy5IVFRQX1dISVRFQk9BUkRfRklMVEVSX05BTUUsICJGMSIpOwoJCXByb3BzLnB1dChIdHRwV2hpdGVib2FyZENvbnN0YW50cy5IVFRQX1dISVRFQk9BUkRfRklMVEVSX0RJU1BBVENIRVIsIG5ldyBTdHJpbmdbXSB7RGlzcGF0Y2hlclR5cGUuRk9SV0FSRC50b1N0cmluZygpLERpc3BhdGNoZXJUeXBlLlJFUVVFU1QudG9TdHJpbmcoKX0pOwoJCXByb3BzLnB1dChIdHRwV2hpdGVib2FyZENvbnN0YW50cy5IVFRQX1dISVRFQk9BUkRfRklMVEVSX1BBVFRFUk4sICIvKiIpOwoJCXJlZ2lzdHJhdGlvbnMuYWRkKGdldEJ1bmRsZUNvbnRleHQoKS5yZWdpc3RlclNlcnZpY2UoRmlsdGVyLmNsYXNzLCBmaWx0ZXIsIHByb3BzKSk7CgoJCVN0cmluZyByZXNwb25zZSA9IHJlcXVlc3RBZHZpc29yLnJlcXVlc3QoImEvczEvZD9wPTEiKTsKCgkJQXNzZXJ0LmFzc2VydEVxdWFscygiYi9hfC9ifHU9NXwvYS9zMi9ifC9zMnwvYXwvZHxwPTF8L2EvczEvZHwvczFiIiwgcmVzcG9uc2UpOwoJCUFzc2VydC5hc3NlcnRFcXVhbHMoMiwgZmlsdGVyLmdldENvdW50KCkpOwoJfQoKCUBUZXN0CglwdWJsaWMgdm9pZCB0ZXN0X2luY2x1ZGVCYXNpYygpIHRocm93cyBFeGNlcHRpb24gewoJCVNlcnZsZXQgc2VydmxldDggPSBuZXcgSHR0cFNlcnZsZXQoKSB7CgkJCXByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDFMOwoKCQkJQE92ZXJyaWRlCgkJCXByb3RlY3RlZCB2b2lkIHNlcnZpY2UoSHR0cFNlcnZsZXRSZXF1ZXN0IHJlcXVlc3QsIEh0dHBTZXJ2bGV0UmVzcG9uc2UgcmVzcG9uc2UpCgkJCQl0aHJvd3MgU2VydmxldEV4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewoKCQkJCVJlcXVlc3REaXNwYXRjaGVyIHJlcXVlc3REaXNwYXRjaGVyID0KCQkJCQlyZXF1ZXN0LmdldFJlcXVlc3REaXNwYXRjaGVyKCIvUzgvdGFyZ2V0Iik7CgoJCQkJcmVxdWVzdERpc3BhdGNoZXIuaW5jbHVkZShyZXF1ZXN0LCByZXNwb25zZSk7CgkJCX0KCgkJfTsKCgkJU2VydmxldCBzZXJ2bGV0OFRhcmdldCA9IG5ldyBIdHRwU2VydmxldCgpIHsKCQkJcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMUw7CgoJCQlAT3ZlcnJpZGUKCQkJcHJvdGVjdGVkIHZvaWQgc2VydmljZShIdHRwU2VydmxldFJlcXVlc3QgcmVxdWVzdCwgSHR0cFNlcnZsZXRSZXNwb25zZSByZXNwb25zZSkKCQkJCXRocm93cyBTZXJ2bGV0RXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CgoJCQkJcmVzcG9uc2UuZ2V0V3JpdGVyKCkucHJpbnQoInM4dGFyZ2V0Iik7CgkJCX0KCgkJfTsKCgkJSHR0cFNlcnZpY2UgaHR0cFNlcnZpY2UgPSBnZXRIdHRwU2VydmljZSgpOwoKCQlIdHRwQ29udGV4dCBodHRwQ29udGV4dCA9IGh0dHBTZXJ2aWNlLmNyZWF0ZURlZmF1bHRIdHRwQ29udGV4dCgpOwoKCQlodHRwU2VydmljZS5yZWdpc3RlclNlcnZsZXQoIi9TOCIsIHNlcnZsZXQ4LCBudWxsLCBodHRwQ29udGV4dCk7CgkJaHR0cFNlcnZpY2UucmVnaXN0ZXJTZXJ2bGV0KCIvUzgvdGFyZ2V0Iiwgc2VydmxldDhUYXJnZXQsIG51bGwsIGh0dHBDb250ZXh0KTsKCgkJQXNzZXJ0LmFzc2VydEVxdWFscygiczh0YXJnZXQiLCByZXF1ZXN0QWR2aXNvci5yZXF1ZXN0KCJTOCIpKTsKCX0KCglAVGVzdAoJcHVibGljIHZvaWQgdGVzdF9pbmNsdWRlRGVwdGgxKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CgkJU2VydmxldCBzZXJ2bGV0MSA9IG5ldyBCYXNlU2VydmxldCgpIHsKCQkJcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMUw7CgoJCQlAT3ZlcnJpZGUKCQkJcHJvdGVjdGVkIHZvaWQgc2VydmljZShIdHRwU2VydmxldFJlcXVlc3QgcmVxdWVzdCwgSHR0cFNlcnZsZXRSZXNwb25zZSByZXNwb25zZSkKCQkJCQl0aHJvd3MgU2VydmxldEV4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewoJCQkJcmVxdWVzdC5nZXRSZXF1ZXN0RGlzcGF0Y2hlcigiL3MyL2I/dT01IikuaW5jbHVkZShyZXF1ZXN0LCByZXNwb25zZSk7CgkJCX0KCQl9OwoKCQlEaWN0aW9uYXJ5PFN0cmluZywgT2JqZWN0PiBwcm9wcyA9IG5ldyBIYXNodGFibGU8U3RyaW5nLCBPYmplY3Q+KCk7CgkJcHJvcHMucHV0KEh0dHBXaGl0ZWJvYXJkQ29uc3RhbnRzLkhUVFBfV0hJVEVCT0FSRF9DT05URVhUX05BTUUsICJhIik7CgkJcHJvcHMucHV0KEh0dHBXaGl0ZWJvYXJkQ29uc3RhbnRzLkhUVFBfV0hJVEVCT0FSRF9DT05URVhUX1BBVEgsICIvYSIpOwoJCXJlZ2lzdHJhdGlvbnMuYWRkKGdldEJ1bmRsZUNvbnRleHQoKS5yZWdpc3RlclNlcnZpY2UoU2VydmxldENvbnRleHRIZWxwZXIuY2xhc3MsIG5ldyBTZXJ2bGV0Q29udGV4dEhlbHBlcigpIHt9LCBwcm9wcykpOwoKCQlwcm9wcyA9IG5ldyBIYXNodGFibGU8U3RyaW5nLCBPYmplY3Q+KCk7CgkJcHJvcHMucHV0KEh0dHBXaGl0ZWJvYXJkQ29uc3RhbnRzLkhUVFBfV0hJVEVCT0FSRF9TRVJWTEVUX1BBVFRFUk4sICIvczEvKiIpOwoJCXByb3BzLnB1dChIdHRwV2hpdGVib2FyZENvbnN0YW50cy5IVFRQX1dISVRFQk9BUkRfQ09OVEVYVF9TRUxFQ1QsICIoIiArIEh0dHBXaGl0ZWJvYXJkQ29uc3RhbnRzLkhUVFBfV0hJVEVCT0FSRF9DT05URVhUX05BTUUgKyAiPWEpIik7CgkJcmVnaXN0cmF0aW9ucy5hZGQoZ2V0QnVuZGxlQ29udGV4dCgpLnJlZ2lzdGVyU2VydmljZShTZXJ2bGV0LmNsYXNzLCBzZXJ2bGV0MSwgcHJvcHMpKTsKCgkJcHJvcHMgPSBuZXcgSGFzaHRhYmxlPFN0cmluZywgT2JqZWN0PigpOwoJCXByb3BzLnB1dChIdHRwV2hpdGVib2FyZENvbnN0YW50cy5IVFRQX1dISVRFQk9BUkRfU0VSVkxFVF9QQVRURVJOLCAiL3MyLyoiKTsKCQlwcm9wcy5wdXQoSHR0cFdoaXRlYm9hcmRDb25zdGFudHMuSFRUUF9XSElURUJPQVJEX0NPTlRFWFRfU0VMRUNULCAiKCIgKyBIdHRwV2hpdGVib2FyZENvbnN0YW50cy5IVFRQX1dISVRFQk9BUkRfQ09OVEVYVF9OQU1FICsgIj1hKSIpOwoJCXJlZ2lzdHJhdGlvbnMuYWRkKGdldEJ1bmRsZUNvbnRleHQoKS5yZWdpc3RlclNlcnZpY2UoU2VydmxldC5jbGFzcywgbmV3IERpc3BhdGNoUmVzdWx0U2VydmxldCgpLCBwcm9wcykpOwoKCQlTdHJpbmcgcmVzcG9uc2UgPSByZXF1ZXN0QWR2aXNvci5yZXF1ZXN0KCJhL3MxL2Q/cD0xIik7CgoJCUFzc2VydC5hc3NlcnRFcXVhbHMoIi9hfC9kfHA9MXwvYS9zMS9kfC9zMXwvYXwvYnx1PTV8L2EvczIvYnwvczIiLCByZXNwb25zZSk7Cgl9CgoJQFRlc3QKCXB1YmxpYyB2b2lkIHRlc3RfaW5jbHVkZURlcHRoMV9XaXRoUmVxdWVzdEZpbHRlcigpIHRocm93cyBFeGNlcHRpb24gewoJCVNlcnZsZXQgc2VydmxldDEgPSBuZXcgQmFzZVNlcnZsZXQoKSB7CgkJCXByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDFMOwoKCQkJQE92ZXJyaWRlCgkJCXByb3RlY3RlZCB2b2lkIHNlcnZpY2UoSHR0cFNlcnZsZXRSZXF1ZXN0IHJlcXVlc3QsIEh0dHBTZXJ2bGV0UmVzcG9uc2UgcmVzcG9uc2UpCgkJCQkJdGhyb3dzIFNlcnZsZXRFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKCQkJCXJlcXVlc3QuZ2V0UmVxdWVzdERpc3BhdGNoZXIoIi9zMi9iP3U9NSIpLmluY2x1ZGUocmVxdWVzdCwgcmVzcG9uc2UpOwoJCQl9CgkJfTsKCgkJVGVzdEZpbHRlciBmaWx0ZXIgPSBuZXcgVGVzdEZpbHRlcigpIHsKCgkJCUBPdmVycmlkZQoJCQlwdWJsaWMgdm9pZCBkb0ZpbHRlcigKCQkJCQlTZXJ2bGV0UmVxdWVzdCByZXF1ZXN0LCBTZXJ2bGV0UmVzcG9uc2UgcmVzcG9uc2UsIEZpbHRlckNoYWluIGNoYWluKQoJCQkJdGhyb3dzIElPRXhjZXB0aW9uLCBTZXJ2bGV0RXhjZXB0aW9uIHsKCgkJCQlyZXNwb25zZS5nZXRXcml0ZXIoKS53cml0ZSgnYicpOwoKCQkJCXN1cGVyLmRvRmlsdGVyKHJlcXVlc3QsIHJlc3BvbnNlLCBjaGFpbik7CgoJCQkJcmVzcG9uc2UuZ2V0V3JpdGVyKCkud3JpdGUoJ2InKTsKCQkJfQoKCQl9OwoKCQlEaWN0aW9uYXJ5PFN0cmluZywgT2JqZWN0PiBwcm9wcyA9IG5ldyBIYXNodGFibGU8U3RyaW5nLCBPYmplY3Q+KCk7CgkJcHJvcHMucHV0KEh0dHBXaGl0ZWJvYXJkQ29uc3RhbnRzLkhUVFBfV0hJVEVCT0FSRF9DT05URVhUX05BTUUsICJhIik7CgkJcHJvcHMucHV0KEh0dHBXaGl0ZWJvYXJkQ29uc3RhbnRzLkhUVFBfV0hJVEVCT0FSRF9DT05URVhUX1BBVEgsICIvYSIpOwoJCXJlZ2lzdHJhdGlvbnMuYWRkKGdldEJ1bmRsZUNvbnRleHQoKS5yZWdpc3RlclNlcnZpY2UoU2VydmxldENvbnRleHRIZWxwZXIuY2xhc3MsIG5ldyBTZXJ2bGV0Q29udGV4dEhlbHBlcigpIHt9LCBwcm9wcykpOwoKCQlwcm9wcyA9IG5ldyBIYXNodGFibGU8U3RyaW5nLCBPYmplY3Q+KCk7CgkJcHJvcHMucHV0KEh0dHBXaGl0ZWJvYXJkQ29uc3RhbnRzLkhUVFBfV0hJVEVCT0FSRF9TRVJWTEVUX1BBVFRFUk4sICIvczEvKiIpOwoJCXByb3BzLnB1dChIdHRwV2hpdGVib2FyZENvbnN0YW50cy5IVFRQX1dISVRFQk9BUkRfQ09OVEVYVF9TRUxFQ1QsICIoIiArIEh0dHBXaGl0ZWJvYXJkQ29uc3RhbnRzLkhUVFBfV0hJVEVCT0FSRF9DT05URVhUX05BTUUgKyAiPWEpIik7CgkJcmVnaXN0cmF0aW9ucy5hZGQoZ2V0QnVuZGxlQ29udGV4dCgpLnJlZ2lzdGVyU2VydmljZShTZXJ2bGV0LmNsYXNzLCBzZXJ2bGV0MSwgcHJvcHMpKTsKCgkJcHJvcHMgPSBuZXcgSGFzaHRhYmxlPFN0cmluZywgT2JqZWN0PigpOwoJCXByb3BzLnB1dChIdHRwV2hpdGVib2FyZENvbnN0YW50cy5IVFRQX1dISVRFQk9BUkRfU0VSVkxFVF9QQVRURVJOLCAiL3MyLyoiKTsKCQlwcm9wcy5wdXQoSHR0cFdoaXRlYm9hcmRDb25zdGFudHMuSFRUUF9XSElURUJPQVJEX0NPTlRFWFRfU0VMRUNULCAiKCIgKyBIdHRwV2hpdGVib2FyZENvbnN0YW50cy5IVFRQX1dISVRFQk9BUkRfQ09OVEVYVF9OQU1FICsgIj1hKSIpOwoJCXJlZ2lzdHJhdGlvbnMuYWRkKGdldEJ1bmRsZUNvbnRleHQoKS5yZWdpc3RlclNlcnZpY2UoU2VydmxldC5jbGFzcywgbmV3IERpc3BhdGNoUmVzdWx0U2VydmxldCgpLCBwcm9wcykpOwoKCQlwcm9wcyA9IG5ldyBIYXNodGFibGU8U3RyaW5nLCBPYmplY3Q+KCk7CgkJcHJvcHMucHV0KEh0dHBXaGl0ZWJvYXJkQ29uc3RhbnRzLkhUVFBfV0hJVEVCT0FSRF9DT05URVhUX1NFTEVDVCwgIigiICsgSHR0cFdoaXRlYm9hcmRDb25zdGFudHMuSFRUUF9XSElURUJPQVJEX0NPTlRFWFRfTkFNRSArICI9YSkiKTsKCQlwcm9wcy5wdXQoSHR0cFdoaXRlYm9hcmRDb25zdGFudHMuSFRUUF9XSElURUJPQVJEX0ZJTFRFUl9OQU1FLCAiRjEiKTsKCQlwcm9wcy5wdXQoSHR0cFdoaXRlYm9hcmRDb25zdGFudHMuSFRUUF9XSElURUJPQVJEX0ZJTFRFUl9ESVNQQVRDSEVSLCBuZXcgU3RyaW5nW10ge0Rpc3BhdGNoZXJUeXBlLlJFUVVFU1QudG9TdHJpbmcoKX0pOwoJCXByb3BzLnB1dChIdHRwV2hpdGVib2FyZENvbnN0YW50cy5IVFRQX1dISVRFQk9BUkRfRklMVEVSX1BBVFRFUk4sICIvKiIpOwoJCXJlZ2lzdHJhdGlvbnMuYWRkKGdldEJ1bmRsZUNvbnRleHQoKS5yZWdpc3RlclNlcnZpY2UoRmlsdGVyLmNsYXNzLCBmaWx0ZXIsIHByb3BzKSk7CgoJCVN0cmluZyByZXNwb25zZSA9IHJlcXVlc3RBZHZpc29yLnJlcXVlc3QoImEvczEvZD9wPTEiKTsKCgkJQXNzZXJ0LmFzc2VydEVxdWFscygiYi9hfC9kfHA9MXwvYS9zMS9kfC9zMXwvYXwvYnx1PTV8L2EvczIvYnwvczJiIiwgcmVzcG9uc2UpOwoJCUFzc2VydC5hc3NlcnRUcnVlKGZpbHRlci5nZXRDYWxsZWQoKSk7Cgl9CgoJQFRlc3QKCXB1YmxpYyB2b2lkIHRlc3RfaW5jbHVkZURlcHRoMV9XaXRoUmVxdWVzdEFuZEluY2x1ZGVGaWx0ZXIoKSB0aHJvd3MgRXhjZXB0aW9uIHsKCQlTZXJ2bGV0IHNlcnZsZXQxID0gbmV3IEJhc2VTZXJ2bGV0KCkgewoJCQlwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAxTDsKCgkJCUBPdmVycmlkZQoJCQlwcm90ZWN0ZWQgdm9pZCBzZXJ2aWNlKEh0dHBTZXJ2bGV0UmVxdWVzdCByZXF1ZXN0LCBIdHRwU2VydmxldFJlc3BvbnNlIHJlc3BvbnNlKQoJCQkJCXRocm93cyBTZXJ2bGV0RXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CgkJCQlyZXF1ZXN0LmdldFJlcXVlc3REaXNwYXRjaGVyKCIvczIvYj91PTUiKS5pbmNsdWRlKHJlcXVlc3QsIHJlc3BvbnNlKTsKCQkJfQoJCX07CgoJCVRlc3RGaWx0ZXIgZmlsdGVyID0gbmV3IFRlc3RGaWx0ZXIoKSB7CgoJCQlAT3ZlcnJpZGUKCQkJcHVibGljIHZvaWQgZG9GaWx0ZXIoCgkJCQkJU2VydmxldFJlcXVlc3QgcmVxdWVzdCwgU2VydmxldFJlc3BvbnNlIHJlc3BvbnNlLCBGaWx0ZXJDaGFpbiBjaGFpbikKCQkJCXRocm93cyBJT0V4Y2VwdGlvbiwgU2VydmxldEV4Y2VwdGlvbiB7CgoJCQkJcmVzcG9uc2UuZ2V0V3JpdGVyKCkud3JpdGUoJ2InKTsKCgkJCQlzdXBlci5kb0ZpbHRlcihyZXF1ZXN0LCByZXNwb25zZSwgY2hhaW4pOwoKCQkJCXJlc3BvbnNlLmdldFdyaXRlcigpLndyaXRlKCdiJyk7CgkJCX0KCgkJfTsKCgkJRGljdGlvbmFyeTxTdHJpbmcsIE9iamVjdD4gcHJvcHMgPSBuZXcgSGFzaHRhYmxlPFN0cmluZywgT2JqZWN0PigpOwoJCXByb3BzLnB1dChIdHRwV2hpdGVib2FyZENvbnN0YW50cy5IVFRQX1dISVRFQk9BUkRfQ09OVEVYVF9OQU1FLCAiYSIpOwoJCXByb3BzLnB1dChIdHRwV2hpdGVib2FyZENvbnN0YW50cy5IVFRQX1dISVRFQk9BUkRfQ09OVEVYVF9QQVRILCAiL2EiKTsKCQlyZWdpc3RyYXRpb25zLmFkZChnZXRCdW5kbGVDb250ZXh0KCkucmVnaXN0ZXJTZXJ2aWNlKFNlcnZsZXRDb250ZXh0SGVscGVyLmNsYXNzLCBuZXcgU2VydmxldENvbnRleHRIZWxwZXIoKSB7fSwgcHJvcHMpKTsKCgkJcHJvcHMgPSBuZXcgSGFzaHRhYmxlPFN0cmluZywgT2JqZWN0PigpOwoJCXByb3BzLnB1dChIdHRwV2hpdGVib2FyZENvbnN0YW50cy5IVFRQX1dISVRFQk9BUkRfU0VSVkxFVF9QQVRURVJOLCAiL3MxLyoiKTsKCQlwcm9wcy5wdXQoSHR0cFdoaXRlYm9hcmRDb25zdGFudHMuSFRUUF9XSElURUJPQVJEX0NPTlRFWFRfU0VMRUNULCAiKCIgKyBIdHRwV2hpdGVib2FyZENvbnN0YW50cy5IVFRQX1dISVRFQk9BUkRfQ09OVEVYVF9OQU1FICsgIj1hKSIpOwoJCXJlZ2lzdHJhdGlvbnMuYWRkKGdldEJ1bmRsZUNvbnRleHQoKS5yZWdpc3RlclNlcnZpY2UoU2VydmxldC5jbGFzcywgc2VydmxldDEsIHByb3BzKSk7CgoJCXByb3BzID0gbmV3IEhhc2h0YWJsZTxTdHJpbmcsIE9iamVjdD4oKTsKCQlwcm9wcy5wdXQoSHR0cFdoaXRlYm9hcmRDb25zdGFudHMuSFRUUF9XSElURUJPQVJEX1NFUlZMRVRfUEFUVEVSTiwgIi9zMi8qIik7CgkJcHJvcHMucHV0KEh0dHBXaGl0ZWJvYXJkQ29uc3RhbnRzLkhUVFBfV0hJVEVCT0FSRF9DT05URVhUX1NFTEVDVCwgIigiICsgSHR0cFdoaXRlYm9hcmRDb25zdGFudHMuSFRUUF9XSElURUJPQVJEX0NPTlRFWFRfTkFNRSArICI9YSkiKTsKCQlyZWdpc3RyYXRpb25zLmFkZChnZXRCdW5kbGVDb250ZXh0KCkucmVnaXN0ZXJTZXJ2aWNlKFNlcnZsZXQuY2xhc3MsIG5ldyBEaXNwYXRjaFJlc3VsdFNlcnZsZXQoKSwgcHJvcHMpKTsKCgkJcHJvcHMgPSBuZXcgSGFzaHRhYmxlPFN0cmluZywgT2JqZWN0PigpOwoJCXByb3BzLnB1dChIdHRwV2hpdGVib2FyZENvbnN0YW50cy5IVFRQX1dISVRFQk9BUkRfQ09OVEVYVF9TRUxFQ1QsICIoIiArIEh0dHBXaGl0ZWJvYXJkQ29uc3RhbnRzLkhUVFBfV0hJVEVCT0FSRF9DT05URVhUX05BTUUgKyAiPWEpIik7CgkJcHJvcHMucHV0KEh0dHBXaGl0ZWJvYXJkQ29uc3RhbnRzLkhUVFBfV0hJVEVCT0FSRF9GSUxURVJfTkFNRSwgIkYxIik7CgkJcHJvcHMucHV0KEh0dHBXaGl0ZWJvYXJkQ29uc3RhbnRzLkhUVFBfV0hJVEVCT0FSRF9GSUxURVJfRElTUEFUQ0hFUiwgbmV3IFN0cmluZ1tdIHtEaXNwYXRjaGVyVHlwZS5JTkNMVURFLnRvU3RyaW5nKCksIERpc3BhdGNoZXJUeXBlLlJFUVVFU1QudG9TdHJpbmcoKX0pOwoJCXByb3BzLnB1dChIdHRwV2hpdGVib2FyZENvbnN0YW50cy5IVFRQX1dISVRFQk9BUkRfRklMVEVSX1BBVFRFUk4sICIvKiIpOwoJCXJlZ2lzdHJhdGlvbnMuYWRkKGdldEJ1bmRsZUNvbnRleHQoKS5yZWdpc3RlclNlcnZpY2UoRmlsdGVyLmNsYXNzLCBmaWx0ZXIsIHByb3BzKSk7CgoJCVN0cmluZyByZXNwb25zZSA9IHJlcXVlc3RBZHZpc29yLnJlcXVlc3QoImEvczEvZD9wPTEiKTsKCgkJQXNzZXJ0LmFzc2VydEVxdWFscygiYmIvYXwvZHxwPTF8L2EvczEvZHwvczF8L2F8L2J8dT01fC9hL3MyL2J8L3MyYmIiLCByZXNwb25zZSk7CgkJQXNzZXJ0LmFzc2VydEVxdWFscygyLCBmaWx0ZXIuZ2V0Q291bnQoKSk7Cgl9CgoJQFRlc3QKCXB1YmxpYyB2b2lkIHRlc3RfaW5jbHVkZURlcHRoMigpIHRocm93cyBFeGNlcHRpb24gewoJCVNlcnZsZXQgc2VydmxldDEgPSBuZXcgQmFzZVNlcnZsZXQoKSB7CgkJCXByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDFMOwoKCQkJQE92ZXJyaWRlCgkJCXByb3RlY3RlZCB2b2lkIHNlcnZpY2UoSHR0cFNlcnZsZXRSZXF1ZXN0IHJlcXVlc3QsIEh0dHBTZXJ2bGV0UmVzcG9uc2UgcmVzcG9uc2UpCgkJCQkJdGhyb3dzIFNlcnZsZXRFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKCQkJCXJlcXVlc3QuZ2V0UmVxdWVzdERpc3BhdGNoZXIoIi9zMi9pMj9wMj0yIikuaW5jbHVkZShyZXF1ZXN0LCByZXNwb25zZSk7CgkJCX0KCQl9OwoKCQlTZXJ2bGV0IHNlcnZsZXQyID0gbmV3IEJhc2VTZXJ2bGV0KCkgewoJCQlwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAxTDsKCgkJCUBPdmVycmlkZQoJCQlwcm90ZWN0ZWQgdm9pZCBzZXJ2aWNlKEh0dHBTZXJ2bGV0UmVxdWVzdCByZXF1ZXN0LCBIdHRwU2VydmxldFJlc3BvbnNlIHJlc3BvbnNlKQoJCQkJCXRocm93cyBTZXJ2bGV0RXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CgkJCQlyZXF1ZXN0LmdldFJlcXVlc3REaXNwYXRjaGVyKCIvczMvaTM/cDM9MyIpLmluY2x1ZGUocmVxdWVzdCwgcmVzcG9uc2UpOwoJCQl9CgkJfTsKCgkJRGljdGlvbmFyeTxTdHJpbmcsIE9iamVjdD4gcHJvcHMgPSBuZXcgSGFzaHRhYmxlPFN0cmluZywgT2JqZWN0PigpOwoJCXByb3BzLnB1dChIdHRwV2hpdGVib2FyZENvbnN0YW50cy5IVFRQX1dISVRFQk9BUkRfQ09OVEVYVF9OQU1FLCAiYzEiKTsKCQlwcm9wcy5wdXQoSHR0cFdoaXRlYm9hcmRDb25zdGFudHMuSFRUUF9XSElURUJPQVJEX0NPTlRFWFRfUEFUSCwgIi9jMSIpOwoJCXJlZ2lzdHJhdGlvbnMuYWRkKGdldEJ1bmRsZUNvbnRleHQoKS5yZWdpc3RlclNlcnZpY2UoU2VydmxldENvbnRleHRIZWxwZXIuY2xhc3MsIG5ldyBTZXJ2bGV0Q29udGV4dEhlbHBlcigpIHt9LCBwcm9wcykpOwoKCQlwcm9wcyA9IG5ldyBIYXNodGFibGU8U3RyaW5nLCBPYmplY3Q+KCk7CgkJcHJvcHMucHV0KEh0dHBXaGl0ZWJvYXJkQ29uc3RhbnRzLkhUVFBfV0hJVEVCT0FSRF9TRVJWTEVUX1BBVFRFUk4sICIvczEvKiIpOwoJCXByb3BzLnB1dChIdHRwV2hpdGVib2FyZENvbnN0YW50cy5IVFRQX1dISVRFQk9BUkRfQ09OVEVYVF9TRUxFQ1QsICIoIiArIEh0dHBXaGl0ZWJvYXJkQ29uc3RhbnRzLkhUVFBfV0hJVEVCT0FSRF9DT05URVhUX05BTUUgKyAiPWMxKSIpOwoJCXJlZ2lzdHJhdGlvbnMuYWRkKGdldEJ1bmRsZUNvbnRleHQoKS5yZWdpc3RlclNlcnZpY2UoU2VydmxldC5jbGFzcywgc2VydmxldDEsIHByb3BzKSk7CgoJCXByb3BzID0gbmV3IEhhc2h0YWJsZTxTdHJpbmcsIE9iamVjdD4oKTsKCQlwcm9wcy5wdXQoSHR0cFdoaXRlYm9hcmRDb25zdGFudHMuSFRUUF9XSElURUJPQVJEX1NFUlZMRVRfUEFUVEVSTiwgIi9zMi8qIik7CgkJcHJvcHMucHV0KEh0dHBXaGl0ZWJvYXJkQ29uc3RhbnRzLkhUVFBfV0hJVEVCT0FSRF9DT05URVhUX1NFTEVDVCwgIigiICsgSHR0cFdoaXRlYm9hcmRDb25zdGFudHMuSFRUUF9XSElURUJPQVJEX0NPTlRFWFRfTkFNRSArICI9YzEpIik7CgkJcmVnaXN0cmF0aW9ucy5hZGQoZ2V0QnVuZGxlQ29udGV4dCgpLnJlZ2lzdGVyU2VydmljZShTZXJ2bGV0LmNsYXNzLCBzZXJ2bGV0MiwgcHJvcHMpKTsKCgkJcHJvcHMgPSBuZXcgSGFzaHRhYmxlPFN0cmluZywgT2JqZWN0PigpOwoJCXByb3BzLnB1dChIdHRwV2hpdGVib2FyZENvbnN0YW50cy5IVFRQX1dISVRFQk9BUkRfU0VSVkxFVF9QQVRURVJOLCAiL3MzLyoiKTsKCQlwcm9wcy5wdXQoSHR0cFdoaXRlYm9hcmRDb25zdGFudHMuSFRUUF9XSElURUJPQVJEX0NPTlRFWFRfU0VMRUNULCAiKCIgKyBIdHRwV2hpdGVib2FyZENvbnN0YW50cy5IVFRQX1dISVRFQk9BUkRfQ09OVEVYVF9OQU1FICsgIj1jMSkiKTsKCQlyZWdpc3RyYXRpb25zLmFkZChnZXRCdW5kbGVDb250ZXh0KCkucmVnaXN0ZXJTZXJ2aWNlKFNlcnZsZXQuY2xhc3MsIG5ldyBEaXNwYXRjaFJlc3VsdFNlcnZsZXQoKSwgcHJvcHMpKTsKCgkJU3RyaW5nIHJlc3BvbnNlID0gcmVxdWVzdEFkdmlzb3IucmVxdWVzdCgiYzEvczEvaTE/cDE9MSIpOwoKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCIvYzF8L2kxfHAxPTF8L2MxL3MxL2kxfC9zMXwvYzF8L2kzfHAzPTN8L2MxL3MzL2kzfC9zMyIsIHJlc3BvbnNlKTsKCX0KCglAVGVzdAoJcHVibGljIHZvaWQgdGVzdF9pbmNsdWRlRGVwdGgzKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CgkJU2VydmxldCBzZXJ2bGV0MSA9IG5ldyBCYXNlU2VydmxldCgpIHsKCQkJcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMUw7CgoJCQlAT3ZlcnJpZGUKCQkJcHJvdGVjdGVkIHZvaWQgc2VydmljZShIdHRwU2VydmxldFJlcXVlc3QgcmVxdWVzdCwgSHR0cFNlcnZsZXRSZXNwb25zZSByZXNwb25zZSkKCQkJCQl0aHJvd3MgU2VydmxldEV4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewoJCQkJcmVxdWVzdC5nZXRSZXF1ZXN0RGlzcGF0Y2hlcigiL3MyL2kyP3AyPTIiKS5pbmNsdWRlKHJlcXVlc3QsIHJlc3BvbnNlKTsKCQkJfQoJCX07CgoJCVNlcnZsZXQgc2VydmxldDIgPSBuZXcgQmFzZVNlcnZsZXQoKSB7CgkJCXByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDFMOwoKCQkJQE92ZXJyaWRlCgkJCXByb3RlY3RlZCB2b2lkIHNlcnZpY2UoSHR0cFNlcnZsZXRSZXF1ZXN0IHJlcXVlc3QsIEh0dHBTZXJ2bGV0UmVzcG9uc2UgcmVzcG9uc2UpCgkJCQkJdGhyb3dzIFNlcnZsZXRFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKCQkJCXJlcXVlc3QuZ2V0UmVxdWVzdERpc3BhdGNoZXIoIi9zMy9pMz9wMz0zIikuaW5jbHVkZShyZXF1ZXN0LCByZXNwb25zZSk7CgkJCX0KCQl9OwoKCQlTZXJ2bGV0IHNlcnZsZXQzID0gbmV3IEJhc2VTZXJ2bGV0KCkgewoJCQlwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAxTDsKCgkJCUBPdmVycmlkZQoJCQlwcm90ZWN0ZWQgdm9pZCBzZXJ2aWNlKEh0dHBTZXJ2bGV0UmVxdWVzdCByZXF1ZXN0LCBIdHRwU2VydmxldFJlc3BvbnNlIHJlc3BvbnNlKQoJCQkJCXRocm93cyBTZXJ2bGV0RXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CgkJCQlyZXF1ZXN0LmdldFJlcXVlc3REaXNwYXRjaGVyKCIvczQvaTQ/cDQ9NCIpLmluY2x1ZGUocmVxdWVzdCwgcmVzcG9uc2UpOwoJCQl9CgkJfTsKCgkJRGljdGlvbmFyeTxTdHJpbmcsIE9iamVjdD4gcHJvcHMgPSBuZXcgSGFzaHRhYmxlPFN0cmluZywgT2JqZWN0PigpOwoJCXByb3BzLnB1dChIdHRwV2hpdGVib2FyZENvbnN0YW50cy5IVFRQX1dISVRFQk9BUkRfQ09OVEVYVF9OQU1FLCAiYzEiKTsKCQlwcm9wcy5wdXQoSHR0cFdoaXRlYm9hcmRDb25zdGFudHMuSFRUUF9XSElURUJPQVJEX0NPTlRFWFRfUEFUSCwgIi9jMSIpOwoJCXJlZ2lzdHJhdGlvbnMuYWRkKGdldEJ1bmRsZUNvbnRleHQoKS5yZWdpc3RlclNlcnZpY2UoU2VydmxldENvbnRleHRIZWxwZXIuY2xhc3MsIG5ldyBTZXJ2bGV0Q29udGV4dEhlbHBlcigpIHt9LCBwcm9wcykpOwoKCQlwcm9wcyA9IG5ldyBIYXNodGFibGU8U3RyaW5nLCBPYmplY3Q+KCk7CgkJcHJvcHMucHV0KEh0dHBXaGl0ZWJvYXJkQ29uc3RhbnRzLkhUVFBfV0hJVEVCT0FSRF9TRVJWTEVUX1BBVFRFUk4sICIvczEvKiIpOwoJCXByb3BzLnB1dChIdHRwV2hpdGVib2FyZENvbnN0YW50cy5IVFRQX1dISVRFQk9BUkRfQ09OVEVYVF9TRUxFQ1QsICIoIiArIEh0dHBXaGl0ZWJvYXJkQ29uc3RhbnRzLkhUVFBfV0hJVEVCT0FSRF9DT05URVhUX05BTUUgKyAiPWMxKSIpOwoJCXJlZ2lzdHJhdGlvbnMuYWRkKGdldEJ1bmRsZUNvbnRleHQoKS5yZWdpc3RlclNlcnZpY2UoU2VydmxldC5jbGFzcywgc2VydmxldDEsIHByb3BzKSk7CgoJCXByb3BzID0gbmV3IEhhc2h0YWJsZTxTdHJpbmcsIE9iamVjdD4oKTsKCQlwcm9wcy5wdXQoSHR0cFdoaXRlYm9hcmRDb25zdGFudHMuSFRUUF9XSElURUJPQVJEX1NFUlZMRVRfUEFUVEVSTiwgIi9zMi8qIik7CgkJcHJvcHMucHV0KEh0dHBXaGl0ZWJvYXJkQ29uc3RhbnRzLkhUVFBfV0hJVEVCT0FSRF9DT05URVhUX1NFTEVDVCwgIigiICsgSHR0cFdoaXRlYm9hcmRDb25zdGFudHMuSFRUUF9XSElURUJPQVJEX0NPTlRFWFRfTkFNRSArICI9YzEpIik7CgkJcmVnaXN0cmF0aW9ucy5hZGQoZ2V0QnVuZGxlQ29udGV4dCgpLnJlZ2lzdGVyU2VydmljZShTZXJ2bGV0LmNsYXNzLCBzZXJ2bGV0MiwgcHJvcHMpKTsKCgkJcHJvcHMgPSBuZXcgSGFzaHRhYmxlPFN0cmluZywgT2JqZWN0PigpOwoJCXByb3BzLnB1dChIdHRwV2hpdGVib2FyZENvbnN0YW50cy5IVFRQX1dISVRFQk9BUkRfU0VSVkxFVF9QQVRURVJOLCAiL3MzLyoiKTsKCQlwcm9wcy5wdXQoSHR0cFdoaXRlYm9hcmRDb25zdGFudHMuSFRUUF9XSElURUJPQVJEX0NPTlRFWFRfU0VMRUNULCAiKCIgKyBIdHRwV2hpdGVib2FyZENvbnN0YW50cy5IVFRQX1dISVRFQk9BUkRfQ09OVEVYVF9OQU1FICsgIj1jMSkiKTsKCQlyZWdpc3RyYXRpb25zLmFkZChnZXRCdW5kbGVDb250ZXh0KCkucmVnaXN0ZXJTZXJ2aWNlKFNlcnZsZXQuY2xhc3MsIHNlcnZsZXQzLCBwcm9wcykpOwoKCQlwcm9wcyA9IG5ldyBIYXNodGFibGU8U3RyaW5nLCBPYmplY3Q+KCk7CgkJcHJvcHMucHV0KEh0dHBXaGl0ZWJvYXJkQ29uc3RhbnRzLkhUVFBfV0hJVEVCT0FSRF9TRVJWTEVUX1BBVFRFUk4sICIvczQvKiIpOwoJCXByb3BzLnB1dChIdHRwV2hpdGVib2FyZENvbnN0YW50cy5IVFRQX1dISVRFQk9BUkRfQ09OVEVYVF9TRUxFQ1QsICIoIiArIEh0dHBXaGl0ZWJvYXJkQ29uc3RhbnRzLkhUVFBfV0hJVEVCT0FSRF9DT05URVhUX05BTUUgKyAiPWMxKSIpOwoJCXJlZ2lzdHJhdGlvbnMuYWRkKGdldEJ1bmRsZUNvbnRleHQoKS5yZWdpc3RlclNlcnZpY2UoU2VydmxldC5jbGFzcywgbmV3IERpc3BhdGNoUmVzdWx0U2VydmxldCgpLCBwcm9wcykpOwoKCQlTdHJpbmcgcmVzcG9uc2UgPSByZXF1ZXN0QWR2aXNvci5yZXF1ZXN0KCJjMS9zMS9pMT9wMT0xIik7CgoJCUFzc2VydC5hc3NlcnRFcXVhbHMoIi9jMXwvaTF8cDE9MXwvYzEvczEvaTF8L3MxfC9jMXwvaTR8cDQ9NHwvYzEvczQvaTR8L3M0IiwgcmVzcG9uc2UpOwoJfQoKCUBUZXN0CglwdWJsaWMgdm9pZCB0ZXN0X2luY2x1ZGVOYW1lZFBhcmFtZXRlckFnZ3JlZ2F0aW9uQW5kUHJlY2VkZW5jZSgpIHRocm93cyBFeGNlcHRpb24gewoJCVNlcnZsZXQgc0EgPSBuZXcgSHR0cFNlcnZsZXQoKSB7CgkJCXByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDFMOwoKCQkJQE92ZXJyaWRlCgkJCXByb3RlY3RlZCB2b2lkIGRvR2V0KAoJCQkJSHR0cFNlcnZsZXRSZXF1ZXN0IHJlcSwgSHR0cFNlcnZsZXRSZXNwb25zZSByZXNwKQoJCQkJdGhyb3dzIFNlcnZsZXRFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKCgkJCQlTZXJ2bGV0Q29udGV4dCBzZXJ2bGV0Q29udGV4dCA9IGdldFNlcnZsZXRDb250ZXh0KCk7CgoJCQkJUmVxdWVzdERpc3BhdGNoZXIgcmVxdWVzdERpc3BhdGNoZXIgPSBzZXJ2bGV0Q29udGV4dC5nZXROYW1lZERpc3BhdGNoZXIoInMyIik7CgoJCQkJcmVxdWVzdERpc3BhdGNoZXIuaW5jbHVkZShyZXEsIHJlc3ApOwoJCQl9CgkJfTsKCQlTZXJ2bGV0IHNCID0gbmV3IEh0dHBTZXJ2bGV0KCkgewoJCQlwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAxTDsKCgkJCUBPdmVycmlkZQoJCQlwcm90ZWN0ZWQgdm9pZCBkb0dldCgKCQkJCUh0dHBTZXJ2bGV0UmVxdWVzdCByZXEsIEh0dHBTZXJ2bGV0UmVzcG9uc2UgcmVzcCkKCQkJCXRocm93cyBTZXJ2bGV0RXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CgoJCQkJUHJpbnRXcml0ZXIgd3JpdGVyID0gcmVzcC5nZXRXcml0ZXIoKTsKCQkJCXdyaXRlci53cml0ZShyZXEuZ2V0UXVlcnlTdHJpbmcoKSk7CgkJCQl3cml0ZXIud3JpdGUoInwiKTsKCQkJCXdyaXRlci53cml0ZShTdHJpbmcudmFsdWVPZihyZXEuZ2V0QXR0cmlidXRlKFJlcXVlc3REaXNwYXRjaGVyLklOQ0xVREVfUVVFUllfU1RSSU5HKSkpOwoJCQkJd3JpdGVyLndyaXRlKCJ8Iik7CgkJCQl3cml0ZXIud3JpdGUocmVxLmdldFBhcmFtZXRlcigicCIpKTsKCQkJCXdyaXRlci53cml0ZSgifCIpOwoJCQkJd3JpdGVyLndyaXRlKEFycmF5cy50b1N0cmluZyhyZXEuZ2V0UGFyYW1ldGVyVmFsdWVzKCJwIikpKTsKCQkJfQoJCX07CgoJCURpY3Rpb25hcnk8U3RyaW5nLCBPYmplY3Q+IHByb3BzID0gbmV3IEhhc2h0YWJsZTxTdHJpbmcsIE9iamVjdD4oKTsKCQlwcm9wcy5wdXQoSHR0cFdoaXRlYm9hcmRDb25zdGFudHMuSFRUUF9XSElURUJPQVJEX0NPTlRFWFRfTkFNRSwgImMxIik7CgkJcHJvcHMucHV0KEh0dHBXaGl0ZWJvYXJkQ29uc3RhbnRzLkhUVFBfV0hJVEVCT0FSRF9DT05URVhUX1BBVEgsICIvYzEiKTsKCQlyZWdpc3RyYXRpb25zLmFkZChnZXRCdW5kbGVDb250ZXh0KCkucmVnaXN0ZXJTZXJ2aWNlKFNlcnZsZXRDb250ZXh0SGVscGVyLmNsYXNzLCBuZXcgU2VydmxldENvbnRleHRIZWxwZXIoKSB7fSwgcHJvcHMpKTsKCgkJcHJvcHMgPSBuZXcgSGFzaHRhYmxlPFN0cmluZywgT2JqZWN0PigpOwoJCXByb3BzLnB1dChIdHRwV2hpdGVib2FyZENvbnN0YW50cy5IVFRQX1dISVRFQk9BUkRfU0VSVkxFVF9OQU1FLCAiczEiKTsKCQlwcm9wcy5wdXQoSHR0cFdoaXRlYm9hcmRDb25zdGFudHMuSFRUUF9XSElURUJPQVJEX0NPTlRFWFRfU0VMRUNULCAiKCIgKyBIdHRwV2hpdGVib2FyZENvbnN0YW50cy5IVFRQX1dISVRFQk9BUkRfQ09OVEVYVF9OQU1FICsgIj1jMSkiKTsKCQlwcm9wcy5wdXQoSHR0cFdoaXRlYm9hcmRDb25zdGFudHMuSFRUUF9XSElURUJPQVJEX1NFUlZMRVRfUEFUVEVSTiwgIi9zMS8qIik7CgkJcmVnaXN0cmF0aW9ucy5hZGQoZ2V0QnVuZGxlQ29udGV4dCgpLnJlZ2lzdGVyU2VydmljZShTZXJ2bGV0LmNsYXNzLCBzQSwgcHJvcHMpKTsKCgkJcHJvcHMgPSBuZXcgSGFzaHRhYmxlPFN0cmluZywgT2JqZWN0PigpOwoJCXByb3BzLnB1dChIdHRwV2hpdGVib2FyZENvbnN0YW50cy5IVFRQX1dISVRFQk9BUkRfU0VSVkxFVF9OQU1FLCAiczIiKTsKCQlwcm9wcy5wdXQoSHR0cFdoaXRlYm9hcmRDb25zdGFudHMuSFRUUF9XSElURUJPQVJEX0NPTlRFWFRfU0VMRUNULCAiKCIgKyBIdHRwV2hpdGVib2FyZENvbnN0YW50cy5IVFRQX1dISVRFQk9BUkRfQ09OVEVYVF9OQU1FICsgIj1jMSkiKTsKCQlwcm9wcy5wdXQoSHR0cFdoaXRlYm9hcmRDb25zdGFudHMuSFRUUF9XSElURUJPQVJEX1NFUlZMRVRfUEFUVEVSTiwgIi9zMi8qIik7CgkJcmVnaXN0cmF0aW9ucy5hZGQoZ2V0QnVuZGxlQ29udGV4dCgpLnJlZ2lzdGVyU2VydmljZShTZXJ2bGV0LmNsYXNzLCBzQiwgcHJvcHMpKTsKCgkJU3RyaW5nIHJlc3VsdCA9IHJlcXVlc3RBZHZpc29yLnJlcXVlc3QoImMxL3MxL2E/cD0xJnA9MiIpOwoKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJwPTEmcD0yfG51bGx8MXxbMSwgMl0iLCByZXN1bHQpOwoJfQoKCUBUZXN0CglwdWJsaWMgdm9pZCB0ZXN0X2luY2x1ZGVOYW1lZCgpIHRocm93cyBFeGNlcHRpb24gewoJCVNlcnZsZXQgc0EgPSBuZXcgSHR0cFNlcnZsZXQoKSB7CgkJCXByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDFMOwoKCQkJQE92ZXJyaWRlCgkJCXByb3RlY3RlZCB2b2lkIGRvR2V0KAoJCQkJSHR0cFNlcnZsZXRSZXF1ZXN0IHJlcSwgSHR0cFNlcnZsZXRSZXNwb25zZSByZXNwKQoJCQkJdGhyb3dzIFNlcnZsZXRFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKCgkJCQlTZXJ2bGV0Q29udGV4dCBzZXJ2bGV0Q29udGV4dCA9IGdldFNlcnZsZXRDb250ZXh0KCk7CgoJCQkJUmVxdWVzdERpc3BhdGNoZXIgcmVxdWVzdERpc3BhdGNoZXIgPSBzZXJ2bGV0Q29udGV4dC5nZXROYW1lZERpc3BhdGNoZXIoInMyIik7CgoJCQkJcmVxdWVzdERpc3BhdGNoZXIuaW5jbHVkZShyZXEsIHJlc3ApOwoJCQl9CgkJfTsKCgkJRGljdGlvbmFyeTxTdHJpbmcsIE9iamVjdD4gcHJvcHMgPSBuZXcgSGFzaHRhYmxlPFN0cmluZywgT2JqZWN0PigpOwoJCXByb3BzLnB1dChIdHRwV2hpdGVib2FyZENvbnN0YW50cy5IVFRQX1dISVRFQk9BUkRfQ09OVEVYVF9OQU1FLCAiYzEiKTsKCQlwcm9wcy5wdXQoSHR0cFdoaXRlYm9hcmRDb25zdGFudHMuSFRUUF9XSElURUJPQVJEX0NPTlRFWFRfUEFUSCwgIi9jMSIpOwoJCXJlZ2lzdHJhdGlvbnMuYWRkKGdldEJ1bmRsZUNvbnRleHQoKS5yZWdpc3RlclNlcnZpY2UoU2VydmxldENvbnRleHRIZWxwZXIuY2xhc3MsIG5ldyBTZXJ2bGV0Q29udGV4dEhlbHBlcigpIHt9LCBwcm9wcykpOwoKCQlwcm9wcyA9IG5ldyBIYXNodGFibGU8U3RyaW5nLCBPYmplY3Q+KCk7CgkJcHJvcHMucHV0KEh0dHBXaGl0ZWJvYXJkQ29uc3RhbnRzLkhUVFBfV0hJVEVCT0FSRF9TRVJWTEVUX05BTUUsICJzMSIpOwoJCXByb3BzLnB1dChIdHRwV2hpdGVib2FyZENvbnN0YW50cy5IVFRQX1dISVRFQk9BUkRfQ09OVEVYVF9TRUxFQ1QsICIoIiArIEh0dHBXaGl0ZWJvYXJkQ29uc3RhbnRzLkhUVFBfV0hJVEVCT0FSRF9DT05URVhUX05BTUUgKyAiPWMxKSIpOwoJCXByb3BzLnB1dChIdHRwV2hpdGVib2FyZENvbnN0YW50cy5IVFRQX1dISVRFQk9BUkRfU0VSVkxFVF9QQVRURVJOLCAiL3MxLyoiKTsKCQlyZWdpc3RyYXRpb25zLmFkZChnZXRCdW5kbGVDb250ZXh0KCkucmVnaXN0ZXJTZXJ2aWNlKFNlcnZsZXQuY2xhc3MsIHNBLCBwcm9wcykpOwoKCQlwcm9wcyA9IG5ldyBIYXNodGFibGU8U3RyaW5nLCBPYmplY3Q+KCk7CgkJcHJvcHMucHV0KEh0dHBXaGl0ZWJvYXJkQ29uc3RhbnRzLkhUVFBfV0hJVEVCT0FSRF9TRVJWTEVUX05BTUUsICJzMiIpOwoJCXByb3BzLnB1dChIdHRwV2hpdGVib2FyZENvbnN0YW50cy5IVFRQX1dISVRFQk9BUkRfQ09OVEVYVF9TRUxFQ1QsICIoIiArIEh0dHBXaGl0ZWJvYXJkQ29uc3RhbnRzLkhUVFBfV0hJVEVCT0FSRF9DT05URVhUX05BTUUgKyAiPWMxKSIpOwoJCXByb3BzLnB1dChIdHRwV2hpdGVib2FyZENvbnN0YW50cy5IVFRQX1dISVRFQk9BUkRfU0VSVkxFVF9QQVRURVJOLCAiL3MyLyoiKTsKCQlyZWdpc3RyYXRpb25zLmFkZChnZXRCdW5kbGVDb250ZXh0KCkucmVnaXN0ZXJTZXJ2aWNlKFNlcnZsZXQuY2xhc3MsIG5ldyBEaXNwYXRjaFJlc3VsdFNlcnZsZXQoKSwgcHJvcHMpKTsKCgkJU3RyaW5nIHJlc3VsdCA9IHJlcXVlc3RBZHZpc29yLnJlcXVlc3QoImMxL3MxL2E/cD0xJnA9MiIpOwoKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCIvYzF8L2F8cD0xJnA9MnwvYzEvczEvYXwvczF8bnVsbHxudWxsfG51bGx8bnVsbHxudWxsIiwgcmVzdWx0KTsKCX0KCglAVGVzdAoJcHVibGljIHZvaWQgdGVzdF9pbmNsdWRlUGFyYW1ldGVyQWdncmVnYXRpb25BbmRQcmVjZWRlbmNlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CgkJU2VydmxldCBzQSA9IG5ldyBIdHRwU2VydmxldCgpIHsKCQkJcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMUw7CgoJCQlAT3ZlcnJpZGUKCQkJcHJvdGVjdGVkIHZvaWQgZG9HZXQoCgkJCQlIdHRwU2VydmxldFJlcXVlc3QgcmVxLCBIdHRwU2VydmxldFJlc3BvbnNlIHJlc3ApCgkJCQl0aHJvd3MgU2VydmxldEV4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewoKCQkJCVJlcXVlc3REaXNwYXRjaGVyIHJlcXVlc3REaXNwYXRjaGVyID0gcmVxLmdldFJlcXVlc3REaXNwYXRjaGVyKCIvU2VydmxldDEzQi9hP3A9MyZwPTQiKTsKCgkJCQlyZXF1ZXN0RGlzcGF0Y2hlci5pbmNsdWRlKHJlcSwgcmVzcCk7CgkJCX0KCQl9OwoJCVNlcnZsZXQgc0IgPSBuZXcgSHR0cFNlcnZsZXQoKSB7CgkJCXByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDFMOwoKCQkJQE92ZXJyaWRlCgkJCXByb3RlY3RlZCB2b2lkIGRvR2V0KAoJCQkJSHR0cFNlcnZsZXRSZXF1ZXN0IHJlcSwgSHR0cFNlcnZsZXRSZXNwb25zZSByZXNwKQoJCQkJdGhyb3dzIFNlcnZsZXRFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKCgkJCQlQcmludFdyaXRlciB3cml0ZXIgPSByZXNwLmdldFdyaXRlcigpOwoJCQkJd3JpdGVyLndyaXRlKHJlcS5nZXRRdWVyeVN0cmluZygpKTsKCQkJCXdyaXRlci53cml0ZSgifCIpOwoJCQkJd3JpdGVyLndyaXRlKChTdHJpbmcpcmVxLmdldEF0dHJpYnV0ZShSZXF1ZXN0RGlzcGF0Y2hlci5JTkNMVURFX1FVRVJZX1NUUklORykpOwoJCQkJd3JpdGVyLndyaXRlKCJ8Iik7CgkJCQl3cml0ZXIud3JpdGUocmVxLmdldFBhcmFtZXRlcigicCIpKTsKCQkJCXdyaXRlci53cml0ZSgifCIpOwoJCQkJd3JpdGVyLndyaXRlKEFycmF5cy50b1N0cmluZyhyZXEuZ2V0UGFyYW1ldGVyVmFsdWVzKCJwIikpKTsKCQkJfQoJCX07CgoJCURpY3Rpb25hcnk8U3RyaW5nLCBPYmplY3Q+IHByb3BzID0gbmV3IEhhc2h0YWJsZTxTdHJpbmcsIE9iamVjdD4oKTsKCQlwcm9wcy5wdXQoSHR0cFdoaXRlYm9hcmRDb25zdGFudHMuSFRUUF9XSElURUJPQVJEX1NFUlZMRVRfTkFNRSwgIlMxM0EiKTsKCQlwcm9wcy5wdXQoSHR0cFdoaXRlYm9hcmRDb25zdGFudHMuSFRUUF9XSElURUJPQVJEX1NFUlZMRVRfUEFUVEVSTiwgIi9TZXJ2bGV0MTNBLyoiKTsKCQlyZWdpc3RyYXRpb25zLmFkZChnZXRCdW5kbGVDb250ZXh0KCkucmVnaXN0ZXJTZXJ2aWNlKFNlcnZsZXQuY2xhc3MsIHNBLCBwcm9wcykpOwoKCQlwcm9wcyA9IG5ldyBIYXNodGFibGU8U3RyaW5nLCBPYmplY3Q+KCk7CgkJcHJvcHMucHV0KEh0dHBXaGl0ZWJvYXJkQ29uc3RhbnRzLkhUVFBfV0hJVEVCT0FSRF9TRVJWTEVUX05BTUUsICJTMTNCIik7CgkJcHJvcHMucHV0KEh0dHBXaGl0ZWJvYXJkQ29uc3RhbnRzLkhUVFBfV0hJVEVCT0FSRF9TRVJWTEVUX1BBVFRFUk4sICIvU2VydmxldDEzQi8qIik7CgkJcmVnaXN0cmF0aW9ucy5hZGQoZ2V0QnVuZGxlQ29udGV4dCgpLnJlZ2lzdGVyU2VydmljZShTZXJ2bGV0LmNsYXNzLCBzQiwgcHJvcHMpKTsKCgkJU3RyaW5nIHJlc3VsdCA9IHJlcXVlc3RBZHZpc29yLnJlcXVlc3QoIlNlcnZsZXQxM0EvYT9wPTEmcD0yIik7CgoJCUFzc2VydC5hc3NlcnRFcXVhbHMoInA9MSZwPTJ8cD0zJnA9NHwzfFszLCA0LCAxLCAyXSIsIHJlc3VsdCk7Cgl9CgoJQFRlc3QKCXB1YmxpYyB2b2lkIHRlc3RfaW5jbHVkZVN0cmVhbWVkKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CgkJU2VydmxldCBzZXJ2bGV0MSA9IG5ldyBCYXNlU2VydmxldCgpIHsKCQkJcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMUw7CgoJCQlAT3ZlcnJpZGUKCQkJcHJvdGVjdGVkIHZvaWQgc2VydmljZShIdHRwU2VydmxldFJlcXVlc3QgcmVxdWVzdCwgSHR0cFNlcnZsZXRSZXNwb25zZSByZXNwb25zZSkKCQkJCQl0aHJvd3MgU2VydmxldEV4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewoJCQkJcmVxdWVzdC5nZXRSZXF1ZXN0RGlzcGF0Y2hlcigiL3MyL2I/dT01IikuaW5jbHVkZShyZXF1ZXN0LCByZXNwb25zZSk7CgkJCX0KCQl9OwoKCQlEaWN0aW9uYXJ5PFN0cmluZywgT2JqZWN0PiBwcm9wcyA9IG5ldyBIYXNodGFibGU8U3RyaW5nLCBPYmplY3Q+KCk7CgkJcHJvcHMucHV0KEh0dHBXaGl0ZWJvYXJkQ29uc3RhbnRzLkhUVFBfV0hJVEVCT0FSRF9DT05URVhUX05BTUUsICJhIik7CgkJcHJvcHMucHV0KEh0dHBXaGl0ZWJvYXJkQ29uc3RhbnRzLkhUVFBfV0hJVEVCT0FSRF9DT05URVhUX1BBVEgsICIvYSIpOwoJCXJlZ2lzdHJhdGlvbnMuYWRkKGdldEJ1bmRsZUNvbnRleHQoKS5yZWdpc3RlclNlcnZpY2UoU2VydmxldENvbnRleHRIZWxwZXIuY2xhc3MsIG5ldyBTZXJ2bGV0Q29udGV4dEhlbHBlcigpIHt9LCBwcm9wcykpOwoKCQlwcm9wcyA9IG5ldyBIYXNodGFibGU8U3RyaW5nLCBPYmplY3Q+KCk7CgkJcHJvcHMucHV0KEh0dHBXaGl0ZWJvYXJkQ29uc3RhbnRzLkhUVFBfV0hJVEVCT0FSRF9TRVJWTEVUX1BBVFRFUk4sICIvczEvKiIpOwoJCXByb3BzLnB1dChIdHRwV2hpdGVib2FyZENvbnN0YW50cy5IVFRQX1dISVRFQk9BUkRfQ09OVEVYVF9TRUxFQ1QsICIoIiArIEh0dHBXaGl0ZWJvYXJkQ29uc3RhbnRzLkhUVFBfV0hJVEVCT0FSRF9DT05URVhUX05BTUUgKyAiPWEpIik7CgkJcmVnaXN0cmF0aW9ucy5hZGQoZ2V0QnVuZGxlQ29udGV4dCgpLnJlZ2lzdGVyU2VydmljZShTZXJ2bGV0LmNsYXNzLCBzZXJ2bGV0MSwgcHJvcHMpKTsKCgkJcHJvcHMgPSBuZXcgSGFzaHRhYmxlPFN0cmluZywgT2JqZWN0PigpOwoJCXByb3BzLnB1dChIdHRwV2hpdGVib2FyZENvbnN0YW50cy5IVFRQX1dISVRFQk9BUkRfU0VSVkxFVF9QQVRURVJOLCAiL3MyLyoiKTsKCQlwcm9wcy5wdXQoSHR0cFdoaXRlYm9hcmRDb25zdGFudHMuSFRUUF9XSElURUJPQVJEX0NPTlRFWFRfU0VMRUNULCAiKCIgKyBIdHRwV2hpdGVib2FyZENvbnN0YW50cy5IVFRQX1dISVRFQk9BUkRfQ09OVEVYVF9OQU1FICsgIj1hKSIpOwoJCXJlZ2lzdHJhdGlvbnMuYWRkKGdldEJ1bmRsZUNvbnRleHQoKS5yZWdpc3RlclNlcnZpY2UoU2VydmxldC5jbGFzcywgbmV3IERpc3BhdGNoUmVzdWx0U2VydmxldCgpLCBwcm9wcykpOwoKCQlTdHJpbmcgcmVzcG9uc2UgPSByZXF1ZXN0QWR2aXNvci5yZXF1ZXN0KCJhL3MxL2Q/cD0xIik7CgoJCUFzc2VydC5hc3NlcnRFcXVhbHMoIi9hfC9kfHA9MXwvYS9zMS9kfC9zMXwvYXwvYnx1PTV8L2EvczIvYnwvczIiLCByZXNwb25zZSk7Cgl9CgoJQFRlc3QKCXB1YmxpYyB2b2lkIHRlc3RfaW5jbHVkZVN0cmVhbWVkX1dpdGhSZXF1ZXN0RmlsdGVyKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CgkJU2VydmxldCBzZXJ2bGV0MSA9IG5ldyBCYXNlU2VydmxldCgpIHsKCQkJcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMUw7CgoJCQlAT3ZlcnJpZGUKCQkJcHJvdGVjdGVkIHZvaWQgc2VydmljZShIdHRwU2VydmxldFJlcXVlc3QgcmVxdWVzdCwgSHR0cFNlcnZsZXRSZXNwb25zZSByZXNwb25zZSkKCQkJCQl0aHJvd3MgU2VydmxldEV4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewoJCQkJcmVxdWVzdC5nZXRSZXF1ZXN0RGlzcGF0Y2hlcigiL3MyL2I/dT01IikuaW5jbHVkZShyZXF1ZXN0LCByZXNwb25zZSk7CgkJCX0KCQl9OwoKCQlUZXN0RmlsdGVyIGZpbHRlciA9IG5ldyBUZXN0RmlsdGVyKCkgewoKCQkJQE92ZXJyaWRlCgkJCXB1YmxpYyB2b2lkIGRvRmlsdGVyKAoJCQkJCVNlcnZsZXRSZXF1ZXN0IHJlcXVlc3QsIFNlcnZsZXRSZXNwb25zZSByZXNwb25zZSwgRmlsdGVyQ2hhaW4gY2hhaW4pCgkJCQl0aHJvd3MgSU9FeGNlcHRpb24sIFNlcnZsZXRFeGNlcHRpb24gewoKCQkJCXdyaXRlKHJlc3BvbnNlLmdldE91dHB1dFN0cmVhbSgpLCAiYiIpOwoKCQkJCXN1cGVyLmRvRmlsdGVyKHJlcXVlc3QsIHJlc3BvbnNlLCBjaGFpbik7CgoJCQkJd3JpdGUocmVzcG9uc2UuZ2V0T3V0cHV0U3RyZWFtKCksICJiIik7CgkJCX0KCgkJfTsKCgkJRGljdGlvbmFyeTxTdHJpbmcsIE9iamVjdD4gcHJvcHMgPSBuZXcgSGFzaHRhYmxlPFN0cmluZywgT2JqZWN0PigpOwoJCXByb3BzLnB1dChIdHRwV2hpdGVib2FyZENvbnN0YW50cy5IVFRQX1dISVRFQk9BUkRfQ09OVEVYVF9OQU1FLCAiYSIpOwoJCXByb3BzLnB1dChIdHRwV2hpdGVib2FyZENvbnN0YW50cy5IVFRQX1dISVRFQk9BUkRfQ09OVEVYVF9QQVRILCAiL2EiKTsKCQlyZWdpc3RyYXRpb25zLmFkZChnZXRCdW5kbGVDb250ZXh0KCkucmVnaXN0ZXJTZXJ2aWNlKFNlcnZsZXRDb250ZXh0SGVscGVyLmNsYXNzLCBuZXcgU2VydmxldENvbnRleHRIZWxwZXIoKSB7fSwgcHJvcHMpKTsKCgkJcHJvcHMgPSBuZXcgSGFzaHRhYmxlPFN0cmluZywgT2JqZWN0PigpOwoJCXByb3BzLnB1dChIdHRwV2hpdGVib2FyZENvbnN0YW50cy5IVFRQX1dISVRFQk9BUkRfU0VSVkxFVF9QQVRURVJOLCAiL3MxLyoiKTsKCQlwcm9wcy5wdXQoSHR0cFdoaXRlYm9hcmRDb25zdGFudHMuSFRUUF9XSElURUJPQVJEX0NPTlRFWFRfU0VMRUNULCAiKCIgKyBIdHRwV2hpdGVib2FyZENvbnN0YW50cy5IVFRQX1dISVRFQk9BUkRfQ09OVEVYVF9OQU1FICsgIj1hKSIpOwoJCXJlZ2lzdHJhdGlvbnMuYWRkKGdldEJ1bmRsZUNvbnRleHQoKS5yZWdpc3RlclNlcnZpY2UoU2VydmxldC5jbGFzcywgc2VydmxldDEsIHByb3BzKSk7CgoJCXByb3BzID0gbmV3IEhhc2h0YWJsZTxTdHJpbmcsIE9iamVjdD4oKTsKCQlwcm9wcy5wdXQoSHR0cFdoaXRlYm9hcmRDb25zdGFudHMuSFRUUF9XSElURUJPQVJEX1NFUlZMRVRfUEFUVEVSTiwgIi9zMi8qIik7CgkJcHJvcHMucHV0KEh0dHBXaGl0ZWJvYXJkQ29uc3RhbnRzLkhUVFBfV0hJVEVCT0FSRF9DT05URVhUX1NFTEVDVCwgIigiICsgSHR0cFdoaXRlYm9hcmRDb25zdGFudHMuSFRUUF9XSElURUJPQVJEX0NPTlRFWFRfTkFNRSArICI9YSkiKTsKCQlyZWdpc3RyYXRpb25zLmFkZChnZXRCdW5kbGVDb250ZXh0KCkucmVnaXN0ZXJTZXJ2aWNlKFNlcnZsZXQuY2xhc3MsIG5ldyBEaXNwYXRjaFJlc3VsdFNlcnZsZXQoKSwgcHJvcHMpKTsKCgkJcHJvcHMgPSBuZXcgSGFzaHRhYmxlPFN0cmluZywgT2JqZWN0PigpOwoJCXByb3BzLnB1dChIdHRwV2hpdGVib2FyZENvbnN0YW50cy5IVFRQX1dISVRFQk9BUkRfQ09OVEVYVF9TRUxFQ1QsICIoIiArIEh0dHBXaGl0ZWJvYXJkQ29uc3RhbnRzLkhUVFBfV0hJVEVCT0FSRF9DT05URVhUX05BTUUgKyAiPWEpIik7CgkJcHJvcHMucHV0KEh0dHBXaGl0ZWJvYXJkQ29uc3RhbnRzLkhUVFBfV0hJVEVCT0FSRF9GSUxURVJfTkFNRSwgIkYxIik7CgkJcHJvcHMucHV0KEh0dHBXaGl0ZWJvYXJkQ29uc3RhbnRzLkhUVFBfV0hJVEVCT0FSRF9GSUxURVJfRElTUEFUQ0hFUiwgbmV3IFN0cmluZ1tdIHtEaXNwYXRjaGVyVHlwZS5SRVFVRVNULnRvU3RyaW5nKCl9KTsKCQlwcm9wcy5wdXQoSHR0cFdoaXRlYm9hcmRDb25zdGFudHMuSFRUUF9XSElURUJPQVJEX0ZJTFRFUl9QQVRURVJOLCAiLyoiKTsKCQlyZWdpc3RyYXRpb25zLmFkZChnZXRCdW5kbGVDb250ZXh0KCkucmVnaXN0ZXJTZXJ2aWNlKEZpbHRlci5jbGFzcywgZmlsdGVyLCBwcm9wcykpOwoKCQlTdHJpbmcgcmVzcG9uc2UgPSByZXF1ZXN0QWR2aXNvci5yZXF1ZXN0KCJhL3MxL2Q/cD0xIik7CgoJCUFzc2VydC5hc3NlcnRFcXVhbHMoImIvYXwvZHxwPTF8L2EvczEvZHwvczF8L2F8L2J8dT01fC9hL3MyL2J8L3MyYiIsIHJlc3BvbnNlKTsKCQlBc3NlcnQuYXNzZXJ0VHJ1ZShmaWx0ZXIuZ2V0Q2FsbGVkKCkpOwoJfQoKCUBUZXN0CglwdWJsaWMgdm9pZCB0ZXN0X2luY2x1ZGVTdHJlYW1lZF9XaXRoUmVxdWVzdEFuZEluY2x1ZGVGaWx0ZXIoKSB0aHJvd3MgRXhjZXB0aW9uIHsKCQlTZXJ2bGV0IHNlcnZsZXQxID0gbmV3IEJhc2VTZXJ2bGV0KCkgewoJCQlwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAxTDsKCgkJCUBPdmVycmlkZQoJCQlwcm90ZWN0ZWQgdm9pZCBzZXJ2aWNlKEh0dHBTZXJ2bGV0UmVxdWVzdCByZXF1ZXN0LCBIdHRwU2VydmxldFJlc3BvbnNlIHJlc3BvbnNlKQoJCQkJCXRocm93cyBTZXJ2bGV0RXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CgkJCQlyZXF1ZXN0LmdldFJlcXVlc3REaXNwYXRjaGVyKCIvczIvYj91PTUiKS5pbmNsdWRlKHJlcXVlc3QsIHJlc3BvbnNlKTsKCQkJfQoJCX07CgoJCVRlc3RGaWx0ZXIgZmlsdGVyID0gbmV3IFRlc3RGaWx0ZXIoKSB7CgoJCQlAT3ZlcnJpZGUKCQkJcHVibGljIHZvaWQgZG9GaWx0ZXIoCgkJCQkJU2VydmxldFJlcXVlc3QgcmVxdWVzdCwgU2VydmxldFJlc3BvbnNlIHJlc3BvbnNlLCBGaWx0ZXJDaGFpbiBjaGFpbikKCQkJCXRocm93cyBJT0V4Y2VwdGlvbiwgU2VydmxldEV4Y2VwdGlvbiB7CgoJCQkJd3JpdGUocmVzcG9uc2UuZ2V0T3V0cHV0U3RyZWFtKCksICJiIik7CgoJCQkJc3VwZXIuZG9GaWx0ZXIocmVxdWVzdCwgcmVzcG9uc2UsIGNoYWluKTsKCgkJCQl3cml0ZShyZXNwb25zZS5nZXRPdXRwdXRTdHJlYW0oKSwgImIiKTsKCQkJfQoKCQl9OwoKCQlEaWN0aW9uYXJ5PFN0cmluZywgT2JqZWN0PiBwcm9wcyA9IG5ldyBIYXNodGFibGU8U3RyaW5nLCBPYmplY3Q+KCk7CgkJcHJvcHMucHV0KEh0dHBXaGl0ZWJvYXJkQ29uc3RhbnRzLkhUVFBfV0hJVEVCT0FSRF9DT05URVhUX05BTUUsICJhIik7CgkJcHJvcHMucHV0KEh0dHBXaGl0ZWJvYXJkQ29uc3RhbnRzLkhUVFBfV0hJVEVCT0FSRF9DT05URVhUX1BBVEgsICIvYSIpOwoJCXJlZ2lzdHJhdGlvbnMuYWRkKGdldEJ1bmRsZUNvbnRleHQoKS5yZWdpc3RlclNlcnZpY2UoU2VydmxldENvbnRleHRIZWxwZXIuY2xhc3MsIG5ldyBTZXJ2bGV0Q29udGV4dEhlbHBlcigpIHt9LCBwcm9wcykpOwoKCQlwcm9wcyA9IG5ldyBIYXNodGFibGU8U3RyaW5nLCBPYmplY3Q+KCk7CgkJcHJvcHMucHV0KEh0dHBXaGl0ZWJvYXJkQ29uc3RhbnRzLkhUVFBfV0hJVEVCT0FSRF9TRVJWTEVUX1BBVFRFUk4sICIvczEvKiIpOwoJCXByb3BzLnB1dChIdHRwV2hpdGVib2FyZENvbnN0YW50cy5IVFRQX1dISVRFQk9BUkRfQ09OVEVYVF9TRUxFQ1QsICIoIiArIEh0dHBXaGl0ZWJvYXJkQ29uc3RhbnRzLkhUVFBfV0hJVEVCT0FSRF9DT05URVhUX05BTUUgKyAiPWEpIik7CgkJcmVnaXN0cmF0aW9ucy5hZGQoZ2V0QnVuZGxlQ29udGV4dCgpLnJlZ2lzdGVyU2VydmljZShTZXJ2bGV0LmNsYXNzLCBzZXJ2bGV0MSwgcHJvcHMpKTsKCgkJcHJvcHMgPSBuZXcgSGFzaHRhYmxlPFN0cmluZywgT2JqZWN0PigpOwoJCXByb3BzLnB1dChIdHRwV2hpdGVib2FyZENvbnN0YW50cy5IVFRQX1dISVRFQk9BUkRfU0VSVkxFVF9QQVRURVJOLCAiL3MyLyoiKTsKCQlwcm9wcy5wdXQoSHR0cFdoaXRlYm9hcmRDb25zdGFudHMuSFRUUF9XSElURUJPQVJEX0NPTlRFWFRfU0VMRUNULCAiKCIgKyBIdHRwV2hpdGVib2FyZENvbnN0YW50cy5IVFRQX1dISVRFQk9BUkRfQ09OVEVYVF9OQU1FICsgIj1hKSIpOwoJCXJlZ2lzdHJhdGlvbnMuYWRkKGdldEJ1bmRsZUNvbnRleHQoKS5yZWdpc3RlclNlcnZpY2UoU2VydmxldC5jbGFzcywgbmV3IERpc3BhdGNoUmVzdWx0U2VydmxldCgpLCBwcm9wcykpOwoKCQlwcm9wcyA9IG5ldyBIYXNodGFibGU8U3RyaW5nLCBPYmplY3Q+KCk7CgkJcHJvcHMucHV0KEh0dHBXaGl0ZWJvYXJkQ29uc3RhbnRzLkhUVFBfV0hJVEVCT0FSRF9DT05URVhUX1NFTEVDVCwgIigiICsgSHR0cFdoaXRlYm9hcmRDb25zdGFudHMuSFRUUF9XSElURUJPQVJEX0NPTlRFWFRfTkFNRSArICI9YSkiKTsKCQlwcm9wcy5wdXQoSHR0cFdoaXRlYm9hcmRDb25zdGFudHMuSFRUUF9XSElURUJPQVJEX0ZJTFRFUl9OQU1FLCAiRjEiKTsKCQlwcm9wcy5wdXQoSHR0cFdoaXRlYm9hcmRDb25zdGFudHMuSFRUUF9XSElURUJPQVJEX0ZJTFRFUl9ESVNQQVRDSEVSLCBuZXcgU3RyaW5nW10ge0Rpc3BhdGNoZXJUeXBlLklOQ0xVREUudG9TdHJpbmcoKSwgRGlzcGF0Y2hlclR5cGUuUkVRVUVTVC50b1N0cmluZygpfSk7CgkJcHJvcHMucHV0KEh0dHBXaGl0ZWJvYXJkQ29uc3RhbnRzLkhUVFBfV0hJVEVCT0FSRF9GSUxURVJfUEFUVEVSTiwgIi8qIik7CgkJcmVnaXN0cmF0aW9ucy5hZGQoZ2V0QnVuZGxlQ29udGV4dCgpLnJlZ2lzdGVyU2VydmljZShGaWx0ZXIuY2xhc3MsIGZpbHRlciwgcHJvcHMpKTsKCgkJU3RyaW5nIHJlc3BvbnNlID0gcmVxdWVzdEFkdmlzb3IucmVxdWVzdCgiYS9zMS9kP3A9MSIpOwoKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJiYi9hfC9kfHA9MXwvYS9zMS9kfC9zMXwvYXwvYnx1PTV8L2EvczIvYnwvczJiYiIsIHJlc3BvbnNlKTsKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKDIsIGZpbHRlci5nZXRDb3VudCgpKTsKCX0KCglAVGVzdAoJcHVibGljIHZvaWQgdGVzdF9CdWc0NzkxMTUoKSB0aHJvd3MgRXhjZXB0aW9uIHsKCQlTZXJ2bGV0IHNlcnZsZXQgPSBuZXcgSHR0cFNlcnZsZXQoKSB7CgkJCXByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDFMOwoKCQkJQE92ZXJyaWRlCgkJCXByb3RlY3RlZCB2b2lkIGRvR2V0KAoJCQkJZmluYWwgSHR0cFNlcnZsZXRSZXF1ZXN0IHJlcSwgZmluYWwgSHR0cFNlcnZsZXRSZXNwb25zZSByZXNwKQoJCQkJdGhyb3dzIFNlcnZsZXRFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKCgkJCQlmaW5hbCBBdG9taWNSZWZlcmVuY2U8U3RyaW5nW10+IHJlc3VsdHMgPSBuZXcgQXRvbWljUmVmZXJlbmNlPFN0cmluZ1tdPigpOwoKCQkJCVRocmVhZCB0aHJlYWQgPSBuZXcgVGhyZWFkKCkgewoKCQkJCQlAT3ZlcnJpZGUKCQkJCQlwdWJsaWMgdm9pZCBydW4oKSB7CgkJCQkJCVN0cmluZ1tdIHBhcnRzID0gbmV3IFN0cmluZ1syXTsKCgkJCQkJCXBhcnRzWzBdID0gcmVxLmdldENvbnRleHRQYXRoKCk7CgkJCQkJCXBhcnRzWzFdID0gcmVxLmdldFJlcXVlc3RVUkkoKTsKCgkJCQkJCXJlc3VsdHMuc2V0KHBhcnRzKTsKCQkJCQl9CgoJCQkJfTsKCgkJCQl0aHJlYWQuc3RhcnQoKTsKCgkJCQl0cnkgewoJCQkJCXRocmVhZC5qb2luKCk7CgkJCQl9CgkJCQljYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gaWUpIHsKCQkJCQl0aHJvdyBuZXcgSU9FeGNlcHRpb24oaWUpOwoJCQkJfQoKCQkJCUFzc2VydC5hc3NlcnROb3ROdWxsKHJlc3VsdHMuZ2V0KCkpOwoKCQkJCVByaW50V3JpdGVyIHdyaXRlciA9IHJlc3AuZ2V0V3JpdGVyKCk7CgkJCQl3cml0ZXIud3JpdGUocmVzdWx0cy5nZXQoKVswXSk7CgkJCQl3cml0ZXIud3JpdGUoInwiKTsKCQkJCXdyaXRlci53cml0ZShyZXN1bHRzLmdldCgpWzFdKTsKCQkJfQoJCX07CgoJCURpY3Rpb25hcnk8U3RyaW5nLCBPYmplY3Q+IHByb3BzID0gbmV3IEhhc2h0YWJsZTxTdHJpbmcsIE9iamVjdD4oKTsKCQlwcm9wcy5wdXQoSHR0cFdoaXRlYm9hcmRDb25zdGFudHMuSFRUUF9XSElURUJPQVJEX1NFUlZMRVRfTkFNRSwgIkJ1ZzQ3OTExNSIpOwoJCXByb3BzLnB1dChIdHRwV2hpdGVib2FyZENvbnN0YW50cy5IVFRQX1dISVRFQk9BUkRfU0VSVkxFVF9QQVRURVJOLCAiL0J1ZzQ3OTExNS8qIik7CgkJcmVnaXN0cmF0aW9ucy5hZGQoZ2V0QnVuZGxlQ29udGV4dCgpLnJlZ2lzdGVyU2VydmljZShTZXJ2bGV0LmNsYXNzLCBzZXJ2bGV0LCBwcm9wcykpOwoKCQlTdHJpbmcgcmVzdWx0ID0gcmVxdWVzdEFkdmlzb3IucmVxdWVzdCgiQnVnNDc5MTE1L2EiKTsKCgkJQXNzZXJ0LmFzc2VydEVxdWFscygifC9CdWc0NzkxMTUvYSIsIHJlc3VsdCk7Cgl9CgoJQFRlc3QKCXB1YmxpYyB2b2lkIHRlc3RfaGVhZGVyc19pbmNsdWRlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CgkJU2ltcGxlRGF0ZUZvcm1hdCBmb3JtYXQgPSBuZXcgU2ltcGxlRGF0ZUZvcm1hdCgiRUVFLCBkZCBNTU0geXl5eSBISDptbTpzcyB6enoiKTsKCQlmb3JtYXQuc2V0VGltZVpvbmUoVGltZVpvbmUuZ2V0VGltZVpvbmUoIkdNVCIpKTsKCQlmaW5hbCBsb25nIGRhdGUxID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCkgLSAoMTAwMCo2MCo2MCoyNCozNjUqMzApOwoJCWZpbmFsIGxvbmcgZGF0ZTIgPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKSAtICgxMDAwKjYwKjYwKjI0KjM2NSo0MCk7CgoJCVNlcnZsZXQgc2VydmxldDEgPSBuZXcgQmFzZVNlcnZsZXQoKSB7CgkJCXByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDFMOwoKCQkJQE92ZXJyaWRlCgkJCXByb3RlY3RlZCB2b2lkIHNlcnZpY2UoSHR0cFNlcnZsZXRSZXF1ZXN0IHJlcXVlc3QsIEh0dHBTZXJ2bGV0UmVzcG9uc2UgcmVzcG9uc2UpCgkJCQkJdGhyb3dzIFNlcnZsZXRFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKCgkJCQlyZXNwb25zZS5hZGRDb29raWUobmV3IENvb2tpZSgiZm9vIiwiYmFyIikpOwoJCQkJcmVzcG9uc2UuYWRkRGF0ZUhlYWRlcigiWC1kYXRlIiwgZGF0ZTEpOwoJCQkJcmVzcG9uc2UuYWRkSGVhZGVyKCJYLWNvbG91ciIsICJibHVlIik7CgkJCQlyZXNwb25zZS5hZGRJbnRIZWFkZXIoIlgtc2l6ZSIsIDIwKTsKCQkJCXJlc3BvbnNlLnNldENoYXJhY3RlckVuY29kaW5nKCJVVEYtOCIpOwoJCQkJcmVzcG9uc2Uuc2V0Q29udGVudFR5cGUoInRleHQvcGxhaW4iKTsKCQkJCXJlc3BvbnNlLnNldEhlYWRlcigiWC1hbmltYWwiLCAiY2F0Iik7CgkJCQlyZXNwb25zZS5zZXRMb2NhbGUoTG9jYWxlLkNBTkFEQSk7CgkJCQlyZXNwb25zZS5zZXRCdWZmZXJTaXplKDEwMjQpOwoKCQkJCXJlcXVlc3QuZ2V0UmVxdWVzdERpc3BhdGNoZXIoIi9zMiIpLmluY2x1ZGUocmVxdWVzdCwgcmVzcG9uc2UpOwoJCQl9CgkJfTsKCgkJU2VydmxldCBzZXJ2bGV0MiA9IG5ldyBCYXNlU2VydmxldCgpIHsKCQkJcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMUw7CgoJCQlAT3ZlcnJpZGUKCQkJcHJvdGVjdGVkIHZvaWQgc2VydmljZShIdHRwU2VydmxldFJlcXVlc3QgcmVxdWVzdCwgSHR0cFNlcnZsZXRSZXNwb25zZSByZXNwb25zZSkKCQkJCQl0aHJvd3MgU2VydmxldEV4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewoKCQkJCXJlc3BvbnNlLmFkZENvb2tpZShuZXcgQ29va2llKCJmb28iLCJiYXoiKSk7CgkJCQlyZXNwb25zZS5hZGREYXRlSGVhZGVyKCJYLWRhdGUiLCBkYXRlMik7CgkJCQlyZXNwb25zZS5hZGRIZWFkZXIoIlgtY29sb3VyIiwgImdyZWVuIik7CgkJCQlyZXNwb25zZS5hZGRJbnRIZWFkZXIoIlgtc2l6ZSIsIDMwKTsKCQkJCXJlc3BvbnNlLnNldENoYXJhY3RlckVuY29kaW5nKCJVVEYtMTYiKTsKCQkJCXJlc3BvbnNlLnNldENvbnRlbnRUeXBlKCJ0ZXh0L2pzb24iKTsKCQkJCXJlc3BvbnNlLnNldEhlYWRlcigiWC1hbmltYWwiLCAiYm9nIik7CgkJCQlyZXNwb25zZS5zZXRMb2NhbGUoTG9jYWxlLlVTKTsKCQkJCXJlc3BvbnNlLnNldEJ1ZmZlclNpemUoMCk7CgkJCX0KCQl9OwoKCQlEaWN0aW9uYXJ5PFN0cmluZywgT2JqZWN0PiBwcm9wcyA9IG5ldyBIYXNodGFibGU8U3RyaW5nLCBPYmplY3Q+KCk7CgkJcHJvcHMucHV0KEh0dHBXaGl0ZWJvYXJkQ29uc3RhbnRzLkhUVFBfV0hJVEVCT0FSRF9TRVJWTEVUX1BBVFRFUk4sICIvczEvKiIpOwoJCXJlZ2lzdHJhdGlvbnMuYWRkKGdldEJ1bmRsZUNvbnRleHQoKS5yZWdpc3RlclNlcnZpY2UoU2VydmxldC5jbGFzcywgc2VydmxldDEsIHByb3BzKSk7CgoJCXByb3BzID0gbmV3IEhhc2h0YWJsZTxTdHJpbmcsIE9iamVjdD4oKTsKCQlwcm9wcy5wdXQoSHR0cFdoaXRlYm9hcmRDb25zdGFudHMuSFRUUF9XSElURUJPQVJEX1NFUlZMRVRfUEFUVEVSTiwgIi9zMi8qIik7CgkJcmVnaXN0cmF0aW9ucy5hZGQoZ2V0QnVuZGxlQ29udGV4dCgpLnJlZ2lzdGVyU2VydmljZShTZXJ2bGV0LmNsYXNzLCBzZXJ2bGV0MiwgcHJvcHMpKTsKCgkJTWFwPFN0cmluZywgTGlzdDxTdHJpbmc+PiByZXNwb25zZSA9IHJlcXVlc3RBZHZpc29yLnJlcXVlc3QoInMxIiwgbnVsbCk7CgoJCUFzc2VydC5hc3NlcnROb3ROdWxsKHJlc3BvbnNlLmdldCgiU2V0LUNvb2tpZSIpKTsKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJmb289YmFyIiwgcmVzcG9uc2UuZ2V0KCJTZXQtQ29va2llIikuZ2V0KDApKTsKCQlBc3NlcnQuYXNzZXJ0Tm90TnVsbChyZXNwb25zZS5nZXQoIlgtZGF0ZSIpKTsKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKGZvcm1hdC5mb3JtYXQobmV3IERhdGUoZGF0ZTEpKSwgcmVzcG9uc2UuZ2V0KCJYLWRhdGUiKS5nZXQoMCkpOwoJCUFzc2VydC5hc3NlcnROb3ROdWxsKHJlc3BvbnNlLmdldCgiWC1jb2xvdXIiKSk7CgkJQXNzZXJ0LmFzc2VydEVxdWFscygiYmx1ZSIsIHJlc3BvbnNlLmdldCgiWC1jb2xvdXIiKS5nZXQoMCkpOwoJCUFzc2VydC5hc3NlcnROb3ROdWxsKHJlc3BvbnNlLmdldCgiWC1zaXplIikpOwoJCUFzc2VydC5hc3NlcnRFcXVhbHMoIjIwIiwgcmVzcG9uc2UuZ2V0KCJYLXNpemUiKS5nZXQoMCkpOwoKCQlTdHJpbmcgY29udGVudFR5cGUgPSByZXNwb25zZS5nZXQoIkNvbnRlbnQtVHlwZSIpLmdldCgwKTsKCgkJQXNzZXJ0LmFzc2VydFRydWUoY29udGVudFR5cGUuY29udGFpbnMoInRleHQvcGxhaW47IikpOwoJCUFzc2VydC5hc3NlcnRUcnVlKGNvbnRlbnRUeXBlLnRvTG93ZXJDYXNlKCkuY29udGFpbnMoImNoYXJzZXQ9dXRmLTgiKSk7CgkJQXNzZXJ0LmFzc2VydEVxdWFscygiZW4tQ0EiLCByZXNwb25zZS5nZXQoIkNvbnRlbnQtTGFuZ3VhZ2UiKS5nZXQoMCkpOwoJCUFzc2VydC5hc3NlcnROb3ROdWxsKHJlc3BvbnNlLmdldCgiWC1hbmltYWwiKSk7CgkJQXNzZXJ0LmFzc2VydEVxdWFscygiY2F0IiwgcmVzcG9uc2UuZ2V0KCJYLWFuaW1hbCIpLmdldCgwKSk7Cgl9CgoJQFRlc3QKCXB1YmxpYyB2b2lkIHRlc3RfaGVhZGVyc19mb3J3YXJkKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CgkJU2ltcGxlRGF0ZUZvcm1hdCBmb3JtYXQgPSBuZXcgU2ltcGxlRGF0ZUZvcm1hdCgiRUVFLCBkZCBNTU0geXl5eSBISDptbTpzcyB6enoiKTsKCQlmb3JtYXQuc2V0VGltZVpvbmUoVGltZVpvbmUuZ2V0VGltZVpvbmUoIkdNVCIpKTsKCQlmaW5hbCBsb25nIGRhdGUxID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCkgLSAoMTAwMCo2MCo2MCoyNCozNjUqMzApOwoJCWZpbmFsIGxvbmcgZGF0ZTIgPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKSAtICgxMDAwKjYwKjYwKjI0KjM2NSo0MCk7CgoJCVNlcnZsZXQgc2VydmxldDEgPSBuZXcgQmFzZVNlcnZsZXQoKSB7CgkJCXByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDFMOwoKCQkJQE92ZXJyaWRlCgkJCXByb3RlY3RlZCB2b2lkIHNlcnZpY2UoSHR0cFNlcnZsZXRSZXF1ZXN0IHJlcXVlc3QsIEh0dHBTZXJ2bGV0UmVzcG9uc2UgcmVzcG9uc2UpCgkJCQkJdGhyb3dzIFNlcnZsZXRFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKCgkJCQlyZXNwb25zZS5hZGRDb29raWUobmV3IENvb2tpZSgiZm9vIiwiYmFyIikpOwoJCQkJcmVzcG9uc2UuYWRkRGF0ZUhlYWRlcigiWC1kYXRlIiwgZGF0ZTEpOwoJCQkJcmVzcG9uc2UuYWRkSGVhZGVyKCJYLWNvbG91ciIsICJibHVlIik7CgkJCQlyZXNwb25zZS5hZGRJbnRIZWFkZXIoIlgtc2l6ZSIsIDIwKTsKCQkJCXJlc3BvbnNlLnNldENoYXJhY3RlckVuY29kaW5nKCJVVEYtOCIpOwoJCQkJcmVzcG9uc2Uuc2V0Q29udGVudFR5cGUoInRleHQvcGxhaW4iKTsKCQkJCXJlc3BvbnNlLnNldEhlYWRlcigiWC1hbmltYWwiLCAiY2F0Iik7CgkJCQlyZXNwb25zZS5zZXRMb2NhbGUoTG9jYWxlLkNBTkFEQSk7CgkJCQlyZXNwb25zZS5zZXRCdWZmZXJTaXplKDEwMjQpOwoKCQkJCXJlcXVlc3QuZ2V0UmVxdWVzdERpc3BhdGNoZXIoIi9zMiIpLmZvcndhcmQocmVxdWVzdCwgcmVzcG9uc2UpOwoJCQl9CgkJfTsKCgkJU2VydmxldCBzZXJ2bGV0MiA9IG5ldyBCYXNlU2VydmxldCgpIHsKCQkJcHJpdmF0ZSBzdGF0aWMgZmluYWwgbG9uZyBzZXJpYWxWZXJzaW9uVUlEID0gMUw7CgoJCQlAT3ZlcnJpZGUKCQkJcHJvdGVjdGVkIHZvaWQgc2VydmljZShIdHRwU2VydmxldFJlcXVlc3QgcmVxdWVzdCwgSHR0cFNlcnZsZXRSZXNwb25zZSByZXNwb25zZSkKCQkJCQl0aHJvd3MgU2VydmxldEV4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewoKCQkJCXJlc3BvbnNlLmFkZENvb2tpZShuZXcgQ29va2llKCJmb28iLCJiYXoiKSk7CgkJCQlyZXNwb25zZS5hZGREYXRlSGVhZGVyKCJYLWRhdGUiLCBkYXRlMik7CgkJCQlyZXNwb25zZS5hZGRIZWFkZXIoIlgtY29sb3VyIiwgImdyZWVuIik7CgkJCQlyZXNwb25zZS5hZGRJbnRIZWFkZXIoIlgtc2l6ZSIsIDMwKTsKCQkJCXJlc3BvbnNlLnNldENoYXJhY3RlckVuY29kaW5nKCJVVEYtMTYiKTsKCQkJCXJlc3BvbnNlLnNldENvbnRlbnRUeXBlKCJ0ZXh0L2pzb24iKTsKCQkJCXJlc3BvbnNlLnNldEhlYWRlcigiWC1hbmltYWwiLCAiZG9nIik7CgkJCQlyZXNwb25zZS5zZXRMb2NhbGUoTG9jYWxlLlVTKTsKCQkJCXJlc3BvbnNlLnNldEJ1ZmZlclNpemUoMCk7CgkJCX0KCQl9OwoKCQlEaWN0aW9uYXJ5PFN0cmluZywgT2JqZWN0PiBwcm9wcyA9IG5ldyBIYXNodGFibGU8U3RyaW5nLCBPYmplY3Q+KCk7CgkJcHJvcHMucHV0KEh0dHBXaGl0ZWJvYXJkQ29uc3RhbnRzLkhUVFBfV0hJVEVCT0FSRF9TRVJWTEVUX1BBVFRFUk4sICIvczEvKiIpOwoJCXJlZ2lzdHJhdGlvbnMuYWRkKGdldEJ1bmRsZUNvbnRleHQoKS5yZWdpc3RlclNlcnZpY2UoU2VydmxldC5jbGFzcywgc2VydmxldDEsIHByb3BzKSk7CgoJCXByb3BzID0gbmV3IEhhc2h0YWJsZTxTdHJpbmcsIE9iamVjdD4oKTsKCQlwcm9wcy5wdXQoSHR0cFdoaXRlYm9hcmRDb25zdGFudHMuSFRUUF9XSElURUJPQVJEX1NFUlZMRVRfUEFUVEVSTiwgIi9zMi8qIik7CgkJcmVnaXN0cmF0aW9ucy5hZGQoZ2V0QnVuZGxlQ29udGV4dCgpLnJlZ2lzdGVyU2VydmljZShTZXJ2bGV0LmNsYXNzLCBzZXJ2bGV0MiwgcHJvcHMpKTsKCgkJTWFwPFN0cmluZywgTGlzdDxTdHJpbmc+PiByZXNwb25zZSA9IHJlcXVlc3RBZHZpc29yLnJlcXVlc3QoInMxIiwgbnVsbCk7CgoJCUFzc2VydC5hc3NlcnROb3ROdWxsKHJlc3BvbnNlLmdldCgiU2V0LUNvb2tpZSIpKTsKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCJmb289YmF6IiwgcmVzcG9uc2UuZ2V0KCJTZXQtQ29va2llIikuZ2V0KDApKTsKCQlBc3NlcnQuYXNzZXJ0Tm90TnVsbChyZXNwb25zZS5nZXQoIlgtZGF0ZSIpKTsKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKGZvcm1hdC5mb3JtYXQobmV3IERhdGUoZGF0ZTIpKSwgcmVzcG9uc2UuZ2V0KCJYLWRhdGUiKS5nZXQoMCkpOwoJCUFzc2VydC5hc3NlcnROb3ROdWxsKHJlc3BvbnNlLmdldCgiWC1jb2xvdXIiKSk7CgkJQXNzZXJ0LmFzc2VydEVxdWFscygiZ3JlZW4iLCByZXNwb25zZS5nZXQoIlgtY29sb3VyIikuZ2V0KDApKTsKCQlBc3NlcnQuYXNzZXJ0Tm90TnVsbChyZXNwb25zZS5nZXQoIlgtc2l6ZSIpKTsKCQlBc3NlcnQuYXNzZXJ0RXF1YWxzKCIzMCIsIHJlc3BvbnNlLmdldCgiWC1zaXplIikuZ2V0KDApKTsKCgkJU3RyaW5nIGNvbnRlbnRUeXBlID0gcmVzcG9uc2UuZ2V0KCJDb250ZW50LVR5cGUiKS5nZXQoMCk7CgoJCUFzc2VydC5hc3NlcnRUcnVlKGNvbnRlbnRUeXBlLmNvbnRhaW5zKCJ0ZXh0L2pzb247IikpOwoJCUFzc2VydC5hc3NlcnRUcnVlKGNvbnRlbnRUeXBlLnRvTG93ZXJDYXNlKCkuY29udGFpbnMoImNoYXJzZXQ9dXRmLTE2IikpOwoJCUFzc2VydC5hc3NlcnRFcXVhbHMoImVuLVVTIiwgcmVzcG9uc2UuZ2V0KCJDb250ZW50LUxhbmd1YWdlIikuZ2V0KDApKTsKCQlBc3NlcnQuYXNzZXJ0Tm90TnVsbChyZXNwb25zZS5nZXQoIlgtYW5pbWFsIikpOwoJCUFzc2VydC5hc3NlcnRFcXVhbHMoImRvZyIsIHJlc3BvbnNlLmdldCgiWC1hbmltYWwiKS5nZXQoMCkpOwoJfQoKCS8vIEJ1ZyA0OTM1ODMKCUBUZXN0CglwdWJsaWMgdm9pZCB0ZXN0X3N0cmVhbWVkX3Jlc3BvbnNlX291dHB1dHN0cmVhbSgpIHRocm93cyBFeGNlcHRpb24gewoJCWZpbmFsIGxvbmcgaW50ZXJ2YWwgPSAxMDBMOwoKCQlTZXJ2bGV0IHNlcnZsZXQxID0gbmV3IEJhc2VTZXJ2bGV0KCkgewoJCQlwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAxTDsKCgkJCUBPdmVycmlkZQoJCQlwcm90ZWN0ZWQgdm9pZCBzZXJ2aWNlKEh0dHBTZXJ2bGV0UmVxdWVzdCByZXF1ZXN0LCBIdHRwU2VydmxldFJlc3BvbnNlIHJlc3BvbnNlKQoJCQkJdGhyb3dzIFNlcnZsZXRFeGNlcHRpb24sIElPRXhjZXB0aW9uIHsKCgkJICAgICAgICByZXNwb25zZS5zZXRDb250ZW50VHlwZSgidGV4dC9ldmVudC1zdHJlYW0iKTsKCQkgICAgICAgIHJlc3BvbnNlLnNldENoYXJhY3RlckVuY29kaW5nKCJVVEYtOCIpOwoKCQkJCXRyeSAoU2VydmxldE91dHB1dFN0cmVhbSBvdXQgPSByZXNwb25zZS5nZXRPdXRwdXRTdHJlYW0oKSkgewoJCQkJCWZvciAoaW50IGkgPSAxOyBpIDw9IDEwOyArK2kpIHsKCQkJCQkJdHJ5IHsKCQkJCQkJCVRocmVhZC5zbGVlcChpbnRlcnZhbCk7CgkJCQkJCX0KCQkJCQkJY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGUpIHsKCQkJCQkJCXRocm93IG5ldyBTZXJ2bGV0RXhjZXB0aW9uKGUpOwoJCQkJCQl9CgoJCQkJCQlvdXQucHJpbnQoImRhdGE6ICIpOwoJCQkJCQlvdXQucHJpbnQoU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCkpOwoJCQkJCQlvdXQucHJpbnQoIlxuXG4iKTsKCQkJCQkJb3V0LmZsdXNoKCk7CgkJCQkJfQoJCQkJfQoJCQl9CgkJfTsKCgkJRGljdGlvbmFyeTxTdHJpbmcsIE9iamVjdD4gcHJvcHMgPSBuZXcgSGFzaHRhYmxlPFN0cmluZywgT2JqZWN0PigpOwoJCXByb3BzLnB1dChIdHRwV2hpdGVib2FyZENvbnN0YW50cy5IVFRQX1dISVRFQk9BUkRfU0VSVkxFVF9QQVRURVJOLCAiL3MxLyoiKTsKCQlyZWdpc3RyYXRpb25zLmFkZChnZXRCdW5kbGVDb250ZXh0KCkucmVnaXN0ZXJTZXJ2aWNlKFNlcnZsZXQuY2xhc3MsIHNlcnZsZXQxLCBwcm9wcykpOwoKCQlmaW5hbCBBdG9taWNMb25nIHByZXZpb3VzVGltZSA9IG5ldyBBdG9taWNMb25nKFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpKTsKCQlmaW5hbCBBdG9taWNJbnRlZ2VyIGNvdW50ZXIgPSBuZXcgQXRvbWljSW50ZWdlcigpOwoJCWZpbmFsIEF0b21pY0Jvb2xlYW4gcmVzdWx0ID0gbmV3IEF0b21pY0Jvb2xlYW4odHJ1ZSk7CgoJCUV2ZW50SGFuZGxlciBoYW5kbGVyID0gbmV3IEV2ZW50SGFuZGxlcigpIHsKCgkJCUBPdmVycmlkZQoJCQlwdWJsaWMgdm9pZCBoYW5kbGUoTWFwPFN0cmluZywgU3RyaW5nPiBldmVudE1hcCkgewoJCQkJc3VwZXIuaGFuZGxlKGV2ZW50TWFwKTsKCgkJCQlsb25nIGN1cnJlbnRUaW1lID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCk7CgoJCQkJbG9uZyBkaWZmID0gKGN1cnJlbnRUaW1lIC0gcHJldmlvdXNUaW1lLmdldCgpKTsKCgkJCQlTeXN0ZW0ub3V0LnByaW50bG4oIkRpZmZlcmVudGlhbDogIiArIGRpZmYpOwoKCQkJCS8vIGNoZWNrIHRoYXQgdGhlcmUgaXMgYXQgbGVhc3QgYSBkaWZmZXJlbnRpYWwgb2YgaGFsZiB0aGUgaW50ZXJ2YWwKCQkJCS8vIGJlY2F1c2Ugd2UgY2FuJ3QgcmVhbGx5IGd1YXJhbnRlZSB0aGF0IG1hY2hpbmUgdGltZSB3aWxsIGFjY3VyYXRlbHkKCQkJCS8vIHJlZmxlY3QgdGhlIHRpbWVvdXRzIHdlJ3ZlIHNldAoJCQkJaWYgKGRpZmYgPCAoaW50ZXJ2YWwgLyAyKSkgewoJCQkJCXJlc3VsdC5zZXQoZmFsc2UpOwoJCQkJfQoKCQkJCXByZXZpb3VzVGltZS5zZXQoY3VycmVudFRpbWUpOwoJCQkJY291bnRlci5pbmNyZW1lbnRBbmRHZXQoKTsKCQkJfQoKCQl9OwoKCQlyZXF1ZXN0QWR2aXNvci5ldmVudFNvdXJjZSgiczEiLCBudWxsLCBoYW5kbGVyKTsKCgkJaGFuZGxlci5jbG9zZSgpOwoKCQlBc3NlcnQuYXNzZXJ0VHJ1ZSgKCQkJIlRoZSBpbnRlcnZhbCBiZXR3ZWVuIGV2ZW50cyB3YXMgdG9vIHNob3J0LiBJdCBtZWFucyB0aGF0IHRoZSByZXNwb25zZSB3YXMgbm90IHByb3Blcmx5IHN0cmVhbWVkLiIsCgkJCXJlc3VsdC5nZXQoKSk7CgkJQXNzZXJ0LmFzc2VydEVxdWFscygxMCwgY291bnRlci5nZXQoKSk7Cgl9CgoJLy8gQnVnIDQ5MzU4MwoJQFRlc3QKCXB1YmxpYyB2b2lkIHRlc3Rfc3RyZWFtZWRfcmVzcG9uc2Vfd3JpdGVyKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CgkJZmluYWwgbG9uZyBpbnRlcnZhbCA9IDEwMEw7CgoJCVNlcnZsZXQgc2VydmxldDEgPSBuZXcgQmFzZVNlcnZsZXQoKSB7CgkJCXByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDFMOwoKCQkJQE92ZXJyaWRlCgkJCXByb3RlY3RlZCB2b2lkIHNlcnZpY2UoSHR0cFNlcnZsZXRSZXF1ZXN0IHJlcXVlc3QsIEh0dHBTZXJ2bGV0UmVzcG9uc2UgcmVzcG9uc2UpCgkJCQl0aHJvd3MgU2VydmxldEV4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewoKCQkgICAgICAgIHJlc3BvbnNlLnNldENvbnRlbnRUeXBlKCJ0ZXh0L2V2ZW50LXN0cmVhbSIpOwoJCSAgICAgICAgcmVzcG9uc2Uuc2V0Q2hhcmFjdGVyRW5jb2RpbmcoIlVURi04Iik7CgoJCQkJdHJ5IChQcmludFdyaXRlciB3cml0ZXIgPSByZXNwb25zZS5nZXRXcml0ZXIoKSkgewoJCQkJCWZvciAoaW50IGkgPSAxOyBpIDw9IDEwOyArK2kpIHsKCQkJCQkJdHJ5IHsKCQkJCQkJCVRocmVhZC5zbGVlcChpbnRlcnZhbCk7CgkJCQkJCX0KCQkJCQkJY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGUpIHsKCQkJCQkJCXRocm93IG5ldyBTZXJ2bGV0RXhjZXB0aW9uKGUpOwoJCQkJCQl9CgoJCQkJCQl3cml0ZXIucHJpbnQoImRhdGE6ICIpOwoJCQkJCQl3cml0ZXIucHJpbnQoU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCkpOwoJCQkJCQl3cml0ZXIucHJpbnQoIlxuXG4iKTsKCQkJCQkJd3JpdGVyLmZsdXNoKCk7CgkJCQkJfQoJCQkJfQoJCQl9CgkJfTsKCgkJRGljdGlvbmFyeTxTdHJpbmcsIE9iamVjdD4gcHJvcHMgPSBuZXcgSGFzaHRhYmxlPFN0cmluZywgT2JqZWN0PigpOwoJCXByb3BzLnB1dChIdHRwV2hpdGVib2FyZENvbnN0YW50cy5IVFRQX1dISVRFQk9BUkRfU0VSVkxFVF9QQVRURVJOLCAiL3MxLyoiKTsKCQlyZWdpc3RyYXRpb25zLmFkZChnZXRCdW5kbGVDb250ZXh0KCkucmVnaXN0ZXJTZXJ2aWNlKFNlcnZsZXQuY2xhc3MsIHNlcnZsZXQxLCBwcm9wcykpOwoKCQlmaW5hbCBBdG9taWNMb25nIHByZXZpb3VzVGltZSA9IG5ldyBBdG9taWNMb25nKFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpKTsKCQlmaW5hbCBBdG9taWNJbnRlZ2VyIGNvdW50ZXIgPSBuZXcgQXRvbWljSW50ZWdlcigpOwoJCWZpbmFsIEF0b21pY0Jvb2xlYW4gcmVzdWx0ID0gbmV3IEF0b21pY0Jvb2xlYW4odHJ1ZSk7CgoJCUV2ZW50SGFuZGxlciBoYW5kbGVyID0gbmV3IEV2ZW50SGFuZGxlcigpIHsKCgkJCUBPdmVycmlkZQoJCQlwdWJsaWMgdm9pZCBoYW5kbGUoTWFwPFN0cmluZywgU3RyaW5nPiBldmVudE1hcCkgewoJCQkJc3VwZXIuaGFuZGxlKGV2ZW50TWFwKTsKCgkJCQlsb25nIGN1cnJlbnRUaW1lID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCk7CgoJCQkJbG9uZyBkaWZmID0gKGN1cnJlbnRUaW1lIC0gcHJldmlvdXNUaW1lLmdldCgpKTsKCgkJCQlTeXN0ZW0ub3V0LnByaW50bG4oIkRpZmZlcmVudGlhbDogIiArIGRpZmYpOwoKCQkJCS8vIGNoZWNrIHRoYXQgdGhlcmUgaXMgYXQgbGVhc3QgYSBkaWZmZXJlbnRpYWwgb2YgaGFsZiB0aGUgaW50ZXJ2YWwKCQkJCS8vIGJlY2F1c2Ugd2UgY2FuJ3QgcmVhbGx5IGd1YXJhbnRlZSB0aGF0IG1hY2hpbmUgdGltZSB3aWxsIGFjY3VyYXRlbHkKCQkJCS8vIHJlZmxlY3QgdGhlIHRpbWVvdXRzIHdlJ3ZlIHNldAoJCQkJaWYgKGRpZmYgPCAoaW50ZXJ2YWwgLyAyKSkgewoJCQkJCXJlc3VsdC5zZXQoZmFsc2UpOwoJCQkJfQoKCQkJCXByZXZpb3VzVGltZS5zZXQoY3VycmVudFRpbWUpOwoJCQkJY291bnRlci5pbmNyZW1lbnRBbmRHZXQoKTsKCQkJfQoKCQl9OwoKCQlyZXF1ZXN0QWR2aXNvci5ldmVudFNvdXJjZSgiczEiLCBudWxsLCBoYW5kbGVyKTsKCgkJaGFuZGxlci5jbG9zZSgpOwoKCQlBc3NlcnQuYXNzZXJ0VHJ1ZSgKCQkJIlRoZSBpbnRlcnZhbCBiZXR3ZWVuIGV2ZW50cyB3YXMgdG9vIHNob3J0LiBJdCBtZWFucyB0aGF0IHRoZSByZXNwb25zZSB3YXMgbm90IHByb3Blcmx5IHN0cmVhbWVkLiIsCgkJCXJlc3VsdC5nZXQoKSk7CgkJQXNzZXJ0LmFzc2VydEVxdWFscygxMCwgY291bnRlci5nZXQoKSk7Cgl9Cgp9