LyoKKiBDb3B5cmlnaHQgqSB7MTk5Ni0xOTk5fSwgSW50ZXJuYXRpb25hbCBCdXNpbmVzcyBNYWNoaW5lcyBDb3Jwb3JhdGlvbiBhbmQgb3RoZXJzLiBBbGwgUmlnaHRzIFJlc2VydmVkLgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCioKKiBGaWxlIHRibGNvbGwuaAoqCiogQ3JlYXRlZCBieTogSGVsZW5hIFNoaWgKKgoqIE1vZGlmaWNhdGlvbiBIaXN0b3J5OgoqCiogIERhdGUgICAgICAgIE5hbWUgICAgICAgIERlc2NyaXB0aW9uCiogIDIvNS85NyAgICAgIGFsaXUgICAgICAgIEFkZGVkIHN0cmVhbUluIGFuZCBzdHJlYW1PdXQgbWV0aG9kcy4gIEFkZGVkCiogICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0cnVjdG9yIHdoaWNoIHJlYWRzIFJ1bGVCYXNlZENvbGxhdG9yIG9iamVjdCBmcm9tCiogICAgICAgICAgICAgICAgICAgICAgICAgIGEgYmluYXJ5IGZpbGUuICBBZGRlZCB3cml0ZVRvRmlsZSBtZXRob2Qgd2hpY2ggc3RyZWFtcwoqICAgICAgICAgICAgICAgICAgICAgICAgICBSdWxlQmFzZWRDb2xsYXRvciBvdXQgdG8gYSBiaW5hcnkgZmlsZS4gIFRoZSBzdHJlYW1JbgoqICAgICAgICAgICAgICAgICAgICAgICAgICBhbmQgc3RyZWFtT3V0IG1ldGhvZHMgdXNlIGlzdHJlYW0gYW5kIG9zdHJlYW0gb2JqZWN0cwoqICAgICAgICAgICAgICAgICAgICAgICAgICBpbiBiaW5hcnkgbW9kZS4KKiAgMi8xMi85NyAgICAgYWxpdSAgICAgICAgTW9kaWZpZWQgdG8gdXNlIFRhYmxlQ29sbGF0aW9uRGF0YSBzdWItb2JqZWN0IHRvCiogICAgICAgICAgICAgICAgICAgICAgICAgIGhvbGQgaW52YXJpYW50IGRhdGEuCiogIDIvMTMvOTcgICAgIGFsaXUgICAgICAgIE1vdmVkIHNldmVyYWwgbWV0aG9kcyBpbnRvIHRoaXMgY2xhc3MgZnJvbSBDb2xsYXRpb24uCiogICAgICAgICAgICAgICAgICAgICAgICAgIEFkZGVkIGEgcHJpdmF0ZSBSdWxlQmFzZWRDb2xsYXRvcihMb2NhbGUmKSBjb25zdHJ1Y3RvciwKKiAgICAgICAgICAgICAgICAgICAgICAgICAgdG8gYmUgdXNlZCBieSBDb2xsYXRvcjo6Y3JlYXRlRGVmYXVsdCgpLiAgR2VuZXJhbAoqICAgICAgICAgICAgICAgICAgICAgICAgICBjbGVhbiB1cC4KKiAgMi8yMC85NyAgICAgaGVsZW5hICAgICAgQWRkZWQgY2xvbmUsIG9wZXJhdG9yPT0sIG9wZXJhdG9yIT0sIG9wZXJhdG9yPSwgYW5kIGNvcHkKKiAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3RydWN0b3IgYW5kIGdldER5bmFtaWNDbGFzc0lELgoqICAzLzUvOTcgICAgICBhbGl1ICAgICAgICBNb2RpZmllZCBjb25zdHJ1Y3RGcm9tRmlsZSgpIHRvIGFkZCBwYXJhbWV0ZXIKKiAgICAgICAgICAgICAgICAgICAgICAgICAgc3BlY2lmeWluZyB3aGV0aGVyIG9yIG5vdCBiaW5hcnkgbG9hZGluZyBpcyB0byBiZQoqICAgICAgICAgICAgICAgICAgICAgICAgICBhdHRlbXB0ZWQuICBUaGlzIGlzIHJlcXVpcmVkIGZvciBkeW5hbWljIHJ1bGUgbG9hZGluZy4KKiAwNS8wNy85NyAgICAgaGVsZW5hICAgICAgQWRkZWQgbWVtb3J5IGFsbG9jYXRpb24gZXJyb3IgZGV0ZWN0aW9uLgoqICA2LzE3Lzk3ICAgICBoZWxlbmEgICAgICBBZGRlZCBJREVOVElDQUwgc3RyZW5ndGggZm9yIGNvbXBhcmUsIGNoYW5nZWQgZ2V0UnVsZXMgdG8gCiogICAgICAgICAgICAgICAgICAgICAgICAgIHVzZSBNZXJnZUNvbGxhdGlvbjo6Z2V0UGF0dGVybi4KKiAgNi8yMC85NyAgICAgaGVsZW5hICAgICAgSmF2YSBjbGFzcyBuYW1lIGNoYW5nZS4KKiAgOC8xOC85NyAgICAgaGVsZW5hICAgICAgQWRkZWQgaW50ZXJuYWwgQVBJIGRvY3VtZW50YXRpb24uCiogMDkvMDMvOTcgICAgIGhlbGVuYSAgICAgIEFkZGVkIGNyZWF0ZUNvbGxhdGlvbktleVZhbHVlcygpLgoqIDAyLzEwLzk4ICAgICBkYW1pYmEgICAgICBBZGRlZCBjb21wYXJlIHdpdGggImxlbmd0aCIgcGFyYW1ldGVyCiogMDgvMDUvOTggICAgIGVybSAgICAgICAgIFN5bmNoZWQgd2l0aCAxLjIgdmVyc2lvbiBvZiBSdWxlQmFzZWRDb2xsYXRvci5qYXZhCiogMDQvMjMvOTkgICAgIHN0ZXBoZW4gICAgIFJlbW92ZWQgRURlY29tcG9zaXRpb25Nb2RlLCBtZXJnZWQgd2l0aAoqICAgICAgICAgICAgICAgICAgICAgICAgICBOb3JtYWxpemVyOjpFTW9kZQoqIDA2LzE0Lzk5ICAgICBzdGVwaGVuICAgICBSZW1vdmVkIGtSZXNvdXJjZUJ1bmRsZVN1ZmZpeAoqIDExLzAyLzk5ICAgICBoZWxlbmEgICAgICBDb2xsYXRvciBwZXJmb3JtYW5jZSBlbmhhbmNlbWVudHMuICBFbGltaW5hdGVzIHRoZSAKKiAgICAgICAgICAgICAgICAgICAgICAgICAgVW5pY29kZVN0cmluZyBjb25zdHJ1Y3Rpb24gYW5kIHNwZWNpYWwgY2FzZSBmb3IgTk9fT1AuCiogMTEvMjMvOTkgICAgIHNybCAgICAgICAgIE1vcmUgcGVyZm9ybWFuY2UgZW5oYW5jZW1lbnRzLiBVcGRhdGVzIHRvIE5vcm1hbGl6ZXJJdGVyYXRvcgoqICAgICAgICAgICAgICAgICAgICAgICAgICBpbnRlcm5hbCBzdGF0ZSBtYW5hZ2VtZW50LgoqIDEyLzE1Lzk5ICAgICBhbGl1ICAgICAgICBVcGRhdGUgdG8gc3VwcG9ydCBUaGFpIGNvbGxhdGlvbi4gIE1vdmUgTm9ybWFsaXplckl0ZXJhdG9yCiogICAgICAgICAgICAgICAgICAgICAgICAgIHRvIGltcGxlbWVudGF0aW9uIGZpbGUuCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKi8KCiNpZm5kZWYgVEJMQ09MTF9ICiNkZWZpbmUgVEJMQ09MTF9ICgojaW5jbHVkZSAidW5pY29kZS91dHlwZXMuaCIKI2luY2x1ZGUgInVuaWNvZGUvY29sbC5oIgojaW5jbHVkZSAidW5pY29kZS9jaGFyaXRlci5oIgojaW5jbHVkZSAidW5pY29kZS91bmlzdHIuaCIKI2luY2x1ZGUgInVuaWNvZGUvc29ydGtleS5oIgojaW5jbHVkZSAidW5pY29kZS9ub3JtbHpyLmgiCgpjbGFzcyBWZWN0b3JPZlBUb0NvbnRyYWN0RWxlbWVudDsKY2xhc3MgVmVjdG9yT2ZJbnQ7CmNsYXNzIFZlY3Rvck9mUFRvQ29udHJhY3RUYWJsZTsKY2xhc3MgVmVjdG9yT2ZQVG9FeHBhbmRUYWJsZTsKY2xhc3MgTWVyZ2VDb2xsYXRpb247CmNsYXNzIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjsKY2xhc3MgUnVsZUJhc2VkQ29sbGF0b3JTdHJlYW1lcjsKY2xhc3MgTm9ybWFsaXplckl0ZXJhdG9yOyAvLyBzZWUgdGJsY29sbC5jcHAKY2xhc3MgQ29sbGF0b3I7CmNsYXNzIFRhYmxlQ29sbGF0aW9uRGF0YTsKCi8qKgogKiBUaGUgUnVsZUJhc2VkQ29sbGF0b3IgY2xhc3MgcHJvdmlkZXMgdGhlIHNpbXBsZSBpbXBsZW1lbnRhdGlvbiBvZiBDb2xsYXRvciwKICogdXNpbmcgZGF0YS1kcml2ZW4gdGFibGVzLiAgVGhlIHVzZXIgY2FuIGNyZWF0ZSBhIGN1c3RvbWl6ZWQgdGFibGUtYmFzZWQKICogY29sbGF0aW9uLgogKiA8UD4KICogUnVsZUJhc2VkQ29sbGF0b3IgbWFwcyBjaGFyYWN0ZXJzIHRvIGNvbGxhdGlvbiBrZXlzLgogKiA8cD4KICogVGFibGUgQ29sbGF0aW9uIGhhcyB0aGUgZm9sbG93aW5nIHJlc3RyaWN0aW9ucyBmb3IgZWZmaWNpZW5jeSAob3RoZXIKICogc3ViY2xhc3NlcyBtYXkgYmUgdXNlZCBmb3IgbW9yZSBjb21wbGV4IGxhbmd1YWdlcykgOgogKiAgICAgICA8cD4xLiBJZiB0aGUgRnJlbmNoIHNlY29uZGFyeSBvcmRlcmluZyBpcyBzcGVjaWZpZWQgaW4gYSBjb2xsYXRpb24gb2JqZWN0LCAKICogICAgICAgICAgICAgaXQgaXMgYXBwbGllZCB0byB0aGUgd2hvbGUgb2JqZWN0LgogKiAgICAgICA8cD4yLiBBbGwgbm9uLW1lbnRpb25lZCBVbmljb2RlIGNoYXJhY3RlcnMgYXJlIGF0IHRoZSBlbmQgb2YgdGhlCiAqICAgICAgICAgICAgIGNvbGxhdGlvbiBvcmRlci4KICogICAgICAgPHA+My4gUHJpdmF0ZSB1c2UgY2hhcmFjdGVycyBhcmUgdHJlYXRlZCBhcyBpZGVudGljYWwuICBUaGUgcHJpdmF0ZQogKiAgICAgICAgICAgICB1c2UgYXJlYSBpbiBVbmljb2RlIGlzIDB4RTgwMC0weEY4RkYuCiAqIDxwPlRoZSBjb2xsYXRpb24gdGFibGUgaXMgY29tcG9zZWQgb2YgYSBsaXN0IG9mIGNvbGxhdGlvbiBydWxlcywgd2hlcmUgZWFjaAogKiBydWxlIGlzIG9mIHRocmVlIGZvcm1zOgogKiA8cHJlPgogKiAuICAgICZsdDsgbW9kaWZpZXIgPgogKiAuICAgICZsdDsgcmVsYXRpb24gPiAmbHQ7IHRleHQtYXJndW1lbnQgPgogKiAuICAgICZsdDsgcmVzZXQgPiAmbHQ7IHRleHQtYXJndW1lbnQgPgogKiA8L3ByZT4KICogVGhlIGZvbGxvd2luZyBkZW1vbnN0cmF0ZXMgaG93IHRvIGNyZWF0ZSB5b3VyIG93biBjb2xsYXRpb24gcnVsZXM6CiAqIDxVTCBUeXBlPXJvdW5kPgogKiAgICA8TEk+PHN0cm9uZz5UZXh0IEFyZ3VtZW50PC9zdHJvbmc+OiBBIHRleHQgYXJndW1lbnQgaXMgYW55IHNlcXVlbmNlIG9mCiAqICAgICAgICBjaGFyYWN0ZXJzLCBleGNsdWRpbmcgc3BlY2lhbCBjaGFyYWN0ZXJzICh0aGF0IGlzLCB3aGl0ZXNwYWNlCiAqICAgICAgICBjaGFyYWN0ZXJzIGFuZCB0aGUgY2hhcmFjdGVycyB1c2VkIGluIG1vZGlmaWVyLCByZWxhdGlvbiBhbmQgcmVzZXQpLgogKiAgICAgICAgSWYgdGhvc2UgY2hhcmFjdGVycyBhcmUgZGVzaXJlZCwgeW91IGNhbiBwdXQgdGhlbSBpbiBzaW5nbGUgcXVvdGVzCiAqICAgICAgICAoZS5nLiBhbXBlcnNhbmQgPT4gJyYnKS48UD4KICogICAgPExJPjxzdHJvbmc+TW9kaWZpZXI8L3N0cm9uZz46IFRoZXJlIGlzIGEgc2luZ2xlIG1vZGlmaWVyLAogKiAgICAgICAgd2hpY2ggaXMgdXNlZCB0byBzcGVjaWZ5IHRoYXQgYWxsIHNlY29uZGFyeSBkaWZmZXJlbmNlcyBhcmUKICogICAgICAgIHNvcnRlZCBiYWNrd2FyZHMuCiAqICAgICAgICA8cD4nQCcgOiBJbmRpY2F0ZXMgdGhhdCBzZWNvbmRhcnkgZGlmZmVyZW5jZXMsIHN1Y2ggYXMgYWNjZW50cywgYXJlIAogKiAgICAgICAgICAgICAgICAgc29ydGVkIGJhY2t3YXJkcywgYXMgaW4gRnJlbmNoLjxQPgogKiAgICA8TEk+PHN0cm9uZz5SZWxhdGlvbjwvc3Ryb25nPjogVGhlIHJlbGF0aW9ucyBhcmUgdGhlIGZvbGxvd2luZzoKICogICAgICAgIDxVTCBUeXBlPXNxdWFyZT4KICogICAgICAgICAgICA8TEk+JyZsdDsnIDogR3JlYXRlciwgYXMgYSBsZXR0ZXIgZGlmZmVyZW5jZSAocHJpbWFyeSkKICogICAgICAgICAgICA8TEk+JzsnIDogR3JlYXRlciwgYXMgYW4gYWNjZW50IGRpZmZlcmVuY2UgKHNlY29uZGFyeSkKICogICAgICAgICAgICA8TEk+JywnIDogR3JlYXRlciwgYXMgYSBjYXNlIGRpZmZlcmVuY2UgKHRlcnRpYXJ5KQogKiAgICAgICAgICAgIDxMST4nPScgOiBFcXVhbAogKiAgICAgICAgPC9VTD48UD4KICogICAgPExJPjxzdHJvbmc+UmVzZXQ8L3N0cm9uZz46IFRoZXJlIGlzIGEgc2luZ2xlIHJlc2V0LAogKiAgICAgICAgd2hpY2ggaXMgdXNlZCBwcmltYXJpbHkgZm9yIGNvbnRyYWN0aW9ucyBhbmQgZXhwYW5zaW9ucywgYnV0IHdoaWNoCiAqICAgICAgICBjYW4gYWxzbyBiZSB1c2VkIHRvIGFkZCBhIG1vZGlmaWNhdGlvbiBhdCB0aGUgZW5kIG9mIGEgc2V0IG9mIHJ1bGVzLgogKiAgICAgICAgPHA+JyYnIDogSW5kaWNhdGVzIHRoYXQgdGhlIG5leHQgcnVsZSBmb2xsb3dzIHRoZSBwb3NpdGlvbiB0byB3aGVyZQogKiAgICAgICAgICAgIHRoZSByZXNldCB0ZXh0LWFyZ3VtZW50IHdvdWxkIGJlIHNvcnRlZC4KICoKICogPHA+CiAqIFRoaXMgc291bmRzIG1vcmUgY29tcGxpY2F0ZWQgdGhhbiBpdCBpcyBpbiBwcmFjdGljZS4gRm9yIGV4YW1wbGUsIHRoZQogKiBmb2xsb3dpbmcgYXJlIGVxdWl2YWxlbnQgd2F5cyBvZiBleHByZXNzaW5nIHRoZSBzYW1lIHRoaW5nOgogKiA8cHJlPgogKiAuICAgIGEgJmx0OyBiICZsdDsgYwogKiAuICAgIGEgJmx0OyBiICYgYiAmbHQ7IGMKICogLiAgICBhICZsdDsgYyAmIGEgJmx0OyBiCiAqIDwvcHJlPgogKiBOb3RpY2UgdGhhdCB0aGUgb3JkZXIgaXMgaW1wb3J0YW50LCBhcyB0aGUgc3Vic2VxdWVudCBpdGVtIGdvZXMgaW1tZWRpYXRlbHkKICogYWZ0ZXIgdGhlIHRleHQtYXJndW1lbnQuIFRoZSBmb2xsb3dpbmcgYXJlIG5vdCBlcXVpdmFsZW50OgogKiA8cHJlPgogKiAuICAgIGEgJmx0OyBiICYgYSAmbHQ7IGMKICogLiAgICBhICZsdDsgYyAmIGEgJmx0OyBiCiAqIDwvcHJlPgogKiBFaXRoZXIgdGhlIHRleHQtYXJndW1lbnQgbXVzdCBhbHJlYWR5IGJlIHByZXNlbnQgaW4gdGhlIHNlcXVlbmNlLCBvciBzb21lCiAqIGluaXRpYWwgc3Vic3RyaW5nIG9mIHRoZSB0ZXh0LWFyZ3VtZW50IG11c3QgYmUgcHJlc2VudC4gKGUuZy4gImEgJmx0OyBiICYgYWUgJmx0OwogKiBlIiBpcyB2YWxpZCBzaW5jZSAiYSIgaXMgcHJlc2VudCBpbiB0aGUgc2VxdWVuY2UgYmVmb3JlICJhZSIgaXMgcmVzZXQpLiBJbgogKiB0aGlzIGxhdHRlciBjYXNlLCAiYWUiIGlzIG5vdCBlbnRlcmVkIGFuZCB0cmVhdGVkIGFzIGEgc2luZ2xlIGNoYXJhY3RlcjsKICogaW5zdGVhZCwgImUiIGlzIHNvcnRlZCBhcyBpZiBpdCB3ZXJlIGV4cGFuZGVkIHRvIHR3byBjaGFyYWN0ZXJzOiAiYSIKICogZm9sbG93ZWQgYnkgYW4gImUiLiBUaGlzIGRpZmZlcmVuY2UgYXBwZWFycyBpbiBuYXR1cmFsIGxhbmd1YWdlczogaW4KICogdHJhZGl0aW9uYWwgU3BhbmlzaCAiY2giIGlzIHRyZWF0ZWQgYXMgdGhvdWdoIGl0IGNvbnRyYWN0cyB0byBhIHNpbmdsZQogKiBjaGFyYWN0ZXIgKGV4cHJlc3NlZCBhcyAiYyAmbHQ7IGNoICZsdDsgZCIpLCB3aGlsZSBpbiB0cmFkaXRpb25hbCBHZXJtYW4gIuQiCiAqIChhLXVtbGF1dCkgaXMgdHJlYXRlZCBhcyB0aG91Z2ggaXQgZXhwYW5kcyB0byB0d28gY2hhcmFjdGVycyAoZXhwcmVzc2VkIGFzCiAqICJhICYgYWUgOyDkICZsdDsgYiIpLgogKiA8cD48c3Ryb25nPklnbm9yYWJsZSBDaGFyYWN0ZXJzPC9zdHJvbmc+CiAqIDxwPkZvciBpZ25vcmFibGUgY2hhcmFjdGVycywgdGhlIGZpcnN0IHJ1bGUgbXVzdCBzdGFydCB3aXRoIGEgcmVsYXRpb24gKHRoZQogKiBleGFtcGxlcyB3ZSBoYXZlIHVzZWQgYWJvdmUgYXJlIHJlYWxseSBmcmFnbWVudHM7ICJhICZsdDsgYiIgcmVhbGx5IHNob3VsZCBiZQogKiAiJmx0OyBhICZsdDsgYiIpLiBJZiwgaG93ZXZlciwgdGhlIGZpcnN0IHJlbGF0aW9uIGlzIG5vdCAiJmx0OyIsIHRoZW4gYWxsIHRoZSAKICogdGV4dC1hcmd1bWVudHMgdXAgdG8gdGhlIGZpcnN0ICImbHQ7IiBhcmUgaWdub3JhYmxlLiBGb3IgZXhhbXBsZSwgIiwgLSAmbHQ7IGEgJmx0OyBiIgogKiBtYWtlcyAiLSIgYW4gaWdub3JhYmxlIGNoYXJhY3RlciwgYXMgd2Ugc2F3IGVhcmxpZXIgaW4gdGhlIHdvcmQKICogImJsYWNrLWJpcmRzIi4gSW4gdGhlIHNhbXBsZXMgZm9yIGRpZmZlcmVudCBsYW5ndWFnZXMsIHlvdSBzZWUgdGhhdCBtb3N0CiAqIGFjY2VudHMgYXJlIGlnbm9yYWJsZS4KICogPHA+PHN0cm9uZz5Ob3JtYWxpemF0aW9uIGFuZCBBY2NlbnRzPC9zdHJvbmc+CiAqIDxwPlRoZSBDb2xsYXRvciBvYmplY3QgYXV0b21hdGljYWxseSBub3JtYWxpemVzIHRleHQgaW50ZXJuYWxseSB0byBzZXBhcmF0ZQogKiBhY2NlbnRzIGZyb20gYmFzZSBjaGFyYWN0ZXJzIHdoZXJlIHBvc3NpYmxlLiBUaGlzIGlzIGRvbmUgYm90aCB3aGVuCiAqIHByb2Nlc3NpbmcgdGhlIHJ1bGVzLCBhbmQgd2hlbiBjb21wYXJpbmcgdHdvIHN0cmluZ3MuIENvbGxhdG9yIGFsc28gdXNlcwogKiB0aGUgVW5pY29kZSBjYW5vbmljYWwgbWFwcGluZyB0byBlbnN1cmUgdGhhdCBjb21iaW5pbmcgc2VxdWVuY2VzIGFyZSBzb3J0ZWQKICogcHJvcGVybHkgKGZvciBtb3JlIGluZm9ybWF0aW9uLCBzZWUgPEEgSFJFRj0iaHR0cDovL3d3dy5hdy5jb20vZGV2cHJlc3MiPgogKiBUaGUgVW5pY29kZSBTdGFuZGFyZCwgVmVyc2lvbiAyLjA8L0E+Lik8L1A+CiAqIDxwPjxzdHJvbmc+RXJyb3JzPC9zdHJvbmc+CiAqIDxwPlRoZSBmb2xsb3dpbmcgYXJlIGVycm9yczoKICogPFVMIFR5cGU9cm91bmQ+CiAqICAgICA8TEk+QSB0ZXh0LWFyZ3VtZW50IGNvbnRhaW5zIHVucXVvdGVkIHB1bmN0dWF0aW9uIHN5bWJvbHMKICogICAgICAgIChlLmcuICJhICZsdDsgYi1jICZsdDsgZCIpLgogKiAgICAgPExJPkEgcmVsYXRpb24gb3IgcmVzZXQgY2hhcmFjdGVyIG5vdCBmb2xsb3dlZCBieSBhIHRleHQtYXJndW1lbnQKICogICAgICAgIChlLmcuICJhICZsdDsgLCBiIikuCiAqICAgICA8TEk+QSByZXNldCB3aGVyZSB0aGUgdGV4dC1hcmd1bWVudCAob3IgYW4gaW5pdGlhbCBzdWJzdHJpbmcgb2YgdGhlCiAqICAgICAgICAgdGV4dC1hcmd1bWVudCkgaXMgbm90IGFscmVhZHkgaW4gdGhlIHNlcXVlbmNlLgogKiAgICAgICAgIChlLmcuICJhICZsdDsgYiAmIGUgJmx0OyBmIikKICogPC9VTD4KICogPHByZT4KICogLiAgICBFeGFtcGxlczoKICogLiAgICBTaW1wbGU6ICAgICAiJmx0OyBhICZsdDsgYiAmbHQ7IGMgJmx0OyBkIgogKiAuICAgIE5vcndlZ2lhbjogICImbHQ7IGEsQSZsdDsgYixCJmx0OyBjLEMmbHQ7IGQsRCZsdDsgZSxFJmx0OyBmLEYmbHQ7IGcsRyZsdDsgaCxIJmx0OyBpLEkmbHQ7IGosSgogKiAuICAgICAgICAgICAgICAgICAmbHQ7IGssSyZsdDsgbCxMJmx0OyBtLE0mbHQ7IG4sTiZsdDsgbyxPJmx0OyBwLFAmbHQ7IHEsUSZsdDsgcixSJmx0OyBzLFMmbHQ7IHQsVAogKiAuICAgICAgICAgICAgICAgICAmbHQ7IHUsVSZsdDsgdixWJmx0OyB3LFcmbHQ7IHgsWCZsdDsgeSxZJmx0OyB6LFoKICogLiAgICAgICAgICAgICAgICAgJmx0OyDlPWGwLMU9QbAKICogLiAgICAgICAgICAgICAgICAgO2FhLEFBJmx0OyDmLMYmbHQ7IPgs2CIKICogPC9wcmU+CiAqIDxwPlRvIGNyZWF0ZSBhIHRhYmxlLWJhc2VkIGNvbGxhdGlvbiBvYmplY3QsIHNpbXBseSBzdXBwbHkgdGhlIGNvbGxhdGlvbgogKiBydWxlcyB0byB0aGUgUnVsZUJhc2VkQ29sbGF0b3IgY29udHJ1Y3Rvci4gIEZvciBleGFtcGxlOgogKiA8cHJlPgogKiAuICAgIFVFcnJvckNvZGUgc3RhdHVzID0gVV9aRVJPX0VSUk9SOwogKiAuICAgIFJ1bGVCYXNlZENvbGxhdG9yICpteVNpbXBsZSA9IG5ldyBSdWxlQmFzZWRDb2xsYXRvcihTaW1wbGUsIHN0YXR1cyk7CiAqIDwvcHJlPgogKiA8cD5Bbm90aGVyIGV4YW1wbGU6CiAqIDxwcmU+CiAqIC4gICAgVUVycm9yQ29kZSBzdGF0dXMgPSBVX1pFUk9fRVJST1I7CiAqIC4gICAgUnVsZUJhc2VkQ29sbGF0b3IgKm15Tm9yd2VnaWFuID0gbmV3IFJ1bGVCYXNlZENvbGxhdG9yKE5vcndlZ2lhbiwgc3RhdHVzKTsKICogPC9wcmU+CiAqIFRvIGFkZCBydWxlcyBvbiB0b3Agb2YgYW4gZXhpc3RpbmcgdGFibGUsIHNpbXBseSBzdXBwbHkgdGhlIG9yZ2luYWwgcnVsZXMKICogYW5kIG1vZGlmaWNhdGlvbnMgdG8gUnVsZUJhc2VkQ29sbGF0b3IgY29uc3RydWN0b3IuICBGb3IgZXhhbXBsZSwKICogPHByZT4KICogLiAgICAgVHJhZGl0aW9uYWwgU3BhbmlzaCAoZnJhZ21lbnQpOiAuLi4gJiBDICZsdDsgY2ggLCBjSCAsIENoICwgQ0ggLi4uCiAqIC4gICAgIEdlcm1hbiAoZnJhZ21lbnQpIDogLi4uJmx0OyB5ICwgWSAmbHQ7IHogLCBaCiAqIC4gICAgICAgICAgICAgICAgICAgICAgICAgJiBBRSwgxCAmIEFFLCDkIAogKiAuICAgICAgICAgICAgICAgICAgICAgICAgICYgT0UgLCDWICYgT0UsIPYgCiAqIC4gICAgICAgICAgICAgICAgICAgICAgICAgJiBVRSAsINwgJiBVRSwg/CAKICogLiAgICAgU3ltYm9scyAoZnJhZ21lbnQpOiAuLi4mbHQ7IHksIFkgJmx0OyB6ICwgWgogKiAuICAgICAgICAgICAgICAgICAgICAgICAgICYgUXVlc3Rpb24tbWFyayA7ICc/JwogKiAuICAgICAgICAgICAgICAgICAgICAgICAgICYgQW1wZXJzYW5kIDsgJyYnCiAqIC4gICAgICAgICAgICAgICAgICAgICAgICAgJiBEb2xsYXItc2lnbiA7ICckJwogKiA8cD5UbyBjcmVhdGUgYSBjb2xsYXRpb24gb2JqZWN0IGZvciB0cmFkaXRpb25hbCBTcGFuaXNoLCB0aGUgdXNlciBjYW4gdGFrZQogKiB0aGUgRW5nbGlzaCBjb2xsYXRpb24gcnVsZXMgYW5kIGFkZCB0aGUgYWRkaXRpb25hbCBydWxlcyB0byB0aGUgdGFibGUuCiAqIEZvciBleGFtcGxlOgogKiA8cHJlPgogKiAuICAgICBVRXJyb3JDb2RlIHN0YXR1cyA9IFVfWkVST19FUlJPUjsKICogLiAgICAgVW5pY29kZVN0cmluZyBydWxlcyhERUZBVUxUUlVMRVMpOwogKiAuICAgICBydWxlcyArPSAiJiBDICZsdDsgY2gsIGNILCBDaCwgQ0giOwogKiAuICAgICBSdWxlQmFzZWRDb2xsYXRvciAqbXlTcGFuaXNoID0gbmV3IFJ1bGVCYXNlZENvbGxhdG9yKHJ1bGVzLCBzdGF0dXMpOwogKiA8L3ByZT4KICogPHA+SW4gb3JkZXIgdG8gc29ydCBzeW1ib2xzIGluIHRoZSBzaW1pbGlhciBvcmRlciBvZiBzb3J0aW5nIHRoZWlyCiAqIGFscGhhYmV0aWMgZXF1aXZhbGVudHMsIHlvdSBjYW4gZG8gdGhlIGZvbGxvd2luZywKICogPHByZT4KICogLiAgICAgVUVycm9yQ29kZSBzdGF0dXMgPSBVX1pFUk9fRVJST1I7CiAqIC4gICAgIFVuaWNvZGVTdHJpbmcgcnVsZXMoREVGQVVMVFJVTEVTKTsKICogLiAgICAgcnVsZXMgKz0gIiYgUXVlc3Rpb24tbWFyayA7ICc/JyAmIEFtcGVyc2FuZCA7ICcmJyAmIERvbGxhci1zaWduIDsgJyQnICI7CiAqIC4gICAgIFJ1bGVCYXNlZENvbGxhdG9yICpteVRhYmxlID0gbmV3IFJ1bGVCYXNlZENvbGxhdG9yKHJ1bGVzLCBzdGF0dXMpOwogKiA8L3ByZT4KICogPHA+QW5vdGhlciB3YXkgb2YgY3JlYXRpbmcgdGhlIHRhYmxlLWJhc2VkIGNvbGxhdGlvbiBvYmplY3QsIG15U2ltcGxlLAogKiBpczoKICogPHByZT4KICogLiAgICAgVUVycm9yQ29kZSBzdGF0dXMgPSBVX1pFUk9fRVJST1I7CiAqIC4gICAgIFJ1bGVCYXNlZENvbGxhdG9yICpteVNpbXBsZSA9IG5ldwogKiAuICAgICAgICAgICBSdWxlQmFzZWRDb2xsYXRvcigiICZsdDsgYSAmbHQ7IGIgJiBiICZsdDsgYyAmIGMgJmx0OyBkIiwgc3RhdHVzKTsKICogPC9wcmU+CiAqIE9yLAogKiA8cHJlPgogKiAuICAgICBVRXJyb3JDb2RlIHN0YXR1cyA9IFVfWkVST19FUlJPUjsKICogLiAgICAgUnVsZUJhc2VkQ29sbGF0b3IgKm15U2ltcGxlID0gbmV3CiAqIC4gICAgICAgICAgIFJ1bGVCYXNlZENvbGxhdG9yKCIgJmx0OyBhICZsdDsgYiAmbHQ7IGQgJiBiICZsdDsgYyIsIHN0YXR1cyk7CiAqIDwvcHJlPgogKiBCZWNhdXNlICIgJmx0OyBhICZsdDsgYiAmbHQ7IGMgJmx0OyBkIiBpcyB0aGUgc2FtZSBhcyAiYSAmbHQ7IGIgJmx0OyBkICYgYiAmbHQ7IGMiIG9yCiAqICImbHQ7IGEgJmx0OyBiICYgYiAmbHQ7IGMgJiBjICZsdDsgZCIuCiAqCiAqIDxwPlRvIGNvbWJpbmUgY29sbGF0aW9ucyBmcm9tIHR3byBsb2NhbGVzLCAod2l0aG91dCBlcnJvciBoYW5kbGluZyBmb3IgY2xhcml0eSkKICogPHByZT4KICogLiAgICAvLyBDcmVhdGUgYW4gZW5fVVMgQ29sbGF0b3Igb2JqZWN0CiAqIC4gICAgTG9jYWxlIGxvY2FsZV9lbl9VUygiZW4iLCAiVVMiLCAiIik7CiAqIC4gICAgUnVsZUJhc2VkQ29sbGF0b3IqIGVuX1VTQ29sbGF0b3IgPSAoUnVsZUJhc2VkQ29sbGF0b3IqKQogKiAuICAgICAgICBDb2xsYXRvcjo6Y3JlYXRlSW5zdGFuY2UoIGxvY2FsZV9lbl9VUywgc3VjY2VzcyApOwogKiAuCiAqIC4gICAgLy8gQ3JlYXRlIGEgZGFfREsgQ29sbGF0b3Igb2JqZWN0CiAqIC4gICAgTG9jYWxlIGxvY2FsZV9kYV9ESygiZGEiLCAiREsiLCAiIik7CiAqIC4gICAgUnVsZUJhc2VkQ29sbGF0b3IqIGRhX0RLQ29sbGF0b3IgPSAoUnVsZUJhc2VkQ29sbGF0b3IqKQogKiAuICAgICAgICBDb2xsYXRvcjo6Y3JlYXRlSW5zdGFuY2UoIGxvY2FsZV9kYV9ESywgc3VjY2VzcyApOwogKiAuCiAqIC4gICAgLy8gQ29tYmluZSB0aGUgdHdvCiAqIC4gICAgLy8gRmlyc3QsIGdldCB0aGUgY29sbGF0aW9uIHJ1bGVzIGZyb20gZW5fVVNDb2xsYXRvcgogKiAuICAgIFVuaWNvZGVTdHJpbmcgcnVsZXMgPSBlbl9VU0NvbGxhdG9yLT5nZXRSdWxlcygpOwogKiAuICAgIC8vIFNlY29uZCwgZ2V0IHRoZSBjb2xsYXRpb24gcnVsZXMgZnJvbSBkYV9ES0NvbGxhdG9yCiAqIC4gICAgcnVsZXMgKz0gZGFfREtDb2xsYXRvci0+Z2V0UnVsZXMoKTsKICogLiAgICBSdWxlQmFzZWRDb2xsYXRvciogbmV3Q29sbGF0b3IgPSBuZXcgUnVsZUJhc2VkQ29sbGF0b3IoIHJ1bGVzLCBzdWNjZXNzICk7CiAqIC4gICAgLy8gbmV3Q29sbGF0b3IgaGFzIHRoZSBjb21iaW5lZCBydWxlcwogKiA8L3ByZT4KICogPHA+QW5vdGhlciBtb3JlIGludGVyZXN0aW5nIGV4YW1wbGUgd291bGQgYmUgdG8gbWFrZSBjaGFuZ2VzIG9uIGFuIGV4aXN0aW5nCiAqIHRhYmxlIHRvIGNyZWF0ZSBhIG5ldyBjb2xsYXRpb24gb2JqZWN0LiAgRm9yIGV4YW1wbGUsIGFkZAogKiAiJiBDICZsdDsgY2gsIGNILCBDaCwgQ0giIHRvIHRoZSBlbl9VU0NvbGxhdGlvbiBvYmplY3QgdG8gY3JlYXRlIHlvdXIgb3duCiAqIEVuZ2xpc2ggY29sbGF0aW9uIG9iamVjdCwKICogPHByZT4KICogLiAgICAvLyBDcmVhdGUgYSBuZXcgQ29sbGF0b3Igb2JqZWN0IHdpdGggYWRkaXRpb25hbCBydWxlcwogKiAuICAgIHJ1bGVzID0gZW5fVVNDb2xsYXRvci0+Z2V0UnVsZXMoKTsKICogLiAgICBydWxlcyArPSAiJiBDIDwgY2gsIGNILCBDaCwgQ0giOwogKiAuICAgIFJ1bGVCYXNlZENvbGxhdG9yKiBteUNvbGxhdG9yID0gbmV3IFJ1bGVCYXNlZENvbGxhdG9yKCBydWxlcywgc3VjY2VzcyApOwogKiAuICAgIC8vIG15Q29sbGF0b3IgY29udGFpbnMgdGhlIG5ldyBydWxlcwogKiA8L3ByZT4KICoKICogPHA+VGhlIGZvbGxvd2luZyBleGFtcGxlIGRlbW9uc3RyYXRlcyBob3cgdG8gY2hhbmdlIHRoZSBvcmRlciBvZgogKiBub24tc3BhY2luZyBhY2NlbnRzLAogKiA8cHJlPgogKiAuICAgICBVQ2hhciBjb250ZW50c1tdID0gewogKiAuICAgICAgICAgJz0nLCAweDAzMDEsICc7JywgMHgwMzAwLCAnOycsIDB4MDMwMiwKICogLiAgICAgICAgICc7JywgMHgwMzA4LCAnOycsIDB4MDMyNywgJywnLCAweDAzMDMsICAgIC8vIG1haW4gYWNjZW50cwogKiAuICAgICAgICAgJzsnLCAweDAzMDQsICc7JywgMHgwMzA1LCAnOycsIDB4MDMwNiwgICAgLy8gbWFpbiBhY2NlbnRzCiAqIC4gICAgICAgICAnOycsIDB4MDMwNywgJzsnLCAweDAzMDksICc7JywgMHgwMzBBLCAgICAvLyBtYWluIGFjY2VudHMKICogLiAgICAgICAgICc7JywgMHgwMzBCLCAnOycsIDB4MDMwQywgJzsnLCAweDAzMEQsICAgIC8vIG1haW4gYWNjZW50cwogKiAuICAgICAgICAgJzsnLCAweDAzMEUsICc7JywgMHgwMzBGLCAnOycsIDB4MDMxMCwgICAgLy8gbWFpbiBhY2NlbnRzCiAqIC4gICAgICAgICAnOycsIDB4MDMxMSwgJzsnLCAweDAzMTIsICAgICAgICAgICAgICAgICAvLyBtYWluIGFjY2VudHMKICogLiAgICAgICAgICcmbHQ7JywgJ2EnLCAnLCcsICdBJywgJzsnLCAnYScsICdlJywgJywnLCAnQScsICdFJywKICogLiAgICAgICAgICc7JywgMHgwMGU2LCAnLCcsIDB4MDBjNiwgJyZsdDsnLCAnYicsICcsJywgJ0InLAogKiAuICAgICAgICAgJyZsdDsnLCAnYycsICcsJywgJ0MnLCAnJmx0OycsICdlJywgJywnLCAnRScsICcmJywgCiAqIC4gICAgICAgICAnQycsICcmbHQ7JywgJ2QnLCAnLCcsICdEJywgMCB9OwogKiAuICAgICBVbmljb2RlU3RyaW5nIG9sZFJ1bGVzKGNvbnRlbnRzKTsKICogLiAgICAgVUVycm9yQ29kZSBzdGF0dXMgPSBVX1pFUk9fRVJST1I7CiAqIC4gICAgIC8vIGNoYW5nZSB0aGUgb3JkZXIgb2YgYWNjZW50IGNoYXJhY3RlcnMKICogLiAgICAgVUNoYXIgYWRkT25bXSA9IHsgJyYnLCAnLCcsIDB4MDMwMCwgJzsnLCAweDAzMDgsICc7JywgMHgwMzAyLCAwIH07CiAqIC4gICAgIG9sZFJ1bGVzICs9IGFkZE9uOwogKiAuICAgICBSdWxlQmFzZWRDb2xsYXRvciAqbXlDb2xsYXRpb24gPSBuZXcgUnVsZUJhc2VkQ29sbGF0b3Iob2xkUnVsZXMsIHN0YXR1cyk7CiAqIDwvcHJlPgogKgogKiA8cD4gVGhlIGxhc3QgZXhhbXBsZSBzaG93cyBob3cgdG8gcHV0IG5ldyBwcmltYXJ5IG9yZGVyaW5nIGluIGJlZm9yZSB0aGUKICogZGVmYXVsdCBzZXR0aW5nLiBGb3IgZXhhbXBsZSwgaW4gSmFwYW5lc2UgY29sbGF0aW9uLCB5b3UgY2FuIGVpdGhlciBzb3J0CiAqIEVuZ2xpc2ggY2hhcmFjdGVycyBiZWZvcmUgb3IgYWZ0ZXIgSmFwYW5lc2UgY2hhcmFjdGVycywKICogPHByZT4KICogLiAgICAgVUVycm9yQ29kZSBzdGF0dXMgPSBVX1pFUk9fRVJST1I7CiAqIC4gICAgIC8vIGdldCBlbl9VUyBjb2xsYXRpb24gcnVsZXMKICogLiAgICAgUnVsZUJhc2VkQ29sbGF0b3IqIGVuX1VTQ29sbGF0aW9uID0gCiAqIC4gICAgICAgICAoUnVsZUJhc2VkQ29sbGF0b3IqKSBDb2xsYXRvcjo6Y3JlYXRlSW5zdGFuY2UoTG9jYWxlOjpVUywgc3RhdHVzKTsKICogLiAgICAgLy8gQWx3YXlzIGNoZWNrIHRoZSBlcnJvciBjb2RlIGFmdGVyIGVhY2ggY2FsbC4KICogLiAgICAgaWYgKFVfRkFJTFVSRShzdGF0dXMpKSByZXR1cm47CiAqIC4gICAgIC8vIGFkZCBhIGZldyBKYXBhbmVzZSBjaGFyYWN0ZXIgdG8gc29ydCBiZWZvcmUgRW5nbGlzaCBjaGFyYWN0ZXJzCiAqIC4gICAgIC8vIHN1cHBvc2UgdGhlIGxhc3QgY2hhcmFjdGVyIGJlZm9yZSB0aGUgZmlyc3QgYmFzZSBsZXR0ZXIgJ2EnIGluCiAqIC4gICAgIC8vIHRoZSBFbmdsaXNoIGNvbGxhdGlvbiBydWxlIGlzIDB4MjIxMgogKiAuICAgICBVQ2hhciBqYVN0cmluZ1tdID0geyAnJicsIDB4MjIxMiwgJyZsdDsnLCAweDMwNDEsICcsJywgMHgzMDQyLCAnJmx0OycsIDB4MzA0MywgJywnLCAweDMwNDQsIDAgfTsKICogLiAgICAgVW5pY29kZVN0cmluZyBydWxlcyggZW5fVVNDb2xsYXRpb24tPmdldFJ1bGVzKCkgKTsKICogLiAgICAgcnVsZXMgKz0gamFTdHJpbmc7CiAqIC4gICAgIFJ1bGVCYXNlZENvbGxhdG9yICpteUphcGFuZXNlQ29sbGF0aW9uID0gbmV3IFJ1bGVCYXNlZENvbGxhdG9yKHJ1bGVzLCBzdGF0dXMpOwogKiA8L3ByZT4KICogPHA+PHN0cm9uZz5OT1RFPC9zdHJvbmc+OiBUeXBpY2FsbHksIGEgY29sbGF0aW9uIG9iamVjdCBpcyBjcmVhdGVkIHdpdGgKICogQ29sbGF0b3I6OmNyZWF0ZUluc3RhbmNlKCkuCiAqIDxwPgogKiA8c3Ryb25nPk5vdGU6PC9zdHJvbmc+IDxjb2RlPlJ1bGVCYXNlZENvbGxhdG9yPC9jb2RlPnMgd2l0aCBkaWZmZXJlbnQgTG9jYWxlLAogKiBDb2xsYXRpb25TdHJlbmd0aCBhbmQgRGVjb21wb3NpdGlvbiBtb2RlIHNldHRpbmdzIHdpbGwgcmV0dXJuIGRpZmZlcmVudAogKiBzb3J0IG9yZGVycyBmb3IgdGhlIHNhbWUgc2V0IG9mIHN0cmluZ3MuIExvY2FsZXMgaGF2ZSBzcGVjaWZpYyAKICogY29sbGF0aW9uIHJ1bGVzLCBhbmQgdGhlIHdheSBpbiB3aGljaCBzZWNvbmRhcnkgYW5kIHRlcnRpYXJ5IGRpZmZlcmVuY2VzIAogKiBhcmUgdGFrZW4gaW50byBhY2NvdW50LCBmb3IgZXhhbXBsZSwgd2lsbCByZXN1bHQgaW4gYSBkaWZmZXJlbnQgc29ydGluZyBvcmRlcgogKiBmb3Igc2FtZSBzdHJpbmdzLgogKiA8cD4KICogQHNlZSAgICAgICAgQ29sbGF0b3IKICogQHZlcnNpb24gICAgMS4yNyA0LzgvOTcKICogQGF1dGhvciAgICAgSGVsZW5hIFNoaWgKICovCmNsYXNzIFVfSTE4Tl9BUEkgUnVsZUJhc2VkQ29sbGF0b3IgOiBwdWJsaWMgQ29sbGF0b3IgCnsKcHVibGljOiAKCiAgLy8gY29uc3RydWN0b3IvZGVzdHJ1Y3RvcgogIC8qKgogICAqIFJ1bGVCYXNlZENvbGxhdG9yIGNvbnN0cnVjdG9yLiAgVGhpcyB0YWtlcyB0aGUgdGFibGUgcnVsZXMgYW5kIGJ1aWxkcwogICAqIGEgY29sbGF0aW9uIHRhYmxlIG91dCBvZiB0aGVtLiAgUGxlYXNlIHNlZSBSdWxlQmFzZWRDb2xsYXRvciBjbGFzcwogICAqIGRlc2NyaXB0aW9uIGZvciBtb3JlIGRldGFpbHMgb24gdGhlIGNvbGxhdGlvbiBydWxlIHN5bnRheC4KICAgKiBAc2VlIExvY2FsZQogICAqIEBwYXJhbSBydWxlcyB0aGUgY29sbGF0aW9uIHJ1bGVzIHRvIGJ1aWxkIHRoZSBjb2xsYXRpb24gdGFibGUgZnJvbS4KICAgKiBAc3RhYmxlCiAgICovCglSdWxlQmFzZWRDb2xsYXRvcihjb25zdCBVbmljb2RlU3RyaW5nJiBydWxlcywKCQkJVUVycm9yQ29kZSYgc3RhdHVzKTsKCiAgUnVsZUJhc2VkQ29sbGF0b3IoICBjb25zdCAgIFVuaWNvZGVTdHJpbmcmICBydWxlcywKICAgICAgICAgICAgICBFQ29sbGF0aW9uU3RyZW5ndGggY29sbGF0aW9uU3RyZW5ndGgsCiAgICAgICAgICAgICAgVUVycm9yQ29kZSYgICAgICBzdGF0dXMpOwoKICBSdWxlQmFzZWRDb2xsYXRvciggIGNvbnN0ICAgVW5pY29kZVN0cmluZyYgIHJ1bGVzLAogICAgICAgICAgICAgIE5vcm1hbGl6ZXI6OkVNb2RlIGRlY29tcG9zaXRpb25Nb2RlLAogICAgICAgICAgICAgIFVFcnJvckNvZGUmICAgICAgc3RhdHVzKTsKCiAgUnVsZUJhc2VkQ29sbGF0b3IoICBjb25zdCAgIFVuaWNvZGVTdHJpbmcmICBydWxlcywKICAgICAgICAgICAgICBFQ29sbGF0aW9uU3RyZW5ndGggY29sbGF0aW9uU3RyZW5ndGgsCiAgICAgICAgICAgICAgTm9ybWFsaXplcjo6RU1vZGUgIGRlY29tcG9zaXRpb25Nb2RlLAogICAgICAgICAgICAgIFVFcnJvckNvZGUmICAgICAgc3RhdHVzKTsKCiAgLyoqIERlc3RydWN0b3IuCiAgICogQHN0YWJsZQogICAqLwoJdmlydHVhbCB+UnVsZUJhc2VkQ29sbGF0b3IoKTsKCgogIC8qKiBDb3B5IGNvbnN0cnVjdG9yLgogICAqIEBzdGFibGUKICAgKi8KCVJ1bGVCYXNlZENvbGxhdG9yKGNvbnN0IFJ1bGVCYXNlZENvbGxhdG9yJiBvdGhlcik7CgogIC8qKgogICAqIEFzc2lnbm1lbnQgb3BlcmF0b3IuCiAgICogQHN0YWJsZQogICAqLwoJUnVsZUJhc2VkQ29sbGF0b3ImIG9wZXJhdG9yPShjb25zdCBSdWxlQmFzZWRDb2xsYXRvciYgb3RoZXIpOwogICAgCiAgLyoqCiAgICogUmV0dXJucyB0cnVlIGlmICJvdGhlciIgaXMgdGhlIHNhbWUgYXMgInRoaXMiLgogICAqIEBzdGFibGUKICAgKi8KICB2aXJ0dWFsIGJvb2xfdCAgICAgICAgICAgICAgICAgIG9wZXJhdG9yPT0oY29uc3QgQ29sbGF0b3ImIG90aGVyKSBjb25zdDsKCiAgLyoqCiAgICogUmV0dXJucyB0cnVlIGlmICJvdGhlciIgaXMgbm90IHRoZSBzYW1lIGFzICJ0aGlzIi4KICAgKiBAc3RhYmxlCiAgICovCiAgdmlydHVhbCBib29sX3QgICAgICAgICAgICAgICAgICBvcGVyYXRvciE9KGNvbnN0IENvbGxhdG9yJiBvdGhlcikgY29uc3Q7CgogIC8qKgogICAqIE1ha2VzIGEgZGVlcCBjb3B5IG9mIHRoZSBvYmplY3QuICBUaGUgY2FsbGVyIG93bnMgdGhlIHJldHVybmVkIG9iamVjdC4KICAgKiBAcmV0dXJuIHRoZSBjbG9uZWQgb2JqZWN0LgogICAqIEBzdGFibGUKICAgKi8KICB2aXJ0dWFsIENvbGxhdG9yKiAgICAgICAgICAgICAgIGNsb25lKHZvaWQpIGNvbnN0OwoKICAvKioKICAgKiBDcmVhdGVzIGEgY29sbGF0aW9uIGVsZW1lbnQgaXRlcmF0b3IgZm9yIHRoZSBzb3VyY2Ugc3RyaW5nLiAgVGhlIAogICAqIGNhbGxlciBvZiB0aGlzIG1ldGhvZCBpcyByZXNwb25zaWJsZSBmb3IgdGhlIG1lbW9yeSBtYW5hZ2VtZW50IG9mIAogICAqIHRoZSByZXR1cm4gcG9pbnRlci4KICAgKiBAcGFyYW0gc291cmNlIHRoZSBzdHJpbmcgb3ZlciB3aGljaCB0aGUgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yIHdpbGwgaXRlcmF0ZS4KICAgKiBAcmV0dXJuIHRoZSBjb2xsYXRpb24gZWxlbWVudCBpdGVyYXRvciBvZiB0aGUgc291cmNlIHN0cmluZyB1c2luZyB0aGlzIGFzCiAgICogdGhlIGJhc2VkIGNvbGxhdG9yLgogICAqIEBzdGFibGUgCiAgICovCgl2aXJ0dWFsIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciogY3JlYXRlQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yKGNvbnN0IFVuaWNvZGVTdHJpbmcmIHNvdXJjZSkgY29uc3Q7CgogIC8qKgogICAqIENyZWF0ZXMgYSBjb2xsYXRpb24gZWxlbWVudCBpdGVyYXRvciBmb3IgdGhlIHNvdXJjZS4gIFRoZSAKICAgKiBjYWxsZXIgb2YgdGhpcyBtZXRob2QgaXMgcmVzcG9uc2libGUgZm9yIHRoZSBtZW1vcnkgbWFuYWdlbWVudCBvZiAKICAgKiB0aGUgcmV0dXJuZWQgcG9pbnRlci4KICAgKiBAcGFyYW0gc291cmNlIHRoZSBDaGFyYWN0ZXJJdGVyYXRvciB3aGljaCBwcm9kdWNlcyB0aGUgY2hhcmFjdGVycyBvdmVyIHdoaWNoIHRoZQogICAqIENvbGxhdGlvbkVsZW1lbnRJdGdlcmF0b3Igd2lsbCBpdGVyYXRlLgogICAqIEByZXR1cm4gdGhlIGNvbGxhdGlvbiBlbGVtZW50IGl0ZXJhdG9yIG9mIHRoZSBzb3VyY2UgdXNpbmcgdGhpcyBhcwogICAqIHRoZSBiYXNlZCBjb2xsYXRvci4KICAgKiBAc3RhYmxlCiAgICovCiAgdmlydHVhbCBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IqICAgICAgIGNyZWF0ZUNvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcihjb25zdCBDaGFyYWN0ZXJJdGVyYXRvciYgc291cmNlKSBjb25zdDsKCiAgLyoqCiAgICogQ29tcGFyZXMgYSByYW5nZSBvZiBjaGFyYWN0ZXIgZGF0YSBzdG9yZWQgaW4gdHdvIGRpZmZlcmVudCBzdHJpbmdzCiAgICogYmFzZWQgb24gdGhlIGNvbGxhdGlvbiBydWxlcy4gIFJldHVybnMKICAgKiBpbmZvcm1hdGlvbiBhYm91dCB3aGV0aGVyIGEgc3RyaW5nIGlzIGxlc3MgdGhhbiwgZ3JlYXRlciB0aGFuIG9yCiAgICogZXF1YWwgdG8gYW5vdGhlciBzdHJpbmcgaW4gYSBsYW5ndWFnZS4KICAgKiBUaGlzIGNhbiBiZSBvdmVycmlkZW4gaW4gYSBzdWJjbGFzcy4KICAgKiBAcGFyYW0gc291cmNlIHRoZSBzb3VyY2Ugc3RyaW5nLgogICAqIEBwYXJhbSB0YXJnZXQgdGhlIHRhcmdldCBzdHJpbmcgdG8gYmUgY29tcGFyZWQgd2l0aCB0aGUgc291cmNlIHN0aXJuZy4KICAgKiBAcmV0dXJuIHRoZSBjb21wYXJpc29uIHJlc3VsdC4gIEdSRUFURVIgaWYgdGhlIHNvdXJjZSBzdHJpbmcgaXMgZ3JlYXRlcgogICAqIHRoYW4gdGhlIHRhcmdldCBzdHJpbmcsIExFU1MgaWYgdGhlIHNvdXJjZSBpcyBsZXNzIHRoYW4gdGhlIHRhcmdldC4gIE90aGVyd2lzZSwKICAgKiByZXR1cm5zIEVRVUFMLgogICAqIEBzdGFibGUKICAgKi8KICB2aXJ0dWFsICAgICBFQ29tcGFyaXNvblJlc3VsdCAgIGNvbXBhcmUoICAgIGNvbnN0ICAgVW5pY29kZVN0cmluZyYgIHNvdXJjZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgICBVbmljb2RlU3RyaW5nJiAgdGFyZ2V0KSBjb25zdDsKICAgICAgICAKICAgICAgICAKICAvKioKICAgKiBDb21wYXJlcyBhIHJhbmdlIG9mIGNoYXJhY3RlciBkYXRhIHN0b3JlZCBpbiB0d28gZGlmZmVyZW50IHN0cmluZ3MKICAgKiBiYXNlZCBvbiB0aGUgY29sbGF0aW9uIHJ1bGVzIHVwIHRvIHRoZSBzcGVjaWZpZWQgbGVuZ3RoLiAgUmV0dXJucwogICAqIGluZm9ybWF0aW9uIGFib3V0IHdoZXRoZXIgYSBzdHJpbmcgaXMgbGVzcyB0aGFuLCBncmVhdGVyIHRoYW4gb3IKICAgKiBlcXVhbCB0byBhbm90aGVyIHN0cmluZyBpbiBhIGxhbmd1YWdlLgogICAqIFRoaXMgY2FuIGJlIG92ZXJyaWRlbiBpbiBhIHN1YmNsYXNzLgogICAqIEBwYXJhbSBzb3VyY2UgdGhlIHNvdXJjZSBzdHJpbmcuCiAgICogQHBhcmFtIHRhcmdldCB0aGUgdGFyZ2V0IHN0cmluZyB0byBiZSBjb21wYXJlZCB3aXRoIHRoZSBzb3VyY2Ugc3RyaW5nLgogICAqIEBwYXJhbSBsZW5ndGggY29tcGFyZXMgdXAgdG8gdGhlIHNwZWNpZmllZCBsZW5ndGgKICAgKiBAcmV0dXJuIHRoZSBjb21wYXJpc29uIHJlc3VsdC4gIEdSRUFURVIgaWYgdGhlIHNvdXJjZSBzdHJpbmcgaXMgZ3JlYXRlcgogICAqIHRoYW4gdGhlIHRhcmdldCBzdHJpbmcsIExFU1MgaWYgdGhlIHNvdXJjZSBpcyBsZXNzIHRoYW4gdGhlIHRhcmdldC4gIE90aGVyd2lzZSwKICAgKiByZXR1cm5zIEVRVUFMLgogICAqIEBkcmFmdAogICAqLyAKICB2aXJ0dWFsICAgICBFQ29tcGFyaXNvblJlc3VsdCAgIGNvbXBhcmUoICAgIGNvbnN0ICAgVW5pY29kZVN0cmluZyYgIHNvdXJjZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgICBVbmljb2RlU3RyaW5nJiAgdGFyZ2V0LAogICAgICAgICAgICAgICAgICAgICAgICAgIGludDMyX3QgbGVuZ3RoKSBjb25zdDsKCiAgLyoqCiAgICogVGhlIGNvbXBhcmlzb24gZnVuY3Rpb24gY29tcGFyZXMgdGhlIGNoYXJhY3RlciBkYXRhIHN0b3JlZCBpbiB0d28KICAgKiBkaWZmZXJlbnQgc3RyaW5nIGFycmF5cy4gIFJldHVybnMgaW5mb3JtYXRpb24gYWJvdXQgd2hldGhlciBhIHN0cmluZwogICAqIGFycmF5IGlzIGxlc3MgdGhhbiwgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIGFub3RoZXIgc3RyaW5nIGFycmF5LgogICAqIDxwPkV4YW1wbGUgb2YgdXNlOgogICAqIDxwcmU+CiAgICogLiAgICAgICBVRXJyb3JDb2RlIHN0YXR1cyA9IFVfWkVST19FUlJPUjsKICAgKiAuICAgICAgIENvbGxhdG9yICpteUNvbGxhdGlvbiA9IENvbGxhdG9yOjpjcmVhdGVJbnN0YW5jZShMb2NhbGU6OlVTLCBzdGF0dXMpOwogICAqIC4gICAgICAgaWYgKFVfRkFJTFVSRShzdGF0dXMpKSByZXR1cm47CiAgICogLiAgICAgICBteUNvbGxhdGlvbi0+c2V0U3RyZW5ndGgoQ29sbGF0b3I6OlBSSU1BUlkpOwogICAqIC4gICAgICAgLy8gcmVzdWx0IHdvdWxkIGJlIENvbGxhdG9yOjpFUVVBTCAoImFiYyIgPT0gIkFCQyIpCiAgICogLiAgICAgICAvLyAobm8gcHJpbWFyeSBkaWZmZXJlbmNlIGJldHdlZW4gImFiYyIgYW5kICJBQkMiKQogICAqIC4gICAgICAgQ29sbGF0b3I6OkVDb21wYXJpc29uUmVzdWx0IHJlc3VsdCA9IG15Q29sbGF0aW9uLT5jb21wYXJlKEwiYWJjIiwgMywgTCJBQkMiLCAzKTsKICAgKiAuICAgICAgIG15Q29sbGF0aW9uLT5zZXRTdHJlbmd0aChDb2xsYXRvcjo6VEVSVElBUlkpOwogICAqIC4gICAgICAgLy8gcmVzdWx0IHdvdWxkIGJlIENvbGxhdG9yOjpMRVNTIChhYmMiICZsdDsmbHQ7Jmx0OyAiQUJDIikKICAgKiAuICAgICAgIC8vICh3aXRoIHRlcnRpYXJ5IGRpZmZlcmVuY2UgYmV0d2VlbiAiYWJjIiBhbmQgIkFCQyIpCiAgICogLiAgICAgICBDb2xsYXRvcjo6RUNvbXBhcmlzb25SZXN1bHQgcmVzdWx0ID0gbXlDb2xsYXRpb24tPmNvbXBhcmUoTCJhYmMiLCAzLCBMIkFCQyIsIDMpOwogICAqIDwvcHJlPgogICAqIEBwYXJhbSBzb3VyY2UgdGhlIHNvdXJjZSBzdHJpbmcgYXJyYXkgdG8gYmUgY29tcGFyZWQgd2l0aC4KICAgKiBAcGFyYW0gc291cmNlTGVuZ3RoIHRoZSBsZW5ndGggb2YgdGhlIHNvdXJjZSBzdHJpbmcgYXJyYXkuICBJZiB0aGlzIHZhbHVlCiAgICogICAgICAgIGlzIGVxdWFsIHRvIC0xLCB0aGUgc3RyaW5nIGFycmF5IGlzIG51bGwtdGVybWluYXRlZC4KICAgKiBAcGFyYW0gdGFyZ2V0IHRoZSBzdHJpbmcgdGhhdCBpcyB0byBiZSBjb21wYXJlZCB3aXRoIHRoZSBzb3VyY2Ugc3RyaW5nLgogICAqIEBwYXJhbSB0YXJnZXRMZW5ndGggdGhlIGxlbmd0aCBvZiB0aGUgdGFyZ2V0IHN0cmluZyBhcnJheS4gIElmIHRoaXMgdmFsdWUKICAgKiAgICAgICAgaXMgZXF1YWwgdG8gLTEsIHRoZSBzdHJpbmcgYXJyYXkgaXMgbnVsbC10ZXJtaW5hdGVkLgogICAqIEByZXR1cm4gUmV0dXJucyBhIGJ5dGUgdmFsdWUuIEdSRUFURVIgaWYgc291cmNlIGlzIGdyZWF0ZXIKICAgKiB0aGFuIHRhcmdldDsgRVFVQUwgaWYgc291cmNlIGlzIGVxdWFsIHRvIHRhcmdldDsgTEVTUyBpZiBzb3VyY2UgaXMgbGVzcwogICAqIHRoYW4gdGFyZ2V0CiAgICogQHN0YWJsZQogICAqKi8KICB2aXJ0dWFsIEVDb21wYXJpc29uUmVzdWx0ICAgY29tcGFyZSggICAgY29uc3QgICBVQ2hhciogc291cmNlLCAKICAgICAgICAgICAgICAgICAgICAgIGludDMyX3Qgc291cmNlTGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgY29uc3QgICBVQ2hhciogIHRhcmdldCwKICAgICAgICAgICAgICAgICAgICAgIGludDMyX3QgdGFyZ2V0TGVuZ3RoKSBjb25zdCA7CgogIC8qKiBUcmFuc2Zvcm1zIGEgc3BlY2lmaWVkIHJlZ2lvbiBvZiB0aGUgc3RyaW5nIGludG8gYSBzZXJpZXMgb2YgY2hhcmFjdGVycwogICAgICogdGhhdCBjYW4gYmUgY29tcGFyZWQgd2l0aCBDb2xsYXRpb25LZXkuY29tcGFyZS4gVXNlIGEgQ29sbGF0aW9uS2V5IHdoZW4KICAgICAqIHlvdSBuZWVkIHRvIGRvIHJlcGVhdGVkIGNvbXBhcmlzaW9ucyBvbiB0aGUgc2FtZSBzdHJpbmcuIEZvciBhIHNpbmdsZSBjb21wYXJpc29uCiAgICAgKiB0aGUgY29tcGFyZSBtZXRob2Qgd2lsbCBiZSBmYXN0ZXIuCiAgICAgKiBAcGFyYW0gc291cmNlIHRoZSBzb3VyY2Ugc3RyaW5nLgogICAgICogQHBhcmFtIGtleSB0aGUgdHJhbnNmb3JtZWQga2V5IG9mIHRoZSBzb3VyY2Ugc3RyaW5nLgogICAgICogQHBhcmFtIHN0YXR1cyB0aGUgZXJyb3IgY29kZSBzdGF0dXMuCiAgICAgKiBAcmV0dXJuIHRoZSB0cmFuc2Zvcm1lZCBrZXkuCiAgICAgKiBAc2VlIENvbGxhdGlvbktleQogICAgICogQGRyYWZ0CiAgICAgKi8KICB2aXJ0dWFsICAgICBDb2xsYXRpb25LZXkmICAgICAgIGdldENvbGxhdGlvbktleSggICAgY29uc3QgICBVbmljb2RlU3RyaW5nJiAgc291cmNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb2xsYXRpb25LZXkmICAga2V5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiAgc3RhdHVzKSBjb25zdDsKCiAgLyoqIFRyYW5zZm9ybXMgYSBzcGVjaWZpZWQgcmVnaW9uIG9mIHRoZSBzdHJpbmcgaW50byBhIHNlcmllcyBvZiBjaGFyYWN0ZXJzCiAgICAgKiB0aGF0IGNhbiBiZSBjb21wYXJlZCB3aXRoIENvbGxhdGlvbktleS5jb21wYXJlLiBVc2UgYSBDb2xsYXRpb25LZXkgd2hlbgogICAgICogeW91IG5lZWQgdG8gZG8gcmVwZWF0ZWQgY29tcGFyaXNpb25zIG9uIHRoZSBzYW1lIHN0cmluZy4gRm9yIGEgc2luZ2xlIGNvbXBhcmlzb24KICAgICAqIHRoZSBjb21wYXJlIG1ldGhvZCB3aWxsIGJlIGZhc3Rlci4KICAgICAqIEBwYXJhbSBzb3VyY2UgdGhlIHNvdXJjZSBzdHJpbmcuCiAgICAgKiBAcGFyYW0ga2V5IHRoZSB0cmFuc2Zvcm1lZCBrZXkgb2YgdGhlIHNvdXJjZSBzdHJpbmcuCiAgICAgKiBAcGFyYW0gc3RhdHVzIHRoZSBlcnJvciBjb2RlIHN0YXR1cy4KICAgICAqIEByZXR1cm4gdGhlIHRyYW5zZm9ybWVkIGtleS4KICAgICAqIEBzZWUgQ29sbGF0aW9uS2V5CiAgICAgKiBAZHJhZnQKICAgICAqLwogIHZpcnR1YWwgQ29sbGF0aW9uS2V5JiAgICAgICBnZXRDb2xsYXRpb25LZXkoY29uc3QgVUNoYXIgKnNvdXJjZSwKCQkJCQkgICAgICBpbnQzMl90IHNvdXJjZUxlbmd0aCwKCQkJCQkgICAgICBDb2xsYXRpb25LZXkmICAgICAgIGtleSwKCQkJCQkgICAgICBVRXJyb3JDb2RlJiAgICAgIHN0YXR1cykgY29uc3Q7CgogIC8qKgogICAqIEdlbmVyYXRlcyB0aGUgaGFzaCBjb2RlIGZvciB0aGUgcnVsZS1iYXNlZCBjb2xsYXRpb24gb2JqZWN0LgogICAqIEByZXR1cm4gdGhlIGhhc2ggY29kZS4KICAgKiBAc3RhYmxlCiAgICovCiAgdmlydHVhbCAgICAgaW50MzJfdCAgICAgICAgICAgICBoYXNoQ29kZSh2b2lkKSBjb25zdDsKCiAgLyoqCiAgICogR2V0cyB0aGUgdGFibGUtYmFzZWQgcnVsZXMgZm9yIHRoZSBjb2xsYXRpb24gb2JqZWN0LgogICAqIEByZXR1cm4gcmV0dXJucyB0aGUgY29sbGF0aW9uIHJ1bGVzIHRoYXQgdGhlIHRhYmxlIGNvbGxhdGlvbiBvYmplY3QKICAgKiB3YXMgY3JlYXRlZCBmcm9tLgogICAqIEBzdGFibGUKICAgKi8KICBjb25zdCAgICAgICBVbmljb2RlU3RyaW5nJiAgICAgIGdldFJ1bGVzKHZvaWQpIGNvbnN0OwoKICAvKioKICAgKiAgUmV0dXJuIHRoZSBtYXhpbXVtIGxlbmd0aCBvZiBhbnkgZXhwYW5zaW9uIHNlcXVlbmNlcyB0aGF0IGVuZAogICAqICB3aXRoIHRoZSBzcGVjaWZpZWQgY29tcGFyaXNvbiBvcmRlci4KICAgKiAKICAgKiAgQHBhcmFtIG9yZGVyIGEgY29sbGF0aW9uIG9yZGVyIHJldHVybmVkIGJ5IHByZXZpb3VzIG9yIG5leHQuCiAgICogIEByZXR1cm4gdGhlIG1heGltdW0gbGVuZ3RoIG9mIGFueSBleHBhbnNpb24gc2V1ZW5jZXMgZW5kaW5nCiAgICogICAgICAgICAgd2l0aCB0aGUgc3BlY2lmaWVkIG9yZGVyLgogICAqIAogICAqICBAc2VlIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciNnZXRNYXhFeHBhbnNpb24KICAgKiBAZHJhZnQgPyBwZW5kaW5nIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6Z2V0TWF4RXhwYW5zaW9uCiAgICovCglpbnQzMl90IGdldE1heEV4cGFuc2lvbihpbnQzMl90IG9yZGVyKSBjb25zdDsKCiAgLyoqCiAgICogUmV0dXJucyBhIHVuaXF1ZSBjbGFzcyBJRCBQT0xZTU9SUEhJQ0FMTFkuICBQdXJlIHZpcnR1YWwgb3ZlcnJpZGUuCiAgICogVGhpcyBtZXRob2QgaXMgdG8gaW1wbGVtZW50IGEgc2ltcGxlIHZlcnNpb24gb2YgUlRUSSwgc2luY2Ugbm90IGFsbAogICAqIEMrKyBjb21waWxlcnMgc3VwcG9ydCBnZW51aW5lIFJUVEkuICBQb2x5bW9ycGhpYyBvcGVyYXRvcj09KCkgYW5kCiAgICogY2xvbmUoKSBtZXRob2RzIGNhbGwgdGhpcyBtZXRob2QuCiAgICoKICAgKiBAcmV0dXJuICAgICAgICAgIFRoZSBjbGFzcyBJRCBmb3IgdGhpcyBvYmplY3QuIEFsbCBvYmplY3RzIG9mIGEKICAgKiAgICAgICAgICAgICAgICAgIGdpdmVuIGNsYXNzIGhhdmUgdGhlIHNhbWUgY2xhc3MgSUQuICBPYmplY3RzIG9mCiAgICogICAgICAgICAgICAgICAgICBvdGhlciBjbGFzc2VzIGhhdmUgZGlmZmVyZW50IGNsYXNzIElEcy4KICAgKi8KICB2aXJ0dWFsIFVDbGFzc0lEIGdldER5bmFtaWNDbGFzc0lEKHZvaWQpIGNvbnN0CiAgICB7IHJldHVybiBSdWxlQmFzZWRDb2xsYXRvcjo6Z2V0U3RhdGljQ2xhc3NJRCgpOyB9CgoKICAvKioKICAgKiBSZXR1cm5zIHRoZSBjbGFzcyBJRCBmb3IgdGhpcyBjbGFzcy4gIFRoaXMgaXMgdXNlZnVsIG9ubHkgZm9yCiAgICogY29tcGFyaW5nIHRvIGEgcmV0dXJuIHZhbHVlIGZyb20gZ2V0RHluYW1pY0NsYXNzSUQoKS4gIEZvciBleGFtcGxlOgogICAqCiAgICogICAgICBCYXNlKiBwb2x5bW9ycGhpY19wb2ludGVyID0gY3JlYXRlUG9seW1vcnBoaWNPYmplY3QoKTsKICAgKiAgICAgIGlmIChwb2x5bW9ycGhpY19wb2ludGVyLT5nZXREeW5hbWljQ2xhc3NJRCgpID09CiAgICogICAgICAgICAgRGVyaXZlZDo6Z2V0U3RhdGljQ2xhc3NJRCgpKSAuLi4KICAgKgogICAqIEByZXR1cm4gICAgICAgICAgVGhlIGNsYXNzIElEIGZvciBhbGwgb2JqZWN0cyBvZiB0aGlzIGNsYXNzLgogICAqLwogIHN0YXRpYyBVQ2xhc3NJRCBnZXRTdGF0aWNDbGFzc0lEKHZvaWQpIHsgcmV0dXJuIChVQ2xhc3NJRCkmZmdDbGFzc0lEOyB9CgogLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFBSSVZBVEUKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpwcml2YXRlOgogIHN0YXRpYyAgICAgIGNoYXIgICAgICAgICAgICAgICAgZmdDbGFzc0lEOwoKICAgICAgICAvLyBTdHJlYW1lciB1c2VkIHRvIHJlYWQvd3JpdGUgYmluYXJ5IGNvbGxhdGlvbiBkYXRhIGZpbGVzLgogIGZyaWVuZCAgICAgICAgY2xhc3MgICAgICAgICAgICAgICAgUnVsZUJhc2VkQ29sbGF0b3JTdHJlYW1lcjsKCiAgLy8gVXNlZCB0byBpdGVyYXRlIG92ZXIgY29sbGF0aW9uIGVsZW1lbnRzIGluIGEgY2hhcmFjdGVyIHNvdXJjZS4KICBmcmllbmQgICAgICBjbGFzcyAgICAgICAgICAgICAgIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjsKICAgICAgICAKICAvLyBDb2xsYXRvciBPTkxZIG5lZWRzIGFjY2VzcyB0byBSdWxlQmFzZWRDb2xsYXRvcihjb25zdCBMb2NhbGUmLCBVRXJyb3JDb2RlJikKICBmcmllbmQgY2xhc3MgQ29sbGF0b3I7CiAgICAgICAgCiAgLy8gVGFibGVDb2xsYXRpb25EYXRhIE9OTFkgbmVlZHMgYWNjZXNzIHRvIFVOTUFQUEVECiAgZnJpZW5kIGNsYXNzIFRhYmxlQ29sbGF0aW9uRGF0YTsKCgogIC8qKiBEZWZhdWx0IGNvbnN0cnVjdG9yCiAgICovCiAgUnVsZUJhc2VkQ29sbGF0b3IoKTsKCiAgLyoqCiAgICogQ3JlYXRlIGEgbmV3IGVudHJ5IGluIHRoZSBleHBhbnNpb24gdGFibGUgdGhhdCBjb250YWlucyB0aGUgb3JkZXJpbmdzCiAgICogZm9yIHRoZSBnaXZlbiBjaGFyYWNlcnMuICBJZiBhbk9yZGVyIGlzIHZhbGlkLCBpdCBpcyBhZGRlZCB0byB0aGUKICAgKiBiZWdpbm5pbmcgb2YgdGhlIGV4cGFuZGVkIGxpc3Qgb2Ygb3JkZXJzLgogICAqLwogIGludDMyX3QgICAgICAgICAgICAgICAgYWRkRXhwYW5zaW9uKGludDMyX3QgYW5PcmRlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBVbmljb2RlU3RyaW5nICZleHBhbmRDaGFycyk7CiAgLyoqCiAgICogQ3JlYXRlIGEgdGFibGUtYmFzZWQgY29sbGF0aW9uIG9iamVjdCB3aXRoIHRoZSBnaXZlbiBydWxlcy4KICAgKiBAc2VlIFJ1bGVCYXNlZENvbGxhdG9yI1J1bGVCYXNlZENvbGxhdG9yCiAgICogQGV4Y2VwdGlvbiBGb3JtYXRFeGNlcHRpb24gSWYgdGhlIHJ1bGVzIGZvcm1hdCBpcyBpbmNvcnJlY3QuCiAgICovCiAgdm9pZCAgICAgICAgICAgICAgICBidWlsZCggIGNvbnN0ICAgVW5pY29kZVN0cmluZyYgIHJ1bGVzLAogICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiAgICAgIHN1Y2Nlc3MpOwoKICAvKiogQWRkIGV4cGFuZGluZyBlbnRyaWVzIGZvciBwcmUtY29tcG9zZWQgdW5pY29kZSBjaGFyYWN0ZXJzIHNvIHRoYXQgdGhpcwogICAqIGNvbGxhdG9yIGNhbiBiZSB1c2VkIHJlYXNvbmFibHkgd2VsbCB3aXRoIGRlY29tcG9zaXRpb24gdHVybmVkIG9mZi4KICAgKi8KICB2b2lkICAgICAgICAgICAgICAgIGFkZENvbXBvc2VkQ2hhcnModm9pZCk7CgogIC8qKgogICAqIExvb2sgdXAgZm9yIHVubWFwcGVkIHZhbHVlcyBpbiB0aGUgZXhwYW5kZWQgY2hhcmFjdGVyIHRhYmxlLgogICAqLwogIHZvaWQgICAgICAgICAgICAgICAgY29tbWl0KHZvaWQpOwogIC8qKgogICAqIEluY3JlbWVudCBvZiB0aGUgbGFzdCBvcmRlciBiYXNlZCBvbiB0aGUgY29sbGF0aW9uIHN0cmVuZ3RoLgogICAqIEBwYXJhbSBzIHRoZSBjb2xsYXRpb24gc3RyZW5ndGguCiAgICogQHBhcmFtIGxhc3RPcmRlciB0aGUgbGFzdCBjb2xsYXRpb24gb3JkZXIuCiAgICogQHJldHVybiB0aGUgbmV3IGNvbGxhdGlvbiBvcmRlci4KICAgKi8KICBpbnQzMl90ICAgICAgICAgICAgIGluY3JlbWVudCggIENvbGxhdG9yOjpFQ29sbGF0aW9uU3RyZW5ndGggICAgcywgCiAgICAgICAgICAgICAgICAgIGludDMyX3QgICAgICAgICAgICAgICAgICAgICAgICAgbGFzdE9yZGVyKTsKICAvKioKICAgKiBBZGRzIGEgY2hhcmFjdGVyIGFuZCBpdHMgZGVzaWduYXRlZCBvcmRlciBpbnRvIHRoZSBjb2xsYXRpb24gdGFibGUuCiAgICogQHBhcmFtIGNoIHRoZSBVbmljb2RlIGNoYXJhY3RlciwKICAgKiBAcGFyYW0gYW5PcmRlciB0aGUgb3JkZXIuCiAgICogQHBhcmFtIHN0YXR1cyB0aGUgZXJyb3IgY29kZSBzdGF0dXMuCiAgICovCiAgdm9pZCAgICAgICAgICAgICAgICBhZGRPcmRlciggICBVQ2hhciAgICAgICAgY2gsIAogICAgICAgICAgICAgICAgICBpbnQzMl90ICAgICAgICBhbk9yZGVyLCAKICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYgIHN0YXR1cyk7CiAgLyoqCiAgICogQWRkcyB0aGUgZXhwYW5kaW5nIHN0cmluZyBpbnRvIHRoZSBjb2xsYXRpb24gdGFibGUsIGZvciBleGFtcGxlLCBhLXVtbGF1dCBpbiBHZXJtYW4uCiAgICogQHBhcmFtIGdyb3VwQ2hhcnMgdGhlIGNvbnRyYWN0aW5nIGNoYXJhY3RlcnMuCiAgICogQHBhcmFtIGV4cENoYXJzIHRoZSBleHBhbmRpbmcgY2hhcmFjdGVycy4KICAgKiBAcGFyYW0gYW5PcmRlciB0aGUgb3JkZXIuCiAgICogQHBhcmFtIHN0YXR1cyB0aGUgZXJyb3IgY29kZSBzdGF0dXMuCiAgICovCiAgdm9pZCAgICAgICAgICAgICAgICBhZGRFeHBhbmRPcmRlcihjb25zdCAgICBVbmljb2RlU3RyaW5nJiAgICAgICAgICBncm91cENoYXJzLCAKICAgICAgICAgICAgICAgICAgICAgY29uc3QgICAgVW5pY29kZVN0cmluZyYgICAgICAgICAgZXhwQ2hhcnMsIAogICAgICAgICAgICAgICAgICAgICBpbnQzMl90ICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFuT3JkZXIsCiAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmICAgICAgICAgICAgICAgICAgICAgICBzdGF0dXMpOwogIC8qKgogICAqIEFkZHMgdGhlIGNvbnRyYWN0aW5nIHN0cmluZyBpbnRvIHRoZSBjb2xsYXRpb24gdGFibGUsIGZvciBleGFtcGxlLCBjaCBpbiBTcGFuaXNoLgogICAqIEBwYXJhbSBncm91cENoYXJzIHRoZSBjb250cmFjdGluZyBjaGFyYWN0ZXJzLgogICAqIEBwYXJhbSBhbk9yZGVyIHRoZSBvcmRlci4KICAgKiBAcGFyYW0gc3RhdHVzIHRoZSBlcnJvciBjb2RlIHN0YXR1cy4KICAgKi8KICB2b2lkICAgICAgICAgICAgICAgIGFkZENvbnRyYWN0T3JkZXIoY29uc3QgIFVuaWNvZGVTdHJpbmcmICAgICAgICAgIGdyb3VwQ2hhcnMsIAogICAgICAgICAgICAgICAgICAgICAgIGludDMyX3QgICAgICAgICAgICAgICAgICAgICAgICBhbk9yZGVyLAogICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmICAgICAgICAgICAgICAgICAgICAgc3RhdHVzKTsKICAvKioKICAgKiBBZGRzIHRoZSBjb250cmFjdGluZyBzdHJpbmcgaW50byB0aGUgY29sbGF0aW9uIHRhYmxlLCBmb3IgZXhhbXBsZSwgY2ggaW4gU3BhbmlzaC4KICAgKiBAcGFyYW0gZ3JvdXBDaGFycyB0aGUgY29udHJhY3RpbmcgY2hhcmFjdGVycy4KICAgKiBAcGFyYW0gYW5PcmRlciB0aGUgb3JkZXIuCiAgICogQHBhcmFtIGZ3ZCBUUlVFIGlmIHRoaXMgaXMgZm9yIHRoZSBmb3J3YXJkIGRpcmVjdGlvbgogICAqIEBwYXJhbSBzdGF0dXMgdGhlIGVycm9yIGNvZGUgc3RhdHVzLgogICAqLwogIHZvaWQgICAgICAgICAgICAgICAgYWRkQ29udHJhY3RPcmRlcihjb25zdCAgVW5pY29kZVN0cmluZyYgICAgICAgICAgZ3JvdXBDaGFycywgCiAgICAgICAgICAgICAgICAgICAgICAgaW50MzJfdCAgICAgICAgICAgICAgICAgICAgICAgIGFuT3JkZXIsCiAgICAgICAgICAgICAgICAgICAgICAgYm9vbF90ICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZ3ZCwKICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiAgICAgICAgICAgICAgICAgICAgIHN0YXR1cyk7CiAgLyoqCiAgICogSWYgdGhlIGdpdmVuIHN0cmluZyBoYXMgYmVlbiBzcGVjaWZpZWQgYXMgYSBjb250cmFjdGluZyBzdHJpbmcKICAgKiBpbiB0aGlzIGNvbGxhdGlvbiB0YWJsZSwgcmV0dXJuIGl0cyBvcmRlcmluZywgb3RoZXJ3aXNlIHJldHVybiBVTk1BUFBFRC4KICAgKiBAcGFyYW0gZ3JvdXBDaGFycyB0aGUgc3RyaW5nCiAgICogQHJldHVybiB0aGUgb3JkZXIgb2YgdGhlIGNvbnRyYWN0ZWQgY2hhcmFjdGVyLCBvciBVTk1BUFBFRCBpZgogICAqIHRoZXJlIGlzbid0IG9uZS4KICAgKi8KICBpbnQzMl90ICAgICAgICAgICAgICAgIGdldENvbnRyYWN0T3JkZXIoY29uc3QgICAgVW5pY29kZVN0cmluZyAgICAgICAgICAgICZncm91cENoYXJzKSBjb25zdDsKICAvKioKICAgKiAgR2V0cyB0aGUgZW50cnkgb2YgbGlzdCBvZiB0aGUgY29udHJhY3Rpbmcgc3RyaW5nIGluIHRoZSBjb2xsYXRpb24KICAgKiAgdGFibGUuCiAgICogIEBwYXJhbSBjaCB0aGUgc3RhcnRpbmcgY2hhcmFjdGVyIG9mIHRoZSBjb250cmFjdGluZyBzdHJpbmcKICAgKiAgQHJldHVybiB0aGUgZW50cnkgb2YgY29udHJhY3RpbmcgZWxlbWVudCB3aGljaCBzdGFydHMgd2l0aCB0aGUgc3BlY2lmaWVkCiAgICogIGNoYXJhY3RlciBpbiB0aGUgbGlzdCBvZiBjb250cmFjdGluZyBlbGVtZW50cy4KICAgKi8KICBWZWN0b3JPZlBUb0NvbnRyYWN0RWxlbWVudCogCiAgZ2V0Q29udHJhY3RWYWx1ZXMoVUNoYXIgICAgIGNoKSBjb25zdDsKICAvKioKICAgKiAgR2VzIHRoZSBlbnRyeSBvZiBsaXN0IG9mIHRoZSBjb250cmFjdGluZyBzdHJpbmcgaW4gdGhlIGNvbGxhdGlvbgogICAqICB0YWJsZS4KICAgKiAgQHBhcmFtIGluZGV4IHRoZSBpbmRleCBvZiB0aGUgY29udHJhY3QgY2hhcmFjdGVyIGxpc3QKICAgKiAgQHJldHVybiB0aGUgZW50cnkgb2YgdGhlIGNvbnRyYWN0aW5nIGVsZW1lbnQgb2YgdGhlIHNwZWNpZmllZCBpbmRleCBpbiB0aGUKICAgKiAgbGlzdC4KICAgKi8KICBWZWN0b3JPZlBUb0NvbnRyYWN0RWxlbWVudCogCiAgZ2V0Q29udHJhY3RWYWx1ZXMoaW50MzJfdCAgICAgaW5kZXgpIGNvbnN0OwogIC8qKgogICAqICBHZXRzIHRoZSBlbnRyeSBvZiB2YWx1ZSBsaXN0IG9mIHRoZSBleHBhbmRpbmcgc3RyaW5nIGluIHRoZSBjb2xsYXRpb24KICAgKiAgdGFibGUgYXQgdGhlIHNwZWNpZmllZCBpbmRleC4KICAgKiAgQHBhcmFtIG9yZGVyIHRoZSBvcmRlciBvZiB0aGUgZXhwYW5kaW5nIHN0cmluZyB2YWx1ZSBsaXN0CiAgICogIEByZXR1cm4gdGhlIGVudHJ5IG9mIHRoZSBleHBhbmRpbmctY2hhciBlbGVtZW50IG9mIHRoZSBzcGVjaWZpZWQgaW5kZXggaW4gCiAgICogIHRoZSBsaXN0LgogICAqLwogIFZlY3Rvck9mSW50KiAgICAgICAgZ2V0RXhwYW5kVmFsdWVMaXN0KGludDMyX3QgICAgIG9yZGVyKSBjb25zdDsKCiAgLyoqCiAgICogIEdldHMgdGhlIGNvbWFyaXNvbiBvcmRlciBvZiBhIGNoYXJhY3RlciBmcm9tIHRoZSBjb2xsYXRpb24gdGFibGUuCiAgICogIEBwYXJhbSBjaCB0aGUgVW5pY29kZSBjaGFyYWN0ZXIKICAgKiAgQHJldHVybiB0aGUgY29tcGFyaXNvbiBvcmRlciBvZiBhIGNoYXJhY3Rlci4KICAgKi8KICBpbnQzMl90ICAgICAgICAgICAgICAgIGdldENoYXJPcmRlcihVQ2hhciBjaCkgY29uc3Q7CgogIC8qKgogICAqICBHZXRzIHRoZSBjb21hcmlzb24gb3JkZXIgb2YgYSBjaGFyYWN0ZXIgZnJvbSB0aGUgY29sbGF0aW9uIHRhYmxlLgogICAqICBAcGFyYW0gbGlzdCB0aGUgY29udHJhY3RpbmcgZWxlbWVudCB0YWJsZS4KICAgKiAgQHBhcmFtIG5hbWUgdGhlIGNvbnRyYWN0aW5nIGNoYXIgc3RyaW5nLgogICAqICBAcmV0dXJuIHRoZSBjb21wYXJpc29uIG9yZGVyIG9mIHRoZSBjb250cmFjdGluZyBjaGFyYWN0ZXIuCiAgICovCiAgc3RhdGljICAgICAgICBpbnQzMl90ICAgICAgICAgICAgIGdldEVudHJ5KCAgIFZlY3Rvck9mUFRvQ29udHJhY3RFbGVtZW50KiAgICAgbGlzdCwgCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0ICAgVW5pY29kZVN0cmluZyYgICAgICAgICAgbmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgYm9vbF90ICAgICAgICAgICAgICAgICAgICBmd2QpOwoKICAvKioKICAgKiBGbGF0dGVucyB0aGUgZ2l2ZW4gb2JqZWN0IHBlcnNpc3RlbnRseSB0byBhIGZpbGUuICBUaGUgZmlsZSBuYW1lCiAgICogYXJndW1lbnQgc2hvdWxkIGJlIGEgcGF0aCBuYW1lIHRoYXQgY2FuIGJlIHBhc3NlZCBkaXJlY3RseSB0byB0aGUKICAgKiB1bmRlcmx5aW5nIE9TLiAgT25jZSBhIFJ1bGVCYXNlZENvbGxhdG9yIGhhcyBiZWVuIHdyaXR0ZW4gdG8gYSBmaWxlLAogICAqIGl0IGNhbiBiZSByZXN1cnJlY3RlZCBieSBjYWxsaW5nIHRoZSBSdWxlQmFzZWRDb2xsYXRvcihjb25zdCBjaGFyKikKICAgKiBjb25zdHJ1Y3Rvciwgd2hpY2ggb3BlcmF0ZXMgdmVyeSBxdWlja2x5LgogICAqIEBwYXJhbSBmaWxlTmFtZSB0aGUgb3V0cHV0IGZpbGUgbmFtZS4KICAgKiBAcmV0dXJuIFRSVUUgaWYgd3JpdGluZyB0byB0aGUgZmlsZSB3YXMgc3VjY2Vzc2Z1bCwgRkFMU0Ugb3RoZXJ3aXNlLgogICAqLwogIGJvb2xfdCAgICAgICAgICAgICAgd3JpdGVUb0ZpbGUoY29uc3QgY2hhciogZmlsZU5hbWUpIGNvbnN0OyAvLyBUcnVlIG9uIHN1Y2Nlc3MKCiAgLyoqCiAgICogQWRkIHRoaXMgdGFibGUgY29sbGF0aW9uIHRvIHRoZSBjYWNoZS4gIFRoaXMgaW52b2x2ZXMgYWRkaW5nIHRoZQogICAqIGVuY2xvc2VkIFRhYmxlQ29sbGF0aW9uRGF0YSB0byB0aGUgY2FjaGUsIGFuZCB0aGVuIG1hcmtpbmcgb3VyCiAgICogcG9pbnRlciBhcyAibm90IG93bmVkIiBieSBzZXR0aW5nIGRhdGFJc093bmVkIHRvIGZhbHNlLgogICAqIEBwYXJhbSBrZXkgdGhlIHVuaXF1ZSB0aGF0IHJlcHJlc2VudHMgdGhpcyBjb2xsYXRpb24gZGF0YSBvYmplY3QuCiAgICovCiAgdm9pZCAgICAgICAgICAgICAgICBhZGRUb0NhY2hlKCAgICAgICAgIGNvbnN0IFVuaWNvZGVTdHJpbmcmIGtleSk7CgogIC8qKgogICAqIFJ1bGVCYXNlZENvbGxhdG9yIGNvbnN0cnVjdG9yLiAgVGhpcyBjb25zdHJ1Y3RvciB0YWtlcyBhIGxvY2FsZS4gIFRoZSBvbmx5CiAgICogY2FsbGVyIG9mIHRoaXMgY2xhc3Mgc2hvdWxkIGJlIENvbGxhdG9yOjpjcmVhdGVJbnN0YW5jZSgpLiAgSWYgY3JlYXRlSW5zdGFuY2UoKQogICAqIGhhcHBlbnMgdG8ga25vdyB0aGF0IHRoZSByZXF1ZXN0ZWQgbG9jYWxlJ3MgY29sbGF0aW9uIGlzIGltcGxlbWVudGVkIGFzCiAgICogYSBSdWxlQmFzZWRDb2xsYXRvciwgaXQgY2FuIHRoZW4gY2FsbCB0aGlzIGNvbnN0cnVjdG9yLiAgT1RIRVJXSVNFIElUIFNIT1VMRE4nVCwKICAgKiBzaW5jZSB0aGlzIGNvbnN0cnVjdG9yIEFMV0FZUyBSRVRVUk5TIEEgVkFMSUQgQ09MTEFUSU9OIFRBQkxFLiAgSXQgZG9lcyB0aGlzCiAgICogYnkgZmFsbGluZyBiYWNrIHRvIGRlZmF1bHRzLgogICAqLwogIFJ1bGVCYXNlZENvbGxhdG9yKCAgICAgIGNvbnN0IExvY2FsZSYgZGVzaXJlZExvY2FsZSwKICAgICAgICAgICAgICBVRXJyb3JDb2RlJiBzdGF0dXMpOwogIC8qKgogICAqIEludGVybmFsIGNvbnN0cnVjdEZyb21YeXgoKSBtZXRob2RzLiAgVGhlc2UgbWV0aG9kcyBkbyBvYmplY3QgY29uc3RydWN0aW9uCiAgICogZnJvbSB2YXJpb3VzIHNvdXJjZXMuICBUaGV5IGFjdCBsaWtlIGFzc2lnbm1lbnQgb3BlcmF0b3JzOyB3aGF0ZXZlciB1c2VkCiAgICogdG8gYmUgaW4gdGhpcyBvYmplY3QgaXMgZGlzY2FyZGVkLiAgPFA+RlJPTSBSVUxFUy4gIFRoaXMgY29uc3RydWN0b3IgdHVybnMKICAgKiBhcm91bmQgYW5kIGNhbGxzIGJ1aWxkKCkuICA8UD5GUk9NIENBQ0hFLiAgVGhpcyBjb25zdHJ1Y3RvciB0cmllcyB0byBnZXQgdGhlCiAgICogcmVxdWVzdGVkIGNhY2hlZCBUYWJsZUNvbGxhdGlvbkRhdGEgb2JqZWN0LCBhbmQgd3JhcCB1cyBhcm91bmQgaXQuICA8UD5GUk9NIEZJTEUuCiAgICogVGhlcmUgYXJlIHR3byBjb25zdHJ1Y3RvcnMgbmFtZWQgY29uc3RydWN0RnJvbUZpbGUoKS4gIE9uZSB0YWtlcyBhIGNvbnN0IGNoYXIqOgogICAqIHRoaXMgaXMgYSBwYXRoIG5hbWUgdG8gYmUgcGFzc2VkIGRpcmVjdGx5IHRvIHRoZSBob3N0IE9TLCB3aGVyZSBhIGZsYXR0ZW5lZAogICAqIHRhYmxlIGNvbGxhdGlvbiAocHJvZHVjZWQgYnkgd3JpdGVUb0ZpbGUoKSkgcmVzaWRlcy4gIFRoZSBvdGhlciBtZXRob2QgdGFrZXMKICAgKiBhIExvY2FsZSwgYW5kIGEgVW5pY29kZVN0cmluZyBsb2NhbGUgZmlsZSBuYW1lLiAgVGhlIGRpc3RpbmN0aW9uIGlzIHRoaXM6CiAgICogdGhlIExvY2FsZSBpcyB0aGUgbG9jYWxlIHdlIGFyZSBzZWVraW5nLiAgVGhlIGZpbGUgbmFtZSBpcyB0aGUgbmFtZSBvZiB0aGUKICAgKiBkYXRhIGZpbGUgKGVpdGhlciBiaW5hcnksIGFzIHByb2R1Y2VkIGJ5IHdyaXRlVG9GaWxlKCksIG9yIEFTQ0lJLCBhcyByZWFkCiAgICogYnkgUmVzb3VyY2VCdW5kbGUpLiAgV2l0aGluIHRoZSBmaWxlLCBpZiBpdCBpcyBmb3VuZCwgdGhlIG1ldGhvZCB3aWxsIGxvb2sKICAgKiBmb3IgdGhlIGdpdmVuIExvY2FsZS4KICAgKi8KICB2b2lkICAgICAgICAgICAgICAgIGNvbnN0cnVjdEZyb21SdWxlcyggY29uc3QgVW5pY29kZVN0cmluZyYgcnVsZXMsCiAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiBzdGF0dXMpOwogIHZvaWQgICAgICAgICAgICAgICAgY29uc3RydWN0RnJvbUZpbGUoICBjb25zdCBMb2NhbGUmICAgICAgICAgICBsb2NhbGUsCiAgICAgICAgICAgICAgICAgICAgICBjb25zdCBVbmljb2RlU3RyaW5nJiAgICBsb2NhbGVGaWxlTmFtZSwKICAgICAgICAgICAgICAgICAgICAgIGJvb2xfdCAgICAgICAgICAgICAgICAgIHRyeUJpbmFyeUZpbGUsCiAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiAgICAgICAgICAgICAgc3RhdHVzKTsKICB2b2lkICAgICAgICAgICAgICAgIGNvbnN0cnVjdEZyb21GaWxlKCAgY29uc3QgY2hhciogZmlsZU5hbWUsCiAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiBzdGF0dXMpOwogIHZvaWQgICAgICAgICAgICAgICAgY29uc3RydWN0RnJvbUNhY2hlKCBjb25zdCBVbmljb2RlU3RyaW5nJiBrZXksCiAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiBzdGF0dXMpOwoKICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgLy8gSW50ZXJuYWwgU3RhdGljIFV0aWxpdHkgTWV0aG9kcwogIC8qKgogICAqIENyZWF0ZXMgdGhlIHBhdGggbmFtZSB3aXRoIGdpdmVuIGluZm9ybWF0aW9uLgogICAqIEBwYXJhbSBwcmVmaXggdGhlIHByZWZpeCBvZiB0aGUgZmlsZSBuYW1lLgogICAqIEBwYXJhbSBuYW1lIHRoZSBhY3R1YWwgZmlsZSBuYW1lLgogICAqIEBwYXJhbSBzdWZmaXggdGhlIHN1ZmZpeCBvZiB0aGUgZmlsZSBuYW1lLgogICAqIEByZXR1cm4gdGhlIGdlbmVyYXRlZCBmaWxlIG5hbWUuCiAgICovCiAgc3RhdGljICBjaGFyKiAgICAgICAgICAgICAgIGNyZWF0ZVBhdGhOYW1lKCBjb25zdCBVbmljb2RlU3RyaW5nJiAgICBwcmVmaXgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVW5pY29kZVN0cmluZyYgICAgbmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBVbmljb2RlU3RyaW5nJiAgICBzdWZmaXgpOwoKICBpbnQzMl90IGdldFN0cmVuZ3RoT3JkZXIoTm9ybWFsaXplckl0ZXJhdG9yKiBjdXJzb3IsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlIHN0YXR1cykgY29uc3Q7CiAgVmVjdG9yT2ZJbnQqIG1ha2VSZW9yZGVyZWRCdWZmZXIoTm9ybWFsaXplckl0ZXJhdG9yKiBjdXJzb3IsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUNoYXIgY29sRmlyc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50MzJfdCBsYXN0VmFsdWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVmVjdG9yT2ZJbnQqIGxhc3RFeHBhbnNpb24pIGNvbnN0OwogIGludDMyX3Qgc3RyZW5ndGhPcmRlcihpbnQzMl90IHZhbHVlKSBjb25zdCA7CiAgaW50MzJfdCBuZXh0Q29udHJhY3RDaGFyKE5vcm1hbGl6ZXJJdGVyYXRvciAqY3Vyc29yLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgVUNoYXIgY2gsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cykgY29uc3Q7CiAgLyoqCiAgICAgKiBDaG9wcyBvZmYgdGhlIGxhc3QgcG9ydGlvbiBvZiB0aGUgbG9jYWxlIG5hbWUuICBGb3IgZXhhbXBsZSwgZnJvbSAiZW5fVVNfQ0EiCiAgICAgKiB0byAiZW5fVVMiIGFuZCAiZW5fVVMiIHRvICJlbiIuCiAgICAgKiBAcGFyYW0gbG9jYWxlTmFtZSB0aGUgbG9jYWxlIG5hbWUuCiAgICAgKi8KICBzdGF0aWMgIHZvaWQgICAgICAgICAgICAgICAgY2hvcExvY2FsZShVbmljb2RlU3RyaW5nJiAgIGxvY2FsZU5hbWUpOwoKICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgLy8gQ29uc3RhbnRzCgogIHN0YXRpYyAgY29uc3QgICBpbnQzMl90ICAgICAgICAgICAgIFVOTUFQUEVEOwogIHN0YXRpYyAgY29uc3QgICBpbnQzMl90ICAgICAgICAgICAgIENIQVJJTkRFWDsgIC8vIG5lZWQgbG9vayB1cCBpbiAuY29tbWl0KCkKICBzdGF0aWMgIGNvbnN0ICAgaW50MzJfdCAgICAgICAgICAgICBFWFBBTkRDSEFSSU5ERVg7IC8vIEV4cGFuZCBpbmRleCBmb2xsb3dzCiAgc3RhdGljICBjb25zdCAgIGludDMyX3QgICAgICAgICAgICAgQ09OVFJBQ1RDSEFSSU5ERVg7ICAvLyBjb250cmFjdCBpbmRleGVzIGZvbGxvdwoKICBzdGF0aWMgIGNvbnN0ICAgaW50MzJfdCAgICAgICAgICAgICBQUklNQVJZT1JERVJJTkNSRU1FTlQ7CiAgc3RhdGljICBjb25zdCAgIGludDMyX3QgICAgICAgICAgICAgTUFYSUdOT1JBQkxFOwogIHN0YXRpYyAgY29uc3QgICBpbnQzMl90ICAgICAgICAgICAgIFNFQ09OREFSWU9SREVSSU5DUkVNRU5UOwogIHN0YXRpYyAgY29uc3QgICBpbnQzMl90ICAgICAgICAgICAgIFRFUlRJQVJZT1JERVJJTkNSRU1FTlQ7CiAgc3RhdGljICBjb25zdCAgIGludDMyX3QgICAgICAgICAgICAgUFJJTUFSWU9SREVSTUFTSzsKICBzdGF0aWMgIGNvbnN0ICAgaW50MzJfdCAgICAgICAgICAgICBTRUNPTkRBUllPUkRFUk1BU0s7CiAgc3RhdGljICBjb25zdCAgIGludDMyX3QgICAgICAgICAgICAgVEVSVElBUllPUkRFUk1BU0s7CiAgc3RhdGljICBjb25zdCAgIGludDMyX3QgICAgICAgICAgICAgU0VDT05EQVJZUkVTRVRNQVNLOwogIHN0YXRpYyAgY29uc3QgICBpbnQzMl90ICAgICAgICAgICAgIElHTk9SQUJMRU1BU0s7CiAgc3RhdGljICBjb25zdCAgIGludDMyX3QgICAgICAgICAgICAgUFJJTUFSWURJRkZFUkVOQ0VPTkxZOwogIHN0YXRpYyAgY29uc3QgICBpbnQzMl90ICAgICAgICAgICAgIFNFQ09OREFSWURJRkZFUkVOQ0VPTkxZOwogIHN0YXRpYyAgY29uc3QgICBpbnQzMl90ICAgICAgICAgICAgIFBSSU1BUllPUkRFUlNISUZUOwogIHN0YXRpYyAgY29uc3QgICBpbnQzMl90ICAgICAgICAgICAgIFNFQ09OREFSWU9SREVSU0hJRlQ7CiAgc3RhdGljICBjb25zdCAgIGludDMyX3QgICAgICAgICAgICAgU09SVEtFWU9GRlNFVDsKICBzdGF0aWMgIGNvbnN0ICAgaW50MzJfdCAgICAgICAgICAgICBDT05UUkFDVENIQVJPVkVSRkxPVzsKCiAgc3RhdGljIGNvbnN0IGludDE2X3QgICAgICAgICAgICAgICAgRklMRUlEOwoKICBzdGF0aWMgICAgICAgVW5pY29kZVN0cmluZyAgICAgIERFRkFVTFRSVUxFUzsKCiAgc3RhdGljICBjb25zdCBjaGFyKiAgICAgICAgICAgICBrRmlsZW5hbWVTdWZmaXg7CgogICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICAgICAvLyBEYXRhIE1lbWJlcnMKCiAgYm9vbF90ICAgICAgICAgICAgICBpc092ZXJJZ25vcmU7CiAgVUNoYXIgICAgICAgICAgICAgbGFzdENoYXI7CiAgTWVyZ2VDb2xsYXRpb24qICAgICBtUGF0dGVybjsKICBVbmljb2RlU3RyaW5nICAgICAgIHNidWZmZXI7CiAgVW5pY29kZVN0cmluZyAgICAgICB0YnVmZmVyOwogIFVuaWNvZGVTdHJpbmcgICAgICAga2V5OwogIE5vcm1hbGl6ZXJJdGVyYXRvciAgKmN1cnNvcjE7CiAgTm9ybWFsaXplckl0ZXJhdG9yICAqY3Vyc29yMjsKICBib29sX3QgICAgICAgICAgICAgIGRhdGFJc093bmVkOwogIFRhYmxlQ29sbGF0aW9uRGF0YSogZGF0YTsKfTsKCmlubGluZSBib29sX3QKUnVsZUJhc2VkQ29sbGF0b3I6Om9wZXJhdG9yIT0oY29uc3QgQ29sbGF0b3ImIG90aGVyKSBjb25zdAp7CiAgcmV0dXJuICEoKnRoaXMgPT0gb3RoZXIpOwp9CgppbmxpbmUgdm9pZApSdWxlQmFzZWRDb2xsYXRvcjo6YWRkQ29udHJhY3RPcmRlcihjb25zdCBVbmljb2RlU3RyaW5nICZncm91cENoYXJzLAogICAgICAgICAgICAgICAgICAgIGludDMyX3QgICAgICAgICAgICAgICAgYW5PcmRlciwKICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlICAgICAgICAgICAgJnN0YXR1cykKewogIGFkZENvbnRyYWN0T3JkZXIoZ3JvdXBDaGFycywgYW5PcmRlciwgVFJVRSwgc3RhdHVzKTsKfQoKCgoKI2VuZGlmCg==