LyoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgIENvcHlyaWdodCAoQykgMTk5Ny0yMDA0LCBJbnRlcm5hdGlvbmFsIEJ1c2luZXNzIE1hY2hpbmVzCiAqICAgQ29ycG9yYXRpb24gYW5kIG90aGVycy4gIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICovCgovKioKKiBGaWxlIGNvbGVpdHIuaAoqCiogCioKKiBDcmVhdGVkIGJ5OiBIZWxlbmEgU2hpaAoqCiogTW9kaWZpY2F0aW9uIEhpc3Rvcnk6CioKKiAgRGF0ZSAgICAgICBOYW1lICAgICAgICBEZXNjcmlwdGlvbgoqCiogIDgvMTgvOTcgICAgaGVsZW5hICAgICAgQWRkZWQgaW50ZXJuYWwgQVBJIGRvY3VtZW50YXRpb24uCiogMDgvMDMvOTggICAgZXJtICAgICAgICAgU3luY2hlZCB3aXRoIDEuMiB2ZXJzaW9uIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvci5qYXZhCiogMTIvMTAvOTkgICAgYWxpdSAgICAgICAgUG9ydGVkIFRoYWkgY29sbGF0aW9uIHN1cHBvcnQgZnJvbSBKYXZhLgoqIDAxLzI1LzAxICAgIHN3cXVlayAgICAgIE1vZGlmaWVkIGludG8gYSBDKysgd3JhcHBlciBjYWxsaW5nIEMgQVBJcyAodWNvbGl0ZXIuaCkKKiAwMi8xOS8wMSAgICBzd3F1ZWsgICAgICBSZW1vdmVkIENvbGxhdGlvbkVsZW1lbnRzSXRlcmF0b3IoKSBzaW5jZSBpdCBpcyAKKiAgICAgICAgICAgICAgICAgICAgICAgICBwcml2YXRlIGNvbnN0cnVjdG9yIGFuZCBubyBjYWxscyBhcmUgbWFkZSB0byBpdAoqLwoKI2lmbmRlZiBDT0xFSVRSX0gKI2RlZmluZSBDT0xFSVRSX0gKCiNpbmNsdWRlICJ1bmljb2RlL3V0eXBlcy5oIgoKI2lmICFVQ09ORklHX05PX0NPTExBVElPTgoKI2luY2x1ZGUgInVuaWNvZGUvdW9iamVjdC5oIgojaW5jbHVkZSAidW5pY29kZS90Ymxjb2xsLmgiCiNpbmNsdWRlICJ1bmljb2RlL3Vjb2xlaXRyLmgiCgovKiogCiAqIFRoZSBVQ29sbGF0aW9uRWxlbWVudHMgc3RydWN0LgogKiBGb3IgdXNhZ2UgaW4gQyBwcm9ncmFtcy4KICogQHN0YWJsZSBJQ1UgMi4wCiAqLwp0eXBlZGVmIHN0cnVjdCBVQ29sbGF0aW9uRWxlbWVudHMgVUNvbGxhdGlvbkVsZW1lbnRzOwoKVV9OQU1FU1BBQ0VfQkVHSU4KCi8qKgoqIFRoZSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IgY2xhc3MgaXMgdXNlZCBhcyBhbiBpdGVyYXRvciB0byB3YWxrIHRocm91Z2ggICAgIAoqIGVhY2ggY2hhcmFjdGVyIG9mIGFuIGludGVybmF0aW9uYWwgc3RyaW5nLiBVc2UgdGhlIGl0ZXJhdG9yIHRvIHJldHVybiB0aGUKKiBvcmRlcmluZyBwcmlvcml0eSBvZiB0aGUgcG9zaXRpb25lZCBjaGFyYWN0ZXIuIFRoZSBvcmRlcmluZyBwcmlvcml0eSBvZiBhIAoqIGNoYXJhY3Rlciwgd2hpY2ggd2UgcmVmZXIgdG8gYXMgYSBrZXksIGRlZmluZXMgaG93IGEgY2hhcmFjdGVyIGlzIGNvbGxhdGVkIGluIAoqIHRoZSBnaXZlbiBjb2xsYXRpb24gb2JqZWN0LgoqIEZvciBleGFtcGxlLCBjb25zaWRlciB0aGUgZm9sbG93aW5nIGluIFNwYW5pc2g6CiogPHByZT4KKiBcY29kZQoqICAgICAgICAiY2EiIC0+IHRoZSBmaXJzdCBrZXkgaXMga2V5KCdjJykgYW5kIHNlY29uZCBrZXkgaXMga2V5KCdhJykuCiogICAgICAgICJjaGEiIC0+IHRoZSBmaXJzdCBrZXkgaXMga2V5KCdjaCcpIGFuZCBzZWNvbmQga2V5IGlzIGtleSgnYScpLgoqIFxlbmRjb2RlCiogPC9wcmU+CiogQW5kIGluIEdlcm1hbiwKKiA8cHJlPgoqIFxjb2RlCiogICAgICAgICLmYiItPiB0aGUgZmlyc3Qga2V5IGlzIGtleSgnYScpLCB0aGUgc2Vjb25kIGtleSBpcyBrZXkoJ2UnKSwgYW5kCiogICAgICAgIHRoZSB0aGlyZCBrZXkgaXMga2V5KCdiJykuCiogXGVuZGNvZGUKKiA8L3ByZT4KKiBUaGUga2V5IG9mIGEgY2hhcmFjdGVyLCBpcyBhbiBpbnRlZ2VyIGNvbXBvc2VkIG9mIHByaW1hcnkgb3JkZXIoc2hvcnQpLAoqIHNlY29uZGFyeSBvcmRlcihjaGFyKSwgYW5kIHRlcnRpYXJ5IG9yZGVyKGNoYXIpLiBKYXZhIHN0cmljdGx5IGRlZmluZXMgdGhlIAoqIHNpemUgYW5kIHNpZ25lZG5lc3Mgb2YgaXRzIHByaW1pdGl2ZSBkYXRhIHR5cGVzLiBUaGVyZWZvcmUsIHRoZSBzdGF0aWMKKiBmdW5jdGlvbnMgcHJpbWFyeU9yZGVyKCksIHNlY29uZGFyeU9yZGVyKCksIGFuZCB0ZXJ0aWFyeU9yZGVyKCkgcmV0dXJuIAoqIGludDMyX3QgdG8gZW5zdXJlIHRoZSBjb3JyZWN0bmVzcyBvZiB0aGUga2V5IHZhbHVlLgoqIDxwPkV4YW1wbGUgb2YgdGhlIGl0ZXJhdG9yIHVzYWdlOiAod2l0aG91dCBlcnJvciBjaGVja2luZykKKiA8cHJlPgoqIFxjb2RlCiogICB2b2lkIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcl9FeGFtcGxlKCkKKiAgIHsKKiAgICAgICBVbmljb2RlU3RyaW5nIHN0ciA9ICJUaGlzIGlzIGEgdGVzdCI7CiogICAgICAgVUVycm9yQ29kZSBzdWNjZXNzID0gVV9aRVJPX0VSUk9SOwoqICAgICAgIFJ1bGVCYXNlZENvbGxhdG9yKiByYmMgPQoqICAgICAgICAgICAoUnVsZUJhc2VkQ29sbGF0b3IqKSBSdWxlQmFzZWRDb2xsYXRvcjo6Y3JlYXRlSW5zdGFuY2Uoc3VjY2Vzcyk7CiogICAgICAgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yKiBjID0KKiAgICAgICAgICAgcmJjLT5jcmVhdGVDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IoIHN0ciApOwoqICAgICAgIGludDMyX3Qgb3JkZXIgPSBjLT5uZXh0KHN1Y2Nlc3MpOwoqICAgICAgIGMtPnJlc2V0KCk7CiogICAgICAgb3JkZXIgPSBjLT5wcmV2aW91cyhzdWNjZXNzKTsKKiAgICAgICBkZWxldGUgYzsKKiAgICAgICBkZWxldGUgcmJjOwoqICAgfQoqIFxlbmRjb2RlCiogPC9wcmU+CiogPHA+CiogQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpuZXh0IHJldHVybnMgdGhlIGNvbGxhdGlvbiBvcmRlciBvZiB0aGUgbmV4dAoqIGNoYXJhY3RlciBiYXNlZCBvbiB0aGUgY29tcGFyaXNvbiBsZXZlbCBvZiB0aGUgY29sbGF0b3IuIAoqIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6cHJldmlvdXMgcmV0dXJucyB0aGUgY29sbGF0aW9uIG9yZGVyIG9mIHRoZSAKKiBwcmV2aW91cyBjaGFyYWN0ZXIgYmFzZWQgb24gdGhlIGNvbXBhcmlzb24gbGV2ZWwgb2YgdGhlIGNvbGxhdG9yLiAKKiBUaGUgQ29sbGF0aW9uIEVsZW1lbnQgSXRlcmF0b3IgbW92ZXMgb25seSBpbiBvbmUgZGlyZWN0aW9uIGJldHdlZW4gY2FsbHMgdG8KKiBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6OnJlc2V0LiBUaGF0IGlzLCBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6Om5leHQoKSAKKiBhbmQgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpwcmV2aW91cyBjYW4gbm90IGJlIGludGVyLXVzZWQuIFdoZW5ldmVyIAoqIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6cHJldmlvdXMgaXMgdG8gYmUgY2FsbGVkIGFmdGVyIAoqIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6bmV4dCgpIG9yIHZpY2UgdmVyc2EsIAoqIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6cmVzZXQgaGFzIHRvIGJlIGNhbGxlZCBmaXJzdCB0byByZXNldCB0aGUgc3RhdHVzLCAKKiBzaGlmdGluZyBwb2ludGVycyB0byBlaXRoZXIgdGhlIGVuZCBvciB0aGUgc3RhcnQgb2YgdGhlIHN0cmluZy4gSGVuY2UgYXQgdGhlIAoqIG5leHQgY2FsbCBvZiBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6OnByZXZpb3VzIG9yIAoqIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6bmV4dCgpLCB0aGUgZmlyc3Qgb3IgbGFzdCBjb2xsYXRpb24gb3JkZXIgd2lsbCBiZSAKKiByZXR1cm5lZC4gCiogSWYgYSBjaGFuZ2Ugb2YgZGlyZWN0aW9uIGlzIGRvbmUgd2l0aG91dCBhIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6cmVzZXQoKSwgCiogdGhlIHJlc3VsdCBpcyB1bmRlZmluZWQuCiogVGhlIHJlc3VsdCBvZiBhIGZvcndhcmQgaXRlcmF0ZSAoQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpuZXh0KSBhbmQgCiogcmV2ZXJzZWQgcmVzdWx0IG9mIHRoZSBiYWNrd2FyZCBpdGVyYXRlIChDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6OnByZXZpb3VzKSAKKiBvbiB0aGUgc2FtZSBzdHJpbmcgYXJlIGVxdWl2YWxlbnQsIGlmIGNvbGxhdGlvbiBvcmRlcnMgd2l0aCB0aGUgdmFsdWUgCiogVUNPTF9JR05PUkFCTEUgYXJlIGlnbm9yZWQuCiogQ2hhcmFjdGVyIGJhc2VkIG9uIHRoZSBjb21wYXJpc29uIGxldmVsIG9mIHRoZSBjb2xsYXRvci4gIEEgY29sbGF0aW9uIG9yZGVyIAoqIGNvbnNpc3RzIG9mIHByaW1hcnkgb3JkZXIsIHNlY29uZGFyeSBvcmRlciBhbmQgdGVydGlhcnkgb3JkZXIuICBUaGUgZGF0YSAKKiB0eXBlIG9mIHRoZSBjb2xsYXRpb24gb3JkZXIgaXMgPHN0cm9uZz50X2ludDMyPC9zdHJvbmc+LiAKKgoqIE5vdGUsIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciBzaG91bGQgbm90IGJlIHN1YmNsYXNzZWQuCiogQHNlZSAgICAgQ29sbGF0b3IKKiBAc2VlICAgICBSdWxlQmFzZWRDb2xsYXRvcgoqIEB2ZXJzaW9uIDEuOCBKYW4gMTYgMjAwMQoqLwpjbGFzcyBVX0kxOE5fQVBJIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciA6IHB1YmxpYyBVT2JqZWN0IHsKcHVibGljOiAKCiAgICAvLyBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IgcHVibGljIGRhdGEgbWVtYmVyIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIC8qKgogICAgKiBOVUxMT1JERVIgaW5kaWNhdGVzIHRoYXQgYW4gZXJyb3IgaGFzIG9jY3VyZWQgd2hpbGUgcHJvY2Vzc2luZwogICAgKiBAc3RhYmxlIElDVSAyLjAKICAgICovCiAgICBzdGF0aWMgaW50MzJfdCBjb25zdCBOVUxMT1JERVI7CgogICAgLy8gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yIHB1YmxpYyBjb25zdHJ1Y3Rvci9kZXN0cnVjdG9yIC0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICAvKioKICAgICogQ29weSBjb25zdHJ1Y3Rvci4KICAgICoKICAgICogQHBhcmFtIG90aGVyICAgIHRoZSBvYmplY3QgdG8gYmUgY29waWVkIGZyb20KICAgICogQHN0YWJsZSBJQ1UgMi4wCiAgICAqLwogICAgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yKGNvbnN0IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciYgb3RoZXIpOwoKICAgIC8qKiAKICAgICogRGVzdHJ1Y3RvcgogICAgKiBAc3RhYmxlIElDVSAyLjAKICAgICovCiAgICB2aXJ0dWFsIH5Db2xsYXRpb25FbGVtZW50SXRlcmF0b3IoKTsKCiAgICAvLyBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IgcHVibGljIG1ldGhvZHMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIC8qKgogICAgKiBSZXR1cm5zIHRydWUgaWYgIm90aGVyIiBpcyB0aGUgc2FtZSBhcyAidGhpcyIKICAgICoKICAgICogQHBhcmFtIG90aGVyICAgIHRoZSBvYmplY3QgdG8gYmUgY29tcGFyZWQKICAgICogQHJldHVybiAgICAgICAgIHRydWUgaWYgIm90aGVyIiBpcyB0aGUgc2FtZSBhcyAidGhpcyIKICAgICogQHN0YWJsZSBJQ1UgMi4wCiAgICAqLwogICAgVUJvb2wgb3BlcmF0b3I9PShjb25zdCBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3ImIG90aGVyKSBjb25zdDsKCiAgICAvKioKICAgICogUmV0dXJucyB0cnVlIGlmICJvdGhlciIgaXMgbm90IHRoZSBzYW1lIGFzICJ0aGlzIi4KICAgICoKICAgICogQHBhcmFtIG90aGVyICAgIHRoZSBvYmplY3QgdG8gYmUgY29tcGFyZWQKICAgICogQHJldHVybiAgICAgICAgIHRydWUgaWYgIm90aGVyIiBpcyBub3QgdGhlIHNhbWUgYXMgInRoaXMiCiAgICAqIEBzdGFibGUgSUNVIDIuMAogICAgKi8KICAgIFVCb29sIG9wZXJhdG9yIT0oY29uc3QgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yJiBvdGhlcikgY29uc3Q7CgogICAgLyoqCiAgICAqIFJlc2V0cyB0aGUgY3Vyc29yIHRvIHRoZSBiZWdpbm5pbmcgb2YgdGhlIHN0cmluZy4KICAgICogQHN0YWJsZSBJQ1UgMi4wCiAgICAqLwogICAgdm9pZCByZXNldCh2b2lkKTsKCiAgICAvKioKICAgICogR2V0cyB0aGUgb3JkZXJpbmcgcHJpb3JpdHkgb2YgdGhlIG5leHQgY2hhcmFjdGVyIGluIHRoZSBzdHJpbmcuCiAgICAqIEBwYXJhbSBzdGF0dXMgdGhlIGVycm9yIGNvZGUgc3RhdHVzLgogICAgKiBAcmV0dXJuIHRoZSBuZXh0IGNoYXJhY3RlcidzIG9yZGVyaW5nLiBvdGhlcndpc2UgcmV0dXJucyBOVUxMT1JERVIgaWYgYW4gCiAgICAqICAgICAgICAgZXJyb3IgaGFzIG9jY3VyZWQgb3IgaWYgdGhlIGVuZCBvZiBzdHJpbmcgaGFzIGJlZW4gcmVhY2hlZAogICAgKiBAc3RhYmxlIElDVSAyLjAKICAgICovCiAgICBpbnQzMl90IG5leHQoVUVycm9yQ29kZSYgc3RhdHVzKTsKCiAgICAvKioKICAgICogR2V0IHRoZSBvcmRlcmluZyBwcmlvcml0eSBvZiB0aGUgcHJldmlvdXMgY29sbGF0aW9uIGVsZW1lbnQgaW4gdGhlIHN0cmluZy4KICAgICogQHBhcmFtIHN0YXR1cyB0aGUgZXJyb3IgY29kZSBzdGF0dXMuCiAgICAqIEByZXR1cm4gdGhlIHByZXZpb3VzIGVsZW1lbnQncyBvcmRlcmluZy4gb3RoZXJ3aXNlIHJldHVybnMgTlVMTE9SREVSIGlmIGFuIAogICAgKiAgICAgICAgIGVycm9yIGhhcyBvY2N1cmVkIG9yIGlmIHRoZSBzdGFydCBvZiBzdHJpbmcgaGFzIGJlZW4gcmVhY2hlZAogICAgKiBAc3RhYmxlIElDVSAyLjAKICAgICovCiAgICBpbnQzMl90IHByZXZpb3VzKFVFcnJvckNvZGUmIHN0YXR1cyk7CgogICAgLyoqCiAgICAqIEdldHMgdGhlIHByaW1hcnkgb3JkZXIgb2YgYSBjb2xsYXRpb24gb3JkZXIuCiAgICAqIEBwYXJhbSBvcmRlciB0aGUgY29sbGF0aW9uIG9yZGVyCiAgICAqIEByZXR1cm4gdGhlIHByaW1hcnkgb3JkZXIgb2YgYSBjb2xsYXRpb24gb3JkZXIuCiAgICAqIEBzdGFibGUgSUNVIDIuMAogICAgKi8KICAgIHN0YXRpYyBpbmxpbmUgaW50MzJfdCBwcmltYXJ5T3JkZXIoaW50MzJfdCBvcmRlcik7CgogICAgLyoqCiAgICAqIEdldHMgdGhlIHNlY29uZGFyeSBvcmRlciBvZiBhIGNvbGxhdGlvbiBvcmRlci4KICAgICogQHBhcmFtIG9yZGVyIHRoZSBjb2xsYXRpb24gb3JkZXIKICAgICogQHJldHVybiB0aGUgc2Vjb25kYXJ5IG9yZGVyIG9mIGEgY29sbGF0aW9uIG9yZGVyLgogICAgKiBAc3RhYmxlIElDVSAyLjAKICAgICovCiAgICBzdGF0aWMgaW5saW5lIGludDMyX3Qgc2Vjb25kYXJ5T3JkZXIoaW50MzJfdCBvcmRlcik7CgogICAgLyoqCiAgICAqIEdldHMgdGhlIHRlcnRpYXJ5IG9yZGVyIG9mIGEgY29sbGF0aW9uIG9yZGVyLgogICAgKiBAcGFyYW0gb3JkZXIgdGhlIGNvbGxhdGlvbiBvcmRlcgogICAgKiBAcmV0dXJuIHRoZSB0ZXJ0aWFyeSBvcmRlciBvZiBhIGNvbGxhdGlvbiBvcmRlci4KICAgICogQHN0YWJsZSBJQ1UgMi4wCiAgICAqLwogICAgc3RhdGljIGlubGluZSBpbnQzMl90IHRlcnRpYXJ5T3JkZXIoaW50MzJfdCBvcmRlcik7CgogICAgLyoqCiAgICAqIFJldHVybiB0aGUgbWF4aW11bSBsZW5ndGggb2YgYW55IGV4cGFuc2lvbiBzZXF1ZW5jZXMgdGhhdCBlbmQgd2l0aCB0aGUgCiAgICAqIHNwZWNpZmllZCBjb21wYXJpc29uIG9yZGVyLgogICAgKiBAcGFyYW0gb3JkZXIgYSBjb2xsYXRpb24gb3JkZXIgcmV0dXJuZWQgYnkgcHJldmlvdXMgb3IgbmV4dC4KICAgICogQHJldHVybiBtYXhpbXVtIHNpemUgb2YgdGhlIGV4cGFuc2lvbiBzZXF1ZW5jZXMgZW5kaW5nIHdpdGggdGhlIGNvbGxhdGlvbiAKICAgICogICAgICAgICBlbGVtZW50IG9yIDEgaWYgY29sbGF0aW9uIGVsZW1lbnQgZG9lcyBub3Qgb2NjdXIgYXQgdGhlIGVuZCBvZiBhbnkgCiAgICAqICAgICAgICAgZXhwYW5zaW9uIHNlcXVlbmNlCiAgICAqIEBzdGFibGUgSUNVIDIuMAogICAgKi8KICAgIGludDMyX3QgZ2V0TWF4RXhwYW5zaW9uKGludDMyX3Qgb3JkZXIpIGNvbnN0OwoKICAgIC8qKgogICAgKiBHZXRzIHRoZSBjb21wYXJpc29uIG9yZGVyIGluIHRoZSBkZXNpcmVkIHN0cmVuZ3RoLiBJZ25vcmUgdGhlIG90aGVyCiAgICAqIGRpZmZlcmVuY2VzLgogICAgKiBAcGFyYW0gb3JkZXIgVGhlIG9yZGVyIHZhbHVlCiAgICAqIEBzdGFibGUgSUNVIDIuMAogICAgKi8KICAgIGludDMyX3Qgc3RyZW5ndGhPcmRlcihpbnQzMl90IG9yZGVyKSBjb25zdDsKCiAgICAvKioKICAgICogU2V0cyB0aGUgc291cmNlIHN0cmluZy4KICAgICogQHBhcmFtIHN0ciB0aGUgc291cmNlIHN0cmluZy4KICAgICogQHBhcmFtIHN0YXR1cyB0aGUgZXJyb3IgY29kZSBzdGF0dXMuCiAgICAqIEBzdGFibGUgSUNVIDIuMAogICAgKi8KICAgIHZvaWQgc2V0VGV4dChjb25zdCBVbmljb2RlU3RyaW5nJiBzdHIsIFVFcnJvckNvZGUmIHN0YXR1cyk7CgogICAgLyoqCiAgICAqIFNldHMgdGhlIHNvdXJjZSBzdHJpbmcuCiAgICAqIEBwYXJhbSBzdHIgdGhlIHNvdXJjZSBjaGFyYWN0ZXIgaXRlcmF0b3IuCiAgICAqIEBwYXJhbSBzdGF0dXMgdGhlIGVycm9yIGNvZGUgc3RhdHVzLgogICAgKiBAc3RhYmxlIElDVSAyLjAKICAgICovCiAgICB2b2lkIHNldFRleHQoQ2hhcmFjdGVySXRlcmF0b3ImIHN0ciwgVUVycm9yQ29kZSYgc3RhdHVzKTsKCiAgICAvKioKICAgICogQ2hlY2tzIGlmIGEgY29tcGFyaXNvbiBvcmRlciBpcyBpZ25vcmFibGUuCiAgICAqIEBwYXJhbSBvcmRlciB0aGUgY29sbGF0aW9uIG9yZGVyLgogICAgKiBAcmV0dXJuIFRSVUUgaWYgYSBjaGFyYWN0ZXIgaXMgaWdub3JhYmxlLCBGQUxTRSBvdGhlcndpc2UuCiAgICAqIEBzdGFibGUgSUNVIDIuMAogICAgKi8KICAgIHN0YXRpYyBpbmxpbmUgVUJvb2wgaXNJZ25vcmFibGUoaW50MzJfdCBvcmRlcik7CgogICAgLyoqCiAgICAqIEdldHMgdGhlIG9mZnNldCBvZiB0aGUgY3VycmVudGx5IHByb2Nlc3NlZCBjaGFyYWN0ZXIgaW4gdGhlIHNvdXJjZSBzdHJpbmcuCiAgICAqIEByZXR1cm4gdGhlIG9mZnNldCBvZiB0aGUgY2hhcmFjdGVyLgogICAgKiBAc3RhYmxlIElDVSAyLjAKICAgICovCiAgICBpbnQzMl90IGdldE9mZnNldCh2b2lkKSBjb25zdDsKCiAgICAvKioKICAgICogU2V0cyB0aGUgb2Zmc2V0IG9mIHRoZSBjdXJyZW50bHkgcHJvY2Vzc2VkIGNoYXJhY3RlciBpbiB0aGUgc291cmNlIHN0cmluZy4KICAgICogQHBhcmFtIG5ld09mZnNldCB0aGUgbmV3IG9mZnNldC4KICAgICogQHBhcmFtIHN0YXR1cyB0aGUgZXJyb3IgY29kZSBzdGF0dXMuCiAgICAqIEByZXR1cm4gdGhlIG9mZnNldCBvZiB0aGUgY2hhcmFjdGVyLgogICAgKiBAc3RhYmxlIElDVSAyLjAKICAgICovCiAgICB2b2lkIHNldE9mZnNldChpbnQzMl90IG5ld09mZnNldCwgVUVycm9yQ29kZSYgc3RhdHVzKTsKCiAgICAvKioKICAgICogSUNVICJwb29yIG1hbidzIFJUVEkiLCByZXR1cm5zIGEgVUNsYXNzSUQgZm9yIHRoZSBhY3R1YWwgY2xhc3MuCiAgICAqCiAgICAqIEBzdGFibGUgSUNVIDIuMgogICAgKi8KICAgIHZpcnR1YWwgVUNsYXNzSUQgZ2V0RHluYW1pY0NsYXNzSUQoKSBjb25zdDsKCiAgICAvKioKICAgICogSUNVICJwb29yIG1hbidzIFJUVEkiLCByZXR1cm5zIGEgVUNsYXNzSUQgZm9yIHRoaXMgY2xhc3MuCiAgICAqCiAgICAqIEBzdGFibGUgSUNVIDIuMgogICAgKi8KICAgIHN0YXRpYyBVQ2xhc3NJRCBVX0VYUE9SVDIgZ2V0U3RhdGljQ2xhc3NJRCgpOwoKcHJvdGVjdGVkOgogIAogICAgLy8gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yIHByb3RlY3RlZCBjb25zdHJ1Y3RvcnMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgIC8qKgogICAgKiBAc3RhYmxlIElDVSAyLjAKICAgICovCiAgICBmcmllbmQgY2xhc3MgUnVsZUJhc2VkQ29sbGF0b3I7CgogICAgLyoqCiAgICAqIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciBjb25zdHJ1Y3Rvci4gVGhpcyB0YWtlcyB0aGUgc291cmNlIHN0cmluZyBhbmQgdGhlIAogICAgKiBjb2xsYXRpb24gb2JqZWN0LiBUaGUgY3Vyc29yIHdpbGwgd2FsayB0aHJ1IHRoZSBzb3VyY2Ugc3RyaW5nIGJhc2VkIG9uIHRoZSAKICAgICogcHJlZGVmaW5lZCBjb2xsYXRpb24gcnVsZXMuIElmIHRoZSBzb3VyY2Ugc3RyaW5nIGlzIGVtcHR5LCBOVUxMT1JERVIgd2lsbCAKICAgICogYmUgcmV0dXJuZWQgb24gdGhlIGNhbGxzIHRvIG5leHQoKS4KICAgICogQHBhcmFtIHNvdXJjZVRleHQgICAgdGhlIHNvdXJjZSBzdHJpbmcuCiAgICAqIEBwYXJhbSBvcmRlciAgICAgICAgIHRoZSBjb2xsYXRpb24gb2JqZWN0LgogICAgKiBAcGFyYW0gc3RhdHVzICAgICAgICB0aGUgZXJyb3IgY29kZSBzdGF0dXMuCiAgICAqIEBzdGFibGUgSUNVIDIuMAogICAgKi8KICAgIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcihjb25zdCBVbmljb2RlU3RyaW5nJiBzb3VyY2VUZXh0LAogICAgICAgIGNvbnN0IFJ1bGVCYXNlZENvbGxhdG9yKiBvcmRlciwgVUVycm9yQ29kZSYgc3RhdHVzKTsKCiAgICAvKioKICAgICogQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yIGNvbnN0cnVjdG9yLiBUaGlzIHRha2VzIHRoZSBzb3VyY2Ugc3RyaW5nIGFuZCB0aGUgCiAgICAqIGNvbGxhdGlvbiBvYmplY3QuICBUaGUgY3Vyc29yIHdpbGwgd2FsayB0aHJ1IHRoZSBzb3VyY2Ugc3RyaW5nIGJhc2VkIG9uIHRoZSAKICAgICogcHJlZGVmaW5lZCBjb2xsYXRpb24gcnVsZXMuICBJZiB0aGUgc291cmNlIHN0cmluZyBpcyBlbXB0eSwgTlVMTE9SREVSIHdpbGwgCiAgICAqIGJlIHJldHVybmVkIG9uIHRoZSBjYWxscyB0byBuZXh0KCkuCiAgICAqIEBwYXJhbSBzb3VyY2VUZXh0ICAgIHRoZSBzb3VyY2Ugc3RyaW5nLgogICAgKiBAcGFyYW0gb3JkZXIgICAgICAgICB0aGUgY29sbGF0aW9uIG9iamVjdC4KICAgICogQHBhcmFtIHN0YXR1cyAgICAgICAgdGhlIGVycm9yIGNvZGUgc3RhdHVzLgogICAgKiBAc3RhYmxlIElDVSAyLjAKICAgICovCiAgICBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IoY29uc3QgQ2hhcmFjdGVySXRlcmF0b3ImIHNvdXJjZVRleHQsCiAgICAgICAgY29uc3QgUnVsZUJhc2VkQ29sbGF0b3IqIG9yZGVyLCBVRXJyb3JDb2RlJiBzdGF0dXMpOwoKICAgIC8vIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciBwcm90ZWN0ZWQgbWV0aG9kcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgLyoqCiAgICAqIEFzc2lnbm1lbnQgb3BlcmF0b3IKICAgICoKICAgICogQHBhcmFtIG90aGVyICAgIHRoZSBvYmplY3QgdG8gYmUgY29waWVkCiAgICAqIEBzdGFibGUgSUNVIDIuMAogICAgKi8KICAgIGNvbnN0IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciYKICAgICAgICBvcGVyYXRvcj0oY29uc3QgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yJiBvdGhlcik7Cgpwcml2YXRlOgogICAgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yKCk7IC8vIGRlZmF1bHQgY29uc3RydWN0b3Igbm90IGltcGxlbWVudGVkCgogICAgLy8gQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yIHByaXZhdGUgZGF0YSBtZW1iZXJzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICAvKioKICAgICogRGF0YSB3cmFwcGVyIGZvciBjb2xsYXRpb24gZWxlbWVudHMKICAgICovCiAgICBVQ29sbGF0aW9uRWxlbWVudHMgKm1fZGF0YV87CgogICAgLyoqCiAgICAqIEluZGljYXRlcyBpZiBtX2RhdGFfIGJlbG9uZ3MgdG8gdGhpcyBvYmplY3QuCiAgICAqLwogICAgVUJvb2wgaXNEYXRhT3duZWRfOwoKfTsKCi8vIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciBpbmxpbmUgbWV0aG9kIGRlZmluYXRpb24gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCi8qKgoqIEdldCB0aGUgcHJpbWFyeSBvcmRlciBvZiBhIGNvbGxhdGlvbiBvcmRlci4KKiBAcGFyYW0gb3JkZXIgdGhlIGNvbGxhdGlvbiBvcmRlcgoqIEByZXR1cm4gdGhlIHByaW1hcnkgb3JkZXIgb2YgYSBjb2xsYXRpb24gb3JkZXIuCiovCmlubGluZSBpbnQzMl90IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6cHJpbWFyeU9yZGVyKGludDMyX3Qgb3JkZXIpCnsKICAgIG9yZGVyICY9IFJ1bGVCYXNlZENvbGxhdG9yOjpQUklNQVJZT1JERVJNQVNLOwogICAgcmV0dXJuIChvcmRlciA+PiBSdWxlQmFzZWRDb2xsYXRvcjo6UFJJTUFSWU9SREVSU0hJRlQpOwp9CgovKioKKiBHZXQgdGhlIHNlY29uZGFyeSBvcmRlciBvZiBhIGNvbGxhdGlvbiBvcmRlci4KKiBAcGFyYW0gb3JkZXIgdGhlIGNvbGxhdGlvbiBvcmRlcgoqIEByZXR1cm4gdGhlIHNlY29uZGFyeSBvcmRlciBvZiBhIGNvbGxhdGlvbiBvcmRlci4KKi8KaW5saW5lIGludDMyX3QgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpzZWNvbmRhcnlPcmRlcihpbnQzMl90IG9yZGVyKQp7CiAgICBvcmRlciA9IG9yZGVyICYgUnVsZUJhc2VkQ29sbGF0b3I6OlNFQ09OREFSWU9SREVSTUFTSzsKICAgIHJldHVybiAob3JkZXIgPj4gUnVsZUJhc2VkQ29sbGF0b3I6OlNFQ09OREFSWU9SREVSU0hJRlQpOwp9CgovKioKKiBHZXQgdGhlIHRlcnRpYXJ5IG9yZGVyIG9mIGEgY29sbGF0aW9uIG9yZGVyLgoqIEBwYXJhbSBvcmRlciB0aGUgY29sbGF0aW9uIG9yZGVyCiogQHJldHVybiB0aGUgdGVydGlhcnkgb3JkZXIgb2YgYSBjb2xsYXRpb24gb3JkZXIuCiovCmlubGluZSBpbnQzMl90IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6dGVydGlhcnlPcmRlcihpbnQzMl90IG9yZGVyKQp7CiAgICByZXR1cm4gKG9yZGVyICY9IFJ1bGVCYXNlZENvbGxhdG9yOjpURVJUSUFSWU9SREVSTUFTSyk7Cn0KCmlubGluZSBpbnQzMl90IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6Z2V0TWF4RXhwYW5zaW9uKGludDMyX3Qgb3JkZXIpIGNvbnN0CnsKICAgIHJldHVybiB1Y29sX2dldE1heEV4cGFuc2lvbihtX2RhdGFfLCAodWludDMyX3Qpb3JkZXIpOwp9CgppbmxpbmUgVUJvb2wgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjppc0lnbm9yYWJsZShpbnQzMl90IG9yZGVyKQp7CiAgICByZXR1cm4gKHByaW1hcnlPcmRlcihvcmRlcikgPT0gUnVsZUJhc2VkQ29sbGF0b3I6OlBSSU1JR05PUkFCTEUpOwp9CgpVX05BTUVTUEFDRV9FTkQKCiNlbmRpZiAvKiAjaWYgIVVDT05GSUdfTk9fQ09MTEFUSU9OICovCgojZW5kaWYK