LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIAogKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCiAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgogKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCiAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQogKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqIAogKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKiAKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAogKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgogKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCiAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKICogdW5kZXIgdGhlIExpY2Vuc2UuCiAqIAogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCgoKLy8gTUFSS0VSKHVwZGF0ZV9wcmVjb21wLnB5KTogYXV0b2dlbiBpbmNsdWRlIHN0YXRlbWVudCwgZG8gbm90IHJlbW92ZQojaW5jbHVkZSAicHJlY29tcGlsZWRfYmFzaWMuaHh4IgoKI2luY2x1ZGUgInJ1bnRpbWUuaHh4IgojaWZuZGVmIEdDQwojZW5kaWYKI2luY2x1ZGUgImlvc3lzLmh4eCIKI2luY2x1ZGUgImltYWdlLmh4eCIKI2luY2x1ZGUgInNiaW50ZXJuLmh4eCIKI2luY2x1ZGUgInNidW5vb2JqLmh4eCIKI2luY2x1ZGUgIm9wY29kZXMuaHh4IgoKI2luY2x1ZGUgPGNvbS9zdW4vc3Rhci9jb250YWluZXIvWEluZGV4QWNjZXNzLmhwcD4KI2luY2x1ZGUgPGNvbS9zdW4vc3Rhci9zY3JpcHQvWERlZmF1bHRNZXRob2QuaHBwPgojaW5jbHVkZSA8Y29tL3N1bi9zdGFyL2JlYW5zL1hQcm9wZXJ0eVNldC5ocHA+CiNpbmNsdWRlIDxjb20vc3VuL3N0YXIvdW5vL0FueS5oeHg+CiNpbmNsdWRlIDxjb21waGVscGVyL3Byb2Nlc3NmYWN0b3J5Lmh4eD4KCnVzaW5nIG5hbWVzcGFjZSBjb206OnN1bjo6c3Rhcjo6dW5vOwp1c2luZyBuYW1lc3BhY2UgY29tOjpzdW46OnN0YXI6OmNvbnRhaW5lcjsKdXNpbmcgbmFtZXNwYWNlIGNvbTo6c3VuOjpzdGFyOjpsYW5nOwp1c2luZyBuYW1lc3BhY2UgY29tOjpzdW46OnN0YXI6OmJlYW5zOwp1c2luZyBuYW1lc3BhY2UgY29tOjpzdW46OnN0YXI6OnNjcmlwdDsKCnVzaW5nIGNvbTo6c3VuOjpzdGFyOjp1bm86OlJlZmVyZW5jZTsKClNieFZhcmlhYmxlKiBnZXRWQkFDb25zdGFudCggY29uc3QgU3RyaW5nJiByTmFtZSApOwoKLy8gU3VjaGVuIGVpbmVzIEVsZW1lbnRzCi8vIERpZSBCaXRzIGltIFN0cmluZy1JRDoKLy8gMHg4MDAwIC0gQXJndiBpc3QgYmVsZWd0CgpTYnhWYXJpYWJsZSogU2JpUnVudGltZTo6RmluZEVsZW1lbnQKCSggU2J4T2JqZWN0KiBwT2JqLCBzYWxfdUludDMyIG5PcDEsIHNhbF91SW50MzIgbk9wMiwgU2JFcnJvciBuTm90Rm91bmQsIHNhbF9Cb29sIGJMb2NhbCwgc2FsX0Jvb2wgYlN0YXRpYyApCnsKCWJvb2wgYklzVkJBSW50ZXJPcCA9IFNiaVJ1bnRpbWU6OmlzVkJBRW5hYmxlZCgpOwoJaWYoIGJJc1ZCQUludGVyT3AgKQoJewoJCVN0YXJCQVNJQyogcE1TT01hY3JvUnVudGltZUxpYiA9IEdldFNiRGF0YSgpLT5wTVNPTWFjcm9SdW50aW1MaWI7CgkJaWYoIHBNU09NYWNyb1J1bnRpbWVMaWIgIT0gTlVMTCApCgkJCXBNU09NYWNyb1J1bnRpbWVMaWItPlJlc2V0RmxhZyggU0JYX0VYVFNFQVJDSCApOwoJfQoKCVNieFZhcmlhYmxlKiBwRWxlbSA9IE5VTEw7CglpZiggIXBPYmogKQoJewoJCUVycm9yKCBTYkVSUl9OT19PQkpFQ1QgKTsKCQlwRWxlbSA9IG5ldyBTYnhWYXJpYWJsZTsKCX0KCWVsc2UKCXsKCQlzYWxfQm9vbCBiRmF0YWxFcnJvciA9IHNhbF9GYWxzZTsKCQlTYnhEYXRhVHlwZSB0ID0gKFNieERhdGFUeXBlKSBuT3AyOwoJCVN0cmluZyBhTmFtZSggcEltZy0+R2V0U3RyaW5nKCBzdGF0aWNfY2FzdDxzaG9ydD4oIG5PcDEgJiAweDdGRkYgKSApICk7CgkJLy8gSGFja3kgY2FwdHVyZSBvZiBFdmFsdWF0ZSBbXSBzeW50YXgKCQkvLyB0aGlzIHNob3VsZCBiZSB0YWNrbGVkIEkgZmVlbCBhdCB0aGUgcGNvZGUgbGV2ZWwKCQlpZiAoIGJJc1ZCQUludGVyT3AgJiYgYU5hbWUuU2VhcmNoKCdbJykgPT0gMCApCgkJewoJCQkvLyBlbXVsYXRlIHBjb2RlIGhlcmUKCQkJU3RlcEFSR0MoKTsKCQkJLy8gcHNldWRvIFN0ZXBMT0FEU0MKCQkJU3RyaW5nIHNBcmcgPSBhTmFtZS5Db3B5KCAxLCBhTmFtZS5MZW4oKSAtIDIgKTsKCQkJU2J4VmFyaWFibGUqIHAgPSBuZXcgU2J4VmFyaWFibGU7CgkJCXAtPlB1dFN0cmluZyggc0FyZyApOwoJCQlQdXNoVmFyKCBwICk7CgkJCS8vCgkJCVN0ZXBBUkdWKCk7CgkJCW5PcDEgPSBuT3AxIHwgMHg4MDAwOyAvLyBpbmRpY2F0ZSBwYXJhbXMgYXJlIHByZXNlbnQKCQkJYU5hbWUgPSBTdHJpbmc6OkNyZWF0ZUZyb21Bc2NpaSgiRXZhbHVhdGUiKTsKCQl9CgkJaWYoIGJMb2NhbCApCgkJewoJCQlpZiAoIGJTdGF0aWMgKQoJCQl7CQoJCQkJaWYgKCBwTWV0aCApCgkJCQkJcEVsZW0gPSBwTWV0aC0+R2V0U3RhdGljcygpLT5GaW5kKCBhTmFtZSwgU2J4Q0xBU1NfRE9OVENBUkUgKTsKCQkJfQoKCQkJaWYgKCAhcEVsZW0gKQoJCQkJcEVsZW0gPSByZWZMb2NhbHMtPkZpbmQoIGFOYW1lLCBTYnhDTEFTU19ET05UQ0FSRSApOwoJCX0KCQlpZiggIXBFbGVtICkKCQl7CgkJCS8vIERpZSBSVEwgYnJhdWNoZW4gd2lyIG5pY2h0IG1laHIgenUgZHVyY2hzdWNoZW4hCgkJCXNhbF9Cb29sIGJTYXZlID0gckJhc2ljLmJOb1J0bDsKCQkJckJhc2ljLmJOb1J0bCA9IHNhbF9UcnVlOwoJCQlwRWxlbSA9IHBPYmotPkZpbmQoIGFOYW1lLCBTYnhDTEFTU19ET05UQ0FSRSApOwoKCQkJLy8gIzExMDAwNCwgIzExMjAxNTogTWFrZSBwcml2YXRlIHJlYWxseSBwcml2YXRlCgkJCWlmKCBiTG9jYWwgJiYgcEVsZW0gKQkvLyBMb2NhbCBhcyBmbGFnIGZvciBnbG9iYWwgc2VhcmNoCgkJCXsKCQkJCWlmKCBwRWxlbS0+SXNTZXQoIFNCWF9QUklWQVRFICkgKQoJCQkJewoJCQkJCVNiaUluc3RhbmNlKiBwSW5zdF8gPSBwSU5TVDsKCQkJCQlpZiggcEluc3RfICYmIHBJbnN0Xy0+SXNDb21wYXRpYmlsaXR5KCkgJiYgcE9iaiAhPSBwRWxlbS0+R2V0UGFyZW50KCkgKQoJCQkJCQlwRWxlbSA9IE5VTEw7CS8vIEZvdW5kIGJ1dCBpbiB3cm9uZyBtb2R1bGUhCgoJCQkJCS8vIEludGVyZmFjZXM6IFVzZSBTQlhfRVhURk9VTkQKCQkJCX0KCQkJfQoJCQlyQmFzaWMuYk5vUnRsID0gYlNhdmU7CgoJCQkvLyBJc3QgZXMgZWluIGdsb2JhbGVyIFVuby1CZXplaWNobmVyPwoJCQlpZiggYkxvY2FsICYmICFwRWxlbSApCgkJCXsKCQkJCWJvb2wgYlNldE5hbWUgPSB0cnVlOyAvLyBwcmVzZXJ2ZSBub3JtYWwgYmVoYXZpb3VyCgoJCQkJLy8gaSNpNjg4OTQjIGlmIFZCQUludGVyT3AgZmF2b3VyIHNlYXJjaGluZyB2YmEgZ2xvYmFscwoJCQkJLy8gb3ZlciBzZWFyY2hpbmcgZm9yIHVubyBjbGFzc2VzcwoJCQkJaWYgKCBiVkJBRW5hYmxlZCApCgkJCQl7CgkJCQkJLy8gVHJ5IEZpbmQgaW4gVkJBIHN5bWJvbHMgc3BhY2UKCQkJCQlwRWxlbSA9IHJCYXNpYy5WQkFGaW5kKCBhTmFtZSwgU2J4Q0xBU1NfRE9OVENBUkUgKTsKCQkJCQlpZiAoIHBFbGVtICkKCQkJCQkJYlNldE5hbWUgPSBmYWxzZTsgLy8gZG9uJ3Qgb3ZlcndyaXRlIHVubyBuYW1lCgkJCQkJZWxzZQoJCQkJCQlwRWxlbSA9IGdldFZCQUNvbnN0YW50KCBhTmFtZSApOwoJCQkJfQoKCQkJCWlmKCAhcEVsZW0gKQoJCQkJewoJCQkJCS8vICM3MjM4MiBWT1JTSUNIVCEgTGllZmVydCBqZXR6dCB3ZWdlbiB1bmJla2FubnRlbgoJCQkJCS8vIE1vZHVsZW4gSU1NRVIgZWluIEVyZ2VibmlzIQoJCQkJCVNiVW5vQ2xhc3MqIHBVbm9DbGFzcyA9IGZpbmRVbm9DbGFzcyggYU5hbWUgKTsKCQkJCQlpZiggcFVub0NsYXNzICkKCQkJCQl7CgkJCQkJCXBFbGVtID0gbmV3IFNieFZhcmlhYmxlKCB0ICk7CgkJCQkJCVNieFZhbHVlcyBhUmVzKCBTYnhPQkpFQ1QgKTsKCQkJCQkJYVJlcy5wT2JqID0gcFVub0NsYXNzOwoJCQkJCQlwRWxlbS0+U2J4VmFyaWFibGU6OlB1dCggYVJlcyApOwoJCQkJCX0KCQkJCX0KCgkJCQkvLyAjNjI5MzkgV2VubiBlaW5lIFVuby1LbGFzc2UgZ2VmdW5kZW4gd3VyZGUsIG11c3MKCQkJCS8vIGRhcyBXcmFwcGVyLU9iamVrdCBnZWhhbHRlbiB3ZXJkZW4sIGRhIHNvbnN0IGF1Y2gKCQkJCS8vIGRpZSBVbm8tS2xhc3NlLCB6LkIuICJzdGFyZGl2IiBpbW1lciB3aWVkZXIgbmV1CgkJCQkvLyBhdXMgZGVyIFJlZ2lzdHJ5IGdlbGVzZW4gd2VyZGVuIG11c3MKCQkJCWlmKCBwRWxlbSApCgkJCQl7CgkJCQkJLy8gIzYzNzc0IERhcmYgbmljaHQgbWl0IGdlc3BlaWNoZXJ0IHdlcmRlbiEhIQoJCQkJCXBFbGVtLT5TZXRGbGFnKCBTQlhfRE9OVFNUT1JFICk7CgkJCQkJcEVsZW0tPlNldEZsYWcoIFNCWF9OT19NT0RJRlkpOwoKCQkJCQkvLyAjNzIzODIgTG9rYWwgc3BlaWNoZXJuLCBzb25zdCB3ZXJkZW4gYWxsZSBpbXBsaXppdAoJCQkJCS8vIGRla2xhcmllcnRlbiBWYXJzIGF1dG9tYXRpc2NoIGdsb2JhbCAhCgkJCQkJaWYgKCBiU2V0TmFtZSApCgkJCQkJCXBFbGVtLT5TZXROYW1lKCBhTmFtZSApOwoJCQkJCXJlZkxvY2Fscy0+UHV0KCBwRWxlbSwgcmVmTG9jYWxzLT5Db3VudCgpICk7CgkJCQl9CgkJCX0KCgkJCWlmKCAhcEVsZW0gKQoJCQl7CgkJCQkvLyBOaWNodCBkYSB1bmQgbmljaHQgaW0gT2JqZWt0PwoJCQkJLy8gSGF0IGRhcyBEaW5nIFBhcmFtZXRlciwgbmljaHQgZWlucmljaHRlbiEKCQkJCWlmKCBuT3AxICYgMHg4MDAwICkKCQkJCQliRmF0YWxFcnJvciA9IHNhbF9UcnVlOwoJCQkJCS8vIEFMVDogU3RhckJBU0lDOjpGYXRhbEVycm9yKCBuTm90Rm91bmQgKTsKCgkJCQkvLyBTb25zdCwgZmFsbHMga2VpbmUgUGFyYW1ldGVyIHNpbmQsIGFuZGVyZW4gRXJyb3IgQ29kZSB2ZXJ3ZW5kZW4KCQkJCWlmKCAhYkxvY2FsIHx8IHBJbWctPkdldEZsYWcoIFNCSU1HX0VYUExJQ0lUICkgKQoJCQkJewoJCQkJCS8vICMzOTEwOCBCZWkgZXhwbGl6aXQgdW5kIGFscyBFTEVNIGltbWVyIGVpbiBGYXRhbCBFcnJvcgoJCQkJCWJGYXRhbEVycm9yID0gc2FsX1RydWU7CgoJCQkJCS8vIEZhbGxzIGtlaW5lIFBhcmFtZXRlciBzaW5kLCBhbmRlcmVuIEVycm9yIENvZGUgdmVyd2VuZGVuCgkJCQkJaWYoICEoIG5PcDEgJiAweDgwMDAgKSAmJiBuTm90Rm91bmQgPT0gU2JFUlJfUFJPQ19VTkRFRklORUQgKQoJCQkJCQluTm90Rm91bmQgPSBTYkVSUl9WQVJfVU5ERUZJTkVEOwoJCQkJfQoJCQkJaWYoIGJGYXRhbEVycm9yICkKCQkJCXsKCQkJCQkvLyAjMzkxMDggU3RhdHQgRmF0YWxFcnJvciB6dSBzZXR6ZW4sIER1bW15LVZhcmlhYmxlIGxpZWZlcm4KCQkJCQlpZiggIXhEdW1teVZhci5JcygpICkKCQkJCQkJeER1bW15VmFyID0gbmV3IFNieFZhcmlhYmxlKCBTYnhWQVJJQU5UICk7CgkJCQkJcEVsZW0gPSB4RHVtbXlWYXI7CgoJCQkJCS8vIFBhcmFtZXRlciB2b24gSGFuZCBsb2VzY2hlbgoJCQkJCUNsZWFyQXJndlN0YWNrKCk7CgoJCQkJCS8vIE5vcm1hbGVuIEVycm9yIHNldHplbgoJCQkJCUVycm9yKCBuTm90Rm91bmQsIGFOYW1lICk7CgkJCQl9CgkJCQllbHNlCgkJCQl7CgkJCQkJaWYgKCBiU3RhdGljICkKCQkJCQkJcEVsZW0gPSBTdGVwU1RBVElDX0ltcGwoIGFOYW1lLCB0ICk7CgkJCQkJaWYgKCAhcEVsZW0gKQoJCQkJCXsKCQkJCQkJLy8gU29uc3QgVmFyaWFibGUgbmV1IGFubGVnZW4KCQkJCQkJcEVsZW0gPSBuZXcgU2J4VmFyaWFibGUoIHQgKTsKCQkJCQkJaWYoIHQgIT0gU2J4VkFSSUFOVCApCgkJCQkJCQlwRWxlbS0+U2V0RmxhZyggU0JYX0ZJWEVEICk7CgkJCQkJCXBFbGVtLT5TZXROYW1lKCBhTmFtZSApOwoJCQkJCQlyZWZMb2NhbHMtPlB1dCggcEVsZW0sIHJlZkxvY2Fscy0+Q291bnQoKSApOwoJCQkJCX0KCQkJCX0KCQkJfQoJCX0KCQkvLyAjMzkxMDggQXJncyBrb2VubmVuIHNjaG9uIGdlbG9lc2NodCBzZWluIQoJCWlmKCAhYkZhdGFsRXJyb3IgKQoJCQlTZXR1cEFyZ3MoIHBFbGVtLCBuT3AxICk7CgkJLy8gRWluIGJlc3RpbW10ZXIgQ2FsbC1UeXBlIHd1cmRlIGdld3VlbnNjaHQsIGRhaGVyIG11ZXNzZW4KCQkvLyB3aXIgaGllciBkZW4gVHlwIHNldHplbiB1bmQgZGFzIERpbmcgYW5mYXNzZW4sIHVtIGRlbgoJCS8vIGtvcnJla3RlbiBSZXR1cm53ZXJ0IHp1IGVyaGFsdGVuIQoJCWlmKCBkeW5hbWljX2Nhc3Q8IFNieE1ldGhvZCogPihwRWxlbSkgKQoJCXsKCQkJLy8gU29sbCBkZXIgVHlwIGtvbnZlcnRpZXJ0IHdlcmRlbj8KCQkJU2J4RGF0YVR5cGUgdDIgPSBwRWxlbS0+R2V0VHlwZSgpOwoJCQlzYWxfQm9vbCBiU2V0ID0gc2FsX0ZhbHNlOwoJCQlpZiggISggcEVsZW0tPkdldEZsYWdzKCkgJiBTQlhfRklYRUQgKSApCgkJCXsKCQkJCWlmKCB0ICE9IFNieFZBUklBTlQgJiYgdCAhPSB0MiAmJgoJCQkJCXQgPj0gU2J4SU5URUdFUiAmJiB0IDw9IFNieFNUUklORyApCgkJCQkJcEVsZW0tPlNldFR5cGUoIHQgKSwgYlNldCA9IHNhbF9UcnVlOwoJCQl9CgkJCS8vIHBFbGVtIGF1ZiBlaW5lIFJlZiB6dXdlaXNlbiwgdW0gZ2dmLiBlaW5lIFRlbXAtVmFyIHp1IGxvZXNjaGVuCgkJCVNieFZhcmlhYmxlUmVmIHJlZlRlbXAgPSBwRWxlbTsKCgkJCS8vIE1vZWdsaWNoZSBSZXN0ZSB2b20gbGV0enRlbiBBdWZydWYgZGVyIFNieE1ldGhvZCBiZXNlaXRpZ2VuCgkJCS8vIFZvcmhlciBTY2hyZWliZW4gZnJlaWdlYmVuLCBkYW1pdCBrZWluIEVycm9yIGdlc2V0enQgd2lyZC4KCQkJc2FsX3VJbnQxNiBuU2F2RmxhZ3MgPSBwRWxlbS0+R2V0RmxhZ3MoKTsKCQkJcEVsZW0tPlNldEZsYWcoIFNCWF9SRUFEV1JJVEUgfCBTQlhfTk9fQlJPQURDQVNUICk7CgkJCXBFbGVtLT5TYnhWYWx1ZTo6Q2xlYXIoKTsKCQkJcEVsZW0tPlNldEZsYWdzKCBuU2F2RmxhZ3MgKTsKCgkJCS8vIEVyc3QgbmFjaCBkZW0gU2V0emVuIGFuZmFzc2VuLCBkYSB6LkIuIExFRlQoKQoJCQkvLyBkZW4gVW50ZXJzY2hpZWQgendpc2NoZW4gTGVmdCQoKSB1bmQgTGVmdCgpIGtlbm5lbiBtdXNzCgoJCQkvLyBBQiAxMi44Ljk2OiBEYSBpbiBQb3BWYXIoKSBkaWUgUGFyYW1ldGVyIHZvbiBNZXRob2RlbiB3ZWdnZWhhdWVuCgkJCS8vIHdlcmRlbiwgbXVlc3NlbiB3aXIgaGllciBleHBsaXppdCBlaW5lIG5ldWUgU2J4TWV0aG9kIGFubGVnZW4KCQkJU2J4VmFyaWFibGUqIHBOZXcgPSBuZXcgU2J4TWV0aG9kKCAqKChTYnhNZXRob2QqKXBFbGVtKSApOyAvLyBkYXMgaXN0IGRlciBDYWxsIQoJCQkvL0FMVDogU2J4VmFyaWFibGUqIHBOZXcgPSBuZXcgU2J4VmFyaWFibGUoICpwRWxlbSApOyAvLyBkYXMgaXN0IGRlciBDYWxsIQoKCQkJcEVsZW0tPlNldFBhcmFtZXRlcnMoMCk7IC8vIHNvbnN0IGJsZWlidCBSZWYgYXVmIHNpY2ggc2VsYnN0CgkJCXBOZXctPlNldEZsYWcoIFNCWF9SRUFEV1JJVEUgKTsKCgkJCS8vIGRlbiBEYXRlbnR5cGVuIHp1cnVlY2tzZXR6ZW4/CgkJCWlmKCBiU2V0ICkKCQkJCXBFbGVtLT5TZXRUeXBlKCB0MiApOwoJCQlwRWxlbSA9IHBOZXc7CgkJfSAKCQkvLyBJbmRleC1BY2Nlc3MgYmVpIFVub09iamVrdGVuIGJlcnVlY2tzaWNodGlnZW4KCQkvLyBkZWZpbml0ZWx5IHdlIHdhbnQgdGhpcyBmb3IgVkJBIHdoZXJlIHByb3BlcnRpZXMgYXJlIG9mdGVuIAoJCS8vIGNvbGxlY3Rpb25zICggd2hpY2ggbmVlZCBpbmRleCBhY2Nlc3MgKSwgYnV0IGxldHMgb25seSBkbyAKCQkvLyB0aGlzIGlmIHdlIGFjdHVhbGx5IGhhdmUgcGFyYW1zIGZvbGxvd2luZwoJCWVsc2UgaWYoIGJWQkFFbmFibGVkICYmIGR5bmFtaWNfY2FzdDwgU2JVbm9Qcm9wZXJ0eSogPihwRWxlbSkgJiYgcEVsZW0tPkdldFBhcmFtZXRlcnMoKSApCgkJewoJCQkvLyBwRWxlbSBhdWYgZWluZSBSZWYgenV3ZWlzZW4sIHVtIGdnZi4gZWluZSBUZW1wLVZhciB6dSBsb2VzY2hlbgoJCQlTYnhWYXJpYWJsZVJlZiByZWZUZW1wID0gcEVsZW07CgoJCQkvLyBWYXJpYWJsZSBrb3BpZXJlbiB1bmQgZGFiZWkgZGVuIE5vdGlmeSBhdWZsb2VzZW4KCQkJU2J4VmFyaWFibGUqIHBOZXcgPSBuZXcgU2J4VmFyaWFibGUoICooKFNieFZhcmlhYmxlKilwRWxlbSkgKTsgLy8gZGFzIGlzdCBkZXIgQ2FsbCEKCQkJcEVsZW0tPlNldFBhcmFtZXRlcnMoIE5VTEwgKTsgLy8gc29uc3QgYmxlaWJ0IFJlZiBhdWYgc2ljaCBzZWxic3QKCQkJcEVsZW0gPSBwTmV3OwoJCX0KCX0KCXJldHVybiBDaGVja0FycmF5KCBwRWxlbSApOwp9CgovLyBGaW5kLUZ1bmt0aW9uIHVlYmVyIE5hbWUgZnVlciBha3R1ZWxsZW4gU2NvcGUgKHouQi4gQWJmcmFnZSBhdXMgQkFTSUMtSURFKQpTYnhCYXNlKiBTYmlSdW50aW1lOjpGaW5kRWxlbWVudEV4dGVybiggY29uc3QgU3RyaW5nJiByTmFtZSApCnsKCS8vIEhpbndlaXMgenUgIzM1MjgxIzogRXMgZGFyZiBuaWNodCBkYXZvbiBhdXNnZWdhbmdlbiB3ZXJkZW4sIGRhc3MKCS8vIHBNZXRoICE9IG51bGwsIGRhIGltIFJ1bkluaXQgbm9jaCBrZWluZSBnZXNldHp0IGlzdC4KCglTYnhWYXJpYWJsZSogcEVsZW0gPSBOVUxMOwoJaWYoICFwTW9kIHx8ICFyTmFtZS5MZW4oKSApCgkJcmV0dXJuIE5VTEw7CgoJLy8gTG9rYWwgc3VjaGVuCglpZiggcmVmTG9jYWxzICkKCQlwRWxlbSA9IHJlZkxvY2Fscy0+RmluZCggck5hbWUsIFNieENMQVNTX0RPTlRDQVJFICk7CgoJLy8gSW4gU3RhdGljcyBzdWNoZW4KCWlmICggIXBFbGVtICYmIHBNZXRoICkKCXsKCQkvLyBCZWkgU3RhdGljcywgTmFtZSBkZXIgTWV0aG9kZSBkYXZvciBzZXR6ZW4KCQlTdHJpbmcgYU1ldGhOYW1lID0gcE1ldGgtPkdldE5hbWUoKTsKCQlhTWV0aE5hbWUgKz0gJzonOwoJCWFNZXRoTmFtZSArPSByTmFtZTsKCQlwRWxlbSA9IHBNb2QtPkZpbmQoYU1ldGhOYW1lLCBTYnhDTEFTU19ET05UQ0FSRSk7Cgl9CgoJLy8gSW4gUGFyYW1ldGVyLUxpc3RlIHN1Y2hlbgoJaWYoICFwRWxlbSAmJiBwTWV0aCApCgl7CgkJU2J4SW5mbyogcEluZm8gPSBwTWV0aC0+R2V0SW5mbygpOwoJCWlmKCBwSW5mbyAmJiByZWZQYXJhbXMgKQoJCXsKICAgICAgICAJc2FsX3VJbnQxNiBuUGFyYW1Db3VudCA9IHJlZlBhcmFtcy0+Q291bnQoKTsKCQkJc2FsX3VJbnQxNiBqID0gMTsKCQkJY29uc3QgU2J4UGFyYW1JbmZvKiBwUGFyYW0gPSBwSW5mby0+R2V0UGFyYW0oIGogKTsKCQkJd2hpbGUoIHBQYXJhbSApCgkJCXsKCQkJCWlmKCBwUGFyYW0tPmFOYW1lLkVxdWFsc0lnbm9yZUNhc2VBc2NpaSggck5hbWUgKSApCgkJCQl7CgkgICAgICAgICAgICAgICAgaWYoIGogPj0gblBhcmFtQ291bnQgKQoJICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gUGFyYW1ldGVyIGlzIG1pc3NpbmcKICAgIAkJCQkJcEVsZW0gPSBuZXcgU2J4VmFyaWFibGUoIFNieFNUUklORyApOwogICAgICAgICAgICAgICAgICAgICAgICBwRWxlbS0+UHV0U3RyaW5nKCBTdHJpbmcoIFJUTF9DT05TVEFTQ0lJX1VTVFJJTkdQQVJBTSgiPG1pc3NpbmcgcGFyYW1ldGVyPiIgKSApICk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICB7CiAgICAJCQkJCXBFbGVtID0gcmVmUGFyYW1zLT5HZXQoIGogKTsKICAgICAgICAgICAgICAgICAgICB9CgkJCQkJYnJlYWs7CgkJCQl9CgkJCQlwUGFyYW0gPSBwSW5mby0+R2V0UGFyYW0oICsraiApOwoJCQl9CgkJfQoJfQoKCS8vIEltIE1vZHVsIHN1Y2hlbgoJaWYoICFwRWxlbSApCgl7CgkJLy8gUlRMIG5pY2h0IGR1cmNoc3VjaGVuIQoJCXNhbF9Cb29sIGJTYXZlID0gckJhc2ljLmJOb1J0bDsKCQlyQmFzaWMuYk5vUnRsID0gc2FsX1RydWU7CgkJcEVsZW0gPSBwTW9kLT5GaW5kKCByTmFtZSwgU2J4Q0xBU1NfRE9OVENBUkUgKTsKCQlyQmFzaWMuYk5vUnRsID0gYlNhdmU7Cgl9CglyZXR1cm4gcEVsZW07Cn0KCgovLyBBcmd1bWVudGUgZWluZXMgRWxlbWVudHMgc2V0emVuCi8vIERhYmVpIGF1Y2ggZGllIEFyZ3VtZW50ZSB1bXNldHplbiwgZmFsbHMgYmVuYW5udGUgUGFyYW1ldGVyCi8vIHZlcndlbmRldCB3dXJkZW4KCnZvaWQgU2JpUnVudGltZTo6U2V0dXBBcmdzKCBTYnhWYXJpYWJsZSogcCwgc2FsX3VJbnQzMiBuT3AxICkKewoJaWYoIG5PcDEgJiAweDgwMDAgKQoJewoJCWlmKCAhcmVmQXJndiApCgkJCVN0YXJCQVNJQzo6RmF0YWxFcnJvciggU2JFUlJfSU5URVJOQUxfRVJST1IgKTsKCQlzYWxfQm9vbCBiSGFzTmFtZWQgPSBzYWxfRmFsc2U7CgkJc2FsX3VJbnQxNiBpOwoJCXNhbF91SW50MTYgbkFyZ0NvdW50ID0gcmVmQXJndi0+Q291bnQoKTsKCQlmb3IoIGkgPSAxIDsgaSA8IG5BcmdDb3VudCA7IGkrKyApCgkJewoJCQlpZiggcmVmQXJndi0+R2V0QWxpYXMoIGkgKS5MZW4oKSApCgkJCXsKCQkJCWJIYXNOYW1lZCA9IHNhbF9UcnVlOyBicmVhazsKCQkJfQoJCX0KCQlpZiggYkhhc05hbWVkICkKCQl7CgkJCS8vIFdpciBoYWJlbiBtaW5kZXN0ZW5zIGVpbmVuIGJlbmFubnRlbiBQYXJhbWV0ZXIhCgkJCS8vIFdpciBtdWVzc2VuIGFsc28gdW1zb3J0aWVyZW4KCQkJLy8gR2lidCBlcyBQYXJhbWV0ZXItSW5mb3M/CgkJCVNieEluZm8qIHBJbmZvID0gcC0+R2V0SW5mbygpOwoJCQlpZiggIXBJbmZvICkKCQkJewoJCQkJYm9vbCBiRXJyb3JfID0gdHJ1ZTsKCgkJCQlTYlVub01ldGhvZCogcFVub01ldGhvZCA9IGR5bmFtaWNfY2FzdDwgU2JVbm9NZXRob2QqID4ocCk7CgkJCQlTYlVub1Byb3BlcnR5KiBwVW5vUHJvcGVydHkgPSBkeW5hbWljX2Nhc3Q8IFNiVW5vUHJvcGVydHkqID4ocCk7CgkJCQlpZiggcFVub01ldGhvZCB8fCBwVW5vUHJvcGVydHkgKQoJCQkJewoJCQkJCVNiVW5vT2JqZWN0KiBwUGFyZW50VW5vT2JqID0gZHluYW1pY19jYXN0PCBTYlVub09iamVjdCogPiggcC0+R2V0UGFyZW50KCkgKTsKCQkJCQlpZiggcFBhcmVudFVub09iaiApCgkJCQkJewoJCQkJCQlBbnkgYVVub0FueSA9IHBQYXJlbnRVbm9PYmotPmdldFVub0FueSgpOwoJCQkJCQlSZWZlcmVuY2U8IFhJbnZvY2F0aW9uID4geEludm9jYXRpb247CgkJCQkJCWFVbm9BbnkgPj49IHhJbnZvY2F0aW9uOwoJCQkJCQlpZiggeEludm9jYXRpb24uaXMoKSApCS8vIFRPRE86IGlmKCB4T0xFQXV0b21hdGlvbi5pcygpICkKCQkJCQkJewoJCQkJCQkJYkVycm9yXyA9IGZhbHNlOwoKCQkJCQkJCXNhbF91SW50MTYgbkN1clBhciA9IDE7CgkJCQkJCQlBdXRvbWF0aW9uTmFtZWRBcmdzU2J4QXJyYXkqIHBBcmcgPQoJCQkJCQkJCW5ldyBBdXRvbWF0aW9uTmFtZWRBcmdzU2J4QXJyYXkoIG5BcmdDb3VudCApOwoJCQkJCQkJOjpydGw6Ok9VU3RyaW5nKiBwTmFtZXMgPSBwQXJnLT5nZXROYW1lcygpLmdldEFycmF5KCk7CgkJCQkJCQlmb3IoIGkgPSAxIDsgaSA8IG5BcmdDb3VudCA7IGkrKyApCgkJCQkJCQl7CgkJCQkJCQkJU2J4VmFyaWFibGUqIHBWYXIgPSByZWZBcmd2LT5HZXQoIGkgKTsKCQkJCQkJCQljb25zdCBTdHJpbmcmIHJOYW1lID0gcmVmQXJndi0+R2V0QWxpYXMoIGkgKTsKCQkJCQkJCQlpZiggck5hbWUuTGVuKCkgKQoJCQkJCQkJCQlwTmFtZXNbaV0gPSByTmFtZTsKCQkJCQkJCQlwQXJnLT5QdXQoIHBWYXIsIG5DdXJQYXIrKyApOwoJCQkJCQkJfQoJCQkJCQkJcmVmQXJndiA9IHBBcmc7CgkJCQkJCX0KCQkJCQl9CgkJCQl9CgkJCQllbHNlIGlmKCBiVkJBRW5hYmxlZCAmJiBwLT5HZXRUeXBlKCkgPT0gU2J4T0JKRUNUICYmICghZHluYW1pY19jYXN0PCBTYnhNZXRob2QqID4ocCkgfHwgIXAtPklzQnJvYWRjYXN0ZXIoKSkgKQoJCQkJewoJCQkJCS8vIENoZWNrIGZvciBkZWZhdWx0IG1ldGhvZCB3aXRoIG5hbWVkIHBhcmFtZXRlcnMKCQkJCQlTYnhCYXNlUmVmIHBPYmogPSAoU2J4QmFzZSopcC0+R2V0T2JqZWN0KCk7CgkJCQkJaWYoIHBPYmogJiYgZHluYW1pY19jYXN0PCBTYlVub09iamVjdCogPigoU2J4QmFzZSopcE9iaikgKQoJCQkJCXsKCQkJCQkJU2JVbm9PYmplY3QqIHBVbm9PYmogPSAoU2JVbm9PYmplY3QqKShTYnhCYXNlKilwT2JqOwoJCQkJCQlBbnkgYUFueSA9IHBVbm9PYmotPmdldFVub0FueSgpOwoKCQkJCQkJaWYoIGFBbnkuZ2V0VmFsdWVUeXBlKCkuZ2V0VHlwZUNsYXNzKCkgPT0gVHlwZUNsYXNzX0lOVEVSRkFDRSApCgkJCQkJCXsKCQkJCQkJCVJlZmVyZW5jZTwgWEludGVyZmFjZSA+IHggPSAqKFJlZmVyZW5jZTwgWEludGVyZmFjZSA+KilhQW55LmdldFZhbHVlKCk7CgkJCQkJCQlSZWZlcmVuY2U8IFhEZWZhdWx0TWV0aG9kID4geERmbHRNZXRob2QoIHgsIFVOT19RVUVSWSApOwoKCQkJCQkJCXJ0bDo6T1VTdHJpbmcgc0RlZmF1bHRNZXRob2Q7CgkJCQkJCQlpZiAoIHhEZmx0TWV0aG9kLmlzKCkgKQoJCQkJCQkJCXNEZWZhdWx0TWV0aG9kID0geERmbHRNZXRob2QtPmdldERlZmF1bHRNZXRob2ROYW1lKCk7CgkJCQkJCQlpZiAoICFzRGVmYXVsdE1ldGhvZC5pc0VtcHR5KCkgKQoJCQkJCQkJewoJCQkJCQkJCVNieFZhcmlhYmxlKiBtZXRoID0gcFVub09iai0+RmluZCggc0RlZmF1bHRNZXRob2QsIFNieENMQVNTX01FVEhPRCApOwoJCQkJCQkJCWlmKCBtZXRoICE9IE5VTEwgKQoJCQkJCQkJCQlwSW5mbyA9IG1ldGgtPkdldEluZm8oKTsKCQkJCQkJCQlpZiggcEluZm8gKQoJCQkJCQkJCQliRXJyb3JfID0gZmFsc2U7CgkJCQkJCQl9CgkJCQkJCX0KCQkJCQl9CgkJCQl9CgkJCQlpZiggYkVycm9yXyApCgkJCQkJRXJyb3IoIFNiRVJSX05PX05BTUVEX0FSR1MgKTsKCQkJfQoJCQllbHNlCgkJCXsKCQkJCXNhbF91SW50MTYgbkN1clBhciA9IDE7CgkJCQlTYnhBcnJheSogcEFyZyA9IG5ldyBTYnhBcnJheTsKCQkJCWZvciggaSA9IDEgOyBpIDwgbkFyZ0NvdW50IDsgaSsrICkKCQkJCXsKCQkJCQlTYnhWYXJpYWJsZSogcFZhciA9IHJlZkFyZ3YtPkdldCggaSApOwoJCQkJCWNvbnN0IFN0cmluZyYgck5hbWUgPSByZWZBcmd2LT5HZXRBbGlhcyggaSApOwoJCQkJCWlmKCByTmFtZS5MZW4oKSApCgkJCQkJewoJCQkJCQkvLyBuQ3VyUGFyIHdpcmQgYXVmIGRlbiBnZWZ1bmRlbmVuIFBhcmFtZXRlciBnZXNldHp0CgkJCQkJCXNhbF91SW50MTYgaiA9IDE7CgkJCQkJCWNvbnN0IFNieFBhcmFtSW5mbyogcFBhcmFtID0gcEluZm8tPkdldFBhcmFtKCBqICk7CgkJCQkJCXdoaWxlKCBwUGFyYW0gKQoJCQkJCQl7CgkJCQkJCQlpZiggcFBhcmFtLT5hTmFtZS5FcXVhbHNJZ25vcmVDYXNlQXNjaWkoIHJOYW1lICkgKQoJCQkJCQkJewoJCQkJCQkJCW5DdXJQYXIgPSBqOwoJCQkJCQkJCWJyZWFrOwoJCQkJCQkJfQoJCQkJCQkJcFBhcmFtID0gcEluZm8tPkdldFBhcmFtKCArK2ogKTsKCQkJCQkJfQoJCQkJCQlpZiggIXBQYXJhbSApCgkJCQkJCXsKCQkJCQkJCUVycm9yKCBTYkVSUl9OQU1FRF9OT1RfRk9VTkQgKTsgYnJlYWs7CgkJCQkJCX0KCQkJCQl9CgkJCQkJcEFyZy0+UHV0KCBwVmFyLCBuQ3VyUGFyKysgKTsKCQkJCX0KCQkJCXJlZkFyZ3YgPSBwQXJnOwoJCQl9CgkJfQoJCS8vIEVpZ2VuZSBWYXIgYWxzIFBhcmFtZXRlciAwCgkJcmVmQXJndi0+UHV0KCBwLCAwICk7CgkJcC0+U2V0UGFyYW1ldGVycyggcmVmQXJndiApOwoJCVBvcEFyZ3YoKTsKCX0KCWVsc2UKCQlwLT5TZXRQYXJhbWV0ZXJzKCBOVUxMICk7Cn0KCi8vIEhvbGVuIGVpbmVzIEFycmF5LUVsZW1lbnRzCgpTYnhWYXJpYWJsZSogU2JpUnVudGltZTo6Q2hlY2tBcnJheSggU2J4VmFyaWFibGUqIHBFbGVtICkKewoJLy8gRmFsbHMgd2lyIGVpbiBBcnJheSBoYWJlbiwgd29sbGVuIHdpciBiaXR0ZSBkYXMgQXJyYXktRWxlbWVudCEKCVNieEFycmF5KiBwUGFyOwoJaWYoIHBFbGVtLT5HZXRUeXBlKCkgJiBTYnhBUlJBWSApCgl7CgkJU2J4QmFzZSogcEVsZW1PYmogPSBwRWxlbS0+R2V0T2JqZWN0KCk7CgkJU2J4RGltQXJyYXkqIHBEaW1BcnJheSA9IGR5bmFtaWNfY2FzdDwgU2J4RGltQXJyYXkqID4oIHBFbGVtT2JqKTsKCQlwUGFyID0gcEVsZW0tPkdldFBhcmFtZXRlcnMoKTsKCQlpZiggcERpbUFycmF5ICkKCQl7CgkJCS8vIERpZSBQYXJhbWV0ZXIga29lbm5lbiBmZWhsZW4sIHdlbm4gZWluIEFycmF5IGFscwoJCQkvLyBBcmd1bWVudCB1ZWJlcmdlYmVuIHdpcmQuCgkJCWlmKCBwUGFyICkKCQkJCXBFbGVtID0gcERpbUFycmF5LT5HZXQoIHBQYXIgKTsKCQl9CgkJZWxzZQoJCXsKCQkJU2J4QXJyYXkqIHBBcnJheSA9IGR5bmFtaWNfY2FzdDwgU2J4QXJyYXkqID4oIHBFbGVtT2JqKTsKCQkJaWYoIHBBcnJheSApCgkJCXsKCQkJCWlmKCAhcFBhciApCgkJCQl7CgkJCQkJRXJyb3IoIFNiRVJSX09VVF9PRl9SQU5HRSApOwoJCQkJCXBFbGVtID0gbmV3IFNieFZhcmlhYmxlOwoJCQkJfQoJCQkJZWxzZQoJCQkJCXBFbGVtID0gcEFycmF5LT5HZXQoIHBQYXItPkdldCggMSApLT5HZXRJbnRlZ2VyKCkgKTsKCQkJfQoJCX0KCgkJLy8gIzQyOTQwLCAwLlBhcmFtZXRlciB6dSBOVUxMIHNldHplbiwgZGFtaXQgc2ljaCBWYXIgbmljaHQgc2VsYnN0IGhhZWx0CgkJaWYoIHBQYXIgKQoJCQlwUGFyLT5QdXQoIE5VTEwsIDAgKTsKCX0KCS8vIEluZGV4LUFjY2VzcyBiZWkgVW5vT2JqZWt0ZW4gYmVydWVja3NpY2h0aWdlbgoJZWxzZSBpZiggcEVsZW0tPkdldFR5cGUoKSA9PSBTYnhPQkpFQ1QgJiYgKCFkeW5hbWljX2Nhc3Q8IFNieE1ldGhvZCogPihwRWxlbSkgfHwgKGJWQkFFbmFibGVkICYmICFwRWxlbS0+SXNCcm9hZGNhc3RlcigpKSkpCiAgICB7CiAgICAgICAgcFBhciA9IHBFbGVtLT5HZXRQYXJhbWV0ZXJzKCk7CiAgICAgICAgaWYgKCBwUGFyICkKICAgICAgICB7CiAgICAgICAgICAgIC8vIElzdCBlcyBlaW4gVW5vLU9iamVrdD8KICAgICAgICAgICAgU2J4QmFzZVJlZiBwT2JqID0gKFNieEJhc2UqKXBFbGVtLT5HZXRPYmplY3QoKTsKICAgICAgICAgICAgaWYoIHBPYmogKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBTYlVub09iamVjdCogcFVub09iaiA9IGR5bmFtaWNfY2FzdDwgU2JVbm9PYmplY3QqID4oKFNieEJhc2UqKXBPYmopOwogICAgICAgICAgICAgICAgCgkJCQlpZiggcFVub09iaiApCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgQW55IGFBbnkgPSBwVW5vT2JqLT5nZXRVbm9BbnkoKTsKCiAgICAgICAgICAgICAgICAgICAgaWYoIGFBbnkuZ2V0VmFsdWVUeXBlKCkuZ2V0VHlwZUNsYXNzKCkgPT0gVHlwZUNsYXNzX0lOVEVSRkFDRSApCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBSZWZlcmVuY2U8IFhJbnRlcmZhY2UgPiB4ID0gKihSZWZlcmVuY2U8IFhJbnRlcmZhY2UgPiopYUFueS5nZXRWYWx1ZSgpOwogICAgICAgICAgICAgICAgICAgICAgICBSZWZlcmVuY2U8IFhJbmRleEFjY2VzcyA+IHhJbmRleEFjY2VzcyggeCwgVU5PX1FVRVJZICk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICggIWJWQkFFbmFibGVkICkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gSGFiZW4gd2lyIEluZGV4LUFjY2Vzcz8KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKCB4SW5kZXhBY2Nlc3MuaXMoKSApCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2FsX3VJbnQzMiBuUGFyYW1Db3VudCA9IChzYWxfdUludDMyKXBQYXItPkNvdW50KCkgLSAxOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKCBuUGFyYW1Db3VudCAhPSAxICkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0YXJCQVNJQzo6RXJyb3IoIFNiRVJSX0JBRF9BUkdVTUVOVCApOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcEVsZW07CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBJbmRleCBob2xlbgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNhbF9JbnQzMiBuSW5kZXggPSBwUGFyLT5HZXQoIDEgKS0+R2V0TG9uZygpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlZmVyZW5jZTwgWEludGVyZmFjZSA+IHhSZXQ7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ5CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBbnkgYUFueTIgPSB4SW5kZXhBY2Nlc3MtPmdldEJ5SW5kZXgoIG5JbmRleCApOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUeXBlQ2xhc3MgZVR5cGUgPSBhQW55Mi5nZXRWYWx1ZVR5cGUoKS5nZXRUeXBlQ2xhc3MoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYoIGVUeXBlID09IFR5cGVDbGFzc19JTlRFUkZBQ0UgKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeFJldCA9ICooUmVmZXJlbmNlPCBYSW50ZXJmYWNlID4qKWFBbnkyLmdldFZhbHVlKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhdGNoIChJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uJikKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEJlaSBFeGNlcHRpb24gZXJzdG1hbCBpbW1lciB2b24gS29udmVydGllcnVuZ3MtUHJvYmxlbSBhdXNnZWhlbgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdGFyQkFTSUM6OkVycm9yKCBTYkVSUl9PVVRfT0ZfUkFOR0UgKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICM1Nzg0NyBJbW1lciBuZXVlIFZhcmlhYmxlIGFubGVnZW4sIHNvbnN0IEZlaGxlcgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGR1cmNoIFB1dE9iamVjdChOVUxMKSBiZWkgUmVhZE9ubHktUHJvcGVydGllcy4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwRWxlbSA9IG5ldyBTYnhWYXJpYWJsZSggU2J4VkFSSUFOVCApOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKCB4UmV0LmlzKCkgKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYUFueSA8PD0geFJldDsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICM2NzE3MyBLZWluIE5hbWVuIGFuZ2ViZW4sIGRhbWl0IGVjaHRlciBLbGFzc2VuLU5hbWVuIGVpbnRyYWdlbiB3aXJkCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cmluZyBhTmFtZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU2J4T2JqZWN0UmVmIHhXcmFwcGVyID0gKFNieE9iamVjdCopbmV3IFNiVW5vT2JqZWN0KCBhTmFtZSwgYUFueSApOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwRWxlbS0+UHV0T2JqZWN0KCB4V3JhcHBlciApOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwRWxlbS0+UHV0T2JqZWN0KCBOVUxMICk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcnRsOjpPVVN0cmluZyBzRGVmYXVsdE1ldGhvZDsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZWZlcmVuY2U8IFhEZWZhdWx0TWV0aG9kID4geERmbHRNZXRob2QoIHgsIFVOT19RVUVSWSApOwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICggeERmbHRNZXRob2QuaXMoKSApCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc0RlZmF1bHRNZXRob2QgPSB4RGZsdE1ldGhvZC0+Z2V0RGVmYXVsdE1ldGhvZE5hbWUoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYoIHhJbmRleEFjY2Vzcy5pcygpICkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzRGVmYXVsdE1ldGhvZCA9IHJ0bDo6T1VTdHJpbmcoIFJUTF9DT05TVEFTQ0lJX1VTVFJJTkdQQVJBTSggImdldEJ5SW5kZXgiICkgKTsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoICFzRGVmYXVsdE1ldGhvZC5pc0VtcHR5KCkgKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNieFZhcmlhYmxlKiBtZXRoID0gcFVub09iai0+RmluZCggc0RlZmF1bHRNZXRob2QsIFNieENMQVNTX01FVEhPRCApOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNieFZhcmlhYmxlUmVmIHJlZlRlbXAgPSBtZXRoOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICggcmVmVGVtcCApCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXRoLT5TZXRQYXJhbWV0ZXJzKCBwUGFyICk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNieFZhcmlhYmxlKiBwTmV3ID0gbmV3IFNieE1ldGhvZCggKihTYnhNZXRob2QqKW1ldGggKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcEVsZW0gPSBwTmV3OwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgLy8gIzQyOTQwLCAwLlBhcmFtZXRlciB6dSBOVUxMIHNldHplbiwgZGFtaXQgc2ljaCBWYXIgbmljaHQgc2VsYnN0IGhhZWx0CiAgICAgICAgICAgICAgICAgICAgcFBhci0+UHV0KCBOVUxMLCAwICk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCgkJCQl7CgkJCQkJQmFzaWNDb2xsZWN0aW9uKiBwQ29sID0gZHluYW1pY19jYXN0PCBCYXNpY0NvbGxlY3Rpb24qID4oKFNieEJhc2UqKXBPYmopOwoJCQkJCQoJCQkJCWlmKCBwQ29sICkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBwRWxlbSA9IG5ldyBTYnhWYXJpYWJsZSggU2J4VkFSSUFOVCApOwogICAgICAgICAgICAgICAgICAgIHBQYXItPlB1dCggcEVsZW0sIDAgKTsKICAgICAgICAgICAgICAgICAgICBwQ29sLT5Db2xsSXRlbSggcFBhciApOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCQkJZWxzZSBpZiggYlZCQUVuYWJsZWQgKQkvLyAhcE9iagogICAgICAgICAgICB7CgkJCQlTYnhBcnJheSogcFBhcmFtID0gcEVsZW0tPkdldFBhcmFtZXRlcnMoKTsKCQkJCWlmKCBwUGFyYW0gIT0gTlVMTCAmJiAhcEVsZW0tPklzU2V0KCBTQlhfVkFSX1RPX0RJTSApICkKCQkJCQlFcnJvciggU2JFUlJfTk9fT0JKRUNUICk7CgkJCX0KICAgICAgICB9CiAgICB9CgoJcmV0dXJuIHBFbGVtOwp9CgovLyBMYWRlbiBlaW5lcyBFbGVtZW50cyBhdXMgZGVyIFJ1bnRpbWUtTGlicmFyeSAoK1N0cmluZ0lEK1R5cCkKCnZvaWQgU2JpUnVudGltZTo6U3RlcFJUTCggc2FsX3VJbnQzMiBuT3AxLCBzYWxfdUludDMyIG5PcDIgKQp7CglQdXNoVmFyKCBGaW5kRWxlbWVudCggckJhc2ljLnBSdGwsIG5PcDEsIG5PcDIsIFNiRVJSX1BST0NfVU5ERUZJTkVELCBzYWxfRmFsc2UgKSApOwp9Cgp2b2lkClNiaVJ1bnRpbWU6OlN0ZXBGSU5EX0ltcGwoIFNieE9iamVjdCogcE9iaiwgc2FsX3VJbnQzMiBuT3AxLCBzYWxfdUludDMyIG5PcDIsIFNiRXJyb3Igbk5vdEZvdW5kLCBzYWxfQm9vbCBiTG9jYWwsIHNhbF9Cb29sIGJTdGF0aWMgKQp7CglpZiggIXJlZkxvY2FscyApCgkJcmVmTG9jYWxzID0gbmV3IFNieEFycmF5OwoJUHVzaFZhciggRmluZEVsZW1lbnQoIHBPYmosIG5PcDEsIG5PcDIsIG5Ob3RGb3VuZCwgYkxvY2FsLCBiU3RhdGljICkgKTsKfQovLyBMYWRlbiBlaW5lciBsb2thbGVuL2dsb2JhbGVuIFZhcmlhYmxlbiAoK1N0cmluZ0lEK1R5cCkKCnZvaWQgU2JpUnVudGltZTo6U3RlcEZJTkQoIHNhbF91SW50MzIgbk9wMSwgc2FsX3VJbnQzMiBuT3AyICkKewoJU3RlcEZJTkRfSW1wbCggcE1vZCwgbk9wMSwgbk9wMiwgU2JFUlJfUFJPQ19VTkRFRklORUQsIHNhbF9UcnVlICk7Cn0KCi8vIFNlYXJjaCBpbnNpZGUgYSBjbGFzcyBtb2R1bGUgKENNKSB0byBlbmFibGUgZ2xvYmFsIHNlYXJjaCBpbiB0aW1lCnZvaWQgU2JpUnVudGltZTo6U3RlcEZJTkRfQ00oIHNhbF91SW50MzIgbk9wMSwgc2FsX3VJbnQzMiBuT3AyICkKewoKCVNiQ2xhc3NNb2R1bGVPYmplY3QqIHBDbGFzc01vZHVsZU9iamVjdCA9IGR5bmFtaWNfY2FzdDwgU2JDbGFzc01vZHVsZU9iamVjdCogPiggcE1vZCk7CglpZiggcENsYXNzTW9kdWxlT2JqZWN0ICkKCQlwTW9kLT5TZXRGbGFnKCBTQlhfR0JMU0VBUkNIICk7CgoJU3RlcEZJTkRfSW1wbCggcE1vZCwgbk9wMSwgbk9wMiwgU2JFUlJfUFJPQ19VTkRFRklORUQsIHNhbF9UcnVlICk7CgoJaWYoIHBDbGFzc01vZHVsZU9iamVjdCApCgkJcE1vZC0+UmVzZXRGbGFnKCBTQlhfR0JMU0VBUkNIICk7Cn0KCnZvaWQgU2JpUnVudGltZTo6U3RlcEZJTkRfU1RBVElDKCBzYWxfdUludDMyIG5PcDEsIHNhbF91SW50MzIgbk9wMiApCnsKCVN0ZXBGSU5EX0ltcGwoIHBNb2QsIG5PcDEsIG5PcDIsIFNiRVJSX1BST0NfVU5ERUZJTkVELCBzYWxfVHJ1ZSwgc2FsX1RydWUgKTsKfQoKLy8gTGFkZW4gZWluZXMgT2JqZWt0LUVsZW1lbnRzICgrU3RyaW5nSUQrVHlwKQovLyBEYXMgT2JqZWt0IGxpZWd0IGF1ZiBUT1MKCnZvaWQgU2JpUnVudGltZTo6U3RlcEVMRU0oIHNhbF91SW50MzIgbk9wMSwgc2FsX3VJbnQzMiBuT3AyICkKewoJLy8gTGllZ3QgYXVmIGRlbSBUT1MgZWluIE9iamVrdD8KCVNieFZhcmlhYmxlUmVmIHBPYmpWYXIgPSBQb3BWYXIoKTsKCglTYnhPYmplY3QqIHBPYmogPSBkeW5hbWljX2Nhc3Q8IFNieE9iamVjdCogPiggKFNieFZhcmlhYmxlKikgcE9ialZhcik7CglpZiggIXBPYmogKQoJewoJCVNieEJhc2UqIHBPYmpWYXJPYmogPSBwT2JqVmFyLT5HZXRPYmplY3QoKTsKCQlwT2JqID0gZHluYW1pY19jYXN0PCBTYnhPYmplY3QqID4oIHBPYmpWYXJPYmopOwoJfQoKCS8vICM1NjM2OCBCZWkgU3RlcEVsZW0gUmVmZXJlbnogc2ljaGVybiwgc29uc3Qga29lbm5lbiBPYmpla3RlCgkvLyBpbiBRdWFsaWZpemllcnVuZ3NrZXR0ZW4gd2llIEFjdGl2ZUNvbXBvbmVudC5TZWxlY3Rpb24oMCkuVGV4dAoJLy8genUgZnVlaCBkaWUgUmVmZXJlbnogdmVybGllcmVuCgkvLyAjNzQyNTQgSmV0enQgcGVyIExpc3RlCglpZiggcE9iaiApCgkJU2F2ZVJlZiggKFNieFZhcmlhYmxlKilwT2JqICk7CgoJUHVzaFZhciggRmluZEVsZW1lbnQoIHBPYmosIG5PcDEsIG5PcDIsIFNiRVJSX05PX01FVEhPRCwgc2FsX0ZhbHNlICkgKTsKfQoKLy8gTGFkZW4gZWluZXMgUGFyYW1ldGVycyAoK09mZnNldCtUeXApCi8vIFdlbm4gZGVyIERhdGVudHlwIG5pY2h0IHN0aW1tZW4gc29sbHRlLCBlaW5lIEtvcGllIGFubGVnZW4KLy8gRGVyIERhdGVudHlwIFNieEVNUFRZIHplaWd0IGFuLCBkYWEga2VpbiBQYXJhbWV0ZXIgYW5nZWdlYmVuIGlzdC4KLy8gR2V0KCAwICkgZGFyZiBFTVBUWSBzZWluCgp2b2lkIFNiaVJ1bnRpbWU6OlN0ZXBQQVJBTSggc2FsX3VJbnQzMiBuT3AxLCBzYWxfdUludDMyIG5PcDIgKQp7CglzYWxfdUludDE2IGkgPSBzdGF0aWNfY2FzdDxzYWxfdUludDE2Piggbk9wMSAmIDB4N0ZGRiApOwoJU2J4RGF0YVR5cGUgdCA9IChTYnhEYXRhVHlwZSkgbk9wMjsKCVNieFZhcmlhYmxlKiBwOwoKCS8vICM1NzkxNSBNaXNzaW5nIHNhdWJlcmVyIGxvZXNlbgoJc2FsX3VJbnQxNiBuUGFyYW1Db3VudCA9IHJlZlBhcmFtcy0+Q291bnQoKTsKCWlmKCBpID49IG5QYXJhbUNvdW50ICkKCXsKCQlzYWxfSW50MTYgaUxvb3AgPSBpOwoJCXdoaWxlKCBpTG9vcCA+PSBuUGFyYW1Db3VudCApCgkJewoJCQlwID0gbmV3IFNieFZhcmlhYmxlKCk7CgoJCQlpZiggU2JpUnVudGltZTo6aXNWQkFFbmFibGVkKCkgJiYKCQkJCSh0ID09IFNieE9CSkVDVCB8fCB0ID09IFNieFNUUklORykgKSAKCQkJewoJCQkJaWYoIHQgPT0gU2J4T0JKRUNUICkKCQkJCQlwLT5QdXRPYmplY3QoIE5VTEwgKTsKCQkJCWVsc2UKCQkJCQlwLT5QdXRTdHJpbmcoIFN0cmluZygpICk7CgkJCX0KCQkJZWxzZQoJCQkJcC0+UHV0RXJyKCA0NDggKTsJCS8vIFdpZSBpbiBWQjogRXJyb3ItQ29kZSA0NDggKFNiRVJSX05BTUVEX05PVF9GT1VORCkKCgkJCXJlZlBhcmFtcy0+UHV0KCBwLCBpTG9vcCApOwoJCQlpTG9vcC0tOwoJCX0KCX0KCXAgPSByZWZQYXJhbXMtPkdldCggaSApOwoKCWlmKCBwLT5HZXRUeXBlKCkgPT0gU2J4RVJST1IgJiYgKCBpICkgKQoJLy9pZiggcC0+R2V0VHlwZSgpID09IFNieEVNUFRZICYmICggaSApICkKCXsKCQkvLyBXZW5uIGVpbiBQYXJhbWV0ZXIgZmVobHQsIGthbm4gZXIgT1BUSU9OQUwgc2VpbgoJCXNhbF9Cb29sIGJPcHQgPSBzYWxfRmFsc2U7CgkJaWYoIHBNZXRoICkKCQl7CiAgICAgICAgICAgIFNieEluZm8qIHBJbmZvID0gcE1ldGgtPkdldEluZm8oKTsKICAgICAgICAgICAgaWYgKCBwSW5mbyApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGNvbnN0IFNieFBhcmFtSW5mbyogcFBhcmFtID0gcEluZm8tPkdldFBhcmFtKCBpICk7CiAgICAgICAgICAgICAgICBpZiggcFBhcmFtICYmICggKHBQYXJhbS0+bkZsYWdzICYgU0JYX09QVElPTkFMKSAhPSAwICkgKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIC8vIERlZmF1bHQgdmFsdWU/CiAgICAgICAgICAgICAgICAgICAgc2FsX3VJbnQxNiBuRGVmYXVsdElkID0gc2FsOjpzdGF0aWNfaW50X2Nhc3Q8IHNhbF91SW50MTYgPigKICAgICAgICAgICAgICAgICAgICAgICAgcFBhcmFtLT5uVXNlckRhdGEgJiAweGZmZmYgKTsKICAgICAgICAgICAgICAgICAgICBpZiggbkRlZmF1bHRJZCA+IDAgKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgU3RyaW5nIGFEZWZhdWx0U3RyID0gcEltZy0+R2V0U3RyaW5nKCBuRGVmYXVsdElkICk7CiAgICAgICAgICAgICAgICAgICAgICAgIHAgPSBuZXcgU2J4VmFyaWFibGUoKTsKICAgICAgICAgICAgICAgICAgICAgICAgcC0+UHV0U3RyaW5nKCBhRGVmYXVsdFN0ciApOwogICAgICAgICAgICAgICAgICAgICAgICByZWZQYXJhbXMtPlB1dCggcCwgaSApOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBiT3B0ID0gc2FsX1RydWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCQl9CgkJaWYoIGJPcHQgPT0gc2FsX0ZhbHNlICkKCQkJRXJyb3IoIFNiRVJSX05PVF9PUFRJT05BTCApOwoJfQoJZWxzZSBpZiggdCAhPSBTYnhWQVJJQU5UICYmIChTYnhEYXRhVHlwZSkocC0+R2V0VHlwZSgpICYgMHgwRkZGICkgIT0gdCApCgl7CgkJU2J4VmFyaWFibGUqIHEgPSBuZXcgU2J4VmFyaWFibGUoIHQgKTsKCQlTYXZlUmVmKCBxICk7CgkJKnEgPSAqcDsKCQlwID0gcTsKCX0KCVNldHVwQXJncyggcCwgbk9wMSApOwoJUHVzaFZhciggQ2hlY2tBcnJheSggcCApICk7Cn0KCi8vIENhc2UtVGVzdCAoK1RydWUtVGFyZ2V0K1Rlc3QtT3Bjb2RlKQoKdm9pZCBTYmlSdW50aW1lOjpTdGVwQ0FTRUlTKCBzYWxfdUludDMyIG5PcDEsIHNhbF91SW50MzIgbk9wMiApCnsKCWlmKCAhcmVmQ2FzZVN0ayB8fCAhcmVmQ2FzZVN0ay0+Q291bnQoKSApCgkJU3RhckJBU0lDOjpGYXRhbEVycm9yKCBTYkVSUl9JTlRFUk5BTF9FUlJPUiApOwoJZWxzZQoJewoJCVNieFZhcmlhYmxlUmVmIHhDb21wID0gUG9wVmFyKCk7CgkJU2J4VmFyaWFibGVSZWYgeENhc2UgPSByZWZDYXNlU3RrLT5HZXQoIHJlZkNhc2VTdGstPkNvdW50KCkgLSAxICk7CgkJaWYoIHhDYXNlLT5Db21wYXJlKCAoU2J4T3BlcmF0b3IpIG5PcDIsICp4Q29tcCApICkKCQkJU3RlcEpVTVAoIG5PcDEgKTsKCX0KfQoKLy8gQXVmcnVmIGVpbmVyIERMTC1Qcm96ZWR1ciAoK1N0cmluZ0lEK1R5cCkKLy8gQXVjaCBoaWVyIHplaWd0IGRhcyBNU0IgZGVzIFN0cmluZ0lEcyBhbiwgZGFzcyBBcmd2IGJlbGVndCBpc3QKCnZvaWQgU2JpUnVudGltZTo6U3RlcENBTEwoIHNhbF91SW50MzIgbk9wMSwgc2FsX3VJbnQzMiBuT3AyICkKewoJU3RyaW5nIGFOYW1lID0gcEltZy0+R2V0U3RyaW5nKCBzdGF0aWNfY2FzdDxzaG9ydD4oIG5PcDEgJiAweDdGRkYgKSApOwoJU2J4QXJyYXkqIHBBcmdzID0gTlVMTDsKCWlmKCBuT3AxICYgMHg4MDAwICkKCQlwQXJncyA9IHJlZkFyZ3Y7CglEbGxDYWxsKCBhTmFtZSwgYUxpYk5hbWUsIHBBcmdzLCAoU2J4RGF0YVR5cGUpIG5PcDIsIHNhbF9GYWxzZSApOwoJYUxpYk5hbWUgPSBTdHJpbmcoKTsKCWlmKCBuT3AxICYgMHg4MDAwICkKCQlQb3BBcmd2KCk7Cn0KCi8vIEF1ZnJ1ZiBlaW5lciBETEwtUHJvemVkdXIgbmFjaCBDRGVjbCAoK1N0cmluZ0lEK1R5cCkKLy8gQXVjaCBoaWVyIHplaWd0IGRhcyBNU0IgZGVzIFN0cmluZ0lEcyBhbiwgZGFzcyBBcmd2IGJlbGVndCBpc3QKCnZvaWQgU2JpUnVudGltZTo6U3RlcENBTExDKCBzYWxfdUludDMyIG5PcDEsIHNhbF91SW50MzIgbk9wMiApCnsKCVN0cmluZyBhTmFtZSA9IHBJbWctPkdldFN0cmluZyggc3RhdGljX2Nhc3Q8c2hvcnQ+KCBuT3AxICYgMHg3RkZGICkgKTsKCVNieEFycmF5KiBwQXJncyA9IE5VTEw7CglpZiggbk9wMSAmIDB4ODAwMCApCgkJcEFyZ3MgPSByZWZBcmd2OwoJRGxsQ2FsbCggYU5hbWUsIGFMaWJOYW1lLCBwQXJncywgKFNieERhdGFUeXBlKSBuT3AyLCBzYWxfVHJ1ZSApOwoJYUxpYk5hbWUgPSBTdHJpbmcoKTsKCWlmKCBuT3AxICYgMHg4MDAwICkKCQlQb3BBcmd2KCk7Cn0KCgovLyBCZWdpbm4gZWluZXMgU3RhdGVtZW50cyAoK0xpbmUrQ29sKQoKdm9pZCBTYmlSdW50aW1lOjpTdGVwU1RNTlQoIHNhbF91SW50MzIgbk9wMSwgc2FsX3VJbnQzMiBuT3AyICkKewoJLy8gV2VubiBkZXIgRXhwci1TdGFjayBhbSBBbmZhbmcgZWluZW4gU3RhdGVtZW50cyBlaW5lIFZhcmlhYmxlIGVudGhhZWx0LAoJLy8gaGF0IGVpbiBUcm90dGVsIFggYWxzIEZ1bmt0aW9uIGF1ZmdlcnVmZW4sIG9id29obCBlcyBlaW5lIFZhcmlhYmxlIGlzdCEKCXNhbF9Cb29sIGJGYXRhbEV4cHIgPSBzYWxfRmFsc2U7CiAgICBTdHJpbmcgc1Vua25vd25NZXRob2ROYW1lOwoJaWYoIG5FeHByTHZsID4gMSApCgkJYkZhdGFsRXhwciA9IHNhbF9UcnVlOwoJZWxzZSBpZiggbkV4cHJMdmwgKQoJewoJCVNieFZhcmlhYmxlKiBwID0gcmVmRXhwclN0ay0+R2V0KCAwICk7CgkJaWYoIHAtPkdldFJlZkNvdW50KCkgPiAxCgkJICYmIHJlZkxvY2Fscy5JcygpICYmIHJlZkxvY2Fscy0+RmluZCggcC0+R2V0TmFtZSgpLCBwLT5HZXRDbGFzcygpICkgKQogICAgICAgIHsKICAgICAgICAgICAgc1Vua25vd25NZXRob2ROYW1lID0gcC0+R2V0TmFtZSgpOwoJCQliRmF0YWxFeHByID0gc2FsX1RydWU7CiAgICAgICAgfQoJfQoJLy8gRGVyIEV4cHItU3RhY2sgaXN0IG51biBuaWNodCBtZWhyIG5vdHdlbmRpZwoJQ2xlYXJFeHByU3RhY2soKTsKCgkvLyAjNTYzNjggS3VlbnN0bGljaGUgUmVmZXJlbnogZnVlciBTdGVwRWxlbSB3aWVkZXIgZnJlaWdlYmVuLAoJLy8gZGFtaXQgc2llIG5pY2h0IHVlYmVyIGVpbiBTdGF0ZW1lbnQgaGluYXVzIGVyaGFsdGVuIGJsZWlidAoJLy9yZWZTYXZlT2JqID0gTlVMTDsKCS8vICM3NDI1NCBKZXR6dCBwZXIgTGlzdGUKCUNsZWFyUmVmcygpOwoKCS8vIFdpciBtdWVzc2VuIGhpZXIgaGFydCBhYmJyZWNoZW4sIGRhIHNvbnN0IFplaWxlIHVuZCBTcGFsdGUgbmljaHQgbWVocgoJLy8gc3RpbW1lbiEKCWlmKCBiRmF0YWxFeHByKQoJewoJCVN0YXJCQVNJQzo6RmF0YWxFcnJvciggU2JFUlJfTk9fTUVUSE9ELCBzVW5rbm93bk1ldGhvZE5hbWUgKTsKCQlyZXR1cm47Cgl9CglwU3RtbnQgPSBwQ29kZSAtIDk7CglzYWxfdUludDE2IG5PbGQgPSBuTGluZTsKCW5MaW5lID0gc3RhdGljX2Nhc3Q8c2hvcnQ+KCBuT3AxICk7CgoJLy8gIzI5OTU1ICYgMHhGRiwgdW0gZm9yLVNjaGxlaWZlbi1FYmVuZSB3ZWd6dWZpbHRlcm4KCW5Db2wxID0gc3RhdGljX2Nhc3Q8c2hvcnQ+KCBuT3AyICYgMHhGRiApOwoKCS8vIFN1Y2hlbiBkZXMgbmFlY2hzdGVuIFNUTU5ULUJlZmVobHMsCgkvLyB1bSBkaWUgRW5kLVNwYWx0ZSBkaWVzZXMgU3RhdGVtZW50cyB6dSBzZXR6ZW4KCS8vIFNlYXJjaGVzIG9mIHRoZSBuZXh0IFNUTU5UIGluc3RydWN0aW9uLAoJLy8gYXJvdW5kIHRoZSBmaW5hbCBjb2x1bW4gb2YgdGhpcyBzdGF0ZW1lbnQgdG8gc2V0CgoJbkNvbDIgPSAweGZmZmY7CglzYWxfdUludDE2IG4xLCBuMjsKCWNvbnN0IHNhbF91SW50OCogcCA9IHBNb2QtPkZpbmROZXh0U3RtbnQoIHBDb2RlLCBuMSwgbjIgKTsKCWlmKCBwICkKCXsKCQlpZiggbjEgPT0gbk9wMSApCgkJewoJCQkvLyAjMjk5NTUgJiAweEZGLCB1bSBmb3ItU2NobGVpZmVuLUViZW5lIHdlZ3p1ZmlsdGVybgoJCQluQ29sMiA9IChuMiAmIDB4RkYpIC0gMTsKCQl9Cgl9CgoJLy8gIzI5OTU1IGZvci1TY2hsZWlmZW4tRWJlbmUga29ycmlnaWVyZW4sICM2NzQ1MiBOSUNIVCBpbSBFcnJvci1IYW5kbGVyIHNvbnN0IENoYW9zCglpZiggIWJJbkVycm9yICkKCXsKCQkvLyAoQmVpIFNwcvxuZ2VuIGF1cyBTY2hsZWlmZW4gdHJpdHQgaGllciBlaW5lIERpZmZlcmVueiBhdWYpCgkJc2FsX3VJbnQxNiBuRXhzcGVjdGVkRm9yTGV2ZWwgPSBzdGF0aWNfY2FzdDxzYWxfdUludDE2Piggbk9wMiAvIDB4MTAwICk7CgkJaWYoIHBHb3N1YlN0ayApCgkJCW5FeHNwZWN0ZWRGb3JMZXZlbCA9IG5FeHNwZWN0ZWRGb3JMZXZlbCArIHBHb3N1YlN0ay0+blN0YXJ0Rm9yTHZsOwoKCQkvLyBXZW5uIGRlciB0YXRzYWVjaGxpY2hlIEZvci1MZXZlbCB6dSBrbGVpbiBpc3QsIHd1cmRlIGF1cwoJCS8vIGVpbmVyIFNjaGxlaWZlIGhlcmF1cyBnZXNwcnVuZ2VuIC0+IGtvcnJpZ2llcmVuCgkJd2hpbGUoIG5Gb3JMdmwgPiBuRXhzcGVjdGVkRm9yTGV2ZWwgKQoJCQlQb3BGb3IoKTsKCX0KCgkvLyAxNi4xMC45NjogIzMxNDYwIE5ldWVzIEtvbnplcHQgZnVlciBTdGVwSW50by9PdmVyL091dAoJLy8gRXJrbORydW5nIHNpZWhlIGJlaSBfSW1wbEdldEJyZWFrQ2FsbExldmVsLgoJaWYoIHBJbnN0LT5uQ2FsbEx2bCA8PSBwSW5zdC0+bkJyZWFrQ2FsbEx2bCApCgkvL2lmKCBuRmxhZ3MgJiBTYkRFQlVHX1NURVBJTlRPICkKCXsKCQlTdGFyQkFTSUMqIHBTdGVwQmFzaWMgPSBHZXRDdXJyZW50QmFzaWMoICZyQmFzaWMgKTsKCQlzYWxfdUludDE2IG5OZXdGbGFncyA9IHBTdGVwQmFzaWMtPlN0ZXBQb2ludCggbkxpbmUsIG5Db2wxLCBuQ29sMiApOwoKCQkvLyBOZXVlbiBCcmVha0NhbGxMZXZlbCBlcm1pdHRlbG4KCQlwSW5zdC0+Q2FsY0JyZWFrQ2FsbExldmVsKCBuTmV3RmxhZ3MgKTsKCX0KCgkvLyBCcmVha3BvaW50cyBudXIgYmVpIFNUTU5ULUJlZmVobGVuIGluIG5ldWVyIFplaWxlIQoJZWxzZSBpZiggKCBuT3AxICE9IG5PbGQgKQoJCSYmICggbkZsYWdzICYgU2JERUJVR19CUkVBSyApCgkJJiYgcE1vZC0+SXNCUCggc3RhdGljX2Nhc3Q8c2FsX3VJbnQxNj4oIG5PcDEgKSApICkKCXsKCQlTdGFyQkFTSUMqIHBCcmVha0Jhc2ljID0gR2V0Q3VycmVudEJhc2ljKCAmckJhc2ljICk7CgkJc2FsX3VJbnQxNiBuTmV3RmxhZ3MgPSBwQnJlYWtCYXNpYy0+QnJlYWtQb2ludCggbkxpbmUsIG5Db2wxLCBuQ29sMiApOwoKCQkvLyBOZXVlbiBCcmVha0NhbGxMZXZlbCBlcm1pdHRlbG4KCQlwSW5zdC0+Q2FsY0JyZWFrQ2FsbExldmVsKCBuTmV3RmxhZ3MgKTsKCQkvLzE2LjEwLjk2LCBBTFQ6CgkJLy9pZiggbk5ld0ZsYWdzICE9IFNiREVCVUdfQ09OVElOVUUgKQoJCS8vCW5GbGFncyA9IG5OZXdGbGFnczsKCX0KfQoKLy8gKCtTdlN0cmVhbUZsYWdzK0ZsYWdzKQovLyBTdGFjazogQmxvY2tsYWVuZ2UKLy8gICAgICAgIEthbmFsbnVtbWVyCi8vICAgICAgICBEYXRlaW5hbWUKCnZvaWQgU2JpUnVudGltZTo6U3RlcE9QRU4oIHNhbF91SW50MzIgbk9wMSwgc2FsX3VJbnQzMiBuT3AyICkKewoJU2J4VmFyaWFibGVSZWYgcE5hbWUgPSBQb3BWYXIoKTsKCVNieFZhcmlhYmxlUmVmIHBDaGFuID0gUG9wVmFyKCk7CglTYnhWYXJpYWJsZVJlZiBwTGVuICA9IFBvcFZhcigpOwoJc2hvcnQgbkJsa0xlbiA9IHBMZW4tPkdldEludGVnZXIoKTsKCXNob3J0IG5DaGFuICAgPSBwQ2hhbi0+R2V0SW50ZWdlcigpOwoJQnl0ZVN0cmluZyBhTmFtZSggcE5hbWUtPkdldFN0cmluZygpLCBnc2xfZ2V0U3lzdGVtVGV4dEVuY29kaW5nKCkgKTsKCXBJb3N5cy0+T3BlbiggbkNoYW4sIGFOYW1lLCBzdGF0aWNfY2FzdDxzaG9ydD4oIG5PcDEgKSwKCQlzdGF0aWNfY2FzdDxzaG9ydD4oIG5PcDIgKSwgbkJsa0xlbiApOwoJRXJyb3IoIHBJb3N5cy0+R2V0RXJyb3IoKSApOwp9CgovLyBPYmpla3Qga3JlaWVyZW4gKCtTdHJpbmdJRCtTdHJpbmdJRCkKCnZvaWQgU2JpUnVudGltZTo6U3RlcENSRUFURSggc2FsX3VJbnQzMiBuT3AxLCBzYWxfdUludDMyIG5PcDIgKQp7CglTdHJpbmcgYUNsYXNzKCBwSW1nLT5HZXRTdHJpbmcoIHN0YXRpY19jYXN0PHNob3J0Piggbk9wMiApICkgKTsKCVNieE9iamVjdCAqcE9iaiA9IFNieEJhc2U6OkNyZWF0ZU9iamVjdCggYUNsYXNzICk7CglpZiggIXBPYmogKQoJCUVycm9yKCBTYkVSUl9JTlZBTElEX09CSkVDVCApOwoJZWxzZQoJewoJCVN0cmluZyBhTmFtZSggcEltZy0+R2V0U3RyaW5nKCBzdGF0aWNfY2FzdDxzaG9ydD4oIG5PcDEgKSApICk7CgkJcE9iai0+U2V0TmFtZSggYU5hbWUgKTsKCS8vIERhcyBPYmpla3QgbXVzcyBCQVNJQyBydWZlbiBrb2VubmVuCgkJcE9iai0+U2V0UGFyZW50KCAmckJhc2ljICk7CgkJU2J4VmFyaWFibGUqIHBOZXcgPSBuZXcgU2J4VmFyaWFibGU7CgkJcE5ldy0+UHV0T2JqZWN0KCBwT2JqICk7CgkJUHVzaFZhciggcE5ldyApOwoJfQp9Cgp2b2lkIFNiaVJ1bnRpbWU6OlN0ZXBEQ1JFQVRFKCBzYWxfdUludDMyIG5PcDEsIHNhbF91SW50MzIgbk9wMiApCnsKICAgIFN0ZXBEQ1JFQVRFX0lNUEwoIG5PcDEsIG5PcDIgKTsKfQoKdm9pZCBTYmlSdW50aW1lOjpTdGVwRENSRUFURV9SRURJTVAoIHNhbF91SW50MzIgbk9wMSwgc2FsX3VJbnQzMiBuT3AyICkKewogICAgU3RlcERDUkVBVEVfSU1QTCggbk9wMSwgbk9wMiApOwp9CgoKLy8gSGVscGVyIGZ1bmN0aW9uIGZvciBTdGVwRENSRUFURV9JTVBMIC8gYlJlZGltcCA9IHRydWUKdm9pZCBpbXBsQ29weURpbUFycmF5X0RDUkVBVEUoIFNieERpbUFycmF5KiBwTmV3QXJyYXksIFNieERpbUFycmF5KiBwT2xkQXJyYXksIHNob3J0IG5NYXhEaW1JbmRleCwKCXNob3J0IG5BY3R1YWxEaW0sIHNhbF9JbnQzMiogcEFjdHVhbEluZGljZXMsIHNhbF9JbnQzMiogcExvd2VyQm91bmRzLCBzYWxfSW50MzIqIHBVcHBlckJvdW5kcyApCnsKCXNhbF9JbnQzMiYgcmkgPSBwQWN0dWFsSW5kaWNlc1tuQWN0dWFsRGltXTsKCWZvciggcmkgPSBwTG93ZXJCb3VuZHNbbkFjdHVhbERpbV0gOyByaSA8PSBwVXBwZXJCb3VuZHNbbkFjdHVhbERpbV0gOyByaSsrICkKCXsKCQlpZiggbkFjdHVhbERpbSA8IG5NYXhEaW1JbmRleCApCgkJewoJCQlpbXBsQ29weURpbUFycmF5X0RDUkVBVEUoIHBOZXdBcnJheSwgcE9sZEFycmF5LCBuTWF4RGltSW5kZXgsIG5BY3R1YWxEaW0gKyAxLAoJCQkJcEFjdHVhbEluZGljZXMsIHBMb3dlckJvdW5kcywgcFVwcGVyQm91bmRzICk7CgkJfQoJCWVsc2UKCQl7CgkJCVNieFZhcmlhYmxlKiBwU291cmNlID0gcE9sZEFycmF5LT5HZXQzMiggcEFjdHVhbEluZGljZXMgKTsKICAgICAgICAgICAgcE5ld0FycmF5LT5QdXQzMiggcFNvdXJjZSwgcEFjdHVhbEluZGljZXMgKTsKCQl9Cgl9Cn0KCi8vICM1NjIwNCBPYmpla3QtQXJyYXkga3JlaWVyZW4gKCtTdHJpbmdJRCtTdHJpbmdJRCksIERDUkVBVEUgPT0gRGltLUNyZWF0ZQp2b2lkIFNiaVJ1bnRpbWU6OlN0ZXBEQ1JFQVRFX0lNUEwoIHNhbF91SW50MzIgbk9wMSwgc2FsX3VJbnQzMiBuT3AyICkKewoJU2J4VmFyaWFibGVSZWYgcmVmVmFyID0gUG9wVmFyKCk7CgoJRGltSW1wbCggcmVmVmFyICk7CgoJLy8gRGFzIEFycmF5IG1pdCBJbnN0YW56ZW4gZGVyIGdlZm9yZGVydGVuIEtsYXNzZSBmdWVsbGVuCglTYnhCYXNlUmVmIHhPYmogPSAoU2J4QmFzZSopcmVmVmFyLT5HZXRPYmplY3QoKTsKCWlmKCAheE9iaiApCgl7CgkJU3RhckJBU0lDOjpFcnJvciggU2JFUlJfSU5WQUxJRF9PQkpFQ1QgKTsKCQlyZXR1cm47Cgl9CgogICAgU2J4RGltQXJyYXkqIHBBcnJheSA9IGR5bmFtaWNfY2FzdDwgU2J4RGltQXJyYXkqID4oKFNieEJhc2UqKXhPYmopOwoKCWlmKCBwQXJyYXkgKQoJewoJCS8vIERpbWVuc2lvbmVuIGF1c3dlcnRlbgoJCXNob3J0IG5EaW1zID0gcEFycmF5LT5HZXREaW1zKCk7CgkJc2FsX0ludDMyIG5Ub3RhbFNpemUgPSAwOwoKCQkvLyBlcyBtdXNzIGVpbiBlaW5kaW1lbnNpb25hbGVzIEFycmF5IHNlaW4KCQlzYWxfSW50MzIgbkxvd2VyLCBuVXBwZXIsIG5TaXplOwoJCXNhbF9JbnQzMiBpOwoJCWZvciggaSA9IDAgOyBpIDwgbkRpbXMgOyBpKysgKQoJCXsKCQkJcEFycmF5LT5HZXREaW0zMiggaSsxLCBuTG93ZXIsIG5VcHBlciApOwoJCQluU2l6ZSA9IG5VcHBlciAtIG5Mb3dlciArIDE7CgkJCWlmKCBpID09IDAgKQoJCQkJblRvdGFsU2l6ZSA9IG5TaXplOwoJCQllbHNlCgkJCQluVG90YWxTaXplICo9IG5TaXplOwoJCX0KCgkJLy8gT2JqZWt0ZSBhbmxlZ2VuIHVuZCBpbnMgQXJyYXkgZWludHJhZ2VuCgkJU3RyaW5nIGFDbGFzcyggcEltZy0+R2V0U3RyaW5nKCBzdGF0aWNfY2FzdDxzaG9ydD4oIG5PcDIgKSApICk7CgkJZm9yKCBpID0gMCA7IGkgPCBuVG90YWxTaXplIDsgaSsrICkKCQl7CgkJCVNieE9iamVjdCAqcENsYXNzT2JqID0gU2J4QmFzZTo6Q3JlYXRlT2JqZWN0KCBhQ2xhc3MgKTsKCQkJaWYoICFwQ2xhc3NPYmogKQoJCQl7CgkJCQlFcnJvciggU2JFUlJfSU5WQUxJRF9PQkpFQ1QgKTsKCQkJCWJyZWFrOwoJCQl9CgkJCWVsc2UKCQkJewoJCQkJU3RyaW5nIGFOYW1lKCBwSW1nLT5HZXRTdHJpbmcoIHN0YXRpY19jYXN0PHNob3J0Piggbk9wMSApICkgKTsKCQkJCXBDbGFzc09iai0+U2V0TmFtZSggYU5hbWUgKTsKCQkJCS8vIERhcyBPYmpla3QgbXVzcyBCQVNJQyBydWZlbiBrb2VubmVuCgkJCQlwQ2xhc3NPYmotPlNldFBhcmVudCggJnJCYXNpYyApOwoJCQkJcEFycmF5LT5TYnhBcnJheTo6UHV0MzIoIHBDbGFzc09iaiwgaSApOwoJCQl9CgkJfQoJfQoKCVNieERpbUFycmF5KiBwT2xkQXJyYXkgPSAoU2J4RGltQXJyYXkqKShTYnhBcnJheSopcmVmUmVkaW1wQXJyYXk7CglpZiggcEFycmF5ICYmIHBPbGRBcnJheSApCgl7CgkJc2hvcnQgbkRpbXNOZXcgPSBwQXJyYXktPkdldERpbXMoKTsKCQlzaG9ydCBuRGltc09sZCA9IHBPbGRBcnJheS0+R2V0RGltcygpOwoJCXNob3J0IG5EaW1zID0gbkRpbXNOZXc7CgkJc2FsX0Jvb2wgYlJhbmdlRXJyb3IgPSBzYWxfRmFsc2U7CgoJCS8vIFN0b3JlIGRpbXMgdG8gdXNlIHRoZW0gZm9yIGNvcHlpbmcgbGF0ZXIKCQlzYWxfSW50MzIqIHBMb3dlckJvdW5kcyA9IG5ldyBzYWxfSW50MzJbbkRpbXNdOwoJCXNhbF9JbnQzMiogcFVwcGVyQm91bmRzID0gbmV3IHNhbF9JbnQzMltuRGltc107CgkJc2FsX0ludDMyKiBwQWN0dWFsSW5kaWNlcyA9IG5ldyBzYWxfSW50MzJbbkRpbXNdOwoJCWlmKCBuRGltc09sZCAhPSBuRGltc05ldyApCgkJewoJCQliUmFuZ2VFcnJvciA9IHNhbF9UcnVlOwoJCX0KCQllbHNlCgkJewoJCQkvLyBDb21wYXJlIGJvdW5kcwoJCQlmb3IoIHNob3J0IGkgPSAxIDsgaSA8PSBuRGltcyA7IGkrKyApCgkJCXsKCQkJCXNhbF9JbnQzMiBsQm91bmROZXcsIHVCb3VuZE5ldzsKCQkJCXNhbF9JbnQzMiBsQm91bmRPbGQsIHVCb3VuZE9sZDsKCQkJCXBBcnJheS0+R2V0RGltMzIoIGksIGxCb3VuZE5ldywgdUJvdW5kTmV3ICk7CgkJCQlwT2xkQXJyYXktPkdldERpbTMyKCBpLCBsQm91bmRPbGQsIHVCb3VuZE9sZCApOwoKCQkJCWxCb3VuZE5ldyA9IHN0ZDo6bWF4KCBsQm91bmROZXcsIGxCb3VuZE9sZCApOwoJCQkJdUJvdW5kTmV3ID0gc3RkOjptaW4oIHVCb3VuZE5ldywgdUJvdW5kT2xkICk7CgkJCQlzaG9ydCBqID0gaSAtIDE7CgkJCQlwQWN0dWFsSW5kaWNlc1tqXSA9IHBMb3dlckJvdW5kc1tqXSA9IGxCb3VuZE5ldzsKCQkJCXBVcHBlckJvdW5kc1tqXSA9IHVCb3VuZE5ldzsKCQkJfQoJCX0KCgkJaWYoIGJSYW5nZUVycm9yICkKCQl7CgkJCVN0YXJCQVNJQzo6RXJyb3IoIFNiRVJSX09VVF9PRl9SQU5HRSApOwoJCX0KCQllbHNlCgkJewoJCQkvLyBDb3B5IGRhdGEgZnJvbSBvbGQgYXJyYXkgYnkgZ29pbmcgcmVjdXJzaXZlbHkgdGhyb3VnaCBhbGwgZGltZW5zaW9ucwoJCQkvLyAoSXQgd291bGQgYmUgZmFzdGVyIHRvIHdvcmsgb24gdGhlIGZsYXQgaW50ZXJuYWwgZGF0YSBhcnJheSBvZiBhbgoJCQkvLyBTYnlBcnJheSBidXQgdGhpcyBzb2x1dGlvbiBpcyBjbGVhcmVyIGFuZCBlYXNpZXIpCgkJCWltcGxDb3B5RGltQXJyYXlfRENSRUFURSggcEFycmF5LCBwT2xkQXJyYXksIG5EaW1zIC0gMSwKCQkJCTAsIHBBY3R1YWxJbmRpY2VzLCBwTG93ZXJCb3VuZHMsIHBVcHBlckJvdW5kcyApOwoJCX0KCQlkZWxldGUgW10gcFVwcGVyQm91bmRzOwoJCWRlbGV0ZSBbXSBwTG93ZXJCb3VuZHM7CgkJZGVsZXRlIFtdIHBBY3R1YWxJbmRpY2VzOwoJCXJlZlJlZGltcEFycmF5ID0gTlVMTDsKICAgIH0KfQoKLy8gT2JqZWt0IGF1cyBVc2VyLVR5cGUga3JlaWVyZW4gICgrU3RyaW5nSUQrU3RyaW5nSUQpCgpTYnhPYmplY3QqIGNyZWF0ZVVzZXJUeXBlSW1wbCggY29uc3QgU3RyaW5nJiByQ2xhc3NOYW1lICk7CS8vIHNiLmN4eAoKdm9pZCBTYmlSdW50aW1lOjpTdGVwVENSRUFURSggc2FsX3VJbnQzMiBuT3AxLCBzYWxfdUludDMyIG5PcDIgKQp7CglTdHJpbmcgYU5hbWUoIHBJbWctPkdldFN0cmluZyggc3RhdGljX2Nhc3Q8c2hvcnQ+KCBuT3AxICkgKSApOwoJU3RyaW5nIGFDbGFzcyggcEltZy0+R2V0U3RyaW5nKCBzdGF0aWNfY2FzdDxzaG9ydD4oIG5PcDIgKSApICk7CgoJU2J4T2JqZWN0KiBwQ29weU9iaiA9IGNyZWF0ZVVzZXJUeXBlSW1wbCggYUNsYXNzICk7CglpZiggcENvcHlPYmogKQoJCXBDb3B5T2JqLT5TZXROYW1lKCBhTmFtZSApOwoJU2J4VmFyaWFibGUqIHBOZXcgPSBuZXcgU2J4VmFyaWFibGU7CglwTmV3LT5QdXRPYmplY3QoIHBDb3B5T2JqICk7CglwTmV3LT5TZXREZWNsYXJlQ2xhc3NOYW1lKCBhQ2xhc3MgKTsKCVB1c2hWYXIoIHBOZXcgKTsKfQoKdm9pZCBTYmlSdW50aW1lOjppbXBsSGFuZGxlU2J4RmxhZ3MoIFNieFZhcmlhYmxlKiBwVmFyLCBTYnhEYXRhVHlwZSB0LCBzYWxfdUludDMyIG5PcDIgKQp7Cglib29sIGJXaXRoRXZlbnRzID0gKCh0ICYgMHhmZikgPT0gU2J4T0JKRUNUICYmIChuT3AyICYgU0JYX1RZUEVfV0lUSF9FVkVOVFNfRkxBRykgIT0gMCk7CglpZiggYldpdGhFdmVudHMgKQoJCXBWYXItPlNldEZsYWcoIFNCWF9XSVRIX0VWRU5UUyApOwoKCWJvb2wgYkRpbUFzTmV3ID0gKChuT3AyICYgU0JYX1RZUEVfRElNX0FTX05FV19GTEFHKSAhPSAwKTsKCWlmKCBiRGltQXNOZXcgKQoJCXBWYXItPlNldEZsYWcoIFNCWF9ESU1fQVNfTkVXICk7CgoJYm9vbCBiRml4ZWRTdHJpbmcgPSAoKHQgJiAweGZmKSA9PSBTYnhTVFJJTkcgJiYgKG5PcDIgJiBTQlhfRklYRURfTEVOX1NUUklOR19GTEFHKSAhPSAwKTsKCWlmKCBiRml4ZWRTdHJpbmcgKQoJewoJCXNhbF91SW50MTYgbkNvdW50ID0gc3RhdGljX2Nhc3Q8c2FsX3VJbnQxNj4oIG5PcDIgPj4gMTcgKTsJCS8vIGxlbiA9IGFsbCBiaXRzIGFib3ZlIDB4MTAwMDAKCQlTdHJpbmcgYVN0cjsKCQlhU3RyLkZpbGwoIG5Db3VudCwgMCApOwoJCXBWYXItPlB1dFN0cmluZyggYVN0ciApOwoJfQoKCWJvb2wgYlZhclRvRGltID0gKChuT3AyICYgU0JYX1RZUEVfVkFSX1RPX0RJTV9GTEFHKSAhPSAwKTsKCWlmKCBiVmFyVG9EaW0gKQoJCXBWYXItPlNldEZsYWcoIFNCWF9WQVJfVE9fRElNICk7Cn0KCi8vIEVpbnJpY2h0ZW4gZWluZXIgbG9rYWxlbiBWYXJpYWJsZW4gKCtTdHJpbmdJRCtUeXApCgp2b2lkIFNiaVJ1bnRpbWU6OlN0ZXBMT0NBTCggc2FsX3VJbnQzMiBuT3AxLCBzYWxfdUludDMyIG5PcDIgKQp7CglpZiggIXJlZkxvY2Fscy5JcygpICkKCQlyZWZMb2NhbHMgPSBuZXcgU2J4QXJyYXk7CglTdHJpbmcgYU5hbWUoIHBJbWctPkdldFN0cmluZyggc3RhdGljX2Nhc3Q8c2hvcnQ+KCBuT3AxICkgKSApOwoJaWYoIHJlZkxvY2Fscy0+RmluZCggYU5hbWUsIFNieENMQVNTX0RPTlRDQVJFICkgPT0gTlVMTCApCgl7CgkJU2J4RGF0YVR5cGUgdCA9IChTYnhEYXRhVHlwZSkobk9wMiAmIDB4ZmZmZik7CgkJU2J4VmFyaWFibGUqIHAgPSBuZXcgU2J4VmFyaWFibGUoIHQgKTsKCQlwLT5TZXROYW1lKCBhTmFtZSApOwoJCWltcGxIYW5kbGVTYnhGbGFncyggcCwgdCwgbk9wMiApOwoJCXJlZkxvY2Fscy0+UHV0KCBwLCByZWZMb2NhbHMtPkNvdW50KCkgKTsKCX0KfQoKLy8gRWlucmljaHRlbiBlaW5lciBtb2R1bGdsb2JhbGVuIFZhcmlhYmxlbiAoK1N0cmluZ0lEK1R5cCkKCnZvaWQgU2JpUnVudGltZTo6U3RlcFBVQkxJQ19JbXBsKCBzYWxfdUludDMyIG5PcDEsIHNhbF91SW50MzIgbk9wMiwgYm9vbCBiVXNlZEZvckNsYXNzTW9kdWxlICkKewoJU3RyaW5nIGFOYW1lKCBwSW1nLT5HZXRTdHJpbmcoIHN0YXRpY19jYXN0PHNob3J0Piggbk9wMSApICkgKTsKCVNieERhdGFUeXBlIHQgPSAoU2J4RGF0YVR5cGUpKFNieERhdGFUeXBlKShuT3AyICYgMHhmZmZmKTs7CglzYWxfQm9vbCBiRmxhZyA9IHBNb2QtPklzU2V0KCBTQlhfTk9fTU9ESUZZICk7CglwTW9kLT5TZXRGbGFnKCBTQlhfTk9fTU9ESUZZICk7CglTYnhWYXJpYWJsZVJlZiBwID0gcE1vZC0+RmluZCggYU5hbWUsIFNieENMQVNTX1BST1BFUlRZICk7CglpZiggcC5JcygpICkKCQlwTW9kLT5SZW1vdmUgKHApOwoJU2JQcm9wZXJ0eSogcFByb3AgPSBwTW9kLT5HZXRQcm9wZXJ0eSggYU5hbWUsIHQgKTsKCWlmKCAhYlVzZWRGb3JDbGFzc01vZHVsZSApCgkJcFByb3AtPlNldEZsYWcoIFNCWF9QUklWQVRFICk7CglpZiggIWJGbGFnICkKCQlwTW9kLT5SZXNldEZsYWcoIFNCWF9OT19NT0RJRlkgKTsKCWlmKCBwUHJvcCApCgl7CgkJcFByb3AtPlNldEZsYWcoIFNCWF9ET05UU1RPUkUgKTsKCQkvLyBBQjogMi43LjE5OTY6IEhBQ0sgd2VnZW4gJ1JlZmVyZW56IGthbm4gbmljaHQgZ2VzaWNoZXJ0IHdlcmRlbicKCQlwUHJvcC0+U2V0RmxhZyggU0JYX05PX01PRElGWSk7CgoJCWltcGxIYW5kbGVTYnhGbGFncyggcFByb3AsIHQsIG5PcDIgKTsKCX0KfQoKdm9pZCBTYmlSdW50aW1lOjpTdGVwUFVCTElDKCBzYWxfdUludDMyIG5PcDEsIHNhbF91SW50MzIgbk9wMiApCnsKCVN0ZXBQVUJMSUNfSW1wbCggbk9wMSwgbk9wMiwgZmFsc2UgKTsKfQoKdm9pZCBTYmlSdW50aW1lOjpTdGVwUFVCTElDX1AoIHNhbF91SW50MzIgbk9wMSwgc2FsX3VJbnQzMiBuT3AyICkKewogICAgLy8gQ3JlYXRlcyBtb2R1bGUgdmFyaWFibGUgdGhhdCBpc24ndCByZWluaXRpYWxpc2VkIHdoZW4KICAgIC8vIGJldHdlZW4gaW52b2NhdGlvbnMgKCBmb3IgVkJBU3VwcG9ydCAmIGRvY3VtZW50IGJhc2ljIG9ubHkgKQogICAgaWYoIHBNb2QtPnBJbWFnZS0+YkZpcnN0SW5pdCApCgl7CgkJYm9vbCBiVXNlZEZvckNsYXNzTW9kdWxlID0gcEltZy0+R2V0RmxhZyggU0JJTUdfQ0xBU1NNT0RVTEUgKTsKCQlTdGVwUFVCTElDX0ltcGwoIG5PcDEsIG5PcDIsIGJVc2VkRm9yQ2xhc3NNb2R1bGUgKTsKCX0KfQoKLy8gRWlucmljaHRlbiBlaW5lciBnbG9iYWxlbiBWYXJpYWJsZW4gKCtTdHJpbmdJRCtUeXApCgp2b2lkIFNiaVJ1bnRpbWU6OlN0ZXBHTE9CQUwoIHNhbF91SW50MzIgbk9wMSwgc2FsX3VJbnQzMiBuT3AyICkKewoJaWYoIHBJbWctPkdldEZsYWcoIFNCSU1HX0NMQVNTTU9EVUxFICkgKQoJCVN0ZXBQVUJMSUNfSW1wbCggbk9wMSwgbk9wMiwgdHJ1ZSApOwoKCVN0cmluZyBhTmFtZSggcEltZy0+R2V0U3RyaW5nKCBzdGF0aWNfY2FzdDxzaG9ydD4oIG5PcDEgKSApICk7CglTYnhEYXRhVHlwZSB0ID0gKFNieERhdGFUeXBlKShuT3AyICYgMHhmZmZmKTsKCgkvLyBTdG9yZSBtb2R1bGUgc2NvcGUgdmFyaWFibGVzIGF0IG1vZHVsZSBzY29wZSAKCS8vIGluIG5vbiB2YmEgbW9kZSB0aGVzZSBhcmUgc3RvcmVkIGF0IHRoZSBsaWJyYXJ5IGxldmVsIDovCgkvLyBub3Qgc3VyZSBpZiB0aGlzIHJlYWxseSBzaG91bGQgbm90IGJlIGVuYWJsZWQgZm9yIEFMTCBiYXNpYwoJU2J4T2JqZWN0KiBwU3RvcmFnZSA9ICZyQmFzaWM7CglpZiAoIFNiaVJ1bnRpbWU6OmlzVkJBRW5hYmxlZCgpICkgCgl7CgkJcFN0b3JhZ2UgPSBwTW9kOwoJCXBNb2QtPkFkZFZhck5hbWUoIGFOYW1lICk7Cgl9CgoJc2FsX0Jvb2wgYkZsYWcgPSBwU3RvcmFnZS0+SXNTZXQoIFNCWF9OT19NT0RJRlkgKTsKCXJCYXNpYy5TZXRGbGFnKCBTQlhfTk9fTU9ESUZZICk7CglTYnhWYXJpYWJsZVJlZiBwID0gcFN0b3JhZ2UtPkZpbmQoIGFOYW1lLCBTYnhDTEFTU19QUk9QRVJUWSApOwoJaWYoIHAuSXMoKSApCgkJcFN0b3JhZ2UtPlJlbW92ZSAocCk7CglwID0gcFN0b3JhZ2UtPk1ha2UoIGFOYW1lLCBTYnhDTEFTU19QUk9QRVJUWSwgdCApOwoJaWYoICFiRmxhZyApCgkJcFN0b3JhZ2UtPlJlc2V0RmxhZyggU0JYX05PX01PRElGWSApOwoJaWYoIHAgKQoJewoJCXAtPlNldEZsYWcoIFNCWF9ET05UU1RPUkUgKTsKCQkvLyBBQjogMi43LjE5OTY6IEhBQ0sgd2VnZW4gJ1JlZmVyZW56IGthbm4gbmljaHQgZ2VzaWNoZXJ0IHdlcmRlbicKCQlwLT5TZXRGbGFnKCBTQlhfTk9fTU9ESUZZKTsKCX0KfQoKCi8vIENyZWF0ZXMgZ2xvYmFsIHZhcmlhYmxlIHRoYXQgaXNuJ3QgcmVpbml0aWFsaXNlZCB3aGVuCi8vIGJhc2ljIGlzIHJlc3RhcnRlZCwgUD1QRVJTSVNUICgrU3RyaW5nSUQrVHlwKQoKdm9pZCBTYmlSdW50aW1lOjpTdGVwR0xPQkFMX1AoIHNhbF91SW50MzIgbk9wMSwgc2FsX3VJbnQzMiBuT3AyICkKewogICAgaWYoIHBNb2QtPnBJbWFnZS0+YkZpcnN0SW5pdCApCiAgICB7CiAgICAgICAgU3RlcEdMT0JBTCggbk9wMSwgbk9wMiApOwogICAgfQp9CgoKLy8gU2VhcmNoZXMgZm9yIGdsb2JhbCB2YXJpYWJsZSwgYmVoYXZpb3IgZGVwZW5kcyBvbiB0aGUgZmFjdAovLyBpZiB0aGUgdmFyaWFibGUgaXMgaW5pdGlhbGlzZWQgZm9yIHRoZSBmaXJzdCB0aW1lCgp2b2lkIFNiaVJ1bnRpbWU6OlN0ZXBGSU5EX0coIHNhbF91SW50MzIgbk9wMSwgc2FsX3VJbnQzMiBuT3AyICkKewogICAgaWYoIHBNb2QtPnBJbWFnZS0+YkZpcnN0SW5pdCApCiAgICB7CiAgICAgICAgLy8gQmVoYXZlIGxpa2UgYWx3YXlzIGR1cmluZyBmaXJzdCBpbml0CiAgICAgICAgU3RlcEZJTkQoIG5PcDEsIG5PcDIgKTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICAvLyBSZXR1cm4gZHVtbXkgdmFyaWFibGUKCQlTYnhEYXRhVHlwZSB0ID0gKFNieERhdGFUeXBlKSBuT3AyOwoJCVN0cmluZyBhTmFtZSggcEltZy0+R2V0U3RyaW5nKCBzdGF0aWNfY2FzdDxzaG9ydD4oIG5PcDEgJiAweDdGRkYgKSApICk7CgogICAgICAgIFNieFZhcmlhYmxlKiBwRHVtbXlWYXIgPSBuZXcgU2J4VmFyaWFibGUoIHQgKTsKCQlwRHVtbXlWYXItPlNldE5hbWUoIGFOYW1lICk7CiAgICAJUHVzaFZhciggcER1bW15VmFyICk7CiAgICB9Cn0KCgpTYnhWYXJpYWJsZSogU2JpUnVudGltZTo6U3RlcFNUQVRJQ19JbXBsKCBTdHJpbmcmIGFOYW1lLCBTYnhEYXRhVHlwZSYgdCApCnsKICAgIFNieFZhcmlhYmxlKiBwID0gTlVMTDsKICAgIGlmICggcE1ldGggKQogICAgewogICAgICAgIFNieEFycmF5KiBwU3RhdGljcyA9IHBNZXRoLT5HZXRTdGF0aWNzKCk7CiAgICAgICAgaWYoIHBTdGF0aWNzICYmICggcFN0YXRpY3MtPkZpbmQoIGFOYW1lLCBTYnhDTEFTU19ET05UQ0FSRSApID09IE5VTEwgKSApCiAgICAgICAgewogICAgICAgICAgICBwID0gbmV3IFNieFZhcmlhYmxlKCB0ICk7CiAgICAgICAgICAgIGlmKCB0ICE9IFNieFZBUklBTlQgKQogICAgICAgICAgICAgICAgcC0+U2V0RmxhZyggU0JYX0ZJWEVEICk7CiAgICAgICAgICAgIHAtPlNldE5hbWUoIGFOYW1lICk7CiAgICAgICAgICAgIHBTdGF0aWNzLT5QdXQoIHAsIHBTdGF0aWNzLT5Db3VudCgpICk7CiAgICAgICAgfQogICAgfQogICAgcmV0dXJuIHA7Cn0KLy8gRWlucmljaHRlbiBlaW5lciBzdGF0aXNjaGVuIFZhcmlhYmxlbiAoK1N0cmluZ0lEK1R5cCkKdm9pZCBTYmlSdW50aW1lOjpTdGVwU1RBVElDKCBzYWxfdUludDMyIG5PcDEsIHNhbF91SW50MzIgbk9wMiApCnsKICAgIFN0cmluZyBhTmFtZSggcEltZy0+R2V0U3RyaW5nKCBzdGF0aWNfY2FzdDxzaG9ydD4oIG5PcDEgKSApICk7CiAgICBTYnhEYXRhVHlwZSB0ID0gKFNieERhdGFUeXBlKSBuT3AyOwogICAgU3RlcFNUQVRJQ19JbXBsKCBhTmFtZSwgdCApOwp9Cgo=