LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiogQ29weXJpZ2h0IChDKSAyMDE1LTIwMTggYnkgU2F2b2lyLWZhaXJlIExpbnV4ICAgICAgICAgICAgICAgICAgICAgICAgICAgKgoqIEF1dGhvcjogRWRyaWMgTGFkZW50IE1pbGFyZXQgPGVkcmljLmxhZGVudC1taWxhcmV0QHNhdm9pcmZhaXJlbGludXguY29tPioKKiBBdXRob3I6IEFudGhvbnkgTOlvbmFyZCA8YW50aG9ueS5sZW9uYXJkQHNhdm9pcmZhaXJlbGludXguY29tPiAgICAgICAgICAqCiogQXV0aG9yOiBPbGl2aWVyIFNvbGRhbm8gPG9saXZpZXIuc29sZGFub0BzYXZvaXJmYWlyZWxpbnV4LmNvbT4gICAgICAgICAgKgoqIEF1dGhvcjogQW5kcmVhcyBUcmFjenlrIDxhbmRyZWFzLnRyYWN6eWtAc2F2b2lyZmFpcmVsaW51eC5jb20+ICAgICAgICAgICoKKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqCiogVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgICAgKgoqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5ICAgICoKKiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIgdmVyc2lvbiAzIG9mIHRoZSBMaWNlbnNlLCBvciAgICAgICAqCiogKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKgoqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICoKKiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgICAgICAgICAqCiogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgICAgICAgICAgKgoqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgICAgICAgICAgICoKKiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAqCiogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKgoqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlICAgICAgICoKKiBhbG9uZyB3aXRoIHRoaXMgcHJvZ3JhbS4gIElmIG5vdCwgc2VlIDxodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvPi4gICAqCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKI2luY2x1ZGUgIm5ld3dpemFyZHdpZGdldC5oIgojaW5jbHVkZSAidWlfbmV3d2l6YXJkd2lkZ2V0LmgiCgojaW5jbHVkZSA8UU1vdmllPgojaW5jbHVkZSA8UU1lc3NhZ2VCb3g+CiNpbmNsdWRlIDxRRmlsZURpYWxvZz4KI2luY2x1ZGUgPFFCaXRtYXA+CgojaW5jbHVkZSAibmFtZWRpcmVjdG9yeS5oIgoKI2luY2x1ZGUgInV0aWxzLmgiCiNpbmNsdWRlICJyaW5ndGhlbWV1dGlscy5oIgoKY29uc3QgUVN0cmluZyBERUZBVUxUX1JJTkdfQUNDVF9BTElBUyA9IFFPYmplY3Q6OnRyKCJKYW1pIGFjY291bnQiLCAiRGVmYXVsdCBhbGlhcyBmb3IgbmV3IEphbWkgYWNjb3VudCIpOwoKTmV3V2l6YXJkV2lkZ2V0OjpOZXdXaXphcmRXaWRnZXQoUVdpZGdldCogcGFyZW50KSA6CiAgICBOYXZXaWRnZXQocGFyZW50KSwKICAgIHVpKG5ldyBVaTo6TmV3V2l6YXJkV2lkZ2V0KSwKICAgIHdpemFyZE1vZGVfKFdpemFyZE1vZGU6OldJWkFSRCksCiAgICBsb29rdXBUaW1lcl8odGhpcykKewogICAgdWktPnNldHVwVWkodGhpcyk7CgogICAgUVBpeG1hcCBsb2dvKCI6L2ltYWdlcy9sb2dvLWphbWktc3RhbmRhcmQtY291bC5wbmciKTsKCiAgICB1aS0+d2VsY29tZUxvZ28tPnNldFBpeG1hcChsb2dvLnNjYWxlZFRvSGVpZ2h0KDEwMCwgUXQ6OlNtb290aFRyYW5zZm9ybWF0aW9uKSk7CiAgICB1aS0+d2VsY29tZUxvZ28tPnNldEFsaWdubWVudChRdDo6QWxpZ25IQ2VudGVyKTsKCiAgICBjcmVhdGlvblNwaW5uZXJNb3ZpZV8gPSBuZXcgUU1vdmllKCI6L2ltYWdlcy9qYW1pX2VjbGlwc2Vfc3Bpbm5lci5naWYiKTsKICAgIHVpLT5zcGlubmVyTGFiZWwtPnNldE1vdmllKGNyZWF0aW9uU3Bpbm5lck1vdmllXyk7CiAgICBjcmVhdGlvblNwaW5uZXJNb3ZpZV8tPnN0YXJ0KCk7CgogICAgbG9va3VwU3Bpbm5lck1vdmllXyA9IG5ldyBRTW92aWUoIjovaW1hZ2VzL2phbWlfcm9sbGluZ19zcGlubmVyLmdpZiIpOwogICAgbG9va3VwU3Bpbm5lck1vdmllXy0+c2V0U2NhbGVkU2l6ZShRU2l6ZSgzMCwgMzApKTsKCiAgICBsb29rdXBTdGF0dXNMYWJlbF8gPSBuZXcgUUxhYmVsKHRoaXMpOwogICAgbG9va3VwU3RhdHVzTGFiZWxfLT5zZXRNb3ZpZShsb29rdXBTcGlubmVyTW92aWVfKTsKICAgIGxvb2t1cFN0YXR1c0xhYmVsXy0+aGlkZSgpOwoKICAgIHJlZ2lzdHJhdGlvblN0YXRlT2tfID0gZmFsc2U7CgogICAgcGFzc3dvcmRTdGF0dXNMYWJlbF8gPSBuZXcgUUxhYmVsKHRoaXMpOwoKICAgIHN0YXR1c1N1Y2Nlc3NQaXhtYXBfID0gVXRpbHM6OmdlbmVyYXRlVGludGVkUGl4bWFwKCI6L2ltYWdlcy9pY29ucy9iYXNlbGluZS1kb25lLTI0cHguc3ZnIiwgUmluZ1RoZW1lOjpwcmVzZW5jZUdyZWVuXyk7CiAgICBzdGF0dXNJbnZhbGlkUGl4bWFwXyA9IFV0aWxzOjpnZW5lcmF0ZVRpbnRlZFBpeG1hcCgiOi9pbWFnZXMvaWNvbnMvYmFzZWxpbmUtZXJyb3Jfb3V0bGluZS0yNHB4LnN2ZyIsIFJpbmdUaGVtZTo6dXJnZW50T3JhbmdlXyk7CiAgICBzdGF0dXNFcnJvclBpeG1hcF8gPSBVdGlsczo6Z2VuZXJhdGVUaW50ZWRQaXhtYXAoIjovaW1hZ2VzL2ljb25zL2Jhc2VsaW5lLWNsb3NlLTI0cHguc3ZnIiwgUmluZ1RoZW1lOjpyZWRfKTsKCiAgICB1aS0+aW5mb1dpZGdldC0+aGlkZSgpOwogICAgc2V0TmF2QmFyVmlzaWJpbGl0eShmYWxzZSwgdHJ1ZSk7CgogICAgbG9va3VwVGltZXJfLnNldFNpbmdsZVNob3QodHJ1ZSk7CgogICAgY29ubmVjdCh1aS0+ZmlsZUltcG9ydEJ0biwgJlFQdXNoQnV0dG9uOjpjbGlja2VkLAogICAgICAgIFt0aGlzXSB7CiAgICAgICAgICAgIFFTdHJpbmcgZmlsZVBhdGg7CiAgICAgICAgICAgIGZpbGVQYXRoID0gUUZpbGVEaWFsb2c6OmdldE9wZW5GaWxlTmFtZSh0aGlzLAogICAgICAgICAgICAgICAgdHIoIk9wZW4gRmlsZSIpLAogICAgICAgICAgICAgICAgUVN0cmluZygpLAogICAgICAgICAgICAgICAgdHIoIkphbWkgYXJjaGl2ZSBmaWxlcyAoKi5neik7IEFsbCBmaWxlcyAoKikiKSk7CiAgICAgICAgICAgIGZpbGVUb0ltcG9ydF8gPSBRRGlyOjp0b05hdGl2ZVNlcGFyYXRvcnMoZmlsZVBhdGgpOwogICAgICAgICAgICBpZiAoIWZpbGVUb0ltcG9ydF8uaXNFbXB0eSgpKSB7CiAgICAgICAgICAgICAgICBRRmlsZUluZm8gZmkoZmlsZVBhdGgpOwogICAgICAgICAgICAgICAgdWktPmZpbGVJbXBvcnRCdG4tPnNldFRleHQoZmkuZmlsZU5hbWUoKSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICB1aS0+ZmlsZUltcG9ydEJ0bi0+c2V0VGV4dCh0cigiKE5vbmUpIikpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHZhbGlkYXRlV2l6YXJkUHJvZ3Jlc3Npb24oKTsKICAgICAgICB9KTsKCiAgICBjb25uZWN0KCZsb29rdXBUaW1lcl8sICZRVGltZXI6OnRpbWVvdXQsCiAgICAgICAgICAgIHRoaXMsICZOZXdXaXphcmRXaWRnZXQ6OnRpbWVvdXROYW1lTG9va3VwVGltZXIpOwoKICAgIGNvbm5lY3QodWktPmJhY2tCdXR0b24sICZRUHVzaEJ1dHRvbjo6Y2xpY2tlZCwKICAgICAgICBbdGhpc10gewogICAgICAgICAgICBlbWl0IE5hdmlnYXRpb25SZXF1ZXN0ZWQoU2NyZWVuRW51bTo6Q2FsbFNjcmVlbik7CiAgICAgICAgfSk7CgogICAgY29ubmVjdCh1aS0+Y29uZmlybVBhc3N3b3JkRWRpdCwgJlFMaW5lRWRpdDo6dGV4dENoYW5nZWQsCiAgICAgICAgW3RoaXNdIHsKICAgICAgICAgICAgdmFsaWRhdGVXaXphcmRQcm9ncmVzc2lvbigpOwogICAgICAgIH0pOwoKICAgIGNvbm5lY3QodWktPnBpbkVkaXQsICZRTGluZUVkaXQ6OnRleHRDaGFuZ2VkLAogICAgICAgIFt0aGlzXSB7CiAgICAgICAgICAgIHZhbGlkYXRlV2l6YXJkUHJvZ3Jlc3Npb24oKTsKICAgICAgICB9KTsKCiAgICB1aS0+Y29udGFpbmVyV2lkZ2V0LT5zZXRWaXNpYmxlKGZhbHNlKTsKfQoKTmV3V2l6YXJkV2lkZ2V0Ojp+TmV3V2l6YXJkV2lkZ2V0KCkKewogICAgZGVsZXRlIHVpOwp9Cgp2b2lkCk5ld1dpemFyZFdpZGdldDo6c2V0VG9NaWdyYXRlKEFjY291bnRJbmZvKiB0b0JlTWlncmF0ZWQpCnsKICAgIHdpemFyZE1vZGVfID0gTUlHUkFUSU9OOwogICAgY2hhbmdlUGFnZSh1aS0+Y3JlYXRlUmluZ0FjY291bnRQYWdlKTsKICAgIHVpLT51c2VybmFtZUVkaXQtPnNldEVuYWJsZWQoZmFsc2UpOwogICAgdWktPnVzZXJuYW1lRWRpdC0+c2V0VGV4dChRU3RyaW5nOjpmcm9tU3RkU3RyaW5nKHRvQmVNaWdyYXRlZC0+cHJvZmlsZUluZm8uYWxpYXMpKTsKICAgIHVpLT5wcmV2aW91c0J1dHRvbi0+aGlkZSgpOwogICAgdWktPmluZm9XaWRnZXQtPnNob3coKTsKICAgIHVpLT5pbmZvTGFiZWwtPnNldFRleHQodHIoIllvdXIgYWNjb3VudCBuZWVkcyB0byBiZSBtaWdyYXRlZC4gRW50ZXIgeW91ciBwYXNzd29yZC4iKSk7Cn0KCnZvaWQKTmV3V2l6YXJkV2lkZ2V0Ojp1cGRhdGVOYW1lUmVnaXN0cmF0aW9uVWkoTmFtZVJlZ2lzdHJhdGlvblVJU3RhdGUgc3RhdGUpCnsKICAgIHN3aXRjaCAoc3RhdGUpIHsKICAgIGNhc2UgTmFtZVJlZ2lzdHJhdGlvblVJU3RhdGU6OkJMQU5LOgogICAgICAgIGxvb2t1cFN0YXR1c0xhYmVsXy0+aGlkZSgpOwogICAgICAgIGJyZWFrOwogICAgY2FzZSBOYW1lUmVnaXN0cmF0aW9uVUlTdGF0ZTo6SU5WQUxJRDoKICAgICAgICBsb29rdXBTdGF0dXNMYWJlbF8tPnNldFBpeG1hcChzdGF0dXNJbnZhbGlkUGl4bWFwXyk7CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIE5hbWVSZWdpc3RyYXRpb25VSVN0YXRlOjpUQUtFTjoKICAgICAgICBsb29rdXBTdGF0dXNMYWJlbF8tPnNldFBpeG1hcChzdGF0dXNFcnJvclBpeG1hcF8pOwogICAgICAgIGJyZWFrOwogICAgY2FzZSBOYW1lUmVnaXN0cmF0aW9uVUlTdGF0ZTo6RlJFRToKICAgICAgICBsb29rdXBTdGF0dXNMYWJlbF8tPnNldFBpeG1hcChzdGF0dXNTdWNjZXNzUGl4bWFwXyk7CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIE5hbWVSZWdpc3RyYXRpb25VSVN0YXRlOjpTRUFSQ0hJTkc6CiAgICAgICAgbG9va3VwU3RhdHVzTGFiZWxfLT5zZXRNb3ZpZShsb29rdXBTcGlubmVyTW92aWVfKTsKICAgICAgICBsb29rdXBTcGlubmVyTW92aWVfLT5zdG9wKCk7CiAgICAgICAgbG9va3VwU3Bpbm5lck1vdmllXy0+c3RhcnQoKTsKICAgICAgICBsb29rdXBTdGF0dXNMYWJlbF8tPnNob3coKTsKICAgICAgICBicmVhazsKICAgIH0KfQoKdm9pZApOZXdXaXphcmRXaWRnZXQ6Om5hdmlnYXRlZChib29sIHRvKQp7CiAgICB1aS0+Y29udGFpbmVyV2lkZ2V0LT5zZXRWaXNpYmxlKHRvKTsKICAgIGNoYW5nZVBhZ2UodWktPndlbGNvbWVQYWdlKTsKICAgIFV0aWxzOjpzZXRTdGFja1dpZGdldCh1aS0+c3RhY2tlZFdpZGdldCwgdWktPndlbGNvbWVQYWdlKTsKfQoKdm9pZApOZXdXaXphcmRXaWRnZXQ6OnByb2Nlc3NXaXphcmRJbmZvcm1hdGlvbnMoKQp7CiAgICBpZiAod2l6YXJkTW9kZV8gPT0gTUlHUkFUSU9OKQogICAgICAgIHVpLT5wcm9ncmVzc0xhYmVsLT5zZXRUZXh0KHRyKCJNaWdyYXRpbmcgeW91ciBKYW1pIGFjY291bnQuLi4iKSk7CiAgICBlbHNlIGlmICh3aXphcmRNb2RlXyA9PSBJTVBPUlQpCiAgICAgICAgdWktPnByb2dyZXNzTGFiZWwtPnNldFRleHQodHIoIkltcG9ydGluZyBhY2NvdW50IGFyY2hpdmUuLi4iKSk7CiAgICBlbHNlCiAgICAgICAgdWktPnByb2dyZXNzTGFiZWwtPnNldFRleHQodHIoIkdlbmVyYXRpbmcgeW91ciBKYW1pIGFjY291bnQuLi4iKSk7CgogICAgaWYgKHdpemFyZE1vZGVfICE9IElNUE9SVCkgewogICAgICAgIFFTdHJpbmcgYWNjb3VudEFsaWFzID0gKHVpLT5mdWxsTmFtZUVkaXQtPnRleHQoKS5pc0VtcHR5KCkgfHwKICAgICAgICAgICAgdWktPmZ1bGxOYW1lRWRpdC0+dGV4dCgpLmlzTnVsbCgpKSA/IERFRkFVTFRfUklOR19BQ0NUX0FMSUFTIDogdWktPmZ1bGxOYW1lRWRpdC0+dGV4dCgpOwogICAgICAgIFFTdHJpbmcgYXJjaGl2ZVBpbiA9ICh1aS0+cGluRWRpdC0+dGV4dCgpLmlzRW1wdHkoKSB8fCB1aS0+cGluRWRpdC0+dGV4dCgpLmlzTnVsbCgpKSA/IFFTdHJpbmcoKSA6IHVpLT5waW5FZGl0LT50ZXh0KCk7CgogICAgICAgIGNoYW5nZVBhZ2UodWktPnNwaW5uZXJQYWdlKTsKICAgICAgICBjcmVhdGVSaW5nQWNjb3VudChhY2NvdW50QWxpYXMsIHVpLT5wYXNzd29yZEVkaXQtPnRleHQoKSwgYXJjaGl2ZVBpbiwgZmlsZVRvSW1wb3J0Xyk7CgogICAgICAgIHVpLT5wYXNzd29yZEVkaXQtPmNsZWFyKCk7CiAgICAgICAgdWktPmNvbmZpcm1QYXNzd29yZEVkaXQtPmNsZWFyKCk7CiAgICAgICAgdWktPnBpbkVkaXQtPmNsZWFyKCk7CiAgICB9CgogICAgVXRpbHM6OkNyZWF0ZVN0YXJ0dXBMaW5rKCk7Cn0KCnZvaWQKTmV3V2l6YXJkV2lkZ2V0Ojpvbl9leGlzdGluZ1B1c2hCdXR0b25fY2xpY2tlZCgpCnsKICAgIGNoYW5nZVBhZ2UodWktPmxpbmtSaW5nQWNjb3VudFBhZ2UpOwp9Cgp2b2lkCk5ld1dpemFyZFdpZGdldDo6b25fbmV3QWNjb3VudEJ1dHRvbl9jbGlja2VkKCkKewogICAgY2hhbmdlUGFnZSh1aS0+Y3JlYXRlUmluZ0FjY291bnRQYWdlKTsKfQoKdm9pZCBOZXdXaXphcmRXaWRnZXQ6OmNoYW5nZVBhZ2UoUVdpZGdldCogdG9QYWdlKQp7CiAgICBpZiAodG9QYWdlID09IHVpLT5zcGlubmVyUGFnZSkgewogICAgICAgIHNldE5hdkJhclZpc2liaWxpdHkoZmFsc2UpOwogICAgfQogICAgVXRpbHM6OnNldFN0YWNrV2lkZ2V0KHVpLT5zdGFja2VkV2lkZ2V0LCB0b1BhZ2UpOwogICAgaWYgKHRvUGFnZSA9PSB1aS0+d2VsY29tZVBhZ2UpIHsKICAgICAgICBzZXROYXZCYXJWaXNpYmlsaXR5KGZhbHNlLCB0cnVlKTsKICAgICAgICBsb29rdXBTdGF0dXNMYWJlbF8tPmhpZGUoKTsKICAgICAgICBwYXNzd29yZFN0YXR1c0xhYmVsXy0+aGlkZSgpOwogICAgfSBlbHNlIGlmICh0b1BhZ2UgPT0gdWktPmNyZWF0ZVJpbmdBY2NvdW50UGFnZSkgewogICAgICAgIHVpLT51c2VybmFtZUVkaXQtPmNsZWFyKCk7CiAgICAgICAgdWktPnBhc3N3b3JkRWRpdC0+Y2xlYXIoKTsKICAgICAgICB1aS0+Y29uZmlybVBhc3N3b3JkRWRpdC0+Y2xlYXIoKTsKICAgICAgICB1aS0+c2lnblVwQ2hlY2tib3gtPnNldENoZWNrZWQodHJ1ZSk7CiAgICAgICAgdWktPnVzZXJuYW1lRWRpdC0+c2V0RW5hYmxlZCh0cnVlKTsKICAgICAgICB1aS0+ZnVsbE5hbWVFZGl0LT5zZXRUZXh0KFV0aWxzOjpHZXRDdXJyZW50VXNlck5hbWUoKSk7CiAgICAgICAgc2V0TmF2QmFyVmlzaWJpbGl0eSh0cnVlKTsKICAgICAgICB1cGRhdGVDdXN0b21VSSgpOwogICAgICAgIHJlZ2lzdGVyZWROYW1lRm91bmRDb25uZWN0aW9uXyA9IGNvbm5lY3QoCiAgICAgICAgICAgICZMUkNJbnN0YW5jZTo6YWNjb3VudE1vZGVsKCksICZscmM6OmFwaTo6TmV3QWNjb3VudE1vZGVsOjpyZWdpc3RlcmVkTmFtZUZvdW5kLAogICAgICAgICAgICB0aGlzLCAmTmV3V2l6YXJkV2lkZ2V0OjpzbG90UmVnaXN0ZXJlZE5hbWVGb3VuZCk7CiAgICAgICAgdmFsaWRhdGVXaXphcmRQcm9ncmVzc2lvbigpOwogICAgICAgIHVpLT5zZXRBdmF0YXJXaWRnZXQtPnN0YXJ0Qm9vdGgoKTsKICAgIH0gZWxzZSBpZiAodG9QYWdlID09IHVpLT5saW5rUmluZ0FjY291bnRQYWdlKSB7CiAgICAgICAgZmlsZVRvSW1wb3J0XyA9IFFTdHJpbmcoIiIpOwogICAgICAgIHVpLT5maWxlSW1wb3J0QnRuLT5zZXRUZXh0KHRyKCIoTm9uZSkiKSk7CiAgICAgICAgdWktPnBpbkVkaXQtPmNsZWFyKCk7CiAgICAgICAgdWktPmltcG9ydFBhc3N3b3JkRWRpdC0+Y2xlYXIoKTsKICAgICAgICB1aS0+cGluRWRpdC0+c2V0RW5hYmxlZCh0cnVlKTsKICAgICAgICB1aS0+ZmlsZUltcG9ydEJ0bi0+c2V0RW5hYmxlZCh0cnVlKTsKICAgICAgICBzZXROYXZCYXJWaXNpYmlsaXR5KHRydWUpOwogICAgICAgIGxvb2t1cFN0YXR1c0xhYmVsXy0+aGlkZSgpOwogICAgICAgIHBhc3N3b3JkU3RhdHVzTGFiZWxfLT5oaWRlKCk7CiAgICAgICAgdmFsaWRhdGVXaXphcmRQcm9ncmVzc2lvbigpOwogICAgfSBlbHNlIGlmICh0b1BhZ2UgPT0gdWktPnNwaW5uZXJQYWdlKSB7CiAgICAgICAgbG9va3VwU3RhdHVzTGFiZWxfLT5oaWRlKCk7CiAgICAgICAgcGFzc3dvcmRTdGF0dXNMYWJlbF8tPmhpZGUoKTsKICAgIH0KfQoKdm9pZApOZXdXaXphcmRXaWRnZXQ6OnVwZGF0ZUN1c3RvbVVJKCkKewogICAgUVBvaW50IGVkaXRVc2VybmFtZVBvcyA9IHVpLT51c2VybmFtZUVkaXQtPm1hcFRvKHRoaXMsIHVpLT51c2VybmFtZUVkaXQtPnJlY3QoKS50b3BSaWdodCgpKTsKICAgIGxvb2t1cFN0YXR1c0xhYmVsXy0+c2V0R2VvbWV0cnkoZWRpdFVzZXJuYW1lUG9zLngoKSArIDYsIGVkaXRVc2VybmFtZVBvcy55KCkgLSAxLCAzMCwgMzApOwogICAgUVBvaW50IGVkaXRjb25mcGFzc1BvcyA9IHVpLT5jb25maXJtUGFzc3dvcmRFZGl0LT5tYXBUbyh0aGlzLCB1aS0+Y29uZmlybVBhc3N3b3JkRWRpdC0+cmVjdCgpLnRvcFJpZ2h0KCkpOwogICAgcGFzc3dvcmRTdGF0dXNMYWJlbF8tPnNldEdlb21ldHJ5KGVkaXRjb25mcGFzc1Bvcy54KCkgKyA2LCBlZGl0Y29uZnBhc3NQb3MueSgpIC0gMSwgMjQsIDI0KTsKfQoKdm9pZApOZXdXaXphcmRXaWRnZXQ6OnNldE5hdkJhclZpc2liaWxpdHkoYm9vbCBuYXYsIGJvb2wgYmFjaykKewogICAgdWktPm5hdkJhcldpZGdldC0+c2V0VmlzaWJsZShuYXYgfHwgYmFjayk7CiAgICB1aS0+bmV4dEJ1dHRvbi0+c2V0VmlzaWJsZShuYXYpOwogICAgdWktPnByZXZpb3VzQnV0dG9uLT5zZXRWaXNpYmxlKG5hdik7CiAgICB1aS0+YmFja0J1dHRvbi0+c2V0VmlzaWJsZShiYWNrICYmIExSQ0luc3RhbmNlOjphY2NvdW50TW9kZWwoKS5nZXRBY2NvdW50TGlzdCgpLnNpemUoKSk7Cn0KCnZvaWQKTmV3V2l6YXJkV2lkZ2V0Ojpvbl9uZXh0QnV0dG9uX2NsaWNrZWQoKQp7CiAgICBjb25zdCBRV2lkZ2V0KiBjdXJXaWRnZXQgPSB1aS0+c3RhY2tlZFdpZGdldC0+Y3VycmVudFdpZGdldCgpOwogICAgdWktPnNldEF2YXRhcldpZGdldC0+c3RvcEJvb3RoKCk7CiAgICBkaXNjb25uZWN0KHJlZ2lzdGVyZWROYW1lRm91bmRDb25uZWN0aW9uXyk7CiAgICBpZiAoY3VyV2lkZ2V0ID09IHVpLT5jcmVhdGVSaW5nQWNjb3VudFBhZ2UgfHwKICAgICAgICBjdXJXaWRnZXQgPT0gdWktPmxpbmtSaW5nQWNjb3VudFBhZ2UpIHsKICAgICAgICBwcm9jZXNzV2l6YXJkSW5mb3JtYXRpb25zKCk7CiAgICB9Cn0KCnZvaWQKTmV3V2l6YXJkV2lkZ2V0Ojpvbl9wcmV2aW91c0J1dHRvbl9jbGlja2VkKCkKewogICAgY29uc3QgUVdpZGdldCogY3VyV2lkZ2V0ID0gdWktPnN0YWNrZWRXaWRnZXQtPmN1cnJlbnRXaWRnZXQoKTsKICAgIHVpLT5zZXRBdmF0YXJXaWRnZXQtPnN0b3BCb290aCgpOwogICAgZGlzY29ubmVjdChyZWdpc3RlcmVkTmFtZUZvdW5kQ29ubmVjdGlvbl8pOwogICAgbG9va3VwU3RhdHVzTGFiZWxfLT5oaWRlKCk7CiAgICBwYXNzd29yZFN0YXR1c0xhYmVsXy0+aGlkZSgpOwogICAgaWYgKGN1cldpZGdldCA9PSB1aS0+Y3JlYXRlUmluZ0FjY291bnRQYWdlIHx8CiAgICAgICAgY3VyV2lkZ2V0ID09IHVpLT5saW5rUmluZ0FjY291bnRQYWdlKSB7CiAgICAgICAgY2hhbmdlUGFnZSh1aS0+d2VsY29tZVBhZ2UpOwogICAgfQp9Cgp2b2lkCk5ld1dpemFyZFdpZGdldDo6b25fcGFzc3dvcmRFZGl0X3RleHRDaGFuZ2VkKGNvbnN0IFFTdHJpbmcmIGFyZzEpCnsKICAgIFFfVU5VU0VEKGFyZzEpOwogICAgdmFsaWRhdGVXaXphcmRQcm9ncmVzc2lvbigpOwp9Cgp2b2lkCk5ld1dpemFyZFdpZGdldDo6b25fdXNlcm5hbWVFZGl0X3RleHRDaGFuZ2VkKGNvbnN0IFFTdHJpbmcgJmFyZzEpCnsKICAgIHJlZ2lzdHJhdGlvblN0YXRlT2tfID0gZmFsc2U7CiAgICBpZiAodWktPnNpZ25VcENoZWNrYm94LT5pc0NoZWNrZWQoKSAmJiAhYXJnMS5pc0VtcHR5KCkpIHsKICAgICAgICByZWdpc3RlcmVkTmFtZV8gPSB1aS0+dXNlcm5hbWVFZGl0LT50ZXh0KCkuc2ltcGxpZmllZCgpOwogICAgICAgIGxvb2t1cFRpbWVyXy5zdGFydCgyMDApOwogICAgfSBlbHNlIHsKICAgICAgICB1cGRhdGVOYW1lUmVnaXN0cmF0aW9uVWkoTmFtZVJlZ2lzdHJhdGlvblVJU3RhdGU6OkJMQU5LKTsKICAgICAgICBsb29rdXBUaW1lcl8uc3RvcCgpOwogICAgICAgIGlmICghYXJnMS5pc0VtcHR5KCkpIHsKICAgICAgICAgICAgbG9va3VwVGltZXJfLnN0YXJ0KDIwMCk7CiAgICAgICAgfQogICAgfQogICAgdmFsaWRhdGVXaXphcmRQcm9ncmVzc2lvbigpOwp9Cgp2b2lkCk5ld1dpemFyZFdpZGdldDo6dGltZW91dE5hbWVMb29rdXBUaW1lcigpCnsKICAgIGlmICh1aS0+c2lnblVwQ2hlY2tib3gtPmlzQ2hlY2tlZCgpICYmICF1aS0+dXNlcm5hbWVFZGl0LT50ZXh0KCkuaXNFbXB0eSgpKSB7CiAgICAgICAgdXBkYXRlTmFtZVJlZ2lzdHJhdGlvblVpKE5hbWVSZWdpc3RyYXRpb25VSVN0YXRlOjpTRUFSQ0hJTkcpOwogICAgICAgIE5hbWVEaXJlY3Rvcnk6Omluc3RhbmNlKCkubG9va3VwTmFtZShudWxscHRyLCBRU3RyaW5nKCksIHJlZ2lzdGVyZWROYW1lXyk7CiAgICB9Cn0KCnZvaWQKTmV3V2l6YXJkV2lkZ2V0OjpzbG90UmVnaXN0ZXJlZE5hbWVGb3VuZChjb25zdCBzdGQ6OnN0cmluZyYgYWNjb3VudElkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExvb2t1cFN0YXR1cyBzdGF0dXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RkOjpzdHJpbmcmIGFkZHJlc3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RkOjpzdHJpbmcmIG5hbWUpCnsKICAgIFFfVU5VU0VEKGFjY291bnRJZCk7CiAgICBRX1VOVVNFRChhZGRyZXNzKTsKCiAgICB1c2luZyBuYW1lc3BhY2UgbHJjOjphcGk6OmFjY291bnQ7CiAgICBpZiAobmFtZS5sZW5ndGgoKSA8IDMpIHsKICAgICAgICByZWdpc3RyYXRpb25TdGF0ZU9rXyA9IGZhbHNlOwogICAgICAgIHVwZGF0ZU5hbWVSZWdpc3RyYXRpb25VaShOYW1lUmVnaXN0cmF0aW9uVUlTdGF0ZTo6SU5WQUxJRCk7CiAgICB9IGVsc2UgaWYgKHJlZ2lzdGVyZWROYW1lXy50b1N0ZFN0cmluZygpID09IG5hbWUpIHsKICAgICAgICBzd2l0Y2ggKHN0YXR1cykgewogICAgICAgIGNhc2UgTG9va3VwU3RhdHVzOjpOT1RfRk9VTkQ6CiAgICAgICAgY2FzZSBMb29rdXBTdGF0dXM6OkVSUk9SOgogICAgICAgICAgICByZWdpc3RyYXRpb25TdGF0ZU9rXyA9IHRydWU7CiAgICAgICAgICAgIHVwZGF0ZU5hbWVSZWdpc3RyYXRpb25VaShOYW1lUmVnaXN0cmF0aW9uVUlTdGF0ZTo6RlJFRSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgTG9va3VwU3RhdHVzOjpJTlZBTElEX05BTUU6CiAgICAgICAgY2FzZSBMb29rdXBTdGF0dXM6OklOVkFMSUQ6CiAgICAgICAgICAgIHJlZ2lzdHJhdGlvblN0YXRlT2tfID0gZmFsc2U7CiAgICAgICAgICAgIHVwZGF0ZU5hbWVSZWdpc3RyYXRpb25VaShOYW1lUmVnaXN0cmF0aW9uVUlTdGF0ZTo6SU5WQUxJRCk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgTG9va3VwU3RhdHVzOjpTVUNDRVNTOgogICAgICAgICAgICByZWdpc3RyYXRpb25TdGF0ZU9rXyA9IGZhbHNlOwogICAgICAgICAgICB1cGRhdGVOYW1lUmVnaXN0cmF0aW9uVWkoTmFtZVJlZ2lzdHJhdGlvblVJU3RhdGU6OlRBS0VOKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgfQogICAgdmFsaWRhdGVXaXphcmRQcm9ncmVzc2lvbigpOwp9Cgp2b2lkCk5ld1dpemFyZFdpZGdldDo6aGFuZGxlX25hbWVSZWdpc3RyYXRpb25FbmRlZChOYW1lRGlyZWN0b3J5OjpSZWdpc3Rlck5hbWVTdGF0dXMgc3RhdHVzLCBjb25zdCBRU3RyaW5nJiBuYW1lKQp7CiAgICBRX1VOVVNFRChuYW1lKTsKICAgIFFfVU5VU0VEKHN0YXR1cyk7Cn0KCnZvaWQKTmV3V2l6YXJkV2lkZ2V0Ojpvbl9zaWduVXBDaGVja2JveF90b2dnbGVkKGJvb2wgY2hlY2tlZCkKewogICAgaWYgKGNoZWNrZWQpIHsKICAgICAgICB1aS0+dXNlcm5hbWVFZGl0LT5zZXRFbmFibGVkKHRydWUpOwogICAgfSBlbHNlIHsKICAgICAgICB1aS0+dXNlcm5hbWVFZGl0LT5zZXRFbmFibGVkKGZhbHNlKTsKICAgICAgICB1aS0+dXNlcm5hbWVFZGl0LT5jbGVhcigpOwogICAgfQogICAgdmFsaWRhdGVXaXphcmRQcm9ncmVzc2lvbigpOwp9Cgp2b2lkCk5ld1dpemFyZFdpZGdldDo6dmFsaWRhdGVXaXphcmRQcm9ncmVzc2lvbigpCnsKICAgIGlmICh1aS0+c3RhY2tlZFdpZGdldC0+Y3VycmVudFdpZGdldCgpID09IHVpLT5saW5rUmluZ0FjY291bnRQYWdlKSB7CiAgICAgICAgYm9vbCB2YWxpZFBpbiA9ICF1aS0+cGluRWRpdC0+dGV4dCgpLmlzRW1wdHkoKTsKICAgICAgICB1aS0+ZmlsZUltcG9ydEJ0bi0+c2V0RW5hYmxlZCghdmFsaWRQaW4pOwogICAgICAgIHVpLT5maWxlSW1wb3J0TGFiZWwtPnNldEVuYWJsZWQoIXZhbGlkUGluKTsKICAgICAgICBib29sIHZhbGlkSW1wb3J0ID0gIWZpbGVUb0ltcG9ydF8uaXNFbXB0eSgpOwogICAgICAgIHVpLT5waW5FZGl0LT5zZXRFbmFibGVkKCF2YWxpZEltcG9ydCk7CiAgICAgICAgdWktPnBpbkVkaXRMYWJlbC0+c2V0RW5hYmxlZCghdmFsaWRJbXBvcnQpOwogICAgICAgIHVpLT5uZXh0QnV0dG9uLT5zZXRFbmFibGVkKHZhbGlkUGluIHx8IHZhbGlkSW1wb3J0KTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBib29sIHVzZXJuYW1lT2sgPQogICAgICAgICF1aS0+c2lnblVwQ2hlY2tib3gtPmlzQ2hlY2tlZCgpIHx8CiAgICAgICAgKHVpLT5zaWduVXBDaGVja2JveC0+aXNDaGVja2VkKCkgJiYKICAgICAgICAgIXJlZ2lzdGVyZWROYW1lXy5pc0VtcHR5KCkgJiYKICAgICAgICAgKHJlZ2lzdGVyZWROYW1lXyA9PSB1aS0+dXNlcm5hbWVFZGl0LT50ZXh0KCkpICYmCiAgICAgICAgIHJlZ2lzdHJhdGlvblN0YXRlT2tfID09IHRydWUpOwogICAgYm9vbCBwYXNzd29yZE9rID0gdWktPnBhc3N3b3JkRWRpdC0+dGV4dCgpID09IHVpLT5jb25maXJtUGFzc3dvcmRFZGl0LT50ZXh0KCk7CiAgICBpZiAocGFzc3dvcmRPayAmJiAhdWktPnBhc3N3b3JkRWRpdC0+dGV4dCgpLmlzRW1wdHkoKSkgewogICAgICAgIHBhc3N3b3JkU3RhdHVzTGFiZWxfLT5zaG93KCk7CiAgICAgICAgcGFzc3dvcmRTdGF0dXNMYWJlbF8tPnNldFBpeG1hcChzdGF0dXNTdWNjZXNzUGl4bWFwXyk7CiAgICB9IGVsc2UgaWYgKCFwYXNzd29yZE9rKSB7CiAgICAgICAgcGFzc3dvcmRTdGF0dXNMYWJlbF8tPnNob3coKTsKICAgICAgICBwYXNzd29yZFN0YXR1c0xhYmVsXy0+c2V0UGl4bWFwKHN0YXR1c0Vycm9yUGl4bWFwXyk7CiAgICB9IGVsc2UgewogICAgICAgIHBhc3N3b3JkU3RhdHVzTGFiZWxfLT5oaWRlKCk7CiAgICB9CiAgICB1aS0+bmV4dEJ1dHRvbi0+c2V0RW5hYmxlZCh1c2VybmFtZU9rICYmIHBhc3N3b3JkT2spOwp9Cgp2b2lkCk5ld1dpemFyZFdpZGdldDo6Y3JlYXRlUmluZ0FjY291bnQoY29uc3QgUVN0cmluZyAmZGlzcGxheU5hbWUsCiAgICBjb25zdCBRU3RyaW5nICZwYXNzd29yZCwKICAgIGNvbnN0IFFTdHJpbmcgJnBpbiwKICAgIGNvbnN0IFFTdHJpbmcgJmFyY2hpdmVQYXRoKQp7CiAgICBVdGlsczo6b25lU2hvdENvbm5lY3QoJkxSQ0luc3RhbmNlOjphY2NvdW50TW9kZWwoKSwgJmxyYzo6YXBpOjpOZXdBY2NvdW50TW9kZWw6OmFjY291bnRBZGRlZCwKICAgICAgICBbdGhpc10oY29uc3Qgc3RkOjpzdHJpbmcmIGFjY291bnRJZCkgewogICAgICAgICAgICAvL3NldCBkZWZhdWx0IHJpbmd0b25lCiAgICAgICAgICAgIGF1dG8gY29uZlByb3BzID0gTFJDSW5zdGFuY2U6OmFjY291bnRNb2RlbCgpLmdldEFjY291bnRDb25maWcoYWNjb3VudElkKTsKICAgICAgICAgICAgY29uZlByb3BzLlJpbmd0b25lLnJpbmd0b25lUGF0aCA9IFV0aWxzOjpHZXRSaW5ndG9uZVBhdGgoKS50b1N0ZFN0cmluZygpOwogICAgICAgICAgICBMUkNJbnN0YW5jZTo6YWNjb3VudE1vZGVsKCkuc2V0QWNjb3VudENvbmZpZyhhY2NvdW50SWQsIGNvbmZQcm9wcyk7CiAgICAgICAgICAgIGNvbm5lY3QoTFJDSW5zdGFuY2U6OmVkaXRhYmxlQWNjb3VudE1vZGVsKCksCiAgICAgICAgICAgICAgICAmbHJjOjphcGk6Ok5ld0FjY291bnRNb2RlbDo6bmFtZVJlZ2lzdHJhdGlvbkVuZGVkLAogICAgICAgICAgICAgICAgW3RoaXNdIHsKICAgICAgICAgICAgICAgICAgICBscmM6OmFwaTo6YWNjb3VudDo6Q29uZlByb3BlcnRpZXNfdCBhY2NvdW50UHJvcGVydGllcyA9IExSQ0luc3RhbmNlOjphY2NvdW50TW9kZWwoKS5nZXRBY2NvdW50Q29uZmlnKExSQ0luc3RhbmNlOjpnZXRDdXJyQWNjSWQoKSk7CiAgICAgICAgICAgICAgICAgICAgTFJDSW5zdGFuY2U6OmFjY291bnRNb2RlbCgpLnNldEFjY291bnRDb25maWcoTFJDSW5zdGFuY2U6OmdldEN1cnJBY2NJZCgpLCBhY2NvdW50UHJvcGVydGllcyk7CiAgICAgICAgICAgICAgICAgICAgZW1pdCBOYXZpZ2F0aW9uUmVxdWVzdGVkKFNjcmVlbkVudW06OkNhbGxTY3JlZW4pOwogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIExSQ0luc3RhbmNlOjplZGl0YWJsZUFjY291bnRNb2RlbCgpLT5yZWdpc3Rlck5hbWUoCiAgICAgICAgICAgICAgICBMUkNJbnN0YW5jZTo6Z2V0Q3VyckFjY0lkKCksCiAgICAgICAgICAgICAgICAiIiwKICAgICAgICAgICAgICAgIHJlZ2lzdGVyZWROYW1lXy50b1N0ZFN0cmluZygpCiAgICAgICAgICAgICk7CiAgICAgICAgICAgIGlmICh1aS0+c2V0QXZhdGFyV2lkZ2V0LT5oYXNBdmF0YXIoKSkgewogICAgICAgICAgICAgICAgTFJDSW5zdGFuY2U6OnNldEN1cnJBY2NBdmF0YXIodWktPnNldEF2YXRhcldpZGdldC0+Z2V0QXZhdGFyUGl4bWFwKCkpOwogICAgICAgICAgICB9CiAgICAgICAgfSk7CiAgICBRdENvbmN1cnJlbnQ6OnJ1bigKICAgICAgICBbPV0gewogICAgICAgICAgICBMUkNJbnN0YW5jZTo6YWNjb3VudE1vZGVsKCkuY3JlYXRlTmV3QWNjb3VudCgKICAgICAgICAgICAgICAgIGxyYzo6YXBpOjpwcm9maWxlOjpUeXBlOjpSSU5HLAogICAgICAgICAgICAgICAgZGlzcGxheU5hbWUudG9TdGRTdHJpbmcoKSwKICAgICAgICAgICAgICAgIGFyY2hpdmVQYXRoLnRvU3RkU3RyaW5nKCksCiAgICAgICAgICAgICAgICBwYXNzd29yZC50b1N0ZFN0cmluZygpLAogICAgICAgICAgICAgICAgcGluLnRvU3RkU3RyaW5nKCkKICAgICAgICAgICAgKTsKICAgICAgICB9KTsKICAgIGNoYW5nZVBhZ2UodWktPnNwaW5uZXJQYWdlKTsKICAgIHJlcGFpbnQoKTsKfQ==