LyoKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICoKKiBDT1BZUklHSFQ6ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICoKKiAgIChDKSBDb3B5cmlnaHQgVGFsaWdlbnQsIEluYy4sICAxOTk2ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICoKKiAgIChDKSBDb3B5cmlnaHQgSW50ZXJuYXRpb25hbCBCdXNpbmVzcyBNYWNoaW5lcyBDb3Jwb3JhdGlvbiwgIDE5OTYtMTk5OCAgICAgICAgICAgICAgICoKKiAgIExpY2Vuc2VkIE1hdGVyaWFsIC0gUHJvZ3JhbS1Qcm9wZXJ0eSBvZiBJQk0gLSBBbGwgUmlnaHRzIFJlc2VydmVkLiAgICAgICAgICAgICAgICAgICoKKiAgIFVTIEdvdmVybm1lbnQgVXNlcnMgUmVzdHJpY3RlZCBSaWdodHMgLSBVc2UsIGR1cGxpY2F0aW9uLCBvciBkaXNjbG9zdXJlICAgICAgICAgICAgICoKKiAgIHJlc3RyaWN0ZWQgYnkgR1NBIEFEUCBTY2hlZHVsZSBDb250cmFjdCB3aXRoIElCTSBDb3JwLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICoKKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICoKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKi8KLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQovLwovLyBGaWxlIGNvbGVpdHIuY3BwCi8vCi8vIAovLwovLyBDcmVhdGVkIGJ5OiBIZWxlbmEgU2hpaAovLwovLyBNb2RpZmljYXRpb24gSGlzdG9yeToKLy8KLy8gIERhdGUgICAgICAgICBOYW1lICAgICAgICAgIERlc2NyaXB0aW9uCi8vCi8vICA2LzIzLzk3ICAgICBoZWxlbmEgICAgICBBZGRpbmcgY29tbWVudHMgdG8gbWFrZSBjb2RlIG1vcmUgcmVhZGFibGUuCi8vIDA4LzAzLzk4ICAgICBlcm0gICAgICAgICBTeW5jaGVkIHdpdGggMS4yIHZlcnNpb24gb2YgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yLmphdmEKLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKI2luY2x1ZGUgInNvcnRrZXkuaCIKI2luY2x1ZGUgImNvbGVpdHIuaCIKCiNpbmNsdWRlICJjaGFyaXRlci5oIgojaW5jbHVkZSAidGFibGVzLmgiCiNpbmNsdWRlICJub3JtbHpyLmgiCiNpbmNsdWRlICJ1bmljb2RlLmgiCgppbnQzMl90IGNvbnN0IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6TlVMTE9SREVSID0gMHhmZmZmZmZmZjsKaW50MzJfdCBjb25zdCBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6OlVOTUFQUEVEQ0hBUlZBTFVFID0gMHg3ZmZmMDAwMDsKCgovLyBUaGlzIHByaXZhdGUgbWV0aG9kIHdpbGwgbmV2ZXIgYmUgY2FsbGVkLCBidXQgaXQgbWFrZXMgdGhlIGxpbmtlciBoYXBweQoKQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IoKQo6IGV4cEluZGV4KDApLAogIHRleHQoMCksCiAgc3dhcE9yZGVyKDApLAogIGJ1ZmZlckFsaWFzKDApLAogIG9yZGVyQWxpYXMoMCkKewp9CgovLyBUaGlzIHByaXZhdGUgbWV0aG9kIHdpbGwgbmV2ZXIgYmUgY2FsbGVkLCBidXQgaXQgbWFrZXMgdGhlIGxpbmtlciBoYXBweQoKQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IoY29uc3QgUnVsZUJhc2VkQ29sbGF0b3IqIG9yZGVyKQo6IGV4cEluZGV4KDApLAogIHRleHQoMCksCiAgYnVmZmVyQWxpYXMoMCksCiAgc3dhcE9yZGVyKDApLAogIG9yZGVyQWxpYXMob3JkZXIpCnsKfQoKLy8gVGhpcyBpcyB0aGUgInJlYWwiIGNvbnN0cnVjdG9yIGZvciB0aGlzIGNsYXNzOyBpdCBjb25zdHJ1Y3RzIGFuIGl0ZXJhdG9yCi8vIG92ZXIgdGhlIHNvdXJjZSB0ZXh0IHVzaW5nIHRoZSBzcGVjaWZpZWQgY29sbGF0b3IKQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IoIGNvbnN0IFVuaWNvZGVTdHJpbmcmIHNvdXJjZVRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBSdWxlQmFzZWRDb2xsYXRvciogb3JkZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiBzdGF0dXMpIAo6IGV4cEluZGV4KDApLCAKICBzd2FwT3JkZXIoMCksCiAgdGV4dChOVUxMKSwKICBidWZmZXJBbGlhcyhOVUxMKSwKICBvcmRlckFsaWFzKG9yZGVyKQp7CiAgICBpZiAoRkFJTFVSRShzdGF0dXMpKSB7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIGlmICggc291cmNlVGV4dC5zaXplKCkgIT0gMCApIHsKICAgICAgICAvLwogICAgICAgIC8vIEEgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yIGlzIHJlYWxseSBhIHR3by1sYXllcmVkIGJlYXN0LgogICAgICAgIC8vIEludGVybmFsbHkgaXQgdXNlcyBhIE5vcm1hbGl6ZXIgdG8gbXVuZ2UgdGhlIHNvdXJjZSB0ZXh0CiAgICAgICAgLy8gaW50byBhIGZvcm0gd2hlcmUgYWxsICJjb21wb3NlZCIgVW5pY29kZSBjaGFyYWN0ZXJzIChzdWNoIGFzIPwpIGFyZQogICAgICAgIC8vIHNwbGl0IGludG8gYSBub3JtYWwgY2hhcmFjdGVyIGFuZCBhIGNvbWJpbmluZyBhY2NlbnQgY2hhcmFjdGVyLiAgCiAgICAgICAgLy8gQWZ0ZXJ3YXJkLCBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IgZG9lcyBpdHMgb3duIHByb2Nlc3NpbmcgdG8gaGFuZGxlCiAgICAgICAgLy8gZXhwYW5kaW5nIGFuZCBjb250cmFjdGluZyBjb2xsYXRpb24gc2VxdWVuY2VzLCBpZ25vcmFibGVzLCBhbmQgc28gb24uCiAgICAgICAgLy8KICAgICAgTm9ybWFsaXplcjo6RU1vZGUgZGVjb21wID0gKG9yZGVyLT5nZXRTdHJlbmd0aCgpID09IENvbGxhdG9yOjpJREVOVElDQUwpCiAgICA/IE5vcm1hbGl6ZXI6Ok5PX09QCiAgICA6IG9yZGVyLT5nZXREZWNvbXBvc2l0aW9uKCk7CiAgICAgIAogICAgICB0ZXh0ID0gbmV3IE5vcm1hbGl6ZXIoc291cmNlVGV4dCwgZGVjb21wKTsKICAgICAgaWYgKHRleHQgPT0gTlVMTCkgewogICAgc3RhdHVzID0gTUVNT1JZX0FMTE9DQVRJT05fRVJST1I7CiAgICAgIH0KICAgIH0KfQoKCi8vIFRoaXMgaXMgdGhlICJyZWFsIiBjb25zdHJ1Y3RvciBmb3IgdGhpcyBjbGFzczsgaXQgY29uc3RydWN0cyBhbiBpdGVyYXRvcgovLyBvdmVyIHRoZSBzb3VyY2UgdGV4dCB1c2luZyB0aGUgc3BlY2lmaWVkIGNvbGxhdG9yCkNvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6Q29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yKCBjb25zdCBDaGFyYWN0ZXJJdGVyYXRvciYgc291cmNlVGV4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFJ1bGVCYXNlZENvbGxhdG9yKiBvcmRlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cykgCjogZXhwSW5kZXgoMCksIAogIHN3YXBPcmRlcigwKSwKICB0ZXh0KE5VTEwpLAogIGJ1ZmZlckFsaWFzKE5VTEwpLAogIG9yZGVyQWxpYXMob3JkZXIpCnsKICAgIGlmIChGQUlMVVJFKHN0YXR1cykpIHsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgLy8gKioqKiBzaG91bGQgSSBqdXN0IGRyb3AgdGhpcyB0ZXN0PyAqKioqCiAgICBpZiAoIHNvdXJjZVRleHQuZW5kSW5kZXgoKSAhPSAwICkKICAgIHsKICAgICAgICAvLwogICAgICAgIC8vIEEgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yIGlzIHJlYWxseSBhIHR3by1sYXllcmVkIGJlYXN0LgogICAgICAgIC8vIEludGVybmFsbHkgaXQgdXNlcyBhIE5vcm1hbGl6ZXIgdG8gbXVuZ2UgdGhlIHNvdXJjZSB0ZXh0CiAgICAgICAgLy8gaW50byBhIGZvcm0gd2hlcmUgYWxsICJjb21wb3NlZCIgVW5pY29kZSBjaGFyYWN0ZXJzIChzdWNoIGFzIPwpIGFyZQogICAgICAgIC8vIHNwbGl0IGludG8gYSBub3JtYWwgY2hhcmFjdGVyIGFuZCBhIGNvbWJpbmluZyBhY2NlbnQgY2hhcmFjdGVyLiAgCiAgICAgICAgLy8gQWZ0ZXJ3YXJkLCBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IgZG9lcyBpdHMgb3duIHByb2Nlc3NpbmcgdG8gaGFuZGxlCiAgICAgICAgLy8gZXhwYW5kaW5nIGFuZCBjb250cmFjdGluZyBjb2xsYXRpb24gc2VxdWVuY2VzLCBpZ25vcmFibGVzLCBhbmQgc28gb24uCiAgICAgICAgLy8KICAgICAgTm9ybWFsaXplcjo6RU1vZGUgZGVjb21wID0gb3JkZXItPmdldFN0cmVuZ3RoKCkgPT0gQ29sbGF0b3I6OklERU5USUNBTAogICAgICAgID8gTm9ybWFsaXplcjo6Tk9fT1AKICAgICAgICA6IG9yZGVyLT5nZXREZWNvbXBvc2l0aW9uKCk7CiAgICAgIAogICAgICB0ZXh0ID0gbmV3IE5vcm1hbGl6ZXIoc291cmNlVGV4dCwgZGVjb21wKTsKICAgICAgaWYgKHRleHQgPT0gTlVMTCkgewogICAgICAgIHN0YXR1cyA9IE1FTU9SWV9BTExPQ0FUSU9OX0VSUk9SOwogICAgICB9CiAgICB9Cn0KCkNvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6Q29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yKGNvbnN0ICAgIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciYgb3RoZXIpCiAgICA6IGV4cEluZGV4KG90aGVyLmV4cEluZGV4KSwgdGV4dCgwKSwgc3dhcE9yZGVyKG90aGVyLnN3YXBPcmRlcikKewogICAgdGV4dCA9IChOb3JtYWxpemVyKikgb3RoZXIudGV4dC0+Y2xvbmUoKTsKICAgIGJ1ZmZlckFsaWFzID0gb3RoZXIuYnVmZmVyQWxpYXM7CiAgICBvcmRlckFsaWFzID0gb3RoZXIub3JkZXJBbGlhczsKfQoKY29uc3QgICBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3ImCkNvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6b3BlcmF0b3I9KGNvbnN0ICAgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yJiBvdGhlcikKewogICAgaWYgKHRoaXMgIT0gJm90aGVyKQogICAgewogICAgICAgIGV4cEluZGV4ID0gb3RoZXIuZXhwSW5kZXg7CiAgICAgICAgc3dhcE9yZGVyID0gb3RoZXIuc3dhcE9yZGVyOwoKICAgICAgICBkZWxldGUgdGV4dDsKICAgICAgICB0ZXh0ID0gKE5vcm1hbGl6ZXIqKW90aGVyLnRleHQtPmNsb25lKCk7CgogICAgICAgIGJ1ZmZlckFsaWFzID0gb3RoZXIuYnVmZmVyQWxpYXM7CiAgICAgICAgb3JkZXJBbGlhcyA9IG90aGVyLm9yZGVyQWxpYXM7CiAgICB9CgogICAgcmV0dXJuICp0aGlzOwp9CgpDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6On5Db2xsYXRpb25FbGVtZW50SXRlcmF0b3IoKQp7CiAgICBkZWxldGUgdGV4dDsKICAgIHRleHQgPSBOVUxMOwogICAgYnVmZmVyQWxpYXMgPSBOVUxMOwogICAgb3JkZXJBbGlhcyA9IE5VTEw7Cn0KCmJvb2xfdApDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6Om9wZXJhdG9yPT0oY29uc3QgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yJiB0aGF0KSBjb25zdAp7CiAgICBpZiAodGhpcyA9PSAmdGhhdCkKICAgIHsKICAgICAgICByZXR1cm4gVFJVRTsKICAgIH0KCiAgICBpZiAoKnRleHQgIT0gKih0aGF0LnRleHQpKQogICAgewogICAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KCiAgICBpZiAoc3dhcE9yZGVyICE9IHRoYXQuc3dhcE9yZGVyKQogICAgewogICAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KCiAgICBpZiAoKmJ1ZmZlckFsaWFzICE9ICoodGhhdC5idWZmZXJBbGlhcykpCiAgICB7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIGlmIChleHBJbmRleCAhPSB0aGF0LmV4cEluZGV4KQogICAgewogICAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KCiAgICBpZiAob3JkZXJBbGlhcyAhPSB0aGF0Lm9yZGVyQWxpYXMpCiAgICB7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIHJldHVybiBUUlVFOwp9Cgpib29sX3QKQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpvcGVyYXRvciE9KGNvbnN0IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciYgb3RoZXIpIGNvbnN0CnsKICAgIHJldHVybiAhKCp0aGlzID09IG90aGVyKTsKfQoKLyoqCiAqIFJlc2V0cyB0aGUgY3Vyc29yIHRvIHRoZSBiZWdpbm5pbmcgb2YgdGhlIHN0cmluZy4KICovCnZvaWQgCkNvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6cmVzZXQoKQp7CiAgaWYgKHRleHQgIT0gTlVMTCkKICAgIHsKICAgICAgdGV4dC0+cmVzZXQoKTsKICAgICAgdGV4dC0+c2V0TW9kZShvcmRlckFsaWFzLT5nZXREZWNvbXBvc2l0aW9uKCkpOwogICAgfQoKICBidWZmZXJBbGlhcyA9IE5VTEw7CiAgZXhwSW5kZXggPSAwOwogIHN3YXBPcmRlciA9IDA7Cn0KCi8vIFNldHMgdGhlIHNvdXJjZSB0byB0aGUgbmV3IHNvdXJjZSBzdHJpbmcuCnZvaWQKQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpzZXRUZXh0KGNvbnN0IFVuaWNvZGVTdHJpbmcmICBzb3VyY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiAgICAgIHN0YXR1cykKewogICAgaWYgKEZBSUxVUkUoc3RhdHVzKSkKICAgIHsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgYnVmZmVyQWxpYXMgPSAwOwogICAgc3dhcE9yZGVyID0gMDsKICAgIGV4cEluZGV4ID0gMDsKCiAgICBpZiAodGV4dCA9PSBOVUxMKQogICAgewogICAgICAgIHRleHQgPSBuZXcgTm9ybWFsaXplcihzb3VyY2UsIG9yZGVyQWxpYXMtPmdldERlY29tcG9zaXRpb24oKSk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgdGV4dC0+c2V0VGV4dChzb3VyY2UsIHN0YXR1cyk7CiAgICAgICAgdGV4dC0+c2V0TW9kZShvcmRlckFsaWFzLT5nZXREZWNvbXBvc2l0aW9uKCkpOwogICAgfQp9CgovLyBTZXRzIHRoZSBzb3VyY2UgdG8gdGhlIG5ldyBjaGFyYWN0ZXIgaXRlcmF0b3IuCnZvaWQKQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpzZXRUZXh0KENoYXJhY3Rlckl0ZXJhdG9yJiAgc291cmNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYgICAgICBzdGF0dXMpCnsKICAgIGlmIChGQUlMVVJFKHN0YXR1cykpIHsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgYnVmZmVyQWxpYXMgPSAwOwogICAgc3dhcE9yZGVyID0gMDsKICAgIGV4cEluZGV4ID0gMDsKCiAgICBpZiAodGV4dCA9PSBOVUxMKSB7CiAgICAgICAgdGV4dCA9IG5ldyBOb3JtYWxpemVyKHNvdXJjZSwgb3JkZXJBbGlhcy0+Z2V0RGVjb21wb3NpdGlvbigpKTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICB0ZXh0LT5zZXRNb2RlKG9yZGVyQWxpYXMtPmdldERlY29tcG9zaXRpb24oKSk7CiAgICAgICAgdGV4dC0+c2V0VGV4dChzb3VyY2UsIHN0YXR1cyk7CiAgICB9Cn0KCi8qKgogKiBHZXQgdGhlIG9yZGVyaW5nIHByaW9yaXR5IG9mIHRoZSBuZXh0IGNoYXJhY3RlciBpbiB0aGUgc3RyaW5nLgogKiBAcmV0dXJuIHRoZSBuZXh0IGNoYXJhY3RlcidzIG9yZGVyaW5nLiAgUmV0dXJucyBOVUxMT1JERVIgaWYKICogdGhlIGVuZCBvZiBzdHJpbmcgaXMgcmVhY2hlZC4KICovCmludDMyX3QKQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpuZXh0KFVFcnJvckNvZGUmIHN0YXR1cykKewogICAgaWYgKHRleHQgPT0gTlVMTCB8fCBGQUlMVVJFKHN0YXR1cykpCiAgICB7CiAgICAgICAgcmV0dXJuIE5VTExPUkRFUjsKICAgIH0KCiAgICAvLyBVcGRhdGUgdGhlIGRlY29tcG9zaXRpb24gbW9kZSBpZiBuZWNlc3NhcnkuCiAgICB0ZXh0LT5zZXRNb2RlKG9yZGVyQWxpYXMtPmdldERlY29tcG9zaXRpb24oKSk7CiAgICAKICAgIGlmIChidWZmZXJBbGlhcyAhPSBOVUxMKQogICAgewogICAgICAgIC8vIGJ1ZmZlckFsaWFzIG5lZWRzIGEgYml0IG9mIGFuIGV4cGxhbmF0aW9uLgogICAgICAgIC8vIFdoZW4gd2UgaGl0IGFuIGV4cGFuZGluZyBjaGFyYWN0ZXIgaW4gdGhlIHRleHQsIHdlIGNhbGwgdGhlIG9yZGVyJ3MKICAgICAgICAvLyBnZXRFeHBhbmRWYWx1ZXMgbWV0aG9kIHRvIHJldHJpZXZlIGFuIGFycmF5IG9mIHRoZSBvcmRlcmluZ3MgZm9yIGFsbAogICAgICAgIC8vIG9mIHRoZSBjaGFyYWN0ZXJzIGluIHRoZSBleHBhbnNpb24gKHNlZSB0aGUgZW5kIG9mIHRoaXMgbWV0aG9kKS4KICAgICAgICAvLyBUaGUgZmlyc3Qgb3JkZXJpbmcgaXMgcmV0dXJuZWQsIGFuZCBhbiBhbGlhcyB0byB0aGUgb3JkZXJpbmdzIGFycmF5CiAgICAgICAgLy8gaXMgc2F2ZWQgc28gdGhhdCB0aGUgcmVtYWluaW5nIG9yZGVyaW5ncyBjYW4gYmUgcmV0dXJuZWQgb24gc3Vic2VxdWVudAogICAgICAgIC8vIGNhbGxzIHRvIG5leHQuICBTbywgaWYgdGhlIGV4cGFuZGluZyBidWZmZXIgaXMgbm90IGV4aGF1c3RlZCwgCiAgICAgICAgLy8gYWxsIHdlIGhhdmUgdG8gZG8gaGVyZSBpcyByZXR1cm4gdGhlIG5leHQgb3JkZXJpbmcgaW4gdGhlIGJ1ZmZlci4gIAogICAgICAgIGlmIChleHBJbmRleCA8IGJ1ZmZlckFsaWFzLT5zaXplKCkpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gc3RyZW5ndGhPcmRlcihidWZmZXJBbGlhcy0+YXQoZXhwSW5kZXgrKykpOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICBidWZmZXJBbGlhcyA9IE5VTEw7CiAgICAgICAgICAgIGV4cEluZGV4ID0gMDsKICAgICAgICB9CiAgICB9CiAgICBlbHNlIGlmIChzd2FwT3JkZXIgIT0gMCkKICAgIHsKICAgICAgICAvLyBJZiB3ZSBmaW5kIGEgY2hhcmFjdGVyIHdpdGggbm8gb3JkZXIsIHdlIHJldHVybiB0aGUgbWFya2luZwogICAgICAgIC8vIGZsYWcsIFVOTUFQUEVEQ0hBUlZBTFVFLCAweDdmZmYwMDAwLCBhbmQgdGhlbiB0aGUgY2hhcmFjdGVyIAogICAgICAgIC8vIGl0c2VsZiBzaGlmdGVkIGxlZnQgMTYgYml0cyBhcyBvcmRlcnMuICBBdCB0aGlzIHBvaW50LCB0aGUKICAgICAgICAvLyBVTk1BUFBFRENIQVJWQUxVRSBmbGFnIGhhcyBhbHJlYWR5IGJlZW4gcmV0dXJuZWQgYnkgdGhlIGNvZGUKICAgICAgICAvLyBiZWxvdywgc28ganVzdCByZXR1cm4gdGhlIHNoaWZ0ZWQgY2hhcmFjdGVyIGhlcmUuCiAgICAgICAgaW50MzJfdCBvcmRlciA9IHN3YXBPcmRlciA8PCAxNjsKCiAgICAgICAgc3dhcE9yZGVyID0gMDsKCiAgICAgICAgcmV0dXJuIG9yZGVyOwogICAgfQoKICAgIC8vIEdldHMgdGhlIG5leHQgY2hhcmFjdGVyIGZyb20gdGhlIHN0cmluZyB1c2luZyBkZWNvbXBvc2l0aW9uIGl0ZXJhdG9yLgogICAgVUNoYXIgY2ggPSB0ZXh0LT5jdXJyZW50KCk7CiAgICB0ZXh0LT5uZXh0KCk7CgogICAgaWYgKEZBSUxVUkUoc3RhdHVzKSkKICAgIHsKICAgICAgICByZXR1cm4gTlVMTE9SREVSOwogICAgfQoKICAgIGlmIChjaCA9PSBOb3JtYWxpemVyOjpET05FKQogICAgewogICAgICAgIHJldHVybiBOVUxMT1JERVI7CiAgICB9CiAgICAKICAgIC8vIEFzayB0aGUgY29sbGF0b3IgZm9yIHRoaXMgY2hhcmFjdGVyJ3Mgb3JkZXJpbmcuCiAgICBpbnQzMl90IHZhbHVlID0gb3JkZXJBbGlhcy0+Z2V0VW5pY29kZU9yZGVyKGNoKTsKCiAgICBpZiAodmFsdWUgPT0gUnVsZUJhc2VkQ29sbGF0b3I6OlVOTUFQUEVEKQogICAgewogICAgICAgIC8vIFJldHVybmVkIGFuICJ1bm1hcHBlZCIgZmxhZyBhbmQgc2F2ZSB0aGUgY2hhcmFjdGVyIHNvIGl0IGNhbiBiZSAKICAgICAgICAvLyByZXR1cm5lZCBuZXh0IHRpbWUgdGhpcyBtZXRob2QgaXMgY2FsbGVkLgogICAgICAgIGlmIChjaCA9PSAweDAwMDApIHJldHVybiBjaDsKICAgICAgICBzd2FwT3JkZXIgPSBjaDsgIC8vIFx1MDAwMCBpcyBub3QgdmFsaWQgaW4gQysrJ3MgVW5pY29kZVN0cmluZwogICAgICAgIHJldHVybiBVTk1BUFBFRENIQVJWQUxVRTsKICAgIH0KICAgIAogICAgaWYgKHZhbHVlID49IFJ1bGVCYXNlZENvbGxhdG9yOjpDT05UUkFDVENIQVJJTkRFWCkKICAgIHsKICAgICAgICB2YWx1ZSA9IG5leHRDb250cmFjdENoYXIoY2gsIHN0YXR1cyk7CiAgICB9CgogICAgaWYgKHZhbHVlID49IFJ1bGVCYXNlZENvbGxhdG9yOjpFWFBBTkRDSEFSSU5ERVgpCiAgICB7CiAgICAgICAgYnVmZmVyQWxpYXMgPSBvcmRlckFsaWFzLT5nZXRFeHBhbmRWYWx1ZUxpc3QodmFsdWUpOwogICAgICAgIGV4cEluZGV4ID0gMDsKICAgICAgICB2YWx1ZSA9IGJ1ZmZlckFsaWFzLT5hdChleHBJbmRleCsrKTsKICAgIH0KCiAgICByZXR1cm4gc3RyZW5ndGhPcmRlcih2YWx1ZSk7Cn0KCiAvKioKICAqIEdldCB0aGUgb3JkZXJpbmcgcHJpb3JpdHkgb2YgdGhlIHByZXZpb3VzIGNvbGxhdGlvbiBlbGVtZW50IGluIHRoZSBzdHJpbmcuCiAgKiBAcGFyYW0gc3RhdHVzIHRoZSBlcnJvciBjb2RlIHN0YXR1cy4KICAqIEByZXR1cm4gdGhlIHByZXZpb3VzIGVsZW1lbnQncyBvcmRlcmluZy4gIFJldHVybnMgTlVMTE9SREVSIGlmCiAgKiB0aGUgYmVnaW5uaW5nIG9mIHN0cmluZyBpcyByZWFjaGVkLgogICovCmludDMyX3QKQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpwcmV2aW91cyhVRXJyb3JDb2RlJiBzdGF0dXMpCnsKICAgIGlmICh0ZXh0ID09IE5VTEwgfHwgRkFJTFVSRShzdGF0dXMpKQogICAgewogICAgICAgIHJldHVybiBOVUxMT1JERVI7CiAgICB9CgogICAgdGV4dC0+c2V0TW9kZShvcmRlckFsaWFzLT5nZXREZWNvbXBvc2l0aW9uKCkpOwoKICAgIGlmIChidWZmZXJBbGlhcyAhPSBOVUxMKQogICAgewogICAgICAgIGlmIChleHBJbmRleCA+IDApCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gc3RyZW5ndGhPcmRlcihidWZmZXJBbGlhcy0+YXQoLS1leHBJbmRleCkpOwogICAgICAgIH0KCiAgICAgICAgYnVmZmVyQWxpYXMgPSBOVUxMOwogICAgICAgIGV4cEluZGV4ID0gMDsKICAgIH0KICAgIGVsc2UgaWYgKHN3YXBPcmRlciAhPSAwKQogICAgewogICAgICAgIGludDMyX3Qgb3JkZXIgPSBzd2FwT3JkZXIgPDwgMTY7CgogICAgICAgIHN3YXBPcmRlciA9IDA7CiAgICAgICAgcmV0dXJuIG9yZGVyOwogICAgfQoKICAgIFVDaGFyIGNoID0gdGV4dC0+cHJldmlvdXMoKTsKCiAgICBpZiAoY2ggPT0gTm9ybWFsaXplcjo6RE9ORSkKICAgIHsKICAgICAgICByZXR1cm4gTlVMTE9SREVSOwogICAgfQoKICAgIGludDMyX3QgdmFsdWUgPSBvcmRlckFsaWFzLT5nZXRVbmljb2RlT3JkZXIoY2gpOwoKICAgIGlmICh2YWx1ZSA9PSBSdWxlQmFzZWRDb2xsYXRvcjo6VU5NQVBQRUQpCiAgICB7CiAgICAgICAgaWYgKGNoID09IDB4MDAwMCkgcmV0dXJuIGNoOwogICAgICAgIHN3YXBPcmRlciA9IFVOTUFQUEVEQ0hBUlZBTFVFOwogICAgICAgIHJldHVybiBjaDsKICAgIH0KICAgIAogICAgaWYgKHZhbHVlID49IFJ1bGVCYXNlZENvbGxhdG9yOjpDT05UUkFDVENIQVJJTkRFWCkKICAgIHsKICAgICAgICB2YWx1ZSA9IHByZXZDb250cmFjdENoYXIoY2gsIHN0YXR1cyk7CiAgICB9CgogICAgaWYgKHZhbHVlID49IFJ1bGVCYXNlZENvbGxhdG9yOjpFWFBBTkRDSEFSSU5ERVgpCiAgICB7CiAgICAgICAgYnVmZmVyQWxpYXMgPSBvcmRlckFsaWFzLT5nZXRFeHBhbmRWYWx1ZUxpc3QodmFsdWUpOwogICAgICAgIGV4cEluZGV4ID0gYnVmZmVyQWxpYXMtPnNpemUoKTsKICAgICAgICB2YWx1ZSA9IGJ1ZmZlckFsaWFzLT5hdCgtLWV4cEluZGV4KTsKICAgIH0KCiAgICByZXR1cm4gc3RyZW5ndGhPcmRlcih2YWx1ZSk7Cn0KCmludDMyX3QKQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpzdHJlbmd0aE9yZGVyKGludDMyX3Qgb3JkZXIpIGNvbnN0CnsKICAgIENvbGxhdG9yOjpFQ29sbGF0aW9uU3RyZW5ndGggcyA9IG9yZGVyQWxpYXMtPmdldFN0cmVuZ3RoKCk7CiAgICAvLyBNYXNrIG9mZiB0aGUgdW53YW50ZWQgZGlmZmVyZW5jZXMuCiAgICBpZiAocyA9PSBDb2xsYXRvcjo6UFJJTUFSWSkKICAgIHsKICAgICAgICBvcmRlciAmPSBSdWxlQmFzZWRDb2xsYXRvcjo6UFJJTUFSWURJRkZFUkVOQ0VPTkxZOwogICAgfSBlbHNlIGlmIChzID09IENvbGxhdG9yOjpTRUNPTkRBUlkpCiAgICB7CiAgICAgICAgb3JkZXIgJj0gUnVsZUJhc2VkQ29sbGF0b3I6OlNFQ09OREFSWURJRkZFUkVOQ0VPTkxZOwogICAgfQogICAgcmV0dXJuIG9yZGVyOwp9CgpVVGV4dE9mZnNldApDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6OmdldE9mZnNldCgpIGNvbnN0CnsKICAgIC8vIFNpbmNlIHRoZSBEZWNvbXBvc2l0aW9uSXRlcmF0b3IgaXMgZG9pbmcgdGhlIHdvcmsgb2YgaXRlcmF0aW5nIHRocm91Z2gKICAgIC8vIHRoZSB0ZXh0IHN0cmluZywgd2UgY2FuIGp1c3QgYXNrIGl0IHdoYXQgaXRzIG9mZnNldCBpcy4KICAgIHJldHVybiAodGV4dCAhPSBOVUxMKSA/IHRleHQtPmdldEluZGV4KCkgOiAwOwp9Cgp2b2lkIApDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6OnNldE9mZnNldChVVGV4dE9mZnNldCBuZXdPZmZzZXQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiBzdGF0dXMpCnsKICAgIGlmIChGQUlMVVJFKHN0YXR1cykpCiAgICB7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIGlmICh0ZXh0ICE9IE5VTEwpCiAgICB7CiAgICAgICAgdGV4dC0+c2V0SW5kZXgobmV3T2Zmc2V0KTsKICAgIH0KCiAgICBidWZmZXJBbGlhcyA9IE5VTEw7CiAgICBleHBJbmRleCA9IDA7CiAgICBzd2FwT3JkZXIgPSAwOwp9CgovLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQovLyBwcml2YXRlcwovLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKCi8qKgogKiBHZXQgdGhlIG9yZGVyaW5nIHByaW9yaXR5IG9mIHRoZSBuZXh0IGNvbnRyYWN0aW5nIGNoYXJhY3RlciBpbiB0aGUKICogc3RyaW5nLgogKiBAcGFyYW0gY2ggdGhlIHN0YXJ0aW5nIGNoYXJhY3RlciBvZiBhIGNvbnRyYWN0aW5nIGNoYXJhY3RlciB0b2tlbgogKiBAcmV0dXJuIHRoZSBuZXh0IGNvbnRyYWN0aW5nIGNoYXJhY3RlcidzIG9yZGVyaW5nLiAgUmV0dXJucyBOVUxMT1JERVIKICogaWYgdGhlIGVuZCBvZiBzdHJpbmcgaXMgcmVhY2hlZC4KICovCmludDMyX3QKQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpuZXh0Q29udHJhY3RDaGFyKFVDaGFyIGNoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYgc3RhdHVzKQp7CiAgICAvLyBGaXJzdCBnZXQgdGhlIG9yZGVyaW5nIG9mIHRoaXMgc2luZ2xlIGNoYXJhY3RlcgogICAgVmVjdG9yT2ZQVG9Db250cmFjdEVsZW1lbnQgKmxpc3QgPSBvcmRlckFsaWFzLT5nZXRDb250cmFjdFZhbHVlcyhjaCk7CiAgICBFbnRyeVBhaXIgKnBhaXIgPSAoRW50cnlQYWlyICopbGlzdC0+YXQoMCk7CiAgICBpbnQzMl90IG9yZGVyID0gcGFpci0+dmFsdWU7CgogICAgLy8gTm93IGl0ZXJhdGUgdGhyb3VnaCB0aGUgY2hhcnMgZm9sbG93aW5nIGl0IGFuZAogICAgLy8gbG9vayBmb3IgdGhlIGxvbmdlc3QgbWF0Y2gKICAgIGtleS5yZW1vdmUoKTsKICAgIGtleSArPSBjaDsKCiAgICB3aGlsZSAoKGNoID0gdGV4dC0+Y3VycmVudCgpKSAhPSBOb3JtYWxpemVyOjpET05FKQogICAgewogICAgICAgIGlmIChGQUlMVVJFKHN0YXR1cykpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gTlVMTE9SREVSOwogICAgICAgIH0KCiAgICAgICAga2V5ICs9IGNoOwoKICAgICAgICBpbnQzMl90IG4gPSBSdWxlQmFzZWRDb2xsYXRvcjo6Z2V0RW50cnkobGlzdCwga2V5LCBUUlVFKTsKCiAgICAgICAgaWYgKG4gPT0gUnVsZUJhc2VkQ29sbGF0b3I6OlVOTUFQUEVEKQogICAgICAgIHsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIHRleHQtPm5leHQoKTsKCiAgICAgICAgcGFpciA9IChFbnRyeVBhaXIgKilsaXN0LT5hdChuKTsKICAgICAgICBvcmRlciA9IHBhaXItPnZhbHVlOwogICAgfQoKICAgIHJldHVybiBvcmRlcjsKfQoKLyoqCiAqIEdldCB0aGUgb3JkZXJpbmcgcHJpb3JpdHkgb2YgdGhlIHByZXZpb3VzIGNvbnRyYWN0aW5nIGNoYXJhY3RlciBpbiB0aGUKICogc3RyaW5nLgogKiBAcGFyYW0gY2ggdGhlIHN0YXJ0aW5nIGNoYXJhY3RlciBvZiBhIGNvbnRyYWN0aW5nIGNoYXJhY3RlciB0b2tlbgogKiBAcmV0dXJuIHRoZSBuZXh0IGNvbnRyYWN0aW5nIGNoYXJhY3RlcidzIG9yZGVyaW5nLiAgUmV0dXJucyBOVUxMT1JERVIKICogaWYgdGhlIGVuZCBvZiBzdHJpbmcgaXMgcmVhY2hlZC4KICovCmludDMyX3QgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpwcmV2Q29udHJhY3RDaGFyKFVDaGFyIGNoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlICZzdGF0dXMpCnsKICAgIC8vIEZpcnN0IGdldCB0aGUgb3JkZXJpbmcgb2YgdGhpcyBzaW5nbGUgY2hhcmFjdGVyCiAgICBWZWN0b3JPZlBUb0NvbnRyYWN0RWxlbWVudCAqbGlzdCA9IG9yZGVyQWxpYXMtPmdldENvbnRyYWN0VmFsdWVzKGNoKTsKICAgIEVudHJ5UGFpciAqcGFpciA9IChFbnRyeVBhaXIgKilsaXN0LT5hdCgwKTsKICAgIGludDMyX3Qgb3JkZXIgPSBwYWlyLT52YWx1ZTsKCiAgICAvLyBOb3cgaXRlcmF0ZSB0aHJvdWdoIHRoZSBjaGFycyBmb2xsb3dpbmcgaXQgYW5kCiAgICAvLyBsb29rIGZvciB0aGUgbG9uZ2VzdCBtYXRjaAogICAga2V5LnJlbW92ZSgpOwogICAga2V5ICs9IGNoOwoKICAgIHdoaWxlICgoY2ggPSB0ZXh0LT5wcmV2aW91cygpKSAhPSBOb3JtYWxpemVyOjpET05FKQogICAgewogICAgICAgIGtleSArPSBjaDsKCiAgICAgICAgaW50MzJfdCBuID0gUnVsZUJhc2VkQ29sbGF0b3I6OmdldEVudHJ5KGxpc3QsIGtleSwgRkFMU0UpOwoKICAgICAgICBpZiAobiA9PSBSdWxlQmFzZWRDb2xsYXRvcjo6VU5NQVBQRUQpCiAgICAgICAgewogICAgICAgICAgICBjaCA9IHRleHQtPm5leHQoKTsKCiAgICAgICAgICAgIGlmIChGQUlMVVJFKHN0YXR1cykpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBOVUxMT1JERVI7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KCiAgICAgICAgcGFpciA9IChFbnRyeVBhaXIgKilsaXN0LT5hdChuKTsKICAgICAgICBvcmRlciA9IHBhaXItPnZhbHVlOwogICAgfQoKICAgIHJldHVybiBvcmRlcjsKfQo=