LyoKKiBDb3B5cmlnaHQgqSB7MTk5OX0sIEludGVybmF0aW9uYWwgQnVzaW5lc3MgTWFjaGluZXMgQ29ycG9yYXRpb24gYW5kIG90aGVycy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqICAgRGF0ZSAgICAgICAgTmFtZSAgICAgICAgRGVzY3JpcHRpb24KKiAgIDEyLzE1Lzk5ICAgIHJnaWxsYW0gICAgIFBvcnQgZnJvbSBKYXZhLgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiovCgojaWZuZGVmIFJCQklfQkxEX0gKI2RlZmluZSBSQkJJX0JMRF9ICgojaW5jbHVkZSAicmJiaS5oIgojaW5jbHVkZSAicmJiaV90YmwuaCIKI2luY2x1ZGUgInVuaWNvZGUvdW5pc2V0LmgiCiNpbmNsdWRlICJ1dmVjdG9yLmgiCgpjbGFzcyBFeHByZXNzaW9uTGlzdDsKCi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLy8gUnVsZUJhc2VkQnJlYWtJdGVyYXRvci5CdWlsZGVyCi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLyoqCiAqIFRoZSBCdWlsZGVyIGNsYXNzIGhhcyB0aGUgam9iIG9mIGNvbnN0cnVjdGluZyBhIFJ1bGVCYXNlZEJyZWFrSXRlcmF0b3IgZnJvbSBhCiAqIHRleHR1YWwgZGVzY3JpcHRpb24uICBBIEJ1aWxkZXIgaXMgY29uc3RydWN0ZWQgYnkgUnVsZUJhc2VkQnJlYWtJdGVyYXRvcidzCiAqIGNvbnN0cnVjdG9yLCB3aGljaCB1c2VzIGl0IHRvIGNvbnN0cnVjdCB0aGUgaXRlcmF0b3IgaXRzZWxmIGFuZCB0aGVuIHRocm93cyBpdAogKiBhd2F5LgogKiA8cD5UaGUgY29uc3RydWN0aW9uIGxvZ2ljIGlzIHNlcGFyYXRlZCBvdXQgaW50byBpdHMgb3duIGNsYXNzIGZvciB0d28gcHJpbWFyeQogKiByZWFzb25zOgogKiA8dWw+PGxpPlRoZSBjb25zdHJ1Y3Rpb24gbG9naWMgaXMgcXVpdGUgY29tcGxpY2F0ZWQgYW5kIGxhcmdlLiAgU2VwYXJhdGluZyBpdAogKiBvdXQgaW50byBpdHMgb3duIGNsYXNzIG1lYW5zIHRoZSBjb2RlIG11c3Qgb25seSBiZSBsb2FkZWQgaW50byBtZW1vcnkgd2hpbGUgYQogKiBSdWxlQmFzZWRCcmVha0l0ZXJhdG9yIGlzIGJlaW5nIGNvbnN0cnVjdGVkLCBhbmQgY2FuIGJlIHB1cmdlZCBhZnRlciB0aGF0LgogKiA8bGk+VGhlcmUgaXMgYSBmYWlyIGFtb3VudCBvZiBzdGF0ZSB0aGF0IG11c3QgYmUgbWFpbnRhaW5lZCB0aHJvdWdob3V0IHRoZQogKiBjb25zdHJ1Y3Rpb24gcHJvY2VzcyB0aGF0IGlzIG5vdCBuZWVkZWQgYnkgdGhlIGl0ZXJhdG9yIGFmdGVyIGNvbnN0cnVjdGlvbi4KICogU2VwYXJhdGluZyB0aGlzIHN0YXRlIG91dCBpbnRvIGFub3RoZXIgY2xhc3MgcHJldmVudHMgYWxsIG9mIHRoZSBmdW5jdGlvbnMgdGhhdAogKiBjb25zdHJ1Y3QgdGhlIGl0ZXJhdG9yIGZyb20gaGF2aW5nIHRvIGhhdmUgcmVhbGx5IGxvbmcgcGFyYW1ldGVyIGxpc3RzLAogKiAoaG9wZWZ1bGx5KSBjb250cmlidXRpbmcgdG8gcmVhZGFiaWxpdHkgYW5kIG1haW50YWluYWJpbGl0eS48L3VsPgogKiA8cD5JdCdkIGJlIHJlYWxseSBuaWNlIGlmIHRoaXMgY291bGQgYmUgYW4gaW5kZXBlbmRlbnQgY2xhc3MgcmF0aGVyIHRoYW4gYW4KICogaW5uZXIgY2xhc3MsIGJlY2F1c2UgdGhhdCB3b3VsZCBzaG9ydGVuIHRoZSBzb3VyY2UgZmlsZSBjb25zaWRlcmFibHksIGJ1dAogKiBtYWtpbmcgQnVpbGRlciBhbiBpbm5lciBjbGFzcyBvZiBSdWxlQmFzZWRCcmVha0l0ZXJhdG9yIGFsbG93cyBpdCBkaXJlY3QgYWNjZXNzCiAqIHRvIFJ1bGVCYXNlZEJyZWFrSXRlcmF0b3IncyBwcml2YXRlIG1lbWJlcnMsIHdoaWNoIHNhdmVzIHVzIGZyb20gaGF2aW5nIHRvCiAqIHByb3ZpZGUgc29tZSBraW5kIG9mICJiYWNrIGRvb3IiIHRvIHRoZSBCdWlsZGVyIGNsYXNzIHRoYXQgY291bGQgdGhlbiBhbHNvIGJlCiAqIHVzZWQgYnkgb3RoZXIgY2xhc3Nlcy4KICovCmNsYXNzIFJ1bGVCYXNlZEJyZWFrSXRlcmF0b3JCdWlsZGVyIHsKCnByb3RlY3RlZDoKICAgIC8qKgogICAgICogVGhlIGl0ZXJhdG9yIHdlJ3JlIGNvbnN0cnVjdGluZy4KICAgICAqLwogICAgUnVsZUJhc2VkQnJlYWtJdGVyYXRvciYgaXRlcmF0b3I7CgogICAgLyoqCiAgICAgKiBUaGUgdGFibGVzIG9iamVjdCBmb3IgdGhlIGl0ZXJhdG9yIHdlJ3JlIGNvbnN0cnVjdGluZy4KICAgICAqLwogICAgUnVsZUJhc2VkQnJlYWtJdGVyYXRvclRhYmxlcyogdGFibGVzOwoKICAgIC8qKgogICAgICogQSB0ZW1wb3JhcnkgcGxhY2UgdG8gaG9sZCB0aGUgcnVsZXMgYXMgdGhleSdyZSBiZWluZyBwcm9jZXNzZWQuCiAgICAgKi8KICAgIFVWZWN0b3IgdGVtcFJ1bGVMaXN0OwogICAgCiAgICAvKioKICAgICAqIEEgdGVtcG9yYXJ5IGhvbGRpbmcgcGxhY2UgdXNlZCBmb3IgY2FsY3VsYXRpbmcgdGhlIGNoYXJhY3RlciBjYXRlZ29yaWVzLgogICAgICogVGhpcyBvYmplY3QgY29udGFpbnMgVW5pY29kZVNldCBvYmplY3RzLgogICAgICovCiAgICBVVmVjdG9yIGNhdGVnb3JpZXM7CgogICAgLyoqCiAgICAgKiBUaGUgbnVtYmVyIG9mIGNhdGVnb3JpZXMgKGFuZCB0aHVzIHRoZSBudW1iZXIgb2YgY29sdW1ucyBpbiB0aGUgZmluaXNoZWQgc3RhdGUgdGFibGVzKQogICAgICovCiAgICBpbnQzMl90IG51bUNhdGVnb3JpZXM7CgogICAgLyoqCiAgICAgKiBBIHRhYmxlIHVzZWQgdG8gbWFwIHBhcnRzIG9mIHJlZ2V4cCB0ZXh0IHRvIGxpc3RzIG9mIGNoYXJhY3RlciBjYXRlZ29yaWVzLAogICAgICogcmF0aGVyIHRoYW4gaGF2aW5nIHRvIGZpZ3VyZSB0aGVtIG91dCBmcm9tIHNjcmF0Y2ggZWFjaCB0aW1lCiAgICAgKi8KICAgIEV4cHJlc3Npb25MaXN0KiBleHByZXNzaW9uczsKCiAgICAvKioKICAgICAqIEEgdGVtcG9yYXJ5IGhvbGRpbmcgcGxhY2UgZm9yIHRoZSBsaXN0IG9mIGlnbm9yZSBjaGFyYWN0ZXJzCiAgICAgKi8KICAgIFVuaWNvZGVTZXQgaWdub3JlQ2hhcnM7CgogICAgLyoqCiAgICAgKiBBIHRlbXBvcmFyeSBob2xkaW5nIHBsYWNlIHdoZXJlIHRoZSBmb3J3YXJkIHN0YXRlIHRhYmxlIGlzIGJ1aWx0CiAgICAgKi8KICAgIFVWZWN0b3IgdGVtcFN0YXRlVGFibGU7CgogICAgLyoqCiAgICAgKiBBIGxpc3Qgb2YgYWxsIHRoZSBzdGF0ZXMgdGhhdCBoYXZlIHRvIGJlIGZpbGxlZCBpbiB3aXRoIHRyYW5zaXRpb25zIHRvIHRoZQogICAgICogbmV4dCBzdGF0ZSB0aGF0IGlzIGNyZWF0ZWQuICBVc2VkIHdoZW4gYnVpbGRpbmcgdGhlIHN0YXRlIHRhYmxlIGZyb20gdGhlCiAgICAgKiByZWd1bGFyIGV4cHJlc3Npb25zLgogICAgICovCiAgICBVVmVjdG9yIGRlY2lzaW9uUG9pbnRMaXN0OwoKICAgIC8qKgogICAgICogQSBVU3RhY2sgZm9yIGhvbGRpbmcgZGVjaXNpb24gcG9pbnQgbGlzdHMuICBUaGlzIGlzIHVzZWQgdG8gaGFuZGxlIG5lc3RlZAogICAgICogcGFyZW50aGVzZXMgYW5kIGJyYWNlcyBpbiByZWdleHBzLgogICAgICovCiAgICBVU3RhY2sgZGVjaXNpb25Qb2ludFN0YWNrOwoKICAgIC8qKgogICAgICogQSBsaXN0IG9mIHN0YXRlcyB0aGF0IGxvb3AgYmFjayBvbiB0aGVtc2VsdmVzLiAgVXNlZCB0byBoYW5kbGUgLio/CiAgICAgKi8KICAgIFVWZWN0b3IgbG9vcGluZ1N0YXRlczsKCiAgICAvKioKICAgICAqIExvb3Bpbmcgc3RhdGVzIGFjdHVhbGx5IGhhdmUgdG8gYmUgYmFja2ZpbGxlZCBsYXRlciBpbiB0aGUgcHJvY2VzcwogICAgICogdGhhbiBldmVyeXRoaW5nIGVsc2UuICBUaGlzIGlzIHdoZXJlIGEgdGhlIGxpc3Qgb2Ygc3RhdGVzIHRvIGJhY2tmaWxsCiAgICAgKiBpcyBhY2N1bXVsYXRlZC4gIFRoaXMgaXMgYWxzbyB1c2VkIHRvIGhhbmRsZSAuKj8KICAgICAqLwogICAgVVZlY3RvciBzdGF0ZXNUb0JhY2tmaWxsOwoKICAgIC8qKgogICAgICogQSBsaXN0IG1hcHBpbmcgcGFpcnMgb2Ygc3RhdGUgbnVtYmVycyBmb3Igc3RhdGVzIHRoYXQgYXJlIHRvIGJlIGNvbWJpbmVkCiAgICAgKiB0byB0aGUgc3RhdGUgbnVtYmVyIG9mIHRoZSBzdGF0ZSByZXByZXNlbnRpbmcgdGhlaXIgY29tYmluYXRpb24uICBVc2VkCiAgICAgKiBpbiB0aGUgcHJvY2VzcyBvZiBtYWtpbmcgdGhlIHN0YXRlIHRhYmxlIGRldGVybWluaXN0aWMgdG8gcHJldmVudAogICAgICogaW5maW5pdGUgcmVjdXJzaW9uLgogICAgICovCiAgICBVVmVjdG9yIG1lcmdlTGlzdDsKCiAgICAvKioKICAgICAqIEEgZmxhZyB0aGF0IGlzIHVzZWQgdG8gaW5kaWNhdGUgd2hlbiB0aGUgbGlzdCBvZiBsb29waW5nIHN0YXRlcyBjYW4KICAgICAqIGJlIHJlc2V0LgogICAgICovCiAgICBib29sX3QgY2xlYXJMb29waW5nU3RhdGVzOwoKICAgIC8qKgogICAgICogQSBwbGFjZSB3aGVyZSBhbiBlcnJvciBtZXNzYWdlIGNhbiBiZSBzdG9yZWQgaWYgd2UgZ2V0IGEgcGFyc2UgZXJyb3IuCiAgICAgKiBUaGUgZXJyb3IgbWVzc2FnZSBpcyBuZXZlciBkaXNwbGF5ZWQgYW55d2hlcmUsIHNvIHRoaXMgaXMgdXNlZnVsIHByZXR0eQogICAgICogbXVjaCBvbmx5IGluIGNvbmp1bmN0aW9uIHdpdGggYSBkZWJ1Z2dlci4KICAgICAqLwogICAgVW5pY29kZVN0cmluZyBlcnJvck1lc3NhZ2U7CgogICAgLyoqCiAgICAgKiBBIGJpdCBtYXNrIHVzZWQgdG8gaW5kaWNhdGUgYSBiaXQgaW4gdGhlIHRhYmxlJ3MgZmxhZ3MgY29sdW1uIHRoYXQgbWFya3MgYQogICAgICogc3RhdGUgYXMgYW4gYWNjZXB0aW5nIHN0YXRlLgogICAgICovCiAgICBzdGF0aWMgY29uc3QgaW50MzJfdCBFTkRfU1RBVEVfRkxBRyAvKj0gMHg4MDAwKi87CgogICAgLyoqCiAgICAgKiBBIGJpdCBtYXNrIHVzZWQgdG8gaW5kaWNhdGUgYSBiaXQgaW4gdGhlIHRhYmxlJ3MgZmxhZ3MgY29sdW1uIHRoYXQgbWFya3MgYQogICAgICogc3RhdGUgYXMgb25lIHRoZSBidWlsZGVyIHNob3VsZG4ndCBsb29wIHRvIGFueSBsb29waW5nIHN0YXRlcwogICAgICovCiAgICBzdGF0aWMgY29uc3QgaW50MzJfdCBET05UX0xPT1BfRkxBRyAvKj0gMHg0MDAwKi87CgogICAgLyoqCiAgICAgKiBBIGJpdCBtYXNrIHVzZWQgdG8gaW5kaWNhdGUgYSBiaXQgaW4gdGhlIHRhYmxlJ3MgZmxhZ3MgY29sdW1uIHRoYXQgbWFya3MgYQogICAgICogc3RhdGUgYXMgYSBsb29rYWhlYWQgc3RhdGUuCiAgICAgKi8KICAgIHN0YXRpYyBjb25zdCBpbnQzMl90IExPT0tBSEVBRF9TVEFURV9GTEFHIC8qPSAweDIwMDAqLzsKCiAgICAvKioKICAgICAqIEEgYml0IG1hc2sgcmVwcmVzZW50aW5nIHRoZSB1bmlvbiBvZiB0aGUgbWFzayB2YWx1ZXMgbGlzdGVkIGFib3ZlLgogICAgICogVXNlZCBmb3IgY2xlYXJpbmcgb3IgbWFza2luZyBvZmYgdGhlIGZsYWcgYml0cy4KICAgICAqLwogICAgc3RhdGljIGNvbnN0IGludDMyX3QgQUxMX0ZMQUdTIC8qPSBFTkRfU1RBVEVfRkxBRyB8IExPT0tBSEVBRF9TVEFURV9GTEFHCiAgICAgICAgICAgIHwgRE9OVF9MT09QX0ZMQUcqLzsKCnB1YmxpYzoKCiAgICAvKioKICAgICAqIFRoZSBCdWlsZGVyIGNsYXNzIGNvbnRhaW5zIGEgcmVmZXJlbmNlIHRvIHRoZSBpdGVyYXRvciBpdCdzIHN1cHBvc2VkIHRvIGJ1aWxkLgogICAgICovCiAgICBSdWxlQmFzZWRCcmVha0l0ZXJhdG9yQnVpbGRlcihSdWxlQmFzZWRCcmVha0l0ZXJhdG9yJiBpdGVyYXRvclRvQnVpbGQpOwoKICAgIC8qKgogICAgICogRGVzdHJ1Y3Rvci4KICAgICAqLwogICAgflJ1bGVCYXNlZEJyZWFrSXRlcmF0b3JCdWlsZGVyKCk7CgogICAgLyoqCiAgICAgKiBUaGlzIGlzIHRoZSBtYWluIGZ1bmN0aW9uIGZvciBzZXR0aW5nIHVwIHRoZSBCcmVha0l0ZXJhdG9yJ3MgdGFibGVzLiAgSXQKICAgICAqIGp1c3QgdmVjdG9ycyBkaWZmZXJlbnQgcGFydHMgb2YgdGhlIGpvYiBvZmYgdG8gb3RoZXIgZnVuY3Rpb25zLgogICAgICovCiAgICB2aXJ0dWFsIHZvaWQgYnVpbGRCcmVha0l0ZXJhdG9yKGNvbnN0IFVuaWNvZGVTdHJpbmcmICAgIGRlc2NyaXB0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiBlcnIpOwoKcHJpdmF0ZToKCiAgICAvKioKICAgICAqIFRodXMgZnVuY3Rpb24gaGFzIHRocmVlIG1haW4gcHVycG9zZXM6CiAgICAgKiA8dWw+PGxpPlBlcmZvcm0gZ2VuZXJhbCBzeW50YXggY2hlY2tpbmcgb24gdGhlIGRlc2NyaXB0aW9uLCBzbyB0aGUgcmVzdCBvZiB0aGUKICAgICAqIGJ1aWxkIGNvZGUgY2FuIGFzc3VtZSB0aGF0IGl0J3MgcGFyc2luZyBhIGxlZ2FsIGRlc2NyaXB0aW9uLgogICAgICogPGxpPlNwbGl0IHRoZSBkZXNjcmlwdGlvbiBpbnRvIHNlcGFyYXRlIHJ1bGVzCiAgICAgKiA8bGk+UGVyZm9ybSB2YXJpYWJsZS1uYW1lIHN1YnN0aXR1dGlvbnMgKHNvIHRoYXQgbm8gb25lIGVsc2Ugc2VlcyB2YXJpYWJsZSBuYW1lcykKICAgICAqIDwvdWw+CiAgICAgKi8KICAgIHZpcnR1YWwgdm9pZCBidWlsZFJ1bGVMaXN0KFVuaWNvZGVTdHJpbmcmIGRlc2NyaXB0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYgZXJyKTsKCnByb3RlY3RlZDoKCiAgICAvKioKICAgICAqIFRoaXMgZnVuY3Rpb24gcGVyZm9ybXMgdmFyaWFibGUtbmFtZSBzdWJzdGl0dXRpb25zLiAgRmlyc3QgaXQgZG9lcyBzeW50YXgKICAgICAqIGNoZWNraW5nIG9uIHRoZSB2YXJpYWJsZS1uYW1lIGRlZmluaXRpb24uICBJZiBpdCdzIHN5bnRhY3RpY2FsbHkgdmFsaWQsIGl0CiAgICAgKiB0aGVuIGdvZXMgdGhyb3VnaCB0aGUgcmVtYWluZGVyIG9mIHRoZSBkZXNjcmlwdGlvbiBhbmQgZG9lcyBhIHNpbXBsZQogICAgICogZmluZC1hbmQtcmVwbGFjZSBvZiB0aGUgdmFyaWFibGUgbmFtZSB3aXRoIGl0cyB0ZXh0LiAgKFRoZSB2YXJpYWJsZSB0ZXh0CiAgICAgKiBtdXN0IGJlIGVuY2xvc2VkIGluIGVpdGhlciBbXSBvciAoKSBmb3IgdGhpcyB0byB3b3JrLikKICAgICAqLwogICAgdmlydHVhbCB2b2lkIHByb2Nlc3NTdWJzdGl0dXRpb24oVW5pY29kZVN0cmluZyYgZGVzY3JpcHRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVVGV4dE9mZnNldCBydWxlU3RhcnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVVGV4dE9mZnNldCBydWxlRW5kLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVVRleHRPZmZzZXQgc3RhcnRQb3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiBlcnIpOwoKICAgIC8qKgogICAgICogVGhpcyBmdW5jdGlvbiBkZWZpbmVzIGEgcHJvdG9jb2wgZm9yIGhhbmRsaW5nIHN1YnN0aXR1dGlvbiBuYW1lcyB0aGF0CiAgICAgKiBhcmUgInNwZWNpYWwsIiBpLmUuLCB0aGF0IGhhdmUgc29tZSBwcm9wZXJ0eSBiZXlvbmQganVzdCBiZWluZwogICAgICogc3Vic3RpdHV0aW9ucy4gIEF0IHRoZSBSdWxlQmFzZWRCcmVha0l0ZXJhdG9yIGxldmVsLCB3ZSBoYXZlIG9uZQogICAgICogc3BlY2lhbCBzdWJzdGl0dXRpb24gbmFtZSwgIjxpZ25vcmU+Ii4gIFN1YmNsYXNzZXMgY2FuIG92ZXJyaWRlIHRoaXMKICAgICAqIGZ1bmN0aW9uIHRvIGFkZCBtb3JlLiAgQW55IHNwZWNpYWwgcHJvY2Vzc2luZyB0aGF0IGhhcyB0byBnbyBvbiBiZXlvbmQKICAgICAqIHRoYXQgd2hpY2ggaXMgZG9uZSBieSB0aGUgbm9ybWFsIHN1YnN0aXR1dGlvbi1wcm9jZXNzaW5nIGNvZGUgaXMgZG9uZQogICAgICogaGVyZS4KICAgICAqLwogICAgdmlydHVhbCB2b2lkIGhhbmRsZVNwZWNpYWxTdWJzdGl0dXRpb24oY29uc3QgVW5pY29kZVN0cmluZyYgcmVwbGFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFVuaWNvZGVTdHJpbmcmIHJlcGxhY2VXaXRoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50MzJfdCBzdGFydFBvcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFVuaWNvZGVTdHJpbmcmIGRlc2NyaXB0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYgZXJyKTsKCiAgICAvKioKICAgICAqIFRoaXMgZnVuY3Rpb24gcHJvdmlkZXMgYSBob29rIGZvciBzdWJjbGFzc2VzIHRvIG1lc3Mgd2l0aCB0aGUgY2hhcmFjdGVyCiAgICAgKiBjYXRlZ29yeSB0YWJsZS4KICAgICAqLwogICAgdmlydHVhbCB2b2lkIG11bmdlRXhwcmVzc2lvbkxpc3QoKTsKCiAgICAvKioKICAgICAqIFRoaXMgZnVuY3Rpb24gYnVpbGRzIHRoZSBjaGFyYWN0ZXIgY2F0ZWdvcnkgdGFibGUuICBPbiBlbnRyeSwKICAgICAqIHRlbXBSdWxlTGlzdCBpcyBhIFVWZWN0b3Igb2YgYnJlYWsgcnVsZXMgdGhhdCBoYXMgaGFkIHZhcmlhYmxlIG5hbWVzIHN1YnN0aXR1dGVkLgogICAgICogT24gZXhpdCwgdGhlIGNoYXJDYXRlZ29yeVRhYmxlIGRhdGEgbWVtYmVyIGhhcyBiZWVuIGluaXRpYWxpemVkIHRvIGhvbGQgdGhlCiAgICAgKiBjaGFyYWN0ZXIgY2F0ZWdvcnkgdGFibGUsIGFuZCB0ZW1wUnVsZUxpc3QncyBydWxlcyBoYXZlIGJlZW4gbXVuZ2VkIHRvIGNvbnRhaW4KICAgICAqIGNoYXJhY3RlciBjYXRlZ29yeSBudW1iZXJzIGV2ZXJ5d2hlcmUgYSBsaXRlcmFsIGNoYXJhY3RlciBvciBhIFtdIGV4cHJlc3Npb24KICAgICAqIG9yaWdpbmFsbHkgb2NjdXJyZWQuCiAgICAgKi8KICAgIHZpcnR1YWwgdm9pZCBidWlsZENoYXJDYXRlZ29yaWVzKFVFcnJvckNvZGUmIGVycik7Cgpwcml2YXRlOgoKICAgIC8qKgogICAgICogVGhpcyBpcyB0aGUgZnVuY3Rpb24gdGhhdCBidWlsZHMgdGhlIGZvcndhcmQgc3RhdGUgdGFibGUuICBNb3N0IG9mIHRoZSByZWFsCiAgICAgKiB3b3JrIGlzIGRvbmUgaW4gcGFyc2VSdWxlKCksIHdoaWNoIGlzIGNhbGxlZCBvbmNlIGZvciBlYWNoIHJ1bGUgaW4gdGhlCiAgICAgKiBkZXNjcmlwdGlvbi4KICAgICAqLwogICAgdmlydHVhbCB2b2lkIGJ1aWxkU3RhdGVUYWJsZShVRXJyb3JDb2RlJiBlcnIpOwoKICAgIC8qKgogICAgICogVGhpcyBpcyB3aGVyZSBtb3N0IG9mIHRoZSB3b3JrIHJlYWxseSBoYXBwZW5zLiAgVGhpcyByb3V0aW5lIHBhcnNlcyBhIHNpbmdsZQogICAgICogcnVsZSBpbiB0aGUgcnVsZSBkZXNjcmlwdGlvbiwgYWRkaW5nIGFuZCBtb2RpZnlpbmcgc3RhdGVzIGluIHRoZSBzdGF0ZQogICAgICogdGFibGUgYWNjb3JkaW5nIHRvIHRoZSBuZXcgZXhwcmVzc2lvbi4gIFRoZSBzdGF0ZSB0YWJsZSBpcyBrZXB0IGRldGVybWluaXN0aWMKICAgICAqIHRocm91Z2hvdXQgdGhlIHdob2xlIG9wZXJhdGlvbiwgYWx0aG91Z2ggc29tZSB1Z2x5IHBvc3Rwcm9jZXNzaW5nIGlzIG5lZWRlZAogICAgICogdG8gaGFuZGxlIHRoZSAqPyB0b2tlbi4KICAgICAqLwogICAgdmlydHVhbCB2b2lkIHBhcnNlUnVsZShjb25zdCBVbmljb2RlU3RyaW5nJiBydWxlLAogICAgICAgICAgICAgICAgICAgICAgICAgICBib29sX3QgICAgICAgICAgICAgICBmb3J3YXJkKTsKCiAgICAvKioKICAgICAqIFVwZGF0ZSBlbnRyaWVzIGluIHRoZSBzdGF0ZSB0YWJsZSwgYW5kIG1lcmdlIHN0YXRlcyB3aGVuIG5lY2Vzc2FyeSB0byBrZWVwCiAgICAgKiB0aGUgdGFibGUgZGV0ZXJtaW5pc3RpYy4KICAgICAqIEBwYXJhbSByb3dzIFRoZSBsaXN0IG9mIHJvd3MgdGhhdCBuZWVkIHVwZGF0aW5nICh0aGUgZGVjaXNpb24gcG9pbnQgbGlzdCkKICAgICAqIEBwYXJhbSBwZW5kaW5nQ2hhcnMgQSBjaGFyYWN0ZXIgY2F0ZWdvcnkgbGlzdCwgZW5jb2RlZCBpbiBhIFN0cmluZy4gIFRoaXMgaXMgdGhlCiAgICAgKiBsaXN0IG9mIHRoZSBjb2x1bW5zIHRoYXQgbmVlZCB1cGRhdGluZy4KICAgICAqIEBwYXJhbSBuZXdWYWx1ZSBVcGRhdGUgdGhlIGNlbGxzIHNwZWNmaWVkIGFib3ZlIHRvIGNvbnRhaW4gdGhpcyB2YWx1ZQogICAgICovCiAgICB2aXJ0dWFsIHZvaWQgdXBkYXRlU3RhdGVUYWJsZShjb25zdCBVVmVjdG9yJiAgICAgICByb3dzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVW5pY29kZVN0cmluZyYgcGVuZGluZ0NoYXJzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50MTZfdCAgICAgICAgICAgICAgbmV3VmFsdWUpOwoKICAgIC8qKgogICAgICogVGhlIHJlYWwgd29yayBvZiBtYWtpbmcgdGhlIHN0YXRlIHRhYmxlIGRldGVybWluaXN0aWMgaGFwcGVucyBoZXJlLiAgVGhpcyBmdW5jdGlvbgogICAgICogbWVyZ2VzIGEgc3RhdGUgaW4gdGhlIHN0YXRlIHRhYmxlIChzcGVjaWZpZWQgYnkgcm93TnVtKSB3aXRoIGEgc3RhdGUgdGhhdCBpcwogICAgICogcGFzc2VkIGluIChuZXdWYWx1ZXMpLiAgVGhlIGJhc2ljIHByb2Nlc3MgaXMgdG8gY29weSB0aGUgbm9uemVybyBjZWxscyBpbiBuZXdTdGF0ZXMKICAgICAqIGludG8gdGhlIHN0YXRlIGluIHRoZSBzdGF0ZSB0YWJsZSAod2UnbGwgY2FsbCB0aGF0IG9sZFZhbHVlcykuICBJZiB0aGVyZSdzIGEKICAgICAqIGNvbGxpc2lvbiAoaS5lLiwgaWYgdGhlIHNhbWUgY2VsbCBoYXMgYSBub256ZXJvIHZhbHVlIGluIGJvdGggc3RhdGVzLCBhbmQgaXQncwogICAgICogbm90IHRoZSBTQU1FIHZhbHVlKSwgdGhlbiB3ZSBoYXZlIHRvIHJlY29uY2lsZSB0aGUgY29sbGlzaW9uLiAgV2UgZG8gdGhpcyBieQogICAgICogY3JlYXRpbmcgYSBuZXcgc3RhdGUsIGFkZGluZyBpdCB0byB0aGUgZW5kIG9mIHRoZSBzdGF0ZSB0YWJsZSwgYW5kIHVzaW5nIHRoaXMKICAgICAqIGZ1bmN0aW9uIHJlY3Vyc2l2ZWx5IHRvIG1lcmdlIHRoZSBvcmlnaW5hbCB0d28gc3RhdGVzIGludG8gYSBzaW5nbGUsIGNvbWJpbmVkCiAgICAgKiBzdGF0ZS4gIFRoaXMgcHJvY2VzcyBtYXkgaGFwcGVuIHJlY3Vyc2l2ZWx5IChpLmUuLCBlYWNoIHN1Y2Nlc3NpdmUgbGV2ZWwgbWF5CiAgICAgKiBpbnZvbHZlIGNvbGxpc2lvbnMpLiAgVG8gcHJldmVudCBpbmZpbml0ZSByZWN1cnNpb24sIHdlIGtlZXAgYSBsb2cgb2YgbWVyZ2UKICAgICAqIG9wZXJhdGlvbnMuICBBbnkgdGltZSB3ZSdyZSBtZXJnaW5nIHR3byBzdGF0ZXMgd2UndmUgbWVyZ2VkIGJlZm9yZSwgd2UgY2FuIGp1c3QKICAgICAqIHN1cHBseSB0aGUgcm93IG51bWJlciBmb3IgdGhlIHJlc3VsdCBvZiB0aGF0IG1lcmdlIG9wZXJhdGlvbiByYXRoZXIgdGhhbiBjcmVhdGluZwogICAgICogYSBuZXcgc3RhdGUganVzdCBsaWtlIGl0LgogICAgICogQHBhcmFtIHJvd051bSBUaGUgcm93IG51bWJlciBpbiB0aGUgc3RhdGUgdGFibGUgb2YgdGhlIHN0YXRlIHRvIGJlIHVwZGF0ZWQKICAgICAqIEBwYXJhbSBuZXdWYWx1ZXMgVGhlIHN0YXRlIHRvIG1lcmdlIGl0IHdpdGguCiAgICAgKiBAcGFyYW0gcm93c0JlaW5nVXBkYXRlZCBBIGNvcHkgb2YgdGhlIGxpc3Qgb2Ygcm93cyBwYXNzZWQgdG8gdXBkYXRlU3RhdGVUYWJsZSgpCiAgICAgKiAoaXRzZWxmIGEgY29weSBvZiB0aGUgZGVjaXNpb24gcG9pbnQgbGlzdCBmcm9tIHBhcnNlUnVsZSgpKS4gIE5ld2x5LWNyZWF0ZWQKICAgICAqIHN0YXRlcyBnZXQgYWRkZWQgdG8gdGhlIGRlY2lzaW9uIHBvaW50IGxpc3QgaWYgdGhlaXIgInBhcmVudHMiIHdlcmUgb24gaXQuCiAgICAgKi8KICAgIHZpcnR1YWwgdm9pZCBtZXJnZVN0YXRlcyhpbnQzMl90ICByb3dOdW0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50MTZfdCogbmV3VmFsdWVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFVWZWN0b3ImIHJvd3NCZWluZ1VwZGF0ZWQpOwoKICAgIC8qKgogICAgICogVGhlIG1lcmdlIGxpc3QgaXMgYSBsaXN0IG9mIHBhaXJzIG9mIHJvd3MgdGhhdCBoYXZlIGJlZW4gbWVyZ2VkIHNvbWV3aGVyZSBpbgogICAgICogdGhlIHByb2Nlc3Mgb2YgYnVpbGRpbmcgdGhpcyBzdGF0ZSB0YWJsZSwgYWxvbmcgd2l0aCB0aGUgcm93IG51bWJlciBvZiB0aGUKICAgICAqIHJvdyBjb250YWluaW5nIHRoZSBtZXJnZWQgc3RhdGUuICBUaGlzIGZ1bmN0aW9uIGxvb2tzIHVwIGEgcGFpciBvZiByb3cgbnVtYmVycwogICAgICogYW5kIHJldHVybnMgdGhlIHJvdyBudW1iZXIgb2YgdGhlIHJvdyB0aGV5IGNvbWJpbmUgaW50by4gIChJdCByZXR1cm5zIDAgaWYKICAgICAqIHRoaXMgcGFpciBvZiByb3dzIGlzbid0IGluIHRoZSBtZXJnZSBsaXN0LikKICAgICAqLwogICAgdmlydHVhbCBpbnQzMl90IHNlYXJjaE1lcmdlTGlzdChpbnQzMl90IGEsIGludDMyX3QgYik7CgogICAgLyoqCiAgICAgKiBUaGlzIGZ1bmN0aW9uIGlzIHVzZWQgdG8gdXBkYXRlIHRoZSBsaXN0IG9mIGN1cnJlbnQgbG9vb3Bpbmcgc3RhdGVzIChpLmUuLAogICAgICogc3RhdGVzIHRoYXQgYXJlIGNvbnRyb2xsZWQgYnkgYSAqPyBjb25zdHJ1Y3QpLiAgSXQgYmFja2ZpbGxzIHZhbHVlcyBmcm9tCiAgICAgKiB0aGUgbG9vcGluZyBzdGF0ZXMgaW50byB1bnBvcHVsYXRlZCBjZWxscyBvZiB0aGUgc3RhdGVzIHRoYXQgYXJlIGN1cnJlbnRseQogICAgICogbWFya2VkIGZvciBiYWNrZmlsbGluZywgYW5kIHRoZW4gdXBkYXRlcyB0aGUgbGlzdCBvZiBsb29waW5nIHN0YXRlcyB0byBiZQogICAgICogdGhlIG5ldyBsaXN0CiAgICAgKiBAcGFyYW0gbmV3TG9vcGluZ1N0YXRlcyBUaGUgbGlzdCBvZiBuZXcgbG9vcGluZyBzdGF0ZXMKICAgICAqIEBwYXJhbSBlbmRTdGF0ZXMgVGhlIGxpc3Qgb2Ygc3RhdGVzIHRvIHRyZWF0IGFzIGVuZCBzdGF0ZXMgKHN0YXRlcyB0aGF0CiAgICAgKiBjYW4gZXhpdCB0aGUgbG9vcCkuCiAgICAgKi8KICAgIHZpcnR1YWwgdm9pZCBzZXRMb29waW5nU3RhdGVzKGNvbnN0IFVWZWN0b3IqIG5ld0xvb3BpbmdTdGF0ZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBVVmVjdG9yJiBlbmRTdGF0ZXMpOwoKICAgIC8qKgogICAgICogVGhpcyByZW1vdmVzICJlbmRpbmcgc3RhdGVzIiBhbmQgc3RhdGVzIHJlYWNoYWJsZSBmcm9tIHRoZW0gZnJvbSB0aGUKICAgICAqIGxpc3Qgb2Ygc3RhdGVzIHRvIGJhY2tmaWxsLgogICAgICogQHBhcmFtIFRoZSByb3cgbnVtYmVyIG9mIHRoZSBzdGF0ZSB0byByZW1vdmUgZnJvbSB0aGUgYmFja2ZpbGwgbGlzdAogICAgICovCiAgICB2aXJ0dWFsIHZvaWQgZWxpbWluYXRlQmFja2ZpbGxTdGF0ZXMoaW50MzJfdCBiYXNlU3RhdGUpOwoKICAgIC8qKgogICAgICogVGhpcyBmdW5jdGlvbiBjb21wbGV0ZXMgdGhlIGJhY2tmaWxsaW5nIHByb2Nlc3MgYnkgYWN0dWFsbHkgZG9pbmcgdGhlCiAgICAgKiBiYWNrZmlsbGluZyBvbiB0aGUgc3RhdGVzIHRoYXQgYXJlIG1hcmtlZCBmb3IgaXQKICAgICAqLwogICAgdmlydHVhbCB2b2lkIGJhY2tmaWxsTG9vcGluZ1N0YXRlcyh2b2lkKTsKCiAgICAvKioKICAgICAqIFRoaXMgZnVuY3Rpb24gY29tcGxldGVzIHRoZSBzdGF0ZS10YWJsZS1idWlsZGluZyBwcm9jZXNzIGJ5IGRvaW5nIHNldmVyYWwKICAgICAqIHBvc3Rwcm9jZXNzaW5nIHN0ZXBzIGFuZCBjb3B5aW5nIGV2ZXJ5dGhpbmcgaW50byBpdHMgZmluYWwgcmVzdGluZyBwbGFjZQogICAgICogaW4gdGhlIGl0ZXJhdG9yIGl0c2VsZgogICAgICogQHBhcmFtIGZvcndhcmQgVHJ1ZSBpZiB3ZSdyZSB3b3JraW5nIG9uIHRoZSBmb3J3YXJkIHN0YXRlIHRhYmxlCiAgICAgKi8KICAgIHZpcnR1YWwgdm9pZCBmaW5pc2hCdWlsZGluZ1N0YXRlVGFibGUoYm9vbF90IGZvcndhcmQpOwoKICAgIC8qKgogICAgICogVGhpcyBmdW5jdGlvbiBidWlsZHMgdGhlIGJhY2t3YXJkIHN0YXRlIHRhYmxlIGZyb20gdGhlIGZvcndhcmQgc3RhdGUKICAgICAqIHRhYmxlIGFuZCBhbnkgYWRkaXRpb25hbCBydWxlcyAoaWRlbnRpZmllZCBieSB0aGUgISBvbiB0aGUgZnJvbnQpCiAgICAgKiBzdXBwbGllZCBpbiB0aGUgZGVzY3JpcHRpb24KICAgICAqLwogICAgdmlydHVhbCB2b2lkIGJ1aWxkQmFja3dhcmRzU3RhdGVUYWJsZShVRXJyb3JDb2RlJiBlcnIpOwoKcHJvdGVjdGVkOgoKICAgIC8qKgogICAgICogVGhyb3dzIGFuIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiByZXByZXNlbnRpbmcgYSBzeW50YXggZXJyb3IgaW4gdGhlIHJ1bGUKICAgICAqIGRlc2NyaXB0aW9uLiAgVGhlIGV4Y2VwdGlvbidzIG1lc3NhZ2UgY29udGFpbnMgc29tZSBkZWJ1Z2dpbmcgaW5mb3JtYXRpb24uCiAgICAgKiBAcGFyYW0gbWVzc2FnZSBBIG1lc3NhZ2UgZGVzY3JpYmluZyB0aGUgcHJvYmxlbQogICAgICogQHBhcmFtIHBvc2l0aW9uIFRoZSBwb3NpdGlvbiBpbiB0aGUgZGVzY3JpcHRpb24gd2hlcmUgdGhlIHByb2JsZW0gd2FzCiAgICAgKiBkaXNjb3ZlcmVkCiAgICAgKiBAcGFyYW0gY29udGV4dCBUaGUgc3RyaW5nIGNvbnRhaW5pbmcgdGhlIGVycm9yCiAgICAgKi8KICAgIHZpcnR1YWwgdm9pZCBzZXRVcEVycm9yTWVzc2FnZShjb25zdCBVbmljb2RlU3RyaW5nJiBtZXNzYWdlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludDMyX3QgcG9zaXRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVW5pY29kZVN0cmluZyYgY29udGV4dCk7Cn07CgojZW5kaWYK