LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIAogKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCiAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgogKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCiAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQogKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqIAogKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKiAKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAogKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgogKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCiAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKICogdW5kZXIgdGhlIExpY2Vuc2UuCiAqIAogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCgoKLy8gTUFSS0VSKHVwZGF0ZV9wcmVjb21wLnB5KTogYXV0b2dlbiBpbmNsdWRlIHN0YXRlbWVudCwgZG8gbm90IHJlbW92ZQojaW5jbHVkZSAicHJlY29tcGlsZWRfYmFzaWMuaHh4IgoKI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8cnRsL21hdGguaHh4PgojaW5jbHVkZSA8YmFzaWMvc2J1bm8uaHh4PgojaW5jbHVkZSAicnVudGltZS5oeHgiCiNpbmNsdWRlICJzYmludGVybi5oeHgiCiNpbmNsdWRlICJpb3N5cy5oeHgiCiNpbmNsdWRlICJpbWFnZS5oeHgiCiNpbmNsdWRlICJzYnVub29iai5oeHgiCiNpbmNsdWRlICJlcnJvYmplY3QuaHh4IgoKYm9vbCBjaGVja1Vub09iamVjdFR5cGUoIFNiVW5vT2JqZWN0KiByZWZWYWwsIGNvbnN0IDo6cnRsOjpPVVN0cmluZyYgYUNsYXNzICk7CgovLyBMYWRlbiBlaW5lciBudW1lcmlzY2hlbiBLb25zdGFudGVuICgrSUQpCgp2b2lkIFNiaVJ1bnRpbWU6OlN0ZXBMT0FETkMoIHNhbF91SW50MzIgbk9wMSApCnsKCVNieFZhcmlhYmxlKiBwID0gbmV3IFNieFZhcmlhYmxlKCBTYnhET1VCTEUgKTsKCgkvLyAjNTc4NDQgTG9rYWxpc2llcnRlIEZ1bmt0aW9uIGJlbnV0emVuCglTdHJpbmcgYVN0ciA9IHBJbWctPkdldFN0cmluZyggc3RhdGljX2Nhc3Q8c2hvcnQ+KCBuT3AxICkgKTsKCS8vIEF1Y2ggLCB6dWxhc3NlbiAhISEKCXNhbF91SW50MTYgaUNvbW1hID0gYVN0ci5TZWFyY2goICcsJyApOwoJaWYoIGlDb21tYSAhPSBTVFJJTkdfTk9URk9VTkQgKQoJewoJCVN0cmluZyBhU3RyMSA9IGFTdHIuQ29weSggMCwgaUNvbW1hICk7CgkJU3RyaW5nIGFTdHIyID0gYVN0ci5Db3B5KCBpQ29tbWEgKyAxICk7CgkJYVN0ciA9IGFTdHIxOwoJCWFTdHIgKz0gJy4nOwoJCWFTdHIgKz0gYVN0cjI7Cgl9CiAgICBkb3VibGUgbiA9IDo6cnRsOjptYXRoOjpzdHJpbmdUb0RvdWJsZSggYVN0ciwgJy4nLCAnLCcsIE5VTEwsIE5VTEwgKTsKCglwLT5QdXREb3VibGUoIG4gKTsKCVB1c2hWYXIoIHAgKTsKfQoKLy8gTGFkZW4gZWluZXIgU3RyaW5na29uc3RhbnRlbiAoK0lEKQoKdm9pZCBTYmlSdW50aW1lOjpTdGVwTE9BRFNDKCBzYWxfdUludDMyIG5PcDEgKQp7CglTYnhWYXJpYWJsZSogcCA9IG5ldyBTYnhWYXJpYWJsZTsKCXAtPlB1dFN0cmluZyggcEltZy0+R2V0U3RyaW5nKCBzdGF0aWNfY2FzdDxzaG9ydD4oIG5PcDEgKSApICk7CglQdXNoVmFyKCBwICk7Cn0KCi8vIEltbWVkaWF0ZSBMb2FkICgrV2VydCkKCnZvaWQgU2JpUnVudGltZTo6U3RlcExPQURJKCBzYWxfdUludDMyIG5PcDEgKQp7CglTYnhWYXJpYWJsZSogcCA9IG5ldyBTYnhWYXJpYWJsZTsKCXAtPlB1dEludGVnZXIoIHN0YXRpY19jYXN0PHNhbF9JbnQxNj4oIG5PcDEgKSApOwoJUHVzaFZhciggcCApOwp9CgovLyBTcGVpY2hlcm4gZWluZXMgbmFtZWQgQXJndW1lbnRzIGluIEFyZ3YgKCtBcmctTnIgYWIgMSEpCgp2b2lkIFNiaVJ1bnRpbWU6OlN0ZXBBUkdOKCBzYWxfdUludDMyIG5PcDEgKQp7CglpZiggIXJlZkFyZ3YgKQoJCVN0YXJCQVNJQzo6RmF0YWxFcnJvciggU2JFUlJfSU5URVJOQUxfRVJST1IgKTsKCWVsc2UKCXsKCQlTdHJpbmcgYUFsaWFzKCBwSW1nLT5HZXRTdHJpbmcoIHN0YXRpY19jYXN0PHNob3J0Piggbk9wMSApICkgKTsKCQlTYnhWYXJpYWJsZVJlZiBwVmFsID0gUG9wVmFyKCk7CgkJcmVmQXJndi0+UHV0KCBwVmFsLCBuQXJnYyApOwoJCXJlZkFyZ3YtPlB1dEFsaWFzKCBhQWxpYXMsIG5BcmdjKysgKTsKCX0KfQoKLy8gS29udmVydGllcnVuZyBkZXMgVHlwcyBlaW5lcyBBcmd1bWVudHMgaW4gQXJndiBmdWVyIERFQ0xBUkUtRmt0LiAoK1R5cCkKCnZvaWQgU2JpUnVudGltZTo6U3RlcEFSR1RZUCggc2FsX3VJbnQzMiBuT3AxICkKewoJaWYoICFyZWZBcmd2ICkKCQlTdGFyQkFTSUM6OkZhdGFsRXJyb3IoIFNiRVJSX0lOVEVSTkFMX0VSUk9SICk7CgllbHNlCgl7CgkJc2FsX0Jvb2wgYkJ5VmFsID0gKG5PcDEgJiAweDgwMDApICE9IDA7CQkJLy8gSXN0IEJZVkFMIHZlcmxhbmd0PwoJCVNieERhdGFUeXBlIHQgPSAoU2J4RGF0YVR5cGUpIChuT3AxICYgMHg3RkZGKTsKCQlTYnhWYXJpYWJsZSogcFZhciA9IHJlZkFyZ3YtPkdldCggcmVmQXJndi0+Q291bnQoKSAtIDEgKTsJLy8gbGV0enRlcyBBcmcKCgkJLy8gQllWQUwgcHL8ZmVuCgkJaWYoIHBWYXItPkdldFJlZkNvdW50KCkgPiAyICkJCS8vIDIgaXN0IG5vcm1hbCBm/HIgQllWQUwKCQl7CgkJCS8vIFBhcmFtZXRlciBpc3QgZWluZSBSZWZlcmVuegoJCQlpZiggYkJ5VmFsICkKCQkJewoJCQkJLy8gQ2FsbCBieSBWYWx1ZSBpc3QgdmVybGFuZ3QgLT4gS29waWUgYW5sZWdlbgoJCQkJcFZhciA9IG5ldyBTYnhWYXJpYWJsZSggKnBWYXIgKTsKCQkJCXBWYXItPlNldEZsYWcoIFNCWF9SRUFEV1JJVEUgKTsKCQkJCXJlZkV4cHJTdGstPlB1dCggcFZhciwgcmVmQXJndi0+Q291bnQoKSAtIDEgKTsKCQkJfQoJCQllbHNlCgkJCQlwVmFyLT5TZXRGbGFnKCBTQlhfUkVGRVJFTkNFICk7CQkvLyBSZWYtRmxhZyBm/HIgRGxsTWdyCgkJfQoJCWVsc2UKCQl7CgkJCS8vIFBhcmFtZXRlciBpc3QgS0VJTkUgUmVmZXJlbnoKCQkJaWYoIGJCeVZhbCApCgkJCQlwVmFyLT5SZXNldEZsYWcoIFNCWF9SRUZFUkVOQ0UgKTsJLy8gS2VpbmUgUmVmZXJlbnogLT4gT0sKCQkJZWxzZQoJCQkJRXJyb3IoIFNiRVJSX0JBRF9QQVJBTUVURVJTICk7CQkvLyBSZWZlcmVueiB2ZXJsYW5ndAoJCX0KCgkJaWYoIHBWYXItPkdldFR5cGUoKSAhPSB0ICkKCQl7CgkJCS8vIFZhcmlhbnQsIGRhbWl0IHJpY2h0aWdlIEtvbnZlcnRpZXJ1bmcKCQkJLy8gQXVzc2VyZGVtIEZlaGxlciwgd2VubiBTYnhCWVJFRgoJCQlwVmFyLT5Db252ZXJ0KCBTYnhWQVJJQU5UICk7CgkJCXBWYXItPkNvbnZlcnQoIHQgKTsKCQl9Cgl9Cn0KCi8vIFN0cmluZyBhdWYgZmVzdGUgTGFlbmdlIGJyaW5nZW4gKCtMYWVuZ2UpCgp2b2lkIFNiaVJ1bnRpbWU6OlN0ZXBQQUQoIHNhbF91SW50MzIgbk9wMSApCnsKCVNieFZhcmlhYmxlKiBwID0gR2V0VE9TKCk7CglTdHJpbmcmIHMgPSAoU3RyaW5nJikoY29uc3QgU3RyaW5nJikgKnA7CglpZiggcy5MZW4oKSA+IG5PcDEgKQoJCXMuRXJhc2UoIHN0YXRpY19jYXN0PHh1Yl9TdHJMZW4+KCBuT3AxICkgKTsKCWVsc2UKCQlzLkV4cGFuZCggc3RhdGljX2Nhc3Q8eHViX1N0ckxlbj4oIG5PcDEgKSwgJyAnICk7Cn0KCi8vIFNwcnVuZyAoK1RhcmdldCkKCnZvaWQgU2JpUnVudGltZTo6U3RlcEpVTVAoIHNhbF91SW50MzIgbk9wMSApCnsKI2lmZGVmIERCR19VVElMCgkvLyAjUVVFU1RJT04gc2hvdWxuJ3QgdGhpcyBiZSAKCS8vIGlmKCAoc2FsX3VJbnQ4KikoIG5PcDErcEltYWdHZXRDb2RlKCkgKSA+PSBwSW1nLT5HZXRDb2RlU2l6ZSgpICkKCWlmKCBuT3AxID49IHBJbWctPkdldENvZGVTaXplKCkgKQoJCVN0YXJCQVNJQzo6RmF0YWxFcnJvciggU2JFUlJfSU5URVJOQUxfRVJST1IgKTsKI2VuZGlmCglwQ29kZSA9IChjb25zdCBzYWxfdUludDgqKSBwSW1nLT5HZXRDb2RlKCkgKyBuT3AxOwp9CgovLyBUT1MgYXVzd2VydGVuLCBiZWRpbmd0ZXIgU3BydW5nICgrVGFyZ2V0KQoKdm9pZCBTYmlSdW50aW1lOjpTdGVwSlVNUFQoIHNhbF91SW50MzIgbk9wMSApCnsKCVNieFZhcmlhYmxlUmVmIHAgPSBQb3BWYXIoKTsKCWlmKCBwLT5HZXRCb29sKCkgKQoJCVN0ZXBKVU1QKCBuT3AxICk7Cn0KCi8vIFRPUyBhdXN3ZXJ0ZW4sIGJlZGluZ3RlciBTcHJ1bmcgKCtUYXJnZXQpCgp2b2lkIFNiaVJ1bnRpbWU6OlN0ZXBKVU1QRiggc2FsX3VJbnQzMiBuT3AxICkKewoJU2J4VmFyaWFibGVSZWYgcCA9IFBvcFZhcigpOwoJaWYoICFwLT5HZXRCb29sKCkgKQoJCVN0ZXBKVU1QKCBuT3AxICk7Cn0KCi8vIFRPUyBhdXN3ZXJ0ZW4sIFNwcnVuZyBpbiBKVU1QLVRhYmVsbGUgKCtNYXhWYWwpCi8vIFNpZWh0IHNvIGF1czoKLy8gT05KVU1QIDIKLy8gSlVNUCB0YXJnZXQxCi8vIEpVTVAgdGFyZ2V0MgovLyAuLi4KLy9GYWxscyBpbSBPcGVyYW5kZW4gMHg4MDAwIGdlc2V0enQgaXN0LCBSZXR1cm5hZHJlc3NlIHB1c2hlbiAoT04uLkdPU1VCKQoKdm9pZCBTYmlSdW50aW1lOjpTdGVwT05KVU1QKCBzYWxfdUludDMyIG5PcDEgKQp7CglTYnhWYXJpYWJsZVJlZiBwID0gUG9wVmFyKCk7CglzYWxfSW50MTYgbiA9IHAtPkdldEludGVnZXIoKTsKCWlmKCBuT3AxICYgMHg4MDAwICkKCXsKCQluT3AxICY9IDB4N0ZGRjsKCQkvL1B1c2hHb3N1YiggcENvZGUgKyAzICogbk9wMSApOwoJCVB1c2hHb3N1YiggcENvZGUgKyA1ICogbk9wMSApOwoJfQoJaWYoIG4gPCAxIHx8IHN0YXRpY19jYXN0PHNhbF91SW50MzI+KG4pID4gbk9wMSApCgkJbiA9IHN0YXRpY19jYXN0PHNhbF9JbnQxNj4oIG5PcDEgKyAxICk7CgkvL25PcDEgPSAoc2FsX3VJbnQzMikgKCAoY29uc3QgY2hhciopIHBDb2RlIC0gcEltZy0+R2V0Q29kZSgpICkgKyAzICogLS1uOwoJbk9wMSA9IChzYWxfdUludDMyKSAoIChjb25zdCBjaGFyKikgcENvZGUgLSBwSW1nLT5HZXRDb2RlKCkgKSArIDUgKiAtLW47CglTdGVwSlVNUCggbk9wMSApOwp9CgovLyBVUC1BdWZydWYgKCtUYXJnZXQpCgp2b2lkIFNiaVJ1bnRpbWU6OlN0ZXBHT1NVQiggc2FsX3VJbnQzMiBuT3AxICkKewoJUHVzaEdvc3ViKCBwQ29kZSApOwoJaWYoIG5PcDEgPj0gcEltZy0+R2V0Q29kZVNpemUoKSApCgkJU3RhckJBU0lDOjpGYXRhbEVycm9yKCBTYkVSUl9JTlRFUk5BTF9FUlJPUiApOwoJcENvZGUgPSAoY29uc3Qgc2FsX3VJbnQ4KikgcEltZy0+R2V0Q29kZSgpICsgbk9wMTsKfQoKLy8gVVAtUmV0dXJuICgrMCBvZGVyIFRhcmdldCkKCnZvaWQgU2JpUnVudGltZTo6U3RlcFJFVFVSTiggc2FsX3VJbnQzMiBuT3AxICkKewoJUG9wR29zdWIoKTsKCWlmKCBuT3AxICkKCQlTdGVwSlVNUCggbk9wMSApOwp9CgovLyBGT1ItVmFyaWFibGUgdGVzdGVuICgrRW5kbGFiZWwpCgp2b2lkIFNiaVJ1bnRpbWU6OlN0ZXBURVNURk9SKCBzYWxfdUludDMyIG5PcDEgKQp7CglpZiggIXBGb3JTdGsgKQoJewoJCVN0YXJCQVNJQzo6RmF0YWxFcnJvciggU2JFUlJfSU5URVJOQUxfRVJST1IgKTsKCQlyZXR1cm47Cgl9CgoJYm9vbCBiRW5kTG9vcCA9IGZhbHNlOwoJc3dpdGNoKCBwRm9yU3RrLT5lRm9yVHlwZSApCgl7CgkJY2FzZSBGT1JfVE86CgkJewoJCQlTYnhPcGVyYXRvciBlT3AgPSAoIHBGb3JTdGstPnJlZkluYy0+R2V0RG91YmxlKCkgPCAwICkgPyBTYnhMVCA6IFNieEdUOwoJCQlpZiggcEZvclN0ay0+cmVmVmFyLT5Db21wYXJlKCBlT3AsICpwRm9yU3RrLT5yZWZFbmQgKSApCgkJCQliRW5kTG9vcCA9IHRydWU7CgkJCWJyZWFrOwoJCX0KCQljYXNlIEZPUl9FQUNIX0FSUkFZOgoJCXsKCQkJU2JpRm9yU3RhY2sqIHAgPSBwRm9yU3RrOwoJCQlpZiggcC0+cEFycmF5Q3VySW5kaWNlcyA9PSBOVUxMICkKCQkJewoJCQkJYkVuZExvb3AgPSB0cnVlOwoJCQl9CgkJCWVsc2UKCQkJewoJCQkJU2J4RGltQXJyYXkqIHBBcnJheSA9IChTYnhEaW1BcnJheSopKFNieFZhcmlhYmxlKilwLT5yZWZFbmQ7CgkJCQlzaG9ydCBuRGltcyA9IHBBcnJheS0+R2V0RGltcygpOwoKCQkJCS8vIEVtcHR5IGFycmF5PwoJCQkJaWYoIG5EaW1zID09IDEgJiYgcC0+cEFycmF5TG93ZXJCb3VuZHNbMF0gPiBwLT5wQXJyYXlVcHBlckJvdW5kc1swXSApCgkJCQl7CgkJCQkJYkVuZExvb3AgPSB0cnVlOwoJCQkJCWJyZWFrOwoJCQkJfQoJCQkJU2J4VmFyaWFibGUqIHBWYWwgPSBwQXJyYXktPkdldDMyKCBwLT5wQXJyYXlDdXJJbmRpY2VzICk7CgkJCQkqKHAtPnJlZlZhcikgPSAqcFZhbDsKCgkJCQlib29sIGJGb3VuZE5leHQgPSBmYWxzZTsKCQkJCWZvciggc2hvcnQgaSA9IDAgOyBpIDwgbkRpbXMgOyBpKysgKQoJCQkJewoJCQkJCWlmKCBwLT5wQXJyYXlDdXJJbmRpY2VzW2ldIDwgcC0+cEFycmF5VXBwZXJCb3VuZHNbaV0gKQoJCQkJCXsKCQkJCQkJYkZvdW5kTmV4dCA9IHRydWU7CgkJCQkJCXAtPnBBcnJheUN1ckluZGljZXNbaV0rKzsKCQkJCQkJZm9yKCBzaG9ydCBqID0gaSAtIDEgOyBqID49IDAgOyBqLS0gKQoJCQkJCQkJcC0+cEFycmF5Q3VySW5kaWNlc1tqXSA9IHAtPnBBcnJheUxvd2VyQm91bmRzW2pdOwoJCQkJCQlicmVhazsKCQkJCQl9CgkJCQl9CgkJCQlpZiggIWJGb3VuZE5leHQgKQoJCQkJewoJCQkJCWRlbGV0ZVtdIHAtPnBBcnJheUN1ckluZGljZXM7CgkJCQkJcC0+cEFycmF5Q3VySW5kaWNlcyA9IE5VTEw7CgkJCQl9CgkJCX0KCQkJYnJlYWs7CgkJfQoJCWNhc2UgRk9SX0VBQ0hfQ09MTEVDVElPTjoKCQl7CgkJCUJhc2ljQ29sbGVjdGlvbiogcENvbGxlY3Rpb24gPSAoQmFzaWNDb2xsZWN0aW9uKikoU2J4VmFyaWFibGUqKXBGb3JTdGstPnJlZkVuZDsKCQkJU2J4QXJyYXlSZWYgeEl0ZW1BcnJheSA9IHBDb2xsZWN0aW9uLT54SXRlbUFycmF5OwoJCQlzYWxfSW50MzIgbkNvdW50ID0geEl0ZW1BcnJheS0+Q291bnQzMigpOwoJCQlpZiggcEZvclN0ay0+bkN1ckNvbGxlY3Rpb25JbmRleCA8IG5Db3VudCApCgkJCXsKCQkJCVNieFZhcmlhYmxlKiBwUmVzID0geEl0ZW1BcnJheS0+R2V0MzIoIHBGb3JTdGstPm5DdXJDb2xsZWN0aW9uSW5kZXggKTsKCQkJCXBGb3JTdGstPm5DdXJDb2xsZWN0aW9uSW5kZXgrKzsKCQkJCSgqcEZvclN0ay0+cmVmVmFyKSA9ICpwUmVzOwoJCQl9CgkJCWVsc2UKCQkJewoJCQkJYkVuZExvb3AgPSB0cnVlOwoJCQl9CgkJCWJyZWFrOwoJCX0KCQljYXNlIEZPUl9FQUNIX1hFTlVNRVJBVElPTjoKCQl7CgkJCVNiaUZvclN0YWNrKiBwID0gcEZvclN0azsKCQkJaWYoIHAtPnhFbnVtZXJhdGlvbi0+aGFzTW9yZUVsZW1lbnRzKCkgKQoJCQl7CgkJCQlBbnkgYUVsZW0gPSBwLT54RW51bWVyYXRpb24tPm5leHRFbGVtZW50KCk7CgkJCQlTYnhWYXJpYWJsZVJlZiB4VmFyID0gbmV3IFNieFZhcmlhYmxlKCBTYnhWQVJJQU5UICk7CgkJCQl1bm9Ub1NieFZhbHVlKCAoU2J4VmFyaWFibGUqKXhWYXIsIGFFbGVtICk7CgkJCQkoKnBGb3JTdGstPnJlZlZhcikgPSAqeFZhcjsKCQkJfQoJCQllbHNlCgkJCXsKCQkJCWJFbmRMb29wID0gdHJ1ZTsKCQkJfQoJCQlicmVhazsKCQl9Cgl9CglpZiggYkVuZExvb3AgKQoJewoJCVBvcEZvcigpOwoJCVN0ZXBKVU1QKCBuT3AxICk7Cgl9Cn0KCi8vIFRvcysxIDw9IFRvcysyIDw9IFRvcywgMnhyZW1vdmUgKCtUYXJnZXQpCgp2b2lkIFNiaVJ1bnRpbWU6OlN0ZXBDQVNFVE8oIHNhbF91SW50MzIgbk9wMSApCnsKCWlmKCAhcmVmQ2FzZVN0ayB8fCAhcmVmQ2FzZVN0ay0+Q291bnQoKSApCgkJU3RhckJBU0lDOjpGYXRhbEVycm9yKCBTYkVSUl9JTlRFUk5BTF9FUlJPUiApOwoJZWxzZQoJewoJCVNieFZhcmlhYmxlUmVmIHhUbyAgID0gUG9wVmFyKCk7CgkJU2J4VmFyaWFibGVSZWYgeEZyb20gPSBQb3BWYXIoKTsKCQlTYnhWYXJpYWJsZVJlZiB4Q2FzZSA9IHJlZkNhc2VTdGstPkdldCggcmVmQ2FzZVN0ay0+Q291bnQoKSAtIDEgKTsKCQlpZiggKnhDYXNlID49ICp4RnJvbSAmJiAqeENhc2UgPD0gKnhUbyApCgkJCVN0ZXBKVU1QKCBuT3AxICk7Cgl9Cn0KCi8vIEZlaGxlci1IYW5kbGVyCgp2b2lkIFNiaVJ1bnRpbWU6OlN0ZXBFUlJIREwoIHNhbF91SW50MzIgbk9wMSApCnsKCWNvbnN0IHNhbF91SW50OCogcCA9IHBDb2RlOwoJU3RlcEpVTVAoIG5PcDEgKTsKCXBFcnJvciA9IHBDb2RlOwoJcENvZGUgPSBwOwoJcEluc3QtPmFFcnJvck1zZyA9IFN0cmluZygpOwoJcEluc3QtPm5FcnIgPSAwOwoJcEluc3QtPm5FcmwgPSAwOwoJbkVycm9yID0gMDsKCVNieEVyck9iamVjdDo6Z2V0VW5vRXJyT2JqZWN0KCktPkNsZWFyKCk7Cn0KCi8vIFJlc3VtZSBuYWNoIEZlaGxlcm4gKCswPXN0YXRlbWVudCwgMT1uZXh0IG9yIExhYmVsKQoKdm9pZCBTYmlSdW50aW1lOjpTdGVwUkVTVU1FKCBzYWxfdUludDMyIG5PcDEgKQp7CgkvLyBBQiAjMzI3MTQgUmVzdW1lIG9obmUgRXJyb3I/IC0+IEZlaGxlcgoJaWYoICFiSW5FcnJvciApCgl7CgkJRXJyb3IoIFNiRVJSX0JBRF9SRVNVTUUgKTsKCQlyZXR1cm47Cgl9CglpZiggbk9wMSApCgl7CgkJLy8gQ29kZS1aZWlnZXIgYXVmIG5hZWNoc3RlcyBTdGF0ZW1lbnQgc2V0emVuCgkJc2FsX3VJbnQxNiBuMSwgbjI7CgkJcENvZGUgPSBwTW9kLT5GaW5kTmV4dFN0bW50KCBwRXJyQ29kZSwgbjEsIG4yLCBzYWxfVHJ1ZSwgcEltZyApOwoJfQoJZWxzZQoJCXBDb2RlID0gcEVyclN0bW50OwoJaWYgKCBwRXJyb3IgKSAvLyBjdXJyZW50IGluIGVycm9yIGhhbmRsZXIgKCBhbmQgZ290IGEgUmVzdW1lIE5leHQgc3RhdG1lbnQgKQoJCVNieEVyck9iamVjdDo6Z2V0VW5vRXJyT2JqZWN0KCktPkNsZWFyKCk7CgoJaWYoIG5PcDEgPiAxICkKCQlTdGVwSlVNUCggbk9wMSApOwoJcEluc3QtPmFFcnJvck1zZyA9IFN0cmluZygpOwoJcEluc3QtPm5FcnIgPSAwOwoJcEluc3QtPm5FcmwgPSAwOwoJbkVycm9yID0gMDsKCWJJbkVycm9yID0gc2FsX0ZhbHNlOwoKCS8vIEVycm9yLVN0YWNrIGxvZXNjaGVuCglTYkVycm9yU3RhY2sqJiByRXJyU3RhY2sgPSBHZXRTYkRhdGEoKS0+cEVyclN0YWNrOwoJZGVsZXRlIHJFcnJTdGFjazsKCXJFcnJTdGFjayA9IE5VTEw7Cn0KCi8vIEthbmFsIHNjaGxpZXNzZW4gKCtLYW5hbCwgMD1BbGxlKQp2b2lkIFNiaVJ1bnRpbWU6OlN0ZXBDTE9TRSggc2FsX3VJbnQzMiBuT3AxICkKewoJU2JFcnJvciBlcnI7CglpZiggIW5PcDEgKQoJCXBJb3N5cy0+U2h1dGRvd24oKTsKCWVsc2UKCXsKCQllcnIgPSBwSW9zeXMtPkdldEVycm9yKCk7CgkJaWYoICFlcnIgKQoJCXsKCQkJcElvc3lzLT5DbG9zZSgpOwoJCX0KCX0KCWVyciA9IHBJb3N5cy0+R2V0RXJyb3IoKTsKCUVycm9yKCBlcnIgKTsKfQoKLy8gWmVpY2hlbiBhdXNnZWJlbiAoK2NoYXIpCgp2b2lkIFNiaVJ1bnRpbWU6OlN0ZXBQUkNIQVIoIHNhbF91SW50MzIgbk9wMSApCnsKCUJ5dGVTdHJpbmcgcyggKGNoYXIpIG5PcDEgKTsKCXBJb3N5cy0+V3JpdGUoIHMgKTsKCUVycm9yKCBwSW9zeXMtPkdldEVycm9yKCkgKTsKfQoKLy8gQ2hlY2ssIG9iIFRPUyBlaW5lIGJlc3RpbW10ZSBPYmpla3RrbGFzc2UgaXN0ICgrU3RyaW5nSUQpCgpib29sIFNiaVJ1bnRpbWU6OmltcGxJc0NsYXNzKCBTYnhPYmplY3QqIHBPYmosIGNvbnN0IFN0cmluZyYgYUNsYXNzICkKewoJYm9vbCBiUmV0ID0gdHJ1ZTsKCglpZiggYUNsYXNzLkxlbigpICE9IDAgKQoJewoJCWJSZXQgPSBwT2JqLT5Jc0NsYXNzKCBhQ2xhc3MgKTsKCQlpZiggIWJSZXQgKQoJCQliUmV0ID0gYUNsYXNzLkVxdWFsc0lnbm9yZUNhc2VBc2NpaSggU3RyaW5nKCBSVExfQ09OU1RBU0NJSV9VU1RSSU5HUEFSQU0oIm9iamVjdCIpICkgKTsKCQlpZiggIWJSZXQgKQoJCXsKCQkJU3RyaW5nIGFPYmpDbGFzcyA9IHBPYmotPkdldENsYXNzTmFtZSgpOwoJCQlTYk1vZHVsZSogcENsYXNzTW9kID0gcENMQVNTRkFDLT5GaW5kQ2xhc3MoIGFPYmpDbGFzcyApOwoJCQlTYkNsYXNzRGF0YSogcENsYXNzRGF0YTsKCQkJaWYoIHBDbGFzc01vZCAmJiAocENsYXNzRGF0YT1wQ2xhc3NNb2QtPnBDbGFzc0RhdGEpICE9IE5VTEwgKQoJCQl7CgkJCQlTYnhWYXJpYWJsZSogcENsYXNzVmFyID0gCgkJCQkJcENsYXNzRGF0YS0+bXhJZmFjZXMtPkZpbmQoIGFDbGFzcywgU2J4Q0xBU1NfRE9OVENBUkUgKTsKCQkJCWJSZXQgPSAocENsYXNzVmFyICE9IE5VTEwpOwoJCQl9CgkJfQoJfQoJcmV0dXJuIGJSZXQ7Cn0KCmJvb2wgU2JpUnVudGltZTo6Y2hlY2tDbGFzc19JbXBsKCBjb25zdCBTYnhWYXJpYWJsZVJlZiYgcmVmVmFsLCAKCWNvbnN0IFN0cmluZyYgYUNsYXNzLCBib29sIGJSYWlzZUVycm9ycywgYm9vbCBiRGVmYXVsdCApCnsKCWJvb2wgYk9rID0gYkRlZmF1bHQ7CgoJU2J4RGF0YVR5cGUgdCA9IHJlZlZhbC0+R2V0VHlwZSgpOwoJaWYoIHQgPT0gU2J4T0JKRUNUICkKCXsKCQlTYnhPYmplY3QqIHBPYmo7CgkJU2J4VmFyaWFibGUqIHBWYWwgPSAoU2J4VmFyaWFibGUqKXJlZlZhbDsKCQlpZiggcFZhbC0+SXNBKCBUWVBFKFNieE9iamVjdCkgKSApCgkJCXBPYmogPSAoU2J4T2JqZWN0KikgcFZhbDsKCQllbHNlCgkJewoJCQlwT2JqID0gKFNieE9iamVjdCopIHJlZlZhbC0+R2V0T2JqZWN0KCk7CgkJCWlmKCBwT2JqICYmICFwT2JqLT5Jc0EoIFRZUEUoU2J4T2JqZWN0KSApICkKCQkJCXBPYmogPSBOVUxMOwoJCX0KCQlpZiggcE9iaiApCgkJewoJCQlpZiggIWltcGxJc0NsYXNzKCBwT2JqLCBhQ2xhc3MgKSApCgkJCXsKCQkJCWlmICggYlZCQUVuYWJsZWQgJiYgcE9iai0+SXNBKCBUWVBFKFNiVW5vT2JqZWN0KSApICkKCQkJCXsKCQkJCQlTYlVub09iamVjdCogcFVub09iaiA9IFBUUl9DQVNUKFNiVW5vT2JqZWN0LHBPYmopOwoJCQkJCWJPayA9IGNoZWNrVW5vT2JqZWN0VHlwZSggcFVub09iaiwgYUNsYXNzICk7CgkJCQl9CgkJCQllbHNlCgkJCQkJYk9rID0gZmFsc2U7CgkJCQlpZiAoICFiT2sgKQoJCQkJewoJCQkJCWlmKCBiUmFpc2VFcnJvcnMgKQoJCQkJCQlFcnJvciggU2JFUlJfSU5WQUxJRF9VU0FHRV9PQkpFQ1QgKTsKCQkJCX0KCQkJfQoJCQllbHNlCgkJCXsKCQkJCWJPayA9IHRydWU7CgoJCQkJU2JDbGFzc01vZHVsZU9iamVjdCogcENsYXNzTW9kdWxlT2JqZWN0ID0gUFRSX0NBU1QoU2JDbGFzc01vZHVsZU9iamVjdCxwT2JqKTsKCQkJCWlmKCBwQ2xhc3NNb2R1bGVPYmplY3QgIT0gTlVMTCApCgkJCQkJcENsYXNzTW9kdWxlT2JqZWN0LT50cmlnZ2VySW5pdGlhbGl6ZUV2ZW50KCk7CgkJCX0KCQl9Cgl9CgllbHNlCgl7CgkJaWYgKCAhYlZCQUVuYWJsZWQgKQoJCXsKCQkJaWYoIGJSYWlzZUVycm9ycyApCgkJCQlFcnJvciggU2JFUlJfTkVFRFNfT0JKRUNUICk7CgkJCWJPayA9IGZhbHNlOwoJCX0KCX0KCXJldHVybiBiT2s7Cn0KCnZvaWQgU2JpUnVudGltZTo6U3RlcFNFVENMQVNTX2ltcGwoIHNhbF91SW50MzIgbk9wMSwgYm9vbCBiSGFuZGxlRGZsdCApCnsKCVNieFZhcmlhYmxlUmVmIHJlZlZhbCA9IFBvcFZhcigpOwoJU2J4VmFyaWFibGVSZWYgcmVmVmFyID0gUG9wVmFyKCk7CglTdHJpbmcgYUNsYXNzKCBwSW1nLT5HZXRTdHJpbmcoIHN0YXRpY19jYXN0PHNob3J0Piggbk9wMSApICkgKTsKCglib29sIGJPayA9IGNoZWNrQ2xhc3NfSW1wbCggcmVmVmFsLCBhQ2xhc3MsIHRydWUgKTsKCWlmKCBiT2sgKQoJCVN0ZXBTRVRfSW1wbCggcmVmVmFsLCByZWZWYXIsIGJIYW5kbGVEZmx0ICk7IC8vIGRvbid0IGRvIGhhbmRsZSBkZmx0IHByb3AgZm9yIGEgInByb3BlciIgc2V0Cn0KCnZvaWQgU2JpUnVudGltZTo6U3RlcFZCQVNFVENMQVNTKCBzYWxfdUludDMyIG5PcDEgKQp7CglTdGVwU0VUQ0xBU1NfaW1wbCggbk9wMSwgZmFsc2UgKTsKfQoKdm9pZCBTYmlSdW50aW1lOjpTdGVwU0VUQ0xBU1MoIHNhbF91SW50MzIgbk9wMSApCnsKCVN0ZXBTRVRDTEFTU19pbXBsKCBuT3AxLCB0cnVlICk7Cn0KCnZvaWQgU2JpUnVudGltZTo6U3RlcFRFU1RDTEFTUyggc2FsX3VJbnQzMiBuT3AxICkKewoJU2J4VmFyaWFibGVSZWYgeE9ialZhbCA9IFBvcFZhcigpOwoJU3RyaW5nIGFDbGFzcyggcEltZy0+R2V0U3RyaW5nKCBzdGF0aWNfY2FzdDxzaG9ydD4oIG5PcDEgKSApICk7Cglib29sIGJEZWZhdWx0ID0gIWJWQkFFbmFibGVkOwoJYm9vbCBiT2sgPSBjaGVja0NsYXNzX0ltcGwoIHhPYmpWYWwsIGFDbGFzcywgZmFsc2UsIGJEZWZhdWx0ICk7CgoJU2J4VmFyaWFibGUqIHBSZXQgPSBuZXcgU2J4VmFyaWFibGU7CglwUmV0LT5QdXRCb29sKCBiT2sgKTsKCVB1c2hWYXIoIHBSZXQgKTsKfQoKLy8gTGlicmFyeSBmdWVyIGFuc2NobGllc3NlbmRlbiBEZWNsYXJlLUNhbGwgZGVmaW5pZXJlbgoKdm9pZCBTYmlSdW50aW1lOjpTdGVwTElCKCBzYWxfdUludDMyIG5PcDEgKQp7CglhTGliTmFtZSA9IHBJbWctPkdldFN0cmluZyggc3RhdGljX2Nhc3Q8c2hvcnQ+KCBuT3AxICkgKTsKfQoKLy8gVE9TIHdpcmQgdW0gQkFTRSBlcmhvZWh0LCBCQVNFIGRhdm9yIGdlcHVzaHQgKCtCQVNFKQovLyBEaWVzZXIgT3Bjb2RlIHdpcmQgdm9yIERJTS9SRURJTS1BbndlaXN1bmdlbiBnZXB1c2h0LAovLyB3ZW5uIG51ciBlaW4gSW5kZXggYW5nZWdlYmVuIHd1cmRlLgoKdm9pZCBTYmlSdW50aW1lOjpTdGVwQkFTRUQoIHNhbF91SW50MzIgbk9wMSApCnsKCVNieFZhcmlhYmxlKiBwMSA9IG5ldyBTYnhWYXJpYWJsZTsKCVNieFZhcmlhYmxlUmVmIHgyID0gUG9wVmFyKCk7CgoJLy8gIzEwOTI3NSBDaGVjayBjb21wYXRpYmxpdHkgbW9kZQoJYm9vbCBiQ29tcGF0aWJsZSA9ICgobk9wMSAmIDB4ODAwMCkgIT0gMCk7CglzYWxfdUludDE2IHVCYXNlID0gc3RhdGljX2Nhc3Q8c2FsX3VJbnQxNj4obk9wMSAmIDEpOwkJLy8gQ2FuIG9ubHkgYmUgMCBvciAxCglwMS0+UHV0SW50ZWdlciggdUJhc2UgKTsKCWlmKCAhYkNvbXBhdGlibGUgKQoJCXgyLT5Db21wdXRlKCBTYnhQTFVTLCAqcDEgKTsKCVB1c2hWYXIoIHgyICk7CS8vIGVyc3QgZGllIEV4cHIKCVB1c2hWYXIoIHAxICk7CS8vIGRhbm4gZGllIEJhc2UKfQoKCgoKCg==