LyoKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiogICBDb3B5cmlnaHQgKEMpIDE5OTYtMjAwNCwgSW50ZXJuYXRpb25hbCBCdXNpbmVzcyBNYWNoaW5lcyAgICAgICAgICAgICAgICAgKgoqICAgQ29ycG9yYXRpb24gYW5kIG90aGVycy4gIEFsbCBSaWdodHMgUmVzZXJ2ZWQuICAgICAgICAgICAgICAgICAgICAgICAgICAgICoKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiovCgovKioKKiBGaWxlIGNvbGwuaAoqIAoqIENyZWF0ZWQgYnk6IEhlbGVuYSBTaGloCioKKiBNb2RpZmljYXRpb24gSGlzdG9yeToKKgoqICBEYXRlICAgICAgICBOYW1lICAgICAgICBEZXNjcmlwdGlvbgoqIDAyLzUvOTcgICAgICBhbGl1ICAgICAgICBNb2RpZmllZCBjcmVhdGVEZWZhdWx0IHRvIGxvYWQgY29sbGF0aW9uIGRhdGEgZnJvbQoqICAgICAgICAgICAgICAgICAgICAgICAgICBiaW5hcnkgZmlsZXMgd2hlbiBwb3NzaWJsZS4gIEFkZGVkIHJlbGF0ZWQgbWV0aG9kcwoqICAgICAgICAgICAgICAgICAgICAgICAgICBjcmVhdGVDb2xsYXRpb25Gcm9tRmlsZSwgY2hvcExvY2FsZSwgY3JlYXRlUGF0aE5hbWUuCiogMDIvMTEvOTcgICAgIGFsaXUgICAgICAgIEFkZGVkIG1lbWJlcnMgYWRkVG9DYWNoZSwgZmluZEluQ2FjaGUsIGFuZCBmZ0NhY2hlLgoqIDAyLzEyLzk3ICAgICBhbGl1ICAgICAgICBNb2RpZmllZCB0byBjcmVhdGUgb2JqZWN0cyBmcm9tIFJ1bGVCYXNlZENvbGxhdG9yIGNhY2hlLgoqICAgICAgICAgICAgICAgICAgICAgICAgICBNb3ZlZCBjYWNoZSBvdXQgb2YgQ29sbGF0aW9uIGNsYXNzLgoqIDAyLzEzLzk3ICAgICBhbGl1ICAgICAgICBNb3ZlZCBzZXZlcmFsIG1ldGhvZHMgb3V0IG9mIHRoaXMgY2xhc3MgYW5kIGludG8KKiAgICAgICAgICAgICAgICAgICAgICAgICAgUnVsZUJhc2VkQ29sbGF0b3IsIHdpdGggbW9kaWZpY2F0aW9ucy4gIE1vZGlmaWVkCiogICAgICAgICAgICAgICAgICAgICAgICAgIGNyZWF0ZURlZmF1bHQoKSB0byBjYWxsIG5ldyBSdWxlQmFzZWRDb2xsYXRvcihMb2NhbGUmKQoqICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdHJ1Y3Rvci4gIEdlbmVyYWwgY2xlYW4gdXAgYW5kIGRvY3VtZW50YXRpb24uCiogMDIvMjAvOTcgICAgIGhlbGVuYSAgICAgIEFkZGVkIGNsb25lLCBvcGVyYXRvcj09LCBvcGVyYXRvciE9LCBvcGVyYXRvcj0sIGNvcHkKKiAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3RydWN0b3IgYW5kIGdldER5bmFtaWNDbGFzc0lELgoqIDAzLzI1Lzk3ICAgICBoZWxlbmEgICAgICBVcGRhdGVkIHdpdGggcGxhdGZvcm0gaW5kZXBlbmRlbnQgZGF0YSB0eXBlcy4KKiAwNS8wNi85NyAgICAgaGVsZW5hICAgICAgQWRkZWQgbWVtb3J5IGFsbG9jYXRpb24gZXJyb3IgZGV0ZWN0aW9uLgoqIDA2LzIwLzk3ICAgICBoZWxlbmEgICAgICBKYXZhIGNsYXNzIG5hbWUgY2hhbmdlLgoqIDA5LzAzLzk3ICAgICBoZWxlbmEgICAgICBBZGRlZCBjcmVhdGVDb2xsYXRpb25LZXlWYWx1ZXMoKS4KKiAwMi8xMC85OCAgICAgZGFtaWJhICAgICAgQWRkZWQgY29tcGFyZSgpIHdpdGggbGVuZ3RoIGFzIHBhcmFtZXRlci4KKiAwNC8yMy85OSAgICAgc3RlcGhlbiAgICAgUmVtb3ZlZCBFRGVjb21wb3NpdGlvbk1vZGUsIG1lcmdlZCB3aXRoCiogICAgICAgICAgICAgICAgICAgICAgICAgIE5vcm1hbGl6ZXI6OkVNb2RlLgoqIDExLzAyLzk5ICAgICBoZWxlbmEgICAgICBDb2xsYXRvciBwZXJmb3JtYW5jZSBlbmhhbmNlbWVudHMuICBFbGltaW5hdGVzIHRoZSAKKiAgICAgICAgICAgICAgICAgICAgICAgICAgVW5pY29kZVN0cmluZyBjb25zdHJ1Y3Rpb24gYW5kIHNwZWNpYWwgY2FzZSBmb3IgTk9fT1AuCiogMTEvMjMvOTkgICAgIHNybCAgICAgICAgIE1vcmUgcGVyZm9ybWFuY2UgZW5oYW5jZW1lbnRzLiBJbmxpbmluZyBvZgoqICAgICAgICAgICAgICAgICAgICAgICAgICBjcml0aWNhbCBhY2Nlc3NvcnMuCiogMDUvMTUvMDAgICAgIGhlbGVuYSAgICAgIEFkZGVkIHZlcnNpb24gaW5mb3JtYXRpb24gQVBJLiAKKiAwMS8yOS8wMSAgICAgc3lud2VlICAgICAgTW9kaWZpZWQgaW50byBhIEMrKyB3cmFwcGVyIHdoaWNoIGNhbGxzIEMgYXBpcyAKKiAgICAgICAgICAgICAgICAgICAgICAgICAgKHVjb2xsLmgpLiAKKi8KCiNpZm5kZWYgQ09MTF9ICiNkZWZpbmUgQ09MTF9ICgojaW5jbHVkZSAidW5pY29kZS91dHlwZXMuaCIKCiNpZiAhVUNPTkZJR19OT19DT0xMQVRJT04KCiNpbmNsdWRlICJ1bmljb2RlL3VvYmplY3QuaCIKI2luY2x1ZGUgInVuaWNvZGUvdWNvbC5oIgojaW5jbHVkZSAidW5pY29kZS9ub3JtbHpyLmgiCiNpbmNsdWRlICJ1bmljb2RlL2xvY2lkLmgiCiNpbmNsdWRlICJ1bmljb2RlL3VuaXNldC5oIgoKVV9OQU1FU1BBQ0VfQkVHSU4KCmNsYXNzIFN0cmluZ0VudW1lcmF0aW9uOwoKLyoqCiAqIEBkcmFmdCBJQ1UgMi42CiAqLwp0eXBlZGVmIGNvbnN0IHZvaWQqIFVSZWdpc3RyeUtleTsKCi8qKgogKiBAZHJhZnQgSUNVIDIuNgogKi8KY2xhc3MgQ29sbGF0b3JGYWN0b3J5OwoKLyoqCiogQHN0YWJsZSBJQ1UgMi4wCiovCmNsYXNzIENvbGxhdGlvbktleTsKCi8qKgoqIFRoZSA8Y29kZT5Db2xsYXRvcjwvY29kZT4gY2xhc3MgcGVyZm9ybXMgbG9jYWxlLXNlbnNpdGl2ZSBzdHJpbmcgCiogY29tcGFyaXNvbi48YnI+CiogWW91IHVzZSB0aGlzIGNsYXNzIHRvIGJ1aWxkIHNlYXJjaGluZyBhbmQgc29ydGluZyByb3V0aW5lcyBmb3IgbmF0dXJhbCAKKiBsYW5ndWFnZSB0ZXh0Ljxicj4KKiA8ZW0+SW1wb3J0YW50OiA8L2VtPlRoZSBJQ1UgY29sbGF0aW9uIHNlcnZpY2UgaGFzIGJlZW4gcmVpbXBsZW1lbnRlZCAKKiBpbiBvcmRlciB0byBhY2hpZXZlIGJldHRlciBwZXJmb3JtYW5jZSBhbmQgVUNBIGNvbXBsaWFuY2UuIAoqIEZvciBkZXRhaWxzLCBzZWUgdGhlIAoqIDxhIGhyZWY9Imh0dHA6Ly9vc3Muc29mdHdhcmUuaWJtLmNvbS9jdnMvaWN1L35jaGVja291dH4vaWN1aHRtbC9kZXNpZ24vY29sbGF0aW9uL0lDVV9jb2xsYXRpb25fZGVzaWduLmh0bSI+CiogY29sbGF0aW9uIGRlc2lnbiBkb2N1bWVudDwvYT4uCiogPHA+CiogPGNvZGU+Q29sbGF0b3I8L2NvZGU+IGlzIGFuIGFic3RyYWN0IGJhc2UgY2xhc3MuIFN1YmNsYXNzZXMgaW1wbGVtZW50IAoqIHNwZWNpZmljIGNvbGxhdGlvbiBzdHJhdGVnaWVzLiBPbmUgc3ViY2xhc3MsIAoqIDxjb2RlPlJ1bGVCYXNlZENvbGxhdG9yPC9jb2RlPiwgaXMgY3VycmVudGx5IHByb3ZpZGVkIGFuZCBpcyBhcHBsaWNhYmxlIAoqIHRvIGEgd2lkZSBzZXQgb2YgbGFuZ3VhZ2VzLiBPdGhlciBzdWJjbGFzc2VzIG1heSBiZSBjcmVhdGVkIHRvIGhhbmRsZSBtb3JlIAoqIHNwZWNpYWxpemVkIG5lZWRzLgoqIDxwPgoqIExpa2Ugb3RoZXIgbG9jYWxlLXNlbnNpdGl2ZSBjbGFzc2VzLCB5b3UgY2FuIHVzZSB0aGUgc3RhdGljIGZhY3RvcnkgbWV0aG9kLCAKKiA8Y29kZT5jcmVhdGVJbnN0YW5jZTwvY29kZT4sIHRvIG9idGFpbiB0aGUgYXBwcm9wcmlhdGUgCiogPGNvZGU+Q29sbGF0b3I8L2NvZGU+IG9iamVjdCBmb3IgYSBnaXZlbiBsb2NhbGUuIFlvdSB3aWxsIG9ubHkgbmVlZCB0byAKKiBsb29rIGF0IHRoZSBzdWJjbGFzc2VzIG9mIDxjb2RlPkNvbGxhdG9yPC9jb2RlPiBpZiB5b3UgbmVlZCB0byAKKiB1bmRlcnN0YW5kIHRoZSBkZXRhaWxzIG9mIGEgcGFydGljdWxhciBjb2xsYXRpb24gc3RyYXRlZ3kgb3IgaWYgeW91IG5lZWQgdG8gCiogbW9kaWZ5IHRoYXQgc3RyYXRlZ3kuCiogPHA+CiogVGhlIGZvbGxvd2luZyBleGFtcGxlIHNob3dzIGhvdyB0byBjb21wYXJlIHR3byBzdHJpbmdzIHVzaW5nIHRoZSAKKiA8Y29kZT5Db2xsYXRvcjwvY29kZT4gZm9yIHRoZSBkZWZhdWx0IGxvY2FsZS4KKiA8YmxvY2txdW90ZT4KKiA8cHJlPgoqIFxjb2RlCiogLy8gQ29tcGFyZSB0d28gc3RyaW5ncyBpbiB0aGUgZGVmYXVsdCBsb2NhbGUKKiBVRXJyb3JDb2RlIHN1Y2Nlc3MgPSBVX1pFUk9fRVJST1I7CiogQ29sbGF0b3IqIG15Q29sbGF0b3IgPSBDb2xsYXRvcjo6Y3JlYXRlSW5zdGFuY2Uoc3VjY2Vzcyk7CiogaWYgKG15Q29sbGF0b3ItPmNvbXBhcmUoImFiYyIsICJBQkMiKSA8IDApCiogICBjb3V0IDw8ICJhYmMgaXMgbGVzcyB0aGFuIEFCQyIgPDwgZW5kbDsKKiBlbHNlCiogICBjb3V0IDw8ICJhYmMgaXMgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIEFCQyIgPDwgZW5kbDsKKiBcZW5kY29kZQoqIDwvcHJlPgoqIDwvYmxvY2txdW90ZT4KKiA8cD4KKiBZb3UgY2FuIHNldCBhIDxjb2RlPkNvbGxhdG9yPC9jb2RlPidzIDxlbT5zdHJlbmd0aDwvZW0+IHByb3BlcnR5IHRvIAoqIGRldGVybWluZSB0aGUgbGV2ZWwgb2YgZGlmZmVyZW5jZSBjb25zaWRlcmVkIHNpZ25pZmljYW50IGluIGNvbXBhcmlzb25zLiAKKiBGaXZlIHN0cmVuZ3RocyBhcmUgcHJvdmlkZWQ6IDxjb2RlPlBSSU1BUlk8L2NvZGU+LCA8Y29kZT5TRUNPTkRBUlk8L2NvZGU+LCAKKiA8Y29kZT5URVJUSUFSWTwvY29kZT4sIDxjb2RlPlFVQVRFUk5BUlk8L2NvZGU+IGFuZCA8Y29kZT5JREVOVElDQUw8L2NvZGU+LiBUaGUgZXhhY3QgYXNzaWdubWVudCBvZiAKKiBzdHJlbmd0aHMgdG8gbGFuZ3VhZ2UgZmVhdHVyZXMgaXMgbG9jYWxlIGRlcGVuZGFudC4gRm9yIGV4YW1wbGUsIGluIEN6ZWNoLCAKKiAiZSIgYW5kICJmIiBhcmUgY29uc2lkZXJlZCBwcmltYXJ5IGRpZmZlcmVuY2VzLCB3aGlsZSAiZSIgYW5kICJcdTAwRUEiIGFyZSAKKiBzZWNvbmRhcnkgZGlmZmVyZW5jZXMsICJlIiBhbmQgIkUiIGFyZSB0ZXJ0aWFyeSBkaWZmZXJlbmNlcyBhbmQgImUiIGFuZCAiZSIgCiogYXJlIGlkZW50aWNhbC4gVGhlIGZvbGxvd2luZyBzaG93cyBob3cgYm90aCBjYXNlIGFuZCBhY2NlbnRzIGNvdWxkIGJlIAoqIGlnbm9yZWQgZm9yIFVTIEVuZ2xpc2guCiogPGJsb2NrcXVvdGU+CiogPHByZT4KKiBcY29kZQoqIC8vR2V0IHRoZSBDb2xsYXRvciBmb3IgVVMgRW5nbGlzaCBhbmQgc2V0IGl0cyBzdHJlbmd0aCB0byBQUklNQVJZIAoqIFVFcnJvckNvZGUgc3VjY2VzcyA9IFVfWkVST19FUlJPUjsKKiBDb2xsYXRvciogdXNDb2xsYXRvciA9IAoqICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvbGxhdG9yOjpjcmVhdGVJbnN0YW5jZShMb2NhbGU6OlVTLCBzdWNjZXNzKTsKKiB1c0NvbGxhdG9yLT5zZXRTdHJlbmd0aChDb2xsYXRvcjo6UFJJTUFSWSk7CiogaWYgKHVzQ29sbGF0b3ItPmNvbXBhcmUoImFiYyIsICJBQkMiKSA9PSAwKQoqICAgY291dCA8PCAKKiAiJ2FiYycgYW5kICdBQkMnIHN0cmluZ3MgYXJlIGVxdWl2YWxlbnQgd2l0aCBzdHJlbmd0aCBQUklNQVJZIiA8PCAKKiBlbmRsOwoqIFxlbmRjb2RlCiogPC9wcmU+CiogPC9ibG9ja3F1b3RlPgoqIDxwPgoqIEZvciBjb21wYXJpbmcgc3RyaW5ncyBleGFjdGx5IG9uY2UsIHRoZSA8Y29kZT5jb21wYXJlPC9jb2RlPiBtZXRob2QgCiogcHJvdmlkZXMgdGhlIGJlc3QgcGVyZm9ybWFuY2UuIFdoZW4gc29ydGluZyBhIGxpc3Qgb2Ygc3RyaW5ncyBob3dldmVyLCBpdCAKKiBpcyBnZW5lcmFsbHkgbmVjZXNzYXJ5IHRvIGNvbXBhcmUgZWFjaCBzdHJpbmcgbXVsdGlwbGUgdGltZXMuIEluIHRoaXMgY2FzZSwgCiogc29ydCBrZXlzIHByb3ZpZGUgYmV0dGVyIHBlcmZvcm1hbmNlLiBUaGUgPGNvZGU+Z2V0U29ydEtleTwvY29kZT4gbWV0aG9kcyAKKiBjb252ZXJ0IGEgc3RyaW5nIHRvIGEgc2VyaWVzIG9mIGJ5dGVzIHRoYXQgY2FuIGJlIGNvbXBhcmVkIGJpdHdpc2UgYWdhaW5zdCAKKiBvdGhlciBzb3J0IGtleXMgdXNpbmcgPGNvZGU+c3RyY21wKCk8L2NvZGU+LiBTb3J0IGtleXMgYXJlIHdyaXR0ZW4gYXMgCiogemVyby10ZXJtaW5hdGVkIGJ5dGUgc3RyaW5ncy4gVGhleSBjb25zaXN0IG9mIHNldmVyYWwgc3Vic3RyaW5ncywgb25lIGZvciAKKiBlYWNoIGNvbGxhdGlvbiBzdHJlbmd0aCBsZXZlbCwgdGhhdCBhcmUgZGVsaW1pdGVkIGJ5IDB4MDEgYnl0ZXMuCiogSWYgdGhlIHN0cmluZyBjb2RlIHBvaW50cyBhcmUgYXBwZW5kZWQgZm9yIFVDT0xfSURFTlRJQ0FMLCB0aGVuIHRoZXkgYXJlIAoqIHByb2Nlc3NlZCBmb3IgY29ycmVjdCBjb2RlIHBvaW50IG9yZGVyIGNvbXBhcmlzb24gYW5kIG1heSBjb250YWluIDB4MDEgCiogYnl0ZXMgYnV0IG5vdCB6ZXJvIGJ5dGVzLgoqIDwvcD4KKiA8cD4KKiBBbiBvbGRlciBzZXQgb2YgQVBJcyByZXR1cm5zIGEgPGNvZGU+Q29sbGF0aW9uS2V5PC9jb2RlPiBvYmplY3QgdGhhdCB3cmFwcyAKKiB0aGUgc29ydCBrZXkgYnl0ZXMgaW5zdGVhZCBvZiByZXR1cm5pbmcgdGhlIGJ5dGVzIHRoZW1zZWx2ZXMuCiogSXRzIHVzZSBpcyBkZXByZWNhdGVkLCBidXQgaXQgaXMgc3RpbGwgYXZhaWxhYmxlIGZvciBjb21wYXRpYmlsaXR5IHdpdGggCiogSmF2YS4KKiA8L3A+CiogPHA+CiogPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiA8Y29kZT5Db2xsYXRvcjwvY29kZT5zIHdpdGggZGlmZmVyZW50IExvY2FsZSwKKiBhbmQgQ29sbGF0aW9uU3RyZW5ndGggc2V0dGluZ3Mgd2lsbCByZXR1cm4gZGlmZmVyZW50IHNvcnQgCiogb3JkZXJzIGZvciB0aGUgc2FtZSBzZXQgb2Ygc3RyaW5ncy4gTG9jYWxlcyBoYXZlIHNwZWNpZmljIGNvbGxhdGlvbiBydWxlcywgCiogYW5kIHRoZSB3YXkgaW4gd2hpY2ggc2Vjb25kYXJ5IGFuZCB0ZXJ0aWFyeSBkaWZmZXJlbmNlcyBhcmUgdGFrZW4gaW50byAKKiBhY2NvdW50LCBmb3IgZXhhbXBsZSwgd2lsbCByZXN1bHQgaW4gYSBkaWZmZXJlbnQgc29ydGluZyBvcmRlciBmb3Igc2FtZSAKKiBzdHJpbmdzLgoqIDwvcD4KKiBAc2VlICAgICAgICAgUnVsZUJhc2VkQ29sbGF0b3IKKiBAc2VlICAgICAgICAgQ29sbGF0aW9uS2V5CiogQHNlZSAgICAgICAgIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcgoqIEBzZWUgICAgICAgICBMb2NhbGUKKiBAc2VlICAgICAgICAgTm9ybWFsaXplcgoqIEB2ZXJzaW9uICAgICAyLjAgMTEvMTUvMDEKKi8KCmNsYXNzIFVfSTE4Tl9BUEkgQ29sbGF0b3IgOiBwdWJsaWMgVU9iamVjdCB7CnB1YmxpYzoKCiAgICAvLyBDb2xsYXRvciBwdWJsaWMgZW51bXMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAKICAgIC8qKgogICAgICogQmFzZSBsZXR0ZXIgcmVwcmVzZW50cyBhIHByaW1hcnkgZGlmZmVyZW5jZS4gU2V0IGNvbXBhcmlzb24gbGV2ZWwgdG8gCiAgICAgKiBQUklNQVJZIHRvIGlnbm9yZSBzZWNvbmRhcnkgYW5kIHRlcnRpYXJ5IGRpZmZlcmVuY2VzLjxicj4KICAgICAqIFVzZSB0aGlzIHRvIHNldCB0aGUgc3RyZW5ndGggb2YgYSBDb2xsYXRvciBvYmplY3QuPGJyPgogICAgICogRXhhbXBsZSBvZiBwcmltYXJ5IGRpZmZlcmVuY2UsICJhYmMiICZsdDsgImFiZCIKICAgICAqIAogICAgICogRGlhY3JpdGljYWwgZGlmZmVyZW5jZXMgb24gdGhlIHNhbWUgYmFzZSBsZXR0ZXIgcmVwcmVzZW50IGEgc2Vjb25kYXJ5CiAgICAgKiBkaWZmZXJlbmNlLiBTZXQgY29tcGFyaXNvbiBsZXZlbCB0byBTRUNPTkRBUlkgdG8gaWdub3JlIHRlcnRpYXJ5CiAgICAgKiBkaWZmZXJlbmNlcy4gVXNlIHRoaXMgdG8gc2V0IHRoZSBzdHJlbmd0aCBvZiBhIENvbGxhdG9yIG9iamVjdC48YnI+CiAgICAgKiBFeGFtcGxlIG9mIHNlY29uZGFyeSBkaWZmZXJlbmNlLCAi5CIgPj4gImEiLgogICAgICoKICAgICAqIFVwcGVyY2FzZSBhbmQgbG93ZXJjYXNlIHZlcnNpb25zIG9mIHRoZSBzYW1lIGNoYXJhY3RlciByZXByZXNlbnRzIGEKICAgICAqIHRlcnRpYXJ5IGRpZmZlcmVuY2UuICBTZXQgY29tcGFyaXNvbiBsZXZlbCB0byBURVJUSUFSWSB0byBpbmNsdWRlIGFsbCAKICAgICAqIGNvbXBhcmlzb24gZGlmZmVyZW5jZXMuIFVzZSB0aGlzIHRvIHNldCB0aGUgc3RyZW5ndGggb2YgYSBDb2xsYXRvcgogICAgICogb2JqZWN0Ljxicj4KICAgICAqIEV4YW1wbGUgb2YgdGVydGlhcnkgZGlmZmVyZW5jZSwgImFiYyIgJmx0OyZsdDsmbHQ7ICJBQkMiLgogICAgICoKICAgICAqIFR3byBjaGFyYWN0ZXJzIGFyZSBjb25zaWRlcmVkICJpZGVudGljYWwiIHdoZW4gdGhleSBoYXZlIHRoZSBzYW1lIHVuaWNvZGUgCiAgICAgKiBzcGVsbGluZ3MuPGJyPgogICAgICogRm9yIGV4YW1wbGUsICLkIiA9PSAi5CIuCiAgICAgKgogICAgICogVUNvbGxhdGlvblN0cmVuZ3RoIGlzIGFsc28gdXNlZCB0byBkZXRlcm1pbmUgdGhlIHN0cmVuZ3RoIG9mIHNvcnQga2V5cyAKICAgICAqIGdlbmVyYXRlZCBmcm9tIENvbGxhdG9yIG9iamVjdHMuCiAgICAgKiBAc3RhYmxlIElDVSAyLjAKICAgICAqLwogICAgZW51bSBFQ29sbGF0aW9uU3RyZW5ndGggCiAgICB7CiAgICAgICAgUFJJTUFSWSAgICA9IDAsCiAgICAgICAgU0VDT05EQVJZICA9IDEsIAogICAgICAgIFRFUlRJQVJZICAgPSAyLAogICAgICAgIFFVQVRFUk5BUlkgPSAzLAogICAgICAgIElERU5USUNBTCAgPSAxNQogICAgfTsKCiAgICAvKioKICAgICAqIExFU1MgaXMgcmV0dXJuZWQgaWYgc291cmNlIHN0cmluZyBpcyBjb21wYXJlZCB0byBiZSBsZXNzIHRoYW4gdGFyZ2V0CiAgICAgKiBzdHJpbmcgaW4gdGhlIGNvbXBhcmUoKSBtZXRob2QuCiAgICAgKiBFUVVBTCBpcyByZXR1cm5lZCBpZiBzb3VyY2Ugc3RyaW5nIGlzIGNvbXBhcmVkIHRvIGJlIGVxdWFsIHRvIHRhcmdldAogICAgICogc3RyaW5nIGluIHRoZSBjb21wYXJlKCkgbWV0aG9kLgogICAgICogR1JFQVRFUiBpcyByZXR1cm5lZCBpZiBzb3VyY2Ugc3RyaW5nIGlzIGNvbXBhcmVkIHRvIGJlIGdyZWF0ZXIgdGhhbgogICAgICogdGFyZ2V0IHN0cmluZyBpbiB0aGUgY29tcGFyZSgpIG1ldGhvZC4KICAgICAqIEBzZWUgQ29sbGF0b3IjY29tcGFyZQogICAgICogQGRlcHJlY2F0ZWQgSUNVIDIuNi4gVXNlIEMgZW51bSBVQ29sbGF0aW9uUmVzdWx0IGRlZmluZWQgaW4gdWNvbC5oCiAgICAgKi8KICAgIGVudW0gRUNvbXBhcmlzb25SZXN1bHQgCiAgICB7CiAgICAgICAgTEVTUyA9IC0xLAogICAgICAgIEVRVUFMID0gMCwKICAgICAgICBHUkVBVEVSID0gMQogICAgfTsKICAKICAgIC8vIENvbGxhdG9yIHB1YmxpYyBkZXN0cnVjdG9yIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgCiAgICAvKioKICAgICAqIERlc3RydWN0b3IKICAgICAqIEBzdGFibGUgSUNVIDIuMAogICAgICovCiAgICB2aXJ0dWFsIH5Db2xsYXRvcigpOwoKICAgIC8vIENvbGxhdG9yIHB1YmxpYyBtZXRob2RzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRydWUgaWYgIm90aGVyIiBpcyB0aGUgc2FtZSBhcyAidGhpcyIKICAgICAqIEBwYXJhbSBvdGhlciBDb2xsYXRvciBvYmplY3QgdG8gYmUgY29tcGFyZWQKICAgICAqIEByZXR1cm4gdHJ1ZSBpZiBvdGhlciBpcyB0aGUgc2FtZSBhcyB0aGlzLgogICAgICogQHN0YWJsZSBJQ1UgMi4wCiAgICAgKi8KICAgIHZpcnR1YWwgVUJvb2wgb3BlcmF0b3I9PShjb25zdCBDb2xsYXRvciYgb3RoZXIpIGNvbnN0OwoKICAgIC8qKgogICAgICogUmV0dXJucyB0cnVlIGlmICJvdGhlciIgaXMgbm90IHRoZSBzYW1lIGFzICJ0aGlzIi4KICAgICAqIEBwYXJhbSBvdGhlciBDb2xsYXRvciBvYmplY3QgdG8gYmUgY29tcGFyZWQKICAgICAqIEByZXR1cm4gdHJ1ZSBpZiBvdGhlciBpcyBub3QgdGhlIHNhbWUgYXMgdGhpcy4KICAgICAqIEBzdGFibGUgSUNVIDIuMAogICAgICovCiAgICB2aXJ0dWFsIFVCb29sIG9wZXJhdG9yIT0oY29uc3QgQ29sbGF0b3ImIG90aGVyKSBjb25zdDsKCiAgICAvKioKICAgICAqIE1ha2VzIGEgc2hhbGxvdyBjb3B5IG9mIHRoZSBjdXJyZW50IG9iamVjdC4KICAgICAqIEByZXR1cm4gYSBjb3B5IG9mIHRoaXMgb2JqZWN0CiAgICAgKiBAc3RhYmxlIElDVSAyLjAKICAgICAqLwogICAgdmlydHVhbCBDb2xsYXRvciogY2xvbmUodm9pZCkgY29uc3QgPSAwOwoKICAgIC8qKgogICAgICogQ3JlYXRlcyB0aGUgQ29sbGF0b3Igb2JqZWN0IGZvciB0aGUgY3VycmVudCBkZWZhdWx0IGxvY2FsZS4KICAgICAqIFRoZSBkZWZhdWx0IGxvY2FsZSBpcyBkZXRlcm1pbmVkIGJ5IExvY2FsZTo6Z2V0RGVmYXVsdC4KICAgICAqIFRoZSBVRXJyb3JDb2RlJiBlcnIgcGFyYW1ldGVyIGlzIHVzZWQgdG8gcmV0dXJuIHN0YXR1cyBpbmZvcm1hdGlvbiB0byB0aGUgdXNlci4KICAgICAqIFRvIGNoZWNrIHdoZXRoZXIgdGhlIGNvbnN0cnVjdGlvbiBzdWNjZWVkZWQgb3Igbm90LCB5b3Ugc2hvdWxkIGNoZWNrIHRoZSAKICAgICAqIHZhbHVlIG9mIFVfU1VDQ0VTUyhlcnIpLiAgSWYgeW91IHdpc2ggbW9yZSBkZXRhaWxlZCBpbmZvcm1hdGlvbiwgeW91IGNhbiAKICAgICAqIGNoZWNrIGZvciBpbmZvcm1hdGlvbmFsIGVycm9yIHJlc3VsdHMgd2hpY2ggc3RpbGwgaW5kaWNhdGUgc3VjY2Vzcy4KICAgICAqIFVfVVNJTkdfRkFMTEJBQ0tfRVJST1IgaW5kaWNhdGVzIHRoYXQgYSBmYWxsIGJhY2sgbG9jYWxlIHdhcyB1c2VkLiBGb3IKICAgICAqIGV4YW1wbGUsICdkZV9DSCcgd2FzIHJlcXVlc3RlZCwgYnV0IG5vdGhpbmcgd2FzIGZvdW5kIHRoZXJlLCBzbyAnZGUnIHdhcwogICAgICogdXNlZC4gVV9VU0lOR19ERUZBVUxUX0VSUk9SIGluZGljYXRlcyB0aGF0IHRoZSBkZWZhdWx0IGxvY2FsZSBkYXRhIHdhcwogICAgICogdXNlZDsgbmVpdGhlciB0aGUgcmVxdWVzdGVkIGxvY2FsZSBub3IgYW55IG9mIGl0cyBmYWxsIGJhY2sgbG9jYWxlcwogICAgICogY291bGQgYmUgZm91bmQuCiAgICAgKiBUaGUgY2FsbGVyIG93bnMgdGhlIHJldHVybmVkIG9iamVjdCBhbmQgaXMgcmVzcG9uc2libGUgZm9yIGRlbGV0aW5nIGl0LgogICAgICoKICAgICAqIEBwYXJhbSBlcnIgICAgdGhlIGVycm9yIGNvZGUgc3RhdHVzLgogICAgICogQHJldHVybiAgICAgICB0aGUgY29sbGF0aW9uIG9iamVjdCBvZiB0aGUgZGVmYXVsdCBsb2NhbGUuKGZvciBleGFtcGxlLCBlbl9VUykKICAgICAqIEBzZWUgTG9jYWxlI2dldERlZmF1bHQKICAgICAqIEBzdGFibGUgSUNVIDIuMAogICAgICovCiAgICBzdGF0aWMgQ29sbGF0b3IqIGNyZWF0ZUluc3RhbmNlKFVFcnJvckNvZGUmICBlcnIpOwoKICAgIC8qKgogICAgICogR2V0cyB0aGUgdGFibGUtYmFzZWQgY29sbGF0aW9uIG9iamVjdCBmb3IgdGhlIGRlc2lyZWQgbG9jYWxlLiBUaGUKICAgICAqIHJlc291cmNlIG9mIHRoZSBkZXNpcmVkIGxvY2FsZSB3aWxsIGJlIGxvYWRlZCBieSBSZXNvdXJjZUxvYWRlci4gCiAgICAgKiBMb2NhbGU6OkVOR0xJU0ggaXMgdGhlIGJhc2UgY29sbGF0aW9uIHRhYmxlIGFuZCBhbGwgb3RoZXIgbGFuZ3VhZ2VzIGFyZSAKICAgICAqIGJ1aWx0IG9uIHRvcCBvZiBpdCB3aXRoIGFkZGl0aW9uYWwgbGFuZ3VhZ2Utc3BlY2lmaWMgbW9kaWZpY2F0aW9ucy4KICAgICAqIFRoZSBVRXJyb3JDb2RlJiBlcnIgcGFyYW1ldGVyIGlzIHVzZWQgdG8gcmV0dXJuIHN0YXR1cyBpbmZvcm1hdGlvbiB0byB0aGUgdXNlci4KICAgICAqIFRvIGNoZWNrIHdoZXRoZXIgdGhlIGNvbnN0cnVjdGlvbiBzdWNjZWVkZWQgb3Igbm90LCB5b3Ugc2hvdWxkIGNoZWNrCiAgICAgKiB0aGUgdmFsdWUgb2YgVV9TVUNDRVNTKGVycikuICBJZiB5b3Ugd2lzaCBtb3JlIGRldGFpbGVkIGluZm9ybWF0aW9uLCB5b3UKICAgICAqIGNhbiBjaGVjayBmb3IgaW5mb3JtYXRpb25hbCBlcnJvciByZXN1bHRzIHdoaWNoIHN0aWxsIGluZGljYXRlIHN1Y2Nlc3MuCiAgICAgKiBVX1VTSU5HX0ZBTExCQUNLX0VSUk9SIGluZGljYXRlcyB0aGF0IGEgZmFsbCBiYWNrIGxvY2FsZSB3YXMgdXNlZC4gIEZvcgogICAgICogZXhhbXBsZSwgJ2RlX0NIJyB3YXMgcmVxdWVzdGVkLCBidXQgbm90aGluZyB3YXMgZm91bmQgdGhlcmUsIHNvICdkZScgd2FzCiAgICAgKiB1c2VkLiAgVV9VU0lOR19ERUZBVUxUX0VSUk9SIGluZGljYXRlcyB0aGF0IHRoZSBkZWZhdWx0IGxvY2FsZSBkYXRhIHdhcwogICAgICogdXNlZDsgbmVpdGhlciB0aGUgcmVxdWVzdGVkIGxvY2FsZSBub3IgYW55IG9mIGl0cyBmYWxsIGJhY2sgbG9jYWxlcwogICAgICogY291bGQgYmUgZm91bmQuCiAgICAgKiBUaGUgY2FsbGVyIG93bnMgdGhlIHJldHVybmVkIG9iamVjdCBhbmQgaXMgcmVzcG9uc2libGUgZm9yIGRlbGV0aW5nIGl0LgogICAgICogQHBhcmFtIGxvYyAgICBUaGUgbG9jYWxlIElEIGZvciB3aGljaCB0byBvcGVuIGEgY29sbGF0b3IuCiAgICAgKiBAcGFyYW0gZXJyICAgIHRoZSBlcnJvciBjb2RlIHN0YXR1cy4KICAgICAqIEByZXR1cm4gICAgICAgdGhlIGNyZWF0ZWQgdGFibGUtYmFzZWQgY29sbGF0aW9uIG9iamVjdCBiYXNlZCBvbiB0aGUgZGVzaXJlZAogICAgICogICAgICAgICAgICAgICBsb2NhbGUuCiAgICAgKiBAc2VlIExvY2FsZQogICAgICogQHNlZSBSZXNvdXJjZUxvYWRlcgogICAgICogQHN0YWJsZSBJQ1UgMi4yCiAgICAgKi8KICAgIHN0YXRpYyBDb2xsYXRvciogY3JlYXRlSW5zdGFuY2UoY29uc3QgTG9jYWxlJiBsb2MsIFVFcnJvckNvZGUmIGVycik7CgojaWZkZWYgVV9VU0VfQ09MTEFUSU9OX09CU09MRVRFXzJfNgogICAgLyoqCiAgICAgKiBDcmVhdGUgYSBDb2xsYXRvciB3aXRoIGEgc3BlY2lmaWMgdmVyc2lvbi4KICAgICAqIFRoaXMgaXMgdGhlIHNhbWUgYXMgY3JlYXRlSW5zdGFuY2UobG9jLCBlcnIpIGV4Y2VwdCB0aGF0IGdldFZlcnNpb24oKSBvZgogICAgICogdGhlIHJldHVybmVkIG9iamVjdCBpcyBndWFyYW50ZWVkIHRvIGJlIHRoZSBzYW1lIGFzIHRoZSB2ZXJzaW9uCiAgICAgKiBwYXJhbWV0ZXIuCiAgICAgKiBUaGlzIGlzIGRlc2lnbmVkIHRvIGJlIHVzZWQgdG8gb3BlbiB0aGUgc2FtZSBjb2xsYXRvciBmb3IgYSBnaXZlbgogICAgICogbG9jYWxlIGV2ZW4gd2hlbiBJQ1UgaXMgdXBkYXRlZC4KICAgICAqIFRoZSBzYW1lIGxvY2FsZSBhbmQgdmVyc2lvbiBndWFyYW50ZWVzIHRoZSBzYW1lIHNvcnQga2V5cyBhbmQKICAgICAqIGNvbXBhcmlzb24gcmVzdWx0cy4KICAgICAqIDxwPgogICAgICogTm90ZTogdGhpcyBBUEkgd2lsbCBiZSByZW1vdmVkIGluIGEgZnV0dXJlIHJlbGVhc2UuICBVc2UKICAgICAqIDx0dD5jcmVhdGVJbnN0YW5jZShjb25zdCBMb2NhbGUmLCBVRXJyb3JDb2RlJikgaW5zdGVhZC48L3R0PjwvcD4KICAgICAqCiAgICAgKiBAcGFyYW0gbG9jIFRoZSBsb2NhbGUgSUQgZm9yIHdoaWNoIHRvIG9wZW4gYSBjb2xsYXRvci4KICAgICAqIEBwYXJhbSB2ZXJzaW9uIFRoZSByZXF1ZXN0ZWQgY29sbGF0b3IgdmVyc2lvbi4KICAgICAqIEBwYXJhbSBlcnIgQSByZWZlcmVuY2UgdG8gYSBVRXJyb3JDb2RlLAogICAgICogICAgICAgICAgICBtdXN0IG5vdCBpbmRpY2F0ZSBhIGZhaWx1cmUgYmVmb3JlIGNhbGxpbmcgdGhpcyBmdW5jdGlvbi4KICAgICAqIEByZXR1cm4gQSBwb2ludGVyIHRvIGEgQ29sbGF0b3IsIG9yIDAgaWYgYW4gZXJyb3Igb2NjdXJyZWQKICAgICAqICAgICAgICAgb3IgYSBjb2xsYXRvciB3aXRoIHRoZSByZXF1ZXN0ZWQgdmVyc2lvbiBpcyBub3QgYXZhaWxhYmxlLgogICAgICoKICAgICAqIEBzZWUgZ2V0VmVyc2lvbgogICAgICogQG9ic29sZXRlIElDVSAyLjYKICAgICAqLwogICAgc3RhdGljIENvbGxhdG9yICpjcmVhdGVJbnN0YW5jZShjb25zdCBMb2NhbGUgJmxvYywgVVZlcnNpb25JbmZvIHZlcnNpb24sIFVFcnJvckNvZGUgJmVycik7CiNlbmRpZgoKICAgIC8qKgogICAgICogVGhlIGNvbXBhcmlzb24gZnVuY3Rpb24gY29tcGFyZXMgdGhlIGNoYXJhY3RlciBkYXRhIHN0b3JlZCBpbiB0d28KICAgICAqIGRpZmZlcmVudCBzdHJpbmdzLiBSZXR1cm5zIGluZm9ybWF0aW9uIGFib3V0IHdoZXRoZXIgYSBzdHJpbmcgaXMgbGVzcyAKICAgICAqIHRoYW4sIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byBhbm90aGVyIHN0cmluZy4KICAgICAqIEBwYXJhbSBzb3VyY2UgdGhlIHNvdXJjZSBzdHJpbmcgdG8gYmUgY29tcGFyZWQgd2l0aC4KICAgICAqIEBwYXJhbSB0YXJnZXQgdGhlIHN0cmluZyB0aGF0IGlzIHRvIGJlIGNvbXBhcmVkIHdpdGggdGhlIHNvdXJjZSBzdHJpbmcuCiAgICAgKiBAcmV0dXJuIFJldHVybnMgYSBieXRlIHZhbHVlLiBHUkVBVEVSIGlmIHNvdXJjZSBpcyBncmVhdGVyCiAgICAgKiB0aGFuIHRhcmdldDsgRVFVQUwgaWYgc291cmNlIGlzIGVxdWFsIHRvIHRhcmdldDsgTEVTUyBpZiBzb3VyY2UgaXMgbGVzcwogICAgICogdGhhbiB0YXJnZXQKICAgICAqIEBkZXByZWNhdGVkIElDVSAyLjYgdXNlIHRoZSBvdmVybG9hZCB3aXRoIFVFcnJvckNvZGUgJgogICAgICovCiAgICB2aXJ0dWFsIEVDb21wYXJpc29uUmVzdWx0IGNvbXBhcmUoY29uc3QgVW5pY29kZVN0cmluZyYgc291cmNlLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBVbmljb2RlU3RyaW5nJiB0YXJnZXQpIGNvbnN0OwoKICAgIC8qKgogICAgICogVGhlIGNvbXBhcmlzb24gZnVuY3Rpb24gY29tcGFyZXMgdGhlIGNoYXJhY3RlciBkYXRhIHN0b3JlZCBpbiB0d28KICAgICAqIGRpZmZlcmVudCBzdHJpbmdzLiBSZXR1cm5zIGluZm9ybWF0aW9uIGFib3V0IHdoZXRoZXIgYSBzdHJpbmcgaXMgbGVzcyAKICAgICAqIHRoYW4sIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byBhbm90aGVyIHN0cmluZy4KICAgICAqIEBwYXJhbSBzb3VyY2UgdGhlIHNvdXJjZSBzdHJpbmcgdG8gYmUgY29tcGFyZWQgd2l0aC4KICAgICAqIEBwYXJhbSB0YXJnZXQgdGhlIHN0cmluZyB0aGF0IGlzIHRvIGJlIGNvbXBhcmVkIHdpdGggdGhlIHNvdXJjZSBzdHJpbmcuCiAgICAgKiBAcGFyYW0gc3RhdHVzIHBvc3NpYmxlIGVycm9yIGNvZGUKICAgICAqIEByZXR1cm4gUmV0dXJucyBhbiBlbnVtIHZhbHVlLiBVQ09MX0dSRUFURVIgaWYgc291cmNlIGlzIGdyZWF0ZXIKICAgICAqIHRoYW4gdGFyZ2V0OyBVQ09MX0VRVUFMIGlmIHNvdXJjZSBpcyBlcXVhbCB0byB0YXJnZXQ7IFVDT0xfTEVTUyBpZiBzb3VyY2UgaXMgbGVzcwogICAgICogdGhhbiB0YXJnZXQKICAgICAqIEBkcmFmdCBJQ1UgMi42CiAgICAgKi8KICAgIHZpcnR1YWwgVUNvbGxhdGlvblJlc3VsdCBjb21wYXJlKGNvbnN0IFVuaWNvZGVTdHJpbmcmIHNvdXJjZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVW5pY29kZVN0cmluZyYgdGFyZ2V0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUgJnN0YXR1cykgY29uc3QgPSAwOwoKICAgIC8qKgogICAgICogRG9lcyB0aGUgc2FtZSB0aGluZyBhcyBjb21wYXJlIGJ1dCBsaW1pdHMgdGhlIGNvbXBhcmlzb24gdG8gYSBzcGVjaWZpZWQgCiAgICAgKiBsZW5ndGgKICAgICAqIEBwYXJhbSBzb3VyY2UgdGhlIHNvdXJjZSBzdHJpbmcgdG8gYmUgY29tcGFyZWQgd2l0aC4KICAgICAqIEBwYXJhbSB0YXJnZXQgdGhlIHN0cmluZyB0aGF0IGlzIHRvIGJlIGNvbXBhcmVkIHdpdGggdGhlIHNvdXJjZSBzdHJpbmcuCiAgICAgKiBAcGFyYW0gbGVuZ3RoIHRoZSBsZW5ndGggdGhlIGNvbXBhcmlzb24gaXMgbGltaXRlZCB0bwogICAgICogQHJldHVybiBSZXR1cm5zIGEgYnl0ZSB2YWx1ZS4gR1JFQVRFUiBpZiBzb3VyY2UgKHVwIHRvIHRoZSBzcGVjaWZpZWQgCiAgICAgKiAgICAgICAgIGxlbmd0aCkgaXMgZ3JlYXRlciB0aGFuIHRhcmdldDsgRVFVQUwgaWYgc291cmNlICh1cCB0byBzcGVjaWZpZWQgCiAgICAgKiAgICAgICAgIGxlbmd0aCkgaXMgZXF1YWwgdG8gdGFyZ2V0OyBMRVNTIGlmIHNvdXJjZSAodXAgdG8gdGhlIHNwZWNpZmllZCAKICAgICAqICAgICAgICAgbGVuZ3RoKSBpcyBsZXNzICB0aGFuIHRhcmdldC4gICAKICAgICAqIEBkZXByZWNhdGVkIElDVSAyLjYgdXNlIHRoZSBvdmVybG9hZCB3aXRoIFVFcnJvckNvZGUgJgogICAgICovCiAgICB2aXJ0dWFsIEVDb21wYXJpc29uUmVzdWx0IGNvbXBhcmUoY29uc3QgVW5pY29kZVN0cmluZyYgc291cmNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFVuaWNvZGVTdHJpbmcmIHRhcmdldCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQzMl90IGxlbmd0aCkgY29uc3Q7CiAgICAKICAgIC8qKgogICAgICogRG9lcyB0aGUgc2FtZSB0aGluZyBhcyBjb21wYXJlIGJ1dCBsaW1pdHMgdGhlIGNvbXBhcmlzb24gdG8gYSBzcGVjaWZpZWQgCiAgICAgKiBsZW5ndGgKICAgICAqIEBwYXJhbSBzb3VyY2UgdGhlIHNvdXJjZSBzdHJpbmcgdG8gYmUgY29tcGFyZWQgd2l0aC4KICAgICAqIEBwYXJhbSB0YXJnZXQgdGhlIHN0cmluZyB0aGF0IGlzIHRvIGJlIGNvbXBhcmVkIHdpdGggdGhlIHNvdXJjZSBzdHJpbmcuCiAgICAgKiBAcGFyYW0gbGVuZ3RoIHRoZSBsZW5ndGggdGhlIGNvbXBhcmlzb24gaXMgbGltaXRlZCB0bwogICAgICogQHBhcmFtIHN0YXR1cyBwb3NzaWJsZSBlcnJvciBjb2RlCiAgICAgKiBAcmV0dXJuIFJldHVybnMgYW4gZW51bSB2YWx1ZS4gVUNPTF9HUkVBVEVSIGlmIHNvdXJjZSAodXAgdG8gdGhlIHNwZWNpZmllZCAKICAgICAqICAgICAgICAgbGVuZ3RoKSBpcyBncmVhdGVyIHRoYW4gdGFyZ2V0OyBVQ09MX0VRVUFMIGlmIHNvdXJjZSAodXAgdG8gc3BlY2lmaWVkIAogICAgICogICAgICAgICBsZW5ndGgpIGlzIGVxdWFsIHRvIHRhcmdldDsgVUNPTF9MRVNTIGlmIHNvdXJjZSAodXAgdG8gdGhlIHNwZWNpZmllZCAKICAgICAqICAgICAgICAgbGVuZ3RoKSBpcyBsZXNzICB0aGFuIHRhcmdldC4gICAKICAgICAqIEBkcmFmdCBJQ1UgMi42CiAgICAgKi8KICAgIHZpcnR1YWwgVUNvbGxhdGlvblJlc3VsdCBjb21wYXJlKGNvbnN0IFVuaWNvZGVTdHJpbmcmIHNvdXJjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBVbmljb2RlU3RyaW5nJiB0YXJnZXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50MzJfdCBsZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSAmc3RhdHVzKSBjb25zdCA9IDA7CgogICAgLyoqCiAgICAgKiBUaGUgY29tcGFyaXNvbiBmdW5jdGlvbiBjb21wYXJlcyB0aGUgY2hhcmFjdGVyIGRhdGEgc3RvcmVkIGluIHR3bwogICAgICogZGlmZmVyZW50IHN0cmluZyBhcnJheXMuIFJldHVybnMgaW5mb3JtYXRpb24gYWJvdXQgd2hldGhlciBhIHN0cmluZyBhcnJheSAKICAgICAqIGlzIGxlc3MgdGhhbiwgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIGFub3RoZXIgc3RyaW5nIGFycmF5LgogICAgICogQHBhcmFtIHNvdXJjZSB0aGUgc291cmNlIHN0cmluZyBhcnJheSB0byBiZSBjb21wYXJlZCB3aXRoLgogICAgICogQHBhcmFtIHNvdXJjZUxlbmd0aCB0aGUgbGVuZ3RoIG9mIHRoZSBzb3VyY2Ugc3RyaW5nIGFycmF5LiAgSWYgdGhpcyB2YWx1ZQogICAgICogICAgICAgIGlzIGVxdWFsIHRvIC0xLCB0aGUgc3RyaW5nIGFycmF5IGlzIG51bGwtdGVybWluYXRlZC4KICAgICAqIEBwYXJhbSB0YXJnZXQgdGhlIHN0cmluZyB0aGF0IGlzIHRvIGJlIGNvbXBhcmVkIHdpdGggdGhlIHNvdXJjZSBzdHJpbmcuCiAgICAgKiBAcGFyYW0gdGFyZ2V0TGVuZ3RoIHRoZSBsZW5ndGggb2YgdGhlIHRhcmdldCBzdHJpbmcgYXJyYXkuICBJZiB0aGlzIHZhbHVlCiAgICAgKiAgICAgICAgaXMgZXF1YWwgdG8gLTEsIHRoZSBzdHJpbmcgYXJyYXkgaXMgbnVsbC10ZXJtaW5hdGVkLgogICAgICogQHJldHVybiBSZXR1cm5zIGEgYnl0ZSB2YWx1ZS4gR1JFQVRFUiBpZiBzb3VyY2UgaXMgZ3JlYXRlciB0aGFuIHRhcmdldDsgCiAgICAgKiAgICAgICAgIEVRVUFMIGlmIHNvdXJjZSBpcyBlcXVhbCB0byB0YXJnZXQ7IExFU1MgaWYgc291cmNlIGlzIGxlc3MgdGhhbiAKICAgICAqICAgICAgICAgdGFyZ2V0CiAgICAgKiBAZGVwcmVjYXRlZCBJQ1UgMi42IHVzZSB0aGUgb3ZlcmxvYWQgd2l0aCBVRXJyb3JDb2RlICYKICAgICAqLwogICAgdmlydHVhbCBFQ29tcGFyaXNvblJlc3VsdCBjb21wYXJlKGNvbnN0IFVDaGFyKiBzb3VyY2UsIGludDMyX3Qgc291cmNlTGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFVDaGFyKiB0YXJnZXQsIGludDMyX3QgdGFyZ2V0TGVuZ3RoKSAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdDsKCiAgICAvKioKICAgICAqIFRoZSBjb21wYXJpc29uIGZ1bmN0aW9uIGNvbXBhcmVzIHRoZSBjaGFyYWN0ZXIgZGF0YSBzdG9yZWQgaW4gdHdvCiAgICAgKiBkaWZmZXJlbnQgc3RyaW5nIGFycmF5cy4gUmV0dXJucyBpbmZvcm1hdGlvbiBhYm91dCB3aGV0aGVyIGEgc3RyaW5nIGFycmF5IAogICAgICogaXMgbGVzcyB0aGFuLCBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gYW5vdGhlciBzdHJpbmcgYXJyYXkuCiAgICAgKiBAcGFyYW0gc291cmNlIHRoZSBzb3VyY2Ugc3RyaW5nIGFycmF5IHRvIGJlIGNvbXBhcmVkIHdpdGguCiAgICAgKiBAcGFyYW0gc291cmNlTGVuZ3RoIHRoZSBsZW5ndGggb2YgdGhlIHNvdXJjZSBzdHJpbmcgYXJyYXkuICBJZiB0aGlzIHZhbHVlCiAgICAgKiAgICAgICAgaXMgZXF1YWwgdG8gLTEsIHRoZSBzdHJpbmcgYXJyYXkgaXMgbnVsbC10ZXJtaW5hdGVkLgogICAgICogQHBhcmFtIHRhcmdldCB0aGUgc3RyaW5nIHRoYXQgaXMgdG8gYmUgY29tcGFyZWQgd2l0aCB0aGUgc291cmNlIHN0cmluZy4KICAgICAqIEBwYXJhbSB0YXJnZXRMZW5ndGggdGhlIGxlbmd0aCBvZiB0aGUgdGFyZ2V0IHN0cmluZyBhcnJheS4gIElmIHRoaXMgdmFsdWUKICAgICAqICAgICAgICBpcyBlcXVhbCB0byAtMSwgdGhlIHN0cmluZyBhcnJheSBpcyBudWxsLXRlcm1pbmF0ZWQuCiAgICAgKiBAcGFyYW0gc3RhdHVzIHBvc3NpYmxlIGVycm9yIGNvZGUKICAgICAqIEByZXR1cm4gUmV0dXJucyBhbiBlbnVtIHZhbHVlLiBVQ09MX0dSRUFURVIgaWYgc291cmNlIGlzIGdyZWF0ZXIKICAgICAqIHRoYW4gdGFyZ2V0OyBVQ09MX0VRVUFMIGlmIHNvdXJjZSBpcyBlcXVhbCB0byB0YXJnZXQ7IFVDT0xfTEVTUyBpZiBzb3VyY2UgaXMgbGVzcwogICAgICogdGhhbiB0YXJnZXQKICAgICAqIEBkcmFmdCBJQ1UgMi42CiAgICAgKi8KICAgIHZpcnR1YWwgVUNvbGxhdGlvblJlc3VsdCBjb21wYXJlKGNvbnN0IFVDaGFyKiBzb3VyY2UsIGludDMyX3Qgc291cmNlTGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFVDaGFyKiB0YXJnZXQsIGludDMyX3QgdGFyZ2V0TGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUgJnN0YXR1cykgY29uc3QgPSAwOwoKICAgIC8qKiAKICAgICAqIFRyYW5zZm9ybXMgdGhlIHN0cmluZyBpbnRvIGEgc2VyaWVzIG9mIGNoYXJhY3RlcnMgdGhhdCBjYW4gYmUgY29tcGFyZWQKICAgICAqIHdpdGggQ29sbGF0aW9uS2V5Ojpjb21wYXJlVG8uIEl0IGlzIG5vdCBwb3NzaWJsZSB0byByZXN0b3JlIHRoZSBvcmlnaW5hbAogICAgICogc3RyaW5nIGZyb20gdGhlIGNoYXJzIGluIHRoZSBzb3J0IGtleS4gIFRoZSBnZW5lcmF0ZWQgc29ydCBrZXkgaGFuZGxlcyAKICAgICAqIG9ubHkgYSBsaW1pdGVkIG51bWJlciBvZiBpZ25vcmFibGUgY2hhcmFjdGVycy4KICAgICAqIDxwPlVzZSBDb2xsYXRpb25LZXk6OmVxdWFscyBvciBDb2xsYXRpb25LZXk6OmNvbXBhcmUgdG8gY29tcGFyZSB0aGUKICAgICAqIGdlbmVyYXRlZCBzb3J0IGtleXMuCiAgICAgKiBJZiB0aGUgc291cmNlIHN0cmluZyBpcyBudWxsLCBhIG51bGwgY29sbGF0aW9uIGtleSB3aWxsIGJlIHJldHVybmVkLgogICAgICogQHBhcmFtIHNvdXJjZSB0aGUgc291cmNlIHN0cmluZyB0byBiZSB0cmFuc2Zvcm1lZCBpbnRvIGEgc29ydCBrZXkuCiAgICAgKiBAcGFyYW0ga2V5IHRoZSBjb2xsYXRpb24ga2V5IHRvIGJlIGZpbGxlZCBpbgogICAgICogQHBhcmFtIHN0YXR1cyB0aGUgZXJyb3IgY29kZSBzdGF0dXMuCiAgICAgKiBAcmV0dXJuIHRoZSBjb2xsYXRpb24ga2V5IG9mIHRoZSBzdHJpbmcgYmFzZWQgb24gdGhlIGNvbGxhdGlvbiBydWxlcy4KICAgICAqIEBzZWUgQ29sbGF0aW9uS2V5I2NvbXBhcmUKICAgICAqIEBkZXByZWNhdGVkIElDVSAyLjggVXNlIGdldFNvcnRLZXkoLi4uKSBpbnN0ZWFkCiAgICAgKi8KICAgIHZpcnR1YWwgQ29sbGF0aW9uS2V5JiBnZXRDb2xsYXRpb25LZXkoY29uc3QgVW5pY29kZVN0cmluZyYgIHNvdXJjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29sbGF0aW9uS2V5JiBrZXksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cykgY29uc3QgPSAwOwoKICAgIC8qKiAKICAgICAqIFRyYW5zZm9ybXMgdGhlIHN0cmluZyBpbnRvIGEgc2VyaWVzIG9mIGNoYXJhY3RlcnMgdGhhdCBjYW4gYmUgY29tcGFyZWQKICAgICAqIHdpdGggQ29sbGF0aW9uS2V5Ojpjb21wYXJlVG8uIEl0IGlzIG5vdCBwb3NzaWJsZSB0byByZXN0b3JlIHRoZSBvcmlnaW5hbAogICAgICogc3RyaW5nIGZyb20gdGhlIGNoYXJzIGluIHRoZSBzb3J0IGtleS4gIFRoZSBnZW5lcmF0ZWQgc29ydCBrZXkgaGFuZGxlcyAKICAgICAqIG9ubHkgYSBsaW1pdGVkIG51bWJlciBvZiBpZ25vcmFibGUgY2hhcmFjdGVycy4KICAgICAqIDxwPlVzZSBDb2xsYXRpb25LZXk6OmVxdWFscyBvciBDb2xsYXRpb25LZXk6OmNvbXBhcmUgdG8gY29tcGFyZSB0aGUKICAgICAqIGdlbmVyYXRlZCBzb3J0IGtleXMuCiAgICAgKiA8cD5JZiB0aGUgc291cmNlIHN0cmluZyBpcyBudWxsLCBhIG51bGwgY29sbGF0aW9uIGtleSB3aWxsIGJlIHJldHVybmVkLgogICAgICogQHBhcmFtIHNvdXJjZSB0aGUgc291cmNlIHN0cmluZyB0byBiZSB0cmFuc2Zvcm1lZCBpbnRvIGEgc29ydCBrZXkuCiAgICAgKiBAcGFyYW0gc291cmNlTGVuZ3RoIGxlbmd0aCBvZiB0aGUgY29sbGF0aW9uIGtleQogICAgICogQHBhcmFtIGtleSB0aGUgY29sbGF0aW9uIGtleSB0byBiZSBmaWxsZWQgaW4KICAgICAqIEBwYXJhbSBzdGF0dXMgdGhlIGVycm9yIGNvZGUgc3RhdHVzLgogICAgICogQHJldHVybiB0aGUgY29sbGF0aW9uIGtleSBvZiB0aGUgc3RyaW5nIGJhc2VkIG9uIHRoZSBjb2xsYXRpb24gcnVsZXMuCiAgICAgKiBAc2VlIENvbGxhdGlvbktleSNjb21wYXJlCiAgICAgKiBAZGVwcmVjYXRlZCBJQ1UgMi44IFVzZSBnZXRTb3J0S2V5KC4uLikgaW5zdGVhZAogICAgICovCiAgICB2aXJ0dWFsIENvbGxhdGlvbktleSYgZ2V0Q29sbGF0aW9uS2V5KGNvbnN0IFVDaGFyKnNvdXJjZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludDMyX3Qgc291cmNlTGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb2xsYXRpb25LZXkmIGtleSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYgc3RhdHVzKSBjb25zdCA9IDA7CiAgICAvKioKICAgICAqIEdlbmVyYXRlcyB0aGUgaGFzaCBjb2RlIGZvciB0aGUgY29sbGF0aW9uIG9iamVjdAogICAgICogQHN0YWJsZSBJQ1UgMi4wCiAgICAgKi8KICAgIHZpcnR1YWwgaW50MzJfdCBoYXNoQ29kZSh2b2lkKSBjb25zdCA9IDA7CgogICAgLyoqCiAgICAgKiBHZXRzIHRoZSBsb2NhbGUgb2YgdGhlIENvbGxhdG9yCiAgICAgKgogICAgICogQHBhcmFtIHR5cGUgY2FuIGJlIGVpdGhlciByZXF1ZXN0ZWQsIHZhbGlkIG9yIGFjdHVhbCBsb2NhbGUuIEZvciBtb3JlCiAgICAgKiAgICAgICAgICAgICBpbmZvcm1hdGlvbiBzZWUgdGhlIGRlZmluaXRpb24gb2YgVUxvY0RhdGFMb2NhbGVUeXBlIGluCiAgICAgKiAgICAgICAgICAgICB1bG9jLmgKICAgICAqIEBwYXJhbSBzdGF0dXMgdGhlIGVycm9yIGNvZGUgc3RhdHVzLgogICAgICogQHJldHVybiBsb2NhbGUgd2hlcmUgdGhlIGNvbGxhdGlvbiBkYXRhIGxpdmVzLiBJZiB0aGUgY29sbGF0b3IKICAgICAqICAgICAgICAgd2FzIGluc3RhbnRpYXRlZCBmcm9tIHJ1bGVzLCBsb2NhbGUgaXMgZW1wdHkuCiAgICAgKiBAZGVwcmVjYXRlZCBJQ1UgMi44IFRoaXMgQVBJIGlzIHVuZGVyIGNvbnNpZGVyYXRpb24gZm9yIHJldmlzaW9uCiAgICAgKiBpbiBJQ1UgMy4wLgogICAgICovCiAgICB2aXJ0dWFsIGNvbnN0IExvY2FsZSBnZXRMb2NhbGUoVUxvY0RhdGFMb2NhbGVUeXBlIHR5cGUsIFVFcnJvckNvZGUmIHN0YXR1cykgY29uc3QgPSAwOwoKICAgIC8qKgogICAgICogQ29udmVuaWVuY2UgbWV0aG9kIGZvciBjb21wYXJpbmcgdHdvIHN0cmluZ3MgYmFzZWQgb24gdGhlIGNvbGxhdGlvbiBydWxlcy4KICAgICAqIEBwYXJhbSBzb3VyY2UgdGhlIHNvdXJjZSBzdHJpbmcgdG8gYmUgY29tcGFyZWQgd2l0aC4KICAgICAqIEBwYXJhbSB0YXJnZXQgdGhlIHRhcmdldCBzdHJpbmcgdG8gYmUgY29tcGFyZWQgd2l0aC4KICAgICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgZmlyc3Qgc3RyaW5nIGlzIGdyZWF0ZXIgdGhhbiB0aGUgc2Vjb25kIG9uZSwKICAgICAqICAgICAgICAgYWNjb3JkaW5nIHRvIHRoZSBjb2xsYXRpb24gcnVsZXMuIGZhbHNlLCBvdGhlcndpc2UuCiAgICAgKiBAc2VlIENvbGxhdG9yI2NvbXBhcmUKICAgICAqIEBzdGFibGUgSUNVIDIuMAogICAgICovCiAgICBVQm9vbCBncmVhdGVyKGNvbnN0IFVuaWNvZGVTdHJpbmcmIHNvdXJjZSwgY29uc3QgVW5pY29kZVN0cmluZyYgdGFyZ2V0KSAKICAgICAgICAgICAgICAgICAgY29uc3Q7CgogICAgLyoqCiAgICAgKiBDb252ZW5pZW5jZSBtZXRob2QgZm9yIGNvbXBhcmluZyB0d28gc3RyaW5ncyBiYXNlZCBvbiB0aGUgY29sbGF0aW9uIHJ1bGVzLgogICAgICogQHBhcmFtIHNvdXJjZSB0aGUgc291cmNlIHN0cmluZyB0byBiZSBjb21wYXJlZCB3aXRoLgogICAgICogQHBhcmFtIHRhcmdldCB0aGUgdGFyZ2V0IHN0cmluZyB0byBiZSBjb21wYXJlZCB3aXRoLgogICAgICogQHJldHVybiB0cnVlIGlmIHRoZSBmaXJzdCBzdHJpbmcgaXMgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIHRoZSBzZWNvbmQgCiAgICAgKiAgICAgICAgIG9uZSwgYWNjb3JkaW5nIHRvIHRoZSBjb2xsYXRpb24gcnVsZXMuIGZhbHNlLCBvdGhlcndpc2UuCiAgICAgKiBAc2VlIENvbGxhdG9yI2NvbXBhcmUKICAgICAqIEBzdGFibGUgSUNVIDIuMAogICAgICovCiAgICBVQm9vbCBncmVhdGVyT3JFcXVhbChjb25zdCBVbmljb2RlU3RyaW5nJiBzb3VyY2UsIAogICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVW5pY29kZVN0cmluZyYgdGFyZ2V0KSBjb25zdDsKCiAgICAvKioKICAgICAqIENvbnZlbmllbmNlIG1ldGhvZCBmb3IgY29tcGFyaW5nIHR3byBzdHJpbmdzIGJhc2VkIG9uIHRoZSBjb2xsYXRpb24gcnVsZXMuCiAgICAgKiBAcGFyYW0gc291cmNlIHRoZSBzb3VyY2Ugc3RyaW5nIHRvIGJlIGNvbXBhcmVkIHdpdGguCiAgICAgKiBAcGFyYW0gdGFyZ2V0IHRoZSB0YXJnZXQgc3RyaW5nIHRvIGJlIGNvbXBhcmVkIHdpdGguCiAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIHN0cmluZ3MgYXJlIGVxdWFsIGFjY29yZGluZyB0byB0aGUgY29sbGF0aW9uIHJ1bGVzLiAgCiAgICAgKiAgICAgICAgIGZhbHNlLCBvdGhlcndpc2UuCiAgICAgKiBAc2VlIENvbGxhdG9yI2NvbXBhcmUKICAgICAqIEBzdGFibGUgSUNVIDIuMAogICAgICovCiAgICBVQm9vbCBlcXVhbHMoY29uc3QgVW5pY29kZVN0cmluZyYgc291cmNlLCBjb25zdCBVbmljb2RlU3RyaW5nJiB0YXJnZXQpIGNvbnN0OwoKICAgIC8qKgogICAgICogRGV0ZXJtaW5lcyB0aGUgbWluaW11bSBzdHJlbmd0aCB0aGF0IHdpbGwgYmUgdXNlIGluIGNvbXBhcmlzb24gb3IKICAgICAqIHRyYW5zZm9ybWF0aW9uLgogICAgICogPHA+RS5nLiB3aXRoIHN0cmVuZ3RoID09IFNFQ09OREFSWSwgdGhlIHRlcnRpYXJ5IGRpZmZlcmVuY2UgaXMgaWdub3JlZAogICAgICogPHA+RS5nLiB3aXRoIHN0cmVuZ3RoID09IFBSSU1BUlksIHRoZSBzZWNvbmRhcnkgYW5kIHRlcnRpYXJ5IGRpZmZlcmVuY2UKICAgICAqIGFyZSBpZ25vcmVkLgogICAgICogQHJldHVybiB0aGUgY3VycmVudCBjb21wYXJpc29uIGxldmVsLgogICAgICogQHNlZSBDb2xsYXRvciNzZXRTdHJlbmd0aAogICAgICogQGRlcHJlY2F0ZWQgSUNVIDIuNiBVc2UgZ2V0QXR0cmlidXRlKFVDT0xfU1RSRU5HVEguLi4pIGluc3RlYWQKICAgICAqLwogICAgdmlydHVhbCBFQ29sbGF0aW9uU3RyZW5ndGggZ2V0U3RyZW5ndGgodm9pZCkgY29uc3QgPSAwOwoKICAgIC8qKgogICAgICogU2V0cyB0aGUgbWluaW11bSBzdHJlbmd0aCB0byBiZSB1c2VkIGluIGNvbXBhcmlzb24gb3IgdHJhbnNmb3JtYXRpb24uCiAgICAgKiA8cD5FeGFtcGxlIG9mIHVzZToKICAgICAqIDxwcmU+CiAgICAgKiAgXGNvZGUKICAgICAqICBVRXJyb3JDb2RlIHN0YXR1cyA9IFVfWkVST19FUlJPUjsKICAgICAqICBDb2xsYXRvcipteUNvbGxhdGlvbiA9IENvbGxhdG9yOjpjcmVhdGVJbnN0YW5jZShMb2NhbGU6OlVTLCAKICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdHVzKTsKICAgICAqICBpZiAoVV9GQUlMVVJFKHN0YXR1cykpIHJldHVybjsKICAgICAqICBteUNvbGxhdGlvbi0+c2V0U3RyZW5ndGgoQ29sbGF0b3I6OlBSSU1BUlkpOwogICAgICogIC8vIHJlc3VsdCB3aWxsIGJlICJhYmMiID09ICJBQkMiCiAgICAgKiAgLy8gdGVydGlhcnkgZGlmZmVyZW5jZXMgd2lsbCBiZSBpZ25vcmVkCiAgICAgKiAgQ29sbGF0b3I6OkNvbXBhcmlzb25SZXN1bHQgcmVzdWx0ID0gbXlDb2xsYXRpb24tPmNvbXBhcmUoImFiYyIsIAogICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJBQkMiKTsKICAgICAqIFxlbmRjb2RlIAogICAgICogPC9wcmU+CiAgICAgKiBAc2VlIENvbGxhdG9yI2dldFN0cmVuZ3RoCiAgICAgKiBAcGFyYW0gbmV3U3RyZW5ndGggdGhlIG5ldyBjb21wYXJpc29uIGxldmVsLgogICAgICogQGRlcHJlY2F0ZWQgSUNVIDIuNiBVc2Ugc2V0QXR0cmlidXRlKFVDT0xfU1RSRU5HVEguLi4pIGluc3RlYWQKICAgICAqLwogICAgdmlydHVhbCB2b2lkIHNldFN0cmVuZ3RoKEVDb2xsYXRpb25TdHJlbmd0aCBuZXdTdHJlbmd0aCkgPSAwOwoKICAgIC8qKgogICAgICogR2V0IG5hbWUgb2YgdGhlIG9iamVjdCBmb3IgdGhlIGRlc2lyZWQgTG9jYWxlLCBpbiB0aGUgZGVzaXJlZCBsYW5nYXVnZQogICAgICogQHBhcmFtIG9iamVjdExvY2FsZSBtdXN0IGJlIGZyb20gZ2V0QXZhaWxhYmxlTG9jYWxlcwogICAgICogQHBhcmFtIGRpc3BsYXlMb2NhbGUgc3BlY2lmaWVzIHRoZSBkZXNpcmVkIGxvY2FsZSBmb3Igb3V0cHV0CiAgICAgKiBAcGFyYW0gbmFtZSB0aGUgZmlsbC1pbiBwYXJhbWV0ZXIgb2YgdGhlIHJldHVybiB2YWx1ZQogICAgICogQHJldHVybiBkaXNwbGF5LWFibGUgbmFtZSBvZiB0aGUgb2JqZWN0IGZvciB0aGUgb2JqZWN0IGxvY2FsZSBpbiB0aGUKICAgICAqICAgICAgICAgZGVzaXJlZCBsYW5ndWFnZQogICAgICogQHN0YWJsZSBJQ1UgMi4wCiAgICAgKi8KICAgIHN0YXRpYyBVbmljb2RlU3RyaW5nJiBnZXREaXNwbGF5TmFtZShjb25zdCBMb2NhbGUmIG9iamVjdExvY2FsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBMb2NhbGUmIGRpc3BsYXlMb2NhbGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVW5pY29kZVN0cmluZyYgbmFtZSk7CgogICAgLyoqCiAgICAqIEdldCBuYW1lIG9mIHRoZSBvYmplY3QgZm9yIHRoZSBkZXNpcmVkIExvY2FsZSwgaW4gdGhlIGxhbmdhdWdlIG9mIHRoZQogICAgKiBkZWZhdWx0IGxvY2FsZS4KICAgICogQHBhcmFtIG9iamVjdExvY2FsZSBtdXN0IGJlIGZyb20gZ2V0QXZhaWxhYmxlTG9jYWxlcwogICAgKiBAcGFyYW0gbmFtZSB0aGUgZmlsbC1pbiBwYXJhbWV0ZXIgb2YgdGhlIHJldHVybiB2YWx1ZQogICAgKiBAcmV0dXJuIG5hbWUgb2YgdGhlIG9iamVjdCBmb3IgdGhlIGRlc2lyZWQgbG9jYWxlIGluIHRoZSBkZWZhdWx0IGxhbmd1YWdlCiAgICAqIEBzdGFibGUgSUNVIDIuMAogICAgKi8KICAgIHN0YXRpYyBVbmljb2RlU3RyaW5nJiBnZXREaXNwbGF5TmFtZShjb25zdCBMb2NhbGUmIG9iamVjdExvY2FsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVbmljb2RlU3RyaW5nJiBuYW1lKTsKCiAgICAvKioKICAgICAqIEdldCB0aGUgc2V0IG9mIExvY2FsZXMgZm9yIHdoaWNoIENvbGxhdGlvbnMgYXJlIGluc3RhbGxlZC4KICAgICAqCiAgICAgKiA8cD5Ob3RlIHRoaXMgZG9lcyBub3QgaW5jbHVkZSBsb2NhbGVzIHN1cHBvcnRlZCBieSByZWdpc3RlcmVkIGNvbGxhdG9ycy4KICAgICAqIElmIGNvbGxhdG9ycyBtaWdodCBoYXZlIGJlZW4gcmVnaXN0ZXJlZCwgdXNlIHRoZSBvdmVybG9hZCBvZiBnZXRBdmFpbGFibGVMb2NhbGVzCiAgICAgKiB0aGF0IHJldHVybnMgYSBTdHJpbmdFbnVtZXJhdGlvbi48L3A+CiAgICAgKgogICAgICogQHBhcmFtIGNvdW50IHRoZSBvdXRwdXQgcGFyYW1ldGVyIG9mIG51bWJlciBvZiBlbGVtZW50cyBpbiB0aGUgbG9jYWxlIGxpc3QKICAgICAqIEByZXR1cm4gdGhlIGxpc3Qgb2YgYXZhaWxhYmxlIGxvY2FsZXMgZm9yIHdoaWNoIGNvbGxhdGlvbnMgYXJlIGluc3RhbGxlZAogICAgICogQHN0YWJsZSBJQ1UgMi4wCiAgICAgKi8KICAgIHN0YXRpYyBjb25zdCBMb2NhbGUqIGdldEF2YWlsYWJsZUxvY2FsZXMoaW50MzJfdCYgY291bnQpOwoKICAgIC8qKgogICAgICogUmV0dXJuIGEgU3RyaW5nRW51bWVyYXRpb24gb3ZlciB0aGUgbG9jYWxlcyBhdmFpbGFibGUgYXQgdGhlIHRpbWUgb2YgdGhlIGNhbGwsIAogICAgICogaW5jbHVkaW5nIHJlZ2lzdGVyZWQgbG9jYWxlcy4gIElmIGEgc2V2ZXJlIGVycm9yIG9jY3VycyAoc3VjaCBhcyBvdXQgb2YgbWVtb3J5CiAgICAgKiBjb25kaXRpb24pIHRoaXMgd2lsbCByZXR1cm4gbnVsbC4gSWYgdGhlcmUgaXMgbm8gbG9jYWxlIGRhdGEsIGFuIGVtcHR5IGVudW1lcmF0aW9uCiAgICAgKiB3aWxsIGJlIHJldHVybmVkLgogICAgICogQHJldHVybiBhIFN0cmluZ0VudW1lcmF0aW9uIG92ZXIgdGhlIGxvY2FsZXMgYXZhaWxhYmxlIGF0IHRoZSB0aW1lIG9mIHRoZSBjYWxsCiAgICAgKiBAZHJhZnQgSUNVIDIuNgogICAgICovCiAgICBzdGF0aWMgU3RyaW5nRW51bWVyYXRpb24qIGdldEF2YWlsYWJsZUxvY2FsZXModm9pZCk7CgogICAgLyoqCiAgICAgKiBDcmVhdGUgYSBzdHJpbmcgZW51bWVyYXRvciBvZiBhbGwgcG9zc2libGUga2V5d29yZHMgdGhhdCBhcmUgcmVsZXZhbnQgdG8KICAgICAqIGNvbGxhdGlvbi4gQXQgdGhpcyBwb2ludCwgdGhlIG9ubHkgcmVjb2duaXplZCBrZXl3b3JkIGZvciB0aGlzCiAgICAgKiBzZXJ2aWNlIGlzICJjb2xsYXRpb24iLgogICAgICogQHBhcmFtIHN0YXR1cyBpbnB1dC1vdXRwdXQgZXJyb3IgY29kZQogICAgICogQHJldHVybiBhIHN0cmluZyBlbnVtZXJhdGlvbiBvdmVyIGxvY2FsZSBzdHJpbmdzLiBUaGUgY2FsbGVyIGlzCiAgICAgKiByZXNwb25zaWJsZSBmb3IgY2xvc2luZyB0aGUgcmVzdWx0LgogICAgICogQGRyYWZ0IElDVSAzLjAKICAgICAqLwogICAgc3RhdGljIFN0cmluZ0VudW1lcmF0aW9uKiBnZXRLZXl3b3JkcyhVRXJyb3JDb2RlJiBzdGF0dXMpOwoKICAgIC8qKgogICAgICogR2l2ZW4gYSBrZXl3b3JkLCBjcmVhdGUgYSBzdHJpbmcgZW51bWVyYXRpb24gb2YgYWxsIHZhbHVlcwogICAgICogZm9yIHRoYXQga2V5d29yZCB0aGF0IGFyZSBjdXJyZW50bHkgaW4gdXNlLgogICAgICogQHBhcmFtIGtleXdvcmQgYSBwYXJ0aWN1bGFyIGtleXdvcmQgYXMgZW51bWVyYXRlZCBieQogICAgICogdWNvbF9nZXRLZXl3b3Jkcy4gSWYgYW55IG90aGVyIGtleXdvcmQgaXMgcGFzc2VkIGluLCBzdGF0dXMgaXMgc2V0CiAgICAgKiB0byBVX0lMTEVHQUxfQVJHVU1FTlRfRVJST1IuCiAgICAgKiBAcGFyYW0gc3RhdHVzIGlucHV0LW91dHB1dCBlcnJvciBjb2RlCiAgICAgKiBAcmV0dXJuIGEgc3RyaW5nIGVudW1lcmF0aW9uIG92ZXIgY29sbGF0aW9uIGtleXdvcmQgdmFsdWVzLCBvciBOVUxMCiAgICAgKiB1cG9uIGVycm9yLiBUaGUgY2FsbGVyIGlzIHJlc3BvbnNpYmxlIGZvciBkZWxldGluZyB0aGUgcmVzdWx0LgogICAgICogQGRyYWZ0IElDVSAzLjAKICAgICAqLwogICAgc3RhdGljIFN0cmluZ0VudW1lcmF0aW9uKiBnZXRLZXl3b3JkVmFsdWVzKGNvbnN0IGNoYXIgKmtleXdvcmQsIFVFcnJvckNvZGUmIHN0YXR1cyk7CiAgICAKICAgIC8qKgogICAgICogUmV0dXJuIHRoZSBmdW5jdGlvbmFsbHkgZXF1aXZhbGVudCBsb2NhbGUgZm9yIHRoZSBnaXZlbgogICAgICogcmVxdWVzdGVkIGxvY2FsZSwgd2l0aCByZXNwZWN0IHRvIGdpdmVuIGtleXdvcmQsIGZvciB0aGUKICAgICAqIGNvbGxhdGlvbiBzZXJ2aWNlLiAgSWYgdHdvIGxvY2FsZXMgcmV0dXJuIHRoZSBzYW1lIHJlc3VsdCwgdGhlbgogICAgICogY29sbGF0b3JzIGluc3RhbnRpYXRlZCBmb3IgdGhlc2UgbG9jYWxlcyB3aWxsIGJlaGF2ZQogICAgICogZXF1aXZhbGVudGx5LiAgVGhlIGNvbnZlcnNlIGlzIG5vdCBhbHdheXMgdHJ1ZTsgdHdvIGNvbGxhdG9ycwogICAgICogbWF5IGluIGZhY3QgYmUgZXF1aXZhbGVudCwgYnV0IHJldHVybiBkaWZmZXJlbnQgcmVzdWx0cywgZHVlIHRvCiAgICAgKiBpbnRlcm5hbCBkZXRhaWxzLiAgVGhlIHJldHVybiByZXN1bHQgaGFzIG5vIG90aGVyIG1lYW5pbmcgdGhhbgogICAgICogdGhhdCBzdGF0ZWQgYWJvdmUsIGFuZCBpbXBsaWVzIG5vdGhpbmcgYXMgdG8gdGhlIHJlbGF0aW9uc2hpcAogICAgICogYmV0d2VlbiB0aGUgdHdvIGxvY2FsZXMuICBUaGlzIGlzIGludGVuZGVkIGZvciB1c2UgYnkKICAgICAqIGFwcGxpY2F0aW9ucyB3aG8gd2lzaCB0byBjYWNoZSBjb2xsYXRvcnMsIG9yIG90aGVyd2lzZSByZXVzZQogICAgICogY29sbGF0b3JzIHdoZW4gcG9zc2libGUuICBUaGUgZnVuY3Rpb25hbCBlcXVpdmFsZW50IG1heSBjaGFuZ2UKICAgICAqIG92ZXIgdGltZS4gIEZvciBtb3JlIGluZm9ybWF0aW9uLCBwbGVhc2Ugc2VlIHRoZSA8YQogICAgICogaHJlZj0iaHR0cDovL29zcy5zb2Z0d2FyZS5pYm0uY29tL2ljdS91c2VyZ3VpZGUvbG9jYWxlLmh0bWwjc2VydmljZXMiPgogICAgICogTG9jYWxlcyBhbmQgU2VydmljZXM8L2E+IHNlY3Rpb24gb2YgdGhlIElDVSBVc2VyIEd1aWRlLgogICAgICogQHBhcmFtIGtleXdvcmQgYSBwYXJ0aWN1bGFyIGtleXdvcmQgYXMgZW51bWVyYXRlZCBieQogICAgICogdWNvbF9nZXRLZXl3b3Jkcy4KICAgICAqIEBwYXJhbSBsb2NhbGUgdGhlIHJlcXVlc3RlZCBsb2NhbGUKICAgICAqIEBwYXJhbSBpc0F2YWlsYWJsZSByZWZlcmVuY2UgdG8gYSBmaWxsaW4gcGFyYW1ldGVyIHRoYXQKICAgICAqIGluZGljYXRlcyB3aGV0aGVyIHRoZSByZXF1ZXN0ZWQgbG9jYWxlIHdhcyAnYXZhaWxhYmxlJyB0byB0aGUKICAgICAqIGNvbGxhdGlvbiBzZXJ2aWNlLiBBIGxvY2FsZSBpcyBkZWZpbmVkIGFzICdhdmFpbGFibGUnIGlmIGl0CiAgICAgKiBwaHlzaWNhbGx5IGV4aXN0cyB3aXRoaW4gdGhlIGNvbGxhdGlvbiBsb2NhbGUgZGF0YS4KICAgICAqIEBwYXJhbSBzdGF0dXMgcmVmZXJlbmNlIHRvIGlucHV0LW91dHB1dCBlcnJvciBjb2RlCiAgICAgKiBAcmV0dXJuIHRoZSBmdW5jdGlvbmFsbHkgZXF1aXZhbGVudCBjb2xsYXRpb24gbG9jYWxlLCBvciB0aGUgcm9vdAogICAgICogbG9jYWxlIHVwb24gZXJyb3IuCiAgICAgKiBAZHJhZnQgSUNVIDMuMAogICAgICovCiAgICBzdGF0aWMgTG9jYWxlIGdldEZ1bmN0aW9uYWxFcXVpdmFsZW50KGNvbnN0IGNoYXIqIGtleXdvcmQsIGNvbnN0IExvY2FsZSYgbG9jYWxlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVQm9vbCYgaXNBdmFpbGFibGUsIFVFcnJvckNvZGUmIHN0YXR1cyk7CgogICAgLyoqCiAgICAgKiBSZWdpc3RlciBhIG5ldyBDb2xsYXRvci4gIFRoZSBjb2xsYXRvciB3aWxsIGJlIGFkb3B0ZWQuCiAgICAgKiBAcGFyYW0gdG9BZG9wdCB0aGUgQ29sbGF0b3IgaW5zdGFuY2UgdG8gYmUgYWRvcHRlZAogICAgICogQHBhcmFtIGxvY2FsZSB0aGUgbG9jYWxlIHdpdGggd2hpY2ggdGhlIGNvbGxhdG9yIHdpbGwgYmUgYXNzb2NpYXRlZAogICAgICogQHBhcmFtIHN0YXR1cyB0aGUgaW4vb3V0IHN0YXR1cyBjb2RlLCBubyBzcGVjaWFsIG1lYW5pbmdzIGFyZSBhc3NpZ25lZAogICAgICogQHJldHVybiBhIHJlZ2lzdHJ5IGtleSB0aGF0IGNhbiBiZSB1c2VkIHRvIHVucmVnaXN0ZXIgdGhpcyBjb2xsYXRvcgogICAgICogQGRyYWZ0IElDVSAyLjYKICAgICAqLwogICAgc3RhdGljIFVSZWdpc3RyeUtleSByZWdpc3Rlckluc3RhbmNlKENvbGxhdG9yKiB0b0Fkb3B0LCBjb25zdCBMb2NhbGUmIGxvY2FsZSwgVUVycm9yQ29kZSYgc3RhdHVzKTsKCiAgICAvKioKICAgICAqIFJlZ2lzdGVyIGEgbmV3IENvbGxhdG9yRmFjdG9yeS4gIFRoZSBmYWN0b3J5IHdpbGwgYmUgYWRvcHRlZC4KICAgICAqIEBwYXJhbSB0b0Fkb3B0IHRoZSBDb2xsYXRvckZhY3RvcnkgaW5zdGFuY2UgdG8gYmUgYWRvcHRlZAogICAgICogQHBhcmFtIHN0YXR1cyB0aGUgaW4vb3V0IHN0YXR1cyBjb2RlLCBubyBzcGVjaWFsIG1lYW5pbmdzIGFyZSBhc3NpZ25lZAogICAgICogQHJldHVybiBhIHJlZ2lzdHJ5IGtleSB0aGF0IGNhbiBiZSB1c2VkIHRvIHVucmVnaXN0ZXIgdGhpcyBjb2xsYXRvcgogICAgICogQGRyYWZ0IElDVSAyLjYKICAgICAqLwogICAgc3RhdGljIFVSZWdpc3RyeUtleSByZWdpc3RlckZhY3RvcnkoQ29sbGF0b3JGYWN0b3J5KiB0b0Fkb3B0LCBVRXJyb3JDb2RlJiBzdGF0dXMpOwoKICAgIC8qKgogICAgICogVW5yZWdpc3RlciBhIHByZXZpb3VzbHktcmVnaXN0ZXJlZCBDb2xsYXRvciBvciBDb2xsYXRvckZhY3RvcnkKICAgICAqIHVzaW5nIHRoZSBrZXkgcmV0dXJuZWQgZnJvbSB0aGUgcmVnaXN0ZXIgY2FsbC4gIEtleSBiZWNvbWVzCiAgICAgKiBpbnZhbGlkIGFmdGVyIGEgc3VjY2Vzc2Z1bCBjYWxsIGFuZCBzaG91bGQgbm90IGJlIHVzZWQgYWdhaW4uCiAgICAgKiBUaGUgb2JqZWN0IGNvcnJlc3BvbmRpbmcgdG8gdGhlIGtleSB3aWxsIGJlIGRlbGV0ZWQuCiAgICAgKiBAcGFyYW0ga2V5IHRoZSByZWdpc3RyeSBrZXkgcmV0dXJuZWQgYnkgYSBwcmV2aW91cyBjYWxsIHRvIHJlZ2lzdGVySW5zdGFuY2UKICAgICAqIEBwYXJhbSBzdGF0dXMgdGhlIGluL291dCBzdGF0dXMgY29kZSwgbm8gc3BlY2lhbCBtZWFuaW5ncyBhcmUgYXNzaWduZWQKICAgICAqIEByZXR1cm4gVFJVRSBpZiB0aGUgY29sbGF0b3IgZm9yIHRoZSBrZXkgd2FzIHN1Y2Nlc3NmdWxseSB1bnJlZ2lzdGVyZWQKICAgICAqIEBkcmFmdCBJQ1UgMi42IAogICAgICovCiAgICBzdGF0aWMgVUJvb2wgdW5yZWdpc3RlcihVUmVnaXN0cnlLZXkga2V5LCBVRXJyb3JDb2RlJiBzdGF0dXMpOwoKICAgIC8qKgogICAgICogR2V0cyB0aGUgdmVyc2lvbiBpbmZvcm1hdGlvbiBmb3IgYSBDb2xsYXRvci4gCiAgICAgKiBAcGFyYW0gaW5mbyB0aGUgdmVyc2lvbiAjIGluZm9ybWF0aW9uLCB0aGUgcmVzdWx0IHdpbGwgYmUgZmlsbGVkIGluCiAgICAgKiBAc3RhYmxlIElDVSAyLjAKICAgICAqLwogICAgdmlydHVhbCB2b2lkIGdldFZlcnNpb24oVVZlcnNpb25JbmZvIGluZm8pIGNvbnN0ID0gMDsKCiAgICAvKioKICAgICAqIFJldHVybnMgYSB1bmlxdWUgY2xhc3MgSUQgUE9MWU1PUlBISUNBTExZLiBQdXJlIHZpcnR1YWwgbWV0aG9kLgogICAgICogVGhpcyBtZXRob2QgaXMgdG8gaW1wbGVtZW50IGEgc2ltcGxlIHZlcnNpb24gb2YgUlRUSSwgc2luY2Ugbm90IGFsbCBDKysgCiAgICAgKiBjb21waWxlcnMgc3VwcG9ydCBnZW51aW5lIFJUVEkuIFBvbHltb3JwaGljIG9wZXJhdG9yPT0oKSBhbmQgY2xvbmUoKSAKICAgICAqIG1ldGhvZHMgY2FsbCB0aGlzIG1ldGhvZC4KICAgICAqIEByZXR1cm4gVGhlIGNsYXNzIElEIGZvciB0aGlzIG9iamVjdC4gQWxsIG9iamVjdHMgb2YgYSBnaXZlbiBjbGFzcyBoYXZlIAogICAgICogICAgICAgICB0aGUgc2FtZSBjbGFzcyBJRC4gIE9iamVjdHMgb2Ygb3RoZXIgY2xhc3NlcyBoYXZlIGRpZmZlcmVudCBjbGFzcyAKICAgICAqICAgICAgICAgSURzLgogICAgICogQHN0YWJsZSBJQ1UgMi4wCiAgICAgKi8KICAgIHZpcnR1YWwgVUNsYXNzSUQgZ2V0RHluYW1pY0NsYXNzSUQodm9pZCkgY29uc3QgPSAwOwoKICAgIC8qKgogICAgICogVW5pdmVyc2FsIGF0dHJpYnV0ZSBzZXR0ZXIKICAgICAqIEBwYXJhbSBhdHRyIGF0dHJpYnV0ZSB0eXBlIAogICAgICogQHBhcmFtIHZhbHVlIGF0dHJpYnV0ZSB2YWx1ZQogICAgICogQHBhcmFtIHN0YXR1cyB0byBpbmRpY2F0ZSB3aGV0aGVyIHRoZSBvcGVyYXRpb24gd2VudCBvbiBzbW9vdGhseSBvciAKICAgICAqICAgICAgICB0aGVyZSB3ZXJlIGVycm9ycwogICAgICogQHN0YWJsZSBJQ1UgMi4yCiAgICAgKi8KICAgIHZpcnR1YWwgdm9pZCBzZXRBdHRyaWJ1dGUoVUNvbEF0dHJpYnV0ZSBhdHRyLCBVQ29sQXR0cmlidXRlVmFsdWUgdmFsdWUsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlICZzdGF0dXMpID0gMDsKCiAgICAvKioKICAgICAqIFVuaXZlcnNhbCBhdHRyaWJ1dGUgZ2V0dGVyCiAgICAgKiBAcGFyYW0gYXR0ciBhdHRyaWJ1dGUgdHlwZQogICAgICogQHBhcmFtIHN0YXR1cyB0byBpbmRpY2F0ZSB3aGV0aGVyIHRoZSBvcGVyYXRpb24gd2VudCBvbiBzbW9vdGhseSBvciAKICAgICAqICAgICAgICB0aGVyZSB3ZXJlIGVycm9ycwogICAgICogQHJldHVybiBhdHRyaWJ1dGUgdmFsdWUKICAgICAqIEBzdGFibGUgSUNVIDIuMgogICAgICovCiAgICB2aXJ0dWFsIFVDb2xBdHRyaWJ1dGVWYWx1ZSBnZXRBdHRyaWJ1dGUoVUNvbEF0dHJpYnV0ZSBhdHRyLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlICZzdGF0dXMpID0gMDsKCiAgICAvKiogCiAgICAgKiBTZXRzIHRoZSB2YXJpYWJsZSB0b3AgdG8gYSBjb2xsYXRpb24gZWxlbWVudCB2YWx1ZSBvZiBhIHN0cmluZyBzdXBwbGllZC4gCiAgICAgKiBAcGFyYW0gdmFyVG9wIG9uZSBvciBtb3JlIChpZiBjb250cmFjdGlvbikgVUNoYXJzIHRvIHdoaWNoIHRoZSB2YXJpYWJsZSB0b3Agc2hvdWxkIGJlIHNldAogICAgICogQHBhcmFtIGxlbiBsZW5ndGggb2YgdmFyaWFibGUgdG9wIHN0cmluZy4gSWYgLTEgaXQgaXMgY29uc2lkZXJlZCB0byBiZSB6ZXJvIHRlcm1pbmF0ZWQuCiAgICAgKiBAcGFyYW0gc3RhdHVzIGVycm9yIGNvZGUuIElmIGVycm9yIGNvZGUgaXMgc2V0LCB0aGUgcmV0dXJuIHZhbHVlIGlzIHVuZGVmaW5lZC4gRXJyb3JzIHNldCBieSB0aGlzIGZ1bmN0aW9uIGFyZTogPGJyPgogICAgICogICAgVV9DRV9OT1RfRk9VTkRfRVJST1IgaWYgbW9yZSB0aGFuIG9uZSBjaGFyYWN0ZXIgd2FzIHBhc3NlZCBhbmQgdGhlcmUgaXMgbm8gc3VjaCBhIGNvbnRyYWN0aW9uPGJyPgogICAgICogICAgVV9QUklNQVJZX1RPT19MT05HX0VSUk9SIGlmIHRoZSBwcmltYXJ5IGZvciB0aGUgdmFyaWFibGUgdG9wIGhhcyBtb3JlIHRoYW4gdHdvIGJ5dGVzCiAgICAgKiBAcmV0dXJuIGEgMzIgYml0IHZhbHVlIGNvbnRhaW5pbmcgdGhlIHZhbHVlIG9mIHRoZSB2YXJpYWJsZSB0b3AgaW4gdXBwZXIgMTYgYml0cy4gTG93ZXIgMTYgYml0cyBhcmUgdW5kZWZpbmVkCiAgICAgKiBAc3RhYmxlIElDVSAyLjAKICAgICAqLwogICAgdmlydHVhbCB1aW50MzJfdCBzZXRWYXJpYWJsZVRvcChjb25zdCBVQ2hhciAqdmFyVG9wLCBpbnQzMl90IGxlbiwgVUVycm9yQ29kZSAmc3RhdHVzKSA9IDA7CgogICAgLyoqIAogICAgICogU2V0cyB0aGUgdmFyaWFibGUgdG9wIHRvIGEgY29sbGF0aW9uIGVsZW1lbnQgdmFsdWUgb2YgYSBzdHJpbmcgc3VwcGxpZWQuIAogICAgICogQHBhcmFtIHZhclRvcCBhbiBVbmljb2RlU3RyaW5nIHNpemUgMSBvciBtb3JlIChpZiBjb250cmFjdGlvbikgb2YgVUNoYXJzIHRvIHdoaWNoIHRoZSB2YXJpYWJsZSB0b3Agc2hvdWxkIGJlIHNldAogICAgICogQHBhcmFtIHN0YXR1cyBlcnJvciBjb2RlLiBJZiBlcnJvciBjb2RlIGlzIHNldCwgdGhlIHJldHVybiB2YWx1ZSBpcyB1bmRlZmluZWQuIEVycm9ycyBzZXQgYnkgdGhpcyBmdW5jdGlvbiBhcmU6IDxicj4KICAgICAqICAgIFVfQ0VfTk9UX0ZPVU5EX0VSUk9SIGlmIG1vcmUgdGhhbiBvbmUgY2hhcmFjdGVyIHdhcyBwYXNzZWQgYW5kIHRoZXJlIGlzIG5vIHN1Y2ggYSBjb250cmFjdGlvbjxicj4KICAgICAqICAgIFVfUFJJTUFSWV9UT09fTE9OR19FUlJPUiBpZiB0aGUgcHJpbWFyeSBmb3IgdGhlIHZhcmlhYmxlIHRvcCBoYXMgbW9yZSB0aGFuIHR3byBieXRlcwogICAgICogQHJldHVybiBhIDMyIGJpdCB2YWx1ZSBjb250YWluaW5nIHRoZSB2YWx1ZSBvZiB0aGUgdmFyaWFibGUgdG9wIGluIHVwcGVyIDE2IGJpdHMuIExvd2VyIDE2IGJpdHMgYXJlIHVuZGVmaW5lZAogICAgICogQHN0YWJsZSBJQ1UgMi4wCiAgICAgKi8KICAgIHZpcnR1YWwgdWludDMyX3Qgc2V0VmFyaWFibGVUb3AoY29uc3QgVW5pY29kZVN0cmluZyB2YXJUb3AsIFVFcnJvckNvZGUgJnN0YXR1cykgPSAwOwoKICAgIC8qKiAKICAgICAqIFNldHMgdGhlIHZhcmlhYmxlIHRvcCB0byBhIGNvbGxhdGlvbiBlbGVtZW50IHZhbHVlIHN1cHBsaWVkLiBWYXJpYWJsZSB0b3AgaXMgc2V0IHRvIHRoZSB1cHBlciAxNiBiaXRzLiAKICAgICAqIExvd2VyIDE2IGJpdHMgYXJlIGlnbm9yZWQuCiAgICAgKiBAcGFyYW0gdmFyVG9wIENFIHZhbHVlLCBhcyByZXR1cm5lZCBieSBzZXRWYXJpYWJsZVRvcCBvciB1Y29sKWdldFZhcmlhYmxlVG9wCiAgICAgKiBAcGFyYW0gc3RhdHVzIGVycm9yIGNvZGUgKG5vdCBjaGFuZ2VkIGJ5IGZ1bmN0aW9uKQogICAgICogQHN0YWJsZSBJQ1UgMi4wCiAgICAgKi8KICAgIHZpcnR1YWwgdm9pZCBzZXRWYXJpYWJsZVRvcChjb25zdCB1aW50MzJfdCB2YXJUb3AsIFVFcnJvckNvZGUgJnN0YXR1cykgPSAwOwoKICAgIC8qKiAKICAgICAqIEdldHMgdGhlIHZhcmlhYmxlIHRvcCB2YWx1ZSBvZiBhIENvbGxhdG9yLiAKICAgICAqIExvd2VyIDE2IGJpdHMgYXJlIHVuZGVmaW5lZCBhbmQgc2hvdWxkIGJlIGlnbm9yZWQuCiAgICAgKiBAcGFyYW0gc3RhdHVzIGVycm9yIGNvZGUgKG5vdCBjaGFuZ2VkIGJ5IGZ1bmN0aW9uKS4gSWYgZXJyb3IgY29kZSBpcyBzZXQsIHRoZSByZXR1cm4gdmFsdWUgaXMgdW5kZWZpbmVkLgogICAgICogQHN0YWJsZSBJQ1UgMi4wCiAgICAgKi8KICAgIHZpcnR1YWwgdWludDMyX3QgZ2V0VmFyaWFibGVUb3AoVUVycm9yQ29kZSAmc3RhdHVzKSBjb25zdCA9IDA7CgogICAgLyoqCiAgICAgKiBHZXQgYW4gVW5pY29kZVNldCB0aGF0IGNvbnRhaW5zIGFsbCB0aGUgY2hhcmFjdGVycyBhbmQgc2VxdWVuY2VzIAogICAgICogdGFpbG9yZWQgaW4gdGhpcyBjb2xsYXRvci4KICAgICAqIEBwYXJhbSBzdGF0dXMgICAgICBlcnJvciBjb2RlIG9mIHRoZSBvcGVyYXRpb24KICAgICAqIEByZXR1cm4gYSBwb2ludGVyIHRvIGEgVW5pY29kZVNldCBvYmplY3QgY29udGFpbmluZyBhbGwgdGhlIAogICAgICogICAgICAgICBjb2RlIHBvaW50cyBhbmQgc2VxdWVuY2VzIHRoYXQgbWF5IHNvcnQgZGlmZmVyZW50bHkgdGhhbgogICAgICogICAgICAgICBpbiB0aGUgVUNBLiBUaGUgb2JqZWN0IG11c3QgYmUgZGlzcG9zZWQgb2YgYnkgdXNpbmcgZGVsZXRlCiAgICAgKiBAc3RhYmxlIElDVSAyLjQKICAgICAqLwogICAgdmlydHVhbCBVbmljb2RlU2V0ICpnZXRUYWlsb3JlZFNldChVRXJyb3JDb2RlICZzdGF0dXMpIGNvbnN0OwoKCiAgICAvKioKICAgICAqIFRocmVhZCBzYWZlIGNsb25pbmcgb3BlcmF0aW9uCiAgICAgKiBAcmV0dXJuIHBvaW50ZXIgdG8gdGhlIG5ldyBjbG9uZSwgdXNlciBzaG91bGQgcmVtb3ZlIGl0LgogICAgICogQHN0YWJsZSBJQ1UgMi4yCiAgICAgKi8KICAgIHZpcnR1YWwgQ29sbGF0b3IqIHNhZmVDbG9uZSh2b2lkKSA9IDA7CgogICAgLyoqCiAgICAgKiBHZXQgdGhlIHNvcnQga2V5IGFzIGFuIGFycmF5IG9mIGJ5dGVzIGZyb20gYW4gVW5pY29kZVN0cmluZy4KICAgICAqIFNvcnQga2V5IGJ5dGUgYXJyYXlzIGFyZSB6ZXJvLXRlcm1pbmF0ZWQgYW5kIGNhbiBiZSBjb21wYXJlZCB1c2luZyAKICAgICAqIHN0cmNtcCgpLgogICAgICogQHBhcmFtIHNvdXJjZSBzdHJpbmcgdG8gYmUgcHJvY2Vzc2VkLgogICAgICogQHBhcmFtIHJlc3VsdCBidWZmZXIgdG8gc3RvcmUgcmVzdWx0IGluLiBJZiBOVUxMLCBudW1iZXIgb2YgYnl0ZXMgbmVlZGVkIAogICAgICogICAgICAgIHdpbGwgYmUgcmV0dXJuZWQuCiAgICAgKiBAcGFyYW0gcmVzdWx0TGVuZ3RoIGxlbmd0aCBvZiB0aGUgcmVzdWx0IGJ1ZmZlci4gSWYgaWYgbm90IGVub3VnaCB0aGUgCiAgICAgKiAgICAgICAgYnVmZmVyIHdpbGwgYmUgZmlsbGVkIHRvIGNhcGFjaXR5LiAKICAgICAqIEByZXR1cm4gTnVtYmVyIG9mIGJ5dGVzIG5lZWRlZCBmb3Igc3RvcmluZyB0aGUgc29ydCBrZXkKICAgICAqIEBzdGFibGUgSUNVIDIuMgogICAgICovCiAgICB2aXJ0dWFsIGludDMyX3QgZ2V0U29ydEtleShjb25zdCBVbmljb2RlU3RyaW5nJiBzb3VyY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVpbnQ4X3QqIHJlc3VsdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50MzJfdCByZXN1bHRMZW5ndGgpIGNvbnN0ID0gMDsKCiAgICAvKioKICAgICAqIEdldCB0aGUgc29ydCBrZXkgYXMgYW4gYXJyYXkgb2YgYnl0ZXMgZnJvbSBhbiBVQ2hhciBidWZmZXIuCiAgICAgKiBTb3J0IGtleSBieXRlIGFycmF5cyBhcmUgemVyby10ZXJtaW5hdGVkIGFuZCBjYW4gYmUgY29tcGFyZWQgdXNpbmcgCiAgICAgKiBzdHJjbXAoKS4KICAgICAqIEBwYXJhbSBzb3VyY2Ugc3RyaW5nIHRvIGJlIHByb2Nlc3NlZC4KICAgICAqIEBwYXJhbSBzb3VyY2VMZW5ndGggbGVuZ3RoIG9mIHN0cmluZyB0byBiZSBwcm9jZXNzZWQuIAogICAgICogICAgICAgIElmIC0xLCB0aGUgc3RyaW5nIGlzIDAgdGVybWluYXRlZCBhbmQgbGVuZ3RoIHdpbGwgYmUgZGVjaWRlZCBieSB0aGUgCiAgICAgKiAgICAgICAgZnVuY3Rpb24uCiAgICAgKiBAcGFyYW0gcmVzdWx0IGJ1ZmZlciB0byBzdG9yZSByZXN1bHQgaW4uIElmIE5VTEwsIG51bWJlciBvZiBieXRlcyBuZWVkZWQgCiAgICAgKiAgICAgICAgd2lsbCBiZSByZXR1cm5lZC4KICAgICAqIEBwYXJhbSByZXN1bHRMZW5ndGggbGVuZ3RoIG9mIHRoZSByZXN1bHQgYnVmZmVyLiBJZiBpZiBub3QgZW5vdWdoIHRoZSAKICAgICAqICAgICAgICBidWZmZXIgd2lsbCBiZSBmaWxsZWQgdG8gY2FwYWNpdHkuIAogICAgICogQHJldHVybiBOdW1iZXIgb2YgYnl0ZXMgbmVlZGVkIGZvciBzdG9yaW5nIHRoZSBzb3J0IGtleQogICAgICogQHN0YWJsZSBJQ1UgMi4yCiAgICAgKi8KICAgIHZpcnR1YWwgaW50MzJfdCBnZXRTb3J0S2V5KGNvbnN0IFVDaGFyKnNvdXJjZSwgaW50MzJfdCBzb3VyY2VMZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1aW50OF90KnJlc3VsdCwgaW50MzJfdCByZXN1bHRMZW5ndGgpIGNvbnN0ID0gMDsKCiAgICAvKioKICAgICAqIFByb2R1Y2UgYSBib3VuZCBmb3IgYSBnaXZlbiBzb3J0a2V5IGFuZCBhIG51bWJlciBvZiBsZXZlbHMuCiAgICAgKiBSZXR1cm4gdmFsdWUgaXMgYWx3YXlzIHRoZSBudW1iZXIgb2YgYnl0ZXMgbmVlZGVkLCByZWdhcmRsZXNzIG9mIAogICAgICogd2hldGhlciB0aGUgcmVzdWx0IGJ1ZmZlciB3YXMgYmlnIGVub3VnaCBvciBldmVuIHZhbGlkLjxicj4KICAgICAqIFJlc3VsdGluZyBib3VuZHMgY2FuIGJlIHVzZWQgdG8gcHJvZHVjZSBhIHJhbmdlIG9mIHN0cmluZ3MgdGhhdCBhcmUKICAgICAqIGJldHdlZW4gdXBwZXIgYW5kIGxvd2VyIGJvdW5kcy4gRm9yIGV4YW1wbGUsIGlmIGJvdW5kcyBhcmUgcHJvZHVjZWQKICAgICAqIGZvciBhIHNvcnRrZXkgb2Ygc3RyaW5nICJzbWl0aCIsIHN0cmluZ3MgYmV0d2VlbiB1cHBlciBhbmQgbG93ZXIgCiAgICAgKiBib3VuZHMgd2l0aCBvbmUgbGV2ZWwgd291bGQgaW5jbHVkZSAiU21pdGgiLCAiU01JVEgiLCAic01pVGgiLjxicj4KICAgICAqIFRoZXJlIGFyZSB0d28gdXBwZXIgYm91bmRzIHRoYXQgY2FuIGJlIHByb2R1Y2VkLiBJZiBVQ09MX0JPVU5EX1VQUEVSCiAgICAgKiBpcyBwcm9kdWNlZCwgc3RyaW5ncyBtYXRjaGVkIHdvdWxkIGJlIGFzIGFib3ZlLiBIb3dldmVyLCBpZiBib3VuZAogICAgICogcHJvZHVjZWQgdXNpbmcgVUNPTF9CT1VORF9VUFBFUl9MT05HIGlzIHVzZWQsIHRoZSBhYm92ZSBleGFtcGxlIHdpbGwKICAgICAqIGFsc28gbWF0Y2ggIlNtaXRoc29uaWFuIiBhbmQgc2ltaWxhci48YnI+CiAgICAgKiBGb3IgbW9yZSBvbiB1c2FnZSwgc2VlIGV4YW1wbGUgaW4gY2ludGx0c3QvY2FwaXRzdC5jIGluIHByb2NlZHVyZQogICAgICogVGVzdEJvdW5kcy4KICAgICAqIFNvcnQga2V5cyBtYXkgYmUgY29tcGFyZWQgdXNpbmcgPFRUPnN0cmNtcDwvVFQ+LgogICAgICogQHBhcmFtIHNvdXJjZSBUaGUgc291cmNlIHNvcnRrZXkuCiAgICAgKiBAcGFyYW0gc291cmNlTGVuZ3RoIFRoZSBsZW5ndGggb2Ygc291cmNlLCBvciAtMSBpZiBudWxsLXRlcm1pbmF0ZWQuIAogICAgICogICAgICAgICAgICAgICAgICAgICAoSWYgYW4gdW5tb2RpZmllZCBzb3J0a2V5IGlzIHBhc3NlZCwgaXQgaXMgYWx3YXlzIG51bGwgCiAgICAgKiAgICAgICAgICAgICAgICAgICAgICB0ZXJtaW5hdGVkKS4KICAgICAqIEBwYXJhbSBib3VuZFR5cGUgVHlwZSBvZiBib3VuZCByZXF1aXJlZC4gSXQgY2FuIGJlIFVDT0xfQk9VTkRfTE9XRVIsIHdoaWNoIAogICAgICogICAgICAgICAgICAgICAgICBwcm9kdWNlcyBhIGxvd2VyIGluY2x1c2l2ZSBib3VuZCwgVUNPTF9CT1VORF9VUFBFUiwgdGhhdCAKICAgICAqICAgICAgICAgICAgICAgICAgcHJvZHVjZXMgdXBwZXIgYm91bmQgdGhhdCBtYXRjaGVzIHN0cmluZ3Mgb2YgdGhlIHNhbWUgbGVuZ3RoIAogICAgICogICAgICAgICAgICAgICAgICBvciBVQ09MX0JPVU5EX1VQUEVSX0xPTkcgdGhhdCBtYXRjaGVzIHN0cmluZ3MgdGhhdCBoYXZlIHRoZSAKICAgICAqICAgICAgICAgICAgICAgICAgc2FtZSBzdGFydGluZyBzdWJzdHJpbmcgYXMgdGhlIHNvdXJjZSBzdHJpbmcuCiAgICAgKiBAcGFyYW0gbm9PZkxldmVscyAgTnVtYmVyIG9mIGxldmVscyByZXF1aXJlZCBpbiB0aGUgcmVzdWx0aW5nIGJvdW5kIChmb3IgbW9zdCAKICAgICAqICAgICAgICAgICAgICAgICAgICB1c2VzLCB0aGUgcmVjb21tZW5kZWQgdmFsdWUgaXMgMSkuIFNlZSB1c2VycyBndWlkZSBmb3IgCiAgICAgKiAgICAgICAgICAgICAgICAgICAgZXhwbGFuYXRpb24gb24gbnVtYmVyIG9mIGxldmVscyBhIHNvcnRrZXkgY2FuIGhhdmUuCiAgICAgKiBAcGFyYW0gcmVzdWx0IEEgcG9pbnRlciB0byBhIGJ1ZmZlciB0byByZWNlaXZlIHRoZSByZXN1bHRpbmcgc29ydGtleS4KICAgICAqIEBwYXJhbSByZXN1bHRMZW5ndGggVGhlIG1heGltdW0gc2l6ZSBvZiByZXN1bHQuCiAgICAgKiBAcGFyYW0gc3RhdHVzIFVzZWQgZm9yIHJldHVybmluZyBlcnJvciBjb2RlIGlmIHNvbWV0aGluZyB3ZW50IHdyb25nLiBJZiB0aGUgCiAgICAgKiAgICAgICAgICAgICAgIG51bWJlciBvZiBsZXZlbHMgcmVxdWVzdGVkIGlzIGhpZ2hlciB0aGFuIHRoZSBudW1iZXIgb2YgbGV2ZWxzCiAgICAgKiAgICAgICAgICAgICAgIGluIHRoZSBzb3VyY2Uga2V5LCBhIHdhcm5pbmcgKFVfU09SVF9LRVlfVE9PX1NIT1JUX1dBUk5JTkcpIGlzIAogICAgICogICAgICAgICAgICAgICBpc3N1ZWQuCiAgICAgKiBAcmV0dXJuIFRoZSBzaXplIG5lZWRlZCB0byBmdWxseSBzdG9yZSB0aGUgYm91bmQuIAogICAgICogQHNlZSB1Y29sX2tleUhhc2hDb2RlCiAgICAgKiBAc3RhYmxlIElDVSAyLjEKICAgICAqLwogICAgc3RhdGljIGludDMyX3QgZ2V0Qm91bmQoY29uc3QgdWludDhfdCAgICAgICAqc291cmNlLAogICAgICAgICAgICBpbnQzMl90ICAgICAgICAgICAgIHNvdXJjZUxlbmd0aCwKICAgICAgICAgICAgVUNvbEJvdW5kTW9kZSAgICAgICBib3VuZFR5cGUsCiAgICAgICAgICAgIHVpbnQzMl90ICAgICAgICAgICAgbm9PZkxldmVscywKICAgICAgICAgICAgdWludDhfdCAgICAgICAgICAgICAqcmVzdWx0LAogICAgICAgICAgICBpbnQzMl90ICAgICAgICAgICAgIHJlc3VsdExlbmd0aCwKICAgICAgICAgICAgVUVycm9yQ29kZSAgICAgICAgICAmc3RhdHVzKTsKCgpwcm90ZWN0ZWQ6CgogICAgLy8gQ29sbGF0b3IgcHJvdGVjdGVkIGNvbnN0cnVjdG9ycyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgLyoqCiAgICAqIERlZmF1bHQgY29uc3RydWN0b3IuCiAgICAqIENvbnN0cnVjdG9yIGlzIGRpZmZlcmVudCBmcm9tIHRoZSBvbGQgZGVmYXVsdCBDb2xsYXRvciBjb25zdHJ1Y3Rvci4KICAgICogVGhlIHRhc2sgZm9yIGRldGVybWluZyB0aGUgZGVmYXVsdCBjb2xsYXRpb24gc3RyZW5ndGggYW5kIG5vcm1hbGl6YXRpb24gCiAgICAqIG1vZGUgaXMgbGVmdCB0byB0aGUgY2hpbGQgY2xhc3MuCiAgICAqIEBzdGFibGUgSUNVIDIuMAogICAgKi8KICAgIENvbGxhdG9yKCk7CgogICAgLyoqCiAgICAqIENvbnN0cnVjdG9yLgogICAgKiBFbXB0eSBjb25zdHJ1Y3RvciwgZG9lcyBub3QgaGFuZGxlIHRoZSBhcmd1bWVudHMuCiAgICAqIFRoaXMgY29uc3RydWN0b3IgaXMgZG9uZSBmb3IgYmFja3dhcmQgY29tcGF0aWJpbGl0eSB3aXRoIDEuNyBhbmQgMS44LgogICAgKiBUaGUgdGFzayBmb3IgaGFuZGxpbmcgdGhlIGFyZ3VtZW50IGNvbGxhdGlvbiBzdHJlbmd0aCBhbmQgbm9ybWFsaXphdGlvbiAKICAgICogbW9kZSBpcyBsZWZ0IHRvIHRoZSBjaGlsZCBjbGFzcy4KICAgICogQHBhcmFtIGNvbGxhdGlvblN0cmVuZ3RoIGNvbGxhdGlvbiBzdHJlbmd0aAogICAgKiBAcGFyYW0gZGVjb21wb3NpdGlvbk1vZGUgCiAgICAqIEBkZXByZWNhdGVkIElDVSAyLjQuIFN1YmNsYXNzZXMgc2hvdWxkIHVzZSB0aGUgZGVmYXVsdCBjb25zdHJ1Y3RvcgogICAgKiBpbnN0ZWFkIGFuZCBoYW5kbGUgdGhlIHN0cmVuZ3RoIGFuZCBub3JtYWxpemF0aW9uIG1vZGUgdGhlbXNlbHZlcy4KICAgICovCiAgICBDb2xsYXRvcihVQ29sbGF0aW9uU3RyZW5ndGggY29sbGF0aW9uU3RyZW5ndGgsIAogICAgICAgICAgICAgVU5vcm1hbGl6YXRpb25Nb2RlIGRlY29tcG9zaXRpb25Nb2RlKTsKICAKICAgIC8qKgogICAgKiBDb3B5IGNvbnN0cnVjdG9yLgogICAgKiBAcGFyYW0gb3RoZXIgQ29sbGF0b3Igb2JqZWN0IHRvIGJlIGNvcGllZCBmcm9tCiAgICAqIEBzdGFibGUgSUNVIDIuMAogICAgKi8KICAgIENvbGxhdG9yKGNvbnN0IENvbGxhdG9yJiBvdGhlcik7CiAgCiAgICAvLyBDb2xsYXRvciBwcm90ZWN0ZWQgbWV0aG9kcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKCiAgIC8qKgogICAgKiBVc2VkIGludGVybmFsbHkgYnkgcmVnaXN0cmF0b24gdG8gZGVmaW5lIHRoZSByZXF1ZXN0ZWQgYW5kIHZhbGlkIGxvY2FsZXMuCiAgICAqIEBwYXJhbSByZXF1ZXN0ZWRMb2NhbGUgdGhlIHJlcXVzdGVkIGxvY2FsZQogICAgKiBAcGFyYW0gdmFsaWRMb2NhbGUgdGhlIHZhbGlkIGxvY2FsZQogICAgKiBAaW50ZXJuYWwKICAgICovCiAgICB2aXJ0dWFsIHZvaWQgc2V0TG9jYWxlcyhjb25zdCBMb2NhbGUmIHJlcXVlc3RlZExvY2FsZSwgY29uc3QgTG9jYWxlJiB2YWxpZExvY2FsZSk7CgpwdWJsaWM6CiAgICAvKioKICAgICAqIHVzZWQgb25seSBieSB1Y29sX29wZW4sIG5vdCBmb3IgcHVibGljIHVzZQogICAgICogQGludGVybmFsCiAgICAgKi8KICAgIHN0YXRpYyBVQ29sbGF0b3IqIGNyZWF0ZVVDb2xsYXRvcihjb25zdCBjaGFyKiBsb2MsIFVFcnJvckNvZGUqIHN0YXR1cyk7Cgpwcml2YXRlOgogICAgLyoqCiAgICAgKiBBc3NpZ25tZW50IG9wZXJhdG9yLiBQcml2YXRlIGZvciBub3cuCiAgICAgKiBAaW50ZXJuYWwKICAgICAqLwogICAgQ29sbGF0b3ImIG9wZXJhdG9yPShjb25zdCBDb2xsYXRvciYgb3RoZXIpOwoKICAgIGZyaWVuZCBjbGFzcyBDRmFjdG9yeTsKICAgIGZyaWVuZCBjbGFzcyBTaW1wbGVDRmFjdG9yeTsKICAgIGZyaWVuZCBjbGFzcyBJQ1VDb2xsYXRvckZhY3Rvcnk7CiAgICBmcmllbmQgY2xhc3MgSUNVQ29sbGF0b3JTZXJ2aWNlOwogICAgc3RhdGljIENvbGxhdG9yKiBtYWtlSW5zdGFuY2UoY29uc3QgTG9jYWxlJiBkZXNpcmVkTG9jYWxlLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cyk7CgogICAgLy8gQ29sbGF0b3IgcHJpdmF0ZSBkYXRhIG1lbWJlcnMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgLyoKICAgIHN5bndlZSA6IHJlbW92ZWQgYXMgYXR0cmlidXRlcyB0byBiZSBoYW5kbGVkIGJ5IGNoaWxkIGNsYXNzCiAgICBVQ29sbGF0aW9uU3RyZW5ndGggIHN0cmVuZ3RoOwogICAgTm9ybWFsaXplcjo6RU1vZGUgIGRlY21wOwogICAgKi8KICAgIC8qIFRoaXMgaXMgdXNlbGVzcyBpbmZvcm1hdGlvbiAqLwovKiAgc3RhdGljIGNvbnN0IFVWZXJzaW9uSW5mbyBmVmVyc2lvbjsqLwp9OwoKLyoqCiAqIEEgZmFjdG9yeSwgdXNlZCB3aXRoIHJlZ2lzdGVyRmFjdG9yeSwgdGhlIGNyZWF0ZXMgbXVsdGlwbGUgY29sbGF0b3JzIGFuZCBwcm92aWRlcwogKiBkaXNwbGF5IG5hbWVzIGZvciB0aGVtLiAgQSBmYWN0b3J5IHN1cHBvcnRzIHNvbWUgbnVtYmVyIG9mIGxvY2FsZXMtLSB0aGVzZSBhcmUgdGhlCiAqIGxvY2FsZXMgZm9yIHdoaWNoIGl0IGNhbiBjcmVhdGUgY29sbGF0b3JzLiAgVGhlIGZhY3RvcnkgY2FuIGJlIHZpc2libGUsIGluIHdoaWNoCiAqIGNhc2UgdGhlIHN1cHBvcnRlZCBsb2NhbGVzIHdpbGwgYmUgZW51bWVyYXRlZCBieSBnZXRBdmFpbGFibGVMb2NhbGVzLCBvciBpbnZpc2libGUsIAogKiBpbiB3aGljaCB0aGV5IGFyZSBub3QuICBJbnZpc2libGUgbG9jYWxlcyBhcmUgc3RpbGwgc3VwcG9ydGVkLCB0aGV5IGFyZSBqdXN0IG5vdAogKiBsaXN0ZWQgYnkgZ2V0QXZhaWxhYmxlTG9jYWxlcy4KICogPHA+CiAqIElmIHN0YW5kYXJkIGxvY2FsZSBkaXNwbGF5IG5hbWVzIGFyZSBzdWZmaWNpZW50LCBDb2xsYXRvciBpbnN0YW5jZXMgY2FuCiAqIGJlIHJlZ2lzdGVyZWQgdXNpbmcgcmVnaXN0ZXJJbnN0YW5jZSBpbnN0ZWFkLjwvcD4KICogPHA+CiAqIE5vdGU6IGlmIHRoZSBjb2xsYXRvcnMgYXJlIHRvIGJlIHVzZWQgZnJvbSBDIEFQSXMsIHRoZXkgbXVzdCBiZSBpbnN0YW5jZXMKICogb2YgUnVsZUJhc2VkQ29sbGF0b3IuPC9wPgogKgogKiBAZHJhZnQgSUNVIDIuNgogKi8KY2xhc3MgVV9JMThOX0FQSSBDb2xsYXRvckZhY3RvcnkgOiBwdWJsaWMgVU9iamVjdCB7CnB1YmxpYzoKCiAgICAvKioKICAgICAqIERlc3RydWN0b3IKICAgICAqIEBkcmFmdCBJQ1UgMy4wCiAgICAgKi8KICAgIHZpcnR1YWwgfkNvbGxhdG9yRmFjdG9yeSgpOwoKICAgIC8qKgogICAgICogUmV0dXJuIHRydWUgaWYgdGhpcyBmYWN0b3J5IGlzIHZpc2libGUuICBEZWZhdWx0IGlzIHRydWUuCiAgICAgKiBJZiBub3QgdmlzaWJsZSwgdGhlIGxvY2FsZXMgc3VwcG9ydGVkIGJ5IHRoaXMgZmFjdG9yeSB3aWxsIG5vdAogICAgICogYmUgbGlzdGVkIGJ5IGdldEF2YWlsYWJsZUxvY2FsZXMuCiAgICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIGZhY3RvcnkgaXMgdmlzaWJsZS4KICAgICAqIEBkcmFmdCBJQ1UgMi42CiAgICAgKi8KICAgIHZpcnR1YWwgVUJvb2wgdmlzaWJsZSh2b2lkKSBjb25zdDsKCiAgICAvKioKICAgICAqIFJldHVybiBhIGNvbGxhdG9yIGZvciB0aGUgcHJvdmlkZWQgbG9jYWxlLiAgSWYgdGhlIGxvY2FsZQogICAgICogaXMgbm90IHN1cHBvcnRlZCwgcmV0dXJuIE5VTEwuCiAgICAgKiBAcGFyYW0gbG9jIHRoZSBsb2NhbGUgaWRlbnRpZnlpbmcgdGhlIGNvbGxhdG9yIHRvIGJlIGNyZWF0ZWQuCiAgICAgKiBAcmV0dXJuIGEgbmV3IGNvbGxhdG9yIGlmIHRoZSBsb2NhbGUgaXMgc3VwcG9ydGVkLCBvdGhlcndpc2UgTlVMTC4KICAgICAqIEBkcmFmdCBJQ1UgMi42CiAgICAgKi8KICAgIHZpcnR1YWwgQ29sbGF0b3IqIGNyZWF0ZUNvbGxhdG9yKGNvbnN0IExvY2FsZSYgbG9jKSA9IDA7CgogICAgLyoqCiAgICAgKiBSZXR1cm4gdGhlIG5hbWUgb2YgdGhlIGNvbGxhdG9yIGZvciB0aGUgb2JqZWN0TG9jYWxlLCBsb2NhbGl6ZWQgZm9yIHRoZSBkaXNwbGF5TG9jYWxlLgogICAgICogSWYgb2JqZWN0TG9jYWxlIGlzIG5vdCBzdXBwb3J0ZWQsIG9yIHRoZSBmYWN0b3J5IGlzIG5vdCB2aXNpYmxlLCBzZXQgdGhlIHJlc3VsdCBzdHJpbmcKICAgICAqIHRvIGJvZ3VzLgogICAgICogQHBhcmFtIG9iamVjdExvY2FsZSB0aGUgbG9jYWxlIGlkZW50aWZ5aW5nIHRoZSBjb2xsYXRvcgogICAgICogQHBhcmFtIGRpc3BsYXlMb2NhbGUgdGhlIGxvY2FsZSBmb3Igd2hpY2ggdGhlIGRpc3BsYXkgbmFtZSBvZiB0aGUgY29sbGF0b3Igc2hvdWxkIGJlIGxvY2FsaXplZAogICAgICogQHBhcmFtIHJlc3VsdCBhbiBvdXRwdXQgcGFyYW1ldGVyIGZvciB0aGUgZGlzcGxheSBuYW1lLCBzZXQgdG8gYm9ndXMgaWYgbm90IHN1cHBvcnRlZC4KICAgICAqIEByZXR1cm4gdGhlIGRpc3BsYXkgbmFtZQogICAgICogQGRyYWZ0IElDVSAyLjYKICAgICAqLwogICAgdmlydHVhbCAgVW5pY29kZVN0cmluZyYgZ2V0RGlzcGxheU5hbWUoY29uc3QgTG9jYWxlJiBvYmplY3RMb2NhbGUsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTG9jYWxlJiBkaXNwbGF5TG9jYWxlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVW5pY29kZVN0cmluZyYgcmVzdWx0KTsKICAgIAogICAgLyoqCiAgICAgKiBSZXR1cm4gYW4gYXJyYXkgb2YgYWxsIHRoZSBsb2NhbGUgbmFtZXMgZGlyZWN0bHkgc3VwcG9ydGVkIGJ5IHRoaXMgZmFjdG9yeS4gIAogICAgICogVGhlIG51bWJlciBvZiBuYW1lcyBpcyByZXR1cm5lZCBpbiBjb3VudC4gIFRoaXMgYXJyYXkgaXMgb3duZWQgYnkgdGhlIGZhY3RvcnkuICAKICAgICAqIEl0cyBjb250ZW50cyBtdXN0IG5ldmVyIGNoYW5nZS4KICAgICAqIEBwYXJhbSBjb3VudCBvdXRwdXQgcGFyYW1ldGVyIGZvciB0aGUgbnVtYmVyIG9mIGxvY2FsZXMgc3VwcG9ydGVkIGJ5IHRoZSBmYWN0b3J5CiAgICAgKiBAcGFyYW0gc3RhdHVzIHRoZSBpbi9vdXQgZXJyb3IgY29kZQogICAgICogQHJldHVybiBhIHBvaW50ZXIgdG8gYW4gYXJyYXkgb2YgY291bnQgVW5pY29kZVN0cmluZ3MuCiAgICAgKiBAZHJhZnQgSUNVIDIuNgogICAgICovCiAgICB2aXJ0dWFsIGNvbnN0IFVuaWNvZGVTdHJpbmcgKiBnZXRTdXBwb3J0ZWRJRHMoaW50MzJfdCAmY291bnQsIFVFcnJvckNvZGUmIHN0YXR1cykgPSAwOwp9OwoKLy8gQ29sbGF0b3IgaW5saW5lIG1ldGhvZHMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCi8qCnN5bndlZSA6IHJlbW92ZWQgc2luY2UgdGhlcmUncyBubyBhdHRyaWJ1dGUgdG8gYmUgcmV0cmlldmVkIGhlcmUKaW5saW5lIFVDb2xsYXRpb25TdHJlbmd0aCBDb2xsYXRvcjo6Z2V0U3RyZW5ndGgoKSBjb25zdAp7CiAgcmV0dXJuIHN0cmVuZ3RoOwp9CgppbmxpbmUgTm9ybWFsaXplcjo6RU1vZGUgQ29sbGF0b3I6OmdldERlY29tcG9zaXRpb24oKSBjb25zdAp7CiAgcmV0dXJuIGRlY21wOwp9CiovClVfTkFNRVNQQUNFX0VORAoKI2VuZGlmIC8qICNpZiAhVUNPTkZJR19OT19DT0xMQVRJT04gKi8KCiNlbmRpZgo=