LyoKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiogICBDb3B5cmlnaHQgKEMpIDE5OTYtMjAwNCwgSW50ZXJuYXRpb25hbCBCdXNpbmVzcyBNYWNoaW5lcyAgICAgICAgICAgICAgICAgKgoqICAgQ29ycG9yYXRpb24gYW5kIG90aGVycy4gIEFsbCBSaWdodHMgUmVzZXJ2ZWQuICAgICAgICAgICAgICAgICAgICAgICAgICAgICoKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiovCgovKioKKiBGaWxlIGNvbGwuaAoqCiogQ3JlYXRlZCBieTogSGVsZW5hIFNoaWgKKgoqIE1vZGlmaWNhdGlvbiBIaXN0b3J5OgoqCiogIERhdGUgICAgICAgIE5hbWUgICAgICAgIERlc2NyaXB0aW9uCiogMDIvNS85NyAgICAgIGFsaXUgICAgICAgIE1vZGlmaWVkIGNyZWF0ZURlZmF1bHQgdG8gbG9hZCBjb2xsYXRpb24gZGF0YSBmcm9tCiogICAgICAgICAgICAgICAgICAgICAgICAgIGJpbmFyeSBmaWxlcyB3aGVuIHBvc3NpYmxlLiAgQWRkZWQgcmVsYXRlZCBtZXRob2RzCiogICAgICAgICAgICAgICAgICAgICAgICAgIGNyZWF0ZUNvbGxhdGlvbkZyb21GaWxlLCBjaG9wTG9jYWxlLCBjcmVhdGVQYXRoTmFtZS4KKiAwMi8xMS85NyAgICAgYWxpdSAgICAgICAgQWRkZWQgbWVtYmVycyBhZGRUb0NhY2hlLCBmaW5kSW5DYWNoZSwgYW5kIGZnQ2FjaGUuCiogMDIvMTIvOTcgICAgIGFsaXUgICAgICAgIE1vZGlmaWVkIHRvIGNyZWF0ZSBvYmplY3RzIGZyb20gUnVsZUJhc2VkQ29sbGF0b3IgY2FjaGUuCiogICAgICAgICAgICAgICAgICAgICAgICAgIE1vdmVkIGNhY2hlIG91dCBvZiBDb2xsYXRpb24gY2xhc3MuCiogMDIvMTMvOTcgICAgIGFsaXUgICAgICAgIE1vdmVkIHNldmVyYWwgbWV0aG9kcyBvdXQgb2YgdGhpcyBjbGFzcyBhbmQgaW50bwoqICAgICAgICAgICAgICAgICAgICAgICAgICBSdWxlQmFzZWRDb2xsYXRvciwgd2l0aCBtb2RpZmljYXRpb25zLiAgTW9kaWZpZWQKKiAgICAgICAgICAgICAgICAgICAgICAgICAgY3JlYXRlRGVmYXVsdCgpIHRvIGNhbGwgbmV3IFJ1bGVCYXNlZENvbGxhdG9yKExvY2FsZSYpCiogICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0cnVjdG9yLiAgR2VuZXJhbCBjbGVhbiB1cCBhbmQgZG9jdW1lbnRhdGlvbi4KKiAwMi8yMC85NyAgICAgaGVsZW5hICAgICAgQWRkZWQgY2xvbmUsIG9wZXJhdG9yPT0sIG9wZXJhdG9yIT0sIG9wZXJhdG9yPSwgY29weQoqICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdHJ1Y3RvciBhbmQgZ2V0RHluYW1pY0NsYXNzSUQuCiogMDMvMjUvOTcgICAgIGhlbGVuYSAgICAgIFVwZGF0ZWQgd2l0aCBwbGF0Zm9ybSBpbmRlcGVuZGVudCBkYXRhIHR5cGVzLgoqIDA1LzA2Lzk3ICAgICBoZWxlbmEgICAgICBBZGRlZCBtZW1vcnkgYWxsb2NhdGlvbiBlcnJvciBkZXRlY3Rpb24uCiogMDYvMjAvOTcgICAgIGhlbGVuYSAgICAgIEphdmEgY2xhc3MgbmFtZSBjaGFuZ2UuCiogMDkvMDMvOTcgICAgIGhlbGVuYSAgICAgIEFkZGVkIGNyZWF0ZUNvbGxhdGlvbktleVZhbHVlcygpLgoqIDAyLzEwLzk4ICAgICBkYW1pYmEgICAgICBBZGRlZCBjb21wYXJlKCkgd2l0aCBsZW5ndGggYXMgcGFyYW1ldGVyLgoqIDA0LzIzLzk5ICAgICBzdGVwaGVuICAgICBSZW1vdmVkIEVEZWNvbXBvc2l0aW9uTW9kZSwgbWVyZ2VkIHdpdGgKKiAgICAgICAgICAgICAgICAgICAgICAgICAgTm9ybWFsaXplcjo6RU1vZGUuCiogMTEvMDIvOTkgICAgIGhlbGVuYSAgICAgIENvbGxhdG9yIHBlcmZvcm1hbmNlIGVuaGFuY2VtZW50cy4gIEVsaW1pbmF0ZXMgdGhlCiogICAgICAgICAgICAgICAgICAgICAgICAgIFVuaWNvZGVTdHJpbmcgY29uc3RydWN0aW9uIGFuZCBzcGVjaWFsIGNhc2UgZm9yIE5PX09QLgoqIDExLzIzLzk5ICAgICBzcmwgICAgICAgICBNb3JlIHBlcmZvcm1hbmNlIGVuaGFuY2VtZW50cy4gSW5saW5pbmcgb2YKKiAgICAgICAgICAgICAgICAgICAgICAgICAgY3JpdGljYWwgYWNjZXNzb3JzLgoqIDA1LzE1LzAwICAgICBoZWxlbmEgICAgICBBZGRlZCB2ZXJzaW9uIGluZm9ybWF0aW9uIEFQSS4KKiAwMS8yOS8wMSAgICAgc3lud2VlICAgICAgTW9kaWZpZWQgaW50byBhIEMrKyB3cmFwcGVyIHdoaWNoIGNhbGxzIEMgYXBpcwoqICAgICAgICAgICAgICAgICAgICAgICAgICAodWNvbGwuaCkuCiovCgojaWZuZGVmIENPTExfSAojZGVmaW5lIENPTExfSAoKI2luY2x1ZGUgInVuaWNvZGUvdXR5cGVzLmgiCgojaWYgIVVDT05GSUdfTk9fQ09MTEFUSU9OCgojaW5jbHVkZSAidW5pY29kZS91b2JqZWN0LmgiCiNpbmNsdWRlICJ1bmljb2RlL3Vjb2wuaCIKI2luY2x1ZGUgInVuaWNvZGUvbm9ybWx6ci5oIgojaW5jbHVkZSAidW5pY29kZS9sb2NpZC5oIgojaW5jbHVkZSAidW5pY29kZS91bmlzZXQuaCIKClVfTkFNRVNQQUNFX0JFR0lOCgpjbGFzcyBTdHJpbmdFbnVtZXJhdGlvbjsKCiNpZiAhVUNPTkZJR19OT19TRVJWSUNFCi8qKgogKiBAc3RhYmxlIElDVSAyLjYKICovCnR5cGVkZWYgY29uc3Qgdm9pZCogVVJlZ2lzdHJ5S2V5OwoKLyoqCiAqIEBzdGFibGUgSUNVIDIuNgogKi8KY2xhc3MgQ29sbGF0b3JGYWN0b3J5OwojZW5kaWYKCi8qKgoqIEBzdGFibGUgSUNVIDIuMAoqLwpjbGFzcyBDb2xsYXRpb25LZXk7CgovKioKKiBUaGUgPGNvZGU+Q29sbGF0b3I8L2NvZGU+IGNsYXNzIHBlcmZvcm1zIGxvY2FsZS1zZW5zaXRpdmUgc3RyaW5nCiogY29tcGFyaXNvbi48YnI+CiogWW91IHVzZSB0aGlzIGNsYXNzIHRvIGJ1aWxkIHNlYXJjaGluZyBhbmQgc29ydGluZyByb3V0aW5lcyBmb3IgbmF0dXJhbAoqIGxhbmd1YWdlIHRleHQuPGJyPgoqIDxlbT5JbXBvcnRhbnQ6IDwvZW0+VGhlIElDVSBjb2xsYXRpb24gc2VydmljZSBoYXMgYmVlbiByZWltcGxlbWVudGVkCiogaW4gb3JkZXIgdG8gYWNoaWV2ZSBiZXR0ZXIgcGVyZm9ybWFuY2UgYW5kIFVDQSBjb21wbGlhbmNlLgoqIEZvciBkZXRhaWxzLCBzZWUgdGhlCiogPGEgaHJlZj0iaHR0cDovL29zcy5zb2Z0d2FyZS5pYm0uY29tL2N2cy9pY3UvfmNoZWNrb3V0fi9pY3VodG1sL2Rlc2lnbi9jb2xsYXRpb24vSUNVX2NvbGxhdGlvbl9kZXNpZ24uaHRtIj4KKiBjb2xsYXRpb24gZGVzaWduIGRvY3VtZW50PC9hPi4KKiA8cD4KKiA8Y29kZT5Db2xsYXRvcjwvY29kZT4gaXMgYW4gYWJzdHJhY3QgYmFzZSBjbGFzcy4gU3ViY2xhc3NlcyBpbXBsZW1lbnQKKiBzcGVjaWZpYyBjb2xsYXRpb24gc3RyYXRlZ2llcy4gT25lIHN1YmNsYXNzLAoqIDxjb2RlPlJ1bGVCYXNlZENvbGxhdG9yPC9jb2RlPiwgaXMgY3VycmVudGx5IHByb3ZpZGVkIGFuZCBpcyBhcHBsaWNhYmxlCiogdG8gYSB3aWRlIHNldCBvZiBsYW5ndWFnZXMuIE90aGVyIHN1YmNsYXNzZXMgbWF5IGJlIGNyZWF0ZWQgdG8gaGFuZGxlIG1vcmUKKiBzcGVjaWFsaXplZCBuZWVkcy4KKiA8cD4KKiBMaWtlIG90aGVyIGxvY2FsZS1zZW5zaXRpdmUgY2xhc3NlcywgeW91IGNhbiB1c2UgdGhlIHN0YXRpYyBmYWN0b3J5IG1ldGhvZCwKKiA8Y29kZT5jcmVhdGVJbnN0YW5jZTwvY29kZT4sIHRvIG9idGFpbiB0aGUgYXBwcm9wcmlhdGUKKiA8Y29kZT5Db2xsYXRvcjwvY29kZT4gb2JqZWN0IGZvciBhIGdpdmVuIGxvY2FsZS4gWW91IHdpbGwgb25seSBuZWVkIHRvCiogbG9vayBhdCB0aGUgc3ViY2xhc3NlcyBvZiA8Y29kZT5Db2xsYXRvcjwvY29kZT4gaWYgeW91IG5lZWQgdG8KKiB1bmRlcnN0YW5kIHRoZSBkZXRhaWxzIG9mIGEgcGFydGljdWxhciBjb2xsYXRpb24gc3RyYXRlZ3kgb3IgaWYgeW91IG5lZWQgdG8KKiBtb2RpZnkgdGhhdCBzdHJhdGVneS4KKiA8cD4KKiBUaGUgZm9sbG93aW5nIGV4YW1wbGUgc2hvd3MgaG93IHRvIGNvbXBhcmUgdHdvIHN0cmluZ3MgdXNpbmcgdGhlCiogPGNvZGU+Q29sbGF0b3I8L2NvZGU+IGZvciB0aGUgZGVmYXVsdCBsb2NhbGUuCiogXGh0bWxvbmx5PGJsb2NrcXVvdGU+XGVuZGh0bWxvbmx5CiogPHByZT4KKiBcY29kZQoqIC8vIENvbXBhcmUgdHdvIHN0cmluZ3MgaW4gdGhlIGRlZmF1bHQgbG9jYWxlCiogVUVycm9yQ29kZSBzdWNjZXNzID0gVV9aRVJPX0VSUk9SOwoqIENvbGxhdG9yKiBteUNvbGxhdG9yID0gQ29sbGF0b3I6OmNyZWF0ZUluc3RhbmNlKHN1Y2Nlc3MpOwoqIGlmIChteUNvbGxhdG9yLT5jb21wYXJlKCJhYmMiLCAiQUJDIikgPCAwKQoqICAgY291dCA8PCAiYWJjIGlzIGxlc3MgdGhhbiBBQkMiIDw8IGVuZGw7CiogZWxzZQoqICAgY291dCA8PCAiYWJjIGlzIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byBBQkMiIDw8IGVuZGw7CiogXGVuZGNvZGUKKiA8L3ByZT4KKiBcaHRtbG9ubHk8L2Jsb2NrcXVvdGU+XGVuZGh0bWxvbmx5CiogPHA+CiogWW91IGNhbiBzZXQgYSA8Y29kZT5Db2xsYXRvcjwvY29kZT4ncyA8ZW0+c3RyZW5ndGg8L2VtPiBwcm9wZXJ0eSB0bwoqIGRldGVybWluZSB0aGUgbGV2ZWwgb2YgZGlmZmVyZW5jZSBjb25zaWRlcmVkIHNpZ25pZmljYW50IGluIGNvbXBhcmlzb25zLgoqIEZpdmUgc3RyZW5ndGhzIGFyZSBwcm92aWRlZDogPGNvZGU+UFJJTUFSWTwvY29kZT4sIDxjb2RlPlNFQ09OREFSWTwvY29kZT4sCiogPGNvZGU+VEVSVElBUlk8L2NvZGU+LCA8Y29kZT5RVUFURVJOQVJZPC9jb2RlPiBhbmQgPGNvZGU+SURFTlRJQ0FMPC9jb2RlPi4KKiBUaGUgZXhhY3QgYXNzaWdubWVudCBvZiBzdHJlbmd0aHMgdG8gbGFuZ3VhZ2UgZmVhdHVyZXMgaXMgbG9jYWxlIGRlcGVuZGFudC4KKiBGb3IgZXhhbXBsZSwgaW4gQ3plY2gsICJlIiBhbmQgImYiIGFyZSBjb25zaWRlcmVkIHByaW1hcnkgZGlmZmVyZW5jZXMsCiogd2hpbGUgImUiIGFuZCAiXHUwMEVBIiBhcmUgc2Vjb25kYXJ5IGRpZmZlcmVuY2VzLCAiZSIgYW5kICJFIiBhcmUgdGVydGlhcnkKKiBkaWZmZXJlbmNlcyBhbmQgImUiIGFuZCAiZSIgYXJlIGlkZW50aWNhbC4gVGhlIGZvbGxvd2luZyBzaG93cyBob3cgYm90aCBjYXNlCiogYW5kIGFjY2VudHMgY291bGQgYmUgaWdub3JlZCBmb3IgVVMgRW5nbGlzaC4KKiBcaHRtbG9ubHk8YmxvY2txdW90ZT5cZW5kaHRtbG9ubHkKKiA8cHJlPgoqIFxjb2RlCiogLy9HZXQgdGhlIENvbGxhdG9yIGZvciBVUyBFbmdsaXNoIGFuZCBzZXQgaXRzIHN0cmVuZ3RoIHRvIFBSSU1BUlkKKiBVRXJyb3JDb2RlIHN1Y2Nlc3MgPSBVX1pFUk9fRVJST1I7CiogQ29sbGF0b3IqIHVzQ29sbGF0b3IgPSBDb2xsYXRvcjo6Y3JlYXRlSW5zdGFuY2UoTG9jYWxlOjpVUywgc3VjY2Vzcyk7CiogdXNDb2xsYXRvci0+c2V0U3RyZW5ndGgoQ29sbGF0b3I6OlBSSU1BUlkpOwoqIGlmICh1c0NvbGxhdG9yLT5jb21wYXJlKCJhYmMiLCAiQUJDIikgPT0gMCkKKiAgICAgY291dCA8PCAiJ2FiYycgYW5kICdBQkMnIHN0cmluZ3MgYXJlIGVxdWl2YWxlbnQgd2l0aCBzdHJlbmd0aCBQUklNQVJZIiA8PCBlbmRsOwoqIFxlbmRjb2RlCiogPC9wcmU+CiogXGh0bWxvbmx5PC9ibG9ja3F1b3RlPlxlbmRodG1sb25seQoqIDxwPgoqIEZvciBjb21wYXJpbmcgc3RyaW5ncyBleGFjdGx5IG9uY2UsIHRoZSA8Y29kZT5jb21wYXJlPC9jb2RlPiBtZXRob2QKKiBwcm92aWRlcyB0aGUgYmVzdCBwZXJmb3JtYW5jZS4gV2hlbiBzb3J0aW5nIGEgbGlzdCBvZiBzdHJpbmdzIGhvd2V2ZXIsIGl0CiogaXMgZ2VuZXJhbGx5IG5lY2Vzc2FyeSB0byBjb21wYXJlIGVhY2ggc3RyaW5nIG11bHRpcGxlIHRpbWVzLiBJbiB0aGlzIGNhc2UsCiogc29ydCBrZXlzIHByb3ZpZGUgYmV0dGVyIHBlcmZvcm1hbmNlLiBUaGUgPGNvZGU+Z2V0U29ydEtleTwvY29kZT4gbWV0aG9kcwoqIGNvbnZlcnQgYSBzdHJpbmcgdG8gYSBzZXJpZXMgb2YgYnl0ZXMgdGhhdCBjYW4gYmUgY29tcGFyZWQgYml0d2lzZSBhZ2FpbnN0Ciogb3RoZXIgc29ydCBrZXlzIHVzaW5nIDxjb2RlPnN0cmNtcCgpPC9jb2RlPi4gU29ydCBrZXlzIGFyZSB3cml0dGVuIGFzCiogemVyby10ZXJtaW5hdGVkIGJ5dGUgc3RyaW5ncy4gVGhleSBjb25zaXN0IG9mIHNldmVyYWwgc3Vic3RyaW5ncywgb25lIGZvcgoqIGVhY2ggY29sbGF0aW9uIHN0cmVuZ3RoIGxldmVsLCB0aGF0IGFyZSBkZWxpbWl0ZWQgYnkgMHgwMSBieXRlcy4KKiBJZiB0aGUgc3RyaW5nIGNvZGUgcG9pbnRzIGFyZSBhcHBlbmRlZCBmb3IgVUNPTF9JREVOVElDQUwsIHRoZW4gdGhleSBhcmUKKiBwcm9jZXNzZWQgZm9yIGNvcnJlY3QgY29kZSBwb2ludCBvcmRlciBjb21wYXJpc29uIGFuZCBtYXkgY29udGFpbiAweDAxCiogYnl0ZXMgYnV0IG5vdCB6ZXJvIGJ5dGVzLgoqIDwvcD4KKiA8cD4KKiBBbiBvbGRlciBzZXQgb2YgQVBJcyByZXR1cm5zIGEgPGNvZGU+Q29sbGF0aW9uS2V5PC9jb2RlPiBvYmplY3QgdGhhdCB3cmFwcwoqIHRoZSBzb3J0IGtleSBieXRlcyBpbnN0ZWFkIG9mIHJldHVybmluZyB0aGUgYnl0ZXMgdGhlbXNlbHZlcy4KKiBJdHMgdXNlIGlzIGRlcHJlY2F0ZWQsIGJ1dCBpdCBpcyBzdGlsbCBhdmFpbGFibGUgZm9yIGNvbXBhdGliaWxpdHkgd2l0aAoqIEphdmEuCiogPC9wPgoqIDxwPgoqIDxzdHJvbmc+Tm90ZTo8L3N0cm9uZz4gPGNvZGU+Q29sbGF0b3I8L2NvZGU+cyB3aXRoIGRpZmZlcmVudCBMb2NhbGUsCiogYW5kIENvbGxhdGlvblN0cmVuZ3RoIHNldHRpbmdzIHdpbGwgcmV0dXJuIGRpZmZlcmVudCBzb3J0Ciogb3JkZXJzIGZvciB0aGUgc2FtZSBzZXQgb2Ygc3RyaW5ncy4gTG9jYWxlcyBoYXZlIHNwZWNpZmljIGNvbGxhdGlvbiBydWxlcywKKiBhbmQgdGhlIHdheSBpbiB3aGljaCBzZWNvbmRhcnkgYW5kIHRlcnRpYXJ5IGRpZmZlcmVuY2VzIGFyZSB0YWtlbiBpbnRvCiogYWNjb3VudCwgZm9yIGV4YW1wbGUsIHdpbGwgcmVzdWx0IGluIGEgZGlmZmVyZW50IHNvcnRpbmcgb3JkZXIgZm9yIHNhbWUKKiBzdHJpbmdzLgoqIDwvcD4KKiBAc2VlICAgICAgICAgUnVsZUJhc2VkQ29sbGF0b3IKKiBAc2VlICAgICAgICAgQ29sbGF0aW9uS2V5CiogQHNlZSAgICAgICAgIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcgoqIEBzZWUgICAgICAgICBMb2NhbGUKKiBAc2VlICAgICAgICAgTm9ybWFsaXplcgoqIEB2ZXJzaW9uICAgICAyLjAgMTEvMTUvMDEKKi8KCmNsYXNzIFVfSTE4Tl9BUEkgQ29sbGF0b3IgOiBwdWJsaWMgVU9iamVjdCB7CnB1YmxpYzoKCiAgICAvLyBDb2xsYXRvciBwdWJsaWMgZW51bXMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICAvKioKICAgICAqIEJhc2UgbGV0dGVyIHJlcHJlc2VudHMgYSBwcmltYXJ5IGRpZmZlcmVuY2UuIFNldCBjb21wYXJpc29uIGxldmVsIHRvCiAgICAgKiBQUklNQVJZIHRvIGlnbm9yZSBzZWNvbmRhcnkgYW5kIHRlcnRpYXJ5IGRpZmZlcmVuY2VzLjxicj4KICAgICAqIFVzZSB0aGlzIHRvIHNldCB0aGUgc3RyZW5ndGggb2YgYSBDb2xsYXRvciBvYmplY3QuPGJyPgogICAgICogRXhhbXBsZSBvZiBwcmltYXJ5IGRpZmZlcmVuY2UsICJhYmMiICZsdDsgImFiZCIKICAgICAqCiAgICAgKiBEaWFjcml0aWNhbCBkaWZmZXJlbmNlcyBvbiB0aGUgc2FtZSBiYXNlIGxldHRlciByZXByZXNlbnQgYSBzZWNvbmRhcnkKICAgICAqIGRpZmZlcmVuY2UuIFNldCBjb21wYXJpc29uIGxldmVsIHRvIFNFQ09OREFSWSB0byBpZ25vcmUgdGVydGlhcnkKICAgICAqIGRpZmZlcmVuY2VzLiBVc2UgdGhpcyB0byBzZXQgdGhlIHN0cmVuZ3RoIG9mIGEgQ29sbGF0b3Igb2JqZWN0Ljxicj4KICAgICAqIEV4YW1wbGUgb2Ygc2Vjb25kYXJ5IGRpZmZlcmVuY2UsICLkIiA+PiAiYSIuCiAgICAgKgogICAgICogVXBwZXJjYXNlIGFuZCBsb3dlcmNhc2UgdmVyc2lvbnMgb2YgdGhlIHNhbWUgY2hhcmFjdGVyIHJlcHJlc2VudHMgYQogICAgICogdGVydGlhcnkgZGlmZmVyZW5jZS4gIFNldCBjb21wYXJpc29uIGxldmVsIHRvIFRFUlRJQVJZIHRvIGluY2x1ZGUgYWxsCiAgICAgKiBjb21wYXJpc29uIGRpZmZlcmVuY2VzLiBVc2UgdGhpcyB0byBzZXQgdGhlIHN0cmVuZ3RoIG9mIGEgQ29sbGF0b3IKICAgICAqIG9iamVjdC48YnI+CiAgICAgKiBFeGFtcGxlIG9mIHRlcnRpYXJ5IGRpZmZlcmVuY2UsICJhYmMiICZsdDsmbHQ7Jmx0OyAiQUJDIi4KICAgICAqCiAgICAgKiBUd28gY2hhcmFjdGVycyBhcmUgY29uc2lkZXJlZCAiaWRlbnRpY2FsIiB3aGVuIHRoZXkgaGF2ZSB0aGUgc2FtZSB1bmljb2RlCiAgICAgKiBzcGVsbGluZ3MuPGJyPgogICAgICogRm9yIGV4YW1wbGUsICLkIiA9PSAi5CIuCiAgICAgKgogICAgICogVUNvbGxhdGlvblN0cmVuZ3RoIGlzIGFsc28gdXNlZCB0byBkZXRlcm1pbmUgdGhlIHN0cmVuZ3RoIG9mIHNvcnQga2V5cwogICAgICogZ2VuZXJhdGVkIGZyb20gQ29sbGF0b3Igb2JqZWN0cy4KICAgICAqIEBzdGFibGUgSUNVIDIuMAogICAgICovCiAgICBlbnVtIEVDb2xsYXRpb25TdHJlbmd0aAogICAgewogICAgICAgIFBSSU1BUlkgICAgPSAwLAogICAgICAgIFNFQ09OREFSWSAgPSAxLAogICAgICAgIFRFUlRJQVJZICAgPSAyLAogICAgICAgIFFVQVRFUk5BUlkgPSAzLAogICAgICAgIElERU5USUNBTCAgPSAxNQogICAgfTsKCiAgICAvKioKICAgICAqIExFU1MgaXMgcmV0dXJuZWQgaWYgc291cmNlIHN0cmluZyBpcyBjb21wYXJlZCB0byBiZSBsZXNzIHRoYW4gdGFyZ2V0CiAgICAgKiBzdHJpbmcgaW4gdGhlIGNvbXBhcmUoKSBtZXRob2QuCiAgICAgKiBFUVVBTCBpcyByZXR1cm5lZCBpZiBzb3VyY2Ugc3RyaW5nIGlzIGNvbXBhcmVkIHRvIGJlIGVxdWFsIHRvIHRhcmdldAogICAgICogc3RyaW5nIGluIHRoZSBjb21wYXJlKCkgbWV0aG9kLgogICAgICogR1JFQVRFUiBpcyByZXR1cm5lZCBpZiBzb3VyY2Ugc3RyaW5nIGlzIGNvbXBhcmVkIHRvIGJlIGdyZWF0ZXIgdGhhbgogICAgICogdGFyZ2V0IHN0cmluZyBpbiB0aGUgY29tcGFyZSgpIG1ldGhvZC4KICAgICAqIEBzZWUgQ29sbGF0b3IjY29tcGFyZQogICAgICogQGRlcHJlY2F0ZWQgSUNVIDIuNi4gVXNlIEMgZW51bSBVQ29sbGF0aW9uUmVzdWx0IGRlZmluZWQgaW4gdWNvbC5oCiAgICAgKi8KICAgIGVudW0gRUNvbXBhcmlzb25SZXN1bHQKICAgIHsKICAgICAgICBMRVNTID0gLTEsCiAgICAgICAgRVFVQUwgPSAwLAogICAgICAgIEdSRUFURVIgPSAxCiAgICB9OwoKICAgIC8vIENvbGxhdG9yIHB1YmxpYyBkZXN0cnVjdG9yIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgLyoqCiAgICAgKiBEZXN0cnVjdG9yCiAgICAgKiBAc3RhYmxlIElDVSAyLjAKICAgICAqLwogICAgdmlydHVhbCB+Q29sbGF0b3IoKTsKCiAgICAvLyBDb2xsYXRvciBwdWJsaWMgbWV0aG9kcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIC8qKgogICAgICogUmV0dXJucyB0cnVlIGlmICJvdGhlciIgaXMgdGhlIHNhbWUgYXMgInRoaXMiCiAgICAgKiBAcGFyYW0gb3RoZXIgQ29sbGF0b3Igb2JqZWN0IHRvIGJlIGNvbXBhcmVkCiAgICAgKiBAcmV0dXJuIHRydWUgaWYgb3RoZXIgaXMgdGhlIHNhbWUgYXMgdGhpcy4KICAgICAqIEBzdGFibGUgSUNVIDIuMAogICAgICovCiAgICB2aXJ0dWFsIFVCb29sIG9wZXJhdG9yPT0oY29uc3QgQ29sbGF0b3ImIG90aGVyKSBjb25zdDsKCiAgICAvKioKICAgICAqIFJldHVybnMgdHJ1ZSBpZiAib3RoZXIiIGlzIG5vdCB0aGUgc2FtZSBhcyAidGhpcyIuCiAgICAgKiBAcGFyYW0gb3RoZXIgQ29sbGF0b3Igb2JqZWN0IHRvIGJlIGNvbXBhcmVkCiAgICAgKiBAcmV0dXJuIHRydWUgaWYgb3RoZXIgaXMgbm90IHRoZSBzYW1lIGFzIHRoaXMuCiAgICAgKiBAc3RhYmxlIElDVSAyLjAKICAgICAqLwogICAgdmlydHVhbCBVQm9vbCBvcGVyYXRvciE9KGNvbnN0IENvbGxhdG9yJiBvdGhlcikgY29uc3Q7CgogICAgLyoqCiAgICAgKiBNYWtlcyBhIHNoYWxsb3cgY29weSBvZiB0aGUgY3VycmVudCBvYmplY3QuCiAgICAgKiBAcmV0dXJuIGEgY29weSBvZiB0aGlzIG9iamVjdAogICAgICogQHN0YWJsZSBJQ1UgMi4wCiAgICAgKi8KICAgIHZpcnR1YWwgQ29sbGF0b3IqIGNsb25lKHZvaWQpIGNvbnN0ID0gMDsKCiAgICAvKioKICAgICAqIENyZWF0ZXMgdGhlIENvbGxhdG9yIG9iamVjdCBmb3IgdGhlIGN1cnJlbnQgZGVmYXVsdCBsb2NhbGUuCiAgICAgKiBUaGUgZGVmYXVsdCBsb2NhbGUgaXMgZGV0ZXJtaW5lZCBieSBMb2NhbGU6OmdldERlZmF1bHQuCiAgICAgKiBUaGUgVUVycm9yQ29kZSYgZXJyIHBhcmFtZXRlciBpcyB1c2VkIHRvIHJldHVybiBzdGF0dXMgaW5mb3JtYXRpb24gdG8gdGhlIHVzZXIuCiAgICAgKiBUbyBjaGVjayB3aGV0aGVyIHRoZSBjb25zdHJ1Y3Rpb24gc3VjY2VlZGVkIG9yIG5vdCwgeW91IHNob3VsZCBjaGVjayB0aGUKICAgICAqIHZhbHVlIG9mIFVfU1VDQ0VTUyhlcnIpLiAgSWYgeW91IHdpc2ggbW9yZSBkZXRhaWxlZCBpbmZvcm1hdGlvbiwgeW91IGNhbgogICAgICogY2hlY2sgZm9yIGluZm9ybWF0aW9uYWwgZXJyb3IgcmVzdWx0cyB3aGljaCBzdGlsbCBpbmRpY2F0ZSBzdWNjZXNzLgogICAgICogVV9VU0lOR19GQUxMQkFDS19FUlJPUiBpbmRpY2F0ZXMgdGhhdCBhIGZhbGwgYmFjayBsb2NhbGUgd2FzIHVzZWQuIEZvcgogICAgICogZXhhbXBsZSwgJ2RlX0NIJyB3YXMgcmVxdWVzdGVkLCBidXQgbm90aGluZyB3YXMgZm91bmQgdGhlcmUsIHNvICdkZScgd2FzCiAgICAgKiB1c2VkLiBVX1VTSU5HX0RFRkFVTFRfRVJST1IgaW5kaWNhdGVzIHRoYXQgdGhlIGRlZmF1bHQgbG9jYWxlIGRhdGEgd2FzCiAgICAgKiB1c2VkOyBuZWl0aGVyIHRoZSByZXF1ZXN0ZWQgbG9jYWxlIG5vciBhbnkgb2YgaXRzIGZhbGwgYmFjayBsb2NhbGVzCiAgICAgKiBjb3VsZCBiZSBmb3VuZC4KICAgICAqIFRoZSBjYWxsZXIgb3ducyB0aGUgcmV0dXJuZWQgb2JqZWN0IGFuZCBpcyByZXNwb25zaWJsZSBmb3IgZGVsZXRpbmcgaXQuCiAgICAgKgogICAgICogQHBhcmFtIGVyciAgICB0aGUgZXJyb3IgY29kZSBzdGF0dXMuCiAgICAgKiBAcmV0dXJuICAgICAgIHRoZSBjb2xsYXRpb24gb2JqZWN0IG9mIHRoZSBkZWZhdWx0IGxvY2FsZS4oZm9yIGV4YW1wbGUsIGVuX1VTKQogICAgICogQHNlZSBMb2NhbGUjZ2V0RGVmYXVsdAogICAgICogQHN0YWJsZSBJQ1UgMi4wCiAgICAgKi8KICAgIHN0YXRpYyBDb2xsYXRvciogVV9FWFBPUlQyIGNyZWF0ZUluc3RhbmNlKFVFcnJvckNvZGUmICBlcnIpOwoKICAgIC8qKgogICAgICogR2V0cyB0aGUgdGFibGUtYmFzZWQgY29sbGF0aW9uIG9iamVjdCBmb3IgdGhlIGRlc2lyZWQgbG9jYWxlLiBUaGUKICAgICAqIHJlc291cmNlIG9mIHRoZSBkZXNpcmVkIGxvY2FsZSB3aWxsIGJlIGxvYWRlZCBieSBSZXNvdXJjZUxvYWRlci4KICAgICAqIExvY2FsZTo6RU5HTElTSCBpcyB0aGUgYmFzZSBjb2xsYXRpb24gdGFibGUgYW5kIGFsbCBvdGhlciBsYW5ndWFnZXMgYXJlCiAgICAgKiBidWlsdCBvbiB0b3Agb2YgaXQgd2l0aCBhZGRpdGlvbmFsIGxhbmd1YWdlLXNwZWNpZmljIG1vZGlmaWNhdGlvbnMuCiAgICAgKiBUaGUgVUVycm9yQ29kZSYgZXJyIHBhcmFtZXRlciBpcyB1c2VkIHRvIHJldHVybiBzdGF0dXMgaW5mb3JtYXRpb24gdG8gdGhlIHVzZXIuCiAgICAgKiBUbyBjaGVjayB3aGV0aGVyIHRoZSBjb25zdHJ1Y3Rpb24gc3VjY2VlZGVkIG9yIG5vdCwgeW91IHNob3VsZCBjaGVjawogICAgICogdGhlIHZhbHVlIG9mIFVfU1VDQ0VTUyhlcnIpLiAgSWYgeW91IHdpc2ggbW9yZSBkZXRhaWxlZCBpbmZvcm1hdGlvbiwgeW91CiAgICAgKiBjYW4gY2hlY2sgZm9yIGluZm9ybWF0aW9uYWwgZXJyb3IgcmVzdWx0cyB3aGljaCBzdGlsbCBpbmRpY2F0ZSBzdWNjZXNzLgogICAgICogVV9VU0lOR19GQUxMQkFDS19FUlJPUiBpbmRpY2F0ZXMgdGhhdCBhIGZhbGwgYmFjayBsb2NhbGUgd2FzIHVzZWQuICBGb3IKICAgICAqIGV4YW1wbGUsICdkZV9DSCcgd2FzIHJlcXVlc3RlZCwgYnV0IG5vdGhpbmcgd2FzIGZvdW5kIHRoZXJlLCBzbyAnZGUnIHdhcwogICAgICogdXNlZC4gIFVfVVNJTkdfREVGQVVMVF9FUlJPUiBpbmRpY2F0ZXMgdGhhdCB0aGUgZGVmYXVsdCBsb2NhbGUgZGF0YSB3YXMKICAgICAqIHVzZWQ7IG5laXRoZXIgdGhlIHJlcXVlc3RlZCBsb2NhbGUgbm9yIGFueSBvZiBpdHMgZmFsbCBiYWNrIGxvY2FsZXMKICAgICAqIGNvdWxkIGJlIGZvdW5kLgogICAgICogVGhlIGNhbGxlciBvd25zIHRoZSByZXR1cm5lZCBvYmplY3QgYW5kIGlzIHJlc3BvbnNpYmxlIGZvciBkZWxldGluZyBpdC4KICAgICAqIEBwYXJhbSBsb2MgICAgVGhlIGxvY2FsZSBJRCBmb3Igd2hpY2ggdG8gb3BlbiBhIGNvbGxhdG9yLgogICAgICogQHBhcmFtIGVyciAgICB0aGUgZXJyb3IgY29kZSBzdGF0dXMuCiAgICAgKiBAcmV0dXJuICAgICAgIHRoZSBjcmVhdGVkIHRhYmxlLWJhc2VkIGNvbGxhdGlvbiBvYmplY3QgYmFzZWQgb24gdGhlIGRlc2lyZWQKICAgICAqICAgICAgICAgICAgICAgbG9jYWxlLgogICAgICogQHNlZSBMb2NhbGUKICAgICAqIEBzZWUgUmVzb3VyY2VMb2FkZXIKICAgICAqIEBzdGFibGUgSUNVIDIuMgogICAgICovCiAgICBzdGF0aWMgQ29sbGF0b3IqIFVfRVhQT1JUMiBjcmVhdGVJbnN0YW5jZShjb25zdCBMb2NhbGUmIGxvYywgVUVycm9yQ29kZSYgZXJyKTsKCiNpZmRlZiBVX1VTRV9DT0xMQVRJT05fT0JTT0xFVEVfMl82CiAgICAvKioKICAgICAqIENyZWF0ZSBhIENvbGxhdG9yIHdpdGggYSBzcGVjaWZpYyB2ZXJzaW9uLgogICAgICogVGhpcyBpcyB0aGUgc2FtZSBhcyBjcmVhdGVJbnN0YW5jZShsb2MsIGVycikgZXhjZXB0IHRoYXQgZ2V0VmVyc2lvbigpIG9mCiAgICAgKiB0aGUgcmV0dXJuZWQgb2JqZWN0IGlzIGd1YXJhbnRlZWQgdG8gYmUgdGhlIHNhbWUgYXMgdGhlIHZlcnNpb24KICAgICAqIHBhcmFtZXRlci4KICAgICAqIFRoaXMgaXMgZGVzaWduZWQgdG8gYmUgdXNlZCB0byBvcGVuIHRoZSBzYW1lIGNvbGxhdG9yIGZvciBhIGdpdmVuCiAgICAgKiBsb2NhbGUgZXZlbiB3aGVuIElDVSBpcyB1cGRhdGVkLgogICAgICogVGhlIHNhbWUgbG9jYWxlIGFuZCB2ZXJzaW9uIGd1YXJhbnRlZXMgdGhlIHNhbWUgc29ydCBrZXlzIGFuZAogICAgICogY29tcGFyaXNvbiByZXN1bHRzLgogICAgICogPHA+CiAgICAgKiBOb3RlOiB0aGlzIEFQSSB3aWxsIGJlIHJlbW92ZWQgaW4gYSBmdXR1cmUgcmVsZWFzZS4gIFVzZQogICAgICogPHR0PmNyZWF0ZUluc3RhbmNlKGNvbnN0IExvY2FsZSYsIFVFcnJvckNvZGUmKSBpbnN0ZWFkLjwvdHQ+PC9wPgogICAgICoKICAgICAqIEBwYXJhbSBsb2MgVGhlIGxvY2FsZSBJRCBmb3Igd2hpY2ggdG8gb3BlbiBhIGNvbGxhdG9yLgogICAgICogQHBhcmFtIHZlcnNpb24gVGhlIHJlcXVlc3RlZCBjb2xsYXRvciB2ZXJzaW9uLgogICAgICogQHBhcmFtIGVyciBBIHJlZmVyZW5jZSB0byBhIFVFcnJvckNvZGUsCiAgICAgKiAgICAgICAgICAgIG11c3Qgbm90IGluZGljYXRlIGEgZmFpbHVyZSBiZWZvcmUgY2FsbGluZyB0aGlzIGZ1bmN0aW9uLgogICAgICogQHJldHVybiBBIHBvaW50ZXIgdG8gYSBDb2xsYXRvciwgb3IgMCBpZiBhbiBlcnJvciBvY2N1cnJlZAogICAgICogICAgICAgICBvciBhIGNvbGxhdG9yIHdpdGggdGhlIHJlcXVlc3RlZCB2ZXJzaW9uIGlzIG5vdCBhdmFpbGFibGUuCiAgICAgKgogICAgICogQHNlZSBnZXRWZXJzaW9uCiAgICAgKiBAb2Jzb2xldGUgSUNVIDIuNgogICAgICovCiAgICBzdGF0aWMgQ29sbGF0b3IgKmNyZWF0ZUluc3RhbmNlKGNvbnN0IExvY2FsZSAmbG9jLCBVVmVyc2lvbkluZm8gdmVyc2lvbiwgVUVycm9yQ29kZSAmZXJyKTsKI2VuZGlmCgogICAgLyoqCiAgICAgKiBUaGUgY29tcGFyaXNvbiBmdW5jdGlvbiBjb21wYXJlcyB0aGUgY2hhcmFjdGVyIGRhdGEgc3RvcmVkIGluIHR3bwogICAgICogZGlmZmVyZW50IHN0cmluZ3MuIFJldHVybnMgaW5mb3JtYXRpb24gYWJvdXQgd2hldGhlciBhIHN0cmluZyBpcyBsZXNzCiAgICAgKiB0aGFuLCBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gYW5vdGhlciBzdHJpbmcuCiAgICAgKiBAcGFyYW0gc291cmNlIHRoZSBzb3VyY2Ugc3RyaW5nIHRvIGJlIGNvbXBhcmVkIHdpdGguCiAgICAgKiBAcGFyYW0gdGFyZ2V0IHRoZSBzdHJpbmcgdGhhdCBpcyB0byBiZSBjb21wYXJlZCB3aXRoIHRoZSBzb3VyY2Ugc3RyaW5nLgogICAgICogQHJldHVybiBSZXR1cm5zIGEgYnl0ZSB2YWx1ZS4gR1JFQVRFUiBpZiBzb3VyY2UgaXMgZ3JlYXRlcgogICAgICogdGhhbiB0YXJnZXQ7IEVRVUFMIGlmIHNvdXJjZSBpcyBlcXVhbCB0byB0YXJnZXQ7IExFU1MgaWYgc291cmNlIGlzIGxlc3MKICAgICAqIHRoYW4gdGFyZ2V0CiAgICAgKiBAZGVwcmVjYXRlZCBJQ1UgMi42IHVzZSB0aGUgb3ZlcmxvYWQgd2l0aCBVRXJyb3JDb2RlICYKICAgICAqLwogICAgdmlydHVhbCBFQ29tcGFyaXNvblJlc3VsdCBjb21wYXJlKGNvbnN0IFVuaWNvZGVTdHJpbmcmIHNvdXJjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBVbmljb2RlU3RyaW5nJiB0YXJnZXQpIGNvbnN0OwoKICAgIC8qKgogICAgICogVGhlIGNvbXBhcmlzb24gZnVuY3Rpb24gY29tcGFyZXMgdGhlIGNoYXJhY3RlciBkYXRhIHN0b3JlZCBpbiB0d28KICAgICAqIGRpZmZlcmVudCBzdHJpbmdzLiBSZXR1cm5zIGluZm9ybWF0aW9uIGFib3V0IHdoZXRoZXIgYSBzdHJpbmcgaXMgbGVzcwogICAgICogdGhhbiwgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIGFub3RoZXIgc3RyaW5nLgogICAgICogQHBhcmFtIHNvdXJjZSB0aGUgc291cmNlIHN0cmluZyB0byBiZSBjb21wYXJlZCB3aXRoLgogICAgICogQHBhcmFtIHRhcmdldCB0aGUgc3RyaW5nIHRoYXQgaXMgdG8gYmUgY29tcGFyZWQgd2l0aCB0aGUgc291cmNlIHN0cmluZy4KICAgICAqIEBwYXJhbSBzdGF0dXMgcG9zc2libGUgZXJyb3IgY29kZQogICAgICogQHJldHVybiBSZXR1cm5zIGFuIGVudW0gdmFsdWUuIFVDT0xfR1JFQVRFUiBpZiBzb3VyY2UgaXMgZ3JlYXRlcgogICAgICogdGhhbiB0YXJnZXQ7IFVDT0xfRVFVQUwgaWYgc291cmNlIGlzIGVxdWFsIHRvIHRhcmdldDsgVUNPTF9MRVNTIGlmIHNvdXJjZSBpcyBsZXNzCiAgICAgKiB0aGFuIHRhcmdldAogICAgICogQHN0YWJsZSBJQ1UgMi42CiAgICAgKi8KICAgIHZpcnR1YWwgVUNvbGxhdGlvblJlc3VsdCBjb21wYXJlKGNvbnN0IFVuaWNvZGVTdHJpbmcmIHNvdXJjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBVbmljb2RlU3RyaW5nJiB0YXJnZXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSAmc3RhdHVzKSBjb25zdCA9IDA7CgogICAgLyoqCiAgICAgKiBEb2VzIHRoZSBzYW1lIHRoaW5nIGFzIGNvbXBhcmUgYnV0IGxpbWl0cyB0aGUgY29tcGFyaXNvbiB0byBhIHNwZWNpZmllZAogICAgICogbGVuZ3RoCiAgICAgKiBAcGFyYW0gc291cmNlIHRoZSBzb3VyY2Ugc3RyaW5nIHRvIGJlIGNvbXBhcmVkIHdpdGguCiAgICAgKiBAcGFyYW0gdGFyZ2V0IHRoZSBzdHJpbmcgdGhhdCBpcyB0byBiZSBjb21wYXJlZCB3aXRoIHRoZSBzb3VyY2Ugc3RyaW5nLgogICAgICogQHBhcmFtIGxlbmd0aCB0aGUgbGVuZ3RoIHRoZSBjb21wYXJpc29uIGlzIGxpbWl0ZWQgdG8KICAgICAqIEByZXR1cm4gUmV0dXJucyBhIGJ5dGUgdmFsdWUuIEdSRUFURVIgaWYgc291cmNlICh1cCB0byB0aGUgc3BlY2lmaWVkCiAgICAgKiAgICAgICAgIGxlbmd0aCkgaXMgZ3JlYXRlciB0aGFuIHRhcmdldDsgRVFVQUwgaWYgc291cmNlICh1cCB0byBzcGVjaWZpZWQKICAgICAqICAgICAgICAgbGVuZ3RoKSBpcyBlcXVhbCB0byB0YXJnZXQ7IExFU1MgaWYgc291cmNlICh1cCB0byB0aGUgc3BlY2lmaWVkCiAgICAgKiAgICAgICAgIGxlbmd0aCkgaXMgbGVzcyAgdGhhbiB0YXJnZXQuCiAgICAgKiBAZGVwcmVjYXRlZCBJQ1UgMi42IHVzZSB0aGUgb3ZlcmxvYWQgd2l0aCBVRXJyb3JDb2RlICYKICAgICAqLwogICAgdmlydHVhbCBFQ29tcGFyaXNvblJlc3VsdCBjb21wYXJlKGNvbnN0IFVuaWNvZGVTdHJpbmcmIHNvdXJjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBVbmljb2RlU3RyaW5nJiB0YXJnZXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50MzJfdCBsZW5ndGgpIGNvbnN0OwoKICAgIC8qKgogICAgICogRG9lcyB0aGUgc2FtZSB0aGluZyBhcyBjb21wYXJlIGJ1dCBsaW1pdHMgdGhlIGNvbXBhcmlzb24gdG8gYSBzcGVjaWZpZWQKICAgICAqIGxlbmd0aAogICAgICogQHBhcmFtIHNvdXJjZSB0aGUgc291cmNlIHN0cmluZyB0byBiZSBjb21wYXJlZCB3aXRoLgogICAgICogQHBhcmFtIHRhcmdldCB0aGUgc3RyaW5nIHRoYXQgaXMgdG8gYmUgY29tcGFyZWQgd2l0aCB0aGUgc291cmNlIHN0cmluZy4KICAgICAqIEBwYXJhbSBsZW5ndGggdGhlIGxlbmd0aCB0aGUgY29tcGFyaXNvbiBpcyBsaW1pdGVkIHRvCiAgICAgKiBAcGFyYW0gc3RhdHVzIHBvc3NpYmxlIGVycm9yIGNvZGUKICAgICAqIEByZXR1cm4gUmV0dXJucyBhbiBlbnVtIHZhbHVlLiBVQ09MX0dSRUFURVIgaWYgc291cmNlICh1cCB0byB0aGUgc3BlY2lmaWVkCiAgICAgKiAgICAgICAgIGxlbmd0aCkgaXMgZ3JlYXRlciB0aGFuIHRhcmdldDsgVUNPTF9FUVVBTCBpZiBzb3VyY2UgKHVwIHRvIHNwZWNpZmllZAogICAgICogICAgICAgICBsZW5ndGgpIGlzIGVxdWFsIHRvIHRhcmdldDsgVUNPTF9MRVNTIGlmIHNvdXJjZSAodXAgdG8gdGhlIHNwZWNpZmllZAogICAgICogICAgICAgICBsZW5ndGgpIGlzIGxlc3MgIHRoYW4gdGFyZ2V0LgogICAgICogQHN0YWJsZSBJQ1UgMi42CiAgICAgKi8KICAgIHZpcnR1YWwgVUNvbGxhdGlvblJlc3VsdCBjb21wYXJlKGNvbnN0IFVuaWNvZGVTdHJpbmcmIHNvdXJjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBVbmljb2RlU3RyaW5nJiB0YXJnZXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50MzJfdCBsZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSAmc3RhdHVzKSBjb25zdCA9IDA7CgogICAgLyoqCiAgICAgKiBUaGUgY29tcGFyaXNvbiBmdW5jdGlvbiBjb21wYXJlcyB0aGUgY2hhcmFjdGVyIGRhdGEgc3RvcmVkIGluIHR3bwogICAgICogZGlmZmVyZW50IHN0cmluZyBhcnJheXMuIFJldHVybnMgaW5mb3JtYXRpb24gYWJvdXQgd2hldGhlciBhIHN0cmluZyBhcnJheQogICAgICogaXMgbGVzcyB0aGFuLCBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gYW5vdGhlciBzdHJpbmcgYXJyYXkuCiAgICAgKiBAcGFyYW0gc291cmNlIHRoZSBzb3VyY2Ugc3RyaW5nIGFycmF5IHRvIGJlIGNvbXBhcmVkIHdpdGguCiAgICAgKiBAcGFyYW0gc291cmNlTGVuZ3RoIHRoZSBsZW5ndGggb2YgdGhlIHNvdXJjZSBzdHJpbmcgYXJyYXkuICBJZiB0aGlzIHZhbHVlCiAgICAgKiAgICAgICAgaXMgZXF1YWwgdG8gLTEsIHRoZSBzdHJpbmcgYXJyYXkgaXMgbnVsbC10ZXJtaW5hdGVkLgogICAgICogQHBhcmFtIHRhcmdldCB0aGUgc3RyaW5nIHRoYXQgaXMgdG8gYmUgY29tcGFyZWQgd2l0aCB0aGUgc291cmNlIHN0cmluZy4KICAgICAqIEBwYXJhbSB0YXJnZXRMZW5ndGggdGhlIGxlbmd0aCBvZiB0aGUgdGFyZ2V0IHN0cmluZyBhcnJheS4gIElmIHRoaXMgdmFsdWUKICAgICAqICAgICAgICBpcyBlcXVhbCB0byAtMSwgdGhlIHN0cmluZyBhcnJheSBpcyBudWxsLXRlcm1pbmF0ZWQuCiAgICAgKiBAcmV0dXJuIFJldHVybnMgYSBieXRlIHZhbHVlLiBHUkVBVEVSIGlmIHNvdXJjZSBpcyBncmVhdGVyIHRoYW4gdGFyZ2V0OwogICAgICogICAgICAgICBFUVVBTCBpZiBzb3VyY2UgaXMgZXF1YWwgdG8gdGFyZ2V0OyBMRVNTIGlmIHNvdXJjZSBpcyBsZXNzIHRoYW4KICAgICAqICAgICAgICAgdGFyZ2V0CiAgICAgKiBAZGVwcmVjYXRlZCBJQ1UgMi42IHVzZSB0aGUgb3ZlcmxvYWQgd2l0aCBVRXJyb3JDb2RlICYKICAgICAqLwogICAgdmlydHVhbCBFQ29tcGFyaXNvblJlc3VsdCBjb21wYXJlKGNvbnN0IFVDaGFyKiBzb3VyY2UsIGludDMyX3Qgc291cmNlTGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFVDaGFyKiB0YXJnZXQsIGludDMyX3QgdGFyZ2V0TGVuZ3RoKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0OwoKICAgIC8qKgogICAgICogVGhlIGNvbXBhcmlzb24gZnVuY3Rpb24gY29tcGFyZXMgdGhlIGNoYXJhY3RlciBkYXRhIHN0b3JlZCBpbiB0d28KICAgICAqIGRpZmZlcmVudCBzdHJpbmcgYXJyYXlzLiBSZXR1cm5zIGluZm9ybWF0aW9uIGFib3V0IHdoZXRoZXIgYSBzdHJpbmcgYXJyYXkKICAgICAqIGlzIGxlc3MgdGhhbiwgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIGFub3RoZXIgc3RyaW5nIGFycmF5LgogICAgICogQHBhcmFtIHNvdXJjZSB0aGUgc291cmNlIHN0cmluZyBhcnJheSB0byBiZSBjb21wYXJlZCB3aXRoLgogICAgICogQHBhcmFtIHNvdXJjZUxlbmd0aCB0aGUgbGVuZ3RoIG9mIHRoZSBzb3VyY2Ugc3RyaW5nIGFycmF5LiAgSWYgdGhpcyB2YWx1ZQogICAgICogICAgICAgIGlzIGVxdWFsIHRvIC0xLCB0aGUgc3RyaW5nIGFycmF5IGlzIG51bGwtdGVybWluYXRlZC4KICAgICAqIEBwYXJhbSB0YXJnZXQgdGhlIHN0cmluZyB0aGF0IGlzIHRvIGJlIGNvbXBhcmVkIHdpdGggdGhlIHNvdXJjZSBzdHJpbmcuCiAgICAgKiBAcGFyYW0gdGFyZ2V0TGVuZ3RoIHRoZSBsZW5ndGggb2YgdGhlIHRhcmdldCBzdHJpbmcgYXJyYXkuICBJZiB0aGlzIHZhbHVlCiAgICAgKiAgICAgICAgaXMgZXF1YWwgdG8gLTEsIHRoZSBzdHJpbmcgYXJyYXkgaXMgbnVsbC10ZXJtaW5hdGVkLgogICAgICogQHBhcmFtIHN0YXR1cyBwb3NzaWJsZSBlcnJvciBjb2RlCiAgICAgKiBAcmV0dXJuIFJldHVybnMgYW4gZW51bSB2YWx1ZS4gVUNPTF9HUkVBVEVSIGlmIHNvdXJjZSBpcyBncmVhdGVyCiAgICAgKiB0aGFuIHRhcmdldDsgVUNPTF9FUVVBTCBpZiBzb3VyY2UgaXMgZXF1YWwgdG8gdGFyZ2V0OyBVQ09MX0xFU1MgaWYgc291cmNlIGlzIGxlc3MKICAgICAqIHRoYW4gdGFyZ2V0CiAgICAgKiBAc3RhYmxlIElDVSAyLjYKICAgICAqLwogICAgdmlydHVhbCBVQ29sbGF0aW9uUmVzdWx0IGNvbXBhcmUoY29uc3QgVUNoYXIqIHNvdXJjZSwgaW50MzJfdCBzb3VyY2VMZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVUNoYXIqIHRhcmdldCwgaW50MzJfdCB0YXJnZXRMZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSAmc3RhdHVzKSBjb25zdCA9IDA7CgogICAgLyoqCiAgICAgKiBUcmFuc2Zvcm1zIHRoZSBzdHJpbmcgaW50byBhIHNlcmllcyBvZiBjaGFyYWN0ZXJzIHRoYXQgY2FuIGJlIGNvbXBhcmVkCiAgICAgKiB3aXRoIENvbGxhdGlvbktleTo6Y29tcGFyZVRvLiBJdCBpcyBub3QgcG9zc2libGUgdG8gcmVzdG9yZSB0aGUgb3JpZ2luYWwKICAgICAqIHN0cmluZyBmcm9tIHRoZSBjaGFycyBpbiB0aGUgc29ydCBrZXkuICBUaGUgZ2VuZXJhdGVkIHNvcnQga2V5IGhhbmRsZXMKICAgICAqIG9ubHkgYSBsaW1pdGVkIG51bWJlciBvZiBpZ25vcmFibGUgY2hhcmFjdGVycy4KICAgICAqIDxwPlVzZSBDb2xsYXRpb25LZXk6OmVxdWFscyBvciBDb2xsYXRpb25LZXk6OmNvbXBhcmUgdG8gY29tcGFyZSB0aGUKICAgICAqIGdlbmVyYXRlZCBzb3J0IGtleXMuCiAgICAgKiBJZiB0aGUgc291cmNlIHN0cmluZyBpcyBudWxsLCBhIG51bGwgY29sbGF0aW9uIGtleSB3aWxsIGJlIHJldHVybmVkLgogICAgICogQHBhcmFtIHNvdXJjZSB0aGUgc291cmNlIHN0cmluZyB0byBiZSB0cmFuc2Zvcm1lZCBpbnRvIGEgc29ydCBrZXkuCiAgICAgKiBAcGFyYW0ga2V5IHRoZSBjb2xsYXRpb24ga2V5IHRvIGJlIGZpbGxlZCBpbgogICAgICogQHBhcmFtIHN0YXR1cyB0aGUgZXJyb3IgY29kZSBzdGF0dXMuCiAgICAgKiBAcmV0dXJuIHRoZSBjb2xsYXRpb24ga2V5IG9mIHRoZSBzdHJpbmcgYmFzZWQgb24gdGhlIGNvbGxhdGlvbiBydWxlcy4KICAgICAqIEBzZWUgQ29sbGF0aW9uS2V5I2NvbXBhcmUKICAgICAqIEBkZXByZWNhdGVkIElDVSAyLjggVXNlIGdldFNvcnRLZXkoLi4uKSBpbnN0ZWFkCiAgICAgKi8KICAgIHZpcnR1YWwgQ29sbGF0aW9uS2V5JiBnZXRDb2xsYXRpb25LZXkoY29uc3QgVW5pY29kZVN0cmluZyYgIHNvdXJjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29sbGF0aW9uS2V5JiBrZXksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cykgY29uc3QgPSAwOwoKICAgIC8qKgogICAgICogVHJhbnNmb3JtcyB0aGUgc3RyaW5nIGludG8gYSBzZXJpZXMgb2YgY2hhcmFjdGVycyB0aGF0IGNhbiBiZSBjb21wYXJlZAogICAgICogd2l0aCBDb2xsYXRpb25LZXk6OmNvbXBhcmVUby4gSXQgaXMgbm90IHBvc3NpYmxlIHRvIHJlc3RvcmUgdGhlIG9yaWdpbmFsCiAgICAgKiBzdHJpbmcgZnJvbSB0aGUgY2hhcnMgaW4gdGhlIHNvcnQga2V5LiAgVGhlIGdlbmVyYXRlZCBzb3J0IGtleSBoYW5kbGVzCiAgICAgKiBvbmx5IGEgbGltaXRlZCBudW1iZXIgb2YgaWdub3JhYmxlIGNoYXJhY3RlcnMuCiAgICAgKiA8cD5Vc2UgQ29sbGF0aW9uS2V5OjplcXVhbHMgb3IgQ29sbGF0aW9uS2V5Ojpjb21wYXJlIHRvIGNvbXBhcmUgdGhlCiAgICAgKiBnZW5lcmF0ZWQgc29ydCBrZXlzLgogICAgICogPHA+SWYgdGhlIHNvdXJjZSBzdHJpbmcgaXMgbnVsbCwgYSBudWxsIGNvbGxhdGlvbiBrZXkgd2lsbCBiZSByZXR1cm5lZC4KICAgICAqIEBwYXJhbSBzb3VyY2UgdGhlIHNvdXJjZSBzdHJpbmcgdG8gYmUgdHJhbnNmb3JtZWQgaW50byBhIHNvcnQga2V5LgogICAgICogQHBhcmFtIHNvdXJjZUxlbmd0aCBsZW5ndGggb2YgdGhlIGNvbGxhdGlvbiBrZXkKICAgICAqIEBwYXJhbSBrZXkgdGhlIGNvbGxhdGlvbiBrZXkgdG8gYmUgZmlsbGVkIGluCiAgICAgKiBAcGFyYW0gc3RhdHVzIHRoZSBlcnJvciBjb2RlIHN0YXR1cy4KICAgICAqIEByZXR1cm4gdGhlIGNvbGxhdGlvbiBrZXkgb2YgdGhlIHN0cmluZyBiYXNlZCBvbiB0aGUgY29sbGF0aW9uIHJ1bGVzLgogICAgICogQHNlZSBDb2xsYXRpb25LZXkjY29tcGFyZQogICAgICogQGRlcHJlY2F0ZWQgSUNVIDIuOCBVc2UgZ2V0U29ydEtleSguLi4pIGluc3RlYWQKICAgICAqLwogICAgdmlydHVhbCBDb2xsYXRpb25LZXkmIGdldENvbGxhdGlvbktleShjb25zdCBVQ2hhcipzb3VyY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludDMyX3Qgc291cmNlTGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb2xsYXRpb25LZXkmIGtleSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYgc3RhdHVzKSBjb25zdCA9IDA7CiAgICAvKioKICAgICAqIEdlbmVyYXRlcyB0aGUgaGFzaCBjb2RlIGZvciB0aGUgY29sbGF0aW9uIG9iamVjdAogICAgICogQHN0YWJsZSBJQ1UgMi4wCiAgICAgKi8KICAgIHZpcnR1YWwgaW50MzJfdCBoYXNoQ29kZSh2b2lkKSBjb25zdCA9IDA7CgogICAgLyoqCiAgICAgKiBHZXRzIHRoZSBsb2NhbGUgb2YgdGhlIENvbGxhdG9yCiAgICAgKgogICAgICogQHBhcmFtIHR5cGUgY2FuIGJlIGVpdGhlciByZXF1ZXN0ZWQsIHZhbGlkIG9yIGFjdHVhbCBsb2NhbGUuIEZvciBtb3JlCiAgICAgKiAgICAgICAgICAgICBpbmZvcm1hdGlvbiBzZWUgdGhlIGRlZmluaXRpb24gb2YgVUxvY0RhdGFMb2NhbGVUeXBlIGluCiAgICAgKiAgICAgICAgICAgICB1bG9jLmgKICAgICAqIEBwYXJhbSBzdGF0dXMgdGhlIGVycm9yIGNvZGUgc3RhdHVzLgogICAgICogQHJldHVybiBsb2NhbGUgd2hlcmUgdGhlIGNvbGxhdGlvbiBkYXRhIGxpdmVzLiBJZiB0aGUgY29sbGF0b3IKICAgICAqICAgICAgICAgd2FzIGluc3RhbnRpYXRlZCBmcm9tIHJ1bGVzLCBsb2NhbGUgaXMgZW1wdHkuCiAgICAgKiBAZGVwcmVjYXRlZCBJQ1UgMi44IFRoaXMgQVBJIGlzIHVuZGVyIGNvbnNpZGVyYXRpb24gZm9yIHJldmlzaW9uCiAgICAgKiBpbiBJQ1UgMy4wLgogICAgICovCiAgICB2aXJ0dWFsIGNvbnN0IExvY2FsZSBnZXRMb2NhbGUoVUxvY0RhdGFMb2NhbGVUeXBlIHR5cGUsIFVFcnJvckNvZGUmIHN0YXR1cykgY29uc3QgPSAwOwoKICAgIC8qKgogICAgICogQ29udmVuaWVuY2UgbWV0aG9kIGZvciBjb21wYXJpbmcgdHdvIHN0cmluZ3MgYmFzZWQgb24gdGhlIGNvbGxhdGlvbiBydWxlcy4KICAgICAqIEBwYXJhbSBzb3VyY2UgdGhlIHNvdXJjZSBzdHJpbmcgdG8gYmUgY29tcGFyZWQgd2l0aC4KICAgICAqIEBwYXJhbSB0YXJnZXQgdGhlIHRhcmdldCBzdHJpbmcgdG8gYmUgY29tcGFyZWQgd2l0aC4KICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgZmlyc3Qgc3RyaW5nIGlzIGdyZWF0ZXIgdGhhbiB0aGUgc2Vjb25kIG9uZSwKICAgICAqICAgICAgICAgYWNjb3JkaW5nIHRvIHRoZSBjb2xsYXRpb24gcnVsZXMuIGZhbHNlLCBvdGhlcndpc2UuCiAgICAgKiBAc2VlIENvbGxhdG9yI2NvbXBhcmUKICAgICAqIEBzdGFibGUgSUNVIDIuMAogICAgICovCiAgICBVQm9vbCBncmVhdGVyKGNvbnN0IFVuaWNvZGVTdHJpbmcmIHNvdXJjZSwgY29uc3QgVW5pY29kZVN0cmluZyYgdGFyZ2V0KQogICAgICAgICAgICAgICAgICBjb25zdDsKCiAgICAvKioKICAgICAqIENvbnZlbmllbmNlIG1ldGhvZCBmb3IgY29tcGFyaW5nIHR3byBzdHJpbmdzIGJhc2VkIG9uIHRoZSBjb2xsYXRpb24gcnVsZXMuCiAgICAgKiBAcGFyYW0gc291cmNlIHRoZSBzb3VyY2Ugc3RyaW5nIHRvIGJlIGNvbXBhcmVkIHdpdGguCiAgICAgKiBAcGFyYW0gdGFyZ2V0IHRoZSB0YXJnZXQgc3RyaW5nIHRvIGJlIGNvbXBhcmVkIHdpdGguCiAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIGZpcnN0IHN0cmluZyBpcyBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gdGhlIHNlY29uZAogICAgICogICAgICAgICBvbmUsIGFjY29yZGluZyB0byB0aGUgY29sbGF0aW9uIHJ1bGVzLiBmYWxzZSwgb3RoZXJ3aXNlLgogICAgICogQHNlZSBDb2xsYXRvciNjb21wYXJlCiAgICAgKiBAc3RhYmxlIElDVSAyLjAKICAgICAqLwogICAgVUJvb2wgZ3JlYXRlck9yRXF1YWwoY29uc3QgVW5pY29kZVN0cmluZyYgc291cmNlLAogICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVW5pY29kZVN0cmluZyYgdGFyZ2V0KSBjb25zdDsKCiAgICAvKioKICAgICAqIENvbnZlbmllbmNlIG1ldGhvZCBmb3IgY29tcGFyaW5nIHR3byBzdHJpbmdzIGJhc2VkIG9uIHRoZSBjb2xsYXRpb24gcnVsZXMuCiAgICAgKiBAcGFyYW0gc291cmNlIHRoZSBzb3VyY2Ugc3RyaW5nIHRvIGJlIGNvbXBhcmVkIHdpdGguCiAgICAgKiBAcGFyYW0gdGFyZ2V0IHRoZSB0YXJnZXQgc3RyaW5nIHRvIGJlIGNvbXBhcmVkIHdpdGguCiAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIHN0cmluZ3MgYXJlIGVxdWFsIGFjY29yZGluZyB0byB0aGUgY29sbGF0aW9uIHJ1bGVzLgogICAgICogICAgICAgICBmYWxzZSwgb3RoZXJ3aXNlLgogICAgICogQHNlZSBDb2xsYXRvciNjb21wYXJlCiAgICAgKiBAc3RhYmxlIElDVSAyLjAKICAgICAqLwogICAgVUJvb2wgZXF1YWxzKGNvbnN0IFVuaWNvZGVTdHJpbmcmIHNvdXJjZSwgY29uc3QgVW5pY29kZVN0cmluZyYgdGFyZ2V0KSBjb25zdDsKCiAgICAvKioKICAgICAqIERldGVybWluZXMgdGhlIG1pbmltdW0gc3RyZW5ndGggdGhhdCB3aWxsIGJlIHVzZSBpbiBjb21wYXJpc29uIG9yCiAgICAgKiB0cmFuc2Zvcm1hdGlvbi4KICAgICAqIDxwPkUuZy4gd2l0aCBzdHJlbmd0aCA9PSBTRUNPTkRBUlksIHRoZSB0ZXJ0aWFyeSBkaWZmZXJlbmNlIGlzIGlnbm9yZWQKICAgICAqIDxwPkUuZy4gd2l0aCBzdHJlbmd0aCA9PSBQUklNQVJZLCB0aGUgc2Vjb25kYXJ5IGFuZCB0ZXJ0aWFyeSBkaWZmZXJlbmNlCiAgICAgKiBhcmUgaWdub3JlZC4KICAgICAqIEByZXR1cm4gdGhlIGN1cnJlbnQgY29tcGFyaXNvbiBsZXZlbC4KICAgICAqIEBzZWUgQ29sbGF0b3Ijc2V0U3RyZW5ndGgKICAgICAqIEBkZXByZWNhdGVkIElDVSAyLjYgVXNlIGdldEF0dHJpYnV0ZShVQ09MX1NUUkVOR1RILi4uKSBpbnN0ZWFkCiAgICAgKi8KICAgIHZpcnR1YWwgRUNvbGxhdGlvblN0cmVuZ3RoIGdldFN0cmVuZ3RoKHZvaWQpIGNvbnN0ID0gMDsKCiAgICAvKioKICAgICAqIFNldHMgdGhlIG1pbmltdW0gc3RyZW5ndGggdG8gYmUgdXNlZCBpbiBjb21wYXJpc29uIG9yIHRyYW5zZm9ybWF0aW9uLgogICAgICogPHA+RXhhbXBsZSBvZiB1c2U6CiAgICAgKiA8cHJlPgogICAgICogIFxjb2RlCiAgICAgKiAgVUVycm9yQ29kZSBzdGF0dXMgPSBVX1pFUk9fRVJST1I7CiAgICAgKiAgQ29sbGF0b3IqbXlDb2xsYXRpb24gPSBDb2xsYXRvcjo6Y3JlYXRlSW5zdGFuY2UoTG9jYWxlOjpVUywgc3RhdHVzKTsKICAgICAqICBpZiAoVV9GQUlMVVJFKHN0YXR1cykpIHJldHVybjsKICAgICAqICBteUNvbGxhdGlvbi0+c2V0U3RyZW5ndGgoQ29sbGF0b3I6OlBSSU1BUlkpOwogICAgICogIC8vIHJlc3VsdCB3aWxsIGJlICJhYmMiID09ICJBQkMiCiAgICAgKiAgLy8gdGVydGlhcnkgZGlmZmVyZW5jZXMgd2lsbCBiZSBpZ25vcmVkCiAgICAgKiAgQ29sbGF0b3I6OkNvbXBhcmlzb25SZXN1bHQgcmVzdWx0ID0gbXlDb2xsYXRpb24tPmNvbXBhcmUoImFiYyIsICJBQkMiKTsKICAgICAqIFxlbmRjb2RlCiAgICAgKiA8L3ByZT4KICAgICAqIEBzZWUgQ29sbGF0b3IjZ2V0U3RyZW5ndGgKICAgICAqIEBwYXJhbSBuZXdTdHJlbmd0aCB0aGUgbmV3IGNvbXBhcmlzb24gbGV2ZWwuCiAgICAgKiBAZGVwcmVjYXRlZCBJQ1UgMi42IFVzZSBzZXRBdHRyaWJ1dGUoVUNPTF9TVFJFTkdUSC4uLikgaW5zdGVhZAogICAgICovCiAgICB2aXJ0dWFsIHZvaWQgc2V0U3RyZW5ndGgoRUNvbGxhdGlvblN0cmVuZ3RoIG5ld1N0cmVuZ3RoKSA9IDA7CgogICAgLyoqCiAgICAgKiBHZXQgbmFtZSBvZiB0aGUgb2JqZWN0IGZvciB0aGUgZGVzaXJlZCBMb2NhbGUsIGluIHRoZSBkZXNpcmVkIGxhbmdhdWdlCiAgICAgKiBAcGFyYW0gb2JqZWN0TG9jYWxlIG11c3QgYmUgZnJvbSBnZXRBdmFpbGFibGVMb2NhbGVzCiAgICAgKiBAcGFyYW0gZGlzcGxheUxvY2FsZSBzcGVjaWZpZXMgdGhlIGRlc2lyZWQgbG9jYWxlIGZvciBvdXRwdXQKICAgICAqIEBwYXJhbSBuYW1lIHRoZSBmaWxsLWluIHBhcmFtZXRlciBvZiB0aGUgcmV0dXJuIHZhbHVlCiAgICAgKiBAcmV0dXJuIGRpc3BsYXktYWJsZSBuYW1lIG9mIHRoZSBvYmplY3QgZm9yIHRoZSBvYmplY3QgbG9jYWxlIGluIHRoZQogICAgICogICAgICAgICBkZXNpcmVkIGxhbmd1YWdlCiAgICAgKiBAc3RhYmxlIElDVSAyLjAKICAgICAqLwogICAgc3RhdGljIFVuaWNvZGVTdHJpbmcmIFVfRVhQT1JUMiBnZXREaXNwbGF5TmFtZShjb25zdCBMb2NhbGUmIG9iamVjdExvY2FsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBMb2NhbGUmIGRpc3BsYXlMb2NhbGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVW5pY29kZVN0cmluZyYgbmFtZSk7CgogICAgLyoqCiAgICAqIEdldCBuYW1lIG9mIHRoZSBvYmplY3QgZm9yIHRoZSBkZXNpcmVkIExvY2FsZSwgaW4gdGhlIGxhbmdhdWdlIG9mIHRoZQogICAgKiBkZWZhdWx0IGxvY2FsZS4KICAgICogQHBhcmFtIG9iamVjdExvY2FsZSBtdXN0IGJlIGZyb20gZ2V0QXZhaWxhYmxlTG9jYWxlcwogICAgKiBAcGFyYW0gbmFtZSB0aGUgZmlsbC1pbiBwYXJhbWV0ZXIgb2YgdGhlIHJldHVybiB2YWx1ZQogICAgKiBAcmV0dXJuIG5hbWUgb2YgdGhlIG9iamVjdCBmb3IgdGhlIGRlc2lyZWQgbG9jYWxlIGluIHRoZSBkZWZhdWx0IGxhbmd1YWdlCiAgICAqIEBzdGFibGUgSUNVIDIuMAogICAgKi8KICAgIHN0YXRpYyBVbmljb2RlU3RyaW5nJiBVX0VYUE9SVDIgZ2V0RGlzcGxheU5hbWUoY29uc3QgTG9jYWxlJiBvYmplY3RMb2NhbGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVW5pY29kZVN0cmluZyYgbmFtZSk7CgogICAgLyoqCiAgICAgKiBHZXQgdGhlIHNldCBvZiBMb2NhbGVzIGZvciB3aGljaCBDb2xsYXRpb25zIGFyZSBpbnN0YWxsZWQuCiAgICAgKgogICAgICogPHA+Tm90ZSB0aGlzIGRvZXMgbm90IGluY2x1ZGUgbG9jYWxlcyBzdXBwb3J0ZWQgYnkgcmVnaXN0ZXJlZCBjb2xsYXRvcnMuCiAgICAgKiBJZiBjb2xsYXRvcnMgbWlnaHQgaGF2ZSBiZWVuIHJlZ2lzdGVyZWQsIHVzZSB0aGUgb3ZlcmxvYWQgb2YgZ2V0QXZhaWxhYmxlTG9jYWxlcwogICAgICogdGhhdCByZXR1cm5zIGEgU3RyaW5nRW51bWVyYXRpb24uPC9wPgogICAgICoKICAgICAqIEBwYXJhbSBjb3VudCB0aGUgb3V0cHV0IHBhcmFtZXRlciBvZiBudW1iZXIgb2YgZWxlbWVudHMgaW4gdGhlIGxvY2FsZSBsaXN0CiAgICAgKiBAcmV0dXJuIHRoZSBsaXN0IG9mIGF2YWlsYWJsZSBsb2NhbGVzIGZvciB3aGljaCBjb2xsYXRpb25zIGFyZSBpbnN0YWxsZWQKICAgICAqIEBzdGFibGUgSUNVIDIuMAogICAgICovCiAgICBzdGF0aWMgY29uc3QgTG9jYWxlKiBVX0VYUE9SVDIgZ2V0QXZhaWxhYmxlTG9jYWxlcyhpbnQzMl90JiBjb3VudCk7CgojaWYgIVVDT05GSUdfTk9fU0VSVklDRQogICAgLyoqCiAgICAgKiBSZXR1cm4gYSBTdHJpbmdFbnVtZXJhdGlvbiBvdmVyIHRoZSBsb2NhbGVzIGF2YWlsYWJsZSBhdCB0aGUgdGltZSBvZiB0aGUgY2FsbCwKICAgICAqIGluY2x1ZGluZyByZWdpc3RlcmVkIGxvY2FsZXMuICBJZiBhIHNldmVyZSBlcnJvciBvY2N1cnMgKHN1Y2ggYXMgb3V0IG9mIG1lbW9yeQogICAgICogY29uZGl0aW9uKSB0aGlzIHdpbGwgcmV0dXJuIG51bGwuIElmIHRoZXJlIGlzIG5vIGxvY2FsZSBkYXRhLCBhbiBlbXB0eSBlbnVtZXJhdGlvbgogICAgICogd2lsbCBiZSByZXR1cm5lZC4KICAgICAqIEByZXR1cm4gYSBTdHJpbmdFbnVtZXJhdGlvbiBvdmVyIHRoZSBsb2NhbGVzIGF2YWlsYWJsZSBhdCB0aGUgdGltZSBvZiB0aGUgY2FsbAogICAgICogQHN0YWJsZSBJQ1UgMi42CiAgICAgKi8KICAgIHN0YXRpYyBTdHJpbmdFbnVtZXJhdGlvbiogVV9FWFBPUlQyIGdldEF2YWlsYWJsZUxvY2FsZXModm9pZCk7CiNlbmRpZgoKICAgIC8qKgogICAgICogQ3JlYXRlIGEgc3RyaW5nIGVudW1lcmF0b3Igb2YgYWxsIHBvc3NpYmxlIGtleXdvcmRzIHRoYXQgYXJlIHJlbGV2YW50IHRvCiAgICAgKiBjb2xsYXRpb24uIEF0IHRoaXMgcG9pbnQsIHRoZSBvbmx5IHJlY29nbml6ZWQga2V5d29yZCBmb3IgdGhpcwogICAgICogc2VydmljZSBpcyAiY29sbGF0aW9uIi4KICAgICAqIEBwYXJhbSBzdGF0dXMgaW5wdXQtb3V0cHV0IGVycm9yIGNvZGUKICAgICAqIEByZXR1cm4gYSBzdHJpbmcgZW51bWVyYXRpb24gb3ZlciBsb2NhbGUgc3RyaW5ncy4gVGhlIGNhbGxlciBpcwogICAgICogcmVzcG9uc2libGUgZm9yIGNsb3NpbmcgdGhlIHJlc3VsdC4KICAgICAqIEBkcmFmdCBJQ1UgMy4wCiAgICAgKi8KICAgIHN0YXRpYyBTdHJpbmdFbnVtZXJhdGlvbiogVV9FWFBPUlQyIGdldEtleXdvcmRzKFVFcnJvckNvZGUmIHN0YXR1cyk7CgogICAgLyoqCiAgICAgKiBHaXZlbiBhIGtleXdvcmQsIGNyZWF0ZSBhIHN0cmluZyBlbnVtZXJhdGlvbiBvZiBhbGwgdmFsdWVzCiAgICAgKiBmb3IgdGhhdCBrZXl3b3JkIHRoYXQgYXJlIGN1cnJlbnRseSBpbiB1c2UuCiAgICAgKiBAcGFyYW0ga2V5d29yZCBhIHBhcnRpY3VsYXIga2V5d29yZCBhcyBlbnVtZXJhdGVkIGJ5CiAgICAgKiB1Y29sX2dldEtleXdvcmRzLiBJZiBhbnkgb3RoZXIga2V5d29yZCBpcyBwYXNzZWQgaW4sIHN0YXR1cyBpcyBzZXQKICAgICAqIHRvIFVfSUxMRUdBTF9BUkdVTUVOVF9FUlJPUi4KICAgICAqIEBwYXJhbSBzdGF0dXMgaW5wdXQtb3V0cHV0IGVycm9yIGNvZGUKICAgICAqIEByZXR1cm4gYSBzdHJpbmcgZW51bWVyYXRpb24gb3ZlciBjb2xsYXRpb24ga2V5d29yZCB2YWx1ZXMsIG9yIE5VTEwKICAgICAqIHVwb24gZXJyb3IuIFRoZSBjYWxsZXIgaXMgcmVzcG9uc2libGUgZm9yIGRlbGV0aW5nIHRoZSByZXN1bHQuCiAgICAgKiBAZHJhZnQgSUNVIDMuMAogICAgICovCiAgICBzdGF0aWMgU3RyaW5nRW51bWVyYXRpb24qIFVfRVhQT1JUMiBnZXRLZXl3b3JkVmFsdWVzKGNvbnN0IGNoYXIgKmtleXdvcmQsIFVFcnJvckNvZGUmIHN0YXR1cyk7CgogICAgLyoqCiAgICAgKiBSZXR1cm4gdGhlIGZ1bmN0aW9uYWxseSBlcXVpdmFsZW50IGxvY2FsZSBmb3IgdGhlIGdpdmVuCiAgICAgKiByZXF1ZXN0ZWQgbG9jYWxlLCB3aXRoIHJlc3BlY3QgdG8gZ2l2ZW4ga2V5d29yZCwgZm9yIHRoZQogICAgICogY29sbGF0aW9uIHNlcnZpY2UuICBJZiB0d28gbG9jYWxlcyByZXR1cm4gdGhlIHNhbWUgcmVzdWx0LCB0aGVuCiAgICAgKiBjb2xsYXRvcnMgaW5zdGFudGlhdGVkIGZvciB0aGVzZSBsb2NhbGVzIHdpbGwgYmVoYXZlCiAgICAgKiBlcXVpdmFsZW50bHkuICBUaGUgY29udmVyc2UgaXMgbm90IGFsd2F5cyB0cnVlOyB0d28gY29sbGF0b3JzCiAgICAgKiBtYXkgaW4gZmFjdCBiZSBlcXVpdmFsZW50LCBidXQgcmV0dXJuIGRpZmZlcmVudCByZXN1bHRzLCBkdWUgdG8KICAgICAqIGludGVybmFsIGRldGFpbHMuICBUaGUgcmV0dXJuIHJlc3VsdCBoYXMgbm8gb3RoZXIgbWVhbmluZyB0aGFuCiAgICAgKiB0aGF0IHN0YXRlZCBhYm92ZSwgYW5kIGltcGxpZXMgbm90aGluZyBhcyB0byB0aGUgcmVsYXRpb25zaGlwCiAgICAgKiBiZXR3ZWVuIHRoZSB0d28gbG9jYWxlcy4gIFRoaXMgaXMgaW50ZW5kZWQgZm9yIHVzZSBieQogICAgICogYXBwbGljYXRpb25zIHdobyB3aXNoIHRvIGNhY2hlIGNvbGxhdG9ycywgb3Igb3RoZXJ3aXNlIHJldXNlCiAgICAgKiBjb2xsYXRvcnMgd2hlbiBwb3NzaWJsZS4gIFRoZSBmdW5jdGlvbmFsIGVxdWl2YWxlbnQgbWF5IGNoYW5nZQogICAgICogb3ZlciB0aW1lLiAgRm9yIG1vcmUgaW5mb3JtYXRpb24sIHBsZWFzZSBzZWUgdGhlIDxhCiAgICAgKiBocmVmPSJodHRwOi8vb3NzLnNvZnR3YXJlLmlibS5jb20vaWN1L3VzZXJndWlkZS9sb2NhbGUuaHRtbCNzZXJ2aWNlcyI+CiAgICAgKiBMb2NhbGVzIGFuZCBTZXJ2aWNlczwvYT4gc2VjdGlvbiBvZiB0aGUgSUNVIFVzZXIgR3VpZGUuCiAgICAgKiBAcGFyYW0ga2V5d29yZCBhIHBhcnRpY3VsYXIga2V5d29yZCBhcyBlbnVtZXJhdGVkIGJ5CiAgICAgKiB1Y29sX2dldEtleXdvcmRzLgogICAgICogQHBhcmFtIGxvY2FsZSB0aGUgcmVxdWVzdGVkIGxvY2FsZQogICAgICogQHBhcmFtIGlzQXZhaWxhYmxlIHJlZmVyZW5jZSB0byBhIGZpbGxpbiBwYXJhbWV0ZXIgdGhhdAogICAgICogaW5kaWNhdGVzIHdoZXRoZXIgdGhlIHJlcXVlc3RlZCBsb2NhbGUgd2FzICdhdmFpbGFibGUnIHRvIHRoZQogICAgICogY29sbGF0aW9uIHNlcnZpY2UuIEEgbG9jYWxlIGlzIGRlZmluZWQgYXMgJ2F2YWlsYWJsZScgaWYgaXQKICAgICAqIHBoeXNpY2FsbHkgZXhpc3RzIHdpdGhpbiB0aGUgY29sbGF0aW9uIGxvY2FsZSBkYXRhLgogICAgICogQHBhcmFtIHN0YXR1cyByZWZlcmVuY2UgdG8gaW5wdXQtb3V0cHV0IGVycm9yIGNvZGUKICAgICAqIEByZXR1cm4gdGhlIGZ1bmN0aW9uYWxseSBlcXVpdmFsZW50IGNvbGxhdGlvbiBsb2NhbGUsIG9yIHRoZSByb290CiAgICAgKiBsb2NhbGUgdXBvbiBlcnJvci4KICAgICAqIEBkcmFmdCBJQ1UgMy4wCiAgICAgKi8KICAgIHN0YXRpYyBMb2NhbGUgVV9FWFBPUlQyIGdldEZ1bmN0aW9uYWxFcXVpdmFsZW50KGNvbnN0IGNoYXIqIGtleXdvcmQsIGNvbnN0IExvY2FsZSYgbG9jYWxlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVQm9vbCYgaXNBdmFpbGFibGUsIFVFcnJvckNvZGUmIHN0YXR1cyk7CgojaWYgIVVDT05GSUdfTk9fU0VSVklDRQogICAgLyoqCiAgICAgKiBSZWdpc3RlciBhIG5ldyBDb2xsYXRvci4gIFRoZSBjb2xsYXRvciB3aWxsIGJlIGFkb3B0ZWQuCiAgICAgKiBAcGFyYW0gdG9BZG9wdCB0aGUgQ29sbGF0b3IgaW5zdGFuY2UgdG8gYmUgYWRvcHRlZAogICAgICogQHBhcmFtIGxvY2FsZSB0aGUgbG9jYWxlIHdpdGggd2hpY2ggdGhlIGNvbGxhdG9yIHdpbGwgYmUgYXNzb2NpYXRlZAogICAgICogQHBhcmFtIHN0YXR1cyB0aGUgaW4vb3V0IHN0YXR1cyBjb2RlLCBubyBzcGVjaWFsIG1lYW5pbmdzIGFyZSBhc3NpZ25lZAogICAgICogQHJldHVybiBhIHJlZ2lzdHJ5IGtleSB0aGF0IGNhbiBiZSB1c2VkIHRvIHVucmVnaXN0ZXIgdGhpcyBjb2xsYXRvcgogICAgICogQHN0YWJsZSBJQ1UgMi42CiAgICAgKi8KICAgIHN0YXRpYyBVUmVnaXN0cnlLZXkgVV9FWFBPUlQyIHJlZ2lzdGVySW5zdGFuY2UoQ29sbGF0b3IqIHRvQWRvcHQsIGNvbnN0IExvY2FsZSYgbG9jYWxlLCBVRXJyb3JDb2RlJiBzdGF0dXMpOwoKICAgIC8qKgogICAgICogUmVnaXN0ZXIgYSBuZXcgQ29sbGF0b3JGYWN0b3J5LiAgVGhlIGZhY3Rvcnkgd2lsbCBiZSBhZG9wdGVkLgogICAgICogQHBhcmFtIHRvQWRvcHQgdGhlIENvbGxhdG9yRmFjdG9yeSBpbnN0YW5jZSB0byBiZSBhZG9wdGVkCiAgICAgKiBAcGFyYW0gc3RhdHVzIHRoZSBpbi9vdXQgc3RhdHVzIGNvZGUsIG5vIHNwZWNpYWwgbWVhbmluZ3MgYXJlIGFzc2lnbmVkCiAgICAgKiBAcmV0dXJuIGEgcmVnaXN0cnkga2V5IHRoYXQgY2FuIGJlIHVzZWQgdG8gdW5yZWdpc3RlciB0aGlzIGNvbGxhdG9yCiAgICAgKiBAc3RhYmxlIElDVSAyLjYKICAgICAqLwogICAgc3RhdGljIFVSZWdpc3RyeUtleSBVX0VYUE9SVDIgcmVnaXN0ZXJGYWN0b3J5KENvbGxhdG9yRmFjdG9yeSogdG9BZG9wdCwgVUVycm9yQ29kZSYgc3RhdHVzKTsKCiAgICAvKioKICAgICAqIFVucmVnaXN0ZXIgYSBwcmV2aW91c2x5LXJlZ2lzdGVyZWQgQ29sbGF0b3Igb3IgQ29sbGF0b3JGYWN0b3J5CiAgICAgKiB1c2luZyB0aGUga2V5IHJldHVybmVkIGZyb20gdGhlIHJlZ2lzdGVyIGNhbGwuICBLZXkgYmVjb21lcwogICAgICogaW52YWxpZCBhZnRlciBhIHN1Y2Nlc3NmdWwgY2FsbCBhbmQgc2hvdWxkIG5vdCBiZSB1c2VkIGFnYWluLgogICAgICogVGhlIG9iamVjdCBjb3JyZXNwb25kaW5nIHRvIHRoZSBrZXkgd2lsbCBiZSBkZWxldGVkLgogICAgICogQHBhcmFtIGtleSB0aGUgcmVnaXN0cnkga2V5IHJldHVybmVkIGJ5IGEgcHJldmlvdXMgY2FsbCB0byByZWdpc3Rlckluc3RhbmNlCiAgICAgKiBAcGFyYW0gc3RhdHVzIHRoZSBpbi9vdXQgc3RhdHVzIGNvZGUsIG5vIHNwZWNpYWwgbWVhbmluZ3MgYXJlIGFzc2lnbmVkCiAgICAgKiBAcmV0dXJuIFRSVUUgaWYgdGhlIGNvbGxhdG9yIGZvciB0aGUga2V5IHdhcyBzdWNjZXNzZnVsbHkgdW5yZWdpc3RlcmVkCiAgICAgKiBAc3RhYmxlIElDVSAyLjYKICAgICAqLwogICAgc3RhdGljIFVCb29sIFVfRVhQT1JUMiB1bnJlZ2lzdGVyKFVSZWdpc3RyeUtleSBrZXksIFVFcnJvckNvZGUmIHN0YXR1cyk7CiNlbmRpZiAvKiBVQ09ORklHX05PX1NFUlZJQ0UgKi8KCiAgICAvKioKICAgICAqIEdldHMgdGhlIHZlcnNpb24gaW5mb3JtYXRpb24gZm9yIGEgQ29sbGF0b3IuCiAgICAgKiBAcGFyYW0gaW5mbyB0aGUgdmVyc2lvbiAjIGluZm9ybWF0aW9uLCB0aGUgcmVzdWx0IHdpbGwgYmUgZmlsbGVkIGluCiAgICAgKiBAc3RhYmxlIElDVSAyLjAKICAgICAqLwogICAgdmlydHVhbCB2b2lkIGdldFZlcnNpb24oVVZlcnNpb25JbmZvIGluZm8pIGNvbnN0ID0gMDsKCiAgICAvKioKICAgICAqIFJldHVybnMgYSB1bmlxdWUgY2xhc3MgSUQgUE9MWU1PUlBISUNBTExZLiBQdXJlIHZpcnR1YWwgbWV0aG9kLgogICAgICogVGhpcyBtZXRob2QgaXMgdG8gaW1wbGVtZW50IGEgc2ltcGxlIHZlcnNpb24gb2YgUlRUSSwgc2luY2Ugbm90IGFsbCBDKysKICAgICAqIGNvbXBpbGVycyBzdXBwb3J0IGdlbnVpbmUgUlRUSS4gUG9seW1vcnBoaWMgb3BlcmF0b3I9PSgpIGFuZCBjbG9uZSgpCiAgICAgKiBtZXRob2RzIGNhbGwgdGhpcyBtZXRob2QuCiAgICAgKiBAcmV0dXJuIFRoZSBjbGFzcyBJRCBmb3IgdGhpcyBvYmplY3QuIEFsbCBvYmplY3RzIG9mIGEgZ2l2ZW4gY2xhc3MgaGF2ZQogICAgICogICAgICAgICB0aGUgc2FtZSBjbGFzcyBJRC4gIE9iamVjdHMgb2Ygb3RoZXIgY2xhc3NlcyBoYXZlIGRpZmZlcmVudCBjbGFzcwogICAgICogICAgICAgICBJRHMuCiAgICAgKiBAc3RhYmxlIElDVSAyLjAKICAgICAqLwogICAgdmlydHVhbCBVQ2xhc3NJRCBnZXREeW5hbWljQ2xhc3NJRCh2b2lkKSBjb25zdCA9IDA7CgogICAgLyoqCiAgICAgKiBVbml2ZXJzYWwgYXR0cmlidXRlIHNldHRlcgogICAgICogQHBhcmFtIGF0dHIgYXR0cmlidXRlIHR5cGUKICAgICAqIEBwYXJhbSB2YWx1ZSBhdHRyaWJ1dGUgdmFsdWUKICAgICAqIEBwYXJhbSBzdGF0dXMgdG8gaW5kaWNhdGUgd2hldGhlciB0aGUgb3BlcmF0aW9uIHdlbnQgb24gc21vb3RobHkgb3IKICAgICAqICAgICAgICB0aGVyZSB3ZXJlIGVycm9ycwogICAgICogQHN0YWJsZSBJQ1UgMi4yCiAgICAgKi8KICAgIHZpcnR1YWwgdm9pZCBzZXRBdHRyaWJ1dGUoVUNvbEF0dHJpYnV0ZSBhdHRyLCBVQ29sQXR0cmlidXRlVmFsdWUgdmFsdWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUgJnN0YXR1cykgPSAwOwoKICAgIC8qKgogICAgICogVW5pdmVyc2FsIGF0dHJpYnV0ZSBnZXR0ZXIKICAgICAqIEBwYXJhbSBhdHRyIGF0dHJpYnV0ZSB0eXBlCiAgICAgKiBAcGFyYW0gc3RhdHVzIHRvIGluZGljYXRlIHdoZXRoZXIgdGhlIG9wZXJhdGlvbiB3ZW50IG9uIHNtb290aGx5IG9yCiAgICAgKiAgICAgICAgdGhlcmUgd2VyZSBlcnJvcnMKICAgICAqIEByZXR1cm4gYXR0cmlidXRlIHZhbHVlCiAgICAgKiBAc3RhYmxlIElDVSAyLjIKICAgICAqLwogICAgdmlydHVhbCBVQ29sQXR0cmlidXRlVmFsdWUgZ2V0QXR0cmlidXRlKFVDb2xBdHRyaWJ1dGUgYXR0ciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlICZzdGF0dXMpID0gMDsKCiAgICAvKioKICAgICAqIFNldHMgdGhlIHZhcmlhYmxlIHRvcCB0byBhIGNvbGxhdGlvbiBlbGVtZW50IHZhbHVlIG9mIGEgc3RyaW5nIHN1cHBsaWVkLgogICAgICogQHBhcmFtIHZhclRvcCBvbmUgb3IgbW9yZSAoaWYgY29udHJhY3Rpb24pIFVDaGFycyB0byB3aGljaCB0aGUgdmFyaWFibGUgdG9wIHNob3VsZCBiZSBzZXQKICAgICAqIEBwYXJhbSBsZW4gbGVuZ3RoIG9mIHZhcmlhYmxlIHRvcCBzdHJpbmcuIElmIC0xIGl0IGlzIGNvbnNpZGVyZWQgdG8gYmUgemVybyB0ZXJtaW5hdGVkLgogICAgICogQHBhcmFtIHN0YXR1cyBlcnJvciBjb2RlLiBJZiBlcnJvciBjb2RlIGlzIHNldCwgdGhlIHJldHVybiB2YWx1ZSBpcyB1bmRlZmluZWQuIEVycm9ycyBzZXQgYnkgdGhpcyBmdW5jdGlvbiBhcmU6IDxicj4KICAgICAqICAgIFVfQ0VfTk9UX0ZPVU5EX0VSUk9SIGlmIG1vcmUgdGhhbiBvbmUgY2hhcmFjdGVyIHdhcyBwYXNzZWQgYW5kIHRoZXJlIGlzIG5vIHN1Y2ggYSBjb250cmFjdGlvbjxicj4KICAgICAqICAgIFVfUFJJTUFSWV9UT09fTE9OR19FUlJPUiBpZiB0aGUgcHJpbWFyeSBmb3IgdGhlIHZhcmlhYmxlIHRvcCBoYXMgbW9yZSB0aGFuIHR3byBieXRlcwogICAgICogQHJldHVybiBhIDMyIGJpdCB2YWx1ZSBjb250YWluaW5nIHRoZSB2YWx1ZSBvZiB0aGUgdmFyaWFibGUgdG9wIGluIHVwcGVyIDE2IGJpdHMuIExvd2VyIDE2IGJpdHMgYXJlIHVuZGVmaW5lZAogICAgICogQHN0YWJsZSBJQ1UgMi4wCiAgICAgKi8KICAgIHZpcnR1YWwgdWludDMyX3Qgc2V0VmFyaWFibGVUb3AoY29uc3QgVUNoYXIgKnZhclRvcCwgaW50MzJfdCBsZW4sIFVFcnJvckNvZGUgJnN0YXR1cykgPSAwOwoKICAgIC8qKgogICAgICogU2V0cyB0aGUgdmFyaWFibGUgdG9wIHRvIGEgY29sbGF0aW9uIGVsZW1lbnQgdmFsdWUgb2YgYSBzdHJpbmcgc3VwcGxpZWQuCiAgICAgKiBAcGFyYW0gdmFyVG9wIGFuIFVuaWNvZGVTdHJpbmcgc2l6ZSAxIG9yIG1vcmUgKGlmIGNvbnRyYWN0aW9uKSBvZiBVQ2hhcnMgdG8gd2hpY2ggdGhlIHZhcmlhYmxlIHRvcCBzaG91bGQgYmUgc2V0CiAgICAgKiBAcGFyYW0gc3RhdHVzIGVycm9yIGNvZGUuIElmIGVycm9yIGNvZGUgaXMgc2V0LCB0aGUgcmV0dXJuIHZhbHVlIGlzIHVuZGVmaW5lZC4gRXJyb3JzIHNldCBieSB0aGlzIGZ1bmN0aW9uIGFyZTogPGJyPgogICAgICogICAgVV9DRV9OT1RfRk9VTkRfRVJST1IgaWYgbW9yZSB0aGFuIG9uZSBjaGFyYWN0ZXIgd2FzIHBhc3NlZCBhbmQgdGhlcmUgaXMgbm8gc3VjaCBhIGNvbnRyYWN0aW9uPGJyPgogICAgICogICAgVV9QUklNQVJZX1RPT19MT05HX0VSUk9SIGlmIHRoZSBwcmltYXJ5IGZvciB0aGUgdmFyaWFibGUgdG9wIGhhcyBtb3JlIHRoYW4gdHdvIGJ5dGVzCiAgICAgKiBAcmV0dXJuIGEgMzIgYml0IHZhbHVlIGNvbnRhaW5pbmcgdGhlIHZhbHVlIG9mIHRoZSB2YXJpYWJsZSB0b3AgaW4gdXBwZXIgMTYgYml0cy4gTG93ZXIgMTYgYml0cyBhcmUgdW5kZWZpbmVkCiAgICAgKiBAc3RhYmxlIElDVSAyLjAKICAgICAqLwogICAgdmlydHVhbCB1aW50MzJfdCBzZXRWYXJpYWJsZVRvcChjb25zdCBVbmljb2RlU3RyaW5nIHZhclRvcCwgVUVycm9yQ29kZSAmc3RhdHVzKSA9IDA7CgogICAgLyoqCiAgICAgKiBTZXRzIHRoZSB2YXJpYWJsZSB0b3AgdG8gYSBjb2xsYXRpb24gZWxlbWVudCB2YWx1ZSBzdXBwbGllZC4gVmFyaWFibGUgdG9wIGlzIHNldCB0byB0aGUgdXBwZXIgMTYgYml0cy4KICAgICAqIExvd2VyIDE2IGJpdHMgYXJlIGlnbm9yZWQuCiAgICAgKiBAcGFyYW0gdmFyVG9wIENFIHZhbHVlLCBhcyByZXR1cm5lZCBieSBzZXRWYXJpYWJsZVRvcCBvciB1Y29sKWdldFZhcmlhYmxlVG9wCiAgICAgKiBAcGFyYW0gc3RhdHVzIGVycm9yIGNvZGUgKG5vdCBjaGFuZ2VkIGJ5IGZ1bmN0aW9uKQogICAgICogQHN0YWJsZSBJQ1UgMi4wCiAgICAgKi8KICAgIHZpcnR1YWwgdm9pZCBzZXRWYXJpYWJsZVRvcChjb25zdCB1aW50MzJfdCB2YXJUb3AsIFVFcnJvckNvZGUgJnN0YXR1cykgPSAwOwoKICAgIC8qKgogICAgICogR2V0cyB0aGUgdmFyaWFibGUgdG9wIHZhbHVlIG9mIGEgQ29sbGF0b3IuCiAgICAgKiBMb3dlciAxNiBiaXRzIGFyZSB1bmRlZmluZWQgYW5kIHNob3VsZCBiZSBpZ25vcmVkLgogICAgICogQHBhcmFtIHN0YXR1cyBlcnJvciBjb2RlIChub3QgY2hhbmdlZCBieSBmdW5jdGlvbikuIElmIGVycm9yIGNvZGUgaXMgc2V0LCB0aGUgcmV0dXJuIHZhbHVlIGlzIHVuZGVmaW5lZC4KICAgICAqIEBzdGFibGUgSUNVIDIuMAogICAgICovCiAgICB2aXJ0dWFsIHVpbnQzMl90IGdldFZhcmlhYmxlVG9wKFVFcnJvckNvZGUgJnN0YXR1cykgY29uc3QgPSAwOwoKICAgIC8qKgogICAgICogR2V0IGFuIFVuaWNvZGVTZXQgdGhhdCBjb250YWlucyBhbGwgdGhlIGNoYXJhY3RlcnMgYW5kIHNlcXVlbmNlcwogICAgICogdGFpbG9yZWQgaW4gdGhpcyBjb2xsYXRvci4KICAgICAqIEBwYXJhbSBzdGF0dXMgICAgICBlcnJvciBjb2RlIG9mIHRoZSBvcGVyYXRpb24KICAgICAqIEByZXR1cm4gYSBwb2ludGVyIHRvIGEgVW5pY29kZVNldCBvYmplY3QgY29udGFpbmluZyBhbGwgdGhlCiAgICAgKiAgICAgICAgIGNvZGUgcG9pbnRzIGFuZCBzZXF1ZW5jZXMgdGhhdCBtYXkgc29ydCBkaWZmZXJlbnRseSB0aGFuCiAgICAgKiAgICAgICAgIGluIHRoZSBVQ0EuIFRoZSBvYmplY3QgbXVzdCBiZSBkaXNwb3NlZCBvZiBieSB1c2luZyBkZWxldGUKICAgICAqIEBzdGFibGUgSUNVIDIuNAogICAgICovCiAgICB2aXJ0dWFsIFVuaWNvZGVTZXQgKmdldFRhaWxvcmVkU2V0KFVFcnJvckNvZGUgJnN0YXR1cykgY29uc3Q7CgoKICAgIC8qKgogICAgICogVGhyZWFkIHNhZmUgY2xvbmluZyBvcGVyYXRpb24KICAgICAqIEByZXR1cm4gcG9pbnRlciB0byB0aGUgbmV3IGNsb25lLCB1c2VyIHNob3VsZCByZW1vdmUgaXQuCiAgICAgKiBAc3RhYmxlIElDVSAyLjIKICAgICAqLwogICAgdmlydHVhbCBDb2xsYXRvciogc2FmZUNsb25lKHZvaWQpID0gMDsKCiAgICAvKioKICAgICAqIEdldCB0aGUgc29ydCBrZXkgYXMgYW4gYXJyYXkgb2YgYnl0ZXMgZnJvbSBhbiBVbmljb2RlU3RyaW5nLgogICAgICogU29ydCBrZXkgYnl0ZSBhcnJheXMgYXJlIHplcm8tdGVybWluYXRlZCBhbmQgY2FuIGJlIGNvbXBhcmVkIHVzaW5nCiAgICAgKiBzdHJjbXAoKS4KICAgICAqIEBwYXJhbSBzb3VyY2Ugc3RyaW5nIHRvIGJlIHByb2Nlc3NlZC4KICAgICAqIEBwYXJhbSByZXN1bHQgYnVmZmVyIHRvIHN0b3JlIHJlc3VsdCBpbi4gSWYgTlVMTCwgbnVtYmVyIG9mIGJ5dGVzIG5lZWRlZAogICAgICogICAgICAgIHdpbGwgYmUgcmV0dXJuZWQuCiAgICAgKiBAcGFyYW0gcmVzdWx0TGVuZ3RoIGxlbmd0aCBvZiB0aGUgcmVzdWx0IGJ1ZmZlci4gSWYgaWYgbm90IGVub3VnaCB0aGUKICAgICAqICAgICAgICBidWZmZXIgd2lsbCBiZSBmaWxsZWQgdG8gY2FwYWNpdHkuCiAgICAgKiBAcmV0dXJuIE51bWJlciBvZiBieXRlcyBuZWVkZWQgZm9yIHN0b3JpbmcgdGhlIHNvcnQga2V5CiAgICAgKiBAc3RhYmxlIElDVSAyLjIKICAgICAqLwogICAgdmlydHVhbCBpbnQzMl90IGdldFNvcnRLZXkoY29uc3QgVW5pY29kZVN0cmluZyYgc291cmNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1aW50OF90KiByZXN1bHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludDMyX3QgcmVzdWx0TGVuZ3RoKSBjb25zdCA9IDA7CgogICAgLyoqCiAgICAgKiBHZXQgdGhlIHNvcnQga2V5IGFzIGFuIGFycmF5IG9mIGJ5dGVzIGZyb20gYW4gVUNoYXIgYnVmZmVyLgogICAgICogU29ydCBrZXkgYnl0ZSBhcnJheXMgYXJlIHplcm8tdGVybWluYXRlZCBhbmQgY2FuIGJlIGNvbXBhcmVkIHVzaW5nCiAgICAgKiBzdHJjbXAoKS4KICAgICAqIEBwYXJhbSBzb3VyY2Ugc3RyaW5nIHRvIGJlIHByb2Nlc3NlZC4KICAgICAqIEBwYXJhbSBzb3VyY2VMZW5ndGggbGVuZ3RoIG9mIHN0cmluZyB0byBiZSBwcm9jZXNzZWQuCiAgICAgKiAgICAgICAgSWYgLTEsIHRoZSBzdHJpbmcgaXMgMCB0ZXJtaW5hdGVkIGFuZCBsZW5ndGggd2lsbCBiZSBkZWNpZGVkIGJ5IHRoZQogICAgICogICAgICAgIGZ1bmN0aW9uLgogICAgICogQHBhcmFtIHJlc3VsdCBidWZmZXIgdG8gc3RvcmUgcmVzdWx0IGluLiBJZiBOVUxMLCBudW1iZXIgb2YgYnl0ZXMgbmVlZGVkCiAgICAgKiAgICAgICAgd2lsbCBiZSByZXR1cm5lZC4KICAgICAqIEBwYXJhbSByZXN1bHRMZW5ndGggbGVuZ3RoIG9mIHRoZSByZXN1bHQgYnVmZmVyLiBJZiBpZiBub3QgZW5vdWdoIHRoZQogICAgICogICAgICAgIGJ1ZmZlciB3aWxsIGJlIGZpbGxlZCB0byBjYXBhY2l0eS4KICAgICAqIEByZXR1cm4gTnVtYmVyIG9mIGJ5dGVzIG5lZWRlZCBmb3Igc3RvcmluZyB0aGUgc29ydCBrZXkKICAgICAqIEBzdGFibGUgSUNVIDIuMgogICAgICovCiAgICB2aXJ0dWFsIGludDMyX3QgZ2V0U29ydEtleShjb25zdCBVQ2hhcipzb3VyY2UsIGludDMyX3Qgc291cmNlTGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdWludDhfdCpyZXN1bHQsIGludDMyX3QgcmVzdWx0TGVuZ3RoKSBjb25zdCA9IDA7CgogICAgLyoqCiAgICAgKiBQcm9kdWNlIGEgYm91bmQgZm9yIGEgZ2l2ZW4gc29ydGtleSBhbmQgYSBudW1iZXIgb2YgbGV2ZWxzLgogICAgICogUmV0dXJuIHZhbHVlIGlzIGFsd2F5cyB0aGUgbnVtYmVyIG9mIGJ5dGVzIG5lZWRlZCwgcmVnYXJkbGVzcyBvZgogICAgICogd2hldGhlciB0aGUgcmVzdWx0IGJ1ZmZlciB3YXMgYmlnIGVub3VnaCBvciBldmVuIHZhbGlkLjxicj4KICAgICAqIFJlc3VsdGluZyBib3VuZHMgY2FuIGJlIHVzZWQgdG8gcHJvZHVjZSBhIHJhbmdlIG9mIHN0cmluZ3MgdGhhdCBhcmUKICAgICAqIGJldHdlZW4gdXBwZXIgYW5kIGxvd2VyIGJvdW5kcy4gRm9yIGV4YW1wbGUsIGlmIGJvdW5kcyBhcmUgcHJvZHVjZWQKICAgICAqIGZvciBhIHNvcnRrZXkgb2Ygc3RyaW5nICJzbWl0aCIsIHN0cmluZ3MgYmV0d2VlbiB1cHBlciBhbmQgbG93ZXIKICAgICAqIGJvdW5kcyB3aXRoIG9uZSBsZXZlbCB3b3VsZCBpbmNsdWRlICJTbWl0aCIsICJTTUlUSCIsICJzTWlUaCIuPGJyPgogICAgICogVGhlcmUgYXJlIHR3byB1cHBlciBib3VuZHMgdGhhdCBjYW4gYmUgcHJvZHVjZWQuIElmIFVDT0xfQk9VTkRfVVBQRVIKICAgICAqIGlzIHByb2R1Y2VkLCBzdHJpbmdzIG1hdGNoZWQgd291bGQgYmUgYXMgYWJvdmUuIEhvd2V2ZXIsIGlmIGJvdW5kCiAgICAgKiBwcm9kdWNlZCB1c2luZyBVQ09MX0JPVU5EX1VQUEVSX0xPTkcgaXMgdXNlZCwgdGhlIGFib3ZlIGV4YW1wbGUgd2lsbAogICAgICogYWxzbyBtYXRjaCAiU21pdGhzb25pYW4iIGFuZCBzaW1pbGFyLjxicj4KICAgICAqIEZvciBtb3JlIG9uIHVzYWdlLCBzZWUgZXhhbXBsZSBpbiBjaW50bHRzdC9jYXBpdHN0LmMgaW4gcHJvY2VkdXJlCiAgICAgKiBUZXN0Qm91bmRzLgogICAgICogU29ydCBrZXlzIG1heSBiZSBjb21wYXJlZCB1c2luZyA8VFQ+c3RyY21wPC9UVD4uCiAgICAgKiBAcGFyYW0gc291cmNlIFRoZSBzb3VyY2Ugc29ydGtleS4KICAgICAqIEBwYXJhbSBzb3VyY2VMZW5ndGggVGhlIGxlbmd0aCBvZiBzb3VyY2UsIG9yIC0xIGlmIG51bGwtdGVybWluYXRlZC4KICAgICAqICAgICAgICAgICAgICAgICAgICAgKElmIGFuIHVubW9kaWZpZWQgc29ydGtleSBpcyBwYXNzZWQsIGl0IGlzIGFsd2F5cyBudWxsCiAgICAgKiAgICAgICAgICAgICAgICAgICAgICB0ZXJtaW5hdGVkKS4KICAgICAqIEBwYXJhbSBib3VuZFR5cGUgVHlwZSBvZiBib3VuZCByZXF1aXJlZC4gSXQgY2FuIGJlIFVDT0xfQk9VTkRfTE9XRVIsIHdoaWNoCiAgICAgKiAgICAgICAgICAgICAgICAgIHByb2R1Y2VzIGEgbG93ZXIgaW5jbHVzaXZlIGJvdW5kLCBVQ09MX0JPVU5EX1VQUEVSLCB0aGF0CiAgICAgKiAgICAgICAgICAgICAgICAgIHByb2R1Y2VzIHVwcGVyIGJvdW5kIHRoYXQgbWF0Y2hlcyBzdHJpbmdzIG9mIHRoZSBzYW1lIGxlbmd0aAogICAgICogICAgICAgICAgICAgICAgICBvciBVQ09MX0JPVU5EX1VQUEVSX0xPTkcgdGhhdCBtYXRjaGVzIHN0cmluZ3MgdGhhdCBoYXZlIHRoZQogICAgICogICAgICAgICAgICAgICAgICBzYW1lIHN0YXJ0aW5nIHN1YnN0cmluZyBhcyB0aGUgc291cmNlIHN0cmluZy4KICAgICAqIEBwYXJhbSBub09mTGV2ZWxzICBOdW1iZXIgb2YgbGV2ZWxzIHJlcXVpcmVkIGluIHRoZSByZXN1bHRpbmcgYm91bmQgKGZvciBtb3N0CiAgICAgKiAgICAgICAgICAgICAgICAgICAgdXNlcywgdGhlIHJlY29tbWVuZGVkIHZhbHVlIGlzIDEpLiBTZWUgdXNlcnMgZ3VpZGUgZm9yCiAgICAgKiAgICAgICAgICAgICAgICAgICAgZXhwbGFuYXRpb24gb24gbnVtYmVyIG9mIGxldmVscyBhIHNvcnRrZXkgY2FuIGhhdmUuCiAgICAgKiBAcGFyYW0gcmVzdWx0IEEgcG9pbnRlciB0byBhIGJ1ZmZlciB0byByZWNlaXZlIHRoZSByZXN1bHRpbmcgc29ydGtleS4KICAgICAqIEBwYXJhbSByZXN1bHRMZW5ndGggVGhlIG1heGltdW0gc2l6ZSBvZiByZXN1bHQuCiAgICAgKiBAcGFyYW0gc3RhdHVzIFVzZWQgZm9yIHJldHVybmluZyBlcnJvciBjb2RlIGlmIHNvbWV0aGluZyB3ZW50IHdyb25nLiBJZiB0aGUKICAgICAqICAgICAgICAgICAgICAgbnVtYmVyIG9mIGxldmVscyByZXF1ZXN0ZWQgaXMgaGlnaGVyIHRoYW4gdGhlIG51bWJlciBvZiBsZXZlbHMKICAgICAqICAgICAgICAgICAgICAgaW4gdGhlIHNvdXJjZSBrZXksIGEgd2FybmluZyAoVV9TT1JUX0tFWV9UT09fU0hPUlRfV0FSTklORykgaXMKICAgICAqICAgICAgICAgICAgICAgaXNzdWVkLgogICAgICogQHJldHVybiBUaGUgc2l6ZSBuZWVkZWQgdG8gZnVsbHkgc3RvcmUgdGhlIGJvdW5kLgogICAgICogQHNlZSB1Y29sX2tleUhhc2hDb2RlCiAgICAgKiBAc3RhYmxlIElDVSAyLjEKICAgICAqLwogICAgc3RhdGljIGludDMyX3QgVV9FWFBPUlQyIGdldEJvdW5kKGNvbnN0IHVpbnQ4X3QgICAgICAgKnNvdXJjZSwKICAgICAgICAgICAgaW50MzJfdCAgICAgICAgICAgICBzb3VyY2VMZW5ndGgsCiAgICAgICAgICAgIFVDb2xCb3VuZE1vZGUgICAgICAgYm91bmRUeXBlLAogICAgICAgICAgICB1aW50MzJfdCAgICAgICAgICAgIG5vT2ZMZXZlbHMsCiAgICAgICAgICAgIHVpbnQ4X3QgICAgICAgICAgICAgKnJlc3VsdCwKICAgICAgICAgICAgaW50MzJfdCAgICAgICAgICAgICByZXN1bHRMZW5ndGgsCiAgICAgICAgICAgIFVFcnJvckNvZGUgICAgICAgICAgJnN0YXR1cyk7CgoKcHJvdGVjdGVkOgoKICAgIC8vIENvbGxhdG9yIHByb3RlY3RlZCBjb25zdHJ1Y3RvcnMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIC8qKgogICAgKiBEZWZhdWx0IGNvbnN0cnVjdG9yLgogICAgKiBDb25zdHJ1Y3RvciBpcyBkaWZmZXJlbnQgZnJvbSB0aGUgb2xkIGRlZmF1bHQgQ29sbGF0b3IgY29uc3RydWN0b3IuCiAgICAqIFRoZSB0YXNrIGZvciBkZXRlcm1pbmcgdGhlIGRlZmF1bHQgY29sbGF0aW9uIHN0cmVuZ3RoIGFuZCBub3JtYWxpemF0aW9uCiAgICAqIG1vZGUgaXMgbGVmdCB0byB0aGUgY2hpbGQgY2xhc3MuCiAgICAqIEBzdGFibGUgSUNVIDIuMAogICAgKi8KICAgIENvbGxhdG9yKCk7CgogICAgLyoqCiAgICAqIENvbnN0cnVjdG9yLgogICAgKiBFbXB0eSBjb25zdHJ1Y3RvciwgZG9lcyBub3QgaGFuZGxlIHRoZSBhcmd1bWVudHMuCiAgICAqIFRoaXMgY29uc3RydWN0b3IgaXMgZG9uZSBmb3IgYmFja3dhcmQgY29tcGF0aWJpbGl0eSB3aXRoIDEuNyBhbmQgMS44LgogICAgKiBUaGUgdGFzayBmb3IgaGFuZGxpbmcgdGhlIGFyZ3VtZW50IGNvbGxhdGlvbiBzdHJlbmd0aCBhbmQgbm9ybWFsaXphdGlvbgogICAgKiBtb2RlIGlzIGxlZnQgdG8gdGhlIGNoaWxkIGNsYXNzLgogICAgKiBAcGFyYW0gY29sbGF0aW9uU3RyZW5ndGggY29sbGF0aW9uIHN0cmVuZ3RoCiAgICAqIEBwYXJhbSBkZWNvbXBvc2l0aW9uTW9kZQogICAgKiBAZGVwcmVjYXRlZCBJQ1UgMi40LiBTdWJjbGFzc2VzIHNob3VsZCB1c2UgdGhlIGRlZmF1bHQgY29uc3RydWN0b3IKICAgICogaW5zdGVhZCBhbmQgaGFuZGxlIHRoZSBzdHJlbmd0aCBhbmQgbm9ybWFsaXphdGlvbiBtb2RlIHRoZW1zZWx2ZXMuCiAgICAqLwogICAgQ29sbGF0b3IoVUNvbGxhdGlvblN0cmVuZ3RoIGNvbGxhdGlvblN0cmVuZ3RoLAogICAgICAgICAgICAgVU5vcm1hbGl6YXRpb25Nb2RlIGRlY29tcG9zaXRpb25Nb2RlKTsKCiAgICAvKioKICAgICogQ29weSBjb25zdHJ1Y3Rvci4KICAgICogQHBhcmFtIG90aGVyIENvbGxhdG9yIG9iamVjdCB0byBiZSBjb3BpZWQgZnJvbQogICAgKiBAc3RhYmxlIElDVSAyLjAKICAgICovCiAgICBDb2xsYXRvcihjb25zdCBDb2xsYXRvciYgb3RoZXIpOwoKICAgIC8vIENvbGxhdG9yIHByb3RlY3RlZCBtZXRob2RzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgoKICAgLyoqCiAgICAqIFVzZWQgaW50ZXJuYWxseSBieSByZWdpc3RyYXRvbiB0byBkZWZpbmUgdGhlIHJlcXVlc3RlZCBhbmQgdmFsaWQgbG9jYWxlcy4KICAgICogQHBhcmFtIHJlcXVlc3RlZExvY2FsZSB0aGUgcmVxdXN0ZWQgbG9jYWxlCiAgICAqIEBwYXJhbSB2YWxpZExvY2FsZSB0aGUgdmFsaWQgbG9jYWxlCiAgICAqIEBpbnRlcm5hbAogICAgKi8KICAgIHZpcnR1YWwgdm9pZCBzZXRMb2NhbGVzKGNvbnN0IExvY2FsZSYgcmVxdWVzdGVkTG9jYWxlLCBjb25zdCBMb2NhbGUmIHZhbGlkTG9jYWxlKTsKCnB1YmxpYzoKI2lmICFVQ09ORklHX05PX1NFUlZJQ0UKICAgIC8qKgogICAgICogdXNlZCBvbmx5IGJ5IHVjb2xfb3Blbiwgbm90IGZvciBwdWJsaWMgdXNlCiAgICAgKiBAaW50ZXJuYWwKICAgICAqLwogICAgc3RhdGljIFVDb2xsYXRvciogY3JlYXRlVUNvbGxhdG9yKGNvbnN0IGNoYXIqIGxvYywgVUVycm9yQ29kZSogc3RhdHVzKTsKI2VuZGlmCnByaXZhdGU6CiAgICAvKioKICAgICAqIEFzc2lnbm1lbnQgb3BlcmF0b3IuIFByaXZhdGUgZm9yIG5vdy4KICAgICAqIEBpbnRlcm5hbAogICAgICovCiAgICBDb2xsYXRvciYgb3BlcmF0b3I9KGNvbnN0IENvbGxhdG9yJiBvdGhlcik7CgogICAgZnJpZW5kIGNsYXNzIENGYWN0b3J5OwogICAgZnJpZW5kIGNsYXNzIFNpbXBsZUNGYWN0b3J5OwogICAgZnJpZW5kIGNsYXNzIElDVUNvbGxhdG9yRmFjdG9yeTsKICAgIGZyaWVuZCBjbGFzcyBJQ1VDb2xsYXRvclNlcnZpY2U7CiAgICBzdGF0aWMgQ29sbGF0b3IqIG1ha2VJbnN0YW5jZShjb25zdCBMb2NhbGUmIGRlc2lyZWRMb2NhbGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiBzdGF0dXMpOwoKICAgIC8vIENvbGxhdG9yIHByaXZhdGUgZGF0YSBtZW1iZXJzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIC8qCiAgICBzeW53ZWUgOiByZW1vdmVkIGFzIGF0dHJpYnV0ZXMgdG8gYmUgaGFuZGxlZCBieSBjaGlsZCBjbGFzcwogICAgVUNvbGxhdGlvblN0cmVuZ3RoICBzdHJlbmd0aDsKICAgIE5vcm1hbGl6ZXI6OkVNb2RlICBkZWNtcDsKICAgICovCiAgICAvKiBUaGlzIGlzIHVzZWxlc3MgaW5mb3JtYXRpb24gKi8KLyogIHN0YXRpYyBjb25zdCBVVmVyc2lvbkluZm8gZlZlcnNpb247Ki8KfTsKCiNpZiAhVUNPTkZJR19OT19TRVJWSUNFCi8qKgogKiBBIGZhY3RvcnksIHVzZWQgd2l0aCByZWdpc3RlckZhY3RvcnksIHRoZSBjcmVhdGVzIG11bHRpcGxlIGNvbGxhdG9ycyBhbmQgcHJvdmlkZXMKICogZGlzcGxheSBuYW1lcyBmb3IgdGhlbS4gIEEgZmFjdG9yeSBzdXBwb3J0cyBzb21lIG51bWJlciBvZiBsb2NhbGVzLS0gdGhlc2UgYXJlIHRoZQogKiBsb2NhbGVzIGZvciB3aGljaCBpdCBjYW4gY3JlYXRlIGNvbGxhdG9ycy4gIFRoZSBmYWN0b3J5IGNhbiBiZSB2aXNpYmxlLCBpbiB3aGljaAogKiBjYXNlIHRoZSBzdXBwb3J0ZWQgbG9jYWxlcyB3aWxsIGJlIGVudW1lcmF0ZWQgYnkgZ2V0QXZhaWxhYmxlTG9jYWxlcywgb3IgaW52aXNpYmxlLAogKiBpbiB3aGljaCB0aGV5IGFyZSBub3QuICBJbnZpc2libGUgbG9jYWxlcyBhcmUgc3RpbGwgc3VwcG9ydGVkLCB0aGV5IGFyZSBqdXN0IG5vdAogKiBsaXN0ZWQgYnkgZ2V0QXZhaWxhYmxlTG9jYWxlcy4KICogPHA+CiAqIElmIHN0YW5kYXJkIGxvY2FsZSBkaXNwbGF5IG5hbWVzIGFyZSBzdWZmaWNpZW50LCBDb2xsYXRvciBpbnN0YW5jZXMgY2FuCiAqIGJlIHJlZ2lzdGVyZWQgdXNpbmcgcmVnaXN0ZXJJbnN0YW5jZSBpbnN0ZWFkLjwvcD4KICogPHA+CiAqIE5vdGU6IGlmIHRoZSBjb2xsYXRvcnMgYXJlIHRvIGJlIHVzZWQgZnJvbSBDIEFQSXMsIHRoZXkgbXVzdCBiZSBpbnN0YW5jZXMKICogb2YgUnVsZUJhc2VkQ29sbGF0b3IuPC9wPgogKgogKiBAc3RhYmxlIElDVSAyLjYKICovCmNsYXNzIFVfSTE4Tl9BUEkgQ29sbGF0b3JGYWN0b3J5IDogcHVibGljIFVPYmplY3QgewpwdWJsaWM6CgogICAgLyoqCiAgICAgKiBEZXN0cnVjdG9yCiAgICAgKiBAZHJhZnQgSUNVIDMuMAogICAgICovCiAgICB2aXJ0dWFsIH5Db2xsYXRvckZhY3RvcnkoKTsKCiAgICAvKioKICAgICAqIFJldHVybiB0cnVlIGlmIHRoaXMgZmFjdG9yeSBpcyB2aXNpYmxlLiAgRGVmYXVsdCBpcyB0cnVlLgogICAgICogSWYgbm90IHZpc2libGUsIHRoZSBsb2NhbGVzIHN1cHBvcnRlZCBieSB0aGlzIGZhY3Rvcnkgd2lsbCBub3QKICAgICAqIGJlIGxpc3RlZCBieSBnZXRBdmFpbGFibGVMb2NhbGVzLgogICAgICogQHJldHVybiB0cnVlIGlmIHRoZSBmYWN0b3J5IGlzIHZpc2libGUuCiAgICAgKiBAc3RhYmxlIElDVSAyLjYKICAgICAqLwogICAgdmlydHVhbCBVQm9vbCB2aXNpYmxlKHZvaWQpIGNvbnN0OwoKICAgIC8qKgogICAgICogUmV0dXJuIGEgY29sbGF0b3IgZm9yIHRoZSBwcm92aWRlZCBsb2NhbGUuICBJZiB0aGUgbG9jYWxlCiAgICAgKiBpcyBub3Qgc3VwcG9ydGVkLCByZXR1cm4gTlVMTC4KICAgICAqIEBwYXJhbSBsb2MgdGhlIGxvY2FsZSBpZGVudGlmeWluZyB0aGUgY29sbGF0b3IgdG8gYmUgY3JlYXRlZC4KICAgICAqIEByZXR1cm4gYSBuZXcgY29sbGF0b3IgaWYgdGhlIGxvY2FsZSBpcyBzdXBwb3J0ZWQsIG90aGVyd2lzZSBOVUxMLgogICAgICogQHN0YWJsZSBJQ1UgMi42CiAgICAgKi8KICAgIHZpcnR1YWwgQ29sbGF0b3IqIGNyZWF0ZUNvbGxhdG9yKGNvbnN0IExvY2FsZSYgbG9jKSA9IDA7CgogICAgLyoqCiAgICAgKiBSZXR1cm4gdGhlIG5hbWUgb2YgdGhlIGNvbGxhdG9yIGZvciB0aGUgb2JqZWN0TG9jYWxlLCBsb2NhbGl6ZWQgZm9yIHRoZSBkaXNwbGF5TG9jYWxlLgogICAgICogSWYgb2JqZWN0TG9jYWxlIGlzIG5vdCBzdXBwb3J0ZWQsIG9yIHRoZSBmYWN0b3J5IGlzIG5vdCB2aXNpYmxlLCBzZXQgdGhlIHJlc3VsdCBzdHJpbmcKICAgICAqIHRvIGJvZ3VzLgogICAgICogQHBhcmFtIG9iamVjdExvY2FsZSB0aGUgbG9jYWxlIGlkZW50aWZ5aW5nIHRoZSBjb2xsYXRvcgogICAgICogQHBhcmFtIGRpc3BsYXlMb2NhbGUgdGhlIGxvY2FsZSBmb3Igd2hpY2ggdGhlIGRpc3BsYXkgbmFtZSBvZiB0aGUgY29sbGF0b3Igc2hvdWxkIGJlIGxvY2FsaXplZAogICAgICogQHBhcmFtIHJlc3VsdCBhbiBvdXRwdXQgcGFyYW1ldGVyIGZvciB0aGUgZGlzcGxheSBuYW1lLCBzZXQgdG8gYm9ndXMgaWYgbm90IHN1cHBvcnRlZC4KICAgICAqIEByZXR1cm4gdGhlIGRpc3BsYXkgbmFtZQogICAgICogQHN0YWJsZSBJQ1UgMi42CiAgICAgKi8KICAgIHZpcnR1YWwgIFVuaWNvZGVTdHJpbmcmIGdldERpc3BsYXlOYW1lKGNvbnN0IExvY2FsZSYgb2JqZWN0TG9jYWxlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTG9jYWxlJiBkaXNwbGF5TG9jYWxlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVW5pY29kZVN0cmluZyYgcmVzdWx0KTsKCiAgICAvKioKICAgICAqIFJldHVybiBhbiBhcnJheSBvZiBhbGwgdGhlIGxvY2FsZSBuYW1lcyBkaXJlY3RseSBzdXBwb3J0ZWQgYnkgdGhpcyBmYWN0b3J5LgogICAgICogVGhlIG51bWJlciBvZiBuYW1lcyBpcyByZXR1cm5lZCBpbiBjb3VudC4gIFRoaXMgYXJyYXkgaXMgb3duZWQgYnkgdGhlIGZhY3RvcnkuCiAgICAgKiBJdHMgY29udGVudHMgbXVzdCBuZXZlciBjaGFuZ2UuCiAgICAgKiBAcGFyYW0gY291bnQgb3V0cHV0IHBhcmFtZXRlciBmb3IgdGhlIG51bWJlciBvZiBsb2NhbGVzIHN1cHBvcnRlZCBieSB0aGUgZmFjdG9yeQogICAgICogQHBhcmFtIHN0YXR1cyB0aGUgaW4vb3V0IGVycm9yIGNvZGUKICAgICAqIEByZXR1cm4gYSBwb2ludGVyIHRvIGFuIGFycmF5IG9mIGNvdW50IFVuaWNvZGVTdHJpbmdzLgogICAgICogQHN0YWJsZSBJQ1UgMi42CiAgICAgKi8KICAgIHZpcnR1YWwgY29uc3QgVW5pY29kZVN0cmluZyAqIGdldFN1cHBvcnRlZElEcyhpbnQzMl90ICZjb3VudCwgVUVycm9yQ29kZSYgc3RhdHVzKSA9IDA7Cn07CiNlbmRpZiAvKiBVQ09ORklHX05PX1NFUlZJQ0UgKi8KCi8vIENvbGxhdG9yIGlubGluZSBtZXRob2RzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpVX05BTUVTUEFDRV9FTkQKCiNlbmRpZiAvKiAjaWYgIVVDT05GSUdfTk9fQ09MTEFUSU9OICovCgojZW5kaWYK