LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIAogKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCiAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgogKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCiAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQogKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqIAogKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKiAKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAogKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgogKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCiAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKICogdW5kZXIgdGhlIExpY2Vuc2UuCiAqIAogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCgoKLy8gTUFSS0VSKHVwZGF0ZV9wcmVjb21wLnB5KTogYXV0b2dlbiBpbmNsdWRlIHN0YXRlbWVudCwgZG8gbm90IHJlbW92ZQojaW5jbHVkZSAicHJlY29tcGlsZWRfYXV0b21hdGlvbi5oeHgiCgoKI2luY2x1ZGUgPHRvb2xzL3RpbWUuaHh4PgojaW5jbHVkZSA8dG9vbHMvc3RyaW5nLmh4eD4KI2luY2x1ZGUgPHVub3Rvb2xzL2xvY2FsZWRhdGF3cmFwcGVyLmh4eD4KI2luY2x1ZGUgPHZjbC9zdmFwcC5oeHg+CiNpZm5kZWYgX0JBU0lDX1RUUkVTSExQX0hYWAojaW5jbHVkZSA8YmFzaWMvdHRzdHJobHAuaHh4PgojZW5kaWYKCgojaW5jbHVkZSAicHJvZmlsZXIuaHh4IgoKClRUUHJvZmlsZXI6OlRUUHJvZmlsZXIoKQo6IG1wU3RhcnQoIE5VTEwgKQosIG1wRW5kKCBOVUxMICkKLCBiSXNQcm9maWxlSW50ZXJ2YWxTdGFydGVkKCBzYWxfRmFsc2UgKQosIGJJc1Byb2ZpbGluZ1BlckNvbW1hbmQoIHNhbF9GYWxzZSApCiwgYklzUGFydGl0aW9uaW5nKCBzYWxfRmFsc2UgKQosIGJJc0F1dG9Qcm9maWxpbmcoIHNhbF9GYWxzZSApCiwgcFN5c0RlcFN0YXRpYyggTlVMTCApCnsKCUluaXRTeXNkZXBQcm9maWxlcigpOwoJbXBTdGFydCA9IG5ldyBQcm9maWxlU25hcHNob3Q7CgltcFN0YXJ0LT5wU3lzZGVwUHJvZmlsZVNuYXBzaG90ID0gTmV3U3lzZGVwU25hcHNob3REYXRhKCk7CgltcEVuZCA9IG5ldyBQcm9maWxlU25hcHNob3Q7CgltcEVuZC0+cFN5c2RlcFByb2ZpbGVTbmFwc2hvdCA9IE5ld1N5c2RlcFNuYXBzaG90RGF0YSgpOwoJU3RhcnRQcm9maWxlSW50ZXJ2YWwoKTsKfQoKVFRQcm9maWxlcjo6flRUUHJvZmlsZXIoKQp7CglpZiAoIElzQXV0b1Byb2ZpbGluZygpICkKCQlTdG9wQXV0b1Byb2ZpbGluZygpOwoJaWYgKCBtcFN0YXJ0ICkKCXsKCQlpZiAoIG1wU3RhcnQtPnBTeXNkZXBQcm9maWxlU25hcHNob3QgKQoJCQlEZWxldGVTeXNkZXBTbmFwc2hvdERhdGEoIG1wU3RhcnQtPnBTeXNkZXBQcm9maWxlU25hcHNob3QgKTsKCQlkZWxldGUgbXBTdGFydDsKCQltcFN0YXJ0ID0gTlVMTDsKCX0KCWlmICggbXBFbmQgKQoJewoJCWlmICggbXBFbmQtPnBTeXNkZXBQcm9maWxlU25hcHNob3QgKQoJCQlEZWxldGVTeXNkZXBTbmFwc2hvdERhdGEoIG1wRW5kLT5wU3lzZGVwUHJvZmlsZVNuYXBzaG90ICk7CgkJZGVsZXRlIG1wRW5kOwoJCW1wRW5kID0gTlVMTDsKCX0KCURlaW5pdFN5c2RlcFByb2ZpbGVyKCk7Cn0KCgpTdHJpbmcgVFRQcm9maWxlcjo6R2V0UHJvZmlsZUhlYWRlcigpCnsKCVVuaVN0cmluZyBhUmV0dXJuOwoJYVJldHVybiArPSAnXG4nOwoJaWYgKCAhSXNBdXRvUHJvZmlsaW5nKCkgKQoJCWFSZXR1cm4uQXBwZW5kQXNjaWkoIkJlZmVobCIpLkFwcGVuZChUYWJTdHJpbmcoMzYpKTsKCglhUmV0dXJuLkFwcGVuZEFzY2lpKCIgICBaZWl0ZGF1ZXIiKTsKCWFSZXR1cm4uQXBwZW5kQXNjaWkoIiAgVGlja3MgaW4gJSIpOwoJYVJldHVybi5BcHBlbmQoIEdldFN5c2RlcFByb2ZpbGVIZWFkZXIoKSApOwoJYVJldHVybi5BcHBlbmRBc2NpaSgiXG4iKTsKCXJldHVybiBhUmV0dXJuOwp9CgoKdm9pZCBUVFByb2ZpbGVyOjpTdGFydFByb2ZpbGVJbnRlcnZhbCggc2FsX0Jvb2wgYlJlYWRBbnl3YXkgKQp7CglpZiAoICFiSXNQcm9maWxlSW50ZXJ2YWxTdGFydGVkIHx8IGJSZWFkQW55d2F5ICkKCXsKCQlHZXRQcm9maWxlU25hcHNob3QoIG1wU3RhcnQgKTsKCQlHZXRTeXNkZXBQcm9maWxlU25hcHNob3QoIG1wU3RhcnQtPnBTeXNkZXBQcm9maWxlU25hcHNob3QsIFBST0ZJTEVfU1RBUlQgKTsKCQliSXNQcm9maWxlSW50ZXJ2YWxTdGFydGVkID0gc2FsX1RydWU7Cgl9Cn0KClN0cmluZyBUVFByb2ZpbGVyOjpHZXRQcm9maWxlTGluZSggUHJvZmlsZVNuYXBzaG90ICpwU3RhcnQsIFByb2ZpbGVTbmFwc2hvdCAqcEVuZCApCnsKCVN0cmluZyBhUHJvZmlsZVN0cmluZzsKCglhUHJvZmlsZVN0cmluZyArPSBQYWQoR2V0cEFwcCgpLT5HZXRBcHBMb2NhbGVEYXRhV3JhcHBlcigpLmdldER1cmF0aW9uKCBESUZGKCBwU3RhcnQsIHBFbmQsIGFUaW1lKSAsIHNhbF9UcnVlLCBzYWxfVHJ1ZSApLCAxMik7CgoJc2FsX3VMb25nIG5Qcm9jZXNzVGlja3MgPSBESUZGKCBwU3RhcnQsIHBFbmQsIG5Qcm9jZXNzVGlja3MgKTsKCXNhbF91TG9uZyBuU3lzdGVtVGlja3MgPSBESUZGKCBwU3RhcnQsIHBFbmQsIG5TeXN0ZW1UaWNrcyApOwoJaWYgKCBuU3lzdGVtVGlja3MgKQoJewoJCWFQcm9maWxlU3RyaW5nICs9IFBhZChVbmlTdHJpbmc6OkNyZWF0ZUZyb21JbnQzMiggKDEwMCAqIG5Qcm9jZXNzVGlja3MpIC8gblN5c3RlbVRpY2tzICksIDExKTsKCQlhUHJvZmlsZVN0cmluZyArPSAnJSc7Cgl9CgllbHNlCgkJYVByb2ZpbGVTdHJpbmcgKz0gUGFkKENVbmlTdHJpbmcoIj8/ICAiKSwgMTIpOwoKCXJldHVybiBhUHJvZmlsZVN0cmluZzsKfQoKClN0cmluZyBUVFByb2ZpbGVyOjpHZXRQcm9maWxlTGluZSggU3RyaW5nICZhUHJlZml4ICkKewoJU3RyaW5nIGFQcm9maWxlU3RyaW5nOwoJaWYgKCBJc1Byb2ZpbGluZ1BlckNvbW1hbmQoKSB8fCBJc0F1dG9Qcm9maWxpbmcoKSApCgl7CgkJYVByb2ZpbGVTdHJpbmcgPSBhUHJlZml4OwoJCWFQcm9maWxlU3RyaW5nICs9IFRhYlN0cmluZygzNSk7CgoKCQlhUHJvZmlsZVN0cmluZyArPSBHZXRQcm9maWxlTGluZSggbXBTdGFydCwgbXBFbmQgKTsKCQlhUHJvZmlsZVN0cmluZyArPSBHZXRTeXNkZXBQcm9maWxlTGluZSggbXBTdGFydC0+cFN5c2RlcFByb2ZpbGVTbmFwc2hvdCwgbXBFbmQtPnBTeXNkZXBQcm9maWxlU25hcHNob3QgKTsKCQlhUHJvZmlsZVN0cmluZyArPSAnXG4nOwoJfQoKCXJldHVybiBhUHJvZmlsZVN0cmluZzsKfQoKCnZvaWQgVFRQcm9maWxlcjo6RW5kUHJvZmlsZUludGVydmFsKCkKewoJR2V0UHJvZmlsZVNuYXBzaG90KCBtcEVuZCApOwoJR2V0U3lzZGVwUHJvZmlsZVNuYXBzaG90KCBtcEVuZC0+cFN5c2RlcFByb2ZpbGVTbmFwc2hvdCwgUFJPRklMRV9FTkQgKTsKCWJJc1Byb2ZpbGVJbnRlcnZhbFN0YXJ0ZWQgPSBzYWxfRmFsc2U7Cn0KCgp2b2lkIFRUUHJvZmlsZXI6OkdldFByb2ZpbGVTbmFwc2hvdCggUHJvZmlsZVNuYXBzaG90ICpwUHJvZmlsZVNuYXBzaG90ICkKewoJcFByb2ZpbGVTbmFwc2hvdC0+YVRpbWUgPSBUaW1lKCk7CglwUHJvZmlsZVNuYXBzaG90LT5uUHJvY2Vzc1RpY2tzID0gVGltZTo6R2V0UHJvY2Vzc1RpY2tzKCk7CglwUHJvZmlsZVNuYXBzaG90LT5uU3lzdGVtVGlja3MgPSBUaW1lOjpHZXRTeXN0ZW1UaWNrcygpOwp9CgoKdm9pZCBUVFByb2ZpbGVyOjpTdGFydFByb2ZpbGluZ1BlckNvbW1hbmQoKQkJLy8gSmVkZW4gQmVmZWhsIG1pdHNjaG5laWRlbgp7CgliSXNQcm9maWxpbmdQZXJDb21tYW5kID0gc2FsX1RydWU7Cn0KCnZvaWQgVFRQcm9maWxlcjo6U3RvcFByb2ZpbGluZ1BlckNvbW1hbmQoKQp7CgliSXNQcm9maWxpbmdQZXJDb21tYW5kID0gc2FsX0ZhbHNlOwp9Cgp2b2lkIFRUUHJvZmlsZXI6OlN0YXJ0UGFydGl0aW9uaW5nKCkKewoJYklzUGFydGl0aW9uaW5nID0gc2FsX1RydWU7Cn0KCnZvaWQgVFRQcm9maWxlcjo6U3RvcFBhcnRpdGlvbmluZygpCnsKCWJJc1BhcnRpdGlvbmluZyA9IHNhbF9UcnVlOwp9CgpzYWxfdUxvbmcgVFRQcm9maWxlcjo6R2V0UGFydGl0aW9uaW5nVGltZSgpCnsKCXJldHVybiBESUZGKCBtcFN0YXJ0LCBtcEVuZCwgblN5c3RlbVRpY2tzICk7Cn0KCgoKdm9pZCBUVFByb2ZpbGVyOjpTdGFydEF1dG9Qcm9maWxpbmcoIHNhbF91TG9uZyBuTVNlYyApCnsKCWlmICggIWJJc0F1dG9Qcm9maWxpbmcgKQoJewoJCXBBdXRvU3RhcnQgPSBuZXcgUHJvZmlsZVNuYXBzaG90OwoJCXBBdXRvU3RhcnQtPnBTeXNkZXBQcm9maWxlU25hcHNob3QgPSBOZXdTeXNkZXBTbmFwc2hvdERhdGEoKTsKCQlwQXV0b0VuZCA9IG5ldyBQcm9maWxlU25hcHNob3Q7CgkJcEF1dG9FbmQtPnBTeXNkZXBQcm9maWxlU25hcHNob3QgPSBOZXdTeXNkZXBTbmFwc2hvdERhdGEoKTsKCQlHZXRQcm9maWxlU25hcHNob3QoIHBBdXRvU3RhcnQgKTsKCQlHZXRTeXNkZXBQcm9maWxlU25hcHNob3QoIHBBdXRvU3RhcnQtPnBTeXNkZXBQcm9maWxlU25hcHNob3QsIFBST0ZJTEVfU1RBUlQgKTsKCQlTZXRUaW1lb3V0KCBuTVNlYyApOwoJCWJJc0F1dG9Qcm9maWxpbmcgPSBzYWxfVHJ1ZTsKCQlTdGFydCgpOwoJfQoKfQoKdm9pZCBUVFByb2ZpbGVyOjpUaW1lb3V0KCkKewoJR2V0UHJvZmlsZVNuYXBzaG90KCBwQXV0b0VuZCApOwoJR2V0U3lzZGVwUHJvZmlsZVNuYXBzaG90KCBwQXV0b0VuZC0+cFN5c2RlcFByb2ZpbGVTbmFwc2hvdCwgUFJPRklMRV9FTkQgKTsKCVN0cmluZyBhTGluZTsKCglhTGluZSArPSBHZXRQcm9maWxlTGluZSggcEF1dG9TdGFydCwgcEF1dG9FbmQgKTsKCWFMaW5lICs9IEdldFN5c2RlcFByb2ZpbGVMaW5lKCBwQXV0b1N0YXJ0LT5wU3lzZGVwUHJvZmlsZVNuYXBzaG90LCBwQXV0b0VuZC0+cFN5c2RlcFByb2ZpbGVTbmFwc2hvdCApOwoJYUxpbmUgKz0gJ1xuJzsKCglhQXV0b1Byb2ZpbGVCdWZmZXIgKz0gYUxpbmU7CgoJUHJvZmlsZVNuYXBzaG90ICpwVGVtcCA9IHBBdXRvU3RhcnQ7CQkvLyBUYXVzY2hlbiwgc28gZGHfIGpldHppZ2VzIEVuZGUgbuRjaHN0ZW4gU3RhcnQgd2lyZAoJcEF1dG9TdGFydCA9IHBBdXRvRW5kOwoJcEF1dG9FbmQgPSBwVGVtcDsKCglTdGFydCgpOwkvLyBUaW1lciBuZXUgc3RhcnRlbgp9CgpTdHJpbmcgVFRQcm9maWxlcjo6R2V0QXV0b1Byb2ZpbGluZygpCnsKCVN0cmluZyBhVGVtcChhQXV0b1Byb2ZpbGVCdWZmZXIpOwoJYUF1dG9Qcm9maWxlQnVmZmVyLkVyYXNlKCk7CglyZXR1cm4gYVRlbXA7Cn0KCnZvaWQgVFRQcm9maWxlcjo6U3RvcEF1dG9Qcm9maWxpbmcoKQp7CglpZiAoIGJJc0F1dG9Qcm9maWxpbmcgKQoJewoJCVN0b3AoKTsKCQliSXNBdXRvUHJvZmlsaW5nID0gc2FsX0ZhbHNlOwoJfQp9CgoKCi8vU3RyaW5nIFRUUHJvZmlsZXI6OkhleCggc2FsX3VMb25nIG5OciApClN0cmluZyBUVFByb2ZpbGVyOjpEZWMoIHNhbF91TG9uZyBuTnIgKQp7CglTdHJpbmcgYVJldChVbmlTdHJpbmc6OkNyZWF0ZUZyb21JbnQzMihuTnIpKTsKCWlmICggbk5yIDwgMTAwICkKCXsKCQlhUmV0ID0gUGFkKCBhUmV0LCAzKTsKCQlhUmV0LlNlYXJjaEFuZFJlcGxhY2VBbGwoJyAnLCcwJyk7Cgl9CglhUmV0Lkluc2VydCggJywnLCBhUmV0LkxlbigpIC0gMiApOwoJcmV0dXJuIGFSZXQ7Cn0KClN0cmluZyBUVFByb2ZpbGVyOjpQYWQoIGNvbnN0IFN0cmluZyBhUywgeHViX1N0ckxlbiBuTGVuICkKewoJaWYgKCBuTGVuID4gYVMuTGVuKCkgKQoJCXJldHVybiBVbmlTdHJpbmcoKS5GaWxsKCBuTGVuIC0gYVMuTGVuKCkgKS5BcHBlbmQoIGFTICk7CgllbHNlCgkJcmV0dXJuIENVbmlTdHJpbmcoIiAiKS5BcHBlbmQoIGFTICk7Cn0KCgo=