LyoKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqICAgQ29weXJpZ2h0IChDKSAxOTk2LTE5OTksIEludGVybmF0aW9uYWwgQnVzaW5lc3MgTWFjaGluZXMKKiAgIENvcnBvcmF0aW9uIGFuZCBvdGhlcnMuICBBbGwgUmlnaHRzIFJlc2VydmVkLgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiovCi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLy8KLy8gRmlsZSBjb2xsLmgKLy8KLy8gCi8vCi8vIENyZWF0ZWQgYnk6IEhlbGVuYSBTaGloCi8vCi8vIE1vZGlmaWNhdGlvbiBIaXN0b3J5OgovLwovLyAgRGF0ZSAgICAgICAgTmFtZSAgICAgICAgRGVzY3JpcHRpb24KLy8gMDIvNS85NyAgICAgIGFsaXUgICAgICAgIE1vZGlmaWVkIGNyZWF0ZURlZmF1bHQgdG8gbG9hZCBjb2xsYXRpb24gZGF0YSBmcm9tCi8vICAgICAgICAgICAgICAgICAgICAgICAgICBiaW5hcnkgZmlsZXMgd2hlbiBwb3NzaWJsZS4gIEFkZGVkIHJlbGF0ZWQgbWV0aG9kcwovLyAgICAgICAgICAgICAgICAgICAgICAgICAgY3JlYXRlQ29sbGF0aW9uRnJvbUZpbGUsIGNob3BMb2NhbGUsIGNyZWF0ZVBhdGhOYW1lLgovLyAwMi8xMS85NyAgICAgYWxpdSAgICAgICAgQWRkZWQgbWVtYmVycyBhZGRUb0NhY2hlLCBmaW5kSW5DYWNoZSwgYW5kIGZnQ2FjaGUuCi8vIDAyLzEyLzk3ICAgICBhbGl1ICAgICAgICBNb2RpZmllZCB0byBjcmVhdGUgb2JqZWN0cyBmcm9tIFJ1bGVCYXNlZENvbGxhdG9yIGNhY2hlLgovLyAgICAgICAgICAgICAgICAgICAgICAgICAgTW92ZWQgY2FjaGUgb3V0IG9mIENvbGxhdGlvbiBjbGFzcy4KLy8gMDIvMTMvOTcgICAgIGFsaXUgICAgICAgIE1vdmVkIHNldmVyYWwgbWV0aG9kcyBvdXQgb2YgdGhpcyBjbGFzcyBhbmQgaW50bwovLyAgICAgICAgICAgICAgICAgICAgICAgICAgUnVsZUJhc2VkQ29sbGF0b3IsIHdpdGggbW9kaWZpY2F0aW9ucy4gIE1vZGlmaWVkCi8vICAgICAgICAgICAgICAgICAgICAgICAgICBjcmVhdGVEZWZhdWx0KCkgdG8gY2FsbCBuZXcgUnVsZUJhc2VkQ29sbGF0b3IoTG9jYWxlJikKLy8gICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0cnVjdG9yLiAgR2VuZXJhbCBjbGVhbiB1cCBhbmQgZG9jdW1lbnRhdGlvbi4KLy8gMDIvMjAvOTcgICAgIGhlbGVuYSAgICAgIEFkZGVkIGNsb25lLCBvcGVyYXRvcj09LCBvcGVyYXRvciE9LCBvcGVyYXRvcj0sIGNvcHkKLy8gICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0cnVjdG9yIGFuZCBnZXREeW5hbWljQ2xhc3NJRC4KLy8gMDMvMjUvOTcgICAgIGhlbGVuYSAgICAgIFVwZGF0ZWQgd2l0aCBwbGF0Zm9ybSBpbmRlcGVuZGVudCBkYXRhIHR5cGVzLgovLyAwNS8wNi85NyAgICAgaGVsZW5hICAgICAgQWRkZWQgbWVtb3J5IGFsbG9jYXRpb24gZXJyb3IgZGV0ZWN0aW9uLgovLyAgNi8yMC85NyAgICAgaGVsZW5hICAgICAgSmF2YSBjbGFzcyBuYW1lIGNoYW5nZS4KLy8gMDkvMDMvOTcgICAgIGhlbGVuYSAgICAgIEFkZGVkIGNyZWF0ZUNvbGxhdGlvbktleVZhbHVlcygpLgovLyAwMi8xMC85OCAgICAgZGFtaWJhICAgICAgQWRkZWQgY29tcGFyZSgpIHdpdGggbGVuZ3RoIGFzIHBhcmFtZXRlci4KLy8gMDQvMjMvOTkgICAgIHN0ZXBoZW4gICAgIFJlbW92ZWQgRURlY29tcG9zaXRpb25Nb2RlLCBtZXJnZWQgd2l0aAovLyAgICAgICAgICAgICAgICAgICAgICAgICAgTm9ybWFsaXplcjo6RU1vZGUuCi8vIDExLzAyLzk5ICAgICBoZWxlbmEgICAgICBDb2xsYXRvciBwZXJmb3JtYW5jZSBlbmhhbmNlbWVudHMuICBFbGltaW5hdGVzIHRoZSAKLy8gICAgICAgICAgICAgICAgICAgICAgICAgIFVuaWNvZGVTdHJpbmcgY29uc3RydWN0aW9uIGFuZCBzcGVjaWFsIGNhc2UgZm9yIE5PX09QLgovLyAxMS8yMy85OSAgICAgc3JsICAgICAgICAgTW9yZSBwZXJmb3JtYW5jZSBlbmhhbmNlbWVudHMuIElubGluaW5nIG9mCi8vICAgICAgICAgICAgICAgICAgICAgICAgICBjcml0aWNhbCBhY2Nlc3NvcnMuCi8vIDA1LzE1LzAwICAgICBoZWxlbmEgICAgICBBZGRlZCB2ZXJzaW9uIGluZm9ybWF0aW9uIEFQSS4gCi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCiNpZm5kZWYgQ09MTF9ICiNkZWZpbmUgQ09MTF9ICgoKI2luY2x1ZGUgInVuaWNvZGUvdWNvbC5oIgojaW5jbHVkZSAidW5pY29kZS9sb2NpZC5oIgojaW5jbHVkZSAidW5pY29kZS91dHlwZXMuaCIKI2luY2x1ZGUgInVuaWNvZGUvdW5pc3RyLmgiCiNpbmNsdWRlICJ1bmljb2RlL25vcm1senIuaCIKI2luY2x1ZGUgInVuaWNvZGUvY2hhcml0ZXIuaCIKCmNsYXNzIENvbGxhdGlvbktleTsKCi8qKgogKiBUaGUgPGNvZGU+Q29sbGF0b3I8L2NvZGU+IGNsYXNzIHBlcmZvcm1zIGxvY2FsZS1zZW5zaXRpdmUKICogPGNvZGU+U3RyaW5nPC9jb2RlPiBjb21wYXJpc29uLiBZb3UgdXNlIHRoaXMgY2xhc3MgdG8gYnVpbGQKICogc2VhcmNoaW5nIGFuZCBzb3J0aW5nIHJvdXRpbmVzIGZvciBuYXR1cmFsIGxhbmd1YWdlIHRleHQuCiAqCiAqIDxwPgogKiA8Y29kZT5Db2xsYXRvcjwvY29kZT4gaXMgYW4gYWJzdHJhY3QgYmFzZSBjbGFzcy4gU3ViY2xhc3NlcwogKiBpbXBsZW1lbnQgc3BlY2lmaWMgY29sbGF0aW9uIHN0cmF0ZWdpZXMuIE9uZSBzdWJjbGFzcywKICogPGNvZGU+UnVsZUJhc2VkQ29sbGF0b3I8L2NvZGU+LCBpcyBjdXJyZW50bHkgcHJvdmlkZWQKICogYW5kIGlzIGFwcGxpY2FibGUgdG8gYSB3aWRlIHNldCBvZiBsYW5ndWFnZXMuIE90aGVyCiAqIHN1YmNsYXNzZXMgbWF5IGJlIGNyZWF0ZWQgdG8gaGFuZGxlIG1vcmUgc3BlY2lhbGl6ZWQgbmVlZHMuCiAqCiAqIDxwPgogKiBMaWtlIG90aGVyIGxvY2FsZS1zZW5zaXRpdmUgY2xhc3NlcywgeW91IGNhbiB1c2UgdGhlIHN0YXRpYwogKiBmYWN0b3J5IG1ldGhvZCwgPGNvZGU+Z2V0SW5zdGFuY2U8L2NvZGU+LCB0byBvYnRhaW4gdGhlIGFwcHJvcHJpYXRlCiAqIDxjb2RlPkNvbGxhdG9yPC9jb2RlPiBvYmplY3QgZm9yIGEgZ2l2ZW4gbG9jYWxlLiBZb3Ugd2lsbCBvbmx5IG5lZWQKICogdG8gbG9vayBhdCB0aGUgc3ViY2xhc3NlcyBvZiA8Y29kZT5Db2xsYXRvcjwvY29kZT4gaWYgeW91IG5lZWQKICogdG8gdW5kZXJzdGFuZCB0aGUgZGV0YWlscyBvZiBhIHBhcnRpY3VsYXIgY29sbGF0aW9uIHN0cmF0ZWd5IG9yCiAqIGlmIHlvdSBuZWVkIHRvIG1vZGlmeSB0aGF0IHN0cmF0ZWd5LgogKgogKiA8cD4KICogVGhlIGZvbGxvd2luZyBleGFtcGxlIHNob3dzIGhvdyB0byBjb21wYXJlIHR3byBzdHJpbmdzIHVzaW5nCiAqIHRoZSA8Y29kZT5Db2xsYXRvcjwvY29kZT4gZm9yIHRoZSBkZWZhdWx0IGxvY2FsZS4KICogPGJsb2NrcXVvdGU+CiAqIDxwcmU+CiAqIFxjb2RlCiAqIC8vIENvbXBhcmUgdHdvIHN0cmluZ3MgaW4gdGhlIGRlZmF1bHQgbG9jYWxlCiAqIFVFcnJvckNvZGUgc3VjY2VzcyA9IFVfWkVST19FUlJPUjsKICogQ29sbGF0b3IqIG15Q29sbGF0b3IgPSBDb2xsYXRvcjo6Y3JlYXRlSW5zdGFuY2Uoc3VjY2Vzcyk7CiAqIGlmKCBteUNvbGxhdG9yLT5jb21wYXJlKCJhYmMiLCAiQUJDIikgJmx0OyAwICkgewogKiAgICAgY291dCAmbHQ7Jmx0OyAiYWJjIGlzIGxlc3MgdGhhbiBBQkMiICZsdDsmbHQ7IGVuZGw7CiAqIH1lbHNlewogKiAgICAgY291dCAmbHQ7Jmx0OyAiYWJjIGlzIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byBBQkMiICZsdDsmbHQ7IGVuZGw7CiAqIH0KICogXGVuZGNvZGUKICogPC9wcmU+CiAqIDwvYmxvY2txdW90ZT4KICoKICogPHA+CiAqIFlvdSBjYW4gc2V0IGEgPGNvZGU+Q29sbGF0b3I8L2NvZGU+J3MgPGVtPnN0cmVuZ3RoPC9lbT4gcHJvcGVydHkKICogdG8gZGV0ZXJtaW5lIHRoZSBsZXZlbCBvZiBkaWZmZXJlbmNlIGNvbnNpZGVyZWQgc2lnbmlmaWNhbnQgaW4KICogY29tcGFyaXNvbnMuIEZvdXIgc3RyZW5ndGhzIGFyZSBwcm92aWRlZDogPGNvZGU+UFJJTUFSWTwvY29kZT4sCiAqIDxjb2RlPlNFQ09OREFSWTwvY29kZT4sIDxjb2RlPlRFUlRJQVJZPC9jb2RlPiwgYW5kIDxjb2RlPklERU5USUNBTDwvY29kZT4uCiAqIFRoZSBleGFjdCBhc3NpZ25tZW50IG9mIHN0cmVuZ3RocyB0byBsYW5ndWFnZSBmZWF0dXJlcyBpcwogKiBsb2NhbGUgZGVwZW5kYW50LiAgRm9yIGV4YW1wbGUsIGluIEN6ZWNoLCAiZSIgYW5kICJmIiBhcmUgY29uc2lkZXJlZAogKiBwcmltYXJ5IGRpZmZlcmVuY2VzLCB3aGlsZSAiZSIgYW5kICJcdTAwRUEiIGFyZSBzZWNvbmRhcnkgZGlmZmVyZW5jZXMsCiAqICJlIiBhbmQgIkUiIGFyZSB0ZXJ0aWFyeSBkaWZmZXJlbmNlcyBhbmQgImUiIGFuZCAiZSIgYXJlIGlkZW50aWNhbC4KICogVGhlIGZvbGxvd2luZyBzaG93cyBob3cgYm90aCBjYXNlIGFuZCBhY2NlbnRzIGNvdWxkIGJlIGlnbm9yZWQgZm9yCiAqIFVTIEVuZ2xpc2guCiAqIDxibG9ja3F1b3RlPgogKiA8cHJlPgogKiBcY29kZQogKiAvL0dldCB0aGUgQ29sbGF0b3IgZm9yIFVTIEVuZ2xpc2ggYW5kIHNldCBpdHMgc3RyZW5ndGggdG8gUFJJTUFSWQogKiBVRXJyb3JDb2RlIHN1Y2Nlc3MgPSBVX1pFUk9fRVJST1I7CiAqIENvbGxhdG9yKiB1c0NvbGxhdG9yID0gQ29sbGF0b3I6OmNyZWF0ZUluc3RhbmNlKExvY2FsZTo6VVMsIHN1Y2Nlc3MpOwogKiB1c0NvbGxhdG9yLT5zZXRTdHJlbmd0aChDb2xsYXRvcjo6UFJJTUFSWSk7CiAqIGlmKCB1c0NvbGxhdG9yLT5jb21wYXJlKCJhYmMiLCAiQUJDIikgPT0gMCApIHsKICogICAgIGNvdXQgJmx0OyZsdDsgIidhYmMnIGFuZCAnQUJDJyBzdHJpbmdzIGFyZSBlcXVpdmFsZW50IHdpdGggc3RyZW5ndGggUFJJTUFSWSIgJmx0OyZsdDsgZW5kbDsKICogfQogKiBcZW5kY29kZQogKiA8L3ByZT4KICogPC9ibG9ja3F1b3RlPgogKiA8cD4KICogRm9yIGNvbXBhcmluZyA8Y29kZT5TdHJpbmc8L2NvZGU+cyBleGFjdGx5IG9uY2UsIHRoZSA8Y29kZT5jb21wYXJlPC9jb2RlPgogKiBtZXRob2QgcHJvdmlkZXMgdGhlIGJlc3QgcGVyZm9ybWFuY2UuIFdoZW4gc29ydGluZyBhIGxpc3Qgb2YKICogPGNvZGU+U3RyaW5nPC9jb2RlPnMgaG93ZXZlciwgaXQgaXMgZ2VuZXJhbGx5IG5lY2Vzc2FyeSB0byBjb21wYXJlIGVhY2gKICogPGNvZGU+U3RyaW5nPC9jb2RlPiBtdWx0aXBsZSB0aW1lcy4gSW4gdGhpcyBjYXNlLCA8Y29kZT5Db2xsYXRpb25LZXk8L2NvZGU+cwogKiBwcm92aWRlIGJldHRlciBwZXJmb3JtYW5jZS4gVGhlIDxjb2RlPkNvbGxhdGlvbktleTwvY29kZT4gY2xhc3MgY29udmVydHMKICogYSA8Y29kZT5TdHJpbmc8L2NvZGU+IHRvIGEgc2VyaWVzIG9mIGJpdHMgdGhhdCBjYW4gYmUgY29tcGFyZWQgYml0d2lzZQogKiBhZ2FpbnN0IG90aGVyIDxjb2RlPkNvbGxhdGlvbktleTwvY29kZT5zLiBBIDxjb2RlPkNvbGxhdGlvbktleTwvY29kZT4gaXMKICogY3JlYXRlZCBieSBhIDxjb2RlPkNvbGxhdG9yPC9jb2RlPiBvYmplY3QgZm9yIGEgZ2l2ZW4gPGNvZGU+U3RyaW5nPC9jb2RlPi4KICogPHA+CiAqIDxzdHJvbmc+Tm90ZTo8L3N0cm9uZz4gPGNvZGU+Q29sbGF0b3I8L2NvZGU+cyB3aXRoIGRpZmZlcmVudCBMb2NhbGUsCiAqIENvbGxhdGlvblN0cmVuZ3RoIGFuZCBEZWNvbXBvc2l0aW9uTW9kZSBzZXR0aW5ncyB3aWxsIHJldHVybiBkaWZmZXJlbnQKICogc29ydCBvcmRlcnMgZm9yIHRoZSBzYW1lIHNldCBvZiBzdHJpbmdzLiBMb2NhbGVzIGhhdmUgc3BlY2lmaWMgCiAqIGNvbGxhdGlvbiBydWxlcywgYW5kIHRoZSB3YXkgaW4gd2hpY2ggc2Vjb25kYXJ5IGFuZCB0ZXJ0aWFyeSBkaWZmZXJlbmNlcyAKICogYXJlIHRha2VuIGludG8gYWNjb3VudCwgZm9yIGV4YW1wbGUsIHdpbGwgcmVzdWx0IGluIGEgZGlmZmVyZW50IHNvcnRpbmcgb3JkZXIKICogZm9yIHNhbWUgc3RyaW5ncy4KICogPHA+CiAqIAogKiBAc2VlICAgICAgICAgUnVsZUJhc2VkQ29sbGF0b3IKICogQHNlZSAgICAgICAgIENvbGxhdGlvbktleQogKiBAc2VlICAgICAgICAgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yCiAqIEBzZWUgICAgICAgICBMb2NhbGUKICogQHNlZSAgICAgICAgIE5vcm1hbGl6ZXIKICogQHZlcnNpb24gICAgIDEuNyAxLzE0Lzk3CiAqIEBhdXRob3IgICAgICBIZWxlbmEgU2hpaAogKi8KCmNsYXNzIFVfSTE4Tl9BUEkgQ29sbGF0b3IgewpwdWJsaWM6CiAgLyoqCiAgICogQmFzZSBsZXR0ZXIgcmVwcmVzZW50cyBhIHByaW1hcnkgZGlmZmVyZW5jZS4gIFNldCBjb21wYXJpc29uCiAgICogbGV2ZWwgdG8gUFJJTUFSWSB0byBpZ25vcmUgc2Vjb25kYXJ5IGFuZCB0ZXJ0aWFyeSBkaWZmZXJlbmNlcy4KICAgKiBVc2UgdGhpcyB0byBzZXQgdGhlIHN0cmVuZ3RoIG9mIGEgQ29sbGF0b3Igb2JqZWN0LgogICAqIEV4YW1wbGUgb2YgcHJpbWFyeSBkaWZmZXJlbmNlLCAiYWJjIiAmbHQ7ICJhYmQiCiAgICogCiAgICogRGlhY3JpdGljYWwgZGlmZmVyZW5jZXMgb24gdGhlIHNhbWUgYmFzZSBsZXR0ZXIgcmVwcmVzZW50IGEgc2Vjb25kYXJ5CiAgICogZGlmZmVyZW5jZS4gIFNldCBjb21wYXJpc29uIGxldmVsIHRvIFNFQ09OREFSWSB0byBpZ25vcmUgdGVydGlhcnkKICAgKiBkaWZmZXJlbmNlcy4gVXNlIHRoaXMgdG8gc2V0IHRoZSBzdHJlbmd0aCBvZiBhIENvbGxhdG9yIG9iamVjdC4KICAgKiBFeGFtcGxlIG9mIHNlY29uZGFyeSBkaWZmZXJlbmNlLCAi5CIgPj4gImEiLgogICAqCiAgICogVXBwZXJjYXNlIGFuZCBsb3dlcmNhc2UgdmVyc2lvbnMgb2YgdGhlIHNhbWUgY2hhcmFjdGVyIHJlcHJlc2VudHMgYQogICAqIHRlcnRpYXJ5IGRpZmZlcmVuY2UuICBTZXQgY29tcGFyaXNvbiBsZXZlbCB0byBURVJUSUFSWSB0byBpbmNsdWRlCiAgICogYWxsIGNvbXBhcmlzb24gZGlmZmVyZW5jZXMuIFVzZSB0aGlzIHRvIHNldCB0aGUgc3RyZW5ndGggb2YgYSBDb2xsYXRvcgogICAqIG9iamVjdC4KICAgKiBFeGFtcGxlIG9mIHRlcnRpYXJ5IGRpZmZlcmVuY2UsICJhYmMiICZsdDsmbHQ7Jmx0OyAiQUJDIi4KICAgKgogICAqIFR3byBjaGFyYWN0ZXJzIGFyZSBjb25zaWRlcmVkICJpZGVudGljYWwiIHdoZW4gdGhleSBoYXZlIHRoZSBzYW1lCiAgICogdW5pY29kZSBzcGVsbGluZ3MuCiAgICogRm9yIGV4YW1wbGUsICLkIiA9PSAi5CIuCiAgICoKICAgKiBFQ29sbGF0aW9uU3RyZW5ndGggaXMgYWxzbyB1c2VkIHRvIGRldGVybWluZSB0aGUgc3RyZW5ndGggb2Ygc29ydCBrZXlzIAogICAqIGdlbmVyYXRlZCBmcm9tIENvbGxhdG9yIG9iamVjdHMuCiAgICovCiAgZW51bSBFQ29sbGF0aW9uU3RyZW5ndGggewogICAgUFJJTUFSWSA9IDAsCiAgICBTRUNPTkRBUlkgPSAxLCAKICAgIFRFUlRJQVJZID0gMiwKICAgIElERU5USUNBTCA9IDMKICB9OwoKICAvKioKICAgKiBMRVNTIGlzIHJldHVybmVkIGlmIHNvdXJjZSBzdHJpbmcgaXMgY29tcGFyZWQgdG8gYmUgbGVzcyB0aGFuIHRhcmdldAogICAqIHN0cmluZyBpbiB0aGUgY29tcGFyZSgpIG1ldGhvZC4KICAgKiBFUVVBTCBpcyByZXR1cm5lZCBpZiBzb3VyY2Ugc3RyaW5nIGlzIGNvbXBhcmVkIHRvIGJlIGVxdWFsIHRvIHRhcmdldAogICAqIHN0cmluZyBpbiB0aGUgY29tcGFyZSgpIG1ldGhvZC4KICAgKiBHUkVBVEVSIGlzIHJldHVybmVkIGlmIHNvdXJjZSBzdHJpbmcgaXMgY29tcGFyZWQgdG8gYmUgZ3JlYXRlciB0aGFuCiAgICogdGFyZ2V0IHN0cmluZyBpbiB0aGUgY29tcGFyZSgpIG1ldGhvZC4KICAgKiBAc2VlIENvbGxhdG9yI2NvbXBhcmUKICAgKi8KICBlbnVtIEVDb21wYXJpc29uUmVzdWx0IHsKICAgIExFU1MgPSAtMSwKICAgIEVRVUFMID0gMCwKICAgIEdSRUFURVIgPSAxCiAgfTsKICAKICAvKioKICAgKiBEZXN0cnVjdG9yCiAgICogQHN0YWJsZQogICAqLwogIHZpcnR1YWwgICAgICAgICAgICAgICAgICAgICAgICAgfkNvbGxhdG9yKCk7CgogIC8qKgogICAqIFJldHVybnMgdHJ1ZSBpZiAib3RoZXIiIGlzIHRoZSBzYW1lIGFzICJ0aGlzIgogICAqIEBzdGFibGUKICAgKi8KICB2aXJ0dWFsICAgICBVQm9vbCAgICAgICAgICAgICAgb3BlcmF0b3I9PShjb25zdCBDb2xsYXRvciYgb3RoZXIpIGNvbnN0OwoKICAvKioKICAgKiBSZXR1cm5zIHRydWUgaWYgIm90aGVyIiBpcyBub3QgdGhlIHNhbWUgYXMgInRoaXMiLgogICAqIEBzdGFibGUKICAgKi8KICB2aXJ0dWFsICAgICBVQm9vbCAgICAgICAgICAgICAgb3BlcmF0b3IhPShjb25zdCBDb2xsYXRvciYgb3RoZXIpIGNvbnN0OwoKICAvKioKICAgKiBNYWtlcyBhIHNoYWxsb3cgY29weSBvZiB0aGUgY3VycmVudCBvYmplY3QuCiAgICogQHN0YWJsZQogICAqLwogIHZpcnR1YWwgICAgIENvbGxhdG9yKiAgICAgICAgICAgY2xvbmUodm9pZCkgY29uc3QgPSAwOwogIC8qKgogICAqIENyZWF0ZXMgdGhlIGNvbGxhdG9yIG9iamVjdCBmb3IgdGhlIGN1cnJlbnQgZGVmYXVsdCBsb2NhbGUuCiAgICogVGhlIGRlZmF1bHQgbG9jYWxlIGlzIGRldGVybWluZWQgYnkgTG9jYWxlOjpnZXREZWZhdWx0LgogICAqIEByZXR1cm4gdGhlIGNvbGxhdGlvbiBvYmplY3Qgb2YgdGhlIGRlZmF1bHQgbG9jYWxlLihmb3IgZXhhbXBsZSwgZW5fVVMpCiAgICogQHNlZSBMb2NhbGUjZ2V0RGVmYXVsdAogICAqIFRoZSBVRXJyb3JDb2RlJiBlcnIgcGFyYW1ldGVyIGlzIHVzZWQgdG8gcmV0dXJuIHN0YXR1cyBpbmZvcm1hdGlvbiB0byB0aGUgdXNlci4KICAgKiBUbyBjaGVjayB3aGV0aGVyIHRoZSBjb25zdHJ1Y3Rpb24gc3VjY2VlZGVkIG9yIG5vdCwgeW91IHNob3VsZCBjaGVjawogICAqIHRoZSB2YWx1ZSBvZiBVX1NVQ0NFU1MoZXJyKS4gIElmIHlvdSB3aXNoIG1vcmUgZGV0YWlsZWQgaW5mb3JtYXRpb24sIHlvdQogICAqIGNhbiBjaGVjayBmb3IgaW5mb3JtYXRpb25hbCBlcnJvciByZXN1bHRzIHdoaWNoIHN0aWxsIGluZGljYXRlIHN1Y2Nlc3MuCiAgICogVV9VU0lOR19GQUxMQkFDS19FUlJPUiBpbmRpY2F0ZXMgdGhhdCBhIGZhbGwgYmFjayBsb2NhbGUgd2FzIHVzZWQuICBGb3IKICAgKiBleGFtcGxlLCAnZGVfQ0gnIHdhcyByZXF1ZXN0ZWQsIGJ1dCBub3RoaW5nIHdhcyBmb3VuZCB0aGVyZSwgc28gJ2RlJyB3YXMKICAgKiB1c2VkLiAgVV9VU0lOR19ERUZBVUxUX0VSUk9SIGluZGljYXRlcyB0aGF0IHRoZSBkZWZhdWx0IGxvY2FsZSBkYXRhIHdhcwogICAqIHVzZWQ7IG5laXRoZXIgdGhlIHJlcXVlc3RlZCBsb2NhbGUgbm9yIGFueSBvZiBpdHMgZmFsbCBiYWNrIGxvY2FsZXMKICAgKiBjb3VsZCBiZSBmb3VuZC4KICAgKiBUaGUgY2FsbGVyIG93bnMgdGhlIHJldHVybmVkIG9iamVjdCBhbmQgaXMgcmVzcG9uc2libGUgZm9yIGRlbGV0aW5nIGl0LgogICAqIEBzdGFibGUKICAgKi8KICBzdGF0aWMgIENvbGxhdG9yKiAgICAgICAgICAgY3JlYXRlSW5zdGFuY2UoIFVFcnJvckNvZGUmICBlcnIpOwoKICAvKioKICAgKiBHZXRzIHRoZSB0YWJsZS1iYXNlZCBjb2xsYXRpb24gb2JqZWN0IGZvciB0aGUgZGVzaXJlZCBsb2NhbGUuICBUaGUKICAgKiByZXNvdXJjZSBvZiB0aGUgZGVzaXJlZCBsb2NhbGUgd2lsbCBiZSBsb2FkZWQgYnkgUmVzb3VyY2VMb2FkZXIuIAogICAqIExvY2FsZTo6RU5HTElTSCBpcyB0aGUgYmFzZSBjb2xsYXRpb24gdGFibGUgYW5kIGFsbCBvdGhlciBsYW5ndWFnZXMgYXJlIAogICAqIGJ1aWx0IG9uIHRvcCBvZiBpdCB3aXRoIGFkZGl0aW9uYWwgbGFuZ3VhZ2Utc3BlY2lmaWMgbW9kaWZpY2F0aW9ucy4KICAgKiBAcGFyYW0gZGVzaXJlZExvY2FsZSB0aGUgZGVzaXJlZCBsb2NhbGUgdG8gY3JlYXRlIHRoZSBjb2xsYXRpb24gdGFibGUKICAgKiB3aXRoLgogICAqIEByZXR1cm4gdGhlIGNyZWF0ZWQgdGFibGUtYmFzZWQgY29sbGF0aW9uIG9iamVjdCBiYXNlZCBvbiB0aGUgZGVzaXJlZAogICAqIGxvY2FsZS4KICAgKiBAc2VlIExvY2FsZQogICAqIEBzZWUgUmVzb3VyY2VMb2FkZXIKICAgKiBUaGUgVUVycm9yQ29kZSYgZXJyIHBhcmFtZXRlciBpcyB1c2VkIHRvIHJldHVybiBzdGF0dXMgaW5mb3JtYXRpb24gdG8gdGhlIHVzZXIuCiAgICogVG8gY2hlY2sgd2hldGhlciB0aGUgY29uc3RydWN0aW9uIHN1Y2NlZWRlZCBvciBub3QsIHlvdSBzaG91bGQgY2hlY2sKICAgKiB0aGUgdmFsdWUgb2YgVV9TVUNDRVNTKGVycikuICBJZiB5b3Ugd2lzaCBtb3JlIGRldGFpbGVkIGluZm9ybWF0aW9uLCB5b3UKICAgKiBjYW4gY2hlY2sgZm9yIGluZm9ybWF0aW9uYWwgZXJyb3IgcmVzdWx0cyB3aGljaCBzdGlsbCBpbmRpY2F0ZSBzdWNjZXNzLgogICAqIFVfVVNJTkdfRkFMTEJBQ0tfRVJST1IgaW5kaWNhdGVzIHRoYXQgYSBmYWxsIGJhY2sgbG9jYWxlIHdhcyB1c2VkLiAgRm9yCiAgICogZXhhbXBsZSwgJ2RlX0NIJyB3YXMgcmVxdWVzdGVkLCBidXQgbm90aGluZyB3YXMgZm91bmQgdGhlcmUsIHNvICdkZScgd2FzCiAgICogdXNlZC4gIFVfVVNJTkdfREVGQVVMVF9FUlJPUiBpbmRpY2F0ZXMgdGhhdCB0aGUgZGVmYXVsdCBsb2NhbGUgZGF0YSB3YXMKICAgKiB1c2VkOyBuZWl0aGVyIHRoZSByZXF1ZXN0ZWQgbG9jYWxlIG5vciBhbnkgb2YgaXRzIGZhbGwgYmFjayBsb2NhbGVzCiAgICogY291bGQgYmUgZm91bmQuCiAgICogVGhlIGNhbGxlciBvd25zIHRoZSByZXR1cm5lZCBvYmplY3QgYW5kIGlzIHJlc3BvbnNpYmxlIGZvciBkZWxldGluZyBpdC4KICAgKiBAc3RhYmxlCiAgICovCiAgc3RhdGljICBDb2xsYXRvciogICAgICAgICAgIGNyZWF0ZUluc3RhbmNlKCBjb25zdCBMb2NhbGUmICAgbG9jLAogICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmICAgICAgZXJyKTsKCiAgLy8gY29tcGFyaXNvbgogIC8qKgogICAqIFRoZSBjb21wYXJpc29uIGZ1bmN0aW9uIGNvbXBhcmVzIHRoZSBjaGFyYWN0ZXIgZGF0YSBzdG9yZWQgaW4gdHdvCiAgICogZGlmZmVyZW50IHN0cmluZ3MuICBSZXR1cm5zIGluZm9ybWF0aW9uIGFib3V0IHdoZXRoZXIgYSBzdHJpbmcKICAgKiBpcyBsZXNzIHRoYW4sIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byBhbm90aGVyIHN0cmluZy4KICAgKiA8cD5FeGFtcGxlIG9mIHVzZToKICAgKiA8cHJlPgogICAqIC4gICAgICAgVUVycm9yQ29kZSBzdGF0dXMgPSBVX1pFUk9fRVJST1I7CiAgICogLiAgICAgICBDb2xsYXRvciAqbXlDb2xsYXRpb24gPSBDb2xsYXRvcjo6Y3JlYXRlSW5zdGFuY2UoTG9jYWxlOjpVUywgc3RhdHVzKTsKICAgKiAuICAgICAgIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkgcmV0dXJuOwogICAqIC4gICAgICAgbXlDb2xsYXRpb24tPnNldFN0cmVuZ3RoKENvbGxhdG9yOjpQUklNQVJZKTsKICAgKiAuICAgICAgIC8vIHJlc3VsdCB3b3VsZCBiZSBDb2xsYXRvcjo6RVFVQUwgKCJhYmMiID09ICJBQkMiKQogICAqIC4gICAgICAgLy8gKG5vIHByaW1hcnkgZGlmZmVyZW5jZSBiZXR3ZWVuICJhYmMiIGFuZCAiQUJDIikKICAgKiAuICAgICAgIENvbGxhdG9yOjpFQ29tcGFyaXNvblJlc3VsdCByZXN1bHQgPSBteUNvbGxhdGlvbi0+Y29tcGFyZSgiYWJjIiwgIkFCQyIpOwogICAqIC4gICAgICAgbXlDb2xsYXRpb24tPnNldFN0cmVuZ3RoKENvbGxhdG9yOjpURVJUSUFSWSk7CiAgICogLiAgICAgICAvLyByZXN1bHQgd291bGQgYmUgQ29sbGF0b3I6OkxFU1MgKGFiYyIgJmx0OyZsdDsmbHQ7ICJBQkMiKQogICAqIC4gICAgICAgLy8gKHdpdGggdGVydGlhcnkgZGlmZmVyZW5jZSBiZXR3ZWVuICJhYmMiIGFuZCAiQUJDIikKICAgKiAuICAgICAgIENvbGxhdG9yOjpFQ29tcGFyaXNvblJlc3VsdCByZXN1bHQgPSBteUNvbGxhdGlvbi0+Y29tcGFyZSgiYWJjIiwgIkFCQyIpOwogICAqIDwvcHJlPgogICAqIEBwYXJhbSBzb3VyY2UgdGhlIHNvdXJjZSBzdHJpbmcgdG8gYmUgY29tcGFyZWQgd2l0aC4KICAgKiBAcGFyYW0gdGFyZ2V0IHRoZSBzdHJpbmcgdGhhdCBpcyB0byBiZSBjb21wYXJlZCB3aXRoIHRoZSBzb3VyY2Ugc3RyaW5nLgogICAqIEByZXR1cm4gUmV0dXJucyBhIGJ5dGUgdmFsdWUuIEdSRUFURVIgaWYgc291cmNlIGlzIGdyZWF0ZXIKICAgKiB0aGFuIHRhcmdldDsgRVFVQUwgaWYgc291cmNlIGlzIGVxdWFsIHRvIHRhcmdldDsgTEVTUyBpZiBzb3VyY2UgaXMgbGVzcwogICAqIHRoYW4gdGFyZ2V0CiAgICogQHN0YWJsZQogICAqKi8KICB2aXJ0dWFsIEVDb21wYXJpc29uUmVzdWx0ICAgY29tcGFyZSggICAgY29uc3QgICBVbmljb2RlU3RyaW5nJiAgc291cmNlLCAKICAgICAgICAgICAgICAgICAgICAgIGNvbnN0ICAgVW5pY29kZVN0cmluZyYgIHRhcmdldCkgY29uc3QgPSAwOwoKICAvKioKICAgKiBEb2VzIHRoZSBzYW1lIHRoaW5nIGFzIGNvbXBhcmUgYnV0IGxpbWl0cyB0aGUgY29tcGFyaXNvbiB0byBhIHNwZWNpZmllZCBsZW5ndGgKICAgKiA8cD5FeGFtcGxlIG9mIHVzZToKICAgKiA8cHJlPgogICAqIC4gICAgICAgVUVycm9yQ29kZSBzdGF0dXMgPSBVX1pFUk9fRVJST1I7CiAgICogLiAgICAgICBDb2xsYXRvciAqbXlDb2xsYXRpb24gPSBDb2xsYXRvcjo6Y3JlYXRlSW5zdGFuY2UoTG9jYWxlOjpVUywgc3RhdHVzKTsKICAgKiAuICAgICAgIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkgcmV0dXJuOwogICAqIC4gICAgICAgbXlDb2xsYXRpb24tPnNldFN0cmVuZ3RoKENvbGxhdG9yOjpQUklNQVJZKTsKICAgKiAuICAgICAgIC8vIHJlc3VsdCB3b3VsZCBiZSBDb2xsYXRvcjo6RVFVQUwgKCJhYmMiID09ICJBQkMiKQogICAqIC4gICAgICAgLy8gKG5vIHByaW1hcnkgZGlmZmVyZW5jZSBiZXR3ZWVuICJhYmMiIGFuZCAiQUJDIikKICAgKiAuICAgICAgIENvbGxhdG9yOjpFQ29tcGFyaXNvblJlc3VsdCByZXN1bHQgPSBteUNvbGxhdGlvbi0+Y29tcGFyZSgiYWJjIiwgIkFCQyIsMyk7CiAgICogLiAgICAgICBteUNvbGxhdGlvbi0+c2V0U3RyZW5ndGgoQ29sbGF0b3I6OlRFUlRJQVJZKTsKICAgKiAuICAgICAgIC8vIHJlc3VsdCB3b3VsZCBiZSBDb2xsYXRvcjo6TEVTUyAoYWJjIiAmbHQ7Jmx0OyZsdDsgIkFCQyIpCiAgICogLiAgICAgICAvLyAod2l0aCB0ZXJ0aWFyeSBkaWZmZXJlbmNlIGJldHdlZW4gImFiYyIgYW5kICJBQkMiKQogICAqIC4gICAgICAgQ29sbGF0b3I6OkVDb21wYXJpc29uUmVzdWx0IHJlc3VsdCA9IG15Q29sbGF0aW9uLT5jb21wYXJlKCJhYmMiLCAiQUJDIiwzKTsKICAgKiA8L3ByZT4KICAgKiBAcGFyYW0gc291cmNlIHRoZSBzb3VyY2Ugc3RyaW5nIHRvIGJlIGNvbXBhcmVkIHdpdGguCiAgICogQHBhcmFtIHRhcmdldCB0aGUgc3RyaW5nIHRoYXQgaXMgdG8gYmUgY29tcGFyZWQgd2l0aCB0aGUgc291cmNlIHN0cmluZy4KICAgKiBAcGFyYW0gbGVuZ3RoIHRoZSBsZW5ndGggdGhlIGNvbXBhcmlzb24gaXMgbGltaXR0ZWQgdG8KICAgKiBAcmV0dXJuIFJldHVybnMgYSBieXRlIHZhbHVlLiBHUkVBVEVSIGlmIHNvdXJjZSAodXAgdG8gdGhlIHNwZWNpZmllZCBsZW5ndGgpIGlzIGdyZWF0ZXIKICAgKiB0aGFuIHRhcmdldDsgRVFVQUwgaWYgc291cmNlICh1cCB0byBzcGVjaWZpZWQgbGVuZ3RoKSBpcyBlcXVhbCB0byB0YXJnZXQ7IExFU1MgaWYgc291cmNlCiAgICogKHVwIHRvIHRoZSBzcGVjaWZpZWQgbGVuZ3RoKSBpcyBsZXNzICB0aGFuIHRhcmdldC4gICAKICAgKiBAZHJhZnQKICAgKiovCgogIHZpcnR1YWwgRUNvbXBhcmlzb25SZXN1bHQgICBjb21wYXJlKCAgICBjb25zdCAgIFVuaWNvZGVTdHJpbmcmICBzb3VyY2UsCiAgICAgICAgICAgICAgICAgICAgICBjb25zdCAgIFVuaWNvZGVTdHJpbmcmICB0YXJnZXQsCiAgICAgICAgICAgICAgICAgICAgICBpbnQzMl90IGxlbmd0aCkgY29uc3QgPSAwOwogICAgCiAgICAKICAvKioKICAgKiBUaGUgY29tcGFyaXNvbiBmdW5jdGlvbiBjb21wYXJlcyB0aGUgY2hhcmFjdGVyIGRhdGEgc3RvcmVkIGluIHR3bwogICAqIGRpZmZlcmVudCBzdHJpbmcgYXJyYXlzLiAgUmV0dXJucyBpbmZvcm1hdGlvbiBhYm91dCB3aGV0aGVyIGEgc3RyaW5nCiAgICogYXJyYXkgaXMgbGVzcyB0aGFuLCBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gYW5vdGhlciBzdHJpbmcgYXJyYXkuCiAgICogPHA+RXhhbXBsZSBvZiB1c2U6CiAgICogPHByZT4KICAgKiAuICAgICAgIFVFcnJvckNvZGUgc3RhdHVzID0gVV9aRVJPX0VSUk9SOwogICAqIC4gICAgICAgQ29sbGF0b3IgKm15Q29sbGF0aW9uID0gQ29sbGF0b3I6OmNyZWF0ZUluc3RhbmNlKExvY2FsZTo6VVMsIHN0YXR1cyk7CiAgICogLiAgICAgICBpZiAoVV9GQUlMVVJFKHN0YXR1cykpIHJldHVybjsKICAgKiAuICAgICAgIG15Q29sbGF0aW9uLT5zZXRTdHJlbmd0aChDb2xsYXRvcjo6UFJJTUFSWSk7CiAgICogLiAgICAgICAvLyByZXN1bHQgd291bGQgYmUgQ29sbGF0b3I6OkVRVUFMICgiYWJjIiA9PSAiQUJDIikKICAgKiAuICAgICAgIC8vIChubyBwcmltYXJ5IGRpZmZlcmVuY2UgYmV0d2VlbiAiYWJjIiBhbmQgIkFCQyIpCiAgICogLiAgICAgICBDb2xsYXRvcjo6RUNvbXBhcmlzb25SZXN1bHQgcmVzdWx0ID0gbXlDb2xsYXRpb24tPmNvbXBhcmUoTCJhYmMiLCAzLCBMIkFCQyIsIDMpOwogICAqIC4gICAgICAgbXlDb2xsYXRpb24tPnNldFN0cmVuZ3RoKENvbGxhdG9yOjpURVJUSUFSWSk7CiAgICogLiAgICAgICAvLyByZXN1bHQgd291bGQgYmUgQ29sbGF0b3I6OkxFU1MgKGFiYyIgJmx0OyZsdDsmbHQ7ICJBQkMiKQogICAqIC4gICAgICAgLy8gKHdpdGggdGVydGlhcnkgZGlmZmVyZW5jZSBiZXR3ZWVuICJhYmMiIGFuZCAiQUJDIikKICAgKiAuICAgICAgIENvbGxhdG9yOjpFQ29tcGFyaXNvblJlc3VsdCByZXN1bHQgPSBteUNvbGxhdGlvbi0+Y29tcGFyZShMImFiYyIsIDMsIEwiQUJDIiwgMyk7CiAgICogPC9wcmU+CiAgICogQHBhcmFtIHNvdXJjZSB0aGUgc291cmNlIHN0cmluZyBhcnJheSB0byBiZSBjb21wYXJlZCB3aXRoLgogICAqIEBwYXJhbSBzb3VyY2VMZW5ndGggdGhlIGxlbmd0aCBvZiB0aGUgc291cmNlIHN0cmluZyBhcnJheS4gIElmIHRoaXMgdmFsdWUKICAgKiAgICAgICAgaXMgZXF1YWwgdG8gLTEsIHRoZSBzdHJpbmcgYXJyYXkgaXMgbnVsbC10ZXJtaW5hdGVkLgogICAqIEBwYXJhbSB0YXJnZXQgdGhlIHN0cmluZyB0aGF0IGlzIHRvIGJlIGNvbXBhcmVkIHdpdGggdGhlIHNvdXJjZSBzdHJpbmcuCiAgICogQHBhcmFtIHRhcmdldExlbmd0aCB0aGUgbGVuZ3RoIG9mIHRoZSB0YXJnZXQgc3RyaW5nIGFycmF5LiAgSWYgdGhpcyB2YWx1ZQogICAqICAgICAgICBpcyBlcXVhbCB0byAtMSwgdGhlIHN0cmluZyBhcnJheSBpcyBudWxsLXRlcm1pbmF0ZWQuCiAgICogQHJldHVybiBSZXR1cm5zIGEgYnl0ZSB2YWx1ZS4gR1JFQVRFUiBpZiBzb3VyY2UgaXMgZ3JlYXRlcgogICAqIHRoYW4gdGFyZ2V0OyBFUVVBTCBpZiBzb3VyY2UgaXMgZXF1YWwgdG8gdGFyZ2V0OyBMRVNTIGlmIHNvdXJjZSBpcyBsZXNzCiAgICogdGhhbiB0YXJnZXQKICAgKiBAc3RhYmxlCiAgICoqLwogIHZpcnR1YWwgRUNvbXBhcmlzb25SZXN1bHQgICBjb21wYXJlKCAgICBjb25zdCAgIFVDaGFyKiBzb3VyY2UsIAogICAgICAgICAgICAgICAgICAgICAgaW50MzJfdCBzb3VyY2VMZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICBjb25zdCAgIFVDaGFyKiAgdGFyZ2V0LAogICAgICAgICAgICAgICAgICAgICAgaW50MzJfdCB0YXJnZXRMZW5ndGgpIGNvbnN0ID0gMDsKCiAgLyoqIFRyYW5zZm9ybXMgdGhlIHN0cmluZyBpbnRvIGEgc2VyaWVzIG9mIGNoYXJhY3RlcnMgdGhhdCBjYW4gYmUgY29tcGFyZWQKICAgKiB3aXRoIENvbGxhdGlvbktleTo6Y29tcGFyZVRvLiBJdCBpcyBub3QgcG9zc2libGUgdG8gcmVzdG9yZSB0aGUgb3JpZ2luYWwKICAgKiBzdHJpbmcgZnJvbSB0aGUgY2hhcnMgaW4gdGhlIHNvcnQga2V5LiAgVGhlIGdlbmVyYXRlZCBzb3J0IGtleSBoYW5kbGVzIAogICAqIG9ubHkgYSBsaW1pdGVkIG51bWJlciBvZiBpZ25vcmFibGUgY2hhcmFjdGVycy4KICAgKiA8cD5Vc2UgQ29sbGF0aW9uS2V5OjplcXVhbHMgb3IgQ29sbGF0aW9uS2V5Ojpjb21wYXJlIHRvIGNvbXBhcmUgdGhlCiAgICogZ2VuZXJhdGVkIHNvcnQga2V5cy4KICAgKiA8cD5FeGFtcGxlIG9mIHVzZToKICAgKiA8cHJlPgogICAqIC4gICAgICAgVUVycm9yQ29kZSBzdGF0dXMgPSBVX1pFUk9fRVJST1I7CiAgICogLiAgICAgICBDb2xsYXRvciAqbXlDb2xsYXRpb24gPSBDb2xsYXRvcjo6Y3JlYXRlSW5zdGFuY2UoTG9jYWxlOjpVUywgc3RhdHVzKTsKICAgKiAuICAgICAgIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkgcmV0dXJuOwogICAqIC4gICAgICAgbXlDb2xsYXRpb24tPnNldFN0cmVuZ3RoKENvbGxhdG9yOjpQUklNQVJZKTsKICAgKiAuICAgICAgIFVFcnJvckNvZGUga2V5MVN0YXR1cywga2V5MlN0YXR1czsKICAgKiAuICAgICAgIENvbGxhdGlvbktleSBDb2xsYXRpb25LZXkxCiAgICogLiAgICAgICBDb2xsYXRpb25LZXkxID0gbXlDb2xsYXRpb24tPmdldENvbGxhdGlvbktleSgiYWJjIiwgQ29sbGF0aW9uS2V5MSwga2V5MVN0YXR1cyk7CiAgICogLiAgICAgICBDb2xsYXRpb25LZXkgQ29sbGF0aW9uS2V5MgogICAqIC4gICAgICAgQ29sbGF0aW9uS2V5MiA9IG15Q29sbGF0aW9uLT5nZXRDb2xsYXRpb25LZXkoIkFCQyIsIENvbGxhdGlvbktleTIsIGtleTJTdGF0dXMpOwogICAqIC4gICAgICAgaWYgKFVfRkFJTFVSRShrZXkxU3RhdHVzKSB8fCBVX0ZBSUxVUkUoa2V5MlN0YXR1cykpIHsgZGVsZXRlIG15Q29sbGF0aW9uOyByZXR1cm47IH0KICAgKiAuICAgICAgIC8vIFVzZSBDb2xsYXRpb25LZXk6OmNvbXBhcmUoKSB0byBjb21wYXJlIHRoZSBzb3J0IGtleXMKICAgKiAuICAgICAgIC8vIHJlc3VsdCB3b3VsZCBiZSAwIChDb2xsYXRpb25LZXkxID09IENvbGxhdGlvbktleTIpCiAgICogLiAgICAgICBpbnQgcmVzdWx0ID0gQ29sbGF0aW9uS2V5MS5jb21wYXJlKENvbGxhdGlvbktleTIpOwogICAqIC4gICAgICAgbXlDb2xsYXRpb24tPnNldFN0cmVuZ3RoKENvbGxhdG9yOjpURVJUSUFSWSk7CiAgICogLiAgICAgICBDb2xsYXRpb25LZXkxID0gbXlDb2xsYXRpb24tPmdldENvbGxhdGlvbktleSgiYWJjIiwgQ29sbGF0aW9uS2V5MSwga2V5MVN0YXR1cyk7CiAgICogLiAgICAgICBDb2xsYXRpb25LZXkyID0gbXlDb2xsYXRpb24tPmdldENvbGxhdGlvbktleSgiQUJDIiwgQ29sbGF0aW9uS2V5Miwga2V5MlN0YXR1cyk7CiAgICogLiAgICAgICBpZiAoVV9GQUlMVVJFKGtleTFTdGF0dXMpIHx8IFVfRkFJTFVSRShrZXkyU3RhdHVzKSkgeyBkZWxldGUgbXlDb2xsYXRpb247IHJldHVybjsgfQogICAqIC4gICAgICAgLy8gVXNlIENvbGxhdGlvbktleTo6Y29tcGFyZVRvIHRvIGNvbXBhcmUgdGhlIGNvbGxhdGlvbiBrZXlzCiAgICogLiAgICAgICAvLyByZXN1bHQgd291bGQgYmUgLTEgKENvbGxhdGlvbktleTEgJmx0OyBDb2xsYXRpb25LZXkyKQogICAqIC4gICAgICAgcmVzdWx0ID0gQ29sbGF0aW9uS2V5MS5jb21wYXJlVG8oQ29sbGF0aW9uS2V5Mik7CiAgICogLiAgICAgICBkZWxldGUgbXlDb2xsYXRpb247CiAgICogPC9wcmU+CiAgICogPHA+SWYgdGhlIHNvdXJjZSBzdHJpbmcgaXMgbnVsbCwgYSBudWxsIGNvbGxhdGlvbiBrZXkgd2lsbCBiZSByZXR1cm5lZC4KICAgKiBAcGFyYW0gc291cmNlIHRoZSBzb3VyY2Ugc3RyaW5nIHRvIGJlIHRyYW5zZm9ybWVkIGludG8gYSBzb3J0IGtleS4KICAgKiBAcGFyYW0ga2V5IHRoZSBjb2xsYXRpb24ga2V5IHRvIGJlIGZpbGxlZCBpbgogICAqIEByZXR1cm4gdGhlIGNvbGxhdGlvbiBrZXkgb2YgdGhlIHN0cmluZyBiYXNlZCBvbiB0aGUgY29sbGF0aW9uIHJ1bGVzLgogICAqIEBzZWUgQ29sbGF0aW9uS2V5I2NvbXBhcmUKICAgKiBAZHJhZnQKICAgKi8KICB2aXJ0dWFsIENvbGxhdGlvbktleSYgICAgICAgZ2V0Q29sbGF0aW9uS2V5KGNvbnN0ICAgVW5pY29kZVN0cmluZyYgIHNvdXJjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICBDb2xsYXRpb25LZXkmICAgICAgIGtleSwKICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiAgICAgIHN0YXR1cykgY29uc3QgPSAwOwoKICAvKiogVHJhbnNmb3JtcyB0aGUgc3RyaW5nIGludG8gYSBzZXJpZXMgb2YgY2hhcmFjdGVycyB0aGF0IGNhbiBiZSBjb21wYXJlZAogICAqIHdpdGggQ29sbGF0aW9uS2V5Ojpjb21wYXJlVG8uIEl0IGlzIG5vdCBwb3NzaWJsZSB0byByZXN0b3JlIHRoZSBvcmlnaW5hbAogICAqIHN0cmluZyBmcm9tIHRoZSBjaGFycyBpbiB0aGUgc29ydCBrZXkuICBUaGUgZ2VuZXJhdGVkIHNvcnQga2V5IGhhbmRsZXMgCiAgICogb25seSBhIGxpbWl0ZWQgbnVtYmVyIG9mIGlnbm9yYWJsZSBjaGFyYWN0ZXJzLgogICAqIDxwPlVzZSBDb2xsYXRpb25LZXk6OmVxdWFscyBvciBDb2xsYXRpb25LZXk6OmNvbXBhcmUgdG8gY29tcGFyZSB0aGUKICAgKiBnZW5lcmF0ZWQgc29ydCBrZXlzLgogICAqIDxwPklmIHRoZSBzb3VyY2Ugc3RyaW5nIGlzIG51bGwsIGEgbnVsbCBjb2xsYXRpb24ga2V5IHdpbGwgYmUgcmV0dXJuZWQuCiAgICogQHBhcmFtIHNvdXJjZSB0aGUgc291cmNlIHN0cmluZyB0byBiZSB0cmFuc2Zvcm1lZCBpbnRvIGEgc29ydCBrZXkuCiAgICogQHBhcmFtIHNvdXJjZUxlbmd0aCBsZW5ndGggb2YgdGhlIGNvbGxhdGlvbiBrZXkKICAgKiBAcGFyYW0ga2V5IHRoZSBjb2xsYXRpb24ga2V5IHRvIGJlIGZpbGxlZCBpbgogICAqIEByZXR1cm4gdGhlIGNvbGxhdGlvbiBrZXkgb2YgdGhlIHN0cmluZyBiYXNlZCBvbiB0aGUgY29sbGF0aW9uIHJ1bGVzLgogICAqIEBzZWUgQ29sbGF0aW9uS2V5I2NvbXBhcmUKICAgKiBAZHJhZnQKICAgKi8KICB2aXJ0dWFsIENvbGxhdGlvbktleSYgICAgICAgZ2V0Q29sbGF0aW9uS2V5KGNvbnN0IFVDaGFyICpzb3VyY2UsCgkJCQkJICAgICAgaW50MzJfdCBzb3VyY2VMZW5ndGgsCgkJCQkJICAgICAgQ29sbGF0aW9uS2V5JiAgICAgICBrZXksCgkJCQkJICAgICAgVUVycm9yQ29kZSYgICAgICBzdGF0dXMpIGNvbnN0ID0gMDsKICAvKioKICAgKiBHZW5lcmF0ZXMgdGhlIGhhc2ggY29kZSBmb3IgdGhlIGNvbGxhdGlvbiBvYmplY3QKICAgKiBAc3RhYmxlCiAgICovCiAgdmlydHVhbCBpbnQzMl90ICAgICAgICAgICAgIGhhc2hDb2RlKHZvaWQpIGNvbnN0ID0gMDsKCiAgLyoqCiAgICogQ29udmVuaWVuY2UgbWV0aG9kIGZvciBjb21wYXJpbmcgdHdvIHN0cmluZ3MgYmFzZWQgb24KICAgKiB0aGUgY29sbGF0aW9uIHJ1bGVzLgogICAqIEBwYXJhbSBzb3VyY2UgdGhlIHNvdXJjZSBzdHJpbmcgdG8gYmUgY29tcGFyZWQgd2l0aC4KICAgKiBAcGFyYW0gdGFyZ2V0IHRoZSB0YXJnZXQgc3RyaW5nIHRvIGJlIGNvbXBhcmVkIHdpdGguCiAgICogQHJldHVybiB0cnVlIGlmIHRoZSBmaXJzdCBzdHJpbmcgaXMgZ3JlYXRlciB0aGFuIHRoZSBzZWNvbmQgb25lLAogICAqIGFjY29yZGluZyB0byB0aGUgY29sbGF0aW9uIHJ1bGVzLiBmYWxzZSwgb3RoZXJ3aXNlLgogICAqIEBzZWUgQ29sbGF0b3IjY29tcGFyZQogICAqIEBzdGFibGUKICAgKi8KICBVQm9vbCAgICAgICAgICAgICAgZ3JlYXRlciggICAgY29uc3QgICBVbmljb2RlU3RyaW5nJiBzb3VyY2UsIAogICAgICAgICAgICAgICAgICBjb25zdCAgIFVuaWNvZGVTdHJpbmcmIHRhcmdldCkgY29uc3Q7CiAgLyoqCiAgICogQ29udmVuaWVuY2UgbWV0aG9kIGZvciBjb21wYXJpbmcgdHdvIHN0cmluZ3MgYmFzZWQgb24gdGhlIGNvbGxhdGlvbgogICAqIHJ1bGVzLgogICAqIEBwYXJhbSBzb3VyY2UgdGhlIHNvdXJjZSBzdHJpbmcgdG8gYmUgY29tcGFyZWQgd2l0aC4KICAgKiBAcGFyYW0gdGFyZ2V0IHRoZSB0YXJnZXQgc3RyaW5nIHRvIGJlIGNvbXBhcmVkIHdpdGguCiAgICogQHJldHVybiB0cnVlIGlmIHRoZSBmaXJzdCBzdHJpbmcgaXMgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIHRoZQogICAqIHNlY29uZCBvbmUsIGFjY29yZGluZyB0byB0aGUgY29sbGF0aW9uIHJ1bGVzLiBmYWxzZSwgb3RoZXJ3aXNlLgogICAqIEBzZWUgQ29sbGF0b3IjY29tcGFyZQogICAqIEBzdGFibGUKICAgKi8KICBVQm9vbCAgICAgICAgICAgICAgZ3JlYXRlck9yRXF1YWwoIGNvbnN0ICAgVW5pY29kZVN0cmluZyYgc291cmNlLCAKICAgICAgICAgICAgICAgICAgICAgIGNvbnN0ICAgVW5pY29kZVN0cmluZyYgdGFyZ2V0KSBjb25zdDsKICAvKioKICAgKiBDb252ZW5pZW5jZSBtZXRob2QgZm9yIGNvbXBhcmluZyB0d28gc3RyaW5ncyBiYXNlZCBvbiB0aGUgY29sbGF0aW9uCiAgICogcnVsZXMuCiAgICogQHBhcmFtIHNvdXJjZSB0aGUgc291cmNlIHN0cmluZyB0byBiZSBjb21wYXJlZCB3aXRoLgogICAqIEBwYXJhbSB0YXJnZXQgdGhlIHRhcmdldCBzdHJpbmcgdG8gYmUgY29tcGFyZWQgd2l0aC4KICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIHN0cmluZ3MgYXJlIGVxdWFsIGFjY29yZGluZyB0byB0aGUgY29sbGF0aW9uCiAgICogcnVsZXMuICBmYWxzZSwgb3RoZXJ3aXNlLgogICAqIEBzZWUgQ29sbGF0b3IjY29tcGFyZQogICAqIEBzdGFibGUKICAgKi8KICBVQm9vbCAgICAgICAgICAgICAgZXF1YWxzKCBjb25zdCAgIFVuaWNvZGVTdHJpbmcmIHNvdXJjZSwgCiAgICAgICAgICAgICAgICAgIGNvbnN0ICAgVW5pY29kZVN0cmluZyYgdGFyZ2V0KSBjb25zdDsKICAgICAgICAKICAvLyBnZXR0ZXIvc2V0dGVyCiAgLyoqCiAgICogR2V0IHRoZSBkZWNvbXBvc2l0aW9uIG1vZGUgb2YgdGhlIGNvbGxhdG9yIG9iamVjdC4KICAgKiBAcmV0dXJuIHRoZSBkZWNvbXBvc2l0aW9uIG1vZGUKICAgKiBAc2VlIENvbGxhdG9yI3NldERlY29tcG9zaXRpb24KICAgKiBAc3RhYmxlCiAgICovCiAgTm9ybWFsaXplcjo6RU1vZGUgIGdldERlY29tcG9zaXRpb24odm9pZCkgY29uc3Q7CiAgLyoqCiAgICogU2V0IHRoZSBkZWNvbXBvc2l0aW9uIG1vZGUgb2YgdGhlIGNvbGxhdG9yIG9iamVjdC4gc3VjY2VzcyBpcyBlcXVhbAogICAqIHRvIFVfSUxMRUdBTF9BUkdVTUVOVF9FUlJPUiBpZiBlcnJvciBvY2N1cnMuCiAgICogQHBhcmFtIHRoZSBuZXcgZGVjb21wb3NpdGlvbiBtb2RlCiAgICogQHNlZSBDb2xsYXRvciNnZXREZWNvbXBvc2l0aW9uCiAgICogQHN0YWJsZQogICAqLwogIHZvaWQgICAgICAgICAgICAgICAgc2V0RGVjb21wb3NpdGlvbihOb3JtYWxpemVyOjpFTW9kZSAgbW9kZSk7CiAgLyoqCiAgICogRGV0ZXJtaW5lcyB0aGUgbWluaW11bSBzdHJlbmd0aCB0aGF0IHdpbGwgYmUgdXNlIGluIGNvbXBhcmlzb24gb3IKICAgKiB0cmFuc2Zvcm1hdGlvbi4KICAgKiA8cD5FLmcuIHdpdGggc3RyZW5ndGggPT0gU0VDT05EQVJZLCB0aGUgdGVydGlhcnkgZGlmZmVyZW5jZSBpcyBpZ25vcmVkCiAgICogPHA+RS5nLiB3aXRoIHN0cmVuZ3RoID09IFBSSU1BUlksIHRoZSBzZWNvbmRhcnkgYW5kIHRlcnRpYXJ5IGRpZmZlcmVuY2UKICAgKiBhcmUgaWdub3JlZC4KICAgKiBAcmV0dXJuIHRoZSBjdXJyZW50IGNvbXBhcmlzb24gbGV2ZWwuCiAgICogQHNlZSBDb2xsYXRvciNzZXRTdHJlbmd0aAogICAqIEBzdGFibGUKICAgKi8KICBFQ29sbGF0aW9uU3RyZW5ndGggIGdldFN0cmVuZ3RoKHZvaWQpIGNvbnN0OwogIC8qKgogICAqIFNldHMgdGhlIG1pbmltdW0gc3RyZW5ndGggdG8gYmUgdXNlZCBpbiBjb21wYXJpc29uIG9yIHRyYW5zZm9ybWF0aW9uLgogICAqIDxwPkV4YW1wbGUgb2YgdXNlOgogICAqIDxwcmU+CiAgICogLiAgICAgICBVRXJyb3JDb2RlIHN0YXR1cyA9IFVfWkVST19FUlJPUjsKICAgKiAuICAgICAgIENvbGxhdG9yICpteUNvbGxhdGlvbiA9IENvbGxhdG9yOjpjcmVhdGVJbnN0YW5jZShMb2NhbGU6OlVTLCBzdGF0dXMpOwogICAqIC4gICAgICAgaWYgKFVfRkFJTFVSRShzdGF0dXMpKSByZXR1cm47CiAgICogLiAgICAgICBteUNvbGxhdGlvbi0+c2V0U3RyZW5ndGgoQ29sbGF0b3I6OlBSSU1BUlkpOwogICAqIC4gICAgICAgLy8gcmVzdWx0IHdpbGwgYmUgImFiYyIgPT0gIkFCQyIKICAgKiAuICAgICAgIC8vIHRlcnRpYXJ5IGRpZmZlcmVuY2VzIHdpbGwgYmUgaWdub3JlZAogICAqIC4gICAgICAgQ29sbGF0b3I6OkNvbXBhcmlzb25SZXN1bHQgcmVzdWx0ID0gbXlDb2xsYXRpb24tPmNvbXBhcmUoImFiYyIsICJBQkMiKTsKICAgKiA8L3ByZT4KICAgKiBAc2VlIENvbGxhdG9yI2dldFN0cmVuZ3RoCiAgICogQHBhcmFtIG5ld1N0cmVuZ3RoIHRoZSBuZXcgY29tcGFyaXNvbiBsZXZlbC4KICAgKiBAc3RhYmxlCiAgICovCiAgdm9pZCAgICAgICAgICAgICAgICBzZXRTdHJlbmd0aCggICAgRUNvbGxhdGlvblN0cmVuZ3RoICBuZXdTdHJlbmd0aCk7CiAgLyoqCiAgICogR2V0IG5hbWUgb2YgdGhlIG9iamVjdCBmb3IgdGhlIGRlc2lyZWQgTG9jYWxlLCBpbiB0aGUgZGVzaXJlZCBsYW5nYXVnZQogICAqIEBwYXJhbSBvYmplY3RMb2NhbGUgbXVzdCBiZSBmcm9tIGdldEF2YWlsYWJsZUxvY2FsZXMKICAgKiBAcGFyYW0gZGlzcGxheUxvY2FsZSBzcGVjaWZpZXMgdGhlIGRlc2lyZWQgbG9jYWxlIGZvciBvdXRwdXQKICAgKiBAcGFyYW0gbmFtZSB0aGUgZmlsbC1pbiBwYXJhbWV0ZXIgb2YgdGhlIHJldHVybiB2YWx1ZQogICAqIEByZXR1cm4gZGlzcGxheS1hYmxlIG5hbWUgb2YgdGhlIG9iamVjdCBmb3IgdGhlIG9iamVjdCBsb2NhbGUgaW4gdGhlCiAgICogZGVzaXJlZCBsYW5ndWFnZQogICAqIEBzdGFibGUKICAgKi8KICBzdGF0aWMgIFVuaWNvZGVTdHJpbmcmICAgICAgZ2V0RGlzcGxheU5hbWUoIGNvbnN0ICAgTG9jYWxlJiAgICAgb2JqZWN0TG9jYWxlLAogICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0ICAgTG9jYWxlJiAgICAgZGlzcGxheUxvY2FsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICBVbmljb2RlU3RyaW5nJiBuYW1lKSA7CiAgLyoqCiAgICogR2V0IG5hbWUgb2YgdGhlIG9iamVjdCBmb3IgdGhlIGRlc2lyZWQgTG9jYWxlLCBpbiB0aGUgbGFuZ2F1Z2Ugb2YgdGhlCiAgICogZGVmYXVsdCBsb2NhbGUuCiAgICogQHBhcmFtIG9iamVjdExvY2FsZSBtdXN0IGJlIGZyb20gZ2V0QXZhaWxhYmxlTG9jYWxlcwogICAqIEBwYXJhbSBuYW1lIHRoZSBmaWxsLWluIHBhcmFtZXRlciBvZiB0aGUgcmV0dXJuIHZhbHVlCiAgICogQHJldHVybiBuYW1lIG9mIHRoZSBvYmplY3QgZm9yIHRoZSBkZXNpcmVkIGxvY2FsZSBpbiB0aGUgZGVmYXVsdAogICAqIGxhbmd1YWdlCiAgICogQHN0YWJsZQogICAqLwogIHN0YXRpYyAgVW5pY29kZVN0cmluZyYgICAgICBnZXREaXNwbGF5TmFtZSggY29uc3QgICBMb2NhbGUmICAgICAgICAgb2JqZWN0TG9jYWxlLAogICAgICAgICAgICAgICAgICAgICAgICAgIFVuaWNvZGVTdHJpbmcmICBuYW1lKSA7CgogIC8qKgogICAqIEdldCB0aGUgc2V0IG9mIExvY2FsZXMgZm9yIHdoaWNoIENvbGxhdGlvbnMgYXJlIGluc3RhbGxlZAogICAqIEBwYXJhbSBjb3VudCB0aGUgb3V0cHV0IHBhcmFtZXRlciBvZiBudW1iZXIgb2YgZWxlbWVudHMgaW4gdGhlIGxvY2FsZSBsaXN0CiAgICogQHJldHVybiB0aGUgbGlzdCBvZiBhdmFpbGFibGUgbG9jYWxlcyB3aGljaCBjb2xsYXRpb25zIGFyZSBpbnN0YWxsZWQKICAgKiBAc3RhYmxlCiAgICovCiAgc3RhdGljICBjb25zdCAgIExvY2FsZSogICAgIGdldEF2YWlsYWJsZUxvY2FsZXMoaW50MzJfdCYgY291bnQpOwoKICAvKioKICAgKiBHZXRzIHRoZSB2ZXJzaW9uIGluZm9ybWF0aW9uIGZvciBhIENvbGxhdG9yLiAKICAgKiBAcGFyYW0gaW5mbyB0aGUgdmVyc2lvbiAjIGluZm9ybWF0aW9uLCB0aGUgcmVzdWx0IHdpbGwgYmUgZmlsbGVkIGluCiAgICogQHN0YWJsZQogICAqLwogIHZvaWQgZ2V0VmVyc2lvbihVVmVyc2lvbkluZm8gaW5mbykgY29uc3Q7CgogIC8qKgogICAqIFJldHVybnMgYSB1bmlxdWUgY2xhc3MgSUQgUE9MWU1PUlBISUNBTExZLiAgUHVyZSB2aXJ0dWFsIG1ldGhvZC4KICAgKiBUaGlzIG1ldGhvZCBpcyB0byBpbXBsZW1lbnQgYSBzaW1wbGUgdmVyc2lvbiBvZiBSVFRJLCBzaW5jZSBub3QgYWxsCiAgICogQysrIGNvbXBpbGVycyBzdXBwb3J0IGdlbnVpbmUgUlRUSS4gIFBvbHltb3JwaGljIG9wZXJhdG9yPT0oKSBhbmQKICAgKiBjbG9uZSgpIG1ldGhvZHMgY2FsbCB0aGlzIG1ldGhvZC4KICAgKgogICAqIENvbmNyZXRlIHN1YmNsYXNzZXMgb2YgRm9ybWF0IG11c3QgaW1wbGVtZW50IGdldER5bmFtaWNDbGFzc0lEKCkKICAgKiBhbmQgYWxzbyBhIHN0YXRpYyBtZXRob2QgYW5kIGRhdGEgbWVtYmVyOgogICAqCiAgICogICAgICBzdGF0aWMgVUNsYXNzSUQgZ2V0U3RhdGljQ2xhc3NJRCgpIHsgcmV0dXJuIChVQ2xhc3NJRCkmZmdDbGFzc0lEOyB9CiAgICogICAgICBzdGF0aWMgY2hhciBmZ0NsYXNzSUQ7CiAgICoKICAgKiBAcmV0dXJuICAgICAgICAgIFRoZSBjbGFzcyBJRCBmb3IgdGhpcyBvYmplY3QuIEFsbCBvYmplY3RzIG9mIGEKICAgKiAgICAgICAgICAgICAgICAgIGdpdmVuIGNsYXNzIGhhdmUgdGhlIHNhbWUgY2xhc3MgSUQuICBPYmplY3RzIG9mCiAgICogICAgICAgICAgICAgICAgICBvdGhlciBjbGFzc2VzIGhhdmUgZGlmZmVyZW50IGNsYXNzIElEcy4KICAgKiBAc3RhYmxlCiAgICovCiAgdmlydHVhbCBVQ2xhc3NJRCBnZXREeW5hbWljQ2xhc3NJRCh2b2lkKSBjb25zdCA9IDA7CgogIC8qIE5ldyBBUElzIGZvciAxLjcuIE5vdCB5ZXQgaW1wbGVtZW50ZWQgKi8KCi8qKgogKiBVbml2ZXJzYWwgYXR0cmlidXRlIHNldHRlcgogKiBAcGFyYW0gYXR0ciBhdHRyaWJ1dGUgdHlwZSAKICogQHBhcmFtIHZhbHVlIGF0dHJpYnV0ZSB2YWx1ZQogKiBAcGFyYW0gc3RhdHVzIHRvIGluZGljYXRlIHdoZXRoZXIgdGhlIG9wZXJhdGlvbiB3ZW50IG9uIHNtb290aGx5IG9yIHRoZXJlIHdlcmUgZXJyb3JzCiAqIEBkcmFmdCBBUEkgMS43IGZyZWV6ZQogKi8KdmlydHVhbCB2b2lkIHNldEF0dHJpYnV0ZShVQ29sQXR0cmlidXRlIGF0dHIsIFVDb2xBdHRyaWJ1dGVWYWx1ZSB2YWx1ZSwgVUVycm9yQ29kZSAmc3RhdHVzKSA9IDA7CgovKioKICogVW5pdmVyc2FsIGF0dHJpYnV0ZSBnZXR0ZXIKICogQHBhcmFtIGF0dHIgYXR0cmlidXRlIHR5cGUKICogQHBhcmFtIHN0YXR1cyB0byBpbmRpY2F0ZSB3aGV0aGVyIHRoZSBvcGVyYXRpb24gd2VudCBvbiBzbW9vdGhseSBvciB0aGVyZSB3ZXJlIGVycm9ycwogKiBAcmV0dXJuIGF0dHJpYnV0ZSB2YWx1ZQogKiBAZHJhZnQgQVBJIDEuNyBmcmVlemUKICovCnZpcnR1YWwgVUNvbEF0dHJpYnV0ZVZhbHVlIGdldEF0dHJpYnV0ZShVQ29sQXR0cmlidXRlIGF0dHIsIFVFcnJvckNvZGUgJnN0YXR1cykgPSAwOwoKLyoqCiAqIFRocmVhZCBzYWZlIGNsb25pbmcgb3BlcmF0aW9uCiAqIEByZXR1cm4gcG9pbnRlciB0byB0aGUgbmV3IGNsb25lLCB1c2VyIHNob3VsZCByZW1vdmUgaXQuCiAqIEBkcmFmdCBBUEkgMS43IGZyZWV6ZQogKi8KdmlydHVhbCBDb2xsYXRvciogc2FmZUNsb25lKHZvaWQpID0gMDsKCgovKioKICogU3RyaW5nIGNvbXBhcmUgdGhhdCB1c2VzIHVzZXIgc3VwcGxpZWQgY2hhcmFjdGVyIGl0ZXJhdGlvbi4KICogVGhlIGlkZWEgaXMgdG8gcHJldmVudCB1c2VycyBmcm9tIGhhdmluZyB0byBjb252ZXJ0IHRoZSB3aG9sZSBzdHJpbmcgaW50byBVQ2hhcidzIGJlZm9yZSBjb21wYXJpbmcKICogc2luY2Ugc29tZXRpbWVzIHN0cmluZ3MgZGlmZmVyIG9uIGZpcnN0IGNvdXBsZSBvZiBjaGFyYWN0ZXJzLgogKiBAcGFyYW0gY29sbCBjb2xsYXRvciB0byBiZSB1c2VkIGZvciBjb21wYXJpbmcKICogQHBhcmFtIHNvdXJjZSBwb2ludGVyIHRvIGZ1bmN0aW9uIGZvciBpdGVyYXRpbmcgb3ZlciB0aGUgZmlyc3Qgc3RyaW5nCiAqIEBwYXJhbSB0YXJnZXQgcG9pbnRlciB0byBmdW5jdGlvbiBmb3IgaXRlcmF0aW5nIG92ZXIgdGhlIHNlY29uZCBzdHJpbmcKICogQHJldHVybiBUaGUgcmVzdWx0IG9mIGNvbXBhcmluZyB0aGUgc3RyaW5nczsgb25lIG9mIFVDT0xfRVFVQUwsCiAqIFVDT0xfR1JFQVRFUiwgVUNPTF9MRVNTCiAqIEBkcmFmdCBBUEkgMS43IGZyZWV6ZQogKi8KdmlydHVhbCBFQ29tcGFyaXNvblJlc3VsdCBjb21wYXJlKEZvcndhcmRDaGFyYWN0ZXJJdGVyYXRvciAmc291cmNlLAoJCQkJCQkJCSBGb3J3YXJkQ2hhcmFjdGVySXRlcmF0b3IgJnRhcmdldCkgPSAwOwoKLyoqCiAqIEdldCB0aGUgc29ydCBrZXkgYXMgYW4gYXJyYXkgb2YgYnl0ZXMgZnJvbSBhbiBVbmljb2RlU3RyaW5nLgogKiBAcGFyYW0gc291cmNlIHN0cmluZyB0byBiZSBwcm9jZXNzZWQuCiAqIEBwYXJhbSByZXN1bHQgYnVmZmVyIHRvIHN0b3JlIHJlc3VsdCBpbi4gSWYgTlVMTCwgbnVtYmVyIG9mIGJ5dGVzIG5lZWRlZCB3aWxsIGJlIHJldHVybmVkLgogKiBAcGFyYW0gcmVzdWx0TGVuZ3RoIGxlbmd0aCBvZiB0aGUgcmVzdWx0IGJ1ZmZlci4gSWYgaWYgbm90IGVub3VnaCB0aGUgYnVmZmVyIHdpbGwgYmUgZmlsbGVkIHRvIGNhcGFjaXR5LiAKICogQHJldHVybiBOdW1iZXIgb2YgYnl0ZXMgbmVlZGVkIGZvciBzdG9yaW5nIHRoZSBzb3J0IGtleQogKiBAZHJhZnQgQVBJIDEuNyBmcmVlemUKICovCiAgdmlydHVhbCBpbnQzMl90ICAgICAgIGdldFNvcnRLZXkoY29uc3QgICBVbmljb2RlU3RyaW5nJiAgc291cmNlLAoJCQkJCQkgIHVpbnQ4X3QgKnJlc3VsdCwKCQkJCQkJICBpbnQzMl90IHJlc3VsdExlbmd0aCkgY29uc3QgPSAwOwoKLyoqCiAqIEdldCB0aGUgc29ydCBrZXkgYXMgYW4gYXJyYXkgb2YgYnl0ZXMgZnJvbSBhbiBVQ2hhciBidWZmZXIuCiAqIEBwYXJhbSBzb3VyY2Ugc3RyaW5nIHRvIGJlIHByb2Nlc3NlZC4KICogQHBhcmFtIHNvdXJjZUxlbmd0aCBsZW5ndGggb2Ygc3RyaW5nIHRvIGJlIHByb2Nlc3NlZC4gCiAqCQkJSWYgLTEsIHRoZSBzdHJpbmcgaXMgMCB0ZXJtaW5hdGVkIGFuZCBsZW5ndGggd2lsbCBiZSBkZWNpZGVkIGJ5IHRoZSBmdW5jdGlvbi4KICogQHBhcmFtIHJlc3VsdCBidWZmZXIgdG8gc3RvcmUgcmVzdWx0IGluLiBJZiBOVUxMLCBudW1iZXIgb2YgYnl0ZXMgbmVlZGVkIHdpbGwgYmUgcmV0dXJuZWQuCiAqIEBwYXJhbSByZXN1bHRMZW5ndGggbGVuZ3RoIG9mIHRoZSByZXN1bHQgYnVmZmVyLiBJZiBpZiBub3QgZW5vdWdoIHRoZSBidWZmZXIgd2lsbCBiZSBmaWxsZWQgdG8gY2FwYWNpdHkuIAogKiBAcmV0dXJuIE51bWJlciBvZiBieXRlcyBuZWVkZWQgZm9yIHN0b3JpbmcgdGhlIHNvcnQga2V5CiAqIEBkcmFmdCBBUEkgMS43IGZyZWV6ZQogKi8KICB2aXJ0dWFsIGludDMyX3QgICAgICAgZ2V0U29ydEtleShjb25zdCAgIFVDaGFyICpzb3VyY2UsCgkJCQkJCSAgaW50MzJfdCBzb3VyY2VMZW5ndGgsCgkJCQkJCSAgdWludDhfdCAqcmVzdWx0LAoJCQkJCQkgIGludDMyX3QgcmVzdWx0TGVuZ3RoKSBjb25zdCA9IDA7Cgpwcm90ZWN0ZWQ6CiAgLyoqCiAgICogQ29uc3RydWN0b3JzCiAgICovCiAgQ29sbGF0b3IoKTsKICBDb2xsYXRvcihFQ29sbGF0aW9uU3RyZW5ndGggY29sbGF0aW9uU3RyZW5ndGgsCiAgICAgICBOb3JtYWxpemVyOjpFTW9kZSBkZWNvbXBvc2l0aW9uTW9kZSk7CiAgQ29sbGF0b3IoY29uc3QgIENvbGxhdG9yJiAgIG90aGVyKTsKCiAgLyoqCiAgICogQXNzaWdubWVudCBvcGVyYXRvcgogICAqLwogIGNvbnN0ICAgICAgIENvbGxhdG9yJiAgICAgICBvcGVyYXRvcj0oY29uc3QgQ29sbGF0b3ImICAgb3RoZXIpOwoKICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnByaXZhdGU6CiAgICAgICAgICAgIAogIEVDb2xsYXRpb25TdHJlbmd0aCAgc3RyZW5ndGg7CiAgTm9ybWFsaXplcjo6RU1vZGUgIGRlY21wOwogIHN0YXRpYyBjb25zdCBVVmVyc2lvbkluZm8gZlZlcnNpb247Cn07CgppbmxpbmUgVUJvb2wKQ29sbGF0b3I6Om9wZXJhdG9yPT0oY29uc3QgQ29sbGF0b3ImIG90aGVyKSBjb25zdAp7CiAgVUJvb2wgcmVzdWx0OwogIGlmICh0aGlzID09ICZvdGhlcikgcmVzdWx0ID0gVFJVRTsKICBlbHNlIHJlc3VsdCA9ICgoc3RyZW5ndGggPT0gb3RoZXIuc3RyZW5ndGgpICYmIChkZWNtcCA9PSBvdGhlci5kZWNtcCkpOwogIHJldHVybiByZXN1bHQ7Cn0KCmlubGluZSBVQm9vbApDb2xsYXRvcjo6b3BlcmF0b3IhPShjb25zdCBDb2xsYXRvciYgb3RoZXIpIGNvbnN0CnsKICBVQm9vbCByZXN1bHQ7CiAgcmVzdWx0ID0gISgqdGhpcyA9PSBvdGhlcik7CiAgcmV0dXJuIHJlc3VsdDsKfQoKaW5saW5lIENvbGxhdG9yOjpFQ29sbGF0aW9uU3RyZW5ndGggCkNvbGxhdG9yOjpnZXRTdHJlbmd0aCgpIGNvbnN0CnsKICByZXR1cm4gc3RyZW5ndGg7Cn0KCmlubGluZSBOb3JtYWxpemVyOjpFTW9kZQpDb2xsYXRvcjo6Z2V0RGVjb21wb3NpdGlvbigpIGNvbnN0CnsKICByZXR1cm4gZGVjbXA7Cn0KCgojZW5kaWYK