LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIAogKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCiAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgogKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCiAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQogKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqIAogKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKiAKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAogKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgogKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCiAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKICogdW5kZXIgdGhlIExpY2Vuc2UuCiAqIAogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCgoKLy8gTUFSS0VSKHVwZGF0ZV9wcmVjb21wLnB5KTogYXV0b2dlbiBpbmNsdWRlIHN0YXRlbWVudCwgZG8gbm90IHJlbW92ZQojaW5jbHVkZSAicHJlY29tcGlsZWRfZGJhY2Nlc3MuaHh4IgojaWZuZGVmIERCQVVJX1FVRVJZREVTSUdOVklFV19IWFgKI2luY2x1ZGUgIlF1ZXJ5RGVzaWduVmlldy5oeHgiCiNlbmRpZgojaWZuZGVmIERCQVVJX1FVRVJZVEFCTEVWSUVXX0hYWAojaW5jbHVkZSAiUXVlcnlUYWJsZVZpZXcuaHh4IgojZW5kaWYKI2lmbmRlZiBEQkFVSV9RVUVSWV9UQUJMRVdJTkRPV19IWFgKI2luY2x1ZGUgIlFUYWJsZVdpbmRvdy5oeHgiCiNlbmRpZgojaWZuZGVmIF9TVl9UT09MQk9YX0hYWAojaW5jbHVkZSA8dmNsL3Rvb2xib3guaHh4PgojZW5kaWYKI2lmbmRlZiBEQkFVSV9RVUVSWUNPTlRST0xMRVJfSFhYCiNpbmNsdWRlICJxdWVyeWNvbnRyb2xsZXIuaHh4IgojZW5kaWYKI2lmbmRlZiBfU1ZfU1BMSVRfSFhYCiNpbmNsdWRlIDx2Y2wvc3BsaXQuaHh4PgojZW5kaWYKI2lmbmRlZiBfVU5ET19IWFgKI2luY2x1ZGUgPHN2bC91bmRvLmh4eD4KI2VuZGlmCiNpZm5kZWYgVE9PTFNfRElBR05PU0VfRVhfSAojaW5jbHVkZSA8dG9vbHMvZGlhZ25vc2VfZXguaD4KI2VuZGlmCiNpZm5kZWYgREJBVUlfUVlETEdUQUJfSFhYCiNpbmNsdWRlICJhZHRhYmRsZy5oeHgiCiNlbmRpZgojaWZuZGVmIF9TVl9TVkFQUF9IWFgKI2luY2x1ZGUgPHZjbC9zdmFwcC5oeHg+CiNlbmRpZgojaWZuZGVmIF9TVl9DT01CT0JPWF9IWFgKI2luY2x1ZGUgPHZjbC9jb21ib2JveC5oeHg+CiNlbmRpZgojaWZuZGVmIF9TVl9NU0dCT1hfSFhYCiNpbmNsdWRlIDx2Y2wvbXNnYm94Lmh4eD4KI2VuZGlmCiNpZm5kZWYgREJBQ0NFU1NfVUlfQlJPV1NFUl9JRF9IWFgKI2luY2x1ZGUgImJyb3dzZXJpZHMuaHh4IgojZW5kaWYKI2lmbmRlZiBEQkFVSV9RVUVSWURFU0lHTl9PU0VMRUNUSU9OQlJPV1NFQk9YX0hYWAojaW5jbHVkZSAiU2VsZWN0aW9uQnJvd3NlQm94Lmh4eCIKI2VuZGlmCiNpZm5kZWYgX0RCVV9RUllfSFJDXwojaW5jbHVkZSAiZGJ1X3FyeS5ocmMiCiNlbmRpZgojaWZuZGVmIF9VVExfQ09ORklHTUdSX0hYWF8KI2luY2x1ZGUgPHVub3Rvb2xzL2NvbmZpZ21nci5oeHg+CiNlbmRpZgojaWZuZGVmIF9DT01QSEVMUEVSX1RZUEVTX0hYWF8KI2luY2x1ZGUgPGNvbXBoZWxwZXIvdHlwZXMuaHh4PgojZW5kaWYKI2lmbmRlZiBfQ09OTkVDVElWSVRZX0RCVE9PTFNfSFhYXwojaW5jbHVkZSA8Y29ubmVjdGl2aXR5L2RidG9vbHMuaHh4PgojZW5kaWYKI2lmbmRlZiBfREJIRUxQRVJfREJFWENFUFRJT05fSFhYXwojaW5jbHVkZSA8Y29ubmVjdGl2aXR5L2RiZXhjZXB0aW9uLmh4eD4KI2VuZGlmCiNpZm5kZWYgX0NPTV9TVU5fU1RBUl9JMThOX1hMT0NBTEVEQVRBX0hQUF8KI2luY2x1ZGUgPGNvbS9zdW4vc3Rhci9pMThuL1hMb2NhbGVEYXRhLmhwcD4KI2VuZGlmCiNpZm5kZWYgX0NPTV9TVU5fU1RBUl9TREJDX0RBVEFUWVBFX0hQUF8KI2luY2x1ZGUgPGNvbS9zdW4vc3Rhci9zZGJjL0RhdGFUeXBlLmhwcD4KI2VuZGlmCiNpZm5kZWYgX0NPTV9TVU5fU1RBUl9DT05UQUlORVJfWE5BTUVBQ0NFU1NfSFBQXwojaW5jbHVkZSA8Y29tL3N1bi9zdGFyL2NvbnRhaW5lci9YTmFtZUFjY2Vzcy5ocHA+CiNlbmRpZgojaWZuZGVmIF9DT01fU1VOX1NUQVJfU0RCQ19DT0xVTU5WQUxVRV9IUFBfCiNpbmNsdWRlIDxjb20vc3VuL3N0YXIvc2RiYy9Db2x1bW5WYWx1ZS5ocHA+CiNlbmRpZgojaWZuZGVmIF9DT05ORUNUSVZJVFlfUENPTFVNTl9IWFhfCiNpbmNsdWRlIDxjb25uZWN0aXZpdHkvUENvbHVtbi5oeHg+CiNlbmRpZgojaWZuZGVmIERCQVVJX1FVRVJZVEFCTEVDT05ORUNUSU9OX0hYWAojaW5jbHVkZSAiUVRhYmxlQ29ubmVjdGlvbi5oeHgiCiNlbmRpZgojaWZuZGVmIERCQVVJX0NPTk5FQ1RJT05MSU5FX0hYWAojaW5jbHVkZSAiQ29ubmVjdGlvbkxpbmUuaHh4IgojZW5kaWYKI2lmbmRlZiBEQkFVSV9DT05ORUNUSU9OTElORURBVEFfSFhYCiNpbmNsdWRlICJDb25uZWN0aW9uTGluZURhdGEuaHh4IgojZW5kaWYKI2lmbmRlZiBEQkFVSV9RVEFCTEVDT05ORUNUSU9OREFUQV9IWFgKI2luY2x1ZGUgIlFUYWJsZUNvbm5lY3Rpb25EYXRhLmh4eCIKI2VuZGlmCiNpZm5kZWYgREJBQ0NFU1NfU0hBUkVEX0RCVVNUUklOR1NfSFJDCiNpbmNsdWRlICJkYnVzdHJpbmdzLmhyYyIKI2VuZGlmCiNpZm5kZWYgX0NPTVBIRUxQRVJfRVhUUkFDVF9IWFhfCiNpbmNsdWRlIDxjb21waGVscGVyL2V4dHJhY3QuaHh4PgojZW5kaWYKI2lmbmRlZiBEQkFVSV9UT09MU19IWFgKI2luY2x1ZGUgIlVJVG9vbHMuaHh4IgojZW5kaWYKI2lmbmRlZiBEQkFVSV9RVUVSWUNPTlRBSU5FUldJTkRPV19IWFgKI2luY2x1ZGUgInF1ZXJ5Y29udGFpbmVyd2luZG93Lmh4eCIKI2VuZGlmCiNpZm5kZWYgREJBVUlfUVVFUllUQUJMRVZJRVdfSFhYCiNpbmNsdWRlICJRdWVyeVRhYmxlVmlldy5oeHgiCiNlbmRpZgojaWZuZGVmIF9EQkFVSV9TUUxNRVNTQUdFX0hYWF8KI2luY2x1ZGUgInNxbG1lc3NhZ2UuaHh4IgojZW5kaWYKI2lmbmRlZiBJTkNMVURFRF9TVlRPT0xTX1NZU0xPQ0FMRV9IWFgKI2luY2x1ZGUgPHVub3Rvb2xzL3N5c2xvY2FsZS5oeHg+CiNlbmRpZgoKdXNpbmcgbmFtZXNwYWNlIDo6ZGJhdWk7CnVzaW5nIG5hbWVzcGFjZSA6OnV0bDsKdXNpbmcgbmFtZXNwYWNlIDo6Y29ubmVjdGl2aXR5Owp1c2luZyBuYW1lc3BhY2UgOjpkYnRvb2xzOwp1c2luZyBuYW1lc3BhY2UgOjpjb206OnN1bjo6c3Rhcjo6dW5vOwp1c2luZyBuYW1lc3BhY2UgOjpjb206OnN1bjo6c3Rhcjo6bGFuZzsKdXNpbmcgbmFtZXNwYWNlIDo6Y29tOjpzdW46OnN0YXI6OmkxOG47CnVzaW5nIG5hbWVzcGFjZSA6OmNvbTo6c3VuOjpzdGFyOjpzZGJjOwp1c2luZyBuYW1lc3BhY2UgOjpjb206OnN1bjo6c3Rhcjo6YmVhbnM7CnVzaW5nIG5hbWVzcGFjZSA6OmNvbTo6c3VuOjpzdGFyOjpjb250YWluZXI7CgojZGVmaW5lIFNRTF9JU1JVTEVPUjIocFBhcnNlTm9kZSwgZTEsZTIpIAkoKHBQYXJzZU5vZGUpLT5pc1J1bGUoKSAmJiAoXAoJCQkJCQkJCQkJCShwUGFyc2VOb2RlKS0+Z2V0UnVsZUlEKCkgPT0gT1NRTFBhcnNlcjo6UnVsZUlEKE9TUUxQYXJzZU5vZGU6OmUxKSB8fCBcCgkJCQkJCQkJCQkJKHBQYXJzZU5vZGUpLT5nZXRSdWxlSUQoKSA9PSBPU1FMUGFyc2VyOjpSdWxlSUQoT1NRTFBhcnNlTm9kZTo6ZTIpKSkKCi8vIGhlcmUgd2UgZGVmaW5lIG91ciBmdW5jdGlvbnMgdXNlZCBpbiB0aGUgYW5vbnltb3VzIG5hbWVzcGFjZSB0byBnZXQgb3VyIGhlYWRlciBmaWxlIHNtYWxsZXIKLy8gcGxlYXNlIGxvb2sgYXQgdGhlIGJvb2sgTGFyZ2VTY2FsZSBDKysgdG8ga25vdyB3aHkKbmFtZXNwYWNlCnsKCXN0YXRpYyBjb25zdCA6OnJ0bDo6T1VTdHJpbmcgQ19BTkQgPSA6OnJ0bDo6T1VTdHJpbmc6OmNyZWF0ZUZyb21Bc2NpaSgiIEFORCAiKTsKCXN0YXRpYyBjb25zdCA6OnJ0bDo6T1VTdHJpbmcgQ19PUiAgPSA6OnJ0bDo6T1VTdHJpbmc6OmNyZWF0ZUZyb21Bc2NpaSgiIE9SICIpOwoKCS8vIGZvcndhcmQgZGVjbGFyYXRpb25zCglzYWxfQm9vbCBJbnNlcnRKb2luKAljb25zdCBPUXVlcnlEZXNpZ25WaWV3KiBfcFZpZXcsCgkJCQkJCQljb25zdCA6OmNvbm5lY3Rpdml0eTo6T1NRTFBhcnNlTm9kZSAqcE5vZGUpOwoKCVNxbFBhcnNlRXJyb3IgSW5zdGFsbEZpZWxkcyhPUXVlcnlEZXNpZ25WaWV3KiBfcFZpZXcsCgkJCQkJCQkJY29uc3QgOjpjb25uZWN0aXZpdHk6Ok9TUUxQYXJzZU5vZGUqIHBOb2RlLAoJCQkJCQkJCU9Kb2luVGFibGVWaWV3OjpPVGFibGVXaW5kb3dNYXAqIHBUYWJMaXN0ICk7CgoJU3FsUGFyc2VFcnJvciBHZXRHcm91cENyaXRlcmlhKAlPUXVlcnlEZXNpZ25WaWV3KiBfcFZpZXcsCgkJCQkJCQkJCU9TZWxlY3Rpb25Ccm93c2VCb3gqIF9wU2VsZWN0aW9uQnJ3LAoJCQkJCQkJCQljb25zdCA6OmNvbm5lY3Rpdml0eTo6T1NRTFBhcnNlTm9kZSogcFNlbGVjdFJvb3QgKTsKCglTcWxQYXJzZUVycm9yIEdldEhhdmluZ0NyaXRlcmlhKE9RdWVyeURlc2lnblZpZXcqIF9wVmlldywKCQkJCQkJCQkJT1NlbGVjdGlvbkJyb3dzZUJveCogX3BTZWxlY3Rpb25CcncsCgkJCQkJCQkJCWNvbnN0IDo6Y29ubmVjdGl2aXR5OjpPU1FMUGFyc2VOb2RlKiBwU2VsZWN0Um9vdCwKCQkJCQkJCQkJc2FsX3VJbnQxNiYgckxldmVsICk7CgoJU3FsUGFyc2VFcnJvciBHZXRPcmRlckNyaXRlcmlhKAlPUXVlcnlEZXNpZ25WaWV3KiBfcFZpZXcsCgkJCQkJCQkJCU9TZWxlY3Rpb25Ccm93c2VCb3gqIF9wU2VsZWN0aW9uQnJ3LAoJCQkJCQkJCQljb25zdCA6OmNvbm5lY3Rpdml0eTo6T1NRTFBhcnNlTm9kZSogcFBhcnNlUm9vdCApOwoKCVNxbFBhcnNlRXJyb3IgQWRkRnVuY3Rpb25Db25kaXRpb24oT1F1ZXJ5RGVzaWduVmlldyogX3BWaWV3LAoJCQkJCQkJCQlPU2VsZWN0aW9uQnJvd3NlQm94KiBfcFNlbGVjdGlvbkJydywKCQkJCQkJCQkJY29uc3QgOjpjb25uZWN0aXZpdHk6Ok9TUUxQYXJzZU5vZGUgKiBwQ29uZGl0aW9uLAoJCQkJCQkJCQljb25zdCBzYWxfdUludDE2IG5MZXZlbCwKCQkJCQkJCQkJc2FsX0Jvb2wgYkhhdmluZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBfYkFkZE9yT25PbmVMaW5lKTsKCgkvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoJOjpydGw6Ok9VU3RyaW5nIHF1b3RlVGFibGVBbGlhcyhzYWxfQm9vbCBfYlF1b3RlLCBjb25zdCA6OnJ0bDo6T1VTdHJpbmcmIF9zQWxpYXNOYW1lLCBjb25zdCA6OnJ0bDo6T1VTdHJpbmcmIF9zUXVvdGUpCgl7CgkJOjpydGw6Ok9VU3RyaW5nIHNSZXQ7CgkJaWYgKCBfYlF1b3RlICYmIF9zQWxpYXNOYW1lLmdldExlbmd0aCgpICkKCQl7CgkJCXNSZXQgPSA6OmRidG9vbHM6OnF1b3RlTmFtZShfc1F1b3RlLF9zQWxpYXNOYW1lKTsKCQkJY29uc3Qgc3RhdGljIDo6cnRsOjpPVVN0cmluZyBzVGFibGVTZXBhcmF0ZXIoJy4nKTsKCQkJc1JldCArPSBzVGFibGVTZXBhcmF0ZXI7CgkJfQoJCXJldHVybiBzUmV0OwoJfQogICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgIDo6cnRsOjpPVVN0cmluZyBnZXRUYWJsZVJhbmdlKGNvbnN0IE9RdWVyeURlc2lnblZpZXcqIF9wVmlldyxjb25zdCA6OmNvbm5lY3Rpdml0eTo6T1NRTFBhcnNlTm9kZSogX3BUYWJsZVJlZikKICAgIHsKICAgICAgICBSZWZlcmVuY2U8IFhDb25uZWN0aW9uPiB4Q29ubmVjdGlvbiA9IHN0YXRpY19jYXN0PE9RdWVyeUNvbnRyb2xsZXImPihfcFZpZXctPmdldENvbnRyb2xsZXIoKSkuZ2V0Q29ubmVjdGlvbigpOwogICAgICAgIDo6cnRsOjpPVVN0cmluZyBzVGFibGVSYW5nZTsKICAgICAgICBpZiAoIF9wVGFibGVSZWYgKQogICAgICAgIHsKICAgICAgICAgICAgc1RhYmxlUmFuZ2UgPSA6OmNvbm5lY3Rpdml0eTo6T1NRTFBhcnNlTm9kZTo6Z2V0VGFibGVSYW5nZShfcFRhYmxlUmVmKTsKICAgICAgICAgICAgaWYgKCAhc1RhYmxlUmFuZ2UuZ2V0TGVuZ3RoKCkgKQogICAgICAgICAgICAgICAgX3BUYWJsZVJlZi0+cGFyc2VOb2RlVG9TdHIoc1RhYmxlUmFuZ2UseENvbm5lY3Rpb24sTlVMTCxzYWxfRmFsc2Usc2FsX0ZhbHNlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHNUYWJsZVJhbmdlOwogICAgfQogICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgIHZvaWQgaW5zZXJ0Q29ubmVjdGlvbihjb25zdCBPUXVlcnlEZXNpZ25WaWV3KiBfcFZpZXcsY29uc3QgRUpvaW5UeXBlJiBfZUpvaW5UeXBlLE9UYWJsZUZpZWxkRGVzY1JlZiBfYURyYWdMZWZ0LE9UYWJsZUZpZWxkRGVzY1JlZiBfYURyYWdSaWdodCxib29sIF9iTmF0dXJhbCA9IGZhbHNlKQogICAgewogICAgICAgIE9RdWVyeVRhYmxlVmlldyogcFRhYmxlVmlldyA9IHN0YXRpY19jYXN0PE9RdWVyeVRhYmxlVmlldyo+KF9wVmlldy0+Z2V0VGFibGVWaWV3KCkpOwoJCU9RdWVyeVRhYmxlQ29ubmVjdGlvbiogcENvbm4gPSBzdGF0aWNfY2FzdDxPUXVlcnlUYWJsZUNvbm5lY3Rpb24qPiggcFRhYmxlVmlldy0+R2V0VGFiQ29ubihzdGF0aWNfY2FzdDxPVGFibGVXaW5kb3cqPihfYURyYWdMZWZ0LT5HZXRUYWJXaW5kb3coKSksc3RhdGljX2Nhc3Q8T1RhYmxlV2luZG93Kj4oX2FEcmFnUmlnaHQtPkdldFRhYldpbmRvdygpKSx0cnVlKSk7CgoJCWlmICggIXBDb25uICkKCQl7CgkJCU9RdWVyeVRhYmxlQ29ubmVjdGlvbkRhdGEqIHBJbmZvRGF0YSA9IG5ldyBPUXVlcnlUYWJsZUNvbm5lY3Rpb25EYXRhKCk7CiAgICAgICAgICAgIFRUYWJsZUNvbm5lY3Rpb25EYXRhOjp2YWx1ZV90eXBlIGFJbmZvRGF0YShwSW5mb0RhdGEpOwoJCQlwSW5mb0RhdGEtPkluaXRGcm9tRHJhZyhfYURyYWdMZWZ0LCBfYURyYWdSaWdodCk7CgkJCXBJbmZvRGF0YS0+U2V0Sm9pblR5cGUoX2VKb2luVHlwZSk7CgogICAgICAgICAgICBpZiAoIF9iTmF0dXJhbCApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGFJbmZvRGF0YS0+UmVzZXRDb25uTGluZXMoKTsKICAgICAgICAgICAgICAgIHBJbmZvRGF0YS0+c2V0TmF0dXJhbChfYk5hdHVyYWwpOwogICAgICAgICAgICAgICAgdHJ5CiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgUmVmZXJlbmNlPFhOYW1lQWNjZXNzPiB4UmVmZXJlbmNlZFRhYmxlQ29sdW1ucyhhSW5mb0RhdGEtPmdldFJlZmVyZW5jZWRUYWJsZSgpLT5nZXRDb2x1bW5zKCkpOwogICAgICAgICAgICAgICAgICAgIFNlcXVlbmNlPCA6OnJ0bDo6T1VTdHJpbmc+IGFTZXEgPSBhSW5mb0RhdGEtPmdldFJlZmVyZW5jaW5nVGFibGUoKS0+Z2V0Q29sdW1ucygpLT5nZXRFbGVtZW50TmFtZXMoKTsKICAgICAgICAgICAgICAgICAgICBjb25zdCA6OnJ0bDo6T1VTdHJpbmcqIHBJdGVyID0gYVNlcS5nZXRDb25zdEFycmF5KCk7CiAgICAgICAgICAgICAgICAgICAgY29uc3QgOjpydGw6Ok9VU3RyaW5nKiBwRW5kCSAgPSBwSXRlciArIGFTZXEuZ2V0TGVuZ3RoKCk7CiAgICAgICAgICAgICAgICAgICAgZm9yKDtwSXRlciAhPSBwRW5kOysrcEl0ZXIpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoIHhSZWZlcmVuY2VkVGFibGVDb2x1bW5zLT5oYXNCeU5hbWUoKnBJdGVyKSApCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhSW5mb0RhdGEtPkFwcGVuZENvbm5MaW5lKCpwSXRlciwqcEl0ZXIpOwogICAgICAgICAgICAgICAgICAgIH0gICAgICAgICAgICAKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGNhdGNoKCBjb25zdCBFeGNlcHRpb24mICkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBEQkdfVU5IQU5ETEVEX0VYQ0VQVElPTigpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgoJCQlPUXVlcnlUYWJsZUNvbm5lY3Rpb24gYUluZm8ocFRhYmxlVmlldywgYUluZm9EYXRhKTsKCQkJLy8gZGEgZWluIE9RdWVyeVRhYmxlQ29ubmVjdGlvbi1PYmpla3QgbmllIGRlbiBCZXNpdHogZGVyIHVlYmVyZ2ViZW5lbiBEYXRlbiB1ZWJlcm5pbW10LCBzb25kZXJuIHNpY2ggbnVyIGRlbiBaZWlnZXIgbWVya3QsCgkJCS8vIGlzdCBkaWVzZXIgWmVpZ2VyIGF1ZiBlaW5lIGxva2FsZSBWYXJpYWJsZSBoaWVyIHVua3JpdGlzY2gsIGRlbm4gYUluZm9EYXRhIHVuZCBhSW5mbyBoYWJlbiBkaWUgc2VsYmUgTGViZW5zZGF1ZXIKCQkJcFRhYmxlVmlldy0+Tm90aWZ5VGFiQ29ubmVjdGlvbiggYUluZm8gKTsKCQl9CgkJZWxzZQoJCXsKCQkJOjpydGw6Ok9VU3RyaW5nIGFTb3VyY2VGaWVsZE5hbWUoX2FEcmFnTGVmdC0+R2V0RmllbGQoKSk7CgkJCTo6cnRsOjpPVVN0cmluZyBhRGVzdEZpZWxkTmFtZShfYURyYWdSaWdodC0+R2V0RmllbGQoKSk7CgkJCS8vIHRoZSBjb25uZWN0aW9uIGNvdWxkIHBvaW50IG9uIHRoZSBvdGhlciBzaWRlCgkJCWlmKHBDb25uLT5HZXRTb3VyY2VXaW4oKSA9PSBfYURyYWdSaWdodC0+R2V0VGFiV2luZG93KCkpCgkJCXsKCQkJCTo6cnRsOjpPVVN0cmluZyBhVG1wKGFTb3VyY2VGaWVsZE5hbWUpOwoJCQkJYVNvdXJjZUZpZWxkTmFtZSA9IGFEZXN0RmllbGROYW1lOwoJCQkJYURlc3RGaWVsZE5hbWUgPSBhVG1wOwoJCQl9CgkJCXBDb25uLT5HZXREYXRhKCktPkFwcGVuZENvbm5MaW5lKCBhU291cmNlRmllbGROYW1lLGFEZXN0RmllbGROYW1lKTsKCQkJcENvbm4tPlVwZGF0ZUxpbmVMaXN0KCk7CgkJCS8vIE1vZGlmaWVkLUZsYWcKCQkJLy8JU2V0TW9kaWZpZWQoKTsKCQkJLy8gdW5kIG5ldSB6ZWljaG5lbgoJCQlwQ29ubi0+UmVjYWxjTGluZXMoKTsKCQkJCS8vIGZ1ZXIgZGFzIHVudGVuIGZvbGdlbmRlIEludmFsaWRhdGUgbXVzcyBpY2ggZGllc2VyIG5ldWVuIENvbm5lY3Rpb24gZXJzdCBtYWwgZGllIE1vZWdsaWNoa2VpdCBnZWJlbiwKCQkJCS8vIGlociBCb3VuZGluZ1JlY3QgenUgZXJtaXR0ZWxuCgkJCXBDb25uLT5JbnZhbGlkYXRlQ29ubmVjdGlvbigpOwoJCX0KICAgIH0KCS8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgk6OnJ0bDo6T1VTdHJpbmcgUGFyc2VDb25kaXRpb24oCU9RdWVyeUNvbnRyb2xsZXImIHJDb250cm9sbGVyCgkJCQkJCQkJCSxjb25zdCA6OmNvbm5lY3Rpdml0eTo6T1NRTFBhcnNlTm9kZSogcENvbmRpdGlvbgoJCQkJCQkJCQksY29uc3QgOjpydGw6Ok9VU3RyaW5nIF9zRGVjaW1hbAoJCQkJCQkJCQksY29uc3QgOjpjb206OnN1bjo6c3Rhcjo6bGFuZzo6TG9jYWxlJiBfckxvY2FsZQoJCQkJCQkJCQksc2FsX3VJbnQzMiBfblN0YXJ0SW5kZXgpCgl7CgkJOjpydGw6Ok9VU3RyaW5nCWFDb25kaXRpb247CgkJUmVmZXJlbmNlPCBYQ29ubmVjdGlvbj4geENvbm5lY3Rpb24gPSByQ29udHJvbGxlci5nZXRDb25uZWN0aW9uKCk7CgkJaWYgKCB4Q29ubmVjdGlvbi5pcygpICkKCQl7CgkJCXNhbF91SW50MzIgbkNvdW50ID0gcENvbmRpdGlvbi0+Y291bnQoKTsKCQkJZm9yKHNhbF91SW50MzIgaSA9IF9uU3RhcnRJbmRleCA7IGkgPCBuQ291bnQgOyArK2kpCgkJCQlwQ29uZGl0aW9uLT5nZXRDaGlsZChpKS0+cGFyc2VOb2RlVG9QcmVkaWNhdGVTdHIoYUNvbmRpdGlvbiwKCQkJCQkJCQl4Q29ubmVjdGlvbiwKCQkJCQkJCQlyQ29udHJvbGxlci5nZXROdW1iZXJGb3JtYXR0ZXIoKSwKCQkJCQkJCQlfckxvY2FsZSwKCQkJCQkJCQlzdGF0aWNfY2FzdDxzYWxfQ2hhcj4oX3NEZWNpbWFsLnRvQ2hhcigpKSwKCQkJCQkJCQkmckNvbnRyb2xsZXIuZ2V0UGFyc2VyKCkuZ2V0Q29udGV4dCgpKTsKCQl9CgkJcmV0dXJuIGFDb25kaXRpb247Cgl9CgkvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoJU3FsUGFyc2VFcnJvciBGaWxsT3V0ZXJKb2lucyhPUXVlcnlEZXNpZ25WaWV3KiBfcFZpZXcsCgkJCQkJCQkJY29uc3QgOjpjb25uZWN0aXZpdHk6Ok9TUUxQYXJzZU5vZGUqIHBUYWJsZVJlZkxpc3QpCgl7CgkJU3FsUGFyc2VFcnJvciBlRXJyb3JDb2RlID0gZU9rOwoJCXNhbF91SW50MzIgbkNvdW50ID0gcFRhYmxlUmVmTGlzdC0+Y291bnQoKTsKCQlzYWxfQm9vbCBiRXJyb3IgPSBzYWxfRmFsc2U7CgkJZm9yIChzYWxfdUludDMyIGk9MDsgIWJFcnJvciAmJiBpIDwgbkNvdW50OyArK2kpCgkJewoJCQljb25zdCA6OmNvbm5lY3Rpdml0eTo6T1NRTFBhcnNlTm9kZSogcFBhcnNlTm9kZSA9IHBUYWJsZVJlZkxpc3QtPmdldENoaWxkKGkpOwoJCQljb25zdCA6OmNvbm5lY3Rpdml0eTo6T1NRTFBhcnNlTm9kZSogcEpvaW5Ob2RlID0gTlVMTDsKCgkJCWlmICggU1FMX0lTUlVMRSggcFBhcnNlTm9kZSwgcXVhbGlmaWVkX2pvaW4gKSB8fCBTUUxfSVNSVUxFKCBwUGFyc2VOb2RlLCBqb2luZWRfdGFibGUgKSB8fCBTUUxfSVNSVUxFKCBwUGFyc2VOb2RlLCBjcm9zc191bmlvbiApICkKCQkJCXBKb2luTm9kZSA9IHBQYXJzZU5vZGU7CgkJCWVsc2UgaWYoCVNRTF9JU1JVTEUocFBhcnNlTm9kZSx0YWJsZV9yZWYpCgkJCQkJJiYJcFBhcnNlTm9kZS0+Y291bnQoKSA9PSA0ICkgLy8gJ3snIFNRTF9UT0tFTl9PSiBqb2luZWRfdGFibGUgJ30nCgkJCQlwSm9pbk5vZGUgPSBwUGFyc2VOb2RlLT5nZXRDaGlsZCgyKTsKCgkJCWlmICggcEpvaW5Ob2RlICkKCQkJewoJCQkJaWYgKCAhSW5zZXJ0Sm9pbihfcFZpZXcscEpvaW5Ob2RlKSApCgkJCQkJYkVycm9yID0gc2FsX1RydWU7CgkJCX0KCQl9CgkJLy8gY2hlY2sgaWYgZXJyb3Igb2NjdXJlZAoJCWlmICggYkVycm9yICkKCQkJZUVycm9yQ29kZSA9IGVJbGxlZ2FsSm9pbjsKCgkJcmV0dXJuIGVFcnJvckNvZGU7Cgl9CgkvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKCS8qKiBGaWxsRHJhZ0luZm8gZmlsbHMgdGhlIGZpZWxkIGRlc2NyaXB0aW9uIG91dCBvZiB0aGUgdGFibGUKCSovCgkvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoJU3FsUGFyc2VFcnJvciBGaWxsRHJhZ0luZm8oCWNvbnN0IE9RdWVyeURlc2lnblZpZXcqIF9wVmlldywKCQkJCQkJCWNvbnN0IDo6Y29ubmVjdGl2aXR5OjpPU1FMUGFyc2VOb2RlKiBwQ29sdW1uUmVmLAoJCQkJCQkJT1RhYmxlRmllbGREZXNjUmVmJiBfckRyYWdJbmZvKQoJewoJCVNxbFBhcnNlRXJyb3IgZUVycm9yQ29kZSA9IGVPazsKCgkJc2FsX0Jvb2wgYkVyZyA9IHNhbF9GYWxzZTsKCgkJOjpydGw6Ok9VU3RyaW5nIGFUYWJsZVJhbmdlLGFDb2x1bW5OYW1lOwoJCXNhbF91SW50MTYgbkNudEFjY291bnQ7CgkJOjpjb25uZWN0aXZpdHk6Ok9TUUxQYXJzZVRyZWVJdGVyYXRvciYgclBhcnNlSXRlciA9IHN0YXRpY19jYXN0PE9RdWVyeUNvbnRyb2xsZXImPihfcFZpZXctPmdldENvbnRyb2xsZXIoKSkuZ2V0UGFyc2VJdGVyYXRvcigpOwoJCXJQYXJzZUl0ZXIuZ2V0Q29sdW1uUmFuZ2UoIHBDb2x1bW5SZWYsIGFDb2x1bW5OYW1lLCBhVGFibGVSYW5nZSApOwoKCQlpZiAoIGFUYWJsZVJhbmdlLmdldExlbmd0aCgpICkKCQl7CgkJCU9RdWVyeVRhYmxlV2luZG93KglwU1RXID0gc3RhdGljX2Nhc3Q8T1F1ZXJ5VGFibGVWaWV3Kj4oX3BWaWV3LT5nZXRUYWJsZVZpZXcoKSktPkZpbmRUYWJsZSggYVRhYmxlUmFuZ2UgKTsKCQkJYkVyZyA9IChwU1RXICYmIHBTVFctPkV4aXN0c0ZpZWxkKCBhQ29sdW1uTmFtZSwgX3JEcmFnSW5mbyApICk7CgkJfQoJCWlmICggIWJFcmcgKQogICAgICAgIHsKCQkJYkVyZyA9IHN0YXRpY19jYXN0PE9RdWVyeVRhYmxlVmlldyo+KF9wVmlldy0+Z2V0VGFibGVWaWV3KCkpLT5GaW5kVGFibGVGcm9tRmllbGQoYUNvbHVtbk5hbWUsIF9yRHJhZ0luZm8sIG5DbnRBY2NvdW50KTsKICAgICAgICAgICAgaWYgKCAhYkVyZyApCiAgICAgICAgICAgICAgICBiRXJnID0gX3BWaWV3LT5IYXNGaWVsZEJ5QWxpYXNOYW1lKGFDb2x1bW5OYW1lLCBfckRyYWdJbmZvKTsKICAgICAgICB9CgkJaWYgKCAhYkVyZyApCgkJewoJCQllRXJyb3JDb2RlID0gZUNvbHVtbk5vdEZvdW5kOwoJCQlTdHJpbmcgc0Vycm9yKE1vZHVsZVJlcyhTVFJfUVJZX0NPTFVNTl9OT1RfRk9VTkQpKTsKCQkJc0Vycm9yLlNlYXJjaEFuZFJlcGxhY2VBc2NpaSgiJG5hbWUkIixhQ29sdW1uTmFtZSk7CgkJCV9wVmlldy0+Z2V0Q29udHJvbGxlcigpLmFwcGVuZEVycm9yKCBzRXJyb3IgKTsKCgkJCXRyeQoJCQl7CgkJCQlSZWZlcmVuY2U8WERhdGFiYXNlTWV0YURhdGE+IHhNZXRhID0gX3BWaWV3LT5nZXRDb250cm9sbGVyKCkuZ2V0Q29ubmVjdGlvbigpLT5nZXRNZXRhRGF0YSgpOwogICAgICAgICAgICAgICAgaWYgKCB4TWV0YS5pcygpICYmIHhNZXRhLT5zdXBwb3J0c01peGVkQ2FzZVF1b3RlZElkZW50aWZpZXJzKCkgKQogICAgICAgICAgICAgICAgICAgIF9wVmlldy0+Z2V0Q29udHJvbGxlcigpLmFwcGVuZEVycm9yKCBTdHJpbmcoIE1vZHVsZVJlcyggU1RSX1FSWV9DSEVDS19DQVNFU0VOU0lUSVZFICkgKSApOwoJCQl9CgkJCWNhdGNoKEV4Y2VwdGlvbiYpCgkJCXsKCQkJfQoJCX0KCgkJcmV0dXJuIGVFcnJvckNvZGU7Cgl9CgkvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoJOjpydGw6Ok9VU3RyaW5nIEJ1aWxkSm9pbkNyaXRlcmlhKAljb25zdCBSZWZlcmVuY2U8IFhDb25uZWN0aW9uPiYgX3hDb25uZWN0aW9uLAoJCQkJCQkJCQkJT0Nvbm5lY3Rpb25MaW5lRGF0YVZlYyogcExpbmVEYXRhTGlzdCwKCQkJCQkJCQkJCU9RdWVyeVRhYmxlQ29ubmVjdGlvbkRhdGEqIHBEYXRhKQoJewoJCTo6cnRsOjpPVVN0cmluZ0J1ZmZlciBhQ29uZGl0aW9uOwoJCWlmICggX3hDb25uZWN0aW9uLmlzKCkgKQogICAgICAgIHsKCQkgICAgT0Nvbm5lY3Rpb25MaW5lRGF0YVZlYzo6aXRlcmF0b3IgYUl0ZXIgPSBwTGluZURhdGFMaXN0LT5iZWdpbigpOwogICAgICAgICAgICBPQ29ubmVjdGlvbkxpbmVEYXRhVmVjOjppdGVyYXRvciBhRW5kID0gcExpbmVEYXRhTGlzdC0+ZW5kKCk7CgkJICAgIHRyeQoJCSAgICB7CgkJCSAgICBjb25zdCBSZWZlcmVuY2U8IFhEYXRhYmFzZU1ldGFEYXRhID4gIHhNZXRhRGF0YSA9IF94Q29ubmVjdGlvbi0+Z2V0TWV0YURhdGEoKTsKCQkJICAgIGNvbnN0IDo6cnRsOjpPVVN0cmluZyBhUXVvdGUgPSB4TWV0YURhdGEtPmdldElkZW50aWZpZXJRdW90ZVN0cmluZygpOwogICAgICAgICAgICAgICAgY29uc3QgOjpydGw6Ok9VU3RyaW5nIHNFcXVhbChSVExfQ09OU1RBU0NJSV9VU1RSSU5HUEFSQU0oIiA9ICIpKTsKCgkJCSAgICBmb3IoO2FJdGVyICE9IGFFbmQ7KythSXRlcikKCQkJICAgIHsKCQkJCSAgICBPQ29ubmVjdGlvbkxpbmVEYXRhUmVmIHBMaW5lRGF0YSA9ICphSXRlcjsKCQkJCSAgICBpZihhQ29uZGl0aW9uLmdldExlbmd0aCgpKQoJCQkJCSAgICBhQ29uZGl0aW9uLmFwcGVuZChDX0FORCk7CgkJCQkgICAgYUNvbmRpdGlvbi5hcHBlbmQocXVvdGVUYWJsZUFsaWFzKHNhbF9UcnVlLHBEYXRhLT5HZXRBbGlhc05hbWUoSlRDU19GUk9NKSxhUXVvdGUpKTsKCQkJCSAgICBhQ29uZGl0aW9uLmFwcGVuZCg6OmRidG9vbHM6OnF1b3RlTmFtZShhUXVvdGUsIHBMaW5lRGF0YS0+R2V0RmllbGROYW1lKEpUQ1NfRlJPTSkgKSk7CgkJCQkgICAgYUNvbmRpdGlvbi5hcHBlbmQoc0VxdWFsKTsKCQkJCSAgICBhQ29uZGl0aW9uLmFwcGVuZChxdW90ZVRhYmxlQWxpYXMoc2FsX1RydWUscERhdGEtPkdldEFsaWFzTmFtZShKVENTX1RPKSxhUXVvdGUpKTsKCQkJCSAgICBhQ29uZGl0aW9uLmFwcGVuZCg6OmRidG9vbHM6OnF1b3RlTmFtZShhUXVvdGUsIHBMaW5lRGF0YS0+R2V0RmllbGROYW1lKEpUQ1NfVE8pICkpOwoJCQkgICAgfQoJCSAgICB9CgkJICAgIGNhdGNoKFNRTEV4Y2VwdGlvbiYpCgkJICAgIHsKCQkJICAgIE9TTF9BU1NFUlQoISJGYWlsdXJlIHdoaWxlIGJ1aWxkaW5nIEpvaW4gY3JpdGVyaWEhIik7CgkJICAgIH0KICAgICAgICB9CgoJCXJldHVybiBhQ29uZGl0aW9uLm1ha2VTdHJpbmdBbmRDbGVhcigpOwoJfQoJLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCS8qKiBKb2luQ3ljbGUgbG9va3MgZm9yIGEgam9pbiBjeWNsZSBhbmQgYXBwZW5kIGl0IHRvIHRoZSBzdHJpbmcKCQlAcGFyYW0JX3hDb25uZWN0aW9uCXRoZSBjb25uZWN0aW9uCgkJQHBhcmFtCV9wRW50cnlDb25uCQl0aGUgdGFibGUgY29ubmVjdGlvbiB3aGljaCBob2xkcyB0aGUgZGF0YQoJCUBwYXJhbQlfcEVudHJ5VGFiVG8JdGhlIGNvcnJlc3BvbmRpbmcgdGFibGUgd2luZG93CgkJQHBhcmFtCV9ySm9pbgkJCXRoZSBTdHJpbmcgd2hpY2ggd2lsbCBjb250YWluIHRoZSByZXN1bHRpbmcgc3RyaW5nCgkqLwoJdm9pZCBKb2luQ3ljbGUoCWNvbnN0IFJlZmVyZW5jZTwgWENvbm5lY3Rpb24+JiBfeENvbm5lY3Rpb24sCgkJCQkJT1F1ZXJ5VGFibGVDb25uZWN0aW9uKiBfcEVudHJ5Q29ubiwKCQkJCQljb25zdCBPUXVlcnlUYWJsZVdpbmRvdyogX3BFbnRyeVRhYlRvLAoJCQkJCTo6cnRsOjpPVVN0cmluZyYgX3JKb2luICkKCXsKCQlPU0xfRU5TVVJFKF9wRW50cnlDb25uLCJUYWJsZUNvbm5lY3Rpb24gY2FuIG5vdCBiZSBudWxsISIpOwoKCQlPUXVlcnlUYWJsZUNvbm5lY3Rpb25EYXRhKiBwRGF0YSA9IHN0YXRpY19jYXN0PCBPUXVlcnlUYWJsZUNvbm5lY3Rpb25EYXRhKj4oX3BFbnRyeUNvbm4tPkdldERhdGEoKS5nZXQoKSk7CgkJaWYgKCBwRGF0YS0+R2V0Sm9pblR5cGUoKSAhPSBJTk5FUl9KT0lOICYmIF9wRW50cnlUYWJUby0+RXhpc3RzQVZpc2l0ZWRDb25uKCkgKQoJCXsKCQkJc2FsX0Jvb2wgYkJyYWNlID0gc2FsX0ZhbHNlOwoJCQlpZihfckpvaW4uZ2V0TGVuZ3RoKCkgJiYgX3JKb2luLmxhc3RJbmRleE9mKCcpJykgPT0gKF9ySm9pbi5nZXRMZW5ndGgoKS0xKSkKCQkJewoJCQkJYkJyYWNlID0gc2FsX1RydWU7CgkJCQlfckpvaW4gPSBfckpvaW4ucmVwbGFjZUF0KF9ySm9pbi5nZXRMZW5ndGgoKS0xLDEsOjpydGw6Ok9VU3RyaW5nKCcgJykpOwoJCQl9CgkJCShfckpvaW4gKz0gQ19BTkQpICs9IEJ1aWxkSm9pbkNyaXRlcmlhKF94Q29ubmVjdGlvbixwRGF0YS0+R2V0Q29ubkxpbmVEYXRhTGlzdCgpLHBEYXRhKTsKCQkJaWYoYkJyYWNlKQoJCQkJX3JKb2luICs9IDo6cnRsOjpPVVN0cmluZygnKScpOwoJCQlfcEVudHJ5Q29ubi0+U2V0VmlzaXRlZChzYWxfVHJ1ZSk7CgkJfQoJfQoJLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCTo6cnRsOjpPVVN0cmluZyBCdWlsZFRhYmxlKAljb25zdCBSZWZlcmVuY2U8IFhDb25uZWN0aW9uPiYgX3hDb25uZWN0aW9uLAoJCQkJCQkJCWNvbnN0IE9RdWVyeVRhYmxlV2luZG93KiBwRW50cnlUYWIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBfYkZvcmNlID0gZmFsc2UKCQkJCQkJCQkpCgl7CgkJOjpydGw6Ok9VU3RyaW5nIGFEQk5hbWUocEVudHJ5VGFiLT5HZXRDb21wb3NlZE5hbWUoKSk7CgoJCS8vCVJlZmVyZW5jZTwgWENvbm5lY3Rpb24+IHhDb25uZWN0aW9uID0gc3RhdGljX2Nhc3Q8T1F1ZXJ5Q29udHJvbGxlciY+KF9wVmlldy0+Z2V0Q29udHJvbGxlcigpKS5nZXRDb25uZWN0aW9uKCk7CgkJaWYoIF94Q29ubmVjdGlvbi5pcygpICkKCQl7CgkJCXRyeQoJCQl7CgkJCQlSZWZlcmVuY2U8IFhEYXRhYmFzZU1ldGFEYXRhID4gIHhNZXRhRGF0YSA9IF94Q29ubmVjdGlvbi0+Z2V0TWV0YURhdGEoKTsKCiAgICAgICAgICAgICAgICA6OnJ0bDo6T1VTdHJpbmcgc0NhdGFsb2csIHNTY2hlbWEsIHNUYWJsZTsKICAgICAgICAgICAgICAgIDo6ZGJ0b29sczo6cXVhbGlmaWVkTmFtZUNvbXBvbmVudHMoIHhNZXRhRGF0YSwgYURCTmFtZSwgc0NhdGFsb2csIHNTY2hlbWEsIHNUYWJsZSwgOjpkYnRvb2xzOjplSW5EYXRhTWFuaXB1bGF0aW9uICk7CgkJCQk6OnJ0bDo6T1VTdHJpbmcgYVRhYmxlTGlzdFN0ciA9IDo6ZGJ0b29sczo6Y29tcG9zZVRhYmxlTmFtZUZvclNlbGVjdCggX3hDb25uZWN0aW9uLCBzQ2F0YWxvZywgc1NjaGVtYSwgc1RhYmxlICk7CgoJCQkJOjpydGw6Ok9VU3RyaW5nIGFRdW90ZSA9IHhNZXRhRGF0YS0+Z2V0SWRlbnRpZmllclF1b3RlU3RyaW5nKCk7CgkJCQlpZiAoIF9iRm9yY2UgfHwgaXNBcHBlbmRUYWJsZUFsaWFzRW5hYmxlZCggX3hDb25uZWN0aW9uICkgfHwgcEVudHJ5VGFiLT5HZXRBbGlhc05hbWUoKSAhPSBhREJOYW1lICkKCQkJCXsKICAgICAgICAgICAgICAgICAgICBhVGFibGVMaXN0U3RyICs9IDo6cnRsOjpPVVN0cmluZzo6Y3JlYXRlRnJvbUFzY2lpKCIgIik7CiAgICAgICAgICAgICAgICAgICAgaWYgKCBnZW5lcmF0ZUFzQmVmb3JlVGFibGVBbGlhcyggX3hDb25uZWN0aW9uICkgKQogICAgICAgICAgICAgICAgICAgICAgICBhVGFibGVMaXN0U3RyICs9IDo6cnRsOjpPVVN0cmluZzo6Y3JlYXRlRnJvbUFzY2lpKCJBUyAiKTsKCQkJCQlhVGFibGVMaXN0U3RyICs9IDo6ZGJ0b29sczo6cXVvdGVOYW1lKCBhUXVvdGUsIHBFbnRyeVRhYi0+R2V0QWxpYXNOYW1lKCkgKTsKCQkJCX0KCQkJCWFEQk5hbWUgPSBhVGFibGVMaXN0U3RyOwoJCQl9CgkJCWNhdGNoKGNvbnN0IFNRTEV4Y2VwdGlvbiYpCgkJCXsKICAgICAgICAgICAgICAgIERCR19VTkhBTkRMRURfRVhDRVBUSU9OKCk7CgkJCX0KCQl9CgkJcmV0dXJuIGFEQk5hbWU7Cgl9CgkvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoJOjpydGw6Ok9VU3RyaW5nIEJ1aWxkSm9pbigJY29uc3QgUmVmZXJlbmNlPCBYQ29ubmVjdGlvbj4mIF94Q29ubmVjdGlvbiwKCQkJCQkJCQljb25zdCA6OnJ0bDo6T1VTdHJpbmcmIHJMaCwKCQkJCQkJCQljb25zdCA6OnJ0bDo6T1VTdHJpbmcmIHJSaCwKCQkJCQkJCQlPUXVlcnlUYWJsZUNvbm5lY3Rpb25EYXRhKiBwRGF0YSkKCXsKCgkJU3RyaW5nIGFFcmcockxoKTsKICAgICAgICBpZiAoIHBEYXRhLT5pc05hdHVyYWwoKSAmJiBwRGF0YS0+R2V0Sm9pblR5cGUoKSAhPSBDUk9TU19KT0lOICkKICAgICAgICAgICAgYUVyZy5BcHBlbmRBc2NpaSgiIE5BVFVSQUwgIik7CgkJc3dpdGNoKHBEYXRhLT5HZXRKb2luVHlwZSgpKQoJCXsKCQkJY2FzZSBMRUZUX0pPSU46CgkJCQlhRXJnLkFwcGVuZEFzY2lpKCIgTEVGVCBPVVRFUiAiKTsKCQkJCWJyZWFrOwoJCQljYXNlIFJJR0hUX0pPSU46CgkJCQlhRXJnLkFwcGVuZEFzY2lpKCIgUklHSFQgT1VURVIgIik7CgkJCQlicmVhazsKICAgICAgICAgICAgY2FzZSBDUk9TU19KT0lOOgogICAgICAgICAgICAgICAgT1NMX0VOU1VSRSghcERhdGEtPmlzTmF0dXJhbCgpLCJPUXVlcnlEZXNpZ25WaWV3OjpCdWlsZEpvaW46IFRoaXMgc2hvdWxkIG5vdCBoYXBwZW4hIik7CgkJCQlhRXJnLkFwcGVuZEFzY2lpKCIgQ1JPU1MgIik7CgkJCQlicmVhazsKCQkJY2FzZSBJTk5FUl9KT0lOOgogICAgICAgICAgICAgICAgT1NMX0VOU1VSRShwRGF0YS0+aXNOYXR1cmFsKCksIk9RdWVyeURlc2lnblZpZXc6OkJ1aWxkSm9pbjogVGhpcyBzaG91bGQgbm90IGhhcHBlbiEiKTsKCQkJCWFFcmcuQXBwZW5kQXNjaWkoIiBJTk5FUiAiKTsKCQkJCWJyZWFrOwoJCQlkZWZhdWx0OgoJCQkJYUVyZy5BcHBlbmRBc2NpaSgiIEZVTEwgT1VURVIgIik7CgkJCQlicmVhazsKCQl9CgkJYUVyZy5BcHBlbmRBc2NpaSgiSk9JTiAiKTsKCQlhRXJnICs9IFN0cmluZyhyUmgpOwogICAgICAgIGlmICggQ1JPU1NfSk9JTiAhPSBwRGF0YS0+R2V0Sm9pblR5cGUoKSAmJiAhcERhdGEtPmlzTmF0dXJhbCgpICkKICAgICAgICB7CgkJICAgIGFFcmcuQXBwZW5kQXNjaWkoIiBPTiAiKTsKCQkgICAgYUVyZyArPSBTdHJpbmcoQnVpbGRKb2luQ3JpdGVyaWEoX3hDb25uZWN0aW9uLHBEYXRhLT5HZXRDb25uTGluZURhdGFMaXN0KCkscERhdGEpKTsKICAgICAgICB9CgoJCXJldHVybiBhRXJnOwoJfQoJLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCTo6cnRsOjpPVVN0cmluZyBCdWlsZEpvaW4oCWNvbnN0IFJlZmVyZW5jZTwgWENvbm5lY3Rpb24+JiBfeENvbm5lY3Rpb24sCgkJCQkJCQkJT1F1ZXJ5VGFibGVXaW5kb3cqIHBMaCwKCQkJCQkJCQlPUXVlcnlUYWJsZVdpbmRvdyogcFJoLAoJCQkJCQkJCU9RdWVyeVRhYmxlQ29ubmVjdGlvbkRhdGEqIHBEYXRhCgkJCQkJCQkJKQoJewogICAgICAgIGJvb2wgYkZvcmNlID0gcERhdGEtPkdldEpvaW5UeXBlKCkgPT0gQ1JPU1NfSk9JTiB8fCBwRGF0YS0+aXNOYXR1cmFsKCk7CgkJcmV0dXJuIEJ1aWxkSm9pbihfeENvbm5lY3Rpb24sQnVpbGRUYWJsZShfeENvbm5lY3Rpb24scExoLGJGb3JjZSksQnVpbGRUYWJsZShfeENvbm5lY3Rpb24scFJoLGJGb3JjZSkscERhdGEpOwoJfQoJLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCTo6cnRsOjpPVVN0cmluZyBCdWlsZEpvaW4oCWNvbnN0IFJlZmVyZW5jZTwgWENvbm5lY3Rpb24+JiBfeENvbm5lY3Rpb24sCgkJCQkJCQkJY29uc3QgOjpydGw6Ok9VU3RyaW5nICZyTGgsCgkJCQkJCQkJT1F1ZXJ5VGFibGVXaW5kb3cqIHBSaCwKCQkJCQkJCQlPUXVlcnlUYWJsZUNvbm5lY3Rpb25EYXRhKiBwRGF0YQoJCQkJCQkJCSkKCXsKCQlyZXR1cm4gQnVpbGRKb2luKF94Q29ubmVjdGlvbixyTGgsQnVpbGRUYWJsZShfeENvbm5lY3Rpb24scFJoKSxwRGF0YSk7Cgl9CgkvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoJOjpydGw6Ok9VU3RyaW5nIEJ1aWxkSm9pbigJY29uc3QgUmVmZXJlbmNlPCBYQ29ubmVjdGlvbj4mIF94Q29ubmVjdGlvbiwKCQkJCQkJCQlPUXVlcnlUYWJsZVdpbmRvdyogcExoLAoJCQkJCQkJCWNvbnN0IDo6cnRsOjpPVVN0cmluZyAmclJoLAoJCQkJCQkJCU9RdWVyeVRhYmxlQ29ubmVjdGlvbkRhdGEqIHBEYXRhCgkJCQkJCQkJKQoJewoJCXJldHVybiBCdWlsZEpvaW4oX3hDb25uZWN0aW9uLEJ1aWxkVGFibGUoX3hDb25uZWN0aW9uLHBMaCksclJoLHBEYXRhKTsKCX0KCS8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgl2b2lkIEdldE5leHRKb2luKAljb25zdCBSZWZlcmVuY2U8IFhDb25uZWN0aW9uPiYgX3hDb25uZWN0aW9uLAoJCQkJCQlPUXVlcnlUYWJsZUNvbm5lY3Rpb24qIHBFbnRyeUNvbm4sCgkJCQkJCU9RdWVyeVRhYmxlV2luZG93KiBwRW50cnlUYWJUbywKCQkJCQkJOjpydGw6Ok9VU3RyaW5nICZhSm9pbikKCXsKCQlPUXVlcnlUYWJsZUNvbm5lY3Rpb25EYXRhKiBwRW50cnlDb25uRGF0YSA9IHN0YXRpY19jYXN0PE9RdWVyeVRhYmxlQ29ubmVjdGlvbkRhdGEqPihwRW50cnlDb25uLT5HZXREYXRhKCkuZ2V0KCkpOwogICAgICAgIGlmICggcEVudHJ5Q29ubkRhdGEtPkdldEpvaW5UeXBlKCkgPT0gSU5ORVJfSk9JTiAmJiAhcEVudHJ5Q29ubkRhdGEtPmlzTmF0dXJhbCgpICkKCQkJcmV0dXJuOwoKCQkvLwlSZWZlcmVuY2U8IFhDb25uZWN0aW9uPiB4Q29ubmVjdGlvbiA9IHN0YXRpY19jYXN0PE9RdWVyeUNvbnRyb2xsZXImPihfcFZpZXctPmdldENvbnRyb2xsZXIoKSkuZ2V0Q29ubmVjdGlvbigpOwoKCQlpZighYUpvaW4uZ2V0TGVuZ3RoKCkpCgkJewoJCQlPUXVlcnlUYWJsZVdpbmRvdyogcEVudHJ5VGFiRnJvbSA9IHN0YXRpY19jYXN0PE9RdWVyeVRhYmxlV2luZG93Kj4ocEVudHJ5Q29ubi0+R2V0U291cmNlV2luKCkpOwoJCQlhSm9pbiA9IEJ1aWxkSm9pbihfeENvbm5lY3Rpb24scEVudHJ5VGFiRnJvbSxwRW50cnlUYWJUbyxwRW50cnlDb25uRGF0YSk7CgkJfQoJCWVsc2UgaWYocEVudHJ5VGFiVG8gPT0gcEVudHJ5Q29ubi0+R2V0RGVzdFdpbigpKQoJCXsKCQkJYUpvaW4gPSBCdWlsZEpvaW4oX3hDb25uZWN0aW9uLGFKb2luLHBFbnRyeVRhYlRvLHBFbnRyeUNvbm5EYXRhKTsKCQl9CgkJZWxzZSBpZihwRW50cnlUYWJUbyA9PSBwRW50cnlDb25uLT5HZXRTb3VyY2VXaW4oKSkKCQl7CgkJCWFKb2luID0gQnVpbGRKb2luKF94Q29ubmVjdGlvbixwRW50cnlUYWJUbyxhSm9pbixwRW50cnlDb25uRGF0YSk7CgkJfQoKCQlwRW50cnlDb25uLT5TZXRWaXNpdGVkKHNhbF9UcnVlKTsKCgkJLy8gZmlyc3Qgc2VhcmNoIGZvciB0aGUgInRvIiB3aW5kb3cKCQljb25zdCA6OnN0ZDo6dmVjdG9yPE9UYWJsZUNvbm5lY3Rpb24qPiogcENvbm5lY3Rpb25zID0gcEVudHJ5Q29ubi0+R2V0UGFyZW50KCktPmdldFRhYmxlQ29ubmVjdGlvbnMoKTsKCQk6OnN0ZDo6dmVjdG9yPE9UYWJsZUNvbm5lY3Rpb24qPjo6Y29uc3RfaXRlcmF0b3IgYUl0ZXIgPSBwQ29ubmVjdGlvbnMtPmJlZ2luKCk7CiAgICAgICAgOjpzdGQ6OnZlY3RvcjxPVGFibGVDb25uZWN0aW9uKj46OmNvbnN0X2l0ZXJhdG9yIGFFbmQgPSBwQ29ubmVjdGlvbnMtPmVuZCgpOwoJCWZvcig7YUl0ZXIgIT0gYUVuZDsrK2FJdGVyKQoJCXsKCQkJT1F1ZXJ5VGFibGVDb25uZWN0aW9uKiBwTmV4dCA9IHN0YXRpY19jYXN0PE9RdWVyeVRhYmxlQ29ubmVjdGlvbio+KCphSXRlcik7CgkJCWlmKCFwTmV4dC0+SXNWaXNpdGVkKCkgJiYgKHBOZXh0LT5HZXRTb3VyY2VXaW4oKSA9PSBwRW50cnlUYWJUbyB8fCBwTmV4dC0+R2V0RGVzdFdpbigpID09IHBFbnRyeVRhYlRvKSkKCQkJewoJCQkJT1F1ZXJ5VGFibGVXaW5kb3cqIHBFbnRyeVRhYiA9IHBOZXh0LT5HZXRTb3VyY2VXaW4oKSA9PSBwRW50cnlUYWJUbyA/IHN0YXRpY19jYXN0PE9RdWVyeVRhYmxlV2luZG93Kj4ocE5leHQtPkdldERlc3RXaW4oKSkgOiBzdGF0aWNfY2FzdDxPUXVlcnlUYWJsZVdpbmRvdyo+KHBOZXh0LT5HZXRTb3VyY2VXaW4oKSk7CgkJCQkvLyBleGlzdHMgdGhlcmUgYSBjb25uZWN0aW9uIHRvIGEgT1F1ZXJ5VGFibGVXaW5kb3cgdGhhdCBob2xkcyBhIGNvbm5lY3Rpb24gdGhhdCBoYXMgYmVlbiBhbHJlYWR5IHZpc2l0ZWQKCQkJCUpvaW5DeWNsZShfeENvbm5lY3Rpb24scE5leHQscEVudHJ5VGFiLGFKb2luKTsKCQkJCWlmKCFwTmV4dC0+SXNWaXNpdGVkKCkpCgkJCQkJR2V0TmV4dEpvaW4oX3hDb25uZWN0aW9uLHBOZXh0LHBFbnRyeVRhYixhSm9pbik7CgkJCX0KCQl9CgoJCS8vIHdoZW4gbm90aGluZyBmb3VuZCBmb3VuZCBsb29rIGZvciB0aGUgImZyb20iIHdpbmRvdwoJCWlmKGFJdGVyID09IGFFbmQpCgkJewoJCQlPUXVlcnlUYWJsZVdpbmRvdyogcEVudHJ5VGFiRnJvbSA9IHN0YXRpY19jYXN0PE9RdWVyeVRhYmxlV2luZG93Kj4ocEVudHJ5Q29ubi0+R2V0U291cmNlV2luKCkpOwoJCQlhSXRlciA9IHBDb25uZWN0aW9ucy0+YmVnaW4oKTsKCQkJZm9yKDthSXRlciAhPSBhRW5kOysrYUl0ZXIpCgkJCXsKCQkJCU9RdWVyeVRhYmxlQ29ubmVjdGlvbiogcE5leHQgPSBzdGF0aWNfY2FzdDxPUXVlcnlUYWJsZUNvbm5lY3Rpb24qPigqYUl0ZXIpOwoJCQkJaWYoIXBOZXh0LT5Jc1Zpc2l0ZWQoKSAmJiAocE5leHQtPkdldFNvdXJjZVdpbigpID09IHBFbnRyeVRhYkZyb20gfHwgcE5leHQtPkdldERlc3RXaW4oKSA9PSBwRW50cnlUYWJGcm9tKSkKCQkJCXsKCQkJCQlPUXVlcnlUYWJsZVdpbmRvdyogcEVudHJ5VGFiID0gcE5leHQtPkdldFNvdXJjZVdpbigpID09IHBFbnRyeVRhYkZyb20gPyBzdGF0aWNfY2FzdDxPUXVlcnlUYWJsZVdpbmRvdyo+KHBOZXh0LT5HZXREZXN0V2luKCkpIDogc3RhdGljX2Nhc3Q8T1F1ZXJ5VGFibGVXaW5kb3cqPihwTmV4dC0+R2V0U291cmNlV2luKCkpOwoJCQkJCS8vIGV4aXN0cyB0aGVyZSBhIGNvbm5lY3Rpb24gdG8gYSBPUXVlcnlUYWJsZVdpbmRvdyB0aGF0IGhvbGRzIGEgY29ubmVjdGlvbiB0aGF0IGhhcyBiZWVuIGFscmVhZHkgdmlzaXRlZAoJCQkJCUpvaW5DeWNsZShfeENvbm5lY3Rpb24scE5leHQscEVudHJ5VGFiLGFKb2luKTsKCQkJCQlpZighcE5leHQtPklzVmlzaXRlZCgpKQoJCQkJCQlHZXROZXh0Sm9pbihfeENvbm5lY3Rpb24scE5leHQscEVudHJ5VGFiLGFKb2luKTsKCQkJCX0KCQkJfQoJCX0KCX0KCS8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCglTcWxQYXJzZUVycm9yIEluc2VydEpvaW5Db25uZWN0aW9uKAljb25zdCBPUXVlcnlEZXNpZ25WaWV3KiBfcFZpZXcsCgkJCQkJCQkJCWNvbnN0IDo6Y29ubmVjdGl2aXR5OjpPU1FMUGFyc2VOb2RlICpwTm9kZSwKCQkJCQkJCQkJY29uc3QgRUpvaW5UeXBlJiBfZUpvaW5UeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCA6OmNvbm5lY3Rpdml0eTo6T1NRTFBhcnNlTm9kZSAqcExlZnRUYWJsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgOjpjb25uZWN0aXZpdHk6Ok9TUUxQYXJzZU5vZGUgKnBSaWdodFRhYmxlKQoJewoJCVNxbFBhcnNlRXJyb3IgZUVycm9yQ29kZSA9IGVPazsKCQlpZiAocE5vZGUtPmNvdW50KCkgPT0gMyAmJgkvLyBBdXNkcnVjayBpcyBnZWtsYW1tZXJ0CgkJCVNRTF9JU1BVTkNUVUFUSU9OKHBOb2RlLT5nZXRDaGlsZCgwKSwiKCIpICYmCgkJCVNRTF9JU1BVTkNUVUFUSU9OKHBOb2RlLT5nZXRDaGlsZCgyKSwiKSIpKQoJCXsKCQkJZUVycm9yQ29kZSA9IEluc2VydEpvaW5Db25uZWN0aW9uKF9wVmlldyxwTm9kZS0+Z2V0Q2hpbGQoMSksIF9lSm9pblR5cGUscExlZnRUYWJsZSxwUmlnaHRUYWJsZSk7CgkJfQoJCWVsc2UgaWYgKFNRTF9JU1JVTEVPUjIocE5vZGUsc2VhcmNoX2NvbmRpdGlvbixib29sZWFuX3Rlcm0pCSYmCQkJLy8gQU5EL09SLVZlcmtudWVwZnVuZzoKCQkJCSBwTm9kZS0+Y291bnQoKSA9PSAzKQoJCXsKCQkJLy8gbnVyIEFORCBWZXJrbvxwZnVuZyB6dWxhc3NlbgoJCQlpZiAoIVNRTF9JU1RPS0VOKHBOb2RlLT5nZXRDaGlsZCgxKSxBTkQpKQoJCQkJZUVycm9yQ29kZSA9IGVJbGxlZ2FsSm9pbkNvbmRpdGlvbjsKCQkJZWxzZSBpZiAoIGVPayA9PSAoZUVycm9yQ29kZSA9IEluc2VydEpvaW5Db25uZWN0aW9uKF9wVmlldyxwTm9kZS0+Z2V0Q2hpbGQoMCksIF9lSm9pblR5cGUscExlZnRUYWJsZSxwUmlnaHRUYWJsZSkpICkKCQkJCQllRXJyb3JDb2RlID0gSW5zZXJ0Sm9pbkNvbm5lY3Rpb24oX3BWaWV3LHBOb2RlLT5nZXRDaGlsZCgyKSwgX2VKb2luVHlwZSxwTGVmdFRhYmxlLHBSaWdodFRhYmxlKTsKCQl9CgkJZWxzZSBpZiAoU1FMX0lTUlVMRShwTm9kZSxjb21wYXJpc29uX3ByZWRpY2F0ZSkpCgkJewoJCQkvLyBvbmx5IHRoZSBjb21wYXJpc29uIG9mIGNvbHVtbnMgaXMgYWxsb3dlZAoJCQlEQkdfQVNTRVJUKHBOb2RlLT5jb3VudCgpID09IDMsIk9RdWVyeURlc2lnblZpZXc6Okluc2VydEpvaW5Db25uZWN0aW9uOiBGZWhsZXIgaW0gUGFyc2UgVHJlZSIpOwoJCQlpZiAoIShTUUxfSVNSVUxFKHBOb2RlLT5nZXRDaGlsZCgwKSxjb2x1bW5fcmVmKSAmJgoJCQkJICBTUUxfSVNSVUxFKHBOb2RlLT5nZXRDaGlsZCgyKSxjb2x1bW5fcmVmKSAmJgoJCQkJICAgcE5vZGUtPmdldENoaWxkKDEpLT5nZXROb2RlVHlwZSgpID09IFNRTF9OT0RFX0VRVUFMKSkKCQkJewoJCQkJU3RyaW5nIHNFcnJvcihNb2R1bGVSZXMoU1RSX1FSWV9KT0lOX0NPTFVNTl9DT01QQVJFKSk7CgkJCQlfcFZpZXctPmdldENvbnRyb2xsZXIoKS5hcHBlbmRFcnJvciggc0Vycm9yICk7CgkJCQlyZXR1cm4gZUlsbGVnYWxKb2luOwoJCQl9CgoJCQlPVGFibGVGaWVsZERlc2NSZWYgYURyYWdMZWZ0ICA9IG5ldyBPVGFibGVGaWVsZERlc2MoKTsKCQkJT1RhYmxlRmllbGREZXNjUmVmIGFEcmFnUmlnaHQgPSBuZXcgT1RhYmxlRmllbGREZXNjKCk7CgkJCWlmICggZU9rICE9ICggZUVycm9yQ29kZSA9IEZpbGxEcmFnSW5mbyhfcFZpZXcscE5vZGUtPmdldENoaWxkKDApLGFEcmFnTGVmdCkpIHx8CgkJCQllT2sgIT0gKCBlRXJyb3JDb2RlID0gRmlsbERyYWdJbmZvKF9wVmlldyxwTm9kZS0+Z2V0Q2hpbGQoMiksYURyYWdSaWdodCkpKQoJCQkJcmV0dXJuIGVFcnJvckNvZGU7CgogICAgICAgICAgICBpZiAoIHBMZWZ0VGFibGUgKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBPUXVlcnlUYWJsZVdpbmRvdyoJcExlZnRXaW5kb3cgPSBzdGF0aWNfY2FzdDxPUXVlcnlUYWJsZVZpZXcqPihfcFZpZXctPmdldFRhYmxlVmlldygpKS0+RmluZFRhYmxlKCBnZXRUYWJsZVJhbmdlKF9wVmlldyxwTGVmdFRhYmxlLT5nZXRCeVJ1bGUoT1NRTFBhcnNlTm9kZTo6dGFibGVfcmVmKSApKTsKICAgICAgICAgICAgICAgIC8vIE9RdWVyeVRhYmxlV2luZG93KglwUmlnaHRXaW5kb3cgPSBzdGF0aWNfY2FzdDxPUXVlcnlUYWJsZVZpZXcqPihfcFZpZXctPmdldFRhYmxlVmlldygpKS0+RmluZFRhYmxlKCBnZXRUYWJsZVJhbmdlKF9wVmlldyxwUmlnaHRUYWJsZS0+Z2V0QnlSdWxlKE9TUUxQYXJzZU5vZGU6OnRhYmxlX3JlZikgKSk7CiAgICAgICAgICAgICAgICBpZiAoIHBMZWZ0V2luZG93ID09IGFEcmFnTGVmdC0+R2V0VGFiV2luZG93KCkgKQogICAgICAgICAgICAgICAgICAgIGluc2VydENvbm5lY3Rpb24oX3BWaWV3LF9lSm9pblR5cGUsYURyYWdMZWZ0LGFEcmFnUmlnaHQpOwogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIGluc2VydENvbm5lY3Rpb24oX3BWaWV3LF9lSm9pblR5cGUsYURyYWdSaWdodCxhRHJhZ0xlZnQpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIGluc2VydENvbm5lY3Rpb24oX3BWaWV3LF9lSm9pblR5cGUsYURyYWdMZWZ0LGFEcmFnUmlnaHQpOwoJCX0KCQllbHNlCgkJCWVFcnJvckNvZGUgPSBlSWxsZWdhbEpvaW47CgkJcmV0dXJuIGVFcnJvckNvZGU7Cgl9CgkvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoJc2FsX0Jvb2wgR2V0SW5uZXJKb2luQ3JpdGVyaWEoCWNvbnN0IE9RdWVyeURlc2lnblZpZXcqIF9wVmlldywKCQkJCQkJCQkJY29uc3QgOjpjb25uZWN0aXZpdHk6Ok9TUUxQYXJzZU5vZGUgKnBDb25kaXRpb24pCgl7CgkJcmV0dXJuIEluc2VydEpvaW5Db25uZWN0aW9uKF9wVmlldyxwQ29uZGl0aW9uLCBJTk5FUl9KT0lOLE5VTEwsTlVMTCkgIT0gZU9rOwoJfQoJLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCTo6cnRsOjpPVVN0cmluZyBHZW5lcmF0ZVNlbGVjdExpc3QoCWNvbnN0IE9RdWVyeURlc2lnblZpZXcqIF9wVmlldywKCQkJCQkJCQkJCU9UYWJsZUZpZWxkcyYJX3JGaWVsZExpc3QsCgkJCQkJCQkJCQlzYWxfQm9vbCBiQWxpYXMpCgl7CiAgICAgICAgUmVmZXJlbmNlPCBYQ29ubmVjdGlvbj4geENvbm5lY3Rpb24gPSBzdGF0aWNfY2FzdDxPUXVlcnlDb250cm9sbGVyJj4oX3BWaWV3LT5nZXRDb250cm9sbGVyKCkpLmdldENvbm5lY3Rpb24oKTsKCQlpZiAoICF4Q29ubmVjdGlvbi5pcygpICkKCQkJcmV0dXJuIDo6cnRsOjpPVVN0cmluZygpOwoKCQk6OnJ0bDo6T1VTdHJpbmdCdWZmZXIgYVRtcFN0cixhRmllbGRMaXN0U3RyOwoKCQlzYWxfQm9vbCBiQXN0ZXJpeCA9IHNhbF9GYWxzZTsKCQlpbnQgblZpcyA9IDA7CgkJT1RhYmxlRmllbGRzOjppdGVyYXRvciBhSXRlciA9IF9yRmllbGRMaXN0LmJlZ2luKCk7CiAgICAgICAgT1RhYmxlRmllbGRzOjppdGVyYXRvciBhRW5kID0gX3JGaWVsZExpc3QuZW5kKCk7CgkJZm9yKDthSXRlciAhPSBhRW5kOysrYUl0ZXIpCgkJewoJCQlPVGFibGVGaWVsZERlc2NSZWYgcEVudHJ5RmllbGQgPSAqYUl0ZXI7CgkJCWlmICggcEVudHJ5RmllbGQtPklzVmlzaWJsZSgpICkKCQkJewoJCQkJaWYgKCBwRW50cnlGaWVsZC0+R2V0RmllbGQoKS50b0NoYXIoKSA9PSAnKicgKQoJCQkJCWJBc3Rlcml4ID0gc2FsX1RydWU7CgkJCQkrK25WaXM7CgkJCX0KCQl9CgkJaWYoblZpcyA9PSAxKQoJCQliQXN0ZXJpeCA9IHNhbF9GYWxzZTsKCgkJdHJ5CgkJewoJCQljb25zdCBSZWZlcmVuY2U8IFhEYXRhYmFzZU1ldGFEYXRhID4gIHhNZXRhRGF0YSA9IHhDb25uZWN0aW9uLT5nZXRNZXRhRGF0YSgpOwoJCQljb25zdCA6OnJ0bDo6T1VTdHJpbmcgYVF1b3RlID0geE1ldGFEYXRhLT5nZXRJZGVudGlmaWVyUXVvdGVTdHJpbmcoKTsKCgkJCU9Kb2luVGFibGVWaWV3OjpPVGFibGVXaW5kb3dNYXAqIHBUYWJMaXN0ID0gX3BWaWV3LT5nZXRUYWJsZVZpZXcoKS0+R2V0VGFiV2luTWFwKCk7CgoJCQljb25zdCBzdGF0aWMgOjpydGw6Ok9VU3RyaW5nIHNGaWVsZFNlcGFyYXRvcihSVExfQ09OU1RBU0NJSV9VU1RSSU5HUEFSQU0oIiwgIikpOwogICAgICAgICAgICBjb25zdCBzdGF0aWMgOjpydGw6Ok9VU3RyaW5nIHNfc0FzKFJUTF9DT05TVEFTQ0lJX1VTVFJJTkdQQVJBTSgiIEFTICIpKTsKCgkJCWFJdGVyID0gX3JGaWVsZExpc3QuYmVnaW4oKTsKCQkgICAgZm9yKDthSXRlciAhPSBhRW5kOysrYUl0ZXIpCgkJCXsKCQkJCU9UYWJsZUZpZWxkRGVzY1JlZiBwRW50cnlGaWVsZCA9ICphSXRlcjsKCQkJCTo6cnRsOjpPVVN0cmluZyByRmllbGROYW1lID0gcEVudHJ5RmllbGQtPkdldEZpZWxkKCk7CgkJCQlpZiAoIHJGaWVsZE5hbWUuZ2V0TGVuZ3RoKCkgJiYgcEVudHJ5RmllbGQtPklzVmlzaWJsZSgpICkKCQkJCXsKCQkJCQlhVG1wU3RyID0gOjpydGw6Ok9VU3RyaW5nKCk7CgkJCQkJY29uc3QgOjpydGw6Ok9VU3RyaW5nIHJBbGlhcyA9IHBFbnRyeUZpZWxkLT5HZXRBbGlhcygpOwoJCQkJCWNvbnN0IDo6cnRsOjpPVVN0cmluZyByRmllbGRBbGlhcyA9IHBFbnRyeUZpZWxkLT5HZXRGaWVsZEFsaWFzKCk7CgoJCQkJCWFUbXBTdHIuYXBwZW5kKHF1b3RlVGFibGVBbGlhcygoYkFsaWFzIHx8IGJBc3Rlcml4KSxyQWxpYXMsYVF1b3RlKSk7CgoJCQkJCS8vIGlmIHdlIGhhdmUgYSBub25lIG51bWVyaWMgZmllbGQsIHRoZSB0YWJsZSBhbGlhcyBjb3VsZCBiZSBpbiB0aGUgbmFtZQoJCQkJCS8vIG90aGVyd2lzZSB3ZSBhcmUgbm90IGFsbG93ZWQgdG8gZG8gdGhpcyAoZS5nLiAwLjEgKiBQUklDRSApCgkJCQkJaWYgICggIXBFbnRyeUZpZWxkLT5pc090aGVyRnVuY3Rpb24oKSApCgkJCQkJewoJCQkJCQkvLyB3ZSBoYXZlIHRvIGxvb2sgaWYgd2UgaGF2ZSBhbGlhcy4qIGhlcmUgYnV0IGJlZm9yZSB3ZSBoYXZlIHRvIGNoZWNrIGlmIHRoZSBjb2x1bW4gZG9lc24ndCBhbHJlYWR5IGV4aXN0CgkJCQkJCVN0cmluZyBzVGVtcCA9IHJGaWVsZE5hbWU7CgkJCQkJCU9UYWJsZUZpZWxkRGVzY1JlZglhSW5mbyA9IG5ldyBPVGFibGVGaWVsZERlc2MoKTsKCQkJCQkJT0pvaW5UYWJsZVZpZXc6Ok9UYWJsZVdpbmRvd01hcDo6aXRlcmF0b3IgdGFibGVJdGVyID0gcFRhYkxpc3QtPmJlZ2luKCk7CiAgICAgICAgICAgICAgICAgICAgICAgIE9Kb2luVGFibGVWaWV3OjpPVGFibGVXaW5kb3dNYXA6Oml0ZXJhdG9yIHRhYmxlRW5kID0gcFRhYkxpc3QtPmVuZCgpOwoJCQkJCQlzYWxfQm9vbCBiRm91bmQgPSBzYWxfRmFsc2U7CgkJCQkJCWZvcig7IWJGb3VuZCAmJiB0YWJsZUl0ZXIgIT0gdGFibGVFbmQgOysrdGFibGVJdGVyKQoJCQkJCQl7CgkJCQkJCQlPUXVlcnlUYWJsZVdpbmRvdyogcFRhYldpbiA9IHN0YXRpY19jYXN0PE9RdWVyeVRhYmxlV2luZG93Kj4odGFibGVJdGVyLT5zZWNvbmQpOwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJGb3VuZCA9IHBUYWJXaW4tPkV4aXN0c0ZpZWxkKCByRmllbGROYW1lLCBhSW5mbyApOwoJCQkJCQkJaWYgKCBiRm91bmQgKQoJCQkJCQkJCXJGaWVsZE5hbWUgPSBhSW5mby0+R2V0RmllbGQoKTsKCQkJCQkJfQoJCQkJCQlpZiAoICggckZpZWxkTmFtZS50b0NoYXIoKSAhPSAnKicgKSAmJiAoIHJGaWVsZE5hbWUuaW5kZXhPZiggYVF1b3RlICkgPT0gLTEgKSApCgkJCQkJCXsKCQkJCQkJCU9TTF9FTlNVUkUocEVudHJ5RmllbGQtPkdldFRhYmxlKCkuZ2V0TGVuZ3RoKCksIk5vIHRhYmxlIGZpZWxkIG5hbWUhIik7CgkJCQkJCQlhVG1wU3RyLmFwcGVuZCg6OmRidG9vbHM6OnF1b3RlTmFtZShhUXVvdGUsIHJGaWVsZE5hbWUpKTsKCQkJCQkJfQoJCQkJCQllbHNlCgkJCQkJCQlhVG1wU3RyLmFwcGVuZChyRmllbGROYW1lKTsKCQkJCQl9CgkJCQkJZWxzZQoJCQkJCQlhVG1wU3RyLmFwcGVuZChyRmllbGROYW1lKTsKCgkJCQkJaWYgICggcEVudHJ5RmllbGQtPmlzQWdncmVhdGVGdW5jdGlvbigpICkKCQkJCQl7CgkJCQkJCURCR19BU1NFUlQocEVudHJ5RmllbGQtPkdldEZ1bmN0aW9uKCkuZ2V0TGVuZ3RoKCksIkZ1bmN0aW9ubmFtZSBkYXJmIGhpZXIgbmljaHQgbGVlciBzZWluISA7LSgiKTsKCQkJCQkJOjpydGw6Ok9VU3RyaW5nQnVmZmVyIGFUbXBTdHIyKCBwRW50cnlGaWVsZC0+R2V0RnVuY3Rpb24oKSk7CgkJCQkJCWFUbXBTdHIyLmFwcGVuZEFzY2lpKCIoIik7CgkJCQkJCWFUbXBTdHIyLmFwcGVuZChhVG1wU3RyLm1ha2VTdHJpbmdBbmRDbGVhcigpKTsKCQkJCQkJYVRtcFN0cjIuYXBwZW5kQXNjaWkoIikiKTsKCQkJCQkJYVRtcFN0ciA9IGFUbXBTdHIyOwoJCQkJCX0KCgkJCQkJaWYgKHJGaWVsZEFsaWFzLmdldExlbmd0aCgpCQkJCQkJCSYmCgkJCQkJCShyRmllbGROYW1lLnRvQ2hhcigpICE9ICcqJwkJCQkJCXx8CgkJCQkJCXBFbnRyeUZpZWxkLT5pc051bWVyaWNPckFnZ3JlYXRlRnVuY3Rpb24oKQkJfHwKCQkJCQkJcEVudHJ5RmllbGQtPmlzT3RoZXJGdW5jdGlvbigpKSkKCQkJCQl7CgkJCQkJCWFUbXBTdHIuYXBwZW5kKHNfc0FzKTsKCQkJCQkJYVRtcFN0ci5hcHBlbmQoOjpkYnRvb2xzOjpxdW90ZU5hbWUoYVF1b3RlLCByRmllbGRBbGlhcykpOwoJCQkJCX0KCQkJCQlhRmllbGRMaXN0U3RyLmFwcGVuZChhVG1wU3RyLm1ha2VTdHJpbmdBbmRDbGVhcigpKTsKCQkJCQlhRmllbGRMaXN0U3RyLmFwcGVuZChzRmllbGRTZXBhcmF0b3IpOwoJCQkJfQoJCQl9CgkJCWlmKGFGaWVsZExpc3RTdHIuZ2V0TGVuZ3RoKCkpCgkJCQlhRmllbGRMaXN0U3RyLnNldExlbmd0aChhRmllbGRMaXN0U3RyLmdldExlbmd0aCgpLTIpOwoJCX0KCQljYXRjaChTUUxFeGNlcHRpb24mKQoJCXsKCQkJT1NMX0FTU0VSVCghIkZhaWx1cmUgd2hpbGUgYnVpbGRpbmcgc2VsZWN0IGxpc3QhIik7CgkJfQoJCXJldHVybiBhRmllbGRMaXN0U3RyLm1ha2VTdHJpbmdBbmRDbGVhcigpOwoJfQoJLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCXNhbF9Cb29sIEdlbmVyYXRlQ3JpdGVyaWFzKAlPUXVlcnlEZXNpZ25WaWV3KiBfcFZpZXcsCgkJCQkJCQkJOjpydGw6Ok9VU3RyaW5nQnVmZmVyJiByUmV0U3RyLAoJCQkJCQkJCTo6cnRsOjpPVVN0cmluZ0J1ZmZlciYgckhhdmluZ1N0ciwKCQkJCQkJCQlPVGFibGVGaWVsZHMmIF9yRmllbGRMaXN0LAoJCQkJCQkJCXNhbF9Cb29sIGJNdWx0aSApCgl7CgkJLy8gKiBkYXJmIGtlaW5lIEZpbHRlciBlbnRoYWx0ZW4gOiBoYWJlIGljaCBkaWUgZW50c3ByZWNoZW5kZSBXYXJudW5nIHNjaG9uIGFuZ2V6ZWlndCA/CgkJc2FsX0Jvb2wgYkNyaXRzT25Bc3RlcmlrV2FybmluZyA9IHNhbF9GYWxzZTsJCS8vICoqIFRNRlMgKioKCgkJOjpydGw6Ok9VU3RyaW5nIGFGaWVsZE5hbWUsYUNyaXRlcmlhLGFXaGVyZVN0cixhSGF2aW5nU3RyLGFXb3JrLyosYU9yZGVyU3RyKi87CgkJLy8gWmVpbGVud2Vpc2Ugd2VyZGVuIGRpZSBBdXNkciJ1Y2tlIG1pdCBBTkQgdmVya251ZXBmdAoJCXNhbF91SW50MTYgbk1heENyaXRlcmlhID0gMDsKCQlPVGFibGVGaWVsZHM6Oml0ZXJhdG9yIGFJdGVyID0gX3JGaWVsZExpc3QuYmVnaW4oKTsKCQlPVGFibGVGaWVsZHM6Oml0ZXJhdG9yIGFFbmQgPSBfckZpZWxkTGlzdC5lbmQoKTsKCQlmb3IoO2FJdGVyICE9IGFFbmQ7KythSXRlcikKCQl7CgkJCW5NYXhDcml0ZXJpYSA9IDo6c3RkOjptYXg8c2FsX3VJbnQxNj4obk1heENyaXRlcmlhLChzYWxfdUludDE2KSgqYUl0ZXIpLT5HZXRDcml0ZXJpYSgpLnNpemUoKSk7CgkJfQoJCVJlZmVyZW5jZTwgWENvbm5lY3Rpb24+IHhDb25uZWN0aW9uID0gc3RhdGljX2Nhc3Q8T1F1ZXJ5Q29udHJvbGxlciY+KF9wVmlldy0+Z2V0Q29udHJvbGxlcigpKS5nZXRDb25uZWN0aW9uKCk7CgkJaWYoIXhDb25uZWN0aW9uLmlzKCkpCgkJCXJldHVybiBzYWxfRmFsc2U7CgkJdHJ5CgkJewoJCQljb25zdCBSZWZlcmVuY2U8IFhEYXRhYmFzZU1ldGFEYXRhID4gIHhNZXRhRGF0YSA9IHhDb25uZWN0aW9uLT5nZXRNZXRhRGF0YSgpOwoJCQljb25zdCA6OnJ0bDo6T1VTdHJpbmcgYVF1b3RlID0geE1ldGFEYXRhLT5nZXRJZGVudGlmaWVyUXVvdGVTdHJpbmcoKTsKCQkJY29uc3QgSVBhcnNlQ29udGV4dCYgckNvbnRleHQgPSBzdGF0aWNfY2FzdDxPUXVlcnlDb250cm9sbGVyJj4oX3BWaWV3LT5nZXRDb250cm9sbGVyKCkpLmdldFBhcnNlcigpLmdldENvbnRleHQoKTsKCgkJCWZvciAoc2FsX3VJbnQxNiBpPTAgOyBpIDwgbk1heENyaXRlcmlhIDsgaSsrKQoJCQl7CgkJCQlhSGF2aW5nU3RyID0gYVdoZXJlU3RyID0gOjpydGw6Ok9VU3RyaW5nKCk7CgoJCQkJZm9yKGFJdGVyID0gX3JGaWVsZExpc3QuYmVnaW4oKTthSXRlciAhPSBhRW5kOysrYUl0ZXIpCgkJCQl7CgkJCQkJT1RhYmxlRmllbGREZXNjUmVmCXBFbnRyeUZpZWxkID0gKmFJdGVyOwoJCQkJCWFGaWVsZE5hbWUgPSBwRW50cnlGaWVsZC0+R2V0RmllbGQoKTsKCgkJCQkJaWYgKCFhRmllbGROYW1lLmdldExlbmd0aCgpKQoJCQkJCQljb250aW51ZTsKCQkJCQlhQ3JpdGVyaWEgPSBwRW50cnlGaWVsZC0+R2V0Q3JpdGVyaWEoIGkgKTsKCQkJCQlpZiAoIGFDcml0ZXJpYS5nZXRMZW5ndGgoKSApCgkJCQkJewoJCQkJCQkvLyAqIGlzIG5vdCBhbGxvd2VkIHRvIGNvbnRhaW4gYW55IGZpbHRlciwgb25seSB3aGVuIHVzZWQgaW4gY29tYmluYXRpb24gYW4gYWdncmVnYXRlIGZ1bmN0aW9uCgkJCQkJCWlmICggYUZpZWxkTmFtZS50b0NoYXIoKSA9PSAnKicgJiYgcEVudHJ5RmllbGQtPmlzTm9uZUZ1bmN0aW9uKCkgKQoJCQkJCQl7CgkJCQkJCQkvLyBvbmx5IHNob3cgdGhlIG1lc3NhZ2Vib3ggdGhlIGZpcnN0IHRpbWUKCQkJCQkJCWlmICghYkNyaXRzT25Bc3RlcmlrV2FybmluZykKCQkJCQkJCQlFcnJvckJveChfcFZpZXcsIE1vZHVsZVJlcyggRVJSX1FSWV9DUklURVJJQV9PTl9BU1RFUklTSykpLkV4ZWN1dGUoKTsKCQkJCQkJCWJDcml0c09uQXN0ZXJpa1dhcm5pbmcgPSBzYWxfVHJ1ZTsKCQkJCQkJCWNvbnRpbnVlOwoJCQkJCQl9CgkJCQkJCWFXb3JrID0gOjpydGw6Ok9VU3RyaW5nKCk7CgoKCQkJCQkJYVdvcmsgKz0gcXVvdGVUYWJsZUFsaWFzKGJNdWx0aSxwRW50cnlGaWVsZC0+R2V0QWxpYXMoKSxhUXVvdGUpOwoKCQkJCQkJaWYgKCAocEVudHJ5RmllbGQtPkdldEZ1bmN0aW9uVHlwZSgpICYgKEZLVF9PVEhFUnxGS1RfTlVNRVJJQykpIHx8IChhRmllbGROYW1lLnRvQ2hhcigpID09ICcqJykgKQoJCQkJCQkJYVdvcmsgKz0gYUZpZWxkTmFtZTsKCQkJCQkJZWxzZQoJCQkJCQkJYVdvcmsgKz0gOjpkYnRvb2xzOjpxdW90ZU5hbWUoYVF1b3RlLCBhRmllbGROYW1lKTsKCgkJCQkJCWlmICggcEVudHJ5RmllbGQtPmlzQWdncmVhdGVGdW5jdGlvbigpIHx8IHBFbnRyeUZpZWxkLT5Jc0dyb3VwQnkoKSApCgkJCQkJCXsKCQkJCQkJCWlmICghYUhhdmluZ1N0ci5nZXRMZW5ndGgoKSkJCQkvLyBub2NoIGtlaW5lIEtyaXRlcmllbgoJCQkJCQkJCWFIYXZpbmdTdHIgKz0gOjpydGw6Ok9VU3RyaW5nKCcoJyk7CQkJLy8gS2xhbW1lcm4KCQkJCQkJCWVsc2UKCQkJCQkJCQlhSGF2aW5nU3RyICs9IENfQU5EOwoKCQkJCQkJCWlmICggcEVudHJ5RmllbGQtPmlzQWdncmVhdGVGdW5jdGlvbigpICkKCQkJCQkJCXsKCQkJCQkJCQlPU0xfRU5TVVJFKHBFbnRyeUZpZWxkLT5HZXRGdW5jdGlvbigpLmdldExlbmd0aCgpLCJObyBmdW5jdGlvbiBuYW1lIGZvciBhZ2dyZWdhdGUgZ2l2ZW4hIik7CgkJCQkJCQkJYUhhdmluZ1N0ciArPSBwRW50cnlGaWVsZC0+R2V0RnVuY3Rpb24oKTsKCQkJCQkJCQlhSGF2aW5nU3RyICs9IDo6cnRsOjpPVVN0cmluZygnKCcpOwkJCS8vIEtsYW1tZXJuCgkJCQkJCQkJYUhhdmluZ1N0ciArPSBhV29yazsKCQkJCQkJCQlhSGF2aW5nU3RyICs9IDo6cnRsOjpPVVN0cmluZygnKScpOwkJCS8vIEtsYW1tZXJuCgkJCQkJCQl9CgkJCQkJCQllbHNlCgkJCQkJCQkJYUhhdmluZ1N0ciArPSBhV29yazsKCgkJCQkJCQk6OnJ0bDo6T1VTdHJpbmcgYVRtcCA9IGFDcml0ZXJpYTsKCQkJCQkJCTo6cnRsOjpPVVN0cmluZyBhRXJyb3JNc2c7CgkJCQkJCQlSZWZlcmVuY2U8WFByb3BlcnR5U2V0PiB4Q29sdW1uOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgOjpzdGQ6OmF1dG9fcHRyPCA6OmNvbm5lY3Rpdml0eTo6T1NRTFBhcnNlTm9kZT4gcFBhcnNlTm9kZShfcFZpZXctPmdldFByZWRpY2F0ZVRyZWVGcm9tRW50cnkocEVudHJ5RmllbGQsYVRtcCxhRXJyb3JNc2cseENvbHVtbikpOwoJCQkJCQkJaWYgKHBQYXJzZU5vZGUuZ2V0KCkpCgkJCQkJCQl7CgkJCQkJCQkJaWYgKGJNdWx0aSAmJiAhKHBFbnRyeUZpZWxkLT5pc090aGVyRnVuY3Rpb24oKSB8fCAoYUZpZWxkTmFtZS50b0NoYXIoKSA9PSAnKicpKSkKCQkJCQkJCQkJcFBhcnNlTm9kZS0+cmVwbGFjZU5vZGVWYWx1ZShwRW50cnlGaWVsZC0+R2V0QWxpYXMoKSxhRmllbGROYW1lKTsKCQkJCQkJCQk6OnJ0bDo6T1VTdHJpbmcgc0hhdmluZ1N0ciA9IGFIYXZpbmdTdHI7CgkJCQkJCQkJCgkJCQkJCQkJc2FsX3VJbnQzMiBuQ291bnQgPSBwUGFyc2VOb2RlLT5jb3VudCgpOwoJCQkJCQkJCWZvciggc2FsX3VJbnQzMiBub2RlID0gMSA7IG5vZGUgPCBuQ291bnQgOyArK25vZGUpCgkJCQkJCQkJCXBQYXJzZU5vZGUtPmdldENoaWxkKG5vZGUpLT5wYXJzZU5vZGVUb1N0cigJc0hhdmluZ1N0ciwKCQkJCQkJCQkJCQkJCQkJCXhDb25uZWN0aW9uLAoJCQkJCQkJCQkJCQkJCQkJJnJDb250ZXh0LAoJCQkJCQkJCQkJCQkJCQkJc2FsX0ZhbHNlLAoJCQkJCQkJCQkJCQkJCQkJIXBFbnRyeUZpZWxkLT5pc090aGVyRnVuY3Rpb24oKSk7CgkJCQkJCQkJYUhhdmluZ1N0ciA9IHNIYXZpbmdTdHI7CgkJCQkJCQl9CgkJCQkJCQllbHNlCgkJCQkJCQkJYUhhdmluZ1N0ciArPSBhQ3JpdGVyaWE7CgkJCQkJCX0KCQkJCQkJZWxzZQoJCQkJCQl7CgkJCQkJCQlpZiAoICFhV2hlcmVTdHIuZ2V0TGVuZ3RoKCkgKQkJCS8vIG5vY2gga2VpbmUgS3JpdGVyaWVuCgkJCQkJCQkJYVdoZXJlU3RyICs9IDo6cnRsOjpPVVN0cmluZygnKCcpOwkJCS8vIEtsYW1tZXJuCgkJCQkJCQllbHNlCgkJCQkJCQkJYVdoZXJlU3RyICs9IENfQU5EOwoKCQkJCQkJCWFXaGVyZVN0ciArPSA6OnJ0bDo6T1VTdHJpbmcoJyAnKTsKCQkJCQkJCS8vIGFDcml0ZXJpYSBjb3VsZCBoYXZlIHNvbWUgZ2VybWFuIG51bWJlcnMgc28gSSBoYXZlIHRvIGJlIHN1cmUgaGVyZQoJCQkJCQkJOjpydGw6Ok9VU3RyaW5nIGFUbXAgPSBhQ3JpdGVyaWE7CgkJCQkJCQk6OnJ0bDo6T1VTdHJpbmcgYUVycm9yTXNnOwoJCQkJCQkJUmVmZXJlbmNlPFhQcm9wZXJ0eVNldD4geENvbHVtbjsKCQkJCQkJCTo6c3RkOjphdXRvX3B0cjwgOjpjb25uZWN0aXZpdHk6Ok9TUUxQYXJzZU5vZGU+IHBQYXJzZU5vZGUoIF9wVmlldy0+Z2V0UHJlZGljYXRlVHJlZUZyb21FbnRyeShwRW50cnlGaWVsZCxhVG1wLGFFcnJvck1zZyx4Q29sdW1uKSk7CgkJCQkJCQlpZiAocFBhcnNlTm9kZS5nZXQoKSkKCQkJCQkJCXsKCQkJCQkJCQlpZiAoYk11bHRpICYmICEocEVudHJ5RmllbGQtPmlzT3RoZXJGdW5jdGlvbigpIHx8IChhRmllbGROYW1lLnRvQ2hhcigpID09ICcqJykpKQoJCQkJCQkJCQlwUGFyc2VOb2RlLT5yZXBsYWNlTm9kZVZhbHVlKHBFbnRyeUZpZWxkLT5HZXRBbGlhcygpLGFGaWVsZE5hbWUpOwoJCQkJCQkJCTo6cnRsOjpPVVN0cmluZyBhV2hlcmUgPSBhV2hlcmVTdHI7CgkJCQkJCQkJcFBhcnNlTm9kZS0+cGFyc2VOb2RlVG9TdHIoCWFXaGVyZSwKCQkJCQkJCQkJCQkJCQkJeENvbm5lY3Rpb24sCgkJCQkJCQkJCQkJCQkJCSZyQ29udGV4dCwKCQkJCQkJCQkJCQkJCQkJc2FsX0ZhbHNlLAoJCQkJCQkJCQkJCQkJCQkhcEVudHJ5RmllbGQtPmlzT3RoZXJGdW5jdGlvbigpICk7CgkJCQkJCQkJYVdoZXJlU3RyID0gYVdoZXJlOwoJCQkJCQkJfQoJCQkJCQkJZWxzZQoJCQkJCQkJewoJCQkJCQkJCWFXaGVyZVN0ciArPSBhV29yazsKCQkJCQkJCQlhV2hlcmVTdHIgKz0gOjpydGw6Ok9VU3RyaW5nKFJUTF9DT05TVEFTQ0lJX1VTVFJJTkdQQVJBTSgiPSIpKTsKCQkJCQkJCQlhV2hlcmVTdHIgKz0gYUNyaXRlcmlhOwoJCQkJCQkJfQoJCQkJCQl9CgkJCQkJfQoJCQkJCS8vIG51ciBlaW5tYWwgZvxyIGplZGVzIEZlbGQKCQkJCQllbHNlIGlmICggIWkgJiYgcEVudHJ5RmllbGQtPmlzQ29uZGl0aW9uKCkgKQoJCQkJCXsKCQkJCQkJaWYgKCFhV2hlcmVTdHIuZ2V0TGVuZ3RoKCkpCQkJLy8gbm9jaCBrZWluZSBLcml0ZXJpZW4KCQkJCQkJCWFXaGVyZVN0ciArPSA6OnJ0bDo6T1VTdHJpbmcoJygnKTsJCQkvLyBLbGFtbWVybgoJCQkJCQllbHNlCgkJCQkJCQlhV2hlcmVTdHIgKz0gQ19BTkQ7CgkJCQkJCWFXaGVyZVN0ciArPSBwRW50cnlGaWVsZC0+R2V0RmllbGQoKTsKCQkJCQl9CgkJCQl9CgkJCQlpZiAoYVdoZXJlU3RyLmdldExlbmd0aCgpKQoJCQkJewoJCQkJCWFXaGVyZVN0ciArPSA6OnJ0bDo6T1VTdHJpbmcoJyknKTsJCQkJCQkvLyBLbGFtbWVybiB6dSBmdWVyICdBTkQnIFp3ZWlnCgkJCQkJaWYgKHJSZXRTdHIuZ2V0TGVuZ3RoKCkpCQkJCQkJCS8vIHNjaG9uIEZlbGRiZWRpbmd1bmdlbiA/CgkJCQkJCXJSZXRTdHIuYXBwZW5kKENfT1IpOwoJCQkJCWVsc2UJCQkJCQkJCQkJLy8gS2xhbW1lcm4gYXVmIGZ1ZXIgJ09SJyBad2VpZwoJCQkJCQlyUmV0U3RyLmFwcGVuZChzYWxfVW5pY29kZSgnKCcpKTsKCQkJCQlyUmV0U3RyLmFwcGVuZChhV2hlcmVTdHIpOwoJCQkJfQoJCQkJaWYgKGFIYXZpbmdTdHIuZ2V0TGVuZ3RoKCkpCgkJCQl7CgkJCQkJYUhhdmluZ1N0ciArPSA6OnJ0bDo6T1VTdHJpbmcoJyknKTsJCQkJCQkvLyBLbGFtbWVybiB6dSBmdWVyICdBTkQnIFp3ZWlnCgkJCQkJaWYgKHJIYXZpbmdTdHIuZ2V0TGVuZ3RoKCkpCQkJCQkJCS8vIHNjaG9uIEZlbGRiZWRpbmd1bmdlbiA/CgkJCQkJCXJIYXZpbmdTdHIuYXBwZW5kKENfT1IpOwoJCQkJCWVsc2UJCQkJCQkJCQkJLy8gS2xhbW1lcm4gYXVmIGZ1ZXIgJ09SJyBad2VpZwoJCQkJCQlySGF2aW5nU3RyLmFwcGVuZChzYWxfVW5pY29kZSgnKCcpKTsKCQkJCQlySGF2aW5nU3RyLmFwcGVuZChhSGF2aW5nU3RyKTsKCQkJCX0KCQkJfQoKCQkJaWYgKHJSZXRTdHIuZ2V0TGVuZ3RoKCkpCgkJCQlyUmV0U3RyLmFwcGVuZChzYWxfVW5pY29kZSgnKScpKTsJCQkJCQkJCS8vIEtsYW1tZXJuIHp1IGZ1ZXIgJ09SJyBad2VpZwoJCQlpZiAockhhdmluZ1N0ci5nZXRMZW5ndGgoKSkKCQkJCXJIYXZpbmdTdHIuYXBwZW5kKHNhbF9Vbmljb2RlKCcpJykpOwkJCQkJCQkJLy8gS2xhbW1lcm4genUgZnVlciAnT1InIFp3ZWlnCgkJfQoJCWNhdGNoKFNRTEV4Y2VwdGlvbiYpCgkJewoJCQlPU0xfQVNTRVJUKCEiRmFpbHVyZSB3aGlsZSBidWlsZGluZyB3aGVyZSBjbGF1c2UhIik7CgkJfQoJCXJldHVybiBzYWxfVHJ1ZTsKCX0KCS8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCglTcWxQYXJzZUVycm9yIEdlbmVyYXRlT3JkZXIoCU9RdWVyeURlc2lnblZpZXcqIF9wVmlldywKCQkJCQkJCQkJT1RhYmxlRmllbGRzJiBfckZpZWxkTGlzdCwKCQkJCQkJCQkJc2FsX0Jvb2wgYk11bHRpLAoJCQkJCQkJCQk6OnJ0bDo6T1VTdHJpbmcmIF9yc1JldCkKCXsKICAgICAgICBjb25zdCBPUXVlcnlDb250cm9sbGVyJiByQ29udHJvbGxlciA9IHN0YXRpY19jYXN0PE9RdWVyeUNvbnRyb2xsZXImPihfcFZpZXctPmdldENvbnRyb2xsZXIoKSk7CgkJUmVmZXJlbmNlPCBYQ29ubmVjdGlvbj4geENvbm5lY3Rpb24gPSByQ29udHJvbGxlci5nZXRDb25uZWN0aW9uKCk7CgkJaWYgKCAheENvbm5lY3Rpb24uaXMoKSApCgkJCXJldHVybiBlTm9Db25uZWN0aW9uOwoKCQlTcWxQYXJzZUVycm9yIGVFcnJvckNvZGUgPSBlT2s7CgoJCTo6cnRsOjpPVVN0cmluZyBhQ29sdW1uTmFtZTsKCQk6OnJ0bDo6T1VTdHJpbmcgYVdvcmtTdHI7CgkJdHJ5CgkJewogICAgICAgICAgICBjb25zdCBib29sIGJDb2x1bW5BbGlhc0luT3JkZXJCeSA9IHJDb250cm9sbGVyLmdldFNkYk1ldGFEYXRhKCkuc3VwcG9ydHNDb2x1bW5BbGlhc0luT3JkZXJCeSgpOwoJCQlSZWZlcmVuY2U8IFhEYXRhYmFzZU1ldGFEYXRhID4gIHhNZXRhRGF0YSA9IHhDb25uZWN0aW9uLT5nZXRNZXRhRGF0YSgpOwoJCQk6OnJ0bDo6T1VTdHJpbmcgYVF1b3RlID0geE1ldGFEYXRhLT5nZXRJZGVudGlmaWVyUXVvdGVTdHJpbmcoKTsKCQkJLy8gKiBkYXJmIGtlaW5lIEZpbHRlciBlbnRoYWx0ZW4gOiBoYWJlIGljaCBkaWUgZW50c3ByZWNoZW5kZSBXYXJudW5nIHNjaG9uIGFuZ2V6ZWlndCA/CgkJCXNhbF9Cb29sIGJDcml0c09uQXN0ZXJpa1dhcm5pbmcgPSBzYWxfRmFsc2U7CQkvLyAqKiBUTUZTICoqCgkJCU9UYWJsZUZpZWxkczo6aXRlcmF0b3IgYUl0ZXIgPSBfckZpZWxkTGlzdC5iZWdpbigpOwoJCQlPVGFibGVGaWVsZHM6Oml0ZXJhdG9yIGFFbmQgPSBfckZpZWxkTGlzdC5lbmQoKTsKCQkgICAgZm9yKDthSXRlciAhPSBhRW5kOysrYUl0ZXIpCgkJCXsKCQkJCU9UYWJsZUZpZWxkRGVzY1JlZglwRW50cnlGaWVsZCA9ICphSXRlcjsKCQkJCUVPcmRlckRpciBlT3JkZXIgPSBwRW50cnlGaWVsZC0+R2V0T3JkZXJEaXIoKTsKCgkJCQkvLyBudXIgd2VubiBlaW5lIFNvcnRpZXJ1bmcgdW5kIGVpbiBUYWJlbGxlbm5hbWUgdm9yaGFuZGVuIGlzdC0+IGVyemV1Z2VuCgkJCQkvLyBzb25zdCB3ZXJkZW4gZGllIEV4cHJlc3Npb25zIHZvbSBPcmRlciBCeSBpbSBHZW5lcmF0ZUNyaXRlcmlhIG1pdCBlcnpldWd0CgkJCQlpZiAoIGVPcmRlciAhPSBPUkRFUl9OT05FICkKCQkJCXsKCQkJCQlhQ29sdW1uTmFtZSA9IHBFbnRyeUZpZWxkLT5HZXRGaWVsZCgpOwoJCQkJCWlmKGFDb2x1bW5OYW1lLnRvQ2hhcigpID09ICcqJykKCQkJCQl7CgkJCQkJCS8vIGRpZSBlbnRzcHJlY2hlbmRlIE1lc3NhZ2VCb3ggbnVyIGJlaW0gZXJzdGVuIG1hbCBhbnplaWdlbgoJCQkJCQlpZiAoIWJDcml0c09uQXN0ZXJpa1dhcm5pbmcpCgkJCQkJCQlFcnJvckJveChfcFZpZXcsIE1vZHVsZVJlcyggRVJSX1FSWV9PUkRFUkJZX09OX0FTVEVSSVNLKSkuRXhlY3V0ZSgpOwoJCQkJCQliQ3JpdHNPbkFzdGVyaWtXYXJuaW5nID0gc2FsX1RydWU7CgkJCQkJCWNvbnRpbnVlOwoJCQkJCX0KCgkJCQkJaWYgKCBiQ29sdW1uQWxpYXNJbk9yZGVyQnkgJiYgcEVudHJ5RmllbGQtPkdldEZpZWxkQWxpYXMoKS5nZXRMZW5ndGgoKSApCgkJCQkJewoJCQkJCQlhV29ya1N0ciArPSA6OmRidG9vbHM6OnF1b3RlTmFtZShhUXVvdGUsIHBFbnRyeUZpZWxkLT5HZXRGaWVsZEFsaWFzKCkpOwoJCQkJCX0KCQkJCQllbHNlIGlmICggcEVudHJ5RmllbGQtPmlzTnVtZXJpY09yQWdncmVhdGVGdW5jdGlvbigpICkKCQkJCQl7CgkJCQkJCURCR19BU1NFUlQocEVudHJ5RmllbGQtPkdldEZ1bmN0aW9uKCkuZ2V0TGVuZ3RoKCksIkZ1bmN0aW9ubmFtZSBkYXJmIGhpZXIgbmljaHQgbGVlciBzZWluISA7LSgiKTsKCQkJCQkJYVdvcmtTdHIgKz0gcEVudHJ5RmllbGQtPkdldEZ1bmN0aW9uKCk7CgkJCQkJCWFXb3JrU3RyICs9ICA6OnJ0bDo6T1VTdHJpbmcoJygnKTsKCQkJCQkJYVdvcmtTdHIgKz0gcXVvdGVUYWJsZUFsaWFzKGJNdWx0aSxwRW50cnlGaWVsZC0+R2V0QWxpYXMoKSxhUXVvdGUpOwoJCQkJCQkvLyBvbmx5IHF1b3RlIGNvbHVtbiBuYW1lIHdoZW4gd2UgZG9uJ3QgaGF2ZSBhIG51bWVyaWMKCQkJCQkJaWYgKCBwRW50cnlGaWVsZC0+aXNOdW1lcmljKCkgKQoJCQkJCQkJYVdvcmtTdHIgKz0gYUNvbHVtbk5hbWU7CgkJCQkJCWVsc2UKCQkJCQkJCWFXb3JrU3RyICs9IDo6ZGJ0b29sczo6cXVvdGVOYW1lKGFRdW90ZSwgYUNvbHVtbk5hbWUpOwoKCQkJCQkJYVdvcmtTdHIgKz0gIDo6cnRsOjpPVVN0cmluZygnKScpOwoJCQkJCX0KICAgICAgICAgICAgICAgICAgICBlbHNlIGlmICggcEVudHJ5RmllbGQtPmlzT3RoZXJGdW5jdGlvbigpICkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGFXb3JrU3RyICs9IGFDb2x1bW5OYW1lOwogICAgICAgICAgICAgICAgICAgIH0KCQkJCQllbHNlCgkJCQkJewoJCQkJCQlhV29ya1N0ciArPSBxdW90ZVRhYmxlQWxpYXMoYk11bHRpLHBFbnRyeUZpZWxkLT5HZXRBbGlhcygpLGFRdW90ZSk7CgkJCQkJCWFXb3JrU3RyICs9IDo6ZGJ0b29sczo6cXVvdGVOYW1lKGFRdW90ZSwgYUNvbHVtbk5hbWUpOwoJCQkJCX0KCQkJCQlhV29ya1N0ciArPSA6OnJ0bDo6T1VTdHJpbmcoJyAnKTsKCQkJCQlhV29ya1N0ciArPSBTdHJpbmc6OkNyZWF0ZUZyb21Bc2NpaSggIjtBU0M7REVTQyIgKS5HZXRUb2tlbiggKHNhbF91SW50MTYpZU9yZGVyICk7CgkJCQkJYVdvcmtTdHIgKz0gOjpydGw6Ok9VU3RyaW5nKCcsJyk7CgkJCQl9CgkJCX0KCgkJCXsKCQkJCVN0cmluZyBzVGVtcChhV29ya1N0cik7CgkJCQlzVGVtcC5FcmFzZVRyYWlsaW5nQ2hhcnMoICcsJyApOwoJCQkJYVdvcmtTdHIgPSBzVGVtcDsKCQkJfQoKCQkJaWYgKCBhV29ya1N0ci5nZXRMZW5ndGgoKSApCgkJCXsKCQkJCWNvbnN0IHNhbF9JbnQzMiBuTWF4T3JkZXIgPSB4TWV0YURhdGEtPmdldE1heENvbHVtbnNJbk9yZGVyQnkoKTsKCQkJCVN0cmluZyBzVG9rZW4oYVdvcmtTdHIpOwoJCQkJaWYgKCBuTWF4T3JkZXIgJiYgbk1heE9yZGVyIDwgc1Rva2VuLkdldFRva2VuQ291bnQoJywnKSApCgkJCQkJZUVycm9yQ29kZSA9IGVTdGF0ZW1lbnRUb29Mb25nOwoJCQkJZWxzZQoJCQkJewoJCQkJCV9yc1JldCA9IDo6cnRsOjpPVVN0cmluZzo6Y3JlYXRlRnJvbUFzY2lpKCIgT1JERVIgQlkgIik7CgkJCQkJX3JzUmV0ICs9IGFXb3JrU3RyOwoJCQkJfQoJCQl9CgkJfQoJCWNhdGNoKFNRTEV4Y2VwdGlvbiYpCgkJewoJCQlPU0xfQVNTRVJUKCEiRmFpbHVyZSB3aGlsZSBidWlsZGluZyBncm91cCBieSEiKTsKCQl9CgoJCXJldHVybiBlRXJyb3JDb2RlOwoJfQoKCS8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgl2b2lkIEdlbmVyYXRlSW5uZXJKb2luQ3JpdGVyaWFzKGNvbnN0IFJlZmVyZW5jZTwgWENvbm5lY3Rpb24+JiBfeENvbm5lY3Rpb24sCgkJCQkJCQkJCTo6cnRsOjpPVVN0cmluZyYgX3JKb2luQ3JpdCwKCQkJCQkJCQkJY29uc3QgOjpzdGQ6OnZlY3RvcjxPVGFibGVDb25uZWN0aW9uKj4qIF9wQ29ubkxpc3QpCgl7CgkJOjpzdGQ6OnZlY3RvcjxPVGFibGVDb25uZWN0aW9uKj46OmNvbnN0X2l0ZXJhdG9yIGFJdGVyID0gX3BDb25uTGlzdC0+YmVnaW4oKTsKICAgICAgICA6OnN0ZDo6dmVjdG9yPE9UYWJsZUNvbm5lY3Rpb24qPjo6Y29uc3RfaXRlcmF0b3IgYUVuZCA9IF9wQ29ubkxpc3QtPmVuZCgpOwoJCWZvcig7YUl0ZXIgIT0gYUVuZDsrK2FJdGVyKQoJCXsKCQkJY29uc3QgT1F1ZXJ5VGFibGVDb25uZWN0aW9uKiBwRW50cnlDb25uID0gc3RhdGljX2Nhc3Q8Y29uc3QgT1F1ZXJ5VGFibGVDb25uZWN0aW9uKj4oKmFJdGVyKTsKCQkJT1F1ZXJ5VGFibGVDb25uZWN0aW9uRGF0YSogcEVudHJ5Q29ubkRhdGEgPSBzdGF0aWNfY2FzdDxPUXVlcnlUYWJsZUNvbm5lY3Rpb25EYXRhKj4ocEVudHJ5Q29ubi0+R2V0RGF0YSgpLmdldCgpKTsKICAgICAgICAgICAgaWYgKCBwRW50cnlDb25uRGF0YS0+R2V0Sm9pblR5cGUoKSA9PSBJTk5FUl9KT0lOICYmICFwRW50cnlDb25uRGF0YS0+aXNOYXR1cmFsKCkgKQoJCQl7CgkJCQlpZihfckpvaW5Dcml0LmdldExlbmd0aCgpKQoJCQkJCV9ySm9pbkNyaXQgKz0gQ19BTkQ7CgkJCQlfckpvaW5Dcml0ICs9IEJ1aWxkSm9pbkNyaXRlcmlhKF94Q29ubmVjdGlvbixwRW50cnlDb25uRGF0YS0+R2V0Q29ubkxpbmVEYXRhTGlzdCgpLHBFbnRyeUNvbm5EYXRhKTsKCQkJfQoJCX0KCX0KCS8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgl2b2lkIHNlYXJjaEFuZEFwcGVuZE5hbWUoY29uc3QgUmVmZXJlbmNlPCBYQ29ubmVjdGlvbj4mIF94Q29ubmVjdGlvbiwKCQkJCQkJCSBjb25zdCBPUXVlcnlUYWJsZVdpbmRvdyogX3BUYWJsZVdpbmRvdywKCQkJCQkJCSA6OnN0ZDo6bWFwPCA6OnJ0bDo6T1VTdHJpbmcsc2FsX0Jvb2wsOjpjb21waGVscGVyOjpVU3RyaW5nTWl4TGVzcz4mIF9yVGFibGVOYW1lcywKCQkJCQkJCSA6OnJ0bDo6T1VTdHJpbmcmIF9yc1RhYmxlTGlzdFN0cgoJCQkJCQkJICkKCXsKCQk6OnJ0bDo6T1VTdHJpbmcgc1RhYk5hbWUoQnVpbGRUYWJsZShfeENvbm5lY3Rpb24sX3BUYWJsZVdpbmRvdykpOwoKCQlpZihfclRhYmxlTmFtZXMuZmluZChzVGFiTmFtZSkgPT0gX3JUYWJsZU5hbWVzLmVuZCgpKQoJCXsKCQkJX3JUYWJsZU5hbWVzW3NUYWJOYW1lXSA9IHNhbF9UcnVlOwoJCQlfcnNUYWJsZUxpc3RTdHIgKz0gc1RhYk5hbWU7CgkJCV9yc1RhYmxlTGlzdFN0ciArPSA6OnJ0bDo6T1VTdHJpbmcoJywnKTsKCQl9Cgl9CgkvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoJOjpydGw6Ok9VU3RyaW5nIEdlbmVyYXRlRnJvbUNsYXVzZSgJY29uc3QgUmVmZXJlbmNlPCBYQ29ubmVjdGlvbj4mIF94Q29ubmVjdGlvbiwKCQkJCQkJCQkJCWNvbnN0IE9RdWVyeVRhYmxlVmlldzo6T1RhYmxlV2luZG93TWFwKglwVGFiTGlzdCwKCQkJCQkJCQkJCWNvbnN0IDo6c3RkOjp2ZWN0b3I8T1RhYmxlQ29ubmVjdGlvbio+KglwQ29ubkxpc3QKCQkJCQkJCQkJCSkKCXsKCgkJOjpydGw6Ok9VU3RyaW5nIGFUYWJsZUxpc3RTdHI7CgkJLy8gd2lyZCBnZWJyYXVjaHQgdW0gc2ljaGVyIHp1c3RlbGxsZW4gZGFzIGVpbmUgVGFiZWxsZSBuaWNodCBkb3BwZWx0IHZvcmtvbW10CgkJOjpzdGQ6Om1hcDwgOjpydGw6Ok9VU3RyaW5nLHNhbF9Cb29sLDo6Y29tcGhlbHBlcjo6VVN0cmluZ01peExlc3M+IGFUYWJsZU5hbWVzOwoKCQkvLyBnZW5lcmF0ZSBvdXRlciBqb2luIGNsYXVzZSBpbiBmcm9tCgkJaWYoIXBDb25uTGlzdC0+ZW1wdHkoKSkKCQl7CgkJCTo6c3RkOjp2ZWN0b3I8T1RhYmxlQ29ubmVjdGlvbio+Ojpjb25zdF9pdGVyYXRvciBhSXRlciA9IHBDb25uTGlzdC0+YmVnaW4oKTsKICAgICAgICAgICAgOjpzdGQ6OnZlY3RvcjxPVGFibGVDb25uZWN0aW9uKj46OmNvbnN0X2l0ZXJhdG9yIGFFbmQgPSBwQ29ubkxpc3QtPmVuZCgpOwogICAgICAgICAgICA6OnN0ZDo6bWFwPE9UYWJsZVdpbmRvdyosc2FsX0ludDMyPiBhQ29ubmVjdGlvbkNvdW50OwoJCQlmb3IoO2FJdGVyICE9IGFFbmQ7KythSXRlcikKICAgICAgICAgICAgewoJCQkJc3RhdGljX2Nhc3Q8T1F1ZXJ5VGFibGVDb25uZWN0aW9uKj4oKmFJdGVyKS0+U2V0VmlzaXRlZChzYWxfRmFsc2UpOwogICAgICAgICAgICAgICAgaWYgKCBhQ29ubmVjdGlvbkNvdW50LmZpbmQoKCphSXRlciktPkdldFNvdXJjZVdpbigpKSA9PSBhQ29ubmVjdGlvbkNvdW50LmVuZCgpICkKICAgICAgICAgICAgICAgICAgICBhQ29ubmVjdGlvbkNvdW50Lmluc2VydCg6OnN0ZDo6bWFwPE9UYWJsZVdpbmRvdyosc2FsX0ludDMyPjo6dmFsdWVfdHlwZSgoKmFJdGVyKS0+R2V0U291cmNlV2luKCksMCkpOwogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIGFDb25uZWN0aW9uQ291bnRbKCphSXRlciktPkdldFNvdXJjZVdpbigpXSsrOwogICAgICAgICAgICAgICAgaWYgKCBhQ29ubmVjdGlvbkNvdW50LmZpbmQoKCphSXRlciktPkdldERlc3RXaW4oKSkgPT0gYUNvbm5lY3Rpb25Db3VudC5lbmQoKSApCiAgICAgICAgICAgICAgICAgICAgYUNvbm5lY3Rpb25Db3VudC5pbnNlcnQoOjpzdGQ6Om1hcDxPVGFibGVXaW5kb3cqLHNhbF9JbnQzMj46OnZhbHVlX3R5cGUoKCphSXRlciktPkdldERlc3RXaW4oKSwwKSk7CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgYUNvbm5lY3Rpb25Db3VudFsoKmFJdGVyKS0+R2V0RGVzdFdpbigpXSsrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIDo6c3RkOjptdWx0aW1hcDxzYWxfSW50MzIgLCBPVGFibGVXaW5kb3cqPiBhTXVsdGk7CiAgICAgICAgICAgIDo6c3RkOjptYXA8T1RhYmxlV2luZG93KixzYWxfSW50MzI+OjppdGVyYXRvciBhQ291bnRJdGVyID0gYUNvbm5lY3Rpb25Db3VudC5iZWdpbigpOwogICAgICAgICAgICA6OnN0ZDo6bWFwPE9UYWJsZVdpbmRvdyosc2FsX0ludDMyPjo6aXRlcmF0b3IgYUNvdW50RW5kID0gYUNvbm5lY3Rpb25Db3VudC5lbmQoKTsKICAgICAgICAgICAgZm9yKDthQ291bnRJdGVyICE9IGFDb3VudEVuZDsrK2FDb3VudEl0ZXIpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGFNdWx0aS5pbnNlcnQoOjpzdGQ6Om11bHRpbWFwPHNhbF9JbnQzMiAsIE9UYWJsZVdpbmRvdyo+Ojp2YWx1ZV90eXBlKGFDb3VudEl0ZXItPnNlY29uZCxhQ291bnRJdGVyLT5maXJzdCkpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBjb25zdCBzYWxfQm9vbCBiVXNlRXNjYXBlID0gOjpkYnRvb2xzOjpnZXRCb29sZWFuRGF0YVNvdXJjZVNldHRpbmcoIF94Q29ubmVjdGlvbiwgUFJPUEVSVFlfT1VURVJKT0lORVNDQVBFICk7CiAgICAgICAgICAgIDo6c3RkOjptdWx0aW1hcDxzYWxfSW50MzIgLCBPVGFibGVXaW5kb3cqPjo6cmV2ZXJzZV9pdGVyYXRvciBhUkl0ZXIgPSBhTXVsdGkucmJlZ2luKCk7CiAgICAgICAgICAgIDo6c3RkOjptdWx0aW1hcDxzYWxfSW50MzIgLCBPVGFibGVXaW5kb3cqPjo6cmV2ZXJzZV9pdGVyYXRvciBhUkVuZCA9IGFNdWx0aS5yZW5kKCk7CiAgICAgICAgICAgIGZvcig7YVJJdGVyICE9IGFSRW5kOysrYVJJdGVyKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICA6OnN0ZDo6dmVjdG9yPE9UYWJsZUNvbm5lY3Rpb24qPjo6Y29uc3RfaXRlcmF0b3IgYUNvbkl0ZXIgPSBhUkl0ZXItPnNlY29uZC0+Z2V0VGFibGVWaWV3KCktPmdldFRhYmxlQ29ubmVjdGlvbnMoYVJJdGVyLT5zZWNvbmQpOwogICAgICAgICAgICAgICAgZm9yKDthQ29uSXRlciAhPSBhRW5kOysrYUNvbkl0ZXIpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgT1F1ZXJ5VGFibGVDb25uZWN0aW9uKiBwRW50cnlDb25uID0gc3RhdGljX2Nhc3Q8T1F1ZXJ5VGFibGVDb25uZWN0aW9uKj4oKmFDb25JdGVyKTsKCQkJCSAgICBpZighcEVudHJ5Q29ubi0+SXNWaXNpdGVkKCkgJiYgcEVudHJ5Q29ubi0+R2V0U291cmNlV2luKCkgPT0gYVJJdGVyLT5zZWNvbmQgKQoJCQkJICAgIHsKCQkJCQkgICAgOjpydGw6Ok9VU3RyaW5nIGFKb2luOwoJCQkJCSAgICBHZXROZXh0Sm9pbihfeENvbm5lY3Rpb24scEVudHJ5Q29ubixzdGF0aWNfY2FzdDxPUXVlcnlUYWJsZVdpbmRvdyo+KHBFbnRyeUNvbm4tPkdldERlc3RXaW4oKSksYUpvaW4pOwoKCQkJCQkgICAgaWYoYUpvaW4uZ2V0TGVuZ3RoKCkpCgkJCQkJICAgIHsKCQkJCQkJICAgIC8vIGluc2VydCB0YWJsZXMgaW50byB0YWJsZSBsaXN0IHRvIGF2b2lkIGRvdWJsZSBlbnRyaWVzCgkJCQkJCSAgICBPUXVlcnlUYWJsZVdpbmRvdyogcEVudHJ5VGFiRnJvbSA9IHN0YXRpY19jYXN0PE9RdWVyeVRhYmxlV2luZG93Kj4ocEVudHJ5Q29ubi0+R2V0U291cmNlV2luKCkpOwoJCQkJCQkgICAgT1F1ZXJ5VGFibGVXaW5kb3cqIHBFbnRyeVRhYlRvID0gc3RhdGljX2Nhc3Q8T1F1ZXJ5VGFibGVXaW5kb3cqPihwRW50cnlDb25uLT5HZXREZXN0V2luKCkpOwoKCQkJCQkJICAgIDo6cnRsOjpPVVN0cmluZyBzVGFiTmFtZShCdWlsZFRhYmxlKF94Q29ubmVjdGlvbixwRW50cnlUYWJGcm9tKSk7CgkJCQkJCSAgICBpZihhVGFibGVOYW1lcy5maW5kKHNUYWJOYW1lKSA9PSBhVGFibGVOYW1lcy5lbmQoKSkKCQkJCQkJCSAgICBhVGFibGVOYW1lc1tzVGFiTmFtZV0gPSBzYWxfVHJ1ZTsKCQkJCQkJICAgIHNUYWJOYW1lID0gQnVpbGRUYWJsZShfeENvbm5lY3Rpb24scEVudHJ5VGFiVG8pOwoJCQkJCQkgICAgaWYoYVRhYmxlTmFtZXMuZmluZChzVGFiTmFtZSkgPT0gYVRhYmxlTmFtZXMuZW5kKCkpCgkJCQkJCQkgICAgYVRhYmxlTmFtZXNbc1RhYk5hbWVdID0gc2FsX1RydWU7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgOjpydGw6Ok9VU3RyaW5nIGFTdHI7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzd2l0Y2goc3RhdGljX2Nhc3Q8T1F1ZXJ5VGFibGVDb25uZWN0aW9uRGF0YSo+KHBFbnRyeUNvbm4tPkdldERhdGEoKS5nZXQoKSktPkdldEpvaW5UeXBlKCkpCgkJICAgICAgICAgICAgICAgICAgICB7CgkJCSAgICAgICAgICAgICAgICAgICAgY2FzZSBMRUZUX0pPSU46CgkJCSAgICAgICAgICAgICAgICAgICAgY2FzZSBSSUdIVF9KT0lOOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgRlVMTF9KT0lOOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CgkJCQkJCSAgICAgICAgICAgICAgICAvLyBjcmVhdGUgb3V0ZXIgam9pbgoJCQkJCQkgICAgICAgICAgICAgICAgaWYgKCBiVXNlRXNjYXBlICkKCQkJCQkJCSAgICAgICAgICAgICAgICBhU3RyICs9IDo6cnRsOjpPVVN0cmluZyhSVExfQ09OU1RBU0NJSV9VU1RSSU5HUEFSQU0oInsgT0ogIikpOwoJCQkJCQkgICAgICAgICAgICAgICAgYVN0ciArPSBhSm9pbjsKCQkJCQkJICAgICAgICAgICAgICAgIGlmICggYlVzZUVzY2FwZSApCgkJCQkJCQkgICAgICAgICAgICAgICAgYVN0ciArPSA6OnJ0bDo6T1VTdHJpbmcoUlRMX0NPTlNUQVNDSUlfVVNUUklOR1BBUkFNKCIgfSIpKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhU3RyICs9IGFKb2luOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KCQkJCQkJICAgIGFTdHIgKz0gOjpydGw6Ok9VU3RyaW5nKFJUTF9DT05TVEFTQ0lJX1VTVFJJTkdQQVJBTSgiLCIpKTsKCQkJCQkJICAgIGFUYWJsZUxpc3RTdHIgKz0gYVN0cjsKCQkJCQkgICAgfQoJCQkJICAgIH0KCQkJICAgIH0KICAgICAgICAgICAgfQoKCQkJLy8gYW5kIG5vdyBhbGwgaW5uZXIgam9pbnMKCQkJYUl0ZXIgPSBwQ29ubkxpc3QtPmJlZ2luKCk7CgkJCWZvcig7YUl0ZXIgIT0gYUVuZDsrK2FJdGVyKQoJCQl7CgkJCQlPUXVlcnlUYWJsZUNvbm5lY3Rpb24qIHBFbnRyeUNvbm4gPSBzdGF0aWNfY2FzdDxPUXVlcnlUYWJsZUNvbm5lY3Rpb24qPigqYUl0ZXIpOwoJCQkJaWYoIXBFbnRyeUNvbm4tPklzVmlzaXRlZCgpKQoJCQkJewoJCQkJCXNlYXJjaEFuZEFwcGVuZE5hbWUoX3hDb25uZWN0aW9uLAoJCQkJCQkJCQkJc3RhdGljX2Nhc3Q8T1F1ZXJ5VGFibGVXaW5kb3cqPihwRW50cnlDb25uLT5HZXRTb3VyY2VXaW4oKSksCgkJCQkJCQkJCQlhVGFibGVOYW1lcywKCQkJCQkJCQkJCWFUYWJsZUxpc3RTdHIpOwoKCQkJCQlzZWFyY2hBbmRBcHBlbmROYW1lKF94Q29ubmVjdGlvbiwKCQkJCQkJCQkJCXN0YXRpY19jYXN0PE9RdWVyeVRhYmxlV2luZG93Kj4ocEVudHJ5Q29ubi0+R2V0RGVzdFdpbigpKSwKCQkJCQkJCQkJCWFUYWJsZU5hbWVzLAoJCQkJCQkJCQkJYVRhYmxlTGlzdFN0cik7CgkJCQl9CgkJCX0KCQl9CgkJLy8gYWxsIHRhYmxlcyB0aGF0IGhhdmVuJ3QgYSBjb25uZWN0aW9uIHRvIGFueW9uZQoJCU9RdWVyeVRhYmxlVmlldzo6T1RhYmxlV2luZG93TWFwOjpjb25zdF9pdGVyYXRvciBhVGFiSXRlciA9IHBUYWJMaXN0LT5iZWdpbigpOwogICAgICAgIE9RdWVyeVRhYmxlVmlldzo6T1RhYmxlV2luZG93TWFwOjpjb25zdF9pdGVyYXRvciBhVGFiRW5kID0gcFRhYkxpc3QtPmVuZCgpOwoJCWZvcig7YVRhYkl0ZXIgIT0gYVRhYkVuZDsrK2FUYWJJdGVyKQoJCXsKCQkJY29uc3QgT1F1ZXJ5VGFibGVXaW5kb3cqIHBFbnRyeVRhYiA9IHN0YXRpY19jYXN0PGNvbnN0IE9RdWVyeVRhYmxlV2luZG93Kj4oYVRhYkl0ZXItPnNlY29uZCk7CgkJCWlmKCFwRW50cnlUYWItPkV4aXN0c0FDb25uKCkpCgkJCXsKCQkJCWFUYWJsZUxpc3RTdHIgKz0gQnVpbGRUYWJsZShfeENvbm5lY3Rpb24scEVudHJ5VGFiKTsKCQkJCWFUYWJsZUxpc3RTdHIgKz0gOjpydGw6Ok9VU3RyaW5nKCcsJyk7CgkJCX0KCQl9CgoJCWlmKGFUYWJsZUxpc3RTdHIuZ2V0TGVuZ3RoKCkpCgkJCWFUYWJsZUxpc3RTdHIgPSBhVGFibGVMaXN0U3RyLnJlcGxhY2VBdChhVGFibGVMaXN0U3RyLmdldExlbmd0aCgpLTEsMSwgOjpydGw6Ok9VU3RyaW5nKCkgKTsKCQlyZXR1cm4gYVRhYmxlTGlzdFN0cjsKCX0KCS8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgk6OnJ0bDo6T1VTdHJpbmcgR2VuZXJhdGVHcm91cEJ5KGNvbnN0IE9RdWVyeURlc2lnblZpZXcqIF9wVmlldyxPVGFibGVGaWVsZHMmIF9yRmllbGRMaXN0LCBzYWxfQm9vbCBiTXVsdGkgKQoJewogICAgICAgIE9RdWVyeUNvbnRyb2xsZXImIHJDb250cm9sbGVyID0gc3RhdGljX2Nhc3Q8T1F1ZXJ5Q29udHJvbGxlciY+KF9wVmlldy0+Z2V0Q29udHJvbGxlcigpKTsKCQljb25zdCBSZWZlcmVuY2U8IFhDb25uZWN0aW9uPiB4Q29ubmVjdGlvbiA9IHJDb250cm9sbGVyLmdldENvbm5lY3Rpb24oKTsKCQlpZigheENvbm5lY3Rpb24uaXMoKSkKCQkJcmV0dXJuIDo6cnRsOjpPVVN0cmluZygpOwoKICAgICAgICA6OnN0ZDo6bWFwPCBydGw6Ok9VU3RyaW5nLGJvb2w+IGFHcm91cEJ5TmFtZXM7CgoJCTo6cnRsOjpPVVN0cmluZyBhR3JvdXBCeVN0cjsKCQl0cnkKCQl7CgkJCWNvbnN0IFJlZmVyZW5jZTwgWERhdGFiYXNlTWV0YURhdGEgPiAgeE1ldGFEYXRhID0geENvbm5lY3Rpb24tPmdldE1ldGFEYXRhKCk7CgkJCWNvbnN0IDo6cnRsOjpPVVN0cmluZyBhUXVvdGUgPSB4TWV0YURhdGEtPmdldElkZW50aWZpZXJRdW90ZVN0cmluZygpOwoKCQkJT1RhYmxlRmllbGRzOjppdGVyYXRvciBhSXRlciA9IF9yRmllbGRMaXN0LmJlZ2luKCk7CgkJCU9UYWJsZUZpZWxkczo6aXRlcmF0b3IgYUVuZCA9IF9yRmllbGRMaXN0LmVuZCgpOwoJCSAgICBmb3IoO2FJdGVyICE9IGFFbmQ7KythSXRlcikKCQkJewoJCQkJT1RhYmxlRmllbGREZXNjUmVmCXBFbnRyeUZpZWxkID0gKmFJdGVyOwoJCQkJaWYgKCBwRW50cnlGaWVsZC0+SXNHcm91cEJ5KCkgKQoJCQkJewoJCQkJCURCR19BU1NFUlQocEVudHJ5RmllbGQtPkdldEZpZWxkKCkuZ2V0TGVuZ3RoKCksIktlaW4gRmllbGROYW1lIHZvcmhhbmRlbiE7LSgiKTsKCQkJCQk6OnJ0bDo6T1VTdHJpbmcgc0dyb3VwQnlQYXJ0ID0gcXVvdGVUYWJsZUFsaWFzKGJNdWx0aSxwRW50cnlGaWVsZC0+R2V0QWxpYXMoKSxhUXVvdGUpOwoKCQkJCQkvLyBvbmx5IHF1b3RlIHRoZSBmaWVsZCBuYW1lIHdoZW4gaXQgaXNuJ3QgY2FsY3VsYXRlZAoJCQkJCWlmICggcEVudHJ5RmllbGQtPmlzTm9uZUZ1bmN0aW9uKCkgKQogICAgICAgICAgICAgICAgICAgIHsKCQkJCQkJc0dyb3VwQnlQYXJ0ICs9IDo6ZGJ0b29sczo6cXVvdGVOYW1lKGFRdW90ZSwgcEVudHJ5RmllbGQtPkdldEZpZWxkKCkpOwogICAgICAgICAgICAgICAgICAgIH0KCQkJCQllbHNlCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICA6OnJ0bDo6T1VTdHJpbmcgYVRtcCA9IHBFbnRyeUZpZWxkLT5HZXRGaWVsZCgpOwoJCQkJCQk6OnJ0bDo6T1VTdHJpbmcgYUVycm9yTXNnOwoJCQkJCQlSZWZlcmVuY2U8WFByb3BlcnR5U2V0PiB4Q29sdW1uOwogICAgICAgICAgICAgICAgICAgICAgICA6OnN0ZDo6YXV0b19wdHI8IDo6Y29ubmVjdGl2aXR5OjpPU1FMUGFyc2VOb2RlPiBwUGFyc2VOb2RlKF9wVmlldy0+Z2V0UHJlZGljYXRlVHJlZUZyb21FbnRyeShwRW50cnlGaWVsZCxhVG1wLGFFcnJvck1zZyx4Q29sdW1uKSk7CgkJCQkJCWlmIChwUGFyc2VOb2RlLmdldCgpKQoJCQkJCQl7CgkJCQkJCQk6OnJ0bDo6T1VTdHJpbmcgc0dyb3VwQnk7CgkJCQkJCQlwUGFyc2VOb2RlLT5nZXRDaGlsZCgwKS0+cGFyc2VOb2RlVG9TdHIoCXNHcm91cEJ5LAoJCQkJCQkJCQkJCQkJCXhDb25uZWN0aW9uLAoJCQkJCQkJCQkJCQkJCSZyQ29udHJvbGxlci5nZXRQYXJzZXIoKS5nZXRDb250ZXh0KCksCgkJCQkJCQkJCQkJCQkJc2FsX0ZhbHNlLAoJCQkJCQkJCQkJCQkJCSFwRW50cnlGaWVsZC0+aXNPdGhlckZ1bmN0aW9uKCkpOwoJCQkJCQkJc0dyb3VwQnlQYXJ0ICs9IHNHcm91cEJ5OwoJCQkJCQl9CgkJCQkJCWVsc2UKCQkJCQkJCXNHcm91cEJ5UGFydCArPSBwRW50cnlGaWVsZC0+R2V0RmllbGQoKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgaWYgKCBhR3JvdXBCeU5hbWVzLmZpbmQoc0dyb3VwQnlQYXJ0KSA9PSBhR3JvdXBCeU5hbWVzLmVuZCgpICkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGFHcm91cEJ5TmFtZXMuaW5zZXJ0KDo6c3RkOjptYXA8IHJ0bDo6T1VTdHJpbmcsYm9vbD46OnZhbHVlX3R5cGUoc0dyb3VwQnlQYXJ0LHRydWUpKTsKICAgICAgICAgICAgICAgICAgICAgICAgYUdyb3VwQnlTdHIgKz0gc0dyb3VwQnlQYXJ0OwoJCQkJCSAgICBhR3JvdXBCeVN0ciArPSA6OnJ0bDo6T1VTdHJpbmcoJywnKTsKICAgICAgICAgICAgICAgICAgICB9CgkJCQl9CgkJCX0KCQkJaWYgKCBhR3JvdXBCeVN0ci5nZXRMZW5ndGgoKSApCgkJCXsKCQkJCWFHcm91cEJ5U3RyID0gYUdyb3VwQnlTdHIucmVwbGFjZUF0KGFHcm91cEJ5U3RyLmdldExlbmd0aCgpLTEsMSwgOjpydGw6Ok9VU3RyaW5nKCcgJykgKTsKCQkJCTo6cnRsOjpPVVN0cmluZyBhR3JvdXBCeVN0cjIgPSA6OnJ0bDo6T1VTdHJpbmc6OmNyZWF0ZUZyb21Bc2NpaSgiIEdST1VQIEJZICIpOwoJCQkJYUdyb3VwQnlTdHIyICs9IGFHcm91cEJ5U3RyOwoJCQkJYUdyb3VwQnlTdHIgPSBhR3JvdXBCeVN0cjI7CgkJCX0KCQl9CgkJY2F0Y2goU1FMRXhjZXB0aW9uJikKCQl7CgkJCU9TTF9BU1NFUlQoISJGYWlsdXJlIHdoaWxlIGJ1aWxkaW5nIGdyb3VwIGJ5ISIpOwoJCX0KCQlyZXR1cm4gYUdyb3VwQnlTdHI7Cgl9CgkvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoJU3FsUGFyc2VFcnJvciBHZXRPUkNyaXRlcmlhKE9RdWVyeURlc2lnblZpZXcqIF9wVmlldywKCQkJCQkJCQlPU2VsZWN0aW9uQnJvd3NlQm94KiBfcFNlbGVjdGlvbkJydywKCQkJCQkJCQljb25zdCA6OmNvbm5lY3Rpdml0eTo6T1NRTFBhcnNlTm9kZSAqIHBDb25kaXRpb24sCgkJCQkJCQkJc2FsX3VJbnQxNiYgbkxldmVsICwKCQkJCQkJCQlzYWxfQm9vbCBiSGF2aW5nID0gc2FsX0ZhbHNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgYkFkZE9yT25PbmVMaW5lID0gZmFsc2UpOwoJLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCVNxbFBhcnNlRXJyb3IgR2V0U2VsZWN0aW9uQ3JpdGVyaWEoCU9RdWVyeURlc2lnblZpZXcqIF9wVmlldywKCQkJCQkJCQkJCU9TZWxlY3Rpb25Ccm93c2VCb3gqIF9wU2VsZWN0aW9uQnJ3LAoJCQkJCQkJCQkJY29uc3QgOjpjb25uZWN0aXZpdHk6Ok9TUUxQYXJzZU5vZGUqIHBOb2RlLAoJCQkJCQkJCQkJc2FsX3VJbnQxNiYgckxldmVsICkKCXsKCQlpZiAoIVNRTF9JU1JVTEUocE5vZGUsIHNlbGVjdF9zdGF0ZW1lbnQpKQoJCQlyZXR1cm4gZU5vU2VsZWN0U3RhdGVtZW50OwoKCQkvLyBueWk6IG1laHIgUHJ1ZWZ1bmcgYXVmIGtvcnJla3RlIFN0cnVrdHVyIQoJCXBOb2RlID0gcE5vZGUgPyBwTm9kZS0+Z2V0Q2hpbGQoMyktPmdldENoaWxkKDEpIDogTlVMTDsKCQkvLyBubyB3aGVyZSBjbGF1c2UgZm91bmQKCQlpZiAoIXBOb2RlIHx8IHBOb2RlLT5pc0xlYWYoKSkKCQkJcmV0dXJuIGVPazsKCgkJLy8gTmFlY2hzdGVyIGZyZWllciBTYXR6IC4uLgoJCVNxbFBhcnNlRXJyb3IgZUVycm9yQ29kZSA9IGVPazsKCQk6OmNvbm5lY3Rpdml0eTo6T1NRTFBhcnNlTm9kZSAqIHBDb25kaXRpb24gPSBwTm9kZS0+Z2V0Q2hpbGQoMSk7CgkJaWYgKCBwQ29uZGl0aW9uICkgLy8gbm8gd2hlcmUgY2xhdXNlCgkJewoJCQkvLyBub3cgd2UgaGF2ZSB0byBjaGVjaCB0aGUgb3RoZXIgY29uZGl0aW9ucwoJCQkvLyBmaXJzdCBtYWtlIHRoZSBsb2dpY2FsIGVhc2llcgoJCQk6OmNvbm5lY3Rpdml0eTo6T1NRTFBhcnNlTm9kZTo6bmVnYXRlU2VhcmNoQ29uZGl0aW9uKHBDb25kaXRpb24pOwoJCQk6OmNvbm5lY3Rpdml0eTo6T1NRTFBhcnNlTm9kZSAqcE5vZGVUbXAgPSBwTm9kZS0+Z2V0Q2hpbGQoMSk7CgoJCQk6OmNvbm5lY3Rpdml0eTo6T1NRTFBhcnNlTm9kZTo6ZGlzanVuY3RpdmVOb3JtYWxGb3JtKHBOb2RlVG1wKTsKCQkJcE5vZGVUbXAgPSBwTm9kZS0+Z2V0Q2hpbGQoMSk7CgkJCTo6Y29ubmVjdGl2aXR5OjpPU1FMUGFyc2VOb2RlOjphYnNvcnB0aW9ucyhwTm9kZVRtcCk7CgkJCXBOb2RlVG1wID0gcE5vZGUtPmdldENoaWxkKDEpOwogICAgICAgICAgICAvLyBjb21wcmVzcyBzb3J0IHRoZSBjcml0ZXJpYSBAc2VlIGh0dHA6Ly93d3cub3Blbm9mZmljZS5vcmcvaXNzdWVzL3Nob3dfYnVnLmNnaT9pZD0yNDA3OQogICAgICAgICAgICBPU1FMUGFyc2VOb2RlOjpjb21wcmVzcyhwTm9kZVRtcCk7CiAgICAgICAgICAgIHBOb2RlVG1wID0gcE5vZGUtPmdldENoaWxkKDEpOwoKCQkJLy8gZmlyc3QgZXh0cmFjdCB0aGUgaW5uZXIgam9pbnMgY29uZGl0aW9ucwoJCQlHZXRJbm5lckpvaW5Dcml0ZXJpYShfcFZpZXcscE5vZGVUbXApOwoJCQkvLyBub3cgc2ltcGxpZnkgYWdhaW4sIGpvaW4gYXJlIGNoZWNrZWQgaW4gQ29tcGFyaXNvblByZWRpY2F0ZQoJCQk6OmNvbm5lY3Rpdml0eTo6T1NRTFBhcnNlTm9kZTo6YWJzb3JwdGlvbnMocE5vZGVUbXApOwoJCQlwTm9kZVRtcCA9IHBOb2RlLT5nZXRDaGlsZCgxKTsJCQkKCgkJCS8vIGl0IGNvdWxkIGhhcHBlbiB0aGF0IHBDb25kaXRpb24gaXMgbm90IG1vcmUgdmFsaWQKCQkJZUVycm9yQ29kZSA9IEdldE9SQ3JpdGVyaWEoX3BWaWV3LF9wU2VsZWN0aW9uQnJ3LHBOb2RlVG1wLCByTGV2ZWwpOwoJCX0KCQlyZXR1cm4gZUVycm9yQ29kZTsKCX0KCS8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCglTcWxQYXJzZUVycm9yIEdldEFORENyaXRlcmlhKAlPUXVlcnlEZXNpZ25WaWV3KiBfcFZpZXcsCgkJCQkJCQkJCU9TZWxlY3Rpb25Ccm93c2VCb3gqIF9wU2VsZWN0aW9uQnJ3LAoJCQkJCQkJCQljb25zdCAgOjpjb25uZWN0aXZpdHk6Ok9TUUxQYXJzZU5vZGUgKiBwQ29uZGl0aW9uLAoJCQkJCQkJCQlzYWxfdUludDE2JiBuTGV2ZWwsCgkJCQkJCQkJCXNhbF9Cb29sIGJIYXZpbmcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgYkFkZE9yT25PbmVMaW5lKTsKCS8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCglTcWxQYXJzZUVycm9yIENvbXBhcmlzb25QcmVkaWNhdGUoT1F1ZXJ5RGVzaWduVmlldyogX3BWaWV3LAoJCQkJCQkJT1NlbGVjdGlvbkJyb3dzZUJveCogX3BTZWxlY3Rpb25CcncsCgkJCQkJCQljb25zdCA6OmNvbm5lY3Rpdml0eTo6T1NRTFBhcnNlTm9kZSAqIHBDb25kaXRpb24sCgkJCQkJCQljb25zdCBzYWxfdUludDE2IG5MZXZlbCwKCQkJCQkJCXNhbF9Cb29sIGJIYXZpbmcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIGJBZGRPck9uT25lTGluZSk7CgkvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoJU3FsUGFyc2VFcnJvciBHZXRPUkNyaXRlcmlhKE9RdWVyeURlc2lnblZpZXcqIF9wVmlldywKCQkJCQkJCQlPU2VsZWN0aW9uQnJvd3NlQm94KiBfcFNlbGVjdGlvbkJydywKCQkJCQkJCQljb25zdCA6OmNvbm5lY3Rpdml0eTo6T1NRTFBhcnNlTm9kZSAqIHBDb25kaXRpb24sCgkJCQkJCQkJc2FsX3VJbnQxNiYgbkxldmVsICwKCQkJCQkJCQlzYWxfQm9vbCBiSGF2aW5nLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgYkFkZE9yT25PbmVMaW5lKQoJewoJCVNxbFBhcnNlRXJyb3IgZUVycm9yQ29kZSA9IGVPazsKCgkJLy8gUnVuZGUgS2xhbW1lcm4gdW0gZGVuIEF1c2RydWNrCgkJaWYgKHBDb25kaXRpb24tPmNvdW50KCkgPT0gMyAmJgoJCQlTUUxfSVNQVU5DVFVBVElPTihwQ29uZGl0aW9uLT5nZXRDaGlsZCgwKSwiKCIpICYmCgkJCVNRTF9JU1BVTkNUVUFUSU9OKHBDb25kaXRpb24tPmdldENoaWxkKDIpLCIpIikpCgkJewoJCQllRXJyb3JDb2RlID0gR2V0T1JDcml0ZXJpYShfcFZpZXcsX3BTZWxlY3Rpb25CcncscENvbmRpdGlvbi0+Z2V0Q2hpbGQoMSksbkxldmVsLGJIYXZpbmcsYkFkZE9yT25PbmVMaW5lKTsKCQl9CgkJLy8gb2RlciBWZXJrbnVlcGZ1bmcKCQkvLyBhIHNlYXJjaGNvbmRpdGlvbiBjYW4gb25seSBsb29rIGxpa2UgdGhpczogc2VhcmNoX2NvbmRpdGlvbiBTUUxfVE9LRU5fT1IgYm9vbGVhbl90ZXJtCgkJZWxzZSBpZiAoU1FMX0lTUlVMRShwQ29uZGl0aW9uLHNlYXJjaF9jb25kaXRpb24pKQoJCXsKCQkJZm9yIChpbnQgaSA9IDA7IGkgPCAzICYmIGVFcnJvckNvZGUgPT0gZU9rIDsgaSs9MikKCQkJewogICAgICAgICAgICAgICAgY29uc3QgIDo6Y29ubmVjdGl2aXR5OjpPU1FMUGFyc2VOb2RlKiBwQ2hpbGQgPSBwQ29uZGl0aW9uLT5nZXRDaGlsZChpKTsKCQkJCWlmICggU1FMX0lTUlVMRShwQ2hpbGQsc2VhcmNoX2NvbmRpdGlvbikgKQoJCQkJCWVFcnJvckNvZGUgPSBHZXRPUkNyaXRlcmlhKF9wVmlldyxfcFNlbGVjdGlvbkJydyxwQ2hpbGQsbkxldmVsLGJIYXZpbmcsYkFkZE9yT25PbmVMaW5lKTsKCQkJCWVsc2UKCQkJCXsKICAgICAgICAgICAgICAgICAgICBlRXJyb3JDb2RlID0gR2V0QU5EQ3JpdGVyaWEoX3BWaWV3LF9wU2VsZWN0aW9uQnJ3LHBDaGlsZCwgbkxldmVsLGJIYXZpbmcsIGkgPT0gMCA/IGZhbHNlIDogYkFkZE9yT25PbmVMaW5lKTsKCQkJCQlpZiAoICFiQWRkT3JPbk9uZUxpbmUpCgkJCQkJCW5MZXZlbCsrOwoJCQkJfQoJCQl9CgkJfQoJCWVsc2UKCQkJZUVycm9yQ29kZSA9IEdldEFORENyaXRlcmlhKCBfcFZpZXcsX3BTZWxlY3Rpb25CcncscENvbmRpdGlvbiwgbkxldmVsLCBiSGF2aW5nLGJBZGRPck9uT25lTGluZSApOwoKCQlyZXR1cm4gZUVycm9yQ29kZTsKCX0KICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgIGJvb2wgQ2hlY2tPckNyaXRlcmlhKGNvbnN0IDo6Y29ubmVjdGl2aXR5OjpPU1FMUGFyc2VOb2RlKiBfcENvbmRpdGlvbiw6OmNvbm5lY3Rpdml0eTo6T1NRTFBhcnNlTm9kZSogX3BGaXJzdENvbHVtblJlZikKICAgIHsKICAgICAgICBib29sIGJSZXQgPSB0cnVlOwogICAgICAgIDo6Y29ubmVjdGl2aXR5OjpPU1FMUGFyc2VOb2RlKiBwRmlyc3RDb2x1bW5SZWYgPSBfcEZpcnN0Q29sdW1uUmVmOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMyAmJiBiUmV0OyBpKz0yKQoJCXsKICAgICAgICAgICAgY29uc3QgIDo6Y29ubmVjdGl2aXR5OjpPU1FMUGFyc2VOb2RlKiBwQ2hpbGQgPSBfcENvbmRpdGlvbi0+Z2V0Q2hpbGQoaSk7CiAgICAgICAgICAgIGlmICggU1FMX0lTUlVMRShwQ2hpbGQsc2VhcmNoX2NvbmRpdGlvbikgKQogICAgICAgICAgICAgICAgYlJldCA9IENoZWNrT3JDcml0ZXJpYShwQ2hpbGQscEZpcnN0Q29sdW1uUmVmKTsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvLyB0aGlzIGlzIGEgc2ltcGxlIHdheSB0byB0ZXN0IGNvbHVtbnMgYXJlIHRoZSBzYW1lLCBtYXkgYmUgd2UgaGF2ZSB0byBhZGp1c3QgdGhpcyBhbGdvIGEgbGl0dGxlIGJpdCBpbiBmdXR1cmUuIDotKQogICAgICAgICAgICAgICAgOjpjb25uZWN0aXZpdHk6Ok9TUUxQYXJzZU5vZGUqIHBTZWNvbmRDb2x1bW5SZWYgPSBwQ2hpbGQtPmdldEJ5UnVsZSg6OmNvbm5lY3Rpdml0eTo6T1NRTFBhcnNlTm9kZTo6Y29sdW1uX3JlZik7CiAgICAgICAgICAgICAgICBpZiAoIHBGaXJzdENvbHVtblJlZiAmJiBwU2Vjb25kQ29sdW1uUmVmICkKICAgICAgICAgICAgICAgICAgICBiUmV0ID0gKnBGaXJzdENvbHVtblJlZiA9PSAqcFNlY29uZENvbHVtblJlZjsKICAgICAgICAgICAgICAgIGVsc2UgaWYgKCAhcEZpcnN0Q29sdW1uUmVmICkKICAgICAgICAgICAgICAgICAgICBwRmlyc3RDb2x1bW5SZWYgPSBwU2Vjb25kQ29sdW1uUmVmOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiBiUmV0OwogICAgfQoJLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoJU3FsUGFyc2VFcnJvciBHZXRBTkRDcml0ZXJpYSgJT1F1ZXJ5RGVzaWduVmlldyogX3BWaWV3LAoJCQkJCQkJCQlPU2VsZWN0aW9uQnJvd3NlQm94KiBfcFNlbGVjdGlvbkJydywKCQkJCQkJCQkJY29uc3QgIDo6Y29ubmVjdGl2aXR5OjpPU1FMUGFyc2VOb2RlICogcENvbmRpdGlvbiwKCQkJCQkJCQkJc2FsX3VJbnQxNiYgbkxldmVsLAoJCQkJCQkJCQlzYWxfQm9vbCBiSGF2aW5nLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIGJBZGRPck9uT25lTGluZSkKCXsKCQljb25zdCA6OmNvbTo6c3VuOjpzdGFyOjpsYW5nOjpMb2NhbGUJYUxvY2FsZSA9IF9wVmlldy0+Z2V0TG9jYWxlKCk7CgkJY29uc3QgOjpydGw6Ok9VU3RyaW5nIHNEZWNpbWFsID0gX3BWaWV3LT5nZXREZWNpbWFsU2VwYXJhdG9yKCk7CgoJCS8vIGljaCB3ZXJkZSBlaW4gcGFhciBNYWwgZWluZW4gZ2VjYXN0ZXRlbiBQb2ludGVyIGF1ZiBtZWluZW4gOjpjb206OnN1bjo6c3Rhcjo6c2RiY3g6OkNvbnRhaW5lciBicmF1Y2hlbgoJCU9RdWVyeUNvbnRyb2xsZXImIHJDb250cm9sbGVyID0gc3RhdGljX2Nhc3Q8T1F1ZXJ5Q29udHJvbGxlciY+KF9wVmlldy0+Z2V0Q29udHJvbGxlcigpKTsKCQlTcWxQYXJzZUVycm9yIGVFcnJvckNvZGUgPSBlT2s7CgoJCS8vIFJ1bmRlIEtsYW1tZXJuCgkJaWYgKFNRTF9JU1JVTEUocENvbmRpdGlvbixib29sZWFuX3ByaW1hcnkpKQoJCXsKICAgICAgICAgICAgLy8gY2hlY2sgaWYgd2UgaGF2ZSB0byBwdXQgdGhlIG9yIGNyaXRlcmlhIG9uIG9uZSBsaW5lLgoJCQljb25zdCAgOjpjb25uZWN0aXZpdHk6Ok9TUUxQYXJzZU5vZGUqIHBTZWFyY2hDb25kaXRpb24gPSBwQ29uZGl0aW9uLT5nZXRDaGlsZCgxKTsKICAgICAgICAgICAgYm9vbCBiTXVzdEFkZE9yT25PbmVMaW5lID0gQ2hlY2tPckNyaXRlcmlhKHBTZWFyY2hDb25kaXRpb24sTlVMTCk7CgkJCWlmICggU1FMX0lTUlVMRSggcFNlYXJjaENvbmRpdGlvbiwgc2VhcmNoX2NvbmRpdGlvbikgKSAvLyB3ZSBoYXZlIGEgb3IKCQkJewoJCQkJX3BTZWxlY3Rpb25CcnctPkR1cGxpY2F0ZUNvbmRpdGlvbkxldmVsKCBuTGV2ZWwpOwoJCQkJZUVycm9yQ29kZSA9IEdldE9SQ3JpdGVyaWEoX3BWaWV3LF9wU2VsZWN0aW9uQnJ3LHBTZWFyY2hDb25kaXRpb24tPmdldENoaWxkKDApLCBuTGV2ZWwsYkhhdmluZyxiTXVzdEFkZE9yT25PbmVMaW5lICk7CQkJCQoJCQkJKytuTGV2ZWw7CgkJCQllRXJyb3JDb2RlID0gR2V0T1JDcml0ZXJpYShfcFZpZXcsX3BTZWxlY3Rpb25CcncscFNlYXJjaENvbmRpdGlvbi0+Z2V0Q2hpbGQoMiksIG5MZXZlbCxiSGF2aW5nLGJNdXN0QWRkT3JPbk9uZUxpbmUgKTsKCQkJfQoJCQllbHNlCgkJCQllRXJyb3JDb2RlID0gR2V0T1JDcml0ZXJpYShfcFZpZXcsX3BTZWxlY3Rpb25CcncscFNlYXJjaENvbmRpdGlvbiwgbkxldmVsLGJIYXZpbmcsYk11c3RBZGRPck9uT25lTGluZSApOwoJCX0KCQkvLyBEYXMgZXJzdGUgRWxlbWVudCBpc3QgKHdpZWRlcikgZWluZSBBTkQtVmVya251ZXBmdW5nCgkJZWxzZSBpZiAoIFNRTF9JU1JVTEUocENvbmRpdGlvbixib29sZWFuX3Rlcm0pICkKCQl7CiAgICAgICAgICAgIE9TTF9FTlNVUkUocENvbmRpdGlvbi0+Y291bnQoKSA9PSAzLCJJbGxlZ2FsIGRlZmluaWZpdG9uIG9mIGJvb2xlYW5fdGVybSIpOwoJCQllRXJyb3JDb2RlID0gR2V0QU5EQ3JpdGVyaWEoX3BWaWV3LF9wU2VsZWN0aW9uQnJ3LHBDb25kaXRpb24tPmdldENoaWxkKDApLCBuTGV2ZWwsYkhhdmluZyxiQWRkT3JPbk9uZUxpbmUgKTsKCQkJaWYgKCBlRXJyb3JDb2RlID09IGVPayApCgkJCQllRXJyb3JDb2RlID0gR2V0QU5EQ3JpdGVyaWEoX3BWaWV3LF9wU2VsZWN0aW9uQnJ3LHBDb25kaXRpb24tPmdldENoaWxkKDIpLCBuTGV2ZWwsYkhhdmluZyxiQWRkT3JPbk9uZUxpbmUgKTsKCQl9CgkJZWxzZSBpZiAoU1FMX0lTUlVMRSggcENvbmRpdGlvbiwgY29tcGFyaXNvbl9wcmVkaWNhdGUpKQoJCXsKCQkJZUVycm9yQ29kZSA9IENvbXBhcmlzb25QcmVkaWNhdGUoX3BWaWV3LF9wU2VsZWN0aW9uQnJ3LHBDb25kaXRpb24sbkxldmVsLGJIYXZpbmcsYkFkZE9yT25PbmVMaW5lKTsKCQl9CgkJZWxzZSBpZiggU1FMX0lTUlVMRShwQ29uZGl0aW9uLGxpa2VfcHJlZGljYXRlKSApCgkJewogICAgICAgICAgICBjb25zdCAgOjpjb25uZWN0aXZpdHk6Ok9TUUxQYXJzZU5vZGUqIHBWYWx1ZUV4cCA9IHBDb25kaXRpb24tPmdldENoaWxkKDApOwoJCQlpZiAoU1FMX0lTUlVMRShwVmFsdWVFeHAsIGNvbHVtbl9yZWYgKSApCgkJCXsKCQkJCTo6cnRsOjpPVVN0cmluZyBhQ29sdW1uTmFtZTsKCQkJCTo6cnRsOjpPVVN0cmluZwlhQ29uZGl0aW9uOwoJCQkJUmVmZXJlbmNlPCBYQ29ubmVjdGlvbj4geENvbm5lY3Rpb24gPSByQ29udHJvbGxlci5nZXRDb25uZWN0aW9uKCk7CgkJCQlpZiAoIHhDb25uZWN0aW9uLmlzKCkgKQoJCQkJewoJCQkJCVJlZmVyZW5jZTwgWERhdGFiYXNlTWV0YURhdGEgPiAgeE1ldGFEYXRhID0geENvbm5lY3Rpb24tPmdldE1ldGFEYXRhKCk7CgkJCQkJLy8gdGhlIGludGVybmF0aW9uYWwgZG9lc24ndCBtYXR0ZXIgSSBoYXZlIGEgc3RyaW5nCgkJCQkJcENvbmRpdGlvbi0+cGFyc2VOb2RlVG9QcmVkaWNhdGVTdHIoYUNvbmRpdGlvbiwKCQkJCQkJCQkJCQkJCQl4Q29ubmVjdGlvbiwKCQkJCQkJCQkJCQkJCQlyQ29udHJvbGxlci5nZXROdW1iZXJGb3JtYXR0ZXIoKSwKCQkJCQkJCQkJCQkJCQlhTG9jYWxlLAoJCQkJCQkJCQkJCQkJCXN0YXRpY19jYXN0PHNhbF9DaGFyPihzRGVjaW1hbC50b0NoYXIoKSksCgkJCQkJCQkJCQkJCQkJJnJDb250cm9sbGVyLmdldFBhcnNlcigpLmdldENvbnRleHQoKSk7CgoJCQkJCXBWYWx1ZUV4cC0+cGFyc2VOb2RlVG9QcmVkaWNhdGVTdHIoCWFDb2x1bW5OYW1lLAoJCQkJCQkJCQkJCQkJCXhDb25uZWN0aW9uLAoJCQkJCQkJCQkJCQkJCXJDb250cm9sbGVyLmdldE51bWJlckZvcm1hdHRlcigpLAoJCQkJCQkJCQkJCQkJCWFMb2NhbGUsCgkJCQkJCQkJCQkJCQkJc3RhdGljX2Nhc3Q8c2FsX0NoYXI+KHNEZWNpbWFsLnRvQ2hhcigpKSwKCQkJCQkJCQkJCQkJCQkmckNvbnRyb2xsZXIuZ2V0UGFyc2VyKCkuZ2V0Q29udGV4dCgpKTsKCgkJCQkJLy8gZG9uJ3QgZGlzcGxheSB0aGUgY29sdW1uIG5hbWUKCQkJCQlhQ29uZGl0aW9uID0gYUNvbmRpdGlvbi5jb3B5KGFDb2x1bW5OYW1lLmdldExlbmd0aCgpKTsKCQkJCQlhQ29uZGl0aW9uID0gYUNvbmRpdGlvbi50cmltKCk7CgkJCQl9CgoJCQkJT1RhYmxlRmllbGREZXNjUmVmIGFEcmFnTGVmdCA9IG5ldyBPVGFibGVGaWVsZERlc2MoKTsKCQkJCWlmICggZU9rID09ICggZUVycm9yQ29kZSA9IEZpbGxEcmFnSW5mbyhfcFZpZXcscFZhbHVlRXhwLGFEcmFnTGVmdCkgKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAoIGJIYXZpbmcgKQoJCQkJCSAgICBhRHJhZ0xlZnQtPlNldEdyb3VwQnkoc2FsX1RydWUpOwoJCQkJCV9wU2VsZWN0aW9uQnJ3LT5BZGRDb25kaXRpb24oYURyYWdMZWZ0LCBhQ29uZGl0aW9uLCBuTGV2ZWwsYkFkZE9yT25PbmVMaW5lKTsKICAgICAgICAgICAgICAgIH0KCQkJfQogICAgICAgICAgICBlbHNlIGlmKFNRTF9JU1JVTEVPUjIocFZhbHVlRXhwLGdlbmVyYWxfc2V0X2ZjdCAsc2V0X2ZjdF9zcGVjKQkgICAgICAgIHx8CgkJCQkJCQlTUUxfSVNSVUxFT1IyKHBWYWx1ZUV4cCxwb3NpdGlvbl9leHAsZXh0cmFjdF9leHApCXx8CgkJCQkJCQlTUUxfSVNSVUxFT1IyKHBWYWx1ZUV4cCxmb2xkLGNoYXJfc3Vic3RyaW5nX2ZjdCkJfHwKCQkJCQkJCVNRTF9JU1JVTEVPUjIocFZhbHVlRXhwLGxlbmd0aF9leHAsY2hhcl92YWx1ZV9mY3QpKQoJCSAgICB7CgkJCSAgICBBZGRGdW5jdGlvbkNvbmRpdGlvbigJX3BWaWV3LAoJCQkJCQkJCQkgICAgX3BTZWxlY3Rpb25CcncsCgkJCQkJCQkJCSAgICBwQ29uZGl0aW9uLAoJCQkJCQkJCQkgICAgbkxldmVsLAoJCQkJCQkJCQkgICAgYkhhdmluZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJBZGRPck9uT25lTGluZSk7CgkJICAgIH0KCQkJZWxzZQoJCQl7CgkJCQllRXJyb3JDb2RlID0gZU5vQ29sdW1uSW5MaWtlOwoJCQkJU3RyaW5nIHNFcnJvcihNb2R1bGVSZXMoU1RSX1FSWV9MSUtFX0xFRlRfTk9fQ09MVU1OKSk7CgkJCQlfcFZpZXctPmdldENvbnRyb2xsZXIoKS5hcHBlbmRFcnJvciggc0Vycm9yICk7CgkJCX0KCQl9CgkJZWxzZSBpZigJU1FMX0lTUlVMRU9SMihwQ29uZGl0aW9uLHRlc3RfZm9yX251bGwsaW5fcHJlZGljYXRlKQoJCQkJfHwJU1FMX0lTUlVMRU9SMihwQ29uZGl0aW9uLGFsbF9vcl9hbnlfcHJlZGljYXRlLGJldHdlZW5fcHJlZGljYXRlKSkKCQl7CgkJCWlmICggU1FMX0lTUlVMRU9SMihwQ29uZGl0aW9uLT5nZXRDaGlsZCgwKSwgc2V0X2ZjdF9zcGVjICwgZ2VuZXJhbF9zZXRfZmN0ICkgKQoJCQl7CgkJCQlBZGRGdW5jdGlvbkNvbmRpdGlvbigJX3BWaWV3LAoJCQkJCQkJCQkJX3BTZWxlY3Rpb25CcncsCgkJCQkJCQkJCQlwQ29uZGl0aW9uLAoJCQkJCQkJCQkJbkxldmVsLAoJCQkJCQkJCQkJYkhhdmluZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJBZGRPck9uT25lTGluZSk7CgkJCX0KCQkJZWxzZSBpZiAoIFNRTF9JU1JVTEUocENvbmRpdGlvbi0+Z2V0Q2hpbGQoMCksIGNvbHVtbl9yZWYgKSApCgkJCXsKCQkJCS8vIHBhcnNlIGNvbmRpdGlvbgoJCQkJOjpydGw6Ok9VU3RyaW5nIHNDb25kaXRpb24gPSBQYXJzZUNvbmRpdGlvbihyQ29udHJvbGxlcixwQ29uZGl0aW9uLHNEZWNpbWFsLGFMb2NhbGUsMSk7CgkJCQlPVGFibGVGaWVsZERlc2NSZWYJYURyYWdMZWZ0ID0gbmV3IE9UYWJsZUZpZWxkRGVzYygpOwoJCQkJaWYgKCBlT2sgPT0gKCBlRXJyb3JDb2RlID0gRmlsbERyYWdJbmZvKF9wVmlldyxwQ29uZGl0aW9uLT5nZXRDaGlsZCgwKSxhRHJhZ0xlZnQpKSApCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCBiSGF2aW5nICkKCQkJCQkgICAgYURyYWdMZWZ0LT5TZXRHcm91cEJ5KHNhbF9UcnVlKTsKCQkJCQlfcFNlbGVjdGlvbkJydy0+QWRkQ29uZGl0aW9uKGFEcmFnTGVmdCwgc0NvbmRpdGlvbiwgbkxldmVsLGJBZGRPck9uT25lTGluZSk7CiAgICAgICAgICAgICAgICB9CgkJCX0KCQkJZWxzZQoJCQl7CgkJCQkvLyBGdW5rdGlvbnMtQmVkaW5ndW5nIHBhcnNlbgoJCQkJOjpydGw6Ok9VU3RyaW5nCXNDb25kaXRpb24gPSBQYXJzZUNvbmRpdGlvbihyQ29udHJvbGxlcixwQ29uZGl0aW9uLHNEZWNpbWFsLGFMb2NhbGUsMSk7CgkJCQlSZWZlcmVuY2U8IFhDb25uZWN0aW9uPiB4Q29ubmVjdGlvbiA9IHJDb250cm9sbGVyLmdldENvbm5lY3Rpb24oKTsKCQkJCVJlZmVyZW5jZTwgWERhdGFiYXNlTWV0YURhdGEgPiAgeE1ldGFEYXRhID0geENvbm5lY3Rpb24tPmdldE1ldGFEYXRhKCk7CgkJCQkJLy8gdGhlIGludGVybmF0aW9uYWwgZG9lc24ndCBtYXR0ZXIgSSBoYXZlIGEgc3RyaW5nCgkJCQk6OnJ0bDo6T1VTdHJpbmcgc05hbWU7CgkJCQlwQ29uZGl0aW9uLT5nZXRDaGlsZCgwKS0+cGFyc2VOb2RlVG9QcmVkaWNhdGVTdHIoc05hbWUsCgkJCQkJCQkJCQkJCQl4Q29ubmVjdGlvbiwKCQkJCQkJCQkJCQkJCXJDb250cm9sbGVyLmdldE51bWJlckZvcm1hdHRlcigpLAoJCQkJCQkJCQkJCQkJYUxvY2FsZSwKCQkJCQkJCQkJCQkJCXN0YXRpY19jYXN0PHNhbF9DaGFyPihzRGVjaW1hbC50b0NoYXIoKSksCgkJCQkJCQkJCQkJCQkmckNvbnRyb2xsZXIuZ2V0UGFyc2VyKCkuZ2V0Q29udGV4dCgpKTsKCgkJCQlPVGFibGVGaWVsZERlc2NSZWYgYURyYWdMZWZ0ID0gbmV3IE9UYWJsZUZpZWxkRGVzYygpOwoJCQkJYURyYWdMZWZ0LT5TZXRGaWVsZChzTmFtZSk7CgkJCQlhRHJhZ0xlZnQtPlNldEZ1bmN0aW9uVHlwZShGS1RfT1RIRVIpOwoKCQkJCWlmICggYkhhdmluZyApCgkJCQkJYURyYWdMZWZ0LT5TZXRHcm91cEJ5KHNhbF9UcnVlKTsKCQkJCV9wU2VsZWN0aW9uQnJ3LT5BZGRDb25kaXRpb24oYURyYWdMZWZ0LCBzQ29uZGl0aW9uLCBuTGV2ZWwsYkFkZE9yT25PbmVMaW5lKTsKCQkJfQoJCX0KCQllbHNlIGlmKCBTUUxfSVNSVUxFT1IyKHBDb25kaXRpb24sZXhpc3RlbmNlX3Rlc3QsdW5pcXVlX3Rlc3QpICkKCQl7CgkJCS8vIEZ1bmt0aW9ucy1CZWRpbmd1bmcgcGFyc2VuCgkJCTo6cnRsOjpPVVN0cmluZwlhQ29uZGl0aW9uID0gUGFyc2VDb25kaXRpb24ockNvbnRyb2xsZXIscENvbmRpdGlvbixzRGVjaW1hbCxhTG9jYWxlLDApOwoKCQkJT1RhYmxlRmllbGREZXNjUmVmIGFEcmFnTGVmdCA9IG5ldyBPVGFibGVGaWVsZERlc2MoKTsKCQkJYURyYWdMZWZ0LT5TZXRGaWVsZChhQ29uZGl0aW9uKTsKCQkJYURyYWdMZWZ0LT5TZXRGdW5jdGlvblR5cGUoRktUX0NPTkRJVElPTik7CgoJCQllRXJyb3JDb2RlID0gX3BTZWxlY3Rpb25CcnctPkluc2VydEZpZWxkKGFEcmFnTGVmdCxCUk9XU0VSX0lOVkFMSURJRCxzYWxfRmFsc2Usc2FsX1RydWUpLmlzVmFsaWQoKSA/IGVPayA6IGVUb29NYW55Q29sdW1uczsKCQl9CgkJZWxzZSAvLyEgVE9ETyBub3Qgc3VwcG9ydGVkIHlldAoJCQllRXJyb3JDb2RlID0gZVN0YXRlbWVudFRvb0NvbXBsZXg7CgkJLy8gRmVobGVyIGVpbmZhY2ggd2VpdGVycmVpY2hlbi4KCQlyZXR1cm4gZUVycm9yQ29kZTsKCX0KCS8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCglTcWxQYXJzZUVycm9yIEFkZEZ1bmN0aW9uQ29uZGl0aW9uKE9RdWVyeURlc2lnblZpZXcqIF9wVmlldywKCQkJCQkJCU9TZWxlY3Rpb25Ccm93c2VCb3gqIF9wU2VsZWN0aW9uQnJ3LAoJCQkJCQkJY29uc3QgOjpjb25uZWN0aXZpdHk6Ok9TUUxQYXJzZU5vZGUgKiBwQ29uZGl0aW9uLAoJCQkJCQkJY29uc3Qgc2FsX3VJbnQxNiBuTGV2ZWwsCgkJCQkJCQlzYWxfQm9vbCBiSGF2aW5nLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBiQWRkT3JPbk9uZUxpbmUpCgl7CgkJU3FsUGFyc2VFcnJvciBlRXJyb3JDb2RlID0gZU9rOwoJCU9RdWVyeUNvbnRyb2xsZXImIHJDb250cm9sbGVyID0gc3RhdGljX2Nhc3Q8T1F1ZXJ5Q29udHJvbGxlciY+KF9wVmlldy0+Z2V0Q29udHJvbGxlcigpKTsKCiAgICAgICAgT1NRTFBhcnNlTm9kZSogcEZ1bmN0aW9uID0gcENvbmRpdGlvbi0+Z2V0Q2hpbGQoMCk7CgogICAgICAgIE9TTF9FTlNVUkUoU1FMX0lTUlVMRU9SMihwRnVuY3Rpb24sZ2VuZXJhbF9zZXRfZmN0ICxzZXRfZmN0X3NwZWMpCSAgICAgICAgfHwKCQkJCQkJCVNRTF9JU1JVTEVPUjIocEZ1bmN0aW9uLHBvc2l0aW9uX2V4cCxleHRyYWN0X2V4cCkJfHwKCQkJCQkJCVNRTF9JU1JVTEVPUjIocEZ1bmN0aW9uLGZvbGQsY2hhcl9zdWJzdHJpbmdfZmN0KQl8fAoJCQkJCQkJU1FMX0lTUlVMRU9SMihwRnVuY3Rpb24sbGVuZ3RoX2V4cCxjaGFyX3ZhbHVlX2ZjdCksIklsbGVnYWwgY2FsbCEiKTsKCQk6OnJ0bDo6T1VTdHJpbmcJYUNvbmRpdGlvbjsKCQlPVGFibGVGaWVsZERlc2NSZWYgYURyYWdMZWZ0ID0gbmV3IE9UYWJsZUZpZWxkRGVzYygpOwoKCQk6OnJ0bDo6T1VTdHJpbmcgYUNvbHVtbk5hbWU7CgkJUmVmZXJlbmNlPCBYQ29ubmVjdGlvbj4geENvbm5lY3Rpb24gPSByQ29udHJvbGxlci5nZXRDb25uZWN0aW9uKCk7CgkJaWYoeENvbm5lY3Rpb24uaXMoKSkKCQl7CgkJCVJlZmVyZW5jZTwgWERhdGFiYXNlTWV0YURhdGEgPiAgeE1ldGFEYXRhID0geENvbm5lY3Rpb24tPmdldE1ldGFEYXRhKCk7CgkJCXBDb25kaXRpb24tPnBhcnNlTm9kZVRvUHJlZGljYXRlU3RyKGFDb25kaXRpb24sCgkJCQkJCQkJCQkJCXhDb25uZWN0aW9uLAoJCQkJCQkJCQkJCQlyQ29udHJvbGxlci5nZXROdW1iZXJGb3JtYXR0ZXIoKSwKCQkJCQkJCQkJCQkJX3BWaWV3LT5nZXRMb2NhbGUoKSwKCQkJCQkJCQkJCQkJc3RhdGljX2Nhc3Q8c2FsX0NoYXI+KF9wVmlldy0+Z2V0RGVjaW1hbFNlcGFyYXRvcigpLnRvQ2hhcigpKSwKCQkJCQkJCQkJCQkJJnJDb250cm9sbGVyLmdldFBhcnNlcigpLmdldENvbnRleHQoKSk7CgogICAgICAgICAgICBwRnVuY3Rpb24tPnBhcnNlTm9kZVRvU3RyKAlhQ29sdW1uTmFtZSwKCQkJCQkJCQkJCXhDb25uZWN0aW9uLAoJCQkJCQkJCQkJJnJDb250cm9sbGVyLmdldFBhcnNlcigpLmdldENvbnRleHQoKSwKCQkJCQkJCQkJCXNhbF9UcnVlLAoJCQkJCQkJCQkJc2FsX1RydWUpOyAvLyBxdW90ZSBpcyB0byB0cnVlIGJlY2F1c2Ugd2UgbmVlZCBxdW90ZWQgZWxlbWVudHMgaW5zaWRlIHRoZSBmdW5jdGlvbgogICAgICAgICAgICAvLyBpNzU1NTcKCQkJLy9wRnVuY3Rpb24tPnBhcnNlTm9kZVRvUHJlZGljYXRlU3RyKGFDb2x1bW5OYW1lLAoJCQkvLwkJCQkJCQkJCXhDb25uZWN0aW9uLAoJCQkvLwkJCQkJCQkJCXJDb250cm9sbGVyLmdldE51bWJlckZvcm1hdHRlcigpLAoJCQkvLwkJCQkJCQkJCV9wVmlldy0+Z2V0TG9jYWxlKCksCgkJCS8vCQkJCQkJCQkJc3RhdGljX2Nhc3Q8c2FsX0NoYXI+KF9wVmlldy0+Z2V0RGVjaW1hbFNlcGFyYXRvcigpLnRvQ2hhcigpKSwKCQkJLy8JCQkJCQkJCQkmckNvbnRyb2xsZXIuZ2V0UGFyc2VyKCkuZ2V0Q29udGV4dCgpKTsKCQkJLy8gZG9uJ3QgZGlzcGxheSB0aGUgY29sdW1uIG5hbWUKCQkJYUNvbmRpdGlvbiA9IGFDb25kaXRpb24uY29weShhQ29sdW1uTmFtZS5nZXRMZW5ndGgoKSk7CgkJCWFDb25kaXRpb24gPSBhQ29uZGl0aW9uLnRyaW0oKTsKCQkJaWYgKCBhQ29uZGl0aW9uLmluZGV4T2YoJz0nLDApID09IDAgKSAvLyBpZ25vcmUgdGhlIGVxdWFsIHNpZ24KCQkJCWFDb25kaXRpb24gPSBhQ29uZGl0aW9uLmNvcHkoMSk7CgoKCQkJaWYgKCBTUUxfSVNSVUxFKHBGdW5jdGlvbiwgZ2VuZXJhbF9zZXRfZmN0ICkgKQoJCQl7CgkJCQlzYWxfSW50MzIgbkZ1bmN0aW9uVHlwZSA9IEZLVF9BR0dSRUdBVEU7CgkJCQlPU1FMUGFyc2VOb2RlKiBwUGFyYW1Ob2RlID0gcEZ1bmN0aW9uLT5nZXRDaGlsZChwRnVuY3Rpb24tPmNvdW50KCktMik7CgkJCQlpZiAoIHBQYXJhbU5vZGUgJiYgcFBhcmFtTm9kZS0+Z2V0VG9rZW5WYWx1ZSgpLnRvQ2hhcigpID09ICcqJyApCgkJCQl7CgkJCQkJT0pvaW5UYWJsZVZpZXc6Ok9UYWJsZVdpbmRvd01hcCogcFRhYkxpc3QgPSBfcFZpZXctPmdldFRhYmxlVmlldygpLT5HZXRUYWJXaW5NYXAoKTsKCQkJCQlPSm9pblRhYmxlVmlldzo6T1RhYmxlV2luZG93TWFwOjppdGVyYXRvciBhSXRlciA9IHBUYWJMaXN0LT5iZWdpbigpOwogICAgICAgICAgICAgICAgICAgIE9Kb2luVGFibGVWaWV3OjpPVGFibGVXaW5kb3dNYXA6Oml0ZXJhdG9yIGFUYWJFbmQgPSBwVGFiTGlzdC0+ZW5kKCk7CgkJCQkJZm9yKDthSXRlciAhPSBhVGFiRW5kOysrYUl0ZXIpCgkJCQkJewoJCQkJCQlPUXVlcnlUYWJsZVdpbmRvdyogcFRhYldpbiA9IHN0YXRpY19jYXN0PE9RdWVyeVRhYmxlV2luZG93Kj4oYUl0ZXItPnNlY29uZCk7CgkJCQkJCWlmIChwVGFiV2luLT5FeGlzdHNGaWVsZCggOjpydGw6Ok9VU3RyaW5nOjpjcmVhdGVGcm9tQXNjaWkoIioiKSwgYURyYWdMZWZ0ICkpCgkJCQkJCXsKCQkJCQkJCWFEcmFnTGVmdC0+U2V0QWxpYXMoU3RyaW5nKCkpOwoJCQkJCQkJYURyYWdMZWZ0LT5TZXRUYWJsZShTdHJpbmcoKSk7CgkJCQkJCQlicmVhazsKCQkJCQkJfQoJCQkJCX0KCQkJCX0KCQkJCWVsc2UgaWYoIGVPayAhPSAoIGVFcnJvckNvZGUgPSBGaWxsRHJhZ0luZm8oX3BWaWV3LHBQYXJhbU5vZGUsYURyYWdMZWZ0KSkKCQkJCQkJJiYgU1FMX0lTUlVMRShwUGFyYW1Ob2RlLG51bV92YWx1ZV9leHApICkKCQkJCXsKCQkJCQk6OnJ0bDo6T1VTdHJpbmcgc1BhcmFtZXRlclZhbHVlOwoJCQkJCXBQYXJhbU5vZGUtPnBhcnNlTm9kZVRvU3RyKAlzUGFyYW1ldGVyVmFsdWUsCgkJCQkJCQkJCQkJCXhDb25uZWN0aW9uLAoJCQkJCQkJCQkJCQkmckNvbnRyb2xsZXIuZ2V0UGFyc2VyKCkuZ2V0Q29udGV4dCgpKTsKCQkJCQluRnVuY3Rpb25UeXBlIHw9IEZLVF9OVU1FUklDOwoJCQkJCWFEcmFnTGVmdC0+U2V0RmllbGQoc1BhcmFtZXRlclZhbHVlKTsKCQkJCQllRXJyb3JDb2RlID0gZU9rOwoJCQkJfQoJCQkJYURyYWdMZWZ0LT5TZXRGdW5jdGlvblR5cGUobkZ1bmN0aW9uVHlwZSk7CgkJCQlpZiAoIGJIYXZpbmcgKQoJCQkJCWFEcmFnTGVmdC0+U2V0R3JvdXBCeShzYWxfVHJ1ZSk7CgkJCQlzYWxfSW50MzIgbkluZGV4ID0gMDsKCQkJCWFEcmFnTGVmdC0+U2V0RnVuY3Rpb24oYUNvbHVtbk5hbWUuZ2V0VG9rZW4oMCwnKCcsbkluZGV4KSk7CgkJCX0KCQkJZWxzZQoJCQl7CgkJCQkvLyBiZWkgdW5iZWthbm50ZW4gRnVua3Rpb25lbiB3aXJkIGRlciBnZXNhbXRlIFRleHQgaW4gZGFzIEZpZWxkIGdlY2hyaWViZW4KCQkJCWFEcmFnTGVmdC0+U2V0RmllbGQoYUNvbHVtbk5hbWUpOwoJCQkJaWYoYkhhdmluZykKCQkJCQlhRHJhZ0xlZnQtPlNldEdyb3VwQnkoc2FsX1RydWUpOwoJCQkJYURyYWdMZWZ0LT5TZXRGdW5jdGlvblR5cGUoRktUX09USEVSfEZLVF9OVU1FUklDKTsKCQkJfQoJCQlfcFNlbGVjdGlvbkJydy0+QWRkQ29uZGl0aW9uKGFEcmFnTGVmdCwgYUNvbmRpdGlvbiwgbkxldmVsLGJBZGRPck9uT25lTGluZSk7CgkJfQoKCQlyZXR1cm4gZUVycm9yQ29kZTsKCX0KCS8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCglTcWxQYXJzZUVycm9yIENvbXBhcmlzb25QcmVkaWNhdGUoT1F1ZXJ5RGVzaWduVmlldyogX3BWaWV3LAoJCQkJCQkJT1NlbGVjdGlvbkJyb3dzZUJveCogX3BTZWxlY3Rpb25CcncsCgkJCQkJCQljb25zdCA6OmNvbm5lY3Rpdml0eTo6T1NRTFBhcnNlTm9kZSAqIHBDb25kaXRpb24sCgkJCQkJCQljb25zdCBzYWxfdUludDE2IG5MZXZlbCwKCQkJCQkJCXNhbF9Cb29sIGJIYXZpbmcgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAsYm9vbCBiQWRkT3JPbk9uZUxpbmUpCgl7CgkJU3FsUGFyc2VFcnJvciBlRXJyb3JDb2RlID0gZU9rOwoJCU9RdWVyeUNvbnRyb2xsZXImIHJDb250cm9sbGVyID0gc3RhdGljX2Nhc3Q8T1F1ZXJ5Q29udHJvbGxlciY+KF9wVmlldy0+Z2V0Q29udHJvbGxlcigpKTsKCgkJREJHX0FTU0VSVChTUUxfSVNSVUxFKCBwQ29uZGl0aW9uLCBjb21wYXJpc29uX3ByZWRpY2F0ZSksIkNvbXBhcmlzb25QcmVkaWNhdGU6IHBDb25kaXRpb24gaXN0IGtlaW4gQ29tcGFyaXNvblByZWRpY2F0ZSIpOwoJCWlmICggU1FMX0lTUlVMRShwQ29uZGl0aW9uLT5nZXRDaGlsZCgwKSwgY29sdW1uX3JlZiApCgkJCXx8IFNRTF9JU1JVTEUocENvbmRpdGlvbi0+Z2V0Q2hpbGQocENvbmRpdGlvbi0+Y291bnQoKS0xKSwgY29sdW1uX3JlZikgKQoJCXsKCQkJOjpydGw6Ok9VU3RyaW5nCWFDb25kaXRpb247CgkJCU9UYWJsZUZpZWxkRGVzY1JlZiBhRHJhZ0xlZnQgPSBuZXcgT1RhYmxlRmllbGREZXNjKCk7CgoJCQlpZiAoIFNRTF9JU1JVTEUocENvbmRpdGlvbi0+Z2V0Q2hpbGQoMCksIGNvbHVtbl9yZWYgKSAmJiBTUUxfSVNSVUxFKHBDb25kaXRpb24tPmdldENoaWxkKHBDb25kaXRpb24tPmNvdW50KCktMSksIGNvbHVtbl9yZWYgKSApCgkJCXsKCQkJCU9UYWJsZUZpZWxkRGVzY1JlZiBhRHJhZ1JpZ2h0ID0gbmV3IE9UYWJsZUZpZWxkRGVzYygpOwoJCQkJaWYgKGVPayAhPSAoIGVFcnJvckNvZGUgPSBGaWxsRHJhZ0luZm8oX3BWaWV3LHBDb25kaXRpb24tPmdldENoaWxkKDApLGFEcmFnTGVmdCkpIHx8CgkJCQkJZU9rICE9ICggZUVycm9yQ29kZSA9IEZpbGxEcmFnSW5mbyhfcFZpZXcscENvbmRpdGlvbi0+Z2V0Q2hpbGQoMiksYURyYWdSaWdodCkpKQoJCQkJCXJldHVybiBlRXJyb3JDb2RlOwoKICAgICAgICAgICAgICAgIE9RdWVyeVRhYmxlQ29ubmVjdGlvbiogcENvbm4gPSBzdGF0aWNfY2FzdDxPUXVlcnlUYWJsZUNvbm5lY3Rpb24qPigKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9wVmlldy0+Z2V0VGFibGVWaWV3KCktPkdldFRhYkNvbm4oc3RhdGljX2Nhc3Q8T1F1ZXJ5VGFibGVXaW5kb3cqPihhRHJhZ0xlZnQtPkdldFRhYldpbmRvdygpKSwKCQkJCQkJCQkJCQkJCQkJCQkJCQkJICAgc3RhdGljX2Nhc3Q8T1F1ZXJ5VGFibGVXaW5kb3cqPihhRHJhZ1JpZ2h0LT5HZXRUYWJXaW5kb3coKSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRydWUpKTsKCQkJCWlmICggcENvbm4gKQoJCQkJewoJCQkJCU9Db25uZWN0aW9uTGluZURhdGFWZWMqIHBMaW5lRGF0YUxpc3QgPSBwQ29ubi0+R2V0RGF0YSgpLT5HZXRDb25uTGluZURhdGFMaXN0KCk7CgkJCQkJT0Nvbm5lY3Rpb25MaW5lRGF0YVZlYzo6aXRlcmF0b3IgYUl0ZXIgPSBwTGluZURhdGFMaXN0LT5iZWdpbigpOwogICAgICAgICAgICAgICAgICAgIE9Db25uZWN0aW9uTGluZURhdGFWZWM6Oml0ZXJhdG9yIGFFbmQgPSBwTGluZURhdGFMaXN0LT5lbmQoKTsKCQkJCQlmb3IoO2FJdGVyICE9IGFFbmQ7KythSXRlcikKCQkJCQl7CgkJCQkJCWlmKCgqYUl0ZXIpLT5HZXRTb3VyY2VGaWVsZE5hbWUoKSA9PSBhRHJhZ0xlZnQtPkdldEZpZWxkKCkgfHwKCQkJCQkJICAgKCphSXRlciktPkdldERlc3RGaWVsZE5hbWUoKSA9PSBhRHJhZ0xlZnQtPkdldEZpZWxkKCkgKQoJCQkJCQkJYnJlYWs7CgkJCQkJfQoJCQkJCWlmKGFJdGVyICE9IGFFbmQpCgkJCQkJCXJldHVybiBlT2s7CgkJCQl9CgkJCX0KCgkJCXNhbF91SW50MzIgblBvcyA9IDA7CgkJCWlmKFNRTF9JU1JVTEUocENvbmRpdGlvbi0+Z2V0Q2hpbGQoMCksIGNvbHVtbl9yZWYgKSkKCQkJewoJCQkJblBvcyA9IDA7CgkJCQlzYWxfdUludDMyIGk9MTsKCgkJCQkvLyBkb24ndCBkaXNwbGF5IHRoZSBlcXVhbAoJCQkJaWYgKHBDb25kaXRpb24tPmdldENoaWxkKGkpLT5nZXROb2RlVHlwZSgpID09IFNRTF9OT0RFX0VRVUFMKQoJCQkJCWkrKzsKCgkJCQkvLyBCZWRpbmd1bmcgcGFyc2VuCgkJCQlhQ29uZGl0aW9uID0gUGFyc2VDb25kaXRpb24ockNvbnRyb2xsZXIKCQkJCQkJCQkJCQkscENvbmRpdGlvbgoJCQkJCQkJCQkJCSxfcFZpZXctPmdldERlY2ltYWxTZXBhcmF0b3IoKQoJCQkJCQkJCQkJCSxfcFZpZXctPmdldExvY2FsZSgpCgkJCQkJCQkJCQkJLGkpOwoJCQl9CgkJCWVsc2UgaWYoIFNRTF9JU1JVTEUocENvbmRpdGlvbi0+Z2V0Q2hpbGQocENvbmRpdGlvbi0+Y291bnQoKS0xKSwgY29sdW1uX3JlZiApICkKCQkJewoJCQkJblBvcyA9IHBDb25kaXRpb24tPmNvdW50KCktMTsKCgkJCQlzYWxfSW50MzIgaSA9IHN0YXRpY19jYXN0PHNhbF9JbnQzMj4ocENvbmRpdGlvbi0+Y291bnQoKSAtIDIpOwoJCQkJc3dpdGNoIChwQ29uZGl0aW9uLT5nZXRDaGlsZChpKS0+Z2V0Tm9kZVR5cGUoKSkKCQkJCXsKCQkJCQljYXNlIFNRTF9OT0RFX0VRVUFMOgoJCQkJCQkvLyBkb24ndCBkaXNwbGF5IHRoZSBlcXVhbAoJCQkJCQlpLS07CgkJCQkJCWJyZWFrOwoJCQkJCWNhc2UgU1FMX05PREVfTEVTUzoKCQkJCQkJLy8gdGFrZSB0aGUgb3Bwb3NpdGUgYXMgd2UgY2hhbmdlIHRoZSBvcmRlcgoJCQkJCQlpLS07CgkJCQkJCWFDb25kaXRpb24gPSBhQ29uZGl0aW9uICsgOjpydGw6Ok9VU3RyaW5nOjpjcmVhdGVGcm9tQXNjaWkoIj4iKTsKCQkJCQkJYnJlYWs7CgkJCQkJY2FzZSBTUUxfTk9ERV9MRVNTRVE6CgkJCQkJCS8vIHRha2UgdGhlIG9wcG9zaXRlIGFzIHdlIGNoYW5nZSB0aGUgb3JkZXIKCQkJCQkJaS0tOwoJCQkJCQlhQ29uZGl0aW9uID0gYUNvbmRpdGlvbiArIDo6cnRsOjpPVVN0cmluZzo6Y3JlYXRlRnJvbUFzY2lpKCI+PSIpOwoJCQkJCQlicmVhazsKCQkJCQljYXNlIFNRTF9OT0RFX0dSRUFUOgoJCQkJCQkvLyB0YWtlIHRoZSBvcHBvc2l0ZSBhcyB3ZSBjaGFuZ2UgdGhlIG9yZGVyCgkJCQkJCWktLTsKCQkJCQkJYUNvbmRpdGlvbiA9IGFDb25kaXRpb24gKyA6OnJ0bDo6T1VTdHJpbmc6OmNyZWF0ZUZyb21Bc2NpaSgiPCIpOwoJCQkJCQlicmVhazsKCQkJCQljYXNlIFNRTF9OT0RFX0dSRUFURVE6CgkJCQkJCS8vIHRha2UgdGhlIG9wcG9zaXRlIGFzIHdlIGNoYW5nZSB0aGUgb3JkZXIKCQkJCQkJaS0tOwoJCQkJCQlhQ29uZGl0aW9uID0gYUNvbmRpdGlvbiArIDo6cnRsOjpPVVN0cmluZzo6Y3JlYXRlRnJvbUFzY2lpKCI8PSIpOwoJCQkJCQlicmVhazsKICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKCQkJCX0KCgkJCQkvLyBnbyBiYWNrd2FyZAoJCQkJUmVmZXJlbmNlPCBYQ29ubmVjdGlvbj4geENvbm5lY3Rpb24gPSByQ29udHJvbGxlci5nZXRDb25uZWN0aW9uKCk7CgkJCQlpZih4Q29ubmVjdGlvbi5pcygpKQoJCQkJewoJCQkJCVJlZmVyZW5jZTwgWERhdGFiYXNlTWV0YURhdGEgPiAgeE1ldGFEYXRhID0geENvbm5lY3Rpb24tPmdldE1ldGFEYXRhKCk7CgkJCQkJZm9yICg7IGkgPj0gMDsgaS0tKQoJCQkJCQlwQ29uZGl0aW9uLT5nZXRDaGlsZChpKS0+cGFyc2VOb2RlVG9QcmVkaWNhdGVTdHIoYUNvbmRpdGlvbiwKCQkJCQkJCQkJCQkJeENvbm5lY3Rpb24sCgkJCQkJCQkJCQkJCXJDb250cm9sbGVyLmdldE51bWJlckZvcm1hdHRlcigpLAoJCQkJCQkJCQkJCQlfcFZpZXctPmdldExvY2FsZSgpLAoJCQkJCQkJCQkJCQlzdGF0aWNfY2FzdDxzYWxfQ2hhcj4oX3BWaWV3LT5nZXREZWNpbWFsU2VwYXJhdG9yKCkudG9DaGFyKCkpLAoJCQkJCQkJCQkJCQkmckNvbnRyb2xsZXIuZ2V0UGFyc2VyKCkuZ2V0Q29udGV4dCgpKTsKCQkJCX0KCQkJfQoJCQkvLyBlbHNlID8/PwoKCQkJCgkJCWlmKCBlT2sgPT0gKCBlRXJyb3JDb2RlID0gRmlsbERyYWdJbmZvKF9wVmlldyxwQ29uZGl0aW9uLT5nZXRDaGlsZChuUG9zKSxhRHJhZ0xlZnQpKSkKCQkJewoJCQkJaWYoYkhhdmluZykKCQkJCQlhRHJhZ0xlZnQtPlNldEdyb3VwQnkoc2FsX1RydWUpOwoJCQkJX3BTZWxlY3Rpb25CcnctPkFkZENvbmRpdGlvbihhRHJhZ0xlZnQsIGFDb25kaXRpb24sIG5MZXZlbCxiQWRkT3JPbk9uZUxpbmUpOwoJCQl9CgkJfQoJCWVsc2UgaWYoIFNRTF9JU1JVTEVPUjIocENvbmRpdGlvbi0+Z2V0Q2hpbGQoMCksIHNldF9mY3Rfc3BlYyAsIGdlbmVyYWxfc2V0X2ZjdCApICkKCQl7CgkJCUFkZEZ1bmN0aW9uQ29uZGl0aW9uKAlfcFZpZXcsCgkJCQkJCQkJCV9wU2VsZWN0aW9uQnJ3LAoJCQkJCQkJCQlwQ29uZGl0aW9uLAoJCQkJCQkJCQluTGV2ZWwsCgkJCQkJCQkJCWJIYXZpbmcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJBZGRPck9uT25lTGluZSk7CgkJfQoJCWVsc2UgLy8ga2FubiBzaWNoIG51ciB1bSBlaW5lbiBFeHByLiBBdXNkcnVjayBoYW5kZWxuCgkJewoJCQk6OnJ0bDo6T1VTdHJpbmcgYU5hbWUsYUNvbmRpdGlvbjsKCgkJCTo6Y29ubmVjdGl2aXR5OjpPU1FMUGFyc2VOb2RlICpwTGhzID0gcENvbmRpdGlvbi0+Z2V0Q2hpbGQoMCk7CgkJCTo6Y29ubmVjdGl2aXR5OjpPU1FMUGFyc2VOb2RlICpwUmhzID0gcENvbmRpdGlvbi0+Z2V0Q2hpbGQoMik7CgkJCS8vIEZlbGRuYW1lbgoJCQlSZWZlcmVuY2U8IFhDb25uZWN0aW9uPiB4Q29ubmVjdGlvbiA9IHJDb250cm9sbGVyLmdldENvbm5lY3Rpb24oKTsKCQkJaWYoeENvbm5lY3Rpb24uaXMoKSkKCQkJewoJCQkJcExocy0+cGFyc2VOb2RlVG9TdHIoYU5hbWUsCgkJCQkJCQkJCSB4Q29ubmVjdGlvbiwKCQkJCQkJCQkJICZyQ29udHJvbGxlci5nZXRQYXJzZXIoKS5nZXRDb250ZXh0KCksCgkJCQkJCQkJCSBzYWxfVHJ1ZSk7CgkJCQkvLyBLcml0ZXJpdW0KCQkJCWFDb25kaXRpb24gPSBwQ29uZGl0aW9uLT5nZXRDaGlsZCgxKS0+Z2V0VG9rZW5WYWx1ZSgpOwoJCQkJcFJocy0+cGFyc2VOb2RlVG9QcmVkaWNhdGVTdHIoYUNvbmRpdGlvbiwKCQkJCQkJCQkJCQkJCQkJeENvbm5lY3Rpb24sCgkJCQkJCQkJCQkJCQkJCXJDb250cm9sbGVyLmdldE51bWJlckZvcm1hdHRlcigpLAoJCQkJCQkJCQkJCQkJCQlfcFZpZXctPmdldExvY2FsZSgpLAoJCQkJCQkJCQkJCQkJCQlzdGF0aWNfY2FzdDxzYWxfQ2hhcj4oX3BWaWV3LT5nZXREZWNpbWFsU2VwYXJhdG9yKCkudG9DaGFyKCkpLAoJCQkJCQkJCQkJCQkJCQkmckNvbnRyb2xsZXIuZ2V0UGFyc2VyKCkuZ2V0Q29udGV4dCgpKTsKCQkJfQoKCQkJT1RhYmxlRmllbGREZXNjUmVmIGFEcmFnTGVmdCA9IG5ldyBPVGFibGVGaWVsZERlc2MoKTsKCQkJYURyYWdMZWZ0LT5TZXRGaWVsZChhTmFtZSk7CgkJCWFEcmFnTGVmdC0+U2V0RnVuY3Rpb25UeXBlKEZLVF9PVEhFUnxGS1RfTlVNRVJJQyk7CgkJCS8vIHVuZCBhbmgiYW5nZW4KCQkJX3BTZWxlY3Rpb25CcnctPkFkZENvbmRpdGlvbihhRHJhZ0xlZnQsIGFDb25kaXRpb24sIG5MZXZlbCxiQWRkT3JPbk9uZUxpbmUpOwoJCX0KCQlyZXR1cm4gZUVycm9yQ29kZTsKCX0KCiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgbmFtZXNwYWNlCiAgICB7CiAgICAgICAgT1F1ZXJ5VGFibGVXaW5kb3cqIGxjbF9maW5kQ29sdW1uSW5UYWJsZXMoIGNvbnN0IDo6cnRsOjpPVVN0cmluZyYgX3JDb2x1bU5hbWUsIGNvbnN0IE9Kb2luVGFibGVWaWV3OjpPVGFibGVXaW5kb3dNYXAmIF9yVGFiTGlzdCwgT1RhYmxlRmllbGREZXNjUmVmJiBfckluZm8gKQogICAgICAgIHsKCQkJT0pvaW5UYWJsZVZpZXc6Ok9UYWJsZVdpbmRvd01hcDo6Y29uc3RfaXRlcmF0b3IgYUl0ZXIgPSBfclRhYkxpc3QuYmVnaW4oKTsKICAgICAgICAgICAgT0pvaW5UYWJsZVZpZXc6Ok9UYWJsZVdpbmRvd01hcDo6Y29uc3RfaXRlcmF0b3IgYUVuZCA9IF9yVGFiTGlzdC5lbmQoKTsKCQkJZm9yICggOyBhSXRlciAhPSBhRW5kOyArK2FJdGVyICkKCQkJewoJCQkJT1F1ZXJ5VGFibGVXaW5kb3cqIHBUYWJXaW4gPSBzdGF0aWNfY2FzdDwgT1F1ZXJ5VGFibGVXaW5kb3cqID4oIGFJdGVyLT5zZWNvbmQgKTsKCQkJCWlmICggcFRhYldpbiAmJiBwVGFiV2luLT5FeGlzdHNGaWVsZCggX3JDb2x1bU5hbWUsIF9ySW5mbyApICkKCQkJCQlyZXR1cm4gcFRhYldpbjsKCQkJfQogICAgICAgICAgICByZXR1cm4gTlVMTDsKICAgICAgICB9CiAgICB9CgogICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCXZvaWQgSW5zZXJ0Q29sdW1uUmVmKGNvbnN0IE9RdWVyeURlc2lnblZpZXcqIF9wVmlldywKCQkJCQkJY29uc3QgOjpjb25uZWN0aXZpdHk6Ok9TUUxQYXJzZU5vZGUgKiBwQ29sdW1uUmVmLAoJCQkJCQk6OnJ0bDo6T1VTdHJpbmcmIGFDb2x1bW5OYW1lLAoJCQkJCQljb25zdCA6OnJ0bDo6T1VTdHJpbmcmIGFDb2x1bW5BbGlhcywKCQkJCQkJOjpydGw6Ok9VU3RyaW5nJiBhVGFibGVSYW5nZSwKCQkJCQkJT1RhYmxlRmllbGREZXNjUmVmJiBfcmFJbmZvLAoJCQkJCQlPSm9pblRhYmxlVmlldzo6T1RhYmxlV2luZG93TWFwKiBwVGFiTGlzdCkKCXsKCgkJLy8gVGFiZWxsZW5uYW1lbiB6dXNhbW1lbiBzZXR6ZW4KCQk6OmNvbm5lY3Rpdml0eTo6T1NRTFBhcnNlVHJlZUl0ZXJhdG9yJiByUGFyc2VJdGVyID0gc3RhdGljX2Nhc3Q8T1F1ZXJ5Q29udHJvbGxlciY+KF9wVmlldy0+Z2V0Q29udHJvbGxlcigpKS5nZXRQYXJzZUl0ZXJhdG9yKCk7CgkJclBhcnNlSXRlci5nZXRDb2x1bW5SYW5nZSggcENvbHVtblJlZiwgYUNvbHVtbk5hbWUsIGFUYWJsZVJhbmdlICk7CgoJCXNhbF9Cb29sIGJGb3VuZChzYWxfRmFsc2UpOwoJCURCR19BU1NFUlQoYUNvbHVtbk5hbWUuZ2V0TGVuZ3RoKCksIkNvbHVtbm5hbWUgZGFyZiBuaWNodCBsZWVyIHNlaW4iKTsKCQlpZiAoIWFUYWJsZVJhbmdlLmdldExlbmd0aCgpKQoJCXsKCQkJLy8gU0VMRUNUIGNvbHVtbiwgLi4uCiAgICAgICAgICAgIGJGb3VuZCA9IE5VTEwgIT0gbGNsX2ZpbmRDb2x1bW5JblRhYmxlcyggYUNvbHVtbk5hbWUsICpwVGFiTGlzdCwgX3JhSW5mbyApOwoJCQlpZiAoIGJGb3VuZCAmJiAoIGFDb2x1bW5OYW1lLnRvQ2hhcigpICE9ICcqJyApICkKCQkJCV9yYUluZm8tPlNldEZpZWxkQWxpYXMoYUNvbHVtbkFsaWFzKTsKCQl9CgkJZWxzZQoJCXsKCQkJLy8gU0VMRUNUIHJhbmdlLmNvbHVtbiwgLi4uCgkJCU9RdWVyeVRhYmxlV2luZG93KiBwVGFiV2luID0gc3RhdGljX2Nhc3Q8T1F1ZXJ5VGFibGVWaWV3Kj4oX3BWaWV3LT5nZXRUYWJsZVZpZXcoKSktPkZpbmRUYWJsZShhVGFibGVSYW5nZSk7CgoJCQlpZiAocFRhYldpbiAmJiBwVGFiV2luLT5FeGlzdHNGaWVsZChhQ29sdW1uTmFtZSwgX3JhSW5mbykpCgkJCXsKCQkJCWlmKGFDb2x1bW5OYW1lLnRvQ2hhcigpICE9ICcqJykKCQkJCQlfcmFJbmZvLT5TZXRGaWVsZEFsaWFzKGFDb2x1bW5BbGlhcyk7CgkJCQliRm91bmQgPSBzYWxfVHJ1ZTsKCQkJfQoJCX0KCQlpZiAoIWJGb3VuZCkKCQl7CgkJCV9yYUluZm8tPlNldFRhYmxlKDo6cnRsOjpPVVN0cmluZygpKTsKCQkJX3JhSW5mby0+U2V0QWxpYXMoOjpydGw6Ok9VU3RyaW5nKCkpOwoJCQlfcmFJbmZvLT5TZXRGaWVsZChhQ29sdW1uTmFtZSk7CgkJCV9yYUluZm8tPlNldEZpZWxkQWxpYXMoYUNvbHVtbkFsaWFzKTsJLy8gbnlpIDogaGllciBlaW4gZm9ydGxhdWZlbmRlcyBFeHByXzEsIEV4cHJfMiAuLi4KCQkJX3JhSW5mby0+U2V0RnVuY3Rpb25UeXBlKEZLVF9PVEhFUik7CgkJfQoJfQoJLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoJc2FsX0Jvb2wgY2hlY2tKb2luQ29uZGl0aW9ucygJY29uc3QgT1F1ZXJ5RGVzaWduVmlldyogX3BWaWV3LAoJCQkJCQkJCQljb25zdCA6OmNvbm5lY3Rpdml0eTo6T1NRTFBhcnNlTm9kZSogX3BOb2RlICkKCXsKCQljb25zdCA6OmNvbm5lY3Rpdml0eTo6T1NRTFBhcnNlTm9kZSogcEpvaW5Ob2RlID0gTlVMTDsKCQlzYWxfQm9vbCBiUmV0ID0gc2FsX1RydWU7CgkJaWYgKFNRTF9JU1JVTEUoX3BOb2RlLHF1YWxpZmllZF9qb2luKSkKCQkJcEpvaW5Ob2RlID0gX3BOb2RlOwogICAgICAgIGVsc2UgaWYgKFNRTF9JU1JVTEUoX3BOb2RlLHRhYmxlX3JlZikgCiAgICAgICAgICAgICAgICAmJiAgX3BOb2RlLT5jb3VudCgpID09IDMgCiAgICAgICAgICAgICAgICAmJiAgU1FMX0lTUFVOQ1RVQVRJT04oX3BOb2RlLT5nZXRDaGlsZCgwKSwiKCIpIAogICAgICAgICAgICAgICAgJiYgIFNRTF9JU1BVTkNUVUFUSU9OKF9wTm9kZS0+Z2V0Q2hpbGQoMiksIikiKSApIC8vICcoJyBqb2luZWRfdGFibGUgJyknCgkJCXBKb2luTm9kZSA9IF9wTm9kZS0+Z2V0Q2hpbGQoMSk7CgkJZWxzZSBpZiAoISAoIFNRTF9JU1JVTEUoX3BOb2RlLCB0YWJsZV9yZWYpICYmIF9wTm9kZS0+Y291bnQoKSA9PSAyKSApIC8vIHRhYmxlX25vZGUgdGFibGVfcHJpbWFyeV9hc19yYW5nZV9jb2x1bW4KCQkJYlJldCA9IHNhbF9GYWxzZTsKCgkJaWYgKHBKb2luTm9kZSAmJiAhSW5zZXJ0Sm9pbihfcFZpZXcscEpvaW5Ob2RlKSkKCQkJYlJldCA9IHNhbF9GYWxzZTsKCQlyZXR1cm4gYlJldDsKCX0KCS8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCXNhbF9Cb29sIEluc2VydEpvaW4oY29uc3QgT1F1ZXJ5RGVzaWduVmlldyogX3BWaWV3LAoJCQkJCQljb25zdCA6OmNvbm5lY3Rpdml0eTo6T1NRTFBhcnNlTm9kZSAqcE5vZGUpCgl7CgkJREJHX0FTU0VSVCggU1FMX0lTUlVMRSggcE5vZGUsIHF1YWxpZmllZF9qb2luICkgfHwgU1FMX0lTUlVMRSggcE5vZGUsIGpvaW5lZF90YWJsZSApIHx8IFNRTF9JU1JVTEUoIHBOb2RlLCBjcm9zc191bmlvbiApLAoJCQkiT1F1ZXJ5RGVzaWduVmlldzo6SW5zZXJ0Sm9pbjogRmVobGVyIGltIFBhcnNlIFRyZWUiKTsKCiAgICAgICAgaWYgKFNRTF9JU1JVTEUocE5vZGUsam9pbmVkX3RhYmxlKSkKICAgICAgICAgICAgcmV0dXJuIEluc2VydEpvaW4oX3BWaWV3LHBOb2RlLT5nZXRDaGlsZCgxKSk7CgoJCS8vIGZpcnN0IGNoZWNrIHRoZSBsZWZ0IGFuZCByaWdodCBzaWRlCiAgICAgICAgY29uc3QgOjpjb25uZWN0aXZpdHk6Ok9TUUxQYXJzZU5vZGUqIHBSaWdodFRhYmxlUmVmID0gcE5vZGUtPmdldENoaWxkKDMpOyAvLyB0YWJsZV9yZWYKICAgICAgICBpZiAoIFNRTF9JU1JVTEUocE5vZGUsIHF1YWxpZmllZF9qb2luKSAmJiBTUUxfSVNUT0tFTihwTm9kZS0+Z2V0Q2hpbGQoMSksTkFUVVJBTCkgKQogICAgICAgICAgICBwUmlnaHRUYWJsZVJlZiA9IHBOb2RlLT5nZXRDaGlsZCg0KTsgLy8gdGFibGVfcmVmCgoJCWlmICggIWNoZWNrSm9pbkNvbmRpdGlvbnMoX3BWaWV3LHBOb2RlLT5nZXRDaGlsZCgwKSkgfHwgIWNoZWNrSm9pbkNvbmRpdGlvbnMoX3BWaWV3LHBSaWdodFRhYmxlUmVmKSkKCQkJcmV0dXJuIHNhbF9GYWxzZTsKCgkJLy8gbmFtZWQgY29sdW1uIGpvaW4gd2lyZCBzcOR0ZXIgdmllbGVpY2h0IG5vY2ggaW1wbGVtZW50aWVydAoJCS8vIFNRTF9JU1JVTEUocE5vZGUtPmdldENoaWxkKDQpLG5hbWVkX2NvbHVtbnNfam9pbikKICAgICAgICBFSm9pblR5cGUgZUpvaW5UeXBlID0gSU5ORVJfSk9JTjsKICAgICAgICBib29sIGJOYXR1cmFsID0gZmFsc2U7CgkJaWYgKCBTUUxfSVNSVUxFKHBOb2RlLCBxdWFsaWZpZWRfam9pbikgKQoJCXsKCQkJOjpjb25uZWN0aXZpdHk6Ok9TUUxQYXJzZU5vZGUqIHBKb2luVHlwZSA9IHBOb2RlLT5nZXRDaGlsZCgxKTsgLy8gam9pbl90eXBlCiAgICAgICAgICAgIGlmICggU1FMX0lTVE9LRU4ocEpvaW5UeXBlLE5BVFVSQUwpICkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgYk5hdHVyYWwgPSB0cnVlOwogICAgICAgICAgICAgICAgcEpvaW5UeXBlID0gcE5vZGUtPmdldENoaWxkKDIpOwogICAgICAgICAgICB9CgoJCQlpZiAoU1FMX0lTUlVMRShwSm9pblR5cGUsam9pbl90eXBlKSAmJiAoIXBKb2luVHlwZS0+Y291bnQoKSB8fCBTUUxfSVNUT0tFTihwSm9pblR5cGUtPmdldENoaWxkKDApLElOTkVSKSkpCgkJCXsKCQkJCWVKb2luVHlwZSA9IElOTkVSX0pPSU47CgkJCX0KCQkJZWxzZQoJCQl7CgkJCQlpZiAoU1FMX0lTUlVMRShwSm9pblR5cGUsam9pbl90eXBlKSkJICAgLy8gZWluZSBFYmVuZSB0aWVmZXIKCQkJCQlwSm9pblR5cGUgPSBwSm9pblR5cGUtPmdldENoaWxkKDApOwoKCQkJCWlmIChTUUxfSVNUT0tFTihwSm9pblR5cGUtPmdldENoaWxkKDApLExFRlQpKQoJCQkJCWVKb2luVHlwZSA9IExFRlRfSk9JTjsKCQkJCWVsc2UgaWYoU1FMX0lTVE9LRU4ocEpvaW5UeXBlLT5nZXRDaGlsZCgwKSxSSUdIVCkpCgkJCQkJZUpvaW5UeXBlID0gUklHSFRfSk9JTjsKCQkJCWVsc2UKCQkJCQllSm9pblR5cGUgPSBGVUxMX0pPSU47CgkJCX0KICAgICAgICAgICAgaWYgKCBTUUxfSVNSVUxFKHBOb2RlLT5nZXRDaGlsZCg0KSxqb2luX2NvbmRpdGlvbikgKQogICAgICAgICAgICB7CgkJCSAgICBpZiAoIEluc2VydEpvaW5Db25uZWN0aW9uKF9wVmlldyxwTm9kZS0+Z2V0Q2hpbGQoNCktPmdldENoaWxkKDEpLCBlSm9pblR5cGUscE5vZGUtPmdldENoaWxkKDApLHBSaWdodFRhYmxlUmVmKSAhPSBlT2sgKQoJCQkJICAgIHJldHVybiBzYWxfRmFsc2U7CiAgICAgICAgICAgIH0KCQl9CiAgICAgICAgZWxzZSBpZiAoIFNRTF9JU1JVTEUocE5vZGUsIGNyb3NzX3VuaW9uKSApCiAgICAgICAgewogICAgICAgICAgICBlSm9pblR5cGUgPSBDUk9TU19KT0lOOwogICAgICAgICAgICBwUmlnaHRUYWJsZVJlZiA9IHBOb2RlLT5nZXRDaGlsZChwTm9kZS0+Y291bnQoKSAtIDEpOwogICAgICAgIH0KICAgICAgICBlbHNlCgkJCXJldHVybiBzYWxfRmFsc2U7CgogICAgICAgIGlmICggZUpvaW5UeXBlID09IENST1NTX0pPSU4gfHwgYk5hdHVyYWwgKQogICAgICAgIHsKCiAgICAgICAgICAgIE9RdWVyeVRhYmxlV2luZG93KglwTGVmdFdpbmRvdyA9IHN0YXRpY19jYXN0PE9RdWVyeVRhYmxlVmlldyo+KF9wVmlldy0+Z2V0VGFibGVWaWV3KCkpLT5GaW5kVGFibGUoIGdldFRhYmxlUmFuZ2UoX3BWaWV3LHBOb2RlLT5nZXRDaGlsZCgwKSkgKTsKICAgICAgICAgICAgT1F1ZXJ5VGFibGVXaW5kb3cqCXBSaWdodFdpbmRvdyA9IHN0YXRpY19jYXN0PE9RdWVyeVRhYmxlVmlldyo+KF9wVmlldy0+Z2V0VGFibGVWaWV3KCkpLT5GaW5kVGFibGUoIGdldFRhYmxlUmFuZ2UoX3BWaWV3LHBSaWdodFRhYmxlUmVmKSApOwogICAgICAgICAgICBPU0xfRU5TVVJFKHBMZWZ0V2luZG93ICYmIHBSaWdodFdpbmRvdywiVGFibGUgV2luZG93cyBjb3VsZCBub3QgYmUgZm91bmQhIik7CiAgICAgICAgICAgIGlmICggIXBMZWZ0V2luZG93IHx8ICFwUmlnaHRXaW5kb3cgKQogICAgICAgICAgICAgICAgcmV0dXJuIHNhbF9GYWxzZTsKCiAgICAgICAgICAgIE9UYWJsZUZpZWxkRGVzY1JlZiBhRHJhZ0xlZnQgID0gbmV3IE9UYWJsZUZpZWxkRGVzYygpOwogICAgICAgICAgICBhRHJhZ0xlZnQtPlNldFRhYldpbmRvdyhwTGVmdFdpbmRvdyk7CiAgICAgICAgICAgIGFEcmFnTGVmdC0+U2V0VGFibGUocExlZnRXaW5kb3ctPkdldFRhYmxlTmFtZSgpKTsKICAgICAgICAgICAgYURyYWdMZWZ0LT5TZXRBbGlhcyhwTGVmdFdpbmRvdy0+R2V0QWxpYXNOYW1lKCkpOwoKCQkJT1RhYmxlRmllbGREZXNjUmVmIGFEcmFnUmlnaHQgPSBuZXcgT1RhYmxlRmllbGREZXNjKCk7CiAgICAgICAgICAgIGFEcmFnUmlnaHQtPlNldFRhYldpbmRvdyhwUmlnaHRXaW5kb3cpOwogICAgICAgICAgICBhRHJhZ1JpZ2h0LT5TZXRUYWJsZShwUmlnaHRXaW5kb3ctPkdldFRhYmxlTmFtZSgpKTsKICAgICAgICAgICAgYURyYWdSaWdodC0+U2V0QWxpYXMocFJpZ2h0V2luZG93LT5HZXRBbGlhc05hbWUoKSk7CgogICAgICAgICAgICBpbnNlcnRDb25uZWN0aW9uKF9wVmlldyxlSm9pblR5cGUsYURyYWdMZWZ0LGFEcmFnUmlnaHQsYk5hdHVyYWwpOwogICAgICAgIH0KCQkKCgkJcmV0dXJuIHNhbF9UcnVlOwoJfQoJLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCXZvaWQgaW5zZXJ0VW5Vc2VkRmllbGRzKE9RdWVyeURlc2lnblZpZXcqIF9wVmlldyxPU2VsZWN0aW9uQnJvd3NlQm94KiBfcFNlbGVjdGlvbkJydykKCXsKCQkvLyBub3cgd2UgaGF2ZSB0byBpbnNlcnQgdGhlIGZpZWxkcyB3aGljaCBhcmVuJ3QgaW4gdGhlIHN0YXRlbWVudAoJCU9RdWVyeUNvbnRyb2xsZXImIHJDb250cm9sbGVyID0gc3RhdGljX2Nhc3Q8T1F1ZXJ5Q29udHJvbGxlciY+KF9wVmlldy0+Z2V0Q29udHJvbGxlcigpKTsKCQlPVGFibGVGaWVsZHMmIHJVblVzZWRGaWVsZHMgPSByQ29udHJvbGxlci5nZXRVblVzZWRGaWVsZHMoKTsKICAgICAgICBPVGFibGVGaWVsZHM6Oml0ZXJhdG9yIGFFbmQgPSByVW5Vc2VkRmllbGRzLmVuZCgpOwoJCWZvcihPVGFibGVGaWVsZHM6Oml0ZXJhdG9yIGFJdGVyID0gclVuVXNlZEZpZWxkcy5iZWdpbigpO2FJdGVyICE9IGFFbmQ7KythSXRlcikKCQkJaWYoX3BTZWxlY3Rpb25CcnctPkluc2VydEZpZWxkKCphSXRlcixCUk9XU0VSX0lOVkFMSURJRCxzYWxfRmFsc2Usc2FsX0ZhbHNlKS5pc1ZhbGlkKCkpCgkJCQkoKmFJdGVyKSA9IE5VTEw7CgkJT1RhYmxlRmllbGRzKCkuc3dhcCggclVuVXNlZEZpZWxkcyApOwoJfQoKCS8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCglTcWxQYXJzZUVycm9yIEluaXRGcm9tUGFyc2VOb2RlSW1wbChPUXVlcnlEZXNpZ25WaWV3KiBfcFZpZXcsT1NlbGVjdGlvbkJyb3dzZUJveCogX3BTZWxlY3Rpb25CcncpCgl7CgkJU3FsUGFyc2VFcnJvciBlRXJyb3JDb2RlID0gZU9rOwoKCQlPUXVlcnlDb250cm9sbGVyJiByQ29udHJvbGxlciA9IHN0YXRpY19jYXN0PE9RdWVyeUNvbnRyb2xsZXImPihfcFZpZXctPmdldENvbnRyb2xsZXIoKSk7CgoJCV9wU2VsZWN0aW9uQnJ3LT5QcmVGaWxsKCk7CgkJX3BTZWxlY3Rpb25CcnctPlNldFJlYWRPbmx5KHJDb250cm9sbGVyLmlzUmVhZE9ubHkoKSk7CgkJX3BTZWxlY3Rpb25CcnctPkZpbGwoKTsKCgoJCTo6Y29ubmVjdGl2aXR5OjpPU1FMUGFyc2VUcmVlSXRlcmF0b3ImIGFJdGVyYXRvciA9IHJDb250cm9sbGVyLmdldFBhcnNlSXRlcmF0b3IoKTsKCQljb25zdCA6OmNvbm5lY3Rpdml0eTo6T1NRTFBhcnNlTm9kZSogcFBhcnNlVHJlZSA9IGFJdGVyYXRvci5nZXRQYXJzZVRyZWUoKTsKCiAgICAgICAgZG8KICAgICAgICB7CiAgICAgICAgICAgIGlmICggIXBQYXJzZVRyZWUgKQogICAgICAgICAgICB7CgkJCSAgICAvLyBub3cgd2UgaGF2ZSB0byBpbnNlcnQgdGhlIGZpZWxkcyB3aGljaCBhcmVuJ3QgaW4gdGhlIHN0YXRlbWVudAoJCQkgICAgaW5zZXJ0VW5Vc2VkRmllbGRzKF9wVmlldyxfcFNlbGVjdGlvbkJydyk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCAhckNvbnRyb2xsZXIuaXNFc2FjcGVQcm9jZXNzaW5nKCkgKSAvLyBub3QgYWxsb3dlZCBpbiB0aGlzIG1vZGUKICAgICAgICAgICAgewoJCQkgICAgZUVycm9yQ29kZSA9IGVOYXRpdmVNb2RlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KCgkJCWlmICggISggU1FMX0lTUlVMRSggcFBhcnNlVHJlZSwgc2VsZWN0X3N0YXRlbWVudCApICkgKQogICAgICAgICAgICB7CgkJCQllRXJyb3JDb2RlID0gZU5vU2VsZWN0U3RhdGVtZW50OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGNvbnN0IE9TUUxQYXJzZU5vZGUqIHBUYWJsZUV4cCA9IHBQYXJzZVRyZWUtPmdldENoaWxkKDMpOwogICAgICAgICAgICBpZiAoIHBUYWJsZUV4cC0+Z2V0Q2hpbGQoNiktPmNvdW50KCkgPiAwIHx8IHBUYWJsZUV4cC0+Z2V0Q2hpbGQoNyktPmNvdW50KCkgPiAwIHx8IHBUYWJsZUV4cC0+Z2V0Q2hpbGQoOCktPmNvdW50KCkgPiAwKQogICAgICAgICAgICB7CgkJCQllRXJyb3JDb2RlID0gZVN0YXRlbWVudFRvb0NvbXBsZXg7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQoKCQkJUmVmZXJlbmNlPCBYQ29ubmVjdGlvbj4geENvbm5lY3Rpb24gPSByQ29udHJvbGxlci5nZXRDb25uZWN0aW9uKCk7CgkJCWlmICggIXhDb25uZWN0aW9uLmlzKCkgKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBEQkdfRVJST1IoICJJbml0RnJvbVBhcnNlTm9kZUltcGw6IG5vIGNvbm5lY3Rpb24/IG5vIGNvbm5lY3Rpb24hIiApOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KCgkJCWNvbnN0IE9TUUxUYWJsZXMmIGFNYXAgPSBhSXRlcmF0b3IuZ2V0VGFibGVzKCk7CgkJCTo6Y29tcGhlbHBlcjo6VVN0cmluZ01peExlc3MgYVRtcChhTWFwLmtleV9jb21wKCkpOwoJCQk6OmNvbXBoZWxwZXI6OlVTdHJpbmdNaXhFcXVhbCBhS2V5Q29tcCggYVRtcC5pc0Nhc2VTZW5zaXRpdmUoKSApOwoKCQkJUmVmZXJlbmNlPCBYRGF0YWJhc2VNZXRhRGF0YSA+ICB4TWV0YURhdGEgPSB4Q29ubmVjdGlvbi0+Z2V0TWV0YURhdGEoKTsKCQkJdHJ5CgkJCXsKCQkJICAgIHNhbF9JbnQzMiBuTWF4ID0geE1ldGFEYXRhLT5nZXRNYXhUYWJsZXNJblNlbGVjdCgpOwogICAgICAgICAgICAgICAgaWYgKCBuTWF4ICYmIG5NYXggPCAoc2FsX0ludDMyKWFNYXAuc2l6ZSgpICkKICAgICAgICAgICAgICAgIHsKCQkJCQllRXJyb3JDb2RlID0gZVRvb01hbnlUYWJsZXM7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CgoJCQkJOjpydGw6Ok9VU3RyaW5nIHNDb21wb3NlZE5hbWU7CgkJCQk6OnJ0bDo6T1VTdHJpbmcgYVF1YWxpZmllck5hbWU7CgkJCQk6OnJ0bDo6T1VTdHJpbmcgc0FsaWFzOwoKCQkJCU9RdWVyeVRhYmxlVmlldyogcFRhYmxlVmlldyA9IHN0YXRpY19jYXN0PE9RdWVyeVRhYmxlVmlldyo+KF9wVmlldy0+Z2V0VGFibGVWaWV3KCkpOwogICAgICAgICAgICAgICAgcFRhYmxlVmlldy0+Y2xlYXJMYXlvdXRJbmZvcm1hdGlvbigpOwoJCQkJT1NRTFRhYmxlczo6Y29uc3RfaXRlcmF0b3IgYUl0ZXIgPSBhTWFwLmJlZ2luKCk7CiAgICAgICAgICAgICAgICBPU1FMVGFibGVzOjpjb25zdF9pdGVyYXRvciBhRW5kID0gYU1hcC5lbmQoKTsKCQkJCWZvcig7YUl0ZXIgIT0gYUVuZDsrK2FJdGVyKQoJCQkJewoJCQkJCU9TUUxUYWJsZSB4VGFibGUgPSBhSXRlci0+c2Vjb25kOwogICAgICAgICAgICAgICAgICAgIFJlZmVyZW5jZTwgWFByb3BlcnR5U2V0ID4geFRhYmxlUHJvcHMoIHhUYWJsZSwgVU5PX1FVRVJZX1RIUk9XICk7CgoJCQkJCXNBbGlhcyA9IGFJdGVyLT5maXJzdDsKCiAgICAgICAgICAgICAgICAgICAgLy8gY2hlY2sgd2hldGhlciB0aGlzIGlzIGEgcXVlcnkKICAgICAgICAgICAgICAgICAgICBSZWZlcmVuY2U8IFhQcm9wZXJ0eVNldEluZm8gPiB4UFNJID0geFRhYmxlUHJvcHMtPmdldFByb3BlcnR5U2V0SW5mbygpOwogICAgICAgICAgICAgICAgICAgIGJvb2wgYklzUXVlcnkgPSB4UFNJLmlzKCkgJiYgeFBTSS0+aGFzUHJvcGVydHlCeU5hbWUoIFBST1BFUlRZX0NPTU1BTkQgKTsKCiAgICAgICAgICAgICAgICAgICAgaWYgKCBiSXNRdWVyeSApCiAgICAgICAgICAgICAgICAgICAgICAgIE9TTF9WRVJJRlkoIHhUYWJsZVByb3BzLT5nZXRQcm9wZXJ0eVZhbHVlKCBQUk9QRVJUWV9OQU1FICkgPj49IHNDb21wb3NlZE5hbWUgKTsKICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBzQ29tcG9zZWROYW1lID0gOjpkYnRvb2xzOjpjb21wb3NlVGFibGVOYW1lKCB4TWV0YURhdGEsIHhUYWJsZVByb3BzLCA6OmRidG9vbHM6OmVJbkRhdGFNYW5pcHVsYXRpb24sIGZhbHNlLCBmYWxzZSwgZmFsc2UgKTsKCiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGlmIHRoZSBhbGlhcyBpcyB0aGUgY29tcGxldGUgKGNvbXBvc2VkKSB0YWJsZSwgdGhlbiBzaG9ydGVuIGl0CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICggYUtleUNvbXAoIHNDb21wb3NlZE5hbWUsIGFJdGVyLT5maXJzdCApICkKCQkJCQkgICAgewoJCQkJCQkgICAgOjpydGw6Ok9VU3RyaW5nIHNDYXRhbG9nLCBzU2NoZW1hLCBzVGFibGU7CgkJCQkJCSAgICA6OmRidG9vbHM6OnF1YWxpZmllZE5hbWVDb21wb25lbnRzKCB4TWV0YURhdGEsIHNDb21wb3NlZE5hbWUsIHNDYXRhbG9nLCBzU2NoZW1hLCBzVGFibGUsIDo6ZGJ0b29sczo6ZUluRGF0YU1hbmlwdWxhdGlvbiApOwoJCQkJCQkgICAgc0FsaWFzID0gc1RhYmxlOwoJCQkJCSAgICB9CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAvLyBmaW5kIHRoZSBleGlzdGVudCB3aW5kb3cgZm9yIHRoaXMgYWxpYXMKCQkJCQlPUXVlcnlUYWJsZVdpbmRvdyogcEV4aXN0ZW50V2luCT0gcFRhYmxlVmlldy0+RmluZFRhYmxlKCBzQWxpYXMgKTsKCQkJCQlpZiAoICFwRXhpc3RlbnRXaW4gKQoJCQkJCXsKCQkJCQkJcFRhYmxlVmlldy0+QWRkVGFiV2luKCBzQ29tcG9zZWROYW1lLCBzQWxpYXMsIHNhbF9GYWxzZSApOyAgLy8gZG9uJ3QgY3JlYXRlIGRhdGEgaGVyZQoJCQkJCX0KCQkJCQllbHNlCgkJCQkJewoJCQkJCQkvLyB0aGVyZSBhbHJlYWR5IGV4aXN0cyBhIHdpbmRvdyBmb3IgdGhpcyBhbGlhcyAuLi4uCgkJCQkJCWlmICggIWFLZXlDb21wKCBwRXhpc3RlbnRXaW4tPkdldERhdGEoKS0+R2V0Q29tcG9zZWROYW1lKCksIHNDb21wb3NlZE5hbWUgKSApCgkJCQkJCQkvLyAuLi4gYnV0IGZvciBhbm90aGVyIGNvbXBsZXRlIHRhYmxlIG5hbWUgLT4gbmV3IHdpbmRvdwoJCQkJCQkJcFRhYmxlVmlldy0+QWRkVGFiV2luKHNDb21wb3NlZE5hbWUsIHNBbGlhcyk7CgkJCQkJfQoJCQkJfQoKCQkJCS8vIG5vdyBkZWxldGUgdGhlIGRhdGEgZm9yIHdoaWNoIHdlIGhhdmVuJ3QgYW55IHRhYmxld2luZG93CgkJCQlPSm9pblRhYmxlVmlldzo6T1RhYmxlV2luZG93TWFwIGFUYWJsZU1hcCgqcFRhYmxlVmlldy0+R2V0VGFiV2luTWFwKCkpOwoJCQkJT0pvaW5UYWJsZVZpZXc6Ok9UYWJsZVdpbmRvd01hcDo6aXRlcmF0b3IgYUl0ZXJUYWJsZU1hcCA9IGFUYWJsZU1hcC5iZWdpbigpOwogICAgICAgICAgICAgICAgT0pvaW5UYWJsZVZpZXc6Ok9UYWJsZVdpbmRvd01hcDo6aXRlcmF0b3IgYUl0ZXJUYWJsZUVuZCA9IGFUYWJsZU1hcC5lbmQoKTsKCQkJCWZvcig7YUl0ZXJUYWJsZU1hcCAhPSBhSXRlclRhYmxlRW5kOysrYUl0ZXJUYWJsZU1hcCkKCQkJCXsKCQkJCQlpZihhTWFwLmZpbmQoYUl0ZXJUYWJsZU1hcC0+c2Vjb25kLT5HZXRDb21wb3NlZE5hbWUoKSkJPT0gYU1hcC5lbmQoKSAmJgoJCQkJCQlhTWFwLmZpbmQoYUl0ZXJUYWJsZU1hcC0+Zmlyc3QpCQkJCQkJPT0gYU1hcC5lbmQoKSkKCQkJCQkJcFRhYmxlVmlldy0+UmVtb3ZlVGFiV2luKGFJdGVyVGFibGVNYXAtPnNlY29uZCk7CgkJCQl9CgoJCQkJaWYgKCBlT2sgPT0gKGVFcnJvckNvZGUgPSBGaWxsT3V0ZXJKb2lucyhfcFZpZXcscFRhYmxlRXhwLT5nZXRDaGlsZCgwKS0+Z2V0Q2hpbGQoMSkpKSApCgkJCQl7CgkJCQkJLy8gY2hlY2sgaWYgd2UgaGF2ZSBhIGRpc3RpbmN0IHN0YXRlbWVudAoJCQkJCWlmKFNRTF9JU1RPS0VOKHBQYXJzZVRyZWUtPmdldENoaWxkKDEpLERJU1RJTkNUKSkKCQkJCQl7CgkJCQkJCXJDb250cm9sbGVyLnNldERpc3RpbmN0KHNhbF9UcnVlKTsKCQkJCQkJckNvbnRyb2xsZXIuSW52YWxpZGF0ZUZlYXR1cmUoU0lEX1FVRVJZX0RJU1RJTkNUX1ZBTFVFUyk7CgkJCQkJfQoJCQkJCWlmICggKGVFcnJvckNvZGUgPSBJbnN0YWxsRmllbGRzKF9wVmlldyxwUGFyc2VUcmVlLCBwVGFibGVWaWV3LT5HZXRUYWJXaW5NYXAoKSkpID09IGVPayApCgkJCQkJewoJCQkJCQkvLyBHZXRTZWxlY3Rpb25Dcml0ZXJpYSBtdXN0IGJlIGNhbGxlZCBiZWZvcmUgR2V0SGF2aW5nQ3JpdGVyaWEKCQkJCQkJc2FsX3VJbnQxNiBuTGV2ZWw9MDsKCgkJCQkJCWlmICggZU9rID09IChlRXJyb3JDb2RlID0gR2V0U2VsZWN0aW9uQ3JpdGVyaWEoX3BWaWV3LF9wU2VsZWN0aW9uQnJ3LHBQYXJzZVRyZWUsbkxldmVsKSkgKQoJCQkJCQl7CgkJCQkJCQlpZiAoIGVPayA9PSAoZUVycm9yQ29kZSA9IEdldEdyb3VwQ3JpdGVyaWEoX3BWaWV3LF9wU2VsZWN0aW9uQnJ3LHBQYXJzZVRyZWUpKSApCgkJCQkJCQl7CgkJCQkJCQkJaWYgKCBlT2sgPT0gKGVFcnJvckNvZGUgPSBHZXRIYXZpbmdDcml0ZXJpYShfcFZpZXcsX3BTZWxlY3Rpb25CcncscFBhcnNlVHJlZSxuTGV2ZWwpKSApCgkJCQkJCQkJewoJCQkJCQkJCQlpZiAoIGVPayA9PSAoZUVycm9yQ29kZSA9IEdldE9yZGVyQ3JpdGVyaWEoX3BWaWV3LF9wU2VsZWN0aW9uQnJ3LHBQYXJzZVRyZWUpKSApCgkJCQkJCQkJCQlpbnNlcnRVblVzZWRGaWVsZHMoX3BWaWV3LF9wU2VsZWN0aW9uQnJ3KTsKCQkJCQkJCQl9CgkJCQkJCQl9CgkJCQkJCX0KCQkJCQl9CgkJCQl9CgkJCX0KCQkJY2F0Y2goU1FMRXhjZXB0aW9uJikKCQkJewoJCQkJT1NMX0FTU0VSVCghImdldE1heFRhYmxlc0luU2VsZWN0ISIpOwoJCQl9CgkJfQogICAgICAgIHdoaWxlICggZmFsc2UgKTsKCgkJLy8gRHVyY2ggZGFzIE5ldWVyemV1Z2VuIHd1cmRlbiB3aWVkZXIgVW5kby1BY3Rpb25zIGluIGRlbiBNYW5hZ2VyIGdlc3RlbGx0CgkJckNvbnRyb2xsZXIuQ2xlYXJVbmRvTWFuYWdlcigpOwoJCV9wU2VsZWN0aW9uQnJ3LT5JbnZhbGlkYXRlKCk7CgkJcmV0dXJuIGVFcnJvckNvZGU7Cgl9CgkvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoJLyoqIGZpbGxTZWxlY3RTdWJMaXN0CgkJQHJldHVybgoJCQk8VFJVRS8+IHdoZW4gY29sdW1ucyBjb3VsZCBiZSBpbnNlcnRlZCBvdGhlcndpc2UgPEZBTFNFLz4KCSovCgkvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoJU3FsUGFyc2VFcnJvciBmaWxsU2VsZWN0U3ViTGlzdCgJT1F1ZXJ5RGVzaWduVmlldyogX3BWaWV3LAoJCQkJCQkJCU9Kb2luVGFibGVWaWV3OjpPVGFibGVXaW5kb3dNYXAqIF9wVGFiTGlzdCkKCXsKCQlTcWxQYXJzZUVycm9yIGVFcnJvckNvZGUgPSBlT2s7CgkJc2FsX0Jvb2wgYkZpcnN0RmllbGQgPSBzYWxfVHJ1ZTsKCQk6OnJ0bDo6T1VTdHJpbmcgc0FzdGVyaXgoUlRMX0NPTlNUQVNDSUlfVVNUUklOR1BBUkFNKCIqIikpOwoJCU9Kb2luVGFibGVWaWV3OjpPVGFibGVXaW5kb3dNYXA6Oml0ZXJhdG9yIGFJdGVyID0gX3BUYWJMaXN0LT5iZWdpbigpOwogICAgICAgIE9Kb2luVGFibGVWaWV3OjpPVGFibGVXaW5kb3dNYXA6Oml0ZXJhdG9yIGFFbmQgPSBfcFRhYkxpc3QtPmVuZCgpOwoJCWZvcig7YUl0ZXIgIT0gYUVuZCAmJiBlT2sgPT0gZUVycm9yQ29kZSA7KythSXRlcikKCQl7CgkJCU9RdWVyeVRhYmxlV2luZG93KiBwVGFiV2luID0gc3RhdGljX2Nhc3Q8T1F1ZXJ5VGFibGVXaW5kb3cqPihhSXRlci0+c2Vjb25kKTsKICAgICAgICAgICAgT1RhYmxlRmllbGREZXNjUmVmCWFJbmZvID0gbmV3IE9UYWJsZUZpZWxkRGVzYygpOwoJCQlpZiAocFRhYldpbi0+RXhpc3RzRmllbGQoIHNBc3Rlcml4LCBhSW5mbyApKQoJCQl7CgkJCQllRXJyb3JDb2RlID0gX3BWaWV3LT5JbnNlcnRGaWVsZChhSW5mbywgc2FsX1RydWUsIGJGaXJzdEZpZWxkKTsKCQkJCWJGaXJzdEZpZWxkID0gc2FsX0ZhbHNlOwoJCQl9CgkJfQoJCXJldHVybiBlRXJyb3JDb2RlOwoJfQoJLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCVNxbFBhcnNlRXJyb3IgSW5zdGFsbEZpZWxkcyhPUXVlcnlEZXNpZ25WaWV3KiBfcFZpZXcsCgkJCQkJCQkJY29uc3QgOjpjb25uZWN0aXZpdHk6Ok9TUUxQYXJzZU5vZGUqIHBOb2RlLAoJCQkJCQkJCU9Kb2luVGFibGVWaWV3OjpPVGFibGVXaW5kb3dNYXAqIHBUYWJMaXN0ICkKCXsKCQlpZiggcE5vZGU9PTAgfHwgIVNRTF9JU1JVTEUocE5vZGUsc2VsZWN0X3N0YXRlbWVudCkpCgkJCXJldHVybiBlTm9TZWxlY3RTdGF0ZW1lbnQ7CgoJCTo6Y29ubmVjdGl2aXR5OjpPU1FMUGFyc2VOb2RlKiBwUGFyc2VUcmVlID0gcE5vZGUtPmdldENoaWxkKDIpOyAvLyBzZWxlY3Rpb24KCQlzYWxfQm9vbCBiRmlyc3RGaWVsZCA9IHNhbF9UcnVlOwkvLyBiZWkgZGVyIEluaXRpYWxpc2llcnVuZyBtdd8gYXVmIGFsbGUgRmFlbGxlIGRhcyBlcnN0ZSBGZWxkIG5ldSBha3RpdmllcnQgd2VyZGVuCgoJCVNxbFBhcnNlRXJyb3IgZUVycm9yQ29kZSA9IGVPazsKCgkJaWYgKCBwUGFyc2VUcmVlLT5pc1J1bGUoKSAmJiBTUUxfSVNQVU5DVFVBVElPTihwUGFyc2VUcmVlLT5nZXRDaGlsZCgwKSwiKiIpICkKCQl7CgkJCS8vIFNFTEVDVCAqIC4uLgoJCQllRXJyb3JDb2RlID0gZmlsbFNlbGVjdFN1Ykxpc3QoX3BWaWV3LHBUYWJMaXN0KTsKCQl9CgkJZWxzZSBpZiAoU1FMX0lTUlVMRShwUGFyc2VUcmVlLHNjYWxhcl9leHBfY29tbWFsaXN0KSApCgkJewoJCQkvLyBTRUxFQ1QgY29sdW1uLCAuLi4KCQkJT1F1ZXJ5Q29udHJvbGxlciYgckNvbnRyb2xsZXIgPSBzdGF0aWNfY2FzdDxPUXVlcnlDb250cm9sbGVyJj4oX3BWaWV3LT5nZXRDb250cm9sbGVyKCkpOwoJCQlSZWZlcmVuY2U8IFhDb25uZWN0aW9uPiB4Q29ubmVjdGlvbiA9IHJDb250cm9sbGVyLmdldENvbm5lY3Rpb24oKTsKCgkJCTo6cnRsOjpPVVN0cmluZyBhQ29sdW1uTmFtZSxhVGFibGVSYW5nZTsKCQkJZm9yIChzYWxfdUludDMyIGkgPSAwOyBpIDwgcFBhcnNlVHJlZS0+Y291bnQoKSAmJiBlT2sgPT0gZUVycm9yQ29kZSA7ICsraSkKCQkJewoJCQkJOjpjb25uZWN0aXZpdHk6Ok9TUUxQYXJzZU5vZGUgKiBwQ29sdW1uUmVmID0gcFBhcnNlVHJlZS0+Z2V0Q2hpbGQoaSk7CgogICAgICAgICAgICAgICAgZG8gewoKICAgICAgICAgICAgICAgIGlmICggU1FMX0lTUlVMRShwQ29sdW1uUmVmLHNlbGVjdF9zdWJsaXN0KSApCgkJCQl7CgkJCQkJIGVFcnJvckNvZGUgPSBmaWxsU2VsZWN0U3ViTGlzdChfcFZpZXcscFRhYkxpc3QpOwogICAgICAgICAgICAgICAgICAgICBicmVhazsKCQkJCX0KCiAgICAgICAgICAgICAgICBpZiAoIFNRTF9JU1JVTEUocENvbHVtblJlZixkZXJpdmVkX2NvbHVtbikgKQoJCQkJewoJCQkJCTo6cnRsOjpPVVN0cmluZyBhQ29sdW1uQWxpYXMockNvbnRyb2xsZXIuZ2V0UGFyc2VJdGVyYXRvcigpLmdldENvbHVtbkFsaWFzKHBDb2x1bW5SZWYpKTsgLy8ga2FubiBsZWVyIHNlaW4KCQkJCQlwQ29sdW1uUmVmID0gcENvbHVtblJlZi0+Z2V0Q2hpbGQoMCk7CgkJCQkJT1RhYmxlRmllbGREZXNjUmVmIGFJbmZvID0gbmV3IE9UYWJsZUZpZWxkRGVzYygpOwoKCQkJCQlpZiAoCXBDb2x1bW5SZWYtPmNvdW50KCkgPT0gMyAmJgoJCQkJCQkJU1FMX0lTUFVOQ1RVQVRJT04ocENvbHVtblJlZi0+Z2V0Q2hpbGQoMCksIigiKSAmJgoJCQkJCQkJU1FMX0lTUFVOQ1RVQVRJT04ocENvbHVtblJlZi0+Z2V0Q2hpbGQoMiksIikiKQoJCQkJCQkpCgkJCQkJCXBDb2x1bW5SZWYgPSBwQ29sdW1uUmVmLT5nZXRDaGlsZCgxKTsKCgkJCQkJaWYgKFNRTF9JU1JVTEUocENvbHVtblJlZixjb2x1bW5fcmVmKSkKCQkJCQl7CgkJCQkJCUluc2VydENvbHVtblJlZihfcFZpZXcscENvbHVtblJlZixhQ29sdW1uTmFtZSxhQ29sdW1uQWxpYXMsYVRhYmxlUmFuZ2UsYUluZm8scFRhYkxpc3QpOwoJCQkJCQllRXJyb3JDb2RlID0gX3BWaWV3LT5JbnNlcnRGaWVsZChhSW5mbywgc2FsX1RydWUsIGJGaXJzdEZpZWxkKTsKCQkJCQkJYkZpcnN0RmllbGQgPSBzYWxfRmFsc2U7CgkJCQkJfQoJCQkJCWVsc2UgaWYoU1FMX0lTUlVMRU9SMihwQ29sdW1uUmVmLGdlbmVyYWxfc2V0X2ZjdCAsc2V0X2ZjdF9zcGVjKQl8fAoJCQkJCQkJU1FMX0lTUlVMRU9SMihwQ29sdW1uUmVmLHBvc2l0aW9uX2V4cCxleHRyYWN0X2V4cCkJCXx8CgkJCQkJCQlTUUxfSVNSVUxFT1IyKHBDb2x1bW5SZWYsZm9sZCxjaGFyX3N1YnN0cmluZ19mY3QpCQl8fAoJCQkJCQkJU1FMX0lTUlVMRU9SMihwQ29sdW1uUmVmLGxlbmd0aF9leHAsY2hhcl92YWx1ZV9mY3QpKQoJCQkJCXsKCQkJCQkJOjpydGw6Ok9VU3RyaW5nIGFDb2x1bW5zOwogICAgICAgICAgICAgICAgICAgICAgICBwQ29sdW1uUmVmLT5wYXJzZU5vZGVUb1ByZWRpY2F0ZVN0cihhQ29sdW1ucywKCQkJCQkJCQkJCQkJICAgICAgICAgICAgeENvbm5lY3Rpb24sCgkJCQkJCQkJCQkJCSAgICAgICAgICAgIHJDb250cm9sbGVyLmdldE51bWJlckZvcm1hdHRlcigpLAoJCQkJCQkJCQkJCQkgICAgICAgICAgICBfcFZpZXctPmdldExvY2FsZSgpLAoJCQkJCQkJCQkJCQkgICAgICAgICAgICBzdGF0aWNfY2FzdDxzYWxfQ2hhcj4oX3BWaWV3LT5nZXREZWNpbWFsU2VwYXJhdG9yKCkudG9DaGFyKCkpLAoJCQkJCQkJCQkJCQkgICAgICAgICAgICAmckNvbnRyb2xsZXIuZ2V0UGFyc2VyKCkuZ2V0Q29udGV4dCgpKTsKCQkJCQkJLy9wQ29sdW1uUmVmLT5wYXJzZU5vZGVUb1N0cigJYUNvbHVtbnMsCgkJCQkJCS8vCQkJCQkJCXhDb25uZWN0aW9uLAoJCQkJCQkvLwkJCQkJCQkmckNvbnRyb2xsZXIuZ2V0UGFyc2VyKCkuZ2V0Q29udGV4dCgpLAoJCQkJCQkvLwkJCQkJCQlzYWxfVHJ1ZSwKCQkJCQkJLy8JCQkJCQkJc2FsX1RydWUpOyAvLyBxdW90ZSBpcyB0byB0cnVlIGJlY2F1c2Ugd2UgbmVlZCBxdW90ZWQgZWxlbWVudHMgaW5zaWRlIHRoZSBmdW5jdGlvbgoKCQkJCQkJc2FsX0ludDMyIG5GdW5jdGlvblR5cGUgPSBGS1RfTk9ORTsKCQkJCQkJOjpjb25uZWN0aXZpdHk6Ok9TUUxQYXJzZU5vZGUqIHBQYXJhbVJlZiA9IE5VTEw7CgkJCQkJCXNhbF9JbnQzMiBuQ29sdW1uUmVmUG9zID0gcENvbHVtblJlZi0+Y291bnQoKSAtIDI7CgkJCQkJCWlmICggbkNvbHVtblJlZlBvcyA+PSAwICYmIHN0YXRpY19jYXN0PHNhbF91SW50MzI+KG5Db2x1bW5SZWZQb3MpIDwgcENvbHVtblJlZi0+Y291bnQoKSApCgkJCQkJCQlwUGFyYW1SZWYgPSBwQ29sdW1uUmVmLT5nZXRDaGlsZChuQ29sdW1uUmVmUG9zKTsKCgkJCQkJCWlmICgJU1FMX0lTUlVMRShwQ29sdW1uUmVmLGdlbmVyYWxfc2V0X2ZjdCkKCQkJCQkJCSYmCVNRTF9JU1JVTEUocFBhcmFtUmVmLGNvbHVtbl9yZWYpICkKCQkJCQkJewoJCQkJCQkJLy8gUGFyYW1ldGVyIGF1ZiBDb2x1bW5yZWYgcHIidWZlbgoJCQkJCQkJSW5zZXJ0Q29sdW1uUmVmKF9wVmlldyxwUGFyYW1SZWYsYUNvbHVtbk5hbWUsYUNvbHVtbkFsaWFzLGFUYWJsZVJhbmdlLGFJbmZvLHBUYWJMaXN0KTsKCQkJCQkJfQoJCQkJCQllbHNlIGlmICggU1FMX0lTUlVMRShwQ29sdW1uUmVmLGdlbmVyYWxfc2V0X2ZjdCkgKQoJCQkJCQl7CgkJCQkJCQlpZiAoIHBQYXJhbVJlZiAmJiBwUGFyYW1SZWYtPmdldFRva2VuVmFsdWUoKS50b0NoYXIoKSA9PSAnKicgKQoJCQkJCQkJewoJCQkJCQkJCU9Kb2luVGFibGVWaWV3OjpPVGFibGVXaW5kb3dNYXA6Oml0ZXJhdG9yIGFJdGVyID0gcFRhYkxpc3QtPmJlZ2luKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT0pvaW5UYWJsZVZpZXc6Ok9UYWJsZVdpbmRvd01hcDo6aXRlcmF0b3IgYUVuZCAgPSBwVGFiTGlzdC0+ZW5kKCk7CgkJCQkJCQkJZm9yKDthSXRlciAhPSBhRW5kOysrYUl0ZXIpCgkJCQkJCQkJewoJCQkJCQkJCQlPUXVlcnlUYWJsZVdpbmRvdyogcFRhYldpbiA9IHN0YXRpY19jYXN0PE9RdWVyeVRhYmxlV2luZG93Kj4oYUl0ZXItPnNlY29uZCk7CgkJCQkJCQkJCWlmIChwVGFiV2luLT5FeGlzdHNGaWVsZCggOjpydGw6Ok9VU3RyaW5nOjpjcmVhdGVGcm9tQXNjaWkoIioiKSwgYUluZm8gKSkKCQkJCQkJCQkJewoJCQkJCQkJCQkJYUluZm8tPlNldEFsaWFzKFN0cmluZygpKTsKCQkJCQkJCQkJCWFJbmZvLT5TZXRUYWJsZShTdHJpbmcoKSk7CgkJCQkJCQkJCQlicmVhazsKCQkJCQkJCQkJfQoJCQkJCQkJCX0KCQkJCQkJCX0KCQkJCQkJCWVsc2UKCQkJCQkJCXsKCQkJCQkJCQk6OnJ0bDo6T1VTdHJpbmcgc0ZpZWxkTmFtZSA9IGFDb2x1bW5zOwoJCQkJCQkJCWlmICggcFBhcmFtUmVmICkKCQkJCQkJCQl7CS8vIHdlIGdvdCBhbiBhZ2dyZWdhdGUgZnVuY3Rpb24gYnV0IHdpdGhvdXQgY29sdW1uIG5hbWUgaW5zaWRlCgkJCQkJCQkJCS8vIHNvIHdlIHNldCB0aGUgd2hvbGUgYXJndW1lbnQgb2YgdGhlIGZ1bmN0aW9uIGFzIGZpZWxkIG5hbWUKCQkJCQkJCQkJbkZ1bmN0aW9uVHlwZSB8PSBGS1RfTlVNRVJJQzsKCQkJCQkJCQkJc0ZpZWxkTmFtZSA9IDo6cnRsOjpPVVN0cmluZygpOwoJCQkJCQkJCQlwUGFyYW1SZWYtPnBhcnNlTm9kZVRvU3RyKAlzRmllbGROYW1lLAoJCQkJCQkJCQkJCQkJCXhDb25uZWN0aW9uLAoJCQkJCQkJCQkJCQkJCSZyQ29udHJvbGxlci5nZXRQYXJzZXIoKS5nZXRDb250ZXh0KCksCgkJCQkJCQkJCQkJCQkJc2FsX1RydWUsCgkJCQkJCQkJCQkJCQkJc2FsX1RydWUpOyAvLyBxdW90ZSBpcyB0byB0cnVlIGJlY2F1c2Ugd2UgbmVlZCBxdW90ZWQgZWxlbWVudHMgaW5zaWRlIHRoZSBmdW5jdGlvbgoJCQkJCQkJCX0KCQkJCQkJCQlhSW5mby0+U2V0RGF0YVR5cGUoRGF0YVR5cGU6OkRPVUJMRSk7CgkJCQkJCQkJYUluZm8tPlNldEZpZWxkVHlwZShUQUJfTk9STUFMX0ZJRUxEKTsKCQkJCQkJCQlhSW5mby0+U2V0RmllbGQoc0ZpZWxkTmFtZSk7CgkJCQkJCQl9CgkJCQkJCQlhSW5mby0+U2V0VGFiV2luZG93KE5VTEwpOwoJCQkJCQkJYUluZm8tPlNldEZpZWxkQWxpYXMoYUNvbHVtbkFsaWFzKTsKCQkJCQkJfQoJCQkJCQllbHNlCgkJCQkJCXsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9wVmlldy0+ZmlsbEZ1bmN0aW9uSW5mbyhwQ29sdW1uUmVmLGFDb2x1bW5zLGFJbmZvKTsKCQkJCQkJCWFJbmZvLT5TZXRGaWVsZEFsaWFzKGFDb2x1bW5BbGlhcyk7CgkJCQkJCX0KCgkJCQkJCWlmICggU1FMX0lTUlVMRShwQ29sdW1uUmVmLGdlbmVyYWxfc2V0X2ZjdCkgKQoJCQkJCQl7CgkJCQkJCQlhSW5mby0+U2V0RnVuY3Rpb25UeXBlKG5GdW5jdGlvblR5cGV8RktUX0FHR1JFR0FURSk7CgkJCQkJCQlTdHJpbmcgYUNvbChhQ29sdW1ucyk7CgkJCQkJCQlhSW5mby0+U2V0RnVuY3Rpb24oYUNvbC5HZXRUb2tlbigwLCcoJykuRXJhc2VUcmFpbGluZ0NoYXJzKCcgJykpOwoJCQkJCQl9CgkJCQkJCWVsc2UKCQkJCQkJCWFJbmZvLT5TZXRGdW5jdGlvblR5cGUobkZ1bmN0aW9uVHlwZXxGS1RfT1RIRVIpOwoKCQkJCQkJZUVycm9yQ29kZSA9IF9wVmlldy0+SW5zZXJ0RmllbGQoYUluZm8sIHNhbF9UcnVlLCBiRmlyc3RGaWVsZCk7CgkJCQkJCWJGaXJzdEZpZWxkID0gc2FsX0ZhbHNlOwoJCQkJCX0KCQkJCQllbHNlIC8vaWYoU1FMX0lTUlVMRShwQ29sdW1uUmVmLG51bV92YWx1ZV9leHApCXx8IFNRTF9JU1JVTEUocENvbHVtblJlZix0ZXJtKSkKCQkJCQl7CgkJCQkJCTo6cnRsOjpPVVN0cmluZyBhQ29sdW1uczsKCQkJCQkJcENvbHVtblJlZi0+cGFyc2VOb2RlVG9TdHIoCWFDb2x1bW5zLAoJCQkJCQkJCQkJCQkJeENvbm5lY3Rpb24sCgkJCQkJCQkJCQkJCQkmckNvbnRyb2xsZXIuZ2V0UGFyc2VyKCkuZ2V0Q29udGV4dCgpLAoJCQkJCQkJCQkJCQkJc2FsX1RydWUsCgkJCQkJCQkJCQkJCQlzYWxfVHJ1ZSk7IC8vIHF1b3RlIGlzIHRvIHRydWUgYmVjYXVzZSB3ZSBuZWVkIHF1b3RlZCBlbGVtZW50cyBpbnNpZGUgdGhlIGZ1bmN0aW9uCgogICAgICAgICAgICAgICAgICAgICAgICBhSW5mby0+U2V0VGFiV2luZG93KCBOVUxMICk7CgogICAgICAgICAgICAgICAgICAgICAgICAvLyBzaW5jZSB3ZSBzdXBwb3J0IHF1ZXJpZXMgaW4gcXVlcmllcywgdGhlIHRoaW5naWUgbWlnaHQgYmVsb25nIHRvIGFuIGV4aXN0aW5nICJ0YWJsZSIKICAgICAgICAgICAgICAgICAgICAgICAgT1F1ZXJ5VGFibGVXaW5kb3cqIHBFeGlzdGluZ1RhYmxlID0gbGNsX2ZpbmRDb2x1bW5JblRhYmxlcyggYUNvbHVtbnMsICpwVGFiTGlzdCwgYUluZm8gKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCBwRXhpc3RpbmdUYWJsZSApCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFJbmZvLT5TZXRUYWJXaW5kb3coIHBFeGlzdGluZ1RhYmxlICk7CgkJCQkJICAgICAgICBhSW5mby0+U2V0VGFibGUoIHBFeGlzdGluZ1RhYmxlLT5HZXRUYWJsZU5hbWUoKSApOwoJCQkJCSAgICAgICAgYUluZm8tPlNldEFsaWFzKCBwRXhpc3RpbmdUYWJsZS0+R2V0QWxpYXNOYW1lKCkgKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgYUluZm8tPlNldERhdGFUeXBlKERhdGFUeXBlOjpET1VCTEUpOwoJCQkJCQlhSW5mby0+U2V0RmllbGRUeXBlKFRBQl9OT1JNQUxfRklFTEQpOwoJCQkJCQlhSW5mby0+U2V0RmllbGQoYUNvbHVtbnMpOwoJCQkJCQlhSW5mby0+U2V0RmllbGRBbGlhcyhhQ29sdW1uQWxpYXMpOwoJCQkJCQlhSW5mby0+U2V0RnVuY3Rpb25UeXBlKEZLVF9OVU1FUklDIHwgRktUX09USEVSKTsKCgkJCQkJCWVFcnJvckNvZGUgPSBfcFZpZXctPkluc2VydEZpZWxkKGFJbmZvLCBzYWxfVHJ1ZSwgYkZpcnN0RmllbGQpOwoJCQkJCQliRmlyc3RGaWVsZCA9IHNhbF9GYWxzZTsKCQkJCQl9CgogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoJCQkJfQoKICAgICAgICAgICAgICAgIERCR19FUlJPUiggIkluc3RhbGxGaWVsZHM6IGRvbid0IGtub3cgaG93IHRvIGludGVycHJldCB0aGlzIHBhcnNlIG5vZGUhIiApOwoKICAgICAgICAgICAgICAgIH0gd2hpbGUgKCBmYWxzZSApOwoJCQl9CgkJfQoJCWVsc2UKCQkJZUVycm9yQ29kZSA9IGVTdGF0ZW1lbnRUb29Db21wbGV4OwoKCQlyZXR1cm4gZUVycm9yQ29kZTsKCX0KCS8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCglTcWxQYXJzZUVycm9yIEdldE9yZGVyQ3JpdGVyaWEoCU9RdWVyeURlc2lnblZpZXcqIF9wVmlldywKCQkJCQkJCU9TZWxlY3Rpb25Ccm93c2VCb3gqIF9wU2VsZWN0aW9uQnJ3LAoJCQkJCQkJY29uc3QgOjpjb25uZWN0aXZpdHk6Ok9TUUxQYXJzZU5vZGUqIHBQYXJzZVJvb3QgKQoJewoJCVNxbFBhcnNlRXJyb3IgZUVycm9yQ29kZSA9IGVPazsKCQlpZiAoIXBQYXJzZVJvb3QtPmdldENoaWxkKDMpLT5nZXRDaGlsZCg0KS0+aXNMZWFmKCkpCgkJewoJCQk6OmNvbm5lY3Rpdml0eTo6T1NRTFBhcnNlTm9kZSogcE5vZGUgPSBwUGFyc2VSb290LT5nZXRDaGlsZCgzKS0+Z2V0Q2hpbGQoNCktPmdldENoaWxkKDIpOwoJCQk6OmNvbm5lY3Rpdml0eTo6T1NRTFBhcnNlTm9kZSogcFBhcmFtUmVmID0gTlVMTDsKCiAgICAgICAgICAgIE9RdWVyeUNvbnRyb2xsZXImIHJDb250cm9sbGVyID0gc3RhdGljX2Nhc3Q8T1F1ZXJ5Q29udHJvbGxlciY+KF9wVmlldy0+Z2V0Q29udHJvbGxlcigpKTsKCQkJRU9yZGVyRGlyIGVPcmRlckRpcjsKCQkJT1RhYmxlRmllbGREZXNjUmVmIGFEcmFnTGVmdCA9IG5ldyBPVGFibGVGaWVsZERlc2MoKTsKCQkJZm9yKCBzYWxfdUludDMyIGk9MCA7IGk8cE5vZGUtPmNvdW50KCkgOyBpKysgKQoJCQl7CgkJCQllT3JkZXJEaXIgPSBPUkRFUl9BU0M7CgkJCQk6OmNvbm5lY3Rpdml0eTo6T1NRTFBhcnNlTm9kZSoJcENoaWxkID0gcE5vZGUtPmdldENoaWxkKCBpICk7CgoJCQkJaWYgKFNRTF9JU1RPS0VOKCBwQ2hpbGQtPmdldENoaWxkKDEpLCBERVNDICkgKQoJCQkJCWVPcmRlckRpciA9IE9SREVSX0RFU0M7CgogICAgICAgICAgICAgICAgOjpjb25uZWN0aXZpdHk6Ok9TUUxQYXJzZU5vZGUqIHBBcmd1bWVudCA9IHBDaGlsZC0+Z2V0Q2hpbGQoMCk7CiAgICAgICAgICAgICAgICAKCQkJCWlmKFNRTF9JU1JVTEUocEFyZ3VtZW50LGNvbHVtbl9yZWYpKQoJCQkJewoJCQkJCWlmKCBlT2sgPT0gRmlsbERyYWdJbmZvKF9wVmlldyxwQXJndW1lbnQsYURyYWdMZWZ0KSkKCQkJCQkJX3BTZWxlY3Rpb25CcnctPkFkZE9yZGVyKCBhRHJhZ0xlZnQsIGVPcmRlckRpciwgaSk7CgkJCQkJZWxzZSAvLyBpdCBjb3VsZCBiZSBhIGFsaWFzIG5hbWUgZm9yIGEgZmllbGQKCQkJCQl7CgkJCQkJCTo6cnRsOjpPVVN0cmluZyBhVGFibGVSYW5nZSxhQ29sdW1uTmFtZTsKCQkJCQkJOjpjb25uZWN0aXZpdHk6Ok9TUUxQYXJzZVRyZWVJdGVyYXRvciYgclBhcnNlSXRlciA9IHJDb250cm9sbGVyLmdldFBhcnNlSXRlcmF0b3IoKTsKCQkJCQkJclBhcnNlSXRlci5nZXRDb2x1bW5SYW5nZSggcEFyZ3VtZW50LCBhQ29sdW1uTmFtZSwgYVRhYmxlUmFuZ2UgKTsKCgkJCQkJCU9UYWJsZUZpZWxkcyYgYUxpc3QgPSByQ29udHJvbGxlci5nZXRUYWJsZUZpZWxkRGVzYygpOwoJCQkJCQlPVGFibGVGaWVsZHM6Oml0ZXJhdG9yIGFJdGVyID0gYUxpc3QuYmVnaW4oKTsKICAgICAgICAgICAgICAgICAgICAgICAgT1RhYmxlRmllbGRzOjppdGVyYXRvciBhRW5kID0gYUxpc3QuZW5kKCk7CgkJCQkJCWZvcig7YUl0ZXIgIT0gYUVuZDsrK2FJdGVyKQoJCQkJCQl7CgkJCQkJCQlPVGFibGVGaWVsZERlc2NSZWYgcEVudHJ5ID0gKmFJdGVyOwoJCQkJCQkJaWYocEVudHJ5LmlzVmFsaWQoKSAmJiBwRW50cnktPkdldEZpZWxkQWxpYXMoKSA9PSBhQ29sdW1uTmFtZSkKCQkJCQkJCQlwRW50cnktPlNldE9yZGVyRGlyKCBlT3JkZXJEaXIgKTsKCQkJCQkJfQoJCQkJCX0KCQkJCX0KCQkJCWVsc2UgaWYoU1FMX0lTUlVMRShwQXJndW1lbnQsIGdlbmVyYWxfc2V0X2ZjdCApICYmCgkJCQkJCVNRTF9JU1JVTEUocFBhcmFtUmVmID0gcEFyZ3VtZW50LT5nZXRDaGlsZChwQXJndW1lbnQtPmNvdW50KCktMiksY29sdW1uX3JlZikgJiYKCQkJCQkJZU9rID09IEZpbGxEcmFnSW5mbyhfcFZpZXcscFBhcmFtUmVmLGFEcmFnTGVmdCkpCgkJCQkJX3BTZWxlY3Rpb25CcnctPkFkZE9yZGVyKCBhRHJhZ0xlZnQsIGVPcmRlckRpciwgaSApOwogICAgICAgICAgICAgICAgZWxzZSBpZiggU1FMX0lTUlVMRShwQXJndW1lbnQsIHNldF9mY3Rfc3BlYyApICkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAKCQkgICAgICAgICAgICBSZWZlcmVuY2U8IFhDb25uZWN0aW9uPiB4Q29ubmVjdGlvbiA9IHJDb250cm9sbGVyLmdldENvbm5lY3Rpb24oKTsKCQkgICAgICAgICAgICBpZih4Q29ubmVjdGlvbi5pcygpKQoJCSAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgOjpydGw6Ok9VU3RyaW5nIHNDb25kaXRpb247CgkJCSAgICAgICAgICAgIHBBcmd1bWVudC0+cGFyc2VOb2RlVG9QcmVkaWNhdGVTdHIoc0NvbmRpdGlvbiwKCQkJCQkJCQkJCQkJICAgICAgICAgICAgeENvbm5lY3Rpb24sCgkJCQkJCQkJCQkJCSAgICAgICAgICAgIHJDb250cm9sbGVyLmdldE51bWJlckZvcm1hdHRlcigpLAoJCQkJCQkJCQkJCQkgICAgICAgICAgICBfcFZpZXctPmdldExvY2FsZSgpLAoJCQkJCQkJCQkJCQkgICAgICAgICAgICBzdGF0aWNfY2FzdDxzYWxfQ2hhcj4oX3BWaWV3LT5nZXREZWNpbWFsU2VwYXJhdG9yKCkudG9DaGFyKCkpLAoJCQkJCQkJCQkJCQkgICAgICAgICAgICAmckNvbnRyb2xsZXIuZ2V0UGFyc2VyKCkuZ2V0Q29udGV4dCgpKTsKICAgICAgICAgICAgICAgICAgICAgICAgX3BWaWV3LT5maWxsRnVuY3Rpb25JbmZvKHBBcmd1bWVudCxzQ29uZGl0aW9uLGFEcmFnTGVmdCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGFEcmFnTGVmdC0+U2V0RnVuY3Rpb25UeXBlKEZLVF9PVEhFUik7CiAgICAgICAgICAgICAgICAgICAgICAgIGFEcmFnTGVmdC0+U2V0T3JkZXJEaXIoZU9yZGVyRGlyKTsKICAgICAgICAgICAgICAgICAgICAgICAgYURyYWdMZWZ0LT5TZXRWaXNpYmxlKHNhbF9GYWxzZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIF9wU2VsZWN0aW9uQnJ3LT5BZGRPcmRlciggYURyYWdMZWZ0LCBlT3JkZXJEaXIsIGkgKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICBlRXJyb3JDb2RlID0gZUNvbHVtbk5vdEZvdW5kOwogICAgICAgICAgICAgICAgfQoJCQkJZWxzZQoJCQkJCWVFcnJvckNvZGUgPSBlQ29sdW1uTm90Rm91bmQ7CgkJCX0KCQl9CgkJcmV0dXJuIGVFcnJvckNvZGU7Cgl9CgkvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoJU3FsUGFyc2VFcnJvciBHZXRIYXZpbmdDcml0ZXJpYSgJT1F1ZXJ5RGVzaWduVmlldyogX3BWaWV3LAoJCQkJCQkJT1NlbGVjdGlvbkJyb3dzZUJveCogX3BTZWxlY3Rpb25CcncsCgkJCQkJCQljb25zdCA6OmNvbm5lY3Rpdml0eTo6T1NRTFBhcnNlTm9kZSogcFNlbGVjdFJvb3QsCgkJCQkJCQlzYWxfdUludDE2JiByTGV2ZWwgKQoJewoJCVNxbFBhcnNlRXJyb3IgZUVycm9yQ29kZSA9IGVPazsKCQlpZiAoIXBTZWxlY3RSb290LT5nZXRDaGlsZCgzKS0+Z2V0Q2hpbGQoMyktPmlzTGVhZigpKQoJCQllRXJyb3JDb2RlID0gR2V0T1JDcml0ZXJpYShfcFZpZXcsX3BTZWxlY3Rpb25CcncscFNlbGVjdFJvb3QtPmdldENoaWxkKDMpLT5nZXRDaGlsZCgzKS0+Z2V0Q2hpbGQoMSksckxldmVsLCBzYWxfVHJ1ZSk7CgkJcmV0dXJuIGVFcnJvckNvZGU7Cgl9CgkvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoJU3FsUGFyc2VFcnJvciBHZXRHcm91cENyaXRlcmlhKAlPUXVlcnlEZXNpZ25WaWV3KiBfcFZpZXcsCgkJCQkJCQlPU2VsZWN0aW9uQnJvd3NlQm94KiBfcFNlbGVjdGlvbkJydywKCQkJCQkJCWNvbnN0IDo6Y29ubmVjdGl2aXR5OjpPU1FMUGFyc2VOb2RlKiBwU2VsZWN0Um9vdCApCgl7CgkJU3FsUGFyc2VFcnJvciBlRXJyb3JDb2RlID0gZU9rOwoJCWlmICghcFNlbGVjdFJvb3QtPmdldENoaWxkKDMpLT5nZXRDaGlsZCgyKS0+aXNMZWFmKCkpIC8vIG9wdF9ncm91cF9ieV9jbGF1c2UKCQl7CiAgICAgICAgICAgIE9RdWVyeUNvbnRyb2xsZXImIHJDb250cm9sbGVyID0gc3RhdGljX2Nhc3Q8T1F1ZXJ5Q29udHJvbGxlciY+KF9wVmlldy0+Z2V0Q29udHJvbGxlcigpKTsKCQkJOjpjb25uZWN0aXZpdHk6Ok9TUUxQYXJzZU5vZGUqIHBHcm91cEJ5ID0gcFNlbGVjdFJvb3QtPmdldENoaWxkKDMpLT5nZXRDaGlsZCgyKS0+Z2V0Q2hpbGQoMik7CgkJCQoJCQlmb3IoIHNhbF91SW50MzIgaT0wIDsgaSA8IHBHcm91cEJ5LT5jb3VudCgpICYmIGVPayA9PSBlRXJyb3JDb2RlOyArK2kgKQoJCQl7CiAgICAgICAgICAgICAgICBPVGFibGVGaWVsZERlc2NSZWYgYURyYWdJbmZvID0gbmV3IE9UYWJsZUZpZWxkRGVzYygpOwogICAgICAgICAgICAgICAgOjpjb25uZWN0aXZpdHk6Ok9TUUxQYXJzZU5vZGUqIHBQYXJhbVJlZiA9IE5VTEw7CgkJCQk6OmNvbm5lY3Rpdml0eTo6T1NRTFBhcnNlTm9kZSogcEFyZ3VtZW50ID0gcEdyb3VwQnktPmdldENoaWxkKCBpICk7CgkJCQlpZihTUUxfSVNSVUxFKHBBcmd1bWVudCxjb2x1bW5fcmVmKSkKCQkJCXsKCQkJCQlpZiAoIGVPayA9PSAoZUVycm9yQ29kZSA9IEZpbGxEcmFnSW5mbyhfcFZpZXcscEFyZ3VtZW50LGFEcmFnSW5mbykpICkKCQkJCQl7CgkJCQkJCWFEcmFnSW5mby0+U2V0R3JvdXBCeShzYWxfVHJ1ZSk7CgkJCQkJCV9wU2VsZWN0aW9uQnJ3LT5BZGRHcm91cEJ5KGFEcmFnSW5mbyxpKTsKCQkJCQl9CgkJCQl9CiAgICAgICAgICAgICAgICBlbHNlIGlmKFNRTF9JU1JVTEUocEFyZ3VtZW50LCBnZW5lcmFsX3NldF9mY3QgKSAmJgoJCQkJCQlTUUxfSVNSVUxFKHBQYXJhbVJlZiA9IHBBcmd1bWVudC0+Z2V0Q2hpbGQocEFyZ3VtZW50LT5jb3VudCgpLTIpLGNvbHVtbl9yZWYpICYmCgkJCQkJCWVPayA9PSBGaWxsRHJhZ0luZm8oX3BWaWV3LHBQYXJhbVJlZixhRHJhZ0luZm8pKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGFEcmFnSW5mby0+U2V0R3JvdXBCeShzYWxfVHJ1ZSk7CgkJCQkJX3BTZWxlY3Rpb25CcnctPkFkZEdyb3VwQnkoIGFEcmFnSW5mbywgaSApOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZSBpZiggU1FMX0lTUlVMRShwQXJndW1lbnQsIHNldF9mY3Rfc3BlYyApICkKICAgICAgICAgICAgICAgIHsgICAgICAgICAgICAgICAgICAgIAoJCSAgICAgICAgICAgIFJlZmVyZW5jZTwgWENvbm5lY3Rpb24+IHhDb25uZWN0aW9uID0gckNvbnRyb2xsZXIuZ2V0Q29ubmVjdGlvbigpOwoJCSAgICAgICAgICAgIGlmKHhDb25uZWN0aW9uLmlzKCkpCgkJICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICA6OnJ0bDo6T1VTdHJpbmcgc0dyb3VwQnlFeHByZXNzaW9uOwoJCQkgICAgICAgICAgICBwQXJndW1lbnQtPnBhcnNlTm9kZVRvU3RyKAlzR3JvdXBCeUV4cHJlc3Npb24sCgkJCQkJCQkJCQkJCQl4Q29ubmVjdGlvbiwKCQkJCQkJCQkJCQkJCSZyQ29udHJvbGxlci5nZXRQYXJzZXIoKS5nZXRDb250ZXh0KCksCgkJCQkJCQkJCQkJCQlzYWxfVHJ1ZSwKCQkJCQkJCQkJCQkJCXNhbF9UcnVlKTsgLy8gcXVvdGUgaXMgdG8gdHJ1ZSBiZWNhdXNlIHdlIG5lZWQgcXVvdGVkIGVsZW1lbnRzIGluc2lkZSB0aGUgZnVuY3Rpb24KICAgICAgICAgICAgICAgICAgICAgICAgX3BWaWV3LT5maWxsRnVuY3Rpb25JbmZvKHBBcmd1bWVudCxzR3JvdXBCeUV4cHJlc3Npb24sYURyYWdJbmZvKTsKICAgICAgICAgICAgICAgICAgICAgICAgYURyYWdJbmZvLT5TZXRGdW5jdGlvblR5cGUoRktUX09USEVSKTsKICAgICAgICAgICAgICAgICAgICAgICAgYURyYWdJbmZvLT5TZXRHcm91cEJ5KHNhbF9UcnVlKTsKICAgICAgICAgICAgICAgICAgICAgICAgYURyYWdJbmZvLT5TZXRWaXNpYmxlKHNhbF9GYWxzZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIF9wU2VsZWN0aW9uQnJ3LT5BZGRHcm91cEJ5KCBhRHJhZ0luZm8sIGkgKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICBlRXJyb3JDb2RlID0gZUNvbHVtbk5vdEZvdW5kOwogICAgICAgICAgICAgICAgfQoJCQl9CgkJfQoJCXJldHVybiBlRXJyb3JDb2RlOwoJfQoKICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCglTdHJpbmcgZ2V0UGFyc2VFcnJvck1lc3NhZ2UoIFNxbFBhcnNlRXJyb3IgX2VFcnJvckNvZGUgKQoJewoJCXNhbF91SW50MTYgblJlc0lkOwoJCXN3aXRjaChfZUVycm9yQ29kZSkKCQl7CgkJCWNhc2UgZUlsbGVnYWxKb2luOgoJCQkJblJlc0lkID0gU1RSX1FSWV9JTExFR0FMX0pPSU47CgkJCQlicmVhazsKCQkJY2FzZSBlU3RhdGVtZW50VG9vTG9uZzoKCQkJCW5SZXNJZCA9IFNUUl9RUllfVE9PX0xPTkdfU1RBVEVNRU5UOwoJCQkJYnJlYWs7CgkJCWNhc2UgZU5vQ29ubmVjdGlvbjoKCQkJCW5SZXNJZCA9IFNUUl9RUllfU1lOVEFYOwoJCQkJYnJlYWs7CgkJCWNhc2UgZU5vU2VsZWN0U3RhdGVtZW50OgoJCQkJblJlc0lkID0gU1RSX1FSWV9OT1NFTEVDVDsKCQkJCWJyZWFrOwoJCQljYXNlIGVDb2x1bW5Jbkxpa2VOb3RGb3VuZDoKCQkJCW5SZXNJZCA9IFNUUl9RUllfU1lOVEFYOwoJCQkJYnJlYWs7CgkJCWNhc2UgZU5vQ29sdW1uSW5MaWtlOgoJCQkJblJlc0lkID0gU1RSX1FSWV9TWU5UQVg7CgkJCQlicmVhazsKCQkJY2FzZSBlQ29sdW1uTm90Rm91bmQ6CgkJCQluUmVzSWQgPSBTVFJfUVJZX1NZTlRBWDsKCQkJCWJyZWFrOwoJCQljYXNlIGVOYXRpdmVNb2RlOgoJCQkJblJlc0lkID0gU1RSX1FSWV9OQVRJVkU7CgkJCQlicmVhazsKCQkJY2FzZSBlVG9vTWFueVRhYmxlczoKCQkJCW5SZXNJZCA9IFNUUl9RUllfVE9PX01BTllfVEFCTEVTOwoJCQkJYnJlYWs7CgkJCWNhc2UgZVRvb01hbnlDb25kaXRpb25zOgoJCQkJblJlc0lkID0gU1RSX1FSWV9UT09NQU5ZQ09ORDsKCQkJCWJyZWFrOwoJCQljYXNlIGVUb29NYW55Q29sdW1uczoKCQkJCW5SZXNJZCA9IFNUUl9RUllfVE9PX01BTllfQ09MVU1OUzsKCQkJCWJyZWFrOwoJCQljYXNlIGVTdGF0ZW1lbnRUb29Db21wbGV4OgoJCQkJblJlc0lkID0gU1RSX1FSWV9UT09DT01QTEVYOwoJCQkJYnJlYWs7CgkJCWRlZmF1bHQ6CgkJCQluUmVzSWQgPSBTVFJfUVJZX1NZTlRBWDsKCQkJCWJyZWFrOwoJCX0KCQk7CiAgICAgICAgcmV0dXJuIFN0cmluZyggTW9kdWxlUmVzKCBuUmVzSWQgKSApOwoJfQoKCS8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgkvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp9Ci8vIGVuZCBvZiBhbm9ueW1vdXNlIG5hbWVzcGFjZQpEQkdfTkFNRShPUXVlcnlEZXNpZ25WaWV3KQoKT1F1ZXJ5RGVzaWduVmlldzo6T1F1ZXJ5RGVzaWduVmlldygJT1F1ZXJ5Q29udGFpbmVyV2luZG93KiBfcFBhcmVudCwKCQkJCQkJCQkJT1F1ZXJ5Q29udHJvbGxlciYgX3JDb250cm9sbGVyLAoJCQkJCQkJCQljb25zdCBSZWZlcmVuY2U8IFhNdWx0aVNlcnZpY2VGYWN0b3J5ID4mIF9yRmFjdG9yeSkKCTpPUXVlcnlWaWV3KCBfcFBhcmVudCwgX3JDb250cm9sbGVyLCBfckZhY3RvcnkgKQoJLG1fYVNwbGl0dGVyKCB0aGlzICkKCSxtX2VDaGlsZEZvY3VzKE5PTkUpCgksbV9iSW5LZXlFdmVudChzYWxfRmFsc2UpCgksbV9iSW5TcGxpdEhhbmRsZXIoIHNhbF9GYWxzZSApCnsKICAgIERCR19DVE9SKE9RdWVyeURlc2lnblZpZXcsTlVMTCk7CgoJdHJ5Cgl7CgkJU3Z0U3lzTG9jYWxlIGFTeXNMb2NhbGU7CgkJbV9hTG9jYWxlID0gYVN5c0xvY2FsZS5HZXRMb2NhbGVEYXRhKCkuZ2V0TG9jYWxlKCk7CgkJbV9zRGVjaW1hbFNlcCA9IGFTeXNMb2NhbGUuR2V0TG9jYWxlRGF0YSgpLmdldE51bURlY2ltYWxTZXAoKTsKCX0KCWNhdGNoKEV4Y2VwdGlvbiYpCgl7Cgl9CgoJbV9wU2VsZWN0aW9uQm94ID0gbmV3IE9TZWxlY3Rpb25Ccm93c2VCb3godGhpcyk7CgoJc2V0Tm9uZVZpc2JsZVJvdyhzdGF0aWNfY2FzdDxPUXVlcnlDb250cm9sbGVyJj4oZ2V0Q29udHJvbGxlcigpKS5nZXRWaXNpYmxlUm93cygpKTsKCW1fcFNlbGVjdGlvbkJveC0+U2hvdygpOwoJLy8gU3BsaXR0ZXIgZWlucmljaHRlbgoJbV9hU3BsaXR0ZXIuU2V0U3BsaXRIZGwoTElOSyh0aGlzLCBPUXVlcnlEZXNpZ25WaWV3LFNwbGl0SGRsKSk7CgltX2FTcGxpdHRlci5TaG93KCk7Cgp9Ci8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCk9RdWVyeURlc2lnblZpZXc6On5PUXVlcnlEZXNpZ25WaWV3KCkKewoJaWYgKCBtX3BUYWJsZVZpZXcgKQoJCTo6ZGJhdWk6Om5vdGlmeVN5c3RlbVdpbmRvdyh0aGlzLG1fcFRhYmxlVmlldyw6OmNvbXBoZWxwZXI6Om1lbV9mdW4oJlRhc2tQYW5lTGlzdDo6UmVtb3ZlV2luZG93KSk7Cgk6OnN0ZDo6YXV0b19wdHI8V2luZG93PiBhVGVtcChtX3BTZWxlY3Rpb25Cb3gpOwoJbV9wU2VsZWN0aW9uQm94ID0gTlVMTDsKCiAgICBEQkdfRFRPUihPUXVlcnlEZXNpZ25WaWV3LE5VTEwpOwp9Ci8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCklNUExfTElOSyggT1F1ZXJ5RGVzaWduVmlldywgU3BsaXRIZGwsIHZvaWQqLCAvKnAqLyApCnsKCWlmICghZ2V0Q29udHJvbGxlcigpLmlzUmVhZE9ubHkoKSkKCXsKCQltX2JJblNwbGl0SGFuZGxlciA9IHNhbF9UcnVlOwoJCW1fYVNwbGl0dGVyLlNldFBvc1BpeGVsKCBQb2ludCggbV9hU3BsaXR0ZXIuR2V0UG9zUGl4ZWwoKS5YKCksbV9hU3BsaXR0ZXIuR2V0U3BsaXRQb3NQaXhlbCgpICkgKTsKCQlzdGF0aWNfY2FzdDxPUXVlcnlDb250cm9sbGVyJj4oZ2V0Q29udHJvbGxlcigpKS5zZXRTcGxpdFBvcyhtX2FTcGxpdHRlci5HZXRTcGxpdFBvc1BpeGVsKCkpOwoJCXN0YXRpY19jYXN0PE9RdWVyeUNvbnRyb2xsZXImPihnZXRDb250cm9sbGVyKCkpLnNldE1vZGlmaWVkKCBzYWxfVHJ1ZSApOwoJCVJlc2l6ZSgpOwoJCW1fYkluU3BsaXRIYW5kbGVyID0gc2FsX1RydWU7Cgl9CglyZXR1cm4gMEw7Cn0KLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIE9RdWVyeURlc2lnblZpZXc6OkNvbnN0cnVjdCgpCnsKCW1fcFRhYmxlVmlldyA9IG5ldyBPUXVlcnlUYWJsZVZpZXcobV9wU2Nyb2xsV2luZG93LHRoaXMpOwoJOjpkYmF1aTo6bm90aWZ5U3lzdGVtV2luZG93KHRoaXMsbV9wVGFibGVWaWV3LDo6Y29tcGhlbHBlcjo6bWVtX2Z1bigmVGFza1BhbmVMaXN0OjpBZGRXaW5kb3cpKTsKCU9RdWVyeVZpZXc6OkNvbnN0cnVjdCgpOwp9Ci8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgT1F1ZXJ5RGVzaWduVmlldzo6aW5pdGlhbGl6ZSgpCnsKCWlmKHN0YXRpY19jYXN0PE9RdWVyeUNvbnRyb2xsZXImPihnZXRDb250cm9sbGVyKCkpLmdldFNwbGl0UG9zKCkgIT0gLTEpCgl7CgkJbV9hU3BsaXR0ZXIuU2V0UG9zUGl4ZWwoIFBvaW50KCBtX2FTcGxpdHRlci5HZXRQb3NQaXhlbCgpLlgoKSxzdGF0aWNfY2FzdDxPUXVlcnlDb250cm9sbGVyJj4oZ2V0Q29udHJvbGxlcigpKS5nZXRTcGxpdFBvcygpICkgKTsKCQltX2FTcGxpdHRlci5TZXRTcGxpdFBvc1BpeGVsKHN0YXRpY19jYXN0PE9RdWVyeUNvbnRyb2xsZXImPihnZXRDb250cm9sbGVyKCkpLmdldFNwbGl0UG9zKCkpOwoJfQoJbV9wU2VsZWN0aW9uQm94LT5pbml0aWFsaXplKCk7CglyZXNldCgpOwp9Ci8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBPUXVlcnlEZXNpZ25WaWV3OjpyZXNpemVEb2N1bWVudFZpZXcoUmVjdGFuZ2xlJiBfclBsYXlncm91bmQpCnsKCVBvaW50IGFQbGF5Z3JvdW5kUG9zKCBfclBsYXlncm91bmQuVG9wTGVmdCgpICk7CglTaXplIGFQbGF5Z3JvdW5kU2l6ZSggX3JQbGF5Z3JvdW5kLkdldFNpemUoKSApOwoKCS8vIGNhbGMgdGhlIHNwbGl0IHBvcywgYW5kIGZvcndhcmQgaXQgdG8gdGhlIGNvbnRyb2xsZXIKCXNhbF9JbnQzMiBuU3BsaXRQb3MgPSBzdGF0aWNfY2FzdDxPUXVlcnlDb250cm9sbGVyJj4oZ2V0Q29udHJvbGxlcigpKS5nZXRTcGxpdFBvcygpOwoJaWYgKCAwICE9IGFQbGF5Z3JvdW5kU2l6ZS5IZWlnaHQoKSApCgl7CgkJaWYJKAkoIC0xID09IG5TcGxpdFBvcyApCgkJCXx8CSggblNwbGl0UG9zID49IGFQbGF5Z3JvdW5kU2l6ZS5IZWlnaHQoKSApCgkJCSkKCQl7CgkJCS8vIGxldCB0aGUgc2VsZWN0aW9uIGJyb3dzZSBib3ggZGV0ZXJtaW5lIGFuIG9wdGltYWwgc2l6ZQoJCQlTaXplIGFTZWxlY3Rpb25Cb3hTaXplID0gbV9wU2VsZWN0aW9uQm94LT5DYWxjT3B0aW1hbFNpemUoIGFQbGF5Z3JvdW5kU2l6ZSApOwoJCQluU3BsaXRQb3MgPSBhUGxheWdyb3VuZFNpemUuSGVpZ2h0KCkgLSBhU2VsZWN0aW9uQm94U2l6ZS5IZWlnaHQoKSAtIG1fYVNwbGl0dGVyLkdldFNpemVQaXhlbCgpLkhlaWdodCgpOwoJCQkvLyBzdGlsbCBhbiBpbnZhbGlkIHNpemU/CgkJCWlmICggblNwbGl0UG9zID09IC0xIHx8IG5TcGxpdFBvcyA+PSBhUGxheWdyb3VuZFNpemUuSGVpZ2h0KCkgKQoJCQkJblNwbGl0UG9zID0gc2FsX0ludDMyKGFQbGF5Z3JvdW5kU2l6ZS5IZWlnaHQoKSowLjYpOwoKCQkJc3RhdGljX2Nhc3Q8T1F1ZXJ5Q29udHJvbGxlciY+KGdldENvbnRyb2xsZXIoKSkuc2V0U3BsaXRQb3MoblNwbGl0UG9zKTsKCQl9CgoJCWlmICggIW1fYkluU3BsaXRIYW5kbGVyICkKCQl7CS8vIHRoZSByZXNpemUgaXMgdHJpZ2dlcmVkIGJ5IHNvbWV0aGluZyBlbHNlIHRoYW4gdGhlIHNwbGl0IGhhbmRsZXIKCQkJLy8gb3VyIG1haW4gZm9jdXMgaXMgdG8gdHJ5IHRvIHByZXNlcnZlIHRoZSBzaXplIG9mIHRoZSBzZWxlY3Rpb25icm93c2UgYm94CgkJCVNpemUgYVNlbEJveFNpemUgPSBtX3BTZWxlY3Rpb25Cb3gtPkdldFNpemVQaXhlbCgpOwoJCQlpZiAoIGFTZWxCb3hTaXplLkhlaWdodCgpICkKCQkJewoJCQkJLy8ga2VlcCB0aGUgc2l6ZSBvZiB0aGUgc2VsIGJveCBjb25zdGFudAoJCQkJblNwbGl0UG9zID0gYVBsYXlncm91bmRTaXplLkhlaWdodCgpIC0gbV9hU3BsaXR0ZXIuR2V0U2l6ZVBpeGVsKCkuSGVpZ2h0KCkgLSBhU2VsQm94U2l6ZS5IZWlnaHQoKTsKCgkJCQkvLyBhbmQgaWYgdGhlIGJveCBpcyBzbWFsbGVyIHRoYW4gdGhlIG9wdGltYWwgc2l6ZSwgdHJ5IHRvIGRvIHNvbWV0aGluZyBhYm91dCBpdAoJCQkJU2l6ZSBhU2VsQm94T3B0U2l6ZSA9IG1fcFNlbGVjdGlvbkJveC0+Q2FsY09wdGltYWxTaXplKCBhUGxheWdyb3VuZFNpemUgKTsKCQkJCWlmICggYVNlbEJveE9wdFNpemUuSGVpZ2h0KCkgPiBhU2VsQm94U2l6ZS5IZWlnaHQoKSApCgkJCQl7CgkJCQkJblNwbGl0UG9zID0gYVBsYXlncm91bmRTaXplLkhlaWdodCgpIC0gbV9hU3BsaXR0ZXIuR2V0U2l6ZVBpeGVsKCkuSGVpZ2h0KCkgLSBhU2VsQm94T3B0U2l6ZS5IZWlnaHQoKTsKCQkJCX0KCgkJCQlzdGF0aWNfY2FzdDwgT1F1ZXJ5Q29udHJvbGxlciYgPihnZXRDb250cm9sbGVyKCkpLnNldFNwbGl0UG9zKCBuU3BsaXRQb3MgKTsKCQkJfQoJCX0KCX0KCgkvLyBub3JtYWxpemUgdGhlIHNwbGl0IHBvcwoJUG9pbnQJYVNwbGl0UG9zCQk9IFBvaW50KCBfclBsYXlncm91bmQuTGVmdCgpLCBuU3BsaXRQb3MgKTsKCVNpemUJYVNwbGl0U2l6ZQkJPSBTaXplKCBfclBsYXlncm91bmQuR2V0U2l6ZSgpLldpZHRoKCksIG1fYVNwbGl0dGVyLkdldFNpemVQaXhlbCgpLkhlaWdodCgpICk7CgoJaWYoICggYVNwbGl0UG9zLlkoKSArIGFTcGxpdFNpemUuSGVpZ2h0KCkgKSA+ICggYVBsYXlncm91bmRTaXplLkhlaWdodCgpICkpCgkJYVNwbGl0UG9zLlkoKSA9IGFQbGF5Z3JvdW5kU2l6ZS5IZWlnaHQoKSAtIGFTcGxpdFNpemUuSGVpZ2h0KCk7CgoJaWYoIGFTcGxpdFBvcy5ZKCkgPD0gYVBsYXlncm91bmRQb3MuWSgpICkKCQlhU3BsaXRQb3MuWSgpID0gYVBsYXlncm91bmRQb3MuWSgpICsgc2FsX0ludDMyKGFQbGF5Z3JvdW5kU2l6ZS5IZWlnaHQoKSAqIDAuMik7CgoJLy8gcG9zaXRpb24gdGhlIHRhYmxlCglTaXplIGFUYWJsZVZpZXdTaXplKGFQbGF5Z3JvdW5kU2l6ZS5XaWR0aCgpLCBhU3BsaXRQb3MuWSgpIC0gYVBsYXlncm91bmRQb3MuWSgpKTsKCW1fcFNjcm9sbFdpbmRvdy0+U2V0UG9zU2l6ZVBpeGVsKGFQbGF5Z3JvdW5kUG9zLCBhVGFibGVWaWV3U2l6ZSk7CgoJLy8gcG9zaXRpb24gdGhlIHNlbGVjdGlvbiBicm93c2UgYm94CglQb2ludCBhUG9zKCBhUGxheWdyb3VuZFBvcy5YKCksIGFTcGxpdFBvcy5ZKCkgKyBhU3BsaXRTaXplLkhlaWdodCgpICk7CgltX3BTZWxlY3Rpb25Cb3gtPlNldFBvc1NpemVQaXhlbCggYVBvcywgU2l6ZSggYVBsYXlncm91bmRTaXplLldpZHRoKCksIGFQbGF5Z3JvdW5kU2l6ZS5IZWlnaHQoKSAtIGFTcGxpdFNpemUuSGVpZ2h0KCkgLSBhVGFibGVWaWV3U2l6ZS5IZWlnaHQoKSApKTsKCgkvLyBzZXQgdGhlIHNpemUgb2YgdGhlIHNwbGl0dGVyCgltX2FTcGxpdHRlci5TZXRQb3NTaXplUGl4ZWwoIGFTcGxpdFBvcywgYVNwbGl0U2l6ZSApOwoJbV9hU3BsaXR0ZXIuU2V0RHJhZ1JlY3RQaXhlbCggX3JQbGF5Z3JvdW5kICk7CgoJLy8ganVzdCBmb3IgY29tcGxldGVuZXNzOiB0aGVyZSBpcyBubyBzcGFjZSBsZWZ0LCB3ZSBvY2N1cGllZCBpdCBhbGwgLi4uCglfclBsYXlncm91bmQuU2V0UG9zKCBfclBsYXlncm91bmQuQm90dG9tUmlnaHQoKSApOwoJX3JQbGF5Z3JvdW5kLlNldFNpemUoIFNpemUoIDAsIDAgKSApOwp9Ci8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgT1F1ZXJ5RGVzaWduVmlldzo6c2V0UmVhZE9ubHkoc2FsX0Jvb2wgX2JSZWFkT25seSkKewoJbV9wU2VsZWN0aW9uQm94LT5TZXRSZWFkT25seShfYlJlYWRPbmx5KTsKfQovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIE9RdWVyeURlc2lnblZpZXc6OmNsZWFyKCkKewoJbV9wU2VsZWN0aW9uQm94LT5DbGVhckFsbCgpOyAvLyBjbGVhciB0aGUgd2hvbGUgc2VsZWN0aW9uCgltX3BUYWJsZVZpZXctPkNsZWFyQWxsKCk7Cn0KLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBPUXVlcnlEZXNpZ25WaWV3OjpzZXRTdGF0ZW1lbnQoY29uc3QgOjpydGw6Ok9VU3RyaW5nJiAvKl9yc1N0YXRlbWVudCovKQp7Cn0KLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBPUXVlcnlEZXNpZ25WaWV3Ojpjb3B5KCkKewoJaWYoIG1fZUNoaWxkRm9jdXMgPT0gU0VMRUNUSU9OKQoJCW1fcFNlbGVjdGlvbkJveC0+Y29weSgpOwp9Ci8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnNhbF9Cb29sIE9RdWVyeURlc2lnblZpZXc6OmlzQ3V0QWxsb3dlZCgpCnsKCXNhbF9Cb29sIGJBbGxvd2VkID0gc2FsX0ZhbHNlOwoJaWYgKCBTRUxFQ1RJT04gPT0gbV9lQ2hpbGRGb2N1cyApCgkJYkFsbG93ZWQgPSBtX3BTZWxlY3Rpb25Cb3gtPmlzQ3V0QWxsb3dlZCgpOwoJcmV0dXJuIGJBbGxvd2VkOwp9Ci8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnNhbF9Cb29sIE9RdWVyeURlc2lnblZpZXc6OmlzUGFzdGVBbGxvd2VkKCkKewoJc2FsX0Jvb2wgYkFsbG93ZWQgPSBzYWxfRmFsc2U7CglpZiAoIFNFTEVDVElPTiA9PSBtX2VDaGlsZEZvY3VzICkKCQliQWxsb3dlZCA9IG1fcFNlbGVjdGlvbkJveC0+aXNQYXN0ZUFsbG93ZWQoKTsKCXJldHVybiBiQWxsb3dlZDsKfQovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpzYWxfQm9vbCBPUXVlcnlEZXNpZ25WaWV3Ojppc0NvcHlBbGxvd2VkKCkKewoJc2FsX0Jvb2wgYkFsbG93ZWQgPSBzYWxfRmFsc2U7CglpZiAoIFNFTEVDVElPTiA9PSBtX2VDaGlsZEZvY3VzICkKCQliQWxsb3dlZCA9IG1fcFNlbGVjdGlvbkJveC0+aXNDb3B5QWxsb3dlZCgpOwoJcmV0dXJuIGJBbGxvd2VkOwp9Ci8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgT1F1ZXJ5RGVzaWduVmlldzo6c3RvcFRpbWVyKCkKewoJbV9wU2VsZWN0aW9uQm94LT5zdG9wVGltZXIoKTsKfQovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIE9RdWVyeURlc2lnblZpZXc6OnN0YXJ0VGltZXIoKQp7CgltX3BTZWxlY3Rpb25Cb3gtPnN0YXJ0VGltZXIoKTsKfQovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIE9RdWVyeURlc2lnblZpZXc6OmN1dCgpCnsKCWlmKCBtX2VDaGlsZEZvY3VzID09IFNFTEVDVElPTikKCXsKCQltX3BTZWxlY3Rpb25Cb3gtPmN1dCgpOwoJCXN0YXRpY19jYXN0PE9RdWVyeUNvbnRyb2xsZXImPihnZXRDb250cm9sbGVyKCkpLnNldE1vZGlmaWVkKHNhbF9UcnVlKTsKCX0KfQovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIE9RdWVyeURlc2lnblZpZXc6OnBhc3RlKCkKewoJaWYoIG1fZUNoaWxkRm9jdXMgPT0gU0VMRUNUSU9OKQoJewoJCW1fcFNlbGVjdGlvbkJveC0+cGFzdGUoKTsKCQlzdGF0aWNfY2FzdDxPUXVlcnlDb250cm9sbGVyJj4oZ2V0Q29udHJvbGxlcigpKS5zZXRNb2RpZmllZChzYWxfVHJ1ZSk7Cgl9Cn0KLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBPUXVlcnlEZXNpZ25WaWV3OjpUYWJsZURlbGV0ZWQoY29uc3QgOjpydGw6Ok9VU3RyaW5nJiByQWxpYXNOYW1lKQp7CgkvLyBOYWNocmljaHQsIGRhc3MgVGFiZWxsZSBhdXMgZGVtIEZlbnN0ZXIgZ2VsIm9zY2h0IHd1cmRlCglEZWxldGVGaWVsZHMockFsaWFzTmFtZSk7CglzdGF0aWNfY2FzdDxPUXVlcnlDb250cm9sbGVyJj4oZ2V0Q29udHJvbGxlcigpKS5JbnZhbGlkYXRlRmVhdHVyZShJRF9CUk9XU0VSX0FERFRBQkxFKTsJLy8gdmlldyBub2NobWFsIGJlc2NoZWlkIHNhZ2VuCn0KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBPUXVlcnlEZXNpZ25WaWV3OjpEZWxldGVGaWVsZHMoIGNvbnN0IDo6cnRsOjpPVVN0cmluZyYgckFsaWFzTmFtZSApCnsKCW1fcFNlbGVjdGlvbkJveC0+RGVsZXRlRmllbGRzKCByQWxpYXNOYW1lICk7Cn0KLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KYm9vbCBPUXVlcnlEZXNpZ25WaWV3OjpIYXNGaWVsZEJ5QWxpYXNOYW1lKGNvbnN0IDo6cnRsOjpPVVN0cmluZyYgckZpZWxkTmFtZSwgT1RhYmxlRmllbGREZXNjUmVmJiBySW5mbykgIGNvbnN0CnsKICAgIHJldHVybiBtX3BTZWxlY3Rpb25Cb3gtPkhhc0ZpZWxkQnlBbGlhc05hbWUoIHJGaWVsZE5hbWUsIHJJbmZvKTsKfQovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpTcWxQYXJzZUVycm9yIE9RdWVyeURlc2lnblZpZXc6Okluc2VydEZpZWxkKCBjb25zdCBPVGFibGVGaWVsZERlc2NSZWYmIHJJbmZvLCBzYWxfQm9vbCBiVmlzLCBzYWxfQm9vbCBiQWN0aXZhdGUpCnsKCXJldHVybiBtX3BTZWxlY3Rpb25Cb3gtPkluc2VydEZpZWxkKCBySW5mbywgQlJPV1NFUl9JTlZBTElESUQsYlZpcywgYkFjdGl2YXRlICkuaXNWYWxpZCgpID8gZU9rIDogZVRvb01hbnlDb2x1bW5zOwp9Ci8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnNhbF9JbnQzMiBPUXVlcnlEZXNpZ25WaWV3OjpnZXRDb2xXaWR0aChzYWxfdUludDE2IF9uQ29sUG9zKSBjb25zdAp7CiAgICBzdGF0aWMgc2FsX0ludDMyIHNfbkRlZmF1bHRXaWR0aCA9IEdldFRleHRXaWR0aChTdHJpbmcoUlRMX0NPTlNUQVNDSUlfVVNUUklOR1BBUkFNKCIwIikpKSAqIDE1OwogICAgc2FsX0ludDMyIG5XaWR0aCA9IHN0YXRpY19jYXN0PE9RdWVyeUNvbnRyb2xsZXImPihnZXRDb250cm9sbGVyKCkpLmdldENvbFdpZHRoKF9uQ29sUG9zKTsKICAgIGlmICggIW5XaWR0aCApCiAgICAgICAgbldpZHRoID0gc19uRGVmYXVsdFdpZHRoOwoJcmV0dXJuIG5XaWR0aDsKfQovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIE9RdWVyeURlc2lnblZpZXc6OmZpbGxWYWxpZEZpZWxkcyhjb25zdCA6OnJ0bDo6T1VTdHJpbmcmIHNBbGlhc05hbWUsIENvbWJvQm94KiBwRmllbGRMaXN0KQp7CglEQkdfQVNTRVJUKHBGaWVsZExpc3QgIT0gTlVMTCwgIk9RdWVyeURlc2lnblZpZXc6OkZpbGxWYWxpZEZpZWxkcyA6IFdoYXQgdGhlIGhlbGwgZG8geW91IHRoaW5rIEkgY2FuIGRvIHdpdGggYSBOVUxMLXB0ciA/IFRoaXMgd2lsbCBjcmFzaCAhIik7CglwRmllbGRMaXN0LT5DbGVhcigpOwoKCXNhbF9Cb29sIGJBbGxUYWJsZXMgPSBzQWxpYXNOYW1lLmdldExlbmd0aCgpID09IDA7CgoJT0pvaW5UYWJsZVZpZXc6Ok9UYWJsZVdpbmRvd01hcCogcFRhYldpbnMgPSBtX3BUYWJsZVZpZXctPkdldFRhYldpbk1hcCgpOwoJOjpydGw6Ok9VU3RyaW5nIHN0ckN1cnJlbnRQcmVmaXg7Cgk6OnN0ZDo6dmVjdG9yPCA6OnJ0bDo6T1VTdHJpbmc+IGFGaWVsZHM7CglPSm9pblRhYmxlVmlldzo6T1RhYmxlV2luZG93TWFwOjppdGVyYXRvciBhSXRlciA9IHBUYWJXaW5zLT5iZWdpbigpOwogICAgT0pvaW5UYWJsZVZpZXc6Ok9UYWJsZVdpbmRvd01hcDo6aXRlcmF0b3IgYUVuZCAgPSBwVGFiV2lucy0+ZW5kKCk7CiAgICBmb3IoO2FJdGVyICE9IGFFbmQ7KythSXRlcikKCXsKCQlPUXVlcnlUYWJsZVdpbmRvdyogcEN1cnJlbnRXaW4gPSBzdGF0aWNfY2FzdDxPUXVlcnlUYWJsZVdpbmRvdyo+KGFJdGVyLT5zZWNvbmQpOwoJCWlmIChiQWxsVGFibGVzIHx8IChwQ3VycmVudFdpbi0+R2V0QWxpYXNOYW1lKCkgPT0gc0FsaWFzTmFtZSkpCgkJewoJCQlzdHJDdXJyZW50UHJlZml4ID0gcEN1cnJlbnRXaW4tPkdldEFsaWFzTmFtZSgpOwoJCQlzdHJDdXJyZW50UHJlZml4ICs9IDo6cnRsOjpPVVN0cmluZygnLicpOwoKCQkJcEN1cnJlbnRXaW4tPkVudW1WYWxpZEZpZWxkcyhhRmllbGRzKTsKCgkJCTo6c3RkOjp2ZWN0b3I8IDo6cnRsOjpPVVN0cmluZz46Oml0ZXJhdG9yIGFTdHJJdGVyID0gYUZpZWxkcy5iZWdpbigpOwogICAgICAgICAgICA6OnN0ZDo6dmVjdG9yPCA6OnJ0bDo6T1VTdHJpbmc+OjppdGVyYXRvciBhU3RyRW5kID0gYUZpZWxkcy5lbmQoKTsKCQkJZm9yKDthU3RySXRlciAhPSBhU3RyRW5kOysrYVN0ckl0ZXIpCgkJCXsKCQkJCWlmIChiQWxsVGFibGVzIHx8IGFTdHJJdGVyLT50b0NoYXIoKSA9PSAnKicpCgkJCQkJcEZpZWxkTGlzdC0+SW5zZXJ0RW50cnkoOjpydGw6Ok9VU3RyaW5nKHN0ckN1cnJlbnRQcmVmaXgpICs9ICphU3RySXRlcik7CgkJCQllbHNlCgkJCQkJcEZpZWxkTGlzdC0+SW5zZXJ0RW50cnkoKmFTdHJJdGVyKTsKCQkJfQoKCQkJaWYgKCFiQWxsVGFibGVzKQoJCQkJLy8gZGFzIGhlaXNzdCwgZGFzcyBpY2ggaW4gZGllc2VuIEJsb2NrIGthbSwgd2VpbCBkZXIgVGFiZWxsZW5uYW1lIGdlbmF1IGRlciBnZXN1Y2h0ZSB3YXIsIGFsc28gYmluIGljaCBmZXJ0aWcKCQkJCS8vIChkYWR1cmNoIHZlcmhpbmRlcmUgaWNoIGF1Y2ggZGFzIGRvcHBlbHRlIEVpbmZ1ZWdlbiB2b24gRmVsZGVybiwgd2VubiBlaW5lIFRhYmVsbGUgbWVocm1hbHMgYWxzIFRhYldpbiB2b3Jrb21tdCkKCQkJCWJyZWFrOwoJCX0KCX0KfQovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpsb25nIE9RdWVyeURlc2lnblZpZXc6OlByZU5vdGlmeShOb3RpZnlFdmVudCYgck5FdnQpCnsKCXN3aXRjaCAock5FdnQuR2V0VHlwZSgpKQoJewoJCWNhc2UgRVZFTlRfR0VURk9DVVM6CiNpZiBPU0xfREVCVUdfTEVWRUwgPiAwCgkJCXsKCQkJCVdpbmRvdyogcEZvY3VzID0gQXBwbGljYXRpb246OkdldEZvY3VzV2luZG93KCk7CiAgICAgICAgICAgICAgICAodm9pZClwRm9jdXM7CgkJCX0KI2VuZGlmCgoJCQlpZiAoIG1fcFNlbGVjdGlvbkJveCAmJiBtX3BTZWxlY3Rpb25Cb3gtPkhhc0NoaWxkUGF0aEZvY3VzKCkgKQoJCQkJbV9lQ2hpbGRGb2N1cyA9IFNFTEVDVElPTjsKCQkJZWxzZQoJCQkJbV9lQ2hpbGRGb2N1cyA9IFRBQkxFVklFVzsKCQkJYnJlYWs7Cgl9CgoJcmV0dXJuIE9RdWVyeVZpZXc6OlByZU5vdGlmeShyTkV2dCk7Cn0KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQovLyBjaGVjayBpZiB0aGUgc3RhdGVtZW50IGlzIGNvcnJlY3Qgd2hlbiBub3QgcmV0dXJuaW5nIGZhbHNlCnNhbF9Cb29sIE9RdWVyeURlc2lnblZpZXc6OmNoZWNrU3RhdGVtZW50KCkKewoJc2FsX0Jvb2wgYlJldCA9IHNhbF9UcnVlOwoJaWYgKCBtX3BTZWxlY3Rpb25Cb3ggKQoJCWJSZXQgPSBtX3BTZWxlY3Rpb25Cb3gtPlNhdmUoKTsgLy8gYSBlcnJvciBvY2N1cmVkIHNvIHdlIHJldHVybiBubwoJcmV0dXJuIGJSZXQ7Cn0KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCjo6cnRsOjpPVVN0cmluZyBPUXVlcnlEZXNpZ25WaWV3OjpnZXRTdGF0ZW1lbnQoKQp7CglPUXVlcnlDb250cm9sbGVyJiByQ29udHJvbGxlciA9IHN0YXRpY19jYXN0PE9RdWVyeUNvbnRyb2xsZXImPihnZXRDb250cm9sbGVyKCkpOwoJbV9yQ29udHJvbGxlci5jbGVhckVycm9yKCk7CgkvLyB1c2VkIGZvciBmaWVsZHMgd2hpY2ggYXJlbid0IGFueSBsb25nZXIgaW4gdGhlIHN0YXRlbWVudAoJT1RhYmxlRmllbGRzJiByVW5Vc2VkRmllbGRzID0gckNvbnRyb2xsZXIuZ2V0VW5Vc2VkRmllbGRzKCk7CglPVGFibGVGaWVsZHMoKS5zd2FwKCByVW5Vc2VkRmllbGRzICk7CgoJLy8gY3JlYXRlIHRoZSBzZWxlY3QgY29sdW1ucwoJc2FsX3VJbnQzMiBuRmllbGRjb3VudCA9IDA7CglPVGFibGVGaWVsZHMmIHJGaWVsZExpc3QgPSByQ29udHJvbGxlci5nZXRUYWJsZUZpZWxkRGVzYygpOwoJT1RhYmxlRmllbGRzOjppdGVyYXRvciBhSXRlciA9IHJGaWVsZExpc3QuYmVnaW4oKTsKICAgIE9UYWJsZUZpZWxkczo6aXRlcmF0b3IgYUVuZCA9IHJGaWVsZExpc3QuZW5kKCk7Cglmb3IoO2FJdGVyICE9IGFFbmQ7KythSXRlcikKCXsKCQlPVGFibGVGaWVsZERlc2NSZWYgcEVudHJ5RmllbGQgPSAqYUl0ZXI7CgkJaWYgKCBwRW50cnlGaWVsZC0+R2V0RmllbGQoKS5nZXRMZW5ndGgoKSAmJiBwRW50cnlGaWVsZC0+SXNWaXNpYmxlKCkgKQoJCQkrK25GaWVsZGNvdW50OwoJCWVsc2UgaWYgKHBFbnRyeUZpZWxkLT5HZXRGaWVsZCgpLmdldExlbmd0aCgpCQkJJiYKCQkJCSFwRW50cnlGaWVsZC0+SGFzQ3JpdGVyaWEoKQkJCQkJJiYKCQkJCXBFbnRyeUZpZWxkLT5pc05vbmVGdW5jdGlvbigpCQkJCSYmCgkJCQlwRW50cnlGaWVsZC0+R2V0T3JkZXJEaXIoKSA9PSBPUkRFUl9OT05FCSYmCiAgICAgICAgICAgICAgICAhcEVudHJ5RmllbGQtPklzR3JvdXBCeSgpICAgICAgICAgICAgICAgICAgICYmCgkJCQkhcEVudHJ5RmllbGQtPkdldEZ1bmN0aW9uKCkuZ2V0TGVuZ3RoKCkgKQoJCQlyVW5Vc2VkRmllbGRzLnB1c2hfYmFjayhwRW50cnlGaWVsZCk7Cgl9CglpZiAoICFuRmllbGRjb3VudCApCS8vIGtlaW5lIEZlbGRlciBzaWNodGJhciBhbHNvIHp1ciJ1Y2sKCXsKCQlyVW5Vc2VkRmllbGRzID0gckZpZWxkTGlzdDsKCQlyZXR1cm4gOjpydGw6Ok9VU3RyaW5nKCk7Cgl9CgoJT1F1ZXJ5VGFibGVWaWV3OjpPVGFibGVXaW5kb3dNYXAqIHBUYWJMaXN0ICAgPSBtX3BUYWJsZVZpZXctPkdldFRhYldpbk1hcCgpOwoJc2FsX3VJbnQzMiBuVGFiY291bnQJCT0gcFRhYkxpc3QtPnNpemUoKTsKCgk6OnJ0bDo6T1VTdHJpbmcJYUZpZWxkTGlzdFN0cihHZW5lcmF0ZVNlbGVjdExpc3QodGhpcyxyRmllbGRMaXN0LG5UYWJjb3VudD4xKSk7CglpZiggIWFGaWVsZExpc3RTdHIuZ2V0TGVuZ3RoKCkgKQoJCXJldHVybiA6OnJ0bDo6T1VTdHJpbmcoKTsKCS8vIEF1c25haG1lYmVoYW5kbHVuZywgd2VubiBrZWluZSBGZWxkZXIgYW5nZWdlYmVuIHdvcmRlbiBzaW5kCgkvLyBEYW5uIGRhcmYgZGllIFRhYnBhZ2UgbmljaHQgZ2V3ZWNoc2VsdCB3ZXJkZW4KCS8vIEltIFRhYkJhclNlbGVjdEhkbCB3aXJkIGRlciBTUUwtOjpydGw6Ok9VU3RyaW5nIGF1ZiBTVEFURU1FTlRfTk9GSUVMRFMgYWJnZWZyYWd0CgkvLyB1bmQgZWluZSBFcnJvcm1lbGR1bmcgZXJ6ZXVndAoJLy8gLS0tLS0tLS0tLS0tLS0tLS0gVGFiZWxsZW5saXN0ZSBhdWZiYXVlbiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgoJY29uc3QgOjpzdGQ6OnZlY3RvcjxPVGFibGVDb25uZWN0aW9uKj4qCXBDb25uTGlzdCA9IG1fcFRhYmxlVmlldy0+Z2V0VGFibGVDb25uZWN0aW9ucygpOwoJUmVmZXJlbmNlPCBYQ29ubmVjdGlvbj4geENvbm5lY3Rpb24gPSByQ29udHJvbGxlci5nZXRDb25uZWN0aW9uKCk7Cgk6OnJ0bDo6T1VTdHJpbmcgYVRhYmxlTGlzdFN0cihHZW5lcmF0ZUZyb21DbGF1c2UoeENvbm5lY3Rpb24scFRhYkxpc3QscENvbm5MaXN0KSk7CglEQkdfQVNTRVJUKGFUYWJsZUxpc3RTdHIuZ2V0TGVuZ3RoKCksICJPUXVlcnlEZXNpZ25WaWV3OjpnZXRTdGF0ZW1lbnQoKSA6IHVuZXJ3YXJ0ZXQgOiBoYWJlIEZlbGRlciwgYWJlciBrZWluZSBUYWJlbGxlbiAhIik7CgkvLyB3ZW5uIGVzIEZlbGRlciBnaWJ0LCBrb2VubmVuIGRpZSBudXIgZHVyY2ggRWluZnVlZ2VuIGF1cyBlaW5lciBzY2hvbiBleGlzdGVudGVuIFRhYmVsbGUgZW50c3RhbmRlbiBzZWluOyB3ZW5uIGFuZGVyZXJzZWl0cwoJLy8gZWluZSBUYWJlbGxlIGdlbG9lc2NodCB3aXJkLCB2ZXJzY2h3aW5kZW4gYXVjaCBkaWUgenVnZWhvZXJpZ2VuIEZlbGRlciAtPiBlcmdvIEtBTk4gZXMgZGFzIG5pY2h0IGdlYmVuLCBkYXNzIEZlbGRlcgoJLy8gZXhpc3RpZXJlbiwgYWJlciBrZWluZSBUYWJlbGxlbiAodW5kIGFGaWVsZExpc3RTdHIgaGF0IHNjaG9uIGVpbmUgTGFlbmdlLCBkYXMgc3RlbGxlIGljaCBvYmVuIHNpY2hlcikKCTo6cnRsOjpPVVN0cmluZ0J1ZmZlciBhSGF2aW5nU3RyLGFDcml0ZXJpYUxpc3RTdHI7CgkvLyAtLS0tLS0tLS0tLS0tLS0tLSBLcml0ZXJpZW4gYXVmYmF1ZW4gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoJaWYgKCFHZW5lcmF0ZUNyaXRlcmlhcyh0aGlzLGFDcml0ZXJpYUxpc3RTdHIsYUhhdmluZ1N0cixyRmllbGRMaXN0LCBuVGFiY291bnQgPiAxKSkKCQlyZXR1cm4gOjpydGw6Ok9VU3RyaW5nKCk7CgoJOjpydGw6Ok9VU3RyaW5nIGFKb2luQ3JpdDsKCUdlbmVyYXRlSW5uZXJKb2luQ3JpdGVyaWFzKHhDb25uZWN0aW9uLGFKb2luQ3JpdCxwQ29ubkxpc3QpOwoJaWYoYUpvaW5Dcml0LmdldExlbmd0aCgpKQoJewoJCTo6cnRsOjpPVVN0cmluZyBhVG1wID0gOjpydGw6Ok9VU3RyaW5nOjpjcmVhdGVGcm9tQXNjaWkoIiggIik7CgkJYVRtcCArPSBhSm9pbkNyaXQ7CgkJYVRtcCArPSA6OnJ0bDo6T1VTdHJpbmc6OmNyZWF0ZUZyb21Bc2NpaSgiICkiKTsKCQlpZihhQ3JpdGVyaWFMaXN0U3RyLmdldExlbmd0aCgpKQoJCXsKCQkJYVRtcCArPSBDX0FORDsKCQkJYVRtcCArPSBhQ3JpdGVyaWFMaXN0U3RyLm1ha2VTdHJpbmdBbmRDbGVhcigpOwoJCX0KCQlhQ3JpdGVyaWFMaXN0U3RyID0gYVRtcDsKCX0KCS8vIC0tLS0tLS0tLS0tLS0tLS0tIFN0YXRlbWVudCBhdWZiYXVlbiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgk6OnJ0bDo6T1VTdHJpbmdCdWZmZXIgYVNxbENtZCg6OnJ0bDo6T1VTdHJpbmc6OmNyZWF0ZUZyb21Bc2NpaSgiU0VMRUNUICIpKTsKCWlmKHN0YXRpY19jYXN0PE9RdWVyeUNvbnRyb2xsZXImPihnZXRDb250cm9sbGVyKCkpLmlzRGlzdGluY3QoKSkKCQlhU3FsQ21kLmFwcGVuZCg6OnJ0bDo6T1VTdHJpbmc6OmNyZWF0ZUZyb21Bc2NpaSgiIERJU1RJTkNUICIpKTsKCWFTcWxDbWQuYXBwZW5kKGFGaWVsZExpc3RTdHIpOwoJYVNxbENtZC5hcHBlbmQoOjpydGw6Ok9VU3RyaW5nOjpjcmVhdGVGcm9tQXNjaWkoIiBGUk9NICIpKTsKCWFTcWxDbWQuYXBwZW5kKGFUYWJsZUxpc3RTdHIpOwoKCWlmIChhQ3JpdGVyaWFMaXN0U3RyLmdldExlbmd0aCgpKQoJewoJCWFTcWxDbWQuYXBwZW5kKDo6cnRsOjpPVVN0cmluZzo6Y3JlYXRlRnJvbUFzY2lpKCIgV0hFUkUgIikpOwoJCWFTcWxDbWQuYXBwZW5kKGFDcml0ZXJpYUxpc3RTdHIubWFrZVN0cmluZ0FuZENsZWFyKCkpOwoJfQoJLy8gLS0tLS0tLS0tLS0tLS0tLS0gR3JvdXBCeSBhdWZiYXVlbiB1bmQgQW5oImFuZ2VuIC0tLS0tLS0tLS0tLQoJUmVmZXJlbmNlPFhEYXRhYmFzZU1ldGFEYXRhPiB4TWV0YTsKCWlmICggeENvbm5lY3Rpb24uaXMoKSApCgkJeE1ldGEgPSB4Q29ubmVjdGlvbi0+Z2V0TWV0YURhdGEoKTsKCXNhbF9Cb29sIGJVc2VBbGlhcyA9IG5UYWJjb3VudCA+IDE7CglpZiAoIHhNZXRhLmlzKCkgKQoJCWJVc2VBbGlhcyA9IGJVc2VBbGlhcyB8fCAheE1ldGEtPnN1cHBvcnRzR3JvdXBCeVVucmVsYXRlZCgpOwoKCWFTcWxDbWQuYXBwZW5kKEdlbmVyYXRlR3JvdXBCeSh0aGlzLHJGaWVsZExpc3QsYlVzZUFsaWFzKSk7CgkvLyAtLS0tLS0tLS0tLS0tLS0tLSBoYXZpbmcgQW5oImFuZ2VuIC0tLS0tLS0tLS0tLQoJaWYoYUhhdmluZ1N0ci5nZXRMZW5ndGgoKSkKCXsKCQlhU3FsQ21kLmFwcGVuZCg6OnJ0bDo6T1VTdHJpbmc6OmNyZWF0ZUZyb21Bc2NpaSgiIEhBVklORyAiKSk7CgkJYVNxbENtZC5hcHBlbmQoYUhhdmluZ1N0ci5tYWtlU3RyaW5nQW5kQ2xlYXIoKSk7Cgl9CgkvLyAtLS0tLS0tLS0tLS0tLS0tLSBTb3J0aWVydW5nIGF1ZmJhdWVuIHVuZCBBbmgiYW5nZW4gLS0tLS0tLS0tLS0tCgk6OnJ0bDo6T1VTdHJpbmcgc09yZGVyOwoJU3FsUGFyc2VFcnJvciBlRXJyb3JDb2RlID0gZU9rOwoJaWYgKCAoZUVycm9yQ29kZSA9IEdlbmVyYXRlT3JkZXIodGhpcyxyRmllbGRMaXN0LG5UYWJjb3VudCA+IDEsc09yZGVyKSkgPT0gZU9rKQoJCWFTcWxDbWQuYXBwZW5kKHNPcmRlcik7CgllbHNlCgl7CgkJaWYgKCAhbV9yQ29udHJvbGxlci5oYXNFcnJvcigpICkKICAgICAgICAgICAgbV9yQ29udHJvbGxlci5hcHBlbmRFcnJvciggZ2V0UGFyc2VFcnJvck1lc3NhZ2UoIGVFcnJvckNvZGUgKSApOwoKICAgICAgICBtX3JDb250cm9sbGVyLmRpc3BsYXlFcnJvcigpOwoJfQoKICAgIDo6cnRsOjpPVVN0cmluZyBzU1FMID0gYVNxbENtZC5tYWtlU3RyaW5nQW5kQ2xlYXIoKTsKICAgIGlmICggeENvbm5lY3Rpb24uaXMoKSApCiAgICB7CiAgICAgICAgOjpjb25uZWN0aXZpdHk6Ok9TUUxQYXJzZXImIHJQYXJzZXIoIHJDb250cm9sbGVyLmdldFBhcnNlcigpICk7CiAgICAgICAgOjpydGw6Ok9VU3RyaW5nIHNFcnJvck1lc3NhZ2U7CiAgICAgICAgOjpzdGQ6OmF1dG9fcHRyPE9TUUxQYXJzZU5vZGU+IHBQYXJzZU5vZGUoIHJQYXJzZXIucGFyc2VUcmVlKCBzRXJyb3JNZXNzYWdlLCBzU1FMLCBzYWxfVHJ1ZSApICk7CiAgICAgICAgaWYgKCBwUGFyc2VOb2RlLmdldCgpICkKICAgICAgICB7CiAgICAgICAgICAgIE9TUUxQYXJzZU5vZGUqIHBOb2RlID0gcFBhcnNlTm9kZS0+Z2V0Q2hpbGQoMyktPmdldENoaWxkKDEpOwogICAgICAgICAgICBpZiAoIHBOb2RlLT5jb3VudCgpID4gMSApCiAgICAgICAgICAgIHsKCQkgICAgICAgIDo6Y29ubmVjdGl2aXR5OjpPU1FMUGFyc2VOb2RlICogcENvbmRpdGlvbiA9IHBOb2RlLT5nZXRDaGlsZCgxKTsKCQkgICAgICAgIGlmICggcENvbmRpdGlvbiApIC8vIG5vIHdoZXJlIGNsYXVzZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIE9TUUxQYXJzZU5vZGU6OmNvbXByZXNzKHBDb25kaXRpb24pOwogICAgICAgICAgICAgICAgICAgIDo6cnRsOjpPVVN0cmluZyBzVGVtcDsKICAgICAgICAgICAgICAgICAgICBwUGFyc2VOb2RlLT5wYXJzZU5vZGVUb1N0cihzVGVtcCx4Q29ubmVjdGlvbik7CiAgICAgICAgICAgICAgICAgICAgc1NRTCA9IHNUZW1wOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoJcmV0dXJuIHNTUUw7Cn0KLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBPUXVlcnlEZXNpZ25WaWV3OjpzZXRTbG90RW5hYmxlZChzYWxfSW50MzIgX25TbG90SWQsc2FsX0Jvb2wgX2JFbmFibGUpCnsKCXNhbF91SW50MTYgblJvdzsKCXN3aXRjaCAoX25TbG90SWQpCgl7CgkJY2FzZSBTSURfUVVFUllfVklFV19GVU5DVElPTlM6CgkJCW5Sb3cgPSBCUk9XX0ZVTkNUSU9OX1JPVzsKCQkJYnJlYWs7CgkJY2FzZSBTSURfUVVFUllfVklFV19UQUJMRVM6CgkJCW5Sb3cgPSBCUk9XX1RBQkxFX1JPVzsKCQkJYnJlYWs7CgkJY2FzZSBTSURfUVVFUllfVklFV19BTElBU0VTOgoJCQluUm93ID0gQlJPV19DT0xVTU5BTElBU19ST1c7CgkJCWJyZWFrOwoJCWRlZmF1bHQ6CgkJCS8vID8/Pz8/Pz8/Pz8/PwoJCQluUm93ID0gMDsKCQkJYnJlYWs7Cgl9CgltX3BTZWxlY3Rpb25Cb3gtPlNldFJvd1Zpc2libGUoblJvdyxfYkVuYWJsZSk7CgltX3BTZWxlY3Rpb25Cb3gtPkludmFsaWRhdGUoKTsKfQovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpzYWxfQm9vbCBPUXVlcnlEZXNpZ25WaWV3Ojppc1Nsb3RFbmFibGVkKHNhbF9JbnQzMiBfblNsb3RJZCkKewoJc2FsX3VJbnQxNiBuUm93OwoJc3dpdGNoIChfblNsb3RJZCkKCXsKCQljYXNlIFNJRF9RVUVSWV9WSUVXX0ZVTkNUSU9OUzoKCQkJblJvdyA9IEJST1dfRlVOQ1RJT05fUk9XOwoJCQlicmVhazsKCQljYXNlIFNJRF9RVUVSWV9WSUVXX1RBQkxFUzoKCQkJblJvdyA9IEJST1dfVEFCTEVfUk9XOwoJCQlicmVhazsKCQljYXNlIFNJRF9RVUVSWV9WSUVXX0FMSUFTRVM6CgkJCW5Sb3cgPSBCUk9XX0NPTFVNTkFMSUFTX1JPVzsKCQkJYnJlYWs7CgkJZGVmYXVsdDoKCQkJLy8gPz8/Pz8/Pz8/CgkJCW5Sb3cgPSAwOwoJCQlicmVhazsKCX0KCXJldHVybiBtX3BTZWxlY3Rpb25Cb3gtPklzUm93VmlzaWJsZShuUm93KTsKfQovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIE9RdWVyeURlc2lnblZpZXc6OlNhdmVVSUNvbmZpZygpCnsKCU9RdWVyeUNvbnRyb2xsZXImIHJDdHJsID0gc3RhdGljX2Nhc3Q8T1F1ZXJ5Q29udHJvbGxlciY+KGdldENvbnRyb2xsZXIoKSk7CglyQ3RybC5TYXZlVGFiV2luc1Bvc1NpemUoIG1fcFRhYmxlVmlldy0+R2V0VGFiV2luTWFwKCksIG1fcFNjcm9sbFdpbmRvdy0+R2V0SFNjcm9sbEJhcigpLT5HZXRUaHVtYlBvcygpLCBtX3BTY3JvbGxXaW5kb3ctPkdldFZTY3JvbGxCYXIoKS0+R2V0VGh1bWJQb3MoKSApOwoJLy8JckN0cmwuU2F2ZVRhYkZpZWxkc1dpZHRoKCBtX3BTZWxlY3Rpb25Cb3ggKTsKCXJDdHJsLnNldFZpc2libGVSb3dzKCBtX3BTZWxlY3Rpb25Cb3gtPkdldE5vbmVWaXNpYmxlUm93cygpICk7CiAgICBpZiAoIG1fYVNwbGl0dGVyLkdldFNwbGl0UG9zUGl4ZWwoKSAhPSAwICkKCSAgICByQ3RybC5zZXRTcGxpdFBvcyggbV9hU3BsaXR0ZXIuR2V0U3BsaXRQb3NQaXhlbCgpICk7Cn0KLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KT1NRTFBhcnNlTm9kZSogT1F1ZXJ5RGVzaWduVmlldzo6Z2V0UHJlZGljYXRlVHJlZUZyb21FbnRyeShPVGFibGVGaWVsZERlc2NSZWYgcEVudHJ5LAoJCQkJCQkJCQkJCQkJCSAgIGNvbnN0IFN0cmluZyYgX3NDcml0ZXJpYSwKCQkJCQkJCQkJCQkJCQkgICA6OnJ0bDo6T1VTdHJpbmcmIF9yc0Vycm9yTWVzc2FnZSwKCQkJCQkJCQkJCQkJCQkgICBSZWZlcmVuY2U8WFByb3BlcnR5U2V0PiYgX3J4Q29sdW1uKSBjb25zdAp7CglPU0xfRU5TVVJFKHBFbnRyeS5pc1ZhbGlkKCksIkVudHJ5IGlzIG51bGwhIik7CglpZighcEVudHJ5LmlzVmFsaWQoKSkKCQlyZXR1cm4gTlVMTDsKCVJlZmVyZW5jZTwgWENvbm5lY3Rpb24+IHhDb25uZWN0aW9uID0gc3RhdGljX2Nhc3Q8T1F1ZXJ5Q29udHJvbGxlciY+KGdldENvbnRyb2xsZXIoKSkuZ2V0Q29ubmVjdGlvbigpOwoJaWYoIXhDb25uZWN0aW9uLmlzKCkpCgkJcmV0dXJuIE5VTEw7CgoJOjpjb25uZWN0aXZpdHk6Ok9TUUxQYXJzZXImIHJQYXJzZXIoIHN0YXRpY19jYXN0PE9RdWVyeUNvbnRyb2xsZXImPihnZXRDb250cm9sbGVyKCkpLmdldFBhcnNlcigpICk7CglPUXVlcnlUYWJsZVdpbmRvdyogcFdpbiA9IHN0YXRpY19jYXN0PE9RdWVyeVRhYmxlV2luZG93Kj4ocEVudHJ5LT5HZXRUYWJXaW5kb3coKSk7CgoJU3RyaW5nIHNUZXN0KF9zQ3JpdGVyaWEpOwoJLy8gc3BlY2lhbCBoYW5kbGluZyBmb3IgZnVuY3Rpb25zCglpZiAoIHBFbnRyeS0+R2V0RnVuY3Rpb25UeXBlKCkgJiAoRktUX09USEVSIHwgRktUX0FHR1JFR0FURSB8IEZLVF9OVU1FUklDKSApCgl7CgkJLy8gd2UgaGF2ZSBhIGZ1bmN0aW9uIGhlcmUgc28gd2UgaGF2ZSB0byBkaXN0aW5ndWlzaCB0aGUgdHlwZSBvZiByZXR1cm4gdmFsdWUKCQlTdHJpbmcgc0Z1bmN0aW9uOwoJCWlmICggcEVudHJ5LT5pc051bWVyaWNPckFnZ3JlYXRlRnVuY3Rpb24oKSApCgkJCXNGdW5jdGlvbiA9IHBFbnRyeS0+R2V0RnVuY3Rpb24oKTsKCiAgICAgICAgaWYgKCAhc0Z1bmN0aW9uLkxlbigpICkKCQkJc0Z1bmN0aW9uID0gcEVudHJ5LT5HZXRGaWVsZCgpOwoKCQlpZihzRnVuY3Rpb24uR2V0VG9rZW5Db3VudCgnKCcpID4gMSkKCQkJc0Z1bmN0aW9uID0gc0Z1bmN0aW9uLkdldFRva2VuKDAsJygnKTsgLy8gdGhpcyBzaG91bGQgYmUgdGhlIG5hbWUgb2YgdGhlIGZ1bmN0aW9uCgoJCXNhbF9JbnQzMiBuVHlwZSA9IDo6Y29ubmVjdGl2aXR5OjpPU1FMUGFyc2VyOjpnZXRGdW5jdGlvblJldHVyblR5cGUoc0Z1bmN0aW9uLCZyUGFyc2VyLmdldENvbnRleHQoKSk7CgkJaWYgKCBuVHlwZSA9PSBEYXRhVHlwZTo6T1RIRVIgfHwgKCFzRnVuY3Rpb24uTGVuKCkgJiYgcEVudHJ5LT5pc051bWVyaWNPckFnZ3JlYXRlRnVuY3Rpb24oKSkgKQoJCXsKCQkJLy8gZmlyc3QgdHJ5IHRoZSBpbnRlcm5hdGlvbmFsIHZlcnNpb24KCQkJOjpydGw6Ok9VU3RyaW5nIHNTcWw7CgkJCXNTcWwgKz0gOjpydGw6Ok9VU3RyaW5nKFJUTF9DT05TVEFTQ0lJX1VTVFJJTkdQQVJBTSgiU0VMRUNUICogIikpOwoJCQlzU3FsICs9IDo6cnRsOjpPVVN0cmluZyhSVExfQ09OU1RBU0NJSV9VU1RSSU5HUEFSQU0oIiBGUk9NIHggV0hFUkUgIikpOwoJCQlzU3FsICs9IHBFbnRyeS0+R2V0RmllbGQoKTsKCQkJc1NxbCArPSBfc0NyaXRlcmlhOwogICAgICAgICAgICA6OnN0ZDo6YXV0b19wdHI8T1NRTFBhcnNlTm9kZT4gcFBhcnNlTm9kZSggclBhcnNlci5wYXJzZVRyZWUoIF9yc0Vycm9yTWVzc2FnZSwgc1NxbCwgc2FsX1RydWUgKSApOwoJCQluVHlwZSA9IERhdGFUeXBlOjpET1VCTEU7CgkJCWlmICggcFBhcnNlTm9kZS5nZXQoKSApCgkJCXsKCQkJCU9TUUxQYXJzZU5vZGUqIHBDb2x1bW5SZWYgPSBwUGFyc2VOb2RlLT5nZXRCeVJ1bGUoT1NRTFBhcnNlTm9kZTo6Y29sdW1uX3JlZik7CgkJCQlpZiAoIHBDb2x1bW5SZWYgKQoJCQkJewoJCQkJCU9UYWJsZUZpZWxkRGVzY1JlZiBhRmllbGQgPSBuZXcgT1RhYmxlRmllbGREZXNjKCk7CgkJCQkJaWYgKCBlT2sgPT0gRmlsbERyYWdJbmZvKHRoaXMscENvbHVtblJlZixhRmllbGQpICkKCQkJCQl7CgkJCQkJCW5UeXBlID0gYUZpZWxkLT5HZXREYXRhVHlwZSgpOwoJCQkJCX0KCQkJCX0KCQkJfQoJCX0KCgkJUmVmZXJlbmNlPFhEYXRhYmFzZU1ldGFEYXRhPiB4TWV0YSA9IHhDb25uZWN0aW9uLT5nZXRNZXRhRGF0YSgpOwoJCXBhcnNlOjpPUGFyc2VDb2x1bW4qIHBDb2x1bW4gPSBuZXcgcGFyc2U6Ok9QYXJzZUNvbHVtbigJcEVudHJ5LT5HZXRGaWVsZCgpLAoJCQkJCQkJCQkJCQkJCQkJOjpydGw6Ok9VU3RyaW5nKCksCgkJCQkJCQkJCQkJCQkJCQk6OnJ0bDo6T1VTdHJpbmcoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDo6cnRsOjpPVVN0cmluZygpLAoJCQkJCQkJCQkJCQkJCQkJQ29sdW1uVmFsdWU6Ok5VTExBQkxFX1VOS05PV04sCgkJCQkJCQkJCQkJCQkJCQkwLAoJCQkJCQkJCQkJCQkJCQkJMCwKCQkJCQkJCQkJCQkJCQkJCW5UeXBlLAoJCQkJCQkJCQkJCQkJCQkJc2FsX0ZhbHNlLAoJCQkJCQkJCQkJCQkJCQkJc2FsX0ZhbHNlLAoJCQkJCQkJCQkJCQkJCQkJeE1ldGEuaXMoKSAmJiB4TWV0YS0+c3VwcG9ydHNNaXhlZENhc2VRdW90ZWRJZGVudGlmaWVycygpKTsKCQlfcnhDb2x1bW4gPSBwQ29sdW1uOwoJCXBDb2x1bW4tPnNldEZ1bmN0aW9uKHNhbF9UcnVlKTsKCQlwQ29sdW1uLT5zZXRSZWFsTmFtZShwRW50cnktPkdldEZpZWxkKCkpOwoJfQoJZWxzZQoJewoJCWlmIChwV2luKQoJCXsKCQkJUmVmZXJlbmNlPFhOYW1lQWNjZXNzPiB4Q29sdW1ucyA9IHBXaW4tPkdldE9yaWdpbmFsQ29sdW1ucygpOwoJCQlpZiAoeENvbHVtbnMuaXMoKSAmJiB4Q29sdW1ucy0+aGFzQnlOYW1lKHBFbnRyeS0+R2V0RmllbGQoKSkpCgkJCQl4Q29sdW1ucy0+Z2V0QnlOYW1lKHBFbnRyeS0+R2V0RmllbGQoKSkgPj49IF9yeENvbHVtbjsKCQl9Cgl9CgoJT1NRTFBhcnNlTm9kZSogcFBhcnNlTm9kZSA9IHJQYXJzZXIucHJlZGljYXRlVHJlZSgJX3JzRXJyb3JNZXNzYWdlLAoJCQkJCQkJCQkJCQkJCXNUZXN0LAoJCQkJCQkJCQkJCQkJCXN0YXRpY19jYXN0PE9RdWVyeUNvbnRyb2xsZXImPihnZXRDb250cm9sbGVyKCkpLmdldE51bWJlckZvcm1hdHRlcigpLAoJCQkJCQkJCQkJCQkJCV9yeENvbHVtbik7CglyZXR1cm4gcFBhcnNlTm9kZTsKfQovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIE9RdWVyeURlc2lnblZpZXc6OkdldEZvY3VzKCkKewoJT1F1ZXJ5Vmlldzo6R2V0Rm9jdXMoKTsKCWlmICggbV9wU2VsZWN0aW9uQm94ICYmICFtX3BTZWxlY3Rpb25Cb3gtPkhhc0NoaWxkUGF0aEZvY3VzKCkgKQoJewoJCS8vIGZpcnN0IHdlIGhhdmUgdG8gZGVhY3RpdmF0ZSB0aGUgY3VycmVudCBjZWxsIHRvIHJlZmlsbCB3aGVuIG5lc2Nlc3NhcnkKCQltX3BTZWxlY3Rpb25Cb3gtPkRlYWN0aXZhdGVDZWxsKCk7CgkJbV9wU2VsZWN0aW9uQm94LT5BY3RpdmF0ZUNlbGwobV9wU2VsZWN0aW9uQm94LT5HZXRDdXJSb3coKSwgbV9wU2VsZWN0aW9uQm94LT5HZXRDdXJDb2x1bW5JZCgpKTsKCQltX3BTZWxlY3Rpb25Cb3gtPkdyYWJGb2N1cygpOwoJfQp9Ci8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgT1F1ZXJ5RGVzaWduVmlldzo6cmVzZXQoKQp7CgltX3BUYWJsZVZpZXctPkNsZWFyQWxsKCk7CgltX3BUYWJsZVZpZXctPlJlU3luYygpOwp9Ci8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgT1F1ZXJ5RGVzaWduVmlldzo6c2V0Tm9uZVZpc2JsZVJvdyhzYWxfSW50MzIgX25Sb3dzKQp7CgltX3BTZWxlY3Rpb25Cb3gtPlNldE5vbmVWaXNibGVSb3coX25Sb3dzKTsKfQoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBPUXVlcnlEZXNpZ25WaWV3Ojppbml0QnlGaWVsZERlc2NyaXB0aW9ucyggY29uc3QgU2VxdWVuY2U8IFByb3BlcnR5VmFsdWUgPiYgaV9yRmllbGREZXNjcmlwdGlvbnMgKQp7CglPUXVlcnlDb250cm9sbGVyJiByQ29udHJvbGxlciA9IHN0YXRpY19jYXN0PCBPUXVlcnlDb250cm9sbGVyJiA+KCBnZXRDb250cm9sbGVyKCkgKTsKCgltX3BTZWxlY3Rpb25Cb3gtPlByZUZpbGwoKTsKCW1fcFNlbGVjdGlvbkJveC0+U2V0UmVhZE9ubHkoIHJDb250cm9sbGVyLmlzUmVhZE9ubHkoKSApOwoJbV9wU2VsZWN0aW9uQm94LT5GaWxsKCk7CgogICAgZm9yICggICBjb25zdCBQcm9wZXJ0eVZhbHVlKiBmaWVsZCA9IGlfckZpZWxkRGVzY3JpcHRpb25zLmdldENvbnN0QXJyYXkoKTsKICAgICAgICAgICAgZmllbGQgIT0gaV9yRmllbGREZXNjcmlwdGlvbnMuZ2V0Q29uc3RBcnJheSgpICsgaV9yRmllbGREZXNjcmlwdGlvbnMuZ2V0TGVuZ3RoKCk7CiAgICAgICAgICAgICsrZmllbGQKICAgICAgICApCiAgICB7CiAgICAgICAgOjp2b3M6Ok9SZWY8IE9UYWJsZUZpZWxkRGVzYyA+IHBGaWVsZCggbmV3IE9UYWJsZUZpZWxkRGVzYygpICk7CiAgICAgICAgcEZpZWxkLT5Mb2FkKCAqZmllbGQsIHRydWUgKTsKICAgICAgICBJbnNlcnRGaWVsZCggcEZpZWxkLCBzYWxfVHJ1ZSwgc2FsX0ZhbHNlICk7CiAgICB9CgogICAgckNvbnRyb2xsZXIuQ2xlYXJVbmRvTWFuYWdlcigpOwoJbV9wU2VsZWN0aW9uQm94LT5JbnZhbGlkYXRlKCk7Cn0KCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCmJvb2wgT1F1ZXJ5RGVzaWduVmlldzo6aW5pdEJ5UGFyc2VJdGVyYXRvciggOjpkYnRvb2xzOjpTUUxFeGNlcHRpb25JbmZvKiBfcEVycm9ySW5mbyApCnsKCVNxbFBhcnNlRXJyb3IgZUVycm9yQ29kZSA9IGVOYXRpdmVNb2RlOwoJbV9yQ29udHJvbGxlci5jbGVhckVycm9yKCk7CgogICAgdHJ5CiAgICB7CiAgICAgICAgZUVycm9yQ29kZSA9IEluaXRGcm9tUGFyc2VOb2RlSW1wbCggdGhpcywgbV9wU2VsZWN0aW9uQm94ICk7CgogICAgICAgIGlmICggZUVycm9yQ29kZSAhPSBlT2sgKQoJICAgIHsKCSAgICAgICAgaWYgKCAhbV9yQ29udHJvbGxlci5oYXNFcnJvcigpICkKICAgICAgICAgICAgICAgIG1fckNvbnRyb2xsZXIuYXBwZW5kRXJyb3IoIGdldFBhcnNlRXJyb3JNZXNzYWdlKCBlRXJyb3JDb2RlICkgKTsKCiAgICAgICAgICAgIGlmICggX3BFcnJvckluZm8gKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAqX3BFcnJvckluZm8gPSBtX3JDb250cm9sbGVyLmdldEVycm9yKCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBtX3JDb250cm9sbGVyLmRpc3BsYXlFcnJvcigpOwogICAgICAgICAgICB9CgkgICAgfQogICAgfQogICAgY2F0Y2ggKCBjb25zdCBFeGNlcHRpb24mICkKICAgIHsKICAgICAgICBEQkdfVU5IQU5ETEVEX0VYQ0VQVElPTigpOwogICAgfQoJcmV0dXJuIGVFcnJvckNvZGUgPT0gZU9rOwp9Ci8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgT1F1ZXJ5RGVzaWduVmlldzo6ZmlsbEZ1bmN0aW9uSW5mbyggIGNvbnN0IDo6Y29ubmVjdGl2aXR5OjpPU1FMUGFyc2VOb2RlKiBwTm9kZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLGNvbnN0IDo6cnRsOjpPVVN0cmluZyYgc0Z1bmN0aW9uVGVybQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLE9UYWJsZUZpZWxkRGVzY1JlZiYgYUluZm8pCnsKICAgIC8vIGdldCB0aGUgdHlwZSBvdXQgb2YgdGhlIGZ1bnRpb24gbmFtZQogICAgT1F1ZXJ5Q29udHJvbGxlciYgckNvbnRyb2xsZXIgPSBzdGF0aWNfY2FzdDxPUXVlcnlDb250cm9sbGVyJj4oZ2V0Q29udHJvbGxlcigpKTsKCXNhbF9JbnQzMiBuRGF0YVR5cGUgPSBEYXRhVHlwZTo6RE9VQkxFOwoJOjpydGw6Ok9VU3RyaW5nIHNGaWVsZE5hbWUgPSBzRnVuY3Rpb25UZXJtOwoJT1NRTFBhcnNlTm9kZSogcEZ1bmN0aW9uTmFtZSA9IHBOb2RlLT5nZXRDaGlsZCgwKTsKCWlmICggIVNRTF9JU1BVTkNUVUFUSU9OKHBGdW5jdGlvbk5hbWUsInsiKSApCgl7CgkJaWYgKCBTUUxfSVNSVUxFT1IyKHBOb2RlLGxlbmd0aF9leHAsY2hhcl92YWx1ZV9mY3QpICkKCQkJcEZ1bmN0aW9uTmFtZSA9IHBGdW5jdGlvbk5hbWUtPmdldENoaWxkKDApOwoKCQk6OnJ0bDo6T1VTdHJpbmcgc0Z1bmN0aW9uTmFtZSA9IHBGdW5jdGlvbk5hbWUtPmdldFRva2VuVmFsdWUoKTsKCQlpZiAoICFzRnVuY3Rpb25OYW1lLmdldExlbmd0aCgpICkKCQkJc0Z1bmN0aW9uTmFtZSA9IDo6cnRsOjpPU3RyaW5nVG9PVVN0cmluZyhPU1FMUGFyc2VyOjpUb2tlbklEVG9TdHIocEZ1bmN0aW9uTmFtZS0+Z2V0VG9rZW5JRCgpKSxSVExfVEVYVEVOQ09ESU5HX1VURjgpOwoKCQluRGF0YVR5cGUgPSBPU1FMUGFyc2VyOjpnZXRGdW5jdGlvblJldHVyblR5cGUoCgkJCQkJCQlzRnVuY3Rpb25OYW1lCgkJCQkJCQksJnJDb250cm9sbGVyLmdldFBhcnNlcigpLmdldENvbnRleHQoKSk7Cgl9CglhSW5mby0+U2V0RGF0YVR5cGUobkRhdGFUeXBlKTsKCWFJbmZvLT5TZXRGaWVsZFR5cGUoVEFCX05PUk1BTF9GSUVMRCk7CglhSW5mby0+U2V0RmllbGQoc0ZpZWxkTmFtZSk7CglhSW5mby0+U2V0VGFiV2luZG93KE5VTEwpOwp9Ci8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCg==