ZGlmZiAtLWdpdCBhL0VQUGx1cy9DZWxsU3RvcmUuY3MgYi9FUFBsdXMvQ2VsbFN0b3JlLmNzCmluZGV4IDY1MzYzMjUuLjllMDVhMDYgMTAwNjQ0Ci0tLSBhL0VQUGx1cy9DZWxsU3RvcmUuY3MKKysrIGIvRVBQbHVzL0NlbGxTdG9yZS5jcwpAQCAtNTIsNyArNTIsNyBAQAogICAgICAgICAgICAgc2V0OwogICAgICAgICB9CiAgICAgfSAgICAgICAgCi0gICAgaW50ZXJuYWwgY2xhc3MgQ29sdW1uSW5kZXggOiBJbmRleEJhc2UsIElEaXNwb3NhYmxlCisgICAgaW50ZXJuYWwgY2xhc3MgQ29sdW1uSW5kZXggOiBJbmRleEJhc2UKICAgICB7CiAgICAgICAgIGludGVybmFsIEluZGV4QmFzZSBfc2VhcmNoSXg9bmV3IEluZGV4QmFzZSgpOwogICAgICAgICBwdWJsaWMgQ29sdW1uSW5kZXggKCkKQEAgLTIwMSwyMSArMjAxLDkgQEAKICAgICAgICAgfQogICAgICAgICBpbnRlcm5hbCBQYWdlSW5kZXhbXSBfcGFnZXM7CiAgICAgICAgIGludGVybmFsIGludCBQYWdlQ291bnQ7Ci0KLSAgICBwdWJsaWMgdm9pZCBEaXNwb3NlKCkKLSAgICB7Ci0gICAgICAgIGlmIChfcGFnZXMgIT0gbnVsbCkKLSAgICAgICAgewotICAgICAgICAgICAgZm9yIChpbnQgcCA9IDA7IHAgPCBQYWdlQ291bnQ7IHArKykKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAoKElEaXNwb3NhYmxlKV9wYWdlc1twXSkuRGlzcG9zZSgpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgX3BhZ2VzID0gbnVsbDsKLSAgICAgICAgfQogICAgIH0KIAotICAgIH0KLSAgICBpbnRlcm5hbCBjbGFzcyBQYWdlSW5kZXggOiBJbmRleEJhc2UsIElEaXNwb3NhYmxlCisgICAgaW50ZXJuYWwgY2xhc3MgUGFnZUluZGV4IDogSW5kZXhCYXNlCiAgICAgewogICAgICAgICBpbnRlcm5hbCBJbmRleEJhc2UgX3NlYXJjaEl4ID0gbmV3IEluZGV4QmFzZSgpOwogICAgICAgICBwdWJsaWMgUGFnZUluZGV4KCkKQEAgLTMxOSwxNiArMzA3LDEyIEBACiAgICAgICAgIHsKICAgICAgICAgICAgIHJldHVybiBJbmRleE9mZnNldCArIFJvd3NbcG9zXS5JbmRleDsKICAgICAgICAgfQotICAgICAgICBwdWJsaWMgdm9pZCBEaXNwb3NlKCkKLSAgICAgICAgewotICAgICAgICAgICAgUm93cyA9IG51bGw7Ci0gICAgICAgIH0KICAgICB9CiAgICAgLy8vIDxzdW1tYXJ5PgogICAgIC8vLyBUaGlzIGlzIHRoZSBzdG9yZSBmb3IgYWxsIFJvd3MsIENvbHVtbnMgYW5kIENlbGxzLgogICAgIC8vLyBJdCBpcyBhIERpY3Rpb25hcnkgaW1wbGVtZW50YXRpb24gdGhhdCBhbGxvd3MgeW91IHRvIGNoYW5nZSB0aGUgS2V5ICh0aGUgUm93SUQsIENvbHVtbklEIG9yIENlbGxJRCApCiAgICAgLy8vIDwvc3VtbWFyeT4KLSAgICBpbnRlcm5hbCBjbGFzcyBDZWxsU3RvcmU8VD4gOiBJRGlzcG9zYWJsZS8vIDogSUVudW1lcmFibGU8dWxvbmc+LCBJRW51bWVyYXRvcjx1bG9uZz4KKyAgICBpbnRlcm5hbCBjbGFzcyBDZWxsU3RvcmU8VD4KICAgICB7CiAgICAgICAgIC8qKioqIFNpemUgY29uc3RhbnRzICoqKiovCiAgICAgICAgIGludGVybmFsIGNvbnN0IGludCBwYWdlQml0cyA9IDEwOyAgIC8vMTNiaXRzPTgxOTIgIE5vdGU6IE1heGltdW0gaXMgMTMgYml0cyBzaW5jZSBzaG9ydCBpcyB1c2VkIChQYWdlTWF4PTE2SykKQEAgLTE0MzEsMjMgKzE0MTUsNiBAQAogICAgICAgICAgICAgfQogICAgICAgICB9CiAKLSAgICAgICAgcHVibGljIHZvaWQgRGlzcG9zZSgpCi0gICAgICAgIHsKLSAgICAgICAgICAgIGlmKF92YWx1ZXMhPW51bGwpIF92YWx1ZXMuQ2xlYXIoKTsKLSAgICAgICAgICAgIGlmIChfY29sdW1uSW5kZXggIT0gbnVsbCkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBmb3IgKHZhciBjID0gMDsgYyA8IENvbHVtbkNvdW50OyBjKyspCi0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICBpZiAoX2NvbHVtbkluZGV4W2NdICE9IG51bGwpCi0gICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICgoSURpc3Bvc2FibGUpX2NvbHVtbkluZGV4W2NdKS5EaXNwb3NlKCk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBfdmFsdWVzID0gbnVsbDsKLSAgICAgICAgICAgIF9jb2x1bW5JbmRleCA9IG51bGw7Ci0gICAgICAgIH0KLQogICAgICAgICAvL29iamVjdCBJRW51bWVyYXRvci5DdXJyZW50CiAgICAgICAgIC8vewogICAgICAgICAvLyAgICBnZXQgCkBAIC0xOTQyLDEwICsxOTA5LDcgQEAKICAgICAgICAgICAgIH0KICAgICAgICAgfQogCi0gICAgICAgIHB1YmxpYyB2b2lkIERpc3Bvc2UoKQotICAgICAgICB7Ci0gICAgICAgICAgICAvL19jZWxsU3RvcmU9bnVsbDsKLSAgICAgICAgfQorICAgICAgICBwdWJsaWMgdm9pZCBEaXNwb3NlKCkgeyB9CiAKICAgICAgICAgb2JqZWN0IElFbnVtZXJhdG9yLkN1cnJlbnQKICAgICAgICAgewpkaWZmIC0tZ2l0IGEvRVBQbHVzL0VQUGx1c1NESy5jc3Byb2ogYi9FUFBsdXMvRVBQbHVzU0RLLmNzcHJvagppbmRleCA5MjAzYWM5Li5jODFmZTlhIDEwMDY0NAotLS0gYS9FUFBsdXMvRVBQbHVzU0RLLmNzcHJvagorKysgYi9FUFBsdXMvRVBQbHVzU0RLLmNzcHJvagpAQCAtNCw3ICs0LDcgQEAKICAgICA8Um9vdE5hbWVzcGFjZT5PZmZpY2VPcGVuWG1sPC9Sb290TmFtZXNwYWNlPgogICAgIDxBc3NlbWJseU5hbWU+RVBQbHVzPC9Bc3NlbWJseU5hbWU+CiAgICAgPFBhY2thZ2VJZD5BcHBzaGVldC5FUFBsdXM8L1BhY2thZ2VJZD4KLSAgICA8VmVyc2lvbj4xLjAuNDwvVmVyc2lvbj4KKyAgICA8VmVyc2lvbj4xLjAuNTwvVmVyc2lvbj4KICAgICA8RGVmYXVsdEl0ZW1FeGNsdWRlcz4kKERlZmF1bHRJdGVtRXhjbHVkZXMpO1Byb3BlcnRpZXMvQXNzZW1ibHlJbmZvLmNzO0Zvcm11bGFQYXJzaW5nL0xleGljYWxBbmFseXNpcy9Ub2tlblNlcGFyYXRvckhhbmRsZXJzLyoqO0Zvcm11bGFQYXJzaW5nL0xleGljYWxBbmFseXNpcy9Ub2tlbkhhbmRsZXIuY3M7Rm9ybXVsYVBhcnNpbmcvRXhjZWwvRnVuY3Rpb25zL01hdGgvUmFuay5jczwvRGVmYXVsdEl0ZW1FeGNsdWRlcz4KICAgICA8RGVmaW5lQ29uc3RhbnRzPkNvcmU7U1RBTkRBUkQyMDwvRGVmaW5lQ29uc3RhbnRzPgogICAgIDxJbXBsaWNpdFVzaW5ncz5kaXNhYmxlPC9JbXBsaWNpdFVzaW5ncz4KZGlmZiAtLWdpdCBhL0VQUGx1cy9FbmNyeXB0aW9uL0VuY3J5cHRpb25IYW5kbGVyLmNzIGIvRVBQbHVzL0VuY3J5cHRpb24vRW5jcnlwdGlvbkhhbmRsZXIuY3MKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDExODUzZGEuLjAwMDAwMDAKLS0tIGEvRVBQbHVzL0VuY3J5cHRpb24vRW5jcnlwdGlvbkhhbmRsZXIuY3MKKysrIC9kZXYvbnVsbApAQCAtMSw5OTcgKzAsMCBAQAot77u/LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKLSAqIFlvdSBtYXkgYW1lbmQgYW5kIGRpc3RyaWJ1dGUgYXMgeW91IGxpa2UsIGJ1dCBkb24ndCByZW1vdmUgdGhpcyBoZWFkZXIhCi0gKgotICogRVBQbHVzIHByb3ZpZGVzIHNlcnZlci1zaWRlIGdlbmVyYXRpb24gb2YgRXhjZWwgMjAwNy8yMDEwIHNwcmVhZHNoZWV0cy4KLSAqIFNlZSBodHRwOi8vd3d3LmNvZGVwbGV4LmNvbS9FUFBsdXMgZm9yIGRldGFpbHMuCi0gKgotICogQ29weXJpZ2h0IChDKSAyMDExICBKYW4gS8OkbGxtYW4KLSAqCi0gKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCi0gKiBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCi0gKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKLSAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgotCi0gKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKLSAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCi0gKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICAKLSAqIFNlZSB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCi0gKgotICogVGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBjYW4gYmUgdmlld2VkIGF0IGh0dHA6Ly93d3cub3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvbGdwbC1saWNlbnNlLnBocAotICogSWYgeW91IHVuZmFtaWxpYXIgd2l0aCB0aGlzIGxpY2Vuc2Ugb3IgaGF2ZSBxdWVzdGlvbnMgYWJvdXQgaXQsIGhlcmUgaXMgYW4gaHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2dwbC1mYXEuaHRtbAotICoKLSAqIEFsbCBjb2RlIGFuZCBleGVjdXRhYmxlcyBhcmUgcHJvdmlkZWQgImFzIGlzIiB3aXRoIG5vIHdhcnJhbnR5IGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuIAotICogVGhlIGF1dGhvciBhY2NlcHRzIG5vIGxpYWJpbGl0eSBmb3IgYW55IGRhbWFnZSBvciBsb3NzIG9mIGJ1c2luZXNzIHRoYXQgdGhpcyBwcm9kdWN0IG1heSBjYXVzZS4KLSAqCi0gKiBDb2RlIGNoYW5nZSBub3RlczoKLSAqIAotICogQXV0aG9yCQkJCQkJCUNoYW5nZQkJCQkJCURhdGUKLSAqICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgotICogSmFuIEvDpGxsbWFuCQkgICAgQWRkZWQgICAgICAgCQkgICAgICAgIDIwMTMtMDEtMDUKLSAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwotdXNpbmcgT2ZmaWNlT3BlblhtbC5VdGlsczsKLXVzaW5nIFN5c3RlbTsKLXVzaW5nIFN5c3RlbS5Db2xsZWN0aW9ucy5HZW5lcmljOwotdXNpbmcgU3lzdGVtLklPOwotdXNpbmcgU3lzdGVtLkxpbnE7Ci11c2luZyBTeXN0ZW0uUnVudGltZS5JbnRlcm9wU2VydmljZXM7Ci11c2luZyBTeXN0ZW0uU2VjdXJpdHk7Ci11c2luZyBTeXN0ZW0uU2VjdXJpdHkuQ3J5cHRvZ3JhcGh5OwotdXNpbmcgU3lzdGVtLlRleHQ7Ci11c2luZyBTeXN0ZW0uWG1sOwotdXNpbmcgY29tVHlwZXMgPSBTeXN0ZW0uUnVudGltZS5JbnRlcm9wU2VydmljZXMuQ29tVHlwZXM7Ci0KLW5hbWVzcGFjZSBPZmZpY2VPcGVuWG1sLkVuY3J5cHRpb24KLXsKLQotICAgIC8vLyA8c3VtbWFyeT4KLSAgICAvLy8gSGFuZGVscyBlbmNyeXB0ZWQgRXhjZWwgZG9jdW1lbnRzIAotICAgIC8vLyA8L3N1bW1hcnk+Ci0gICAgaW50ZXJuYWwgY2xhc3MgRW5jcnlwdGVkUGFja2FnZUhhbmRsZXIKLSAgICB7Ci0jaWYgIU1PTk8KLSAgICAgICAgLy8vIDxzdW1tYXJ5PgotICAgICAgICAvLy8gUmVhZCB0aGUgcGFja2FnZSBmcm9tIHRoZSBPTEUgZG9jdW1lbnQgYW5kIGRlY3J5cHQgaXQgdXNpbmcgdGhlIHN1cHBsaWVkIHBhc3N3b3JkCi0gICAgICAgIC8vLyA8L3N1bW1hcnk+Ci0gICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iZmkiPlRoZSBmaWxlPC9wYXJhbT4KLSAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJlbmNyeXB0aW9uIj48L3BhcmFtPgotICAgICAgICAvLy8gPHJldHVybnM+PC9yZXR1cm5zPgotICAgICAgICBpbnRlcm5hbCBNZW1vcnlTdHJlYW0gRGVjcnlwdFBhY2thZ2UoRmlsZUluZm8gZmksIEV4Y2VsRW5jcnlwdGlvbiBlbmNyeXB0aW9uKQotICAgICAgICB7Ci0gICAgICAgICAgICBDb21wb3VuZERvY3VtZW50IGRvYyA9IG5ldyBDb21wb3VuZERvY3VtZW50KGZpKTsKLSAgICAgICAgICAgIAotICAgICAgICAgICAgTWVtb3J5U3RyZWFtIHJldCA9IG51bGw7Ci0gICAgICAgICAgICBpZiAoQ29tcG91bmREb2N1bWVudC5Jc1N0b3JhZ2VGaWxlKGZpLkZ1bGxOYW1lKSA9PSAwKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIHJldCA9IEdldFN0cmVhbUZyb21QYWNrYWdlKGRvYywgZW5jcnlwdGlvbik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgKG5ldyBJbnZhbGlkRGF0YUV4Y2VwdGlvbihzdHJpbmcuRm9ybWF0KCJGaWxlIHswfSBpcyBub3QgYW4gZW5jcnlwdGVkIHBhY2thZ2UiLCBmaS5GdWxsTmFtZSkpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybiByZXQ7Ci0gICAgICAgIH0KLQotICAgICAgICAvL0hlbHBtZXRob2QgdG8gb3V0cHV0IHRoZSBzdHJlYW1zIGluIHRoZSBzdG9yYWdlCi0gICAgICAgIC8vcHJpdmF0ZSB2b2lkIFdyaXRlRG9jKENvbXBvdW5kRG9jdW1lbnQuU3RvcmFnZVBhcnQgc3RvcmFnZVBhcnQsIHN0cmluZyBwKQotICAgICAgICAvL3sKLSAgICAgICAgLy8gICAgZm9yZWFjaCAodmFyIHN0b3JlIGluIHN0b3JhZ2VQYXJ0LlN1YlN0b3JhZ2UpCi0gICAgICAgIC8vICAgIHsKLSAgICAgICAgLy8gICAgICAgIHN0cmluZyBzZGlyPXAgKyBzdG9yZS5LZXkuUmVwbGFjZSgoY2hhcik2LCd4JykgKyAiXFwiOwotICAgICAgICAvLyAgICAgICAgRGlyZWN0b3J5LkNyZWF0ZURpcmVjdG9yeShzZGlyKTsKLSAgICAgICAgLy8gICAgICAgIFdyaXRlRG9jKHN0b3JlLlZhbHVlLCBzZGlyKTsKLSAgICAgICAgLy8gICAgfQotICAgICAgICAvLyAgICBmb3JlYWNoICh2YXIgc3RyIGluIHN0b3JhZ2VQYXJ0LkRhdGFTdHJlYW1zKQotICAgICAgICAvLyAgICB7Ci0gICAgICAgIC8vICAgICAgICBGaWxlLldyaXRlQWxsQnl0ZXMocCArIHN0ci5LZXkuUmVwbGFjZSgoY2hhcik2LCAneCcpICsgIi5iaW4iLCBzdHIuVmFsdWUpOwotICAgICAgICAvLyAgICB9Ci0gICAgICAgIC8vfQotICAgICAgICAvLy8gPHN1bW1hcnk+Ci0gICAgICAgIC8vLyBSZWFkIHRoZSBwYWNrYWdlIGZyb20gdGhlIE9MRSBkb2N1bWVudCBhbmQgZGVjcnlwdCBpdCB1c2luZyB0aGUgc3VwcGxpZWQgcGFzc3dvcmQKLSAgICAgICAgLy8vIDwvc3VtbWFyeT4KLSAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJzdHJlYW0iPlRoZSBtZW1vcnkgc3RyZWFtLiA8L3BhcmFtPgotICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImVuY3J5cHRpb24iPlRoZSBlbmNyeXB0aW9uIG9iamVjdCBmcm9tIHRoZSBQYWNrYWdlPC9wYXJhbT4KLSAgICAgICAgLy8vIDxyZXR1cm5zPjwvcmV0dXJucz4KLSAgICAgICAgW1NlY3VyaXR5U2FmZUNyaXRpY2FsXQotICAgICAgICBpbnRlcm5hbCBNZW1vcnlTdHJlYW0gRGVjcnlwdFBhY2thZ2UoTWVtb3J5U3RyZWFtIHN0cmVhbSwgRXhjZWxFbmNyeXB0aW9uIGVuY3J5cHRpb24pCi0gICAgICAgIHsKLSAgICAgICAgICAgIC8vQ3JlYXRlIHRoZSBsb2NrQnl0ZXMgb2JqZWN0LgotICAgICAgICAgICAgQ29tcG91bmREb2N1bWVudC5JTG9ja0J5dGVzIGxiPW51bGw7Ci0gICAgICAgICAgICB0cnkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBsYiA9IENvbXBvdW5kRG9jdW1lbnQuR2V0TG9ja2J5dGUoc3RyZWFtKTsKLQotICAgICAgICAgICAgICAgIGlmIChDb21wb3VuZERvY3VtZW50LklzU3RvcmFnZUlMb2NrQnl0ZXMobGIpID09IDApCi0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICB2YXIgZG9jID0gbmV3IENvbXBvdW5kRG9jdW1lbnQobGIpOwotICAgICAgICAgICAgICAgICAgICByZXR1cm4gR2V0U3RyZWFtRnJvbVBhY2thZ2UoZG9jLCBlbmNyeXB0aW9uKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgTWFyc2hhbC5SZWxlYXNlQ29tT2JqZWN0KGxiKTsKLSAgICAgICAgICAgICAgICAgICAgdGhyb3cgKG5ldyBJbnZhbGlkRGF0YUV4Y2VwdGlvbigiVGhlIHN0cmVhbSBpcyBub3QgYW4gdmFsaWQvc3VwcG9ydGVkIGVuY3J5cHRlZCBkb2N1bWVudC4iKSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgY2F0Y2gvLyAoRXhjZXB0aW9uIGV4KQotICAgICAgICAgICAgeyAgICAgICAgICAgICAgICAKLSAgICAgICAgICAgICAgICB0aHJvdzsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGZpbmFsbHkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBNYXJzaGFsLlJlbGVhc2VDb21PYmplY3QobGIpOwotICAgICAgICAgICAgICAgIGxiID0gbnVsbDsKLSAgICAgICAgICAgIH0KLQotICAgICAgICB9Ci0gICAgICAgIC8vLyA8c3VtbWFyeT4KLSAgICAgICAgLy8vIEVuY3J5cHRzIGEgcGFja2FnZQotICAgICAgICAvLy8gPC9zdW1tYXJ5PgotICAgICAgICAvLy8gPHBhcmFtIG5hbWU9InBhY2thZ2UiPlRoZSBwYWNrYWdlIGFzIGEgYnl0ZSBhcnJheTwvcGFyYW0+Ci0gICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iZW5jcnlwdGlvbiI+VGhlIGVuY3J5cHRpb24gaW5mbyBmcm9tIHRoZSB3b3JrYm9vazwvcGFyYW0+Ci0gICAgICAgIC8vLyA8cmV0dXJucz48L3JldHVybnM+Ci0gICAgICAgIGludGVybmFsIE1lbW9yeVN0cmVhbSBFbmNyeXB0UGFja2FnZShieXRlW10gcGFja2FnZSwgRXhjZWxFbmNyeXB0aW9uIGVuY3J5cHRpb24pCi0gICAgICAgIHsKLSAgICAgICAgICAgIGlmIChlbmNyeXB0aW9uLlZlcnNpb24gPT0gRW5jcnlwdGlvblZlcnNpb24uU3RhbmRhcmQpIC8vU3RhbmRhcmQgZW5jcnlwdGlvbgotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIHJldHVybiBFbmNyeXB0UGFja2FnZUJpbmFyeShwYWNrYWdlLCBlbmNyeXB0aW9uKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgaWYgKGVuY3J5cHRpb24uVmVyc2lvbiA9PSBFbmNyeXB0aW9uVmVyc2lvbi5BZ2lsZSkgLy9BZ2lsZSBlbmNyeXB0aW9uCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIEVuY3J5cHRQYWNrYWdlQWdpbGUocGFja2FnZSwgZW5jcnlwdGlvbik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICB0aHJvdyhuZXcgQXJndW1lbnRFeGNlcHRpb24oIlVuc3VwcG9ydGVkIGVuY3J5cHRpb24gdmVyc2lvbi4iKSk7Ci0gICAgICAgIH0KLQotICAgICAgICBwcml2YXRlIE1lbW9yeVN0cmVhbSBFbmNyeXB0UGFja2FnZUFnaWxlKGJ5dGVbXSBwYWNrYWdlLCBFeGNlbEVuY3J5cHRpb24gZW5jcnlwdGlvbikKLSAgICAgICAgewotICAgICAgICAgICAgdmFyIHhtbD0gIjw/eG1sIHZlcnNpb249XCIxLjBcIiBlbmNvZGluZz1cIlVURi04XCIgc3RhbmRhbG9uZT1cInllc1wiPz5cclxuIjsKLSAgICAgICAgICAgIHhtbCArPSAiPGVuY3J5cHRpb24geG1sbnM9XCJodHRwOi8vc2NoZW1hcy5taWNyb3NvZnQuY29tL29mZmljZS8yMDA2L2VuY3J5cHRpb25cIiB4bWxuczpwPVwiaHR0cDovL3NjaGVtYXMubWljcm9zb2Z0LmNvbS9vZmZpY2UvMjAwNi9rZXlFbmNyeXB0b3IvcGFzc3dvcmRcIiB4bWxuczpjPVwiaHR0cDovL3NjaGVtYXMubWljcm9zb2Z0LmNvbS9vZmZpY2UvMjAwNi9rZXlFbmNyeXB0b3IvY2VydGlmaWNhdGVcIj4iOwotICAgICAgICAgICAgeG1sICs9ICI8a2V5RGF0YSBzYWx0U2l6ZT1cIjE2XCIgYmxvY2tTaXplPVwiMTZcIiBrZXlCaXRzPVwiMjU2XCIgaGFzaFNpemU9XCI2NFwiIGNpcGhlckFsZ29yaXRobT1cIkFFU1wiIGNpcGhlckNoYWluaW5nPVwiQ2hhaW5pbmdNb2RlQ0JDXCIgaGFzaEFsZ29yaXRobT1cIlNIQTUxMlwiIHNhbHRWYWx1ZT1cIlwiLz4iOwotICAgICAgICAgICAgeG1sICs9ICI8ZGF0YUludGVncml0eSBlbmNyeXB0ZWRIbWFjS2V5PVwiXCIgZW5jcnlwdGVkSG1hY1ZhbHVlPVwiXCIvPiI7Ci0gICAgICAgICAgICB4bWwgKz0gIjxrZXlFbmNyeXB0b3JzPiI7Ci0gICAgICAgICAgICB4bWwgKz0gIjxrZXlFbmNyeXB0b3IgdXJpPVwiaHR0cDovL3NjaGVtYXMubWljcm9zb2Z0LmNvbS9vZmZpY2UvMjAwNi9rZXlFbmNyeXB0b3IvcGFzc3dvcmRcIj4iOwotICAgICAgICAgICAgeG1sICs9ICI8cDplbmNyeXB0ZWRLZXkgc3BpbkNvdW50PVwiMTAwMDAwXCIgc2FsdFNpemU9XCIxNlwiIGJsb2NrU2l6ZT1cIjE2XCIga2V5Qml0cz1cIjI1NlwiIGhhc2hTaXplPVwiNjRcIiBjaXBoZXJBbGdvcml0aG09XCJBRVNcIiBjaXBoZXJDaGFpbmluZz1cIkNoYWluaW5nTW9kZUNCQ1wiIGhhc2hBbGdvcml0aG09XCJTSEE1MTJcIiBzYWx0VmFsdWU9XCJcIiBlbmNyeXB0ZWRWZXJpZmllckhhc2hJbnB1dD1cIlwiIGVuY3J5cHRlZFZlcmlmaWVySGFzaFZhbHVlPVwiXCIgZW5jcnlwdGVkS2V5VmFsdWU9XCJcIiAvPiI7Ci0gICAgICAgICAgICB4bWwgKz0gIjwva2V5RW5jcnlwdG9yPjwva2V5RW5jcnlwdG9ycz48L2VuY3J5cHRpb24+IjsKLSAgICAgICAgICAgIAotICAgICAgICAgICAgdmFyIGVuY3J5cHRpb25JbmZvID0gbmV3IEVuY3J5cHRpb25JbmZvQWdpbGUoKTsKLSAgICAgICAgICAgIGVuY3J5cHRpb25JbmZvLlJlYWRGcm9tWG1sKHhtbCk7Ci0gICAgICAgICAgICB2YXIgZW5jciA9IGVuY3J5cHRpb25JbmZvLktleUVuY3J5cHRvcnNbMF07Ci0gICAgICAgICAgICB2YXIgcm5kID0gUmFuZG9tTnVtYmVyR2VuZXJhdG9yLkNyZWF0ZSgpOwotICAgICAgICAgICAgCi0gICAgICAgICAgICB2YXIgcyA9IG5ldyBieXRlWzE2XTsKLSAgICAgICAgICAgIHJuZC5HZXRCeXRlcyhzKTsKLSAgICAgICAgICAgIGVuY3J5cHRpb25JbmZvLktleURhdGEuU2FsdFZhbHVlID0gczsKLQotICAgICAgICAgICAgcm5kLkdldEJ5dGVzKHMpOwotICAgICAgICAgICAgZW5jci5TYWx0VmFsdWUgPSBzOwotCi0gICAgICAgICAgICBlbmNyLktleVZhbHVlID0gbmV3IGJ5dGVbZW5jci5LZXlCaXRzIC8gOF07Ci0gICAgICAgICAgICBybmQuR2V0Qnl0ZXMoZW5jci5LZXlWYWx1ZSk7Ci0KLSAgICAgICAgICAgIC8vR2V0IHRoZSBwYXNzd29yayBrZXkuCi0gICAgICAgICAgICB2YXIgaGFzaFByb3ZpZGVyID0gR2V0SGFzaFByb3ZpZGVyKGVuY3J5cHRpb25JbmZvLktleUVuY3J5cHRvcnNbMF0pOwotICAgICAgICAgICAgdmFyIGJhc2VIYXNoID0gR2V0UGFzc3dvcmRIYXNoKGhhc2hQcm92aWRlciwgZW5jci5TYWx0VmFsdWUsIGVuY3J5cHRpb24uUGFzc3dvcmQsIGVuY3IuU3BpbkNvdW50LCBlbmNyLkhhc2hTaXplKTsKLSAgICAgICAgICAgIHZhciBoYXNoRmluYWwgPSBHZXRGaW5hbEhhc2goaGFzaFByb3ZpZGVyLCBlbmNyLCBCbG9ja0tleV9LZXlWYWx1ZSwgYmFzZUhhc2gpOwotICAgICAgICAgICAgaGFzaEZpbmFsID0gRml4SGFzaFNpemUoaGFzaEZpbmFsLCBlbmNyLktleUJpdHMgLyA4KTsKLQotICAgICAgICAgICAgdmFyIGVuY3JEYXRhID0gRW5jcnlwdERhdGFBZ2lsZShwYWNrYWdlLCBlbmNyeXB0aW9uSW5mbywgaGFzaFByb3ZpZGVyKTsKLQotICAgICAgICAgICAgLyoqKiogRGF0YSBJbnRlZ3JpdHkgKioqKi8KLSAgICAgICAgICAgIHZhciBzYWx0SE1BQz1uZXcgYnl0ZVs2NF07Ci0gICAgICAgICAgICBybmQuR2V0Qnl0ZXMoc2FsdEhNQUMpOwotCi0gICAgICAgICAgICBTZXRITUFDKGVuY3J5cHRpb25JbmZvLGhhc2hQcm92aWRlcixzYWx0SE1BQywgZW5jckRhdGEpOwotCi0gICAgICAgICAgICAvKioqKiBWZXJpZmllciAqKioqLwotICAgICAgICAgICAgZW5jci5WZXJpZmllckhhc2hJbnB1dCA9IG5ldyBieXRlWzE2XTsKLSAgICAgICAgICAgIHJuZC5HZXRCeXRlcyhlbmNyLlZlcmlmaWVySGFzaElucHV0KTsKLQotICAgICAgICAgICAgZW5jci5WZXJpZmllckhhc2ggPSBoYXNoUHJvdmlkZXIuQ29tcHV0ZUhhc2goZW5jci5WZXJpZmllckhhc2hJbnB1dCk7Ci0KLSAgICAgICAgICAgIHZhciBWZXJpZmllcklucHV0S2V5ID0gR2V0RmluYWxIYXNoKGhhc2hQcm92aWRlciwgZW5jciwgQmxvY2tLZXlfSGFzaElucHV0LCBiYXNlSGFzaCk7Ci0gICAgICAgICAgICB2YXIgVmVyaWZpZXJIYXNoS2V5ID0gR2V0RmluYWxIYXNoKGhhc2hQcm92aWRlciwgZW5jciwgQmxvY2tLZXlfSGFzaFZhbHVlLCBiYXNlSGFzaCk7Ci0gICAgICAgICAgICB2YXIgS2V5VmFsdWVLZXkgPSBHZXRGaW5hbEhhc2goaGFzaFByb3ZpZGVyLCBlbmNyLCBCbG9ja0tleV9LZXlWYWx1ZSwgYmFzZUhhc2gpOwotCi0gICAgICAgICAgICB2YXIgbXMgPSBuZXcgTWVtb3J5U3RyZWFtKCk7Ci0gICAgICAgICAgICBFbmNyeXB0QWdpbGVGcm9tS2V5KGVuY3IsIFZlcmlmaWVySW5wdXRLZXksIGVuY3IuVmVyaWZpZXJIYXNoSW5wdXQsIDAsIGVuY3IuVmVyaWZpZXJIYXNoSW5wdXQuTGVuZ3RoLCBlbmNyLlNhbHRWYWx1ZSwgbXMpOwotICAgICAgICAgICAgZW5jci5FbmNyeXB0ZWRWZXJpZmllckhhc2hJbnB1dCA9IG1zLlRvQXJyYXkoKTsKLQotICAgICAgICAgICAgbXMgPSBuZXcgTWVtb3J5U3RyZWFtKCk7IAotICAgICAgICAgICAgRW5jcnlwdEFnaWxlRnJvbUtleShlbmNyLCBWZXJpZmllckhhc2hLZXksIGVuY3IuVmVyaWZpZXJIYXNoLCAwLCBlbmNyLlZlcmlmaWVySGFzaC5MZW5ndGgsIGVuY3IuU2FsdFZhbHVlLCBtcyk7Ci0gICAgICAgICAgICBlbmNyLkVuY3J5cHRlZFZlcmlmaWVySGFzaCA9IG1zLlRvQXJyYXkoKTsKLQotICAgICAgICAgICAgbXMgPSBuZXcgTWVtb3J5U3RyZWFtKCk7Ci0gICAgICAgICAgICBFbmNyeXB0QWdpbGVGcm9tS2V5KGVuY3IsIEtleVZhbHVlS2V5LCBlbmNyLktleVZhbHVlLCAwLCBlbmNyLktleVZhbHVlLkxlbmd0aCwgZW5jci5TYWx0VmFsdWUsIG1zKTsKLSAgICAgICAgICAgIGVuY3IuRW5jcnlwdGVkS2V5VmFsdWUgPSBtcy5Ub0FycmF5KCk7Ci0KLSAgICAgICAgICAgIHhtbCA9IGVuY3J5cHRpb25JbmZvLlhtbC5PdXRlclhtbDsKLQotICAgICAgICAgICAgdmFyIGJ5WG1sID0gRW5jb2RpbmcuVVRGOC5HZXRCeXRlcyh4bWwpOwotICAgICAgICAgICAgCi0gICAgICAgICAgICBtcyA9IG5ldyBNZW1vcnlTdHJlYW0oKTsKLSAgICAgICAgICAgIG1zLldyaXRlKEJpdENvbnZlcnRlci5HZXRCeXRlcygodXNob3J0KTQpLCAwLCAyKTsgLy9NYWpvciBWZXJzaW9uCi0gICAgICAgICAgICBtcy5Xcml0ZShCaXRDb252ZXJ0ZXIuR2V0Qnl0ZXMoKHVzaG9ydCk0KSwgMCwgMik7IC8vTWlub3IgVmVyc2lvbgotICAgICAgICAgICAgbXMuV3JpdGUoQml0Q29udmVydGVyLkdldEJ5dGVzKCh1aW50KTB4NDApLCAwLCA0KTsgLy9SZXNlcnZlZAotICAgICAgICAgICAgbXMuV3JpdGUoYnlYbWwsMCxieVhtbC5MZW5ndGgpOwotCi0gICAgICAgICAgICB2YXIgZG9jID0gbmV3IENvbXBvdW5kRG9jdW1lbnQoKTsKLSAgICAgICAgICAgIAotICAgICAgICAgICAgLy9BZGQgdGhlIGRhdGFzcGFjZSBzdHJlYW1zCi0gICAgICAgICAgICBDcmVhdGVEYXRhU3BhY2VzKGRvYyk7Ci0gICAgICAgICAgICAvL0VuY3J5cHRpb25JbmZvLi4uCi0gICAgICAgICAgICBkb2MuU3RvcmFnZS5EYXRhU3RyZWFtcy5BZGQoIkVuY3J5cHRpb25JbmZvIiwgbXMuVG9BcnJheSgpKTsKLSAgICAgICAgICAgIC8vLi4uYW5kIHRoZSBlbmNyeXB0ZWQgcGFja2FnZQotICAgICAgICAgICAgZG9jLlN0b3JhZ2UuRGF0YVN0cmVhbXMuQWRkKCJFbmNyeXB0ZWRQYWNrYWdlIiwgZW5jckRhdGEpOwotCi0gICAgICAgICAgICBtcyA9IG5ldyBNZW1vcnlTdHJlYW0oKTsKLSAgICAgICAgICAgIHZhciBlPWRvYy5TYXZlKCk7Ci0gICAgICAgICAgICBtcy5Xcml0ZShlLDAsZS5MZW5ndGgpOwotICAgICAgICAgICAgcmV0dXJuIG1zOwotICAgICAgICB9Ci0KLSAgICAgICAgcHJpdmF0ZSBieXRlW10gRW5jcnlwdERhdGFBZ2lsZShieXRlW10gZGF0YSwgRW5jcnlwdGlvbkluZm9BZ2lsZSBlbmNyeXB0aW9uSW5mbywgSGFzaEFsZ29yaXRobSBoYXNoUHJvdmlkZXIpCi0gICAgICAgIHsKLSAgICAgICAgICAgIHZhciBrZSA9IGVuY3J5cHRpb25JbmZvLktleUVuY3J5cHRvcnNbMF07Ci0gICAgICAgICAgICBSaWpuZGFlbE1hbmFnZWQgYWVzID0gbmV3IFJpam5kYWVsTWFuYWdlZCgpOwotICAgICAgICAgICAgYWVzLktleVNpemUgPSBrZS5LZXlCaXRzOwotICAgICAgICAgICAgYWVzLk1vZGUgPSBDaXBoZXJNb2RlLkNCQzsKLSAgICAgICAgICAgIGFlcy5QYWRkaW5nID0gUGFkZGluZ01vZGUuWmVyb3M7Ci0KLSAgICAgICAgICAgIGludCBwb3M9MDsKLSAgICAgICAgICAgIGludCBzZWdtZW50PTA7Ci0KLSAgICAgICAgICAgIC8vRW5jcnlwdCB0aGUgZGF0YQotICAgICAgICAgICAgdmFyIG1zID0gbmV3IE1lbW9yeVN0cmVhbSgpOwotICAgICAgICAgICAgbXMuV3JpdGUoQml0Q29udmVydGVyLkdldEJ5dGVzKGRhdGEuTG9uZ0xlbmd0aCksIDAsIDgpOwotICAgICAgICAgICAgd2hpbGUgKHBvcyA8IGRhdGEuTGVuZ3RoKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIHZhciBzZWdtZW50U2l6ZSA9IChpbnQpKGRhdGEuTGVuZ3RoIC0gcG9zID4gNDA5NiA/IDQwOTYgOiBkYXRhLkxlbmd0aCAtIHBvcyk7Ci0gICAgICAgICAgICAgICAgCi0gICAgICAgICAgICAgICAgdmFyIGl2VG1wID0gbmV3IGJ5dGVbNCArIGVuY3J5cHRpb25JbmZvLktleURhdGEuU2FsdFNpemVdOwotICAgICAgICAgICAgICAgIEFycmF5LkNvcHkoZW5jcnlwdGlvbkluZm8uS2V5RGF0YS5TYWx0VmFsdWUsIDAsIGl2VG1wLCAwLCBlbmNyeXB0aW9uSW5mby5LZXlEYXRhLlNhbHRTaXplKTsKLSAgICAgICAgICAgICAgICBBcnJheS5Db3B5KEJpdENvbnZlcnRlci5HZXRCeXRlcyhzZWdtZW50KSwgMCwgaXZUbXAsIGVuY3J5cHRpb25JbmZvLktleURhdGEuU2FsdFNpemUsIDQpOwotICAgICAgICAgICAgICAgIHZhciBpdj1oYXNoUHJvdmlkZXIuQ29tcHV0ZUhhc2goaXZUbXApOwotCi0gICAgICAgICAgICAgICAgRW5jcnlwdEFnaWxlRnJvbUtleShrZSwga2UuS2V5VmFsdWUsIGRhdGEsIHBvcywgc2VnbWVudFNpemUsIGl2LCBtcyk7Ci0gICAgICAgICAgICAgICAgcG9zICs9IHNlZ21lbnRTaXplOwotICAgICAgICAgICAgICAgIHNlZ21lbnQrKzsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIG1zLkZsdXNoKCk7Ci0gICAgICAgICAgICByZXR1cm4gbXMuVG9BcnJheSgpOwotICAgICAgICB9Ci0gICAgICAgIC8vIFNldCB0aGUgZGF0YWludGVncml0eQotICAgICAgICBwcml2YXRlIHZvaWQgU2V0SE1BQyhFbmNyeXB0aW9uSW5mb0FnaWxlIGVpLCBIYXNoQWxnb3JpdGhtIGhhc2hQcm92aWRlciwgYnl0ZVtdIHNhbHQsIGJ5dGVbXSBkYXRhKQotICAgICAgICB7Ci0gICAgICAgICAgICB2YXIgaXYgPSBHZXRGaW5hbEhhc2goaGFzaFByb3ZpZGVyLCBlaS5LZXlFbmNyeXB0b3JzWzBdLCBCbG9ja0tleV9IbWFjS2V5LCBlaS5LZXlEYXRhLlNhbHRWYWx1ZSk7Ci0gICAgICAgICAgICB2YXIgbXMgPSBuZXcgTWVtb3J5U3RyZWFtKCk7Ci0gICAgICAgICAgICBFbmNyeXB0QWdpbGVGcm9tS2V5KGVpLktleUVuY3J5cHRvcnNbMF0sIGVpLktleUVuY3J5cHRvcnNbMF0uS2V5VmFsdWUsIHNhbHQsIDBMLCBzYWx0LkxvbmdMZW5ndGgsIGl2LCBtcyk7Ci0gICAgICAgICAgICBlaS5EYXRhSW50ZWdyaXR5LkVuY3J5cHRlZEhtYWNLZXkgPSBtcy5Ub0FycmF5KCk7Ci0gICAgICAgICAgICAKLSAgICAgICAgICAgIHZhciBoID0gR2V0SG1hY1Byb3ZpZGVyKGVpLktleUVuY3J5cHRvcnNbMF0sIHNhbHQpOwotICAgICAgICAgICAgdmFyIGhtYWNWYWx1ZSA9IGguQ29tcHV0ZUhhc2goZGF0YSk7Ci0KLSAgICAgICAgICAgIG1zID0gbmV3IE1lbW9yeVN0cmVhbSgpOwotICAgICAgICAgICAgaXYgPSBHZXRGaW5hbEhhc2goaGFzaFByb3ZpZGVyLCBlaS5LZXlFbmNyeXB0b3JzWzBdLCBCbG9ja0tleV9IbWFjVmFsdWUsIGVpLktleURhdGEuU2FsdFZhbHVlKTsKLSAgICAgICAgICAgIEVuY3J5cHRBZ2lsZUZyb21LZXkoZWkuS2V5RW5jcnlwdG9yc1swXSwgZWkuS2V5RW5jcnlwdG9yc1swXS5LZXlWYWx1ZSwgaG1hY1ZhbHVlLCAwTCwgaG1hY1ZhbHVlLkxvbmdMZW5ndGgsIGl2LCBtcyk7Ci0gICAgICAgICAgICBlaS5EYXRhSW50ZWdyaXR5LkVuY3J5cHRlZEhtYWNWYWx1ZSA9IG1zLlRvQXJyYXkoKTsKLSAgICAgICAgfQotCi0gICAgICAgIHByaXZhdGUgSE1BQyBHZXRIbWFjUHJvdmlkZXIoRW5jcnlwdGlvbkluZm9BZ2lsZS5FbmNyeXB0aW9uS2V5RW5jcnlwdG9yIGVpLCBieXRlW10gc2FsdCkKLSAgICAgICAgewotICAgICAgICAgICAgc3dpdGNoIChlaS5IYXNoQWxnb3JpdGhtKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIGNhc2UgZUhhc2hBbG9nb3JpdGhtLk1ENToKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBITUFDTUQ1KHNhbHQpOyAgICAgICAgICAgICAgCi0gICAgICAgICAgICAgICAgY2FzZSBlSGFzaEFsb2dvcml0aG0uU0hBMToKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBITUFDU0hBMShzYWx0KTsKLSAgICAgICAgICAgICAgICBjYXNlIGVIYXNoQWxvZ29yaXRobS5TSEEyNTY6Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgSE1BQ1NIQTI1NihzYWx0KTsKLSAgICAgICAgICAgICAgICBjYXNlIGVIYXNoQWxvZ29yaXRobS5TSEEzODQ6Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgSE1BQ1NIQTM4NChzYWx0KTsKLSAgICAgICAgICAgICAgICBjYXNlIGVIYXNoQWxvZ29yaXRobS5TSEE1MTI6Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgSE1BQ1NIQTUxMihzYWx0KTsKLSAgICAgICAgICAgICAgICBkZWZhdWx0OgotICAgICAgICAgICAgICAgICAgICB0aHJvdyhuZXcgTm90U3VwcG9ydGVkRXhjZXB0aW9uKHN0cmluZy5Gb3JtYXQoIkhhc2ggbWV0aG9kIHswfSBub3Qgc3VwcG9ydGVkLiIsZWkuSGFzaEFsZ29yaXRobSkpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIHByaXZhdGUgTWVtb3J5U3RyZWFtIEVuY3J5cHRQYWNrYWdlQmluYXJ5KGJ5dGVbXSBwYWNrYWdlLCBFeGNlbEVuY3J5cHRpb24gZW5jcnlwdGlvbikKLSAgICAgICAgewotICAgICAgICAgICAgYnl0ZVtdIGVuY3J5cHRpb25LZXk7Ci0gICAgICAgICAgICAvL0NyZWF0ZSB0aGUgRW5jcnlwdGlvbiBJbmZvLiBUaGlzIGFsc28gcmV0dXJucyB0aGUgRW5jcnlwdGlvbmtleQotICAgICAgICAgICAgdmFyIGVuY3J5cHRpb25JbmZvID0gQ3JlYXRlRW5jcnlwdGlvbkluZm8oZW5jcnlwdGlvbi5QYXNzd29yZCwKLSAgICAgICAgICAgICAgICAgICAgZW5jcnlwdGlvbi5BbGdvcml0aG0gPT0gRW5jcnlwdGlvbkFsZ29yaXRobS5BRVMxMjggPwotICAgICAgICAgICAgICAgICAgICAgICAgQWxnb3JpdGhtSUQuQUVTMTI4IDoKLSAgICAgICAgICAgICAgICAgICAgZW5jcnlwdGlvbi5BbGdvcml0aG0gPT0gRW5jcnlwdGlvbkFsZ29yaXRobS5BRVMxOTIgPwotICAgICAgICAgICAgICAgICAgICAgICAgQWxnb3JpdGhtSUQuQUVTMTkyIDoKLSAgICAgICAgICAgICAgICAgICAgICAgIEFsZ29yaXRobUlELkFFUzI1Niwgb3V0IGVuY3J5cHRpb25LZXkpOwotCi0gICAgICAgICAgICAvL0lMb2NrQnl0ZXMgbGI7Ci0gICAgICAgICAgICAvL3ZhciBpcmV0ID0gQ3JlYXRlSUxvY2tCeXRlc09uSEdsb2JhbChJbnRQdHIuWmVybywgdHJ1ZSwgb3V0IGxiKTsKLQotICAgICAgICAgICAgLy9JU3RvcmFnZSBzdG9yYWdlID0gbnVsbDsKLSAgICAgICAgICAgIC8vTWVtb3J5U3RyZWFtIHJldCA9IG51bGw7Ci0KLSAgICAgICAgICAgIHZhciBkb2MgPSBuZXcgQ29tcG91bmREb2N1bWVudCgpOwotICAgICAgICAgICAgQ3JlYXRlRGF0YVNwYWNlcyhkb2MpOwotCi0gICAgICAgICAgICBkb2MuU3RvcmFnZS5EYXRhU3RyZWFtcy5BZGQoIkVuY3J5cHRpb25JbmZvIiwgZW5jcnlwdGlvbkluZm8uV3JpdGVCaW5hcnkoKSk7Ci0gICAgICAgICAgICAKLSAgICAgICAgICAgIC8vRW5jcnlwdCB0aGUgcGFja2FnZQotICAgICAgICAgICAgYnl0ZVtdIGVuY3J5cHRlZFBhY2thZ2UgPSBFbmNyeXB0RGF0YShlbmNyeXB0aW9uS2V5LCBwYWNrYWdlLCBmYWxzZSk7Ci0gICAgICAgICAgICBNZW1vcnlTdHJlYW0gbXMgPSBuZXcgTWVtb3J5U3RyZWFtKCk7Ci0gICAgICAgICAgICBtcy5Xcml0ZShCaXRDb252ZXJ0ZXIuR2V0Qnl0ZXMoKHVsb25nKXBhY2thZ2UuTG9uZ0xlbmd0aCksIDAsIDgpOwotICAgICAgICAgICAgbXMuV3JpdGUoZW5jcnlwdGVkUGFja2FnZSwgMCwgZW5jcnlwdGVkUGFja2FnZS5MZW5ndGgpOwotICAgICAgICAgICAgZG9jLlN0b3JhZ2UuRGF0YVN0cmVhbXMuQWRkKCJFbmNyeXB0ZWRQYWNrYWdlIiwgbXMuVG9BcnJheSgpKTsKLQotICAgICAgICAgICAgdmFyIHJldCA9IG5ldyBNZW1vcnlTdHJlYW0oKTsgICAgICAgICAgICAgICAgCi0gICAgICAgICAgICB2YXIgYnVmZmVyID0gZG9jLlNhdmUoKTsKLSAgICAgICAgICAgIHJldC5Xcml0ZShidWZmZXIsIDAsIGJ1ZmZlci5MZW5ndGgpOwotCi0gICAgICAgICAgICByZXR1cm4gcmV0OwotICAgICAgICB9Ci0gICAgICAgICNyZWdpb24gIkRhdGFzcGFjZXMgU3RyZWFtIG1ldGhvZHMiCi0gICAgICAgIHByaXZhdGUgdm9pZCBDcmVhdGVEYXRhU3BhY2VzKENvbXBvdW5kRG9jdW1lbnQgZG9jKQotICAgICAgICB7Ci0gICAgICAgICAgICB2YXIgZHMgPSBuZXcgQ29tcG91bmREb2N1bWVudC5TdG9yYWdlUGFydCgpOwotICAgICAgICAgICAgZG9jLlN0b3JhZ2UuU3ViU3RvcmFnZS5BZGQoIlx4MDYiICsgIkRhdGFTcGFjZXMiLCBkcyk7Ci0gICAgICAgICAgICB2YXIgdmVyPW5ldyBDb21wb3VuZERvY3VtZW50LlN0b3JhZ2VQYXJ0KCk7Ci0gICAgICAgICAgICBkcy5EYXRhU3RyZWFtcy5BZGQoIlZlcnNpb24iLCBDcmVhdGVWZXJzaW9uU3RyZWFtKCkpOwotICAgICAgICAgICAgZHMuRGF0YVN0cmVhbXMuQWRkKCJEYXRhU3BhY2VNYXAiLCBDcmVhdGVEYXRhU3BhY2VNYXAoKSk7Ci0gICAgICAgICAgICAKLSAgICAgICAgICAgIHZhciBkc0luZm89bmV3IENvbXBvdW5kRG9jdW1lbnQuU3RvcmFnZVBhcnQoKTsKLSAgICAgICAgICAgIGRzLlN1YlN0b3JhZ2UuQWRkKCJEYXRhU3BhY2VJbmZvIiwgZHNJbmZvKTsKLSAgICAgICAgICAgIGRzSW5mby5EYXRhU3RyZWFtcy5BZGQoIlN0cm9uZ0VuY3J5cHRpb25EYXRhU3BhY2UiLCBDcmVhdGVTdHJvbmdFbmNyeXB0aW9uRGF0YVNwYWNlU3RyZWFtKCkpOwotICAgICAgICAgICAgCi0gICAgICAgICAgICB2YXIgdHJhbnNJbmZvPW5ldyBDb21wb3VuZERvY3VtZW50LlN0b3JhZ2VQYXJ0KCk7Ci0gICAgICAgICAgICBkcy5TdWJTdG9yYWdlLkFkZCgiVHJhbnNmb3JtSW5mbyIsIHRyYW5zSW5mbyk7Ci0KLSAgICAgICAgICAgIHZhciBzdHJFbmNUcmFucz1uZXcgQ29tcG91bmREb2N1bWVudC5TdG9yYWdlUGFydCgpOwotICAgICAgICAgICAgdHJhbnNJbmZvLlN1YlN0b3JhZ2UuQWRkKCJTdHJvbmdFbmNyeXB0aW9uVHJhbnNmb3JtIiwgc3RyRW5jVHJhbnMpOwotICAgICAgICAgICAgCi0gICAgICAgICAgICBzdHJFbmNUcmFucy5EYXRhU3RyZWFtcy5BZGQoIlx4MDZQcmltYXJ5IiwgQ3JlYXRlVHJhbnNmb3JtSW5mb1ByaW1hcnkoKSk7Ci0gICAgICAgIH0KLSAgICAgICAgcHJpdmF0ZSBieXRlW10gQ3JlYXRlU3Ryb25nRW5jcnlwdGlvbkRhdGFTcGFjZVN0cmVhbSgpCi0gICAgICAgIHsKLSAgICAgICAgICAgIE1lbW9yeVN0cmVhbSBtcyA9IG5ldyBNZW1vcnlTdHJlYW0oKTsKLSAgICAgICAgICAgIEJpbmFyeVdyaXRlciBidyA9IG5ldyBCaW5hcnlXcml0ZXIobXMpOwotCi0gICAgICAgICAgICBidy5Xcml0ZSgoaW50KTgpOyAgICAgICAvL0hlYWRlckxlbmd0aAotICAgICAgICAgICAgYncuV3JpdGUoKGludCkxKTsgICAgICAgLy9FbnRyeUNvdW50Ci0KLSAgICAgICAgICAgIHN0cmluZyB0ciA9ICJTdHJvbmdFbmNyeXB0aW9uVHJhbnNmb3JtIjsKLSAgICAgICAgICAgIGJ3LldyaXRlKChpbnQpdHIuTGVuZ3RoKjIpOwotICAgICAgICAgICAgYncuV3JpdGUoVVRGOEVuY29kaW5nLlVuaWNvZGUuR2V0Qnl0ZXModHIgKyAiXDAiKSk7IC8vIGVuZCBcMCBpcyBmb3IgcGFkZGluZwotCi0gICAgICAgICAgICBidy5GbHVzaCgpOwotICAgICAgICAgICAgcmV0dXJuIG1zLlRvQXJyYXkoKTsKLSAgICAgICAgfQotICAgICAgICBwcml2YXRlIGJ5dGVbXSBDcmVhdGVWZXJzaW9uU3RyZWFtKCkKLSAgICAgICAgewotICAgICAgICAgICAgTWVtb3J5U3RyZWFtIG1zID0gbmV3IE1lbW9yeVN0cmVhbSgpOwotICAgICAgICAgICAgQmluYXJ5V3JpdGVyIGJ3ID0gbmV3IEJpbmFyeVdyaXRlcihtcyk7Ci0KLSAgICAgICAgICAgIGJ3LldyaXRlKChzaG9ydCkweDNDKTsgIC8vTWFqb3IKLSAgICAgICAgICAgIGJ3LldyaXRlKChzaG9ydCkwKTsgICAgIC8vTWlub3IKLSAgICAgICAgICAgIGJ3LldyaXRlKFVURjhFbmNvZGluZy5Vbmljb2RlLkdldEJ5dGVzKCJNaWNyb3NvZnQuQ29udGFpbmVyLkRhdGFTcGFjZXMiKSk7Ci0gICAgICAgICAgICBidy5Xcml0ZSgoaW50KTEpOyAgICAgICAvL1JlYWRlclZlcnNpb24KLSAgICAgICAgICAgIGJ3LldyaXRlKChpbnQpMSk7ICAgICAgIC8vVXBkYXRlclZlcnNpb24KLSAgICAgICAgICAgIGJ3LldyaXRlKChpbnQpMSk7ICAgICAgIC8vV3JpdGVyVmVyc2lvbgotCi0gICAgICAgICAgICBidy5GbHVzaCgpOwotICAgICAgICAgICAgcmV0dXJuIG1zLlRvQXJyYXkoKTsKLSAgICAgICAgfQotICAgICAgICBwcml2YXRlIGJ5dGVbXSBDcmVhdGVEYXRhU3BhY2VNYXAoKQotICAgICAgICB7Ci0gICAgICAgICAgICBNZW1vcnlTdHJlYW0gbXMgPSBuZXcgTWVtb3J5U3RyZWFtKCk7Ci0gICAgICAgICAgICBCaW5hcnlXcml0ZXIgYncgPSBuZXcgQmluYXJ5V3JpdGVyKG1zKTsKLQotICAgICAgICAgICAgYncuV3JpdGUoKGludCk4KTsgICAgICAgLy9IZWFkZXJMZW5ndGgKLSAgICAgICAgICAgIGJ3LldyaXRlKChpbnQpMSk7ICAgICAgIC8vRW50cnlDb3VudAotICAgICAgICAgICAgc3RyaW5nIHMxID0gIkVuY3J5cHRlZFBhY2thZ2UiOwotICAgICAgICAgICAgc3RyaW5nIHMyID0gIlN0cm9uZ0VuY3J5cHRpb25EYXRhU3BhY2UiOwotICAgICAgICAgICAgYncuV3JpdGUoKGludCkoczEuTGVuZ3RoICsgczIuTGVuZ3RoKSoyICsgMHgxNik7Ci0gICAgICAgICAgICBidy5Xcml0ZSgoaW50KTEpOyAgICAgICAvL1JlZmVyZW5jZUNvbXBvbmVudENvdW50Ci0gICAgICAgICAgICBidy5Xcml0ZSgoaW50KTApOyAgICAgICAvL1N0cmVhbT0wCi0gICAgICAgICAgICBidy5Xcml0ZSgoaW50KXMxLkxlbmd0aCAqIDIpOyAvL0xlbmd0aCBzMQotICAgICAgICAgICAgYncuV3JpdGUoVVRGOEVuY29kaW5nLlVuaWNvZGUuR2V0Qnl0ZXMoczEpKTsKLSAgICAgICAgICAgIGJ3LldyaXRlKChpbnQpKHMyLkxlbmd0aCAqIDIpKTsgICAvL0xlbmd0aCBzMgotICAgICAgICAgICAgYncuV3JpdGUoVVRGOEVuY29kaW5nLlVuaWNvZGUuR2V0Qnl0ZXMoczIgKyAiXDAiKSk7ICAgLy8gZW5kIFwwIGlzIGZvciBwYWRkaW5nCi0KLSAgICAgICAgICAgIGJ3LkZsdXNoKCk7Ci0gICAgICAgICAgICByZXR1cm4gbXMuVG9BcnJheSgpOwotICAgICAgICB9Ci0gICAgICAgIHByaXZhdGUgYnl0ZVtdIENyZWF0ZVRyYW5zZm9ybUluZm9QcmltYXJ5KCkKLSAgICAgICAgewotICAgICAgICAgICAgTWVtb3J5U3RyZWFtIG1zID0gbmV3IE1lbW9yeVN0cmVhbSgpOwotICAgICAgICAgICAgQmluYXJ5V3JpdGVyIGJ3ID0gbmV3IEJpbmFyeVdyaXRlcihtcyk7Ci0gICAgICAgICAgICBzdHJpbmcgVHJhbnNmb3JtSUQgPSAie0ZGOUEzRjAzLTU2RUYtNDYxMy1CREQ1LTVBNDFDMUQwNzI0Nn0iOwotICAgICAgICAgICAgc3RyaW5nIFRyYW5zZm9ybU5hbWUgPSAiTWljcm9zb2Z0LkNvbnRhaW5lci5FbmNyeXB0aW9uVHJhbnNmb3JtIjsKLSAgICAgICAgICAgIGJ3LldyaXRlKFRyYW5zZm9ybUlELkxlbmd0aCAqIDIgKyAxMik7Ci0gICAgICAgICAgICBidy5Xcml0ZSgoaW50KTEpOwotICAgICAgICAgICAgYncuV3JpdGUoVHJhbnNmb3JtSUQuTGVuZ3RoICogMik7Ci0gICAgICAgICAgICBidy5Xcml0ZShVVEY4RW5jb2RpbmcuVW5pY29kZS5HZXRCeXRlcyhUcmFuc2Zvcm1JRCkpOwotICAgICAgICAgICAgYncuV3JpdGUoVHJhbnNmb3JtTmFtZS5MZW5ndGggKiAyKTsKLSAgICAgICAgICAgIGJ3LldyaXRlKFVURjhFbmNvZGluZy5Vbmljb2RlLkdldEJ5dGVzKFRyYW5zZm9ybU5hbWUgKyAiXDAiKSk7Ci0gICAgICAgICAgICBidy5Xcml0ZSgoaW50KTEpOyAgIC8vUmVhZGVyVmVyc2lvbgotICAgICAgICAgICAgYncuV3JpdGUoKGludCkxKTsgICAvL1VwZGF0ZXJWZXJzaW9uCi0gICAgICAgICAgICBidy5Xcml0ZSgoaW50KTEpOyAgIC8vV3JpdGVyVmVyc2lvbgotCi0gICAgICAgICAgICBidy5Xcml0ZSgoaW50KTApOwotICAgICAgICAgICAgYncuV3JpdGUoKGludCkwKTsKLSAgICAgICAgICAgIGJ3LldyaXRlKChpbnQpMCk7ICAgICAgIC8vQ2lwaGVyTW9kZQotICAgICAgICAgICAgYncuV3JpdGUoKGludCk0KTsgICAgICAgLy9SZXNlcnZlZAotCi0gICAgICAgICAgICBidy5GbHVzaCgpOwotICAgICAgICAgICAgcmV0dXJuIG1zLlRvQXJyYXkoKTsKLSAgICAgICAgfQotICAgICAgICAjZW5kcmVnaW9uCi0gICAgICAgIC8vLyA8c3VtbWFyeT4KLSAgICAgICAgLy8vIENyZWF0ZSBhbiBFbmNyeXB0aW9uSW5mbyBvYmplY3QgdG8gZW5jcnlwdCBhIHdvcmtib29rCi0gICAgICAgIC8vLyA8L3N1bW1hcnk+Ci0gICAgICAgIC8vLyA8cGFyYW0gbmFtZT0icGFzc3dvcmQiPlRoZSBwYXNzd29yZDwvcGFyYW0+Ci0gICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iYWxnSUQiPjwvcGFyYW0+Ci0gICAgICAgIC8vLyA8cGFyYW0gbmFtZT0ia2V5Ij5UaGUgRW5jcnlwdGlvbiBrZXk8L3BhcmFtPgotICAgICAgICAvLy8gPHJldHVybnM+PC9yZXR1cm5zPgotICAgICAgICBwcml2YXRlIEVuY3J5cHRpb25JbmZvQmluYXJ5IENyZWF0ZUVuY3J5cHRpb25JbmZvKHN0cmluZyBwYXNzd29yZCwgQWxnb3JpdGhtSUQgYWxnSUQsIG91dCBieXRlW10ga2V5KQotICAgICAgICB7Ci0gICAgICAgICAgICBpZiAoYWxnSUQgPT0gQWxnb3JpdGhtSUQuRmxhZ3MgfHwgYWxnSUQgPT0gQWxnb3JpdGhtSUQuUkM0KQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIHRocm93IChuZXcgQXJndW1lbnRFeGNlcHRpb24oImFsZ0lEIG11c3QgYmUgQUVTMTI4LCBBRVMxOTIgb3IgQUVTMjU2IikpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgdmFyIGVuY3J5cHRpb25JbmZvID0gbmV3IEVuY3J5cHRpb25JbmZvQmluYXJ5KCk7Ci0gICAgICAgICAgICBlbmNyeXB0aW9uSW5mby5NYWpvclZlcnNpb24gPSA0OwotICAgICAgICAgICAgZW5jcnlwdGlvbkluZm8uTWlub3JWZXJzaW9uID0gMjsKLSAgICAgICAgICAgIGVuY3J5cHRpb25JbmZvLkZsYWdzID0gRmxhZ3MuZkFFUyB8IEZsYWdzLmZDcnlwdG9BUEk7Ci0KLSAgICAgICAgICAgIC8vSGVhZGVyCi0gICAgICAgICAgICBlbmNyeXB0aW9uSW5mby5IZWFkZXIgPSBuZXcgRW5jcnlwdGlvbkhlYWRlcigpOwotICAgICAgICAgICAgZW5jcnlwdGlvbkluZm8uSGVhZGVyLkFsZ0lEID0gYWxnSUQ7Ci0gICAgICAgICAgICBlbmNyeXB0aW9uSW5mby5IZWFkZXIuQWxnSURIYXNoID0gQWxnb3JpdGhtSGFzaElELlNIQTE7Ci0gICAgICAgICAgICBlbmNyeXB0aW9uSW5mby5IZWFkZXIuRmxhZ3MgPSBlbmNyeXB0aW9uSW5mby5GbGFnczsKLSAgICAgICAgICAgIGVuY3J5cHRpb25JbmZvLkhlYWRlci5LZXlTaXplID0KLSAgICAgICAgICAgICAgICAoYWxnSUQgPT0gQWxnb3JpdGhtSUQuQUVTMTI4ID8gMHg4MCA6IGFsZ0lEID09IEFsZ29yaXRobUlELkFFUzE5MiA/IDB4QzAgOiAweDEwMCk7Ci0gICAgICAgICAgICBlbmNyeXB0aW9uSW5mby5IZWFkZXIuUHJvdmlkZXJUeXBlID0gUHJvdmlkZXJUeXBlLkFFUzsKLSAgICAgICAgICAgIGVuY3J5cHRpb25JbmZvLkhlYWRlci5DU1BOYW1lID0gIk1pY3Jvc29mdCBFbmhhbmNlZCBSU0EgYW5kIEFFUyBDcnlwdG9ncmFwaGljIFByb3ZpZGVyXDAiOwotICAgICAgICAgICAgZW5jcnlwdGlvbkluZm8uSGVhZGVyLlJlc2VydmVkMSA9IDA7Ci0gICAgICAgICAgICBlbmNyeXB0aW9uSW5mby5IZWFkZXIuUmVzZXJ2ZWQyID0gMDsKLSAgICAgICAgICAgIGVuY3J5cHRpb25JbmZvLkhlYWRlci5TaXplRXh0cmEgPSAwOwotCi0gICAgICAgICAgICAvL1ZlcmlmaWVyCi0gICAgICAgICAgICBlbmNyeXB0aW9uSW5mby5WZXJpZmllciA9IG5ldyBFbmNyeXB0aW9uVmVyaWZpZXIoKTsKLSAgICAgICAgICAgIGVuY3J5cHRpb25JbmZvLlZlcmlmaWVyLlNhbHQgPSBuZXcgYnl0ZVsxNl07Ci0KLSAgICAgICAgICAgIHZhciBybmQgPSBSYW5kb21OdW1iZXJHZW5lcmF0b3IuQ3JlYXRlKCk7Ci0gICAgICAgICAgICBybmQuR2V0Qnl0ZXMoZW5jcnlwdGlvbkluZm8uVmVyaWZpZXIuU2FsdCk7Ci0gICAgICAgICAgICBlbmNyeXB0aW9uSW5mby5WZXJpZmllci5TYWx0U2l6ZSA9IDB4MTA7Ci0KLSAgICAgICAgICAgIGtleSA9IEdldFBhc3N3b3JkSGFzaEJpbmFyeShwYXNzd29yZCwgZW5jcnlwdGlvbkluZm8pOwotCi0gICAgICAgICAgICB2YXIgdmVyaWZpZXIgPSBuZXcgYnl0ZVsxNl07Ci0gICAgICAgICAgICBybmQuR2V0Qnl0ZXModmVyaWZpZXIpOwotICAgICAgICAgICAgZW5jcnlwdGlvbkluZm8uVmVyaWZpZXIuRW5jcnlwdGVkVmVyaWZpZXIgPSBFbmNyeXB0RGF0YShrZXksIHZlcmlmaWVyLCB0cnVlKTsKLQotICAgICAgICAgICAgLy9BRVMgPSAzMiBCaXRzCi0gICAgICAgICAgICBlbmNyeXB0aW9uSW5mby5WZXJpZmllci5WZXJpZmllckhhc2hTaXplID0gMHgyMDsKLSAgICAgICAgICAgIFNIQTEgc2hhID0gbmV3IFNIQTFNYW5hZ2VkKCk7Ci0gICAgICAgICAgICB2YXIgdmVyaWZpZXJIYXNoID0gc2hhLkNvbXB1dGVIYXNoKHZlcmlmaWVyKTsKLQotICAgICAgICAgICAgZW5jcnlwdGlvbkluZm8uVmVyaWZpZXIuRW5jcnlwdGVkVmVyaWZpZXJIYXNoID0gRW5jcnlwdERhdGEoa2V5LCB2ZXJpZmllckhhc2gsIGZhbHNlKTsKLQotICAgICAgICAgICAgcmV0dXJuIGVuY3J5cHRpb25JbmZvOwotICAgICAgICB9Ci0gICAgICAgIHByaXZhdGUgYnl0ZVtdIEVuY3J5cHREYXRhKGJ5dGVbXSBrZXksIGJ5dGVbXSBkYXRhLCBib29sIHVzZURhdGFTaXplKQotICAgICAgICB7Ci0gICAgICAgICAgICBSaWpuZGFlbE1hbmFnZWQgYWVzID0gbmV3IFJpam5kYWVsTWFuYWdlZCgpOwotICAgICAgICAgICAgYWVzLktleVNpemUgPSBrZXkuTGVuZ3RoICogODsKLSAgICAgICAgICAgIGFlcy5Nb2RlID0gQ2lwaGVyTW9kZS5FQ0I7Ci0gICAgICAgICAgICBhZXMuUGFkZGluZyA9IFBhZGRpbmdNb2RlLlplcm9zOwotCi0gICAgICAgICAgICAvL0VuY3J5cHQgdGhlIGRhdGEKLSAgICAgICAgICAgIHZhciBjcnlwdCA9IGFlcy5DcmVhdGVFbmNyeXB0b3Ioa2V5LCBudWxsKTsKLSAgICAgICAgICAgIHZhciBtcyA9IG5ldyBNZW1vcnlTdHJlYW0oKTsKLSAgICAgICAgICAgIHZhciBjcyA9IG5ldyBDcnlwdG9TdHJlYW0obXMsIGNyeXB0LCBDcnlwdG9TdHJlYW1Nb2RlLldyaXRlKTsKLSAgICAgICAgICAgIGNzLldyaXRlKGRhdGEsIDAsIGRhdGEuTGVuZ3RoKTsKLQotICAgICAgICAgICAgY3MuRmx1c2hGaW5hbEJsb2NrKCk7Ci0KLSAgICAgICAgICAgIGJ5dGVbXSByZXQ7Ci0gICAgICAgICAgICBpZiAodXNlRGF0YVNpemUpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgcmV0ID0gbmV3IGJ5dGVbZGF0YS5MZW5ndGhdOwotICAgICAgICAgICAgICAgIG1zLlNlZWsoMCwgU2Vla09yaWdpbi5CZWdpbik7Ci0gICAgICAgICAgICAgICAgbXMuUmVhZChyZXQsIDAsIGRhdGEuTGVuZ3RoKTsgIC8vVHJ1bmNhdGUgYW55IHBhZGRlZCBaZXJvcwotICAgICAgICAgICAgICAgIHJldHVybiByZXQ7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIG1zLlRvQXJyYXkoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBwcml2YXRlIE1lbW9yeVN0cmVhbSBHZXRTdHJlYW1Gcm9tUGFja2FnZShDb21wb3VuZERvY3VtZW50IGRvYywgRXhjZWxFbmNyeXB0aW9uIGVuY3J5cHRpb24pCi0gICAgICAgIHsKLSAgICAgICAgICAgIHZhciByZXQgPSBuZXcgTWVtb3J5U3RyZWFtKCk7Ci0gICAgICAgICAgICBpZihkb2MuU3RvcmFnZS5EYXRhU3RyZWFtcy5Db250YWluc0tleSgiRW5jcnlwdGlvbkluZm8iKSB8fAotICAgICAgICAgICAgICAgZG9jLlN0b3JhZ2UuRGF0YVN0cmVhbXMuQ29udGFpbnNLZXkoIkVuY3J5cHRlZFBhY2thZ2UiKSkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICB2YXIgZW5jcnlwdGlvbkluZm8gPSBFbmNyeXB0aW9uSW5mby5SZWFkQmluYXJ5KGRvYy5TdG9yYWdlLkRhdGFTdHJlYW1zWyJFbmNyeXB0aW9uSW5mbyJdKTsKLSAgICAgICAgICAgICAgICAKLSAgICAgICAgICAgICAgICByZXR1cm4gRGVjcnlwdERvY3VtZW50KGRvYy5TdG9yYWdlLkRhdGFTdHJlYW1zWyJFbmNyeXB0ZWRQYWNrYWdlIl0sIGVuY3J5cHRpb25JbmZvLCBlbmNyeXB0aW9uLlBhc3N3b3JkKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICB0aHJvdyAobmV3IEludmFsaWREYXRhRXhjZXB0aW9uKCJJbnZhbGlkIGRvY3VtZW50LiBFbmNyeXB0aW9uSW5mbyBvciBFbmNyeXB0ZWRQYWNrYWdlIHN0cmVhbSBpcyBtaXNzaW5nIikpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8vIDxzdW1tYXJ5PgotICAgICAgICAvLy8gRGVjcnlwdCBhIGRvY3VtZW50Ci0gICAgICAgIC8vLyA8L3N1bW1hcnk+Ci0gICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iZGF0YSI+VGhlIEVuY3J5cHRlZCBkYXRhPC9wYXJhbT4KLSAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJlbmNyeXB0aW9uSW5mbyI+RW5jcnlwdGlvbiBJbmZvIG9iamVjdDwvcGFyYW0+Ci0gICAgICAgIC8vLyA8cGFyYW0gbmFtZT0icGFzc3dvcmQiPlRoZSBwYXNzd29yZDwvcGFyYW0+Ci0gICAgICAgIC8vLyA8cmV0dXJucz48L3JldHVybnM+Ci0gICAgICAgIHByaXZhdGUgTWVtb3J5U3RyZWFtIERlY3J5cHREb2N1bWVudChieXRlW10gZGF0YSwgRW5jcnlwdGlvbkluZm8gZW5jcnlwdGlvbkluZm8sIHN0cmluZyBwYXNzd29yZCkKLSAgICAgICAgewotICAgICAgICAgICAgbG9uZyBzaXplID0gQml0Q29udmVydGVyLlRvSW50NjQoZGF0YSwgMCk7Ci0KLSAgICAgICAgICAgIHZhciBlbmNyeXB0ZWREYXRhID0gbmV3IGJ5dGVbZGF0YS5MZW5ndGggLSA4XTsKLSAgICAgICAgICAgIEFycmF5LkNvcHkoZGF0YSwgOCwgZW5jcnlwdGVkRGF0YSwgMCwgZW5jcnlwdGVkRGF0YS5MZW5ndGgpOwotCi0gICAgICAgICAgICBpZiAoZW5jcnlwdGlvbkluZm8gaXMgRW5jcnlwdGlvbkluZm9CaW5hcnkpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIERlY3J5cHRCaW5hcnkoKEVuY3J5cHRpb25JbmZvQmluYXJ5KWVuY3J5cHRpb25JbmZvLCBwYXNzd29yZCwgc2l6ZSwgZW5jcnlwdGVkRGF0YSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIERlY3J5cHRBZ2lsZSgoRW5jcnlwdGlvbkluZm9BZ2lsZSllbmNyeXB0aW9uSW5mbywgcGFzc3dvcmQsIHNpemUsIGVuY3J5cHRlZERhdGEsIGRhdGEpOwotICAgICAgICAgICAgfQotCi0gICAgICAgIH0KLQotICAgICAgICByZWFkb25seSBieXRlW10gQmxvY2tLZXlfSGFzaElucHV0ID0gbmV3IGJ5dGVbXSB7IDB4ZmUsIDB4YTcsIDB4ZDIsIDB4NzYsIDB4M2IsIDB4NGIsIDB4OWUsIDB4NzkgfTsKLSAgICAgICAgcmVhZG9ubHkgYnl0ZVtdIEJsb2NrS2V5X0hhc2hWYWx1ZSA9IG5ldyBieXRlW10geyAweGQ3LCAweGFhLCAweDBmLCAweDZkLCAweDMwLCAweDYxLCAweDM0LCAweDRlIH07Ci0gICAgICAgIHJlYWRvbmx5IGJ5dGVbXSBCbG9ja0tleV9LZXlWYWx1ZSA9IG5ldyBieXRlW10geyAweDE0LCAweDZlLCAweDBiLCAweGU3LCAweGFiLCAweGFjLCAweGQwLCAweGQ2IH07Ci0gICAgICAgIHJlYWRvbmx5IGJ5dGVbXSBCbG9ja0tleV9IbWFjS2V5ID0gbmV3IGJ5dGVbXSB7IDB4NWYsIDB4YjIsIDB4YWQsIDB4MDEsIDB4MGMsIDB4YjksIDB4ZTEsIDB4ZjYgfTsvL01TT0ZGQ1JZUFRPIDIuMy40LjE0IHNlY3Rpb24gMwotICAgICAgICByZWFkb25seSBieXRlW10gQmxvY2tLZXlfSG1hY1ZhbHVlID0gbmV3IGJ5dGVbXSB7IDB4YTAsIDB4NjcsIDB4N2YsIDB4MDIsIDB4YjIsIDB4MmMsIDB4ODQsIDB4MzMgfTsvL01TT0ZGQ1JZUFRPIDIuMy40LjE0IHNlY3Rpb24gNQotICAgICAgICAKLSAgICAgICAgcHJpdmF0ZSBNZW1vcnlTdHJlYW0gRGVjcnlwdEFnaWxlKEVuY3J5cHRpb25JbmZvQWdpbGUgZW5jcnlwdGlvbkluZm8sIHN0cmluZyBwYXNzd29yZCwgbG9uZyBzaXplLCBieXRlW10gZW5jcnlwdGVkRGF0YSwgYnl0ZVtdIGRhdGEpCi0gICAgICAgIHsgCi0gICAgICAgICAgICBNZW1vcnlTdHJlYW0gZG9jID0gbmV3IE1lbW9yeVN0cmVhbSgpOwotCi0gICAgICAgICAgICBpZiAoZW5jcnlwdGlvbkluZm8uS2V5RGF0YS5DaXBoZXJBbGdvcml0aG0gPT0gZUNpcGhlckFsZ29yaXRobS5BRVMpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgdmFyIGVuY3IgPSBlbmNyeXB0aW9uSW5mby5LZXlFbmNyeXB0b3JzWzBdOwotICAgICAgICAgICAgICAgIHZhciBoYXNoUHJvdmlkZXIgPSBHZXRIYXNoUHJvdmlkZXIoZW5jcik7Ci0gICAgICAgICAgICAgICAgdmFyIGJhc2VIYXNoID0gR2V0UGFzc3dvcmRIYXNoKGhhc2hQcm92aWRlciwgZW5jci5TYWx0VmFsdWUsIHBhc3N3b3JkLCBlbmNyLlNwaW5Db3VudCwgZW5jci5IYXNoU2l6ZSk7Ci0KLSAgICAgICAgICAgICAgICAvL0dldCB0aGUga2V5cyBmb3IgdGhlIHZlcmlmaWVycyBhbmQgdGhlIGtleSB2YWx1ZQotICAgICAgICAgICAgICAgIHZhciB2YWxJbnB1dEtleSA9IEdldEZpbmFsSGFzaChoYXNoUHJvdmlkZXIsIGVuY3IsIEJsb2NrS2V5X0hhc2hJbnB1dCwgYmFzZUhhc2gpOwotICAgICAgICAgICAgICAgIHZhciB2YWxIYXNoS2V5ID0gR2V0RmluYWxIYXNoKGhhc2hQcm92aWRlciwgZW5jciwgQmxvY2tLZXlfSGFzaFZhbHVlLCBiYXNlSGFzaCk7Ci0gICAgICAgICAgICAgICAgdmFyIHZhbEtleVNpemVLZXkgPSBHZXRGaW5hbEhhc2goaGFzaFByb3ZpZGVyLCBlbmNyLCBCbG9ja0tleV9LZXlWYWx1ZSwgYmFzZUhhc2gpOwotCi0gICAgICAgICAgICAgICAgLy9EZWNyeXB0Ci0gICAgICAgICAgICAgICAgZW5jci5WZXJpZmllckhhc2hJbnB1dCA9IERlY3J5cHRBZ2lsZUZyb21LZXkoZW5jciwgdmFsSW5wdXRLZXksIGVuY3IuRW5jcnlwdGVkVmVyaWZpZXJIYXNoSW5wdXQsIGVuY3IuU2FsdFNpemUsIGVuY3IuU2FsdFZhbHVlKTsKLSAgICAgICAgICAgICAgICBlbmNyLlZlcmlmaWVySGFzaCA9IERlY3J5cHRBZ2lsZUZyb21LZXkoZW5jciwgdmFsSGFzaEtleSwgZW5jci5FbmNyeXB0ZWRWZXJpZmllckhhc2gsIGVuY3IuSGFzaFNpemUsIGVuY3IuU2FsdFZhbHVlKTsKLSAgICAgICAgICAgICAgICBlbmNyLktleVZhbHVlID0gRGVjcnlwdEFnaWxlRnJvbUtleShlbmNyLCB2YWxLZXlTaXplS2V5LCBlbmNyLkVuY3J5cHRlZEtleVZhbHVlLCBlbmNyLktleUJpdHMgLyA4LCBlbmNyLlNhbHRWYWx1ZSk7Ci0KLSAgICAgICAgICAgICAgICBpZiAoSXNQYXNzd29yZFZhbGlkKGhhc2hQcm92aWRlciwgZW5jcikpCi0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICB2YXIgaXZobWFjID0gR2V0RmluYWxIYXNoKGhhc2hQcm92aWRlciwgZW5jciwgQmxvY2tLZXlfSG1hY0tleSwgZW5jcnlwdGlvbkluZm8uS2V5RGF0YS5TYWx0VmFsdWUpOwotICAgICAgICAgICAgICAgICAgICB2YXIga2V5ID0gRGVjcnlwdEFnaWxlRnJvbUtleShlbmNyLCBlbmNyLktleVZhbHVlLCBlbmNyeXB0aW9uSW5mby5EYXRhSW50ZWdyaXR5LkVuY3J5cHRlZEhtYWNLZXksIGVuY3J5cHRpb25JbmZvLktleURhdGEuSGFzaFNpemUsIGl2aG1hYyk7Ci0KLSAgICAgICAgICAgICAgICAgICAgaXZobWFjID0gR2V0RmluYWxIYXNoKGhhc2hQcm92aWRlciwgZW5jciwgQmxvY2tLZXlfSG1hY1ZhbHVlLCBlbmNyeXB0aW9uSW5mby5LZXlEYXRhLlNhbHRWYWx1ZSk7Ci0gICAgICAgICAgICAgICAgICAgIHZhciB2YWx1ZSA9IERlY3J5cHRBZ2lsZUZyb21LZXkoZW5jciwgZW5jci5LZXlWYWx1ZSwgZW5jcnlwdGlvbkluZm8uRGF0YUludGVncml0eS5FbmNyeXB0ZWRIbWFjVmFsdWUsIGVuY3J5cHRpb25JbmZvLktleURhdGEuSGFzaFNpemUsIGl2aG1hYyk7Ci0KLSAgICAgICAgICAgICAgICAgICAgdmFyIGhtY2EgPSBHZXRIbWFjUHJvdmlkZXIoZW5jciwga2V5KTsKLSAgICAgICAgICAgICAgICAgICAgdmFyIHYyID0gaG1jYS5Db21wdXRlSGFzaChkYXRhKTsKLQotICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHYyLkxlbmd0aDsgaSsrKQotICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAodmFsdWVbaV0gIT0gdjJbaV0pCi0gICAgICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgKG5ldyBFeGNlcHRpb24oIkRhdGFpbnRlZ3JpdHkga2V5IG1pc3NtYXRjaCIpKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgICAgIGludCBwb3MgPSAwOwotICAgICAgICAgICAgICAgICAgICB1aW50IHNlZ21lbnQgPSAwOwotICAgICAgICAgICAgICAgICAgICB3aGlsZSAocG9zIDwgc2l6ZSkKLSAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHNlZ21lbnRTaXplID0gKGludCkoc2l6ZSAtIHBvcyA+IDQwOTYgPyA0MDk2IDogc2l6ZSAtIHBvcyk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB2YXIgYnVmZmVyU2l6ZSA9IChpbnQpKGVuY3J5cHRlZERhdGEuTGVuZ3RoIC0gcG9zID4gNDA5NiA/IDQwOTYgOiBlbmNyeXB0ZWREYXRhLkxlbmd0aCAtIHBvcyk7Ci0gICAgICAgICAgICAgICAgICAgICAgICB2YXIgaXZUbXAgPSBuZXcgYnl0ZVs0ICsgZW5jcnlwdGlvbkluZm8uS2V5RGF0YS5TYWx0U2l6ZV07Ci0gICAgICAgICAgICAgICAgICAgICAgICBBcnJheS5Db3B5KGVuY3J5cHRpb25JbmZvLktleURhdGEuU2FsdFZhbHVlLCAwLCBpdlRtcCwgMCwgZW5jcnlwdGlvbkluZm8uS2V5RGF0YS5TYWx0U2l6ZSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBBcnJheS5Db3B5KEJpdENvbnZlcnRlci5HZXRCeXRlcyhzZWdtZW50KSwgMCwgaXZUbXAsIGVuY3J5cHRpb25JbmZvLktleURhdGEuU2FsdFNpemUsIDQpOwotICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGl2ID0gaGFzaFByb3ZpZGVyLkNvbXB1dGVIYXNoKGl2VG1wKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHZhciBidWZmZXIgPSBuZXcgYnl0ZVtidWZmZXJTaXplXTsKLSAgICAgICAgICAgICAgICAgICAgICAgIEFycmF5LkNvcHkoZW5jcnlwdGVkRGF0YSwgcG9zLCBidWZmZXIsIDAsIGJ1ZmZlclNpemUpOwotCi0gICAgICAgICAgICAgICAgICAgICAgICB2YXIgYiA9IERlY3J5cHRBZ2lsZUZyb21LZXkoZW5jciwgZW5jci5LZXlWYWx1ZSwgYnVmZmVyLCBzZWdtZW50U2l6ZSwgaXYpOwotICAgICAgICAgICAgICAgICAgICAgICAgZG9jLldyaXRlKGIsIDAsIGIuTGVuZ3RoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHBvcyArPSBzZWdtZW50U2l6ZTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHNlZ21lbnQrKzsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBkb2MuRmx1c2goKTsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRvYzsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgdGhyb3cgKG5ldyBTZWN1cml0eUV4Y2VwdGlvbigiSW52YWxpZCBwYXNzd29yZCIpKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgfQotICAgICAgICBwcml2YXRlIEhhc2hBbGdvcml0aG0gR2V0SGFzaFByb3ZpZGVyKEVuY3J5cHRpb25JbmZvQWdpbGUuRW5jcnlwdGlvbktleUVuY3J5cHRvciBlbmNyKQotICAgICAgICB7Ci0gICAgICAgICAgICBzd2l0Y2ggKGVuY3IuSGFzaEFsZ29yaXRobSkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBjYXNlIGVIYXNoQWxvZ29yaXRobS5NRDU6Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IE1ENUNyeXB0b1NlcnZpY2VQcm92aWRlcigpOwotICAgICAgICAgICAgICAgIGNhc2UgZUhhc2hBbG9nb3JpdGhtLlNIQTE6Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFNIQTFDcnlwdG9TZXJ2aWNlUHJvdmlkZXIoKTsKLSAgICAgICAgICAgICAgICBjYXNlIGVIYXNoQWxvZ29yaXRobS5TSEEyNTY6Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gIG5ldyBTSEEyNTZDcnlwdG9TZXJ2aWNlUHJvdmlkZXIoKTsKLSAgICAgICAgICAgICAgICBjYXNlIGVIYXNoQWxvZ29yaXRobS5TSEEzODQ6Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFNIQTM4NENyeXB0b1NlcnZpY2VQcm92aWRlcigpOwotICAgICAgICAgICAgICAgIGNhc2UgZUhhc2hBbG9nb3JpdGhtLlNIQTUxMjoKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgU0hBNTEyQ3J5cHRvU2VydmljZVByb3ZpZGVyKCk7Ci0gICAgICAgICAgICAgICAgZGVmYXVsdDoKLSAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBOb3RTdXBwb3J0ZWRFeGNlcHRpb24oc3RyaW5nLkZvcm1hdCgiSGFzaCBwcm92aWRlciBpcyB1bnN1cHBvcnRlZC4gezB9IiwgZW5jci5IYXNoQWxnb3JpdGhtKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgcHJpdmF0ZSBNZW1vcnlTdHJlYW0gRGVjcnlwdEJpbmFyeShFbmNyeXB0aW9uSW5mb0JpbmFyeSBlbmNyeXB0aW9uSW5mbywgc3RyaW5nIHBhc3N3b3JkLCBsb25nIHNpemUsIGJ5dGVbXSBlbmNyeXB0ZWREYXRhKQotICAgICAgICB7Ci0gICAgICAgICAgICBNZW1vcnlTdHJlYW0gZG9jID0gbmV3IE1lbW9yeVN0cmVhbSgpOwotCi0gICAgICAgICAgICBpZiAoZW5jcnlwdGlvbkluZm8uSGVhZGVyLkFsZ0lEID09IEFsZ29yaXRobUlELkFFUzEyOCB8fCAoZW5jcnlwdGlvbkluZm8uSGVhZGVyLkFsZ0lEID09IEFsZ29yaXRobUlELkZsYWdzICYmICgoZW5jcnlwdGlvbkluZm8uRmxhZ3MgJiAoRmxhZ3MuZkFFUyB8IEZsYWdzLmZFeHRlcm5hbCB8IEZsYWdzLmZDcnlwdG9BUEkpKSA9PSAoRmxhZ3MuZkFFUyB8IEZsYWdzLmZDcnlwdG9BUEkpKSkKLSAgICAgICAgICAgICAgICB8fAotICAgICAgICAgICAgICAgIGVuY3J5cHRpb25JbmZvLkhlYWRlci5BbGdJRCA9PSBBbGdvcml0aG1JRC5BRVMxOTIKLSAgICAgICAgICAgICAgICB8fAotICAgICAgICAgICAgICAgIGVuY3J5cHRpb25JbmZvLkhlYWRlci5BbGdJRCA9PSBBbGdvcml0aG1JRC5BRVMyNTYKLSAgICAgICAgICAgICAgICApCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgUmlqbmRhZWxNYW5hZ2VkIGRlY3J5cHRLZXkgPSBuZXcgUmlqbmRhZWxNYW5hZ2VkKCk7Ci0gICAgICAgICAgICAgICAgZGVjcnlwdEtleS5LZXlTaXplID0gZW5jcnlwdGlvbkluZm8uSGVhZGVyLktleVNpemU7Ci0gICAgICAgICAgICAgICAgZGVjcnlwdEtleS5Nb2RlID0gQ2lwaGVyTW9kZS5FQ0I7Ci0gICAgICAgICAgICAgICAgZGVjcnlwdEtleS5QYWRkaW5nID0gUGFkZGluZ01vZGUuTm9uZTsKLQotICAgICAgICAgICAgICAgIHZhciBrZXkgPSBHZXRQYXNzd29yZEhhc2hCaW5hcnkocGFzc3dvcmQsIGVuY3J5cHRpb25JbmZvKTsKLSAgICAgICAgICAgICAgICBpZiAoSXNQYXNzd29yZFZhbGlkKGtleSwgZW5jcnlwdGlvbkluZm8pKQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgSUNyeXB0b1RyYW5zZm9ybSBkZWNyeXB0b3IgPSBkZWNyeXB0S2V5LkNyZWF0ZURlY3J5cHRvcigKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBrZXksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVsbCk7Ci0KLSAgICAgICAgICAgICAgICAgICAgdmFyIGRhdGFTdHJlYW0gPSBuZXcgTWVtb3J5U3RyZWFtKGVuY3J5cHRlZERhdGEpOwotICAgICAgICAgICAgICAgICAgICB2YXIgY3J5cHRvU3RyZWFtID0gbmV3IENyeXB0b1N0cmVhbShkYXRhU3RyZWFtLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVjcnlwdG9yLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ3J5cHRvU3RyZWFtTW9kZS5SZWFkKTsKLQotICAgICAgICAgICAgICAgICAgICB2YXIgZGVjcnlwdGVkRGF0YSA9IG5ldyBieXRlW3NpemVdOwotCi0gICAgICAgICAgICAgICAgICAgIGNyeXB0b1N0cmVhbS5SZWFkKGRlY3J5cHRlZERhdGEsIDAsIChpbnQpc2l6ZSk7Ci0gICAgICAgICAgICAgICAgICAgIGRvYy5Xcml0ZShkZWNyeXB0ZWREYXRhLCAwLCAoaW50KXNpemUpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICB0aHJvdyAobmV3IFVuYXV0aG9yaXplZEFjY2Vzc0V4Y2VwdGlvbigiSW52YWxpZCBwYXNzd29yZCIpKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gZG9jOwotICAgICAgICB9Ci0gICAgICAgIC8vLyA8c3VtbWFyeT4KLSAgICAgICAgLy8vIFZhbGlkYXRlIHRoZSBwYXNzd29yZAotICAgICAgICAvLy8gPC9zdW1tYXJ5PgotICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImtleSI+VGhlIGVuY3J5cHRpb24ga2V5PC9wYXJhbT4KLSAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJlbmNyeXB0aW9uSW5mbyI+VGhlIGVuY3J5cHRpb24gaW5mbyBleHRyYWN0ZWQgZnJvbSB0aGUgRU5DUllQVElPSU5GTyBzdHJlYW0gaW5zaWRlIHRoZSBPTEUgZG9jdW1lbnQ8L3BhcmFtPgotICAgICAgICAvLy8gPHJldHVybnM+PC9yZXR1cm5zPgotICAgICAgICBwcml2YXRlIGJvb2wgSXNQYXNzd29yZFZhbGlkKGJ5dGVbXSBrZXksIEVuY3J5cHRpb25JbmZvQmluYXJ5IGVuY3J5cHRpb25JbmZvKQotICAgICAgICB7Ci0gICAgICAgICAgICBSaWpuZGFlbE1hbmFnZWQgZGVjcnlwdEtleSA9IG5ldyBSaWpuZGFlbE1hbmFnZWQoKTsKLSAgICAgICAgICAgIGRlY3J5cHRLZXkuS2V5U2l6ZSA9IGVuY3J5cHRpb25JbmZvLkhlYWRlci5LZXlTaXplOwotICAgICAgICAgICAgZGVjcnlwdEtleS5Nb2RlID0gQ2lwaGVyTW9kZS5FQ0I7Ci0gICAgICAgICAgICBkZWNyeXB0S2V5LlBhZGRpbmcgPSBQYWRkaW5nTW9kZS5Ob25lOwotCi0gICAgICAgICAgICBJQ3J5cHRvVHJhbnNmb3JtIGRlY3J5cHRvciA9IGRlY3J5cHRLZXkuQ3JlYXRlRGVjcnlwdG9yKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBrZXksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGwpOwotCi0KLSAgICAgICAgICAgIC8vRGVjcnlwdCB0aGUgdmVyaWZpZXIKLSAgICAgICAgICAgIE1lbW9yeVN0cmVhbSBkYXRhU3RyZWFtID0gbmV3IE1lbW9yeVN0cmVhbShlbmNyeXB0aW9uSW5mby5WZXJpZmllci5FbmNyeXB0ZWRWZXJpZmllcik7Ci0gICAgICAgICAgICBDcnlwdG9TdHJlYW0gY3J5cHRvU3RyZWFtID0gbmV3IENyeXB0b1N0cmVhbShkYXRhU3RyZWFtLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlY3J5cHRvciwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDcnlwdG9TdHJlYW1Nb2RlLlJlYWQpOwotICAgICAgICAgICAgdmFyIGRlY3J5cHRlZFZlcmlmaWVyID0gbmV3IGJ5dGVbMTZdOwotICAgICAgICAgICAgY3J5cHRvU3RyZWFtLlJlYWQoZGVjcnlwdGVkVmVyaWZpZXIsIDAsIDE2KTsKLQotICAgICAgICAgICAgZGF0YVN0cmVhbSA9IG5ldyBNZW1vcnlTdHJlYW0oZW5jcnlwdGlvbkluZm8uVmVyaWZpZXIuRW5jcnlwdGVkVmVyaWZpZXJIYXNoKTsKLQotICAgICAgICAgICAgY3J5cHRvU3RyZWFtID0gbmV3IENyeXB0b1N0cmVhbShkYXRhU3RyZWFtLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVjcnlwdG9yLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ3J5cHRvU3RyZWFtTW9kZS5SZWFkKTsKLQotICAgICAgICAgICAgLy9EZWNyeXB0IHRoZSB2ZXJpZmllciBoYXNoCi0gICAgICAgICAgICB2YXIgZGVjcnlwdGVkVmVyaWZpZXJIYXNoID0gbmV3IGJ5dGVbMTZdOwotICAgICAgICAgICAgY3J5cHRvU3RyZWFtLlJlYWQoZGVjcnlwdGVkVmVyaWZpZXJIYXNoLCAwLCAoaW50KTE2KTsKLQotICAgICAgICAgICAgLy9HZXQgdGhlIGhhc2ggZm9yIHRoZSBkZWNyeXB0ZWQgdmVyaWZpZXIKLSAgICAgICAgICAgIHZhciBzaGEgPSBuZXcgU0hBMU1hbmFnZWQoKTsKLSAgICAgICAgICAgIHZhciBoYXNoID0gc2hhLkNvbXB1dGVIYXNoKGRlY3J5cHRlZFZlcmlmaWVyKTsKLQotICAgICAgICAgICAgLy9FcXVhbD8KLSAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMTY7IGkrKykKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBpZiAoaGFzaFtpXSAhPSBkZWNyeXB0ZWRWZXJpZmllckhhc2hbaV0pCi0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmV0dXJuIHRydWU7Ci0gICAgICAgIH0KLSAgICAgICAgLy8vIDxzdW1tYXJ5PgotICAgICAgICAvLy8gVmFsaWRhdGUgdGhlIHBhc3N3b3JkCi0gICAgICAgIC8vLyA8L3N1bW1hcnk+Ci0gICAgICAgIC8vLyA8cGFyYW0gbmFtZT0ic2hhIj5UaGUgaGFzaCBhbGdvcml0aG08L3BhcmFtPgotICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImVuY3IiPlRoZSBlbmNyeXB0aW9uIGluZm8gZXh0cmFjdGVkIGZyb20gdGhlIEVOQ1JZUFRJT0lORk8gc3RyZWFtIGluc2lkZSB0aGUgT0xFIGRvY3VtZW50PC9wYXJhbT4KLSAgICAgICAgLy8vIDxyZXR1cm5zPjwvcmV0dXJucz4KLSAgICAgICAgcHJpdmF0ZSBib29sIElzUGFzc3dvcmRWYWxpZChIYXNoQWxnb3JpdGhtIHNoYSwgRW5jcnlwdGlvbkluZm9BZ2lsZS5FbmNyeXB0aW9uS2V5RW5jcnlwdG9yIGVuY3IpCi0gICAgICAgIHsKLSAgICAgICAgICAgIHZhciB2YWxIYXNoID0gc2hhLkNvbXB1dGVIYXNoKGVuY3IuVmVyaWZpZXJIYXNoSW5wdXQpOwotCi0gICAgICAgICAgICAvL0VxdWFsPwotICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCB2YWxIYXNoLkxlbmd0aDsgaSsrKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIGlmIChlbmNyLlZlcmlmaWVySGFzaFtpXSAhPSB2YWxIYXNoW2ldKQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHJldHVybiB0cnVlOwotICAgICAgICB9Ci0KLSAgICAgICAgcHJpdmF0ZSBieXRlW10gRGVjcnlwdEFnaWxlRnJvbUtleShFbmNyeXB0aW9uSW5mb0FnaWxlLkVuY3J5cHRpb25LZXlFbmNyeXB0b3IgZW5jciwgYnl0ZVtdIGtleSwgYnl0ZVtdIGVuY3J5cHRlZERhdGEsIGxvbmcgc2l6ZSwgYnl0ZVtdIGl2KQotICAgICAgICB7Ci0gICAgICAgICAgICBTeW1tZXRyaWNBbGdvcml0aG0gZGVjcnlwdEtleSA9IEdldEVuY3J5cHRpb25BbGdvcml0aG0oZW5jcik7Ci0gICAgICAgICAgICBkZWNyeXB0S2V5LkJsb2NrU2l6ZSA9IGVuY3IuQmxvY2tTaXplIDw8IDM7Ci0gICAgICAgICAgICBkZWNyeXB0S2V5LktleVNpemUgPSBlbmNyLktleUJpdHM7Ci0gICAgICAgICAgICBkZWNyeXB0S2V5Lk1vZGUgPSBlbmNyLkNoaXB0aGVyQ2hhaW5pbmcgPT0gZUNoYWluaW5nTW9kZS5DaGFpbmluZ01vZGVDQkMgPyBDaXBoZXJNb2RlLkNCQyA6IENpcGhlck1vZGUuQ0ZCOwotICAgICAgICAgICAgZGVjcnlwdEtleS5QYWRkaW5nID0gUGFkZGluZ01vZGUuWmVyb3M7Ci0KLSAgICAgICAgICAgIElDcnlwdG9UcmFuc2Zvcm0gZGVjcnlwdG9yID0gZGVjcnlwdEtleS5DcmVhdGVEZWNyeXB0b3IoCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZpeEhhc2hTaXplKGtleSwgZW5jci5LZXlCaXRzIC8gOCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZpeEhhc2hTaXplKGl2LCBlbmNyLkJsb2NrU2l6ZSwgMHgzNikpOwotCi0KLSAgICAgICAgICAgIE1lbW9yeVN0cmVhbSBkYXRhU3RyZWFtID0gbmV3IE1lbW9yeVN0cmVhbShlbmNyeXB0ZWREYXRhKTsKLQotICAgICAgICAgICAgQ3J5cHRvU3RyZWFtIGNyeXB0b1N0cmVhbSA9IG5ldyBDcnlwdG9TdHJlYW0oZGF0YVN0cmVhbSwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlY3J5cHRvciwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENyeXB0b1N0cmVhbU1vZGUuUmVhZCk7Ci0KLSAgICAgICAgICAgIHZhciBkZWNyeXB0ZWREYXRhID0gbmV3IGJ5dGVbc2l6ZV07Ci0KLSAgICAgICAgICAgIGNyeXB0b1N0cmVhbS5SZWFkKGRlY3J5cHRlZERhdGEsIDAsIChpbnQpc2l6ZSk7Ci0gICAgICAgICAgICByZXR1cm4gZGVjcnlwdGVkRGF0YTsKLSAgICAgICAgfQotCi0gICAgICAgIHByaXZhdGUgU3ltbWV0cmljQWxnb3JpdGhtIEdldEVuY3J5cHRpb25BbGdvcml0aG0oRW5jcnlwdGlvbkluZm9BZ2lsZS5FbmNyeXB0aW9uS2V5RW5jcnlwdG9yIGVuY3IpCi0gICAgICAgIHsKLSAgICAgICAgICAgIHN3aXRjaCAoZW5jci5DaXBoZXJBbGdvcml0aG0pCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgY2FzZSBlQ2lwaGVyQWxnb3JpdGhtLkFFUzoKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBSaWpuZGFlbE1hbmFnZWQoKTsKLSAgICAgICAgICAgICAgICBjYXNlIGVDaXBoZXJBbGdvcml0aG0uREVTOgotICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IERFU0NyeXB0b1NlcnZpY2VQcm92aWRlcigpOwotICAgICAgICAgICAgICAgIGNhc2UgZUNpcGhlckFsZ29yaXRobS5UUklQTEVfREVTOgotICAgICAgICAgICAgICAgIGNhc2UgZUNpcGhlckFsZ29yaXRobS5UUklQTEVfREVTXzExMjoKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBUcmlwbGVERVNDcnlwdG9TZXJ2aWNlUHJvdmlkZXIoKTsKLSAgICAgICAgICAgICAgICBjYXNlIGVDaXBoZXJBbGdvcml0aG0uUkMyOgotICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFJDMkNyeXB0b1NlcnZpY2VQcm92aWRlcigpOwotICAgICAgICAgICAgICAgIGRlZmF1bHQ6Ci0gICAgICAgICAgICAgICAgICAgIHRocm93KG5ldyBOb3RTdXBwb3J0ZWRFeGNlcHRpb24oc3RyaW5nLkZvcm1hdCgiVW5zdXBwb3J0ZWQgQ2lwaGVyIEFsZ29yaXRobTogezB9IiwgZW5jci5DaXBoZXJBbGdvcml0aG0uVG9TdHJpbmcoKSkpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBwcml2YXRlIHZvaWQgRW5jcnlwdEFnaWxlRnJvbUtleShFbmNyeXB0aW9uSW5mb0FnaWxlLkVuY3J5cHRpb25LZXlFbmNyeXB0b3IgZW5jciwgYnl0ZVtdIGtleSwgYnl0ZVtdIGRhdGEsIGxvbmcgcG9zLCBsb25nIHNpemUsIGJ5dGVbXSBpdixNZW1vcnlTdHJlYW0gbXMpCi0gICAgICAgIHsKLSAgICAgICAgICAgIHZhciBlbmNyeXB0S2V5ID0gR2V0RW5jcnlwdGlvbkFsZ29yaXRobShlbmNyKTsKLSAgICAgICAgICAgIGVuY3J5cHRLZXkuQmxvY2tTaXplID0gZW5jci5CbG9ja1NpemUgPDwgMzsKLSAgICAgICAgICAgIGVuY3J5cHRLZXkuS2V5U2l6ZSA9IGVuY3IuS2V5Qml0czsKLSAgICAgICAgICAgIGVuY3J5cHRLZXkuTW9kZSA9IGVuY3IuQ2hpcHRoZXJDaGFpbmluZz09ZUNoYWluaW5nTW9kZS5DaGFpbmluZ01vZGVDQkMgPyBDaXBoZXJNb2RlLkNCQyA6IENpcGhlck1vZGUuQ0ZCOwotICAgICAgICAgICAgZW5jcnlwdEtleS5QYWRkaW5nID0gUGFkZGluZ01vZGUuWmVyb3M7Ci0KLSAgICAgICAgICAgIElDcnlwdG9UcmFuc2Zvcm0gZW5jcnlwdG9yID0gZW5jcnlwdEtleS5DcmVhdGVFbmNyeXB0b3IoCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZpeEhhc2hTaXplKGtleSwgZW5jci5LZXlCaXRzIC8gOCksCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZpeEhhc2hTaXplKGl2LCAxNiwgMHgzNikpOwotCi0KLSAgICAgICAgICAgIENyeXB0b1N0cmVhbSBjcnlwdG9TdHJlYW0gPSBuZXcgQ3J5cHRvU3RyZWFtKG1zLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW5jcnlwdG9yLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ3J5cHRvU3RyZWFtTW9kZS5Xcml0ZSk7Ci0gICAgICAgICAgICAKLSAgICAgICAgICAgIHZhciBjcnlwdG9TaXplID0gc2l6ZSAlIGVuY3IuQmxvY2tTaXplID09IDAgPyBzaXplIDogKHNpemUgKyAoZW5jci5CbG9ja1NpemUgLSAoc2l6ZSAlIGVuY3IuQmxvY2tTaXplKSkpOwotICAgICAgICAgICAgdmFyIGJ1ZmZlciA9IG5ldyBieXRlW3NpemVdOwotICAgICAgICAgICAgQXJyYXkuQ29weShkYXRhLCBwb3MsIGJ1ZmZlciwgMCwgc2l6ZSk7Ci0gICAgICAgICAgICBjcnlwdG9TdHJlYW0uV3JpdGUoYnVmZmVyLCAwLCAoaW50KXNpemUpOwotICAgICAgICAgICAgd2hpbGUgKHNpemUgJSBlbmNyLkJsb2NrU2l6ZSAhPSAwKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIGNyeXB0b1N0cmVhbS5Xcml0ZUJ5dGUoMCk7Ci0gICAgICAgICAgICAgICAgc2l6ZSsrOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0KLSAgICAgICAgLy8vIDxzdW1tYXJ5PgotICAgICAgICAvLy8gQ3JlYXRlIHRoZSBoYXNoLgotICAgICAgICAvLy8gVGhpcyBtZXRob2QgaXMgd3JpdHRlbiB3aXRoIHRoZSBoZWxwIG9mIEx5cXVpZGl0eSBsaWJyYXJ5LCBtYW55IHRoYW5rcyBmb3IgdGhpcyBuaWNlIHNhbXBsZQotICAgICAgICAvLy8gPC9zdW1tYXJ5PgotICAgICAgICAvLy8gPHBhcmFtIG5hbWU9InBhc3N3b3JkIj5UaGUgcGFzc3dvcmQ8L3BhcmFtPgotICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImVuY3J5cHRpb25JbmZvIj5UaGUgZW5jcnlwdGlvbiBpbmZvIGV4dHJhY3RlZCBmcm9tIHRoZSBFTkNSWVBUSU9JTkZPIHN0cmVhbSBpbnNpZGUgdGhlIE9MRSBkb2N1bWVudDwvcGFyYW0+Ci0gICAgICAgIC8vLyA8cmV0dXJucz5UaGUgaGFzaCB0byBlbmNyeXB0IHRoZSBkb2N1bWVudDwvcmV0dXJucz4KLSAgICAgICAgcHJpdmF0ZSBieXRlW10gR2V0UGFzc3dvcmRIYXNoQmluYXJ5KHN0cmluZyBwYXNzd29yZCwgRW5jcnlwdGlvbkluZm9CaW5hcnkgZW5jcnlwdGlvbkluZm8pCi0gICAgICAgIHsKLSAgICAgICAgICAgIGJ5dGVbXSBoYXNoID0gbnVsbDsKLSAgICAgICAgICAgIGJ5dGVbXSB0ZW1wSGFzaCA9IG5ldyBieXRlWzQgKyAyMF07ICAgIC8vSXRlcmF0b3IgKyBwcmV2LiBoYXNoCi0gICAgICAgICAgICB0cnkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBIYXNoQWxnb3JpdGhtIGhhc2hQcm92aWRlcjsKLSAgICAgICAgICAgICAgICBpZiAoZW5jcnlwdGlvbkluZm8uSGVhZGVyLkFsZ0lESGFzaCA9PSBBbGdvcml0aG1IYXNoSUQuU0hBMSB8fCBlbmNyeXB0aW9uSW5mby5IZWFkZXIuQWxnSURIYXNoID09IEFsZ29yaXRobUhhc2hJRC5BcHAgJiYgKGVuY3J5cHRpb25JbmZvLkZsYWdzICYgRmxhZ3MuZkV4dGVybmFsKSA9PSAwKQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgaGFzaFByb3ZpZGVyID0gbmV3IFNIQTFDcnlwdG9TZXJ2aWNlUHJvdmlkZXIoKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSBpZiAoZW5jcnlwdGlvbkluZm8uSGVhZGVyLktleVNpemUgPiAwICYmIGVuY3J5cHRpb25JbmZvLkhlYWRlci5LZXlTaXplIDwgODApCi0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTm90U3VwcG9ydGVkRXhjZXB0aW9uKCJSQzQgSGFzaCBwcm92aWRlciBpcyBub3Qgc3VwcG9ydGVkLiBNdXN0IGJlIFNIQTEoQWxnSURIYXNoID09IDB4ODAwNCkiKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IE5vdFN1cHBvcnRlZEV4Y2VwdGlvbigiSGFzaCBwcm92aWRlciBpcyBpbnZhbGlkLiBNdXN0IGJlIFNIQTEoQWxnSURIYXNoID09IDB4ODAwNCkiKTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICBoYXNoID0gR2V0UGFzc3dvcmRIYXNoKGhhc2hQcm92aWRlciwgZW5jcnlwdGlvbkluZm8uVmVyaWZpZXIuU2FsdCwgcGFzc3dvcmQsIDUwMDAwLCAyMCk7Ci0KLSAgICAgICAgICAgICAgICAvLyBBcHBlbmQgImJsb2NrIiAoMCkKLSAgICAgICAgICAgICAgICBBcnJheS5Db3B5KGhhc2gsIHRlbXBIYXNoLCBoYXNoLkxlbmd0aCk7Ci0gICAgICAgICAgICAgICAgQXJyYXkuQ29weShTeXN0ZW0uQml0Q29udmVydGVyLkdldEJ5dGVzKDApLCAwLCB0ZW1wSGFzaCwgaGFzaC5MZW5ndGgsIDQpOwotICAgICAgICAgICAgICAgIGhhc2ggPSBoYXNoUHJvdmlkZXIuQ29tcHV0ZUhhc2godGVtcEhhc2gpOwotCi0gICAgICAgICAgICAgICAgLyoqKioqIE5vdyB1c2UgdGhlIGRlcml2ZWQga2V5IGFsZ29yaXRobSAqKioqKi8KLSAgICAgICAgICAgICAgICBieXRlW10gZGVyaXZlZEtleSA9IG5ldyBieXRlWzY0XTsKLSAgICAgICAgICAgICAgICBpbnQga2V5U2l6ZUJ5dGVzID0gZW5jcnlwdGlvbkluZm8uSGVhZGVyLktleVNpemUgLyA4OwotCi0gICAgICAgICAgICAgICAgLy9GaXJzdCBYT1IgaGFzaCBieXRlcyB3aXRoIDB4MzYgYW5kIGZpbGwgdGhlIHJlc3Qgd2l0aCAweDM2Ci0gICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXJpdmVkS2V5Lkxlbmd0aDsgaSsrKQotICAgICAgICAgICAgICAgICAgICBkZXJpdmVkS2V5W2ldID0gKGJ5dGUpKGkgPCBoYXNoLkxlbmd0aCA/IDB4MzYgXiBoYXNoW2ldIDogMHgzNik7Ci0KLQotICAgICAgICAgICAgICAgIGJ5dGVbXSBYMSA9IGhhc2hQcm92aWRlci5Db21wdXRlSGFzaChkZXJpdmVkS2V5KTsKLQotICAgICAgICAgICAgICAgIC8vaWYgdmVyaWZpZXIgc2l6ZSBpcyBiaWdnZXIgdGhhbiB0aGUga2V5IHNpemUgd2UgY2FuIHJldHVybiBYMQotICAgICAgICAgICAgICAgIGlmICgoaW50KWVuY3J5cHRpb25JbmZvLlZlcmlmaWVyLlZlcmlmaWVySGFzaFNpemUgPiBrZXlTaXplQnl0ZXMpCi0gICAgICAgICAgICAgICAgICAgIHJldHVybiBGaXhIYXNoU2l6ZShYMSwga2V5U2l6ZUJ5dGVzKTsKLQotICAgICAgICAgICAgICAgIC8vRWxzZSBYT1IgaGFzaCBieXRlcyB3aXRoIDB4NUMgYW5kIGZpbGwgdGhlIHJlc3Qgd2l0aCAweDVDCi0gICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBkZXJpdmVkS2V5Lkxlbmd0aDsgaSsrKQotICAgICAgICAgICAgICAgICAgICBkZXJpdmVkS2V5W2ldID0gKGJ5dGUpKGkgPCBoYXNoLkxlbmd0aCA/IDB4NUMgXiBoYXNoW2ldIDogMHg1Qyk7Ci0KLSAgICAgICAgICAgICAgICBieXRlW10gWDIgPSBoYXNoUHJvdmlkZXIuQ29tcHV0ZUhhc2goZGVyaXZlZEtleSk7Ci0KLSAgICAgICAgICAgICAgICAvL0pvaW4gdGhlIHR3byBhbmQgcmV0dXJuIAotICAgICAgICAgICAgICAgIGJ5dGVbXSBqb2luID0gbmV3IGJ5dGVbWDEuTGVuZ3RoICsgWDIuTGVuZ3RoXTsKLQotICAgICAgICAgICAgICAgIEFycmF5LkNvcHkoWDEsIDAsIGpvaW4sIDAsIFgxLkxlbmd0aCk7Ci0gICAgICAgICAgICAgICAgQXJyYXkuQ29weShYMiwgMCwgam9pbiwgWDEuTGVuZ3RoLCBYMi5MZW5ndGgpOwotCi0KLSAgICAgICAgICAgICAgICByZXR1cm4gRml4SGFzaFNpemUoam9pbiwga2V5U2l6ZUJ5dGVzKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGNhdGNoIChFeGNlcHRpb24gZXgpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgKG5ldyBFeGNlcHRpb24oIkFuIGVycm9yIG9jY3VyZWQgd2hlbiB0aGUgZW5jcnlwdGlvbmtleSB3YXMgY3JlYXRlZCIsIGV4KSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICAvLy8gPHN1bW1hcnk+Ci0gICAgICAgIC8vLyBDcmVhdGUgdGhlIGhhc2guCi0gICAgICAgIC8vLyBUaGlzIG1ldGhvZCBpcyB3cml0dGVuIHdpdGggdGhlIGhlbHAgb2YgTHlxdWlkaXR5IGxpYnJhcnksIG1hbnkgdGhhbmtzIGZvciB0aGlzIG5pY2Ugc2FtcGxlCi0gICAgICAgIC8vLyA8L3N1bW1hcnk+Ci0gICAgICAgIC8vLyA8cGFyYW0gbmFtZT0icGFzc3dvcmQiPlRoZSBwYXNzd29yZDwvcGFyYW0+Ci0gICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iZW5jciI+VGhlIGVuY3J5cHRpb24gaW5mbyBleHRyYWN0ZWQgZnJvbSB0aGUgRU5DUllQVElPSU5GTyBzdHJlYW0gaW5zaWRlIHRoZSBPTEUgZG9jdW1lbnQ8L3BhcmFtPgotICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImJsb2NrS2V5Ij5UaGUgYmxvY2sga2V5IGFwcGVuZGVkIHRvIHRoZSBoYXNoIHRvIG9idGFpbiB0aGUgZmluYWwgaGFzaDwvcGFyYW0+Ci0gICAgICAgIC8vLyA8cmV0dXJucz5UaGUgaGFzaCB0byBlbmNyeXB0IHRoZSBkb2N1bWVudDwvcmV0dXJucz4KLSAgICAgICAgcHJpdmF0ZSBieXRlW10gR2V0UGFzc3dvcmRIYXNoQWdpbGUoc3RyaW5nIHBhc3N3b3JkLCBFbmNyeXB0aW9uSW5mb0FnaWxlLkVuY3J5cHRpb25LZXlFbmNyeXB0b3IgZW5jciwgYnl0ZVtdIGJsb2NrS2V5KQotICAgICAgICB7Ci0gICAgICAgICAgICB0cnkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICB2YXIgaGFzaFByb3ZpZGVyID0gR2V0SGFzaFByb3ZpZGVyKGVuY3IpOwotICAgICAgICAgICAgICAgIHZhciBoYXNoID0gR2V0UGFzc3dvcmRIYXNoKGhhc2hQcm92aWRlciwgZW5jci5TYWx0VmFsdWUsIHBhc3N3b3JkLCBlbmNyLlNwaW5Db3VudCwgZW5jci5IYXNoU2l6ZSk7Ci0gICAgICAgICAgICAgICAgdmFyIGhhc2hGaW5hbCA9IEdldEZpbmFsSGFzaChoYXNoUHJvdmlkZXIsIGVuY3IsIGJsb2NrS2V5LCBoYXNoKTsKLQotICAgICAgICAgICAgICAgIHJldHVybiBGaXhIYXNoU2l6ZShoYXNoRmluYWwsIGVuY3IuS2V5Qml0cyAvIDgpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBleCkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICB0aHJvdyAobmV3IEV4Y2VwdGlvbigiQW4gZXJyb3Igb2NjdXJlZCB3aGVuIHRoZSBlbmNyeXB0aW9ua2V5IHdhcyBjcmVhdGVkIiwgZXgpKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotI2VuZGlmCi0JCQlwcml2YXRlIGJ5dGVbXSBHZXRGaW5hbEhhc2goSGFzaEFsZ29yaXRobSBoYXNoUHJvdmlkZXIsIEVuY3J5cHRpb25JbmZvQWdpbGUuRW5jcnlwdGlvbktleUVuY3J5cHRvciBlbmNyLCBieXRlW10gYmxvY2tLZXksIGJ5dGVbXSBoYXNoKQotICAgICAgICB7Ci0gICAgICAgICAgICAvLzIuMy40LjEzIE1TLU9GRkNSWVBUTwotICAgICAgICAgICAgdmFyIHRlbXBIYXNoID0gbmV3IGJ5dGVbaGFzaC5MZW5ndGggKyBibG9ja0tleS5MZW5ndGhdOwotICAgICAgICAgICAgQXJyYXkuQ29weShoYXNoLCB0ZW1wSGFzaCwgaGFzaC5MZW5ndGgpOwotICAgICAgICAgICAgQXJyYXkuQ29weShibG9ja0tleSwgMCwgdGVtcEhhc2gsIGhhc2guTGVuZ3RoLCBibG9ja0tleS5MZW5ndGgpOwotICAgICAgICAgICAgdmFyIGhhc2hGaW5hbCA9IGhhc2hQcm92aWRlci5Db21wdXRlSGFzaCh0ZW1wSGFzaCk7Ci0gICAgICAgICAgICByZXR1cm4gaGFzaEZpbmFsOwotICAgICAgICB9Ci0gICAgICAgIHByaXZhdGUgYnl0ZVtdIEdldFBhc3N3b3JkSGFzaChIYXNoQWxnb3JpdGhtIGhhc2hQcm92aWRlciwgYnl0ZVtdIHNhbHQsIHN0cmluZyBwYXNzd29yZCwgaW50IHNwaW5Db3VudCwgaW50IGhhc2hTaXplKQotICAgICAgICB7Ci0gICAgICAgICAgICBieXRlW10gaGFzaCA9IG51bGw7Ci0gICAgICAgICAgICBieXRlW10gdGVtcEhhc2ggPSBuZXcgYnl0ZVs0ICsgaGFzaFNpemVdOyAgICAvL0l0ZXJhdG9yICsgcHJldi4gaGFzaAotICAgICAgICAgICAgaGFzaCA9IGhhc2hQcm92aWRlci5Db21wdXRlSGFzaChDb21iaW5lUGFzc3dvcmQoc2FsdCwgcGFzc3dvcmQpKTsKLQotICAgICAgICAgICAgLy9JdGVyYXRlICJzcGluQ291bnQiIHRpbWVzLCBpbnNlcnRpbmcgaSBpbiBmaXJzdCA0IGJ5dGVzIGFuZCB0aGVuIHRoZSBwcmV2LiBoYXNoIGluIGJ5dGUgNS0yNAotICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBzcGluQ291bnQ7IGkrKykKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBBcnJheS5Db3B5KEJpdENvbnZlcnRlci5HZXRCeXRlcyhpKSwgdGVtcEhhc2gsIDQpOwotICAgICAgICAgICAgICAgIEFycmF5LkNvcHkoaGFzaCwgMCwgdGVtcEhhc2gsIDQsIGhhc2guTGVuZ3RoKTsKLQotICAgICAgICAgICAgICAgIGhhc2ggPSBoYXNoUHJvdmlkZXIuQ29tcHV0ZUhhc2godGVtcEhhc2gpOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICByZXR1cm4gaGFzaDsKLSAgICAgICAgfQotICAgICAgICBwcml2YXRlIGJ5dGVbXSBGaXhIYXNoU2l6ZShieXRlW10gaGFzaCwgaW50IHNpemUsIGJ5dGUgZmlsbD0wKQotICAgICAgICB7Ci0gICAgICAgICAgICBpZiAoaGFzaC5MZW5ndGggPT0gc2l6ZSkKLSAgICAgICAgICAgICAgICByZXR1cm4gaGFzaDsKLSAgICAgICAgICAgIGVsc2UgaWYgKGhhc2guTGVuZ3RoIDwgc2l6ZSkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBieXRlW10gYnVmZiA9IG5ldyBieXRlW3NpemVdOwotICAgICAgICAgICAgICAgIEFycmF5LkNvcHkoaGFzaCwgYnVmZiwgaGFzaC5MZW5ndGgpOwotICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSBoYXNoLkxlbmd0aDsgaSA8IHNpemU7IGkrKykKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgIGJ1ZmZbaV0gPSBmaWxsOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICByZXR1cm4gYnVmZjsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBieXRlW10gYnVmZiA9IG5ldyBieXRlW3NpemVdOwotICAgICAgICAgICAgICAgIEFycmF5LkNvcHkoaGFzaCwgYnVmZiwgc2l6ZSk7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIGJ1ZmY7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgcHJpdmF0ZSBieXRlW10gQ29tYmluZVBhc3N3b3JkKGJ5dGVbXSBzYWx0LCBzdHJpbmcgcGFzc3dvcmQpCi0gICAgICAgIHsKLSAgICAgICAgICAgIGlmIChwYXNzd29yZCA9PSAiIikKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBwYXNzd29yZCA9ICJWZWx2ZXRTd2VhdHNob3AiOyAgIC8vVXNlZCBpZiBQYXNzd29yZCBpcyBibGFuawotICAgICAgICAgICAgfQotICAgICAgICAgICAgLy8gQ29udmVydCBwYXNzd29yZCB0byB1bmljb2RlLi4uCi0gICAgICAgICAgICBieXRlW10gcGFzc3dvcmRCdWYgPSBVbmljb2RlRW5jb2RpbmcuVW5pY29kZS5HZXRCeXRlcyhwYXNzd29yZCk7Ci0KLSAgICAgICAgICAgIGJ5dGVbXSBpbnB1dEJ1ZiA9IG5ldyBieXRlW3NhbHQuTGVuZ3RoICsgcGFzc3dvcmRCdWYuTGVuZ3RoXTsKLSAgICAgICAgICAgIEFycmF5LkNvcHkoc2FsdCwgaW5wdXRCdWYsIHNhbHQuTGVuZ3RoKTsKLSAgICAgICAgICAgIEFycmF5LkNvcHkocGFzc3dvcmRCdWYsIDAsIGlucHV0QnVmLCBzYWx0Lkxlbmd0aCwgcGFzc3dvcmRCdWYuTGVuZ3RoKTsKLSAgICAgICAgICAgIHJldHVybiBpbnB1dEJ1ZjsKLSAgICAgICAgfQotICAgICAgICBpbnRlcm5hbCBzdGF0aWMgdXNob3J0IENhbGN1bGF0ZVBhc3N3b3JkSGFzaChzdHJpbmcgUGFzc3dvcmQpCi0gICAgICAgIHsKLSAgICAgICAgICAgIC8vQ2FsY3VsYXRlIHRoZSBoYXNoCi0gICAgICAgICAgICAvL1RoYW5rcyB0byBLb2hlaSBZb3NoaWRhIGZvciB0aGUgc2FtcGxlIGh0dHA6Ly9rb2hlaS51cy8yMDA4LzAxLzE4L2V4Y2VsLXNoZWV0LXByb3RlY3Rpb24tcGFzc3dvcmQtaGFzaC8KLSAgICAgICAgICAgIHVzaG9ydCBoYXNoID0gMDsKLSAgICAgICAgICAgIGZvciAoaW50IGkgPSBQYXNzd29yZC5MZW5ndGggLSAxOyBpID49IDA7IGktLSkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBoYXNoIF49IFBhc3N3b3JkW2ldOwotICAgICAgICAgICAgICAgIGhhc2ggPSAodXNob3J0KSgoKHVzaG9ydCkoKGhhc2ggPj4gMTQpICYgMHgwMSkpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKCh1c2hvcnQpKChoYXNoIDw8IDEpICYgMHg3RkZGKSkpOyAgLy9TaGlmdCAxIHRvIHRoZSBsZWZ0LiBPdmVyZmxvd2luZyBiaXQgMTUgZ29lcyBpbnRvIGJpdCAwCi0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGhhc2ggXj0gKDB4ODAwMCB8ICgnTicgPDwgOCkgfCAnSycpOyAvL1hvciBOSyB3aXRoIGhpZ2ggYml0IHNldCgweENFNEIpCi0gICAgICAgICAgICBoYXNoIF49ICh1c2hvcnQpUGFzc3dvcmQuTGVuZ3RoOwotCi0gICAgICAgICAgICByZXR1cm4gaGFzaDsKLSAgICAgICAgfQotICAgIH0KLX0KZGlmZiAtLWdpdCBhL0VQUGx1cy9FbmNyeXB0aW9uL0VuY3J5cHRpb25IZWFkZXIuY3MgYi9FUFBsdXMvRW5jcnlwdGlvbi9FbmNyeXB0aW9uSGVhZGVyLmNzCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBjMGNhNjk3Li4wMDAwMDAwCi0tLSBhL0VQUGx1cy9FbmNyeXB0aW9uL0VuY3J5cHRpb25IZWFkZXIuY3MKKysrIC9kZXYvbnVsbApAQCAtMSwxMDEgKzAsMCBAQAot77u/LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKLSAqIFlvdSBtYXkgYW1lbmQgYW5kIGRpc3RyaWJ1dGUgYXMgeW91IGxpa2UsIGJ1dCBkb24ndCByZW1vdmUgdGhpcyBoZWFkZXIhCi0gKgotICogRVBQbHVzIHByb3ZpZGVzIHNlcnZlci1zaWRlIGdlbmVyYXRpb24gb2YgRXhjZWwgMjAwNy8yMDEwIHNwcmVhZHNoZWV0cy4KLSAqIFNlZSBodHRwOi8vd3d3LmNvZGVwbGV4LmNvbS9FUFBsdXMgZm9yIGRldGFpbHMuCi0gKgotICogQ29weXJpZ2h0IChDKSAyMDExICBKYW4gS8OkbGxtYW4KLSAqCi0gKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCi0gKiBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCi0gKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKLSAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgotCi0gKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKLSAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCi0gKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICAKLSAqIFNlZSB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCi0gKgotICogVGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBjYW4gYmUgdmlld2VkIGF0IGh0dHA6Ly93d3cub3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvbGdwbC1saWNlbnNlLnBocAotICogSWYgeW91IHVuZmFtaWxpYXIgd2l0aCB0aGlzIGxpY2Vuc2Ugb3IgaGF2ZSBxdWVzdGlvbnMgYWJvdXQgaXQsIGhlcmUgaXMgYW4gaHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2dwbC1mYXEuaHRtbAotICoKLSAqIEFsbCBjb2RlIGFuZCBleGVjdXRhYmxlcyBhcmUgcHJvdmlkZWQgImFzIGlzIiB3aXRoIG5vIHdhcnJhbnR5IGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuIAotICogVGhlIGF1dGhvciBhY2NlcHRzIG5vIGxpYWJpbGl0eSBmb3IgYW55IGRhbWFnZSBvciBsb3NzIG9mIGJ1c2luZXNzIHRoYXQgdGhpcyBwcm9kdWN0IG1heSBjYXVzZS4KLSAqCi0gKiBDb2RlIGNoYW5nZSBub3RlczoKLSAqIAotICogQXV0aG9yCQkJCQkJCUNoYW5nZQkJCQkJCURhdGUKLSAqICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgotICogSmFuIEvDpGxsbWFuCQkgICAgQWRkZWQgICAgICAgCQkgICAgICAgIDIwMTMtMDEtMDUKLSAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwotdXNpbmcgU3lzdGVtOwotdXNpbmcgU3lzdGVtLkNvbGxlY3Rpb25zLkdlbmVyaWM7Ci11c2luZyBTeXN0ZW0uSU87Ci11c2luZyBTeXN0ZW0uTGlucTsKLXVzaW5nIFN5c3RlbS5UZXh0OwotCi1uYW1lc3BhY2UgT2ZmaWNlT3BlblhtbC5FbmNyeXB0aW9uCi17Ci0gICAgW0ZsYWdzXQotICAgIGludGVybmFsIGVudW0gRmxhZ3MKLSAgICB7Ci0gICAgICAgIFJlc2VydmVkMSA9IDEsICAgLy8gKDEgYml0KTogTVVTVCBiZSBzZXQgdG8gemVybywgYW5kIE1VU1QgYmUgaWdub3JlZC4KLSAgICAgICAgUmVzZXJ2ZWQyID0gMiwgICAvLyAoMSBiaXQpOiBNVVNUIGJlIHNldCB0byB6ZXJvLCBhbmQgTVVTVCBiZSBpZ25vcmVkLgotICAgICAgICBmQ3J5cHRvQVBJID0gNCwgICAvLyAoMSBiaXQpOiBBIGZsYWcgdGhhdCBzcGVjaWZpZXMgd2hldGhlciBDcnlwdG9BUEkgUkM0IG9yIFtFQ01BLTM3Nl0gZW5jcnlwdGlvbiBpcyB1c2VkLiBJdCBNVVNUIGJlIHNldCB0byAxIHVubGVzcyBmRXh0ZXJuYWwgaXMgMS4gSWYgZkV4dGVybmFsIGlzIHNldCB0byAxLCBpdCBNVVNUIGJlIHNldCB0byB6ZXJvLiAgICAgICAgCi0gICAgICAgIGZEb2NQcm9wcyA9IDgsICAgLy8gKDEgYml0KTogTVVTVCBiZSBzZXQgdG8gemVybyBpZiBkb2N1bWVudCBwcm9wZXJ0aWVzIGFyZSBlbmNyeXB0ZWQuIE90aGVyd2lzZSwgaXQgTVVTVCBiZSBzZXQgdG8gMS4gRW5jcnlwdGlvbiBvZiBkb2N1bWVudCBwcm9wZXJ0aWVzIGlzIHNwZWNpZmllZCBpbiBzZWN0aW9uIDIuMy41LjQuCi0gICAgICAgIGZFeHRlcm5hbCA9IDE2LCAgLy8gKDEgYml0KTogSWYgZXh0ZW5zaWJsZSBlbmNyeXB0aW9uIGlzIHVzZWQsIGl0IE1VU1QgYmUgc2V0IHRvIDEuIE90aGVyd2lzZSwgaXQgTVVTVCBiZSBzZXQgdG8gemVyby4gSWYgdGhpcyBmaWVsZCBpcyBzZXQgdG8gMSwgYWxsIG90aGVyIGZpZWxkcyBpbiB0aGlzIHN0cnVjdHVyZSBNVVNUIGJlIHNldCB0byB6ZXJvLgotICAgICAgICBmQUVTID0gMzIgICAvLygxIGJpdCk6IElmIHRoZSBwcm90ZWN0ZWQgY29udGVudCBpcyBhbiBbRUNNQS0zNzZdIGRvY3VtZW50LCBpdCBNVVNUIGJlIHNldCB0byAxLiBPdGhlcndpc2UsIGl0IE1VU1QgYmUgc2V0IHRvIHplcm8uIElmIHRoZSBmQUVTIGJpdCBpcyBzZXQgdG8gMSwgdGhlIGZDcnlwdG9BUEkgYml0IE1VU1QgYWxzbyBiZSBzZXQgdG8gMQotICAgIH0KLSAgICBpbnRlcm5hbCBlbnVtIEFsZ29yaXRobUlECi0gICAgewotICAgICAgICBGbGFncyA9IDB4MDAwMDAwMDAsICAgLy8gRGV0ZXJtaW5lZCBieSBGbGFncwotICAgICAgICBSQzQgPSAweDAwMDA2ODAxLCAgIC8vIFJDNAotICAgICAgICBBRVMxMjggPSAweDAwMDA2NjBFLCAgIC8vIDEyOC1iaXQgQUVTCi0gICAgICAgIEFFUzE5MiA9IDB4MDAwMDY2MEYsICAgLy8gMTkyLWJpdCBBRVMKLSAgICAgICAgQUVTMjU2ID0gMHgwMDAwNjYxMCAgICAvLyAyNTYtYml0IEFFUwotICAgIH0KLSAgICBpbnRlcm5hbCBlbnVtIEFsZ29yaXRobUhhc2hJRAotICAgIHsKLSAgICAgICAgQXBwID0gMHgwMDAwMDAwMCwKLSAgICAgICAgU0hBMSA9IDB4MDAwMDgwMDQsCi0gICAgfQotICAgIGludGVybmFsIGVudW0gUHJvdmlkZXJUeXBlCi0gICAgewotICAgICAgICBGbGFncyA9IDB4MDAwMDAwMDAsLy9EZXRlcm1pbmVkIGJ5IEZsYWdzCi0gICAgICAgIFJDNCA9IDB4MDAwMDAwMDEsCi0gICAgICAgIEFFUyA9IDB4MDAwMDAwMTgsCi0gICAgfQotICAgIC8vLyA8c3VtbWFyeT4KLSAgICAvLy8gRW5jcnlwdGlvbiBIZWFkZXIgaW5zaWRlIHRoZSBFbmNyeXB0aW9uSW5mbyBzdHJlYW0KLSAgICAvLy8gPC9zdW1tYXJ5PgotICAgIGludGVybmFsIGNsYXNzIEVuY3J5cHRpb25IZWFkZXIKLSAgICB7Ci0gICAgICAgIGludGVybmFsIEZsYWdzIEZsYWdzOwotICAgICAgICBpbnRlcm5hbCBpbnQgU2l6ZUV4dHJhOyAgICAgICAgICAgICAvL01VU1QgYmUgMHgwMDAwMDAwMC4KLSAgICAgICAgaW50ZXJuYWwgQWxnb3JpdGhtSUQgQWxnSUQ7ICAgICAgICAgLy9NVVNUIGJlIDB4MDAwMDY2MEUgKEFFUy0xMjgpLCAweDAwMDA2NjBGIChBRVMtMTkyKSwgb3IgMHgwMDAwNjYxMCAoQUVTLTI1NikuCi0gICAgICAgIGludGVybmFsIEFsZ29yaXRobUhhc2hJRCBBbGdJREhhc2g7IC8vTVVTVCBiZSAweDAwMDA4MDA0IChTSEEtMSkuCi0gICAgICAgIGludGVybmFsIGludCBLZXlTaXplOyAgICAgICAgICAgICAgIC8vTVVTVCBiZSAweDAwMDAwMDgwIChBRVMtMTI4KSwgMHgwMDAwMDBDMCAoQUVTLTE5MiksIG9yIDB4MDAwMDAxMDAgKEFFUy0yNTYpLgotICAgICAgICBpbnRlcm5hbCBQcm92aWRlclR5cGUgUHJvdmlkZXJUeXBlOyAvL1NIT1VMRDwxMD4gYmUgMHgwMDAwMDAxOCAoQUVTKS4KLSAgICAgICAgaW50ZXJuYWwgaW50IFJlc2VydmVkMTsgICAgICAgICAgICAgLy9VbmRlZmluZWQgYW5kIE1VU1QgYmUgaWdub3JlZC4KLSAgICAgICAgaW50ZXJuYWwgaW50IFJlc2VydmVkMjsgICAgICAgICAgICAgLy9NVVNUIGJlIDB4MDAwMDAwMDAgYW5kIE1VU1QgYmUgaWdub3JlZC4KLSAgICAgICAgaW50ZXJuYWwgc3RyaW5nIENTUE5hbWU7ICAgICAgICAgICAgLy9TSE9VTEQ8MTE+IGJlIHNldCB0byBlaXRoZXIgIk1pY3Jvc29mdCBFbmhhbmNlZCBSU0EgYW5kIEFFUyBDcnlwdG9ncmFwaGljIFByb3ZpZGVyIiBvciAiTWljcm9zb2Z0IEVuaGFuY2VkIFJTQSBhbmQgQUVTIENyeXB0b2dyYXBoaWMgUHJvdmlkZXIgKFByb3RvdHlwZSkiIGFzIGEgbnVsbC10ZXJtaW5hdGVkIFVuaWNvZGUgc3RyaW5nLgotICAgICAgICBpbnRlcm5hbCBieXRlW10gV3JpdGVCaW5hcnkoKQotICAgICAgICB7Ci0gICAgICAgICAgICBNZW1vcnlTdHJlYW0gbXMgPSBuZXcgTWVtb3J5U3RyZWFtKCk7Ci0gICAgICAgICAgICBCaW5hcnlXcml0ZXIgYncgPSBuZXcgQmluYXJ5V3JpdGVyKG1zKTsKLQotICAgICAgICAgICAgYncuV3JpdGUoKGludClGbGFncyk7Ci0gICAgICAgICAgICBidy5Xcml0ZShTaXplRXh0cmEpOwotICAgICAgICAgICAgYncuV3JpdGUoKGludClBbGdJRCk7Ci0gICAgICAgICAgICBidy5Xcml0ZSgoaW50KUFsZ0lESGFzaCk7Ci0gICAgICAgICAgICBidy5Xcml0ZSgoaW50KUtleVNpemUpOwotICAgICAgICAgICAgYncuV3JpdGUoKGludClQcm92aWRlclR5cGUpOwotICAgICAgICAgICAgYncuV3JpdGUoUmVzZXJ2ZWQxKTsKLSAgICAgICAgICAgIGJ3LldyaXRlKFJlc2VydmVkMik7Ci0gICAgICAgICAgICBidy5Xcml0ZShFbmNvZGluZy5Vbmljb2RlLkdldEJ5dGVzKENTUE5hbWUpKTsKLQotICAgICAgICAgICAgYncuRmx1c2goKTsKLSAgICAgICAgICAgIHJldHVybiBtcy5Ub0FycmF5KCk7Ci0gICAgICAgIH0KLSAgICB9Ci19CmRpZmYgLS1naXQgYS9FUFBsdXMvRW5jcnlwdGlvbi9FbmNyeXB0aW9uSW5mby5jcyBiL0VQUGx1cy9FbmNyeXB0aW9uL0VuY3J5cHRpb25JbmZvLmNzCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBkMjlhMzY5Li4wMDAwMDAwCi0tLSBhL0VQUGx1cy9FbmNyeXB0aW9uL0VuY3J5cHRpb25JbmZvLmNzCisrKyAvZGV2L251bGwKQEAgLTEsNTg0ICswLDAgQEAKLe+7vy8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCi0gKiBZb3UgbWF5IGFtZW5kIGFuZCBkaXN0cmlidXRlIGFzIHlvdSBsaWtlLCBidXQgZG9uJ3QgcmVtb3ZlIHRoaXMgaGVhZGVyIQotICoKLSAqIEVQUGx1cyBwcm92aWRlcyBzZXJ2ZXItc2lkZSBnZW5lcmF0aW9uIG9mIEV4Y2VsIDIwMDcvMjAxMCBzcHJlYWRzaGVldHMuCi0gKiBTZWUgaHR0cDovL3d3dy5jb2RlcGxleC5jb20vRVBQbHVzIGZvciBkZXRhaWxzLgotICoKLSAqIENvcHlyaWdodCAoQykgMjAxMSAgSmFuIEvDpGxsbWFuCi0gKgotICogVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgotICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwotICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCi0gKiB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KLQotICogVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCi0gKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgotICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgCi0gKiBTZWUgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgotICoKLSAqIFRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgY2FuIGJlIHZpZXdlZCBhdCBodHRwOi8vd3d3Lm9wZW5zb3VyY2Uub3JnL2xpY2Vuc2VzL2xncGwtbGljZW5zZS5waHAKLSAqIElmIHlvdSB1bmZhbWlsaWFyIHdpdGggdGhpcyBsaWNlbnNlIG9yIGhhdmUgcXVlc3Rpb25zIGFib3V0IGl0LCBoZXJlIGlzIGFuIGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9ncGwtZmFxLmh0bWwKLSAqCi0gKiBBbGwgY29kZSBhbmQgZXhlY3V0YWJsZXMgYXJlIHByb3ZpZGVkICJhcyBpcyIgd2l0aCBubyB3YXJyYW50eSBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAKLSAqIFRoZSBhdXRob3IgYWNjZXB0cyBubyBsaWFiaWxpdHkgZm9yIGFueSBkYW1hZ2Ugb3IgbG9zcyBvZiBidXNpbmVzcyB0aGF0IHRoaXMgcHJvZHVjdCBtYXkgY2F1c2UuCi0gKgotICogQ29kZSBjaGFuZ2Ugbm90ZXM6Ci0gKiAKLSAqIEF1dGhvcgkJCQkJCQlDaGFuZ2UJCQkJCQlEYXRlCi0gKiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKLSAqIEphbiBLw6RsbG1hbgkJICAgIEFkZGVkICAgICAgIAkJICAgICAgICAyMDEzLTAxLTA1Ci0gKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLXVzaW5nIFN5c3RlbTsKLXVzaW5nIFN5c3RlbS5Db2xsZWN0aW9ucy5HZW5lcmljOwotdXNpbmcgU3lzdGVtLklPOwotdXNpbmcgU3lzdGVtLkxpbnE7Ci11c2luZyBTeXN0ZW0uVGV4dDsKLXVzaW5nIFN5c3RlbS5YbWw7Ci0KLW5hbWVzcGFjZSBPZmZpY2VPcGVuWG1sLkVuY3J5cHRpb24KLXsKLSAgICBpbnRlcm5hbCBhYnN0cmFjdCBjbGFzcyBFbmNyeXB0aW9uSW5mbwotICAgIHsKLSAgICAgICAgaW50ZXJuYWwgc2hvcnQgTWFqb3JWZXJzaW9uOwotICAgICAgICBpbnRlcm5hbCBzaG9ydCBNaW5vclZlcnNpb247Ci0gICAgICAgIGludGVybmFsIGFic3RyYWN0IHZvaWQgUmVhZChieXRlW10gZGF0YSk7Ci0KLSAgICAgICAgaW50ZXJuYWwgc3RhdGljIEVuY3J5cHRpb25JbmZvIFJlYWRCaW5hcnkoYnl0ZVtdIGRhdGEpCi0gICAgICAgIHsKLSAgICAgICAgICAgIHZhciBtYWpvclZlcnNpb24gPSBCaXRDb252ZXJ0ZXIuVG9JbnQxNihkYXRhLCAwKTsKLSAgICAgICAgICAgIHZhciBtaW5vclZlcnNpb24gPSBCaXRDb252ZXJ0ZXIuVG9JbnQxNihkYXRhLCAyKTsKLSAgICAgICAgICAgIEVuY3J5cHRpb25JbmZvIHJldDsKLSAgICAgICAgICAgIGlmICgobWlub3JWZXJzaW9uID09IDIgfHwgbWlub3JWZXJzaW9uID09IDMpICYmIG1ham9yVmVyc2lvbiA8PSA0KSAvLyBtaW5vclZlcnNpb249PTEgaXMgUkM0LCBub3Qgc3VwcG9ydGVkLgotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIHJldCA9IG5ldyBFbmNyeXB0aW9uSW5mb0JpbmFyeSgpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSBpZiAobWFqb3JWZXJzaW9uID09IDQgJiYgbWlub3JWZXJzaW9uPT00KQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIHJldCA9IG5ldyBFbmNyeXB0aW9uSW5mb0FnaWxlKCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgKG5ldyBOb3RTdXBwb3J0ZWRFeGNlcHRpb24oIlVuc3VwcG9ydGVkIGVuY3J5cHRpb24gZm9ybWF0IikpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmV0Lk1ham9yVmVyc2lvbiA9IG1ham9yVmVyc2lvbjsKLSAgICAgICAgICAgIHJldC5NaW5vclZlcnNpb24gPSBtaW5vclZlcnNpb247Ci0gICAgICAgICAgICByZXQuUmVhZChkYXRhKTsKLSAgICAgICAgICAgIHJldHVybiByZXQ7Ci0gICAgICAgIH0KLSAgICB9Ci0gICAgaW50ZXJuYWwgZW51bSBlQ2lwaGVyQWxnb3JpdGhtCi0gICAgewotICAgICAgICAvLy8gPHN1bW1hcnk+Ci0gICAgICAgIC8vLyBBRVMuIE1VU1QgY29uZm9ybSB0byB0aGUgQUVTIGFsZ29yaXRobS4KLSAgICAgICAgLy8vIDwvc3VtbWFyeT4KLSAgICAgICAgQUVTLAotICAgICAgICAvLy8gPHN1bW1hcnk+Ci0gICAgICAgIC8vLyBSQzIuIE1VU1QgY29uZm9ybSB0byBbUkZDMjI2OF0uCi0gICAgICAgIC8vLyA8L3N1bW1hcnk+Ci0gICAgICAgIFJDMiwKLSAgICAgICAgLy8vIDxzdW1tYXJ5PgotICAgICAgICAvLy8gUkM0LiAKLSAgICAgICAgLy8vIDwvc3VtbWFyeT4KLSAgICAgICAgUkM0LAotICAgICAgICAvLy8gPHN1bW1hcnk+Ci0gICAgICAgIC8vLyBNVVNUIGNvbmZvcm0gdG8gdGhlIERFUyBhbGdvcml0aG0uCi0gICAgICAgIC8vLyA8L3N1bW1hcnk+Ci0gICAgICAgIERFUywKLSAgICAgICAgLy8vIDxzdW1tYXJ5PgotICAgICAgICAvLy8gTVVTVCBjb25mb3JtIHRvIHRoZSBbRFJBRlQtREVTWF0gYWxnb3JpdGhtLgotICAgICAgICAvLy8gPC9zdW1tYXJ5PgotICAgICAgICBERVNYLAotICAgICAgICAvLy8gPHN1bW1hcnk+Ci0gICAgICAgIC8vLyAzREVTLiBNVVNUIGNvbmZvcm0gdG8gdGhlIFtSRkMxODUxXSBhbGdvcml0aG0uIAotICAgICAgICAvLy8gPC9zdW1tYXJ5PgotICAgICAgICBUUklQTEVfREVTLAotICAgICAgICAvLy8gM0RFU18xMTIgTVVTVCBjb25mb3JtIHRvIHRoZSBbUkZDMTg1MV0gYWxnb3JpdGhtLiAKLSAgICAgICAgVFJJUExFX0RFU18xMTIgICAgICAgIAotICAgIH0KLSAgICBpbnRlcm5hbCBlbnVtIGVDaGFpbmluZ01vZGUKLSAgICB7Ci0gICAgICAgIC8vLyA8c3VtbWFyeT4KLSAgICAgICAgLy8vIENpcGhlciBibG9jayBjaGFpbmluZyAoQ0JDKS4KLSAgICAgICAgLy8vIDwvc3VtbWFyeT4KLSAgICAgICAgQ2hhaW5pbmdNb2RlQ0JDLAotICAgICAgICAvLy8gPHN1bW1hcnk+Ci0gICAgICAgIC8vLyBDaXBoZXIgZmVlZGJhY2sgY2hhaW5pbmcgKENGQiksIHdpdGggOC1iaXQgd2luZG93LgotICAgICAgICAvLy8gPC9zdW1tYXJ5PgotICAgICAgICBDaGFpbmluZ01vZGVDRkIKLSAgICB9Ci0gICAgLy8vIDxzdW1tYXJ5PgotICAgIC8vLyBIYXNoYWxnb3JpdGhtCi0gICAgLy8vIDwvc3VtbWFyeT4KLSAgICBpbnRlcm5hbCBlbnVtIGVIYXNoQWxvZ29yaXRobQotICAgIHsKLSAgICAgICAgLy8vIDxzdW1tYXJ5PgotICAgICAgICAvLy8gU2hhIDEtTVVTVCBjb25mb3JtIHRvIFtSRkM0NjM0XQotICAgICAgICAvLy8gPC9zdW1tYXJ5PgotICAgICAgICBTSEExLAotICAgICAgICAvLy8gPHN1bW1hcnk+Ci0gICAgICAgIC8vLyBTaGEgMjU2LU1VU1QgY29uZm9ybSB0byBbUkZDNDYzNF0KLSAgICAgICAgLy8vIDwvc3VtbWFyeT4KLSAgICAgICAgU0hBMjU2LAotICAgICAgICAvLy8gPHN1bW1hcnk+Ci0gICAgICAgIC8vLyBTaGEgMzg0LU1VU1QgY29uZm9ybSB0byBbUkZDNDYzNF0KLSAgICAgICAgLy8vIDwvc3VtbWFyeT4KLSAgICAgICAgU0hBMzg0LAotICAgICAgICAvLy8gPHN1bW1hcnk+Ci0gICAgICAgIC8vLyBTaGEgNTEyLU1VU1QgY29uZm9ybSB0byBbUkZDNDYzNF0KLSAgICAgICAgLy8vIDwvc3VtbWFyeT4KLSAgICAgICAgU0hBNTEyLAotICAgICAgICAvLy8gPHN1bW1hcnk+Ci0gICAgICAgIC8vLyBNRDUKLSAgICAgICAgLy8vIDwvc3VtbWFyeT4KLSAgICAgICAgTUQ1LAotICAgICAgICAvLy8gPHN1bW1hcnk+Ci0gICAgICAgIC8vLyBNRDQKLSAgICAgICAgLy8vIDwvc3VtbWFyeT4KLSAgICAgICAgTUQ0LAotICAgICAgICAvLy8gPHN1bW1hcnk+Ci0gICAgICAgIC8vLyBNRDIKLSAgICAgICAgLy8vIDwvc3VtbWFyeT4KLSAgICAgICAgTUQyLAotICAgICAgICAvLy8gPHN1bW1hcnk+Ci0gICAgICAgIC8vLyBSSVBFTUQtMTI4IE1VU1QgY29uZm9ybSB0byBbSVNPL0lFQyAxMDExOF0KLSAgICAgICAgLy8vIDwvc3VtbWFyeT4KLSAgICAgICAgUklQRU1EMTI4LAotICAgICAgICAvLy8gPHN1bW1hcnk+Ci0gICAgICAgIC8vLyBSSVBFTUQtMTYwIE1VU1QgY29uZm9ybSB0byBbSVNPL0lFQyAxMDExOF0KLSAgICAgICAgLy8vIDwvc3VtbWFyeT4KLSAgICAgICAgUklQRU1EMTYwLAotICAgICAgICAvLy8gPHN1bW1hcnk+Ci0gICAgICAgIC8vLyBXSElSTFBPT0wgTVVTVCBjb25mb3JtIHRvIFtJU08vSUVDIDEwMTE4XQotICAgICAgICAvLy8gPC9zdW1tYXJ5PgotICAgICAgICBXSElSTFBPT0wKLSAgICB9Ci0gICAgLy8vIDxzdW1tYXJ5PgotICAgIC8vLyBIYW5kZWxzIHRoZSBhZ2lsZSBlbmNyeXB0aW9uCi0gICAgLy8vIDwvc3VtbWFyeT4KLSAgICBpbnRlcm5hbCBjbGFzcyBFbmNyeXB0aW9uSW5mb0FnaWxlIDogRW5jcnlwdGlvbkluZm8KLSAgICB7Ci0gICAgICAgIFhtbE5hbWVzcGFjZU1hbmFnZXIgX25zbTsKLSAgICAgICAgcHVibGljIEVuY3J5cHRpb25JbmZvQWdpbGUoKQotICAgICAgICB7Ci0gICAgICAgICAgICB2YXIgbnQgPSBuZXcgTmFtZVRhYmxlKCk7Ci0gICAgICAgICAgICBfbnNtID0gbmV3IFhtbE5hbWVzcGFjZU1hbmFnZXIobnQpOwotICAgICAgICAgICAgX25zbS5BZGROYW1lc3BhY2UoImQiLCAiaHR0cDovL3NjaGVtYXMubWljcm9zb2Z0LmNvbS9vZmZpY2UvMjAwNi9lbmNyeXB0aW9uIik7Ci0gICAgICAgICAgICBfbnNtLkFkZE5hbWVzcGFjZSgiYyIsICJodHRwOi8vc2NoZW1hcy5taWNyb3NvZnQuY29tL29mZmljZS8yMDA2L2tleUVuY3J5cHRvci9jZXJ0aWZpY2F0ZSIpOwotICAgICAgICAgICAgX25zbS5BZGROYW1lc3BhY2UoInAiLCAiaHR0cDovL3NjaGVtYXMubWljcm9zb2Z0LmNvbS9vZmZpY2UvMjAwNi9rZXlFbmNyeXB0b3IvcGFzc3dvcmQiKTsKLSAgICAgICAgfQotICAgICAgICBpbnRlcm5hbCBjbGFzcyBFbmNyeXB0aW9uS2V5RGF0YSA6IFhtbEhlbHBlcgotICAgICAgICB7Ci0gICAgICAgICAgICBwdWJsaWMgRW5jcnlwdGlvbktleURhdGEoWG1sTmFtZXNwYWNlTWFuYWdlciBuc20sIFhtbE5vZGUgdG9wTm9kZSkgOgotICAgICAgICAgICAgICAgIGJhc2UobnNtLCB0b3BOb2RlKQotICAgICAgICAgICAgewotCi0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpbnRlcm5hbCBieXRlW10gU2FsdFZhbHVlCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgZ2V0Ci0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICB2YXIgcyA9IEdldFhtbE5vZGVTdHJpbmcoIkBzYWx0VmFsdWUiKTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKCFzdHJpbmcuSXNOdWxsT3JFbXB0eShzKSkKLSAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIENvbnZlcnQuRnJvbUJhc2U2NFN0cmluZyhzKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgc2V0Ci0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICBTZXRYbWxOb2RlU3RyaW5nKCJAc2FsdFZhbHVlIiwgQ29udmVydC5Ub0Jhc2U2NFN0cmluZyh2YWx1ZSkpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGludGVybmFsIGVIYXNoQWxvZ29yaXRobSBIYXNoQWxnb3JpdGhtCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgZ2V0Ci0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICByZXR1cm4gR2V0SGFzaEFsZ29yaXRobShHZXRYbWxOb2RlU3RyaW5nKCJAaGFzaEFsZ29yaXRobSIpKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgc2V0Ci0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICBTZXRYbWxOb2RlU3RyaW5nKCJAaGFzaEFsZ29yaXRobSIsIEdldEhhc2hBbGdvcml0aG1TdHJpbmcodmFsdWUpKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIHByaXZhdGUgZUhhc2hBbG9nb3JpdGhtIEdldEhhc2hBbGdvcml0aG0oc3RyaW5nIHYpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgc3dpdGNoICh2KQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgY2FzZSAiUklQRU1ELTEyOCI6Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZUhhc2hBbG9nb3JpdGhtLlJJUEVNRDEyODsKLSAgICAgICAgICAgICAgICAgICAgY2FzZSAiUklQRU1ELTE2MCI6Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZUhhc2hBbG9nb3JpdGhtLlJJUEVNRDE2MDsKLSAgICAgICAgICAgICAgICAgICAgY2FzZSAiU0hBLTEiOgotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGVIYXNoQWxvZ29yaXRobS5TSEExOwotICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OgotICAgICAgICAgICAgICAgICAgICAgICAgdHJ5Ci0gICAgICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIChlSGFzaEFsb2dvcml0aG0pRW51bS5QYXJzZSh0eXBlb2YoZUhhc2hBbG9nb3JpdGhtKSx2KTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIGNhdGNoCi0gICAgICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgKG5ldyBJbnZhbGlkRGF0YUV4Y2VwdGlvbigiSW52YWxpZCBIYXNoIGFsZ29yaXRobSIpKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIHByaXZhdGUgc3RyaW5nIEdldEhhc2hBbGdvcml0aG1TdHJpbmcoZUhhc2hBbG9nb3JpdGhtIHZhbHVlKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIHN3aXRjaCAodmFsdWUpCi0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICBjYXNlIGVIYXNoQWxvZ29yaXRobS5SSVBFTUQxMjg6Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gIlJJUEVNRC0xMjgiOwotICAgICAgICAgICAgICAgICAgICBjYXNlIGVIYXNoQWxvZ29yaXRobS5SSVBFTUQxNjA6Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gIlJJUEVNRC0xNjAiOwotICAgICAgICAgICAgICAgICAgICBjYXNlIGVIYXNoQWxvZ29yaXRobS5TSEExOgotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICJTSEEtMSI7Ci0gICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6IAotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlLlRvU3RyaW5nKCk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgaW50ZXJuYWwgZUNoYWluaW5nTW9kZSBDaGlwdGhlckNoYWluaW5nCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgZ2V0Ci0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICB2YXIgdj1HZXRYbWxOb2RlU3RyaW5nKCJAY2lwaGVyQ2hhaW5pbmciKTsKLSAgICAgICAgICAgICAgICAgICAgdHJ5Ci0gICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAoZUNoYWluaW5nTW9kZSlFbnVtLlBhcnNlKHR5cGVvZihlQ2hhaW5pbmdNb2RlKSwgdik7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgY2F0Y2gKLSAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgKG5ldyBJbnZhbGlkRGF0YUV4Y2VwdGlvbigiSW52YWxpZCBjaGFpbmluZyBtb2RlIikpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIHNldAotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgU2V0WG1sTm9kZVN0cmluZygiQGNpcGhlckNoYWluaW5nIiwgdmFsdWUuVG9TdHJpbmcoKSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgaW50ZXJuYWwgZUNpcGhlckFsZ29yaXRobSBDaXBoZXJBbGdvcml0aG0KLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBnZXQKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiBHZXRDaXBoZXJBbGdvcml0aG0oR2V0WG1sTm9kZVN0cmluZygiQGNpcGhlckFsZ29yaXRobSIpKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgc2V0Ci0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICBTZXRYbWxOb2RlU3RyaW5nKCJAY2lwaGVyQWxnb3JpdGhtIiwgR2V0Q2lwaGVyQWxnb3JpdGhtU3RyaW5nKHZhbHVlKSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBwcml2YXRlIGVDaXBoZXJBbGdvcml0aG0gR2V0Q2lwaGVyQWxnb3JpdGhtKHN0cmluZyB2KQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIHN3aXRjaCAodikKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgIGNhc2UgIjNERVMiOgotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGVDaXBoZXJBbGdvcml0aG0uVFJJUExFX0RFUzsKLSAgICAgICAgICAgICAgICAgICAgY2FzZSAiM0RFU18xMTIiOgotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGVDaXBoZXJBbGdvcml0aG0uVFJJUExFX0RFU18xMTI7Ci0gICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6Ci0gICAgICAgICAgICAgICAgICAgICAgICB0cnkKLSAgICAgICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gKGVDaXBoZXJBbGdvcml0aG0pRW51bS5QYXJzZSh0eXBlb2YoZUNpcGhlckFsZ29yaXRobSksIHYpOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgY2F0Y2gKLSAgICAgICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyAobmV3IEludmFsaWREYXRhRXhjZXB0aW9uKCJJbnZhbGlkIEhhc2ggYWxnb3JpdGhtIikpOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgcHJpdmF0ZSBzdHJpbmcgR2V0Q2lwaGVyQWxnb3JpdGhtU3RyaW5nKGVDaXBoZXJBbGdvcml0aG0gYWxnKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIHN3aXRjaCAoYWxnKQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgY2FzZSBlQ2lwaGVyQWxnb3JpdGhtLlRSSVBMRV9ERVM6Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gIjNERVMiOwotICAgICAgICAgICAgICAgICAgICBjYXNlIGVDaXBoZXJBbGdvcml0aG0uVFJJUExFX0RFU18xMTI6Ci0gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gIjNERVNfMTEyIjsgICAgICAgICAgICAgICAgICAgIAotICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OgotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGFsZy5Ub1N0cmluZygpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGludGVybmFsIGludCBIYXNoU2l6ZQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIGdldAotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIEdldFhtbE5vZGVJbnQoIkBoYXNoU2l6ZSIpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBzZXQKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgIFNldFhtbE5vZGVTdHJpbmcoIkBoYXNoU2l6ZSIsIHZhbHVlLlRvU3RyaW5nKCkpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGludGVybmFsIGludCBLZXlCaXRzCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgZ2V0Ci0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICByZXR1cm4gR2V0WG1sTm9kZUludCgiQGtleUJpdHMiKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgc2V0Ci0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICBTZXRYbWxOb2RlU3RyaW5nKCJAa2V5Qml0cyIsIHZhbHVlLlRvU3RyaW5nKCkpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGludGVybmFsIGludCBCbG9ja1NpemUKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBnZXQKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgIHJldHVybiBHZXRYbWxOb2RlSW50KCJAYmxvY2tTaXplIik7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIHNldAotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgU2V0WG1sTm9kZVN0cmluZygiQGJsb2NrU2l6ZSIsIHZhbHVlLlRvU3RyaW5nKCkpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGludGVybmFsIGludCBTYWx0U2l6ZQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIGdldAotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIEdldFhtbE5vZGVJbnQoIkBzYWx0U2l6ZSIpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBzZXQKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgIFNldFhtbE5vZGVTdHJpbmcoIkBzYWx0U2l6ZSIsIHZhbHVlLlRvU3RyaW5nKCkpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBpbnRlcm5hbCBjbGFzcyBFbmNyeXB0aW9uRGF0YUludGVncml0eSA6IFhtbEhlbHBlcgotICAgICAgICB7Ci0gICAgICAgICAgICBwdWJsaWMgRW5jcnlwdGlvbkRhdGFJbnRlZ3JpdHkoWG1sTmFtZXNwYWNlTWFuYWdlciBuc20sIFhtbE5vZGUgdG9wTm9kZSkgOgotICAgICAgICAgICAgICAgIGJhc2UobnNtLCB0b3BOb2RlKQotICAgICAgICAgICAgewotCi0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpbnRlcm5hbCBieXRlW10gRW5jcnlwdGVkSG1hY1ZhbHVlCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgZ2V0Ci0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICB2YXIgcyA9IEdldFhtbE5vZGVTdHJpbmcoIkBlbmNyeXB0ZWRIbWFjVmFsdWUiKTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKCFzdHJpbmcuSXNOdWxsT3JFbXB0eShzKSkKLSAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIENvbnZlcnQuRnJvbUJhc2U2NFN0cmluZyhzKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgc2V0Ci0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICBTZXRYbWxOb2RlU3RyaW5nKCJAZW5jcnlwdGVkSG1hY1ZhbHVlIiwgQ29udmVydC5Ub0Jhc2U2NFN0cmluZyh2YWx1ZSkpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGludGVybmFsIGJ5dGVbXSBFbmNyeXB0ZWRIbWFjS2V5Ci0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgZ2V0Ci0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICB2YXIgcyA9IEdldFhtbE5vZGVTdHJpbmcoIkBlbmNyeXB0ZWRIbWFjS2V5Iik7Ci0gICAgICAgICAgICAgICAgICAgIGlmICghc3RyaW5nLklzTnVsbE9yRW1wdHkocykpCi0gICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBDb252ZXJ0LkZyb21CYXNlNjRTdHJpbmcocyk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIHNldAotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgU2V0WG1sTm9kZVN0cmluZygiQGVuY3J5cHRlZEhtYWNLZXkiLCBDb252ZXJ0LlRvQmFzZTY0U3RyaW5nKHZhbHVlKSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIGludGVybmFsIGNsYXNzIEVuY3J5cHRpb25LZXlFbmNyeXB0b3IgOiBFbmNyeXB0aW9uS2V5RGF0YQotICAgICAgICB7Ci0gICAgICAgICAgICBwdWJsaWMgRW5jcnlwdGlvbktleUVuY3J5cHRvcihYbWxOYW1lc3BhY2VNYW5hZ2VyIG5zbSwgWG1sTm9kZSB0b3BOb2RlKSA6Ci0gICAgICAgICAgICAgICAgYmFzZShuc20sIHRvcE5vZGUpCi0gICAgICAgICAgICB7Ci0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGludGVybmFsIGJ5dGVbXSBFbmNyeXB0ZWRLZXlWYWx1ZQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIGdldAotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgdmFyIHMgPSBHZXRYbWxOb2RlU3RyaW5nKCJAZW5jcnlwdGVkS2V5VmFsdWUiKTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKCFzdHJpbmcuSXNOdWxsT3JFbXB0eShzKSkKLSAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIENvbnZlcnQuRnJvbUJhc2U2NFN0cmluZyhzKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgc2V0Ci0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICBTZXRYbWxOb2RlU3RyaW5nKCJAZW5jcnlwdGVkS2V5VmFsdWUiLCBDb252ZXJ0LlRvQmFzZTY0U3RyaW5nKHZhbHVlKSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgaW50ZXJuYWwgYnl0ZVtdIEVuY3J5cHRlZFZlcmlmaWVySGFzaAotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIGdldAotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgdmFyIHMgPSBHZXRYbWxOb2RlU3RyaW5nKCJAZW5jcnlwdGVkVmVyaWZpZXJIYXNoVmFsdWUiKTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKCFzdHJpbmcuSXNOdWxsT3JFbXB0eShzKSkKLSAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIENvbnZlcnQuRnJvbUJhc2U2NFN0cmluZyhzKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKLQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBzZXQKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgIFNldFhtbE5vZGVTdHJpbmcoIkBlbmNyeXB0ZWRWZXJpZmllckhhc2hWYWx1ZSIsIENvbnZlcnQuVG9CYXNlNjRTdHJpbmcodmFsdWUpKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpbnRlcm5hbCBieXRlW10gRW5jcnlwdGVkVmVyaWZpZXJIYXNoSW5wdXQKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBnZXQKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgIHZhciBzID0gR2V0WG1sTm9kZVN0cmluZygiQGVuY3J5cHRlZFZlcmlmaWVySGFzaElucHV0Iik7Ci0gICAgICAgICAgICAgICAgICAgIGlmICghc3RyaW5nLklzTnVsbE9yRW1wdHkocykpCi0gICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBDb252ZXJ0LkZyb21CYXNlNjRTdHJpbmcocyk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIHNldAotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgU2V0WG1sTm9kZVN0cmluZygiQGVuY3J5cHRlZFZlcmlmaWVySGFzaElucHV0IiwgQ29udmVydC5Ub0Jhc2U2NFN0cmluZyh2YWx1ZSkpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGludGVybmFsIGJ5dGVbXSBWZXJpZmllckhhc2hJbnB1dCB7IGdldDsgc2V0OyB9Ci0gICAgICAgICAgICBpbnRlcm5hbCBieXRlW10gVmVyaWZpZXJIYXNoIHsgZ2V0OyBzZXQ7IH0KLSAgICAgICAgICAgIGludGVybmFsIGJ5dGVbXSBLZXlWYWx1ZSB7IGdldDsgc2V0OyB9Ci0gICAgICAgICAgICBpbnRlcm5hbCBpbnQgU3BpbkNvdW50Ci0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgZ2V0Ci0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICByZXR1cm4gR2V0WG1sTm9kZUludCgiQHNwaW5Db3VudCIpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBzZXQKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgIFNldFhtbE5vZGVTdHJpbmcoIkBzcGluQ291bnQiLCB2YWx1ZS5Ub1N0cmluZygpKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgLyoKLSAgICAgICAgPD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9InllcyI/PgotICAgICAgICAgICA8ZW5jcnlwdGlvbiB4bWxucz0iaHR0cDovL3NjaGVtYXMubWljcm9zb2Z0LmNvbS9vZmZpY2UvMjAwNi9lbmNyeXB0aW9uIiB4bWxuczpwPSJodHRwOi8vc2NoZW1hcy5taWNyb3NvZnQuY29tL29mZmljZS8yMDA2L2tleUVuY3J5cHRvci9wYXNzd29yZCIgeG1sbnM6Yz0iaHR0cDovL3NjaGVtYXMubWljcm9zb2Z0LmNvbS9vZmZpY2UvMjAwNi9rZXlFbmNyeXB0b3IvY2VydGlmaWNhdGUiPgotICAgICAgICAgICAgICAgPGtleURhdGEgc2FsdFNpemU9IjE2IiBibG9ja1NpemU9IjE2IiBrZXlCaXRzPSIyNTYiIGhhc2hTaXplPSI2NCIgY2lwaGVyQWxnb3JpdGhtPSJBRVMiIGNpcGhlckNoYWluaW5nPSJDaGFpbmluZ01vZGVDQkMiIGhhc2hBbGdvcml0aG09IlNIQTUxMiIgc2FsdFZhbHVlPSJwYStockozczF6clk2aG1WdVNhNUpRPT0iIC8+Ci0gICAgICAgICAgICAgICA8ZGF0YUludGVncml0eSBlbmNyeXB0ZWRIbWFjS2V5PSJuZDhpNHNFS2pzTWpWTjJnTG85MW9GTjJlN2JoTXBXS0RDQVVCRXB6NEdXNk5jRTNoQlhEb2JMa3NadlFHd0xyUGowU1VWelFBOFZ1RE15ak1BZlZDQT09IiBlbmNyeXB0ZWRIbWFjVmFsdWU9Ik82b2VnSHBRVnoydU83T200b1ppalNpNGt6TGlpTVpHSWpmWmxxL0VGRk82UFpiS2l0ZW5CcWUyb3IxUkVheGFJN2dPL0ptdEp6WjFWaXVjcVRhdzRnPT0iIC8+Ci0gICAgICAgICAgICAgICA8a2V5RW5jcnlwdG9ycz4KLSAgICAgICAgICAgICAgICAgICA8a2V5RW5jcnlwdG9yIHVyaT0iaHR0cDovL3NjaGVtYXMubWljcm9zb2Z0LmNvbS9vZmZpY2UvMjAwNi9rZXlFbmNyeXB0b3IvcGFzc3dvcmQiPgotICAgICAgICAgICAgICAgICAgICAgIDxwOmVuY3J5cHRlZEtleSBzcGluQ291bnQ9IjEwMDAwMCIgc2FsdFNpemU9IjE2IiBibG9ja1NpemU9IjE2IiBrZXlCaXRzPSIyNTYiIGhhc2hTaXplPSI2NCIgY2lwaGVyQWxnb3JpdGhtPSJBRVMiIGNpcGhlckNoYWluaW5nPSJDaGFpbmluZ01vZGVDQkMiIGhhc2hBbGdvcml0aG09IlNIQTUxMiIgc2FsdFZhbHVlPSJ1MkJORkF1SFluM00vV1JqYTMvdVBnPT0iIGVuY3J5cHRlZFZlcmlmaWVySGFzaElucHV0PSJNMFYrZlJvbEpNUmdGeUk5dytBVnhRPT0iIGVuY3J5cHRlZFZlcmlmaWVySGFzaFZhbHVlPSJWLzZsOXBGSDdBYVhGcUVic25GQmZIZTdnTU9xRmVSd2FOTWpjN0QzTE5kdzZLZ1p6T09RbHQ1c0U4L29HN0dQVkJER2ZvUU1UeGpReWRWUFZ5NHFuZz09IiBlbmNyeXB0ZWRLZXlWYWx1ZT0iQjAvcmJTUVJpSUtHNUNRREg2QUtZU3liZFh6eGdLQWZYMWYrUzVrN21ORT0iIC8+Ci0gICAgICAgICAgICAgICAgICAgPC9rZXlFbmNyeXB0b3I+PC9rZXlFbmNyeXB0b3JzPjwvZW5jcnlwdGlvbj4KLSAgICAgICAgKi8KLSAgICAgICAgCi0gICAgICAgIC8qKioKLSAgICAgICAgICogPD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9InRydWUiPz4KLSAgICAgICAgICAgIDxlbmNyeXB0aW9uIHhtbG5zOmM9Imh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC5jb20vb2ZmaWNlLzIwMDYva2V5RW5jcnlwdG9yL2NlcnRpZmljYXRlIiB4bWxuczpwPSJodHRwOi8vc2NoZW1hcy5taWNyb3NvZnQuY29tL29mZmljZS8yMDA2L2tleUVuY3J5cHRvci9wYXNzd29yZCIgeG1sbnM9Imh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC5jb20vb2ZmaWNlLzIwMDYvZW5jcnlwdGlvbiI+Ci0gICAgICAgICAqICAgICAgPGtleURhdGEgc2FsdFZhbHVlPSJYbVRCL1hCR0pTYndkL0dUS3pRdjVBPT0iIGhhc2hBbGdvcml0aG09IlNIQTUxMiIgY2lwaGVyQ2hhaW5pbmc9IkNoYWluaW5nTW9kZUNCQyIgY2lwaGVyQWxnb3JpdGhtPSJBRVMiIGhhc2hTaXplPSI2NCIga2V5Qml0cz0iMjU2IiBibG9ja1NpemU9IjE2IiBzYWx0U2l6ZT0iMTYiLz4KLSAgICAgICAgICogICAgICA8ZGF0YUludGVncml0eSBlbmNyeXB0ZWRIbWFjVmFsdWU9IldXdzNCYjJkYmNOUE1ubDlmMW83ck8wdTdzY2xXR0tUWHFCQTZyUnpLc1AyS3pXUzVUMEx4WTlxRm9DNlFFNjd0L3QrRk5OdE1EZE10RTNEMXh2VDh3PT0iIGVuY3J5cHRlZEhtYWNLZXk9InAvZFZkbEpZNUtqMGszakkxSFJqcXRrNHMwWTRIbURBc2M4bnFaZ2Z4TlM3RG9wQXNTM0xVLzJwM0NZb0lST2JIc25IVEF0YnVlSDA4REZDWUdaVVJnPT0iLz4KLSAgICAgICAgICogICAgICAgICAgPGtleUVuY3J5cHRvcnM+Ci0gICAgICAgICAqICAgICAgICAgICAgICA8a2V5RW5jcnlwdG9yIHVyaT0iaHR0cDovL3NjaGVtYXMubWljcm9zb2Z0LmNvbS9vZmZpY2UvMjAwNi9rZXlFbmNyeXB0b3IvcGFzc3dvcmQiPgotICAgICAgICAgKiAgICAgICAgICAgICAgICAgIDxwOmVuY3J5cHRlZEtleSBzYWx0VmFsdWU9IkVlQnRZMFFmdHlPa0x6dENsN05GMGc9PSIgaGFzaEFsZ29yaXRobT0iU0hBNTEyIiBjaXBoZXJDaGFpbmluZz0iQ2hhaW5pbmdNb2RlQ0JDIiBjaXBoZXJBbGdvcml0aG09IkFFUyIgaGFzaFNpemU9IjY0IiBrZXlCaXRzPSIyNTYiIGJsb2NrU2l6ZT0iMTYiIHNhbHRTaXplPSIxNiIgZW5jcnlwdGVkS2V5VmFsdWU9Ilo3QU84dkhublBaRWIxVnF5WkxKNkpGYzNNcTNFMzIyWFB4V1hTMjFmYlU9IiBlbmNyeXB0ZWRWZXJpZmllckhhc2hWYWx1ZT0iRzdCeGJLblphbmxkdnRzYnU1MW1QOUozZjlXcjV2Q2ZDcHZXU2g1ZUlKZmY3U3IzSjJEekgxLzlhS2o5dUlwcUZRSXNMb2hwUmsrb0JZRGNYN2hSZ3c9PSIgZW5jcnlwdGVkVmVyaWZpZXJIYXNoSW5wdXQ9Ijg1MWVzemw1eTVyZFUxUm5UakVXSHc9PSIgc3BpbkNvdW50PSIxMDAwMDAiLz4KLSAgICAgICAgICogICAgICAgICAgICAgIDwva2V5RW5jcnlwdG9yPgotICAgICAgICAgKiAgICAgIDwva2V5RW5jcnlwdG9ycz4KLSAgICAgICAgICogICAgICA8L2VuY3J5cHRpb24KLSAgICAgICAgICogKioqLwotICAgICAgICBpbnRlcm5hbCBFbmNyeXB0aW9uRGF0YUludGVncml0eSBEYXRhSW50ZWdyaXR5IHsgZ2V0OyBzZXQ7IH0KLSAgICAgICAgaW50ZXJuYWwgRW5jcnlwdGlvbktleURhdGEgS2V5RGF0YSB7IGdldDsgc2V0OyB9Ci0gICAgICAgIGludGVybmFsIExpc3Q8RW5jcnlwdGlvbktleUVuY3J5cHRvcj4gS2V5RW5jcnlwdG9ycwotICAgICAgICB7Ci0gICAgICAgICAgICBnZXQ7Ci0gICAgICAgICAgICBwcml2YXRlIHNldDsKLSAgICAgICAgfQotCi0gICAgICAgIGludGVybmFsIFhtbERvY3VtZW50IFhtbCB7Z2V0O3NldDt9Ci0gICAgICAgIGludGVybmFsIG92ZXJyaWRlIHZvaWQgUmVhZChieXRlW10gZGF0YSkKLSAgICAgICAgewotICAgICAgICAgICAgdmFyIGJ5WG1sID0gbmV3IGJ5dGVbZGF0YS5MZW5ndGggLSA4XTsKLSAgICAgICAgICAgIEFycmF5LkNvcHkoZGF0YSwgOCwgYnlYbWwsIDAsIGRhdGEuTGVuZ3RoIC0gOCk7Ci0gICAgICAgICAgICB2YXIgeG1sID0gRW5jb2RpbmcuVVRGOC5HZXRTdHJpbmcoYnlYbWwpOwotICAgICAgICAgICAgUmVhZEZyb21YbWwoeG1sKTsKLSAgICAgICAgfQotICAgICAgICBpbnRlcm5hbCB2b2lkIFJlYWRGcm9tWG1sKHN0cmluZyB4bWwpCi0gICAgICAgIHsKLSAgICAgICAgICAgIFhtbCA9IG5ldyBYbWxEb2N1bWVudCgpOwotICAgICAgICAgICAgWG1sSGVscGVyLkxvYWRYbWxTYWZlKFhtbCwgeG1sLCBFbmNvZGluZy5VVEY4KTsKLSAgICAgICAgICAgIHZhciBub2RlID0gWG1sLlNlbGVjdFNpbmdsZU5vZGUoIi9kOmVuY3J5cHRpb24vZDprZXlEYXRhIiwgX25zbSk7Ci0gICAgICAgICAgICBLZXlEYXRhID0gbmV3IEVuY3J5cHRpb25LZXlEYXRhKF9uc20sIG5vZGUpOwotICAgICAgICAgICAgbm9kZSA9IFhtbC5TZWxlY3RTaW5nbGVOb2RlKCIvZDplbmNyeXB0aW9uL2Q6ZGF0YUludGVncml0eSIsIF9uc20pOwotICAgICAgICAgICAgRGF0YUludGVncml0eSA9IG5ldyBFbmNyeXB0aW9uRGF0YUludGVncml0eShfbnNtLCBub2RlKTsKLSAgICAgICAgICAgIEtleUVuY3J5cHRvcnMgPSBuZXcgTGlzdDxFbmNyeXB0aW9uS2V5RW5jcnlwdG9yPigpOwotCi0gICAgICAgICAgICB2YXIgbGlzdCA9IFhtbC5TZWxlY3ROb2RlcygiL2Q6ZW5jcnlwdGlvbi9kOmtleUVuY3J5cHRvcnMvZDprZXlFbmNyeXB0b3IvcDplbmNyeXB0ZWRLZXkiLCBfbnNtKTsKLSAgICAgICAgICAgIGlmIChsaXN0ICE9IG51bGwpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgZm9yZWFjaCAoWG1sTm9kZSBuIGluIGxpc3QpCi0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICBLZXlFbmNyeXB0b3JzLkFkZChuZXcgRW5jcnlwdGlvbktleUVuY3J5cHRvcihfbnNtLCBuKSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotCi0gICAgICAgIH0KLSAgICB9Ci0gICAgLy8vIDxzdW1tYXJ5PgotICAgIC8vLyBIYW5kbGVzIHRoZSBFbmNyeXB0aW9uSW5mbyBzdHJlYW0KLSAgICAvLy8gPC9zdW1tYXJ5PgotICAgIGludGVybmFsIGNsYXNzIEVuY3J5cHRpb25JbmZvQmluYXJ5IDogRW5jcnlwdGlvbkluZm8KLSAgICB7Ci0KLQotICAgICAgICBpbnRlcm5hbCBGbGFncyBGbGFnczsKLSAgICAgICAgaW50ZXJuYWwgdWludCBIZWFkZXJTaXplOwotICAgICAgICBpbnRlcm5hbCBFbmNyeXB0aW9uSGVhZGVyIEhlYWRlcjsKLSAgICAgICAgaW50ZXJuYWwgRW5jcnlwdGlvblZlcmlmaWVyIFZlcmlmaWVyOwotICAgICAgICBpbnRlcm5hbCBvdmVycmlkZSB2b2lkIFJlYWQoYnl0ZVtdIGRhdGEpCi0gICAgICAgIHsKLSAgICAgICAgICAgIEZsYWdzID0gKEZsYWdzKUJpdENvbnZlcnRlci5Ub0ludDMyKGRhdGEsIDQpOwotICAgICAgICAgICAgSGVhZGVyU2l6ZSA9ICh1aW50KUJpdENvbnZlcnRlci5Ub0ludDMyKGRhdGEsIDgpOwotCi0gICAgICAgICAgICAvKioqKiBFbmNyeXB0aW9uSGVhZGVyICoqKiovCi0gICAgICAgICAgICBIZWFkZXIgPSBuZXcgRW5jcnlwdGlvbkhlYWRlcigpOwotICAgICAgICAgICAgSGVhZGVyLkZsYWdzID0gKEZsYWdzKUJpdENvbnZlcnRlci5Ub0ludDMyKGRhdGEsIDEyKTsKLSAgICAgICAgICAgIEhlYWRlci5TaXplRXh0cmEgPSBCaXRDb252ZXJ0ZXIuVG9JbnQzMihkYXRhLCAxNik7Ci0gICAgICAgICAgICBIZWFkZXIuQWxnSUQgPSAoQWxnb3JpdGhtSUQpQml0Q29udmVydGVyLlRvSW50MzIoZGF0YSwgMjApOwotICAgICAgICAgICAgSGVhZGVyLkFsZ0lESGFzaCA9IChBbGdvcml0aG1IYXNoSUQpQml0Q29udmVydGVyLlRvSW50MzIoZGF0YSwgMjQpOwotICAgICAgICAgICAgSGVhZGVyLktleVNpemUgPSBCaXRDb252ZXJ0ZXIuVG9JbnQzMihkYXRhLCAyOCk7Ci0gICAgICAgICAgICBIZWFkZXIuUHJvdmlkZXJUeXBlID0gKFByb3ZpZGVyVHlwZSlCaXRDb252ZXJ0ZXIuVG9JbnQzMihkYXRhLCAzMik7Ci0gICAgICAgICAgICBIZWFkZXIuUmVzZXJ2ZWQxID0gQml0Q29udmVydGVyLlRvSW50MzIoZGF0YSwgMzYpOwotICAgICAgICAgICAgSGVhZGVyLlJlc2VydmVkMiA9IEJpdENvbnZlcnRlci5Ub0ludDMyKGRhdGEsIDQwKTsKLQotICAgICAgICAgICAgYnl0ZVtdIHRleHQgPSBuZXcgYnl0ZVsoaW50KUhlYWRlclNpemUgLSAzNF07Ci0gICAgICAgICAgICBBcnJheS5Db3B5KGRhdGEsIDQ0LCB0ZXh0LCAwLCAoaW50KUhlYWRlclNpemUgLSAzNCk7Ci0gICAgICAgICAgICBIZWFkZXIuQ1NQTmFtZSA9IFVURjhFbmNvZGluZy5Vbmljb2RlLkdldFN0cmluZyh0ZXh0KTsKLQotICAgICAgICAgICAgaW50IHBvcyA9IChpbnQpSGVhZGVyU2l6ZSArIDEyOwotCi0gICAgICAgICAgICAvKioqKiBFbmNyeXB0aW9uVmVyaWZpZXIgKioqKi8KLSAgICAgICAgICAgIFZlcmlmaWVyID0gbmV3IEVuY3J5cHRpb25WZXJpZmllcigpOwotICAgICAgICAgICAgVmVyaWZpZXIuU2FsdFNpemUgPSAodWludClCaXRDb252ZXJ0ZXIuVG9JbnQzMihkYXRhLCBwb3MpOwotICAgICAgICAgICAgVmVyaWZpZXIuU2FsdCA9IG5ldyBieXRlW1ZlcmlmaWVyLlNhbHRTaXplXTsKLQotICAgICAgICAgICAgQXJyYXkuQ29weShkYXRhLCBwb3MgKyA0LCBWZXJpZmllci5TYWx0LCAwLCBWZXJpZmllci5TYWx0U2l6ZSk7Ci0KLSAgICAgICAgICAgIFZlcmlmaWVyLkVuY3J5cHRlZFZlcmlmaWVyID0gbmV3IGJ5dGVbMTZdOwotICAgICAgICAgICAgQXJyYXkuQ29weShkYXRhLCBwb3MgKyAyMCwgVmVyaWZpZXIuRW5jcnlwdGVkVmVyaWZpZXIsIDAsIDE2KTsKLQotICAgICAgICAgICAgVmVyaWZpZXIuVmVyaWZpZXJIYXNoU2l6ZSA9ICh1aW50KUJpdENvbnZlcnRlci5Ub0ludDMyKGRhdGEsIHBvcyArIDM2KTsKLSAgICAgICAgICAgIFZlcmlmaWVyLkVuY3J5cHRlZFZlcmlmaWVySGFzaCA9IG5ldyBieXRlW1ZlcmlmaWVyLlZlcmlmaWVySGFzaFNpemVdOwotICAgICAgICAgICAgQXJyYXkuQ29weShkYXRhLCBwb3MgKyA0MCwgVmVyaWZpZXIuRW5jcnlwdGVkVmVyaWZpZXJIYXNoLCAwLCBWZXJpZmllci5WZXJpZmllckhhc2hTaXplKTsKLSAgICAgICAgfQotICAgICAgICBpbnRlcm5hbCBieXRlW10gV3JpdGVCaW5hcnkoKQotICAgICAgICB7Ci0gICAgICAgICAgICBNZW1vcnlTdHJlYW0gbXMgPSBuZXcgTWVtb3J5U3RyZWFtKCk7Ci0gICAgICAgICAgICBCaW5hcnlXcml0ZXIgYncgPSBuZXcgQmluYXJ5V3JpdGVyKG1zKTsKLQotICAgICAgICAgICAgYncuV3JpdGUoTWFqb3JWZXJzaW9uKTsKLSAgICAgICAgICAgIGJ3LldyaXRlKE1pbm9yVmVyc2lvbik7Ci0gICAgICAgICAgICBidy5Xcml0ZSgoaW50KUZsYWdzKTsKLSAgICAgICAgICAgIGJ5dGVbXSBoZWFkZXIgPSBIZWFkZXIuV3JpdGVCaW5hcnkoKTsKLSAgICAgICAgICAgIGJ3LldyaXRlKCh1aW50KWhlYWRlci5MZW5ndGgpOwotICAgICAgICAgICAgYncuV3JpdGUoaGVhZGVyKTsKLSAgICAgICAgICAgIGJ3LldyaXRlKFZlcmlmaWVyLldyaXRlQmluYXJ5KCkpOwotCi0gICAgICAgICAgICBidy5GbHVzaCgpOwotICAgICAgICAgICAgcmV0dXJuIG1zLlRvQXJyYXkoKTsKLSAgICAgICAgfQotCi0gICAgfQotfQpkaWZmIC0tZ2l0IGEvRVBQbHVzL0VuY3J5cHRpb24vRW5jcnlwdGlvblZlcmlmaWVyLmNzIGIvRVBQbHVzL0VuY3J5cHRpb24vRW5jcnlwdGlvblZlcmlmaWVyLmNzCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBiZmQxMzUzLi4wMDAwMDAwCi0tLSBhL0VQUGx1cy9FbmNyeXB0aW9uL0VuY3J5cHRpb25WZXJpZmllci5jcworKysgL2Rldi9udWxsCkBAIC0xLDY0ICswLDAgQEAKLe+7vy8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCi0gKiBZb3UgbWF5IGFtZW5kIGFuZCBkaXN0cmlidXRlIGFzIHlvdSBsaWtlLCBidXQgZG9uJ3QgcmVtb3ZlIHRoaXMgaGVhZGVyIQotICoKLSAqIEVQUGx1cyBwcm92aWRlcyBzZXJ2ZXItc2lkZSBnZW5lcmF0aW9uIG9mIEV4Y2VsIDIwMDcvMjAxMCBzcHJlYWRzaGVldHMuCi0gKiBTZWUgaHR0cDovL3d3dy5jb2RlcGxleC5jb20vRVBQbHVzIGZvciBkZXRhaWxzLgotICoKLSAqIENvcHlyaWdodCAoQykgMjAxMSAgSmFuIEvDpGxsbWFuCi0gKgotICogVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgotICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwotICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCi0gKiB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KLQotICogVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCi0gKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgotICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgCi0gKiBTZWUgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgotICoKLSAqIFRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgY2FuIGJlIHZpZXdlZCBhdCBodHRwOi8vd3d3Lm9wZW5zb3VyY2Uub3JnL2xpY2Vuc2VzL2xncGwtbGljZW5zZS5waHAKLSAqIElmIHlvdSB1bmZhbWlsaWFyIHdpdGggdGhpcyBsaWNlbnNlIG9yIGhhdmUgcXVlc3Rpb25zIGFib3V0IGl0LCBoZXJlIGlzIGFuIGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9ncGwtZmFxLmh0bWwKLSAqCi0gKiBBbGwgY29kZSBhbmQgZXhlY3V0YWJsZXMgYXJlIHByb3ZpZGVkICJhcyBpcyIgd2l0aCBubyB3YXJyYW50eSBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAKLSAqIFRoZSBhdXRob3IgYWNjZXB0cyBubyBsaWFiaWxpdHkgZm9yIGFueSBkYW1hZ2Ugb3IgbG9zcyBvZiBidXNpbmVzcyB0aGF0IHRoaXMgcHJvZHVjdCBtYXkgY2F1c2UuCi0gKgotICogQ29kZSBjaGFuZ2Ugbm90ZXM6Ci0gKiAKLSAqIEF1dGhvcgkJCQkJCQlDaGFuZ2UJCQkJCQlEYXRlCi0gKiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKLSAqIEphbiBLw6RsbG1hbgkJICAgIEFkZGVkICAgICAgIAkJICAgICAgICAyMDEzLTAxLTA1Ci0gKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLXVzaW5nIFN5c3RlbTsKLXVzaW5nIFN5c3RlbS5Db2xsZWN0aW9ucy5HZW5lcmljOwotdXNpbmcgU3lzdGVtLklPOwotdXNpbmcgU3lzdGVtLkxpbnE7Ci11c2luZyBTeXN0ZW0uVGV4dDsKLQotbmFtZXNwYWNlIE9mZmljZU9wZW5YbWwuRW5jcnlwdGlvbgotewotICAgIC8vLyA8c3VtbWFyeT4KLSAgICAvLy8gRW5jcnlwdGlvbiB2ZXJpZmllciBpbnNpZGUgdGhlIEVuY3J5cHRpb25JbmZvIHN0cmVhbQotICAgIC8vLyA8L3N1bW1hcnk+Ci0gICAgaW50ZXJuYWwgY2xhc3MgRW5jcnlwdGlvblZlcmlmaWVyCi0gICAgewotICAgICAgICBpbnRlcm5hbCB1aW50IFNhbHRTaXplOyAgICAgICAgICAgICAgLy8gQW4gdW5zaWduZWQgaW50ZWdlciB0aGF0IHNwZWNpZmllcyB0aGUgc2l6ZSBvZiB0aGUgU2FsdCBmaWVsZC4gSXQgTVVTVCBiZSAweDAwMDAwMDEwLgotICAgICAgICBpbnRlcm5hbCBieXRlW10gU2FsdDsgICAgICAgICAgICAgICAgLy8oMTYgYnl0ZXMpOiBBbiBhcnJheSBvZiBieXRlcyB0aGF0IHNwZWNpZmllcyB0aGUgc2FsdCB2YWx1ZSB1c2VkIGR1cmluZyBwYXNzd29yZCBoYXNoIGdlbmVyYXRpb24uIEl0IE1VU1QgTk9UIGJlIHRoZSBzYW1lIGRhdGEgdXNlZCBmb3IgdGhlIHZlcmlmaWVyIHN0b3JlZCBlbmNyeXB0ZWQgaW4gdGhlIEVuY3J5cHRlZFZlcmlmaWVyIGZpZWxkLgotICAgICAgICBpbnRlcm5hbCBieXRlW10gRW5jcnlwdGVkVmVyaWZpZXI7ICAgLy8oMTYgYnl0ZXMpOiBNVVNUIGJlIHRoZSByYW5kb21seSBnZW5lcmF0ZWQgVmVyaWZpZXIgdmFsdWUgZW5jcnlwdGVkIHVzaW5nIHRoZSBhbGdvcml0aG0gY2hvc2VuIGJ5IHRoZSBpbXBsZW1lbnRhdGlvbi4KLSAgICAgICAgaW50ZXJuYWwgdWludCBWZXJpZmllckhhc2hTaXplOyAgICAgIC8vKDQgYnl0ZXMpOiBBbiB1bnNpZ25lZCBpbnRlZ2VyIHRoYXQgc3BlY2lmaWVzIHRoZSBudW1iZXIgb2YgYnl0ZXMgbmVlZGVkIHRvIGNvbnRhaW4gdGhlIGhhc2ggb2YgdGhlIGRhdGEgdXNlZCB0byBnZW5lcmF0ZSB0aGUgRW5jcnlwdGVkVmVyaWZpZXIgZmllbGQuCi0gICAgICAgIGludGVybmFsIGJ5dGVbXSBFbmNyeXB0ZWRWZXJpZmllckhhc2g7IC8vKHZhcmlhYmxlKTogQW4gYXJyYXkgb2YgYnl0ZXMgdGhhdCBjb250YWlucyB0aGUgZW5jcnlwdGVkIGZvcm0gb2YgdGhlIGhhc2ggb2YgdGhlIHJhbmRvbWx5IGdlbmVyYXRlZCBWZXJpZmllciB2YWx1ZS4gVGhlIGxlbmd0aCBvZiB0aGUgYXJyYXkgTVVTVCBiZSB0aGUgc2l6ZSBvZiB0aGUgZW5jcnlwdGlvbiBibG9jayBzaXplIG11bHRpcGxpZWQgYnkgdGhlIG51bWJlciBvZiBibG9ja3MgbmVlZGVkIHRvIGVuY3J5cHQgdGhlIGhhc2ggb2YgdGhlIFZlcmlmaWVyLiBJZiB0aGUgZW5jcnlwdGlvbiBhbGdvcml0aG0gaXMgUkM0LCB0aGUgbGVuZ3RoIE1VU1QgYmUgMjAgYnl0ZXMuIElmIHRoZSBlbmNyeXB0aW9uIGFsZ29yaXRobSBpcyBBRVMsIHRoZSBsZW5ndGggTVVTVCBiZSAzMiBieXRlcy4KLSAgICAgICAgaW50ZXJuYWwgYnl0ZVtdIFdyaXRlQmluYXJ5KCkKLSAgICAgICAgewotICAgICAgICAgICAgTWVtb3J5U3RyZWFtIG1zID0gbmV3IE1lbW9yeVN0cmVhbSgpOwotICAgICAgICAgICAgQmluYXJ5V3JpdGVyIGJ3ID0gbmV3IEJpbmFyeVdyaXRlcihtcyk7Ci0KLSAgICAgICAgICAgIGJ3LldyaXRlKFNhbHRTaXplKTsKLSAgICAgICAgICAgIGJ3LldyaXRlKFNhbHQpOwotICAgICAgICAgICAgYncuV3JpdGUoRW5jcnlwdGVkVmVyaWZpZXIpOwotICAgICAgICAgICAgYncuV3JpdGUoMHgxNCk7ICAgICAgICAgICAgICAgICAvL1NoYTEgaXMgMjAgYnl0ZXMgIChFbmNyeXB0ZWQgaXMgMzIpCi0gICAgICAgICAgICBidy5Xcml0ZShFbmNyeXB0ZWRWZXJpZmllckhhc2gpOwotCi0gICAgICAgICAgICBidy5GbHVzaCgpOwotICAgICAgICAgICAgcmV0dXJuIG1zLlRvQXJyYXkoKTsKLSAgICAgICAgfQotICAgIH0KLX0KZGlmZiAtLWdpdCBhL0VQUGx1cy9FeGNlbENvbW1lbnRDb2xsZWN0aW9uLmNzIGIvRVBQbHVzL0V4Y2VsQ29tbWVudENvbGxlY3Rpb24uY3MKaW5kZXggNjU5NzY1My4uY2YwYTU0MCAxMDA2NDQKLS0tIGEvRVBQbHVzL0V4Y2VsQ29tbWVudENvbGxlY3Rpb24uY3MKKysrIGIvRVBQbHVzL0V4Y2VsQ29tbWVudENvbGxlY3Rpb24uY3MKQEAgLTIwNiwxMSArMjA2LDggQEAKICAgICAgICAgICAgIH0KICAgICAgICAgfQogCi0gICAgICAgIHZvaWQgSURpc3Bvc2FibGUuRGlzcG9zZSgpIAotICAgICAgICB7IAotICAgICAgICAgICAgaWYgKF9jb21tZW50cyAhPSBudWxsKSAKLSAgICAgICAgICAgICAgICAoKElEaXNwb3NhYmxlKV9jb21tZW50cykuRGlzcG9zZSgpOyAKLSAgICAgICAgfSAKKyAgICAgICAgdm9pZCBJRGlzcG9zYWJsZS5EaXNwb3NlKCkgeyB9IAorICAgICAgICAKICAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgICAvLy8gUmVtb3ZlcyB0aGUgY29tbWVudCBhdCB0aGUgc3BlY2lmaWVkIHBvc2l0aW9uCiAgICAgICAgIC8vLyA8L3N1bW1hcnk+CmRpZmYgLS1naXQgYS9FUFBsdXMvRXhjZWxFbmNyeXB0aW9uLmNzIGIvRVBQbHVzL0V4Y2VsRW5jcnlwdGlvbi5jcwpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNmJkZGI1MS4uMDAwMDAwMAotLS0gYS9FUFBsdXMvRXhjZWxFbmNyeXB0aW9uLmNzCisrKyAvZGV2L251bGwKQEAgLTEsMTc1ICswLDAgQEAKLe+7vy8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCi0gKiBZb3UgbWF5IGFtZW5kIGFuZCBkaXN0cmlidXRlIGFzIHlvdSBsaWtlLCBidXQgZG9uJ3QgcmVtb3ZlIHRoaXMgaGVhZGVyIQotICoKLSAqIEVQUGx1cyBwcm92aWRlcyBzZXJ2ZXItc2lkZSBnZW5lcmF0aW9uIG9mIEV4Y2VsIDIwMDcvMjAxMCBzcHJlYWRzaGVldHMuCi0gKiBTZWUgaHR0cDovL3d3dy5jb2RlcGxleC5jb20vRVBQbHVzIGZvciBkZXRhaWxzLgotICoKLSAqIENvcHlyaWdodCAoQykgMjAxMSAgSmFuIEvDpGxsbWFuCi0gKgotICogVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgotICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwotICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCi0gKiB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KLQotICogVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCi0gKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgotICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgCi0gKiBTZWUgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgotICoKLSAqIFRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgY2FuIGJlIHZpZXdlZCBhdCBodHRwOi8vd3d3Lm9wZW5zb3VyY2Uub3JnL2xpY2Vuc2VzL2xncGwtbGljZW5zZS5waHAKLSAqIElmIHlvdSB1bmZhbWlsaWFyIHdpdGggdGhpcyBsaWNlbnNlIG9yIGhhdmUgcXVlc3Rpb25zIGFib3V0IGl0LCBoZXJlIGlzIGFuIGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9ncGwtZmFxLmh0bWwKLSAqCi0gKiBBbGwgY29kZSBhbmQgZXhlY3V0YWJsZXMgYXJlIHByb3ZpZGVkICJhcyBpcyIgd2l0aCBubyB3YXJyYW50eSBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAKLSAqIFRoZSBhdXRob3IgYWNjZXB0cyBubyBsaWFiaWxpdHkgZm9yIGFueSBkYW1hZ2Ugb3IgbG9zcyBvZiBidXNpbmVzcyB0aGF0IHRoaXMgcHJvZHVjdCBtYXkgY2F1c2UuCi0gKgotICogQ29kZSBjaGFuZ2Ugbm90ZXM6Ci0gKiAKLSAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKLSAqIFRoaXMgY2xhc3MgaXMgY3JlYXRlZCB3aXRoIHRoZSBoZWxwIG9mIHRoZSBNUy1PRkZDUllQVE8gUERGIGRvY3VtZW50YXRpb24uLi4gaHR0cDovL21zZG4ubWljcm9zb2Z0LmNvbS9lbi11cy9saWJyYXJ5L2NjMzEzMDcxKG9mZmljZS4xMikuYXNweAotICogRGVjcnlweXRpb24gbGlicmFyeSBmb3IgT2ZmaWNlIE9wZW4gWE1MIGZpbGVzKEx5cXVpZGl0eSkgYW5kIFNtaW5rcyB2ZXJ5IG5pY2UgZXhhbXBsZSAKLSAqIG9uICJSZWFkaW5nIGNvbXBvdW5kIGRvY3VtZW50cyBpbiBjIyIgb24gU3RhY2tvdmVyZmxvdy4gTWFueSB0aGFua3MhCi0gKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCi0gKiAgCi0gKiBDb2RlIGNoYW5nZSBub3RlczoKLSAqIAotICogQXV0aG9yCQkJCQkJCUNoYW5nZQkJCQkJCURhdGUKLSAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCi0gKiBKYW4gS8OkbGxtYW4JCUFkZGVkCQkxMC1BVUctMjAxMAotICogSmFuIEvDpGxsbWFuCQlMaWNlbnNlIGNoYW5nZWQgR1BMLS0+TEdQTCAyMDExLTEyLTI3Ci0gKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLXVzaW5nIFN5c3RlbTsKLXVzaW5nIFN5c3RlbS5Db2xsZWN0aW9ucy5HZW5lcmljOwotdXNpbmcgU3lzdGVtLlRleHQ7Ci0KLW5hbWVzcGFjZSBPZmZpY2VPcGVuWG1sCi17Ci0gICAgLy8vIDxzdW1tYXJ5PgotICAgIC8vLyBFbmNyeXB0aW9uIEFsZ29yaXRobQotICAgIC8vLyA8L3N1bW1hcnk+Ci0gICAgcHVibGljIGVudW0gRW5jcnlwdGlvbkFsZ29yaXRobQotICAgIHsKLSAgICAgICAgLy8vIDxzdW1tYXJ5PgotICAgICAgICAvLy8gMTI4LWJpdCBBRVMuIERlZmF1bHQKLSAgICAgICAgLy8vIDwvc3VtbWFyeT4KLSAgICAgICAgQUVTMTI4LAotICAgICAgICAvLy8gPHN1bW1hcnk+Ci0gICAgICAgIC8vLyAxOTItYml0IEFFUy4KLSAgICAgICAgLy8vIDwvc3VtbWFyeT4KLSAgICAgICAgQUVTMTkyLAotICAgICAgICAvLy8gPHN1bW1hcnk+Ci0gICAgICAgIC8vLyAyNTYtYml0IEFFUy4gCi0gICAgICAgIC8vLyA8L3N1bW1hcnk+Ci0gICAgICAgIEFFUzI1NgotICAgIH0KLSAgICAvLy8gPHN1bW1hcnk+Ci0gICAgLy8vIFRoZSBtYWpvciB2ZXJzaW9uIG9mIHRoZSBFbmNyeXB0aW9uIAotICAgIC8vLyA8L3N1bW1hcnk+Ci0gICAgcHVibGljIGVudW0gRW5jcnlwdGlvblZlcnNpb24KLSAgICB7Ci0gICAgICAgIC8vLyA8c3VtbWFyeT4KLSAgICAgICAgLy8vIFN0YW5kYXJkIEVuY3J5cHRpb24uCi0gICAgICAgIC8vLyBVc2VkIGluIEV4Y2VsIDIwMDcgYW5kIHByZXZpb3VzIHZlcnNpb24gd2l0aCBjb21wYXRpYmlsaXR5IHBhY2suCi0gICAgICAgIC8vLyA8cmVtYXJrcz5EZWZhdWx0IEFFUyAxMjggd2l0aCBTSEEtMSBhcyB0aGUgaGFzaCBhbGdvcml0aG0uIFNwaW5jb3VudCBpcyBoYXJkY29kZWQgdG8gNTAwMDA8L3JlbWFya3M+Ci0gICAgICAgIC8vLyA8L3N1bW1hcnk+Ci0gICAgICAgIFN0YW5kYXJkLAotICAgICAgICAvLy8gPHN1bW1hcnk+Ci0gICAgICAgIC8vLyBBZ2lsZSBFbmNyeXB0aW9uLgotICAgICAgICAvLy8gVXNlZCBpbiBFeGNlbCAyMDEwLQotICAgICAgICAvLy8gRGVmYXVsdC4KLSAgICAgICAgLy8vIDwvc3VtbWFyeT4KLSAgICAgICAgQWdpbGUKLSAgICB9Ci0gICAgLy8vIDxzdW1tYXJ5PgotICAgIC8vLyBIb3cgYW5kIGlmIHRoZSB3b3JrYm9vayBpcyBlbmNyeXB0ZWQKLSAgICAvLy88c2VlYWxzbyBjcmVmPSJFeGNlbFByb3RlY3Rpb24iLz4gCi0gICAgLy8vPHNlZWFsc28gY3JlZj0iRXhjZWxTaGVldFByb3RlY3Rpb24iLz4gCi0gICAgLy8vIDwvc3VtbWFyeT4KLSAgICBwdWJsaWMgY2xhc3MgRXhjZWxFbmNyeXB0aW9uCi0gICAgewotICAgICAgICAvLy8gPHN1bW1hcnk+Ci0gICAgICAgIC8vLyBDb25zdHJ1Y3RvcgotICAgICAgICAvLy8gPHJlbWFya3M+RGVmYXVsdCBBRVMgMjU2IHdpdGggU0hBLTUxMiBhcyB0aGUgaGFzaCBhbGdvcml0aG0uIFNwaW5jb3VudCBpcyBzZXQgdG8gMTAwMDAwPC9yZW1hcmtzPgotICAgICAgICAvLy8gPC9zdW1tYXJ5PgotICAgICAgICBpbnRlcm5hbCBFeGNlbEVuY3J5cHRpb24oKQotICAgICAgICB7Ci0gICAgICAgICAgICBBbGdvcml0aG0gPSBFbmNyeXB0aW9uQWxnb3JpdGhtLkFFUzI1NjsKLSAgICAgICAgfQotICAgICAgICAvLy8gPHN1bW1hcnk+Ci0gICAgICAgIC8vLyBDb25zdHJ1Y3RvcgotICAgICAgICAvLy8gPC9zdW1tYXJ5PgotICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImVuY3J5cHRpb25BbGdvcml0aG0iPkFsZ29yaXRobSB1c2VkIHRvIGVuY3J5cHQgdGhlIHBhY2thZ2UuIERlZmF1bHQgaXMgQUVTMTI4PC9wYXJhbT4KLSAgICAgICAgaW50ZXJuYWwgRXhjZWxFbmNyeXB0aW9uKEVuY3J5cHRpb25BbGdvcml0aG0gZW5jcnlwdGlvbkFsZ29yaXRobSkKLSAgICAgICAgewotICAgICAgICAgICAgQWxnb3JpdGhtID0gZW5jcnlwdGlvbkFsZ29yaXRobTsKLSAgICAgICAgfSAgICAgICAgCi0gICAgICAgIGJvb2wgX2lzRW5jcnlwdGVkID0gZmFsc2U7Ci0gICAgICAgIC8vLyA8c3VtbWFyeT4KLSAgICAgICAgLy8vIElzIHRoZSBwYWNrYWdlIGVuY3J5cHRlZAotICAgICAgICAvLy8gPC9zdW1tYXJ5PgotICAgICAgICBwdWJsaWMgYm9vbCBJc0VuY3J5cHRlZCAKLSAgICAgICAgewotICAgICAgICAgICAgZ2V0Ci0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIF9pc0VuY3J5cHRlZDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHNldAotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIF9pc0VuY3J5cHRlZCA9IHZhbHVlOwotICAgICAgICAgICAgICAgIGlmIChfaXNFbmNyeXB0ZWQpCi0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICBpZiAoX3Bhc3N3b3JkID09IG51bGwpIF9wYXNzd29yZCA9ICIiOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICBfcGFzc3dvcmQgPSBudWxsOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBzdHJpbmcgX3Bhc3N3b3JkPW51bGw7Ci0gICAgICAgIC8vLyA8c3VtbWFyeT4KLSAgICAgICAgLy8vIFRoZSBwYXNzd29yZCB1c2VkIHRvIGVuY3J5cHQgdGhlIHdvcmtib29rLgotICAgICAgICAvLy8gPC9zdW1tYXJ5PgotICAgICAgICBwdWJsaWMgc3RyaW5nIFBhc3N3b3JkIAotICAgICAgICB7Ci0gICAgICAgICAgICBnZXQKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gX3Bhc3N3b3JkOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgc2V0Ci0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgX3Bhc3N3b3JkID0gdmFsdWU7Ci0gICAgICAgICAgICAgICAgX2lzRW5jcnlwdGVkID0gKHZhbHVlICE9IG51bGwpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIC8vLyA8c3VtbWFyeT4KLSAgICAgICAgLy8vIEFsZ29yaXRobSB1c2VkIGZvciBlbmNyeXB0aW5nIHRoZSBwYWNrYWdlLiBEZWZhdWx0IGlzIEFFUyAxMjgtYml0IGZvciBzdGFuZGFyZCBhbmQgQUVTIDI1NiBmb3IgYWdpbGUKLSAgICAgICAgLy8vIDwvc3VtbWFyeT4KLSAgICAgICAgcHVibGljIEVuY3J5cHRpb25BbGdvcml0aG0gQWxnb3JpdGhtIHsgZ2V0OyBzZXQ7IH0KLSAgICAgICAgcHJpdmF0ZSBFbmNyeXB0aW9uVmVyc2lvbiBfdmVyc2lvbiA9IEVuY3J5cHRpb25WZXJzaW9uLkFnaWxlOwotICAgICAgICAvLy8gPHN1bW1hcnk+Ci0gICAgICAgIC8vLyBUaGUgdmVyc2lvbiBvZiB0aGUgZW5jcnlwdGlvbi4gICAgICAgIAotICAgICAgICAvLy8gPC9zdW1tYXJ5PgotICAgICAgICBwdWJsaWMgRW5jcnlwdGlvblZlcnNpb24gVmVyc2lvbgotICAgICAgICB7Ci0gICAgICAgICAgICBnZXQKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gX3ZlcnNpb247Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBzZXQKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBpZiAodmFsdWUgIT0gVmVyc2lvbikKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgIGlmICh2YWx1ZSA9PSBFbmNyeXB0aW9uVmVyc2lvbi5BZ2lsZSkKLSAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgQWxnb3JpdGhtID0gRW5jcnlwdGlvbkFsZ29yaXRobS5BRVMyNTY7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBBbGdvcml0aG0gPSBFbmNyeXB0aW9uQWxnb3JpdGhtLkFFUzEyODsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBfdmVyc2lvbiA9IHZhbHVlOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgIH0KLX0KZGlmZiAtLWdpdCBhL0VQUGx1cy9FeGNlbFBhY2thZ2UuY3MgYi9FUFBsdXMvRXhjZWxQYWNrYWdlLmNzCmluZGV4IGJiMmI5ODMuLjc4YzQwODMgMTAwNjQ0Ci0tLSBhL0VQUGx1cy9FeGNlbFBhY2thZ2UuY3MKKysrIGIvRVBQbHVzL0V4Y2VsUGFja2FnZS5jcwpAQCAtMzgsNyArMzgsNiBAQAogdXNpbmcgU3lzdGVtLkNvbGxlY3Rpb25zLkdlbmVyaWM7CiB1c2luZyBTeXN0ZW0uU2VjdXJpdHkuQ3J5cHRvZ3JhcGh5OwogdXNpbmcgT2ZmaWNlT3BlblhtbC5VdGlsczsKLXVzaW5nIE9mZmljZU9wZW5YbWwuRW5jcnlwdGlvbjsKIG5hbWVzcGFjZSBPZmZpY2VPcGVuWG1sCiB7CiAgICAgLy8vIDxzdW1tYXJ5PgpAQCAtMTU5LDE5ICsxNTgsMTAgQEAKICAgICAvLy8gPC9jb2RlPgogICAgIC8vLyBNb3JlIHNhbXBsZXMgY2FuIGJlIGZvdW5kIGF0ICA8YSBocmVmPSJodHRwOi8vZXBwbHVzLmNvZGVwbGV4LmNvbS8iPmh0dHA6Ly9lcHBsdXMuY29kZXBsZXguY29tLzwvYT4KICAgICAvLy8gPC9zdW1tYXJ5PgotCXB1YmxpYyBzZWFsZWQgY2xhc3MgRXhjZWxQYWNrYWdlIDogSURpc3Bvc2FibGUKKwlwdWJsaWMgc2VhbGVkIGNsYXNzIEV4Y2VsUGFja2FnZQogCXsKICAgICAgICAgaW50ZXJuYWwgY29uc3QgYm9vbCBwcmVzZXJ2ZVdoaXRlc3BhY2U9ZmFsc2U7Ci0gICAgICAgIFN0cmVhbSBfc3RyZWFtID0gbnVsbDsKLSAgICAgICAgcHJpdmF0ZSBib29sIF9pc0V4dGVybmFsU3RyZWFtPWZhbHNlOwotICAgICAgICBpbnRlcm5hbCBjbGFzcyBJbWFnZUluZm8KLSAgICAgICAgewotICAgICAgICAgICAgaW50ZXJuYWwgc3RyaW5nIEhhc2ggeyBnZXQ7IHNldDsgfQotICAgICAgICAgICAgaW50ZXJuYWwgVXJpIFVyaXtnZXQ7c2V0O30KLSAgICAgICAgICAgIGludGVybmFsIGludCBSZWZDb3VudCB7IGdldDsgc2V0OyB9Ci0gICAgICAgICAgICBpbnRlcm5hbCBQYWNrYWdpbmcuWmlwUGFja2FnZVBhcnQgUGFydCB7IGdldDsgc2V0OyB9Ci0gICAgICAgIH0KLSAgICAgICAgaW50ZXJuYWwgRGljdGlvbmFyeTxzdHJpbmcsIEltYWdlSW5mbz4gX2ltYWdlcyA9IG5ldyBEaWN0aW9uYXJ5PHN0cmluZywgSW1hZ2VJbmZvPigpOworICAgICAgICAKIAkJI3JlZ2lvbiBQcm9wZXJ0aWVzCiAJCS8vLyA8c3VtbWFyeT4KIAkJLy8vIEV4dGVudGlvbiBTY2hlbWEgdHlwZXMKQEAgLTE4OCw4ICsxNzgsNiBAQAogCQlpbnRlcm5hbCBjb25zdCBzdHJpbmcgc2NoZW1hUmVsYXRpb25zaGlwcyA9IEAiaHR0cDovL3NjaGVtYXMub3BlbnhtbGZvcm1hdHMub3JnL29mZmljZURvY3VtZW50LzIwMDYvcmVsYXRpb25zaGlwcyI7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgaW50ZXJuYWwgY29uc3Qgc3RyaW5nIHNjaGVtYURyYXdpbmdzID0gQCJodHRwOi8vc2NoZW1hcy5vcGVueG1sZm9ybWF0cy5vcmcvZHJhd2luZ21sLzIwMDYvbWFpbiI7Ci0gICAgICAgIGludGVybmFsIGNvbnN0IHN0cmluZyBzY2hlbWFTaGVldERyYXdpbmdzID0gQCJodHRwOi8vc2NoZW1hcy5vcGVueG1sZm9ybWF0cy5vcmcvZHJhd2luZ21sLzIwMDYvc3ByZWFkc2hlZXREcmF3aW5nIjsKLSAgICAgICAgaW50ZXJuYWwgY29uc3Qgc3RyaW5nIHNjaGVtYU1hcmt1cENvbXBhdGliaWxpdHkgPSBAImh0dHA6Ly9zY2hlbWFzLm9wZW54bWxmb3JtYXRzLm9yZy9tYXJrdXAtY29tcGF0aWJpbGl0eS8yMDA2IjsKIAogICAgICAgICBpbnRlcm5hbCBjb25zdCBzdHJpbmcgc2NoZW1hTWljcm9zb2Z0Vm1sID0gQCJ1cm46c2NoZW1hcy1taWNyb3NvZnQtY29tOnZtbCI7CiAgICAgICAgIGludGVybmFsIGNvbnN0IHN0cmluZyBzY2hlbWFNaWNyb3NvZnRPZmZpY2UgPSAidXJuOnNjaGVtYXMtbWljcm9zb2Z0LWNvbTpvZmZpY2U6b2ZmaWNlIjsKQEAgLTE5OCw3ICsxODYsNiBAQAogICAgICAgICBpbnRlcm5hbCBjb25zdCBzdHJpbmcgc2NoZW1hQ2hhcnQgPSBAImh0dHA6Ly9zY2hlbWFzLm9wZW54bWxmb3JtYXRzLm9yZy9kcmF3aW5nbWwvMjAwNi9jaGFydCI7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgaW50ZXJuYWwgY29uc3Qgc3RyaW5nIHNjaGVtYUh5cGVybGluayA9IEAiaHR0cDovL3NjaGVtYXMub3BlbnhtbGZvcm1hdHMub3JnL29mZmljZURvY3VtZW50LzIwMDYvcmVsYXRpb25zaGlwcy9oeXBlcmxpbmsiOwogICAgICAgICBpbnRlcm5hbCBjb25zdCBzdHJpbmcgc2NoZW1hQ29tbWVudCA9IEAiaHR0cDovL3NjaGVtYXMub3BlbnhtbGZvcm1hdHMub3JnL29mZmljZURvY3VtZW50LzIwMDYvcmVsYXRpb25zaGlwcy9jb21tZW50cyI7Ci0gICAgICAgIGludGVybmFsIGNvbnN0IHN0cmluZyBzY2hlbWFJbWFnZSA9IEAiaHR0cDovL3NjaGVtYXMub3BlbnhtbGZvcm1hdHMub3JnL29mZmljZURvY3VtZW50LzIwMDYvcmVsYXRpb25zaGlwcy9pbWFnZSI7CiAgICAgICAgIC8vT2ZmaWNlIHByb3BlcnRpZXMKICAgICAgICAgaW50ZXJuYWwgY29uc3Qgc3RyaW5nIHNjaGVtYUNvcmUgPSBAImh0dHA6Ly9zY2hlbWFzLm9wZW54bWxmb3JtYXRzLm9yZy9wYWNrYWdlLzIwMDYvbWV0YWRhdGEvY29yZS1wcm9wZXJ0aWVzIjsKICAgICAgICAgaW50ZXJuYWwgY29uc3Qgc3RyaW5nIHNjaGVtYUV4dGVuZGVkID0gQCJodHRwOi8vc2NoZW1hcy5vcGVueG1sZm9ybWF0cy5vcmcvb2ZmaWNlRG9jdW1lbnQvMjAwNi9leHRlbmRlZC1wcm9wZXJ0aWVzIjsKQEAgLTIxNCwxNiArMjAxLDkgQEAKICAgICAgICAgaW50ZXJuYWwgY29uc3Qgc3RyaW5nIHNjaGVtYVBpdm90Q2FjaGVEZWZpbml0aW9uID0gQCJhcHBsaWNhdGlvbi92bmQub3BlbnhtbGZvcm1hdHMtb2ZmaWNlZG9jdW1lbnQuc3ByZWFkc2hlZXRtbC5waXZvdENhY2hlRGVmaW5pdGlvbit4bWwiOwogICAgICAgICBpbnRlcm5hbCBjb25zdCBzdHJpbmcgc2NoZW1hUGl2b3RDYWNoZVJlY29yZHMgPSBAImFwcGxpY2F0aW9uL3ZuZC5vcGVueG1sZm9ybWF0cy1vZmZpY2Vkb2N1bWVudC5zcHJlYWRzaGVldG1sLnBpdm90Q2FjaGVSZWNvcmRzK3htbCI7CiAKLSAgICAgICAgLy9WQkEKLSAgICAgICAgaW50ZXJuYWwgY29uc3Qgc3RyaW5nIHNjaGVtYVZCQSA9IEAiYXBwbGljYXRpb24vdm5kLm1zLW9mZmljZS52YmFQcm9qZWN0IjsKLSAgICAgICAgaW50ZXJuYWwgY29uc3Qgc3RyaW5nIHNjaGVtYVZCQVNpZ25hdHVyZSA9IEAiYXBwbGljYXRpb24vdm5kLm1zLW9mZmljZS52YmFQcm9qZWN0U2lnbmF0dXJlIjsKLQogICAgICAgICBpbnRlcm5hbCBjb25zdCBzdHJpbmcgY29udGVudFR5cGVXb3JrYm9va0RlZmF1bHQgPSBAImFwcGxpY2F0aW9uL3ZuZC5vcGVueG1sZm9ybWF0cy1vZmZpY2Vkb2N1bWVudC5zcHJlYWRzaGVldG1sLnNoZWV0Lm1haW4reG1sIjsKICAgICAgICAgaW50ZXJuYWwgY29uc3Qgc3RyaW5nIGNvbnRlbnRUeXBlV29ya2Jvb2tNYWNyb0VuYWJsZWQgPSAiYXBwbGljYXRpb24vdm5kLm1zLWV4Y2VsLnNoZWV0Lm1hY3JvRW5hYmxlZC5tYWluK3htbCI7CiAgICAgICAgIGludGVybmFsIGNvbnN0IHN0cmluZyBjb250ZW50VHlwZVNoYXJlZFN0cmluZyA9IEAiYXBwbGljYXRpb24vdm5kLm9wZW54bWxmb3JtYXRzLW9mZmljZWRvY3VtZW50LnNwcmVhZHNoZWV0bWwuc2hhcmVkU3RyaW5ncyt4bWwiOwotICAgICAgICAvL1BhY2thZ2UgcmVmZXJlbmNlCi0gICAgICAgIHByaXZhdGUgUGFja2FnaW5nLlppcFBhY2thZ2UgX3BhY2thZ2U7Ci0JCWludGVybmFsIEV4Y2VsV29ya2Jvb2sgX3dvcmtib29rOwogICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgIC8vLyBNYXhpbXVtIG51bWJlciBvZiBjb2x1bW5zIGluIGEgd29ya3NoZWV0ICgxNjM4NCkuIAogICAgICAgICAvLy8gPC9zdW1tYXJ5PgpAQCAtMjQwLDQwNCArMjIwLDU2IEBACiAgICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgIHB1YmxpYyBFeGNlbFBhY2thZ2UoKQogICAgICAgICB7Ci0gICAgICAgICAgICBDb25zdHJ1Y3ROZXdGaWxlKG51bGwpOworICAgICAgICAgICAgUGFja2FnZSA9IG5ldygpOyAKKyAgICAgICAgICAgIFdvcmtib29rID0gQ3JlYXRlV29ya2Jvb2soKTsKKyAgICAgICAgICAgIF8gPSBXb3JrYm9vay5Xb3JrYm9va1htbDsKKyAgICAgICAgICAgIC8vIGNyZWF0ZSB0aGUgcmVsYXRpb25zaGlwIHRvIHRoZSBtYWluIHBhcnQKKyAgICAgICAgICAgIFBhY2thZ2UuQ3JlYXRlUmVsYXRpb25zaGlwKFVyaUhlbHBlci5HZXRSZWxhdGl2ZVVyaShuZXcgVXJpKCIveGwiLCBVcmlLaW5kLlJlbGF0aXZlKSwgV29ya2Jvb2suV29ya2Jvb2tVcmkpLCBQYWNrYWdpbmcuVGFyZ2V0TW9kZS5JbnRlcm5hbCwgc2NoZW1hUmVsYXRpb25zaGlwcyArICIvb2ZmaWNlRG9jdW1lbnQiKTsKICAgICAgICAgfQorICAgICAgICAKICAgICAgICAgLy8vIDxzdW1tYXJ5PgogCQkvLy8gQ3JlYXRlIGEgbmV3IGluc3RhbmNlIG9mIHRoZSBFeGNlbFBhY2thZ2UgY2xhc3MgYmFzZWQgb24gYSBleGlzdGluZyBmaWxlIG9yIGNyZWF0ZXMgYSBuZXcgZmlsZS4gCiAJCS8vLyA8L3N1bW1hcnk+CiAJCS8vLyA8cGFyYW0gbmFtZT0ibmV3RmlsZSI+SWYgbmV3RmlsZSBleGlzdHMsIGl0IGlzIG9wZW5lZC4gIE90aGVyd2lzZSBpdCBpcyBjcmVhdGVkIGZyb20gc2NyYXRjaC48L3BhcmFtPgogICAgICAgICBwdWJsaWMgRXhjZWxQYWNrYWdlKEZpbGVJbmZvIG5ld0ZpbGUpCi0JCXsKLSAgICAgICAgICAgIEZpbGUgPSBuZXdGaWxlOwotICAgICAgICAgICAgQ29uc3RydWN0TmV3RmlsZShudWxsKTsKLSAgICAgICAgfQotICAgICAgICAvLy8gPHN1bW1hcnk+Ci0gICAgICAgIC8vLyBDcmVhdGUgYSBuZXcgaW5zdGFuY2Ugb2YgdGhlIEV4Y2VsUGFja2FnZSBjbGFzcyBiYXNlZCBvbiBhIGV4aXN0aW5nIGZpbGUgb3IgY3JlYXRlcyBhIG5ldyBmaWxlLiAKLSAgICAgICAgLy8vIDwvc3VtbWFyeT4KLSAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJuZXdGaWxlIj5JZiBuZXdGaWxlIGV4aXN0cywgaXQgaXMgb3BlbmVkLiAgT3RoZXJ3aXNlIGl0IGlzIGNyZWF0ZWQgZnJvbSBzY3JhdGNoLjwvcGFyYW0+Ci0gICAgICAgIC8vLyA8cGFyYW0gbmFtZT0icGFzc3dvcmQiPlBhc3N3b3JkIGZvciBhbiBlbmNyeXB0ZWQgcGFja2FnZTwvcGFyYW0+Ci0gICAgICAgIHB1YmxpYyBFeGNlbFBhY2thZ2UoRmlsZUluZm8gbmV3RmlsZSwgc3RyaW5nIHBhc3N3b3JkKQogICAgICAgICB7Ci0gICAgICAgICAgICBGaWxlID0gbmV3RmlsZTsKLSAgICAgICAgICAgIENvbnN0cnVjdE5ld0ZpbGUocGFzc3dvcmQpOworICAgICAgICAgICAgdXNpbmcgdmFyIGlucHV0U3RyZWFtID0gbmV3RmlsZS5PcGVuUmVhZCgpOworICAgICAgICAgICAgUGFja2FnZSA9IG5ldyhpbnB1dFN0cmVhbSk7CisgICAgICAgICAgICBXb3JrYm9vayA9IENyZWF0ZVdvcmtib29rKCk7CiAgICAgICAgIH0KLQkJLy8vIDxzdW1tYXJ5PgotCQkvLy8gQ3JlYXRlIGEgbmV3IGluc3RhbmNlIG9mIHRoZSBFeGNlbFBhY2thZ2UgY2xhc3MgYmFzZWQgb24gYSBleGlzdGluZyB0ZW1wbGF0ZS4KLQkJLy8vIElmIG5ld0ZpbGUgZXhpc3RzLCBpdCB3aWxsIGJlIG92ZXJ3cml0dGVuIHdoZW4gdGhlIFNhdmUgbWV0aG9kIGlzIGNhbGxlZAotCQkvLy8gPC9zdW1tYXJ5PgotCQkvLy8gPHBhcmFtIG5hbWU9Im5ld0ZpbGUiPlRoZSBuYW1lIG9mIHRoZSBFeGNlbCBmaWxlIHRvIGJlIGNyZWF0ZWQ8L3BhcmFtPgotCQkvLy8gPHBhcmFtIG5hbWU9InRlbXBsYXRlIj5UaGUgbmFtZSBvZiB0aGUgRXhjZWwgdGVtcGxhdGUgdG8gdXNlIGFzIHRoZSBiYXNpcyBvZiB0aGUgbmV3IEV4Y2VsIGZpbGU8L3BhcmFtPgotCQlwdWJsaWMgRXhjZWxQYWNrYWdlKEZpbGVJbmZvIG5ld0ZpbGUsIEZpbGVJbmZvIHRlbXBsYXRlKQotCQl7Ci0gICAgICAgICAgICBGaWxlID0gbmV3RmlsZTsKLSAgICAgICAgICAgIENyZWF0ZUZyb21UZW1wbGF0ZSh0ZW1wbGF0ZSwgbnVsbCk7Ci0JCX0KLSAgICAgICAgLy8vIDxzdW1tYXJ5PgotICAgICAgICAvLy8gQ3JlYXRlIGEgbmV3IGluc3RhbmNlIG9mIHRoZSBFeGNlbFBhY2thZ2UgY2xhc3MgYmFzZWQgb24gYSBleGlzdGluZyB0ZW1wbGF0ZS4KLSAgICAgICAgLy8vIElmIG5ld0ZpbGUgZXhpc3RzLCBpdCB3aWxsIGJlIG92ZXJ3cml0dGVuIHdoZW4gdGhlIFNhdmUgbWV0aG9kIGlzIGNhbGxlZAotICAgICAgICAvLy8gPC9zdW1tYXJ5PgotICAgICAgICAvLy8gPHBhcmFtIG5hbWU9Im5ld0ZpbGUiPlRoZSBuYW1lIG9mIHRoZSBFeGNlbCBmaWxlIHRvIGJlIGNyZWF0ZWQ8L3BhcmFtPgotICAgICAgICAvLy8gPHBhcmFtIG5hbWU9InRlbXBsYXRlIj5UaGUgbmFtZSBvZiB0aGUgRXhjZWwgdGVtcGxhdGUgdG8gdXNlIGFzIHRoZSBiYXNpcyBvZiB0aGUgbmV3IEV4Y2VsIGZpbGU8L3BhcmFtPgotICAgICAgICAvLy8gPHBhcmFtIG5hbWU9InBhc3N3b3JkIj5QYXNzd29yZCB0byBkZWNyeXB0ZWQgdGhlIHRlbXBsYXRlPC9wYXJhbT4KLSAgICAgICAgcHVibGljIEV4Y2VsUGFja2FnZShGaWxlSW5mbyBuZXdGaWxlLCBGaWxlSW5mbyB0ZW1wbGF0ZSwgc3RyaW5nIHBhc3N3b3JkKQotICAgICAgICB7Ci0gICAgICAgICAgICBGaWxlID0gbmV3RmlsZTsKLSAgICAgICAgICAgIENyZWF0ZUZyb21UZW1wbGF0ZSh0ZW1wbGF0ZSwgcGFzc3dvcmQpOwotICAgICAgICB9Ci0gICAgICAgIC8vLyA8c3VtbWFyeT4KLSAgICAgICAgLy8vIENyZWF0ZSBhIG5ldyBpbnN0YW5jZSBvZiB0aGUgRXhjZWxQYWNrYWdlIGNsYXNzIGJhc2VkIG9uIGEgZXhpc3RpbmcgdGVtcGxhdGUuCi0gICAgICAgIC8vLyA8L3N1bW1hcnk+Ci0gICAgICAgIC8vLyA8cGFyYW0gbmFtZT0idGVtcGxhdGUiPlRoZSBuYW1lIG9mIHRoZSBFeGNlbCB0ZW1wbGF0ZSB0byB1c2UgYXMgdGhlIGJhc2lzIG9mIHRoZSBuZXcgRXhjZWwgZmlsZTwvcGFyYW0+Ci0gICAgICAgIC8vLyA8cGFyYW0gbmFtZT0idXNlU3RyZWFtIj5pZiB0cnVlIHVzZSBhIHN0cmVhbS4gSWYgZmFsc2UgY3JlYXRlIGEgZmlsZSBpbiB0aGUgdGVtcCBkaXIgd2l0aCBhIHJhbmRvbSBuYW1lPC9wYXJhbT4KLSAgICAgICAgcHVibGljIEV4Y2VsUGFja2FnZShGaWxlSW5mbyB0ZW1wbGF0ZSwgYm9vbCB1c2VTdHJlYW0pCi0gICAgICAgIHsKLSAgICAgICAgICAgIENyZWF0ZUZyb21UZW1wbGF0ZSh0ZW1wbGF0ZSwgbnVsbCk7Ci0gICAgICAgICAgICBpZiAodXNlU3RyZWFtID09IGZhbHNlKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIEZpbGUgPSBuZXcgRmlsZUluZm8oUGF0aC5HZXRUZW1wUGF0aCgpICsgR3VpZC5OZXdHdWlkKCkuVG9TdHJpbmcoKSArICIueGxzeCIpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIC8vLyA8c3VtbWFyeT4KLSAgICAgICAgLy8vIENyZWF0ZSBhIG5ldyBpbnN0YW5jZSBvZiB0aGUgRXhjZWxQYWNrYWdlIGNsYXNzIGJhc2VkIG9uIGEgZXhpc3RpbmcgdGVtcGxhdGUuCi0gICAgICAgIC8vLyA8L3N1bW1hcnk+Ci0gICAgICAgIC8vLyA8cGFyYW0gbmFtZT0idGVtcGxhdGUiPlRoZSBuYW1lIG9mIHRoZSBFeGNlbCB0ZW1wbGF0ZSB0byB1c2UgYXMgdGhlIGJhc2lzIG9mIHRoZSBuZXcgRXhjZWwgZmlsZTwvcGFyYW0+Ci0gICAgICAgIC8vLyA8cGFyYW0gbmFtZT0idXNlU3RyZWFtIj5pZiB0cnVlIHVzZSBhIHN0cmVhbS4gSWYgZmFsc2UgY3JlYXRlIGEgZmlsZSBpbiB0aGUgdGVtcCBkaXIgd2l0aCBhIHJhbmRvbSBuYW1lPC9wYXJhbT4KLSAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJwYXNzd29yZCI+UGFzc3dvcmQgdG8gZGVjcnlwdGVkIHRoZSB0ZW1wbGF0ZTwvcGFyYW0+Ci0gICAgICAgIHB1YmxpYyBFeGNlbFBhY2thZ2UoRmlsZUluZm8gdGVtcGxhdGUsIGJvb2wgdXNlU3RyZWFtLCBzdHJpbmcgcGFzc3dvcmQpCi0gICAgICAgIHsKLSAgICAgICAgICAgIENyZWF0ZUZyb21UZW1wbGF0ZSh0ZW1wbGF0ZSwgcGFzc3dvcmQpOwotICAgICAgICAgICAgaWYgKHVzZVN0cmVhbSA9PSBmYWxzZSkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBGaWxlID0gbmV3IEZpbGVJbmZvKFBhdGguR2V0VGVtcFBhdGgoKSArIEd1aWQuTmV3R3VpZCgpLlRvU3RyaW5nKCkgKyAiLnhsc3giKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQorICAgICAgICAKICAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgICAvLy8gQ3JlYXRlIGEgbmV3IGluc3RhbmNlIG9mIHRoZSBFeGNlbFBhY2thZ2UgY2xhc3MgYmFzZWQgb24gYSBzdHJlYW0KICAgICAgICAgLy8vIDwvc3VtbWFyeT4KICAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJuZXdTdHJlYW0iPlRoZSBzdHJlYW0gb2JqZWN0IGNhbiBiZSBlbXB0eSBvciBjb250YWluIGEgcGFja2FnZS4gVGhlIHN0cmVhbSBtdXN0IGJlIFJlYWQvV3JpdGU8L3BhcmFtPgogICAgICAgICBwdWJsaWMgRXhjZWxQYWNrYWdlKFN0cmVhbSBuZXdTdHJlYW0pIAogICAgICAgICB7Ci0gICAgICAgICAgICBpZiAobmV3U3RyZWFtLkxlbmd0aCA9PSAwKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIF9zdHJlYW0gPSBuZXdTdHJlYW07Ci0gICAgICAgICAgICAgICAgX2lzRXh0ZXJuYWxTdHJlYW0gPSB0cnVlOwotICAgICAgICAgICAgICAgIENvbnN0cnVjdE5ld0ZpbGUobnVsbCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICB7ICAgICAgICAgICAgICAgIAotICAgICAgICAgICAgICAgIExvYWQobmV3U3RyZWFtKTsKLSAgICAgICAgICAgIH0KKyAgICAgICAgICAgIFBhY2thZ2UgPSBuZXcobmV3U3RyZWFtKTsKKyAgICAgICAgICAgIFdvcmtib29rID0gQ3JlYXRlV29ya2Jvb2soKTsKICAgICAgICAgfQotICAgICAgICAvLy8gPHN1bW1hcnk+Ci0gICAgICAgIC8vLyBDcmVhdGUgYSBuZXcgaW5zdGFuY2Ugb2YgdGhlIEV4Y2VsUGFja2FnZSBjbGFzcyBiYXNlZCBvbiBhIHN0cmVhbQotICAgICAgICAvLy8gPC9zdW1tYXJ5PgotICAgICAgICAvLy8gPHBhcmFtIG5hbWU9Im5ld1N0cmVhbSI+VGhlIHN0cmVhbSBvYmplY3QgY2FuIGJlIGVtcHR5IG9yIGNvbnRhaW4gYSBwYWNrYWdlLiBUaGUgc3RyZWFtIG11c3QgYmUgUmVhZC9Xcml0ZTwvcGFyYW0+Ci0gICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iUGFzc3dvcmQiPlRoZSBwYXNzd29yZCB0byBkZWNyeXB0IHRoZSBkb2N1bWVudDwvcGFyYW0+Ci0gICAgICAgIHB1YmxpYyBFeGNlbFBhY2thZ2UoU3RyZWFtIG5ld1N0cmVhbSwgc3RyaW5nIFBhc3N3b3JkKQorCisgICAgICAgIHByaXZhdGUgRXhjZWxXb3JrYm9vayBDcmVhdGVXb3JrYm9vaygpCiAgICAgICAgIHsKLSAgICAgICAgICAgIGlmICghKG5ld1N0cmVhbS5DYW5SZWFkICYmIG5ld1N0cmVhbS5DYW5Xcml0ZSkpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEV4Y2VwdGlvbigiVGhlIHN0cmVhbSBtdXN0IGJlIHJlYWQvd3JpdGUiKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmIChuZXdTdHJlYW0uTGVuZ3RoID4gMCkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBMb2FkKG5ld1N0cmVhbSxQYXNzd29yZCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgX3N0cmVhbSA9IG5ld1N0cmVhbTsKLSAgICAgICAgICAgICAgICBfaXNFeHRlcm5hbFN0cmVhbSA9IHRydWU7Ci0gICAgICAgICAgICAgICAgLy9fcGFja2FnZSA9IFBhY2thZ2UuT3Blbihfc3RyZWFtLCBGaWxlTW9kZS5DcmVhdGUsIEZpbGVBY2Nlc3MuUmVhZFdyaXRlKTsgVE9ETzpSZW1vdmUKLSAgICAgICAgICAgICAgICBfcGFja2FnZSA9IG5ldyBQYWNrYWdpbmcuWmlwUGFja2FnZShfc3RyZWFtKTsKLSAgICAgICAgICAgICAgICBDcmVhdGVCbGFua1diKCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgLy8vIDxzdW1tYXJ5PgotICAgICAgICAvLy8gQ3JlYXRlIGEgbmV3IGluc3RhbmNlIG9mIHRoZSBFeGNlbFBhY2thZ2UgY2xhc3MgYmFzZWQgb24gYSBzdHJlYW0KLSAgICAgICAgLy8vIDwvc3VtbWFyeT4KLSAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJuZXdTdHJlYW0iPlRoZSBvdXRwdXQgc3RyZWFtLiBNdXN0IGJlIGFuIGVtcHR5IHJlYWQvd3JpdGUgc3RyZWFtLjwvcGFyYW0+Ci0gICAgICAgIC8vLyA8cGFyYW0gbmFtZT0idGVtcGxhdGVTdHJlYW0iPlRoaXMgc3RyZWFtIGlzIGNvcGllZCB0byB0aGUgb3V0cHV0IHN0cmVhbSBhdCBsb2FkPC9wYXJhbT4KLSAgICAgICAgcHVibGljIEV4Y2VsUGFja2FnZShTdHJlYW0gbmV3U3RyZWFtLCBTdHJlYW0gdGVtcGxhdGVTdHJlYW0pCi0gICAgICAgIHsKLSAgICAgICAgICAgIGlmIChuZXdTdHJlYW0uTGVuZ3RoID4gMCkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICB0aHJvdyhuZXcgRXhjZXB0aW9uKCJUaGUgb3V0cHV0IHN0cmVhbSBtdXN0IGJlIGVtcHR5LiBMZW5ndGggPiAwIikpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSBpZiAoIShuZXdTdHJlYW0uQ2FuUmVhZCAmJiBuZXdTdHJlYW0uQ2FuV3JpdGUpKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIHRocm93IG5ldyBFeGNlcHRpb24oIlRoZSBzdHJlYW0gbXVzdCBiZSByZWFkL3dyaXRlIik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBMb2FkKHRlbXBsYXRlU3RyZWFtLCBuZXdTdHJlYW0sIG51bGwpOwotICAgICAgICB9Ci0gICAgICAgIC8vLyA8c3VtbWFyeT4KLSAgICAgICAgLy8vIENyZWF0ZSBhIG5ldyBpbnN0YW5jZSBvZiB0aGUgRXhjZWxQYWNrYWdlIGNsYXNzIGJhc2VkIG9uIGEgc3RyZWFtCi0gICAgICAgIC8vLyA8L3N1bW1hcnk+Ci0gICAgICAgIC8vLyA8cGFyYW0gbmFtZT0ibmV3U3RyZWFtIj5UaGUgb3V0cHV0IHN0cmVhbS4gTXVzdCBiZSBhbiBlbXB0eSByZWFkL3dyaXRlIHN0cmVhbS48L3BhcmFtPgotICAgICAgICAvLy8gPHBhcmFtIG5hbWU9InRlbXBsYXRlU3RyZWFtIj5UaGlzIHN0cmVhbSBpcyBjb3BpZWQgdG8gdGhlIG91dHB1dCBzdHJlYW0gYXQgbG9hZDwvcGFyYW0+Ci0gICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iUGFzc3dvcmQiPlBhc3N3b3JkIHRvIGRlY3J5cHRlZCB0aGUgdGVtcGxhdGU8L3BhcmFtPgotICAgICAgICBwdWJsaWMgRXhjZWxQYWNrYWdlKFN0cmVhbSBuZXdTdHJlYW0sIFN0cmVhbSB0ZW1wbGF0ZVN0cmVhbSwgc3RyaW5nIFBhc3N3b3JkKQotICAgICAgICB7Ci0gICAgICAgICAgICBpZiAobmV3U3RyZWFtLkxlbmd0aCA+IDApCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgKG5ldyBFeGNlcHRpb24oIlRoZSBvdXRwdXQgc3RyZWFtIG11c3QgYmUgZW1wdHkuIExlbmd0aCA+IDAiKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmICghKG5ld1N0cmVhbS5DYW5SZWFkICYmIG5ld1N0cmVhbS5DYW5Xcml0ZSkpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEV4Y2VwdGlvbigiVGhlIHN0cmVhbSBtdXN0IGJlIHJlYWQvd3JpdGUiKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIExvYWQodGVtcGxhdGVTdHJlYW0sIG5ld1N0cmVhbSwgUGFzc3dvcmQpOwotICAgICAgICB9CisgICAgICAgICAgICBFeGNlbFdvcmtib29rIHdvcmtib29rID0gbmV3KHRoaXMsIENyZWF0ZURlZmF1bHROU00oKSk7CisgICAgICAgICAgICB3b3JrYm9vay5HZXRFeHRlcm5hbFJlZmVyZW5jZXMoKTsKKyAgICAgICAgICAgIHdvcmtib29rLkdldERlZmluZWROYW1lcygpOworICAgICAgICAgICAgcmV0dXJuIHdvcmtib29rOworICAgICAgICB9IAorICAgICAgICAKICAgICAgICAgI2VuZHJlZ2lvbgotICAgICAgICBpbnRlcm5hbCBJbWFnZUluZm8gQWRkSW1hZ2UoYnl0ZVtdIGltYWdlKQotICAgICAgICB7Ci0gICAgICAgICAgICByZXR1cm4gQWRkSW1hZ2UoaW1hZ2UsIG51bGwsICIiKTsKLSAgICAgICAgfQotICAgICAgICBpbnRlcm5hbCBJbWFnZUluZm8gQWRkSW1hZ2UoYnl0ZVtdIGltYWdlLCBVcmkgdXJpLCBzdHJpbmcgY29udGVudFR5cGUpCi0gICAgICAgIHsKLSAgICAgICAgICAgIHZhciBoYXNoUHJvdmlkZXIgPSBuZXcgU0hBMUNyeXB0b1NlcnZpY2VQcm92aWRlcigpOwotICAgICAgICAgICAgdmFyIGhhc2ggPSBCaXRDb252ZXJ0ZXIuVG9TdHJpbmcoaGFzaFByb3ZpZGVyLkNvbXB1dGVIYXNoKGltYWdlKSkuUmVwbGFjZSgiLSIsIiIpOwotICAgICAgICAgICAgbG9jayAoX2ltYWdlcykKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBpZiAoX2ltYWdlcy5Db250YWluc0tleShoYXNoKSkKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgIF9pbWFnZXNbaGFzaF0uUmVmQ291bnQrKzsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgUGFja2FnaW5nLlppcFBhY2thZ2VQYXJ0IGltYWdlUGFydDsKLSAgICAgICAgICAgICAgICAgICAgaWYgKHVyaSA9PSBudWxsKQotICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICB1cmkgPSBHZXROZXdVcmkoUGFja2FnZSwgIi94bC9tZWRpYS9pbWFnZXswfS5qcGciKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGltYWdlUGFydCA9IFBhY2thZ2UuQ3JlYXRlUGFydCh1cmksICJpbWFnZS9qcGVnIiwgQ29tcHJlc3Npb25MZXZlbC5Ob25lKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIGltYWdlUGFydCA9IFBhY2thZ2UuQ3JlYXRlUGFydCh1cmksIGNvbnRlbnRUeXBlLCBDb21wcmVzc2lvbkxldmVsLk5vbmUpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIHZhciBzdHJlYW0gPSBpbWFnZVBhcnQuR2V0U3RyZWFtKEZpbGVNb2RlLkNyZWF0ZSwgRmlsZUFjY2Vzcy5Xcml0ZSk7Ci0gICAgICAgICAgICAgICAgICAgIHN0cmVhbS5Xcml0ZShpbWFnZSwgMCwgaW1hZ2UuR2V0TGVuZ3RoKDApKTsKLQotICAgICAgICAgICAgICAgICAgICBfaW1hZ2VzLkFkZChoYXNoLCBuZXcgSW1hZ2VJbmZvKCkgeyBVcmkgPSB1cmksIFJlZkNvdW50ID0gMSwgSGFzaCA9IGhhc2gsIFBhcnQgPSBpbWFnZVBhcnQgfSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmV0dXJuIF9pbWFnZXNbaGFzaF07Ci0gICAgICAgIH0KLSAgICAgICAgaW50ZXJuYWwgSW1hZ2VJbmZvIExvYWRJbWFnZShieXRlW10gaW1hZ2UsIFVyaSB1cmksIFBhY2thZ2luZy5aaXBQYWNrYWdlUGFydCBpbWFnZVBhcnQpCi0gICAgICAgIHsKLSAgICAgICAgICAgIHZhciBoYXNoUHJvdmlkZXIgPSBuZXcgU0hBMUNyeXB0b1NlcnZpY2VQcm92aWRlcigpOwotICAgICAgICAgICAgdmFyIGhhc2ggPSBCaXRDb252ZXJ0ZXIuVG9TdHJpbmcoaGFzaFByb3ZpZGVyLkNvbXB1dGVIYXNoKGltYWdlKSkuUmVwbGFjZSgiLSIsICIiKTsKLSAgICAgICAgICAgIGlmIChfaW1hZ2VzLkNvbnRhaW5zS2V5KGhhc2gpKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIF9pbWFnZXNbaGFzaF0uUmVmQ291bnQrKzsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBfaW1hZ2VzLkFkZChoYXNoLCBuZXcgSW1hZ2VJbmZvKCkgeyBVcmkgPSB1cmksIFJlZkNvdW50ID0gMSwgSGFzaCA9IGhhc2gsIFBhcnQgPSBpbWFnZVBhcnQgfSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gX2ltYWdlc1toYXNoXTsKLSAgICAgICAgfQotICAgICAgICBpbnRlcm5hbCB2b2lkIFJlbW92ZUltYWdlKHN0cmluZyBoYXNoKQotICAgICAgICB7Ci0gICAgICAgICAgICBsb2NrIChfaW1hZ2VzKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIGlmIChfaW1hZ2VzLkNvbnRhaW5zS2V5KGhhc2gpKQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgdmFyIGlpID0gX2ltYWdlc1toYXNoXTsKLSAgICAgICAgICAgICAgICAgICAgaWkuUmVmQ291bnQtLTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGlpLlJlZkNvdW50ID09IDApCi0gICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIFBhY2thZ2UuRGVsZXRlUGFydChpaS5VcmkpOwotICAgICAgICAgICAgICAgICAgICAgICAgX2ltYWdlcy5SZW1vdmUoaGFzaCk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgaW50ZXJuYWwgSW1hZ2VJbmZvIEdldEltYWdlSW5mbyhieXRlW10gaW1hZ2UpCi0gICAgICAgIHsKLSAgICAgICAgICAgIHZhciBoYXNoUHJvdmlkZXIgPSBuZXcgU0hBMUNyeXB0b1NlcnZpY2VQcm92aWRlcigpOwotICAgICAgICAgICAgdmFyIGhhc2ggPSBCaXRDb252ZXJ0ZXIuVG9TdHJpbmcoaGFzaFByb3ZpZGVyLkNvbXB1dGVIYXNoKGltYWdlKSkuUmVwbGFjZSgiLSIsIiIpOwotCi0gICAgICAgICAgICBpZiAoX2ltYWdlcy5Db250YWluc0tleShoYXNoKSkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gX2ltYWdlc1toYXNoXTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBwcml2YXRlIFVyaSBHZXROZXdVcmkoUGFja2FnaW5nLlppcFBhY2thZ2UgcGFja2FnZSwgc3RyaW5nIHNVcmkpCi0gICAgICAgIHsKLSAgICAgICAgICAgIGludCBpZCA9IDE7Ci0gICAgICAgICAgICBVcmkgdXJpOwotICAgICAgICAgICAgZG8KLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICB1cmkgPSBuZXcgVXJpKHN0cmluZy5Gb3JtYXQoc1VyaSwgaWQrKyksIFVyaUtpbmQuUmVsYXRpdmUpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgd2hpbGUgKHBhY2thZ2UuUGFydEV4aXN0cyh1cmkpKTsKLSAgICAgICAgICAgIHJldHVybiB1cmk7Ci0gICAgICAgIH0KLSAgICAgICAgLy8vIDxzdW1tYXJ5PgotICAgICAgICAvLy8gQ3JlYXRlIGEgbmV3IGZpbGUgZnJvbSBhIHRlbXBsYXRlCi0gICAgICAgIC8vLyA8L3N1bW1hcnk+Ci0gICAgICAgIC8vLyA8cGFyYW0gbmFtZT0idGVtcGxhdGUiPkFuIGV4aXN0aW5nIHhsc3ggZmlsZSB0byB1c2UgYXMgYSB0ZW1wbGF0ZTwvcGFyYW0+Ci0gICAgICAgIC8vLyA8cGFyYW0gbmFtZT0icGFzc3dvcmQiPlRoZSBwYXNzd29yZCB0byBkZWNyeXB0IHRoZSBwYWNrYWdlLjwvcGFyYW0+Ci0gICAgICAgIC8vLyA8cmV0dXJucz48L3JldHVybnM+Ci0gICAgICAgIHByaXZhdGUgdm9pZCBDcmVhdGVGcm9tVGVtcGxhdGUoRmlsZUluZm8gdGVtcGxhdGUsIHN0cmluZyBwYXNzd29yZCkKLSAgICAgICAgewotICAgICAgICAgICAgaWYgKHRlbXBsYXRlICE9IG51bGwpIHRlbXBsYXRlLlJlZnJlc2goKTsKLSAgICAgICAgICAgIGlmICh0ZW1wbGF0ZS5FeGlzdHMpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgaWYoX3N0cmVhbT09bnVsbCkgX3N0cmVhbT1uZXcgTWVtb3J5U3RyZWFtKCk7Ci0gICAgICAgICAgICAgICAgdmFyIG1zID0gbmV3IE1lbW9yeVN0cmVhbSgpOwotICAgICAgICAgICAgICAgIGlmIChwYXNzd29yZCAhPSBudWxsKQotICAgICAgICAgICAgICAgIHsKLSNpZiAhTU9OTwotICAgICAgICAgICAgICAgICAgICBFbmNyeXB0aW9uLklzRW5jcnlwdGVkID0gdHJ1ZTsKLSAgICAgICAgICAgICAgICAgICAgRW5jcnlwdGlvbi5QYXNzd29yZCA9IHBhc3N3b3JkOwotICAgICAgICAgICAgICAgICAgICB2YXIgZW5jckhhbmRsZXIgPSBuZXcgRW5jcnlwdGVkUGFja2FnZUhhbmRsZXIoKTsKLSAgICAgICAgICAgICAgICAgICAgbXMgPSBlbmNySGFuZGxlci5EZWNyeXB0UGFja2FnZSh0ZW1wbGF0ZSwgRW5jcnlwdGlvbik7Ci0gICAgICAgICAgICAgICAgICAgIGVuY3JIYW5kbGVyID0gbnVsbDsKLSNlbmRpZgotI2lmIE1PTk8KLQkgICAgICAgICAgICAgICAgdGhyb3cgKG5ldyBOb3RJbXBsZW1lbnRlZEV4Y2VwdGlvbigiTm8gc3VwcG9ydCBmb3IgRW5jcnlwdGVkIHBhY2thZ2VzIGluIE1vbm8iKSk7Ci0jZW5kaWYKLQkgICAgICAgICAgICAgICAgLy90aHJvdyAobmV3IE5vdEltcGxlbWVudGVkRXhjZXB0aW9uKCJObyBzdXBwb3J0IGZvciBFbmNyeXB0ZWQgcGFja2FnZXMgaW4gdGhpcyB2ZXJzaW9uIikpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICBieXRlW10gYiA9IFN5c3RlbS5JTy5GaWxlLlJlYWRBbGxCeXRlcyh0ZW1wbGF0ZS5GdWxsTmFtZSk7Ci0gICAgICAgICAgICAgICAgICAgIG1zLldyaXRlKGIsIDAsIGIuTGVuZ3RoKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgdHJ5Ci0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAvL19wYWNrYWdlID0gUGFja2FnZS5PcGVuKF9zdHJlYW0sIEZpbGVNb2RlLk9wZW4sIEZpbGVBY2Nlc3MuUmVhZFdyaXRlKTsKLSAgICAgICAgICAgICAgICAgICAgX3BhY2thZ2UgPSBuZXcgUGFja2FnaW5nLlppcFBhY2thZ2UobXMpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBjYXRjaCAoRXhjZXB0aW9uIGV4KQotICAgICAgICAgICAgICAgIHsKLSNpZiAhTU9OTwotICAgICAgICAgICAgICAgICAgICBpZiAocGFzc3dvcmQgPT0gbnVsbCAmJiBDb21wb3VuZERvY3VtZW50LklzU3RvcmFnZUZpbGUodGVtcGxhdGUuRnVsbE5hbWUpPT0wKQotICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXhjZXB0aW9uKCJDYW4gbm90IG9wZW4gdGhlIHBhY2thZ2UuIFBhY2thZ2UgaXMgYW4gT0xFIGNvbXBvdW5kIGRvY3VtZW50LiBJZiB0aGlzIGlzIGFuIGVuY3J5cHRlZCBwYWNrYWdlLCBwbGVhc2Ugc3VwcGx5IHRoZSBwYXNzd29yZCIsIGV4KTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHRocm93OwotICAgICAgICAgICAgICAgICAgICB9Ci0jZW5kaWYKLSNpZiBNT05PCi0gICAgICAgICAgICAgICAgICAgIHRocm93OwotI2VuZGlmCi0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgIHRocm93IG5ldyBFeGNlcHRpb24oIlBhc3NlZCBpbnZhbGlkIFRlbXBsYXRlUGF0aCB0byBFeGNlbCBUZW1wbGF0ZSIpOwotICAgICAgICAgICAgLy9yZXR1cm4gbmV3RmlsZTsKLSAgICAgICAgfQotICAgICAgICBwcml2YXRlIHZvaWQgQ29uc3RydWN0TmV3RmlsZShzdHJpbmcgcGFzc3dvcmQpCi0gICAgICAgIHsKLSAgICAgICAgICAgIHZhciBtcyA9IG5ldyBNZW1vcnlTdHJlYW0oKTsKLSAgICAgICAgICAgIGlmIChfc3RyZWFtID09IG51bGwpIF9zdHJlYW0gPSBuZXcgTWVtb3J5U3RyZWFtKCk7Ci0gICAgICAgICAgICBpZiAoRmlsZSAhPSBudWxsKSBGaWxlLlJlZnJlc2goKTsKLSAgICAgICAgICAgIGlmIChGaWxlICE9IG51bGwgJiYgRmlsZS5FeGlzdHMpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgaWYgKHBhc3N3b3JkICE9IG51bGwpCi0gICAgICAgICAgICAgICAgewotI2lmICFNT05PCi0gICAgICAgICAgICAgICAgICAgIHZhciBlbmNySGFuZGxlciA9IG5ldyBFbmNyeXB0ZWRQYWNrYWdlSGFuZGxlcigpOwotICAgICAgICAgICAgICAgICAgICBFbmNyeXB0aW9uLklzRW5jcnlwdGVkID0gdHJ1ZTsKLSAgICAgICAgICAgICAgICAgICAgRW5jcnlwdGlvbi5QYXNzd29yZCA9IHBhc3N3b3JkOwotICAgICAgICAgICAgICAgICAgICBtcyA9IGVuY3JIYW5kbGVyLkRlY3J5cHRQYWNrYWdlKEZpbGUsIEVuY3J5cHRpb24pOwotICAgICAgICAgICAgICAgICAgICBlbmNySGFuZGxlciA9IG51bGw7Ci0jZW5kaWYKLSNpZiBNT05PCi0gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBOb3RJbXBsZW1lbnRlZEV4Y2VwdGlvbigiTm8gc3VwcG9ydCBmb3IgRW5jcnlwdGVkIHBhY2thZ2VzIGluIE1vbm8iKTsKLSNlbmRpZgotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICBieXRlW10gYiA9IFN5c3RlbS5JTy5GaWxlLlJlYWRBbGxCeXRlcyhGaWxlLkZ1bGxOYW1lKTsKLSAgICAgICAgICAgICAgICAgICAgbXMuV3JpdGUoYiwgMCwgYi5MZW5ndGgpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB0cnkKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgIC8vX3BhY2thZ2UgPSBQYWNrYWdlLk9wZW4oX3N0cmVhbSwgRmlsZU1vZGUuT3BlbiwgRmlsZUFjY2Vzcy5SZWFkV3JpdGUpOwotICAgICAgICAgICAgICAgICAgICBfcGFja2FnZSA9IG5ldyBQYWNrYWdpbmcuWmlwUGFja2FnZShtcyk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGNhdGNoIChFeGNlcHRpb24gZXgpCi0gICAgICAgICAgICAgICB7Ci0jaWYgIU1PTk8KLSAgICAgICAgICAgICAgICAgICAgaWYgKHBhc3N3b3JkID09IG51bGwgJiYgQ29tcG91bmREb2N1bWVudC5Jc1N0b3JhZ2VGaWxlKEZpbGUuRnVsbE5hbWUpPT0wKQotICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXhjZXB0aW9uKCJDYW4gbm90IG9wZW4gdGhlIHBhY2thZ2UuIFBhY2thZ2UgaXMgYW4gT0xFIGNvbXBvdW5kIGRvY3VtZW50LiBJZiB0aGlzIGlzIGFuIGVuY3J5cHRlZCBwYWNrYWdlLCBwbGVhc2Ugc3VwcGx5IHRoZSBwYXNzd29yZCIsIGV4KTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHRocm93OwotICAgICAgICAgICAgICAgICAgICB9Ci0jZW5kaWYKLSNpZiBNT05PCi0gICAgICAgICAgICAgICAgICAgIHRocm93OwotI2VuZGlmCi0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIC8vX3BhY2thZ2UgPSBQYWNrYWdlLk9wZW4oX3N0cmVhbSwgRmlsZU1vZGUuQ3JlYXRlLCBGaWxlQWNjZXNzLlJlYWRXcml0ZSk7Ci0gICAgICAgICAgICAgICAgX3BhY2thZ2UgPSBuZXcgUGFja2FnaW5nLlppcFBhY2thZ2UobXMpOwotICAgICAgICAgICAgICAgIENyZWF0ZUJsYW5rV2IoKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIHByaXZhdGUgdm9pZCBDcmVhdGVCbGFua1diKCkKLSAgICAgICAgewotICAgICAgICAgICAgWG1sRG9jdW1lbnQgd29ya2Jvb2sgPSBXb3JrYm9vay5Xb3JrYm9va1htbDsgLy8gdGhpcyB3aWxsIGNyZWF0ZSB0aGUgd29ya2Jvb2sgeG1sIGluIHRoZSBwYWNrYWdlCi0gICAgICAgICAgICAvLyBjcmVhdGUgdGhlIHJlbGF0aW9uc2hpcCB0byB0aGUgbWFpbiBwYXJ0Ci0gICAgICAgICAgICBfcGFja2FnZS5DcmVhdGVSZWxhdGlvbnNoaXAoVXJpSGVscGVyLkdldFJlbGF0aXZlVXJpKG5ldyBVcmkoIi94bCIsIFVyaUtpbmQuUmVsYXRpdmUpLCBXb3JrYm9vay5Xb3JrYm9va1VyaSksIFBhY2thZ2luZy5UYXJnZXRNb2RlLkludGVybmFsLCBzY2hlbWFSZWxhdGlvbnNoaXBzICsgIi9vZmZpY2VEb2N1bWVudCIpOwotICAgICAgICB9Ci0KKyAgICAgICAgCiAJCS8vLyA8c3VtbWFyeT4KIAkJLy8vIFJldHVybnMgYSByZWZlcmVuY2UgdG8gdGhlIHBhY2thZ2UKIAkJLy8vIDwvc3VtbWFyeT4KLQkJcHVibGljIFBhY2thZ2luZy5aaXBQYWNrYWdlIFBhY2thZ2UgeyBnZXQgeyByZXR1cm4gKF9wYWNrYWdlKTsgfSB9Ci0gICAgICAgIEV4Y2VsRW5jcnlwdGlvbiBfZW5jcnlwdGlvbj1udWxsOwotICAgICAgICAvLy8gPHN1bW1hcnk+Ci0gICAgICAgIC8vLyBJbmZvcm1hdGlvbiBob3cgYW5kIGlmIHRoZSBwYWNrYWdlIGlzIGVuY3J5cHRlZAotICAgICAgICAvLy8gPC9zdW1tYXJ5PgotICAgICAgICBwdWJsaWMgRXhjZWxFbmNyeXB0aW9uIEVuY3J5cHRpb24KLSAgICAgICAgewotICAgICAgICAgICAgZ2V0Ci0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgaWYgKF9lbmNyeXB0aW9uID09IG51bGwpCi0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICBfZW5jcnlwdGlvbiA9IG5ldyBFeGNlbEVuY3J5cHRpb24oKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgcmV0dXJuIF9lbmNyeXB0aW9uOwotICAgICAgICAgICAgfQotICAgICAgICB9CisJCWludGVybmFsIFBhY2thZ2luZy5aaXBQYWNrYWdlIFBhY2thZ2UgeyBnZXQ7IH0KKwkJCiAJCS8vLyA8c3VtbWFyeT4KIAkJLy8vIFJldHVybnMgYSByZWZlcmVuY2UgdG8gdGhlIHdvcmtib29rIGNvbXBvbmVudCB3aXRoaW4gdGhlIHBhY2thZ2UuCiAJCS8vLyBBbGwgd29ya3NoZWV0cyBhbmQgY2VsbHMgY2FuIGJlIGFjY2Vzc2VkIHRocm91Z2ggdGhlIHdvcmtib29rLgogCQkvLy8gPC9zdW1tYXJ5PgotCQlwdWJsaWMgRXhjZWxXb3JrYm9vayBXb3JrYm9vawotCQl7Ci0JCQlnZXQKLQkJCXsKLSAgICAgICAgICAgICAgICBpZiAoX3dvcmtib29rID09IG51bGwpCi0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICB2YXIgbnNtID0gQ3JlYXRlRGVmYXVsdE5TTSgpOworCQlwdWJsaWMgRXhjZWxXb3JrYm9vayBXb3JrYm9vayB7IGdldDsgfQogCi0gICAgICAgICAgICAgICAgICAgIF93b3JrYm9vayA9IG5ldyBFeGNlbFdvcmtib29rKHRoaXMsIG5zbSk7Ci0KLSAgICAgICAgICAgICAgICAgICAgX3dvcmtib29rLkdldEV4dGVybmFsUmVmZXJlbmNlcygpOwotICAgICAgICAgICAgICAgICAgICBfd29ya2Jvb2suR2V0RGVmaW5lZE5hbWVzKCk7Ci0KLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgcmV0dXJuIChfd29ya2Jvb2spOwotCQkJfQotCQl9Ci0gICAgICAgIHByaXZhdGUgWG1sTmFtZXNwYWNlTWFuYWdlciBDcmVhdGVEZWZhdWx0TlNNKCkKKwkJcHJpdmF0ZSBYbWxOYW1lc3BhY2VNYW5hZ2VyIENyZWF0ZURlZmF1bHROU00oKQogICAgICAgICB7CiAgICAgICAgICAgICAvLyAgQ3JlYXRlIGEgTmFtZXNwYWNlTWFuYWdlciB0byBoYW5kbGUgdGhlIGRlZmF1bHQgbmFtZXNwYWNlLCAKICAgICAgICAgICAgIC8vICBhbmQgY3JlYXRlIGEgcHJlZml4IGZvciB0aGUgZGVmYXVsdCBuYW1lc3BhY2U6CkBAIC02NzAsMjQwICszMDIsMTIgQEAKIAkJLy8vIDxwYXJhbSBuYW1lPSJ4bWxEb2MiPlRoZSBYbWxEb2N1bWVudCB0byBzYXZlPC9wYXJhbT4KIAkJaW50ZXJuYWwgdm9pZCBTYXZlUGFydChVcmkgdXJpLCBYbWxEb2N1bWVudCB4bWxEb2MpCiAJCXsKLSAgICAgICAgICAgIFBhY2thZ2luZy5aaXBQYWNrYWdlUGFydCBwYXJ0ID0gX3BhY2thZ2UuR2V0UGFydCh1cmkpOworICAgICAgICAgICAgUGFja2FnaW5nLlppcFBhY2thZ2VQYXJ0IHBhcnQgPSBQYWNrYWdlLkdldFBhcnQodXJpKTsKIAkJCXhtbERvYy5TYXZlKHBhcnQuR2V0U3RyZWFtKEZpbGVNb2RlLkNyZWF0ZSwgRmlsZUFjY2Vzcy5Xcml0ZSkpOwogCQl9CiAKICAgICAgICAgI2VuZHJlZ2lvbgogCi0JCSNyZWdpb24gRGlzcG9zZQotCQkvLy8gPHN1bW1hcnk+Ci0JCS8vLyBDbG9zZXMgdGhlIHBhY2thZ2UuCi0JCS8vLyA8L3N1bW1hcnk+Ci0JCXB1YmxpYyB2b2lkIERpc3Bvc2UoKQotCQl7Ci0gICAgICAgICAgICBpZihfcGFja2FnZSAhPSBudWxsKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIGlmIChfaXNFeHRlcm5hbFN0cmVhbT09ZmFsc2UgJiYgU3RyZWFtICE9IG51bGwgJiYgKFN0cmVhbS5DYW5SZWFkIHx8IFN0cmVhbS5DYW5Xcml0ZSkpCi0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICBTdHJlYW0uQ2xvc2UoKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgX3BhY2thZ2UuQ2xvc2UoKTsKLSAgICAgICAgICAgICAgICBpZihfaXNFeHRlcm5hbFN0cmVhbT09ZmFsc2UpICgoSURpc3Bvc2FibGUpX3N0cmVhbSkuRGlzcG9zZSgpOwotICAgICAgICAgICAgICAgIGlmKF93b3JrYm9vayAhPSBudWxsKQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgX3dvcmtib29rLkRpc3Bvc2UoKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgX3BhY2thZ2UgPSBudWxsOwotICAgICAgICAgICAgICAgIF9pbWFnZXMgPSBudWxsOwotICAgICAgICAgICAgICAgIF9maWxlID0gbnVsbDsKLSAgICAgICAgICAgICAgICBfd29ya2Jvb2sgPSBudWxsOwotICAgICAgICAgICAgICAgIF9zdHJlYW0gPSBudWxsOwotICAgICAgICAgICAgICAgIF93b3JrYm9vayA9IG51bGw7Ci0gICAgICAgICAgICB9Ci0JCX0KLQkJI2VuZHJlZ2lvbgotCi0JCSNyZWdpb24gU2F2ZSAgLy8gRXhjZWxQYWNrYWdlIHNhdmUKLSAgICAgICAgLy8vIDxzdW1tYXJ5PgotICAgICAgICAvLy8gU2F2ZXMgYWxsIHRoZSBjb21wb25lbnRzIGJhY2sgaW50byB0aGUgcGFja2FnZS4KLSAgICAgICAgLy8vIFRoaXMgbWV0aG9kIHJlY3Vyc2l2ZWx5IGNhbGxzIHRoZSBTYXZlIG1ldGhvZCBvbiBhbGwgc3ViLWNvbXBvbmVudHMuCi0gICAgICAgIC8vLyBXZSBjbG9zZSB0aGUgcGFja2FnZSBhZnRlciB0aGUgc2F2ZSBpcyBkb25lLgotICAgICAgICAvLy8gPC9zdW1tYXJ5PgotICAgICAgICBwdWJsaWMgdm9pZCBTYXZlKCkKLSAgICAgICAgewotICAgICAgICAgICAgdHJ5Ci0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgV29ya2Jvb2suU2F2ZSgpOwotICAgICAgICAgICAgICAgIGlmIChGaWxlID09IG51bGwpCi0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICBpZihFbmNyeXB0aW9uLklzRW5jcnlwdGVkKQotICAgICAgICAgICAgICAgICAgICB7Ci0jaWYgIU1PTk8KLSAgICAgICAgICAgICAgICAgICAgICAgIHZhciBtcyA9IG5ldyBNZW1vcnlTdHJlYW0oKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIF9wYWNrYWdlLlNhdmUobXMpOwotICAgICAgICAgICAgICAgICAgICAgICAgYnl0ZVtdIGZpbGUgPSBtcy5Ub0FycmF5KCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBFbmNyeXB0ZWRQYWNrYWdlSGFuZGxlciBlcGggPSBuZXcgRW5jcnlwdGVkUGFja2FnZUhhbmRsZXIoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHZhciBtc0VuYyA9IGVwaC5FbmNyeXB0UGFja2FnZShmaWxlLCBFbmNyeXB0aW9uKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIENvcHlTdHJlYW0obXNFbmMsIHJlZiBfc3RyZWFtKTsKLSNlbmRpZgotI2lmIE1PTk8KLSAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBOb3RTdXBwb3J0ZWRFeGNlcHRpb24oIkVuY3J5cHRpb24gaXMgbm90IHN1cHBvcnRlZCB1bmRlciBNb25vLiIpOwotI2VuZGlmCi0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBfcGFja2FnZS5TYXZlKF9zdHJlYW0pOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIF9zdHJlYW0uRmx1c2goKTsKLSAgICAgICAgICAgICAgICAgICAgX3BhY2thZ2UuQ2xvc2UoKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKFN5c3RlbS5JTy5GaWxlLkV4aXN0cyhGaWxlLkZ1bGxOYW1lKSkKLSAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgdHJ5Ci0gICAgICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgU3lzdGVtLklPLkZpbGUuRGVsZXRlKEZpbGUuRnVsbE5hbWUpOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBleCkKLSAgICAgICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyAobmV3IEV4Y2VwdGlvbihzdHJpbmcuRm9ybWF0KCJFcnJvciBvdmVyd3JpdGluZyBmaWxlIHswfSIsIEZpbGUuRnVsbE5hbWUpLCBleCkpOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICAgICAgX3BhY2thZ2UuU2F2ZShfc3RyZWFtKTsKLSAgICAgICAgICAgICAgICAgICAgX3BhY2thZ2UuQ2xvc2UoKTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKFN0cmVhbSBpcyBNZW1vcnlTdHJlYW0pCi0gICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIHZhciBmaSA9IG5ldyBGaWxlU3RyZWFtKEZpbGUuRnVsbE5hbWUsIEZpbGVNb2RlLkNyZWF0ZSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvL0VuY3J5cHRQYWNrYWdlCi0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoRW5jcnlwdGlvbi5Jc0VuY3J5cHRlZCkKLSAgICAgICAgICAgICAgICAgICAgICAgIHsKLSNpZiAhTU9OTwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ5dGVbXSBmaWxlID0gKChNZW1vcnlTdHJlYW0pU3RyZWFtKS5Ub0FycmF5KCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgRW5jcnlwdGVkUGFja2FnZUhhbmRsZXIgZXBoID0gbmV3IEVuY3J5cHRlZFBhY2thZ2VIYW5kbGVyKCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG1zID0gZXBoLkVuY3J5cHRQYWNrYWdlKGZpbGUsIEVuY3J5cHRpb24pOwotCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgZmkuV3JpdGUobXMuR2V0QnVmZmVyKCksIDAsIChpbnQpbXMuTGVuZ3RoKTsKLSNlbmRpZgotI2lmIE1PTk8KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTm90U3VwcG9ydGVkRXhjZXB0aW9uKCJFbmNyeXB0aW9uIGlzIG5vdCBzdXBwb3J0ZWQgdW5kZXIgTW9uby4iKTsKLSNlbmRpZgotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgICAgICAgICAgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaS5Xcml0ZSgoKE1lbW9yeVN0cmVhbSlTdHJlYW0pLkdldEJ1ZmZlcigpLCAwLCAoaW50KVN0cmVhbS5MZW5ndGgpOwotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgZmkuQ2xvc2UoKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIFN5c3RlbS5JTy5GaWxlLldyaXRlQWxsQnl0ZXMoRmlsZS5GdWxsTmFtZSwgR2V0QXNCeXRlQXJyYXkoZmFsc2UpKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGNhdGNoIChFeGNlcHRpb24gZXgpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgaWYgKEZpbGUgPT0gbnVsbCkKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgIHRocm93OwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICB0aHJvdyAobmV3IEludmFsaWRPcGVyYXRpb25FeGNlcHRpb24oc3RyaW5nLkZvcm1hdCgiRXJyb3Igc2F2aW5nIGZpbGUgezB9IiwgRmlsZS5GdWxsTmFtZSksIGV4KSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgIC8vLyA8c3VtbWFyeT4KLSAgICAgICAgLy8vIFNhdmVzIGFsbCB0aGUgY29tcG9uZW50cyBiYWNrIGludG8gdGhlIHBhY2thZ2UuCi0gICAgICAgIC8vLyBUaGlzIG1ldGhvZCByZWN1cnNpdmVseSBjYWxscyB0aGUgU2F2ZSBtZXRob2Qgb24gYWxsIHN1Yi1jb21wb25lbnRzLgotICAgICAgICAvLy8gVGhlIHBhY2thZ2UgaXMgY2xvc2VkIGFmdGVyIGl0IGhhCi0gICAgICAgIC8vLyBkIHRvIGVuY3J5cHQgdGhlIHdvcmtib29rIHdpdGguIAotICAgICAgICAvLy8gPC9zdW1tYXJ5PgotICAgICAgICAvLy8gPHBhcmFtIG5hbWU9InBhc3N3b3JkIj5UaGlzIHBhcmFtZXRlciBvdmVycmlkZXMgdGhlIFdvcmtib29rLkVuY3J5cHRpb24uUGFzc3dvcmQuPC9wYXJhbT4KLSAgICAgICAgcHVibGljIHZvaWQgU2F2ZShzdHJpbmcgcGFzc3dvcmQpCi0JCXsKLSAgICAgICAgICAgIEVuY3J5cHRpb24uUGFzc3dvcmQgPSBwYXNzd29yZDsKLSAgICAgICAgICAgIFNhdmUoKTsKLSAgICAgICAgfQotICAgICAgICAvLy8gPHN1bW1hcnk+Ci0gICAgICAgIC8vLyBTYXZlcyB0aGUgd29ya2Jvb2sgdG8gYSBuZXcgZmlsZQotICAgICAgICAvLy8gVGhlIHBhY2thZ2UgaXMgY2xvc2VkIGFmdGVyIGl0IGhhcyBiZWVuIHNhdmVkICAgICAgICAKLSAgICAgICAgLy8vIDwvc3VtbWFyeT4KLSAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJmaWxlIj5UaGUgZmlsZSBsb2NhdGlvbjwvcGFyYW0+Ci0gICAgICAgIHB1YmxpYyB2b2lkIFNhdmVBcyhGaWxlSW5mbyBmaWxlKQotICAgICAgICB7Ci0gICAgICAgICAgICBGaWxlID0gZmlsZTsKLSAgICAgICAgICAgIFNhdmUoKTsKLSAgICAgICAgfQotICAgICAgICAvLy8gPHN1bW1hcnk+Ci0gICAgICAgIC8vLyBTYXZlcyB0aGUgd29ya2Jvb2sgdG8gYSBuZXcgZmlsZQotICAgICAgICAvLy8gVGhlIHBhY2thZ2UgaXMgY2xvc2VkIGFmdGVyIGl0IGhhcyBiZWVuIHNhdmVkCi0gICAgICAgIC8vLyA8L3N1bW1hcnk+Ci0gICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iZmlsZSI+VGhlIGZpbGU8L3BhcmFtPgotICAgICAgICAvLy8gPHBhcmFtIG5hbWU9InBhc3N3b3JkIj5UaGUgcGFzc3dvcmQgdG8gZW5jcnlwdCB0aGUgd29ya2Jvb2sgd2l0aC4gCi0gICAgICAgIC8vLyBUaGlzIHBhcmFtZXRlciBvdmVycmlkZXMgdGhlIEVuY3J5cHRpb24uUGFzc3dvcmQuPC9wYXJhbT4KLSAgICAgICAgcHVibGljIHZvaWQgU2F2ZUFzKEZpbGVJbmZvIGZpbGUsIHN0cmluZyBwYXNzd29yZCkKLSAgICAgICAgewotICAgICAgICAgICAgRmlsZSA9IGZpbGU7Ci0gICAgICAgICAgICBFbmNyeXB0aW9uLlBhc3N3b3JkID0gcGFzc3dvcmQ7Ci0gICAgICAgICAgICBTYXZlKCk7Ci0gICAgICAgIH0KLSAgICAgICAgLy8vIDxzdW1tYXJ5PgotICAgICAgICAvLy8gQ29waWVzIHRoZSBQYWNrYWdlIHRvIHRoZSBPdXRzdHJlYW0KLSAgICAgICAgLy8vIFRoZSBwYWNrYWdlIGlzIGNsb3NlZCBhZnRlciBpdCBoYXMgYmVlbiBzYXZlZAotICAgICAgICAvLy8gPC9zdW1tYXJ5PgotICAgICAgICAvLy8gPHBhcmFtIG5hbWU9Ik91dHB1dFN0cmVhbSI+VGhlIHN0cmVhbSB0byBjb3B5IHRoZSBwYWNrYWdlIHRvPC9wYXJhbT4KLSAgICAgICAgcHVibGljIHZvaWQgU2F2ZUFzKFN0cmVhbSBPdXRwdXRTdHJlYW0pCi0gICAgICAgIHsKLSAgICAgICAgICAgIEZpbGUgPSBudWxsOwotICAgICAgICAgICAgU2F2ZSgpOwotCi0gICAgICAgICAgICBpZiAoT3V0cHV0U3RyZWFtICE9IF9zdHJlYW0pCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgaWYgKEVuY3J5cHRpb24uSXNFbmNyeXB0ZWQpCi0gICAgICAgICAgICAgICAgewotI2lmICFNT05PCi0gICAgICAgICAgICAgICAgICAgIC8vRW5jcnlwdCBXb3JrYm9vawotICAgICAgICAgICAgICAgICAgICBCeXRlW10gZmlsZSA9IG5ldyBieXRlW1N0cmVhbS5MZW5ndGhdOwotICAgICAgICAgICAgICAgICAgICBsb25nIHBvcyA9IFN0cmVhbS5Qb3NpdGlvbjsKLSAgICAgICAgICAgICAgICAgICAgU3RyZWFtLlNlZWsoMCwgU2Vla09yaWdpbi5CZWdpbik7Ci0gICAgICAgICAgICAgICAgICAgIFN0cmVhbS5SZWFkKGZpbGUsIDAsIChpbnQpIFN0cmVhbS5MZW5ndGgpOwotICAgICAgICAgICAgICAgICAgICBFbmNyeXB0ZWRQYWNrYWdlSGFuZGxlciBlcGggPSBuZXcgRW5jcnlwdGVkUGFja2FnZUhhbmRsZXIoKTsKLSAgICAgICAgICAgICAgICAgICAgdmFyIG1zID0gZXBoLkVuY3J5cHRQYWNrYWdlKGZpbGUsIEVuY3J5cHRpb24pOwotICAgICAgICAgICAgICAgICAgICBDb3B5U3RyZWFtKG1zLCByZWYgT3V0cHV0U3RyZWFtKTsKLSNlbmRpZgotI2lmIE1PTk8KLSAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTm90U3VwcG9ydGVkRXhjZXB0aW9uKCJFbmNyeXB0aW9uIGlzIG5vdCBzdXBwb3J0ZWQgdW5kZXIgTW9uby4iKTsKLSNlbmRpZgotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICBDb3B5U3RyZWFtKF9zdHJlYW0sIHJlZiBPdXRwdXRTdHJlYW0pOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICAvLy8gPHN1bW1hcnk+Ci0gICAgICAgIC8vLyBDb3BpZXMgdGhlIFBhY2thZ2UgdG8gdGhlIE91dHN0cmVhbQotICAgICAgICAvLy8gVGhlIHBhY2thZ2UgaXMgY2xvc2VkIGFmdGVyIGl0IGhhcyBiZWVuIHNhdmVkCi0gICAgICAgIC8vLyA8L3N1bW1hcnk+Ci0gICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iT3V0cHV0U3RyZWFtIj5UaGUgc3RyZWFtIHRvIGNvcHkgdGhlIHBhY2thZ2UgdG88L3BhcmFtPgotICAgICAgICAvLy8gPHBhcmFtIG5hbWU9InBhc3N3b3JkIj5UaGUgcGFzc3dvcmQgdG8gZW5jcnlwdCB0aGUgd29ya2Jvb2sgd2l0aC4gCi0gICAgICAgIC8vLyBUaGlzIHBhcmFtZXRlciBvdmVycmlkZXMgdGhlIEVuY3J5cHRpb24uUGFzc3dvcmQuPC9wYXJhbT4KLSAgICAgICAgcHVibGljIHZvaWQgU2F2ZUFzKFN0cmVhbSBPdXRwdXRTdHJlYW0sIHN0cmluZyBwYXNzd29yZCkKLSAgICAgICAgewotICAgICAgICAgICAgRW5jcnlwdGlvbi5QYXNzd29yZCA9IHBhc3N3b3JkOwotICAgICAgICAgICAgU2F2ZUFzKE91dHB1dFN0cmVhbSk7Ci0gICAgICAgIH0KLSAgICAgICAgRmlsZUluZm8gX2ZpbGUgPSBudWxsOwotCi0gICAgICAgIC8vLyA8c3VtbWFyeT4KLSAgICAgICAgLy8vIFRoZSBvdXRwdXQgZmlsZS4gTnVsbCBpZiBubyBmaWxlIGlzIHVzZWQKLSAgICAgICAgLy8vIDwvc3VtbWFyeT4KLSAgICAgICAgcHVibGljIEZpbGVJbmZvIEZpbGUKLSAgICAgICAgewotICAgICAgICAgICAgZ2V0Ci0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIF9maWxlOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgc2V0Ci0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgX2ZpbGUgPSB2YWx1ZTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICAvLy8gPHN1bW1hcnk+Ci0gICAgICAgIC8vLyBUaGUgb3V0cHV0IHN0cmVhbS4gVGhpcyBzdHJlYW0gaXMgdGhlIG5vdCB0aGUgZW5jcnlwdGVkIHBhY2thZ2UuCi0gICAgICAgIC8vLyBUbyBnZXQgdGhlIGVuY3J5cHRlZCBwYWNrYWdlIHVzZSB0aGUgU2F2ZUFzKHN0cmVhbSkgbWV0aG9kLgotICAgICAgICAvLy8gPC9zdW1tYXJ5PgotICAgICAgICBwdWJsaWMgU3RyZWFtIFN0cmVhbQotICAgICAgICB7Ci0gICAgICAgICAgICBnZXQKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gX3N0cmVhbTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCQkjZW5kcmVnaW9uCiAgICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAgLy8vIENvbXByZXNzaW9uIG9wdGlvbiBmb3IgdGhlIHBhY2thZ2UKICAgICAgICAgLy8vIDwvc3VtbWFyeT4gICAgICAgIApAQCAtOTI3LDcgKzMzMSw3IEBACiAJCWludGVybmFsIFhtbERvY3VtZW50IEdldFhtbEZyb21VcmkoVXJpIHVyaSkKIAkJewogCQkJWG1sRG9jdW1lbnQgeG1sID0gbmV3IFhtbERvY3VtZW50KCk7Ci0JCQlQYWNrYWdpbmcuWmlwUGFja2FnZVBhcnQgcGFydCA9IF9wYWNrYWdlLkdldFBhcnQodXJpKTsKKwkJCVBhY2thZ2luZy5aaXBQYWNrYWdlUGFydCBwYXJ0ID0gUGFja2FnZS5HZXRQYXJ0KHVyaSk7CiAgICAgICAgICAgICBYbWxIZWxwZXIuTG9hZFhtbFNhZmUoeG1sLCBwYXJ0LkdldFN0cmVhbSgpKTsgCiAJCQlyZXR1cm4gKHhtbCk7CiAJCX0KQEAgLTk1MSwxODcgKzM1NSwxMCBAQAogICAgICAgICAvLy8gPHJldHVybnM+PC9yZXR1cm5zPgogICAgICAgICBwdWJsaWMgYnl0ZVtdIEdldEFzQnl0ZUFycmF5KCkKICAgICAgICAgewotICAgICAgICAgICByZXR1cm4gR2V0QXNCeXRlQXJyYXkodHJ1ZSk7Ci0gICAgICAgIH0KLSAgICAgICAgLy8vIDxzdW1tYXJ5PgotICAgICAgICAvLy8gU2F2ZXMgYW5kIHJldHVybnMgdGhlIEV4Y2VsIGZpbGVzIGFzIGEgYnl0ZWFycmF5Ci0gICAgICAgIC8vLyBOb3RlIHRoYXQgdGhlIHBhY2thZ2UgaXMgY2xvc2VkIHVwb24gc2F2ZQotICAgICAgICAvLy8gPC9zdW1tYXJ5PgotICAgICAgICAvLy8gPGV4YW1wbGU+ICAgICAgCi0gICAgICAgIC8vLyBFeGFtcGxlIGhvdyB0byByZXR1cm4gYSBkb2N1bWVudCBmcm9tIGEgV2Vic2VydmVyLi4uCi0gICAgICAgIC8vLyA8Y29kZT4gCi0gICAgICAgIC8vLyAgRXhjZWxQYWNrYWdlIHBhY2thZ2U9bmV3IEV4Y2VsUGFja2FnZSgpOwotICAgICAgICAvLy8gIC8qKioqIC4uLiBDcmVhdGUgdGhlIGRvY3VtZW50ICoqKiovCi0gICAgICAgIC8vLyAgQnl0ZVtdIGJpbiA9IHBhY2thZ2UuR2V0QXNCeXRlQXJyYXkoKTsKLSAgICAgICAgLy8vICBSZXNwb25zZS5Db250ZW50VHlwZSA9ICJBcHBsaWNhdGlvbi92bmQubXMtRXhjZWwiOwotICAgICAgICAvLy8gIFJlc3BvbnNlLkFkZEhlYWRlcigiY29udGVudC1kaXNwb3NpdGlvbiIsICJhdHRhY2htZW50OyAgZmlsZW5hbWU9VGhlRmlsZS54bHN4Iik7Ci0gICAgICAgIC8vLyAgUmVzcG9uc2UuQmluYXJ5V3JpdGUoYmluKTsKLSAgICAgICAgLy8vIDwvY29kZT4KLSAgICAgICAgLy8vIDwvZXhhbXBsZT4KLSAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJwYXNzd29yZCI+VGhlIHBhc3N3b3JkIHRvIGVuY3J5cHQgdGhlIHdvcmtib29rIHdpdGguIAotICAgICAgICAvLy8gVGhpcyBwYXJhbWV0ZXIgb3ZlcnJpZGVzIHRoZSBFbmNyeXB0aW9uLlBhc3N3b3JkLjwvcGFyYW0+Ci0gICAgICAgIC8vLyA8cmV0dXJucz48L3JldHVybnM+Ci0gICAgICAgIHB1YmxpYyBieXRlW10gR2V0QXNCeXRlQXJyYXkoc3RyaW5nIHBhc3N3b3JkKQotICAgICAgICB7Ci0gICAgICAgICAgICBpZiAocGFzc3dvcmQgIT0gbnVsbCkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBFbmNyeXB0aW9uLlBhc3N3b3JkID0gcGFzc3dvcmQ7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICByZXR1cm4gR2V0QXNCeXRlQXJyYXkodHJ1ZSk7Ci0gICAgICAgIH0KLSAgICAgICAgaW50ZXJuYWwgYnl0ZVtdIEdldEFzQnl0ZUFycmF5KGJvb2wgc2F2ZSkKLSAgICAgICAgewotICAgICAgICAgICAgaWYgKHNhdmUpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgV29ya2Jvb2suU2F2ZSgpOwotICAgICAgICAgICAgICAgIF9wYWNrYWdlLkNsb3NlKCk7Ci0gICAgICAgICAgICAgICAgX3BhY2thZ2UuU2F2ZShfc3RyZWFtKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIEJ5dGVbXSBieVJldCA9IG5ldyBieXRlW1N0cmVhbS5MZW5ndGhdOwotICAgICAgICAgICAgbG9uZyBwb3MgPSBTdHJlYW0uUG9zaXRpb247ICAgICAgICAgICAgCi0gICAgICAgICAgICBTdHJlYW0uU2VlaygwLCBTZWVrT3JpZ2luLkJlZ2luKTsKLSAgICAgICAgICAgIFN0cmVhbS5SZWFkKGJ5UmV0LCAwLCAoaW50KVN0cmVhbS5MZW5ndGgpOwotCi0gICAgICAgICAgICAvL0VuY3J5cHQgV29ya2Jvb2s/Ci0gICAgICAgICAgICBpZiAoRW5jcnlwdGlvbi5Jc0VuY3J5cHRlZCkKLSAgICAgICAgICAgIHsKLSNpZiAhTU9OTwotICAgICAgICAgICAgICAgIEVuY3J5cHRlZFBhY2thZ2VIYW5kbGVyIGVwaD1uZXcgRW5jcnlwdGVkUGFja2FnZUhhbmRsZXIoKTsKLSAgICAgICAgICAgICAgICB2YXIgbXMgPSBlcGguRW5jcnlwdFBhY2thZ2UoYnlSZXQsIEVuY3J5cHRpb24pOwotICAgICAgICAgICAgICAgIGJ5UmV0ID0gbXMuVG9BcnJheSgpOwotI2VuZGlmCi0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIFN0cmVhbS5TZWVrKHBvcywgU2Vla09yaWdpbi5CZWdpbik7Ci0gICAgICAgICAgICBTdHJlYW0uQ2xvc2UoKTsKLSAgICAgICAgICAgIHJldHVybiBieVJldDsKLSAgICAgICAgfQotICAgICAgICAvLy8gPHN1bW1hcnk+Ci0gICAgICAgIC8vLyBMb2FkcyB0aGUgc3BlY2lmaWVkIHBhY2thZ2UgZGF0YSBmcm9tIGEgc3RyZWFtLgotICAgICAgICAvLy8gPC9zdW1tYXJ5PgotICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImlucHV0Ij5UaGUgaW5wdXQuPC9wYXJhbT4KLSAgICAgICAgcHVibGljIHZvaWQgTG9hZChTdHJlYW0gaW5wdXQpCi0gICAgICAgIHsKLSAgICAgICAgICAgIExvYWQoaW5wdXQsIG5ldyBNZW1vcnlTdHJlYW0oKSwgbnVsbCk7Ci0gICAgICAgIH0KLSAgICAgICAgLy8vIDxzdW1tYXJ5PgotICAgICAgICAvLy8gTG9hZHMgdGhlIHNwZWNpZmllZCBwYWNrYWdlIGRhdGEgZnJvbSBhIHN0cmVhbS4KLSAgICAgICAgLy8vIDwvc3VtbWFyeT4KLSAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJpbnB1dCI+VGhlIGlucHV0LjwvcGFyYW0+Ci0gICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iUGFzc3dvcmQiPlRoZSBwYXNzd29yZCB0byBkZWNyeXB0IHRoZSBkb2N1bWVudDwvcGFyYW0+Ci0gICAgICAgIHB1YmxpYyB2b2lkIExvYWQoU3RyZWFtIGlucHV0LCBzdHJpbmcgUGFzc3dvcmQpCi0gICAgICAgIHsKLSAgICAgICAgICAgIExvYWQoaW5wdXQsIG5ldyBNZW1vcnlTdHJlYW0oKSwgUGFzc3dvcmQpOwotICAgICAgICB9Ci0gICAgICAgIC8vLyA8c3VtbWFyeT4KLSAgICAgICAgLy8vIAotICAgICAgICAvLy8gPC9zdW1tYXJ5PgotICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImlucHV0Ij48L3BhcmFtPiAgICAKLSAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJvdXRwdXQiPjwvcGFyYW0+Ci0gICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iUGFzc3dvcmQiPjwvcGFyYW0+Ci0gICAgICAgIHByaXZhdGUgdm9pZCBMb2FkKFN0cmVhbSBpbnB1dCwgU3RyZWFtIG91dHB1dCwgc3RyaW5nIFBhc3N3b3JkKQotICAgICAgICB7Ci0gICAgICAgICAgICAvL1JlbGVhc2Ugc29tZSByZXNvdXJjZXM6Ci0gICAgICAgICAgICBpZiAodGhpcy5fcGFja2FnZSAhPSBudWxsKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIHRoaXMuX3BhY2thZ2UuQ2xvc2UoKTsKLSAgICAgICAgICAgICAgICB0aGlzLl9wYWNrYWdlID0gbnVsbDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmICh0aGlzLl9zdHJlYW0gIT0gbnVsbCkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICB0aGlzLl9zdHJlYW0uQ2xvc2UoKTsKLSAgICAgICAgICAgICAgICB0aGlzLl9zdHJlYW0uRGlzcG9zZSgpOwotICAgICAgICAgICAgICAgIHRoaXMuX3N0cmVhbSA9IG51bGw7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBfaXNFeHRlcm5hbFN0cmVhbSA9IHRydWU7Ci0gICAgICAgICAgICBpZiAoaW5wdXQuTGVuZ3RoID09IDApIC8vIFRlbXBsYXRlIGlzIGJsYW5rLCBDb25zdHJ1Y3QgbmV3Ci0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgX3N0cmVhbSA9IG91dHB1dDsKLSAgICAgICAgICAgICAgICBDb25zdHJ1Y3ROZXdGaWxlKFBhc3N3b3JkKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBTdHJlYW0gbXM7Ci0gICAgICAgICAgICAgICAgdGhpcy5fc3RyZWFtID0gb3V0cHV0OwotICAgICAgICAgICAgICAgIGlmIChQYXNzd29yZCAhPSBudWxsKQotICAgICAgICAgICAgICAgIHsKLSNpZiAhTU9OTwotICAgICAgICAgICAgICAgICAgICBTdHJlYW0gZW5jclN0cmVhbSA9IG5ldyBNZW1vcnlTdHJlYW0oKTsKLSAgICAgICAgICAgICAgICAgICAgQ29weVN0cmVhbShpbnB1dCwgcmVmIGVuY3JTdHJlYW0pOwotICAgICAgICAgICAgICAgICAgICBFbmNyeXB0ZWRQYWNrYWdlSGFuZGxlciBlcGggPSBuZXcgRW5jcnlwdGVkUGFja2FnZUhhbmRsZXIoKTsKLSAgICAgICAgICAgICAgICAgICAgRW5jcnlwdGlvbi5QYXNzd29yZCA9IFBhc3N3b3JkOwotICAgICAgICAgICAgICAgICAgICBtcyA9IGVwaC5EZWNyeXB0UGFja2FnZSgoTWVtb3J5U3RyZWFtKWVuY3JTdHJlYW0sIEVuY3J5cHRpb24pOwotI2VuZGlmCi0jaWYgTU9OTwotICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTm90U3VwcG9ydGVkRXhjZXB0aW9uKCJFbmNyeXB0aW9uIGlzIG5vdCBzdXBwb3J0ZWQgdW5kZXIgTW9uby4iKTsKLSNlbmRpZgotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICBtcyA9IG5ldyBNZW1vcnlTdHJlYW0oKTsKLSAgICAgICAgICAgICAgICAgICAgQ29weVN0cmVhbShpbnB1dCwgcmVmIG1zKTsKLSAgICAgICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgICAgICB0cnkKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgIC8vdGhpcy5fcGFja2FnZSA9IFBhY2thZ2UuT3Blbih0aGlzLl9zdHJlYW0sIEZpbGVNb2RlLk9wZW4sIEZpbGVBY2Nlc3MuUmVhZFdyaXRlKTsKLSAgICAgICAgICAgICAgICAgICAgX3BhY2thZ2UgPSBuZXcgUGFja2FnaW5nLlppcFBhY2thZ2UobXMpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBjYXRjaCAoRXhjZXB0aW9uIGV4KQotICAgICAgICAgICAgICAgIHsKLSNpZiAhTU9OTwotICAgICAgICAgICAgICAgICAgICBFbmNyeXB0ZWRQYWNrYWdlSGFuZGxlciBlcGggPSBuZXcgRW5jcnlwdGVkUGFja2FnZUhhbmRsZXIoKTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKFBhc3N3b3JkID09IG51bGwgJiYgQ29tcG91bmREb2N1bWVudC5Jc1N0b3JhZ2VJTG9ja0J5dGVzKENvbXBvdW5kRG9jdW1lbnQuR2V0TG9ja2J5dGUoKE1lbW9yeVN0cmVhbSlfc3RyZWFtKSkgPT0gMCkKLSAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEV4Y2VwdGlvbigiQ2FuIG5vdCBvcGVuIHRoZSBwYWNrYWdlLiBQYWNrYWdlIGlzIGFuIE9MRSBjb21wb3VuZCBkb2N1bWVudC4gSWYgdGhpcyBpcyBhbiBlbmNyeXB0ZWQgcGFja2FnZSwgcGxlYXNlIHN1cHBseSB0aGUgcGFzc3dvcmQiLCBleCk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdzsKLSAgICAgICAgICAgICAgICAgICAgfQotI2VuZGlmCi0jaWYgTU9OTwotICAgICAgICAgICAgICAgICAgICB0aHJvdzsKLSNlbmRpZgotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIH0gICAgICAgICAgICAKLSAgICAgICAgICAgIC8vQ2xlYXIgdGhlIHdvcmtib29rIHNvIHRoYXQgaXQgZ2V0cyByZWluaXRpYWxpemVkIG5leHQgdGltZQotICAgICAgICAgICAgdGhpcy5fd29ya2Jvb2sgPSBudWxsOwotICAgICAgICB9Ci0gICAgICAgIHN0YXRpYyBvYmplY3QgX2xvY2s9bmV3IG9iamVjdCgpOwotICAgICAgICAvLy8gPHN1bW1hcnk+Ci0gICAgICAgIC8vLyBDb3BpZXMgdGhlIGlucHV0IHN0cmVhbSB0byB0aGUgb3V0cHV0IHN0cmVhbS4KLSAgICAgICAgLy8vIDwvc3VtbWFyeT4KLSAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJpbnB1dFN0cmVhbSI+VGhlIGlucHV0IHN0cmVhbS48L3BhcmFtPgotICAgICAgICAvLy8gPHBhcmFtIG5hbWU9Im91dHB1dFN0cmVhbSI+VGhlIG91dHB1dCBzdHJlYW0uPC9wYXJhbT4KLSAgICAgICAgaW50ZXJuYWwgc3RhdGljIHZvaWQgQ29weVN0cmVhbShTdHJlYW0gaW5wdXRTdHJlYW0sIHJlZiBTdHJlYW0gb3V0cHV0U3RyZWFtKQotICAgICAgICB7Ci0gICAgICAgICAgICBpZiAoIWlucHV0U3RyZWFtLkNhblJlYWQpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgKG5ldyBFeGNlcHRpb24oIkNhbiBub3QgcmVhZCBmcm9tIGlucHV0c3RyZWFtIikpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKCFvdXRwdXRTdHJlYW0uQ2FuV3JpdGUpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgdGhyb3cgKG5ldyBFeGNlcHRpb24oIkNhbiBub3Qgd3JpdGUgdG8gb3V0cHV0c3RyZWFtIikpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgaWYgKGlucHV0U3RyZWFtLkNhblNlZWspCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgaW5wdXRTdHJlYW0uU2VlaygwLCBTZWVrT3JpZ2luLkJlZ2luKTsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgICAgIGNvbnN0IGludCBidWZmZXJMZW5ndGggPSA4MDk2OwotICAgICAgICAgICAgICAgIHZhciBidWZmZXIgPSBuZXcgQnl0ZVtidWZmZXJMZW5ndGhdOwotICAgICAgICAgICAgICAgIGxvY2sgKF9sb2NrKQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgaW50IGJ5dGVzUmVhZCA9IGlucHV0U3RyZWFtLlJlYWQoYnVmZmVyLCAwLCBidWZmZXJMZW5ndGgpOwotICAgICAgICAgICAgICAgICAgICAvLyB3cml0ZSB0aGUgcmVxdWlyZWQgYnl0ZXMKLSAgICAgICAgICAgICAgICAgICAgd2hpbGUgKGJ5dGVzUmVhZCA+IDApCi0gICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIG91dHB1dFN0cmVhbS5Xcml0ZShidWZmZXIsIDAsIGJ5dGVzUmVhZCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBieXRlc1JlYWQgPSBpbnB1dFN0cmVhbS5SZWFkKGJ1ZmZlciwgMCwgYnVmZmVyTGVuZ3RoKTsKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICBvdXRwdXRTdHJlYW0uRmx1c2goKTsKLSAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHZhciByZXN1bHQgPSBuZXcgTWVtb3J5U3RyZWFtKCk7CisgICAgICAgICAgICBXb3JrYm9vay5TYXZlKCk7CisgICAgICAgICAgICBQYWNrYWdlLlNhdmUocmVzdWx0KTsKKyAgICAgICAgICAgIHJldHVybiByZXN1bHQuVG9BcnJheSgpOwogICAgICAgICB9CiAgICAgfQogfQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL0VQUGx1cy9FeGNlbFByb3RlY3RlZFJhbmdlLmNzIGIvRVBQbHVzL0V4Y2VsUHJvdGVjdGVkUmFuZ2UuY3MKaW5kZXggNmE5ZDQ1Yy4uYmI2Njk0NSAxMDA2NDQKLS0tIGEvRVBQbHVzL0V4Y2VsUHJvdGVjdGVkUmFuZ2UuY3MKKysrIGIvRVBQbHVzL0V4Y2VsUHJvdGVjdGVkUmFuZ2UuY3MKQEAgLTEsNjAgKzEsOCBAQAog77u/dXNpbmcgT2ZmaWNlT3BlblhtbC5VdGlsczsKLXVzaW5nIFN5c3RlbTsKLXVzaW5nIFN5c3RlbS5Db2xsZWN0aW9ucy5HZW5lcmljOwotdXNpbmcgU3lzdGVtLkdsb2JhbGl6YXRpb247Ci11c2luZyBTeXN0ZW0uTGlucTsKLXVzaW5nIFN5c3RlbS5TZWN1cml0eS5DcnlwdG9ncmFwaHk7Ci11c2luZyBTeXN0ZW0uVGV4dDsKIHVzaW5nIFN5c3RlbS5YbWw7CiAKIG5hbWVzcGFjZSBPZmZpY2VPcGVuWG1sCiB7Ci0gICAgLy8vIDxzdW1tYXJ5PgotICAgIC8vLyBBbGdvcml0aG0gZm9yIHBhc3N3b3JkIGhhc2gKLSAgICAvLy8gPC9zdW1tYXJ5PgotICAgIGludGVybmFsIGVudW0gZVByb3RlY3RlZFJhbmdlQWxnb3JpdGhtCi0gICAgewotICAgICAgICAvLy8gPHN1bW1hcnk+Ci0gICAgICAgIC8vLyBTcGVjaWZpZXMgdGhhdCB0aGUgTUQyIGFsZ29yaXRobSwgYXMgZGVmaW5lZCBieSBSRkMgMTMxOSwgc2hhbGwgYmUgdXNlZC4KLSAgICAgICAgLy8vIDwvc3VtbWFyeT4KLSAgICAgICAgTUQyLAotICAgICAgICAvLy8gPHN1bW1hcnk+Ci0gICAgICAgIC8vLyBTcGVjaWZpZXMgdGhhdCB0aGUgTUQ0IGFsZ29yaXRobSwgYXMgZGVmaW5lZCBieSBSRkMgMTMxOSwgc2hhbGwgYmUgdXNlZC4KLSAgICAgICAgLy8vIDwvc3VtbWFyeT4KLSAgICAgICAgTUQ0LAotICAgICAgICAvLy8gPHN1bW1hcnk+Ci0gICAgICAgIC8vLyBTcGVjaWZpZXMgdGhhdCB0aGUgTUQ1IGFsZ29yaXRobSwgYXMgZGVmaW5lZCBieSBSRkMgMTMxOSwgc2hhbGwgYmUgdXNlZC4KLSAgICAgICAgLy8vIDwvc3VtbWFyeT4KLSAgICAgICAgTUQ1LAotICAgICAgICAvLy8gPHN1bW1hcnk+Ci0gICAgICAgIC8vLyBTcGVjaWZpZXMgdGhhdCB0aGUgUklQRU1ELTEyOCBhbGdvcml0aG0sIGFzIGRlZmluZWQgYnkgUkZDIDEzMTksIHNoYWxsIGJlIHVzZWQuCi0gICAgICAgIC8vLyA8L3N1bW1hcnk+Ci0gICAgICAgIFJJUEVNRDEyOCwKLSAgICAgICAgLy8vIDxzdW1tYXJ5PgotICAgICAgICAvLy8gU3BlY2lmaWVzIHRoYXQgdGhlIFJJUEVNRC0xNjAgYWxnb3JpdGhtLCBhcyBkZWZpbmVkIGJ5IElTTy9JRUMxMDExOC0zOjIwMDQgc2hhbGwgYmUgdXNlZC4KLSAgICAgICAgLy8vIDwvc3VtbWFyeT4KLSAgICAgICAgUklQRU1EMTYwLCAKLSAgICAgICAgLy8vIDxzdW1tYXJ5PgotICAgICAgICAvLy8gU3BlY2lmaWVzIHRoYXQgdGhlIFNIQS0xIGFsZ29yaXRobSwgYXMgZGVmaW5lZCBieSBJU08vSUVDIDEwMTE4LTM6MjAwNCBzaGFsbCBiZSB1c2VkLgotICAgICAgICAvLy8gPC9zdW1tYXJ5PgotICAgICAgICBTSEExLAotICAgICAgICAvLy8gPHN1bW1hcnk+Ci0gICAgICAgIC8vLyBTcGVjaWZpZXMgdGhhdCB0aGUgU0hBLTI1NiBhbGdvcml0aG0sIGFzIGRlZmluZWQgYnkgSVNPL0lFQzEwMTE4LTM6MjAwNCBzaGFsbCBiZSB1c2VkLgotICAgICAgICAvLy8gPC9zdW1tYXJ5PgotICAgICAgICBTSEEyNTYsIAotICAgICAgICAvLy8gPHN1bW1hcnk+Ci0gICAgICAgIC8vLyBTcGVjaWZpZXMgdGhhdCB0aGUgU0hBLTM4NCBhbGdvcml0aG0sIGFzIGRlZmluZWQgYnkgSVNPL0lFQyAxMDExOC0zOjIwMDQgc2hhbGwgYmUgdXNlZC4KLSAgICAgICAgLy8vIDwvc3VtbWFyeT4KLSAgICAgICAgU0hBMzg0LAotICAgICAgICAvLy8gPHN1bW1hcnk+Ci0gICAgICAgIC8vLyBTcGVjaWZpZXMgdGhhdCB0aGUgU0hBLTUxMiBhbGdvcml0aG0sIGFzIGRlZmluZWQgYnkgSVNPL0lFQzEwMTE4LTM6MjAwNCBzaGFsbCBiZSB1c2VkLgotICAgICAgICAvLy8gPC9zdW1tYXJ5PgotICAgICAgICBTSEE1MTIsIAotICAgICAgICAvLy8gPHN1bW1hcnk+Ci0gICAgICAgIC8vLyBTcGVjaWZpZXMgdGhhdCB0aGUgV0hJUkxQT09MIGFsZ29yaXRobSwgYXMgZGVmaW5lZCBieSBJU08vSUVDIDEwMTE4LTM6MjAwNCBzaGFsbCBiZSB1c2VkLgotICAgICAgICAvLy8gPC9zdW1tYXJ5PgotICAgICAgICBXSElSTFBPT0wKLSAgICB9CiAgICAgcHVibGljIGNsYXNzIEV4Y2VsUHJvdGVjdGVkUmFuZ2UgOiBYbWxIZWxwZXIKICAgICB7CiAgICAgICAgIHB1YmxpYyBzdHJpbmcgTmFtZQpAQCAtOTIsMTAzICs0MCw1IEBACiAgICAgICAgICAgICBOYW1lID0gbmFtZTsKICAgICAgICAgICAgIEFkZHJlc3MgPSBhZGRyZXNzOwogICAgICAgICB9Ci0gICAgICAgIC8vLyA8c3VtbWFyeT4KLSAgICAgICAgLy8vIFNldHMgdGhlIHBhc3N3b3JkIGZvciB0aGUgcmFuZ2UKLSAgICAgICAgLy8vIDwvc3VtbWFyeT4KLSAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJwYXNzd29yZCI+PC9wYXJhbT4KLSAgICAgICAgcHVibGljIHZvaWQgU2V0UGFzc3dvcmQoc3RyaW5nIHBhc3N3b3JkKQotICAgICAgICB7Ci0gICAgICAgICAgICB2YXIgYnlQd2QgPSBFbmNvZGluZy5Vbmljb2RlLkdldEJ5dGVzKHBhc3N3b3JkKTsKLSAgICAgICAgICAgIHZhciBybmQgPSBSYW5kb21OdW1iZXJHZW5lcmF0b3IuQ3JlYXRlKCk7Ci0gICAgICAgICAgICB2YXIgYnlTYWx0PW5ldyBieXRlWzE2XTsKLSAgICAgICAgICAgIHJuZC5HZXRCeXRlcyhieVNhbHQpOwotICAgICAgICAgICAgCi0gICAgICAgICAgICAvL0RlZmF1bHQgU0hBNTEyIGFuZCAxMDAwMCBzcGlucwotICAgICAgICAgICAgQWxnb3JpdGhtPWVQcm90ZWN0ZWRSYW5nZUFsZ29yaXRobS5TSEE1MTI7Ci0gICAgICAgICAgICBTcGluQ291bnQgPSBTcGluQ291bnQgPCAxMDAwMDAgPyAxMDAwMDAgOiBTcGluQ291bnQ7Ci0gICAgICAgICAgICAKLSAgICAgICAgICAgIC8vQ29tYmluZSBzYWx0IGFuZCBwYXNzd29yZCBhbmQgY2FsY3VsYXRlIHRoZSBpbml0aWFsIGhhc2gKLSAgICAgICAgICAgIHZhciBocD1uZXcgU0hBNTEyQ3J5cHRvU2VydmljZVByb3ZpZGVyKCk7Ci0gICAgICAgICAgICB2YXIgYnVmZmVyPW5ldyBieXRlW2J5UHdkLkxlbmd0aCArIGJ5U2FsdC5MZW5ndGhdOwotICAgICAgICAgICAgQXJyYXkuQ29weShieVNhbHQsIGJ1ZmZlciwgYnlTYWx0Lkxlbmd0aCk7Ci0gICAgICAgICAgICBBcnJheS5Db3B5KGJ5UHdkLCAwLCBidWZmZXIsIDE2LCBieVB3ZC5MZW5ndGgpOwotICAgICAgICAgICAgdmFyIGhhc2ggPSBocC5Db21wdXRlSGFzaChidWZmZXIpOwotCi0gICAgICAgICAgICAvL05vdyBpdGVyYXRlIHRoZSBudW1iZXIgb2Ygc3Bpbm5zLgotICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBTcGluQ291bnQ7IGkrKykKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBidWZmZXI9bmV3IGJ5dGVbaGFzaC5MZW5ndGgrNF07Ci0gICAgICAgICAgICAgICAgQXJyYXkuQ29weShoYXNoLCBidWZmZXIsIGhhc2guTGVuZ3RoKTsKLSAgICAgICAgICAgICAgICBBcnJheS5Db3B5KEJpdENvbnZlcnRlci5HZXRCeXRlcyhpKSwgMCwgYnVmZmVyLCBoYXNoLkxlbmd0aCwgNCk7Ci0gICAgICAgICAgICAgICAgaGFzaCA9IGhwLkNvbXB1dGVIYXNoKGJ1ZmZlcik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBTYWx0ID0gQ29udmVydC5Ub0Jhc2U2NFN0cmluZyhieVNhbHQpOwotICAgICAgICAgICAgSGFzaCA9IENvbnZlcnQuVG9CYXNlNjRTdHJpbmcoaGFzaCk7ICAgICAgICAgICAgCi0gICAgICAgIH0KLSAgICAgICAgcHVibGljIHN0cmluZyBTZWN1cml0eURlc2NyaXB0b3IKLSAgICAgICAgewotICAgICAgICAgICAgZ2V0Ci0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIEdldFhtbE5vZGVTdHJpbmcoIkBzZWN1cml0eURlc2NyaXB0b3IiKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHNldAotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIFNldFhtbE5vZGVTdHJpbmcoIkBzZWN1cml0eURlc2NyaXB0b3IiLHZhbHVlKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBpbnRlcm5hbCBpbnQgU3BpbkNvdW50Ci0gICAgICAgIHsKLSAgICAgICAgICAgIGdldAotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIHJldHVybiBHZXRYbWxOb2RlSW50KCJAc3BpbkNvdW50Iik7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBzZXQKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBTZXRYbWxOb2RlU3RyaW5nKCJAc3BpbkNvdW50Iix2YWx1ZS5Ub1N0cmluZyhDdWx0dXJlSW5mby5JbnZhcmlhbnRDdWx0dXJlKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgaW50ZXJuYWwgc3RyaW5nIFNhbHQKLSAgICAgICAgewotICAgICAgICAgICAgZ2V0Ci0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIEdldFhtbE5vZGVTdHJpbmcoIkBzYWx0VmFsdWUiKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHNldAotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIFNldFhtbE5vZGVTdHJpbmcoIkBzYWx0VmFsdWUiLCB2YWx1ZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgaW50ZXJuYWwgc3RyaW5nIEhhc2gKLSAgICAgICAgewotICAgICAgICAgICAgZ2V0Ci0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIEdldFhtbE5vZGVTdHJpbmcoIkBoYXNoVmFsdWUiKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIHNldAotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIFNldFhtbE5vZGVTdHJpbmcoIkBoYXNoVmFsdWUiLCB2YWx1ZSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgaW50ZXJuYWwgZVByb3RlY3RlZFJhbmdlQWxnb3JpdGhtIEFsZ29yaXRobQotICAgICAgICB7Ci0gICAgICAgICAgICBnZXQKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICB2YXIgdj1HZXRYbWxOb2RlU3RyaW5nKCJAYWxnb3JpdGhtTmFtZSIpOwotICAgICAgICAgICAgICAgIHJldHVybiAoZVByb3RlY3RlZFJhbmdlQWxnb3JpdGhtKUVudW0uUGFyc2UodHlwZW9mKGVQcm90ZWN0ZWRSYW5nZUFsZ29yaXRobSksIHYuUmVwbGFjZSgiLSIsICIiKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBzZXQKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICB2YXIgdiA9IHZhbHVlLlRvU3RyaW5nKCk7Ci0gICAgICAgICAgICAgICAgaWYodi5TdGFydHNXaXRoKCJTSEEiKSkKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgIHY9di5JbnNlcnQoMywiLSIpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBlbHNlIGlmKHYuU3RhcnRzV2l0aCgiUklQRU1EIikpCi0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICB2PXYuSW5zZXJ0KDYsIi0iKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgU2V0WG1sTm9kZVN0cmluZygiQGFsZ29yaXRobU5hbWUiLCB2KTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQogICAgIH0KIH0KZGlmZiAtLWdpdCBhL0VQUGx1cy9FeGNlbFByb3RlY3Rpb24uY3MgYi9FUFBsdXMvRXhjZWxQcm90ZWN0aW9uLmNzCmluZGV4IDNiZWU2MWUuLjZlMzA3YTMgMTAwNjQ0Ci0tLSBhL0VQUGx1cy9FeGNlbFByb3RlY3Rpb24uY3MKKysrIGIvRVBQbHVzL0V4Y2VsUHJvdGVjdGlvbi5jcwpAQCAtMjksMTIgKzI5LDcgQEAKICAqIEphbiBLw6RsbG1hbgkJICAgIEFkZGVkCQkxMC1BVUctMjAxMAogICogSmFuIEvDpGxsbWFuCQkgICAgTGljZW5zZSBjaGFuZ2VkIEdQTC0tPkxHUEwgMjAxMS0xMi0yNwogICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi11c2luZyBTeXN0ZW07Ci11c2luZyBTeXN0ZW0uQ29sbGVjdGlvbnMuR2VuZXJpYzsKLXVzaW5nIFN5c3RlbS5UZXh0OwogdXNpbmcgU3lzdGVtLlhtbDsKLXVzaW5nIE9mZmljZU9wZW5YbWwuVXRpbHM7Ci11c2luZyBPZmZpY2VPcGVuWG1sLkVuY3J5cHRpb247CiBuYW1lc3BhY2UgT2ZmaWNlT3BlblhtbAogewogICAgIC8vLyA8c3VtbWFyeT4KQEAgLTQ5LDIyICs0NCw2IEBACiAgICAgICAgIHsKICAgICAgICAgICAgIFNjaGVtYU5vZGVPcmRlciA9IHdiLlNjaGVtYU5vZGVPcmRlcjsKICAgICAgICAgfQotICAgICAgICBjb25zdCBzdHJpbmcgd29ya2Jvb2tQYXNzd29yZFBhdGggPSAiZDp3b3JrYm9va1Byb3RlY3Rpb24vQHdvcmtib29rUGFzc3dvcmQiOwotICAgICAgICAvLy8gPHN1bW1hcnk+Ci0gICAgICAgIC8vLyBTZXRzIGEgcGFzc3dvcmQgZm9yIHRoZSB3b3JrYm9vay4gVGhpcyBkb2VzIG5vdCBlbmNyeXB0IHRoZSB3b3JrYm9vay4gCi0gICAgICAgIC8vLyA8L3N1bW1hcnk+Ci0gICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iUGFzc3dvcmQiPlRoZSBwYXNzd29yZC4gPC9wYXJhbT4KLSAgICAgICAgcHVibGljIHZvaWQgU2V0UGFzc3dvcmQoc3RyaW5nIFBhc3N3b3JkKQotICAgICAgICB7Ci0gICAgICAgICAgICBpZihzdHJpbmcuSXNOdWxsT3JFbXB0eShQYXNzd29yZCkpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgRGVsZXRlTm9kZSh3b3JrYm9va1Bhc3N3b3JkUGF0aCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgU2V0WG1sTm9kZVN0cmluZyh3b3JrYm9va1Bhc3N3b3JkUGF0aCwgKChpbnQpRW5jcnlwdGVkUGFja2FnZUhhbmRsZXIuQ2FsY3VsYXRlUGFzc3dvcmRIYXNoKFBhc3N3b3JkKSkuVG9TdHJpbmcoIngiKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KICAgICAgICAgY29uc3Qgc3RyaW5nIGxvY2tTdHJ1Y3R1cmVQYXRoID0gImQ6d29ya2Jvb2tQcm90ZWN0aW9uL0Bsb2NrU3RydWN0dXJlIjsKICAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgICAvLy8gTG9ja3MgdGhlIHN0cnVjdHVyZSx3aGljaCBwcmV2ZW50cyB1c2VycyBmcm9tIGFkZGluZyBvciBkZWxldGluZyB3b3Jrc2hlZXRzIG9yIGZyb20gZGlzcGxheWluZyBoaWRkZW4gd29ya3NoZWV0cy4KZGlmZiAtLWdpdCBhL0VQUGx1cy9FeGNlbFJhbmdlQmFzZS5jcyBiL0VQUGx1cy9FeGNlbFJhbmdlQmFzZS5jcwppbmRleCBkM2MzYzIwLi5hNGNmMTk4IDEwMDY0NAotLS0gYS9FUFBsdXMvRXhjZWxSYW5nZUJhc2UuY3MKKysrIGIvRVBQbHVzL0V4Y2VsUmFuZ2VCYXNlLmNzCkBAIC03MzYsNyArNzM2LDcgQEAKIAkJCXRvUm93ID0gYWRkci5fdG9Sb3cgPiBkLl90b1JvdyA/IGQuX3RvUm93IDogYWRkci5fdG9Sb3c7CiAJCQl0b0NvbCA9IGFkZHIuX3RvQ29sID4gZC5fdG9Db2wgPyBkLl90b0NvbCA6IGFkZHIuX3RvQ29sOwogCi0JCQlpZiAoYWRkci5fZnJvbUNvbCA9PSBmcm9tUm93ICYmIGFkZHIuX2Zyb21Db2wgPT0gYWRkci5fZnJvbUNvbCAmJiBhZGRyLl90b1JvdyA9PSB0b1JvdyAmJiBhZGRyLl90b0NvbCA9PSBfdG9Db2wpCisJCQlpZiAoYWRkci5fZnJvbUNvbCA9PSBmcm9tUm93ICYmIGFkZHIuX3RvUm93ID09IHRvUm93ICYmIGFkZHIuX3RvQ29sID09IF90b0NvbCkKIAkJCXsKIAkJCQlyZXR1cm4gYWRkcjsKIAkJCX0KQEAgLTI2NDUsNyArMjY0NSw2IEBACiAKIAkJcHVibGljIHZvaWQgRGlzcG9zZSgpCiAJCXsKLQkJCS8vX3dvcmtzaGVldCA9IG51bGw7ICAgICAgICAgICAgCiAJCX0KIAogCQkjZW5kcmVnaW9uCmRpZmYgLS1naXQgYS9FUFBsdXMvRXhjZWxTaGVldFByb3RlY3Rpb24uY3MgYi9FUFBsdXMvRXhjZWxTaGVldFByb3RlY3Rpb24uY3MKaW5kZXggODNjNjQ5Yy4uMmNhYTdiOSAxMDA2NDQKLS0tIGEvRVBQbHVzL0V4Y2VsU2hlZXRQcm90ZWN0aW9uLmNzCisrKyBiL0VQUGx1cy9FeGNlbFNoZWV0UHJvdGVjdGlvbi5jcwpAQCAtMjksMTMgKzI5LDcgQEAKICAqIEphbiBLw6RsbG1hbgkJICAgIEluaXRpYWwgUmVsZWFzZQkJICAgICAgICAyMDEwLTAzLTE0CiAgKiBKYW4gS8OkbGxtYW4JCSAgICBMaWNlbnNlIGNoYW5nZWQgR1BMLS0+TEdQTCAyMDExLTEyLTI3CiAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLXVzaW5nIFN5c3RlbTsKLXVzaW5nIFN5c3RlbS5Db2xsZWN0aW9ucy5HZW5lcmljOwotdXNpbmcgU3lzdGVtLlRleHQ7CiB1c2luZyBTeXN0ZW0uWG1sOwotdXNpbmcgU3lzdGVtLlNlY3VyaXR5LkNyeXB0b2dyYXBoeTsKLXVzaW5nIE9mZmljZU9wZW5YbWwuVXRpbHM7Ci11c2luZyBPZmZpY2VPcGVuWG1sLkVuY3J5cHRpb247CiAKIG5hbWVzcGFjZSBPZmZpY2VPcGVuWG1sCiB7CkBAIC0zMDQsMzAgKzI5OCw1IEBACiAgICAgICAgICAgICAgICAgU2V0WG1sTm9kZUJvb2woX2FsbG93UGl2b3RUYWJsZXNQYXRoLCAhdmFsdWUsIHRydWUpOwogICAgICAgICAgICAgfQogICAgICAgICB9Ci0KLSAgICAgICAgcHJpdmF0ZSBjb25zdCBzdHJpbmcgX3Bhc3N3b3JkUGF0aCA9ICJkOnNoZWV0UHJvdGVjdGlvbi9AcGFzc3dvcmQiOwotICAgICAgICAvLy8gPHN1bW1hcnk+Ci0gICAgICAgIC8vLyBTZXRzIGEgcGFzc3dvcmQgZm9yIHRoZSBzaGVldC4KLSAgICAgICAgLy8vIDwvc3VtbWFyeT4KLSAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJQYXNzd29yZCI+PC9wYXJhbT4KLSAgICAgICAgcHVibGljIHZvaWQgU2V0UGFzc3dvcmQoc3RyaW5nIFBhc3N3b3JkKQotICAgICAgICB7Ci0gICAgICAgICAgICBpZiAoSXNQcm90ZWN0ZWQgPT0gZmFsc2UpIElzUHJvdGVjdGVkID0gdHJ1ZTsKLQotICAgICAgICAgICAgUGFzc3dvcmQgPSBQYXNzd29yZC5UcmltKCk7Ci0gICAgICAgICAgICBpZiAoUGFzc3dvcmQgPT0gIiIpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgdmFyIG5vZGUgPSBUb3BOb2RlLlNlbGVjdFNpbmdsZU5vZGUoX3Bhc3N3b3JkUGF0aCwgTmFtZVNwYWNlTWFuYWdlcik7Ci0gICAgICAgICAgICAgICAgaWYgKG5vZGUgIT0gbnVsbCkKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgIChub2RlIGFzIFhtbEF0dHJpYnV0ZSkuT3duZXJFbGVtZW50LkF0dHJpYnV0ZXMuUmVtb3ZlKG5vZGUgYXMgWG1sQXR0cmlidXRlKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgcmV0dXJuOwotICAgICAgICAgICAgfQotCi0gICAgICAgICAgICBpbnQgaGFzaCA9IEVuY3J5cHRlZFBhY2thZ2VIYW5kbGVyLkNhbGN1bGF0ZVBhc3N3b3JkSGFzaChQYXNzd29yZCk7Ci0gICAgICAgICAgICBTZXRYbWxOb2RlU3RyaW5nKF9wYXNzd29yZFBhdGgsICgoaW50KWhhc2gpLlRvU3RyaW5nKCJ4IikpOwotICAgICAgICB9Ci0KICAgICB9CiB9CmRpZmYgLS1naXQgYS9FUFBsdXMvRXhjZWxTdHlsZXMuY3MgYi9FUFBsdXMvRXhjZWxTdHlsZXMuY3MKaW5kZXggNjJkZjMwOS4uY2ZhZWQ0ZCAxMDA2NDQKLS0tIGEvRVBQbHVzL0V4Y2VsU3R5bGVzLmNzCisrKyBiL0VQUGx1cy9FeGNlbFN0eWxlcy5jcwpAQCAtNCw3ICs0LDcgQEAKICAqIEVQUGx1cyBwcm92aWRlcyBzZXJ2ZXItc2lkZSBnZW5lcmF0aW9uIG9mIEV4Y2VsIDIwMDcvMjAxMCBzcHJlYWRzaGVldHMuCiAgKiBTZWUgaHR0cDovL3d3dy5jb2RlcGxleC5jb20vRVBQbHVzIGZvciBkZXRhaWxzLgogICoKLSAqIENvcHlyaWdodCAoQykgMjAxMSAgSmFuIEvkbGxtYW4KKyAqIENvcHlyaWdodCAoQykgMjAxMSAgSmFuIEvvv71sbG1hbgogICoKICAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKQEAgLTI2LDE1ICsyNiwxMyBAQAogICogCiAgKiBBdXRob3IJCQkJCQkJQ2hhbmdlCQkJCQkJRGF0ZQogICogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCi0gKiBKYW4gS+RsbG1hbgkJICAgIEluaXRpYWwgUmVsZWFzZQkJICAgICAgICAyMDA5LTEwLTAxCi0gKiBKYW4gS+RsbG1hbgkJICAgIExpY2Vuc2UgY2hhbmdlZCBHUEwtLT5MR1BMIDIwMTEtMTItMjcKKyAqIEphbiBL77+9bGxtYW4JCSAgICBJbml0aWFsIFJlbGVhc2UJCSAgICAgICAgMjAwOS0xMC0wMQorICogSmFuIEvvv71sbG1hbgkJICAgIExpY2Vuc2UgY2hhbmdlZCBHUEwtLT5MR1BMIDIwMTEtMTItMjcKICAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwogdXNpbmcgU3lzdGVtOwogdXNpbmcgU3lzdGVtLlhtbDsKIHVzaW5nIFN5c3RlbS5MaW5xOwogdXNpbmcgU3lzdGVtLkNvbGxlY3Rpb25zLkdlbmVyaWM7Ci11c2luZyBPZmZpY2VPcGVuWG1sLkZvcm11bGFQYXJzaW5nLkV4Y2VsLkZ1bmN0aW9ucy5Mb2dpY2FsOwotdXNpbmcgZHJhdz1TeXN0ZW0uRHJhd2luZzsKIHVzaW5nIE9mZmljZU9wZW5YbWwuU3R5bGU7CiB1c2luZyBPZmZpY2VPcGVuWG1sLlN0eWxlLlhtbEFjY2VzczsKIHVzaW5nIE9mZmljZU9wZW5YbWwuU3R5bGUuRHhmOwpAQCAtMzQwLDcgKzMzOCw2IEBACiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgd3MuU2V0U3R5bGUocm93TnVtLCAwLCBzKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGNzZS5EaXNwb3NlKCk7CiAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgaWYgKHN0eWxlQ2FzaGUuQ29udGFpbnNLZXkocykpCiAgICAgICAgICAgICAgICAgICAgIHsKZGlmZiAtLWdpdCBhL0VQUGx1cy9FeGNlbFdvcmtib29rLmNzIGIvRVBQbHVzL0V4Y2VsV29ya2Jvb2suY3MKaW5kZXggYmEwMjU2MC4uZjUyOTgyNiAxMDA2NDQKLS0tIGEvRVBQbHVzL0V4Y2VsV29ya2Jvb2suY3MKKysrIGIvRVBQbHVzL0V4Y2VsV29ya2Jvb2suY3MKQEAgLTcwLDcgKzcwLDcgQEAKIAkvLy8gUmVwcmVzZW50cyB0aGUgRXhjZWwgd29ya2Jvb2sgYW5kIHByb3ZpZGVzIGFjY2VzcyB0byBhbGwgdGhlIAogCS8vLyBkb2N1bWVudCBwcm9wZXJ0aWVzIGFuZCB3b3Jrc2hlZXRzIHdpdGhpbiB0aGUgd29ya2Jvb2suCiAJLy8vIDwvc3VtbWFyeT4KLQlwdWJsaWMgc2VhbGVkIGNsYXNzIEV4Y2VsV29ya2Jvb2sgOiBYbWxIZWxwZXIsIElEaXNwb3NhYmxlCisJcHVibGljIHNlYWxlZCBjbGFzcyBFeGNlbFdvcmtib29rIDogWG1sSGVscGVyCiAJewogCQlpbnRlcm5hbCBjbGFzcyBTaGFyZWRTdHJpbmdJdGVtCiAJCXsKQEAgLTI5Miw4ICsyOTIsNiBAQAogCQkJfQogCQl9CiAJCSNyZWdpb24gV29ya2Jvb2sgUHJvcGVydGllcwotCQlkZWNpbWFsIF9zdGFuZGFyZEZvbnRXaWR0aCA9IGRlY2ltYWwuTWluVmFsdWU7Ci0gICAgICAgIHN0cmluZyBfZm9udElEID0gIiI7CiAgICAgICAgIGludGVybmFsIEZvcm11bGFQYXJzZXIgRm9ybXVsYVBhcnNlcgogICAgICAgICB7CiAgICAgICAgICAgICBnZXQKQEAgLTMxOCw4NyArMzE2LDYgQEAKIAkgICAgICAgIH0KIAkgICAgfQogCi0gICAgICAgIC8vLyA8c3VtbWFyeT4KLQkJLy8vIE1heCBmb250IHdpZHRoIGZvciB0aGUgd29ya2Jvb2sKLSAgICAgICAgLy8vIDxyZW1hcmtzPlRoaXMgbWV0aG9kIHVzZXMgR0RJLiBJZiB5b3UgdXNlIEFzdXJlIG9yIGFub3RoZXIgZW52aXJvbm1lbnQgdGhhdCBkb2VzIG5vdCBzdXBwb3J0IEdESSwgeW91IGhhdmUgdG8gc2V0IHRoaXMgdmFsdWUgbWFudWFsbHkgaWYgeW91IGRvbid0IHVzZSB0aGUgc3RhbmRhcmQgQ2FsaWJyaSBmb250PC9yZW1hcmtzPgotCQkvLy8gPC9zdW1tYXJ5PgotCQlwdWJsaWMgZGVjaW1hbCBNYXhGb250V2lkdGggCi0JCXsKLQkJCWdldAotCQkJewotICAgICAgICAgICAgICAgIGlmIChfc3RhbmRhcmRGb250V2lkdGggPT0gZGVjaW1hbC5NaW5WYWx1ZSB8fCBfZm9udElEICE9IFN0eWxlcy5Gb250c1swXS5JZCkKLQkJCQl7Ci0JCQkJCXZhciBmb250ID0gU3R5bGVzLkZvbnRzWzBdOwotICAgICAgICAgICAgICAgICAgICB0cnkKLSAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGYgPSBuZXcgRm9udChmb250Lk5hbWUsIGZvbnQuU2l6ZSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBfc3RhbmRhcmRGb250V2lkdGggPSAwOwotICAgICAgICAgICAgICAgICAgICAgICAgX2ZvbnRJRCA9IGZvbnQuSWQ7Ci0gICAgICAgICAgICAgICAgIAotICAgICAgICAgICAgICAgICAgICAgICAgLy9SZW1vdmUgdGhlIFByZXNlbnRhaW9uQ29yZSBEZXBlbmRlbmNleS4gVGhpcyBtaWdodCBlZmZlY3QgY29tcG9uZW50cyBydW5uaW5nIHVuZGVyIEF6dXJlIG5vdCBoYXZpbmcgc3VwcG9ydCBmb3IgR0RJKwotCi0gICAgICAgICAgICAgICAgICAgICAgICAvL1R5cGVmYWNlIHRmID0gbmV3IFR5cGVmYWNlKG5ldyBTeXN0ZW0uV2luZG93cy5NZWRpYS5Gb250RmFtaWx5KGZvbnQuTmFtZSksCi0gICAgICAgICAgICAgICAgICAgICAgICAvLy8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoZm9udC5JdGFsaWMpID8gRm9udFN0eWxlcy5Ob3JtYWwgOiBGb250U3R5bGVzLkl0YWxpYywKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoZm9udC5Cb2xkKSA/IEZvbnRXZWlnaHRzLkJvbGQgOiBGb250V2VpZ2h0cy5Ob3JtYWwsCi0gICAgICAgICAgICAgICAgICAgICAgICAvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRm9udFN0cmV0Y2hlcy5Ob3JtYWwpOwotICAgICAgICAgICAgICAgICAgICAgICAgLy9mb3IoaW50IGk9MDtpPDEwO2krKykKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vewotICAgICAgICAgICAgICAgICAgICAgICAgLy8gICAgdmFyIGZ0ID0gbmV3IFN5c3RlbS5XaW5kb3dzLk1lZGlhLkZvcm1hdHRlZFRleHQoIjAxMjM0NTY3ODkiLlN1YnN0cmluZyhpLDEpLCBDdWx0dXJlSW5mby5JbnZhcmlhbnRDdWx0dXJlLCBTeXN0ZW0uV2luZG93cy5GbG93RGlyZWN0aW9uLkxlZnRUb1JpZ2h0LCB0ZiwgZm9udC5TaXplICogKDk2RCAvIDcyRCksIG5ldyBEcmF3aW5nQnJ1c2goKSk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAvLyAgICB2YXIgd2lkdGg9KGludClNYXRoLlJvdW5kKGZ0LldpZHRoLDApOyAgIAotICAgICAgICAgICAgICAgICAgICAgICAgLy8gICAgaWYod2lkdGg+X3N0YW5kYXJkRm9udFdpZHRoKQotICAgICAgICAgICAgICAgICAgICAgICAgLy8gICAgewotICAgICAgICAgICAgICAgICAgICAgICAgLy8gICAgICAgIF9zdGFuZGFyZEZvbnRXaWR0aCA9IHdpZHRoOwotICAgICAgICAgICAgICAgICAgICAgICAgLy8gICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgLy99Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgIC8vdmFyIHNpemUgPSBuZXcgU3lzdGVtLldpbmRvd3MuU2l6ZSB7IFdpZHRoID0gZnQuV2lkdGhJbmNsdWRpbmdUcmFpbGluZ1doaXRlc3BhY2UsIEhlaWdodCA9IGZ0LkhlaWdodCB9OwotCi0gICAgICAgICAgICAgICAgICAgICAgICBfc3RhbmRhcmRGb250V2lkdGggPSBHZXRXaWR0aFBpeGVscyhmLCIxMjM0NTY3ODkwIik7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoX3N0YW5kYXJkRm9udFdpZHRoIDw9IDApIC8vTm8gR0RJPwotICAgICAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9zdGFuZGFyZEZvbnRXaWR0aCA9IChpbnQpKGZvbnQuU2l6ZSAqICgyRCAvIDNEKSk7IC8vQXByb3guIGZvciBDYWxpYnJpLgotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGNhdGNoICAgLy9FcnJvciwgc2V0IGRlZmF1bHQgdmFsdWUKLSAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgX3N0YW5kYXJkRm9udFdpZHRoID0gKGludCkoZm9udC5TaXplICogKDJEIC8gM0QpKTsgLy9BcHJveCBmb3IgQ2FsaWJyaS4KLSAgICAgICAgICAgICAgICAgICAgfQotCQkJCX0KLQkJCQlyZXR1cm4gX3N0YW5kYXJkRm9udFdpZHRoOwotCQkJfQotICAgICAgICAgICAgc2V0Ci0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgX3N0YW5kYXJkRm9udFdpZHRoID0gdmFsdWU7Ci0gICAgICAgICAgICB9Ci0JCX0KLQotCSAgICBpbnRlcm5hbCBzdGF0aWMgZGVjaW1hbCBHZXRXaWR0aFBpeGVscyhGb250IGYsIHN0cmluZyBzKQotCSAgICB7Ci0JICAgICAgICB2YXIgcmV0ID0gME07Ci0gICAgICAgICAgICB1c2luZyAodmFyIGIgPSBuZXcgQml0bWFwKDEsIDEpKQotCSAgICAgICAgewotCSAgICAgICAgICAgIHVzaW5nIChHcmFwaGljcyBnID0gR3JhcGhpY3MuRnJvbUltYWdlKGIpKQotCSAgICAgICAgICAgIHsKLQkgICAgICAgICAgICAgICAgZy5QYWdlVW5pdCA9IEdyYXBoaWNzVW5pdC5QaXhlbDsKLQotCSAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IHMuTGVuZ3RoOyBpKyspCi0JICAgICAgICAgICAgICAgIHsKLQkgICAgICAgICAgICAgICAgICAgIHZhciBjID0gc1tpXTsKLQkgICAgICAgICAgICAgICAgICAgIHZhciB3aWR0aCA9Ci0JICAgICAgICAgICAgICAgICAgICAgICAgKGRlY2ltYWwpCi0JICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1hdGguVHJ1bmNhdGUoCi0JICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnLk1lYXN1cmVTdHJpbmcobmV3IHN0cmluZyhjLCAyKSwgZiwgMTAwMCwgU3RyaW5nRm9ybWF0LkdlbmVyaWNUeXBvZ3JhcGhpYykuV2lkdGggLQotCSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZy5NZWFzdXJlU3RyaW5nKG5ldyBzdHJpbmcoYywgMSksIGYsIDEwMDAsIFN0cmluZ0Zvcm1hdC5HZW5lcmljVHlwb2dyYXBoaWMpLldpZHRoKTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGlmICh3aWR0aCA+IHJldCkKLQkgICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXQgPSB3aWR0aDsKLQkgICAgICAgICAgICAgICAgICAgIH0KLQkgICAgICAgICAgICAgICAgfQotCSAgICAgICAgICAgIH0KLQkgICAgICAgIH0KLQkgICAgICAgIHJldHVybiByZXQ7Ci0JICAgIH0KLQogCSAgICBFeGNlbFByb3RlY3Rpb24gX3Byb3RlY3Rpb24gPSBudWxsOwogCQkvLy8gPHN1bW1hcnk+CiAJCS8vLyBBY2Nlc3MgcHJvcGVydGllcyB0byBwcm90ZWN0IG9yIHVucHJvdGVjdCBhIHdvcmtib29rCkBAIC01NDUsNyArNDYyLDYgQEAKIAkJCQlTdHJlYW1Xcml0ZXIgc3RyZWFtID0gbmV3IFN0cmVhbVdyaXRlcihwYXJ0V29ya2Jvb2suR2V0U3RyZWFtKEZpbGVNb2RlLkNyZWF0ZSwgRmlsZUFjY2Vzcy5Xcml0ZSkpOwogCQkJCV93b3JrYm9va1htbC5TYXZlKHN0cmVhbSk7CiAJCQkJLy9zdHJlYW0uQ2xvc2UoKTsKLQkJCQlfcGFja2FnZS5QYWNrYWdlLkZsdXNoKCk7CiAJCQl9CiAJCX0KIAkJI2VuZHJlZ2lvbgpAQCAtNTg3LDExICs1MDMsOSBAQAogCiAJCQkJCQlfc3R5bGVzWG1sLlNhdmUoc3RyZWFtKTsKIAkJCQkJCS8vc3RyZWFtLkNsb3NlKCk7Ci0JCQkJCQlfcGFja2FnZS5QYWNrYWdlLkZsdXNoKCk7CiAKIAkJCQkJCS8vIGNyZWF0ZSB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gdGhlIHdvcmtib29rIGFuZCB0aGUgbmV3IHNoYXJlZCBzdHJpbmdzIHBhcnQKIAkJCQkJCV9wYWNrYWdlLldvcmtib29rLlBhcnQuQ3JlYXRlUmVsYXRpb25zaGlwKFVyaUhlbHBlci5HZXRSZWxhdGl2ZVVyaShXb3JrYm9va1VyaSwgU3R5bGVzVXJpKSwgUGFja2FnaW5nLlRhcmdldE1vZGUuSW50ZXJuYWwsIEV4Y2VsUGFja2FnZS5zY2hlbWFSZWxhdGlvbnNoaXBzICsgIi9zdHlsZXMiKTsKLQkJCQkJCV9wYWNrYWdlLlBhY2thZ2UuRmx1c2goKTsKIAkJCQkJfQogCQkJCX0KIAkJCQlyZXR1cm4gKF9zdHlsZXNYbWwpOwpAQCAtMTAwMywzMyArOTE3LDcgQEAKIAkJCQl9CiAJCQl9CiAJCX0KLQotICAgICAgICBwdWJsaWMgdm9pZCBEaXNwb3NlKCkKLSAgICAgICAgewotICAgICAgICAgICAgaWYgKF9zaGFyZWRTdHJpbmdzICE9IG51bGwpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgX3NoYXJlZFN0cmluZ3MuQ2xlYXIoKTsKLSAgICAgICAgICAgICAgICBfc2hhcmVkU3RyaW5ncyA9IG51bGw7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBpZiAoX3NoYXJlZFN0cmluZ3NMaXN0ICE9IG51bGwpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgX3NoYXJlZFN0cmluZ3NMaXN0LkNsZWFyKCk7Ci0gICAgICAgICAgICAgICAgX3NoYXJlZFN0cmluZ3NMaXN0ID0gbnVsbDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGlmIChfd29ya3NoZWV0cyAhPSBudWxsKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIF93b3Jrc2hlZXRzLkRpc3Bvc2UoKTsKLSAgICAgICAgICAgICAgICBfd29ya3NoZWV0cyA9IG51bGw7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBfcGFja2FnZSA9IG51bGw7Ci0gICAgICAgICAgICBfcHJvcGVydGllcyA9IG51bGw7Ci0gICAgICAgICAgICBpZiAoX2Zvcm11bGFQYXJzZXIgIT0gbnVsbCkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBfZm9ybXVsYVBhcnNlci5EaXNwb3NlKCk7Ci0gICAgICAgICAgICAgICAgX2Zvcm11bGFQYXJzZXIgPSBudWxsOwotICAgICAgICAgICAgfSAgIAotICAgICAgICB9Ci0KKwkJCiAgICAgICAgIGludGVybmFsIHZvaWQgUmVhZEFsbFRhYmxlcygpCiAgICAgICAgIHsKICAgICAgICAgICAgIGlmIChfbmV4dFRhYmxlSUQgPiAwKSByZXR1cm47CmRpZmYgLS1naXQgYS9FUFBsdXMvRXhjZWxXb3Jrc2hlZXQuY3MgYi9FUFBsdXMvRXhjZWxXb3Jrc2hlZXQuY3MKaW5kZXggZjhiNmFlYi4uYzJiZjZlNyAxMDA2NDQKLS0tIGEvRVBQbHVzL0V4Y2VsV29ya3NoZWV0LmNzCisrKyBiL0VQUGx1cy9FeGNlbFdvcmtzaGVldC5jcwpAQCAtOTAsNyArOTAsNyBAQAogICAgIC8vLyA8c3VtbWFyeT4KIAkvLy8gUmVwcmVzZW50cyBhbiBFeGNlbCB3b3Jrc2hlZXQgYW5kIHByb3ZpZGVzIGFjY2VzcyB0byBpdHMgcHJvcGVydGllcyBhbmQgbWV0aG9kcwogCS8vLyA8L3N1bW1hcnk+Ci0gICAgcHVibGljIGNsYXNzIEV4Y2VsV29ya3NoZWV0IDogWG1sSGVscGVyLCBJRXF1YWxpdHlDb21wYXJlcjxFeGNlbFdvcmtzaGVldD4sIElEaXNwb3NhYmxlCisgICAgcHVibGljIGNsYXNzIEV4Y2VsV29ya3NoZWV0IDogWG1sSGVscGVyLCBJRXF1YWxpdHlDb21wYXJlcjxFeGNlbFdvcmtzaGVldD4KIAl7CiAgICAgICAgIGludGVybmFsIGNsYXNzIEZvcm11bGFzCiAgICAgICAgIHsKQEAgLTQxMDUsNDggKzQxMDUsNyBAQAogICAgICAgICAgICAgfQogICAgICAgICAgICAgcmV0dXJuIHN0eWxlSWQ7CiAgICAgICAgIH0KLQotICAgICAgICBwcml2YXRlIHZvaWQgRGlzcG9zZUludGVybmFsKElEaXNwb3NhYmxlIGNhbmRpZGF0ZURpc3Bvc2FibGUpCi0gICAgICAgIHsKLSAgICAgICAgICAgIGlmIChjYW5kaWRhdGVEaXNwb3NhYmxlICE9IG51bGwpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgY2FuZGlkYXRlRGlzcG9zYWJsZS5EaXNwb3NlKCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotCi0gICAgICAgIHB1YmxpYyB2b2lkIERpc3Bvc2UoKQotICAgICAgICB7Ci0gICAgICAgICAgICBEaXNwb3NlSW50ZXJuYWwoX3ZhbHVlcyk7Ci0gICAgICAgICAgICBEaXNwb3NlSW50ZXJuYWwoX2Zvcm11bGFzKTsKLSAgICAgICAgICAgIERpc3Bvc2VJbnRlcm5hbChfZmxhZ3MpOwotICAgICAgICAgICAgRGlzcG9zZUludGVybmFsKF9oeXBlckxpbmtzKTsKLSAgICAgICAgICAgIERpc3Bvc2VJbnRlcm5hbChfc3R5bGVzKTsKLSAgICAgICAgICAgIERpc3Bvc2VJbnRlcm5hbChfdHlwZXMpOwotICAgICAgICAgICAgRGlzcG9zZUludGVybmFsKF9jb21tZW50c1N0b3JlKTsKLSAgICAgICAgICAgIERpc3Bvc2VJbnRlcm5hbChfZm9ybXVsYVRva2Vucyk7Ci0KLSAgICAgICAgICAgIF92YWx1ZXMgPSBudWxsOwotICAgICAgICAgICAgX2Zvcm11bGFzID0gbnVsbDsKLSAgICAgICAgICAgIF9mbGFncyA9IG51bGw7Ci0gICAgICAgICAgICBfaHlwZXJMaW5rcyA9IG51bGw7Ci0gICAgICAgICAgICBfc3R5bGVzID0gbnVsbDsKLSAgICAgICAgICAgIF90eXBlcyA9IG51bGw7Ci0gICAgICAgICAgICBfY29tbWVudHNTdG9yZSA9IG51bGw7Ci0gICAgICAgICAgICBfZm9ybXVsYVRva2VucyA9IG51bGw7Ci0KLSAgICAgICAgICAgIF9wYWNrYWdlID0gbnVsbDsKLSAgICAgICAgICAgIF9waXZvdFRhYmxlcyA9IG51bGw7Ci0gICAgICAgICAgICBfcHJvdGVjdGlvbiA9IG51bGw7Ci0gICAgICAgICAgICBpZihfc2hhcmVkRm9ybXVsYXMgIT0gbnVsbCkgX3NoYXJlZEZvcm11bGFzLkNsZWFyKCk7Ci0gICAgICAgICAgICBfc2hhcmVkRm9ybXVsYXMgPSBudWxsOwotICAgICAgICAgICAgX3NoZWV0VmlldyA9IG51bGw7Ci0gICAgICAgICAgICBfdGFibGVzID0gbnVsbDsKLSAgICAgICAgICAgIF92bWxEcmF3aW5ncyA9IG51bGw7Ci0gICAgICAgICAgICBfY29uZGl0aW9uYWxGb3JtYXR0aW5nID0gbnVsbDsKLSAgICAgICAgICAgIF9kYXRhVmFsaWRhdGlvbiA9IG51bGw7Ci0gICAgICAgIH0KLQorICAgICAgICAKICAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgICAvLy8gR2V0IHRoZSBFeGNlbENvbHVtbiBmb3IgY29sdW1uIChzcGFuIENvbHVtbk1pbiBhbmQgQ29sdW1uTWF4KQogICAgICAgICAvLy8gPC9zdW1tYXJ5PgpkaWZmIC0tZ2l0IGEvRVBQbHVzL0V4Y2VsV29ya3NoZWV0cy5jcyBiL0VQUGx1cy9FeGNlbFdvcmtzaGVldHMuY3MKaW5kZXggNDc1YWY1OC4uMThjMmVjZiAxMDA2NDQKLS0tIGEvRVBQbHVzL0V4Y2VsV29ya3NoZWV0cy5jcworKysgYi9FUFBsdXMvRXhjZWxXb3Jrc2hlZXRzLmNzCkBAIC0zNCwxNCArMzQsMTMgQEAKIHVzaW5nIFN5c3RlbS5Db2xsZWN0aW9ucy5HZW5lcmljOwogdXNpbmcgU3lzdGVtLlhtbDsKIHVzaW5nIFN5c3RlbS5JTzsKLXVzaW5nIFN5c3RlbS5MaW5xOwogdXNpbmcgT2ZmaWNlT3BlblhtbC5VdGlsczsKIG5hbWVzcGFjZSBPZmZpY2VPcGVuWG1sCiB7CiAJLy8vIDxzdW1tYXJ5PgogCS8vLyBUaGUgY29sbGVjdGlvbiBvZiB3b3Jrc2hlZXRzIGZvciB0aGUgd29ya2Jvb2sKIAkvLy8gPC9zdW1tYXJ5PgotCXB1YmxpYyBjbGFzcyBFeGNlbFdvcmtzaGVldHMgOiBYbWxIZWxwZXIsIElFbnVtZXJhYmxlPEV4Y2VsV29ya3NoZWV0PiwgSURpc3Bvc2FibGUKKwlwdWJsaWMgY2xhc3MgRXhjZWxXb3Jrc2hlZXRzIDogWG1sSGVscGVyLCBJRW51bWVyYWJsZTxFeGNlbFdvcmtzaGVldD4KIAl7CiAJCSNyZWdpb24gUHJpdmF0ZSBQcm9wZXJ0aWVzCiAgICAgICAgIHByaXZhdGUgRXhjZWxQYWNrYWdlIF9wY2s7CkBAIC0xNTQsNyArMTUzLDYgQEAKICAgICAgICAgICAgICAgICBTdHJlYW1Xcml0ZXIgc3RyZWFtV29ya3NoZWV0ID0gbmV3IFN0cmVhbVdyaXRlcih3b3Jrc2hlZXRQYXJ0LkdldFN0cmVhbShGaWxlTW9kZS5DcmVhdGUsIEZpbGVBY2Nlc3MuV3JpdGUpKTsKICAgICAgICAgICAgICAgICBYbWxEb2N1bWVudCB3b3Jrc2hlZXRYbWwgPSBDcmVhdGVOZXdXb3Jrc2hlZXQoZmFsc2UpOwogICAgICAgICAgICAgICAgIHdvcmtzaGVldFhtbC5TYXZlKHN0cmVhbVdvcmtzaGVldCk7Ci0gICAgICAgICAgICAgICAgX3Bjay5QYWNrYWdlLkZsdXNoKCk7CiAKICAgICAgICAgICAgICAgICBzdHJpbmcgcmVsID0gQ3JlYXRlV29ya2Jvb2tSZWwoTmFtZSwgc2hlZXRJRCwgdXJpV29ya3NoZWV0LCBmYWxzZSk7CiAKQEAgLTE3NCw3ICsxNzIsNiBAQAogICAgICAgICB7CiAgICAgICAgICAgICAvL0NyZWF0ZSB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gdGhlIHdvcmtib29rIGFuZCB0aGUgbmV3IHdvcmtzaGVldAogICAgICAgICAgICAgdmFyIHJlbCA9IF9wY2suV29ya2Jvb2suUGFydC5DcmVhdGVSZWxhdGlvbnNoaXAoVXJpSGVscGVyLkdldFJlbGF0aXZlVXJpKF9wY2suV29ya2Jvb2suV29ya2Jvb2tVcmksIHVyaVdvcmtzaGVldCksIFBhY2thZ2luZy5UYXJnZXRNb2RlLkludGVybmFsLCBFeGNlbFBhY2thZ2Uuc2NoZW1hUmVsYXRpb25zaGlwcyArICIvIiArIChpc0NoYXJ0ID8gImNoYXJ0c2hlZXQiIDogIndvcmtzaGVldCIpKTsKLSAgICAgICAgICAgIF9wY2suUGFja2FnZS5GbHVzaCgpOwogCiAgICAgICAgICAgICAvL0NyZWF0ZSB0aGUgbmV3IHNoZWV0IG5vZGUKICAgICAgICAgICAgIFhtbEVsZW1lbnQgd29ya3NoZWV0Tm9kZSA9IF9wY2suV29ya2Jvb2suV29ya2Jvb2tYbWwuQ3JlYXRlRWxlbWVudCgic2hlZXQiLCBFeGNlbFBhY2thZ2Uuc2NoZW1hTWFpbik7CkBAIC01MjcsMTQgKzUyNCw1IEBACiAJCX0KIAogCQkjZW5kcmVnaW9uCi0gICAgICAgIHB1YmxpYyB2b2lkIERpc3Bvc2UoKQotICAgICAgICB7ICAgICAgICAgICAgCi0gICAgICAgICAgICAgZm9yZWFjaCAodmFyIHNoZWV0IGluIHRoaXMuX3dvcmtzaGVldHMuVmFsdWVzKSAKLSAgICAgICAgICAgICB7IAotICAgICAgICAgICAgICAgICAoKElEaXNwb3NhYmxlKXNoZWV0KS5EaXNwb3NlKCk7IAotICAgICAgICAgICAgIH0gCi0gICAgICAgICAgICAgX3dvcmtzaGVldHMgPSBudWxsOwotICAgICAgICAgICAgIF9wY2sgPSBudWxsOyAgICAgICAgICAgIAotICAgICAgICB9CiAgICAgfSAvLyBlbmQgY2xhc3MgV29ya3NoZWV0cwogfQpkaWZmIC0tZ2l0IGEvRVBQbHVzL0Zvcm11bGFQYXJzaW5nL0NhbGN1bGF0ZUV4dGVudGlvbnMuY3MgYi9FUFBsdXMvRm9ybXVsYVBhcnNpbmcvQ2FsY3VsYXRlRXh0ZW50aW9ucy5jcwppbmRleCAyMjYzN2FjLi42OWJjM2VlIDEwMDY0NAotLS0gYS9FUFBsdXMvRm9ybXVsYVBhcnNpbmcvQ2FsY3VsYXRlRXh0ZW50aW9ucy5jcworKysgYi9FUFBsdXMvRm9ybXVsYVBhcnNpbmcvQ2FsY3VsYXRlRXh0ZW50aW9ucy5jcwpAQCAtNTIsMzMgKzUyLDcgQEAKIAogICAgICAgICAgICAgdmFyIGRjID0gRGVwZW5kZW5jeUNoYWluRmFjdG9yeS5DcmVhdGUod29ya2Jvb2ssIG9wdGlvbnMpOwogICAgICAgICAgICAgd29ya2Jvb2suRm9ybXVsYVBhcnNlci5Jbml0TmV3Q2FsYygpOwotICAgICAgICAgICAgaWYgKHdvcmtib29rLkZvcm11bGFQYXJzZXIuTG9nZ2VyICE9IG51bGwpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgdmFyIG1zZyA9IHN0cmluZy5Gb3JtYXQoIlN0YXJ0aW5nLi4uIG51bWJlciBvZiBjZWxscyB0byBwYXJzZTogezB9IiwgZGMubGlzdC5Db3VudCk7Ci0gICAgICAgICAgICAgICAgd29ya2Jvb2suRm9ybXVsYVBhcnNlci5Mb2dnZXIuTG9nKG1zZyk7Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIC8vVE9ETzogUmVtb3ZlIHdoZW4gdGVzdHMgYXJlIGRvbmUuIE91dHB1dHMgdGhlIGRjIHRvIGEgdGV4dCBmaWxlLiAKLSAgICAgICAgICAgIC8vdmFyIGZpbGVEYyA9IG5ldyBTeXN0ZW0uSU8uU3RyZWFtV3JpdGVyKCJjOlxcdGVtcFxcZGMudHh0Iik7Ci0gICAgICAgICAgICAgICAgICAgICAgICAKLSAgICAgICAgICAgIC8vZm9yIChpbnQgaSA9IDA7IGkgPCBkYy5saXN0LkNvdW50OyBpKyspCi0gICAgICAgICAgICAvL3sKLSAgICAgICAgICAgIC8vICAgIGZpbGVEYy5Xcml0ZUxpbmUoaS5Ub1N0cmluZygpICsgIiwiICsgZGMubGlzdFtpXS5Db2x1bW4uVG9TdHJpbmcoKSArICIsIiArIGRjLmxpc3RbaV0uUm93LlRvU3RyaW5nKCkgKyAiLCIgKyAoZGMubGlzdFtpXS53cz09bnVsbCA/ICIiIDogZGMubGlzdFtpXS53cy5OYW1lKSArICIsIiArIGRjLmxpc3RbaV0uRm9ybXVsYSk7Ci0gICAgICAgICAgICAvL30KLSAgICAgICAgICAgIC8vZmlsZURjLkNsb3NlKCk7Ci0gICAgICAgICAgICAvL2ZpbGVEYyA9IG5ldyBTeXN0ZW0uSU8uU3RyZWFtV3JpdGVyKCJjOlxcdGVtcFxcZGNvcmRlci50eHQiKTsKLSAgICAgICAgICAgIC8vZm9yIChpbnQgaSA9IDA7IGkgPCBkYy5DYWxjT3JkZXIuQ291bnQ7IGkrKykKLSAgICAgICAgICAgIC8vewotICAgICAgICAgICAgLy8gICAgZmlsZURjLldyaXRlTGluZShkYy5DYWxjT3JkZXJbaV0uVG9TdHJpbmcoKSk7Ci0gICAgICAgICAgICAvL30KLSAgICAgICAgICAgIC8vZmlsZURjLkNsb3NlKCk7Ci0gICAgICAgICAgICAvL2ZpbGVEYyA9IG51bGw7Ci0KLSAgICAgICAgICAgIC8vVE9ETzogQWRkIGNhbGN1bGF0aW9uIGhlcmUKLQogICAgICAgICAgICAgQ2FsY0NoYWluKHdvcmtib29rLCB3b3JrYm9vay5Gb3JtdWxhUGFyc2VyLCBkYyk7Ci0KLSAgICAgICAgICAgIC8vd29ya2Jvb2suX2lzQ2FsY3VsYXRlZCA9IHRydWU7CiAgICAgICAgIH0KICAgICAgICAgcHVibGljIHN0YXRpYyB2b2lkIENhbGN1bGF0ZSh0aGlzIEV4Y2VsV29ya3NoZWV0IHdvcmtzaGVldCkKICAgICAgICAgewpAQCAtOTYsMTEgKzcwLDYgQEAKIAogICAgICAgICAgICAgdmFyIHBhcnNlciA9IHdvcmtzaGVldC5Xb3JrYm9vay5Gb3JtdWxhUGFyc2VyOwogICAgICAgICAgICAgcGFyc2VyLkluaXROZXdDYWxjKCk7Ci0gICAgICAgICAgICBpZiAocGFyc2VyLkxvZ2dlciAhPSBudWxsKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIHZhciBtc2cgPSBzdHJpbmcuRm9ybWF0KCJTdGFydGluZy4uLiBudW1iZXIgb2YgY2VsbHMgdG8gcGFyc2U6IHswfSIsIGRjLmxpc3QuQ291bnQpOwotICAgICAgICAgICAgICAgIHBhcnNlci5Mb2dnZXIuTG9nKG1zZyk7Ci0gICAgICAgICAgICB9CiAgICAgICAgICAgICBDYWxjQ2hhaW4od29ya3NoZWV0Lldvcmtib29rLCBwYXJzZXIsIGRjKTsKICAgICAgICAgfQogCkBAIC0xNzUsNyArMTQ0LDYgQEAKICAgICAgICAgfQogICAgICAgICBwcml2YXRlIHN0YXRpYyB2b2lkIENhbGNDaGFpbihFeGNlbFdvcmtib29rIHdiLCBGb3JtdWxhUGFyc2VyIHBhcnNlciwgRGVwZW5kZW5jeUNoYWluIGRjKQogICAgICAgICB7Ci0gICAgICAgICAgICB2YXIgZGVidWcgPSBwYXJzZXIuTG9nZ2VyICE9IG51bGw7CiAgICAgICAgICAgICBmb3JlYWNoICh2YXIgaXggaW4gZGMuQ2FsY09yZGVyKQogICAgICAgICAgICAgewogICAgICAgICAgICAgICAgIHZhciBpdGVtID0gZGMubGlzdFtpeF07CkBAIC0xODQsMjIgKzE1MiwxNyBAQAogICAgICAgICAgICAgICAgICAgICB2YXIgd3MgPSB3Yi5Xb3Jrc2hlZXRzLkdldEJ5U2hlZXRJRChpdGVtLlNoZWV0SUQpOwogICAgICAgICAgICAgICAgICAgICB2YXIgdiA9IHBhcnNlci5QYXJzZUNlbGwoaXRlbS5Ub2tlbnMsIHdzID09IG51bGwgPyAiIiA6IHdzLk5hbWUsIGl0ZW0uUm93LCBpdGVtLkNvbHVtbik7CiAgICAgICAgICAgICAgICAgICAgIFNldFZhbHVlKHdiLCBpdGVtLCB2KTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGRlYnVnKQotICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBwYXJzZXIuTG9nZ2VyLkxvZ0NlbGxDb3VudGVkKCk7Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgVGhyZWFkLlNsZWVwKDApOwogICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBjYXRjaCAoT2ZmaWNlT3BlblhtbC5Gb3JtdWxhUGFyc2luZy5FeGNlbC5GdW5jdGlvbnMuRnVuY3Rpb25FeGNlcHRpb24gZnVuY3Rpb25leCkKKyAgICAgICAgICAgICAgICBjYXRjaCAoT2ZmaWNlT3BlblhtbC5Gb3JtdWxhUGFyc2luZy5FeGNlbC5GdW5jdGlvbnMuRnVuY3Rpb25FeGNlcHRpb24pCiAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAvLyBFeGNlbCBmdW5jdGlvbiBpcyBub3Qgc3VwcG9ydGVkIGJ5IEVQUGx1cwotICAgICAgICAgICAgICAgICAgICB0aHJvdyAoZnVuY3Rpb25leCk7CisgICAgICAgICAgICAgICAgICAgIHRocm93OwogICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBjYXRjaCAoRm9ybWF0RXhjZXB0aW9uIGZlKQorICAgICAgICAgICAgICAgIGNhdGNoIChGb3JtYXRFeGNlcHRpb24pCiAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICB0aHJvdyAoZmUpOworICAgICAgICAgICAgICAgICAgICB0aHJvdzsKICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBlKQorICAgICAgICAgICAgICAgIGNhdGNoIChFeGNlcHRpb24pCiAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICB2YXIgZXJyb3IgPSBFeGNlbEVycm9yVmFsdWUuUGFyc2UoRXhjZWxFcnJvclZhbHVlLlZhbHVlcy5WYWx1ZSk7CiAgICAgICAgICAgICAgICAgICAgIFNldFZhbHVlKHdiLCBpdGVtLCBlcnJvcik7CkBAIC0yMTMsMTAgKzE3Niw2IEBACiAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgaWYgKCEod3MgaXMgRXhjZWxDaGFydHNoZWV0KSkKICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgIGlmICh3cy5fZm9ybXVsYVRva2VucyAhPSBudWxsKQotICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICB3cy5fZm9ybXVsYVRva2Vucy5EaXNwb3NlKCk7Ci0gICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgd3MuX2Zvcm11bGFUb2tlbnMgPSBuZXcgQ2VsbFN0b3JlPExpc3Q8VG9rZW4+PigpOwogICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgIH0KZGlmZiAtLWdpdCBhL0VQUGx1cy9Gb3JtdWxhUGFyc2luZy9FcHBsdXNFeGNlbERhdGFQcm92aWRlci5jcyBiL0VQUGx1cy9Gb3JtdWxhUGFyc2luZy9FcHBsdXNFeGNlbERhdGFQcm92aWRlci5jcwppbmRleCA1ZTc1MWFiLi4xNzRmMzAzIDEwMDY0NAotLS0gYS9FUFBsdXMvRm9ybXVsYVBhcnNpbmcvRXBwbHVzRXhjZWxEYXRhUHJvdmlkZXIuY3MKKysrIGIvRVBQbHVzL0Zvcm11bGFQYXJzaW5nL0VwcGx1c0V4Y2VsRGF0YVByb3ZpZGVyLmNzCkBAIC0xLDEwICsxLDYgQEAKLe+7v3VzaW5nIFN5c3RlbTsKLXVzaW5nIFN5c3RlbS5Db2xsZWN0aW9ucy5HZW5lcmljOwor77u/dXNpbmcgU3lzdGVtLkNvbGxlY3Rpb25zLkdlbmVyaWM7CiB1c2luZyBTeXN0ZW0uTGlucTsKLXVzaW5nIFN5c3RlbS5UZXh0OwotdXNpbmcgT2ZmaWNlT3BlblhtbC5Gb3JtdWxhUGFyc2luZzsKIHVzaW5nIE9mZmljZU9wZW5YbWwuRm9ybXVsYVBhcnNpbmcuRXhjZWxVdGlsaXRpZXM7Ci11c2luZyBPZmZpY2VPcGVuWG1sLkZvcm11bGFQYXJzaW5nLkV4Y2VsLkZ1bmN0aW9uczsKIHVzaW5nIE9mZmljZU9wZW5YbWwuRm9ybXVsYVBhcnNpbmcuTGV4aWNhbEFuYWx5c2lzOwogdXNpbmcgT2ZmaWNlT3BlblhtbC5VdGlsczsKIHVzaW5nIE9mZmljZU9wZW5YbWwuU3R5bGUuWG1sQWNjZXNzOwpAQCAtOTYsOSArOTIsNiBAQAogCiAgICAgICAgICAgICBwdWJsaWMgdm9pZCBEaXNwb3NlKCkKICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAvL192YWx1ZXMgPSBudWxsOwotICAgICAgICAgICAgICAgIC8vX3dzID0gbnVsbDsKLSAgICAgICAgICAgICAgICAvL19jZWxsID0gbnVsbDsKICAgICAgICAgICAgIH0KIAogICAgICAgICAgICAgb2JqZWN0IFN5c3RlbS5Db2xsZWN0aW9ucy5JRW51bWVyYXRvci5DdXJyZW50CkBAIC0zMDMsOSArMjk2LDkgQEAKICAgICAgICAgICAgIEV4Y2VsV29ya3NoZWV0IHdzOwogICAgICAgICAgICAgaWYgKHN0cmluZy5Jc051bGxPckVtcHR5KHdvcmtzaGVldCkpCiAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgaWYoX3BhY2thZ2UuX3dvcmtib29rLk5hbWVzLkNvbnRhaW5zS2V5KG5hbWUpKQorICAgICAgICAgICAgICAgIGlmKF9wYWNrYWdlLldvcmtib29rLk5hbWVzLkNvbnRhaW5zS2V5KG5hbWUpKQogICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgbmFtZUl0ZW0gPSBfcGFja2FnZS5fd29ya2Jvb2suTmFtZXNbbmFtZV07CisgICAgICAgICAgICAgICAgICAgIG5hbWVJdGVtID0gX3BhY2thZ2UuV29ya2Jvb2suTmFtZXNbbmFtZV07CiAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICB7CkBAIC0zMTUsMTQgKzMwOCwxNCBAQAogICAgICAgICAgICAgfQogICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIHdzID0gX3BhY2thZ2UuX3dvcmtib29rLldvcmtzaGVldHNbd29ya3NoZWV0XTsKKyAgICAgICAgICAgICAgICB3cyA9IF9wYWNrYWdlLldvcmtib29rLldvcmtzaGVldHNbd29ya3NoZWV0XTsKICAgICAgICAgICAgICAgICBpZiAod3MgIT1udWxsICYmIHdzLk5hbWVzLkNvbnRhaW5zS2V5KG5hbWUpKQogICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgbmFtZUl0ZW0gPSB3cy5OYW1lc1tuYW1lXTsKICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgZWxzZSBpZiAoX3BhY2thZ2UuX3dvcmtib29rLk5hbWVzLkNvbnRhaW5zS2V5KG5hbWUpKQorICAgICAgICAgICAgICAgIGVsc2UgaWYgKF9wYWNrYWdlLldvcmtib29rLk5hbWVzLkNvbnRhaW5zS2V5KG5hbWUpKQogICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgbmFtZUl0ZW0gPSBfcGFja2FnZS5fd29ya2Jvb2suTmFtZXNbbmFtZV07CisgICAgICAgICAgICAgICAgICAgIG5hbWVJdGVtID0gX3BhY2thZ2UuV29ya2Jvb2suTmFtZXNbbmFtZV07CiAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICB7CkBAIC00MjYsMjEgKzQxOSw2IEBACiAgICAgICAgICAgICAKICAgICAgICAgfQogCi0gICAgICAgIC8vcHVibGljIG92ZXJyaWRlIHZvaWQgU2V0Q2VsbFZhbHVlKHN0cmluZyBhZGRyZXNzLCBvYmplY3QgdmFsdWUpCi0gICAgICAgIC8vewotICAgICAgICAvLyAgICB2YXIgYWRkcmVzc0luZm8gPSBFeGNlbEFkZHJlc3NJbmZvLlBhcnNlKGFkZHJlc3MpOwotICAgICAgICAvLyAgICB2YXIgcmEgPSBfcmFuZ2VBZGRyZXNzRmFjdG9yeS5DcmVhdGUoYWRkcmVzcyk7Ci0gICAgICAgIC8vICAgIFNldEN1cnJlbnRXb3Jrc2hlZXQoYWRkcmVzc0luZm8pOwotICAgICAgICAvLyAgICAvL3ZhciB2YWx1ZUluZm8gPSAoSUNhbGNFbmdpbmVWYWx1ZUluZm8pX2N1cnJlbnRXb3Jrc2hlZXQ7Ci0gICAgICAgIC8vICAgIC8vdmFsdWVJbmZvLlNldEZvcm11bGFWYWx1ZShyYS5Gcm9tUm93ICsgMSwgcmEuRnJvbUNvbCArIDEsIHZhbHVlKTsKLSAgICAgICAgLy8gICAgX2N1cnJlbnRXb3Jrc2hlZXQuQ2VsbHNbcmEuRnJvbVJvdyArIDEsIHJhLkZyb21Db2wgKyAxXS5WYWx1ZSA9IHZhbHVlOwotICAgICAgICAvL30KLQotICAgICAgICBwdWJsaWMgb3ZlcnJpZGUgdm9pZCBEaXNwb3NlKCkKLSAgICAgICAgewotICAgICAgICAgICAgX3BhY2thZ2UuRGlzcG9zZSgpOwotICAgICAgICB9Ci0KICAgICAgICAgcHVibGljIG92ZXJyaWRlIGludCBFeGNlbE1heENvbHVtbnMKICAgICAgICAgewogICAgICAgICAgICAgZ2V0IHsgcmV0dXJuIEV4Y2VsUGFja2FnZS5NYXhDb2x1bW5zOyB9CmRpZmYgLS1naXQgYS9FUFBsdXMvRm9ybXVsYVBhcnNpbmcvRXhjZWwvRnVuY3Rpb25zL0RhdGFiYXNlL0V4Y2VsRGF0YWJhc2VDcml0ZXJpYS5jcyBiL0VQUGx1cy9Gb3JtdWxhUGFyc2luZy9FeGNlbC9GdW5jdGlvbnMvRGF0YWJhc2UvRXhjZWxEYXRhYmFzZUNyaXRlcmlhLmNzCmluZGV4IDg1OTA4YWMuLjUyMmU4MTAgMTAwNjQ0Ci0tLSBhL0VQUGx1cy9Gb3JtdWxhUGFyc2luZy9FeGNlbC9GdW5jdGlvbnMvRGF0YWJhc2UvRXhjZWxEYXRhYmFzZUNyaXRlcmlhLmNzCisrKyBiL0VQUGx1cy9Gb3JtdWxhUGFyc2luZy9FeGNlbC9GdW5jdGlvbnMvRGF0YWJhc2UvRXhjZWxEYXRhYmFzZUNyaXRlcmlhLmNzCkBAIC01NCw3ICs1NCw2IEBACiAKICAgICAgICAgcHJpdmF0ZSB2b2lkIEluaXRpYWxpemUoKQogICAgICAgICB7Ci0gICAgICAgICAgICB2YXIgZm8gPSAxOwogICAgICAgICAgICAgZm9yICh2YXIgeCA9IF9mcm9tQ29sOyB4IDw9IF90b0NvbDsgeCsrKQogICAgICAgICAgICAgewogICAgICAgICAgICAgICAgIHZhciBmaWVsZE9iaiA9IF9kYXRhUHJvdmlkZXIuR2V0Q2VsbFZhbHVlKF93b3Jrc2hlZXQsIF9maWVsZFJvdywgeCk7CmRpZmYgLS1naXQgYS9FUFBsdXMvRm9ybXVsYVBhcnNpbmcvRXhjZWwvRnVuY3Rpb25zL0Z1bmN0aW9uUmVwb3NpdG9yeS5jcyBiL0VQUGx1cy9Gb3JtdWxhUGFyc2luZy9FeGNlbC9GdW5jdGlvbnMvRnVuY3Rpb25SZXBvc2l0b3J5LmNzCmluZGV4IDRiOTA1NDYuLjgxOGNjNTYgMTAwNjQ0Ci0tLSBhL0VQUGx1cy9Gb3JtdWxhUGFyc2luZy9FeGNlbC9GdW5jdGlvbnMvRnVuY3Rpb25SZXBvc2l0b3J5LmNzCisrKyBiL0VQUGx1cy9Gb3JtdWxhUGFyc2luZy9FeGNlbC9GdW5jdGlvbnMvRnVuY3Rpb25SZXBvc2l0b3J5LmNzCkBAIC05NCwxMCArOTQsNiBAQAogICAgICAgICAgICAgewogICAgICAgICAgICAgICAgIC8vIFJlcG9ydCB0aGF0IEV4Y2VsIGZ1bmN0aW9uIGlzIG5vdCBzdXBwb3J0ZWQgYnkgRVBQbHVzCiAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEZ1bmN0aW9uRXhjZXB0aW9uKHN0cmluZy5Gb3JtYXQoIkV4Y2VsIGZ1bmN0aW9uICd7MH0nIGlzIG5vdCBzdXBwb3J0ZWQgaW4gZm9ybXVsYXMuIiwgbmFtZSkpOwotCi0gICAgICAgICAgICAgICAgLy90aHJvdyBuZXcgSW52YWxpZE9wZXJhdGlvbkV4Y2VwdGlvbigiTm9uIHN1cHBvcnRlZCBmdW5jdGlvbjogIiArIG5hbWUpOwotICAgICAgICAgICAgICAgIC8vdGhyb3cgbmV3IEV4Y2VsRXJyb3JWYWx1ZUV4Y2VwdGlvbigiTm9uIHN1cHBvcnRlZCBmdW5jdGlvbjogIiArIG5hbWUsIEV4Y2VsRXJyb3JWYWx1ZS5DcmVhdGUoZUVycm9yVHlwZS5OYW1lKSk7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgICAgICAgICB9CiAgICAgICAgICAgICByZXR1cm4gX2Z1bmN0aW9uc1tuYW1lLlRvTG93ZXIoQ3VsdHVyZUluZm8uSW52YXJpYW50Q3VsdHVyZSldOwogICAgICAgICB9CmRpZmYgLS1naXQgYS9FUFBsdXMvRm9ybXVsYVBhcnNpbmcvRXhjZWxEYXRhUHJvdmlkZXIuY3MgYi9FUFBsdXMvRm9ybXVsYVBhcnNpbmcvRXhjZWxEYXRhUHJvdmlkZXIuY3MKaW5kZXggNDJmOTk2Yi4uMTdmMTI1NyAxMDA2NDQKLS0tIGEvRVBQbHVzL0Zvcm11bGFQYXJzaW5nL0V4Y2VsRGF0YVByb3ZpZGVyLmNzCisrKyBiL0VQUGx1cy9Gb3JtdWxhUGFyc2luZy9FeGNlbERhdGFQcm92aWRlci5jcwpAQCAtMSw4ICsxLDUgQEAKIO+7v3VzaW5nIE9mZmljZU9wZW5YbWwuRm9ybXVsYVBhcnNpbmcuTGV4aWNhbEFuYWx5c2lzOwotdXNpbmcgU3lzdGVtOwogdXNpbmcgU3lzdGVtLkNvbGxlY3Rpb25zLkdlbmVyaWM7Ci11c2luZyBTeXN0ZW0uTGlucTsKLXVzaW5nIFN5c3RlbS5UZXh0OwogCiBuYW1lc3BhY2UgT2ZmaWNlT3BlblhtbC5Gb3JtdWxhUGFyc2luZwogewpAQCAtMTAsNyArNyw3IEBACiAgICAgLy8vIFRoaXMgY2xhc3Mgc2hvdWxkIGJlIGltcGxlbWVudGVkIHRvIGJlIGFibGUgdG8gZGVsaXZlciBleGNlbCBkYXRhCiAgICAgLy8vIHRvIHRoZSBmb3JtdWxhIHBhcnNlci4KICAgICAvLy8gPC9zdW1tYXJ5PgotICAgIHB1YmxpYyBhYnN0cmFjdCBjbGFzcyBFeGNlbERhdGFQcm92aWRlciA6IElEaXNwb3NhYmxlCisgICAgcHVibGljIGFic3RyYWN0IGNsYXNzIEV4Y2VsRGF0YVByb3ZpZGVyCiAgICAgewogICAgICAgICAvLy8gPHN1bW1hcnk+CiAgICAgICAgIC8vLyBBIHJhbmdlIG9mIGNlbGxzIGluIGEgd29ya3NoZWV0LgpAQCAtMTA4LDExICsxMDUsNiBAQAogICAgICAgICBwdWJsaWMgYWJzdHJhY3QgRXhjZWxDZWxsQWRkcmVzcyBHZXREaW1lbnNpb25FbmQoc3RyaW5nIHdvcmtzaGVldCk7CiAKICAgICAgICAgLy8vIDxzdW1tYXJ5PgotICAgICAgICAvLy8gVXNlIHRoaXMgbWV0aG9kIHRvIGZyZWUgdW5tYW5hZ2VkIHJlc291cmNlcy4KLSAgICAgICAgLy8vIDwvc3VtbWFyeT4KLSAgICAgICAgcHVibGljIGFic3RyYWN0IHZvaWQgRGlzcG9zZSgpOwotCi0gICAgICAgIC8vLyA8c3VtbWFyeT4KICAgICAgICAgLy8vIE1heCBudW1iZXIgb2YgY29sdW1ucyBpbiBhIHdvcmtzaGVldCB0aGF0IHRoZSBFeGNlbCBkYXRhIHByb3ZpZGVyIGNhbiBoYW5kbGUuCiAgICAgICAgIC8vLyA8L3N1bW1hcnk+CiAgICAgICAgIHB1YmxpYyBhYnN0cmFjdCBpbnQgRXhjZWxNYXhDb2x1bW5zIHsgZ2V0OyB9CmRpZmYgLS1naXQgYS9FUFBsdXMvRm9ybXVsYVBhcnNpbmcvRXhwcmVzc2lvbkdyYXBoL0NvbXBpbGVSZXN1bHQuY3MgYi9FUFBsdXMvRm9ybXVsYVBhcnNpbmcvRXhwcmVzc2lvbkdyYXBoL0NvbXBpbGVSZXN1bHQuY3MKaW5kZXggZDE5NTljNi4uN2FiYzMyZSAxMDA2NDQKLS0tIGEvRVBQbHVzL0Zvcm11bGFQYXJzaW5nL0V4cHJlc3Npb25HcmFwaC9Db21waWxlUmVzdWx0LmNzCisrKyBiL0VQUGx1cy9Gb3JtdWxhUGFyc2luZy9FeHByZXNzaW9uR3JhcGgvQ29tcGlsZVJlc3VsdC5jcwpAQCAtMTA2LDcgKzEwNiw3IEBACiAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBkb3VibGUuUGFyc2UoUmVzdWx0LlRvU3RyaW5nKCksIE51bWJlclN0eWxlcy5GbG9hdCwgQ3VsdHVyZUluZm8uSW52YXJpYW50Q3VsdHVyZSk7CiAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBleCkKKyAgICAgICAgICAgICAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbikKICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgICAgICAgICAgICAgIH0KZGlmZiAtLWdpdCBhL0VQUGx1cy9Gb3JtdWxhUGFyc2luZy9FeHByZXNzaW9uR3JhcGgvRnVuY3Rpb25Db21waWxlcnMvSWZFcnJvckZ1bmN0aW9uQ29tcGlsZXIuY3MgYi9FUFBsdXMvRm9ybXVsYVBhcnNpbmcvRXhwcmVzc2lvbkdyYXBoL0Z1bmN0aW9uQ29tcGlsZXJzL0lmRXJyb3JGdW5jdGlvbkNvbXBpbGVyLmNzCmluZGV4IDU2M2M4MWIuLmE0MDk2MzIgMTAwNjQ0Ci0tLSBhL0VQUGx1cy9Gb3JtdWxhUGFyc2luZy9FeHByZXNzaW9uR3JhcGgvRnVuY3Rpb25Db21waWxlcnMvSWZFcnJvckZ1bmN0aW9uQ29tcGlsZXIuY3MKKysrIGIvRVBQbHVzL0Zvcm11bGFQYXJzaW5nL0V4cHJlc3Npb25HcmFwaC9GdW5jdGlvbkNvbXBpbGVycy9JZkVycm9yRnVuY3Rpb25Db21waWxlci5jcwpAQCAtMzgsNyArMzgsNyBAQAogICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGNhdGNoIChFeGNlbEVycm9yVmFsdWVFeGNlcHRpb24gZXgpCisgICAgICAgICAgICBjYXRjaCAoRXhjZWxFcnJvclZhbHVlRXhjZXB0aW9uKQogICAgICAgICAgICAgewogICAgICAgICAgICAgICAgIGFyZ3MuQWRkKG5ldyBGdW5jdGlvbkFyZ3VtZW50KGxhc3RDaGlsZC5Db21waWxlKCkuUmVzdWx0KSk7CiAgICAgICAgICAgICB9CmRpZmYgLS1naXQgYS9FUFBsdXMvRm9ybXVsYVBhcnNpbmcvRXhwcmVzc2lvbkdyYXBoL0Z1bmN0aW9uQ29tcGlsZXJzL0lmTmFGdW5jdGlvbkNvbXBpbGVyLmNzIGIvRVBQbHVzL0Zvcm11bGFQYXJzaW5nL0V4cHJlc3Npb25HcmFwaC9GdW5jdGlvbkNvbXBpbGVycy9JZk5hRnVuY3Rpb25Db21waWxlci5jcwppbmRleCBlMzE2YTc5Li5lY2ZmZjMxIDEwMDY0NAotLS0gYS9FUFBsdXMvRm9ybXVsYVBhcnNpbmcvRXhwcmVzc2lvbkdyYXBoL0Z1bmN0aW9uQ29tcGlsZXJzL0lmTmFGdW5jdGlvbkNvbXBpbGVyLmNzCisrKyBiL0VQUGx1cy9Gb3JtdWxhUGFyc2luZy9FeHByZXNzaW9uR3JhcGgvRnVuY3Rpb25Db21waWxlcnMvSWZOYUZ1bmN0aW9uQ29tcGlsZXIuY3MKQEAgLTM2LDcgKzM2LDcgQEAKICAgICAgICAgICAgICAgICB9CiAKICAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGNhdGNoIChFeGNlbEVycm9yVmFsdWVFeGNlcHRpb24gZXgpCisgICAgICAgICAgICBjYXRjaCAoRXhjZWxFcnJvclZhbHVlRXhjZXB0aW9uKQogICAgICAgICAgICAgewogICAgICAgICAgICAgICAgIGFyZ3MuQWRkKG5ldyBGdW5jdGlvbkFyZ3VtZW50KGxhc3RDaGlsZC5Db21waWxlKCkuUmVzdWx0KSk7CiAgICAgICAgICAgICB9CmRpZmYgLS1naXQgYS9FUFBsdXMvRm9ybXVsYVBhcnNpbmcvRm9ybXVsYVBhcnNlci5jcyBiL0VQUGx1cy9Gb3JtdWxhUGFyc2luZy9Gb3JtdWxhUGFyc2VyLmNzCmluZGV4IGUwMjUxMTQuLmE3YWQyZDggMTAwNjQ0Ci0tLSBhL0VQUGx1cy9Gb3JtdWxhUGFyc2luZy9Gb3JtdWxhUGFyc2VyLmNzCisrKyBiL0VQUGx1cy9Gb3JtdWxhUGFyc2luZy9Gb3JtdWxhUGFyc2VyLmNzCkBAIC0zMSwyMiArMzEsMTYgQEAKIHVzaW5nIFN5c3RlbTsKIHVzaW5nIFN5c3RlbS5Db2xsZWN0aW9ucy5HZW5lcmljOwogdXNpbmcgU3lzdGVtLkxpbnE7Ci11c2luZyBTeXN0ZW0uVGV4dDsKIHVzaW5nIE9mZmljZU9wZW5YbWwuRm9ybXVsYVBhcnNpbmcuRXhwcmVzc2lvbkdyYXBoOwotdXNpbmcgT2ZmaWNlT3BlblhtbC5Gb3JtdWxhUGFyc2luZzsKLXVzaW5nIE9mZmljZU9wZW5YbWwuRm9ybXVsYVBhcnNpbmcuRXhjZWwuT3BlcmF0b3JzOwogdXNpbmcgT2ZmaWNlT3BlblhtbC5Gb3JtdWxhUGFyc2luZy5MZXhpY2FsQW5hbHlzaXM7Ci11c2luZyBPZmZpY2VPcGVuWG1sLkZvcm11bGFQYXJzaW5nLkV4Y2VsOwogdXNpbmcgT2ZmaWNlT3BlblhtbC5Gb3JtdWxhUGFyc2luZy5FeGNlbC5GdW5jdGlvbnM7CiB1c2luZyBPZmZpY2VPcGVuWG1sLkZvcm11bGFQYXJzaW5nLkV4Y2VsVXRpbGl0aWVzOwotdXNpbmcgT2ZmaWNlT3BlblhtbC5Gb3JtdWxhUGFyc2luZy5Mb2dnaW5nOwogdXNpbmcgT2ZmaWNlT3BlblhtbC5Gb3JtdWxhUGFyc2luZy5VdGlsaXRpZXM7Ci11c2luZyBTeXN0ZW0uRGlhZ25vc3RpY3M7CiB1c2luZyBPZmZpY2VPcGVuWG1sLkZvcm11bGFQYXJzaW5nLkV4Y2VwdGlvbnM7CiAKIG5hbWVzcGFjZSBPZmZpY2VPcGVuWG1sLkZvcm11bGFQYXJzaW5nCiB7Ci0gICAgcHVibGljIGNsYXNzIEZvcm11bGFQYXJzZXIgOiBJRGlzcG9zYWJsZQorICAgIHB1YmxpYyBjbGFzcyBGb3JtdWxhUGFyc2VyCiAgICAgewogICAgICAgICBwcml2YXRlIHJlYWRvbmx5IFBhcnNpbmdDb250ZXh0IF9wYXJzaW5nQ29udGV4dDsKICAgICAgICAgcHJpdmF0ZSByZWFkb25seSBFeGNlbERhdGFQcm92aWRlciBfZXhjZWxEYXRhUHJvdmlkZXI7CkBAIC0yMjgsMTggKzIyMiw1IEBACiAgICAgICAgICAgICAgICAgcmV0dXJuIGdyYXBoOwogICAgICAgICAgICAgfQogICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIElGb3JtdWxhUGFyc2VyTG9nZ2VyIExvZ2dlcgotICAgICAgICB7Ci0gICAgICAgICAgICBnZXQgeyByZXR1cm4gX3BhcnNpbmdDb250ZXh0LkNvbmZpZ3VyYXRpb24uTG9nZ2VyOyB9Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgdm9pZCBEaXNwb3NlKCkKLSAgICAgICAgewotICAgICAgICAgICAgaWYgKF9wYXJzaW5nQ29udGV4dC5EZWJ1ZykKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBfcGFyc2luZ0NvbnRleHQuQ29uZmlndXJhdGlvbi5Mb2dnZXIuRGlzcG9zZSgpOwotICAgICAgICAgICAgfQotICAgICAgICB9CiAgICAgfQogfQpkaWZmIC0tZ2l0IGEvRVBQbHVzL0Zvcm11bGFQYXJzaW5nL0Zvcm11bGFQYXJzZXJNYW5hZ2VyLmNzIGIvRVBQbHVzL0Zvcm11bGFQYXJzaW5nL0Zvcm11bGFQYXJzZXJNYW5hZ2VyLmNzCmluZGV4IGFhOTY1OGIuLjUxYTUyMzQgMTAwNjQ0Ci0tLSBhL0VQUGx1cy9Gb3JtdWxhUGFyc2luZy9Gb3JtdWxhUGFyc2VyTWFuYWdlci5jcworKysgYi9FUFBsdXMvRm9ybXVsYVBhcnNpbmcvRm9ybXVsYVBhcnNlck1hbmFnZXIuY3MKQEAgLTEwMiwzMSArMTAyLDUgQEAKICAgICAgICAgewogICAgICAgICAgICAgcmV0dXJuIF9wYXJzZXIuUGFyc2VUb0dyYXBoKGZvcm11bGEpOwogICAgICAgICB9Ci0KLSAgICAgICAgLy8vIDxzdW1tYXJ5PgotICAgICAgICAvLy8gQXR0YWNoZXMgYSBsb2dnZXIgdG8gdGhlIDxzZWUgY3JlZj0iRm9ybXVsYVBhcnNlciIvPi4KLSAgICAgICAgLy8vIDwvc3VtbWFyeT4KLSAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJsb2dnZXIiPkFuIGluc3RhbmNlIG9mIDxzZWUgY3JlZj0iSUZvcm11bGFQYXJzZXJMb2dnZXIiLz48L3BhcmFtPgotICAgICAgICAvLy8gPHNlZSBjcmVmPSJPZmZpY2VPcGVuWG1sLkZvcm11bGFQYXJzaW5nLkxvZ2dpbmcuTG9nZ2VyRmFjdG9yeSIvPgotICAgICAgICBwdWJsaWMgdm9pZCBBdHRhY2hMb2dnZXIoSUZvcm11bGFQYXJzZXJMb2dnZXIgbG9nZ2VyKQotICAgICAgICB7Ci0gICAgICAgICAgICBfcGFyc2VyLkNvbmZpZ3VyZShjID0+IGMuQXR0YWNoTG9nZ2VyKGxvZ2dlcikpOwotICAgICAgICB9Ci0KLSAgICAgICAgLy8vIDxzdW1tYXJ5PgotICAgICAgICAvLy8gQXR0YWNoZXMgYSBsb2dnZXIgdG8gdGhlIGZvcm11bGEgcGFyc2VyIHRoYXQgcHJvZHVjZXMgb3V0cHV0IHRvIHRoZSBzdXBwbGllZCBsb2dmaWxlLgotICAgICAgICAvLy8gPC9zdW1tYXJ5PgotICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImxvZ2ZpbGUiPjwvcGFyYW0+Ci0gICAgICAgIHB1YmxpYyB2b2lkIEF0dGFjaExvZ2dlcihGaWxlSW5mbyBsb2dmaWxlKQotICAgICAgICB7Ci0gICAgICAgICAgICBfcGFyc2VyLkNvbmZpZ3VyZShjID0+IGMuQXR0YWNoTG9nZ2VyKExvZ2dlckZhY3RvcnkuQ3JlYXRlVGV4dEZpbGVMb2dnZXIobG9nZmlsZSkpKTsKLSAgICAgICAgfQotICAgICAgICAvLy8gPHN1bW1hcnk+Ci0gICAgICAgIC8vLyBEZXRhY2hlcyBhbnkgYXR0YWNoZWQgbG9nZ2VyIGZyb20gdGhlIGZvcm11bGEgcGFyc2VyLgotICAgICAgICAvLy8gPC9zdW1tYXJ5PgotICAgICAgICBwdWJsaWMgdm9pZCBEZXRhY2hMb2dnZXIoKQotICAgICAgICB7Ci0gICAgICAgICAgICBfcGFyc2VyLkNvbmZpZ3VyZShjID0+IGMuRGV0YWNoTG9nZ2VyKCkpOwotICAgICAgICB9CiAgICAgfQogfQpkaWZmIC0tZ2l0IGEvRVBQbHVzL0Zvcm11bGFQYXJzaW5nL0xvZ2dpbmcvTG9nZ2VyRmFjdG9yeS5jcyBiL0VQUGx1cy9Gb3JtdWxhUGFyc2luZy9Mb2dnaW5nL0xvZ2dlckZhY3RvcnkuY3MKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDNiMzBlODEuLjAwMDAwMDAKLS0tIGEvRVBQbHVzL0Zvcm11bGFQYXJzaW5nL0xvZ2dpbmcvTG9nZ2VyRmFjdG9yeS5jcworKysgL2Rldi9udWxsCkBAIC0xLDI0ICswLDAgQEAKLe+7v3VzaW5nIFN5c3RlbTsKLXVzaW5nIFN5c3RlbS5Db2xsZWN0aW9ucy5HZW5lcmljOwotdXNpbmcgU3lzdGVtLklPOwotdXNpbmcgU3lzdGVtLkxpbnE7Ci11c2luZyBTeXN0ZW0uVGV4dDsKLQotbmFtZXNwYWNlIE9mZmljZU9wZW5YbWwuRm9ybXVsYVBhcnNpbmcuTG9nZ2luZwotewotICAgIC8vLyA8c3VtbWFyeT4KLSAgICAvLy8gQ3JlYXRlIGxvZ2dlcnMgdGhhdCBjYW4gYmUgdXNlZCBmb3IgbG9nZ2luZyB0aGUgZm9ybXVsYSBwYXJzZXIuCi0gICAgLy8vIDwvc3VtbWFyeT4KLSAgICBwdWJsaWMgc3RhdGljIGNsYXNzIExvZ2dlckZhY3RvcnkKLSAgICB7Ci0gICAgICAgIC8vLyA8c3VtbWFyeT4KLSAgICAgICAgLy8vIENyZWF0ZXMgYSBsb2dnZXIgdGhhdCBsb2dzIHRvIGEgc2ltcGxlIHRleHRmaWxlLgotICAgICAgICAvLy8gPC9zdW1tYXJ5PgotICAgICAgICAvLy8gPHBhcmFtIG5hbWU9ImZpbGUiPjwvcGFyYW0+Ci0gICAgICAgIC8vLyA8cmV0dXJucz48L3JldHVybnM+Ci0gICAgICAgIHB1YmxpYyBzdGF0aWMgSUZvcm11bGFQYXJzZXJMb2dnZXIgQ3JlYXRlVGV4dEZpbGVMb2dnZXIoRmlsZUluZm8gZmlsZSkKLSAgICAgICAgewotICAgICAgICAgICAgcmV0dXJuIG5ldyBUZXh0RmlsZUxvZ2dlcihmaWxlKTsKLSAgICAgICAgfQotICAgIH0KLX0KZGlmZiAtLWdpdCBhL0VQUGx1cy9Gb3JtdWxhUGFyc2luZy9Mb2dnaW5nL1RleHRGaWxlTG9nZ2VyLmNzIGIvRVBQbHVzL0Zvcm11bGFQYXJzaW5nL0xvZ2dpbmcvVGV4dEZpbGVMb2dnZXIuY3MKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGFiYzlmMTcuLjAwMDAwMDAKLS0tIGEvRVBQbHVzL0Zvcm11bGFQYXJzaW5nL0xvZ2dpbmcvVGV4dEZpbGVMb2dnZXIuY3MKKysrIC9kZXYvbnVsbApAQCAtMSwxMTIgKzAsMCBAQAot77u/dXNpbmcgU3lzdGVtOwotdXNpbmcgU3lzdGVtLkNvbGxlY3Rpb25zLkdlbmVyaWM7Ci11c2luZyBTeXN0ZW0uSU87Ci11c2luZyBTeXN0ZW0uTGlucTsKLXVzaW5nIFN5c3RlbS5UZXh0OwotdXNpbmcgT2ZmaWNlT3BlblhtbC5Gb3JtdWxhUGFyc2luZy5FeGNlbC5GdW5jdGlvbnMuTG9naWNhbDsKLXVzaW5nIE9mZmljZU9wZW5YbWwuRm9ybXVsYVBhcnNpbmcuRXhjZWwuRnVuY3Rpb25zLk1hdGg7Ci0KLW5hbWVzcGFjZSBPZmZpY2VPcGVuWG1sLkZvcm11bGFQYXJzaW5nLkxvZ2dpbmcKLXsKLSAgICBpbnRlcm5hbCBjbGFzcyBUZXh0RmlsZUxvZ2dlciA6IElGb3JtdWxhUGFyc2VyTG9nZ2VyCi0gICAgewotICAgICAgICBwcml2YXRlIFN0cmVhbVdyaXRlciBfc3c7Ci0gICAgICAgIHByaXZhdGUgY29uc3Qgc3RyaW5nIFNlcGFyYXRvciA9ICI9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0iOwotICAgICAgICBwcml2YXRlIGludCBfY291bnQ7Ci0gICAgICAgIHByaXZhdGUgRGF0ZVRpbWUgX3N0YXJ0VGltZSA9IERhdGVUaW1lLk5vdzsKLSAgICAgICAgcHJpdmF0ZSBEaWN0aW9uYXJ5PHN0cmluZywgaW50PiBfZnVuY3MgPSBuZXcgRGljdGlvbmFyeTxzdHJpbmcsIGludD4oKTsKLSAgICAgICAgcHJpdmF0ZSBEaWN0aW9uYXJ5PHN0cmluZywgbG9uZz4gX2Z1bmNQZXJmb3JtYW5jZSA9IG5ldyBEaWN0aW9uYXJ5PHN0cmluZywgbG9uZz4oKTsKLSAgICAgICAgaW50ZXJuYWwgVGV4dEZpbGVMb2dnZXIoRmlsZUluZm8gZmlsZUluZm8pCi0gICAgICAgIHsKLSAgICAgICAgICAgIF9zdyA9IG5ldyBTdHJlYW1Xcml0ZXIoZmlsZUluZm8uRnVsbE5hbWUpOwotICAgICAgICB9Ci0KLSAgICAgICAgcHJpdmF0ZSB2b2lkIFdyaXRlU2VwYXJhdG9yQW5kVGltZVN0YW1wKCkKLSAgICAgICAgewotICAgICAgICAgICAgX3N3LldyaXRlTGluZShTZXBhcmF0b3IpOwotICAgICAgICAgICAgX3N3LldyaXRlTGluZSgiVGltZXN0YW1wOiB7MH0iLCBEYXRlVGltZS5Ob3cpOwotICAgICAgICAgICAgX3N3LldyaXRlTGluZSgpOwotICAgICAgICB9Ci0KLSAgICAgICAgcHJpdmF0ZSB2b2lkIFdyaXRlQWRkcmVzc0luZm8oUGFyc2luZ0NvbnRleHQgY29udGV4dCkKLSAgICAgICAgewotICAgICAgICAgICAgaWYgKGNvbnRleHQuU2NvcGVzLkN1cnJlbnQgIT0gbnVsbCAmJiBjb250ZXh0LlNjb3Blcy5DdXJyZW50LkFkZHJlc3MgIT0gbnVsbCkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBfc3cuV3JpdGVMaW5lKCJXb3Jrc2hlZXQ6IHswfSIsIGNvbnRleHQuU2NvcGVzLkN1cnJlbnQuQWRkcmVzcy5Xb3Jrc2hlZXQgPz8gIjxub3Qgc3BlY2lmaWVkPiIpOwotICAgICAgICAgICAgICAgIF9zdy5Xcml0ZUxpbmUoIkFkZHJlc3M6IHswfSIsIGNvbnRleHQuU2NvcGVzLkN1cnJlbnQuQWRkcmVzcy5BZGRyZXNzID8/ICI8bm90IGF2YWlsYWJsZT4iKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyB2b2lkIExvZyhQYXJzaW5nQ29udGV4dCBjb250ZXh0LCBFeGNlcHRpb24gZXgpCi0gICAgICAgIHsKLSAgICAgICAgICAgIFdyaXRlU2VwYXJhdG9yQW5kVGltZVN0YW1wKCk7Ci0gICAgICAgICAgICBXcml0ZUFkZHJlc3NJbmZvKGNvbnRleHQpOwotICAgICAgICAgICAgX3N3LldyaXRlTGluZShleCk7Ci0gICAgICAgICAgICBfc3cuV3JpdGVMaW5lKCk7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgdm9pZCBMb2coUGFyc2luZ0NvbnRleHQgY29udGV4dCwgc3RyaW5nIG1lc3NhZ2UpCi0gICAgICAgIHsKLSAgICAgICAgICAgIFdyaXRlU2VwYXJhdG9yQW5kVGltZVN0YW1wKCk7Ci0gICAgICAgICAgICBXcml0ZUFkZHJlc3NJbmZvKGNvbnRleHQpOwotICAgICAgICAgICAgX3N3LldyaXRlTGluZShtZXNzYWdlKTsKLSAgICAgICAgICAgIF9zdy5Xcml0ZUxpbmUoKTsKLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyB2b2lkIExvZyhzdHJpbmcgbWVzc2FnZSkKLSAgICAgICAgewotICAgICAgICAgICAgV3JpdGVTZXBhcmF0b3JBbmRUaW1lU3RhbXAoKTsKLSAgICAgICAgICAgIF9zdy5Xcml0ZUxpbmUobWVzc2FnZSk7Ci0gICAgICAgICAgICBfc3cuV3JpdGVMaW5lKCk7Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgdm9pZCBMb2dDZWxsQ291bnRlZCgpCi0gICAgICAgIHsKLSAgICAgICAgICAgIF9jb3VudCsrOwotICAgICAgICAgICAgaWYgKF9jb3VudCU1MDAgPT0gMCkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBfc3cuV3JpdGVMaW5lKFNlcGFyYXRvcik7Ci0gICAgICAgICAgICAgICAgdmFyIHRpbWVFbGxhcHNlZCA9IERhdGVUaW1lLk5vdy5TdWJ0cmFjdChfc3RhcnRUaW1lKTsKLSAgICAgICAgICAgICAgICBfc3cuV3JpdGVMaW5lKCJ7MH0gY2VsbHMgcGFyc2VkLCB0aW1lIHsxfSBzZWNvbmRzIiwgX2NvdW50LCB0aW1lRWxsYXBzZWQuVG90YWxTZWNvbmRzKTsKLQotICAgICAgICAgICAgICAgIHZhciBmdW5jcyA9IF9mdW5jcy5LZXlzLk9yZGVyQnlEZXNjZW5kaW5nKHggPT4gX2Z1bmNzW3hdKS5Ub0xpc3QoKTsKLSAgICAgICAgICAgICAgICBmb3JlYWNoICh2YXIgZnVuYyBpbiBmdW5jcykKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgIF9zdy5Xcml0ZShmdW5jICsgIiAgLSAiICsgX2Z1bmNzW2Z1bmNdKTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKF9mdW5jUGVyZm9ybWFuY2UuQ29udGFpbnNLZXkoZnVuYykpCi0gICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIF9zdy5Xcml0ZSgiIC0gYXZnOiAiICsgX2Z1bmNQZXJmb3JtYW5jZVtmdW5jXS9fZnVuY3NbZnVuY10gKyAiIG1pbGxpc2Vjb25kcyIpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIF9zdy5Xcml0ZUxpbmUoKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgX3N3LldyaXRlTGluZSgpOwotICAgICAgICAgICAgICAgIF9mdW5jcy5DbGVhcigpOwotCi0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLQotICAgICAgICBwdWJsaWMgdm9pZCBMb2dGdW5jdGlvbihzdHJpbmcgZnVuYykKLSAgICAgICAgewotICAgICAgICAgICAgaWYgKCFfZnVuY3MuQ29udGFpbnNLZXkoZnVuYykpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgX2Z1bmNzLkFkZChmdW5jLCAwKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIF9mdW5jc1tmdW5jXSsrOwotICAgICAgICB9Ci0KLSAgICAgICAgcHVibGljIHZvaWQgTG9nRnVuY3Rpb24oc3RyaW5nIGZ1bmMsIGxvbmcgbWlsbGlzZWNvbmRzKQotICAgICAgICB7Ci0gICAgICAgICAgICBpZiAoIV9mdW5jUGVyZm9ybWFuY2UuQ29udGFpbnNLZXkoZnVuYykpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgX2Z1bmNQZXJmb3JtYW5jZVtmdW5jXSA9IDA7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBfZnVuY1BlcmZvcm1hbmNlW2Z1bmNdICs9IG1pbGxpc2Vjb25kczsKLSAgICAgICAgfQotCi0gICAgICAgIHB1YmxpYyB2b2lkIERpc3Bvc2UoKQotICAgICAgICB7Ci0gICAgICAgICAgICBfc3cuQ2xvc2UoKTsgCi0gICAgICAgICAgICBfc3cuRGlzcG9zZSgpOwotICAgICAgICB9Ci0gICAgfQotfQpkaWZmIC0tZ2l0IGEvRVBQbHVzL09mZmljZVByb3BlcnRpZXMuY3MgYi9FUFBsdXMvT2ZmaWNlUHJvcGVydGllcy5jcwppbmRleCA2ZTI5ZDc4Li5kOWU4M2JhIDEwMDY0NAotLS0gYS9FUFBsdXMvT2ZmaWNlUHJvcGVydGllcy5jcworKysgYi9FUFBsdXMvT2ZmaWNlUHJvcGVydGllcy5jcwpAQCAtNCw3ICs0LDcgQEAKICAqIEVQUGx1cyBwcm92aWRlcyBzZXJ2ZXItc2lkZSBnZW5lcmF0aW9uIG9mIEV4Y2VsIDIwMDcvMjAxMCBzcHJlYWRzaGVldHMuCiAgKiBTZWUgaHR0cDovL3d3dy5jb2RlcGxleC5jb20vRVBQbHVzIGZvciBkZXRhaWxzLgogICoKLSAqIENvcHlyaWdodCAoQykgMjAxMSAgSmFuIEvkbGxtYW4KKyAqIENvcHlyaWdodCAoQykgMjAxMSAgSmFuIEvvv71sbG1hbgogICoKICAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKQEAgLTI2LDkgKzI2LDkgQEAKICAqIAogICogQXV0aG9yCQkJCQkJCUNoYW5nZQkJCQkJCURhdGUKICAqICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgotICogSmFuIEvkbGxtYW4JCSAgICAgICAgICAgICAgICBJbml0aWFsIFJlbGVhc2UJCSAgICAgICAgMjAwOS0xMC0wMQotICogSmFuIEvkbGxtYW4gICAgICAgICAgICAgICAgICAgICAgVG90YWwgcmV3cml0ZSAgICAgICAgICAgICAgIDIwMTAtMDMtMDEKLSAqIEphbiBL5GxsbWFuCQkgICAgTGljZW5zZSBjaGFuZ2VkIEdQTC0tPkxHUEwgIDIwMTEtMTItMjcKKyAqIEphbiBL77+9bGxtYW4JCSAgICAgICAgICAgICAgICBJbml0aWFsIFJlbGVhc2UJCSAgICAgICAgMjAwOS0xMC0wMQorICogSmFuIEvvv71sbG1hbiAgICAgICAgICAgICAgICAgICAgICBUb3RhbCByZXdyaXRlICAgICAgICAgICAgICAgMjAxMC0wMy0wMQorICogSmFuIEvvv71sbG1hbgkJICAgIExpY2Vuc2UgY2hhbmdlZCBHUEwtLT5MR1BMICAyMDExLTEyLTI3CiAgKiBSYXppcSBZb3JrICAgICAgICAgICAgICAgICAgICAgICBBZGRlZCBDcmVhdGVkICYgTW9kaWZpZWQgICAgMjAxNC0wOC0yMAogICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCiB1c2luZyBTeXN0ZW07CkBAIC0xMTcsMTEgKzExNyw5IEBACiAgICAgICAgICAgICAgICAgU3RyZWFtV3JpdGVyIHN0cmVhbSA9IG5ldyBTdHJlYW1Xcml0ZXIocGFydC5HZXRTdHJlYW0oRmlsZU1vZGUuQ3JlYXRlLCBGaWxlQWNjZXNzLldyaXRlKSk7CiAgICAgICAgICAgICAgICAgeG1sRG9jLlNhdmUoc3RyZWFtKTsKICAgICAgICAgICAgICAgICAvL3N0cmVhbS5DbG9zZSgpOwotICAgICAgICAgICAgICAgIF9wYWNrYWdlLlBhY2thZ2UuRmx1c2goKTsKIAogICAgICAgICAgICAgICAgIC8vIGNyZWF0ZSB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gdGhlIHdvcmtib29rIGFuZCB0aGUgbmV3IHNoYXJlZCBzdHJpbmdzIHBhcnQKICAgICAgICAgICAgICAgICBfcGFja2FnZS5QYWNrYWdlLkNyZWF0ZVJlbGF0aW9uc2hpcChVcmlIZWxwZXIuR2V0UmVsYXRpdmVVcmkobmV3IFVyaSgiL3hsIiwgVXJpS2luZC5SZWxhdGl2ZSksIHVyaSksIFBhY2thZ2luZy5UYXJnZXRNb2RlLkludGVybmFsLCByZWxhdGlvbnNoaXApOwotICAgICAgICAgICAgICAgIF9wYWNrYWdlLlBhY2thZ2UuRmx1c2goKTsKICAgICAgICAgICAgIH0KICAgICAgICAgICAgIHJldHVybiB4bWxEb2M7CiAgICAgICAgIH0KZGlmZiAtLWdpdCBhL0VQUGx1cy9QYWNrYWdpbmcvWmlwUGFja2FnZS5jcyBiL0VQUGx1cy9QYWNrYWdpbmcvWmlwUGFja2FnZS5jcwppbmRleCBjNDdkNWVhLi4xMmUzNDMxIDEwMDY0NAotLS0gYS9FUFBsdXMvUGFja2FnaW5nL1ppcFBhY2thZ2UuY3MKKysrIGIvRVBQbHVzL1BhY2thZ2luZy9aaXBQYWNrYWdlLmNzCkBAIC05NCw3ICs5NCw3IEBACiAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgdmFyIHJlbHMgPSBuZXcgRGljdGlvbmFyeTxzdHJpbmcsIFppcEFyY2hpdmVFbnRyeT4oKTsKICAgICAgICAgICAgICAgICBzdHJlYW0uU2VlaygwLCBTZWVrT3JpZ2luLkJlZ2luKTsKLSAgICAgICAgICAgICAgICB1c2luZyB2YXIgemlwID0gbmV3IFppcEFyY2hpdmUoc3RyZWFtKTsKKyAgICAgICAgICAgICAgICB1c2luZyB2YXIgemlwID0gbmV3IFppcEFyY2hpdmUoc3RyZWFtLCBaaXBBcmNoaXZlTW9kZS5SZWFkLCBsZWF2ZU9wZW46IHRydWUpOwogICAgICAgICAgICAgICAgIGZvcmVhY2ggKHZhciBlIGluIHppcC5FbnRyaWVzKQogICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgaWYgKGUuTGVuZ3RoID4gMCkKQEAgLTE0OCwxMSArMTQ4LDcgQEAKICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgaWYgKCFoYXNDb250ZW50VHlwZVhtbCkKICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgIHRocm93IChuZXcgSW52YWxpZERhdGFFeGNlcHRpb24oIlRoZSBmaWxlIGlzIG5vdCBhbiB2YWxpZCBQYWNrYWdlIGZpbGUuIElmIHRoZSBmaWxlIGlzIGVuY3J5cHRlZCwgcGxlYXNlIHN1cHBseSB0aGUgcGFzc3dvcmQgaW4gdGhlIGNvbnN0cnVjdG9yLiIpKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgaWYgKCFoYXNDb250ZW50VHlwZVhtbCkKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgIHRocm93IChuZXcgSW52YWxpZERhdGFFeGNlcHRpb24oIlRoZSBmaWxlIGlzIG5vdCBhbiB2YWxpZCBQYWNrYWdlIGZpbGUuIElmIHRoZSBmaWxlIGlzIGVuY3J5cHRlZCwgcGxlYXNlIHN1cHBseSB0aGUgcGFzc3dvcmQgaW4gdGhlIGNvbnN0cnVjdG9yLiIpKTsKKyAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWREYXRhRXhjZXB0aW9uKCJUaGUgZmlsZSBpcyBub3QgYW4gdmFsaWQgUGFja2FnZSBmaWxlLiIpOwogICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgIH0KICAgICAgICAgfQpAQCAtMjUyLDcgKzI0OCw3IEBACiAgICAgICAgIH0KICAgICAgICAgaW50ZXJuYWwgdm9pZCBTYXZlKFN0cmVhbSBzdHJlYW0pCiAgICAgICAgIHsKLSAgICAgICAgICAgIHVzaW5nIHZhciB6aXBBcmNoaXZlID0gbmV3IFppcEFyY2hpdmUoc3RyZWFtLCBaaXBBcmNoaXZlTW9kZS5DcmVhdGUpOworICAgICAgICAgICAgdXNpbmcgdmFyIHppcEFyY2hpdmUgPSBuZXcgWmlwQXJjaGl2ZShzdHJlYW0sIFppcEFyY2hpdmVNb2RlLkNyZWF0ZSwgbGVhdmVPcGVuOiB0cnVlKTsKICAgICAgICAgICAgIC8qKioqIENvbnRlbnRUeXBlKioqKi8KICAgICAgICAgICAgIHZhciBjb250ZW50VHlwZXNFbnRyeSA9IHppcEFyY2hpdmUuQ3JlYXRlRW50cnkoIltDb250ZW50X1R5cGVzXS54bWwiKTsKICAgICAgICAgICAgIHVzaW5nICh2YXIgY29udGVudFR5cGVzV3JpdGVyID0gbmV3IFN0cmVhbVdyaXRlcihjb250ZW50VHlwZXNFbnRyeS5PcGVuKCkpKQpAQCAtMjk4LDE0ICsyOTQsNiBAQAogICAgICAgICAgICAgeG1sLkFwcGVuZCgiPC9UeXBlcz4iKTsKICAgICAgICAgICAgIHJldHVybiB4bWwuVG9TdHJpbmcoKTsKICAgICAgICAgfQotICAgICAgICBpbnRlcm5hbCB2b2lkIEZsdXNoKCkKLSAgICAgICAgewotCi0gICAgICAgIH0KLSAgICAgICAgaW50ZXJuYWwgdm9pZCBDbG9zZSgpCi0gICAgICAgIHsKLSAgICAgICAgICAgIAotICAgICAgICB9CiAgICAgICAgIENvbXByZXNzaW9uTGV2ZWwgX2NvbXByZXNzaW9uID0gQ29tcHJlc3Npb25MZXZlbC5EZWZhdWx0OwogICAgICAgICBwdWJsaWMgQ29tcHJlc3Npb25MZXZlbCBDb21wcmVzc2lvbiAKICAgICAgICAgeyAKZGlmZiAtLWdpdCBhL0VQUGx1cy9VdGlscy9Db21wb3VuZERvY3VtZW50LmNzIGIvRVBQbHVzL1V0aWxzL0NvbXBvdW5kRG9jdW1lbnQuY3MKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDMzYzRjZTIuLjAwMDAwMDAKLS0tIGEvRVBQbHVzL1V0aWxzL0NvbXBvdW5kRG9jdW1lbnQuY3MKKysrIC9kZXYvbnVsbApAQCAtMSw3NTUgKzAsMCBAQAot77u/LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKLSAqIFlvdSBtYXkgYW1lbmQgYW5kIGRpc3RyaWJ1dGUgYXMgeW91IGxpa2UsIGJ1dCBkb24ndCByZW1vdmUgdGhpcyBoZWFkZXIhCi0gKgotICogRVBQbHVzIHByb3ZpZGVzIHNlcnZlci1zaWRlIGdlbmVyYXRpb24gb2YgRXhjZWwgMjAwNy8yMDEwIHNwcmVhZHNoZWV0cy4KLSAqIFNlZSBodHRwOi8vd3d3LmNvZGVwbGV4LmNvbS9FUFBsdXMgZm9yIGRldGFpbHMuCi0gKgotICogQ29weXJpZ2h0IChDKSAyMDExICBKYW4gS8OkbGxtYW4KLSAqCi0gKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCi0gKiBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCi0gKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKLSAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgotCi0gKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKLSAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCi0gKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICAKLSAqIFNlZSB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCi0gKgotICogVGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBjYW4gYmUgdmlld2VkIGF0IGh0dHA6Ly93d3cub3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvbGdwbC1saWNlbnNlLnBocAotICogSWYgeW91IHVuZmFtaWxpYXIgd2l0aCB0aGlzIGxpY2Vuc2Ugb3IgaGF2ZSBxdWVzdGlvbnMgYWJvdXQgaXQsIGhlcmUgaXMgYW4gaHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2dwbC1mYXEuaHRtbAotICoKLSAqIEFsbCBjb2RlIGFuZCBleGVjdXRhYmxlcyBhcmUgcHJvdmlkZWQgImFzIGlzIiB3aXRoIG5vIHdhcnJhbnR5IGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuIAotICogVGhlIGF1dGhvciBhY2NlcHRzIG5vIGxpYWJpbGl0eSBmb3IgYW55IGRhbWFnZSBvciBsb3NzIG9mIGJ1c2luZXNzIHRoYXQgdGhpcyBwcm9kdWN0IG1heSBjYXVzZS4KLSAqCi0gKiBDb2RlIGNoYW5nZSBub3RlczoKLSAqIAotICogQXV0aG9yCQkJCQkJCUNoYW5nZQkJCQkJCURhdGUKLSAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCi0gKiBKYW4gS8OkbGxtYW4JCUFkZGVkCQkwMS0wMS0yMDEyCi0gKiBKYW4gS8OkbGxtYW4gICAgICBBZGRlZCBjb21wcmVzc2lvbiBzdXBwb3J0IDI3LTAzLTIwMTIKLSAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwotdXNpbmcgU3lzdGVtOwotdXNpbmcgU3lzdGVtLkNvbGxlY3Rpb25zLkdlbmVyaWM7Ci11c2luZyBTeXN0ZW0uTGlucTsKLXVzaW5nIFN5c3RlbS5UZXh0OwotdXNpbmcgU3lzdGVtLlJ1bnRpbWUuSW50ZXJvcFNlcnZpY2VzOwotdXNpbmcgY29tVHlwZXMgPSBTeXN0ZW0uUnVudGltZS5JbnRlcm9wU2VydmljZXMuQ29tVHlwZXM7Ci11c2luZyBTeXN0ZW0uSU87Ci11c2luZyBTeXN0ZW0uU2VjdXJpdHk7Ci0KLW5hbWVzcGFjZSBPZmZpY2VPcGVuWG1sLlV0aWxzCi17Ci0jaWYgIU1PTk8KLSAgICBpbnRlcm5hbCBjbGFzcyBDb21wb3VuZERvY3VtZW50Ci0gICAgeyAgICAgICAgCi0gICAgICAgIGludGVybmFsIGNsYXNzIFN0b3JhZ2VQYXJ0Ci0gICAgICAgIHsKLSAgICAgICAgICAgIHB1YmxpYyBTdG9yYWdlUGFydCgpCi0gICAgICAgICAgICB7Ci0KLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGludGVybmFsIERpY3Rpb25hcnk8c3RyaW5nLCBTdG9yYWdlUGFydD4gU3ViU3RvcmFnZSA9IG5ldyBEaWN0aW9uYXJ5PHN0cmluZywgU3RvcmFnZVBhcnQ+KCk7Ci0gICAgICAgICAgICBpbnRlcm5hbCBEaWN0aW9uYXJ5PHN0cmluZywgYnl0ZVtdPiBEYXRhU3RyZWFtcyA9IG5ldyBEaWN0aW9uYXJ5PHN0cmluZywgYnl0ZVtdPigpOwotICAgICAgICB9Ci0gICAgICAgIGludGVybmFsIFN0b3JhZ2VQYXJ0IFN0b3JhZ2UgPSBudWxsOwotICAgICAgICBpbnRlcm5hbCBDb21wb3VuZERvY3VtZW50KCkKLSAgICAgICAgewotICAgICAgICAgICAgU3RvcmFnZSA9IG5ldyBDb21wb3VuZERvY3VtZW50LlN0b3JhZ2VQYXJ0KCk7Ci0gICAgICAgIH0KLSAgICAgICAgaW50ZXJuYWwgQ29tcG91bmREb2N1bWVudChGaWxlSW5mbyBmaSkKLSAgICAgICAgewotICAgICAgICAgICAgUmVhZChmaSk7Ci0gICAgICAgIH0KLSAgICAgICAgaW50ZXJuYWwgQ29tcG91bmREb2N1bWVudChJTG9ja0J5dGVzIGxiKQotICAgICAgICB7Ci0gICAgICAgICAgICBSZWFkKGxiKTsKLSAgICAgICAgfQotICAgICAgICBpbnRlcm5hbCBDb21wb3VuZERvY3VtZW50KGJ5dGVbXSBkb2MpCi0gICAgICAgIHsKLSAgICAgICAgICAgIFJlYWQoZG9jKTsKLSAgICAgICAgfQotICAgICAgICBpbnRlcm5hbCB2b2lkIFJlYWQoRmlsZUluZm8gZmkpCi0gICAgICAgIHsKLSAgICAgICAgICAgIHZhciBiID0gRmlsZS5SZWFkQWxsQnl0ZXMoZmkuRnVsbE5hbWUpOwotICAgICAgICAgICAgUmVhZChiKTsKLSAgICAgICAgfQotICAgICAgICBbU2VjdXJpdHlTYWZlQ3JpdGljYWxdCi0gICAgICAgIGludGVybmFsIHZvaWQgUmVhZChieXRlW10gZG9jKQotICAgICAgICB7Ci0gICAgICAgICAgICBJTG9ja0J5dGVzIGxiOwotICAgICAgICAgICAgdmFyIGlyZXQgPSBDcmVhdGVJTG9ja0J5dGVzT25IR2xvYmFsKEludFB0ci5aZXJvLCB0cnVlLCBvdXQgbGIpOwotCi0gICAgICAgICAgICBJbnRQdHIgYnVmZmVyID0gTWFyc2hhbC5BbGxvY0hHbG9iYWwoZG9jLkxlbmd0aCk7Ci0gICAgICAgICAgICBNYXJzaGFsLkNvcHkoZG9jLCAwLCBidWZmZXIsIGRvYy5MZW5ndGgpOwotICAgICAgICAgICAgVUludFB0ciByZWFkU2l6ZTsKLSAgICAgICAgICAgIGxiLldyaXRlQXQoMCwgYnVmZmVyLCBkb2MuTGVuZ3RoLCBvdXQgcmVhZFNpemUpOwotICAgICAgICAgICAgTWFyc2hhbC5GcmVlSEdsb2JhbChidWZmZXIpOwotCi0gICAgICAgICAgICBSZWFkKGxiKTsKLSAgICAgICAgfQotCi0gICAgICAgIFtTZWN1cml0eVNhZmVDcml0aWNhbF0KLSAgICAgICAgaW50ZXJuYWwgdm9pZCBSZWFkKElMb2NrQnl0ZXMgbGIpCi0gICAgICAgIHsKLSAgICAgICAgICAgIGlmIChTdGdJc1N0b3JhZ2VJTG9ja0J5dGVzKGxiKSA9PSAwKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIElTdG9yYWdlIHN0b3JhZ2UgPSBudWxsOwotICAgICAgICAgICAgICAgIGlmIChTdGdPcGVuU3RvcmFnZU9uSUxvY2tCeXRlcygKLSAgICAgICAgICAgICAgICAgICAgbGIsCi0gICAgICAgICAgICAgICAgICAgIG51bGwsCi0gICAgICAgICAgICAgICAgICAgIFNUR00uRElSRUNUIHwgU1RHTS5SRUFEIHwgU1RHTS5TSEFSRV9FWENMVVNJVkUsCi0gICAgICAgICAgICAgICAgICAgIEludFB0ci5aZXJvLAotICAgICAgICAgICAgICAgICAgICAwLAotICAgICAgICAgICAgICAgICAgICBvdXQgc3RvcmFnZSkgPT0gMCkKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgIFN0b3JhZ2UgPSBuZXcgU3RvcmFnZVBhcnQoKTsKLSAgICAgICAgICAgICAgICAgICAgUmVhZFBhcnRzKHN0b3JhZ2UsIFN0b3JhZ2UpOwotICAgICAgICAgICAgICAgICAgICBNYXJzaGFsLlJlbGVhc2VDb21PYmplY3Qoc3RvcmFnZSk7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIHRocm93IChuZXcgSW52YWxpZERhdGFFeGNlcHRpb24oc3RyaW5nLkZvcm1hdCgiUGFydCBpcyBub3QgYSBjb21wb3VuZCBkb2N1bWVudCIpKSk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KLSAgICAgICAgI3JlZ2lvbiAgQ29tcHJlc3Npb24KLSAgICAgICAgLy8vIDxzdW1tYXJ5PgotICAgICAgICAvLy8gQ29tcHJlc3Npb24gdXNpbmcgYSBydW4gbGVuZ3RoIGVuY29kaW5nIGFsZ29yaXRobS4KLSAgICAgICAgLy8vIFNlZSBNUy1PVkJBIFNlY3Rpb24gMi40Ci0gICAgICAgIC8vLyA8L3N1bW1hcnk+Ci0gICAgICAgIC8vLyA8cGFyYW0gbmFtZT0icGFydCI+Qnl0ZSBhcnJheSB0byBkZWNvbXByZXNzPC9wYXJhbT4KLSAgICAgICAgLy8vIDxyZXR1cm5zPjwvcmV0dXJucz4KLSAgICAgICAgaW50ZXJuYWwgc3RhdGljIGJ5dGVbXSBDb21wcmVzc1BhcnQoYnl0ZVtdIHBhcnQpCi0gICAgICAgIHsKLSAgICAgICAgICAgIE1lbW9yeVN0cmVhbSBtcyA9IG5ldyBNZW1vcnlTdHJlYW0oNDA5Nik7Ci0gICAgICAgICAgICBCaW5hcnlXcml0ZXIgYnIgPSBuZXcgQmluYXJ5V3JpdGVyKG1zKTsKLSAgICAgICAgICAgIGJyLldyaXRlKChieXRlKTEpOwotCi0gICAgICAgICAgICBpbnQgY29tcFN0YXJ0ID0gMTsKLSAgICAgICAgICAgIGludCBjb21wRW5kID0gNDA5ODsKLSAgICAgICAgICAgIGludCBkZWNvbXBTdGFydCA9IDA7Ci0gICAgICAgICAgICBpbnQgZGVjb21wRW5kID0gcGFydC5MZW5ndGggPCA0MDk2ID8gcGFydC5MZW5ndGggOiA0MDk2OwotCi0gICAgICAgICAgICB3aGlsZSAoZGVjb21wU3RhcnQgPCBkZWNvbXBFbmQgJiYgY29tcFN0YXJ0IDwgY29tcEVuZCkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBieXRlW10gY2h1bmsgPSBDb21wcmVzc0NodW5rKHBhcnQsIHJlZiBkZWNvbXBTdGFydCk7Ci0gICAgICAgICAgICAgICAgdXNob3J0IGhlYWRlcjsKLSAgICAgICAgICAgICAgICBpZiAoY2h1bmsgPT0gbnVsbCB8fCBjaHVuay5MZW5ndGggPT0gMCkKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgIGhlYWRlciA9IDQwOTYgfCAweDYwMDsgIC8vQj0wMTEgQT0wCi0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgIGhlYWRlciA9ICh1c2hvcnQpKCgoY2h1bmsuTGVuZ3RoIC0gMSkgJiAweEZGRikpOwotICAgICAgICAgICAgICAgICAgICBoZWFkZXIgfD0gMHhCMDAwOyAgIC8vQj0wMTEgQT0xCi0gICAgICAgICAgICAgICAgICAgIGJyLldyaXRlKGhlYWRlcik7Ci0gICAgICAgICAgICAgICAgICAgIGJyLldyaXRlKGNodW5rKTsgICAgICAgICAgICAgICAgICAgIAotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBkZWNvbXBFbmQgPSBwYXJ0Lkxlbmd0aCA8IGRlY29tcFN0YXJ0ICsgNDA5NiA/IHBhcnQuTGVuZ3RoIDogZGVjb21wU3RhcnQrNDA5NjsKLSAgICAgICAgICAgIH0KLQotICAgICAgICAgICAgCi0gICAgICAgICAgICBici5GbHVzaCgpOwotICAgICAgICAgICAgcmV0dXJuIG1zLlRvQXJyYXkoKTsgICAgICAgIAotICAgICAgICB9Ci0gICAgICAgIHByaXZhdGUgc3RhdGljIGJ5dGVbXSBDb21wcmVzc0NodW5rKGJ5dGVbXSBidWZmZXIsIHJlZiBpbnQgc3RhcnRQb3MpCi0gICAgICAgIHsKLSAgICAgICAgICAgIHZhciBjb21wckJ1ZmZlcj1uZXcgYnl0ZVs0MDk2XTsKLSAgICAgICAgICAgIGludCBmbGFnUG9zID0gMDsKLSAgICAgICAgICAgIGludCBjUG9zPTE7Ci0gICAgICAgICAgICBpbnQgZFBvcyA9IHN0YXJ0UG9zOwotICAgICAgICAgICAgaW50IGRFbmQ9c3RhcnRQb3MrNDA5NiA8IGJ1ZmZlci5MZW5ndGg/IHN0YXJ0UG9zKzQwOTYgOiBidWZmZXIuTGVuZ3RoOwotICAgICAgICAgICAgd2hpbGUoZFBvczxkRW5kKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIGJ5dGUgdG9rZW5GbGFncyA9IDA7Ci0gICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCA4OyBpKyspCi0gICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICBpZiAoZFBvcyAtIHN0YXJ0UG9zID4gMCkKLSAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgaW50IGJlc3RDYW5kaWRhdGUgPSAtMTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGludCBiZXN0TGVuZ3RoID0gMDsKLSAgICAgICAgICAgICAgICAgICAgICAgIGludCBjYW5kaWRhdGUgPSBkUG9zIC0gMTsKLSAgICAgICAgICAgICAgICAgICAgICAgIGludCBiaXRDb3VudCA9IEdldExlbmd0aEJpdHMoZFBvcy1zdGFydFBvcyk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBpbnQgYml0cyA9ICgxNiAtIGJpdENvdW50KTsKLSAgICAgICAgICAgICAgICAgICAgICAgIHVzaG9ydCBsZW5ndGhNYXNrID0gKHVzaG9ydCkoKDB4RkZGRikgPj4gYml0cyk7Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlIChjYW5kaWRhdGUgPj0gc3RhcnRQb3MpCi0gICAgICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGJ1ZmZlcltjYW5kaWRhdGVdID09IGJ1ZmZlcltkUG9zXSkKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBsZW5ndGggPSAxOwotCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlIChidWZmZXIuTGVuZ3RoID4gZFBvcyArIGxlbmd0aCAmJiBidWZmZXJbY2FuZGlkYXRlICsgbGVuZ3RoXSA9PSBidWZmZXJbZFBvcyArIGxlbmd0aF0gJiYgbGVuZ3RoIDwgbGVuZ3RoTWFzayAmJiBkUG9zK2xlbmd0aCA8IGRFbmQpCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxlbmd0aCsrOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChsZW5ndGggPiBiZXN0TGVuZ3RoKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiZXN0Q2FuZGlkYXRlID0gY2FuZGlkYXRlOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYmVzdExlbmd0aCA9IGxlbmd0aDsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChiZXN0TGVuZ3RoID09IGxlbmd0aE1hc2spCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FuZGlkYXRlLS07Ci0gICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICBpZiAoYmVzdExlbmd0aCA+PSAzKSAgICAvL0NvcHkgdG9rZW4KLSAgICAgICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b2tlbkZsYWdzIHw9IChieXRlKSgxIDw8IGkpOwotCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgVUludDE2IG9mZnNldE1hc2sgPSAodXNob3J0KX5sZW5ndGhNYXNrOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVzaG9ydCB0b2tlbiA9ICh1c2hvcnQpKCgodXNob3J0KShkUG9zIC0gKGJlc3RDYW5kaWRhdGUrMSkpKSA8PCAoYml0Q291bnQpIHwgKHVzaG9ydCkoYmVzdExlbmd0aCAtIDMpKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBBcnJheS5Db3B5KEJpdENvbnZlcnRlci5HZXRCeXRlcyh0b2tlbiksIDAsIGNvbXByQnVmZmVyLCBjUG9zLCAyKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBkUG9zID0gZFBvcyArIGJlc3RMZW5ndGg7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgY1BvcyArPSAyOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vU2V0Q29weSBUb2tlbiAgICAgICAgICAgICAgICAgICAgICAgIAotICAgICAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbXByQnVmZmVyW2NQb3MrK10gPSBidWZmZXJbZFBvcysrXTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgICAgICAKLSAgICAgICAgICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBjb21wckJ1ZmZlcltjUG9zKytdID0gYnVmZmVyW2RQb3MrK107Ci0gICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgaWYgKGRQb3MgPj0gZEVuZCkgYnJlYWs7Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIGNvbXByQnVmZmVyW2ZsYWdQb3NdID0gdG9rZW5GbGFnczsKLSAgICAgICAgICAgICAgICBmbGFnUG9zID0gY1BvcysrOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgdmFyIHJldCA9IG5ldyBieXRlW2NQb3MgLSAxXTsKLSAgICAgICAgICAgIEFycmF5LkNvcHkoY29tcHJCdWZmZXIsIHJldCwgcmV0Lkxlbmd0aCk7Ci0gICAgICAgICAgICBzdGFydFBvcyA9IGRFbmQ7Ci0gICAgICAgICAgICByZXR1cm4gcmV0OwotICAgICAgICB9Ci0gICAgICAgIGludGVybmFsIHN0YXRpYyBieXRlW10gRGVjb21wcmVzc1BhcnQoYnl0ZVtdIHBhcnQpCi0gICAgICAgIHsKLSAgICAgICAgICAgIHJldHVybiBEZWNvbXByZXNzUGFydChwYXJ0LCAwKTsKLSAgICAgICAgfQotICAgICAgICAvLy8gPHN1bW1hcnk+Ci0gICAgICAgIC8vLyBEZWNvbXByZXNzaW9uIHVzaW5nIGEgcnVuIGxlbmd0aCBlbmNvZGluZyBhbGdvcml0aG0uCi0gICAgICAgIC8vLyBTZWUgTVMtT1ZCQSBTZWN0aW9uIDIuNAotICAgICAgICAvLy8gPC9zdW1tYXJ5PgotICAgICAgICAvLy8gPHBhcmFtIG5hbWU9InBhcnQiPkJ5dGUgYXJyYXkgdG8gZGVjb21wcmVzczwvcGFyYW0+Ci0gICAgICAgIC8vLyA8cGFyYW0gbmFtZT0ic3RhcnRQb3MiPjwvcGFyYW0+Ci0gICAgICAgIC8vLyA8cmV0dXJucz48L3JldHVybnM+Ci0gICAgICAgIGludGVybmFsIHN0YXRpYyBieXRlW10gRGVjb21wcmVzc1BhcnQoYnl0ZVtdIHBhcnQsIGludCBzdGFydFBvcykKLSAgICAgICAgewotCi0gICAgICAgICAgICBpZiAocGFydFtzdGFydFBvc10gIT0gMSkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIE1lbW9yeVN0cmVhbSBtcyA9IG5ldyBNZW1vcnlTdHJlYW0oNDA5Nik7Ci0gICAgICAgICAgICBpbnQgY29tcHJlc3NQb3MgPSBzdGFydFBvcyArIDE7Ci0gICAgICAgICAgICB3aGlsZShjb21wcmVzc1BvcyA8IHBhcnQuTGVuZ3RoLTEpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgRGVjb21wcmVzc0NodW5rKG1zLCBwYXJ0LCByZWYgY29tcHJlc3NQb3MpOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgcmV0dXJuIG1zLlRvQXJyYXkoKTsKLSAgICAgICAgfQotICAgICAgICBwcml2YXRlIHN0YXRpYyB2b2lkIERlY29tcHJlc3NDaHVuayhNZW1vcnlTdHJlYW0gbXMsIGJ5dGVbXSBjb21wQnVmZmVyLCByZWYgaW50IHBvcykKLSAgICAgICAgewotICAgICAgICAgICAgdXNob3J0IGhlYWRlciA9IEJpdENvbnZlcnRlci5Ub1VJbnQxNihjb21wQnVmZmVyLCBwb3MpOwotICAgICAgICAgICAgaW50ICBkZWNvbXByUG9zPTA7Ci0gICAgICAgICAgICBieXRlW10gYnVmZmVyID0gbmV3IGJ5dGVbNDE5OF07IC8vQWRkIGFuIGV4dHJhIDEwMCBieXRlLiBTb21lIHdvcmtib29rcyBoYXZlIG92ZXJmbG93aW5nIHdvcmtzaGVldHMuCi0gICAgICAgICAgICBpbnQgc2l6ZSA9IChpbnQpKGhlYWRlciAmIDB4RkZGKSszOwotICAgICAgICAgICAgaW50IGVuZFBvcyA9IHBvcytzaXplOwotICAgICAgICAgICAgaW50IGEgPSAoaW50KShoZWFkZXIgJiAweDcwMDApID4+IDEyOwotICAgICAgICAgICAgaW50IGIgPSAoaW50KShoZWFkZXIgJiAweDgwMDApID4+IDE1OwotICAgICAgICAgICAgcG9zICs9IDI7Ci0gICAgICAgICAgICBpZiAoYiA9PSAxKSAvL0NvbXByZXNzZWQgY2h1bmsKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICB3aGlsZSAocG9zIDwgY29tcEJ1ZmZlci5MZW5ndGggJiYgcG9zIDwgZW5kUG9zKQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgLy9EZWNvbXByZXNzIHRva2VuCi0gICAgICAgICAgICAgICAgICAgIGJ5dGUgdG9rZW4gPSBjb21wQnVmZmVyW3BvcysrXTsKLSAgICAgICAgICAgICAgICAgICAgaWYgKHBvcyA+PSBlbmRQb3MpCi0gICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCA4OyBpKyspCi0gICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgIC8vTGl0ZXJhbCB0b2tlbgotICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCh0b2tlbiAmICgxIDw8IGkpKSA9PSAwKQotICAgICAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1zLldyaXRlQnl0ZShjb21wQnVmZmVyW3Bvc10pOyAgCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnVmZmVyW2RlY29tcHJQb3MrK10gPSBjb21wQnVmZmVyW3BvcysrXTsKLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgLy9jb3B5IHRva2VuCi0gICAgICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHQgPSBCaXRDb252ZXJ0ZXIuVG9VSW50MTYoY29tcEJ1ZmZlciwgcG9zKTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgYml0Q291bnQgPSBHZXRMZW5ndGhCaXRzKGRlY29tcHJQb3MpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBiaXRzID0gKDE2IC0gYml0Q291bnQpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVzaG9ydCBsZW5ndGhNYXNrID0gKHVzaG9ydCkoKDB4RkZGRikgPj4gYml0cyk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgVUludDE2IG9mZnNldE1hc2sgPSAodXNob3J0KX5sZW5ndGhNYXNrOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBsZW5ndGggPSAobGVuZ3RoTWFzayAmIHQpICsgMzsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgb2Zmc2V0ID0gKG9mZnNldE1hc2sgJiB0KSA+PiAoYml0Q291bnQpOwotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBzb3VyY2UgPSBkZWNvbXByUG9zIC0gb2Zmc2V0IC0gMTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZGVjb21wclBvcyArIGxlbmd0aCA+PSBidWZmZXIuTGVuZ3RoKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQmUgbGVuaWVudCBvbiBkZWNvbXByZXNzaW9uLCBzbyBleHRlbmQgb3VyIGRlY29tcHJlc3Npb24KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gYnVmZmVyLiBFeGNlbCBnZW5lcmF0ZWQgVkJBIHByb2plY3RzIGRvIGVuY291bnRlciB0aGlzIGlzc3VlLgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBPbmUgd291bGQgdGhpbmsgKG5vdCBzdXJwcmlzaW5nbHkgdGhhdCB0aGUgVkJBIHByb2plY3Qgc3BlYykKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gb3ZlciBlbXBoYXNpemVzIHRoZSBzaXplIHJlc3RyaWN0aW9ucyBvZiBhIERlY29tcHJlc3Npb25DaHVuay4KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGxhcmdlckJ1ZmZlciA9IG5ldyBieXRlW2J1ZmZlci5MZW5ndGggKyA0MDk4XTsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXJyYXkuQ29weShidWZmZXIsIGxhcmdlckJ1ZmZlciwgZGVjb21wclBvcyk7Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ1ZmZlciA9IGxhcmdlckJ1ZmZlcjsKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gRXZlbiB0aG91Z2ggd2UndmUgd3JpdHRlbiB0byB0aGUgTWVtb3J5U3RyZWFtLAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFdlIHN0aWxsIHNob3VsZCBkZWNvbXByZXNzIHRoZSB0b2tlbiBpbnRvIHRoaXMgYnVmZmVyCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gaW4gY2FzZSBhIGxhdGVyIHRva2VuIG5lZWRzIHRvIHVzZSB0aGUgYnl0ZXMgd2UncmUKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBhYm91dCB0byBkZWNvbXByZXNzLgotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoaW50IGMgPSAwOyBjIDwgbGVuZ3RoOyBjKyspCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtcy5Xcml0ZUJ5dGUoYnVmZmVyW3NvdXJjZV0pOyAvL011c3QgY29weSBieXRlLXdpc2UgYmVjYXVzZSBjb3B5dG9rZW5zIGNhbiBvdmVybGFwIGNvbXByZXNzZWQgYnVmZmVyLgotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBidWZmZXJbZGVjb21wclBvcysrXSA9IGJ1ZmZlcltzb3VyY2UrK107Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgfQotCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9zICs9IDI7Ci0KLSAgICAgICAgICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwb3MgPj0gZW5kUG9zKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgLy9SYXcgY2h1bmsKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBtcy5Xcml0ZShjb21wQnVmZmVyLCBwb3MsIHNpemUpOwotICAgICAgICAgICAgICAgIHBvcyArPSBzaXplOwotICAgICAgICAgICAgICAgIHJldHVybjsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfQotICAgICAgICBwcml2YXRlIHN0YXRpYyBpbnQgR2V0TGVuZ3RoQml0cyhpbnQgZGVjb21wUG9zKQotICAgICAgICB7Ci0gICAgICAgICAgICBpZiAoZGVjb21wUG9zIDw9IDE2KQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIHJldHVybiAxMjsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgaWYgKGRlY29tcFBvcyA8PSAzMikKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gMTE7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmIChkZWNvbXBQb3MgPD0gNjQpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIDEwOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSBpZiAoZGVjb21wUG9zIDw9IDEyOCkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gOTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgaWYgKGRlY29tcFBvcyA8PSAyNTYpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIDg7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmIChkZWNvbXBQb3MgPD0gNTEyKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIHJldHVybiA3OwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZSBpZiAoZGVjb21wUG9zIDw9IDEwMjQpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgcmV0dXJuIDY7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBlbHNlIGlmIChkZWNvbXBQb3MgPD0gMjA0OCkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICByZXR1cm4gNTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIGVsc2UgaWYgKGRlY29tcFBvcyA8PSA0MDk2KQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIHJldHVybiA0OwotICAgICAgICAgICAgfQotICAgICAgICAgICAgZWxzZQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIC8vV2Ugc2hvdWxkIG5ldmVyIGVuZCB1cCBoZXJlLCBidXQgaWYgc28gdGhpcyBpcyB0aGUgZm9ybXVsYSB0byBjYWxjdWxhdGUgdGhlIGJpdHMuLi4KLSAgICAgICAgICAgICAgICByZXR1cm4gMTIgLSAoaW50KU1hdGguVHJ1bmNhdGUoTWF0aC5Mb2coZGVjb21wUG9zIC0gMSA+PiA0LCAyKSArIDEpOwotICAgICAgICAgICAgfQotICAgICAgICB9Ci0gICAgICAgICNlbmRyZWdpb24KLSAgICAgICAgI3JlZ2lvbiAiQVBJIGRlY2xhcmUiCi0gICAgICAgIFtDb21JbXBvcnRdCi0gICAgICAgIFtHdWlkKCIwMDAwMDAwZC0wMDAwLTAwMDAtQzAwMC0wMDAwMDAwMDAwNDYiKV0KLSAgICAgICAgW0ludGVyZmFjZVR5cGUoQ29tSW50ZXJmYWNlVHlwZS5JbnRlcmZhY2VJc0lVbmtub3duKV0KLSAgICAgICAgaW50ZXJuYWwgaW50ZXJmYWNlIElFbnVtU1RBVFNURwotICAgICAgICB7Ci0gICAgICAgICAgICAvLyBUaGUgdXNlciBuZWVkcyB0byBhbGxvY2F0ZSBhbiBTVEFUU1RHIGFycmF5IHdob3NlIHNpemUgaXMgY2VsdC4gCi0gICAgICAgICAgICBbUHJlc2VydmVTaWddCi0gICAgICAgICAgICB1aW50IE5leHQoCi0gICAgICAgICAgICAgICAgdWludCBjZWx0LAotICAgICAgICAgICAgICAgIFtNYXJzaGFsQXMoVW5tYW5hZ2VkVHlwZS5MUEFycmF5KSwgT3V0XSAKLSAgICAgICAgICAgIFN5c3RlbS5SdW50aW1lLkludGVyb3BTZXJ2aWNlcy5Db21UeXBlcy5TVEFUU1RHW10gcmdlbHQsCi0gICAgICAgICAgICAgICAgb3V0IHVpbnQgcGNlbHRGZXRjaGVkCi0gICAgICAgICAgICApOwotCi0gICAgICAgICAgICB2b2lkIFNraXAodWludCBjZWx0KTsKLQotICAgICAgICAgICAgdm9pZCBSZXNldCgpOwotCi0gICAgICAgICAgICBbcmV0dXJuOiBNYXJzaGFsQXMoVW5tYW5hZ2VkVHlwZS5JbnRlcmZhY2UpXQotICAgICAgICAgICAgSUVudW1TVEFUU1RHIENsb25lKCk7Ci0gICAgICAgIH0KLQotICAgICAgICBbQ29tSW1wb3J0XQotICAgICAgICBbR3VpZCgiMDAwMDAwMGItMDAwMC0wMDAwLUMwMDAtMDAwMDAwMDAwMDQ2IildCi0gICAgICAgIFtJbnRlcmZhY2VUeXBlKENvbUludGVyZmFjZVR5cGUuSW50ZXJmYWNlSXNJVW5rbm93bildCi0gICAgICAgIGludGVyZmFjZSBJU3RvcmFnZQotICAgICAgICB7Ci0gICAgICAgICAgICB2b2lkIENyZWF0ZVN0cmVhbSgKLSAgICAgICAgICAgICAgICAvKiBbc3RyaW5nXVtpbl0gKi8gc3RyaW5nIHB3Y3NOYW1lLAotICAgICAgICAgICAgICAgIC8qIFtpbl0gKi8gdWludCBncmZNb2RlLAotICAgICAgICAgICAgICAgIC8qIFtpbl0gKi8gdWludCByZXNlcnZlZDEsCi0gICAgICAgICAgICAgICAgLyogW2luXSAqLyB1aW50IHJlc2VydmVkMiwKLSAgICAgICAgICAgICAgICAvKiBbb3V0XSAqLyBvdXQgY29tVHlwZXMuSVN0cmVhbSBwcHN0bSk7Ci0KLSAgICAgICAgICAgIHZvaWQgT3BlblN0cmVhbSgKLSAgICAgICAgICAgICAgICAvKiBbc3RyaW5nXVtpbl0gKi8gc3RyaW5nIHB3Y3NOYW1lLAotICAgICAgICAgICAgICAgIC8qIFt1bmlxdWVdW2luXSAqLyBJbnRQdHIgcmVzZXJ2ZWQxLAotICAgICAgICAgICAgICAgIC8qIFtpbl0gKi8gdWludCBncmZNb2RlLAotICAgICAgICAgICAgICAgIC8qIFtpbl0gKi8gdWludCByZXNlcnZlZDIsCi0gICAgICAgICAgICAgICAgLyogW291dF0gKi8gb3V0IGNvbVR5cGVzLklTdHJlYW0gcHBzdG0pOwotCi0gICAgICAgICAgICB2b2lkIENyZWF0ZVN0b3JhZ2UoCi0gICAgICAgICAgICAgICAgLyogW3N0cmluZ11baW5dICovIHN0cmluZyBwd2NzTmFtZSwKLSAgICAgICAgICAgICAgICAvKiBbaW5dICovIHVpbnQgZ3JmTW9kZSwKLSAgICAgICAgICAgICAgICAvKiBbaW5dICovIHVpbnQgcmVzZXJ2ZWQxLAotICAgICAgICAgICAgICAgIC8qIFtpbl0gKi8gdWludCByZXNlcnZlZDIsCi0gICAgICAgICAgICAgICAgLyogW291dF0gKi8gb3V0IElTdG9yYWdlIHBwc3RnKTsKLQotICAgICAgICAgICAgdm9pZCBPcGVuU3RvcmFnZSgKLSAgICAgICAgICAgICAgICAvKiBbc3RyaW5nXVt1bmlxdWVdW2luXSAqLyBzdHJpbmcgcHdjc05hbWUsCi0gICAgICAgICAgICAgICAgLyogW3VuaXF1ZV1baW5dICovIElTdG9yYWdlIHBzdGdQcmlvcml0eSwKLSAgICAgICAgICAgICAgICAvKiBbaW5dICovIFNUR00gZ3JmTW9kZSwKLSAgICAgICAgICAgICAgICAvKiBbdW5pcXVlXVtpbl0gKi8gSW50UHRyIHNuYkV4Y2x1ZGUsCi0gICAgICAgICAgICAgICAgLyogW2luXSAqLyB1aW50IHJlc2VydmVkLAotICAgICAgICAgICAgICAgIC8qIFtvdXRdICovIG91dCBJU3RvcmFnZSBwcHN0Zyk7Ci0KLSAgICAgICAgICAgIHZvaWQgQ29weVRvKAotICAgICAgICAgICAgICAgIFtJbkF0dHJpYnV0ZV0gdWludCBjaWlkRXhjbHVkZSwKLSAgICAgICAgICAgICAgICBbSW5BdHRyaWJ1dGVdIEd1aWRbXSByZ2lpZEV4Y2x1ZGUsCi0gICAgICAgICAgICAgICAgW0luQXR0cmlidXRlXSBJbnRQdHIgc25iRXhjbHVkZSwKLSAgICAgICAgICAgICAgICBbSW5BdHRyaWJ1dGVdIElTdG9yYWdlIHBzdGdEZXN0Ci0gICAgICAgICAgICApOwotCi0gICAgICAgICAgICB2b2lkIE1vdmVFbGVtZW50VG8oCi0gICAgICAgICAgICAgICAgLyogW3N0cmluZ11baW5dICovIHN0cmluZyBwd2NzTmFtZSwKLSAgICAgICAgICAgICAgICAvKiBbdW5pcXVlXVtpbl0gKi8gSVN0b3JhZ2UgcHN0Z0Rlc3QsCi0gICAgICAgICAgICAgICAgLyogW3N0cmluZ11baW5dICovIHN0cmluZyBwd2NzTmV3TmFtZSwKLSAgICAgICAgICAgICAgICAvKiBbaW5dICovIHVpbnQgZ3JmRmxhZ3MpOwotCi0gICAgICAgICAgICB2b2lkIENvbW1pdCgKLSAgICAgICAgICAgICAgICAvKiBbaW5dICovIHVpbnQgZ3JmQ29tbWl0RmxhZ3MpOwotCi0gICAgICAgICAgICB2b2lkIFJldmVydCgpOwotCi0gICAgICAgICAgICB2b2lkIEVudW1FbGVtZW50cygKLSAgICAgICAgICAgICAgICAvKiBbaW5dICovIHVpbnQgcmVzZXJ2ZWQxLAotICAgICAgICAgICAgICAgIC8qIFtzaXplX2lzXVt1bmlxdWVdW2luXSAqLyBJbnRQdHIgcmVzZXJ2ZWQyLAotICAgICAgICAgICAgICAgIC8qIFtpbl0gKi8gdWludCByZXNlcnZlZDMsCi0gICAgICAgICAgICAgICAgLyogW291dF0gKi8gb3V0IElFbnVtU1RBVFNURyBwcGVudW0pOwotCi0gICAgICAgICAgICB2b2lkIERlc3Ryb3lFbGVtZW50KAotICAgICAgICAgICAgICAgIC8qIFtzdHJpbmddW2luXSAqLyBzdHJpbmcgcHdjc05hbWUpOwotCi0gICAgICAgICAgICB2b2lkIFJlbmFtZUVsZW1lbnQoCi0gICAgICAgICAgICAgICAgLyogW3N0cmluZ11baW5dICovIHN0cmluZyBwd2NzT2xkTmFtZSwKLSAgICAgICAgICAgICAgICAvKiBbc3RyaW5nXVtpbl0gKi8gc3RyaW5nIHB3Y3NOZXdOYW1lKTsKLQotICAgICAgICAgICAgdm9pZCBTZXRFbGVtZW50VGltZXMoCi0gICAgICAgICAgICAgICAgLyogW3N0cmluZ11bdW5pcXVlXVtpbl0gKi8gc3RyaW5nIHB3Y3NOYW1lLAotICAgICAgICAgICAgICAgIC8qIFt1bmlxdWVdW2luXSAqLyBTeXN0ZW0uUnVudGltZS5JbnRlcm9wU2VydmljZXMuQ29tVHlwZXMuRklMRVRJTUUgcGN0aW1lLAotICAgICAgICAgICAgICAgIC8qIFt1bmlxdWVdW2luXSAqLyBTeXN0ZW0uUnVudGltZS5JbnRlcm9wU2VydmljZXMuQ29tVHlwZXMuRklMRVRJTUUgcGF0aW1lLAotICAgICAgICAgICAgICAgIC8qIFt1bmlxdWVdW2luXSAqLyBTeXN0ZW0uUnVudGltZS5JbnRlcm9wU2VydmljZXMuQ29tVHlwZXMuRklMRVRJTUUgcG10aW1lKTsKLQotICAgICAgICAgICAgdm9pZCBTZXRDbGFzcygKLSAgICAgICAgICAgICAgICAvKiBbaW5dICovIEd1aWQgY2xzaWQpOwotCi0gICAgICAgICAgICB2b2lkIFNldFN0YXRlQml0cygKLSAgICAgICAgICAgICAgICAvKiBbaW5dICovIHVpbnQgZ3JmU3RhdGVCaXRzLAotICAgICAgICAgICAgICAgIC8qIFtpbl0gKi8gdWludCBncmZNYXNrKTsKLQotICAgICAgICAgICAgdm9pZCBTdGF0KAotICAgICAgICAgICAgICAgIC8qIFtvdXRdICovIG91dCBTeXN0ZW0uUnVudGltZS5JbnRlcm9wU2VydmljZXMuQ29tVHlwZXMuU1RBVFNURyBwc3RhdHN0ZywKLSAgICAgICAgICAgICAgICAvKiBbaW5dICovIHVpbnQgZ3JmU3RhdEZsYWcpOwotCi0gICAgICAgIH0KLSAgICAgICAgW0NvbVZpc2libGUoZmFsc2UpXQotICAgICAgICBbQ29tSW1wb3J0LCBJbnRlcmZhY2VUeXBlKENvbUludGVyZmFjZVR5cGUuSW50ZXJmYWNlSXNJVW5rbm93biksIEd1aWQoIjAwMDAwMDBBLTAwMDAtMDAwMC1DMDAwLTAwMDAwMDAwMDA0NiIpXQotICAgICAgICBpbnRlcm5hbCBpbnRlcmZhY2UgSUxvY2tCeXRlcwotICAgICAgICB7Ci0gICAgICAgICAgICB2b2lkIFJlYWRBdChsb25nIHVsT2Zmc2V0LCBTeXN0ZW0uSW50UHRyIHB2LCBpbnQgY2IsIG91dCBVSW50UHRyIHBjYlJlYWQpOwotICAgICAgICAgICAgdm9pZCBXcml0ZUF0KGxvbmcgdWxPZmZzZXQsIFN5c3RlbS5JbnRQdHIgcHYsIGludCBjYiwgb3V0IFVJbnRQdHIgcGNiV3JpdHRlbik7Ci0gICAgICAgICAgICB2b2lkIEZsdXNoKCk7Ci0gICAgICAgICAgICB2b2lkIFNldFNpemUobG9uZyBjYik7Ci0gICAgICAgICAgICB2b2lkIExvY2tSZWdpb24obG9uZyBsaWJPZmZzZXQsIGxvbmcgY2IsIGludCBkd0xvY2tUeXBlKTsKLSAgICAgICAgICAgIHZvaWQgVW5sb2NrUmVnaW9uKGxvbmcgbGliT2Zmc2V0LCBsb25nIGNiLCBpbnQgZHdMb2NrVHlwZSk7Ci0gICAgICAgICAgICB2b2lkIFN0YXQob3V0IFN5c3RlbS5SdW50aW1lLkludGVyb3BTZXJ2aWNlcy5Db21UeXBlcy5TVEFUU1RHIHBzdGF0c3RnLCBpbnQgZ3JmU3RhdEZsYWcpOwotICAgICAgICB9Ci0gICAgICAgIFtGbGFnc10KLSAgICAgICAgaW50ZXJuYWwgZW51bSBTVEdNIDogaW50Ci0gICAgICAgIHsKLSAgICAgICAgICAgIERJUkVDVCA9IDB4MDAwMDAwMDAsCi0gICAgICAgICAgICBUUkFOU0FDVEVEID0gMHgwMDAxMDAwMCwKLSAgICAgICAgICAgIFNJTVBMRSA9IDB4MDgwMDAwMDAsCi0gICAgICAgICAgICBSRUFEID0gMHgwMDAwMDAwMCwKLSAgICAgICAgICAgIFdSSVRFID0gMHgwMDAwMDAwMSwKLSAgICAgICAgICAgIFJFQURXUklURSA9IDB4MDAwMDAwMDIsCi0gICAgICAgICAgICBTSEFSRV9ERU5ZX05PTkUgPSAweDAwMDAwMDQwLAotICAgICAgICAgICAgU0hBUkVfREVOWV9SRUFEID0gMHgwMDAwMDAzMCwKLSAgICAgICAgICAgIFNIQVJFX0RFTllfV1JJVEUgPSAweDAwMDAwMDIwLAotICAgICAgICAgICAgU0hBUkVfRVhDTFVTSVZFID0gMHgwMDAwMDAxMCwKLSAgICAgICAgICAgIFBSSU9SSVRZID0gMHgwMDA0MDAwMCwKLSAgICAgICAgICAgIERFTEVURU9OUkVMRUFTRSA9IDB4MDQwMDAwMDAsCi0gICAgICAgICAgICBOT1NDUkFUQ0ggPSAweDAwMTAwMDAwLAotICAgICAgICAgICAgQ1JFQVRFID0gMHgwMDAwMTAwMCwKLSAgICAgICAgICAgIENPTlZFUlQgPSAweDAwMDIwMDAwLAotICAgICAgICAgICAgRkFJTElGVEhFUkUgPSAweDAwMDAwMDAwLAotICAgICAgICAgICAgTk9TTkFQU0hPVCA9IDB4MDAyMDAwMDAsCi0gICAgICAgICAgICBESVJFQ1RfU1dNUiA9IDB4MDA0MDAwMDAsCi0gICAgICAgIH0KLQotICAgICAgICBpbnRlcm5hbCBlbnVtIFNUQVRGTEFHIDogdWludAotICAgICAgICB7Ci0gICAgICAgICAgICBTVEFURkxBR19ERUZBVUxUID0gMCwKLSAgICAgICAgICAgIFNUQVRGTEFHX05PTkFNRSA9IDEsCi0gICAgICAgICAgICBTVEFURkxBR19OT09QRU4gPSAyCi0gICAgICAgIH0KLQotICAgICAgICBpbnRlcm5hbCBlbnVtIFNUR1RZIDogaW50Ci0gICAgICAgIHsKLSAgICAgICAgICAgIFNUR1RZX1NUT1JBR0UgPSAxLAotICAgICAgICAgICAgU1RHVFlfU1RSRUFNID0gMiwKLSAgICAgICAgICAgIFNUR1RZX0xPQ0tCWVRFUyA9IDMsCi0gICAgICAgICAgICBTVEdUWV9QUk9QRVJUWSA9IDQKLSAgICAgICAgfQotCi0gICAgICAgIFtEbGxJbXBvcnQoIm9sZTMyLmRsbCIpXQotICAgICAgICBwcml2YXRlIHN0YXRpYyBleHRlcm4gaW50IFN0Z0lzU3RvcmFnZUZpbGUoCi0gICAgICAgICAgICBbTWFyc2hhbEFzKFVubWFuYWdlZFR5cGUuTFBXU3RyKV0gc3RyaW5nIHB3Y3NOYW1lKTsKLSAgICAgICAgW0RsbEltcG9ydCgib2xlMzIuZGxsIildCi0gICAgICAgIHByaXZhdGUgc3RhdGljIGV4dGVybiBpbnQgU3RnSXNTdG9yYWdlSUxvY2tCeXRlcygKLSAgICAgICAgICAgIElMb2NrQnl0ZXMgcGxrYnl0KTsKLQotCi0gICAgICAgIFtEbGxJbXBvcnQoIm9sZTMyLmRsbCIpXQotICAgICAgICBzdGF0aWMgZXh0ZXJuIGludCBTdGdPcGVuU3RvcmFnZSgKLSAgICAgICAgICAgIFtNYXJzaGFsQXMoVW5tYW5hZ2VkVHlwZS5MUFdTdHIpXSBzdHJpbmcgcHdjc05hbWUsCi0gICAgICAgICAgICBJU3RvcmFnZSBwc3RnUHJpb3JpdHksCi0gICAgICAgICAgICBTVEdNIGdyZk1vZGUsCi0gICAgICAgICAgICBJbnRQdHIgc25iRXhjbHVkZSwKLSAgICAgICAgICAgIHVpbnQgcmVzZXJ2ZWQsCi0gICAgICAgICAgICBvdXQgSVN0b3JhZ2UgcHBzdGdPcGVuKTsKLQotICAgICAgICBbRGxsSW1wb3J0KCJvbGUzMi5kbGwiKV0KLSAgICAgICAgc3RhdGljIGV4dGVybiBpbnQgU3RnT3BlblN0b3JhZ2VPbklMb2NrQnl0ZXMoCi0gICAgICAgICAgICBJTG9ja0J5dGVzIHBsa2J5dCwKLSAgICAgICAgICAgIElTdG9yYWdlIHBTdGdQcmlvcml0eSwKLSAgICAgICAgICAgIFNUR00gZ3JmTW9kZSwKLSAgICAgICAgICAgIEludFB0ciBzbmJFbmNsdWRlLAotICAgICAgICAgICAgdWludCByZXNlcnZlZCwKLSAgICAgICAgICAgIG91dCBJU3RvcmFnZSBwcHN0Z09wZW4pOwotICAgICAgICBbRGxsSW1wb3J0KCJvbGUzMi5kbGwiKV0KLSAgICAgICAgc3RhdGljIGV4dGVybiBpbnQgQ3JlYXRlSUxvY2tCeXRlc09uSEdsb2JhbCgKLSAgICAgICAgICAgIEludFB0ciBoR2xvYmFsLAotICAgICAgICAgICAgYm9vbCBmRGVsZXRlT25SZWxlYXNlLAotICAgICAgICAgICAgb3V0IElMb2NrQnl0ZXMgcHBMa2J5dCk7Ci0KLSAgICAgICAgW0RsbEltcG9ydCgib2xlMzIuZGxsIildCi0gICAgICAgIHN0YXRpYyBleHRlcm4gaW50IFN0Z0NyZWF0ZURvY2ZpbGVPbklMb2NrQnl0ZXMoSUxvY2tCeXRlcyBwbGtieXQsIFNUR00gZ3JmTW9kZSwgaW50IHJlc2VydmVkLCBvdXQgSVN0b3JhZ2UgcHBzdGdPcGVuKTsKLQotICAgICAgICAjZW5kcmVnaW9uCi0gICAgICAgIFtTZWN1cml0eVNhZmVDcml0aWNhbF0KLSAgICAgICAgaW50ZXJuYWwgc3RhdGljIGludCBJc1N0b3JhZ2VGaWxlKHN0cmluZyBOYW1lKQotICAgICAgICB7Ci0gICAgICAgICAgICByZXR1cm4gU3RnSXNTdG9yYWdlRmlsZShOYW1lKTsKLSAgICAgICAgfQotICAgICAgICBbU2VjdXJpdHlTYWZlQ3JpdGljYWxdCi0gICAgICAgIGludGVybmFsIHN0YXRpYyBpbnQgSXNTdG9yYWdlSUxvY2tCeXRlcyhJTG9ja0J5dGVzIGxiKQotICAgICAgICB7Ci0gICAgICAgICAgICByZXR1cm4gU3RnSXNTdG9yYWdlSUxvY2tCeXRlcyhsYik7Ci0gICAgICAgIH0KLSAgICAgICAgW1NlY3VyaXR5U2FmZUNyaXRpY2FsXQotICAgICAgICBpbnRlcm5hbCBzdGF0aWMgSUxvY2tCeXRlcyBHZXRMb2NrYnl0ZShNZW1vcnlTdHJlYW0gc3RyZWFtKQotICAgICAgICB7Ci0gICAgICAgICAgICBJTG9ja0J5dGVzIGxiOwotICAgICAgICAgICAgdmFyIGlyZXQgPSBDcmVhdGVJTG9ja0J5dGVzT25IR2xvYmFsKEludFB0ci5aZXJvLCB0cnVlLCBvdXQgbGIpOwotICAgICAgICAgICAgYnl0ZVtdIGRvY0FycmF5ID0gc3RyZWFtLkdldEJ1ZmZlcigpOwotCi0gICAgICAgICAgICBJbnRQdHIgYnVmZmVyID0gTWFyc2hhbC5BbGxvY0hHbG9iYWwoZG9jQXJyYXkuTGVuZ3RoKTsKLSAgICAgICAgICAgIE1hcnNoYWwuQ29weShkb2NBcnJheSwgMCwgYnVmZmVyLCBkb2NBcnJheS5MZW5ndGgpOwotICAgICAgICAgICAgVUludFB0ciByZWFkU2l6ZTsKLSAgICAgICAgICAgIGxiLldyaXRlQXQoMCwgYnVmZmVyLCBkb2NBcnJheS5MZW5ndGgsIG91dCByZWFkU2l6ZSk7Ci0gICAgICAgICAgICBNYXJzaGFsLkZyZWVIR2xvYmFsKGJ1ZmZlcik7Ci0KLSAgICAgICAgICAgIHJldHVybiBsYjsKLSAgICAgICAgfQotICAgICAgICBbU2VjdXJpdHlTYWZlQ3JpdGljYWxdCi0gICAgICAgIHByaXZhdGUgTWVtb3J5U3RyZWFtIFJlYWRQYXJ0cyhJU3RvcmFnZSBzdG9yYWdlLCBTdG9yYWdlUGFydCBzdG9yYWdlUGFydCkKLSAgICAgICAgewotICAgICAgICAgICAgTWVtb3J5U3RyZWFtIHJldCA9IG51bGw7Ci0gICAgICAgICAgICBjb21UeXBlcy5TVEFUU1RHIHN0YXRzdGc7Ci0KLSAgICAgICAgICAgIHN0b3JhZ2UuU3RhdChvdXQgc3RhdHN0ZywgKHVpbnQpU1RBVEZMQUcuU1RBVEZMQUdfREVGQVVMVCk7Ci0KLSAgICAgICAgICAgIElFbnVtU1RBVFNURyBwSUVudW1TdGF0U3RnID0gbnVsbDsKLSAgICAgICAgICAgIHN0b3JhZ2UuRW51bUVsZW1lbnRzKDAsIEludFB0ci5aZXJvLCAwLCBvdXQgcElFbnVtU3RhdFN0Zyk7Ci0KLSAgICAgICAgICAgIGNvbVR5cGVzLlNUQVRTVEdbXSByZWdlbHQgPSB7IHN0YXRzdGcgfTsKLSAgICAgICAgICAgIHVpbnQgZmV0Y2hlZCA9IDA7Ci0gICAgICAgICAgICB1aW50IHJlcyA9IHBJRW51bVN0YXRTdGcuTmV4dCgxLCByZWdlbHQsIG91dCBmZXRjaGVkKTsKLQotICAgICAgICAgICAgLy9pZiAocmVnZWx0WzBdLnB3Y3NOYW1lID09ICIGRGF0YVNwYWNlcyIpCi0gICAgICAgICAgICAvL3sKLSAgICAgICAgICAgIC8vICAgIFByaW50U3RvcmFnZShzdG9yYWdlLCByZWdlbHRbMF0sIiIpOwotICAgICAgICAgICAgLy99Ci0gICAgICAgICAgICB3aGlsZSAocmVzICE9IDEpCi0gICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgZm9yZWFjaCAodmFyIGl0ZW0gaW4gcmVnZWx0KQotICAgICAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICAgICAgaWYgKGl0ZW0udHlwZSA9PSAxKQotICAgICAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgICAgICBJU3RvcmFnZSBzdWJTdG9yYWdlOwotICAgICAgICAgICAgICAgICAgICAgICAgc3RvcmFnZS5PcGVuU3RvcmFnZShpdGVtLnB3Y3NOYW1lLCBudWxsLCBTVEdNLkRJUkVDVCB8IFNUR00uUkVBRCB8IFNUR00uU0hBUkVfRVhDTFVTSVZFLCBJbnRQdHIuWmVybywgMCwgb3V0IHN1YlN0b3JhZ2UpOwotICAgICAgICAgICAgICAgICAgICAgICAgU3RvcmFnZVBhcnQgc3ViU3RvcmFnZVBhcnQ9bmV3IFN0b3JhZ2VQYXJ0KCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBzdG9yYWdlUGFydC5TdWJTdG9yYWdlLkFkZChpdGVtLnB3Y3NOYW1lLCBzdWJTdG9yYWdlUGFydCk7Ci0gICAgICAgICAgICAgICAgICAgICAgICBSZWFkUGFydHMoc3ViU3RvcmFnZSwgc3ViU3RvcmFnZVBhcnQpOwotICAgICAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgICAgIGVsc2UKLSAgICAgICAgICAgICAgICAgICAgewotICAgICAgICAgICAgICAgICAgICAgICAgc3RvcmFnZVBhcnQuRGF0YVN0cmVhbXMuQWRkKGl0ZW0ucHdjc05hbWUsIEdldE9sZVN0cmVhbShzdG9yYWdlLCBpdGVtKSk7ICAgICAgICAgICAgICAgICAgICAKLSAgICAgICAgICAgICAgICAgICAgfQotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICByZXMgPSBwSUVudW1TdGF0U3RnLk5leHQoMSwgcmVnZWx0LCBvdXQgZmV0Y2hlZCk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgICAgICBNYXJzaGFsLlJlbGVhc2VDb21PYmplY3QocElFbnVtU3RhdFN0Zyk7Ci0gICAgICAgICAgICByZXR1cm4gcmV0OwotICAgICAgICB9Ci0gICAgICAgIC8vIEhlbHAgbWV0aG9kIHRvIHByaW50IGEgc3RvcmFnZSBwYXJ0IGJpbmFyeSB0byBjOlx0ZW1wCi0gICAgICAgIC8vcHJpdmF0ZSB2b2lkIFByaW50U3RvcmFnZShJU3RvcmFnZSBzdG9yYWdlLCBTeXN0ZW0uUnVudGltZS5JbnRlcm9wU2VydmljZXMuQ29tVHlwZXMuU1RBVFNURyBzVEFUU1RHLCBzdHJpbmcgdG9wTmFtZSkKLSAgICAgICAgLy97Ci0gICAgICAgIC8vICAgIElTdG9yYWdlIGRzOwotICAgICAgICAvLyAgICBpZiAodG9wTmFtZS5MZW5ndGggPiAwKQotICAgICAgICAvLyAgICB7Ci0gICAgICAgIC8vICAgICAgICB0b3BOYW1lID0gdG9wTmFtZVswXSA8ICdBJyA/IHRvcE5hbWUuU3Vic3RyaW5nKDEsIHRvcE5hbWUuTGVuZ3RoIC0gMSkgOiB0b3BOYW1lOwotICAgICAgICAvLyAgICB9Ci0gICAgICAgIC8vICAgIHN0b3JhZ2UuT3BlblN0b3JhZ2Uoc1RBVFNURy5wd2NzTmFtZSwKLSAgICAgICAgLy8gICAgICAgIG51bGwsCi0gICAgICAgIC8vICAgICAgICAodWludCkoU1RHTS5ESVJFQ1QgfCBTVEdNLlJFQUQgfCBTVEdNLlNIQVJFX0VYQ0xVU0lWRSksCi0gICAgICAgIC8vICAgICAgICBJbnRQdHIuWmVybywKLSAgICAgICAgLy8gICAgICAgIDAsCi0gICAgICAgIC8vICAgICAgICBvdXQgZHMpOwotCi0gICAgICAgIC8vICAgIFN5c3RlbS5SdW50aW1lLkludGVyb3BTZXJ2aWNlcy5Db21UeXBlcy5TVEFUU1RHIHN0YXRzdGdTdWI7Ci0gICAgICAgIC8vICAgIGRzLlN0YXQob3V0IHN0YXRzdGdTdWIsICh1aW50KVNUQVRGTEFHLlNUQVRGTEFHX0RFRkFVTFQpOwotCi0gICAgICAgIC8vICAgIElFbnVtU1RBVFNURyBwSUVudW1TdGF0U3RnU3ViID0gbnVsbDsKLSAgICAgICAgLy8gICAgU3lzdGVtLlJ1bnRpbWUuSW50ZXJvcFNlcnZpY2VzLkNvbVR5cGVzLlNUQVRTVEdbXSByZWdlbHRTdWIgPSB7IHN0YXRzdGdTdWIgfTsKLSAgICAgICAgLy8gICAgZHMuRW51bUVsZW1lbnRzKDAsIEludFB0ci5aZXJvLCAwLCBvdXQgcElFbnVtU3RhdFN0Z1N1Yik7Ci0KLSAgICAgICAgLy8gICAgdWludCBmZXRjaGVkID0gMDsKLSAgICAgICAgLy8gICAgd2hpbGUgKHBJRW51bVN0YXRTdGdTdWIuTmV4dCgxLCByZWdlbHRTdWIsIG91dCBmZXRjaGVkKSA9PSAwKQotICAgICAgICAvLyAgICB7Ci0gICAgICAgIC8vICAgICAgICBzdHJpbmcgc05hbWUgPSByZWdlbHRTdWJbMF0ucHdjc05hbWVbMF0gPCAnQScgPyByZWdlbHRTdWJbMF0ucHdjc05hbWUuU3Vic3RyaW5nKDEsIHJlZ2VsdFN1YlswXS5wd2NzTmFtZS5MZW5ndGggLSAxKSA6IHJlZ2VsdFN1YlswXS5wd2NzTmFtZTsKLSAgICAgICAgLy8gICAgICAgIGlmIChyZWdlbHRTdWJbMF0udHlwZSA9PSAxKQotICAgICAgICAvLyAgICAgICAgewotICAgICAgICAvLyAgICAgICAgICAgIFByaW50U3RvcmFnZShkcywgcmVnZWx0U3ViWzBdLCB0b3BOYW1lICsgc05hbWUgKyAiXyIpOwotICAgICAgICAvLyAgICAgICAgfQotICAgICAgICAvLyAgICAgICAgZWxzZSBpZihyZWdlbHRTdWJbMF0udHlwZT09MikKLSAgICAgICAgLy8gICAgICAgIHsKLSAgICAgICAgLy8gICAgICAgICAgICBGaWxlLldyaXRlQWxsQnl0ZXMoQCJjOlx0ZW1wXCIgKyB0b3BOYW1lICsgc05hbWUgKyAiLmJpbiIsIEdldE9sZVN0cmVhbShkcywgcmVnZWx0U3ViWzBdKSk7Ci0gICAgICAgIC8vICAgICAgICB9Ci0gICAgICAgIC8vICAgIH0KLSAgICAgICAgLy99ICAgIH0KLSAgICAgICAgLy8vIDxzdW1tYXJ5PgotICAgICAgICAvLy8gUmVhZCB0aGUgc3RyZWFtIGFuZCByZXR1cm4gaXQgYXMgYSBieXRlLWFycmF5Ci0gICAgICAgIC8vLyA8L3N1bW1hcnk+Ci0gICAgICAgIC8vLyA8cGFyYW0gbmFtZT0ic3RvcmFnZSI+PC9wYXJhbT4KLSAgICAgICAgLy8vIDxwYXJhbSBuYW1lPSJzdGF0c3RnIj48L3BhcmFtPgotICAgICAgICAvLy8gPHJldHVybnM+PC9yZXR1cm5zPgotICAgICAgICBbU2VjdXJpdHlTYWZlQ3JpdGljYWxdCi0gICAgICAgIHByaXZhdGUgYnl0ZVtdIEdldE9sZVN0cmVhbShJU3RvcmFnZSBzdG9yYWdlLCBjb21UeXBlcy5TVEFUU1RHIHN0YXRzdGcpCi0gICAgICAgIHsKLSAgICAgICAgICAgIGNvbVR5cGVzLklTdHJlYW0gcElTdHJlYW07Ci0gICAgICAgICAgICBzdG9yYWdlLk9wZW5TdHJlYW0oc3RhdHN0Zy5wd2NzTmFtZSwKLSAgICAgICAgICAgICAgIEludFB0ci5aZXJvLAotICAgICAgICAgICAgICAgKHVpbnQpKFNUR00uUkVBRCB8IFNUR00uU0hBUkVfRVhDTFVTSVZFKSwKLSAgICAgICAgICAgICAgIDAsCi0gICAgICAgICAgICAgICBvdXQgcElTdHJlYW0pOwotCi0gICAgICAgICAgICBieXRlW10gZGF0YSA9IG5ldyBieXRlW3N0YXRzdGcuY2JTaXplXTsKLSAgICAgICAgICAgIHBJU3RyZWFtLlJlYWQoZGF0YSwgKGludClzdGF0c3RnLmNiU2l6ZSwgSW50UHRyLlplcm8pOwotICAgICAgICAgICAgTWFyc2hhbC5SZWxlYXNlQ29tT2JqZWN0KHBJU3RyZWFtKTsKLQotICAgICAgICAgICAgcmV0dXJuIGRhdGE7Ci0gICAgICAgIH0KLQotICAgICAgICBbU2VjdXJpdHlTYWZlQ3JpdGljYWxdCi0gICAgICAgIGludGVybmFsIGJ5dGVbXSBTYXZlKCkKLSAgICAgICAgewotICAgICAgICAgICAgSUxvY2tCeXRlcyBsYjsKLSAgICAgICAgICAgIHZhciBpcmV0ID0gQ3JlYXRlSUxvY2tCeXRlc09uSEdsb2JhbChJbnRQdHIuWmVybywgdHJ1ZSwgb3V0IGxiKTsKLQotICAgICAgICAgICAgSVN0b3JhZ2Ugc3RvcmFnZSA9IG51bGw7Ci0gICAgICAgICAgICBieXRlW10gcmV0ID0gbnVsbDsKLQotICAgICAgICAgICAgLy9DcmVhdGUgdGhlIGRvY3VtZW50IGluLW1lbW9yeQotICAgICAgICAgICAgaWYgKFN0Z0NyZWF0ZURvY2ZpbGVPbklMb2NrQnl0ZXMobGIsCi0gICAgICAgICAgICAgICAgICAgIFNUR00uQ1JFQVRFIHwgU1RHTS5SRUFEV1JJVEUgfCBTVEdNLlNIQVJFX0VYQ0xVU0lWRSB8IFNUR00uVFJBTlNBQ1RFRCwgCi0gICAgICAgICAgICAgICAgICAgIDAsCi0gICAgICAgICAgICAgICAgICAgIG91dCBzdG9yYWdlKT09MCkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBmb3JlYWNoKHZhciBzdG9yZSBpbiB0aGlzLlN0b3JhZ2UuU3ViU3RvcmFnZSkKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAgICAgICAgIENyZWF0ZVN0b3JlKHN0b3JlLktleSwgc3RvcmUuVmFsdWUsIHN0b3JhZ2UpOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICBDcmVhdGVTdHJlYW1zKHRoaXMuU3RvcmFnZSwgc3RvcmFnZSk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKLSAgICAgICAgICAgICAgICBsYi5GbHVzaCgpOwotICAgICAgICAgICAgICAgIAotICAgICAgICAgICAgICAgIC8vTm93IGNvcHkgdGhlIHVubWFuYWdlZCBzdHJlYW0gdG8gYSBieXRlIGFycmF5IC0tPiBtZW1vcnkgc3RyZWFtCi0gICAgICAgICAgICAgICAgdmFyIHN0YXRzdGcgPSBuZXcgY29tVHlwZXMuU1RBVFNURygpOwotICAgICAgICAgICAgICAgIGxiLlN0YXQob3V0IHN0YXRzdGcsIDApOwotICAgICAgICAgICAgICAgIGludCBzaXplID0gKGludClzdGF0c3RnLmNiU2l6ZTsKLSAgICAgICAgICAgICAgICBJbnRQdHIgYnVmZmVyID0gTWFyc2hhbC5BbGxvY0hHbG9iYWwoc2l6ZSk7Ci0gICAgICAgICAgICAgICAgVUludFB0ciByZWFkU2l6ZTsKLSAgICAgICAgICAgICAgICByZXQ9bmV3IGJ5dGVbc2l6ZV07Ci0gICAgICAgICAgICAgICAgbGIuUmVhZEF0KDAsIGJ1ZmZlciwgc2l6ZSwgb3V0IHJlYWRTaXplKTsKLSAgICAgICAgICAgICAgICBNYXJzaGFsLkNvcHkoYnVmZmVyLCByZXQsIDAsIHNpemUpOwotICAgICAgICAgICAgICAgIE1hcnNoYWwuRnJlZUhHbG9iYWwoYnVmZmVyKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIE1hcnNoYWwuUmVsZWFzZUNvbU9iamVjdChzdG9yYWdlKTsKLSAgICAgICAgICAgIE1hcnNoYWwuUmVsZWFzZUNvbU9iamVjdChsYik7Ci0KLSAgICAgICAgICAgIHJldHVybiByZXQ7Ci0gICAgICAgIH0KLQotICAgICAgICBwcml2YXRlIHZvaWQgQ3JlYXRlU3RvcmUoc3RyaW5nIG5hbWUsIFN0b3JhZ2VQYXJ0IHN1YlN0b3JlLCBJU3RvcmFnZSBzdG9yYWdlKQotICAgICAgICB7Ci0gICAgICAgICAgICBJU3RvcmFnZSBzdWJTdG9yYWdlOwotICAgICAgICAgICAgc3RvcmFnZS5DcmVhdGVTdG9yYWdlKG5hbWUsICh1aW50KShTVEdNLkNSRUFURSB8IFNUR00uV1JJVEUgfCBTVEdNLkRJUkVDVCB8IFNUR00uU0hBUkVfRVhDTFVTSVZFKSwgMCwgMCwgb3V0IHN1YlN0b3JhZ2UpOwotICAgICAgICAgICAgc3RvcmFnZS5Db21taXQoMCk7Ci0gICAgICAgICAgICBmb3JlYWNoICh2YXIgc3RvcmUgaW4gc3ViU3RvcmUuU3ViU3RvcmFnZSkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBDcmVhdGVTdG9yZShzdG9yZS5LZXksIHN0b3JlLlZhbHVlLCBzdWJTdG9yYWdlKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgICAgIAotICAgICAgICAgICAgQ3JlYXRlU3RyZWFtcyhzdWJTdG9yZSwgc3ViU3RvcmFnZSk7Ci0gICAgICAgIH0KLQotICAgICAgICBwcml2YXRlIHZvaWQgQ3JlYXRlU3RyZWFtcyhTdG9yYWdlUGFydCBzdWJTdG9yZSwgSVN0b3JhZ2Ugc3ViU3RvcmFnZSkKLSAgICAgICAgewotICAgICAgICAgICAgZm9yZWFjaCAodmFyIGRzIGluIHN1YlN0b3JlLkRhdGFTdHJlYW1zKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIGNvbVR5cGVzLklTdHJlYW0gc3RyZWFtOwotICAgICAgICAgICAgICAgIHN1YlN0b3JhZ2UuQ3JlYXRlU3RyZWFtKGRzLktleSwgKHVpbnQpKFNUR00uQ1JFQVRFIHwgU1RHTS5XUklURSB8IFNUR00uRElSRUNUIHwgU1RHTS5TSEFSRV9FWENMVVNJVkUpLCAwLCAwLCBvdXQgc3RyZWFtKTsKLSAgICAgICAgICAgICAgICBzdHJlYW0uV3JpdGUoZHMuVmFsdWUsIGRzLlZhbHVlLkxlbmd0aCwgSW50UHRyLlplcm8pOwotICAgICAgICAgICAgfQotICAgICAgICAgICAgc3ViU3RvcmFnZS5Db21taXQoMCk7Ci0gICAgICAgIH0KLQkJCQotICAgIH0KLSNlbmRpZgotfQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL0VQUGx1cy9VdGlscy9FbmNyeXB0ZWRQYWNrYWdlSGFuZGxlci5jcyBiL0VQUGx1cy9VdGlscy9FbmNyeXB0ZWRQYWNrYWdlSGFuZGxlci5jcwpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDBiNGMwZS4uMDAwMDAwMAotLS0gYS9FUFBsdXMvVXRpbHMvRW5jcnlwdGVkUGFja2FnZUhhbmRsZXIuY3MKKysrIC9kZXYvbnVsbApAQCAtMSwyMDAgKzAsMCBAQAot77u/LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKLSAqIFlvdSBtYXkgYW1lbmQgYW5kIGRpc3RyaWJ1dGUgYXMgeW91IGxpa2UsIGJ1dCBkb24ndCByZW1vdmUgdGhpcyBoZWFkZXIhCi0gKgotICogRVBQbHVzIHByb3ZpZGVzIHNlcnZlci1zaWRlIGdlbmVyYXRpb24gb2YgRXhjZWwgMjAwNy8yMDEwIHNwcmVhZHNoZWV0cy4KLSAqIFNlZSBodHRwOi8vd3d3LmNvZGVwbGV4LmNvbS9FUFBsdXMgZm9yIGRldGFpbHMuCi0gKgotICogQ29weXJpZ2h0IChDKSAyMDExICBKYW4gS8OkbGxtYW4KLSAqCi0gKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCi0gKiBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCi0gKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKLSAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgotCi0gKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKLSAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCi0gKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICAKLSAqIFNlZSB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCi0gKgotICogVGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBjYW4gYmUgdmlld2VkIGF0IGh0dHA6Ly93d3cub3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvbGdwbC1saWNlbnNlLnBocAotICogSWYgeW91IHVuZmFtaWxpYXIgd2l0aCB0aGlzIGxpY2Vuc2Ugb3IgaGF2ZSBxdWVzdGlvbnMgYWJvdXQgaXQsIGhlcmUgaXMgYW4gaHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2dwbC1mYXEuaHRtbAotICoKLSAqIEFsbCBjb2RlIGFuZCBleGVjdXRhYmxlcyBhcmUgcHJvdmlkZWQgImFzIGlzIiB3aXRoIG5vIHdhcnJhbnR5IGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuIAotICogVGhlIGF1dGhvciBhY2NlcHRzIG5vIGxpYWJpbGl0eSBmb3IgYW55IGRhbWFnZSBvciBsb3NzIG9mIGJ1c2luZXNzIHRoYXQgdGhpcyBwcm9kdWN0IG1heSBjYXVzZS4KLSAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgotICogVGhpcyBjbGFzcyBpcyBjcmVhdGVkIHdpdGggdGhlIGhlbHAgb2YgdGhlIE1TLU9GRkNSWVBUTyBQREYgZG9jdW1lbnRhdGlvbi4uLiBodHRwOi8vbXNkbi5taWNyb3NvZnQuY29tL2VuLXVzL2xpYnJhcnkvY2MzMTMwNzEob2ZmaWNlLjEyKS5hc3B4Ci0gKiBEZWNyeXB0aW9uIGxpYnJhcnkgZm9yIE9mZmljZSBPcGVuIFhNTCBmaWxlcyhMeXF1aWRpdHkpIGFuZCBTbWlua3MgdmVyeSBuaWNlIGV4YW1wbGUgCi0gKiBvbiAiUmVhZGluZyBjb21wb3VuZCBkb2N1bWVudHMgaW4gYyMiIG9uIFN0YWNrb3ZlcmZsb3cuIE1hbnkgdGhhbmtzIQotICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgotICogQ29kZSBjaGFuZ2Ugbm90ZXM6Ci0gKiAKLSAqIEF1dGhvcgkJCQkJCQlDaGFuZ2UJCQkJCQlEYXRlCi0gKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgotICogSmFuIEvDpGxsbWFuCQlBZGRlZAkJMTAtQVVHLTIwMTAKLSAqIEphbiBLw6RsbG1hbgkJTGljZW5zZSBjaGFuZ2VkIEdQTC0tPkxHUEwgMjAxMS0xMi0xNgotICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi11c2luZyBTeXN0ZW07Ci11c2luZyBTeXN0ZW0uQ29sbGVjdGlvbnMuR2VuZXJpYzsKLXVzaW5nIFN5c3RlbS5UZXh0OwotdXNpbmcgU3lzdGVtLlJ1bnRpbWUuSW50ZXJvcFNlcnZpY2VzOyAKLXVzaW5nIGNvbVR5cGVzPVN5c3RlbS5SdW50aW1lLkludGVyb3BTZXJ2aWNlcy5Db21UeXBlczsKLXVzaW5nIFN5c3RlbS5JTzsKLXVzaW5nIFN5c3RlbS5TZWN1cml0eS5DcnlwdG9ncmFwaHk7Ci11c2luZyBTeXN0ZW0uWG1sOwotbmFtZXNwYWNlIE9mZmljZU9wZW5YbWwuVXRpbHMKLXsKLSAgICBbQ29tSW1wb3J0XSAKLSAgICBbR3VpZCgiMDAwMDAwMGQtMDAwMC0wMDAwLUMwMDAtMDAwMDAwMDAwMDQ2IildIAotICAgIFtJbnRlcmZhY2VUeXBlKENvbUludGVyZmFjZVR5cGUuSW50ZXJmYWNlSXNJVW5rbm93bildIAotICAgIGludGVybmFsIGludGVyZmFjZSBJRW51bVNUQVRTVEcgCi0gICAgeyAKLSAgICAgICAgLy8gVGhlIHVzZXIgbmVlZHMgdG8gYWxsb2NhdGUgYW4gU1RBVFNURyBhcnJheSB3aG9zZSBzaXplIGlzIGNlbHQuIAotICAgICAgICBbUHJlc2VydmVTaWddIAotICAgICAgICB1aW50IE5leHQoIAotICAgICAgICAgICAgdWludCBjZWx0LCAKLSAgICAgICAgICAgIFtNYXJzaGFsQXMoVW5tYW5hZ2VkVHlwZS5MUEFycmF5KSwgT3V0XSAKLSAgICAgICAgICAgIFN5c3RlbS5SdW50aW1lLkludGVyb3BTZXJ2aWNlcy5Db21UeXBlcy5TVEFUU1RHW10gcmdlbHQsIAotICAgICAgICAgICAgb3V0IHVpbnQgcGNlbHRGZXRjaGVkIAotICAgICAgICApOyAKLSAKLSAgICAgICAgdm9pZCBTa2lwKHVpbnQgY2VsdCk7IAotIAotICAgICAgICB2b2lkIFJlc2V0KCk7IAotIAotICAgICAgICBbcmV0dXJuOiBNYXJzaGFsQXMoVW5tYW5hZ2VkVHlwZS5JbnRlcmZhY2UpXSAKLSAgICAgICAgSUVudW1TVEFUU1RHIENsb25lKCk7IAotICAgIH0gCi0gCi0gICAgW0NvbUltcG9ydF0gCi0gICAgW0d1aWQoIjAwMDAwMDBiLTAwMDAtMDAwMC1DMDAwLTAwMDAwMDAwMDA0NiIpXSAKLSAgICBbSW50ZXJmYWNlVHlwZShDb21JbnRlcmZhY2VUeXBlLkludGVyZmFjZUlzSVVua25vd24pXSAKLSAgICBpbnRlcmZhY2UgSVN0b3JhZ2UgCi0gICAgeyAKLSAgICAgICAgdm9pZCBDcmVhdGVTdHJlYW0oIAotICAgICAgICAgICAgLyogW3N0cmluZ11baW5dICovIHN0cmluZyBwd2NzTmFtZSwgCi0gICAgICAgICAgICAvKiBbaW5dICovIHVpbnQgZ3JmTW9kZSwgCi0gICAgICAgICAgICAvKiBbaW5dICovIHVpbnQgcmVzZXJ2ZWQxLCAKLSAgICAgICAgICAgIC8qIFtpbl0gKi8gdWludCByZXNlcnZlZDIsIAotICAgICAgICAgICAgLyogW291dF0gKi8gb3V0IGNvbVR5cGVzLklTdHJlYW0gcHBzdG0pOyAKLSAgICAgICAgCi0gICAgICAgIHZvaWQgT3BlblN0cmVhbSggCi0gICAgICAgICAgICAvKiBbc3RyaW5nXVtpbl0gKi8gc3RyaW5nIHB3Y3NOYW1lLCAKLSAgICAgICAgICAgIC8qIFt1bmlxdWVdW2luXSAqLyBJbnRQdHIgcmVzZXJ2ZWQxLCAKLSAgICAgICAgICAgIC8qIFtpbl0gKi8gdWludCBncmZNb2RlLCAKLSAgICAgICAgICAgIC8qIFtpbl0gKi8gdWludCByZXNlcnZlZDIsCi0gICAgICAgICAgICAvKiBbb3V0XSAqLyBvdXQgY29tVHlwZXMuSVN0cmVhbSBwcHN0bSk7IAotIAotICAgICAgICB2b2lkIENyZWF0ZVN0b3JhZ2UoIAotICAgICAgICAgICAgLyogW3N0cmluZ11baW5dICovIHN0cmluZyBwd2NzTmFtZSwgCi0gICAgICAgICAgICAvKiBbaW5dICovIHVpbnQgZ3JmTW9kZSwgCi0gICAgICAgICAgICAvKiBbaW5dICovIHVpbnQgcmVzZXJ2ZWQxLCAKLSAgICAgICAgICAgIC8qIFtpbl0gKi8gdWludCByZXNlcnZlZDIsIAotICAgICAgICAgICAgLyogW291dF0gKi8gb3V0IElTdG9yYWdlIHBwc3RnKTsgCi0gCi0gICAgICAgIHZvaWQgT3BlblN0b3JhZ2UoIAotICAgICAgICAgICAgLyogW3N0cmluZ11bdW5pcXVlXVtpbl0gKi8gc3RyaW5nIHB3Y3NOYW1lLCAKLSAgICAgICAgICAgIC8qIFt1bmlxdWVdW2luXSAqLyBJU3RvcmFnZSBwc3RnUHJpb3JpdHksIAotICAgICAgICAgICAgLyogW2luXSAqLyB1aW50IGdyZk1vZGUsIAotICAgICAgICAgICAgLyogW3VuaXF1ZV1baW5dICovIEludFB0ciBzbmJFeGNsdWRlLCAKLSAgICAgICAgICAgIC8qIFtpbl0gKi8gdWludCByZXNlcnZlZCwgCi0gICAgICAgICAgICAvKiBbb3V0XSAqLyBvdXQgSVN0b3JhZ2UgcHBzdGcpOwotCi0gICAgICAgIHZvaWQgQ29weVRvKAotICAgICAgICAgICAgW0luQXR0cmlidXRlXSB1aW50IGNpaWRFeGNsdWRlLAotICAgICAgICAgICAgW0luQXR0cmlidXRlXSBHdWlkW10gcmdpaWRFeGNsdWRlLAotICAgICAgICAgICAgW0luQXR0cmlidXRlXSBJbnRQdHIgc25iRXhjbHVkZSwKLSAgICAgICAgICAgIFtJbkF0dHJpYnV0ZV0gSVN0b3JhZ2UgcHN0Z0Rlc3QKLSAgICAgICAgKTsKLSAKLSAgICAgICAgdm9pZCBNb3ZlRWxlbWVudFRvKCAKLSAgICAgICAgICAgIC8qIFtzdHJpbmddW2luXSAqLyBzdHJpbmcgcHdjc05hbWUsIAotICAgICAgICAgICAgLyogW3VuaXF1ZV1baW5dICovIElTdG9yYWdlIHBzdGdEZXN0LCAKLSAgICAgICAgICAgIC8qIFtzdHJpbmddW2luXSAqLyBzdHJpbmcgcHdjc05ld05hbWUsIAotICAgICAgICAgICAgLyogW2luXSAqLyB1aW50IGdyZkZsYWdzKTsgCi0gCi0gICAgICAgIHZvaWQgQ29tbWl0KCAKLSAgICAgICAgICAgIC8qIFtpbl0gKi8gdWludCBncmZDb21taXRGbGFncyk7IAotIAotICAgICAgICB2b2lkIFJldmVydCgpOyAKLSAKLSAgICAgICAgdm9pZCBFbnVtRWxlbWVudHMoIAotICAgICAgICAgICAgLyogW2luXSAqLyB1aW50IHJlc2VydmVkMSwgCi0gICAgICAgICAgICAvKiBbc2l6ZV9pc11bdW5pcXVlXVtpbl0gKi8gSW50UHRyIHJlc2VydmVkMiwgCi0gICAgICAgICAgICAvKiBbaW5dICovIHVpbnQgcmVzZXJ2ZWQzLCAKLSAgICAgICAgICAgIC8qIFtvdXRdICovIG91dCBJRW51bVNUQVRTVEcgcHBlbnVtKTsgCi0gCi0gICAgICAgIHZvaWQgRGVzdHJveUVsZW1lbnQoIAotICAgICAgICAgICAgLyogW3N0cmluZ11baW5dICovIHN0cmluZyBwd2NzTmFtZSk7IAotIAotICAgICAgICB2b2lkIFJlbmFtZUVsZW1lbnQoIAotICAgICAgICAgICAgLyogW3N0cmluZ11baW5dICovIHN0cmluZyBwd2NzT2xkTmFtZSwgCi0gICAgICAgICAgICAvKiBbc3RyaW5nXVtpbl0gKi8gc3RyaW5nIHB3Y3NOZXdOYW1lKTsgCi0gCi0gICAgICAgIHZvaWQgU2V0RWxlbWVudFRpbWVzKCAKLSAgICAgICAgICAgIC8qIFtzdHJpbmddW3VuaXF1ZV1baW5dICovIHN0cmluZyBwd2NzTmFtZSwgCi0gICAgICAgICAgICAvKiBbdW5pcXVlXVtpbl0gKi8gU3lzdGVtLlJ1bnRpbWUuSW50ZXJvcFNlcnZpY2VzLkNvbVR5cGVzLkZJTEVUSU1FIHBjdGltZSwgCi0gICAgICAgICAgICAvKiBbdW5pcXVlXVtpbl0gKi8gU3lzdGVtLlJ1bnRpbWUuSW50ZXJvcFNlcnZpY2VzLkNvbVR5cGVzLkZJTEVUSU1FIHBhdGltZSwgCi0gICAgICAgICAgICAvKiBbdW5pcXVlXVtpbl0gKi8gU3lzdGVtLlJ1bnRpbWUuSW50ZXJvcFNlcnZpY2VzLkNvbVR5cGVzLkZJTEVUSU1FIHBtdGltZSk7IAotIAotICAgICAgICB2b2lkIFNldENsYXNzKCAKLSAgICAgICAgICAgIC8qIFtpbl0gKi8gR3VpZCBjbHNpZCk7IAotIAotICAgICAgICB2b2lkIFNldFN0YXRlQml0cyggCi0gICAgICAgICAgICAvKiBbaW5dICovIHVpbnQgZ3JmU3RhdGVCaXRzLCAKLSAgICAgICAgICAgIC8qIFtpbl0gKi8gdWludCBncmZNYXNrKTsgCi0gCi0gICAgICAgIHZvaWQgU3RhdCggCi0gICAgICAgICAgICAvKiBbb3V0XSAqLyBvdXQgU3lzdGVtLlJ1bnRpbWUuSW50ZXJvcFNlcnZpY2VzLkNvbVR5cGVzLlNUQVRTVEcgcHN0YXRzdGcsIAotICAgICAgICAgICAgLyogW2luXSAqLyB1aW50IGdyZlN0YXRGbGFnKTsgCi0gCi0gICAgfQotICAgIFtDb21WaXNpYmxlKGZhbHNlKV0KLSAgICBbQ29tSW1wb3J0LCBJbnRlcmZhY2VUeXBlKENvbUludGVyZmFjZVR5cGUuSW50ZXJmYWNlSXNJVW5rbm93biksIEd1aWQoIjAwMDAwMDBBLTAwMDAtMDAwMC1DMDAwLTAwMDAwMDAwMDA0NiIpXQotICAgIGludGVybmFsIGludGVyZmFjZSBJTG9ja0J5dGVzCi0gICAgewotICAgICAgICB2b2lkIFJlYWRBdChsb25nIHVsT2Zmc2V0LCBTeXN0ZW0uSW50UHRyIHB2LCBpbnQgY2IsIG91dCBVSW50UHRyIHBjYlJlYWQpOwotICAgICAgICB2b2lkIFdyaXRlQXQobG9uZyB1bE9mZnNldCwgU3lzdGVtLkludFB0ciBwdiwgaW50IGNiLCBvdXQgVUludFB0ciBwY2JXcml0dGVuKTsKLSAgICAgICAgdm9pZCBGbHVzaCgpOwotICAgICAgICB2b2lkIFNldFNpemUobG9uZyBjYik7Ci0gICAgICAgIHZvaWQgTG9ja1JlZ2lvbihsb25nIGxpYk9mZnNldCwgbG9uZyBjYiwgaW50IGR3TG9ja1R5cGUpOwotICAgICAgICB2b2lkIFVubG9ja1JlZ2lvbihsb25nIGxpYk9mZnNldCwgbG9uZyBjYiwgaW50IGR3TG9ja1R5cGUpOwotICAgICAgICB2b2lkIFN0YXQob3V0IFN5c3RlbS5SdW50aW1lLkludGVyb3BTZXJ2aWNlcy5Db21UeXBlcy5TVEFUU1RHIHBzdGF0c3RnLCBpbnQgZ3JmU3RhdEZsYWcpOwotICAgIH0KLSAgICBbRmxhZ3NdIAotICAgIGludGVybmFsIGVudW0gU1RHTSA6IGludCAKLSAgICB7IAotICAgICAgICBESVJFQ1QgPSAweDAwMDAwMDAwLCAKLSAgICAgICAgVFJBTlNBQ1RFRCA9IDB4MDAwMTAwMDAsIAotICAgICAgICBTSU1QTEUgPSAweDA4MDAwMDAwLCAKLSAgICAgICAgUkVBRCA9IDB4MDAwMDAwMDAsIAotICAgICAgICBXUklURSA9IDB4MDAwMDAwMDEsIAotICAgICAgICBSRUFEV1JJVEUgPSAweDAwMDAwMDAyLCAKLSAgICAgICAgU0hBUkVfREVOWV9OT05FID0gMHgwMDAwMDA0MCwgCi0gICAgICAgIFNIQVJFX0RFTllfUkVBRCA9IDB4MDAwMDAwMzAsIAotICAgICAgICBTSEFSRV9ERU5ZX1dSSVRFID0gMHgwMDAwMDAyMCwgCi0gICAgICAgIFNIQVJFX0VYQ0xVU0lWRSA9IDB4MDAwMDAwMTAsIAotICAgICAgICBQUklPUklUWSA9IDB4MDAwNDAwMDAsIAotICAgICAgICBERUxFVEVPTlJFTEVBU0UgPSAweDA0MDAwMDAwLCAKLSAgICAgICAgTk9TQ1JBVENIID0gMHgwMDEwMDAwMCwgCi0gICAgICAgIENSRUFURSA9IDB4MDAwMDEwMDAsIAotICAgICAgICBDT05WRVJUID0gMHgwMDAyMDAwMCwgCi0gICAgICAgIEZBSUxJRlRIRVJFID0gMHgwMDAwMDAwMCwgCi0gICAgICAgIE5PU05BUFNIT1QgPSAweDAwMjAwMDAwLCAKLSAgICAgICAgRElSRUNUX1NXTVIgPSAweDAwNDAwMDAwLCAKLSAgICB9IAotIAotICAgIGludGVybmFsIGVudW0gU1RBVEZMQUcgOiB1aW50IAotICAgIHsgCi0gICAgICAgIFNUQVRGTEFHX0RFRkFVTFQgPSAwLCAKLSAgICAgICAgU1RBVEZMQUdfTk9OQU1FID0gMSwgCi0gICAgICAgIFNUQVRGTEFHX05PT1BFTiA9IDIgCi0gICAgfSAKLSAKLSAgICBpbnRlcm5hbCBlbnVtIFNUR1RZIDogaW50IAotICAgIHsgCi0gICAgICAgIFNUR1RZX1NUT1JBR0UgPSAxLCAKLSAgICAgICAgU1RHVFlfU1RSRUFNID0gMiwgCi0gICAgICAgIFNUR1RZX0xPQ0tCWVRFUyA9IDMsIAotICAgICAgICBTVEdUWV9QUk9QRVJUWSA9IDQgCi0gICAgfQotfQpkaWZmIC0tZ2l0IGEvTmV0Q29yZVRlc3RzL0V4Y2VsUGFja2FnZVRlc3QuY3MgYi9OZXRDb3JlVGVzdHMvRXhjZWxQYWNrYWdlVGVzdC5jcwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lNTkyNzhmCi0tLSAvZGV2L251bGwKKysrIGIvTmV0Q29yZVRlc3RzL0V4Y2VsUGFja2FnZVRlc3QuY3MKQEAgLTAsMCArMSwzMCBAQAordXNpbmcgU3lzdGVtLklPOwordXNpbmcgU3lzdGVtLkxpbnE7Cit1c2luZyBGbHVlbnRBc3NlcnRpb25zOwordXNpbmcgTWljcm9zb2Z0LlZpc3VhbFN0dWRpby5UZXN0VG9vbHMuVW5pdFRlc3Rpbmc7Cit1c2luZyBPZmZpY2VPcGVuWG1sOworCituYW1lc3BhY2UgTmV0Q29yZVRlc3RzOworCitbVGVzdENsYXNzXQorcHVibGljIGNsYXNzIEV4Y2VsUGFja2FnZVRlc3QKK3sKKyAgICBbVGVzdE1ldGhvZF0KKyAgICBwdWJsaWMgdm9pZCBUZXN0R2V0QXNCeXRlQXJyYXkoKQorICAgIHsKKyAgICAgICAgdmFyIHBhY2thZ2UgPSBuZXcgRXhjZWxQYWNrYWdlKG5ldyBGaWxlSW5mbyhHZXRUZXN0V29ya2Jvb2tQYXRoKCJUaW1lcy54bHN4IikpKTsKKyAgICAgICAgdmFyIGRhdGEgPSBwYWNrYWdlLkdldEFzQnl0ZUFycmF5KCk7CisgICAgICAgIAorICAgICAgICAvLyBWZXJpZnkgdGhhdCB3ZSBjYW4gcmVsb2FkCisgICAgICAgIHZhciBuZXdQYWNrYWdlID0gbmV3IEV4Y2VsUGFja2FnZShuZXcgTWVtb3J5U3RyZWFtKGRhdGEsIGZhbHNlKSk7CisgICAgICAgIG5ld1BhY2thZ2UuV29ya2Jvb2suV29ya3NoZWV0cy5Db3VudC5TaG91bGQoKS5CZSgxKTsKKyAgICAgICAgdmFyIHdvcmtzaGVldCA9IG5ld1BhY2thZ2UuV29ya2Jvb2suV29ya3NoZWV0cy5GaXJzdCgpOworICAgICAgICB3b3Jrc2hlZXQuTmFtZS5TaG91bGQoKS5CZSgiVGltZXNfY3N2Iik7CisgICAgfQorICAgIAorICAgIHByaXZhdGUgc3RhdGljIHN0cmluZyBHZXRUZXN0V29ya2Jvb2tQYXRoKHN0cmluZyBmaWxlbmFtZSkKKyAgICB7CisgICAgICAgIHZhciBhc3NlbWJseVBhdGggPSBQYXRoLkdldERpcmVjdG9yeU5hbWUodHlwZW9mKEV4Y2VsUGFja2FnZVRlc3QpLkFzc2VtYmx5LkxvY2F0aW9uKSE7CisgICAgICAgIHJldHVybiBQYXRoLkNvbWJpbmUoYXNzZW1ibHlQYXRoLCAiVGVzdFdvcmtib29rcyIsIGZpbGVuYW1lKTsKKyAgICB9Cit9ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvTmV0Q29yZVRlc3RzL1RpbWVUZXN0LmNzIGIvTmV0Q29yZVRlc3RzL1RpbWVUZXN0LmNzCmluZGV4IDM5Y2MwMzguLmIyMDdmZjAgMTAwNjQ0Ci0tLSBhL05ldENvcmVUZXN0cy9UaW1lVGVzdC5jcworKysgYi9OZXRDb3JlVGVzdHMvVGltZVRlc3QuY3MKQEAgLTM3LDcgKzM3LDcgQEAKICAgICBbVGVzdE1ldGhvZF0KICAgICBwdWJsaWMgdm9pZCBUZXN0RGF0ZVBhcnNlKCkKICAgICB7Ci0gICAgICAgIHVzaW5nIHZhciBwYWNrYWdlID0gbmV3IEV4Y2VsUGFja2FnZShuZXcgRmlsZUluZm8oR2V0VGVzdFdvcmtib29rUGF0aCgiVGltZXMueGxzeCIpKSk7CisgICAgICAgIHZhciBwYWNrYWdlID0gbmV3IEV4Y2VsUGFja2FnZShuZXcgRmlsZUluZm8oR2V0VGVzdFdvcmtib29rUGF0aCgiVGltZXMueGxzeCIpKSk7CiAgICAgICAgIHZhciBzaGVldCA9IHBhY2thZ2UuV29ya2Jvb2suV29ya3NoZWV0cy5GaXJzdCgpOwogCiAgICAgICAgIHNoZWV0LkNlbGxzWyJCMyJdLlZhbHVlLlNob3VsZCgpLkJlKG5ldyBEYXRlVGltZSgxODk5LCAxMiwgMzAsIDMsIDE1LCAzMCkpOwo=