LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCiAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCiAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQogKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCiAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAogKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgogKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCiAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKICogdW5kZXIgdGhlIExpY2Vuc2UuCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKCgovLyBNQVJLRVIodXBkYXRlX3ByZWNvbXAucHkpOiBhdXRvZ2VuIGluY2x1ZGUgc3RhdGVtZW50LCBkbyBub3QgcmVtb3ZlCiNpbmNsdWRlICJwcmVjb21waWxlZF9iYXNpYy5oeHgiCgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxydGwvbWF0aC5oeHg+CiNpbmNsdWRlIDxiYXNpYy9zYnVuby5oeHg+CiNpbmNsdWRlICJydW50aW1lLmh4eCIKI2luY2x1ZGUgInNiaW50ZXJuLmh4eCIKI2luY2x1ZGUgImlvc3lzLmh4eCIKI2luY2x1ZGUgImltYWdlLmh4eCIKI2luY2x1ZGUgInNidW5vb2JqLmh4eCIKI2luY2x1ZGUgImVycm9iamVjdC5oeHgiCgpib29sIGNoZWNrVW5vT2JqZWN0VHlwZSggU2JVbm9PYmplY3QqIHJlZlZhbCwgY29uc3QgOjpydGw6Ok9VU3RyaW5nJiBhQ2xhc3MgKTsKCi8vIExhZGVuIGVpbmVyIG51bWVyaXNjaGVuIEtvbnN0YW50ZW4gKCtJRCkKCnZvaWQgU2JpUnVudGltZTo6U3RlcExPQUROQyggc2FsX3VJbnQzMiBuT3AxICkKewoJU2J4VmFyaWFibGUqIHAgPSBuZXcgU2J4VmFyaWFibGUoIFNieERPVUJMRSApOwoKCS8vICM1Nzg0NCBMb2thbGlzaWVydGUgRnVua3Rpb24gYmVudXR6ZW4KCVN0cmluZyBhU3RyID0gcEltZy0+R2V0U3RyaW5nKCBzdGF0aWNfY2FzdDxzaG9ydD4oIG5PcDEgKSApOwoJLy8gQXVjaCAsIHp1bGFzc2VuICEhIQoJc2FsX3VJbnQxNiBpQ29tbWEgPSBhU3RyLlNlYXJjaCggJywnICk7CglpZiggaUNvbW1hICE9IFNUUklOR19OT1RGT1VORCApCgl7CgkJU3RyaW5nIGFTdHIxID0gYVN0ci5Db3B5KCAwLCBpQ29tbWEgKTsKCQlTdHJpbmcgYVN0cjIgPSBhU3RyLkNvcHkoIGlDb21tYSArIDEgKTsKCQlhU3RyID0gYVN0cjE7CgkJYVN0ciArPSAnLic7CgkJYVN0ciArPSBhU3RyMjsKCX0KICAgIGRvdWJsZSBuID0gOjpydGw6Om1hdGg6OnN0cmluZ1RvRG91YmxlKCBhU3RyLCAnLicsICcsJywgTlVMTCwgTlVMTCApOwoKCXAtPlB1dERvdWJsZSggbiApOwoJUHVzaFZhciggcCApOwp9CgovLyBMYWRlbiBlaW5lciBTdHJpbmdrb25zdGFudGVuICgrSUQpCgp2b2lkIFNiaVJ1bnRpbWU6OlN0ZXBMT0FEU0MoIHNhbF91SW50MzIgbk9wMSApCnsKCVNieFZhcmlhYmxlKiBwID0gbmV3IFNieFZhcmlhYmxlOwoJcC0+UHV0U3RyaW5nKCBwSW1nLT5HZXRTdHJpbmcoIHN0YXRpY19jYXN0PHNob3J0Piggbk9wMSApICkgKTsKCVB1c2hWYXIoIHAgKTsKfQoKLy8gSW1tZWRpYXRlIExvYWQgKCtXZXJ0KQoKdm9pZCBTYmlSdW50aW1lOjpTdGVwTE9BREkoIHNhbF91SW50MzIgbk9wMSApCnsKCVNieFZhcmlhYmxlKiBwID0gbmV3IFNieFZhcmlhYmxlOwoJcC0+UHV0SW50ZWdlciggc3RhdGljX2Nhc3Q8c2FsX0ludDE2Piggbk9wMSApICk7CglQdXNoVmFyKCBwICk7Cn0KCi8vIFNwZWljaGVybiBlaW5lcyBuYW1lZCBBcmd1bWVudHMgaW4gQXJndiAoK0FyZy1OciBhYiAxISkKCnZvaWQgU2JpUnVudGltZTo6U3RlcEFSR04oIHNhbF91SW50MzIgbk9wMSApCnsKCWlmKCAhcmVmQXJndiApCgkJU3RhckJBU0lDOjpGYXRhbEVycm9yKCBTYkVSUl9JTlRFUk5BTF9FUlJPUiApOwoJZWxzZQoJewoJCVN0cmluZyBhQWxpYXMoIHBJbWctPkdldFN0cmluZyggc3RhdGljX2Nhc3Q8c2hvcnQ+KCBuT3AxICkgKSApOwoJCVNieFZhcmlhYmxlUmVmIHBWYWwgPSBQb3BWYXIoKTsKCQlyZWZBcmd2LT5QdXQoIHBWYWwsIG5BcmdjICk7CgkJcmVmQXJndi0+UHV0QWxpYXMoIGFBbGlhcywgbkFyZ2MrKyApOwoJfQp9CgovLyBLb252ZXJ0aWVydW5nIGRlcyBUeXBzIGVpbmVzIEFyZ3VtZW50cyBpbiBBcmd2IGZ1ZXIgREVDTEFSRS1Ga3QuICgrVHlwKQoKdm9pZCBTYmlSdW50aW1lOjpTdGVwQVJHVFlQKCBzYWxfdUludDMyIG5PcDEgKQp7CglpZiggIXJlZkFyZ3YgKQoJCVN0YXJCQVNJQzo6RmF0YWxFcnJvciggU2JFUlJfSU5URVJOQUxfRVJST1IgKTsKCWVsc2UKCXsKCQlzYWxfQm9vbCBiQnlWYWwgPSAobk9wMSAmIDB4ODAwMCkgIT0gMDsJCQkvLyBJc3QgQllWQUwgdmVybGFuZ3Q/CgkJU2J4RGF0YVR5cGUgdCA9IChTYnhEYXRhVHlwZSkgKG5PcDEgJiAweDdGRkYpOwoJCVNieFZhcmlhYmxlKiBwVmFyID0gcmVmQXJndi0+R2V0KCByZWZBcmd2LT5Db3VudCgpIC0gMSApOwkvLyBsZXR6dGVzIEFyZwoKCQkvLyBCWVZBTCBwcvxmZW4KCQlpZiggcFZhci0+R2V0UmVmQ291bnQoKSA+IDIgKQkJLy8gMiBpc3Qgbm9ybWFsIGb8ciBCWVZBTAoJCXsKCQkJLy8gUGFyYW1ldGVyIGlzdCBlaW5lIFJlZmVyZW56CgkJCWlmKCBiQnlWYWwgKQoJCQl7CgkJCQkvLyBDYWxsIGJ5IFZhbHVlIGlzdCB2ZXJsYW5ndCAtPiBLb3BpZSBhbmxlZ2VuCgkJCQlwVmFyID0gbmV3IFNieFZhcmlhYmxlKCAqcFZhciApOwoJCQkJcFZhci0+U2V0RmxhZyggU0JYX1JFQURXUklURSApOwoJCQkJcmVmRXhwclN0ay0+UHV0KCBwVmFyLCByZWZBcmd2LT5Db3VudCgpIC0gMSApOwoJCQl9CgkJCWVsc2UKCQkJCXBWYXItPlNldEZsYWcoIFNCWF9SRUZFUkVOQ0UgKTsJCS8vIFJlZi1GbGFnIGb8ciBEbGxNZ3IKCQl9CgkJZWxzZQoJCXsKCQkJLy8gUGFyYW1ldGVyIGlzdCBLRUlORSBSZWZlcmVuegoJCQlpZiggYkJ5VmFsICkKCQkJCXBWYXItPlJlc2V0RmxhZyggU0JYX1JFRkVSRU5DRSApOwkvLyBLZWluZSBSZWZlcmVueiAtPiBPSwoJCQllbHNlCgkJCQlFcnJvciggU2JFUlJfQkFEX1BBUkFNRVRFUlMgKTsJCS8vIFJlZmVyZW56IHZlcmxhbmd0CgkJfQoKCQlpZiggcFZhci0+R2V0VHlwZSgpICE9IHQgKQoJCXsKCQkJLy8gVmFyaWFudCwgZGFtaXQgcmljaHRpZ2UgS29udmVydGllcnVuZwoJCQkvLyBBdXNzZXJkZW0gRmVobGVyLCB3ZW5uIFNieEJZUkVGCgkJCXBWYXItPkNvbnZlcnQoIFNieFZBUklBTlQgKTsKCQkJcFZhci0+Q29udmVydCggdCApOwoJCX0KCX0KfQoKLy8gU3RyaW5nIGF1ZiBmZXN0ZSBMYWVuZ2UgYnJpbmdlbiAoK0xhZW5nZSkKCnZvaWQgU2JpUnVudGltZTo6U3RlcFBBRCggc2FsX3VJbnQzMiBuT3AxICkKewoJU2J4VmFyaWFibGUqIHAgPSBHZXRUT1MoKTsKCVN0cmluZyYgcyA9IChTdHJpbmcmKShjb25zdCBTdHJpbmcmKSAqcDsKCWlmKCBzLkxlbigpID4gbk9wMSApCgkJcy5FcmFzZSggc3RhdGljX2Nhc3Q8eHViX1N0ckxlbj4oIG5PcDEgKSApOwoJZWxzZQoJCXMuRXhwYW5kKCBzdGF0aWNfY2FzdDx4dWJfU3RyTGVuPiggbk9wMSApLCAnICcgKTsKfQoKLy8gU3BydW5nICgrVGFyZ2V0KQoKdm9pZCBTYmlSdW50aW1lOjpTdGVwSlVNUCggc2FsX3VJbnQzMiBuT3AxICkKewojaWZkZWYgREJHX1VUSUwKCS8vICNRVUVTVElPTiBzaG91bG4ndCB0aGlzIGJlCgkvLyBpZiggKHNhbF91SW50OCopKCBuT3AxK3BJbWFnR2V0Q29kZSgpICkgPj0gcEltZy0+R2V0Q29kZVNpemUoKSApCglpZiggbk9wMSA+PSBwSW1nLT5HZXRDb2RlU2l6ZSgpICkKCQlTdGFyQkFTSUM6OkZhdGFsRXJyb3IoIFNiRVJSX0lOVEVSTkFMX0VSUk9SICk7CiNlbmRpZgoJcENvZGUgPSAoY29uc3Qgc2FsX3VJbnQ4KikgcEltZy0+R2V0Q29kZSgpICsgbk9wMTsKfQoKLy8gVE9TIGF1c3dlcnRlbiwgYmVkaW5ndGVyIFNwcnVuZyAoK1RhcmdldCkKCnZvaWQgU2JpUnVudGltZTo6U3RlcEpVTVBUKCBzYWxfdUludDMyIG5PcDEgKQp7CglTYnhWYXJpYWJsZVJlZiBwID0gUG9wVmFyKCk7CglpZiggcC0+R2V0Qm9vbCgpICkKCQlTdGVwSlVNUCggbk9wMSApOwp9CgovLyBUT1MgYXVzd2VydGVuLCBiZWRpbmd0ZXIgU3BydW5nICgrVGFyZ2V0KQoKdm9pZCBTYmlSdW50aW1lOjpTdGVwSlVNUEYoIHNhbF91SW50MzIgbk9wMSApCnsKCVNieFZhcmlhYmxlUmVmIHAgPSBQb3BWYXIoKTsKCWlmKCAhcC0+R2V0Qm9vbCgpICkKCQlTdGVwSlVNUCggbk9wMSApOwp9CgovLyBUT1MgYXVzd2VydGVuLCBTcHJ1bmcgaW4gSlVNUC1UYWJlbGxlICgrTWF4VmFsKQovLyBTaWVodCBzbyBhdXM6Ci8vIE9OSlVNUCAyCi8vIEpVTVAgdGFyZ2V0MQovLyBKVU1QIHRhcmdldDIKLy8gLi4uCi8vRmFsbHMgaW0gT3BlcmFuZGVuIDB4ODAwMCBnZXNldHp0IGlzdCwgUmV0dXJuYWRyZXNzZSBwdXNoZW4gKE9OLi5HT1NVQikKCnZvaWQgU2JpUnVudGltZTo6U3RlcE9OSlVNUCggc2FsX3VJbnQzMiBuT3AxICkKewoJU2J4VmFyaWFibGVSZWYgcCA9IFBvcFZhcigpOwoJc2FsX0ludDE2IG4gPSBwLT5HZXRJbnRlZ2VyKCk7CglpZiggbk9wMSAmIDB4ODAwMCApCgl7CgkJbk9wMSAmPSAweDdGRkY7CgkJLy9QdXNoR29zdWIoIHBDb2RlICsgMyAqIG5PcDEgKTsKCQlQdXNoR29zdWIoIHBDb2RlICsgNSAqIG5PcDEgKTsKCX0KCWlmKCBuIDwgMSB8fCBzdGF0aWNfY2FzdDxzYWxfdUludDMyPihuKSA+IG5PcDEgKQoJCW4gPSBzdGF0aWNfY2FzdDxzYWxfSW50MTY+KCBuT3AxICsgMSApOwoJLy9uT3AxID0gKHNhbF91SW50MzIpICggKGNvbnN0IGNoYXIqKSBwQ29kZSAtIHBJbWctPkdldENvZGUoKSApICsgMyAqIC0tbjsKCW5PcDEgPSAoc2FsX3VJbnQzMikgKCAoY29uc3QgY2hhciopIHBDb2RlIC0gcEltZy0+R2V0Q29kZSgpICkgKyA1ICogLS1uOwoJU3RlcEpVTVAoIG5PcDEgKTsKfQoKLy8gVVAtQXVmcnVmICgrVGFyZ2V0KQoKdm9pZCBTYmlSdW50aW1lOjpTdGVwR09TVUIoIHNhbF91SW50MzIgbk9wMSApCnsKCVB1c2hHb3N1YiggcENvZGUgKTsKCWlmKCBuT3AxID49IHBJbWctPkdldENvZGVTaXplKCkgKQoJCVN0YXJCQVNJQzo6RmF0YWxFcnJvciggU2JFUlJfSU5URVJOQUxfRVJST1IgKTsKCXBDb2RlID0gKGNvbnN0IHNhbF91SW50OCopIHBJbWctPkdldENvZGUoKSArIG5PcDE7Cn0KCi8vIFVQLVJldHVybiAoKzAgb2RlciBUYXJnZXQpCgp2b2lkIFNiaVJ1bnRpbWU6OlN0ZXBSRVRVUk4oIHNhbF91SW50MzIgbk9wMSApCnsKCVBvcEdvc3ViKCk7CglpZiggbk9wMSApCgkJU3RlcEpVTVAoIG5PcDEgKTsKfQoKLy8gRk9SLVZhcmlhYmxlIHRlc3RlbiAoK0VuZGxhYmVsKQoKdm9pZCBTYmlSdW50aW1lOjpTdGVwVEVTVEZPUiggc2FsX3VJbnQzMiBuT3AxICkKewoJaWYoICFwRm9yU3RrICkKCXsKCQlTdGFyQkFTSUM6OkZhdGFsRXJyb3IoIFNiRVJSX0lOVEVSTkFMX0VSUk9SICk7CgkJcmV0dXJuOwoJfQoKCWJvb2wgYkVuZExvb3AgPSBmYWxzZTsKCXN3aXRjaCggcEZvclN0ay0+ZUZvclR5cGUgKQoJewoJCWNhc2UgRk9SX1RPOgoJCXsKCQkJU2J4T3BlcmF0b3IgZU9wID0gKCBwRm9yU3RrLT5yZWZJbmMtPkdldERvdWJsZSgpIDwgMCApID8gU2J4TFQgOiBTYnhHVDsKCQkJaWYoIHBGb3JTdGstPnJlZlZhci0+Q29tcGFyZSggZU9wLCAqcEZvclN0ay0+cmVmRW5kICkgKQoJCQkJYkVuZExvb3AgPSB0cnVlOwoJCQlicmVhazsKCQl9CgkJY2FzZSBGT1JfRUFDSF9BUlJBWToKCQl7CgkJCVNiaUZvclN0YWNrKiBwID0gcEZvclN0azsKCQkJaWYoIHAtPnBBcnJheUN1ckluZGljZXMgPT0gTlVMTCApCgkJCXsKCQkJCWJFbmRMb29wID0gdHJ1ZTsKCQkJfQoJCQllbHNlCgkJCXsKCQkJCVNieERpbUFycmF5KiBwQXJyYXkgPSAoU2J4RGltQXJyYXkqKShTYnhWYXJpYWJsZSopcC0+cmVmRW5kOwoJCQkJc2hvcnQgbkRpbXMgPSBwQXJyYXktPkdldERpbXMoKTsKCgkJCQkvLyBFbXB0eSBhcnJheT8KCQkJCWlmKCBuRGltcyA9PSAxICYmIHAtPnBBcnJheUxvd2VyQm91bmRzWzBdID4gcC0+cEFycmF5VXBwZXJCb3VuZHNbMF0gKQoJCQkJewoJCQkJCWJFbmRMb29wID0gdHJ1ZTsKCQkJCQlicmVhazsKCQkJCX0KCQkJCVNieFZhcmlhYmxlKiBwVmFsID0gcEFycmF5LT5HZXQzMiggcC0+cEFycmF5Q3VySW5kaWNlcyApOwoJCQkJKihwLT5yZWZWYXIpID0gKnBWYWw7CgoJCQkJYm9vbCBiRm91bmROZXh0ID0gZmFsc2U7CgkJCQlmb3IoIHNob3J0IGkgPSAwIDsgaSA8IG5EaW1zIDsgaSsrICkKCQkJCXsKCQkJCQlpZiggcC0+cEFycmF5Q3VySW5kaWNlc1tpXSA8IHAtPnBBcnJheVVwcGVyQm91bmRzW2ldICkKCQkJCQl7CgkJCQkJCWJGb3VuZE5leHQgPSB0cnVlOwoJCQkJCQlwLT5wQXJyYXlDdXJJbmRpY2VzW2ldKys7CgkJCQkJCWZvciggc2hvcnQgaiA9IGkgLSAxIDsgaiA+PSAwIDsgai0tICkKCQkJCQkJCXAtPnBBcnJheUN1ckluZGljZXNbal0gPSBwLT5wQXJyYXlMb3dlckJvdW5kc1tqXTsKCQkJCQkJYnJlYWs7CgkJCQkJfQoJCQkJfQoJCQkJaWYoICFiRm91bmROZXh0ICkKCQkJCXsKCQkJCQlkZWxldGVbXSBwLT5wQXJyYXlDdXJJbmRpY2VzOwoJCQkJCXAtPnBBcnJheUN1ckluZGljZXMgPSBOVUxMOwoJCQkJfQoJCQl9CgkJCWJyZWFrOwoJCX0KCQljYXNlIEZPUl9FQUNIX0NPTExFQ1RJT046CgkJewoJCQlCYXNpY0NvbGxlY3Rpb24qIHBDb2xsZWN0aW9uID0gKEJhc2ljQ29sbGVjdGlvbiopKFNieFZhcmlhYmxlKilwRm9yU3RrLT5yZWZFbmQ7CgkJCVNieEFycmF5UmVmIHhJdGVtQXJyYXkgPSBwQ29sbGVjdGlvbi0+eEl0ZW1BcnJheTsKCQkJc2FsX0ludDMyIG5Db3VudCA9IHhJdGVtQXJyYXktPkNvdW50MzIoKTsKCQkJaWYoIHBGb3JTdGstPm5DdXJDb2xsZWN0aW9uSW5kZXggPCBuQ291bnQgKQoJCQl7CgkJCQlTYnhWYXJpYWJsZSogcFJlcyA9IHhJdGVtQXJyYXktPkdldDMyKCBwRm9yU3RrLT5uQ3VyQ29sbGVjdGlvbkluZGV4ICk7CgkJCQlwRm9yU3RrLT5uQ3VyQ29sbGVjdGlvbkluZGV4Kys7CgkJCQkoKnBGb3JTdGstPnJlZlZhcikgPSAqcFJlczsKCQkJfQoJCQllbHNlCgkJCXsKCQkJCWJFbmRMb29wID0gdHJ1ZTsKCQkJfQoJCQlicmVhazsKCQl9CgkJY2FzZSBGT1JfRUFDSF9YRU5VTUVSQVRJT046CgkJewoJCQlTYmlGb3JTdGFjayogcCA9IHBGb3JTdGs7CgkJCWlmKCBwLT54RW51bWVyYXRpb24tPmhhc01vcmVFbGVtZW50cygpICkKCQkJewoJCQkJQW55IGFFbGVtID0gcC0+eEVudW1lcmF0aW9uLT5uZXh0RWxlbWVudCgpOwoJCQkJU2J4VmFyaWFibGVSZWYgeFZhciA9IG5ldyBTYnhWYXJpYWJsZSggU2J4VkFSSUFOVCApOwoJCQkJdW5vVG9TYnhWYWx1ZSggKFNieFZhcmlhYmxlKil4VmFyLCBhRWxlbSApOwoJCQkJKCpwRm9yU3RrLT5yZWZWYXIpID0gKnhWYXI7CgkJCX0KCQkJZWxzZQoJCQl7CgkJCQliRW5kTG9vcCA9IHRydWU7CgkJCX0KCQkJYnJlYWs7CgkJfQoJfQoJaWYoIGJFbmRMb29wICkKCXsKCQlQb3BGb3IoKTsKCQlTdGVwSlVNUCggbk9wMSApOwoJfQp9CgovLyBUb3MrMSA8PSBUb3MrMiA8PSBUb3MsIDJ4cmVtb3ZlICgrVGFyZ2V0KQoKdm9pZCBTYmlSdW50aW1lOjpTdGVwQ0FTRVRPKCBzYWxfdUludDMyIG5PcDEgKQp7CglpZiggIXJlZkNhc2VTdGsgfHwgIXJlZkNhc2VTdGstPkNvdW50KCkgKQoJCVN0YXJCQVNJQzo6RmF0YWxFcnJvciggU2JFUlJfSU5URVJOQUxfRVJST1IgKTsKCWVsc2UKCXsKCQlTYnhWYXJpYWJsZVJlZiB4VG8gICA9IFBvcFZhcigpOwoJCVNieFZhcmlhYmxlUmVmIHhGcm9tID0gUG9wVmFyKCk7CgkJU2J4VmFyaWFibGVSZWYgeENhc2UgPSByZWZDYXNlU3RrLT5HZXQoIHJlZkNhc2VTdGstPkNvdW50KCkgLSAxICk7CgkJaWYoICp4Q2FzZSA+PSAqeEZyb20gJiYgKnhDYXNlIDw9ICp4VG8gKQoJCQlTdGVwSlVNUCggbk9wMSApOwoJfQp9CgovLyBGZWhsZXItSGFuZGxlcgoKdm9pZCBTYmlSdW50aW1lOjpTdGVwRVJSSERMKCBzYWxfdUludDMyIG5PcDEgKQp7Cgljb25zdCBzYWxfdUludDgqIHAgPSBwQ29kZTsKCVN0ZXBKVU1QKCBuT3AxICk7CglwRXJyb3IgPSBwQ29kZTsKCXBDb2RlID0gcDsKCXBJbnN0LT5hRXJyb3JNc2cgPSBTdHJpbmcoKTsKCXBJbnN0LT5uRXJyID0gMDsKCXBJbnN0LT5uRXJsID0gMDsKCW5FcnJvciA9IDA7CglTYnhFcnJPYmplY3Q6OmdldFVub0Vyck9iamVjdCgpLT5DbGVhcigpOwp9CgovLyBSZXN1bWUgbmFjaCBGZWhsZXJuICgrMD1zdGF0ZW1lbnQsIDE9bmV4dCBvciBMYWJlbCkKCnZvaWQgU2JpUnVudGltZTo6U3RlcFJFU1VNRSggc2FsX3VJbnQzMiBuT3AxICkKewoJLy8gQUIgIzMyNzE0IFJlc3VtZSBvaG5lIEVycm9yPyAtPiBGZWhsZXIKCWlmKCAhYkluRXJyb3IgKQoJewoJCUVycm9yKCBTYkVSUl9CQURfUkVTVU1FICk7CgkJcmV0dXJuOwoJfQoJaWYoIG5PcDEgKQoJewoJCS8vIENvZGUtWmVpZ2VyIGF1ZiBuYWVjaHN0ZXMgU3RhdGVtZW50IHNldHplbgoJCXNhbF91SW50MTYgbjEsIG4yOwoJCXBDb2RlID0gcE1vZC0+RmluZE5leHRTdG1udCggcEVyckNvZGUsIG4xLCBuMiwgc2FsX1RydWUsIHBJbWcgKTsKCX0KCWVsc2UKCQlwQ29kZSA9IHBFcnJTdG1udDsKCWlmICggcEVycm9yICkgLy8gY3VycmVudCBpbiBlcnJvciBoYW5kbGVyICggYW5kIGdvdCBhIFJlc3VtZSBOZXh0IHN0YXRlbWVudCApCgkJU2J4RXJyT2JqZWN0OjpnZXRVbm9FcnJPYmplY3QoKS0+Q2xlYXIoKTsKCglpZiggbk9wMSA+IDEgKQoJCVN0ZXBKVU1QKCBuT3AxICk7CglwSW5zdC0+YUVycm9yTXNnID0gU3RyaW5nKCk7CglwSW5zdC0+bkVyciA9IDA7CglwSW5zdC0+bkVybCA9IDA7CgluRXJyb3IgPSAwOwoJYkluRXJyb3IgPSBzYWxfRmFsc2U7CgoJLy8gRXJyb3ItU3RhY2sgbG9lc2NoZW4KCVNiRXJyb3JTdGFjayomIHJFcnJTdGFjayA9IEdldFNiRGF0YSgpLT5wRXJyU3RhY2s7CglkZWxldGUgckVyclN0YWNrOwoJckVyclN0YWNrID0gTlVMTDsKfQoKLy8gS2FuYWwgc2NobGllc3NlbiAoK0thbmFsLCAwPUFsbGUpCnZvaWQgU2JpUnVudGltZTo6U3RlcENMT1NFKCBzYWxfdUludDMyIG5PcDEgKQp7CglTYkVycm9yIGVycjsKCWlmKCAhbk9wMSApCgkJcElvc3lzLT5TaHV0ZG93bigpOwoJZWxzZQoJewoJCWVyciA9IHBJb3N5cy0+R2V0RXJyb3IoKTsKCQlpZiggIWVyciApCgkJewoJCQlwSW9zeXMtPkNsb3NlKCk7CgkJfQoJfQoJZXJyID0gcElvc3lzLT5HZXRFcnJvcigpOwoJRXJyb3IoIGVyciApOwp9CgovLyBaZWljaGVuIGF1c2dlYmVuICgrY2hhcikKCnZvaWQgU2JpUnVudGltZTo6U3RlcFBSQ0hBUiggc2FsX3VJbnQzMiBuT3AxICkKewoJQnl0ZVN0cmluZyBzKCAoY2hhcikgbk9wMSApOwoJcElvc3lzLT5Xcml0ZSggcyApOwoJRXJyb3IoIHBJb3N5cy0+R2V0RXJyb3IoKSApOwp9CgovLyBDaGVjaywgb2IgVE9TIGVpbmUgYmVzdGltbXRlIE9iamVrdGtsYXNzZSBpc3QgKCtTdHJpbmdJRCkKCmJvb2wgU2JpUnVudGltZTo6aW1wbElzQ2xhc3MoIFNieE9iamVjdCogcE9iaiwgY29uc3QgU3RyaW5nJiBhQ2xhc3MgKQp7Cglib29sIGJSZXQgPSB0cnVlOwoKCWlmKCBhQ2xhc3MuTGVuKCkgIT0gMCApCgl7CgkJYlJldCA9IHBPYmotPklzQ2xhc3MoIGFDbGFzcyApOwoJCWlmKCAhYlJldCApCgkJCWJSZXQgPSBhQ2xhc3MuRXF1YWxzSWdub3JlQ2FzZUFzY2lpKCBTdHJpbmcoIFJUTF9DT05TVEFTQ0lJX1VTVFJJTkdQQVJBTSgib2JqZWN0IikgKSApOwoJCWlmKCAhYlJldCApCgkJewoJCQlTdHJpbmcgYU9iakNsYXNzID0gcE9iai0+R2V0Q2xhc3NOYW1lKCk7CgkJCVNiTW9kdWxlKiBwQ2xhc3NNb2QgPSBwQ0xBU1NGQUMtPkZpbmRDbGFzcyggYU9iakNsYXNzICk7CgkJCVNiQ2xhc3NEYXRhKiBwQ2xhc3NEYXRhOwoJCQlpZiggcENsYXNzTW9kICYmIChwQ2xhc3NEYXRhPXBDbGFzc01vZC0+cENsYXNzRGF0YSkgIT0gTlVMTCApCgkJCXsKCQkJCVNieFZhcmlhYmxlKiBwQ2xhc3NWYXIgPQoJCQkJCXBDbGFzc0RhdGEtPm14SWZhY2VzLT5GaW5kKCBhQ2xhc3MsIFNieENMQVNTX0RPTlRDQVJFICk7CgkJCQliUmV0ID0gKHBDbGFzc1ZhciAhPSBOVUxMKTsKCQkJfQoJCX0KCX0KCXJldHVybiBiUmV0Owp9Cgpib29sIFNiaVJ1bnRpbWU6OmNoZWNrQ2xhc3NfSW1wbCggY29uc3QgU2J4VmFyaWFibGVSZWYmIHJlZlZhbCwKCWNvbnN0IFN0cmluZyYgYUNsYXNzLCBib29sIGJSYWlzZUVycm9ycywgYm9vbCBiRGVmYXVsdCApCnsKCWJvb2wgYk9rID0gYkRlZmF1bHQ7CgoJU2J4RGF0YVR5cGUgdCA9IHJlZlZhbC0+R2V0VHlwZSgpOwoJaWYoIHQgPT0gU2J4T0JKRUNUICkKCXsKCQlTYnhPYmplY3QqIHBPYmo7CgkJU2J4VmFyaWFibGUqIHBWYWwgPSAoU2J4VmFyaWFibGUqKXJlZlZhbDsKCQlpZiggcFZhbC0+SXNBKCBUWVBFKFNieE9iamVjdCkgKSApCgkJCXBPYmogPSAoU2J4T2JqZWN0KikgcFZhbDsKCQllbHNlCgkJewoJCQlwT2JqID0gKFNieE9iamVjdCopIHJlZlZhbC0+R2V0T2JqZWN0KCk7CgkJCWlmKCBwT2JqICYmICFwT2JqLT5Jc0EoIFRZUEUoU2J4T2JqZWN0KSApICkKCQkJCXBPYmogPSBOVUxMOwoJCX0KCQlpZiggcE9iaiApCgkJewoJCQlpZiggIWltcGxJc0NsYXNzKCBwT2JqLCBhQ2xhc3MgKSApCgkJCXsKCQkJCWlmICggYlZCQUVuYWJsZWQgJiYgcE9iai0+SXNBKCBUWVBFKFNiVW5vT2JqZWN0KSApICkKCQkJCXsKCQkJCQlTYlVub09iamVjdCogcFVub09iaiA9IFBUUl9DQVNUKFNiVW5vT2JqZWN0LHBPYmopOwoJCQkJCWJPayA9IGNoZWNrVW5vT2JqZWN0VHlwZSggcFVub09iaiwgYUNsYXNzICk7CgkJCQl9CgkJCQllbHNlCgkJCQkJYk9rID0gZmFsc2U7CgkJCQlpZiAoICFiT2sgKQoJCQkJewoJCQkJCWlmKCBiUmFpc2VFcnJvcnMgKQoJCQkJCQlFcnJvciggU2JFUlJfSU5WQUxJRF9VU0FHRV9PQkpFQ1QgKTsKCQkJCX0KCQkJfQoJCQllbHNlCgkJCXsKCQkJCWJPayA9IHRydWU7CgoJCQkJU2JDbGFzc01vZHVsZU9iamVjdCogcENsYXNzTW9kdWxlT2JqZWN0ID0gUFRSX0NBU1QoU2JDbGFzc01vZHVsZU9iamVjdCxwT2JqKTsKCQkJCWlmKCBwQ2xhc3NNb2R1bGVPYmplY3QgIT0gTlVMTCApCgkJCQkJcENsYXNzTW9kdWxlT2JqZWN0LT50cmlnZ2VySW5pdGlhbGl6ZUV2ZW50KCk7CgkJCX0KCQl9Cgl9CgllbHNlCgl7CgkJaWYgKCAhYlZCQUVuYWJsZWQgKQoJCXsKCQkJaWYoIGJSYWlzZUVycm9ycyApCgkJCQlFcnJvciggU2JFUlJfTkVFRFNfT0JKRUNUICk7CgkJCWJPayA9IGZhbHNlOwoJCX0KCX0KCXJldHVybiBiT2s7Cn0KCnZvaWQgU2JpUnVudGltZTo6U3RlcFNFVENMQVNTX2ltcGwoIHNhbF91SW50MzIgbk9wMSwgYm9vbCBiSGFuZGxlRGZsdCApCnsKCVNieFZhcmlhYmxlUmVmIHJlZlZhbCA9IFBvcFZhcigpOwoJU2J4VmFyaWFibGVSZWYgcmVmVmFyID0gUG9wVmFyKCk7CglTdHJpbmcgYUNsYXNzKCBwSW1nLT5HZXRTdHJpbmcoIHN0YXRpY19jYXN0PHNob3J0Piggbk9wMSApICkgKTsKCglib29sIGJPayA9IGNoZWNrQ2xhc3NfSW1wbCggcmVmVmFsLCBhQ2xhc3MsIHRydWUgKTsKCWlmKCBiT2sgKQoJCVN0ZXBTRVRfSW1wbCggcmVmVmFsLCByZWZWYXIsIGJIYW5kbGVEZmx0ICk7IC8vIGRvbid0IGRvIGhhbmRsZSBkZmx0IHByb3AgZm9yIGEgInByb3BlciIgc2V0Cn0KCnZvaWQgU2JpUnVudGltZTo6U3RlcFZCQVNFVENMQVNTKCBzYWxfdUludDMyIG5PcDEgKQp7CglTdGVwU0VUQ0xBU1NfaW1wbCggbk9wMSwgZmFsc2UgKTsKfQoKdm9pZCBTYmlSdW50aW1lOjpTdGVwU0VUQ0xBU1MoIHNhbF91SW50MzIgbk9wMSApCnsKCVN0ZXBTRVRDTEFTU19pbXBsKCBuT3AxLCB0cnVlICk7Cn0KCnZvaWQgU2JpUnVudGltZTo6U3RlcFRFU1RDTEFTUyggc2FsX3VJbnQzMiBuT3AxICkKewoJU2J4VmFyaWFibGVSZWYgeE9ialZhbCA9IFBvcFZhcigpOwoJU3RyaW5nIGFDbGFzcyggcEltZy0+R2V0U3RyaW5nKCBzdGF0aWNfY2FzdDxzaG9ydD4oIG5PcDEgKSApICk7Cglib29sIGJEZWZhdWx0ID0gIWJWQkFFbmFibGVkOwoJYm9vbCBiT2sgPSBjaGVja0NsYXNzX0ltcGwoIHhPYmpWYWwsIGFDbGFzcywgZmFsc2UsIGJEZWZhdWx0ICk7CgoJU2J4VmFyaWFibGUqIHBSZXQgPSBuZXcgU2J4VmFyaWFibGU7CglwUmV0LT5QdXRCb29sKCBiT2sgKTsKCVB1c2hWYXIoIHBSZXQgKTsKfQoKLy8gTGlicmFyeSBmdWVyIGFuc2NobGllc3NlbmRlbiBEZWNsYXJlLUNhbGwgZGVmaW5pZXJlbgoKdm9pZCBTYmlSdW50aW1lOjpTdGVwTElCKCBzYWxfdUludDMyIG5PcDEgKQp7CglhTGliTmFtZSA9IHBJbWctPkdldFN0cmluZyggc3RhdGljX2Nhc3Q8c2hvcnQ+KCBuT3AxICkgKTsKfQoKLy8gVE9TIHdpcmQgdW0gQkFTRSBlcmhvZWh0LCBCQVNFIGRhdm9yIGdlcHVzaHQgKCtCQVNFKQovLyBEaWVzZXIgT3Bjb2RlIHdpcmQgdm9yIERJTS9SRURJTS1BbndlaXN1bmdlbiBnZXB1c2h0LAovLyB3ZW5uIG51ciBlaW4gSW5kZXggYW5nZWdlYmVuIHd1cmRlLgoKdm9pZCBTYmlSdW50aW1lOjpTdGVwQkFTRUQoIHNhbF91SW50MzIgbk9wMSApCnsKCVNieFZhcmlhYmxlKiBwMSA9IG5ldyBTYnhWYXJpYWJsZTsKCVNieFZhcmlhYmxlUmVmIHgyID0gUG9wVmFyKCk7CgoJLy8gIzEwOTI3NSBDaGVjayBjb21wYXRpYmlsaXR5IG1vZGUKCWJvb2wgYkNvbXBhdGlibGUgPSAoKG5PcDEgJiAweDgwMDApICE9IDApOwoJc2FsX3VJbnQxNiB1QmFzZSA9IHN0YXRpY19jYXN0PHNhbF91SW50MTY+KG5PcDEgJiAxKTsJCS8vIENhbiBvbmx5IGJlIDAgb3IgMQoJcDEtPlB1dEludGVnZXIoIHVCYXNlICk7CglpZiggIWJDb21wYXRpYmxlICkKCQl4Mi0+Q29tcHV0ZSggU2J4UExVUywgKnAxICk7CglQdXNoVmFyKCB4MiApOwkvLyBlcnN0IGRpZSBFeHByCglQdXNoVmFyKCBwMSApOwkvLyBkYW5uIGRpZSBCYXNlCn0K