LyoKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqCiogQ09QWVJJR0hUOiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICoKKiAgIChDKSBDb3B5cmlnaHQgVGFsaWdlbnQsIEluYy4sICAxOTk2ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKgoqICAgKEMpIENvcHlyaWdodCBJbnRlcm5hdGlvbmFsIEJ1c2luZXNzIE1hY2hpbmVzIENvcnBvcmF0aW9uLCAgMTk5Ni0xOTk5ICAgICAqCiogICBMaWNlbnNlZCBNYXRlcmlhbCAtIFByb2dyYW0tUHJvcGVydHkgb2YgSUJNIC0gQWxsIFJpZ2h0cyBSZXNlcnZlZC4gICAgICAgICoKKiAgIFVTIEdvdmVybm1lbnQgVXNlcnMgUmVzdHJpY3RlZCBSaWdodHMgLSBVc2UsIGR1cGxpY2F0aW9uLCBvciBkaXNjbG9zdXJlICAgKgoqICAgcmVzdHJpY3RlZCBieSBHU0EgQURQIFNjaGVkdWxlIENvbnRyYWN0IHdpdGggSUJNIENvcnAuICAgICAgICAgICAgICAgICAgICAqCiogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICoKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqLwovLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci8vCi8vIEZpbGUgY29sbC5oCi8vCi8vIAovLwovLyBDcmVhdGVkIGJ5OiBIZWxlbmEgU2hpaAovLwovLyBNb2RpZmljYXRpb24gSGlzdG9yeToKLy8KLy8gIERhdGUgICAgICAgIE5hbWUgICAgICAgIERlc2NyaXB0aW9uCi8vIDAyLzUvOTcgICAgICBhbGl1ICAgICAgICBNb2RpZmllZCBjcmVhdGVEZWZhdWx0IHRvIGxvYWQgY29sbGF0aW9uIGRhdGEgZnJvbQovLyAgICAgICAgICAgICAgICAgICAgICAgICAgYmluYXJ5IGZpbGVzIHdoZW4gcG9zc2libGUuICBBZGRlZCByZWxhdGVkIG1ldGhvZHMKLy8gICAgICAgICAgICAgICAgICAgICAgICAgIGNyZWF0ZUNvbGxhdGlvbkZyb21GaWxlLCBjaG9wTG9jYWxlLCBjcmVhdGVQYXRoTmFtZS4KLy8gMDIvMTEvOTcgICAgIGFsaXUgICAgICAgIEFkZGVkIG1lbWJlcnMgYWRkVG9DYWNoZSwgZmluZEluQ2FjaGUsIGFuZCBmZ0NhY2hlLgovLyAwMi8xMi85NyAgICAgYWxpdSAgICAgICAgTW9kaWZpZWQgdG8gY3JlYXRlIG9iamVjdHMgZnJvbSBSdWxlQmFzZWRDb2xsYXRvciBjYWNoZS4KLy8gICAgICAgICAgICAgICAgICAgICAgICAgIE1vdmVkIGNhY2hlIG91dCBvZiBDb2xsYXRpb24gY2xhc3MuCi8vIDAyLzEzLzk3ICAgICBhbGl1ICAgICAgICBNb3ZlZCBzZXZlcmFsIG1ldGhvZHMgb3V0IG9mIHRoaXMgY2xhc3MgYW5kIGludG8KLy8gICAgICAgICAgICAgICAgICAgICAgICAgIFJ1bGVCYXNlZENvbGxhdG9yLCB3aXRoIG1vZGlmaWNhdGlvbnMuICBNb2RpZmllZAovLyAgICAgICAgICAgICAgICAgICAgICAgICAgY3JlYXRlRGVmYXVsdCgpIHRvIGNhbGwgbmV3IFJ1bGVCYXNlZENvbGxhdG9yKExvY2FsZSYpCi8vICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdHJ1Y3Rvci4gIEdlbmVyYWwgY2xlYW4gdXAgYW5kIGRvY3VtZW50YXRpb24uCi8vIDAyLzIwLzk3ICAgICBoZWxlbmEgICAgICBBZGRlZCBjbG9uZSwgb3BlcmF0b3I9PSwgb3BlcmF0b3IhPSwgb3BlcmF0b3I9LCBjb3B5Ci8vICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdHJ1Y3RvciBhbmQgZ2V0RHluYW1pY0NsYXNzSUQuCi8vIDAzLzI1Lzk3ICAgICBoZWxlbmEgICAgICBVcGRhdGVkIHdpdGggcGxhdGZvcm0gaW5kZXBlbmRlbnQgZGF0YSB0eXBlcy4KLy8gMDUvMDYvOTcgICAgIGhlbGVuYSAgICAgIEFkZGVkIG1lbW9yeSBhbGxvY2F0aW9uIGVycm9yIGRldGVjdGlvbi4KLy8gIDYvMjAvOTcgICAgIGhlbGVuYSAgICAgIEphdmEgY2xhc3MgbmFtZSBjaGFuZ2UuCi8vIDA5LzAzLzk3ICAgICBoZWxlbmEgICAgICBBZGRlZCBjcmVhdGVDb2xsYXRpb25LZXlWYWx1ZXMoKS4KLy8gMDIvMTAvOTggICAgIGRhbWliYSAgICAgIEFkZGVkIGNvbXBhcmUoKSB3aXRoIGxlbmd0aCBhcyBwYXJhbWV0ZXIuCi8vIDA0LzIzLzk5ICAgICBzdGVwaGVuICAgICBSZW1vdmVkIEVEZWNvbXBvc2l0aW9uTW9kZSwgbWVyZ2VkIHdpdGgKLy8gICAgICAgICAgICAgICAgICAgICAgICAgIE5vcm1hbGl6ZXI6OkVNb2RlLgovLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CgojaWZuZGVmIENPTExfSAojZGVmaW5lIENPTExfSAoKCiNpbmNsdWRlICJsb2NpZC5oIgojaW5jbHVkZSAidXR5cGVzLmgiCiNpbmNsdWRlICJ1bmlzdHIuaCIKI2luY2x1ZGUgIm5vcm1senIuaCIKCmNsYXNzIENvbGxhdGlvbktleTsKCi8qKgogKiBUaGUgPGNvZGU+Q29sbGF0b3I8L2NvZGU+IGNsYXNzIHBlcmZvcm1zIGxvY2FsZS1zZW5zaXRpdmUKICogPGNvZGU+U3RyaW5nPC9jb2RlPiBjb21wYXJpc29uLiBZb3UgdXNlIHRoaXMgY2xhc3MgdG8gYnVpbGQKICogc2VhcmNoaW5nIGFuZCBzb3J0aW5nIHJvdXRpbmVzIGZvciBuYXR1cmFsIGxhbmd1YWdlIHRleHQuCiAqCiAqIDxwPgogKiA8Y29kZT5Db2xsYXRvcjwvY29kZT4gaXMgYW4gYWJzdHJhY3QgYmFzZSBjbGFzcy4gU3ViY2xhc3NlcwogKiBpbXBsZW1lbnQgc3BlY2lmaWMgY29sbGF0aW9uIHN0cmF0ZWdpZXMuIE9uZSBzdWJjbGFzcywKICogPGNvZGU+UnVsZUJhc2VkQ29sbGF0b3I8L2NvZGU+LCBpcyBjdXJyZW50bHkgcHJvdmlkZWQKICogYW5kIGlzIGFwcGxpY2FibGUgdG8gYSB3aWRlIHNldCBvZiBsYW5ndWFnZXMuIE90aGVyCiAqIHN1YmNsYXNzZXMgbWF5IGJlIGNyZWF0ZWQgdG8gaGFuZGxlIG1vcmUgc3BlY2lhbGl6ZWQgbmVlZHMuCiAqCiAqIDxwPgogKiBMaWtlIG90aGVyIGxvY2FsZS1zZW5zaXRpdmUgY2xhc3NlcywgeW91IGNhbiB1c2UgdGhlIHN0YXRpYwogKiBmYWN0b3J5IG1ldGhvZCwgPGNvZGU+Z2V0SW5zdGFuY2U8L2NvZGU+LCB0byBvYnRhaW4gdGhlIGFwcHJvcHJpYXRlCiAqIDxjb2RlPkNvbGxhdG9yPC9jb2RlPiBvYmplY3QgZm9yIGEgZ2l2ZW4gbG9jYWxlLiBZb3Ugd2lsbCBvbmx5IG5lZWQKICogdG8gbG9vayBhdCB0aGUgc3ViY2xhc3NlcyBvZiA8Y29kZT5Db2xsYXRvcjwvY29kZT4gaWYgeW91IG5lZWQKICogdG8gdW5kZXJzdGFuZCB0aGUgZGV0YWlscyBvZiBhIHBhcnRpY3VsYXIgY29sbGF0aW9uIHN0cmF0ZWd5IG9yCiAqIGlmIHlvdSBuZWVkIHRvIG1vZGlmeSB0aGF0IHN0cmF0ZWd5LgogKgogKiA8cD4KICogVGhlIGZvbGxvd2luZyBleGFtcGxlIHNob3dzIGhvdyB0byBjb21wYXJlIHR3byBzdHJpbmdzIHVzaW5nCiAqIHRoZSA8Y29kZT5Db2xsYXRvcjwvY29kZT4gZm9yIHRoZSBkZWZhdWx0IGxvY2FsZS4KICogPGJsb2NrcXVvdGU+CiAqIDxwcmU+CiAqIC8vIENvbXBhcmUgdHdvIHN0cmluZ3MgaW4gdGhlIGRlZmF1bHQgbG9jYWxlCiAqIFVFcnJvckNvZGUgc3VjY2VzcyA9IFpFUk9fRVJST1I7CiAqIENvbGxhdG9yKiBteUNvbGxhdG9yID0gQ29sbGF0b3I6OmNyZWF0ZUluc3RhbmNlKHN1Y2Nlc3MpOwogKiBpZiggbXlDb2xsYXRvci0+Y29tcGFyZSgiYWJjIiwgIkFCQyIpICZsdDsgMCApIHsKICogICAgIGNvdXQgJmx0OyZsdDsgImFiYyBpcyBsZXNzIHRoYW4gQUJDIiAmbHQ7Jmx0OyBlbmRsOwogKiB9ZWxzZXsKICogICAgIGNvdXQgJmx0OyZsdDsgImFiYyBpcyBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gQUJDIiAmbHQ7Jmx0OyBlbmRsOwogKiB9CiAqIDwvcHJlPgogKiA8L2Jsb2NrcXVvdGU+CiAqCiAqIDxwPgogKiBZb3UgY2FuIHNldCBhIDxjb2RlPkNvbGxhdG9yPC9jb2RlPidzIDxlbT5zdHJlbmd0aDwvZW0+IHByb3BlcnR5CiAqIHRvIGRldGVybWluZSB0aGUgbGV2ZWwgb2YgZGlmZmVyZW5jZSBjb25zaWRlcmVkIHNpZ25pZmljYW50IGluCiAqIGNvbXBhcmlzb25zLiBGb3VyIHN0cmVuZ3RocyBhcmUgcHJvdmlkZWQ6IDxjb2RlPlBSSU1BUlk8L2NvZGU+LAogKiA8Y29kZT5TRUNPTkRBUlk8L2NvZGU+LCA8Y29kZT5URVJUSUFSWTwvY29kZT4sIGFuZCA8Y29kZT5JREVOVElDQUw8L2NvZGU+LgogKiBUaGUgZXhhY3QgYXNzaWdubWVudCBvZiBzdHJlbmd0aHMgdG8gbGFuZ3VhZ2UgZmVhdHVyZXMgaXMKICogbG9jYWxlIGRlcGVuZGFudC4gIEZvciBleGFtcGxlLCBpbiBDemVjaCwgImUiIGFuZCAiZiIgYXJlIGNvbnNpZGVyZWQKICogcHJpbWFyeSBkaWZmZXJlbmNlcywgd2hpbGUgImUiIGFuZCAiXHUwMEVBIiBhcmUgc2Vjb25kYXJ5IGRpZmZlcmVuY2VzLAogKiAiZSIgYW5kICJFIiBhcmUgdGVydGlhcnkgZGlmZmVyZW5jZXMgYW5kICJlIiBhbmQgImUiIGFyZSBpZGVudGljYWwuCiAqIFRoZSBmb2xsb3dpbmcgc2hvd3MgaG93IGJvdGggY2FzZSBhbmQgYWNjZW50cyBjb3VsZCBiZSBpZ25vcmVkIGZvcgogKiBVUyBFbmdsaXNoLgogKiA8YmxvY2txdW90ZT4KICogPHByZT4KICogLy9HZXQgdGhlIENvbGxhdG9yIGZvciBVUyBFbmdsaXNoIGFuZCBzZXQgaXRzIHN0cmVuZ3RoIHRvIFBSSU1BUlkKICogVUVycm9yQ29kZSBzdWNjZXNzID0gWkVST19FUlJPUjsKICogQ29sbGF0b3IqIHVzQ29sbGF0b3IgPSBDb2xsYXRvcjo6Y3JlYXRlSW5zdGFuY2UoTG9jYWxlOjpVUywgc3VjY2Vzcyk7CiAqIHVzQ29sbGF0b3ItPnNldFN0cmVuZ3RoKENvbGxhdG9yOjpQUklNQVJZKTsKICogaWYoIHVzQ29sbGF0b3ItPmNvbXBhcmUoImFiYyIsICJBQkMiKSA9PSAwICkgewogKiAgICAgY291dCAmbHQ7Jmx0OyAiJ2FiYycgYW5kICdBQkMnIHN0cmluZ3MgYXJlIGVxdWl2YWxlbnQgd2l0aCBzdHJlbmd0aCBQUklNQVJZIiAmbHQ7Jmx0OyBlbmRsOwogKiB9CiAqIDwvcHJlPgogKiA8L2Jsb2NrcXVvdGU+CiAqIDxwPgogKiBGb3IgY29tcGFyaW5nIDxjb2RlPlN0cmluZzwvY29kZT5zIGV4YWN0bHkgb25jZSwgdGhlIDxjb2RlPmNvbXBhcmU8L2NvZGU+CiAqIG1ldGhvZCBwcm92aWRlcyB0aGUgYmVzdCBwZXJmb3JtYW5jZS4gV2hlbiBzb3J0aW5nIGEgbGlzdCBvZgogKiA8Y29kZT5TdHJpbmc8L2NvZGU+cyBob3dldmVyLCBpdCBpcyBnZW5lcmFsbHkgbmVjZXNzYXJ5IHRvIGNvbXBhcmUgZWFjaAogKiA8Y29kZT5TdHJpbmc8L2NvZGU+IG11bHRpcGxlIHRpbWVzLiBJbiB0aGlzIGNhc2UsIDxjb2RlPkNvbGxhdGlvbktleTwvY29kZT5zCiAqIHByb3ZpZGUgYmV0dGVyIHBlcmZvcm1hbmNlLiBUaGUgPGNvZGU+Q29sbGF0aW9uS2V5PC9jb2RlPiBjbGFzcyBjb252ZXJ0cwogKiBhIDxjb2RlPlN0cmluZzwvY29kZT4gdG8gYSBzZXJpZXMgb2YgYml0cyB0aGF0IGNhbiBiZSBjb21wYXJlZCBiaXR3aXNlCiAqIGFnYWluc3Qgb3RoZXIgPGNvZGU+Q29sbGF0aW9uS2V5PC9jb2RlPnMuIEEgPGNvZGU+Q29sbGF0aW9uS2V5PC9jb2RlPiBpcwogKiBjcmVhdGVkIGJ5IGEgPGNvZGU+Q29sbGF0b3I8L2NvZGU+IG9iamVjdCBmb3IgYSBnaXZlbiA8Y29kZT5TdHJpbmc8L2NvZGU+LgogKiA8cD4KICogPHN0cm9uZz5Ob3RlOjwvc3Ryb25nPiA8Y29kZT5Db2xsYXRvcjwvY29kZT5zIHdpdGggZGlmZmVyZW50IExvY2FsZSwKICogQ29sbGF0aW9uU3RyZW5ndGggYW5kIERlY29tcG9zaXRpb25Nb2RlIHNldHRpbmdzIHdpbGwgcmV0dXJuIGRpZmZlcmVudAogKiBzb3J0IG9yZGVycyBmb3IgdGhlIHNhbWUgc2V0IG9mIHN0cmluZ3MuIExvY2FsZXMgaGF2ZSBzcGVjaWZpYyAKICogY29sbGF0aW9uIHJ1bGVzLCBhbmQgdGhlIHdheSBpbiB3aGljaCBzZWNvbmRhcnkgYW5kIHRlcnRpYXJ5IGRpZmZlcmVuY2VzIAogKiBhcmUgdGFrZW4gaW50byBhY2NvdW50LCBmb3IgZXhhbXBsZSwgd2lsbCByZXN1bHQgaW4gYSBkaWZmZXJlbnQgc29ydGluZyBvcmRlcgogKiBmb3Igc2FtZSBzdHJpbmdzLgogKiA8cD4KICogCiAqIEBzZWUgICAgICAgICBSdWxlQmFzZWRDb2xsYXRvcgogKiBAc2VlICAgICAgICAgQ29sbGF0aW9uS2V5CiAqIEBzZWUgICAgICAgICBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IKICogQHNlZSAgICAgICAgIExvY2FsZQogKiBAc2VlICAgICAgICAgTm9ybWFsaXplcgogKiBAdmVyc2lvbiAgICAgMS43IDEvMTQvOTcKICogQGF1dGhvciAgICAgIEhlbGVuYSBTaGloCiAqLwoKY2xhc3MgVV9JMThOX0FQSSBDb2xsYXRvciAKewpwdWJsaWMgOiAKICAKICAvKioKICAgICAqIEJhc2UgbGV0dGVyIHJlcHJlc2VudHMgYSBwcmltYXJ5IGRpZmZlcmVuY2UuICBTZXQgY29tcGFyaXNvbgogICAgICogbGV2ZWwgdG8gUFJJTUFSWSB0byBpZ25vcmUgc2Vjb25kYXJ5IGFuZCB0ZXJ0aWFyeSBkaWZmZXJlbmNlcy4KICAgICAqIFVzZSB0aGlzIHRvIHNldCB0aGUgc3RyZW5ndGggb2YgYSBDb2xsYXRvciBvYmplY3QuCiAgICAgKiBFeGFtcGxlIG9mIHByaW1hcnkgZGlmZmVyZW5jZSwgImFiYyIgJmx0OyAiYWJkIgogICAgICogCiAgICAgKiBEaWFjcml0aWNhbCBkaWZmZXJlbmNlcyBvbiB0aGUgc2FtZSBiYXNlIGxldHRlciByZXByZXNlbnQgYSBzZWNvbmRhcnkKICAgICAqIGRpZmZlcmVuY2UuICBTZXQgY29tcGFyaXNvbiBsZXZlbCB0byBTRUNPTkRBUlkgdG8gaWdub3JlIHRlcnRpYXJ5CiAgICAgKiBkaWZmZXJlbmNlcy4gVXNlIHRoaXMgdG8gc2V0IHRoZSBzdHJlbmd0aCBvZiBhIENvbGxhdG9yIG9iamVjdC4KICAgICAqIEV4YW1wbGUgb2Ygc2Vjb25kYXJ5IGRpZmZlcmVuY2UsICLkIiA+PiAiYSIuCiAgICAgKgogICAgICogVXBwZXJjYXNlIGFuZCBsb3dlcmNhc2UgdmVyc2lvbnMgb2YgdGhlIHNhbWUgY2hhcmFjdGVyIHJlcHJlc2VudHMgYQogICAgICogdGVydGlhcnkgZGlmZmVyZW5jZS4gIFNldCBjb21wYXJpc29uIGxldmVsIHRvIFRFUlRJQVJZIHRvIGluY2x1ZGUKICAgICAqIGFsbCBjb21wYXJpc29uIGRpZmZlcmVuY2VzLiBVc2UgdGhpcyB0byBzZXQgdGhlIHN0cmVuZ3RoIG9mIGEgQ29sbGF0b3IKICAgICAqIG9iamVjdC4KICAgICAqIEV4YW1wbGUgb2YgdGVydGlhcnkgZGlmZmVyZW5jZSwgImFiYyIgJmx0OyZsdDsmbHQ7ICJBQkMiLgogICAgICoKICAgICAqIFR3byBjaGFyYWN0ZXJzIGFyZSBjb25zaWRlcmVkICJpZGVudGljYWwiIHdoZW4gdGhleSBoYXZlIHRoZSBzYW1lCiAgICAgKiB1bmljb2RlIHNwZWxsaW5ncy4KICAgICAqIEZvciBleGFtcGxlLCAi5CIgPT0gIuQiLgogICAgICoKICAgICAqIEVDb2xsYXRpb25TdHJlbmd0aCBpcyBhbHNvIHVzZWQgdG8gZGV0ZXJtaW5lIHRoZSBzdHJlbmd0aCBvZiBzb3J0IGtleXMgCiAgICAgKiBnZW5lcmF0ZWQgZnJvbSBDb2xsYXRvciBvYmplY3RzLgogICAgICovCiAgZW51bSBFQ29sbGF0aW9uU3RyZW5ndGggewogICAgUFJJTUFSWSA9IDAsCiAgICBTRUNPTkRBUlkgPSAxLCAKICAgIFRFUlRJQVJZID0gMiwKICAgIElERU5USUNBTCA9IDMKICB9OwoKICAvKioKICAgKiBMRVNTIGlzIHJldHVybmVkIGlmIHNvdXJjZSBzdHJpbmcgaXMgY29tcGFyZWQgdG8gYmUgbGVzcyB0aGFuIHRhcmdldAogICAqIHN0cmluZyBpbiB0aGUgY29tcGFyZSgpIG1ldGhvZC4KICAgKiBFUVVBTCBpcyByZXR1cm5lZCBpZiBzb3VyY2Ugc3RyaW5nIGlzIGNvbXBhcmVkIHRvIGJlIGVxdWFsIHRvIHRhcmdldAogICAqIHN0cmluZyBpbiB0aGUgY29tcGFyZSgpIG1ldGhvZC4KICAgKiBHUkVBVEVSIGlzIHJldHVybmVkIGlmIHNvdXJjZSBzdHJpbmcgaXMgY29tcGFyZWQgdG8gYmUgZ3JlYXRlciB0aGFuCiAgICogdGFyZ2V0IHN0cmluZyBpbiB0aGUgY29tcGFyZSgpIG1ldGhvZC4KICAgKiBAc2VlIENvbGxhdG9yI2NvbXBhcmUKICAgKi8KICBlbnVtIEVDb21wYXJpc29uUmVzdWx0IHsKICAgIExFU1MgPSAtMSwKICAgIEVRVUFMID0gMCwKICAgIEdSRUFURVIgPSAxCiAgfTsKICAKICAvKioKICAgKiBEZXN0cnVjdG9yCiAgICovCiAgdmlydHVhbCAgICAgICAgICAgICAgICAgICAgICAgICB+Q29sbGF0b3IoKTsKCiAgLyoqCiAgICogUmV0dXJucyB0cnVlIGlmICJvdGhlciIgaXMgdGhlIHNhbWUgYXMgInRoaXMiCiAgICovCiAgdmlydHVhbCAgICAgYm9vbF90ICAgICAgICAgICAgICBvcGVyYXRvcj09KGNvbnN0IENvbGxhdG9yJiBvdGhlcikgY29uc3Q7CgogIC8qKgogICAqIFJldHVybnMgdHJ1ZSBpZiAib3RoZXIiIGlzIG5vdCB0aGUgc2FtZSBhcyAidGhpcyIuCiAgICovCiAgdmlydHVhbCAgICAgYm9vbF90ICAgICAgICAgICAgICBvcGVyYXRvciE9KGNvbnN0IENvbGxhdG9yJiBvdGhlcikgY29uc3Q7CgogIC8qKgogICAqIE1ha2VzIGEgc2hhbGxvdyBjb3B5IG9mIHRoZSBjdXJyZW50IG9iamVjdC4KICAgKi8KICB2aXJ0dWFsICAgICBDb2xsYXRvciogICAgICAgICAgIGNsb25lKHZvaWQpIGNvbnN0ID0gMDsKICAvKioKICAgKiBDcmVhdGVzIHRoZSBjb2xsYXRvciBvYmplY3QgZm9yIHRoZSBjdXJyZW50IGRlZmF1bHQgbG9jYWxlLgogICAqIFRoZSBkZWZhdWx0IGxvY2FsZSBpcyBkZXRlcm1pbmVkIGJ5IExvY2FsZTo6Z2V0RGVmYXVsdC4KICAgKiBAcmV0dXJuIHRoZSBjb2xsYXRpb24gb2JqZWN0IG9mIHRoZSBkZWZhdWx0IGxvY2FsZS4oZm9yIGV4YW1wbGUsIGVuX1VTKQogICAqIEBzZWUgTG9jYWxlI2dldERlZmF1bHQKICAgKiBUaGUgVUVycm9yQ29kZSYgZXJyIHBhcmFtZXRlciBpcyB1c2VkIHRvIHJldHVybiBzdGF0dXMgaW5mb3JtYXRpb24gdG8gdGhlIHVzZXIuCiAgICogVG8gY2hlY2sgd2hldGhlciB0aGUgY29uc3RydWN0aW9uIHN1Y2NlZWRlZCBvciBub3QsIHlvdSBzaG91bGQgY2hlY2sKICAgKiB0aGUgdmFsdWUgb2YgU1VDQ0VTUyhlcnIpLiAgSWYgeW91IHdpc2ggbW9yZSBkZXRhaWxlZCBpbmZvcm1hdGlvbiwgeW91CiAgICogY2FuIGNoZWNrIGZvciBpbmZvcm1hdGlvbmFsIGVycm9yIHJlc3VsdHMgd2hpY2ggc3RpbGwgaW5kaWNhdGUgc3VjY2Vzcy4KICAgKiBVU0lOR19GQUxMQkFDS19FUlJPUiBpbmRpY2F0ZXMgdGhhdCBhIGZhbGwgYmFjayBsb2NhbGUgd2FzIHVzZWQuICBGb3IKICAgKiBleGFtcGxlLCAnZGVfQ0gnIHdhcyByZXF1ZXN0ZWQsIGJ1dCBub3RoaW5nIHdhcyBmb3VuZCB0aGVyZSwgc28gJ2RlJyB3YXMKICAgKiB1c2VkLiAgVVNJTkdfREVGQVVMVF9FUlJPUiBpbmRpY2F0ZXMgdGhhdCB0aGUgZGVmYXVsdCBsb2NhbGUgZGF0YSB3YXMKICAgKiB1c2VkOyBuZWl0aGVyIHRoZSByZXF1ZXN0ZWQgbG9jYWxlIG5vciBhbnkgb2YgaXRzIGZhbGwgYmFjayBsb2NhbGVzCiAgICogY291bGQgYmUgZm91bmQuCiAgICogVGhlIGNhbGxlciBvd25zIHRoZSByZXR1cm5lZCBvYmplY3QgYW5kIGlzIHJlc3BvbnNpYmxlIGZvciBkZWxldGluZyBpdC4KICAgKi8KICBzdGF0aWMgIENvbGxhdG9yKiAgICAgICAgICAgY3JlYXRlSW5zdGFuY2UoIFVFcnJvckNvZGUmICBlcnIpOwoKICAvKioKICAgKiBHZXRzIHRoZSB0YWJsZS1iYXNlZCBjb2xsYXRpb24gb2JqZWN0IGZvciB0aGUgZGVzaXJlZCBsb2NhbGUuICBUaGUKICAgKiByZXNvdXJjZSBvZiB0aGUgZGVzaXJlZCBsb2NhbGUgd2lsbCBiZSBsb2FkZWQgYnkgUmVzb3VyY2VMb2FkZXIuIAogICAqIExvY2FsZTo6RU5HTElTSCBpcyB0aGUgYmFzZSBjb2xsYXRpb24gdGFibGUgYW5kIGFsbCBvdGhlciBsYW5ndWFnZXMgYXJlIAogICAqIGJ1aWx0IG9uIHRvcCBvZiBpdCB3aXRoIGFkZGl0aW9uYWwgbGFuZ3VhZ2Utc3BlY2lmaWMgbW9kaWZpY2F0aW9ucy4KICAgKiBAcGFyYW0gZGVzaXJlZExvY2FsZSB0aGUgZGVzaXJlZCBsb2NhbGUgdG8gY3JlYXRlIHRoZSBjb2xsYXRpb24gdGFibGUKICAgKiB3aXRoLgogICAqIEByZXR1cm4gdGhlIGNyZWF0ZWQgdGFibGUtYmFzZWQgY29sbGF0aW9uIG9iamVjdCBiYXNlZCBvbiB0aGUgZGVzaXJlZAogICAqIGxvY2FsZS4KICAgKiBAc2VlIExvY2FsZQogICAqIEBzZWUgUmVzb3VyY2VMb2FkZXIKICAgKiBUaGUgVUVycm9yQ29kZSYgZXJyIHBhcmFtZXRlciBpcyB1c2VkIHRvIHJldHVybiBzdGF0dXMgaW5mb3JtYXRpb24gdG8gdGhlIHVzZXIuCiAgICogVG8gY2hlY2sgd2hldGhlciB0aGUgY29uc3RydWN0aW9uIHN1Y2NlZWRlZCBvciBub3QsIHlvdSBzaG91bGQgY2hlY2sKICAgKiB0aGUgdmFsdWUgb2YgU1VDQ0VTUyhlcnIpLiAgSWYgeW91IHdpc2ggbW9yZSBkZXRhaWxlZCBpbmZvcm1hdGlvbiwgeW91CiAgICogY2FuIGNoZWNrIGZvciBpbmZvcm1hdGlvbmFsIGVycm9yIHJlc3VsdHMgd2hpY2ggc3RpbGwgaW5kaWNhdGUgc3VjY2Vzcy4KICAgKiBVU0lOR19GQUxMQkFDS19FUlJPUiBpbmRpY2F0ZXMgdGhhdCBhIGZhbGwgYmFjayBsb2NhbGUgd2FzIHVzZWQuICBGb3IKICAgKiBleGFtcGxlLCAnZGVfQ0gnIHdhcyByZXF1ZXN0ZWQsIGJ1dCBub3RoaW5nIHdhcyBmb3VuZCB0aGVyZSwgc28gJ2RlJyB3YXMKICAgKiB1c2VkLiAgVVNJTkdfREVGQVVMVF9FUlJPUiBpbmRpY2F0ZXMgdGhhdCB0aGUgZGVmYXVsdCBsb2NhbGUgZGF0YSB3YXMKICAgKiB1c2VkOyBuZWl0aGVyIHRoZSByZXF1ZXN0ZWQgbG9jYWxlIG5vciBhbnkgb2YgaXRzIGZhbGwgYmFjayBsb2NhbGVzCiAgICogY291bGQgYmUgZm91bmQuCiAgICogVGhlIGNhbGxlciBvd25zIHRoZSByZXR1cm5lZCBvYmplY3QgYW5kIGlzIHJlc3BvbnNpYmxlIGZvciBkZWxldGluZyBpdC4KICAgKi8KICBzdGF0aWMgIENvbGxhdG9yKiAgICAgICAgICAgY3JlYXRlSW5zdGFuY2UoIGNvbnN0IExvY2FsZSYgICBsb2MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYgICAgICBlcnIpOwoKICAvLyBjb21wYXJpc29uCiAgLyoqCiAgICogVGhlIGNvbXBhcmlzb24gZnVuY3Rpb24gY29tcGFyZXMgdGhlIGNoYXJhY3RlciBkYXRhIHN0b3JlZCBpbiB0d28KICAgKiBkaWZmZXJlbnQgc3RyaW5ncy4gIFJldHVybnMgaW5mb3JtYXRpb24gYWJvdXQgd2hldGhlciBhIHN0cmluZwogICAqIGlzIGxlc3MgdGhhbiwgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIGFub3RoZXIgc3RyaW5nLgogICAqIDxwPkV4YW1wbGUgb2YgdXNlOgogICAqIDxwcmU+CiAgICogLiAgICAgICBVRXJyb3JDb2RlIHN0YXR1cyA9IFpFUk9fRVJST1I7CiAgICogLiAgICAgICBDb2xsYXRvciAqbXlDb2xsYXRpb24gPSBDb2xsYXRvcjo6Y3JlYXRlSW5zdGFuY2UoTG9jYWxlOjpVUywgc3RhdHVzKTsKICAgKiAuICAgICAgIGlmIChGQUlMVVJFKHN0YXR1cykpIHJldHVybjsKICAgKiAuICAgICAgIG15Q29sbGF0aW9uLT5zZXRTdHJlbmd0aChDb2xsYXRvcjo6UFJJTUFSWSk7CiAgICogLiAgICAgICAvLyByZXN1bHQgd291bGQgYmUgQ29sbGF0b3I6OkVRVUFMICgiYWJjIiA9PSAiQUJDIikKICAgKiAuICAgICAgIC8vIChubyBwcmltYXJ5IGRpZmZlcmVuY2UgYmV0d2VlbiAiYWJjIiBhbmQgIkFCQyIpCiAgICogLiAgICAgICBDb2xsYXRvcjo6RUNvbXBhcmlzb25SZXN1bHQgcmVzdWx0ID0gbXlDb2xsYXRpb24tPmNvbXBhcmUoImFiYyIsICJBQkMiKTsKICAgKiAuICAgICAgIG15Q29sbGF0aW9uLT5zZXRTdHJlbmd0aChDb2xsYXRvcjo6VEVSVElBUlkpOwogICAqIC4gICAgICAgLy8gcmVzdWx0IHdvdWxkIGJlIENvbGxhdG9yOjpMRVNTIChhYmMiICZsdDsmbHQ7Jmx0OyAiQUJDIikKICAgKiAuICAgICAgIC8vICh3aXRoIHRlcnRpYXJ5IGRpZmZlcmVuY2UgYmV0d2VlbiAiYWJjIiBhbmQgIkFCQyIpCiAgICogLiAgICAgICBDb2xsYXRvcjo6RUNvbXBhcmlzb25SZXN1bHQgcmVzdWx0ID0gbXlDb2xsYXRpb24tPmNvbXBhcmUoImFiYyIsICJBQkMiKTsKICAgKiA8L3ByZT4KICAgKiBAcGFyYW0gc291cmNlIHRoZSBzb3VyY2Ugc3RyaW5nIHRvIGJlIGNvbXBhcmVkIHdpdGguCiAgICogQHBhcmFtIHRhcmdldCB0aGUgc3RyaW5nIHRoYXQgaXMgdG8gYmUgY29tcGFyZWQgd2l0aCB0aGUgc291cmNlIHN0cmluZy4KICAgKiBAcmV0dXJuIFJldHVybnMgYSBieXRlIHZhbHVlLiBHUkVBVEVSIGlmIHNvdXJjZSBpcyBncmVhdGVyCiAgICogdGhhbiB0YXJnZXQ7IEVRVUFMIGlmIHNvdXJjZSBpcyBlcXVhbCB0byB0YXJnZXQ7IExFU1MgaWYgc291cmNlIGlzIGxlc3MKICAgKiB0aGFuIHRhcmdldAogICAqKi8KICB2aXJ0dWFsIEVDb21wYXJpc29uUmVzdWx0ICAgY29tcGFyZSggICAgY29uc3QgICBVbmljb2RlU3RyaW5nJiAgc291cmNlLCAKICAgICAgICAgICAgICAgICAgICAgIGNvbnN0ICAgVW5pY29kZVN0cmluZyYgIHRhcmdldCkgY29uc3QgPSAwOwoKICAvKioKICAgKiBEb2VzIHRoZSBzYW1lIHRoaW5nIGFzIGNvbXBhcmUgYnV0IGxpbWl0cyB0aGUgY29tcGFyaXNvbiB0byBhIHNwZWNpZmllZCBsZW5ndGgKICAgKiA8cD5FeGFtcGxlIG9mIHVzZToKICAgKiA8cHJlPgogICAqIC4gICAgICAgVUVycm9yQ29kZSBzdGF0dXMgPSBaRVJPX0VSUk9SOwogICAqIC4gICAgICAgQ29sbGF0b3IgKm15Q29sbGF0aW9uID0gQ29sbGF0b3I6OmNyZWF0ZUluc3RhbmNlKExvY2FsZTo6VVMsIHN0YXR1cyk7CiAgICogLiAgICAgICBpZiAoRkFJTFVSRShzdGF0dXMpKSByZXR1cm47CiAgICogLiAgICAgICBteUNvbGxhdGlvbi0+c2V0U3RyZW5ndGgoQ29sbGF0b3I6OlBSSU1BUlkpOwogICAqIC4gICAgICAgLy8gcmVzdWx0IHdvdWxkIGJlIENvbGxhdG9yOjpFUVVBTCAoImFiYyIgPT0gIkFCQyIpCiAgICogLiAgICAgICAvLyAobm8gcHJpbWFyeSBkaWZmZXJlbmNlIGJldHdlZW4gImFiYyIgYW5kICJBQkMiKQogICAqIC4gICAgICAgQ29sbGF0b3I6OkVDb21wYXJpc29uUmVzdWx0IHJlc3VsdCA9IG15Q29sbGF0aW9uLT5jb21wYXJlKCJhYmMiLCAiQUJDIiwzKTsKICAgKiAuICAgICAgIG15Q29sbGF0aW9uLT5zZXRTdHJlbmd0aChDb2xsYXRvcjo6VEVSVElBUlkpOwogICAqIC4gICAgICAgLy8gcmVzdWx0IHdvdWxkIGJlIENvbGxhdG9yOjpMRVNTIChhYmMiICZsdDsmbHQ7Jmx0OyAiQUJDIikKICAgKiAuICAgICAgIC8vICh3aXRoIHRlcnRpYXJ5IGRpZmZlcmVuY2UgYmV0d2VlbiAiYWJjIiBhbmQgIkFCQyIpCiAgICogLiAgICAgICBDb2xsYXRvcjo6RUNvbXBhcmlzb25SZXN1bHQgcmVzdWx0ID0gbXlDb2xsYXRpb24tPmNvbXBhcmUoImFiYyIsICJBQkMiLDMpOwogICAqIDwvcHJlPgogICAqIEBwYXJhbSBzb3VyY2UgdGhlIHNvdXJjZSBzdHJpbmcgdG8gYmUgY29tcGFyZWQgd2l0aC4KICAgKiBAcGFyYW0gdGFyZ2V0IHRoZSBzdHJpbmcgdGhhdCBpcyB0byBiZSBjb21wYXJlZCB3aXRoIHRoZSBzb3VyY2Ugc3RyaW5nLgogICAqIEBwYXJhbSBsZW5ndGggdGhlIGxlbmd0aCB0aGUgY29tcGFyaXNvbiBpcyBsaW1pdHRlZCB0bwogICAqIEByZXR1cm4gUmV0dXJucyBhIGJ5dGUgdmFsdWUuIEdSRUFURVIgaWYgc291cmNlICh1cCB0byB0aGUgc3BlY2lmaWVkIGxlbmd0aCkgaXMgZ3JlYXRlcgogICAqIHRoYW4gdGFyZ2V0OyBFUVVBTCBpZiBzb3VyY2UgKHVwIHRvIHNwZWNpZmllZCBsZW5ndGgpIGlzIGVxdWFsIHRvIHRhcmdldDsgTEVTUyBpZiBzb3VyY2UKICAgKiAodXAgdG8gdGhlIHNwZWNpZmllZCBsZW5ndGgpIGlzIGxlc3MgIHRoYW4gdGFyZ2V0LiAgIAogICAqKi8KCiAgdmlydHVhbCBFQ29tcGFyaXNvblJlc3VsdCAgIGNvbXBhcmUoICAgIGNvbnN0ICAgVW5pY29kZVN0cmluZyYgIHNvdXJjZSwKICAgICAgICAgICAgICAgICAgICAgIGNvbnN0ICAgVW5pY29kZVN0cmluZyYgIHRhcmdldCwKICAgICAgICAgICAgICAgICAgICAgIGludDMyX3QgbGVuZ3RoKSBjb25zdCA9IDA7CiAgICAKICAgIAoKICAvKiogVHJhbnNmb3JtcyB0aGUgc3RyaW5nIGludG8gYSBzZXJpZXMgb2YgY2hhcmFjdGVycyB0aGF0IGNhbiBiZSBjb21wYXJlZAogICAqIHdpdGggQ29sbGF0aW9uS2V5Ojpjb21wYXJlVG8uIEl0IGlzIG5vdCBwb3NzaWJsZSB0byByZXN0b3JlIHRoZSBvcmlnaW5hbAogICAqIHN0cmluZyBmcm9tIHRoZSBjaGFycyBpbiB0aGUgc29ydCBrZXkuICBUaGUgZ2VuZXJhdGVkIHNvcnQga2V5IGhhbmRsZXMgCiAgICogb25seSBhIGxpbWl0ZWQgbnVtYmVyIG9mIGlnbm9yYWJsZSBjaGFyYWN0ZXJzLgogICAqIDxwPlVzZSBDb2xsYXRpb25LZXk6OmVxdWFscyBvciBDb2xsYXRpb25LZXk6OmNvbXBhcmUgdG8gY29tcGFyZSB0aGUKICAgKiBnZW5lcmF0ZWQgc29ydCBrZXlzLgogICAqIDxwPkV4YW1wbGUgb2YgdXNlOgogICAqIDxwcmU+CiAgICogLiAgICAgICBVRXJyb3JDb2RlIHN0YXR1cyA9IFpFUk9fRVJST1I7CiAgICogLiAgICAgICBDb2xsYXRvciAqbXlDb2xsYXRpb24gPSBDb2xsYXRvcjo6Y3JlYXRlSW5zdGFuY2UoTG9jYWxlOjpVUywgc3RhdHVzKTsKICAgKiAuICAgICAgIGlmIChGQUlMVVJFKHN0YXR1cykpIHJldHVybjsKICAgKiAuICAgICAgIG15Q29sbGF0aW9uLT5zZXRTdHJlbmd0aChDb2xsYXRvcjo6UFJJTUFSWSk7CiAgICogLiAgICAgICBVRXJyb3JDb2RlIGtleTFTdGF0dXMsIGtleTJTdGF0dXM7CiAgICogLiAgICAgICBDb2xsYXRpb25LZXkgQ29sbGF0aW9uS2V5MQogICAqIC4gICAgICAgQ29sbGF0aW9uS2V5MSA9IG15Q29sbGF0aW9uLT5nZXRDb2xsYXRpb25LZXkoImFiYyIsIENvbGxhdGlvbktleTEsIGtleTFTdGF0dXMpOwogICAqIC4gICAgICAgQ29sbGF0aW9uS2V5IENvbGxhdGlvbktleTIKICAgKiAuICAgICAgIENvbGxhdGlvbktleTIgPSBteUNvbGxhdGlvbi0+Z2V0Q29sbGF0aW9uS2V5KCJBQkMiLCBDb2xsYXRpb25LZXkyLCBrZXkyU3RhdHVzKTsKICAgKiAuICAgICAgIGlmIChGQUlMVVJFKGtleTFTdGF0dXMpIHx8IEZBSUxVUkUoa2V5MlN0YXR1cykpIHsgZGVsZXRlIG15Q29sbGF0aW9uOyByZXR1cm47IH0KICAgKiAuICAgICAgIC8vIFVzZSBDb2xsYXRpb25LZXk6OmNvbXBhcmUoKSB0byBjb21wYXJlIHRoZSBzb3J0IGtleXMKICAgKiAuICAgICAgIC8vIHJlc3VsdCB3b3VsZCBiZSAwIChDb2xsYXRpb25LZXkxID09IENvbGxhdGlvbktleTIpCiAgICogLiAgICAgICBpbnQgcmVzdWx0ID0gQ29sbGF0aW9uS2V5MS5jb21wYXJlKENvbGxhdGlvbktleTIpOwogICAqIC4gICAgICAgbXlDb2xsYXRpb24tPnNldFN0cmVuZ3RoKENvbGxhdG9yOjpURVJUSUFSWSk7CiAgICogLiAgICAgICBDb2xsYXRpb25LZXkxID0gbXlDb2xsYXRpb24tPmdldENvbGxhdGlvbktleSgiYWJjIiwgQ29sbGF0aW9uS2V5MSwga2V5MVN0YXR1cyk7CiAgICogLiAgICAgICBDb2xsYXRpb25LZXkyID0gbXlDb2xsYXRpb24tPmdldENvbGxhdGlvbktleSgiQUJDIiwgQ29sbGF0aW9uS2V5Miwga2V5MlN0YXR1cyk7CiAgICogLiAgICAgICBpZiAoRkFJTFVSRShrZXkxU3RhdHVzKSB8fCBGQUlMVVJFKGtleTJTdGF0dXMpKSB7IGRlbGV0ZSBteUNvbGxhdGlvbjsgcmV0dXJuOyB9CiAgICogLiAgICAgICAvLyBVc2UgQ29sbGF0aW9uS2V5Ojpjb21wYXJlVG8gdG8gY29tcGFyZSB0aGUgY29sbGF0aW9uIGtleXMKICAgKiAuICAgICAgIC8vIHJlc3VsdCB3b3VsZCBiZSAtMSAoQ29sbGF0aW9uS2V5MSAmbHQ7IENvbGxhdGlvbktleTIpCiAgICogLiAgICAgICByZXN1bHQgPSBDb2xsYXRpb25LZXkxLmNvbXBhcmVUbyhDb2xsYXRpb25LZXkyKTsKICAgKiAuICAgICAgIGRlbGV0ZSBteUNvbGxhdGlvbjsKICAgKiA8L3ByZT4KICAgKiA8cD5JZiB0aGUgc291cmNlIHN0cmluZyBpcyBudWxsLCBhIG51bGwgY29sbGF0aW9uIGtleSB3aWxsIGJlIHJldHVybmVkLgogICAqIEBwYXJhbSBzb3VyY2UgdGhlIHNvdXJjZSBzdHJpbmcgdG8gYmUgdHJhbnNmb3JtZWQgaW50byBhIHNvcnQga2V5LgogICAqIEBwYXJhbSBrZXkgdGhlIGNvbGxhdGlvbiBrZXkgdG8gYmUgZmlsbGVkIGluCiAgICogQHJldHVybiB0aGUgY29sbGF0aW9uIGtleSBvZiB0aGUgc3RyaW5nIGJhc2VkIG9uIHRoZSBjb2xsYXRpb24gcnVsZXMuCiAgICogQHNlZSBDb2xsYXRpb25LZXkjY29tcGFyZQogICAqLwogIHZpcnR1YWwgQ29sbGF0aW9uS2V5JiAgICAgICBnZXRDb2xsYXRpb25LZXkoY29uc3QgICBVbmljb2RlU3RyaW5nJiAgc291cmNlLAogICAgICAgICAgICAgICAgICAgICAgICAgIENvbGxhdGlvbktleSYgICAgICAga2V5LAogICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmICAgICAgc3RhdHVzKSBjb25zdCA9IDA7CiAgLyoqCiAgICogR2VuZXJhdGVzIHRoZSBoYXNoIGNvZGUgZm9yIHRoZSBjb2xsYXRpb24gb2JqZWN0CiAgICovCiAgdmlydHVhbCBpbnQzMl90ICAgICAgICAgICAgIGhhc2hDb2RlKHZvaWQpIGNvbnN0ID0gMDsKCiAgLyoqCiAgICogQ29udmVuaWVuY2UgbWV0aG9kIGZvciBjb21wYXJpbmcgdHdvIHN0cmluZ3MgYmFzZWQgb24KICAgKiB0aGUgY29sbGF0aW9uIHJ1bGVzLgogICAqIEBwYXJhbSBzb3VyY2UgdGhlIHNvdXJjZSBzdHJpbmcgdG8gYmUgY29tcGFyZWQgd2l0aC4KICAgKiBAcGFyYW0gdGFyZ2V0IHRoZSB0YXJnZXQgc3RyaW5nIHRvIGJlIGNvbXBhcmVkIHdpdGguCiAgICogQHJldHVybiB0cnVlIGlmIHRoZSBmaXJzdCBzdHJpbmcgaXMgZ3JlYXRlciB0aGFuIHRoZSBzZWNvbmQgb25lLAogICAqIGFjY29yZGluZyB0byB0aGUgY29sbGF0aW9uIHJ1bGVzLiBmYWxzZSwgb3RoZXJ3aXNlLgogICAqIEBzZWUgQ29sbGF0b3IjY29tcGFyZQogICAqLwogIGJvb2xfdCAgICAgICAgICAgICAgZ3JlYXRlciggICAgY29uc3QgICBVbmljb2RlU3RyaW5nJiBzb3VyY2UsIAogICAgICAgICAgICAgICAgICBjb25zdCAgIFVuaWNvZGVTdHJpbmcmIHRhcmdldCkgY29uc3Q7CiAgLyoqCiAgICogQ29udmVuaWVuY2UgbWV0aG9kIGZvciBjb21wYXJpbmcgdHdvIHN0cmluZ3MgYmFzZWQgb24gdGhlIGNvbGxhdGlvbgogICAqIHJ1bGVzLgogICAqIEBwYXJhbSBzb3VyY2UgdGhlIHNvdXJjZSBzdHJpbmcgdG8gYmUgY29tcGFyZWQgd2l0aC4KICAgKiBAcGFyYW0gdGFyZ2V0IHRoZSB0YXJnZXQgc3RyaW5nIHRvIGJlIGNvbXBhcmVkIHdpdGguCiAgICogQHJldHVybiB0cnVlIGlmIHRoZSBmaXJzdCBzdHJpbmcgaXMgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIHRoZQogICAqIHNlY29uZCBvbmUsIGFjY29yZGluZyB0byB0aGUgY29sbGF0aW9uIHJ1bGVzLiBmYWxzZSwgb3RoZXJ3aXNlLgogICAqIEBzZWUgQ29sbGF0b3IjY29tcGFyZQogICAqLwogIGJvb2xfdCAgICAgICAgICAgICAgZ3JlYXRlck9yRXF1YWwoIGNvbnN0ICAgVW5pY29kZVN0cmluZyYgc291cmNlLCAKICAgICAgICAgICAgICAgICAgICAgIGNvbnN0ICAgVW5pY29kZVN0cmluZyYgdGFyZ2V0KSBjb25zdDsKICAvKioKICAgKiBDb252ZW5pZW5jZSBtZXRob2QgZm9yIGNvbXBhcmluZyB0d28gc3RyaW5ncyBiYXNlZCBvbiB0aGUgY29sbGF0aW9uCiAgICogcnVsZXMuCiAgICogQHBhcmFtIHNvdXJjZSB0aGUgc291cmNlIHN0cmluZyB0byBiZSBjb21wYXJlZCB3aXRoLgogICAqIEBwYXJhbSB0YXJnZXQgdGhlIHRhcmdldCBzdHJpbmcgdG8gYmUgY29tcGFyZWQgd2l0aC4KICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIHN0cmluZ3MgYXJlIGVxdWFsIGFjY29yZGluZyB0byB0aGUgY29sbGF0aW9uCiAgICogcnVsZXMuICBmYWxzZSwgb3RoZXJ3aXNlLgogICAqIEBzZWUgQ29sbGF0b3IjY29tcGFyZQogICAqLwogIGJvb2xfdCAgICAgICAgICAgICAgZXF1YWxzKCBjb25zdCAgIFVuaWNvZGVTdHJpbmcmIHNvdXJjZSwgCiAgICAgICAgICAgICAgICAgIGNvbnN0ICAgVW5pY29kZVN0cmluZyYgdGFyZ2V0KSBjb25zdDsKICAgICAgICAKICAvLyBnZXR0ZXIvc2V0dGVyCiAgLyoqCiAgICogR2V0IHRoZSBkZWNvbXBvc2l0aW9uIG1vZGUgb2YgdGhlIGNvbGxhdG9yIG9iamVjdC4KICAgKiBAcmV0dXJuIHRoZSBkZWNvbXBvc2l0aW9uIG1vZGUKICAgKiBAc2VlIENvbGxhdG9yI3NldERlY29tcG9zaXRpb24KICAgKi8KICBOb3JtYWxpemVyOjpFTW9kZSAgZ2V0RGVjb21wb3NpdGlvbih2b2lkKSBjb25zdDsKICAvKioKICAgKiBTZXQgdGhlIGRlY29tcG9zaXRpb24gbW9kZSBvZiB0aGUgY29sbGF0b3Igb2JqZWN0LiBzdWNjZXNzIGlzIGVxdWFsCiAgICogdG8gSUxMRUdBTF9BUkdVTUVOVF9FUlJPUiBpZiBlcnJvciBvY2N1cnMuCiAgICogQHBhcmFtIHRoZSBuZXcgZGVjb21wb3NpdGlvbiBtb2RlCiAgICogQHNlZSBDb2xsYXRvciNnZXREZWNvbXBvc2l0aW9uCiAgICovCiAgdm9pZCAgICAgICAgICAgICAgICBzZXREZWNvbXBvc2l0aW9uKE5vcm1hbGl6ZXI6OkVNb2RlICBtb2RlKTsKICAvKioKICAgKiBEZXRlcm1pbmVzIHRoZSBtaW5pbXVtIHN0cmVuZ3RoIHRoYXQgd2lsbCBiZSB1c2UgaW4gY29tcGFyaXNvbiBvcgogICAqIHRyYW5zZm9ybWF0aW9uLgogICAqIDxwPkUuZy4gd2l0aCBzdHJlbmd0aCA9PSBTRUNPTkRBUlksIHRoZSB0ZXJ0aWFyeSBkaWZmZXJlbmNlIGlzIGlnbm9yZWQKICAgKiA8cD5FLmcuIHdpdGggc3RyZW5ndGggPT0gUFJJTUFSWSwgdGhlIHNlY29uZGFyeSBhbmQgdGVydGlhcnkgZGlmZmVyZW5jZQogICAqIGFyZSBpZ25vcmVkLgogICAqIEByZXR1cm4gdGhlIGN1cnJlbnQgY29tcGFyaXNvbiBsZXZlbC4KICAgKiBAc2VlIENvbGxhdG9yI3NldFN0cmVuZ3RoCiAgICovCiAgRUNvbGxhdGlvblN0cmVuZ3RoICBnZXRTdHJlbmd0aCh2b2lkKSBjb25zdDsKICAvKioKICAgKiBTZXRzIHRoZSBtaW5pbXVtIHN0cmVuZ3RoIHRvIGJlIHVzZWQgaW4gY29tcGFyaXNvbiBvciB0cmFuc2Zvcm1hdGlvbi4KICAgKiA8cD5FeGFtcGxlIG9mIHVzZToKICAgKiA8cHJlPgogICAqIC4gICAgICAgVUVycm9yQ29kZSBzdGF0dXMgPSBaRVJPX0VSUk9SOwogICAqIC4gICAgICAgQ29sbGF0b3IgKm15Q29sbGF0aW9uID0gQ29sbGF0b3I6OmNyZWF0ZUluc3RhbmNlKExvY2FsZTo6VVMsIHN0YXR1cyk7CiAgICogLiAgICAgICBpZiAoRkFJTFVSRShzdGF0dXMpKSByZXR1cm47CiAgICogLiAgICAgICBteUNvbGxhdGlvbi0+c2V0U3RyZW5ndGgoQ29sbGF0b3I6OlBSSU1BUlkpOwogICAqIC4gICAgICAgLy8gcmVzdWx0IHdpbGwgYmUgImFiYyIgPT0gIkFCQyIKICAgKiAuICAgICAgIC8vIHRlcnRpYXJ5IGRpZmZlcmVuY2VzIHdpbGwgYmUgaWdub3JlZAogICAqIC4gICAgICAgQ29sbGF0b3I6OkNvbXBhcmlzb25SZXN1bHQgcmVzdWx0ID0gbXlDb2xsYXRpb24tPmNvbXBhcmUoImFiYyIsICJBQkMiKTsKICAgKiA8L3ByZT4KICAgKiBAc2VlIENvbGxhdG9yI2dldFN0cmVuZ3RoCiAgICogQHBhcmFtIG5ld1N0cmVuZ3RoIHRoZSBuZXcgY29tcGFyaXNvbiBsZXZlbC4KICAgKi8KICB2b2lkICAgICAgICAgICAgICAgIHNldFN0cmVuZ3RoKCAgICBFQ29sbGF0aW9uU3RyZW5ndGggIG5ld1N0cmVuZ3RoKTsKICAvKioKICAgKiBHZXQgbmFtZSBvZiB0aGUgb2JqZWN0IGZvciB0aGUgZGVzaXJlZCBMb2NhbGUsIGluIHRoZSBkZXNpcmVkIGxhbmdhdWdlCiAgICogQHBhcmFtIG9iamVjdExvY2FsZSBtdXN0IGJlIGZyb20gZ2V0QXZhaWxhYmxlTG9jYWxlcwogICAqIEBwYXJhbSBkaXNwbGF5TG9jYWxlIHNwZWNpZmllcyB0aGUgZGVzaXJlZCBsb2NhbGUgZm9yIG91dHB1dAogICAqIEBwYXJhbSBuYW1lIHRoZSBmaWxsLWluIHBhcmFtZXRlciBvZiB0aGUgcmV0dXJuIHZhbHVlCiAgICogQHJldHVybiBkaXNwbGF5LWFibGUgbmFtZSBvZiB0aGUgb2JqZWN0IGZvciB0aGUgb2JqZWN0IGxvY2FsZSBpbiB0aGUKICAgKiBkZXNpcmVkIGxhbmd1YWdlCiAgICovCiAgc3RhdGljICBVbmljb2RlU3RyaW5nJiAgICAgIGdldERpc3BsYXlOYW1lKCBjb25zdCAgIExvY2FsZSYgICAgIG9iamVjdExvY2FsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCAgIExvY2FsZSYgICAgIGRpc3BsYXlMb2NhbGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgVW5pY29kZVN0cmluZyYgbmFtZSkgOwogIC8qKgogICAqIEdldCBuYW1lIG9mIHRoZSBvYmplY3QgZm9yIHRoZSBkZXNpcmVkIExvY2FsZSwgaW4gdGhlIGxhbmdhdWdlIG9mIHRoZQogICAqIGRlZmF1bHQgbG9jYWxlLgogICAqIEBwYXJhbSBvYmplY3RMb2NhbGUgbXVzdCBiZSBmcm9tIGdldEF2YWlsYWJsZUxvY2FsZXMKICAgKiBAcGFyYW0gbmFtZSB0aGUgZmlsbC1pbiBwYXJhbWV0ZXIgb2YgdGhlIHJldHVybiB2YWx1ZQogICAqIEByZXR1cm4gbmFtZSBvZiB0aGUgb2JqZWN0IGZvciB0aGUgZGVzaXJlZCBsb2NhbGUgaW4gdGhlIGRlZmF1bHQKICAgKiBsYW5ndWFnZQogICAqLwogIHN0YXRpYyAgVW5pY29kZVN0cmluZyYgICAgICBnZXREaXNwbGF5TmFtZSggY29uc3QgICBMb2NhbGUmICAgICAgICAgb2JqZWN0TG9jYWxlLAogICAgICAgICAgICAgICAgICAgICAgICAgIFVuaWNvZGVTdHJpbmcmICBuYW1lKSA7CgogIC8qKgogICAqIEdldCB0aGUgc2V0IG9mIExvY2FsZXMgZm9yIHdoaWNoIENvbGxhdGlvbnMgYXJlIGluc3RhbGxlZAogICAqIEBwYXJhbSBjb3VudCB0aGUgb3V0cHV0IHBhcmFtZXRlciBvZiBudW1iZXIgb2YgZWxlbWVudHMgaW4gdGhlIGxvY2FsZSBsaXN0CiAgICogQHJldHVybiB0aGUgbGlzdCBvZiBhdmFpbGFibGUgbG9jYWxlcyB3aGljaCBjb2xsYXRpb25zIGFyZSBpbnN0YWxsZWQKICAgKi8KICBzdGF0aWMgIGNvbnN0ICAgTG9jYWxlKiAgICAgZ2V0QXZhaWxhYmxlTG9jYWxlcyhpbnQzMl90JiBjb3VudCk7CgogIC8qKgogICAqIFJldHVybnMgYSB1bmlxdWUgY2xhc3MgSUQgUE9MWU1PUlBISUNBTExZLiAgUHVyZSB2aXJ0dWFsIG1ldGhvZC4KICAgKiBUaGlzIG1ldGhvZCBpcyB0byBpbXBsZW1lbnQgYSBzaW1wbGUgdmVyc2lvbiBvZiBSVFRJLCBzaW5jZSBub3QgYWxsCiAgICogQysrIGNvbXBpbGVycyBzdXBwb3J0IGdlbnVpbmUgUlRUSS4gIFBvbHltb3JwaGljIG9wZXJhdG9yPT0oKSBhbmQKICAgKiBjbG9uZSgpIG1ldGhvZHMgY2FsbCB0aGlzIG1ldGhvZC4KICAgKgogICAqIENvbmNyZXRlIHN1YmNsYXNzZXMgb2YgRm9ybWF0IG11c3QgaW1wbGVtZW50IGdldER5bmFtaWNDbGFzc0lEKCkKICAgKiBhbmQgYWxzbyBhIHN0YXRpYyBtZXRob2QgYW5kIGRhdGEgbWVtYmVyOgogICAqCiAgICogICAgICBzdGF0aWMgQ2xhc3NJRCBnZXRTdGF0aWNDbGFzc0lEKCkgeyByZXR1cm4gKENsYXNzSUQpJmZnQ2xhc3NJRDsgfQogICAqICAgICAgc3RhdGljIGNoYXIgZmdDbGFzc0lEOwogICAqCiAgICogQHJldHVybiAgICAgICAgICBUaGUgY2xhc3MgSUQgZm9yIHRoaXMgb2JqZWN0LiBBbGwgb2JqZWN0cyBvZiBhCiAgICogICAgICAgICAgICAgICAgICBnaXZlbiBjbGFzcyBoYXZlIHRoZSBzYW1lIGNsYXNzIElELiAgT2JqZWN0cyBvZgogICAqICAgICAgICAgICAgICAgICAgb3RoZXIgY2xhc3NlcyBoYXZlIGRpZmZlcmVudCBjbGFzcyBJRHMuCiAgICovCiAgdmlydHVhbCBDbGFzc0lEIGdldER5bmFtaWNDbGFzc0lEKHZvaWQpIGNvbnN0ID0gMDsKCnByb3RlY3RlZDoKICAvKioKICAgKiBDb25zdHJ1Y3RvcnMKICAgKi8KICBDb2xsYXRvcigpOwogIENvbGxhdG9yKEVDb2xsYXRpb25TdHJlbmd0aCBjb2xsYXRpb25TdHJlbmd0aCwKICAgICAgIE5vcm1hbGl6ZXI6OkVNb2RlIGRlY29tcG9zaXRpb25Nb2RlKTsKICBDb2xsYXRvcihjb25zdCAgQ29sbGF0b3ImICAgb3RoZXIpOwoKICAvKioKICAgKiBBc3NpZ25tZW50IG9wZXJhdG9yCiAgICovCiAgY29uc3QgICAgICAgQ29sbGF0b3ImICAgICAgIG9wZXJhdG9yPShjb25zdCBDb2xsYXRvciYgICBvdGhlcik7CgogIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KcHJpdmF0ZToKICAgICAgICAgICAgCiAgRUNvbGxhdGlvblN0cmVuZ3RoICBzdHJlbmd0aDsKICBOb3JtYWxpemVyOjpFTW9kZSAgZGVjbXA7Cn07CgppbmxpbmUgYm9vbF90CkNvbGxhdG9yOjpvcGVyYXRvcj09KGNvbnN0IENvbGxhdG9yJiBvdGhlcikgY29uc3QKewogIGJvb2xfdCByZXN1bHQ7CiAgaWYgKHRoaXMgPT0gJm90aGVyKSByZXN1bHQgPSBUUlVFOwogIGVsc2UgcmVzdWx0ID0gKChzdHJlbmd0aCA9PSBvdGhlci5zdHJlbmd0aCkgJiYgKGRlY21wID09IG90aGVyLmRlY21wKSk7CiAgcmV0dXJuIHJlc3VsdDsKfQoKaW5saW5lIGJvb2xfdApDb2xsYXRvcjo6b3BlcmF0b3IhPShjb25zdCBDb2xsYXRvciYgb3RoZXIpIGNvbnN0CnsKICBib29sX3QgcmVzdWx0OwogIHJlc3VsdCA9ICEoKnRoaXMgPT0gb3RoZXIpOwogIHJldHVybiByZXN1bHQ7Cn0KCiNlbmRpZgo=