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+CiAqIE5vcm1hdGl2ZQogKiAgICAgTW4gPSBNYXJrLCBOb24tU3BhY2luZwogKiAgICAgTWMgPSBNYXJrLCBTcGFjaW5nIENvbWJpbmluZwogKiAgICAgTWUgPSBNYXJrLCBFbmNsb3NpbmcKICogCiAqICAgICBOZCA9IE51bWJlciwgRGVjaW1hbCBEaWdpdAogKiAgICAgTmwgPSBOdW1iZXIsIExldHRlcgogKiAgICAgTm8gPSBOdW1iZXIsIE90aGVyCiAqIAogKiAgICAgWnMgPSBTZXBhcmF0b3IsIFNwYWNlCiAqICAgICBabCA9IFNlcGFyYXRvciwgTGluZQogKiAgICAgWnAgPSBTZXBhcmF0b3IsIFBhcmFncmFwaAogKiAKICogICAgIENjID0gT3RoZXIsIENvbnRyb2wKICogICAgIENmID0gT3RoZXIsIEZvcm1hdAogKiAgICAgQ3MgPSBPdGhlciwgU3Vycm9nYXRlCiAqICAgICBDbyA9IE90aGVyLCBQcml2YXRlIFVzZQogKiAgICAgQ24gPSBPdGhlciwgTm90IEFzc2lnbmVkCiAqIAogKiBJbmZvcm1hdGl2ZQogKiAgICAgTHUgPSBMZXR0ZXIsIFVwcGVyY2FzZQogKiAgICAgTGwgPSBMZXR0ZXIsIExvd2VyY2FzZQogKiAgICAgTHQgPSBMZXR0ZXIsIFRpdGxlY2FzZQogKiAgICAgTG0gPSBMZXR0ZXIsIE1vZGlmaWVyCiAqICAgICBMbyA9IExldHRlciwgT3RoZXIKICogCiAqICAgICBQYyA9IFB1bmN0dWF0aW9uLCBDb25uZWN0b3IKICogICAgIFBkID0gUHVuY3R1YXRpb24sIERhc2gKICogICAgIFBzID0gUHVuY3R1YXRpb24sIE9wZW4KICogICAgIFBlID0gUHVuY3R1YXRpb24sIENsb3NlCiAqICAgICBQaSA9IFB1bmN0dWF0aW9uLCBJbml0aWFsIHF1b3RlCiAqICAgICBQZiA9IFB1bmN0dWF0aW9uLCBGaW5hbCBxdW90ZQogKiAgICAgUG8gPSBQdW5jdHVhdGlvbiwgT3RoZXIKICogCiAqICAgICBTbSA9IFN5bWJvbCwgTWF0aAogKiAgICAgU2MgPSBTeW1ib2wsIEN1cnJlbmN5CiAqICAgICBTayA9IFN5bWJvbCwgTW9kaWZpZXIKICogICAgIFNvID0gU3ltYm9sLCBPdGhlcgogKiA8L3ByZT4KICoKICogQGF1dGhvciBBbGFuIExpdQogKiBAZHJhZnQKICovCmNsYXNzIFVfSTE4Tl9BUEkgVW5pY29kZVNldCA6IHB1YmxpYyBVbmljb2RlRmlsdGVyIHsKCiAgICAvKioKICAgICAqIFRoZSBpbnRlcm5hbCByZXByZXNlbnRhdGlvbiBpcyBhIFVuaWNvZGVTdHJpbmcgb2YgZXZlbiBsZW5ndGguCiAgICAgKiBFYWNoIHBhaXIgb2YgY2hhcmFjdGVycyByZXByZXNlbnRzIGEgcmFuZ2UgdGhhdCBpcyBpbmNsdWRlZCBpbgogICAgICogdGhlIHNldC4gIEEgc2luZ2xlIGNoYXJhY3RlciBjIGlzIHJlcHJlc2VudGVkIGFzIGNjLiAgVGh1cywgdGhlCiAgICAgKiByYW5nZXMgaW4gdGhlIHNldCBhcmUgKGEsYiksIGEgYW5kIGIgaW5jbHVzaXZlLCB3aGVyZSBhID0KICAgICAqIHBhaXJzLmNoYXJBdChpKSBhbmQgYiA9IHBhaXJzLmNoYXJBdChpKzEpIGZvciBhbGwgZXZlbiBpLCAwIDw9CiAgICAgKiBpIDw9IHBhaXJzLmxlbmd0aCgpLTIuICBQYWlycyBhcmUgYWx3YXlzIHN0b3JlZCBpbiBhc2NlbmRpbmcKICAgICAqIFVuaWNvZGUgb3JkZXIuICBQYWlycyBhcmUgYWx3YXlzIHN0b3JlZCBpbiBzaG9ydGVzdCBmb3JtLiAgRm9yCiAgICAgKiBleGFtcGxlLCBpZiB0aGUgcGFpciAiaGgiLCByZXByZXNlbnRpbmcgdGhlIHNpbmdsZSBjaGFyYWN0ZXIKICAgICAqICdoJywgaXMgYWRkZWQgdG8gdGhlIHBhaXJzIGxpc3QgImFnaWsiLCByZXByZXNlbnRpbmcgdGhlIHJhbmdlcwogICAgICogJ2EnLSdnJyBhbmQgJ2knLSdrJywgdGhlIHJlc3VsdCBpcyAiYWsiLCBub3QgImFnaGhpayIuCiAgICAgKi8KICAgIFVuaWNvZGVTdHJpbmcgcGFpcnM7CgogICAgc3RhdGljIGNvbnN0IFVuaWNvZGVTdHJpbmcgQ0FURUdPUllfTkFNRVM7CgogICAgLyoqCiAgICAgKiBBIGNhY2hlIG1hcHBpbmcgY2hhcmFjdGVyIGNhdGVnb3J5IGludGVnZXJzLCBhcyByZXR1cm5lZCBieQogICAgICogVW5pY29kZTo6Z2V0VHlwZSgpLCB0byBwYWlycyBzdHJpbmdzLiAgRW50cmllcyBhcmUgaW5pdGlhbGx5CiAgICAgKiB6ZXJvIGxlbmd0aCBhbmQgYXJlIGZpbGxlZCBpbiBvbiBkZW1hbmQuCiAgICAgKi8KICAgIHN0YXRpYyBVbmljb2RlU3RyaW5nKiBDQVRFR09SWV9QQUlSU19DQUNIRTsKCiAgICAvKioKICAgICAqIERlbGltaXRlciBzdHJpbmcgdXNlZCBpbiBwYXR0ZXJucyB0byBjbG9zZSBhIGNhdGVnb3J5IHJlZmVyZW5jZToKICAgICAqICI6XSIuICBFeGFtcGxlOiAiWzpMdTpdIi4KICAgICAqLwogICAgc3RhdGljIGNvbnN0IFVuaWNvZGVTdHJpbmcgQ0FURUdPUllfQ0xPU0U7CgogICAgLyoqCiAgICAgKiBEZWxpbWl0ZXIgY2hhciBiZWdpbm5pbmcgYSB2YXJpYWJsZSByZWZlcmVuY2U6CiAgICAgKiAieyIuICBFeGFtcGxlOiAie3Zhcn0iLgogICAgICovCiAgICBzdGF0aWMgY29uc3QgVUNoYXIgVkFSSUFCTEVfUkVGX09QRU47CiAgICAKICAgIC8qKgogICAgICogRGVsaW1pdGVyIGNoYXIgZW5kaW5nIGEgdmFyaWFibGUgcmVmZXJlbmNlOgogICAgICogIn0iLiAgRXhhbXBsZTogInt2YXJ9Ii4KICAgICAqLwogICAgc3RhdGljIGNvbnN0IFVDaGFyIFZBUklBQkxFX1JFRl9DTE9TRTsKICAgIAogICAgLy8gTW9yZSBzcGVjaWFsIGNoYXJhY3RlcnMuLi4KICAgIHN0YXRpYyBjb25zdCBVQ2hhciBTRVRfT1BFTjsKICAgIHN0YXRpYyBjb25zdCBVQ2hhciBTRVRfQ0xPU0U7CiAgICBzdGF0aWMgY29uc3QgVUNoYXIgSFlQSEVOOwogICAgc3RhdGljIGNvbnN0IFVDaGFyIENPTVBMRU1FTlQ7CiAgICBzdGF0aWMgY29uc3QgVUNoYXIgQ09MT047CiAgICBzdGF0aWMgY29uc3QgVUNoYXIgQkFDS1NMQVNIOwogICAgc3RhdGljIGNvbnN0IFVDaGFyIElOVEVSU0VDVElPTjsKICAgIAogICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAvLyBEZWJ1Z2dpbmcgYW5kIHRlc3RpbmcKICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKcHVibGljOgoKICAgIC8qKgogICAgICogUmV0dXJuIHRoZSByZXByZXNlbnRhdGlvbiBvZiB0aGlzIHNldCBhcyBhIGxpc3Qgb2YgY2hhcmFjdGVyCiAgICAgKiByYW5nZXMuICBSYW5nZXMgYXJlIGxpc3RlZCBpbiBhc2NlbmRpbmcgVW5pY29kZSBvcmRlci4gIEZvcgogICAgICogZXhhbXBsZSwgdGhlIHNldCBbYS16QS1NM10gaXMgcmVwcmVzZW50ZWQgYXMgIjMzQU1heiIuCiAgICAgKi8KICAgIGNvbnN0IFVuaWNvZGVTdHJpbmcmIGdldFBhaXJzKHZvaWQpIGNvbnN0OwoKICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgLy8gQ29uc3RydWN0b3JzICZjCiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCnB1YmxpYzoKCiAgICAvKioKICAgICAqIENvbnN0cnVjdHMgYW4gZW1wdHkgc2V0LgogICAgICogQGRyYWZ0CiAgICAgKi8KICAgIFVuaWNvZGVTZXQoKTsKCiAgICAvKioKICAgICAqIENvbnN0cnVjdHMgYSBzZXQgZnJvbSB0aGUgZ2l2ZW4gcGF0dGVybi4gIFNlZSB0aGUgY2xhc3MKICAgICAqIGRlc2NyaXB0aW9uIGZvciB0aGUgc3ludGF4IG9mIHRoZSBwYXR0ZXJuIGxhbmd1YWdlLgogICAgICogQHBhcmFtIHBhdHRlcm4gYSBzdHJpbmcgc3BlY2lmeWluZyB3aGF0IGNoYXJhY3RlcnMgYXJlIGluIHRoZSBzZXQKICAgICAqIEBleGNlcHRpb24gPGNvZGU+SWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uPC9jb2RlPiBpZiB0aGUgcGF0dGVybgogICAgICogY29udGFpbnMgYSBzeW50YXggZXJyb3IuCiAgICAgKiBAZHJhZnQKICAgICAqLwogICAgVW5pY29kZVNldChjb25zdCBVbmljb2RlU3RyaW5nJiBwYXR0ZXJuLAogICAgICAgICAgICAgICBVRXJyb3JDb2RlJiBzdGF0dXMpOwoKICAgIC8qKgogICAgICogQ29uc3RydWN0cyBhIHNldCBmcm9tIHRoZSBnaXZlbiBVbmljb2RlIGNoYXJhY3RlciBjYXRlZ29yeS4KICAgICAqIEBwYXJhbSBjYXRlZ29yeSBhbiBpbnRlZ2VyIGluZGljYXRpbmcgdGhlIGNoYXJhY3RlciBjYXRlZ29yeSBhcwogICAgICogcmV0dXJuZWQgYnkgPGNvZGU+Q2hhcmFjdGVyLmdldFR5cGUoKTwvY29kZT4uCiAgICAgKiBAZXhjZXB0aW9uIDxjb2RlPklsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbjwvY29kZT4gaWYgdGhlIGdpdmVuCiAgICAgKiBjYXRlZ29yeSBpcyBpbnZhbGlkLgogICAgICogQGRyYWZ0CiAgICAgKi8KICAgIFVuaWNvZGVTZXQoaW50OF90IGNhdGVnb3J5LCBVRXJyb3JDb2RlJiBzdGF0dXMpOwoKICAgIC8qKgogICAgICogQ29uc3RydWN0cyBhIHNldCB0aGF0IGlzIGlkZW50aWNhbCB0byB0aGUgZ2l2ZW4gVW5pY29kZVNldC4KICAgICAqIEBkcmFmdAogICAgICovCiAgICBVbmljb2RlU2V0KGNvbnN0IFVuaWNvZGVTZXQmIG8pOwoKICAgIC8qKgogICAgICogRGVzdHJ1Y3RzIHRoZSBzZXQuCiAgICAgKiBAZHJhZnQKICAgICAqLwogICAgdmlydHVhbCB+VW5pY29kZVNldCgpOwoKICAgIC8qKgogICAgICogQXNzaWducyB0aGlzIG9iamVjdCB0byBiZSBhIGNvcHkgb2YgYW5vdGhlci4KICAgICAqIEBkcmFmdAogICAgICovCiAgICBVbmljb2RlU2V0JiBvcGVyYXRvcj0oY29uc3QgVW5pY29kZVNldCYgbyk7CgogICAgLyoqCiAgICAgKiBDb21wYXJlcyB0aGUgc3BlY2lmaWVkIG9iamVjdCB3aXRoIHRoaXMgc2V0IGZvciBlcXVhbGl0eS4gIFJldHVybnMKICAgICAqIDx0dD50cnVlPC90dD4gaWYgdGhlIHR3byBzZXRzCiAgICAgKiBoYXZlIHRoZSBzYW1lIHNpemUsIGFuZCBldmVyeSBtZW1iZXIgb2YgdGhlIHNwZWNpZmllZCBzZXQgaXMKICAgICAqIGNvbnRhaW5lZCBpbiB0aGlzIHNldCAob3IgZXF1aXZhbGVudGx5LCBldmVyeSBtZW1iZXIgb2YgdGhpcyBzZXQgaXMKICAgICAqIGNvbnRhaW5lZCBpbiB0aGUgc3BlY2lmaWVkIHNldCkuCiAgICAgKgogICAgICogQHBhcmFtIG8gc2V0IHRvIGJlIGNvbXBhcmVkIGZvciBlcXVhbGl0eSB3aXRoIHRoaXMgc2V0LgogICAgICogQHJldHVybiA8dHQ+dHJ1ZTwvdHQ+IGlmIHRoZSBzcGVjaWZpZWQgc2V0IGlzIGVxdWFsIHRvIHRoaXMgc2V0LgogICAgICogQGRyYWZ0CiAgICAgKi8KICAgIHZpcnR1YWwgYm9vbF90IG9wZXJhdG9yPT0oY29uc3QgVW5pY29kZVNldCYgbykgY29uc3Q7CgogICAgLyoqCiAgICAgKiBDb21wYXJlcyB0aGUgc3BlY2lmaWVkIG9iamVjdCB3aXRoIHRoaXMgc2V0IGZvciBlcXVhbGl0eS4gIFJldHVybnMKICAgICAqIDx0dD50cnVlPC90dD4gaWYgdGhlIHNwZWNpZmllZCBzZXQgaXMgbm90IGVxdWFsIHRvIHRoaXMgc2V0LgogICAgICogQGRyYWZ0CiAgICAgKi8KICAgIGJvb2xfdCBvcGVyYXRvciE9KGNvbnN0IFVuaWNvZGVTZXQmIG8pIGNvbnN0OwoKICAgIC8qKgogICAgICogUmV0dXJucyBhIGNvcHkgb2YgdGhpcyBvYmplY3QuICBBbGwgVW5pY29kZUZpbHRlciBvYmplY3RzIGhhdmUKICAgICAqIHRvIHN1cHBvcnQgY2xvbmluZyBpbiBvcmRlciB0byBhbGxvdyBjbGFzc2VzIHVzaW5nCiAgICAgKiBVbmljb2RlRmlsdGVycywgc3VjaCBhcyBUcmFuc2xpdGVyYXRvciwgdG8gaW1wbGVtZW50IGNsb25pbmcuCiAgICAgKiBAZHJhZnQKICAgICAqLwogICAgdmlydHVhbCBVbmljb2RlRmlsdGVyKiBjbG9uZSgpIGNvbnN0OwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgaGFzaCBjb2RlIHZhbHVlIGZvciB0aGlzIHNldC4KICAgICAqCiAgICAgKiBAcmV0dXJuIHRoZSBoYXNoIGNvZGUgdmFsdWUgZm9yIHRoaXMgc2V0LgogICAgICogQHNlZSBPYmplY3QjaGFzaENvZGUoKQogICAgICogQGRyYWZ0CiAgICAgKi8KICAgIHZpcnR1YWwgaW50MzJfdCBoYXNoQ29kZSh2b2lkKSBjb25zdDsKCiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgIC8vIFB1YmxpYyBBUEkKICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIC8qKgogICAgICogTW9kaWZpZXMgdGhpcyBzZXQgdG8gcmVwcmVzZW50IHRoZSBzZXQgc3BlY2lmaWVkIGJ5IHRoZSBnaXZlbgogICAgICogcGF0dGVybiwgb3B0aW9uYWxseSBpZ25vcmluZyB3aGl0ZSBzcGFjZS4gIFNlZSB0aGUgY2xhc3MKICAgICAqIGRlc2NyaXB0aW9uIGZvciB0aGUgc3ludGF4IG9mIHRoZSBwYXR0ZXJuIGxhbmd1YWdlLgogICAgICogQHBhcmFtIHBhdHRlcm4gYSBzdHJpbmcgc3BlY2lmeWluZyB3aGF0IGNoYXJhY3RlcnMgYXJlIGluIHRoZSBzZXQKICAgICAqIEBleGNlcHRpb24gPGNvZGU+SWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uPC9jb2RlPiBpZiB0aGUgcGF0dGVybgogICAgICogY29udGFpbnMgYSBzeW50YXggZXJyb3IuCiAgICAgKiBAZHJhZnQKICAgICAqLwogICAgdmlydHVhbCB2b2lkIGFwcGx5UGF0dGVybihjb25zdCBVbmljb2RlU3RyaW5nJiBwYXR0ZXJuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiBzdGF0dXMpOwoKICAgIC8qKgogICAgICogUmV0dXJucyBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGlzIHNldC4gIElmIHRoZSByZXN1bHQgb2YKICAgICAqIGNhbGxpbmcgdGhpcyBmdW5jdGlvbiBpcyBwYXNzZWQgdG8gYSBVbmljb2RlU2V0IGNvbnN0cnVjdG9yLCBpdAogICAgICogd2lsbCBwcm9kdWNlIGFub3RoZXIgc2V0IHRoYXQgaXMgZXF1YWwgdG8gdGhpcyBvbmUuCiAgICAgKiBAZHJhZnQKICAgICAqLwogICAgdmlydHVhbCBVbmljb2RlU3RyaW5nJiB0b1BhdHRlcm4oVW5pY29kZVN0cmluZyYgcmVzdWx0KSBjb25zdDsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIG51bWJlciBvZiBlbGVtZW50cyBpbiB0aGlzIHNldCAoaXRzIGNhcmRpbmFsaXR5KSwKICAgICAqIDxlbT5uPC9lbT4sIHdoZXJlIDxjb2RlPjAgPD0gPC9jb2RlPjxlbT5uPC9lbT48Y29kZT4gPD0gNjU1MzY8L2NvZGU+LgogICAgICoKICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBlbGVtZW50cyBpbiB0aGlzIHNldCAoaXRzIGNhcmRpbmFsaXR5KS4KICAgICAqIEBkcmFmdAogICAgICovCiAgICB2aXJ0dWFsIGludDMyX3Qgc2l6ZSh2b2lkKSBjb25zdDsKCiAgICAvKioKICAgICAqIFJldHVybnMgPHR0PnRydWU8L3R0PiBpZiB0aGlzIHNldCBjb250YWlucyBubyBlbGVtZW50cy4KICAgICAqCiAgICAgKiBAcmV0dXJuIDx0dD50cnVlPC90dD4gaWYgdGhpcyBzZXQgY29udGFpbnMgbm8gZWxlbWVudHMuCiAgICAgKiBAZHJhZnQKICAgICAqLwogICAgdmlydHVhbCBib29sX3QgaXNFbXB0eSh2b2lkKSBjb25zdDsKCiAgICAvKioKICAgICAqIFJldHVybnMgPHR0PnRydWU8L3R0PiBpZiB0aGlzIHNldCBjb250YWlucyB0aGUgc3BlY2lmaWVkIHJhbmdlCiAgICAgKiBvZiBjaGFycy4KICAgICAqCiAgICAgKiBAcmV0dXJuIDx0dD50cnVlPC90dD4gaWYgdGhpcyBzZXQgY29udGFpbnMgdGhlIHNwZWNpZmllZCByYW5nZQogICAgICogb2YgY2hhcnMuCiAgICAgKiBAZHJhZnQKICAgICAqLwogICAgdmlydHVhbCBib29sX3QgY29udGFpbnMoVUNoYXIgZmlyc3QsIFVDaGFyIGxhc3QpIGNvbnN0OwoKICAgIC8qKgogICAgICogUmV0dXJucyA8dHQ+dHJ1ZTwvdHQ+IGlmIHRoaXMgc2V0IGNvbnRhaW5zIHRoZSBzcGVjaWZpZWQgY2hhci4KICAgICAqCiAgICAgKiBAcmV0dXJuIDx0dD50cnVlPC90dD4gaWYgdGhpcyBzZXQgY29udGFpbnMgdGhlIHNwZWNpZmllZCBjaGFyLgogICAgICogQGRyYWZ0CiAgICAgKi8KICAgIHZpcnR1YWwgYm9vbF90IGNvbnRhaW5zKFVDaGFyIGMpIGNvbnN0OwoKICAgIC8qKgogICAgICogQWRkcyB0aGUgc3BlY2lmaWVkIHJhbmdlIHRvIHRoaXMgc2V0IGlmIGl0IGlzIG5vdCBhbHJlYWR5CiAgICAgKiBwcmVzZW50LiAgSWYgdGhpcyBzZXQgYWxyZWFkeSBjb250YWlucyB0aGUgc3BlY2lmaWVkIHJhbmdlLAogICAgICogdGhlIGNhbGwgbGVhdmVzIHRoaXMgc2V0IHVuY2hhbmdlZC4gIElmIDxjb2RlPmxhc3QgPiBmaXJzdDwvY29kZT4KICAgICAqIHRoZW4gYW4gZW1wdHkgcmFuZ2UgaXMgYWRkZWQsIGxlYXZpbmcgdGhlIHNldCB1bmNoYW5nZWQuCiAgICAgKgogICAgICogQHBhcmFtIGZpcnN0IGZpcnN0IGNoYXJhY3RlciwgaW5jbHVzaXZlLCBvZiByYW5nZSB0byBiZSBhZGRlZAogICAgICogdG8gdGhpcyBzZXQuCiAgICAgKiBAcGFyYW0gbGFzdCBsYXN0IGNoYXJhY3RlciwgaW5jbHVzaXZlLCBvZiByYW5nZSB0byBiZSBhZGRlZAogICAgICogdG8gdGhpcyBzZXQuCiAgICAgKiBAZHJhZnQKICAgICAqLwogICAgdmlydHVhbCB2b2lkIGFkZChVQ2hhciBmaXJzdCwgVUNoYXIgbGFzdCk7CgogICAgLyoqCiAgICAgKiBBZGRzIHRoZSBzcGVjaWZpZWQgY2hhcmFjdGVyIHRvIHRoaXMgc2V0IGlmIGl0IGlzIG5vdCBhbHJlYWR5CiAgICAgKiBwcmVzZW50LiAgSWYgdGhpcyBzZXQgYWxyZWFkeSBjb250YWlucyB0aGUgc3BlY2lmaWVkIGNoYXJhY3RlciwKICAgICAqIHRoZSBjYWxsIGxlYXZlcyB0aGlzIHNldCB1bmNoYW5nZWQuCiAgICAgKiBAZHJhZnQKICAgICAqLwogICAgdmlydHVhbCB2b2lkIGFkZChVQ2hhciBjKTsKCiAgICAvKioKICAgICAqIFJlbW92ZXMgdGhlIHNwZWNpZmllZCByYW5nZSBmcm9tIHRoaXMgc2V0IGlmIGl0IGlzIHByZXNlbnQuCiAgICAgKiBUaGUgc2V0IHdpbGwgbm90IGNvbnRhaW4gdGhlIHNwZWNpZmllZCByYW5nZSBvbmNlIHRoZSBjYWxsCiAgICAgKiByZXR1cm5zLiAgSWYgPGNvZGU+bGFzdCA+IGZpcnN0PC9jb2RlPiB0aGVuIGFuIGVtcHR5IHJhbmdlIGlzCiAgICAgKiByZW1vdmVkLCBsZWF2aW5nIHRoZSBzZXQgdW5jaGFuZ2VkLgogICAgICogCiAgICAgKiBAcGFyYW0gZmlyc3QgZmlyc3QgY2hhcmFjdGVyLCBpbmNsdXNpdmUsIG9mIHJhbmdlIHRvIGJlIHJlbW92ZWQKICAgICAqIGZyb20gdGhpcyBzZXQuCiAgICAgKiBAcGFyYW0gbGFzdCBsYXN0IGNoYXJhY3RlciwgaW5jbHVzaXZlLCBvZiByYW5nZSB0byBiZSByZW1vdmVkCiAgICAgKiBmcm9tIHRoaXMgc2V0LgogICAgICogQGRyYWZ0CiAgICAgKi8KICAgIHZpcnR1YWwgdm9pZCByZW1vdmUoVUNoYXIgZmlyc3QsIFVDaGFyIGxhc3QpOwoKICAgIC8qKgogICAgICogUmVtb3ZlcyB0aGUgc3BlY2lmaWVkIGNoYXJhY3RlciBmcm9tIHRoaXMgc2V0IGlmIGl0IGlzIHByZXNlbnQuCiAgICAgKiBUaGUgc2V0IHdpbGwgbm90IGNvbnRhaW4gdGhlIHNwZWNpZmllZCByYW5nZSBvbmNlIHRoZSBjYWxsCiAgICAgKiByZXR1cm5zLgogICAgICogQGRyYWZ0CiAgICAgKi8KICAgIHZpcnR1YWwgdm9pZCByZW1vdmUoVUNoYXIgYyk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIDx0dD50cnVlPC90dD4gaWYgdGhlIHNwZWNpZmllZCBzZXQgaXMgYSA8aT5zdWJzZXQ8L2k+CiAgICAgKiBvZiB0aGlzIHNldC4KICAgICAqCiAgICAgKiBAcGFyYW0gYyBzZXQgdG8gYmUgY2hlY2tlZCBmb3IgY29udGFpbm1lbnQgaW4gdGhpcyBzZXQuCiAgICAgKiBAcmV0dXJuIDx0dD50cnVlPC90dD4gaWYgdGhpcyBzZXQgY29udGFpbnMgYWxsIG9mIHRoZSBlbGVtZW50cyBvZiB0aGUKICAgICAqIAkgICAgICAgc3BlY2lmaWVkIHNldC4KICAgICAqIEBkcmFmdAogICAgICovCiAgICB2aXJ0dWFsIGJvb2xfdCBjb250YWluc0FsbChjb25zdCBVbmljb2RlU2V0JiBjKSBjb25zdDsKCiAgICAvKioKICAgICAqIEFkZHMgYWxsIG9mIHRoZSBlbGVtZW50cyBpbiB0aGUgc3BlY2lmaWVkIHNldCB0byB0aGlzIHNldCBpZgogICAgICogdGhleSdyZSBub3QgYWxyZWFkeSBwcmVzZW50LiAgVGhpcyBvcGVyYXRpb24gZWZmZWN0aXZlbHkKICAgICAqIG1vZGlmaWVzIHRoaXMgc2V0IHNvIHRoYXQgaXRzIHZhbHVlIGlzIHRoZSA8aT51bmlvbjwvaT4gb2YgdGhlIHR3bwogICAgICogc2V0cy4gIFRoZSBiZWhhdmlvciBvZiB0aGlzIG9wZXJhdGlvbiBpcyB1bnNwZWNpZmllZCBpZiB0aGUgc3BlY2lmaWVkCiAgICAgKiBjb2xsZWN0aW9uIGlzIG1vZGlmaWVkIHdoaWxlIHRoZSBvcGVyYXRpb24gaXMgaW4gcHJvZ3Jlc3MuCiAgICAgKgogICAgICogQHBhcmFtIGMgc2V0IHdob3NlIGVsZW1lbnRzIGFyZSB0byBiZSBhZGRlZCB0byB0aGlzIHNldC4KICAgICAqIEBzZWUgI2FkZChjaGFyLCBjaGFyKQogICAgICogQGRyYWZ0CiAgICAgKi8KICAgIHZpcnR1YWwgdm9pZCBhZGRBbGwoY29uc3QgVW5pY29kZVNldCYgYyk7CgogICAgLyoqCiAgICAgKiBSZXRhaW5zIG9ubHkgdGhlIGVsZW1lbnRzIGluIHRoaXMgc2V0IHRoYXQgYXJlIGNvbnRhaW5lZCBpbiB0aGUKICAgICAqIHNwZWNpZmllZCBzZXQuICBJbiBvdGhlciB3b3JkcywgcmVtb3ZlcyBmcm9tIHRoaXMgc2V0IGFsbCBvZgogICAgICogaXRzIGVsZW1lbnRzIHRoYXQgYXJlIG5vdCBjb250YWluZWQgaW4gdGhlIHNwZWNpZmllZCBzZXQuICBUaGlzCiAgICAgKiBvcGVyYXRpb24gZWZmZWN0aXZlbHkgbW9kaWZpZXMgdGhpcyBzZXQgc28gdGhhdCBpdHMgdmFsdWUgaXMKICAgICAqIHRoZSA8aT5pbnRlcnNlY3Rpb248L2k+IG9mIHRoZSB0d28gc2V0cy4KICAgICAqCiAgICAgKiBAcGFyYW0gYyBzZXQgdGhhdCBkZWZpbmVzIHdoaWNoIGVsZW1lbnRzIHRoaXMgc2V0IHdpbGwgcmV0YWluLgogICAgICogQGRyYWZ0CiAgICAgKi8KICAgIHZpcnR1YWwgdm9pZCByZXRhaW5BbGwoY29uc3QgVW5pY29kZVNldCYgYyk7CgogICAgLyoqCiAgICAgKiBSZW1vdmVzIGZyb20gdGhpcyBzZXQgYWxsIG9mIGl0cyBlbGVtZW50cyB0aGF0IGFyZSBjb250YWluZWQgaW4gdGhlCiAgICAgKiBzcGVjaWZpZWQgc2V0LiAgVGhpcyBvcGVyYXRpb24gZWZmZWN0aXZlbHkgbW9kaWZpZXMgdGhpcwogICAgICogc2V0IHNvIHRoYXQgaXRzIHZhbHVlIGlzIHRoZSA8aT5hc3ltbWV0cmljIHNldCBkaWZmZXJlbmNlPC9pPiBvZgogICAgICogdGhlIHR3byBzZXRzLgogICAgICoKICAgICAqIEBwYXJhbSBjIHNldCB0aGF0IGRlZmluZXMgd2hpY2ggZWxlbWVudHMgd2lsbCBiZSByZW1vdmVkIGZyb20KICAgICAqICAgICAgICAgIHRoaXMgc2V0LgogICAgICogQGRyYWZ0CiAgICAgKi8KICAgIHZpcnR1YWwgdm9pZCByZW1vdmVBbGwoY29uc3QgVW5pY29kZVNldCYgYyk7CgogICAgLyoqCiAgICAgKiBJbnZlcnRzIHRoaXMgc2V0LiAgVGhpcyBvcGVyYXRpb24gbW9kaWZpZXMgdGhpcyBzZXQgc28gdGhhdAogICAgICogaXRzIHZhbHVlIGlzIGl0cyBjb21wbGVtZW50LiAgVGhpcyBpcyBlcXVpdmFsZW50IHRvIHRoZSBwc2V1ZG8gY29kZToKICAgICAqIDxjb2RlPnRoaXMgPSBuZXcgQ2hhclNldCgiW1x1MDAwMC1cdUZGRkZdIikucmVtb3ZlQWxsKHRoaXMpPC9jb2RlPi4KICAgICAqIEBkcmFmdAogICAgICovCiAgICB2aXJ0dWFsIHZvaWQgY29tcGxlbWVudCh2b2lkKTsKCiAgICAvKioKICAgICAqIFJlbW92ZXMgYWxsIG9mIHRoZSBlbGVtZW50cyBmcm9tIHRoaXMgc2V0LiAgVGhpcyBzZXQgd2lsbCBiZQogICAgICogZW1wdHkgYWZ0ZXIgdGhpcyBjYWxsIHJldHVybnMuCiAgICAgKiBAZHJhZnQKICAgICAqLwogICAgdmlydHVhbCB2b2lkIGNsZWFyKHZvaWQpOwoKcHJpdmF0ZToKCiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgIC8vIFJ1bGVCYXNlZFRyYW5zbGl0ZXJhdG9yIHN1cHBvcnQKICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIGZyaWVuZCBjbGFzcyBUcmFuc2xpdGVyYXRpb25SdWxlUGFyc2VyOwogICAgZnJpZW5kIGNsYXNzIFRyYW5zbGl0ZXJhdGlvblJ1bGU7CgogICAgLyoqCiAgICAgKiBDb25zdHJ1Y3RzIGEgc2V0IGZyb20gdGhlIGdpdmVuIHBhdHRlcm4uICBTZWUgdGhlIGNsYXNzIGRlc2NyaXB0aW9uCiAgICAgKiBmb3IgdGhlIHN5bnRheCBvZiB0aGUgcGF0dGVybiBsYW5ndWFnZS4KCiAgICAgKiBAcGFyYW0gcGF0dGVybiBhIHN0cmluZyBzcGVjaWZ5aW5nIHdoYXQgY2hhcmFjdGVycyBhcmUgaW4gdGhlIHNldAogICAgICogQHBhcmFtIHBvcyBvbiBpbnB1dCwgdGhlIHBvc2l0aW9uIGluIHBhdHRlcm4gYXQgd2hpY2ggdG8gc3RhcnQgcGFyc2luZy4KICAgICAqIE9uIG91dHB1dCwgdGhlIHBvc2l0aW9uIGFmdGVyIHRoZSBsYXN0IGNoYXJhY3RlciBwYXJzZWQuCiAgICAgKiBAcGFyYW0gdmFyTmFtZVRvQ2hhciBhIG1hcHBpbmcgZnJvbSB2YXJpYWJsZSBuYW1lcyAoU3RyaW5nKSB0byBjaGFyYWN0ZXJzCiAgICAgKiAoQ2hhcmFjdGVyKS4gIE1heSBiZSBudWxsLiAgSWYgdmFyQ2hhclRvU2V0IGlzIG5vbi1udWxsLCB0aGVuIG5hbWVzIG1heQogICAgICogbWFwIHRvIGVpdGhlciBzaW5nbGUgY2hhcmFjdGVycyBvciBzZXRzLCBkZXBlbmRpbmcgb24gd2hldGhlciBhIG1hcHBpbmcKICAgICAqIGV4aXN0cyBpbiB2YXJDaGFyVG9TZXQuICBJZiB2YXJDaGFyVG9TZXQgaXMgbnVsbCB0aGVuIGFsbCBuYW1lcyBtYXAgdG8KICAgICAqIHNpbmdsZSBjaGFyYWN0ZXJzLgogICAgICogQHBhcmFtIHZhckNoYXJUb1NldCBhIG1hcHBpbmcgZnJvbSBjaGFyYWN0ZXJzIChDaGFyYWN0ZXIgb2JqZWN0cyBmcm9tCiAgICAgKiB2YXJOYW1lVG9DaGFyKSB0byBVbmljb2RlU2V0IG9iamVjdHMuICBNYXkgYmUgbnVsbC4gIElzIG9ubHkgdXNlZCBpZgogICAgICogdmFyTmFtZVRvQ2hhciBpcyBhbHNvIG5vbi1udWxsLgogICAgICogQGV4Y2VwdGlvbiA8Y29kZT5JbGxlZ2FsQXJndW1lbnRFeGNlcHRpb248L2NvZGU+IGlmIHRoZSBwYXR0ZXJuCiAgICAgKiBjb250YWlucyBhIHN5bnRheCBlcnJvci4KICAgICAqLwogICAgVW5pY29kZVNldChjb25zdCBVbmljb2RlU3RyaW5nJiBwYXR0ZXJuLCBQYXJzZVBvc2l0aW9uJiBwb3MsCiAgICAgICAgICAgICAgIGNvbnN0IFN5bWJvbFRhYmxlJiBzeW1ib2xzLAogICAgICAgICAgICAgICBVRXJyb3JDb2RlJiBzdGF0dXMpOwoKICAgIC8qKgogICAgICogUmV0dXJucyA8dHQ+dHJ1ZTwvdHQ+IGlmIHRoaXMgc2V0IGNvbnRhaW5zIGFueSBjaGFyYWN0ZXIgd2hvc2UgbG93IGJ5dGUKICAgICAqIGlzIHRoZSBnaXZlbiB2YWx1ZS4gIFRoaXMgaXMgdXNlZCBieSA8dHQ+UnVsZUJhc2VkVHJhbnNsaXRlcmF0b3I8L3R0PiBmb3IKICAgICAqIGluZGV4aW5nLgogICAgICovCiAgICBib29sX3QgY29udGFpbnNJbmRleFZhbHVlKHVpbnQ4X3QgdikgY29uc3Q7Cgpwcml2YXRlOgoKICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgLy8gSW1wbGVtZW50YXRpb246IFBhdHRlcm4gcGFyc2luZwogICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgLyoqCiAgICAgKiBQYXJzZXMgdGhlIGdpdmVuIHBhdHRlcm4sIHN0YXJ0aW5nIGF0IHRoZSBnaXZlbiBwb3NpdGlvbi4gIFRoZQogICAgICogY2hhcmFjdGVyIGF0IHBhdHRlcm4uY2hhckF0KHBvcy5nZXRJbmRleCgpKSBtdXN0IGJlICdbJywgb3IgdGhlCiAgICAgKiBwYXJzZSBmYWlscy4gIFBhcnNpbmcgY29udGludWVzIHVudGlsIHRoZSBjb3JyZXNwb25kaW5nIGNsb3NpbmcKICAgICAqICddJy4gIElmIGEgc3ludGF4IGVycm9yIGlzIGVuY291bnRlcmVkIGJldHdlZW4gdGhlIG9wZW5pbmcgYW5kCiAgICAgKiBjbG9zaW5nIGJyYWNlLCB0aGUgcGFyc2UgZmFpbHMuICBVcG9uIHJldHVybiBmcm9tIGEgc3VjY2Vzc2Z1bAogICAgICogcGFyc2UsIHRoZSBQYXJzZVBvc2l0aW9uIGlzIHVwZGF0ZWQgdG8gcG9pbnQgdG8gdGhlIGNoYXJhY3RlcgogICAgICogZm9sbG93aW5nIHRoZSBjbG9zaW5nICddJywgYW5kIGEgU3RyaW5nQnVmZmVyIGNvbnRhaW5pbmcgYQogICAgICogcGFpcnMgbGlzdCBmb3IgdGhlIHBhcnNlZCBwYXR0ZXJuIGlzIHJldHVybmVkLiAgVGhpcyBtZXRob2QgY2FsbHMKICAgICAqIGl0c2VsZiByZWN1cnNpdmVseSB0byBwYXJzZSBlbWJlZGRlZCBzdWJwYXR0ZXJucy4KICAgICAqCiAgICAgKiBAcGFyYW0gcGF0dGVybiB0aGUgc3RyaW5nIGNvbnRhaW5pbmcgdGhlIHBhdHRlcm4gdG8gYmUgcGFyc2VkLgogICAgICogVGhlIHBvcnRpb24gb2YgdGhlIHN0cmluZyBmcm9tIHBvcy5nZXRJbmRleCgpLCB3aGljaCBtdXN0IGJlIGEKICAgICAqICdbJywgdG8gdGhlIGNvcnJlc3BvbmRpbmcgY2xvc2luZyAnXScsIGlzIHBhcnNlZC4KICAgICAqIEBwYXJhbSBwb3MgdXBvbiBlbnRyeSwgdGhlIHBvc2l0aW9uIGF0IHdoaWNoIHRvIGJlaW5nIHBhcnNpbmcuCiAgICAgKiBUaGUgY2hhcmFjdGVyIGF0IHBhdHRlcm4uY2hhckF0KHBvcy5nZXRJbmRleCgpKSBtdXN0IGJlIGEgJ1snLgogICAgICogVXBvbiByZXR1cm4gZnJvbSBhIHN1Y2Nlc3NmdWwgcGFyc2UsIHBvcy5nZXRJbmRleCgpIGlzIGVpdGhlcgogICAgICogdGhlIGNoYXJhY3RlciBhZnRlciB0aGUgY2xvc2luZyAnXScgb2YgdGhlIHBhcnNlZCBwYXR0ZXJuLCBvcgogICAgICogcGF0dGVybi5sZW5ndGgoKSBpZiB0aGUgY2xvc2luZyAnXScgaXMgdGhlIGxhc3QgY2hhcmFjdGVyIG9mCiAgICAgKiB0aGUgcGF0dGVybiBzdHJpbmcuCiAgICAgKiBAcmV0dXJuIGEgU3RyaW5nQnVmZmVyIGNvbnRhaW5pbmcgYSBwYWlycyBsaXN0IGZvciB0aGUgcGFyc2VkCiAgICAgKiBzdWJzdHJpbmcgb2YgPGNvZGU+cGF0dGVybjwvY29kZT4KICAgICAqIEBleGNlcHRpb24gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHRoZSBwYXJzZSBmYWlscy4KICAgICAqLwogICAgc3RhdGljIFVuaWNvZGVTdHJpbmcmIHBhcnNlKFVuaWNvZGVTdHJpbmcmIHBhaXJzQnVmIC8qcmVzdWx0Ki8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVW5pY29kZVN0cmluZyYgcGF0dGVybiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQYXJzZVBvc2l0aW9uJiBwb3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgU3ltYm9sVGFibGUqIHN5bWJvbHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYgc3RhdHVzKTsKCiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgIC8vIEltcGxlbWVudGF0aW9uOiBFZmZpY2llbnQgaW4tcGxhY2UgdW5pb24gJiBkaWZmZXJlbmNlCiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICAvKioKICAgICAqIFBlcmZvcm1zIGEgdW5pb24gb3BlcmF0aW9uOiBhZGRzIHRoZSByYW5nZSAnYyctJ2QnIHRvIHRoZSBnaXZlbgogICAgICogcGFpcnMgbGlzdC4gIFRoZSBwYWlycyBsaXN0IGlzIG1vZGlmaWVkIGluIHBsYWNlLiAgVGhlIHJlc3VsdAogICAgICogaXMgbm9ybWFsaXplZCAoaW4gb3JkZXIgYW5kIGFzIHNob3J0IGFzIHBvc3NpYmxlKS4gIEZvcgogICAgICogZXhhbXBsZSwgYWRkUGFpcigiYW0iLCAnbCcsICdxJykgPT4gImFxIi4gIGFkZFBhaXIoImFtcHoiLCAnbicsCiAgICAgKiAnbycpID0+ICJheiIuCiAgICAgKi8KICAgIHN0YXRpYyB2b2lkIGFkZFBhaXIoVW5pY29kZVN0cmluZyYgcGFpcnMsIFVDaGFyIGMsIFVDaGFyIGQpOwoKICAgIC8qKgogICAgICogUGVyZm9ybXMgYW4gYXN5bW1ldHJpYyBkaWZmZXJlbmNlOiByZW1vdmVzIHRoZSByYW5nZSAnYyctJ2QnCiAgICAgKiBmcm9tIHRoZSBwYWlycyBsaXN0LiAgVGhlIHBhaXJzIGxpc3QgaXMgbW9kaWZpZWQgaW4gcGxhY2UuICBUaGUKICAgICAqIHJlc3VsdCBpcyBub3JtYWxpemVkIChpbiBvcmRlciBhbmQgYXMgc2hvcnQgYXMgcG9zc2libGUpLiAgRm9yCiAgICAgKiBleGFtcGxlLCByZW1vdmVQYWlyKCJhbSIsICdsJywgJ3EnKSA9PiAiYWsiLgogICAgICogcmVtb3ZlUGFpcigiYW1weiIsICdsJywgJ3EnKSA9PiAiYWtyeiIuCiAgICAgKi8KICAgIHN0YXRpYyB2b2lkIHJlbW92ZVBhaXIoVW5pY29kZVN0cmluZyYgcGFpcnMsIFVDaGFyIGMsIFVDaGFyIGQpOwoKICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgLy8gSW1wbGVtZW50YXRpb246IEZ1bmRhbWVudGFsIG9wZXJhdG9ycwogICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgLyoqCiAgICAgKiBDaGFuZ2VzIHRoZSBwYWlycyBsaXN0IHRvIHJlcHJlc2VudCB0aGUgY29tcGxlbWVudCBvZiB0aGUgc2V0IGl0CiAgICAgKiBjdXJyZW50bHkgcmVwcmVzZW50cy4gIFRoZSBwYWlycyBsaXN0IHdpbGwgYmUgbm9ybWFsaXplZCAoaW4KICAgICAqIG9yZGVyIGFuZCBpbiBzaG9ydGVzdCBwb3NzaWJsZSBmb3JtKSBpZiB0aGUgb3JpZ2luYWwgcGFpcnMgbGlzdAogICAgICogd2FzIG5vcm1hbGl6ZWQuCiAgICAgKi8KICAgIHN0YXRpYyB2b2lkIGRvQ29tcGxlbWVudChVbmljb2RlU3RyaW5nJiBwYWlycyk7CgogICAgLyoqCiAgICAgKiBHaXZlbiB0d28gcGFpcnMgbGlzdHMsIGNoYW5nZXMgdGhlIGZpcnN0IGluIHBsYWNlIHRvIHJlcHJlc2VudAogICAgICogdGhlIHVuaW9uIG9mIHRoZSB0d28gc2V0cy4KICAgICAqLwogICAgc3RhdGljIHZvaWQgZG9VbmlvbihVbmljb2RlU3RyaW5nJiBwYWlycywgY29uc3QgVW5pY29kZVN0cmluZyYgYzIpOwoKICAgIC8qKgogICAgICogR2l2ZW4gdHdvIHBhaXJzIGxpc3RzLCBjaGFuZ2VzIHRoZSBmaXJzdCBpbiBwbGFjZSB0byByZXByZXNlbnQKICAgICAqIHRoZSBhc3ltbWV0cmljIGRpZmZlcmVuY2Ugb2YgdGhlIHR3byBzZXRzLgogICAgICovCiAgICBzdGF0aWMgdm9pZCBkb0RpZmZlcmVuY2UoVW5pY29kZVN0cmluZyYgcGFpcnMsIGNvbnN0IFVuaWNvZGVTdHJpbmcmIHBhaXJzMik7CgogICAgLyoqCiAgICAgKiBHaXZlbiB0d28gcGFpcnMgbGlzdHMsIGNoYW5nZXMgdGhlIGZpcnN0IGluIHBsYWNlIHRvIHJlcHJlc2VudAogICAgICogdGhlIGludGVyc2VjdGlvbiBvZiB0aGUgdHdvIHNldHMuCiAgICAgKi8KICAgIHN0YXRpYyB2b2lkIGRvSW50ZXJzZWN0aW9uKFVuaWNvZGVTdHJpbmcmIHBhaXJzLCBjb25zdCBVbmljb2RlU3RyaW5nJiBjMik7CgogICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAvLyBJbXBsZW1lbnRhdGlvbjogR2VuZXJhdGlvbiBvZiBwYWlycyBmb3IgVW5pY29kZSBjYXRlZ29yaWVzCiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICAvKioKICAgICAqIFJldHVybnMgYSBwYWlycyBzdHJpbmcgZm9yIHRoZSBnaXZlbiBjYXRlZ29yeSwgZ2l2ZW4gaXRzIG5hbWUuCiAgICAgKiBUaGUgY2F0ZWdvcnkgbmFtZSBtdXN0IGJlIGVpdGhlciBhIHR3by1sZXR0ZXIgbmFtZSwgc3VjaCBhcwogICAgICogIkx1Iiwgb3IgYSBvbmUgbGV0dGVyIG5hbWUsIHN1Y2ggYXMgIkwiLiAgT25lLWxldHRlciBuYW1lcwogICAgICogaW5kaWNhdGUgdGhlIGxvZ2ljYWwgdW5pb24gb2YgYWxsIHR3by1sZXR0ZXIgbmFtZXMgdGhhdCBzdGFydAogICAgICogd2l0aCB0aGF0IGxldHRlci4gIENhc2UgaXMgc2lnbmlmaWNhbnQuICBJZiB0aGUgbmFtZSBzdGFydHMKICAgICAqIHdpdGggdGhlIGNoYXJhY3RlciAnXicgdGhlbiB0aGUgY29tcGxlbWVudCBvZiB0aGUgZ2l2ZW4KICAgICAqIGNoYXJhY3RlciBzZXQgaXMgcmV0dXJuZWQuCiAgICAgKgogICAgICogQWx0aG91Z2ggaW5kaXZpZHVhbCBjYXRlZ29yaWVzIHN1Y2ggYXMgIkx1IiBhcmUgY2FjaGVkLCB3ZSBkbwogICAgICogbm90IGN1cnJlbnRseSBjYWNoZSBzaW5nbGUtbGV0dGVyIGNhdGVnb3JpZXMgc3VjaCBhcyAiTCIgb3IKICAgICAqIGNvbXBsZW1lbnRzIHN1Y2ggYXMgIl5MdSIgb3IgIl5MIi4gIEl0IHdvdWxkIGJlIGVhc3kgdG8gY2FjaGUKICAgICAqIHRoZXNlIGFzIHdlbGwgaW4gYSBoYXNodGFibGUgc2hvdWxkIHRoZSBuZWVkIGFyaXNlLgogICAgICovCiAgICBzdGF0aWMgVW5pY29kZVN0cmluZyYgZ2V0Q2F0ZWdvcnlQYWlycyhVbmljb2RlU3RyaW5nJiByZXN1bHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBVbmljb2RlU3RyaW5nJiBjYXROYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYgc3RhdHVzKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgYSBwYWlycyBzdHJpbmcgZm9yIHRoZSBnaXZlbiBjYXRlZ29yeS4gIFRoaXMgc3RyaW5nIGlzCiAgICAgKiBjYWNoZWQgYW5kIHJldHVybmVkIGFnYWluIGlmIHRoaXMgbWV0aG9kIGlzIGNhbGxlZCBhZ2FpbiB3aXRoCiAgICAgKiB0aGUgc2FtZSBwYXJhbWV0ZXIuCiAgICAgKi8KICAgIHN0YXRpYyBjb25zdCBVbmljb2RlU3RyaW5nJiBnZXRDYXRlZ29yeVBhaXJzKGludDhfdCBjYXQpOwoKICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgLy8gSW1wbGVtZW50YXRpb246IFV0aWxpdHkgbWV0aG9kcwogICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBjaGFyYWN0ZXIgYWZ0ZXIgdGhlIGdpdmVuIHBvc2l0aW9uLCBvciAnXHVGRkZGJyBpZgogICAgICogdGhlcmUgaXMgbm9uZS4KICAgICAqLwogICAgc3RhdGljIFVDaGFyIGNoYXJBZnRlcihjb25zdCBVbmljb2RlU3RyaW5nJiBzdHIsIGludDMyX3QgaSk7Cn07CgppbmxpbmUgYm9vbF90IFVuaWNvZGVTZXQ6Om9wZXJhdG9yIT0oY29uc3QgVW5pY29kZVNldCYgbykgY29uc3QgewoJcmV0dXJuICFvcGVyYXRvcj09KG8pOwp9CgojZW5kaWYK