LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCiAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKICogb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCiAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKICogdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZQogKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCiAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAogKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgogKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCiAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKICogdW5kZXIgdGhlIExpY2Vuc2UuCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKCgovLyBNQVJLRVIodXBkYXRlX3ByZWNvbXAucHkpOiBhdXRvZ2VuIGluY2x1ZGUgc3RhdGVtZW50LCBkbyBub3QgcmVtb3ZlCiNpbmNsdWRlICJwcmVjb21waWxlZF9zZC5oeHgiCgojaW5jbHVkZSA8c2FsL3R5cGVzLmg+CiNpbmNsdWRlIDxzb3QvZm9ybWF0cy5oeHg+CiNpbmNsdWRlIDxzb3Qvc3RvcmFnZS5oeHg+CiNpbmNsdWRlIDx2Y2wvbXNnYm94Lmh4eD4KI2luY2x1ZGUgPHN2bC91cmloZWxwZXIuaHh4PgojaW5jbHVkZSA8c3Z4L3N2ZGl0ZXIuaHh4PgojaW5jbHVkZSA8c2Z4Mi9kb2NmaWxlLmh4eD4KI2luY2x1ZGUgPHN2eC9zdmRvb2xlMi5oeHg+CiNpbmNsdWRlIDx2Y2wvc3ZhcHAuaHh4PgojaW5jbHVkZSAiY3Vzc2hvdy5oeHgiCiNpbmNsdWRlIDxzZngyL2NoaWxkd2luLmh4eD4KCiNpbmNsdWRlIDxzZngyL3ZpZXdmcm0uaHh4PgoKI2luY2x1ZGUgInN0cm1uYW1lLmgiCiNpbmNsdWRlICJzZHRyZWVsYi5oeHgiCiNpbmNsdWRlICJEcmF3RG9jU2hlbGwuaHh4IgojaW5jbHVkZSAiZHJhd2RvYy5oeHgiCiNpbmNsdWRlICJzZHBhZ2UuaHh4IgojaW5jbHVkZSAic2RyZXNpZC5oeHgiCiNpbmNsdWRlICJuYXZpZ2F0ci5oeHgiCiNpZm5kZWYgX1NEX0NGR0lEX0hYWAojaW5jbHVkZSAic3RyaW5ncy5ocmMiCiNlbmRpZgojaW5jbHVkZSAicmVzX2JtcC5ocmMiCiNpbmNsdWRlICJWaWV3U2hlbGwuaHh4IgojaW5jbHVkZSAiRHJhd0NvbnRyb2xsZXIuaHh4IgojaW5jbHVkZSAiVmlld1NoZWxsQmFzZS5oeHgiCgojaW5jbHVkZSA8Y29tL3N1bi9zdGFyL2VtYmVkL1hFbWJlZFBlcnNpc3QuaHBwPgojaW5jbHVkZSA8Y29tL3N1bi9zdGFyL2ZyYW1lL1hEZXNrdG9wLmhwcD4KI2luY2x1ZGUgPGNvbS9zdW4vc3Rhci9mcmFtZS9YRnJhbWVzU3VwcGxpZXIuaHBwPgojaW5jbHVkZSA8c3Z0b29scy9lbWJlZHRyYW5zZmVyLmh4eD4KI2luY2x1ZGUgPGNvbXBoZWxwZXIvcHJvY2Vzc2ZhY3RvcnkuaHh4PgojaW5jbHVkZSA8dG9vbHMvZGlhZ25vc2VfZXguaD4KCnVzaW5nIG5hbWVzcGFjZSBjb206OnN1bjo6c3RhcjsKCmNsYXNzIFNkUGFnZU9ianNUTEI6Okljb25Qcm92aWRlcgp7CnB1YmxpYzoKICAgIEljb25Qcm92aWRlciAodm9pZCk7CgogICAgLy8gUmVndWxhciBpY29ucy4KICAgIEltYWdlIG1hSW1nUGFnZTsKICAgIEltYWdlIG1hSW1nUGFnZUV4Y2w7CiAgICBJbWFnZSBtYUltZ1BhZ2VPYmpzRXhjbDsKICAgIEltYWdlIG1hSW1nUGFnZU9ianM7CiAgICBJbWFnZSBtYUltZ09iamVjdHM7CiAgICBJbWFnZSBtYUltZ0dyb3VwOwoKICAgIC8vIEhpZ2ggY29udHJhc3QgaWNvbnMuCiAgICBJbWFnZSBtYUltZ1BhZ2VIOwogICAgSW1hZ2UgbWFJbWdQYWdlRXhjbEg7CiAgICBJbWFnZSBtYUltZ1BhZ2VPYmpzRXhjbEg7CiAgICBJbWFnZSBtYUltZ1BhZ2VPYmpzSDsKICAgIEltYWdlIG1hSW1nT2JqZWN0c0g7CiAgICBJbWFnZSBtYUltZ0dyb3VwSDsKfTsKCgpzYWxfQm9vbCBTRF9ETExQUklWQVRFIFNkUGFnZU9ianNUTEI6OmJJc0luRHJhZyA9IHNhbF9GYWxzZTsKCnNhbF9Cb29sIFNkUGFnZU9ianNUTEI6OklzSW5EcmFnKCkKewoJcmV0dXJuIGJJc0luRHJhZzsKfQoKc2FsX3VJbnQzMiBTZFBhZ2VPYmpzVExCOjpTZFBhZ2VPYmpzVHJhbnNmZXJhYmxlOjptbkxpc3RCb3hEcm9wRm9ybWF0SWQgPSBTQUxfTUFYX1VJTlQzMjsKCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi8vIC0gU2RQYWdlT2Jqc1RMQjo6U2RQYWdlT2Jqc1RyYW5zZmVyYWJsZSAtCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpTZFBhZ2VPYmpzVExCOjpTZFBhZ2VPYmpzVHJhbnNmZXJhYmxlOjpTZFBhZ2VPYmpzVHJhbnNmZXJhYmxlKAogICAgU2RQYWdlT2Jqc1RMQiYgclBhcmVudCwKICAgICAgICBjb25zdCBJTmV0Qm9va21hcmsmIHJCb29rbWFyaywKICAgIDo6c2Q6OkRyYXdEb2NTaGVsbCYgckRvY1NoZWxsLAogICAgTmF2aWdhdG9yRHJhZ1R5cGUgZURyYWdUeXBlLAogICAgY29uc3QgOjpjb206OnN1bjo6c3Rhcjo6dW5vOjpBbnkmIHJUcmVlTGlzdEJveERhdGEgKQogICAgOiBTZFRyYW5zZmVyYWJsZShyRG9jU2hlbGwuR2V0RG9jKCksIE5VTEwsIHNhbF9UcnVlKSwKICAgICAgbXJQYXJlbnQoIHJQYXJlbnQgKSwKICAgICAgbWFCb29rbWFyayggckJvb2ttYXJrICksCiAgICAgIG1yRG9jU2hlbGwoIHJEb2NTaGVsbCApLAogICAgICBtZURyYWdUeXBlKCBlRHJhZ1R5cGUgKSwKICAgICAgbWFUcmVlTGlzdEJveERhdGEoIHJUcmVlTGlzdEJveERhdGEgKQp7Cn0KCgoKClNkUGFnZU9ianNUTEI6OlNkUGFnZU9ianNUcmFuc2ZlcmFibGU6On5TZFBhZ2VPYmpzVHJhbnNmZXJhYmxlKCkKewp9CgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKdm9pZCBTZFBhZ2VPYmpzVExCOjpTZFBhZ2VPYmpzVHJhbnNmZXJhYmxlOjpBZGRTdXBwb3J0ZWRGb3JtYXRzKCkKewogICAgQWRkRm9ybWF0KFNPVF9GT1JNQVRTVFJfSURfTkVUU0NBUEVfQk9PS01BUkspOwogICAgQWRkRm9ybWF0KFNPVF9GT1JNQVRTVFJfSURfVFJFRUxJU1RCT1gpOwogICAgQWRkRm9ybWF0KEdldExpc3RCb3hEcm9wRm9ybWF0SWQoKSk7Cn0KCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpzYWxfQm9vbCBTZFBhZ2VPYmpzVExCOjpTZFBhZ2VPYmpzVHJhbnNmZXJhYmxlOjpHZXREYXRhKCBjb25zdCA6OmNvbTo6c3VuOjpzdGFyOjpkYXRhdHJhbnNmZXI6OkRhdGFGbGF2b3ImIHJGbGF2b3IgKQp7CglzYWxfdUxvbmcgbkZvcm1hdElkID0gU290RXhjaGFuZ2U6OkdldEZvcm1hdCggckZsYXZvciApOwogICAgc3dpdGNoIChuRm9ybWF0SWQpCiAgICB7CiAgICAgICAgY2FzZSBTT1RfRk9STUFUU1RSX0lEX05FVFNDQVBFX0JPT0tNQVJLOgogICAgICAgICAgICBTZXRJTmV0Qm9va21hcmsoIG1hQm9va21hcmssIHJGbGF2b3IgKTsKICAgICAgICAgICAgcmV0dXJuIHNhbF9UcnVlOwoKICAgICAgICBjYXNlIFNPVF9GT1JNQVRTVFJfSURfVFJFRUxJU1RCT1g6CiAgICAgICAgICAgIFNldEFueShtYVRyZWVMaXN0Qm94RGF0YSwgckZsYXZvcik7CiAgICAgICAgICAgIHJldHVybiBzYWxfVHJ1ZTsKCiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgcmV0dXJuIHNhbF9GYWxzZTsKICAgIH0KfQoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCnZvaWQgU2RQYWdlT2Jqc1RMQjo6U2RQYWdlT2Jqc1RyYW5zZmVyYWJsZTo6RHJhZ0ZpbmlzaGVkKCBzYWxfSW50OCBuRHJvcEFjdGlvbiApCnsKCW1yUGFyZW50Lk9uRHJhZ0ZpbmlzaGVkKCBuRHJvcEFjdGlvbiApOwogICAgU2RUcmFuc2ZlcmFibGU6OkRyYWdGaW5pc2hlZChuRHJvcEFjdGlvbik7Cn0KCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgo6OnNkOjpEcmF3RG9jU2hlbGwmIFNkUGFnZU9ianNUTEI6OlNkUGFnZU9ianNUcmFuc2ZlcmFibGU6OkdldERvY1NoZWxsKCkgY29uc3QKewogICAgcmV0dXJuIG1yRG9jU2hlbGw7Cn0KCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpOYXZpZ2F0b3JEcmFnVHlwZSBTZFBhZ2VPYmpzVExCOjpTZFBhZ2VPYmpzVHJhbnNmZXJhYmxlOjpHZXREcmFnVHlwZSgpIGNvbnN0CnsKICAgIHJldHVybiBtZURyYWdUeXBlOwp9CgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKc2FsX0ludDY0IFNBTF9DQUxMIFNkUGFnZU9ianNUTEI6OlNkUGFnZU9ianNUcmFuc2ZlcmFibGU6OmdldFNvbWV0aGluZyggY29uc3QgOjpjb206OnN1bjo6c3Rhcjo6dW5vOjpTZXF1ZW5jZTwgc2FsX0ludDggPiYgcklkICkgdGhyb3coIDo6Y29tOjpzdW46OnN0YXI6OnVubzo6UnVudGltZUV4Y2VwdGlvbiApCnsKICAgIHNhbF9JbnQ2NCBuUmV0OwoKICAgIGlmKCAoIHJJZC5nZXRMZW5ndGgoKSA9PSAxNiApICYmCiAgICAgICAgKCAwID09IHJ0bF9jb21wYXJlTWVtb3J5KCBnZXRVbm9UdW5uZWxJZCgpLmdldENvbnN0QXJyYXkoKSwgcklkLmdldENvbnN0QXJyYXkoKSwgMTYgKSApICkKICAgIHsKICAgICAgICBuUmV0ID0gKHNhbF9JbnQ2NCkoc2FsX0ludFB0cil0aGlzOwogICAgfQogICAgZWxzZQogICAgICAgIG5SZXQgPSBTZFRyYW5zZmVyYWJsZTo6Z2V0U29tZXRoaW5nKHJJZCk7CgoJcmV0dXJuIG5SZXQ7Cn0KCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpjb25zdCA6OmNvbTo6c3VuOjpzdGFyOjp1bm86OlNlcXVlbmNlPCBzYWxfSW50OCA+JiBTZFBhZ2VPYmpzVExCOjpTZFBhZ2VPYmpzVHJhbnNmZXJhYmxlOjpnZXRVbm9UdW5uZWxJZCgpCnsKICAgIHN0YXRpYyA6OmNvbTo6c3VuOjpzdGFyOjp1bm86OlNlcXVlbmNlPCBzYWxfSW50OCA+IGFTZXE7CgoJaWYoICFhU2VxLmdldExlbmd0aCgpICkKCXsKCQlzdGF0aWMgb3NsOjpNdXRleCAgIGFDcmVhdGVNdXRleDsKICAgIAlvc2w6Ok11dGV4R3VhcmQgICAgIGFHdWFyZCggYUNyZWF0ZU11dGV4ICk7CgoJCWFTZXEucmVhbGxvYyggMTYgKTsKICAgIAlydGxfY3JlYXRlVXVpZCggcmVpbnRlcnByZXRfY2FzdDwgc2FsX3VJbnQ4KiA+KCBhU2VxLmdldEFycmF5KCkgKSwgMCwgc2FsX1RydWUgKTsKCX0KCiAgICByZXR1cm4gYVNlcTsKfQoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KClNkUGFnZU9ianNUTEI6OlNkUGFnZU9ianNUcmFuc2ZlcmFibGUqIFNkUGFnZU9ianNUTEI6OlNkUGFnZU9ianNUcmFuc2ZlcmFibGU6OmdldEltcGxlbWVudGF0aW9uKCBjb25zdCA6OmNvbTo6c3VuOjpzdGFyOjp1bm86OlJlZmVyZW5jZTwgOjpjb206OnN1bjo6c3Rhcjo6dW5vOjpYSW50ZXJmYWNlID4mIHJ4RGF0YSApCiAgICB0aHJvdygpCnsKICAgIHRyeQogICAgewoJICAgIDo6Y29tOjpzdW46OnN0YXI6OnVubzo6UmVmZXJlbmNlPCA6OmNvbTo6c3VuOjpzdGFyOjpsYW5nOjpYVW5vVHVubmVsID4geFVub1R1bm5lbCggcnhEYXRhLCA6OmNvbTo6c3VuOjpzdGFyOjp1bm86OlVOT19RVUVSWV9USFJPVyApOwoKCQlyZXR1cm4gcmVpbnRlcnByZXRfY2FzdDxTZFBhZ2VPYmpzVExCOjpTZFBhZ2VPYmpzVHJhbnNmZXJhYmxlKj4oCgkJCQlzYWw6OnN0YXRpY19pbnRfY2FzdDxzYWxfdUludFB0cj4oCgkJCQkJeFVub1R1bm5lbC0+Z2V0U29tZXRoaW5nKCBTZFBhZ2VPYmpzVExCOjpTZFBhZ2VPYmpzVHJhbnNmZXJhYmxlOjpnZXRVbm9UdW5uZWxJZCgpKSApICk7CiAgICB9CiAgICBjYXRjaCggY29uc3QgOjpjb206OnN1bjo6c3Rhcjo6dW5vOjpFeGNlcHRpb24mICkKCXsKCX0KCXJldHVybiAwOwp9CgoKc2FsX3VJbnQzMiBTZFBhZ2VPYmpzVExCOjpTZFBhZ2VPYmpzVHJhbnNmZXJhYmxlOjpHZXRMaXN0Qm94RHJvcEZvcm1hdElkICh2b2lkKQp7CiAgICBpZiAobW5MaXN0Qm94RHJvcEZvcm1hdElkID09IFNBTF9NQVhfVUlOVDMyKQogICAgICAgIG1uTGlzdEJveERyb3BGb3JtYXRJZCA9IFNvdEV4Y2hhbmdlOjpSZWdpc3RlckZvcm1hdE1pbWVUeXBlKAogICAgICAgICAgICA6OnJ0bDo6T1VTdHJpbmc6OmNyZWF0ZUZyb21Bc2NpaSgKICAgICAgICAgICAgICAgICJhcHBsaWNhdGlvbi94LW9wZW5vZmZpY2UtdHJlZWxpc3Rib3gtbW92ZW9ubHk7IgogICAgICAgICAgICAgICAgICAgICJ3aW5kb3dzX2Zvcm1hdG5hbWU9XCJTVl9MQk9YX0REX0ZPUk1BVF9NT1ZFXCIiKSk7CiAgICByZXR1cm4gbW5MaXN0Qm94RHJvcEZvcm1hdElkOwp9CgoKCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgp8Kgp8KiBDdG9yMSBTZFBhZ2VPYmpzVExCCnwqClwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgpTZFBhZ2VPYmpzVExCOjpTZFBhZ2VPYmpzVExCKCBXaW5kb3cqIHBQYXJlbnRXaW4sIGNvbnN0IFNkUmVzSWQmIHJTZFJlc0lkICkKOglTdlRyZWVMaXN0Qm94ICAgICAgICggcFBhcmVudFdpbiwgclNkUmVzSWQgKQosICAgYmlzSW5TZE5hdmlnYXRvcldpbiAgKCBzYWxfRmFsc2UgKQosCW1wUGFyZW50IAkJICAgICggcFBhcmVudFdpbiApCiwJbXBEb2MJCQkgICAgKCBOVUxMICkKLAltcEJvb2ttYXJrRG9jCSAgICAoIE5VTEwgKQosCW1wTWVkaXVtIAkgICAgCSggTlVMTCApCiwJbXBPd25NZWRpdW0JCSAgICAoIE5VTEwgKQosCW1hSW1nT2xlICAgICAgICAgICAgICggQml0bWFwRXgoIFNkUmVzSWQoIEJNUF9PTEUgKSApICkKLAltYUltZ0dyYXBoaWMgICAgICAgICAoIEJpdG1hcEV4KCBTZFJlc0lkKCBCTVBfR1JBUEhJQyApICkgKQosCW1hSW1nT2xlSCAgICAgICAgICAgICggQml0bWFwRXgoIFNkUmVzSWQoIEJNUF9PTEVfSCApICkgKQosCW1hSW1nR3JhcGhpY0ggICAgICAgICggQml0bWFwRXgoIFNkUmVzSWQoIEJNUF9HUkFQSElDX0ggKSApICkKLAltYkxpbmthYmxlU2VsZWN0ZWQgICggc2FsX0ZhbHNlICkKLAltcERyb3BOYXZXaW4JCSggTlVMTCApCiwgICBtYlNob3dBbGxTaGFwZXMgICAgICggZmFsc2UgKQosICAgbWJTaG93QWxsUGFnZXMgICAgICAoIGZhbHNlICkKewoJLy8gVHJlZS1MaXN0Qm94IG1pdCBMaW5pZW4gdmVyc2VoZW4KCVNldFN0eWxlKCBHZXRTdHlsZSgpIHwgV0JfVEFCU1RPUCB8IFdCX0JPUkRFUiB8IFdCX0hBU0xJTkVTIHwKCQkJCQkJICAgV0JfSEFTQlVUVE9OUyB8IC8vIFdCX0hBU0xJTkVTQVRST09UIHwKCQkJCQkJICAgV0JfSFNDUk9MTCB8IC8vICMzMTU2MiMKCQkJCQkJICAgV0JfSEFTQlVUVE9OU0FUUk9PVCB8CiAgICAgICAgICAgICAgICAgICAgICAgICAgIFdCX1FVSUNLX1NFQVJDSCAvKiBpMzEyNzUgKi8gKTsKCVNldE5vZGVCaXRtYXBzKCBCaXRtYXAoIFNkUmVzSWQoIEJNUF9FWFBBTkQgKSApLAoJCQkJCUJpdG1hcCggU2RSZXNJZCggQk1QX0NPTExBUFNFICkgKSApOwoKCVNldE5vZGVCaXRtYXBzKCBCaXRtYXAoIFNkUmVzSWQoIEJNUF9FWFBBTkRfSCApICksCgkJCQkJQml0bWFwKCBTZFJlc0lkKCBCTVBfQ09MTEFQU0VfSCApICksCgkJCQkJQk1QX0NPTE9SX0hJR0hDT05UUkFTVCApOwoKICAgIFNldERyYWdEcm9wTW9kZSgKIAkJU1ZfRFJBR0RST1BfQ1RSTF9NT1ZFIHwgU1ZfRFJBR0RST1BfQ1RSTF9DT1BZIHwKICAgICAgICAgICAgU1ZfRFJBR0RST1BfQVBQX01PVkUgIHwgU1ZfRFJBR0RST1BfQVBQX0NPUFkgIHwgU1ZfRFJBR0RST1BfQVBQX0RST1AgKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKfCoKfCogRHRvciBTZFBhZ2VPYmpzVExCCnwqClwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgpTZFBhZ2VPYmpzVExCOjp+U2RQYWdlT2Jqc1RMQigpCnsKICAgIGlmICggbXBCb29rbWFya0RvYyApCiAgICAgICAgQ2xvc2VCb29rbWFya0RvYygpOwogICAgZWxzZQogICAgICAgIC8vIG5vIGRvY3VtZW50IHdhcyBjcmVhdGVkIGZyb20gbXBNZWRpdW0sIHNvIHRoaXMgb2JqZWN0IGlzIHN0aWxsIHRoZSBvd25lciBvZiBpdAogICAgICAgIGRlbGV0ZSBtcE1lZGl1bTsKfQoKLy8gaGVscGVyIGZ1bmN0aW9uIGZvciAJR2V0RW50cnlBbHRUZXh0IGFuZCBHZXRFbnRyeUxvbmdEZXNjcmlwdGlvbgpTdHJpbmcgU2RQYWdlT2Jqc1RMQjo6Z2V0QWx0TG9uZ0Rlc2NUZXh0KCBTdkxCb3hFbnRyeSogcEVudHJ5ICwgc2FsX0Jvb2wgaXNBbHRUZXh0KSBjb25zdAp7CglzYWxfdUludDE2IG1heFBhZ2VzID0gbXBEb2MtPkdldFBhZ2VDb3VudCgpOwoJc2FsX3VJbnQxNiBwYWdlTm87CglTZHJPYmplY3QqCSBwT2JqID0gTlVMTDsKCVNkUGFnZSogcFBhZ2UgPSBOVUxMOwoKCglTdHJpbmcgUGFyZW50TmFtZSA9IEdldEVudHJ5VGV4dCggR2V0Um9vdExldmVsUGFyZW50KCBwRW50cnkgKSApOwoKCWZvciggcGFnZU5vID0gMDsgIHBhZ2VObyA8IG1heFBhZ2VzOyBwYWdlTm8rKyApCgl7CgkJcFBhZ2UgPSAoU2RQYWdlKikgbXBEb2MtPkdldFBhZ2UoIHBhZ2VObyApOwoJCWlmKCBwUGFnZS0+R2V0UGFnZUtpbmQoKSAhPSBQS19TVEFOREFSRCApIGNvbnRpbnVlOwoJCWlmKCBwUGFnZS0+R2V0TmFtZSgpICE9ICBQYXJlbnROYW1lICkgY29udGludWU7CgkJU2RyT2JqTGlzdEl0ZXIgYUl0ZXIoICpwUGFnZSwgSU1fRkxBVCApOwoJCXdoaWxlKCBhSXRlci5Jc01vcmUoKSApCgkJewoJCQlwT2JqID0gYUl0ZXIuTmV4dCgpOwoJCQlpZiggR2V0RW50cnlUZXh0KHBFbnRyeSkgPT0gIEdldE9iamVjdE5hbWUoIHBPYmogKSAgKQoJCQl7CgkJCQlpZiggaXNBbHRUZXh0ICkKCQkJCQlyZXR1cm4gcE9iai0+R2V0VGl0bGUoKTsKCQkJCWVsc2UKCQkJCQlyZXR1cm4gcE9iai0+R2V0RGVzY3JpcHRpb24oKTsKCQkJfQoJCX0KCX0KCXJldHVybiBTdHJpbmcoKTsKCn0KClN0cmluZyBTZFBhZ2VPYmpzVExCOjpHZXRFbnRyeUFsdFRleHQoIFN2TEJveEVudHJ5KiBwRW50cnkgKSBjb25zdAp7CglyZXR1cm4gZ2V0QWx0TG9uZ0Rlc2NUZXh0KCBwRW50cnksIHNhbF9UcnVlICk7Cn0KClN0cmluZyBTZFBhZ2VPYmpzVExCOjpHZXRFbnRyeUxvbmdEZXNjcmlwdGlvbiggU3ZMQm94RW50cnkqIHBFbnRyeSApIGNvbnN0CnsKCXJldHVybiBnZXRBbHRMb25nRGVzY1RleHQoIHBFbnRyeSwgc2FsX0ZhbHNlKTsKfQoKdm9pZCAgU2RQYWdlT2Jqc1RMQjo6TWFya0N1ckVudHJ5KCBjb25zdCBTdHJpbmcmIHJOYW1lICkKewoKCWlmKCByTmFtZS5MZW4oKSApCgl7CgkJU3ZMQm94RW50cnkqIHBDdXJFbnRyeSA9R2V0Q3VyRW50cnkoKTsKCQlTdkxCb3hFbnRyeSogcEVudHJ5ID1OVUxMOwoJCVN0cmluZyBhVG1wMTsKCQlTdHJpbmcgYVRtcDI7CgoJICAgICAgIGlmKCBHZXRQYXJlbnQocEN1ckVudHJ5KT09TlVMTCApCgkgICAgICAgewoJICAgICAgICAgICAgICBhVG1wMSA9IEdldEVudHJ5VGV4dCggcEN1ckVudHJ5ICk7CgkJICAgICAgIGZvciggcEVudHJ5ID0gRmlyc3QoKTsgcEVudHJ5IDsgcEVudHJ5ID0gTmV4dCggcEVudHJ5ICkgKQoJCQl7CgkJCSAgICAgICBpZihHZXRQYXJlbnQoIHBFbnRyeSApPT1OVUxMKQoJCQkJICAgCSAgICAgY29udGludWU7CgkJCQlhVG1wMiA9IEdldEVudHJ5VGV4dCggR2V0UGFyZW50KCBwRW50cnkgKSk7CgkJCQlpZiggYVRtcDEgIT0gYVRtcDIpCgkJCQl7CgkJCQkJLy8gSUEyIENXUy4gTVQ6IFJlbW92ZWQgaW4gU3ZMQm94RW50cnkgZm9yIG5vdyAtIG9ubHkgdXNlZCBpbiBTdy9TZC9TY0NvbnRlbnRMQm94U3RyaW5nLCB0aGV5IHNob3VsZCBkZWNpZGUgaWYgdGhleSBuZWVkIHRoaXMKCQkJCQlwRW50cnktPlNldE1hcmtlZChzYWxfRmFsc2UpOwoJCQkJfQoJCQl9CgoJICAgICAgIH0KICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgewoJICAgICAgICAgICAgICBmb3IoIHBFbnRyeSA9IEZpcnN0KCk7IHBFbnRyeSA7IHBFbnRyeSA9IE5leHQoIHBFbnRyeSApICkKCQkJewoJCQkJYVRtcDIgPSBHZXRFbnRyeVRleHQoIHBFbnRyeSApOwoJCQkJaWYoIGFUbXAyID09IHJOYW1lKQoJCQkJewoJCQkJCXBFbnRyeS0+U2V0TWFya2VkKHNhbF9UcnVlKTsKCQkJCX0KCQkJCWVsc2UKCQkJCXsKCQkJCSAgICAgICAgcEVudHJ5LT5TZXRNYXJrZWQoc2FsX0ZhbHNlKTsKCQkJCX0KCQkJfQogICAgICAgICAgICAgIH0KCX0KCUludmFsaWRhdGUoKTsKfQoKdm9pZCAgU2RQYWdlT2Jqc1RMQjo6IEZyZXNoQ3VyRW50cnkoKQp7CiAgICAgICBTdkxCb3hFbnRyeSogcEVudHJ5ID1OVUxMOwogICAgICAgZm9yKCBwRW50cnkgPSBGaXJzdCgpOyBwRW50cnkgOyBwRW50cnkgPSBOZXh0KCBwRW50cnkgKSApCgl7CgkJICAgICAgICBwRW50cnktPlNldE1hcmtlZChzYWxfRmFsc2UpOwoJfQoJSW52YWxpZGF0ZSgpOwp9CgpjbGFzcyBTZENvbnRlbnRMQm94U3RyaW5nIDogcHVibGljIFN2TEJveFN0cmluZwp7CnB1YmxpYzoKCVNkQ29udGVudExCb3hTdHJpbmcoIFN2TEJveEVudHJ5KiBwRW50cnksIHNhbF91SW50MTYgbkZsYWdzLAoJCWNvbnN0IFN0cmluZyYgclN0ciApIDogU3ZMQm94U3RyaW5nKHBFbnRyeSxuRmxhZ3MsclN0cikJe30KCgl2aXJ0dWFsIHZvaWQgUGFpbnQoIGNvbnN0IFBvaW50JiByUG9zLCBTdkxCb3gmIHJEZXYsIHNhbF91SW50MTYgbkZsYWdzLAoJCVN2TEJveEVudHJ5KiBwRW50cnkpOwp9OwoKdm9pZCBTZFBhZ2VPYmpzVExCOjpJbml0RW50cnkoU3ZMQm94RW50cnkqIHBFbnRyeSwKCQljb25zdCBYdWJTdHJpbmcmIHJTdHIgLGNvbnN0IEltYWdlJiBySW1nMSxjb25zdCBJbWFnZSYgckltZzIsU3ZMQm94QnV0dG9uS2luZCBlQnV0dG9uS2luZCkKewoJc2FsX3VJbnQxNiBuQ29sVG9IaWxpdGUgPSAxOyAvLzA9PUJpdG1hcDsxPT0iU3BhbHRlMSI7Mj09IlNwYWx0ZTIiCglTdlRyZWVMaXN0Qm94OjpJbml0RW50cnkoIHBFbnRyeSwgclN0ciwgckltZzEsIHJJbWcyLCBlQnV0dG9uS2luZCApOwoJU3ZMQm94U3RyaW5nKiBwQ29sID0gKFN2TEJveFN0cmluZyopcEVudHJ5LT5HZXRJdGVtKCBuQ29sVG9IaWxpdGUgKTsKCVNkQ29udGVudExCb3hTdHJpbmcqIHBTdHIgPSBuZXcgU2RDb250ZW50TEJveFN0cmluZyggcEVudHJ5LCAwLCBwQ29sLT5HZXRUZXh0KCkgKTsKCXBFbnRyeS0+UmVwbGFjZUl0ZW0oIHBTdHIsIG5Db2xUb0hpbGl0ZSApOwp9Cgp2b2lkIFNkQ29udGVudExCb3hTdHJpbmc6OlBhaW50KCBjb25zdCBQb2ludCYgclBvcywgU3ZMQm94JiByRGV2LCBzYWxfdUludDE2IG5GbGFncywKCVN2TEJveEVudHJ5KiBwRW50cnkgKQp7CgkvLyBJQTIgQ1dTLiBNVDogUmVtb3ZlZCBmb3Igbm93IChhbHNvIGluIFN2TEJveEVudHJ5KSAtIG9ubHkgdXNlZCBpbiBTdy9TZC9TY0NvbnRlbnRMQm94U3RyaW5nLCB0aGV5IHNob3VsZCBkZWNpZGUgaWYgdGhleSBuZWVkIHRoaXMKCS8qCglpZiAocEVudHJ5LT5Jc01hcmtlZCgpKQoJewoJCQlyRGV2LkRyYXdUZXh0KCByUG9zLCBHZXRUZXh0KCkgKTsKCQkJWHViU3RyaW5nIHN0cjsKCQkJc3RyID0gWHViU3RyaW5nOjpDcmVhdGVGcm9tQXNjaWkoIioiKTsKCQkJUG9pbnQgclBvc1N0YXIoclBvcy5YKCktNixyUG9zLlkoKSk7CgkJCUZvbnQgYU9sZEZvbnQoIHJEZXYuR2V0Rm9udCgpKTsKCQkJRm9udCBhRm9udChhT2xkRm9udCk7CgkJCUNvbG9yIGFDb2woIGFPbGRGb250LkdldENvbG9yKCkgKTsKCQkJYUNvbC5EZWNyZWFzZUx1bWluYW5jZSggMjAwICk7CgkJCWFGb250LlNldENvbG9yKCBhQ29sICk7CgkJCXJEZXYuU2V0Rm9udCggYUZvbnQgKTsKCQkJckRldi5EcmF3VGV4dCggclBvc1N0YXIsIHN0cik7CgkJCXJEZXYuU2V0Rm9udCggYU9sZEZvbnQgKTsKCX0KCWVsc2UKCSovCgkJU3ZMQm94U3RyaW5nOjpQYWludCggclBvcywgckRldiwgbkZsYWdzLCBwRW50cnkpOwoKfQoKdm9pZCBTZFBhZ2VPYmpzVExCOjpTYXZlRXhwYW5kZWRUcmVlSXRlbVN0YXRlKFN2TEJveEVudHJ5KiBwRW50cnksIHZlY3RvcjxTdHJpbmc+JiB2ZWN0VHJlZUl0ZW0pCnsKCWlmIChwRW50cnkpCgl7CgkJU3ZMQm94RW50cnkqIHBMaXN0RW50cnkgPSBwRW50cnk7CgkJd2hpbGUgKHBMaXN0RW50cnkpCgkJewoJCQlpZiAocExpc3RFbnRyeS0+SGFzQ2hpbGRzKCkpCgkJCXsKCQkJCWlmIChJc0V4cGFuZGVkKHBMaXN0RW50cnkpKQoJCQkJCXZlY3RUcmVlSXRlbS5wdXNoX2JhY2soR2V0RW50cnlUZXh0KHBMaXN0RW50cnkpKTsKCQkJCVN2TEJveEVudHJ5KiBwQ2hpbGRFbnRyeSA9IEZpcnN0Q2hpbGQocExpc3RFbnRyeSk7CgkJCQlTYXZlRXhwYW5kZWRUcmVlSXRlbVN0YXRlKHBDaGlsZEVudHJ5LCB2ZWN0VHJlZUl0ZW0pOwoJCQl9CgkJCXBMaXN0RW50cnkgPSBOZXh0U2libGluZyhwTGlzdEVudHJ5KTsKCQl9Cgl9Cn0Kdm9pZCBTZFBhZ2VPYmpzVExCOjpDbGVhcigpCnsKCS8vU2F2ZSB0aGUgZXhwYW5kZWQgdHJlZSBpdGVtCglpZiAobWJTYXZlVHJlZUl0ZW1TdGF0ZSkKCXsKCQltYVNlbGVjdGlvbkVudHJ5VGV4dCA9IFN0cmluZygpOwoJCW1hVHJlZUl0ZW0uY2xlYXIoKTsKCQlpZiAoR2V0Q3VyRW50cnkoKSkKCQkJbWFTZWxlY3Rpb25FbnRyeVRleHQgPSBHZXRTZWxlY3RFbnRyeSgpOwoJCVN2TEJveEVudHJ5KiBwRW50cnkgPSBGaXJzdENoaWxkKE5VTEwpOwoJCVNhdmVFeHBhbmRlZFRyZWVJdGVtU3RhdGUocEVudHJ5LCBtYVRyZWVJdGVtKTsKCX0KCXJldHVybiBTdlRyZWVMaXN0Qm94OjpDbGVhcigpOwp9Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCnwqCnwqIHJldHVybiBuYW1lIG9mIG9iamVjdAp8KgpcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKU3RyaW5nIFNkUGFnZU9ianNUTEI6OkdldE9iamVjdE5hbWUoCiAgICBjb25zdCBTZHJPYmplY3QqIHBPYmplY3QsCiAgICBjb25zdCBib29sIGJDcmVhdGUpIGNvbnN0CnsKICAgIFN0cmluZyBhUmV0OwoKICAgIGlmICggcE9iamVjdCApCiAgICB7CiAgICAgICAgYVJldCA9IHBPYmplY3QtPkdldE5hbWUoKTsKCiAgICAgICAgaWYoICFhUmV0LkxlbigpICYmIHBPYmplY3QtPklTQSggU2RyT2xlMk9iaiApICkKICAgICAgICAgICAgYVJldCA9IHN0YXRpY19jYXN0PCBjb25zdCBTZHJPbGUyT2JqKiA+KCBwT2JqZWN0ICktPkdldFBlcnNpc3ROYW1lKCk7CiAgICB9CgogICAgaWYgKGJDcmVhdGUKICAgICAgICAmJiBtYlNob3dBbGxTaGFwZXMKICAgICAgICAmJiBhUmV0LkxlbigpID09IDAKICAgICAgICAmJiBwT2JqZWN0IT1OVUxMKQogICAgewogICAgICAgIGFSZXQgPSBTZFJlc0lkKFNUUl9OQVZJR0FUT1JfU0hBUEVfQkFTRV9OQU1FKTsKICAgICAgICBhUmV0LlNlYXJjaEFuZFJlcGxhY2VBc2NpaSgiJTEiLCBTdHJpbmc6OkNyZWF0ZUZyb21JbnQzMihwT2JqZWN0LT5HZXRPcmROdW0oKSArIDEpKTsKICAgIH0KCiAgICByZXR1cm4gYVJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKfCoKfCogSW4gVHJlZUxCIEVpbnRyYWcgc2VsZWt0aWVyZW4KfCoKXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCnNhbF9Cb29sIFNkUGFnZU9ianNUTEI6OlNlbGVjdEVudHJ5KCBjb25zdCBTdHJpbmcmIHJOYW1lICkKewoJc2FsX0Jvb2wgYkZvdW5kID0gc2FsX0ZhbHNlOwoKCWlmKCByTmFtZS5MZW4oKSApCgl7CgkJU3ZMQm94RW50cnkqIHBFbnRyeSA9IE5VTEw7CgkJU3RyaW5nIGFUbXA7CgoJCWZvciggcEVudHJ5ID0gRmlyc3QoKTsgcEVudHJ5ICYmICFiRm91bmQ7IHBFbnRyeSA9IE5leHQoIHBFbnRyeSApICkKCQl7CgkJCWFUbXAgPSBHZXRFbnRyeVRleHQoIHBFbnRyeSApOwoJCQlpZiggYVRtcCA9PSByTmFtZSApCgkJCXsKCQkJCWJGb3VuZCA9IHNhbF9UcnVlOwoJCQkJU2V0Q3VyRW50cnkoIHBFbnRyeSApOwoJCQl9CgkJfQoJfQoJcmV0dXJuKCBiRm91bmQgKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKfCoKfCogR2lidCB6dXJ1ZWNrLCBvYiBDaGlsZHMgZGVzIHVlYmVyZ2ViZW5lbiBTdHJpbmdzIHNlbGVrdGllcnQgc2luZAp8KgpcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKc2FsX0Jvb2wgU2RQYWdlT2Jqc1RMQjo6SGFzU2VsZWN0ZWRDaGlsZHMoIGNvbnN0IFN0cmluZyYgck5hbWUgKQp7CglzYWxfQm9vbCBiRm91bmQgID0gc2FsX0ZhbHNlOwoJc2FsX0Jvb2wgYkNoaWxkcyA9IHNhbF9GYWxzZTsKCglpZiggck5hbWUuTGVuKCkgKQoJewoJCVN2TEJveEVudHJ5KiBwRW50cnkgPSBOVUxMOwoJCVN0cmluZyBhVG1wOwoKCQlmb3IoIHBFbnRyeSA9IEZpcnN0KCk7IHBFbnRyeSAmJiAhYkZvdW5kOyBwRW50cnkgPSBOZXh0KCBwRW50cnkgKSApCgkJewoJCQlhVG1wID0gR2V0RW50cnlUZXh0KCBwRW50cnkgKTsKCQkJaWYoIGFUbXAgPT0gck5hbWUgKQoJCQl7CgkJCQliRm91bmQgPSBzYWxfVHJ1ZTsKCQkJCXNhbF9Cb29sIGJFeHBhbmRlZCA9IElzRXhwYW5kZWQoIHBFbnRyeSApOwoJCQkJbG9uZyBuQ291bnQgPSBHZXRDaGlsZFNlbGVjdGlvbkNvdW50KCBwRW50cnkgKTsKCQkJCWlmKCBiRXhwYW5kZWQgJiYgbkNvdW50ID4gMCApCgkJCQkJYkNoaWxkcyA9IHNhbF9UcnVlOwoJCQl9CgkJfQoJfQoJcmV0dXJuKCBiQ2hpbGRzICk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgp8Kgp8KiBUcmVlTEIgbWl0IFNlaXRlbiB1bmQgT2JqZWt0ZW4gZnVlbGxlbgp8KgpcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKdm9pZCBTZFBhZ2VPYmpzVExCOjpGaWxsKCBjb25zdCBTZERyYXdEb2N1bWVudCogcEluRG9jLCBzYWxfQm9vbCBiQWxsUGFnZXMsCgkJCQkJCSAgY29uc3QgU3RyaW5nJiByRG9jTmFtZSkKewoJU3RyaW5nIGFTZWxlY3Rpb247CglpZiggR2V0U2VsZWN0aW9uQ291bnQoKSA+IDAgKQoJewoJCWFTZWxlY3Rpb24gPSBHZXRTZWxlY3RFbnRyeSgpOwoJCUNsZWFyKCk7Cgl9CgoJbXBEb2MgPSBwSW5Eb2M7CgltYURvY05hbWUgPSByRG9jTmFtZTsKICAgIG1iU2hvd0FsbFBhZ2VzID0gKGJBbGxQYWdlcyA9PSBzYWxfVHJ1ZSk7CgltcE1lZGl1bSA9IE5VTEw7CgoJU2RQYWdlKiAJIHBQYWdlID0gTlVMTDsKCiAgICBJY29uUHJvdmlkZXIgYUljb25Qcm92aWRlcjsKCgkvLyBmaXJzdCBpbnNlcnQgYWxsIHBhZ2VzIGluY2x1ZGluZyBvYmplY3RzCglzYWxfdUludDE2IG5QYWdlID0gMDsKCWNvbnN0IHNhbF91SW50MTYgbk1heFBhZ2VzID0gbXBEb2MtPkdldFBhZ2VDb3VudCgpOwoKCXdoaWxlKCBuUGFnZSA8IG5NYXhQYWdlcyApCgl7CgkJcFBhZ2UgPSAoU2RQYWdlKikgbXBEb2MtPkdldFBhZ2UoIG5QYWdlICk7CgkJaWYoICAobWJTaG93QWxsUGFnZXMgfHwgcFBhZ2UtPkdldFBhZ2VLaW5kKCkgPT0gUEtfU1RBTkRBUkQpCgkJICAgICAmJiAhKHBQYWdlLT5HZXRQYWdlS2luZCgpPT1QS19IQU5ET1VUKSAgICkgLy8jOTQ5NTQjIG5ldmVyIGxpc3QgdGhlIG5vcm1hbCBoYW5kb3V0IHBhZ2UgKCBoYW5kb3V0LW1hc3RlcnBhZ2UgaXMgdXNlZCBpbnN0ZWFkICkKCQl7CgkJCXNhbF9Cb29sIGJQYWdlRXhsdWRlZCA9IHBQYWdlLT5Jc0V4Y2x1ZGVkKCk7CgogICAgICAgICAgICBib29sIGJQYWdlQmVsb25nc1RvU2hvdyA9IFBhZ2VCZWxvbmdzVG9DdXJyZW50U2hvdyAocFBhZ2UpOwogICAgICAgICAgICBiUGFnZUV4bHVkZWQgfD0gIWJQYWdlQmVsb25nc1RvU2hvdzsKCiAgICAgICAgICAgIEFkZFNoYXBlTGlzdCgqcFBhZ2UsIE5VTEwsIHBQYWdlLT5HZXROYW1lKCksIGJQYWdlRXhsdWRlZCwgTlVMTCwgYUljb25Qcm92aWRlcik7CgkJfQoJCW5QYWdlKys7Cgl9CgoJLy8gZGFubiBhbGxlIE1hc3RlclBhZ2VzIGluY2wuIE9iamVrdGUgZWluZnVlZ2VuCglpZiggbWJTaG93QWxsUGFnZXMgKQoJewoJCW5QYWdlID0gMDsKCQljb25zdCBzYWxfdUludDE2IG5NYXhNYXN0ZXJQYWdlcyA9IG1wRG9jLT5HZXRNYXN0ZXJQYWdlQ291bnQoKTsKCgkJd2hpbGUoIG5QYWdlIDwgbk1heE1hc3RlclBhZ2VzICkKCQl7CgkJCXBQYWdlID0gKFNkUGFnZSopIG1wRG9jLT5HZXRNYXN0ZXJQYWdlKCBuUGFnZSApOwogICAgICAgICAgICBBZGRTaGFwZUxpc3QoKnBQYWdlLCBOVUxMLCBwUGFnZS0+R2V0TmFtZSgpLCBmYWxzZSwgTlVMTCwgYUljb25Qcm92aWRlcik7CgkJCW5QYWdlKys7CgkJfQoJfQoJaWYoIGFTZWxlY3Rpb24uTGVuKCkgKQoJCVNlbGVjdEVudHJ5KCBhU2VsZWN0aW9uICk7CgllbHNlIGlmIChtYlNhdmVUcmVlSXRlbVN0YXRlICYmIG1hU2VsZWN0aW9uRW50cnlUZXh0LkxlbigpKQoJewoJCVNlbGVjdEVudHJ5KG1hU2VsZWN0aW9uRW50cnlUZXh0KTsKCX0KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKfCoKfCogRXMgd2lyZCBudXIgZGVyIGVyc3RlIEVpbnRyYWcgZWluZ2VmdWVndC4gQ2hpbGRzIHdlcmRlbiBPbkRlbWFuZCBlcnpldWd0CnwqClwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgp2b2lkIFNkUGFnZU9ianNUTEI6OkZpbGwoIGNvbnN0IFNkRHJhd0RvY3VtZW50KiBwSW5Eb2MsIFNmeE1lZGl1bSogcEluTWVkaXVtLAoJCQkJCQkgIGNvbnN0IFN0cmluZyYgckRvY05hbWUgKQp7CgltcERvYyA9IHBJbkRvYzsKCiAgICAvLyB0aGlzIG9iamVjdCBub3cgb3ducyB0aGUgTWVkaXVtCgltcE1lZGl1bSA9IHBJbk1lZGl1bTsKCW1hRG9jTmFtZSA9IHJEb2NOYW1lOwoKCUltYWdlIGFJbWdEb2NPcGVuPUltYWdlKCBCaXRtYXBFeCggU2RSZXNJZCggQk1QX0RPQ19PUEVOICkgKSApOwoJSW1hZ2UgYUltZ0RvY0Nsb3NlZD1JbWFnZSggQml0bWFwRXgoIFNkUmVzSWQoIEJNUF9ET0NfQ0xPU0VEICkgKSApOwoJSW1hZ2UgYUltZ0RvY09wZW5IPUltYWdlKCBCaXRtYXBFeCggU2RSZXNJZCggQk1QX0RPQ19PUEVOX0ggKSApICk7CglJbWFnZSBhSW1nRG9jQ2xvc2VkSD1JbWFnZSggQml0bWFwRXgoIFNkUmVzSWQoIEJNUF9ET0NfQ0xPU0VEX0ggKSApICk7CgoJLy8gRG9rdW1lbnRuYW1lbiBlaW5mdWVnZW4KCVN2TEJveEVudHJ5KiBwRmlsZUVudHJ5ID0gSW5zZXJ0RW50cnkoIG1hRG9jTmFtZSwKCSAgICAgICAgICAgICAgICAgICAgICAgICAgYUltZ0RvY09wZW4sCgkgICAgICAgICAgICAgICAgICAgICAgICAgIGFJbWdEb2NDbG9zZWQsCgkgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwsCgkgICAgICAgICAgICAgICAgICAgICAgICAgIHNhbF9UcnVlLAoJCQkJCQkJICBMSVNUX0FQUEVORCwKCQkJCQkJCSAgcmVpbnRlcnByZXRfY2FzdDwgdm9pZCogPiggMSApICk7CgoJU2V0RXhwYW5kZWRFbnRyeUJtcCggcEZpbGVFbnRyeSwgYUltZ0RvY09wZW5ILCBCTVBfQ09MT1JfSElHSENPTlRSQVNUICk7CglTZXRDb2xsYXBzZWRFbnRyeUJtcCggcEZpbGVFbnRyeSwgYUltZ0RvY0Nsb3NlZEgsIEJNUF9DT0xPUl9ISUdIQ09OVFJBU1QgKTsKfQoKCgoKdm9pZCBTZFBhZ2VPYmpzVExCOjpBZGRTaGFwZUxpc3QgKAogICAgY29uc3QgU2RyT2JqTGlzdCYgckxpc3QsCiAgICBTZHJPYmplY3QqIHBTaGFwZSwKICAgIGNvbnN0IDo6cnRsOjpPVVN0cmluZyYgcnNOYW1lLAogICAgY29uc3QgYm9vbCBiSXNFeGNsdWRlZCwKICAgIFN2TEJveEVudHJ5KiBwUGFyZW50RW50cnksCiAgICBjb25zdCBJY29uUHJvdmlkZXImIHJJY29uUHJvdmlkZXIpCnsKICAgIEltYWdlIGFJY29uIChySWNvblByb3ZpZGVyLm1hSW1nUGFnZSk7CiAgICBpZiAoYklzRXhjbHVkZWQpCiAgICAgICAgYUljb24gPSBySWNvblByb3ZpZGVyLm1hSW1nUGFnZUV4Y2w7CiAgICBlbHNlIGlmIChwU2hhcGUgIT0gTlVMTCkKICAgICAgICBhSWNvbiA9IHJJY29uUHJvdmlkZXIubWFJbWdHcm91cDsKCiAgICB2b2lkKiBwVXNlckRhdGEgKHJlaW50ZXJwcmV0X2Nhc3Q8dm9pZCo+KDEpKTsKICAgIGlmIChwU2hhcGUgIT0gTlVMTCkKICAgICAgICBwVXNlckRhdGEgPSBwU2hhcGU7CgoJU3ZMQm94RW50cnkqIHBFbnRyeSA9IEluc2VydEVudHJ5KAogICAgICAgIHJzTmFtZSwKICAgICAgICBhSWNvbiwKICAgICAgICBhSWNvbiwKICAgICAgICBwUGFyZW50RW50cnksCiAgICAgICAgc2FsX0ZhbHNlLAogICAgICAgIExJU1RfQVBQRU5ELAogICAgICAgIHBVc2VyRGF0YSk7CgogICAgU2V0RXhwYW5kZWRFbnRyeUJtcCgKICAgICAgICBwRW50cnksCiAgICAgICAgYklzRXhjbHVkZWQgPyBySWNvblByb3ZpZGVyLm1hSW1nUGFnZUV4Y2xIIDogckljb25Qcm92aWRlci5tYUltZ1BhZ2VILAogICAgICAgIEJNUF9DT0xPUl9ISUdIQ09OVFJBU1QgKTsKICAgIFNldENvbGxhcHNlZEVudHJ5Qm1wKAogICAgICAgIHBFbnRyeSwKICAgICAgICBiSXNFeGNsdWRlZCA/IHJJY29uUHJvdmlkZXIubWFJbWdQYWdlRXhjbEggOiBySWNvblByb3ZpZGVyLm1hSW1nUGFnZUgsCiAgICAgICAgQk1QX0NPTE9SX0hJR0hDT05UUkFTVCApOwoKICAgIFNkck9iakxpc3RJdGVyIGFJdGVyKAogICAgICAgIHJMaXN0LAogICAgICAgICFyTGlzdC5IYXNPYmplY3ROYXZpZ2F0aW9uT3JkZXIoKSAvKiB1c2UgbmF2aWdhdGlvbiBvcmRlciwgaWYgYXZhaWxhYmxlICovLAogICAgICAgIElNX0ZMQVQsCiAgICAgICAgc2FsX0ZhbHNlIC8qbm90IHJldmVyc2UqLyk7CgoJc2FsX0Jvb2wgIGJNYXJrZWQ9c2FsX0ZhbHNlOwoJaWYoYmlzSW5TZE5hdmlnYXRvcldpbikKCXsKCQlXaW5kb3cqIHBXaW5kb3c9TlVMTDsKCQlTZE5hdmlnYXRvcldpbiogcFNkTmF2aWdhdG9yV2luPU5VTEw7CgkJc2Q6OkRyYXdEb2NTaGVsbCogcFNkRHJhd0RvY1NoZWxsID0gTlVMTDsKCQlpZihwRW50cnkpCgkJCXBXaW5kb3c9KFdpbmRvdyopR2V0UGFyZW50KHBFbnRyeSk7CgkJaWYocFdpbmRvdykKCQkJcFNkTmF2aWdhdG9yV2luID0gKFNkTmF2aWdhdG9yV2luKilwV2luZG93OwoJCWlmKCBwU2ROYXZpZ2F0b3JXaW4gKQoJCQlwU2REcmF3RG9jU2hlbGwgPSBwU2ROYXZpZ2F0b3JXaW4tPkdldERyYXdEb2NTaGVsbChtcERvYyk7CgkJaWYocFNkRHJhd0RvY1NoZWxsKQoJCQliTWFya2VkPXBTZERyYXdEb2NTaGVsbC0+SXNNYXJrZWQocFNoYXBlKTsKCQlpZihwRW50cnkpCgkJewoJCQlpZihiTWFya2VkKQoJCQkJcEVudHJ5LT5TZXRNYXJrZWQoc2FsX1RydWUpOwoJCQllbHNlCgkJCQlwRW50cnktPlNldE1hcmtlZCggc2FsX0ZhbHNlICk7CgkJfQoJfQogICAgd2hpbGUoIGFJdGVyLklzTW9yZSgpICkKICAgIHsKICAgICAgICBTZHJPYmplY3QqIHBPYmogPSBhSXRlci5OZXh0KCk7CiAgICAgICAgT1NMX0FTU0VSVChwT2JqIT1OVUxMKTsKCiAgICAgICAgLy8gR2V0IHRoZSBzaGFwZSBuYW1lLgogICAgICAgIFN0cmluZyBhU3RyIChHZXRPYmplY3ROYW1lKCBwT2JqICkgKTsKCiAgICAgICAgaWYoIGFTdHIuTGVuKCkgKQogICAgICAgIHsKICAgICAgICAgICAgaWYoIHBPYmotPkdldE9iakludmVudG9yKCkgPT0gU2RySW52ZW50b3IgJiYgcE9iai0+R2V0T2JqSWRlbnRpZmllcigpID09IE9CSl9PTEUyICkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgU3ZMQm94RW50cnkqIHBOZXdFbnRyeSA9IEluc2VydEVudHJ5KCBhU3RyLCBtYUltZ09sZSwgbWFJbWdPbGUsIHBFbnRyeSwKICAgICAgICAgICAgICAgICAgICBzYWxfRmFsc2UsIExJU1RfQVBQRU5ELCBwT2JqKTsKCQkJCWlmKGJpc0luU2ROYXZpZ2F0b3JXaW4pCgkJCQl7CgkJCQkJV2luZG93KiBwV2luZG93PU5VTEw7CgkJCQkJU2ROYXZpZ2F0b3JXaW4qIHBTZE5hdmlnYXRvcldpbj1OVUxMOwoJCQkJCXNkOjpEcmF3RG9jU2hlbGwqIHBTZERyYXdEb2NTaGVsbCA9IE5VTEw7CgkJCQkJaWYocE5ld0VudHJ5KQoJCQkJCQlwV2luZG93PShXaW5kb3cqKUdldFBhcmVudChwTmV3RW50cnkpOwoJCQkJCWlmKHBXaW5kb3cpCgkJCQkJCXBTZE5hdmlnYXRvcldpbiA9IChTZE5hdmlnYXRvcldpbiopcFdpbmRvdzsKCQkJCQlpZiggcFNkTmF2aWdhdG9yV2luICkKCQkJCQkJcFNkRHJhd0RvY1NoZWxsID0gcFNkTmF2aWdhdG9yV2luLT5HZXREcmF3RG9jU2hlbGwobXBEb2MpOwoJCQkJCWlmKHBTZERyYXdEb2NTaGVsbCkKCQkJCQkJYk1hcmtlZD1wU2REcmF3RG9jU2hlbGwtPklzTWFya2VkKChTZHJPYmplY3QqKXBPYmopOwoJCQkJCWlmKHBOZXdFbnRyeSkKCQkJCQl7CgkJCQkJCWlmKGJNYXJrZWQpCgkJCQkJCQlwTmV3RW50cnktPlNldE1hcmtlZChzYWxfVHJ1ZSk7CgkJCQkJCWVsc2UKCQkJCQkJCXBOZXdFbnRyeS0+U2V0TWFya2VkKCBzYWxfRmFsc2UgKTsKCQkJCQl9CgkJCQl9CiAgICAgICAgICAgICAgICBTZXRFeHBhbmRlZEVudHJ5Qm1wKCBwTmV3RW50cnksIG1hSW1nT2xlSCwgQk1QX0NPTE9SX0hJR0hDT05UUkFTVCApOwogICAgICAgICAgICAgICAgU2V0Q29sbGFwc2VkRW50cnlCbXAoIHBOZXdFbnRyeSwgbWFJbWdPbGVILCBCTVBfQ09MT1JfSElHSENPTlRSQVNUICk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZiggcE9iai0+R2V0T2JqSW52ZW50b3IoKSA9PSBTZHJJbnZlbnRvciAmJiBwT2JqLT5HZXRPYmpJZGVudGlmaWVyKCkgPT0gT0JKX0dSQUYgKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBTdkxCb3hFbnRyeSogcE5ld0VudHJ5ID0gSW5zZXJ0RW50cnkoIGFTdHIsIG1hSW1nR3JhcGhpYywgbWFJbWdHcmFwaGljLCBwRW50cnksCiAgICAgICAgICAgICAgICAgICAgc2FsX0ZhbHNlLCBMSVNUX0FQUEVORCwgcE9iaiApOwoJCQkJaWYoYmlzSW5TZE5hdmlnYXRvcldpbikKCQkJCXsKCQkJCQlXaW5kb3cqIHBXaW5kb3c9TlVMTDsKCQkJCQlTZE5hdmlnYXRvcldpbiogcFNkTmF2aWdhdG9yV2luPU5VTEw7CgkJCQkJc2Q6OkRyYXdEb2NTaGVsbCogcFNkRHJhd0RvY1NoZWxsID0gTlVMTDsKCQkJCQlpZihwTmV3RW50cnkpCgkJCQkJCXBXaW5kb3c9KFdpbmRvdyopR2V0UGFyZW50KHBOZXdFbnRyeSk7CgkJCQkJaWYocFdpbmRvdykKCQkJCQkJcFNkTmF2aWdhdG9yV2luID0gKFNkTmF2aWdhdG9yV2luKilwV2luZG93OwoJCQkJCWlmKCBwU2ROYXZpZ2F0b3JXaW4gKQoJCQkJCQlwU2REcmF3RG9jU2hlbGwgPSBwU2ROYXZpZ2F0b3JXaW4tPkdldERyYXdEb2NTaGVsbChtcERvYyk7CgkJCQkJaWYocFNkRHJhd0RvY1NoZWxsKQoJCQkJCQliTWFya2VkPXBTZERyYXdEb2NTaGVsbC0+SXNNYXJrZWQoKFNkck9iamVjdCopcE9iaik7CgkJCQkJaWYocE5ld0VudHJ5KQoJCQkJCXsKCQkJCQkJaWYoYk1hcmtlZCkKCQkJCQkJewoJCQkJCQkJcE5ld0VudHJ5LT5TZXRNYXJrZWQoc2FsX1RydWUpOwoJCQkJCQl9CgkJCQkJCWVsc2UKCQkJCQkJewoJCQkJCQkJcE5ld0VudHJ5LT5TZXRNYXJrZWQoIHNhbF9GYWxzZSApOwoJCQkJCQl9CgkJCQkJfQoJCQkJfQogICAgICAgICAgICAgICAgU2V0RXhwYW5kZWRFbnRyeUJtcCggcE5ld0VudHJ5LCBtYUltZ0dyYXBoaWNILCBCTVBfQ09MT1JfSElHSENPTlRSQVNUICk7CiAgICAgICAgICAgICAgICBTZXRDb2xsYXBzZWRFbnRyeUJtcCggcE5ld0VudHJ5LCBtYUltZ0dyYXBoaWNILCBCTVBfQ09MT1JfSElHSENPTlRSQVNUICk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZiAocE9iai0+SXNHcm91cE9iamVjdCgpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBBZGRTaGFwZUxpc3QoCiAgICAgICAgICAgICAgICAgICAgKnBPYmotPkdldFN1Ykxpc3QoKSwKICAgICAgICAgICAgICAgICAgICBwT2JqLAogICAgICAgICAgICAgICAgICAgIGFTdHIsCiAgICAgICAgICAgICAgICAgICAgZmFsc2UsCiAgICAgICAgICAgICAgICAgICAgcEVudHJ5LAogICAgICAgICAgICAgICAgICAgIHJJY29uUHJvdmlkZXIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgU3ZMQm94RW50cnkqIHBOZXdFbnRyeSA9IEluc2VydEVudHJ5KCBhU3RyLCBySWNvblByb3ZpZGVyLm1hSW1nT2JqZWN0cywgckljb25Qcm92aWRlci5tYUltZ09iamVjdHMsIHBFbnRyeSwKICAgICAgICAgICAgICAgICAgICBzYWxfRmFsc2UsIExJU1RfQVBQRU5ELCBwT2JqICk7CgkJCQlpZihiaXNJblNkTmF2aWdhdG9yV2luKQoJCQkJewoJCQkJCVdpbmRvdyogcFdpbmRvdz1OVUxMOwoJCQkJCVNkTmF2aWdhdG9yV2luKiBwU2ROYXZpZ2F0b3JXaW49TlVMTDsKCQkJCQlzZDo6RHJhd0RvY1NoZWxsKiBwU2REcmF3RG9jU2hlbGwgPSBOVUxMOwoJCQkJCWlmKHBOZXdFbnRyeSkKCQkJCQkJcFdpbmRvdz0oV2luZG93KilHZXRQYXJlbnQocE5ld0VudHJ5KTsKCQkJCQlpZihwV2luZG93KQoJCQkJCQlwU2ROYXZpZ2F0b3JXaW4gPSAoU2ROYXZpZ2F0b3JXaW4qKXBXaW5kb3c7CgkJCQkJaWYoIHBTZE5hdmlnYXRvcldpbiApCgkJCQkJCXBTZERyYXdEb2NTaGVsbCA9IHBTZE5hdmlnYXRvcldpbi0+R2V0RHJhd0RvY1NoZWxsKG1wRG9jKTsKCQkJCQlpZihwU2REcmF3RG9jU2hlbGwpCgkJCQkJCWJNYXJrZWQ9cFNkRHJhd0RvY1NoZWxsLT5Jc01hcmtlZCgoU2RyT2JqZWN0KilwT2JqKTsKCQkJCQlpZihwTmV3RW50cnkpCgkJCQkJewoJCQkJCQlpZihiTWFya2VkKQoJCQkJCQl7CgkJCQkJCQlwTmV3RW50cnktPlNldE1hcmtlZChzYWxfVHJ1ZSk7CgkJCQkJCX0KCQkJCQkJZWxzZQoJCQkJCQl7CgkJCQkJCQlwTmV3RW50cnktPlNldE1hcmtlZCggc2FsX0ZhbHNlICk7CgkJCQkJCX0KCQkJCQl9CgkJCQl9CiAgICAgICAgICAgICAgICBTZXRFeHBhbmRlZEVudHJ5Qm1wKCBwTmV3RW50cnksIHJJY29uUHJvdmlkZXIubWFJbWdPYmplY3RzSCwgQk1QX0NPTE9SX0hJR0hDT05UUkFTVCApOwogICAgICAgICAgICAgICAgU2V0Q29sbGFwc2VkRW50cnlCbXAoIHBOZXdFbnRyeSwgckljb25Qcm92aWRlci5tYUltZ09iamVjdHNILCBCTVBfQ09MT1JfSElHSENPTlRSQVNUICk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgaWYoIHBFbnRyeS0+SGFzQ2hpbGRzKCkgKQogICAgewogICAgICAgIFNldEV4cGFuZGVkRW50cnlCbXAoCiAgICAgICAgICAgIHBFbnRyeSwKICAgICAgICAgICAgYklzRXhjbHVkZWQgPyBySWNvblByb3ZpZGVyLm1hSW1nUGFnZU9ianNFeGNsIDogckljb25Qcm92aWRlci5tYUltZ1BhZ2VPYmpzKTsKICAgICAgICBTZXRDb2xsYXBzZWRFbnRyeUJtcCgKICAgICAgICAgICAgcEVudHJ5LAogICAgICAgICAgICBiSXNFeGNsdWRlZCA/IHJJY29uUHJvdmlkZXIubWFJbWdQYWdlT2Jqc0V4Y2wgOiBySWNvblByb3ZpZGVyLm1hSW1nUGFnZU9ianMpOwogICAgICAgIFNldEV4cGFuZGVkRW50cnlCbXAoCiAgICAgICAgICAgIHBFbnRyeSwKICAgICAgICAgICAgYklzRXhjbHVkZWQgPyBySWNvblByb3ZpZGVyLm1hSW1nUGFnZU9ianNFeGNsSCA6IHJJY29uUHJvdmlkZXIubWFJbWdQYWdlT2Jqc0gsCiAgICAgICAgICAgIEJNUF9DT0xPUl9ISUdIQ09OVFJBU1QpOwogICAgICAgIFNldENvbGxhcHNlZEVudHJ5Qm1wKAogICAgICAgICAgICBwRW50cnksCiAgICAgICAgICAgIGJJc0V4Y2x1ZGVkID8gckljb25Qcm92aWRlci5tYUltZ1BhZ2VPYmpzRXhjbEggOiBySWNvblByb3ZpZGVyLm1hSW1nUGFnZU9ianNILAogICAgICAgICAgICBCTVBfQ09MT1JfSElHSENPTlRSQVNUKTsKCQlpZiAobWJTYXZlVHJlZUl0ZW1TdGF0ZSkKCQl7CgkJCXZlY3RvcjxTdHJpbmc+OjogaXRlcmF0b3IgaXRlU3RhcnQgPSBtYVRyZWVJdGVtLmJlZ2luKCk7CgkJCXdoaWxlIChpdGVTdGFydCAhPSBtYVRyZWVJdGVtLmVuZCgpKQoJCQl7CgkJCQlTdHJpbmcgc3RyRW50cnkgPSBHZXRFbnRyeVRleHQocEVudHJ5KTsKCQkJCWlmICgqaXRlU3RhcnQgPT0gc3RyRW50cnkpCgkJCQl7CgkJCQkJRXhwYW5kKCBwRW50cnkgKTsKCQkJCQlicmVhazsKCQkJCX0KCQkJCSsraXRlU3RhcnQ7CgkJCX0KCQl9CgkJZWxzZQoJCQlFeHBhbmQoIHBFbnRyeSApOwogICAgfQp9CgoKCgp2b2lkIFNkUGFnZU9ianNUTEI6OlNldFNob3dBbGxTaGFwZXMgKAogICAgY29uc3QgYm9vbCBiU2hvd0FsbFNoYXBlcywKICAgIGNvbnN0IGJvb2wgYkZpbGxMaXN0KQp7CiAgICBtYlNob3dBbGxTaGFwZXMgPSBiU2hvd0FsbFNoYXBlczsKICAgIGlmIChiRmlsbExpc3QpCiAgICB7CiAgICAgICAgaWYgKG1wTWVkaXVtID09IE5VTEwpCiAgICAgICAgICAgIEZpbGwobXBEb2MsIG1iU2hvd0FsbFBhZ2VzLCBtYURvY05hbWUpOwogICAgICAgIGVsc2UKICAgICAgICAgICAgRmlsbChtcERvYywgbXBNZWRpdW0sIG1hRG9jTmFtZSk7CiAgICB9Cn0KCgoKCmJvb2wgU2RQYWdlT2Jqc1RMQjo6R2V0U2hvd0FsbFNoYXBlcyAodm9pZCkgY29uc3QKewogICAgcmV0dXJuIG1iU2hvd0FsbFNoYXBlczsKfQoKCgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKfCoKfCogUHJ1ZWZ0LCBvYiBkaWUgU2VpdGVuIChQS19TVEFOREFSRCkgdW5kIGRpZSBkYXJhdWYgYmVmaW5kbGljaGVuIE9iamVrdGUKfCogZGVzIERvY3MgdW5kIGRlciBUcmVlTEIgaWRlbnRpc2NoIHNpbmQuCnwqIFdpcmQgZWluIERvYyB1ZWJlcmdlYmVuLCB3aXJkIGRpZXNlcyB6dW0gYWt0dWVsbGVtIERvYyAoV2ljaHRpZyBiZWkKfCogbWVocmVyZW4gRG9jdW1lbnRlbikuCnwqClwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgpzYWxfQm9vbCBTZFBhZ2VPYmpzVExCOjpJc0VxdWFsVG9Eb2MoIGNvbnN0IFNkRHJhd0RvY3VtZW50KiBwSW5Eb2MgKQp7CglpZiggcEluRG9jICkKCQltcERvYyA9IHBJbkRvYzsKCglpZiggIW1wRG9jICkKCQlyZXR1cm4oIHNhbF9GYWxzZSApOwoKCVNkck9iamVjdCoJIHBPYmogPSBOVUxMOwoJU2RQYWdlKiAJIHBQYWdlID0gTlVMTDsKCVN2TEJveEVudHJ5KiBwRW50cnkgPSBGaXJzdCgpOwoJU3RyaW5nCQkgYU5hbWU7CgoJLy8gQWxsZSBQYWdlcyBpbmNsLiBPYmpla3RlIHZlcmdsZWljaGVuCglzYWxfdUludDE2IG5QYWdlID0gMDsKCWNvbnN0IHNhbF91SW50MTYgbk1heFBhZ2VzID0gbXBEb2MtPkdldFBhZ2VDb3VudCgpOwoKCXdoaWxlKCBuUGFnZSA8IG5NYXhQYWdlcyApCgl7CgkJcFBhZ2UgPSAoU2RQYWdlKikgbXBEb2MtPkdldFBhZ2UoIG5QYWdlICk7CgkJaWYoIHBQYWdlLT5HZXRQYWdlS2luZCgpID09IFBLX1NUQU5EQVJEICkKCQl7CgkJCWlmKCAhcEVudHJ5ICkKCQkJCXJldHVybiggc2FsX0ZhbHNlICk7CgkJCWFOYW1lID0gR2V0RW50cnlUZXh0KCBwRW50cnkgKTsKCgkJCWlmKCBwUGFnZS0+R2V0TmFtZSgpICE9IGFOYW1lICkKCQkJCXJldHVybiggc2FsX0ZhbHNlICk7CgoJCQlwRW50cnkgPSBOZXh0KCBwRW50cnkgKTsKCgkJCVNkck9iakxpc3RJdGVyIGFJdGVyKAogICAgICAgICAgICAgICAgKnBQYWdlLAogICAgICAgICAgICAgICAgIXBQYWdlLT5IYXNPYmplY3ROYXZpZ2F0aW9uT3JkZXIoKSAvKiB1c2UgbmF2aWdhdGlvbiBvcmRlciwgaWYgYXZhaWxhYmxlICovLAogICAgICAgICAgICAgICAgSU1fREVFUFdJVEhHUk9VUFMgKTsKCgkJCXdoaWxlKCBhSXRlci5Jc01vcmUoKSApCgkJCXsKCQkJCXBPYmogPSBhSXRlci5OZXh0KCk7CgogICAgICAgICAgICAgICAgY29uc3QgU3RyaW5nIGFPYmplY3ROYW1lKCBHZXRPYmplY3ROYW1lKCBwT2JqICkgKTsKCgkJCQlpZiggYU9iamVjdE5hbWUuTGVuKCkgKQoJCQkJewoJCQkJCWlmKCAhcEVudHJ5ICkKCQkJCQkJcmV0dXJuKCBzYWxfRmFsc2UgKTsKCiAgICAgICAgICAgICAgICAJYU5hbWUgPSBHZXRFbnRyeVRleHQoIHBFbnRyeSApOwoKCQkJCQlpZiggYU9iamVjdE5hbWUgIT0gYU5hbWUgKQoJCQkJCQlyZXR1cm4oIHNhbF9GYWxzZSApOwoKCQkJCQlwRW50cnkgPSBOZXh0KCBwRW50cnkgKTsKCQkJCX0KCQkJfQoJCX0KCQluUGFnZSsrOwoJfQoJLy8gV2VubiBub2NoIEVpbnRyYWVnZSBpbiBkZXIgTGlzdGJveCB2b3JoYW5kZW4gc2luZCwgd3VyZGVuCgkvLyBPYmpla3RlIChtaXQgTmFtZW4pIG9kZXIgU2VpdGVuIGdlbG9lc2NodAoJcmV0dXJuKCAhcEVudHJ5ICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCnwqCnwqIFNlbGVjdGllcnRlbiBTdHJpbmcgenVydWVja2dlYmVuCnwqClwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgpTdHJpbmcgU2RQYWdlT2Jqc1RMQjo6R2V0U2VsZWN0RW50cnkoKQp7CglyZXR1cm4oIEdldEVudHJ5VGV4dCggR2V0Q3VyRW50cnkoKSApICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCnwqCnwqIFNlbGVrdGllcnRlIEVpbnRyYWdlIHp1cnVlY2tnZWJlbgp8KiBuRGVwdGggPT0gMCAtPiBTZWl0ZW4KfCogbkRlcHRoID09IDEgLT4gT2JqZWt0ZQp8KgpcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKTGlzdCogU2RQYWdlT2Jqc1RMQjo6R2V0U2VsZWN0RW50cnlMaXN0KCBzYWxfdUludDE2IG5EZXB0aCApCnsKCUxpc3QqCQkgcExpc3QJPSBOVUxMOwoJU3ZMQm94RW50cnkqIHBFbnRyeSA9IEZpcnN0U2VsZWN0ZWQoKTsKCgl3aGlsZSggcEVudHJ5ICkKCXsKCQlzYWxfdUludDE2IG5MaXN0RGVwdGggPSBHZXRNb2RlbCgpLT5HZXREZXB0aCggcEVudHJ5ICk7CgkJaWYoIG5MaXN0RGVwdGggPT0gbkRlcHRoICkKCQl7CgkJCWlmKCAhcExpc3QgKQoJCQkJcExpc3QgPSBuZXcgTGlzdCgpOwoKCQkJY29uc3QgU3RyaW5nIGFFbnRyeVRleHQoIEdldEVudHJ5VGV4dCggcEVudHJ5ICkgKTsKCQkJcExpc3QtPkluc2VydCggbmV3IFN0cmluZyggYUVudHJ5VGV4dCApLCBMSVNUX0FQUEVORCApOwoJCX0KCQlwRW50cnkgPSBOZXh0U2VsZWN0ZWQoIHBFbnRyeSApOwoJfQoKCXJldHVybiggcExpc3QgKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKfCoKfCogRWludHJhZWdlIHdlcmRlbiBlcnN0IGF1ZiBBbmZvcmRlcnVuZyAoRG9wcGVsa2xpY2spIGVpbmdlZnVlZ3QKfCoKXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCnZvaWQgU2RQYWdlT2Jqc1RMQjo6UmVxdWVzdGluZ0NoaWxkcyggU3ZMQm94RW50cnkqIHBGaWxlRW50cnkgKQp7CglpZiggIXBGaWxlRW50cnktPkhhc0NoaWxkcygpICkKCXsKCQlpZiggR2V0Qm9va21hcmtEb2MoKSApCgkJewoJCQlTZHJPYmplY3QqCSBwT2JqID0gTlVMTDsKCQkJU2RQYWdlKiAJIHBQYWdlID0gTlVMTDsKCQkJU3ZMQm94RW50cnkqIHBQYWdlRW50cnkgPSBOVUxMOwoKCQkJSW1hZ2UgYUltZ1BhZ2U9SW1hZ2UoIEJpdG1hcEV4KCBTZFJlc0lkKCBCTVBfUEFHRSApICkgKTsKCQkJSW1hZ2UgYUltZ1BhZ2VPYmpzPUltYWdlKCBCaXRtYXBFeCggU2RSZXNJZCggQk1QX1BBR0VPQkpTICkgKSApOwoJCQlJbWFnZSBhSW1nT2JqZWN0cz1JbWFnZSggQml0bWFwRXgoIFNkUmVzSWQoIEJNUF9PQkpFQ1RTICkgKSApOwoJCQlJbWFnZSBhSW1nUGFnZUg9SW1hZ2UoIEJpdG1hcEV4KCBTZFJlc0lkKCBCTVBfUEFHRV9IICkgKSApOwoJCQlJbWFnZSBhSW1nUGFnZU9ianNIPUltYWdlKCBCaXRtYXBFeCggU2RSZXNJZCggQk1QX1BBR0VPQkpTX0ggKSApICk7CgkJCUltYWdlIGFJbWdPYmplY3RzSD1JbWFnZSggQml0bWFwRXgoIFNkUmVzSWQoIEJNUF9PQkpFQ1RTX0ggKSApICk7CgoJCQkvLyBkb2N1bWVudCBuYW1lIGFscmVhZHkgaW5zZXJ0ZWQKCgkJCS8vIG9ubHkgaW5zZXJ0IGFsbCAibm9ybWFsIiA/IHNsaWRlcyB3aXRoIG9iamVjdHMKCQkJc2FsX3VJbnQxNiBuUGFnZSA9IDA7CgkJCWNvbnN0IHNhbF91SW50MTYgbk1heFBhZ2VzID0gbXBCb29rbWFya0RvYy0+R2V0UGFnZUNvdW50KCk7CgoJCQl3aGlsZSggblBhZ2UgPCBuTWF4UGFnZXMgKQoJCQl7CgkJCQlwUGFnZSA9IChTZFBhZ2UqKSBtcEJvb2ttYXJrRG9jLT5HZXRQYWdlKCBuUGFnZSApOwoJCQkJaWYoIHBQYWdlLT5HZXRQYWdlS2luZCgpID09IFBLX1NUQU5EQVJEICkKCQkJCXsKCQkJCQlwUGFnZUVudHJ5ID0gSW5zZXJ0RW50cnkoIHBQYWdlLT5HZXROYW1lKCksCgkJCQkJICAgICAgICAgICAgICAgICAgICAgICAgICBhSW1nUGFnZSwKCQkJCQkgICAgICAgICAgICAgICAgICAgICAgICAgIGFJbWdQYWdlLAoJCQkJCSAgICAgICAgICAgICAgICAgICAgICAgICAgcEZpbGVFbnRyeSwKCQkJCQkJCSAgICAgICAgICAgICAgICAgIHNhbF9GYWxzZSwKCQkJCQkJCQkgICAgICAgICAgICAgIExJU1RfQVBQRU5ELAoJCQkJCQkJCSAgICAgICAgICAgICAgcmVpbnRlcnByZXRfY2FzdDwgdm9pZCogPiggMSApICk7CgoJCQkJCVNldEV4cGFuZGVkRW50cnlCbXAoIHBQYWdlRW50cnksIGFJbWdQYWdlSCwgQk1QX0NPTE9SX0hJR0hDT05UUkFTVCApOwoJCQkJCVNldENvbGxhcHNlZEVudHJ5Qm1wKCBwUGFnZUVudHJ5LCBhSW1nUGFnZUgsIEJNUF9DT0xPUl9ISUdIQ09OVFJBU1QgKTsKCgkJCQkJU2RyT2JqTGlzdEl0ZXIgYUl0ZXIoICpwUGFnZSwgSU1fREVFUFdJVEhHUk9VUFMgKTsKCgkJCQkJd2hpbGUoIGFJdGVyLklzTW9yZSgpICkKCQkJCQl7CgkJCQkJCXBPYmogPSBhSXRlci5OZXh0KCk7CgkJCQkJCVN0cmluZyBhU3RyKCBHZXRPYmplY3ROYW1lKCBwT2JqICkgKTsKCQkJCQkJaWYoIGFTdHIuTGVuKCkgKQoJCQkJCQl7CgkJCQkJCQlpZiggcE9iai0+R2V0T2JqSW52ZW50b3IoKSA9PSBTZHJJbnZlbnRvciAmJiBwT2JqLT5HZXRPYmpJZGVudGlmaWVyKCkgPT0gT0JKX09MRTIgKQoJCQkJCQkJewoJCQkJCQkJCVN2TEJveEVudHJ5KiBwTmV3RW50cnkgPSBJbnNlcnRFbnRyeShhU3RyLCBtYUltZ09sZSwgbWFJbWdPbGUsIHBQYWdlRW50cnkpOwoKCgkJCQkJCQkJU2V0RXhwYW5kZWRFbnRyeUJtcCggcE5ld0VudHJ5LCBtYUltZ09sZUgsIEJNUF9DT0xPUl9ISUdIQ09OVFJBU1QgKTsKCQkJCQkJCQlTZXRDb2xsYXBzZWRFbnRyeUJtcCggcE5ld0VudHJ5LCBtYUltZ09sZUgsIEJNUF9DT0xPUl9ISUdIQ09OVFJBU1QgKTsKCQkJCQkJCX0KCQkJCQkJCWVsc2UgaWYoIHBPYmotPkdldE9iakludmVudG9yKCkgPT0gU2RySW52ZW50b3IgJiYgcE9iai0+R2V0T2JqSWRlbnRpZmllcigpID09IE9CSl9HUkFGICkKCQkJCQkJCXsKCQkJCQkJCQlTdkxCb3hFbnRyeSogcE5ld0VudHJ5ID0gSW5zZXJ0RW50cnkoYVN0ciwgbWFJbWdHcmFwaGljLCBtYUltZ0dyYXBoaWMsIHBQYWdlRW50cnkpOwoKCQkJCQkJCQlTZXRFeHBhbmRlZEVudHJ5Qm1wKCBwTmV3RW50cnksIG1hSW1nR3JhcGhpY0gsIEJNUF9DT0xPUl9ISUdIQ09OVFJBU1QgKTsKCQkJCQkJCQlTZXRDb2xsYXBzZWRFbnRyeUJtcCggcE5ld0VudHJ5LCBtYUltZ0dyYXBoaWNILCBCTVBfQ09MT1JfSElHSENPTlRSQVNUICk7CgkJCQkJCQl9CgkJCQkJCQllbHNlCgkJCQkJCQl7CgkJCQkJCQkJU3ZMQm94RW50cnkqIHBOZXdFbnRyeSA9IEluc2VydEVudHJ5KGFTdHIsIGFJbWdPYmplY3RzLCBhSW1nT2JqZWN0cywgcFBhZ2VFbnRyeSk7CgoJCQkJCQkJCVNldEV4cGFuZGVkRW50cnlCbXAoIHBOZXdFbnRyeSwgYUltZ09iamVjdHNILCBCTVBfQ09MT1JfSElHSENPTlRSQVNUICk7CgkJCQkJCQkJU2V0Q29sbGFwc2VkRW50cnlCbXAoIHBOZXdFbnRyeSwgYUltZ09iamVjdHNILCBCTVBfQ09MT1JfSElHSENPTlRSQVNUICk7CgkJCQkJCQl9CgkJCQkJCX0KCQkJCQl9CgkJCQkJaWYoIHBQYWdlRW50cnktPkhhc0NoaWxkcygpICkKCQkJCQl7CgkJCQkJCVNldEV4cGFuZGVkRW50cnlCbXAoIHBQYWdlRW50cnksIGFJbWdQYWdlT2JqcyApOwoJCQkJCQlTZXRDb2xsYXBzZWRFbnRyeUJtcCggcFBhZ2VFbnRyeSwgYUltZ1BhZ2VPYmpzICk7CgkJCQkJCVNldEV4cGFuZGVkRW50cnlCbXAoIHBQYWdlRW50cnksIGFJbWdQYWdlT2Jqc0gsIEJNUF9DT0xPUl9ISUdIQ09OVFJBU1QgKTsKCQkJCQkJU2V0Q29sbGFwc2VkRW50cnlCbXAoIHBQYWdlRW50cnksIGFJbWdQYWdlT2Jqc0gsIEJNUF9DT0xPUl9ISUdIQ09OVFJBU1QgKTsKCQkJCQl9CgkJCQl9CgkJCQluUGFnZSsrOwoJCQl9CgkJfQoJfQoJZWxzZQoJCVN2VHJlZUxpc3RCb3g6OlJlcXVlc3RpbmdDaGlsZHMoIHBGaWxlRW50cnkgKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKfCoKfCoJUHJ1ZWZ0LCBvYiBlcyBzaWNoIHVtIGVpbmUgRHJhdy1EYXRlaSBoYW5kZWx0IHVuZCBvZWZmbmV0IGFuaGFuZCBkZXMKfCoJdWViZXJnZWJlbmVuIERvY3MgZGFzIEJvb2ttYXJrRG9jCnwqClwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgpTZERyYXdEb2N1bWVudCogU2RQYWdlT2Jqc1RMQjo6R2V0Qm9va21hcmtEb2MoU2Z4TWVkaXVtKiBwTWVkKQp7CglpZiAoCiAgICAgICAhbXBCb29rbWFya0RvYyB8fAoJCSAocE1lZCAmJiAoIW1wT3duTWVkaXVtIHx8IG1wT3duTWVkaXVtLT5HZXROYW1lKCkgIT0gcE1lZC0+R2V0TmFtZSgpKSkKICAgICAgKQoJewogICAgICAgIC8vIGNyZWF0ZSBhIG5ldyBCb29rbWFya0RvYyBpZiBub3cgb25lIGV4aXN0cyBvciBpZiBhIG5ldyBNZWRpdW0gaXMgcHJvdmlkZWQKICAgICAgICBpZiAobXBPd25NZWRpdW0gIT0gcE1lZCkKCQl7CgkJCUNsb3NlQm9va21hcmtEb2MoKTsKCQl9CgoJCWlmIChwTWVkKQoJCXsKICAgICAgICAgICAgLy8gaXQgbG9va3MgdGhhdCBpdCBpcyB1bmRlZmluZWQgaWYgYSBNZWRpdW0gd2FzIHNldCBieSBGaWxsKCkgYWxyZWFkeQogICAgICAgICAgICBEQkdfQVNTRVJUKCAhbXBNZWRpdW0sICJTZnhNZWRpdW0gY29uZnVzaW9uISIgKTsKICAgICAgICAgICAgZGVsZXRlIG1wTWVkaXVtOwogICAgICAgICAgICBtcE1lZGl1bSA9IE5VTEw7CgogICAgICAgICAgICAvLyB0YWtlIG92ZXIgdGhpcyBNZWRpdW0gKGN1cnJlbnRseSB1c2VkIG9ubHkgYmUgTmF2aWdhdG9yKQoJCQltcE93bk1lZGl1bSA9IHBNZWQ7CiAgICAgICAgfQoKICAgICAgICBEQkdfQVNTRVJUKCBtcE1lZGl1bSB8fCBwTWVkLCAiTm8gU2Z4TWVkaXVtIHByb3ZpZGVkISIgKTsKCiAgICAgICAgaWYoIHBNZWQgKQogICAgICAgIHsKICAgICAgICAgICAgLy8gaW4gdGhpcyBtb2RlIHRoZSBkb2N1bWVudCBpcyBhbHNvIG93bmVkIGFuZCBjb250cm9sbGVkIGJ5IHRoaXMgaW5zdGFuY2UKICAgICAgICAgICAgbXhCb29rbWFya0RvY1NoUmVmID0gbmV3IDo6c2Q6OkRyYXdEb2NTaGVsbChTRlhfQ1JFQVRFX01PREVfU1RBTkRBUkQsIHNhbF9UcnVlKTsKICAgICAgICAgICAgaWYgKG14Qm9va21hcmtEb2NTaFJlZi0+RG9Mb2FkKHBNZWQpKQogICAgICAgICAgICAgICAgbXBCb29rbWFya0RvYyA9IG14Qm9va21hcmtEb2NTaFJlZi0+R2V0RG9jKCk7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIG1wQm9va21hcmtEb2MgPSBOVUxMOwogICAgICAgIH0KICAgICAgICBlbHNlIGlmICggbXBNZWRpdW0gKQogICAgICAgICAgICAvLyBpbiB0aGlzIG1vZGUgdGhlIGRvY3VtZW50IGlzIG93bmVkIGFuZCBjb250cm9sbGVkIGJ5IHRoZSBTZERyYXdEb2N1bWVudAogICAgICAgICAgICAvLyBpdCBjYW4gYmUgcmVsZWFzZWQgYnkgY2FsbGluZyB0aGUgY29ycmVzcG9uZGluZyBDbG9zZUJvb2ttYXJrRG9jIG1ldGhvZAogICAgICAgICAgICAvLyBzdWNjZXNzZnVsIGNyZWF0aW9uIG9mIGEgZG9jdW1lbnQgbWFrZXMgdGhpcyB0aGUgb3duZXIgb2YgdGhlIG1lZGl1bQogICAgICAgICAgICBtcEJvb2ttYXJrRG9jID0gKChTZERyYXdEb2N1bWVudCopIG1wRG9jKS0+T3BlbkJvb2ttYXJrRG9jKCptcE1lZGl1bSk7CgogICAgICAgIGlmICggIW1wQm9va21hcmtEb2MgKQoJCXsKCQkJRXJyb3JCb3ggYUVycm9yQm94KCB0aGlzLCBXQl9PSywgU3RyaW5nKCBTZFJlc0lkKCBTVFJfUkVBRF9EQVRBX0VSUk9SICkgKSApOwoJCQlhRXJyb3JCb3guRXhlY3V0ZSgpOwogICAgICAgICAgICBtcE1lZGl1bSA9IDA7IC8vT24gZmFpbHVyZSB0aGUgU2Z4TWVkaXVtIGlzIGludmFsaWQKCQl9Cgl9CgoJcmV0dXJuKCBtcEJvb2ttYXJrRG9jICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCnwqCnwqIEJvb2ttYXJrLURva3VtZW50IHNjaGxpZeFlbiB1bmQgbG9lc2NoZW4KfCoKXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCnZvaWQgU2RQYWdlT2Jqc1RMQjo6Q2xvc2VCb29rbWFya0RvYygpCnsKCWlmIChteEJvb2ttYXJrRG9jU2hSZWYuSXMoKSkKCXsKCQlteEJvb2ttYXJrRG9jU2hSZWYtPkRvQ2xvc2UoKTsKICAgICAgICBteEJvb2ttYXJrRG9jU2hSZWYuQ2xlYXIoKTsKCiAgICAgICAgLy8gTWVkaXVtIGlzIG93bmVkIGJ5IGRvY3VtZW50LCBzbyBpdCdzIGRlc3Ryb3llZCBhbHJlYWR5CiAgICAgICAgbXBPd25NZWRpdW0gPSAwOwoJfQogICAgZWxzZSBpZiAoIG1wQm9va21hcmtEb2MgKQoJewogICAgICAgIERCR19BU1NFUlQoICFtcE93bk1lZGl1bSwgIlNmeE1lZGl1bSBjb25mdXNpb24hIiApOwogICAgICAgIGlmICggbXBEb2MgKQogICAgICAgIHsKICAgICAgICAgICAgLy8gVGhlIGRvY3VtZW50IG93bnMgdGhlIE1lZGl1bSwgc28gdGhlIE1lZGl1bSB3aWxsIGJlIGludmFsaWQgYWZ0ZXIgY2xvc2luZyB0aGUgZG9jdW1lbnQKCQkJKChTZERyYXdEb2N1bWVudCopIG1wRG9jKS0+Q2xvc2VCb29rbWFya0RvYygpOwogICAgICAgICAgICBtcE1lZGl1bSA9IDA7CiAgICAgICAgfQoJfQogICAgZWxzZQogICAgewogICAgICAgIC8vIHBlcmhhcHMgbXBPd25NZWRpdW0gcHJvdmlkZWQsIGJ1dCBubyBzdWNjZXNzZnVsIGNyZWF0aW9uIG9mIEJvb2ttYXJrRG9jCiAgICAgICAgZGVsZXRlIG1wT3duTWVkaXVtOwogICAgICAgIG1wT3duTWVkaXVtID0gTlVMTDsKICAgIH0KCgltcEJvb2ttYXJrRG9jID0gTlVMTDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKfCoKfCoKfCoKXCoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCnZvaWQgU2RQYWdlT2Jqc1RMQjo6U2VsZWN0SGRsKCkKewoJU3ZMQm94RW50cnkqIHBFbnRyeSA9IEZpcnN0U2VsZWN0ZWQoKTsKCgltYkxpbmthYmxlU2VsZWN0ZWQgPSBzYWxfVHJ1ZTsKCgl3aGlsZSggcEVudHJ5ICYmIG1iTGlua2FibGVTZWxlY3RlZCApCgl7CgkgICAgaWYoIE5VTEwgPT0gcEVudHJ5LT5HZXRVc2VyRGF0YSgpICkKCSAgICAgICAgbWJMaW5rYWJsZVNlbGVjdGVkID0gc2FsX0ZhbHNlOwoKCQlwRW50cnkgPSBOZXh0U2VsZWN0ZWQoIHBFbnRyeSApOwoJfQoKCVN2VHJlZUxpc3RCb3g6OlNlbGVjdEhkbCgpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgp8Kgp8KiBVZWJlcmxhZWR0IFJFVFVSTiBtaXQgZGVyIEZ1bmt0aW9uc3dlaXNlIHZvbiBEb3VibGVDbGljawp8KgpcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKdm9pZCBTZFBhZ2VPYmpzVExCOjpLZXlJbnB1dCggY29uc3QgS2V5RXZlbnQmIHJLRXZ0ICkKewoJaWYoIHJLRXZ0LkdldEtleUNvZGUoKS5HZXRDb2RlKCkgPT0gS0VZX1JFVFVSTiApCgl7CgkJLy8gQXVza29tbWVudGllcnRlciBDb2RlIGF1cyBzdnRvb2xzL3NvdXJjZS9jb250bnIvc3ZpbXBib3guY3h4CgkJU3ZMQm94RW50cnkqIHBDdXJzb3IgPSBHZXRDdXJFbnRyeSgpOwoJCWlmKCBwQ3Vyc29yLT5IYXNDaGlsZHMoKSB8fCBwQ3Vyc29yLT5IYXNDaGlsZHNPbkRlbWFuZCgpICkKCQl7CgkJCWlmKCBJc0V4cGFuZGVkKCBwQ3Vyc29yICkgKQoJCQkJQ29sbGFwc2UoIHBDdXJzb3IgKTsKCQkJZWxzZQoJCQkJRXhwYW5kKCBwQ3Vyc29yICk7CgkJfQoKCQlEb3VibGVDbGlja0hkbCgpOwoJfQoJZWxzZSBpZiAocktFdnQuR2V0S2V5Q29kZSgpLkdldENvZGUoKSA9PSBLRVlfU1BBQ0UpCgl7CgkgICBpZihiaXNJblNkTmF2aWdhdG9yV2luKQoJICAgewoJCSAgIHNhbF9Cb29sIGJNYXJrZWQ9c2FsX0ZhbHNlOwoJCSAgIFN2TEJveEVudHJ5KiBwTmV3RW50cnkgPSBHZXRDdXJFbnRyeSgpOwoJCSAgIGlmKCBHZXRQYXJlbnQocE5ld0VudHJ5KSA9PSBOVUxMICkKCQkJICAgcmV0dXJuOwoJCSAgIFN0cmluZyAgYVN0cj1HZXRTZWxlY3RFbnRyeSgpOwoJCSAgIFdpbmRvdyogcFdpbmRvdz1OVUxMOwoJCSAgIFNkTmF2aWdhdG9yV2luKiBwU2ROYXZpZ2F0b3JXaW49TlVMTDsKCQkgICBzZDo6RHJhd0RvY1NoZWxsKiBwU2REcmF3RG9jU2hlbGwgPSBOVUxMOwoJCSAgIGlmKHBOZXdFbnRyeSkKCQkJICAgcFdpbmRvdz0oV2luZG93KilHZXRQYXJlbnQocE5ld0VudHJ5KTsKCQkgICBpZihwV2luZG93KQoJCQkgICBwU2ROYXZpZ2F0b3JXaW4gPSAoU2ROYXZpZ2F0b3JXaW4qKXBXaW5kb3c7CgkJICAgaWYoIHBTZE5hdmlnYXRvcldpbiApCgkJCSAgIHBTZERyYXdEb2NTaGVsbCA9IHBTZE5hdmlnYXRvcldpbi0+R2V0RHJhd0RvY1NoZWxsKG1wRG9jKTsKCQkgICBpZihwU2REcmF3RG9jU2hlbGwpCgkJICAgewoJCQkgICBwU2REcmF3RG9jU2hlbGwtPkdvdG9UcmVlQm9va21hcmsoYVN0cik7CgkJCSAgIGJNYXJrZWQ9cFNkRHJhd0RvY1NoZWxsLT5HZXRPYmplY3RJc21hcmtlZChhU3RyKTsKCQkgICB9CgkJICAgLy9SZW1vdmVkIGJ5IHlhbmp1biBmb3Igc3ltMl82Mzg1CgkJICAgLy9UaGUgc3ltcGhvbnkyLjAgY2FuIHN1cHBvcnQgbW9ybiB0aGFuIG9uZSBsZXZlbCB0cmVlIGxpc3QsIGFsc28gc3VwcG9ydCB0byBzZWxlY3QgdG93IG9yIG1vcmUgaXRlbXMgaW4gZGlmZmVyZW50IGxldmVsLgoJCSAgIC8qCgkJICAgU3ZMQm94RW50cnkqIHBCZWdpbkVudHJ5ID0gRmlyc3QoKTsKCQkgICBpZiggcEJlZ2luRW50cnkgKQoJCSAgIHsKCQkJICAgaWYoIEdldFBhcmVudChwQmVnaW5FbnRyeSkgIT0gIEdldFBhcmVudChwTmV3RW50cnkpICkKCQkJCSAgIHBCZWdpbkVudHJ5LT5TZXRNYXJrZWQoIHNhbF9GYWxzZSApOwoJCQkgICBTdkxCb3hFbnRyeSogcE5leHRFbnRyeSA9IE5leHQoIHBCZWdpbkVudHJ5ICk7CgkJCSAgIHdoaWxlKCBwTmV4dEVudHJ5ICkKCQkJICAgewoJCQkJICAgaWYoIEdldFBhcmVudChwTmV4dEVudHJ5KSAhPSAgR2V0UGFyZW50KHBOZXdFbnRyeSkgKQoJCQkJCSAgIHBOZXh0RW50cnktPlNldE1hcmtlZCggc2FsX0ZhbHNlICk7CgkJCQkgICBwTmV4dEVudHJ5ID0gIE5leHQoIHBOZXh0RW50cnkgKTsKCQkJICAgfQoJCSAgIH0KCQkgICBFbmQqLwoJCSAgIGlmKHBOZXdFbnRyeSkKCQkgICB7CgkJCSAgIGlmKGJNYXJrZWQpCgkJCSAgIHsKCQkJCSAgIHBOZXdFbnRyeS0+U2V0TWFya2VkKHNhbF9UcnVlKTsKCQkJICAgfQoJCQkgICBlbHNlCgkJCSAgIHsKCQkJCSAgIHBOZXdFbnRyeS0+U2V0TWFya2VkKCBzYWxfRmFsc2UgKTsKCQkJICAgfQoJCSAgIH0KCQkgICBJbnZhbGlkYXRlKCk7CgkgICB9Cgl9CgllbHNlCgkJU3ZUcmVlTGlzdEJveDo6S2V5SW5wdXQoIHJLRXZ0ICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCnwqCnwqIFN0YXJ0RHJhZy1SZXF1ZXN0CnwqClwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgp2b2lkIFNkUGFnZU9ianNUTEI6OlN0YXJ0RHJhZyggc2FsX0ludDggbkFjdGlvbiwgY29uc3QgUG9pbnQmIHJQb3NQaXhlbCkKewogICAgKHZvaWQpbkFjdGlvbjsKICAgICh2b2lkKXJQb3NQaXhlbDsKCglTZE5hdmlnYXRvcldpbiogcE5hdldpbiA9IE5VTEw7CiAgICBTdkxCb3hFbnRyeSogcEVudHJ5ID0gR2V0RW50cnkoclBvc1BpeGVsKTsKCglpZiggbXBGcmFtZS0+SGFzQ2hpbGRXaW5kb3coIFNJRF9OQVZJR0FUT1IgKSApCgkJcE5hdldpbiA9IChTZE5hdmlnYXRvcldpbiopICggbXBGcmFtZS0+R2V0Q2hpbGRXaW5kb3coIFNJRF9OQVZJR0FUT1IgKS0+R2V0Q29udGV4dFdpbmRvdyggU0RfTU9EKCkgKSApOwoKCWlmIChwRW50cnkgIT0gTlVMTAogICAgICAgICYmIHBOYXZXaW4gIT1OVUxMCiAgICAgICAgJiYgcE5hdldpbiA9PSBtcFBhcmVudAogICAgICAgICYmIHBOYXZXaW4tPkdldE5hdmlnYXRvckRyYWdUeXBlKCkgIT0gTkFWSUdBVE9SX0RSQUdUWVBFX05PTkUgKQoJewogICAgICAgIC8vIE1hcmsgb25seSB0aGUgY2hpbGRyZW4gb2YgdGhlIHBhZ2UgdW5kZXIgdGhlIG1vdXNlIGFzIGRyb3AKICAgICAgICAvLyB0YXJnZXRzLiAgVGhpcyBwcmV2ZW50cyBtb3Zpbmcgc2hhcGVzIGZyb20gb25lIHBhZ2UgdG8gYW5vdGhlci4KCiAgICAgICAgLy8gU2VsZWN0IGFsbCBlbnRyaWVzIGFuZCBkaXNhYmxlIHRoZW0gYXMgZHJvcCB0YXJnZXRzLgogICAgICAgIFNldFNlbGVjdGlvbk1vZGUoTVVMVElQTEVfU0VMRUNUSU9OKTsKICAgICAgICBTZXRDdXJzb3IoTlVMTCwgc2FsX0ZhbHNlKTsKICAgICAgICBTZWxlY3RBbGwoc2FsX1RydWUsIHNhbF9GYWxzZSk7CiAgICAgICAgRW5hYmxlU2VsZWN0aW9uQXNEcm9wVGFyZ2V0KHNhbF9GYWxzZSwgc2FsX1RydWUpOwoKICAgICAgICAvLyBFbmFibGUgb25seSB0aGUgZW50cmllcyBhcyBkcm9wIHRhcmdldHMgdGhhdCBhcmUgY2hpbGRyZW4gb2YgdGhlCiAgICAgICAgLy8gcGFnZSB1bmRlciB0aGUgbW91c2UuCiAgICAgICAgU3ZMQm94RW50cnkqIHBQYXJlbnQgPSBHZXRSb290TGV2ZWxQYXJlbnQocEVudHJ5KTsKICAgICAgICBpZiAocFBhcmVudCAhPSBOVUxMKQogICAgICAgIHsKICAgICAgICAgICAgU2VsZWN0QWxsKHNhbF9GYWxzZSwgc2FsX0ZhbHNlKTsKICAgICAgICAgICAgU2VsZWN0KHBQYXJlbnQsIHNhbF9UcnVlKTsKICAgICAgICAgICAgLy8gICAgICAgICAgICBmb3IgKFN2TEJveEVudHJ5KnBDaGlsZD1GaXJzdENoaWxkKHBQYXJlbnQpOyBwQ2hpbGQhPU5VTEw7IHBDaGlsZD1OZXh0U2libGluZyhwQ2hpbGQpKQogICAgICAgICAgICAvLyAgICAgICAgICAgICAgICBTZWxlY3QocENoaWxkLCBzYWxfVHJ1ZSk7CiAgICAgICAgICAgIEVuYWJsZVNlbGVjdGlvbkFzRHJvcFRhcmdldChzYWxfVHJ1ZSwgc2FsX1RydWUpOy8vc2FsX0ZhbHNlKTsKICAgICAgICB9CgogICAgICAgIC8vIFNldCBzZWxlY3Rpb24gYmFjayB0byB0aGUgZW50cnkgdW5kZXIgdGhlIG1vdXNlLgogICAgICAgIFNlbGVjdEFsbChzYWxfRmFsc2Usc2FsX0ZhbHNlKTsKICAgICAgICBTZXRTZWxlY3Rpb25Nb2RlKFNJTkdMRV9TRUxFQ1RJT04pOwogICAgICAgIFNlbGVjdChwRW50cnksIHNhbF9UcnVlKTsKCgkJLy8gIEF1cyBkZW0gRXhlY3V0ZURyYWcgaGVyYXVzIGthbm4gZGVyIE5hdmlnYXRvciBnZWxvZXNjaHQgd2VyZGVuCgkJLy8gIChiZWltIFVtc2NoYWx0ZW4gYXVmIGVpbmVuIGFuZGVyZW4gRG9rdW1lbnQtVHlwKSwgZGFzIHd1ZXJkZSBhYmVyCgkJLy8gIGRlbiBTdGFyVmlldyBNb3VzZU1vdmUtSGFuZGxlciwgZGVyIENvbW1hbmQoKSBhdWZydWZ0LCB1bWJyaW5nZW4uCgkJLy8gIERlc2hhbGIgRHJhZyZEcm9wIGFzeW5jaHJvbjoKICAgICAgICBBcHBsaWNhdGlvbjo6UG9zdFVzZXJFdmVudCggU1RBVElDX0xJTksoIHRoaXMsIFNkUGFnZU9ianNUTEIsIEV4ZWNEcmFnSGRsICkgKTsKCX0KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKfCoKfCogQmVnaW4gZHJhZwp8KgpcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKdm9pZCBTZFBhZ2VPYmpzVExCOjpEb0RyYWcoKQp7CgltcERyb3BOYXZXaW4gPSAoIG1wRnJhbWUtPkhhc0NoaWxkV2luZG93KCBTSURfTkFWSUdBVE9SICkgKSA/CgkJCQkgIChTZE5hdmlnYXRvcldpbiopKCBtcEZyYW1lLT5HZXRDaGlsZFdpbmRvdyggU0lEX05BVklHQVRPUiApLT5HZXRDb250ZXh0V2luZG93KCBTRF9NT0QoKSApICkgOgoJCQkJICBOVUxMOwoKCWlmKCBtcERyb3BOYXZXaW4gKQoJewoJCTo6c2Q6OkRyYXdEb2NTaGVsbCogcERvY1NoZWxsID0gbXBEb2MtPkdldERvY1NoKCk7CiAgICAgICAgU3RyaW5nIGFVUkwgPSBJTmV0VVJMT2JqZWN0KCBwRG9jU2hlbGwtPkdldE1lZGl1bSgpLT5HZXRQaHlzaWNhbE5hbWUoKSwgSU5FVF9QUk9UX0ZJTEUgKS5HZXRNYWluVVJMKCBJTmV0VVJMT2JqZWN0OjpOT19ERUNPREUgKTsKCQlOYXZpZ2F0b3JEcmFnVHlwZQllRHJhZ1R5cGUgPSBtcERyb3BOYXZXaW4tPkdldE5hdmlnYXRvckRyYWdUeXBlKCk7CgoJCWFVUkwuQXBwZW5kKCAnIycgKTsKCQlhVVJMLkFwcGVuZCggR2V0U2VsZWN0RW50cnkoKSApOwoKCQlJTmV0Qm9va21hcmsJYUJvb2ttYXJrKCBhVVJMLCBHZXRTZWxlY3RFbnRyeSgpICk7CgkJc2FsX0ludDgJCW5ETkRBY3Rpb25zID0gRE5EX0FDVElPTl9DT1BZTU9WRTsKCgkJaWYoIGVEcmFnVHlwZSA9PSBOQVZJR0FUT1JfRFJBR1RZUEVfTElOSyApCgkJCW5ETkRBY3Rpb25zID0gRE5EX0FDVElPTl9MSU5LOwkvLyAjOTMyNDAjIEVpdGhlciBDT1BZICpvciogTElOSywgbmV2ZXIgYm90aCEKICAgICAgICBlbHNlIGlmIChtcERvYy0+R2V0U2RQYWdlQ291bnQoUEtfU1RBTkRBUkQpID09IDEpCiAgICAgICAgewogICAgICAgICAgICAvLyBDYW4gbm90IG1vdmUgYXdheSB0aGUgbGFzdCBzbGlkZSBpbiBhIGRvY3VtZW50LgogICAgICAgICAgICBuRE5EQWN0aW9ucyA9IERORF9BQ1RJT05fQ09QWTsKICAgICAgICB9CgoJCVN2VHJlZUxpc3RCb3g6OlJlbGVhc2VNb3VzZSgpOwoKCQliSXNJbkRyYWcgPSBzYWxfVHJ1ZTsKCiAgICAgICAgU3ZMQm94RERJbmZvIGFEREluZm87CiAgICAgICAgbWVtc2V0KCZhRERJbmZvLDAsc2l6ZW9mKFN2TEJveERESW5mbykpOwogICAgICAgIGFEREluZm8ucEFwcCA9IEdldHBBcHAoKTsKICAgICAgICBhRERJbmZvLnBTb3VyY2UgPSB0aGlzOwogICAgICAgIC8vICAgICAgICAgICAgYURESW5mby5wRERTdGFydEVudHJ5ID0gcEVudHJ5OwoJCTo6Y29tOjpzdW46OnN0YXI6OnVubzo6U2VxdWVuY2U8c2FsX0ludDg+IGFTZXF1ZW5jZSAoc2l6ZW9mKFN2TEJveERESW5mbykpOwoJCW1lbWNweShhU2VxdWVuY2UuZ2V0QXJyYXkoKSwgKHNhbF9DaGFyKikmYURESW5mbywgc2l6ZW9mKFN2TEJveERESW5mbykpOwoJCTo6Y29tOjpzdW46OnN0YXI6OnVubzo6QW55IGFUcmVlTGlzdEJveERhdGEgKGFTZXF1ZW5jZSk7CgoJCS8vIG9iamVjdCBpcyBkZXN0cm95ZWQgYnkgaW50ZXJuYWwgcmVmZXJlbmNlIG1lY2hhbmlzbQoJCVNkVHJhbnNmZXJhYmxlKiBwVHJhbnNmZXJhYmxlID0gbmV3IFNkUGFnZU9ianNUTEI6OlNkUGFnZU9ianNUcmFuc2ZlcmFibGUoCiAgICAgICAgICAgICp0aGlzLCBhQm9va21hcmssICpwRG9jU2hlbGwsIGVEcmFnVHlwZSwgYVRyZWVMaXN0Qm94RGF0YSk7CgogICAgICAgIC8vIEdldCB0aGUgdmlldy4KICAgICAgICA6OnNkOjpWaWV3U2hlbGwqIHBWaWV3U2hlbGwgPSBHZXRWaWV3U2hlbGxGb3JEb2NTaGVsbCgqcERvY1NoZWxsKTsKICAgICAgICBpZiAocFZpZXdTaGVsbCA9PSBOVUxMKQogICAgICAgIHsKICAgICAgICAgICAgT1NMX0FTU0VSVChwVmlld1NoZWxsIT1OVUxMKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgICAgICBzZDo6VmlldyogcFZpZXcgPSBwVmlld1NoZWxsLT5HZXRWaWV3KCk7CiAgICAgICAgaWYgKHBWaWV3ID09IE5VTEwpCiAgICAgICAgewogICAgICAgICAgICBPU0xfQVNTRVJUKHBWaWV3IT1OVUxMKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgU2RyT2JqZWN0KiBwT2JqZWN0ID0gTlVMTDsKICAgICAgICB2b2lkKiBwVXNlckRhdGEgPSBHZXRDdXJFbnRyeSgpLT5HZXRVc2VyRGF0YSgpOwogICAgICAgIGlmIChwVXNlckRhdGEgIT0gTlVMTCAmJiBwVXNlckRhdGEgIT0gKHZvaWQqKTEpCiAgICAgICAgICAgIHBPYmplY3QgPSByZWludGVycHJldF9jYXN0PFNkck9iamVjdCo+KHBVc2VyRGF0YSk7CiAgICAgICAgaWYgKHBPYmplY3QgIT0gTlVMTCkKICAgICAgICB7CiAgICAgICAgICAgIC8vIEZvciBzaGFwZXMgd2l0aG91dCBhIHVzZXIgc3VwcGxpZWQgbmFtZSAodGhlIGF1dG9tYXRpY2FsbHkKICAgICAgICAgICAgLy8gY3JlYXRlZCBuYW1lIGRvZXMgbm90IGNvdW50KSwgYSBkaWZmZXJlbnQgZHJhZyBhbmQgZHJvcCB0ZWNobmlxdWUKICAgICAgICAgICAgLy8gaXMgdXNlZC4KICAgICAgICAgICAgaWYgKEdldE9iamVjdE5hbWUocE9iamVjdCwgZmFsc2UpLkxlbigpID09IDApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEFkZFNoYXBlVG9UcmFuc2ZlcmFibGUoKnBUcmFuc2ZlcmFibGUsICpwT2JqZWN0KTsKICAgICAgICAgICAgICAgIHBUcmFuc2ZlcmFibGUtPlNldFZpZXcocFZpZXcpOwogICAgICAgICAgICAgICAgU0RfTU9EKCktPnBUcmFuc2ZlckRyYWcgPSBwVHJhbnNmZXJhYmxlOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBVbm5hbWVkIHNoYXBlcyBoYXZlIHRvIGJlIHNlbGVjdGVkIHRvIGJlIHJlY29nbml6ZWQgYnkgdGhlCiAgICAgICAgICAgIC8vIGN1cnJlbnQgZHJvcCBpbXBsZW1lbnRhdGlvbi4gIEluIG9yZGVyIHRvIGhhdmUgYSBjb25zaXN0ZW50CiAgICAgICAgICAgIC8vIGJlaGF2aW91ciBmb3IgYWxsIHNoYXBlcywgZXZlcnkgc2hhcGUgdGhhdCBpcyB0byBiZSBkcmFnZ2VkIGlzCiAgICAgICAgICAgIC8vIHNlbGVjdGVkIGZpcnN0LgogICAgICAgICAgICBTZHJQYWdlVmlldyogcFBhZ2VWaWV3ID0gcFZpZXctPkdldFNkclBhZ2VWaWV3KCk7CiAgICAgICAgICAgIHBWaWV3LT5Vbm1hcmtBbGxPYmoocFBhZ2VWaWV3KTsKICAgICAgICAgICAgcFZpZXctPk1hcmtPYmoocE9iamVjdCwgcFBhZ2VWaWV3KTsKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgcFRyYW5zZmVyYWJsZS0+U2V0VmlldyhwVmlldyk7CiAgICAgICAgICAgIFNEX01PRCgpLT5wVHJhbnNmZXJEcmFnID0gcFRyYW5zZmVyYWJsZTsKICAgICAgICB9CgogICAgICAgIHBUcmFuc2ZlcmFibGUtPlN0YXJ0RHJhZyggdGhpcywgbkROREFjdGlvbnMgKTsKCX0KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKfCoKfCogRHJhZyBmaW5pc2hlZAp8KgpcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKdm9pZCBTZFBhZ2VPYmpzVExCOjpPbkRyYWdGaW5pc2hlZCggc2FsX3VJbnQ4ICkKewoJaWYoIG1wRnJhbWUtPkhhc0NoaWxkV2luZG93KCBTSURfTkFWSUdBVE9SICkgKQoJewoJCVNkTmF2aWdhdG9yV2luKiBwTmV3TmF2V2luID0gKFNkTmF2aWdhdG9yV2luKikgKCBtcEZyYW1lLT5HZXRDaGlsZFdpbmRvdyggU0lEX05BVklHQVRPUiApLT5HZXRDb250ZXh0V2luZG93KCBTRF9NT0QoKSApICk7CgoJCWlmKCBtcERyb3BOYXZXaW4gPT0gcE5ld05hdldpbikKCQl7CgkJCU1vdXNlRXZlbnQgYU1FdnQoIG1wRHJvcE5hdldpbi0+R2V0UG9pbnRlclBvc1BpeGVsKCkgKTsKCQkJU3ZUcmVlTGlzdEJveDo6TW91c2VCdXR0b25VcCggYU1FdnQgKTsKCQl9Cgl9CgoJbXBEcm9wTmF2V2luID0gTlVMTDsKCWJJc0luRHJhZyA9IHNhbF9GYWxzZTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKfCoKfCogQWNjZXB0RHJvcC1FdmVudAp8KgpcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKc2FsX0ludDggU2RQYWdlT2Jqc1RMQjo6QWNjZXB0RHJvcCAoY29uc3QgQWNjZXB0RHJvcEV2ZW50JiByRXZlbnQpCnsKICAgIHNhbF9JbnQ4IG5SZXN1bHQgKERORF9BQ1RJT05fTk9ORSk7CgoJaWYgKCAhYklzSW5EcmFnICYmIElzRHJvcEZvcm1hdFN1cHBvcnRlZCggRk9STUFUX0ZJTEUgKSApCiAgICB7CiAgICAgICAgblJlc3VsdCA9IHJFdmVudC5tbkFjdGlvbjsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBTdkxCb3hFbnRyeSogcEVudHJ5ID0gR2V0RHJvcFRhcmdldChyRXZlbnQubWFQb3NQaXhlbCk7CiAgICAgICAgaWYgKHJFdmVudC5tYkxlYXZpbmcgfHwgIUNoZWNrRHJhZ0FuZERyb3BNb2RlKCB0aGlzLCByRXZlbnQubW5BY3Rpb24gKSkKICAgICAgICB7CiAgICAgICAgICAgIEltcGxTaG93VGFyZ2V0RW1waGFzaXMoIHBUYXJnZXRFbnRyeSwgc2FsX0ZhbHNlICk7CiAgICAgICAgfQogICAgICAgIGVsc2UgaWYoICFuRHJhZ0Ryb3BNb2RlICkKICAgICAgICB7CiAgICAgICAgICAgIERCR19FUlJPUkZJTEUoICJTZFBhZ2VPYmpzVExCOjpBY2NlcHREcm9wKCk6IG5vIHRhcmdldCIgKTsKICAgICAgICB9CiAgICAgICAgZWxzZSBpZiAoSXNEcm9wQWxsb3dlZChwRW50cnkpKQogICAgICAgIHsKICAgICAgICAgICAgblJlc3VsdCA9IERORF9BQ1RJT05fTU9WRTsKCiAgICAgICAgICAgIC8vIERyYXcgZW1waGFzaXMuCiAgICAgICAgICAgIGlmIChwRW50cnkgIT0gcFRhcmdldEVudHJ5IHx8ICEobkltcEZsYWdzICYgU1ZMQk9YX1RBUkdFTVBIX1ZJUykpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEltcGxTaG93VGFyZ2V0RW1waGFzaXMoIHBUYXJnZXRFbnRyeSwgc2FsX0ZhbHNlICk7CiAgICAgICAgICAgICAgICBwVGFyZ2V0RW50cnkgPSBwRW50cnk7CiAgICAgICAgICAgICAgICBJbXBsU2hvd1RhcmdldEVtcGhhc2lzKCBwVGFyZ2V0RW50cnksIHNhbF9UcnVlICk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLy8gSGlkZSBlbXBoYXNpcyB3aGVuIHRoZXJlIGlzIG5vIHZhbGlkIGRyb3AgYWN0aW9uLgogICAgaWYgKG5SZXN1bHQgPT0gRE5EX0FDVElPTl9OT05FKQogICAgICAgIEltcGxTaG93VGFyZ2V0RW1waGFzaXMocFRhcmdldEVudHJ5LCBzYWxfRmFsc2UpOwoKICAgIHJldHVybiBuUmVzdWx0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgp8Kgp8KiBFeGVjdXRlRHJvcC1FdmVudAp8KgpcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKc2FsX0ludDggU2RQYWdlT2Jqc1RMQjo6RXhlY3V0ZURyb3AoIGNvbnN0IEV4ZWN1dGVEcm9wRXZlbnQmIHJFdnQgKQp7CglzYWxfSW50OCBuUmV0ID0gRE5EX0FDVElPTl9OT05FOwoKICAgIHRyeQogICAgewogICAgICAgIGlmKCAhYklzSW5EcmFnICkKICAgICAgICB7CiAgICAgICAgICAgIFNkTmF2aWdhdG9yV2luKiBwTmF2V2luID0gTlVMTDsKICAgICAgICAgICAgc2FsX3VJbnQxNgkJCW5JZCA9IFNJRF9OQVZJR0FUT1I7CgogICAgICAgICAgICBpZiggbXBGcmFtZS0+SGFzQ2hpbGRXaW5kb3coIG5JZCApICkKICAgICAgICAgICAgICAgIHBOYXZXaW4gPSAoU2ROYXZpZ2F0b3JXaW4qKSggbXBGcmFtZS0+R2V0Q2hpbGRXaW5kb3coIG5JZCApLT5HZXRDb250ZXh0V2luZG93KCBTRF9NT0QoKSApICk7CgogICAgICAgICAgICBpZiggcE5hdldpbiAmJiAoIHBOYXZXaW4gPT0gbXBQYXJlbnQgKSApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFRyYW5zZmVyYWJsZURhdGFIZWxwZXIJYURhdGFIZWxwZXIoIHJFdnQubWFEcm9wRXZlbnQuVHJhbnNmZXJhYmxlICk7CiAgICAgICAgICAgICAgICBTdHJpbmcJCQkJCWFGaWxlOwoKICAgICAgICAgICAgICAgIGlmKCBhRGF0YUhlbHBlci5HZXRTdHJpbmcoIEZPUk1BVF9GSUxFLCBhRmlsZSApICYmCiAgICAgICAgICAgICAgICAgICAgKCAoU2ROYXZpZ2F0b3JXaW4qKSBtcFBhcmVudCktPkluc2VydEZpbGUoIGFGaWxlICkgKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIG5SZXQgPSByRXZ0Lm1uQWN0aW9uOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQogICAgY2F0Y2ggKGNvbTo6c3VuOjpzdGFyOjp1bm86OkV4Y2VwdGlvbiYpCiAgICB7CiAgICAgICAgREJHX1VOSEFORExFRF9FWENFUFRJT04oKTsKICAgIH0KCiAgICBpZiAoblJldCA9PSBETkRfQUNUSU9OX05PTkUpCiAgICAgICAgU3ZUcmVlTGlzdEJveDo6RXhlY3V0ZURyb3AockV2dCwgdGhpcyk7CgoKCXJldHVybiBuUmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgp8Kgp8KiBIYW5kbGVyIGZ1ZXJzIERyYWdnaW5nCnwqClwqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgpJTVBMX1NUQVRJQ19MSU5LKFNkUGFnZU9ianNUTEIsIEV4ZWNEcmFnSGRsLCB2b2lkKiwgRU1QVFlBUkcpCnsKCS8vCWFscyBMaW5rLCBkYW1pdCBhc3luY2hyb24gb2huZSBJbXBNb3VzZU1vdmVNc2cgYXVmIGRlbSBTdGFjayBhdWNoIGRlcgoJLy8JTmF2aWdhdG9yIGdlbG9lc2NodCB3ZXJkZW4gZGFyZgoJcFRoaXMtPkRvRHJhZygpOwoJcmV0dXJuIDA7Cn0KCgpib29sIFNkUGFnZU9ianNUTEI6OlBhZ2VCZWxvbmdzVG9DdXJyZW50U2hvdyAoY29uc3QgU2RQYWdlKiBwUGFnZSkgY29uc3QKewogICAgLy8gUmV0dXJuIDxUUlVFLz4gYXMgZGVmYXVsdCB3aGVuIHRoZXJlIGlzIG5vIGN1c3RvbSBzaG93IG9yIHdoZW4gbm9uZQogICAgLy8gaXMgdXNlZC4gIFRoZSBwYWdlIGRvZXMgdGhlbiBiZWxvbmcgdG8gdGhlIHN0YW5kYXJkIHNob3cuCiAgICBib29sIGJCZWxvbmdzVG9TaG93ID0gdHJ1ZTsKCiAgICBpZiAobXBEb2MtPmdldFByZXNlbnRhdGlvblNldHRpbmdzKCkubWJDdXN0b21TaG93KQogICAgewogICAgICAgIC8vIEdldCB0aGUgY3VycmVudCBjdXN0b20gc2hvdy4KICAgICAgICBTZEN1c3RvbVNob3cqIHBDdXN0b21TaG93ID0gTlVMTDsKICAgICAgICBMaXN0KiBwU2hvd0xpc3QgPSBjb25zdF9jYXN0PFNkRHJhd0RvY3VtZW50Kj4obXBEb2MpLT5HZXRDdXN0b21TaG93TGlzdCgpOwogICAgICAgIGlmIChwU2hvd0xpc3QgIT0gTlVMTCkKICAgICAgICB7CiAgICAgICAgICAgIHNhbF91TG9uZyBuQ3VycmVudFNob3dJbmRleCA9IHBTaG93TGlzdC0+R2V0Q3VyUG9zKCk7CiAgICAgICAgICAgIHZvaWQqIHBPYmplY3QgPSBwU2hvd0xpc3QtPkdldE9iamVjdChuQ3VycmVudFNob3dJbmRleCk7CiAgICAgICAgICAgIHBDdXN0b21TaG93ID0gc3RhdGljX2Nhc3Q8U2RDdXN0b21TaG93Kj4ocE9iamVjdCk7CiAgICAgICAgfQoKICAgICAgICAvLyBDaGVjayB3aGV0aGVyIHRoZSBnaXZlbiBwYWdlIGlzIHBhcnQgb2YgdGhhdCBjdXN0b20gc2hvdy4KICAgICAgICBpZiAocEN1c3RvbVNob3cgIT0gTlVMTCkKICAgICAgICB7CiAgICAgICAgICAgIGJCZWxvbmdzVG9TaG93ID0gZmFsc2U7CiAgICAgICAgICAgIHNhbF91TG9uZyBuUGFnZUNvdW50ID0gcEN1c3RvbVNob3ctPkNvdW50KCk7CiAgICAgICAgICAgIGZvciAoc2FsX3VJbnQxNiBpPTA7IGk8blBhZ2VDb3VudCAmJiAhYkJlbG9uZ3NUb1Nob3c7IGkrKykKICAgICAgICAgICAgICAgIGlmIChwUGFnZSA9PSBzdGF0aWNfY2FzdDxTZFBhZ2UqPihwQ3VzdG9tU2hvdy0+R2V0T2JqZWN0IChpKSkpCiAgICAgICAgICAgICAgICAgICAgYkJlbG9uZ3NUb1Nob3cgPSB0cnVlOwogICAgICAgIH0KICAgIH0KCiAgICByZXR1cm4gYkJlbG9uZ3NUb1Nob3c7Cn0KCgoKCnNhbF9Cb29sIFNkUGFnZU9ianNUTEI6Ok5vdGlmeU1vdmluZygKICAgIFN2TEJveEVudHJ5KiBwVGFyZ2V0LAogICAgU3ZMQm94RW50cnkqIHBFbnRyeSwKICAgIFN2TEJveEVudHJ5KiYgcnBOZXdQYXJlbnQsCiAgICBzYWxfdUxvbmcmIHJOZXdDaGlsZFBvcykKewogICAgU3ZMQm94RW50cnkqIHBEZXN0aW5hdGlvbiA9IHBUYXJnZXQ7CiAgICB3aGlsZSAoR2V0UGFyZW50KHBEZXN0aW5hdGlvbikgIT0gTlVMTCAmJiBHZXRQYXJlbnQoR2V0UGFyZW50KHBEZXN0aW5hdGlvbikpICE9IE5VTEwpCiAgICAgICAgcERlc3RpbmF0aW9uID0gR2V0UGFyZW50KHBEZXN0aW5hdGlvbik7CgogICAgU2RyT2JqZWN0KiBwVGFyZ2V0T2JqZWN0ID0gcmVpbnRlcnByZXRfY2FzdDxTZHJPYmplY3QqPihwRGVzdGluYXRpb24tPkdldFVzZXJEYXRhKCkpOwogICAgU2RyT2JqZWN0KiBwU291cmNlT2JqZWN0ID0gcmVpbnRlcnByZXRfY2FzdDxTZHJPYmplY3QqPihwRW50cnktPkdldFVzZXJEYXRhKCkpOwogICAgaWYgKHBTb3VyY2VPYmplY3QgPT0gcmVpbnRlcnByZXRfY2FzdDxTZHJPYmplY3QqPigxKSkKICAgICAgICBwU291cmNlT2JqZWN0ID0gTlVMTDsKCiAgICBpZiAocFRhcmdldE9iamVjdCAhPSBOVUxMICYmIHBTb3VyY2VPYmplY3QgIT0gTlVMTCkKICAgIHsKICAgICAgICBTZHJQYWdlKiBwT2JqZWN0TGlzdCA9IHBTb3VyY2VPYmplY3QtPkdldFBhZ2UoKTsKICAgICAgICBpZiAocE9iamVjdExpc3QgIT0gTlVMTCkKICAgICAgICB7CiAgICAgICAgICAgIHNhbF91SW50MzIgbk5ld1Bvc2l0aW9uOwogICAgICAgICAgICBpZiAocFRhcmdldE9iamVjdCA9PSByZWludGVycHJldF9jYXN0PFNkck9iamVjdCo+KDEpKQogICAgICAgICAgICAgICAgbk5ld1Bvc2l0aW9uID0gMDsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgbk5ld1Bvc2l0aW9uID0gcFRhcmdldE9iamVjdC0+R2V0TmF2aWdhdGlvblBvc2l0aW9uKCkgKyAxOwogICAgICAgICAgICBwT2JqZWN0TGlzdC0+U2V0T2JqZWN0TmF2aWdhdGlvblBvc2l0aW9uKCpwU291cmNlT2JqZWN0LCBuTmV3UG9zaXRpb24pOwogICAgICAgIH0KCiAgICAgICAgLy8gVXBkYXRlIHRoZSB0cmVlIGxpc3QuCiAgICAgICAgaWYgKHBUYXJnZXQgPT0gTlVMTCkKICAgICAgICB7CiAgICAgICAgICAgIHJwTmV3UGFyZW50ID0gMDsKICAgICAgICAgICAgck5ld0NoaWxkUG9zID0gMDsKICAgICAgICAgICAgcmV0dXJuIHNhbF9UcnVlOwogICAgICAgIH0KICAgICAgICBlbHNlIGlmIChHZXRQYXJlbnQocERlc3RpbmF0aW9uKSA9PSBOVUxMKQogICAgICAgIHsKICAgICAgICAgICAgcnBOZXdQYXJlbnQgPSBwRGVzdGluYXRpb247CiAgICAgICAgICAgIHJOZXdDaGlsZFBvcyA9IDA7CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIHJwTmV3UGFyZW50ID0gR2V0UGFyZW50KHBEZXN0aW5hdGlvbik7CiAgICAgICAgICAgIHJOZXdDaGlsZFBvcyA9IHBNb2RlbC0+R2V0UmVsUG9zKHBEZXN0aW5hdGlvbikgKyAxOwogICAgICAgICAgICByTmV3Q2hpbGRQb3MgKz0gbkN1ckVudHJ5U2VsUG9zOwogICAgICAgICAgICBuQ3VyRW50cnlTZWxQb3MrKzsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHNhbF9UcnVlOwogICAgfQogICAgZWxzZQogICAgICAgIHJldHVybiBzYWxfRmFsc2U7Cn0KCgoKClN2TEJveEVudHJ5KiBTZFBhZ2VPYmpzVExCOjpHZXREcm9wVGFyZ2V0IChjb25zdCBQb2ludCYgckxvY2F0aW9uKQp7CiAgICBTdkxCb3hFbnRyeSogcEVudHJ5ID0gU3ZUcmVlTGlzdEJveDo6R2V0RHJvcFRhcmdldChyTG9jYXRpb24pOwogICAgaWYgKHBFbnRyeSA9PSBOVUxMKQogICAgICAgIHJldHVybiBOVUxMOwoKICAgIGlmIChHZXRQYXJlbnQocEVudHJ5KSA9PSBOVUxMKQogICAgewogICAgICAgIC8vIFVzZSBwYWdlIGVudHJ5IGFzIGluc2VydGlvbiBwb3NpdGlvbi4KICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICAvLyBHbyB0byBzZWNvbmQgaGllcmFyY2h5IGxldmVsLCBpLmUuIHRvcCBsZXZlbCBzaGFwZXMsCiAgICAgICAgLy8gaS5lLiBjaGlsZHJlbiBvZiBwYWdlcy4KICAgICAgICB3aGlsZSAoR2V0UGFyZW50KHBFbnRyeSkgIT0gTlVMTCAmJiBHZXRQYXJlbnQoR2V0UGFyZW50KHBFbnRyeSkpICE9IE5VTEwpCiAgICAgICAgICAgIHBFbnRyeSA9IEdldFBhcmVudChwRW50cnkpOwoKICAgICAgICAvLyBBZHZhbmNlIHRvIG5leHQgc2libGluZy4KICAgICAgICBTdkxCb3hFbnRyeSogcE5leHQ7CiAgICAgICAgc2FsX3VJbnQxNiBuRGVwdGggKDApOwogICAgICAgIHdoaWxlIChwRW50cnkgIT0gTlVMTCkKICAgICAgICB7CiAgICAgICAgICAgIHBOZXh0ID0gZHluYW1pY19jYXN0PFN2TEJveEVudHJ5Kj4oTmV4dFZpc2libGUocEVudHJ5LCAmbkRlcHRoKSk7CiAgICAgICAgICAgIGlmIChwTmV4dCAhPSBOVUxMICYmIG5EZXB0aCA+IDAgJiYgbkRlcHRoIT0weGZmZmYpCiAgICAgICAgICAgICAgICBwRW50cnkgPSBwTmV4dDsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgfQoKICAgIHJldHVybiBwRW50cnk7Cn0KCgoKCmJvb2wgU2RQYWdlT2Jqc1RMQjo6SXNEcm9wQWxsb3dlZCAoU3ZMQm94RW50cnkqIHBFbnRyeSkKewogICAgaWYgKHBFbnRyeSA9PSBOVUxMKQogICAgICAgIHJldHVybiBmYWxzZTsKCiAgICBpZiAoICEgSXNEcm9wRm9ybWF0U3VwcG9ydGVkKFNkUGFnZU9ianNUcmFuc2ZlcmFibGU6OkdldExpc3RCb3hEcm9wRm9ybWF0SWQoKSkpCiAgICAgICAgcmV0dXJuIGZhbHNlOwoKICAgIGlmICgocEVudHJ5LT5HZXRGbGFncygpICYgU1ZfRU5UUllGTEFHX0RJU0FCTEVfRFJPUCkgIT0gMCkKICAgICAgICByZXR1cm4gZmFsc2U7CgogICAgcmV0dXJuIHRydWU7Cn0KCgoKCnZvaWQgU2RQYWdlT2Jqc1RMQjo6QWRkU2hhcGVUb1RyYW5zZmVyYWJsZSAoCiAgICBTZFRyYW5zZmVyYWJsZSYgclRyYW5zZmVyYWJsZSwKICAgIFNkck9iamVjdCYgck9iamVjdCkgY29uc3QKewoJVHJhbnNmZXJhYmxlT2JqZWN0RGVzY3JpcHRvciBhT2JqZWN0RGVzY3JpcHRvcjsKICAgIGJvb2wgYklzRGVzY3JpcHRvckZpbGxpbmdQZW5kaW5nICh0cnVlKTsKCiAgICBjb25zdCBTZHJPbGUyT2JqKiBwT2xlT2JqZWN0ID0gZHluYW1pY19jYXN0PGNvbnN0IFNkck9sZTJPYmoqPigmck9iamVjdCk7CiAgICBpZiAocE9sZU9iamVjdCAhPSBOVUxMICYmIHBPbGVPYmplY3QtPkdldE9ialJlZigpLmlzKCkpCiAgICB7CiAgICAgICAgLy8gSWYgb2JqZWN0IGhhcyBubyBwZXJzaXN0ZW5jZSBpdCBtdXN0IGJlIGNvcGllZCBhcyBwYXJ0IG9mIHRoZSBkb2N1bWVudAogICAgICAgIHRyeQogICAgICAgIHsKICAgICAgICAgICAgdW5vOjpSZWZlcmVuY2U8IGVtYmVkOjpYRW1iZWRQZXJzaXN0ID4geFBlcnNPYmogKHBPbGVPYmplY3QtPkdldE9ialJlZigpLCB1bm86OlVOT19RVUVSWSApOwogICAgICAgICAgICBpZiAoeFBlcnNPYmouaXMoKSAmJiB4UGVyc09iai0+aGFzRW50cnkoKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgU3ZFbWJlZFRyYW5zZmVySGVscGVyOjpGaWxsVHJhbnNmZXJhYmxlT2JqZWN0RGVzY3JpcHRvcigKICAgICAgICAgICAgICAgICAgICBhT2JqZWN0RGVzY3JpcHRvciwKICAgICAgICAgICAgICAgICAgICBwT2xlT2JqZWN0LT5HZXRPYmpSZWYoKSwKICAgICAgICAgICAgICAgICAgICBwT2xlT2JqZWN0LT5HZXRHcmFwaGljKCksCiAgICAgICAgICAgICAgICAgICAgcE9sZU9iamVjdC0+R2V0QXNwZWN0KCkpOwogICAgICAgICAgICAgICAgYklzRGVzY3JpcHRvckZpbGxpbmdQZW5kaW5nID0gZmFsc2U7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgY2F0Y2goIHVubzo6RXhjZXB0aW9uJiApCiAgICAgICAgewogICAgICAgIH0KCX0KCiAgICA6OnNkOjpEcmF3RG9jU2hlbGwqIHBEb2NTaGVsbCA9IG1wRG9jLT5HZXREb2NTaCgpOwoJaWYgKGJJc0Rlc2NyaXB0b3JGaWxsaW5nUGVuZGluZyAmJiBwRG9jU2hlbGwhPU5VTEwpCiAgICB7CiAgICAgICAgYklzRGVzY3JpcHRvckZpbGxpbmdQZW5kaW5nID0gZmFsc2U7CiAgICAgICAgcERvY1NoZWxsLT5GaWxsVHJhbnNmZXJhYmxlT2JqZWN0RGVzY3JpcHRvcihhT2JqZWN0RGVzY3JpcHRvcik7CiAgICB9CgogICAgUG9pbnQgYURyYWdQb3MgKHJPYmplY3QuR2V0Q3VycmVudEJvdW5kUmVjdCgpLkNlbnRlcigpKTsKICAgIC8vUG9pbnQgYURyYWdQb3MgKDAsMCk7CglhT2JqZWN0RGVzY3JpcHRvci5tYURyYWdTdGFydFBvcyA9IGFEcmFnUG9zOwogICAgLy8JYU9iamVjdERlc2NyaXB0b3IubWFTaXplID0gR2V0QWxsTWFya2VkUmVjdCgpLkdldFNpemUoKTsKICAgIGlmIChwRG9jU2hlbGwgIT0gTlVMTCkKICAgICAgICBhT2JqZWN0RGVzY3JpcHRvci5tYURpc3BsYXlOYW1lID0gcERvY1NoZWxsLT5HZXRNZWRpdW0oKS0+R2V0VVJMT2JqZWN0KCkuR2V0VVJMTm9QYXNzKCk7CiAgICBlbHNlCiAgICAgICAgYU9iamVjdERlc2NyaXB0b3IubWFEaXNwbGF5TmFtZSA9IFN0cmluZygpOwoJYU9iamVjdERlc2NyaXB0b3IubWJDYW5MaW5rID0gc2FsX0ZhbHNlOwoKCXJUcmFuc2ZlcmFibGUuU2V0U3RhcnRQb3MoYURyYWdQb3MpOwoJclRyYW5zZmVyYWJsZS5TZXRPYmplY3REZXNjcmlwdG9yKCBhT2JqZWN0RGVzY3JpcHRvciApOwp9CgoKCgo6OnNkOjpWaWV3U2hlbGwqIFNkUGFnZU9ianNUTEI6OkdldFZpZXdTaGVsbEZvckRvY1NoZWxsICg6OnNkOjpEcmF3RG9jU2hlbGwmIHJEb2NTaGVsbCkKewogICAgewogICAgICAgIDo6c2Q6OlZpZXdTaGVsbCogcFZpZXdTaGVsbCA9IHJEb2NTaGVsbC5HZXRWaWV3U2hlbGwoKTsKICAgICAgICBpZiAocFZpZXdTaGVsbCAhPSBOVUxMKQogICAgICAgICAgICByZXR1cm4gcFZpZXdTaGVsbDsKICAgIH0KCiAgICB0cnkKICAgIHsKICAgICAgICAvLyBHZXQgYSBjb21wb25lbnQgZW51bWVyYXRpb24gZnJvbSB0aGUgZGVza3RvcCBhbmQgc2VhcmNoIGl0IGZvciBkb2N1bWVudHMuCiAgICAgICAgdW5vOjpSZWZlcmVuY2U8bGFuZzo6WE11bHRpU2VydmljZUZhY3Rvcnk+IHhGYWN0b3J5ICgKICAgICAgICAgICAgOjpjb21waGVscGVyOjpnZXRQcm9jZXNzU2VydmljZUZhY3RvcnkgKCkpOwogICAgICAgIGlmICggISB4RmFjdG9yeS5pcygpKQogICAgICAgICAgICByZXR1cm4gTlVMTDsKCiAgICAgICAgdW5vOjpSZWZlcmVuY2U8ZnJhbWU6OlhEZXNrdG9wPiB4RGVza3RvcCAoeEZhY3RvcnktPmNyZWF0ZUluc3RhbmNlICgKICAgICAgICAgICAgICAgIDo6cnRsOjpPVVN0cmluZzo6Y3JlYXRlRnJvbUFzY2lpKCJjb20uc3VuLnN0YXIuZnJhbWUuRGVza3RvcCIpKSwgdW5vOjpVTk9fUVVFUlkpOwogICAgICAgIGlmICggISB4RGVza3RvcC5pcygpKQogICAgICAgICAgICByZXR1cm4gTlVMTDsKCiAgICAgICAgdW5vOjpSZWZlcmVuY2U8ZnJhbWU6OlhGcmFtZXNTdXBwbGllcj4geEZyYW1lU3VwcGxpZXIgKHhEZXNrdG9wLCB1bm86OlVOT19RVUVSWSk7CiAgICAgICAgaWYgKCAhIHhGcmFtZVN1cHBsaWVyLmlzKCkpCiAgICAgICAgICAgIHJldHVybiBOVUxMOwoKICAgICAgICB1bm86OlJlZmVyZW5jZTxjb250YWluZXI6OlhJbmRleEFjY2Vzcz4geEZyYW1lQWNjZXNzICh4RnJhbWVTdXBwbGllci0+Z2V0RnJhbWVzKCksIHVubzo6VU5PX1FVRVJZKTsKICAgICAgICBpZiAoICEgeEZyYW1lQWNjZXNzLmlzKCkpCiAgICAgICAgICAgIHJldHVybiBOVUxMOwoKICAgICAgICBmb3IgKHNhbF9JbnQzMiBuSW5kZXg9MCxuQ291bnQ9eEZyYW1lQWNjZXNzLT5nZXRDb3VudCgpOyBuSW5kZXg8bkNvdW50OyArK25JbmRleCkKICAgICAgICB7CiAgICAgICAgICAgIHVubzo6UmVmZXJlbmNlPGZyYW1lOjpYRnJhbWU+IHhGcmFtZTsKICAgICAgICAgICAgaWYgKCAhICh4RnJhbWVBY2Nlc3MtPmdldEJ5SW5kZXgobkluZGV4KSA+Pj0geEZyYW1lKSkKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwoKICAgICAgICAgICAgOjpzZDo6RHJhd0NvbnRyb2xsZXIqIHBDb250cm9sbGVyID0gZHluYW1pY19jYXN0PHNkOjpEcmF3Q29udHJvbGxlcio+KHhGcmFtZS0+Z2V0Q29udHJvbGxlcigpLmdldCgpKTsKICAgICAgICAgICAgaWYgKHBDb250cm9sbGVyID09IE5VTEwpCiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgOjpzZDo6Vmlld1NoZWxsQmFzZSogcEJhc2UgPSBwQ29udHJvbGxlci0+R2V0Vmlld1NoZWxsQmFzZSgpOwogICAgICAgICAgICBpZiAocEJhc2UgPT0gTlVMTCkKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICBpZiAocEJhc2UtPkdldERvY1NoZWxsKCkgIT0gJnJEb2NTaGVsbCkKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwoKICAgICAgICAgICAgY29uc3QgOjpib29zdDo6c2hhcmVkX3B0cjxzZDo6Vmlld1NoZWxsPiBwVmlld1NoZWxsIChwQmFzZS0+R2V0TWFpblZpZXdTaGVsbCgpKTsKICAgICAgICAgICAgaWYgKHBWaWV3U2hlbGwpCiAgICAgICAgICAgICAgICByZXR1cm4gcFZpZXdTaGVsbC5nZXQoKTsKICAgICAgICB9CiAgICB9CiAgICBjYXRjaCAodW5vOjpFeGNlcHRpb24gZSkKICAgIHsKICAgICAgICAvLyBXaGVuIHRoZXJlIGlzIGFuIGV4Y2VwdGlvbiB0aGVuIHNpbXBseSB1c2UgdGhlIGRlZmF1bHQgdmFsdWUgb2YKICAgICAgICAvLyBiSXNFbmFibGVkIGFuZCBkaXNhYmxlIHRoZSBjb250cm9scy4KICAgIH0KICAgIHJldHVybiBOVUxMOwp9CgoKCgovLz09PT09IEljb25Qcm92aWRlciA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CgpTZFBhZ2VPYmpzVExCOjpJY29uUHJvdmlkZXI6Okljb25Qcm92aWRlciAodm9pZCkKICAgIDogbWFJbWdQYWdlKCBCaXRtYXBFeCggU2RSZXNJZCggQk1QX1BBR0UgKSApICksCiAgICAgIG1hSW1nUGFnZUV4Y2woIEJpdG1hcEV4KCBTZFJlc0lkKCBCTVBfUEFHRV9FWENMVURFRCApICkgKSwKICAgICAgbWFJbWdQYWdlT2Jqc0V4Y2woIEJpdG1hcEV4KCBTZFJlc0lkKCBCTVBfUEFHRU9CSlNfRVhDTFVERUQgKSApICksCiAgICAgIG1hSW1nUGFnZU9ianMoIEJpdG1hcEV4KCBTZFJlc0lkKCBCTVBfUEFHRU9CSlMgKSApICksCiAgICAgIG1hSW1nT2JqZWN0cyggQml0bWFwRXgoIFNkUmVzSWQoIEJNUF9PQkpFQ1RTICkgKSApLAogICAgICBtYUltZ0dyb3VwKCBCaXRtYXBFeCggU2RSZXNJZCggQk1QX0dST1VQICkgKSApLAoKICAgICAgbWFJbWdQYWdlSCggQml0bWFwRXgoIFNkUmVzSWQoIEJNUF9QQUdFX0ggKSApICksCiAgICAgIG1hSW1nUGFnZUV4Y2xIKCBCaXRtYXBFeCggU2RSZXNJZCggQk1QX1BBR0VfRVhDTFVERURfSCApICkgKSwKICAgICAgbWFJbWdQYWdlT2Jqc0V4Y2xIKCBCaXRtYXBFeCggU2RSZXNJZCggQk1QX1BBR0VPQkpTX0VYQ0xVREVEX0ggKSApICksCiAgICAgIG1hSW1nUGFnZU9ianNIKCBCaXRtYXBFeCggU2RSZXNJZCggQk1QX1BBR0VPQkpTX0ggKSApICksCiAgICAgIG1hSW1nT2JqZWN0c0goIEJpdG1hcEV4KCBTZFJlc0lkKCBCTVBfT0JKRUNUU19IICkgKSApLAogICAgICBtYUltZ0dyb3VwSCggQml0bWFwRXgoIFNkUmVzSWQoIEJNUF9HUk9VUF9IICkgKSApCnsKfQo=