LyoKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiogQ29weXJpZ2h0IKkgezE5OTYtMjAwMX0sIEludGVybmF0aW9uYWwgQnVzaW5lc3MgTWFjaGluZXMgQ29ycG9yYXRpb24gYW5kIAoqIG90aGVycy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiovCgovKioKKiBGaWxlIHRibGNvbGwuaAoqCiogQ3JlYXRlZCBieTogSGVsZW5hIFNoaWgKKgoqIE1vZGlmaWNhdGlvbiBIaXN0b3J5OgoqCiogIERhdGUgICAgICAgIE5hbWUgICAgICAgIERlc2NyaXB0aW9uCiogIDIvNS85NyAgICAgIGFsaXUgICAgICAgIEFkZGVkIHN0cmVhbUluIGFuZCBzdHJlYW1PdXQgbWV0aG9kcy4gIEFkZGVkCiogICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0cnVjdG9yIHdoaWNoIHJlYWRzIFJ1bGVCYXNlZENvbGxhdG9yIG9iamVjdCBmcm9tCiogICAgICAgICAgICAgICAgICAgICAgICAgIGEgYmluYXJ5IGZpbGUuICBBZGRlZCB3cml0ZVRvRmlsZSBtZXRob2Qgd2hpY2ggc3RyZWFtcwoqICAgICAgICAgICAgICAgICAgICAgICAgICBSdWxlQmFzZWRDb2xsYXRvciBvdXQgdG8gYSBiaW5hcnkgZmlsZS4gIFRoZSBzdHJlYW1JbgoqICAgICAgICAgICAgICAgICAgICAgICAgICBhbmQgc3RyZWFtT3V0IG1ldGhvZHMgdXNlIGlzdHJlYW0gYW5kIG9zdHJlYW0gb2JqZWN0cwoqICAgICAgICAgICAgICAgICAgICAgICAgICBpbiBiaW5hcnkgbW9kZS4KKiAgMi8xMi85NyAgICAgYWxpdSAgICAgICAgTW9kaWZpZWQgdG8gdXNlIFRhYmxlQ29sbGF0aW9uRGF0YSBzdWItb2JqZWN0IHRvCiogICAgICAgICAgICAgICAgICAgICAgICAgIGhvbGQgaW52YXJpYW50IGRhdGEuCiogIDIvMTMvOTcgICAgIGFsaXUgICAgICAgIE1vdmVkIHNldmVyYWwgbWV0aG9kcyBpbnRvIHRoaXMgY2xhc3MgZnJvbSBDb2xsYXRpb24uCiogICAgICAgICAgICAgICAgICAgICAgICAgIEFkZGVkIGEgcHJpdmF0ZSBSdWxlQmFzZWRDb2xsYXRvcihMb2NhbGUmKSBjb25zdHJ1Y3RvciwKKiAgICAgICAgICAgICAgICAgICAgICAgICAgdG8gYmUgdXNlZCBieSBDb2xsYXRvcjo6Y3JlYXRlRGVmYXVsdCgpLiAgR2VuZXJhbAoqICAgICAgICAgICAgICAgICAgICAgICAgICBjbGVhbiB1cC4KKiAgMi8yMC85NyAgICAgaGVsZW5hICAgICAgQWRkZWQgY2xvbmUsIG9wZXJhdG9yPT0sIG9wZXJhdG9yIT0sIG9wZXJhdG9yPSwgYW5kIGNvcHkKKiAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3RydWN0b3IgYW5kIGdldER5bmFtaWNDbGFzc0lELgoqICAzLzUvOTcgICAgICBhbGl1ICAgICAgICBNb2RpZmllZCBjb25zdHJ1Y3RGcm9tRmlsZSgpIHRvIGFkZCBwYXJhbWV0ZXIKKiAgICAgICAgICAgICAgICAgICAgICAgICAgc3BlY2lmeWluZyB3aGV0aGVyIG9yIG5vdCBiaW5hcnkgbG9hZGluZyBpcyB0byBiZQoqICAgICAgICAgICAgICAgICAgICAgICAgICBhdHRlbXB0ZWQuICBUaGlzIGlzIHJlcXVpcmVkIGZvciBkeW5hbWljIHJ1bGUgbG9hZGluZy4KKiAwNS8wNy85NyAgICAgaGVsZW5hICAgICAgQWRkZWQgbWVtb3J5IGFsbG9jYXRpb24gZXJyb3IgZGV0ZWN0aW9uLgoqICA2LzE3Lzk3ICAgICBoZWxlbmEgICAgICBBZGRlZCBJREVOVElDQUwgc3RyZW5ndGggZm9yIGNvbXBhcmUsIGNoYW5nZWQgZ2V0UnVsZXMgdG8gCiogICAgICAgICAgICAgICAgICAgICAgICAgIHVzZSBNZXJnZUNvbGxhdGlvbjo6Z2V0UGF0dGVybi4KKiAgNi8yMC85NyAgICAgaGVsZW5hICAgICAgSmF2YSBjbGFzcyBuYW1lIGNoYW5nZS4KKiAgOC8xOC85NyAgICAgaGVsZW5hICAgICAgQWRkZWQgaW50ZXJuYWwgQVBJIGRvY3VtZW50YXRpb24uCiogMDkvMDMvOTcgICAgIGhlbGVuYSAgICAgIEFkZGVkIGNyZWF0ZUNvbGxhdGlvbktleVZhbHVlcygpLgoqIDAyLzEwLzk4ICAgICBkYW1pYmEgICAgICBBZGRlZCBjb21wYXJlIHdpdGggImxlbmd0aCIgcGFyYW1ldGVyCiogMDgvMDUvOTggICAgIGVybSAgICAgICAgIFN5bmNoZWQgd2l0aCAxLjIgdmVyc2lvbiBvZiBSdWxlQmFzZWRDb2xsYXRvci5qYXZhCiogMDQvMjMvOTkgICAgIHN0ZXBoZW4gICAgIFJlbW92ZWQgRURlY29tcG9zaXRpb25Nb2RlLCBtZXJnZWQgd2l0aAoqICAgICAgICAgICAgICAgICAgICAgICAgICBOb3JtYWxpemVyOjpFTW9kZQoqIDA2LzE0Lzk5ICAgICBzdGVwaGVuICAgICBSZW1vdmVkIGtSZXNvdXJjZUJ1bmRsZVN1ZmZpeAoqIDExLzAyLzk5ICAgICBoZWxlbmEgICAgICBDb2xsYXRvciBwZXJmb3JtYW5jZSBlbmhhbmNlbWVudHMuICBFbGltaW5hdGVzIHRoZSAKKiAgICAgICAgICAgICAgICAgICAgICAgICAgVW5pY29kZVN0cmluZyBjb25zdHJ1Y3Rpb24gYW5kIHNwZWNpYWwgY2FzZSBmb3IgTk9fT1AuCiogMTEvMjMvOTkgICAgIHNybCAgICAgICAgIE1vcmUgcGVyZm9ybWFuY2UgZW5oYW5jZW1lbnRzLiBVcGRhdGVzIHRvIE5vcm1hbGl6ZXJJdGVyYXRvcgoqICAgICAgICAgICAgICAgICAgICAgICAgICBpbnRlcm5hbCBzdGF0ZSBtYW5hZ2VtZW50LgoqIDEyLzE1Lzk5ICAgICBhbGl1ICAgICAgICBVcGRhdGUgdG8gc3VwcG9ydCBUaGFpIGNvbGxhdGlvbi4gIE1vdmUgTm9ybWFsaXplckl0ZXJhdG9yCiogICAgICAgICAgICAgICAgICAgICAgICAgIHRvIGltcGxlbWVudGF0aW9uIGZpbGUuCiogMDEvMjkvMDEgICAgIHN5bndlZSAgICAgIE1vZGlmaWVkIGludG8gYSBDKysgd3JhcHBlciB3aGljaCBjYWxscyBDIEFQSSAKKiAgICAgICAgICAgICAgICAgICAgICAgICAgKHVjb2wuaCkKKi8KCiNpZm5kZWYgVEJMQ09MTF9ICiNkZWZpbmUgVEJMQ09MTF9ICgojaW5jbHVkZSAidW5pY29kZS9jb2xsLmgiCiNpbmNsdWRlICJ1bmljb2RlL3NvcnRrZXkuaCIKI2luY2x1ZGUgInVuaWNvZGUvbm9ybWx6ci5oIgoKY2xhc3MgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOwoKLyoqCiAqIFRoZSBSdWxlQmFzZWRDb2xsYXRvciBjbGFzcyBwcm92aWRlcyB0aGUgc2ltcGxlIGltcGxlbWVudGF0aW9uIG9mIAogKiBDb2xsYXRvciwgdXNpbmcgZGF0YS1kcml2ZW4gdGFibGVzLiBUaGUgdXNlciBjYW4gY3JlYXRlIGEgY3VzdG9taXplZCAKICogdGFibGUtYmFzZWQgY29sbGF0aW9uLgogKiA8UD4KICogUnVsZUJhc2VkQ29sbGF0b3IgbWFwcyBjaGFyYWN0ZXJzIHRvIGNvbGxhdGlvbiBrZXlzLgogKiA8cD4KICogVGFibGUgQ29sbGF0aW9uIGhhcyB0aGUgZm9sbG93aW5nIHJlc3RyaWN0aW9ucyBmb3IgZWZmaWNpZW5jeSAob3RoZXIKICogc3ViY2xhc3NlcyBtYXkgYmUgdXNlZCBmb3IgbW9yZSBjb21wbGV4IGxhbmd1YWdlcykgOgogKiAgICAgICA8cD4xLiBJZiB0aGUgRnJlbmNoIHNlY29uZGFyeSBvcmRlcmluZyBpcyBzcGVjaWZpZWQgaW4gYSBjb2xsYXRpb24gCiAqICAgICAgICAgICAgIG9iamVjdCwgaXQgaXMgYXBwbGllZCB0byB0aGUgd2hvbGUgb2JqZWN0LgogKiAgICAgICA8cD4yLiBBbGwgbm9uLW1lbnRpb25lZCBVbmljb2RlIGNoYXJhY3RlcnMgYXJlIGF0IHRoZSBlbmQgb2YgdGhlCiAqICAgICAgICAgICAgIGNvbGxhdGlvbiBvcmRlci4KICogICAgICAgPHA+My4gUHJpdmF0ZSB1c2UgY2hhcmFjdGVycyBhcmUgdHJlYXRlZCBhcyBpZGVudGljYWwuICBUaGUgcHJpdmF0ZQogKiAgICAgICAgICAgICB1c2UgYXJlYSBpbiBVbmljb2RlIGlzIDB4RTgwMC0weEY4RkYuCiAqIDxwPlRoZSBjb2xsYXRpb24gdGFibGUgaXMgY29tcG9zZWQgb2YgYSBsaXN0IG9mIGNvbGxhdGlvbiBydWxlcywgd2hlcmUgZWFjaAogKiBydWxlIGlzIG9mIHRocmVlIGZvcm1zOgogKiA8cHJlPgogKiBcY29kZQogKiAgICAgPG1vZGlmaWVyID4KICogICAgIDxyZWxhdGlvbiA+ICZsdDsgdGV4dC1hcmd1bWVudCA+CiAqICAgICA8cmVzZXQgPiAmbHQ7IHRleHQtYXJndW1lbnQgPgogKiBcZW5kY29kZQogKiA8L3ByZT4KICogVGhlIGZvbGxvd2luZyBkZW1vbnN0cmF0ZXMgaG93IHRvIGNyZWF0ZSB5b3VyIG93biBjb2xsYXRpb24gcnVsZXM6CiAqIDxVTCBUeXBlPXJvdW5kPgogKiAgICA8TEk+PHN0cm9uZz5UZXh0IEFyZ3VtZW50PC9zdHJvbmc+OiBBIHRleHQgYXJndW1lbnQgaXMgYW55IHNlcXVlbmNlIG9mCiAqICAgICAgICBjaGFyYWN0ZXJzLCBleGNsdWRpbmcgc3BlY2lhbCBjaGFyYWN0ZXJzICh0aGF0IGlzLCB3aGl0ZXNwYWNlCiAqICAgICAgICBjaGFyYWN0ZXJzIGFuZCB0aGUgY2hhcmFjdGVycyB1c2VkIGluIG1vZGlmaWVyLCByZWxhdGlvbiBhbmQgcmVzZXQpLgogKiAgICAgICAgSWYgdGhvc2UgY2hhcmFjdGVycyBhcmUgZGVzaXJlZCwgeW91IGNhbiBwdXQgdGhlbSBpbiBzaW5nbGUgcXVvdGVzCiAqICAgICAgICAoZS5nLiBhbXBlcnNhbmQgPT4gJyYnKS48UD4KICogICAgPExJPjxzdHJvbmc+TW9kaWZpZXI8L3N0cm9uZz46IFRoZXJlIGlzIGEgc2luZ2xlIG1vZGlmaWVyLAogKiAgICAgICAgd2hpY2ggaXMgdXNlZCB0byBzcGVjaWZ5IHRoYXQgYWxsIHNlY29uZGFyeSBkaWZmZXJlbmNlcyBhcmUKICogICAgICAgIHNvcnRlZCBiYWNrd2FyZHMuCiAqICAgICAgICA8cD4nQCcgOiBJbmRpY2F0ZXMgdGhhdCBzZWNvbmRhcnkgZGlmZmVyZW5jZXMsIHN1Y2ggYXMgYWNjZW50cywgYXJlIAogKiAgICAgICAgICAgICAgICAgc29ydGVkIGJhY2t3YXJkcywgYXMgaW4gRnJlbmNoLjxQPgogKiAgICA8TEk+PHN0cm9uZz5SZWxhdGlvbjwvc3Ryb25nPjogVGhlIHJlbGF0aW9ucyBhcmUgdGhlIGZvbGxvd2luZzoKICogICAgICAgIDxVTCBUeXBlPXNxdWFyZT4KICogICAgICAgICAgICA8TEk+JyZsdDsnIDogR3JlYXRlciwgYXMgYSBsZXR0ZXIgZGlmZmVyZW5jZSAocHJpbWFyeSkKICogICAgICAgICAgICA8TEk+JzsnIDogR3JlYXRlciwgYXMgYW4gYWNjZW50IGRpZmZlcmVuY2UgKHNlY29uZGFyeSkKICogICAgICAgICAgICA8TEk+JywnIDogR3JlYXRlciwgYXMgYSBjYXNlIGRpZmZlcmVuY2UgKHRlcnRpYXJ5KQogKiAgICAgICAgICAgIDxMST4nPScgOiBFcXVhbAogKiAgICAgICAgPC9VTD48UD4KICogICAgPExJPjxzdHJvbmc+UmVzZXQ8L3N0cm9uZz46IFRoZXJlIGlzIGEgc2luZ2xlIHJlc2V0LAogKiAgICAgICAgd2hpY2ggaXMgdXNlZCBwcmltYXJpbHkgZm9yIGNvbnRyYWN0aW9ucyBhbmQgZXhwYW5zaW9ucywgYnV0IHdoaWNoCiAqICAgICAgICBjYW4gYWxzbyBiZSB1c2VkIHRvIGFkZCBhIG1vZGlmaWNhdGlvbiBhdCB0aGUgZW5kIG9mIGEgc2V0IG9mIHJ1bGVzLgogKiAgICAgICAgPHA+JyYnIDogSW5kaWNhdGVzIHRoYXQgdGhlIG5leHQgcnVsZSBmb2xsb3dzIHRoZSBwb3NpdGlvbiB0byB3aGVyZQogKiAgICAgICAgICAgIHRoZSByZXNldCB0ZXh0LWFyZ3VtZW50IHdvdWxkIGJlIHNvcnRlZC4KICogPC9VTD4KICoKICogPHA+CiAqIFRoaXMgc291bmRzIG1vcmUgY29tcGxpY2F0ZWQgdGhhbiBpdCBpcyBpbiBwcmFjdGljZS4gRm9yIGV4YW1wbGUsIHRoZQogKiBmb2xsb3dpbmcgYXJlIGVxdWl2YWxlbnQgd2F5cyBvZiBleHByZXNzaW5nIHRoZSBzYW1lIHRoaW5nOgogKiA8cHJlPgogKiBcY29kZQogKiAgICAgYSA8IGIgPCBjCiAqICAgICBhIDwgYiAmIGIgIDwgYwogKiAgICAgYSA8IGMgJiBhICA8IGIKICogXGVuZGNvZGUKICogPC9wcmU+CiAqIE5vdGljZSB0aGF0IHRoZSBvcmRlciBpcyBpbXBvcnRhbnQsIGFzIHRoZSBzdWJzZXF1ZW50IGl0ZW0gZ29lcyBpbW1lZGlhdGVseQogKiBhZnRlciB0aGUgdGV4dC1hcmd1bWVudC4gVGhlIGZvbGxvd2luZyBhcmUgbm90IGVxdWl2YWxlbnQ6CiAqIDxwcmU+CiAqIFxjb2RlCiAqICAgICBhIDwgIGIgJiBhICA8IGMKICogICAgIGEgPCAgYyAmIGEgIDwgYgogKiBcZW5kY29kZQogKiA8L3ByZT4KICogRWl0aGVyIHRoZSB0ZXh0LWFyZ3VtZW50IG11c3QgYWxyZWFkeSBiZSBwcmVzZW50IGluIHRoZSBzZXF1ZW5jZSwgb3Igc29tZQogKiBpbml0aWFsIHN1YnN0cmluZyBvZiB0aGUgdGV4dC1hcmd1bWVudCBtdXN0IGJlIHByZXNlbnQuIChlLmcuICJhICZsdDsgYiAmIAogKiBhZSAmbHQ7IGUiIGlzIHZhbGlkIHNpbmNlICJhIiBpcyBwcmVzZW50IGluIHRoZSBzZXF1ZW5jZSBiZWZvcmUgImFlIiBpcyAKICogcmVzZXQpLiBJbiB0aGlzIGxhdHRlciBjYXNlLCAiYWUiIGlzIG5vdCBlbnRlcmVkIGFuZCB0cmVhdGVkIGFzIGEgc2luZ2xlIAogKiBjaGFyYWN0ZXI7IGluc3RlYWQsICJlIiBpcyBzb3J0ZWQgYXMgaWYgaXQgd2VyZSBleHBhbmRlZCB0byB0d28gY2hhcmFjdGVyczogCiAqICJhIiBmb2xsb3dlZCBieSBhbiAiZSIuIFRoaXMgZGlmZmVyZW5jZSBhcHBlYXJzIGluIG5hdHVyYWwgbGFuZ3VhZ2VzOiBpbgogKiB0cmFkaXRpb25hbCBTcGFuaXNoICJjaCIgaXMgdHJlYXRlZCBhcyB0aG91Z2ggaXQgY29udHJhY3RzIHRvIGEgc2luZ2xlCiAqIGNoYXJhY3RlciAoZXhwcmVzc2VkIGFzICJjICZsdDsgY2ggJmx0OyBkIiksIHdoaWxlIGluIHRyYWRpdGlvbmFsIEdlcm1hbiAKICogIuQiIChhLXVtbGF1dCkgaXMgdHJlYXRlZCBhcyB0aG91Z2ggaXQgZXhwYW5kcyB0byB0d28gY2hhcmFjdGVycyAoZXhwcmVzc2VkIAogKiBhcyAiYSAmIGFlIDsg5CAmbHQ7IGIiKS4KICogPHA+PHN0cm9uZz5JZ25vcmFibGUgQ2hhcmFjdGVyczwvc3Ryb25nPgogKiA8cD5Gb3IgaWdub3JhYmxlIGNoYXJhY3RlcnMsIHRoZSBmaXJzdCBydWxlIG11c3Qgc3RhcnQgd2l0aCBhIHJlbGF0aW9uICh0aGUKICogZXhhbXBsZXMgd2UgaGF2ZSB1c2VkIGFib3ZlIGFyZSByZWFsbHkgZnJhZ21lbnRzOyAiYSAmbHQ7IGIiIHJlYWxseSBzaG91bGQgCiAqIGJlICImbHQ7IGEgJmx0OyBiIikuIElmLCBob3dldmVyLCB0aGUgZmlyc3QgcmVsYXRpb24gaXMgbm90ICImbHQ7IiwgdGhlbiAKICogYWxsIHRoZSB0ZXh0LWFyZ3VtZW50cyB1cCB0byB0aGUgZmlyc3QgIiZsdDsiIGFyZSBpZ25vcmFibGUuIEZvciBleGFtcGxlLCAKICogIiwgLSAmbHQ7IGEgJmx0OyBiIiBtYWtlcyAiLSIgYW4gaWdub3JhYmxlIGNoYXJhY3RlciwgYXMgd2Ugc2F3IGVhcmxpZXIgaW4gCiAqIHRoZSB3b3JkICJibGFjay1iaXJkcyIuIEluIHRoZSBzYW1wbGVzIGZvciBkaWZmZXJlbnQgbGFuZ3VhZ2VzLCB5b3Ugc2VlIAogKiB0aGF0IG1vc3QgYWNjZW50cyBhcmUgaWdub3JhYmxlLgogKiA8cD48c3Ryb25nPk5vcm1hbGl6YXRpb24gYW5kIEFjY2VudHM8L3N0cm9uZz4KICogPHA+VGhlIENvbGxhdG9yIG9iamVjdCBhdXRvbWF0aWNhbGx5IG5vcm1hbGl6ZXMgdGV4dCBpbnRlcm5hbGx5IHRvIAogKiBzZXBhcmF0ZSBhY2NlbnRzIGZyb20gYmFzZSBjaGFyYWN0ZXJzIHdoZXJlIHBvc3NpYmxlLiBUaGlzIGlzIGRvbmUgYm90aCAKICogd2hlbiBwcm9jZXNzaW5nIHRoZSBydWxlcywgYW5kIHdoZW4gY29tcGFyaW5nIHR3byBzdHJpbmdzLiBDb2xsYXRvciBhbHNvIAogKiB1c2VzIHRoZSBVbmljb2RlIGNhbm9uaWNhbCBtYXBwaW5nIHRvIGVuc3VyZSB0aGF0IGNvbWJpbmluZyBzZXF1ZW5jZXMgYXJlIAogKiBzb3J0ZWQgcHJvcGVybHkgKGZvciBtb3JlIGluZm9ybWF0aW9uLCBzZWUgCiAqIDxBIEhSRUY9Imh0dHA6Ly93d3cuYXcuY29tL2RldnByZXNzIj4gVGhlIFVuaWNvZGUgU3RhbmRhcmQsIFZlcnNpb24gMi4wPC9BPgogKiAuKTwvUD4KICogPHA+PHN0cm9uZz5FcnJvcnM8L3N0cm9uZz4KICogPHA+VGhlIGZvbGxvd2luZyBhcmUgZXJyb3JzOgogKiA8VUwgVHlwZT1yb3VuZD4KICogICAgIDxMST5BIHRleHQtYXJndW1lbnQgY29udGFpbnMgdW5xdW90ZWQgcHVuY3R1YXRpb24gc3ltYm9scwogKiAgICAgICAgKGUuZy4gImEgJmx0OyBiLWMgJmx0OyBkIikuCiAqICAgICA8TEk+QSByZWxhdGlvbiBvciByZXNldCBjaGFyYWN0ZXIgbm90IGZvbGxvd2VkIGJ5IGEgdGV4dC1hcmd1bWVudAogKiAgICAgICAgKGUuZy4gImEgJmx0OyAsIGIiKS4KICogICAgIDxMST5BIHJlc2V0IHdoZXJlIHRoZSB0ZXh0LWFyZ3VtZW50IChvciBhbiBpbml0aWFsIHN1YnN0cmluZyBvZiB0aGUKICogICAgICAgICB0ZXh0LWFyZ3VtZW50KSBpcyBub3QgYWxyZWFkeSBpbiB0aGUgc2VxdWVuY2UuCiAqICAgICAgICAgKGUuZy4gImEgJmx0OyBiICYgZSAmbHQ7IGYiKQogKiA8L1VMPgogKiA8cHJlPgogKiBcY29kZQogKiAgICAgRXhhbXBsZXM6CiAqICAgICBTaW1wbGU6ICAgICAiPCBhIDwgYiA8IGMgPCBkIgogKiAgICAgTm9yd2VnaWFuOiAgIjwgYSxBPCBiLEI8IGMsQzwgZCxEPCBlLEU8IGYsRjwgZyxHPCBoLEg8IGksSTwgaixKCiAqICAgICAgICAgICAgICAgICAgPCBrLEs8IGwsTDwgbSxNPCBuLE48IG8sTzwgcCxQPCBxLFE8IHIsUjwgcyxTPCB0LFQKICogICAgICAgICAgICAgICAgICA8IHUsVTwgdixWPCB3LFc8IHgsWDwgeSxZPCB6LFoKICogICAgICAgICAgICAgICAgICA8IOU9YbAsxT1BsAogKiAgICAgICAgICAgICAgICAgIDthYSxBQTwg5izGPCD4LNgiCiAqIFxlbmRjb2RlCiAqIDwvcHJlPgogKiA8cD5UbyBjcmVhdGUgYSB0YWJsZS1iYXNlZCBjb2xsYXRpb24gb2JqZWN0LCBzaW1wbHkgc3VwcGx5IHRoZSBjb2xsYXRpb24KICogcnVsZXMgdG8gdGhlIFJ1bGVCYXNlZENvbGxhdG9yIGNvbnRydWN0b3IuICBGb3IgZXhhbXBsZToKICogPHByZT4KICogXGNvZGUKICogICAgIFVFcnJvckNvZGUgc3RhdHVzID0gVV9aRVJPX0VSUk9SOwogKiAgICAgUnVsZUJhc2VkQ29sbGF0b3IgKm15U2ltcGxlID0gCiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFJ1bGVCYXNlZENvbGxhdG9yKFNpbXBsZSwgc3RhdHVzKTsKICogXGVuZGNvZGUKICogPC9wcmU+CiAqIDxwPkFub3RoZXIgZXhhbXBsZToKICogPHByZT4KICogXGNvZGUKICogICAgIFVFcnJvckNvZGUgc3RhdHVzID0gVV9aRVJPX0VSUk9SOwogKiAgICAgUnVsZUJhc2VkQ29sbGF0b3IgKm15Tm9yd2VnaWFuID0gCiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFJ1bGVCYXNlZENvbGxhdG9yKE5vcndlZ2lhbiwgc3RhdHVzKTsKICogXGVuZGNvZGUKICogPC9wcmU+CiAqIFRvIGFkZCBydWxlcyBvbiB0b3Agb2YgYW4gZXhpc3RpbmcgdGFibGUsIHNpbXBseSBzdXBwbHkgdGhlIG9yZ2luYWwgcnVsZXMKICogYW5kIG1vZGlmaWNhdGlvbnMgdG8gUnVsZUJhc2VkQ29sbGF0b3IgY29uc3RydWN0b3IuICBGb3IgZXhhbXBsZSwKICogPHByZT4KICogXGNvZGUKICogICAgICBUcmFkaXRpb25hbCBTcGFuaXNoIChmcmFnbWVudCk6IC4uLiAmIEMgPCBjaCAsIGNIICwgQ2ggLCBDSCAuLi4KICogICAgICBHZXJtYW4gKGZyYWdtZW50KSA6IC4uLjwgeSAsIFkgPCB6ICwgWgogKiAgICAgICAgICAgICAgICAgICAgICAgICAgJiBBRSwgxCAmIEFFLCDkCiAqICAgICAgICAgICAgICAgICAgICAgICAgICAmIE9FICwg1iAmIE9FLCD2CiAqICAgICAgICAgICAgICAgICAgICAgICAgICAmIFVFICwg3CAmIFVFLCD8CiAqICAgICAgU3ltYm9scyAoZnJhZ21lbnQpOiAuLi48IHksIFkgPCB6ICwgWgogKiAgICAgICAgICAgICAgICAgICAgICAgICAgJiBRdWVzdGlvbi1tYXJrIDsgJz8nCiAqICAgICAgICAgICAgICAgICAgICAgICAgICAmIEFtcGVyc2FuZCA7ICcmJwogKiAgICAgICAgICAgICAgICAgICAgICAgICAgJiBEb2xsYXItc2lnbiA7ICckJwogKiBcZW5kY29kZQogKiA8L3ByZT4KICogPHA+VG8gY3JlYXRlIGEgY29sbGF0aW9uIG9iamVjdCBmb3IgdHJhZGl0aW9uYWwgU3BhbmlzaCwgdGhlIHVzZXIgY2FuIHRha2UKICogdGhlIEVuZ2xpc2ggY29sbGF0aW9uIHJ1bGVzIGFuZCBhZGQgdGhlIGFkZGl0aW9uYWwgcnVsZXMgdG8gdGhlIHRhYmxlLgogKiBGb3IgZXhhbXBsZToKICogPHByZT4KICogXGNvZGUKICogICAgICBVRXJyb3JDb2RlIHN0YXR1cyA9IFVfWkVST19FUlJPUjsKICogICAgICBVbmljb2RlU3RyaW5nIHJ1bGVzKERFRkFVTFRSVUxFUyk7CiAqICAgICAgcnVsZXMgKz0gIiYgQyAmbHQ7IGNoLCBjSCwgQ2gsIENIIjsKICogICAgICBSdWxlQmFzZWRDb2xsYXRvciAqbXlTcGFuaXNoID0gCiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBSdWxlQmFzZWRDb2xsYXRvcihydWxlcywgc3RhdHVzKTsKICogXGVuZGNvZGUKICogPC9wcmU+CiAqIDxwPkluIG9yZGVyIHRvIHNvcnQgc3ltYm9scyBpbiB0aGUgc2ltaWxpYXIgb3JkZXIgb2Ygc29ydGluZyB0aGVpcgogKiBhbHBoYWJldGljIGVxdWl2YWxlbnRzLCB5b3UgY2FuIGRvIHRoZSBmb2xsb3dpbmcsCiAqIDxwcmU+CiAqIFxjb2RlCiAqICAgICAgVUVycm9yQ29kZSBzdGF0dXMgPSBVX1pFUk9fRVJST1I7CiAqICAgICAgVW5pY29kZVN0cmluZyBydWxlcyhERUZBVUxUUlVMRVMpOwogKiAgICAgIHJ1bGVzICs9ICImIFF1ZXN0aW9uLW1hcmsgOyAnPycgJiBBbXBlcnNhbmQgOyAnJicgJiBEb2xsYXItc2lnbiA7IAogKiAgICAgICAgICAgICAgICckJyAiOwogKiAgICAgIFJ1bGVCYXNlZENvbGxhdG9yICpteVRhYmxlID0gCiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBSdWxlQmFzZWRDb2xsYXRvcihydWxlcywgc3RhdHVzKTsKICogXGVuZGNvZGUKICogPC9wcmU+CiAqIDxwPkFub3RoZXIgd2F5IG9mIGNyZWF0aW5nIHRoZSB0YWJsZS1iYXNlZCBjb2xsYXRpb24gb2JqZWN0LCBteVNpbXBsZSwKICogaXM6CiAqIDxwcmU+CiAqIFxjb2RlCiAqICAgICAgVUVycm9yQ29kZSBzdGF0dXMgPSBVX1pFUk9fRVJST1I7CiAqICAgICAgUnVsZUJhc2VkQ29sbGF0b3IgKm15U2ltcGxlID0gbmV3CiAqICAgICAgICBSdWxlQmFzZWRDb2xsYXRvcigiICZsdDsgYSAmbHQ7IGIgJiBiICZsdDsgYyAmIGMgJmx0OyBkIiwgc3RhdHVzKTsKICogXGVuZGNvZGUKICogPC9wcmU+CiAqIE9yLAogKiA8cHJlPgogKiBcY29kZQogKiAgICAgIFVFcnJvckNvZGUgc3RhdHVzID0gVV9aRVJPX0VSUk9SOwogKiAgICAgIFJ1bGVCYXNlZENvbGxhdG9yICpteVNpbXBsZSA9IG5ldwogKiAgICAgICAgICAgIFJ1bGVCYXNlZENvbGxhdG9yKCIgJmx0OyBhICZsdDsgYiAmbHQ7IGQgJiBiICZsdDsgYyIsIHN0YXR1cyk7CiAqIFxlbmRjb2RlCiAqIDwvcHJlPgogKiBCZWNhdXNlICIgJmx0OyBhICZsdDsgYiAmbHQ7IGMgJmx0OyBkIiBpcyB0aGUgc2FtZSBhcyAiYSAmbHQ7IGIgJmx0OyBkICYgYiAKICogICAgICAgICAgJmx0OyBjIiBvciAiJmx0OyBhICZsdDsgYiAmIGIgJmx0OyBjICYgYyAmbHQ7IGQiLgogKgogKiA8cD5UbyBjb21iaW5lIGNvbGxhdGlvbnMgZnJvbSB0d28gbG9jYWxlcywgKHdpdGhvdXQgZXJyb3IgaGFuZGxpbmcgZm9yIAogKiBjbGFyaXR5KQogKiA8cHJlPgogKiBcY29kZQogKiAgICAgLy8gQ3JlYXRlIGFuIGVuX1VTIENvbGxhdG9yIG9iamVjdAogKiAgICAgTG9jYWxlIGxvY2FsZV9lbl9VUygiZW4iLCAiVVMiLCAiIik7CiAqICAgICBSdWxlQmFzZWRDb2xsYXRvciogZW5fVVNDb2xsYXRvciA9IChSdWxlQmFzZWRDb2xsYXRvciopCiAqICAgICAgICAgQ29sbGF0b3I6OmNyZWF0ZUluc3RhbmNlKCBsb2NhbGVfZW5fVVMsIHN1Y2Nlc3MgKTsKICogCiAqICAgICAvLyBDcmVhdGUgYSBkYV9ESyBDb2xsYXRvciBvYmplY3QKICogICAgIExvY2FsZSBsb2NhbGVfZGFfREsoImRhIiwgIkRLIiwgIiIpOwogKiAgICAgUnVsZUJhc2VkQ29sbGF0b3IqIGRhX0RLQ29sbGF0b3IgPSAoUnVsZUJhc2VkQ29sbGF0b3IqKQogKiAgICAgICAgIENvbGxhdG9yOjpjcmVhdGVJbnN0YW5jZSggbG9jYWxlX2RhX0RLLCBzdWNjZXNzICk7CiAqIAogKiAgICAgLy8gQ29tYmluZSB0aGUgdHdvCiAqICAgICAvLyBGaXJzdCwgZ2V0IHRoZSBjb2xsYXRpb24gcnVsZXMgZnJvbSBlbl9VU0NvbGxhdG9yCiAqICAgICBVbmljb2RlU3RyaW5nIHJ1bGVzID0gZW5fVVNDb2xsYXRvci0+Z2V0UnVsZXMoKTsKICogICAgIC8vIFNlY29uZCwgZ2V0IHRoZSBjb2xsYXRpb24gcnVsZXMgZnJvbSBkYV9ES0NvbGxhdG9yCiAqICAgICBydWxlcyArPSBkYV9ES0NvbGxhdG9yLT5nZXRSdWxlcygpOwogKiAgICAgUnVsZUJhc2VkQ29sbGF0b3IqIG5ld0NvbGxhdG9yID0gCiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFJ1bGVCYXNlZENvbGxhdG9yKHJ1bGVzLCBzdWNjZXNzKTsKICogICAgIC8vIG5ld0NvbGxhdG9yIGhhcyB0aGUgY29tYmluZWQgcnVsZXMKICogXGVuZGNvZGUKICogPC9wcmU+CiAqIDxwPkFub3RoZXIgbW9yZSBpbnRlcmVzdGluZyBleGFtcGxlIHdvdWxkIGJlIHRvIG1ha2UgY2hhbmdlcyBvbiBhbiBleGlzdGluZwogKiB0YWJsZSB0byBjcmVhdGUgYSBuZXcgY29sbGF0aW9uIG9iamVjdC4gIEZvciBleGFtcGxlLCBhZGQKICogIiYgQyAmbHQ7IGNoLCBjSCwgQ2gsIENIIiB0byB0aGUgZW5fVVNDb2xsYXRpb24gb2JqZWN0IHRvIGNyZWF0ZSB5b3VyIG93bgogKiBFbmdsaXNoIGNvbGxhdGlvbiBvYmplY3QsCiAqIDxwcmU+CiAqIFxjb2RlCiAqICAgICAvLyBDcmVhdGUgYSBuZXcgQ29sbGF0b3Igb2JqZWN0IHdpdGggYWRkaXRpb25hbCBydWxlcwogKiAgICAgcnVsZXMgPSBlbl9VU0NvbGxhdG9yLT5nZXRSdWxlcygpOwogKiAgICAgcnVsZXMgKz0gIiYgQyA8IGNoLCBjSCwgQ2gsIENIIjsKICogICAgIFJ1bGVCYXNlZENvbGxhdG9yKiBteUNvbGxhdG9yID0gCiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFJ1bGVCYXNlZENvbGxhdG9yKHJ1bGVzLCBzdWNjZXNzKTsKICogICAgIC8vIG15Q29sbGF0b3IgY29udGFpbnMgdGhlIG5ldyBydWxlcwogKiBcZW5kY29kZQogKiA8L3ByZT4KICoKICogPHA+VGhlIGZvbGxvd2luZyBleGFtcGxlIGRlbW9uc3RyYXRlcyBob3cgdG8gY2hhbmdlIHRoZSBvcmRlciBvZgogKiBub24tc3BhY2luZyBhY2NlbnRzLAogKiA8cHJlPgogKiBcY29kZQogKiAgICAgIFVDaGFyIGNvbnRlbnRzW10gPSB7CiAqICAgICAgICAgICc9JywgMHgwMzAxLCAnOycsIDB4MDMwMCwgJzsnLCAweDAzMDIsCiAqICAgICAgICAgICc7JywgMHgwMzA4LCAnOycsIDB4MDMyNywgJywnLCAweDAzMDMsICAgIC8vIG1haW4gYWNjZW50cwogKiAgICAgICAgICAnOycsIDB4MDMwNCwgJzsnLCAweDAzMDUsICc7JywgMHgwMzA2LCAgICAvLyBtYWluIGFjY2VudHMKICogICAgICAgICAgJzsnLCAweDAzMDcsICc7JywgMHgwMzA5LCAnOycsIDB4MDMwQSwgICAgLy8gbWFpbiBhY2NlbnRzCiAqICAgICAgICAgICc7JywgMHgwMzBCLCAnOycsIDB4MDMwQywgJzsnLCAweDAzMEQsICAgIC8vIG1haW4gYWNjZW50cwogKiAgICAgICAgICAnOycsIDB4MDMwRSwgJzsnLCAweDAzMEYsICc7JywgMHgwMzEwLCAgICAvLyBtYWluIGFjY2VudHMKICogICAgICAgICAgJzsnLCAweDAzMTEsICc7JywgMHgwMzEyLCAgICAgICAgICAgICAgICAgLy8gbWFpbiBhY2NlbnRzCiAqICAgICAgICAgICc8JywgJ2EnLCAnLCcsICdBJywgJzsnLCAnYScsICdlJywgJywnLCAnQScsICdFJywKICogICAgICAgICAgJzsnLCAweDAwZTYsICcsJywgMHgwMGM2LCAnPCcsICdiJywgJywnLCAnQicsCiAqICAgICAgICAgICc8JywgJ2MnLCAnLCcsICdDJywgJzwnLCAnZScsICcsJywgJ0UnLCAnJicsIAogKiAgICAgICAgICAnQycsICc8JywgJ2QnLCAnLCcsICdEJywgMCB9OwogKiAgICAgIFVuaWNvZGVTdHJpbmcgb2xkUnVsZXMoY29udGVudHMpOwogKiAgICAgIFVFcnJvckNvZGUgc3RhdHVzID0gVV9aRVJPX0VSUk9SOwogKiAgICAgIC8vIGNoYW5nZSB0aGUgb3JkZXIgb2YgYWNjZW50IGNoYXJhY3RlcnMKICogICAgICBVQ2hhciBhZGRPbltdID0geyAnJicsICcsJywgMHgwMzAwLCAnOycsIDB4MDMwOCwgJzsnLCAweDAzMDIsIDAgfTsKICogICAgICBvbGRSdWxlcyArPSBhZGRPbjsKICogICAgICBSdWxlQmFzZWRDb2xsYXRvciAqbXlDb2xsYXRpb24gPSAKICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFJ1bGVCYXNlZENvbGxhdG9yKG9sZFJ1bGVzLCBzdGF0dXMpOwogKiAgXGVuZGNvZGUKICogPC9wcmU+CiAqCiAqIDxwPiBUaGUgbGFzdCBleGFtcGxlIHNob3dzIGhvdyB0byBwdXQgbmV3IHByaW1hcnkgb3JkZXJpbmcgaW4gYmVmb3JlIHRoZQogKiBkZWZhdWx0IHNldHRpbmcuIEZvciBleGFtcGxlLCBpbiBKYXBhbmVzZSBjb2xsYXRpb24sIHlvdSBjYW4gZWl0aGVyIHNvcnQKICogRW5nbGlzaCBjaGFyYWN0ZXJzIGJlZm9yZSBvciBhZnRlciBKYXBhbmVzZSBjaGFyYWN0ZXJzLAogKiA8cHJlPgogKiBcY29kZQogKiAgICAgIFVFcnJvckNvZGUgc3RhdHVzID0gVV9aRVJPX0VSUk9SOwogKiAgICAgIC8vIGdldCBlbl9VUyBjb2xsYXRpb24gcnVsZXMKICogICAgICBSdWxlQmFzZWRDb2xsYXRvciogZW5fVVNDb2xsYXRpb24gPSAoUnVsZUJhc2VkQ29sbGF0b3IqKSAKICogICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvbGxhdG9yOjpjcmVhdGVJbnN0YW5jZShMb2NhbGU6OlVTLCBzdGF0dXMpOwogKiAgICAgIC8vIEFsd2F5cyBjaGVjayB0aGUgZXJyb3IgY29kZSBhZnRlciBlYWNoIGNhbGwuCiAqICAgICAgaWYgKFVfRkFJTFVSRShzdGF0dXMpKSByZXR1cm47CiAqICAgICAgLy8gYWRkIGEgZmV3IEphcGFuZXNlIGNoYXJhY3RlciB0byBzb3J0IGJlZm9yZSBFbmdsaXNoIGNoYXJhY3RlcnMKICogICAgICAvLyBzdXBwb3NlIHRoZSBsYXN0IGNoYXJhY3RlciBiZWZvcmUgdGhlIGZpcnN0IGJhc2UgbGV0dGVyICdhJyBpbgogKiAgICAgIC8vIHRoZSBFbmdsaXNoIGNvbGxhdGlvbiBydWxlIGlzIDB4MjIxMgogKiAgICAgIFVDaGFyIGphU3RyaW5nW10gPSB7JyYnLCAweDIyMTIsICcmbHQ7JywgMHgzMDQxLCAnLCcsIDB4MzA0MiwgJyZsdDsnLCAKICogICAgICAgICAgICAgICAgICAgICAgICAgIDB4MzA0MywgJywnLCAweDMwNDQsIDB9OwogKiAgICAgIFVuaWNvZGVTdHJpbmcgcnVsZXMoZW5fVVNDb2xsYXRpb24tPmdldFJ1bGVzKCkpOwogKiAgICAgIHJ1bGVzICs9IGphU3RyaW5nOwogKiAgICAgIFJ1bGVCYXNlZENvbGxhdG9yICpteUphcGFuZXNlQ29sbGF0aW9uID0gCiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBSdWxlQmFzZWRDb2xsYXRvcihydWxlcywgc3RhdHVzKTsKICogXGVuZGNvZGUKICogPC9wcmU+CiAqIDxwPjxzdHJvbmc+Tk9URTwvc3Ryb25nPjogVHlwaWNhbGx5LCBhIGNvbGxhdGlvbiBvYmplY3QgaXMgY3JlYXRlZCB3aXRoCiAqIENvbGxhdG9yOjpjcmVhdGVJbnN0YW5jZSgpLgogKiA8cD4KICogPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiA8Y29kZT5SdWxlQmFzZWRDb2xsYXRvcjwvY29kZT5zIHdpdGggZGlmZmVyZW50IAogKiBMb2NhbGUsIENvbGxhdGlvblN0cmVuZ3RoIGFuZCBEZWNvbXBvc2l0aW9uIG1vZGUgc2V0dGluZ3Mgd2lsbCByZXR1cm4gCiAqIGRpZmZlcmVudCBzb3J0IG9yZGVycyBmb3IgdGhlIHNhbWUgc2V0IG9mIHN0cmluZ3MuIExvY2FsZXMgaGF2ZSBzcGVjaWZpYyAKICogY29sbGF0aW9uIHJ1bGVzLCBhbmQgdGhlIHdheSBpbiB3aGljaCBzZWNvbmRhcnkgYW5kIHRlcnRpYXJ5IGRpZmZlcmVuY2VzIAogKiBhcmUgdGFrZW4gaW50byBhY2NvdW50LCBmb3IgZXhhbXBsZSwgd2lsbCByZXN1bHQgaW4gYSBkaWZmZXJlbnQgc29ydGluZyAKICogb3JkZXIgZm9yIHNhbWUgc3RyaW5ncy4KICogPHA+CiAqIEBzZWUgICAgICAgIENvbGxhdG9yCiAqIEB2ZXJzaW9uICAgIDEuOCBKYW4gOCAyMDAxCiAqLwpjbGFzcyBVX0kxOE5fQVBJIFJ1bGVCYXNlZENvbGxhdG9yIDogcHVibGljIENvbGxhdG9yIAp7CnB1YmxpYzogCgogIC8vIGNvbnN0cnVjdG9yIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgLyoqCiAgICogUnVsZUJhc2VkQ29sbGF0b3IgY29uc3RydWN0b3IuIFRoaXMgdGFrZXMgdGhlIHRhYmxlIHJ1bGVzIGFuZCBidWlsZHMgYSAKICAgKiBjb2xsYXRpb24gdGFibGUgb3V0IG9mIHRoZW0uIFBsZWFzZSBzZWUgUnVsZUJhc2VkQ29sbGF0b3IgY2xhc3MKICAgKiBkZXNjcmlwdGlvbiBmb3IgbW9yZSBkZXRhaWxzIG9uIHRoZSBjb2xsYXRpb24gcnVsZSBzeW50YXguCiAgICogQHBhcmFtIHJ1bGVzIHRoZSBjb2xsYXRpb24gcnVsZXMgdG8gYnVpbGQgdGhlIGNvbGxhdGlvbiB0YWJsZSBmcm9tLgogICAqIEBwYXJhbSBzdGF0dXMgcmVwb3J0aW5nIGEgc3VjY2VzcyBvciBhbiBlcnJvci4KICAgKiBAc2VlIExvY2FsZQogICAqLwoJUnVsZUJhc2VkQ29sbGF0b3IoY29uc3QgVW5pY29kZVN0cmluZyYgcnVsZXMsIFVFcnJvckNvZGUmIHN0YXR1cyk7CgogIC8qKgogICAqIFJ1bGVCYXNlZENvbGxhdG9yIGNvbnN0cnVjdG9yLiBUaGlzIHRha2VzIHRoZSB0YWJsZSBydWxlcyBhbmQgYnVpbGRzIGEgCiAgICogY29sbGF0aW9uIHRhYmxlIG91dCBvZiB0aGVtLiBQbGVhc2Ugc2VlIFJ1bGVCYXNlZENvbGxhdG9yIGNsYXNzCiAgICogZGVzY3JpcHRpb24gZm9yIG1vcmUgZGV0YWlscyBvbiB0aGUgY29sbGF0aW9uIHJ1bGUgc3ludGF4LgogICAqIEBwYXJhbSBydWxlcyB0aGUgY29sbGF0aW9uIHJ1bGVzIHRvIGJ1aWxkIHRoZSBjb2xsYXRpb24gdGFibGUgZnJvbS4KICAgKiBAcGFyYW0gY29sbGF0aW9uU3RyZW5ndGggZGVmYXVsdCBzdHJlbmd0aCBmb3IgY29tcGFyaXNvbgogICAqIEBwYXJhbSBzdGF0dXMgcmVwb3J0aW5nIGEgc3VjY2VzcyBvciBhbiBlcnJvci4KICAgKiBAc2VlIExvY2FsZQogICAqLwogIFJ1bGVCYXNlZENvbGxhdG9yKGNvbnN0IFVuaWNvZGVTdHJpbmcmIHJ1bGVzLCAKICAgICAgICAgICAgICAgICAgICAgICBFQ29sbGF0aW9uU3RyZW5ndGggY29sbGF0aW9uU3RyZW5ndGgsIAogICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cyk7CgogIC8qKgogICAqIFJ1bGVCYXNlZENvbGxhdG9yIGNvbnN0cnVjdG9yLiBUaGlzIHRha2VzIHRoZSB0YWJsZSBydWxlcyBhbmQgYnVpbGRzIGEgCiAgICogY29sbGF0aW9uIHRhYmxlIG91dCBvZiB0aGVtLiBQbGVhc2Ugc2VlIFJ1bGVCYXNlZENvbGxhdG9yIGNsYXNzCiAgICogZGVzY3JpcHRpb24gZm9yIG1vcmUgZGV0YWlscyBvbiB0aGUgY29sbGF0aW9uIHJ1bGUgc3ludGF4LgogICAqIEBwYXJhbSBydWxlcyB0aGUgY29sbGF0aW9uIHJ1bGVzIHRvIGJ1aWxkIHRoZSBjb2xsYXRpb24gdGFibGUgZnJvbS4KICAgKiBAcGFyYW0gZGVjb21wb3NpdGlvbk1vZGUgdGhlIG5vcm1hbGlzYXRpb24gbW9kZQogICAqIEBwYXJhbSBzdGF0dXMgcmVwb3J0aW5nIGEgc3VjY2VzcyBvciBhbiBlcnJvci4KICAgKiBAc2VlIExvY2FsZQogICAqLwogIFJ1bGVCYXNlZENvbGxhdG9yKGNvbnN0IFVuaWNvZGVTdHJpbmcmIHJ1bGVzLAogICAgICAgICAgICAgICAgICAgIE5vcm1hbGl6ZXI6OkVNb2RlIGRlY29tcG9zaXRpb25Nb2RlLCAKICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiBzdGF0dXMpOwoKICAvKioKICAgKiBSdWxlQmFzZWRDb2xsYXRvciBjb25zdHJ1Y3Rvci4gVGhpcyB0YWtlcyB0aGUgdGFibGUgcnVsZXMgYW5kIGJ1aWxkcyBhIAogICAqIGNvbGxhdGlvbiB0YWJsZSBvdXQgb2YgdGhlbS4gUGxlYXNlIHNlZSBSdWxlQmFzZWRDb2xsYXRvciBjbGFzcwogICAqIGRlc2NyaXB0aW9uIGZvciBtb3JlIGRldGFpbHMgb24gdGhlIGNvbGxhdGlvbiBydWxlIHN5bnRheC4KICAgKiBAcGFyYW0gcnVsZXMgdGhlIGNvbGxhdGlvbiBydWxlcyB0byBidWlsZCB0aGUgY29sbGF0aW9uIHRhYmxlIGZyb20uCiAgICogQHBhcmFtIGNvbGxhdGlvblN0cmVuZ3RoIGRlZmF1bHQgc3RyZW5ndGggZm9yIGNvbXBhcmlzb24KICAgKiBAcGFyYW0gZGVjb21wb3NpdGlvbk1vZGUgdGhlIG5vcm1hbGlzYXRpb24gbW9kZQogICAqIEBwYXJhbSBzdGF0dXMgcmVwb3J0aW5nIGEgc3VjY2VzcyBvciBhbiBlcnJvci4KICAgKiBAc2VlIExvY2FsZQogICAqLwogIFJ1bGVCYXNlZENvbGxhdG9yKGNvbnN0IFVuaWNvZGVTdHJpbmcmIHJ1bGVzLCAKICAgICAgICAgICAgICAgICAgICBFQ29sbGF0aW9uU3RyZW5ndGggY29sbGF0aW9uU3RyZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgTm9ybWFsaXplcjo6RU1vZGUgZGVjb21wb3NpdGlvbk1vZGUsCiAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYgc3RhdHVzKTsKCiAgLyoqIAogICAqIENvcHkgY29uc3RydWN0b3IuCiAgICogQHBhcmFtIHRoZSBSdWxlQmFzZWRDb2xsYXRvciBvYmplY3QgdG8gYmUgY29waWVkCiAgICogQHNlZSBMb2NhbGUKICAgKi8KCVJ1bGVCYXNlZENvbGxhdG9yKGNvbnN0IFJ1bGVCYXNlZENvbGxhdG9yJiBvdGhlcik7CgogIC8vIGRlc3RydWN0b3IgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgLyoqIAogICAqIERlc3RydWN0b3IuCiAgICovCgl2aXJ0dWFsIH5SdWxlQmFzZWRDb2xsYXRvcigpOwoKICAvLyBwdWJsaWMgbWV0aG9kcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogIC8qKgogICAqIEFzc2lnbm1lbnQgb3BlcmF0b3IuCiAgICogQHBhcmFtIG90aGVyIG90aGVyIFJ1bGVCYXNlZENvbGxhdG9yIG9iamVjdCB0byBjb21wYXJlIHdpdGguCiAgICovCglSdWxlQmFzZWRDb2xsYXRvciYgb3BlcmF0b3I9KGNvbnN0IFJ1bGVCYXNlZENvbGxhdG9yJiBvdGhlcik7CiAgICAKICAvKioKICAgKiBSZXR1cm5zIHRydWUgaWYgYXJndW1lbnQgaXMgdGhlIHNhbWUgYXMgdGhpcyBvYmplY3QuCiAgICogQHBhcmFtIG90aGVyIENvbGxhdG9yIG9iamVjdCB0byBiZSBjb21wYXJlZC4KICAgKiBAcmV0dXJuIHRydWUgaWYgYXJndW1lbnRzIGlzIHRoZSBzYW1lIGFzIHRoaXMgb2JqZWN0LgogICAqLwogIHZpcnR1YWwgVUJvb2wgb3BlcmF0b3I9PShjb25zdCBDb2xsYXRvciYgb3RoZXIpIGNvbnN0OwoKICAvKioKICAgKiBSZXR1cm5zIHRydWUgaWYgYXJndW1lbnQgaXMgbm90IHRoZSBzYW1lIGFzIHRoaXMgb2JqZWN0LgogICAqIEBwYXJhbSBvdGhlciBDb2xsYXRvciBvYmplY3QgdG8gYmUgY29tcGFyZWQKICAgKiBAcmV0dXJuIHJldHVybnMgdHJ1ZSBpZiBhcmd1bWVudCBpcyBub3QgdGhlIHNhbWUgYXMgdGhpcyBvYmplY3QuCiAgICovCiAgdmlydHVhbCBVQm9vbCBvcGVyYXRvciE9KGNvbnN0IENvbGxhdG9yJiBvdGhlcikgY29uc3Q7CgogIC8qKgogICAqIE1ha2VzIGEgZGVlcCBjb3B5IG9mIHRoZSBvYmplY3QuIAogICAqIFRoZSBjYWxsZXIgb3ducyB0aGUgcmV0dXJuZWQgb2JqZWN0LgogICAqIEByZXR1cm4gdGhlIGNsb25lZCBvYmplY3QuCiAgICovCiAgdmlydHVhbCBDb2xsYXRvciogY2xvbmUodm9pZCkgY29uc3Q7CgogIC8qKgogICAqIENyZWF0ZXMgYSBjb2xsYXRpb24gZWxlbWVudCBpdGVyYXRvciBmb3IgdGhlIHNvdXJjZSBzdHJpbmcuIFRoZSBjYWxsZXIgb2YgCiAgICogdGhpcyBtZXRob2QgaXMgcmVzcG9uc2libGUgZm9yIHRoZSBtZW1vcnkgbWFuYWdlbWVudCBvZiB0aGUgcmV0dXJuIAogICAqIHBvaW50ZXIuCiAgICogQHBhcmFtIHNvdXJjZSB0aGUgc3RyaW5nIG92ZXIgd2hpY2ggdGhlIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciB3aWxsIAogICAqICAgICAgICBpdGVyYXRlLgogICAqIEByZXR1cm4gdGhlIGNvbGxhdGlvbiBlbGVtZW50IGl0ZXJhdG9yIG9mIHRoZSBzb3VyY2Ugc3RyaW5nIHVzaW5nIHRoaXMgYXMKICAgKiAgICAgICAgIHRoZSBiYXNlZCBDb2xsYXRvci4KICAgKi8KCXZpcnR1YWwgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yKiBjcmVhdGVDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBVbmljb2RlU3RyaW5nJiBzb3VyY2UpIGNvbnN0OwoKICAvKioKICAgKiBDcmVhdGVzIGEgY29sbGF0aW9uIGVsZW1lbnQgaXRlcmF0b3IgZm9yIHRoZSBzb3VyY2UuIFRoZSBjYWxsZXIgb2YgdGhpcyAKICAgKiBtZXRob2QgaXMgcmVzcG9uc2libGUgZm9yIHRoZSBtZW1vcnkgbWFuYWdlbWVudCBvZiB0aGUgcmV0dXJuZWQgcG9pbnRlci4KICAgKiBAcGFyYW0gc291cmNlIHRoZSBDaGFyYWN0ZXJJdGVyYXRvciB3aGljaCBwcm9kdWNlcyB0aGUgY2hhcmFjdGVycyBvdmVyIAogICAqICAgICAgICB3aGljaCB0aGUgQ29sbGF0aW9uRWxlbWVudEl0Z2VyYXRvciB3aWxsIGl0ZXJhdGUuCiAgICogQHJldHVybiB0aGUgY29sbGF0aW9uIGVsZW1lbnQgaXRlcmF0b3Igb2YgdGhlIHNvdXJjZSB1c2luZyB0aGlzIGFzIHRoZSAKICAgKiAgICAgICAgIGJhc2VkIENvbGxhdG9yLgogICAqLwogIHZpcnR1YWwgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yKiBjcmVhdGVDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IENoYXJhY3Rlckl0ZXJhdG9yJiBzb3VyY2UpIGNvbnN0OwoKICAvKioKICAgKiBDb21wYXJlcyBhIHJhbmdlIG9mIGNoYXJhY3RlciBkYXRhIHN0b3JlZCBpbiB0d28gZGlmZmVyZW50IHN0cmluZ3MgYmFzZWQgCiAgICogb24gdGhlIGNvbGxhdGlvbiBydWxlcy4gUmV0dXJucyBpbmZvcm1hdGlvbiBhYm91dCB3aGV0aGVyIGEgc3RyaW5nIGlzIAogICAqIGxlc3MgdGhhbiwgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIGFub3RoZXIgc3RyaW5nIGluIGEgbGFuZ3VhZ2UuCiAgICogVGhpcyBjYW4gYmUgb3ZlcnJpZGVuIGluIGEgc3ViY2xhc3MuCiAgICogQHBhcmFtIHNvdXJjZSB0aGUgc291cmNlIHN0cmluZy4KICAgKiBAcGFyYW0gdGFyZ2V0IHRoZSB0YXJnZXQgc3RyaW5nIHRvIGJlIGNvbXBhcmVkIHdpdGggdGhlIHNvdXJjZSBzdHJpbmcuCiAgICogQHJldHVybiB0aGUgY29tcGFyaXNvbiByZXN1bHQuIEdSRUFURVIgaWYgdGhlIHNvdXJjZSBzdHJpbmcgaXMgZ3JlYXRlcgogICAqICAgICAgICAgdGhhbiB0aGUgdGFyZ2V0IHN0cmluZywgTEVTUyBpZiB0aGUgc291cmNlIGlzIGxlc3MgdGhhbiB0aGUgCiAgICogICAgICAgICB0YXJnZXQuIE90aGVyd2lzZSwgcmV0dXJucyBFUVVBTC4KICAgKi8KICB2aXJ0dWFsIEVDb21wYXJpc29uUmVzdWx0IGNvbXBhcmUoY29uc3QgVW5pY29kZVN0cmluZyYgc291cmNlLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVW5pY29kZVN0cmluZyYgdGFyZ2V0KSBjb25zdDsKICAgICAgICAKICAgICAgICAKICAvKioKICAgKiBDb21wYXJlcyBhIHJhbmdlIG9mIGNoYXJhY3RlciBkYXRhIHN0b3JlZCBpbiB0d28gZGlmZmVyZW50IHN0cmluZ3MgYmFzZWQgCiAgICogb24gdGhlIGNvbGxhdGlvbiBydWxlcyB1cCB0byB0aGUgc3BlY2lmaWVkIGxlbmd0aC4gUmV0dXJucyBpbmZvcm1hdGlvbiAKICAgKiBhYm91dCB3aGV0aGVyIGEgc3RyaW5nIGlzIGxlc3MgdGhhbiwgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIGFub3RoZXIgCiAgICogc3RyaW5nIGluIGEgbGFuZ3VhZ2UuIFRoaXMgY2FuIGJlIG92ZXJyaWRlbiBpbiBhIHN1YmNsYXNzLgogICAqIEBwYXJhbSBzb3VyY2UgdGhlIHNvdXJjZSBzdHJpbmcuCiAgICogQHBhcmFtIHRhcmdldCB0aGUgdGFyZ2V0IHN0cmluZyB0byBiZSBjb21wYXJlZCB3aXRoIHRoZSBzb3VyY2Ugc3RyaW5nLgogICAqIEBwYXJhbSBsZW5ndGggY29tcGFyZXMgdXAgdG8gdGhlIHNwZWNpZmllZCBsZW5ndGgKICAgKiBAcmV0dXJuIHRoZSBjb21wYXJpc29uIHJlc3VsdC4gR1JFQVRFUiBpZiB0aGUgc291cmNlIHN0cmluZyBpcyBncmVhdGVyCiAgICogICAgICAgICB0aGFuIHRoZSB0YXJnZXQgc3RyaW5nLCBMRVNTIGlmIHRoZSBzb3VyY2UgaXMgbGVzcyB0aGFuIHRoZSAKICAgKiAgICAgICAgIHRhcmdldC4gT3RoZXJ3aXNlLCByZXR1cm5zIEVRVUFMLgogICAqLyAKICB2aXJ0dWFsIEVDb21wYXJpc29uUmVzdWx0IGNvbXBhcmUoY29uc3QgVW5pY29kZVN0cmluZyYgc291cmNlLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVW5pY29kZVN0cmluZyYgIHRhcmdldCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50MzJfdCBsZW5ndGgpIGNvbnN0OwoKICAvKioKICAgKiBUaGUgY29tcGFyaXNvbiBmdW5jdGlvbiBjb21wYXJlcyB0aGUgY2hhcmFjdGVyIGRhdGEgc3RvcmVkIGluIHR3bwogICAqIGRpZmZlcmVudCBzdHJpbmcgYXJyYXlzLiBSZXR1cm5zIGluZm9ybWF0aW9uIGFib3V0IHdoZXRoZXIgYSBzdHJpbmcgYXJyYXkgCiAgICogaXMgbGVzcyB0aGFuLCBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gYW5vdGhlciBzdHJpbmcgYXJyYXkuCiAgICogPHA+RXhhbXBsZSBvZiB1c2U6CiAgICogPHByZT4KICAgKiAuICAgICAgIFVFcnJvckNvZGUgc3RhdHVzID0gVV9aRVJPX0VSUk9SOwogICAqIC4gICAgICAgQ29sbGF0b3IgKm15Q29sbGF0aW9uID0gCiAgICogLiAgICAgICAgICAgICAgICAgICAgICAgICBDb2xsYXRvcjo6Y3JlYXRlSW5zdGFuY2UoTG9jYWxlOjpVUywgc3RhdHVzKTsKICAgKiAuICAgICAgIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkgcmV0dXJuOwogICAqIC4gICAgICAgbXlDb2xsYXRpb24tPnNldFN0cmVuZ3RoKENvbGxhdG9yOjpQUklNQVJZKTsKICAgKiAuICAgICAgIC8vIHJlc3VsdCB3b3VsZCBiZSBDb2xsYXRvcjo6RVFVQUwgKCJhYmMiID09ICJBQkMiKQogICAqIC4gICAgICAgLy8gKG5vIHByaW1hcnkgZGlmZmVyZW5jZSBiZXR3ZWVuICJhYmMiIGFuZCAiQUJDIikKICAgKiAuICAgICAgIENvbGxhdG9yOjpVQ29sbGF0aW9uUmVzdWx0IHJlc3VsdCA9IAogICAqIC4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBteUNvbGxhdGlvbi0+Y29tcGFyZShMImFiYyIsIDMsIEwiQUJDIiwgMyk7CiAgICogLiAgICAgICBteUNvbGxhdGlvbi0+c2V0U3RyZW5ndGgoQ29sbGF0b3I6OlRFUlRJQVJZKTsKICAgKiAuICAgICAgIC8vIHJlc3VsdCB3b3VsZCBiZSBDb2xsYXRvcjo6TEVTUyAoYWJjIiAmbHQ7Jmx0OyZsdDsgIkFCQyIpCiAgICogLiAgICAgICAvLyAod2l0aCB0ZXJ0aWFyeSBkaWZmZXJlbmNlIGJldHdlZW4gImFiYyIgYW5kICJBQkMiKQogICAqIC4gICAgICAgQ29sbGF0b3I6OlVDb2xsYXRpb25SZXN1bHQgcmVzdWx0ID0gCiAgICogLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG15Q29sbGF0aW9uLT5jb21wYXJlKEwiYWJjIiwgMywgTCJBQkMiLCAzKTsKICAgKiA8L3ByZT4KICAgKiBAcGFyYW0gc291cmNlIHRoZSBzb3VyY2Ugc3RyaW5nIGFycmF5IHRvIGJlIGNvbXBhcmVkIHdpdGguCiAgICogQHBhcmFtIHNvdXJjZUxlbmd0aCB0aGUgbGVuZ3RoIG9mIHRoZSBzb3VyY2Ugc3RyaW5nIGFycmF5LiBJZiB0aGlzIHZhbHVlCiAgICogICAgICAgIGlzIGVxdWFsIHRvIC0xLCB0aGUgc3RyaW5nIGFycmF5IGlzIG51bGwtdGVybWluYXRlZC4KICAgKiBAcGFyYW0gdGFyZ2V0IHRoZSBzdHJpbmcgdGhhdCBpcyB0byBiZSBjb21wYXJlZCB3aXRoIHRoZSBzb3VyY2Ugc3RyaW5nLgogICAqIEBwYXJhbSB0YXJnZXRMZW5ndGggdGhlIGxlbmd0aCBvZiB0aGUgdGFyZ2V0IHN0cmluZyBhcnJheS4gSWYgdGhpcyB2YWx1ZQogICAqICAgICAgICBpcyBlcXVhbCB0byAtMSwgdGhlIHN0cmluZyBhcnJheSBpcyBudWxsLXRlcm1pbmF0ZWQuCiAgICogQHJldHVybiBSZXR1cm5zIGEgYnl0ZSB2YWx1ZS4gR1JFQVRFUiBpZiBzb3VyY2UgaXMgZ3JlYXRlciB0aGFuIHRhcmdldDsgCiAgICogICAgICAgICBFUVVBTCBpZiBzb3VyY2UgaXMgZXF1YWwgdG8gdGFyZ2V0OyBMRVNTIGlmIHNvdXJjZSBpcyBsZXNzIHRoYW4gCiAgICogICAgICAgICB0YXJnZXQKICAgKi8KICB2aXJ0dWFsIEVDb21wYXJpc29uUmVzdWx0IGNvbXBhcmUoY29uc3QgVUNoYXIqIHNvdXJjZSwgaW50MzJfdCBzb3VyY2VMZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFVDaGFyKiB0YXJnZXQsIGludDMyX3QgdGFyZ2V0TGVuZ3RoKSAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Q7CgogIC8qKiAKICAqIFRyYW5zZm9ybXMgYSBzcGVjaWZpZWQgcmVnaW9uIG9mIHRoZSBzdHJpbmcgaW50byBhIHNlcmllcyBvZiBjaGFyYWN0ZXJzCiAgKiB0aGF0IGNhbiBiZSBjb21wYXJlZCB3aXRoIENvbGxhdGlvbktleS5jb21wYXJlLiBVc2UgYSBDb2xsYXRpb25LZXkgd2hlbiAKICAqIHlvdSBuZWVkIHRvIGRvIHJlcGVhdGVkIGNvbXBhcmlzaW9ucyBvbiB0aGUgc2FtZSBzdHJpbmcuIEZvciBhIHNpbmdsZSAKICAqIGNvbXBhcmlzb24gdGhlIGNvbXBhcmUgbWV0aG9kIHdpbGwgYmUgZmFzdGVyLgogICogQHBhcmFtIHNvdXJjZSB0aGUgc291cmNlIHN0cmluZy4KICAqIEBwYXJhbSBrZXkgdGhlIHRyYW5zZm9ybWVkIGtleSBvZiB0aGUgc291cmNlIHN0cmluZy4KICAqIEBwYXJhbSBzdGF0dXMgdGhlIGVycm9yIGNvZGUgc3RhdHVzLgogICogQHJldHVybiB0aGUgdHJhbnNmb3JtZWQga2V5LgogICogQHNlZSBDb2xsYXRpb25LZXkKICAqLwogIHZpcnR1YWwgQ29sbGF0aW9uS2V5JiBnZXRDb2xsYXRpb25LZXkoY29uc3QgVW5pY29kZVN0cmluZyYgc291cmNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29sbGF0aW9uS2V5JiBrZXksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiBzdGF0dXMpIGNvbnN0OwoKICAvKiogCiAgKiBUcmFuc2Zvcm1zIGEgc3BlY2lmaWVkIHJlZ2lvbiBvZiB0aGUgc3RyaW5nIGludG8gYSBzZXJpZXMgb2YgY2hhcmFjdGVycwogICogdGhhdCBjYW4gYmUgY29tcGFyZWQgd2l0aCBDb2xsYXRpb25LZXkuY29tcGFyZS4gVXNlIGEgQ29sbGF0aW9uS2V5IHdoZW4KICAqIHlvdSBuZWVkIHRvIGRvIHJlcGVhdGVkIGNvbXBhcmlzaW9ucyBvbiB0aGUgc2FtZSBzdHJpbmcuIEZvciBhIHNpbmdsZSAKICAqIGNvbXBhcmlzb24gdGhlIGNvbXBhcmUgbWV0aG9kIHdpbGwgYmUgZmFzdGVyLgogICogQHBhcmFtIHNvdXJjZSB0aGUgc291cmNlIHN0cmluZy4KICAqIEBwYXJhbSBrZXkgdGhlIHRyYW5zZm9ybWVkIGtleSBvZiB0aGUgc291cmNlIHN0cmluZy4KICAqIEBwYXJhbSBzdGF0dXMgdGhlIGVycm9yIGNvZGUgc3RhdHVzLgogICogQHJldHVybiB0aGUgdHJhbnNmb3JtZWQga2V5LgogICogQHNlZSBDb2xsYXRpb25LZXkKICAqLwogIHZpcnR1YWwgQ29sbGF0aW9uS2V5JiBnZXRDb2xsYXRpb25LZXkoY29uc3QgVUNoYXIgKnNvdXJjZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQzMl90IHNvdXJjZUxlbmd0aCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb2xsYXRpb25LZXkmIGtleSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiBzdGF0dXMpIGNvbnN0OwoKICAvKioKICAgKiBHZW5lcmF0ZXMgdGhlIGhhc2ggY29kZSBmb3IgdGhlIHJ1bGUtYmFzZWQgY29sbGF0aW9uIG9iamVjdC4KICAgKiBAcmV0dXJuIHRoZSBoYXNoIGNvZGUuCiAgICovCiAgdmlydHVhbCBpbnQzMl90IGhhc2hDb2RlKHZvaWQpIGNvbnN0OwoKICAvKioKICAgKiBHZXRzIHRoZSB0YWJsZS1iYXNlZCBydWxlcyBmb3IgdGhlIGNvbGxhdGlvbiBvYmplY3QuCiAgICogQHJldHVybiByZXR1cm5zIHRoZSBjb2xsYXRpb24gcnVsZXMgdGhhdCB0aGUgdGFibGUgY29sbGF0aW9uIG9iamVjdCB3YXMgCiAgICogICAgICAgICBjcmVhdGVkIGZyb20uCiAgICovCiAgY29uc3QgVW5pY29kZVN0cmluZyYgZ2V0UnVsZXModm9pZCkgY29uc3Q7CgogIC8qKgogICAqIFJldHVybiB0aGUgbWF4aW11bSBsZW5ndGggb2YgYW55IGV4cGFuc2lvbiBzZXF1ZW5jZXMgdGhhdCBlbmQgd2l0aCB0aGUgCiAgICogc3BlY2lmaWVkIGNvbXBhcmlzb24gb3JkZXIuCiAgICogQHBhcmFtIG9yZGVyIGEgY29sbGF0aW9uIG9yZGVyIHJldHVybmVkIGJ5IHByZXZpb3VzIG9yIG5leHQuCiAgICogQHJldHVybiBtYXhpbXVtIHNpemUgb2YgdGhlIGV4cGFuc2lvbiBzZXF1ZW5jZXMgZW5kaW5nIHdpdGggdGhlIGNvbGxhdGlvbiAKICAgKiAgICAgICAgIGVsZW1lbnQgb3IgMSBpZiBjb2xsYXRpb24gZWxlbWVudCBkb2VzIG5vdCBvY2N1ciBhdCB0aGUgZW5kIG9mIAogICAqICAgICAgICAgYW55IGV4cGFuc2lvbiBzZXF1ZW5jZQogICAqIEBzZWUgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yI2dldE1heEV4cGFuc2lvbgogICAqLwoJaW50MzJfdCBnZXRNYXhFeHBhbnNpb24oaW50MzJfdCBvcmRlcikgY29uc3Q7CgogIC8qKgogICAqIFJldHVybnMgYSB1bmlxdWUgY2xhc3MgSUQgUE9MWU1PUlBISUNBTExZLiBQdXJlIHZpcnR1YWwgb3ZlcnJpZGUuIFRoaXMgCiAgICogbWV0aG9kIGlzIHRvIGltcGxlbWVudCBhIHNpbXBsZSB2ZXJzaW9uIG9mIFJUVEksIHNpbmNlIG5vdCBhbGwgQysrIAogICAqIGNvbXBpbGVycyBzdXBwb3J0IGdlbnVpbmUgUlRUSS4gUG9seW1vcnBoaWMgb3BlcmF0b3I9PSgpIGFuZCBjbG9uZSgpIAogICAqIG1ldGhvZHMgY2FsbCB0aGlzIG1ldGhvZC4KICAgKiBAcmV0dXJuIFRoZSBjbGFzcyBJRCBmb3IgdGhpcyBvYmplY3QuIEFsbCBvYmplY3RzIG9mIGEgZ2l2ZW4gY2xhc3MgaGF2ZSAKICAgKiAgICAgICAgIHRoZSBzYW1lIGNsYXNzIElELiBPYmplY3RzIG9mIG90aGVyIGNsYXNzZXMgaGF2ZSBkaWZmZXJlbnQgY2xhc3MgCiAgICogICAgICAgICBJRHMuCiAgICovCiAgdmlydHVhbCBVQ2xhc3NJRCBnZXREeW5hbWljQ2xhc3NJRCh2b2lkKSBjb25zdAogIHsgCiAgICByZXR1cm4gUnVsZUJhc2VkQ29sbGF0b3I6OmdldFN0YXRpY0NsYXNzSUQoKTsgCiAgfQoKICAvKioKICAgKiBSZXR1cm5zIHRoZSBjbGFzcyBJRCBmb3IgdGhpcyBjbGFzcy4gVGhpcyBpcyB1c2VmdWwgb25seSBmb3IgY29tcGFyaW5nIHRvIAogICAqIGEgcmV0dXJuIHZhbHVlIGZyb20gZ2V0RHluYW1pY0NsYXNzSUQoKS4gRm9yIGV4YW1wbGU6CiAgICogPHByZT4KICAgKiBCYXNlKiBwb2x5bW9ycGhpY19wb2ludGVyID0gY3JlYXRlUG9seW1vcnBoaWNPYmplY3QoKTsKICAgKiBpZiAocG9seW1vcnBoaWNfcG9pbnRlci0+Z2V0RHluYW1pY0NsYXNzSUQoKSA9PSAKICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERlcml2ZWQ6OmdldFN0YXRpY0NsYXNzSUQoKSkgLi4uCiAgICogPC9wcmU+CiAgICogQHJldHVybiBUaGUgY2xhc3MgSUQgZm9yIGFsbCBvYmplY3RzIG9mIHRoaXMgY2xhc3MuCiAgICovCiAgc3RhdGljIFVDbGFzc0lEIGdldFN0YXRpY0NsYXNzSUQodm9pZCkgCiAgeyAKICAgIHJldHVybiAoVUNsYXNzSUQpJmZnQ2xhc3NJRDsgCiAgfQoKICAvKioKICAgKiBSZXR1cm5zIHRoZSBiaW5hcnkgZm9ybWF0IG9mIHRoZSBjbGFzcydzIHJ1bGVzLiBUaGUgZm9ybWF0IGlzIHRoYXQgb2YgCiAgICogLmNvbCBmaWxlcy4gIAogICAqIEBwYXJhbSBsZW5ndGggUmV0dXJucyB0aGUgbGVuZ3RoIG9mIHRoZSBkYXRhLCBpbiBieXRlcwogICAqIEBwYXJhbSBzdGF0dXMgdGhlIGVycm9yIGNvZGUgc3RhdHVzLgogICAqIEByZXR1cm4gbWVtb3J5LCBvd25lZCBieSB0aGUgY2FsbGVyLCBvZiBzaXplICdsZW5ndGgnIGJ5dGVzLgogICAqLwogIHVpbnQ4X3QgKmNsb25lUnVsZURhdGEoaW50MzJfdCAmbGVuZ3RoLCBVRXJyb3JDb2RlICZzdGF0dXMpOwoKCS8qKgoJICogUmV0dXJucyBjdXJyZW50IHJ1bGVzLiBEZWx0YSBkZWZpbmVzIHdoZXRoZXIgZnVsbCBydWxlcyBhcmUgcmV0dXJuZWQgb3IgCiAgICoganVzdCB0aGUgdGFpbG9yaW5nLiAKCSAqIEBwYXJhbSBkZWx0YSBvbmUgb2YgCVVDT0xfVEFJTE9SSU5HX09OTFksIFVDT0xfRlVMTF9SVUxFUy4gCgkgKiBAcmV0dXJuIFVuaWNvZGVTdHJpbmcgd2l0aCBydWxlcwoJICovCglVbmljb2RlU3RyaW5nIGdldFJ1bGVzKFVDb2xSdWxlT3B0aW9uIGRlbHRhKTsKCiAgLyoqCiAgICogVW5pdmVyc2FsIGF0dHJpYnV0ZSBzZXR0ZXIKICAgKiBAcGFyYW0gYXR0ciBhdHRyaWJ1dGUgdHlwZSAKICAgKiBAcGFyYW0gdmFsdWUgYXR0cmlidXRlIHZhbHVlCiAgICogQHBhcmFtIHN0YXR1cyB0byBpbmRpY2F0ZSB3aGV0aGVyIHRoZSBvcGVyYXRpb24gd2VudCBvbiBzbW9vdGhseSBvciB0aGVyZSB3ZXJlIGVycm9ycwogICAqLwogIHZpcnR1YWwgdm9pZCBzZXRBdHRyaWJ1dGUoVUNvbEF0dHJpYnV0ZSBhdHRyLCBVQ29sQXR0cmlidXRlVmFsdWUgdmFsdWUsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSAmc3RhdHVzKTsKCiAgLyoqCiAgICogVW5pdmVyc2FsIGF0dHJpYnV0ZSBnZXR0ZXIuCiAgICogQHBhcmFtIGF0dHIgYXR0cmlidXRlIHR5cGUKICAgKiBAcGFyYW0gc3RhdHVzIHRvIGluZGljYXRlIHdoZXRoZXIgdGhlIG9wZXJhdGlvbiB3ZW50IG9uIHNtb290aGx5IG9yIHRoZXJlIHdlcmUgZXJyb3JzCiAgICogQHJldHVybiBhdHRyaWJ1dGUgdmFsdWUKICAgKi8KICB2aXJ0dWFsIFVDb2xBdHRyaWJ1dGVWYWx1ZSBnZXRBdHRyaWJ1dGUoVUNvbEF0dHJpYnV0ZSBhdHRyLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSAmc3RhdHVzKTsKCiAgLyoqCiAgICogVGhyZWFkIHNhZmUgY2xvbmluZyBvcGVyYXRpb24uCiAgICogQHJldHVybiBwb2ludGVyIHRvIHRoZSBuZXcgY2xvbmUsIHVzZXIgc2hvdWxkIHJlbW92ZSBpdC4KICAgKi8KICB2aXJ0dWFsIENvbGxhdG9yKiBzYWZlQ2xvbmUodm9pZCk7CgogIC8qKgogICAqIFN0cmluZyBjb21wYXJlIHRoYXQgdXNlcyB1c2VyIHN1cHBsaWVkIGNoYXJhY3RlciBpdGVyYXRpb24uIFRoZSBpZGVhIGlzIAogICAqIHRvIHByZXZlbnQgdXNlcnMgZnJvbSBoYXZpbmcgdG8gY29udmVydCB0aGUgd2hvbGUgc3RyaW5nIGludG8gVUNoYXIncyAKICAgKiBiZWZvcmUgY29tcGFyaW5nIHNpbmNlIHNvbWV0aW1lcyBzdHJpbmdzIGRpZmZlciBvbiBmaXJzdCBjb3VwbGUgb2YgCiAgICogY2hhcmFjdGVycy4KICAgKiBAcGFyYW0gY29sbCBDb2xsYXRvciB0byBiZSB1c2VkIGZvciBjb21wYXJpbmcKICAgKiBAcGFyYW0gc291cmNlIHBvaW50ZXIgdG8gZnVuY3Rpb24gZm9yIGl0ZXJhdGluZyBvdmVyIHRoZSBmaXJzdCBzdHJpbmcKICAgKiBAcGFyYW0gdGFyZ2V0IHBvaW50ZXIgdG8gZnVuY3Rpb24gZm9yIGl0ZXJhdGluZyBvdmVyIHRoZSBzZWNvbmQgc3RyaW5nCiAgICogQHJldHVybiBUaGUgcmVzdWx0IG9mIGNvbXBhcmluZyB0aGUgc3RyaW5nczsgb25lIG9mIFVDT0xfRVFVQUwsCiAgICogICAgICAgICBVQ09MX0dSRUFURVIsIFVDT0xfTEVTUwogICAqLwogIHZpcnR1YWwgRUNvbXBhcmlzb25SZXN1bHQgY29tcGFyZShGb3J3YXJkQ2hhcmFjdGVySXRlcmF0b3IgJnNvdXJjZSwKCQkJCQkJCQkgICBGb3J3YXJkQ2hhcmFjdGVySXRlcmF0b3IgJnRhcmdldCk7CgogIC8qKgogICAqIEdldCB0aGUgc29ydCBrZXkgYXMgYW4gYXJyYXkgb2YgYnl0ZXMgZnJvbSBhbiBVbmljb2RlU3RyaW5nLgogICAqIEBwYXJhbSBzb3VyY2Ugc3RyaW5nIHRvIGJlIHByb2Nlc3NlZC4KICAgKiBAcGFyYW0gcmVzdWx0IGJ1ZmZlciB0byBzdG9yZSByZXN1bHQgaW4uIElmIE5VTEwsIG51bWJlciBvZiBieXRlcyBuZWVkZWQgCiAgICogICAgICAgIHdpbGwgYmUgcmV0dXJuZWQuCiAgICogQHBhcmFtIHJlc3VsdExlbmd0aCBsZW5ndGggb2YgdGhlIHJlc3VsdCBidWZmZXIuIElmIGlmIG5vdCBlbm91Z2ggdGhlIAogICAqICAgICAgICBidWZmZXIgd2lsbCBiZSBmaWxsZWQgdG8gY2FwYWNpdHkuIAogICAqIEByZXR1cm4gTnVtYmVyIG9mIGJ5dGVzIG5lZWRlZCBmb3Igc3RvcmluZyB0aGUgc29ydCBrZXkKICAgKi8KICB2aXJ0dWFsIGludDMyX3QgZ2V0U29ydEtleShjb25zdCBVbmljb2RlU3RyaW5nJiBzb3VyY2UsIHVpbnQ4X3QgKnJlc3VsdCwKCQkJCQkJICAgICAgICAgICAgICAgICBpbnQzMl90IHJlc3VsdExlbmd0aCkgY29uc3Q7CgogIC8qKgogICAqIEdldCB0aGUgc29ydCBrZXkgYXMgYW4gYXJyYXkgb2YgYnl0ZXMgZnJvbSBhbiBVQ2hhciBidWZmZXIuCiAgICogQHBhcmFtIHNvdXJjZSBzdHJpbmcgdG8gYmUgcHJvY2Vzc2VkLgogICAqIEBwYXJhbSBzb3VyY2VMZW5ndGggbGVuZ3RoIG9mIHN0cmluZyB0byBiZSBwcm9jZXNzZWQuIElmIC0xLCB0aGUgc3RyaW5nIAogICAqICAgICAgICBpcyAwIHRlcm1pbmF0ZWQgYW5kIGxlbmd0aCB3aWxsIGJlIGRlY2lkZWQgYnkgdGhlIGZ1bmN0aW9uLgogICAqIEBwYXJhbSByZXN1bHQgYnVmZmVyIHRvIHN0b3JlIHJlc3VsdCBpbi4gSWYgTlVMTCwgbnVtYmVyIG9mIGJ5dGVzIG5lZWRlZCAKICAgKiAgICAgICAgd2lsbCBiZSByZXR1cm5lZC4KICAgKiBAcGFyYW0gcmVzdWx0TGVuZ3RoIGxlbmd0aCBvZiB0aGUgcmVzdWx0IGJ1ZmZlci4gSWYgaWYgbm90IGVub3VnaCB0aGUgCiAgICogICAgICAgIGJ1ZmZlciB3aWxsIGJlIGZpbGxlZCB0byBjYXBhY2l0eS4gCiAgICogQHJldHVybiBOdW1iZXIgb2YgYnl0ZXMgbmVlZGVkIGZvciBzdG9yaW5nIHRoZSBzb3J0IGtleQogICAqLwogIHZpcnR1YWwgaW50MzJfdCBnZXRTb3J0S2V5KGNvbnN0IFVDaGFyICpzb3VyY2UsIGludDMyX3Qgc291cmNlTGVuZ3RoLAoJCQkJCQkgICAgICAgICAgICAgICAgIHVpbnQ4X3QgKnJlc3VsdCwgaW50MzJfdCByZXN1bHRMZW5ndGgpIGNvbnN0OwoKICAvKioKICAqIERldGVybWluZXMgdGhlIG1pbmltdW0gc3RyZW5ndGggdGhhdCB3aWxsIGJlIHVzZSBpbiBjb21wYXJpc29uIG9yCiAgKiB0cmFuc2Zvcm1hdGlvbi4KICAqIDxwPkUuZy4gd2l0aCBzdHJlbmd0aCA9PSBTRUNPTkRBUlksIHRoZSB0ZXJ0aWFyeSBkaWZmZXJlbmNlIGlzIGlnbm9yZWQKICAqIDxwPkUuZy4gd2l0aCBzdHJlbmd0aCA9PSBQUklNQVJZLCB0aGUgc2Vjb25kYXJ5IGFuZCB0ZXJ0aWFyeSBkaWZmZXJlbmNlCiAgKiBhcmUgaWdub3JlZC4KICAqIEByZXR1cm4gdGhlIGN1cnJlbnQgY29tcGFyaXNvbiBsZXZlbC4KICAqIEBzZWUgUnVsZUJhc2VkQ29sbGF0b3Ijc2V0U3RyZW5ndGgKICAqLwogIHZpcnR1YWwgRUNvbGxhdGlvblN0cmVuZ3RoIGdldFN0cmVuZ3RoKHZvaWQpIGNvbnN0OwogIAogIC8qKgogICogU2V0cyB0aGUgbWluaW11bSBzdHJlbmd0aCB0byBiZSB1c2VkIGluIGNvbXBhcmlzb24gb3IgdHJhbnNmb3JtYXRpb24uCiAgKiA8cD5FeGFtcGxlIG9mIHVzZToKICAqIDxwcmU+CiAgKiAuIFVFcnJvckNvZGUgc3RhdHVzID0gVV9aRVJPX0VSUk9SOwogICogLiBDb2xsYXRvcipteUNvbGxhdGlvbiA9IENvbGxhdG9yOjpjcmVhdGVJbnN0YW5jZShMb2NhbGU6OlVTLCAKICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdHVzKTsKICAqIC4gaWYgKFVfRkFJTFVSRShzdGF0dXMpKSByZXR1cm47CiAgKiAuIG15Q29sbGF0aW9uLT5zZXRTdHJlbmd0aChDb2xsYXRvcjo6UFJJTUFSWSk7CiAgKiAuIC8vIHJlc3VsdCB3aWxsIGJlICJhYmMiID09ICJBQkMiCiAgKiAuIC8vIHRlcnRpYXJ5IGRpZmZlcmVuY2VzIHdpbGwgYmUgaWdub3JlZAogICogLiBDb2xsYXRvcjo6Q29tcGFyaXNvblJlc3VsdCByZXN1bHQgPSBteUNvbGxhdGlvbi0+Y29tcGFyZSgiYWJjIiwgCiAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJBQkMiKTsKICAqIDwvcHJlPgogICogQHNlZSBSdWxlQmFzZWRDb2xsYXRvciNnZXRTdHJlbmd0aAogICogQHBhcmFtIG5ld1N0cmVuZ3RoIHRoZSBuZXcgY29tcGFyaXNvbiBsZXZlbC4KICAqIEBzdGFibGUKICAqLwogIHZpcnR1YWwgdm9pZCBzZXRTdHJlbmd0aChFQ29sbGF0aW9uU3RyZW5ndGggbmV3U3RyZW5ndGgpOwoKICAvKioKICAqIFNldCB0aGUgZGVjb21wb3NpdGlvbiBtb2RlIG9mIHRoZSBDb2xsYXRvciBvYmplY3QuIHN1Y2Nlc3MgaXMgZXF1YWwgdG8gCiAgKiBVX0lMTEVHQUxfQVJHVU1FTlRfRVJST1IgaWYgZXJyb3Igb2NjdXJzLgogICogQHBhcmFtIHRoZSBuZXcgZGVjb21wb3NpdGlvbiBtb2RlCiAgKiBAc2VlIENvbGxhdG9yI2dldERlY29tcG9zaXRpb24KICAqLwogIHZpcnR1YWwgdm9pZCBzZXREZWNvbXBvc2l0aW9uKE5vcm1hbGl6ZXI6OkVNb2RlICBtb2RlKTsKCiAgLyoqCiAgKiBHZXQgdGhlIGRlY29tcG9zaXRpb24gbW9kZSBvZiB0aGUgQ29sbGF0b3Igb2JqZWN0LgogICogQHJldHVybiB0aGUgZGVjb21wb3NpdGlvbiBtb2RlCiAgKiBAc2VlIENvbGxhdG9yI3NldERlY29tcG9zaXRpb24KICAqLwogIHZpcnR1YWwgTm9ybWFsaXplcjo6RU1vZGUgZ2V0RGVjb21wb3NpdGlvbih2b2lkKSBjb25zdDsKCnByaXZhdGU6CiAgCiAgLy8gcHJpdmF0ZSBzdGF0aWMgY29uc3RhbnRzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogIHN0YXRpYyBjb25zdCBpbnQzMl90IFVOTUFQUEVEOwogIHN0YXRpYyBjb25zdCBpbnQzMl90IENIQVJJTkRFWDsgIC8vIG5lZWQgbG9vayB1cCBpbiAuY29tbWl0KCkKICBzdGF0aWMgY29uc3QgaW50MzJfdCBFWFBBTkRDSEFSSU5ERVg7IC8vIEV4cGFuZCBpbmRleCBmb2xsb3dzCiAgc3RhdGljIGNvbnN0IGludDMyX3QgQ09OVFJBQ1RDSEFSSU5ERVg7ICAvLyBjb250cmFjdCBpbmRleGVzIGZvbGxvdwoKICBzdGF0aWMgY29uc3QgaW50MzJfdCBQUklNQVJZT1JERVJJTkNSRU1FTlQ7CiAgc3RhdGljIGNvbnN0IGludDMyX3QgU0VDT05EQVJZT1JERVJJTkNSRU1FTlQ7CiAgc3RhdGljIGNvbnN0IGludDMyX3QgVEVSVElBUllPUkRFUklOQ1JFTUVOVDsKICBzdGF0aWMgY29uc3QgaW50MzJfdCBQUklNQVJZT1JERVJNQVNLOwogIHN0YXRpYyBjb25zdCBpbnQzMl90IFNFQ09OREFSWU9SREVSTUFTSzsKICBzdGF0aWMgY29uc3QgaW50MzJfdCBURVJUSUFSWU9SREVSTUFTSzsKICBzdGF0aWMgY29uc3QgaW50MzJfdCBJR05PUkFCTEVNQVNLOwogIHN0YXRpYyBjb25zdCBpbnQzMl90IFBSSU1BUllESUZGRVJFTkNFT05MWTsKICBzdGF0aWMgY29uc3QgaW50MzJfdCBTRUNPTkRBUllESUZGRVJFTkNFT05MWTsKICBzdGF0aWMgY29uc3QgaW50MzJfdCBQUklNQVJZT1JERVJTSElGVDsKICBzdGF0aWMgY29uc3QgaW50MzJfdCBTRUNPTkRBUllPUkRFUlNISUZUOwogIAogIHN0YXRpYyBjb25zdCBpbnQzMl90IENPTEVMRU1FTlRTVEFSVDsKICBzdGF0aWMgY29uc3QgaW50MzJfdCBQUklNQVJZTE9XWkVST01BU0s7CiAgc3RhdGljIGNvbnN0IGludDMyX3QgUkVTRVRTRUNPTkRBUllURVJUSUFSWTsKICBzdGF0aWMgY29uc3QgaW50MzJfdCBSRVNFVFRFUlRJQVJZOwoKICBzdGF0aWMgY29uc3QgaW50MzJfdCBQUklNSUdOT1JBQkxFOwogIAogIHN0YXRpYyBjb25zdCBpbnQxNl90IEZJTEVJRDsKICBzdGF0aWMgY29uc3QgY2hhciAgICAqa0ZpbGVuYW1lU3VmZml4OwoKICAvLyBwcml2YXRlIHN0YXRpYyB2YXJpYWJsZXMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgLyoqCiAgKiBzdGF0aWMgY2xhc3MgaWQKICAqLwogIHN0YXRpYyBjaGFyIGZnQ2xhc3NJRDsKCiAgLy8gcHJpdmF0ZSBkYXRhIG1lbWJlcnMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogIFVCb29sIGRhdGFJc093bmVkOwogIAogIC8qKgogICogYyBzdHJ1Y3QgZm9yIGNvbGxhdGlvbi4gQWxsIGluaXRpYWxpc2F0aW9uIGZvciBpdCBoYXMgdG8gYmUgZG9uZSB0aHJvdWdoCiAgKiBzZXRVQ29sbGF0b3IoKS4KICAqLwogIFVDb2xsYXRvciAqdWNvbGxhdG9yOwoKICAvKioKICAqIFJ1bGUgVW5pY29kZVN0cmluZwogICovCiAgVW5pY29kZVN0cmluZyAqdXJ1bGVzdHJpbmc7CgogIC8vIGZyaWVuZCBjbGFzc2VzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogIC8qKiAKICAqIFN0cmVhbWVyIHVzZWQgdG8gcmVhZC93cml0ZSBiaW5hcnkgY29sbGF0aW9uIGRhdGEgZmlsZXMuCiAgKi8KICBmcmllbmQgY2xhc3MgUnVsZUJhc2VkQ29sbGF0b3JTdHJlYW1lcjsKCiAgLyoqCiAgKiBVc2VkIHRvIGl0ZXJhdGUgb3ZlciBjb2xsYXRpb24gZWxlbWVudHMgaW4gYSBjaGFyYWN0ZXIgc291cmNlLgogICovCiAgZnJpZW5kIGNsYXNzIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjsKICAgICAgICAKICAvKioKICAqIENvbGxhdG9yIE9OTFkgbmVlZHMgYWNjZXNzIHRvIFJ1bGVCYXNlZENvbGxhdG9yKGNvbnN0IExvY2FsZSYsIAogICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYpCiAgKi8KICBmcmllbmQgY2xhc3MgQ29sbGF0b3I7CiAgICAgICAgCiAgLy8gcHJpdmF0ZSBjb25zdHJ1Y3RvcnMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgLyoqIAogICAqIERlZmF1bHQgY29uc3RydWN0b3IKICAgKi8KICBSdWxlQmFzZWRDb2xsYXRvcigpOwoKICAvKioKICAqIENvbnN0cnVjdG9yIHRoYXQgdGFrZXMgaW4gYSBVQ29sbGF0b3Igc3RydWN0CiAgKiBAcGFyYW0gY29sbGF0b3IgVUNvbGxhdG9yIHN0cnVjdAogICovCiAgUnVsZUJhc2VkQ29sbGF0b3IoVUNvbGxhdG9yICpjb2xsYXRvciwgVW5pY29kZVN0cmluZyAqcnVsZSk7CgogIC8qKgogICAqIFJ1bGVCYXNlZENvbGxhdG9yIGNvbnN0cnVjdG9yLiBUaGlzIGNvbnN0cnVjdG9yIHRha2VzIGEgbG9jYWxlLiBUaGUgCiAgICogb25seSBjYWxsZXIgb2YgdGhpcyBjbGFzcyBzaG91bGQgYmUgQ29sbGF0b3I6OmNyZWF0ZUluc3RhbmNlKCkuIElmIAogICAqIGNyZWF0ZUluc3RhbmNlKCkgaGFwcGVucyB0byBrbm93IHRoYXQgdGhlIHJlcXVlc3RlZCBsb2NhbGUncyBjb2xsYXRpb24gaXMgCiAgICogaW1wbGVtZW50ZWQgYXMgYSBSdWxlQmFzZWRDb2xsYXRvciwgaXQgY2FuIHRoZW4gY2FsbCB0aGlzIGNvbnN0cnVjdG9yLiAgCiAgICogT1RIRVJXSVNFIElUIFNIT1VMRE4nVCwgc2luY2UgdGhpcyBjb25zdHJ1Y3RvciBBTFdBWVMgUkVUVVJOUyBBIFZBTElEIAogICAqIENPTExBVElPTiBUQUJMRS4gSXQgZG9lcyB0aGlzIGJ5IGZhbGxpbmcgYmFjayB0byBkZWZhdWx0cy4KICAgKiBAcGFyYW0gZGVzaXJlZExvY2FsZSBsb2NhbGUgdXNlZAogICAqIEBwYXJhbSBzdGF0dXMgZXJyb3IgY29kZSBzdGF0dXMKICAgKi8KICBSdWxlQmFzZWRDb2xsYXRvcihjb25zdCBMb2NhbGUmIGRlc2lyZWRMb2NhbGUsIFVFcnJvckNvZGUmIHN0YXR1cyk7CgogIC8vIHByaXZhdGUgbWV0aG9kcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogIC8qKgogICogQ3JlYXRlcyB0aGUgYyBzdHJ1Y3QgZm9yIHVjb2xsYXRvcgogICogQHBhcmFtIGxvY2FsZSBkZXNpcmVkIGxvY2FsZQogICogQHBhcmFtIHN0YXR1cyBlcnJvciBzdGF0dXMKICAqLwogIHZvaWQgc2V0VUNvbGxhdG9yKGNvbnN0IExvY2FsZSYgbG9jYWxlLCBVRXJyb3JDb2RlJiBzdGF0dXMpOwoKICAvKioKICAqIENyZWF0ZXMgdGhlIGMgc3RydWN0IGZvciB1Y29sbGF0b3IKICAqIEBwYXJhbSBsb2NhbGUgZGVzaXJlZCBsb2NhbGUgbmFtZQogICogQHBhcmFtIHN0YXR1cyBlcnJvciBzdGF0dXMKICAqLwogIHZvaWQgc2V0VUNvbGxhdG9yKGNvbnN0IGNoYXIqIGxvY2FsZSwgVUVycm9yQ29kZSYgc3RhdHVzKTsKCiAgLyoqCiAgKiBDcmVhdGVzIHRoZSBjIHN0cnVjdCBmb3IgdWNvbGxhdG9yCiAgKiBAcGFyYW0gY29sbGF0b3IgbmV3IHVjb2xsYXRvciBkYXRhCiAgKiBAcGFyYW0gc3RhdHVzIGVycm9yIHN0YXR1cwogICovCiAgdm9pZCBzZXRVQ29sbGF0b3IoVUNvbGxhdG9yICpjb2xsYXRvcik7CgogIC8qKgogICogQ29udmVydHMgQydzIFVDb2xsYXRpb25SZXN1bHQgdG8gRUNvbXBhcmlzb25SZXN1bHQKICAqIEBwYXJhbSByZXN1bHQgbWVtYmVyIG9mIHRoZSBlbnVtIFVDb21wYXJpc29uUmVzdWx0CiAgKiBAcmV0dXJuIEVDb21wYXJpc29uUmVzdWx0IGVxdWl2YWxlbnQgb2YgVUNvbGxhdGlvblJlc3VsdAogICovCiAgQ29sbGF0b3I6OkVDb21wYXJpc29uUmVzdWx0IGdldEVDb21wYXJpc29uUmVzdWx0KAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBVQ29sbGF0aW9uUmVzdWx0ICZyZXN1bHQpIGNvbnN0OwoKICAvKioKICAqIENvbnZlcnRzIEMncyBVQ29sbGF0aW9uU3RyZW5ndGggdG8gRUNvbGxhdGlvblN0cmVuZ3RoCiAgKiBAcGFyYW0gc3RyZW5ndGggbWVtYmVyIG9mIHRoZSBlbnVtIFVDb2xsYXRpb25TdHJlbmd0aAogICogQHJldHVybiBFQ29sbGF0aW9uU3RyZW5ndGggZXF1aXZhbGVudCBvZiBVQ29sbGF0aW9uU3RyZW5ndGgKICAqLwogIENvbGxhdG9yOjpFQ29sbGF0aW9uU3RyZW5ndGggZ2V0RUNvbGxhdGlvblN0cmVuZ3RoKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFVDb2xsYXRpb25TdHJlbmd0aCAmc3RyZW5ndGgpIGNvbnN0OwoKICAvKioKICAqIENvbnZlcnRzIEMrKydzIEVDb2xsYXRpb25TdHJlbmd0aCB0byBVQ29sbGF0aW9uU3RyZW5ndGgKICAqIEBwYXJhbSBzdHJlbmd0aCBtZW1iZXIgb2YgdGhlIGVudW0gRUNvbGxhdGlvblN0cmVuZ3RoCiAgKiBAcmV0dXJuIFVDb2xsYXRpb25TdHJlbmd0aCBlcXVpdmFsZW50IG9mIEVDb2xsYXRpb25TdHJlbmd0aAogICovCiAgVUNvbGxhdGlvblN0cmVuZ3RoIGdldFVDb2xsYXRpb25TdHJlbmd0aCgKICAgIGNvbnN0IENvbGxhdG9yOjpFQ29sbGF0aW9uU3RyZW5ndGggJnN0cmVuZ3RoKSBjb25zdDsKfTsKCi8vIGlubGluZSBtZXRob2QgaW1wbGVtZW50YXRpb24gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgppbmxpbmUgVUJvb2wgUnVsZUJhc2VkQ29sbGF0b3I6Om9wZXJhdG9yIT0oY29uc3QgQ29sbGF0b3ImIG90aGVyKSBjb25zdAp7CiAgcmV0dXJuICEoKnRoaXMgPT0gb3RoZXIpOwp9CgppbmxpbmUgdm9pZCBSdWxlQmFzZWRDb2xsYXRvcjo6c2V0VUNvbGxhdG9yKGNvbnN0IGNoYXIgKmxvY2FsZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSAmc3RhdHVzKQp7CiAgaWYgKFVfRkFJTFVSRShzdGF0dXMpKQogICAgcmV0dXJuOwogIGlmICh1Y29sbGF0b3IgJiYgZGF0YUlzT3duZWQpCiAgICB1Y29sX2Nsb3NlKHVjb2xsYXRvcik7CiAgdWNvbGxhdG9yID0gdWNvbF9vcGVuKGxvY2FsZSwgJnN0YXR1cyk7Cn0KCmlubGluZSB2b2lkIFJ1bGVCYXNlZENvbGxhdG9yOjpzZXRVQ29sbGF0b3IoY29uc3QgTG9jYWxlICZsb2NhbGUsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUgJnN0YXR1cykKewogIHNldFVDb2xsYXRvcihsb2NhbGUuZ2V0TmFtZSgpLCBzdGF0dXMpOwp9CgppbmxpbmUgdm9pZCBSdWxlQmFzZWRDb2xsYXRvcjo6c2V0VUNvbGxhdG9yKFVDb2xsYXRvciAqY29sbGF0b3IpCnsKICBpZiAodWNvbGxhdG9yICYmIGRhdGFJc093bmVkKQogICAgdWNvbF9jbG9zZSh1Y29sbGF0b3IpOwogIHVjb2xsYXRvciA9IGNvbGxhdG9yOwp9CgppbmxpbmUgQ29sbGF0b3I6OkVDb21wYXJpc29uUmVzdWx0IFJ1bGVCYXNlZENvbGxhdG9yOjpnZXRFQ29tcGFyaXNvblJlc3VsdCgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFVDb2xsYXRpb25SZXN1bHQgJnJlc3VsdCkgY29uc3QKewogIHN3aXRjaCAocmVzdWx0KQogIHsKICBjYXNlIFVDT0xfTEVTUyA6CiAgICByZXR1cm4gQ29sbGF0b3I6OkxFU1M7CiAgY2FzZSBVQ09MX0VRVUFMIDoKICAgIHJldHVybiBDb2xsYXRvcjo6RVFVQUw7ICAKICBkZWZhdWx0IDoKICAgIHJldHVybiBDb2xsYXRvcjo6R1JFQVRFUjsKICB9Cn0KCmlubGluZSBDb2xsYXRvcjo6RUNvbGxhdGlvblN0cmVuZ3RoIFJ1bGVCYXNlZENvbGxhdG9yOjpnZXRFQ29sbGF0aW9uU3RyZW5ndGgoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFVDb2xsYXRpb25TdHJlbmd0aCAmc3RyZW5ndGgpIGNvbnN0CnsgIAogIHN3aXRjaCAoc3RyZW5ndGgpCiAgewogIGNhc2UgVUNPTF9QUklNQVJZIDoKICAgIHJldHVybiBDb2xsYXRvcjo6UFJJTUFSWTsKICBjYXNlIFVDT0xfU0VDT05EQVJZIDoKICAgIHJldHVybiBDb2xsYXRvcjo6U0VDT05EQVJZOwogIGNhc2UgVUNPTF9URVJUSUFSWSA6IAogICAgcmV0dXJuIENvbGxhdG9yOjpURVJUSUFSWTsKICBkZWZhdWx0IDoKICAgIHJldHVybiBDb2xsYXRvcjo6SURFTlRJQ0FMOwogIH0KfQoKaW5saW5lIFVDb2xsYXRpb25TdHJlbmd0aCBSdWxlQmFzZWRDb2xsYXRvcjo6Z2V0VUNvbGxhdGlvblN0cmVuZ3RoKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IENvbGxhdG9yOjpFQ29sbGF0aW9uU3RyZW5ndGggJnN0cmVuZ3RoKSBjb25zdAp7ICAKICBzd2l0Y2ggKHN0cmVuZ3RoKQogIHsKICBjYXNlIENvbGxhdG9yOjpQUklNQVJZIDoKICAgIHJldHVybiBVQ09MX1BSSU1BUlk7CiAgY2FzZSBDb2xsYXRvcjo6U0VDT05EQVJZIDoKICAgIHJldHVybiBVQ09MX1NFQ09OREFSWTsKICBjYXNlIENvbGxhdG9yOjpURVJUSUFSWSA6IAogICAgcmV0dXJuIFVDT0xfVEVSVElBUlk7CiAgZGVmYXVsdCA6CiAgICByZXR1cm4gVUNPTF9JREVOVElDQUw7CiAgfQp9CgojZW5kaWYK