LyoKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqIENvcHlyaWdodCCpIHsxOTk5fSwgSW50ZXJuYXRpb25hbCBCdXNpbmVzcyBNYWNoaW5lcyBDb3Jwb3JhdGlvbiBhbmQgb3RoZXJzLiBBbGwgUmlnaHRzIFJlc2VydmVkLgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiogICBEYXRlICAgICAgICBOYW1lICAgICAgICBEZXNjcmlwdGlvbgoqICAgMTAvMjAvOTkgICAgYWxhbiAgICAgICAgQ3JlYXRpb24uCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKi8KCiNpZm5kZWYgVU5JQ09ERVNFVF9ICiNkZWZpbmUgVU5JQ09ERVNFVF9ICgojaW5jbHVkZSAidW5pY29kZS91bmlmaWx0LmgiCiNpbmNsdWRlICJ1bmljb2RlL3V0eXBlcy5oIgojaW5jbHVkZSAidW5pY29kZS91bmlzdHIuaCIKCmNsYXNzIFBhcnNlUG9zaXRpb247CmNsYXNzIFN5bWJvbFRhYmxlOwpjbGFzcyBUcmFuc2xpdGVyYXRpb25SdWxlUGFyc2VyOwpjbGFzcyBUcmFuc2xpdGVyYXRpb25SdWxlOwoKLyoqCiAqIEEgbXV0YWJsZSBzZXQgb2YgVW5pY29kZSBjaGFyYWN0ZXJzLiAgT2JqZWN0cyBvZiB0aGlzIGNsYXNzCiAqIHJlcHJlc2VudCA8ZW0+Y2hhcmFjdGVyIGNsYXNzZXM8L2VtPiB1c2VkIGluIHJlZ3VsYXIgZXhwcmVzc2lvbnMuCiAqIFN1Y2ggY2xhc3NlcyBzcGVjaWZ5IGEgc3Vic2V0IG9mIHRoZSBzZXQgb2YgYWxsIFVuaWNvZGUgY2hhcmFjdGVycywKICogd2hpY2ggaW4gdGhpcyBpbXBsZW1lbnRhdGlvbiBpcyB0aGUgY2hhcmFjdGVycyBmcm9tIFUrMDAwMCB0bwogKiBVK0ZGRkYsIGlnbm9yaW5nIHN1cnJvZ2F0ZXMuCiAqCiAqIDxwPlRoaXMgY2xhc3Mgc3VwcG9ydHMgdHdvIEFQSXMuICBUaGUgZmlyc3QgaXMgbW9kZWxlZCBhZnRlciBKYXZhIDIncwogKiA8Y29kZT5qYXZhLnV0aWwuU2V0PC9jb2RlPiBpbnRlcmZhY2UsIGFsdGhvdWdoIHRoaXMgY2xhc3MgZG9lcyBub3QKICogaW1wbGVtZW50IHRoYXQgaW50ZXJmYWNlLiAgQWxsIG1ldGhvZHMgb2YgPGNvZGU+U2V0PC9jb2RlPiBhcmUKICogc3VwcG9ydGVkLCB3aXRoIHRoZSBtb2RpZmljYXRpb24gdGhhdCB0aGV5IHRha2UgYSBjaGFyYWN0ZXIgcmFuZ2UKICogb3Igc2luZ2xlIGNoYXJhY3RlciBpbnN0ZWFkIG9mIGFuIDxjb2RlPk9iamVjdDwvY29kZT4sIGFuZCB0aGV5CiAqIHRha2UgYSA8Y29kZT5Vbmljb2RlU2V0PC9jb2RlPiBpbnN0ZWFkIG9mIGEgPGNvZGU+Q29sbGVjdGlvbjwvY29kZT4uCiAqCiAqIDxwPlRoZSBzZWNvbmQgQVBJIGlzIHRoZQogKiA8Y29kZT5hcHBseVBhdHRlcm4oKTwvY29kZT4vPGNvZGU+dG9QYXR0ZXJuKCk8L2NvZGU+IEFQSSBmcm9tIHRoZQogKiA8Y29kZT5Gb3JtYXQ8L2NvZGU+LWRlcml2ZWQgY2xhc3Nlcy4gIFVubGlrZSB0aGUKICogbWV0aG9kcyB0aGF0IGFkZCBjaGFyYWN0ZXJzLCBhZGQgY2F0ZWdvcmllcywgYW5kIGNvbnRyb2wgdGhlIGxvZ2ljCiAqIG9mIHRoZSBzZXQsIHRoZSBtZXRob2QgPGNvZGU+YXBwbHlQYXR0ZXJuKCk8L2NvZGU+IHNldHMgYWxsCiAqIGF0dHJpYnV0ZXMgb2YgYSA8Y29kZT5Vbmljb2RlU2V0PC9jb2RlPiBhdCBvbmNlLCBiYXNlZCBvbiBhCiAqIHN0cmluZyBwYXR0ZXJuLgogKgogKiA8cD5JbiBhZGRpdGlvbiwgdGhlIHNldCBjb21wbGVtZW50IG9wZXJhdGlvbiBpcyBzdXBwb3J0ZWQgdGhyb3VnaAogKiB0aGUgPGNvZGU+Y29tcGxlbWVudCgpPC9jb2RlPiBtZXRob2QuCiAqCiAqIDxwPjxiPlBhdHRlcm4gc3ludGF4PC9iPjwvcD4KICoKICogUGF0dGVybnMgYXJlIGFjY2VwdGVkIGJ5IHRoZSBjb25zdHJ1Y3RvcnMgYW5kIHRoZQogKiA8Y29kZT5hcHBseVBhdHRlcm4oKTwvY29kZT4gbWV0aG9kcyBhbmQgcmV0dXJuZWQgYnkgdGhlCiAqIDxjb2RlPnRvUGF0dGVybigpPC9jb2RlPiBtZXRob2QuICBUaGVzZSBwYXR0ZXJucyBmb2xsb3cgYSBzeW50YXgKICogc2ltaWxhciB0byB0aGF0IGVtcGxveWVkIGJ5IHZlcnNpb24gOCByZWd1bGFyIGV4cHJlc3Npb24gY2hhcmFjdGVyCiAqIGNsYXNzZXM6CiAqCiAqIDxibG9ja3F1b3RlPgogKiAgIDx0YWJsZT4KICogICAgIDx0ciBhbGlnbj0idG9wIj4KICogICAgICAgPHRkIG5vd3JhcCB2YWxpZ249InRvcCIgYWxpZ249InJpZ2h0Ij48Y29kZT5wYXR0ZXJuIDo9Jm5ic3A7IDwvY29kZT48L3RkPgogKiAgICAgICA8dGQgdmFsaWduPSJ0b3AiPjxjb2RlPignWycgJ14nPyBpdGVtKiAnXScpIHwKICogICAgICAgKCdbOicgJ14nPyBjYXRlZ29yeSAnOl0nKTwvY29kZT48L3RkPgogKiAgICAgPC90cj4KICogICAgIDx0ciBhbGlnbj0idG9wIj4KICogICAgICAgPHRkIG5vd3JhcCB2YWxpZ249InRvcCIgYWxpZ249InJpZ2h0Ij48Y29kZT5pdGVtIDo9Jm5ic3A7IDwvY29kZT48L3RkPgogKiAgICAgICA8dGQgdmFsaWduPSJ0b3AiPjxjb2RlPmNoYXIgfCAoY2hhciAnLScgY2hhcikgfCBwYXR0ZXJuLWV4cHI8YnI+CiAqICAgICAgIDwvY29kZT48L3RkPgogKiAgICAgPC90cj4KICogICAgIDx0ciBhbGlnbj0idG9wIj4KICogICAgICAgPHRkIG5vd3JhcCB2YWxpZ249InRvcCIgYWxpZ249InJpZ2h0Ij48Y29kZT5wYXR0ZXJuLWV4cHIgOj0mbmJzcDsgPC9jb2RlPjwvdGQ+CiAqICAgICAgIDx0ZCB2YWxpZ249InRvcCI+PGNvZGU+cGF0dGVybiB8IHBhdHRlcm4tZXhwciBwYXR0ZXJuIHwKICogICAgICAgcGF0dGVybi1leHByIG9wIHBhdHRlcm48YnI+CiAqICAgICAgIDwvY29kZT48L3RkPgogKiAgICAgPC90cj4KICogICAgIDx0ciBhbGlnbj0idG9wIj4KICogICAgICAgPHRkIG5vd3JhcCB2YWxpZ249InRvcCIgYWxpZ249InJpZ2h0Ij48Y29kZT5vcCA6PSZuYnNwOyA8L2NvZGU+PC90ZD4KICogICAgICAgPHRkIHZhbGlnbj0idG9wIj48Y29kZT4nJmFtcDsnIHwgJy0nPGJyPgogKiAgICAgICA8L2NvZGU+PC90ZD4KICogICAgIDwvdHI+CiAqICAgICA8dHIgYWxpZ249InRvcCI+CiAqICAgICAgIDx0ZCBub3dyYXAgdmFsaWduPSJ0b3AiIGFsaWduPSJyaWdodCI+PGNvZGU+c3BlY2lhbCA6PSZuYnNwOyA8L2NvZGU+PC90ZD4KICogICAgICAgPHRkIHZhbGlnbj0idG9wIj48Y29kZT4nWycgfCAnXScgfCAnLSc8YnI+CiAqICAgICAgIDwvY29kZT48L3RkPgogKiAgICAgPC90cj4KICogICAgIDx0ciBhbGlnbj0idG9wIj4KICogICAgICAgPHRkIG5vd3JhcCB2YWxpZ249InRvcCIgYWxpZ249InJpZ2h0Ij48Y29kZT5jaGFyIDo9Jm5ic3A7IDwvY29kZT48L3RkPgogKiAgICAgICA8dGQgdmFsaWduPSJ0b3AiPjxlbT5hbnkgY2hhcmFjdGVyIHRoYXQgaXMgbm90PC9lbT48Y29kZT4gc3BlY2lhbDxicj4KICogICAgICAgfCAoJ1x1MDA1QycgPC9jb2RlPjxlbT5hbnkgY2hhcmFjdGVyPC9lbT48Y29kZT4pPGJyPgogKiAgICAgICB8ICgnXHUwMDVDdScgaGV4IGhleCBoZXggaGV4KTxicj4KICogICAgICAgPC9jb2RlPjwvdGQ+CiAqICAgICA8L3RyPgogKiAgICAgPHRyIGFsaWduPSJ0b3AiPgogKiAgICAgICA8dGQgbm93cmFwIHZhbGlnbj0idG9wIiBhbGlnbj0icmlnaHQiPjxjb2RlPmhleCA6PSZuYnNwOyA8L2NvZGU+PC90ZD4KICogICAgICAgPHRkIHZhbGlnbj0idG9wIj48ZW0+YW55IGNoYXJhY3RlciBmb3Igd2hpY2gKICogICAgICAgPC9lbT48Y29kZT5DaGFyYWN0ZXIuZGlnaXQoYywgMTYpPC9jb2RlPjxlbT4KICogICAgICAgcmV0dXJucyBhIG5vbi1uZWdhdGl2ZSByZXN1bHQ8L2VtPjwvdGQ+CiAqICAgICA8L3RyPgogKiAgICAgPHRyPgogKiAgICAgICA8dGQgbm93cmFwIHZhbGlnbj0idG9wIiBhbGlnbj0icmlnaHQiPjxjb2RlPmNhdGVnb3J5IDo9Jm5ic3A7IDwvY29kZT48L3RkPgogKiAgICAgICA8dGQgdmFsaWduPSJ0b3AiPjxjb2RlPidNJyB8ICdOJyB8ICdaJyB8ICdDJyB8ICdMJyB8ICdQJyB8CiAqICAgICAgICdTJyB8ICdNbicgfCAnTWMnIHwgJ01lJyB8ICdOZCcgfCAnTmwnIHwgJ05vJyB8ICdacycgfCAnWmwnIHwKICogICAgICAgJ1pwJyB8ICdDYycgfCAnQ2YnIHwgJ0NzJyB8ICdDbycgfCAnQ24nIHwgJ0x1JyB8ICdMbCcgfCAnTHQnCiAqICAgICAgIHwgJ0xtJyB8ICdMbycgfCAnUGMnIHwgJ1BkJyB8ICdQcycgfCAnUGUnIHwgJ1BvJyB8ICdTbScgfAogKiAgICAgICAnU2MnIHwgJ1NrJyB8ICdTbyc8L2NvZGU+PC90ZD4KICogICAgIDwvdHI+CiAqICAgPC90YWJsZT4KICogICA8YnI+CiAqICAgPHRhYmxlIGJvcmRlcj0iMSI+CiAqICAgICA8dHI+CiAqICAgICAgIDx0ZD5MZWdlbmQ6IDx0YWJsZT4KICogICAgICAgICA8dHI+CiAqICAgICAgICAgICA8dGQgbm93cmFwIHZhbGlnbj0idG9wIj48Y29kZT5hIDo9IGI8L2NvZGU+PC90ZD4KICogICAgICAgICAgIDx0ZCB3aWR0aD0iMjAiIHZhbGlnbj0idG9wIj4mbmJzcDsgPC90ZD4KICogICAgICAgICAgIDx0ZCB2YWxpZ249InRvcCI+PGNvZGU+YTwvY29kZT4gbWF5IGJlIHJlcGxhY2VkIGJ5IDxjb2RlPmI8L2NvZGU+IDwvdGQ+CiAqICAgICAgICAgPC90cj4KICogICAgICAgICA8dHI+CiAqICAgICAgICAgICA8dGQgbm93cmFwIHZhbGlnbj0idG9wIj48Y29kZT5hPzwvY29kZT48L3RkPgogKiAgICAgICAgICAgPHRkIHZhbGlnbj0idG9wIj48L3RkPgogKiAgICAgICAgICAgPHRkIHZhbGlnbj0idG9wIj56ZXJvIG9yIG9uZSBpbnN0YW5jZSBvZiA8Y29kZT5hPC9jb2RlPjxicj4KICogICAgICAgICAgIDwvdGQ+CiAqICAgICAgICAgPC90cj4KICogICAgICAgICA8dHI+CiAqICAgICAgICAgICA8dGQgbm93cmFwIHZhbGlnbj0idG9wIj48Y29kZT5hKjwvY29kZT48L3RkPgogKiAgICAgICAgICAgPHRkIHZhbGlnbj0idG9wIj48L3RkPgogKiAgICAgICAgICAgPHRkIHZhbGlnbj0idG9wIj5vbmUgb3IgbW9yZSBpbnN0YW5jZXMgb2YgPGNvZGU+YTwvY29kZT48YnI+CiAqICAgICAgICAgICA8L3RkPgogKiAgICAgICAgIDwvdHI+CiAqICAgICAgICAgPHRyPgogKiAgICAgICAgICAgPHRkIG5vd3JhcCB2YWxpZ249InRvcCI+PGNvZGU+YSB8IGI8L2NvZGU+PC90ZD4KICogICAgICAgICAgIDx0ZCB2YWxpZ249InRvcCI+PC90ZD4KICogICAgICAgICAgIDx0ZCB2YWxpZ249InRvcCI+ZWl0aGVyIDxjb2RlPmE8L2NvZGU+IG9yIDxjb2RlPmI8L2NvZGU+PGJyPgogKiAgICAgICAgICAgPC90ZD4KICogICAgICAgICA8L3RyPgogKiAgICAgICAgIDx0cj4KICogICAgICAgICAgIDx0ZCBub3dyYXAgdmFsaWduPSJ0b3AiPjxjb2RlPidhJzwvY29kZT48L3RkPgogKiAgICAgICAgICAgPHRkIHZhbGlnbj0idG9wIj48L3RkPgogKiAgICAgICAgICAgPHRkIHZhbGlnbj0idG9wIj50aGUgbGl0ZXJhbCBzdHJpbmcgYmV0d2VlbiB0aGUgcXVvdGVzIDwvdGQ+CiAqICAgICAgICAgPC90cj4KICogICAgICAgPC90YWJsZT4KICogICAgICAgPC90ZD4KICogICAgIDwvdHI+CiAqICAgPC90YWJsZT4KICogPC9ibG9ja3F1b3RlPgogKgogKiBBbnkgY2hhcmFjdGVyIG1heSBiZSBwcmVjZWRlZCBieSBhIGJhY2tzbGFzaCBpbiBvcmRlciB0byByZW1vdmUgYW55IHNwZWNpYWwKICogbWVhbmluZy4gIFdoaXRlIHNwYWNlIGNoYXJhY3RlcnMsIGFzIGRlZmluZWQgYnkgQ2hhcmFjdGVyLmlzV2hpdGVzcGFjZSgpLCBhcmUKICogaWdub3JlZCwgdW5sZXNzIHRoZXkgYXJlIGVzY2FwZWQuCiAqCiAqIFBhdHRlcm5zIHNwZWNpZnkgaW5kaXZpZHVhbCBjaGFyYWN0ZXJzLCByYW5nZXMgb2YgY2hhcmFjdGVycywgYW5kCiAqIFVuaWNvZGUgY2hhcmFjdGVyIGNhdGVnb3JpZXMuICBXaGVuIGVsZW1lbnRzIGFyZSBjb25jYXRlbmF0ZWQsIHRoZXkKICogc3BlY2lmeSB0aGVpciB1bmlvbi4gIFRvIGNvbXBsZW1lbnQgYSBzZXQsIHBsYWNlIGEgJ14nIGltbWVkaWF0ZWx5CiAqIGFmdGVyIHRoZSBvcGVuaW5nICdbJyBvciAnWzonLiAgSW4gYW55IG90aGVyIGxvY2F0aW9uLCAnXicgaGFzIG5vCiAqIHNwZWNpYWwgbWVhbmluZy4KICoKICogPHA+UmFuZ2VzIGFyZSBpbmRpY2F0ZWQgYnkgcGxhY2luZyB0d28gYSAnLScgYmV0d2VlbiB0d28KICogY2hhcmFjdGVycywgYXMgaW4gImEteiIuICBUaGlzIHNwZWNpZmllcyB0aGUgcmFuZ2Ugb2YgYWxsCiAqIGNoYXJhY3RlcnMgZnJvbSB0aGUgbGVmdCB0byB0aGUgcmlnaHQsIGluIFVuaWNvZGUgb3JkZXIuICBJZiB0aGUKICogbGVmdCBhbmQgcmlnaHQgY2hhcmFjdGVycyBhcmUgdGhlIHNhbWUsIHRoZW4gdGhlIHJhbmdlIGNvbnNpc3RzIG9mCiAqIGp1c3QgdGhhdCBjaGFyYWN0ZXIuICBJZiB0aGUgbGVmdCBjaGFyYWN0ZXIgaXMgZ3JlYXRlciB0aGFuIHRoZQogKiByaWdodCBjaGFyYWN0ZXIgaXQgaXMgYSBzeW50YXggZXJyb3IuICBJZiBhICctJyBvY2N1cnMgYXMgdGhlIGZpcnN0CiAqIGNoYXJhY3RlciBhZnRlciB0aGUgb3BlbmluZyAnWycgb3IgJ1teJywgb3IgaWYgaXQgb2NjdXJzIGFzIHRoZQogKiBsYXN0IGNoYXJhY3RlciBiZWZvcmUgdGhlIGNsb3NpbmcgJ10nLCB0aGVuIGl0IGlzIHRha2VuIGFzIGEKICogbGl0ZXJhbC4gIFRodXMgIlthXC1iXSIsICJbLWFiXSIsIGFuZCAiW2FiLV0iIGFsbCBpbmRpY2F0ZSB0aGUgc2FtZQogKiBzZXQgb2YgdGhyZWUgY2hhcmFjdGVycywgJ2EnLCAnYicsIGFuZCAnLScuCiAqCiAqIDxwPlNldHMgbWF5IGJlIGludGVyc2VjdGVkIHVzaW5nIHRoZSAnJicgb3BlcmF0b3Igb3IgdGhlIGFzeW1tZXRyaWMKICogc2V0IGRpZmZlcmVuY2UgbWF5IGJlIHRha2VuIHVzaW5nIHRoZSAnLScgb3BlcmF0b3IsIGZvciBleGFtcGxlLAogKiAiW1s6TDpdJltcdTAwMDAtXHUwRkZGXV0iIGluZGljYXRlcyB0aGUgc2V0IG9mIGFsbCBVbmljb2RlIGxldHRlcnMKICogd2l0aCB2YWx1ZXMgbGVzcyB0aGFuIDQwOTYuICBPcGVyYXRvcnMgKCcmJyBhbmQgJ3wnKSBoYXZlIGVxdWFsCiAqIHByZWNlZGVuY2UgYW5kIGJpbmQgbGVmdC10by1yaWdodC4gIFRodXMKICogIltbOkw6XS1bYS16XS1bXHUwMTAwLVx1MDFGRl1dIiBpcyBlcXVpdmFsZW50IHRvCiAqICJbW1s6TDpdLVthLXpdXS1bXHUwMTAwLVx1MDFGRl1dIi4gIFRoaXMgb25seSByZWFsbHkgbWF0dGVycyBmb3IKICogZGlmZmVyZW5jZTsgaW50ZXJzZWN0aW9uIGlzIGNvbW11dGF0aXZlLgogKgogKiA8dGFibGU+CiAqIDx0ciB2YWxpZ249dG9wPjx0ZCBub3dyYXA+PGNvZGU+W2FdPC9jb2RlPjx0ZD5UaGUgc2V0IGNvbnRhaW5pbmcgJ2EnCiAqIDx0ciB2YWxpZ249dG9wPjx0ZCBub3dyYXA+PGNvZGU+W2Etel08L2NvZGU+PHRkPlRoZSBzZXQgY29udGFpbmluZyAnYScKICogdGhyb3VnaCAneicgYW5kIGFsbCBsZXR0ZXJzIGluIGJldHdlZW4sIGluIFVuaWNvZGUgb3JkZXIKICogPHRyIHZhbGlnbj10b3A+PHRkIG5vd3JhcD48Y29kZT5bXmEtel08L2NvZGU+PHRkPlRoZSBzZXQgY29udGFpbmluZwogKiBhbGwgY2hhcmFjdGVycyBidXQgJ2EnIHRocm91Z2ggJ3onLAogKiB0aGF0IGlzLCBVKzAwMDAgdGhyb3VnaCAnYSctMSBhbmQgJ3onKzEgdGhyb3VnaCBVK0ZGRkYKICogPHRyIHZhbGlnbj10b3A+PHRkIG5vd3JhcD48Y29kZT5bWzxlbT5wYXQxPC9lbT5dWzxlbT5wYXQyPC9lbT5dXTwvY29kZT4KICogPHRkPlRoZSB1bmlvbiBvZiBzZXRzIHNwZWNpZmllZCBieSA8ZW0+cGF0MTwvZW0+IGFuZCA8ZW0+cGF0MjwvZW0+CiAqIDx0ciB2YWxpZ249dG9wPjx0ZCBub3dyYXA+PGNvZGU+W1s8ZW0+cGF0MTwvZW0+XSZbPGVtPnBhdDI8L2VtPl1dPC9jb2RlPgogKiA8dGQ+VGhlIGludGVyc2VjdGlvbiBvZiBzZXRzIHNwZWNpZmllZCBieSA8ZW0+cGF0MTwvZW0+IGFuZCA8ZW0+cGF0MjwvZW0+CiAqIDx0ciB2YWxpZ249dG9wPjx0ZCBub3dyYXA+PGNvZGU+W1s8ZW0+cGF0MTwvZW0+XS1bPGVtPnBhdDI8L2VtPl1dPC9jb2RlPgogKiA8dGQ+VGhlIGFzeW1tZXRyaWMgZGlmZmVyZW5jZSBvZiBzZXRzIHNwZWNpZmllZCBieSA8ZW0+cGF0MTwvZW0+IGFuZAogKiA8ZW0+cGF0MjwvZW0+CiAqIDx0ciB2YWxpZ249dG9wPjx0ZCBub3dyYXA+PGNvZGU+WzpMdTpdPC9jb2RlPgogKiA8dGQ+VGhlIHNldCBvZiBjaGFyYWN0ZXJzIGJlbG9uZ2luZyB0byB0aGUgZ2l2ZW4KICogVW5pY29kZSBjYXRlZ29yeSwgYXMgZGVmaW5lZCBieSA8Y29kZT5DaGFyYWN0ZXIuZ2V0VHlwZSgpPC9jb2RlPjsgaW4KICogdGhpcyBjYXNlLCBVbmljb2RlIHVwcGVyY2FzZSBsZXR0ZXJzCiAqIDx0ciB2YWxpZ249dG9wPjx0ZCBub3dyYXA+PGNvZGU+WzpMOl08L2NvZGU+CiAqIDx0ZD5UaGUgc2V0IG9mIGNoYXJhY3RlcnMgYmVsb25naW5nIHRvIGFsbCBVbmljb2RlIGNhdGVnb3JpZXMKICogc3RhcnRpbmcgd2loICdMJywgdGhhdCBpcywgPGNvZGU+W1s6THU6XVs6TGw6XVs6THQ6XVs6TG06XVs6TG86XV08L2NvZGU+LgogKiA8L3RhYmxlPgogKgogKiA8cD48Yj5DaGFyYWN0ZXIgY2F0ZWdvcmllcy48L2I+CiAqCiAqIENoYXJhY3RlciBjYXRlZ29yaWVzIGFyZSBzcGVjaWZpZWQgdXNpbmcgdGhlIFBPU0lYLWxpa2Ugc3ludGF4CiAqICdbOkx1Ol0nLiAgVGhlIGNvbXBsZW1lbnQgb2YgYSBjYXRlZ29yeSBpcyBzcGVjaWZpZWQgYnkgaW5zZXJ0aW5nCiAqICdeJyBhZnRlciB0aGUgb3BlbmluZyAnWzonLiAgVGhlIGZvbGxvd2luZyBjYXRlZ29yeSBuYW1lcyBhcmUKICogcmVjb2duaXplZC4gIEFjdHVhbCBkZXRlcm1pbmF0aW9uIG9mIGNhdGVnb3J5IGRhdGEgdXNlcwogKiA8Y29kZT5Vbmljb2RlOjpnZXRUeXBlKCk8L2NvZGU+LCBzbyBpdCByZWZsZWN0cyB0aGUgdW5kZXJseWluZwogKiBkYXRhIHVzZWQgYnkgPGNvZGU+VW5pY29kZTwvY29kZT4uCiAqCiAqIDxwcmU+CiAqIE5vcm1hdGl2ZQogKiAgICAgTW4gPSBNYXJrLCBOb24tU3BhY2luZwogKiAgICAgTWMgPSBNYXJrLCBTcGFjaW5nIENvbWJpbmluZwogKiAgICAgTWUgPSBNYXJrLCBFbmNsb3NpbmcKICogCiAqICAgICBOZCA9IE51bWJlciwgRGVjaW1hbCBEaWdpdAogKiAgICAgTmwgPSBOdW1iZXIsIExldHRlcgogKiAgICAgTm8gPSBOdW1iZXIsIE90aGVyCiAqIAogKiAgICAgWnMgPSBTZXBhcmF0b3IsIFNwYWNlCiAqICAgICBabCA9IFNlcGFyYXRvciwgTGluZQogKiAgICAgWnAgPSBTZXBhcmF0b3IsIFBhcmFncmFwaAogKiAKICogICAgIENjID0gT3RoZXIsIENvbnRyb2wKICogICAgIENmID0gT3RoZXIsIEZvcm1hdAogKiAgICAgQ3MgPSBPdGhlciwgU3Vycm9nYXRlCiAqICAgICBDbyA9IE90aGVyLCBQcml2YXRlIFVzZQogKiAgICAgQ24gPSBPdGhlciwgTm90IEFzc2lnbmVkCiAqIAogKiBJbmZvcm1hdGl2ZQogKiAgICAgTHUgPSBMZXR0ZXIsIFVwcGVyY2FzZQogKiAgICAgTGwgPSBMZXR0ZXIsIExvd2VyY2FzZQogKiAgICAgTHQgPSBMZXR0ZXIsIFRpdGxlY2FzZQogKiAgICAgTG0gPSBMZXR0ZXIsIE1vZGlmaWVyCiAqICAgICBMbyA9IExldHRlciwgT3RoZXIKICogCiAqICAgICBQYyA9IFB1bmN0dWF0aW9uLCBDb25uZWN0b3IKICogICAgIFBkID0gUHVuY3R1YXRpb24sIERhc2gKICogICAgIFBzID0gUHVuY3R1YXRpb24sIE9wZW4KICogICAgIFBlID0gUHVuY3R1YXRpb24sIENsb3NlCiAqICAgICBQaSA9IFB1bmN0dWF0aW9uLCBJbml0aWFsIHF1b3RlCiAqICAgICBQZiA9IFB1bmN0dWF0aW9uLCBGaW5hbCBxdW90ZQogKiAgICAgUG8gPSBQdW5jdHVhdGlvbiwgT3RoZXIKICogCiAqICAgICBTbSA9IFN5bWJvbCwgTWF0aAogKiAgICAgU2MgPSBTeW1ib2wsIEN1cnJlbmN5CiAqICAgICBTayA9IFN5bWJvbCwgTW9kaWZpZXIKICogICAgIFNvID0gU3ltYm9sLCBPdGhlcgogKiA8L3ByZT4KICoKICogQGF1dGhvciBBbGFuIExpdQogKiBAZHJhZnQKICovCmNsYXNzIFVfSTE4Tl9BUEkgVW5pY29kZVNldCA6IHB1YmxpYyBVbmljb2RlRmlsdGVyIHsKCiAgICBpbnQzMl90IGxlbjsgLy8gbGVuZ3RoIG9mIGxpc3QgdXNlZDsgMCA8PSBsZW4gPD0gY2FwYWNpdHkKICAgIGludDMyX3QgY2FwYWNpdHk7IC8vIGNhcGFjaXR5IG9mIGxpc3QKICAgIGludDMyX3QgYnVmZmVyQ2FwYWNpdHk7IC8vIGNhcGFjaXR5IG9mIGJ1ZmZlcgogICAgVUNoYXIzMiogbGlzdDsgLy8gTVVTVCBiZSB0ZXJtaW5hdGVkIHdpdGggSElHSAogICAgVUNoYXIzMiogYnVmZmVyOyAvLyBpbnRlcm5hbCBidWZmZXIsIG1heSBiZSBOVUxMCgojaWZuZGVmIEhQVVgKICAgIHN0YXRpYyBjb25zdCBVQ2hhcjMyIEhJR0g7IC8vIEhJR0ggPiBhbGwgdmFsaWQgdmFsdWVzLiAxMTAwMDAgZm9yIGNvZGVwb2ludHMKI2VuZGlmCiAgICBzdGF0aWMgY29uc3QgVUNoYXIzMiBMT1c7IC8vIExPVyA8PSBhbGwgdmFsaWQgdmFsdWVzLiBaRVJPIGZvciBjb2RlcG9pbnRzCgogICAgc3RhdGljIGNvbnN0IGludDMyX3QgU1RBUlRfRVhUUkE7IC8vIGluaXRpYWwgc3RvcmFnZS4gTXVzdCBiZSA+PSAwCiAgICBzdGF0aWMgY29uc3QgaW50MzJfdCBHUk9XX0VYVFJBOyAvLyBleHRyYSBhbW91bnQgZm9yIGdyb3d0aC4gTXVzdCBiZSA+PSAwCgogICAgc3RhdGljIGNvbnN0IFVuaWNvZGVTdHJpbmcgQ0FURUdPUllfTkFNRVM7CgogICAgLyoqCiAgICAgKiBBIGNhY2hlIG1hcHBpbmcgY2hhcmFjdGVyIGNhdGVnb3J5IGludGVnZXJzLCBhcyByZXR1cm5lZCBieQogICAgICogVW5pY29kZTo6Z2V0VHlwZSgpLCB0byBwYWlycyBzdHJpbmdzLiAgRW50cmllcyBhcmUgaW5pdGlhbGx5CiAgICAgKiB6ZXJvIGxlbmd0aCBhbmQgYXJlIGZpbGxlZCBpbiBvbiBkZW1hbmQuCiAgICAgKi8KICAgIHN0YXRpYyBVbmljb2RlU2V0KiBDQVRFR09SWV9DQUNIRTsKCiAgICAvKioKICAgICAqIERlbGltaXRlciBzdHJpbmcgdXNlZCBpbiBwYXR0ZXJucyB0byBjbG9zZSBhIGNhdGVnb3J5IHJlZmVyZW5jZToKICAgICAqICI6XSIuICBFeGFtcGxlOiAiWzpMdTpdIi4KICAgICAqLwogICAgc3RhdGljIGNvbnN0IFVuaWNvZGVTdHJpbmcgQ0FURUdPUllfQ0xPU0U7CiAgICAKICAgIC8vIE1vcmUgc3BlY2lhbCBjaGFyYWN0ZXJzLi4uCiAgICBzdGF0aWMgY29uc3QgVUNoYXIgU0VUX09QRU47CiAgICBzdGF0aWMgY29uc3QgVUNoYXIgU0VUX0NMT1NFOwogICAgc3RhdGljIGNvbnN0IFVDaGFyIEhZUEhFTjsKICAgIHN0YXRpYyBjb25zdCBVQ2hhciBDT01QTEVNRU5UOwogICAgc3RhdGljIGNvbnN0IFVDaGFyIENPTE9OOwogICAgc3RhdGljIGNvbnN0IFVDaGFyIEJBQ0tTTEFTSDsKICAgIHN0YXRpYyBjb25zdCBVQ2hhciBJTlRFUlNFQ1RJT047CiAgICBzdGF0aWMgY29uc3QgVUNoYXIgVVBQRVJfVTsKICAgIApwdWJsaWM6CgogICAgLyoqCiAgICAgKiBNaW5pbXVtIHZhbHVlIHRoYXQgY2FuIGJlIHN0b3JlZCBpbiBhIFVuaWNvZGVTZXQuCiAgICAgKi8KICAgIHN0YXRpYyBjb25zdCBVQ2hhcjMyIE1JTl9WQUxVRTsKCiAgICAvKioKICAgICAqIE1heGltdW0gdmFsdWUgdGhhdCBjYW4gYmUgc3RvcmVkIGluIGEgVW5pY29kZVNldC4KICAgICAqLwogICAgc3RhdGljIGNvbnN0IFVDaGFyMzIgTUFYX1ZBTFVFOwoKICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgLy8gQ29uc3RydWN0b3JzICZjCiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCnB1YmxpYzoKCiAgICAvKioKICAgICAqIENvbnN0cnVjdHMgYW4gZW1wdHkgc2V0LgogICAgICogQGRyYWZ0CiAgICAgKi8KICAgIFVuaWNvZGVTZXQoKTsKCiAgICAvKioKICAgICAqIENvbnN0cnVjdHMgYSBzZXQgY29udGFpbmluZyB0aGUgZ2l2ZW4gcmFuZ2UuIElmIDxjb2RlPmVuZCA+CiAgICAgKiBzdGFydDwvY29kZT4gdGhlbiBhbiBlbXB0eSBzZXQgaXMgY3JlYXRlZC4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RhcnQgZmlyc3QgY2hhcmFjdGVyLCBpbmNsdXNpdmUsIG9mIHJhbmdlCiAgICAgKiBAcGFyYW0gZW5kIGxhc3QgY2hhcmFjdGVyLCBpbmNsdXNpdmUsIG9mIHJhbmdlCiAgICAgKi8KICAgIFVuaWNvZGVTZXQoVUNoYXIzMiBzdGFydCwgVUNoYXIzMiBlbmQpOwoKICAgIC8qKgogICAgICogQ29uc3RydWN0cyBhIHNldCBmcm9tIHRoZSBnaXZlbiBwYXR0ZXJuLiAgU2VlIHRoZSBjbGFzcwogICAgICogZGVzY3JpcHRpb24gZm9yIHRoZSBzeW50YXggb2YgdGhlIHBhdHRlcm4gbGFuZ3VhZ2UuCiAgICAgKiBAcGFyYW0gcGF0dGVybiBhIHN0cmluZyBzcGVjaWZ5aW5nIHdoYXQgY2hhcmFjdGVycyBhcmUgaW4gdGhlIHNldAogICAgICogQGV4Y2VwdGlvbiA8Y29kZT5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb248L2NvZGU+IGlmIHRoZSBwYXR0ZXJuCiAgICAgKiBjb250YWlucyBhIHN5bnRheCBlcnJvci4KICAgICAqIEBkcmFmdAogICAgICovCiAgICBVbmljb2RlU2V0KGNvbnN0IFVuaWNvZGVTdHJpbmcmIHBhdHRlcm4sCiAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cyk7CgogICAgLyoqCiAgICAgKiBDb25zdHJ1Y3RzIGEgc2V0IGZyb20gdGhlIGdpdmVuIFVuaWNvZGUgY2hhcmFjdGVyIGNhdGVnb3J5LgogICAgICogQHBhcmFtIGNhdGVnb3J5IGFuIGludGVnZXIgaW5kaWNhdGluZyB0aGUgY2hhcmFjdGVyIGNhdGVnb3J5IGFzCiAgICAgKiByZXR1cm5lZCBieSA8Y29kZT5DaGFyYWN0ZXIuZ2V0VHlwZSgpPC9jb2RlPi4KICAgICAqIEBleGNlcHRpb24gPGNvZGU+SWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uPC9jb2RlPiBpZiB0aGUgZ2l2ZW4KICAgICAqIGNhdGVnb3J5IGlzIGludmFsaWQuCiAgICAgKiBAZHJhZnQKICAgICAqLwogICAgVW5pY29kZVNldChpbnQ4X3QgY2F0ZWdvcnksIFVFcnJvckNvZGUmIHN0YXR1cyk7CgogICAgLyoqCiAgICAgKiBDb25zdHJ1Y3RzIGEgc2V0IHRoYXQgaXMgaWRlbnRpY2FsIHRvIHRoZSBnaXZlbiBVbmljb2RlU2V0LgogICAgICogQGRyYWZ0CiAgICAgKi8KICAgIFVuaWNvZGVTZXQoY29uc3QgVW5pY29kZVNldCYgbyk7CgogICAgLyoqCiAgICAgKiBEZXN0cnVjdHMgdGhlIHNldC4KICAgICAqIEBkcmFmdAogICAgICovCiAgICB2aXJ0dWFsIH5Vbmljb2RlU2V0KCk7CgogICAgLyoqCiAgICAgKiBBc3NpZ25zIHRoaXMgb2JqZWN0IHRvIGJlIGEgY29weSBvZiBhbm90aGVyLgogICAgICogQGRyYWZ0CiAgICAgKi8KICAgIFVuaWNvZGVTZXQmIG9wZXJhdG9yPShjb25zdCBVbmljb2RlU2V0JiBvKTsKCiAgICAvKioKICAgICAqIENvbXBhcmVzIHRoZSBzcGVjaWZpZWQgb2JqZWN0IHdpdGggdGhpcyBzZXQgZm9yIGVxdWFsaXR5LiAgUmV0dXJucwogICAgICogPHR0PnRydWU8L3R0PiBpZiB0aGUgdHdvIHNldHMKICAgICAqIGhhdmUgdGhlIHNhbWUgc2l6ZSwgYW5kIGV2ZXJ5IG1lbWJlciBvZiB0aGUgc3BlY2lmaWVkIHNldCBpcwogICAgICogY29udGFpbmVkIGluIHRoaXMgc2V0IChvciBlcXVpdmFsZW50bHksIGV2ZXJ5IG1lbWJlciBvZiB0aGlzIHNldCBpcwogICAgICogY29udGFpbmVkIGluIHRoZSBzcGVjaWZpZWQgc2V0KS4KICAgICAqCiAgICAgKiBAcGFyYW0gbyBzZXQgdG8gYmUgY29tcGFyZWQgZm9yIGVxdWFsaXR5IHdpdGggdGhpcyBzZXQuCiAgICAgKiBAcmV0dXJuIDx0dD50cnVlPC90dD4gaWYgdGhlIHNwZWNpZmllZCBzZXQgaXMgZXF1YWwgdG8gdGhpcyBzZXQuCiAgICAgKiBAZHJhZnQKICAgICAqLwogICAgdmlydHVhbCBVQm9vbCBvcGVyYXRvcj09KGNvbnN0IFVuaWNvZGVTZXQmIG8pIGNvbnN0OwoKICAgIC8qKgogICAgICogQ29tcGFyZXMgdGhlIHNwZWNpZmllZCBvYmplY3Qgd2l0aCB0aGlzIHNldCBmb3IgZXF1YWxpdHkuICBSZXR1cm5zCiAgICAgKiA8dHQ+dHJ1ZTwvdHQ+IGlmIHRoZSBzcGVjaWZpZWQgc2V0IGlzIG5vdCBlcXVhbCB0byB0aGlzIHNldC4KICAgICAqIEBkcmFmdAogICAgICovCiAgICBVQm9vbCBvcGVyYXRvciE9KGNvbnN0IFVuaWNvZGVTZXQmIG8pIGNvbnN0OwoKICAgIC8qKgogICAgICogUmV0dXJucyBhIGNvcHkgb2YgdGhpcyBvYmplY3QuICBBbGwgVW5pY29kZUZpbHRlciBvYmplY3RzIGhhdmUKICAgICAqIHRvIHN1cHBvcnQgY2xvbmluZyBpbiBvcmRlciB0byBhbGxvdyBjbGFzc2VzIHVzaW5nCiAgICAgKiBVbmljb2RlRmlsdGVycywgc3VjaCBhcyBUcmFuc2xpdGVyYXRvciwgdG8gaW1wbGVtZW50IGNsb25pbmcuCiAgICAgKiBAZHJhZnQKICAgICAqLwogICAgdmlydHVhbCBVbmljb2RlRmlsdGVyKiBjbG9uZSgpIGNvbnN0OwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgaGFzaCBjb2RlIHZhbHVlIGZvciB0aGlzIHNldC4KICAgICAqCiAgICAgKiBAcmV0dXJuIHRoZSBoYXNoIGNvZGUgdmFsdWUgZm9yIHRoaXMgc2V0LgogICAgICogQHNlZSBPYmplY3QjaGFzaENvZGUoKQogICAgICogQGRyYWZ0CiAgICAgKi8KICAgIHZpcnR1YWwgaW50MzJfdCBoYXNoQ29kZSh2b2lkKSBjb25zdDsKCiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgIC8vIFB1YmxpYyBBUEkKICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIC8qKgogICAgICogTWFrZSB0aGlzIG9iamVjdCByZXByZXNlbnQgdGhlIHJhbmdlIDxjb2RlPnN0YXJ0IC0gZW5kPC9jb2RlPi4KICAgICAqIElmIDxjb2RlPmVuZCA+IHN0YXJ0PC9jb2RlPiB0aGVuIHRoaXMgb2JqZWN0IGlzIHNldCB0byBhbgogICAgICogYW4gZW1wdHkgcmFuZ2UuCiAgICAgKgogICAgICogQHBhcmFtIHN0YXJ0IGZpcnN0IGNoYXJhY3RlciBpbiB0aGUgc2V0LCBpbmNsdXNpdmUKICAgICAqIEBycGFyYW0gZW5kIGxhc3QgY2hhcmFjdGVyIGluIHRoZSBzZXQsIGluY2x1c2l2ZQogICAgICovCiAgICB2b2lkIHNldChVQ2hhcjMyIHN0YXJ0LCBVQ2hhcjMyIGVuZCk7CgogICAgLyoqCiAgICAgKiBNb2RpZmllcyB0aGlzIHNldCB0byByZXByZXNlbnQgdGhlIHNldCBzcGVjaWZpZWQgYnkgdGhlIGdpdmVuCiAgICAgKiBwYXR0ZXJuLCBvcHRpb25hbGx5IGlnbm9yaW5nIHdoaXRlIHNwYWNlLiAgU2VlIHRoZSBjbGFzcwogICAgICogZGVzY3JpcHRpb24gZm9yIHRoZSBzeW50YXggb2YgdGhlIHBhdHRlcm4gbGFuZ3VhZ2UuCiAgICAgKiBAcGFyYW0gcGF0dGVybiBhIHN0cmluZyBzcGVjaWZ5aW5nIHdoYXQgY2hhcmFjdGVycyBhcmUgaW4gdGhlIHNldAogICAgICogQGV4Y2VwdGlvbiA8Y29kZT5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb248L2NvZGU+IGlmIHRoZSBwYXR0ZXJuCiAgICAgKiBjb250YWlucyBhIHN5bnRheCBlcnJvci4KICAgICAqIEBkcmFmdAogICAgICovCiAgICB2aXJ0dWFsIHZvaWQgYXBwbHlQYXR0ZXJuKGNvbnN0IFVuaWNvZGVTdHJpbmcmIHBhdHRlcm4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cyk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoaXMgc2V0LiAgSWYgdGhlIHJlc3VsdCBvZgogICAgICogY2FsbGluZyB0aGlzIGZ1bmN0aW9uIGlzIHBhc3NlZCB0byBhIFVuaWNvZGVTZXQgY29uc3RydWN0b3IsIGl0CiAgICAgKiB3aWxsIHByb2R1Y2UgYW5vdGhlciBzZXQgdGhhdCBpcyBlcXVhbCB0byB0aGlzIG9uZS4KICAgICAqIEBkcmFmdAogICAgICovCiAgICB2aXJ0dWFsIFVuaWNvZGVTdHJpbmcmIHRvUGF0dGVybihVbmljb2RlU3RyaW5nJiByZXN1bHQpIGNvbnN0OwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgbnVtYmVyIG9mIGVsZW1lbnRzIGluIHRoaXMgc2V0IChpdHMgY2FyZGluYWxpdHkpLAogICAgICogPGVtPm48L2VtPiwgd2hlcmUgPGNvZGU+MCA8PSA8L2NvZGU+PGVtPm48L2VtPjxjb2RlPiA8PSA2NTUzNjwvY29kZT4uCiAgICAgKgogICAgICogQHJldHVybiB0aGUgbnVtYmVyIG9mIGVsZW1lbnRzIGluIHRoaXMgc2V0IChpdHMgY2FyZGluYWxpdHkpLgogICAgICogQGRyYWZ0CiAgICAgKi8KICAgIHZpcnR1YWwgaW50MzJfdCBzaXplKHZvaWQpIGNvbnN0OwoKICAgIC8qKgogICAgICogUmV0dXJucyA8dHQ+dHJ1ZTwvdHQ+IGlmIHRoaXMgc2V0IGNvbnRhaW5zIG5vIGVsZW1lbnRzLgogICAgICoKICAgICAqIEByZXR1cm4gPHR0PnRydWU8L3R0PiBpZiB0aGlzIHNldCBjb250YWlucyBubyBlbGVtZW50cy4KICAgICAqIEBkcmFmdAogICAgICovCiAgICB2aXJ0dWFsIFVCb29sIGlzRW1wdHkodm9pZCkgY29uc3Q7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIDx0dD50cnVlPC90dD4gaWYgdGhpcyBzZXQgY29udGFpbnMgdGhlIHNwZWNpZmllZCByYW5nZQogICAgICogb2YgY2hhcnMuCiAgICAgKgogICAgICogQHJldHVybiA8dHQ+dHJ1ZTwvdHQ+IGlmIHRoaXMgc2V0IGNvbnRhaW5zIHRoZSBzcGVjaWZpZWQgcmFuZ2UKICAgICAqIG9mIGNoYXJzLgogICAgICogQGRyYWZ0CiAgICAgKi8KICAgIHZpcnR1YWwgVUJvb2wgY29udGFpbnMoVUNoYXIzMiBzdGFydCwgVUNoYXIzMiBlbmQpIGNvbnN0OwoKICAgIC8qKgogICAgICogUmV0dXJucyA8dHQ+dHJ1ZTwvdHQ+IGlmIHRoaXMgc2V0IGNvbnRhaW5zIHRoZSBzcGVjaWZpZWQgY2hhci4KICAgICAqCiAgICAgKiBAcmV0dXJuIDx0dD50cnVlPC90dD4gaWYgdGhpcyBzZXQgY29udGFpbnMgdGhlIHNwZWNpZmllZCBjaGFyLgogICAgICogQGRyYWZ0CiAgICAgKi8KICAgIHZpcnR1YWwgVUJvb2wgY29udGFpbnMoVUNoYXIzMiBjKSBjb25zdDsKCiAgICAvKioKICAgICAqIEltcGxlbWVudCBVbmljb2RlRmlsdGVyOgogICAgICogUmV0dXJucyA8dHQ+dHJ1ZTwvdHQ+IGlmIHRoaXMgc2V0IGNvbnRhaW5zIHRoZSBzcGVjaWZpZWQgY2hhci4KICAgICAqCiAgICAgKiBAcmV0dXJuIDx0dD50cnVlPC90dD4gaWYgdGhpcyBzZXQgY29udGFpbnMgdGhlIHNwZWNpZmllZCBjaGFyLgogICAgICogQGRyYWZ0CiAgICAgKi8KICAgIHZpcnR1YWwgVUJvb2wgY29udGFpbnMoVUNoYXIgYykgY29uc3Q7CgogICAgLyoqCiAgICAgKiBBZGRzIHRoZSBzcGVjaWZpZWQgcmFuZ2UgdG8gdGhpcyBzZXQgaWYgaXQgaXMgbm90IGFscmVhZHkKICAgICAqIHByZXNlbnQuICBJZiB0aGlzIHNldCBhbHJlYWR5IGNvbnRhaW5zIHRoZSBzcGVjaWZpZWQgcmFuZ2UsCiAgICAgKiB0aGUgY2FsbCBsZWF2ZXMgdGhpcyBzZXQgdW5jaGFuZ2VkLiAgSWYgPGNvZGU+ZW5kID4gc3RhcnQ8L2NvZGU+CiAgICAgKiB0aGVuIGFuIGVtcHR5IHJhbmdlIGlzIGFkZGVkLCBsZWF2aW5nIHRoZSBzZXQgdW5jaGFuZ2VkLgogICAgICogVGhpcyBpcyBlcXVpdmFsZW50IHRvIGEgYm9vbGVhbiBsb2dpYyBPUiwgb3IgYSBzZXQgVU5JT04uCiAgICAgKgogICAgICogQHBhcmFtIHN0YXJ0IGZpcnN0IGNoYXJhY3RlciwgaW5jbHVzaXZlLCBvZiByYW5nZSB0byBiZSBhZGRlZAogICAgICogdG8gdGhpcyBzZXQuCiAgICAgKiBAcGFyYW0gZW5kIGxhc3QgY2hhcmFjdGVyLCBpbmNsdXNpdmUsIG9mIHJhbmdlIHRvIGJlIGFkZGVkCiAgICAgKiB0byB0aGlzIHNldC4KICAgICAqIEBkcmFmdAogICAgICovCiAgICB2aXJ0dWFsIHZvaWQgYWRkKFVDaGFyMzIgc3RhcnQsIFVDaGFyMzIgZW5kKTsKCiAgICAvKioKICAgICAqIEFkZHMgdGhlIHNwZWNpZmllZCBjaGFyYWN0ZXIgdG8gdGhpcyBzZXQgaWYgaXQgaXMgbm90IGFscmVhZHkKICAgICAqIHByZXNlbnQuICBJZiB0aGlzIHNldCBhbHJlYWR5IGNvbnRhaW5zIHRoZSBzcGVjaWZpZWQgY2hhcmFjdGVyLAogICAgICogdGhlIGNhbGwgbGVhdmVzIHRoaXMgc2V0IHVuY2hhbmdlZC4KICAgICAqIEBkcmFmdAogICAgICovCiAgICB2b2lkIGFkZChVQ2hhcjMyIGMpOwoKICAgIC8qKgogICAgICogUmV0YWluIG9ubHkgdGhlIGVsZW1lbnRzIGluIHRoaXMgc2V0IHRoYXQgYXJlIGNvbnRhaW5lZCBpbiB0aGUKICAgICAqIHNwZWNpZmllZCByYW5nZS4gIElmIDxjb2RlPmVuZCA+IHN0YXJ0PC9jb2RlPiB0aGVuIGFuIGVtcHR5IHJhbmdlIGlzCiAgICAgKiByZXRhaW5lZCwgbGVhdmluZyB0aGUgc2V0IGVtcHR5LiAgVGhpcyBpcyBlcXVpdmFsZW50IHRvCiAgICAgKiBhIGJvb2xlYW4gbG9naWMgQU5ELCBvciBhIHNldCBJTlRFUlNFQ1RJT04uCiAgICAgKgogICAgICogQHBhcmFtIHN0YXJ0IGZpcnN0IGNoYXJhY3RlciwgaW5jbHVzaXZlLCBvZiByYW5nZSB0byBiZSByZXRhaW5lZAogICAgICogdG8gdGhpcyBzZXQuCiAgICAgKiBAcGFyYW0gZW5kIGxhc3QgY2hhcmFjdGVyLCBpbmNsdXNpdmUsIG9mIHJhbmdlIHRvIGJlIHJldGFpbmVkCiAgICAgKiB0byB0aGlzIHNldC4KICAgICAqLwogICAgdmlydHVhbCB2b2lkIHJldGFpbihVQ2hhcjMyIHN0YXJ0LCBVQ2hhcjMyIGVuZCk7CgoKICAgIC8qKgogICAgICogUmV0YWluIHRoZSBzcGVjaWZpZWQgY2hhcmFjdGVyIGZyb20gdGhpcyBzZXQgaWYgaXQgaXMgcHJlc2VudC4KICAgICAqLwogICAgdm9pZCByZXRhaW4oVUNoYXIzMiBjKTsKCiAgICAvKioKICAgICAqIFJlbW92ZXMgdGhlIHNwZWNpZmllZCByYW5nZSBmcm9tIHRoaXMgc2V0IGlmIGl0IGlzIHByZXNlbnQuCiAgICAgKiBUaGUgc2V0IHdpbGwgbm90IGNvbnRhaW4gdGhlIHNwZWNpZmllZCByYW5nZSBvbmNlIHRoZSBjYWxsCiAgICAgKiByZXR1cm5zLiAgSWYgPGNvZGU+ZW5kID4gc3RhcnQ8L2NvZGU+IHRoZW4gYW4gZW1wdHkgcmFuZ2UgaXMKICAgICAqIHJlbW92ZWQsIGxlYXZpbmcgdGhlIHNldCB1bmNoYW5nZWQuCiAgICAgKiAKICAgICAqIEBwYXJhbSBzdGFydCBmaXJzdCBjaGFyYWN0ZXIsIGluY2x1c2l2ZSwgb2YgcmFuZ2UgdG8gYmUgcmVtb3ZlZAogICAgICogZnJvbSB0aGlzIHNldC4KICAgICAqIEBwYXJhbSBlbmQgbGFzdCBjaGFyYWN0ZXIsIGluY2x1c2l2ZSwgb2YgcmFuZ2UgdG8gYmUgcmVtb3ZlZAogICAgICogZnJvbSB0aGlzIHNldC4KICAgICAqIEBkcmFmdAogICAgICovCiAgICB2aXJ0dWFsIHZvaWQgcmVtb3ZlKFVDaGFyMzIgc3RhcnQsIFVDaGFyMzIgZW5kKTsKCiAgICAvKioKICAgICAqIFJlbW92ZXMgdGhlIHNwZWNpZmllZCBjaGFyYWN0ZXIgZnJvbSB0aGlzIHNldCBpZiBpdCBpcyBwcmVzZW50LgogICAgICogVGhlIHNldCB3aWxsIG5vdCBjb250YWluIHRoZSBzcGVjaWZpZWQgcmFuZ2Ugb25jZSB0aGUgY2FsbAogICAgICogcmV0dXJucy4KICAgICAqIEBkcmFmdAogICAgICovCiAgICB2b2lkIHJlbW92ZShVQ2hhcjMyIGMpOwoKICAgIC8qKgogICAgICogSW52ZXJ0cyB0aGlzIHNldC4gIFRoaXMgb3BlcmF0aW9uIG1vZGlmaWVzIHRoaXMgc2V0IHNvIHRoYXQKICAgICAqIGl0cyB2YWx1ZSBpcyBpdHMgY29tcGxlbWVudC4gIFRoaXMgaXMgZXF1aXZhbGVudCB0bwogICAgICogPGNvZGU+Y29tcGxlbWVudChNSU5fVkFMVUUsIE1BWF9WQUxVRSk8L2NvZGU+LgogICAgICogQGRyYWZ0CiAgICAgKi8KICAgIHZpcnR1YWwgdm9pZCBjb21wbGVtZW50KHZvaWQpOwoKICAgIC8qKgogICAgICogQ29tcGxlbWVudHMgdGhlIHNwZWNpZmllZCByYW5nZSBpbiB0aGlzIHNldC4gIEFueSBjaGFyYWN0ZXIgaW4KICAgICAqIHRoZSByYW5nZSB3aWxsIGJlIHJlbW92ZWQgaWYgaXQgaXMgaW4gdGhpcyBzZXQsIG9yIHdpbGwgYmUKICAgICAqIGFkZGVkIGlmIGl0IGlzIG5vdCBpbiB0aGlzIHNldC4gIElmIDxjb2RlPmVuZCA+IHN0YXJ0PC9jb2RlPgogICAgICogdGhlbiBhbiBlbXB0eSByYW5nZSBpcyBjb21wbGVtZW50ZWQsIGxlYXZpbmcgdGhlIHNldCB1bmNoYW5nZWQuCiAgICAgKiBUaGlzIGlzIGVxdWl2YWxlbnQgdG8gYSBib29sZWFuIGxvZ2ljIFhPUi4KICAgICAqCiAgICAgKiBAcGFyYW0gc3RhcnQgZmlyc3QgY2hhcmFjdGVyLCBpbmNsdXNpdmUsIG9mIHJhbmdlIHRvIGJlIHJlbW92ZWQKICAgICAqIGZyb20gdGhpcyBzZXQuCiAgICAgKiBAcGFyYW0gZW5kIGxhc3QgY2hhcmFjdGVyLCBpbmNsdXNpdmUsIG9mIHJhbmdlIHRvIGJlIHJlbW92ZWQKICAgICAqIGZyb20gdGhpcyBzZXQuCiAgICAgKi8KICAgIHZpcnR1YWwgdm9pZCBjb21wbGVtZW50KFVDaGFyMzIgc3RhcnQsIFVDaGFyMzIgZW5kKTsKCgogICAgLyoqCiAgICAgKiBDb21wbGVtZW50cyB0aGUgc3BlY2lmaWVkIGNoYXJhY3RlciBpbiB0aGlzIHNldC4gIFRoZSBjaGFyYWN0ZXIKICAgICAqIHdpbGwgYmUgcmVtb3ZlZCBpZiBpdCBpcyBpbiB0aGlzIHNldCwgb3Igd2lsbCBiZSBhZGRlZCBpZiBpdCBpcwogICAgICogbm90IGluIHRoaXMgc2V0LgogICAgICovCiAgICB2b2lkIGNvbXBsZW1lbnQoVUNoYXIzMiBjKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgPHR0PnRydWU8L3R0PiBpZiB0aGUgc3BlY2lmaWVkIHNldCBpcyBhIDxpPnN1YnNldDwvaT4KICAgICAqIG9mIHRoaXMgc2V0LgogICAgICoKICAgICAqIEBwYXJhbSBjIHNldCB0byBiZSBjaGVja2VkIGZvciBjb250YWlubWVudCBpbiB0aGlzIHNldC4KICAgICAqIEByZXR1cm4gPHR0PnRydWU8L3R0PiBpZiB0aGlzIHNldCBjb250YWlucyBhbGwgb2YgdGhlIGVsZW1lbnRzIG9mIHRoZQogICAgICogCSAgICAgICBzcGVjaWZpZWQgc2V0LgogICAgICogQGRyYWZ0CiAgICAgKi8KICAgIHZpcnR1YWwgVUJvb2wgY29udGFpbnNBbGwoY29uc3QgVW5pY29kZVNldCYgYykgY29uc3Q7CgogICAgLyoqCiAgICAgKiBBZGRzIGFsbCBvZiB0aGUgZWxlbWVudHMgaW4gdGhlIHNwZWNpZmllZCBzZXQgdG8gdGhpcyBzZXQgaWYKICAgICAqIHRoZXkncmUgbm90IGFscmVhZHkgcHJlc2VudC4gIFRoaXMgb3BlcmF0aW9uIGVmZmVjdGl2ZWx5CiAgICAgKiBtb2RpZmllcyB0aGlzIHNldCBzbyB0aGF0IGl0cyB2YWx1ZSBpcyB0aGUgPGk+dW5pb248L2k+IG9mIHRoZSB0d28KICAgICAqIHNldHMuICBUaGUgYmVoYXZpb3Igb2YgdGhpcyBvcGVyYXRpb24gaXMgdW5zcGVjaWZpZWQgaWYgdGhlIHNwZWNpZmllZAogICAgICogY29sbGVjdGlvbiBpcyBtb2RpZmllZCB3aGlsZSB0aGUgb3BlcmF0aW9uIGlzIGluIHByb2dyZXNzLgogICAgICoKICAgICAqIEBwYXJhbSBjIHNldCB3aG9zZSBlbGVtZW50cyBhcmUgdG8gYmUgYWRkZWQgdG8gdGhpcyBzZXQuCiAgICAgKiBAc2VlICNhZGQoY2hhciwgY2hhcikKICAgICAqIEBkcmFmdAogICAgICovCiAgICB2aXJ0dWFsIHZvaWQgYWRkQWxsKGNvbnN0IFVuaWNvZGVTZXQmIGMpOwoKICAgIC8qKgogICAgICogUmV0YWlucyBvbmx5IHRoZSBlbGVtZW50cyBpbiB0aGlzIHNldCB0aGF0IGFyZSBjb250YWluZWQgaW4gdGhlCiAgICAgKiBzcGVjaWZpZWQgc2V0LiAgSW4gb3RoZXIgd29yZHMsIHJlbW92ZXMgZnJvbSB0aGlzIHNldCBhbGwgb2YKICAgICAqIGl0cyBlbGVtZW50cyB0aGF0IGFyZSBub3QgY29udGFpbmVkIGluIHRoZSBzcGVjaWZpZWQgc2V0LiAgVGhpcwogICAgICogb3BlcmF0aW9uIGVmZmVjdGl2ZWx5IG1vZGlmaWVzIHRoaXMgc2V0IHNvIHRoYXQgaXRzIHZhbHVlIGlzCiAgICAgKiB0aGUgPGk+aW50ZXJzZWN0aW9uPC9pPiBvZiB0aGUgdHdvIHNldHMuCiAgICAgKgogICAgICogQHBhcmFtIGMgc2V0IHRoYXQgZGVmaW5lcyB3aGljaCBlbGVtZW50cyB0aGlzIHNldCB3aWxsIHJldGFpbi4KICAgICAqIEBkcmFmdAogICAgICovCiAgICB2aXJ0dWFsIHZvaWQgcmV0YWluQWxsKGNvbnN0IFVuaWNvZGVTZXQmIGMpOwoKICAgIC8qKgogICAgICogUmVtb3ZlcyBmcm9tIHRoaXMgc2V0IGFsbCBvZiBpdHMgZWxlbWVudHMgdGhhdCBhcmUgY29udGFpbmVkIGluIHRoZQogICAgICogc3BlY2lmaWVkIHNldC4gIFRoaXMgb3BlcmF0aW9uIGVmZmVjdGl2ZWx5IG1vZGlmaWVzIHRoaXMKICAgICAqIHNldCBzbyB0aGF0IGl0cyB2YWx1ZSBpcyB0aGUgPGk+YXN5bW1ldHJpYyBzZXQgZGlmZmVyZW5jZTwvaT4gb2YKICAgICAqIHRoZSB0d28gc2V0cy4KICAgICAqCiAgICAgKiBAcGFyYW0gYyBzZXQgdGhhdCBkZWZpbmVzIHdoaWNoIGVsZW1lbnRzIHdpbGwgYmUgcmVtb3ZlZCBmcm9tCiAgICAgKiAgICAgICAgICB0aGlzIHNldC4KICAgICAqIEBkcmFmdAogICAgICovCiAgICB2aXJ0dWFsIHZvaWQgcmVtb3ZlQWxsKGNvbnN0IFVuaWNvZGVTZXQmIGMpOwoKICAgIC8qKgogICAgICogQ29tcGxlbWVudHMgaW4gdGhpcyBzZXQgYWxsIGVsZW1lbnRzIGNvbnRhaW5lZCBpbiB0aGUgc3BlY2lmaWVkCiAgICAgKiBzZXQuICBBbnkgY2hhcmFjdGVyIGluIHRoZSBvdGhlciBzZXQgd2lsbCBiZSByZW1vdmVkIGlmIGl0IGlzCiAgICAgKiBpbiB0aGlzIHNldCwgb3Igd2lsbCBiZSBhZGRlZCBpZiBpdCBpcyBub3QgaW4gdGhpcyBzZXQuCiAgICAgKgogICAgICogQHBhcmFtIGMgc2V0IHRoYXQgZGVmaW5lcyB3aGljaCBlbGVtZW50cyB3aWxsIGJlIHhvcidlZCBmcm9tCiAgICAgKiAgICAgICAgICB0aGlzIHNldC4KICAgICAqLwogICAgdmlydHVhbCB2b2lkIGNvbXBsZW1lbnRBbGwoY29uc3QgVW5pY29kZVNldCYgYyk7CgogICAgLyoqCiAgICAgKiBSZW1vdmVzIGFsbCBvZiB0aGUgZWxlbWVudHMgZnJvbSB0aGlzIHNldC4gIFRoaXMgc2V0IHdpbGwgYmUKICAgICAqIGVtcHR5IGFmdGVyIHRoaXMgY2FsbCByZXR1cm5zLgogICAgICogQGRyYWZ0CiAgICAgKi8KICAgIHZpcnR1YWwgdm9pZCBjbGVhcih2b2lkKTsKCiAgICAvKioKICAgICAqIEl0ZXJhdGlvbiBtZXRob2QgdGhhdCByZXR1cm5zIHRoZSBudW1iZXIgb2YgcmFuZ2VzIGNvbnRhaW5lZCBpbgogICAgICogdGhpcyBzZXQuCiAgICAgKiBAc2VlICNnZXRSYW5nZVN0YXJ0CiAgICAgKiBAc2VlICNnZXRSYW5nZUVuZAogICAgICovCiAgICB2aXJ0dWFsIGludDMyX3QgZ2V0UmFuZ2VDb3VudCh2b2lkKSBjb25zdDsKCiAgICAvKioKICAgICAqIEl0ZXJhdGlvbiBtZXRob2QgdGhhdCByZXR1cm5zIHRoZSBmaXJzdCBjaGFyYWN0ZXIgaW4gdGhlCiAgICAgKiBzcGVjaWZpZWQgcmFuZ2Ugb2YgdGhpcyBzZXQuCiAgICAgKiBAc2VlICNnZXRSYW5nZUNvdW50CiAgICAgKiBAc2VlICNnZXRSYW5nZUVuZAogICAgICovCiAgICB2aXJ0dWFsIFVDaGFyMzIgZ2V0UmFuZ2VTdGFydChpbnQzMl90IGluZGV4KSBjb25zdDsKCiAgICAvKioKICAgICAqIEl0ZXJhdGlvbiBtZXRob2QgdGhhdCByZXR1cm5zIHRoZSBsYXN0IGNoYXJhY3RlciBpbiB0aGUKICAgICAqIHNwZWNpZmllZCByYW5nZSBvZiB0aGlzIHNldC4KICAgICAqIEBzZWUgI2dldFJhbmdlU3RhcnQKICAgICAqIEBzZWUgI2dldFJhbmdlRW5kCiAgICAgKi8KICAgIHZpcnR1YWwgVUNoYXIzMiBnZXRSYW5nZUVuZChpbnQzMl90IGluZGV4KSBjb25zdDsKCiAgICAvKioKICAgICAqIFJlYWxsb2NhdGUgdGhpcyBvYmplY3RzIGludGVybmFsIHN0cnVjdHVyZXMgdG8gdGFrZSB1cCB0aGUgbGVhc3QKICAgICAqIHBvc3NpYmxlIHNwYWNlLCB3aXRob3V0IGNoYW5naW5nIHRoaXMgb2JqZWN0J3MgdmFsdWUuCiAgICAgKi8KICAgIHZpcnR1YWwgdm9pZCBjb21wYWN0KCk7Cgpwcml2YXRlOgoKICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgLy8gUnVsZUJhc2VkVHJhbnNsaXRlcmF0b3Igc3VwcG9ydAogICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgZnJpZW5kIGNsYXNzIFRyYW5zbGl0ZXJhdGlvblJ1bGVQYXJzZXI7CiAgICBmcmllbmQgY2xhc3MgVHJhbnNsaXRlcmF0aW9uUnVsZTsKCiAgICAvKioKICAgICAqIENvbnN0cnVjdHMgYSBzZXQgZnJvbSB0aGUgZ2l2ZW4gcGF0dGVybi4gIFNlZSB0aGUgY2xhc3MgZGVzY3JpcHRpb24KICAgICAqIGZvciB0aGUgc3ludGF4IG9mIHRoZSBwYXR0ZXJuIGxhbmd1YWdlLgoKICAgICAqIEBwYXJhbSBwYXR0ZXJuIGEgc3RyaW5nIHNwZWNpZnlpbmcgd2hhdCBjaGFyYWN0ZXJzIGFyZSBpbiB0aGUgc2V0CiAgICAgKiBAcGFyYW0gcG9zIG9uIGlucHV0LCB0aGUgcG9zaXRpb24gaW4gcGF0dGVybiBhdCB3aGljaCB0byBzdGFydCBwYXJzaW5nLgogICAgICogT24gb3V0cHV0LCB0aGUgcG9zaXRpb24gYWZ0ZXIgdGhlIGxhc3QgY2hhcmFjdGVyIHBhcnNlZC4KICAgICAqIEBwYXJhbSB2YXJOYW1lVG9DaGFyIGEgbWFwcGluZyBmcm9tIHZhcmlhYmxlIG5hbWVzIChTdHJpbmcpIHRvIGNoYXJhY3RlcnMKICAgICAqIChDaGFyYWN0ZXIpLiAgTWF5IGJlIG51bGwuICBJZiB2YXJDaGFyVG9TZXQgaXMgbm9uLW51bGwsIHRoZW4gbmFtZXMgbWF5CiAgICAgKiBtYXAgdG8gZWl0aGVyIHNpbmdsZSBjaGFyYWN0ZXJzIG9yIHNldHMsIGRlcGVuZGluZyBvbiB3aGV0aGVyIGEgbWFwcGluZwogICAgICogZXhpc3RzIGluIHZhckNoYXJUb1NldC4gIElmIHZhckNoYXJUb1NldCBpcyBudWxsIHRoZW4gYWxsIG5hbWVzIG1hcCB0bwogICAgICogc2luZ2xlIGNoYXJhY3RlcnMuCiAgICAgKiBAcGFyYW0gdmFyQ2hhclRvU2V0IGEgbWFwcGluZyBmcm9tIGNoYXJhY3RlcnMgKENoYXJhY3RlciBvYmplY3RzIGZyb20KICAgICAqIHZhck5hbWVUb0NoYXIpIHRvIFVuaWNvZGVTZXQgb2JqZWN0cy4gIE1heSBiZSBudWxsLiAgSXMgb25seSB1c2VkIGlmCiAgICAgKiB2YXJOYW1lVG9DaGFyIGlzIGFsc28gbm9uLW51bGwuCiAgICAgKiBAZXhjZXB0aW9uIDxjb2RlPklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbjwvY29kZT4gaWYgdGhlIHBhdHRlcm4KICAgICAqIGNvbnRhaW5zIGEgc3ludGF4IGVycm9yLgogICAgICovCiAgICBVbmljb2RlU2V0KGNvbnN0IFVuaWNvZGVTdHJpbmcmIHBhdHRlcm4sIFBhcnNlUG9zaXRpb24mIHBvcywKICAgICAgICAgICAgICAgY29uc3QgU3ltYm9sVGFibGUmIHN5bWJvbHMsCiAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cyk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIDx0dD50cnVlPC90dD4gaWYgdGhpcyBzZXQgY29udGFpbnMgYW55IGNoYXJhY3RlciB3aG9zZSBsb3cgYnl0ZQogICAgICogaXMgdGhlIGdpdmVuIHZhbHVlLiAgVGhpcyBpcyB1c2VkIGJ5IDx0dD5SdWxlQmFzZWRUcmFuc2xpdGVyYXRvcjwvdHQ+IGZvcgogICAgICogaW5kZXhpbmcuCiAgICAgKi8KICAgIFVCb29sIGNvbnRhaW5zSW5kZXhWYWx1ZSh1aW50OF90IHYpIGNvbnN0OwoKcHJpdmF0ZToKCiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgIC8vIEltcGxlbWVudGF0aW9uOiBQYXR0ZXJuIHBhcnNpbmcKICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIC8qKgogICAgICogUGFyc2VzIHRoZSBnaXZlbiBwYXR0ZXJuLCBzdGFydGluZyBhdCB0aGUgZ2l2ZW4gcG9zaXRpb24uICBUaGUKICAgICAqIGNoYXJhY3RlciBhdCBwYXR0ZXJuLmNoYXJBdChwb3MuZ2V0SW5kZXgoKSkgbXVzdCBiZSAnWycsIG9yIHRoZQogICAgICogcGFyc2UgZmFpbHMuICBQYXJzaW5nIGNvbnRpbnVlcyB1bnRpbCB0aGUgY29ycmVzcG9uZGluZyBjbG9zaW5nCiAgICAgKiAnXScuICBJZiBhIHN5bnRheCBlcnJvciBpcyBlbmNvdW50ZXJlZCBiZXR3ZWVuIHRoZSBvcGVuaW5nIGFuZAogICAgICogY2xvc2luZyBicmFjZSwgdGhlIHBhcnNlIGZhaWxzLiAgVXBvbiByZXR1cm4gZnJvbSBhIHN1Y2Nlc3NmdWwKICAgICAqIHBhcnNlLCB0aGUgUGFyc2VQb3NpdGlvbiBpcyB1cGRhdGVkIHRvIHBvaW50IHRvIHRoZSBjaGFyYWN0ZXIKICAgICAqIGZvbGxvd2luZyB0aGUgY2xvc2luZyAnXScsIGFuZCBhIFN0cmluZ0J1ZmZlciBjb250YWluaW5nIGEKICAgICAqIHBhaXJzIGxpc3QgZm9yIHRoZSBwYXJzZWQgcGF0dGVybiBpcyByZXR1cm5lZC4gIFRoaXMgbWV0aG9kIGNhbGxzCiAgICAgKiBpdHNlbGYgcmVjdXJzaXZlbHkgdG8gcGFyc2UgZW1iZWRkZWQgc3VicGF0dGVybnMuCiAgICAgKgogICAgICogQHBhcmFtIHBhdHRlcm4gdGhlIHN0cmluZyBjb250YWluaW5nIHRoZSBwYXR0ZXJuIHRvIGJlIHBhcnNlZC4KICAgICAqIFRoZSBwb3J0aW9uIG9mIHRoZSBzdHJpbmcgZnJvbSBwb3MuZ2V0SW5kZXgoKSwgd2hpY2ggbXVzdCBiZSBhCiAgICAgKiAnWycsIHRvIHRoZSBjb3JyZXNwb25kaW5nIGNsb3NpbmcgJ10nLCBpcyBwYXJzZWQuCiAgICAgKiBAcGFyYW0gcG9zIHVwb24gZW50cnksIHRoZSBwb3NpdGlvbiBhdCB3aGljaCB0byBiZWluZyBwYXJzaW5nLgogICAgICogVGhlIGNoYXJhY3RlciBhdCBwYXR0ZXJuLmNoYXJBdChwb3MuZ2V0SW5kZXgoKSkgbXVzdCBiZSBhICdbJy4KICAgICAqIFVwb24gcmV0dXJuIGZyb20gYSBzdWNjZXNzZnVsIHBhcnNlLCBwb3MuZ2V0SW5kZXgoKSBpcyBlaXRoZXIKICAgICAqIHRoZSBjaGFyYWN0ZXIgYWZ0ZXIgdGhlIGNsb3NpbmcgJ10nIG9mIHRoZSBwYXJzZWQgcGF0dGVybiwgb3IKICAgICAqIHBhdHRlcm4ubGVuZ3RoKCkgaWYgdGhlIGNsb3NpbmcgJ10nIGlzIHRoZSBsYXN0IGNoYXJhY3RlciBvZgogICAgICogdGhlIHBhdHRlcm4gc3RyaW5nLgogICAgICogQHJldHVybiBhIFN0cmluZ0J1ZmZlciBjb250YWluaW5nIGEgcGFpcnMgbGlzdCBmb3IgdGhlIHBhcnNlZAogICAgICogc3Vic3RyaW5nIG9mIDxjb2RlPnBhdHRlcm48L2NvZGU+CiAgICAgKiBAZXhjZXB0aW9uIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB0aGUgcGFyc2UgZmFpbHMuCiAgICAgKi8KICAgIHZvaWQgYXBwbHlQYXR0ZXJuKGNvbnN0IFVuaWNvZGVTdHJpbmcmIHBhdHRlcm4sCiAgICAgICAgICAgICAgICAgICAgICBQYXJzZVBvc2l0aW9uJiBwb3MsCiAgICAgICAgICAgICAgICAgICAgICBjb25zdCBTeW1ib2xUYWJsZSogc3ltYm9scywKICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cyk7CgogICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAvLyBJbXBsZW1lbnRhdGlvbjogR2VuZXJhdGlvbiBvZiBwYWlycyBmb3IgVW5pY29kZSBjYXRlZ29yaWVzCiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICAvKioKICAgICAqIFNldHMgdGhpcyBvYmplY3QgdG8gdGhlIGdpdmVuIGNhdGVnb3J5LCBnaXZlbiBpdHMgbmFtZS4KICAgICAqIFRoZSBjYXRlZ29yeSBuYW1lIG11c3QgYmUgZWl0aGVyIGEgdHdvLWxldHRlciBuYW1lLCBzdWNoIGFzCiAgICAgKiAiTHUiLCBvciBhIG9uZSBsZXR0ZXIgbmFtZSwgc3VjaCBhcyAiTCIuICBPbmUtbGV0dGVyIG5hbWVzCiAgICAgKiBpbmRpY2F0ZSB0aGUgbG9naWNhbCB1bmlvbiBvZiBhbGwgdHdvLWxldHRlciBuYW1lcyB0aGF0IHN0YXJ0CiAgICAgKiB3aXRoIHRoYXQgbGV0dGVyLiAgQ2FzZSBpcyBzaWduaWZpY2FudC4gIElmIHRoZSBuYW1lIHN0YXJ0cwogICAgICogd2l0aCB0aGUgY2hhcmFjdGVyICdeJyB0aGVuIHRoZSBjb21wbGVtZW50IG9mIHRoZSBnaXZlbgogICAgICogY2hhcmFjdGVyIHNldCBpcyByZXR1cm5lZC4KICAgICAqCiAgICAgKiBBbHRob3VnaCBpbmRpdmlkdWFsIGNhdGVnb3JpZXMgc3VjaCBhcyAiTHUiIGFyZSBjYWNoZWQsIHdlIGRvCiAgICAgKiBub3QgY3VycmVudGx5IGNhY2hlIHNpbmdsZS1sZXR0ZXIgY2F0ZWdvcmllcyBzdWNoIGFzICJMIiBvcgogICAgICogY29tcGxlbWVudHMgc3VjaCBhcyAiXkx1IiBvciAiXkwiLiAgSXQgd291bGQgYmUgZWFzeSB0byBjYWNoZQogICAgICogdGhlc2UgYXMgd2VsbCBpbiBhIGhhc2h0YWJsZSBzaG91bGQgdGhlIG5lZWQgYXJpc2UuCiAgICAgKi8KICAgIHZvaWQgYXBwbHlDYXRlZ29yeShjb25zdCBVbmljb2RlU3RyaW5nJiBjYXROYW1lLAogICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cyk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGEgcGFpcnMgc3RyaW5nIGZvciB0aGUgZ2l2ZW4gY2F0ZWdvcnkuICBUaGlzIHN0cmluZyBpcwogICAgICogY2FjaGVkIGFuZCByZXR1cm5lZCBhZ2FpbiBpZiB0aGlzIG1ldGhvZCBpcyBjYWxsZWQgYWdhaW4gd2l0aAogICAgICogdGhlIHNhbWUgcGFyYW1ldGVyLgogICAgICovCiAgICBzdGF0aWMgY29uc3QgVW5pY29kZVNldCYgZ2V0Q2F0ZWdvcnlTZXQoaW50OF90IGNhdCk7CgogICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAvLyBJbXBsZW1lbnRhdGlvbjogVXRpbGl0eSBtZXRob2RzCiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGNoYXJhY3RlciBhZnRlciB0aGUgZ2l2ZW4gcG9zaXRpb24sIG9yICdcdUZGRkUnIGlmCiAgICAgKiB0aGVyZSBpcyBub25lLgogICAgICovCiAgICBzdGF0aWMgVUNoYXIgY2hhckFmdGVyKGNvbnN0IFVuaWNvZGVTdHJpbmcmIHN0ciwgaW50MzJfdCBpKTsKCiAgICB2b2lkIGVuc3VyZUNhcGFjaXR5KGludDMyX3QgbmV3TGVuKTsKICAgIAogICAgdm9pZCBlbnN1cmVCdWZmZXJDYXBhY2l0eShpbnQzMl90IG5ld0xlbik7CiAgICAKICAgIHZvaWQgc3dhcEJ1ZmZlcnModm9pZCk7CgogICAgc3RhdGljIGNvbnN0IFVDaGFyIEhFWFsxNl07CiAgICAKICAgIHN0YXRpYyB2b2lkIF90b1BhdChVbmljb2RlU3RyaW5nJiBidWYsIFVDaGFyMzIgYyk7CgogICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAvLyBJbXBsZW1lbnRhdGlvbjogRnVuZGFtZW50YWwgb3BlcmF0b3JzCiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICB2b2lkIGV4Y2x1c2l2ZU9yKGNvbnN0IFVDaGFyMzIqIG90aGVyLCBpbnQzMl90IG90aGVyTGVuLCBpbnQ4X3QgcG9sYXJpdHkpOwogICAgICAgIAogICAgdm9pZCBhZGQoY29uc3QgVUNoYXIzMiogb3RoZXIsIGludDMyX3Qgb3RoZXJMZW4sIGludDhfdCBwb2xhcml0eSk7CiAgICAgICAgICAgIAogICAgdm9pZCByZXRhaW4oY29uc3QgVUNoYXIzMiogb3RoZXIsIGludDMyX3Qgb3RoZXJMZW4sIGludDhfdCBwb2xhcml0eSk7Cn07CgppbmxpbmUgVUJvb2wgVW5pY29kZVNldDo6b3BlcmF0b3IhPShjb25zdCBVbmljb2RlU2V0JiBvKSBjb25zdCB7CglyZXR1cm4gIW9wZXJhdG9yPT0obyk7Cn0KCiNlbmRpZgo=