LyoKKiBDb3B5cmlnaHQgqSB7MTk5OX0sIEludGVybmF0aW9uYWwgQnVzaW5lc3MgTWFjaGluZXMgQ29ycG9yYXRpb24gYW5kIG90aGVycy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqICAgRGF0ZSAgICAgICAgTmFtZSAgICAgICAgRGVzY3JpcHRpb24KKiAgIDEyLzE1Lzk5ICAgIHJnaWxsYW0gICAgIFBvcnQgZnJvbSBKYXZhLgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiovCgojaWZuZGVmIFJCQklfQkxEX0gKI2RlZmluZSBSQkJJX0JMRF9ICgojaW5jbHVkZSAicmJiaS5oIgojaW5jbHVkZSAicmJiaV90YmwuaCIKI2luY2x1ZGUgInVuaWNvZGUvdW5pc2V0LmgiCiNpbmNsdWRlICJ1dmVjdG9yLmgiCgpjbGFzcyBFeHByZXNzaW9uTGlzdDsKCi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLy8gUnVsZUJhc2VkQnJlYWtJdGVyYXRvci5CdWlsZGVyCi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLyoqCiAqIFRoZSBCdWlsZGVyIGNsYXNzIGhhcyB0aGUgam9iIG9mIGNvbnN0cnVjdGluZyBhIFJ1bGVCYXNlZEJyZWFrSXRlcmF0b3IgZnJvbSBhCiAqIHRleHR1YWwgZGVzY3JpcHRpb24uICBBIEJ1aWxkZXIgaXMgY29uc3RydWN0ZWQgYnkgUnVsZUJhc2VkQnJlYWtJdGVyYXRvcidzCiAqIGNvbnN0cnVjdG9yLCB3aGljaCB1c2VzIGl0IHRvIGNvbnN0cnVjdCB0aGUgaXRlcmF0b3IgaXRzZWxmIGFuZCB0aGVuIHRocm93cyBpdAogKiBhd2F5LgogKiA8cD5UaGUgY29uc3RydWN0aW9uIGxvZ2ljIGlzIHNlcGFyYXRlZCBvdXQgaW50byBpdHMgb3duIGNsYXNzIGZvciB0d28gcHJpbWFyeQogKiByZWFzb25zOgogKiA8dWw+PGxpPlRoZSBjb25zdHJ1Y3Rpb24gbG9naWMgaXMgcXVpdGUgY29tcGxpY2F0ZWQgYW5kIGxhcmdlLiAgU2VwYXJhdGluZyBpdAogKiBvdXQgaW50byBpdHMgb3duIGNsYXNzIG1lYW5zIHRoZSBjb2RlIG11c3Qgb25seSBiZSBsb2FkZWQgaW50byBtZW1vcnkgd2hpbGUgYQogKiBSdWxlQmFzZWRCcmVha0l0ZXJhdG9yIGlzIGJlaW5nIGNvbnN0cnVjdGVkLCBhbmQgY2FuIGJlIHB1cmdlZCBhZnRlciB0aGF0LgogKiA8bGk+VGhlcmUgaXMgYSBmYWlyIGFtb3VudCBvZiBzdGF0ZSB0aGF0IG11c3QgYmUgbWFpbnRhaW5lZCB0aHJvdWdob3V0IHRoZQogKiBjb25zdHJ1Y3Rpb24gcHJvY2VzcyB0aGF0IGlzIG5vdCBuZWVkZWQgYnkgdGhlIGl0ZXJhdG9yIGFmdGVyIGNvbnN0cnVjdGlvbi4KICogU2VwYXJhdGluZyB0aGlzIHN0YXRlIG91dCBpbnRvIGFub3RoZXIgY2xhc3MgcHJldmVudHMgYWxsIG9mIHRoZSBmdW5jdGlvbnMgdGhhdAogKiBjb25zdHJ1Y3QgdGhlIGl0ZXJhdG9yIGZyb20gaGF2aW5nIHRvIGhhdmUgcmVhbGx5IGxvbmcgcGFyYW1ldGVyIGxpc3RzLAogKiAoaG9wZWZ1bGx5KSBjb250cmlidXRpbmcgdG8gcmVhZGFiaWxpdHkgYW5kIG1haW50YWluYWJpbGl0eS48L3VsPgogKiA8cD5JdCdkIGJlIHJlYWxseSBuaWNlIGlmIHRoaXMgY291bGQgYmUgYW4gaW5kZXBlbmRlbnQgY2xhc3MgcmF0aGVyIHRoYW4gYW4KICogaW5uZXIgY2xhc3MsIGJlY2F1c2UgdGhhdCB3b3VsZCBzaG9ydGVuIHRoZSBzb3VyY2UgZmlsZSBjb25zaWRlcmFibHksIGJ1dAogKiBtYWtpbmcgQnVpbGRlciBhbiBpbm5lciBjbGFzcyBvZiBSdWxlQmFzZWRCcmVha0l0ZXJhdG9yIGFsbG93cyBpdCBkaXJlY3QgYWNjZXNzCiAqIHRvIFJ1bGVCYXNlZEJyZWFrSXRlcmF0b3IncyBwcml2YXRlIG1lbWJlcnMsIHdoaWNoIHNhdmVzIHVzIGZyb20gaGF2aW5nIHRvCiAqIHByb3ZpZGUgc29tZSBraW5kIG9mICJiYWNrIGRvb3IiIHRvIHRoZSBCdWlsZGVyIGNsYXNzIHRoYXQgY291bGQgdGhlbiBhbHNvIGJlCiAqIHVzZWQgYnkgb3RoZXIgY2xhc3Nlcy4KICovCmNsYXNzIFJ1bGVCYXNlZEJyZWFrSXRlcmF0b3JCdWlsZGVyIHsKCnByb3RlY3RlZDoKICAgIC8qKgogICAgICogVGhlIGl0ZXJhdG9yIHdlJ3JlIGNvbnN0cnVjdGluZy4KICAgICAqLwogICAgUnVsZUJhc2VkQnJlYWtJdGVyYXRvciYgaXRlcmF0b3I7CgogICAgLyoqCiAgICAgKiBUaGUgdGFibGVzIG9iamVjdCBmb3IgdGhlIGl0ZXJhdG9yIHdlJ3JlIGNvbnN0cnVjdGluZy4KICAgICAqLwogICAgUnVsZUJhc2VkQnJlYWtJdGVyYXRvclRhYmxlcyogdGFibGVzOwoKICAgIC8qKgogICAgICogQSB0ZW1wb3JhcnkgcGxhY2UgdG8gaG9sZCB0aGUgcnVsZXMgYXMgdGhleSdyZSBiZWluZyBwcm9jZXNzZWQuCiAgICAgKi8KICAgIFVWZWN0b3IgdGVtcFJ1bGVMaXN0OwogICAgCiAgICAvKioKICAgICAqIEEgdGVtcG9yYXJ5IGhvbGRpbmcgcGxhY2UgdXNlZCBmb3IgY2FsY3VsYXRpbmcgdGhlIGNoYXJhY3RlciBjYXRlZ29yaWVzLgogICAgICogVGhpcyBvYmplY3QgY29udGFpbnMgVW5pY29kZVNldCBvYmplY3RzLgogICAgICovCiAgICBVVmVjdG9yIGNhdGVnb3JpZXM7CgogICAgLyoqCiAgICAgKiBUaGUgbnVtYmVyIG9mIGNhdGVnb3JpZXMgKGFuZCB0aHVzIHRoZSBudW1iZXIgb2YgY29sdW1ucyBpbiB0aGUgZmluaXNoZWQgc3RhdGUgdGFibGVzKQogICAgICovCiAgICBpbnQzMl90IG51bUNhdGVnb3JpZXM7CgogICAgLyoqCiAgICAgKiBBIHRhYmxlIHVzZWQgdG8gbWFwIHBhcnRzIG9mIHJlZ2V4cCB0ZXh0IHRvIGxpc3RzIG9mIGNoYXJhY3RlciBjYXRlZ29yaWVzLAogICAgICogcmF0aGVyIHRoYW4gaGF2aW5nIHRvIGZpZ3VyZSB0aGVtIG91dCBmcm9tIHNjcmF0Y2ggZWFjaCB0aW1lCiAgICAgKi8KICAgIEV4cHJlc3Npb25MaXN0KiBleHByZXNzaW9uczsKCiAgICAvKioKICAgICAqIEEgdGVtcG9yYXJ5IGhvbGRpbmcgcGxhY2UgZm9yIHRoZSBsaXN0IG9mIGlnbm9yZSBjaGFyYWN0ZXJzCiAgICAgKi8KICAgIFVuaWNvZGVTZXQgaWdub3JlQ2hhcnM7CgogICAgLyoqCiAgICAgKiBBIHRlbXBvcmFyeSBob2xkaW5nIHBsYWNlIHdoZXJlIHRoZSBmb3J3YXJkIHN0YXRlIHRhYmxlIGlzIGJ1aWx0CiAgICAgKi8KICAgIFVWZWN0b3IgdGVtcFN0YXRlVGFibGU7CgogICAgLyoqCiAgICAgKiBBIGxpc3Qgb2YgYWxsIHRoZSBzdGF0ZXMgdGhhdCBoYXZlIHRvIGJlIGZpbGxlZCBpbiB3aXRoIHRyYW5zaXRpb25zIHRvIHRoZQogICAgICogbmV4dCBzdGF0ZSB0aGF0IGlzIGNyZWF0ZWQuICBVc2VkIHdoZW4gYnVpbGRpbmcgdGhlIHN0YXRlIHRhYmxlIGZyb20gdGhlCiAgICAgKiByZWd1bGFyIGV4cHJlc3Npb25zLgogICAgICovCiAgICBVVmVjdG9yIGRlY2lzaW9uUG9pbnRMaXN0OwoKICAgIC8qKgogICAgICogQSBVU3RhY2sgZm9yIGhvbGRpbmcgZGVjaXNpb24gcG9pbnQgbGlzdHMuICBUaGlzIGlzIHVzZWQgdG8gaGFuZGxlIG5lc3RlZAogICAgICogcGFyZW50aGVzZXMgYW5kIGJyYWNlcyBpbiByZWdleHBzLgogICAgICovCiAgICBVU3RhY2sgZGVjaXNpb25Qb2ludFN0YWNrOwoKICAgIC8qKgogICAgICogQSBsaXN0IG9mIHN0YXRlcyB0aGF0IGxvb3AgYmFjayBvbiB0aGVtc2VsdmVzLiAgVXNlZCB0byBoYW5kbGUgLio/CiAgICAgKi8KICAgIFVWZWN0b3IgbG9vcGluZ1N0YXRlczsKCiAgICAvKioKICAgICAqIExvb3Bpbmcgc3RhdGVzIGFjdHVhbGx5IGhhdmUgdG8gYmUgYmFja2ZpbGxlZCBsYXRlciBpbiB0aGUgcHJvY2VzcwogICAgICogdGhhbiBldmVyeXRoaW5nIGVsc2UuICBUaGlzIGlzIHdoZXJlIGEgdGhlIGxpc3Qgb2Ygc3RhdGVzIHRvIGJhY2tmaWxsCiAgICAgKiBpcyBhY2N1bXVsYXRlZC4gIFRoaXMgaXMgYWxzbyB1c2VkIHRvIGhhbmRsZSAuKj8KICAgICAqLwogICAgVVZlY3RvciBzdGF0ZXNUb0JhY2tmaWxsOwoKICAgIC8qKgogICAgICogQSBsaXN0IG1hcHBpbmcgcGFpcnMgb2Ygc3RhdGUgbnVtYmVycyBmb3Igc3RhdGVzIHRoYXQgYXJlIHRvIGJlIGNvbWJpbmVkCiAgICAgKiB0byB0aGUgc3RhdGUgbnVtYmVyIG9mIHRoZSBzdGF0ZSByZXByZXNlbnRpbmcgdGhlaXIgY29tYmluYXRpb24uICBVc2VkCiAgICAgKiBpbiB0aGUgcHJvY2VzcyBvZiBtYWtpbmcgdGhlIHN0YXRlIHRhYmxlIGRldGVybWluaXN0aWMgdG8gcHJldmVudAogICAgICogaW5maW5pdGUgcmVjdXJzaW9uLgogICAgICovCiAgICBVVmVjdG9yIG1lcmdlTGlzdDsKCiAgICAvKioKICAgICAqIEEgZmxhZyB0aGF0IGlzIHVzZWQgdG8gaW5kaWNhdGUgd2hlbiB0aGUgbGlzdCBvZiBsb29waW5nIHN0YXRlcyBjYW4KICAgICAqIGJlIHJlc2V0LgogICAgICovCiAgICBVQm9vbCBjbGVhckxvb3BpbmdTdGF0ZXM7CgogICAgLyoqCiAgICAgKiBBIHBsYWNlIHdoZXJlIGFuIGVycm9yIG1lc3NhZ2UgY2FuIGJlIHN0b3JlZCBpZiB3ZSBnZXQgYSBwYXJzZSBlcnJvci4KICAgICAqIFRoZSBlcnJvciBtZXNzYWdlIGlzIG5ldmVyIGRpc3BsYXllZCBhbnl3aGVyZSwgc28gdGhpcyBpcyB1c2VmdWwgcHJldHR5CiAgICAgKiBtdWNoIG9ubHkgaW4gY29uanVuY3Rpb24gd2l0aCBhIGRlYnVnZ2VyLgogICAgICovCiAgICBVbmljb2RlU3RyaW5nIGVycm9yTWVzc2FnZTsKCiAgICAvKioKICAgICAqIEEgYml0IG1hc2sgdXNlZCB0byBpbmRpY2F0ZSBhIGJpdCBpbiB0aGUgdGFibGUncyBmbGFncyBjb2x1bW4gdGhhdCBtYXJrcyBhCiAgICAgKiBzdGF0ZSBhcyBhbiBhY2NlcHRpbmcgc3RhdGUuCiAgICAgKi8KICAgIHN0YXRpYyBjb25zdCBpbnQzMl90IEVORF9TVEFURV9GTEFHIC8qPSAweDgwMDAqLzsKCiAgICAvKioKICAgICAqIEEgYml0IG1hc2sgdXNlZCB0byBpbmRpY2F0ZSBhIGJpdCBpbiB0aGUgdGFibGUncyBmbGFncyBjb2x1bW4gdGhhdCBtYXJrcyBhCiAgICAgKiBzdGF0ZSBhcyBvbmUgdGhlIGJ1aWxkZXIgc2hvdWxkbid0IGxvb3AgdG8gYW55IGxvb3Bpbmcgc3RhdGVzCiAgICAgKi8KICAgIHN0YXRpYyBjb25zdCBpbnQzMl90IERPTlRfTE9PUF9GTEFHIC8qPSAweDQwMDAqLzsKCiAgICAvKioKICAgICAqIEEgYml0IG1hc2sgdXNlZCB0byBpbmRpY2F0ZSBhIGJpdCBpbiB0aGUgdGFibGUncyBmbGFncyBjb2x1bW4gdGhhdCBtYXJrcyBhCiAgICAgKiBzdGF0ZSBhcyBhIGxvb2thaGVhZCBzdGF0ZS4KICAgICAqLwogICAgc3RhdGljIGNvbnN0IGludDMyX3QgTE9PS0FIRUFEX1NUQVRFX0ZMQUcgLyo9IDB4MjAwMCovOwoKICAgIC8qKgogICAgICogQSBiaXQgbWFzayByZXByZXNlbnRpbmcgdGhlIHVuaW9uIG9mIHRoZSBtYXNrIHZhbHVlcyBsaXN0ZWQgYWJvdmUuCiAgICAgKiBVc2VkIGZvciBjbGVhcmluZyBvciBtYXNraW5nIG9mZiB0aGUgZmxhZyBiaXRzLgogICAgICovCiAgICBzdGF0aWMgY29uc3QgaW50MzJfdCBBTExfRkxBR1MgLyo9IEVORF9TVEFURV9GTEFHIHwgTE9PS0FIRUFEX1NUQVRFX0ZMQUcKICAgICAgICAgICAgfCBET05UX0xPT1BfRkxBRyovOwoKcHVibGljOgoKICAgIC8qKgogICAgICogVGhlIEJ1aWxkZXIgY2xhc3MgY29udGFpbnMgYSByZWZlcmVuY2UgdG8gdGhlIGl0ZXJhdG9yIGl0J3Mgc3VwcG9zZWQgdG8gYnVpbGQuCiAgICAgKi8KICAgIFJ1bGVCYXNlZEJyZWFrSXRlcmF0b3JCdWlsZGVyKFJ1bGVCYXNlZEJyZWFrSXRlcmF0b3ImIGl0ZXJhdG9yVG9CdWlsZCk7CgogICAgLyoqCiAgICAgKiBEZXN0cnVjdG9yLgogICAgICovCiAgICB+UnVsZUJhc2VkQnJlYWtJdGVyYXRvckJ1aWxkZXIoKTsKCiAgICAvKioKICAgICAqIFRoaXMgaXMgdGhlIG1haW4gZnVuY3Rpb24gZm9yIHNldHRpbmcgdXAgdGhlIEJyZWFrSXRlcmF0b3IncyB0YWJsZXMuICBJdAogICAgICoganVzdCB2ZWN0b3JzIGRpZmZlcmVudCBwYXJ0cyBvZiB0aGUgam9iIG9mZiB0byBvdGhlciBmdW5jdGlvbnMuCiAgICAgKi8KICAgIHZpcnR1YWwgdm9pZCBidWlsZEJyZWFrSXRlcmF0b3IoY29uc3QgVW5pY29kZVN0cmluZyYgICAgZGVzY3JpcHRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIGVycik7Cgpwcml2YXRlOgoKICAgIC8qKgogICAgICogVGh1cyBmdW5jdGlvbiBoYXMgdGhyZWUgbWFpbiBwdXJwb3NlczoKICAgICAqIDx1bD48bGk+UGVyZm9ybSBnZW5lcmFsIHN5bnRheCBjaGVja2luZyBvbiB0aGUgZGVzY3JpcHRpb24sIHNvIHRoZSByZXN0IG9mIHRoZQogICAgICogYnVpbGQgY29kZSBjYW4gYXNzdW1lIHRoYXQgaXQncyBwYXJzaW5nIGEgbGVnYWwgZGVzY3JpcHRpb24uCiAgICAgKiA8bGk+U3BsaXQgdGhlIGRlc2NyaXB0aW9uIGludG8gc2VwYXJhdGUgcnVsZXMKICAgICAqIDxsaT5QZXJmb3JtIHZhcmlhYmxlLW5hbWUgc3Vic3RpdHV0aW9ucyAoc28gdGhhdCBubyBvbmUgZWxzZSBzZWVzIHZhcmlhYmxlIG5hbWVzKQogICAgICogPC91bD4KICAgICAqLwogICAgdmlydHVhbCB2b2lkIGJ1aWxkUnVsZUxpc3QoVW5pY29kZVN0cmluZyYgZGVzY3JpcHRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiBlcnIpOwoKcHJvdGVjdGVkOgoKICAgIC8qKgogICAgICogVGhpcyBmdW5jdGlvbiBwZXJmb3JtcyB2YXJpYWJsZS1uYW1lIHN1YnN0aXR1dGlvbnMuICBGaXJzdCBpdCBkb2VzIHN5bnRheAogICAgICogY2hlY2tpbmcgb24gdGhlIHZhcmlhYmxlLW5hbWUgZGVmaW5pdGlvbi4gIElmIGl0J3Mgc3ludGFjdGljYWxseSB2YWxpZCwgaXQKICAgICAqIHRoZW4gZ29lcyB0aHJvdWdoIHRoZSByZW1haW5kZXIgb2YgdGhlIGRlc2NyaXB0aW9uIGFuZCBkb2VzIGEgc2ltcGxlCiAgICAgKiBmaW5kLWFuZC1yZXBsYWNlIG9mIHRoZSB2YXJpYWJsZSBuYW1lIHdpdGggaXRzIHRleHQuICAoVGhlIHZhcmlhYmxlIHRleHQKICAgICAqIG11c3QgYmUgZW5jbG9zZWQgaW4gZWl0aGVyIFtdIG9yICgpIGZvciB0aGlzIHRvIHdvcmsuKQogICAgICovCiAgICB2aXJ0dWFsIHZvaWQgcHJvY2Vzc1N1YnN0aXR1dGlvbihVbmljb2RlU3RyaW5nJiBkZXNjcmlwdGlvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVUZXh0T2Zmc2V0IHJ1bGVTdGFydCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVUZXh0T2Zmc2V0IHJ1bGVFbmQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVVGV4dE9mZnNldCBzdGFydFBvcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIGVycik7CgogICAgLyoqCiAgICAgKiBUaGlzIGZ1bmN0aW9uIGRlZmluZXMgYSBwcm90b2NvbCBmb3IgaGFuZGxpbmcgc3Vic3RpdHV0aW9uIG5hbWVzIHRoYXQKICAgICAqIGFyZSAic3BlY2lhbCwiIGkuZS4sIHRoYXQgaGF2ZSBzb21lIHByb3BlcnR5IGJleW9uZCBqdXN0IGJlaW5nCiAgICAgKiBzdWJzdGl0dXRpb25zLiAgQXQgdGhlIFJ1bGVCYXNlZEJyZWFrSXRlcmF0b3IgbGV2ZWwsIHdlIGhhdmUgb25lCiAgICAgKiBzcGVjaWFsIHN1YnN0aXR1dGlvbiBuYW1lLCAiPGlnbm9yZT4iLiAgU3ViY2xhc3NlcyBjYW4gb3ZlcnJpZGUgdGhpcwogICAgICogZnVuY3Rpb24gdG8gYWRkIG1vcmUuICBBbnkgc3BlY2lhbCBwcm9jZXNzaW5nIHRoYXQgaGFzIHRvIGdvIG9uIGJleW9uZAogICAgICogdGhhdCB3aGljaCBpcyBkb25lIGJ5IHRoZSBub3JtYWwgc3Vic3RpdHV0aW9uLXByb2Nlc3NpbmcgY29kZSBpcyBkb25lCiAgICAgKiBoZXJlLgogICAgICovCiAgICB2aXJ0dWFsIHZvaWQgaGFuZGxlU3BlY2lhbFN1YnN0aXR1dGlvbihjb25zdCBVbmljb2RlU3RyaW5nJiByZXBsYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVW5pY29kZVN0cmluZyYgcmVwbGFjZVdpdGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQzMl90IHN0YXJ0UG9zLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVW5pY29kZVN0cmluZyYgZGVzY3JpcHRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiBlcnIpOwoKICAgIC8qKgogICAgICogVGhpcyBmdW5jdGlvbiBwcm92aWRlcyBhIGhvb2sgZm9yIHN1YmNsYXNzZXMgdG8gbWVzcyB3aXRoIHRoZSBjaGFyYWN0ZXIKICAgICAqIGNhdGVnb3J5IHRhYmxlLgogICAgICovCiAgICB2aXJ0dWFsIHZvaWQgbXVuZ2VFeHByZXNzaW9uTGlzdCgpOwoKICAgIC8qKgogICAgICogVGhpcyBmdW5jdGlvbiBidWlsZHMgdGhlIGNoYXJhY3RlciBjYXRlZ29yeSB0YWJsZS4gIE9uIGVudHJ5LAogICAgICogdGVtcFJ1bGVMaXN0IGlzIGEgVVZlY3RvciBvZiBicmVhayBydWxlcyB0aGF0IGhhcyBoYWQgdmFyaWFibGUgbmFtZXMgc3Vic3RpdHV0ZWQuCiAgICAgKiBPbiBleGl0LCB0aGUgY2hhckNhdGVnb3J5VGFibGUgZGF0YSBtZW1iZXIgaGFzIGJlZW4gaW5pdGlhbGl6ZWQgdG8gaG9sZCB0aGUKICAgICAqIGNoYXJhY3RlciBjYXRlZ29yeSB0YWJsZSwgYW5kIHRlbXBSdWxlTGlzdCdzIHJ1bGVzIGhhdmUgYmVlbiBtdW5nZWQgdG8gY29udGFpbgogICAgICogY2hhcmFjdGVyIGNhdGVnb3J5IG51bWJlcnMgZXZlcnl3aGVyZSBhIGxpdGVyYWwgY2hhcmFjdGVyIG9yIGEgW10gZXhwcmVzc2lvbgogICAgICogb3JpZ2luYWxseSBvY2N1cnJlZC4KICAgICAqLwogICAgdmlydHVhbCB2b2lkIGJ1aWxkQ2hhckNhdGVnb3JpZXMoVUVycm9yQ29kZSYgZXJyKTsKCnByaXZhdGU6CgogICAgLyoqCiAgICAgKiBUaGlzIGlzIHRoZSBmdW5jdGlvbiB0aGF0IGJ1aWxkcyB0aGUgZm9yd2FyZCBzdGF0ZSB0YWJsZS4gIE1vc3Qgb2YgdGhlIHJlYWwKICAgICAqIHdvcmsgaXMgZG9uZSBpbiBwYXJzZVJ1bGUoKSwgd2hpY2ggaXMgY2FsbGVkIG9uY2UgZm9yIGVhY2ggcnVsZSBpbiB0aGUKICAgICAqIGRlc2NyaXB0aW9uLgogICAgICovCiAgICB2aXJ0dWFsIHZvaWQgYnVpbGRTdGF0ZVRhYmxlKFVFcnJvckNvZGUmIGVycik7CgogICAgLyoqCiAgICAgKiBUaGlzIGlzIHdoZXJlIG1vc3Qgb2YgdGhlIHdvcmsgcmVhbGx5IGhhcHBlbnMuICBUaGlzIHJvdXRpbmUgcGFyc2VzIGEgc2luZ2xlCiAgICAgKiBydWxlIGluIHRoZSBydWxlIGRlc2NyaXB0aW9uLCBhZGRpbmcgYW5kIG1vZGlmeWluZyBzdGF0ZXMgaW4gdGhlIHN0YXRlCiAgICAgKiB0YWJsZSBhY2NvcmRpbmcgdG8gdGhlIG5ldyBleHByZXNzaW9uLiAgVGhlIHN0YXRlIHRhYmxlIGlzIGtlcHQgZGV0ZXJtaW5pc3RpYwogICAgICogdGhyb3VnaG91dCB0aGUgd2hvbGUgb3BlcmF0aW9uLCBhbHRob3VnaCBzb21lIHVnbHkgcG9zdHByb2Nlc3NpbmcgaXMgbmVlZGVkCiAgICAgKiB0byBoYW5kbGUgdGhlICo/IHRva2VuLgogICAgICovCiAgICB2aXJ0dWFsIHZvaWQgcGFyc2VSdWxlKGNvbnN0IFVuaWNvZGVTdHJpbmcmIHJ1bGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFVCb29sICAgICAgICAgICAgICAgZm9yd2FyZCk7CgogICAgLyoqCiAgICAgKiBVcGRhdGUgZW50cmllcyBpbiB0aGUgc3RhdGUgdGFibGUsIGFuZCBtZXJnZSBzdGF0ZXMgd2hlbiBuZWNlc3NhcnkgdG8ga2VlcAogICAgICogdGhlIHRhYmxlIGRldGVybWluaXN0aWMuCiAgICAgKiBAcGFyYW0gcm93cyBUaGUgbGlzdCBvZiByb3dzIHRoYXQgbmVlZCB1cGRhdGluZyAodGhlIGRlY2lzaW9uIHBvaW50IGxpc3QpCiAgICAgKiBAcGFyYW0gcGVuZGluZ0NoYXJzIEEgY2hhcmFjdGVyIGNhdGVnb3J5IGxpc3QsIGVuY29kZWQgaW4gYSBTdHJpbmcuICBUaGlzIGlzIHRoZQogICAgICogbGlzdCBvZiB0aGUgY29sdW1ucyB0aGF0IG5lZWQgdXBkYXRpbmcuCiAgICAgKiBAcGFyYW0gbmV3VmFsdWUgVXBkYXRlIHRoZSBjZWxscyBzcGVjZmllZCBhYm92ZSB0byBjb250YWluIHRoaXMgdmFsdWUKICAgICAqLwogICAgdmlydHVhbCB2b2lkIHVwZGF0ZVN0YXRlVGFibGUoY29uc3QgVVZlY3RvciYgICAgICAgcm93cywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFVuaWNvZGVTdHJpbmcmIHBlbmRpbmdDaGFycywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludDE2X3QgICAgICAgICAgICAgIG5ld1ZhbHVlKTsKCiAgICAvKioKICAgICAqIFRoZSByZWFsIHdvcmsgb2YgbWFraW5nIHRoZSBzdGF0ZSB0YWJsZSBkZXRlcm1pbmlzdGljIGhhcHBlbnMgaGVyZS4gIFRoaXMgZnVuY3Rpb24KICAgICAqIG1lcmdlcyBhIHN0YXRlIGluIHRoZSBzdGF0ZSB0YWJsZSAoc3BlY2lmaWVkIGJ5IHJvd051bSkgd2l0aCBhIHN0YXRlIHRoYXQgaXMKICAgICAqIHBhc3NlZCBpbiAobmV3VmFsdWVzKS4gIFRoZSBiYXNpYyBwcm9jZXNzIGlzIHRvIGNvcHkgdGhlIG5vbnplcm8gY2VsbHMgaW4gbmV3U3RhdGVzCiAgICAgKiBpbnRvIHRoZSBzdGF0ZSBpbiB0aGUgc3RhdGUgdGFibGUgKHdlJ2xsIGNhbGwgdGhhdCBvbGRWYWx1ZXMpLiAgSWYgdGhlcmUncyBhCiAgICAgKiBjb2xsaXNpb24gKGkuZS4sIGlmIHRoZSBzYW1lIGNlbGwgaGFzIGEgbm9uemVybyB2YWx1ZSBpbiBib3RoIHN0YXRlcywgYW5kIGl0J3MKICAgICAqIG5vdCB0aGUgU0FNRSB2YWx1ZSksIHRoZW4gd2UgaGF2ZSB0byByZWNvbmNpbGUgdGhlIGNvbGxpc2lvbi4gIFdlIGRvIHRoaXMgYnkKICAgICAqIGNyZWF0aW5nIGEgbmV3IHN0YXRlLCBhZGRpbmcgaXQgdG8gdGhlIGVuZCBvZiB0aGUgc3RhdGUgdGFibGUsIGFuZCB1c2luZyB0aGlzCiAgICAgKiBmdW5jdGlvbiByZWN1cnNpdmVseSB0byBtZXJnZSB0aGUgb3JpZ2luYWwgdHdvIHN0YXRlcyBpbnRvIGEgc2luZ2xlLCBjb21iaW5lZAogICAgICogc3RhdGUuICBUaGlzIHByb2Nlc3MgbWF5IGhhcHBlbiByZWN1cnNpdmVseSAoaS5lLiwgZWFjaCBzdWNjZXNzaXZlIGxldmVsIG1heQogICAgICogaW52b2x2ZSBjb2xsaXNpb25zKS4gIFRvIHByZXZlbnQgaW5maW5pdGUgcmVjdXJzaW9uLCB3ZSBrZWVwIGEgbG9nIG9mIG1lcmdlCiAgICAgKiBvcGVyYXRpb25zLiAgQW55IHRpbWUgd2UncmUgbWVyZ2luZyB0d28gc3RhdGVzIHdlJ3ZlIG1lcmdlZCBiZWZvcmUsIHdlIGNhbiBqdXN0CiAgICAgKiBzdXBwbHkgdGhlIHJvdyBudW1iZXIgZm9yIHRoZSByZXN1bHQgb2YgdGhhdCBtZXJnZSBvcGVyYXRpb24gcmF0aGVyIHRoYW4gY3JlYXRpbmcKICAgICAqIGEgbmV3IHN0YXRlIGp1c3QgbGlrZSBpdC4KICAgICAqIEBwYXJhbSByb3dOdW0gVGhlIHJvdyBudW1iZXIgaW4gdGhlIHN0YXRlIHRhYmxlIG9mIHRoZSBzdGF0ZSB0byBiZSB1cGRhdGVkCiAgICAgKiBAcGFyYW0gbmV3VmFsdWVzIFRoZSBzdGF0ZSB0byBtZXJnZSBpdCB3aXRoLgogICAgICogQHBhcmFtIHJvd3NCZWluZ1VwZGF0ZWQgQSBjb3B5IG9mIHRoZSBsaXN0IG9mIHJvd3MgcGFzc2VkIHRvIHVwZGF0ZVN0YXRlVGFibGUoKQogICAgICogKGl0c2VsZiBhIGNvcHkgb2YgdGhlIGRlY2lzaW9uIHBvaW50IGxpc3QgZnJvbSBwYXJzZVJ1bGUoKSkuICBOZXdseS1jcmVhdGVkCiAgICAgKiBzdGF0ZXMgZ2V0IGFkZGVkIHRvIHRoZSBkZWNpc2lvbiBwb2ludCBsaXN0IGlmIHRoZWlyICJwYXJlbnRzIiB3ZXJlIG9uIGl0LgogICAgICovCiAgICB2aXJ0dWFsIHZvaWQgbWVyZ2VTdGF0ZXMoaW50MzJfdCAgcm93TnVtLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludDE2X3QqIG5ld1ZhbHVlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBVVmVjdG9yJiByb3dzQmVpbmdVcGRhdGVkKTsKCiAgICAvKioKICAgICAqIFRoZSBtZXJnZSBsaXN0IGlzIGEgbGlzdCBvZiBwYWlycyBvZiByb3dzIHRoYXQgaGF2ZSBiZWVuIG1lcmdlZCBzb21ld2hlcmUgaW4KICAgICAqIHRoZSBwcm9jZXNzIG9mIGJ1aWxkaW5nIHRoaXMgc3RhdGUgdGFibGUsIGFsb25nIHdpdGggdGhlIHJvdyBudW1iZXIgb2YgdGhlCiAgICAgKiByb3cgY29udGFpbmluZyB0aGUgbWVyZ2VkIHN0YXRlLiAgVGhpcyBmdW5jdGlvbiBsb29rcyB1cCBhIHBhaXIgb2Ygcm93IG51bWJlcnMKICAgICAqIGFuZCByZXR1cm5zIHRoZSByb3cgbnVtYmVyIG9mIHRoZSByb3cgdGhleSBjb21iaW5lIGludG8uICAoSXQgcmV0dXJucyAwIGlmCiAgICAgKiB0aGlzIHBhaXIgb2Ygcm93cyBpc24ndCBpbiB0aGUgbWVyZ2UgbGlzdC4pCiAgICAgKi8KICAgIHZpcnR1YWwgaW50MzJfdCBzZWFyY2hNZXJnZUxpc3QoaW50MzJfdCBhLCBpbnQzMl90IGIpOwoKICAgIC8qKgogICAgICogVGhpcyBmdW5jdGlvbiBpcyB1c2VkIHRvIHVwZGF0ZSB0aGUgbGlzdCBvZiBjdXJyZW50IGxvb29waW5nIHN0YXRlcyAoaS5lLiwKICAgICAqIHN0YXRlcyB0aGF0IGFyZSBjb250cm9sbGVkIGJ5IGEgKj8gY29uc3RydWN0KS4gIEl0IGJhY2tmaWxscyB2YWx1ZXMgZnJvbQogICAgICogdGhlIGxvb3Bpbmcgc3RhdGVzIGludG8gdW5wb3B1bGF0ZWQgY2VsbHMgb2YgdGhlIHN0YXRlcyB0aGF0IGFyZSBjdXJyZW50bHkKICAgICAqIG1hcmtlZCBmb3IgYmFja2ZpbGxpbmcsIGFuZCB0aGVuIHVwZGF0ZXMgdGhlIGxpc3Qgb2YgbG9vcGluZyBzdGF0ZXMgdG8gYmUKICAgICAqIHRoZSBuZXcgbGlzdAogICAgICogQHBhcmFtIG5ld0xvb3BpbmdTdGF0ZXMgVGhlIGxpc3Qgb2YgbmV3IGxvb3Bpbmcgc3RhdGVzCiAgICAgKiBAcGFyYW0gZW5kU3RhdGVzIFRoZSBsaXN0IG9mIHN0YXRlcyB0byB0cmVhdCBhcyBlbmQgc3RhdGVzIChzdGF0ZXMgdGhhdAogICAgICogY2FuIGV4aXQgdGhlIGxvb3ApLgogICAgICovCiAgICB2aXJ0dWFsIHZvaWQgc2V0TG9vcGluZ1N0YXRlcyhjb25zdCBVVmVjdG9yKiBuZXdMb29waW5nU3RhdGVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVVZlY3RvciYgZW5kU3RhdGVzKTsKCiAgICAvKioKICAgICAqIFRoaXMgcmVtb3ZlcyAiZW5kaW5nIHN0YXRlcyIgYW5kIHN0YXRlcyByZWFjaGFibGUgZnJvbSB0aGVtIGZyb20gdGhlCiAgICAgKiBsaXN0IG9mIHN0YXRlcyB0byBiYWNrZmlsbC4KICAgICAqIEBwYXJhbSBUaGUgcm93IG51bWJlciBvZiB0aGUgc3RhdGUgdG8gcmVtb3ZlIGZyb20gdGhlIGJhY2tmaWxsIGxpc3QKICAgICAqLwogICAgdmlydHVhbCB2b2lkIGVsaW1pbmF0ZUJhY2tmaWxsU3RhdGVzKGludDMyX3QgYmFzZVN0YXRlKTsKCiAgICAvKioKICAgICAqIFRoaXMgZnVuY3Rpb24gY29tcGxldGVzIHRoZSBiYWNrZmlsbGluZyBwcm9jZXNzIGJ5IGFjdHVhbGx5IGRvaW5nIHRoZQogICAgICogYmFja2ZpbGxpbmcgb24gdGhlIHN0YXRlcyB0aGF0IGFyZSBtYXJrZWQgZm9yIGl0CiAgICAgKi8KICAgIHZpcnR1YWwgdm9pZCBiYWNrZmlsbExvb3BpbmdTdGF0ZXModm9pZCk7CgogICAgLyoqCiAgICAgKiBUaGlzIGZ1bmN0aW9uIGNvbXBsZXRlcyB0aGUgc3RhdGUtdGFibGUtYnVpbGRpbmcgcHJvY2VzcyBieSBkb2luZyBzZXZlcmFsCiAgICAgKiBwb3N0cHJvY2Vzc2luZyBzdGVwcyBhbmQgY29weWluZyBldmVyeXRoaW5nIGludG8gaXRzIGZpbmFsIHJlc3RpbmcgcGxhY2UKICAgICAqIGluIHRoZSBpdGVyYXRvciBpdHNlbGYKICAgICAqIEBwYXJhbSBmb3J3YXJkIFRydWUgaWYgd2UncmUgd29ya2luZyBvbiB0aGUgZm9yd2FyZCBzdGF0ZSB0YWJsZQogICAgICovCiAgICB2aXJ0dWFsIHZvaWQgZmluaXNoQnVpbGRpbmdTdGF0ZVRhYmxlKFVCb29sIGZvcndhcmQpOwoKICAgIC8qKgogICAgICogVGhpcyBmdW5jdGlvbiBidWlsZHMgdGhlIGJhY2t3YXJkIHN0YXRlIHRhYmxlIGZyb20gdGhlIGZvcndhcmQgc3RhdGUKICAgICAqIHRhYmxlIGFuZCBhbnkgYWRkaXRpb25hbCBydWxlcyAoaWRlbnRpZmllZCBieSB0aGUgISBvbiB0aGUgZnJvbnQpCiAgICAgKiBzdXBwbGllZCBpbiB0aGUgZGVzY3JpcHRpb24KICAgICAqLwogICAgdmlydHVhbCB2b2lkIGJ1aWxkQmFja3dhcmRzU3RhdGVUYWJsZShVRXJyb3JDb2RlJiBlcnIpOwoKcHJvdGVjdGVkOgoKICAgIC8qKgogICAgICogVGhyb3dzIGFuIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiByZXByZXNlbnRpbmcgYSBzeW50YXggZXJyb3IgaW4gdGhlIHJ1bGUKICAgICAqIGRlc2NyaXB0aW9uLiAgVGhlIGV4Y2VwdGlvbidzIG1lc3NhZ2UgY29udGFpbnMgc29tZSBkZWJ1Z2dpbmcgaW5mb3JtYXRpb24uCiAgICAgKiBAcGFyYW0gbWVzc2FnZSBBIG1lc3NhZ2UgZGVzY3JpYmluZyB0aGUgcHJvYmxlbQogICAgICogQHBhcmFtIHBvc2l0aW9uIFRoZSBwb3NpdGlvbiBpbiB0aGUgZGVzY3JpcHRpb24gd2hlcmUgdGhlIHByb2JsZW0gd2FzCiAgICAgKiBkaXNjb3ZlcmVkCiAgICAgKiBAcGFyYW0gY29udGV4dCBUaGUgc3RyaW5nIGNvbnRhaW5pbmcgdGhlIGVycm9yCiAgICAgKi8KICAgIHZpcnR1YWwgdm9pZCBzZXRVcEVycm9yTWVzc2FnZShjb25zdCBVbmljb2RlU3RyaW5nJiBtZXNzYWdlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludDMyX3QgcG9zaXRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVW5pY29kZVN0cmluZyYgY29udGV4dCk7Cn07CgojZW5kaWYK