LyoKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiogICBDb3B5cmlnaHQgKEMpIDE5OTYtMjAwMSwgSW50ZXJuYXRpb25hbCBCdXNpbmVzcyBNYWNoaW5lcyAgICAgICAgICAgICAgICAgKgoqICAgQ29ycG9yYXRpb24gYW5kIG90aGVycy4gIEFsbCBSaWdodHMgUmVzZXJ2ZWQuICAgICAgICAgICAgICAgICAgICAgICAgICAgICoKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiovCgovKioKKiBGaWxlIGNvbGwuaAoqIAoqIENyZWF0ZWQgYnk6IEhlbGVuYSBTaGloCioKKiBNb2RpZmljYXRpb24gSGlzdG9yeToKKgoqICBEYXRlICAgICAgICBOYW1lICAgICAgICBEZXNjcmlwdGlvbgoqIDAyLzUvOTcgICAgICBhbGl1ICAgICAgICBNb2RpZmllZCBjcmVhdGVEZWZhdWx0IHRvIGxvYWQgY29sbGF0aW9uIGRhdGEgZnJvbQoqICAgICAgICAgICAgICAgICAgICAgICAgICBiaW5hcnkgZmlsZXMgd2hlbiBwb3NzaWJsZS4gIEFkZGVkIHJlbGF0ZWQgbWV0aG9kcwoqICAgICAgICAgICAgICAgICAgICAgICAgICBjcmVhdGVDb2xsYXRpb25Gcm9tRmlsZSwgY2hvcExvY2FsZSwgY3JlYXRlUGF0aE5hbWUuCiogMDIvMTEvOTcgICAgIGFsaXUgICAgICAgIEFkZGVkIG1lbWJlcnMgYWRkVG9DYWNoZSwgZmluZEluQ2FjaGUsIGFuZCBmZ0NhY2hlLgoqIDAyLzEyLzk3ICAgICBhbGl1ICAgICAgICBNb2RpZmllZCB0byBjcmVhdGUgb2JqZWN0cyBmcm9tIFJ1bGVCYXNlZENvbGxhdG9yIGNhY2hlLgoqICAgICAgICAgICAgICAgICAgICAgICAgICBNb3ZlZCBjYWNoZSBvdXQgb2YgQ29sbGF0aW9uIGNsYXNzLgoqIDAyLzEzLzk3ICAgICBhbGl1ICAgICAgICBNb3ZlZCBzZXZlcmFsIG1ldGhvZHMgb3V0IG9mIHRoaXMgY2xhc3MgYW5kIGludG8KKiAgICAgICAgICAgICAgICAgICAgICAgICAgUnVsZUJhc2VkQ29sbGF0b3IsIHdpdGggbW9kaWZpY2F0aW9ucy4gIE1vZGlmaWVkCiogICAgICAgICAgICAgICAgICAgICAgICAgIGNyZWF0ZURlZmF1bHQoKSB0byBjYWxsIG5ldyBSdWxlQmFzZWRDb2xsYXRvcihMb2NhbGUmKQoqICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdHJ1Y3Rvci4gIEdlbmVyYWwgY2xlYW4gdXAgYW5kIGRvY3VtZW50YXRpb24uCiogMDIvMjAvOTcgICAgIGhlbGVuYSAgICAgIEFkZGVkIGNsb25lLCBvcGVyYXRvcj09LCBvcGVyYXRvciE9LCBvcGVyYXRvcj0sIGNvcHkKKiAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3RydWN0b3IgYW5kIGdldER5bmFtaWNDbGFzc0lELgoqIDAzLzI1Lzk3ICAgICBoZWxlbmEgICAgICBVcGRhdGVkIHdpdGggcGxhdGZvcm0gaW5kZXBlbmRlbnQgZGF0YSB0eXBlcy4KKiAwNS8wNi85NyAgICAgaGVsZW5hICAgICAgQWRkZWQgbWVtb3J5IGFsbG9jYXRpb24gZXJyb3IgZGV0ZWN0aW9uLgoqIDA2LzIwLzk3ICAgICBoZWxlbmEgICAgICBKYXZhIGNsYXNzIG5hbWUgY2hhbmdlLgoqIDA5LzAzLzk3ICAgICBoZWxlbmEgICAgICBBZGRlZCBjcmVhdGVDb2xsYXRpb25LZXlWYWx1ZXMoKS4KKiAwMi8xMC85OCAgICAgZGFtaWJhICAgICAgQWRkZWQgY29tcGFyZSgpIHdpdGggbGVuZ3RoIGFzIHBhcmFtZXRlci4KKiAwNC8yMy85OSAgICAgc3RlcGhlbiAgICAgUmVtb3ZlZCBFRGVjb21wb3NpdGlvbk1vZGUsIG1lcmdlZCB3aXRoCiogICAgICAgICAgICAgICAgICAgICAgICAgIE5vcm1hbGl6ZXI6OkVNb2RlLgoqIDExLzAyLzk5ICAgICBoZWxlbmEgICAgICBDb2xsYXRvciBwZXJmb3JtYW5jZSBlbmhhbmNlbWVudHMuICBFbGltaW5hdGVzIHRoZSAKKiAgICAgICAgICAgICAgICAgICAgICAgICAgVW5pY29kZVN0cmluZyBjb25zdHJ1Y3Rpb24gYW5kIHNwZWNpYWwgY2FzZSBmb3IgTk9fT1AuCiogMTEvMjMvOTkgICAgIHNybCAgICAgICAgIE1vcmUgcGVyZm9ybWFuY2UgZW5oYW5jZW1lbnRzLiBJbmxpbmluZyBvZgoqICAgICAgICAgICAgICAgICAgICAgICAgICBjcml0aWNhbCBhY2Nlc3NvcnMuCiogMDUvMTUvMDAgICAgIGhlbGVuYSAgICAgIEFkZGVkIHZlcnNpb24gaW5mb3JtYXRpb24gQVBJLiAKKiAwMS8yOS8wMSAgICAgc3lud2VlICAgICAgTW9kaWZpZWQgaW50byBhIEMrKyB3cmFwcGVyIHdoaWNoIGNhbGxzIEMgYXBpcyAKKiAgICAgICAgICAgICAgICAgICAgICAgICAgKHVjb2xsLmgpLiAKKi8KCiNpZm5kZWYgQ09MTF9ICiNkZWZpbmUgQ09MTF9ICgojaW5jbHVkZSAidW5pY29kZS91dHlwZXMuaCIKI2luY2x1ZGUgInVuaWNvZGUvdW9iamVjdC5oIgojaW5jbHVkZSAidW5pY29kZS91Y29sLmgiCiNpbmNsdWRlICJ1bmljb2RlL25vcm1senIuaCIKI2luY2x1ZGUgInVuaWNvZGUvbG9jaWQuaCIKClVfTkFNRVNQQUNFX0JFR0lOCgovKioKKiBAc3RhYmxlCiovCmNsYXNzIENvbGxhdGlvbktleTsKCi8qKgoqIFRoZSA8Y29kZT5Db2xsYXRvcjwvY29kZT4gY2xhc3MgcGVyZm9ybXMgbG9jYWxlLXNlbnNpdGl2ZSBzdHJpbmcgCiogY29tcGFyaXNvbi48YnI+CiogWW91IHVzZSB0aGlzIGNsYXNzIHRvIGJ1aWxkIHNlYXJjaGluZyBhbmQgc29ydGluZyByb3V0aW5lcyBmb3IgbmF0dXJhbCAKKiBsYW5ndWFnZSB0ZXh0Ljxicj4KKiA8ZW0+SW1wb3J0YW50OiA8L2VtPlRoZSBJQ1UgY29sbGF0aW9uIHNlcnZpY2UgaGFzIGJlZW4gcmVpbXBsZW1lbnRlZCAKKiBpbiBvcmRlciB0byBhY2hpZXZlIGJldHRlciBwZXJmb3JtYW5jZSBhbmQgVUNBIGNvbXBsaWFuY2UuIAoqIEZvciBkZXRhaWxzLCBzZWUgdGhlIAoqIDxhIGhyZWY9Imh0dHA6Ly9vc3Muc29mdHdhcmUuaWJtLmNvbS9jdnMvaWN1L35jaGVja291dH4vaWN1aHRtbC9kZXNpZ24vY29sbGF0aW9uL0lDVV9jb2xsYXRpb25fZGVzaWduLmh0bSI+CiogY29sbGF0aW9uIGRlc2lnbiBkb2N1bWVudDwvYT4uCiogPHA+CiogPGNvZGU+Q29sbGF0b3I8L2NvZGU+IGlzIGFuIGFic3RyYWN0IGJhc2UgY2xhc3MuIFN1YmNsYXNzZXMgaW1wbGVtZW50IAoqIHNwZWNpZmljIGNvbGxhdGlvbiBzdHJhdGVnaWVzLiBPbmUgc3ViY2xhc3MsIAoqIDxjb2RlPlJ1bGVCYXNlZENvbGxhdG9yPC9jb2RlPiwgaXMgY3VycmVudGx5IHByb3ZpZGVkIGFuZCBpcyBhcHBsaWNhYmxlIAoqIHRvIGEgd2lkZSBzZXQgb2YgbGFuZ3VhZ2VzLiBPdGhlciBzdWJjbGFzc2VzIG1heSBiZSBjcmVhdGVkIHRvIGhhbmRsZSBtb3JlIAoqIHNwZWNpYWxpemVkIG5lZWRzLgoqIDxwPgoqIExpa2Ugb3RoZXIgbG9jYWxlLXNlbnNpdGl2ZSBjbGFzc2VzLCB5b3UgY2FuIHVzZSB0aGUgc3RhdGljIGZhY3RvcnkgbWV0aG9kLCAKKiA8Y29kZT5jcmVhdGVJbnN0YW5jZTwvY29kZT4sIHRvIG9idGFpbiB0aGUgYXBwcm9wcmlhdGUgCiogPGNvZGU+Q29sbGF0b3I8L2NvZGU+IG9iamVjdCBmb3IgYSBnaXZlbiBsb2NhbGUuIFlvdSB3aWxsIG9ubHkgbmVlZCB0byAKKiBsb29rIGF0IHRoZSBzdWJjbGFzc2VzIG9mIDxjb2RlPkNvbGxhdG9yPC9jb2RlPiBpZiB5b3UgbmVlZCB0byAKKiB1bmRlcnN0YW5kIHRoZSBkZXRhaWxzIG9mIGEgcGFydGljdWxhciBjb2xsYXRpb24gc3RyYXRlZ3kgb3IgaWYgeW91IG5lZWQgdG8gCiogbW9kaWZ5IHRoYXQgc3RyYXRlZ3kuCiogPHA+CiogVGhlIGZvbGxvd2luZyBleGFtcGxlIHNob3dzIGhvdyB0byBjb21wYXJlIHR3byBzdHJpbmdzIHVzaW5nIHRoZSAKKiA8Y29kZT5Db2xsYXRvcjwvY29kZT4gZm9yIHRoZSBkZWZhdWx0IGxvY2FsZS4KKiA8YmxvY2txdW90ZT4KKiA8cHJlPgoqIFxjb2RlCiogLy8gQ29tcGFyZSB0d28gc3RyaW5ncyBpbiB0aGUgZGVmYXVsdCBsb2NhbGUKKiBVRXJyb3JDb2RlIHN1Y2Nlc3MgPSBVX1pFUk9fRVJST1I7CiogQ29sbGF0b3IqIG15Q29sbGF0b3IgPSBDb2xsYXRvcjo6Y3JlYXRlSW5zdGFuY2Uoc3VjY2Vzcyk7CiogaWYgKG15Q29sbGF0b3ItPmNvbXBhcmUoImFiYyIsICJBQkMiKSA8IDApCiogICBjb3V0IDw8ICJhYmMgaXMgbGVzcyB0aGFuIEFCQyIgPDwgZW5kbDsKKiBlbHNlCiogICBjb3V0IDw8ICJhYmMgaXMgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIEFCQyIgPDwgZW5kbDsKKiBcZW5kY29kZQoqIDwvcHJlPgoqIDwvYmxvY2txdW90ZT4KKiA8cD4KKiBZb3UgY2FuIHNldCBhIDxjb2RlPkNvbGxhdG9yPC9jb2RlPidzIDxlbT5zdHJlbmd0aDwvZW0+IHByb3BlcnR5IHRvIAoqIGRldGVybWluZSB0aGUgbGV2ZWwgb2YgZGlmZmVyZW5jZSBjb25zaWRlcmVkIHNpZ25pZmljYW50IGluIGNvbXBhcmlzb25zLiAKKiBGaXZlIHN0cmVuZ3RocyBhcmUgcHJvdmlkZWQ6IDxjb2RlPlBSSU1BUlk8L2NvZGU+LCA8Y29kZT5TRUNPTkRBUlk8L2NvZGU+LCAKKiA8Y29kZT5URVJUSUFSWTwvY29kZT4sIDxjb2RlPlFVQVRFUk5BUlk8L2NvZGU+IGFuZCA8Y29kZT5JREVOVElDQUw8L2NvZGU+LiBUaGUgZXhhY3QgYXNzaWdubWVudCBvZiAKKiBzdHJlbmd0aHMgdG8gbGFuZ3VhZ2UgZmVhdHVyZXMgaXMgbG9jYWxlIGRlcGVuZGFudC4gRm9yIGV4YW1wbGUsIGluIEN6ZWNoLCAKKiAiZSIgYW5kICJmIiBhcmUgY29uc2lkZXJlZCBwcmltYXJ5IGRpZmZlcmVuY2VzLCB3aGlsZSAiZSIgYW5kICJcdTAwRUEiIGFyZSAKKiBzZWNvbmRhcnkgZGlmZmVyZW5jZXMsICJlIiBhbmQgIkUiIGFyZSB0ZXJ0aWFyeSBkaWZmZXJlbmNlcyBhbmQgImUiIGFuZCAiZSIgCiogYXJlIGlkZW50aWNhbC4gVGhlIGZvbGxvd2luZyBzaG93cyBob3cgYm90aCBjYXNlIGFuZCBhY2NlbnRzIGNvdWxkIGJlIAoqIGlnbm9yZWQgZm9yIFVTIEVuZ2xpc2guCiogPGJsb2NrcXVvdGU+CiogPHByZT4KKiBcY29kZQoqIC8vR2V0IHRoZSBDb2xsYXRvciBmb3IgVVMgRW5nbGlzaCBhbmQgc2V0IGl0cyBzdHJlbmd0aCB0byBQUklNQVJZIAoqIFVFcnJvckNvZGUgc3VjY2VzcyA9IFVfWkVST19FUlJPUjsKKiBDb2xsYXRvciogdXNDb2xsYXRvciA9IAoqICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvbGxhdG9yOjpjcmVhdGVJbnN0YW5jZShMb2NhbGU6OlVTLCBzdWNjZXNzKTsKKiB1c0NvbGxhdG9yLT5zZXRTdHJlbmd0aChDb2xsYXRvcjo6UFJJTUFSWSk7CiogaWYgKHVzQ29sbGF0b3ItPmNvbXBhcmUoImFiYyIsICJBQkMiKSA9PSAwKQoqICAgY291dCA8PCAKKiAiJ2FiYycgYW5kICdBQkMnIHN0cmluZ3MgYXJlIGVxdWl2YWxlbnQgd2l0aCBzdHJlbmd0aCBQUklNQVJZIiA8PCAKKiBlbmRsOwoqIFxlbmRjb2RlCiogPC9wcmU+CiogPC9ibG9ja3F1b3RlPgoqIDxwPgoqIEZvciBjb21wYXJpbmcgc3RyaW5ncyBleGFjdGx5IG9uY2UsIHRoZSA8Y29kZT5jb21wYXJlPC9jb2RlPiBtZXRob2QgCiogcHJvdmlkZXMgdGhlIGJlc3QgcGVyZm9ybWFuY2UuIFdoZW4gc29ydGluZyBhIGxpc3Qgb2Ygc3RyaW5ncyBob3dldmVyLCBpdCAKKiBpcyBnZW5lcmFsbHkgbmVjZXNzYXJ5IHRvIGNvbXBhcmUgZWFjaCBzdHJpbmcgbXVsdGlwbGUgdGltZXMuIEluIHRoaXMgY2FzZSwgCiogc29ydCBrZXlzIHByb3ZpZGUgYmV0dGVyIHBlcmZvcm1hbmNlLiBUaGUgPGNvZGU+Z2V0U29ydEtleTwvY29kZT4gbWV0aG9kcyAKKiBjb252ZXJ0IGEgc3RyaW5nIHRvIGEgc2VyaWVzIG9mIGJ5dGVzIHRoYXQgY2FuIGJlIGNvbXBhcmVkIGJpdHdpc2UgYWdhaW5zdCAKKiBvdGhlciBzb3J0IGtleXMgdXNpbmcgPGNvZGU+c3RyY21wKCk8L2NvZGU+LiBTb3J0IGtleXMgYXJlIHdyaXR0ZW4gYXMgCiogemVyby10ZXJtaW5hdGVkIGJ5dGUgc3RyaW5ncy4gVGhleSBjb25zaXN0IG9mIHNldmVyYWwgc3Vic3RyaW5ncywgb25lIGZvciAKKiBlYWNoIGNvbGxhdGlvbiBzdHJlbmd0aCBsZXZlbCwgdGhhdCBhcmUgZGVsaW1pdGVkIGJ5IDB4MDEgYnl0ZXMuCiogSWYgdGhlIHN0cmluZyBjb2RlIHBvaW50cyBhcmUgYXBwZW5kZWQgZm9yIFVDT0xfSURFTlRJQ0FMLCB0aGVuIHRoZXkgYXJlIAoqIHByb2Nlc3NlZCBmb3IgY29ycmVjdCBjb2RlIHBvaW50IG9yZGVyIGNvbXBhcmlzb24gYW5kIG1heSBjb250YWluIDB4MDEgCiogYnl0ZXMgYnV0IG5vdCB6ZXJvIGJ5dGVzLgoqIDwvcD4KKiA8cD4KKiBBbiBvbGRlciBzZXQgb2YgQVBJcyByZXR1cm5zIGEgPGNvZGU+Q29sbGF0aW9uS2V5PC9jb2RlPiBvYmplY3QgdGhhdCB3cmFwcyAKKiB0aGUgc29ydCBrZXkgYnl0ZXMgaW5zdGVhZCBvZiByZXR1cm5pbmcgdGhlIGJ5dGVzIHRoZW1zZWx2ZXMuCiogSXRzIHVzZSBpcyBkZXByZWNhdGVkLCBidXQgaXQgaXMgc3RpbGwgYXZhaWxhYmxlIGZvciBjb21wYXRpYmlsaXR5IHdpdGggCiogSmF2YS4KKiA8L3A+CiogPHA+CiogPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiA8Y29kZT5Db2xsYXRvcjwvY29kZT5zIHdpdGggZGlmZmVyZW50IExvY2FsZSwKKiBhbmQgQ29sbGF0aW9uU3RyZW5ndGggc2V0dGluZ3Mgd2lsbCByZXR1cm4gZGlmZmVyZW50IHNvcnQgCiogb3JkZXJzIGZvciB0aGUgc2FtZSBzZXQgb2Ygc3RyaW5ncy4gTG9jYWxlcyBoYXZlIHNwZWNpZmljIGNvbGxhdGlvbiBydWxlcywgCiogYW5kIHRoZSB3YXkgaW4gd2hpY2ggc2Vjb25kYXJ5IGFuZCB0ZXJ0aWFyeSBkaWZmZXJlbmNlcyBhcmUgdGFrZW4gaW50byAKKiBhY2NvdW50LCBmb3IgZXhhbXBsZSwgd2lsbCByZXN1bHQgaW4gYSBkaWZmZXJlbnQgc29ydGluZyBvcmRlciBmb3Igc2FtZSAKKiBzdHJpbmdzLgoqIDwvcD4KKiBAc2VlICAgICAgICAgUnVsZUJhc2VkQ29sbGF0b3IKKiBAc2VlICAgICAgICAgQ29sbGF0aW9uS2V5CiogQHNlZSAgICAgICAgIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcgoqIEBzZWUgICAgICAgICBMb2NhbGUKKiBAc2VlICAgICAgICAgTm9ybWFsaXplcgoqIEB2ZXJzaW9uICAgICAyLjAgMTEvMTUvMDEKKi8KCmNsYXNzIFVfSTE4Tl9BUEkgQ29sbGF0b3IgOiBwdWJsaWMgVU9iamVjdCB7CnB1YmxpYzoKCiAgLy8gQ29sbGF0b3IgcHVibGljIGVudW1zIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogIC8qKgogICogQmFzZSBsZXR0ZXIgcmVwcmVzZW50cyBhIHByaW1hcnkgZGlmZmVyZW5jZS4gU2V0IGNvbXBhcmlzb24gbGV2ZWwgdG8gCiAgKiBQUklNQVJZIHRvIGlnbm9yZSBzZWNvbmRhcnkgYW5kIHRlcnRpYXJ5IGRpZmZlcmVuY2VzLjxicj4KICAqIFVzZSB0aGlzIHRvIHNldCB0aGUgc3RyZW5ndGggb2YgYSBDb2xsYXRvciBvYmplY3QuPGJyPgogICogRXhhbXBsZSBvZiBwcmltYXJ5IGRpZmZlcmVuY2UsICJhYmMiICZsdDsgImFiZCIKICAqIAogICogRGlhY3JpdGljYWwgZGlmZmVyZW5jZXMgb24gdGhlIHNhbWUgYmFzZSBsZXR0ZXIgcmVwcmVzZW50IGEgc2Vjb25kYXJ5CiAgKiBkaWZmZXJlbmNlLiBTZXQgY29tcGFyaXNvbiBsZXZlbCB0byBTRUNPTkRBUlkgdG8gaWdub3JlIHRlcnRpYXJ5CiAgKiBkaWZmZXJlbmNlcy4gVXNlIHRoaXMgdG8gc2V0IHRoZSBzdHJlbmd0aCBvZiBhIENvbGxhdG9yIG9iamVjdC48YnI+CiAgKiBFeGFtcGxlIG9mIHNlY29uZGFyeSBkaWZmZXJlbmNlLCAi5CIgPj4gImEiLgogICoKICAqIFVwcGVyY2FzZSBhbmQgbG93ZXJjYXNlIHZlcnNpb25zIG9mIHRoZSBzYW1lIGNoYXJhY3RlciByZXByZXNlbnRzIGEKICAqIHRlcnRpYXJ5IGRpZmZlcmVuY2UuICBTZXQgY29tcGFyaXNvbiBsZXZlbCB0byBURVJUSUFSWSB0byBpbmNsdWRlIGFsbCAKICAqIGNvbXBhcmlzb24gZGlmZmVyZW5jZXMuIFVzZSB0aGlzIHRvIHNldCB0aGUgc3RyZW5ndGggb2YgYSBDb2xsYXRvcgogICogb2JqZWN0Ljxicj4KICAqIEV4YW1wbGUgb2YgdGVydGlhcnkgZGlmZmVyZW5jZSwgImFiYyIgJmx0OyZsdDsmbHQ7ICJBQkMiLgogICoKICAqIFR3byBjaGFyYWN0ZXJzIGFyZSBjb25zaWRlcmVkICJpZGVudGljYWwiIHdoZW4gdGhleSBoYXZlIHRoZSBzYW1lIHVuaWNvZGUgCiAgKiBzcGVsbGluZ3MuPGJyPgogICogRm9yIGV4YW1wbGUsICLkIiA9PSAi5CIuCiAgKgogICogVUNvbGxhdGlvblN0cmVuZ3RoIGlzIGFsc28gdXNlZCB0byBkZXRlcm1pbmUgdGhlIHN0cmVuZ3RoIG9mIHNvcnQga2V5cyAKICAqIGdlbmVyYXRlZCBmcm9tIENvbGxhdG9yIG9iamVjdHMuCiAgKiBAc3RhYmxlCiAgKi8KICBlbnVtIEVDb2xsYXRpb25TdHJlbmd0aCAKICB7CiAgICBQUklNQVJZICAgID0gMCwKICAgIFNFQ09OREFSWSAgPSAxLCAKICAgIFRFUlRJQVJZICAgPSAyLAogICAgUVVBVEVSTkFSWSA9IDMsCiAgICBJREVOVElDQUwgID0gMTUKICB9OwogIAogIC8qKgogICogTEVTUyBpcyByZXR1cm5lZCBpZiBzb3VyY2Ugc3RyaW5nIGlzIGNvbXBhcmVkIHRvIGJlIGxlc3MgdGhhbiB0YXJnZXQKICAqIHN0cmluZyBpbiB0aGUgY29tcGFyZSgpIG1ldGhvZC4KICAqIEVRVUFMIGlzIHJldHVybmVkIGlmIHNvdXJjZSBzdHJpbmcgaXMgY29tcGFyZWQgdG8gYmUgZXF1YWwgdG8gdGFyZ2V0CiAgKiBzdHJpbmcgaW4gdGhlIGNvbXBhcmUoKSBtZXRob2QuCiAgKiBHUkVBVEVSIGlzIHJldHVybmVkIGlmIHNvdXJjZSBzdHJpbmcgaXMgY29tcGFyZWQgdG8gYmUgZ3JlYXRlciB0aGFuCiAgKiB0YXJnZXQgc3RyaW5nIGluIHRoZSBjb21wYXJlKCkgbWV0aG9kLgogICogQHNlZSBDb2xsYXRvciNjb21wYXJlCiAgKiBAc3RhYmxlCiAgKi8KICBlbnVtIEVDb21wYXJpc29uUmVzdWx0IAogIHsKICAgIExFU1MgPSAtMSwKICAgIEVRVUFMID0gMCwKICAgIEdSRUFURVIgPSAxCiAgfTsKICAKICAvLyBDb2xsYXRvciBwdWJsaWMgZGVzdHJ1Y3RvciAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogIAogIC8qKgogICogRGVzdHJ1Y3RvcgogICogQHN0YWJsZQogICovCiAgdmlydHVhbCB+Q29sbGF0b3IoKTsKCiAgLy8gQ29sbGF0b3IgcHVibGljIG1ldGhvZHMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgLyoqCiAgKiBSZXR1cm5zIHRydWUgaWYgIm90aGVyIiBpcyB0aGUgc2FtZSBhcyAidGhpcyIKICAqIEBwYXJhbSBvdGhlciBDb2xsYXRvciBvYmplY3QgdG8gYmUgY29tcGFyZWQKICAqIEByZXR1cm4gdHJ1ZSBpZiBvdGhlciBpcyB0aGUgc2FtZSBhcyB0aGlzLgogICogQHN0YWJsZQogICovCiAgdmlydHVhbCBVQm9vbCBvcGVyYXRvcj09KGNvbnN0IENvbGxhdG9yJiBvdGhlcikgY29uc3Q7CgogIC8qKgogICogUmV0dXJucyB0cnVlIGlmICJvdGhlciIgaXMgbm90IHRoZSBzYW1lIGFzICJ0aGlzIi4KICAqIEBwYXJhbSBvdGhlciBDb2xsYXRvciBvYmplY3QgdG8gYmUgY29tcGFyZWQKICAqIEByZXR1cm4gdHJ1ZSBpZiBvdGhlciBpcyBub3QgdGhlIHNhbWUgYXMgdGhpcy4KICAqIEBzdGFibGUKICAqLwogIHZpcnR1YWwgVUJvb2wgb3BlcmF0b3IhPShjb25zdCBDb2xsYXRvciYgb3RoZXIpIGNvbnN0OwoKICAvKioKICAqIE1ha2VzIGEgc2hhbGxvdyBjb3B5IG9mIHRoZSBjdXJyZW50IG9iamVjdC4KICAqIEByZXR1cm4gYSBjb3B5IG9mIHRoaXMgb2JqZWN0CiAgKiBAc3RhYmxlCiAgKi8KICB2aXJ0dWFsIENvbGxhdG9yKiBjbG9uZSh2b2lkKSBjb25zdCA9IDA7CgogIC8qKgogICogQ3JlYXRlcyB0aGUgQ29sbGF0b3Igb2JqZWN0IGZvciB0aGUgY3VycmVudCBkZWZhdWx0IGxvY2FsZS4KICAqIFRoZSBkZWZhdWx0IGxvY2FsZSBpcyBkZXRlcm1pbmVkIGJ5IExvY2FsZTo6Z2V0RGVmYXVsdC4KICAqIFRoZSBVRXJyb3JDb2RlJiBlcnIgcGFyYW1ldGVyIGlzIHVzZWQgdG8gcmV0dXJuIHN0YXR1cyBpbmZvcm1hdGlvbiB0byB0aGUgdXNlci4KICAqIFRvIGNoZWNrIHdoZXRoZXIgdGhlIGNvbnN0cnVjdGlvbiBzdWNjZWVkZWQgb3Igbm90LCB5b3Ugc2hvdWxkIGNoZWNrIHRoZSAKICAqIHZhbHVlIG9mIFVfU1VDQ0VTUyhlcnIpLiAgSWYgeW91IHdpc2ggbW9yZSBkZXRhaWxlZCBpbmZvcm1hdGlvbiwgeW91IGNhbiAKICAqIGNoZWNrIGZvciBpbmZvcm1hdGlvbmFsIGVycm9yIHJlc3VsdHMgd2hpY2ggc3RpbGwgaW5kaWNhdGUgc3VjY2Vzcy4KICAqIFVfVVNJTkdfRkFMTEJBQ0tfRVJST1IgaW5kaWNhdGVzIHRoYXQgYSBmYWxsIGJhY2sgbG9jYWxlIHdhcyB1c2VkLiBGb3IKICAqIGV4YW1wbGUsICdkZV9DSCcgd2FzIHJlcXVlc3RlZCwgYnV0IG5vdGhpbmcgd2FzIGZvdW5kIHRoZXJlLCBzbyAnZGUnIHdhcwogICogdXNlZC4gVV9VU0lOR19ERUZBVUxUX0VSUk9SIGluZGljYXRlcyB0aGF0IHRoZSBkZWZhdWx0IGxvY2FsZSBkYXRhIHdhcwogICogdXNlZDsgbmVpdGhlciB0aGUgcmVxdWVzdGVkIGxvY2FsZSBub3IgYW55IG9mIGl0cyBmYWxsIGJhY2sgbG9jYWxlcwogICogY291bGQgYmUgZm91bmQuCiAgKiBUaGUgY2FsbGVyIG93bnMgdGhlIHJldHVybmVkIG9iamVjdCBhbmQgaXMgcmVzcG9uc2libGUgZm9yIGRlbGV0aW5nIGl0LgogICoKICAqIEBwYXJhbSBlcnIgICAgdGhlIGVycm9yIGNvZGUgc3RhdHVzLgogICogQHJldHVybiAgICAgICB0aGUgY29sbGF0aW9uIG9iamVjdCBvZiB0aGUgZGVmYXVsdCBsb2NhbGUuKGZvciBleGFtcGxlLCBlbl9VUykKICAqIEBzZWUgTG9jYWxlI2dldERlZmF1bHQKICAqIEBzdGFibGUKICAqLwogIHN0YXRpYyBDb2xsYXRvciogY3JlYXRlSW5zdGFuY2UoVUVycm9yQ29kZSYgIGVycik7CgogIC8qKgogICogR2V0cyB0aGUgdGFibGUtYmFzZWQgY29sbGF0aW9uIG9iamVjdCBmb3IgdGhlIGRlc2lyZWQgbG9jYWxlLiBUaGUKICAqIHJlc291cmNlIG9mIHRoZSBkZXNpcmVkIGxvY2FsZSB3aWxsIGJlIGxvYWRlZCBieSBSZXNvdXJjZUxvYWRlci4gCiAgKiBMb2NhbGU6OkVOR0xJU0ggaXMgdGhlIGJhc2UgY29sbGF0aW9uIHRhYmxlIGFuZCBhbGwgb3RoZXIgbGFuZ3VhZ2VzIGFyZSAKICAqIGJ1aWx0IG9uIHRvcCBvZiBpdCB3aXRoIGFkZGl0aW9uYWwgbGFuZ3VhZ2Utc3BlY2lmaWMgbW9kaWZpY2F0aW9ucy4KICAqIFRoZSBVRXJyb3JDb2RlJiBlcnIgcGFyYW1ldGVyIGlzIHVzZWQgdG8gcmV0dXJuIHN0YXR1cyBpbmZvcm1hdGlvbiB0byB0aGUgdXNlci4KICAqIFRvIGNoZWNrIHdoZXRoZXIgdGhlIGNvbnN0cnVjdGlvbiBzdWNjZWVkZWQgb3Igbm90LCB5b3Ugc2hvdWxkIGNoZWNrCiAgKiB0aGUgdmFsdWUgb2YgVV9TVUNDRVNTKGVycikuICBJZiB5b3Ugd2lzaCBtb3JlIGRldGFpbGVkIGluZm9ybWF0aW9uLCB5b3UKICAqIGNhbiBjaGVjayBmb3IgaW5mb3JtYXRpb25hbCBlcnJvciByZXN1bHRzIHdoaWNoIHN0aWxsIGluZGljYXRlIHN1Y2Nlc3MuCiAgKiBVX1VTSU5HX0ZBTExCQUNLX0VSUk9SIGluZGljYXRlcyB0aGF0IGEgZmFsbCBiYWNrIGxvY2FsZSB3YXMgdXNlZC4gIEZvcgogICogZXhhbXBsZSwgJ2RlX0NIJyB3YXMgcmVxdWVzdGVkLCBidXQgbm90aGluZyB3YXMgZm91bmQgdGhlcmUsIHNvICdkZScgd2FzCiAgKiB1c2VkLiAgVV9VU0lOR19ERUZBVUxUX0VSUk9SIGluZGljYXRlcyB0aGF0IHRoZSBkZWZhdWx0IGxvY2FsZSBkYXRhIHdhcwogICogdXNlZDsgbmVpdGhlciB0aGUgcmVxdWVzdGVkIGxvY2FsZSBub3IgYW55IG9mIGl0cyBmYWxsIGJhY2sgbG9jYWxlcwogICogY291bGQgYmUgZm91bmQuCiAgKiBUaGUgY2FsbGVyIG93bnMgdGhlIHJldHVybmVkIG9iamVjdCBhbmQgaXMgcmVzcG9uc2libGUgZm9yIGRlbGV0aW5nIGl0LgogICogQHBhcmFtIGxvYyAgICBUaGUgbG9jYWxlIElEIGZvciB3aGljaCB0byBvcGVuIGEgY29sbGF0b3IuCiAgKiBAcGFyYW0gZXJyICAgIHRoZSBlcnJvciBjb2RlIHN0YXR1cy4KICAqIEByZXR1cm4gICAgICAgdGhlIGNyZWF0ZWQgdGFibGUtYmFzZWQgY29sbGF0aW9uIG9iamVjdCBiYXNlZCBvbiB0aGUgZGVzaXJlZAogICogICAgICAgICAgICAgICBsb2NhbGUuCiAgKiBAc2VlIExvY2FsZQogICogQHNlZSBSZXNvdXJjZUxvYWRlcgogICogQHN0YWJsZQogICovCiAgc3RhdGljIENvbGxhdG9yKiBjcmVhdGVJbnN0YW5jZShjb25zdCBMb2NhbGUmIGxvYywgVUVycm9yQ29kZSYgZXJyKTsKCiAgLyoqCiAgICogQ3JlYXRlIGEgQ29sbGF0b3Igd2l0aCBhIHNwZWNpZmljIHZlcnNpb24uCiAgICogVGhpcyBpcyB0aGUgc2FtZSBhcyBjcmVhdGVJbnN0YW5jZShsb2MsIGVycikgZXhjZXB0IHRoYXQgZ2V0VmVyc2lvbigpIG9mCiAgICogdGhlIHJldHVybmVkIG9iamVjdCBpcyBndWFyYW50ZWVkIHRvIGJlIHRoZSBzYW1lIGFzIHRoZSB2ZXJzaW9uCiAgICogcGFyYW1ldGVyLgogICAqIFRoaXMgaXMgZGVzaWduZWQgdG8gYmUgdXNlZCB0byBvcGVuIHRoZSBzYW1lIGNvbGxhdG9yIGZvciBhIGdpdmVuCiAgICogbG9jYWxlIGV2ZW4gd2hlbiBJQ1UgaXMgdXBkYXRlZC4KICAgKiBUaGUgc2FtZSBsb2NhbGUgYW5kIHZlcnNpb24gZ3VhcmFudGVlcyB0aGUgc2FtZSBzb3J0IGtleXMgYW5kCiAgICogY29tcGFyaXNvbiByZXN1bHRzLgogICAqCiAgICogQHBhcmFtIGxvYyBUaGUgbG9jYWxlIElEIGZvciB3aGljaCB0byBvcGVuIGEgY29sbGF0b3IuCiAgICogQHBhcmFtIHZlcnNpb24gVGhlIHJlcXVlc3RlZCBjb2xsYXRvciB2ZXJzaW9uLgogICAqIEBwYXJhbSBlcnIgQSByZWZlcmVuY2UgdG8gYSBVRXJyb3JDb2RlLAogICAqICAgICAgICAgICAgbXVzdCBub3QgaW5kaWNhdGUgYSBmYWlsdXJlIGJlZm9yZSBjYWxsaW5nIHRoaXMgZnVuY3Rpb24uCiAgICogQHJldHVybiBBIHBvaW50ZXIgdG8gYSBDb2xsYXRvciwgb3IgMCBpZiBhbiBlcnJvciBvY2N1cnJlZAogICAqICAgICAgICAgb3IgYSBjb2xsYXRvciB3aXRoIHRoZSByZXF1ZXN0ZWQgdmVyc2lvbiBpcyBub3QgYXZhaWxhYmxlLgogICAqCiAgICogQHNlZSBnZXRWZXJzaW9uCiAgICogQHN0YWJsZSAyLjIKICAgKi8KICBzdGF0aWMgQ29sbGF0b3IgKmNyZWF0ZUluc3RhbmNlKGNvbnN0IExvY2FsZSAmbG9jLCBVVmVyc2lvbkluZm8gdmVyc2lvbiwgVUVycm9yQ29kZSAmZXJyKTsKCiAgLyoqCiAgKiBUaGUgY29tcGFyaXNvbiBmdW5jdGlvbiBjb21wYXJlcyB0aGUgY2hhcmFjdGVyIGRhdGEgc3RvcmVkIGluIHR3bwogICogZGlmZmVyZW50IHN0cmluZ3MuIFJldHVybnMgaW5mb3JtYXRpb24gYWJvdXQgd2hldGhlciBhIHN0cmluZyBpcyBsZXNzIAogICogdGhhbiwgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIGFub3RoZXIgc3RyaW5nLgogICogQHBhcmFtIHNvdXJjZSB0aGUgc291cmNlIHN0cmluZyB0byBiZSBjb21wYXJlZCB3aXRoLgogICogQHBhcmFtIHRhcmdldCB0aGUgc3RyaW5nIHRoYXQgaXMgdG8gYmUgY29tcGFyZWQgd2l0aCB0aGUgc291cmNlIHN0cmluZy4KICAqIEByZXR1cm4gUmV0dXJucyBhIGJ5dGUgdmFsdWUuIEdSRUFURVIgaWYgc291cmNlIGlzIGdyZWF0ZXIKICAqIHRoYW4gdGFyZ2V0OyBFUVVBTCBpZiBzb3VyY2UgaXMgZXF1YWwgdG8gdGFyZ2V0OyBMRVNTIGlmIHNvdXJjZSBpcyBsZXNzCiAgKiB0aGFuIHRhcmdldAogICogQHN0YWJsZQogICoqLwogIHZpcnR1YWwgRUNvbXBhcmlzb25SZXN1bHQgY29tcGFyZShjb25zdCBVbmljb2RlU3RyaW5nJiBzb3VyY2UsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBVbmljb2RlU3RyaW5nJiB0YXJnZXQpIGNvbnN0ID0gMDsKCiAgLyoqCiAgKiBEb2VzIHRoZSBzYW1lIHRoaW5nIGFzIGNvbXBhcmUgYnV0IGxpbWl0cyB0aGUgY29tcGFyaXNvbiB0byBhIHNwZWNpZmllZCAKICAqIGxlbmd0aAogICogQHBhcmFtIHNvdXJjZSB0aGUgc291cmNlIHN0cmluZyB0byBiZSBjb21wYXJlZCB3aXRoLgogICogQHBhcmFtIHRhcmdldCB0aGUgc3RyaW5nIHRoYXQgaXMgdG8gYmUgY29tcGFyZWQgd2l0aCB0aGUgc291cmNlIHN0cmluZy4KICAqIEBwYXJhbSBsZW5ndGggdGhlIGxlbmd0aCB0aGUgY29tcGFyaXNvbiBpcyBsaW1pdHRlZCB0bwogICogQHJldHVybiBSZXR1cm5zIGEgYnl0ZSB2YWx1ZS4gR1JFQVRFUiBpZiBzb3VyY2UgKHVwIHRvIHRoZSBzcGVjaWZpZWQgCiAgKiAgICAgICAgIGxlbmd0aCkgaXMgZ3JlYXRlciB0aGFuIHRhcmdldDsgRVFVQUwgaWYgc291cmNlICh1cCB0byBzcGVjaWZpZWQgCiAgKiAgICAgICAgIGxlbmd0aCkgaXMgZXF1YWwgdG8gdGFyZ2V0OyBMRVNTIGlmIHNvdXJjZSAodXAgdG8gdGhlIHNwZWNpZmllZCAKICAqICAgICAgICAgbGVuZ3RoKSBpcyBsZXNzICB0aGFuIHRhcmdldC4gICAKICAqIEBzdGFibGUKICAqLwogIHZpcnR1YWwgRUNvbXBhcmlzb25SZXN1bHQgY29tcGFyZShjb25zdCBVbmljb2RlU3RyaW5nJiBzb3VyY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFVuaWNvZGVTdHJpbmcmIHRhcmdldCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50MzJfdCBsZW5ndGgpIGNvbnN0ID0gMDsKICAgIAogIC8qKgogICogVGhlIGNvbXBhcmlzb24gZnVuY3Rpb24gY29tcGFyZXMgdGhlIGNoYXJhY3RlciBkYXRhIHN0b3JlZCBpbiB0d28KICAqIGRpZmZlcmVudCBzdHJpbmcgYXJyYXlzLiBSZXR1cm5zIGluZm9ybWF0aW9uIGFib3V0IHdoZXRoZXIgYSBzdHJpbmcgYXJyYXkgCiAgKiBpcyBsZXNzIHRoYW4sIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byBhbm90aGVyIHN0cmluZyBhcnJheS4KICAqIEBwYXJhbSBzb3VyY2UgdGhlIHNvdXJjZSBzdHJpbmcgYXJyYXkgdG8gYmUgY29tcGFyZWQgd2l0aC4KICAqIEBwYXJhbSBzb3VyY2VMZW5ndGggdGhlIGxlbmd0aCBvZiB0aGUgc291cmNlIHN0cmluZyBhcnJheS4gIElmIHRoaXMgdmFsdWUKICAqICAgICAgICBpcyBlcXVhbCB0byAtMSwgdGhlIHN0cmluZyBhcnJheSBpcyBudWxsLXRlcm1pbmF0ZWQuCiAgKiBAcGFyYW0gdGFyZ2V0IHRoZSBzdHJpbmcgdGhhdCBpcyB0byBiZSBjb21wYXJlZCB3aXRoIHRoZSBzb3VyY2Ugc3RyaW5nLgogICogQHBhcmFtIHRhcmdldExlbmd0aCB0aGUgbGVuZ3RoIG9mIHRoZSB0YXJnZXQgc3RyaW5nIGFycmF5LiAgSWYgdGhpcyB2YWx1ZQogICogICAgICAgIGlzIGVxdWFsIHRvIC0xLCB0aGUgc3RyaW5nIGFycmF5IGlzIG51bGwtdGVybWluYXRlZC4KICAqIEByZXR1cm4gUmV0dXJucyBhIGJ5dGUgdmFsdWUuIEdSRUFURVIgaWYgc291cmNlIGlzIGdyZWF0ZXIgdGhhbiB0YXJnZXQ7IAogICogICAgICAgICBFUVVBTCBpZiBzb3VyY2UgaXMgZXF1YWwgdG8gdGFyZ2V0OyBMRVNTIGlmIHNvdXJjZSBpcyBsZXNzIHRoYW4gCiAgKiAgICAgICAgIHRhcmdldAogICogQHN0YWJsZQogICovCiAgdmlydHVhbCBFQ29tcGFyaXNvblJlc3VsdCBjb21wYXJlKGNvbnN0IFVDaGFyKiBzb3VyY2UsIGludDMyX3Qgc291cmNlTGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBVQ2hhciogdGFyZ2V0LCBpbnQzMl90IHRhcmdldExlbmd0aCkgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0ID0gMDsKCiAgLyoqIAogICogVHJhbnNmb3JtcyB0aGUgc3RyaW5nIGludG8gYSBzZXJpZXMgb2YgY2hhcmFjdGVycyB0aGF0IGNhbiBiZSBjb21wYXJlZAogICogd2l0aCBDb2xsYXRpb25LZXk6OmNvbXBhcmVUby4gSXQgaXMgbm90IHBvc3NpYmxlIHRvIHJlc3RvcmUgdGhlIG9yaWdpbmFsCiAgKiBzdHJpbmcgZnJvbSB0aGUgY2hhcnMgaW4gdGhlIHNvcnQga2V5LiAgVGhlIGdlbmVyYXRlZCBzb3J0IGtleSBoYW5kbGVzIAogICogb25seSBhIGxpbWl0ZWQgbnVtYmVyIG9mIGlnbm9yYWJsZSBjaGFyYWN0ZXJzLgogICogPHA+VXNlIENvbGxhdGlvbktleTo6ZXF1YWxzIG9yIENvbGxhdGlvbktleTo6Y29tcGFyZSB0byBjb21wYXJlIHRoZQogICogZ2VuZXJhdGVkIHNvcnQga2V5cy4KICAqIElmIHRoZSBzb3VyY2Ugc3RyaW5nIGlzIG51bGwsIGEgbnVsbCBjb2xsYXRpb24ga2V5IHdpbGwgYmUgcmV0dXJuZWQuCiAgKiBAcGFyYW0gc291cmNlIHRoZSBzb3VyY2Ugc3RyaW5nIHRvIGJlIHRyYW5zZm9ybWVkIGludG8gYSBzb3J0IGtleS4KICAqIEBwYXJhbSBrZXkgdGhlIGNvbGxhdGlvbiBrZXkgdG8gYmUgZmlsbGVkIGluCiAgKiBAcGFyYW0gc3RhdHVzIHRoZSBlcnJvciBjb2RlIHN0YXR1cy4KICAqIEByZXR1cm4gdGhlIGNvbGxhdGlvbiBrZXkgb2YgdGhlIHN0cmluZyBiYXNlZCBvbiB0aGUgY29sbGF0aW9uIHJ1bGVzLgogICogQHNlZSBDb2xsYXRpb25LZXkjY29tcGFyZQogICogQHN0YWJsZQogICovCiAgdmlydHVhbCBDb2xsYXRpb25LZXkmIGdldENvbGxhdGlvbktleShjb25zdCBVbmljb2RlU3RyaW5nJiAgc291cmNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29sbGF0aW9uS2V5JiBrZXksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiBzdGF0dXMpIGNvbnN0ID0gMDsKCiAgLyoqIAogICogVHJhbnNmb3JtcyB0aGUgc3RyaW5nIGludG8gYSBzZXJpZXMgb2YgY2hhcmFjdGVycyB0aGF0IGNhbiBiZSBjb21wYXJlZAogICogd2l0aCBDb2xsYXRpb25LZXk6OmNvbXBhcmVUby4gSXQgaXMgbm90IHBvc3NpYmxlIHRvIHJlc3RvcmUgdGhlIG9yaWdpbmFsCiAgKiBzdHJpbmcgZnJvbSB0aGUgY2hhcnMgaW4gdGhlIHNvcnQga2V5LiAgVGhlIGdlbmVyYXRlZCBzb3J0IGtleSBoYW5kbGVzIAogICogb25seSBhIGxpbWl0ZWQgbnVtYmVyIG9mIGlnbm9yYWJsZSBjaGFyYWN0ZXJzLgogICogPHA+VXNlIENvbGxhdGlvbktleTo6ZXF1YWxzIG9yIENvbGxhdGlvbktleTo6Y29tcGFyZSB0byBjb21wYXJlIHRoZQogICogZ2VuZXJhdGVkIHNvcnQga2V5cy4KICAqIDxwPklmIHRoZSBzb3VyY2Ugc3RyaW5nIGlzIG51bGwsIGEgbnVsbCBjb2xsYXRpb24ga2V5IHdpbGwgYmUgcmV0dXJuZWQuCiAgKiBAcGFyYW0gc291cmNlIHRoZSBzb3VyY2Ugc3RyaW5nIHRvIGJlIHRyYW5zZm9ybWVkIGludG8gYSBzb3J0IGtleS4KICAqIEBwYXJhbSBzb3VyY2VMZW5ndGggbGVuZ3RoIG9mIHRoZSBjb2xsYXRpb24ga2V5CiAgKiBAcGFyYW0ga2V5IHRoZSBjb2xsYXRpb24ga2V5IHRvIGJlIGZpbGxlZCBpbgogICogQHBhcmFtIHN0YXR1cyB0aGUgZXJyb3IgY29kZSBzdGF0dXMuCiAgKiBAcmV0dXJuIHRoZSBjb2xsYXRpb24ga2V5IG9mIHRoZSBzdHJpbmcgYmFzZWQgb24gdGhlIGNvbGxhdGlvbiBydWxlcy4KICAqIEBzZWUgQ29sbGF0aW9uS2V5I2NvbXBhcmUKICAqIEBzdGFibGUKICAqLwogIHZpcnR1YWwgQ29sbGF0aW9uS2V5JiBnZXRDb2xsYXRpb25LZXkoY29uc3QgVUNoYXIqc291cmNlLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludDMyX3Qgc291cmNlTGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29sbGF0aW9uS2V5JiBrZXksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiBzdGF0dXMpIGNvbnN0ID0gMDsKICAvKioKICAqIEdlbmVyYXRlcyB0aGUgaGFzaCBjb2RlIGZvciB0aGUgY29sbGF0aW9uIG9iamVjdAogICogQHN0YWJsZQogICovCiAgdmlydHVhbCBpbnQzMl90IGhhc2hDb2RlKHZvaWQpIGNvbnN0ID0gMDsKCiAgLyoqCiAgKiBHZXRzIHRoZSBsb2NhbGUgb2YgdGhlIENvbGxhdG9yCiAgKgogICogQHBhcmFtIHR5cGUgY2FuIGJlIGVpdGhlciByZXF1ZXN0ZWQsIHZhbGlkIG9yIGFjdHVhbCBsb2NhbGUuIEZvciBtb3JlCiAgKiAgICAgICAgICAgICBpbmZvcm1hdGlvbiBzZWUgdGhlIGRlZmluaXRpb24gb2YgVUxvY0RhdGFMb2NhbGVUeXBlIGluCiAgKiAgICAgICAgICAgICB1bG9jLmgKICAqIEByZXR1cm4gbG9jYWxlIHdoZXJlIHRoZSBjb2xsYXRpb24gZGF0YSBsaXZlcy4gSWYgdGhlIGNvbGxhdG9yCiAgKiAgICAgICAgIHdhcyBpbnN0YW50aWF0ZWQgZnJvbSBydWxlcywgbG9jYWxlIGlzIGVtcHR5LgogICogQGRyYWZ0IElDVSAyLjEKICAqLwogIHZpcnR1YWwgY29uc3QgTG9jYWxlIGdldExvY2FsZShVTG9jRGF0YUxvY2FsZVR5cGUgdHlwZSwgVUVycm9yQ29kZSYgc3RhdHVzKSBjb25zdCA9IDA7CgogIC8qKgogICogQ29udmVuaWVuY2UgbWV0aG9kIGZvciBjb21wYXJpbmcgdHdvIHN0cmluZ3MgYmFzZWQgb24gdGhlIGNvbGxhdGlvbiBydWxlcy4KICAqIEBwYXJhbSBzb3VyY2UgdGhlIHNvdXJjZSBzdHJpbmcgdG8gYmUgY29tcGFyZWQgd2l0aC4KICAqIEBwYXJhbSB0YXJnZXQgdGhlIHRhcmdldCBzdHJpbmcgdG8gYmUgY29tcGFyZWQgd2l0aC4KICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgZmlyc3Qgc3RyaW5nIGlzIGdyZWF0ZXIgdGhhbiB0aGUgc2Vjb25kIG9uZSwKICAqICAgICAgICAgYWNjb3JkaW5nIHRvIHRoZSBjb2xsYXRpb24gcnVsZXMuIGZhbHNlLCBvdGhlcndpc2UuCiAgKiBAc2VlIENvbGxhdG9yI2NvbXBhcmUKICAqIEBzdGFibGUKICAqLwogIFVCb29sIGdyZWF0ZXIoY29uc3QgVW5pY29kZVN0cmluZyYgc291cmNlLCBjb25zdCBVbmljb2RlU3RyaW5nJiB0YXJnZXQpIAogICAgICAgICAgICAgICAgY29uc3Q7CgogIC8qKgogICogQ29udmVuaWVuY2UgbWV0aG9kIGZvciBjb21wYXJpbmcgdHdvIHN0cmluZ3MgYmFzZWQgb24gdGhlIGNvbGxhdGlvbiBydWxlcy4KICAqIEBwYXJhbSBzb3VyY2UgdGhlIHNvdXJjZSBzdHJpbmcgdG8gYmUgY29tcGFyZWQgd2l0aC4KICAqIEBwYXJhbSB0YXJnZXQgdGhlIHRhcmdldCBzdHJpbmcgdG8gYmUgY29tcGFyZWQgd2l0aC4KICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgZmlyc3Qgc3RyaW5nIGlzIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byB0aGUgc2Vjb25kIAogICogICAgICAgICBvbmUsIGFjY29yZGluZyB0byB0aGUgY29sbGF0aW9uIHJ1bGVzLiBmYWxzZSwgb3RoZXJ3aXNlLgogICogQHNlZSBDb2xsYXRvciNjb21wYXJlCiAgKiBAc3RhYmxlCiAgKi8KICBVQm9vbCBncmVhdGVyT3JFcXVhbChjb25zdCBVbmljb2RlU3RyaW5nJiBzb3VyY2UsIAogICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFVuaWNvZGVTdHJpbmcmIHRhcmdldCkgY29uc3Q7CiAgLyoqCiAgKiBDb252ZW5pZW5jZSBtZXRob2QgZm9yIGNvbXBhcmluZyB0d28gc3RyaW5ncyBiYXNlZCBvbiB0aGUgY29sbGF0aW9uIHJ1bGVzLgogICogQHBhcmFtIHNvdXJjZSB0aGUgc291cmNlIHN0cmluZyB0byBiZSBjb21wYXJlZCB3aXRoLgogICogQHBhcmFtIHRhcmdldCB0aGUgdGFyZ2V0IHN0cmluZyB0byBiZSBjb21wYXJlZCB3aXRoLgogICogQHJldHVybiB0cnVlIGlmIHRoZSBzdHJpbmdzIGFyZSBlcXVhbCBhY2NvcmRpbmcgdG8gdGhlIGNvbGxhdGlvbiBydWxlcy4gIAogICogICAgICAgICBmYWxzZSwgb3RoZXJ3aXNlLgogICogQHNlZSBDb2xsYXRvciNjb21wYXJlCiAgKiBAc3RhYmxlCiAgKi8KICBVQm9vbCBlcXVhbHMoY29uc3QgVW5pY29kZVN0cmluZyYgc291cmNlLCBjb25zdCBVbmljb2RlU3RyaW5nJiB0YXJnZXQpIGNvbnN0OwogICAgICAgIAogIC8qKgogICogRGV0ZXJtaW5lcyB0aGUgbWluaW11bSBzdHJlbmd0aCB0aGF0IHdpbGwgYmUgdXNlIGluIGNvbXBhcmlzb24gb3IKICAqIHRyYW5zZm9ybWF0aW9uLgogICogPHA+RS5nLiB3aXRoIHN0cmVuZ3RoID09IFNFQ09OREFSWSwgdGhlIHRlcnRpYXJ5IGRpZmZlcmVuY2UgaXMgaWdub3JlZAogICogPHA+RS5nLiB3aXRoIHN0cmVuZ3RoID09IFBSSU1BUlksIHRoZSBzZWNvbmRhcnkgYW5kIHRlcnRpYXJ5IGRpZmZlcmVuY2UKICAqIGFyZSBpZ25vcmVkLgogICogQHJldHVybiB0aGUgY3VycmVudCBjb21wYXJpc29uIGxldmVsLgogICogQHNlZSBDb2xsYXRvciNzZXRTdHJlbmd0aAogICogQHN0YWJsZQogICovCiAgdmlydHVhbCBFQ29sbGF0aW9uU3RyZW5ndGggZ2V0U3RyZW5ndGgodm9pZCkgY29uc3QgPSAwOwogIAogIC8qKgogICogU2V0cyB0aGUgbWluaW11bSBzdHJlbmd0aCB0byBiZSB1c2VkIGluIGNvbXBhcmlzb24gb3IgdHJhbnNmb3JtYXRpb24uCiAgKiA8cD5FeGFtcGxlIG9mIHVzZToKICAqIDxwcmU+CiAgKiAgXGNvZGUKICAqICBVRXJyb3JDb2RlIHN0YXR1cyA9IFVfWkVST19FUlJPUjsKICAqICBDb2xsYXRvcipteUNvbGxhdGlvbiA9IENvbGxhdG9yOjpjcmVhdGVJbnN0YW5jZShMb2NhbGU6OlVTLCAKICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdHVzKTsKICAqICBpZiAoVV9GQUlMVVJFKHN0YXR1cykpIHJldHVybjsKICAqICBteUNvbGxhdGlvbi0+c2V0U3RyZW5ndGgoQ29sbGF0b3I6OlBSSU1BUlkpOwogICogIC8vIHJlc3VsdCB3aWxsIGJlICJhYmMiID09ICJBQkMiCiAgKiAgLy8gdGVydGlhcnkgZGlmZmVyZW5jZXMgd2lsbCBiZSBpZ25vcmVkCiAgKiAgQ29sbGF0b3I6OkNvbXBhcmlzb25SZXN1bHQgcmVzdWx0ID0gbXlDb2xsYXRpb24tPmNvbXBhcmUoImFiYyIsIAogICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJBQkMiKTsKICAqIFxlbmRjb2RlIAogICogPC9wcmU+CiAgKiBAc2VlIENvbGxhdG9yI2dldFN0cmVuZ3RoCiAgKiBAcGFyYW0gbmV3U3RyZW5ndGggdGhlIG5ldyBjb21wYXJpc29uIGxldmVsLgogICogQHN0YWJsZQogICovCiAgdmlydHVhbCB2b2lkIHNldFN0cmVuZ3RoKEVDb2xsYXRpb25TdHJlbmd0aCBuZXdTdHJlbmd0aCkgPSAwOwoKICAvKioKICAqIEdldCBuYW1lIG9mIHRoZSBvYmplY3QgZm9yIHRoZSBkZXNpcmVkIExvY2FsZSwgaW4gdGhlIGRlc2lyZWQgbGFuZ2F1Z2UKICAqIEBwYXJhbSBvYmplY3RMb2NhbGUgbXVzdCBiZSBmcm9tIGdldEF2YWlsYWJsZUxvY2FsZXMKICAqIEBwYXJhbSBkaXNwbGF5TG9jYWxlIHNwZWNpZmllcyB0aGUgZGVzaXJlZCBsb2NhbGUgZm9yIG91dHB1dAogICogQHBhcmFtIG5hbWUgdGhlIGZpbGwtaW4gcGFyYW1ldGVyIG9mIHRoZSByZXR1cm4gdmFsdWUKICAqIEByZXR1cm4gZGlzcGxheS1hYmxlIG5hbWUgb2YgdGhlIG9iamVjdCBmb3IgdGhlIG9iamVjdCBsb2NhbGUgaW4gdGhlCiAgKiAgICAgICAgIGRlc2lyZWQgbGFuZ3VhZ2UKICAqIEBzdGFibGUKICAqLwogIHN0YXRpYyBVbmljb2RlU3RyaW5nJiBnZXREaXNwbGF5TmFtZShjb25zdCBMb2NhbGUmIG9iamVjdExvY2FsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTG9jYWxlJiBkaXNwbGF5TG9jYWxlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVbmljb2RlU3RyaW5nJiBuYW1lKTsKICAvKioKICAqIEdldCBuYW1lIG9mIHRoZSBvYmplY3QgZm9yIHRoZSBkZXNpcmVkIExvY2FsZSwgaW4gdGhlIGxhbmdhdWdlIG9mIHRoZQogICogZGVmYXVsdCBsb2NhbGUuCiAgKiBAcGFyYW0gb2JqZWN0TG9jYWxlIG11c3QgYmUgZnJvbSBnZXRBdmFpbGFibGVMb2NhbGVzCiAgKiBAcGFyYW0gbmFtZSB0aGUgZmlsbC1pbiBwYXJhbWV0ZXIgb2YgdGhlIHJldHVybiB2YWx1ZQogICogQHJldHVybiBuYW1lIG9mIHRoZSBvYmplY3QgZm9yIHRoZSBkZXNpcmVkIGxvY2FsZSBpbiB0aGUgZGVmYXVsdCBsYW5ndWFnZQogICogQHN0YWJsZQogICovCiAgc3RhdGljIFVuaWNvZGVTdHJpbmcmIGdldERpc3BsYXlOYW1lKGNvbnN0IExvY2FsZSYgb2JqZWN0TG9jYWxlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVbmljb2RlU3RyaW5nJiBuYW1lKTsKCiAgLyoqCiAgKiBHZXQgdGhlIHNldCBvZiBMb2NhbGVzIGZvciB3aGljaCBDb2xsYXRpb25zIGFyZSBpbnN0YWxsZWQKICAqIEBwYXJhbSBjb3VudCB0aGUgb3V0cHV0IHBhcmFtZXRlciBvZiBudW1iZXIgb2YgZWxlbWVudHMgaW4gdGhlIGxvY2FsZSBsaXN0CiAgKiBAcmV0dXJuIHRoZSBsaXN0IG9mIGF2YWlsYWJsZSBsb2NhbGVzIHdoaWNoIGNvbGxhdGlvbnMgYXJlIGluc3RhbGxlZAogICogQHN0YWJsZQogICovCiAgc3RhdGljIGNvbnN0IExvY2FsZSogZ2V0QXZhaWxhYmxlTG9jYWxlcyhpbnQzMl90JiBjb3VudCk7CgogIC8qKgogICogR2V0cyB0aGUgdmVyc2lvbiBpbmZvcm1hdGlvbiBmb3IgYSBDb2xsYXRvci4gCiAgKiBAcGFyYW0gaW5mbyB0aGUgdmVyc2lvbiAjIGluZm9ybWF0aW9uLCB0aGUgcmVzdWx0IHdpbGwgYmUgZmlsbGVkIGluCiAgKiBAc3RhYmxlCiAgKi8KICB2aXJ0dWFsIHZvaWQgZ2V0VmVyc2lvbihVVmVyc2lvbkluZm8gaW5mbykgY29uc3QgPSAwOwoKICAvKioKICAqIFJldHVybnMgYSB1bmlxdWUgY2xhc3MgSUQgUE9MWU1PUlBISUNBTExZLiBQdXJlIHZpcnR1YWwgbWV0aG9kLgogICogVGhpcyBtZXRob2QgaXMgdG8gaW1wbGVtZW50IGEgc2ltcGxlIHZlcnNpb24gb2YgUlRUSSwgc2luY2Ugbm90IGFsbCBDKysgCiAgKiBjb21waWxlcnMgc3VwcG9ydCBnZW51aW5lIFJUVEkuIFBvbHltb3JwaGljIG9wZXJhdG9yPT0oKSBhbmQgY2xvbmUoKSAKICAqIG1ldGhvZHMgY2FsbCB0aGlzIG1ldGhvZC4KICAqIENvbmNyZXRlIHN1YmNsYXNzZXMgb2YgRm9ybWF0IG11c3QgaW1wbGVtZW50IGdldER5bmFtaWNDbGFzc0lEKCkgYW5kIGFsc28gCiAgKiBhIHN0YXRpYyBtZXRob2QgYW5kIGRhdGEgbWVtYmVyOgogICogICBzdGF0aWMgVUNsYXNzSUQgZ2V0U3RhdGljQ2xhc3NJRCgpIAogICogICB7IAogICogICAgICByZXR1cm4gKFVDbGFzc0lEKSZmZ0NsYXNzSUQ7IAogICogICB9CiAgKiAgIHN0YXRpYyBjaGFyIGZnQ2xhc3NJRDsKICAqIEByZXR1cm4gVGhlIGNsYXNzIElEIGZvciB0aGlzIG9iamVjdC4gQWxsIG9iamVjdHMgb2YgYSBnaXZlbiBjbGFzcyBoYXZlIAogICogICAgICAgICB0aGUgc2FtZSBjbGFzcyBJRC4gIE9iamVjdHMgb2Ygb3RoZXIgY2xhc3NlcyBoYXZlIGRpZmZlcmVudCBjbGFzcyAKICAqICAgICAgICAgSURzLgogICogQHN0YWJsZQogICovCiAgdmlydHVhbCBVQ2xhc3NJRCBnZXREeW5hbWljQ2xhc3NJRCh2b2lkKSBjb25zdCA9IDA7CgogIC8qKgogICogVW5pdmVyc2FsIGF0dHJpYnV0ZSBzZXR0ZXIKICAqIEBwYXJhbSBhdHRyIGF0dHJpYnV0ZSB0eXBlIAogICogQHBhcmFtIHZhbHVlIGF0dHJpYnV0ZSB2YWx1ZQogICogQHBhcmFtIHN0YXR1cyB0byBpbmRpY2F0ZSB3aGV0aGVyIHRoZSBvcGVyYXRpb24gd2VudCBvbiBzbW9vdGhseSBvciAKICAqICAgICAgICB0aGVyZSB3ZXJlIGVycm9ycwogICogQHN0YWJsZSAyLjIKICAqLwogIHZpcnR1YWwgdm9pZCBzZXRBdHRyaWJ1dGUoVUNvbEF0dHJpYnV0ZSBhdHRyLCBVQ29sQXR0cmlidXRlVmFsdWUgdmFsdWUsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSAmc3RhdHVzKSA9IDA7CgogIC8qKgogICogVW5pdmVyc2FsIGF0dHJpYnV0ZSBnZXR0ZXIKICAqIEBwYXJhbSBhdHRyIGF0dHJpYnV0ZSB0eXBlCiAgKiBAcGFyYW0gc3RhdHVzIHRvIGluZGljYXRlIHdoZXRoZXIgdGhlIG9wZXJhdGlvbiB3ZW50IG9uIHNtb290aGx5IG9yIAogICogICAgICAgIHRoZXJlIHdlcmUgZXJyb3JzCiAgKiBAcmV0dXJuIGF0dHJpYnV0ZSB2YWx1ZQogICogQHN0YWJsZSAyLjIKICAqLwogIHZpcnR1YWwgVUNvbEF0dHJpYnV0ZVZhbHVlIGdldEF0dHJpYnV0ZShVQ29sQXR0cmlidXRlIGF0dHIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlICZzdGF0dXMpID0gMDsKCiAgLyoqIAogICAqIFNldHMgdGhlIHZhcmlhYmxlIHRvcCB0byBhIGNvbGxhdGlvbiBlbGVtZW50IHZhbHVlIG9mIGEgc3RyaW5nIHN1cHBsaWVkLiAKICAgKiBAcGFyYW0gdmFyVG9wIG9uZSBvciBtb3JlIChpZiBjb250cmFjdGlvbikgVUNoYXJzIHRvIHdoaWNoIHRoZSB2YXJpYWJsZSB0b3Agc2hvdWxkIGJlIHNldAogICAqIEBwYXJhbSBsZW4gbGVuZ3RoIG9mIHZhcmlhYmxlIHRvcCBzdHJpbmcuIElmIC0xIGl0IGlzIGNvbnNpZGVyZWQgdG8gYmUgemVybyB0ZXJtaW5hdGVkLgogICAqIEBwYXJhbSBzdGF0dXMgZXJyb3IgY29kZS4gSWYgZXJyb3IgY29kZSBpcyBzZXQsIHRoZSByZXR1cm4gdmFsdWUgaXMgdW5kZWZpbmVkLiBFcnJvcnMgc2V0IGJ5IHRoaXMgZnVuY3Rpb24gYXJlOiA8YnI+CiAgICogICAgVV9DRV9OT1RfRk9VTkRfRVJST1IgaWYgbW9yZSB0aGFuIG9uZSBjaGFyYWN0ZXIgd2FzIHBhc3NlZCBhbmQgdGhlcmUgaXMgbm8gc3VjaCBhIGNvbnRyYWN0aW9uPGJyPgogICAqICAgIFVfUFJJTUFSWV9UT09fTE9OR19FUlJPUiBpZiB0aGUgcHJpbWFyeSBmb3IgdGhlIHZhcmlhYmxlIHRvcCBoYXMgbW9yZSB0aGFuIHR3byBieXRlcwogICAqIEByZXR1cm4gYSAzMiBiaXQgdmFsdWUgY29udGFpbmluZyB0aGUgdmFsdWUgb2YgdGhlIHZhcmlhYmxlIHRvcCBpbiB1cHBlciAxNiBiaXRzLiBMb3dlciAxNiBiaXRzIGFyZSB1bmRlZmluZWQKICAgKiBAZHJhZnQgSUNVIDIuMAogICAqLwogIHZpcnR1YWwgdWludDMyX3Qgc2V0VmFyaWFibGVUb3AoY29uc3QgVUNoYXIgKnZhclRvcCwgaW50MzJfdCBsZW4sIFVFcnJvckNvZGUgJnN0YXR1cykgPSAwOwoKICAvKiogCiAgICogU2V0cyB0aGUgdmFyaWFibGUgdG9wIHRvIGEgY29sbGF0aW9uIGVsZW1lbnQgdmFsdWUgb2YgYSBzdHJpbmcgc3VwcGxpZWQuIAogICAqIEBwYXJhbSB2YXJUb3AgYW4gVW5pY29kZVN0cmluZyBzaXplIDEgb3IgbW9yZSAoaWYgY29udHJhY3Rpb24pIG9mIFVDaGFycyB0byB3aGljaCB0aGUgdmFyaWFibGUgdG9wIHNob3VsZCBiZSBzZXQKICAgKiBAcGFyYW0gc3RhdHVzIGVycm9yIGNvZGUuIElmIGVycm9yIGNvZGUgaXMgc2V0LCB0aGUgcmV0dXJuIHZhbHVlIGlzIHVuZGVmaW5lZC4gRXJyb3JzIHNldCBieSB0aGlzIGZ1bmN0aW9uIGFyZTogPGJyPgogICAqICAgIFVfQ0VfTk9UX0ZPVU5EX0VSUk9SIGlmIG1vcmUgdGhhbiBvbmUgY2hhcmFjdGVyIHdhcyBwYXNzZWQgYW5kIHRoZXJlIGlzIG5vIHN1Y2ggYSBjb250cmFjdGlvbjxicj4KICAgKiAgICBVX1BSSU1BUllfVE9PX0xPTkdfRVJST1IgaWYgdGhlIHByaW1hcnkgZm9yIHRoZSB2YXJpYWJsZSB0b3AgaGFzIG1vcmUgdGhhbiB0d28gYnl0ZXMKICAgKiBAcmV0dXJuIGEgMzIgYml0IHZhbHVlIGNvbnRhaW5pbmcgdGhlIHZhbHVlIG9mIHRoZSB2YXJpYWJsZSB0b3AgaW4gdXBwZXIgMTYgYml0cy4gTG93ZXIgMTYgYml0cyBhcmUgdW5kZWZpbmVkCiAgICogQGRyYWZ0IElDVSAyLjAKICAgKi8KICB2aXJ0dWFsIHVpbnQzMl90IHNldFZhcmlhYmxlVG9wKGNvbnN0IFVuaWNvZGVTdHJpbmcgdmFyVG9wLCBVRXJyb3JDb2RlICZzdGF0dXMpID0gMDsKCiAgLyoqIAogICAqIFNldHMgdGhlIHZhcmlhYmxlIHRvcCB0byBhIGNvbGxhdGlvbiBlbGVtZW50IHZhbHVlIHN1cHBsaWVkLiBWYXJpYWJsZSB0b3AgaXMgc2V0IHRvIHRoZSB1cHBlciAxNiBiaXRzLiAKICAgKiBMb3dlciAxNiBiaXRzIGFyZSBpZ25vcmVkLgogICAqIEBwYXJhbSB2YXJUb3AgQ0UgdmFsdWUsIGFzIHJldHVybmVkIGJ5IHNldFZhcmlhYmxlVG9wIG9yIHVjb2wpZ2V0VmFyaWFibGVUb3AKICAgKiBAcGFyYW0gc3RhdHVzIGVycm9yIGNvZGUgKG5vdCBjaGFuZ2VkIGJ5IGZ1bmN0aW9uKQogICAqIEBkcmFmdCBJQ1UgMi4wCiAgICovCiAgdmlydHVhbCB2b2lkIHNldFZhcmlhYmxlVG9wKGNvbnN0IHVpbnQzMl90IHZhclRvcCwgVUVycm9yQ29kZSAmc3RhdHVzKSA9IDA7CgogIC8qKiAKICAgKiBHZXRzIHRoZSB2YXJpYWJsZSB0b3AgdmFsdWUgb2YgYSBDb2xsYXRvci4gCiAgICogTG93ZXIgMTYgYml0cyBhcmUgdW5kZWZpbmVkIGFuZCBzaG91bGQgYmUgaWdub3JlZC4KICAgKiBAcGFyYW0gc3RhdHVzIGVycm9yIGNvZGUgKG5vdCBjaGFuZ2VkIGJ5IGZ1bmN0aW9uKS4gSWYgZXJyb3IgY29kZSBpcyBzZXQsIHRoZSByZXR1cm4gdmFsdWUgaXMgdW5kZWZpbmVkLgogICAqIEBkcmFmdCBJQ1UgMi4wCiAgICovCiAgdmlydHVhbCB1aW50MzJfdCBnZXRWYXJpYWJsZVRvcChVRXJyb3JDb2RlICZzdGF0dXMpIGNvbnN0ID0gMDsKCgogIC8qKgogICogVGhyZWFkIHNhZmUgY2xvbmluZyBvcGVyYXRpb24KICAqIEByZXR1cm4gcG9pbnRlciB0byB0aGUgbmV3IGNsb25lLCB1c2VyIHNob3VsZCByZW1vdmUgaXQuCiAgKiBAc3RhYmxlIDIuMgogICovCiAgdmlydHVhbCBDb2xsYXRvciogc2FmZUNsb25lKHZvaWQpID0gMDsKCiAgLyoqCiAgKiBHZXQgdGhlIHNvcnQga2V5IGFzIGFuIGFycmF5IG9mIGJ5dGVzIGZyb20gYW4gVW5pY29kZVN0cmluZy4KICAqIFNvcnQga2V5IGJ5dGUgYXJyYXlzIGFyZSB6ZXJvLXRlcm1pbmF0ZWQgYW5kIGNhbiBiZSBjb21wYXJlZCB1c2luZyAKICAqIHN0cmNtcCgpLgogICogQHBhcmFtIHNvdXJjZSBzdHJpbmcgdG8gYmUgcHJvY2Vzc2VkLgogICogQHBhcmFtIHJlc3VsdCBidWZmZXIgdG8gc3RvcmUgcmVzdWx0IGluLiBJZiBOVUxMLCBudW1iZXIgb2YgYnl0ZXMgbmVlZGVkIAogICogICAgICAgIHdpbGwgYmUgcmV0dXJuZWQuCiAgKiBAcGFyYW0gcmVzdWx0TGVuZ3RoIGxlbmd0aCBvZiB0aGUgcmVzdWx0IGJ1ZmZlci4gSWYgaWYgbm90IGVub3VnaCB0aGUgCiAgKiAgICAgICAgYnVmZmVyIHdpbGwgYmUgZmlsbGVkIHRvIGNhcGFjaXR5LiAKICAqIEByZXR1cm4gTnVtYmVyIG9mIGJ5dGVzIG5lZWRlZCBmb3Igc3RvcmluZyB0aGUgc29ydCBrZXkKICAqIEBzdGFibGUgMi4yCiAgKi8KICB2aXJ0dWFsIGludDMyX3QgZ2V0U29ydEtleShjb25zdCBVbmljb2RlU3RyaW5nJiBzb3VyY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1aW50OF90KiByZXN1bHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQzMl90IHJlc3VsdExlbmd0aCkgY29uc3QgPSAwOwoKICAvKioKICAqIEdldCB0aGUgc29ydCBrZXkgYXMgYW4gYXJyYXkgb2YgYnl0ZXMgZnJvbSBhbiBVQ2hhciBidWZmZXIuCiAgKiBTb3J0IGtleSBieXRlIGFycmF5cyBhcmUgemVyby10ZXJtaW5hdGVkIGFuZCBjYW4gYmUgY29tcGFyZWQgdXNpbmcgCiAgKiBzdHJjbXAoKS4KICAqIEBwYXJhbSBzb3VyY2Ugc3RyaW5nIHRvIGJlIHByb2Nlc3NlZC4KICAqIEBwYXJhbSBzb3VyY2VMZW5ndGggbGVuZ3RoIG9mIHN0cmluZyB0byBiZSBwcm9jZXNzZWQuIAogICogICAgICAgIElmIC0xLCB0aGUgc3RyaW5nIGlzIDAgdGVybWluYXRlZCBhbmQgbGVuZ3RoIHdpbGwgYmUgZGVjaWRlZCBieSB0aGUgCiAgKiAgICAgICAgZnVuY3Rpb24uCiAgKiBAcGFyYW0gcmVzdWx0IGJ1ZmZlciB0byBzdG9yZSByZXN1bHQgaW4uIElmIE5VTEwsIG51bWJlciBvZiBieXRlcyBuZWVkZWQgCiAgKiAgICAgICAgd2lsbCBiZSByZXR1cm5lZC4KICAqIEBwYXJhbSByZXN1bHRMZW5ndGggbGVuZ3RoIG9mIHRoZSByZXN1bHQgYnVmZmVyLiBJZiBpZiBub3QgZW5vdWdoIHRoZSAKICAqICAgICAgICBidWZmZXIgd2lsbCBiZSBmaWxsZWQgdG8gY2FwYWNpdHkuIAogICogQHJldHVybiBOdW1iZXIgb2YgYnl0ZXMgbmVlZGVkIGZvciBzdG9yaW5nIHRoZSBzb3J0IGtleQogICogQHN0YWJsZSAyLjIKICAqLwogIHZpcnR1YWwgaW50MzJfdCBnZXRTb3J0S2V5KGNvbnN0IFVDaGFyKnNvdXJjZSwgaW50MzJfdCBzb3VyY2VMZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdWludDhfdCpyZXN1bHQsIGludDMyX3QgcmVzdWx0TGVuZ3RoKSBjb25zdCA9IDA7CgogIC8vIHN0YXJ0IGRlcHJlY2F0ZWQgQVBJcwogIC8qKgogICogR2V0IHRoZSBkZWNvbXBvc2l0aW9uIG1vZGUgb2YgdGhlIENvbGxhdG9yIG9iamVjdC4KICAqIEByZXR1cm4gdGhlIGRlY29tcG9zaXRpb24gbW9kZQogICogQHNlZSBDb2xsYXRvciNzZXREZWNvbXBvc2l0aW9uCiAgKiBAZGVwcmVjYXRlZCBUbyBiZSByZW1vdmVkIGFmdGVyIDIwMDItc2VwLTMwOyB1c2UgZ2V0QXR0cmlidXRlKCkuCiAgKi8KICB2aXJ0dWFsIE5vcm1hbGl6ZXI6OkVNb2RlIGdldERlY29tcG9zaXRpb24odm9pZCkgY29uc3QgPSAwOwoKICAvKioKICAqIFNldCB0aGUgZGVjb21wb3NpdGlvbiBtb2RlIG9mIHRoZSBDb2xsYXRvciBvYmplY3QuIHN1Y2Nlc3MgaXMgZXF1YWwgdG8gCiAgKiBVX0lMTEVHQUxfQVJHVU1FTlRfRVJST1IgaWYgZXJyb3Igb2NjdXJzLgogICogQHBhcmFtIHRoZSBuZXcgZGVjb21wb3NpdGlvbiBtb2RlCiAgKiBAc2VlIENvbGxhdG9yI2dldERlY29tcG9zaXRpb24KICAqIEBkZXByZWNhdGVkIFRvIGJlIHJlbW92ZWQgYWZ0ZXIgMjAwMi1zZXAtMzA7IHVzZSBzZXRBdHRyaWJ1dGUoKS4KICAqLwogIHZpcnR1YWwgdm9pZCBzZXREZWNvbXBvc2l0aW9uKE5vcm1hbGl6ZXI6OkVNb2RlICBtb2RlKSA9IDA7CgoKLyoqCiAqIFByb2R1Y2UgYSBib3VuZCBmb3IgYSBnaXZlbiBzb3J0a2V5IGFuZCBhIG51bWJlciBvZiBsZXZlbHMuCiAqIFJldHVybiB2YWx1ZSBpcyBhbHdheXMgdGhlIG51bWJlciBvZiBieXRlcyBuZWVkZWQsIHJlZ2FyZGxlc3Mgb2YgCiAqIHdoZXRoZXIgdGhlIHJlc3VsdCBidWZmZXIgd2FzIGJpZyBlbm91Z2ggb3IgZXZlbiB2YWxpZC48YnI+CiAqIFJlc3VsdGluZyBib3VuZHMgY2FuIGJlIHVzZWQgdG8gcHJvZHVjZSBhIHJhbmdlIG9mIHN0cmluZ3MgdGhhdCBhcmUKICogYmV0d2VlbiB1cHBlciBhbmQgbG93ZXIgYm91bmRzLiBGb3IgZXhhbXBsZSwgaWYgYm91bmRzIGFyZSBwcm9kdWNlZAogKiBmb3IgYSBzb3J0a2V5IG9mIHN0cmluZyAic21pdGgiLCBzdHJpbmdzIGJldHdlZW4gdXBwZXIgYW5kIGxvd2VyIAogKiBib3VuZHMgd2l0aCBvbmUgbGV2ZWwgd291bGQgaW5jbHVkZSAiU21pdGgiLCAiU01JVEgiLCAic01pVGgiLjxicj4KICogVGhlcmUgYXJlIHR3byB1cHBlciBib3VuZHMgdGhhdCBjYW4gYmUgcHJvZHVjZWQuIElmIFVDT0xfQk9VTkRfVVBQRVIKICogaXMgcHJvZHVjZWQsIHN0cmluZ3MgbWF0Y2hlZCB3b3VsZCBiZSBhcyBhYm92ZS4gSG93ZXZlciwgaWYgYm91bmQKICogcHJvZHVjZWQgdXNpbmcgVUNPTF9CT1VORF9VUFBFUl9MT05HIGlzIHVzZWQsIHRoZSBhYm92ZSBleGFtcGxlIHdpbGwKICogYWxzbyBtYXRjaCAiU21pdGhzb25pYW4iIGFuZCBzaW1pbGFyLjxicj4KICogRm9yIG1vcmUgb24gdXNhZ2UsIHNlZSBleGFtcGxlIGluIGNpbnRsdHN0L2NhcGl0c3QuYyBpbiBwcm9jZWR1cmUKICogVGVzdEJvdW5kcy4KICogU29ydCBrZXlzIG1heSBiZSBjb21wYXJlZCB1c2luZyA8VFQ+c3RyY21wPC9UVD4uCiAqIEBwYXJhbSBzb3VyY2UgVGhlIHNvdXJjZSBzb3J0a2V5LgogKiBAcGFyYW0gc291cmNlTGVuZ3RoIFRoZSBsZW5ndGggb2Ygc291cmNlLCBvciAtMSBpZiBudWxsLXRlcm1pbmF0ZWQuIAogKiAgICAgICAgICAgICAgICAgICAgIChJZiBhbiB1bm1vZGlmaWVkIHNvcnRrZXkgaXMgcGFzc2VkLCBpdCBpcyBhbHdheXMgbnVsbCAKICogICAgICAgICAgICAgICAgICAgICAgdGVybWluYXRlZCkuCiAqIEBwYXJhbSBib3VuZFR5cGUgVHlwZSBvZiBib3VuZCByZXF1aXJlZC4gSXQgY2FuIGJlIFVDT0xfQk9VTkRfTE9XRVIsIHdoaWNoIAogKiAgICAgICAgICAgICAgICAgIHByb2R1Y2VzIGEgbG93ZXIgaW5jbHVzaXZlIGJvdW5kLCBVQ09MX0JPVU5EX1VQUEVSLCB0aGF0IAogKiAgICAgICAgICAgICAgICAgIHByb2R1Y2VzIHVwcGVyIGJvdW5kIHRoYXQgbWF0Y2hlcyBzdHJpbmdzIG9mIHRoZSBzYW1lIGxlbmd0aCAKICogICAgICAgICAgICAgICAgICBvciBVQ09MX0JPVU5EX1VQUEVSX0xPTkcgdGhhdCBtYXRjaGVzIHN0cmluZ3MgdGhhdCBoYXZlIHRoZSAKICogICAgICAgICAgICAgICAgICBzYW1lIHN0YXJ0aW5nIHN1YnN0cmluZyBhcyB0aGUgc291cmNlIHN0cmluZy4KICogQHBhcmFtIG5vT2ZMZXZlbHMgIE51bWJlciBvZiBsZXZlbHMgcmVxdWlyZWQgaW4gdGhlIHJlc3VsdGluZyBib3VuZCAoZm9yIG1vc3QgCiAqICAgICAgICAgICAgICAgICAgICB1c2VzLCB0aGUgcmVjb21tZW5kZWQgdmFsdWUgaXMgMSkuIFNlZSB1c2VycyBndWlkZSBmb3IgCiAqICAgICAgICAgICAgICAgICAgICBleHBsYW5hdGlvbiBvbiBudW1iZXIgb2YgbGV2ZWxzIGEgc29ydGtleSBjYW4gaGF2ZS4KICogQHBhcmFtIHJlc3VsdCBBIHBvaW50ZXIgdG8gYSBidWZmZXIgdG8gcmVjZWl2ZSB0aGUgcmVzdWx0aW5nIHNvcnRrZXkuCiAqIEBwYXJhbSByZXN1bHRMZW5ndGggVGhlIG1heGltdW0gc2l6ZSBvZiByZXN1bHQuCiAqIEBwYXJhbSBzdGF0dXMgVXNlZCBmb3IgcmV0dXJuaW5nIGVycm9yIGNvZGUgaWYgc29tZXRoaW5nIHdlbnQgd3JvbmcuIElmIHRoZSAKICogICAgICAgICAgICAgICBudW1iZXIgb2YgbGV2ZWxzIHJlcXVlc3RlZCBpcyBoaWdoZXIgdGhhbiB0aGUgbnVtYmVyIG9mIGxldmVscwogKiAgICAgICAgICAgICAgIGluIHRoZSBzb3VyY2Uga2V5LCBhIHdhcm5pbmcgKFVfU09SVF9LRVlfVE9PX1NIT1JUX1dBUk5JTkcpIGlzIAogKiAgICAgICAgICAgICAgIGlzc3VlZC4KICogQHJldHVybiBUaGUgc2l6ZSBuZWVkZWQgdG8gZnVsbHkgc3RvcmUgdGhlIGJvdW5kLiAKICogQHNlZSB1Y29sX2tleUhhc2hDb2RlCiAqIEBkcmFmdCBJQ1UgMi4xCiAqLwpzdGF0aWMgaW50MzJfdCBnZXRCb3VuZChjb25zdCB1aW50OF90ICAgICAgICpzb3VyY2UsCiAgICAgICAgaW50MzJfdCAgICAgICAgICAgICBzb3VyY2VMZW5ndGgsCiAgICAgICAgVUNvbEJvdW5kTW9kZSAgICAgICBib3VuZFR5cGUsCiAgICAgICAgdWludDMyX3QgICAgICAgICAgICBub09mTGV2ZWxzLAogICAgICAgIHVpbnQ4X3QgICAgICAgICAgICAgKnJlc3VsdCwKICAgICAgICBpbnQzMl90ICAgICAgICAgICAgIHJlc3VsdExlbmd0aCwKICAgICAgICBVRXJyb3JDb2RlICAgICAgICAgICZzdGF0dXMpOwoKCnByb3RlY3RlZDoKCiAgLy8gQ29sbGF0b3IgcHJvdGVjdGVkIGNvbnN0cnVjdG9ycyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogIC8qKgogICogRGVmYXVsdCBjb25zdHJ1Y3Rvci4KICAqIENvbnN0cnVjdG9yIGlzIGRpZmZlcmVudCBmcm9tIHRoZSBvbGQgZGVmYXVsdCBDb2xsYXRvciBjb25zdHJ1Y3Rvci4KICAqIFRoZSB0YXNrIGZvciBkZXRlcm1pbmcgdGhlIGRlZmF1bHQgY29sbGF0aW9uIHN0cmVuZ3RoIGFuZCBub3JtYWxpemF0aW9uIAogICogbW9kZSBpcyBsZWZ0IHRvIHRoZSBjaGlsZCBjbGFzcy4KICAqIEBzdGFibGUKICAqLwogIENvbGxhdG9yKCk7CgogIC8qKgogICogQ29uc3RydWN0b3IuCiAgKiBFbXB0eSBjb25zdHJ1Y3RvciwgZG9lcyBub3QgaGFuZGxlIHRoZSBhcmd1bWVudHMuCiAgKiBUaGlzIGNvbnN0cnVjdG9yIGlzIGRvbmUgZm9yIGJhY2t3YXJkIGNvbXBhdGliaWxpdHkgd2l0aCAxLjcgYW5kIDEuOC4KICAqIFRoZSB0YXNrIGZvciBoYW5kbGluZyB0aGUgYXJndW1lbnQgY29sbGF0aW9uIHN0cmVuZ3RoIGFuZCBub3JtYWxpemF0aW9uIAogICogbW9kZSBpcyBsZWZ0IHRvIHRoZSBjaGlsZCBjbGFzcy4KICAqIEBwYXJhbSBjb2xsYXRpb25TdHJlbmd0aCBjb2xsYXRpb24gc3RyZW5ndGgKICAqIEBwYXJhbSBkZWNvbXBvc2l0aW9uTW9kZSAKICAqIEBzdGFibGUKICAqLwogIENvbGxhdG9yKFVDb2xsYXRpb25TdHJlbmd0aCBjb2xsYXRpb25TdHJlbmd0aCwgCiAgICAgICAgICAgICAgVU5vcm1hbGl6YXRpb25Nb2RlIGRlY29tcG9zaXRpb25Nb2RlKTsKICAKICAvKioKICAqIENvcHkgY29uc3RydWN0b3IuCiAgKiBAcGFyYW0gb3RoZXIgQ29sbGF0b3Igb2JqZWN0IHRvIGJlIGNvcGllZCBmcm9tCiAgKiBAc3RhYmxlCiAgKi8KICBDb2xsYXRvcihjb25zdCBDb2xsYXRvciYgb3RoZXIpOwogIAogIC8vIENvbGxhdG9yIHByb3RlY3RlZCBtZXRob2RzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpwcml2YXRlOgogCiAgLy8gQ29sbGF0b3IgcHJpdmF0ZSBkYXRhIG1lbWJlcnMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogIC8qCiAgc3lud2VlIDogcmVtb3ZlZCBhcyBhdHRyaWJ1dGVzIHRvIGJlIGhhbmRsZWQgYnkgY2hpbGQgY2xhc3MKICBVQ29sbGF0aW9uU3RyZW5ndGggIHN0cmVuZ3RoOwogIE5vcm1hbGl6ZXI6OkVNb2RlICBkZWNtcDsKICAqLwogICAgLyogVGhpcyBpcyB1c2VsZXNzIGluZm9ybWF0aW9uICovCi8qICBzdGF0aWMgY29uc3QgVVZlcnNpb25JbmZvIGZWZXJzaW9uOyovCn07CgovLyBDb2xsYXRvciBpbmxpbmUgbWV0aG9kcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKaW5saW5lIFVCb29sIENvbGxhdG9yOjpvcGVyYXRvcj09KGNvbnN0IENvbGxhdG9yJiBvdGhlcikgY29uc3QKewogIHJldHVybiAoVUJvb2wpKHRoaXMgPT0gJm90aGVyKTsKfQoKaW5saW5lIFVCb29sIENvbGxhdG9yOjpvcGVyYXRvciE9KGNvbnN0IENvbGxhdG9yJiBvdGhlcikgY29uc3QKewogIHJldHVybiAoVUJvb2wpISgqdGhpcyA9PSBvdGhlcik7Cn0KCi8qCnN5bndlZSA6IHJlbW92ZWQgc2luY2UgdGhlcmUncyBubyBhdHRyaWJ1dGUgdG8gYmUgcmV0cmlldmVkIGhlcmUKaW5saW5lIFVDb2xsYXRpb25TdHJlbmd0aCBDb2xsYXRvcjo6Z2V0U3RyZW5ndGgoKSBjb25zdAp7CiAgcmV0dXJuIHN0cmVuZ3RoOwp9CgppbmxpbmUgTm9ybWFsaXplcjo6RU1vZGUgQ29sbGF0b3I6OmdldERlY29tcG9zaXRpb24oKSBjb25zdAp7CiAgcmV0dXJuIGRlY21wOwp9CiovClVfTkFNRVNQQUNFX0VORAoKI2VuZGlmCg==