LyoKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiogICBDb3B5cmlnaHQgKEMpIDE5OTctMjAwMSwgSW50ZXJuYXRpb25hbCBCdXNpbmVzcyBNYWNoaW5lcwoqICAgQ29ycG9yYXRpb24gYW5kIG90aGVycy4gIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqLwoKLyoqCiogRmlsZSBjb2xlaXRyLmgKKgoqIAoqCiogQ3JlYXRlZCBieTogSGVsZW5hIFNoaWgKKgoqIE1vZGlmaWNhdGlvbiBIaXN0b3J5OgoqCiogIERhdGUgICAgICAgTmFtZSAgICAgICAgRGVzY3JpcHRpb24KKgoqICA4LzE4Lzk3ICAgIGhlbGVuYSAgICAgIEFkZGVkIGludGVybmFsIEFQSSBkb2N1bWVudGF0aW9uLgoqIDA4LzAzLzk4ICAgIGVybSAgICAgICAgIFN5bmNoZWQgd2l0aCAxLjIgdmVyc2lvbiBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IuamF2YQoqIDEyLzEwLzk5ICAgIGFsaXUgICAgICAgIFBvcnRlZCBUaGFpIGNvbGxhdGlvbiBzdXBwb3J0IGZyb20gSmF2YS4KKiAwMS8yNS8wMSAgICBzd3F1ZWsgICAgICBNb2RpZmllZCBpbnRvIGEgQysrIHdyYXBwZXIgY2FsbGluZyBDIEFQSXMgKHVjb2xpdGVyLmgpCiogMDIvMTkvMDEgICAgc3dxdWVrICAgICAgUmVtb3ZlZCBDb2xsYXRpb25FbGVtZW50c0l0ZXJhdG9yKCkgc2luY2UgaXQgaXMgCiogICAgICAgICAgICAgICAgICAgICAgICAgcHJpdmF0ZSBjb25zdHJ1Y3RvciBhbmQgbm8gY2FsbHMgYXJlIG1hZGUgdG8gaXQKKi8KCiNpZm5kZWYgQ09MRUlUUl9ICiNkZWZpbmUgQ09MRUlUUl9ICgojaW5jbHVkZSAidW5pY29kZS90Ymxjb2xsLmgiCiNpbmNsdWRlICJ1bmljb2RlL3Vjb2xlaXRyLmgiCgp0eXBlZGVmIHN0cnVjdCBVQ29sbGF0aW9uRWxlbWVudHMgVUNvbGxhdGlvbkVsZW1lbnRzOwoKVV9OQU1FU1BBQ0VfQkVHSU4KCi8qKgoqIFRoZSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IgY2xhc3MgaXMgdXNlZCBhcyBhbiBpdGVyYXRvciB0byB3YWxrIHRocm91Z2ggICAgIAoqIGVhY2ggY2hhcmFjdGVyIG9mIGFuIGludGVybmF0aW9uYWwgc3RyaW5nLiBVc2UgdGhlIGl0ZXJhdG9yIHRvIHJldHVybiB0aGUKKiBvcmRlcmluZyBwcmlvcml0eSBvZiB0aGUgcG9zaXRpb25lZCBjaGFyYWN0ZXIuIFRoZSBvcmRlcmluZyBwcmlvcml0eSBvZiBhIAoqIGNoYXJhY3Rlciwgd2hpY2ggd2UgcmVmZXIgdG8gYXMgYSBrZXksIGRlZmluZXMgaG93IGEgY2hhcmFjdGVyIGlzIGNvbGxhdGVkIGluIAoqIHRoZSBnaXZlbiBjb2xsYXRpb24gb2JqZWN0LgoqIEZvciBleGFtcGxlLCBjb25zaWRlciB0aGUgZm9sbG93aW5nIGluIFNwYW5pc2g6CiogPHByZT4KKiBcY29kZQoqICAgICAgICAiY2EiIC0+IHRoZSBmaXJzdCBrZXkgaXMga2V5KCdjJykgYW5kIHNlY29uZCBrZXkgaXMga2V5KCdhJykuCiogICAgICAgICJjaGEiIC0+IHRoZSBmaXJzdCBrZXkgaXMga2V5KCdjaCcpIGFuZCBzZWNvbmQga2V5IGlzIGtleSgnYScpLgoqIFxlbmRjb2RlCiogPC9wcmU+CiogQW5kIGluIEdlcm1hbiwKKiA8cHJlPgoqIFxjb2RlCiogICAgICAgICLmYiItPiB0aGUgZmlyc3Qga2V5IGlzIGtleSgnYScpLCB0aGUgc2Vjb25kIGtleSBpcyBrZXkoJ2UnKSwgYW5kCiogICAgICAgIHRoZSB0aGlyZCBrZXkgaXMga2V5KCdiJykuCiogXGVuZGNvZGUKKiA8L3ByZT4KKiBUaGUga2V5IG9mIGEgY2hhcmFjdGVyLCBpcyBhbiBpbnRlZ2VyIGNvbXBvc2VkIG9mIHByaW1hcnkgb3JkZXIoc2hvcnQpLAoqIHNlY29uZGFyeSBvcmRlcihjaGFyKSwgYW5kIHRlcnRpYXJ5IG9yZGVyKGNoYXIpLiBKYXZhIHN0cmljdGx5IGRlZmluZXMgdGhlIAoqIHNpemUgYW5kIHNpZ25lZG5lc3Mgb2YgaXRzIHByaW1pdGl2ZSBkYXRhIHR5cGVzLiBUaGVyZWZvcmUsIHRoZSBzdGF0aWMKKiBmdW5jdGlvbnMgcHJpbWFyeU9yZGVyKCksIHNlY29uZGFyeU9yZGVyKCksIGFuZCB0ZXJ0aWFyeU9yZGVyKCkgcmV0dXJuIAoqIGludDMyX3QgdG8gZW5zdXJlIHRoZSBjb3JyZWN0bmVzcyBvZiB0aGUga2V5IHZhbHVlLgoqIDxwPkV4YW1wbGUgb2YgdGhlIGl0ZXJhdG9yIHVzYWdlOiAod2l0aG91dCBlcnJvciBjaGVja2luZykKKiA8cHJlPgoqIFxjb2RlCiogICB2b2lkIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcl9FeGFtcGxlKCkKKiAgIHsKKiAgICAgICBVbmljb2RlU3RyaW5nIHN0ciA9ICJUaGlzIGlzIGEgdGVzdCI7CiogICAgICAgVUVycm9yQ29kZSBzdWNjZXNzID0gVV9aRVJPX0VSUk9SOwoqICAgICAgIFJ1bGVCYXNlZENvbGxhdG9yKiByYmMgPQoqICAgICAgICAgICAoUnVsZUJhc2VkQ29sbGF0b3IqKSBSdWxlQmFzZWRDb2xsYXRvcjo6Y3JlYXRlSW5zdGFuY2Uoc3VjY2Vzcyk7CiogICAgICAgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yKiBjID0KKiAgICAgICAgICAgcmJjLT5jcmVhdGVDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IoIHN0ciApOwoqICAgICAgIGludDMyX3Qgb3JkZXIgPSBjLT5uZXh0KHN1Y2Nlc3MpOwoqICAgICAgIGMtPnJlc2V0KCk7CiogICAgICAgb3JkZXIgPSBjLT5wcmV2aW91cyhzdWNjZXNzKTsKKiAgICAgICBkZWxldGUgYzsKKiAgICAgICBkZWxldGUgcmJjOwoqICAgfQoqIFxlbmRjb2RlCiogPC9wcmU+CiogPHA+CiogQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpuZXh0IHJldHVybnMgdGhlIGNvbGxhdGlvbiBvcmRlciBvZiB0aGUgbmV4dAoqIGNoYXJhY3RlciBiYXNlZCBvbiB0aGUgY29tcGFyaXNvbiBsZXZlbCBvZiB0aGUgY29sbGF0b3IuIAoqIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6cHJldmlvdXMgcmV0dXJucyB0aGUgY29sbGF0aW9uIG9yZGVyIG9mIHRoZSAKKiBwcmV2aW91cyBjaGFyYWN0ZXIgYmFzZWQgb24gdGhlIGNvbXBhcmlzb24gbGV2ZWwgb2YgdGhlIGNvbGxhdG9yLiAKKiBUaGUgQ29sbGF0aW9uIEVsZW1lbnQgSXRlcmF0b3IgbW92ZXMgb25seSBpbiBvbmUgZGlyZWN0aW9uIGJldHdlZW4gY2FsbHMgdG8KKiBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6OnJlc2V0LiBUaGF0IGlzLCBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6Om5leHQoKSAKKiBhbmQgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpwcmV2aW91cyBjYW4gbm90IGJlIGludGVyLXVzZWQuIFdoZW5ldmVyIAoqIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6cHJldmlvdXMgaXMgdG8gYmUgY2FsbGVkIGFmdGVyIAoqIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6bmV4dCgpIG9yIHZpY2UgdmVyc2EsIAoqIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6cmVzZXQgaGFzIHRvIGJlIGNhbGxlZCBmaXJzdCB0byByZXNldCB0aGUgc3RhdHVzLCAKKiBzaGlmdGluZyBwb2ludGVycyB0byBlaXRoZXIgdGhlIGVuZCBvciB0aGUgc3RhcnQgb2YgdGhlIHN0cmluZy4gSGVuY2UgYXQgdGhlIAoqIG5leHQgY2FsbCBvZiBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6OnByZXZpb3VzIG9yIAoqIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6bmV4dCgpLCB0aGUgZmlyc3Qgb3IgbGFzdCBjb2xsYXRpb24gb3JkZXIgd2lsbCBiZSAKKiByZXR1cm5lZC4gCiogSWYgYSBjaGFuZ2Ugb2YgZGlyZWN0aW9uIGlzIGRvbmUgd2l0aG91dCBhIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6cmVzZXQoKSwgCiogdGhlIHJlc3VsdCBpcyB1bmRlZmluZWQuCiogVGhlIHJlc3VsdCBvZiBhIGZvcndhcmQgaXRlcmF0ZSAoQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpuZXh0KSBhbmQgCiogcmV2ZXJzZWQgcmVzdWx0IG9mIHRoZSBiYWNrd2FyZCBpdGVyYXRlIChDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6OnByZXZpb3VzKSAKKiBvbiB0aGUgc2FtZSBzdHJpbmcgYXJlIGVxdWl2YWxlbnQsIGlmIGNvbGxhdGlvbiBvcmRlcnMgd2l0aCB0aGUgdmFsdWUgCiogVUNPTF9JR05PUkFCTEUgYXJlIGlnbm9yZWQuCiogQ2hhcmFjdGVyIGJhc2VkIG9uIHRoZSBjb21wYXJpc29uIGxldmVsIG9mIHRoZSBjb2xsYXRvci4gIEEgY29sbGF0aW9uIG9yZGVyIAoqIGNvbnNpc3RzIG9mIHByaW1hcnkgb3JkZXIsIHNlY29uZGFyeSBvcmRlciBhbmQgdGVydGlhcnkgb3JkZXIuICBUaGUgZGF0YSAKKiB0eXBlIG9mIHRoZSBjb2xsYXRpb24gb3JkZXIgaXMgPHN0cm9uZz50X2ludDMyPC9zdHJvbmc+LiAKKgoqIE5vdGUsIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciBzaG91bGQgbm90IGJlIHN1YmNsYXNzZWQuCiogQHNlZSAgICAgQ29sbGF0b3IKKiBAc2VlICAgICBSdWxlQmFzZWRDb2xsYXRvcgoqIEB2ZXJzaW9uIDEuOCBKYW4gMTYgMjAwMQoqLwpjbGFzcyBVX0kxOE5fQVBJIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcgp7CnB1YmxpYzogCgogIC8vIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciBwdWJsaWMgZGF0YSBtZW1iZXIgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogIC8qKgogICogTlVMTE9SREVSIGluZGljYXRlcyB0aGF0IGFuIGVycm9yIGhhcyBvY2N1cmVkIHdoaWxlIHByb2Nlc3NpbmcKICAqLwogIHN0YXRpYyBpbnQzMl90IGNvbnN0IE5VTExPUkRFUjsKCiAgLy8gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yIHB1YmxpYyBjb25zdHJ1Y3Rvci9kZXN0cnVjdG9yIC0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgLyoqCiAgKiBDb3B5IGNvbnN0cnVjdG9yLgogICogQHN0YWJsZQogICovCiAgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yKGNvbnN0IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciYgb3RoZXIpOwoKICAvKiogCiAgKiBEZXN0cnVjdG9yCiAgKiBAc3RhYmxlCiAgKi8KICB+Q29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yKCk7CiAgCiAgLy8gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yIHB1YmxpYyBtZXRob2RzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgLyoqCiAgKiBSZXR1cm5zIHRydWUgaWYgIm90aGVyIiBpcyB0aGUgc2FtZSBhcyAidGhpcyIKICAqIEBzdGFibGUKICAqLwogIFVCb29sIG9wZXJhdG9yPT0oY29uc3QgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yJiBvdGhlcikgY29uc3Q7CgogIC8qKgogICogUmV0dXJucyB0cnVlIGlmICJvdGhlciIgaXMgbm90IHRoZSBzYW1lIGFzICJ0aGlzIi4KICAqIEBzdGFibGUKICAqLwogIFVCb29sIG9wZXJhdG9yIT0oY29uc3QgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yJiBvdGhlcikgY29uc3Q7CgogIC8qKgogICogUmVzZXRzIHRoZSBjdXJzb3IgdG8gdGhlIGJlZ2lubmluZyBvZiB0aGUgc3RyaW5nLgogICogQHN0YWJsZQogICovCiAgdm9pZCByZXNldCh2b2lkKTsKICAgIAogIC8qKgogICogR2V0cyB0aGUgb3JkZXJpbmcgcHJpb3JpdHkgb2YgdGhlIG5leHQgY2hhcmFjdGVyIGluIHRoZSBzdHJpbmcuCiAgKiBAcGFyYW0gc3RhdHVzIHRoZSBlcnJvciBjb2RlIHN0YXR1cy4KICAqIEByZXR1cm4gdGhlIG5leHQgY2hhcmFjdGVyJ3Mgb3JkZXJpbmcuIG90aGVyd2lzZSByZXR1cm5zIE5VTExPUkRFUiBpZiBhbiAKICAqICAgICAgICAgZXJyb3IgaGFzIG9jY3VyZWQgb3IgaWYgdGhlIGVuZCBvZiBzdHJpbmcgaGFzIGJlZW4gcmVhY2hlZAogICogQHN0YWJsZQogICovCiAgaW50MzJfdCBuZXh0KFVFcnJvckNvZGUmIHN0YXR1cyk7CgogIC8qKgogICogR2V0IHRoZSBvcmRlcmluZyBwcmlvcml0eSBvZiB0aGUgcHJldmlvdXMgY29sbGF0aW9uIGVsZW1lbnQgaW4gdGhlIHN0cmluZy4KICAqIEBwYXJhbSBzdGF0dXMgdGhlIGVycm9yIGNvZGUgc3RhdHVzLgogICogQHJldHVybiB0aGUgcHJldmlvdXMgZWxlbWVudCdzIG9yZGVyaW5nLiBvdGhlcndpc2UgcmV0dXJucyBOVUxMT1JERVIgaWYgYW4gCiAgKiAgICAgICAgIGVycm9yIGhhcyBvY2N1cmVkIG9yIGlmIHRoZSBzdGFydCBvZiBzdHJpbmcgaGFzIGJlZW4gcmVhY2hlZAogICogQHN0YWJsZQogICovCiAgaW50MzJfdCBwcmV2aW91cyhVRXJyb3JDb2RlJiBzdGF0dXMpOwoKICAvKioKICAqIEdldHMgdGhlIHByaW1hcnkgb3JkZXIgb2YgYSBjb2xsYXRpb24gb3JkZXIuCiAgKiBAcGFyYW0gb3JkZXIgdGhlIGNvbGxhdGlvbiBvcmRlcgogICogQHJldHVybiB0aGUgcHJpbWFyeSBvcmRlciBvZiBhIGNvbGxhdGlvbiBvcmRlci4KICAqIEBzdGFibGUKICAqLwogIHN0YXRpYyBpbnQzMl90IHByaW1hcnlPcmRlcihpbnQzMl90IG9yZGVyKTsKCiAgLyoqCiAgKiBHZXRzIHRoZSBzZWNvbmRhcnkgb3JkZXIgb2YgYSBjb2xsYXRpb24gb3JkZXIuCiAgKiBAcGFyYW0gb3JkZXIgdGhlIGNvbGxhdGlvbiBvcmRlcgogICogQHJldHVybiB0aGUgc2Vjb25kYXJ5IG9yZGVyIG9mIGEgY29sbGF0aW9uIG9yZGVyLgogICogQHN0YWJsZQogICovCiAgc3RhdGljIGludDMyX3Qgc2Vjb25kYXJ5T3JkZXIoaW50MzJfdCBvcmRlcik7CgogIC8qKgogICogR2V0cyB0aGUgdGVydGlhcnkgb3JkZXIgb2YgYSBjb2xsYXRpb24gb3JkZXIuCiAgKiBAcGFyYW0gb3JkZXIgdGhlIGNvbGxhdGlvbiBvcmRlcgogICogQHJldHVybiB0aGUgdGVydGlhcnkgb3JkZXIgb2YgYSBjb2xsYXRpb24gb3JkZXIuCiAgKiBAc3RhYmxlCiAgKi8KICBzdGF0aWMgaW50MzJfdCB0ZXJ0aWFyeU9yZGVyKGludDMyX3Qgb3JkZXIpOwoKICAvKioKICAqIFJldHVybiB0aGUgbWF4aW11bSBsZW5ndGggb2YgYW55IGV4cGFuc2lvbiBzZXF1ZW5jZXMgdGhhdCBlbmQgd2l0aCB0aGUgCiAgKiBzcGVjaWZpZWQgY29tcGFyaXNvbiBvcmRlci4KICAqIEBwYXJhbSBvcmRlciBhIGNvbGxhdGlvbiBvcmRlciByZXR1cm5lZCBieSBwcmV2aW91cyBvciBuZXh0LgogICogQHJldHVybiBtYXhpbXVtIHNpemUgb2YgdGhlIGV4cGFuc2lvbiBzZXF1ZW5jZXMgZW5kaW5nIHdpdGggdGhlIGNvbGxhdGlvbiAKICAqICAgICAgICAgZWxlbWVudCBvciAxIGlmIGNvbGxhdGlvbiBlbGVtZW50IGRvZXMgbm90IG9jY3VyIGF0IHRoZSBlbmQgb2YgYW55IAogICogICAgICAgICBleHBhbnNpb24gc2VxdWVuY2UKICAqIEBzdGFibGUKICAqLwogIGludDMyX3QgZ2V0TWF4RXhwYW5zaW9uKGludDMyX3Qgb3JkZXIpIGNvbnN0OwoKICAvKioKICAqIEdldHMgdGhlIGNvbXBhcmlzb24gb3JkZXIgaW4gdGhlIGRlc2lyZWQgc3RyZW5ndGguIElnbm9yZSB0aGUgb3RoZXIKICAqIGRpZmZlcmVuY2VzLgogICogQHBhcmFtIG9yZGVyIFRoZSBvcmRlciB2YWx1ZQogICogQHN0YWJsZQogICovCiAgaW50MzJfdCBzdHJlbmd0aE9yZGVyKGludDMyX3Qgb3JkZXIpIGNvbnN0OwoKICAvKioKICAqIFNldHMgdGhlIHNvdXJjZSBzdHJpbmcuCiAgKiBAcGFyYW0gc3RyIHRoZSBzb3VyY2Ugc3RyaW5nLgogICogQHBhcmFtIHN0YXR1cyB0aGUgZXJyb3IgY29kZSBzdGF0dXMuCiAgKiBAc3RhYmxlCiAgKi8KICB2b2lkIHNldFRleHQoY29uc3QgVW5pY29kZVN0cmluZyYgc3RyLCBVRXJyb3JDb2RlJiBzdGF0dXMpOwoKICAvKioKICAqIFNldHMgdGhlIHNvdXJjZSBzdHJpbmcuCiAgKiBAcGFyYW0gc3RyIHRoZSBzb3VyY2UgY2hhcmFjdGVyIGl0ZXJhdG9yLgogICogQHBhcmFtIHN0YXR1cyB0aGUgZXJyb3IgY29kZSBzdGF0dXMuCiAgKiBAc3RhYmxlCiAgKi8KICB2b2lkIHNldFRleHQoQ2hhcmFjdGVySXRlcmF0b3ImIHN0ciwgVUVycm9yQ29kZSYgc3RhdHVzKTsKCiAgLyoqCiAgKiBDaGVja3MgaWYgYSBjb21wYXJpc29uIG9yZGVyIGlzIGlnbm9yYWJsZS4KICAqIEBwYXJhbSBvcmRlciB0aGUgY29sbGF0aW9uIG9yZGVyLgogICogQHJldHVybiBUUlVFIGlmIGEgY2hhcmFjdGVyIGlzIGlnbm9yYWJsZSwgRkFMU0Ugb3RoZXJ3aXNlLgogICogQHN0YWJsZQogICovCiAgc3RhdGljIFVCb29sIGlzSWdub3JhYmxlKGludDMyX3Qgb3JkZXIpOwoKICAvKioKICAqIEdldHMgdGhlIG9mZnNldCBvZiB0aGUgY3VycmVudGx5IHByb2Nlc3NlZCBjaGFyYWN0ZXIgaW4gdGhlIHNvdXJjZSBzdHJpbmcuCiAgKiBAcmV0dXJuIHRoZSBvZmZzZXQgb2YgdGhlIGNoYXJhY3Rlci4KICAqIEBzdGFibGUKICAqLwogIFVUZXh0T2Zmc2V0IGdldE9mZnNldCh2b2lkKSBjb25zdDsKCiAgLyoqCiAgKiBTZXRzIHRoZSBvZmZzZXQgb2YgdGhlIGN1cnJlbnRseSBwcm9jZXNzZWQgY2hhcmFjdGVyIGluIHRoZSBzb3VyY2Ugc3RyaW5nLgogICogQHBhcmFtIG5ld09mZnNldCB0aGUgbmV3IG9mZnNldC4KICAqIEBwYXJhbSBzdGF0dXMgdGhlIGVycm9yIGNvZGUgc3RhdHVzLgogICogQHJldHVybiB0aGUgb2Zmc2V0IG9mIHRoZSBjaGFyYWN0ZXIuCiAgKiBAc3RhYmxlCiAgKi8KICB2b2lkIHNldE9mZnNldChVVGV4dE9mZnNldCBuZXdPZmZzZXQsIFVFcnJvckNvZGUmIHN0YXR1cyk7Cgpwcm90ZWN0ZWQ6CiAgCiAgLy8gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yIHByb3RlY3RlZCBjb25zdHJ1Y3RvcnMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgZnJpZW5kIGNsYXNzIFJ1bGVCYXNlZENvbGxhdG9yOwoKICAvKioKICAqIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciBjb25zdHJ1Y3Rvci4gVGhpcyB0YWtlcyB0aGUgc291cmNlIHN0cmluZyBhbmQgdGhlIAogICogY29sbGF0aW9uIG9iamVjdC4gVGhlIGN1cnNvciB3aWxsIHdhbGsgdGhydSB0aGUgc291cmNlIHN0cmluZyBiYXNlZCBvbiB0aGUgCiAgKiBwcmVkZWZpbmVkIGNvbGxhdGlvbiBydWxlcy4gSWYgdGhlIHNvdXJjZSBzdHJpbmcgaXMgZW1wdHksIE5VTExPUkRFUiB3aWxsIAogICogYmUgcmV0dXJuZWQgb24gdGhlIGNhbGxzIHRvIG5leHQoKS4KICAqIEBwYXJhbSBzb3VyY2VUZXh0IHRoZSBzb3VyY2Ugc3RyaW5nLgogICogQHBhcmFtIHN0YXJ0T2Zmc2V0IHRoZSBiZWdpbm5pbmcgb2Zmc2V0IG9mIHRoZSBzdHJpbmcgd2hlcmUgdGhlIGN1cnNvciAKICAqICAgICAgICBzdGFydHMgdGhlIGl0ZXJhdGluZy4KICAqIEBwYXJhbSBlbmRPZmZzZXQgdGhlIGVuZGluZyBvZmZzZXQgb2YgdGhlIHN0cmluZyB3aGVyZSB0aGUgY3Vyc29yIHN0b3BzIHRoZSAKICAqICAgICAgICBpdGVyYXRpbmcuCiAgKiBAcGFyYW0gb3JkZXIgdGhlIGNvbGxhdGlvbiBvYmplY3QuCiAgKi8KICBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IoY29uc3QgVW5pY29kZVN0cmluZyYgc291cmNlVGV4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgUnVsZUJhc2VkQ29sbGF0b3IqIG9yZGVyLCBVRXJyb3JDb2RlJiBzdGF0dXMpOwoKICAvKioKICAqIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciBjb25zdHJ1Y3Rvci4gVGhpcyB0YWtlcyB0aGUgc291cmNlIHN0cmluZyBhbmQgdGhlIAogICogY29sbGF0aW9uIG9iamVjdC4gIFRoZSBjdXJzb3Igd2lsbCB3YWxrIHRocnUgdGhlIHNvdXJjZSBzdHJpbmcgYmFzZWQgb24gdGhlIAogICogcHJlZGVmaW5lZCBjb2xsYXRpb24gcnVsZXMuICBJZiB0aGUgc291cmNlIHN0cmluZyBpcyBlbXB0eSwgTlVMTE9SREVSIHdpbGwgCiAgKiBiZSByZXR1cm5lZCBvbiB0aGUgY2FsbHMgdG8gbmV4dCgpLgogICogQHBhcmFtIHNvdXJjZVRleHQgdGhlIHNvdXJjZSBzdHJpbmcuCiAgKiBAcGFyYW0gc3RhcnRPZmZzZXQgdGhlIGJlZ2lubmluZyBvZmZzZXQgb2YgdGhlIHN0cmluZyB3aGVyZSB0aGUgY3Vyc29yIAogICogICAgICAgIHN0YXJ0cyB0aGUgaXRlcmF0aW5nLgogICogQHBhcmFtIGVuZE9mZnNldCB0aGUgZW5kaW5nIG9mZnNldCBvZiB0aGUgc3RyaW5nIHdoZXJlIHRoZSBjdXJzb3Igc3RvcHMgdGhlIAogICogICAgICAgIGl0ZXJhdGluZy4KICAqIEBwYXJhbSBvcmRlciB0aGUgY29sbGF0aW9uIG9iamVjdC4KICAqLwogIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcihjb25zdCBDaGFyYWN0ZXJJdGVyYXRvciYgc291cmNlVGV4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgUnVsZUJhc2VkQ29sbGF0b3IqIG9yZGVyLCBVRXJyb3JDb2RlJiBzdGF0dXMpOwogIAogIC8vIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciBwcm90ZWN0ZWQgbWV0aG9kcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogIC8qKgogICogQXNzaWdubWVudCBvcGVyYXRvcgogICovCiAgY29uc3QgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yJgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcGVyYXRvcj0oY29uc3QgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yJiBvdGhlcik7Cgpwcml2YXRlOgoKICAvLyBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IgcHJpdmF0ZSBkYXRhIG1lbWJlcnMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAvKioKICAqIERhdGEgd3JhcHBlciBmb3IgY29sbGF0aW9uIGVsZW1lbnRzCiAgKi8KICBVQ29sbGF0aW9uRWxlbWVudHMgKm1fZGF0YV87CgogIC8qKgogICogSW5kaWNhdGVzIGlmIG1fZGF0YV8gYmVsb25ncyB0byB0aGlzIG9iamVjdC4KICAqLwogIFVCb29sIGlzRGF0YU93bmVkXzsKfTsKCi8vIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciBpbmxpbmUgbWV0aG9kIGRlZmluYXRpb24gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCi8qKgoqIEdldCB0aGUgcHJpbWFyeSBvcmRlciBvZiBhIGNvbGxhdGlvbiBvcmRlci4KKiBAcGFyYW0gb3JkZXIgdGhlIGNvbGxhdGlvbiBvcmRlcgoqIEByZXR1cm4gdGhlIHByaW1hcnkgb3JkZXIgb2YgYSBjb2xsYXRpb24gb3JkZXIuCiovCmlubGluZSBpbnQzMl90IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6cHJpbWFyeU9yZGVyKGludDMyX3Qgb3JkZXIpCnsKICBvcmRlciAmPSBSdWxlQmFzZWRDb2xsYXRvcjo6UFJJTUFSWU9SREVSTUFTSzsKICByZXR1cm4gKG9yZGVyID4+IFJ1bGVCYXNlZENvbGxhdG9yOjpQUklNQVJZT1JERVJTSElGVCk7Cn0KCi8qKgoqIEdldCB0aGUgc2Vjb25kYXJ5IG9yZGVyIG9mIGEgY29sbGF0aW9uIG9yZGVyLgoqIEBwYXJhbSBvcmRlciB0aGUgY29sbGF0aW9uIG9yZGVyCiogQHJldHVybiB0aGUgc2Vjb25kYXJ5IG9yZGVyIG9mIGEgY29sbGF0aW9uIG9yZGVyLgoqLwppbmxpbmUgaW50MzJfdCBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6OnNlY29uZGFyeU9yZGVyKGludDMyX3Qgb3JkZXIpCnsKICBvcmRlciA9IG9yZGVyICYgUnVsZUJhc2VkQ29sbGF0b3I6OlNFQ09OREFSWU9SREVSTUFTSzsKICByZXR1cm4gKG9yZGVyID4+IFJ1bGVCYXNlZENvbGxhdG9yOjpTRUNPTkRBUllPUkRFUlNISUZUKTsKfQoKLyoqCiogR2V0IHRoZSB0ZXJ0aWFyeSBvcmRlciBvZiBhIGNvbGxhdGlvbiBvcmRlci4KKiBAcGFyYW0gb3JkZXIgdGhlIGNvbGxhdGlvbiBvcmRlcgoqIEByZXR1cm4gdGhlIHRlcnRpYXJ5IG9yZGVyIG9mIGEgY29sbGF0aW9uIG9yZGVyLgoqLwppbmxpbmUgaW50MzJfdCBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6OnRlcnRpYXJ5T3JkZXIoaW50MzJfdCBvcmRlcikKewogIHJldHVybiAob3JkZXIgJj0gUnVsZUJhc2VkQ29sbGF0b3I6OlRFUlRJQVJZT1JERVJNQVNLKTsKfQoKaW5saW5lIGludDMyX3QgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpnZXRNYXhFeHBhbnNpb24oaW50MzJfdCBvcmRlcikgY29uc3QKewogIHJldHVybiB1Y29sX2dldE1heEV4cGFuc2lvbihtX2RhdGFfLCAodWludDMyX3Qpb3JkZXIpOwp9CgppbmxpbmUgVUJvb2wgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjppc0lnbm9yYWJsZShpbnQzMl90IG9yZGVyKQp7CiAgcmV0dXJuIChwcmltYXJ5T3JkZXIob3JkZXIpID09IFJ1bGVCYXNlZENvbGxhdG9yOjpQUklNSUdOT1JBQkxFKTsKfQoKVV9OQU1FU1BBQ0VfRU5ECgojZW5kaWYK