LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29weXJpZ2h0IChjKSAyMDA2LCAyMDA3IEVjbGlwc2UgRm91bmRhdGlvbgogKiBBbGwgcmlnaHRzIHJlc2VydmVkLiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzCiAqIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2UgdjEuMAogKiB3aGljaCBhY2NvbXBhbmllcyB0aGlzIGRpc3RyaWJ1dGlvbiwgYW5kIGlzIGF2YWlsYWJsZSBhdAogKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC12MTAuaHRtbAogKiAKICogQ29udHJpYnV0b3JzOgogKiAgICAgSmVzcGVyIFN0ZWVuIE34bGxlciAtIGplc3BlckBzZWxza2FiZXQub3JnCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpwYWNrYWdlIG9yZy5lY2xpcHNlLndzdC54bWwuY29yZS50ZXN0cy5mb3JtYXQ7CgppbXBvcnQgamF2YS5pby5CeXRlQXJyYXlPdXRwdXRTdHJlYW07CmltcG9ydCBqYXZhLmlvLkZpbGVOb3RGb3VuZEV4Y2VwdGlvbjsKaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247CmltcG9ydCBqYXZhLmlvLklucHV0U3RyZWFtOwppbXBvcnQgamF2YS5pby5VbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uOwoKaW1wb3J0IGp1bml0LmZyYW1ld29yay5UZXN0Q2FzZTsKCmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJlc291cmNlcy5JQ29udGFpbmVyOwppbXBvcnQgb3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMuSVByb2plY3Q7CmltcG9ydCBvcmcuZWNsaXBzZS5jb3JlLnJ1bnRpbWUuQ29yZUV4Y2VwdGlvbjsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zc2UuY29yZS5TdHJ1Y3R1cmVkTW9kZWxNYW5hZ2VyOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNzZS5jb3JlLmludGVybmFsLmZvcm1hdC5BYnN0cmFjdFN0cnVjdHVyZWRGb3JtYXRQcm9jZXNzb3I7CmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc3NlLmNvcmUuaW50ZXJuYWwuZm9ybWF0LklTdHJ1Y3R1cmVkRm9ybWF0UHJlZmVyZW5jZXM7CmltcG9ydCBvcmcuZWNsaXBzZS53c3Quc3NlLmNvcmUuaW50ZXJuYWwucHJvdmlzaW9uYWwuSU1vZGVsTWFuYWdlcjsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC5zc2UuY29yZS5pbnRlcm5hbC5wcm92aXNpb25hbC5JU3RydWN0dXJlZE1vZGVsOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnNzZS5jb3JlLmludGVybmFsLnV0aWwuVVJJUmVzb2x2ZXI7CmltcG9ydCBvcmcuZWNsaXBzZS53c3QueG1sLmNvcmUuaW50ZXJuYWwucHJvdmlzaW9uYWwuZm9ybWF0LkZvcm1hdFByb2Nlc3NvclhNTDsKaW1wb3J0IG9yZy5lY2xpcHNlLndzdC54bWwuY29yZS5pbnRlcm5hbC5wcm92aXNpb25hbC5mb3JtYXQuU3RydWN0dXJlZEZvcm1hdFByZWZlcmVuY2VzWE1MOwppbXBvcnQgb3JnLmVjbGlwc2Uud3N0LnhtbC5jb3JlLnRlc3RzLnV0aWwuU3RyaW5nQ29tcGFyZVV0aWw7CgpwdWJsaWMgY2xhc3MgVGVzdEZvcm1hdFByb2Nlc3NvclhNTCBleHRlbmRzIFRlc3RDYXNlIHsKCglwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuIFNQTElUX01VTFRJX0FUVFJTID0gZmFsc2U7CgoJcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIElOREVOVCA9ICJcdCI7CgoJcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbiBDTEVBUl9BTExfQkxBTktfTElORVMgPSBmYWxzZTsKCglwcml2YXRlIHN0YXRpYyBmaW5hbCBpbnQgTUFYX0xJTkVfV0lEVEggPSA3MjsKCglwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgVVRGXzggPSAiVVRGLTgiOwoKCXByaXZhdGUgU3RyaW5nQ29tcGFyZVV0aWwgZlN0cmluZ0NvbXBhcmVVdGlsOwoKCXB1YmxpYyBUZXN0Rm9ybWF0UHJvY2Vzc29yWE1MKFN0cmluZyBuYW1lKSB7CgkJc3VwZXIobmFtZSk7Cgl9CgoJcHJpdmF0ZSBGb3JtYXRQcm9jZXNzb3JYTUwgZm9ybWF0UHJvY2Vzc29yOwoKCXByb3RlY3RlZCB2b2lkIHNldFVwKCkgdGhyb3dzIEV4Y2VwdGlvbiB7CgkJZm9ybWF0UHJvY2Vzc29yID0gbmV3IEZvcm1hdFByb2Nlc3NvclhNTCgpOwoJCWZTdHJpbmdDb21wYXJlVXRpbCA9IG5ldyBTdHJpbmdDb21wYXJlVXRpbCgpOwoJfQoKCS8qKgoJICogbXVzdCByZWxlYXNlIG1vZGVsIChmcm9tIGVkaXQpIGFmdGVyCgkgKiAKCSAqIEBwYXJhbSBmaWxlbmFtZQoJICogICAgICAgICAgICByZWxhdGl2ZSB0byB0aGlzIGNsYXNzIChUZXN0U3RydWN0dXJlZFBhcnRpdGlvbmVyKQoJICovCglwcml2YXRlIElTdHJ1Y3R1cmVkTW9kZWwgZ2V0TW9kZWxGb3JFZGl0KGZpbmFsIFN0cmluZyBmaWxlbmFtZSkgewoKCQlJU3RydWN0dXJlZE1vZGVsIG1vZGVsID0gbnVsbDsKCQl0cnkgewoJCQlJTW9kZWxNYW5hZ2VyIG1vZGVsTWFuYWdlciA9IFN0cnVjdHVyZWRNb2RlbE1hbmFnZXIuZ2V0TW9kZWxNYW5hZ2VyKCk7CgkJCUlucHV0U3RyZWFtIGluU3RyZWFtID0gZ2V0Q2xhc3MoKS5nZXRSZXNvdXJjZUFzU3RyZWFtKGZpbGVuYW1lKTsKCQkJaWYgKGluU3RyZWFtID09IG51bGwpCgkJCQl0aHJvdyBuZXcgRmlsZU5vdEZvdW5kRXhjZXB0aW9uKCJDYW4ndCBmaWxlIHJlc291cmNlIHN0cmVhbSAiICsgZmlsZW5hbWUpOwoJCQlmaW5hbCBTdHJpbmcgYmFzZUZpbGUgPSBnZXRDbGFzcygpLmdldFJlc291cmNlKGZpbGVuYW1lKS50b1N0cmluZygpOwoJCQltb2RlbCA9IG1vZGVsTWFuYWdlci5nZXRNb2RlbEZvckVkaXQoYmFzZUZpbGUsIGluU3RyZWFtLCBuZXcgVVJJUmVzb2x2ZXIoKSB7CgoJCQkJU3RyaW5nIGZCYXNlID0gYmFzZUZpbGU7CgoJCQkJcHVibGljIFN0cmluZyBnZXRGaWxlQmFzZUxvY2F0aW9uKCkgewoJCQkJCXJldHVybiBmQmFzZTsKCQkJCX0KCgkJCQlwdWJsaWMgU3RyaW5nIGdldExvY2F0aW9uQnlVUkkoU3RyaW5nIHVyaSkgewoJCQkJCXJldHVybiBnZXRMb2NhdGlvbkJ5VVJJKHVyaSwgZkJhc2UpOwoJCQkJfQoKCQkJCXB1YmxpYyBTdHJpbmcgZ2V0TG9jYXRpb25CeVVSSShTdHJpbmcgdXJpLCBib29sZWFuIHJlc29sdmVDcm9zc1Byb2plY3RMaW5rcykgewoJCQkJCXJldHVybiBnZXRMb2NhdGlvbkJ5VVJJKHVyaSk7CgkJCQl9CgoJCQkJcHVibGljIFN0cmluZyBnZXRMb2NhdGlvbkJ5VVJJKFN0cmluZyB1cmksIFN0cmluZyBiYXNlUmVmZXJlbmNlKSB7CgkJCQkJaW50IGxhc3RTbGFzaCA9IGJhc2VSZWZlcmVuY2UubGFzdEluZGV4T2YoIi8iKTsKCQkJCQlpZiAobGFzdFNsYXNoID4gMCkKCQkJCQkJcmV0dXJuIGJhc2VSZWZlcmVuY2Uuc3Vic3RyaW5nKDAsIGxhc3RTbGFzaCArIDEpICsgdXJpOwoJCQkJCXJldHVybiBiYXNlUmVmZXJlbmNlOwoJCQkJfQoKCQkJCXB1YmxpYyBTdHJpbmcgZ2V0TG9jYXRpb25CeVVSSShTdHJpbmcgdXJpLCBTdHJpbmcgYmFzZVJlZmVyZW5jZSwgYm9vbGVhbiByZXNvbHZlQ3Jvc3NQcm9qZWN0TGlua3MpIHsKCQkJCQlyZXR1cm4gZ2V0TG9jYXRpb25CeVVSSSh1cmksIGJhc2VSZWZlcmVuY2UpOwoJCQkJfQoKCQkJCXB1YmxpYyBJUHJvamVjdCBnZXRQcm9qZWN0KCkgewoJCQkJCXJldHVybiBudWxsOwoJCQkJfQoKCQkJCXB1YmxpYyBJQ29udGFpbmVyIGdldFJvb3RMb2NhdGlvbigpIHsKCQkJCQlyZXR1cm4gbnVsbDsKCQkJCX0KCgkJCQlwdWJsaWMgSW5wdXRTdHJlYW0gZ2V0VVJJU3RyZWFtKFN0cmluZyB1cmkpIHsKCQkJCQlyZXR1cm4gZ2V0Q2xhc3MoKS5nZXRSZXNvdXJjZUFzU3RyZWFtKGdldExvY2F0aW9uQnlVUkkodXJpKSk7CgkJCQl9CgoJCQkJcHVibGljIHZvaWQgc2V0RmlsZUJhc2VMb2NhdGlvbihTdHJpbmcgbmV3TG9jYXRpb24pIHsKCQkJCQl0aGlzLmZCYXNlID0gbmV3TG9jYXRpb247CgkJCQl9CgoJCQkJcHVibGljIHZvaWQgc2V0UHJvamVjdChJUHJvamVjdCBuZXdQcm9qZWN0KSB7CgkJCQl9CgkJCX0pOwoJCX0KCQljYXRjaCAoSU9FeGNlcHRpb24gZXgpIHsKCQkJZXgucHJpbnRTdGFja1RyYWNlKCk7CgkJfQoJCXJldHVybiBtb2RlbDsKCX0KCglwcm90ZWN0ZWQgdm9pZCBmb3JtYXRBbmRBc3NlcnRFcXVhbHMoU3RyaW5nIGJlZm9yZVBhdGgsIFN0cmluZyBhZnRlclBhdGgpIHRocm93cyBVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiwgQ29yZUV4Y2VwdGlvbiB7CgkJZm9ybWF0QW5kQXNzZXJ0RXF1YWxzKGJlZm9yZVBhdGgsIGFmdGVyUGF0aCwgdHJ1ZSk7Cgl9CgoJcHJpdmF0ZSB2b2lkIGZvcm1hdEFuZEFzc2VydEVxdWFscyhTdHJpbmcgYmVmb3JlUGF0aCwgU3RyaW5nIGFmdGVyUGF0aCwgYm9vbGVhbiByZXNldFByZWZlcmVuY2VzKSB0aHJvd3MgVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiwgSU9FeGNlcHRpb24sIENvcmVFeGNlcHRpb24gewoJCUlTdHJ1Y3R1cmVkTW9kZWwgYmVmb3JlTW9kZWwgPSBudWxsLCBhZnRlck1vZGVsID0gbnVsbDsKCQl0cnkgewoJCQliZWZvcmVNb2RlbCA9IGdldE1vZGVsRm9yRWRpdChiZWZvcmVQYXRoKTsKCQkJYXNzZXJ0Tm90TnVsbCgiY291bGQgbm90IHJldHJpZXZlIHN0cnVjdHVyZWQgbW9kZWwgZm9yIDogIiArIGJlZm9yZVBhdGgsIGJlZm9yZU1vZGVsKTsKCgkJCWFmdGVyTW9kZWwgPSBnZXRNb2RlbEZvckVkaXQoYWZ0ZXJQYXRoKTsKCQkJYXNzZXJ0Tm90TnVsbCgiY291bGQgbm90IHJldHJpZXZlIHN0cnVjdHVyZWQgbW9kZWwgZm9yIDogIiArIGFmdGVyUGF0aCwgYWZ0ZXJNb2RlbCk7CgoJCQlpZiAocmVzZXRQcmVmZXJlbmNlcykKCQkJCXJlc2V0UHJlZmVyZW5jZXNUb0RlZmF1bHQoKTsKCgkJCSgoQWJzdHJhY3RTdHJ1Y3R1cmVkRm9ybWF0UHJvY2Vzc29yKSBmb3JtYXRQcm9jZXNzb3IpLnJlZnJlc2hGb3JtYXRQcmVmZXJlbmNlcyA9IGZhbHNlOwoJCQlmb3JtYXRQcm9jZXNzb3IuZm9ybWF0TW9kZWwoYmVmb3JlTW9kZWwpOwoJCQkoKEFic3RyYWN0U3RydWN0dXJlZEZvcm1hdFByb2Nlc3NvcikgZm9ybWF0UHJvY2Vzc29yKS5yZWZyZXNoRm9ybWF0UHJlZmVyZW5jZXMgPSB0cnVlOwoKCQkJQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGZvcm1hdHRlZEJ5dGVzID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOwoJCQliZWZvcmVNb2RlbC5zYXZlKGZvcm1hdHRlZEJ5dGVzKTsgLy8gImJlZm9yZU1vZGVsIiBzaG91bGQgbm93IGJlCgkJCS8vIGFmdGVyIHRoZSBmb3JtYXR0ZXIKCgkJCUJ5dGVBcnJheU91dHB1dFN0cmVhbSBhZnRlckJ5dGVzID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOwoJCQlhZnRlck1vZGVsLnNhdmUoYWZ0ZXJCeXRlcyk7CgoJCQlTdHJpbmcgZXhwZWN0ZWRDb250ZW50cyA9IG5ldyBTdHJpbmcoYWZ0ZXJCeXRlcy50b0J5dGVBcnJheSgpLCBVVEZfOCk7CgkJCVN0cmluZyBhY3R1YWxDb250ZW50cyA9IG5ldyBTdHJpbmcoZm9ybWF0dGVkQnl0ZXMudG9CeXRlQXJyYXkoKSwgVVRGXzgpOwoJCQlhc3NlcnRUcnVlKCJGb3JtYXR0ZWQgZG9jdW1lbnQgZGlmZmVycyBmcm9tIHRoZSBleHBlY3RlZC5cbkV4cGVjdGVkIENvbnRlbnRzOlxuIiArIGV4cGVjdGVkQ29udGVudHMgKyAiXG5BY3R1YWwgQ29udGVudHM6XG4iICsgYWN0dWFsQ29udGVudHMsIGZTdHJpbmdDb21wYXJlVXRpbC5lcXVhbHNJZ25vcmVMaW5lU2VwZXJhdG9yKGV4cGVjdGVkQ29udGVudHMsIGFjdHVhbENvbnRlbnRzKSk7CgkJfQoJCWZpbmFsbHkgewoJCQlpZiAoYmVmb3JlTW9kZWwgIT0gbnVsbCkKCQkJCWJlZm9yZU1vZGVsLnJlbGVhc2VGcm9tRWRpdCgpOwoJCQlpZiAoYWZ0ZXJNb2RlbCAhPSBudWxsKQoJCQkJYWZ0ZXJNb2RlbC5yZWxlYXNlRnJvbUVkaXQoKTsKCQl9Cgl9CgoJcHJpdmF0ZSB2b2lkIHJlc2V0UHJlZmVyZW5jZXNUb0RlZmF1bHQoKSB7CgkJSVN0cnVjdHVyZWRGb3JtYXRQcmVmZXJlbmNlcyBmb3JtYXRQcmVmZXJlbmNlcyA9IGZvcm1hdFByb2Nlc3Nvci5nZXRGb3JtYXRQcmVmZXJlbmNlcygpOwoJCWZvcm1hdFByZWZlcmVuY2VzLnNldExpbmVXaWR0aChNQVhfTElORV9XSURUSCk7CgkJZm9ybWF0UHJlZmVyZW5jZXMuc2V0Q2xlYXJBbGxCbGFua0xpbmVzKENMRUFSX0FMTF9CTEFOS19MSU5FUyk7CgkJZm9ybWF0UHJlZmVyZW5jZXMuc2V0SW5kZW50KElOREVOVCk7CgkJKChTdHJ1Y3R1cmVkRm9ybWF0UHJlZmVyZW5jZXNYTUwpIGZvcm1hdFByZWZlcmVuY2VzKS5zZXRTcGxpdE11bHRpQXR0cnMoU1BMSVRfTVVMVElfQVRUUlMpOwoJfQoKCXB1YmxpYyB2b2lkIHRlc3RTaW1wbGVYbWwoKSB0aHJvd3MgVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiwgSU9FeGNlcHRpb24sIENvcmVFeGNlcHRpb24gewoJCWZvcm1hdEFuZEFzc2VydEVxdWFscygidGVzdGZpbGVzL3htbC9zaW1wbGUtc3RhbmRhbG9uZS54bWwiLCAidGVzdGZpbGVzL3htbC9zaW1wbGUtc3RhbmRhbG9uZS1mbXQueG1sIik7Cgl9CgoJcHVibGljIHZvaWQgdGVzdFByZXNlcnZlRm9ybWF0KCkgdGhyb3dzIFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24sIElPRXhjZXB0aW9uLCBDb3JlRXhjZXB0aW9uIHsKCQlmb3JtYXRBbmRBc3NlcnRFcXVhbHMoInRlc3RmaWxlcy94bWwveG1sLXNwYWNlLXByZXNlcnZlLXN0YW5kYWxvbmUueG1sIiwgInRlc3RmaWxlcy94bWwveG1sLXNwYWNlLXByZXNlcnZlLXN0YW5kYWxvbmUtZm10LnhtbCIpOwoJfQoKCXB1YmxpYyB2b2lkIHRlc3RQcmVzZXJ2ZUZvcm1hdERURCgpIHRocm93cyBVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiwgQ29yZUV4Y2VwdGlvbiB7CgkJZm9ybWF0QW5kQXNzZXJ0RXF1YWxzKCJ0ZXN0ZmlsZXMveG1sL3htbC1zcGFjZS1wcmVzZXJ2ZS1kdGQueG1sIiwgInRlc3RmaWxlcy94bWwveG1sLXNwYWNlLXByZXNlcnZlLWR0ZC1mbXQueG1sIik7Cgl9CgoJcHVibGljIHZvaWQgdGVzdE9uZUxpbmVGb3JtYXQoKSB0aHJvd3MgVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiwgSU9FeGNlcHRpb24sIENvcmVFeGNlcHRpb24gewoJCS8vIEJVRzExNTcxNgoJCWZvcm1hdEFuZEFzc2VydEVxdWFscygidGVzdGZpbGVzL3htbC9vbmVsaW5lLnhtbCIsICJ0ZXN0ZmlsZXMveG1sL29uZWxpbmUtZm10LnhtbCIpOwoJfQoKCXB1YmxpYyB2b2lkIHRlc3RPbmVMaW5lVGV4dE5vZGVGb3JtYXQoKSB0aHJvd3MgVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiwgSU9FeGNlcHRpb24sIENvcmVFeGNlcHRpb24gewoJCS8vIEJVRzE2NjQ0MQoJCWZvcm1hdEFuZEFzc2VydEVxdWFscygidGVzdGZpbGVzL3htbC9vbmVsaW5lVGV4dE5vZGUueG1sIiwgInRlc3RmaWxlcy94bWwvb25lbGluZVRleHROb2RlLWZtdC54bWwiKTsKCX0KCglwdWJsaWMgdm9pZCB0ZXN0RW1wdHlDb250ZW50Tm9kZUZvcm1hdCgpIHRocm93cyBVbnN1cHBvcnRlZEVuY29kaW5nRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiwgQ29yZUV4Y2VwdGlvbiB7CgkJLy8gQlVHMTc0MjQzCgkJSVN0cnVjdHVyZWRGb3JtYXRQcmVmZXJlbmNlcyBmb3JtYXRQcmVmZXJlbmNlcyA9IGZvcm1hdFByb2Nlc3Nvci5nZXRGb3JtYXRQcmVmZXJlbmNlcygpOwoJCSgoU3RydWN0dXJlZEZvcm1hdFByZWZlcmVuY2VzWE1MKSBmb3JtYXRQcmVmZXJlbmNlcykuc2V0U3BsaXRNdWx0aUF0dHJzKHRydWUpOwoJCWZvcm1hdEFuZEFzc2VydEVxdWFscygidGVzdGZpbGVzL3htbC91c2V0YWdzd2l0aGVtcHR5Y29udGVudC54bWwiLCAidGVzdGZpbGVzL3htbC91c2V0YWdzd2l0aGVtcHR5Y29udGVudC1mbXQueG1sIiwgZmFsc2UpOwoJfQoKCXB1YmxpYyB2b2lkIHRlc3RYU0xGb3JtYXQoKSB0aHJvd3MgVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiwgSU9FeGNlcHRpb24sIENvcmVFeGNlcHRpb24gewoJCS8vIEJVRzEwODA3NAoJCWZvcm1hdEFuZEFzc2VydEVxdWFscygidGVzdGZpbGVzL3htbC94c2xhdHRyaWJ1dGV0ZXh0LnhzbCIsICJ0ZXN0ZmlsZXMveG1sL3hzbGF0dHJpYnV0ZXRleHQtZm10LnhzbCIpOwoJfQoKCXB1YmxpYyB2b2lkIHRlc3RFbnRpdHlGb3JtYXQoKSB0aHJvd3MgVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiwgSU9FeGNlcHRpb24sIENvcmVFeGNlcHRpb24gewoJCS8vIEJVRzEwMjA3NgoJCWZvcm1hdEFuZEFzc2VydEVxdWFscygidGVzdGZpbGVzL3htbC9lbnRpdGllcy54bWwiLCAidGVzdGZpbGVzL3htbC9lbnRpdGllcy1mbXQueG1sIik7Cgl9CgoJcHVibGljIHZvaWQgdGVzdFByZXNlcnZlUENEQVRBRm9ybWF0KCkgdGhyb3dzIFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24sIElPRXhjZXB0aW9uLCBDb3JlRXhjZXB0aW9uIHsKCQkvLyBCVUc4NDY4OAoJCUlTdHJ1Y3R1cmVkRm9ybWF0UHJlZmVyZW5jZXMgZm9ybWF0UHJlZmVyZW5jZXMgPSBmb3JtYXRQcm9jZXNzb3IuZ2V0Rm9ybWF0UHJlZmVyZW5jZXMoKTsKCQkoKFN0cnVjdHVyZWRGb3JtYXRQcmVmZXJlbmNlc1hNTCkgZm9ybWF0UHJlZmVyZW5jZXMpLnNldFByZXNlcnZlUENEQVRBQ29udGVudCh0cnVlKTsKCQlmb3JtYXRBbmRBc3NlcnRFcXVhbHMoInRlc3RmaWxlcy94bWwveG1sLXByZXNlcnZlcGNkYXRhLnhtbCIsICJ0ZXN0ZmlsZXMveG1sL3htbC1wcmVzZXJ2ZXBjZGF0YS15ZXMtZm10LnhtbCIsIGZhbHNlKTsKCgkJKChTdHJ1Y3R1cmVkRm9ybWF0UHJlZmVyZW5jZXNYTUwpIGZvcm1hdFByZWZlcmVuY2VzKS5zZXRQcmVzZXJ2ZVBDREFUQUNvbnRlbnQoZmFsc2UpOwoJCWZvcm1hdEFuZEFzc2VydEVxdWFscygidGVzdGZpbGVzL3htbC94bWwtcHJlc2VydmVwY2RhdGEueG1sIiwgInRlc3RmaWxlcy94bWwveG1sLXByZXNlcnZlcGNkYXRhLW5vLWZtdC54bWwiLCBmYWxzZSk7Cgl9CgoJcHVibGljIHZvaWQgdGVzdFByZXNlcnZlQ0RBVEFGb3JtYXQoKSB0aHJvd3MgVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiwgSU9FeGNlcHRpb24sIENvcmVFeGNlcHRpb24gewoJCS8vIEJVRzE2MTMzMAoJCWZvcm1hdEFuZEFzc2VydEVxdWFscygidGVzdGZpbGVzL3htbC91c2VjZGF0YS54bWwiLCAidGVzdGZpbGVzL3htbC91c2VjZGF0YS1mbXQueG1sIik7CgkJZm9ybWF0QW5kQXNzZXJ0RXF1YWxzKCJ0ZXN0ZmlsZXMveG1sL3VzZWNkYXRhMi54bWwiLCAidGVzdGZpbGVzL3htbC91c2VjZGF0YTItZm10LnhtbCIpOwoJfQoKCXB1YmxpYyB2b2lkIHRlc3RTcGxpdEF0dHJpYnV0ZXNGb3JtYXQoKSB0aHJvd3MgVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbiwgSU9FeGNlcHRpb24sIENvcmVFeGNlcHRpb24gewoJCS8vIEJVRzExMzU4NAoJCUlTdHJ1Y3R1cmVkRm9ybWF0UHJlZmVyZW5jZXMgZm9ybWF0UHJlZmVyZW5jZXMgPSBmb3JtYXRQcm9jZXNzb3IuZ2V0Rm9ybWF0UHJlZmVyZW5jZXMoKTsKCQkoKFN0cnVjdHVyZWRGb3JtYXRQcmVmZXJlbmNlc1hNTCkgZm9ybWF0UHJlZmVyZW5jZXMpLnNldFNwbGl0TXVsdGlBdHRycyh0cnVlKTsKCQkoKFN0cnVjdHVyZWRGb3JtYXRQcmVmZXJlbmNlc1hNTCkgZm9ybWF0UHJlZmVyZW5jZXMpLnNldEFsaWduRW5kQnJhY2tldChmYWxzZSk7CgkJZm9ybWF0QW5kQXNzZXJ0RXF1YWxzKCJ0ZXN0ZmlsZXMveG1sL211bHRpYXR0cmlidXRlcy54bWwiLCAidGVzdGZpbGVzL3htbC9tdWx0aWF0dHJpYnV0ZXMteWVzc3BsaXQtbm9hbGlnbi1mbXQueG1sIiwgZmFsc2UpOwoKCQkoKFN0cnVjdHVyZWRGb3JtYXRQcmVmZXJlbmNlc1hNTCkgZm9ybWF0UHJlZmVyZW5jZXMpLnNldFNwbGl0TXVsdGlBdHRycyhmYWxzZSk7CgkJKChTdHJ1Y3R1cmVkRm9ybWF0UHJlZmVyZW5jZXNYTUwpIGZvcm1hdFByZWZlcmVuY2VzKS5zZXRBbGlnbkVuZEJyYWNrZXQoZmFsc2UpOwoJCWZvcm1hdEFuZEFzc2VydEVxdWFscygidGVzdGZpbGVzL3htbC9tdWx0aWF0dHJpYnV0ZXMueG1sIiwgInRlc3RmaWxlcy94bWwvbXVsdGlhdHRyaWJ1dGVzLW5vc3BsaXQtbm9hbGlnbi1mbXQueG1sIiwgZmFsc2UpOwoKCX0KCglwdWJsaWMgdm9pZCB0ZXN0QWxpZ25FbmRCcmFja2V0Rm9ybWF0KCkgdGhyb3dzIFVuc3VwcG9ydGVkRW5jb2RpbmdFeGNlcHRpb24sIElPRXhjZXB0aW9uLCBDb3JlRXhjZXB0aW9uIHsKCQkvLyBCVUcxMTM1ODQKCQlJU3RydWN0dXJlZEZvcm1hdFByZWZlcmVuY2VzIGZvcm1hdFByZWZlcmVuY2VzID0gZm9ybWF0UHJvY2Vzc29yLmdldEZvcm1hdFByZWZlcmVuY2VzKCk7CgkJKChTdHJ1Y3R1cmVkRm9ybWF0UHJlZmVyZW5jZXNYTUwpIGZvcm1hdFByZWZlcmVuY2VzKS5zZXRTcGxpdE11bHRpQXR0cnMoZmFsc2UpOwoJCSgoU3RydWN0dXJlZEZvcm1hdFByZWZlcmVuY2VzWE1MKSBmb3JtYXRQcmVmZXJlbmNlcykuc2V0QWxpZ25FbmRCcmFja2V0KHRydWUpOwoJCWZvcm1hdEFuZEFzc2VydEVxdWFscygidGVzdGZpbGVzL3htbC9tdWx0aWF0dHJpYnV0ZXMueG1sIiwgInRlc3RmaWxlcy94bWwvbXVsdGlhdHRyaWJ1dGVzLW5vc3BsaXQteWVzYWxpZ24tZm10LnhtbCIsIGZhbHNlKTsKCgkJKChTdHJ1Y3R1cmVkRm9ybWF0UHJlZmVyZW5jZXNYTUwpIGZvcm1hdFByZWZlcmVuY2VzKS5zZXRTcGxpdE11bHRpQXR0cnModHJ1ZSk7CgkJKChTdHJ1Y3R1cmVkRm9ybWF0UHJlZmVyZW5jZXNYTUwpIGZvcm1hdFByZWZlcmVuY2VzKS5zZXRBbGlnbkVuZEJyYWNrZXQodHJ1ZSk7CgkJZm9ybWF0QW5kQXNzZXJ0RXF1YWxzKCJ0ZXN0ZmlsZXMveG1sL211bHRpYXR0cmlidXRlcy54bWwiLCAidGVzdGZpbGVzL3htbC9tdWx0aWF0dHJpYnV0ZXMteWVzc3BsaXQteWVzYWxpZ24tZm10LnhtbCIsIGZhbHNlKTsKCgl9Cn0K