LyoKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiogICBDb3B5cmlnaHQgKEMpIDE5OTctMjAwMSwgSW50ZXJuYXRpb25hbCBCdXNpbmVzcyBNYWNoaW5lcwoqICAgQ29ycG9yYXRpb24gYW5kIG90aGVycy4gIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqLwoKLyoqCiogRmlsZSBjb2xlaXRyLmgKKgoqIAoqCiogQ3JlYXRlZCBieTogSGVsZW5hIFNoaWgKKgoqIE1vZGlmaWNhdGlvbiBIaXN0b3J5OgoqCiogIERhdGUgICAgICAgTmFtZSAgICAgICAgRGVzY3JpcHRpb24KKgoqICA4LzE4Lzk3ICAgIGhlbGVuYSAgICAgIEFkZGVkIGludGVybmFsIEFQSSBkb2N1bWVudGF0aW9uLgoqIDA4LzAzLzk4ICAgIGVybSAgICAgICAgIFN5bmNoZWQgd2l0aCAxLjIgdmVyc2lvbiBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IuamF2YQoqIDEyLzEwLzk5ICAgIGFsaXUgICAgICAgIFBvcnRlZCBUaGFpIGNvbGxhdGlvbiBzdXBwb3J0IGZyb20gSmF2YS4KKiAwMS8yNS8wMSAgICBzd3F1ZWsgICAgICBNb2RpZmllZCBpbnRvIGEgQysrIHdyYXBwZXIgY2FsbGluZyBDIEFQSXMgKHVjb2xpdGVyLmgpCiogMDIvMTkvMDEgICAgc3dxdWVrICAgICAgUmVtb3ZlZCBDb2xsYXRpb25FbGVtZW50c0l0ZXJhdG9yKCkgc2luY2UgaXQgaXMgCiogICAgICAgICAgICAgICAgICAgICAgICAgcHJpdmF0ZSBjb25zdHJ1Y3RvciBhbmQgbm8gY2FsbHMgYXJlIG1hZGUgdG8gaXQKKi8KCiNpZm5kZWYgQ09MRUlUUl9ICiNkZWZpbmUgQ09MRUlUUl9ICgovLyAjaW5jbHVkZSAidW5pY29kZS91bmlzdHIuaCIKI2luY2x1ZGUgInVuaWNvZGUvdGJsY29sbC5oIgojaW5jbHVkZSAidW5pY29kZS91Y29sZWl0ci5oIgoKLy8gI2luY2x1ZGUgInRhYmxlcy5oIgovLyAjaW5jbHVkZSAidW5pY29kZS9jaGFyaXRlci5oIgoKLy8gaGF2ZSB0byBkbyB0aGlzIGJlY2F1c2UgdGhlIGluY2x1ZGUgcGF0aCBpbiB0aGUgbWFpbiBwcm9qZWN0IGRvZXMgbm90IGhhdmUgCi8vIHRhYmxlcy5oLgovLyBjbGFzcyBWZWN0b3JPZkludDsKLy8gY2xhc3MgTm9ybWFsaXplcjsKLy8gY2xhc3MgVmVjdG9yT2ZQVG9Db250cmFjdEVsZW1lbnQ7Ci8vIGNsYXNzIFJ1bGVCYXNlZENvbGxhdG9yOwoKLy8gdHlwZWRlZiB2b2lkICogVUNvbGxhdGlvbkVsZW1lbnRzOwovLyBzdHJ1Y3QgVUNvbGxhdGlvbkVsZW1lbnRzOwp0eXBlZGVmIHN0cnVjdCBVQ29sbGF0aW9uRWxlbWVudHMgVUNvbGxhdGlvbkVsZW1lbnRzOwoKLyoqCiogVGhlIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciBjbGFzcyBpcyB1c2VkIGFzIGFuIGl0ZXJhdG9yIHRvIHdhbGsgdGhyb3VnaCAgICAgCiogZWFjaCBjaGFyYWN0ZXIgb2YgYW4gaW50ZXJuYXRpb25hbCBzdHJpbmcuIFVzZSB0aGUgaXRlcmF0b3IgdG8gcmV0dXJuIHRoZQoqIG9yZGVyaW5nIHByaW9yaXR5IG9mIHRoZSBwb3NpdGlvbmVkIGNoYXJhY3Rlci4gVGhlIG9yZGVyaW5nIHByaW9yaXR5IG9mIGEgCiogY2hhcmFjdGVyLCB3aGljaCB3ZSByZWZlciB0byBhcyBhIGtleSwgZGVmaW5lcyBob3cgYSBjaGFyYWN0ZXIgaXMgY29sbGF0ZWQgaW4gCiogdGhlIGdpdmVuIGNvbGxhdGlvbiBvYmplY3QuCiogRm9yIGV4YW1wbGUsIGNvbnNpZGVyIHRoZSBmb2xsb3dpbmcgaW4gU3BhbmlzaDoKKiA8cHJlPgoqIFxjb2RlCiogICAgICAgICJjYSIgLT4gdGhlIGZpcnN0IGtleSBpcyBrZXkoJ2MnKSBhbmQgc2Vjb25kIGtleSBpcyBrZXkoJ2EnKS4KKiAgICAgICAgImNoYSIgLT4gdGhlIGZpcnN0IGtleSBpcyBrZXkoJ2NoJykgYW5kIHNlY29uZCBrZXkgaXMga2V5KCdhJykuCiogXGVuZGNvZGUKKiA8L3ByZT4KKiBBbmQgaW4gR2VybWFuLAoqIDxwcmU+CiogXGNvZGUKKiAgICAgICAgIuZiIi0+IHRoZSBmaXJzdCBrZXkgaXMga2V5KCdhJyksIHRoZSBzZWNvbmQga2V5IGlzIGtleSgnZScpLCBhbmQKKiAgICAgICAgdGhlIHRoaXJkIGtleSBpcyBrZXkoJ2InKS4KKiBcZW5kY29kZQoqIDwvcHJlPgoqIFRoZSBrZXkgb2YgYSBjaGFyYWN0ZXIsIGlzIGFuIGludGVnZXIgY29tcG9zZWQgb2YgcHJpbWFyeSBvcmRlcihzaG9ydCksCiogc2Vjb25kYXJ5IG9yZGVyKGNoYXIpLCBhbmQgdGVydGlhcnkgb3JkZXIoY2hhcikuIEphdmEgc3RyaWN0bHkgZGVmaW5lcyB0aGUgCiogc2l6ZSBhbmQgc2lnbmVkbmVzcyBvZiBpdHMgcHJpbWl0aXZlIGRhdGEgdHlwZXMuIFRoZXJlZm9yZSwgdGhlIHN0YXRpYwoqIGZ1bmN0aW9ucyBwcmltYXJ5T3JkZXIoKSwgc2Vjb25kYXJ5T3JkZXIoKSwgYW5kIHRlcnRpYXJ5T3JkZXIoKSByZXR1cm4gCiogaW50MzJfdCB0byBlbnN1cmUgdGhlIGNvcnJlY3RuZXNzIG9mIHRoZSBrZXkgdmFsdWUuCiogPHA+RXhhbXBsZSBvZiB0aGUgaXRlcmF0b3IgdXNhZ2U6ICh3aXRob3V0IGVycm9yIGNoZWNraW5nKQoqIDxwcmU+CiogXGNvZGUKKiAgIHZvaWQgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yX0V4YW1wbGUoKQoqICAgewoqICAgICAgIFVuaWNvZGVTdHJpbmcgc3RyID0gIlRoaXMgaXMgYSB0ZXN0IjsKKiAgICAgICBVRXJyb3JDb2RlIHN1Y2Nlc3MgPSBVX1pFUk9fRVJST1I7CiogICAgICAgUnVsZUJhc2VkQ29sbGF0b3IqIHJiYyA9CiogICAgICAgICAgIChSdWxlQmFzZWRDb2xsYXRvciopIFJ1bGVCYXNlZENvbGxhdG9yOjpjcmVhdGVJbnN0YW5jZShzdWNjZXNzKTsKKiAgICAgICBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IqIGMgPQoqICAgICAgICAgICByYmMtPmNyZWF0ZUNvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciggc3RyICk7CiogICAgICAgaW50MzJfdCBvcmRlciA9IGMtPm5leHQoc3VjY2Vzcyk7CiogICAgICAgYy0+cmVzZXQoKTsKKiAgICAgICBvcmRlciA9IGMtPnByZXZpb3VzKHN1Y2Nlc3MpOwoqICAgICAgIGRlbGV0ZSBjOwoqICAgICAgIGRlbGV0ZSByYmM7CiogICB9CiogXGVuZGNvZGUKKiA8L3ByZT4KKiA8cD4KKiBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6Om5leHQgcmV0dXJucyB0aGUgY29sbGF0aW9uIG9yZGVyIG9mIHRoZSBuZXh0CiogY2hhcmFjdGVyIGJhc2VkIG9uIHRoZSBjb21wYXJpc29uIGxldmVsIG9mIHRoZSBjb2xsYXRvci4gCiogQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpwcmV2aW91cyByZXR1cm5zIHRoZSBjb2xsYXRpb24gb3JkZXIgb2YgdGhlIAoqIHByZXZpb3VzIGNoYXJhY3RlciBiYXNlZCBvbiB0aGUgY29tcGFyaXNvbiBsZXZlbCBvZiB0aGUgY29sbGF0b3IuIAoqIFRoZSBDb2xsYXRpb24gRWxlbWVudCBJdGVyYXRvciBtb3ZlcyBvbmx5IGluIG9uZSBkaXJlY3Rpb24gYmV0d2VlbiBjYWxscyB0bwoqIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6cmVzZXQuIFRoYXQgaXMsIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6bmV4dCgpIAoqIGFuZCBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6OnByZXZpb3VzIGNhbiBub3QgYmUgaW50ZXItdXNlZC4gV2hlbmV2ZXIgCiogQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpwcmV2aW91cyBpcyB0byBiZSBjYWxsZWQgYWZ0ZXIgCiogQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpuZXh0KCkgb3IgdmljZSB2ZXJzYSwgCiogQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpyZXNldCBoYXMgdG8gYmUgY2FsbGVkIGZpcnN0IHRvIHJlc2V0IHRoZSBzdGF0dXMsIAoqIHNoaWZ0aW5nIHBvaW50ZXJzIHRvIGVpdGhlciB0aGUgZW5kIG9yIHRoZSBzdGFydCBvZiB0aGUgc3RyaW5nLiBIZW5jZSBhdCB0aGUgCiogbmV4dCBjYWxsIG9mIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6cHJldmlvdXMgb3IgCiogQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpuZXh0KCksIHRoZSBmaXJzdCBvciBsYXN0IGNvbGxhdGlvbiBvcmRlciB3aWxsIGJlIAoqIHJldHVybmVkLiAKKiBJZiBhIGNoYW5nZSBvZiBkaXJlY3Rpb24gaXMgZG9uZSB3aXRob3V0IGEgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpyZXNldCgpLCAKKiB0aGUgcmVzdWx0IGlzIHVuZGVmaW5lZC4KKiBUaGUgcmVzdWx0IG9mIGEgZm9yd2FyZCBpdGVyYXRlIChDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6Om5leHQpIGFuZCAKKiByZXZlcnNlZCByZXN1bHQgb2YgdGhlIGJhY2t3YXJkIGl0ZXJhdGUgKENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6cHJldmlvdXMpIAoqIG9uIHRoZSBzYW1lIHN0cmluZyBhcmUgZXF1aXZhbGVudCwgaWYgY29sbGF0aW9uIG9yZGVycyB3aXRoIHRoZSB2YWx1ZSAKKiBVQ09MX0lHTk9SQUJMRSBhcmUgaWdub3JlZC4KKiBDaGFyYWN0ZXIgYmFzZWQgb24gdGhlIGNvbXBhcmlzb24gbGV2ZWwgb2YgdGhlIGNvbGxhdG9yLiAgQSBjb2xsYXRpb24gb3JkZXIgCiogY29uc2lzdHMgb2YgcHJpbWFyeSBvcmRlciwgc2Vjb25kYXJ5IG9yZGVyIGFuZCB0ZXJ0aWFyeSBvcmRlci4gIFRoZSBkYXRhIAoqIHR5cGUgb2YgdGhlIGNvbGxhdGlvbiBvcmRlciBpcyA8c3Ryb25nPnRfaW50MzI8L3N0cm9uZz4uIAoqCiogTm90ZSwgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yIHNob3VsZCBub3QgYmUgc3ViY2xhc3NlZC4KKiBAc2VlICAgICBDb2xsYXRvcgoqIEBzZWUgICAgIFJ1bGVCYXNlZENvbGxhdG9yCiogQHZlcnNpb24gMS44IEphbiAxNiAyMDAxCiovCmNsYXNzIFVfSTE4Tl9BUEkgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yCnsKcHVibGljOiAKCiAgLy8gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yIHB1YmxpYyBkYXRhIG1lbWJlciAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgLyoqCiAgKiBOVUxMT1JERVIgaW5kaWNhdGVzIHRoYXQgYW4gZXJyb3IgaGFzIG9jY3VyZWQgd2hpbGUgcHJvY2Vzc2luZwogICovCiAgc3RhdGljIGludDMyX3QgY29uc3QgTlVMTE9SREVSOwoKICAvLyBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IgcHVibGljIGNvbnN0cnVjdG9yL2Rlc3RydWN0b3IgLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAvKioKICAqIENvcHkgY29uc3RydWN0b3IuCiAgKi8KICBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IoY29uc3QgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yJiBvdGhlcik7CgogIC8qKiAKICAqIERlc3RydWN0b3IKICAqLwogIH5Db2xsYXRpb25FbGVtZW50SXRlcmF0b3IoKTsKICAKICAvLyBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IgcHVibGljIG1ldGhvZHMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAvKioKICAqIFJldHVybnMgdHJ1ZSBpZiAib3RoZXIiIGlzIHRoZSBzYW1lIGFzICJ0aGlzIgogICovCiAgVUJvb2wgb3BlcmF0b3I9PShjb25zdCBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3ImIG90aGVyKSBjb25zdDsKCiAgLyoqCiAgKiBSZXR1cm5zIHRydWUgaWYgIm90aGVyIiBpcyBub3QgdGhlIHNhbWUgYXMgInRoaXMiLgogICovCiAgVUJvb2wgb3BlcmF0b3IhPShjb25zdCBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3ImIG90aGVyKSBjb25zdDsKCiAgLyoqCiAgKiBSZXNldHMgdGhlIGN1cnNvciB0byB0aGUgYmVnaW5uaW5nIG9mIHRoZSBzdHJpbmcuCiAgKi8KICB2b2lkIHJlc2V0KHZvaWQpOwogICAgCiAgLyoqCiAgKiBHZXRzIHRoZSBvcmRlcmluZyBwcmlvcml0eSBvZiB0aGUgbmV4dCBjaGFyYWN0ZXIgaW4gdGhlIHN0cmluZy4KICAqIEBwYXJhbSBzdGF0dXMgdGhlIGVycm9yIGNvZGUgc3RhdHVzLgogICogQHJldHVybiB0aGUgbmV4dCBjaGFyYWN0ZXIncyBvcmRlcmluZy4gb3RoZXJ3aXNlIHJldHVybnMgTlVMTE9SREVSIGlmIGFuIAogICogICAgICAgICBlcnJvciBoYXMgb2NjdXJlZCBvciBpZiB0aGUgZW5kIG9mIHN0cmluZyBoYXMgYmVlbiByZWFjaGVkCiAgKi8KICBpbnQzMl90IG5leHQoVUVycm9yQ29kZSYgc3RhdHVzKTsKCiAgLyoqCiAgKiBHZXQgdGhlIG9yZGVyaW5nIHByaW9yaXR5IG9mIHRoZSBwcmV2aW91cyBjb2xsYXRpb24gZWxlbWVudCBpbiB0aGUgc3RyaW5nLgogICogQHBhcmFtIHN0YXR1cyB0aGUgZXJyb3IgY29kZSBzdGF0dXMuCiAgKiBAcmV0dXJuIHRoZSBwcmV2aW91cyBlbGVtZW50J3Mgb3JkZXJpbmcuIG90aGVyd2lzZSByZXR1cm5zIE5VTExPUkRFUiBpZiBhbiAKICAqICAgICAgICAgZXJyb3IgaGFzIG9jY3VyZWQgb3IgaWYgdGhlIHN0YXJ0IG9mIHN0cmluZyBoYXMgYmVlbiByZWFjaGVkCiAgKi8KICBpbnQzMl90IHByZXZpb3VzKFVFcnJvckNvZGUmIHN0YXR1cyk7CgogIC8qKgogICogR2V0cyB0aGUgcHJpbWFyeSBvcmRlciBvZiBhIGNvbGxhdGlvbiBvcmRlci4KICAqIEBwYXJhbSBvcmRlciB0aGUgY29sbGF0aW9uIG9yZGVyCiAgKiBAcmV0dXJuIHRoZSBwcmltYXJ5IG9yZGVyIG9mIGEgY29sbGF0aW9uIG9yZGVyLgogICovCiAgc3RhdGljIGludDMyX3QgcHJpbWFyeU9yZGVyKGludDMyX3Qgb3JkZXIpOwoKICAvKioKICAqIEdldHMgdGhlIHNlY29uZGFyeSBvcmRlciBvZiBhIGNvbGxhdGlvbiBvcmRlci4KICAqIEBwYXJhbSBvcmRlciB0aGUgY29sbGF0aW9uIG9yZGVyCiAgKiBAcmV0dXJuIHRoZSBzZWNvbmRhcnkgb3JkZXIgb2YgYSBjb2xsYXRpb24gb3JkZXIuCiAgKi8KICBzdGF0aWMgaW50MzJfdCBzZWNvbmRhcnlPcmRlcihpbnQzMl90IG9yZGVyKTsKCiAgLyoqCiAgKiBHZXRzIHRoZSB0ZXJ0aWFyeSBvcmRlciBvZiBhIGNvbGxhdGlvbiBvcmRlci4KICAqIEBwYXJhbSBvcmRlciB0aGUgY29sbGF0aW9uIG9yZGVyCiAgKiBAcmV0dXJuIHRoZSB0ZXJ0aWFyeSBvcmRlciBvZiBhIGNvbGxhdGlvbiBvcmRlci4KICAqLwogIHN0YXRpYyBpbnQzMl90IHRlcnRpYXJ5T3JkZXIoaW50MzJfdCBvcmRlcik7CgogIC8qKgogICogUmV0dXJuIHRoZSBtYXhpbXVtIGxlbmd0aCBvZiBhbnkgZXhwYW5zaW9uIHNlcXVlbmNlcyB0aGF0IGVuZCB3aXRoIHRoZSAKICAqIHNwZWNpZmllZCBjb21wYXJpc29uIG9yZGVyLgogICogQHBhcmFtIG9yZGVyIGEgY29sbGF0aW9uIG9yZGVyIHJldHVybmVkIGJ5IHByZXZpb3VzIG9yIG5leHQuCiAgKiBAcmV0dXJuIG1heGltdW0gc2l6ZSBvZiB0aGUgZXhwYW5zaW9uIHNlcXVlbmNlcyBlbmRpbmcgd2l0aCB0aGUgY29sbGF0aW9uIAogICogICAgICAgICBlbGVtZW50IG9yIDEgaWYgY29sbGF0aW9uIGVsZW1lbnQgZG9lcyBub3Qgb2NjdXIgYXQgdGhlIGVuZCBvZiBhbnkgCiAgKiAgICAgICAgIGV4cGFuc2lvbiBzZXF1ZW5jZQogICovCiAgaW50MzJfdCBnZXRNYXhFeHBhbnNpb24oaW50MzJfdCBvcmRlcikgY29uc3Q7CgogIC8qKgogICogR2V0cyB0aGUgY29tcGFyaXNvbiBvcmRlciBpbiB0aGUgZGVzaXJlZCBzdHJlbmd0aC4gSWdub3JlIHRoZSBvdGhlcgogICogZGlmZmVyZW5jZXMuCiAgKiBAcGFyYW0gb3JkZXIgVGhlIG9yZGVyIHZhbHVlCiAgKi8KICBpbnQzMl90IHN0cmVuZ3RoT3JkZXIoaW50MzJfdCBvcmRlcikgY29uc3Q7CgogIC8qKgogICogU2V0cyB0aGUgc291cmNlIHN0cmluZy4KICAqIEBwYXJhbSBzdHIgdGhlIHNvdXJjZSBzdHJpbmcuCiAgKiBAcGFyYW0gc3RhdHVzIHRoZSBlcnJvciBjb2RlIHN0YXR1cy4KICAqLwogIHZvaWQgc2V0VGV4dChjb25zdCBVbmljb2RlU3RyaW5nJiBzdHIsIFVFcnJvckNvZGUmIHN0YXR1cyk7CgogIC8qKgogICogU2V0cyB0aGUgc291cmNlIHN0cmluZy4KICAqIEBwYXJhbSBzdHIgdGhlIHNvdXJjZSBjaGFyYWN0ZXIgaXRlcmF0b3IuCiAgKiBAcGFyYW0gc3RhdHVzIHRoZSBlcnJvciBjb2RlIHN0YXR1cy4KICAqLwogIHZvaWQgc2V0VGV4dChDaGFyYWN0ZXJJdGVyYXRvciYgc3RyLCBVRXJyb3JDb2RlJiBzdGF0dXMpOwoKICAvKioKICAqIENoZWNrcyBpZiBhIGNvbXBhcmlzb24gb3JkZXIgaXMgaWdub3JhYmxlLgogICogQHBhcmFtIG9yZGVyIHRoZSBjb2xsYXRpb24gb3JkZXIuCiAgKiBAcmV0dXJuIFRSVUUgaWYgYSBjaGFyYWN0ZXIgaXMgaWdub3JhYmxlLCBGQUxTRSBvdGhlcndpc2UuCiAgKi8KICBzdGF0aWMgVUJvb2wgaXNJZ25vcmFibGUoaW50MzJfdCBvcmRlcik7CgogIC8qKgogICogR2V0cyB0aGUgb2Zmc2V0IG9mIHRoZSBjdXJyZW50bHkgcHJvY2Vzc2VkIGNoYXJhY3RlciBpbiB0aGUgc291cmNlIHN0cmluZy4KICAqIEByZXR1cm4gdGhlIG9mZnNldCBvZiB0aGUgY2hhcmFjdGVyLgogICovCiAgVVRleHRPZmZzZXQgZ2V0T2Zmc2V0KHZvaWQpIGNvbnN0OwoKICAvKioKICAqIFNldHMgdGhlIG9mZnNldCBvZiB0aGUgY3VycmVudGx5IHByb2Nlc3NlZCBjaGFyYWN0ZXIgaW4gdGhlIHNvdXJjZSBzdHJpbmcuCiAgKiBAcGFyYW0gbmV3T2Zmc2V0IHRoZSBuZXcgb2Zmc2V0LgogICogQHBhcmFtIHN0YXR1cyB0aGUgZXJyb3IgY29kZSBzdGF0dXMuCiAgKiBAcmV0dXJuIHRoZSBvZmZzZXQgb2YgdGhlIGNoYXJhY3Rlci4KICAqLwogIHZvaWQgc2V0T2Zmc2V0KFVUZXh0T2Zmc2V0IG5ld09mZnNldCwgVUVycm9yQ29kZSYgc3RhdHVzKTsKCnByb3RlY3RlZDoKICAKICAvLyBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IgcHJvdGVjdGVkIGNvbnN0cnVjdG9ycyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICBmcmllbmQgY2xhc3MgUnVsZUJhc2VkQ29sbGF0b3I7CgogIC8qKgogICogQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yIGNvbnN0cnVjdG9yLiBUaGlzIHRha2VzIHRoZSBzb3VyY2Ugc3RyaW5nIGFuZCB0aGUgCiAgKiBjb2xsYXRpb24gb2JqZWN0LiBUaGUgY3Vyc29yIHdpbGwgd2FsayB0aHJ1IHRoZSBzb3VyY2Ugc3RyaW5nIGJhc2VkIG9uIHRoZSAKICAqIHByZWRlZmluZWQgY29sbGF0aW9uIHJ1bGVzLiBJZiB0aGUgc291cmNlIHN0cmluZyBpcyBlbXB0eSwgTlVMTE9SREVSIHdpbGwgCiAgKiBiZSByZXR1cm5lZCBvbiB0aGUgY2FsbHMgdG8gbmV4dCgpLgogICogQHBhcmFtIHNvdXJjZVRleHQgdGhlIHNvdXJjZSBzdHJpbmcuCiAgKiBAcGFyYW0gc3RhcnRPZmZzZXQgdGhlIGJlZ2lubmluZyBvZmZzZXQgb2YgdGhlIHN0cmluZyB3aGVyZSB0aGUgY3Vyc29yIAogICogICAgICAgIHN0YXJ0cyB0aGUgaXRlcmF0aW5nLgogICogQHBhcmFtIGVuZE9mZnNldCB0aGUgZW5kaW5nIG9mZnNldCBvZiB0aGUgc3RyaW5nIHdoZXJlIHRoZSBjdXJzb3Igc3RvcHMgdGhlIAogICogICAgICAgIGl0ZXJhdGluZy4KICAqIEBwYXJhbSBvcmRlciB0aGUgY29sbGF0aW9uIG9iamVjdC4KICAqLwogIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcihjb25zdCBVbmljb2RlU3RyaW5nJiBzb3VyY2VUZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBSdWxlQmFzZWRDb2xsYXRvciogb3JkZXIsIFVFcnJvckNvZGUmIHN0YXR1cyk7CgogIC8qKgogICogQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yIGNvbnN0cnVjdG9yLiBUaGlzIHRha2VzIHRoZSBzb3VyY2Ugc3RyaW5nIGFuZCB0aGUgCiAgKiBjb2xsYXRpb24gb2JqZWN0LiAgVGhlIGN1cnNvciB3aWxsIHdhbGsgdGhydSB0aGUgc291cmNlIHN0cmluZyBiYXNlZCBvbiB0aGUgCiAgKiBwcmVkZWZpbmVkIGNvbGxhdGlvbiBydWxlcy4gIElmIHRoZSBzb3VyY2Ugc3RyaW5nIGlzIGVtcHR5LCBOVUxMT1JERVIgd2lsbCAKICAqIGJlIHJldHVybmVkIG9uIHRoZSBjYWxscyB0byBuZXh0KCkuCiAgKiBAcGFyYW0gc291cmNlVGV4dCB0aGUgc291cmNlIHN0cmluZy4KICAqIEBwYXJhbSBzdGFydE9mZnNldCB0aGUgYmVnaW5uaW5nIG9mZnNldCBvZiB0aGUgc3RyaW5nIHdoZXJlIHRoZSBjdXJzb3IgCiAgKiAgICAgICAgc3RhcnRzIHRoZSBpdGVyYXRpbmcuCiAgKiBAcGFyYW0gZW5kT2Zmc2V0IHRoZSBlbmRpbmcgb2Zmc2V0IG9mIHRoZSBzdHJpbmcgd2hlcmUgdGhlIGN1cnNvciBzdG9wcyB0aGUgCiAgKiAgICAgICAgaXRlcmF0aW5nLgogICogQHBhcmFtIG9yZGVyIHRoZSBjb2xsYXRpb24gb2JqZWN0LgogICovCiAgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yKGNvbnN0IENoYXJhY3Rlckl0ZXJhdG9yJiBzb3VyY2VUZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBSdWxlQmFzZWRDb2xsYXRvciogb3JkZXIsIFVFcnJvckNvZGUmIHN0YXR1cyk7CiAgCiAgLy8gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yIHByb3RlY3RlZCBtZXRob2RzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgLyoqCiAgKiBBc3NpZ25tZW50IG9wZXJhdG9yCiAgKi8KICBjb25zdCBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3ImCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wZXJhdG9yPShjb25zdCBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3ImIG90aGVyKTsKCnByaXZhdGU6CgogIC8vIGZyaWVuZCAgY2xhc3MgICBSdWxlQmFzZWRDb2xsYXRvcjsKCiAgLy8gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yIHByaXZhdGUgZGF0YSBtZW1iZXJzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgLy8gc3RhdGljIGNvbnN0IGludDMyX3QgVU5NQVBQRURDSEFSVkFMVUU7CgogIC8qIAogIE5vcm1hbGl6ZXIqIHRleHQ7ICAgICAgIC8vIG93bmluZyAKCiAgVmVjdG9yT2ZJbnQqIGJ1ZmZlckFsaWFzOyAvLyBub3Qgb3duZWQKICAqLwoKICAvKioKICAqIG93bkJ1ZmZlciB3YW50cyB0byBiZSBhIHN1Ym9iamVjdCwgbm90IGEgcG9pbnRlciwgYnV0IHRoYXQgbWVhbnMgZXhwb3NpbmcgCiAgKiB0aGUgaW50ZXJuYWwgY2xhc3MgVmVjdG9yT2ZJbnQgYnkgI2luY2x1ZGluZyB0aGUgaW50ZXJuYWwgaGVhZGVyIAogICogInRhYmxlcy5oIiAtLSBub3QgYWxsb3dlZCEgb3duQnVmZmVyIGlzIGEgZml4ZWQtc2l6ZSAyLWVsZW1lbnQgdmVjdG9yIHRoYXQgCiAgKiBpcyB1c2VkIHRvIGhhbmRsZSBUaGFpIGNvbGxhdGlvbjsgYnVmZmVyQWxpYXMgcG9pbnRzIHRvIG93bkJ1ZmZlciBpbiBzb21lIAogICogc2l0dWF0aW9ucy4gW2oxNTkgLSBhbGl1XQogICovCiAgLy8gVmVjdG9yT2ZJbnQqIG93bkJ1ZmZlcjsKCiAgLyoqCiAgKiByZW9yZGVyQnVmZmVyIGlzIGNyZWF0ZWQgb24gZGVtYW5kLCBzbyBpdCBkb2Vzbid0IHdhbnQgdG8gYmUgYSBzdWJvYmplY3QgLS0gCiAgKiBwb2ludGVyIGlzIGZpbmUuIEl0IGlzIGNyZWF0ZWQgYW5kIGJ1ZmZlckFsaWFzIGlzIHNldCB0byBpdCB1bmRlciBjZXJ0YWluIAogICogY29uZGl0aW9ucy4gT25jZSBjcmVhdGVkLCBpdCBpcyByZXVzZWQgZm9yIHRoZSBsaWZlIG9mIHRoaXMgb2JqZWN0LiBCZWNhdXNlIAogICogb2YgdGhlIGltcGxlbWVudGF0aW9uIG9mIFZlY3Rvck9mSW50LCBpdCBncm93cyBtb25vdG9uaWNhbGx5LiBbajE1OSAtIGFsaXVdCiAgKi8KICAvKgogIFZlY3Rvck9mSW50KiByZW9yZGVyQnVmZmVyOwoKICBpbnQzMl90IGV4cEluZGV4OwogIFVuaWNvZGVTdHJpbmcga2V5OwogIGNvbnN0IFJ1bGVCYXNlZENvbGxhdG9yKiBvcmRlckFsaWFzOwogICovCgogIC8qKgogICogRGF0YSB3cmFwcGVyIGZvciBjb2xsYXRpb24gZWxlbWVudHMKICAqLwogIFVDb2xsYXRpb25FbGVtZW50cyAqbV9kYXRhXzsKCiAgLyoqCiAgKiBJbmRpY2F0ZXMgaWYgbV9kYXRhXyBiZWxvbmdzIHRvIHRoaXMgb2JqZWN0LgogICovCiAgVUJvb2wgaXNEYXRhT3duZWRfOwogIAogIC8vIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciBwcml2YXRlIGNvbnN0cnVjdG9yL2Rlc3RydWN0b3IgLS0tLS0tLS0tLS0tLS0tLS0tCgogIC8qKgogICogRGVmYXVsdCBjb25zdHJ1Y3Rvci4KICAqLwogIC8qIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcigpOyAqLwogIAogIC8qKgogICogQ29uc3RydWN0b3IuCiAgKiBAcGFyYW0gb3JkZXIgUnVsZUJhc2VkQ29sbGF0b3Igb2JqZWN0CiAgKi8KICBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IoY29uc3QgUnVsZUJhc2VkQ29sbGF0b3IqIG9yZGVyKTsKCiAgLy8gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yIHByaXZhdGUgbWV0aG9kcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgLyoqCiAgKiBHZXRzIHRoZSBvcmRlcmluZyBwcmlvcml0eSBvZiB0aGUgbmV4dCBjb250cmFjdGluZyBjaGFyYWN0ZXIgaW4gdGhlIHN0cmluZy4KICAqIEBwYXJhbSBjaCB0aGUgc3RhcnRpbmcgY2hhcmFjdGVyIG9mIGEgY29udHJhY3RpbmcgY2hhcmFjdGVyIHRva2VuCiAgKiBAcGFyYW0gc3RhdHVzIHRoZSBlcnJvciBjb2RlIHN0YXR1cy4KICAqIEByZXR1cm4gdGhlIG5leHQgY29udHJhY3RpbmcgY2hhcmFjdGVyJ3Mgb3JkZXJpbmcuIFJldHVybnMgTlVMTE9SREVSIGlmIHRoZSAKICAqICAgICAgICAgZW5kIG9mIHN0cmluZyBpcyByZWFjaGVkLgogICovCiAgLy8gaW50MzJfdCBuZXh0Q29udHJhY3RDaGFyKFVDaGFyMzIgY2gsIFVFcnJvckNvZGUmICBzdGF0dXMpOwoKICAvKioKICAqIEdldHMgdGhlIG9yZGVyaW5nIHByaW9yaXR5IG9mIHRoZSBwcmV2aW91cyBjb250cmFjdGluZyBjaGFyYWN0ZXIgaW4gdGhlCiAgKiBzdHJpbmcuCiAgKiBAcGFyYW0gY2ggdGhlIHN0YXJ0aW5nIGNoYXJhY3RlciBvZiBhIGNvbnRyYWN0aW5nIGNoYXJhY3RlciB0b2tlbgogICogQHBhcmFtIHN0YXR1cyB0aGUgZXJyb3IgY29kZSBzdGF0dXMuCiAgKiBAcmV0dXJuIHRoZSBwcmV2aW91cyBjb250cmFjdGluZyBjaGFyYWN0ZXIncyBvcmRlcmluZy4gUmV0dXJucyBOVUxMT1JERVIgaWYgCiAgKiAgICAgICAgIHRoZSBzdGFydCBvZiBzdHJpbmcgaXMgcmVhY2hlZC4KICAqLwogIC8vIGludDMyX3QgcHJldkNvbnRyYWN0Q2hhcihVQ2hhcjMyIGNoLCBVRXJyb3JDb2RlJiAgc3RhdHVzKTsKICAgIAogIC8vIGlubGluZSBzdGF0aWMgVUJvb2wgaXNUaGFpUHJlVm93ZWwoVUNoYXIzMiBjaCk7CiAgICAgICAgICAgICAgICAgCiAgLy8gaW5saW5lIHN0YXRpYyBVQm9vbCBpc1RoYWlCYXNlQ29uc29uYW50KFVDaGFyMzIgY2gpOwogICAgICAgICAgICAgICAKICAvKgogIFZlY3Rvck9mSW50KiBtYWtlUmVvcmRlcmVkQnVmZmVyKFVDaGFyIGNvbEZpcnN0LCBpbnQzMl90IGxhc3RWYWx1ZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVmVjdG9yT2ZJbnQqIGxhc3RFeHBhbnNpb24sIFVCb29sIGZvcndhcmQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cyk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KfTsKCi8vIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciBpbmxpbmUgbWV0aG9kIGRlZmluYXRpb24gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCi8qKgoqIEdldCB0aGUgcHJpbWFyeSBvcmRlciBvZiBhIGNvbGxhdGlvbiBvcmRlci4KKiBAcGFyYW0gb3JkZXIgdGhlIGNvbGxhdGlvbiBvcmRlcgoqIEByZXR1cm4gdGhlIHByaW1hcnkgb3JkZXIgb2YgYSBjb2xsYXRpb24gb3JkZXIuCiovCmlubGluZSBpbnQzMl90IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6cHJpbWFyeU9yZGVyKGludDMyX3Qgb3JkZXIpCnsKICBvcmRlciAmPSBSdWxlQmFzZWRDb2xsYXRvcjo6UFJJTUFSWU9SREVSTUFTSzsKICByZXR1cm4gKG9yZGVyID4+IFJ1bGVCYXNlZENvbGxhdG9yOjpQUklNQVJZT1JERVJTSElGVCk7Cn0KCi8qKgoqIEdldCB0aGUgc2Vjb25kYXJ5IG9yZGVyIG9mIGEgY29sbGF0aW9uIG9yZGVyLgoqIEBwYXJhbSBvcmRlciB0aGUgY29sbGF0aW9uIG9yZGVyCiogQHJldHVybiB0aGUgc2Vjb25kYXJ5IG9yZGVyIG9mIGEgY29sbGF0aW9uIG9yZGVyLgoqLwppbmxpbmUgaW50MzJfdCBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6OnNlY29uZGFyeU9yZGVyKGludDMyX3Qgb3JkZXIpCnsKICBvcmRlciA9IG9yZGVyICYgUnVsZUJhc2VkQ29sbGF0b3I6OlNFQ09OREFSWU9SREVSTUFTSzsKICByZXR1cm4gKG9yZGVyID4+IFJ1bGVCYXNlZENvbGxhdG9yOjpTRUNPTkRBUllPUkRFUlNISUZUKTsKfQoKLyoqCiogR2V0IHRoZSB0ZXJ0aWFyeSBvcmRlciBvZiBhIGNvbGxhdGlvbiBvcmRlci4KKiBAcGFyYW0gb3JkZXIgdGhlIGNvbGxhdGlvbiBvcmRlcgoqIEByZXR1cm4gdGhlIHRlcnRpYXJ5IG9yZGVyIG9mIGEgY29sbGF0aW9uIG9yZGVyLgoqLwppbmxpbmUgaW50MzJfdCBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6OnRlcnRpYXJ5T3JkZXIoaW50MzJfdCBvcmRlcikKewogIHJldHVybiAob3JkZXIgJj0gUnVsZUJhc2VkQ29sbGF0b3I6OlRFUlRJQVJZT1JERVJNQVNLKTsKfQoKaW5saW5lIGludDMyX3QgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpnZXRNYXhFeHBhbnNpb24oaW50MzJfdCBvcmRlcikgY29uc3QKewogIHJldHVybiB1Y29sX2dldE1heEV4cGFuc2lvbihtX2RhdGFfLCAodWludDMyX3Qpb3JkZXIpOwp9CgppbmxpbmUgVUJvb2wgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjppc0lnbm9yYWJsZShpbnQzMl90IG9yZGVyKQp7CiAgcmV0dXJuIChwcmltYXJ5T3JkZXIob3JkZXIpID09IFJ1bGVCYXNlZENvbGxhdG9yOjpQUklNSUdOT1JBQkxFKTsKfQoKLyoqCiogRGV0ZXJtaW5lIGlmIGEgY2hhcmFjdGVyIGlzIGEgVGhhaSB2b3dlbCAod2hpY2ggc29ydHMgYWZ0ZXIKKiBpdHMgYmFzZSBjb25zb25hbnQpLgoqLwovKgppbmxpbmUgVUJvb2wgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjppc1RoYWlQcmVWb3dlbChVQ2hhcjMyIGNoKSAKewogIHJldHVybiAoKHVpbnQzMl90KWNoIC0gMHhlNDApIDw9ICgweGU0NCAtIDB4ZTQwKTsKfQoqLwoKLyoqCiogRGV0ZXJtaW5lIGlmIGEgY2hhcmFjdGVyIGlzIGEgVGhhaSBiYXNlIGNvbnNvbmFudAoqLwovKgppbmxpbmUgVUJvb2wgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjppc1RoYWlCYXNlQ29uc29uYW50KFVDaGFyMzIgY2gpIAp7CiAgcmV0dXJuICgodWludDMyX3QpY2ggLSAweGUwMSkgPD0gKDB4ZTJlIC0gMHhlMDEpOwp9CiovCgojZW5kaWYK