LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCiAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCiAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQogKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCiAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAogKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgogKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCiAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKICogdW5kZXIgdGhlIExpY2Vuc2UuCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKCgovLyBNQVJLRVIodXBkYXRlX3ByZWNvbXAucHkpOiBhdXRvZ2VuIGluY2x1ZGUgc3RhdGVtZW50LCBkbyBub3QgcmVtb3ZlCiNpbmNsdWRlICJwcmVjb21waWxlZF9kYnVpLmh4eCIKI2lmbmRlZiBEQkFVSV9RVUVSWURFU0lHTlZJRVdfSFhYCiNpbmNsdWRlICJRdWVyeURlc2lnblZpZXcuaHh4IgojZW5kaWYKI2lmbmRlZiBEQkFVSV9RVUVSWVRBQkxFVklFV19IWFgKI2luY2x1ZGUgIlF1ZXJ5VGFibGVWaWV3Lmh4eCIKI2VuZGlmCiNpZm5kZWYgREJBVUlfUVVFUllfVEFCTEVXSU5ET1dfSFhYCiNpbmNsdWRlICJRVGFibGVXaW5kb3cuaHh4IgojZW5kaWYKI2lmbmRlZiBfU1ZfVE9PTEJPWF9IWFgKI2luY2x1ZGUgPHZjbC90b29sYm94Lmh4eD4KI2VuZGlmCiNpZm5kZWYgREJBVUlfUVVFUllDT05UUk9MTEVSX0hYWAojaW5jbHVkZSAicXVlcnljb250cm9sbGVyLmh4eCIKI2VuZGlmCiNpZm5kZWYgX1NWX1NQTElUX0hYWAojaW5jbHVkZSA8dmNsL3NwbGl0Lmh4eD4KI2VuZGlmCiNpZm5kZWYgX1VORE9fSFhYCiNpbmNsdWRlIDxzdmwvdW5kby5oeHg+CiNlbmRpZgojaWZuZGVmIFRPT0xTX0RJQUdOT1NFX0VYX0gKI2luY2x1ZGUgPHRvb2xzL2RpYWdub3NlX2V4Lmg+CiNlbmRpZgojaWZuZGVmIERCQVVJX1FZRExHVEFCX0hYWAojaW5jbHVkZSAiYWR0YWJkbGcuaHh4IgojZW5kaWYKI2lmbmRlZiBfU1ZfU1ZBUFBfSFhYCiNpbmNsdWRlIDx2Y2wvc3ZhcHAuaHh4PgojZW5kaWYKI2lmbmRlZiBfU1ZfQ09NQk9CT1hfSFhYCiNpbmNsdWRlIDx2Y2wvY29tYm9ib3guaHh4PgojZW5kaWYKI2lmbmRlZiBfU1ZfTVNHQk9YX0hYWAojaW5jbHVkZSA8dmNsL21zZ2JveC5oeHg+CiNlbmRpZgojaWZuZGVmIERCQUNDRVNTX1VJX0JST1dTRVJfSURfSFhYCiNpbmNsdWRlICJicm93c2VyaWRzLmh4eCIKI2VuZGlmCiNpZm5kZWYgREJBVUlfUVVFUllERVNJR05fT1NFTEVDVElPTkJST1dTRUJPWF9IWFgKI2luY2x1ZGUgIlNlbGVjdGlvbkJyb3dzZUJveC5oeHgiCiNlbmRpZgojaWZuZGVmIF9EQlVfUVJZX0hSQ18KI2luY2x1ZGUgImRidV9xcnkuaHJjIgojZW5kaWYKI2lmbmRlZiBfVVRMX0NPTkZJR01HUl9IWFhfCiNpbmNsdWRlIDx1bm90b29scy9jb25maWdtZ3IuaHh4PgojZW5kaWYKI2lmbmRlZiBfQ09NUEhFTFBFUl9UWVBFU19IWFhfCiNpbmNsdWRlIDxjb21waGVscGVyL3R5cGVzLmh4eD4KI2VuZGlmCiNpZm5kZWYgX0NPTk5FQ1RJVklUWV9EQlRPT0xTX0hYWF8KI2luY2x1ZGUgPGNvbm5lY3Rpdml0eS9kYnRvb2xzLmh4eD4KI2VuZGlmCiNpZm5kZWYgX0RCSEVMUEVSX0RCRVhDRVBUSU9OX0hYWF8KI2luY2x1ZGUgPGNvbm5lY3Rpdml0eS9kYmV4Y2VwdGlvbi5oeHg+CiNlbmRpZgojaWZuZGVmIF9DT01fU1VOX1NUQVJfSTE4Tl9YTE9DQUxFREFUQV9IUFBfCiNpbmNsdWRlIDxjb20vc3VuL3N0YXIvaTE4bi9YTG9jYWxlRGF0YS5ocHA+CiNlbmRpZgojaWZuZGVmIF9DT01fU1VOX1NUQVJfU0RCQ19EQVRBVFlQRV9IUFBfCiNpbmNsdWRlIDxjb20vc3VuL3N0YXIvc2RiYy9EYXRhVHlwZS5ocHA+CiNlbmRpZgojaWZuZGVmIF9DT01fU1VOX1NUQVJfQ09OVEFJTkVSX1hOQU1FQUNDRVNTX0hQUF8KI2luY2x1ZGUgPGNvbS9zdW4vc3Rhci9jb250YWluZXIvWE5hbWVBY2Nlc3MuaHBwPgojZW5kaWYKI2lmbmRlZiBfQ09NX1NVTl9TVEFSX1NEQkNfQ09MVU1OVkFMVUVfSFBQXwojaW5jbHVkZSA8Y29tL3N1bi9zdGFyL3NkYmMvQ29sdW1uVmFsdWUuaHBwPgojZW5kaWYKI2lmbmRlZiBfQ09OTkVDVElWSVRZX1BDT0xVTU5fSFhYXwojaW5jbHVkZSA8Y29ubmVjdGl2aXR5L1BDb2x1bW4uaHh4PgojZW5kaWYKI2lmbmRlZiBEQkFVSV9RVUVSWVRBQkxFQ09OTkVDVElPTl9IWFgKI2luY2x1ZGUgIlFUYWJsZUNvbm5lY3Rpb24uaHh4IgojZW5kaWYKI2lmbmRlZiBEQkFVSV9DT05ORUNUSU9OTElORV9IWFgKI2luY2x1ZGUgIkNvbm5lY3Rpb25MaW5lLmh4eCIKI2VuZGlmCiNpZm5kZWYgREJBVUlfQ09OTkVDVElPTkxJTkVEQVRBX0hYWAojaW5jbHVkZSAiQ29ubmVjdGlvbkxpbmVEYXRhLmh4eCIKI2VuZGlmCiNpZm5kZWYgREJBVUlfUVRBQkxFQ09OTkVDVElPTkRBVEFfSFhYCiNpbmNsdWRlICJRVGFibGVDb25uZWN0aW9uRGF0YS5oeHgiCiNlbmRpZgojaWZuZGVmIERCQUNDRVNTX1NIQVJFRF9EQlVTVFJJTkdTX0hSQwojaW5jbHVkZSAiZGJ1c3RyaW5ncy5ocmMiCiNlbmRpZgojaWZuZGVmIF9DT01QSEVMUEVSX0VYVFJBQ1RfSFhYXwojaW5jbHVkZSA8Y29tcGhlbHBlci9leHRyYWN0Lmh4eD4KI2VuZGlmCiNpZm5kZWYgREJBVUlfVE9PTFNfSFhYCiNpbmNsdWRlICJVSVRvb2xzLmh4eCIKI2VuZGlmCiNpZm5kZWYgREJBVUlfUVVFUllDT05UQUlORVJXSU5ET1dfSFhYCiNpbmNsdWRlICJxdWVyeWNvbnRhaW5lcndpbmRvdy5oeHgiCiNlbmRpZgojaWZuZGVmIERCQVVJX1FVRVJZVEFCTEVWSUVXX0hYWAojaW5jbHVkZSAiUXVlcnlUYWJsZVZpZXcuaHh4IgojZW5kaWYKI2lmbmRlZiBfREJBVUlfU1FMTUVTU0FHRV9IWFhfCiNpbmNsdWRlICJzcWxtZXNzYWdlLmh4eCIKI2VuZGlmCiNpZm5kZWYgSU5DTFVERURfU1ZUT09MU19TWVNMT0NBTEVfSFhYCiNpbmNsdWRlIDx1bm90b29scy9zeXNsb2NhbGUuaHh4PgojZW5kaWYKCnVzaW5nIG5hbWVzcGFjZSA6OmRiYXVpOwp1c2luZyBuYW1lc3BhY2UgOjp1dGw7CnVzaW5nIG5hbWVzcGFjZSA6OmNvbm5lY3Rpdml0eTsKdXNpbmcgbmFtZXNwYWNlIDo6ZGJ0b29sczsKdXNpbmcgbmFtZXNwYWNlIDo6Y29tOjpzdW46OnN0YXI6OnVubzsKdXNpbmcgbmFtZXNwYWNlIDo6Y29tOjpzdW46OnN0YXI6Omxhbmc7CnVzaW5nIG5hbWVzcGFjZSA6OmNvbTo6c3VuOjpzdGFyOjppMThuOwp1c2luZyBuYW1lc3BhY2UgOjpjb206OnN1bjo6c3Rhcjo6c2RiYzsKdXNpbmcgbmFtZXNwYWNlIDo6Y29tOjpzdW46OnN0YXI6OmJlYW5zOwp1c2luZyBuYW1lc3BhY2UgOjpjb206OnN1bjo6c3Rhcjo6Y29udGFpbmVyOwoKI2RlZmluZSBTUUxfSVNSVUxFT1IyKHBQYXJzZU5vZGUsIGUxLGUyKSAJKChwUGFyc2VOb2RlKS0+aXNSdWxlKCkgJiYgKFwKCQkJCQkJCQkJCQkocFBhcnNlTm9kZSktPmdldFJ1bGVJRCgpID09IE9TUUxQYXJzZXI6OlJ1bGVJRChPU1FMUGFyc2VOb2RlOjplMSkgfHwgXAoJCQkJCQkJCQkJCShwUGFyc2VOb2RlKS0+Z2V0UnVsZUlEKCkgPT0gT1NRTFBhcnNlcjo6UnVsZUlEKE9TUUxQYXJzZU5vZGU6OmUyKSkpCgovLyBoZXJlIHdlIGRlZmluZSBvdXIgZnVuY3Rpb25zIHVzZWQgaW4gdGhlIGFub255bW91cyBuYW1lc3BhY2UgdG8gZ2V0IG91ciBoZWFkZXIgZmlsZSBzbWFsbGVyCi8vIHBsZWFzZSBsb29rIGF0IHRoZSBib29rIExhcmdlU2NhbGUgQysrIHRvIGtub3cgd2h5Cm5hbWVzcGFjZQp7CglzdGF0aWMgY29uc3QgOjpydGw6Ok9VU3RyaW5nIENfQU5EID0gOjpydGw6Ok9VU3RyaW5nOjpjcmVhdGVGcm9tQXNjaWkoIiBBTkQgIik7CglzdGF0aWMgY29uc3QgOjpydGw6Ok9VU3RyaW5nIENfT1IgID0gOjpydGw6Ok9VU3RyaW5nOjpjcmVhdGVGcm9tQXNjaWkoIiBPUiAiKTsKCgkvLyBmb3J3YXJkIGRlY2xhcmF0aW9ucwoJc2FsX0Jvb2wgSW5zZXJ0Sm9pbigJY29uc3QgT1F1ZXJ5RGVzaWduVmlldyogX3BWaWV3LAoJCQkJCQkJY29uc3QgOjpjb25uZWN0aXZpdHk6Ok9TUUxQYXJzZU5vZGUgKnBOb2RlKTsKCglTcWxQYXJzZUVycm9yIEluc3RhbGxGaWVsZHMoT1F1ZXJ5RGVzaWduVmlldyogX3BWaWV3LAoJCQkJCQkJCWNvbnN0IDo6Y29ubmVjdGl2aXR5OjpPU1FMUGFyc2VOb2RlKiBwTm9kZSwKCQkJCQkJCQlPSm9pblRhYmxlVmlldzo6T1RhYmxlV2luZG93TWFwKiBwVGFiTGlzdCApOwoKCVNxbFBhcnNlRXJyb3IgR2V0R3JvdXBDcml0ZXJpYSgJT1F1ZXJ5RGVzaWduVmlldyogX3BWaWV3LAoJCQkJCQkJCQlPU2VsZWN0aW9uQnJvd3NlQm94KiBfcFNlbGVjdGlvbkJydywKCQkJCQkJCQkJY29uc3QgOjpjb25uZWN0aXZpdHk6Ok9TUUxQYXJzZU5vZGUqIHBTZWxlY3RSb290ICk7CgoJU3FsUGFyc2VFcnJvciBHZXRIYXZpbmdDcml0ZXJpYShPUXVlcnlEZXNpZ25WaWV3KiBfcFZpZXcsCgkJCQkJCQkJCU9TZWxlY3Rpb25Ccm93c2VCb3gqIF9wU2VsZWN0aW9uQnJ3LAoJCQkJCQkJCQljb25zdCA6OmNvbm5lY3Rpdml0eTo6T1NRTFBhcnNlTm9kZSogcFNlbGVjdFJvb3QsCgkJCQkJCQkJCXNhbF91SW50MTYmIHJMZXZlbCApOwoKCVNxbFBhcnNlRXJyb3IgR2V0T3JkZXJDcml0ZXJpYSgJT1F1ZXJ5RGVzaWduVmlldyogX3BWaWV3LAoJCQkJCQkJCQlPU2VsZWN0aW9uQnJvd3NlQm94KiBfcFNlbGVjdGlvbkJydywKCQkJCQkJCQkJY29uc3QgOjpjb25uZWN0aXZpdHk6Ok9TUUxQYXJzZU5vZGUqIHBQYXJzZVJvb3QgKTsKCglTcWxQYXJzZUVycm9yIEFkZEZ1bmN0aW9uQ29uZGl0aW9uKE9RdWVyeURlc2lnblZpZXcqIF9wVmlldywKCQkJCQkJCQkJT1NlbGVjdGlvbkJyb3dzZUJveCogX3BTZWxlY3Rpb25CcncsCgkJCQkJCQkJCWNvbnN0IDo6Y29ubmVjdGl2aXR5OjpPU1FMUGFyc2VOb2RlICogcENvbmRpdGlvbiwKCQkJCQkJCQkJY29uc3Qgc2FsX3VJbnQxNiBuTGV2ZWwsCgkJCQkJCQkJCXNhbF9Cb29sIGJIYXZpbmcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgX2JBZGRPck9uT25lTGluZSk7CgoJLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCTo6cnRsOjpPVVN0cmluZyBxdW90ZVRhYmxlQWxpYXMoc2FsX0Jvb2wgX2JRdW90ZSwgY29uc3QgOjpydGw6Ok9VU3RyaW5nJiBfc0FsaWFzTmFtZSwgY29uc3QgOjpydGw6Ok9VU3RyaW5nJiBfc1F1b3RlKQoJewoJCTo6cnRsOjpPVVN0cmluZyBzUmV0OwoJCWlmICggX2JRdW90ZSAmJiBfc0FsaWFzTmFtZS5nZXRMZW5ndGgoKSApCgkJewoJCQlzUmV0ID0gOjpkYnRvb2xzOjpxdW90ZU5hbWUoX3NRdW90ZSxfc0FsaWFzTmFtZSk7CgkJCWNvbnN0IHN0YXRpYyA6OnJ0bDo6T1VTdHJpbmcgc1RhYmxlU2VwYXJhdGVyKCcuJyk7CgkJCXNSZXQgKz0gc1RhYmxlU2VwYXJhdGVyOwoJCX0KCQlyZXR1cm4gc1JldDsKCX0KICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICA6OnJ0bDo6T1VTdHJpbmcgZ2V0VGFibGVSYW5nZShjb25zdCBPUXVlcnlEZXNpZ25WaWV3KiBfcFZpZXcsY29uc3QgOjpjb25uZWN0aXZpdHk6Ok9TUUxQYXJzZU5vZGUqIF9wVGFibGVSZWYpCiAgICB7CiAgICAgICAgUmVmZXJlbmNlPCBYQ29ubmVjdGlvbj4geENvbm5lY3Rpb24gPSBzdGF0aWNfY2FzdDxPUXVlcnlDb250cm9sbGVyJj4oX3BWaWV3LT5nZXRDb250cm9sbGVyKCkpLmdldENvbm5lY3Rpb24oKTsKICAgICAgICA6OnJ0bDo6T1VTdHJpbmcgc1RhYmxlUmFuZ2U7CiAgICAgICAgaWYgKCBfcFRhYmxlUmVmICkKICAgICAgICB7CiAgICAgICAgICAgIHNUYWJsZVJhbmdlID0gOjpjb25uZWN0aXZpdHk6Ok9TUUxQYXJzZU5vZGU6OmdldFRhYmxlUmFuZ2UoX3BUYWJsZVJlZik7CiAgICAgICAgICAgIGlmICggIXNUYWJsZVJhbmdlLmdldExlbmd0aCgpICkKICAgICAgICAgICAgICAgIF9wVGFibGVSZWYtPnBhcnNlTm9kZVRvU3RyKHNUYWJsZVJhbmdlLHhDb25uZWN0aW9uLE5VTEwsc2FsX0ZhbHNlLHNhbF9GYWxzZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzVGFibGVSYW5nZTsKICAgIH0KICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICB2b2lkIGluc2VydENvbm5lY3Rpb24oY29uc3QgT1F1ZXJ5RGVzaWduVmlldyogX3BWaWV3LGNvbnN0IEVKb2luVHlwZSYgX2VKb2luVHlwZSxPVGFibGVGaWVsZERlc2NSZWYgX2FEcmFnTGVmdCxPVGFibGVGaWVsZERlc2NSZWYgX2FEcmFnUmlnaHQsYm9vbCBfYk5hdHVyYWwgPSBmYWxzZSkKICAgIHsKICAgICAgICBPUXVlcnlUYWJsZVZpZXcqIHBUYWJsZVZpZXcgPSBzdGF0aWNfY2FzdDxPUXVlcnlUYWJsZVZpZXcqPihfcFZpZXctPmdldFRhYmxlVmlldygpKTsKCQlPUXVlcnlUYWJsZUNvbm5lY3Rpb24qIHBDb25uID0gc3RhdGljX2Nhc3Q8T1F1ZXJ5VGFibGVDb25uZWN0aW9uKj4oIHBUYWJsZVZpZXctPkdldFRhYkNvbm4oc3RhdGljX2Nhc3Q8T1RhYmxlV2luZG93Kj4oX2FEcmFnTGVmdC0+R2V0VGFiV2luZG93KCkpLHN0YXRpY19jYXN0PE9UYWJsZVdpbmRvdyo+KF9hRHJhZ1JpZ2h0LT5HZXRUYWJXaW5kb3coKSksdHJ1ZSkpOwoKCQlpZiAoICFwQ29ubiApCgkJewoJCQlPUXVlcnlUYWJsZUNvbm5lY3Rpb25EYXRhKiBwSW5mb0RhdGEgPSBuZXcgT1F1ZXJ5VGFibGVDb25uZWN0aW9uRGF0YSgpOwogICAgICAgICAgICBUVGFibGVDb25uZWN0aW9uRGF0YTo6dmFsdWVfdHlwZSBhSW5mb0RhdGEocEluZm9EYXRhKTsKCQkJcEluZm9EYXRhLT5Jbml0RnJvbURyYWcoX2FEcmFnTGVmdCwgX2FEcmFnUmlnaHQpOwoJCQlwSW5mb0RhdGEtPlNldEpvaW5UeXBlKF9lSm9pblR5cGUpOwoKICAgICAgICAgICAgaWYgKCBfYk5hdHVyYWwgKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBhSW5mb0RhdGEtPlJlc2V0Q29ubkxpbmVzKCk7CiAgICAgICAgICAgICAgICBwSW5mb0RhdGEtPnNldE5hdHVyYWwoX2JOYXR1cmFsKTsKICAgICAgICAgICAgICAgIHRyeQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIFJlZmVyZW5jZTxYTmFtZUFjY2Vzcz4geFJlZmVyZW5jZWRUYWJsZUNvbHVtbnMoYUluZm9EYXRhLT5nZXRSZWZlcmVuY2VkVGFibGUoKS0+Z2V0Q29sdW1ucygpKTsKICAgICAgICAgICAgICAgICAgICBTZXF1ZW5jZTwgOjpydGw6Ok9VU3RyaW5nPiBhU2VxID0gYUluZm9EYXRhLT5nZXRSZWZlcmVuY2luZ1RhYmxlKCktPmdldENvbHVtbnMoKS0+Z2V0RWxlbWVudE5hbWVzKCk7CiAgICAgICAgICAgICAgICAgICAgY29uc3QgOjpydGw6Ok9VU3RyaW5nKiBwSXRlciA9IGFTZXEuZ2V0Q29uc3RBcnJheSgpOwogICAgICAgICAgICAgICAgICAgIGNvbnN0IDo6cnRsOjpPVVN0cmluZyogcEVuZAkgID0gcEl0ZXIgKyBhU2VxLmdldExlbmd0aCgpOwogICAgICAgICAgICAgICAgICAgIGZvcig7cEl0ZXIgIT0gcEVuZDsrK3BJdGVyKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCB4UmVmZXJlbmNlZFRhYmxlQ29sdW1ucy0+aGFzQnlOYW1lKCpwSXRlcikgKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgYUluZm9EYXRhLT5BcHBlbmRDb25uTGluZSgqcEl0ZXIsKnBJdGVyKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBjYXRjaCggY29uc3QgRXhjZXB0aW9uJiApCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgREJHX1VOSEFORExFRF9FWENFUFRJT04oKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKCQkJT1F1ZXJ5VGFibGVDb25uZWN0aW9uIGFJbmZvKHBUYWJsZVZpZXcsIGFJbmZvRGF0YSk7CgkJCS8vIGRhIGVpbiBPUXVlcnlUYWJsZUNvbm5lY3Rpb24tT2JqZWt0IG5pZSBkZW4gQmVzaXR6IGRlciB1ZWJlcmdlYmVuZW4gRGF0ZW4gdWViZXJuaW1tdCwgc29uZGVybiBzaWNoIG51ciBkZW4gWmVpZ2VyIG1lcmt0LAoJCQkvLyBpc3QgZGllc2VyIFplaWdlciBhdWYgZWluZSBsb2thbGUgVmFyaWFibGUgaGllciB1bmtyaXRpc2NoLCBkZW5uIGFJbmZvRGF0YSB1bmQgYUluZm8gaGFiZW4gZGllIHNlbGJlIExlYmVuc2RhdWVyCgkJCXBUYWJsZVZpZXctPk5vdGlmeVRhYkNvbm5lY3Rpb24oIGFJbmZvICk7CgkJfQoJCWVsc2UKCQl7CgkJCTo6cnRsOjpPVVN0cmluZyBhU291cmNlRmllbGROYW1lKF9hRHJhZ0xlZnQtPkdldEZpZWxkKCkpOwoJCQk6OnJ0bDo6T1VTdHJpbmcgYURlc3RGaWVsZE5hbWUoX2FEcmFnUmlnaHQtPkdldEZpZWxkKCkpOwoJCQkvLyB0aGUgY29ubmVjdGlvbiBjb3VsZCBwb2ludCBvbiB0aGUgb3RoZXIgc2lkZQoJCQlpZihwQ29ubi0+R2V0U291cmNlV2luKCkgPT0gX2FEcmFnUmlnaHQtPkdldFRhYldpbmRvdygpKQoJCQl7CgkJCQk6OnJ0bDo6T1VTdHJpbmcgYVRtcChhU291cmNlRmllbGROYW1lKTsKCQkJCWFTb3VyY2VGaWVsZE5hbWUgPSBhRGVzdEZpZWxkTmFtZTsKCQkJCWFEZXN0RmllbGROYW1lID0gYVRtcDsKCQkJfQoJCQlwQ29ubi0+R2V0RGF0YSgpLT5BcHBlbmRDb25uTGluZSggYVNvdXJjZUZpZWxkTmFtZSxhRGVzdEZpZWxkTmFtZSk7CgkJCXBDb25uLT5VcGRhdGVMaW5lTGlzdCgpOwoJCQkvLyBNb2RpZmllZC1GbGFnCgkJCS8vCVNldE1vZGlmaWVkKCk7CgkJCS8vIHVuZCBuZXUgemVpY2huZW4KCQkJcENvbm4tPlJlY2FsY0xpbmVzKCk7CgkJCQkvLyBmdWVyIGRhcyB1bnRlbiBmb2xnZW5kZSBJbnZhbGlkYXRlIG11c3MgaWNoIGRpZXNlciBuZXVlbiBDb25uZWN0aW9uIGVyc3QgbWFsIGRpZSBNb2VnbGljaGtlaXQgZ2ViZW4sCgkJCQkvLyBpaHIgQm91bmRpbmdSZWN0IHp1IGVybWl0dGVsbgoJCQlwQ29ubi0+SW52YWxpZGF0ZUNvbm5lY3Rpb24oKTsKCQl9CiAgICB9CgkvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoJOjpydGw6Ok9VU3RyaW5nIFBhcnNlQ29uZGl0aW9uKAlPUXVlcnlDb250cm9sbGVyJiByQ29udHJvbGxlcgoJCQkJCQkJCQksY29uc3QgOjpjb25uZWN0aXZpdHk6Ok9TUUxQYXJzZU5vZGUqIHBDb25kaXRpb24KCQkJCQkJCQkJLGNvbnN0IDo6cnRsOjpPVVN0cmluZyBfc0RlY2ltYWwKCQkJCQkJCQkJLGNvbnN0IDo6Y29tOjpzdW46OnN0YXI6Omxhbmc6OkxvY2FsZSYgX3JMb2NhbGUKCQkJCQkJCQkJLHNhbF91SW50MzIgX25TdGFydEluZGV4KQoJewoJCTo6cnRsOjpPVVN0cmluZwlhQ29uZGl0aW9uOwoJCVJlZmVyZW5jZTwgWENvbm5lY3Rpb24+IHhDb25uZWN0aW9uID0gckNvbnRyb2xsZXIuZ2V0Q29ubmVjdGlvbigpOwoJCWlmICggeENvbm5lY3Rpb24uaXMoKSApCgkJewoJCQlzYWxfdUludDMyIG5Db3VudCA9IHBDb25kaXRpb24tPmNvdW50KCk7CgkJCWZvcihzYWxfdUludDMyIGkgPSBfblN0YXJ0SW5kZXggOyBpIDwgbkNvdW50IDsgKytpKQoJCQkJcENvbmRpdGlvbi0+Z2V0Q2hpbGQoaSktPnBhcnNlTm9kZVRvUHJlZGljYXRlU3RyKGFDb25kaXRpb24sCgkJCQkJCQkJeENvbm5lY3Rpb24sCgkJCQkJCQkJckNvbnRyb2xsZXIuZ2V0TnVtYmVyRm9ybWF0dGVyKCksCgkJCQkJCQkJX3JMb2NhbGUsCgkJCQkJCQkJc3RhdGljX2Nhc3Q8c2FsX0NoYXI+KF9zRGVjaW1hbC50b0NoYXIoKSksCgkJCQkJCQkJJnJDb250cm9sbGVyLmdldFBhcnNlcigpLmdldENvbnRleHQoKSk7CgkJfQoJCXJldHVybiBhQ29uZGl0aW9uOwoJfQoJLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCVNxbFBhcnNlRXJyb3IgRmlsbE91dGVySm9pbnMoT1F1ZXJ5RGVzaWduVmlldyogX3BWaWV3LAoJCQkJCQkJCWNvbnN0IDo6Y29ubmVjdGl2aXR5OjpPU1FMUGFyc2VOb2RlKiBwVGFibGVSZWZMaXN0KQoJewoJCVNxbFBhcnNlRXJyb3IgZUVycm9yQ29kZSA9IGVPazsKCQlzYWxfdUludDMyIG5Db3VudCA9IHBUYWJsZVJlZkxpc3QtPmNvdW50KCk7CgkJc2FsX0Jvb2wgYkVycm9yID0gc2FsX0ZhbHNlOwoJCWZvciAoc2FsX3VJbnQzMiBpPTA7ICFiRXJyb3IgJiYgaSA8IG5Db3VudDsgKytpKQoJCXsKCQkJY29uc3QgOjpjb25uZWN0aXZpdHk6Ok9TUUxQYXJzZU5vZGUqIHBQYXJzZU5vZGUgPSBwVGFibGVSZWZMaXN0LT5nZXRDaGlsZChpKTsKCQkJY29uc3QgOjpjb25uZWN0aXZpdHk6Ok9TUUxQYXJzZU5vZGUqIHBKb2luTm9kZSA9IE5VTEw7CgoJCQlpZiAoIFNRTF9JU1JVTEUoIHBQYXJzZU5vZGUsIHF1YWxpZmllZF9qb2luICkgfHwgU1FMX0lTUlVMRSggcFBhcnNlTm9kZSwgam9pbmVkX3RhYmxlICkgfHwgU1FMX0lTUlVMRSggcFBhcnNlTm9kZSwgY3Jvc3NfdW5pb24gKSApCgkJCQlwSm9pbk5vZGUgPSBwUGFyc2VOb2RlOwoJCQllbHNlIGlmKAlTUUxfSVNSVUxFKHBQYXJzZU5vZGUsdGFibGVfcmVmKQoJCQkJCSYmCXBQYXJzZU5vZGUtPmNvdW50KCkgPT0gNCApIC8vICd7JyBTUUxfVE9LRU5fT0ogam9pbmVkX3RhYmxlICd9JwoJCQkJcEpvaW5Ob2RlID0gcFBhcnNlTm9kZS0+Z2V0Q2hpbGQoMik7CgoJCQlpZiAoIHBKb2luTm9kZSApCgkJCXsKCQkJCWlmICggIUluc2VydEpvaW4oX3BWaWV3LHBKb2luTm9kZSkgKQoJCQkJCWJFcnJvciA9IHNhbF9UcnVlOwoJCQl9CgkJfQoJCS8vIGNoZWNrIGlmIGVycm9yIG9jY3VycmVkCgkJaWYgKCBiRXJyb3IgKQoJCQllRXJyb3JDb2RlID0gZUlsbGVnYWxKb2luOwoKCQlyZXR1cm4gZUVycm9yQ29kZTsKCX0KCS8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgoJLyoqIEZpbGxEcmFnSW5mbyBmaWxscyB0aGUgZmllbGQgZGVzY3JpcHRpb24gb3V0IG9mIHRoZSB0YWJsZQoJKi8KCS8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCglTcWxQYXJzZUVycm9yIEZpbGxEcmFnSW5mbygJY29uc3QgT1F1ZXJ5RGVzaWduVmlldyogX3BWaWV3LAoJCQkJCQkJY29uc3QgOjpjb25uZWN0aXZpdHk6Ok9TUUxQYXJzZU5vZGUqIHBDb2x1bW5SZWYsCgkJCQkJCQlPVGFibGVGaWVsZERlc2NSZWYmIF9yRHJhZ0luZm8pCgl7CgkJU3FsUGFyc2VFcnJvciBlRXJyb3JDb2RlID0gZU9rOwoKCQlzYWxfQm9vbCBiRXJnID0gc2FsX0ZhbHNlOwoKCQk6OnJ0bDo6T1VTdHJpbmcgYVRhYmxlUmFuZ2UsYUNvbHVtbk5hbWU7CgkJc2FsX3VJbnQxNiBuQ250QWNjb3VudDsKCQk6OmNvbm5lY3Rpdml0eTo6T1NRTFBhcnNlVHJlZUl0ZXJhdG9yJiByUGFyc2VJdGVyID0gc3RhdGljX2Nhc3Q8T1F1ZXJ5Q29udHJvbGxlciY+KF9wVmlldy0+Z2V0Q29udHJvbGxlcigpKS5nZXRQYXJzZUl0ZXJhdG9yKCk7CgkJclBhcnNlSXRlci5nZXRDb2x1bW5SYW5nZSggcENvbHVtblJlZiwgYUNvbHVtbk5hbWUsIGFUYWJsZVJhbmdlICk7CgoJCWlmICggYVRhYmxlUmFuZ2UuZ2V0TGVuZ3RoKCkgKQoJCXsKCQkJT1F1ZXJ5VGFibGVXaW5kb3cqCXBTVFcgPSBzdGF0aWNfY2FzdDxPUXVlcnlUYWJsZVZpZXcqPihfcFZpZXctPmdldFRhYmxlVmlldygpKS0+RmluZFRhYmxlKCBhVGFibGVSYW5nZSApOwoJCQliRXJnID0gKHBTVFcgJiYgcFNUVy0+RXhpc3RzRmllbGQoIGFDb2x1bW5OYW1lLCBfckRyYWdJbmZvICkgKTsKCQl9CgkJaWYgKCAhYkVyZyApCiAgICAgICAgewoJCQliRXJnID0gc3RhdGljX2Nhc3Q8T1F1ZXJ5VGFibGVWaWV3Kj4oX3BWaWV3LT5nZXRUYWJsZVZpZXcoKSktPkZpbmRUYWJsZUZyb21GaWVsZChhQ29sdW1uTmFtZSwgX3JEcmFnSW5mbywgbkNudEFjY291bnQpOwogICAgICAgICAgICBpZiAoICFiRXJnICkKICAgICAgICAgICAgICAgIGJFcmcgPSBfcFZpZXctPkhhc0ZpZWxkQnlBbGlhc05hbWUoYUNvbHVtbk5hbWUsIF9yRHJhZ0luZm8pOwogICAgICAgIH0KCQlpZiAoICFiRXJnICkKCQl7CgkJCWVFcnJvckNvZGUgPSBlQ29sdW1uTm90Rm91bmQ7CgkJCVN0cmluZyBzRXJyb3IoTW9kdWxlUmVzKFNUUl9RUllfQ09MVU1OX05PVF9GT1VORCkpOwoJCQlzRXJyb3IuU2VhcmNoQW5kUmVwbGFjZUFzY2lpKCIkbmFtZSQiLGFDb2x1bW5OYW1lKTsKCQkJX3BWaWV3LT5nZXRDb250cm9sbGVyKCkuYXBwZW5kRXJyb3IoIHNFcnJvciApOwoKCQkJdHJ5CgkJCXsKCQkJCVJlZmVyZW5jZTxYRGF0YWJhc2VNZXRhRGF0YT4geE1ldGEgPSBfcFZpZXctPmdldENvbnRyb2xsZXIoKS5nZXRDb25uZWN0aW9uKCktPmdldE1ldGFEYXRhKCk7CiAgICAgICAgICAgICAgICBpZiAoIHhNZXRhLmlzKCkgJiYgeE1ldGEtPnN1cHBvcnRzTWl4ZWRDYXNlUXVvdGVkSWRlbnRpZmllcnMoKSApCiAgICAgICAgICAgICAgICAgICAgX3BWaWV3LT5nZXRDb250cm9sbGVyKCkuYXBwZW5kRXJyb3IoIFN0cmluZyggTW9kdWxlUmVzKCBTVFJfUVJZX0NIRUNLX0NBU0VTRU5TSVRJVkUgKSApICk7CgkJCX0KCQkJY2F0Y2goRXhjZXB0aW9uJikKCQkJewoJCQl9CgkJfQoKCQlyZXR1cm4gZUVycm9yQ29kZTsKCX0KCS8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgk6OnJ0bDo6T1VTdHJpbmcgQnVpbGRKb2luQ3JpdGVyaWEoCWNvbnN0IFJlZmVyZW5jZTwgWENvbm5lY3Rpb24+JiBfeENvbm5lY3Rpb24sCgkJCQkJCQkJCQlPQ29ubmVjdGlvbkxpbmVEYXRhVmVjKiBwTGluZURhdGFMaXN0LAoJCQkJCQkJCQkJT1F1ZXJ5VGFibGVDb25uZWN0aW9uRGF0YSogcERhdGEpCgl7CgkJOjpydGw6Ok9VU3RyaW5nQnVmZmVyIGFDb25kaXRpb247CgkJaWYgKCBfeENvbm5lY3Rpb24uaXMoKSApCiAgICAgICAgewoJCSAgICBPQ29ubmVjdGlvbkxpbmVEYXRhVmVjOjppdGVyYXRvciBhSXRlciA9IHBMaW5lRGF0YUxpc3QtPmJlZ2luKCk7CiAgICAgICAgICAgIE9Db25uZWN0aW9uTGluZURhdGFWZWM6Oml0ZXJhdG9yIGFFbmQgPSBwTGluZURhdGFMaXN0LT5lbmQoKTsKCQkgICAgdHJ5CgkJICAgIHsKCQkJICAgIGNvbnN0IFJlZmVyZW5jZTwgWERhdGFiYXNlTWV0YURhdGEgPiAgeE1ldGFEYXRhID0gX3hDb25uZWN0aW9uLT5nZXRNZXRhRGF0YSgpOwoJCQkgICAgY29uc3QgOjpydGw6Ok9VU3RyaW5nIGFRdW90ZSA9IHhNZXRhRGF0YS0+Z2V0SWRlbnRpZmllclF1b3RlU3RyaW5nKCk7CiAgICAgICAgICAgICAgICBjb25zdCA6OnJ0bDo6T1VTdHJpbmcgc0VxdWFsKFJUTF9DT05TVEFTQ0lJX1VTVFJJTkdQQVJBTSgiID0gIikpOwoKCQkJICAgIGZvcig7YUl0ZXIgIT0gYUVuZDsrK2FJdGVyKQoJCQkgICAgewoJCQkJICAgIE9Db25uZWN0aW9uTGluZURhdGFSZWYgcExpbmVEYXRhID0gKmFJdGVyOwoJCQkJICAgIGlmKGFDb25kaXRpb24uZ2V0TGVuZ3RoKCkpCgkJCQkJICAgIGFDb25kaXRpb24uYXBwZW5kKENfQU5EKTsKCQkJCSAgICBhQ29uZGl0aW9uLmFwcGVuZChxdW90ZVRhYmxlQWxpYXMoc2FsX1RydWUscERhdGEtPkdldEFsaWFzTmFtZShKVENTX0ZST00pLGFRdW90ZSkpOwoJCQkJICAgIGFDb25kaXRpb24uYXBwZW5kKDo6ZGJ0b29sczo6cXVvdGVOYW1lKGFRdW90ZSwgcExpbmVEYXRhLT5HZXRGaWVsZE5hbWUoSlRDU19GUk9NKSApKTsKCQkJCSAgICBhQ29uZGl0aW9uLmFwcGVuZChzRXF1YWwpOwoJCQkJICAgIGFDb25kaXRpb24uYXBwZW5kKHF1b3RlVGFibGVBbGlhcyhzYWxfVHJ1ZSxwRGF0YS0+R2V0QWxpYXNOYW1lKEpUQ1NfVE8pLGFRdW90ZSkpOwoJCQkJICAgIGFDb25kaXRpb24uYXBwZW5kKDo6ZGJ0b29sczo6cXVvdGVOYW1lKGFRdW90ZSwgcExpbmVEYXRhLT5HZXRGaWVsZE5hbWUoSlRDU19UTykgKSk7CgkJCSAgICB9CgkJICAgIH0KCQkgICAgY2F0Y2goU1FMRXhjZXB0aW9uJikKCQkgICAgewoJCQkgICAgT1NMX0FTU0VSVCghIkZhaWx1cmUgd2hpbGUgYnVpbGRpbmcgSm9pbiBjcml0ZXJpYSEiKTsKCQkgICAgfQogICAgICAgIH0KCgkJcmV0dXJuIGFDb25kaXRpb24ubWFrZVN0cmluZ0FuZENsZWFyKCk7Cgl9CgkvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoJLyoqIEpvaW5DeWNsZSBsb29rcyBmb3IgYSBqb2luIGN5Y2xlIGFuZCBhcHBlbmQgaXQgdG8gdGhlIHN0cmluZwoJCUBwYXJhbQlfeENvbm5lY3Rpb24JdGhlIGNvbm5lY3Rpb24KCQlAcGFyYW0JX3BFbnRyeUNvbm4JCXRoZSB0YWJsZSBjb25uZWN0aW9uIHdoaWNoIGhvbGRzIHRoZSBkYXRhCgkJQHBhcmFtCV9wRW50cnlUYWJUbwl0aGUgY29ycmVzcG9uZGluZyB0YWJsZSB3aW5kb3cKCQlAcGFyYW0JX3JKb2luCQkJdGhlIFN0cmluZyB3aGljaCB3aWxsIGNvbnRhaW4gdGhlIHJlc3VsdGluZyBzdHJpbmcKCSovCgl2b2lkIEpvaW5DeWNsZSgJY29uc3QgUmVmZXJlbmNlPCBYQ29ubmVjdGlvbj4mIF94Q29ubmVjdGlvbiwKCQkJCQlPUXVlcnlUYWJsZUNvbm5lY3Rpb24qIF9wRW50cnlDb25uLAoJCQkJCWNvbnN0IE9RdWVyeVRhYmxlV2luZG93KiBfcEVudHJ5VGFiVG8sCgkJCQkJOjpydGw6Ok9VU3RyaW5nJiBfckpvaW4gKQoJewoJCU9TTF9FTlNVUkUoX3BFbnRyeUNvbm4sIlRhYmxlQ29ubmVjdGlvbiBjYW4gbm90IGJlIG51bGwhIik7CgoJCU9RdWVyeVRhYmxlQ29ubmVjdGlvbkRhdGEqIHBEYXRhID0gc3RhdGljX2Nhc3Q8IE9RdWVyeVRhYmxlQ29ubmVjdGlvbkRhdGEqPihfcEVudHJ5Q29ubi0+R2V0RGF0YSgpLmdldCgpKTsKCQlpZiAoIHBEYXRhLT5HZXRKb2luVHlwZSgpICE9IElOTkVSX0pPSU4gJiYgX3BFbnRyeVRhYlRvLT5FeGlzdHNBVmlzaXRlZENvbm4oKSApCgkJewoJCQlzYWxfQm9vbCBiQnJhY2UgPSBzYWxfRmFsc2U7CgkJCWlmKF9ySm9pbi5nZXRMZW5ndGgoKSAmJiBfckpvaW4ubGFzdEluZGV4T2YoJyknKSA9PSAoX3JKb2luLmdldExlbmd0aCgpLTEpKQoJCQl7CgkJCQliQnJhY2UgPSBzYWxfVHJ1ZTsKCQkJCV9ySm9pbiA9IF9ySm9pbi5yZXBsYWNlQXQoX3JKb2luLmdldExlbmd0aCgpLTEsMSw6OnJ0bDo6T1VTdHJpbmcoJyAnKSk7CgkJCX0KCQkJKF9ySm9pbiArPSBDX0FORCkgKz0gQnVpbGRKb2luQ3JpdGVyaWEoX3hDb25uZWN0aW9uLHBEYXRhLT5HZXRDb25uTGluZURhdGFMaXN0KCkscERhdGEpOwoJCQlpZihiQnJhY2UpCgkJCQlfckpvaW4gKz0gOjpydGw6Ok9VU3RyaW5nKCcpJyk7CgkJCV9wRW50cnlDb25uLT5TZXRWaXNpdGVkKHNhbF9UcnVlKTsKCQl9Cgl9CgkvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoJOjpydGw6Ok9VU3RyaW5nIEJ1aWxkVGFibGUoCWNvbnN0IFJlZmVyZW5jZTwgWENvbm5lY3Rpb24+JiBfeENvbm5lY3Rpb24sCgkJCQkJCQkJY29uc3QgT1F1ZXJ5VGFibGVXaW5kb3cqIHBFbnRyeVRhYiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIF9iRm9yY2UgPSBmYWxzZQoJCQkJCQkJCSkKCXsKCQk6OnJ0bDo6T1VTdHJpbmcgYURCTmFtZShwRW50cnlUYWItPkdldENvbXBvc2VkTmFtZSgpKTsKCgkJLy8JUmVmZXJlbmNlPCBYQ29ubmVjdGlvbj4geENvbm5lY3Rpb24gPSBzdGF0aWNfY2FzdDxPUXVlcnlDb250cm9sbGVyJj4oX3BWaWV3LT5nZXRDb250cm9sbGVyKCkpLmdldENvbm5lY3Rpb24oKTsKCQlpZiggX3hDb25uZWN0aW9uLmlzKCkgKQoJCXsKCQkJdHJ5CgkJCXsKCQkJCVJlZmVyZW5jZTwgWERhdGFiYXNlTWV0YURhdGEgPiAgeE1ldGFEYXRhID0gX3hDb25uZWN0aW9uLT5nZXRNZXRhRGF0YSgpOwoKICAgICAgICAgICAgICAgIDo6cnRsOjpPVVN0cmluZyBzQ2F0YWxvZywgc1NjaGVtYSwgc1RhYmxlOwogICAgICAgICAgICAgICAgOjpkYnRvb2xzOjpxdWFsaWZpZWROYW1lQ29tcG9uZW50cyggeE1ldGFEYXRhLCBhREJOYW1lLCBzQ2F0YWxvZywgc1NjaGVtYSwgc1RhYmxlLCA6OmRidG9vbHM6OmVJbkRhdGFNYW5pcHVsYXRpb24gKTsKCQkJCTo6cnRsOjpPVVN0cmluZyBhVGFibGVMaXN0U3RyID0gOjpkYnRvb2xzOjpjb21wb3NlVGFibGVOYW1lRm9yU2VsZWN0KCBfeENvbm5lY3Rpb24sIHNDYXRhbG9nLCBzU2NoZW1hLCBzVGFibGUgKTsKCgkJCQk6OnJ0bDo6T1VTdHJpbmcgYVF1b3RlID0geE1ldGFEYXRhLT5nZXRJZGVudGlmaWVyUXVvdGVTdHJpbmcoKTsKCQkJCWlmICggX2JGb3JjZSB8fCBpc0FwcGVuZFRhYmxlQWxpYXNFbmFibGVkKCBfeENvbm5lY3Rpb24gKSB8fCBwRW50cnlUYWItPkdldEFsaWFzTmFtZSgpICE9IGFEQk5hbWUgKQoJCQkJewogICAgICAgICAgICAgICAgICAgIGFUYWJsZUxpc3RTdHIgKz0gOjpydGw6Ok9VU3RyaW5nOjpjcmVhdGVGcm9tQXNjaWkoIiAiKTsKICAgICAgICAgICAgICAgICAgICBpZiAoIGdlbmVyYXRlQXNCZWZvcmVUYWJsZUFsaWFzKCBfeENvbm5lY3Rpb24gKSApCiAgICAgICAgICAgICAgICAgICAgICAgIGFUYWJsZUxpc3RTdHIgKz0gOjpydGw6Ok9VU3RyaW5nOjpjcmVhdGVGcm9tQXNjaWkoIkFTICIpOwoJCQkJCWFUYWJsZUxpc3RTdHIgKz0gOjpkYnRvb2xzOjpxdW90ZU5hbWUoIGFRdW90ZSwgcEVudHJ5VGFiLT5HZXRBbGlhc05hbWUoKSApOwoJCQkJfQoJCQkJYURCTmFtZSA9IGFUYWJsZUxpc3RTdHI7CgkJCX0KCQkJY2F0Y2goY29uc3QgU1FMRXhjZXB0aW9uJikKCQkJewogICAgICAgICAgICAgICAgREJHX1VOSEFORExFRF9FWENFUFRJT04oKTsKCQkJfQoJCX0KCQlyZXR1cm4gYURCTmFtZTsKCX0KCS8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgk6OnJ0bDo6T1VTdHJpbmcgQnVpbGRKb2luKAljb25zdCBSZWZlcmVuY2U8IFhDb25uZWN0aW9uPiYgX3hDb25uZWN0aW9uLAoJCQkJCQkJCWNvbnN0IDo6cnRsOjpPVVN0cmluZyYgckxoLAoJCQkJCQkJCWNvbnN0IDo6cnRsOjpPVVN0cmluZyYgclJoLAoJCQkJCQkJCU9RdWVyeVRhYmxlQ29ubmVjdGlvbkRhdGEqIHBEYXRhKQoJewoKCQlTdHJpbmcgYUVyZyhyTGgpOwogICAgICAgIGlmICggcERhdGEtPmlzTmF0dXJhbCgpICYmIHBEYXRhLT5HZXRKb2luVHlwZSgpICE9IENST1NTX0pPSU4gKQogICAgICAgICAgICBhRXJnLkFwcGVuZEFzY2lpKCIgTkFUVVJBTCAiKTsKCQlzd2l0Y2gocERhdGEtPkdldEpvaW5UeXBlKCkpCgkJewoJCQljYXNlIExFRlRfSk9JTjoKCQkJCWFFcmcuQXBwZW5kQXNjaWkoIiBMRUZUIE9VVEVSICIpOwoJCQkJYnJlYWs7CgkJCWNhc2UgUklHSFRfSk9JTjoKCQkJCWFFcmcuQXBwZW5kQXNjaWkoIiBSSUdIVCBPVVRFUiAiKTsKCQkJCWJyZWFrOwogICAgICAgICAgICBjYXNlIENST1NTX0pPSU46CiAgICAgICAgICAgICAgICBPU0xfRU5TVVJFKCFwRGF0YS0+aXNOYXR1cmFsKCksIk9RdWVyeURlc2lnblZpZXc6OkJ1aWxkSm9pbjogVGhpcyBzaG91bGQgbm90IGhhcHBlbiEiKTsKCQkJCWFFcmcuQXBwZW5kQXNjaWkoIiBDUk9TUyAiKTsKCQkJCWJyZWFrOwoJCQljYXNlIElOTkVSX0pPSU46CiAgICAgICAgICAgICAgICBPU0xfRU5TVVJFKHBEYXRhLT5pc05hdHVyYWwoKSwiT1F1ZXJ5RGVzaWduVmlldzo6QnVpbGRKb2luOiBUaGlzIHNob3VsZCBub3QgaGFwcGVuISIpOwoJCQkJYUVyZy5BcHBlbmRBc2NpaSgiIElOTkVSICIpOwoJCQkJYnJlYWs7CgkJCWRlZmF1bHQ6CgkJCQlhRXJnLkFwcGVuZEFzY2lpKCIgRlVMTCBPVVRFUiAiKTsKCQkJCWJyZWFrOwoJCX0KCQlhRXJnLkFwcGVuZEFzY2lpKCJKT0lOICIpOwoJCWFFcmcgKz0gU3RyaW5nKHJSaCk7CiAgICAgICAgaWYgKCBDUk9TU19KT0lOICE9IHBEYXRhLT5HZXRKb2luVHlwZSgpICYmICFwRGF0YS0+aXNOYXR1cmFsKCkgKQogICAgICAgIHsKCQkgICAgYUVyZy5BcHBlbmRBc2NpaSgiIE9OICIpOwoJCSAgICBhRXJnICs9IFN0cmluZyhCdWlsZEpvaW5Dcml0ZXJpYShfeENvbm5lY3Rpb24scERhdGEtPkdldENvbm5MaW5lRGF0YUxpc3QoKSxwRGF0YSkpOwogICAgICAgIH0KCgkJcmV0dXJuIGFFcmc7Cgl9CgkvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoJOjpydGw6Ok9VU3RyaW5nIEJ1aWxkSm9pbigJY29uc3QgUmVmZXJlbmNlPCBYQ29ubmVjdGlvbj4mIF94Q29ubmVjdGlvbiwKCQkJCQkJCQlPUXVlcnlUYWJsZVdpbmRvdyogcExoLAoJCQkJCQkJCU9RdWVyeVRhYmxlV2luZG93KiBwUmgsCgkJCQkJCQkJT1F1ZXJ5VGFibGVDb25uZWN0aW9uRGF0YSogcERhdGEKCQkJCQkJCQkpCgl7CiAgICAgICAgYm9vbCBiRm9yY2UgPSBwRGF0YS0+R2V0Sm9pblR5cGUoKSA9PSBDUk9TU19KT0lOIHx8IHBEYXRhLT5pc05hdHVyYWwoKTsKCQlyZXR1cm4gQnVpbGRKb2luKF94Q29ubmVjdGlvbixCdWlsZFRhYmxlKF94Q29ubmVjdGlvbixwTGgsYkZvcmNlKSxCdWlsZFRhYmxlKF94Q29ubmVjdGlvbixwUmgsYkZvcmNlKSxwRGF0YSk7Cgl9CgkvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoJOjpydGw6Ok9VU3RyaW5nIEJ1aWxkSm9pbigJY29uc3QgUmVmZXJlbmNlPCBYQ29ubmVjdGlvbj4mIF94Q29ubmVjdGlvbiwKCQkJCQkJCQljb25zdCA6OnJ0bDo6T1VTdHJpbmcgJnJMaCwKCQkJCQkJCQlPUXVlcnlUYWJsZVdpbmRvdyogcFJoLAoJCQkJCQkJCU9RdWVyeVRhYmxlQ29ubmVjdGlvbkRhdGEqIHBEYXRhCgkJCQkJCQkJKQoJewoJCXJldHVybiBCdWlsZEpvaW4oX3hDb25uZWN0aW9uLHJMaCxCdWlsZFRhYmxlKF94Q29ubmVjdGlvbixwUmgpLHBEYXRhKTsKCX0KCS8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgk6OnJ0bDo6T1VTdHJpbmcgQnVpbGRKb2luKAljb25zdCBSZWZlcmVuY2U8IFhDb25uZWN0aW9uPiYgX3hDb25uZWN0aW9uLAoJCQkJCQkJCU9RdWVyeVRhYmxlV2luZG93KiBwTGgsCgkJCQkJCQkJY29uc3QgOjpydGw6Ok9VU3RyaW5nICZyUmgsCgkJCQkJCQkJT1F1ZXJ5VGFibGVDb25uZWN0aW9uRGF0YSogcERhdGEKCQkJCQkJCQkpCgl7CgkJcmV0dXJuIEJ1aWxkSm9pbihfeENvbm5lY3Rpb24sQnVpbGRUYWJsZShfeENvbm5lY3Rpb24scExoKSxyUmgscERhdGEpOwoJfQoJLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCXZvaWQgR2V0TmV4dEpvaW4oCWNvbnN0IFJlZmVyZW5jZTwgWENvbm5lY3Rpb24+JiBfeENvbm5lY3Rpb24sCgkJCQkJCU9RdWVyeVRhYmxlQ29ubmVjdGlvbiogcEVudHJ5Q29ubiwKCQkJCQkJT1F1ZXJ5VGFibGVXaW5kb3cqIHBFbnRyeVRhYlRvLAoJCQkJCQk6OnJ0bDo6T1VTdHJpbmcgJmFKb2luKQoJewoJCU9RdWVyeVRhYmxlQ29ubmVjdGlvbkRhdGEqIHBFbnRyeUNvbm5EYXRhID0gc3RhdGljX2Nhc3Q8T1F1ZXJ5VGFibGVDb25uZWN0aW9uRGF0YSo+KHBFbnRyeUNvbm4tPkdldERhdGEoKS5nZXQoKSk7CiAgICAgICAgaWYgKCBwRW50cnlDb25uRGF0YS0+R2V0Sm9pblR5cGUoKSA9PSBJTk5FUl9KT0lOICYmICFwRW50cnlDb25uRGF0YS0+aXNOYXR1cmFsKCkgKQoJCQlyZXR1cm47CgoJCS8vCVJlZmVyZW5jZTwgWENvbm5lY3Rpb24+IHhDb25uZWN0aW9uID0gc3RhdGljX2Nhc3Q8T1F1ZXJ5Q29udHJvbGxlciY+KF9wVmlldy0+Z2V0Q29udHJvbGxlcigpKS5nZXRDb25uZWN0aW9uKCk7CgoJCWlmKCFhSm9pbi5nZXRMZW5ndGgoKSkKCQl7CgkJCU9RdWVyeVRhYmxlV2luZG93KiBwRW50cnlUYWJGcm9tID0gc3RhdGljX2Nhc3Q8T1F1ZXJ5VGFibGVXaW5kb3cqPihwRW50cnlDb25uLT5HZXRTb3VyY2VXaW4oKSk7CgkJCWFKb2luID0gQnVpbGRKb2luKF94Q29ubmVjdGlvbixwRW50cnlUYWJGcm9tLHBFbnRyeVRhYlRvLHBFbnRyeUNvbm5EYXRhKTsKCQl9CgkJZWxzZSBpZihwRW50cnlUYWJUbyA9PSBwRW50cnlDb25uLT5HZXREZXN0V2luKCkpCgkJewoJCQlhSm9pbiA9IEJ1aWxkSm9pbihfeENvbm5lY3Rpb24sYUpvaW4scEVudHJ5VGFiVG8scEVudHJ5Q29ubkRhdGEpOwoJCX0KCQllbHNlIGlmKHBFbnRyeVRhYlRvID09IHBFbnRyeUNvbm4tPkdldFNvdXJjZVdpbigpKQoJCXsKCQkJYUpvaW4gPSBCdWlsZEpvaW4oX3hDb25uZWN0aW9uLHBFbnRyeVRhYlRvLGFKb2luLHBFbnRyeUNvbm5EYXRhKTsKCQl9CgoJCXBFbnRyeUNvbm4tPlNldFZpc2l0ZWQoc2FsX1RydWUpOwoKCQkvLyBmaXJzdCBzZWFyY2ggZm9yIHRoZSAidG8iIHdpbmRvdwoJCWNvbnN0IDo6c3RkOjp2ZWN0b3I8T1RhYmxlQ29ubmVjdGlvbio+KiBwQ29ubmVjdGlvbnMgPSBwRW50cnlDb25uLT5HZXRQYXJlbnQoKS0+Z2V0VGFibGVDb25uZWN0aW9ucygpOwoJCTo6c3RkOjp2ZWN0b3I8T1RhYmxlQ29ubmVjdGlvbio+Ojpjb25zdF9pdGVyYXRvciBhSXRlciA9IHBDb25uZWN0aW9ucy0+YmVnaW4oKTsKICAgICAgICA6OnN0ZDo6dmVjdG9yPE9UYWJsZUNvbm5lY3Rpb24qPjo6Y29uc3RfaXRlcmF0b3IgYUVuZCA9IHBDb25uZWN0aW9ucy0+ZW5kKCk7CgkJZm9yKDthSXRlciAhPSBhRW5kOysrYUl0ZXIpCgkJewoJCQlPUXVlcnlUYWJsZUNvbm5lY3Rpb24qIHBOZXh0ID0gc3RhdGljX2Nhc3Q8T1F1ZXJ5VGFibGVDb25uZWN0aW9uKj4oKmFJdGVyKTsKCQkJaWYoIXBOZXh0LT5Jc1Zpc2l0ZWQoKSAmJiAocE5leHQtPkdldFNvdXJjZVdpbigpID09IHBFbnRyeVRhYlRvIHx8IHBOZXh0LT5HZXREZXN0V2luKCkgPT0gcEVudHJ5VGFiVG8pKQoJCQl7CgkJCQlPUXVlcnlUYWJsZVdpbmRvdyogcEVudHJ5VGFiID0gcE5leHQtPkdldFNvdXJjZVdpbigpID09IHBFbnRyeVRhYlRvID8gc3RhdGljX2Nhc3Q8T1F1ZXJ5VGFibGVXaW5kb3cqPihwTmV4dC0+R2V0RGVzdFdpbigpKSA6IHN0YXRpY19jYXN0PE9RdWVyeVRhYmxlV2luZG93Kj4ocE5leHQtPkdldFNvdXJjZVdpbigpKTsKCQkJCS8vIGV4aXN0cyB0aGVyZSBhIGNvbm5lY3Rpb24gdG8gYSBPUXVlcnlUYWJsZVdpbmRvdyB0aGF0IGhvbGRzIGEgY29ubmVjdGlvbiB0aGF0IGhhcyBiZWVuIGFscmVhZHkgdmlzaXRlZAoJCQkJSm9pbkN5Y2xlKF94Q29ubmVjdGlvbixwTmV4dCxwRW50cnlUYWIsYUpvaW4pOwoJCQkJaWYoIXBOZXh0LT5Jc1Zpc2l0ZWQoKSkKCQkJCQlHZXROZXh0Sm9pbihfeENvbm5lY3Rpb24scE5leHQscEVudHJ5VGFiLGFKb2luKTsKCQkJfQoJCX0KCgkJLy8gd2hlbiBub3RoaW5nIGZvdW5kIGZvdW5kIGxvb2sgZm9yIHRoZSAiZnJvbSIgd2luZG93CgkJaWYoYUl0ZXIgPT0gYUVuZCkKCQl7CgkJCU9RdWVyeVRhYmxlV2luZG93KiBwRW50cnlUYWJGcm9tID0gc3RhdGljX2Nhc3Q8T1F1ZXJ5VGFibGVXaW5kb3cqPihwRW50cnlDb25uLT5HZXRTb3VyY2VXaW4oKSk7CgkJCWFJdGVyID0gcENvbm5lY3Rpb25zLT5iZWdpbigpOwoJCQlmb3IoO2FJdGVyICE9IGFFbmQ7KythSXRlcikKCQkJewoJCQkJT1F1ZXJ5VGFibGVDb25uZWN0aW9uKiBwTmV4dCA9IHN0YXRpY19jYXN0PE9RdWVyeVRhYmxlQ29ubmVjdGlvbio+KCphSXRlcik7CgkJCQlpZighcE5leHQtPklzVmlzaXRlZCgpICYmIChwTmV4dC0+R2V0U291cmNlV2luKCkgPT0gcEVudHJ5VGFiRnJvbSB8fCBwTmV4dC0+R2V0RGVzdFdpbigpID09IHBFbnRyeVRhYkZyb20pKQoJCQkJewoJCQkJCU9RdWVyeVRhYmxlV2luZG93KiBwRW50cnlUYWIgPSBwTmV4dC0+R2V0U291cmNlV2luKCkgPT0gcEVudHJ5VGFiRnJvbSA/IHN0YXRpY19jYXN0PE9RdWVyeVRhYmxlV2luZG93Kj4ocE5leHQtPkdldERlc3RXaW4oKSkgOiBzdGF0aWNfY2FzdDxPUXVlcnlUYWJsZVdpbmRvdyo+KHBOZXh0LT5HZXRTb3VyY2VXaW4oKSk7CgkJCQkJLy8gZXhpc3RzIHRoZXJlIGEgY29ubmVjdGlvbiB0byBhIE9RdWVyeVRhYmxlV2luZG93IHRoYXQgaG9sZHMgYSBjb25uZWN0aW9uIHRoYXQgaGFzIGJlZW4gYWxyZWFkeSB2aXNpdGVkCgkJCQkJSm9pbkN5Y2xlKF94Q29ubmVjdGlvbixwTmV4dCxwRW50cnlUYWIsYUpvaW4pOwoJCQkJCWlmKCFwTmV4dC0+SXNWaXNpdGVkKCkpCgkJCQkJCUdldE5leHRKb2luKF94Q29ubmVjdGlvbixwTmV4dCxwRW50cnlUYWIsYUpvaW4pOwoJCQkJfQoJCQl9CgkJfQoJfQoJLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCVNxbFBhcnNlRXJyb3IgSW5zZXJ0Sm9pbkNvbm5lY3Rpb24oCWNvbnN0IE9RdWVyeURlc2lnblZpZXcqIF9wVmlldywKCQkJCQkJCQkJY29uc3QgOjpjb25uZWN0aXZpdHk6Ok9TUUxQYXJzZU5vZGUgKnBOb2RlLAoJCQkJCQkJCQljb25zdCBFSm9pblR5cGUmIF9lSm9pblR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IDo6Y29ubmVjdGl2aXR5OjpPU1FMUGFyc2VOb2RlICpwTGVmdFRhYmxlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCA6OmNvbm5lY3Rpdml0eTo6T1NRTFBhcnNlTm9kZSAqcFJpZ2h0VGFibGUpCgl7CgkJU3FsUGFyc2VFcnJvciBlRXJyb3JDb2RlID0gZU9rOwoJCWlmIChwTm9kZS0+Y291bnQoKSA9PSAzICYmCS8vIEF1c2RydWNrIGlzIGdla2xhbW1lcnQKCQkJU1FMX0lTUFVOQ1RVQVRJT04ocE5vZGUtPmdldENoaWxkKDApLCIoIikgJiYKCQkJU1FMX0lTUFVOQ1RVQVRJT04ocE5vZGUtPmdldENoaWxkKDIpLCIpIikpCgkJewoJCQllRXJyb3JDb2RlID0gSW5zZXJ0Sm9pbkNvbm5lY3Rpb24oX3BWaWV3LHBOb2RlLT5nZXRDaGlsZCgxKSwgX2VKb2luVHlwZSxwTGVmdFRhYmxlLHBSaWdodFRhYmxlKTsKCQl9CgkJZWxzZSBpZiAoU1FMX0lTUlVMRU9SMihwTm9kZSxzZWFyY2hfY29uZGl0aW9uLGJvb2xlYW5fdGVybSkJJiYJCQkvLyBBTkQvT1ItVmVya251ZXBmdW5nOgoJCQkJIHBOb2RlLT5jb3VudCgpID09IDMpCgkJewoJCQkvLyBudXIgQU5EIFZlcmtu/HBmdW5nIHp1bGFzc2VuCgkJCWlmICghU1FMX0lTVE9LRU4ocE5vZGUtPmdldENoaWxkKDEpLEFORCkpCgkJCQllRXJyb3JDb2RlID0gZUlsbGVnYWxKb2luQ29uZGl0aW9uOwoJCQllbHNlIGlmICggZU9rID09IChlRXJyb3JDb2RlID0gSW5zZXJ0Sm9pbkNvbm5lY3Rpb24oX3BWaWV3LHBOb2RlLT5nZXRDaGlsZCgwKSwgX2VKb2luVHlwZSxwTGVmdFRhYmxlLHBSaWdodFRhYmxlKSkgKQoJCQkJCWVFcnJvckNvZGUgPSBJbnNlcnRKb2luQ29ubmVjdGlvbihfcFZpZXcscE5vZGUtPmdldENoaWxkKDIpLCBfZUpvaW5UeXBlLHBMZWZ0VGFibGUscFJpZ2h0VGFibGUpOwoJCX0KCQllbHNlIGlmIChTUUxfSVNSVUxFKHBOb2RlLGNvbXBhcmlzb25fcHJlZGljYXRlKSkKCQl7CgkJCS8vIG9ubHkgdGhlIGNvbXBhcmlzb24gb2YgY29sdW1ucyBpcyBhbGxvd2VkCgkJCURCR19BU1NFUlQocE5vZGUtPmNvdW50KCkgPT0gMywiT1F1ZXJ5RGVzaWduVmlldzo6SW5zZXJ0Sm9pbkNvbm5lY3Rpb246IEZlaGxlciBpbSBQYXJzZSBUcmVlIik7CgkJCWlmICghKFNRTF9JU1JVTEUocE5vZGUtPmdldENoaWxkKDApLGNvbHVtbl9yZWYpICYmCgkJCQkgIFNRTF9JU1JVTEUocE5vZGUtPmdldENoaWxkKDIpLGNvbHVtbl9yZWYpICYmCgkJCQkgICBwTm9kZS0+Z2V0Q2hpbGQoMSktPmdldE5vZGVUeXBlKCkgPT0gU1FMX05PREVfRVFVQUwpKQoJCQl7CgkJCQlTdHJpbmcgc0Vycm9yKE1vZHVsZVJlcyhTVFJfUVJZX0pPSU5fQ09MVU1OX0NPTVBBUkUpKTsKCQkJCV9wVmlldy0+Z2V0Q29udHJvbGxlcigpLmFwcGVuZEVycm9yKCBzRXJyb3IgKTsKCQkJCXJldHVybiBlSWxsZWdhbEpvaW47CgkJCX0KCgkJCU9UYWJsZUZpZWxkRGVzY1JlZiBhRHJhZ0xlZnQgID0gbmV3IE9UYWJsZUZpZWxkRGVzYygpOwoJCQlPVGFibGVGaWVsZERlc2NSZWYgYURyYWdSaWdodCA9IG5ldyBPVGFibGVGaWVsZERlc2MoKTsKCQkJaWYgKCBlT2sgIT0gKCBlRXJyb3JDb2RlID0gRmlsbERyYWdJbmZvKF9wVmlldyxwTm9kZS0+Z2V0Q2hpbGQoMCksYURyYWdMZWZ0KSkgfHwKCQkJCWVPayAhPSAoIGVFcnJvckNvZGUgPSBGaWxsRHJhZ0luZm8oX3BWaWV3LHBOb2RlLT5nZXRDaGlsZCgyKSxhRHJhZ1JpZ2h0KSkpCgkJCQlyZXR1cm4gZUVycm9yQ29kZTsKCiAgICAgICAgICAgIGlmICggcExlZnRUYWJsZSApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIE9RdWVyeVRhYmxlV2luZG93KglwTGVmdFdpbmRvdyA9IHN0YXRpY19jYXN0PE9RdWVyeVRhYmxlVmlldyo+KF9wVmlldy0+Z2V0VGFibGVWaWV3KCkpLT5GaW5kVGFibGUoIGdldFRhYmxlUmFuZ2UoX3BWaWV3LHBMZWZ0VGFibGUtPmdldEJ5UnVsZShPU1FMUGFyc2VOb2RlOjp0YWJsZV9yZWYpICkpOwogICAgICAgICAgICAgICAgLy8gT1F1ZXJ5VGFibGVXaW5kb3cqCXBSaWdodFdpbmRvdyA9IHN0YXRpY19jYXN0PE9RdWVyeVRhYmxlVmlldyo+KF9wVmlldy0+Z2V0VGFibGVWaWV3KCkpLT5GaW5kVGFibGUoIGdldFRhYmxlUmFuZ2UoX3BWaWV3LHBSaWdodFRhYmxlLT5nZXRCeVJ1bGUoT1NRTFBhcnNlTm9kZTo6dGFibGVfcmVmKSApKTsKICAgICAgICAgICAgICAgIGlmICggcExlZnRXaW5kb3cgPT0gYURyYWdMZWZ0LT5HZXRUYWJXaW5kb3coKSApCiAgICAgICAgICAgICAgICAgICAgaW5zZXJ0Q29ubmVjdGlvbihfcFZpZXcsX2VKb2luVHlwZSxhRHJhZ0xlZnQsYURyYWdSaWdodCk7CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgaW5zZXJ0Q29ubmVjdGlvbihfcFZpZXcsX2VKb2luVHlwZSxhRHJhZ1JpZ2h0LGFEcmFnTGVmdCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgaW5zZXJ0Q29ubmVjdGlvbihfcFZpZXcsX2VKb2luVHlwZSxhRHJhZ0xlZnQsYURyYWdSaWdodCk7CgkJfQoJCWVsc2UKCQkJZUVycm9yQ29kZSA9IGVJbGxlZ2FsSm9pbjsKCQlyZXR1cm4gZUVycm9yQ29kZTsKCX0KCS8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCglzYWxfQm9vbCBHZXRJbm5lckpvaW5Dcml0ZXJpYSgJY29uc3QgT1F1ZXJ5RGVzaWduVmlldyogX3BWaWV3LAoJCQkJCQkJCQljb25zdCA6OmNvbm5lY3Rpdml0eTo6T1NRTFBhcnNlTm9kZSAqcENvbmRpdGlvbikKCXsKCQlyZXR1cm4gSW5zZXJ0Sm9pbkNvbm5lY3Rpb24oX3BWaWV3LHBDb25kaXRpb24sIElOTkVSX0pPSU4sTlVMTCxOVUxMKSAhPSBlT2s7Cgl9CgkvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoJOjpydGw6Ok9VU3RyaW5nIEdlbmVyYXRlU2VsZWN0TGlzdCgJY29uc3QgT1F1ZXJ5RGVzaWduVmlldyogX3BWaWV3LAoJCQkJCQkJCQkJT1RhYmxlRmllbGRzJglfckZpZWxkTGlzdCwKCQkJCQkJCQkJCXNhbF9Cb29sIGJBbGlhcykKCXsKICAgICAgICBSZWZlcmVuY2U8IFhDb25uZWN0aW9uPiB4Q29ubmVjdGlvbiA9IHN0YXRpY19jYXN0PE9RdWVyeUNvbnRyb2xsZXImPihfcFZpZXctPmdldENvbnRyb2xsZXIoKSkuZ2V0Q29ubmVjdGlvbigpOwoJCWlmICggIXhDb25uZWN0aW9uLmlzKCkgKQoJCQlyZXR1cm4gOjpydGw6Ok9VU3RyaW5nKCk7CgoJCTo6cnRsOjpPVVN0cmluZ0J1ZmZlciBhVG1wU3RyLGFGaWVsZExpc3RTdHI7CgoJCXNhbF9Cb29sIGJBc3Rlcml4ID0gc2FsX0ZhbHNlOwoJCWludCBuVmlzID0gMDsKCQlPVGFibGVGaWVsZHM6Oml0ZXJhdG9yIGFJdGVyID0gX3JGaWVsZExpc3QuYmVnaW4oKTsKICAgICAgICBPVGFibGVGaWVsZHM6Oml0ZXJhdG9yIGFFbmQgPSBfckZpZWxkTGlzdC5lbmQoKTsKCQlmb3IoO2FJdGVyICE9IGFFbmQ7KythSXRlcikKCQl7CgkJCU9UYWJsZUZpZWxkRGVzY1JlZiBwRW50cnlGaWVsZCA9ICphSXRlcjsKCQkJaWYgKCBwRW50cnlGaWVsZC0+SXNWaXNpYmxlKCkgKQoJCQl7CgkJCQlpZiAoIHBFbnRyeUZpZWxkLT5HZXRGaWVsZCgpLnRvQ2hhcigpID09ICcqJyApCgkJCQkJYkFzdGVyaXggPSBzYWxfVHJ1ZTsKCQkJCSsrblZpczsKCQkJfQoJCX0KCQlpZihuVmlzID09IDEpCgkJCWJBc3Rlcml4ID0gc2FsX0ZhbHNlOwoKCQl0cnkKCQl7CgkJCWNvbnN0IFJlZmVyZW5jZTwgWERhdGFiYXNlTWV0YURhdGEgPiAgeE1ldGFEYXRhID0geENvbm5lY3Rpb24tPmdldE1ldGFEYXRhKCk7CgkJCWNvbnN0IDo6cnRsOjpPVVN0cmluZyBhUXVvdGUgPSB4TWV0YURhdGEtPmdldElkZW50aWZpZXJRdW90ZVN0cmluZygpOwoKCQkJT0pvaW5UYWJsZVZpZXc6Ok9UYWJsZVdpbmRvd01hcCogcFRhYkxpc3QgPSBfcFZpZXctPmdldFRhYmxlVmlldygpLT5HZXRUYWJXaW5NYXAoKTsKCgkJCWNvbnN0IHN0YXRpYyA6OnJ0bDo6T1VTdHJpbmcgc0ZpZWxkU2VwYXJhdG9yKFJUTF9DT05TVEFTQ0lJX1VTVFJJTkdQQVJBTSgiLCAiKSk7CiAgICAgICAgICAgIGNvbnN0IHN0YXRpYyA6OnJ0bDo6T1VTdHJpbmcgc19zQXMoUlRMX0NPTlNUQVNDSUlfVVNUUklOR1BBUkFNKCIgQVMgIikpOwoKCQkJYUl0ZXIgPSBfckZpZWxkTGlzdC5iZWdpbigpOwoJCSAgICBmb3IoO2FJdGVyICE9IGFFbmQ7KythSXRlcikKCQkJewoJCQkJT1RhYmxlRmllbGREZXNjUmVmIHBFbnRyeUZpZWxkID0gKmFJdGVyOwoJCQkJOjpydGw6Ok9VU3RyaW5nIHJGaWVsZE5hbWUgPSBwRW50cnlGaWVsZC0+R2V0RmllbGQoKTsKCQkJCWlmICggckZpZWxkTmFtZS5nZXRMZW5ndGgoKSAmJiBwRW50cnlGaWVsZC0+SXNWaXNpYmxlKCkgKQoJCQkJewoJCQkJCWFUbXBTdHIgPSA6OnJ0bDo6T1VTdHJpbmcoKTsKCQkJCQljb25zdCA6OnJ0bDo6T1VTdHJpbmcgckFsaWFzID0gcEVudHJ5RmllbGQtPkdldEFsaWFzKCk7CgkJCQkJY29uc3QgOjpydGw6Ok9VU3RyaW5nIHJGaWVsZEFsaWFzID0gcEVudHJ5RmllbGQtPkdldEZpZWxkQWxpYXMoKTsKCgkJCQkJYVRtcFN0ci5hcHBlbmQocXVvdGVUYWJsZUFsaWFzKChiQWxpYXMgfHwgYkFzdGVyaXgpLHJBbGlhcyxhUXVvdGUpKTsKCgkJCQkJLy8gaWYgd2UgaGF2ZSBhIG5vbmUgbnVtZXJpYyBmaWVsZCwgdGhlIHRhYmxlIGFsaWFzIGNvdWxkIGJlIGluIHRoZSBuYW1lCgkJCQkJLy8gb3RoZXJ3aXNlIHdlIGFyZSBub3QgYWxsb3dlZCB0byBkbyB0aGlzIChlLmcuIDAuMSAqIFBSSUNFICkKCQkJCQlpZiAgKCAhcEVudHJ5RmllbGQtPmlzT3RoZXJGdW5jdGlvbigpICkKCQkJCQl7CgkJCQkJCS8vIHdlIGhhdmUgdG8gbG9vayBpZiB3ZSBoYXZlIGFsaWFzLiogaGVyZSBidXQgYmVmb3JlIHdlIGhhdmUgdG8gY2hlY2sgaWYgdGhlIGNvbHVtbiBkb2Vzbid0IGFscmVhZHkgZXhpc3QKCQkJCQkJU3RyaW5nIHNUZW1wID0gckZpZWxkTmFtZTsKCQkJCQkJT1RhYmxlRmllbGREZXNjUmVmCWFJbmZvID0gbmV3IE9UYWJsZUZpZWxkRGVzYygpOwoJCQkJCQlPSm9pblRhYmxlVmlldzo6T1RhYmxlV2luZG93TWFwOjppdGVyYXRvciB0YWJsZUl0ZXIgPSBwVGFiTGlzdC0+YmVnaW4oKTsKICAgICAgICAgICAgICAgICAgICAgICAgT0pvaW5UYWJsZVZpZXc6Ok9UYWJsZVdpbmRvd01hcDo6aXRlcmF0b3IgdGFibGVFbmQgPSBwVGFiTGlzdC0+ZW5kKCk7CgkJCQkJCXNhbF9Cb29sIGJGb3VuZCA9IHNhbF9GYWxzZTsKCQkJCQkJZm9yKDshYkZvdW5kICYmIHRhYmxlSXRlciAhPSB0YWJsZUVuZCA7Kyt0YWJsZUl0ZXIpCgkJCQkJCXsKCQkJCQkJCU9RdWVyeVRhYmxlV2luZG93KiBwVGFiV2luID0gc3RhdGljX2Nhc3Q8T1F1ZXJ5VGFibGVXaW5kb3cqPih0YWJsZUl0ZXItPnNlY29uZCk7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgYkZvdW5kID0gcFRhYldpbi0+RXhpc3RzRmllbGQoIHJGaWVsZE5hbWUsIGFJbmZvICk7CgkJCQkJCQlpZiAoIGJGb3VuZCApCgkJCQkJCQkJckZpZWxkTmFtZSA9IGFJbmZvLT5HZXRGaWVsZCgpOwoJCQkJCQl9CgkJCQkJCWlmICggKCByRmllbGROYW1lLnRvQ2hhcigpICE9ICcqJyApICYmICggckZpZWxkTmFtZS5pbmRleE9mKCBhUXVvdGUgKSA9PSAtMSApICkKCQkJCQkJewoJCQkJCQkJT1NMX0VOU1VSRShwRW50cnlGaWVsZC0+R2V0VGFibGUoKS5nZXRMZW5ndGgoKSwiTm8gdGFibGUgZmllbGQgbmFtZSEiKTsKCQkJCQkJCWFUbXBTdHIuYXBwZW5kKDo6ZGJ0b29sczo6cXVvdGVOYW1lKGFRdW90ZSwgckZpZWxkTmFtZSkpOwoJCQkJCQl9CgkJCQkJCWVsc2UKCQkJCQkJCWFUbXBTdHIuYXBwZW5kKHJGaWVsZE5hbWUpOwoJCQkJCX0KCQkJCQllbHNlCgkJCQkJCWFUbXBTdHIuYXBwZW5kKHJGaWVsZE5hbWUpOwoKCQkJCQlpZiAgKCBwRW50cnlGaWVsZC0+aXNBZ2dyZWF0ZUZ1bmN0aW9uKCkgKQoJCQkJCXsKCQkJCQkJREJHX0FTU0VSVChwRW50cnlGaWVsZC0+R2V0RnVuY3Rpb24oKS5nZXRMZW5ndGgoKSwiRnVuY3Rpb25uYW1lIGRhcmYgaGllciBuaWNodCBsZWVyIHNlaW4hIDstKCIpOwoJCQkJCQk6OnJ0bDo6T1VTdHJpbmdCdWZmZXIgYVRtcFN0cjIoIHBFbnRyeUZpZWxkLT5HZXRGdW5jdGlvbigpKTsKCQkJCQkJYVRtcFN0cjIuYXBwZW5kQXNjaWkoIigiKTsKCQkJCQkJYVRtcFN0cjIuYXBwZW5kKGFUbXBTdHIubWFrZVN0cmluZ0FuZENsZWFyKCkpOwoJCQkJCQlhVG1wU3RyMi5hcHBlbmRBc2NpaSgiKSIpOwoJCQkJCQlhVG1wU3RyID0gYVRtcFN0cjI7CgkJCQkJfQoKCQkJCQlpZiAockZpZWxkQWxpYXMuZ2V0TGVuZ3RoKCkJCQkJCQkJJiYKCQkJCQkJKHJGaWVsZE5hbWUudG9DaGFyKCkgIT0gJyonCQkJCQkJfHwKCQkJCQkJcEVudHJ5RmllbGQtPmlzTnVtZXJpY09yQWdncmVhdGVGdW5jdGlvbigpCQl8fAoJCQkJCQlwRW50cnlGaWVsZC0+aXNPdGhlckZ1bmN0aW9uKCkpKQoJCQkJCXsKCQkJCQkJYVRtcFN0ci5hcHBlbmQoc19zQXMpOwoJCQkJCQlhVG1wU3RyLmFwcGVuZCg6OmRidG9vbHM6OnF1b3RlTmFtZShhUXVvdGUsIHJGaWVsZEFsaWFzKSk7CgkJCQkJfQoJCQkJCWFGaWVsZExpc3RTdHIuYXBwZW5kKGFUbXBTdHIubWFrZVN0cmluZ0FuZENsZWFyKCkpOwoJCQkJCWFGaWVsZExpc3RTdHIuYXBwZW5kKHNGaWVsZFNlcGFyYXRvcik7CgkJCQl9CgkJCX0KCQkJaWYoYUZpZWxkTGlzdFN0ci5nZXRMZW5ndGgoKSkKCQkJCWFGaWVsZExpc3RTdHIuc2V0TGVuZ3RoKGFGaWVsZExpc3RTdHIuZ2V0TGVuZ3RoKCktMik7CgkJfQoJCWNhdGNoKFNRTEV4Y2VwdGlvbiYpCgkJewoJCQlPU0xfQVNTRVJUKCEiRmFpbHVyZSB3aGlsZSBidWlsZGluZyBzZWxlY3QgbGlzdCEiKTsKCQl9CgkJcmV0dXJuIGFGaWVsZExpc3RTdHIubWFrZVN0cmluZ0FuZENsZWFyKCk7Cgl9CgkvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoJc2FsX0Jvb2wgR2VuZXJhdGVDcml0ZXJpYXMoCU9RdWVyeURlc2lnblZpZXcqIF9wVmlldywKCQkJCQkJCQk6OnJ0bDo6T1VTdHJpbmdCdWZmZXImIHJSZXRTdHIsCgkJCQkJCQkJOjpydGw6Ok9VU3RyaW5nQnVmZmVyJiBySGF2aW5nU3RyLAoJCQkJCQkJCU9UYWJsZUZpZWxkcyYgX3JGaWVsZExpc3QsCgkJCQkJCQkJc2FsX0Jvb2wgYk11bHRpICkKCXsKCQkvLyAqIGRhcmYga2VpbmUgRmlsdGVyIGVudGhhbHRlbiA6IGhhYmUgaWNoIGRpZSBlbnRzcHJlY2hlbmRlIFdhcm51bmcgc2Nob24gYW5nZXplaWd0ID8KCQlzYWxfQm9vbCBiQ3JpdHNPbkFzdGVyaWtXYXJuaW5nID0gc2FsX0ZhbHNlOwkJLy8gKiogVE1GUyAqKgoKCQk6OnJ0bDo6T1VTdHJpbmcgYUZpZWxkTmFtZSxhQ3JpdGVyaWEsYVdoZXJlU3RyLGFIYXZpbmdTdHIsYVdvcmsvKixhT3JkZXJTdHIqLzsKCQkvLyBaZWlsZW53ZWlzZSB3ZXJkZW4gZGllIEF1c2RyInVja2UgbWl0IEFORCB2ZXJrbnVlcGZ0CgkJc2FsX3VJbnQxNiBuTWF4Q3JpdGVyaWEgPSAwOwoJCU9UYWJsZUZpZWxkczo6aXRlcmF0b3IgYUl0ZXIgPSBfckZpZWxkTGlzdC5iZWdpbigpOwoJCU9UYWJsZUZpZWxkczo6aXRlcmF0b3IgYUVuZCA9IF9yRmllbGRMaXN0LmVuZCgpOwoJCWZvcig7YUl0ZXIgIT0gYUVuZDsrK2FJdGVyKQoJCXsKCQkJbk1heENyaXRlcmlhID0gOjpzdGQ6Om1heDxzYWxfdUludDE2PihuTWF4Q3JpdGVyaWEsKHNhbF91SW50MTYpKCphSXRlciktPkdldENyaXRlcmlhKCkuc2l6ZSgpKTsKCQl9CgkJUmVmZXJlbmNlPCBYQ29ubmVjdGlvbj4geENvbm5lY3Rpb24gPSBzdGF0aWNfY2FzdDxPUXVlcnlDb250cm9sbGVyJj4oX3BWaWV3LT5nZXRDb250cm9sbGVyKCkpLmdldENvbm5lY3Rpb24oKTsKCQlpZigheENvbm5lY3Rpb24uaXMoKSkKCQkJcmV0dXJuIHNhbF9GYWxzZTsKCQl0cnkKCQl7CgkJCWNvbnN0IFJlZmVyZW5jZTwgWERhdGFiYXNlTWV0YURhdGEgPiAgeE1ldGFEYXRhID0geENvbm5lY3Rpb24tPmdldE1ldGFEYXRhKCk7CgkJCWNvbnN0IDo6cnRsOjpPVVN0cmluZyBhUXVvdGUgPSB4TWV0YURhdGEtPmdldElkZW50aWZpZXJRdW90ZVN0cmluZygpOwoJCQljb25zdCBJUGFyc2VDb250ZXh0JiByQ29udGV4dCA9IHN0YXRpY19jYXN0PE9RdWVyeUNvbnRyb2xsZXImPihfcFZpZXctPmdldENvbnRyb2xsZXIoKSkuZ2V0UGFyc2VyKCkuZ2V0Q29udGV4dCgpOwoKCQkJZm9yIChzYWxfdUludDE2IGk9MCA7IGkgPCBuTWF4Q3JpdGVyaWEgOyBpKyspCgkJCXsKCQkJCWFIYXZpbmdTdHIgPSBhV2hlcmVTdHIgPSA6OnJ0bDo6T1VTdHJpbmcoKTsKCgkJCQlmb3IoYUl0ZXIgPSBfckZpZWxkTGlzdC5iZWdpbigpO2FJdGVyICE9IGFFbmQ7KythSXRlcikKCQkJCXsKCQkJCQlPVGFibGVGaWVsZERlc2NSZWYJcEVudHJ5RmllbGQgPSAqYUl0ZXI7CgkJCQkJYUZpZWxkTmFtZSA9IHBFbnRyeUZpZWxkLT5HZXRGaWVsZCgpOwoKCQkJCQlpZiAoIWFGaWVsZE5hbWUuZ2V0TGVuZ3RoKCkpCgkJCQkJCWNvbnRpbnVlOwoJCQkJCWFDcml0ZXJpYSA9IHBFbnRyeUZpZWxkLT5HZXRDcml0ZXJpYSggaSApOwoJCQkJCWlmICggYUNyaXRlcmlhLmdldExlbmd0aCgpICkKCQkJCQl7CgkJCQkJCS8vICogaXMgbm90IGFsbG93ZWQgdG8gY29udGFpbiBhbnkgZmlsdGVyLCBvbmx5IHdoZW4gdXNlZCBpbiBjb21iaW5hdGlvbiBhbiBhZ2dyZWdhdGUgZnVuY3Rpb24KCQkJCQkJaWYgKCBhRmllbGROYW1lLnRvQ2hhcigpID09ICcqJyAmJiBwRW50cnlGaWVsZC0+aXNOb25lRnVuY3Rpb24oKSApCgkJCQkJCXsKCQkJCQkJCS8vIG9ubHkgc2hvdyB0aGUgbWVzc2FnZWJveCB0aGUgZmlyc3QgdGltZQoJCQkJCQkJaWYgKCFiQ3JpdHNPbkFzdGVyaWtXYXJuaW5nKQoJCQkJCQkJCUVycm9yQm94KF9wVmlldywgTW9kdWxlUmVzKCBFUlJfUVJZX0NSSVRFUklBX09OX0FTVEVSSVNLKSkuRXhlY3V0ZSgpOwoJCQkJCQkJYkNyaXRzT25Bc3RlcmlrV2FybmluZyA9IHNhbF9UcnVlOwoJCQkJCQkJY29udGludWU7CgkJCQkJCX0KCQkJCQkJYVdvcmsgPSA6OnJ0bDo6T1VTdHJpbmcoKTsKCgoJCQkJCQlhV29yayArPSBxdW90ZVRhYmxlQWxpYXMoYk11bHRpLHBFbnRyeUZpZWxkLT5HZXRBbGlhcygpLGFRdW90ZSk7CgoJCQkJCQlpZiAoIChwRW50cnlGaWVsZC0+R2V0RnVuY3Rpb25UeXBlKCkgJiAoRktUX09USEVSfEZLVF9OVU1FUklDKSkgfHwgKGFGaWVsZE5hbWUudG9DaGFyKCkgPT0gJyonKSApCgkJCQkJCQlhV29yayArPSBhRmllbGROYW1lOwoJCQkJCQllbHNlCgkJCQkJCQlhV29yayArPSA6OmRidG9vbHM6OnF1b3RlTmFtZShhUXVvdGUsIGFGaWVsZE5hbWUpOwoKCQkJCQkJaWYgKCBwRW50cnlGaWVsZC0+aXNBZ2dyZWF0ZUZ1bmN0aW9uKCkgfHwgcEVudHJ5RmllbGQtPklzR3JvdXBCeSgpICkKCQkJCQkJewoJCQkJCQkJaWYgKCFhSGF2aW5nU3RyLmdldExlbmd0aCgpKQkJCS8vIG5vY2gga2VpbmUgS3JpdGVyaWVuCgkJCQkJCQkJYUhhdmluZ1N0ciArPSA6OnJ0bDo6T1VTdHJpbmcoJygnKTsJCQkvLyBLbGFtbWVybgoJCQkJCQkJZWxzZQoJCQkJCQkJCWFIYXZpbmdTdHIgKz0gQ19BTkQ7CgoJCQkJCQkJaWYgKCBwRW50cnlGaWVsZC0+aXNBZ2dyZWF0ZUZ1bmN0aW9uKCkgKQoJCQkJCQkJewoJCQkJCQkJCU9TTF9FTlNVUkUocEVudHJ5RmllbGQtPkdldEZ1bmN0aW9uKCkuZ2V0TGVuZ3RoKCksIk5vIGZ1bmN0aW9uIG5hbWUgZm9yIGFnZ3JlZ2F0ZSBnaXZlbiEiKTsKCQkJCQkJCQlhSGF2aW5nU3RyICs9IHBFbnRyeUZpZWxkLT5HZXRGdW5jdGlvbigpOwoJCQkJCQkJCWFIYXZpbmdTdHIgKz0gOjpydGw6Ok9VU3RyaW5nKCcoJyk7CQkJLy8gS2xhbW1lcm4KCQkJCQkJCQlhSGF2aW5nU3RyICs9IGFXb3JrOwoJCQkJCQkJCWFIYXZpbmdTdHIgKz0gOjpydGw6Ok9VU3RyaW5nKCcpJyk7CQkJLy8gS2xhbW1lcm4KCQkJCQkJCX0KCQkJCQkJCWVsc2UKCQkJCQkJCQlhSGF2aW5nU3RyICs9IGFXb3JrOwoKCQkJCQkJCTo6cnRsOjpPVVN0cmluZyBhVG1wID0gYUNyaXRlcmlhOwoJCQkJCQkJOjpydGw6Ok9VU3RyaW5nIGFFcnJvck1zZzsKCQkJCQkJCVJlZmVyZW5jZTxYUHJvcGVydHlTZXQ+IHhDb2x1bW47CiAgICAgICAgICAgICAgICAgICAgICAgICAgICA6OnN0ZDo6YXV0b19wdHI8IDo6Y29ubmVjdGl2aXR5OjpPU1FMUGFyc2VOb2RlPiBwUGFyc2VOb2RlKF9wVmlldy0+Z2V0UHJlZGljYXRlVHJlZUZyb21FbnRyeShwRW50cnlGaWVsZCxhVG1wLGFFcnJvck1zZyx4Q29sdW1uKSk7CgkJCQkJCQlpZiAocFBhcnNlTm9kZS5nZXQoKSkKCQkJCQkJCXsKCQkJCQkJCQlpZiAoYk11bHRpICYmICEocEVudHJ5RmllbGQtPmlzT3RoZXJGdW5jdGlvbigpIHx8IChhRmllbGROYW1lLnRvQ2hhcigpID09ICcqJykpKQoJCQkJCQkJCQlwUGFyc2VOb2RlLT5yZXBsYWNlTm9kZVZhbHVlKHBFbnRyeUZpZWxkLT5HZXRBbGlhcygpLGFGaWVsZE5hbWUpOwoJCQkJCQkJCTo6cnRsOjpPVVN0cmluZyBzSGF2aW5nU3RyID0gYUhhdmluZ1N0cjsKCgkJCQkJCQkJc2FsX3VJbnQzMiBuQ291bnQgPSBwUGFyc2VOb2RlLT5jb3VudCgpOwoJCQkJCQkJCWZvciggc2FsX3VJbnQzMiBub2RlID0gMSA7IG5vZGUgPCBuQ291bnQgOyArK25vZGUpCgkJCQkJCQkJCXBQYXJzZU5vZGUtPmdldENoaWxkKG5vZGUpLT5wYXJzZU5vZGVUb1N0cigJc0hhdmluZ1N0ciwKCQkJCQkJCQkJCQkJCQkJCXhDb25uZWN0aW9uLAoJCQkJCQkJCQkJCQkJCQkJJnJDb250ZXh0LAoJCQkJCQkJCQkJCQkJCQkJc2FsX0ZhbHNlLAoJCQkJCQkJCQkJCQkJCQkJIXBFbnRyeUZpZWxkLT5pc090aGVyRnVuY3Rpb24oKSk7CgkJCQkJCQkJYUhhdmluZ1N0ciA9IHNIYXZpbmdTdHI7CgkJCQkJCQl9CgkJCQkJCQllbHNlCgkJCQkJCQkJYUhhdmluZ1N0ciArPSBhQ3JpdGVyaWE7CgkJCQkJCX0KCQkJCQkJZWxzZQoJCQkJCQl7CgkJCQkJCQlpZiAoICFhV2hlcmVTdHIuZ2V0TGVuZ3RoKCkgKQkJCS8vIG5vY2gga2VpbmUgS3JpdGVyaWVuCgkJCQkJCQkJYVdoZXJlU3RyICs9IDo6cnRsOjpPVVN0cmluZygnKCcpOwkJCS8vIEtsYW1tZXJuCgkJCQkJCQllbHNlCgkJCQkJCQkJYVdoZXJlU3RyICs9IENfQU5EOwoKCQkJCQkJCWFXaGVyZVN0ciArPSA6OnJ0bDo6T1VTdHJpbmcoJyAnKTsKCQkJCQkJCS8vIGFDcml0ZXJpYSBjb3VsZCBoYXZlIHNvbWUgZ2VybWFuIG51bWJlcnMgc28gSSBoYXZlIHRvIGJlIHN1cmUgaGVyZQoJCQkJCQkJOjpydGw6Ok9VU3RyaW5nIGFUbXAgPSBhQ3JpdGVyaWE7CgkJCQkJCQk6OnJ0bDo6T1VTdHJpbmcgYUVycm9yTXNnOwoJCQkJCQkJUmVmZXJlbmNlPFhQcm9wZXJ0eVNldD4geENvbHVtbjsKCQkJCQkJCTo6c3RkOjphdXRvX3B0cjwgOjpjb25uZWN0aXZpdHk6Ok9TUUxQYXJzZU5vZGU+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+Z2V0Q2hpbGQoMSk7CgkJCTo6Y29ubmVjdGl2aXR5OjpPU1FMUGFyc2VOb2RlOjphYnNvcnB0aW9ucyhwTm9kZVRtcCk7CgkJCXBOb2RlVG1wID0gcE5vZGUtPmdldENoaWxkKDEpOwogICAgICAgICAgICAvLyBjb21wcmVzcyBzb3J0IHRoZSBjcml0ZXJpYSBAc2VlIGh0dHA6Ly93d3cub3Blbm9mZmljZS5vcmcvaXNzdWVzL3Nob3dfYnVnLmNnaT9pZD0yNDA3OQogICAgICAgICAgICBPU1FMUGFyc2VOb2RlOjpjb21wcmVzcyhwTm9kZVRtcCk7CiAgICAgICAgICAgIHBOb2RlVG1wID0gcE5vZGUtPmdldENoaWxkKDEpOwoKCQkJLy8gZmlyc3QgZXh0cmFjdCB0aGUgaW5uZXIgam9pbnMgY29uZGl0aW9ucwoJCQlHZXRJbm5lckpvaW5Dcml0ZXJpYShfcFZpZXcscE5vZGVUbXApOwoJCQkvLyBub3cgc2ltcGxpZnkgYWdhaW4sIGpvaW4gYXJlIGNoZWNrZWQgaW4gQ29tcGFyaXNvblByZWRpY2F0ZQoJCQk6OmNvbm5lY3Rpdml0eTo6T1NRTFBhcnNlTm9kZTo6YWJzb3JwdGlvbnMocE5vZGVUbXApOwoJCQlwTm9kZVRtcCA9IHBOb2RlLT5nZXRDaGlsZCgxKTsKCgkJCS8vIGl0IGNvdWxkIGhhcHBlbiB0aGF0IHBDb25kaXRpb24gaXMgbm90IG1vcmUgdmFsaWQKCQkJZUVycm9yQ29kZSA9IEdldE9SQ3JpdGVyaWEoX3BWaWV3LF9wU2VsZWN0aW9uQnJ3LHBOb2RlVG1wLCByTGV2ZWwpOwoJCX0KCQlyZXR1cm4gZUVycm9yQ29kZTsKCX0KCS8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCglTcWxQYXJzZUVycm9yIEdldEFORENyaXRlcmlhKAlPUXVlcnlEZXNpZ25WaWV3KiBfcFZpZXcsCgkJCQkJCQkJCU9TZWxlY3Rpb25Ccm93c2VCb3gqIF9wU2VsZWN0aW9uQnJ3LAoJCQkJCQkJCQljb25zdCAgOjpjb25uZWN0aXZpdHk6Ok9TUUxQYXJzZU5vZGUgKiBwQ29uZGl0aW9uLAoJCQkJCQkJCQlzYWxfdUludDE2JiBuTGV2ZWwsCgkJCQkJCQkJCXNhbF9Cb29sIGJIYXZpbmcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgYkFkZE9yT25PbmVMaW5lKTsKCS8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCglTcWxQYXJzZUVycm9yIENvbXBhcmlzb25QcmVkaWNhdGUoT1F1ZXJ5RGVzaWduVmlldyogX3BWaWV3LAoJCQkJCQkJT1NlbGVjdGlvbkJyb3dzZUJveCogX3BTZWxlY3Rpb25CcncsCgkJCQkJCQljb25zdCA6OmNvbm5lY3Rpdml0eTo6T1NRTFBhcnNlTm9kZSAqIHBDb25kaXRpb24sCgkJCQkJCQljb25zdCBzYWxfdUludDE2IG5MZXZlbCwKCQkJCQkJCXNhbF9Cb29sIGJIYXZpbmcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIGJBZGRPck9uT25lTGluZSk7CgkvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoJU3FsUGFyc2VFcnJvciBHZXRPUkNyaXRlcmlhKE9RdWVyeURlc2lnblZpZXcqIF9wVmlldywKCQkJCQkJCQlPU2VsZWN0aW9uQnJvd3NlQm94KiBfcFNlbGVjdGlvbkJydywKCQkJCQkJCQljb25zdCA6OmNvbm5lY3Rpdml0eTo6T1NRTFBhcnNlTm9kZSAqIHBDb25kaXRpb24sCgkJCQkJCQkJc2FsX3VJbnQxNiYgbkxldmVsICwKCQkJCQkJCQlzYWxfQm9vbCBiSGF2aW5nLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgYkFkZE9yT25PbmVMaW5lKQoJewoJCVNxbFBhcnNlRXJyb3IgZUVycm9yQ29kZSA9IGVPazsKCgkJLy8gUnVuZGUgS2xhbW1lcm4gdW0gZGVuIEF1c2RydWNrCgkJaWYgKHBDb25kaXRpb24tPmNvdW50KCkgPT0gMyAmJgoJCQlTUUxfSVNQVU5DVFVBVElPTihwQ29uZGl0aW9uLT5nZXRDaGlsZCgwKSwiKCIpICYmCgkJCVNRTF9JU1BVTkNUVUFUSU9OKHBDb25kaXRpb24tPmdldENoaWxkKDIpLCIpIikpCgkJewoJCQllRXJyb3JDb2RlID0gR2V0T1JDcml0ZXJpYShfcFZpZXcsX3BTZWxlY3Rpb25CcncscENvbmRpdGlvbi0+Z2V0Q2hpbGQoMSksbkxldmVsLGJIYXZpbmcsYkFkZE9yT25PbmVMaW5lKTsKCQl9CgkJLy8gb2RlciBWZXJrbnVlcGZ1bmcKCQkvLyBhIHNlYXJjaGNvbmRpdGlvbiBjYW4gb25seSBsb29rIGxpa2UgdGhpczogc2VhcmNoX2NvbmRpdGlvbiBTUUxfVE9LRU5fT1IgYm9vbGVhbl90ZXJtCgkJZWxzZSBpZiAoU1FMX0lTUlVMRShwQ29uZGl0aW9uLHNlYXJjaF9jb25kaXRpb24pKQoJCXsKCQkJZm9yIChpbnQgaSA9IDA7IGkgPCAzICYmIGVFcnJvckNvZGUgPT0gZU9rIDsgaSs9MikKCQkJewogICAgICAgICAgICAgICAgY29uc3QgIDo6Y29ubmVjdGl2aXR5OjpPU1FMUGFyc2VOb2RlKiBwQ2hpbGQgPSBwQ29uZGl0aW9uLT5nZXRDaGlsZChpKTsKCQkJCWlmICggU1FMX0lTUlVMRShwQ2hpbGQsc2VhcmNoX2NvbmRpdGlvbikgKQoJCQkJCWVFcnJvckNvZGUgPSBHZXRPUkNyaXRlcmlhKF9wVmlldyxfcFNlbGVjdGlvbkJydyxwQ2hpbGQsbkxldmVsLGJIYXZpbmcsYkFkZE9yT25PbmVMaW5lKTsKCQkJCWVsc2UKCQkJCXsKICAgICAgICAgICAgICAgICAgICBlRXJyb3JDb2RlID0gR2V0QU5EQ3JpdGVyaWEoX3BWaWV3LF9wU2VsZWN0aW9uQnJ3LHBDaGlsZCwgbkxldmVsLGJIYXZpbmcsIGkgPT0gMCA/IGZhbHNlIDogYkFkZE9yT25PbmVMaW5lKTsKCQkJCQlpZiAoICFiQWRkT3JPbk9uZUxpbmUpCgkJCQkJCW5MZXZlbCsrOwoJCQkJfQoJCQl9CgkJfQoJCWVsc2UKCQkJZUVycm9yQ29kZSA9IEdldEFORENyaXRlcmlhKCBfcFZpZXcsX3BTZWxlY3Rpb25CcncscENvbmRpdGlvbiwgbkxldmVsLCBiSGF2aW5nLGJBZGRPck9uT25lTGluZSApOwoKCQlyZXR1cm4gZUVycm9yQ29kZTsKCX0KICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgIGJvb2wgQ2hlY2tPckNyaXRlcmlhKGNvbnN0IDo6Y29ubmVjdGl2aXR5OjpPU1FMUGFyc2VOb2RlKiBfcENvbmRpdGlvbiw6OmNvbm5lY3Rpdml0eTo6T1NRTFBhcnNlTm9kZSogX3BGaXJzdENvbHVtblJlZikKICAgIHsKICAgICAgICBib29sIGJSZXQgPSB0cnVlOwogICAgICAgIDo6Y29ubmVjdGl2aXR5OjpPU1FMUGFyc2VOb2RlKiBwRmlyc3RDb2x1bW5SZWYgPSBfcEZpcnN0Q29sdW1uUmVmOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMyAmJiBiUmV0OyBpKz0yKQoJCXsKICAgICAgICAgICAgY29uc3QgIDo6Y29ubmVjdGl2aXR5OjpPU1FMUGFyc2VOb2RlKiBwQ2hpbGQgPSBfcENvbmRpdGlvbi0+Z2V0Q2hpbGQoaSk7CiAgICAgICAgICAgIGlmICggU1FMX0lTUlVMRShwQ2hpbGQsc2VhcmNoX2NvbmRpdGlvbikgKQogICAgICAgICAgICAgICAgYlJldCA9IENoZWNrT3JDcml0ZXJpYShwQ2hpbGQscEZpcnN0Q29sdW1uUmVmKTsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvLyB0aGlzIGlzIGEgc2ltcGxlIHdheSB0byB0ZXN0IGNvbHVtbnMgYXJlIHRoZSBzYW1lLCBtYXkgYmUgd2UgaGF2ZSB0byBhZGp1c3QgdGhpcyBhbGdvIGEgbGl0dGxlIGJpdCBpbiBmdXR1cmUuIDotKQogICAgICAgICAgICAgICAgOjpjb25uZWN0aXZpdHk6Ok9TUUxQYXJzZU5vZGUqIHBTZWNvbmRDb2x1bW5SZWYgPSBwQ2hpbGQtPmdldEJ5UnVsZSg6OmNvbm5lY3Rpdml0eTo6T1NRTFBhcnNlTm9kZTo6Y29sdW1uX3JlZik7CiAgICAgICAgICAgICAgICBpZiAoIHBGaXJzdENvbHVtblJlZiAmJiBwU2Vjb25kQ29sdW1uUmVmICkKICAgICAgICAgICAgICAgICAgICBiUmV0ID0gKnBGaXJzdENvbHVtblJlZiA9PSAqcFNlY29uZENvbHVtblJlZjsKICAgICAgICAgICAgICAgIGVsc2UgaWYgKCAhcEZpcnN0Q29sdW1uUmVmICkKICAgICAgICAgICAgICAgICAgICBwRmlyc3RDb2x1bW5SZWYgPSBwU2Vjb25kQ29sdW1uUmVmOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiBiUmV0OwogICAgfQoJLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoJU3FsUGFyc2VFcnJvciBHZXRBTkRDcml0ZXJpYSgJT1F1ZXJ5RGVzaWduVmlldyogX3BWaWV3LAoJCQkJCQkJCQlPU2VsZWN0aW9uQnJvd3NlQm94KiBfcFNlbGVjdGlvbkJydywKCQkJCQkJCQkJY29uc3QgIDo6Y29ubmVjdGl2aXR5OjpPU1FMUGFyc2VOb2RlICogcENvbmRpdGlvbiwKCQkJCQkJCQkJc2FsX3VJbnQxNiYgbkxldmVsLAoJCQkJCQkJCQlzYWxfQm9vbCBiSGF2aW5nLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIGJBZGRPck9uT25lTGluZSkKCXsKCQljb25zdCA6OmNvbTo6c3VuOjpzdGFyOjpsYW5nOjpMb2NhbGUJYUxvY2FsZSA9IF9wVmlldy0+Z2V0TG9jYWxlKCk7CgkJY29uc3QgOjpydGw6Ok9VU3RyaW5nIHNEZWNpbWFsID0gX3BWaWV3LT5nZXREZWNpbWFsU2VwYXJhdG9yKCk7CgoJCS8vIGljaCB3ZXJkZSBlaW4gcGFhciBNYWwgZWluZW4gZ2VjYXN0ZXRlbiBQb2ludGVyIGF1ZiBtZWluZW4gOjpjb206OnN1bjo6c3Rhcjo6c2RiY3g6OkNvbnRhaW5lciBicmF1Y2hlbgoJCU9RdWVyeUNvbnRyb2xsZXImIHJDb250cm9sbGVyID0gc3RhdGljX2Nhc3Q8T1F1ZXJ5Q29udHJvbGxlciY+KF9wVmlldy0+Z2V0Q29udHJvbGxlcigpKTsKCQlTcWxQYXJzZUVycm9yIGVFcnJvckNvZGUgPSBlT2s7CgoJCS8vIFJ1bmRlIEtsYW1tZXJuCgkJaWYgKFNRTF9JU1JVTEUocENvbmRpdGlvbixib29sZWFuX3ByaW1hcnkpKQoJCXsKICAgICAgICAgICAgLy8gY2hlY2sgaWYgd2UgaGF2ZSB0byBwdXQgdGhlIG9yIGNyaXRlcmlhIG9uIG9uZSBsaW5lLgoJCQljb25zdCAgOjpjb25uZWN0aXZpdHk6Ok9TUUxQYXJzZU5vZGUqIHBTZWFyY2hDb25kaXRpb24gPSBwQ29uZGl0aW9uLT5nZXRDaGlsZCgxKTsKICAgICAgICAgICAgYm9vbCBiTXVzdEFkZE9yT25PbmVMaW5lID0gQ2hlY2tPckNyaXRlcmlhKHBTZWFyY2hDb25kaXRpb24sTlVMTCk7CgkJCWlmICggU1FMX0lTUlVMRSggcFNlYXJjaENvbmRpdGlvbiwgc2VhcmNoX2NvbmRpdGlvbikgKSAvLyB3ZSBoYXZlIGEgb3IKCQkJewoJCQkJX3BTZWxlY3Rpb25CcnctPkR1cGxpY2F0ZUNvbmRpdGlvbkxldmVsKCBuTGV2ZWwpOwoJCQkJZUVycm9yQ29kZSA9IEdldE9SQ3JpdGVyaWEoX3BWaWV3LF9wU2VsZWN0aW9uQnJ3LHBTZWFyY2hDb25kaXRpb24tPmdldENoaWxkKDApLCBuTGV2ZWwsYkhhdmluZyxiTXVzdEFkZE9yT25PbmVMaW5lICk7CgkJCQkrK25MZXZlbDsKCQkJCWVFcnJvckNvZGUgPSBHZXRPUkNyaXRlcmlhKF9wVmlldyxfcFNlbGVjdGlvbkJydyxwU2VhcmNoQ29uZGl0aW9uLT5nZXRDaGlsZCgyKSwgbkxldmVsLGJIYXZpbmcsYk11c3RBZGRPck9uT25lTGluZSApOwoJCQl9CgkJCWVsc2UKCQkJCWVFcnJvckNvZGUgPSBHZXRPUkNyaXRlcmlhKF9wVmlldyxfcFNlbGVjdGlvbkJydyxwU2VhcmNoQ29uZGl0aW9uLCBuTGV2ZWwsYkhhdmluZyxiTXVzdEFkZE9yT25PbmVMaW5lICk7CgkJfQoJCS8vIERhcyBlcnN0ZSBFbGVtZW50IGlzdCAod2llZGVyKSBlaW5lIEFORC1WZXJrbnVlcGZ1bmcKCQllbHNlIGlmICggU1FMX0lTUlVMRShwQ29uZGl0aW9uLGJvb2xlYW5fdGVybSkgKQoJCXsKICAgICAgICAgICAgT1NMX0VOU1VSRShwQ29uZGl0aW9uLT5jb3VudCgpID09IDMsIklsbGVnYWwgZGVmaW5pZml0b24gb2YgYm9vbGVhbl90ZXJtIik7CgkJCWVFcnJvckNvZGUgPSBHZXRBTkRDcml0ZXJpYShfcFZpZXcsX3BTZWxlY3Rpb25CcncscENvbmRpdGlvbi0+Z2V0Q2hpbGQoMCksIG5MZXZlbCxiSGF2aW5nLGJBZGRPck9uT25lTGluZSApOwoJCQlpZiAoIGVFcnJvckNvZGUgPT0gZU9rICkKCQkJCWVFcnJvckNvZGUgPSBHZXRBTkRDcml0ZXJpYShfcFZpZXcsX3BTZWxlY3Rpb25CcncscENvbmRpdGlvbi0+Z2V0Q2hpbGQoMiksIG5MZXZlbCxiSGF2aW5nLGJBZGRPck9uT25lTGluZSApOwoJCX0KCQllbHNlIGlmIChTUUxfSVNSVUxFKCBwQ29uZGl0aW9uLCBjb21wYXJpc29uX3ByZWRpY2F0ZSkpCgkJewoJCQllRXJyb3JDb2RlID0gQ29tcGFyaXNvblByZWRpY2F0ZShfcFZpZXcsX3BTZWxlY3Rpb25CcncscENvbmRpdGlvbixuTGV2ZWwsYkhhdmluZyxiQWRkT3JPbk9uZUxpbmUpOwoJCX0KCQllbHNlIGlmKCBTUUxfSVNSVUxFKHBDb25kaXRpb24sbGlrZV9wcmVkaWNhdGUpICkKCQl7CiAgICAgICAgICAgIGNvbnN0ICA6OmNvbm5lY3Rpdml0eTo6T1NRTFBhcnNlTm9kZSogcFZhbHVlRXhwID0gcENvbmRpdGlvbi0+Z2V0Q2hpbGQoMCk7CgkJCWlmIChTUUxfSVNSVUxFKHBWYWx1ZUV4cCwgY29sdW1uX3JlZiApICkKCQkJewoJCQkJOjpydGw6Ok9VU3RyaW5nIGFDb2x1bW5OYW1lOwoJCQkJOjpydGw6Ok9VU3RyaW5nCWFDb25kaXRpb247CgkJCQlSZWZlcmVuY2U8IFhDb25uZWN0aW9uPiB4Q29ubmVjdGlvbiA9IHJDb250cm9sbGVyLmdldENvbm5lY3Rpb24oKTsKCQkJCWlmICggeENvbm5lY3Rpb24uaXMoKSApCgkJCQl7CgkJCQkJUmVmZXJlbmNlPCBYRGF0YWJhc2VNZXRhRGF0YSA+ICB4TWV0YURhdGEgPSB4Q29ubmVjdGlvbi0+Z2V0TWV0YURhdGEoKTsKCQkJCQkvLyB0aGUgaW50ZXJuYXRpb25hbCBkb2Vzbid0IG1hdHRlciBJIGhhdmUgYSBzdHJpbmcKCQkJCQlwQ29uZGl0aW9uLT5wYXJzZU5vZGVUb1ByZWRpY2F0ZVN0cihhQ29uZGl0aW9uLAoJCQkJCQkJCQkJCQkJCXhDb25uZWN0aW9uLAoJCQkJCQkJCQkJCQkJCXJDb250cm9sbGVyLmdldE51bWJlckZvcm1hdHRlcigpLAoJCQkJCQkJCQkJCQkJCWFMb2NhbGUsCgkJCQkJCQkJCQkJCQkJc3RhdGljX2Nhc3Q8c2FsX0NoYXI+KHNEZWNpbWFsLnRvQ2hhcigpKSwKCQkJCQkJCQkJCQkJCQkmckNvbnRyb2xsZXIuZ2V0UGFyc2VyKCkuZ2V0Q29udGV4dCgpKTsKCgkJCQkJcFZhbHVlRXhwLT5wYXJzZU5vZGVUb1ByZWRpY2F0ZVN0cigJYUNvbHVtbk5hbWUsCgkJCQkJCQkJCQkJCQkJeENvbm5lY3Rpb24sCgkJCQkJCQkJCQkJCQkJckNvbnRyb2xsZXIuZ2V0TnVtYmVyRm9ybWF0dGVyKCksCgkJCQkJCQkJCQkJCQkJYUxvY2FsZSwKCQkJCQkJCQkJCQkJCQlzdGF0aWNfY2FzdDxzYWxfQ2hhcj4oc0RlY2ltYWwudG9DaGFyKCkpLAoJCQkJCQkJCQkJCQkJCSZyQ29udHJvbGxlci5nZXRQYXJzZXIoKS5nZXRDb250ZXh0KCkpOwoKCQkJCQkvLyBkb24ndCBkaXNwbGF5IHRoZSBjb2x1bW4gbmFtZQoJCQkJCWFDb25kaXRpb24gPSBhQ29uZGl0aW9uLmNvcHkoYUNvbHVtbk5hbWUuZ2V0TGVuZ3RoKCkpOwoJCQkJCWFDb25kaXRpb24gPSBhQ29uZGl0aW9uLnRyaW0oKTsKCQkJCX0KCgkJCQlPVGFibGVGaWVsZERlc2NSZWYgYURyYWdMZWZ0ID0gbmV3IE9UYWJsZUZpZWxkRGVzYygpOwoJCQkJaWYgKCBlT2sgPT0gKCBlRXJyb3JDb2RlID0gRmlsbERyYWdJbmZvKF9wVmlldyxwVmFsdWVFeHAsYURyYWdMZWZ0KSApKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmICggYkhhdmluZyApCgkJCQkJICAgIGFEcmFnTGVmdC0+U2V0R3JvdXBCeShzYWxfVHJ1ZSk7CgkJCQkJX3BTZWxlY3Rpb25CcnctPkFkZENvbmRpdGlvbihhRHJhZ0xlZnQsIGFDb25kaXRpb24sIG5MZXZlbCxiQWRkT3JPbk9uZUxpbmUpOwogICAgICAgICAgICAgICAgfQoJCQl9CiAgICAgICAgICAgIGVsc2UgaWYoU1FMX0lTUlVMRU9SMihwVmFsdWVFeHAsZ2VuZXJhbF9zZXRfZmN0ICxzZXRfZmN0X3NwZWMpCSAgICAgICAgfHwKCQkJCQkJCVNRTF9JU1JVTEVPUjIocFZhbHVlRXhwLHBvc2l0aW9uX2V4cCxleHRyYWN0X2V4cCkJfHwKCQkJCQkJCVNRTF9JU1JVTEVPUjIocFZhbHVlRXhwLGZvbGQsY2hhcl9zdWJzdHJpbmdfZmN0KQl8fAoJCQkJCQkJU1FMX0lTUlVMRU9SMihwVmFsdWVFeHAsbGVuZ3RoX2V4cCxjaGFyX3ZhbHVlX2ZjdCkpCgkJICAgIHsKCQkJICAgIEFkZEZ1bmN0aW9uQ29uZGl0aW9uKAlfcFZpZXcsCgkJCQkJCQkJCSAgICBfcFNlbGVjdGlvbkJydywKCQkJCQkJCQkJICAgIHBDb25kaXRpb24sCgkJCQkJCQkJCSAgICBuTGV2ZWwsCgkJCQkJCQkJCSAgICBiSGF2aW5nLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYkFkZE9yT25PbmVMaW5lKTsKCQkgICAgfQoJCQllbHNlCgkJCXsKCQkJCWVFcnJvckNvZGUgPSBlTm9Db2x1bW5Jbkxpa2U7CgkJCQlTdHJpbmcgc0Vycm9yKE1vZHVsZVJlcyhTVFJfUVJZX0xJS0VfTEVGVF9OT19DT0xVTU4pKTsKCQkJCV9wVmlldy0+Z2V0Q29udHJvbGxlcigpLmFwcGVuZEVycm9yKCBzRXJyb3IgKTsKCQkJfQoJCX0KCQllbHNlIGlmKAlTUUxfSVNSVUxFT1IyKHBDb25kaXRpb24sdGVzdF9mb3JfbnVsbCxpbl9wcmVkaWNhdGUpCgkJCQl8fAlTUUxfSVNSVUxFT1IyKHBDb25kaXRpb24sYWxsX29yX2FueV9wcmVkaWNhdGUsYmV0d2Vlbl9wcmVkaWNhdGUpKQoJCXsKCQkJaWYgKCBTUUxfSVNSVUxFT1IyKHBDb25kaXRpb24tPmdldENoaWxkKDApLCBzZXRfZmN0X3NwZWMgLCBnZW5lcmFsX3NldF9mY3QgKSApCgkJCXsKCQkJCUFkZEZ1bmN0aW9uQ29uZGl0aW9uKAlfcFZpZXcsCgkJCQkJCQkJCQlfcFNlbGVjdGlvbkJydywKCQkJCQkJCQkJCXBDb25kaXRpb24sCgkJCQkJCQkJCQluTGV2ZWwsCgkJCQkJCQkJCQliSGF2aW5nLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYkFkZE9yT25PbmVMaW5lKTsKCQkJfQoJCQllbHNlIGlmICggU1FMX0lTUlVMRShwQ29uZGl0aW9uLT5nZXRDaGlsZCgwKSwgY29sdW1uX3JlZiApICkKCQkJewoJCQkJLy8gcGFyc2UgY29uZGl0aW9uCgkJCQk6OnJ0bDo6T1VTdHJpbmcgc0NvbmRpdGlvbiA9IFBhcnNlQ29uZGl0aW9uKHJDb250cm9sbGVyLHBDb25kaXRpb24sc0RlY2ltYWwsYUxvY2FsZSwxKTsKCQkJCU9UYWJsZUZpZWxkRGVzY1JlZglhRHJhZ0xlZnQgPSBuZXcgT1RhYmxlRmllbGREZXNjKCk7CgkJCQlpZiAoIGVPayA9PSAoIGVFcnJvckNvZGUgPSBGaWxsRHJhZ0luZm8oX3BWaWV3LHBDb25kaXRpb24tPmdldENoaWxkKDApLGFEcmFnTGVmdCkpICkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAoIGJIYXZpbmcgKQoJCQkJCSAgICBhRHJhZ0xlZnQtPlNldEdyb3VwQnkoc2FsX1RydWUpOwoJCQkJCV9wU2VsZWN0aW9uQnJ3LT5BZGRDb25kaXRpb24oYURyYWdMZWZ0LCBzQ29uZGl0aW9uLCBuTGV2ZWwsYkFkZE9yT25PbmVMaW5lKTsKICAgICAgICAgICAgICAgIH0KCQkJfQoJCQllbHNlCgkJCXsKCQkJCS8vIEZ1bmt0aW9ucy1CZWRpbmd1bmcgcGFyc2VuCgkJCQk6OnJ0bDo6T1VTdHJpbmcJc0NvbmRpdGlvbiA9IFBhcnNlQ29uZGl0aW9uKHJDb250cm9sbGVyLHBDb25kaXRpb24sc0RlY2ltYWwsYUxvY2FsZSwxKTsKCQkJCVJlZmVyZW5jZTwgWENvbm5lY3Rpb24+IHhDb25uZWN0aW9uID0gckNvbnRyb2xsZXIuZ2V0Q29ubmVjdGlvbigpOwoJCQkJUmVmZXJlbmNlPCBYRGF0YWJhc2VNZXRhRGF0YSA+ICB4TWV0YURhdGEgPSB4Q29ubmVjdGlvbi0+Z2V0TWV0YURhdGEoKTsKCQkJCQkvLyB0aGUgaW50ZXJuYXRpb25hbCBkb2Vzbid0IG1hdHRlciBJIGhhdmUgYSBzdHJpbmcKCQkJCTo6cnRsOjpPVVN0cmluZyBzTmFtZTsKCQkJCXBDb25kaXRpb24tPmdldENoaWxkKDApLT5wYXJzZU5vZGVUb1ByZWRpY2F0ZVN0cihzTmFtZSwKCQkJCQkJCQkJCQkJCXhDb25uZWN0aW9uLAoJCQkJCQkJCQkJCQkJckNvbnRyb2xsZXIuZ2V0TnVtYmVyRm9ybWF0dGVyKCksCgkJCQkJCQkJCQkJCQlhTG9jYWxlLAoJCQkJCQkJCQkJCQkJc3RhdGljX2Nhc3Q8c2FsX0NoYXI+KHNEZWNpbWFsLnRvQ2hhcigpKSwKCQkJCQkJCQkJCQkJCSZyQ29udHJvbGxlci5nZXRQYXJzZXIoKS5nZXRDb250ZXh0KCkpOwoKCQkJCU9UYWJsZUZpZWxkRGVzY1JlZiBhRHJhZ0xlZnQgPSBuZXcgT1RhYmxlRmllbGREZXNjKCk7CgkJCQlhRHJhZ0xlZnQtPlNldEZpZWxkKHNOYW1lKTsKCQkJCWFEcmFnTGVmdC0+U2V0RnVuY3Rpb25UeXBlKEZLVF9PVEhFUik7CgoJCQkJaWYgKCBiSGF2aW5nICkKCQkJCQlhRHJhZ0xlZnQtPlNldEdyb3VwQnkoc2FsX1RydWUpOwoJCQkJX3BTZWxlY3Rpb25CcnctPkFkZENvbmRpdGlvbihhRHJhZ0xlZnQsIHNDb25kaXRpb24sIG5MZXZlbCxiQWRkT3JPbk9uZUxpbmUpOwoJCQl9CgkJfQoJCWVsc2UgaWYoIFNRTF9JU1JVTEVPUjIocENvbmRpdGlvbixleGlzdGVuY2VfdGVzdCx1bmlxdWVfdGVzdCkgKQoJCXsKCQkJLy8gRnVua3Rpb25zLUJlZGluZ3VuZyBwYXJzZW4KCQkJOjpydGw6Ok9VU3RyaW5nCWFDb25kaXRpb24gPSBQYXJzZUNvbmRpdGlvbihyQ29udHJvbGxlcixwQ29uZGl0aW9uLHNEZWNpbWFsLGFMb2NhbGUsMCk7CgoJCQlPVGFibGVGaWVsZERlc2NSZWYgYURyYWdMZWZ0ID0gbmV3IE9UYWJsZUZpZWxkRGVzYygpOwoJCQlhRHJhZ0xlZnQtPlNldEZpZWxkKGFDb25kaXRpb24pOwoJCQlhRHJhZ0xlZnQtPlNldEZ1bmN0aW9uVHlwZShGS1RfQ09ORElUSU9OKTsKCgkJCWVFcnJvckNvZGUgPSBfcFNlbGVjdGlvbkJydy0+SW5zZXJ0RmllbGQoYURyYWdMZWZ0LEJST1dTRVJfSU5WQUxJRElELHNhbF9GYWxzZSxzYWxfVHJ1ZSkuaXNWYWxpZCgpID8gZU9rIDogZVRvb01hbnlDb2x1bW5zOwoJCX0KCQllbHNlIC8vISBUT0RPIG5vdCBzdXBwb3J0ZWQgeWV0CgkJCWVFcnJvckNvZGUgPSBlU3RhdGVtZW50VG9vQ29tcGxleDsKCQkvLyBGZWhsZXIgZWluZmFjaCB3ZWl0ZXJyZWljaGVuLgoJCXJldHVybiBlRXJyb3JDb2RlOwoJfQoJLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCVNxbFBhcnNlRXJyb3IgQWRkRnVuY3Rpb25Db25kaXRpb24oT1F1ZXJ5RGVzaWduVmlldyogX3BWaWV3LAoJCQkJCQkJT1NlbGVjdGlvbkJyb3dzZUJveCogX3BTZWxlY3Rpb25CcncsCgkJCQkJCQljb25zdCA6OmNvbm5lY3Rpdml0eTo6T1NRTFBhcnNlTm9kZSAqIHBDb25kaXRpb24sCgkJCQkJCQljb25zdCBzYWxfdUludDE2IG5MZXZlbCwKCQkJCQkJCXNhbF9Cb29sIGJIYXZpbmcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBib29sIGJBZGRPck9uT25lTGluZSkKCXsKCQlTcWxQYXJzZUVycm9yIGVFcnJvckNvZGUgPSBlT2s7CgkJT1F1ZXJ5Q29udHJvbGxlciYgckNvbnRyb2xsZXIgPSBzdGF0aWNfY2FzdDxPUXVlcnlDb250cm9sbGVyJj4oX3BWaWV3LT5nZXRDb250cm9sbGVyKCkpOwoKICAgICAgICBPU1FMUGFyc2VOb2RlKiBwRnVuY3Rpb24gPSBwQ29uZGl0aW9uLT5nZXRDaGlsZCgwKTsKCiAgICAgICAgT1NMX0VOU1VSRShTUUxfSVNSVUxFT1IyKHBGdW5jdGlvbixnZW5lcmFsX3NldF9mY3QgLHNldF9mY3Rfc3BlYykJICAgICAgICB8fAoJCQkJCQkJU1FMX0lTUlVMRU9SMihwRnVuY3Rpb24scG9zaXRpb25fZXhwLGV4dHJhY3RfZXhwKQl8fAoJCQkJCQkJU1FMX0lTUlVMRU9SMihwRnVuY3Rpb24sZm9sZCxjaGFyX3N1YnN0cmluZ19mY3QpCXx8CgkJCQkJCQlTUUxfSVNSVUxFT1IyKHBGdW5jdGlvbixsZW5ndGhfZXhwLGNoYXJfdmFsdWVfZmN0KSwiSWxsZWdhbCBjYWxsISIpOwoJCTo6cnRsOjpPVVN0cmluZwlhQ29uZGl0aW9uOwoJCU9UYWJsZUZpZWxkRGVzY1JlZiBhRHJhZ0xlZnQgPSBuZXcgT1RhYmxlRmllbGREZXNjKCk7CgoJCTo6cnRsOjpPVVN0cmluZyBhQ29sdW1uTmFtZTsKCQlSZWZlcmVuY2U8IFhDb25uZWN0aW9uPiB4Q29ubmVjdGlvbiA9IHJDb250cm9sbGVyLmdldENvbm5lY3Rpb24oKTsKCQlpZih4Q29ubmVjdGlvbi5pcygpKQoJCXsKCQkJUmVmZXJlbmNlPCBYRGF0YWJhc2VNZXRhRGF0YSA+ICB4TWV0YURhdGEgPSB4Q29ubmVjdGlvbi0+Z2V0TWV0YURhdGEoKTsKCQkJcENvbmRpdGlvbi0+cGFyc2VOb2RlVG9QcmVkaWNhdGVTdHIoYUNvbmRpdGlvbiwKCQkJCQkJCQkJCQkJeENvbm5lY3Rpb24sCgkJCQkJCQkJCQkJCXJDb250cm9sbGVyLmdldE51bWJlckZvcm1hdHRlcigpLAoJCQkJCQkJCQkJCQlfcFZpZXctPmdldExvY2FsZSgpLAoJCQkJCQkJCQkJCQlzdGF0aWNfY2FzdDxzYWxfQ2hhcj4oX3BWaWV3LT5nZXREZWNpbWFsU2VwYXJhdG9yKCkudG9DaGFyKCkpLAoJCQkJCQkJCQkJCQkmckNvbnRyb2xsZXIuZ2V0UGFyc2VyKCkuZ2V0Q29udGV4dCgpKTsKCiAgICAgICAgICAgIHBGdW5jdGlvbi0+cGFyc2VOb2RlVG9TdHIoCWFDb2x1bW5OYW1lLAoJCQkJCQkJCQkJeENvbm5lY3Rpb24sCgkJCQkJCQkJCQkmckNvbnRyb2xsZXIuZ2V0UGFyc2VyKCkuZ2V0Q29udGV4dCgpLAoJCQkJCQkJCQkJc2FsX1RydWUsCgkJCQkJCQkJCQlzYWxfVHJ1ZSk7IC8vIHF1b3RlIGlzIHRvIHRydWUgYmVjYXVzZSB3ZSBuZWVkIHF1b3RlZCBlbGVtZW50cyBpbnNpZGUgdGhlIGZ1bmN0aW9uCiAgICAgICAgICAgIC8vIGk3NTU1NwoJCQkvL3BGdW5jdGlvbi0+cGFyc2VOb2RlVG9QcmVkaWNhdGVTdHIoYUNvbHVtbk5hbWUsCgkJCS8vCQkJCQkJCQkJeENvbm5lY3Rpb24sCgkJCS8vCQkJCQkJCQkJckNvbnRyb2xsZXIuZ2V0TnVtYmVyRm9ybWF0dGVyKCksCgkJCS8vCQkJCQkJCQkJX3BWaWV3LT5nZXRMb2NhbGUoKSwKCQkJLy8JCQkJCQkJCQlzdGF0aWNfY2FzdDxzYWxfQ2hhcj4oX3BWaWV3LT5nZXREZWNpbWFsU2VwYXJhdG9yKCkudG9DaGFyKCkpLAoJCQkvLwkJCQkJCQkJCSZyQ29udHJvbGxlci5nZXRQYXJzZXIoKS5nZXRDb250ZXh0KCkpOwoJCQkvLyBkb24ndCBkaXNwbGF5IHRoZSBjb2x1bW4gbmFtZQoJCQlhQ29uZGl0aW9uID0gYUNvbmRpdGlvbi5jb3B5KGFDb2x1bW5OYW1lLmdldExlbmd0aCgpKTsKCQkJYUNvbmRpdGlvbiA9IGFDb25kaXRpb24udHJpbSgpOwoJCQlpZiAoIGFDb25kaXRpb24uaW5kZXhPZignPScsMCkgPT0gMCApIC8vIGlnbm9yZSB0aGUgZXF1YWwgc2lnbgoJCQkJYUNvbmRpdGlvbiA9IGFDb25kaXRpb24uY29weSgxKTsKCgoJCQlpZiAoIFNRTF9JU1JVTEUocEZ1bmN0aW9uLCBnZW5lcmFsX3NldF9mY3QgKSApCgkJCXsKCQkJCXNhbF9JbnQzMiBuRnVuY3Rpb25UeXBlID0gRktUX0FHR1JFR0FURTsKCQkJCU9TUUxQYXJzZU5vZGUqIHBQYXJhbU5vZGUgPSBwRnVuY3Rpb24tPmdldENoaWxkKHBGdW5jdGlvbi0+Y291bnQoKS0yKTsKCQkJCWlmICggcFBhcmFtTm9kZSAmJiBwUGFyYW1Ob2RlLT5nZXRUb2tlblZhbHVlKCkudG9DaGFyKCkgPT0gJyonICkKCQkJCXsKCQkJCQlPSm9pblRhYmxlVmlldzo6T1RhYmxlV2luZG93TWFwKiBwVGFiTGlzdCA9IF9wVmlldy0+Z2V0VGFibGVWaWV3KCktPkdldFRhYldpbk1hcCgpOwoJCQkJCU9Kb2luVGFibGVWaWV3OjpPVGFibGVXaW5kb3dNYXA6Oml0ZXJhdG9yIGFJdGVyID0gcFRhYkxpc3QtPmJlZ2luKCk7CiAgICAgICAgICAgICAgICAgICAgT0pvaW5UYWJsZVZpZXc6Ok9UYWJsZVdpbmRvd01hcDo6aXRlcmF0b3IgYVRhYkVuZCA9IHBUYWJMaXN0LT5lbmQoKTsKCQkJCQlmb3IoO2FJdGVyICE9IGFUYWJFbmQ7KythSXRlcikKCQkJCQl7CgkJCQkJCU9RdWVyeVRhYmxlV2luZG93KiBwVGFiV2luID0gc3RhdGljX2Nhc3Q8T1F1ZXJ5VGFibGVXaW5kb3cqPihhSXRlci0+c2Vjb25kKTsKCQkJCQkJaWYgKHBUYWJXaW4tPkV4aXN0c0ZpZWxkKCA6OnJ0bDo6T1VTdHJpbmc6OmNyZWF0ZUZyb21Bc2NpaSgiKiIpLCBhRHJhZ0xlZnQgKSkKCQkJCQkJewoJCQkJCQkJYURyYWdMZWZ0LT5TZXRBbGlhcyhTdHJpbmcoKSk7CgkJCQkJCQlhRHJhZ0xlZnQtPlNldFRhYmxlKFN0cmluZygpKTsKCQkJCQkJCWJyZWFrOwoJCQkJCQl9CgkJCQkJfQoJCQkJfQoJCQkJZWxzZSBpZiggZU9rICE9ICggZUVycm9yQ29kZSA9IEZpbGxEcmFnSW5mbyhfcFZpZXcscFBhcmFtTm9kZSxhRHJhZ0xlZnQpKQoJCQkJCQkmJiBTUUxfSVNSVUxFKHBQYXJhbU5vZGUsbnVtX3ZhbHVlX2V4cCkgKQoJCQkJewoJCQkJCTo6cnRsOjpPVVN0cmluZyBzUGFyYW1ldGVyVmFsdWU7CgkJCQkJcFBhcmFtTm9kZS0+cGFyc2VOb2RlVG9TdHIoCXNQYXJhbWV0ZXJWYWx1ZSwKCQkJCQkJCQkJCQkJeENvbm5lY3Rpb24sCgkJCQkJCQkJCQkJCSZyQ29udHJvbGxlci5nZXRQYXJzZXIoKS5nZXRDb250ZXh0KCkpOwoJCQkJCW5GdW5jdGlvblR5cGUgfD0gRktUX05VTUVSSUM7CgkJCQkJYURyYWdMZWZ0LT5TZXRGaWVsZChzUGFyYW1ldGVyVmFsdWUpOwoJCQkJCWVFcnJvckNvZGUgPSBlT2s7CgkJCQl9CgkJCQlhRHJhZ0xlZnQtPlNldEZ1bmN0aW9uVHlwZShuRnVuY3Rpb25UeXBlKTsKCQkJCWlmICggYkhhdmluZyApCgkJCQkJYURyYWdMZWZ0LT5TZXRHcm91cEJ5KHNhbF9UcnVlKTsKCQkJCXNhbF9JbnQzMiBuSW5kZXggPSAwOwoJCQkJYURyYWdMZWZ0LT5TZXRGdW5jdGlvbihhQ29sdW1uTmFtZS5nZXRUb2tlbigwLCcoJyxuSW5kZXgpKTsKCQkJfQoJCQllbHNlCgkJCXsKCQkJCS8vIGJlaSB1bmJla2FubnRlbiBGdW5rdGlvbmVuIHdpcmQgZGVyIGdlc2FtdGUgVGV4dCBpbiBkYXMgRmllbGQgZ2VjaHJpZWJlbgoJCQkJYURyYWdMZWZ0LT5TZXRGaWVsZChhQ29sdW1uTmFtZSk7CgkJCQlpZihiSGF2aW5nKQoJCQkJCWFEcmFnTGVmdC0+U2V0R3JvdXBCeShzYWxfVHJ1ZSk7CgkJCQlhRHJhZ0xlZnQtPlNldEZ1bmN0aW9uVHlwZShGS1RfT1RIRVJ8RktUX05VTUVSSUMpOwoJCQl9CgkJCV9wU2VsZWN0aW9uQnJ3LT5BZGRDb25kaXRpb24oYURyYWdMZWZ0LCBhQ29uZGl0aW9uLCBuTGV2ZWwsYkFkZE9yT25PbmVMaW5lKTsKCQl9CgoJCXJldHVybiBlRXJyb3JDb2RlOwoJfQoJLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCVNxbFBhcnNlRXJyb3IgQ29tcGFyaXNvblByZWRpY2F0ZShPUXVlcnlEZXNpZ25WaWV3KiBfcFZpZXcsCgkJCQkJCQlPU2VsZWN0aW9uQnJvd3NlQm94KiBfcFNlbGVjdGlvbkJydywKCQkJCQkJCWNvbnN0IDo6Y29ubmVjdGl2aXR5OjpPU1FMUGFyc2VOb2RlICogcENvbmRpdGlvbiwKCQkJCQkJCWNvbnN0IHNhbF91SW50MTYgbkxldmVsLAoJCQkJCQkJc2FsX0Jvb2wgYkhhdmluZwogICAgICAgICAgICAgICAgICAgICAgICAgICAgLGJvb2wgYkFkZE9yT25PbmVMaW5lKQoJewoJCVNxbFBhcnNlRXJyb3IgZUVycm9yQ29kZSA9IGVPazsKCQlPUXVlcnlDb250cm9sbGVyJiByQ29udHJvbGxlciA9IHN0YXRpY19jYXN0PE9RdWVyeUNvbnRyb2xsZXImPihfcFZpZXctPmdldENvbnRyb2xsZXIoKSk7CgoJCURCR19BU1NFUlQoU1FMX0lTUlVMRSggcENvbmRpdGlvbiwgY29tcGFyaXNvbl9wcmVkaWNhdGUpLCJDb21wYXJpc29uUHJlZGljYXRlOiBwQ29uZGl0aW9uIGlzdCBrZWluIENvbXBhcmlzb25QcmVkaWNhdGUiKTsKCQlpZiAoIFNRTF9JU1JVTEUocENvbmRpdGlvbi0+Z2V0Q2hpbGQoMCksIGNvbHVtbl9yZWYgKQoJCQl8fCBTUUxfSVNSVUxFKHBDb25kaXRpb24tPmdldENoaWxkKHBDb25kaXRpb24tPmNvdW50KCktMSksIGNvbHVtbl9yZWYpICkKCQl7CgkJCTo6cnRsOjpPVVN0cmluZwlhQ29uZGl0aW9uOwoJCQlPVGFibGVGaWVsZERlc2NSZWYgYURyYWdMZWZ0ID0gbmV3IE9UYWJsZUZpZWxkRGVzYygpOwoKCQkJaWYgKCBTUUxfSVNSVUxFKHBDb25kaXRpb24tPmdldENoaWxkKDApLCBjb2x1bW5fcmVmICkgJiYgU1FMX0lTUlVMRShwQ29uZGl0aW9uLT5nZXRDaGlsZChwQ29uZGl0aW9uLT5jb3VudCgpLTEpLCBjb2x1bW5fcmVmICkgKQoJCQl7CgkJCQlPVGFibGVGaWVsZERlc2NSZWYgYURyYWdSaWdodCA9IG5ldyBPVGFibGVGaWVsZERlc2MoKTsKCQkJCWlmIChlT2sgIT0gKCBlRXJyb3JDb2RlID0gRmlsbERyYWdJbmZvKF9wVmlldyxwQ29uZGl0aW9uLT5nZXRDaGlsZCgwKSxhRHJhZ0xlZnQpKSB8fAoJCQkJCWVPayAhPSAoIGVFcnJvckNvZGUgPSBGaWxsRHJhZ0luZm8oX3BWaWV3LHBDb25kaXRpb24tPmdldENoaWxkKDIpLGFEcmFnUmlnaHQpKSkKCQkJCQlyZXR1cm4gZUVycm9yQ29kZTsKCiAgICAgICAgICAgICAgICBPUXVlcnlUYWJsZUNvbm5lY3Rpb24qIHBDb25uID0gc3RhdGljX2Nhc3Q8T1F1ZXJ5VGFibGVDb25uZWN0aW9uKj4oCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfcFZpZXctPmdldFRhYmxlVmlldygpLT5HZXRUYWJDb25uKHN0YXRpY19jYXN0PE9RdWVyeVRhYmxlV2luZG93Kj4oYURyYWdMZWZ0LT5HZXRUYWJXaW5kb3coKSksCgkJCQkJCQkJCQkJCQkJCQkJCQkJCSAgIHN0YXRpY19jYXN0PE9RdWVyeVRhYmxlV2luZG93Kj4oYURyYWdSaWdodC0+R2V0VGFiV2luZG93KCkpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnVlKSk7CgkJCQlpZiAoIHBDb25uICkKCQkJCXsKCQkJCQlPQ29ubmVjdGlvbkxpbmVEYXRhVmVjKiBwTGluZURhdGFMaXN0ID0gcENvbm4tPkdldERhdGEoKS0+R2V0Q29ubkxpbmVEYXRhTGlzdCgpOwoJCQkJCU9Db25uZWN0aW9uTGluZURhdGFWZWM6Oml0ZXJhdG9yIGFJdGVyID0gcExpbmVEYXRhTGlzdC0+YmVnaW4oKTsKICAgICAgICAgICAgICAgICAgICBPQ29ubmVjdGlvbkxpbmVEYXRhVmVjOjppdGVyYXRvciBhRW5kID0gcExpbmVEYXRhTGlzdC0+ZW5kKCk7CgkJCQkJZm9yKDthSXRlciAhPSBhRW5kOysrYUl0ZXIpCgkJCQkJewoJCQkJCQlpZigoKmFJdGVyKS0+R2V0U291cmNlRmllbGROYW1lKCkgPT0gYURyYWdMZWZ0LT5HZXRGaWVsZCgpIHx8CgkJCQkJCSAgICgqYUl0ZXIpLT5HZXREZXN0RmllbGROYW1lKCkgPT0gYURyYWdMZWZ0LT5HZXRGaWVsZCgpICkKCQkJCQkJCWJyZWFrOwoJCQkJCX0KCQkJCQlpZihhSXRlciAhPSBhRW5kKQoJCQkJCQlyZXR1cm4gZU9rOwoJCQkJfQoJCQl9CgoJCQlzYWxfdUludDMyIG5Qb3MgPSAwOwoJCQlpZihTUUxfSVNSVUxFKHBDb25kaXRpb24tPmdldENoaWxkKDApLCBjb2x1bW5fcmVmICkpCgkJCXsKCQkJCW5Qb3MgPSAwOwoJCQkJc2FsX3VJbnQzMiBpPTE7CgoJCQkJLy8gZG9uJ3QgZGlzcGxheSB0aGUgZXF1YWwKCQkJCWlmIChwQ29uZGl0aW9uLT5nZXRDaGlsZChpKS0+Z2V0Tm9kZVR5cGUoKSA9PSBTUUxfTk9ERV9FUVVBTCkKCQkJCQlpKys7CgoJCQkJLy8gQmVkaW5ndW5nIHBhcnNlbgoJCQkJYUNvbmRpdGlvbiA9IFBhcnNlQ29uZGl0aW9uKHJDb250cm9sbGVyCgkJCQkJCQkJCQkJLHBDb25kaXRpb24KCQkJCQkJCQkJCQksX3BWaWV3LT5nZXREZWNpbWFsU2VwYXJhdG9yKCkKCQkJCQkJCQkJCQksX3BWaWV3LT5nZXRMb2NhbGUoKQoJCQkJCQkJCQkJCSxpKTsKCQkJfQoJCQllbHNlIGlmKCBTUUxfSVNSVUxFKHBDb25kaXRpb24tPmdldENoaWxkKHBDb25kaXRpb24tPmNvdW50KCktMSksIGNvbHVtbl9yZWYgKSApCgkJCXsKCQkJCW5Qb3MgPSBwQ29uZGl0aW9uLT5jb3VudCgpLTE7CgoJCQkJc2FsX0ludDMyIGkgPSBzdGF0aWNfY2FzdDxzYWxfSW50MzI+KHBDb25kaXRpb24tPmNvdW50KCkgLSAyKTsKCQkJCXN3aXRjaCAocENvbmRpdGlvbi0+Z2V0Q2hpbGQoaSktPmdldE5vZGVUeXBlKCkpCgkJCQl7CgkJCQkJY2FzZSBTUUxfTk9ERV9FUVVBTDoKCQkJCQkJLy8gZG9uJ3QgZGlzcGxheSB0aGUgZXF1YWwKCQkJCQkJaS0tOwoJCQkJCQlicmVhazsKCQkJCQljYXNlIFNRTF9OT0RFX0xFU1M6CgkJCQkJCS8vIHRha2UgdGhlIG9wcG9zaXRlIGFzIHdlIGNoYW5nZSB0aGUgb3JkZXIKCQkJCQkJaS0tOwoJCQkJCQlhQ29uZGl0aW9uID0gYUNvbmRpdGlvbiArIDo6cnRsOjpPVVN0cmluZzo6Y3JlYXRlRnJvbUFzY2lpKCI+Iik7CgkJCQkJCWJyZWFrOwoJCQkJCWNhc2UgU1FMX05PREVfTEVTU0VROgoJCQkJCQkvLyB0YWtlIHRoZSBvcHBvc2l0ZSBhcyB3ZSBjaGFuZ2UgdGhlIG9yZGVyCgkJCQkJCWktLTsKCQkJCQkJYUNvbmRpdGlvbiA9IGFDb25kaXRpb24gKyA6OnJ0bDo6T1VTdHJpbmc6OmNyZWF0ZUZyb21Bc2NpaSgiPj0iKTsKCQkJCQkJYnJlYWs7CgkJCQkJY2FzZSBTUUxfTk9ERV9HUkVBVDoKCQkJCQkJLy8gdGFrZSB0aGUgb3Bwb3NpdGUgYXMgd2UgY2hhbmdlIHRoZSBvcmRlcgoJCQkJCQlpLS07CgkJCQkJCWFDb25kaXRpb24gPSBhQ29uZGl0aW9uICsgOjpydGw6Ok9VU3RyaW5nOjpjcmVhdGVGcm9tQXNjaWkoIjwiKTsKCQkJCQkJYnJlYWs7CgkJCQkJY2FzZSBTUUxfTk9ERV9HUkVBVEVROgoJCQkJCQkvLyB0YWtlIHRoZSBvcHBvc2l0ZSBhcyB3ZSBjaGFuZ2UgdGhlIG9yZGVyCgkJCQkJCWktLTsKCQkJCQkJYUNvbmRpdGlvbiA9IGFDb25kaXRpb24gKyA6OnJ0bDo6T1VTdHJpbmc6OmNyZWF0ZUZyb21Bc2NpaSgiPD0iKTsKCQkJCQkJYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgkJCQl9CgoJCQkJLy8gZ28gYmFja3dhcmQKCQkJCVJlZmVyZW5jZTwgWENvbm5lY3Rpb24+IHhDb25uZWN0aW9uID0gckNvbnRyb2xsZXIuZ2V0Q29ubmVjdGlvbigpOwoJCQkJaWYoeENvbm5lY3Rpb24uaXMoKSkKCQkJCXsKCQkJCQlSZWZlcmVuY2U8IFhEYXRhYmFzZU1ldGFEYXRhID4gIHhNZXRhRGF0YSA9IHhDb25uZWN0aW9uLT5nZXRNZXRhRGF0YSgpOwoJCQkJCWZvciAoOyBpID49IDA7IGktLSkKCQkJCQkJcENvbmRpdGlvbi0+Z2V0Q2hpbGQoaSktPnBhcnNlTm9kZVRvUHJlZGljYXRlU3RyKGFDb25kaXRpb24sCgkJCQkJCQkJCQkJCXhDb25uZWN0aW9uLAoJCQkJCQkJCQkJCQlyQ29udHJvbGxlci5nZXROdW1iZXJGb3JtYXR0ZXIoKSwKCQkJCQkJCQkJCQkJX3BWaWV3LT5nZXRMb2NhbGUoKSwKCQkJCQkJCQkJCQkJc3RhdGljX2Nhc3Q8c2FsX0NoYXI+KF9wVmlldy0+Z2V0RGVjaW1hbFNlcGFyYXRvcigpLnRvQ2hhcigpKSwKCQkJCQkJCQkJCQkJJnJDb250cm9sbGVyLmdldFBhcnNlcigpLmdldENvbnRleHQoKSk7CgkJCQl9CgkJCX0KCQkJLy8gZWxzZSA/Pz8KCgoJCQlpZiggZU9rID09ICggZUVycm9yQ29kZSA9IEZpbGxEcmFnSW5mbyhfcFZpZXcscENvbmRpdGlvbi0+Z2V0Q2hpbGQoblBvcyksYURyYWdMZWZ0KSkpCgkJCXsKCQkJCWlmKGJIYXZpbmcpCgkJCQkJYURyYWdMZWZ0LT5TZXRHcm91cEJ5KHNhbF9UcnVlKTsKCQkJCV9wU2VsZWN0aW9uQnJ3LT5BZGRDb25kaXRpb24oYURyYWdMZWZ0LCBhQ29uZGl0aW9uLCBuTGV2ZWwsYkFkZE9yT25PbmVMaW5lKTsKCQkJfQoJCX0KCQllbHNlIGlmKCBTUUxfSVNSVUxFT1IyKHBDb25kaXRpb24tPmdldENoaWxkKDApLCBzZXRfZmN0X3NwZWMgLCBnZW5lcmFsX3NldF9mY3QgKSApCgkJewoJCQlBZGRGdW5jdGlvbkNvbmRpdGlvbigJX3BWaWV3LAoJCQkJCQkJCQlfcFNlbGVjdGlvbkJydywKCQkJCQkJCQkJcENvbmRpdGlvbiwKCQkJCQkJCQkJbkxldmVsLAoJCQkJCQkJCQliSGF2aW5nLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiQWRkT3JPbk9uZUxpbmUpOwoJCX0KCQllbHNlIC8vIGthbm4gc2ljaCBudXIgdW0gZWluZW4gRXhwci4gQXVzZHJ1Y2sgaGFuZGVsbgoJCXsKCQkJOjpydGw6Ok9VU3RyaW5nIGFOYW1lLGFDb25kaXRpb247CgoJCQk6OmNvbm5lY3Rpdml0eTo6T1NRTFBhcnNlTm9kZSAqcExocyA9IHBDb25kaXRpb24tPmdldENoaWxkKDApOwoJCQk6OmNvbm5lY3Rpdml0eTo6T1NRTFBhcnNlTm9kZSAqcFJocyA9IHBDb25kaXRpb24tPmdldENoaWxkKDIpOwoJCQkvLyBGZWxkbmFtZW4KCQkJUmVmZXJlbmNlPCBYQ29ubmVjdGlvbj4geENvbm5lY3Rpb24gPSByQ29udHJvbGxlci5nZXRDb25uZWN0aW9uKCk7CgkJCWlmKHhDb25uZWN0aW9uLmlzKCkpCgkJCXsKCQkJCXBMaHMtPnBhcnNlTm9kZVRvU3RyKGFOYW1lLAoJCQkJCQkJCQkgeENvbm5lY3Rpb24sCgkJCQkJCQkJCSAmckNvbnRyb2xsZXIuZ2V0UGFyc2VyKCkuZ2V0Q29udGV4dCgpLAoJCQkJCQkJCQkgc2FsX1RydWUpOwoJCQkJLy8gS3JpdGVyaXVtCgkJCQlhQ29uZGl0aW9uID0gcENvbmRpdGlvbi0+Z2V0Q2hpbGQoMSktPmdldFRva2VuVmFsdWUoKTsKCQkJCXBSaHMtPnBhcnNlTm9kZVRvUHJlZGljYXRlU3RyKGFDb25kaXRpb24sCgkJCQkJCQkJCQkJCQkJCXhDb25uZWN0aW9uLAoJCQkJCQkJCQkJCQkJCQlyQ29udHJvbGxlci5nZXROdW1iZXJGb3JtYXR0ZXIoKSwKCQkJCQkJCQkJCQkJCQkJX3BWaWV3LT5nZXRMb2NhbGUoKSwKCQkJCQkJCQkJCQkJCQkJc3RhdGljX2Nhc3Q8c2FsX0NoYXI+KF9wVmlldy0+Z2V0RGVjaW1hbFNlcGFyYXRvcigpLnRvQ2hhcigpKSwKCQkJCQkJCQkJCQkJCQkJJnJDb250cm9sbGVyLmdldFBhcnNlcigpLmdldENvbnRleHQoKSk7CgkJCX0KCgkJCU9UYWJsZUZpZWxkRGVzY1JlZiBhRHJhZ0xlZnQgPSBuZXcgT1RhYmxlRmllbGREZXNjKCk7CgkJCWFEcmFnTGVmdC0+U2V0RmllbGQoYU5hbWUpOwoJCQlhRHJhZ0xlZnQtPlNldEZ1bmN0aW9uVHlwZShGS1RfT1RIRVJ8RktUX05VTUVSSUMpOwoJCQkvLyB1bmQgYW5oImFuZ2VuCgkJCV9wU2VsZWN0aW9uQnJ3LT5BZGRDb25kaXRpb24oYURyYWdMZWZ0LCBhQ29uZGl0aW9uLCBuTGV2ZWwsYkFkZE9yT25PbmVMaW5lKTsKCQl9CgkJcmV0dXJuIGVFcnJvckNvZGU7Cgl9CgogICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgIG5hbWVzcGFjZQogICAgewogICAgICAgIE9RdWVyeVRhYmxlV2luZG93KiBsY2xfZmluZENvbHVtbkluVGFibGVzKCBjb25zdCA6OnJ0bDo6T1VTdHJpbmcmIF9yQ29sdW1OYW1lLCBjb25zdCBPSm9pblRhYmxlVmlldzo6T1RhYmxlV2luZG93TWFwJiBfclRhYkxpc3QsIE9UYWJsZUZpZWxkRGVzY1JlZiYgX3JJbmZvICkKICAgICAgICB7CgkJCU9Kb2luVGFibGVWaWV3OjpPVGFibGVXaW5kb3dNYXA6OmNvbnN0X2l0ZXJhdG9yIGFJdGVyID0gX3JUYWJMaXN0LmJlZ2luKCk7CiAgICAgICAgICAgIE9Kb2luVGFibGVWaWV3OjpPVGFibGVXaW5kb3dNYXA6OmNvbnN0X2l0ZXJhdG9yIGFFbmQgPSBfclRhYkxpc3QuZW5kKCk7CgkJCWZvciAoIDsgYUl0ZXIgIT0gYUVuZDsgKythSXRlciApCgkJCXsKCQkJCU9RdWVyeVRhYmxlV2luZG93KiBwVGFiV2luID0gc3RhdGljX2Nhc3Q8IE9RdWVyeVRhYmxlV2luZG93KiA+KCBhSXRlci0+c2Vjb25kICk7CgkJCQlpZiAoIHBUYWJXaW4gJiYgcFRhYldpbi0+RXhpc3RzRmllbGQoIF9yQ29sdW1OYW1lLCBfckluZm8gKSApCgkJCQkJcmV0dXJuIHBUYWJXaW47CgkJCX0KICAgICAgICAgICAgcmV0dXJuIE5VTEw7CiAgICAgICAgfQogICAgfQoKICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgl2b2lkIEluc2VydENvbHVtblJlZihjb25zdCBPUXVlcnlEZXNpZ25WaWV3KiBfcFZpZXcsCgkJCQkJCWNvbnN0IDo6Y29ubmVjdGl2aXR5OjpPU1FMUGFyc2VOb2RlICogcENvbHVtblJlZiwKCQkJCQkJOjpydGw6Ok9VU3RyaW5nJiBhQ29sdW1uTmFtZSwKCQkJCQkJY29uc3QgOjpydGw6Ok9VU3RyaW5nJiBhQ29sdW1uQWxpYXMsCgkJCQkJCTo6cnRsOjpPVVN0cmluZyYgYVRhYmxlUmFuZ2UsCgkJCQkJCU9UYWJsZUZpZWxkRGVzY1JlZiYgX3JhSW5mbywKCQkJCQkJT0pvaW5UYWJsZVZpZXc6Ok9UYWJsZVdpbmRvd01hcCogcFRhYkxpc3QpCgl7CgoJCS8vIFRhYmVsbGVubmFtZW4genVzYW1tZW4gc2V0emVuCgkJOjpjb25uZWN0aXZpdHk6Ok9TUUxQYXJzZVRyZWVJdGVyYXRvciYgclBhcnNlSXRlciA9IHN0YXRpY19jYXN0PE9RdWVyeUNvbnRyb2xsZXImPihfcFZpZXctPmdldENvbnRyb2xsZXIoKSkuZ2V0UGFyc2VJdGVyYXRvcigpOwoJCXJQYXJzZUl0ZXIuZ2V0Q29sdW1uUmFuZ2UoIHBDb2x1bW5SZWYsIGFDb2x1bW5OYW1lLCBhVGFibGVSYW5nZSApOwoKCQlzYWxfQm9vbCBiRm91bmQoc2FsX0ZhbHNlKTsKCQlEQkdfQVNTRVJUKGFDb2x1bW5OYW1lLmdldExlbmd0aCgpLCJDb2x1bW5uYW1lIGRhcmYgbmljaHQgbGVlciBzZWluIik7CgkJaWYgKCFhVGFibGVSYW5nZS5nZXRMZW5ndGgoKSkKCQl7CgkJCS8vIFNFTEVDVCBjb2x1bW4sIC4uLgogICAgICAgICAgICBiRm91bmQgPSBOVUxMICE9IGxjbF9maW5kQ29sdW1uSW5UYWJsZXMoIGFDb2x1bW5OYW1lLCAqcFRhYkxpc3QsIF9yYUluZm8gKTsKCQkJaWYgKCBiRm91bmQgJiYgKCBhQ29sdW1uTmFtZS50b0NoYXIoKSAhPSAnKicgKSApCgkJCQlfcmFJbmZvLT5TZXRGaWVsZEFsaWFzKGFDb2x1bW5BbGlhcyk7CgkJfQoJCWVsc2UKCQl7CgkJCS8vIFNFTEVDVCByYW5nZS5jb2x1bW4sIC4uLgoJCQlPUXVlcnlUYWJsZVdpbmRvdyogcFRhYldpbiA9IHN0YXRpY19jYXN0PE9RdWVyeVRhYmxlVmlldyo+KF9wVmlldy0+Z2V0VGFibGVWaWV3KCkpLT5GaW5kVGFibGUoYVRhYmxlUmFuZ2UpOwoKCQkJaWYgKHBUYWJXaW4gJiYgcFRhYldpbi0+RXhpc3RzRmllbGQoYUNvbHVtbk5hbWUsIF9yYUluZm8pKQoJCQl7CgkJCQlpZihhQ29sdW1uTmFtZS50b0NoYXIoKSAhPSAnKicpCgkJCQkJX3JhSW5mby0+U2V0RmllbGRBbGlhcyhhQ29sdW1uQWxpYXMpOwoJCQkJYkZvdW5kID0gc2FsX1RydWU7CgkJCX0KCQl9CgkJaWYgKCFiRm91bmQpCgkJewoJCQlfcmFJbmZvLT5TZXRUYWJsZSg6OnJ0bDo6T1VTdHJpbmcoKSk7CgkJCV9yYUluZm8tPlNldEFsaWFzKDo6cnRsOjpPVVN0cmluZygpKTsKCQkJX3JhSW5mby0+U2V0RmllbGQoYUNvbHVtbk5hbWUpOwoJCQlfcmFJbmZvLT5TZXRGaWVsZEFsaWFzKGFDb2x1bW5BbGlhcyk7CS8vIG55aSA6IGhpZXIgZWluIGZvcnRsYXVmZW5kZXMgRXhwcl8xLCBFeHByXzIgLi4uCgkJCV9yYUluZm8tPlNldEZ1bmN0aW9uVHlwZShGS1RfT1RIRVIpOwoJCX0KCX0KCS8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCXNhbF9Cb29sIGNoZWNrSm9pbkNvbmRpdGlvbnMoCWNvbnN0IE9RdWVyeURlc2lnblZpZXcqIF9wVmlldywKCQkJCQkJCQkJY29uc3QgOjpjb25uZWN0aXZpdHk6Ok9TUUxQYXJzZU5vZGUqIF9wTm9kZSApCgl7CgkJY29uc3QgOjpjb25uZWN0aXZpdHk6Ok9TUUxQYXJzZU5vZGUqIHBKb2luTm9kZSA9IE5VTEw7CgkJc2FsX0Jvb2wgYlJldCA9IHNhbF9UcnVlOwoJCWlmIChTUUxfSVNSVUxFKF9wTm9kZSxxdWFsaWZpZWRfam9pbikpCgkJCXBKb2luTm9kZSA9IF9wTm9kZTsKICAgICAgICBlbHNlIGlmIChTUUxfSVNSVUxFKF9wTm9kZSx0YWJsZV9yZWYpCiAgICAgICAgICAgICAgICAmJiAgX3BOb2RlLT5jb3VudCgpID09IDMKICAgICAgICAgICAgICAgICYmICBTUUxfSVNQVU5DVFVBVElPTihfcE5vZGUtPmdldENoaWxkKDApLCIoIikKICAgICAgICAgICAgICAgICYmICBTUUxfSVNQVU5DVFVBVElPTihfcE5vZGUtPmdldENoaWxkKDIpLCIpIikgKSAvLyAnKCcgam9pbmVkX3RhYmxlICcpJwoJCQlwSm9pbk5vZGUgPSBfcE5vZGUtPmdldENoaWxkKDEpOwoJCWVsc2UgaWYgKCEgKCBTUUxfSVNSVUxFKF9wTm9kZSwgdGFibGVfcmVmKSAmJiBfcE5vZGUtPmNvdW50KCkgPT0gMikgKSAvLyB0YWJsZV9ub2RlIHRhYmxlX3ByaW1hcnlfYXNfcmFuZ2VfY29sdW1uCgkJCWJSZXQgPSBzYWxfRmFsc2U7CgoJCWlmIChwSm9pbk5vZGUgJiYgIUluc2VydEpvaW4oX3BWaWV3LHBKb2luTm9kZSkpCgkJCWJSZXQgPSBzYWxfRmFsc2U7CgkJcmV0dXJuIGJSZXQ7Cgl9CgkvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCglzYWxfQm9vbCBJbnNlcnRKb2luKGNvbnN0IE9RdWVyeURlc2lnblZpZXcqIF9wVmlldywKCQkJCQkJY29uc3QgOjpjb25uZWN0aXZpdHk6Ok9TUUxQYXJzZU5vZGUgKnBOb2RlKQoJewoJCURCR19BU1NFUlQoIFNRTF9JU1JVTEUoIHBOb2RlLCBxdWFsaWZpZWRfam9pbiApIHx8IFNRTF9JU1JVTEUoIHBOb2RlLCBqb2luZWRfdGFibGUgKSB8fCBTUUxfSVNSVUxFKCBwTm9kZSwgY3Jvc3NfdW5pb24gKSwKCQkJIk9RdWVyeURlc2lnblZpZXc6Okluc2VydEpvaW46IEZlaGxlciBpbSBQYXJzZSBUcmVlIik7CgogICAgICAgIGlmIChTUUxfSVNSVUxFKHBOb2RlLGpvaW5lZF90YWJsZSkpCiAgICAgICAgICAgIHJldHVybiBJbnNlcnRKb2luKF9wVmlldyxwTm9kZS0+Z2V0Q2hpbGQoMSkpOwoKCQkvLyBmaXJzdCBjaGVjayB0aGUgbGVmdCBhbmQgcmlnaHQgc2lkZQogICAgICAgIGNvbnN0IDo6Y29ubmVjdGl2aXR5OjpPU1FMUGFyc2VOb2RlKiBwUmlnaHRUYWJsZVJlZiA9IHBOb2RlLT5nZXRDaGlsZCgzKTsgLy8gdGFibGVfcmVmCiAgICAgICAgaWYgKCBTUUxfSVNSVUxFKHBOb2RlLCBxdWFsaWZpZWRfam9pbikgJiYgU1FMX0lTVE9LRU4ocE5vZGUtPmdldENoaWxkKDEpLE5BVFVSQUwpICkKICAgICAgICAgICAgcFJpZ2h0VGFibGVSZWYgPSBwTm9kZS0+Z2V0Q2hpbGQoNCk7IC8vIHRhYmxlX3JlZgoKCQlpZiAoICFjaGVja0pvaW5Db25kaXRpb25zKF9wVmlldyxwTm9kZS0+Z2V0Q2hpbGQoMCkpIHx8ICFjaGVja0pvaW5Db25kaXRpb25zKF9wVmlldyxwUmlnaHRUYWJsZVJlZikpCgkJCXJldHVybiBzYWxfRmFsc2U7CgoJCS8vIG5hbWVkIGNvbHVtbiBqb2luIHdpcmQgc3DkdGVyIHZpZWxlaWNodCBub2NoIGltcGxlbWVudGllcnQKCQkvLyBTUUxfSVNSVUxFKHBOb2RlLT5nZXRDaGlsZCg0KSxuYW1lZF9jb2x1bW5zX2pvaW4pCiAgICAgICAgRUpvaW5UeXBlIGVKb2luVHlwZSA9IElOTkVSX0pPSU47CiAgICAgICAgYm9vbCBiTmF0dXJhbCA9IGZhbHNlOwoJCWlmICggU1FMX0lTUlVMRShwTm9kZSwgcXVhbGlmaWVkX2pvaW4pICkKCQl7CgkJCTo6Y29ubmVjdGl2aXR5OjpPU1FMUGFyc2VOb2RlKiBwSm9pblR5cGUgPSBwTm9kZS0+Z2V0Q2hpbGQoMSk7IC8vIGpvaW5fdHlwZQogICAgICAgICAgICBpZiAoIFNRTF9JU1RPS0VOKHBKb2luVHlwZSxOQVRVUkFMKSApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGJOYXR1cmFsID0gdHJ1ZTsKICAgICAgICAgICAgICAgIHBKb2luVHlwZSA9IHBOb2RlLT5nZXRDaGlsZCgyKTsKICAgICAgICAgICAgfQoKCQkJaWYgKFNRTF9JU1JVTEUocEpvaW5UeXBlLGpvaW5fdHlwZSkgJiYgKCFwSm9pblR5cGUtPmNvdW50KCkgfHwgU1FMX0lTVE9LRU4ocEpvaW5UeXBlLT5nZXRDaGlsZCgwKSxJTk5FUikpKQoJCQl7CgkJCQllSm9pblR5cGUgPSBJTk5FUl9KT0lOOwoJCQl9CgkJCWVsc2UKCQkJewoJCQkJaWYgKFNRTF9JU1JVTEUocEpvaW5UeXBlLGpvaW5fdHlwZSkpCSAgIC8vIGVpbmUgRWJlbmUgdGllZmVyCgkJCQkJcEpvaW5UeXBlID0gcEpvaW5UeXBlLT5nZXRDaGlsZCgwKTsKCgkJCQlpZiAoU1FMX0lTVE9LRU4ocEpvaW5UeXBlLT5nZXRDaGlsZCgwKSxMRUZUKSkKCQkJCQllSm9pblR5cGUgPSBMRUZUX0pPSU47CgkJCQllbHNlIGlmKFNRTF9JU1RPS0VOKHBKb2luVHlwZS0+Z2V0Q2hpbGQoMCksUklHSFQpKQoJCQkJCWVKb2luVHlwZSA9IFJJR0hUX0pPSU47CgkJCQllbHNlCgkJCQkJZUpvaW5UeXBlID0gRlVMTF9KT0lOOwoJCQl9CiAgICAgICAgICAgIGlmICggU1FMX0lTUlVMRShwTm9kZS0+Z2V0Q2hpbGQoNCksam9pbl9jb25kaXRpb24pICkKICAgICAgICAgICAgewoJCQkgICAgaWYgKCBJbnNlcnRKb2luQ29ubmVjdGlvbihfcFZpZXcscE5vZGUtPmdldENoaWxkKDQpLT5nZXRDaGlsZCgxKSwgZUpvaW5UeXBlLHBOb2RlLT5nZXRDaGlsZCgwKSxwUmlnaHRUYWJsZVJlZikgIT0gZU9rICkKCQkJCSAgICByZXR1cm4gc2FsX0ZhbHNlOwogICAgICAgICAgICB9CgkJfQogICAgICAgIGVsc2UgaWYgKCBTUUxfSVNSVUxFKHBOb2RlLCBjcm9zc191bmlvbikgKQogICAgICAgIHsKICAgICAgICAgICAgZUpvaW5UeXBlID0gQ1JPU1NfSk9JTjsKICAgICAgICAgICAgcFJpZ2h0VGFibGVSZWYgPSBwTm9kZS0+Z2V0Q2hpbGQocE5vZGUtPmNvdW50KCkgLSAxKTsKICAgICAgICB9CiAgICAgICAgZWxzZQoJCQlyZXR1cm4gc2FsX0ZhbHNlOwoKICAgICAgICBpZiAoIGVKb2luVHlwZSA9PSBDUk9TU19KT0lOIHx8IGJOYXR1cmFsICkKICAgICAgICB7CgogICAgICAgICAgICBPUXVlcnlUYWJsZVdpbmRvdyoJcExlZnRXaW5kb3cgPSBzdGF0aWNfY2FzdDxPUXVlcnlUYWJsZVZpZXcqPihfcFZpZXctPmdldFRhYmxlVmlldygpKS0+RmluZFRhYmxlKCBnZXRUYWJsZVJhbmdlKF9wVmlldyxwTm9kZS0+Z2V0Q2hpbGQoMCkpICk7CiAgICAgICAgICAgIE9RdWVyeVRhYmxlV2luZG93KglwUmlnaHRXaW5kb3cgPSBzdGF0aWNfY2FzdDxPUXVlcnlUYWJsZVZpZXcqPihfcFZpZXctPmdldFRhYmxlVmlldygpKS0+RmluZFRhYmxlKCBnZXRUYWJsZVJhbmdlKF9wVmlldyxwUmlnaHRUYWJsZVJlZikgKTsKICAgICAgICAgICAgT1NMX0VOU1VSRShwTGVmdFdpbmRvdyAmJiBwUmlnaHRXaW5kb3csIlRhYmxlIFdpbmRvd3MgY291bGQgbm90IGJlIGZvdW5kISIpOwogICAgICAgICAgICBpZiAoICFwTGVmdFdpbmRvdyB8fCAhcFJpZ2h0V2luZG93ICkKICAgICAgICAgICAgICAgIHJldHVybiBzYWxfRmFsc2U7CgogICAgICAgICAgICBPVGFibGVGaWVsZERlc2NSZWYgYURyYWdMZWZ0ICA9IG5ldyBPVGFibGVGaWVsZERlc2MoKTsKICAgICAgICAgICAgYURyYWdMZWZ0LT5TZXRUYWJXaW5kb3cocExlZnRXaW5kb3cpOwogICAgICAgICAgICBhRHJhZ0xlZnQtPlNldFRhYmxlKHBMZWZ0V2luZG93LT5HZXRUYWJsZU5hbWUoKSk7CiAgICAgICAgICAgIGFEcmFnTGVmdC0+U2V0QWxpYXMocExlZnRXaW5kb3ctPkdldEFsaWFzTmFtZSgpKTsKCgkJCU9UYWJsZUZpZWxkRGVzY1JlZiBhRHJhZ1JpZ2h0ID0gbmV3IE9UYWJsZUZpZWxkRGVzYygpOwogICAgICAgICAgICBhRHJhZ1JpZ2h0LT5TZXRUYWJXaW5kb3cocFJpZ2h0V2luZG93KTsKICAgICAgICAgICAgYURyYWdSaWdodC0+U2V0VGFibGUocFJpZ2h0V2luZG93LT5HZXRUYWJsZU5hbWUoKSk7CiAgICAgICAgICAgIGFEcmFnUmlnaHQtPlNldEFsaWFzKHBSaWdodFdpbmRvdy0+R2V0QWxpYXNOYW1lKCkpOwoKICAgICAgICAgICAgaW5zZXJ0Q29ubmVjdGlvbihfcFZpZXcsZUpvaW5UeXBlLGFEcmFnTGVmdCxhRHJhZ1JpZ2h0LGJOYXR1cmFsKTsKICAgICAgICB9CgoKCQlyZXR1cm4gc2FsX1RydWU7Cgl9CgkvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoJdm9pZCBpbnNlcnRVblVzZWRGaWVsZHMoT1F1ZXJ5RGVzaWduVmlldyogX3BWaWV3LE9TZWxlY3Rpb25Ccm93c2VCb3gqIF9wU2VsZWN0aW9uQnJ3KQoJewoJCS8vIG5vdyB3ZSBoYXZlIHRvIGluc2VydCB0aGUgZmllbGRzIHdoaWNoIGFyZW4ndCBpbiB0aGUgc3RhdGVtZW50CgkJT1F1ZXJ5Q29udHJvbGxlciYgckNvbnRyb2xsZXIgPSBzdGF0aWNfY2FzdDxPUXVlcnlDb250cm9sbGVyJj4oX3BWaWV3LT5nZXRDb250cm9sbGVyKCkpOwoJCU9UYWJsZUZpZWxkcyYgclVuVXNlZEZpZWxkcyA9IHJDb250cm9sbGVyLmdldFVuVXNlZEZpZWxkcygpOwogICAgICAgIE9UYWJsZUZpZWxkczo6aXRlcmF0b3IgYUVuZCA9IHJVblVzZWRGaWVsZHMuZW5kKCk7CgkJZm9yKE9UYWJsZUZpZWxkczo6aXRlcmF0b3IgYUl0ZXIgPSByVW5Vc2VkRmllbGRzLmJlZ2luKCk7YUl0ZXIgIT0gYUVuZDsrK2FJdGVyKQoJCQlpZihfcFNlbGVjdGlvbkJydy0+SW5zZXJ0RmllbGQoKmFJdGVyLEJST1dTRVJfSU5WQUxJRElELHNhbF9GYWxzZSxzYWxfRmFsc2UpLmlzVmFsaWQoKSkKCQkJCSgqYUl0ZXIpID0gTlVMTDsKCQlPVGFibGVGaWVsZHMoKS5zd2FwKCByVW5Vc2VkRmllbGRzICk7Cgl9CgoJLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCVNxbFBhcnNlRXJyb3IgSW5pdEZyb21QYXJzZU5vZGVJbXBsKE9RdWVyeURlc2lnblZpZXcqIF9wVmlldyxPU2VsZWN0aW9uQnJvd3NlQm94KiBfcFNlbGVjdGlvbkJydykKCXsKCQlTcWxQYXJzZUVycm9yIGVFcnJvckNvZGUgPSBlT2s7CgoJCU9RdWVyeUNvbnRyb2xsZXImIHJDb250cm9sbGVyID0gc3RhdGljX2Nhc3Q8T1F1ZXJ5Q29udHJvbGxlciY+KF9wVmlldy0+Z2V0Q29udHJvbGxlcigpKTsKCgkJX3BTZWxlY3Rpb25CcnctPlByZUZpbGwoKTsKCQlfcFNlbGVjdGlvbkJydy0+U2V0UmVhZE9ubHkockNvbnRyb2xsZXIuaXNSZWFkT25seSgpKTsKCQlfcFNlbGVjdGlvbkJydy0+RmlsbCgpOwoKCgkJOjpjb25uZWN0aXZpdHk6Ok9TUUxQYXJzZVRyZWVJdGVyYXRvciYgYUl0ZXJhdG9yID0gckNvbnRyb2xsZXIuZ2V0UGFyc2VJdGVyYXRvcigpOwoJCWNvbnN0IDo6Y29ubmVjdGl2aXR5OjpPU1FMUGFyc2VOb2RlKiBwUGFyc2VUcmVlID0gYUl0ZXJhdG9yLmdldFBhcnNlVHJlZSgpOwoKICAgICAgICBkbwogICAgICAgIHsKICAgICAgICAgICAgaWYgKCAhcFBhcnNlVHJlZSApCiAgICAgICAgICAgIHsKCQkJICAgIC8vIG5vdyB3ZSBoYXZlIHRvIGluc2VydCB0aGUgZmllbGRzIHdoaWNoIGFyZW4ndCBpbiB0aGUgc3RhdGVtZW50CgkJCSAgICBpbnNlcnRVblVzZWRGaWVsZHMoX3BWaWV3LF9wU2VsZWN0aW9uQnJ3KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoICFyQ29udHJvbGxlci5pc0VzYWNwZVByb2Nlc3NpbmcoKSApIC8vIG5vdCBhbGxvd2VkIGluIHRoaXMgbW9kZQogICAgICAgICAgICB7CgkJCSAgICBlRXJyb3JDb2RlID0gZU5hdGl2ZU1vZGU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQoKCQkJaWYgKCAhKCBTUUxfSVNSVUxFKCBwUGFyc2VUcmVlLCBzZWxlY3Rfc3RhdGVtZW50ICkgKSApCiAgICAgICAgICAgIHsKCQkJCWVFcnJvckNvZGUgPSBlTm9TZWxlY3RTdGF0ZW1lbnQ7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgY29uc3QgT1NRTFBhcnNlTm9kZSogcFRhYmxlRXhwID0gcFBhcnNlVHJlZS0+Z2V0Q2hpbGQoMyk7CiAgICAgICAgICAgIGlmICggcFRhYmxlRXhwLT5nZXRDaGlsZCg2KS0+Y291bnQoKSA+IDAgfHwgcFRhYmxlRXhwLT5nZXRDaGlsZCg3KS0+Y291bnQoKSA+IDAgfHwgcFRhYmxlRXhwLT5nZXRDaGlsZCg4KS0+Y291bnQoKSA+IDApCiAgICAgICAgICAgIHsKCQkJCWVFcnJvckNvZGUgPSBlU3RhdGVtZW50VG9vQ29tcGxleDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CgoJCQlSZWZlcmVuY2U8IFhDb25uZWN0aW9uPiB4Q29ubmVjdGlvbiA9IHJDb250cm9sbGVyLmdldENvbm5lY3Rpb24oKTsKCQkJaWYgKCAheENvbm5lY3Rpb24uaXMoKSApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIERCR19FUlJPUiggIkluaXRGcm9tUGFyc2VOb2RlSW1wbDogbm8gY29ubmVjdGlvbj8gbm8gY29ubmVjdGlvbiEiICk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQoKCQkJY29uc3QgT1NRTFRhYmxlcyYgYU1hcCA9IGFJdGVyYXRvci5nZXRUYWJsZXMoKTsKCQkJOjpjb21waGVscGVyOjpVU3RyaW5nTWl4TGVzcyBhVG1wKGFNYXAua2V5X2NvbXAoKSk7CgkJCTo6Y29tcGhlbHBlcjo6VVN0cmluZ01peEVxdWFsIGFLZXlDb21wKCBhVG1wLmlzQ2FzZVNlbnNpdGl2ZSgpICk7CgoJCQlSZWZlcmVuY2U8IFhEYXRhYmFzZU1ldGFEYXRhID4gIHhNZXRhRGF0YSA9IHhDb25uZWN0aW9uLT5nZXRNZXRhRGF0YSgpOwoJCQl0cnkKCQkJewoJCQkgICAgc2FsX0ludDMyIG5NYXggPSB4TWV0YURhdGEtPmdldE1heFRhYmxlc0luU2VsZWN0KCk7CiAgICAgICAgICAgICAgICBpZiAoIG5NYXggJiYgbk1heCA8IChzYWxfSW50MzIpYU1hcC5zaXplKCkgKQogICAgICAgICAgICAgICAgewoJCQkJCWVFcnJvckNvZGUgPSBlVG9vTWFueVRhYmxlczsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KCgkJCQk6OnJ0bDo6T1VTdHJpbmcgc0NvbXBvc2VkTmFtZTsKCQkJCTo6cnRsOjpPVVN0cmluZyBhUXVhbGlmaWVyTmFtZTsKCQkJCTo6cnRsOjpPVVN0cmluZyBzQWxpYXM7CgoJCQkJT1F1ZXJ5VGFibGVWaWV3KiBwVGFibGVWaWV3ID0gc3RhdGljX2Nhc3Q8T1F1ZXJ5VGFibGVWaWV3Kj4oX3BWaWV3LT5nZXRUYWJsZVZpZXcoKSk7CiAgICAgICAgICAgICAgICBwVGFibGVWaWV3LT5jbGVhckxheW91dEluZm9ybWF0aW9uKCk7CgkJCQlPU1FMVGFibGVzOjpjb25zdF9pdGVyYXRvciBhSXRlciA9IGFNYXAuYmVnaW4oKTsKICAgICAgICAgICAgICAgIE9TUUxUYWJsZXM6OmNvbnN0X2l0ZXJhdG9yIGFFbmQgPSBhTWFwLmVuZCgpOwoJCQkJZm9yKDthSXRlciAhPSBhRW5kOysrYUl0ZXIpCgkJCQl7CgkJCQkJT1NRTFRhYmxlIHhUYWJsZSA9IGFJdGVyLT5zZWNvbmQ7CiAgICAgICAgICAgICAgICAgICAgUmVmZXJlbmNlPCBYUHJvcGVydHlTZXQgPiB4VGFibGVQcm9wcyggeFRhYmxlLCBVTk9fUVVFUllfVEhST1cgKTsKCgkJCQkJc0FsaWFzID0gYUl0ZXItPmZpcnN0OwoKICAgICAgICAgICAgICAgICAgICAvLyBjaGVjayB3aGV0aGVyIHRoaXMgaXMgYSBxdWVyeQogICAgICAgICAgICAgICAgICAgIFJlZmVyZW5jZTwgWFByb3BlcnR5U2V0SW5mbyA+IHhQU0kgPSB4VGFibGVQcm9wcy0+Z2V0UHJvcGVydHlTZXRJbmZvKCk7CiAgICAgICAgICAgICAgICAgICAgYm9vbCBiSXNRdWVyeSA9IHhQU0kuaXMoKSAmJiB4UFNJLT5oYXNQcm9wZXJ0eUJ5TmFtZSggUFJPUEVSVFlfQ09NTUFORCApOwoKICAgICAgICAgICAgICAgICAgICBpZiAoIGJJc1F1ZXJ5ICkKICAgICAgICAgICAgICAgICAgICAgICAgT1NMX1ZFUklGWSggeFRhYmxlUHJvcHMtPmdldFByb3BlcnR5VmFsdWUoIFBST1BFUlRZX05BTUUgKSA+Pj0gc0NvbXBvc2VkTmFtZSApOwogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHNDb21wb3NlZE5hbWUgPSA6OmRidG9vbHM6OmNvbXBvc2VUYWJsZU5hbWUoIHhNZXRhRGF0YSwgeFRhYmxlUHJvcHMsIDo6ZGJ0b29sczo6ZUluRGF0YU1hbmlwdWxhdGlvbiwgZmFsc2UsIGZhbHNlLCBmYWxzZSApOwoKICAgICAgICAgICAgICAgICAgICAgICAgLy8gaWYgdGhlIGFsaWFzIGlzIHRoZSBjb21wbGV0ZSAoY29tcG9zZWQpIHRhYmxlLCB0aGVuIHNob3J0ZW4gaXQKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCBhS2V5Q29tcCggc0NvbXBvc2VkTmFtZSwgYUl0ZXItPmZpcnN0ICkgKQoJCQkJCSAgICB7CgkJCQkJCSAgICA6OnJ0bDo6T1VTdHJpbmcgc0NhdGFsb2csIHNTY2hlbWEsIHNUYWJsZTsKCQkJCQkJICAgIDo6ZGJ0b29sczo6cXVhbGlmaWVkTmFtZUNvbXBvbmVudHMoIHhNZXRhRGF0YSwgc0NvbXBvc2VkTmFtZSwgc0NhdGFsb2csIHNTY2hlbWEsIHNUYWJsZSwgOjpkYnRvb2xzOjplSW5EYXRhTWFuaXB1bGF0aW9uICk7CgkJCQkJCSAgICBzQWxpYXMgPSBzVGFibGU7CgkJCQkJICAgIH0KICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIC8vIGZpbmQgdGhlIGV4aXN0ZW50IHdpbmRvdyBmb3IgdGhpcyBhbGlhcwoJCQkJCU9RdWVyeVRhYmxlV2luZG93KiBwRXhpc3RlbnRXaW4JPSBwVGFibGVWaWV3LT5GaW5kVGFibGUoIHNBbGlhcyApOwoJCQkJCWlmICggIXBFeGlzdGVudFdpbiApCgkJCQkJewoJCQkJCQlwVGFibGVWaWV3LT5BZGRUYWJXaW4oIHNDb21wb3NlZE5hbWUsIHNBbGlhcywgc2FsX0ZhbHNlICk7ICAvLyBkb24ndCBjcmVhdGUgZGF0YSBoZXJlCgkJCQkJfQoJCQkJCWVsc2UKCQkJCQl7CgkJCQkJCS8vIHRoZXJlIGFscmVhZHkgZXhpc3RzIGEgd2luZG93IGZvciB0aGlzIGFsaWFzIC4uLi4KCQkJCQkJaWYgKCAhYUtleUNvbXAoIHBFeGlzdGVudFdpbi0+R2V0RGF0YSgpLT5HZXRDb21wb3NlZE5hbWUoKSwgc0NvbXBvc2VkTmFtZSApICkKCQkJCQkJCS8vIC4uLiBidXQgZm9yIGFub3RoZXIgY29tcGxldGUgdGFibGUgbmFtZSAtPiBuZXcgd2luZG93CgkJCQkJCQlwVGFibGVWaWV3LT5BZGRUYWJXaW4oc0NvbXBvc2VkTmFtZSwgc0FsaWFzKTsKCQkJCQl9CgkJCQl9CgoJCQkJLy8gbm93IGRlbGV0ZSB0aGUgZGF0YSBmb3Igd2hpY2ggd2UgaGF2ZW4ndCBhbnkgdGFibGV3aW5kb3cKCQkJCU9Kb2luVGFibGVWaWV3OjpPVGFibGVXaW5kb3dNYXAgYVRhYmxlTWFwKCpwVGFibGVWaWV3LT5HZXRUYWJXaW5NYXAoKSk7CgkJCQlPSm9pblRhYmxlVmlldzo6T1RhYmxlV2luZG93TWFwOjppdGVyYXRvciBhSXRlclRhYmxlTWFwID0gYVRhYmxlTWFwLmJlZ2luKCk7CiAgICAgICAgICAgICAgICBPSm9pblRhYmxlVmlldzo6T1RhYmxlV2luZG93TWFwOjppdGVyYXRvciBhSXRlclRhYmxlRW5kID0gYVRhYmxlTWFwLmVuZCgpOwoJCQkJZm9yKDthSXRlclRhYmxlTWFwICE9IGFJdGVyVGFibGVFbmQ7KythSXRlclRhYmxlTWFwKQoJCQkJewoJCQkJCWlmKGFNYXAuZmluZChhSXRlclRhYmxlTWFwLT5zZWNvbmQtPkdldENvbXBvc2VkTmFtZSgpKQk9PSBhTWFwLmVuZCgpICYmCgkJCQkJCWFNYXAuZmluZChhSXRlclRhYmxlTWFwLT5maXJzdCkJCQkJCQk9PSBhTWFwLmVuZCgpKQoJCQkJCQlwVGFibGVWaWV3LT5SZW1vdmVUYWJXaW4oYUl0ZXJUYWJsZU1hcC0+c2Vjb25kKTsKCQkJCX0KCgkJCQlpZiAoIGVPayA9PSAoZUVycm9yQ29kZSA9IEZpbGxPdXRlckpvaW5zKF9wVmlldyxwVGFibGVFeHAtPmdldENoaWxkKDApLT5nZXRDaGlsZCgxKSkpICkKCQkJCXsKCQkJCQkvLyBjaGVjayBpZiB3ZSBoYXZlIGEgZGlzdGluY3Qgc3RhdGVtZW50CgkJCQkJaWYoU1FMX0lTVE9LRU4ocFBhcnNlVHJlZS0+Z2V0Q2hpbGQoMSksRElTVElOQ1QpKQoJCQkJCXsKCQkJCQkJckNvbnRyb2xsZXIuc2V0RGlzdGluY3Qoc2FsX1RydWUpOwoJCQkJCQlyQ29udHJvbGxlci5JbnZhbGlkYXRlRmVhdHVyZShTSURfUVVFUllfRElTVElOQ1RfVkFMVUVTKTsKCQkJCQl9CgkJCQkJaWYgKCAoZUVycm9yQ29kZSA9IEluc3RhbGxGaWVsZHMoX3BWaWV3LHBQYXJzZVRyZWUsIHBUYWJsZVZpZXctPkdldFRhYldpbk1hcCgpKSkgPT0gZU9rICkKCQkJCQl7CgkJCQkJCS8vIEdldFNlbGVjdGlvbkNyaXRlcmlhIG11c3QgYmUgY2FsbGVkIGJlZm9yZSBHZXRIYXZpbmdDcml0ZXJpYQoJCQkJCQlzYWxfdUludDE2IG5MZXZlbD0wOwoKCQkJCQkJaWYgKCBlT2sgPT0gKGVFcnJvckNvZGUgPSBHZXRTZWxlY3Rpb25Dcml0ZXJpYShfcFZpZXcsX3BTZWxlY3Rpb25CcncscFBhcnNlVHJlZSxuTGV2ZWwpKSApCgkJCQkJCXsKCQkJCQkJCWlmICggZU9rID09IChlRXJyb3JDb2RlID0gR2V0R3JvdXBDcml0ZXJpYShfcFZpZXcsX3BTZWxlY3Rpb25CcncscFBhcnNlVHJlZSkpICkKCQkJCQkJCXsKCQkJCQkJCQlpZiAoIGVPayA9PSAoZUVycm9yQ29kZSA9IEdldEhhdmluZ0NyaXRlcmlhKF9wVmlldyxfcFNlbGVjdGlvbkJydyxwUGFyc2VUcmVlLG5MZXZlbCkpICkKCQkJCQkJCQl7CgkJCQkJCQkJCWlmICggZU9rID09IChlRXJyb3JDb2RlID0gR2V0T3JkZXJDcml0ZXJpYShfcFZpZXcsX3BTZWxlY3Rpb25CcncscFBhcnNlVHJlZSkpICkKCQkJCQkJCQkJCWluc2VydFVuVXNlZEZpZWxkcyhfcFZpZXcsX3BTZWxlY3Rpb25CcncpOwoJCQkJCQkJCX0KCQkJCQkJCX0KCQkJCQkJfQoJCQkJCX0KCQkJCX0KCQkJfQoJCQljYXRjaChTUUxFeGNlcHRpb24mKQoJCQl7CgkJCQlPU0xfQVNTRVJUKCEiZ2V0TWF4VGFibGVzSW5TZWxlY3QhIik7CgkJCX0KCQl9CiAgICAgICAgd2hpbGUgKCBmYWxzZSApOwoKCQkvLyBEdXJjaCBkYXMgTmV1ZXJ6ZXVnZW4gd3VyZGVuIHdpZWRlciBVbmRvLUFjdGlvbnMgaW4gZGVuIE1hbmFnZXIgZ2VzdGVsbHQKCQlyQ29udHJvbGxlci5DbGVhclVuZG9NYW5hZ2VyKCk7CgkJX3BTZWxlY3Rpb25CcnctPkludmFsaWRhdGUoKTsKCQlyZXR1cm4gZUVycm9yQ29kZTsKCX0KCS8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgkvKiogZmlsbFNlbGVjdFN1Ykxpc3QKCQlAcmV0dXJuCgkJCTxUUlVFLz4gd2hlbiBjb2x1bW5zIGNvdWxkIGJlIGluc2VydGVkIG90aGVyd2lzZSA8RkFMU0UvPgoJKi8KCS8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCglTcWxQYXJzZUVycm9yIGZpbGxTZWxlY3RTdWJMaXN0KAlPUXVlcnlEZXNpZ25WaWV3KiBfcFZpZXcsCgkJCQkJCQkJT0pvaW5UYWJsZVZpZXc6Ok9UYWJsZVdpbmRvd01hcCogX3BUYWJMaXN0KQoJewoJCVNxbFBhcnNlRXJyb3IgZUVycm9yQ29kZSA9IGVPazsKCQlzYWxfQm9vbCBiRmlyc3RGaWVsZCA9IHNhbF9UcnVlOwoJCTo6cnRsOjpPVVN0cmluZyBzQXN0ZXJpeChSVExfQ09OU1RBU0NJSV9VU1RSSU5HUEFSQU0oIioiKSk7CgkJT0pvaW5UYWJsZVZpZXc6Ok9UYWJsZVdpbmRvd01hcDo6aXRlcmF0b3IgYUl0ZXIgPSBfcFRhYkxpc3QtPmJlZ2luKCk7CiAgICAgICAgT0pvaW5UYWJsZVZpZXc6Ok9UYWJsZVdpbmRvd01hcDo6aXRlcmF0b3IgYUVuZCA9IF9wVGFiTGlzdC0+ZW5kKCk7CgkJZm9yKDthSXRlciAhPSBhRW5kICYmIGVPayA9PSBlRXJyb3JDb2RlIDsrK2FJdGVyKQoJCXsKCQkJT1F1ZXJ5VGFibGVXaW5kb3cqIHBUYWJXaW4gPSBzdGF0aWNfY2FzdDxPUXVlcnlUYWJsZVdpbmRvdyo+KGFJdGVyLT5zZWNvbmQpOwogICAgICAgICAgICBPVGFibGVGaWVsZERlc2NSZWYJYUluZm8gPSBuZXcgT1RhYmxlRmllbGREZXNjKCk7CgkJCWlmIChwVGFiV2luLT5FeGlzdHNGaWVsZCggc0FzdGVyaXgsIGFJbmZvICkpCgkJCXsKCQkJCWVFcnJvckNvZGUgPSBfcFZpZXctPkluc2VydEZpZWxkKGFJbmZvLCBzYWxfVHJ1ZSwgYkZpcnN0RmllbGQpOwoJCQkJYkZpcnN0RmllbGQgPSBzYWxfRmFsc2U7CgkJCX0KCQl9CgkJcmV0dXJuIGVFcnJvckNvZGU7Cgl9CgkvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoJU3FsUGFyc2VFcnJvciBJbnN0YWxsRmllbGRzKE9RdWVyeURlc2lnblZpZXcqIF9wVmlldywKCQkJCQkJCQljb25zdCA6OmNvbm5lY3Rpdml0eTo6T1NRTFBhcnNlTm9kZSogcE5vZGUsCgkJCQkJCQkJT0pvaW5UYWJsZVZpZXc6Ok9UYWJsZVdpbmRvd01hcCogcFRhYkxpc3QgKQoJewoJCWlmKCBwTm9kZT09MCB8fCAhU1FMX0lTUlVMRShwTm9kZSxzZWxlY3Rfc3RhdGVtZW50KSkKCQkJcmV0dXJuIGVOb1NlbGVjdFN0YXRlbWVudDsKCgkJOjpjb25uZWN0aXZpdHk6Ok9TUUxQYXJzZU5vZGUqIHBQYXJzZVRyZWUgPSBwTm9kZS0+Z2V0Q2hpbGQoMik7IC8vIHNlbGVjdGlvbgoJCXNhbF9Cb29sIGJGaXJzdEZpZWxkID0gc2FsX1RydWU7CS8vIGJlaSBkZXIgSW5pdGlhbGlzaWVydW5nIG113yBhdWYgYWxsZSBGYWVsbGUgZGFzIGVyc3RlIEZlbGQgbmV1IGFrdGl2aWVydCB3ZXJkZW4KCgkJU3FsUGFyc2VFcnJvciBlRXJyb3JDb2RlID0gZU9rOwoKCQlpZiAoIHBQYXJzZVRyZWUtPmlzUnVsZSgpICYmIFNRTF9JU1BVTkNUVUFUSU9OKHBQYXJzZVRyZWUtPmdldENoaWxkKDApLCIqIikgKQoJCXsKCQkJLy8gU0VMRUNUICogLi4uCgkJCWVFcnJvckNvZGUgPSBmaWxsU2VsZWN0U3ViTGlzdChfcFZpZXcscFRhYkxpc3QpOwoJCX0KCQllbHNlIGlmIChTUUxfSVNSVUxFKHBQYXJzZVRyZWUsc2NhbGFyX2V4cF9jb21tYWxpc3QpICkKCQl7CgkJCS8vIFNFTEVDVCBjb2x1bW4sIC4uLgoJCQlPUXVlcnlDb250cm9sbGVyJiByQ29udHJvbGxlciA9IHN0YXRpY19jYXN0PE9RdWVyeUNvbnRyb2xsZXImPihfcFZpZXctPmdldENvbnRyb2xsZXIoKSk7CgkJCVJlZmVyZW5jZTwgWENvbm5lY3Rpb24+IHhDb25uZWN0aW9uID0gckNvbnRyb2xsZXIuZ2V0Q29ubmVjdGlvbigpOwoKCQkJOjpydGw6Ok9VU3RyaW5nIGFDb2x1bW5OYW1lLGFUYWJsZVJhbmdlOwoJCQlmb3IgKHNhbF91SW50MzIgaSA9IDA7IGkgPCBwUGFyc2VUcmVlLT5jb3VudCgpICYmIGVPayA9PSBlRXJyb3JDb2RlIDsgKytpKQoJCQl7CgkJCQk6OmNvbm5lY3Rpdml0eTo6T1NRTFBhcnNlTm9kZSAqIHBDb2x1bW5SZWYgPSBwUGFyc2VUcmVlLT5nZXRDaGlsZChpKTsKCiAgICAgICAgICAgICAgICBkbyB7CgogICAgICAgICAgICAgICAgaWYgKCBTUUxfSVNSVUxFKHBDb2x1bW5SZWYsc2VsZWN0X3N1Ymxpc3QpICkKCQkJCXsKCQkJCQkgZUVycm9yQ29kZSA9IGZpbGxTZWxlY3RTdWJMaXN0KF9wVmlldyxwVGFiTGlzdCk7CiAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwoJCQkJfQoKICAgICAgICAgICAgICAgIGlmICggU1FMX0lTUlVMRShwQ29sdW1uUmVmLGRlcml2ZWRfY29sdW1uKSApCgkJCQl7CgkJCQkJOjpydGw6Ok9VU3RyaW5nIGFDb2x1bW5BbGlhcyhyQ29udHJvbGxlci5nZXRQYXJzZUl0ZXJhdG9yKCkuZ2V0Q29sdW1uQWxpYXMocENvbHVtblJlZikpOyAvLyBrYW5uIGxlZXIgc2VpbgoJCQkJCXBDb2x1bW5SZWYgPSBwQ29sdW1uUmVmLT5nZXRDaGlsZCgwKTsKCQkJCQlPVGFibGVGaWVsZERlc2NSZWYgYUluZm8gPSBuZXcgT1RhYmxlRmllbGREZXNjKCk7CgoJCQkJCWlmICgJcENvbHVtblJlZi0+Y291bnQoKSA9PSAzICYmCgkJCQkJCQlTUUxfSVNQVU5DVFVBVElPTihwQ29sdW1uUmVmLT5nZXRDaGlsZCgwKSwiKCIpICYmCgkJCQkJCQlTUUxfSVNQVU5DVFVBVElPTihwQ29sdW1uUmVmLT5nZXRDaGlsZCgyKSwiKSIpCgkJCQkJCSkKCQkJCQkJcENvbHVtblJlZiA9IHBDb2x1bW5SZWYtPmdldENoaWxkKDEpOwoKCQkJCQlpZiAoU1FMX0lTUlVMRShwQ29sdW1uUmVmLGNvbHVtbl9yZWYpKQoJCQkJCXsKCQkJCQkJSW5zZXJ0Q29sdW1uUmVmKF9wVmlldyxwQ29sdW1uUmVmLGFDb2x1bW5OYW1lLGFDb2x1bW5BbGlhcyxhVGFibGVSYW5nZSxhSW5mbyxwVGFiTGlzdCk7CgkJCQkJCWVFcnJvckNvZGUgPSBfcFZpZXctPkluc2VydEZpZWxkKGFJbmZvLCBzYWxfVHJ1ZSwgYkZpcnN0RmllbGQpOwoJCQkJCQliRmlyc3RGaWVsZCA9IHNhbF9GYWxzZTsKCQkJCQl9CgkJCQkJZWxzZSBpZihTUUxfSVNSVUxFT1IyKHBDb2x1bW5SZWYsZ2VuZXJhbF9zZXRfZmN0ICxzZXRfZmN0X3NwZWMpCXx8CgkJCQkJCQlTUUxfSVNSVUxFT1IyKHBDb2x1bW5SZWYscG9zaXRpb25fZXhwLGV4dHJhY3RfZXhwKQkJfHwKCQkJCQkJCVNRTF9JU1JVTEVPUjIocENvbHVtblJlZixmb2xkLGNoYXJfc3Vic3RyaW5nX2ZjdCkJCXx8CgkJCQkJCQlTUUxfSVNSVUxFT1IyKHBDb2x1bW5SZWYsbGVuZ3RoX2V4cCxjaGFyX3ZhbHVlX2ZjdCkpCgkJCQkJewoJCQkJCQk6OnJ0bDo6T1VTdHJpbmcgYUNvbHVtbnM7CiAgICAgICAgICAgICAgICAgICAgICAgIHBDb2x1bW5SZWYtPnBhcnNlTm9kZVRvUHJlZGljYXRlU3RyKGFDb2x1bW5zLAoJCQkJCQkJCQkJCQkgICAgICAgICAgICB4Q29ubmVjdGlvbiwKCQkJCQkJCQkJCQkJICAgICAgICAgICAgckNvbnRyb2xsZXIuZ2V0TnVtYmVyRm9ybWF0dGVyKCksCgkJCQkJCQkJCQkJCSAgICAgICAgICAgIF9wVmlldy0+Z2V0TG9jYWxlKCksCgkJCQkJCQkJCQkJCSAgICAgICAgICAgIHN0YXRpY19jYXN0PHNhbF9DaGFyPihfcFZpZXctPmdldERlY2ltYWxTZXBhcmF0b3IoKS50b0NoYXIoKSksCgkJCQkJCQkJCQkJCSAgICAgICAgICAgICZyQ29udHJvbGxlci5nZXRQYXJzZXIoKS5nZXRDb250ZXh0KCkpOwoJCQkJCQkvL3BDb2x1bW5SZWYtPnBhcnNlTm9kZVRvU3RyKAlhQ29sdW1ucywKCQkJCQkJLy8JCQkJCQkJeENvbm5lY3Rpb24sCgkJCQkJCS8vCQkJCQkJCSZyQ29udHJvbGxlci5nZXRQYXJzZXIoKS5nZXRDb250ZXh0KCksCgkJCQkJCS8vCQkJCQkJCXNhbF9UcnVlLAoJCQkJCQkvLwkJCQkJCQlzYWxfVHJ1ZSk7IC8vIHF1b3RlIGlzIHRvIHRydWUgYmVjYXVzZSB3ZSBuZWVkIHF1b3RlZCBlbGVtZW50cyBpbnNpZGUgdGhlIGZ1bmN0aW9uCgoJCQkJCQlzYWxfSW50MzIgbkZ1bmN0aW9uVHlwZSA9IEZLVF9OT05FOwoJCQkJCQk6OmNvbm5lY3Rpdml0eTo6T1NRTFBhcnNlTm9kZSogcFBhcmFtUmVmID0gTlVMTDsKCQkJCQkJc2FsX0ludDMyIG5Db2x1bW5SZWZQb3MgPSBwQ29sdW1uUmVmLT5jb3VudCgpIC0gMjsKCQkJCQkJaWYgKCBuQ29sdW1uUmVmUG9zID49IDAgJiYgc3RhdGljX2Nhc3Q8c2FsX3VJbnQzMj4obkNvbHVtblJlZlBvcykgPCBwQ29sdW1uUmVmLT5jb3VudCgpICkKCQkJCQkJCXBQYXJhbVJlZiA9IHBDb2x1bW5SZWYtPmdldENoaWxkKG5Db2x1bW5SZWZQb3MpOwoKCQkJCQkJaWYgKAlTUUxfSVNSVUxFKHBDb2x1bW5SZWYsZ2VuZXJhbF9zZXRfZmN0KQoJCQkJCQkJJiYJU1FMX0lTUlVMRShwUGFyYW1SZWYsY29sdW1uX3JlZikgKQoJCQkJCQl7CgkJCQkJCQkvLyBQYXJhbWV0ZXIgYXVmIENvbHVtbnJlZiBwciJ1ZmVuCgkJCQkJCQlJbnNlcnRDb2x1bW5SZWYoX3BWaWV3LHBQYXJhbVJlZixhQ29sdW1uTmFtZSxhQ29sdW1uQWxpYXMsYVRhYmxlUmFuZ2UsYUluZm8scFRhYkxpc3QpOwoJCQkJCQl9CgkJCQkJCWVsc2UgaWYgKCBTUUxfSVNSVUxFKHBDb2x1bW5SZWYsZ2VuZXJhbF9zZXRfZmN0KSApCgkJCQkJCXsKCQkJCQkJCWlmICggcFBhcmFtUmVmICYmIHBQYXJhbVJlZi0+Z2V0VG9rZW5WYWx1ZSgpLnRvQ2hhcigpID09ICcqJyApCgkJCQkJCQl7CgkJCQkJCQkJT0pvaW5UYWJsZVZpZXc6Ok9UYWJsZVdpbmRvd01hcDo6aXRlcmF0b3IgYUl0ZXIgPSBwVGFiTGlzdC0+YmVnaW4oKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPSm9pblRhYmxlVmlldzo6T1RhYmxlV2luZG93TWFwOjppdGVyYXRvciBhRW5kICA9IHBUYWJMaXN0LT5lbmQoKTsKCQkJCQkJCQlmb3IoO2FJdGVyICE9IGFFbmQ7KythSXRlcikKCQkJCQkJCQl7CgkJCQkJCQkJCU9RdWVyeVRhYmxlV2luZG93KiBwVGFiV2luID0gc3RhdGljX2Nhc3Q8T1F1ZXJ5VGFibGVXaW5kb3cqPihhSXRlci0+c2Vjb25kKTsKCQkJCQkJCQkJaWYgKHBUYWJXaW4tPkV4aXN0c0ZpZWxkKCA6OnJ0bDo6T1VTdHJpbmc6OmNyZWF0ZUZyb21Bc2NpaSgiKiIpLCBhSW5mbyApKQoJCQkJCQkJCQl7CgkJCQkJCQkJCQlhSW5mby0+U2V0QWxpYXMoU3RyaW5nKCkpOwoJCQkJCQkJCQkJYUluZm8tPlNldFRhYmxlKFN0cmluZygpKTsKCQkJCQkJCQkJCWJyZWFrOwoJCQkJCQkJCQl9CgkJCQkJCQkJfQoJCQkJCQkJfQoJCQkJCQkJZWxzZQoJCQkJCQkJewoJCQkJCQkJCTo6cnRsOjpPVVN0cmluZyBzRmllbGROYW1lID0gYUNvbHVtbnM7CgkJCQkJCQkJaWYgKCBwUGFyYW1SZWYgKQoJCQkJCQkJCXsJLy8gd2UgZ290IGFuIGFnZ3JlZ2F0ZSBmdW5jdGlvbiBidXQgd2l0aG91dCBjb2x1bW4gbmFtZSBpbnNpZGUKCQkJCQkJCQkJLy8gc28gd2Ugc2V0IHRoZSB3aG9sZSBhcmd1bWVudCBvZiB0aGUgZnVuY3Rpb24gYXMgZmllbGQgbmFtZQoJCQkJCQkJCQluRnVuY3Rpb25UeXBlIHw9IEZLVF9OVU1FUklDOwoJCQkJCQkJCQlzRmllbGROYW1lID0gOjpydGw6Ok9VU3RyaW5nKCk7CgkJCQkJCQkJCXBQYXJhbVJlZi0+cGFyc2VOb2RlVG9TdHIoCXNGaWVsZE5hbWUsCgkJCQkJCQkJCQkJCQkJeENvbm5lY3Rpb24sCgkJCQkJCQkJCQkJCQkJJnJDb250cm9sbGVyLmdldFBhcnNlcigpLmdldENvbnRleHQoKSwKCQkJCQkJCQkJCQkJCQlzYWxfVHJ1ZSwKCQkJCQkJCQkJCQkJCQlzYWxfVHJ1ZSk7IC8vIHF1b3RlIGlzIHRvIHRydWUgYmVjYXVzZSB3ZSBuZWVkIHF1b3RlZCBlbGVtZW50cyBpbnNpZGUgdGhlIGZ1bmN0aW9uCgkJCQkJCQkJfQoJCQkJCQkJCWFJbmZvLT5TZXREYXRhVHlwZShEYXRhVHlwZTo6RE9VQkxFKTsKCQkJCQkJCQlhSW5mby0+U2V0RmllbGRUeXBlKFRBQl9OT1JNQUxfRklFTEQpOwoJCQkJCQkJCWFJbmZvLT5TZXRGaWVsZChzRmllbGROYW1lKTsKCQkJCQkJCX0KCQkJCQkJCWFJbmZvLT5TZXRUYWJXaW5kb3coTlVMTCk7CgkJCQkJCQlhSW5mby0+U2V0RmllbGRBbGlhcyhhQ29sdW1uQWxpYXMpOwoJCQkJCQl9CgkJCQkJCWVsc2UKCQkJCQkJewogICAgICAgICAgICAgICAgICAgICAgICAgICAgX3BWaWV3LT5maWxsRnVuY3Rpb25JbmZvKHBDb2x1bW5SZWYsYUNvbHVtbnMsYUluZm8pOwoJCQkJCQkJYUluZm8tPlNldEZpZWxkQWxpYXMoYUNvbHVtbkFsaWFzKTsKCQkJCQkJfQoKCQkJCQkJaWYgKCBTUUxfSVNSVUxFKHBDb2x1bW5SZWYsZ2VuZXJhbF9zZXRfZmN0KSApCgkJCQkJCXsKCQkJCQkJCWFJbmZvLT5TZXRGdW5jdGlvblR5cGUobkZ1bmN0aW9uVHlwZXxGS1RfQUdHUkVHQVRFKTsKCQkJCQkJCVN0cmluZyBhQ29sKGFDb2x1bW5zKTsKCQkJCQkJCWFJbmZvLT5TZXRGdW5jdGlvbihhQ29sLkdldFRva2VuKDAsJygnKS5FcmFzZVRyYWlsaW5nQ2hhcnMoJyAnKSk7CgkJCQkJCX0KCQkJCQkJZWxzZQoJCQkJCQkJYUluZm8tPlNldEZ1bmN0aW9uVHlwZShuRnVuY3Rpb25UeXBlfEZLVF9PVEhFUik7CgoJCQkJCQllRXJyb3JDb2RlID0gX3BWaWV3LT5JbnNlcnRGaWVsZChhSW5mbywgc2FsX1RydWUsIGJGaXJzdEZpZWxkKTsKCQkJCQkJYkZpcnN0RmllbGQgPSBzYWxfRmFsc2U7CgkJCQkJfQoJCQkJCWVsc2UgLy9pZihTUUxfSVNSVUxFKHBDb2x1bW5SZWYsbnVtX3ZhbHVlX2V4cCkJfHwgU1FMX0lTUlVMRShwQ29sdW1uUmVmLHRlcm0pKQoJCQkJCXsKCQkJCQkJOjpydGw6Ok9VU3RyaW5nIGFDb2x1bW5zOwoJCQkJCQlwQ29sdW1uUmVmLT5wYXJzZU5vZGVUb1N0cigJYUNvbHVtbnMsCgkJCQkJCQkJCQkJCQl4Q29ubmVjdGlvbiwKCQkJCQkJCQkJCQkJCSZyQ29udHJvbGxlci5nZXRQYXJzZXIoKS5nZXRDb250ZXh0KCksCgkJCQkJCQkJCQkJCQlzYWxfVHJ1ZSwKCQkJCQkJCQkJCQkJCXNhbF9UcnVlKTsgLy8gcXVvdGUgaXMgdG8gdHJ1ZSBiZWNhdXNlIHdlIG5lZWQgcXVvdGVkIGVsZW1lbnRzIGluc2lkZSB0aGUgZnVuY3Rpb24KCiAgICAgICAgICAgICAgICAgICAgICAgIGFJbmZvLT5TZXRUYWJXaW5kb3coIE5VTEwgKTsKCiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHNpbmNlIHdlIHN1cHBvcnQgcXVlcmllcyBpbiBxdWVyaWVzLCB0aGUgdGhpbmdpZSBtaWdodCBiZWxvbmcgdG8gYW4gZXhpc3RpbmcgInRhYmxlIgogICAgICAgICAgICAgICAgICAgICAgICBPUXVlcnlUYWJsZVdpbmRvdyogcEV4aXN0aW5nVGFibGUgPSBsY2xfZmluZENvbHVtbkluVGFibGVzKCBhQ29sdW1ucywgKnBUYWJMaXN0LCBhSW5mbyApOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoIHBFeGlzdGluZ1RhYmxlICkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgYUluZm8tPlNldFRhYldpbmRvdyggcEV4aXN0aW5nVGFibGUgKTsKCQkJCQkgICAgICAgIGFJbmZvLT5TZXRUYWJsZSggcEV4aXN0aW5nVGFibGUtPkdldFRhYmxlTmFtZSgpICk7CgkJCQkJICAgICAgICBhSW5mby0+U2V0QWxpYXMoIHBFeGlzdGluZ1RhYmxlLT5HZXRBbGlhc05hbWUoKSApOwogICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICBhSW5mby0+U2V0RGF0YVR5cGUoRGF0YVR5cGU6OkRPVUJMRSk7CgkJCQkJCWFJbmZvLT5TZXRGaWVsZFR5cGUoVEFCX05PUk1BTF9GSUVMRCk7CgkJCQkJCWFJbmZvLT5TZXRGaWVsZChhQ29sdW1ucyk7CgkJCQkJCWFJbmZvLT5TZXRGaWVsZEFsaWFzKGFDb2x1bW5BbGlhcyk7CgkJCQkJCWFJbmZvLT5TZXRGdW5jdGlvblR5cGUoRktUX05VTUVSSUMgfCBGS1RfT1RIRVIpOwoKCQkJCQkJZUVycm9yQ29kZSA9IF9wVmlldy0+SW5zZXJ0RmllbGQoYUluZm8sIHNhbF9UcnVlLCBiRmlyc3RGaWVsZCk7CgkJCQkJCWJGaXJzdEZpZWxkID0gc2FsX0ZhbHNlOwoJCQkJCX0KCiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgkJCQl9CgogICAgICAgICAgICAgICAgREJHX0VSUk9SKCAiSW5zdGFsbEZpZWxkczogZG9uJ3Qga25vdyBob3cgdG8gaW50ZXJwcmV0IHRoaXMgcGFyc2Ugbm9kZSEiICk7CgogICAgICAgICAgICAgICAgfSB3aGlsZSAoIGZhbHNlICk7CgkJCX0KCQl9CgkJZWxzZQoJCQllRXJyb3JDb2RlID0gZVN0YXRlbWVudFRvb0NvbXBsZXg7CgoJCXJldHVybiBlRXJyb3JDb2RlOwoJfQoJLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCVNxbFBhcnNlRXJyb3IgR2V0T3JkZXJDcml0ZXJpYSgJT1F1ZXJ5RGVzaWduVmlldyogX3BWaWV3LAoJCQkJCQkJT1NlbGVjdGlvbkJyb3dzZUJveCogX3BTZWxlY3Rpb25CcncsCgkJCQkJCQljb25zdCA6OmNvbm5lY3Rpdml0eTo6T1NRTFBhcnNlTm9kZSogcFBhcnNlUm9vdCApCgl7CgkJU3FsUGFyc2VFcnJvciBlRXJyb3JDb2RlID0gZU9rOwoJCWlmICghcFBhcnNlUm9vdC0+Z2V0Q2hpbGQoMyktPmdldENoaWxkKE9SREVSX0JZX0NISUxEX1BPUyktPmlzTGVhZigpKQoJCXsKCQkJOjpjb25uZWN0aXZpdHk6Ok9TUUxQYXJzZU5vZGUqIHBOb2RlID0gcFBhcnNlUm9vdC0+Z2V0Q2hpbGQoMyktPmdldENoaWxkKE9SREVSX0JZX0NISUxEX1BPUyktPmdldENoaWxkKDIpOwoJCQk6OmNvbm5lY3Rpdml0eTo6T1NRTFBhcnNlTm9kZSogcFBhcmFtUmVmID0gTlVMTDsKCiAgICAgICAgICAgIE9RdWVyeUNvbnRyb2xsZXImIHJDb250cm9sbGVyID0gc3RhdGljX2Nhc3Q8T1F1ZXJ5Q29udHJvbGxlciY+KF9wVmlldy0+Z2V0Q29udHJvbGxlcigpKTsKCQkJRU9yZGVyRGlyIGVPcmRlckRpcjsKCQkJT1RhYmxlRmllbGREZXNjUmVmIGFEcmFnTGVmdCA9IG5ldyBPVGFibGVGaWVsZERlc2MoKTsKCQkJZm9yKCBzYWxfdUludDMyIGk9MCA7IGk8cE5vZGUtPmNvdW50KCkgOyBpKysgKQoJCQl7CgkJCQllT3JkZXJEaXIgPSBPUkRFUl9BU0M7CgkJCQk6OmNvbm5lY3Rpdml0eTo6T1NRTFBhcnNlTm9kZSoJcENoaWxkID0gcE5vZGUtPmdldENoaWxkKCBpICk7CgoJCQkJaWYgKFNRTF9JU1RPS0VOKCBwQ2hpbGQtPmdldENoaWxkKDEpLCBERVNDICkgKQoJCQkJCWVPcmRlckRpciA9IE9SREVSX0RFU0M7CgogICAgICAgICAgICAgICAgOjpjb25uZWN0aXZpdHk6Ok9TUUxQYXJzZU5vZGUqIHBBcmd1bWVudCA9IHBDaGlsZC0+Z2V0Q2hpbGQoMCk7CgoJCQkJaWYoU1FMX0lTUlVMRShwQXJndW1lbnQsY29sdW1uX3JlZikpCgkJCQl7CgkJCQkJaWYoIGVPayA9PSBGaWxsRHJhZ0luZm8oX3BWaWV3LHBBcmd1bWVudCxhRHJhZ0xlZnQpKQoJCQkJCQlfcFNlbGVjdGlvbkJydy0+QWRkT3JkZXIoIGFEcmFnTGVmdCwgZU9yZGVyRGlyLCBpKTsKCQkJCQllbHNlIC8vIGl0IGNvdWxkIGJlIGEgYWxpYXMgbmFtZSBmb3IgYSBmaWVsZAoJCQkJCXsKCQkJCQkJOjpydGw6Ok9VU3RyaW5nIGFUYWJsZVJhbmdlLGFDb2x1bW5OYW1lOwoJCQkJCQk6OmNvbm5lY3Rpdml0eTo6T1NRTFBhcnNlVHJlZUl0ZXJhdG9yJiByUGFyc2VJdGVyID0gckNvbnRyb2xsZXIuZ2V0UGFyc2VJdGVyYXRvcigpOwoJCQkJCQlyUGFyc2VJdGVyLmdldENvbHVtblJhbmdlKCBwQXJndW1lbnQsIGFDb2x1bW5OYW1lLCBhVGFibGVSYW5nZSApOwoKCQkJCQkJT1RhYmxlRmllbGRzJiBhTGlzdCA9IHJDb250cm9sbGVyLmdldFRhYmxlRmllbGREZXNjKCk7CgkJCQkJCU9UYWJsZUZpZWxkczo6aXRlcmF0b3IgYUl0ZXIgPSBhTGlzdC5iZWdpbigpOwogICAgICAgICAgICAgICAgICAgICAgICBPVGFibGVGaWVsZHM6Oml0ZXJhdG9yIGFFbmQgPSBhTGlzdC5lbmQoKTsKCQkJCQkJZm9yKDthSXRlciAhPSBhRW5kOysrYUl0ZXIpCgkJCQkJCXsKCQkJCQkJCU9UYWJsZUZpZWxkRGVzY1JlZiBwRW50cnkgPSAqYUl0ZXI7CgkJCQkJCQlpZihwRW50cnkuaXNWYWxpZCgpICYmIHBFbnRyeS0+R2V0RmllbGRBbGlhcygpID09IGFDb2x1bW5OYW1lKQoJCQkJCQkJCXBFbnRyeS0+U2V0T3JkZXJEaXIoIGVPcmRlckRpciApOwoJCQkJCQl9CgkJCQkJfQoJCQkJfQoJCQkJZWxzZSBpZihTUUxfSVNSVUxFKHBBcmd1bWVudCwgZ2VuZXJhbF9zZXRfZmN0ICkgJiYKCQkJCQkJU1FMX0lTUlVMRShwUGFyYW1SZWYgPSBwQXJndW1lbnQtPmdldENoaWxkKHBBcmd1bWVudC0+Y291bnQoKS0yKSxjb2x1bW5fcmVmKSAmJgoJCQkJCQllT2sgPT0gRmlsbERyYWdJbmZvKF9wVmlldyxwUGFyYW1SZWYsYURyYWdMZWZ0KSkKCQkJCQlfcFNlbGVjdGlvbkJydy0+QWRkT3JkZXIoIGFEcmFnTGVmdCwgZU9yZGVyRGlyLCBpICk7CiAgICAgICAgICAgICAgICBlbHNlIGlmKCBTUUxfSVNSVUxFKHBBcmd1bWVudCwgc2V0X2ZjdF9zcGVjICkgKQogICAgICAgICAgICAgICAgewoKCQkgICAgICAgICAgICBSZWZlcmVuY2U8IFhDb25uZWN0aW9uPiB4Q29ubmVjdGlvbiA9IHJDb250cm9sbGVyLmdldENvbm5lY3Rpb24oKTsKCQkgICAgICAgICAgICBpZih4Q29ubmVjdGlvbi5pcygpKQoJCSAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgOjpydGw6Ok9VU3RyaW5nIHNDb25kaXRpb247CgkJCSAgICAgICAgICAgIHBBcmd1bWVudC0+cGFyc2VOb2RlVG9QcmVkaWNhdGVTdHIoc0NvbmRpdGlvbiwKCQkJCQkJCQkJCQkJICAgICAgICAgICAgeENvbm5lY3Rpb24sCgkJCQkJCQkJCQkJCSAgICAgICAgICAgIHJDb250cm9sbGVyLmdldE51bWJlckZvcm1hdHRlcigpLAoJCQkJCQkJCQkJCQkgICAgICAgICAgICBfcFZpZXctPmdldExvY2FsZSgpLAoJCQkJCQkJCQkJCQkgICAgICAgICAgICBzdGF0aWNfY2FzdDxzYWxfQ2hhcj4oX3BWaWV3LT5nZXREZWNpbWFsU2VwYXJhdG9yKCkudG9DaGFyKCkpLAoJCQkJCQkJCQkJCQkgICAgICAgICAgICAmckNvbnRyb2xsZXIuZ2V0UGFyc2VyKCkuZ2V0Q29udGV4dCgpKTsKICAgICAgICAgICAgICAgICAgICAgICAgX3BWaWV3LT5maWxsRnVuY3Rpb25JbmZvKHBBcmd1bWVudCxzQ29uZGl0aW9uLGFEcmFnTGVmdCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGFEcmFnTGVmdC0+U2V0RnVuY3Rpb25UeXBlKEZLVF9PVEhFUik7CiAgICAgICAgICAgICAgICAgICAgICAgIGFEcmFnTGVmdC0+U2V0T3JkZXJEaXIoZU9yZGVyRGlyKTsKICAgICAgICAgICAgICAgICAgICAgICAgYURyYWdMZWZ0LT5TZXRWaXNpYmxlKHNhbF9GYWxzZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIF9wU2VsZWN0aW9uQnJ3LT5BZGRPcmRlciggYURyYWdMZWZ0LCBlT3JkZXJEaXIsIGkgKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICBlRXJyb3JDb2RlID0gZUNvbHVtbk5vdEZvdW5kOwogICAgICAgICAgICAgICAgfQoJCQkJZWxzZQoJCQkJCWVFcnJvckNvZGUgPSBlQ29sdW1uTm90Rm91bmQ7CgkJCX0KCQl9CgkJcmV0dXJuIGVFcnJvckNvZGU7Cgl9CgkvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoJU3FsUGFyc2VFcnJvciBHZXRIYXZpbmdDcml0ZXJpYSgJT1F1ZXJ5RGVzaWduVmlldyogX3BWaWV3LAoJCQkJCQkJT1NlbGVjdGlvbkJyb3dzZUJveCogX3BTZWxlY3Rpb25CcncsCgkJCQkJCQljb25zdCA6OmNvbm5lY3Rpdml0eTo6T1NRTFBhcnNlTm9kZSogcFNlbGVjdFJvb3QsCgkJCQkJCQlzYWxfdUludDE2JiByTGV2ZWwgKQoJewoJCVNxbFBhcnNlRXJyb3IgZUVycm9yQ29kZSA9IGVPazsKCQlpZiAoIXBTZWxlY3RSb290LT5nZXRDaGlsZCgzKS0+Z2V0Q2hpbGQoMyktPmlzTGVhZigpKQoJCQllRXJyb3JDb2RlID0gR2V0T1JDcml0ZXJpYShfcFZpZXcsX3BTZWxlY3Rpb25CcncscFNlbGVjdFJvb3QtPmdldENoaWxkKDMpLT5nZXRDaGlsZCgzKS0+Z2V0Q2hpbGQoMSksckxldmVsLCBzYWxfVHJ1ZSk7CgkJcmV0dXJuIGVFcnJvckNvZGU7Cgl9CgkvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoJU3FsUGFyc2VFcnJvciBHZXRHcm91cENyaXRlcmlhKAlPUXVlcnlEZXNpZ25WaWV3KiBfcFZpZXcsCgkJCQkJCQlPU2VsZWN0aW9uQnJvd3NlQm94KiBfcFNlbGVjdGlvbkJydywKCQkJCQkJCWNvbnN0IDo6Y29ubmVjdGl2aXR5OjpPU1FMUGFyc2VOb2RlKiBwU2VsZWN0Um9vdCApCgl7CgkJU3FsUGFyc2VFcnJvciBlRXJyb3JDb2RlID0gZU9rOwoJCWlmICghcFNlbGVjdFJvb3QtPmdldENoaWxkKDMpLT5nZXRDaGlsZCgyKS0+aXNMZWFmKCkpIC8vIG9wdF9ncm91cF9ieV9jbGF1c2UKCQl7CiAgICAgICAgICAgIE9RdWVyeUNvbnRyb2xsZXImIHJDb250cm9sbGVyID0gc3RhdGljX2Nhc3Q8T1F1ZXJ5Q29udHJvbGxlciY+KF9wVmlldy0+Z2V0Q29udHJvbGxlcigpKTsKCQkJOjpjb25uZWN0aXZpdHk6Ok9TUUxQYXJzZU5vZGUqIHBHcm91cEJ5ID0gcFNlbGVjdFJvb3QtPmdldENoaWxkKDMpLT5nZXRDaGlsZCgyKS0+Z2V0Q2hpbGQoMik7CgoJCQlmb3IoIHNhbF91SW50MzIgaT0wIDsgaSA8IHBHcm91cEJ5LT5jb3VudCgpICYmIGVPayA9PSBlRXJyb3JDb2RlOyArK2kgKQoJCQl7CiAgICAgICAgICAgICAgICBPVGFibGVGaWVsZERlc2NSZWYgYURyYWdJbmZvID0gbmV3IE9UYWJsZUZpZWxkRGVzYygpOwogICAgICAgICAgICAgICAgOjpjb25uZWN0aXZpdHk6Ok9TUUxQYXJzZU5vZGUqIHBQYXJhbVJlZiA9IE5VTEw7CgkJCQk6OmNvbm5lY3Rpdml0eTo6T1NRTFBhcnNlTm9kZSogcEFyZ3VtZW50ID0gcEdyb3VwQnktPmdldENoaWxkKCBpICk7CgkJCQlpZihTUUxfSVNSVUxFKHBBcmd1bWVudCxjb2x1bW5fcmVmKSkKCQkJCXsKCQkJCQlpZiAoIGVPayA9PSAoZUVycm9yQ29kZSA9IEZpbGxEcmFnSW5mbyhfcFZpZXcscEFyZ3VtZW50LGFEcmFnSW5mbykpICkKCQkJCQl7CgkJCQkJCWFEcmFnSW5mby0+U2V0R3JvdXBCeShzYWxfVHJ1ZSk7CgkJCQkJCV9wU2VsZWN0aW9uQnJ3LT5BZGRHcm91cEJ5KGFEcmFnSW5mbyxpKTsKCQkJCQl9CgkJCQl9CiAgICAgICAgICAgICAgICBlbHNlIGlmKFNRTF9JU1JVTEUocEFyZ3VtZW50LCBnZW5lcmFsX3NldF9mY3QgKSAmJgoJCQkJCQlTUUxfSVNSVUxFKHBQYXJhbVJlZiA9IHBBcmd1bWVudC0+Z2V0Q2hpbGQocEFyZ3VtZW50LT5jb3VudCgpLTIpLGNvbHVtbl9yZWYpICYmCgkJCQkJCWVPayA9PSBGaWxsRHJhZ0luZm8oX3BWaWV3LHBQYXJhbVJlZixhRHJhZ0luZm8pKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGFEcmFnSW5mby0+U2V0R3JvdXBCeShzYWxfVHJ1ZSk7CgkJCQkJX3BTZWxlY3Rpb25CcnctPkFkZEdyb3VwQnkoIGFEcmFnSW5mbywgaSApOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZSBpZiggU1FMX0lTUlVMRShwQXJndW1lbnQsIHNldF9mY3Rfc3BlYyApICkKICAgICAgICAgICAgICAgIHsKCQkgICAgICAgICAgICBSZWZlcmVuY2U8IFhDb25uZWN0aW9uPiB4Q29ubmVjdGlvbiA9IHJDb250cm9sbGVyLmdldENvbm5lY3Rpb24oKTsKCQkgICAgICAgICAgICBpZih4Q29ubmVjdGlvbi5pcygpKQoJCSAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgOjpydGw6Ok9VU3RyaW5nIHNHcm91cEJ5RXhwcmVzc2lvbjsKCQkJICAgICAgICAgICAgcEFyZ3VtZW50LT5wYXJzZU5vZGVUb1N0cigJc0dyb3VwQnlFeHByZXNzaW9uLAoJCQkJCQkJCQkJCQkJeENvbm5lY3Rpb24sCgkJCQkJCQkJCQkJCQkmckNvbnRyb2xsZXIuZ2V0UGFyc2VyKCkuZ2V0Q29udGV4dCgpLAoJCQkJCQkJCQkJCQkJc2FsX1RydWUsCgkJCQkJCQkJCQkJCQlzYWxfVHJ1ZSk7IC8vIHF1b3RlIGlzIHRvIHRydWUgYmVjYXVzZSB3ZSBuZWVkIHF1b3RlZCBlbGVtZW50cyBpbnNpZGUgdGhlIGZ1bmN0aW9uCiAgICAgICAgICAgICAgICAgICAgICAgIF9wVmlldy0+ZmlsbEZ1bmN0aW9uSW5mbyhwQXJndW1lbnQsc0dyb3VwQnlFeHByZXNzaW9uLGFEcmFnSW5mbyk7CiAgICAgICAgICAgICAgICAgICAgICAgIGFEcmFnSW5mby0+U2V0RnVuY3Rpb25UeXBlKEZLVF9PVEhFUik7CiAgICAgICAgICAgICAgICAgICAgICAgIGFEcmFnSW5mby0+U2V0R3JvdXBCeShzYWxfVHJ1ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGFEcmFnSW5mby0+U2V0VmlzaWJsZShzYWxfRmFsc2UpOwogICAgICAgICAgICAgICAgICAgICAgICBfcFNlbGVjdGlvbkJydy0+QWRkR3JvdXBCeSggYURyYWdJbmZvLCBpICk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgZUVycm9yQ29kZSA9IGVDb2x1bW5Ob3RGb3VuZDsKICAgICAgICAgICAgICAgIH0KCQkJfQoJCX0KCQlyZXR1cm4gZUVycm9yQ29kZTsKCX0KCiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoJU3RyaW5nIGdldFBhcnNlRXJyb3JNZXNzYWdlKCBTcWxQYXJzZUVycm9yIF9lRXJyb3JDb2RlICkKCXsKCQlzYWxfdUludDE2IG5SZXNJZDsKCQlzd2l0Y2goX2VFcnJvckNvZGUpCgkJewoJCQljYXNlIGVJbGxlZ2FsSm9pbjoKCQkJCW5SZXNJZCA9IFNUUl9RUllfSUxMRUdBTF9KT0lOOwoJCQkJYnJlYWs7CgkJCWNhc2UgZVN0YXRlbWVudFRvb0xvbmc6CgkJCQluUmVzSWQgPSBTVFJfUVJZX1RPT19MT05HX1NUQVRFTUVOVDsKCQkJCWJyZWFrOwoJCQljYXNlIGVOb0Nvbm5lY3Rpb246CgkJCQluUmVzSWQgPSBTVFJfUVJZX1NZTlRBWDsKCQkJCWJyZWFrOwoJCQljYXNlIGVOb1NlbGVjdFN0YXRlbWVudDoKCQkJCW5SZXNJZCA9IFNUUl9RUllfTk9TRUxFQ1Q7CgkJCQlicmVhazsKCQkJY2FzZSBlQ29sdW1uSW5MaWtlTm90Rm91bmQ6CgkJCQluUmVzSWQgPSBTVFJfUVJZX1NZTlRBWDsKCQkJCWJyZWFrOwoJCQljYXNlIGVOb0NvbHVtbkluTGlrZToKCQkJCW5SZXNJZCA9IFNUUl9RUllfU1lOVEFYOwoJCQkJYnJlYWs7CgkJCWNhc2UgZUNvbHVtbk5vdEZvdW5kOgoJCQkJblJlc0lkID0gU1RSX1FSWV9TWU5UQVg7CgkJCQlicmVhazsKCQkJY2FzZSBlTmF0aXZlTW9kZToKCQkJCW5SZXNJZCA9IFNUUl9RUllfTkFUSVZFOwoJCQkJYnJlYWs7CgkJCWNhc2UgZVRvb01hbnlUYWJsZXM6CgkJCQluUmVzSWQgPSBTVFJfUVJZX1RPT19NQU5ZX1RBQkxFUzsKCQkJCWJyZWFrOwoJCQljYXNlIGVUb29NYW55Q29uZGl0aW9uczoKCQkJCW5SZXNJZCA9IFNUUl9RUllfVE9PTUFOWUNPTkQ7CgkJCQlicmVhazsKCQkJY2FzZSBlVG9vTWFueUNvbHVtbnM6CgkJCQluUmVzSWQgPSBTVFJfUVJZX1RPT19NQU5ZX0NPTFVNTlM7CgkJCQlicmVhazsKCQkJY2FzZSBlU3RhdGVtZW50VG9vQ29tcGxleDoKCQkJCW5SZXNJZCA9IFNUUl9RUllfVE9PQ09NUExFWDsKCQkJCWJyZWFrOwoJCQlkZWZhdWx0OgoJCQkJblJlc0lkID0gU1RSX1FSWV9TWU5UQVg7CgkJCQlicmVhazsKCQl9CgkJOwogICAgICAgIHJldHVybiBTdHJpbmcoIE1vZHVsZVJlcyggblJlc0lkICkgKTsKCX0KCgkvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoJLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KfQovLyBlbmQgb2YgYW5vbnltb3VzZSBuYW1lc3BhY2UKREJHX05BTUUoT1F1ZXJ5RGVzaWduVmlldykKCk9RdWVyeURlc2lnblZpZXc6Ok9RdWVyeURlc2lnblZpZXcoCU9RdWVyeUNvbnRhaW5lcldpbmRvdyogX3BQYXJlbnQsCgkJCQkJCQkJCU9RdWVyeUNvbnRyb2xsZXImIF9yQ29udHJvbGxlciwKCQkJCQkJCQkJY29uc3QgUmVmZXJlbmNlPCBYTXVsdGlTZXJ2aWNlRmFjdG9yeSA+JiBfckZhY3RvcnkpCgk6T1F1ZXJ5VmlldyggX3BQYXJlbnQsIF9yQ29udHJvbGxlciwgX3JGYWN0b3J5ICkKCSxtX2FTcGxpdHRlciggdGhpcyApCgksbV9lQ2hpbGRGb2N1cyhOT05FKQoJLG1fYkluS2V5RXZlbnQoc2FsX0ZhbHNlKQoJLG1fYkluU3BsaXRIYW5kbGVyKCBzYWxfRmFsc2UgKQp7CiAgICBEQkdfQ1RPUihPUXVlcnlEZXNpZ25WaWV3LE5VTEwpOwoKCXRyeQoJewoJCVN2dFN5c0xvY2FsZSBhU3lzTG9jYWxlOwoJCW1fYUxvY2FsZSA9IGFTeXNMb2NhbGUuR2V0TG9jYWxlRGF0YSgpLmdldExvY2FsZSgpOwoJCW1fc0RlY2ltYWxTZXAgPSBhU3lzTG9jYWxlLkdldExvY2FsZURhdGEoKS5nZXROdW1EZWNpbWFsU2VwKCk7Cgl9CgljYXRjaChFeGNlcHRpb24mKQoJewoJfQoKCW1fcFNlbGVjdGlvbkJveCA9IG5ldyBPU2VsZWN0aW9uQnJvd3NlQm94KHRoaXMpOwoKCXNldE5vbmVWaXNibGVSb3coc3RhdGljX2Nhc3Q8T1F1ZXJ5Q29udHJvbGxlciY+KGdldENvbnRyb2xsZXIoKSkuZ2V0VmlzaWJsZVJvd3MoKSk7CgltX3BTZWxlY3Rpb25Cb3gtPlNob3coKTsKCS8vIFNwbGl0dGVyIGVpbnJpY2h0ZW4KCW1fYVNwbGl0dGVyLlNldFNwbGl0SGRsKExJTksodGhpcywgT1F1ZXJ5RGVzaWduVmlldyxTcGxpdEhkbCkpOwoJbV9hU3BsaXR0ZXIuU2hvdygpOwoKfQovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpPUXVlcnlEZXNpZ25WaWV3Ojp+T1F1ZXJ5RGVzaWduVmlldygpCnsKCWlmICggbV9wVGFibGVWaWV3ICkKCQk6OmRiYXVpOjpub3RpZnlTeXN0ZW1XaW5kb3codGhpcyxtX3BUYWJsZVZpZXcsOjpjb21waGVscGVyOjptZW1fZnVuKCZUYXNrUGFuZUxpc3Q6OlJlbW92ZVdpbmRvdykpOwoJOjpzdGQ6OmF1dG9fcHRyPFdpbmRvdz4gYVRlbXAobV9wU2VsZWN0aW9uQm94KTsKCW1fcFNlbGVjdGlvbkJveCA9IE5VTEw7CgogICAgREJHX0RUT1IoT1F1ZXJ5RGVzaWduVmlldyxOVUxMKTsKfQovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpJTVBMX0xJTksoIE9RdWVyeURlc2lnblZpZXcsIFNwbGl0SGRsLCB2b2lkKiwgLypwKi8gKQp7CglpZiAoIWdldENvbnRyb2xsZXIoKS5pc1JlYWRPbmx5KCkpCgl7CgkJbV9iSW5TcGxpdEhhbmRsZXIgPSBzYWxfVHJ1ZTsKCQltX2FTcGxpdHRlci5TZXRQb3NQaXhlbCggUG9pbnQoIG1fYVNwbGl0dGVyLkdldFBvc1BpeGVsKCkuWCgpLG1fYVNwbGl0dGVyLkdldFNwbGl0UG9zUGl4ZWwoKSApICk7CgkJc3RhdGljX2Nhc3Q8T1F1ZXJ5Q29udHJvbGxlciY+KGdldENvbnRyb2xsZXIoKSkuc2V0U3BsaXRQb3MobV9hU3BsaXR0ZXIuR2V0U3BsaXRQb3NQaXhlbCgpKTsKCQlzdGF0aWNfY2FzdDxPUXVlcnlDb250cm9sbGVyJj4oZ2V0Q29udHJvbGxlcigpKS5zZXRNb2RpZmllZCggc2FsX1RydWUgKTsKCQlSZXNpemUoKTsKCQltX2JJblNwbGl0SGFuZGxlciA9IHNhbF9UcnVlOwoJfQoJcmV0dXJuIDBMOwp9Ci8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBPUXVlcnlEZXNpZ25WaWV3OjpDb25zdHJ1Y3QoKQp7CgltX3BUYWJsZVZpZXcgPSBuZXcgT1F1ZXJ5VGFibGVWaWV3KG1fcFNjcm9sbFdpbmRvdyx0aGlzKTsKCTo6ZGJhdWk6Om5vdGlmeVN5c3RlbVdpbmRvdyh0aGlzLG1fcFRhYmxlVmlldyw6OmNvbXBoZWxwZXI6Om1lbV9mdW4oJlRhc2tQYW5lTGlzdDo6QWRkV2luZG93KSk7CglPUXVlcnlWaWV3OjpDb25zdHJ1Y3QoKTsKfQovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIE9RdWVyeURlc2lnblZpZXc6OmluaXRpYWxpemUoKQp7CglpZihzdGF0aWNfY2FzdDxPUXVlcnlDb250cm9sbGVyJj4oZ2V0Q29udHJvbGxlcigpKS5nZXRTcGxpdFBvcygpICE9IC0xKQoJewoJCW1fYVNwbGl0dGVyLlNldFBvc1BpeGVsKCBQb2ludCggbV9hU3BsaXR0ZXIuR2V0UG9zUGl4ZWwoKS5YKCksc3RhdGljX2Nhc3Q8T1F1ZXJ5Q29udHJvbGxlciY+KGdldENvbnRyb2xsZXIoKSkuZ2V0U3BsaXRQb3MoKSApICk7CgkJbV9hU3BsaXR0ZXIuU2V0U3BsaXRQb3NQaXhlbChzdGF0aWNfY2FzdDxPUXVlcnlDb250cm9sbGVyJj4oZ2V0Q29udHJvbGxlcigpKS5nZXRTcGxpdFBvcygpKTsKCX0KCW1fcFNlbGVjdGlvbkJveC0+aW5pdGlhbGl6ZSgpOwoJcmVzZXQoKTsKfQovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgT1F1ZXJ5RGVzaWduVmlldzo6cmVzaXplRG9jdW1lbnRWaWV3KFJlY3RhbmdsZSYgX3JQbGF5Z3JvdW5kKQp7CglQb2ludCBhUGxheWdyb3VuZFBvcyggX3JQbGF5Z3JvdW5kLlRvcExlZnQoKSApOwoJU2l6ZSBhUGxheWdyb3VuZFNpemUoIF9yUGxheWdyb3VuZC5HZXRTaXplKCkgKTsKCgkvLyBjYWxjIHRoZSBzcGxpdCBwb3MsIGFuZCBmb3J3YXJkIGl0IHRvIHRoZSBjb250cm9sbGVyCglzYWxfSW50MzIgblNwbGl0UG9zID0gc3RhdGljX2Nhc3Q8T1F1ZXJ5Q29udHJvbGxlciY+KGdldENvbnRyb2xsZXIoKSkuZ2V0U3BsaXRQb3MoKTsKCWlmICggMCAhPSBhUGxheWdyb3VuZFNpemUuSGVpZ2h0KCkgKQoJewoJCWlmCSgJKCAtMSA9PSBuU3BsaXRQb3MgKQoJCQl8fAkoIG5TcGxpdFBvcyA+PSBhUGxheWdyb3VuZFNpemUuSGVpZ2h0KCkgKQoJCQkpCgkJewoJCQkvLyBsZXQgdGhlIHNlbGVjdGlvbiBicm93c2UgYm94IGRldGVybWluZSBhbiBvcHRpbWFsIHNpemUKCQkJU2l6ZSBhU2VsZWN0aW9uQm94U2l6ZSA9IG1fcFNlbGVjdGlvbkJveC0+Q2FsY09wdGltYWxTaXplKCBhUGxheWdyb3VuZFNpemUgKTsKCQkJblNwbGl0UG9zID0gYVBsYXlncm91bmRTaXplLkhlaWdodCgpIC0gYVNlbGVjdGlvbkJveFNpemUuSGVpZ2h0KCkgLSBtX2FTcGxpdHRlci5HZXRTaXplUGl4ZWwoKS5IZWlnaHQoKTsKCQkJLy8gc3RpbGwgYW4gaW52YWxpZCBzaXplPwoJCQlpZiAoIG5TcGxpdFBvcyA9PSAtMSB8fCBuU3BsaXRQb3MgPj0gYVBsYXlncm91bmRTaXplLkhlaWdodCgpICkKCQkJCW5TcGxpdFBvcyA9IHNhbF9JbnQzMihhUGxheWdyb3VuZFNpemUuSGVpZ2h0KCkqMC42KTsKCgkJCXN0YXRpY19jYXN0PE9RdWVyeUNvbnRyb2xsZXImPihnZXRDb250cm9sbGVyKCkpLnNldFNwbGl0UG9zKG5TcGxpdFBvcyk7CgkJfQoKCQlpZiAoICFtX2JJblNwbGl0SGFuZGxlciApCgkJewkvLyB0aGUgcmVzaXplIGlzIHRyaWdnZXJlZCBieSBzb21ldGhpbmcgZWxzZSB0aGFuIHRoZSBzcGxpdCBoYW5kbGVyCgkJCS8vIG91ciBtYWluIGZvY3VzIGlzIHRvIHRyeSB0byBwcmVzZXJ2ZSB0aGUgc2l6ZSBvZiB0aGUgc2VsZWN0aW9uYnJvd3NlIGJveAoJCQlTaXplIGFTZWxCb3hTaXplID0gbV9wU2VsZWN0aW9uQm94LT5HZXRTaXplUGl4ZWwoKTsKCQkJaWYgKCBhU2VsQm94U2l6ZS5IZWlnaHQoKSApCgkJCXsKCQkJCS8vIGtlZXAgdGhlIHNpemUgb2YgdGhlIHNlbCBib3ggY29uc3RhbnQKCQkJCW5TcGxpdFBvcyA9IGFQbGF5Z3JvdW5kU2l6ZS5IZWlnaHQoKSAtIG1fYVNwbGl0dGVyLkdldFNpemVQaXhlbCgpLkhlaWdodCgpIC0gYVNlbEJveFNpemUuSGVpZ2h0KCk7CgoJCQkJLy8gYW5kIGlmIHRoZSBib3ggaXMgc21hbGxlciB0aGFuIHRoZSBvcHRpbWFsIHNpemUsIHRyeSB0byBkbyBzb21ldGhpbmcgYWJvdXQgaXQKCQkJCVNpemUgYVNlbEJveE9wdFNpemUgPSBtX3BTZWxlY3Rpb25Cb3gtPkNhbGNPcHRpbWFsU2l6ZSggYVBsYXlncm91bmRTaXplICk7CgkJCQlpZiAoIGFTZWxCb3hPcHRTaXplLkhlaWdodCgpID4gYVNlbEJveFNpemUuSGVpZ2h0KCkgKQoJCQkJewoJCQkJCW5TcGxpdFBvcyA9IGFQbGF5Z3JvdW5kU2l6ZS5IZWlnaHQoKSAtIG1fYVNwbGl0dGVyLkdldFNpemVQaXhlbCgpLkhlaWdodCgpIC0gYVNlbEJveE9wdFNpemUuSGVpZ2h0KCk7CgkJCQl9CgoJCQkJc3RhdGljX2Nhc3Q8IE9RdWVyeUNvbnRyb2xsZXImID4oZ2V0Q29udHJvbGxlcigpKS5zZXRTcGxpdFBvcyggblNwbGl0UG9zICk7CgkJCX0KCQl9Cgl9CgoJLy8gbm9ybWFsaXplIHRoZSBzcGxpdCBwb3MKCVBvaW50CWFTcGxpdFBvcwkJPSBQb2ludCggX3JQbGF5Z3JvdW5kLkxlZnQoKSwgblNwbGl0UG9zICk7CglTaXplCWFTcGxpdFNpemUJCT0gU2l6ZSggX3JQbGF5Z3JvdW5kLkdldFNpemUoKS5XaWR0aCgpLCBtX2FTcGxpdHRlci5HZXRTaXplUGl4ZWwoKS5IZWlnaHQoKSApOwoKCWlmKCAoIGFTcGxpdFBvcy5ZKCkgKyBhU3BsaXRTaXplLkhlaWdodCgpICkgPiAoIGFQbGF5Z3JvdW5kU2l6ZS5IZWlnaHQoKSApKQoJCWFTcGxpdFBvcy5ZKCkgPSBhUGxheWdyb3VuZFNpemUuSGVpZ2h0KCkgLSBhU3BsaXRTaXplLkhlaWdodCgpOwoKCWlmKCBhU3BsaXRQb3MuWSgpIDw9IGFQbGF5Z3JvdW5kUG9zLlkoKSApCgkJYVNwbGl0UG9zLlkoKSA9IGFQbGF5Z3JvdW5kUG9zLlkoKSArIHNhbF9JbnQzMihhUGxheWdyb3VuZFNpemUuSGVpZ2h0KCkgKiAwLjIpOwoKCS8vIHBvc2l0aW9uIHRoZSB0YWJsZQoJU2l6ZSBhVGFibGVWaWV3U2l6ZShhUGxheWdyb3VuZFNpemUuV2lkdGgoKSwgYVNwbGl0UG9zLlkoKSAtIGFQbGF5Z3JvdW5kUG9zLlkoKSk7CgltX3BTY3JvbGxXaW5kb3ctPlNldFBvc1NpemVQaXhlbChhUGxheWdyb3VuZFBvcywgYVRhYmxlVmlld1NpemUpOwoKCS8vIHBvc2l0aW9uIHRoZSBzZWxlY3Rpb24gYnJvd3NlIGJveAoJUG9pbnQgYVBvcyggYVBsYXlncm91bmRQb3MuWCgpLCBhU3BsaXRQb3MuWSgpICsgYVNwbGl0U2l6ZS5IZWlnaHQoKSApOwoJbV9wU2VsZWN0aW9uQm94LT5TZXRQb3NTaXplUGl4ZWwoIGFQb3MsIFNpemUoIGFQbGF5Z3JvdW5kU2l6ZS5XaWR0aCgpLCBhUGxheWdyb3VuZFNpemUuSGVpZ2h0KCkgLSBhU3BsaXRTaXplLkhlaWdodCgpIC0gYVRhYmxlVmlld1NpemUuSGVpZ2h0KCkgKSk7CgoJLy8gc2V0IHRoZSBzaXplIG9mIHRoZSBzcGxpdHRlcgoJbV9hU3BsaXR0ZXIuU2V0UG9zU2l6ZVBpeGVsKCBhU3BsaXRQb3MsIGFTcGxpdFNpemUgKTsKCW1fYVNwbGl0dGVyLlNldERyYWdSZWN0UGl4ZWwoIF9yUGxheWdyb3VuZCApOwoKCS8vIGp1c3QgZm9yIGNvbXBsZXRlbmVzczogdGhlcmUgaXMgbm8gc3BhY2UgbGVmdCwgd2Ugb2NjdXBpZWQgaXQgYWxsIC4uLgoJX3JQbGF5Z3JvdW5kLlNldFBvcyggX3JQbGF5Z3JvdW5kLkJvdHRvbVJpZ2h0KCkgKTsKCV9yUGxheWdyb3VuZC5TZXRTaXplKCBTaXplKCAwLCAwICkgKTsKfQovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIE9RdWVyeURlc2lnblZpZXc6OnNldFJlYWRPbmx5KHNhbF9Cb29sIF9iUmVhZE9ubHkpCnsKCW1fcFNlbGVjdGlvbkJveC0+U2V0UmVhZE9ubHkoX2JSZWFkT25seSk7Cn0KLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBPUXVlcnlEZXNpZ25WaWV3OjpjbGVhcigpCnsKCW1fcFNlbGVjdGlvbkJveC0+Q2xlYXJBbGwoKTsgLy8gY2xlYXIgdGhlIHdob2xlIHNlbGVjdGlvbgoJbV9wVGFibGVWaWV3LT5DbGVhckFsbCgpOwp9Ci8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgT1F1ZXJ5RGVzaWduVmlldzo6c2V0U3RhdGVtZW50KGNvbnN0IDo6cnRsOjpPVVN0cmluZyYgLypfcnNTdGF0ZW1lbnQqLykKewp9Ci8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgT1F1ZXJ5RGVzaWduVmlldzo6Y29weSgpCnsKCWlmKCBtX2VDaGlsZEZvY3VzID09IFNFTEVDVElPTikKCQltX3BTZWxlY3Rpb25Cb3gtPmNvcHkoKTsKfQovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpzYWxfQm9vbCBPUXVlcnlEZXNpZ25WaWV3Ojppc0N1dEFsbG93ZWQoKQp7CglzYWxfQm9vbCBiQWxsb3dlZCA9IHNhbF9GYWxzZTsKCWlmICggU0VMRUNUSU9OID09IG1fZUNoaWxkRm9jdXMgKQoJCWJBbGxvd2VkID0gbV9wU2VsZWN0aW9uQm94LT5pc0N1dEFsbG93ZWQoKTsKCXJldHVybiBiQWxsb3dlZDsKfQovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpzYWxfQm9vbCBPUXVlcnlEZXNpZ25WaWV3Ojppc1Bhc3RlQWxsb3dlZCgpCnsKCXNhbF9Cb29sIGJBbGxvd2VkID0gc2FsX0ZhbHNlOwoJaWYgKCBTRUxFQ1RJT04gPT0gbV9lQ2hpbGRGb2N1cyApCgkJYkFsbG93ZWQgPSBtX3BTZWxlY3Rpb25Cb3gtPmlzUGFzdGVBbGxvd2VkKCk7CglyZXR1cm4gYkFsbG93ZWQ7Cn0KLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kc2FsX0Jvb2wgT1F1ZXJ5RGVzaWduVmlldzo6aXNDb3B5QWxsb3dlZCgpCnsKCXNhbF9Cb29sIGJBbGxvd2VkID0gc2FsX0ZhbHNlOwoJaWYgKCBTRUxFQ1RJT04gPT0gbV9lQ2hpbGRGb2N1cyApCgkJYkFsbG93ZWQgPSBtX3BTZWxlY3Rpb25Cb3gtPmlzQ29weUFsbG93ZWQoKTsKCXJldHVybiBiQWxsb3dlZDsKfQovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIE9RdWVyeURlc2lnblZpZXc6OnN0b3BUaW1lcigpCnsKCW1fcFNlbGVjdGlvbkJveC0+c3RvcFRpbWVyKCk7Cn0KLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBPUXVlcnlEZXNpZ25WaWV3OjpzdGFydFRpbWVyKCkKewoJbV9wU2VsZWN0aW9uQm94LT5zdGFydFRpbWVyKCk7Cn0KLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBPUXVlcnlEZXNpZ25WaWV3OjpjdXQoKQp7CglpZiggbV9lQ2hpbGRGb2N1cyA9PSBTRUxFQ1RJT04pCgl7CgkJbV9wU2VsZWN0aW9uQm94LT5jdXQoKTsKCQlzdGF0aWNfY2FzdDxPUXVlcnlDb250cm9sbGVyJj4oZ2V0Q29udHJvbGxlcigpKS5zZXRNb2RpZmllZChzYWxfVHJ1ZSk7Cgl9Cn0KLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBPUXVlcnlEZXNpZ25WaWV3OjpwYXN0ZSgpCnsKCWlmKCBtX2VDaGlsZEZvY3VzID09IFNFTEVDVElPTikKCXsKCQltX3BTZWxlY3Rpb25Cb3gtPnBhc3RlKCk7CgkJc3RhdGljX2Nhc3Q8T1F1ZXJ5Q29udHJvbGxlciY+KGdldENvbnRyb2xsZXIoKSkuc2V0TW9kaWZpZWQoc2FsX1RydWUpOwoJfQp9Ci8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgT1F1ZXJ5RGVzaWduVmlldzo6VGFibGVEZWxldGVkKGNvbnN0IDo6cnRsOjpPVVN0cmluZyYgckFsaWFzTmFtZSkKewoJLy8gTmFjaHJpY2h0LCBkYXNzIFRhYmVsbGUgYXVzIGRlbSBGZW5zdGVyIGdlbCJvc2NodCB3dXJkZQoJRGVsZXRlRmllbGRzKHJBbGlhc05hbWUpOwoJc3RhdGljX2Nhc3Q8T1F1ZXJ5Q29udHJvbGxlciY+KGdldENvbnRyb2xsZXIoKSkuSW52YWxpZGF0ZUZlYXR1cmUoSURfQlJPV1NFUl9BRERUQUJMRSk7CS8vIHZpZXcgbm9jaG1hbCBiZXNjaGVpZCBzYWdlbgp9Ci8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgT1F1ZXJ5RGVzaWduVmlldzo6RGVsZXRlRmllbGRzKCBjb25zdCA6OnJ0bDo6T1VTdHJpbmcmIHJBbGlhc05hbWUgKQp7CgltX3BTZWxlY3Rpb25Cb3gtPkRlbGV0ZUZpZWxkcyggckFsaWFzTmFtZSApOwp9Ci8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCmJvb2wgT1F1ZXJ5RGVzaWduVmlldzo6SGFzRmllbGRCeUFsaWFzTmFtZShjb25zdCA6OnJ0bDo6T1VTdHJpbmcmIHJGaWVsZE5hbWUsIE9UYWJsZUZpZWxkRGVzY1JlZiYgckluZm8pICBjb25zdAp7CiAgICByZXR1cm4gbV9wU2VsZWN0aW9uQm94LT5IYXNGaWVsZEJ5QWxpYXNOYW1lKCByRmllbGROYW1lLCBySW5mbyk7Cn0KLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KU3FsUGFyc2VFcnJvciBPUXVlcnlEZXNpZ25WaWV3OjpJbnNlcnRGaWVsZCggY29uc3QgT1RhYmxlRmllbGREZXNjUmVmJiBySW5mbywgc2FsX0Jvb2wgYlZpcywgc2FsX0Jvb2wgYkFjdGl2YXRlKQp7CglyZXR1cm4gbV9wU2VsZWN0aW9uQm94LT5JbnNlcnRGaWVsZCggckluZm8sIEJST1dTRVJfSU5WQUxJRElELGJWaXMsIGJBY3RpdmF0ZSApLmlzVmFsaWQoKSA/IGVPayA6IGVUb29NYW55Q29sdW1uczsKfQovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpzYWxfSW50MzIgT1F1ZXJ5RGVzaWduVmlldzo6Z2V0Q29sV2lkdGgoc2FsX3VJbnQxNiBfbkNvbFBvcykgY29uc3QKewogICAgc3RhdGljIHNhbF9JbnQzMiBzX25EZWZhdWx0V2lkdGggPSBHZXRUZXh0V2lkdGgoU3RyaW5nKFJUTF9DT05TVEFTQ0lJX1VTVFJJTkdQQVJBTSgiMCIpKSkgKiAxNTsKICAgIHNhbF9JbnQzMiBuV2lkdGggPSBzdGF0aWNfY2FzdDxPUXVlcnlDb250cm9sbGVyJj4oZ2V0Q29udHJvbGxlcigpKS5nZXRDb2xXaWR0aChfbkNvbFBvcyk7CiAgICBpZiAoICFuV2lkdGggKQogICAgICAgIG5XaWR0aCA9IHNfbkRlZmF1bHRXaWR0aDsKCXJldHVybiBuV2lkdGg7Cn0KLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0Kdm9pZCBPUXVlcnlEZXNpZ25WaWV3OjpmaWxsVmFsaWRGaWVsZHMoY29uc3QgOjpydGw6Ok9VU3RyaW5nJiBzQWxpYXNOYW1lLCBDb21ib0JveCogcEZpZWxkTGlzdCkKewoJREJHX0FTU0VSVChwRmllbGRMaXN0ICE9IE5VTEwsICJPUXVlcnlEZXNpZ25WaWV3OjpGaWxsVmFsaWRGaWVsZHMgOiBXaGF0IHRoZSBoZWxsIGRvIHlvdSB0aGluayBJIGNhbiBkbyB3aXRoIGEgTlVMTC1wdHIgPyBUaGlzIHdpbGwgY3Jhc2ggISIpOwoJcEZpZWxkTGlzdC0+Q2xlYXIoKTsKCglzYWxfQm9vbCBiQWxsVGFibGVzID0gc0FsaWFzTmFtZS5nZXRMZW5ndGgoKSA9PSAwOwoKCU9Kb2luVGFibGVWaWV3OjpPVGFibGVXaW5kb3dNYXAqIHBUYWJXaW5zID0gbV9wVGFibGVWaWV3LT5HZXRUYWJXaW5NYXAoKTsKCTo6cnRsOjpPVVN0cmluZyBzdHJDdXJyZW50UHJlZml4OwoJOjpzdGQ6OnZlY3RvcjwgOjpydGw6Ok9VU3RyaW5nPiBhRmllbGRzOwoJT0pvaW5UYWJsZVZpZXc6Ok9UYWJsZVdpbmRvd01hcDo6aXRlcmF0b3IgYUl0ZXIgPSBwVGFiV2lucy0+YmVnaW4oKTsKICAgIE9Kb2luVGFibGVWaWV3OjpPVGFibGVXaW5kb3dNYXA6Oml0ZXJhdG9yIGFFbmQgID0gcFRhYldpbnMtPmVuZCgpOwogICAgZm9yKDthSXRlciAhPSBhRW5kOysrYUl0ZXIpCgl7CgkJT1F1ZXJ5VGFibGVXaW5kb3cqIHBDdXJyZW50V2luID0gc3RhdGljX2Nhc3Q8T1F1ZXJ5VGFibGVXaW5kb3cqPihhSXRlci0+c2Vjb25kKTsKCQlpZiAoYkFsbFRhYmxlcyB8fCAocEN1cnJlbnRXaW4tPkdldEFsaWFzTmFtZSgpID09IHNBbGlhc05hbWUpKQoJCXsKCQkJc3RyQ3VycmVudFByZWZpeCA9IHBDdXJyZW50V2luLT5HZXRBbGlhc05hbWUoKTsKCQkJc3RyQ3VycmVudFByZWZpeCArPSA6OnJ0bDo6T1VTdHJpbmcoJy4nKTsKCgkJCXBDdXJyZW50V2luLT5FbnVtVmFsaWRGaWVsZHMoYUZpZWxkcyk7CgoJCQk6OnN0ZDo6dmVjdG9yPCA6OnJ0bDo6T1VTdHJpbmc+OjppdGVyYXRvciBhU3RySXRlciA9IGFGaWVsZHMuYmVnaW4oKTsKICAgICAgICAgICAgOjpzdGQ6OnZlY3RvcjwgOjpydGw6Ok9VU3RyaW5nPjo6aXRlcmF0b3IgYVN0ckVuZCA9IGFGaWVsZHMuZW5kKCk7CgkJCWZvcig7YVN0ckl0ZXIgIT0gYVN0ckVuZDsrK2FTdHJJdGVyKQoJCQl7CgkJCQlpZiAoYkFsbFRhYmxlcyB8fCBhU3RySXRlci0+dG9DaGFyKCkgPT0gJyonKQoJCQkJCXBGaWVsZExpc3QtPkluc2VydEVudHJ5KDo6cnRsOjpPVVN0cmluZyhzdHJDdXJyZW50UHJlZml4KSArPSAqYVN0ckl0ZXIpOwoJCQkJZWxzZQoJCQkJCXBGaWVsZExpc3QtPkluc2VydEVudHJ5KCphU3RySXRlcik7CgkJCX0KCgkJCWlmICghYkFsbFRhYmxlcykKCQkJCS8vIGRhcyBoZWlzc3QsIGRhc3MgaWNoIGluIGRpZXNlbiBCbG9jayBrYW0sIHdlaWwgZGVyIFRhYmVsbGVubmFtZSBnZW5hdSBkZXIgZ2VzdWNodGUgd2FyLCBhbHNvIGJpbiBpY2ggZmVydGlnCgkJCQkvLyAoZGFkdXJjaCB2ZXJoaW5kZXJlIGljaCBhdWNoIGRhcyBkb3BwZWx0ZSBFaW5mdWVnZW4gdm9uIEZlbGRlcm4sIHdlbm4gZWluZSBUYWJlbGxlIG1laHJtYWxzIGFscyBUYWJXaW4gdm9ya29tbXQpCgkJCQlicmVhazsKCQl9Cgl9Cn0KLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KbG9uZyBPUXVlcnlEZXNpZ25WaWV3OjpQcmVOb3RpZnkoTm90aWZ5RXZlbnQmIHJORXZ0KQp7Cglzd2l0Y2ggKHJORXZ0LkdldFR5cGUoKSkKCXsKCQljYXNlIEVWRU5UX0dFVEZPQ1VTOgojaWYgT1NMX0RFQlVHX0xFVkVMID4gMAoJCQl7CgkJCQlXaW5kb3cqIHBGb2N1cyA9IEFwcGxpY2F0aW9uOjpHZXRGb2N1c1dpbmRvdygpOwogICAgICAgICAgICAgICAgKHZvaWQpcEZvY3VzOwoJCQl9CiNlbmRpZgoKCQkJaWYgKCBtX3BTZWxlY3Rpb25Cb3ggJiYgbV9wU2VsZWN0aW9uQm94LT5IYXNDaGlsZFBhdGhGb2N1cygpICkKCQkJCW1fZUNoaWxkRm9jdXMgPSBTRUxFQ1RJT047CgkJCWVsc2UKCQkJCW1fZUNoaWxkRm9jdXMgPSBUQUJMRVZJRVc7CgkJCWJyZWFrOwoJfQoKCXJldHVybiBPUXVlcnlWaWV3OjpQcmVOb3RpZnkock5FdnQpOwp9Ci8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLy8gY2hlY2sgaWYgdGhlIHN0YXRlbWVudCBpcyBjb3JyZWN0IHdoZW4gbm90IHJldHVybmluZyBmYWxzZQpzYWxfQm9vbCBPUXVlcnlEZXNpZ25WaWV3OjpjaGVja1N0YXRlbWVudCgpCnsKCXNhbF9Cb29sIGJSZXQgPSBzYWxfVHJ1ZTsKCWlmICggbV9wU2VsZWN0aW9uQm94ICkKCQliUmV0ID0gbV9wU2VsZWN0aW9uQm94LT5TYXZlKCk7IC8vIGEgZXJyb3Igb2NjdXJyZWQgc28gd2UgcmV0dXJuIG5vCglyZXR1cm4gYlJldDsKfQovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KOjpydGw6Ok9VU3RyaW5nIE9RdWVyeURlc2lnblZpZXc6OmdldFN0YXRlbWVudCgpCnsKCU9RdWVyeUNvbnRyb2xsZXImIHJDb250cm9sbGVyID0gc3RhdGljX2Nhc3Q8T1F1ZXJ5Q29udHJvbGxlciY+KGdldENvbnRyb2xsZXIoKSk7CgltX3JDb250cm9sbGVyLmNsZWFyRXJyb3IoKTsKCS8vIHVzZWQgZm9yIGZpZWxkcyB3aGljaCBhcmVuJ3QgYW55IGxvbmdlciBpbiB0aGUgc3RhdGVtZW50CglPVGFibGVGaWVsZHMmIHJVblVzZWRGaWVsZHMgPSByQ29udHJvbGxlci5nZXRVblVzZWRGaWVsZHMoKTsKCU9UYWJsZUZpZWxkcygpLnN3YXAoIHJVblVzZWRGaWVsZHMgKTsKCgkvLyBjcmVhdGUgdGhlIHNlbGVjdCBjb2x1bW5zCglzYWxfdUludDMyIG5GaWVsZGNvdW50ID0gMDsKCU9UYWJsZUZpZWxkcyYgckZpZWxkTGlzdCA9IHJDb250cm9sbGVyLmdldFRhYmxlRmllbGREZXNjKCk7CglPVGFibGVGaWVsZHM6Oml0ZXJhdG9yIGFJdGVyID0gckZpZWxkTGlzdC5iZWdpbigpOwogICAgT1RhYmxlRmllbGRzOjppdGVyYXRvciBhRW5kID0gckZpZWxkTGlzdC5lbmQoKTsKCWZvcig7YUl0ZXIgIT0gYUVuZDsrK2FJdGVyKQoJewoJCU9UYWJsZUZpZWxkRGVzY1JlZiBwRW50cnlGaWVsZCA9ICphSXRlcjsKCQlpZiAoIHBFbnRyeUZpZWxkLT5HZXRGaWVsZCgpLmdldExlbmd0aCgpICYmIHBFbnRyeUZpZWxkLT5Jc1Zpc2libGUoKSApCgkJCSsrbkZpZWxkY291bnQ7CgkJZWxzZSBpZiAocEVudHJ5RmllbGQtPkdldEZpZWxkKCkuZ2V0TGVuZ3RoKCkJCQkmJgoJCQkJIXBFbnRyeUZpZWxkLT5IYXNDcml0ZXJpYSgpCQkJCQkmJgoJCQkJcEVudHJ5RmllbGQtPmlzTm9uZUZ1bmN0aW9uKCkJCQkJJiYKCQkJCXBFbnRyeUZpZWxkLT5HZXRPcmRlckRpcigpID09IE9SREVSX05PTkUJJiYKICAgICAgICAgICAgICAgICFwRW50cnlGaWVsZC0+SXNHcm91cEJ5KCkgICAgICAgICAgICAgICAgICAgJiYKCQkJCSFwRW50cnlGaWVsZC0+R2V0RnVuY3Rpb24oKS5nZXRMZW5ndGgoKSApCgkJCXJVblVzZWRGaWVsZHMucHVzaF9iYWNrKHBFbnRyeUZpZWxkKTsKCX0KCWlmICggIW5GaWVsZGNvdW50ICkJLy8ga2VpbmUgRmVsZGVyIHNpY2h0YmFyIGFsc28genVyInVjawoJewoJCXJVblVzZWRGaWVsZHMgPSByRmllbGRMaXN0OwoJCXJldHVybiA6OnJ0bDo6T1VTdHJpbmcoKTsKCX0KCglPUXVlcnlUYWJsZVZpZXc6Ok9UYWJsZVdpbmRvd01hcCogcFRhYkxpc3QgICA9IG1fcFRhYmxlVmlldy0+R2V0VGFiV2luTWFwKCk7CglzYWxfdUludDMyIG5UYWJjb3VudAkJPSBwVGFiTGlzdC0+c2l6ZSgpOwoKCTo6cnRsOjpPVVN0cmluZwlhRmllbGRMaXN0U3RyKEdlbmVyYXRlU2VsZWN0TGlzdCh0aGlzLHJGaWVsZExpc3QsblRhYmNvdW50PjEpKTsKCWlmKCAhYUZpZWxkTGlzdFN0ci5nZXRMZW5ndGgoKSApCgkJcmV0dXJuIDo6cnRsOjpPVVN0cmluZygpOwoJLy8gQXVzbmFobWViZWhhbmRsdW5nLCB3ZW5uIGtlaW5lIEZlbGRlciBhbmdlZ2ViZW4gd29yZGVuIHNpbmQKCS8vIERhbm4gZGFyZiBkaWUgVGFicGFnZSBuaWNodCBnZXdlY2hzZWx0IHdlcmRlbgoJLy8gSW0gVGFiQmFyU2VsZWN0SGRsIHdpcmQgZGVyIFNRTC06OnJ0bDo6T1VTdHJpbmcgYXVmIFNUQVRFTUVOVF9OT0ZJRUxEUyBhYmdlZnJhZ3QKCS8vIHVuZCBlaW5lIEVycm9ybWVsZHVuZyBlcnpldWd0CgkvLyAtLS0tLS0tLS0tLS0tLS0tLSBUYWJlbGxlbmxpc3RlIGF1ZmJhdWVuIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCgljb25zdCA6OnN0ZDo6dmVjdG9yPE9UYWJsZUNvbm5lY3Rpb24qPioJcENvbm5MaXN0ID0gbV9wVGFibGVWaWV3LT5nZXRUYWJsZUNvbm5lY3Rpb25zKCk7CglSZWZlcmVuY2U8IFhDb25uZWN0aW9uPiB4Q29ubmVjdGlvbiA9IHJDb250cm9sbGVyLmdldENvbm5lY3Rpb24oKTsKCTo6cnRsOjpPVVN0cmluZyBhVGFibGVMaXN0U3RyKEdlbmVyYXRlRnJvbUNsYXVzZSh4Q29ubmVjdGlvbixwVGFiTGlzdCxwQ29ubkxpc3QpKTsKCURCR19BU1NFUlQoYVRhYmxlTGlzdFN0ci5nZXRMZW5ndGgoKSwgIk9RdWVyeURlc2lnblZpZXc6OmdldFN0YXRlbWVudCgpIDogdW5lcndhcnRldCA6IGhhYmUgRmVsZGVyLCBhYmVyIGtlaW5lIFRhYmVsbGVuICEiKTsKCS8vIHdlbm4gZXMgRmVsZGVyIGdpYnQsIGtvZW5uZW4gZGllIG51ciBkdXJjaCBFaW5mdWVnZW4gYXVzIGVpbmVyIHNjaG9uIGV4aXN0ZW50ZW4gVGFiZWxsZSBlbnRzdGFuZGVuIHNlaW47IHdlbm4gYW5kZXJlcnNlaXRzCgkvLyBlaW5lIFRhYmVsbGUgZ2Vsb2VzY2h0IHdpcmQsIHZlcnNjaHdpbmRlbiBhdWNoIGRpZSB6dWdlaG9lcmlnZW4gRmVsZGVyIC0+IGVyZ28gS0FOTiBlcyBkYXMgbmljaHQgZ2ViZW4sIGRhc3MgRmVsZGVyCgkvLyBleGlzdGllcmVuLCBhYmVyIGtlaW5lIFRhYmVsbGVuICh1bmQgYUZpZWxkTGlzdFN0ciBoYXQgc2Nob24gZWluZSBMYWVuZ2UsIGRhcyBzdGVsbGUgaWNoIG9iZW4gc2ljaGVyKQoJOjpydGw6Ok9VU3RyaW5nQnVmZmVyIGFIYXZpbmdTdHIsYUNyaXRlcmlhTGlzdFN0cjsKCS8vIC0tLS0tLS0tLS0tLS0tLS0tIEtyaXRlcmllbiBhdWZiYXVlbiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tCglpZiAoIUdlbmVyYXRlQ3JpdGVyaWFzKHRoaXMsYUNyaXRlcmlhTGlzdFN0cixhSGF2aW5nU3RyLHJGaWVsZExpc3QsIG5UYWJjb3VudCA+IDEpKQoJCXJldHVybiA6OnJ0bDo6T1VTdHJpbmcoKTsKCgk6OnJ0bDo6T1VTdHJpbmcgYUpvaW5Dcml0OwoJR2VuZXJhdGVJbm5lckpvaW5Dcml0ZXJpYXMoeENvbm5lY3Rpb24sYUpvaW5Dcml0LHBDb25uTGlzdCk7CglpZihhSm9pbkNyaXQuZ2V0TGVuZ3RoKCkpCgl7CgkJOjpydGw6Ok9VU3RyaW5nIGFUbXAgPSA6OnJ0bDo6T1VTdHJpbmc6OmNyZWF0ZUZyb21Bc2NpaSgiKCAiKTsKCQlhVG1wICs9IGFKb2luQ3JpdDsKCQlhVG1wICs9IDo6cnRsOjpPVVN0cmluZzo6Y3JlYXRlRnJvbUFzY2lpKCIgKSIpOwoJCWlmKGFDcml0ZXJpYUxpc3RTdHIuZ2V0TGVuZ3RoKCkpCgkJewoJCQlhVG1wICs9IENfQU5EOwoJCQlhVG1wICs9IGFDcml0ZXJpYUxpc3RTdHIubWFrZVN0cmluZ0FuZENsZWFyKCk7CgkJfQoJCWFDcml0ZXJpYUxpc3RTdHIgPSBhVG1wOwoJfQoJLy8gLS0tLS0tLS0tLS0tLS0tLS0gU3RhdGVtZW50IGF1ZmJhdWVuIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCTo6cnRsOjpPVVN0cmluZ0J1ZmZlciBhU3FsQ21kKDo6cnRsOjpPVVN0cmluZzo6Y3JlYXRlRnJvbUFzY2lpKCJTRUxFQ1QgIikpOwoJaWYoc3RhdGljX2Nhc3Q8T1F1ZXJ5Q29udHJvbGxlciY+KGdldENvbnRyb2xsZXIoKSkuaXNEaXN0aW5jdCgpKQoJCWFTcWxDbWQuYXBwZW5kKDo6cnRsOjpPVVN0cmluZzo6Y3JlYXRlRnJvbUFzY2lpKCIgRElTVElOQ1QgIikpOwoJYVNxbENtZC5hcHBlbmQoYUZpZWxkTGlzdFN0cik7CglhU3FsQ21kLmFwcGVuZCg6OnJ0bDo6T1VTdHJpbmc6OmNyZWF0ZUZyb21Bc2NpaSgiIEZST00gIikpOwoJYVNxbENtZC5hcHBlbmQoYVRhYmxlTGlzdFN0cik7CgoJaWYgKGFDcml0ZXJpYUxpc3RTdHIuZ2V0TGVuZ3RoKCkpCgl7CgkJYVNxbENtZC5hcHBlbmQoOjpydGw6Ok9VU3RyaW5nOjpjcmVhdGVGcm9tQXNjaWkoIiBXSEVSRSAiKSk7CgkJYVNxbENtZC5hcHBlbmQoYUNyaXRlcmlhTGlzdFN0ci5tYWtlU3RyaW5nQW5kQ2xlYXIoKSk7Cgl9CgkvLyAtLS0tLS0tLS0tLS0tLS0tLSBHcm91cEJ5IGF1ZmJhdWVuIHVuZCBBbmgiYW5nZW4gLS0tLS0tLS0tLS0tCglSZWZlcmVuY2U8WERhdGFiYXNlTWV0YURhdGE+IHhNZXRhOwoJaWYgKCB4Q29ubmVjdGlvbi5pcygpICkKCQl4TWV0YSA9IHhDb25uZWN0aW9uLT5nZXRNZXRhRGF0YSgpOwoJc2FsX0Jvb2wgYlVzZUFsaWFzID0gblRhYmNvdW50ID4gMTsKCWlmICggeE1ldGEuaXMoKSApCgkJYlVzZUFsaWFzID0gYlVzZUFsaWFzIHx8ICF4TWV0YS0+c3VwcG9ydHNHcm91cEJ5VW5yZWxhdGVkKCk7CgoJYVNxbENtZC5hcHBlbmQoR2VuZXJhdGVHcm91cEJ5KHRoaXMsckZpZWxkTGlzdCxiVXNlQWxpYXMpKTsKCS8vIC0tLS0tLS0tLS0tLS0tLS0tIGhhdmluZyBBbmgiYW5nZW4gLS0tLS0tLS0tLS0tCglpZihhSGF2aW5nU3RyLmdldExlbmd0aCgpKQoJewoJCWFTcWxDbWQuYXBwZW5kKDo6cnRsOjpPVVN0cmluZzo6Y3JlYXRlRnJvbUFzY2lpKCIgSEFWSU5HICIpKTsKCQlhU3FsQ21kLmFwcGVuZChhSGF2aW5nU3RyLm1ha2VTdHJpbmdBbmRDbGVhcigpKTsKCX0KCS8vIC0tLS0tLS0tLS0tLS0tLS0tIFNvcnRpZXJ1bmcgYXVmYmF1ZW4gdW5kIEFuaCJhbmdlbiAtLS0tLS0tLS0tLS0KCTo6cnRsOjpPVVN0cmluZyBzT3JkZXI7CglTcWxQYXJzZUVycm9yIGVFcnJvckNvZGUgPSBlT2s7CglpZiAoIChlRXJyb3JDb2RlID0gR2VuZXJhdGVPcmRlcih0aGlzLHJGaWVsZExpc3QsblRhYmNvdW50ID4gMSxzT3JkZXIpKSA9PSBlT2spCgkJYVNxbENtZC5hcHBlbmQoc09yZGVyKTsKCWVsc2UKCXsKCQlpZiAoICFtX3JDb250cm9sbGVyLmhhc0Vycm9yKCkgKQogICAgICAgICAgICBtX3JDb250cm9sbGVyLmFwcGVuZEVycm9yKCBnZXRQYXJzZUVycm9yTWVzc2FnZSggZUVycm9yQ29kZSApICk7CgogICAgICAgIG1fckNvbnRyb2xsZXIuZGlzcGxheUVycm9yKCk7Cgl9CgogICAgOjpydGw6Ok9VU3RyaW5nIHNTUUwgPSBhU3FsQ21kLm1ha2VTdHJpbmdBbmRDbGVhcigpOwogICAgaWYgKCB4Q29ubmVjdGlvbi5pcygpICkKICAgIHsKICAgICAgICA6OmNvbm5lY3Rpdml0eTo6T1NRTFBhcnNlciYgclBhcnNlciggckNvbnRyb2xsZXIuZ2V0UGFyc2VyKCkgKTsKICAgICAgICA6OnJ0bDo6T1VTdHJpbmcgc0Vycm9yTWVzc2FnZTsKICAgICAgICA6OnN0ZDo6YXV0b19wdHI8T1NRTFBhcnNlTm9kZT4gcFBhcnNlTm9kZSggclBhcnNlci5wYXJzZVRyZWUoIHNFcnJvck1lc3NhZ2UsIHNTUUwsIHNhbF9UcnVlICkgKTsKICAgICAgICBpZiAoIHBQYXJzZU5vZGUuZ2V0KCkgKQogICAgICAgIHsKICAgICAgICAgICAgT1NRTFBhcnNlTm9kZSogcE5vZGUgPSBwUGFyc2VOb2RlLT5nZXRDaGlsZCgzKS0+Z2V0Q2hpbGQoMSk7CiAgICAgICAgICAgIGlmICggcE5vZGUtPmNvdW50KCkgPiAxICkKICAgICAgICAgICAgewoJCSAgICAgICAgOjpjb25uZWN0aXZpdHk6Ok9TUUxQYXJzZU5vZGUgKiBwQ29uZGl0aW9uID0gcE5vZGUtPmdldENoaWxkKDEpOwoJCSAgICAgICAgaWYgKCBwQ29uZGl0aW9uICkgLy8gbm8gd2hlcmUgY2xhdXNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgT1NRTFBhcnNlTm9kZTo6Y29tcHJlc3MocENvbmRpdGlvbik7CiAgICAgICAgICAgICAgICAgICAgOjpydGw6Ok9VU3RyaW5nIHNUZW1wOwogICAgICAgICAgICAgICAgICAgIHBQYXJzZU5vZGUtPnBhcnNlTm9kZVRvU3RyKHNUZW1wLHhDb25uZWN0aW9uKTsKICAgICAgICAgICAgICAgICAgICBzU1FMID0gc1RlbXA7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CglyZXR1cm4gc1NRTDsKfQovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIE9RdWVyeURlc2lnblZpZXc6OnNldFNsb3RFbmFibGVkKHNhbF9JbnQzMiBfblNsb3RJZCxzYWxfQm9vbCBfYkVuYWJsZSkKewoJc2FsX3VJbnQxNiBuUm93OwoJc3dpdGNoIChfblNsb3RJZCkKCXsKCQljYXNlIFNJRF9RVUVSWV9WSUVXX0ZVTkNUSU9OUzoKCQkJblJvdyA9IEJST1dfRlVOQ1RJT05fUk9XOwoJCQlicmVhazsKCQljYXNlIFNJRF9RVUVSWV9WSUVXX1RBQkxFUzoKCQkJblJvdyA9IEJST1dfVEFCTEVfUk9XOwoJCQlicmVhazsKCQljYXNlIFNJRF9RVUVSWV9WSUVXX0FMSUFTRVM6CgkJCW5Sb3cgPSBCUk9XX0NPTFVNTkFMSUFTX1JPVzsKCQkJYnJlYWs7CgkJZGVmYXVsdDoKCQkJLy8gPz8/Pz8/Pz8/Pz8/CgkJCW5Sb3cgPSAwOwoJCQlicmVhazsKCX0KCW1fcFNlbGVjdGlvbkJveC0+U2V0Um93VmlzaWJsZShuUm93LF9iRW5hYmxlKTsKCW1fcFNlbGVjdGlvbkJveC0+SW52YWxpZGF0ZSgpOwp9Ci8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnNhbF9Cb29sIE9RdWVyeURlc2lnblZpZXc6OmlzU2xvdEVuYWJsZWQoc2FsX0ludDMyIF9uU2xvdElkKQp7CglzYWxfdUludDE2IG5Sb3c7Cglzd2l0Y2ggKF9uU2xvdElkKQoJewoJCWNhc2UgU0lEX1FVRVJZX1ZJRVdfRlVOQ1RJT05TOgoJCQluUm93ID0gQlJPV19GVU5DVElPTl9ST1c7CgkJCWJyZWFrOwoJCWNhc2UgU0lEX1FVRVJZX1ZJRVdfVEFCTEVTOgoJCQluUm93ID0gQlJPV19UQUJMRV9ST1c7CgkJCWJyZWFrOwoJCWNhc2UgU0lEX1FVRVJZX1ZJRVdfQUxJQVNFUzoKCQkJblJvdyA9IEJST1dfQ09MVU1OQUxJQVNfUk9XOwoJCQlicmVhazsKCQlkZWZhdWx0OgoJCQkvLyA/Pz8/Pz8/Pz8KCQkJblJvdyA9IDA7CgkJCWJyZWFrOwoJfQoJcmV0dXJuIG1fcFNlbGVjdGlvbkJveC0+SXNSb3dWaXNpYmxlKG5Sb3cpOwp9Ci8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgT1F1ZXJ5RGVzaWduVmlldzo6U2F2ZVVJQ29uZmlnKCkKewoJT1F1ZXJ5Q29udHJvbGxlciYgckN0cmwgPSBzdGF0aWNfY2FzdDxPUXVlcnlDb250cm9sbGVyJj4oZ2V0Q29udHJvbGxlcigpKTsKCXJDdHJsLlNhdmVUYWJXaW5zUG9zU2l6ZSggbV9wVGFibGVWaWV3LT5HZXRUYWJXaW5NYXAoKSwgbV9wU2Nyb2xsV2luZG93LT5HZXRIU2Nyb2xsQmFyKCktPkdldFRodW1iUG9zKCksIG1fcFNjcm9sbFdpbmRvdy0+R2V0VlNjcm9sbEJhcigpLT5HZXRUaHVtYlBvcygpICk7CgkvLwlyQ3RybC5TYXZlVGFiRmllbGRzV2lkdGgoIG1fcFNlbGVjdGlvbkJveCApOwoJckN0cmwuc2V0VmlzaWJsZVJvd3MoIG1fcFNlbGVjdGlvbkJveC0+R2V0Tm9uZVZpc2libGVSb3dzKCkgKTsKICAgIGlmICggbV9hU3BsaXR0ZXIuR2V0U3BsaXRQb3NQaXhlbCgpICE9IDAgKQoJICAgIHJDdHJsLnNldFNwbGl0UG9zKCBtX2FTcGxpdHRlci5HZXRTcGxpdFBvc1BpeGVsKCkgKTsKfQovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpPU1FMUGFyc2VOb2RlKiBPUXVlcnlEZXNpZ25WaWV3OjpnZXRQcmVkaWNhdGVUcmVlRnJvbUVudHJ5KE9UYWJsZUZpZWxkRGVzY1JlZiBwRW50cnksCgkJCQkJCQkJCQkJCQkJICAgY29uc3QgU3RyaW5nJiBfc0NyaXRlcmlhLAoJCQkJCQkJCQkJCQkJCSAgIDo6cnRsOjpPVVN0cmluZyYgX3JzRXJyb3JNZXNzYWdlLAoJCQkJCQkJCQkJCQkJCSAgIFJlZmVyZW5jZTxYUHJvcGVydHlTZXQ+JiBfcnhDb2x1bW4pIGNvbnN0CnsKCU9TTF9FTlNVUkUocEVudHJ5LmlzVmFsaWQoKSwiRW50cnkgaXMgbnVsbCEiKTsKCWlmKCFwRW50cnkuaXNWYWxpZCgpKQoJCXJldHVybiBOVUxMOwoJUmVmZXJlbmNlPCBYQ29ubmVjdGlvbj4geENvbm5lY3Rpb24gPSBzdGF0aWNfY2FzdDxPUXVlcnlDb250cm9sbGVyJj4oZ2V0Q29udHJvbGxlcigpKS5nZXRDb25uZWN0aW9uKCk7CglpZigheENvbm5lY3Rpb24uaXMoKSkKCQlyZXR1cm4gTlVMTDsKCgk6OmNvbm5lY3Rpdml0eTo6T1NRTFBhcnNlciYgclBhcnNlciggc3RhdGljX2Nhc3Q8T1F1ZXJ5Q29udHJvbGxlciY+KGdldENvbnRyb2xsZXIoKSkuZ2V0UGFyc2VyKCkgKTsKCU9RdWVyeVRhYmxlV2luZG93KiBwV2luID0gc3RhdGljX2Nhc3Q8T1F1ZXJ5VGFibGVXaW5kb3cqPihwRW50cnktPkdldFRhYldpbmRvdygpKTsKCglTdHJpbmcgc1Rlc3QoX3NDcml0ZXJpYSk7CgkvLyBzcGVjaWFsIGhhbmRsaW5nIGZvciBmdW5jdGlvbnMKCWlmICggcEVudHJ5LT5HZXRGdW5jdGlvblR5cGUoKSAmIChGS1RfT1RIRVIgfCBGS1RfQUdHUkVHQVRFIHwgRktUX05VTUVSSUMpICkKCXsKCQkvLyB3ZSBoYXZlIGEgZnVuY3Rpb24gaGVyZSBzbyB3ZSBoYXZlIHRvIGRpc3Rpbmd1aXNoIHRoZSB0eXBlIG9mIHJldHVybiB2YWx1ZQoJCVN0cmluZyBzRnVuY3Rpb247CgkJaWYgKCBwRW50cnktPmlzTnVtZXJpY09yQWdncmVhdGVGdW5jdGlvbigpICkKCQkJc0Z1bmN0aW9uID0gcEVudHJ5LT5HZXRGdW5jdGlvbigpOwoKICAgICAgICBpZiAoICFzRnVuY3Rpb24uTGVuKCkgKQoJCQlzRnVuY3Rpb24gPSBwRW50cnktPkdldEZpZWxkKCk7CgoJCWlmKHNGdW5jdGlvbi5HZXRUb2tlbkNvdW50KCcoJykgPiAxKQoJCQlzRnVuY3Rpb24gPSBzRnVuY3Rpb24uR2V0VG9rZW4oMCwnKCcpOyAvLyB0aGlzIHNob3VsZCBiZSB0aGUgbmFtZSBvZiB0aGUgZnVuY3Rpb24KCgkJc2FsX0ludDMyIG5UeXBlID0gOjpjb25uZWN0aXZpdHk6Ok9TUUxQYXJzZXI6OmdldEZ1bmN0aW9uUmV0dXJuVHlwZShzRnVuY3Rpb24sJnJQYXJzZXIuZ2V0Q29udGV4dCgpKTsKCQlpZiAoIG5UeXBlID09IERhdGFUeXBlOjpPVEhFUiB8fCAoIXNGdW5jdGlvbi5MZW4oKSAmJiBwRW50cnktPmlzTnVtZXJpY09yQWdncmVhdGVGdW5jdGlvbigpKSApCgkJewoJCQkvLyBmaXJzdCB0cnkgdGhlIGludGVybmF0aW9uYWwgdmVyc2lvbgoJCQk6OnJ0bDo6T1VTdHJpbmcgc1NxbDsKCQkJc1NxbCArPSA6OnJ0bDo6T1VTdHJpbmcoUlRMX0NPTlNUQVNDSUlfVVNUUklOR1BBUkFNKCJTRUxFQ1QgKiAiKSk7CgkJCXNTcWwgKz0gOjpydGw6Ok9VU3RyaW5nKFJUTF9DT05TVEFTQ0lJX1VTVFJJTkdQQVJBTSgiIEZST00geCBXSEVSRSAiKSk7CgkJCXNTcWwgKz0gcEVudHJ5LT5HZXRGaWVsZCgpOwoJCQlzU3FsICs9IF9zQ3JpdGVyaWE7CiAgICAgICAgICAgIDo6c3RkOjphdXRvX3B0cjxPU1FMUGFyc2VOb2RlPiBwUGFyc2VOb2RlKCByUGFyc2VyLnBhcnNlVHJlZSggX3JzRXJyb3JNZXNzYWdlLCBzU3FsLCBzYWxfVHJ1ZSApICk7CgkJCW5UeXBlID0gRGF0YVR5cGU6OkRPVUJMRTsKCQkJaWYgKCBwUGFyc2VOb2RlLmdldCgpICkKCQkJewoJCQkJT1NRTFBhcnNlTm9kZSogcENvbHVtblJlZiA9IHBQYXJzZU5vZGUtPmdldEJ5UnVsZShPU1FMUGFyc2VOb2RlOjpjb2x1bW5fcmVmKTsKCQkJCWlmICggcENvbHVtblJlZiApCgkJCQl7CgkJCQkJT1RhYmxlRmllbGREZXNjUmVmIGFGaWVsZCA9IG5ldyBPVGFibGVGaWVsZERlc2MoKTsKCQkJCQlpZiAoIGVPayA9PSBGaWxsRHJhZ0luZm8odGhpcyxwQ29sdW1uUmVmLGFGaWVsZCkgKQoJCQkJCXsKCQkJCQkJblR5cGUgPSBhRmllbGQtPkdldERhdGFUeXBlKCk7CgkJCQkJfQoJCQkJfQoJCQl9CgkJfQoKCQlSZWZlcmVuY2U8WERhdGFiYXNlTWV0YURhdGE+IHhNZXRhID0geENvbm5lY3Rpb24tPmdldE1ldGFEYXRhKCk7CgkJcGFyc2U6Ok9QYXJzZUNvbHVtbiogcENvbHVtbiA9IG5ldyBwYXJzZTo6T1BhcnNlQ29sdW1uKAlwRW50cnktPkdldEZpZWxkKCksCgkJCQkJCQkJCQkJCQkJCQk6OnJ0bDo6T1VTdHJpbmcoKSwKCQkJCQkJCQkJCQkJCQkJCTo6cnRsOjpPVVN0cmluZygpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOjpydGw6Ok9VU3RyaW5nKCksCgkJCQkJCQkJCQkJCQkJCQlDb2x1bW5WYWx1ZTo6TlVMTEFCTEVfVU5LTk9XTiwKCQkJCQkJCQkJCQkJCQkJCTAsCgkJCQkJCQkJCQkJCQkJCQkwLAoJCQkJCQkJCQkJCQkJCQkJblR5cGUsCgkJCQkJCQkJCQkJCQkJCQlzYWxfRmFsc2UsCgkJCQkJCQkJCQkJCQkJCQlzYWxfRmFsc2UsCgkJCQkJCQkJCQkJCQkJCQl4TWV0YS5pcygpICYmIHhNZXRhLT5zdXBwb3J0c01peGVkQ2FzZVF1b3RlZElkZW50aWZpZXJzKCkpOwoJCV9yeENvbHVtbiA9IHBDb2x1bW47CgkJcENvbHVtbi0+c2V0RnVuY3Rpb24oc2FsX1RydWUpOwoJCXBDb2x1bW4tPnNldFJlYWxOYW1lKHBFbnRyeS0+R2V0RmllbGQoKSk7Cgl9CgllbHNlCgl7CgkJaWYgKHBXaW4pCgkJewoJCQlSZWZlcmVuY2U8WE5hbWVBY2Nlc3M+IHhDb2x1bW5zID0gcFdpbi0+R2V0T3JpZ2luYWxDb2x1bW5zKCk7CgkJCWlmICh4Q29sdW1ucy5pcygpICYmIHhDb2x1bW5zLT5oYXNCeU5hbWUocEVudHJ5LT5HZXRGaWVsZCgpKSkKCQkJCXhDb2x1bW5zLT5nZXRCeU5hbWUocEVudHJ5LT5HZXRGaWVsZCgpKSA+Pj0gX3J4Q29sdW1uOwoJCX0KCX0KCglPU1FMUGFyc2VOb2RlKiBwUGFyc2VOb2RlID0gclBhcnNlci5wcmVkaWNhdGVUcmVlKAlfcnNFcnJvck1lc3NhZ2UsCgkJCQkJCQkJCQkJCQkJc1Rlc3QsCgkJCQkJCQkJCQkJCQkJc3RhdGljX2Nhc3Q8T1F1ZXJ5Q29udHJvbGxlciY+KGdldENvbnRyb2xsZXIoKSkuZ2V0TnVtYmVyRm9ybWF0dGVyKCksCgkJCQkJCQkJCQkJCQkJX3J4Q29sdW1uKTsKCXJldHVybiBwUGFyc2VOb2RlOwp9Ci8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgT1F1ZXJ5RGVzaWduVmlldzo6R2V0Rm9jdXMoKQp7CglPUXVlcnlWaWV3OjpHZXRGb2N1cygpOwoJaWYgKCBtX3BTZWxlY3Rpb25Cb3ggJiYgIW1fcFNlbGVjdGlvbkJveC0+SGFzQ2hpbGRQYXRoRm9jdXMoKSApCgl7CgkJLy8gZmlyc3Qgd2UgaGF2ZSB0byBkZWFjdGl2YXRlIHRoZSBjdXJyZW50IGNlbGwgdG8gcmVmaWxsIHdoZW4gbmVjZXNzYXJ5CgkJbV9wU2VsZWN0aW9uQm94LT5EZWFjdGl2YXRlQ2VsbCgpOwoJCW1fcFNlbGVjdGlvbkJveC0+QWN0aXZhdGVDZWxsKG1fcFNlbGVjdGlvbkJveC0+R2V0Q3VyUm93KCksIG1fcFNlbGVjdGlvbkJveC0+R2V0Q3VyQ29sdW1uSWQoKSk7CgkJbV9wU2VsZWN0aW9uQm94LT5HcmFiRm9jdXMoKTsKCX0KfQovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIE9RdWVyeURlc2lnblZpZXc6OnJlc2V0KCkKewoJbV9wVGFibGVWaWV3LT5DbGVhckFsbCgpOwoJbV9wVGFibGVWaWV3LT5SZVN5bmMoKTsKfQovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIE9RdWVyeURlc2lnblZpZXc6OnNldE5vbmVWaXNibGVSb3coc2FsX0ludDMyIF9uUm93cykKewoJbV9wU2VsZWN0aW9uQm94LT5TZXROb25lVmlzYmxlUm93KF9uUm93cyk7Cn0KCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnZvaWQgT1F1ZXJ5RGVzaWduVmlldzo6aW5pdEJ5RmllbGREZXNjcmlwdGlvbnMoIGNvbnN0IFNlcXVlbmNlPCBQcm9wZXJ0eVZhbHVlID4mIGlfckZpZWxkRGVzY3JpcHRpb25zICkKewoJT1F1ZXJ5Q29udHJvbGxlciYgckNvbnRyb2xsZXIgPSBzdGF0aWNfY2FzdDwgT1F1ZXJ5Q29udHJvbGxlciYgPiggZ2V0Q29udHJvbGxlcigpICk7CgoJbV9wU2VsZWN0aW9uQm94LT5QcmVGaWxsKCk7CgltX3BTZWxlY3Rpb25Cb3gtPlNldFJlYWRPbmx5KCByQ29udHJvbGxlci5pc1JlYWRPbmx5KCkgKTsKCW1fcFNlbGVjdGlvbkJveC0+RmlsbCgpOwoKICAgIGZvciAoICAgY29uc3QgUHJvcGVydHlWYWx1ZSogZmllbGQgPSBpX3JGaWVsZERlc2NyaXB0aW9ucy5nZXRDb25zdEFycmF5KCk7CiAgICAgICAgICAgIGZpZWxkICE9IGlfckZpZWxkRGVzY3JpcHRpb25zLmdldENvbnN0QXJyYXkoKSArIGlfckZpZWxkRGVzY3JpcHRpb25zLmdldExlbmd0aCgpOwogICAgICAgICAgICArK2ZpZWxkCiAgICAgICAgKQogICAgewogICAgICAgIDo6dm9zOjpPUmVmPCBPVGFibGVGaWVsZERlc2MgPiBwRmllbGQoIG5ldyBPVGFibGVGaWVsZERlc2MoKSApOwogICAgICAgIHBGaWVsZC0+TG9hZCggKmZpZWxkLCB0cnVlICk7CiAgICAgICAgSW5zZXJ0RmllbGQoIHBGaWVsZCwgc2FsX1RydWUsIHNhbF9GYWxzZSApOwogICAgfQoKICAgIHJDb250cm9sbGVyLkNsZWFyVW5kb01hbmFnZXIoKTsKCW1fcFNlbGVjdGlvbkJveC0+SW52YWxpZGF0ZSgpOwp9CgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpib29sIE9RdWVyeURlc2lnblZpZXc6OmluaXRCeVBhcnNlSXRlcmF0b3IoIDo6ZGJ0b29sczo6U1FMRXhjZXB0aW9uSW5mbyogX3BFcnJvckluZm8gKQp7CglTcWxQYXJzZUVycm9yIGVFcnJvckNvZGUgPSBlTmF0aXZlTW9kZTsKCW1fckNvbnRyb2xsZXIuY2xlYXJFcnJvcigpOwoKICAgIHRyeQogICAgewogICAgICAgIGVFcnJvckNvZGUgPSBJbml0RnJvbVBhcnNlTm9kZUltcGwoIHRoaXMsIG1fcFNlbGVjdGlvbkJveCApOwoKICAgICAgICBpZiAoIGVFcnJvckNvZGUgIT0gZU9rICkKCSAgICB7CgkgICAgICAgIGlmICggIW1fckNvbnRyb2xsZXIuaGFzRXJyb3IoKSApCiAgICAgICAgICAgICAgICBtX3JDb250cm9sbGVyLmFwcGVuZEVycm9yKCBnZXRQYXJzZUVycm9yTWVzc2FnZSggZUVycm9yQ29kZSApICk7CgogICAgICAgICAgICBpZiAoIF9wRXJyb3JJbmZvICkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgKl9wRXJyb3JJbmZvID0gbV9yQ29udHJvbGxlci5nZXRFcnJvcigpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgbV9yQ29udHJvbGxlci5kaXNwbGF5RXJyb3IoKTsKICAgICAgICAgICAgfQoJICAgIH0KICAgIH0KICAgIGNhdGNoICggY29uc3QgRXhjZXB0aW9uJiApCiAgICB7CiAgICAgICAgREJHX1VOSEFORExFRF9FWENFUFRJT04oKTsKICAgIH0KCXJldHVybiBlRXJyb3JDb2RlID09IGVPazsKfQovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIE9RdWVyeURlc2lnblZpZXc6OmZpbGxGdW5jdGlvbkluZm8oICBjb25zdCA6OmNvbm5lY3Rpdml0eTo6T1NRTFBhcnNlTm9kZSogcE5vZGUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICxjb25zdCA6OnJ0bDo6T1VTdHJpbmcmIHNGdW5jdGlvblRlcm0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICxPVGFibGVGaWVsZERlc2NSZWYmIGFJbmZvKQp7CiAgICAvLyBnZXQgdGhlIHR5cGUgb3V0IG9mIHRoZSBmdW5jdGlvbiBuYW1lCiAgICBPUXVlcnlDb250cm9sbGVyJiByQ29udHJvbGxlciA9IHN0YXRpY19jYXN0PE9RdWVyeUNvbnRyb2xsZXImPihnZXRDb250cm9sbGVyKCkpOwoJc2FsX0ludDMyIG5EYXRhVHlwZSA9IERhdGFUeXBlOjpET1VCTEU7Cgk6OnJ0bDo6T1VTdHJpbmcgc0ZpZWxkTmFtZSA9IHNGdW5jdGlvblRlcm07CglPU1FMUGFyc2VOb2RlKiBwRnVuY3Rpb25OYW1lID0gcE5vZGUtPmdldENoaWxkKDApOwoJaWYgKCAhU1FMX0lTUFVOQ1RVQVRJT04ocEZ1bmN0aW9uTmFtZSwieyIpICkKCXsKCQlpZiAoIFNRTF9JU1JVTEVPUjIocE5vZGUsbGVuZ3RoX2V4cCxjaGFyX3ZhbHVlX2ZjdCkgKQoJCQlwRnVuY3Rpb25OYW1lID0gcEZ1bmN0aW9uTmFtZS0+Z2V0Q2hpbGQoMCk7CgoJCTo6cnRsOjpPVVN0cmluZyBzRnVuY3Rpb25OYW1lID0gcEZ1bmN0aW9uTmFtZS0+Z2V0VG9rZW5WYWx1ZSgpOwoJCWlmICggIXNGdW5jdGlvbk5hbWUuZ2V0TGVuZ3RoKCkgKQoJCQlzRnVuY3Rpb25OYW1lID0gOjpydGw6Ok9TdHJpbmdUb09VU3RyaW5nKE9TUUxQYXJzZXI6OlRva2VuSURUb1N0cihwRnVuY3Rpb25OYW1lLT5nZXRUb2tlbklEKCkpLFJUTF9URVhURU5DT0RJTkdfVVRGOCk7CgoJCW5EYXRhVHlwZSA9IE9TUUxQYXJzZXI6OmdldEZ1bmN0aW9uUmV0dXJuVHlwZSgKCQkJCQkJCXNGdW5jdGlvbk5hbWUKCQkJCQkJCSwmckNvbnRyb2xsZXIuZ2V0UGFyc2VyKCkuZ2V0Q29udGV4dCgpKTsKCX0KCWFJbmZvLT5TZXREYXRhVHlwZShuRGF0YVR5cGUpOwoJYUluZm8tPlNldEZpZWxkVHlwZShUQUJfTk9STUFMX0ZJRUxEKTsKCWFJbmZvLT5TZXRGaWVsZChzRmllbGROYW1lKTsKCWFJbmZvLT5TZXRUYWJXaW5kb3coTlVMTCk7Cn0KLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0K