LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIAogKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCiAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoaXMgd29yayBmb3IgYWRkaXRpb25hbCBpbmZvcm1hdGlvbgogKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCiAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKICogIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZQogKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqIAogKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKiAKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLAogKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgogKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKICogS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlCiAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKICogdW5kZXIgdGhlIExpY2Vuc2UuCiAqIAogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCgoKLy8gTUFSS0VSKHVwZGF0ZV9wcmVjb21wLnB5KTogYXV0b2dlbiBpbmNsdWRlIHN0YXRlbWVudCwgZG8gbm90IHJlbW92ZQojaW5jbHVkZSAicHJlY29tcGlsZWRfYXV0b21hdGlvbi5oeHgiCgojaWYgT1NMX0RFQlVHX0xFVkVMID4gMQojaW5jbHVkZSA8dmNsL3N2YXBwLmh4eD4KI2luY2x1ZGUgImVkaXR3aW4uaHh4IgoKCmNsYXNzIEltcFdvcmtXaW5kb3cgOiBwdWJsaWMgV29ya1dpbmRvdwp7CnB1YmxpYzoKCU11bHRpTGluZUVkaXQJbV9hSW5oYWx0OwoJSW1wV29ya1dpbmRvdyggV29ya1dpbmRvdyAqcFBhcmVudCwgY29uc3QgVW5pU3RyaW5nICZyTmFtZSwgV2luQml0cyApOwoJfkltcFdvcmtXaW5kb3coKTsKCXZvaWQgUmVzaXplKCk7Cn07CgpJbXBXb3JrV2luZG93OjpJbXBXb3JrV2luZG93KCBXb3JrV2luZG93ICpwUGFyZW50LCBjb25zdCBTdHJpbmcgJnJOYW1lLCBXaW5CaXRzIGlXc3R5bGUgKQo6IFdvcmtXaW5kb3coIHBQYXJlbnQgLCBXQl9TSVpFTU9WRSApCiwgbV9hSW5oYWx0KCB0aGlzLCBpV3N0eWxlICkKewoJbV9hSW5oYWx0LlNob3coKTsKCVNldFRleHQock5hbWUpOwoJU2V0UG9zU2l6ZVBpeGVsKCBQb2ludCggMSw0MCApLCBTaXplKDUwMCwxNTApICk7CglSZXNpemUoKTsKfQoKSW1wV29ya1dpbmRvdzo6fkltcFdvcmtXaW5kb3coKQp7CglIaWRlKCk7Cn0KCnZvaWQgSW1wV29ya1dpbmRvdzo6UmVzaXplKCkKewoJbV9hSW5oYWx0LlNldFBvc1NpemVQaXhlbCggUG9pbnQoKSwgR2V0T3V0cHV0U2l6ZVBpeGVsKCkgKTsKfQoKc2FsX0Jvb2wgRWRpdFdpbmRvdzo6Q2xvc2UoKQp7CglpZiAoIHBJbXBXb3JrV2luZG93ICkKCXsKCQlkZWxldGUgcEltcFdvcmtXaW5kb3c7CgkJcEltcFdvcmtXaW5kb3cgPSBOVUxMOwoJfQoJcmV0dXJuIHNhbF9UcnVlOwp9Cgp2b2lkIEVkaXRXaW5kb3c6OlNob3coKQp7CglpZiAoIENoZWNrKCkgKQoJCXBJbXBXb3JrV2luZG93LT5TaG93KCk7CgllbHNlCgkJYlNob3dXaW4gPSBzYWxfVHJ1ZTsKfQoKdm9pZCBFZGl0V2luZG93OjpIaWRlKCkKewoJaWYgKCBDaGVjaygpICkKCQlwSW1wV29ya1dpbmRvdy0+SGlkZSgpOwoJZWxzZQoJCWJTaG93V2luID0gc2FsX0ZhbHNlOwp9CgpFZGl0V2luZG93OjpFZGl0V2luZG93KCBXb3JrV2luZG93ICpwUGFyZW50LCBjb25zdCBTdHJpbmcgJnJOYW1lLCBXaW5CaXRzIGlXc3R5bGUgKQo6IHBJbXBXb3JrV2luZG93KE5VTEwpCiwgcE1lbVBhcmVudChwUGFyZW50KQosIGFNZW1OYW1lKHJOYW1lKQosIGlNZW1Xc3R5bGUoaVdzdHlsZSkKLCBuVGV4dExlbigwKQosIGJRdWlldChzYWxfRmFsc2UpCnsKfQoKRWRpdFdpbmRvdzo6fkVkaXRXaW5kb3coKQp7CglDbG9zZSgpOwp9CgpzYWxfQm9vbCBFZGl0V2luZG93OjpDaGVjaygpCnsKCWlmICggISBwSW1wV29ya1dpbmRvdyAmJiBBcHBsaWNhdGlvbjo6SXNJbkV4ZWN1dGUoKSApCgl7CgkJcEltcFdvcmtXaW5kb3cgPSBuZXcgSW1wV29ya1dpbmRvdyggcE1lbVBhcmVudCwgYU1lbU5hbWUsIGlNZW1Xc3R5bGUgICk7CgkJcEltcFdvcmtXaW5kb3ctPm1fYUluaGFsdC5TZXRUZXh0KCBhTWVtUHJlV2luVGV4dCApOwoJCW5UZXh0TGVuID0gYU1lbVByZVdpblRleHQuTGVuKCk7CgkJYU1lbVByZVdpblRleHQuRXJhc2UoKTsKCQlpZiAoIGJTaG93V2luICkKCQkJcEltcFdvcmtXaW5kb3ctPlNob3coKTsKCQlyZXR1cm4gc2FsX1RydWU7Cgl9CglyZXR1cm4gcEltcFdvcmtXaW5kb3cgIT0gTlVMTDsKfQoKdm9pZCBFZGl0V2luZG93OjpDbGVhcigpCnsKCWlmICggQ2hlY2soKSApCgl7CgkJcEltcFdvcmtXaW5kb3ctPm1fYUluaGFsdC5TZXRUZXh0KCBTdHJpbmcoKSApOwoJCW5UZXh0TGVuID0gMDsKCX0KCWFNZW1QcmVXaW5UZXh0LkVyYXNlKCk7Cn0KCnZvaWQgRWRpdFdpbmRvdzo6QWRkVGV4dCggY29uc3Qgc2FsX0NoYXIqIHJOZXcgKQp7CglBZGRUZXh0KCBVbmlTdHJpbmc6OkNyZWF0ZUZyb21Bc2NpaSggck5ldyApICk7Cn0KCnZvaWQgRWRpdFdpbmRvdzo6QWRkVGV4dCggY29uc3QgU3RyaW5nICZyTmV3ICkKewoJaWYgKCBiUXVpZXQgKSByZXR1cm47CgoJU3RyaW5nIGFUZXh0ID0gck5ldzsKCWFUZXh0LkNvbnZlcnRMaW5lRW5kKCk7CgoJaWYgKCBDaGVjaygpICkKCXsKCQlpZiAoIG5UZXh0TGVuID4gNTAwMCApCgkJewoJCQlwSW1wV29ya1dpbmRvdy0+bV9hSW5oYWx0LlNldFRleHQoIHBJbXBXb3JrV2luZG93LT5tX2FJbmhhbHQuR2V0VGV4dCgpLkVyYXNlKDAsMTAwMCkgKTsKCQkJblRleHRMZW4gPSBwSW1wV29ya1dpbmRvdy0+bV9hSW5oYWx0LkdldFRleHQoKS5MZW4oKTsJCS8vIEFic29sdXQsIHVtIEZlaGxlciBzb25zdHdvIGF1c3p1YvxnZWxuCgkJfQoKCgkJcEltcFdvcmtXaW5kb3ctPm1fYUluaGFsdC5TZXRTZWxlY3Rpb24oIFNlbGVjdGlvbiggU0VMRUNUSU9OX01BWCwgU0VMRUNUSU9OX01BWCApICk7CgkJcEltcFdvcmtXaW5kb3ctPm1fYUluaGFsdC5SZXBsYWNlU2VsZWN0ZWQoIGFUZXh0ICk7CgkJblRleHRMZW4gPSBuVGV4dExlbiArIGFUZXh0LkxlbigpOwoJCXBJbXBXb3JrV2luZG93LT5tX2FJbmhhbHQuU2V0U2VsZWN0aW9uKCBTZWxlY3Rpb24oIFNFTEVDVElPTl9NQVgsIFNFTEVDVElPTl9NQVggKSApOwoJfQoJZWxzZQoJewoJCWFNZW1QcmVXaW5UZXh0ICs9IGFUZXh0OwoJfQp9CgojZW5kaWYKCg==