LyoKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiogICBDb3B5cmlnaHQgKEMpIDE5OTYtMjAwMSwgSW50ZXJuYXRpb25hbCBCdXNpbmVzcyBNYWNoaW5lcyAgICAgICAgICAgICAgICAgKgoqICAgQ29ycG9yYXRpb24gYW5kIG90aGVycy4gIEFsbCBSaWdodHMgUmVzZXJ2ZWQuICAgICAgICAgICAgICAgICAgICAgICAgICAgICoKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiovCgovKioKKiBGaWxlIGNvbGwuaAoqIAoqIENyZWF0ZWQgYnk6IEhlbGVuYSBTaGloCioKKiBNb2RpZmljYXRpb24gSGlzdG9yeToKKgoqICBEYXRlICAgICAgICBOYW1lICAgICAgICBEZXNjcmlwdGlvbgoqIDAyLzUvOTcgICAgICBhbGl1ICAgICAgICBNb2RpZmllZCBjcmVhdGVEZWZhdWx0IHRvIGxvYWQgY29sbGF0aW9uIGRhdGEgZnJvbQoqICAgICAgICAgICAgICAgICAgICAgICAgICBiaW5hcnkgZmlsZXMgd2hlbiBwb3NzaWJsZS4gIEFkZGVkIHJlbGF0ZWQgbWV0aG9kcwoqICAgICAgICAgICAgICAgICAgICAgICAgICBjcmVhdGVDb2xsYXRpb25Gcm9tRmlsZSwgY2hvcExvY2FsZSwgY3JlYXRlUGF0aE5hbWUuCiogMDIvMTEvOTcgICAgIGFsaXUgICAgICAgIEFkZGVkIG1lbWJlcnMgYWRkVG9DYWNoZSwgZmluZEluQ2FjaGUsIGFuZCBmZ0NhY2hlLgoqIDAyLzEyLzk3ICAgICBhbGl1ICAgICAgICBNb2RpZmllZCB0byBjcmVhdGUgb2JqZWN0cyBmcm9tIFJ1bGVCYXNlZENvbGxhdG9yIGNhY2hlLgoqICAgICAgICAgICAgICAgICAgICAgICAgICBNb3ZlZCBjYWNoZSBvdXQgb2YgQ29sbGF0aW9uIGNsYXNzLgoqIDAyLzEzLzk3ICAgICBhbGl1ICAgICAgICBNb3ZlZCBzZXZlcmFsIG1ldGhvZHMgb3V0IG9mIHRoaXMgY2xhc3MgYW5kIGludG8KKiAgICAgICAgICAgICAgICAgICAgICAgICAgUnVsZUJhc2VkQ29sbGF0b3IsIHdpdGggbW9kaWZpY2F0aW9ucy4gIE1vZGlmaWVkCiogICAgICAgICAgICAgICAgICAgICAgICAgIGNyZWF0ZURlZmF1bHQoKSB0byBjYWxsIG5ldyBSdWxlQmFzZWRDb2xsYXRvcihMb2NhbGUmKQoqICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdHJ1Y3Rvci4gIEdlbmVyYWwgY2xlYW4gdXAgYW5kIGRvY3VtZW50YXRpb24uCiogMDIvMjAvOTcgICAgIGhlbGVuYSAgICAgIEFkZGVkIGNsb25lLCBvcGVyYXRvcj09LCBvcGVyYXRvciE9LCBvcGVyYXRvcj0sIGNvcHkKKiAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3RydWN0b3IgYW5kIGdldER5bmFtaWNDbGFzc0lELgoqIDAzLzI1Lzk3ICAgICBoZWxlbmEgICAgICBVcGRhdGVkIHdpdGggcGxhdGZvcm0gaW5kZXBlbmRlbnQgZGF0YSB0eXBlcy4KKiAwNS8wNi85NyAgICAgaGVsZW5hICAgICAgQWRkZWQgbWVtb3J5IGFsbG9jYXRpb24gZXJyb3IgZGV0ZWN0aW9uLgoqIDA2LzIwLzk3ICAgICBoZWxlbmEgICAgICBKYXZhIGNsYXNzIG5hbWUgY2hhbmdlLgoqIDA5LzAzLzk3ICAgICBoZWxlbmEgICAgICBBZGRlZCBjcmVhdGVDb2xsYXRpb25LZXlWYWx1ZXMoKS4KKiAwMi8xMC85OCAgICAgZGFtaWJhICAgICAgQWRkZWQgY29tcGFyZSgpIHdpdGggbGVuZ3RoIGFzIHBhcmFtZXRlci4KKiAwNC8yMy85OSAgICAgc3RlcGhlbiAgICAgUmVtb3ZlZCBFRGVjb21wb3NpdGlvbk1vZGUsIG1lcmdlZCB3aXRoCiogICAgICAgICAgICAgICAgICAgICAgICAgIE5vcm1hbGl6ZXI6OkVNb2RlLgoqIDExLzAyLzk5ICAgICBoZWxlbmEgICAgICBDb2xsYXRvciBwZXJmb3JtYW5jZSBlbmhhbmNlbWVudHMuICBFbGltaW5hdGVzIHRoZSAKKiAgICAgICAgICAgICAgICAgICAgICAgICAgVW5pY29kZVN0cmluZyBjb25zdHJ1Y3Rpb24gYW5kIHNwZWNpYWwgY2FzZSBmb3IgTk9fT1AuCiogMTEvMjMvOTkgICAgIHNybCAgICAgICAgIE1vcmUgcGVyZm9ybWFuY2UgZW5oYW5jZW1lbnRzLiBJbmxpbmluZyBvZgoqICAgICAgICAgICAgICAgICAgICAgICAgICBjcml0aWNhbCBhY2Nlc3NvcnMuCiogMDUvMTUvMDAgICAgIGhlbGVuYSAgICAgIEFkZGVkIHZlcnNpb24gaW5mb3JtYXRpb24gQVBJLiAKKiAwMS8yOS8wMSAgICAgc3lud2VlICAgICAgTW9kaWZpZWQgaW50byBhIEMrKyB3cmFwcGVyIHdoaWNoIGNhbGxzIEMgYXBpcyAKKiAgICAgICAgICAgICAgICAgICAgICAgICAgKHVjb2xsLmgpLiAKKi8KCiNpZm5kZWYgQ09MTF9ICiNkZWZpbmUgQ09MTF9ICgojaW5jbHVkZSAidW5pY29kZS91dHlwZXMuaCIKI2luY2x1ZGUgInVuaWNvZGUvdW9iamVjdC5oIgojaW5jbHVkZSAidW5pY29kZS91Y29sLmgiCiNpbmNsdWRlICJ1bmljb2RlL25vcm1senIuaCIKI2luY2x1ZGUgInVuaWNvZGUvbG9jaWQuaCIKClVfTkFNRVNQQUNFX0JFR0lOCgpjbGFzcyBDb2xsYXRpb25LZXk7CgovKioKKiBUaGUgPGNvZGU+Q29sbGF0b3I8L2NvZGU+IGNsYXNzIHBlcmZvcm1zIGxvY2FsZS1zZW5zaXRpdmUgc3RyaW5nIAoqIGNvbXBhcmlzb24uPGJyPgoqIFlvdSB1c2UgdGhpcyBjbGFzcyB0byBidWlsZCBzZWFyY2hpbmcgYW5kIHNvcnRpbmcgcm91dGluZXMgZm9yIG5hdHVyYWwgCiogbGFuZ3VhZ2UgdGV4dC48YnI+CiogPGVtPkltcG9ydGFudDogPC9lbT5UaGUgSUNVIGNvbGxhdGlvbiBzZXJ2aWNlIGhhcyBiZWVuIHJlaW1wbGVtZW50ZWQgCiogaW4gb3JkZXIgdG8gYWNoaWV2ZSBiZXR0ZXIgcGVyZm9ybWFuY2UgYW5kIFVDQSBjb21wbGlhbmNlLiAKKiBGb3IgZGV0YWlscywgc2VlIHRoZSAKKiA8YSBocmVmPSJodHRwOi8vb3NzLnNvZnR3YXJlLmlibS5jb20vY3ZzL2ljdS9+Y2hlY2tvdXR+L2ljdWh0bWwvZGVzaWduL2NvbGxhdGlvbi9JQ1VfY29sbGF0aW9uX2Rlc2lnbi5odG0iPgoqIGNvbGxhdGlvbiBkZXNpZ24gZG9jdW1lbnQ8L2E+LgoqIDxwPgoqIDxjb2RlPkNvbGxhdG9yPC9jb2RlPiBpcyBhbiBhYnN0cmFjdCBiYXNlIGNsYXNzLiBTdWJjbGFzc2VzIGltcGxlbWVudCAKKiBzcGVjaWZpYyBjb2xsYXRpb24gc3RyYXRlZ2llcy4gT25lIHN1YmNsYXNzLCAKKiA8Y29kZT5SdWxlQmFzZWRDb2xsYXRvcjwvY29kZT4sIGlzIGN1cnJlbnRseSBwcm92aWRlZCBhbmQgaXMgYXBwbGljYWJsZSAKKiB0byBhIHdpZGUgc2V0IG9mIGxhbmd1YWdlcy4gT3RoZXIgc3ViY2xhc3NlcyBtYXkgYmUgY3JlYXRlZCB0byBoYW5kbGUgbW9yZSAKKiBzcGVjaWFsaXplZCBuZWVkcy4KKiA8cD4KKiBMaWtlIG90aGVyIGxvY2FsZS1zZW5zaXRpdmUgY2xhc3NlcywgeW91IGNhbiB1c2UgdGhlIHN0YXRpYyBmYWN0b3J5IG1ldGhvZCwgCiogPGNvZGU+Y3JlYXRlSW5zdGFuY2U8L2NvZGU+LCB0byBvYnRhaW4gdGhlIGFwcHJvcHJpYXRlIAoqIDxjb2RlPkNvbGxhdG9yPC9jb2RlPiBvYmplY3QgZm9yIGEgZ2l2ZW4gbG9jYWxlLiBZb3Ugd2lsbCBvbmx5IG5lZWQgdG8gCiogbG9vayBhdCB0aGUgc3ViY2xhc3NlcyBvZiA8Y29kZT5Db2xsYXRvcjwvY29kZT4gaWYgeW91IG5lZWQgdG8gCiogdW5kZXJzdGFuZCB0aGUgZGV0YWlscyBvZiBhIHBhcnRpY3VsYXIgY29sbGF0aW9uIHN0cmF0ZWd5IG9yIGlmIHlvdSBuZWVkIHRvIAoqIG1vZGlmeSB0aGF0IHN0cmF0ZWd5LgoqIDxwPgoqIFRoZSBmb2xsb3dpbmcgZXhhbXBsZSBzaG93cyBob3cgdG8gY29tcGFyZSB0d28gc3RyaW5ncyB1c2luZyB0aGUgCiogPGNvZGU+Q29sbGF0b3I8L2NvZGU+IGZvciB0aGUgZGVmYXVsdCBsb2NhbGUuCiogPGJsb2NrcXVvdGU+CiogPHByZT4KKiBcY29kZQoqIC8vIENvbXBhcmUgdHdvIHN0cmluZ3MgaW4gdGhlIGRlZmF1bHQgbG9jYWxlCiogVUVycm9yQ29kZSBzdWNjZXNzID0gVV9aRVJPX0VSUk9SOwoqIENvbGxhdG9yKiBteUNvbGxhdG9yID0gQ29sbGF0b3I6OmNyZWF0ZUluc3RhbmNlKHN1Y2Nlc3MpOwoqIGlmIChteUNvbGxhdG9yLT5jb21wYXJlKCJhYmMiLCAiQUJDIikgPCAwKQoqICAgY291dCA8PCAiYWJjIGlzIGxlc3MgdGhhbiBBQkMiIDw8IGVuZGw7CiogZWxzZQoqICAgY291dCA8PCAiYWJjIGlzIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byBBQkMiIDw8IGVuZGw7CiogXGVuZGNvZGUKKiA8L3ByZT4KKiA8L2Jsb2NrcXVvdGU+CiogPHA+CiogWW91IGNhbiBzZXQgYSA8Y29kZT5Db2xsYXRvcjwvY29kZT4ncyA8ZW0+c3RyZW5ndGg8L2VtPiBwcm9wZXJ0eSB0byAKKiBkZXRlcm1pbmUgdGhlIGxldmVsIG9mIGRpZmZlcmVuY2UgY29uc2lkZXJlZCBzaWduaWZpY2FudCBpbiBjb21wYXJpc29ucy4gCiogRml2ZSBzdHJlbmd0aHMgYXJlIHByb3ZpZGVkOiA8Y29kZT5QUklNQVJZPC9jb2RlPiwgPGNvZGU+U0VDT05EQVJZPC9jb2RlPiwgCiogPGNvZGU+VEVSVElBUlk8L2NvZGU+LCA8Y29kZT5RVUFURVJOQVJZPC9jb2RlPiBhbmQgPGNvZGU+SURFTlRJQ0FMPC9jb2RlPi4gVGhlIGV4YWN0IGFzc2lnbm1lbnQgb2YgCiogc3RyZW5ndGhzIHRvIGxhbmd1YWdlIGZlYXR1cmVzIGlzIGxvY2FsZSBkZXBlbmRhbnQuIEZvciBleGFtcGxlLCBpbiBDemVjaCwgCiogImUiIGFuZCAiZiIgYXJlIGNvbnNpZGVyZWQgcHJpbWFyeSBkaWZmZXJlbmNlcywgd2hpbGUgImUiIGFuZCAiXHUwMEVBIiBhcmUgCiogc2Vjb25kYXJ5IGRpZmZlcmVuY2VzLCAiZSIgYW5kICJFIiBhcmUgdGVydGlhcnkgZGlmZmVyZW5jZXMgYW5kICJlIiBhbmQgImUiIAoqIGFyZSBpZGVudGljYWwuIFRoZSBmb2xsb3dpbmcgc2hvd3MgaG93IGJvdGggY2FzZSBhbmQgYWNjZW50cyBjb3VsZCBiZSAKKiBpZ25vcmVkIGZvciBVUyBFbmdsaXNoLgoqIDxibG9ja3F1b3RlPgoqIDxwcmU+CiogXGNvZGUKKiAvL0dldCB0aGUgQ29sbGF0b3IgZm9yIFVTIEVuZ2xpc2ggYW5kIHNldCBpdHMgc3RyZW5ndGggdG8gUFJJTUFSWSAKKiBVRXJyb3JDb2RlIHN1Y2Nlc3MgPSBVX1pFUk9fRVJST1I7CiogQ29sbGF0b3IqIHVzQ29sbGF0b3IgPSAKKiAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb2xsYXRvcjo6Y3JlYXRlSW5zdGFuY2UoTG9jYWxlOjpVUywgc3VjY2Vzcyk7CiogdXNDb2xsYXRvci0+c2V0U3RyZW5ndGgoQ29sbGF0b3I6OlBSSU1BUlkpOwoqIGlmICh1c0NvbGxhdG9yLT5jb21wYXJlKCJhYmMiLCAiQUJDIikgPT0gMCkKKiAgIGNvdXQgPDwgCiogIidhYmMnIGFuZCAnQUJDJyBzdHJpbmdzIGFyZSBlcXVpdmFsZW50IHdpdGggc3RyZW5ndGggUFJJTUFSWSIgPDwgCiogZW5kbDsKKiBcZW5kY29kZQoqIDwvcHJlPgoqIDwvYmxvY2txdW90ZT4KKiA8cD4KKiBGb3IgY29tcGFyaW5nIHN0cmluZ3MgZXhhY3RseSBvbmNlLCB0aGUgPGNvZGU+Y29tcGFyZTwvY29kZT4gbWV0aG9kIAoqIHByb3ZpZGVzIHRoZSBiZXN0IHBlcmZvcm1hbmNlLiBXaGVuIHNvcnRpbmcgYSBsaXN0IG9mIHN0cmluZ3MgaG93ZXZlciwgaXQgCiogaXMgZ2VuZXJhbGx5IG5lY2Vzc2FyeSB0byBjb21wYXJlIGVhY2ggc3RyaW5nIG11bHRpcGxlIHRpbWVzLiBJbiB0aGlzIGNhc2UsIAoqIHNvcnQga2V5cyBwcm92aWRlIGJldHRlciBwZXJmb3JtYW5jZS4gVGhlIDxjb2RlPmdldFNvcnRLZXk8L2NvZGU+IG1ldGhvZHMgCiogY29udmVydCBhIHN0cmluZyB0byBhIHNlcmllcyBvZiBieXRlcyB0aGF0IGNhbiBiZSBjb21wYXJlZCBiaXR3aXNlIGFnYWluc3QgCiogb3RoZXIgc29ydCBrZXlzIHVzaW5nIDxjb2RlPnN0cmNtcCgpPC9jb2RlPi4gU29ydCBrZXlzIGFyZSB3cml0dGVuIGFzIAoqIHplcm8tdGVybWluYXRlZCBieXRlIHN0cmluZ3MuIFRoZXkgY29uc2lzdCBvZiBzZXZlcmFsIHN1YnN0cmluZ3MsIG9uZSBmb3IgCiogZWFjaCBjb2xsYXRpb24gc3RyZW5ndGggbGV2ZWwsIHRoYXQgYXJlIGRlbGltaXRlZCBieSAweDAxIGJ5dGVzLgoqIElmIHRoZSBzdHJpbmcgY29kZSBwb2ludHMgYXJlIGFwcGVuZGVkIGZvciBVQ09MX0lERU5USUNBTCwgdGhlbiB0aGV5IGFyZSAKKiBwcm9jZXNzZWQgZm9yIGNvcnJlY3QgY29kZSBwb2ludCBvcmRlciBjb21wYXJpc29uIGFuZCBtYXkgY29udGFpbiAweDAxIAoqIGJ5dGVzIGJ1dCBub3QgemVybyBieXRlcy4KKiA8L3A+CiogPHA+CiogQW4gb2xkZXIgc2V0IG9mIEFQSXMgcmV0dXJucyBhIDxjb2RlPkNvbGxhdGlvbktleTwvY29kZT4gb2JqZWN0IHRoYXQgd3JhcHMgCiogdGhlIHNvcnQga2V5IGJ5dGVzIGluc3RlYWQgb2YgcmV0dXJuaW5nIHRoZSBieXRlcyB0aGVtc2VsdmVzLgoqIEl0cyB1c2UgaXMgZGVwcmVjYXRlZCwgYnV0IGl0IGlzIHN0aWxsIGF2YWlsYWJsZSBmb3IgY29tcGF0aWJpbGl0eSB3aXRoIAoqIEphdmEuCiogPC9wPgoqIDxwPgoqIDxzdHJvbmc+Tm90ZTo8L3N0cm9uZz4gPGNvZGU+Q29sbGF0b3I8L2NvZGU+cyB3aXRoIGRpZmZlcmVudCBMb2NhbGUsCiogYW5kIENvbGxhdGlvblN0cmVuZ3RoIHNldHRpbmdzIHdpbGwgcmV0dXJuIGRpZmZlcmVudCBzb3J0IAoqIG9yZGVycyBmb3IgdGhlIHNhbWUgc2V0IG9mIHN0cmluZ3MuIExvY2FsZXMgaGF2ZSBzcGVjaWZpYyBjb2xsYXRpb24gcnVsZXMsIAoqIGFuZCB0aGUgd2F5IGluIHdoaWNoIHNlY29uZGFyeSBhbmQgdGVydGlhcnkgZGlmZmVyZW5jZXMgYXJlIHRha2VuIGludG8gCiogYWNjb3VudCwgZm9yIGV4YW1wbGUsIHdpbGwgcmVzdWx0IGluIGEgZGlmZmVyZW50IHNvcnRpbmcgb3JkZXIgZm9yIHNhbWUgCiogc3RyaW5ncy4KKiA8L3A+CiogQHNlZSAgICAgICAgIFJ1bGVCYXNlZENvbGxhdG9yCiogQHNlZSAgICAgICAgIENvbGxhdGlvbktleQoqIEBzZWUgICAgICAgICBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IKKiBAc2VlICAgICAgICAgTG9jYWxlCiogQHNlZSAgICAgICAgIE5vcm1hbGl6ZXIKKiBAdmVyc2lvbiAgICAgMi4wIDExLzE1LzAxCiovCgpjbGFzcyBVX0kxOE5fQVBJIENvbGxhdG9yIDogcHVibGljIFVPYmplY3QgewpwdWJsaWM6CgogIC8vIENvbGxhdG9yIHB1YmxpYyBlbnVtcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAvKioKICAqIEJhc2UgbGV0dGVyIHJlcHJlc2VudHMgYSBwcmltYXJ5IGRpZmZlcmVuY2UuIFNldCBjb21wYXJpc29uIGxldmVsIHRvIAogICogUFJJTUFSWSB0byBpZ25vcmUgc2Vjb25kYXJ5IGFuZCB0ZXJ0aWFyeSBkaWZmZXJlbmNlcy48YnI+CiAgKiBVc2UgdGhpcyB0byBzZXQgdGhlIHN0cmVuZ3RoIG9mIGEgQ29sbGF0b3Igb2JqZWN0Ljxicj4KICAqIEV4YW1wbGUgb2YgcHJpbWFyeSBkaWZmZXJlbmNlLCAiYWJjIiAmbHQ7ICJhYmQiCiAgKiAKICAqIERpYWNyaXRpY2FsIGRpZmZlcmVuY2VzIG9uIHRoZSBzYW1lIGJhc2UgbGV0dGVyIHJlcHJlc2VudCBhIHNlY29uZGFyeQogICogZGlmZmVyZW5jZS4gU2V0IGNvbXBhcmlzb24gbGV2ZWwgdG8gU0VDT05EQVJZIHRvIGlnbm9yZSB0ZXJ0aWFyeQogICogZGlmZmVyZW5jZXMuIFVzZSB0aGlzIHRvIHNldCB0aGUgc3RyZW5ndGggb2YgYSBDb2xsYXRvciBvYmplY3QuPGJyPgogICogRXhhbXBsZSBvZiBzZWNvbmRhcnkgZGlmZmVyZW5jZSwgIuQiID4+ICJhIi4KICAqCiAgKiBVcHBlcmNhc2UgYW5kIGxvd2VyY2FzZSB2ZXJzaW9ucyBvZiB0aGUgc2FtZSBjaGFyYWN0ZXIgcmVwcmVzZW50cyBhCiAgKiB0ZXJ0aWFyeSBkaWZmZXJlbmNlLiAgU2V0IGNvbXBhcmlzb24gbGV2ZWwgdG8gVEVSVElBUlkgdG8gaW5jbHVkZSBhbGwgCiAgKiBjb21wYXJpc29uIGRpZmZlcmVuY2VzLiBVc2UgdGhpcyB0byBzZXQgdGhlIHN0cmVuZ3RoIG9mIGEgQ29sbGF0b3IKICAqIG9iamVjdC48YnI+CiAgKiBFeGFtcGxlIG9mIHRlcnRpYXJ5IGRpZmZlcmVuY2UsICJhYmMiICZsdDsmbHQ7Jmx0OyAiQUJDIi4KICAqCiAgKiBUd28gY2hhcmFjdGVycyBhcmUgY29uc2lkZXJlZCAiaWRlbnRpY2FsIiB3aGVuIHRoZXkgaGF2ZSB0aGUgc2FtZSB1bmljb2RlIAogICogc3BlbGxpbmdzLjxicj4KICAqIEZvciBleGFtcGxlLCAi5CIgPT0gIuQiLgogICoKICAqIFVDb2xsYXRpb25TdHJlbmd0aCBpcyBhbHNvIHVzZWQgdG8gZGV0ZXJtaW5lIHRoZSBzdHJlbmd0aCBvZiBzb3J0IGtleXMgCiAgKiBnZW5lcmF0ZWQgZnJvbSBDb2xsYXRvciBvYmplY3RzLgogICogQHN0YWJsZQogICovCiAgZW51bSBFQ29sbGF0aW9uU3RyZW5ndGggCiAgewogICAgUFJJTUFSWSAgICA9IDAsCiAgICBTRUNPTkRBUlkgID0gMSwgCiAgICBURVJUSUFSWSAgID0gMiwKICAgIFFVQVRFUk5BUlkgPSAzLAogICAgSURFTlRJQ0FMICA9IDE1CiAgfTsKICAKICAvKioKICAqIExFU1MgaXMgcmV0dXJuZWQgaWYgc291cmNlIHN0cmluZyBpcyBjb21wYXJlZCB0byBiZSBsZXNzIHRoYW4gdGFyZ2V0CiAgKiBzdHJpbmcgaW4gdGhlIGNvbXBhcmUoKSBtZXRob2QuCiAgKiBFUVVBTCBpcyByZXR1cm5lZCBpZiBzb3VyY2Ugc3RyaW5nIGlzIGNvbXBhcmVkIHRvIGJlIGVxdWFsIHRvIHRhcmdldAogICogc3RyaW5nIGluIHRoZSBjb21wYXJlKCkgbWV0aG9kLgogICogR1JFQVRFUiBpcyByZXR1cm5lZCBpZiBzb3VyY2Ugc3RyaW5nIGlzIGNvbXBhcmVkIHRvIGJlIGdyZWF0ZXIgdGhhbgogICogdGFyZ2V0IHN0cmluZyBpbiB0aGUgY29tcGFyZSgpIG1ldGhvZC4KICAqIEBzZWUgQ29sbGF0b3IjY29tcGFyZQogICogQHN0YWJsZQogICovCiAgZW51bSBFQ29tcGFyaXNvblJlc3VsdCAKICB7CiAgICBMRVNTID0gLTEsCiAgICBFUVVBTCA9IDAsCiAgICBHUkVBVEVSID0gMQogIH07CiAgCiAgLy8gQ29sbGF0b3IgcHVibGljIGRlc3RydWN0b3IgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAKICAvKioKICAqIERlc3RydWN0b3IKICAqIEBzdGFibGUKICAqLwogIHZpcnR1YWwgfkNvbGxhdG9yKCk7CgogIC8vIENvbGxhdG9yIHB1YmxpYyBtZXRob2RzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogIC8qKgogICogUmV0dXJucyB0cnVlIGlmICJvdGhlciIgaXMgdGhlIHNhbWUgYXMgInRoaXMiCiAgKiBAcGFyYW0gb3RoZXIgQ29sbGF0b3Igb2JqZWN0IHRvIGJlIGNvbXBhcmVkCiAgKiBAcmV0dXJuIHRydWUgaWYgb3RoZXIgaXMgdGhlIHNhbWUgYXMgdGhpcy4KICAqIEBzdGFibGUKICAqLwogIHZpcnR1YWwgVUJvb2wgb3BlcmF0b3I9PShjb25zdCBDb2xsYXRvciYgb3RoZXIpIGNvbnN0OwoKICAvKioKICAqIFJldHVybnMgdHJ1ZSBpZiAib3RoZXIiIGlzIG5vdCB0aGUgc2FtZSBhcyAidGhpcyIuCiAgKiBAcGFyYW0gb3RoZXIgQ29sbGF0b3Igb2JqZWN0IHRvIGJlIGNvbXBhcmVkCiAgKiBAcmV0dXJuIHRydWUgaWYgb3RoZXIgaXMgbm90IHRoZSBzYW1lIGFzIHRoaXMuCiAgKiBAc3RhYmxlCiAgKi8KICB2aXJ0dWFsIFVCb29sIG9wZXJhdG9yIT0oY29uc3QgQ29sbGF0b3ImIG90aGVyKSBjb25zdDsKCiAgLyoqCiAgKiBNYWtlcyBhIHNoYWxsb3cgY29weSBvZiB0aGUgY3VycmVudCBvYmplY3QuCiAgKiBAcmV0dXJuIGEgY29weSBvZiB0aGlzIG9iamVjdAogICogQHN0YWJsZQogICovCiAgdmlydHVhbCBDb2xsYXRvciogY2xvbmUodm9pZCkgY29uc3QgPSAwOwoKICAvKioKICAqIENyZWF0ZXMgdGhlIENvbGxhdG9yIG9iamVjdCBmb3IgdGhlIGN1cnJlbnQgZGVmYXVsdCBsb2NhbGUuCiAgKiBUaGUgZGVmYXVsdCBsb2NhbGUgaXMgZGV0ZXJtaW5lZCBieSBMb2NhbGU6OmdldERlZmF1bHQuCiAgKiBUaGUgVUVycm9yQ29kZSYgZXJyIHBhcmFtZXRlciBpcyB1c2VkIHRvIHJldHVybiBzdGF0dXMgaW5mb3JtYXRpb24gdG8gdGhlIHVzZXIuCiAgKiBUbyBjaGVjayB3aGV0aGVyIHRoZSBjb25zdHJ1Y3Rpb24gc3VjY2VlZGVkIG9yIG5vdCwgeW91IHNob3VsZCBjaGVjayB0aGUgCiAgKiB2YWx1ZSBvZiBVX1NVQ0NFU1MoZXJyKS4gIElmIHlvdSB3aXNoIG1vcmUgZGV0YWlsZWQgaW5mb3JtYXRpb24sIHlvdSBjYW4gCiAgKiBjaGVjayBmb3IgaW5mb3JtYXRpb25hbCBlcnJvciByZXN1bHRzIHdoaWNoIHN0aWxsIGluZGljYXRlIHN1Y2Nlc3MuCiAgKiBVX1VTSU5HX0ZBTExCQUNLX0VSUk9SIGluZGljYXRlcyB0aGF0IGEgZmFsbCBiYWNrIGxvY2FsZSB3YXMgdXNlZC4gRm9yCiAgKiBleGFtcGxlLCAnZGVfQ0gnIHdhcyByZXF1ZXN0ZWQsIGJ1dCBub3RoaW5nIHdhcyBmb3VuZCB0aGVyZSwgc28gJ2RlJyB3YXMKICAqIHVzZWQuIFVfVVNJTkdfREVGQVVMVF9FUlJPUiBpbmRpY2F0ZXMgdGhhdCB0aGUgZGVmYXVsdCBsb2NhbGUgZGF0YSB3YXMKICAqIHVzZWQ7IG5laXRoZXIgdGhlIHJlcXVlc3RlZCBsb2NhbGUgbm9yIGFueSBvZiBpdHMgZmFsbCBiYWNrIGxvY2FsZXMKICAqIGNvdWxkIGJlIGZvdW5kLgogICogVGhlIGNhbGxlciBvd25zIHRoZSByZXR1cm5lZCBvYmplY3QgYW5kIGlzIHJlc3BvbnNpYmxlIGZvciBkZWxldGluZyBpdC4KICAqCiAgKiBAcGFyYW0gZXJyICAgIHRoZSBlcnJvciBjb2RlIHN0YXR1cy4KICAqIEByZXR1cm4gICAgICAgdGhlIGNvbGxhdGlvbiBvYmplY3Qgb2YgdGhlIGRlZmF1bHQgbG9jYWxlLihmb3IgZXhhbXBsZSwgZW5fVVMpCiAgKiBAc2VlIExvY2FsZSNnZXREZWZhdWx0CiAgKiBAc3RhYmxlCiAgKi8KICBzdGF0aWMgQ29sbGF0b3IqIGNyZWF0ZUluc3RhbmNlKFVFcnJvckNvZGUmICBlcnIpOwoKICAvKioKICAqIEdldHMgdGhlIHRhYmxlLWJhc2VkIGNvbGxhdGlvbiBvYmplY3QgZm9yIHRoZSBkZXNpcmVkIGxvY2FsZS4gVGhlCiAgKiByZXNvdXJjZSBvZiB0aGUgZGVzaXJlZCBsb2NhbGUgd2lsbCBiZSBsb2FkZWQgYnkgUmVzb3VyY2VMb2FkZXIuIAogICogTG9jYWxlOjpFTkdMSVNIIGlzIHRoZSBiYXNlIGNvbGxhdGlvbiB0YWJsZSBhbmQgYWxsIG90aGVyIGxhbmd1YWdlcyBhcmUgCiAgKiBidWlsdCBvbiB0b3Agb2YgaXQgd2l0aCBhZGRpdGlvbmFsIGxhbmd1YWdlLXNwZWNpZmljIG1vZGlmaWNhdGlvbnMuCiAgKiBUaGUgVUVycm9yQ29kZSYgZXJyIHBhcmFtZXRlciBpcyB1c2VkIHRvIHJldHVybiBzdGF0dXMgaW5mb3JtYXRpb24gdG8gdGhlIHVzZXIuCiAgKiBUbyBjaGVjayB3aGV0aGVyIHRoZSBjb25zdHJ1Y3Rpb24gc3VjY2VlZGVkIG9yIG5vdCwgeW91IHNob3VsZCBjaGVjawogICogdGhlIHZhbHVlIG9mIFVfU1VDQ0VTUyhlcnIpLiAgSWYgeW91IHdpc2ggbW9yZSBkZXRhaWxlZCBpbmZvcm1hdGlvbiwgeW91CiAgKiBjYW4gY2hlY2sgZm9yIGluZm9ybWF0aW9uYWwgZXJyb3IgcmVzdWx0cyB3aGljaCBzdGlsbCBpbmRpY2F0ZSBzdWNjZXNzLgogICogVV9VU0lOR19GQUxMQkFDS19FUlJPUiBpbmRpY2F0ZXMgdGhhdCBhIGZhbGwgYmFjayBsb2NhbGUgd2FzIHVzZWQuICBGb3IKICAqIGV4YW1wbGUsICdkZV9DSCcgd2FzIHJlcXVlc3RlZCwgYnV0IG5vdGhpbmcgd2FzIGZvdW5kIHRoZXJlLCBzbyAnZGUnIHdhcwogICogdXNlZC4gIFVfVVNJTkdfREVGQVVMVF9FUlJPUiBpbmRpY2F0ZXMgdGhhdCB0aGUgZGVmYXVsdCBsb2NhbGUgZGF0YSB3YXMKICAqIHVzZWQ7IG5laXRoZXIgdGhlIHJlcXVlc3RlZCBsb2NhbGUgbm9yIGFueSBvZiBpdHMgZmFsbCBiYWNrIGxvY2FsZXMKICAqIGNvdWxkIGJlIGZvdW5kLgogICogVGhlIGNhbGxlciBvd25zIHRoZSByZXR1cm5lZCBvYmplY3QgYW5kIGlzIHJlc3BvbnNpYmxlIGZvciBkZWxldGluZyBpdC4KICAqIEBwYXJhbSBsb2MgICAgVGhlIGxvY2FsZSBJRCBmb3Igd2hpY2ggdG8gb3BlbiBhIGNvbGxhdG9yLgogICogQHBhcmFtIGVyciAgICB0aGUgZXJyb3IgY29kZSBzdGF0dXMuCiAgKiBAcmV0dXJuICAgICAgIHRoZSBjcmVhdGVkIHRhYmxlLWJhc2VkIGNvbGxhdGlvbiBvYmplY3QgYmFzZWQgb24gdGhlIGRlc2lyZWQKICAqICAgICAgICAgICAgICAgbG9jYWxlLgogICogQHNlZSBMb2NhbGUKICAqIEBzZWUgUmVzb3VyY2VMb2FkZXIKICAqIEBzdGFibGUKICAqLwogIHN0YXRpYyBDb2xsYXRvciogY3JlYXRlSW5zdGFuY2UoY29uc3QgTG9jYWxlJiBsb2MsIFVFcnJvckNvZGUmIGVycik7CgogIC8qKgogICAqIENyZWF0ZSBhIENvbGxhdG9yIHdpdGggYSBzcGVjaWZpYyB2ZXJzaW9uLgogICAqIFRoaXMgaXMgdGhlIHNhbWUgYXMgY3JlYXRlSW5zdGFuY2UobG9jLCBlcnIpIGV4Y2VwdCB0aGF0IGdldFZlcnNpb24oKSBvZgogICAqIHRoZSByZXR1cm5lZCBvYmplY3QgaXMgZ3VhcmFudGVlZCB0byBiZSB0aGUgc2FtZSBhcyB0aGUgdmVyc2lvbgogICAqIHBhcmFtZXRlci4KICAgKiBUaGlzIGlzIGRlc2lnbmVkIHRvIGJlIHVzZWQgdG8gb3BlbiB0aGUgc2FtZSBjb2xsYXRvciBmb3IgYSBnaXZlbgogICAqIGxvY2FsZSBldmVuIHdoZW4gSUNVIGlzIHVwZGF0ZWQuCiAgICogVGhlIHNhbWUgbG9jYWxlIGFuZCB2ZXJzaW9uIGd1YXJhbnRlZXMgdGhlIHNhbWUgc29ydCBrZXlzIGFuZAogICAqIGNvbXBhcmlzb24gcmVzdWx0cy4KICAgKgogICAqIEBwYXJhbSBsb2MgVGhlIGxvY2FsZSBJRCBmb3Igd2hpY2ggdG8gb3BlbiBhIGNvbGxhdG9yLgogICAqIEBwYXJhbSB2ZXJzaW9uIFRoZSByZXF1ZXN0ZWQgY29sbGF0b3IgdmVyc2lvbi4KICAgKiBAcGFyYW0gZXJyIEEgcmVmZXJlbmNlIHRvIGEgVUVycm9yQ29kZSwKICAgKiAgICAgICAgICAgIG11c3Qgbm90IGluZGljYXRlIGEgZmFpbHVyZSBiZWZvcmUgY2FsbGluZyB0aGlzIGZ1bmN0aW9uLgogICAqIEByZXR1cm4gQSBwb2ludGVyIHRvIGEgQ29sbGF0b3IsIG9yIDAgaWYgYW4gZXJyb3Igb2NjdXJyZWQKICAgKiAgICAgICAgIG9yIGEgY29sbGF0b3Igd2l0aCB0aGUgcmVxdWVzdGVkIHZlcnNpb24gaXMgbm90IGF2YWlsYWJsZS4KICAgKgogICAqIEBzZWUgZ2V0VmVyc2lvbgogICAqIEBkcmFmdCBJQ1UgMS44CiAgICovCiAgc3RhdGljIENvbGxhdG9yICpjcmVhdGVJbnN0YW5jZShjb25zdCBMb2NhbGUgJmxvYywgVVZlcnNpb25JbmZvIHZlcnNpb24sIFVFcnJvckNvZGUgJmVycik7CgogIC8qKgogICogVGhlIGNvbXBhcmlzb24gZnVuY3Rpb24gY29tcGFyZXMgdGhlIGNoYXJhY3RlciBkYXRhIHN0b3JlZCBpbiB0d28KICAqIGRpZmZlcmVudCBzdHJpbmdzLiBSZXR1cm5zIGluZm9ybWF0aW9uIGFib3V0IHdoZXRoZXIgYSBzdHJpbmcgaXMgbGVzcyAKICAqIHRoYW4sIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byBhbm90aGVyIHN0cmluZy4KICAqIEBwYXJhbSBzb3VyY2UgdGhlIHNvdXJjZSBzdHJpbmcgdG8gYmUgY29tcGFyZWQgd2l0aC4KICAqIEBwYXJhbSB0YXJnZXQgdGhlIHN0cmluZyB0aGF0IGlzIHRvIGJlIGNvbXBhcmVkIHdpdGggdGhlIHNvdXJjZSBzdHJpbmcuCiAgKiBAcmV0dXJuIFJldHVybnMgYSBieXRlIHZhbHVlLiBHUkVBVEVSIGlmIHNvdXJjZSBpcyBncmVhdGVyCiAgKiB0aGFuIHRhcmdldDsgRVFVQUwgaWYgc291cmNlIGlzIGVxdWFsIHRvIHRhcmdldDsgTEVTUyBpZiBzb3VyY2UgaXMgbGVzcwogICogdGhhbiB0YXJnZXQKICAqIEBzdGFibGUKICAqKi8KICB2aXJ0dWFsIEVDb21wYXJpc29uUmVzdWx0IGNvbXBhcmUoY29uc3QgVW5pY29kZVN0cmluZyYgc291cmNlLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVW5pY29kZVN0cmluZyYgdGFyZ2V0KSBjb25zdCA9IDA7CgogIC8qKgogICogRG9lcyB0aGUgc2FtZSB0aGluZyBhcyBjb21wYXJlIGJ1dCBsaW1pdHMgdGhlIGNvbXBhcmlzb24gdG8gYSBzcGVjaWZpZWQgCiAgKiBsZW5ndGgKICAqIEBwYXJhbSBzb3VyY2UgdGhlIHNvdXJjZSBzdHJpbmcgdG8gYmUgY29tcGFyZWQgd2l0aC4KICAqIEBwYXJhbSB0YXJnZXQgdGhlIHN0cmluZyB0aGF0IGlzIHRvIGJlIGNvbXBhcmVkIHdpdGggdGhlIHNvdXJjZSBzdHJpbmcuCiAgKiBAcGFyYW0gbGVuZ3RoIHRoZSBsZW5ndGggdGhlIGNvbXBhcmlzb24gaXMgbGltaXR0ZWQgdG8KICAqIEByZXR1cm4gUmV0dXJucyBhIGJ5dGUgdmFsdWUuIEdSRUFURVIgaWYgc291cmNlICh1cCB0byB0aGUgc3BlY2lmaWVkIAogICogICAgICAgICBsZW5ndGgpIGlzIGdyZWF0ZXIgdGhhbiB0YXJnZXQ7IEVRVUFMIGlmIHNvdXJjZSAodXAgdG8gc3BlY2lmaWVkIAogICogICAgICAgICBsZW5ndGgpIGlzIGVxdWFsIHRvIHRhcmdldDsgTEVTUyBpZiBzb3VyY2UgKHVwIHRvIHRoZSBzcGVjaWZpZWQgCiAgKiAgICAgICAgIGxlbmd0aCkgaXMgbGVzcyAgdGhhbiB0YXJnZXQuICAgCiAgKiBAc3RhYmxlCiAgKi8KICB2aXJ0dWFsIEVDb21wYXJpc29uUmVzdWx0IGNvbXBhcmUoY29uc3QgVW5pY29kZVN0cmluZyYgc291cmNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBVbmljb2RlU3RyaW5nJiB0YXJnZXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludDMyX3QgbGVuZ3RoKSBjb25zdCA9IDA7CiAgICAKICAvKioKICAqIFRoZSBjb21wYXJpc29uIGZ1bmN0aW9uIGNvbXBhcmVzIHRoZSBjaGFyYWN0ZXIgZGF0YSBzdG9yZWQgaW4gdHdvCiAgKiBkaWZmZXJlbnQgc3RyaW5nIGFycmF5cy4gUmV0dXJucyBpbmZvcm1hdGlvbiBhYm91dCB3aGV0aGVyIGEgc3RyaW5nIGFycmF5IAogICogaXMgbGVzcyB0aGFuLCBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gYW5vdGhlciBzdHJpbmcgYXJyYXkuCiAgKiBAcGFyYW0gc291cmNlIHRoZSBzb3VyY2Ugc3RyaW5nIGFycmF5IHRvIGJlIGNvbXBhcmVkIHdpdGguCiAgKiBAcGFyYW0gc291cmNlTGVuZ3RoIHRoZSBsZW5ndGggb2YgdGhlIHNvdXJjZSBzdHJpbmcgYXJyYXkuICBJZiB0aGlzIHZhbHVlCiAgKiAgICAgICAgaXMgZXF1YWwgdG8gLTEsIHRoZSBzdHJpbmcgYXJyYXkgaXMgbnVsbC10ZXJtaW5hdGVkLgogICogQHBhcmFtIHRhcmdldCB0aGUgc3RyaW5nIHRoYXQgaXMgdG8gYmUgY29tcGFyZWQgd2l0aCB0aGUgc291cmNlIHN0cmluZy4KICAqIEBwYXJhbSB0YXJnZXRMZW5ndGggdGhlIGxlbmd0aCBvZiB0aGUgdGFyZ2V0IHN0cmluZyBhcnJheS4gIElmIHRoaXMgdmFsdWUKICAqICAgICAgICBpcyBlcXVhbCB0byAtMSwgdGhlIHN0cmluZyBhcnJheSBpcyBudWxsLXRlcm1pbmF0ZWQuCiAgKiBAcmV0dXJuIFJldHVybnMgYSBieXRlIHZhbHVlLiBHUkVBVEVSIGlmIHNvdXJjZSBpcyBncmVhdGVyIHRoYW4gdGFyZ2V0OyAKICAqICAgICAgICAgRVFVQUwgaWYgc291cmNlIGlzIGVxdWFsIHRvIHRhcmdldDsgTEVTUyBpZiBzb3VyY2UgaXMgbGVzcyB0aGFuIAogICogICAgICAgICB0YXJnZXQKICAqIEBzdGFibGUKICAqLwogIHZpcnR1YWwgRUNvbXBhcmlzb25SZXN1bHQgY29tcGFyZShjb25zdCBVQ2hhciogc291cmNlLCBpbnQzMl90IHNvdXJjZUxlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVUNoYXIqIHRhcmdldCwgaW50MzJfdCB0YXJnZXRMZW5ndGgpIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCA9IDA7CgogIC8qKiAKICAqIFRyYW5zZm9ybXMgdGhlIHN0cmluZyBpbnRvIGEgc2VyaWVzIG9mIGNoYXJhY3RlcnMgdGhhdCBjYW4gYmUgY29tcGFyZWQKICAqIHdpdGggQ29sbGF0aW9uS2V5Ojpjb21wYXJlVG8uIEl0IGlzIG5vdCBwb3NzaWJsZSB0byByZXN0b3JlIHRoZSBvcmlnaW5hbAogICogc3RyaW5nIGZyb20gdGhlIGNoYXJzIGluIHRoZSBzb3J0IGtleS4gIFRoZSBnZW5lcmF0ZWQgc29ydCBrZXkgaGFuZGxlcyAKICAqIG9ubHkgYSBsaW1pdGVkIG51bWJlciBvZiBpZ25vcmFibGUgY2hhcmFjdGVycy4KICAqIDxwPlVzZSBDb2xsYXRpb25LZXk6OmVxdWFscyBvciBDb2xsYXRpb25LZXk6OmNvbXBhcmUgdG8gY29tcGFyZSB0aGUKICAqIGdlbmVyYXRlZCBzb3J0IGtleXMuCiAgKiBJZiB0aGUgc291cmNlIHN0cmluZyBpcyBudWxsLCBhIG51bGwgY29sbGF0aW9uIGtleSB3aWxsIGJlIHJldHVybmVkLgogICogQHBhcmFtIHNvdXJjZSB0aGUgc291cmNlIHN0cmluZyB0byBiZSB0cmFuc2Zvcm1lZCBpbnRvIGEgc29ydCBrZXkuCiAgKiBAcGFyYW0ga2V5IHRoZSBjb2xsYXRpb24ga2V5IHRvIGJlIGZpbGxlZCBpbgogICogQHBhcmFtIHN0YXR1cyB0aGUgZXJyb3IgY29kZSBzdGF0dXMuCiAgKiBAcmV0dXJuIHRoZSBjb2xsYXRpb24ga2V5IG9mIHRoZSBzdHJpbmcgYmFzZWQgb24gdGhlIGNvbGxhdGlvbiBydWxlcy4KICAqIEBzZWUgQ29sbGF0aW9uS2V5I2NvbXBhcmUKICAqIEBzdGFibGUKICAqLwogIHZpcnR1YWwgQ29sbGF0aW9uS2V5JiBnZXRDb2xsYXRpb25LZXkoY29uc3QgVW5pY29kZVN0cmluZyYgIHNvdXJjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvbGxhdGlvbktleSYga2V5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYgc3RhdHVzKSBjb25zdCA9IDA7CgogIC8qKiAKICAqIFRyYW5zZm9ybXMgdGhlIHN0cmluZyBpbnRvIGEgc2VyaWVzIG9mIGNoYXJhY3RlcnMgdGhhdCBjYW4gYmUgY29tcGFyZWQKICAqIHdpdGggQ29sbGF0aW9uS2V5Ojpjb21wYXJlVG8uIEl0IGlzIG5vdCBwb3NzaWJsZSB0byByZXN0b3JlIHRoZSBvcmlnaW5hbAogICogc3RyaW5nIGZyb20gdGhlIGNoYXJzIGluIHRoZSBzb3J0IGtleS4gIFRoZSBnZW5lcmF0ZWQgc29ydCBrZXkgaGFuZGxlcyAKICAqIG9ubHkgYSBsaW1pdGVkIG51bWJlciBvZiBpZ25vcmFibGUgY2hhcmFjdGVycy4KICAqIDxwPlVzZSBDb2xsYXRpb25LZXk6OmVxdWFscyBvciBDb2xsYXRpb25LZXk6OmNvbXBhcmUgdG8gY29tcGFyZSB0aGUKICAqIGdlbmVyYXRlZCBzb3J0IGtleXMuCiAgKiA8cD5JZiB0aGUgc291cmNlIHN0cmluZyBpcyBudWxsLCBhIG51bGwgY29sbGF0aW9uIGtleSB3aWxsIGJlIHJldHVybmVkLgogICogQHBhcmFtIHNvdXJjZSB0aGUgc291cmNlIHN0cmluZyB0byBiZSB0cmFuc2Zvcm1lZCBpbnRvIGEgc29ydCBrZXkuCiAgKiBAcGFyYW0gc291cmNlTGVuZ3RoIGxlbmd0aCBvZiB0aGUgY29sbGF0aW9uIGtleQogICogQHBhcmFtIGtleSB0aGUgY29sbGF0aW9uIGtleSB0byBiZSBmaWxsZWQgaW4KICAqIEBwYXJhbSBzdGF0dXMgdGhlIGVycm9yIGNvZGUgc3RhdHVzLgogICogQHJldHVybiB0aGUgY29sbGF0aW9uIGtleSBvZiB0aGUgc3RyaW5nIGJhc2VkIG9uIHRoZSBjb2xsYXRpb24gcnVsZXMuCiAgKiBAc2VlIENvbGxhdGlvbktleSNjb21wYXJlCiAgKiBAc3RhYmxlCiAgKi8KICB2aXJ0dWFsIENvbGxhdGlvbktleSYgZ2V0Q29sbGF0aW9uS2V5KGNvbnN0IFVDaGFyKnNvdXJjZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQzMl90IHNvdXJjZUxlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvbGxhdGlvbktleSYga2V5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYgc3RhdHVzKSBjb25zdCA9IDA7CiAgLyoqCiAgKiBHZW5lcmF0ZXMgdGhlIGhhc2ggY29kZSBmb3IgdGhlIGNvbGxhdGlvbiBvYmplY3QKICAqIEBzdGFibGUKICAqLwogIHZpcnR1YWwgaW50MzJfdCBoYXNoQ29kZSh2b2lkKSBjb25zdCA9IDA7CgogIC8qKgogICogR2V0cyB0aGUgbG9jYWxlIG9mIHRoZSBDb2xsYXRvcgogICoKICAqIEBwYXJhbSB0eXBlIGNhbiBiZSBlaXRoZXIgcmVxdWVzdGVkLCB2YWxpZCBvciBhY3R1YWwgbG9jYWxlLiBGb3IgbW9yZQogICogICAgICAgICAgICAgaW5mb3JtYXRpb24gc2VlIHRoZSBkZWZpbml0aW9uIG9mIFVMb2NEYXRhTG9jYWxlVHlwZSBpbgogICogICAgICAgICAgICAgdWxvYy5oCiAgKiBAcmV0dXJuIGxvY2FsZSB3aGVyZSB0aGUgY29sbGF0aW9uIGRhdGEgbGl2ZXMuIElmIHRoZSBjb2xsYXRvcgogICogICAgICAgICB3YXMgaW5zdGFudGlhdGVkIGZyb20gcnVsZXMsIGxvY2FsZSBpcyBlbXB0eS4KICAqIEBkcmFmdCBJQ1UgMi4xCiAgKi8KICB2aXJ0dWFsIGNvbnN0IExvY2FsZSBnZXRMb2NhbGUoVUxvY0RhdGFMb2NhbGVUeXBlIHR5cGUsIFVFcnJvckNvZGUmIHN0YXR1cykgY29uc3QgPSAwOwoKICAvKioKICAqIENvbnZlbmllbmNlIG1ldGhvZCBmb3IgY29tcGFyaW5nIHR3byBzdHJpbmdzIGJhc2VkIG9uIHRoZSBjb2xsYXRpb24gcnVsZXMuCiAgKiBAcGFyYW0gc291cmNlIHRoZSBzb3VyY2Ugc3RyaW5nIHRvIGJlIGNvbXBhcmVkIHdpdGguCiAgKiBAcGFyYW0gdGFyZ2V0IHRoZSB0YXJnZXQgc3RyaW5nIHRvIGJlIGNvbXBhcmVkIHdpdGguCiAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIGZpcnN0IHN0cmluZyBpcyBncmVhdGVyIHRoYW4gdGhlIHNlY29uZCBvbmUsCiAgKiAgICAgICAgIGFjY29yZGluZyB0byB0aGUgY29sbGF0aW9uIHJ1bGVzLiBmYWxzZSwgb3RoZXJ3aXNlLgogICogQHNlZSBDb2xsYXRvciNjb21wYXJlCiAgKiBAc3RhYmxlCiAgKi8KICBVQm9vbCBncmVhdGVyKGNvbnN0IFVuaWNvZGVTdHJpbmcmIHNvdXJjZSwgY29uc3QgVW5pY29kZVN0cmluZyYgdGFyZ2V0KSAKICAgICAgICAgICAgICAgIGNvbnN0OwoKICAvKioKICAqIENvbnZlbmllbmNlIG1ldGhvZCBmb3IgY29tcGFyaW5nIHR3byBzdHJpbmdzIGJhc2VkIG9uIHRoZSBjb2xsYXRpb24gcnVsZXMuCiAgKiBAcGFyYW0gc291cmNlIHRoZSBzb3VyY2Ugc3RyaW5nIHRvIGJlIGNvbXBhcmVkIHdpdGguCiAgKiBAcGFyYW0gdGFyZ2V0IHRoZSB0YXJnZXQgc3RyaW5nIHRvIGJlIGNvbXBhcmVkIHdpdGguCiAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIGZpcnN0IHN0cmluZyBpcyBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gdGhlIHNlY29uZCAKICAqICAgICAgICAgb25lLCBhY2NvcmRpbmcgdG8gdGhlIGNvbGxhdGlvbiBydWxlcy4gZmFsc2UsIG90aGVyd2lzZS4KICAqIEBzZWUgQ29sbGF0b3IjY29tcGFyZQogICogQHN0YWJsZQogICovCiAgVUJvb2wgZ3JlYXRlck9yRXF1YWwoY29uc3QgVW5pY29kZVN0cmluZyYgc291cmNlLCAKICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBVbmljb2RlU3RyaW5nJiB0YXJnZXQpIGNvbnN0OwogIC8qKgogICogQ29udmVuaWVuY2UgbWV0aG9kIGZvciBjb21wYXJpbmcgdHdvIHN0cmluZ3MgYmFzZWQgb24gdGhlIGNvbGxhdGlvbiBydWxlcy4KICAqIEBwYXJhbSBzb3VyY2UgdGhlIHNvdXJjZSBzdHJpbmcgdG8gYmUgY29tcGFyZWQgd2l0aC4KICAqIEBwYXJhbSB0YXJnZXQgdGhlIHRhcmdldCBzdHJpbmcgdG8gYmUgY29tcGFyZWQgd2l0aC4KICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgc3RyaW5ncyBhcmUgZXF1YWwgYWNjb3JkaW5nIHRvIHRoZSBjb2xsYXRpb24gcnVsZXMuICAKICAqICAgICAgICAgZmFsc2UsIG90aGVyd2lzZS4KICAqIEBzZWUgQ29sbGF0b3IjY29tcGFyZQogICogQHN0YWJsZQogICovCiAgVUJvb2wgZXF1YWxzKGNvbnN0IFVuaWNvZGVTdHJpbmcmIHNvdXJjZSwgY29uc3QgVW5pY29kZVN0cmluZyYgdGFyZ2V0KSBjb25zdDsKICAgICAgICAKICAvKioKICAqIERldGVybWluZXMgdGhlIG1pbmltdW0gc3RyZW5ndGggdGhhdCB3aWxsIGJlIHVzZSBpbiBjb21wYXJpc29uIG9yCiAgKiB0cmFuc2Zvcm1hdGlvbi4KICAqIDxwPkUuZy4gd2l0aCBzdHJlbmd0aCA9PSBTRUNPTkRBUlksIHRoZSB0ZXJ0aWFyeSBkaWZmZXJlbmNlIGlzIGlnbm9yZWQKICAqIDxwPkUuZy4gd2l0aCBzdHJlbmd0aCA9PSBQUklNQVJZLCB0aGUgc2Vjb25kYXJ5IGFuZCB0ZXJ0aWFyeSBkaWZmZXJlbmNlCiAgKiBhcmUgaWdub3JlZC4KICAqIEByZXR1cm4gdGhlIGN1cnJlbnQgY29tcGFyaXNvbiBsZXZlbC4KICAqIEBzZWUgQ29sbGF0b3Ijc2V0U3RyZW5ndGgKICAqIEBzdGFibGUKICAqLwogIHZpcnR1YWwgRUNvbGxhdGlvblN0cmVuZ3RoIGdldFN0cmVuZ3RoKHZvaWQpIGNvbnN0ID0gMDsKICAKICAvKioKICAqIFNldHMgdGhlIG1pbmltdW0gc3RyZW5ndGggdG8gYmUgdXNlZCBpbiBjb21wYXJpc29uIG9yIHRyYW5zZm9ybWF0aW9uLgogICogPHA+RXhhbXBsZSBvZiB1c2U6CiAgKiA8cHJlPgogICogIFxjb2RlCiAgKiAgVUVycm9yQ29kZSBzdGF0dXMgPSBVX1pFUk9fRVJST1I7CiAgKiAgQ29sbGF0b3IqbXlDb2xsYXRpb24gPSBDb2xsYXRvcjo6Y3JlYXRlSW5zdGFuY2UoTG9jYWxlOjpVUywgCiAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXR1cyk7CiAgKiAgaWYgKFVfRkFJTFVSRShzdGF0dXMpKSByZXR1cm47CiAgKiAgbXlDb2xsYXRpb24tPnNldFN0cmVuZ3RoKENvbGxhdG9yOjpQUklNQVJZKTsKICAqICAvLyByZXN1bHQgd2lsbCBiZSAiYWJjIiA9PSAiQUJDIgogICogIC8vIHRlcnRpYXJ5IGRpZmZlcmVuY2VzIHdpbGwgYmUgaWdub3JlZAogICogIENvbGxhdG9yOjpDb21wYXJpc29uUmVzdWx0IHJlc3VsdCA9IG15Q29sbGF0aW9uLT5jb21wYXJlKCJhYmMiLCAKICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQUJDIik7CiAgKiBcZW5kY29kZSAKICAqIDwvcHJlPgogICogQHNlZSBDb2xsYXRvciNnZXRTdHJlbmd0aAogICogQHBhcmFtIG5ld1N0cmVuZ3RoIHRoZSBuZXcgY29tcGFyaXNvbiBsZXZlbC4KICAqIEBzdGFibGUKICAqLwogIHZpcnR1YWwgdm9pZCBzZXRTdHJlbmd0aChFQ29sbGF0aW9uU3RyZW5ndGggbmV3U3RyZW5ndGgpID0gMDsKCiAgLyoqCiAgKiBHZXQgbmFtZSBvZiB0aGUgb2JqZWN0IGZvciB0aGUgZGVzaXJlZCBMb2NhbGUsIGluIHRoZSBkZXNpcmVkIGxhbmdhdWdlCiAgKiBAcGFyYW0gb2JqZWN0TG9jYWxlIG11c3QgYmUgZnJvbSBnZXRBdmFpbGFibGVMb2NhbGVzCiAgKiBAcGFyYW0gZGlzcGxheUxvY2FsZSBzcGVjaWZpZXMgdGhlIGRlc2lyZWQgbG9jYWxlIGZvciBvdXRwdXQKICAqIEBwYXJhbSBuYW1lIHRoZSBmaWxsLWluIHBhcmFtZXRlciBvZiB0aGUgcmV0dXJuIHZhbHVlCiAgKiBAcmV0dXJuIGRpc3BsYXktYWJsZSBuYW1lIG9mIHRoZSBvYmplY3QgZm9yIHRoZSBvYmplY3QgbG9jYWxlIGluIHRoZQogICogICAgICAgICBkZXNpcmVkIGxhbmd1YWdlCiAgKiBAc3RhYmxlCiAgKi8KICBzdGF0aWMgVW5pY29kZVN0cmluZyYgZ2V0RGlzcGxheU5hbWUoY29uc3QgTG9jYWxlJiBvYmplY3RMb2NhbGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IExvY2FsZSYgZGlzcGxheUxvY2FsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVW5pY29kZVN0cmluZyYgbmFtZSk7CiAgLyoqCiAgKiBHZXQgbmFtZSBvZiB0aGUgb2JqZWN0IGZvciB0aGUgZGVzaXJlZCBMb2NhbGUsIGluIHRoZSBsYW5nYXVnZSBvZiB0aGUKICAqIGRlZmF1bHQgbG9jYWxlLgogICogQHBhcmFtIG9iamVjdExvY2FsZSBtdXN0IGJlIGZyb20gZ2V0QXZhaWxhYmxlTG9jYWxlcwogICogQHBhcmFtIG5hbWUgdGhlIGZpbGwtaW4gcGFyYW1ldGVyIG9mIHRoZSByZXR1cm4gdmFsdWUKICAqIEByZXR1cm4gbmFtZSBvZiB0aGUgb2JqZWN0IGZvciB0aGUgZGVzaXJlZCBsb2NhbGUgaW4gdGhlIGRlZmF1bHQgbGFuZ3VhZ2UKICAqIEBzdGFibGUKICAqLwogIHN0YXRpYyBVbmljb2RlU3RyaW5nJiBnZXREaXNwbGF5TmFtZShjb25zdCBMb2NhbGUmIG9iamVjdExvY2FsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVW5pY29kZVN0cmluZyYgbmFtZSk7CgogIC8qKgogICogR2V0IHRoZSBzZXQgb2YgTG9jYWxlcyBmb3Igd2hpY2ggQ29sbGF0aW9ucyBhcmUgaW5zdGFsbGVkCiAgKiBAcGFyYW0gY291bnQgdGhlIG91dHB1dCBwYXJhbWV0ZXIgb2YgbnVtYmVyIG9mIGVsZW1lbnRzIGluIHRoZSBsb2NhbGUgbGlzdAogICogQHJldHVybiB0aGUgbGlzdCBvZiBhdmFpbGFibGUgbG9jYWxlcyB3aGljaCBjb2xsYXRpb25zIGFyZSBpbnN0YWxsZWQKICAqIEBzdGFibGUKICAqLwogIHN0YXRpYyBjb25zdCBMb2NhbGUqIGdldEF2YWlsYWJsZUxvY2FsZXMoaW50MzJfdCYgY291bnQpOwoKICAvKioKICAqIEdldHMgdGhlIHZlcnNpb24gaW5mb3JtYXRpb24gZm9yIGEgQ29sbGF0b3IuIAogICogQHBhcmFtIGluZm8gdGhlIHZlcnNpb24gIyBpbmZvcm1hdGlvbiwgdGhlIHJlc3VsdCB3aWxsIGJlIGZpbGxlZCBpbgogICogQHN0YWJsZQogICovCiAgdmlydHVhbCB2b2lkIGdldFZlcnNpb24oVVZlcnNpb25JbmZvIGluZm8pIGNvbnN0ID0gMDsKCiAgLyoqCiAgKiBSZXR1cm5zIGEgdW5pcXVlIGNsYXNzIElEIFBPTFlNT1JQSElDQUxMWS4gUHVyZSB2aXJ0dWFsIG1ldGhvZC4KICAqIFRoaXMgbWV0aG9kIGlzIHRvIGltcGxlbWVudCBhIHNpbXBsZSB2ZXJzaW9uIG9mIFJUVEksIHNpbmNlIG5vdCBhbGwgQysrIAogICogY29tcGlsZXJzIHN1cHBvcnQgZ2VudWluZSBSVFRJLiBQb2x5bW9ycGhpYyBvcGVyYXRvcj09KCkgYW5kIGNsb25lKCkgCiAgKiBtZXRob2RzIGNhbGwgdGhpcyBtZXRob2QuCiAgKiBDb25jcmV0ZSBzdWJjbGFzc2VzIG9mIEZvcm1hdCBtdXN0IGltcGxlbWVudCBnZXREeW5hbWljQ2xhc3NJRCgpIGFuZCBhbHNvIAogICogYSBzdGF0aWMgbWV0aG9kIGFuZCBkYXRhIG1lbWJlcjoKICAqICAgc3RhdGljIFVDbGFzc0lEIGdldFN0YXRpY0NsYXNzSUQoKSAKICAqICAgeyAKICAqICAgICAgcmV0dXJuIChVQ2xhc3NJRCkmZmdDbGFzc0lEOyAKICAqICAgfQogICogICBzdGF0aWMgY2hhciBmZ0NsYXNzSUQ7CiAgKiBAcmV0dXJuIFRoZSBjbGFzcyBJRCBmb3IgdGhpcyBvYmplY3QuIEFsbCBvYmplY3RzIG9mIGEgZ2l2ZW4gY2xhc3MgaGF2ZSAKICAqICAgICAgICAgdGhlIHNhbWUgY2xhc3MgSUQuICBPYmplY3RzIG9mIG90aGVyIGNsYXNzZXMgaGF2ZSBkaWZmZXJlbnQgY2xhc3MgCiAgKiAgICAgICAgIElEcy4KICAqIEBzdGFibGUKICAqLwogIHZpcnR1YWwgVUNsYXNzSUQgZ2V0RHluYW1pY0NsYXNzSUQodm9pZCkgY29uc3QgPSAwOwoKICAvKioKICAqIFVuaXZlcnNhbCBhdHRyaWJ1dGUgc2V0dGVyCiAgKiBAcGFyYW0gYXR0ciBhdHRyaWJ1dGUgdHlwZSAKICAqIEBwYXJhbSB2YWx1ZSBhdHRyaWJ1dGUgdmFsdWUKICAqIEBwYXJhbSBzdGF0dXMgdG8gaW5kaWNhdGUgd2hldGhlciB0aGUgb3BlcmF0aW9uIHdlbnQgb24gc21vb3RobHkgb3IgCiAgKiAgICAgICAgdGhlcmUgd2VyZSBlcnJvcnMKICAqIEBkcmFmdCBJQ1UgMS44CiAgKi8KICB2aXJ0dWFsIHZvaWQgc2V0QXR0cmlidXRlKFVDb2xBdHRyaWJ1dGUgYXR0ciwgVUNvbEF0dHJpYnV0ZVZhbHVlIHZhbHVlLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUgJnN0YXR1cykgPSAwOwoKICAvKioKICAqIFVuaXZlcnNhbCBhdHRyaWJ1dGUgZ2V0dGVyCiAgKiBAcGFyYW0gYXR0ciBhdHRyaWJ1dGUgdHlwZQogICogQHBhcmFtIHN0YXR1cyB0byBpbmRpY2F0ZSB3aGV0aGVyIHRoZSBvcGVyYXRpb24gd2VudCBvbiBzbW9vdGhseSBvciAKICAqICAgICAgICB0aGVyZSB3ZXJlIGVycm9ycwogICogQHJldHVybiBhdHRyaWJ1dGUgdmFsdWUKICAqIEBkcmFmdCBJQ1UgMS44CiAgKi8KICB2aXJ0dWFsIFVDb2xBdHRyaWJ1dGVWYWx1ZSBnZXRBdHRyaWJ1dGUoVUNvbEF0dHJpYnV0ZSBhdHRyLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSAmc3RhdHVzKSA9IDA7CgogIC8qKiAKICAgKiBTZXRzIHRoZSB2YXJpYWJsZSB0b3AgdG8gYSBjb2xsYXRpb24gZWxlbWVudCB2YWx1ZSBvZiBhIHN0cmluZyBzdXBwbGllZC4gCiAgICogQHBhcmFtIHZhclRvcCBvbmUgb3IgbW9yZSAoaWYgY29udHJhY3Rpb24pIFVDaGFycyB0byB3aGljaCB0aGUgdmFyaWFibGUgdG9wIHNob3VsZCBiZSBzZXQKICAgKiBAcGFyYW0gbGVuIGxlbmd0aCBvZiB2YXJpYWJsZSB0b3Agc3RyaW5nLiBJZiAtMSBpdCBpcyBjb25zaWRlcmVkIHRvIGJlIHplcm8gdGVybWluYXRlZC4KICAgKiBAcGFyYW0gc3RhdHVzIGVycm9yIGNvZGUuIElmIGVycm9yIGNvZGUgaXMgc2V0LCB0aGUgcmV0dXJuIHZhbHVlIGlzIHVuZGVmaW5lZC4gRXJyb3JzIHNldCBieSB0aGlzIGZ1bmN0aW9uIGFyZTogPGJyPgogICAqICAgIFVfQ0VfTk9UX0ZPVU5EX0VSUk9SIGlmIG1vcmUgdGhhbiBvbmUgY2hhcmFjdGVyIHdhcyBwYXNzZWQgYW5kIHRoZXJlIGlzIG5vIHN1Y2ggYSBjb250cmFjdGlvbjxicj4KICAgKiAgICBVX1BSSU1BUllfVE9PX0xPTkdfRVJST1IgaWYgdGhlIHByaW1hcnkgZm9yIHRoZSB2YXJpYWJsZSB0b3AgaGFzIG1vcmUgdGhhbiB0d28gYnl0ZXMKICAgKiBAcmV0dXJuIGEgMzIgYml0IHZhbHVlIGNvbnRhaW5pbmcgdGhlIHZhbHVlIG9mIHRoZSB2YXJpYWJsZSB0b3AgaW4gdXBwZXIgMTYgYml0cy4gTG93ZXIgMTYgYml0cyBhcmUgdW5kZWZpbmVkCiAgICogQGRyYWZ0IElDVSAyLjAKICAgKi8KICB2aXJ0dWFsIHVpbnQzMl90IHNldFZhcmlhYmxlVG9wKGNvbnN0IFVDaGFyICp2YXJUb3AsIGludDMyX3QgbGVuLCBVRXJyb3JDb2RlICZzdGF0dXMpID0gMDsKCiAgLyoqIAogICAqIFNldHMgdGhlIHZhcmlhYmxlIHRvcCB0byBhIGNvbGxhdGlvbiBlbGVtZW50IHZhbHVlIG9mIGEgc3RyaW5nIHN1cHBsaWVkLiAKICAgKiBAcGFyYW0gdmFyVG9wIGFuIFVuaWNvZGVTdHJpbmcgc2l6ZSAxIG9yIG1vcmUgKGlmIGNvbnRyYWN0aW9uKSBvZiBVQ2hhcnMgdG8gd2hpY2ggdGhlIHZhcmlhYmxlIHRvcCBzaG91bGQgYmUgc2V0CiAgICogQHBhcmFtIHN0YXR1cyBlcnJvciBjb2RlLiBJZiBlcnJvciBjb2RlIGlzIHNldCwgdGhlIHJldHVybiB2YWx1ZSBpcyB1bmRlZmluZWQuIEVycm9ycyBzZXQgYnkgdGhpcyBmdW5jdGlvbiBhcmU6IDxicj4KICAgKiAgICBVX0NFX05PVF9GT1VORF9FUlJPUiBpZiBtb3JlIHRoYW4gb25lIGNoYXJhY3RlciB3YXMgcGFzc2VkIGFuZCB0aGVyZSBpcyBubyBzdWNoIGEgY29udHJhY3Rpb248YnI+CiAgICogICAgVV9QUklNQVJZX1RPT19MT05HX0VSUk9SIGlmIHRoZSBwcmltYXJ5IGZvciB0aGUgdmFyaWFibGUgdG9wIGhhcyBtb3JlIHRoYW4gdHdvIGJ5dGVzCiAgICogQHJldHVybiBhIDMyIGJpdCB2YWx1ZSBjb250YWluaW5nIHRoZSB2YWx1ZSBvZiB0aGUgdmFyaWFibGUgdG9wIGluIHVwcGVyIDE2IGJpdHMuIExvd2VyIDE2IGJpdHMgYXJlIHVuZGVmaW5lZAogICAqIEBkcmFmdCBJQ1UgMi4wCiAgICovCiAgdmlydHVhbCB1aW50MzJfdCBzZXRWYXJpYWJsZVRvcChjb25zdCBVbmljb2RlU3RyaW5nIHZhclRvcCwgVUVycm9yQ29kZSAmc3RhdHVzKSA9IDA7CgogIC8qKiAKICAgKiBTZXRzIHRoZSB2YXJpYWJsZSB0b3AgdG8gYSBjb2xsYXRpb24gZWxlbWVudCB2YWx1ZSBzdXBwbGllZC4gVmFyaWFibGUgdG9wIGlzIHNldCB0byB0aGUgdXBwZXIgMTYgYml0cy4gCiAgICogTG93ZXIgMTYgYml0cyBhcmUgaWdub3JlZC4KICAgKiBAcGFyYW0gdmFyVG9wIENFIHZhbHVlLCBhcyByZXR1cm5lZCBieSBzZXRWYXJpYWJsZVRvcCBvciB1Y29sKWdldFZhcmlhYmxlVG9wCiAgICogQHBhcmFtIHN0YXR1cyBlcnJvciBjb2RlIChub3QgY2hhbmdlZCBieSBmdW5jdGlvbikKICAgKiBAZHJhZnQgSUNVIDIuMAogICAqLwogIHZpcnR1YWwgdm9pZCBzZXRWYXJpYWJsZVRvcChjb25zdCB1aW50MzJfdCB2YXJUb3AsIFVFcnJvckNvZGUgJnN0YXR1cykgPSAwOwoKICAvKiogCiAgICogR2V0cyB0aGUgdmFyaWFibGUgdG9wIHZhbHVlIG9mIGEgQ29sbGF0b3IuIAogICAqIExvd2VyIDE2IGJpdHMgYXJlIHVuZGVmaW5lZCBhbmQgc2hvdWxkIGJlIGlnbm9yZWQuCiAgICogQHBhcmFtIHN0YXR1cyBlcnJvciBjb2RlIChub3QgY2hhbmdlZCBieSBmdW5jdGlvbikuIElmIGVycm9yIGNvZGUgaXMgc2V0LCB0aGUgcmV0dXJuIHZhbHVlIGlzIHVuZGVmaW5lZC4KICAgKiBAZHJhZnQgSUNVIDIuMAogICAqLwogIHZpcnR1YWwgdWludDMyX3QgZ2V0VmFyaWFibGVUb3AoVUVycm9yQ29kZSAmc3RhdHVzKSBjb25zdCA9IDA7CgoKICAvKioKICAqIFRocmVhZCBzYWZlIGNsb25pbmcgb3BlcmF0aW9uCiAgKiBAcmV0dXJuIHBvaW50ZXIgdG8gdGhlIG5ldyBjbG9uZSwgdXNlciBzaG91bGQgcmVtb3ZlIGl0LgogICogQGRyYWZ0IElDVSAxLjgKICAqLwogIHZpcnR1YWwgQ29sbGF0b3IqIHNhZmVDbG9uZSh2b2lkKSA9IDA7CgogIC8qKgogICogR2V0IHRoZSBzb3J0IGtleSBhcyBhbiBhcnJheSBvZiBieXRlcyBmcm9tIGFuIFVuaWNvZGVTdHJpbmcuCiAgKiBTb3J0IGtleSBieXRlIGFycmF5cyBhcmUgemVyby10ZXJtaW5hdGVkIGFuZCBjYW4gYmUgY29tcGFyZWQgdXNpbmcgCiAgKiBzdHJjbXAoKS4KICAqIEBwYXJhbSBzb3VyY2Ugc3RyaW5nIHRvIGJlIHByb2Nlc3NlZC4KICAqIEBwYXJhbSByZXN1bHQgYnVmZmVyIHRvIHN0b3JlIHJlc3VsdCBpbi4gSWYgTlVMTCwgbnVtYmVyIG9mIGJ5dGVzIG5lZWRlZCAKICAqICAgICAgICB3aWxsIGJlIHJldHVybmVkLgogICogQHBhcmFtIHJlc3VsdExlbmd0aCBsZW5ndGggb2YgdGhlIHJlc3VsdCBidWZmZXIuIElmIGlmIG5vdCBlbm91Z2ggdGhlIAogICogICAgICAgIGJ1ZmZlciB3aWxsIGJlIGZpbGxlZCB0byBjYXBhY2l0eS4gCiAgKiBAcmV0dXJuIE51bWJlciBvZiBieXRlcyBuZWVkZWQgZm9yIHN0b3JpbmcgdGhlIHNvcnQga2V5CiAgKiBAZHJhZnQgSUNVIDEuOAogICovCiAgdmlydHVhbCBpbnQzMl90IGdldFNvcnRLZXkoY29uc3QgVW5pY29kZVN0cmluZyYgc291cmNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdWludDhfdCogcmVzdWx0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50MzJfdCByZXN1bHRMZW5ndGgpIGNvbnN0ID0gMDsKCiAgLyoqCiAgKiBHZXQgdGhlIHNvcnQga2V5IGFzIGFuIGFycmF5IG9mIGJ5dGVzIGZyb20gYW4gVUNoYXIgYnVmZmVyLgogICogU29ydCBrZXkgYnl0ZSBhcnJheXMgYXJlIHplcm8tdGVybWluYXRlZCBhbmQgY2FuIGJlIGNvbXBhcmVkIHVzaW5nIAogICogc3RyY21wKCkuCiAgKiBAcGFyYW0gc291cmNlIHN0cmluZyB0byBiZSBwcm9jZXNzZWQuCiAgKiBAcGFyYW0gc291cmNlTGVuZ3RoIGxlbmd0aCBvZiBzdHJpbmcgdG8gYmUgcHJvY2Vzc2VkLiAKICAqICAgICAgICBJZiAtMSwgdGhlIHN0cmluZyBpcyAwIHRlcm1pbmF0ZWQgYW5kIGxlbmd0aCB3aWxsIGJlIGRlY2lkZWQgYnkgdGhlIAogICogICAgICAgIGZ1bmN0aW9uLgogICogQHBhcmFtIHJlc3VsdCBidWZmZXIgdG8gc3RvcmUgcmVzdWx0IGluLiBJZiBOVUxMLCBudW1iZXIgb2YgYnl0ZXMgbmVlZGVkIAogICogICAgICAgIHdpbGwgYmUgcmV0dXJuZWQuCiAgKiBAcGFyYW0gcmVzdWx0TGVuZ3RoIGxlbmd0aCBvZiB0aGUgcmVzdWx0IGJ1ZmZlci4gSWYgaWYgbm90IGVub3VnaCB0aGUgCiAgKiAgICAgICAgYnVmZmVyIHdpbGwgYmUgZmlsbGVkIHRvIGNhcGFjaXR5LiAKICAqIEByZXR1cm4gTnVtYmVyIG9mIGJ5dGVzIG5lZWRlZCBmb3Igc3RvcmluZyB0aGUgc29ydCBrZXkKICAqIEBkcmFmdCBJQ1UgMS44CiAgKi8KICB2aXJ0dWFsIGludDMyX3QgZ2V0U29ydEtleShjb25zdCBVQ2hhcipzb3VyY2UsIGludDMyX3Qgc291cmNlTGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVpbnQ4X3QqcmVzdWx0LCBpbnQzMl90IHJlc3VsdExlbmd0aCkgY29uc3QgPSAwOwoKICAvLyBzdGFydCBkZXByZWNhdGVkIEFQSXMKICAvKioKICAqIEdldCB0aGUgZGVjb21wb3NpdGlvbiBtb2RlIG9mIHRoZSBDb2xsYXRvciBvYmplY3QuCiAgKiBAcmV0dXJuIHRoZSBkZWNvbXBvc2l0aW9uIG1vZGUKICAqIEBzZWUgQ29sbGF0b3Ijc2V0RGVjb21wb3NpdGlvbgogICogQGRlcHJlY2F0ZWQgVG8gYmUgcmVtb3ZlZCBhZnRlciAyMDAyLXNlcC0zMDsgdXNlIGdldEF0dHJpYnV0ZSgpLgogICovCiAgdmlydHVhbCBOb3JtYWxpemVyOjpFTW9kZSBnZXREZWNvbXBvc2l0aW9uKHZvaWQpIGNvbnN0ID0gMDsKCiAgLyoqCiAgKiBTZXQgdGhlIGRlY29tcG9zaXRpb24gbW9kZSBvZiB0aGUgQ29sbGF0b3Igb2JqZWN0LiBzdWNjZXNzIGlzIGVxdWFsIHRvIAogICogVV9JTExFR0FMX0FSR1VNRU5UX0VSUk9SIGlmIGVycm9yIG9jY3Vycy4KICAqIEBwYXJhbSB0aGUgbmV3IGRlY29tcG9zaXRpb24gbW9kZQogICogQHNlZSBDb2xsYXRvciNnZXREZWNvbXBvc2l0aW9uCiAgKiBAZGVwcmVjYXRlZCBUbyBiZSByZW1vdmVkIGFmdGVyIDIwMDItc2VwLTMwOyB1c2Ugc2V0QXR0cmlidXRlKCkuCiAgKi8KICB2aXJ0dWFsIHZvaWQgc2V0RGVjb21wb3NpdGlvbihOb3JtYWxpemVyOjpFTW9kZSAgbW9kZSkgPSAwOwoKCi8qKgogKiBQcm9kdWNlIGEgYm91bmQgZm9yIGEgZ2l2ZW4gc29ydGtleSBhbmQgYSBudW1iZXIgb2YgbGV2ZWxzLgogKiBSZXR1cm4gdmFsdWUgaXMgYWx3YXlzIHRoZSBudW1iZXIgb2YgYnl0ZXMgbmVlZGVkLCByZWdhcmRsZXNzIG9mIAogKiB3aGV0aGVyIHRoZSByZXN1bHQgYnVmZmVyIHdhcyBiaWcgZW5vdWdoIG9yIGV2ZW4gdmFsaWQuPGJyPgogKiBSZXN1bHRpbmcgYm91bmRzIGNhbiBiZSB1c2VkIHRvIHByb2R1Y2UgYSByYW5nZSBvZiBzdHJpbmdzIHRoYXQgYXJlCiAqIGJldHdlZW4gdXBwZXIgYW5kIGxvd2VyIGJvdW5kcy4gRm9yIGV4YW1wbGUsIGlmIGJvdW5kcyBhcmUgcHJvZHVjZWQKICogZm9yIGEgc29ydGtleSBvZiBzdHJpbmcgInNtaXRoIiwgc3RyaW5ncyBiZXR3ZWVuIHVwcGVyIGFuZCBsb3dlciAKICogYm91bmRzIHdpdGggb25lIGxldmVsIHdvdWxkIGluY2x1ZGUgIlNtaXRoIiwgIlNNSVRIIiwgInNNaVRoIi48YnI+CiAqIFRoZXJlIGFyZSB0d28gdXBwZXIgYm91bmRzIHRoYXQgY2FuIGJlIHByb2R1Y2VkLiBJZiBVQ09MX0JPVU5EX1VQUEVSCiAqIGlzIHByb2R1Y2VkLCBzdHJpbmdzIG1hdGNoZWQgd291bGQgYmUgYXMgYWJvdmUuIEhvd2V2ZXIsIGlmIGJvdW5kCiAqIHByb2R1Y2VkIHVzaW5nIFVDT0xfQk9VTkRfVVBQRVJfTE9ORyBpcyB1c2VkLCB0aGUgYWJvdmUgZXhhbXBsZSB3aWxsCiAqIGFsc28gbWF0Y2ggIlNtaXRoc29uaWFuIiBhbmQgc2ltaWxhci48YnI+CiAqIEZvciBtb3JlIG9uIHVzYWdlLCBzZWUgZXhhbXBsZSBpbiBjaW50bHRzdC9jYXBpdHN0LmMgaW4gcHJvY2VkdXJlCiAqIFRlc3RCb3VuZHMuCiAqIFNvcnQga2V5cyBtYXkgYmUgY29tcGFyZWQgdXNpbmcgPFRUPnN0cmNtcDwvVFQ+LgogKiBAcGFyYW0gc291cmNlIFRoZSBzb3VyY2Ugc29ydGtleS4KICogQHBhcmFtIHNvdXJjZUxlbmd0aCBUaGUgbGVuZ3RoIG9mIHNvdXJjZSwgb3IgLTEgaWYgbnVsbC10ZXJtaW5hdGVkLiAKICogICAgICAgICAgICAgICAgICAgICAoSWYgYW4gdW5tb2RpZmllZCBzb3J0a2V5IGlzIHBhc3NlZCwgaXQgaXMgYWx3YXlzIG51bGwgCiAqICAgICAgICAgICAgICAgICAgICAgIHRlcm1pbmF0ZWQpLgogKiBAcGFyYW0gYm91bmRUeXBlIFR5cGUgb2YgYm91bmQgcmVxdWlyZWQuIEl0IGNhbiBiZSBVQ09MX0JPVU5EX0xPV0VSLCB3aGljaCAKICogICAgICAgICAgICAgICAgICBwcm9kdWNlcyBhIGxvd2VyIGluY2x1c2l2ZSBib3VuZCwgVUNPTF9CT1VORF9VUFBFUiwgdGhhdCAKICogICAgICAgICAgICAgICAgICBwcm9kdWNlcyB1cHBlciBib3VuZCB0aGF0IG1hdGNoZXMgc3RyaW5ncyBvZiB0aGUgc2FtZSBsZW5ndGggCiAqICAgICAgICAgICAgICAgICAgb3IgVUNPTF9CT1VORF9VUFBFUl9MT05HIHRoYXQgbWF0Y2hlcyBzdHJpbmdzIHRoYXQgaGF2ZSB0aGUgCiAqICAgICAgICAgICAgICAgICAgc2FtZSBzdGFydGluZyBzdWJzdHJpbmcgYXMgdGhlIHNvdXJjZSBzdHJpbmcuCiAqIEBwYXJhbSBub09mTGV2ZWxzICBOdW1iZXIgb2YgbGV2ZWxzIHJlcXVpcmVkIGluIHRoZSByZXN1bHRpbmcgYm91bmQgKGZvciBtb3N0IAogKiAgICAgICAgICAgICAgICAgICAgdXNlcywgdGhlIHJlY29tbWVuZGVkIHZhbHVlIGlzIDEpLiBTZWUgdXNlcnMgZ3VpZGUgZm9yIAogKiAgICAgICAgICAgICAgICAgICAgZXhwbGFuYXRpb24gb24gbnVtYmVyIG9mIGxldmVscyBhIHNvcnRrZXkgY2FuIGhhdmUuCiAqIEBwYXJhbSByZXN1bHQgQSBwb2ludGVyIHRvIGEgYnVmZmVyIHRvIHJlY2VpdmUgdGhlIHJlc3VsdGluZyBzb3J0a2V5LgogKiBAcGFyYW0gcmVzdWx0TGVuZ3RoIFRoZSBtYXhpbXVtIHNpemUgb2YgcmVzdWx0LgogKiBAcGFyYW0gc3RhdHVzIFVzZWQgZm9yIHJldHVybmluZyBlcnJvciBjb2RlIGlmIHNvbWV0aGluZyB3ZW50IHdyb25nLiBJZiB0aGUgCiAqICAgICAgICAgICAgICAgbnVtYmVyIG9mIGxldmVscyByZXF1ZXN0ZWQgaXMgaGlnaGVyIHRoYW4gdGhlIG51bWJlciBvZiBsZXZlbHMKICogICAgICAgICAgICAgICBpbiB0aGUgc291cmNlIGtleSwgYSB3YXJuaW5nIChVX1NPUlRfS0VZX1RPT19TSE9SVF9XQVJOSU5HKSBpcyAKICogICAgICAgICAgICAgICBpc3N1ZWQuCiAqIEByZXR1cm4gVGhlIHNpemUgbmVlZGVkIHRvIGZ1bGx5IHN0b3JlIHRoZSBib3VuZC4gCiAqIEBzZWUgdWNvbF9rZXlIYXNoQ29kZQogKiBAZHJhZnQgSUNVIDIuMQogKi8Kc3RhdGljIGludDMyX3QgZ2V0Qm91bmQoY29uc3QgdWludDhfdCAgICAgICAqc291cmNlLAogICAgICAgIGludDMyX3QgICAgICAgICAgICAgc291cmNlTGVuZ3RoLAogICAgICAgIFVDb2xCb3VuZE1vZGUgICAgICAgYm91bmRUeXBlLAogICAgICAgIHVpbnQzMl90ICAgICAgICAgICAgbm9PZkxldmVscywKICAgICAgICB1aW50OF90ICAgICAgICAgICAgICpyZXN1bHQsCiAgICAgICAgaW50MzJfdCAgICAgICAgICAgICByZXN1bHRMZW5ndGgsCiAgICAgICAgVUVycm9yQ29kZSAgICAgICAgICAmc3RhdHVzKTsKCgpwcm90ZWN0ZWQ6CgogIC8vIENvbGxhdG9yIHByb3RlY3RlZCBjb25zdHJ1Y3RvcnMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAvKioKICAqIERlZmF1bHQgY29uc3RydWN0b3IuCiAgKiBDb25zdHJ1Y3RvciBpcyBkaWZmZXJlbnQgZnJvbSB0aGUgb2xkIGRlZmF1bHQgQ29sbGF0b3IgY29uc3RydWN0b3IuCiAgKiBUaGUgdGFzayBmb3IgZGV0ZXJtaW5nIHRoZSBkZWZhdWx0IGNvbGxhdGlvbiBzdHJlbmd0aCBhbmQgbm9ybWFsaXphdGlvbiAKICAqIG1vZGUgaXMgbGVmdCB0byB0aGUgY2hpbGQgY2xhc3MuCiAgKi8KICBDb2xsYXRvcigpOwoKICAvKioKICAqIENvbnN0cnVjdG9yLgogICogRW1wdHkgY29uc3RydWN0b3IsIGRvZXMgbm90IGhhbmRsZSB0aGUgYXJndW1lbnRzLgogICogVGhpcyBjb25zdHJ1Y3RvciBpcyBkb25lIGZvciBiYWNrd2FyZCBjb21wYXRpYmlsaXR5IHdpdGggMS43IGFuZCAxLjguCiAgKiBUaGUgdGFzayBmb3IgaGFuZGxpbmcgdGhlIGFyZ3VtZW50IGNvbGxhdGlvbiBzdHJlbmd0aCBhbmQgbm9ybWFsaXphdGlvbiAKICAqIG1vZGUgaXMgbGVmdCB0byB0aGUgY2hpbGQgY2xhc3MuCiAgKiBAcGFyYW0gY29sbGF0aW9uU3RyZW5ndGggY29sbGF0aW9uIHN0cmVuZ3RoCiAgKiBAcGFyYW0gZGVjb21wb3NpdGlvbk1vZGUgCiAgKi8KICBDb2xsYXRvcihVQ29sbGF0aW9uU3RyZW5ndGggY29sbGF0aW9uU3RyZW5ndGgsIAogICAgICAgICAgICAgIFVOb3JtYWxpemF0aW9uTW9kZSBkZWNvbXBvc2l0aW9uTW9kZSk7CiAgCiAgLyoqCiAgKiBDb3B5IGNvbnN0cnVjdG9yLgogICogQHBhcmFtIG90aGVyIENvbGxhdG9yIG9iamVjdCB0byBiZSBjb3BpZWQgZnJvbQogICovCiAgQ29sbGF0b3IoY29uc3QgQ29sbGF0b3ImIG90aGVyKTsKICAKICAvLyBDb2xsYXRvciBwcm90ZWN0ZWQgbWV0aG9kcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKcHJpdmF0ZToKIAogIC8vIENvbGxhdG9yIHByaXZhdGUgZGF0YSBtZW1iZXJzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAvKgogIHN5bndlZSA6IHJlbW92ZWQgYXMgYXR0cmlidXRlcyB0byBiZSBoYW5kbGVkIGJ5IGNoaWxkIGNsYXNzCiAgVUNvbGxhdGlvblN0cmVuZ3RoICBzdHJlbmd0aDsKICBOb3JtYWxpemVyOjpFTW9kZSAgZGVjbXA7CiAgKi8KICAgIC8qIFRoaXMgaXMgdXNlbGVzcyBpbmZvcm1hdGlvbiAqLwovKiAgc3RhdGljIGNvbnN0IFVWZXJzaW9uSW5mbyBmVmVyc2lvbjsqLwp9OwoKLy8gQ29sbGF0b3IgaW5saW5lIG1ldGhvZHMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCmlubGluZSBVQm9vbCBDb2xsYXRvcjo6b3BlcmF0b3I9PShjb25zdCBDb2xsYXRvciYgb3RoZXIpIGNvbnN0CnsKICByZXR1cm4gKFVCb29sKSh0aGlzID09ICZvdGhlcik7Cn0KCmlubGluZSBVQm9vbCBDb2xsYXRvcjo6b3BlcmF0b3IhPShjb25zdCBDb2xsYXRvciYgb3RoZXIpIGNvbnN0CnsKICByZXR1cm4gKFVCb29sKSEoKnRoaXMgPT0gb3RoZXIpOwp9CgovKgpzeW53ZWUgOiByZW1vdmVkIHNpbmNlIHRoZXJlJ3Mgbm8gYXR0cmlidXRlIHRvIGJlIHJldHJpZXZlZCBoZXJlCmlubGluZSBVQ29sbGF0aW9uU3RyZW5ndGggQ29sbGF0b3I6OmdldFN0cmVuZ3RoKCkgY29uc3QKewogIHJldHVybiBzdHJlbmd0aDsKfQoKaW5saW5lIE5vcm1hbGl6ZXI6OkVNb2RlIENvbGxhdG9yOjpnZXREZWNvbXBvc2l0aW9uKCkgY29uc3QKewogIHJldHVybiBkZWNtcDsKfQoqLwpVX05BTUVTUEFDRV9FTkQKCiNlbmRpZgo=