LyoKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiogICBDb3B5cmlnaHQgKEMpIDE5OTctMjAwMSwgSW50ZXJuYXRpb25hbCBCdXNpbmVzcyBNYWNoaW5lcwoqICAgQ29ycG9yYXRpb24gYW5kIG90aGVycy4gIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqLwoKLyoqCiogRmlsZSBjb2xlaXRyLmgKKgoqIAoqCiogQ3JlYXRlZCBieTogSGVsZW5hIFNoaWgKKgoqIE1vZGlmaWNhdGlvbiBIaXN0b3J5OgoqCiogIERhdGUgICAgICAgTmFtZSAgICAgICAgRGVzY3JpcHRpb24KKgoqICA4LzE4Lzk3ICAgIGhlbGVuYSAgICAgIEFkZGVkIGludGVybmFsIEFQSSBkb2N1bWVudGF0aW9uLgoqIDA4LzAzLzk4ICAgIGVybSAgICAgICAgIFN5bmNoZWQgd2l0aCAxLjIgdmVyc2lvbiBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IuamF2YQoqIDEyLzEwLzk5ICAgIGFsaXUgICAgICAgIFBvcnRlZCBUaGFpIGNvbGxhdGlvbiBzdXBwb3J0IGZyb20gSmF2YS4KKiAwMS8yNS8wMSAgICBzd3F1ZWsgICAgICBNb2RpZmllZCBpbnRvIGEgQysrIHdyYXBwZXIgY2FsbGluZyBDIEFQSXMgKHVjb2xpdGVyLmgpCiogMDIvMTkvMDEgICAgc3dxdWVrICAgICAgUmVtb3ZlZCBDb2xsYXRpb25FbGVtZW50c0l0ZXJhdG9yKCkgc2luY2UgaXQgaXMgCiogICAgICAgICAgICAgICAgICAgICAgICAgcHJpdmF0ZSBjb25zdHJ1Y3RvciBhbmQgbm8gY2FsbHMgYXJlIG1hZGUgdG8gaXQKKi8KCiNpZm5kZWYgQ09MRUlUUl9ICiNkZWZpbmUgQ09MRUlUUl9ICgojaW5jbHVkZSAidW5pY29kZS90Ymxjb2xsLmgiCiNpbmNsdWRlICJ1bmljb2RlL3Vjb2xlaXRyLmgiCgp0eXBlZGVmIHN0cnVjdCBVQ29sbGF0aW9uRWxlbWVudHMgVUNvbGxhdGlvbkVsZW1lbnRzOwoKVV9OQU1FU1BBQ0VfQkVHSU4KCi8qKgoqIFRoZSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IgY2xhc3MgaXMgdXNlZCBhcyBhbiBpdGVyYXRvciB0byB3YWxrIHRocm91Z2ggICAgIAoqIGVhY2ggY2hhcmFjdGVyIG9mIGFuIGludGVybmF0aW9uYWwgc3RyaW5nLiBVc2UgdGhlIGl0ZXJhdG9yIHRvIHJldHVybiB0aGUKKiBvcmRlcmluZyBwcmlvcml0eSBvZiB0aGUgcG9zaXRpb25lZCBjaGFyYWN0ZXIuIFRoZSBvcmRlcmluZyBwcmlvcml0eSBvZiBhIAoqIGNoYXJhY3Rlciwgd2hpY2ggd2UgcmVmZXIgdG8gYXMgYSBrZXksIGRlZmluZXMgaG93IGEgY2hhcmFjdGVyIGlzIGNvbGxhdGVkIGluIAoqIHRoZSBnaXZlbiBjb2xsYXRpb24gb2JqZWN0LgoqIEZvciBleGFtcGxlLCBjb25zaWRlciB0aGUgZm9sbG93aW5nIGluIFNwYW5pc2g6CiogPHByZT4KKiBcY29kZQoqICAgICAgICAiY2EiIC0+IHRoZSBmaXJzdCBrZXkgaXMga2V5KCdjJykgYW5kIHNlY29uZCBrZXkgaXMga2V5KCdhJykuCiogICAgICAgICJjaGEiIC0+IHRoZSBmaXJzdCBrZXkgaXMga2V5KCdjaCcpIGFuZCBzZWNvbmQga2V5IGlzIGtleSgnYScpLgoqIFxlbmRjb2RlCiogPC9wcmU+CiogQW5kIGluIEdlcm1hbiwKKiA8cHJlPgoqIFxjb2RlCiogICAgICAgICLmYiItPiB0aGUgZmlyc3Qga2V5IGlzIGtleSgnYScpLCB0aGUgc2Vjb25kIGtleSBpcyBrZXkoJ2UnKSwgYW5kCiogICAgICAgIHRoZSB0aGlyZCBrZXkgaXMga2V5KCdiJykuCiogXGVuZGNvZGUKKiA8L3ByZT4KKiBUaGUga2V5IG9mIGEgY2hhcmFjdGVyLCBpcyBhbiBpbnRlZ2VyIGNvbXBvc2VkIG9mIHByaW1hcnkgb3JkZXIoc2hvcnQpLAoqIHNlY29uZGFyeSBvcmRlcihjaGFyKSwgYW5kIHRlcnRpYXJ5IG9yZGVyKGNoYXIpLiBKYXZhIHN0cmljdGx5IGRlZmluZXMgdGhlIAoqIHNpemUgYW5kIHNpZ25lZG5lc3Mgb2YgaXRzIHByaW1pdGl2ZSBkYXRhIHR5cGVzLiBUaGVyZWZvcmUsIHRoZSBzdGF0aWMKKiBmdW5jdGlvbnMgcHJpbWFyeU9yZGVyKCksIHNlY29uZGFyeU9yZGVyKCksIGFuZCB0ZXJ0aWFyeU9yZGVyKCkgcmV0dXJuIAoqIGludDMyX3QgdG8gZW5zdXJlIHRoZSBjb3JyZWN0bmVzcyBvZiB0aGUga2V5IHZhbHVlLgoqIDxwPkV4YW1wbGUgb2YgdGhlIGl0ZXJhdG9yIHVzYWdlOiAod2l0aG91dCBlcnJvciBjaGVja2luZykKKiA8cHJlPgoqIFxjb2RlCiogICB2b2lkIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcl9FeGFtcGxlKCkKKiAgIHsKKiAgICAgICBVbmljb2RlU3RyaW5nIHN0ciA9ICJUaGlzIGlzIGEgdGVzdCI7CiogICAgICAgVUVycm9yQ29kZSBzdWNjZXNzID0gVV9aRVJPX0VSUk9SOwoqICAgICAgIFJ1bGVCYXNlZENvbGxhdG9yKiByYmMgPQoqICAgICAgICAgICAoUnVsZUJhc2VkQ29sbGF0b3IqKSBSdWxlQmFzZWRDb2xsYXRvcjo6Y3JlYXRlSW5zdGFuY2Uoc3VjY2Vzcyk7CiogICAgICAgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yKiBjID0KKiAgICAgICAgICAgcmJjLT5jcmVhdGVDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IoIHN0ciApOwoqICAgICAgIGludDMyX3Qgb3JkZXIgPSBjLT5uZXh0KHN1Y2Nlc3MpOwoqICAgICAgIGMtPnJlc2V0KCk7CiogICAgICAgb3JkZXIgPSBjLT5wcmV2aW91cyhzdWNjZXNzKTsKKiAgICAgICBkZWxldGUgYzsKKiAgICAgICBkZWxldGUgcmJjOwoqICAgfQoqIFxlbmRjb2RlCiogPC9wcmU+CiogPHA+CiogQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpuZXh0IHJldHVybnMgdGhlIGNvbGxhdGlvbiBvcmRlciBvZiB0aGUgbmV4dAoqIGNoYXJhY3RlciBiYXNlZCBvbiB0aGUgY29tcGFyaXNvbiBsZXZlbCBvZiB0aGUgY29sbGF0b3IuIAoqIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6cHJldmlvdXMgcmV0dXJucyB0aGUgY29sbGF0aW9uIG9yZGVyIG9mIHRoZSAKKiBwcmV2aW91cyBjaGFyYWN0ZXIgYmFzZWQgb24gdGhlIGNvbXBhcmlzb24gbGV2ZWwgb2YgdGhlIGNvbGxhdG9yLiAKKiBUaGUgQ29sbGF0aW9uIEVsZW1lbnQgSXRlcmF0b3IgbW92ZXMgb25seSBpbiBvbmUgZGlyZWN0aW9uIGJldHdlZW4gY2FsbHMgdG8KKiBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6OnJlc2V0LiBUaGF0IGlzLCBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6Om5leHQoKSAKKiBhbmQgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpwcmV2aW91cyBjYW4gbm90IGJlIGludGVyLXVzZWQuIFdoZW5ldmVyIAoqIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6cHJldmlvdXMgaXMgdG8gYmUgY2FsbGVkIGFmdGVyIAoqIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6bmV4dCgpIG9yIHZpY2UgdmVyc2EsIAoqIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6cmVzZXQgaGFzIHRvIGJlIGNhbGxlZCBmaXJzdCB0byByZXNldCB0aGUgc3RhdHVzLCAKKiBzaGlmdGluZyBwb2ludGVycyB0byBlaXRoZXIgdGhlIGVuZCBvciB0aGUgc3RhcnQgb2YgdGhlIHN0cmluZy4gSGVuY2UgYXQgdGhlIAoqIG5leHQgY2FsbCBvZiBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6OnByZXZpb3VzIG9yIAoqIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6bmV4dCgpLCB0aGUgZmlyc3Qgb3IgbGFzdCBjb2xsYXRpb24gb3JkZXIgd2lsbCBiZSAKKiByZXR1cm5lZC4gCiogSWYgYSBjaGFuZ2Ugb2YgZGlyZWN0aW9uIGlzIGRvbmUgd2l0aG91dCBhIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6cmVzZXQoKSwgCiogdGhlIHJlc3VsdCBpcyB1bmRlZmluZWQuCiogVGhlIHJlc3VsdCBvZiBhIGZvcndhcmQgaXRlcmF0ZSAoQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpuZXh0KSBhbmQgCiogcmV2ZXJzZWQgcmVzdWx0IG9mIHRoZSBiYWNrd2FyZCBpdGVyYXRlIChDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6OnByZXZpb3VzKSAKKiBvbiB0aGUgc2FtZSBzdHJpbmcgYXJlIGVxdWl2YWxlbnQsIGlmIGNvbGxhdGlvbiBvcmRlcnMgd2l0aCB0aGUgdmFsdWUgCiogVUNPTF9JR05PUkFCTEUgYXJlIGlnbm9yZWQuCiogQ2hhcmFjdGVyIGJhc2VkIG9uIHRoZSBjb21wYXJpc29uIGxldmVsIG9mIHRoZSBjb2xsYXRvci4gIEEgY29sbGF0aW9uIG9yZGVyIAoqIGNvbnNpc3RzIG9mIHByaW1hcnkgb3JkZXIsIHNlY29uZGFyeSBvcmRlciBhbmQgdGVydGlhcnkgb3JkZXIuICBUaGUgZGF0YSAKKiB0eXBlIG9mIHRoZSBjb2xsYXRpb24gb3JkZXIgaXMgPHN0cm9uZz50X2ludDMyPC9zdHJvbmc+LiAKKgoqIE5vdGUsIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciBzaG91bGQgbm90IGJlIHN1YmNsYXNzZWQuCiogQHNlZSAgICAgQ29sbGF0b3IKKiBAc2VlICAgICBSdWxlQmFzZWRDb2xsYXRvcgoqIEB2ZXJzaW9uIDEuOCBKYW4gMTYgMjAwMQoqLwpjbGFzcyBVX0kxOE5fQVBJIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcgp7CnB1YmxpYzogCgogIC8vIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciBwdWJsaWMgZGF0YSBtZW1iZXIgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogIC8qKgogICogTlVMTE9SREVSIGluZGljYXRlcyB0aGF0IGFuIGVycm9yIGhhcyBvY2N1cmVkIHdoaWxlIHByb2Nlc3NpbmcKICAqLwogIHN0YXRpYyBpbnQzMl90IGNvbnN0IE5VTExPUkRFUjsKCiAgLy8gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yIHB1YmxpYyBjb25zdHJ1Y3Rvci9kZXN0cnVjdG9yIC0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgLyoqCiAgKiBDb3B5IGNvbnN0cnVjdG9yLgogICogQHN0YWJsZQogICovCiAgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yKGNvbnN0IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciYgb3RoZXIpOwoKICAvKiogCiAgKiBEZXN0cnVjdG9yCiAgKiBAc3RhYmxlCiAgKi8KICB+Q29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yKCk7CiAgCiAgLy8gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yIHB1YmxpYyBtZXRob2RzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgLyoqCiAgKiBSZXR1cm5zIHRydWUgaWYgIm90aGVyIiBpcyB0aGUgc2FtZSBhcyAidGhpcyIKICAqIEBzdGFibGUKICAqLwogIFVCb29sIG9wZXJhdG9yPT0oY29uc3QgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yJiBvdGhlcikgY29uc3Q7CgogIC8qKgogICogUmV0dXJucyB0cnVlIGlmICJvdGhlciIgaXMgbm90IHRoZSBzYW1lIGFzICJ0aGlzIi4KICAqIEBzdGFibGUKICAqLwogIFVCb29sIG9wZXJhdG9yIT0oY29uc3QgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yJiBvdGhlcikgY29uc3Q7CgogIC8qKgogICogUmVzZXRzIHRoZSBjdXJzb3IgdG8gdGhlIGJlZ2lubmluZyBvZiB0aGUgc3RyaW5nLgogICogQHN0YWJsZQogICovCiAgdm9pZCByZXNldCh2b2lkKTsKICAgIAogIC8qKgogICogR2V0cyB0aGUgb3JkZXJpbmcgcHJpb3JpdHkgb2YgdGhlIG5leHQgY2hhcmFjdGVyIGluIHRoZSBzdHJpbmcuCiAgKiBAcGFyYW0gc3RhdHVzIHRoZSBlcnJvciBjb2RlIHN0YXR1cy4KICAqIEByZXR1cm4gdGhlIG5leHQgY2hhcmFjdGVyJ3Mgb3JkZXJpbmcuIG90aGVyd2lzZSByZXR1cm5zIE5VTExPUkRFUiBpZiBhbiAKICAqICAgICAgICAgZXJyb3IgaGFzIG9jY3VyZWQgb3IgaWYgdGhlIGVuZCBvZiBzdHJpbmcgaGFzIGJlZW4gcmVhY2hlZAogICogQHN0YWJsZQogICovCiAgaW50MzJfdCBuZXh0KFVFcnJvckNvZGUmIHN0YXR1cyk7CgogIC8qKgogICogR2V0IHRoZSBvcmRlcmluZyBwcmlvcml0eSBvZiB0aGUgcHJldmlvdXMgY29sbGF0aW9uIGVsZW1lbnQgaW4gdGhlIHN0cmluZy4KICAqIEBwYXJhbSBzdGF0dXMgdGhlIGVycm9yIGNvZGUgc3RhdHVzLgogICogQHJldHVybiB0aGUgcHJldmlvdXMgZWxlbWVudCdzIG9yZGVyaW5nLiBvdGhlcndpc2UgcmV0dXJucyBOVUxMT1JERVIgaWYgYW4gCiAgKiAgICAgICAgIGVycm9yIGhhcyBvY2N1cmVkIG9yIGlmIHRoZSBzdGFydCBvZiBzdHJpbmcgaGFzIGJlZW4gcmVhY2hlZAogICogQHN0YWJsZQogICovCiAgaW50MzJfdCBwcmV2aW91cyhVRXJyb3JDb2RlJiBzdGF0dXMpOwoKICAvKioKICAqIEdldHMgdGhlIHByaW1hcnkgb3JkZXIgb2YgYSBjb2xsYXRpb24gb3JkZXIuCiAgKiBAcGFyYW0gb3JkZXIgdGhlIGNvbGxhdGlvbiBvcmRlcgogICogQHJldHVybiB0aGUgcHJpbWFyeSBvcmRlciBvZiBhIGNvbGxhdGlvbiBvcmRlci4KICAqIEBzdGFibGUKICAqLwogIHN0YXRpYyBpbnQzMl90IHByaW1hcnlPcmRlcihpbnQzMl90IG9yZGVyKTsKCiAgLyoqCiAgKiBHZXRzIHRoZSBzZWNvbmRhcnkgb3JkZXIgb2YgYSBjb2xsYXRpb24gb3JkZXIuCiAgKiBAcGFyYW0gb3JkZXIgdGhlIGNvbGxhdGlvbiBvcmRlcgogICogQHJldHVybiB0aGUgc2Vjb25kYXJ5IG9yZGVyIG9mIGEgY29sbGF0aW9uIG9yZGVyLgogICogQHN0YWJsZQogICovCiAgc3RhdGljIGludDMyX3Qgc2Vjb25kYXJ5T3JkZXIoaW50MzJfdCBvcmRlcik7CgogIC8qKgogICogR2V0cyB0aGUgdGVydGlhcnkgb3JkZXIgb2YgYSBjb2xsYXRpb24gb3JkZXIuCiAgKiBAcGFyYW0gb3JkZXIgdGhlIGNvbGxhdGlvbiBvcmRlcgogICogQHJldHVybiB0aGUgdGVydGlhcnkgb3JkZXIgb2YgYSBjb2xsYXRpb24gb3JkZXIuCiAgKiBAc3RhYmxlCiAgKi8KICBzdGF0aWMgaW50MzJfdCB0ZXJ0aWFyeU9yZGVyKGludDMyX3Qgb3JkZXIpOwoKICAvKioKICAqIFJldHVybiB0aGUgbWF4aW11bSBsZW5ndGggb2YgYW55IGV4cGFuc2lvbiBzZXF1ZW5jZXMgdGhhdCBlbmQgd2l0aCB0aGUgCiAgKiBzcGVjaWZpZWQgY29tcGFyaXNvbiBvcmRlci4KICAqIEBwYXJhbSBvcmRlciBhIGNvbGxhdGlvbiBvcmRlciByZXR1cm5lZCBieSBwcmV2aW91cyBvciBuZXh0LgogICogQHJldHVybiBtYXhpbXVtIHNpemUgb2YgdGhlIGV4cGFuc2lvbiBzZXF1ZW5jZXMgZW5kaW5nIHdpdGggdGhlIGNvbGxhdGlvbiAKICAqICAgICAgICAgZWxlbWVudCBvciAxIGlmIGNvbGxhdGlvbiBlbGVtZW50IGRvZXMgbm90IG9jY3VyIGF0IHRoZSBlbmQgb2YgYW55IAogICogICAgICAgICBleHBhbnNpb24gc2VxdWVuY2UKICAqIEBzdGFibGUKICAqLwogIGludDMyX3QgZ2V0TWF4RXhwYW5zaW9uKGludDMyX3Qgb3JkZXIpIGNvbnN0OwoKICAvKioKICAqIEdldHMgdGhlIGNvbXBhcmlzb24gb3JkZXIgaW4gdGhlIGRlc2lyZWQgc3RyZW5ndGguIElnbm9yZSB0aGUgb3RoZXIKICAqIGRpZmZlcmVuY2VzLgogICogQHBhcmFtIG9yZGVyIFRoZSBvcmRlciB2YWx1ZQogICogQHN0YWJsZQogICovCiAgaW50MzJfdCBzdHJlbmd0aE9yZGVyKGludDMyX3Qgb3JkZXIpIGNvbnN0OwoKICAvKioKICAqIFNldHMgdGhlIHNvdXJjZSBzdHJpbmcuCiAgKiBAcGFyYW0gc3RyIHRoZSBzb3VyY2Ugc3RyaW5nLgogICogQHBhcmFtIHN0YXR1cyB0aGUgZXJyb3IgY29kZSBzdGF0dXMuCiAgKiBAc3RhYmxlCiAgKi8KICB2b2lkIHNldFRleHQoY29uc3QgVW5pY29kZVN0cmluZyYgc3RyLCBVRXJyb3JDb2RlJiBzdGF0dXMpOwoKICAvKioKICAqIFNldHMgdGhlIHNvdXJjZSBzdHJpbmcuCiAgKiBAcGFyYW0gc3RyIHRoZSBzb3VyY2UgY2hhcmFjdGVyIGl0ZXJhdG9yLgogICogQHBhcmFtIHN0YXR1cyB0aGUgZXJyb3IgY29kZSBzdGF0dXMuCiAgKiBAc3RhYmxlCiAgKi8KICB2b2lkIHNldFRleHQoQ2hhcmFjdGVySXRlcmF0b3ImIHN0ciwgVUVycm9yQ29kZSYgc3RhdHVzKTsKCiAgLyoqCiAgKiBDaGVja3MgaWYgYSBjb21wYXJpc29uIG9yZGVyIGlzIGlnbm9yYWJsZS4KICAqIEBwYXJhbSBvcmRlciB0aGUgY29sbGF0aW9uIG9yZGVyLgogICogQHJldHVybiBUUlVFIGlmIGEgY2hhcmFjdGVyIGlzIGlnbm9yYWJsZSwgRkFMU0Ugb3RoZXJ3aXNlLgogICogQHN0YWJsZQogICovCiAgc3RhdGljIFVCb29sIGlzSWdub3JhYmxlKGludDMyX3Qgb3JkZXIpOwoKICAvKioKICAqIEdldHMgdGhlIG9mZnNldCBvZiB0aGUgY3VycmVudGx5IHByb2Nlc3NlZCBjaGFyYWN0ZXIgaW4gdGhlIHNvdXJjZSBzdHJpbmcuCiAgKiBAcmV0dXJuIHRoZSBvZmZzZXQgb2YgdGhlIGNoYXJhY3Rlci4KICAqIEBzdGFibGUKICAqLwogIGludDMyX3QgZ2V0T2Zmc2V0KHZvaWQpIGNvbnN0OwoKICAvKioKICAqIFNldHMgdGhlIG9mZnNldCBvZiB0aGUgY3VycmVudGx5IHByb2Nlc3NlZCBjaGFyYWN0ZXIgaW4gdGhlIHNvdXJjZSBzdHJpbmcuCiAgKiBAcGFyYW0gbmV3T2Zmc2V0IHRoZSBuZXcgb2Zmc2V0LgogICogQHBhcmFtIHN0YXR1cyB0aGUgZXJyb3IgY29kZSBzdGF0dXMuCiAgKiBAcmV0dXJuIHRoZSBvZmZzZXQgb2YgdGhlIGNoYXJhY3Rlci4KICAqIEBzdGFibGUKICAqLwogIHZvaWQgc2V0T2Zmc2V0KGludDMyX3QgbmV3T2Zmc2V0LCBVRXJyb3JDb2RlJiBzdGF0dXMpOwoKcHJvdGVjdGVkOgogIAogIC8vIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciBwcm90ZWN0ZWQgY29uc3RydWN0b3JzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogIGZyaWVuZCBjbGFzcyBSdWxlQmFzZWRDb2xsYXRvcjsKCiAgLyoqCiAgKiBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IgY29uc3RydWN0b3IuIFRoaXMgdGFrZXMgdGhlIHNvdXJjZSBzdHJpbmcgYW5kIHRoZSAKICAqIGNvbGxhdGlvbiBvYmplY3QuIFRoZSBjdXJzb3Igd2lsbCB3YWxrIHRocnUgdGhlIHNvdXJjZSBzdHJpbmcgYmFzZWQgb24gdGhlIAogICogcHJlZGVmaW5lZCBjb2xsYXRpb24gcnVsZXMuIElmIHRoZSBzb3VyY2Ugc3RyaW5nIGlzIGVtcHR5LCBOVUxMT1JERVIgd2lsbCAKICAqIGJlIHJldHVybmVkIG9uIHRoZSBjYWxscyB0byBuZXh0KCkuCiAgKiBAcGFyYW0gc291cmNlVGV4dCB0aGUgc291cmNlIHN0cmluZy4KICAqIEBwYXJhbSBzdGFydE9mZnNldCB0aGUgYmVnaW5uaW5nIG9mZnNldCBvZiB0aGUgc3RyaW5nIHdoZXJlIHRoZSBjdXJzb3IgCiAgKiAgICAgICAgc3RhcnRzIHRoZSBpdGVyYXRpbmcuCiAgKiBAcGFyYW0gZW5kT2Zmc2V0IHRoZSBlbmRpbmcgb2Zmc2V0IG9mIHRoZSBzdHJpbmcgd2hlcmUgdGhlIGN1cnNvciBzdG9wcyB0aGUgCiAgKiAgICAgICAgaXRlcmF0aW5nLgogICogQHBhcmFtIG9yZGVyIHRoZSBjb2xsYXRpb24gb2JqZWN0LgogICovCiAgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yKGNvbnN0IFVuaWNvZGVTdHJpbmcmIHNvdXJjZVRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFJ1bGVCYXNlZENvbGxhdG9yKiBvcmRlciwgVUVycm9yQ29kZSYgc3RhdHVzKTsKCiAgLyoqCiAgKiBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IgY29uc3RydWN0b3IuIFRoaXMgdGFrZXMgdGhlIHNvdXJjZSBzdHJpbmcgYW5kIHRoZSAKICAqIGNvbGxhdGlvbiBvYmplY3QuICBUaGUgY3Vyc29yIHdpbGwgd2FsayB0aHJ1IHRoZSBzb3VyY2Ugc3RyaW5nIGJhc2VkIG9uIHRoZSAKICAqIHByZWRlZmluZWQgY29sbGF0aW9uIHJ1bGVzLiAgSWYgdGhlIHNvdXJjZSBzdHJpbmcgaXMgZW1wdHksIE5VTExPUkRFUiB3aWxsIAogICogYmUgcmV0dXJuZWQgb24gdGhlIGNhbGxzIHRvIG5leHQoKS4KICAqIEBwYXJhbSBzb3VyY2VUZXh0IHRoZSBzb3VyY2Ugc3RyaW5nLgogICogQHBhcmFtIHN0YXJ0T2Zmc2V0IHRoZSBiZWdpbm5pbmcgb2Zmc2V0IG9mIHRoZSBzdHJpbmcgd2hlcmUgdGhlIGN1cnNvciAKICAqICAgICAgICBzdGFydHMgdGhlIGl0ZXJhdGluZy4KICAqIEBwYXJhbSBlbmRPZmZzZXQgdGhlIGVuZGluZyBvZmZzZXQgb2YgdGhlIHN0cmluZyB3aGVyZSB0aGUgY3Vyc29yIHN0b3BzIHRoZSAKICAqICAgICAgICBpdGVyYXRpbmcuCiAgKiBAcGFyYW0gb3JkZXIgdGhlIGNvbGxhdGlvbiBvYmplY3QuCiAgKi8KICBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IoY29uc3QgQ2hhcmFjdGVySXRlcmF0b3ImIHNvdXJjZVRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFJ1bGVCYXNlZENvbGxhdG9yKiBvcmRlciwgVUVycm9yQ29kZSYgc3RhdHVzKTsKICAKICAvLyBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IgcHJvdGVjdGVkIG1ldGhvZHMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAvKioKICAqIEFzc2lnbm1lbnQgb3BlcmF0b3IKICAqLwogIGNvbnN0IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciYKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3BlcmF0b3I9KGNvbnN0IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciYgb3RoZXIpOwoKcHJpdmF0ZToKCiAgLy8gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yIHByaXZhdGUgZGF0YSBtZW1iZXJzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgLyoqCiAgKiBEYXRhIHdyYXBwZXIgZm9yIGNvbGxhdGlvbiBlbGVtZW50cwogICovCiAgVUNvbGxhdGlvbkVsZW1lbnRzICptX2RhdGFfOwoKICAvKioKICAqIEluZGljYXRlcyBpZiBtX2RhdGFfIGJlbG9uZ3MgdG8gdGhpcyBvYmplY3QuCiAgKi8KICBVQm9vbCBpc0RhdGFPd25lZF87Cn07CgovLyBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IgaW5saW5lIG1ldGhvZCBkZWZpbmF0aW9uIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgovKioKKiBHZXQgdGhlIHByaW1hcnkgb3JkZXIgb2YgYSBjb2xsYXRpb24gb3JkZXIuCiogQHBhcmFtIG9yZGVyIHRoZSBjb2xsYXRpb24gb3JkZXIKKiBAcmV0dXJuIHRoZSBwcmltYXJ5IG9yZGVyIG9mIGEgY29sbGF0aW9uIG9yZGVyLgoqLwppbmxpbmUgaW50MzJfdCBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6OnByaW1hcnlPcmRlcihpbnQzMl90IG9yZGVyKQp7CiAgb3JkZXIgJj0gUnVsZUJhc2VkQ29sbGF0b3I6OlBSSU1BUllPUkRFUk1BU0s7CiAgcmV0dXJuIChvcmRlciA+PiBSdWxlQmFzZWRDb2xsYXRvcjo6UFJJTUFSWU9SREVSU0hJRlQpOwp9CgovKioKKiBHZXQgdGhlIHNlY29uZGFyeSBvcmRlciBvZiBhIGNvbGxhdGlvbiBvcmRlci4KKiBAcGFyYW0gb3JkZXIgdGhlIGNvbGxhdGlvbiBvcmRlcgoqIEByZXR1cm4gdGhlIHNlY29uZGFyeSBvcmRlciBvZiBhIGNvbGxhdGlvbiBvcmRlci4KKi8KaW5saW5lIGludDMyX3QgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpzZWNvbmRhcnlPcmRlcihpbnQzMl90IG9yZGVyKQp7CiAgb3JkZXIgPSBvcmRlciAmIFJ1bGVCYXNlZENvbGxhdG9yOjpTRUNPTkRBUllPUkRFUk1BU0s7CiAgcmV0dXJuIChvcmRlciA+PiBSdWxlQmFzZWRDb2xsYXRvcjo6U0VDT05EQVJZT1JERVJTSElGVCk7Cn0KCi8qKgoqIEdldCB0aGUgdGVydGlhcnkgb3JkZXIgb2YgYSBjb2xsYXRpb24gb3JkZXIuCiogQHBhcmFtIG9yZGVyIHRoZSBjb2xsYXRpb24gb3JkZXIKKiBAcmV0dXJuIHRoZSB0ZXJ0aWFyeSBvcmRlciBvZiBhIGNvbGxhdGlvbiBvcmRlci4KKi8KaW5saW5lIGludDMyX3QgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjp0ZXJ0aWFyeU9yZGVyKGludDMyX3Qgb3JkZXIpCnsKICByZXR1cm4gKG9yZGVyICY9IFJ1bGVCYXNlZENvbGxhdG9yOjpURVJUSUFSWU9SREVSTUFTSyk7Cn0KCmlubGluZSBpbnQzMl90IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6Z2V0TWF4RXhwYW5zaW9uKGludDMyX3Qgb3JkZXIpIGNvbnN0CnsKICByZXR1cm4gdWNvbF9nZXRNYXhFeHBhbnNpb24obV9kYXRhXywgKHVpbnQzMl90KW9yZGVyKTsKfQoKaW5saW5lIFVCb29sIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6aXNJZ25vcmFibGUoaW50MzJfdCBvcmRlcikKewogIHJldHVybiAocHJpbWFyeU9yZGVyKG9yZGVyKSA9PSBSdWxlQmFzZWRDb2xsYXRvcjo6UFJJTUlHTk9SQUJMRSk7Cn0KClVfTkFNRVNQQUNFX0VORAoKI2VuZGlmCg==