LyoKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKgoqICAgQ29weXJpZ2h0IChDKSAxOTk2LTE5OTksIEludGVybmF0aW9uYWwgQnVzaW5lc3MgTWFjaGluZXMKKiAgIENvcnBvcmF0aW9uIGFuZCBvdGhlcnMuICBBbGwgUmlnaHRzIFJlc2VydmVkLgoqCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCioKKiBGaWxlIGxvY2lkLmgKKgoqIENyZWF0ZWQgYnk6IEhlbGVuYSBTaGloCioKKiBNb2RpZmljYXRpb24gSGlzdG9yeToKKgoqICAgRGF0ZSAgICAgICAgTmFtZSAgICAgICAgRGVzY3JpcHRpb24KKiAgIDAyLzExLzk3ICAgIGFsaXUgICAgICAgIENoYW5nZWQgZ0xvY1BhdGggdG8gZmdMb2NQYXRoIGFuZCBhZGRlZCBtZXRob2RzIHRvCiogICAgICAgICAgICAgICAgICAgICAgICAgICBnZXQgYW5kIHNldCBpdC4KKiAgIDA0LzAyLzk3ICAgIGFsaXUgICAgICAgIE1hZGUgb3BlcmF0b3IhPSBpbmxpbmU7IGZpeGVkIHJldHVybiB2YWx1ZSBvZiBnZXROYW1lKCkuCiogICAwNC8xNS85NyAgICBhbGl1ICAgICAgICBDbGVhbnVwIGZvciBBSVgvV2luMzIuCiogICAwNC8yNC85NyAgICBhbGl1ICAgICAgICBOdW1lcm91cyBjaGFuZ2VzIHBlciBjb2RlIHJldmlldy4KKiAgIDA4LzE4Lzk4ICAgIHN0ZXBoZW4gICAgIEFkZGVkIHRva2VuaXplU3RyaW5nKCksY2hhbmdlZCBnZXREaXNwbGF5TmFtZSgpCiogICAwOS8wOC85OCAgICBzdGVwaGVuICAgICBNb3ZlZCBkZWZpbml0aW9uIG9mIGtFbXB0eVN0cmluZyBmb3IgTWFjIFBvcnQKKiAgIDExLzA5Lzk5CXdlaXYgICAgICAgIEFkZGVkIGNvbnN0IGNoYXIgKiBnZXROYW1lKCkgY29uc3Q7CiogICAwNC8xMi8wMCAgICBzcmwgICAgICAgICByZW1vdmluZyB1bmljb2Rlc3RyaW5nIGFwaSdzIGFuZCBjYWNoZWQgaGFzaCBjb2RlCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiovCgojaWZuZGVmIExPQ0lEX0gKI2RlZmluZSBMT0NJRF9ICgoKI2luY2x1ZGUgInVuaWNvZGUvdW5pc3RyLmgiCgp0eXBlZGVmIHN0cnVjdCBVTG9jYWxlIFVMb2NhbGU7CnR5cGVkZWYgc3RydWN0IFVIYXNodGFibGUgVUhhc2h0YWJsZTsKCiNkZWZpbmUgVUxPQ19MQU5HX0NBUEFDSVRZIDMKI2RlZmluZSBVTE9DX0NPVU5UUllfQ0FQQUNJVFkgMwojZGVmaW5lIFVMT0NfRlVMTE5BTUVfQ0FQQUNJVFkgNTAKCi8qKiAgICAKICoKICogQSA8Y29kZT5Mb2NhbGU8L2NvZGU+IG9iamVjdCByZXByZXNlbnRzIGEgc3BlY2lmaWMgZ2VvZ3JhcGhpY2FsLCBwb2xpdGljYWwsCiAqIG9yIGN1bHR1cmFsIHJlZ2lvbi4gQW4gb3BlcmF0aW9uIHRoYXQgcmVxdWlyZXMgYSA8Y29kZT5Mb2NhbGU8L2NvZGU+IHRvIHBlcmZvcm0KICogaXRzIHRhc2sgaXMgY2FsbGVkIDxlbT5sb2NhbGUtc2Vuc2l0aXZlPC9lbT4gYW5kIHVzZXMgdGhlIDxjb2RlPkxvY2FsZTwvY29kZT4KICogdG8gdGFpbG9yIGluZm9ybWF0aW9uIGZvciB0aGUgdXNlci4gRm9yIGV4YW1wbGUsIGRpc3BsYXlpbmcgYSBudW1iZXIKICogaXMgYSBsb2NhbGUtc2Vuc2l0aXZlIG9wZXJhdGlvbi0tdGhlIG51bWJlciBzaG91bGQgYmUgZm9ybWF0dGVkCiAqIGFjY29yZGluZyB0byB0aGUgY3VzdG9tcy9jb252ZW50aW9ucyBvZiB0aGUgdXNlcidzIG5hdGl2ZSBjb3VudHJ5LAogKiByZWdpb24sIG9yIGN1bHR1cmUuCiAqCiAqIDxQPgogKiBZb3UgY3JlYXRlIGEgPGNvZGU+TG9jYWxlPC9jb2RlPiBvYmplY3QgdXNpbmcgdGhlIGNvbnN0cnVjdG9yIGluCiAqIHRoaXMgY2xhc3M6CiAqIDxibG9ja3F1b3RlPgogKiA8cHJlPgogKiAuICAgICAgTG9jYWxlKCBjb25zdCAgIGNoYXIqICBsYW5ndWFnZSwgCiAqIC4gICAgICAgICAgICAgIGNvbnN0ICAgY2hhciogIGNvdW50cnksIAogKiAuICAgICAgICAgICAgICBjb25zdCAgIGNoYXIqICB2YXJpYW50KTsKICogPC9wcmU+CiAqIDwvYmxvY2txdW90ZT4KICogVGhlIGZpcnN0IGFyZ3VtZW50IHRvIHRoZSBjb25zdHJ1Y3RvcnMgaXMgYSB2YWxpZCA8U1RST05HPklTTwogKiBMYW5ndWFnZSBDb2RlLjwvU1RST05HPiBUaGVzZSBjb2RlcyBhcmUgdGhlIGxvd2VyLWNhc2UgdHdvLWxldHRlcgogKiBjb2RlcyBhcyBkZWZpbmVkIGJ5IElTTy02MzkuCiAqIFlvdSBjYW4gZmluZCBhIGZ1bGwgbGlzdCBvZiB0aGVzZSBjb2RlcyBhdCBhIG51bWJlciBvZiBzaXRlcywgc3VjaCBhczoKICogPEJSPjxhIGhyZWYgPSJodHRwOi8vd3d3Lmljcy51Y2kuZWR1L3B1Yi9pZXRmL2h0dHAvcmVsYXRlZC9pc282MzkudHh0Ij4KICogPGNvZGU+aHR0cDovL3d3dy5pY3MudWNpLmVkdS9wdWIvaWV0Zi9odHRwL3JlbGF0ZWQvaXNvNjM5LnR4dDwvY29kZT48L2E+CiAqCiAqIDxQPgogKiBUaGUgc2Vjb25kIGFyZ3VtZW50IHRvIHRoZSBjb25zdHJ1Y3RvcnMgaXMgYSB2YWxpZCA8U1RST05HPklTTyBDb3VudHJ5CiAqIENvZGUuPC9TVFJPTkc+IFRoZXNlIGNvZGVzIGFyZSB0aGUgdXBwZXItY2FzZSB0d28tbGV0dGVyIGNvZGVzCiAqIGFzIGRlZmluZWQgYnkgSVNPLTMxNjYuCiAqIFlvdSBjYW4gZmluZCBhIGZ1bGwgbGlzdCBvZiB0aGVzZSBjb2RlcyBhdCBhIG51bWJlciBvZiBzaXRlcywgc3VjaCBhczoKICogPEJSPjxhIGhyZWY9Imh0dHA6Ly93d3cuY2hlbWllLmZ1LWJlcmxpbi5kZS9kaXZlcnNlL2RvYy9JU09fMzE2Ni5odG1sIj4KICogPGNvZGU+aHR0cDovL3d3dy5jaGVtaWUuZnUtYmVybGluLmRlL2RpdmVyc2UvZG9jL0lTT18zMTY2Lmh0bWw8L2NvZGU+PC9hPgogKgogKiA8UD4KICogVGhlIHRoaXJkIGNvbnN0cnVjdG9yIHJlcXVpcmVzIGEgdGhpcmQgYXJndW1lbnQtLXRoZSA8U1RST05HPlZhcmlhbnQuPC9TVFJPTkc+CiAqIFRoZSBWYXJpYW50IGNvZGVzIGFyZSB2ZW5kb3IgYW5kIGJyb3dzZXItc3BlY2lmaWMuCiAqIEZvciBleGFtcGxlLCB1c2UgV0lOIGZvciBXaW5kb3dzLCBNQUMgZm9yIE1hY2ludG9zaCwgYW5kIFBPU0lYIGZvciBQT1NJWC4KICogV2hlcmUgdGhlcmUgYXJlIHR3byB2YXJpYW50cywgc2VwYXJhdGUgdGhlbSB3aXRoIGFuIHVuZGVyc2NvcmUsIGFuZAogKiBwdXQgdGhlIG1vc3QgaW1wb3J0YW50IG9uZSBmaXJzdC4gRm9yCiAqIGV4YW1wbGUsIGEgVHJhZGl0aW9uYWwgU3BhbmlzaCBjb2xsYXRpb24gbWlnaHQgYmUgcmVmZXJlbmNlZCwgd2l0aAogKiAiRVMiLCAiRVMiLCAiVHJhZGl0aW9uYWxfV0lOIi4KICoKICogPFA+CiAqIEJlY2F1c2UgYSA8Y29kZT5Mb2NhbGU8L2NvZGU+IG9iamVjdCBpcyBqdXN0IGFuIGlkZW50aWZpZXIgZm9yIGEgcmVnaW9uLAogKiBubyB2YWxpZGl0eSBjaGVjayBpcyBwZXJmb3JtZWQgd2hlbiB5b3UgY29uc3RydWN0IGEgPGNvZGU+TG9jYWxlPC9jb2RlPi4KICogSWYgeW91IHdhbnQgdG8gc2VlIHdoZXRoZXIgcGFydGljdWxhciByZXNvdXJjZXMgYXJlIGF2YWlsYWJsZSBmb3IgdGhlCiAqIDxjb2RlPkxvY2FsZTwvY29kZT4geW91IGNvbnN0cnVjdCwgeW91IG11c3QgcXVlcnkgdGhvc2UgcmVzb3VyY2VzLiBGb3IKICogZXhhbXBsZSwgYXNrIHRoZSA8Y29kZT5OdW1iZXJGb3JtYXQ8L2NvZGU+IGZvciB0aGUgbG9jYWxlcyBpdCBzdXBwb3J0cwogKiB1c2luZyBpdHMgPGNvZGU+Z2V0QXZhaWxhYmxlTG9jYWxlczwvY29kZT4gbWV0aG9kLgogKiA8QlI+PFNUUk9ORz5Ob3RlOjwvU1RST05HPiBXaGVuIHlvdSBhc2sgZm9yIGEgcmVzb3VyY2UgZm9yIGEgcGFydGljdWxhcgogKiBsb2NhbGUsIHlvdSBnZXQgYmFjayB0aGUgYmVzdCBhdmFpbGFibGUgbWF0Y2gsIG5vdCBuZWNlc3NhcmlseQogKiBwcmVjaXNlbHkgd2hhdCB5b3UgYXNrZWQgZm9yLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgbG9vayBhdAogKiA8YSBocmVmPSJqYXZhLnV0aWwuUmVzb3VyY2VCdW5kbGUuaHRtbCI+PGNvZGU+UmVzb3VyY2VCdW5kbGU8L2NvZGU+PC9hPi4KICoKICogPFA+CiAqIFRoZSA8Y29kZT5Mb2NhbGU8L2NvZGU+IGNsYXNzIHByb3ZpZGVzIGEgbnVtYmVyIG9mIGNvbnZlbmllbnQgY29uc3RhbnRzCiAqIHRoYXQgeW91IGNhbiB1c2UgdG8gY3JlYXRlIDxjb2RlPkxvY2FsZTwvY29kZT4gb2JqZWN0cyBmb3IgY29tbW9ubHkgdXNlZAogKiBsb2NhbGVzLiBGb3IgZXhhbXBsZSwgdGhlIGZvbGxvd2luZyByZWZlcnMgdG8gYSA8Y29kZT5Mb2NhbGU8L2NvZGU+IG9iamVjdAogKiBmb3IgdGhlIFVuaXRlZCBTdGF0ZXM6CiAqIDxibG9ja3F1b3RlPgogKiA8cHJlPgogKiAuICAgICAgTG9jYWxlOjpVUwogKiA8L3ByZT4KICogPC9ibG9ja3F1b3RlPgogKgogKiA8UD4KICogT25jZSB5b3UndmUgY3JlYXRlZCBhIDxjb2RlPkxvY2FsZTwvY29kZT4geW91IGNhbiBxdWVyeSBpdCBmb3IgaW5mb3JtYXRpb24gYWJvdXQKICogaXRzZWxmLiBVc2UgPGNvZGU+Z2V0Q291bnRyeTwvY29kZT4gdG8gZ2V0IHRoZSBJU08gQ291bnRyeSBDb2RlIGFuZAogKiA8Y29kZT5nZXRMYW5ndWFnZTwvY29kZT4gdG8gZ2V0IHRoZSBJU08gTGFuZ3VhZ2UgQ29kZS4gWW91IGNhbgogKiB1c2UgPGNvZGU+Z2V0RGlzcGxheUNvdW50cnk8L2NvZGU+IHRvIGdldCB0aGUKICogbmFtZSBvZiB0aGUgY291bnRyeSBzdWl0YWJsZSBmb3IgZGlzcGxheWluZyB0byB0aGUgdXNlci4gU2ltaWxhcmx5LAogKiB5b3UgY2FuIHVzZSA8Y29kZT5nZXREaXNwbGF5TGFuZ3VhZ2U8L2NvZGU+IHRvIGdldCB0aGUgbmFtZSBvZgogKiB0aGUgbGFuZ3VhZ2Ugc3VpdGFibGUgZm9yIGRpc3BsYXlpbmcgdG8gdGhlIHVzZXIuIEludGVyZXN0aW5nbHksCiAqIHRoZSA8Y29kZT5nZXREaXNwbGF5WFhYPC9jb2RlPiBtZXRob2RzIGFyZSB0aGVtc2VsdmVzIGxvY2FsZS1zZW5zaXRpdmUKICogYW5kIGhhdmUgdHdvIHZlcnNpb25zOiBvbmUgdGhhdCB1c2VzIHRoZSBkZWZhdWx0IGxvY2FsZSBhbmQgb25lCiAqIHRoYXQgdGFrZXMgYSBsb2NhbGUgYXMgYW4gYXJndW1lbnQgYW5kIGRpc3BsYXlzIHRoZSBuYW1lIG9yIGNvdW50cnkgaW4KICogYSBsYW5ndWFnZSBhcHByb3ByaWF0ZSB0byB0aGF0IGxvY2FsZS4KICoKICogPFA+CiAqIFRoZSBUSUZDIHByb3ZpZGVzIGEgbnVtYmVyIG9mIGNsYXNzZXMgdGhhdCBwZXJmb3JtIGxvY2FsZS1zZW5zaXRpdmUKICogb3BlcmF0aW9ucy4gRm9yIGV4YW1wbGUsIHRoZSA8Y29kZT5OdW1iZXJGb3JtYXQ8L2NvZGU+IGNsYXNzIGZvcm1hdHMKICogbnVtYmVycywgY3VycmVuY3ksIG9yIHBlcmNlbnRhZ2VzIGluIGEgbG9jYWxlLXNlbnNpdGl2ZSBtYW5uZXIuIENsYXNzZXMKICogc3VjaCBhcyA8Y29kZT5OdW1iZXJGb3JtYXQ8L2NvZGU+IGhhdmUgYSBudW1iZXIgb2YgY29udmVuaWVuY2UgbWV0aG9kcwogKiBmb3IgY3JlYXRpbmcgYSBkZWZhdWx0IG9iamVjdCBvZiB0aGF0IHR5cGUuIEZvciBleGFtcGxlLCB0aGUKICogPGNvZGU+TnVtYmVyRm9ybWF0PC9jb2RlPiBjbGFzcyBwcm92aWRlcyB0aGVzZSB0aHJlZSBjb252ZW5pZW5jZSBtZXRob2RzCiAqIGZvciBjcmVhdGluZyBhIGRlZmF1bHQgPGNvZGU+TnVtYmVyRm9ybWF0PC9jb2RlPiBvYmplY3Q6CiAqIDxibG9ja3F1b3RlPgogKiA8cHJlPgogKiAuICAgIFVFcnJvckNvZGUgc3VjY2VzcyA9IFVfWkVST19FUlJPUjsKICogLiAgICBMb2NhbGUgbXlMb2NhbGU7CiAqIC4gICAgTnVtYmVyRm9ybWF0ICpuZjsKICogLgogKiAuICAgIG5mID0gTnVtYmVyRm9ybWF0OjpjcmVhdGVJbnN0YW5jZSggc3VjY2VzcyApOyAgICAgICAgICBkZWxldGUgbmY7CiAqIC4gICAgbmYgPSBOdW1iZXJGb3JtYXQ6OmNyZWF0ZUN1cnJlbmN5SW5zdGFuY2UoIHN1Y2Nlc3MgKTsgIGRlbGV0ZSBuZjsKICogLiAgICBuZiA9IE51bWJlckZvcm1hdDo6Y3JlYXRlUGVyY2VudEluc3RhbmNlKCBzdWNjZXNzICk7ICAgZGVsZXRlIG5mOwogKiA8L3ByZT4KICogPC9ibG9ja3F1b3RlPgogKiBFYWNoIG9mIHRoZXNlIG1ldGhvZHMgaGFzIHR3byB2YXJpYW50czsgb25lIHdpdGggYW4gZXhwbGljaXQgbG9jYWxlCiAqIGFuZCBvbmUgd2l0aG91dDsgdGhlIGxhdHRlciB1c2luZyB0aGUgZGVmYXVsdCBsb2NhbGUuCiAqIDxibG9ja3F1b3RlPgogKiA8cHJlPgogKiAuICAgIG5mID0gTnVtYmVyRm9ybWF0OjpjcmVhdGVJbnN0YW5jZSggbXlMb2NhbGUsIHN1Y2Nlc3MgKTsgICAgICAgICAgZGVsZXRlIG5mOwogKiAuICAgIG5mID0gTnVtYmVyRm9ybWF0OjpjcmVhdGVDdXJyZW5jeUluc3RhbmNlKCBteUxvY2FsZSwgc3VjY2VzcyApOyAgZGVsZXRlIG5mOwogKiAuICAgIG5mID0gTnVtYmVyRm9ybWF0OjpjcmVhdGVQZXJjZW50SW5zdGFuY2UoIG15TG9jYWxlLCBzdWNjZXNzICk7ICAgZGVsZXRlIG5mOwogKiA8L3ByZT4KICogPC9ibG9ja3F1b3RlPgogKiBBIDxjb2RlPkxvY2FsZTwvY29kZT4gaXMgdGhlIG1lY2hhbmlzbSBmb3IgaWRlbnRpZnlpbmcgdGhlIGtpbmQgb2Ygb2JqZWN0CiAqICg8Y29kZT5OdW1iZXJGb3JtYXQ8L2NvZGU+KSB0aGF0IHlvdSB3b3VsZCBsaWtlIHRvIGdldC4gVGhlIGxvY2FsZSBpcwogKiA8U1RST05HPmp1c3Q8L1NUUk9ORz4gYSBtZWNoYW5pc20gZm9yIGlkZW50aWZ5aW5nIG9iamVjdHMsCiAqIDxTVFJPTkc+bm90PC9TVFJPTkc+IGEgY29udGFpbmVyIGZvciB0aGUgb2JqZWN0cyB0aGVtc2VsdmVzLgogKgogKiA8UD4KICogRWFjaCBjbGFzcyB0aGF0IHBlcmZvcm1zIGxvY2FsZS1zZW5zaXRpdmUgb3BlcmF0aW9ucyBhbGxvd3MgeW91CiAqIHRvIGdldCBhbGwgdGhlIGF2YWlsYWJsZSBvYmplY3RzIG9mIHRoYXQgdHlwZS4gWW91IGNhbiBzaWZ0CiAqIHRocm91Z2ggdGhlc2Ugb2JqZWN0cyBieSBsYW5ndWFnZSwgY291bnRyeSwgb3IgdmFyaWFudCwKICogYW5kIHVzZSB0aGUgZGlzcGxheSBuYW1lcyB0byBwcmVzZW50IGEgbWVudSB0byB0aGUgdXNlci4KICogRm9yIGV4YW1wbGUsIHlvdSBjYW4gY3JlYXRlIGEgbWVudSBvZiBhbGwgdGhlIGNvbGxhdGlvbiBvYmplY3RzCiAqIHN1aXRhYmxlIGZvciBhIGdpdmVuIGxhbmd1YWdlLiBTdWNoIGNsYXNzZXMgaW1wbGVtZW50IHRoZXNlCiAqIHRocmVlIGNsYXNzIG1ldGhvZHM6CiAqIDxibG9ja3F1b3RlPgogKiA8cHJlPgogKiAuICAgICAgc3RhdGljIExvY2FsZSogZ2V0QXZhaWxhYmxlTG9jYWxlcyhpbnQzMl90JiBudW1Mb2NhbGVzKQogKiAuICAgICAgc3RhdGljIFVuaWNvZGVTdHJpbmcmIGdldERpc3BsYXlOYW1lKGNvbnN0IExvY2FsZSYgIG9iamVjdExvY2FsZSwKICogLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBMb2NhbGUmICBkaXNwbGF5TG9jYWxlLAogKiAuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVuaWNvZGVTdHJpbmcmIGRpc3BsYXlOYW1lKQogKiAuICAgICAgc3RhdGljIFVuaWNvZGVTdHJpbmcmIGdldERpc3BsYXlOYW1lKGNvbnN0IExvY2FsZSYgIG9iamVjdExvY2FsZSwKICogLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVbmljb2RlU3RyaW5nJiBkaXNwbGF5TmFtZSkKICogPC9wcmU+CiAqIDwvYmxvY2txdW90ZT4KICovCmNsYXNzIFVfQ09NTU9OX0FQSSBMb2NhbGUgCnsKcHVibGljOgogICAgLyoqCiAgICAgKiBVc2VmdWwgY29uc3RhbnRzIGZvciBsYW5ndWFnZS4KICAgICAqLwogICAgc3RhdGljIGNvbnN0IExvY2FsZSBFTkdMSVNIOwogICAgc3RhdGljIGNvbnN0IExvY2FsZSBGUkVOQ0g7CiAgICBzdGF0aWMgY29uc3QgTG9jYWxlIEdFUk1BTjsKICAgIHN0YXRpYyBjb25zdCBMb2NhbGUgSVRBTElBTjsKICAgIHN0YXRpYyBjb25zdCBMb2NhbGUgSkFQQU5FU0U7CiAgICBzdGF0aWMgY29uc3QgTG9jYWxlIEtPUkVBTjsKICAgIHN0YXRpYyBjb25zdCBMb2NhbGUgQ0hJTkVTRTsKICAgIHN0YXRpYyBjb25zdCBMb2NhbGUgU0lNUExJRklFRF9DSElORVNFOwogICAgc3RhdGljIGNvbnN0IExvY2FsZSBUUkFESVRJT05BTF9DSElORVNFOwoKICAgIC8qKgogICAgICogVXNlZnVsIGNvbnN0YW50cyBmb3IgY291bnRyeS4KICAgICAqLwogICAgc3RhdGljIGNvbnN0IExvY2FsZSBGUkFOQ0U7CiAgICBzdGF0aWMgY29uc3QgTG9jYWxlIEdFUk1BTlk7CiAgICBzdGF0aWMgY29uc3QgTG9jYWxlIElUQUxZOwogICAgc3RhdGljIGNvbnN0IExvY2FsZSBKQVBBTjsKICAgIHN0YXRpYyBjb25zdCBMb2NhbGUgS09SRUE7CiAgICBzdGF0aWMgY29uc3QgTG9jYWxlIENISU5BOyAgICAgIC8vIEFsaWFzIGZvciBQUkMKICAgIHN0YXRpYyBjb25zdCBMb2NhbGUgUFJDOyAgICAgICAgLy8gUGVvcGxlcyBSZXB1YmxpYyBvZiBDaGluYQogICAgc3RhdGljIGNvbnN0IExvY2FsZSBUQUlXQU47CiAgICBzdGF0aWMgY29uc3QgTG9jYWxlIFVLOwogICAgc3RhdGljIGNvbnN0IExvY2FsZSBVUzsKICAgIHN0YXRpYyBjb25zdCBMb2NhbGUgQ0FOQURBOwogICAgc3RhdGljIGNvbnN0IExvY2FsZSBDQU5BREFfRlJFTkNIOwoKICAgLyoqCiAgICAqIENvbnN0cnVjdCBhbiBlbXB0eSBsb2NhbGUuIEl0J3Mgb25seSB1c2VkIHdoZW4gYSBmaWxsLWluIHBhcmFtZXRlciBpcwogICAgKiBuZWVkZWQuCiAgICAqIEBzdGFibGUKICAgICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTG9jYWxlKCk7IAoKICAgIC8qKgogICAgICogQ29uc3RydWN0IGEgbG9jYWxlIGZyb20gbGFuZ3VhZ2UsIGNvdW50cnksIHZhcmlhbnQuCiAgICAgKgogICAgICogQHBhcmFtIGxhbmd1YWdlIExvd2VyY2FzZSB0d28tbGV0dGVyIElTTy02MzkgY29kZS4KICAgICAqIEBwYXJhbSBjb3VudHJ5ICBVcHBlcmNhc2UgdHdvLWxldHRlciBJU08tMzE2NiBjb2RlLiAob3B0aW9uYWwpCiAgICAgKiBAcGFyYW0gdmFyaWFudCAgVXBwZXJjYXNlIHZlbmRvciBhbmQgYnJvd3NlciBzcGVjaWZpYyBjb2RlLiBTZWUgY2xhc3MKICAgICAqICAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbi4gKG9wdGlvbmFsKQogICAgICogQGRyYWZ0CiAgICAgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMb2NhbGUoIGNvbnN0ICAgY2hhciAqIGxhbmd1YWdlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgICBjaGFyICogY291bnRyeSAgPSAwLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0ICAgY2hhciAqIHZhcmlhbnQgID0gMCk7CiNpZm5kZWYgSUNVX0xPQ0lEX05PX0RFUFJFQ0FURVMKICAgIC8qKgogICAgICogQ29uc3RydWN0IGEgbG9jYWxlIGZyb20gbGFuZ3VhZ2UsIGNvdW50cnksIHZhcmlhbnQuCiAgICAgKgogICAgICogQHBhcmFtIGxhbmd1YWdlIExvd2VyY2FzZSB0d28tbGV0dGVyIElTTy02MzkgY29kZS4KICAgICAqIEBwYXJhbSBjb3VudHJ5ICBVcHBlcmNhc2UgdHdvLWxldHRlciBJU08tMzE2NiBjb2RlLiAob3B0aW9uYWwpCiAgICAgKiBAcGFyYW0gdmFyaWFudCAgVXBwZXJjYXNlIHZlbmRvciBhbmQgYnJvd3NlciBzcGVjaWZpYyBjb2RlLiBTZWUgY2xhc3MKICAgICAqICAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbi4gKG9wdGlvbmFsKQogICAgICogQGRlcHJlY2F0ZWQgUmVtb3ZlIGluIHRoZSBmaXJzdCByZWxlYXNlIG9mIDIwMDEuCiAgICAgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMb2NhbGUoIGNvbnN0ICAgVW5pY29kZVN0cmluZyYgIGxhbmd1YWdlLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0ICAgVW5pY29kZVN0cmluZyYgIGNvdW50cnkgLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0ICAgVW5pY29kZVN0cmluZyYgIHZhcmlhbnQgKTsKCiAgICAgLyoqCiAgICAgKiBDb25zdHJ1Y3QgYSBsb2NhbGUgZnJvbSBsYW5ndWFnZSwgY291bnRyeS4KICAgICAqCiAgICAgKiBAcGFyYW0gbGFuZ3VhZ2UgTG93ZXJjYXNlIHR3by1sZXR0ZXIgSVNPLTYzOSBjb2RlLgogICAgICogQHBhcmFtIGNvdW50cnkgIFVwcGVyY2FzZSB0d28tbGV0dGVyIElTTy0zMTY2IGNvZGUuIChvcHRpb25hbCkKICAgICAqIEBkZXByZWNhdGVkIFJlbW92ZSBpbiB0aGUgZmlyc3QgcmVsZWFzZSBvZiAyMDAxLgogICAgICovCiAgICAgICAgICAgICAgIExvY2FsZSggY29uc3QgICBVbmljb2RlU3RyaW5nJiAgbGFuZ3VhZ2UsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgICBVbmljb2RlU3RyaW5nJiAgY291bnRyeSApOwogICAgICAgICAgICAgICAgCiAgICAvKioKICAgICAqIENvbnN0cnVjdCBhIGxvY2FsZSBmcm9tIGxhbmd1YWdlLgogICAgICoKICAgICAqIEBwYXJhbSBsYW5ndWFnZSBMb3dlcmNhc2UgdHdvLWxldHRlciBJU08tNjM5IGNvZGUuCiAgICAgKiBAZGVwcmVjYXRlZCBSZW1vdmUgaW4gdGhlIGZpcnN0IHJlbGVhc2Ugb2YgMjAwMS4KICAgICAqLwogICAgICAgICAgICAgICAgTG9jYWxlKCBjb25zdCAgIFVuaWNvZGVTdHJpbmcmICBsYW5ndWFnZSk7CgoKI2VuZGlmIC8vIElDVV9MT0NJRF9OT19ERVBSRUNBVEVTCiAgICAvKioKICAgICAqIEluaXRpYWxpemVzIGEgTG9jYWxlIG9iamVjdCBmcm9tIGFub3RoZXIgTG9jYWxlIG9iamVjdC4KICAgICAqCiAgICAgKiBAcGFyYW0gb3RoZXIgVGhlIExvY2FsZSBvYmplY3QgYmVpbmcgY29waWVkIGluLgogICAgICogQHN0YWJsZQogICAgICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTG9jYWxlKGNvbnN0ICAgIExvY2FsZSYgb3RoZXIpOwoKCiAgICAvKioKICAgICAqIERlc3RydWN0b3IKICAgICAqIEBzdGFibGUKICAgICAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH5Mb2NhbGUoKSA7CiAgICAgICAgICAgICAgICAgIAogICAgLyoqCiAgICAgKiBSZXBsYWNlcyB0aGUgZW50aXJlIGNvbnRlbnRzIG9mICp0aGlzIHdpdGggdGhlIHNwZWNpZmllZCB2YWx1ZS4KICAgICAqCiAgICAgKiBAcGFyYW0gb3RoZXIgVGhlIExvY2FsZSBvYmplY3QgYmVpbmcgY29waWVkIGluLgogICAgICogQHJldHVybiAgICAgICp0aGlzCiAgICAgKiBAc3RhYmxlCiAgICAgKi8KICAgIExvY2FsZSYgICAgICAgICAgICAgICAgICAgICBvcGVyYXRvcj0oY29uc3QgTG9jYWxlJiBvdGhlcik7CgogICAgLyoqCiAgICAgKiBDaGVja3MgaWYgdHdvIGxvY2FsZSBrZXlzIGFyZSB0aGUgc2FtZS4KICAgICAqCiAgICAgKiBAcGFyYW0gb3RoZXIgVGhlIGxvY2FsZSBrZXkgb2JqZWN0IHRvIGJlIGNvbXBhcmVkIHdpdGggdGhpcy4KICAgICAqIEByZXR1cm4gICAgICBUcnVlIGlmIHRoZSB0d28gbG9jYWxlIGtleXMgYXJlIHRoZSBzYW1lLCBmYWxzZSBvdGhlcndpc2UuCiAgICAgKiBAc3RhYmxlCiAgICAgKi8KICAgICAgICAgICAgICAgIFVCb29sICAgICAgICAgIG9wZXJhdG9yPT0oY29uc3QgICAgTG9jYWxlJiAgICAgb3RoZXIpIGNvbnN0OyAgIAoKICAgIC8qKgogICAgICogQ2hlY2tzIGlmIHR3byBsb2NhbGUga2V5cyBhcmUgbm90IHRoZSBzYW1lLgogICAgICoKICAgICAqIEBwYXJhbSBvdGhlciBUaGUgbG9jYWxlIGtleSBvYmplY3QgdG8gYmUgY29tcGFyZWQgd2l0aCB0aGlzLgogICAgICogQHJldHVybiAgICAgIFRydWUgaWYgdGhlIHR3byBsb2NhbGUga2V5cyBhcmUgbm90IHRoZSBzYW1lLCBmYWxzZQogICAgICogICAgICAgICAgICAgIG90aGVyd2lzZS4KICAgICAqIEBzdGFibGUKICAgICAqLwogICAgICAgICAgICAgICAgVUJvb2wgICAgICAgICAgb3BlcmF0b3IhPShjb25zdCAgICBMb2NhbGUmICAgICBvdGhlcikgY29uc3Q7CgogICAgLyoqCiAgICAgKiBDb21tb24gbWV0aG9kcyBvZiBnZXR0aW5nIHRoZSBjdXJyZW50IGRlZmF1bHQgTG9jYWxlLiBVc2VkIGZvciB0aGUKICAgICAqIHByZXNlbnRhdGlvbjogbWVudXMsIGRpYWxvZ3MsIGV0Yy4gR2VuZXJhbGx5IHNldCBvbmNlIHdoZW4geW91ciBhcHBsZXQgb3IKICAgICAqIGFwcGxpY2F0aW9uIGlzIGluaXRpYWxpemVkLCB0aGVuIG5ldmVyIHJlc2V0LiAoSWYgeW91IGRvIHJlc2V0IHRoZQogICAgICogZGVmYXVsdCBsb2NhbGUsIHlvdSBwcm9iYWJseSB3YW50IHRvIHJlbG9hZCB5b3VyIEdVSSwgc28gdGhhdCB0aGUgY2hhbmdlCiAgICAgKiBpcyByZWZsZWN0ZWQgaW4geW91ciBpbnRlcmZhY2UuKQogICAgICoKICAgICAqIE1vcmUgYWR2YW5jZWQgcHJvZ3JhbXMgd2lsbCBhbGxvdyB1c2VycyB0byB1c2UgZGlmZmVyZW50IGxvY2FsZXMgZm9yCiAgICAgKiBkaWZmZXJlbnQgZmllbGRzLCBlLmcuIGluIGEgc3ByZWFkc2hlZXQuCiAgICAgKgogICAgICogTm90ZSB0aGF0IHRoZSBpbml0aWFsIHNldHRpbmcgd2lsbCBtYXRjaCB0aGUgaG9zdCBzeXN0ZW0uCiAgICAgKiBAc3lzdGVtCiAgICAgKiBAc3RhYmxlCiAgICAgKi8KICAgIHN0YXRpYyAgTG9jYWxlJiAgICAgICAgICAgICBnZXREZWZhdWx0KHZvaWQpOwoKICAgIC8qKgogICAgICogU2V0cyB0aGUgZGVmYXVsdC4gTm9ybWFsbHkgc2V0IG9uY2UgYXQgdGhlIGJlZ2lubmluZyBvZiBhcHBsZXQgb3IKICAgICAqIGFwcGxpY2F0aW9uLCB0aGVuIG5ldmVyIHJlc2V0LiBzZXREZWZhdWx0IGRvZXMgTk9UIHJlc2V0IHRoZSBob3N0IGxvY2FsZS4KICAgICAqCiAgICAgKiBAcGFyYW0gbmV3TG9jYWxlIExvY2FsZSB0byBzZXQgdG8uCiAgICAgKiBAc3lzdGVtCiAgICAgKiBAc3RhYmxlCiAgICAgKi8KICAgIHN0YXRpYyAgICAgIHZvaWQgICAgICAgICAgICBzZXREZWZhdWx0KGNvbnN0ICAgIExvY2FsZSYgICAgIG5ld0xvY2FsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmICBzdWNjZXNzKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGxvY2FsZSdzIHR3by1sZXR0ZXIgSVNPLTYzOSBsYW5ndWFnZSBjb2RlLgogICAgICogQHJldHVybiAgICAgIEFuIGFsaWFzIHRvIHRoZSBjb2RlCiAgICAgKiBAZHJhZnQKICAgICAqLwogICAgICAgICAgICAgICAgY29uc3QgY2hhciAqICBnZXRMYW5ndWFnZSggKSBjb25zdDsKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgbG9jYWxlJ3MgdHdvLWxldHRlciBJU08tMzE2NiBjb3VudHJ5IGNvZGUuCiAgICAgKiBAcmV0dXJuICAgICAgQW4gYWxpYXMgdG8gdGhlIGNvZGUKICAgICAqIEBkcmFmdAogICAgICovCiAgICAgICAgICAgICAgICBjb25zdCBjaGFyICogICBnZXRDb3VudHJ5KCApIGNvbnN0OwogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBsb2NhbGUncyB2YXJpYW50IGNvZGUuCiAgICAgKiBAcmV0dXJuICAgICAgQW4gYWxpYXMgdG8gdGhlIGNvZGUKICAgICAqIEBkcmFmdAogICAgICovCiAgICAgICAgICAgICAgICBjb25zdCBjaGFyICogIGdldFZhcmlhbnQoICkgY29uc3Q7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBwcm9ncmFtbWF0aWMgbmFtZSBvZiB0aGUgZW50aXJlIGxvY2FsZSwgd2l0aCB0aGUgbGFuZ3VhZ2UsCiAgICAgKiBjb3VudHJ5IGFuZCB2YXJpYW50IHNlcGFyYXRlZCBieSB1bmRlcmJhcnMuIElmIGEgZmllbGQgaXMgbWlzc2luZywgdXAKICAgICAqIHRvIHR3byBsZWFkaW5nIHVuZGVyYmFycyB3aWxsIG9jY3VyLiBFeGFtcGxlOiAiZW4iLCAiZGVfREUiLCAiZW5fVVNfV0lOIiwKICAgICAqICJkZV9fUE9TSVgiLCAiZnJfX01BQyIsICJfX01BQyIsICJfTVQiLCAiX0ZSX0VVUk8iCiAgICAgKiBAcmV0dXJuICAgICAgQSBwb2ludGVyIHRvICJuYW1lIi4KICAgICAqLwogICAgICAgICAgICAgICAgY29uc3QgY2hhciAqIGdldE5hbWUoKSBjb25zdDsKCiAgICAvKioKICAgICAqIHJldHVybnMgdGhlIGxvY2FsZSdzIHRocmVlLWxldHRlciBsYW5ndWFnZSBjb2RlLCBhcyBzcGVjaWZpZWQKICAgICAqIGluIElTTyBkcmFmdCBzdGFuZGFyZCBJU08tNjM5LTIuLgogICAgICogQHJldHVybiAgICAgIEFuIGFsaWFzIHRvIHRoZSBjb2RlLCBvciBOVUxMCiAgICAgKiBAZHJhZnQKICAgICAqLwogICAgICAgICAgICAgICAgY29uc3QgY2hhciAqIGdldElTTzNMYW5ndWFnZSgpIGNvbnN0OwoKICAgIC8qKgogICAgICogRmlsbHMgaW4gIm5hbWUiIHdpdGggdGhlIGxvY2FsZSdzIHRocmVlLWxldHRlciBJU08tMzE2NiBjb3VudHJ5IGNvZGUuCiAgICAgKiBAcmV0dXJuICAgICAgQW4gYWxpYXMgdG8gdGhlIGNvZGUsIG9yIE5VTEwKICAgICAqIEBkcmFmdAogICAgICovCiAgICAgICAgICAgICAgICBjb25zdCBjaGFyICogZ2V0SVNPM0NvdW50cnkoKSBjb25zdDsKCiNpZm5kZWYgSUNVX0xPQ0lEX05PX0RFUFJFQ0FURVMKLy8gYmVnaW4gZGVwcmVjYXRlZCB2ZXJzaW9ucwoKICAgIC8qKgogICAgICogRmlsbHMgaW4gImxhbmciIHdpdGggdGhlIGxvY2FsZSdzIHR3by1sZXR0ZXIgSVNPLTYzOSBsYW5ndWFnZSBjb2RlLgogICAgICogQHBhcmFtIGxhbmcgIFJlY2VpdmVzIHRoZSBsYW5ndWFnZSBjb2RlLgogICAgICogQHJldHVybiAgICAgIEEgcmVmZXJlbmNlIHRvICJsYW5nIgogICAgICogQGRlcHJlY2F0ZWQgUmVtb3ZlIGluIHRoZSBmaXJzdCByZWxlYXNlIG9mIDIwMDEuCiAgICAgKi8KICAgICAgICAgICAgICAgIFVuaWNvZGVTdHJpbmcmICAgIGdldExhbmd1YWdlKCAgICAgICAgVW5pY29kZVN0cmluZyYgIGxhbmcpIGNvbnN0OwogICAgLyoqCiAgICAgKiBGaWxscyBpbiAiY250cnkiIHdpdGggdGhlIGxvY2FsZSdzIHR3by1sZXR0ZXIgSVNPLTMxNjYgY291bnRyeSBjb2RlLgogICAgICogQHBhcmFtIGNudHJ5IFJlY2VpdmVzIHRoZSBjb3VudHJ5IGNvZGUuCiAgICAgKiBAcmV0dXJuICAgICAgQSByZWZlcmVuY2UgdG8gImNudHJ5Ii4KICAgICAqIEBkZXByZWNhdGVkIFJlbW92ZSBpbiB0aGUgZmlyc3QgcmVsZWFzZSBvZiAyMDAxLgogICAgICovCiAgICAgICAgICAgICAgICBVbmljb2RlU3RyaW5nJiAgIGdldENvdW50cnkoICAgICAgICAgVW5pY29kZVN0cmluZyYgIGNudHJ5KSBjb25zdDsKICAgIC8qKgogICAgICogRmlsbHMgaW4gInZhciIgd2l0aCB0aGUgbG9jYWxlJ3MgdmFyaWFudCBjb2RlLgogICAgICogQHBhcmFtIHZhciAgIFJlY2VpdmVzIHRoZSB2YXJpYW50IGNvZGUuCiAgICAgKiBAcmV0dXJuICAgICAgQSByZWZlcmVuY2UgdG8gInZhciIuCiAgICAgKiBAZGVwcmVjYXRlZCBSZW1vdmUgaW4gdGhlIGZpcnN0IHJlbGVhc2Ugb2YgMjAwMS4KICAgICAqLwogICAgICAgICAgICAgICAgVW5pY29kZVN0cmluZyYgIGdldFZhcmlhbnQoICAgICAgICAgVW5pY29kZVN0cmluZyYgIHZhcikgY29uc3Q7CgogICAgLyoqCiAgICAgKiBGaWxscyBpbiAibmFtZSIgdGhlIHByb2dyYW1tYXRpYyBuYW1lIG9mIHRoZSBlbnRpcmUgbG9jYWxlLCB3aXRoIHRoZSBsYW5ndWFnZSwKICAgICAqIGNvdW50cnkgYW5kIHZhcmlhbnQgc2VwYXJhdGVkIGJ5IHVuZGVyYmFycy4gSWYgYSBmaWVsZCBpcyBtaXNzaW5nLCBhdAogICAgICogbW9zdCBvbmUgdW5kZXJiYXIgd2lsbCBvY2N1ci4gRXhhbXBsZTogImVuIiwgImRlX0RFIiwgImVuX1VTX1dJTiIsCiAgICAgKiAiZGVfUE9TSVgiLCAiZnJfTUFDIgogICAgICogQHBhcmFtIHZhciAgIFJlY2VpdmVzIHRoZSBwcm9ncmFtbWF0aWMgbG9jYWxlIG5hbWUuCiAgICAgKiBAcmV0dXJuICAgICAgQSByZWZlcmVuY2UgdG8gIm5hbWUiLgogICAgICogQGRlcHJlY2F0ZWQgUmVtb3ZlIGluIHRoZSBmaXJzdCByZWxlYXNlIG9mIDIwMDEuCiAgICAgKi8KICAgICAgICAgICAgICAgIFVuaWNvZGVTdHJpbmcmICBnZXROYW1lKCAgICAgICAgVW5pY29kZVN0cmluZyYgIG5hbWUpIGNvbnN0OwoKCiAgICAvKioKICAgICAqIEZpbGxzIGluICJuYW1lIiB3aXRoIHRoZSBsb2NhbGUncyB0aHJlZS1sZXR0ZXIgbGFuZ3VhZ2UgY29kZSwgYXMgc3BlY2lmaWVkCiAgICAgKiBpbiBJU08gZHJhZnQgc3RhbmRhcmQgSVNPLTYzOS0yLi4KICAgICAqIEBwYXJhbSBuYW1lICBSZWNlaXZlcyB0aGUgdGhyZWUtbGV0dGVyIGxhbmd1YWdlIGNvZGUuCiAgICAgKiBAcGFyYW0gc3RhdHVzIEFuIFVFcnJvckNvZGUgdG8gcmVjZWl2ZSBhbnkgTUlTU0lOR19SRVNPVVJDRV9FUlJPUnMKICAgICAqIEByZXR1cm4gICAgICBBIHJlZmVyZW5jZSB0byAibmFtZSIuCiAgICAgKiBAZGVwcmVjYXRlZCBSZW1vdmUgaW4gdGhlIGZpcnN0IHJlbGVhc2Ugb2YgMjAwMS4KICAgICAqLwogICAgICAgICAgICAgICAgVW5pY29kZVN0cmluZyYgIGdldElTTzNMYW5ndWFnZShVbmljb2RlU3RyaW5nJiAgbmFtZSwgVUVycm9yQ29kZSYgc3RhdHVzKSBjb25zdDsKCiAgICAvKioKICAgICAqIEZpbGxzIGluICJuYW1lIiB3aXRoIHRoZSBsb2NhbGUncyB0aHJlZS1sZXR0ZXIgSVNPLTMxNjYgY291bnRyeSBjb2RlLgogICAgICogQHBhcmFtIG5hbWUgIFJlY2VpdmVzIHRoZSB0aHJlZS1sZXR0ZXIgY291bnRyeSBjb2RlLgogICAgICogQHBhcmFtIHN0YXR1cyBBbiBVRXJyb3JDb2RlIHRvIHJlY2VpdmUgYW55IE1JU1NJTkdfUkVTT1VSQ0VfRVJST1JzCiAgICAgKiBAcmV0dXJuICAgICAgQSByZWZlcmVuY2UgdG8gIm5hbWUiLgogICAgICogQGRlcHJlY2F0ZWQgUmVtb3ZlIGluIHRoZSBmaXJzdCByZWxlYXNlIG9mIDIwMDEuCiAgICAgKi8KICAgICAgICAgICAgICAgIFVuaWNvZGVTdHJpbmcmICBnZXRJU08zQ291bnRyeSggVW5pY29kZVN0cmluZyYgIG5hbWUsIFVFcnJvckNvZGUmIHN0YXR1cykgY29uc3Q7CgovLyBFTkQgZGVwcmVjYXRlZCBbIElDVV9MT0NJRF9OT19ERVBSRUNBVEVTIF0KI2VuZGlmIC8vIElDVV9MT0NJRF9OT19ERVBSRUNBVEVTCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIFdpbmRvd3MgTENJRCB2YWx1ZSBjb3JyZXNwb25kaW5nIHRvIHRoaXMgbG9jYWxlLgogICAgICogVGhpcyB2YWx1ZSBpcyBzdG9yZWQgaW4gdGhlIHJlc291cmNlIGRhdGEgZm9yIHRoZSBsb2NhbGUgYXMgYSBvbmUtdG8tZm91ci1kaWdpdAogICAgICogaGV4YWRlY2ltYWwgbnVtYmVyLiAgSWYgdGhlIHJlc291cmNlIGlzIG1pc3NpbmcsIGluIHRoZSB3cm9uZyBmb3JtYXQsIG9yCiAgICAgKiB0aGVyZSBpcyBubyBXaW5kb3dzIExDSUQgdmFsdWUgdGhhdCBjb3JyZXNwb25kcyB0byB0aGlzIGxvY2FsZSwgcmV0dXJucyAwLgogICAgICogQHN0YWJsZQogICAgICovCiAgICAgICAgICAgICAgICB1aW50MzJfdCAgICAgICAgZ2V0TENJRCh2b2lkKSBjb25zdDsKCiAgICAvKioKICAgICAqIEZpbGxzIGluICJkaXNwTGFuZyIgd2l0aCB0aGUgbmFtZSBvZiB0aGlzIGxvY2FsZSdzIGxhbmd1YWdlIGluIGEgZm9ybWF0IHN1aXRhYmxlIGZvcgogICAgICogdXNlciBkaXNwbGF5IGluIHRoZSBkZWZhdWx0IGxvY2FsZS4gIEZvciBleGFtcGxlLCBpZiB0aGUgbG9jYWxlJ3MgbGFuZ3VhZ2UgY29kZSBpcwogICAgICogImZyIiBhbmQgdGhlIGRlZmF1bHQgbG9jYWxlJ3MgbGFuZ3VhZ2UgY29kZSBpcyAiZW4iLCB0aGlzIGZ1bmN0aW9uIHdvdWxkIHNldAogICAgICogZGlzcExhbmcgdG8gIkZyZW5jaCIuCiAgICAgKiBAcGFyYW0gZGlzcExhbmcgIFJlY2VpdmVzIHRoZSBsYW5ndWFnZSdzIGRpc3BsYXkgbmFtZS4KICAgICAqIEByZXR1cm4gICAgICAgICAgQSByZWZlcmVuY2UgdG8gImRpc3BMYW5nIi4KICAgICAqIEBzdGFibGUKICAgICAqLwogICAgICAgICAgICAgICAgVW5pY29kZVN0cmluZyYgIGdldERpc3BsYXlMYW5ndWFnZShVbmljb2RlU3RyaW5nJiAgIGRpc3BMYW5nKSBjb25zdDsKCiAgICAvKioKICAgICAqIEZpbGxzIGluICJkaXNwTGFuZyIgd2l0aCB0aGUgbmFtZSBvZiB0aGlzIGxvY2FsZSdzIGxhbmd1YWdlIGluIGEgZm9ybWF0IHN1aXRhYmxlIGZvcgogICAgICogdXNlciBkaXNwbGF5IGluIHRoZSBsb2NhbGUgc3BlY2lmaWVkIGJ5ICJpbkxvY2FsZSIuICBGb3IgZXhhbXBsZSwgaWYgdGhlIGxvY2FsZSdzCiAgICAgKiBsYW5ndWFnZSBjb2RlIGlzICJlbiIgYW5kIGluTG9jYWxlJ3MgbGFuZ3VhZ2UgY29kZSBpcyAiZnIiLCB0aGlzIGZ1bmN0aW9uIHdvdWxkIHNldAogICAgICogZGlzcExhbmcgdG8gIkFuZ2xhaXMiLgogICAgICogQHBhcmFtIGluTG9jYWxlICBTcGVjaWZpZXMgdGhlIGxvY2FsZSB0byBiZSB1c2VkIHRvIGRpc3BsYXkgdGhlIG5hbWUuICBJbiBvdGhlciB3b3JkcywKICAgICAqICAgICAgICAgICAgICAgICAgaWYgdGhlIGxvY2FsZSdzIGxhbmd1YWdlIGNvZGUgaXMgImVuIiwgcGFzc2luZyBMb2NhbGU6OkZSRU5DSCBmb3IKICAgICAqICAgICAgICAgICAgICAgICAgaW5Mb2NhbGUgd291bGQgcmVzdWx0IGluICJBbmdsYWlzIiwgd2hpbGUgcGFzc2luZyBMb2NhbGU6OkdFUk1BTgogICAgICogICAgICAgICAgICAgICAgICBmb3IgaW5Mb2NhbGUgd291bGQgcmVzdWx0IGluICJFbmdsaXNjaCIuCiAgICAgKiBAcGFyYW0gZGlzcExhbmcgIFJlY2VpdmVzIHRoZSBsYW5ndWFnZSdzIGRpc3BsYXkgbmFtZS4KICAgICAqIEByZXR1cm4gICAgICAgICAgQSByZWZlcmVuY2UgdG8gImRpc3BMYW5nIi4KICAgICAqIEBzdGFibGUKICAgICAqLwogICAgICAgICAgICAgICAgVW5pY29kZVN0cmluZyYgIGdldERpc3BsYXlMYW5ndWFnZSggY29uc3QgICBMb2NhbGUmICAgICAgICAgaW5Mb2NhbGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVuaWNvZGVTdHJpbmcmICBkaXNwTGFuZykgY29uc3Q7CiAgICAvKioKICAgICAqIEZpbGxzIGluICJkaXNwQ291bnRyeSIgd2l0aCB0aGUgbmFtZSBvZiB0aGlzIGxvY2FsZSdzIGNvdW50cnkgaW4gYSBmb3JtYXQgc3VpdGFibGUKICAgICAqIGZvciB1c2VyIGRpc3BsYXkgaW4gdGhlIGRlZmF1bHQgbG9jYWxlLiAgRm9yIGV4YW1wbGUsIGlmIHRoZSBsb2NhbGUncyBjb3VudHJ5IGNvZGUKICAgICAqIGlzICJGUiIgYW5kIHRoZSBkZWZhdWx0IGxvY2FsZSdzIGxhbmd1YWdlIGNvZGUgaXMgImVuIiwgdGhpcyBmdW5jdGlvbiB3b3VsZCBzZXQKICAgICAqIGRpc3BDb3VudHJ5IHRvICJGcmFuY2UiLgogICAgICogQHBhcmFtIGRpc3BDb3VudHJ5ICAgUmVjZWl2ZXMgdGhlIGNvdW50cnkncyBkaXNwbGF5IG5hbWUuCiAgICAgKiBAcmV0dXJuICAgICAgICAgICAgICBBIHJlZmVyZW5jZSB0byAiZGlzcENvdW50cnkiLgogICAgICogQHN0YWJsZQogICAgICovCiAgICAgICAgICAgICAgICBVbmljb2RlU3RyaW5nJiAgZ2V0RGlzcGxheUNvdW50cnkoICAgICAgICAgIFVuaWNvZGVTdHJpbmcmIGRpc3BDb3VudHJ5KSBjb25zdDsKICAgIC8qKgogICAgICogRmlsbHMgaW4gImRpc3BDb3VudHJ5IiB3aXRoIHRoZSBuYW1lIG9mIHRoaXMgbG9jYWxlJ3MgY291bnRyeSBpbiBhIGZvcm1hdCBzdWl0YWJsZQogICAgICogZm9yIHVzZXIgZGlzcGxheSBpbiB0aGUgbG9jYWxlIHNwZWNpZmllZCBieSAiaW5Mb2NhbGUiLiAgRm9yIGV4YW1wbGUsIGlmIHRoZSBsb2NhbGUncwogICAgICogY291bnRyeSBjb2RlIGlzICJVUyIgYW5kIGluTG9jYWxlJ3MgbGFuZ3VhZ2UgY29kZSBpcyAiZnIiLCB0aGlzIGZ1bmN0aW9uIHdvdWxkIHNldAogICAgICogZGlzcENvdW50cnkgdG8gIkV0YXRzLVVuaXMiLgogICAgICogQHBhcmFtIGluTG9jYWxlICAgICAgU3BlY2lmaWVzIHRoZSBsb2NhbGUgdG8gYmUgdXNlZCB0byBkaXNwbGF5IHRoZSBuYW1lLiAgSW4gb3RoZXIKICAgICAqICAgICAgICAgICAgICAgICAgICAgIHdvcmRzLCBpZiB0aGUgbG9jYWxlJ3MgY291bnRyeSBjb2RlIGlzICJVUyIsIHBhc3NpbmcKICAgICAqICAgICAgICAgICAgICAgICAgICAgIExvY2FsZTo6RlJFTkNIIGZvciBpbkxvY2FsZSB3b3VsZCByZXN1bHQgaW4gIsl0YXRzLVVuaXMiLCB3aGlsZQogICAgICogICAgICAgICAgICAgICAgICAgICAgcGFzc2luZyBMb2NhbGU6OkdFUk1BTiBmb3IgaW5Mb2NhbGUgd291bGQgcmVzdWx0IGluCiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAiVmVyZWluaWd0ZSBTdGFhdGVuIi4KICAgICAqIEBwYXJhbSBkaXNwQ291bnRyeSAgIFJlY2VpdmVzIHRoZSBjb3VudHJ5J3MgZGlzcGxheSBuYW1lLgogICAgICogQHJldHVybiAgICAgICAgICAgICAgQSByZWZlcmVuY2UgdG8gImRpc3BDb3VudHJ5Ii4KICAgICAqIEBzdGFibGUKICAgICAqLwogICAgICAgICAgICAgICAgVW5pY29kZVN0cmluZyYgIGdldERpc3BsYXlDb3VudHJ5KCAgY29uc3QgICBMb2NhbGUmICAgICAgICAgaW5Mb2NhbGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVuaWNvZGVTdHJpbmcmICBkaXNwQ291bnRyeSkgY29uc3Q7CgogICAgLyoqCiAgICAgKiBGaWxscyBpbiAiZGlzcFZhciIgd2l0aCB0aGUgbmFtZSBvZiB0aGlzIGxvY2FsZSdzIHZhcmlhbnQgY29kZSBpbiBhIGZvcm1hdCBzdWl0YWJsZQogICAgICogZm9yIHVzZXIgZGlzcGxheSBpbiB0aGUgZGVmYXVsdCBsb2NhbGUuCiAgICAgKiBAcGFyYW0gZGlzcFZhciAgIFJlY2VpdmVzIHRoZSB2YXJpYW50J3MgbmFtZS4KICAgICAqIEByZXR1cm4gICAgICAgICAgQSByZWZlcmVuY2UgdG8gImRpc3BWYXIiLgogICAgICogQHN0YWJsZQogICAgICovCiAgICAgICAgICAgICAgICBVbmljb2RlU3RyaW5nJiAgZ2V0RGlzcGxheVZhcmlhbnQoICAgICAgVW5pY29kZVN0cmluZyYgZGlzcFZhcikgY29uc3Q7CiAgICAvKioKICAgICAqIEZpbGxzIGluICJkaXNwVmFyIiB3aXRoIHRoZSBuYW1lIG9mIHRoaXMgbG9jYWxlJ3MgdmFyaWFudCBjb2RlIGluIGEgZm9ybWF0CiAgICAgKiBzdWl0YWJsZSBmb3IgdXNlciBkaXNwbGF5IGluIHRoZSBsb2NhbGUgc3BlY2lmaWVkIGJ5ICJpbkxvY2FsZSIuCiAgICAgKiBAcGFyYW0gaW5Mb2NhbGUgIFNwZWNpZmllcyB0aGUgbG9jYWxlIHRvIGJlIHVzZWQgdG8gZGlzcGxheSB0aGUgbmFtZS4KICAgICAqIEBwYXJhbSBkaXNwVmFyICAgUmVjZWl2ZXMgdGhlIHZhcmlhbnQncyBkaXNwbGF5IG5hbWUuCiAgICAgKiBAcmV0dXJuICAgICAgICAgIEEgcmVmZXJlbmNlIHRvICJkaXNwVmFyIi4KICAgICAqIEBzdGFibGUKICAgICAqLwogICAgICAgICAgICAgICAgVW5pY29kZVN0cmluZyYgIGdldERpc3BsYXlWYXJpYW50KCAgY29uc3QgICBMb2NhbGUmICAgICAgICAgaW5Mb2NhbGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVuaWNvZGVTdHJpbmcmICBkaXNwVmFyKSBjb25zdDsKICAgIC8qKgogICAgICogRmlsbHMgaW4gIm5hbWUiIHdpdGggdGhlIG5hbWUgb2YgdGhpcyBsb2NhbGUgaW4gYSBmb3JtYXQgc3VpdGFibGUgZm9yIHVzZXIgZGlzcGxheSAKICAgICAqIGluIHRoZSBkZWZhdWx0IGxvY2FsZS4gIFRoaXMgZnVuY3Rpb24gdXNlcyBnZXREaXNwbGF5TGFuZ3VhZ2UoKSwgZ2V0RGlzcGxheUNvdW50cnkoKSwKICAgICAqIGFuZCBnZXREaXNwbGF5VmFyaWFudCgpIHRvIGRvIGl0cyB3b3JrLCBhbmQgb3V0cHV0cyB0aGUgZGlzcGxheSBuYW1lIGluIHRoZSBmb3JtYXQKICAgICAqICJsYW5ndWFnZSAoY291bnRyeVssdmFyaWFudF0pIi4gIEZvciBleGFtcGxlLCBpZiB0aGUgZGVmYXVsdCBsb2NhbGUgaXMgZW5fVVMsIHRoZW4KICAgICAqIGZyX0ZSJ3MgZGlzcGxheSBuYW1lIHdvdWxkIGJlICJGcmVuY2ggKEZyYW5jZSkiLCBhbmQgZXNfTVhfVHJhZGl0aW9uYWwncyBkaXNwbGF5IG5hbWUKICAgICAqIHdvdWxkIGJlICJTcGFuaXNoIChNZXhpY28sVHJhZGl0aW9uYWwpIi4KICAgICAqIEBwYXJhbSBuYW1lICBSZWNlaXZlcyB0aGUgbG9jYWxlJ3MgZGlzcGxheSBuYW1lLgogICAgICogQHJldHVybiAgICAgIEEgcmVmZXJlbmNlIHRvICJuYW1lIi4KICAgICAqIEBzdGFibGUKICAgICAqLwogICAgICAgICAgICAgICAgVW5pY29kZVN0cmluZyYgIGdldERpc3BsYXlOYW1lKCAgICAgICAgIFVuaWNvZGVTdHJpbmcmICBuYW1lKSBjb25zdDsKICAgIC8qKgogICAgICogRmlsbHMgaW4gIm5hbWUiIHdpdGggdGhlIG5hbWUgb2YgdGhpcyBsb2NhbGUgaW4gYSBmb3JtYXQgc3VpdGFibGUgZm9yIHVzZXIgZGlzcGxheSAKICAgICAqIGluIHRoZSBsb2NhbGUgc3BlY2ZpZWQgYnkgImluTG9jYWxlIi4gIFRoaXMgZnVuY3Rpb24gdXNlcyBnZXREaXNwbGF5TGFuZ3VhZ2UoKSwKICAgICAqIGdldERpc3BsYXlDb3VudHJ5KCksIGFuZCBnZXREaXNwbGF5VmFyaWFudCgpIHRvIGRvIGl0cyB3b3JrLCBhbmQgb3V0cHV0cyB0aGUgZGlzcGxheQogICAgICogbmFtZSBpbiB0aGUgZm9ybWF0ICJsYW5ndWFnZSAoY291bnRyeVssdmFyaWFudF0pIi4gIEZvciBleGFtcGxlLCBpZiBpbkxvY2FsZSBpcwogICAgICogZnJfRlIsIHRoZW4gZW5fVVMncyBkaXNwbGF5IG5hbWUgd291bGQgYmUgIkFuZ2xhaXMgKMl0YXRzLVVuaXMpIiwgYW5kIG5vX05PX05ZJ3MKICAgICAqIGRpc3BsYXkgbmFtZSB3b3VsZCBiZSAibm9ydulnaWVuIChOb3J26GdlLE5ZKSIuCiAgICAgKiBAcGFyYW0gaW5Mb2NhbGUgIFNwZWNpZmllcyB0aGUgbG9jYWxlIHRvIGJlIHVzZWQgdG8gZGlzcGxheSB0aGUgbmFtZS4KICAgICAqIEBwYXJhbSBuYW1lICAgICAgUmVjZWl2ZXMgdGhlIGxvY2FsZSdzIGRpc3BsYXkgbmFtZS4KICAgICAqIEByZXR1cm4gICAgICAgICAgQSByZWZlcmVuY2UgdG8gIm5hbWUiLgogICAgICogQHN0YWJsZQogICAgICovCiAgICAgICAgICAgICAgICBVbmljb2RlU3RyaW5nJiAgZ2V0RGlzcGxheU5hbWUoIGNvbnN0ICAgTG9jYWxlJiAgICAgICAgIGluTG9jYWxlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVuaWNvZGVTdHJpbmcmICBuYW1lKSBjb25zdDsKICAgIC8qKgogICAgICogR2VuZXJhdGVzIGEgaGFzaCBjb2RlIGZvciB0aGUgbG9jYWxlLgogICAgICogQHN0YWJsZQogICAgICovCiAgICAgICAgICAgICAgICBpbnQzMl90ICAgICAgICAgaGFzaENvZGUodm9pZCkgY29uc3Q7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGEgbGlzdCBvZiBhbGwgaW5zdGFsbGVkIGxvY2FsZXMuCiAgICAgKiBAcGFyYW0gY291bnQgUmVjZWl2ZXMgdGhlIG51bWJlciBvZiBsb2NhbGVzIGluIHRoZSBsaXN0LgogICAgICogQHJldHVybiAgICAgIEEgcG9pbnRlciB0byBhbiBhcnJheSBvZiBMb2NhbGUgb2JqZWN0cy4gIFRoaXMgYXJyYXkgaXMgdGhlIGxpc3QKICAgICAqICAgICAgICAgICAgICBvZiBhbGwgbG9jYWxlcyB3aXRoIGluc3RhbGxlZCByZXNvdXJjZSBmaWxlcy4gIFRoZSBjYWxsZWQgZG9lcyBOT1QKICAgICAqICAgICAgICAgICAgICBnZXQgb3duZXJzaGlwIG9mIHRoaXMgbGlzdCwgYW5kIG11c3QgTk9UIGRlbGV0ZSBpdC4KICAgICAqIEBzdGFibGUKICAgICAqLwogICAgc3RhdGljICBjb25zdCAgIExvY2FsZSogICAgIGdldEF2YWlsYWJsZUxvY2FsZXMoaW50MzJfdCYgY291bnQpOwoKICAgIC8qKgogICAgICogR2V0cyBhIGxpc3Qgb2YgYWxsIGF2YWlsYWJsZSAyLWxldHRlciBjb3VudHJ5IGNvZGVzIGRlZmluZWQgaW4gSVNPIDYzOS4gIFRoaXMgaXMgYQogICAgICogcG9pbnRlciB0byBhbiBhcnJheSBvZiBwb2ludGVycyB0byBhcnJheXMgb2YgY2hhci4gIEFsbCBvZiB0aGVzZSBwb2ludGVycyBhcmUKICAgICAqIG93bmVkIGJ5IElDVS0tIGRvIG5vdCBkZWxldGUgdGhlbSwgYW5kIGRvIG5vdCB3cml0ZSB0aHJvdWdoIHRoZW0uICBUaGUgYXJyYXkgaXMKICAgICAqIHRlcm1pbmF0ZWQgd2l0aCBhIG51bGwgcG9pbnRlci4KICAgICAqIEByZXR1cm4gYSBsaXN0IG9mIGFsbCBhdmFpbGFibGUgY291bnRyeSBjb2RlcwogICAgICogQGRyYWZ0CiAgICAgKi8KICAgIHN0YXRpYyBjb25zdCBjaGFyKiBjb25zdCogZ2V0SVNPQ291bnRyaWVzKCk7CgogICAgLyoqCiAgICAgKiBHZXRzIGEgbGlzdCBvZiBhbGwgYXZhaWxhYmxlIGxhbmd1YWdlIGNvZGVzIGRlZmluZWQgaW4gSVNPIDYzOS4gIFRoaXMgaXMgYSBwb2ludGVyCiAgICAgKiB0byBhbiBhcnJheSBvZiBwb2ludGVycyB0byBhcnJheXMgb2YgY2hhci4gIEFsbCBvZiB0aGVzZSBwb2ludGVycyBhcmUgb3duZWQKICAgICAqIGJ5IElDVS0tIGRvIG5vdCBkZWxldGUgdGhlbSwgYW5kIGRvIG5vdCB3cml0ZSB0aHJvdWdoIHRoZW0uICBUaGUgYXJyYXkgaXMKICAgICAqIHRlcm1pbmF0ZWQgd2l0aCBhIG51bGwgcG9pbnRlci4KICAgICAqIEByZXR1cm4gYSBsaXN0IG9mIGFsbCBhdmFpbGFibGUgbGFuZ3VhZ2UgY29kZXMKICAgICAqIEBkcmFmdAogICAgICovCiAgICBzdGF0aWMgY29uc3QgY2hhciogY29uc3QqICBnZXRJU09MYW5ndWFnZXMoKTsKCgojaWZuZGVmIElDVV9MT0NJRF9OT19ERVBSRUNBVEVTCiAgICAvKioKICAgICAqIFJldHVybnMgYSBsaXN0IG9mIGFsbCAyLWxldHRlciBjb3VudHJ5IGNvZGVzIGRlZmluZWQgaW4gSVNPIDMxNjYuCiAgICAgKiBDYW4gYmUgdXNlZCB0byBjcmVhdGUgTG9jYWxlcy4KICAgICAqIEBwYXJhbSBjb3VudCBSZWNlaXZlcyB0aGUgbnVtYmVyIG9mIGNvdW50cmllcyBpbiB0aGUgbGlzdC4KICAgICAqIEByZXR1cm4gQSBwb2ludGVyIHRvIGFuIGFycmF5IG9mIFVuaWNvZGVTdHJpbmcgb2JqZWN0cy4gVGhlIGNhbGxlciBkb2VzIE5PVAogICAgICogIGdldCBvd25lcnNoaXAgb2YgdGhpcyBsaXN0LCBhbmQgbXVzdCBOT1QgZGVsZXRlIGl0LgogICAgICogQGRlcHJlY2F0ZWQgUmVtb3ZlIGluIHRoZSBmaXJzdCByZWxlYXNlIG9mIDIwMDEuCiAgICAgKi8KICAgIHN0YXRpYyBjb25zdCBVbmljb2RlU3RyaW5nKiBnZXRJU09Db3VudHJpZXMoaW50MzJfdCYgY291bnQpOwoKICAgIC8qKgogICAgICogUmV0dXJucyBhIGxpc3Qgb2YgYWxsIDItbGV0dGVyIGxhbmd1YWdlIGNvZGVzIGRlZmluZWQgaW4gSVNPIDYzOS4KICAgICAqIENhbiBiZSB1c2VkIHRvIGNyZWF0ZSBMb2NhbGVzLgogICAgICogW05PVEU6ICBJU08gNjM5IGlzIG5vdCBhIHN0YWJsZSBzdGFuZGFyZC0tIHNvbWUgbGFuZ3VhZ2VzJyBjb2RlcyBoYXZlIGNoYW5nZWQuCiAgICAgKiBUaGUgbGlzdCB0aGlzIGZ1bmN0aW9uIHJldHVybnMgaW5jbHVkZXMgYm90aCB0aGUgbmV3IGFuZCB0aGUgb2xkIGNvZGVzIGZvciB0aGUKICAgICAqIGxhbmd1YWdlcyB3aG9zZSBjb2RlcyBoYXZlIGNoYW5nZWQuXQogICAgICogQHBhcmFtIGNvdW50IFJlY2VpdmVzIHRoZSBudW1iZXIgb2YgbGFuZ3VhZ2VzIGluIHRoZSBsaXN0LgogICAgICogQHJldHVybiBBIHBvaW50ZXIgdG8gYW4gYXJyYXkgb2YgVW5pY29kZVN0cmluZyBvYmplY3RzLiBUaGUgY2FsbGVyIGRvZXMgTk9UCiAgICAgKiAgZ2V0IG93bmVyc2hpcCBvZiB0aGlzIGxpc3QsIGFuZCBtdXN0IE5PVCBkZWxldGUgaXQuCiAgICAgKiBAZGVwcmVjYXRlZCBSZW1vdmUgaW4gdGhlIGZpcnN0IHJlbGVhc2Ugb2YgMjAwMS4KICAgICAqLwogICAgc3RhdGljIGNvbnN0IFVuaWNvZGVTdHJpbmcqIGdldElTT0xhbmd1YWdlcyhpbnQzMl90JiBjb3VudCk7CiNlbmRpZiAvLyBJQ1VfTE9DSURfTk9fREVQUkVDQVRFUwogICAgCnByb3RlY3RlZDogLy8gb25seSBwcm90ZWN0ZWQgZm9yIHRlc3RpbmcgcHVycG9zZXMuIERPIE5PVCBVU0UuCiAgICB2b2lkIHNldEZyb21QT1NJWElEKGNvbnN0IGNoYXIgKnBvc2l4SUQpOyAvLyBzZXQgaXQgZnJvbSBhIHNpbmdsZSBzdHJpbmcuCgogICAgLyoqCiAgICAgKiBHaXZlbiBhbiBJU08gY291bnRyeSBjb2RlLCByZXR1cm5zIGFuIGFycmF5IG9mIFN0cmluZ3MgY29udGFpbmluZyB0aGUgSVNPCiAgICAgKiBjb2RlcyBvZiB0aGUgbGFuZ3VhZ2VzIHNwb2tlbiBpbiB0aGF0IGNvdW50cnkuICBPZmZpY2lhbCBsYW5ndWFnZXMgYXJlIGxpc3RlZAogICAgICogaW4gdGhlIHJldHVybmVkIHRhYmxlIGJlZm9yZSB1bm9mZmljaWFsIGxhbmd1YWdlcywgYnV0IG90aGVyIHRoYW4gdGhhdCwgdGhlCiAgICAgKiBvcmRlciBvZiB0aGUgcmV0dXJuZWQgbGlzdCBpcyBpbmRldGVybWluYXRlLiAgSWYgdGhlIHZhbHVlIHRoZSB1c2VyIHBhc3NlcyBpbgogICAgICogZm9yICJjb3VudHJ5IiBpcyBub3QgYSB2YWxpZCBJU08gMzE2IGNvdW50cnkgY29kZSwgb3IgaWYgd2UgZG9uJ3QgaGF2ZSBsYW5ndWFnZQogICAgICogaW5mb3JtYXRpb24gZm9yIHRoZSBzcGVjaWZpZWQgY291bnRyeSwgdGhpcyBmdW5jdGlvbiByZXR1cm5zIGFuIGVtcHR5IGFycmF5LgogICAgICoKICAgICAqIFtUaGlzIGZ1bmN0aW9uIGlzIG5vdCBjdXJyZW50bHkgcGFydCBvZiBMb2NhbGUncyBBUEksIGJ1dCBpcyBuZWVkZWQgaW4gdGhlCiAgICAgKiBpbXBsZW1lbnRhdGlvbi4gIFdlIGhvcGUgdG8gYWRkIGl0IHRvIHRoZSBBUEkgaW4gYSBmdXR1cmUgcmVsZWFzZS5dCiAgICAgKiBAcGFyYW0gY291bnRyeSBUaGUgSVNPIDItbGV0dGVyIGNvdW50cnkgY29kZSBvZiB0aGUgZGVzaXJlZCBjb3VudHJ5CiAgICAgKiBAcGFyYW0gY291bnQgUmVjZWl2ZXMgdGhlIG51bWJlciBvZiBsYW5ndWFnZXMgaW4gdGhlIGxpc3QuCiAgICAgKiBAcmV0dXJuIEEgcG9pbnRlciB0byBhbiBhcnJheSBvZiBVbmljb2RlU3RyaW5nIG9iamVjdHMuIFRoZSBjYWxsZXIgZG9lcyBOT1QKICAgICAqICBnZXQgb3duZXJzaGlwIG9mIHRoaXMgbGlzdCwgYW5kIG11c3QgTk9UIGRlbGV0ZSBpdC4KICAgICAqLwogICAgc3RhdGljIGNvbnN0IFVuaWNvZGVTdHJpbmcqIGdldExhbmd1YWdlc0ZvckNvdW50cnkoICAgIGNvbnN0IFVuaWNvZGVTdHJpbmcmIGNvdW50cnksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludDMyX3QmIGNvdW50KTsKCgpwcml2YXRlOgogICAgLyoqCiAgICAgKiBJbml0aWFsaXplIHRoZSBsb2NhbGUgb2JqZWN0IHdpdGggYSBuZXcgbmFtZS4KICAgICAqIFdhcyBkZXByZWNhdGVkIC0gdXNlZCBpbiBpbXBsZW1lbnRhdGlvbiAtIG1vdmVkIGludGVybmFsCiAgICAgKgogICAgICogQHBhcmFtIGNMb2NhbGVJRCBUaGUgbmV3IGxvY2FsZSBuYW1lLgogICAgICovCiAgICBMb2NhbGUmIGluaXQoY29uc3QgY2hhciogY0xvY2FsZUlEKTsKICAgIAogICAgCiAgICBjaGFyIGxhbmd1YWdlW1VMT0NfTEFOR19DQVBBQ0lUWV07CiAgICBjaGFyIGNvdW50cnlbVUxPQ19DT1VOVFJZX0NBUEFDSVRZXTsKICAgIGNoYXIqIHZhcmlhbnQ7CiAgICBjaGFyKiBmdWxsTmFtZTsKICAgIGNoYXIgZnVsbE5hbWVCdWZmZXJbVUxPQ19GVUxMTkFNRV9DQVBBQ0lUWV07CiAgICAKICAgIHN0YXRpYyBMb2NhbGUgKmxvY2FsZUxpc3Q7CiAgICBzdGF0aWMgaW50MzJfdCBsb2NhbGVMaXN0Q291bnQ7CgovLyBCZWdpbiBkZXByZWNhdGVkIGZpZWxkcwogICAgc3RhdGljIFVuaWNvZGVTdHJpbmcgKmlzb0xhbmd1YWdlczsKICAgIHN0YXRpYyBpbnQzMl90IGlzb0xhbmd1YWdlc0NvdW50OwogICAgc3RhdGljIFVuaWNvZGVTdHJpbmcgKmlzb0NvdW50cmllczsKICAgIHN0YXRpYyBpbnQzMl90IGlzb0NvdW50cmllc0NvdW50OwovLyBFbmQgZGVwcmVjYXRlZCBmaWVsZHMKCiAgICBzdGF0aWMgVUhhc2h0YWJsZSAqY3RyeTJMYW5nTWFwcGluZzsKICAgIHN0YXRpYyBjb25zdCBVbmljb2RlU3RyaW5nIGNvbXByZXNzZWRDdHJ5MkxhbmdNYXBwaW5nOwoKICAgIHN0YXRpYyBMb2NhbGUgZmdEZWZhdWx0TG9jYWxlOwoKZnJpZW5kICB2b2lkIGxvY2FsZV9zZXRfZGVmYXVsdF9pbnRlcm5hbChjb25zdCBjaGFyICopOwoKfTsKCmlubGluZSBVQm9vbApMb2NhbGU6Om9wZXJhdG9yIT0oY29uc3QgICAgTG9jYWxlJiAgICAgb3RoZXIpIGNvbnN0CnsKICAgIHJldHVybiAhb3BlcmF0b3I9PShvdGhlcik7Cn0KCiNlbmRpZgoKCg==