LyoKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKiAgIENvcHlyaWdodCAoQykgMTk5Ny0xOTk5LCBJbnRlcm5hdGlvbmFsIEJ1c2luZXNzIE1hY2hpbmVzCiogICBDb3Jwb3JhdGlvbiBhbmQgb3RoZXJzLiAgQWxsIFJpZ2h0cyBSZXNlcnZlZC4KKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKi8KLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci8vCi8vIEZpbGUgY29sZWl0ci5oCi8vCi8vIAovLwovLyBDcmVhdGVkIGJ5OiBIZWxlbmEgU2hpaAovLwovLyBNb2RpZmljYXRpb24gSGlzdG9yeToKLy8KLy8gIERhdGUgICAgICAgICBOYW1lICAgICAgICAgIERlc2NyaXB0aW9uCi8vCi8vICA4LzE4Lzk3ICAgICBoZWxlbmEgICAgICBBZGRlZCBpbnRlcm5hbCBBUEkgZG9jdW1lbnRhdGlvbi4KLy8gMDgvMDMvOTggICAgICAgIGVybSAgICAgICAgICAgIFN5bmNoZWQgd2l0aCAxLjIgdmVyc2lvbiBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IuamF2YQovLyAxMi8xMC85OSAgICAgIGFsaXUgICAgICAgICAgUG9ydGVkIFRoYWkgY29sbGF0aW9uIHN1cHBvcnQgZnJvbSBKYXZhLgovLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCiNpZm5kZWYgQ09MRUlUUl9ICiNkZWZpbmUgQ09MRUlUUl9ICgoKI2luY2x1ZGUgInVuaWNvZGUvdW5pc3RyLmgiCiNpbmNsdWRlICJ1bmljb2RlL3RibGNvbGwuaCIKI2luY2x1ZGUgInVuaWNvZGUvY2hhcml0ZXIuaCIKCmNsYXNzIE5vcm1hbGl6ZXI7CmNsYXNzIFZlY3Rvck9mUFRvQ29udHJhY3RFbGVtZW50OwpjbGFzcyBSdWxlQmFzZWRDb2xsYXRvcjsKCgovKioKICogVGhlIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciBjbGFzcyBpcyB1c2VkIGFzIGFuIGl0ZXJhdG9yIHRvIHdhbGsgdGhyb3VnaAogKiBlYWNoIGNoYXJhY3RlciBvZiBhbiBpbnRlcm5hdGlvbmFsIHN0cmluZy4gVXNlIHRoZSBpdGVyYXRvciB0byByZXR1cm4gdGhlCiAqIG9yZGVyaW5nIHByaW9yaXR5IG9mIHRoZSBwb3NpdGlvbmVkIGNoYXJhY3Rlci4gVGhlIG9yZGVyaW5nIHByaW9yaXR5IG9mCiAqIGEgY2hhcmFjdGVyLCB3aGljaCB3ZSByZWZlciB0byBhcyBhIGtleSwgZGVmaW5lcyBob3cgYSBjaGFyYWN0ZXIgaXMKICogY29sbGF0ZWQgaW4gdGhlIGdpdmVuIGNvbGxhdGlvbiBvYmplY3QuCiAqIEZvciBleGFtcGxlLCBjb25zaWRlciB0aGUgZm9sbG93aW5nIGluIFNwYW5pc2g6CiAqIDxwcmU+CiAqIFxjb2RlCiAqICAgICAgICAiY2EiIC0+IHRoZSBmaXJzdCBrZXkgaXMga2V5KCdjJykgYW5kIHNlY29uZCBrZXkgaXMga2V5KCdhJykuCiAqICAgICAgICAiY2hhIiAtPiB0aGUgZmlyc3Qga2V5IGlzIGtleSgnY2gnKSBhbmQgc2Vjb25kIGtleSBpcyBrZXkoJ2EnKS4KICogXGVuZGNvZGUKICogPC9wcmU+CiAqIEFuZCBpbiBHZXJtYW4sCiAqIDxwcmU+CiAqIFxjb2RlCiAqICAgICAgICAi5mIiLT4gdGhlIGZpcnN0IGtleSBpcyBrZXkoJ2EnKSwgdGhlIHNlY29uZCBrZXkgaXMga2V5KCdlJyksIGFuZAogKiAgICAgICAgdGhlIHRoaXJkIGtleSBpcyBrZXkoJ2InKS4KKiBcZW5kY29kZQogKiA8L3ByZT4KICogVGhlIGtleSBvZiBhIGNoYXJhY3RlciwgaXMgYW4gaW50ZWdlciBjb21wb3NlZCBvZiBwcmltYXJ5IG9yZGVyKHNob3J0KSwKICogc2Vjb25kYXJ5IG9yZGVyKGNoYXIpLCBhbmQgdGVydGlhcnkgb3JkZXIoY2hhcikuICBKYXZhIHN0cmljdGx5IGRlZmluZXMKICogdGhlIHNpemUgYW5kIHNpZ25lZG5lc3Mgb2YgaXRzIHByaW1pdGl2ZSBkYXRhIHR5cGVzLiAgVGhlcmVmb3JlLCB0aGUgc3RhdGljCiAqIGZ1bmN0aW9ucyBwcmltYXJ5T3JkZXIoKSwgc2Vjb25kYXJ5T3JkZXIoKSwgYW5kIHRlcnRpYXJ5T3JkZXIoKSByZXR1cm4gaW50MzJfdAogKiB0byBlbnN1cmUgdGhlIGNvcnJlY3RuZXNzIG9mIHRoZSBrZXkgdmFsdWUuCiAqIDxwPkV4YW1wbGUgb2YgdGhlIGl0ZXJhdG9yIHVzYWdlOiAod2l0aG91dCBlcnJvciBjaGVja2luZykKICogPHByZT4KICogXGNvZGUKICogICB2b2lkIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcl9FeGFtcGxlKCkKICogICB7CiAqICAgICAgIFVuaWNvZGVTdHJpbmcgc3RyID0gIlRoaXMgaXMgYSB0ZXN0IjsKICogICAgICAgVUVycm9yQ29kZSBzdWNjZXNzID0gVV9aRVJPX0VSUk9SOwogKiAgICAgICBSdWxlQmFzZWRDb2xsYXRvciogcmJjID0KICogICAgICAgICAgIChSdWxlQmFzZWRDb2xsYXRvciopIFJ1bGVCYXNlZENvbGxhdG9yOjpjcmVhdGVJbnN0YW5jZShzdWNjZXNzKTsKICogICAgICAgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yKiBjID0KICogICAgICAgICAgIHJiYy0+Y3JlYXRlQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yKCBzdHIgKTsKICogICAgICAgaW50MzJfdCBvcmRlciA9IGMtPm5leHQoc3VjY2Vzcyk7CiAqICAgICAgIGludDMyX3QgcHJpbWFyeU9yZGVyID0gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpwcmltYXJ5T3JkZXIoIG9yZGVyICk7CiAqICAgICAgIGRlbGV0ZSBjOwogKiAgICAgICBkZWxldGUgcmJjOwogKiAgIH0KICogXGVuZGNvZGUKICogPC9wcmU+CiAqIDxwPgogKiBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6Om5leHQgcmV0dXJucyB0aGUgY29sbGF0aW9uIG9yZGVyIG9mIHRoZSBuZXh0CiAqIGNoYXJhY3RlciBiYXNlZCBvbiB0aGUgY29tcGFyaXNvbiBsZXZlbCBvZiB0aGUgY29sbGF0b3IuICBBIGNvbGxhdGlvbiBvcmRlciAKICogY29uc2lzdHMgb2YgcHJpbWFyeSBvcmRlciwgc2Vjb25kYXJ5IG9yZGVyIGFuZCB0ZXJ0aWFyeSBvcmRlci4gIFRoZSBkYXRhIAogKiB0eXBlIG9mIHRoZSBjb2xsYXRpb24gb3JkZXIgaXMgPHN0cm9uZz5pbnQzMl90PC9zdHJvbmc+LiAgVGhlIGZpcnN0IDE2IGJpdHMgb2YgCiAqIGEgY29sbGF0aW9uIG9yZGVyIGlzIGl0cyBwcmltYXJ5IG9yZGVyOyB0aGUgbmV4dCA4IGJpdHMgaXMgdGhlIHNlY29uZGFyeSAKICogb3JkZXIgYW5kIHRoZSBsYXN0IDggYml0cyBpcyB0aGUgdGVydGlhcnkgb3JkZXIuCiAqCiAqIEBzZWUgICAgICAgICAgICAgICAgQ29sbGF0b3IKICogQHNlZSAgICAgICAgICAgICAgICBSdWxlQmFzZWRDb2xsYXRvcgogKiBAdmVyc2lvbiAgICAgICAgICAgIDEuOSAxLzMwLzk3CiAqIEBhdXRob3IgICAgICAgICAgICAgSGVsZW5hIFNoaWgKICovCmNsYXNzIFVfSTE4Tl9BUEkgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yCnsKcHVibGljOiAKICAgIC8qKgogICAgICogTlVMTE9SREVSIGluZGljYXRlcyB0aGUgaXRlcmF0b3IgaGFzIGNvbnN1bWVkIHRoZSBsYXN0IGVsZW1lbnQuCiAgICAgKi8KICAgIHN0YXRpYyAgaW50MzJfdCBjb25zdCAgIE5VTExPUkRFUjsKCiAgICAvKiogRGVzdHJ1Y3RvcgogICAgICogQHN0YWJsZQogICAgICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfkNvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcigpOwogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRydWUgaWYgIm90aGVyIiBpcyB0aGUgc2FtZSBhcyAidGhpcyIKICAgICAqIEBzdGFibGUKICAgICAqLwogICAgVUJvb2wgICAgICAgICAgb3BlcmF0b3I9PShjb25zdCBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3ImIG90aGVyKSBjb25zdDsKCiAgICAvKioKICAgICAqIFJldHVybnMgdHJ1ZSBpZiAib3RoZXIiIGlzIG5vdCB0aGUgc2FtZSBhcyAidGhpcyIuCiAgICAgKiBAc3RhYmxlCiAgICAgKi8KICAgIFVCb29sICAgICAgICAgIG9wZXJhdG9yIT0oY29uc3QgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yJiBvdGhlcikgY29uc3Q7CgogICAgLyoqCiAgICAgKiBSZXNldHMgdGhlIGN1cnNvciB0byB0aGUgYmVnaW5uaW5nIG9mIHRoZSBzdHJpbmcuCiAgICAgKiBAc3RhYmxlCiAgICAgKi8KICAgICAgICAgICAgdm9pZCAgICAgICAgICAgICAgICByZXNldCh2b2lkKTsKICAgIC8qKgogICAgICogR2V0cyB0aGUgb3JkZXJpbmcgcHJpb3JpdHkgb2YgdGhlIG5leHQgY2hhcmFjdGVyIGluIHRoZSBzdHJpbmcuCiAgICAgKiBAcGFyYW0gc3RhdHVzIHRoZSBlcnJvciBjb2RlIHN0YXR1cy4KICAgICAqIEByZXR1cm4gdGhlIG5leHQgY2hhcmFjdGVyJ3Mgb3JkZXJpbmcuICBSZXR1cm5zIE5VTExPUkRFUiBpZgogICAgICogdGhlIGVuZCBvZiBzdHJpbmcgaXMgcmVhY2hlZC4KICAgICAqIEBzdGFibGUKICAgICAqLwogICAgICAgICAgICBpbnQzMl90ICAgICAgICAgICAgIG5leHQoVUVycm9yQ29kZSYgc3RhdHVzKTsKICAgICAvKioKICAgICAgKiBHZXQgdGhlIG9yZGVyaW5nIHByaW9yaXR5IG9mIHRoZSBwcmV2aW91cyBjb2xsYXRpb24gZWxlbWVudCBpbiB0aGUgc3RyaW5nLgogICAgICAqIEBwYXJhbSBzdGF0dXMgdGhlIGVycm9yIGNvZGUgc3RhdHVzLgogICAgICAqIEByZXR1cm4gdGhlIHByZXZpb3VzIGVsZW1lbnQncyBvcmRlcmluZy4gIFJldHVybnMgTlVMTE9SREVSIGlmCiAgICAgICogdGhlIGJlZ2lubmluZyBvZiBzdHJpbmcgaXMgcmVhY2hlZC4KICAgICAqIEBzdGFibGUKICAgICAgKi8KICAgICAgICAgICAgaW50MzJfdCAgICAgICAgICAgICAgICAgcHJldmlvdXMoVUVycm9yQ29kZSYgc3RhdHVzKTsKCiAgICAvKioKICAgICAqIEdldHMgdGhlIHByaW1hcnkgb3JkZXIgb2YgYSBjb2xsYXRpb24gb3JkZXIuCiAgICAgKiBAcGFyYW0gb3JkZXIgdGhlIGNvbGxhdGlvbiBvcmRlcgogICAgICogQHJldHVybiB0aGUgcHJpbWFyeSBvcmRlciBvZiBhIGNvbGxhdGlvbiBvcmRlci4KICAgICAqIEBzdGFibGUKICAgICAqLwogICAgc3RhdGljICBpbnQzMl90ICAgICAgICAgICAgIHByaW1hcnlPcmRlcihpbnQzMl90IG9yZGVyKTsKICAgIC8qKgogICAgICogR2V0cyB0aGUgc2Vjb25kYXJ5IG9yZGVyIG9mIGEgY29sbGF0aW9uIG9yZGVyLgogICAgICogQHBhcmFtIG9yZGVyIHRoZSBjb2xsYXRpb24gb3JkZXIKICAgICAqIEByZXR1cm4gdGhlIHNlY29uZGFyeSBvcmRlciBvZiBhIGNvbGxhdGlvbiBvcmRlci4KICAgICAqIEBzdGFibGUKICAgICAqLwogICAgc3RhdGljICBpbnQzMl90ICAgICAgICAgICAgIHNlY29uZGFyeU9yZGVyKGludDMyX3Qgb3JkZXIpOwogICAgLyoqCiAgICAgKiBHZXRzIHRoZSB0ZXJ0aWFyeSBvcmRlciBvZiBhIGNvbGxhdGlvbiBvcmRlci4KICAgICAqIEBwYXJhbSBvcmRlciB0aGUgY29sbGF0aW9uIG9yZGVyCiAgICAgKiBAcmV0dXJuIHRoZSB0ZXJ0aWFyeSBvcmRlciBvZiBhIGNvbGxhdGlvbiBvcmRlci4KICAgICAqIEBzdGFibGUKICAgICAqLwogICAgc3RhdGljICBpbnQzMl90ICAgICAgICAgICAgIHRlcnRpYXJ5T3JkZXIoaW50MzJfdCBvcmRlcik7CiAgICAvKioKICAgICAqICBSZXR1cm4gdGhlIG1heGltdW0gbGVuZ3RoIG9mIGFueSBleHBhbnNpb24gc2VxdWVuY2VzIHRoYXQgZW5kCiAgICAgKiAgd2l0aCB0aGUgc3BlY2lmaWVkIGNvbXBhcmlzb24gb3JkZXIuCiAgICAgKiAgQHBhcmFtIG9yZGVyIGEgY29sbGF0aW9uIG9yZGVyIHJldHVybmVkIGJ5IHByZXZpb3VzIG9yIG5leHQuCiAgICAgKiAgQHJldHVybiB0aGUgbWF4aW11bSBsZW5ndGggb2YgYW55IGV4cGFuc2lvbiBzZXF1ZW5jZXMgZW5kaW5nCiAgICAgKiAgICAgICAgICB3aXRoIHRoZSBzcGVjaWZpZWQgb3JkZXIuCiAgICAgKiAgQHN0YWJsZQogICAgICovCiAgICAgICAgaW50MzJfdCAgICAgICAgICAgICAgICAgICAgZ2V0TWF4RXhwYW5zaW9uKGludDMyX3Qgb3JkZXIpIGNvbnN0OwoKcHVibGljOgogICAgLyoqCiAgICAgKiAgR2V0cyB0aGUgY29tcGFyaXNvbiBvcmRlciBpbiB0aGUgZGVzaXJlZCBzdHJlbmd0aC4gIElnbm9yZSB0aGUgb3RoZXIKICAgICAqICBkaWZmZXJlbmNlcy4KICAgICAqICBAcGFyYW0gb3JkZXIgVGhlIG9yZGVyIHZhbHVlCiAgICAgKiAgQHN0YWJsZSAKICAgICAqLwogICAgICAgICAgIGludDMyX3QgICAgICAgICAgICAgIHN0cmVuZ3RoT3JkZXIoaW50MzJfdCBvcmRlcikgY29uc3Q7CiAgICAvKioKICAgICAqIFNldHMgdGhlIHNvdXJjZSBzdHJpbmcuCiAgICAgKiBAcGFyYW0gc3RyIHRoZSBzb3VyY2Ugc3RyaW5nLgogICAgICogQHBhcmFtIHN0YXR1cyB0aGUgZXJyb3IgY29kZSBzdGF0dXMuCiAgICAgKiBAc3RhYmxlCiAgICAgKi8KICAgICAgICAgICAgdm9pZCAgICAgICAgICAgICAgICBzZXRUZXh0KGNvbnN0ICAgVW5pY29kZVN0cmluZyYgIHN0ciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYgICAgICBzdGF0dXMpOwogICAgIC8qKgogICAgICogU2V0cyB0aGUgc291cmNlIHN0cmluZy4KICAgICAqIEBwYXJhbSBzdHIgdGhlIHNvdXJjZSBjaGFyYWN0ZXIgaXRlcmF0b3IuCiAgICAgKiBAcGFyYW0gc3RhdHVzIHRoZSBlcnJvciBjb2RlIHN0YXR1cy4KICAgICAqIEBzdGFibGUKICAgICAqLwogICAgICAgICAgICB2b2lkICAgICAgICAgICAgICAgIHNldFRleHQoQ2hhcmFjdGVySXRlcmF0b3ImICBzdHIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiAgICAgICAgICAgIHN0YXR1cyk7CiAgIC8qKgogICAgICogIENoZWNrcyBpZiBhIGNvbXBhcmlzb24gb3JkZXIgaXMgaWdub3JhYmxlLgogICAgICogIEBwYXJhbSBvcmRlciB0aGUgY29sbGF0aW9uIG9yZGVyLgogICAgICogIEByZXR1cm4gVFJVRSBpZiBhIGNoYXJhY3RlciBpcyBpZ25vcmFibGUsIEZBTFNFIG90aGVyd2lzZS4KICAgICAqICBAc3RhYmxlCiAgICAgKi8KICAgIHN0YXRpYyAgICBVQm9vbCAgICAgICAgICAgICAgaXNJZ25vcmFibGUoaW50MzJfdCBvcmRlcik7CiAgICAvKioKICAgICAqICBHZXRzIHRoZSBvZmZzZXQgb2YgdGhlIGN1cnJlbnRseSBwcm9jZXNzZWQgY2hhcmFjdGVyIGluIHRoZSBzb3VyY2Ugc3RyaW5nLgogICAgICogIEByZXR1cm4gdGhlIG9mZnNldCBvZiB0aGUgY2hhcmFjdGVyLgogICAgICogIEBzdGFibGUKICAgICAqLwogICAgICAgICAgICBVVGV4dE9mZnNldCAgICAgICAgICBnZXRPZmZzZXQodm9pZCkgY29uc3Q7CiAgICAvKioKICAgICAqICBTZXRzIHRoZSBvZmZzZXQgb2YgdGhlIGN1cnJlbnRseSBwcm9jZXNzZWQgY2hhcmFjdGVyIGluIHRoZSBzb3VyY2Ugc3RyaW5nLgogICAgICogIEBwYXJhbSBuZXdPZmZzZXQgdGhlIG5ldyBvZmZzZXQuCiAgICAgKiAgQHBhcmFtIHN0YXR1cyB0aGUgZXJyb3IgY29kZSBzdGF0dXMuCiAgICAgKiAgQHJldHVybiB0aGUgb2Zmc2V0IG9mIHRoZSBjaGFyYWN0ZXIuCiAgICAgKiAgQHN0YWJsZQogICAgICovCiAgICAgICAgICAgIHZvaWQgICAgICAgICAgICAgICAgc2V0T2Zmc2V0KFVUZXh0T2Zmc2V0IG5ld09mZnNldCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYgc3RhdHVzKTsKICAgIC8qIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciBzaG91bGQgbm90IGJlIHN1YmNsYXNzZWQuICovCnByb3RlY3RlZDoKICAgIC8qKgogICAgICogQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yIGNvbnN0cnVjdG9yLiAgVGhpcyB0YWtlcyB0aGUgc291cmNlIHN0cmluZyBhbmQKICAgICAqIHRoZSBjb2xsYXRpb24gb2JqZWN0LiAgVGhlIGN1cnNvciB3aWxsIHdhbGsgdGhydSB0aGUgc291cmNlIHN0cmluZyBiYXNlZAogICAgICogb24gdGhlIHByZWRlZmluZWQgY29sbGF0aW9uIHJ1bGVzLiAgSWYgdGhlIHNvdXJjZSBzdHJpbmcgaXMgZW1wdHksCiAgICAgKiBOVUxMT1JERVIgd2lsbCBiZSByZXR1cm5lZCBvbiB0aGUgY2FsbHMgdG8gbmV4dCgpLgogICAgICogQHBhcmFtIHNvdXJjZVRleHQgdGhlIHNvdXJjZSBzdHJpbmcuCiAgICAgKiBAcGFyYW0gc3RhcnRPZmZzZXQgdGhlIGJlZ2lubmluZyBvZmZzZXQgb2YgdGhlIHN0cmluZyB3aGVyZSB0aGUgY3Vyc29yCiAgICAgKiBzdGFydHMgdGhlIGl0ZXJhdGluZy4KICAgICAqIEBwYXJhbSBlbmRPZmZzZXQgdGhlIGVuZGluZyBvZmZzZXQgb2YgdGhlIHN0cmluZyB3aGVyZSB0aGUgY3Vyc29yCiAgICAgKiBzdG9wcyB0aGUgaXRlcmF0aW5nLgogICAgICogQHBhcmFtIG9yZGVyIHRoZSBjb2xsYXRpb24gb2JqZWN0LgogICAgICogQHN0YWJsZQogICAgICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yKCAgIGNvbnN0ICAgVW5pY29kZVN0cmluZyYgIHNvdXJjZVRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0ICAgUnVsZUJhc2VkQ29sbGF0b3IqICBvcmRlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYgc3RhdHVzKTsKCiAgICAvKioKICAgICAqIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciBjb25zdHJ1Y3Rvci4gIFRoaXMgdGFrZXMgdGhlIHNvdXJjZSBzdHJpbmcgYW5kCiAgICAgKiB0aGUgY29sbGF0aW9uIG9iamVjdC4gIFRoZSBjdXJzb3Igd2lsbCB3YWxrIHRocnUgdGhlIHNvdXJjZSBzdHJpbmcgYmFzZWQKICAgICAqIG9uIHRoZSBwcmVkZWZpbmVkIGNvbGxhdGlvbiBydWxlcy4gIElmIHRoZSBzb3VyY2Ugc3RyaW5nIGlzIGVtcHR5LAogICAgICogTlVMTE9SREVSIHdpbGwgYmUgcmV0dXJuZWQgb24gdGhlIGNhbGxzIHRvIG5leHQoKS4KICAgICAqIEBwYXJhbSBzb3VyY2VUZXh0IHRoZSBzb3VyY2Ugc3RyaW5nLgogICAgICogQHBhcmFtIHN0YXJ0T2Zmc2V0IHRoZSBiZWdpbm5pbmcgb2Zmc2V0IG9mIHRoZSBzdHJpbmcgd2hlcmUgdGhlIGN1cnNvcgogICAgICogc3RhcnRzIHRoZSBpdGVyYXRpbmcuCiAgICAgKiBAcGFyYW0gZW5kT2Zmc2V0IHRoZSBlbmRpbmcgb2Zmc2V0IG9mIHRoZSBzdHJpbmcgd2hlcmUgdGhlIGN1cnNvcgogICAgICogc3RvcHMgdGhlIGl0ZXJhdGluZy4KICAgICAqIEBwYXJhbSBvcmRlciB0aGUgY29sbGF0aW9uIG9iamVjdC4KICAgICAqIEBzdGFibGUKICAgICAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciggICBjb25zdCAgICBDaGFyYWN0ZXJJdGVyYXRvciYgIHNvdXJjZVRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0ICAgUnVsZUJhc2VkQ29sbGF0b3IqICBvcmRlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYgc3RhdHVzKTsKICAgIC8qKgogICAgICogQXNzaWdubWVudCBvcGVyYXRvcgogICAgICogQHN0YWJsZQogICAgICovCiAgICBjb25zdCAgIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciYKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcGVyYXRvcj0oY29uc3QgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yJiBvdGhlcik7CnB1YmxpYzoKICAgIC8qKgogICAgICogQ29weSBjb25zdHJ1Y3Rvci4KICAgICAqIEBzdGFibGUKICAgICAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcihjb25zdCAgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yJiBvdGhlcik7CiAgICAvLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogICAgLy8gcHJpdmF0ZXMKICAgIC8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CnByaXZhdGU6CiAgICAvKioKICAgICAqIERlZmF1bHQgY29uc3RydWN0b3IuCiAgICAgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IoKTsKICAgIC8qKgogICAgICogQ29weSBjb25zdHJ1Y3Rvci4KICAgICAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcihjb25zdCBSdWxlQmFzZWRDb2xsYXRvciogb3JkZXIpOwoKICAgIC8qKgogICAgICogR2V0cyB0aGUgb3JkZXJpbmcgcHJpb3JpdHkgb2YgdGhlIG5leHQgY29udHJhY3RpbmcgY2hhcmFjdGVyIGluIHRoZQogICAgICogc3RyaW5nLgogICAgICogQHBhcmFtIGNoIHRoZSBzdGFydGluZyBjaGFyYWN0ZXIgb2YgYSBjb250cmFjdGluZyBjaGFyYWN0ZXIgdG9rZW4KICAgICAqIEBwYXJhbSBzdGF0dXMgdGhlIGVycm9yIGNvZGUgc3RhdHVzLgogICAgICogQHJldHVybiB0aGUgbmV4dCBjb250cmFjdGluZyBjaGFyYWN0ZXIncyBvcmRlcmluZy4gIFJldHVybnMgTlVMTE9SREVSCiAgICAgKiBpZiB0aGUgZW5kIG9mIHN0cmluZyBpcyByZWFjaGVkLgogICAgICovCiAgICAgICAgICAgIGludDMyX3QgICAgICAgICAgICAgbmV4dENvbnRyYWN0Q2hhciggICBVQ2hhcjMyICAgICBjaCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmICBzdGF0dXMpOwoKICAgIC8qKgogICAgICogR2V0cyB0aGUgb3JkZXJpbmcgcHJpb3JpdHkgb2YgdGhlIHByZXZpb3VzIGNvbnRyYWN0aW5nIGNoYXJhY3RlciBpbiB0aGUKICAgICAqIHN0cmluZy4KICAgICAqIEBwYXJhbSBjaCB0aGUgc3RhcnRpbmcgY2hhcmFjdGVyIG9mIGEgY29udHJhY3RpbmcgY2hhcmFjdGVyIHRva2VuCiAgICAgKiBAcGFyYW0gc3RhdHVzIHRoZSBlcnJvciBjb2RlIHN0YXR1cy4KICAgICAqIEByZXR1cm4gdGhlIHByZXZpb3VzIGNvbnRyYWN0aW5nIGNoYXJhY3RlcidzIG9yZGVyaW5nLiAgUmV0dXJucyBOVUxMT1JERVIKICAgICAqIGlmIHRoZSBzdGFydCBvZiBzdHJpbmcgaXMgcmVhY2hlZC4KICAgICAqLwogICAgICAgICAgICBpbnQzMl90ICAgICAgICAgICAgIHByZXZDb250cmFjdENoYXIoICAgVUNoYXIzMiAgICAgY2gsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiAgc3RhdHVzKTsKICAgIAogICAgaW5saW5lIHN0YXRpYyBVQm9vbCBpc1RoYWlQcmVWb3dlbChVQ2hhcjMyIGNoKTsKICAgICAgICAgICAgICAgICAKICAgIGlubGluZSBzdGF0aWMgVUJvb2wgaXNUaGFpQmFzZUNvbnNvbmFudChVQ2hhcjMyIGNoKTsKICAgICAgICAgICAgICAgICAKICAgIFZlY3Rvck9mSW50KiBtYWtlUmVvcmRlcmVkQnVmZmVyKFVDaGFyIGNvbEZpcnN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50MzJfdCBsYXN0VmFsdWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBWZWN0b3JPZkludCogbGFzdEV4cGFuc2lvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVCb29sIGZvcndhcmQsIFVFcnJvckNvZGUmIHN0YXR1cyk7CgogICAgZnJpZW5kICBjbGFzcyAgIFJ1bGVCYXNlZENvbGxhdG9yOwoKLy8gVGhpcyBpcyBqdXN0IHRlbXBvcmFyeSwgZm9yIHByb3RvdHlwaW5nLgogIGZyaWVuZCBpbnQzMl90IHVjb2xfZ2V0TmV4dENFKGNvbnN0IFVDb2xsYXRvciAqY29sbCwgY29sbEl0ZXJhdGUgKnNvdXJjZSwgVUVycm9yQ29kZSAqc3RhdHVzKTsKCiAgICBzdGF0aWMgIGNvbnN0ICAgaW50MzJfdCAgICAgICAgIFVOTUFQUEVEQ0hBUlZBTFVFOwoKICAgICAgICAgICAgTm9ybWFsaXplciogICAgICAgICAgICB0ZXh0OyAgICAgICAvLyBvd25pbmcgCgogICAgICAgICAgICBWZWN0b3JPZkludCogICAgICAgIGJ1ZmZlckFsaWFzOyAvLyBub3Qgb3duZWQKCiAgICAvKioKICAgICAqIG93bkJ1ZmZlciB3YW50cyB0byBiZSBhIHN1Ym9iamVjdCwgbm90IGEgcG9pbnRlciwgYnV0IHRoYXQKICAgICAqIG1lYW5zIGV4cG9zaW5nIHRoZSBpbnRlcm5hbCBjbGFzcyBWZWN0b3JPZkludCBieSAjaW5jbHVkaW5nIHRoZQogICAgICogaW50ZXJuYWwgaGVhZGVyICJ0YWJsZXMuaCIgLS0gbm90IGFsbG93ZWQhICBvd25CdWZmZXIgaXMgYQogICAgICogZml4ZWQtc2l6ZSAyLWVsZW1lbnQgdmVjdG9yIHRoYXQgaXMgdXNlZCB0byBoYW5kbGUgVGhhaQogICAgICogY29sbGF0aW9uOyBidWZmZXJBbGlhcyBwb2ludHMgdG8gb3duQnVmZmVyIGluIHNvbWUgc2l0dWF0aW9ucy4KICAgICAqIFtqMTU5IC0gYWxpdV0KICAgICAqLwogICAgICAgICAgICBWZWN0b3JPZkludCogICAgICAgIG93bkJ1ZmZlcjsKCiAgICAvKioKICAgICAqIHJlb3JkZXJCdWZmZXIgaXMgY3JlYXRlZCBvbiBkZW1hbmQsIHNvIGl0IGRvZXNuJ3Qgd2FudCB0byBiZQogICAgICogYSBzdWJvYmplY3QgLS0gcG9pbnRlciBpcyBmaW5lLiAgSXQgaXMgY3JlYXRlZCBhbmQgYnVmZmVyQWxpYXMKICAgICAqIGlzIHNldCB0byBpdCB1bmRlciBjZXJ0YWluIGNvbmRpdGlvbnMuICBPbmNlIGNyZWF0ZWQsIGl0IGlzCiAgICAgKiByZXVzZWQgZm9yIHRoZSBsaWZlIG9mIHRoaXMgb2JqZWN0LiAgQmVjYXVzZSBvZiB0aGUgaW1wbGVtZW50YXRpb24KICAgICAqIG9mIFZlY3Rvck9mSW50LCBpdCBncm93cyBtb25vdG9uaWNhbGx5LiAgW2oxNTkgLSBhbGl1XQogICAgICovCiAgICAgICAgICAgIFZlY3Rvck9mSW50KiAgICAgICAgcmVvcmRlckJ1ZmZlcjsKCiAgICAgICAgICAgIGludDMyX3QgICAgICAgICAgICAgZXhwSW5kZXg7CiAgICAgICAgICAgIFVuaWNvZGVTdHJpbmcgICAgICAga2V5OwogICAgY29uc3QgICBSdWxlQmFzZWRDb2xsYXRvciogIG9yZGVyQWxpYXM7Cn07CgoKLyoqCiAqIEdldCB0aGUgcHJpbWFyeSBvcmRlciBvZiBhIGNvbGxhdGlvbiBvcmRlci4KICogQHBhcmFtIG9yZGVyIHRoZSBjb2xsYXRpb24gb3JkZXIKICogQHJldHVybiB0aGUgcHJpbWFyeSBvcmRlciBvZiBhIGNvbGxhdGlvbiBvcmRlci4KICovCmlubGluZSBpbnQzMl90CkNvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6cHJpbWFyeU9yZGVyKGludDMyX3Qgb3JkZXIpCnsKICAgIG9yZGVyICY9IFJ1bGVCYXNlZENvbGxhdG9yOjpQUklNQVJZT1JERVJNQVNLOwogICAgcmV0dXJuIChvcmRlciA+PiBSdWxlQmFzZWRDb2xsYXRvcjo6UFJJTUFSWU9SREVSU0hJRlQpOwp9Ci8qKgogKiBHZXQgdGhlIHNlY29uZGFyeSBvcmRlciBvZiBhIGNvbGxhdGlvbiBvcmRlci4KICogQHBhcmFtIG9yZGVyIHRoZSBjb2xsYXRpb24gb3JkZXIKICogQHJldHVybiB0aGUgc2Vjb25kYXJ5IG9yZGVyIG9mIGEgY29sbGF0aW9uIG9yZGVyLgogKi8KaW5saW5lIGludDMyX3QKQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpzZWNvbmRhcnlPcmRlcihpbnQzMl90IG9yZGVyKQp7CiAgICBvcmRlciA9IG9yZGVyICYgUnVsZUJhc2VkQ29sbGF0b3I6OlNFQ09OREFSWU9SREVSTUFTSzsKICAgIHJldHVybiAob3JkZXIgPj4gUnVsZUJhc2VkQ29sbGF0b3I6OlNFQ09OREFSWU9SREVSU0hJRlQpOwp9Ci8qKgogKiBHZXQgdGhlIHRlcnRpYXJ5IG9yZGVyIG9mIGEgY29sbGF0aW9uIG9yZGVyLgogKiBAcGFyYW0gb3JkZXIgdGhlIGNvbGxhdGlvbiBvcmRlcgogKiBAcmV0dXJuIHRoZSB0ZXJ0aWFyeSBvcmRlciBvZiBhIGNvbGxhdGlvbiBvcmRlci4KICovCmlubGluZSBpbnQzMl90CkNvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6dGVydGlhcnlPcmRlcihpbnQzMl90IG9yZGVyKQp7CiAgICByZXR1cm4gKG9yZGVyICY9IFJ1bGVCYXNlZENvbGxhdG9yOjpURVJUSUFSWU9SREVSTUFTSyk7Cn0KCmlubGluZSBpbnQzMl90CkNvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6Z2V0TWF4RXhwYW5zaW9uKGludDMyX3Qgb3JkZXIpIGNvbnN0CnsKICAgIHJldHVybiBvcmRlckFsaWFzLT5nZXRNYXhFeHBhbnNpb24ob3JkZXIpOwp9CgppbmxpbmUgVUJvb2wKQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjppc0lnbm9yYWJsZShpbnQzMl90IG9yZGVyKQp7CiAgICByZXR1cm4gKHByaW1hcnlPcmRlcihvcmRlcikgPT0gUnVsZUJhc2VkQ29sbGF0b3I6OlBSSU1JR05PUkFCTEUpOwp9CgovKioKICogRGV0ZXJtaW5lIGlmIGEgY2hhcmFjdGVyIGlzIGEgVGhhaSB2b3dlbCAod2hpY2ggc29ydHMgYWZ0ZXIKICogaXRzIGJhc2UgY29uc29uYW50KS4KICovCmlubGluZSBVQm9vbCBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6OmlzVGhhaVByZVZvd2VsKFVDaGFyMzIgY2gpIHsKICAgIHJldHVybiAoKHVpbnQzMl90KWNoIC0gMHhlNDApIDw9ICgweGU0NCAtIDB4ZTQwKTsKfQoKLyoqCiAqIERldGVybWluZSBpZiBhIGNoYXJhY3RlciBpcyBhIFRoYWkgYmFzZSBjb25zb25hbnQKICovCmlubGluZSBVQm9vbCBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6OmlzVGhhaUJhc2VDb25zb25hbnQoVUNoYXIzMiBjaCkgewogICAgcmV0dXJuICgodWludDMyX3QpY2ggLSAweGUwMSkgPD0gKDB4ZTJlIC0gMHhlMDEpOwp9CgojZW5kaWYK