LyoKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiogICBDb3B5cmlnaHQgKEMpIDE5OTctMjAwMSwgSW50ZXJuYXRpb25hbCBCdXNpbmVzcyBNYWNoaW5lcwoqICAgQ29ycG9yYXRpb24gYW5kIG90aGVycy4gIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqLwoKLyoqCiogRmlsZSBjb2xlaXRyLmgKKgoqIAoqCiogQ3JlYXRlZCBieTogSGVsZW5hIFNoaWgKKgoqIE1vZGlmaWNhdGlvbiBIaXN0b3J5OgoqCiogIERhdGUgICAgICAgTmFtZSAgICAgICAgRGVzY3JpcHRpb24KKgoqICA4LzE4Lzk3ICAgIGhlbGVuYSAgICAgIEFkZGVkIGludGVybmFsIEFQSSBkb2N1bWVudGF0aW9uLgoqIDA4LzAzLzk4ICAgIGVybSAgICAgICAgIFN5bmNoZWQgd2l0aCAxLjIgdmVyc2lvbiBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IuamF2YQoqIDEyLzEwLzk5ICAgIGFsaXUgICAgICAgIFBvcnRlZCBUaGFpIGNvbGxhdGlvbiBzdXBwb3J0IGZyb20gSmF2YS4KKiAwMS8yNS8wMSAgICBzd3F1ZWsgICAgICBNb2RpZmllZCBpbnRvIGEgQysrIHdyYXBwZXIgY2FsbGluZyBDIEFQSXMgKHVjb2xpdGVyLmgpCiogMDIvMTkvMDEgICAgc3dxdWVrICAgICAgUmVtb3ZlZCBDb2xsYXRpb25FbGVtZW50c0l0ZXJhdG9yKCkgc2luY2UgaXQgaXMgCiogICAgICAgICAgICAgICAgICAgICAgICAgcHJpdmF0ZSBjb25zdHJ1Y3RvciBhbmQgbm8gY2FsbHMgYXJlIG1hZGUgdG8gaXQKKi8KCiNpZm5kZWYgQ09MRUlUUl9ICiNkZWZpbmUgQ09MRUlUUl9ICgojaW5jbHVkZSAidW5pY29kZS91dHlwZXMuaCIKI2luY2x1ZGUgInVuaWNvZGUvdW9iamVjdC5oIgojaW5jbHVkZSAidW5pY29kZS90Ymxjb2xsLmgiCiNpbmNsdWRlICJ1bmljb2RlL3Vjb2xlaXRyLmgiCgp0eXBlZGVmIHN0cnVjdCBVQ29sbGF0aW9uRWxlbWVudHMgVUNvbGxhdGlvbkVsZW1lbnRzOwoKVV9OQU1FU1BBQ0VfQkVHSU4KCi8qKgoqIFRoZSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IgY2xhc3MgaXMgdXNlZCBhcyBhbiBpdGVyYXRvciB0byB3YWxrIHRocm91Z2ggICAgIAoqIGVhY2ggY2hhcmFjdGVyIG9mIGFuIGludGVybmF0aW9uYWwgc3RyaW5nLiBVc2UgdGhlIGl0ZXJhdG9yIHRvIHJldHVybiB0aGUKKiBvcmRlcmluZyBwcmlvcml0eSBvZiB0aGUgcG9zaXRpb25lZCBjaGFyYWN0ZXIuIFRoZSBvcmRlcmluZyBwcmlvcml0eSBvZiBhIAoqIGNoYXJhY3Rlciwgd2hpY2ggd2UgcmVmZXIgdG8gYXMgYSBrZXksIGRlZmluZXMgaG93IGEgY2hhcmFjdGVyIGlzIGNvbGxhdGVkIGluIAoqIHRoZSBnaXZlbiBjb2xsYXRpb24gb2JqZWN0LgoqIEZvciBleGFtcGxlLCBjb25zaWRlciB0aGUgZm9sbG93aW5nIGluIFNwYW5pc2g6CiogPHByZT4KKiBcY29kZQoqICAgICAgICAiY2EiIC0+IHRoZSBmaXJzdCBrZXkgaXMga2V5KCdjJykgYW5kIHNlY29uZCBrZXkgaXMga2V5KCdhJykuCiogICAgICAgICJjaGEiIC0+IHRoZSBmaXJzdCBrZXkgaXMga2V5KCdjaCcpIGFuZCBzZWNvbmQga2V5IGlzIGtleSgnYScpLgoqIFxlbmRjb2RlCiogPC9wcmU+CiogQW5kIGluIEdlcm1hbiwKKiA8cHJlPgoqIFxjb2RlCiogICAgICAgICLmYiItPiB0aGUgZmlyc3Qga2V5IGlzIGtleSgnYScpLCB0aGUgc2Vjb25kIGtleSBpcyBrZXkoJ2UnKSwgYW5kCiogICAgICAgIHRoZSB0aGlyZCBrZXkgaXMga2V5KCdiJykuCiogXGVuZGNvZGUKKiA8L3ByZT4KKiBUaGUga2V5IG9mIGEgY2hhcmFjdGVyLCBpcyBhbiBpbnRlZ2VyIGNvbXBvc2VkIG9mIHByaW1hcnkgb3JkZXIoc2hvcnQpLAoqIHNlY29uZGFyeSBvcmRlcihjaGFyKSwgYW5kIHRlcnRpYXJ5IG9yZGVyKGNoYXIpLiBKYXZhIHN0cmljdGx5IGRlZmluZXMgdGhlIAoqIHNpemUgYW5kIHNpZ25lZG5lc3Mgb2YgaXRzIHByaW1pdGl2ZSBkYXRhIHR5cGVzLiBUaGVyZWZvcmUsIHRoZSBzdGF0aWMKKiBmdW5jdGlvbnMgcHJpbWFyeU9yZGVyKCksIHNlY29uZGFyeU9yZGVyKCksIGFuZCB0ZXJ0aWFyeU9yZGVyKCkgcmV0dXJuIAoqIGludDMyX3QgdG8gZW5zdXJlIHRoZSBjb3JyZWN0bmVzcyBvZiB0aGUga2V5IHZhbHVlLgoqIDxwPkV4YW1wbGUgb2YgdGhlIGl0ZXJhdG9yIHVzYWdlOiAod2l0aG91dCBlcnJvciBjaGVja2luZykKKiA8cHJlPgoqIFxjb2RlCiogICB2b2lkIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcl9FeGFtcGxlKCkKKiAgIHsKKiAgICAgICBVbmljb2RlU3RyaW5nIHN0ciA9ICJUaGlzIGlzIGEgdGVzdCI7CiogICAgICAgVUVycm9yQ29kZSBzdWNjZXNzID0gVV9aRVJPX0VSUk9SOwoqICAgICAgIFJ1bGVCYXNlZENvbGxhdG9yKiByYmMgPQoqICAgICAgICAgICAoUnVsZUJhc2VkQ29sbGF0b3IqKSBSdWxlQmFzZWRDb2xsYXRvcjo6Y3JlYXRlSW5zdGFuY2Uoc3VjY2Vzcyk7CiogICAgICAgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yKiBjID0KKiAgICAgICAgICAgcmJjLT5jcmVhdGVDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IoIHN0ciApOwoqICAgICAgIGludDMyX3Qgb3JkZXIgPSBjLT5uZXh0KHN1Y2Nlc3MpOwoqICAgICAgIGMtPnJlc2V0KCk7CiogICAgICAgb3JkZXIgPSBjLT5wcmV2aW91cyhzdWNjZXNzKTsKKiAgICAgICBkZWxldGUgYzsKKiAgICAgICBkZWxldGUgcmJjOwoqICAgfQoqIFxlbmRjb2RlCiogPC9wcmU+CiogPHA+CiogQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpuZXh0IHJldHVybnMgdGhlIGNvbGxhdGlvbiBvcmRlciBvZiB0aGUgbmV4dAoqIGNoYXJhY3RlciBiYXNlZCBvbiB0aGUgY29tcGFyaXNvbiBsZXZlbCBvZiB0aGUgY29sbGF0b3IuIAoqIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6cHJldmlvdXMgcmV0dXJucyB0aGUgY29sbGF0aW9uIG9yZGVyIG9mIHRoZSAKKiBwcmV2aW91cyBjaGFyYWN0ZXIgYmFzZWQgb24gdGhlIGNvbXBhcmlzb24gbGV2ZWwgb2YgdGhlIGNvbGxhdG9yLiAKKiBUaGUgQ29sbGF0aW9uIEVsZW1lbnQgSXRlcmF0b3IgbW92ZXMgb25seSBpbiBvbmUgZGlyZWN0aW9uIGJldHdlZW4gY2FsbHMgdG8KKiBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6OnJlc2V0LiBUaGF0IGlzLCBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6Om5leHQoKSAKKiBhbmQgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpwcmV2aW91cyBjYW4gbm90IGJlIGludGVyLXVzZWQuIFdoZW5ldmVyIAoqIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6cHJldmlvdXMgaXMgdG8gYmUgY2FsbGVkIGFmdGVyIAoqIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6bmV4dCgpIG9yIHZpY2UgdmVyc2EsIAoqIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6cmVzZXQgaGFzIHRvIGJlIGNhbGxlZCBmaXJzdCB0byByZXNldCB0aGUgc3RhdHVzLCAKKiBzaGlmdGluZyBwb2ludGVycyB0byBlaXRoZXIgdGhlIGVuZCBvciB0aGUgc3RhcnQgb2YgdGhlIHN0cmluZy4gSGVuY2UgYXQgdGhlIAoqIG5leHQgY2FsbCBvZiBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6OnByZXZpb3VzIG9yIAoqIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6bmV4dCgpLCB0aGUgZmlyc3Qgb3IgbGFzdCBjb2xsYXRpb24gb3JkZXIgd2lsbCBiZSAKKiByZXR1cm5lZC4gCiogSWYgYSBjaGFuZ2Ugb2YgZGlyZWN0aW9uIGlzIGRvbmUgd2l0aG91dCBhIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6cmVzZXQoKSwgCiogdGhlIHJlc3VsdCBpcyB1bmRlZmluZWQuCiogVGhlIHJlc3VsdCBvZiBhIGZvcndhcmQgaXRlcmF0ZSAoQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpuZXh0KSBhbmQgCiogcmV2ZXJzZWQgcmVzdWx0IG9mIHRoZSBiYWNrd2FyZCBpdGVyYXRlIChDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6OnByZXZpb3VzKSAKKiBvbiB0aGUgc2FtZSBzdHJpbmcgYXJlIGVxdWl2YWxlbnQsIGlmIGNvbGxhdGlvbiBvcmRlcnMgd2l0aCB0aGUgdmFsdWUgCiogVUNPTF9JR05PUkFCTEUgYXJlIGlnbm9yZWQuCiogQ2hhcmFjdGVyIGJhc2VkIG9uIHRoZSBjb21wYXJpc29uIGxldmVsIG9mIHRoZSBjb2xsYXRvci4gIEEgY29sbGF0aW9uIG9yZGVyIAoqIGNvbnNpc3RzIG9mIHByaW1hcnkgb3JkZXIsIHNlY29uZGFyeSBvcmRlciBhbmQgdGVydGlhcnkgb3JkZXIuICBUaGUgZGF0YSAKKiB0eXBlIG9mIHRoZSBjb2xsYXRpb24gb3JkZXIgaXMgPHN0cm9uZz50X2ludDMyPC9zdHJvbmc+LiAKKgoqIE5vdGUsIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciBzaG91bGQgbm90IGJlIHN1YmNsYXNzZWQuCiogQHNlZSAgICAgQ29sbGF0b3IKKiBAc2VlICAgICBSdWxlQmFzZWRDb2xsYXRvcgoqIEB2ZXJzaW9uIDEuOCBKYW4gMTYgMjAwMQoqLwpjbGFzcyBVX0kxOE5fQVBJIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciA6IHB1YmxpYyBVT2JqZWN0IHsKcHVibGljOiAKCiAgLy8gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yIHB1YmxpYyBkYXRhIG1lbWJlciAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgLyoqCiAgKiBOVUxMT1JERVIgaW5kaWNhdGVzIHRoYXQgYW4gZXJyb3IgaGFzIG9jY3VyZWQgd2hpbGUgcHJvY2Vzc2luZwogICogQHN0YWJsZQogICovCiAgc3RhdGljIGludDMyX3QgY29uc3QgTlVMTE9SREVSOwoKICAvLyBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IgcHVibGljIGNvbnN0cnVjdG9yL2Rlc3RydWN0b3IgLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAvKioKICAqIENvcHkgY29uc3RydWN0b3IuCiAgKgogICogQHBhcmFtIG90aGVyICAgIHRoZSBvYmplY3QgdG8gYmUgY29waWVkIGZyb20KICAqIEBzdGFibGUKICAqLwogIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcihjb25zdCBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3ImIG90aGVyKTsKCiAgLyoqIAogICogRGVzdHJ1Y3RvcgogICogQHN0YWJsZQogICovCiAgfkNvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcigpOwogIAogIC8vIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciBwdWJsaWMgbWV0aG9kcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogIC8qKgogICogUmV0dXJucyB0cnVlIGlmICJvdGhlciIgaXMgdGhlIHNhbWUgYXMgInRoaXMiCiAgKgogICogQHBhcmFtIG90aGVyICAgIHRoZSBvYmplY3QgdG8gYmUgY29tcGFyZWQKICAqIEByZXR1cm4gICAgICAgICB0cnVlIGlmICJvdGhlciIgaXMgdGhlIHNhbWUgYXMgInRoaXMiCiAgKiBAc3RhYmxlCiAgKi8KICBVQm9vbCBvcGVyYXRvcj09KGNvbnN0IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciYgb3RoZXIpIGNvbnN0OwoKICAvKioKICAqIFJldHVybnMgdHJ1ZSBpZiAib3RoZXIiIGlzIG5vdCB0aGUgc2FtZSBhcyAidGhpcyIuCiAgKgogICogQHBhcmFtIG90aGVyICAgIHRoZSBvYmplY3QgdG8gYmUgY29tcGFyZWQKICAqIEByZXR1cm4gICAgICAgICB0cnVlIGlmICJvdGhlciIgaXMgbm90IHRoZSBzYW1lIGFzICJ0aGlzIgogICogQHN0YWJsZQogICovCiAgVUJvb2wgb3BlcmF0b3IhPShjb25zdCBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3ImIG90aGVyKSBjb25zdDsKCiAgLyoqCiAgKiBSZXNldHMgdGhlIGN1cnNvciB0byB0aGUgYmVnaW5uaW5nIG9mIHRoZSBzdHJpbmcuCiAgKiBAc3RhYmxlCiAgKi8KICB2b2lkIHJlc2V0KHZvaWQpOwogICAgCiAgLyoqCiAgKiBHZXRzIHRoZSBvcmRlcmluZyBwcmlvcml0eSBvZiB0aGUgbmV4dCBjaGFyYWN0ZXIgaW4gdGhlIHN0cmluZy4KICAqIEBwYXJhbSBzdGF0dXMgdGhlIGVycm9yIGNvZGUgc3RhdHVzLgogICogQHJldHVybiB0aGUgbmV4dCBjaGFyYWN0ZXIncyBvcmRlcmluZy4gb3RoZXJ3aXNlIHJldHVybnMgTlVMTE9SREVSIGlmIGFuIAogICogICAgICAgICBlcnJvciBoYXMgb2NjdXJlZCBvciBpZiB0aGUgZW5kIG9mIHN0cmluZyBoYXMgYmVlbiByZWFjaGVkCiAgKiBAc3RhYmxlCiAgKi8KICBpbnQzMl90IG5leHQoVUVycm9yQ29kZSYgc3RhdHVzKTsKCiAgLyoqCiAgKiBHZXQgdGhlIG9yZGVyaW5nIHByaW9yaXR5IG9mIHRoZSBwcmV2aW91cyBjb2xsYXRpb24gZWxlbWVudCBpbiB0aGUgc3RyaW5nLgogICogQHBhcmFtIHN0YXR1cyB0aGUgZXJyb3IgY29kZSBzdGF0dXMuCiAgKiBAcmV0dXJuIHRoZSBwcmV2aW91cyBlbGVtZW50J3Mgb3JkZXJpbmcuIG90aGVyd2lzZSByZXR1cm5zIE5VTExPUkRFUiBpZiBhbiAKICAqICAgICAgICAgZXJyb3IgaGFzIG9jY3VyZWQgb3IgaWYgdGhlIHN0YXJ0IG9mIHN0cmluZyBoYXMgYmVlbiByZWFjaGVkCiAgKiBAc3RhYmxlCiAgKi8KICBpbnQzMl90IHByZXZpb3VzKFVFcnJvckNvZGUmIHN0YXR1cyk7CgogIC8qKgogICogR2V0cyB0aGUgcHJpbWFyeSBvcmRlciBvZiBhIGNvbGxhdGlvbiBvcmRlci4KICAqIEBwYXJhbSBvcmRlciB0aGUgY29sbGF0aW9uIG9yZGVyCiAgKiBAcmV0dXJuIHRoZSBwcmltYXJ5IG9yZGVyIG9mIGEgY29sbGF0aW9uIG9yZGVyLgogICogQHN0YWJsZQogICovCiAgc3RhdGljIGludDMyX3QgcHJpbWFyeU9yZGVyKGludDMyX3Qgb3JkZXIpOwoKICAvKioKICAqIEdldHMgdGhlIHNlY29uZGFyeSBvcmRlciBvZiBhIGNvbGxhdGlvbiBvcmRlci4KICAqIEBwYXJhbSBvcmRlciB0aGUgY29sbGF0aW9uIG9yZGVyCiAgKiBAcmV0dXJuIHRoZSBzZWNvbmRhcnkgb3JkZXIgb2YgYSBjb2xsYXRpb24gb3JkZXIuCiAgKiBAc3RhYmxlCiAgKi8KICBzdGF0aWMgaW50MzJfdCBzZWNvbmRhcnlPcmRlcihpbnQzMl90IG9yZGVyKTsKCiAgLyoqCiAgKiBHZXRzIHRoZSB0ZXJ0aWFyeSBvcmRlciBvZiBhIGNvbGxhdGlvbiBvcmRlci4KICAqIEBwYXJhbSBvcmRlciB0aGUgY29sbGF0aW9uIG9yZGVyCiAgKiBAcmV0dXJuIHRoZSB0ZXJ0aWFyeSBvcmRlciBvZiBhIGNvbGxhdGlvbiBvcmRlci4KICAqIEBzdGFibGUKICAqLwogIHN0YXRpYyBpbnQzMl90IHRlcnRpYXJ5T3JkZXIoaW50MzJfdCBvcmRlcik7CgogIC8qKgogICogUmV0dXJuIHRoZSBtYXhpbXVtIGxlbmd0aCBvZiBhbnkgZXhwYW5zaW9uIHNlcXVlbmNlcyB0aGF0IGVuZCB3aXRoIHRoZSAKICAqIHNwZWNpZmllZCBjb21wYXJpc29uIG9yZGVyLgogICogQHBhcmFtIG9yZGVyIGEgY29sbGF0aW9uIG9yZGVyIHJldHVybmVkIGJ5IHByZXZpb3VzIG9yIG5leHQuCiAgKiBAcmV0dXJuIG1heGltdW0gc2l6ZSBvZiB0aGUgZXhwYW5zaW9uIHNlcXVlbmNlcyBlbmRpbmcgd2l0aCB0aGUgY29sbGF0aW9uIAogICogICAgICAgICBlbGVtZW50IG9yIDEgaWYgY29sbGF0aW9uIGVsZW1lbnQgZG9lcyBub3Qgb2NjdXIgYXQgdGhlIGVuZCBvZiBhbnkgCiAgKiAgICAgICAgIGV4cGFuc2lvbiBzZXF1ZW5jZQogICogQHN0YWJsZQogICovCiAgaW50MzJfdCBnZXRNYXhFeHBhbnNpb24oaW50MzJfdCBvcmRlcikgY29uc3Q7CgogIC8qKgogICogR2V0cyB0aGUgY29tcGFyaXNvbiBvcmRlciBpbiB0aGUgZGVzaXJlZCBzdHJlbmd0aC4gSWdub3JlIHRoZSBvdGhlcgogICogZGlmZmVyZW5jZXMuCiAgKiBAcGFyYW0gb3JkZXIgVGhlIG9yZGVyIHZhbHVlCiAgKiBAc3RhYmxlCiAgKi8KICBpbnQzMl90IHN0cmVuZ3RoT3JkZXIoaW50MzJfdCBvcmRlcikgY29uc3Q7CgogIC8qKgogICogU2V0cyB0aGUgc291cmNlIHN0cmluZy4KICAqIEBwYXJhbSBzdHIgdGhlIHNvdXJjZSBzdHJpbmcuCiAgKiBAcGFyYW0gc3RhdHVzIHRoZSBlcnJvciBjb2RlIHN0YXR1cy4KICAqIEBzdGFibGUKICAqLwogIHZvaWQgc2V0VGV4dChjb25zdCBVbmljb2RlU3RyaW5nJiBzdHIsIFVFcnJvckNvZGUmIHN0YXR1cyk7CgogIC8qKgogICogU2V0cyB0aGUgc291cmNlIHN0cmluZy4KICAqIEBwYXJhbSBzdHIgdGhlIHNvdXJjZSBjaGFyYWN0ZXIgaXRlcmF0b3IuCiAgKiBAcGFyYW0gc3RhdHVzIHRoZSBlcnJvciBjb2RlIHN0YXR1cy4KICAqIEBzdGFibGUKICAqLwogIHZvaWQgc2V0VGV4dChDaGFyYWN0ZXJJdGVyYXRvciYgc3RyLCBVRXJyb3JDb2RlJiBzdGF0dXMpOwoKICAvKioKICAqIENoZWNrcyBpZiBhIGNvbXBhcmlzb24gb3JkZXIgaXMgaWdub3JhYmxlLgogICogQHBhcmFtIG9yZGVyIHRoZSBjb2xsYXRpb24gb3JkZXIuCiAgKiBAcmV0dXJuIFRSVUUgaWYgYSBjaGFyYWN0ZXIgaXMgaWdub3JhYmxlLCBGQUxTRSBvdGhlcndpc2UuCiAgKiBAc3RhYmxlCiAgKi8KICBzdGF0aWMgVUJvb2wgaXNJZ25vcmFibGUoaW50MzJfdCBvcmRlcik7CgogIC8qKgogICogR2V0cyB0aGUgb2Zmc2V0IG9mIHRoZSBjdXJyZW50bHkgcHJvY2Vzc2VkIGNoYXJhY3RlciBpbiB0aGUgc291cmNlIHN0cmluZy4KICAqIEByZXR1cm4gdGhlIG9mZnNldCBvZiB0aGUgY2hhcmFjdGVyLgogICogQHN0YWJsZQogICovCiAgaW50MzJfdCBnZXRPZmZzZXQodm9pZCkgY29uc3Q7CgogIC8qKgogICogU2V0cyB0aGUgb2Zmc2V0IG9mIHRoZSBjdXJyZW50bHkgcHJvY2Vzc2VkIGNoYXJhY3RlciBpbiB0aGUgc291cmNlIHN0cmluZy4KICAqIEBwYXJhbSBuZXdPZmZzZXQgdGhlIG5ldyBvZmZzZXQuCiAgKiBAcGFyYW0gc3RhdHVzIHRoZSBlcnJvciBjb2RlIHN0YXR1cy4KICAqIEByZXR1cm4gdGhlIG9mZnNldCBvZiB0aGUgY2hhcmFjdGVyLgogICogQHN0YWJsZQogICovCiAgdm9pZCBzZXRPZmZzZXQoaW50MzJfdCBuZXdPZmZzZXQsIFVFcnJvckNvZGUmIHN0YXR1cyk7CgogIC8qKgogICAqIElDVSAicG9vciBtYW4ncyBSVFRJIiwgcmV0dXJucyBhIFVDbGFzc0lEIGZvciB0aGUgYWN0dWFsIGNsYXNzLgogICAqCiAgICogQGRyYWZ0IElDVSAyLjIKICAgKi8KICB2aXJ0dWFsIGlubGluZSBVQ2xhc3NJRCBnZXREeW5hbWljQ2xhc3NJRCgpIGNvbnN0IHsgcmV0dXJuIGdldFN0YXRpY0NsYXNzSUQoKTsgfQoKICAvKioKICAgKiBJQ1UgInBvb3IgbWFuJ3MgUlRUSSIsIHJldHVybnMgYSBVQ2xhc3NJRCBmb3IgdGhpcyBjbGFzcy4KICAgKgogICAqIEBkcmFmdCBJQ1UgMi4yCiAgICovCiAgc3RhdGljIGlubGluZSBVQ2xhc3NJRCBnZXRTdGF0aWNDbGFzc0lEKCkgeyByZXR1cm4gKFVDbGFzc0lEKSZmZ0NsYXNzSUQ7IH0KCnByb3RlY3RlZDoKICAKICAvLyBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IgcHJvdGVjdGVkIGNvbnN0cnVjdG9ycyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogIC8qKgogICogQHN0YWJsZQogICovCiAgZnJpZW5kIGNsYXNzIFJ1bGVCYXNlZENvbGxhdG9yOwoKICAvKioKICAqIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciBjb25zdHJ1Y3Rvci4gVGhpcyB0YWtlcyB0aGUgc291cmNlIHN0cmluZyBhbmQgdGhlIAogICogY29sbGF0aW9uIG9iamVjdC4gVGhlIGN1cnNvciB3aWxsIHdhbGsgdGhydSB0aGUgc291cmNlIHN0cmluZyBiYXNlZCBvbiB0aGUgCiAgKiBwcmVkZWZpbmVkIGNvbGxhdGlvbiBydWxlcy4gSWYgdGhlIHNvdXJjZSBzdHJpbmcgaXMgZW1wdHksIE5VTExPUkRFUiB3aWxsIAogICogYmUgcmV0dXJuZWQgb24gdGhlIGNhbGxzIHRvIG5leHQoKS4KICAqIEBwYXJhbSBzb3VyY2VUZXh0ICAgIHRoZSBzb3VyY2Ugc3RyaW5nLgogICogQHBhcmFtIG9yZGVyICAgICAgICAgdGhlIGNvbGxhdGlvbiBvYmplY3QuCiAgKiBAcGFyYW0gc3RhdHVzICAgICAgICB0aGUgZXJyb3IgY29kZSBzdGF0dXMuCiAgKiBAc3RhYmxlCiAgKi8KICBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IoY29uc3QgVW5pY29kZVN0cmluZyYgc291cmNlVGV4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgUnVsZUJhc2VkQ29sbGF0b3IqIG9yZGVyLCBVRXJyb3JDb2RlJiBzdGF0dXMpOwoKICAvKioKICAqIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciBjb25zdHJ1Y3Rvci4gVGhpcyB0YWtlcyB0aGUgc291cmNlIHN0cmluZyBhbmQgdGhlIAogICogY29sbGF0aW9uIG9iamVjdC4gIFRoZSBjdXJzb3Igd2lsbCB3YWxrIHRocnUgdGhlIHNvdXJjZSBzdHJpbmcgYmFzZWQgb24gdGhlIAogICogcHJlZGVmaW5lZCBjb2xsYXRpb24gcnVsZXMuICBJZiB0aGUgc291cmNlIHN0cmluZyBpcyBlbXB0eSwgTlVMTE9SREVSIHdpbGwgCiAgKiBiZSByZXR1cm5lZCBvbiB0aGUgY2FsbHMgdG8gbmV4dCgpLgogICogQHBhcmFtIHNvdXJjZVRleHQgICAgdGhlIHNvdXJjZSBzdHJpbmcuCiAgKiBAcGFyYW0gb3JkZXIgICAgICAgICB0aGUgY29sbGF0aW9uIG9iamVjdC4KICAqIEBwYXJhbSBzdGF0dXMgICAgICAgIHRoZSBlcnJvciBjb2RlIHN0YXR1cy4KICAqIEBzdGFibGUKICAqLwogIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcihjb25zdCBDaGFyYWN0ZXJJdGVyYXRvciYgc291cmNlVGV4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgUnVsZUJhc2VkQ29sbGF0b3IqIG9yZGVyLCBVRXJyb3JDb2RlJiBzdGF0dXMpOwogIAogIC8vIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciBwcm90ZWN0ZWQgbWV0aG9kcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogIC8qKgogICogQXNzaWdubWVudCBvcGVyYXRvcgogICoKICAqIEBwYXJhbSBvdGhlciAgICB0aGUgb2JqZWN0IHRvIGJlIGNvcGllZAogICogQHN0YWJsZQogICovCiAgY29uc3QgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yJgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcGVyYXRvcj0oY29uc3QgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yJiBvdGhlcik7Cgpwcml2YXRlOgoKICAvLyBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IgcHJpdmF0ZSBkYXRhIG1lbWJlcnMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAvKioKICAqIERhdGEgd3JhcHBlciBmb3IgY29sbGF0aW9uIGVsZW1lbnRzCiAgKi8KICBVQ29sbGF0aW9uRWxlbWVudHMgKm1fZGF0YV87CgogIC8qKgogICogSW5kaWNhdGVzIGlmIG1fZGF0YV8gYmVsb25ncyB0byB0aGlzIG9iamVjdC4KICAqLwogIFVCb29sIGlzRGF0YU93bmVkXzsKCiAgLyoqCiAgICogVGhlIGFkZHJlc3Mgb2YgdGhpcyBzdGF0aWMgY2xhc3MgdmFyaWFibGUgc2VydmVzIGFzIHRoaXMgY2xhc3MncyBJRAogICAqIGZvciBJQ1UgInBvb3IgbWFuJ3MgUlRUSSIuCiAgICovCiAgc3RhdGljIGNvbnN0IGNoYXIgZmdDbGFzc0lEOwp9OwoKLy8gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yIGlubGluZSBtZXRob2QgZGVmaW5hdGlvbiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKLyoqCiogR2V0IHRoZSBwcmltYXJ5IG9yZGVyIG9mIGEgY29sbGF0aW9uIG9yZGVyLgoqIEBwYXJhbSBvcmRlciB0aGUgY29sbGF0aW9uIG9yZGVyCiogQHJldHVybiB0aGUgcHJpbWFyeSBvcmRlciBvZiBhIGNvbGxhdGlvbiBvcmRlci4KKi8KaW5saW5lIGludDMyX3QgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpwcmltYXJ5T3JkZXIoaW50MzJfdCBvcmRlcikKewogIG9yZGVyICY9IFJ1bGVCYXNlZENvbGxhdG9yOjpQUklNQVJZT1JERVJNQVNLOwogIHJldHVybiAob3JkZXIgPj4gUnVsZUJhc2VkQ29sbGF0b3I6OlBSSU1BUllPUkRFUlNISUZUKTsKfQoKLyoqCiogR2V0IHRoZSBzZWNvbmRhcnkgb3JkZXIgb2YgYSBjb2xsYXRpb24gb3JkZXIuCiogQHBhcmFtIG9yZGVyIHRoZSBjb2xsYXRpb24gb3JkZXIKKiBAcmV0dXJuIHRoZSBzZWNvbmRhcnkgb3JkZXIgb2YgYSBjb2xsYXRpb24gb3JkZXIuCiovCmlubGluZSBpbnQzMl90IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6c2Vjb25kYXJ5T3JkZXIoaW50MzJfdCBvcmRlcikKewogIG9yZGVyID0gb3JkZXIgJiBSdWxlQmFzZWRDb2xsYXRvcjo6U0VDT05EQVJZT1JERVJNQVNLOwogIHJldHVybiAob3JkZXIgPj4gUnVsZUJhc2VkQ29sbGF0b3I6OlNFQ09OREFSWU9SREVSU0hJRlQpOwp9CgovKioKKiBHZXQgdGhlIHRlcnRpYXJ5IG9yZGVyIG9mIGEgY29sbGF0aW9uIG9yZGVyLgoqIEBwYXJhbSBvcmRlciB0aGUgY29sbGF0aW9uIG9yZGVyCiogQHJldHVybiB0aGUgdGVydGlhcnkgb3JkZXIgb2YgYSBjb2xsYXRpb24gb3JkZXIuCiovCmlubGluZSBpbnQzMl90IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6dGVydGlhcnlPcmRlcihpbnQzMl90IG9yZGVyKQp7CiAgcmV0dXJuIChvcmRlciAmPSBSdWxlQmFzZWRDb2xsYXRvcjo6VEVSVElBUllPUkRFUk1BU0spOwp9CgppbmxpbmUgaW50MzJfdCBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6OmdldE1heEV4cGFuc2lvbihpbnQzMl90IG9yZGVyKSBjb25zdAp7CiAgcmV0dXJuIHVjb2xfZ2V0TWF4RXhwYW5zaW9uKG1fZGF0YV8sICh1aW50MzJfdClvcmRlcik7Cn0KCmlubGluZSBVQm9vbCBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6OmlzSWdub3JhYmxlKGludDMyX3Qgb3JkZXIpCnsKICByZXR1cm4gKHByaW1hcnlPcmRlcihvcmRlcikgPT0gUnVsZUJhc2VkQ29sbGF0b3I6OlBSSU1JR05PUkFCTEUpOwp9CgpVX05BTUVTUEFDRV9FTkQKCiNlbmRpZgo=