From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: jan via "Bug reports for GNU Emacs, the Swiss army knife of text editors" Newsgroups: gmane.emacs.bugs Subject: bug#48871: 27.2; Unusably slow in C# mode Date: Sun, 6 Jun 2021 15:53:11 +0100 Message-ID: References: <835yyri2f2.fsf@gnu.org> <83y2bngl0b.fsf@gnu.org> Reply-To: jan Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="00000000000089580f05c41a1588" Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="29838"; mail-complaints-to="usenet@ciao.gmane.io" Cc: 48871@debbugs.gnu.org To: Eli Zaretskii Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Sun Jun 06 16:54:17 2021 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1lpuAK-0007OG-UT for geb-bug-gnu-emacs@m.gmane-mx.org; Sun, 06 Jun 2021 16:54:17 +0200 Original-Received: from localhost ([::1]:33626 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lpuAI-0004gh-Rw for geb-bug-gnu-emacs@m.gmane-mx.org; Sun, 06 Jun 2021 10:54:14 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:48906) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lpuA6-0004gU-5K for bug-gnu-emacs@gnu.org; Sun, 06 Jun 2021 10:54:02 -0400 Original-Received: from debbugs.gnu.org ([209.51.188.43]:42149) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1lpuA5-0000Qq-UO for bug-gnu-emacs@gnu.org; Sun, 06 Jun 2021 10:54:01 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1lpuA5-0002uv-RO for bug-gnu-emacs@gnu.org; Sun, 06 Jun 2021 10:54:01 -0400 X-Loop: help-debbugs@gnu.org Resent-From: jan Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sun, 06 Jun 2021 14:54:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 48871 X-GNU-PR-Package: emacs Original-Received: via spool by 48871-submit@debbugs.gnu.org id=B48871.162299120111159 (code B ref 48871); Sun, 06 Jun 2021 14:54:01 +0000 Original-Received: (at 48871) by debbugs.gnu.org; 6 Jun 2021 14:53:21 +0000 Original-Received: from localhost ([127.0.0.1]:53696 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1lpu9R-0002tv-4W for submit@debbugs.gnu.org; Sun, 06 Jun 2021 10:53:21 -0400 Original-Received: from mail-pg1-f170.google.com ([209.85.215.170]:45622) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1lpu9P-0002tj-E9 for 48871@debbugs.gnu.org; Sun, 06 Jun 2021 10:53:19 -0400 Original-Received: by mail-pg1-f170.google.com with SMTP id q15so11803958pgg.12 for <48871@debbugs.gnu.org>; Sun, 06 Jun 2021 07:53:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=googlemail.com; s=20161025; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :cc; bh=HdjIrsLolbsvmILfGGnComIW2VbKgYr3rZFG4wqLKEU=; b=FSPtcCj6shgjtd/cb8ZjLnr6m7h4MQAeNAVxhciwGon+4vnT1aPtYl9v2Rvttj/2Ig 8p6jIRcHxfJvtXXYDyRGz5h3LGv66KRxdynilgqfXEx0IxVgYIdJa0OF7iIuzhGEpjor XdZz92fC8Kkjp60Fv28kyLg9PQDmsPiw426UB65J06st5W9tmEAXUSKMptEGr+wDXD55 7RuHoF78SJbE/owzj9E7uxYYHRVDd1541cQX2oTIKWYMTv73R/BZfrvrBjRT/qgloDQB avYR9dnMOFTdgpX/NfjUgUIMGlxxvP8XRhnD3PDMgsD2cRNcMu/WIxMK9FMlz7VAXQn1 pqKg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to:cc; bh=HdjIrsLolbsvmILfGGnComIW2VbKgYr3rZFG4wqLKEU=; b=XZqn/UjDSfvOunStmnYqdE7o2N+xWU4aiaeeNqFHt4CsKWvh6MtuKVrackSvhpc89C q1u2tCDLe9rEk+tEZc9qG8EwPNzatVh/GR/CjO+uD/jDD+M5buY0aFVzdkOsFuN/bqJZ QFNfJYbXfoBGrt4LikhFvNLcV/S77WJ6ueEn4sKfHStp6+mVliWZe3i9y4+IzM4XXehf CwVX9sOuByx+ep7gEwJammzfUJ+AXsV3PMmJgd5grx1FI10bLNZxoho0mK1ycEBbWJ+q ViMLYjCPWTmOzgiFnxRIAw6+s4hVLEyZtwQ5HwGpX98ZPc0eREW+qlLZzl2WqY0qq+dr MRSw== X-Gm-Message-State: AOAM5333xhwbGmrKDhgpswEulzFr+qygodo3Z9N1LsTj58VETl17lZGy 1PHmKHm04mNiq6eZj79Rjw6LTRDxG5qjJtcmUHk= X-Google-Smtp-Source: ABdhPJxRqSmY2FlvE792xc+NnnHMX2MbWe26uiIwcR685+XqviZ6WMl0YIxWdRw9NfUgtmdnPJwWPvUfRKgwdVjKvkQ= X-Received: by 2002:a63:a805:: with SMTP id o5mr9593565pgf.328.1622991193057; Sun, 06 Jun 2021 07:53:13 -0700 (PDT) Original-Received: by 2002:a17:90a:aa06:0:0:0:0 with HTTP; Sun, 6 Jun 2021 07:53:11 -0700 (PDT) In-Reply-To: <83y2bngl0b.fsf@gnu.org> X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Original-Sender: "bug-gnu-emacs" Xref: news.gmane.io gmane.emacs.bugs:208132 Archived-At: --00000000000089580f05c41a1588 Content-Type: text/plain; charset="UTF-8" Hi, I don't recall installing c# but may well have happened. >From package-list-packages: csharp-mode 20210328.2004 installed C# mode derived mode Which does not say built-in so likely I did. Looking in the unzipped emacs 27.2 , no relevant *sharp* file in it, and did find it in the elpa directory, so I guess must have. Started with -Q. Did the M-x load-file for csharp-mode.el (FYI also had to do load-file for csharp-compilation.el before that to make it happy). Finally got to load the C# file itself, exactly the same. No faster. Troublesome C# file attached. cheers jan On 06/06/2021, Eli Zaretskii wrote: >> From: jan >> Date: Sun, 6 Jun 2021 14:34:19 +0100 >> Cc: 48871@debbugs.gnu.org >> >> had already tried the -Q option. Emacs started but when I tried "M-x >> csharp-mode" it didn't recognise it. I tried exactly the same on the >> normally-started emacs to check I was entering it correctly and that >> did understand it. >> I guess the -Q effectively disables some modes? I was surprised. >> >> Yep, customisation may well be the issue here. > > So let's try to figure out why "emacs -Q" fails to load csharp-mode. > Since there's no such mode bundled with Emacs, I guess you downloaded > it from somewhere? Then try this: > > emacs -Q > M-x load-file RET /path/to/csharp-mode.el RE > > The last line assumes that the Lisp file which defines the function > csharp-mode is called csharp-mode.el; if not, change the file name to > fit the reality. Also, "/path/to/" should be replaced with the actual > absolute file name of the file on your system. > > Then say what you tried: > > M-x csharp-mode RET > > If that still doesn't work, please show the error messages. Likely > they will identify packages csharp-mode depends on that you also need > to load with "M-x load-file". > >> I have a file of equivalent size which should demo the issue but can't >> zip it as gmail blocks anything with a zip attached, I can post as >> attachment directly but it's 220KBytes, you ok with that on your >> mailing list? > > Yes, it's okay. But let's first try and see whether "emacs -Q" > exhibits the same problem, okay? > --00000000000089580f05c41a1588 Content-Type: text/plain; charset="UTF-8"; name="expression.cs" Content-Disposition: attachment; filename="expression.cs" Content-Transfer-Encoding: base64 X-Attachment-Id: file0 77u/Ly8gRm9yIHJlcHJvZHVjaW5nIGVtYWNzIGlzc3VlIG9mIHNsb3cgcmVzcG9uc2UgaW4gQyMg bW9kZS4NCi8vIElnbm9yZSBhbnkgc3dlYXJpbmcuIA0KDQp1c2luZyBBbnRscjQuUnVudGltZS5U cmVlOyAgLy8gZmFxIC0gbmVlZCB0aGlzIGZvciBQYXJzZVRyZWVQcm9wZXJ0eQ0KdXNpbmcgU3lz dGVtOw0KdXNpbmcgU3lzdGVtLkNvbGxlY3Rpb25zLkdlbmVyaWM7DQp1c2luZyBTeXN0ZW0uVGV4 dDsNCg0KdXNpbmcgc3RhdGljIExEQi5MREJ1dGlsczsNCnVzaW5nIHN0YXRpYyBMREIuVHlwZXNC cm9hZGx5Ow0KdXNpbmcgc3RhdGljIExEQi5JbnN0RnVsbHlPclBhcnRseTsNCnVzaW5nIHN0YXRp YyBMREIuZXJyb3JIYW5kbGluZzsNCnVzaW5nIHN0YXRpYyBMREIuU3ltVGFiOw0KDQp1c2luZyBT eXN0ZW0uTGlucTsNCnVzaW5nIFN5c3RlbS5EaWFnbm9zdGljcy5Db2RlQW5hbHlzaXM7ICAvLyB3 aGVyZSBmcm9tPyB3aHk/IC0gdG9kbw0KDQp1c2luZyBzdGF0aWMgTERCLmdsb2JhbHM7DQoNCg0K Ly8gQ2F1c2VkIHRyb3VibGUgYnV0IHdhcyBnZW5lcmFsbHkgd29ydGggaXQ7IGNhdWdodCBhIGZl dyBidWdzIGFuZA0KLy8gd2lsbCBwcm9iYWJseSBjYXRjaCBhIGZldyBtb3JlLiBZZXAsIGRlZmlu aXRlbHkgd29ydGggaXQhDQovLw0KLy8NCi8vIENlcnRhaW4gbWV0aG9kcy9wcm9wZXJ0aWVzIChl LmcuIHRoZSBuYW1lIHByb3BlcnR5KSB3ZXJlIGRlY2xhcmVkDQovLyBpbiBhYnN0cmFjdCBzdXBl cmNsYXNzZXMgYnV0IHdoZW4gSSBhZGRlZCAnI251bGxhYmxlIGVuYWJsZScgdGhleQ0KLy8gc3Rh cnRlZCByZXBvcnRpbmcgbnVsbGFiaWxpdHkgZXJyb3JzLiBJIGNvdWxkIGVpdGhlciBkaXNhYmxl IHRob3NlDQovLyB3aXRoICI9IG51bGwhIiwgdG90YWxseSBkZWZlYXRpbmcgdGhlIHBvaW50LCBv ciBkZWFsIHdpdGggdGhlbQ0KLy8gcHJvcGVybHkgYnkgcHVsbGluZyB0aG9zZSBtZXRob2RzL3By b3BlcnRpZXMgZG93biBpbnRvIHRoZSBjb25jcmV0ZQ0KLy8gc3ViY2xhc3Nlcywgd2hpY2ggd2Fz IG1vcmUgdmVyYm9zZSBhbmQgaW4gc29tZSBzZW5zZSBsZXNzDQovLyBlbmNhcHN1bGF0ZWQuIElu IHRoZSBtYWluLCBJIGNob3NlIHRvIGRvIHRoYXQgdG8gZ2V0IHN0YXRpYw0KLy8gZ3VhcmFudGVl cy4NCiNudWxsYWJsZSBlbmFibGUNCg0KDQovKg0KDQpUaGlzIG1vZHVsZSBpcyBjYWxsZWQgZXhw cmVzc2lvbnMgYmVjYXVzZSB0aGF0J3Mgd2hlcmUgSSBzdGFydGVkLCBhbmQNClNRTCBhdCBoZWFy dCBpcyBhbiBleHByZXNzaW9uIGxhbmd1YWdlLCBob3dldmVyIHRoZXJlIHdpbGwgYmUNCm5vbi1l eHByZXNzaW9uIGNvbnN0cnVjdHMgc3VjaCBhcyBpZiBhbmQgbG9vcHMsIGFuZCB0aGV5IGdvIGhl cmUgYXMNCndlbGwuDQoNCiovDQoNCm5hbWVzcGFjZSBMREIgew0KDQoJcHVibGljIGludGVyZmFj ZSBJaGFuZGxlUHJlZml4ZXM8VD4NCgkJCQkJCXdoZXJlIFQgOiBMREJSb290IHsNCg0KCQlwdWJs aWMgYm9vbCBpc1ByZWZpeGVkIHsgZ2V0OyB9DQoNCgkJcHVibGljIGJvb2wgaXNFeGNlc3NQcmVm aXhlZCB7IGdldDsgfQ0KDQoJCS8vIFRoZSBUIGluIGFkZFByZWZpeC9yZVByZWZpeC93aXRob3V0 UHJlZml4IGlzIGJlY2F1c2Ugd2UgbWF5IGJlIA0KCQkvLyByZXR1cm5pbmcgZWcuIGEgbGlzdCBv ZiBpdGVtcyB3aXRoIHByZWZpeGVzIA0KCQkvLyB0aHVzIG1vZGlmaWVkLCBub3QgYSBzaW5nbGUg UE1RSWRlbnQNCg0KCQlwdWJsaWMgVCBhZGRQcmVmaXgoUE1RSWRlbnQgcGZ4KTsNCg0KCQlwdWJs aWMgVCByZVByZWZpeChQTVFJZGVudCBuZXdwZngpOw0KDQovLwkJcHVibGljIFQgc3RyaXBQcmVm aXgoUE1RSWRlbnQgaWQpOw0KCX0NCgkvLyB0b2RvIC0gbW92ZSB0aGlzDQoNCg0KDQoNCg0KCXB1 YmxpYyBhYnN0cmFjdCBjbGFzcyBMREJSb290IHsNCgkJLy8gUm9vdCBvZiBldmVyeXRoaW5nIExE Qi1pc2gNCg0KCQlwdWJsaWMgYm9vbCBFcXVhbHMoW0FsbG93TnVsbF0gTERCUm9vdCBvdGhlcikg ew0KCQkJdGhyb3cgbmV3IExEQlNob3VsZE5vdEJlSW1wbGVtZW50ZWRFeGNlcHRpb24oDQoJCQkJ CQkJCQkiY2FsbGVkIEVxdWFscyBvbiBMREJSb290Iik7DQoJCX0NCg0KCQlwdWJsaWMgb3ZlcnJp ZGUNCgkJCWJvb2wgRXF1YWxzKFtBbGxvd051bGxdIE9iamVjdCBvdGhlcikgew0KCQkJdGhyb3cg bmV3IExEQlNob3VsZE5vdEJlSW1wbGVtZW50ZWRFeGNlcHRpb24oDQoJCQkJCQkJCQkiY2FsbGVk IEVxdWFscyBpbiBPYmplY3QiKTsNCgkJfQ0KDQoJCXB1YmxpYyBvdmVycmlkZSBpbnQgR2V0SGFz aENvZGUoKSB7DQoJCQl0aHJvdyBuZXcgTERCU2hvdWxkTm90QmVJbXBsZW1lbnRlZEV4Y2VwdGlv bigNCgkJCQkJCQkJCSJjYWxsZWQgR2V0SGFzaENvZGUgaW4gTERCUm9vdCIpOw0KCQl9DQoNCgkJ cHVibGljIHN0YXRpYyBib29sIG9wZXJhdG9yID09KExEQlJvb3QgbGhzLA0KCQkJCQkJCQkJICAg TERCUm9vdCByaHMpIHsNCgkJCXRocm93IG5ldyBMREJTaG91bGROb3RCZUltcGxlbWVudGVkRXhj ZXB0aW9uKA0KCQkJCQkJCQkJImNhbGxlZCA9PSBpbiBMREJSb290Iik7DQoJCX0NCg0KCQlwdWJs aWMgc3RhdGljIGJvb2wgb3BlcmF0b3IgIT0oTERCUm9vdCBsaHMsDQoJCQkJCQkJCQkgICBMREJS b290IHJocykgew0KCQkJdGhyb3cgbmV3IExEQlNob3VsZE5vdEJlSW1wbGVtZW50ZWRFeGNlcHRp b24oDQoJCQkJCQkJCQkiY2FsbGVkICE9IGluIExEQlJvb3QiKTsNCgkJfQ0KDQoNCgkJcHVibGlj IHZpcnR1YWwgc3RyaW5nIGNsYXNzTmFtZSB7DQoJCQkvLyB0b2RvIC0gdGhpcyBuZWVkcyBjaGVj a2luZyBpdCB3b3JrcyBhcyBJIHdhbnQNCgkJCS8vIGFsc28gcmVuYW1lIHRvIGxkYmNsYXNzbmFt ZSAtLSB0b2RvDQoJCQlnZXQgPT4gdGhpcy5HZXRUeXBlKCkuRnVsbE5hbWUgPz8gIih1bmtub3du KSI7DQoJCX0NCg0KDQoJCXB1YmxpYyB2aXJ0dWFsIHN0cmluZyBjbGFzc05hbWVRID0+DQoJCQki JyIgKyBjbGFzc05hbWUgKyAiJyI7DQoNCg0KCQlwdWJsaWMgdmlydHVhbCBzdHJpbmcgY2xhc3NO YW1lUGx1cyhzdHJpbmcgcGx1cykgPT4NCgkJCWNsYXNzTmFtZSArICIuIiArIHBsdXM7DQoNCgkJ cHVibGljIG92ZXJyaWRlIHN0cmluZyBUb1N0cmluZygpIHsNCgkJCS8vIFRoaXMgaW1wbGljaXQg dG8tc3RyaW5nIGNvbnZlcnNpb24gY3JhcCBjb3N0IG1lIGEgZmV3IGhvdXJzLCBzbyBhdCBsZWFz dA0KCQkJLy8gZG8gdGhpcyAmIGJsb3cgdXAgYXQgcnVudGltZS4gV291bGQgcHJlZmVyIGNvbXBp bGUgdGltZSBidXQgaXQgc2VlbXMNCgkJCS8vIG5vdCBwb3NzaWJsZS4gIFRoaXMgdHVybnMgb3V0 IHRvIGhhdmUgYmVlbiBhIGdvb2QgaWRlYSwNCgkJCS8vIHNhdmVkIG1lIHF1aXRlIGEgYml0IG1v cmUgZGVidWdnaW5nIQ0KCQkJLy8gPGh0dHBzOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25z LzE1MzQ1NTE3L2lzLWl0LXBvc3NpYmxlLXRvLWRpc2FibGUtaW1wbGljaXQtdG9zdHJpbmctY2Fs bD4NCgkJCS8vIFdpbGwgdHJ5IDxodHRwczovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy81 NDM1NDM0Mi9ob3ctdG8tZ2V0LWFuLWVycm9yLXNob3duLXdoZW4tdXNpbmctbm9uLXN0cmluZ3Mt YXMtc3RyaW5ncy1pbnN0ZWFkLW9mLWFuLWF1dG9tLzU0MzU1MTE1IzU0MzU1MTE1KQ0KCQkJdmFy IG1zZyA9ICJMREJSb290LlRvU3RyaW5nKCkiOw0KCQkJdGhyb3cgbmV3IExEQlRvU3RyaW5nSW1w bGljdENvbnZlcnNpb25FeGNlcHRpb24obXNnKTsNCgkJfQ0KDQoJCXB1YmxpYyBhYnN0cmFjdCBz dHJpbmcgdG9EZWJ1Z1N0cigpOw0KCX0NCg0KDQoNCglwdWJsaWMgYWJzdHJhY3QgY2xhc3MgRXBo ZW1lcmFsIDogTERCUm9vdCB7DQoJCS8vIGZvciBvYmplY3RzIHRoYXQgYXJlIG5vdCBwYXJ0IG9m IHRoZSBBU1QNCgl9DQoNCg0KDQoJcHVibGljIGludGVyZmFjZSBJV2l0aExpbmVOVW0geyAgLy8g dG9kbyAtIHVzZSBvciByZW1vdmUgLSB0b2RvDQoJCS8vCXB1YmxpYyANCgl9DQoNCg0KCXB1Ymxp YyBpbnRlcmZhY2UgSUhhc1RhYmxlQWxpYXMgew0KCQkvLyBIYXMgYSB0YWJsZSBhbGlhcyBBU1Qg b2JqLiBNYXkgYmUgYSAuLi5NaXNzaW5nIHN1YnR5cGUgaW4gd2hpY2gNCgkJLy8gaXQgaGFzIG5v IGFsaWFzIGdpdmVuIGJ5IHRoZSB1c2VyLCBidXQgYWxpYXMgQVNUIGlzIHRoZXJlLiBNb3JlDQoJ CS8vIGFjY3VyYXRlbHkgYSBUYWJsZVNvdXJjZSBhbGlhcyBidXQgb2sNCgkJcHVibGljIGFic3Ry YWN0IFRhYmxlQWxpYXMgdGEgeyBnZXQ7IHNldDsgfQ0KCX0NCg0KDQoJLy8gQmFzZSBjbGFzcyBm b3IgYWxsIExEQiBBU1Qgb2JqZWN0cw0KCXB1YmxpYyBhYnN0cmFjdCBjbGFzcyBMREJBU1RvYmog OiBMREJSb290IHsNCgkJLy8gVGhpcyBvbmUgaXMgYSBwcm9ibGVtLiBJZiBJIGRlY2xhcmUgdGhl ICdwYXJlbnQnIHByb3BlcnR5DQoJCS8vIGFic3RyYWN0IEkgdGhlbiBoYXZlIHRvIGltcGxlbWVu dCBpdCBsaXRlcmFsbHkgaHVuZHJlZHMgb2YNCgkJLy8gdGltZXMgaW4gdGhlIGRlcml2ZWQgY2xh c3NlcywgYW5kIEkgcmVhbGx5IGRvbid0IHRoaW5rIGl0DQoJCS8vIHdvdWxkIGhlbHAgc28ganVz dCBzZXQgaXQgdG8gYSBkZWZhdWx0IHdoaWNoIGdldHMgb3ZlcndyaXR0ZW4gbGF0ZXIuDQoJCS8v IA0KCQkvLyBUaGUgcHJvYmxlbSBpcyB0aGF0IHRob3NlIG9iamVjdHMgd2VyZSBjcmVhdGVkIGJ5 IHRoZQ0KCQkvLyBwYXJzZXIsIHdoaWNoIGNyZWF0ZXMgdGhlbSBib3R0b20tdXAsIHdoaWNoIG1l YW5zIHlvdSBjYW4ndA0KCQkvLyBrbm93IHRoZSBwYXJlbnQgd2hlbiB0aGV5IGFyZSBjcmVhdGVk LiBJdCBzaG91bGQgYmUNCgkJLy8gcG9zc2libGUgdG8gd29yayBhcm91bmQgdGhpcyBidXQgaXQg ZG9lcyBtZWFuIHJld29ya2luZyB0aGUNCgkJLy8gcGFyc2VyIGZ1bmRhbWVudGFsbHksIGFuZCBJ J20gbm90IGdvaW5nIHRvIGRvIHRoYXQNCgkJLy8gYXNzdW1laW5nIGl0J3MgZXZlbiBwb3NzaWJs ZS4NCg0KCQkvLyB0b2RvIC0gcmVhZCB1cCBvbiBwcml2L3B1Yi9wcm9nIGFjY2Vzc29ycyBJIHJl YWxseSBkb24ndA0KCQkvLyBnZXQgdGhlc2UgYXQgYWxsDQoJCXB1YmxpYyBMREJBU1RvYmogcGFy ZW50IHsgZ2V0OyBwcml2YXRlIHNldDsgfQ0KCQkJCQkJPSBub1BhcmVudDsNCgkJLy8gVW5pcXVl IElEIHBlciBvYmplY3QsIHVzZWZ1bCBmb3IgZGlzdGluZ3Vpc2hpbmcgdGhlbQ0KCQkvLyB3aXRo b3V0IGdlbmVyYWwgZXF1YWxpdHkuDQoJCXJlYWRvbmx5IHB1YmxpYyB1bG9uZyB1aWQgPSBuZXdV SUQoKTsNCg0KCQkvLyBwdWJsaWMgYWJzdHJhY3QgaW50IGxpbmVOdW0geyBnZXQ7IHNldDsgfQ0K DQoJCS8vIElzIHZhbGlkYXRlZCBpcyBhIGNoZWFwaXNoIGNoZWNrIHRvIGVuc3VyZSBldmVyeXRo aW5nIGdldHMNCgkJLy8gdmFsaWRhdGVkDQoJCS8vIGNhbiBkbyB0aGlzIGFzIGF1dG8gcHJvcD8g dG9kbw0KCQlwcml2YXRlIGJvb2wgX3ZhbGlkYXRlZCA9IGZhbHNlOw0KDQoJCXByb3RlY3RlZCBi b29sIHZhbGlkYXRlZCB7DQoJCQlnZXQgPT4gX3ZhbGlkYXRlZDsNCgkJCXNldCB7DQoJCQkJLy8g aGFyZE11c3QoIXZhbGlkYXRlZCwgIi4uLiBhbHJlYWR5IHZhbGlkYXRlZC4uLiAiKTsgLSBubw0K CQkJCS8vIEl0J3MgaGFyZCB0byBhdm9pZCB2YWxpZGF0aW5nIGEgdGhpbmcgdHdpY2UsIHNvIGZv ciBub3cgYWxsb3cgaXQNCgkJCQkvLyBMb29rIGludG8gaXQgbGF0ZXIsIHJlYWxseSBzaG91bGRu J3QgaGFwcGVuDQoJCQkJX3ZhbGlkYXRlZCA9IHRydWU7DQoJCQl9DQoJCX0NCg0KCQlwdWJsaWMg TERCU3RydWN0c0NoaWxkcmVuIGtpZHMgeyBnZXQ7IHByaXZhdGUgc2V0OyB9ID0NCgkJCQkJbmV3 IExEQlN0cnVjdHNDaGlsZHJlbihub1BhcmVudCk7IC8vIGp1c3QgZWFzaWVyDQoNCgkJcHVibGlj IExEQkFTVG9iaigpIHsgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8v Ly8vLy8vLy8vLy8vLy8vLy8vLy8vLy8gdG9kbyBkZWFkPw0KCQkJCQkJCSAgLy8gVlN0dWRpbyB0 aGlua3MgdGhpcyBoYXMgemVybyByZWZlcmVuY2VzLCB3aGljaCBpcyB0cnVlIGV4cGxpY2l0bHks IGJ1dCBpdCdzIA0KCQkJCQkJCSAgLy8gY2FsbGVkIGltcGxpY2l0bHkgb24gZXZlcnkgb2JqIGNy ZWF0aW9uIC0gb3Igc2hvdWxkIGRvIHRvZG8tIGNoZWNrDQoJCQlpZiAocmVjb3JkT2JqZWN0c0Ny ZWF0ZWQpIHsNCgkJCQlBbGxDcmVhdGVkSXRlbXMuQWRkKHRoaXMpOw0KCQkJfQ0KCQl9DQoNCg0K CQlwdWJsaWMgdmlydHVhbCB2b2lkIHZhbGlkYXRlKCkgew0KCQkJaWYgKHJlcG9ydEFsc29JZlZh bGlkYXRpb25PSykgew0KCQkJCWRlYnVnbXNnKCJ2YWxpZGF0aW5nLi4uIiArIGNsYXNzTmFtZQ0K CQkJCQkrICIgKCIgKyBhc05hbWVPcklkZW50Q29udGVudHMoKSArICIpIik7DQoJCQl9DQoJCQlt aHBfbWhrKCk7DQoJCQlraWRzLnZhbGlkYXRlKCk7DQoJCQkvLyB2YWxpZGF0ZWQgPSB0cnVlOyAt LSBObywgZ2V0IGVhY2ggc3ViY2xhc3MgdG8gc2V0DQoJCQkvLyB2YWxpZGF0ZWQuIFRoYXQgZm9y Y2VzIGFuIGV4cGxpY2l0IGNhbGwgdG8gYmFzZSgpIHdoaWNoDQoJCQkvLyBpcyBtb3JlIGNvZGUg YnV0IG9rLg0KCQl9DQoNCg0KCQlwdWJsaWMgYm9vbCBpc1ZhbGlkYXRlZCB7IGdldCA9PiB2YWxp ZGF0ZWQ7IH0gIC8vIHRvZG8ganVzdCA9PiB2YWxpZGF0ZWQ7DQoNCg0KCQlwdWJsaWMgdmlydHVh bCBib29sIGlzVG9wTGV2ZWxJdGVtU2VxID0+IGZhbHNlOw0KDQoNCgkJcHVibGljIHZpcnR1YWwg dm9pZCBtaHBfbWhrKCkgeyAgLy8gZG9uJ3QgdGhpbmsgdGhpcyBuZWVkIGJlIHZpcnR1YWwgLSB0 b2RvPw0KCQkJCQkJCQkJCSAvLyA9IG11c3QgaGF2ZSBwYXJlbnQsIG11c3QgaGF2ZSBraWRzLiBU aGUga2lkcyBtYXkgYmUgdGhlDQoJCQkJCQkJCQkJIC8vIGVtcHR5IHNldCBhbmQgdGhlIHBhcmVu dCBtYXkgYmUgbm9QYXJlbnQgYnV0IHRoZXkgbXVzdA0KCQkJCQkJCQkJCSAvLyBleGlzdC4NCgkJ CQkJCQkJCQkgLy8gV2h5IG5vdCBqdXN0IGlubGluZSB0aGlzIGludG8gdmFsaWRhdGUoKT8NCgkJ CQkJCQkJCQkgLy8gQmVjYXVzZSBhIGZldyBjbGFzc2VzIG5lZWQgYmVzcG9rZSB2YWxpZGF0aW9u LCBidXQgc3RpbGwgbXVzdCBjaGVjayB0aGlzLg0KCQkJaGFyZE11c3RQYXJlbnRJc1ByZXNlbnQo KTsNCgkJCWtpZHMuZWFjaEtpZFBhcmVudE11c3RCZSh0aGlzKTsNCgkJfQ0KDQoNCgkJcHVibGlj IHN0cmluZyBhc05hbWVPcklkZW50Q29udGVudHMoKSB7DQoJCQkvLyBmb3IgdmVyeSBjcnVkZSBk ZWJ1Z2dpbmcgDQoJCQl2YXIgb3B0TmFtZSA9IHRoaXMgaXMgSWlzTmFtZWRJdGVtIG5pID8gbmku bmFtZS50b1Jhd1N0cigpIDogIiI7DQoJCQlvcHROYW1lID0gKG9wdE5hbWUgPT0gIiIgJiYgdGhp cyBpcyBQTVFJZGVudCkgPyB0aGlzLnRvUmF3U3RyKCkgOiAiIjsNCg0KCQkJdmFyIG9wdE5hbWUy ID0gb3B0TmFtZSArICIgICh1aWQ6IiArIHVpZC5Ub1N0cmluZygpICsgIikgIg0KCQkJCSsgZ2V0 Rmlyc3RGZXdDaGFyc09mKHRvUmF3U3RyKCkpOw0KCQkJcmV0dXJuIG9wdE5hbWUyOw0KCQl9DQoN Cg0KCQlwdWJsaWMgdmlydHVhbCB2b2lkIGdldEFsbFVJRHMoVUlEc2V0IHVpZHMpIHsNCgkJCXVp ZHMuQWRkKHRoaXMpOw0KCQkJa2lkcy5Gb3JFYWNoKG5hbWVkS2lkID0+IG5hbWVkS2lkLmtpZC5n ZXRBbGxVSURzKHVpZHMpKTsNCgkJfQ0KDQoNCgkJcHVibGljIGJvb2wgaXNTdHViUGFyZW50IHsg Z2V0ID0+ICh0aGlzIGlzIE5vUGFyZW50KSB8fCAodGhpcyBpcyBGYWtlUGFyZW50KTsgfQ0KDQoN CgkJcHVibGljIHZvaWQgdmFsaWRhdGVTcGVjaWZpY0l0ZW1zKHBhcmFtcyBMREJBU1RvYmpbXSBp dGVtcykgew0KCQkJQXJyYXkuRm9yRWFjaChpdGVtcywgaXRlbSA9PiBpdGVtLnZhbGlkYXRlKCkp Ow0KCQl9DQoNCg0KCQlwdWJsaWMgVD8gb3B0Q2xpbWJUbzxUPigpIHdoZXJlIFQgOiBMREJBU1Rv Ymogew0KCQkJdmFyIHJlc0l0ZW0gPSB0aGlzOw0KCQkJd2hpbGUgKCEocmVzSXRlbSBpcyBUKSkg ew0KCQkJCWlmIChyZXNJdGVtLnBhcmVudC5pc1N0dWJQYXJlbnQpIHsNCgkJCQkJcmV0dXJuIG51 bGw7DQoJCQkJfQ0KCQkJCXJlc0l0ZW0gPSByZXNJdGVtLnBhcmVudDsNCgkJCX0NCg0KCQkJdmFy IHJlcyA9IHJlc0l0ZW0gYXMgVDsNCgkJCXJldHVybiByZXM7DQoJCX0NCg0KDQoJCXB1YmxpYyBU IHJlcUNsaW1iVG88VD4oKSB3aGVyZSBUIDogTERCQVNUb2JqIHsNCgkJCXZhciBsb2MgPSBjbGFz c05hbWUgKyAiLnJlcUNsaW1iVG88VD4oKSI7DQoJCQl2YXIgcmVzID0gb3B0Q2xpbWJUbzxUPigp Ow0KCQkJaGFyZE11c3QyKCEocmVzIGlzIG51bGwpLCANCgkJCQkvLyBUaGFua3MgU08gPGh0dHBz Oi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzI1ODE2NDIvaG93LWRvLWktZ2V0LXRoZS10 eXBlLW5hbWUtb2YtYS1nZW5lcmljLXR5cGUtYXJndW1lbnQ+DQoJCQkJLy8gVG9kbyAtIHVzZSB0 aGlzIGVsc2V3aGVyZSwgcG9zcyBFeHBlY3RFeGNlcHRpb24/IHRvZG8NCgkJCQkoKSA9Pg0KCQkJ CWxvYyANCgkJCQkrIG5sICsgIiwgY2xpbWJlZCB0byB0b3AsIGRpZG4ndCBmaW5kIHR5cGUgIg0K CQkJCSsgdHlwZW9mKFQpLkZ1bGxOYW1lDQoJCQkJKyBubCArICJIaWVyYXJjaHkgaXM6ICINCgkJ CQkrIG5sICsgZ2V0SXRlbVdpdGhQYXJlbnRzKHRoaXMpKTsNCgkJCWlmIChyZXMgaXMgbnVsbCkg eyB0aHJvdyBuZXcgTk5RQygpOyB9DQoJCQlyZXR1cm4gcmVzOw0KCQl9DQoNCg0KCQlwdWJsaWMg dm9pZCBoYXJkTXVzdFBhcmVudElzUHJlc2VudCgpIHsNCg0KCQkJaGFyZE11c3QyKCEocGFyZW50 IGlzIG51bGwpLCANCgkJCQkoKSA9Pg0KCQkJCSAiTlVMTCBwYXJlbnQgZm9yIGl0ZW0gb2YgdHlw ZVxuIg0KCQkJCSArICQie0dldFR5cGUoKX1cbi4iKTsNCg0KCQkJaGFyZE11c3QyKCEodGhpcy5w YXJlbnQgaXMgTm9QYXJlbnQpLA0KCQkJCSgpID0+DQoJCQkJIlBhcmVudCBpcyBOb1BhcmVudCBv biBvYmplY3Qgb2YgdHlwZVxuIg0KCQkJCSsgJCIne3RoaXMuY2xhc3NOYW1lfSciKTsNCgkJfQ0K DQoNCgkJcHVibGljIHZvaWQgaGFyZE11c3RQYXJlbnRJc0Fic2VudCgpIHsNCgkJCS8vIEZvciBj aGVja2luZyBjbG9uaW5nIC0gcGFyZW50IHNob3VsZCBiZSBOb1BhcmVudCBpbW1lZGlhdGVseSAN CgkJCS8vIGFmdGVyLCBiZWZvcmUgaXQncyBzZXQgYnkgcGFyZW50LCBhbmQgbmV2ZXIgbnVsbA0K CQkJaGFyZE11c3QoIShwYXJlbnQgaXMgbnVsbCksDQoJCQkJICJOVUxMIHBhcmVudCBmb3IgaXRl bSBvZiB0eXBlXG4iDQoJCQkJICsgJCJ7R2V0VHlwZSgpfVxuLiIpOw0KCQkJaGFyZE11c3QoKHRo aXMucGFyZW50IGlzIE5vUGFyZW50KSwNCgkJCQkiUGFyZW50IHNob3VsZCBiZSBOb1BhcmVudCBv biBvYmplY3Qgb2YgdHlwZVxuIg0KCQkJCSsgJCIne3RoaXMuY2xhc3NOYW1lfSciKTsNCgkJfQ0K DQoNCgkJcHVibGljIGJvb2wgaGFzUGFyZW50PFA+KCkgew0KCQkJaGFyZE11c3QoISh0aGlzIGlz IE5vUGFyZW50KSwgIkl0ZW0gaXMgTm9QYXJlbnQiKTsNCgkJCXJldHVybiB0aGlzLnBhcmVudCBp cyBQOw0KCQl9DQoNCg0KCQlwdWJsaWMgYm9vbCBoYXNBbmNlc3RvcjxBPigpIHsNCgkJCWhhcmRN dXN0KCF0aGlzLmlzU3R1YlBhcmVudCwgIkl0ZW0gaXMgTm9QYXJlbnQiKTsNCg0KCQkJLy8gaG93 IHRvIGRvIHdpdGggYSBzd2l0Y2ggZXhwcj8NCgkJCWlmICh0aGlzLnBhcmVudC5pc1N0dWJQYXJl bnQgLyogaXMgTm9QYXJlbnQgfHwgdGhpcy5wYXJlbnQgaXMgRmFrZVBhcmVudCovICkgeyAvLyB0 b2RvIGRvIGFzIHguaGFzRnVkZ2VkUGFyZW50KCkgLSB0b2RvDQoJCQkJcmV0dXJuIGZhbHNlOw0K CQkJfSBlbHNlIGlmICh0aGlzLnBhcmVudCBpcyBBKSB7DQoJCQkJcmV0dXJuIHRydWU7DQoJCQl9 IGVsc2Ugew0KCQkJCXJldHVybiB0aGlzLnBhcmVudC5oYXNBbmNlc3RvcjxBPigpOw0KCQkJfQ0K CQl9DQoNCgkJcHVibGljIGJvb2wgbm90SGFzQW5jZXN0b3I8QT4oKSA9Pg0KCQkJIWhhc0FuY2Vz dG9yPEE+KCk7DQoNCg0KCQlwdWJsaWMgdm9pZCBzZXRNeVBhcmVudFRvKExEQkFTVG9iaiBwcm50 KSB7DQoJCQkvLyBBbiBvYmplY3QgbWF5IG9ubHkgc2V0IGl0cyBwYXJlbnQgaWYgaXRzIGN1cnJl bnQgcGFyZW50IGlzDQoJCQkvLyB0aGUgZHVtbXkgJ25vUGFyZW50Jywgd2hpY2ggYWxtb3N0IGV2 ZXJ5IG9iamVjdCdzIHBhcmVudCBpcw0KCQkJLy8gc2V0IHRvIG9uIGNyZWF0aW9uIChzZWUgTERC QVNUb2JqIHBhcmVudCBwcm9wZXJ0eSBkZWYpLg0KDQoJCQkvLyBUaGUgdGVzdCBmb3IgbnVsbCBp cyBwZWN1bGlhciBnaXZlbiB0aGlzLiBCZWNhdXNlDQoJCQkvLyBub1BhcmVudCBpcyBjcmVhdGVk IHN0YXRpY2FsbHksIHNldHRpbmcgdGhlIHBhcmVudCBvZg0KCQkJLy8gbm9QYXJlbnQgaXMgZGlm ZmljdWx0LCBwZXJoYXBzIGltcG9zc2libGUsIHRvIGRvIHN0YXRpY2FsbHkNCgkJCS8vIGFuZCBy ZWxpYWJseS5EZXNwaXRlIHRoZSBkZWNsYXJhdGlvbiAnI251bGxhYmxlIGVuYWJsZScsIGl0DQoJ CQkvLyBnZXRzIGNyZWF0ZWQgd2l0aCBhIG51bGwgcGFycmVudCAocXVpdGUgcmVhc29uYWJseSks IGhlbmNlDQoJCQkvLyB0aGlzIGNoZWNrLlRoZSBhY3R1YWwgc2V0dGluZyBvZiB0aGUgcGFyZW50 IGhhcyB0byBiZSBkb25lDQoJCQkvLyBhdCBydW50aW1lIGkuZS5hZnRlciB0aGUgc3RhdGljIGNy ZWF0aW9uIG9mICdub1BhcmVudCcuDQoNCgkJCWhhcmRNdXN0MigodGhpcy5wYXJlbnQgaXMgTm9Q YXJlbnQpIHx8ICh0aGlzLnBhcmVudCBpcyBudWxsKSwNCgkJCQkoKSA9Pg0KCQkJCSJ0cmllZCB0 byByZS1zZXQgcGFyZW50IG9uIG9iamVjdCBvZiB0eXBlOiAiDQoJCQkJKyBubCArIHRoaXMuY2xh c3NOYW1lUQ0KCQkJCSsgbmwgKyAiT3JpZ2luYWwgcGFyZW50IHR5cGUgaXM6ICINCgkJCQkrICh0 aGlzPy5wYXJlbnQ/LmNsYXNzTmFtZVEgPT0gbnVsbCA/ICJudWxsIiA6IHRoaXMucGFyZW50LmNs YXNzTmFtZVEpDQoJCQkJKyBubCArICJhbmQgbmV3IHBhcmVudCB0eXBlIGlzOiAiDQoJCQkJKyBw cm50LmNsYXNzTmFtZVENCgkJCQkrIG5sICsgIkl0ZW0gaGF2aW5nIHBhcmVudCBzZXQgb24gaXQg aXM6ICINCgkJCQkvLyBiZWNhdXNlIG9iamVjdCBtYXkgbm90IGJlIGZ1bGx5IGNvbnN0cnVjdGVk IHlldCwgY2hlY2sgaG93dmVyIFRPRE8gdGhpcyBpcyBhIG1ham9yIGhhY2sgYW5kIG11c3QgYmUg Zml4ZWQgc29tZXRpbWUuDQovLwkJCQkrIG5sICsgKHRoaXMgaXMgbnVsbCA/ICIobnVsbCkiIDog dGhpcy50b1Jhd1N0cigpKSk7DQoJCQkJKyBubCArIHRoaXMudG9SYXdTdHIoKSApOw0KDQoJCQlw YXJlbnQgPSBwcm50Ow0KCQl9DQoNCg0KCQlwdWJsaWMgdm9pZCBmb3JjZU5ld1BhcmVudEZvclJv b3RPYmplY3QoKSB7DQoJCQkvLyBFdmVyeSBvYmplY3QgbXVzdCBoYXZlIHNvbWUgcGFyZW50LCBp bmNsdWRpbmcgdGhlDQoJCQkvLyByb290IG9iamVjdCBvZiB0aGUgcGFyc2UsIHdoaWNoIGlzIExE Qml0ZW1zDQoJCQkvLyAoYSBzZXF1ZW5jZSBvZiBMREIgaXRlbXMpLCBzbyB0aGlzIGZvcmNlcyBv bmUuDQoJCQkvLyBJdCBpcyBvbmx5IGZvciB0aGF0IHB1cnBvc2UhDQoJCQkvLyANCgkJCS8vIExE Qml0ZW1zIG9iaiBleGlzdHMgZm9yIHN1YiBvYmpzIHN1Y2ggYXMgdGhlIHN0YXRlbWVudHMNCgkJ CS8vIGluIGEgd2hpbGUgbG9vcCwgaW4gYSBwcm9jLCBpbiBhbiBpZi4uLiBldGMuLCBmb3INCgkJ CS8vIHdoaWNoIHRoZWlyIHBhcmVudCBpcyB0aGUgd2hpbGUvcHJvYy9pZiBldGMuDQoJCQloYXJk TXVzdFBhcmVudElzQWJzZW50KCk7DQoJCQl0aGlzLnBhcmVudCA9IGZha2VQYXJlbnQ7DQoJCX0N Cg0KDQoJCS8vcHVibGljIHZvaWQgcmVzZXRNeVBhcmVudFRvKExEQkFTVG9iaiBwcm50KSB7ICAv Ly8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vIGRlc3Ryb3khISEhISEgdG9kbw0KCQkv LwlwYXJlbnQgPSBwcm50Ow0KCQkvL30NCg0KCQkvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8geHh4 eHh4eHh4eHh4eCBkZWxldGUgLSB0b2RvDQoJCS8vcHJpdmF0ZSB2b2lkIHNldFBhcmVudE9uS2lk KExEQkFTVG9iaiBraWQpID0+IC8vIHRvZG8gbmVlZGVkPw0KCQkvLwkJCQkJCQkJCQkJICAvLyBj aGVjayBwYXJlbnRlIGRvZXNuJ3QgZXhpc3QgLSB0b2RvDQoJCS8vCWtpZC5wYXJlbnQgPSB0aGlz Ow0KDQoJCXB1YmxpYyB2aXJ0dWFsIHZvaWQgc2V0UGFyZW50T25LaWRzQW5kTWFrZUtpZHNEaWN0 KCAgLy8gdG9kbyAtIGFuZCBhZGQgdG8ga2lkcyBkaWN0DQoJCQkJCQkJCQkJCQkJCQkgLy8gdGhp cyBtaXhlcyB1cCBzZXR0aW5nIHBhcmVudCBhbmQgbWFraW5nIGNoaWxkIGRpY3QuIE5vdCBnb29k LiAtIHRvZG8NCgkJCQkJCXBhcmFtcyAoc3RyaW5nIGtpZE5hbWUsIExEQkFTVG9iaiBraWQpW10g a2lkc0luKSB7DQoJCQl2YXIgbG9jID0gY2xhc3NOYW1lUGx1cygic2V0UGFyZW50T25LaWRzQW5k TWFrZUtpZHNEaWN0Iik7DQoNCgkJCXZhciBraWRzVG9BZGQgPSBuZXcgTERCU3RydWN0c0NoaWxk cmVuKHRoaXMsIGtpZHNJbik7DQoJCQloYXJkTXVzdDIoa2lkcy5pc0VtcHR5LA0KCQkJCSgpID0+ DQoJCQkJJCJzZXR0aW5nIGtpZHMgb24gcGFyZW50ICd7Y2xhc3NOYW1lfSciIA0KCQkJCSsgIndo ZW4ga2lkcyBpcyBub3QgZW1wdHksICINCgkJCQkrICQia2lkcyBpcyAoe2tpZHMuQ291bnR9IGtp ZHMpOiINCgkJCQkrIG5sICsga2lkcy50b0RlYnVnU3RyKCkNCgkJCQkrIG5sICsgJCJUcnlpbmcg dG8gYWRkXG57a2lkc1RvQWRkLnRvRGVidWdTdHIoKX1cbiINCgkJCQkrICQiaW4ge2NsYXNzTmFt ZX0iKTsNCgkJCS8vIGlmIHRoZXJlIGlzIGFuIExEQlN0cnVjdHNDaGlsZHJlbiBhbmQgYW5vdGhl ciBjaGlsZCwNCgkJCS8vIHRoaXMgd2lsbCBibG93IHVwIC0gd2lsbCBuZWVkIHRvIGRvIGtpZHMu QWRkIG9yDQoJCQkvLyBzb21ldGhpbmcgLSBpbiBmYWN0LCBraWRzIG5lZWRzIHRvIGJlIGNyZWF0 ZWQgaW4gb25lDQoJCQkvLyBnbywgd2hpY2ggaXMgd2hhdCBoYXBwZW5zLg0KCQkJa2lkcyA9IGtp ZHNUb0FkZDsgICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8v Ly8vLy8vLy8vLy8vIHdoeSB0aGlzPyB0b2RvDQoJCQlBcnJheS5Gb3JFYWNoKGtpZHNJbiwgeGtp ZCA9PiBoYXJkTXVzdCghKHhraWQua2lkIGlzIG51bGwpLCBsb2MsICJudWxsIGtpZCIpKTsNCgkJ CUFycmF5LkZvckVhY2goa2lkc0luLCB4a2lkID0+IHhraWQua2lkLnNldE15UGFyZW50VG8odGhp cykpOw0KCQl9DQoNCg0KCQlwdWJsaWMgdmlydHVhbCB2b2lkIHNldFBhcmVudE9uS2lkc0FuZEFk ZFRvS2lkc0RpY3QoDQoJCQkJCXBhcmFtcyAoc3RyaW5nIGtpZE5hbWUsIExEQkFTVG9iaiBraWQp W10ga2lkc0luKSB7DQoJCQl2YXIga2lkc1RvQWRkX2p1c3RGb3JFcnJSZXBvcnRpbmcgPSBuZXcg TERCU3RydWN0c0NoaWxkcmVuKHRoaXMsIGtpZHNJbik7DQoJCQloYXJkTXVzdDIoIWtpZHMuaXNF bXB0eSwgLy8gbWF5IGRpc2FibGUgdGhpcyBsYXRlciANCgkJCQkoKSA9Pg0KCQkJCSJhZGRpbmcg dG8ga2lkcyB3aGVuIGtpZHMgaXMgZW1wdHksICINCgkJCQkgKyAkImtpZHMgaXNcbntraWRzLnRv RGVidWdTdHIoKX1cbiINCgkJCQkgKyAkIlRyeWluZyB0byBhZGRcbntraWRzVG9BZGRfanVzdEZv ckVyclJlcG9ydGluZy50b0RlYnVnU3RyKCl9XG4iDQoJCQkJICsgJCJpbiB7Y2xhc3NOYW1lfSIp Ow0KCQkJQXJyYXkuRm9yRWFjaChraWRzSW4sIHhraWQgPT4gew0KLy8JCQkJc2V0UGFyZW50T25L aWQoeGtpZC5raWQpOw0KCQkJCXhraWQua2lkLnNldE15UGFyZW50VG8odGhpcyk7DQoJCQkJa2lk cy5BZGQoeGtpZCk7DQoJCQl9KTsNCgkJfQ0KDQoNCgkJcHVibGljIHZpcnR1YWwgSWRlbnRzVXNl ZCBnZXRBbGxJRHMoKSB7DQoJCS8qIFRoaXMgaXMgb3ZlcnJpZGRlbiBvbmx5IGluIFRlbXBsYXRl ZEFnZywgYW5kIHRoYXQncyBvbmx5IHRvIA0KCQkJZGVsaWJlcmF0ZWx5IGZhaWwuIFRoZXJlJ3Mg c29tZXRoaW5nIHdyb25nIHRoZXJlLCB0b2RvIC0gDQoJCQl1bi12aXJ0dWFsaXNlIHRoaXMgYW5k IHJlbW92ZSB0aGUgb25lIG92ZXJyaWRlLiAtIHRvZG8NCgkJKi8NCgkJCXZhciBpdSA9IG5ldyBJ ZGVudHNVc2VkKCk7DQoJCQl0aGlzLl9nZXRBbGxJRHMoaXUpOw0KCQkJcmV0dXJuIGl1Ow0KCQl9 DQoNCgkJcHVibGljIHZpcnR1YWwgdm9pZCBfZ2V0QWxsSURzKElkZW50c1VzZWQgaXUpIHsNCgkJ Ly8gR2V0cyBhbGwgdGhlIGlkZW50aWZpZXJzIGV4cGxpY2l0bHkgdXNlZCAocmVhZCBvciB3cml0 dGVuKSAgLS0tLS0gdG9kbyB1cGRhdGUgdGhpcw0KCQkvLyBhbnl3aGVyZSBpbiB0aGUgQVNULiAg RG9lcyBub3QgZ2V0IGlkZW50cyB3aGljaCBhcmUNCgkJLy8gZGVjbGFyYXRpb25zIGllLiBwYXJh bWV0ZXJzLCBvciB2YXIvY29uc3QgZGVjbGFyYXRpb25zDQoJCS8vIHVubGVzcyB0aGVzZSBhcmUg Y29tYmluZWQgd2l0aCBhbiBhc3NpZ25tZW50Lg0KCQkvLw0KCQkvLyBJbXBsaWVkIGlkZW50cyBz dWNoIGFzIHRob3NlIGZyb20gdGJsLiogYXJlIGltcGxpY2l0IGFuZCBpZ25vcmVkLg0KCQkvLw0K CQkvLyBSb290IGNhbGxlciBzdXBwbGllcyBuZXcsIGVtcHR5IGl1DQoJCS8vIG5lZWQgdXNhZ2Ug aGVyZSAtIHRvZG8gZG9jcy8vDQoJCQlraWRzLl9nZXRBbGxJRHMoaXUpOw0KCQl9DQoNCgkJcHVi bGljIGFic3RyYWN0IGJvb2wgY2FuR2V0QWxsSWRlbnRzVXNlZCB7DQoJCS8vIAlUaGlzIHNlZW1z IHRvIGJlIHRydWUgb24gbW9zdCBjbGFzc2VzIHNvIEkgY291bGQgc2V0IHRydWUgDQoJCS8vIGFz IGEgZGVmYXVsdCBoZXJlIGFuZCBvdmVycmlkZSBpdCB3aGVyZSBpdCdzIG5vdCB3YW50ZWQsIHNh dmluZyANCgkJLy8gYSBjaHVuayBvZiBjb2RlLCBidXQgSSdkIHJhdGhlciBtYWtlIGl0IGV4cGxp Y2l0IHRvIGZvcmNlIG1lIHRvIGNvbnNpZGVyIGVhY2ggY2FzZS4gQSBiaXQgbW9yZSBDJlAgZm9y IGxlc3MgY2hhbmNlIG9mIGJ1Z3MuDQoJCQlnZXQ7DQoJCX0NCg0KDQoJCS8vIFByb2R1Y2VzIGEg c3RyaW5nIHRoYXQgc2hvdWxkIGJlIGlkZW50aWNhbCB0byAoZXhjZXB0aW5nDQoJCS8vIHdoaXRl c3BhY2VzKSB0aGUgaW5wdXQgaWUuIGVtaXQgTERCIGNvZGUgbm90IHZhbGlkIFNRTA0KCQkvLw0K CQkvLyBUb1N0cmluZyB3YXMgY2F1c2luZyB0b28gbWFueSB3ZWlyZCBwcm9ibGVtcyAoZHVlIHRv IG15DQoJCS8vIGluZXhwZXJpZW5jZSB3aXRoIGMjKSBzbyBqdXN0IHVzZWQgdG9SYXdTdHIoKQ0K CQlwdWJsaWMgYWJzdHJhY3Qgc3RyaW5nIHRvUmF3U3RyKCk7DQoNCgkJcHVibGljIG92ZXJyaWRl IHN0cmluZyB0b0RlYnVnU3RyKCkgPT4gdG9SYXdTdHIoKTsNCg0KCX0gLy8gZW5kIExEQkFTVG9i ag0KDQoNCg0KCXB1YmxpYyBpbnRlcmZhY2UgSWhhbmRsZVByZWZpeGVzPFQ+DQoJCQkJCQl3aGVy ZSBUIDogTERCUm9vdCB7DQoNCgkJcHVibGljIGJvb2wgaXNQcmVmaXhlZCB7IGdldDsgfQ0KDQoJ CXB1YmxpYyBib29sIGlzRXhjZXNzUHJlZml4ZWQgeyBnZXQ7IH0NCg0KCQkvLyBUaGUgVCBpbiBh ZGRQcmVmaXgvcmVQcmVmaXgvd2l0aG91dFByZWZpeCBpcyBiZWNhdXNlIHdlIG1heSBiZSANCgkJ Ly8gcmV0dXJuaW5nIGVnLiBhIGxpc3Qgb2YgaXRlbXMgd2l0aCBwcmVmaXhlcyANCgkJLy8gdGh1 cyBtb2RpZmllZCwgbm90IGEgc2luZ2xlIFBNUUlkZW50DQoNCgkJcHVibGljIFQgYWRkUHJlZml4 KFBNUUlkZW50IHBmeCk7DQoNCgkJcHVibGljIFQgcmVQcmVmaXgoUE1RSWRlbnQgbmV3cGZ4KTsN Cg0KLy8JCXB1YmxpYyBUIHN0cmlwUHJlZml4KFBNUUlkZW50IGlkKTsNCgl9DQoJLy8gdG9kbyAt IG1vdmUgdGhpcw0KDQoNCg0KDQoNCglwdWJsaWMgYWJzdHJhY3QgY2xhc3MgTERCUm9vdCB7DQoJ CS8vIFJvb3Qgb2YgZXZlcnl0aGluZyBMREItaXNoDQoNCgkJcHVibGljIGJvb2wgRXF1YWxzKFtB bGxvd051bGxdIExEQlJvb3Qgb3RoZXIpIHsNCgkJCXRocm93IG5ldyBMREJTaG91bGROb3RCZUlt cGxlbWVudGVkRXhjZXB0aW9uKA0KCQkJCQkJCQkJImNhbGxlZCBFcXVhbHMgb24gTERCUm9vdCIp Ow0KCQl9DQoNCgkJcHVibGljIG92ZXJyaWRlDQoJCQlib29sIEVxdWFscyhbQWxsb3dOdWxsXSBP YmplY3Qgb3RoZXIpIHsNCgkJCXRocm93IG5ldyBMREJTaG91bGROb3RCZUltcGxlbWVudGVkRXhj ZXB0aW9uKA0KCQkJCQkJCQkJImNhbGxlZCBFcXVhbHMgaW4gT2JqZWN0Iik7DQoJCX0NCg0KCQlw dWJsaWMgb3ZlcnJpZGUgaW50IEdldEhhc2hDb2RlKCkgew0KCQkJdGhyb3cgbmV3IExEQlNob3Vs ZE5vdEJlSW1wbGVtZW50ZWRFeGNlcHRpb24oDQoJCQkJCQkJCQkiY2FsbGVkIEdldEhhc2hDb2Rl IGluIExEQlJvb3QiKTsNCgkJfQ0KDQoJCXB1YmxpYyBzdGF0aWMgYm9vbCBvcGVyYXRvciA9PShM REJSb290IGxocywNCgkJCQkJCQkJCSAgIExEQlJvb3QgcmhzKSB7DQoJCQl0aHJvdyBuZXcgTERC U2hvdWxkTm90QmVJbXBsZW1lbnRlZEV4Y2VwdGlvbigNCgkJCQkJCQkJCSJjYWxsZWQgPT0gaW4g TERCUm9vdCIpOw0KCQl9DQoNCgkJcHVibGljIHN0YXRpYyBib29sIG9wZXJhdG9yICE9KExEQlJv b3QgbGhzLA0KCQkJCQkJCQkJICAgTERCUm9vdCByaHMpIHsNCgkJCXRocm93IG5ldyBMREJTaG91 bGROb3RCZUltcGxlbWVudGVkRXhjZXB0aW9uKA0KCQkJCQkJCQkJImNhbGxlZCAhPSBpbiBMREJS b290Iik7DQoJCX0NCg0KDQoJCXB1YmxpYyB2aXJ0dWFsIHN0cmluZyBjbGFzc05hbWUgew0KCQkJ Ly8gdG9kbyAtIHRoaXMgbmVlZHMgY2hlY2tpbmcgaXQgd29ya3MgYXMgSSB3YW50DQoJCQkvLyBh bHNvIHJlbmFtZSB0byBsZGJjbGFzc25hbWUgLS0gdG9kbw0KCQkJZ2V0ID0+IHRoaXMuR2V0VHlw ZSgpLkZ1bGxOYW1lID8/ICIodW5rbm93bikiOw0KCQl9DQoNCg0KCQlwdWJsaWMgdmlydHVhbCBz dHJpbmcgY2xhc3NOYW1lUSA9Pg0KCQkJIiciICsgY2xhc3NOYW1lICsgIiciOw0KDQoNCgkJcHVi bGljIHZpcnR1YWwgc3RyaW5nIGNsYXNzTmFtZVBsdXMoc3RyaW5nIHBsdXMpID0+DQoJCQljbGFz c05hbWUgKyAiLiIgKyBwbHVzOw0KDQoJCXB1YmxpYyBvdmVycmlkZSBzdHJpbmcgVG9TdHJpbmco KSB7DQoJCQkvLyBUaGlzIGltcGxpY2l0IHRvLXN0cmluZyBjb252ZXJzaW9uIGNyYXAgY29zdCBt ZSBhIGZldyBob3Vycywgc28gYXQgbGVhc3QNCgkJCS8vIGRvIHRoaXMgJiBibG93IHVwIGF0IHJ1 bnRpbWUuIFdvdWxkIHByZWZlciBjb21waWxlIHRpbWUgYnV0IGl0IHNlZW1zDQoJCQkvLyBub3Qg cG9zc2libGUuICBUaGlzIHR1cm5zIG91dCB0byBoYXZlIGJlZW4gYSBnb29kIGlkZWEsDQoJCQkv LyBzYXZlZCBtZSBxdWl0ZSBhIGJpdCBtb3JlIGRlYnVnZ2luZyENCgkJCS8vIDxodHRwczovL3N0 YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy8xNTM0NTUxNy9pcy1pdC1wb3NzaWJsZS10by1kaXNh YmxlLWltcGxpY2l0LXRvc3RyaW5nLWNhbGw+DQoJCQkvLyBXaWxsIHRyeSA8aHR0cHM6Ly9zdGFj a292ZXJmbG93LmNvbS9xdWVzdGlvbnMvNTQzNTQzNDIvaG93LXRvLWdldC1hbi1lcnJvci1zaG93 bi13aGVuLXVzaW5nLW5vbi1zdHJpbmdzLWFzLXN0cmluZ3MtaW5zdGVhZC1vZi1hbi1hdXRvbS81 NDM1NTExNSM1NDM1NTExNSkNCgkJCXZhciBtc2cgPSAiTERCUm9vdC5Ub1N0cmluZygpIjsNCgkJ CXRocm93IG5ldyBMREJUb1N0cmluZ0ltcGxpY3RDb252ZXJzaW9uRXhjZXB0aW9uKG1zZyk7DQoJ CX0NCg0KCQlwdWJsaWMgYWJzdHJhY3Qgc3RyaW5nIHRvRGVidWdTdHIoKTsNCgl9DQoNCg0KDQoJ cHVibGljIGFic3RyYWN0IGNsYXNzIEVwaGVtZXJhbCA6IExEQlJvb3Qgew0KCQkvLyBmb3Igb2Jq ZWN0cyB0aGF0IGFyZSBub3QgcGFydCBvZiB0aGUgQVNUDQoJfQ0KDQoNCg0KCXB1YmxpYyBpbnRl cmZhY2UgSVdpdGhMaW5lTlVtIHsgIC8vIHRvZG8gLSB1c2Ugb3IgcmVtb3ZlIC0gdG9kbw0KCQkv LwlwdWJsaWMgDQoJfQ0KDQoNCglwdWJsaWMgaW50ZXJmYWNlIElIYXNUYWJsZUFsaWFzIHsNCgkJ Ly8gSGFzIGEgdGFibGUgYWxpYXMgQVNUIG9iai4gTWF5IGJlIGEgLi4uTWlzc2luZyBzdWJ0eXBl IGluIHdoaWNoDQoJCS8vIGl0IGhhcyBubyBhbGlhcyBnaXZlbiBieSB0aGUgdXNlciwgYnV0IGFs aWFzIEFTVCBpcyB0aGVyZS4gTW9yZQ0KCQkvLyBhY2N1cmF0ZWx5IGEgVGFibGVTb3VyY2UgYWxp YXMgYnV0IG9rDQoJCXB1YmxpYyBhYnN0cmFjdCBUYWJsZUFsaWFzIHRhIHsgZ2V0OyBzZXQ7IH0N Cgl9DQoNCg0KCS8vIEJhc2UgY2xhc3MgZm9yIGFsbCBMREIgQVNUIG9iamVjdHMNCglwdWJsaWMg YWJzdHJhY3QgY2xhc3MgTERCQVNUb2JqIDogTERCUm9vdCB7DQoJCS8vIFRoaXMgb25lIGlzIGEg cHJvYmxlbS4gSWYgSSBkZWNsYXJlIHRoZSAncGFyZW50JyBwcm9wZXJ0eQ0KCQkvLyBhYnN0cmFj dCBJIHRoZW4gaGF2ZSB0byBpbXBsZW1lbnQgaXQgbGl0ZXJhbGx5IGh1bmRyZWRzIG9mDQoJCS8v IHRpbWVzIGluIHRoZSBkZXJpdmVkIGNsYXNzZXMsIGFuZCBJIHJlYWxseSBkb24ndCB0aGluayBp dA0KCQkvLyB3b3VsZCBoZWxwIHNvIGp1c3Qgc2V0IGl0IHRvIGEgZGVmYXVsdCB3aGljaCBnZXRz IG92ZXJ3cml0dGVuIGxhdGVyLg0KCQkvLyANCgkJLy8gVGhlIHByb2JsZW0gaXMgdGhhdCB0aG9z ZSBvYmplY3RzIHdlcmUgY3JlYXRlZCBieSB0aGUNCgkJLy8gcGFyc2VyLCB3aGljaCBjcmVhdGVz IHRoZW0gYm90dG9tLXVwLCB3aGljaCBtZWFucyB5b3UgY2FuJ3QNCgkJLy8ga25vdyB0aGUgcGFy ZW50IHdoZW4gdGhleSBhcmUgY3JlYXRlZC4gSXQgc2hvdWxkIGJlDQoJCS8vIHBvc3NpYmxlIHRv IHdvcmsgYXJvdW5kIHRoaXMgYnV0IGl0IGRvZXMgbWVhbiByZXdvcmtpbmcgdGhlDQoJCS8vIHBh cnNlciBmdW5kYW1lbnRhbGx5LCBhbmQgSSdtIG5vdCBnb2luZyB0byBkbyB0aGF0DQoJCS8vIGFz c3VtZWluZyBpdCdzIGV2ZW4gcG9zc2libGUuDQoNCgkJLy8gdG9kbyAtIHJlYWQgdXAgb24gcHJp di9wdWIvcHJvZyBhY2Nlc3NvcnMgSSByZWFsbHkgZG9uJ3QNCgkJLy8gZ2V0IHRoZXNlIGF0IGFs bA0KCQlwdWJsaWMgTERCQVNUb2JqIHBhcmVudCB7IGdldDsgcHJpdmF0ZSBzZXQ7IH0NCgkJCQkJ CT0gbm9QYXJlbnQ7DQoJCS8vIFVuaXF1ZSBJRCBwZXIgb2JqZWN0LCB1c2VmdWwgZm9yIGRpc3Rp bmd1aXNoaW5nIHRoZW0NCgkJLy8gd2l0aG91dCBnZW5lcmFsIGVxdWFsaXR5Lg0KCQlyZWFkb25s eSBwdWJsaWMgdWxvbmcgdWlkID0gbmV3VUlEKCk7DQoNCgkJLy8gcHVibGljIGFic3RyYWN0IGlu dCBsaW5lTnVtIHsgZ2V0OyBzZXQ7IH0NCg0KCQkvLyBJcyB2YWxpZGF0ZWQgaXMgYSBjaGVhcGlz aCBjaGVjayB0byBlbnN1cmUgZXZlcnl0aGluZyBnZXRzDQoJCS8vIHZhbGlkYXRlZA0KCQkvLyBj YW4gZG8gdGhpcyBhcyBhdXRvIHByb3A/IHRvZG8NCgkJcHJpdmF0ZSBib29sIF92YWxpZGF0ZWQg PSBmYWxzZTsNCg0KCQlwcm90ZWN0ZWQgYm9vbCB2YWxpZGF0ZWQgew0KCQkJZ2V0ID0+IF92YWxp ZGF0ZWQ7DQoJCQlzZXQgew0KCQkJCS8vIGhhcmRNdXN0KCF2YWxpZGF0ZWQsICIuLi4gYWxyZWFk eSB2YWxpZGF0ZWQuLi4gIik7IC0gbm8NCgkJCQkvLyBJdCdzIGhhcmQgdG8gYXZvaWQgdmFsaWRh dGluZyBhIHRoaW5nIHR3aWNlLCBzbyBmb3Igbm93IGFsbG93IGl0DQoJCQkJLy8gTG9vayBpbnRv IGl0IGxhdGVyLCByZWFsbHkgc2hvdWxkbid0IGhhcHBlbg0KCQkJCV92YWxpZGF0ZWQgPSB0cnVl Ow0KCQkJfQ0KCQl9DQoNCgkJcHVibGljIExEQlN0cnVjdHNDaGlsZHJlbiBraWRzIHsgZ2V0OyBw cml2YXRlIHNldDsgfSA9DQoJCQkJCW5ldyBMREJTdHJ1Y3RzQ2hpbGRyZW4obm9QYXJlbnQpOyAv LyBqdXN0IGVhc2llcg0KDQoJCXB1YmxpYyBMREJBU1RvYmooKSB7ICAvLy8vLy8vLy8vLy8vLy8v Ly8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vIHRvZG8gZGVh ZD8NCgkJCQkJCQkgIC8vIFZTdHVkaW8gdGhpbmtzIHRoaXMgaGFzIHplcm8gcmVmZXJlbmNlcywg d2hpY2ggaXMgdHJ1ZSBleHBsaWNpdGx5LCBidXQgaXQncyANCgkJCQkJCQkgIC8vIGNhbGxlZCBp bXBsaWNpdGx5IG9uIGV2ZXJ5IG9iaiBjcmVhdGlvbiAtIG9yIHNob3VsZCBkbyB0b2RvLSBjaGVj aw0KCQkJaWYgKHJlY29yZE9iamVjdHNDcmVhdGVkKSB7DQoJCQkJQWxsQ3JlYXRlZEl0ZW1zLkFk ZCh0aGlzKTsNCgkJCX0NCgkJfQ0KDQoNCgkJcHVibGljIHZpcnR1YWwgdm9pZCB2YWxpZGF0ZSgp IHsNCgkJCWlmIChyZXBvcnRBbHNvSWZWYWxpZGF0aW9uT0spIHsNCgkJCQlkZWJ1Z21zZygidmFs aWRhdGluZy4uLiIgKyBjbGFzc05hbWUNCgkJCQkJKyAiICgiICsgYXNOYW1lT3JJZGVudENvbnRl bnRzKCkgKyAiKSIpOw0KCQkJfQ0KCQkJbWhwX21oaygpOw0KCQkJa2lkcy52YWxpZGF0ZSgpOw0K CQkJLy8gdmFsaWRhdGVkID0gdHJ1ZTsgLS0gTm8sIGdldCBlYWNoIHN1YmNsYXNzIHRvIHNldA0K CQkJLy8gdmFsaWRhdGVkLiBUaGF0IGZvcmNlcyBhbiBleHBsaWNpdCBjYWxsIHRvIGJhc2UoKSB3 aGljaA0KCQkJLy8gaXMgbW9yZSBjb2RlIGJ1dCBvay4NCgkJfQ0KDQoNCgkJcHVibGljIGJvb2wg aXNWYWxpZGF0ZWQgeyBnZXQgPT4gdmFsaWRhdGVkOyB9ICAvLyB0b2RvIGp1c3QgPT4gdmFsaWRh dGVkOw0KDQoNCgkJcHVibGljIHZpcnR1YWwgYm9vbCBpc1RvcExldmVsSXRlbVNlcSA9PiBmYWxz ZTsNCg0KDQoJCXB1YmxpYyB2aXJ0dWFsIHZvaWQgbWhwX21oaygpIHsgIC8vIGRvbid0IHRoaW5r IHRoaXMgbmVlZCBiZSB2aXJ0dWFsIC0gdG9kbz8NCgkJCQkJCQkJCQkgLy8gPSBtdXN0IGhhdmUg cGFyZW50LCBtdXN0IGhhdmUga2lkcy4gVGhlIGtpZHMgbWF5IGJlIHRoZQ0KCQkJCQkJCQkJCSAv LyBlbXB0eSBzZXQgYW5kIHRoZSBwYXJlbnQgbWF5IGJlIG5vUGFyZW50IGJ1dCB0aGV5IG11c3QN CgkJCQkJCQkJCQkgLy8gZXhpc3QuDQoJCQkJCQkJCQkJIC8vIFdoeSBub3QganVzdCBpbmxpbmUg dGhpcyBpbnRvIHZhbGlkYXRlKCk/DQoJCQkJCQkJCQkJIC8vIEJlY2F1c2UgYSBmZXcgY2xhc3Nl cyBuZWVkIGJlc3Bva2UgdmFsaWRhdGlvbiwgYnV0IHN0aWxsIG11c3QgY2hlY2sgdGhpcy4NCgkJ CWhhcmRNdXN0UGFyZW50SXNQcmVzZW50KCk7DQoJCQlraWRzLmVhY2hLaWRQYXJlbnRNdXN0QmUo dGhpcyk7DQoJCX0NCg0KDQoJCXB1YmxpYyBzdHJpbmcgYXNOYW1lT3JJZGVudENvbnRlbnRzKCkg ew0KCQkJLy8gZm9yIHZlcnkgY3J1ZGUgZGVidWdnaW5nIA0KCQkJdmFyIG9wdE5hbWUgPSB0aGlz IGlzIElpc05hbWVkSXRlbSBuaSA/IG5pLm5hbWUudG9SYXdTdHIoKSA6ICIiOw0KCQkJb3B0TmFt ZSA9IChvcHROYW1lID09ICIiICYmIHRoaXMgaXMgUE1RSWRlbnQpID8gdGhpcy50b1Jhd1N0cigp IDogIiI7DQoNCgkJCXZhciBvcHROYW1lMiA9IG9wdE5hbWUgKyAiICAodWlkOiIgKyB1aWQuVG9T dHJpbmcoKSArICIpICINCgkJCQkrIGdldEZpcnN0RmV3Q2hhcnNPZih0b1Jhd1N0cigpKTsNCgkJ CXJldHVybiBvcHROYW1lMjsNCgkJfQ0KDQoNCgkJcHVibGljIHZpcnR1YWwgdm9pZCBnZXRBbGxV SURzKFVJRHNldCB1aWRzKSB7DQoJCQl1aWRzLkFkZCh0aGlzKTsNCgkJCWtpZHMuRm9yRWFjaChu YW1lZEtpZCA9PiBuYW1lZEtpZC5raWQuZ2V0QWxsVUlEcyh1aWRzKSk7DQoJCX0NCg0KDQoJCXB1 YmxpYyBib29sIGlzU3R1YlBhcmVudCB7IGdldCA9PiAodGhpcyBpcyBOb1BhcmVudCkgfHwgKHRo aXMgaXMgRmFrZVBhcmVudCk7IH0NCg0KDQoJCXB1YmxpYyB2b2lkIHZhbGlkYXRlU3BlY2lmaWNJ dGVtcyhwYXJhbXMgTERCQVNUb2JqW10gaXRlbXMpIHsNCgkJCUFycmF5LkZvckVhY2goaXRlbXMs IGl0ZW0gPT4gaXRlbS52YWxpZGF0ZSgpKTsNCgkJfQ0KDQoNCgkJcHVibGljIFQ/IG9wdENsaW1i VG88VD4oKSB3aGVyZSBUIDogTERCQVNUb2JqIHsNCgkJCXZhciByZXNJdGVtID0gdGhpczsNCgkJ CXdoaWxlICghKHJlc0l0ZW0gaXMgVCkpIHsNCgkJCQlpZiAocmVzSXRlbS5wYXJlbnQuaXNTdHVi UGFyZW50KSB7DQoJCQkJCXJldHVybiBudWxsOw0KCQkJCX0NCgkJCQlyZXNJdGVtID0gcmVzSXRl bS5wYXJlbnQ7DQoJCQl9DQoNCgkJCXZhciByZXMgPSByZXNJdGVtIGFzIFQ7DQoJCQlyZXR1cm4g cmVzOw0KCQl9DQoNCg0KCQlwdWJsaWMgVCByZXFDbGltYlRvPFQ+KCkgd2hlcmUgVCA6IExEQkFT VG9iaiB7DQoJCQl2YXIgbG9jID0gY2xhc3NOYW1lICsgIi5yZXFDbGltYlRvPFQ+KCkiOw0KCQkJ dmFyIHJlcyA9IG9wdENsaW1iVG88VD4oKTsNCgkJCWhhcmRNdXN0MighKHJlcyBpcyBudWxsKSwg DQoJCQkJLy8gVGhhbmtzIFNPIDxodHRwczovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy8y NTgxNjQyL2hvdy1kby1pLWdldC10aGUtdHlwZS1uYW1lLW9mLWEtZ2VuZXJpYy10eXBlLWFyZ3Vt ZW50Pg0KCQkJCS8vIFRvZG8gLSB1c2UgdGhpcyBlbHNld2hlcmUsIHBvc3MgRXhwZWN0RXhjZXB0 aW9uPyB0b2RvDQoJCQkJKCkgPT4NCgkJCQlsb2MgDQoJCQkJKyBubCArICIsIGNsaW1iZWQgdG8g dG9wLCBkaWRuJ3QgZmluZCB0eXBlICINCgkJCQkrIHR5cGVvZihUKS5GdWxsTmFtZQ0KCQkJCSsg bmwgKyAiSGllcmFyY2h5IGlzOiAiDQoJCQkJKyBubCArIGdldEl0ZW1XaXRoUGFyZW50cyh0aGlz KSk7DQoJCQlpZiAocmVzIGlzIG51bGwpIHsgdGhyb3cgbmV3IE5OUUMoKTsgfQ0KCQkJcmV0dXJu IHJlczsNCgkJfQ0KDQoNCgkJcHVibGljIHZvaWQgaGFyZE11c3RQYXJlbnRJc1ByZXNlbnQoKSB7 DQoNCgkJCWhhcmRNdXN0MighKHBhcmVudCBpcyBudWxsKSwgDQoJCQkJKCkgPT4NCgkJCQkgIk5V TEwgcGFyZW50IGZvciBpdGVtIG9mIHR5cGVcbiINCgkJCQkgKyAkIntHZXRUeXBlKCl9XG4uIik7 DQoNCgkJCWhhcmRNdXN0MighKHRoaXMucGFyZW50IGlzIE5vUGFyZW50KSwNCgkJCQkoKSA9Pg0K CQkJCSJQYXJlbnQgaXMgTm9QYXJlbnQgb24gb2JqZWN0IG9mIHR5cGVcbiINCgkJCQkrICQiJ3t0 aGlzLmNsYXNzTmFtZX0nIik7DQoJCX0NCg0KDQoJCXB1YmxpYyB2b2lkIGhhcmRNdXN0UGFyZW50 SXNBYnNlbnQoKSB7DQoJCQkvLyBGb3IgY2hlY2tpbmcgY2xvbmluZyAtIHBhcmVudCBzaG91bGQg YmUgTm9QYXJlbnQgaW1tZWRpYXRlbHkgDQoJCQkvLyBhZnRlciwgYmVmb3JlIGl0J3Mgc2V0IGJ5 IHBhcmVudCwgYW5kIG5ldmVyIG51bGwNCgkJCWhhcmRNdXN0KCEocGFyZW50IGlzIG51bGwpLA0K CQkJCSAiTlVMTCBwYXJlbnQgZm9yIGl0ZW0gb2YgdHlwZVxuIg0KCQkJCSArICQie0dldFR5cGUo KX1cbi4iKTsNCgkJCWhhcmRNdXN0KCh0aGlzLnBhcmVudCBpcyBOb1BhcmVudCksDQoJCQkJIlBh cmVudCBzaG91bGQgYmUgTm9QYXJlbnQgb24gb2JqZWN0IG9mIHR5cGVcbiINCgkJCQkrICQiJ3t0 aGlzLmNsYXNzTmFtZX0nIik7DQoJCX0NCg0KDQoJCXB1YmxpYyBib29sIGhhc1BhcmVudDxQPigp IHsNCgkJCWhhcmRNdXN0KCEodGhpcyBpcyBOb1BhcmVudCksICJJdGVtIGlzIE5vUGFyZW50Iik7 DQoJCQlyZXR1cm4gdGhpcy5wYXJlbnQgaXMgUDsNCgkJfQ0KDQoNCgkJcHVibGljIGJvb2wgaGFz QW5jZXN0b3I8QT4oKSB7DQoJCQloYXJkTXVzdCghdGhpcy5pc1N0dWJQYXJlbnQsICJJdGVtIGlz IE5vUGFyZW50Iik7DQoNCgkJCS8vIGhvdyB0byBkbyB3aXRoIGEgc3dpdGNoIGV4cHI/DQoJCQlp ZiAodGhpcy5wYXJlbnQuaXNTdHViUGFyZW50IC8qIGlzIE5vUGFyZW50IHx8IHRoaXMucGFyZW50 IGlzIEZha2VQYXJlbnQqLyApIHsgLy8gdG9kbyBkbyBhcyB4Lmhhc0Z1ZGdlZFBhcmVudCgpIC0g dG9kbw0KCQkJCXJldHVybiBmYWxzZTsNCgkJCX0gZWxzZSBpZiAodGhpcy5wYXJlbnQgaXMgQSkg ew0KCQkJCXJldHVybiB0cnVlOw0KCQkJfSBlbHNlIHsNCgkJCQlyZXR1cm4gdGhpcy5wYXJlbnQu aGFzQW5jZXN0b3I8QT4oKTsNCgkJCX0NCgkJfQ0KDQoJCXB1YmxpYyBib29sIG5vdEhhc0FuY2Vz dG9yPEE+KCkgPT4NCgkJCSFoYXNBbmNlc3RvcjxBPigpOw0KDQoNCgkJcHVibGljIHZvaWQgc2V0 TXlQYXJlbnRUbyhMREJBU1RvYmogcHJudCkgew0KCQkJLy8gQW4gb2JqZWN0IG1heSBvbmx5IHNl dCBpdHMgcGFyZW50IGlmIGl0cyBjdXJyZW50IHBhcmVudCBpcw0KCQkJLy8gdGhlIGR1bW15ICdu b1BhcmVudCcsIHdoaWNoIGFsbW9zdCBldmVyeSBvYmplY3QncyBwYXJlbnQgaXMNCgkJCS8vIHNl dCB0byBvbiBjcmVhdGlvbiAoc2VlIExEQkFTVG9iaiBwYXJlbnQgcHJvcGVydHkgZGVmKS4NCg0K CQkJLy8gVGhlIHRlc3QgZm9yIG51bGwgaXMgcGVjdWxpYXIgZ2l2ZW4gdGhpcy4gQmVjYXVzZQ0K CQkJLy8gbm9QYXJlbnQgaXMgY3JlYXRlZCBzdGF0aWNhbGx5LCBzZXR0aW5nIHRoZSBwYXJlbnQg b2YNCgkJCS8vIG5vUGFyZW50IGlzIGRpZmZpY3VsdCwgcGVyaGFwcyBpbXBvc3NpYmxlLCB0byBk byBzdGF0aWNhbGx5DQoJCQkvLyBhbmQgcmVsaWFibHkuRGVzcGl0ZSB0aGUgZGVjbGFyYXRpb24g JyNudWxsYWJsZSBlbmFibGUnLCBpdA0KCQkJLy8gZ2V0cyBjcmVhdGVkIHdpdGggYSBudWxsIHBh cnJlbnQgKHF1aXRlIHJlYXNvbmFibHkpLCBoZW5jZQ0KCQkJLy8gdGhpcyBjaGVjay5UaGUgYWN0 dWFsIHNldHRpbmcgb2YgdGhlIHBhcmVudCBoYXMgdG8gYmUgZG9uZQ0KCQkJLy8gYXQgcnVudGlt ZSBpLmUuYWZ0ZXIgdGhlIHN0YXRpYyBjcmVhdGlvbiBvZiAnbm9QYXJlbnQnLg0KDQoJCQloYXJk TXVzdDIoKHRoaXMucGFyZW50IGlzIE5vUGFyZW50KSB8fCAodGhpcy5wYXJlbnQgaXMgbnVsbCks DQoJCQkJKCkgPT4NCgkJCQkidHJpZWQgdG8gcmUtc2V0IHBhcmVudCBvbiBvYmplY3Qgb2YgdHlw ZTogIg0KCQkJCSsgbmwgKyB0aGlzLmNsYXNzTmFtZVENCgkJCQkrIG5sICsgIk9yaWdpbmFsIHBh cmVudCB0eXBlIGlzOiAiDQoJCQkJKyAodGhpcz8ucGFyZW50Py5jbGFzc05hbWVRID09IG51bGwg PyAibnVsbCIgOiB0aGlzLnBhcmVudC5jbGFzc05hbWVRKQ0KCQkJCSsgbmwgKyAiYW5kIG5ldyBw YXJlbnQgdHlwZSBpczogIg0KCQkJCSsgcHJudC5jbGFzc05hbWVRDQoJCQkJKyBubCArICJJdGVt IGhhdmluZyBwYXJlbnQgc2V0IG9uIGl0IGlzOiAiDQoJCQkJLy8gYmVjYXVzZSBvYmplY3QgbWF5 IG5vdCBiZSBmdWxseSBjb25zdHJ1Y3RlZCB5ZXQsIGNoZWNrIGhvd3ZlciBUT0RPIHRoaXMgaXMg YSBtYWpvciBoYWNrIGFuZCBtdXN0IGJlIGZpeGVkIHNvbWV0aW1lLg0KLy8JCQkJKyBubCArICh0 aGlzIGlzIG51bGwgPyAiKG51bGwpIiA6IHRoaXMudG9SYXdTdHIoKSkpOw0KCQkJCSsgbmwgKyB0 aGlzLnRvUmF3U3RyKCkgKTsNCg0KCQkJcGFyZW50ID0gcHJudDsNCgkJfQ0KDQoNCgkJcHVibGlj IHZvaWQgZm9yY2VOZXdQYXJlbnRGb3JSb290T2JqZWN0KCkgew0KCQkJLy8gRXZlcnkgb2JqZWN0 IG11c3QgaGF2ZSBzb21lIHBhcmVudCwgaW5jbHVkaW5nIHRoZQ0KCQkJLy8gcm9vdCBvYmplY3Qg b2YgdGhlIHBhcnNlLCB3aGljaCBpcyBMREJpdGVtcw0KCQkJLy8gKGEgc2VxdWVuY2Ugb2YgTERC IGl0ZW1zKSwgc28gdGhpcyBmb3JjZXMgb25lLg0KCQkJLy8gSXQgaXMgb25seSBmb3IgdGhhdCBw dXJwb3NlIQ0KCQkJLy8gDQoJCQkvLyBMREJpdGVtcyBvYmogZXhpc3RzIGZvciBzdWIgb2JqcyBz dWNoIGFzIHRoZSBzdGF0ZW1lbnRzDQoJCQkvLyBpbiBhIHdoaWxlIGxvb3AsIGluIGEgcHJvYywg aW4gYW4gaWYuLi4gZXRjLiwgZm9yDQoJCQkvLyB3aGljaCB0aGVpciBwYXJlbnQgaXMgdGhlIHdo aWxlL3Byb2MvaWYgZXRjLg0KCQkJaGFyZE11c3RQYXJlbnRJc0Fic2VudCgpOw0KCQkJdGhpcy5w YXJlbnQgPSBmYWtlUGFyZW50Ow0KCQl9DQoNCg0KCQkvL3B1YmxpYyB2b2lkIHJlc2V0TXlQYXJl bnRUbyhMREJBU1RvYmogcHJudCkgeyAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8v LyBkZXN0cm95ISEhISEhIHRvZG8NCgkJLy8JcGFyZW50ID0gcHJudDsNCgkJLy99DQoNCgkJLy8v Ly8vLy8vLy8vLy8vLy8vLy8vLy8vIHh4eHh4eHh4eHh4eHggZGVsZXRlIC0gdG9kbw0KCQkvL3By aXZhdGUgdm9pZCBzZXRQYXJlbnRPbktpZChMREJBU1RvYmoga2lkKSA9PiAvLyB0b2RvIG5lZWRl ZD8NCgkJLy8JCQkJCQkJCQkJCSAgLy8gY2hlY2sgcGFyZW50ZSBkb2Vzbid0IGV4aXN0IC0gdG9k bw0KCQkvLwlraWQucGFyZW50ID0gdGhpczsNCg0KCQlwdWJsaWMgdmlydHVhbCB2b2lkIHNldFBh cmVudE9uS2lkc0FuZE1ha2VLaWRzRGljdCggIC8vIHRvZG8gLSBhbmQgYWRkIHRvIGtpZHMgZGlj dA0KCQkJCQkJCQkJCQkJCQkJIC8vIHRoaXMgbWl4ZXMgdXAgc2V0dGluZyBwYXJlbnQgYW5kIG1h a2luZyBjaGlsZCBkaWN0LiBOb3QgZ29vZC4gLSB0b2RvDQoJCQkJCQlwYXJhbXMgKHN0cmluZyBr aWROYW1lLCBMREJBU1RvYmoga2lkKVtdIGtpZHNJbikgew0KCQkJdmFyIGxvYyA9IGNsYXNzTmFt ZVBsdXMoInNldFBhcmVudE9uS2lkc0FuZE1ha2VLaWRzRGljdCIpOw0KDQoJCQl2YXIga2lkc1Rv QWRkID0gbmV3IExEQlN0cnVjdHNDaGlsZHJlbih0aGlzLCBraWRzSW4pOw0KCQkJaGFyZE11c3Qy KGtpZHMuaXNFbXB0eSwNCgkJCQkoKSA9Pg0KCQkJCSQic2V0dGluZyBraWRzIG9uIHBhcmVudCAn e2NsYXNzTmFtZX0nIiANCgkJCQkrICJ3aGVuIGtpZHMgaXMgbm90IGVtcHR5LCAiDQoJCQkJKyAk ImtpZHMgaXMgKHtraWRzLkNvdW50fSBraWRzKToiDQoJCQkJKyBubCArIGtpZHMudG9EZWJ1Z1N0 cigpDQoJCQkJKyBubCArICQiVHJ5aW5nIHRvIGFkZFxue2tpZHNUb0FkZC50b0RlYnVnU3RyKCl9 XG4iDQoJCQkJKyAkImluIHtjbGFzc05hbWV9Iik7DQoJCQkvLyBpZiB0aGVyZSBpcyBhbiBMREJT dHJ1Y3RzQ2hpbGRyZW4gYW5kIGFub3RoZXIgY2hpbGQsDQoJCQkvLyB0aGlzIHdpbGwgYmxvdyB1 cCAtIHdpbGwgbmVlZCB0byBkbyBraWRzLkFkZCBvcg0KCQkJLy8gc29tZXRoaW5nIC0gaW4gZmFj dCwga2lkcyBuZWVkcyB0byBiZSBjcmVhdGVkIGluIG9uZQ0KCQkJLy8gZ28sIHdoaWNoIGlzIHdo YXQgaGFwcGVucy4NCgkJCWtpZHMgPSBraWRzVG9BZGQ7ICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8v Ly8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLyB3aHkgdGhpcz8gdG9kbw0KCQkJ QXJyYXkuRm9yRWFjaChraWRzSW4sIHhraWQgPT4gaGFyZE11c3QoISh4a2lkLmtpZCBpcyBudWxs KSwgbG9jLCAibnVsbCBraWQiKSk7DQoJCQlBcnJheS5Gb3JFYWNoKGtpZHNJbiwgeGtpZCA9PiB4 a2lkLmtpZC5zZXRNeVBhcmVudFRvKHRoaXMpKTsNCgkJfQ0KDQoNCgkJcHVibGljIHZpcnR1YWwg dm9pZCBzZXRQYXJlbnRPbktpZHNBbmRBZGRUb0tpZHNEaWN0KA0KCQkJCQlwYXJhbXMgKHN0cmlu ZyBraWROYW1lLCBMREJBU1RvYmoga2lkKVtdIGtpZHNJbikgew0KCQkJdmFyIGtpZHNUb0FkZF9q dXN0Rm9yRXJyUmVwb3J0aW5nID0gbmV3IExEQlN0cnVjdHNDaGlsZHJlbih0aGlzLCBraWRzSW4p Ow0KCQkJaGFyZE11c3QyKCFraWRzLmlzRW1wdHksIC8vIG1heSBkaXNhYmxlIHRoaXMgbGF0ZXIg DQoJCQkJKCkgPT4NCgkJCQkiYWRkaW5nIHRvIGtpZHMgd2hlbiBraWRzIGlzIGVtcHR5LCAiDQoJ CQkJICsgJCJraWRzIGlzXG57a2lkcy50b0RlYnVnU3RyKCl9XG4iDQoJCQkJICsgJCJUcnlpbmcg dG8gYWRkXG57a2lkc1RvQWRkX2p1c3RGb3JFcnJSZXBvcnRpbmcudG9EZWJ1Z1N0cigpfVxuIg0K CQkJCSArICQiaW4ge2NsYXNzTmFtZX0iKTsNCgkJCUFycmF5LkZvckVhY2goa2lkc0luLCB4a2lk ID0+IHsNCi8vCQkJCXNldFBhcmVudE9uS2lkKHhraWQua2lkKTsNCgkJCQl4a2lkLmtpZC5zZXRN eVBhcmVudFRvKHRoaXMpOw0KCQkJCWtpZHMuQWRkKHhraWQpOw0KCQkJfSk7DQoJCX0NCg0KDQoJ CXB1YmxpYyB2aXJ0dWFsIElkZW50c1VzZWQgZ2V0QWxsSURzKCkgew0KCQkvKiBUaGlzIGlzIG92 ZXJyaWRkZW4gb25seSBpbiBUZW1wbGF0ZWRBZ2csIGFuZCB0aGF0J3Mgb25seSB0byANCgkJCWRl bGliZXJhdGVseSBmYWlsLiBUaGVyZSdzIHNvbWV0aGluZyB3cm9uZyB0aGVyZSwgdG9kbyAtIA0K CQkJdW4tdmlydHVhbGlzZSB0aGlzIGFuZCByZW1vdmUgdGhlIG9uZSBvdmVycmlkZS4gLSB0b2Rv DQoJCSovDQoJCQl2YXIgaXUgPSBuZXcgSWRlbnRzVXNlZCgpOw0KCQkJdGhpcy5fZ2V0QWxsSURz KGl1KTsNCgkJCXJldHVybiBpdTsNCgkJfQ0KDQoJCXB1YmxpYyB2aXJ0dWFsIHZvaWQgX2dldEFs bElEcyhJZGVudHNVc2VkIGl1KSB7DQoJCS8vIEdldHMgYWxsIHRoZSBpZGVudGlmaWVycyBleHBs aWNpdGx5IHVzZWQgKHJlYWQgb3Igd3JpdHRlbikgIC0tLS0tIHRvZG8gdXBkYXRlIHRoaXMNCgkJ Ly8gYW55d2hlcmUgaW4gdGhlIEFTVC4gIERvZXMgbm90IGdldCBpZGVudHMgd2hpY2ggYXJlDQoJ CS8vIGRlY2xhcmF0aW9ucyBpZS4gcGFyYW1ldGVycywgb3IgdmFyL2NvbnN0IGRlY2xhcmF0aW9u cw0KCQkvLyB1bmxlc3MgdGhlc2UgYXJlIGNvbWJpbmVkIHdpdGggYW4gYXNzaWdubWVudC4NCgkJ Ly8NCgkJLy8gSW1wbGllZCBpZGVudHMgc3VjaCBhcyB0aG9zZSBmcm9tIHRibC4qIGFyZSBpbXBs aWNpdCBhbmQgaWdub3JlZC4NCgkJLy8NCgkJLy8gUm9vdCBjYWxsZXIgc3VwcGxpZXMgbmV3LCBl bXB0eSBpdQ0KCQkvLyBuZWVkIHVzYWdlIGhlcmUgLSB0b2RvIGRvY3MvLw0KCQkJa2lkcy5fZ2V0 QWxsSURzKGl1KTsNCgkJfQ0KDQoJCXB1YmxpYyBhYnN0cmFjdCBib29sIGNhbkdldEFsbElkZW50 c1VzZWQgew0KCQkvLyAJVGhpcyBzZWVtcyB0byBiZSB0cnVlIG9uIG1vc3QgY2xhc3NlcyBzbyBJ IGNvdWxkIHNldCB0cnVlIA0KCQkvLyBhcyBhIGRlZmF1bHQgaGVyZSBhbmQgb3ZlcnJpZGUgaXQg d2hlcmUgaXQncyBub3Qgd2FudGVkLCBzYXZpbmcgDQoJCS8vIGEgY2h1bmsgb2YgY29kZSwgYnV0 IEknZCByYXRoZXIgbWFrZSBpdCBleHBsaWNpdCB0byBmb3JjZSBtZSB0byBjb25zaWRlciBlYWNo IGNhc2UuIEEgYml0IG1vcmUgQyZQIGZvciBsZXNzIGNoYW5jZSBvZiBidWdzLg0KCQkJZ2V0Ow0K CQl9DQoNCg0KCQkvLyBQcm9kdWNlcyBhIHN0cmluZyB0aGF0IHNob3VsZCBiZSBpZGVudGljYWwg dG8gKGV4Y2VwdGluZw0KCQkvLyB3aGl0ZXNwYWNlcykgdGhlIGlucHV0IGllLiBlbWl0IExEQiBj b2RlIG5vdCB2YWxpZCBTUUwNCgkJLy8NCgkJLy8gVG9TdHJpbmcgd2FzIGNhdXNpbmcgdG9vIG1h bnkgd2VpcmQgcHJvYmxlbXMgKGR1ZSB0byBteQ0KCQkvLyBpbmV4cGVyaWVuY2Ugd2l0aCBjIykg c28ganVzdCB1c2VkIHRvUmF3U3RyKCkNCgkJcHVibGljIGFic3RyYWN0IHN0cmluZyB0b1Jhd1N0 cigpOw0KDQoJCXB1YmxpYyBvdmVycmlkZSBzdHJpbmcgdG9EZWJ1Z1N0cigpID0+IHRvUmF3U3Ry KCk7DQoNCgl9IC8vIGVuZCBMREJBU1RvYmoNCg0KDQoNCglwdWJsaWMgaW50ZXJmYWNlIEloYW5k bGVQcmVmaXhlczxUPg0KCQkJCQkJd2hlcmUgVCA6IExEQlJvb3Qgew0KDQoJCXB1YmxpYyBib29s IGlzUHJlZml4ZWQgeyBnZXQ7IH0NCg0KCQlwdWJsaWMgYm9vbCBpc0V4Y2Vzc1ByZWZpeGVkIHsg Z2V0OyB9DQoNCgkJLy8gVGhlIFQgaW4gYWRkUHJlZml4L3JlUHJlZml4L3dpdGhvdXRQcmVmaXgg aXMgYmVjYXVzZSB3ZSBtYXkgYmUgDQoJCS8vIHJldHVybmluZyBlZy4gYSBsaXN0IG9mIGl0ZW1z IHdpdGggcHJlZml4ZXMgDQoJCS8vIHRodXMgbW9kaWZpZWQsIG5vdCBhIHNpbmdsZSBQTVFJZGVu dA0KDQoJCXB1YmxpYyBUIGFkZFByZWZpeChQTVFJZGVudCBwZngpOw0KDQoJCXB1YmxpYyBUIHJl UHJlZml4KFBNUUlkZW50IG5ld3BmeCk7DQoNCi8vCQlwdWJsaWMgVCBzdHJpcFByZWZpeChQTVFJ ZGVudCBpZCk7DQoJfQ0KCS8vIHRvZG8gLSBtb3ZlIHRoaXMNCg0KDQoNCg0KDQoJcHVibGljIGFi c3RyYWN0IGNsYXNzIExEQlJvb3Qgew0KCQkvLyBSb290IG9mIGV2ZXJ5dGhpbmcgTERCLWlzaA0K DQoJCXB1YmxpYyBib29sIEVxdWFscyhbQWxsb3dOdWxsXSBMREJSb290IG90aGVyKSB7DQoJCQl0 aHJvdyBuZXcgTERCU2hvdWxkTm90QmVJbXBsZW1lbnRlZEV4Y2VwdGlvbigNCgkJCQkJCQkJCSJj YWxsZWQgRXF1YWxzIG9uIExEQlJvb3QiKTsNCgkJfQ0KDQoJCXB1YmxpYyBvdmVycmlkZQ0KCQkJ Ym9vbCBFcXVhbHMoW0FsbG93TnVsbF0gT2JqZWN0IG90aGVyKSB7DQoJCQl0aHJvdyBuZXcgTERC U2hvdWxkTm90QmVJbXBsZW1lbnRlZEV4Y2VwdGlvbigNCgkJCQkJCQkJCSJjYWxsZWQgRXF1YWxz IGluIE9iamVjdCIpOw0KCQl9DQoNCgkJcHVibGljIG92ZXJyaWRlIGludCBHZXRIYXNoQ29kZSgp IHsNCgkJCXRocm93IG5ldyBMREJTaG91bGROb3RCZUltcGxlbWVudGVkRXhjZXB0aW9uKA0KCQkJ CQkJCQkJImNhbGxlZCBHZXRIYXNoQ29kZSBpbiBMREJSb290Iik7DQoJCX0NCg0KCQlwdWJsaWMg c3RhdGljIGJvb2wgb3BlcmF0b3IgPT0oTERCUm9vdCBsaHMsDQoJCQkJCQkJCQkgICBMREJSb290 IHJocykgew0KCQkJdGhyb3cgbmV3IExEQlNob3VsZE5vdEJlSW1wbGVtZW50ZWRFeGNlcHRpb24o DQoJCQkJCQkJCQkiY2FsbGVkID09IGluIExEQlJvb3QiKTsNCgkJfQ0KDQoJCXB1YmxpYyBzdGF0 aWMgYm9vbCBvcGVyYXRvciAhPShMREJSb290IGxocywNCgkJCQkJCQkJCSAgIExEQlJvb3Qgcmhz KSB7DQoJCQl0aHJvdyBuZXcgTERCU2hvdWxkTm90QmVJbXBsZW1lbnRlZEV4Y2VwdGlvbigNCgkJ CQkJCQkJCSJjYWxsZWQgIT0gaW4gTERCUm9vdCIpOw0KCQl9DQoNCg0KCQlwdWJsaWMgdmlydHVh bCBzdHJpbmcgY2xhc3NOYW1lIHsNCgkJCS8vIHRvZG8gLSB0aGlzIG5lZWRzIGNoZWNraW5nIGl0 IHdvcmtzIGFzIEkgd2FudA0KCQkJLy8gYWxzbyByZW5hbWUgdG8gbGRiY2xhc3NuYW1lIC0tIHRv ZG8NCgkJCWdldCA9PiB0aGlzLkdldFR5cGUoKS5GdWxsTmFtZSA/PyAiKHVua25vd24pIjsNCgkJ fQ0KDQoNCgkJcHVibGljIHZpcnR1YWwgc3RyaW5nIGNsYXNzTmFtZVEgPT4NCgkJCSInIiArIGNs YXNzTmFtZSArICInIjsNCg0KDQoJCXB1YmxpYyB2aXJ0dWFsIHN0cmluZyBjbGFzc05hbWVQbHVz KHN0cmluZyBwbHVzKSA9Pg0KCQkJY2xhc3NOYW1lICsgIi4iICsgcGx1czsNCg0KCQlwdWJsaWMg b3ZlcnJpZGUgc3RyaW5nIFRvU3RyaW5nKCkgew0KCQkJLy8gVGhpcyBpbXBsaWNpdCB0by1zdHJp bmcgY29udmVyc2lvbiBjcmFwIGNvc3QgbWUgYSBmZXcgaG91cnMsIHNvIGF0IGxlYXN0DQoJCQkv LyBkbyB0aGlzICYgYmxvdyB1cCBhdCBydW50aW1lLiBXb3VsZCBwcmVmZXIgY29tcGlsZSB0aW1l IGJ1dCBpdCBzZWVtcw0KCQkJLy8gbm90IHBvc3NpYmxlLiAgVGhpcyB0dXJucyBvdXQgdG8gaGF2 ZSBiZWVuIGEgZ29vZCBpZGVhLA0KCQkJLy8gc2F2ZWQgbWUgcXVpdGUgYSBiaXQgbW9yZSBkZWJ1 Z2dpbmchDQoJCQkvLyA8aHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvMTUzNDU1 MTcvaXMtaXQtcG9zc2libGUtdG8tZGlzYWJsZS1pbXBsaWNpdC10b3N0cmluZy1jYWxsPg0KCQkJ Ly8gV2lsbCB0cnkgPGh0dHBzOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzU0MzU0MzQy L2hvdy10by1nZXQtYW4tZXJyb3Itc2hvd24td2hlbi11c2luZy1ub24tc3RyaW5ncy1hcy1zdHJp bmdzLWluc3RlYWQtb2YtYW4tYXV0b20vNTQzNTUxMTUjNTQzNTUxMTUpDQoJCQl2YXIgbXNnID0g IkxEQlJvb3QuVG9TdHJpbmcoKSI7DQoJCQl0aHJvdyBuZXcgTERCVG9TdHJpbmdJbXBsaWN0Q29u dmVyc2lvbkV4Y2VwdGlvbihtc2cpOw0KCQl9DQoNCgkJcHVibGljIGFic3RyYWN0IHN0cmluZyB0 b0RlYnVnU3RyKCk7DQoJfQ0KDQoNCg0KCXB1YmxpYyBhYnN0cmFjdCBjbGFzcyBFcGhlbWVyYWwg OiBMREJSb290IHsNCgkJLy8gZm9yIG9iamVjdHMgdGhhdCBhcmUgbm90IHBhcnQgb2YgdGhlIEFT VA0KCX0NCg0KDQoNCglwdWJsaWMgaW50ZXJmYWNlIElXaXRoTGluZU5VbSB7ICAvLyB0b2RvIC0g dXNlIG9yIHJlbW92ZSAtIHRvZG8NCgkJLy8JcHVibGljIA0KCX0NCg0KDQoJcHVibGljIGludGVy ZmFjZSBJSGFzVGFibGVBbGlhcyB7DQoJCS8vIEhhcyBhIHRhYmxlIGFsaWFzIEFTVCBvYmouIE1h eSBiZSBhIC4uLk1pc3Npbmcgc3VidHlwZSBpbiB3aGljaA0KCQkvLyBpdCBoYXMgbm8gYWxpYXMg Z2l2ZW4gYnkgdGhlIHVzZXIsIGJ1dCBhbGlhcyBBU1QgaXMgdGhlcmUuIE1vcmUNCgkJLy8gYWNj dXJhdGVseSBhIFRhYmxlU291cmNlIGFsaWFzIGJ1dCBvaw0KCQlwdWJsaWMgYWJzdHJhY3QgVGFi bGVBbGlhcyB0YSB7IGdldDsgc2V0OyB9DQoJfQ0KDQoNCgkvLyBCYXNlIGNsYXNzIGZvciBhbGwg TERCIEFTVCBvYmplY3RzDQoJcHVibGljIGFic3RyYWN0IGNsYXNzIExEQkFTVG9iaiA6IExEQlJv b3Qgew0KCQkvLyBUaGlzIG9uZSBpcyBhIHByb2JsZW0uIElmIEkgZGVjbGFyZSB0aGUgJ3BhcmVu dCcgcHJvcGVydHkNCgkJLy8gYWJzdHJhY3QgSSB0aGVuIGhhdmUgdG8gaW1wbGVtZW50IGl0IGxp dGVyYWxseSBodW5kcmVkcyBvZg0KCQkvLyB0aW1lcyBpbiB0aGUgZGVyaXZlZCBjbGFzc2VzLCBh bmQgSSByZWFsbHkgZG9uJ3QgdGhpbmsgaXQNCgkJLy8gd291bGQgaGVscCBzbyBqdXN0IHNldCBp dCB0byBhIGRlZmF1bHQgd2hpY2ggZ2V0cyBvdmVyd3JpdHRlbiBsYXRlci4NCgkJLy8gDQoJCS8v IFRoZSBwcm9ibGVtIGlzIHRoYXQgdGhvc2Ugb2JqZWN0cyB3ZXJlIGNyZWF0ZWQgYnkgdGhlDQoJ CS8vIHBhcnNlciwgd2hpY2ggY3JlYXRlcyB0aGVtIGJvdHRvbS11cCwgd2hpY2ggbWVhbnMgeW91 IGNhbid0DQoJCS8vIGtub3cgdGhlIHBhcmVudCB3aGVuIHRoZXkgYXJlIGNyZWF0ZWQuIEl0IHNo b3VsZCBiZQ0KCQkvLyBwb3NzaWJsZSB0byB3b3JrIGFyb3VuZCB0aGlzIGJ1dCBpdCBkb2VzIG1l YW4gcmV3b3JraW5nIHRoZQ0KCQkvLyBwYXJzZXIgZnVuZGFtZW50YWxseSwgYW5kIEknbSBub3Qg Z29pbmcgdG8gZG8gdGhhdA0KCQkvLyBhc3N1bWVpbmcgaXQncyBldmVuIHBvc3NpYmxlLg0KDQoJ CS8vIHRvZG8gLSByZWFkIHVwIG9uIHByaXYvcHViL3Byb2cgYWNjZXNzb3JzIEkgcmVhbGx5IGRv bid0DQoJCS8vIGdldCB0aGVzZSBhdCBhbGwNCgkJcHVibGljIExEQkFTVG9iaiBwYXJlbnQgeyBn ZXQ7IHByaXZhdGUgc2V0OyB9DQoJCQkJCQk9IG5vUGFyZW50Ow0KCQkvLyBVbmlxdWUgSUQgcGVy IG9iamVjdCwgdXNlZnVsIGZvciBkaXN0aW5ndWlzaGluZyB0aGVtDQoJCS8vIHdpdGhvdXQgZ2Vu ZXJhbCBlcXVhbGl0eS4NCgkJcmVhZG9ubHkgcHVibGljIHVsb25nIHVpZCA9IG5ld1VJRCgpOw0K DQoJCS8vIHB1YmxpYyBhYnN0cmFjdCBpbnQgbGluZU51bSB7IGdldDsgc2V0OyB9DQoNCgkJLy8g SXMgdmFsaWRhdGVkIGlzIGEgY2hlYXBpc2ggY2hlY2sgdG8gZW5zdXJlIGV2ZXJ5dGhpbmcgZ2V0 cw0KCQkvLyB2YWxpZGF0ZWQNCgkJLy8gY2FuIGRvIHRoaXMgYXMgYXV0byBwcm9wPyB0b2RvDQoJ CXByaXZhdGUgYm9vbCBfdmFsaWRhdGVkID0gZmFsc2U7DQoNCgkJcHJvdGVjdGVkIGJvb2wgdmFs aWRhdGVkIHsNCgkJCWdldCA9PiBfdmFsaWRhdGVkOw0KCQkJc2V0IHsNCgkJCQkvLyBoYXJkTXVz dCghdmFsaWRhdGVkLCAiLi4uIGFscmVhZHkgdmFsaWRhdGVkLi4uICIpOyAtIG5vDQoJCQkJLy8g SXQncyBoYXJkIHRvIGF2b2lkIHZhbGlkYXRpbmcgYSB0aGluZyB0d2ljZSwgc28gZm9yIG5vdyBh bGxvdyBpdA0KCQkJCS8vIExvb2sgaW50byBpdCBsYXRlciwgcmVhbGx5IHNob3VsZG4ndCBoYXBw ZW4NCgkJCQlfdmFsaWRhdGVkID0gdHJ1ZTsNCgkJCX0NCgkJfQ0KDQoJCXB1YmxpYyBMREJTdHJ1 Y3RzQ2hpbGRyZW4ga2lkcyB7IGdldDsgcHJpdmF0ZSBzZXQ7IH0gPQ0KCQkJCQluZXcgTERCU3Ry dWN0c0NoaWxkcmVuKG5vUGFyZW50KTsgLy8ganVzdCBlYXNpZXINCg0KCQlwdWJsaWMgTERCQVNU b2JqKCkgeyAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8v Ly8vLy8vLy8vLy8vLy8vLyB0b2RvIGRlYWQ/DQoJCQkJCQkJICAvLyBWU3R1ZGlvIHRoaW5rcyB0 aGlzIGhhcyB6ZXJvIHJlZmVyZW5jZXMsIHdoaWNoIGlzIHRydWUgZXhwbGljaXRseSwgYnV0IGl0 J3MgDQoJCQkJCQkJICAvLyBjYWxsZWQgaW1wbGljaXRseSBvbiBldmVyeSBvYmogY3JlYXRpb24g LSBvciBzaG91bGQgZG8gdG9kby0gY2hlY2sNCgkJCWlmIChyZWNvcmRPYmplY3RzQ3JlYXRlZCkg ew0KCQkJCUFsbENyZWF0ZWRJdGVtcy5BZGQodGhpcyk7DQoJCQl9DQoJCX0NCg0KDQoJCXB1Ymxp YyB2aXJ0dWFsIHZvaWQgdmFsaWRhdGUoKSB7DQoJCQlpZiAocmVwb3J0QWxzb0lmVmFsaWRhdGlv bk9LKSB7DQoJCQkJZGVidWdtc2coInZhbGlkYXRpbmcuLi4iICsgY2xhc3NOYW1lDQoJCQkJCSsg IiAoIiArIGFzTmFtZU9ySWRlbnRDb250ZW50cygpICsgIikiKTsNCgkJCX0NCgkJCW1ocF9taGso KTsNCgkJCWtpZHMudmFsaWRhdGUoKTsNCgkJCS8vIHZhbGlkYXRlZCA9IHRydWU7IC0tIE5vLCBn ZXQgZWFjaCBzdWJjbGFzcyB0byBzZXQNCgkJCS8vIHZhbGlkYXRlZC4gVGhhdCBmb3JjZXMgYW4g ZXhwbGljaXQgY2FsbCB0byBiYXNlKCkgd2hpY2gNCgkJCS8vIGlzIG1vcmUgY29kZSBidXQgb2su DQoJCX0NCg0KDQoJCXB1YmxpYyBib29sIGlzVmFsaWRhdGVkIHsgZ2V0ID0+IHZhbGlkYXRlZDsg fSAgLy8gdG9kbyBqdXN0ID0+IHZhbGlkYXRlZDsNCg0KDQoJCXB1YmxpYyB2aXJ0dWFsIGJvb2wg aXNUb3BMZXZlbEl0ZW1TZXEgPT4gZmFsc2U7DQoNCg0KCQlwdWJsaWMgdmlydHVhbCB2b2lkIG1o cF9taGsoKSB7ICAvLyBkb24ndCB0aGluayB0aGlzIG5lZWQgYmUgdmlydHVhbCAtIHRvZG8/DQoJ CQkJCQkJCQkJIC8vID0gbXVzdCBoYXZlIHBhcmVudCwgbXVzdCBoYXZlIGtpZHMuIFRoZSBraWRz IG1heSBiZSB0aGUNCgkJCQkJCQkJCQkgLy8gZW1wdHkgc2V0IGFuZCB0aGUgcGFyZW50IG1heSBi ZSBub1BhcmVudCBidXQgdGhleSBtdXN0DQoJCQkJCQkJCQkJIC8vIGV4aXN0Lg0KCQkJCQkJCQkJ CSAvLyBXaHkgbm90IGp1c3QgaW5saW5lIHRoaXMgaW50byB2YWxpZGF0ZSgpPw0KCQkJCQkJCQkJ CSAvLyBCZWNhdXNlIGEgZmV3IGNsYXNzZXMgbmVlZCBiZXNwb2tlIHZhbGlkYXRpb24sIGJ1dCBz dGlsbCBtdXN0IGNoZWNrIHRoaXMuDQoJCQloYXJkTXVzdFBhcmVudElzUHJlc2VudCgpOw0KCQkJ a2lkcy5lYWNoS2lkUGFyZW50TXVzdEJlKHRoaXMpOw0KCQl9DQoNCg0KCQlwdWJsaWMgc3RyaW5n IGFzTmFtZU9ySWRlbnRDb250ZW50cygpIHsNCgkJCS8vIGZvciB2ZXJ5IGNydWRlIGRlYnVnZ2lu ZyANCgkJCXZhciBvcHROYW1lID0gdGhpcyBpcyBJaXNOYW1lZEl0ZW0gbmkgPyBuaS5uYW1lLnRv UmF3U3RyKCkgOiAiIjsNCgkJCW9wdE5hbWUgPSAob3B0TmFtZSA9PSAiIiAmJiB0aGlzIGlzIFBN UUlkZW50KSA/IHRoaXMudG9SYXdTdHIoKSA6ICIiOw0KDQoJCQl2YXIgb3B0TmFtZTIgPSBvcHRO YW1lICsgIiAgKHVpZDoiICsgdWlkLlRvU3RyaW5nKCkgKyAiKSAiDQoJCQkJKyBnZXRGaXJzdEZl d0NoYXJzT2YodG9SYXdTdHIoKSk7DQoJCQlyZXR1cm4gb3B0TmFtZTI7DQoJCX0NCg0KDQoJCXB1 YmxpYyB2aXJ0dWFsIHZvaWQgZ2V0QWxsVUlEcyhVSURzZXQgdWlkcykgew0KCQkJdWlkcy5BZGQo dGhpcyk7DQoJCQlraWRzLkZvckVhY2gobmFtZWRLaWQgPT4gbmFtZWRLaWQua2lkLmdldEFsbFVJ RHModWlkcykpOw0KCQl9DQoNCg0KCQlwdWJsaWMgYm9vbCBpc1N0dWJQYXJlbnQgeyBnZXQgPT4g KHRoaXMgaXMgTm9QYXJlbnQpIHx8ICh0aGlzIGlzIEZha2VQYXJlbnQpOyB9DQoNCg0KCQlwdWJs aWMgdm9pZCB2YWxpZGF0ZVNwZWNpZmljSXRlbXMocGFyYW1zIExEQkFTVG9ialtdIGl0ZW1zKSB7 DQoJCQlBcnJheS5Gb3JFYWNoKGl0ZW1zLCBpdGVtID0+IGl0ZW0udmFsaWRhdGUoKSk7DQoJCX0N Cg0KDQoJCXB1YmxpYyBUPyBvcHRDbGltYlRvPFQ+KCkgd2hlcmUgVCA6IExEQkFTVG9iaiB7DQoJ CQl2YXIgcmVzSXRlbSA9IHRoaXM7DQoJCQl3aGlsZSAoIShyZXNJdGVtIGlzIFQpKSB7DQoJCQkJ aWYgKHJlc0l0ZW0ucGFyZW50LmlzU3R1YlBhcmVudCkgew0KCQkJCQlyZXR1cm4gbnVsbDsNCgkJ CQl9DQoJCQkJcmVzSXRlbSA9IHJlc0l0ZW0ucGFyZW50Ow0KCQkJfQ0KDQoJCQl2YXIgcmVzID0g cmVzSXRlbSBhcyBUOw0KCQkJcmV0dXJuIHJlczsNCgkJfQ0KDQoNCgkJcHVibGljIFQgcmVxQ2xp bWJUbzxUPigpIHdoZXJlIFQgOiBMREJBU1RvYmogew0KCQkJdmFyIGxvYyA9IGNsYXNzTmFtZSAr ICIucmVxQ2xpbWJUbzxUPigpIjsNCgkJCXZhciByZXMgPSBvcHRDbGltYlRvPFQ+KCk7DQoJCQlo YXJkTXVzdDIoIShyZXMgaXMgbnVsbCksIA0KCQkJCS8vIFRoYW5rcyBTTyA8aHR0cHM6Ly9zdGFj a292ZXJmbG93LmNvbS9xdWVzdGlvbnMvMjU4MTY0Mi9ob3ctZG8taS1nZXQtdGhlLXR5cGUtbmFt ZS1vZi1hLWdlbmVyaWMtdHlwZS1hcmd1bWVudD4NCgkJCQkvLyBUb2RvIC0gdXNlIHRoaXMgZWxz ZXdoZXJlLCBwb3NzIEV4cGVjdEV4Y2VwdGlvbj8gdG9kbw0KCQkJCSgpID0+DQoJCQkJbG9jIA0K CQkJCSsgbmwgKyAiLCBjbGltYmVkIHRvIHRvcCwgZGlkbid0IGZpbmQgdHlwZSAiDQoJCQkJKyB0 eXBlb2YoVCkuRnVsbE5hbWUNCgkJCQkrIG5sICsgIkhpZXJhcmNoeSBpczogIg0KCQkJCSsgbmwg KyBnZXRJdGVtV2l0aFBhcmVudHModGhpcykpOw0KCQkJaWYgKHJlcyBpcyBudWxsKSB7IHRocm93 IG5ldyBOTlFDKCk7IH0NCgkJCXJldHVybiByZXM7DQoJCX0NCg0KDQoJCXB1YmxpYyB2b2lkIGhh cmRNdXN0UGFyZW50SXNQcmVzZW50KCkgew0KDQoJCQloYXJkTXVzdDIoIShwYXJlbnQgaXMgbnVs bCksIA0KCQkJCSgpID0+DQoJCQkJICJOVUxMIHBhcmVudCBmb3IgaXRlbSBvZiB0eXBlXG4iDQoJ CQkJICsgJCJ7R2V0VHlwZSgpfVxuLiIpOw0KDQoJCQloYXJkTXVzdDIoISh0aGlzLnBhcmVudCBp cyBOb1BhcmVudCksDQoJCQkJKCkgPT4NCgkJCQkiUGFyZW50IGlzIE5vUGFyZW50IG9uIG9iamVj dCBvZiB0eXBlXG4iDQoJCQkJKyAkIid7dGhpcy5jbGFzc05hbWV9JyIpOw0KCQl9DQoNCg0KCQlw dWJsaWMgdm9pZCBoYXJkTXVzdFBhcmVudElzQWJzZW50KCkgew0KCQkJLy8gRm9yIGNoZWNraW5n IGNsb25pbmcgLSBwYXJlbnQgc2hvdWxkIGJlIE5vUGFyZW50IGltbWVkaWF0ZWx5IA0KCQkJLy8g YWZ0ZXIsIGJlZm9yZSBpdCdzIHNldCBieSBwYXJlbnQsIGFuZCBuZXZlciBudWxsDQoJCQloYXJk TXVzdCghKHBhcmVudCBpcyBudWxsKSwNCgkJCQkgIk5VTEwgcGFyZW50IGZvciBpdGVtIG9mIHR5 cGVcbiINCgkJCQkgKyAkIntHZXRUeXBlKCl9XG4uIik7DQoJCQloYXJkTXVzdCgodGhpcy5wYXJl bnQgaXMgTm9QYXJlbnQpLA0KCQkJCSJQYXJlbnQgc2hvdWxkIGJlIE5vUGFyZW50IG9uIG9iamVj dCBvZiB0eXBlXG4iDQoJCQkJKyAkIid7dGhpcy5jbGFzc05hbWV9JyIpOw0KCQl9DQoNCg0KCQlw dWJsaWMgYm9vbCBoYXNQYXJlbnQ8UD4oKSB7DQoJCQloYXJkTXVzdCghKHRoaXMgaXMgTm9QYXJl bnQpLCAiSXRlbSBpcyBOb1BhcmVudCIpOw0KCQkJcmV0dXJuIHRoaXMucGFyZW50IGlzIFA7DQoJ CX0NCg0KDQoJCXB1YmxpYyBib29sIGhhc0FuY2VzdG9yPEE+KCkgew0KCQkJaGFyZE11c3QoIXRo aXMuaXNTdHViUGFyZW50LCAiSXRlbSBpcyBOb1BhcmVudCIpOw0KDQoJCQkvLyBob3cgdG8gZG8g d2l0aCBhIHN3aXRjaCBleHByPw0KCQkJaWYgKHRoaXMucGFyZW50LmlzU3R1YlBhcmVudCAvKiBp cyBOb1BhcmVudCB8fCB0aGlzLnBhcmVudCBpcyBGYWtlUGFyZW50Ki8gKSB7IC8vIHRvZG8gZG8g YXMgeC5oYXNGdWRnZWRQYXJlbnQoKSAtIHRvZG8NCgkJCQlyZXR1cm4gZmFsc2U7DQoJCQl9IGVs c2UgaWYgKHRoaXMucGFyZW50IGlzIEEpIHsNCgkJCQlyZXR1cm4gdHJ1ZTsNCgkJCX0gZWxzZSB7 DQoJCQkJcmV0dXJuIHRoaXMucGFyZW50Lmhhc0FuY2VzdG9yPEE+KCk7DQoJCQl9DQoJCX0NCg0K CQlwdWJsaWMgYm9vbCBub3RIYXNBbmNlc3RvcjxBPigpID0+DQoJCQkhaGFzQW5jZXN0b3I8QT4o KTsNCg0KDQoJCXB1YmxpYyB2b2lkIHNldE15UGFyZW50VG8oTERCQVNUb2JqIHBybnQpIHsNCgkJ CS8vIEFuIG9iamVjdCBtYXkgb25seSBzZXQgaXRzIHBhcmVudCBpZiBpdHMgY3VycmVudCBwYXJl bnQgaXMNCgkJCS8vIHRoZSBkdW1teSAnbm9QYXJlbnQnLCB3aGljaCBhbG1vc3QgZXZlcnkgb2Jq ZWN0J3MgcGFyZW50IGlzDQoJCQkvLyBzZXQgdG8gb24gY3JlYXRpb24gKHNlZSBMREJBU1RvYmog cGFyZW50IHByb3BlcnR5IGRlZikuDQoNCgkJCS8vIFRoZSB0ZXN0IGZvciBudWxsIGlzIHBlY3Vs aWFyIGdpdmVuIHRoaXMuIEJlY2F1c2UNCgkJCS8vIG5vUGFyZW50IGlzIGNyZWF0ZWQgc3RhdGlj YWxseSwgc2V0dGluZyB0aGUgcGFyZW50IG9mDQoJCQkvLyBub1BhcmVudCBpcyBkaWZmaWN1bHQs IHBlcmhhcHMgaW1wb3NzaWJsZSwgdG8gZG8gc3RhdGljYWxseQ0KCQkJLy8gYW5kIHJlbGlhYmx5 LkRlc3BpdGUgdGhlIGRlY2xhcmF0aW9uICcjbnVsbGFibGUgZW5hYmxlJywgaXQNCgkJCS8vIGdl dHMgY3JlYXRlZCB3aXRoIGEgbnVsbCBwYXJyZW50IChxdWl0ZSByZWFzb25hYmx5KSwgaGVuY2UN CgkJCS8vIHRoaXMgY2hlY2suVGhlIGFjdHVhbCBzZXR0aW5nIG9mIHRoZSBwYXJlbnQgaGFzIHRv IGJlIGRvbmUNCgkJCS8vIGF0IHJ1bnRpbWUgaS5lLmFmdGVyIHRoZSBzdGF0aWMgY3JlYXRpb24g b2YgJ25vUGFyZW50Jy4NCg0KCQkJaGFyZE11c3QyKCh0aGlzLnBhcmVudCBpcyBOb1BhcmVudCkg fHwgKHRoaXMucGFyZW50IGlzIG51bGwpLA0KCQkJCSgpID0+DQoJCQkJInRyaWVkIHRvIHJlLXNl dCBwYXJlbnQgb24gb2JqZWN0IG9mIHR5cGU6ICINCgkJCQkrIG5sICsgdGhpcy5jbGFzc05hbWVR DQoJCQkJKyBubCArICJPcmlnaW5hbCBwYXJlbnQgdHlwZSBpczogIg0KCQkJCSsgKHRoaXM/LnBh cmVudD8uY2xhc3NOYW1lUSA9PSBudWxsID8gIm51bGwiIDogdGhpcy5wYXJlbnQuY2xhc3NOYW1l USkNCgkJCQkrIG5sICsgImFuZCBuZXcgcGFyZW50IHR5cGUgaXM6ICINCgkJCQkrIHBybnQuY2xh c3NOYW1lUQ0KCQkJCSsgbmwgKyAiSXRlbSBoYXZpbmcgcGFyZW50IHNldCBvbiBpdCBpczogIg0K CQkJCS8vIGJlY2F1c2Ugb2JqZWN0IG1heSBub3QgYmUgZnVsbHkgY29uc3RydWN0ZWQgeWV0LCBj aGVjayBob3d2ZXIgVE9ETyB0aGlzIGlzIGEgbWFqb3IgaGFjayBhbmQgbXVzdCBiZSBmaXhlZCBz b21ldGltZS4NCi8vCQkJCSsgbmwgKyAodGhpcyBpcyBudWxsID8gIihudWxsKSIgOiB0aGlzLnRv UmF3U3RyKCkpKTsNCgkJCQkrIG5sICsgdGhpcy50b1Jhd1N0cigpICk7DQoNCgkJCXBhcmVudCA9 IHBybnQ7DQoJCX0NCg0KDQoJCXB1YmxpYyB2b2lkIGZvcmNlTmV3UGFyZW50Rm9yUm9vdE9iamVj dCgpIHsNCgkJCS8vIEV2ZXJ5IG9iamVjdCBtdXN0IGhhdmUgc29tZSBwYXJlbnQsIGluY2x1ZGlu ZyB0aGUNCgkJCS8vIHJvb3Qgb2JqZWN0IG9mIHRoZSBwYXJzZSwgd2hpY2ggaXMgTERCaXRlbXMN CgkJCS8vIChhIHNlcXVlbmNlIG9mIExEQiBpdGVtcyksIHNvIHRoaXMgZm9yY2VzIG9uZS4NCgkJ CS8vIEl0IGlzIG9ubHkgZm9yIHRoYXQgcHVycG9zZSENCgkJCS8vIA0KCQkJLy8gTERCaXRlbXMg b2JqIGV4aXN0cyBmb3Igc3ViIG9ianMgc3VjaCBhcyB0aGUgc3RhdGVtZW50cw0KCQkJLy8gaW4g YSB3aGlsZSBsb29wLCBpbiBhIHByb2MsIGluIGFuIGlmLi4uIGV0Yy4sIGZvcg0KCQkJLy8gd2hp Y2ggdGhlaXIgcGFyZW50IGlzIHRoZSB3aGlsZS9wcm9jL2lmIGV0Yy4NCgkJCWhhcmRNdXN0UGFy ZW50SXNBYnNlbnQoKTsNCgkJCXRoaXMucGFyZW50ID0gZmFrZVBhcmVudDsNCgkJfQ0KDQoNCgkJ Ly9wdWJsaWMgdm9pZCByZXNldE15UGFyZW50VG8oTERCQVNUb2JqIHBybnQpIHsgIC8vLy8vLy8v Ly8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8gZGVzdHJveSEhISEhISB0b2RvDQoJCS8vCXBhcmVu dCA9IHBybnQ7DQoJCS8vfQ0KDQoJCS8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLyB4eHh4eHh4eHh4 eHh4IGRlbGV0ZSAtIHRvZG8NCgkJLy9wcml2YXRlIHZvaWQgc2V0UGFyZW50T25LaWQoTERCQVNU b2JqIGtpZCkgPT4gLy8gdG9kbyBuZWVkZWQ/DQoJCS8vCQkJCQkJCQkJCQkgIC8vIGNoZWNrIHBh cmVudGUgZG9lc24ndCBleGlzdCAtIHRvZG8NCgkJLy8Ja2lkLnBhcmVudCA9IHRoaXM7DQoNCgkJ cHVibGljIHZpcnR1YWwgdm9pZCBzZXRQYXJlbnRPbktpZHNBbmRNYWtlS2lkc0RpY3QoICAvLyB0 b2RvIC0gYW5kIGFkZCB0byBraWRzIGRpY3QNCgkJCQkJCQkJCQkJCQkJCSAvLyB0aGlzIG1peGVz IHVwIHNldHRpbmcgcGFyZW50IGFuZCBtYWtpbmcgY2hpbGQgZGljdC4gTm90IGdvb2QuIC0gdG9k bw0KCQkJCQkJcGFyYW1zIChzdHJpbmcga2lkTmFtZSwgTERCQVNUb2JqIGtpZClbXSBraWRzSW4p IHsNCgkJCXZhciBsb2MgPSBjbGFzc05hbWVQbHVzKCJzZXRQYXJlbnRPbktpZHNBbmRNYWtlS2lk c0RpY3QiKTsNCg0KCQkJdmFyIGtpZHNUb0FkZCA9IG5ldyBMREJTdHJ1Y3RzQ2hpbGRyZW4odGhp cywga2lkc0luKTsNCgkJCWhhcmRNdXN0MihraWRzLmlzRW1wdHksDQoJCQkJKCkgPT4NCgkJCQkk InNldHRpbmcga2lkcyBvbiBwYXJlbnQgJ3tjbGFzc05hbWV9JyIgDQoJCQkJKyAid2hlbiBraWRz IGlzIG5vdCBlbXB0eSwgIg0KCQkJCSsgJCJraWRzIGlzICh7a2lkcy5Db3VudH0ga2lkcyk6Ig0K CQkJCSsgbmwgKyBraWRzLnRvRGVidWdTdHIoKQ0KCQkJCSsgbmwgKyAkIlRyeWluZyB0byBhZGRc bntraWRzVG9BZGQudG9EZWJ1Z1N0cigpfVxuIg0KCQkJCSsgJCJpbiB7Y2xhc3NOYW1lfSIpOw0K CQkJLy8gaWYgdGhlcmUgaXMgYW4gTERCU3RydWN0c0NoaWxkcmVuIGFuZCBhbm90aGVyIGNoaWxk LA0KCQkJLy8gdGhpcyB3aWxsIGJsb3cgdXAgLSB3aWxsIG5lZWQgdG8gZG8ga2lkcy5BZGQgb3IN CgkJCS8vIHNvbWV0aGluZyAtIGluIGZhY3QsIGtpZHMgbmVlZHMgdG8gYmUgY3JlYXRlZCBpbiBv bmUNCgkJCS8vIGdvLCB3aGljaCBpcyB3aGF0IGhhcHBlbnMuDQoJCQlraWRzID0ga2lkc1RvQWRk OyAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8v Ly8vLy8gd2h5IHRoaXM/IHRvZG8NCgkJCUFycmF5LkZvckVhY2goa2lkc0luLCB4a2lkID0+IGhh cmRNdXN0KCEoeGtpZC5raWQgaXMgbnVsbCksIGxvYywgIm51bGwga2lkIikpOw0KCQkJQXJyYXku Rm9yRWFjaChraWRzSW4sIHhraWQgPT4geGtpZC5raWQuc2V0TXlQYXJlbnRUbyh0aGlzKSk7DQoJ CX0NCg0KDQoJCXB1YmxpYyB2aXJ0dWFsIHZvaWQgc2V0UGFyZW50T25LaWRzQW5kQWRkVG9LaWRz RGljdCgNCgkJCQkJcGFyYW1zIChzdHJpbmcga2lkTmFtZSwgTERCQVNUb2JqIGtpZClbXSBraWRz SW4pIHsNCgkJCXZhciBraWRzVG9BZGRfanVzdEZvckVyclJlcG9ydGluZyA9IG5ldyBMREJTdHJ1 Y3RzQ2hpbGRyZW4odGhpcywga2lkc0luKTsNCgkJCWhhcmRNdXN0Migha2lkcy5pc0VtcHR5LCAv LyBtYXkgZGlzYWJsZSB0aGlzIGxhdGVyIA0KCQkJCSgpID0+DQoJCQkJImFkZGluZyB0byBraWRz IHdoZW4ga2lkcyBpcyBlbXB0eSwgIg0KCQkJCSArICQia2lkcyBpc1xue2tpZHMudG9EZWJ1Z1N0 cigpfVxuIg0KCQkJCSArICQiVHJ5aW5nIHRvIGFkZFxue2tpZHNUb0FkZF9qdXN0Rm9yRXJyUmVw b3J0aW5nLnRvRGVidWdTdHIoKX1cbiINCgkJCQkgKyAkImluIHtjbGFzc05hbWV9Iik7DQoJCQlB cnJheS5Gb3JFYWNoKGtpZHNJbiwgeGtpZCA9PiB7DQovLwkJCQlzZXRQYXJlbnRPbktpZCh4a2lk LmtpZCk7DQoJCQkJeGtpZC5raWQuc2V0TXlQYXJlbnRUbyh0aGlzKTsNCgkJCQlraWRzLkFkZCh4 a2lkKTsNCgkJCX0pOw0KCQl9DQoNCg0KCQlwdWJsaWMgdmlydHVhbCBJZGVudHNVc2VkIGdldEFs bElEcygpIHsNCgkJLyogVGhpcyBpcyBvdmVycmlkZGVuIG9ubHkgaW4gVGVtcGxhdGVkQWdnLCBh bmQgdGhhdCdzIG9ubHkgdG8gDQoJCQlkZWxpYmVyYXRlbHkgZmFpbC4gVGhlcmUncyBzb21ldGhp bmcgd3JvbmcgdGhlcmUsIHRvZG8gLSANCgkJCXVuLXZpcnR1YWxpc2UgdGhpcyBhbmQgcmVtb3Zl IHRoZSBvbmUgb3ZlcnJpZGUuIC0gdG9kbw0KCQkqLw0KCQkJdmFyIGl1ID0gbmV3IElkZW50c1Vz ZWQoKTsNCgkJCXRoaXMuX2dldEFsbElEcyhpdSk7DQoJCQlyZXR1cm4gaXU7DQoJCX0NCg0KCQlw dWJsaWMgdmlydHVhbCB2b2lkIF9nZXRBbGxJRHMoSWRlbnRzVXNlZCBpdSkgew0KCQkvLyBHZXRz IGFsbCB0aGUgaWRlbnRpZmllcnMgZXhwbGljaXRseSB1c2VkIChyZWFkIG9yIHdyaXR0ZW4pICAt LS0tLSB0b2RvIHVwZGF0ZSB0aGlzDQoJCS8vIGFueXdoZXJlIGluIHRoZSBBU1QuICBEb2VzIG5v dCBnZXQgaWRlbnRzIHdoaWNoIGFyZQ0KCQkvLyBkZWNsYXJhdGlvbnMgaWUuIHBhcmFtZXRlcnMs IG9yIHZhci9jb25zdCBkZWNsYXJhdGlvbnMNCgkJLy8gdW5sZXNzIHRoZXNlIGFyZSBjb21iaW5l ZCB3aXRoIGFuIGFzc2lnbm1lbnQuDQoJCS8vDQoJCS8vIEltcGxpZWQgaWRlbnRzIHN1Y2ggYXMg dGhvc2UgZnJvbSB0YmwuKiBhcmUgaW1wbGljaXQgYW5kIGlnbm9yZWQuDQoJCS8vDQoJCS8vIFJv b3QgY2FsbGVyIHN1cHBsaWVzIG5ldywgZW1wdHkgaXUNCgkJLy8gbmVlZCB1c2FnZSBoZXJlIC0g dG9kbyBkb2NzLy8NCgkJCWtpZHMuX2dldEFsbElEcyhpdSk7DQoJCX0NCg0KCQlwdWJsaWMgYWJz dHJhY3QgYm9vbCBjYW5HZXRBbGxJZGVudHNVc2VkIHsNCgkJLy8gCVRoaXMgc2VlbXMgdG8gYmUg dHJ1ZSBvbiBtb3N0IGNsYXNzZXMgc28gSSBjb3VsZCBzZXQgdHJ1ZSANCgkJLy8gYXMgYSBkZWZh dWx0IGhlcmUgYW5kIG92ZXJyaWRlIGl0IHdoZXJlIGl0J3Mgbm90IHdhbnRlZCwgc2F2aW5nIA0K CQkvLyBhIGNodW5rIG9mIGNvZGUsIGJ1dCBJJ2QgcmF0aGVyIG1ha2UgaXQgZXhwbGljaXQgdG8g Zm9yY2UgbWUgdG8gY29uc2lkZXIgZWFjaCBjYXNlLiBBIGJpdCBtb3JlIEMmUCBmb3IgbGVzcyBj aGFuY2Ugb2YgYnVncy4NCgkJCWdldDsNCgkJfQ0KDQoNCgkJLy8gUHJvZHVjZXMgYSBzdHJpbmcg dGhhdCBzaG91bGQgYmUgaWRlbnRpY2FsIHRvIChleGNlcHRpbmcNCgkJLy8gd2hpdGVzcGFjZXMp IHRoZSBpbnB1dCBpZS4gZW1pdCBMREIgY29kZSBub3QgdmFsaWQgU1FMDQoJCS8vDQoJCS8vIFRv U3RyaW5nIHdhcyBjYXVzaW5nIHRvbyBtYW55IHdlaXJkIHByb2JsZW1zIChkdWUgdG8gbXkNCgkJ Ly8gaW5leHBlcmllbmNlIHdpdGggYyMpIHNvIGp1c3QgdXNlZCB0b1Jhd1N0cigpDQoJCXB1Ymxp YyBhYnN0cmFjdCBzdHJpbmcgdG9SYXdTdHIoKTsNCg0KCQlwdWJsaWMgb3ZlcnJpZGUgc3RyaW5n IHRvRGVidWdTdHIoKSA9PiB0b1Jhd1N0cigpOw0KDQoJfSAvLyBlbmQgTERCQVNUb2JqDQoNCg0K DQoJcHVibGljIGludGVyZmFjZSBJaGFuZGxlUHJlZml4ZXM8VD4NCgkJCQkJCXdoZXJlIFQgOiBM REJSb290IHsNCg0KCQlwdWJsaWMgYm9vbCBpc1ByZWZpeGVkIHsgZ2V0OyB9DQoNCgkJcHVibGlj IGJvb2wgaXNFeGNlc3NQcmVmaXhlZCB7IGdldDsgfQ0KDQoJCS8vIFRoZSBUIGluIGFkZFByZWZp eC9yZVByZWZpeC93aXRob3V0UHJlZml4IGlzIGJlY2F1c2Ugd2UgbWF5IGJlIA0KCQkvLyByZXR1 cm5pbmcgZWcuIGEgbGlzdCBvZiBpdGVtcyB3aXRoIHByZWZpeGVzIA0KCQkvLyB0aHVzIG1vZGlm aWVkLCBub3QgYSBzaW5nbGUgUE1RSWRlbnQNCg0KCQlwdWJsaWMgVCBhZGRQcmVmaXgoUE1RSWRl bnQgcGZ4KTsNCg0KCQlwdWJsaWMgVCByZVByZWZpeChQTVFJZGVudCBuZXdwZngpOw0KDQovLwkJ cHVibGljIFQgc3RyaXBQcmVmaXgoUE1RSWRlbnQgaWQpOw0KCX0NCgkvLyB0b2RvIC0gbW92ZSB0 aGlzDQoNCg0KDQoNCg0KCXB1YmxpYyBhYnN0cmFjdCBjbGFzcyBMREJSb290IHsNCgkJLy8gUm9v dCBvZiBldmVyeXRoaW5nIExEQi1pc2gNCg0KCQlwdWJsaWMgYm9vbCBFcXVhbHMoW0FsbG93TnVs bF0gTERCUm9vdCBvdGhlcikgew0KCQkJdGhyb3cgbmV3IExEQlNob3VsZE5vdEJlSW1wbGVtZW50 ZWRFeGNlcHRpb24oDQoJCQkJCQkJCQkiY2FsbGVkIEVxdWFscyBvbiBMREJSb290Iik7DQoJCX0N Cg0KCQlwdWJsaWMgb3ZlcnJpZGUNCgkJCWJvb2wgRXF1YWxzKFtBbGxvd051bGxdIE9iamVjdCBv dGhlcikgew0KCQkJdGhyb3cgbmV3IExEQlNob3VsZE5vdEJlSW1wbGVtZW50ZWRFeGNlcHRpb24o DQoJCQkJCQkJCQkiY2FsbGVkIEVxdWFscyBpbiBPYmplY3QiKTsNCgkJfQ0KDQoJCXB1YmxpYyBv dmVycmlkZSBpbnQgR2V0SGFzaENvZGUoKSB7DQoJCQl0aHJvdyBuZXcgTERCU2hvdWxkTm90QmVJ bXBsZW1lbnRlZEV4Y2VwdGlvbigNCgkJCQkJCQkJCSJjYWxsZWQgR2V0SGFzaENvZGUgaW4gTERC Um9vdCIpOw0KCQl9DQoNCgkJcHVibGljIHN0YXRpYyBib29sIG9wZXJhdG9yID09KExEQlJvb3Qg bGhzLA0KCQkJCQkJCQkJICAgTERCUm9vdCByaHMpIHsNCgkJCXRocm93IG5ldyBMREJTaG91bGRO b3RCZUltcGxlbWVudGVkRXhjZXB0aW9uKA0KCQkJCQkJCQkJImNhbGxlZCA9PSBpbiBMREJSb290 Iik7DQoJCX0NCg0KCQlwdWJsaWMgc3RhdGljIGJvb2wgb3BlcmF0b3IgIT0oTERCUm9vdCBsaHMs DQoJCQkJCQkJCQkgICBMREJSb290IHJocykgew0KCQkJdGhyb3cgbmV3IExEQlNob3VsZE5vdEJl SW1wbGVtZW50ZWRFeGNlcHRpb24oDQoJCQkJCQkJCQkiY2FsbGVkICE9IGluIExEQlJvb3QiKTsN CgkJfQ0KDQoNCgkJcHVibGljIHZpcnR1YWwgc3RyaW5nIGNsYXNzTmFtZSB7DQoJCQkvLyB0b2Rv IC0gdGhpcyBuZWVkcyBjaGVja2luZyBpdCB3b3JrcyBhcyBJIHdhbnQNCgkJCS8vIGFsc28gcmVu YW1lIHRvIGxkYmNsYXNzbmFtZSAtLSB0b2RvDQoJCQlnZXQgPT4gdGhpcy5HZXRUeXBlKCkuRnVs bE5hbWUgPz8gIih1bmtub3duKSI7DQoJCX0NCg0KDQoJCXB1YmxpYyB2aXJ0dWFsIHN0cmluZyBj bGFzc05hbWVRID0+DQoJCQkiJyIgKyBjbGFzc05hbWUgKyAiJyI7DQoNCg0KCQlwdWJsaWMgdmly dHVhbCBzdHJpbmcgY2xhc3NOYW1lUGx1cyhzdHJpbmcgcGx1cykgPT4NCgkJCWNsYXNzTmFtZSAr ICIuIiArIHBsdXM7DQoNCgkJcHVibGljIG92ZXJyaWRlIHN0cmluZyBUb1N0cmluZygpIHsNCgkJ CS8vIFRoaXMgaW1wbGljaXQgdG8tc3RyaW5nIGNvbnZlcnNpb24gY3JhcCBjb3N0IG1lIGEgZmV3 IGhvdXJzLCBzbyBhdCBsZWFzdA0KCQkJLy8gZG8gdGhpcyAmIGJsb3cgdXAgYXQgcnVudGltZS4g V291bGQgcHJlZmVyIGNvbXBpbGUgdGltZSBidXQgaXQgc2VlbXMNCgkJCS8vIG5vdCBwb3NzaWJs ZS4gIFRoaXMgdHVybnMgb3V0IHRvIGhhdmUgYmVlbiBhIGdvb2QgaWRlYSwNCgkJCS8vIHNhdmVk IG1lIHF1aXRlIGEgYml0IG1vcmUgZGVidWdnaW5nIQ0KCQkJLy8gPGh0dHBzOi8vc3RhY2tvdmVy Zmxvdy5jb20vcXVlc3Rpb25zLzE1MzQ1NTE3L2lzLWl0LXBvc3NpYmxlLXRvLWRpc2FibGUtaW1w bGljaXQtdG9zdHJpbmctY2FsbD4NCgkJCS8vIFdpbGwgdHJ5IDxodHRwczovL3N0YWNrb3ZlcmZs b3cuY29tL3F1ZXN0aW9ucy81NDM1NDM0Mi9ob3ctdG8tZ2V0LWFuLWVycm9yLXNob3duLXdoZW4t dXNpbmctbm9uLXN0cmluZ3MtYXMtc3RyaW5ncy1pbnN0ZWFkLW9mLWFuLWF1dG9tLzU0MzU1MTE1 IzU0MzU1MTE1KQ0KCQkJdmFyIG1zZyA9ICJMREJSb290LlRvU3RyaW5nKCkiOw0KCQkJdGhyb3cg bmV3IExEQlRvU3RyaW5nSW1wbGljdENvbnZlcnNpb25FeGNlcHRpb24obXNnKTsNCgkJfQ0KDQoJ CXB1YmxpYyBhYnN0cmFjdCBzdHJpbmcgdG9EZWJ1Z1N0cigpOw0KCX0NCg0KDQoNCglwdWJsaWMg YWJzdHJhY3QgY2xhc3MgRXBoZW1lcmFsIDogTERCUm9vdCB7DQoJCS8vIGZvciBvYmplY3RzIHRo YXQgYXJlIG5vdCBwYXJ0IG9mIHRoZSBBU1QNCgl9DQoNCg0KDQoJcHVibGljIGludGVyZmFjZSBJ V2l0aExpbmVOVW0geyAgLy8gdG9kbyAtIHVzZSBvciByZW1vdmUgLSB0b2RvDQoJCS8vCXB1Ymxp YyANCgl9DQoNCg0KCXB1YmxpYyBpbnRlcmZhY2UgSUhhc1RhYmxlQWxpYXMgew0KCQkvLyBIYXMg YSB0YWJsZSBhbGlhcyBBU1Qgb2JqLiBNYXkgYmUgYSAuLi5NaXNzaW5nIHN1YnR5cGUgaW4gd2hp Y2gNCgkJLy8gaXQgaGFzIG5vIGFsaWFzIGdpdmVuIGJ5IHRoZSB1c2VyLCBidXQgYWxpYXMgQVNU IGlzIHRoZXJlLiBNb3JlDQoJCS8vIGFjY3VyYXRlbHkgYSBUYWJsZVNvdXJjZSBhbGlhcyBidXQg b2sNCgkJcHVibGljIGFic3RyYWN0IFRhYmxlQWxpYXMgdGEgeyBnZXQ7IHNldDsgfQ0KCX0NCg0K DQoJLy8gQmFzZSBjbGFzcyBmb3IgYWxsIExEQiBBU1Qgb2JqZWN0cw0KCXB1YmxpYyBhYnN0cmFj dCBjbGFzcyBMREJBU1RvYmogOiBMREJSb290IHsNCgkJLy8gVGhpcyBvbmUgaXMgYSBwcm9ibGVt LiBJZiBJIGRlY2xhcmUgdGhlICdwYXJlbnQnIHByb3BlcnR5DQoJCS8vIGFic3RyYWN0IEkgdGhl biBoYXZlIHRvIGltcGxlbWVudCBpdCBsaXRlcmFsbHkgaHVuZHJlZHMgb2YNCgkJLy8gdGltZXMg aW4gdGhlIGRlcml2ZWQgY2xhc3NlcywgYW5kIEkgcmVhbGx5IGRvbid0IHRoaW5rIGl0DQoJCS8v IHdvdWxkIGhlbHAgc28ganVzdCBzZXQgaXQgdG8gYSBkZWZhdWx0IHdoaWNoIGdldHMgb3Zlcndy aXR0ZW4gbGF0ZXIuDQoJCS8vIA0KCQkvLyBUaGUgcHJvYmxlbSBpcyB0aGF0IHRob3NlIG9iamVj dHMgd2VyZSBjcmVhdGVkIGJ5IHRoZQ0KCQkvLyBwYXJzZXIsIHdoaWNoIGNyZWF0ZXMgdGhlbSBi b3R0b20tdXAsIHdoaWNoIG1lYW5zIHlvdSBjYW4ndA0KCQkvLyBrbm93IHRoZSBwYXJlbnQgd2hl biB0aGV5IGFyZSBjcmVhdGVkLiBJdCBzaG91bGQgYmUNCgkJLy8gcG9zc2libGUgdG8gd29yayBh cm91bmQgdGhpcyBidXQgaXQgZG9lcyBtZWFuIHJld29ya2luZyB0aGUNCgkJLy8gcGFyc2VyIGZ1 bmRhbWVudGFsbHksIGFuZCBJJ20gbm90IGdvaW5nIHRvIGRvIHRoYXQNCgkJLy8gYXNzdW1laW5n IGl0J3MgZXZlbiBwb3NzaWJsZS4NCg0KCQkvLyB0b2RvIC0gcmVhZCB1cCBvbiBwcml2L3B1Yi9w cm9nIGFjY2Vzc29ycyBJIHJlYWxseSBkb24ndA0KCQkvLyBnZXQgdGhlc2UgYXQgYWxsDQoJCXB1 YmxpYyBMREJBU1RvYmogcGFyZW50IHsgZ2V0OyBwcml2YXRlIHNldDsgfQ0KCQkJCQkJPSBub1Bh cmVudDsNCgkJLy8gVW5pcXVlIElEIHBlciBvYmplY3QsIHVzZWZ1bCBmb3IgZGlzdGluZ3Vpc2hp bmcgdGhlbQ0KCQkvLyB3aXRob3V0IGdlbmVyYWwgZXF1YWxpdHkuDQoJCXJlYWRvbmx5IHB1Ymxp YyB1bG9uZyB1aWQgPSBuZXdVSUQoKTsNCg0KCQkvLyBwdWJsaWMgYWJzdHJhY3QgaW50IGxpbmVO dW0geyBnZXQ7IHNldDsgfQ0KDQoJCS8vIElzIHZhbGlkYXRlZCBpcyBhIGNoZWFwaXNoIGNoZWNr IHRvIGVuc3VyZSBldmVyeXRoaW5nIGdldHMNCgkJLy8gdmFsaWRhdGVkDQoJCS8vIGNhbiBkbyB0 aGlzIGFzIGF1dG8gcHJvcD8gdG9kbw0KCQlwcml2YXRlIGJvb2wgX3ZhbGlkYXRlZCA9IGZhbHNl Ow0KDQoJCXByb3RlY3RlZCBib29sIHZhbGlkYXRlZCB7DQoJCQlnZXQgPT4gX3ZhbGlkYXRlZDsN CgkJCXNldCB7DQoJCQkJLy8gaGFyZE11c3QoIXZhbGlkYXRlZCwgIi4uLiBhbHJlYWR5IHZhbGlk YXRlZC4uLiAiKTsgLSBubw0KCQkJCS8vIEl0J3MgaGFyZCB0byBhdm9pZCB2YWxpZGF0aW5nIGEg dGhpbmcgdHdpY2UsIHNvIGZvciBub3cgYWxsb3cgaXQNCgkJCQkvLyBMb29rIGludG8gaXQgbGF0 ZXIsIHJlYWxseSBzaG91bGRuJ3QgaGFwcGVuDQoJCQkJX3ZhbGlkYXRlZCA9IHRydWU7DQoJCQl9 DQoJCX0NCg0KCQlwdWJsaWMgTERCU3RydWN0c0NoaWxkcmVuIGtpZHMgeyBnZXQ7IHByaXZhdGUg c2V0OyB9ID0NCgkJCQkJbmV3IExEQlN0cnVjdHNDaGlsZHJlbihub1BhcmVudCk7IC8vIGp1c3Qg ZWFzaWVyDQoNCgkJcHVibGljIExEQkFTVG9iaigpIHsgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8v Ly8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8gdG9kbyBkZWFkPw0KCQkJ CQkJCSAgLy8gVlN0dWRpbyB0aGlua3MgdGhpcyBoYXMgemVybyByZWZlcmVuY2VzLCB3aGljaCBp cyB0cnVlIGV4cGxpY2l0bHksIGJ1dCBpdCdzIA0KCQkJCQkJCSAgLy8gY2FsbGVkIGltcGxpY2l0 bHkgb24gZXZlcnkgb2JqIGNyZWF0aW9uIC0gb3Igc2hvdWxkIGRvIHRvZG8tIGNoZWNrDQoJCQlp ZiAocmVjb3JkT2JqZWN0c0NyZWF0ZWQpIHsNCgkJCQlBbGxDcmVhdGVkSXRlbXMuQWRkKHRoaXMp Ow0KCQkJfQ0KCQl9DQoNCg0KCQlwdWJsaWMgdmlydHVhbCB2b2lkIHZhbGlkYXRlKCkgew0KCQkJ aWYgKHJlcG9ydEFsc29JZlZhbGlkYXRpb25PSykgew0KCQkJCWRlYnVnbXNnKCJ2YWxpZGF0aW5n Li4uIiArIGNsYXNzTmFtZQ0KCQkJCQkrICIgKCIgKyBhc05hbWVPcklkZW50Q29udGVudHMoKSAr ICIpIik7DQoJCQl9DQoJCQltaHBfbWhrKCk7DQoJCQlraWRzLnZhbGlkYXRlKCk7DQoJCQkvLyB2 YWxpZGF0ZWQgPSB0cnVlOyAtLSBObywgZ2V0IGVhY2ggc3ViY2xhc3MgdG8gc2V0DQoJCQkvLyB2 YWxpZGF0ZWQuIFRoYXQgZm9yY2VzIGFuIGV4cGxpY2l0IGNhbGwgdG8gYmFzZSgpIHdoaWNoDQoJ CQkvLyBpcyBtb3JlIGNvZGUgYnV0IG9rLg0KCQl9DQoNCg0KCQlwdWJsaWMgYm9vbCBpc1ZhbGlk YXRlZCB7IGdldCA9PiB2YWxpZGF0ZWQ7IH0gIC8vIHRvZG8ganVzdCA9PiB2YWxpZGF0ZWQ7DQoN Cg0KCQlwdWJsaWMgdmlydHVhbCBib29sIGlzVG9wTGV2ZWxJdGVtU2VxID0+IGZhbHNlOw0KDQoN CgkJcHVibGljIHZpcnR1YWwgdm9pZCBtaHBfbWhrKCkgeyAgLy8gZG9uJ3QgdGhpbmsgdGhpcyBu ZWVkIGJlIHZpcnR1YWwgLSB0b2RvPw0KCQkJCQkJCQkJCSAvLyA9IG11c3QgaGF2ZSBwYXJlbnQs IG11c3QgaGF2ZSBraWRzLiBUaGUga2lkcyBtYXkgYmUgdGhlDQoJCQkJCQkJCQkJIC8vIGVtcHR5 IHNldCBhbmQgdGhlIHBhcmVudCBtYXkgYmUgbm9QYXJlbnQgYnV0IHRoZXkgbXVzdA0KCQkJCQkJ CQkJCSAvLyBleGlzdC4NCgkJCQkJCQkJCQkgLy8gV2h5IG5vdCBqdXN0IGlubGluZSB0aGlzIGlu dG8gdmFsaWRhdGUoKT8NCgkJCQkJCQkJCQkgLy8gQmVjYXVzZSBhIGZldyBjbGFzc2VzIG5lZWQg YmVzcG9rZSB2YWxpZGF0aW9uLCBidXQgc3RpbGwgbXVzdCBjaGVjayB0aGlzLg0KCQkJaGFyZE11 c3RQYXJlbnRJc1ByZXNlbnQoKTsNCgkJCWtpZHMuZWFjaEtpZFBhcmVudE11c3RCZSh0aGlzKTsN CgkJfQ0KDQoNCgkJcHVibGljIHN0cmluZyBhc05hbWVPcklkZW50Q29udGVudHMoKSB7DQoJCQkv LyBmb3IgdmVyeSBjcnVkZSBkZWJ1Z2dpbmcgDQoJCQl2YXIgb3B0TmFtZSA9IHRoaXMgaXMgSWlz TmFtZWRJdGVtIG5pID8gbmkubmFtZS50b1Jhd1N0cigpIDogIiI7DQoJCQlvcHROYW1lID0gKG9w dE5hbWUgPT0gIiIgJiYgdGhpcyBpcyBQTVFJZGVudCkgPyB0aGlzLnRvUmF3U3RyKCkgOiAiIjsN Cg0KCQkJdmFyIG9wdE5hbWUyID0gb3B0TmFtZSArICIgICh1aWQ6IiArIHVpZC5Ub1N0cmluZygp ICsgIikgIg0KCQkJCSsgZ2V0Rmlyc3RGZXdDaGFyc09mKHRvUmF3U3RyKCkpOw0KCQkJcmV0dXJu IG9wdE5hbWUyOw0KCQl9DQoNCg0KCQlwdWJsaWMgdmlydHVhbCB2b2lkIGdldEFsbFVJRHMoVUlE c2V0IHVpZHMpIHsNCgkJCXVpZHMuQWRkKHRoaXMpOw0KCQkJa2lkcy5Gb3JFYWNoKG5hbWVkS2lk ID0+IG5hbWVkS2lkLmtpZC5nZXRBbGxVSURzKHVpZHMpKTsNCgkJfQ0KDQoNCgkJcHVibGljIGJv b2wgaXNTdHViUGFyZW50IHsgZ2V0ID0+ICh0aGlzIGlzIE5vUGFyZW50KSB8fCAodGhpcyBpcyBG YWtlUGFyZW50KTsgfQ0KDQoNCgkJcHVibGljIHZvaWQgdmFsaWRhdGVTcGVjaWZpY0l0ZW1zKHBh cmFtcyBMREJBU1RvYmpbXSBpdGVtcykgew0KCQkJQXJyYXkuRm9yRWFjaChpdGVtcywgaXRlbSA9 PiBpdGVtLnZhbGlkYXRlKCkpOw0KCQl9DQoNCg0KCQlwdWJsaWMgVD8gb3B0Q2xpbWJUbzxUPigp IHdoZXJlIFQgOiBMREJBU1RvYmogew0KCQkJdmFyIHJlc0l0ZW0gPSB0aGlzOw0KCQkJd2hpbGUg KCEocmVzSXRlbSBpcyBUKSkgew0KCQkJCWlmIChyZXNJdGVtLnBhcmVudC5pc1N0dWJQYXJlbnQp IHsNCgkJCQkJcmV0dXJuIG51bGw7DQoJCQkJfQ0KCQkJCXJlc0l0ZW0gPSByZXNJdGVtLnBhcmVu dDsNCgkJCX0NCg0KCQkJdmFyIHJlcyA9IHJlc0l0ZW0gYXMgVDsNCgkJCXJldHVybiByZXM7DQoJ CX0NCg0KDQoJCXB1YmxpYyBUIHJlcUNsaW1iVG88VD4oKSB3aGVyZSBUIDogTERCQVNUb2JqIHsN CgkJCXZhciBsb2MgPSBjbGFzc05hbWUgKyAiLnJlcUNsaW1iVG88VD4oKSI7DQoJCQl2YXIgcmVz ID0gb3B0Q2xpbWJUbzxUPigpOw0KCQkJaGFyZE11c3QyKCEocmVzIGlzIG51bGwpLCANCgkJCQkv LyBUaGFua3MgU08gPGh0dHBzOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzI1ODE2NDIv aG93LWRvLWktZ2V0LXRoZS10eXBlLW5hbWUtb2YtYS1nZW5lcmljLXR5cGUtYXJndW1lbnQ+DQoJ CQkJLy8gVG9kbyAtIHVzZSB0aGlzIGVsc2V3aGVyZSwgcG9zcyBFeHBlY3RFeGNlcHRpb24/IHRv ZG8NCgkJCQkoKSA9Pg0KCQkJCWxvYyANCgkJCQkrIG5sICsgIiwgY2xpbWJlZCB0byB0b3AsIGRp ZG4ndCBmaW5kIHR5cGUgIg0KCQkJCSsgdHlwZW9mKFQpLkZ1bGxOYW1lDQoJCQkJKyBubCArICJI aWVyYXJjaHkgaXM6ICINCgkJCQkrIG5sICsgZ2V0SXRlbVdpdGhQYXJlbnRzKHRoaXMpKTsNCgkJ CWlmIChyZXMgaXMgbnVsbCkgeyB0aHJvdyBuZXcgTk5RQygpOyB9DQoJCQlyZXR1cm4gcmVzOw0K CQl9DQoNCg0KCQlwdWJsaWMgdm9pZCBoYXJkTXVzdFBhcmVudElzUHJlc2VudCgpIHsNCg0KCQkJ aGFyZE11c3QyKCEocGFyZW50IGlzIG51bGwpLCANCgkJCQkoKSA9Pg0KCQkJCSAiTlVMTCBwYXJl bnQgZm9yIGl0ZW0gb2YgdHlwZVxuIg0KCQkJCSArICQie0dldFR5cGUoKX1cbi4iKTsNCg0KCQkJ aGFyZE11c3QyKCEodGhpcy5wYXJlbnQgaXMgTm9QYXJlbnQpLA0KCQkJCSgpID0+DQoJCQkJIlBh cmVudCBpcyBOb1BhcmVudCBvbiBvYmplY3Qgb2YgdHlwZVxuIg0KCQkJCSsgJCIne3RoaXMuY2xh c3NOYW1lfSciKTsNCgkJfQ0KDQoNCgkJcHVibGljIHZvaWQgaGFyZE11c3RQYXJlbnRJc0Fic2Vu dCgpIHsNCgkJCS8vIEZvciBjaGVja2luZyBjbG9uaW5nIC0gcGFyZW50IHNob3VsZCBiZSBOb1Bh cmVudCBpbW1lZGlhdGVseSANCgkJCS8vIGFmdGVyLCBiZWZvcmUgaXQncyBzZXQgYnkgcGFyZW50 LCBhbmQgbmV2ZXIgbnVsbA0KCQkJaGFyZE11c3QoIShwYXJlbnQgaXMgbnVsbCksDQoJCQkJICJO VUxMIHBhcmVudCBmb3IgaXRlbSBvZiB0eXBlXG4iDQoJCQkJICsgJCJ7R2V0VHlwZSgpfVxuLiIp Ow0KCQkJaGFyZE11c3QoKHRoaXMucGFyZW50IGlzIE5vUGFyZW50KSwNCgkJCQkiUGFyZW50IHNo b3VsZCBiZSBOb1BhcmVudCBvbiBvYmplY3Qgb2YgdHlwZVxuIg0KCQkJCSsgJCIne3RoaXMuY2xh c3NOYW1lfSciKTsNCgkJfQ0KDQoNCgkJcHVibGljIGJvb2wgaGFzUGFyZW50PFA+KCkgew0KCQkJ aGFyZE11c3QoISh0aGlzIGlzIE5vUGFyZW50KSwgIkl0ZW0gaXMgTm9QYXJlbnQiKTsNCgkJCXJl dHVybiB0aGlzLnBhcmVudCBpcyBQOw0KCQl9DQoNCg0KCQlwdWJsaWMgYm9vbCBoYXNBbmNlc3Rv cjxBPigpIHsNCgkJCWhhcmRNdXN0KCF0aGlzLmlzU3R1YlBhcmVudCwgIkl0ZW0gaXMgTm9QYXJl bnQiKTsNCg0KCQkJLy8gaG93IHRvIGRvIHdpdGggYSBzd2l0Y2ggZXhwcj8NCgkJCWlmICh0aGlz LnBhcmVudC5pc1N0dWJQYXJlbnQgLyogaXMgTm9QYXJlbnQgfHwgdGhpcy5wYXJlbnQgaXMgRmFr ZVBhcmVudCovICkgeyAvLyB0b2RvIGRvIGFzIHguaGFzRnVkZ2VkUGFyZW50KCkgLSB0b2RvDQoJ CQkJcmV0dXJuIGZhbHNlOw0KCQkJfSBlbHNlIGlmICh0aGlzLnBhcmVudCBpcyBBKSB7DQoJCQkJ cmV0dXJuIHRydWU7DQoJCQl9IGVsc2Ugew0KCQkJCXJldHVybiB0aGlzLnBhcmVudC5oYXNBbmNl c3RvcjxBPigpOw0KCQkJfQ0KCQl9DQoNCgkJcHVibGljIGJvb2wgbm90SGFzQW5jZXN0b3I8QT4o KSA9Pg0KCQkJIWhhc0FuY2VzdG9yPEE+KCk7DQoNCg0KCQlwdWJsaWMgdm9pZCBzZXRNeVBhcmVu dFRvKExEQkFTVG9iaiBwcm50KSB7DQoJCQkvLyBBbiBvYmplY3QgbWF5IG9ubHkgc2V0IGl0cyBw YXJlbnQgaWYgaXRzIGN1cnJlbnQgcGFyZW50IGlzDQoJCQkvLyB0aGUgZHVtbXkgJ25vUGFyZW50 Jywgd2hpY2ggYWxtb3N0IGV2ZXJ5IG9iamVjdCdzIHBhcmVudCBpcw0KCQkJLy8gc2V0IHRvIG9u IGNyZWF0aW9uIChzZWUgTERCQVNUb2JqIHBhcmVudCBwcm9wZXJ0eSBkZWYpLg0KDQoJCQkvLyBU aGUgdGVzdCBmb3IgbnVsbCBpcyBwZWN1bGlhciBnaXZlbiB0aGlzLiBCZWNhdXNlDQoJCQkvLyBu b1BhcmVudCBpcyBjcmVhdGVkIHN0YXRpY2FsbHksIHNldHRpbmcgdGhlIHBhcmVudCBvZg0KCQkJ Ly8gbm9QYXJlbnQgaXMgZGlmZmljdWx0LCBwZXJoYXBzIGltcG9zc2libGUsIHRvIGRvIHN0YXRp Y2FsbHkNCgkJCS8vIGFuZCByZWxpYWJseS5EZXNwaXRlIHRoZSBkZWNsYXJhdGlvbiAnI251bGxh YmxlIGVuYWJsZScsIGl0DQoJCQkvLyBnZXRzIGNyZWF0ZWQgd2l0aCBhIG51bGwgcGFycmVudCAo cXVpdGUgcmVhc29uYWJseSksIGhlbmNlDQoJCQkvLyB0aGlzIGNoZWNrLlRoZSBhY3R1YWwgc2V0 dGluZyBvZiB0aGUgcGFyZW50IGhhcyB0byBiZSBkb25lDQoJCQkvLyBhdCBydW50aW1lIGkuZS5h ZnRlciB0aGUgc3RhdGljIGNyZWF0aW9uIG9mICdub1BhcmVudCcuDQoNCgkJCWhhcmRNdXN0Migo dGhpcy5wYXJlbnQgaXMgTm9QYXJlbnQpIHx8ICh0aGlzLnBhcmVudCBpcyBudWxsKSwNCgkJCQko KSA9Pg0KCQkJCSJ0cmllZCB0byByZS1zZXQgcGFyZW50IG9uIG9iamVjdCBvZiB0eXBlOiAiDQoJ CQkJKyBubCArIHRoaXMuY2xhc3NOYW1lUQ0KCQkJCSsgbmwgKyAiT3JpZ2luYWwgcGFyZW50IHR5 cGUgaXM6ICINCgkJCQkrICh0aGlzPy5wYXJlbnQ/LmNsYXNzTmFtZVEgPT0gbnVsbCA/ICJudWxs IiA6IHRoaXMucGFyZW50LmNsYXNzTmFtZVEpDQoJCQkJKyBubCArICJhbmQgbmV3IHBhcmVudCB0 eXBlIGlzOiAiDQoJCQkJKyBwcm50LmNsYXNzTmFtZVENCgkJCQkrIG5sICsgIkl0ZW0gaGF2aW5n IHBhcmVudCBzZXQgb24gaXQgaXM6ICINCgkJCQkvLyBiZWNhdXNlIG9iamVjdCBtYXkgbm90IGJl IGZ1bGx5IGNvbnN0cnVjdGVkIHlldCwgY2hlY2sgaG93dmVyIFRPRE8gdGhpcyBpcyBhIG1ham9y IGhhY2sgYW5kIG11c3QgYmUgZml4ZWQgc29tZXRpbWUuDQovLwkJCQkrIG5sICsgKHRoaXMgaXMg bnVsbCA/ICIobnVsbCkiIDogdGhpcy50b1Jhd1N0cigpKSk7DQoJCQkJKyBubCArIHRoaXMudG9S YXdTdHIoKSApOw0KDQoJCQlwYXJlbnQgPSBwcm50Ow0KCQl9DQoNCg0KCQlwdWJsaWMgdm9pZCBm b3JjZU5ld1BhcmVudEZvclJvb3RPYmplY3QoKSB7DQoJCQkvLyBFdmVyeSBvYmplY3QgbXVzdCBo YXZlIHNvbWUgcGFyZW50LCBpbmNsdWRpbmcgdGhlDQoJCQkvLyByb290IG9iamVjdCBvZiB0aGUg cGFyc2UsIHdoaWNoIGlzIExEQml0ZW1zDQoJCQkvLyAoYSBzZXF1ZW5jZSBvZiBMREIgaXRlbXMp LCBzbyB0aGlzIGZvcmNlcyBvbmUuDQoJCQkvLyBJdCBpcyBvbmx5IGZvciB0aGF0IHB1cnBvc2Uh DQoJCQkvLyANCgkJCS8vIExEQml0ZW1zIG9iaiBleGlzdHMgZm9yIHN1YiBvYmpzIHN1Y2ggYXMg dGhlIHN0YXRlbWVudHMNCgkJCS8vIGluIGEgd2hpbGUgbG9vcCwgaW4gYSBwcm9jLCBpbiBhbiBp Zi4uLiBldGMuLCBmb3INCgkJCS8vIHdoaWNoIHRoZWlyIHBhcmVudCBpcyB0aGUgd2hpbGUvcHJv Yy9pZiBldGMuDQoJCQloYXJkTXVzdFBhcmVudElzQWJzZW50KCk7DQoJCQl0aGlzLnBhcmVudCA9 IGZha2VQYXJlbnQ7DQoJCX0NCg0KDQoJCS8vcHVibGljIHZvaWQgcmVzZXRNeVBhcmVudFRvKExE QkFTVG9iaiBwcm50KSB7ICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vIGRlc3Ry b3khISEhISEgdG9kbw0KCQkvLwlwYXJlbnQgPSBwcm50Ow0KCQkvL30NCg0KCQkvLy8vLy8vLy8v Ly8vLy8vLy8vLy8vLy8geHh4eHh4eHh4eHh4eCBkZWxldGUgLSB0b2RvDQoJCS8vcHJpdmF0ZSB2 b2lkIHNldFBhcmVudE9uS2lkKExEQkFTVG9iaiBraWQpID0+IC8vIHRvZG8gbmVlZGVkPw0KCQkv LwkJCQkJCQkJCQkJICAvLyBjaGVjayBwYXJlbnRlIGRvZXNuJ3QgZXhpc3QgLSB0b2RvDQoJCS8v CWtpZC5wYXJlbnQgPSB0aGlzOw0KDQoJCXB1YmxpYyB2aXJ0dWFsIHZvaWQgc2V0UGFyZW50T25L aWRzQW5kTWFrZUtpZHNEaWN0KCAgLy8gdG9kbyAtIGFuZCBhZGQgdG8ga2lkcyBkaWN0DQoJCQkJ CQkJCQkJCQkJCQkgLy8gdGhpcyBtaXhlcyB1cCBzZXR0aW5nIHBhcmVudCBhbmQgbWFraW5nIGNo aWxkIGRpY3QuIE5vdCBnb29kLiAtIHRvZG8NCgkJCQkJCXBhcmFtcyAoc3RyaW5nIGtpZE5hbWUs IExEQkFTVG9iaiBraWQpW10ga2lkc0luKSB7DQoJCQl2YXIgbG9jID0gY2xhc3NOYW1lUGx1cygi c2V0UGFyZW50T25LaWRzQW5kTWFrZUtpZHNEaWN0Iik7DQoNCgkJCXZhciBraWRzVG9BZGQgPSBu ZXcgTERCU3RydWN0c0NoaWxkcmVuKHRoaXMsIGtpZHNJbik7DQoJCQloYXJkTXVzdDIoa2lkcy5p c0VtcHR5LA0KCQkJCSgpID0+DQoJCQkJJCJzZXR0aW5nIGtpZHMgb24gcGFyZW50ICd7Y2xhc3NO YW1lfSciIA0KCQkJCSsgIndoZW4ga2lkcyBpcyBub3QgZW1wdHksICINCgkJCQkrICQia2lkcyBp cyAoe2tpZHMuQ291bnR9IGtpZHMpOiINCgkJCQkrIG5sICsga2lkcy50b0RlYnVnU3RyKCkNCgkJ CQkrIG5sICsgJCJUcnlpbmcgdG8gYWRkXG57a2lkc1RvQWRkLnRvRGVidWdTdHIoKX1cbiINCgkJ CQkrICQiaW4ge2NsYXNzTmFtZX0iKTsNCgkJCS8vIGlmIHRoZXJlIGlzIGFuIExEQlN0cnVjdHND aGlsZHJlbiBhbmQgYW5vdGhlciBjaGlsZCwNCgkJCS8vIHRoaXMgd2lsbCBibG93IHVwIC0gd2ls bCBuZWVkIHRvIGRvIGtpZHMuQWRkIG9yDQoJCQkvLyBzb21ldGhpbmcgLSBpbiBmYWN0LCBraWRz IG5lZWRzIHRvIGJlIGNyZWF0ZWQgaW4gb25lDQoJCQkvLyBnbywgd2hpY2ggaXMgd2hhdCBoYXBw ZW5zLg0KCQkJa2lkcyA9IGtpZHNUb0FkZDsgICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8v Ly8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vIHdoeSB0aGlzPyB0b2RvDQoJCQlBcnJheS5G b3JFYWNoKGtpZHNJbiwgeGtpZCA9PiBoYXJkTXVzdCghKHhraWQua2lkIGlzIG51bGwpLCBsb2Ms ICJudWxsIGtpZCIpKTsNCgkJCUFycmF5LkZvckVhY2goa2lkc0luLCB4a2lkID0+IHhraWQua2lk LnNldE15UGFyZW50VG8odGhpcykpOw0KCQl9DQoNCg0KCQlwdWJsaWMgdmlydHVhbCB2b2lkIHNl dFBhcmVudE9uS2lkc0FuZEFkZFRvS2lkc0RpY3QoDQoJCQkJCXBhcmFtcyAoc3RyaW5nIGtpZE5h bWUsIExEQkFTVG9iaiBraWQpW10ga2lkc0luKSB7DQoJCQl2YXIga2lkc1RvQWRkX2p1c3RGb3JF cnJSZXBvcnRpbmcgPSBuZXcgTERCU3RydWN0c0NoaWxkcmVuKHRoaXMsIGtpZHNJbik7DQoJCQlo YXJkTXVzdDIoIWtpZHMuaXNFbXB0eSwgLy8gbWF5IGRpc2FibGUgdGhpcyBsYXRlciANCgkJCQko KSA9Pg0KCQkJCSJhZGRpbmcgdG8ga2lkcyB3aGVuIGtpZHMgaXMgZW1wdHksICINCgkJCQkgKyAk ImtpZHMgaXNcbntraWRzLnRvRGVidWdTdHIoKX1cbiINCgkJCQkgKyAkIlRyeWluZyB0byBhZGRc bntraWRzVG9BZGRfanVzdEZvckVyclJlcG9ydGluZy50b0RlYnVnU3RyKCl9XG4iDQoJCQkJICsg JCJpbiB7Y2xhc3NOYW1lfSIpOw0KCQkJQXJyYXkuRm9yRWFjaChraWRzSW4sIHhraWQgPT4gew0K Ly8JCQkJc2V0UGFyZW50T25LaWQoeGtpZC5raWQpOw0KCQkJCXhraWQua2lkLnNldE15UGFyZW50 VG8odGhpcyk7DQoJCQkJa2lkcy5BZGQoeGtpZCk7DQoJCQl9KTsNCgkJfQ0KDQoNCgkJcHVibGlj IHZpcnR1YWwgSWRlbnRzVXNlZCBnZXRBbGxJRHMoKSB7DQoJCS8qIFRoaXMgaXMgb3ZlcnJpZGRl biBvbmx5IGluIFRlbXBsYXRlZEFnZywgYW5kIHRoYXQncyBvbmx5IHRvIA0KCQkJZGVsaWJlcmF0 ZWx5IGZhaWwuIFRoZXJlJ3Mgc29tZXRoaW5nIHdyb25nIHRoZXJlLCB0b2RvIC0gDQoJCQl1bi12 aXJ0dWFsaXNlIHRoaXMgYW5kIHJlbW92ZSB0aGUgb25lIG92ZXJyaWRlLiAtIHRvZG8NCgkJKi8N CgkJCXZhciBpdSA9IG5ldyBJZGVudHNVc2VkKCk7DQoJCQl0aGlzLl9nZXRBbGxJRHMoaXUpOw0K CQkJcmV0dXJuIGl1Ow0KCQl9DQoNCgkJcHVibGljIHZpcnR1YWwgdm9pZCBfZ2V0QWxsSURzKElk ZW50c1VzZWQgaXUpIHsNCgkJLy8gR2V0cyBhbGwgdGhlIGlkZW50aWZpZXJzIGV4cGxpY2l0bHkg dXNlZCAocmVhZCBvciB3cml0dGVuKSAgLS0tLS0gdG9kbyB1cGRhdGUgdGhpcw0KCQkvLyBhbnl3 aGVyZSBpbiB0aGUgQVNULiAgRG9lcyBub3QgZ2V0IGlkZW50cyB3aGljaCBhcmUNCgkJLy8gZGVj bGFyYXRpb25zIGllLiBwYXJhbWV0ZXJzLCBvciB2YXIvY29uc3QgZGVjbGFyYXRpb25zDQoJCS8v IHVubGVzcyB0aGVzZSBhcmUgY29tYmluZWQgd2l0aCBhbiBhc3NpZ25tZW50Lg0KCQkvLw0KCQkv LyBJbXBsaWVkIGlkZW50cyBzdWNoIGFzIHRob3NlIGZyb20gdGJsLiogYXJlIGltcGxpY2l0IGFu ZCBpZ25vcmVkLg0KCQkvLw0KCQkvLyBSb290IGNhbGxlciBzdXBwbGllcyBuZXcsIGVtcHR5IGl1 DQoJCS8vIG5lZWQgdXNhZ2UgaGVyZSAtIHRvZG8gZG9jcy8vDQoJCQlraWRzLl9nZXRBbGxJRHMo aXUpOw0KCQl9DQoNCgkJcHVibGljIGFic3RyYWN0IGJvb2wgY2FuR2V0QWxsSWRlbnRzVXNlZCB7 DQoJCS8vIAlUaGlzIHNlZW1zIHRvIGJlIHRydWUgb24gbW9zdCBjbGFzc2VzIHNvIEkgY291bGQg c2V0IHRydWUgDQoJCS8vIGFzIGEgZGVmYXVsdCBoZXJlIGFuZCBvdmVycmlkZSBpdCB3aGVyZSBp dCdzIG5vdCB3YW50ZWQsIHNhdmluZyANCgkJLy8gYSBjaHVuayBvZiBjb2RlLCBidXQgSSdkIHJh dGhlciBtYWtlIGl0IGV4cGxpY2l0IHRvIGZvcmNlIG1lIHRvIGNvbnNpZGVyIGVhY2ggY2FzZS4g QSBiaXQgbW9yZSBDJlAgZm9yIGxlc3MgY2hhbmNlIG9mIGJ1Z3MuDQoJCQlnZXQ7DQoJCX0NCg0K DQoJCS8vIFByb2R1Y2VzIGEgc3RyaW5nIHRoYXQgc2hvdWxkIGJlIGlkZW50aWNhbCB0byAoZXhj ZXB0aW5nDQoJCS8vIHdoaXRlc3BhY2VzKSB0aGUgaW5wdXQgaWUuIGVtaXQgTERCIGNvZGUgbm90 IHZhbGlkIFNRTA0KCQkvLw0KCQkvLyBUb1N0cmluZyB3YXMgY2F1c2luZyB0b28gbWFueSB3ZWly ZCBwcm9ibGVtcyAoZHVlIHRvIG15DQoJCS8vIGluZXhwZXJpZW5jZSB3aXRoIGMjKSBzbyBqdXN0 IHVzZWQgdG9SYXdTdHIoKQ0KCQlwdWJsaWMgYWJzdHJhY3Qgc3RyaW5nIHRvUmF3U3RyKCk7DQoN CgkJcHVibGljIG92ZXJyaWRlIHN0cmluZyB0b0RlYnVnU3RyKCkgPT4gdG9SYXdTdHIoKTsNCg0K CX0gLy8gZW5kIExEQkFTVG9iag0KDQoNCg0KCXB1YmxpYyBpbnRlcmZhY2UgSWhhbmRsZVByZWZp eGVzPFQ+DQoJCQkJCQl3aGVyZSBUIDogTERCUm9vdCB7DQoNCgkJcHVibGljIGJvb2wgaXNQcmVm aXhlZCB7IGdldDsgfQ0KDQoJCXB1YmxpYyBib29sIGlzRXhjZXNzUHJlZml4ZWQgeyBnZXQ7IH0N Cg0KCQkvLyBUaGUgVCBpbiBhZGRQcmVmaXgvcmVQcmVmaXgvd2l0aG91dFByZWZpeCBpcyBiZWNh dXNlIHdlIG1heSBiZSANCgkJLy8gcmV0dXJuaW5nIGVnLiBhIGxpc3Qgb2YgaXRlbXMgd2l0aCBw cmVmaXhlcyANCgkJLy8gdGh1cyBtb2RpZmllZCwgbm90IGEgc2luZ2xlIFBNUUlkZW50DQoNCgkJ cHVibGljIFQgYWRkUHJlZml4KFBNUUlkZW50IHBmeCk7DQoNCgkJcHVibGljIFQgcmVQcmVmaXgo UE1RSWRlbnQgbmV3cGZ4KTsNCg0KLy8JCXB1YmxpYyBUIHN0cmlwUHJlZml4KFBNUUlkZW50IGlk KTsNCgl9DQoJLy8gdG9kbyAtIG1vdmUgdGhpcw0KDQoNCg0KDQoNCglwdWJsaWMgYWJzdHJhY3Qg Y2xhc3MgTERCUm9vdCB7DQoJCS8vIFJvb3Qgb2YgZXZlcnl0aGluZyBMREItaXNoDQoNCgkJcHVi bGljIGJvb2wgRXF1YWxzKFtBbGxvd051bGxdIExEQlJvb3Qgb3RoZXIpIHsNCgkJCXRocm93IG5l dyBMREJTaG91bGROb3RCZUltcGxlbWVudGVkRXhjZXB0aW9uKA0KCQkJCQkJCQkJImNhbGxlZCBF cXVhbHMgb24gTERCUm9vdCIpOw0KCQl9DQoNCgkJcHVibGljIG92ZXJyaWRlDQoJCQlib29sIEVx dWFscyhbQWxsb3dOdWxsXSBPYmplY3Qgb3RoZXIpIHsNCgkJCXRocm93IG5ldyBMREJTaG91bGRO b3RCZUltcGxlbWVudGVkRXhjZXB0aW9uKA0KCQkJCQkJCQkJImNhbGxlZCBFcXVhbHMgaW4gT2Jq ZWN0Iik7DQoJCX0NCg0KCQlwdWJsaWMgb3ZlcnJpZGUgaW50IEdldEhhc2hDb2RlKCkgew0KCQkJ dGhyb3cgbmV3IExEQlNob3VsZE5vdEJlSW1wbGVtZW50ZWRFeGNlcHRpb24oDQoJCQkJCQkJCQki Y2FsbGVkIEdldEhhc2hDb2RlIGluIExEQlJvb3QiKTsNCgkJfQ0KDQoJCXB1YmxpYyBzdGF0aWMg Ym9vbCBvcGVyYXRvciA9PShMREJSb290IGxocywNCgkJCQkJCQkJCSAgIExEQlJvb3QgcmhzKSB7 DQoJCQl0aHJvdyBuZXcgTERCU2hvdWxkTm90QmVJbXBsZW1lbnRlZEV4Y2VwdGlvbigNCgkJCQkJ CQkJCSJjYWxsZWQgPT0gaW4gTERCUm9vdCIpOw0KCQl9DQoNCgkJcHVibGljIHN0YXRpYyBib29s IG9wZXJhdG9yICE9KExEQlJvb3QgbGhzLA0KCQkJCQkJCQkJICAgTERCUm9vdCByaHMpIHsNCgkJ CXRocm93IG5ldyBMREJTaG91bGROb3RCZUltcGxlbWVudGVkRXhjZXB0aW9uKA0KCQkJCQkJCQkJ ImNhbGxlZCAhPSBpbiBMREJSb290Iik7DQoJCX0NCg0KDQoJCXB1YmxpYyB2aXJ0dWFsIHN0cmlu ZyBjbGFzc05hbWUgew0KCQkJLy8gdG9kbyAtIHRoaXMgbmVlZHMgY2hlY2tpbmcgaXQgd29ya3Mg YXMgSSB3YW50DQoJCQkvLyBhbHNvIHJlbmFtZSB0byBsZGJjbGFzc25hbWUgLS0gdG9kbw0KCQkJ Z2V0ID0+IHRoaXMuR2V0VHlwZSgpLkZ1bGxOYW1lID8/ICIodW5rbm93bikiOw0KCQl9DQoNCg0K CQlwdWJsaWMgdmlydHVhbCBzdHJpbmcgY2xhc3NOYW1lUSA9Pg0KCQkJIiciICsgY2xhc3NOYW1l ICsgIiciOw0KDQoNCgkJcHVibGljIHZpcnR1YWwgc3RyaW5nIGNsYXNzTmFtZVBsdXMoc3RyaW5n IHBsdXMpID0+DQoJCQljbGFzc05hbWUgKyAiLiIgKyBwbHVzOw0KDQoJCXB1YmxpYyBvdmVycmlk ZSBzdHJpbmcgVG9TdHJpbmcoKSB7DQoJCQkvLyBUaGlzIGltcGxpY2l0IHRvLXN0cmluZyBjb252 ZXJzaW9uIGNyYXAgY29zdCBtZSBhIGZldyBob3Vycywgc28gYXQgbGVhc3QNCgkJCS8vIGRvIHRo aXMgJiBibG93IHVwIGF0IHJ1bnRpbWUuIFdvdWxkIHByZWZlciBjb21waWxlIHRpbWUgYnV0IGl0 IHNlZW1zDQoJCQkvLyBub3QgcG9zc2libGUuICBUaGlzIHR1cm5zIG91dCB0byBoYXZlIGJlZW4g YSBnb29kIGlkZWEsDQoJCQkvLyBzYXZlZCBtZSBxdWl0ZSBhIGJpdCBtb3JlIGRlYnVnZ2luZyEN CgkJCS8vIDxodHRwczovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy8xNTM0NTUxNy9pcy1p dC1wb3NzaWJsZS10by1kaXNhYmxlLWltcGxpY2l0LXRvc3RyaW5nLWNhbGw+DQoJCQkvLyBXaWxs IHRyeSA8aHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvNTQzNTQzNDIvaG93LXRv LWdldC1hbi1lcnJvci1zaG93bi13aGVuLXVzaW5nLW5vbi1zdHJpbmdzLWFzLXN0cmluZ3MtaW5z dGVhZC1vZi1hbi1hdXRvbS81NDM1NTExNSM1NDM1NTExNSkNCgkJCXZhciBtc2cgPSAiTERCUm9v dC5Ub1N0cmluZygpIjsNCgkJCXRocm93IG5ldyBMREJUb1N0cmluZ0ltcGxpY3RDb252ZXJzaW9u RXhjZXB0aW9uKG1zZyk7DQoJCX0NCg0KCQlwdWJsaWMgYWJzdHJhY3Qgc3RyaW5nIHRvRGVidWdT dHIoKTsNCgl9DQoNCg0KDQoJcHVibGljIGFic3RyYWN0IGNsYXNzIEVwaGVtZXJhbCA6IExEQlJv b3Qgew0KCQkvLyBmb3Igb2JqZWN0cyB0aGF0IGFyZSBub3QgcGFydCBvZiB0aGUgQVNUDQoJfQ0K DQoNCg0KCXB1YmxpYyBpbnRlcmZhY2UgSVdpdGhMaW5lTlVtIHsgIC8vIHRvZG8gLSB1c2Ugb3Ig cmVtb3ZlIC0gdG9kbw0KCQkvLwlwdWJsaWMgDQoJfQ0KDQoNCglwdWJsaWMgaW50ZXJmYWNlIElI YXNUYWJsZUFsaWFzIHsNCgkJLy8gSGFzIGEgdGFibGUgYWxpYXMgQVNUIG9iai4gTWF5IGJlIGEg Li4uTWlzc2luZyBzdWJ0eXBlIGluIHdoaWNoDQoJCS8vIGl0IGhhcyBubyBhbGlhcyBnaXZlbiBi eSB0aGUgdXNlciwgYnV0IGFsaWFzIEFTVCBpcyB0aGVyZS4gTW9yZQ0KCQkvLyBhY2N1cmF0ZWx5 IGEgVGFibGVTb3VyY2UgYWxpYXMgYnV0IG9rDQoJCXB1YmxpYyBhYnN0cmFjdCBUYWJsZUFsaWFz IHRhIHsgZ2V0OyBzZXQ7IH0NCgl9DQoNCg0KCS8vIEJhc2UgY2xhc3MgZm9yIGFsbCBMREIgQVNU IG9iamVjdHMNCglwdWJsaWMgYWJzdHJhY3QgY2xhc3MgTERCQVNUb2JqIDogTERCUm9vdCB7DQoJ CS8vIFRoaXMgb25lIGlzIGEgcHJvYmxlbS4gSWYgSSBkZWNsYXJlIHRoZSAncGFyZW50JyBwcm9w ZXJ0eQ0KCQkvLyBhYnN0cmFjdCBJIHRoZW4gaGF2ZSB0byBpbXBsZW1lbnQgaXQgbGl0ZXJhbGx5 IGh1bmRyZWRzIG9mDQoJCS8vIHRpbWVzIGluIHRoZSBkZXJpdmVkIGNsYXNzZXMsIGFuZCBJIHJl YWxseSBkb24ndCB0aGluayBpdA0KCQkvLyB3b3VsZCBoZWxwIHNvIGp1c3Qgc2V0IGl0IHRvIGEg ZGVmYXVsdCB3aGljaCBnZXRzIG92ZXJ3cml0dGVuIGxhdGVyLg0KCQkvLyANCgkJLy8gVGhlIHBy b2JsZW0gaXMgdGhhdCB0aG9zZSBvYmplY3RzIHdlcmUgY3JlYXRlZCBieSB0aGUNCgkJLy8gcGFy c2VyLCB3aGljaCBjcmVhdGVzIHRoZW0gYm90dG9tLXVwLCB3aGljaCBtZWFucyB5b3UgY2FuJ3QN CgkJLy8ga25vdyB0aGUgcGFyZW50IHdoZW4gdGhleSBhcmUgY3JlYXRlZC4gSXQgc2hvdWxkIGJl DQoJCS8vIHBvc3NpYmxlIHRvIHdvcmsgYXJvdW5kIHRoaXMgYnV0IGl0IGRvZXMgbWVhbiByZXdv cmtpbmcgdGhlDQoJCS8vIHBhcnNlciBmdW5kYW1lbnRhbGx5LCBhbmQgSSdtIG5vdCBnb2luZyB0 byBkbyB0aGF0DQoJCS8vIGFzc3VtZWluZyBpdCdzIGV2ZW4gcG9zc2libGUuDQoNCgkJLy8gdG9k byAtIHJlYWQgdXAgb24gcHJpdi9wdWIvcHJvZyBhY2Nlc3NvcnMgSSByZWFsbHkgZG9uJ3QNCgkJ Ly8gZ2V0IHRoZXNlIGF0IGFsbA0KCQlwdWJsaWMgTERCQVNUb2JqIHBhcmVudCB7IGdldDsgcHJp dmF0ZSBzZXQ7IH0NCgkJCQkJCT0gbm9QYXJlbnQ7DQoJCS8vIFVuaXF1ZSBJRCBwZXIgb2JqZWN0 LCB1c2VmdWwgZm9yIGRpc3Rpbmd1aXNoaW5nIHRoZW0NCgkJLy8gd2l0aG91dCBnZW5lcmFsIGVx dWFsaXR5Lg0KCQlyZWFkb25seSBwdWJsaWMgdWxvbmcgdWlkID0gbmV3VUlEKCk7DQoNCgkJLy8g cHVibGljIGFic3RyYWN0IGludCBsaW5lTnVtIHsgZ2V0OyBzZXQ7IH0NCg0KCQkvLyBJcyB2YWxp ZGF0ZWQgaXMgYSBjaGVhcGlzaCBjaGVjayB0byBlbnN1cmUgZXZlcnl0aGluZyBnZXRzDQoJCS8v IHZhbGlkYXRlZA0KCQkvLyBjYW4gZG8gdGhpcyBhcyBhdXRvIHByb3A/IHRvZG8NCgkJcHJpdmF0 ZSBib29sIF92YWxpZGF0ZWQgPSBmYWxzZTsNCg0KCQlwcm90ZWN0ZWQgYm9vbCB2YWxpZGF0ZWQg ew0KCQkJZ2V0ID0+IF92YWxpZGF0ZWQ7DQoJCQlzZXQgew0KCQkJCS8vIGhhcmRNdXN0KCF2YWxp ZGF0ZWQsICIuLi4gYWxyZWFkeSB2YWxpZGF0ZWQuLi4gIik7IC0gbm8NCgkJCQkvLyBJdCdzIGhh cmQgdG8gYXZvaWQgdmFsaWRhdGluZyBhIHRoaW5nIHR3aWNlLCBzbyBmb3Igbm93IGFsbG93IGl0 DQoJCQkJLy8gTG9vayBpbnRvIGl0IGxhdGVyLCByZWFsbHkgc2hvdWxkbid0IGhhcHBlbg0KCQkJ CV92YWxpZGF0ZWQgPSB0cnVlOw0KCQkJfQ0KCQl9DQoNCgkJcHVibGljIExEQlN0cnVjdHNDaGls ZHJlbiBraWRzIHsgZ2V0OyBwcml2YXRlIHNldDsgfSA9DQoJCQkJCW5ldyBMREJTdHJ1Y3RzQ2hp bGRyZW4obm9QYXJlbnQpOyAvLyBqdXN0IGVhc2llcg0KDQoJCXB1YmxpYyBMREJBU1RvYmooKSB7 ICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8v Ly8vLy8vLy8vIHRvZG8gZGVhZD8NCgkJCQkJCQkgIC8vIFZTdHVkaW8gdGhpbmtzIHRoaXMgaGFz IHplcm8gcmVmZXJlbmNlcywgd2hpY2ggaXMgdHJ1ZSBleHBsaWNpdGx5LCBidXQgaXQncyANCgkJ CQkJCQkgIC8vIGNhbGxlZCBpbXBsaWNpdGx5IG9uIGV2ZXJ5IG9iaiBjcmVhdGlvbiAtIG9yIHNo b3VsZCBkbyB0b2RvLSBjaGVjaw0KCQkJaWYgKHJlY29yZE9iamVjdHNDcmVhdGVkKSB7DQoJCQkJ QWxsQ3JlYXRlZEl0ZW1zLkFkZCh0aGlzKTsNCgkJCX0NCgkJfQ0KDQoNCgkJcHVibGljIHZpcnR1 YWwgdm9pZCB2YWxpZGF0ZSgpIHsNCgkJCWlmIChyZXBvcnRBbHNvSWZWYWxpZGF0aW9uT0spIHsN CgkJCQlkZWJ1Z21zZygidmFsaWRhdGluZy4uLiIgKyBjbGFzc05hbWUNCgkJCQkJKyAiICgiICsg YXNOYW1lT3JJZGVudENvbnRlbnRzKCkgKyAiKSIpOw0KCQkJfQ0KCQkJbWhwX21oaygpOw0KCQkJ a2lkcy52YWxpZGF0ZSgpOw0KCQkJLy8gdmFsaWRhdGVkID0gdHJ1ZTsgLS0gTm8sIGdldCBlYWNo IHN1YmNsYXNzIHRvIHNldA0KCQkJLy8gdmFsaWRhdGVkLiBUaGF0IGZvcmNlcyBhbiBleHBsaWNp dCBjYWxsIHRvIGJhc2UoKSB3aGljaA0KCQkJLy8gaXMgbW9yZSBjb2RlIGJ1dCBvay4NCgkJfQ0K DQoNCgkJcHVibGljIGJvb2wgaXNWYWxpZGF0ZWQgeyBnZXQgPT4gdmFsaWRhdGVkOyB9ICAvLyB0 b2RvIGp1c3QgPT4gdmFsaWRhdGVkOw0KDQoNCgkJcHVibGljIHZpcnR1YWwgYm9vbCBpc1RvcExl dmVsSXRlbVNlcSA9PiBmYWxzZTsNCg0KDQoJCXB1YmxpYyB2aXJ0dWFsIHZvaWQgbWhwX21oaygp IHsgIC8vIGRvbid0IHRoaW5rIHRoaXMgbmVlZCBiZSB2aXJ0dWFsIC0gdG9kbz8NCgkJCQkJCQkJ CQkgLy8gPSBtdXN0IGhhdmUgcGFyZW50LCBtdXN0IGhhdmUga2lkcy4gVGhlIGtpZHMgbWF5IGJl IHRoZQ0KCQkJCQkJCQkJCSAvLyBlbXB0eSBzZXQgYW5kIHRoZSBwYXJlbnQgbWF5IGJlIG5vUGFy ZW50IGJ1dCB0aGV5IG11c3QNCgkJCQkJCQkJCQkgLy8gZXhpc3QuDQoJCQkJCQkJCQkJIC8vIFdo eSBub3QganVzdCBpbmxpbmUgdGhpcyBpbnRvIHZhbGlkYXRlKCk/DQoJCQkJCQkJCQkJIC8vIEJl Y2F1c2UgYSBmZXcgY2xhc3NlcyBuZWVkIGJlc3Bva2UgdmFsaWRhdGlvbiwgYnV0IHN0aWxsIG11 c3QgY2hlY2sgdGhpcy4NCgkJCWhhcmRNdXN0UGFyZW50SXNQcmVzZW50KCk7DQoJCQlraWRzLmVh Y2hLaWRQYXJlbnRNdXN0QmUodGhpcyk7DQoJCX0NCg0KDQoJCXB1YmxpYyBzdHJpbmcgYXNOYW1l T3JJZGVudENvbnRlbnRzKCkgew0KCQkJLy8gZm9yIHZlcnkgY3J1ZGUgZGVidWdnaW5nIA0KCQkJ dmFyIG9wdE5hbWUgPSB0aGlzIGlzIElpc05hbWVkSXRlbSBuaSA/IG5pLm5hbWUudG9SYXdTdHIo KSA6ICIiOw0KCQkJb3B0TmFtZSA9IChvcHROYW1lID09ICIiICYmIHRoaXMgaXMgUE1RSWRlbnQp ID8gdGhpcy50b1Jhd1N0cigpIDogIiI7DQoNCgkJCXZhciBvcHROYW1lMiA9IG9wdE5hbWUgKyAi ICAodWlkOiIgKyB1aWQuVG9TdHJpbmcoKSArICIpICINCgkJCQkrIGdldEZpcnN0RmV3Q2hhcnNP Zih0b1Jhd1N0cigpKTsNCgkJCXJldHVybiBvcHROYW1lMjsNCgkJfQ0KDQoNCgkJcHVibGljIHZp cnR1YWwgdm9pZCBnZXRBbGxVSURzKFVJRHNldCB1aWRzKSB7DQoJCQl1aWRzLkFkZCh0aGlzKTsN CgkJCWtpZHMuRm9yRWFjaChuYW1lZEtpZCA9PiBuYW1lZEtpZC5raWQuZ2V0QWxsVUlEcyh1aWRz KSk7DQoJCX0NCg0KDQoJCXB1YmxpYyBib29sIGlzU3R1YlBhcmVudCB7IGdldCA9PiAodGhpcyBp cyBOb1BhcmVudCkgfHwgKHRoaXMgaXMgRmFrZVBhcmVudCk7IH0NCg0KDQoJCXB1YmxpYyB2b2lk IHZhbGlkYXRlU3BlY2lmaWNJdGVtcyhwYXJhbXMgTERCQVNUb2JqW10gaXRlbXMpIHsNCgkJCUFy cmF5LkZvckVhY2goaXRlbXMsIGl0ZW0gPT4gaXRlbS52YWxpZGF0ZSgpKTsNCgkJfQ0KDQoNCgkJ cHVibGljIFQ/IG9wdENsaW1iVG88VD4oKSB3aGVyZSBUIDogTERCQVNUb2JqIHsNCgkJCXZhciBy ZXNJdGVtID0gdGhpczsNCgkJCXdoaWxlICghKHJlc0l0ZW0gaXMgVCkpIHsNCgkJCQlpZiAocmVz SXRlbS5wYXJlbnQuaXNTdHViUGFyZW50KSB7DQoJCQkJCXJldHVybiBudWxsOw0KCQkJCX0NCgkJ CQlyZXNJdGVtID0gcmVzSXRlbS5wYXJlbnQ7DQoJCQl9DQoNCgkJCXZhciByZXMgPSByZXNJdGVt IGFzIFQ7DQoJCQlyZXR1cm4gcmVzOw0KCQl9DQoNCg0KCQlwdWJsaWMgVCByZXFDbGltYlRvPFQ+ KCkgd2hlcmUgVCA6IExEQkFTVG9iaiB7DQoJCQl2YXIgbG9jID0gY2xhc3NOYW1lICsgIi5yZXFD bGltYlRvPFQ+KCkiOw0KCQkJdmFyIHJlcyA9IG9wdENsaW1iVG88VD4oKTsNCgkJCWhhcmRNdXN0 MighKHJlcyBpcyBudWxsKSwgDQoJCQkJLy8gVGhhbmtzIFNPIDxodHRwczovL3N0YWNrb3ZlcmZs b3cuY29tL3F1ZXN0aW9ucy8yNTgxNjQyL2hvdy1kby1pLWdldC10aGUtdHlwZS1uYW1lLW9mLWEt Z2VuZXJpYy10eXBlLWFyZ3VtZW50Pg0KCQkJCS8vIFRvZG8gLSB1c2UgdGhpcyBlbHNld2hlcmUs IHBvc3MgRXhwZWN0RXhjZXB0aW9uPyB0b2RvDQoJCQkJKCkgPT4NCgkJCQlsb2MgDQoJCQkJKyBu bCArICIsIGNsaW1iZWQgdG8gdG9wLCBkaWRuJ3QgZmluZCB0eXBlICINCgkJCQkrIHR5cGVvZihU KS5GdWxsTmFtZQ0KCQkJCSsgbmwgKyAiSGllcmFyY2h5IGlzOiAiDQoJCQkJKyBubCArIGdldEl0 ZW1XaXRoUGFyZW50cyh0aGlzKSk7DQoJCQlpZiAocmVzIGlzIG51bGwpIHsgdGhyb3cgbmV3IE5O UUMoKTsgfQ0KCQkJcmV0dXJuIHJlczsNCgkJfQ0KDQoNCgkJcHVibGljIHZvaWQgaGFyZE11c3RQ YXJlbnRJc1ByZXNlbnQoKSB7DQoNCgkJCWhhcmRNdXN0MighKHBhcmVudCBpcyBudWxsKSwgDQoJ CQkJKCkgPT4NCgkJCQkgIk5VTEwgcGFyZW50IGZvciBpdGVtIG9mIHR5cGVcbiINCgkJCQkgKyAk IntHZXRUeXBlKCl9XG4uIik7DQoNCgkJCWhhcmRNdXN0MighKHRoaXMucGFyZW50IGlzIE5vUGFy ZW50KSwNCgkJCQkoKSA9Pg0KCQkJCSJQYXJlbnQgaXMgTm9QYXJlbnQgb24gb2JqZWN0IG9mIHR5 cGVcbiINCgkJCQkrICQiJ3t0aGlzLmNsYXNzTmFtZX0nIik7DQoJCX0NCg0KDQoJCXB1YmxpYyB2 b2lkIGhhcmRNdXN0UGFyZW50SXNBYnNlbnQoKSB7DQoJCQkvLyBGb3IgY2hlY2tpbmcgY2xvbmlu ZyAtIHBhcmVudCBzaG91bGQgYmUgTm9QYXJlbnQgaW1tZWRpYXRlbHkgDQoJCQkvLyBhZnRlciwg YmVmb3JlIGl0J3Mgc2V0IGJ5IHBhcmVudCwgYW5kIG5ldmVyIG51bGwNCgkJCWhhcmRNdXN0KCEo cGFyZW50IGlzIG51bGwpLA0KCQkJCSAiTlVMTCBwYXJlbnQgZm9yIGl0ZW0gb2YgdHlwZVxuIg0K CQkJCSArICQie0dldFR5cGUoKX1cbi4iKTsNCgkJCWhhcmRNdXN0KCh0aGlzLnBhcmVudCBpcyBO b1BhcmVudCksDQoJCQkJIlBhcmVudCBzaG91bGQgYmUgTm9QYXJlbnQgb24gb2JqZWN0IG9mIHR5 cGVcbiINCgkJCQkrICQiJ3t0aGlzLmNsYXNzTmFtZX0nIik7DQoJCX0NCg0KDQoJCXB1YmxpYyBi b29sIGhhc1BhcmVudDxQPigpIHsNCgkJCWhhcmRNdXN0KCEodGhpcyBpcyBOb1BhcmVudCksICJJ dGVtIGlzIE5vUGFyZW50Iik7DQoJCQlyZXR1cm4gdGhpcy5wYXJlbnQgaXMgUDsNCgkJfQ0KDQoN CgkJcHVibGljIGJvb2wgaGFzQW5jZXN0b3I8QT4oKSB7DQoJCQloYXJkTXVzdCghdGhpcy5pc1N0 dWJQYXJlbnQsICJJdGVtIGlzIE5vUGFyZW50Iik7DQoNCgkJCS8vIGhvdyB0byBkbyB3aXRoIGEg c3dpdGNoIGV4cHI/DQoJCQlpZiAodGhpcy5wYXJlbnQuaXNTdHViUGFyZW50IC8qIGlzIE5vUGFy ZW50IHx8IHRoaXMucGFyZW50IGlzIEZha2VQYXJlbnQqLyApIHsgLy8gdG9kbyBkbyBhcyB4Lmhh c0Z1ZGdlZFBhcmVudCgpIC0gdG9kbw0KCQkJCXJldHVybiBmYWxzZTsNCgkJCX0gZWxzZSBpZiAo dGhpcy5wYXJlbnQgaXMgQSkgew0KCQkJCXJldHVybiB0cnVlOw0KCQkJfSBlbHNlIHsNCgkJCQly ZXR1cm4gdGhpcy5wYXJlbnQuaGFzQW5jZXN0b3I8QT4oKTsNCgkJCX0NCgkJfQ0KDQoJCXB1Ymxp YyBib29sIG5vdEhhc0FuY2VzdG9yPEE+KCkgPT4NCgkJCSFoYXNBbmNlc3RvcjxBPigpOw0KDQoN CgkJcHVibGljIHZvaWQgc2V0TXlQYXJlbnRUbyhMREJBU1RvYmogcHJudCkgew0KCQkJLy8gQW4g b2JqZWN0IG1heSBvbmx5IHNldCBpdHMgcGFyZW50IGlmIGl0cyBjdXJyZW50IHBhcmVudCBpcw0K CQkJLy8gdGhlIGR1bW15ICdub1BhcmVudCcsIHdoaWNoIGFsbW9zdCBldmVyeSBvYmplY3QncyBw YXJlbnQgaXMNCgkJCS8vIHNldCB0byBvbiBjcmVhdGlvbiAoc2VlIExEQkFTVG9iaiBwYXJlbnQg cHJvcGVydHkgZGVmKS4NCg0KCQkJLy8gVGhlIHRlc3QgZm9yIG51bGwgaXMgcGVjdWxpYXIgZ2l2 ZW4gdGhpcy4gQmVjYXVzZQ0KCQkJLy8gbm9QYXJlbnQgaXMgY3JlYXRlZCBzdGF0aWNhbGx5LCBz ZXR0aW5nIHRoZSBwYXJlbnQgb2YNCgkJCS8vIG5vUGFyZW50IGlzIGRpZmZpY3VsdCwgcGVyaGFw cyBpbXBvc3NpYmxlLCB0byBkbyBzdGF0aWNhbGx5DQoJCQkvLyBhbmQgcmVsaWFibHkuRGVzcGl0 ZSB0aGUgZGVjbGFyYXRpb24gJyNudWxsYWJsZSBlbmFibGUnLCBpdA0KCQkJLy8gZ2V0cyBjcmVh dGVkIHdpdGggYSBudWxsIHBhcnJlbnQgKHF1aXRlIHJlYXNvbmFibHkpLCBoZW5jZQ0KCQkJLy8g dGhpcyBjaGVjay5UaGUgYWN0dWFsIHNldHRpbmcgb2YgdGhlIHBhcmVudCBoYXMgdG8gYmUgZG9u ZQ0KCQkJLy8gYXQgcnVudGltZSBpLmUuYWZ0ZXIgdGhlIHN0YXRpYyBjcmVhdGlvbiBvZiAnbm9Q YXJlbnQnLg0KDQoJCQloYXJkTXVzdDIoKHRoaXMucGFyZW50IGlzIE5vUGFyZW50KSB8fCAodGhp cy5wYXJlbnQgaXMgbnVsbCksDQoJCQkJKCkgPT4NCgkJCQkidHJpZWQgdG8gcmUtc2V0IHBhcmVu dCBvbiBvYmplY3Qgb2YgdHlwZTogIg0KCQkJCSsgbmwgKyB0aGlzLmNsYXNzTmFtZVENCgkJCQkr IG5sICsgIk9yaWdpbmFsIHBhcmVudCB0eXBlIGlzOiAiDQoJCQkJKyAodGhpcz8ucGFyZW50Py5j bGFzc05hbWVRID09IG51bGwgPyAibnVsbCIgOiB0aGlzLnBhcmVudC5jbGFzc05hbWVRKQ0KCQkJ CSsgbmwgKyAiYW5kIG5ldyBwYXJlbnQgdHlwZSBpczogIg0KCQkJCSsgcHJudC5jbGFzc05hbWVR DQoJCQkJKyBubCArICJJdGVtIGhhdmluZyBwYXJlbnQgc2V0IG9uIGl0IGlzOiAiDQoJCQkJLy8g YmVjYXVzZSBvYmplY3QgbWF5IG5vdCBiZSBmdWxseSBjb25zdHJ1Y3RlZCB5ZXQsIGNoZWNrIGhv d3ZlciBUT0RPIHRoaXMgaXMgYSBtYWpvciBoYWNrIGFuZCBtdXN0IGJlIGZpeGVkIHNvbWV0aW1l Lg0KLy8JCQkJKyBubCArICh0aGlzIGlzIG51bGwgPyAiKG51bGwpIiA6IHRoaXMudG9SYXdTdHIo KSkpOw0KCQkJCSsgbmwgKyB0aGlzLnRvUmF3U3RyKCkgKTsNCg0KCQkJcGFyZW50ID0gcHJudDsN CgkJfQ0KDQoNCgkJcHVibGljIHZvaWQgZm9yY2VOZXdQYXJlbnRGb3JSb290T2JqZWN0KCkgew0K CQkJLy8gRXZlcnkgb2JqZWN0IG11c3QgaGF2ZSBzb21lIHBhcmVudCwgaW5jbHVkaW5nIHRoZQ0K CQkJLy8gcm9vdCBvYmplY3Qgb2YgdGhlIHBhcnNlLCB3aGljaCBpcyBMREJpdGVtcw0KCQkJLy8g KGEgc2VxdWVuY2Ugb2YgTERCIGl0ZW1zKSwgc28gdGhpcyBmb3JjZXMgb25lLg0KCQkJLy8gSXQg aXMgb25seSBmb3IgdGhhdCBwdXJwb3NlIQ0KCQkJLy8gDQoJCQkvLyBMREJpdGVtcyBvYmogZXhp c3RzIGZvciBzdWIgb2JqcyBzdWNoIGFzIHRoZSBzdGF0ZW1lbnRzDQoJCQkvLyBpbiBhIHdoaWxl IGxvb3AsIGluIGEgcHJvYywgaW4gYW4gaWYuLi4gZXRjLiwgZm9yDQoJCQkvLyB3aGljaCB0aGVp ciBwYXJlbnQgaXMgdGhlIHdoaWxlL3Byb2MvaWYgZXRjLg0KCQkJaGFyZE11c3RQYXJlbnRJc0Fi c2VudCgpOw0KCQkJdGhpcy5wYXJlbnQgPSBmYWtlUGFyZW50Ow0KCQl9DQoNCg0KCQkvL3B1Ymxp YyB2b2lkIHJlc2V0TXlQYXJlbnRUbyhMREJBU1RvYmogcHJudCkgeyAgLy8vLy8vLy8vLy8vLy8v Ly8vLy8vLy8vLy8vLy8vLy8vLyBkZXN0cm95ISEhISEhIHRvZG8NCgkJLy8JcGFyZW50ID0gcHJu dDsNCgkJLy99DQoNCgkJLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vIHh4eHh4eHh4eHh4eHggZGVs ZXRlIC0gdG9kbw0KCQkvL3ByaXZhdGUgdm9pZCBzZXRQYXJlbnRPbktpZChMREJBU1RvYmoga2lk KSA9PiAvLyB0b2RvIG5lZWRlZD8NCgkJLy8JCQkJCQkJCQkJCSAgLy8gY2hlY2sgcGFyZW50ZSBk b2Vzbid0IGV4aXN0IC0gdG9kbw0KCQkvLwlraWQucGFyZW50ID0gdGhpczsNCg0KCQlwdWJsaWMg dmlydHVhbCB2b2lkIHNldFBhcmVudE9uS2lkc0FuZE1ha2VLaWRzRGljdCggIC8vIHRvZG8gLSBh bmQgYWRkIHRvIGtpZHMgZGljdA0KCQkJCQkJCQkJCQkJCQkJIC8vIHRoaXMgbWl4ZXMgdXAgc2V0 dGluZyBwYXJlbnQgYW5kIG1ha2luZyBjaGlsZCBkaWN0LiBOb3QgZ29vZC4gLSB0b2RvDQoJCQkJ CQlwYXJhbXMgKHN0cmluZyBraWROYW1lLCBMREJBU1RvYmoga2lkKVtdIGtpZHNJbikgew0KCQkJ dmFyIGxvYyA9IGNsYXNzTmFtZVBsdXMoInNldFBhcmVudE9uS2lkc0FuZE1ha2VLaWRzRGljdCIp Ow0KDQoJCQl2YXIga2lkc1RvQWRkID0gbmV3IExEQlN0cnVjdHNDaGlsZHJlbih0aGlzLCBraWRz SW4pOw0KCQkJaGFyZE11c3QyKGtpZHMuaXNFbXB0eSwNCgkJCQkoKSA9Pg0KCQkJCSQic2V0dGlu ZyBraWRzIG9uIHBhcmVudCAne2NsYXNzTmFtZX0nIiANCgkJCQkrICJ3aGVuIGtpZHMgaXMgbm90 IGVtcHR5LCAiDQoJCQkJKyAkImtpZHMgaXMgKHtraWRzLkNvdW50fSBraWRzKToiDQoJCQkJKyBu bCArIGtpZHMudG9EZWJ1Z1N0cigpDQoJCQkJKyBubCArICQiVHJ5aW5nIHRvIGFkZFxue2tpZHNU b0FkZC50b0RlYnVnU3RyKCl9XG4iDQoJCQkJKyAkImluIHtjbGFzc05hbWV9Iik7DQoJCQkvLyBp ZiB0aGVyZSBpcyBhbiBMREJTdHJ1Y3RzQ2hpbGRyZW4gYW5kIGFub3RoZXIgY2hpbGQsDQoJCQkv LyB0aGlzIHdpbGwgYmxvdyB1cCAtIHdpbGwgbmVlZCB0byBkbyBraWRzLkFkZCBvcg0KCQkJLy8g c29tZXRoaW5nIC0gaW4gZmFjdCwga2lkcyBuZWVkcyB0byBiZSBjcmVhdGVkIGluIG9uZQ0KCQkJ Ly8gZ28sIHdoaWNoIGlzIHdoYXQgaGFwcGVucy4NCgkJCWtpZHMgPSBraWRzVG9BZGQ7ICAgIC8v Ly8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLyB3 aHkgdGhpcz8gdG9kbw0KCQkJQXJyYXkuRm9yRWFjaChraWRzSW4sIHhraWQgPT4gaGFyZE11c3Qo ISh4a2lkLmtpZCBpcyBudWxsKSwgbG9jLCAibnVsbCBraWQiKSk7DQoJCQlBcnJheS5Gb3JFYWNo KGtpZHNJbiwgeGtpZCA9PiB4a2lkLmtpZC5zZXRNeVBhcmVudFRvKHRoaXMpKTsNCgkJfQ0KDQoN CgkJcHVibGljIHZpcnR1YWwgdm9pZCBzZXRQYXJlbnRPbktpZHNBbmRBZGRUb0tpZHNEaWN0KA0K CQkJCQlwYXJhbXMgKHN0cmluZyBraWROYW1lLCBMREJBU1RvYmoga2lkKVtdIGtpZHNJbikgew0K CQkJdmFyIGtpZHNUb0FkZF9qdXN0Rm9yRXJyUmVwb3J0aW5nID0gbmV3IExEQlN0cnVjdHNDaGls ZHJlbih0aGlzLCBraWRzSW4pOw0KCQkJaGFyZE11c3QyKCFraWRzLmlzRW1wdHksIC8vIG1heSBk aXNhYmxlIHRoaXMgbGF0ZXIgDQoJCQkJKCkgPT4NCgkJCQkiYWRkaW5nIHRvIGtpZHMgd2hlbiBr aWRzIGlzIGVtcHR5LCAiDQoJCQkJICsgJCJraWRzIGlzXG57a2lkcy50b0RlYnVnU3RyKCl9XG4i DQoJCQkJICsgJCJUcnlpbmcgdG8gYWRkXG57a2lkc1RvQWRkX2p1c3RGb3JFcnJSZXBvcnRpbmcu dG9EZWJ1Z1N0cigpfVxuIg0KCQkJCSArICQiaW4ge2NsYXNzTmFtZX0iKTsNCgkJCUFycmF5LkZv ckVhY2goa2lkc0luLCB4a2lkID0+IHsNCi8vCQkJCXNldFBhcmVudE9uS2lkKHhraWQua2lkKTsN CgkJCQl4a2lkLmtpZC5zZXRNeVBhcmVudFRvKHRoaXMpOw0KCQkJCWtpZHMuQWRkKHhraWQpOw0K CQkJfSk7DQoJCX0NCg0KDQoJCXB1YmxpYyB2aXJ0dWFsIElkZW50c1VzZWQgZ2V0QWxsSURzKCkg ew0KCQkvKiBUaGlzIGlzIG92ZXJyaWRkZW4gb25seSBpbiBUZW1wbGF0ZWRBZ2csIGFuZCB0aGF0 J3Mgb25seSB0byANCgkJCWRlbGliZXJhdGVseSBmYWlsLiBUaGVyZSdzIHNvbWV0aGluZyB3cm9u ZyB0aGVyZSwgdG9kbyAtIA0KCQkJdW4tdmlydHVhbGlzZSB0aGlzIGFuZCByZW1vdmUgdGhlIG9u ZSBvdmVycmlkZS4gLSB0b2RvDQoJCSovDQoJCQl2YXIgaXUgPSBuZXcgSWRlbnRzVXNlZCgpOw0K CQkJdGhpcy5fZ2V0QWxsSURzKGl1KTsNCgkJCXJldHVybiBpdTsNCgkJfQ0KDQoJCXB1YmxpYyB2 aXJ0dWFsIHZvaWQgX2dldEFsbElEcyhJZGVudHNVc2VkIGl1KSB7DQoJCS8vIEdldHMgYWxsIHRo ZSBpZGVudGlmaWVycyBleHBsaWNpdGx5IHVzZWQgKHJlYWQgb3Igd3JpdHRlbikgIC0tLS0tIHRv ZG8gdXBkYXRlIHRoaXMNCgkJLy8gYW55d2hlcmUgaW4gdGhlIEFTVC4gIERvZXMgbm90IGdldCBp ZGVudHMgd2hpY2ggYXJlDQoJCS8vIGRlY2xhcmF0aW9ucyBpZS4gcGFyYW1ldGVycywgb3IgdmFy L2NvbnN0IGRlY2xhcmF0aW9ucw0KCQkvLyB1bmxlc3MgdGhlc2UgYXJlIGNvbWJpbmVkIHdpdGgg YW4gYXNzaWdubWVudC4NCgkJLy8NCgkJLy8gSW1wbGllZCBpZGVudHMgc3VjaCBhcyB0aG9zZSBm cm9tIHRibC4qIGFyZSBpbXBsaWNpdCBhbmQgaWdub3JlZC4NCgkJLy8NCgkJLy8gUm9vdCBjYWxs ZXIgc3VwcGxpZXMgbmV3LCBlbXB0eSBpdQ0KCQkvLyBuZWVkIHVzYWdlIGhlcmUgLSB0b2RvIGRv Y3MvLw0KCQkJa2lkcy5fZ2V0QWxsSURzKGl1KTsNCgkJfQ0KDQoJCXB1YmxpYyBhYnN0cmFjdCBi b29sIGNhbkdldEFsbElkZW50c1VzZWQgew0KCQkvLyAJVGhpcyBzZWVtcyB0byBiZSB0cnVlIG9u IG1vc3QgY2xhc3NlcyBzbyBJIGNvdWxkIHNldCB0cnVlIA0KCQkvLyBhcyBhIGRlZmF1bHQgaGVy ZSBhbmQgb3ZlcnJpZGUgaXQgd2hlcmUgaXQncyBub3Qgd2FudGVkLCBzYXZpbmcgDQoJCS8vIGEg Y2h1bmsgb2YgY29kZSwgYnV0IEknZCByYXRoZXIgbWFrZSBpdCBleHBsaWNpdCB0byBmb3JjZSBt ZSB0byBjb25zaWRlciBlYWNoIGNhc2UuIEEgYml0IG1vcmUgQyZQIGZvciBsZXNzIGNoYW5jZSBv ZiBidWdzLg0KCQkJZ2V0Ow0KCQl9DQoNCg0KCQkvLyBQcm9kdWNlcyBhIHN0cmluZyB0aGF0IHNo b3VsZCBiZSBpZGVudGljYWwgdG8gKGV4Y2VwdGluZw0KCQkvLyB3aGl0ZXNwYWNlcykgdGhlIGlu cHV0IGllLiBlbWl0IExEQiBjb2RlIG5vdCB2YWxpZCBTUUwNCgkJLy8NCgkJLy8gVG9TdHJpbmcg d2FzIGNhdXNpbmcgdG9vIG1hbnkgd2VpcmQgcHJvYmxlbXMgKGR1ZSB0byBteQ0KCQkvLyBpbmV4 cGVyaWVuY2Ugd2l0aCBjIykgc28ganVzdCB1c2VkIHRvUmF3U3RyKCkNCgkJcHVibGljIGFic3Ry YWN0IHN0cmluZyB0b1Jhd1N0cigpOw0KDQoJCXB1YmxpYyBvdmVycmlkZSBzdHJpbmcgdG9EZWJ1 Z1N0cigpID0+IHRvUmF3U3RyKCk7DQoNCgl9IC8vIGVuZCBMREJBU1RvYmoNCg0KDQoNCglwdWJs aWMgaW50ZXJmYWNlIEloYW5kbGVQcmVmaXhlczxUPg0KCQkJCQkJd2hlcmUgVCA6IExEQlJvb3Qg ew0KDQoJCXB1YmxpYyBib29sIGlzUHJlZml4ZWQgeyBnZXQ7IH0NCg0KCQlwdWJsaWMgYm9vbCBp c0V4Y2Vzc1ByZWZpeGVkIHsgZ2V0OyB9DQoNCgkJLy8gVGhlIFQgaW4gYWRkUHJlZml4L3JlUHJl Zml4L3dpdGhvdXRQcmVmaXggaXMgYmVjYXVzZSB3ZSBtYXkgYmUgDQoJCS8vIHJldHVybmluZyBl Zy4gYSBsaXN0IG9mIGl0ZW1zIHdpdGggcHJlZml4ZXMgDQoJCS8vIHRodXMgbW9kaWZpZWQsIG5v dCBhIHNpbmdsZSBQTVFJZGVudA0KDQoJCXB1YmxpYyBUIGFkZFByZWZpeChQTVFJZGVudCBwZngp Ow0KDQoJCXB1YmxpYyBUIHJlUHJlZml4KFBNUUlkZW50IG5ld3BmeCk7DQoNCi8vCQlwdWJsaWMg VCBzdHJpcFByZWZpeChQTVFJZGVudCBpZCk7DQoJfQ0KCS8vIHRvZG8gLSBtb3ZlIHRoaXMNCg0K DQoNCg0KDQoJcHVibGljIGFic3RyYWN0IGNsYXNzIExEQlJvb3Qgew0KCQkvLyBSb290IG9mIGV2 ZXJ5dGhpbmcgTERCLWlzaA0KDQoJCXB1YmxpYyBib29sIEVxdWFscyhbQWxsb3dOdWxsXSBMREJS b290IG90aGVyKSB7DQoJCQl0aHJvdyBuZXcgTERCU2hvdWxkTm90QmVJbXBsZW1lbnRlZEV4Y2Vw dGlvbigNCgkJCQkJCQkJCSJjYWxsZWQgRXF1YWxzIG9uIExEQlJvb3QiKTsNCgkJfQ0KDQoJCXB1 YmxpYyBvdmVycmlkZQ0KCQkJYm9vbCBFcXVhbHMoW0FsbG93TnVsbF0gT2JqZWN0IG90aGVyKSB7 DQoJCQl0aHJvdyBuZXcgTERCU2hvdWxkTm90QmVJbXBsZW1lbnRlZEV4Y2VwdGlvbigNCgkJCQkJ CQkJCSJjYWxsZWQgRXF1YWxzIGluIE9iamVjdCIpOw0KCQl9DQoNCgkJcHVibGljIG92ZXJyaWRl IGludCBHZXRIYXNoQ29kZSgpIHsNCgkJCXRocm93IG5ldyBMREJTaG91bGROb3RCZUltcGxlbWVu dGVkRXhjZXB0aW9uKA0KCQkJCQkJCQkJImNhbGxlZCBHZXRIYXNoQ29kZSBpbiBMREJSb290Iik7 DQoJCX0NCg0KCQlwdWJsaWMgc3RhdGljIGJvb2wgb3BlcmF0b3IgPT0oTERCUm9vdCBsaHMsDQoJ CQkJCQkJCQkgICBMREJSb290IHJocykgew0KCQkJdGhyb3cgbmV3IExEQlNob3VsZE5vdEJlSW1w bGVtZW50ZWRFeGNlcHRpb24oDQoJCQkJCQkJCQkiY2FsbGVkID09IGluIExEQlJvb3QiKTsNCgkJ fQ0KDQoJCXB1YmxpYyBzdGF0aWMgYm9vbCBvcGVyYXRvciAhPShMREJSb290IGxocywNCgkJCQkJ CQkJCSAgIExEQlJvb3QgcmhzKSB7DQoJCQl0aHJvdyBuZXcgTERCU2hvdWxkTm90QmVJbXBsZW1l bnRlZEV4Y2VwdGlvbigNCgkJCQkJCQkJCSJjYWxsZWQgIT0gaW4gTERCUm9vdCIpOw0KCQl9DQoN Cg0KCQlwdWJsaWMgdmlydHVhbCBzdHJpbmcgY2xhc3NOYW1lIHsNCgkJCS8vIHRvZG8gLSB0aGlz IG5lZWRzIGNoZWNraW5nIGl0IHdvcmtzIGFzIEkgd2FudA0KCQkJLy8gYWxzbyByZW5hbWUgdG8g bGRiY2xhc3NuYW1lIC0tIHRvZG8NCgkJCWdldCA9PiB0aGlzLkdldFR5cGUoKS5GdWxsTmFtZSA/ PyAiKHVua25vd24pIjsNCgkJfQ0KDQoNCgkJcHVibGljIHZpcnR1YWwgc3RyaW5nIGNsYXNzTmFt ZVEgPT4NCgkJCSInIiArIGNsYXNzTmFtZSArICInIjsNCg0KDQoJCXB1YmxpYyB2aXJ0dWFsIHN0 cmluZyBjbGFzc05hbWVQbHVzKHN0cmluZyBwbHVzKSA9Pg0KCQkJY2xhc3NOYW1lICsgIi4iICsg cGx1czsNCg0KCQlwdWJsaWMgb3ZlcnJpZGUgc3RyaW5nIFRvU3RyaW5nKCkgew0KCQkJLy8gVGhp cyBpbXBsaWNpdCB0by1zdHJpbmcgY29udmVyc2lvbiBjcmFwIGNvc3QgbWUgYSBmZXcgaG91cnMs IHNvIGF0IGxlYXN0DQoJCQkvLyBkbyB0aGlzICYgYmxvdyB1cCBhdCBydW50aW1lLiBXb3VsZCBw cmVmZXIgY29tcGlsZSB0aW1lIGJ1dCBpdCBzZWVtcw0KCQkJLy8gbm90IHBvc3NpYmxlLiAgVGhp cyB0dXJucyBvdXQgdG8gaGF2ZSBiZWVuIGEgZ29vZCBpZGVhLA0KCQkJLy8gc2F2ZWQgbWUgcXVp dGUgYSBiaXQgbW9yZSBkZWJ1Z2dpbmchDQoJCQkvLyA8aHR0cHM6Ly9zdGFja292ZXJmbG93LmNv bS9xdWVzdGlvbnMvMTUzNDU1MTcvaXMtaXQtcG9zc2libGUtdG8tZGlzYWJsZS1pbXBsaWNpdC10 b3N0cmluZy1jYWxsPg0KCQkJLy8gV2lsbCB0cnkgPGh0dHBzOi8vc3RhY2tvdmVyZmxvdy5jb20v cXVlc3Rpb25zLzU0MzU0MzQyL2hvdy10by1nZXQtYW4tZXJyb3Itc2hvd24td2hlbi11c2luZy1u b24tc3RyaW5ncy1hcy1zdHJpbmdzLWluc3RlYWQtb2YtYW4tYXV0b20vNTQzNTUxMTUjNTQzNTUx MTUpDQoJCQl2YXIgbXNnID0gIkxEQlJvb3QuVG9TdHJpbmcoKSI7DQoJCQl0aHJvdyBuZXcgTERC VG9TdHJpbmdJbXBsaWN0Q29udmVyc2lvbkV4Y2VwdGlvbihtc2cpOw0KCQl9DQoNCgkJcHVibGlj IGFic3RyYWN0IHN0cmluZyB0b0RlYnVnU3RyKCk7DQoJfQ0KDQoNCg0KCXB1YmxpYyBhYnN0cmFj dCBjbGFzcyBFcGhlbWVyYWwgOiBMREJSb290IHsNCgkJLy8gZm9yIG9iamVjdHMgdGhhdCBhcmUg bm90IHBhcnQgb2YgdGhlIEFTVA0KCX0NCg0KDQoNCglwdWJsaWMgaW50ZXJmYWNlIElXaXRoTGlu ZU5VbSB7ICAvLyB0b2RvIC0gdXNlIG9yIHJlbW92ZSAtIHRvZG8NCgkJLy8JcHVibGljIA0KCX0N Cg0KDQoJcHVibGljIGludGVyZmFjZSBJSGFzVGFibGVBbGlhcyB7DQoJCS8vIEhhcyBhIHRhYmxl IGFsaWFzIEFTVCBvYmouIE1heSBiZSBhIC4uLk1pc3Npbmcgc3VidHlwZSBpbiB3aGljaA0KCQkv LyBpdCBoYXMgbm8gYWxpYXMgZ2l2ZW4gYnkgdGhlIHVzZXIsIGJ1dCBhbGlhcyBBU1QgaXMgdGhl cmUuIE1vcmUNCgkJLy8gYWNjdXJhdGVseSBhIFRhYmxlU291cmNlIGFsaWFzIGJ1dCBvaw0KCQlw dWJsaWMgYWJzdHJhY3QgVGFibGVBbGlhcyB0YSB7IGdldDsgc2V0OyB9DQoJfQ0KDQoNCgkvLyBC YXNlIGNsYXNzIGZvciBhbGwgTERCIEFTVCBvYmplY3RzDQoJcHVibGljIGFic3RyYWN0IGNsYXNz IExEQkFTVG9iaiA6IExEQlJvb3Qgew0KCQkvLyBUaGlzIG9uZSBpcyBhIHByb2JsZW0uIElmIEkg ZGVjbGFyZSB0aGUgJ3BhcmVudCcgcHJvcGVydHkNCgkJLy8gYWJzdHJhY3QgSSB0aGVuIGhhdmUg dG8gaW1wbGVtZW50IGl0IGxpdGVyYWxseSBodW5kcmVkcyBvZg0KCQkvLyB0aW1lcyBpbiB0aGUg ZGVyaXZlZCBjbGFzc2VzLCBhbmQgSSByZWFsbHkgZG9uJ3QgdGhpbmsgaXQNCgkJLy8gd291bGQg aGVscCBzbyBqdXN0IHNldCBpdCB0byBhIGRlZmF1bHQgd2hpY2ggZ2V0cyBvdmVyd3JpdHRlbiBs YXRlci4NCgkJLy8gDQoJCS8vIFRoZSBwcm9ibGVtIGlzIHRoYXQgdGhvc2Ugb2JqZWN0cyB3ZXJl IGNyZWF0ZWQgYnkgdGhlDQoJCS8vIHBhcnNlciwgd2hpY2ggY3JlYXRlcyB0aGVtIGJvdHRvbS11 cCwgd2hpY2ggbWVhbnMgeW91IGNhbid0DQoJCS8vIGtub3cgdGhlIHBhcmVudCB3aGVuIHRoZXkg YXJlIGNyZWF0ZWQuIEl0IHNob3VsZCBiZQ0KCQkvLyBwb3NzaWJsZSB0byB3b3JrIGFyb3VuZCB0 aGlzIGJ1dCBpdCBkb2VzIG1lYW4gcmV3b3JraW5nIHRoZQ0KCQkvLyBwYXJzZXIgZnVuZGFtZW50 YWxseSwgYW5kIEknbSBub3QgZ29pbmcgdG8gZG8gdGhhdA0KCQkvLyBhc3N1bWVpbmcgaXQncyBl dmVuIHBvc3NpYmxlLg0KDQoJCS8vIHRvZG8gLSByZWFkIHVwIG9uIHByaXYvcHViL3Byb2cgYWNj ZXNzb3JzIEkgcmVhbGx5IGRvbid0DQoJCS8vIGdldCB0aGVzZSBhdCBhbGwNCgkJcHVibGljIExE QkFTVG9iaiBwYXJlbnQgeyBnZXQ7IHByaXZhdGUgc2V0OyB9DQoJCQkJCQk9IG5vUGFyZW50Ow0K CQkvLyBVbmlxdWUgSUQgcGVyIG9iamVjdCwgdXNlZnVsIGZvciBkaXN0aW5ndWlzaGluZyB0aGVt DQoJCS8vIHdpdGhvdXQgZ2VuZXJhbCBlcXVhbGl0eS4NCgkJcmVhZG9ubHkgcHVibGljIHVsb25n IHVpZCA9IG5ld1VJRCgpOw0KDQoJCS8vIHB1YmxpYyBhYnN0cmFjdCBpbnQgbGluZU51bSB7IGdl dDsgc2V0OyB9DQoNCgkJLy8gSXMgdmFsaWRhdGVkIGlzIGEgY2hlYXBpc2ggY2hlY2sgdG8gZW5z dXJlIGV2ZXJ5dGhpbmcgZ2V0cw0KCQkvLyB2YWxpZGF0ZWQNCgkJLy8gY2FuIGRvIHRoaXMgYXMg YXV0byBwcm9wPyB0b2RvDQoJCXByaXZhdGUgYm9vbCBfdmFsaWRhdGVkID0gZmFsc2U7DQoNCgkJ cHJvdGVjdGVkIGJvb2wgdmFsaWRhdGVkIHsNCgkJCWdldCA9PiBfdmFsaWRhdGVkOw0KCQkJc2V0 IHsNCgkJCQkvLyBoYXJkTXVzdCghdmFsaWRhdGVkLCAiLi4uIGFscmVhZHkgdmFsaWRhdGVkLi4u ICIpOyAtIG5vDQoJCQkJLy8gSXQncyBoYXJkIHRvIGF2b2lkIHZhbGlkYXRpbmcgYSB0aGluZyB0 d2ljZSwgc28gZm9yIG5vdyBhbGxvdyBpdA0KCQkJCS8vIExvb2sgaW50byBpdCBsYXRlciwgcmVh bGx5IHNob3VsZG4ndCBoYXBwZW4NCgkJCQlfdmFsaWRhdGVkID0gdHJ1ZTsNCgkJCX0NCgkJfQ0K DQoJCXB1YmxpYyBMREJTdHJ1Y3RzQ2hpbGRyZW4ga2lkcyB7IGdldDsgcHJpdmF0ZSBzZXQ7IH0g PQ0KCQkJCQluZXcgTERCU3RydWN0c0NoaWxkcmVuKG5vUGFyZW50KTsgLy8ganVzdCBlYXNpZXIN Cg0KCQlwdWJsaWMgTERCQVNUb2JqKCkgeyAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8v Ly8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLyB0b2RvIGRlYWQ/DQoJCQkJCQkJICAv LyBWU3R1ZGlvIHRoaW5rcyB0aGlzIGhhcyB6ZXJvIHJlZmVyZW5jZXMsIHdoaWNoIGlzIHRydWUg ZXhwbGljaXRseSwgYnV0IGl0J3MgDQoJCQkJCQkJICAvLyBjYWxsZWQgaW1wbGljaXRseSBvbiBl dmVyeSBvYmogY3JlYXRpb24gLSBvciBzaG91bGQgZG8gdG9kby0gY2hlY2sNCgkJCWlmIChyZWNv cmRPYmplY3RzQ3JlYXRlZCkgew0KCQkJCUFsbENyZWF0ZWRJdGVtcy5BZGQodGhpcyk7DQoJCQl9 DQoJCX0NCg0KDQoJCXB1YmxpYyB2aXJ0dWFsIHZvaWQgdmFsaWRhdGUoKSB7DQoJCQlpZiAocmVw b3J0QWxzb0lmVmFsaWRhdGlvbk9LKSB7DQoJCQkJZGVidWdtc2coInZhbGlkYXRpbmcuLi4iICsg Y2xhc3NOYW1lDQoJCQkJCSsgIiAoIiArIGFzTmFtZU9ySWRlbnRDb250ZW50cygpICsgIikiKTsN CgkJCX0NCgkJCW1ocF9taGsoKTsNCgkJCWtpZHMudmFsaWRhdGUoKTsNCgkJCS8vIHZhbGlkYXRl ZCA9IHRydWU7IC0tIE5vLCBnZXQgZWFjaCBzdWJjbGFzcyB0byBzZXQNCgkJCS8vIHZhbGlkYXRl ZC4gVGhhdCBmb3JjZXMgYW4gZXhwbGljaXQgY2FsbCB0byBiYXNlKCkgd2hpY2gNCgkJCS8vIGlz IG1vcmUgY29kZSBidXQgb2suDQoJCX0NCg0KDQoJCXB1YmxpYyBib29sIGlzVmFsaWRhdGVkIHsg Z2V0ID0+IHZhbGlkYXRlZDsgfSAgLy8gdG9kbyBqdXN0ID0+IHZhbGlkYXRlZDsNCg0KDQoJCXB1 YmxpYyB2aXJ0dWFsIGJvb2wgaXNUb3BMZXZlbEl0ZW1TZXEgPT4gZmFsc2U7DQoNCg0KCQlwdWJs aWMgdmlydHVhbCB2b2lkIG1ocF9taGsoKSB7ICAvLyBkb24ndCB0aGluayB0aGlzIG5lZWQgYmUg dmlydHVhbCAtIHRvZG8/DQoJCQkJCQkJCQkJIC8vID0gbXVzdCBoYXZlIHBhcmVudCwgbXVzdCBo YXZlIGtpZHMuIFRoZSBraWRzIG1heSBiZSB0aGUNCgkJCQkJCQkJCQkgLy8gZW1wdHkgc2V0IGFu ZCB0aGUgcGFyZW50IG1heSBiZSBub1BhcmVudCBidXQgdGhleSBtdXN0DQoJCQkJCQkJCQkJIC8v IGV4aXN0Lg0KCQkJCQkJCQkJCSAvLyBXaHkgbm90IGp1c3QgaW5saW5lIHRoaXMgaW50byB2YWxp ZGF0ZSgpPw0KCQkJCQkJCQkJCSAvLyBCZWNhdXNlIGEgZmV3IGNsYXNzZXMgbmVlZCBiZXNwb2tl IHZhbGlkYXRpb24sIGJ1dCBzdGlsbCBtdXN0IGNoZWNrIHRoaXMuDQoJCQloYXJkTXVzdFBhcmVu dElzUHJlc2VudCgpOw0KCQkJa2lkcy5lYWNoS2lkUGFyZW50TXVzdEJlKHRoaXMpOw0KCQl9DQoN Cg0KCQlwdWJsaWMgc3RyaW5nIGFzTmFtZU9ySWRlbnRDb250ZW50cygpIHsNCgkJCS8vIGZvciB2 ZXJ5IGNydWRlIGRlYnVnZ2luZyANCgkJCXZhciBvcHROYW1lID0gdGhpcyBpcyBJaXNOYW1lZEl0 ZW0gbmkgPyBuaS5uYW1lLnRvUmF3U3RyKCkgOiAiIjsNCgkJCW9wdE5hbWUgPSAob3B0TmFtZSA9 PSAiIiAmJiB0aGlzIGlzIFBNUUlkZW50KSA/IHRoaXMudG9SYXdTdHIoKSA6ICIiOw0KDQoJCQl2 YXIgb3B0TmFtZTIgPSBvcHROYW1lICsgIiAgKHVpZDoiICsgdWlkLlRvU3RyaW5nKCkgKyAiKSAi DQoJCQkJKyBnZXRGaXJzdEZld0NoYXJzT2YodG9SYXdTdHIoKSk7DQoJCQlyZXR1cm4gb3B0TmFt ZTI7DQoJCX0NCg0KDQoJCXB1YmxpYyB2aXJ0dWFsIHZvaWQgZ2V0QWxsVUlEcyhVSURzZXQgdWlk cykgew0KCQkJdWlkcy5BZGQodGhpcyk7DQoJCQlraWRzLkZvckVhY2gobmFtZWRLaWQgPT4gbmFt ZWRLaWQua2lkLmdldEFsbFVJRHModWlkcykpOw0KCQl9DQoNCg0KCQlwdWJsaWMgYm9vbCBpc1N0 dWJQYXJlbnQgeyBnZXQgPT4gKHRoaXMgaXMgTm9QYXJlbnQpIHx8ICh0aGlzIGlzIEZha2VQYXJl bnQpOyB9DQoNCg0KCQlwdWJsaWMgdm9pZCB2YWxpZGF0ZVNwZWNpZmljSXRlbXMocGFyYW1zIExE QkFTVG9ialtdIGl0ZW1zKSB7DQoJCQlBcnJheS5Gb3JFYWNoKGl0ZW1zLCBpdGVtID0+IGl0ZW0u dmFsaWRhdGUoKSk7DQoJCX0NCg0KDQoJCXB1YmxpYyBUPyBvcHRDbGltYlRvPFQ+KCkgd2hlcmUg VCA6IExEQkFTVG9iaiB7DQoJCQl2YXIgcmVzSXRlbSA9IHRoaXM7DQoJCQl3aGlsZSAoIShyZXNJ dGVtIGlzIFQpKSB7DQoJCQkJaWYgKHJlc0l0ZW0ucGFyZW50LmlzU3R1YlBhcmVudCkgew0KCQkJ CQlyZXR1cm4gbnVsbDsNCgkJCQl9DQoJCQkJcmVzSXRlbSA9IHJlc0l0ZW0ucGFyZW50Ow0KCQkJ fQ0KDQoJCQl2YXIgcmVzID0gcmVzSXRlbSBhcyBUOw0KCQkJcmV0dXJuIHJlczsNCgkJfQ0KDQoN CgkJcHVibGljIFQgcmVxQ2xpbWJUbzxUPigpIHdoZXJlIFQgOiBMREJBU1RvYmogew0KCQkJdmFy IGxvYyA9IGNsYXNzTmFtZSArICIucmVxQ2xpbWJUbzxUPigpIjsNCgkJCXZhciByZXMgPSBvcHRD bGltYlRvPFQ+KCk7DQoJCQloYXJkTXVzdDIoIShyZXMgaXMgbnVsbCksIA0KCQkJCS8vIFRoYW5r cyBTTyA8aHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvMjU4MTY0Mi9ob3ctZG8t aS1nZXQtdGhlLXR5cGUtbmFtZS1vZi1hLWdlbmVyaWMtdHlwZS1hcmd1bWVudD4NCgkJCQkvLyBU b2RvIC0gdXNlIHRoaXMgZWxzZXdoZXJlLCBwb3NzIEV4cGVjdEV4Y2VwdGlvbj8gdG9kbw0KCQkJ CSgpID0+DQoJCQkJbG9jIA0KCQkJCSsgbmwgKyAiLCBjbGltYmVkIHRvIHRvcCwgZGlkbid0IGZp bmQgdHlwZSAiDQoJCQkJKyB0eXBlb2YoVCkuRnVsbE5hbWUNCgkJCQkrIG5sICsgIkhpZXJhcmNo eSBpczogIg0KCQkJCSsgbmwgKyBnZXRJdGVtV2l0aFBhcmVudHModGhpcykpOw0KCQkJaWYgKHJl cyBpcyBudWxsKSB7IHRocm93IG5ldyBOTlFDKCk7IH0NCgkJCXJldHVybiByZXM7DQoJCX0NCg0K DQoJCXB1YmxpYyB2b2lkIGhhcmRNdXN0UGFyZW50SXNQcmVzZW50KCkgew0KDQoJCQloYXJkTXVz dDIoIShwYXJlbnQgaXMgbnVsbCksIA0KCQkJCSgpID0+DQoJCQkJICJOVUxMIHBhcmVudCBmb3Ig aXRlbSBvZiB0eXBlXG4iDQoJCQkJICsgJCJ7R2V0VHlwZSgpfVxuLiIpOw0KDQoJCQloYXJkTXVz dDIoISh0aGlzLnBhcmVudCBpcyBOb1BhcmVudCksDQoJCQkJKCkgPT4NCgkJCQkiUGFyZW50IGlz IE5vUGFyZW50IG9uIG9iamVjdCBvZiB0eXBlXG4iDQoJCQkJKyAkIid7dGhpcy5jbGFzc05hbWV9 JyIpOw0KCQl9DQoNCg0KCQlwdWJsaWMgdm9pZCBoYXJkTXVzdFBhcmVudElzQWJzZW50KCkgew0K CQkJLy8gRm9yIGNoZWNraW5nIGNsb25pbmcgLSBwYXJlbnQgc2hvdWxkIGJlIE5vUGFyZW50IGlt bWVkaWF0ZWx5IA0KCQkJLy8gYWZ0ZXIsIGJlZm9yZSBpdCdzIHNldCBieSBwYXJlbnQsIGFuZCBu ZXZlciBudWxsDQoJCQloYXJkTXVzdCghKHBhcmVudCBpcyBudWxsKSwNCgkJCQkgIk5VTEwgcGFy ZW50IGZvciBpdGVtIG9mIHR5cGVcbiINCgkJCQkgKyAkIntHZXRUeXBlKCl9XG4uIik7DQoJCQlo YXJkTXVzdCgodGhpcy5wYXJlbnQgaXMgTm9QYXJlbnQpLA0KCQkJCSJQYXJlbnQgc2hvdWxkIGJl IE5vUGFyZW50IG9uIG9iamVjdCBvZiB0eXBlXG4iDQoJCQkJKyAkIid7dGhpcy5jbGFzc05hbWV9 JyIpOw0KCQl9DQoNCg0KCQlwdWJsaWMgYm9vbCBoYXNQYXJlbnQ8UD4oKSB7DQoJCQloYXJkTXVz dCghKHRoaXMgaXMgTm9QYXJlbnQpLCAiSXRlbSBpcyBOb1BhcmVudCIpOw0KCQkJcmV0dXJuIHRo aXMucGFyZW50IGlzIFA7DQoJCX0NCg0KDQoJCXB1YmxpYyBib29sIGhhc0FuY2VzdG9yPEE+KCkg ew0KCQkJaGFyZE11c3QoIXRoaXMuaXNTdHViUGFyZW50LCAiSXRlbSBpcyBOb1BhcmVudCIpOw0K DQoJCQkvLyBob3cgdG8gZG8gd2l0aCBhIHN3aXRjaCBleHByPw0KCQkJaWYgKHRoaXMucGFyZW50 LmlzU3R1YlBhcmVudCAvKiBpcyBOb1BhcmVudCB8fCB0aGlzLnBhcmVudCBpcyBGYWtlUGFyZW50 Ki8gKSB7IC8vIHRvZG8gZG8gYXMgeC5oYXNGdWRnZWRQYXJlbnQoKSAtIHRvZG8NCgkJCQlyZXR1 cm4gZmFsc2U7DQoJCQl9IGVsc2UgaWYgKHRoaXMucGFyZW50IGlzIEEpIHsNCgkJCQlyZXR1cm4g dHJ1ZTsNCgkJCX0gZWxzZSB7DQoJCQkJcmV0dXJuIHRoaXMucGFyZW50Lmhhc0FuY2VzdG9yPEE+ KCk7DQoJCQl9DQoJCX0NCg0KCQlwdWJsaWMgYm9vbCBub3RIYXNBbmNlc3RvcjxBPigpID0+DQoJ CQkhaGFzQW5jZXN0b3I8QT4oKTsNCg0KDQoJCXB1YmxpYyB2b2lkIHNldE15UGFyZW50VG8oTERC QVNUb2JqIHBybnQpIHsNCgkJCS8vIEFuIG9iamVjdCBtYXkgb25seSBzZXQgaXRzIHBhcmVudCBp ZiBpdHMgY3VycmVudCBwYXJlbnQgaXMNCgkJCS8vIHRoZSBkdW1teSAnbm9QYXJlbnQnLCB3aGlj aCBhbG1vc3QgZXZlcnkgb2JqZWN0J3MgcGFyZW50IGlzDQoJCQkvLyBzZXQgdG8gb24gY3JlYXRp b24gKHNlZSBMREJBU1RvYmogcGFyZW50IHByb3BlcnR5IGRlZikuDQoNCgkJCS8vIFRoZSB0ZXN0 IGZvciBudWxsIGlzIHBlY3VsaWFyIGdpdmVuIHRoaXMuIEJlY2F1c2UNCgkJCS8vIG5vUGFyZW50 IGlzIGNyZWF0ZWQgc3RhdGljYWxseSwgc2V0dGluZyB0aGUgcGFyZW50IG9mDQoJCQkvLyBub1Bh cmVudCBpcyBkaWZmaWN1bHQsIHBlcmhhcHMgaW1wb3NzaWJsZSwgdG8gZG8gc3RhdGljYWxseQ0K CQkJLy8gYW5kIHJlbGlhYmx5LkRlc3BpdGUgdGhlIGRlY2xhcmF0aW9uICcjbnVsbGFibGUgZW5h YmxlJywgaXQNCgkJCS8vIGdldHMgY3JlYXRlZCB3aXRoIGEgbnVsbCBwYXJyZW50IChxdWl0ZSBy ZWFzb25hYmx5KSwgaGVuY2UNCgkJCS8vIHRoaXMgY2hlY2suVGhlIGFjdHVhbCBzZXR0aW5nIG9m IHRoZSBwYXJlbnQgaGFzIHRvIGJlIGRvbmUNCgkJCS8vIGF0IHJ1bnRpbWUgaS5lLmFmdGVyIHRo ZSBzdGF0aWMgY3JlYXRpb24gb2YgJ25vUGFyZW50Jy4NCg0KCQkJaGFyZE11c3QyKCh0aGlzLnBh cmVudCBpcyBOb1BhcmVudCkgfHwgKHRoaXMucGFyZW50IGlzIG51bGwpLA0KCQkJCSgpID0+DQoJ CQkJInRyaWVkIHRvIHJlLXNldCBwYXJlbnQgb24gb2JqZWN0IG9mIHR5cGU6ICINCgkJCQkrIG5s ICsgdGhpcy5jbGFzc05hbWVRDQoJCQkJKyBubCArICJPcmlnaW5hbCBwYXJlbnQgdHlwZSBpczog Ig0KCQkJCSsgKHRoaXM/LnBhcmVudD8uY2xhc3NOYW1lUSA9PSBudWxsID8gIm51bGwiIDogdGhp cy5wYXJlbnQuY2xhc3NOYW1lUSkNCgkJCQkrIG5sICsgImFuZCBuZXcgcGFyZW50IHR5cGUgaXM6 ICINCgkJCQkrIHBybnQuY2xhc3NOYW1lUQ0KCQkJCSsgbmwgKyAiSXRlbSBoYXZpbmcgcGFyZW50 IHNldCBvbiBpdCBpczogIg0KCQkJCS8vIGJlY2F1c2Ugb2JqZWN0IG1heSBub3QgYmUgZnVsbHkg Y29uc3RydWN0ZWQgeWV0LCBjaGVjayBob3d2ZXIgVE9ETyB0aGlzIGlzIGEgbWFqb3IgaGFjayBh bmQgbXVzdCBiZSBmaXhlZCBzb21ldGltZS4NCi8vCQkJCSsgbmwgKyAodGhpcyBpcyBudWxsID8g IihudWxsKSIgOiB0aGlzLnRvUmF3U3RyKCkpKTsNCgkJCQkrIG5sICsgdGhpcy50b1Jhd1N0cigp ICk7DQoNCgkJCXBhcmVudCA9IHBybnQ7DQoJCX0NCg0KDQoJCXB1YmxpYyB2b2lkIGZvcmNlTmV3 UGFyZW50Rm9yUm9vdE9iamVjdCgpIHsNCgkJCS8vIEV2ZXJ5IG9iamVjdCBtdXN0IGhhdmUgc29t ZSBwYXJlbnQsIGluY2x1ZGluZyB0aGUNCgkJCS8vIHJvb3Qgb2JqZWN0IG9mIHRoZSBwYXJzZSwg d2hpY2ggaXMgTERCaXRlbXMNCgkJCS8vIChhIHNlcXVlbmNlIG9mIExEQiBpdGVtcyksIHNvIHRo aXMgZm9yY2VzIG9uZS4NCgkJCS8vIEl0IGlzIG9ubHkgZm9yIHRoYXQgcHVycG9zZSENCgkJCS8v IA0KCQkJLy8gTERCaXRlbXMgb2JqIGV4aXN0cyBmb3Igc3ViIG9ianMgc3VjaCBhcyB0aGUgc3Rh dGVtZW50cw0KCQkJLy8gaW4gYSB3aGlsZSBsb29wLCBpbiBhIHByb2MsIGluIGFuIGlmLi4uIGV0 Yy4sIGZvcg0KCQkJLy8gd2hpY2ggdGhlaXIgcGFyZW50IGlzIHRoZSB3aGlsZS9wcm9jL2lmIGV0 Yy4NCgkJCWhhcmRNdXN0UGFyZW50SXNBYnNlbnQoKTsNCgkJCXRoaXMucGFyZW50ID0gZmFrZVBh cmVudDsNCgkJfQ0KDQoNCgkJLy9wdWJsaWMgdm9pZCByZXNldE15UGFyZW50VG8oTERCQVNUb2Jq IHBybnQpIHsgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8gZGVzdHJveSEhISEh ISB0b2RvDQoJCS8vCXBhcmVudCA9IHBybnQ7DQoJCS8vfQ0KDQoJCS8vLy8vLy8vLy8vLy8vLy8v Ly8vLy8vLyB4eHh4eHh4eHh4eHh4IGRlbGV0ZSAtIHRvZG8NCgkJLy9wcml2YXRlIHZvaWQgc2V0 UGFyZW50T25LaWQoTERCQVNUb2JqIGtpZCkgPT4gLy8gdG9kbyBuZWVkZWQ/DQoJCS8vCQkJCQkJ CQkJCQkgIC8vIGNoZWNrIHBhcmVudGUgZG9lc24ndCBleGlzdCAtIHRvZG8NCgkJLy8Ja2lkLnBh cmVudCA9IHRoaXM7DQoNCgkJcHVibGljIHZpcnR1YWwgdm9pZCBzZXRQYXJlbnRPbktpZHNBbmRN YWtlS2lkc0RpY3QoICAvLyB0b2RvIC0gYW5kIGFkZCB0byBraWRzIGRpY3QNCgkJCQkJCQkJCQkJ CQkJCSAvLyB0aGlzIG1peGVzIHVwIHNldHRpbmcgcGFyZW50IGFuZCBtYWtpbmcgY2hpbGQgZGlj dC4gTm90IGdvb2QuIC0gdG9kbw0KCQkJCQkJcGFyYW1zIChzdHJpbmcga2lkTmFtZSwgTERCQVNU b2JqIGtpZClbXSBraWRzSW4pIHsNCgkJCXZhciBsb2MgPSBjbGFzc05hbWVQbHVzKCJzZXRQYXJl bnRPbktpZHNBbmRNYWtlS2lkc0RpY3QiKTsNCg0KCQkJdmFyIGtpZHNUb0FkZCA9IG5ldyBMREJT dHJ1Y3RzQ2hpbGRyZW4odGhpcywga2lkc0luKTsNCgkJCWhhcmRNdXN0MihraWRzLmlzRW1wdHks DQoJCQkJKCkgPT4NCgkJCQkkInNldHRpbmcga2lkcyBvbiBwYXJlbnQgJ3tjbGFzc05hbWV9JyIg DQoJCQkJKyAid2hlbiBraWRzIGlzIG5vdCBlbXB0eSwgIg0KCQkJCSsgJCJraWRzIGlzICh7a2lk cy5Db3VudH0ga2lkcyk6Ig0KCQkJCSsgbmwgKyBraWRzLnRvRGVidWdTdHIoKQ0KCQkJCSsgbmwg KyAkIlRyeWluZyB0byBhZGRcbntraWRzVG9BZGQudG9EZWJ1Z1N0cigpfVxuIg0KCQkJCSsgJCJp biB7Y2xhc3NOYW1lfSIpOw0KCQkJLy8gaWYgdGhlcmUgaXMgYW4gTERCU3RydWN0c0NoaWxkcmVu IGFuZCBhbm90aGVyIGNoaWxkLA0KCQkJLy8gdGhpcyB3aWxsIGJsb3cgdXAgLSB3aWxsIG5lZWQg dG8gZG8ga2lkcy5BZGQgb3INCgkJCS8vIHNvbWV0aGluZyAtIGluIGZhY3QsIGtpZHMgbmVlZHMg dG8gYmUgY3JlYXRlZCBpbiBvbmUNCgkJCS8vIGdvLCB3aGljaCBpcyB3aGF0IGhhcHBlbnMuDQoJ CQlraWRzID0ga2lkc1RvQWRkOyAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8v Ly8vLy8vLy8vLy8vLy8vLy8vLy8vLy8gd2h5IHRoaXM/IHRvZG8NCgkJCUFycmF5LkZvckVhY2go a2lkc0luLCB4a2lkID0+IGhhcmRNdXN0KCEoeGtpZC5raWQgaXMgbnVsbCksIGxvYywgIm51bGwg a2lkIikpOw0KCQkJQXJyYXkuRm9yRWFjaChraWRzSW4sIHhraWQgPT4geGtpZC5raWQuc2V0TXlQ YXJlbnRUbyh0aGlzKSk7DQoJCX0NCg0KDQoJCXB1YmxpYyB2aXJ0dWFsIHZvaWQgc2V0UGFyZW50 T25LaWRzQW5kQWRkVG9LaWRzRGljdCgNCgkJCQkJcGFyYW1zIChzdHJpbmcga2lkTmFtZSwgTERC QVNUb2JqIGtpZClbXSBraWRzSW4pIHsNCgkJCXZhciBraWRzVG9BZGRfanVzdEZvckVyclJlcG9y dGluZyA9IG5ldyBMREJTdHJ1Y3RzQ2hpbGRyZW4odGhpcywga2lkc0luKTsNCgkJCWhhcmRNdXN0 Migha2lkcy5pc0VtcHR5LCAvLyBtYXkgZGlzYWJsZSB0aGlzIGxhdGVyIA0KCQkJCSgpID0+DQoJ CQkJImFkZGluZyB0byBraWRzIHdoZW4ga2lkcyBpcyBlbXB0eSwgIg0KCQkJCSArICQia2lkcyBp c1xue2tpZHMudG9EZWJ1Z1N0cigpfVxuIg0KCQkJCSArICQiVHJ5aW5nIHRvIGFkZFxue2tpZHNU b0FkZF9qdXN0Rm9yRXJyUmVwb3J0aW5nLnRvRGVidWdTdHIoKX1cbiINCgkJCQkgKyAkImluIHtj bGFzc05hbWV9Iik7DQoJCQlBcnJheS5Gb3JFYWNoKGtpZHNJbiwgeGtpZCA9PiB7DQovLwkJCQlz ZXRQYXJlbnRPbktpZCh4a2lkLmtpZCk7DQoJCQkJeGtpZC5raWQuc2V0TXlQYXJlbnRUbyh0aGlz KTsNCgkJCQlraWRzLkFkZCh4a2lkKTsNCgkJCX0pOw0KCQl9DQoNCg0KCQlwdWJsaWMgdmlydHVh bCBJZGVudHNVc2VkIGdldEFsbElEcygpIHsNCgkJLyogVGhpcyBpcyBvdmVycmlkZGVuIG9ubHkg aW4gVGVtcGxhdGVkQWdnLCBhbmQgdGhhdCdzIG9ubHkgdG8gDQoJCQlkZWxpYmVyYXRlbHkgZmFp bC4gVGhlcmUncyBzb21ldGhpbmcgd3JvbmcgdGhlcmUsIHRvZG8gLSANCgkJCXVuLXZpcnR1YWxp c2UgdGhpcyBhbmQgcmVtb3ZlIHRoZSBvbmUgb3ZlcnJpZGUuIC0gdG9kbw0KCQkqLw0KCQkJdmFy IGl1ID0gbmV3IElkZW50c1VzZWQoKTsNCgkJCXRoaXMuX2dldEFsbElEcyhpdSk7DQoJCQlyZXR1 cm4gaXU7DQoJCX0NCg0KCQlwdWJsaWMgdmlydHVhbCB2b2lkIF9nZXRBbGxJRHMoSWRlbnRzVXNl ZCBpdSkgew0KCQkvLyBHZXRzIGFsbCB0aGUgaWRlbnRpZmllcnMgZXhwbGljaXRseSB1c2VkIChy ZWFkIG9yIHdyaXR0ZW4pICAtLS0tLSB0b2RvIHVwZGF0ZSB0aGlzDQoJCS8vIGFueXdoZXJlIGlu IHRoZSBBU1QuICBEb2VzIG5vdCBnZXQgaWRlbnRzIHdoaWNoIGFyZQ0KCQkvLyBkZWNsYXJhdGlv bnMgaWUuIHBhcmFtZXRlcnMsIG9yIHZhci9jb25zdCBkZWNsYXJhdGlvbnMNCgkJLy8gdW5sZXNz IHRoZXNlIGFyZSBjb21iaW5lZCB3aXRoIGFuIGFzc2lnbm1lbnQuDQoJCS8vDQoJCS8vIEltcGxp ZWQgaWRlbnRzIHN1Y2ggYXMgdGhvc2UgZnJvbSB0YmwuKiBhcmUgaW1wbGljaXQgYW5kIGlnbm9y ZWQuDQoJCS8vDQoJCS8vIFJvb3QgY2FsbGVyIHN1cHBsaWVzIG5ldywgZW1wdHkgaXUNCgkJLy8g bmVlZCB1c2FnZSBoZXJlIC0gdG9kbyBkb2NzLy8NCgkJCWtpZHMuX2dldEFsbElEcyhpdSk7DQoJ CX0NCg0KCQlwdWJsaWMgYWJzdHJhY3QgYm9vbCBjYW5HZXRBbGxJZGVudHNVc2VkIHsNCgkJLy8g CVRoaXMgc2VlbXMgdG8gYmUgdHJ1ZSBvbiBtb3N0IGNsYXNzZXMgc28gSSBjb3VsZCBzZXQgdHJ1 ZSANCgkJLy8gYXMgYSBkZWZhdWx0IGhlcmUgYW5kIG92ZXJyaWRlIGl0IHdoZXJlIGl0J3Mgbm90 IHdhbnRlZCwgc2F2aW5nIA0KCQkvLyBhIGNodW5rIG9mIGNvZGUsIGJ1dCBJJ2QgcmF0aGVyIG1h a2UgaXQgZXhwbGljaXQgdG8gZm9yY2UgbWUgdG8gY29uc2lkZXIgZWFjaCBjYXNlLiBBIGJpdCBt b3JlIEMmUCBmb3IgbGVzcyBjaGFuY2Ugb2YgYnVncy4NCgkJCWdldDsNCgkJfQ0KDQoNCgkJLy8g UHJvZHVjZXMgYSBzdHJpbmcgdGhhdCBzaG91bGQgYmUgaWRlbnRpY2FsIHRvIChleGNlcHRpbmcN CgkJLy8gd2hpdGVzcGFjZXMpIHRoZSBpbnB1dCBpZS4gZW1pdCBMREIgY29kZSBub3QgdmFsaWQg U1FMDQoJCS8vDQoJCS8vIFRvU3RyaW5nIHdhcyBjYXVzaW5nIHRvbyBtYW55IHdlaXJkIHByb2Js ZW1zIChkdWUgdG8gbXkNCgkJLy8gaW5leHBlcmllbmNlIHdpdGggYyMpIHNvIGp1c3QgdXNlZCB0 b1Jhd1N0cigpDQoJCXB1YmxpYyBhYnN0cmFjdCBzdHJpbmcgdG9SYXdTdHIoKTsNCg0KCQlwdWJs aWMgb3ZlcnJpZGUgc3RyaW5nIHRvRGVidWdTdHIoKSA9PiB0b1Jhd1N0cigpOw0KDQoJfSAvLyBl bmQgTERCQVNUb2JqDQoNCg0KDQoJcHVibGljIGludGVyZmFjZSBJaGFuZGxlUHJlZml4ZXM8VD4N CgkJCQkJCXdoZXJlIFQgOiBMREJSb290IHsNCg0KCQlwdWJsaWMgYm9vbCBpc1ByZWZpeGVkIHsg Z2V0OyB9DQoNCgkJcHVibGljIGJvb2wgaXNFeGNlc3NQcmVmaXhlZCB7IGdldDsgfQ0KDQoJCS8v IFRoZSBUIGluIGFkZFByZWZpeC9yZVByZWZpeC93aXRob3V0UHJlZml4IGlzIGJlY2F1c2Ugd2Ug bWF5IGJlIA0KCQkvLyByZXR1cm5pbmcgZWcuIGEgbGlzdCBvZiBpdGVtcyB3aXRoIHByZWZpeGVz IA0KCQkvLyB0aHVzIG1vZGlmaWVkLCBub3QgYSBzaW5nbGUgUE1RSWRlbnQNCg0KCQlwdWJsaWMg VCBhZGRQcmVmaXgoUE1RSWRlbnQgcGZ4KTsNCg0KCQlwdWJsaWMgVCByZVByZWZpeChQTVFJZGVu dCBuZXdwZngpOw0KDQovLwkJcHVibGljIFQgc3RyaXBQcmVmaXgoUE1RSWRlbnQgaWQpOw0KCX0N CgkvLyB0b2RvIC0gbW92ZSB0aGlzDQoNCg0KDQoNCg0KCXB1YmxpYyBhYnN0cmFjdCBjbGFzcyBM REJSb290IHsNCgkJLy8gUm9vdCBvZiBldmVyeXRoaW5nIExEQi1pc2gNCg0KCQlwdWJsaWMgYm9v bCBFcXVhbHMoW0FsbG93TnVsbF0gTERCUm9vdCBvdGhlcikgew0KCQkJdGhyb3cgbmV3IExEQlNo b3VsZE5vdEJlSW1wbGVtZW50ZWRFeGNlcHRpb24oDQoJCQkJCQkJCQkiY2FsbGVkIEVxdWFscyBv biBMREJSb290Iik7DQoJCX0NCg0KCQlwdWJsaWMgb3ZlcnJpZGUNCgkJCWJvb2wgRXF1YWxzKFtB bGxvd051bGxdIE9iamVjdCBvdGhlcikgew0KCQkJdGhyb3cgbmV3IExEQlNob3VsZE5vdEJlSW1w bGVtZW50ZWRFeGNlcHRpb24oDQoJCQkJCQkJCQkiY2FsbGVkIEVxdWFscyBpbiBPYmplY3QiKTsN CgkJfQ0KDQoJCXB1YmxpYyBvdmVycmlkZSBpbnQgR2V0SGFzaENvZGUoKSB7DQoJCQl0aHJvdyBu ZXcgTERCU2hvdWxkTm90QmVJbXBsZW1lbnRlZEV4Y2VwdGlvbigNCgkJCQkJCQkJCSJjYWxsZWQg R2V0SGFzaENvZGUgaW4gTERCUm9vdCIpOw0KCQl9DQoNCgkJcHVibGljIHN0YXRpYyBib29sIG9w ZXJhdG9yID09KExEQlJvb3QgbGhzLA0KCQkJCQkJCQkJICAgTERCUm9vdCByaHMpIHsNCgkJCXRo cm93IG5ldyBMREJTaG91bGROb3RCZUltcGxlbWVudGVkRXhjZXB0aW9uKA0KCQkJCQkJCQkJImNh bGxlZCA9PSBpbiBMREJSb290Iik7DQoJCX0NCg0KCQlwdWJsaWMgc3RhdGljIGJvb2wgb3BlcmF0 b3IgIT0oTERCUm9vdCBsaHMsDQoJCQkJCQkJCQkgICBMREJSb290IHJocykgew0KCQkJdGhyb3cg bmV3IExEQlNob3VsZE5vdEJlSW1wbGVtZW50ZWRFeGNlcHRpb24oDQoJCQkJCQkJCQkiY2FsbGVk ICE9IGluIExEQlJvb3QiKTsNCgkJfQ0KDQoNCgkJcHVibGljIHZpcnR1YWwgc3RyaW5nIGNsYXNz TmFtZSB7DQoJCQkvLyB0b2RvIC0gdGhpcyBuZWVkcyBjaGVja2luZyBpdCB3b3JrcyBhcyBJIHdh bnQNCgkJCS8vIGFsc28gcmVuYW1lIHRvIGxkYmNsYXNzbmFtZSAtLSB0b2RvDQoJCQlnZXQgPT4g dGhpcy5HZXRUeXBlKCkuRnVsbE5hbWUgPz8gIih1bmtub3duKSI7DQoJCX0NCg0KDQoJCXB1Ymxp YyB2aXJ0dWFsIHN0cmluZyBjbGFzc05hbWVRID0+DQoJCQkiJyIgKyBjbGFzc05hbWUgKyAiJyI7 DQoNCg0KCQlwdWJsaWMgdmlydHVhbCBzdHJpbmcgY2xhc3NOYW1lUGx1cyhzdHJpbmcgcGx1cykg PT4NCgkJCWNsYXNzTmFtZSArICIuIiArIHBsdXM7DQoNCgkJcHVibGljIG92ZXJyaWRlIHN0cmlu ZyBUb1N0cmluZygpIHsNCgkJCS8vIFRoaXMgaW1wbGljaXQgdG8tc3RyaW5nIGNvbnZlcnNpb24g Y3JhcCBjb3N0IG1lIGEgZmV3IGhvdXJzLCBzbyBhdCBsZWFzdA0KCQkJLy8gZG8gdGhpcyAmIGJs b3cgdXAgYXQgcnVudGltZS4gV291bGQgcHJlZmVyIGNvbXBpbGUgdGltZSBidXQgaXQgc2VlbXMN CgkJCS8vIG5vdCBwb3NzaWJsZS4gIFRoaXMgdHVybnMgb3V0IHRvIGhhdmUgYmVlbiBhIGdvb2Qg aWRlYSwNCgkJCS8vIHNhdmVkIG1lIHF1aXRlIGEgYml0IG1vcmUgZGVidWdnaW5nIQ0KCQkJLy8g PGh0dHBzOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzE1MzQ1NTE3L2lzLWl0LXBvc3Np YmxlLXRvLWRpc2FibGUtaW1wbGljaXQtdG9zdHJpbmctY2FsbD4NCgkJCS8vIFdpbGwgdHJ5IDxo dHRwczovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy81NDM1NDM0Mi9ob3ctdG8tZ2V0LWFu LWVycm9yLXNob3duLXdoZW4tdXNpbmctbm9uLXN0cmluZ3MtYXMtc3RyaW5ncy1pbnN0ZWFkLW9m LWFuLWF1dG9tLzU0MzU1MTE1IzU0MzU1MTE1KQ0KCQkJdmFyIG1zZyA9ICJMREJSb290LlRvU3Ry aW5nKCkiOw0KCQkJdGhyb3cgbmV3IExEQlRvU3RyaW5nSW1wbGljdENvbnZlcnNpb25FeGNlcHRp b24obXNnKTsNCgkJfQ0KDQoJCXB1YmxpYyBhYnN0cmFjdCBzdHJpbmcgdG9EZWJ1Z1N0cigpOw0K CX0NCg0KDQoNCglwdWJsaWMgYWJzdHJhY3QgY2xhc3MgRXBoZW1lcmFsIDogTERCUm9vdCB7DQoJ CS8vIGZvciBvYmplY3RzIHRoYXQgYXJlIG5vdCBwYXJ0IG9mIHRoZSBBU1QNCgl9DQoNCg0KDQoJ cHVibGljIGludGVyZmFjZSBJV2l0aExpbmVOVW0geyAgLy8gdG9kbyAtIHVzZSBvciByZW1vdmUg LSB0b2RvDQoJCS8vCXB1YmxpYyANCgl9DQoNCg0KCXB1YmxpYyBpbnRlcmZhY2UgSUhhc1RhYmxl QWxpYXMgew0KCQkvLyBIYXMgYSB0YWJsZSBhbGlhcyBBU1Qgb2JqLiBNYXkgYmUgYSAuLi5NaXNz aW5nIHN1YnR5cGUgaW4gd2hpY2gNCgkJLy8gaXQgaGFzIG5vIGFsaWFzIGdpdmVuIGJ5IHRoZSB1 c2VyLCBidXQgYWxpYXMgQVNUIGlzIHRoZXJlLiBNb3JlDQoJCS8vIGFjY3VyYXRlbHkgYSBUYWJs ZVNvdXJjZSBhbGlhcyBidXQgb2sNCgkJcHVibGljIGFic3RyYWN0IFRhYmxlQWxpYXMgdGEgeyBn ZXQ7IHNldDsgfQ0KCX0NCg0KDQoJLy8gQmFzZSBjbGFzcyBmb3IgYWxsIExEQiBBU1Qgb2JqZWN0 cw0KCXB1YmxpYyBhYnN0cmFjdCBjbGFzcyBMREJBU1RvYmogOiBMREJSb290IHsNCgkJLy8gVGhp cyBvbmUgaXMgYSBwcm9ibGVtLiBJZiBJIGRlY2xhcmUgdGhlICdwYXJlbnQnIHByb3BlcnR5DQoJ CS8vIGFic3RyYWN0IEkgdGhlbiBoYXZlIHRvIGltcGxlbWVudCBpdCBsaXRlcmFsbHkgaHVuZHJl ZHMgb2YNCgkJLy8gdGltZXMgaW4gdGhlIGRlcml2ZWQgY2xhc3NlcywgYW5kIEkgcmVhbGx5IGRv bid0IHRoaW5rIGl0DQoJCS8vIHdvdWxkIGhlbHAgc28ganVzdCBzZXQgaXQgdG8gYSBkZWZhdWx0 IHdoaWNoIGdldHMgb3ZlcndyaXR0ZW4gbGF0ZXIuDQoJCS8vIA0KCQkvLyBUaGUgcHJvYmxlbSBp cyB0aGF0IHRob3NlIG9iamVjdHMgd2VyZSBjcmVhdGVkIGJ5IHRoZQ0KCQkvLyBwYXJzZXIsIHdo aWNoIGNyZWF0ZXMgdGhlbSBib3R0b20tdXAsIHdoaWNoIG1lYW5zIHlvdSBjYW4ndA0KCQkvLyBr bm93IHRoZSBwYXJlbnQgd2hlbiB0aGV5IGFyZSBjcmVhdGVkLiBJdCBzaG91bGQgYmUNCgkJLy8g cG9zc2libGUgdG8gd29yayBhcm91bmQgdGhpcyBidXQgaXQgZG9lcyBtZWFuIHJld29ya2luZyB0 aGUNCgkJLy8gcGFyc2VyIGZ1bmRhbWVudGFsbHksIGFuZCBJJ20gbm90IGdvaW5nIHRvIGRvIHRo YXQNCgkJLy8gYXNzdW1laW5nIGl0J3MgZXZlbiBwb3NzaWJsZS4NCg0KCQkvLyB0b2RvIC0gcmVh ZCB1cCBvbiBwcml2L3B1Yi9wcm9nIGFjY2Vzc29ycyBJIHJlYWxseSBkb24ndA0KCQkvLyBnZXQg dGhlc2UgYXQgYWxsDQoJCXB1YmxpYyBMREJBU1RvYmogcGFyZW50IHsgZ2V0OyBwcml2YXRlIHNl dDsgfQ0KCQkJCQkJPSBub1BhcmVudDsNCgkJLy8gVW5pcXVlIElEIHBlciBvYmplY3QsIHVzZWZ1 bCBmb3IgZGlzdGluZ3Vpc2hpbmcgdGhlbQ0KCQkvLyB3aXRob3V0IGdlbmVyYWwgZXF1YWxpdHku DQoJCXJlYWRvbmx5IHB1YmxpYyB1bG9uZyB1aWQgPSBuZXdVSUQoKTsNCg0KCQkvLyBwdWJsaWMg YWJzdHJhY3QgaW50IGxpbmVOdW0geyBnZXQ7IHNldDsgfQ0KDQoJCS8vIElzIHZhbGlkYXRlZCBp cyBhIGNoZWFwaXNoIGNoZWNrIHRvIGVuc3VyZSBldmVyeXRoaW5nIGdldHMNCgkJLy8gdmFsaWRh dGVkDQoJCS8vIGNhbiBkbyB0aGlzIGFzIGF1dG8gcHJvcD8gdG9kbw0KCQlwcml2YXRlIGJvb2wg X3ZhbGlkYXRlZCA9IGZhbHNlOw0KDQoJCXByb3RlY3RlZCBib29sIHZhbGlkYXRlZCB7DQoJCQln ZXQgPT4gX3ZhbGlkYXRlZDsNCgkJCXNldCB7DQoJCQkJLy8gaGFyZE11c3QoIXZhbGlkYXRlZCwg Ii4uLiBhbHJlYWR5IHZhbGlkYXRlZC4uLiAiKTsgLSBubw0KCQkJCS8vIEl0J3MgaGFyZCB0byBh dm9pZCB2YWxpZGF0aW5nIGEgdGhpbmcgdHdpY2UsIHNvIGZvciBub3cgYWxsb3cgaXQNCgkJCQkv LyBMb29rIGludG8gaXQgbGF0ZXIsIHJlYWxseSBzaG91bGRuJ3QgaGFwcGVuDQoJCQkJX3ZhbGlk YXRlZCA9IHRydWU7DQoJCQl9DQoJCX0NCg0KCQlwdWJsaWMgTERCU3RydWN0c0NoaWxkcmVuIGtp ZHMgeyBnZXQ7IHByaXZhdGUgc2V0OyB9ID0NCgkJCQkJbmV3IExEQlN0cnVjdHNDaGlsZHJlbihu b1BhcmVudCk7IC8vIGp1c3QgZWFzaWVyDQoNCgkJcHVibGljIExEQkFTVG9iaigpIHsgIC8vLy8v Ly8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8v Ly8gdG9kbyBkZWFkPw0KCQkJCQkJCSAgLy8gVlN0dWRpbyB0aGlua3MgdGhpcyBoYXMgemVybyBy ZWZlcmVuY2VzLCB3aGljaCBpcyB0cnVlIGV4cGxpY2l0bHksIGJ1dCBpdCdzIA0KCQkJCQkJCSAg Ly8gY2FsbGVkIGltcGxpY2l0bHkgb24gZXZlcnkgb2JqIGNyZWF0aW9uIC0gb3Igc2hvdWxkIGRv IHRvZG8tIGNoZWNrDQoJCQlpZiAocmVjb3JkT2JqZWN0c0NyZWF0ZWQpIHsNCgkJCQlBbGxDcmVh dGVkSXRlbXMuQWRkKHRoaXMpOw0KCQkJfQ0KCQl9DQoNCg0KCQlwdWJsaWMgdmlydHVhbCB2b2lk IHZhbGlkYXRlKCkgew0KCQkJaWYgKHJlcG9ydEFsc29JZlZhbGlkYXRpb25PSykgew0KCQkJCWRl YnVnbXNnKCJ2YWxpZGF0aW5nLi4uIiArIGNsYXNzTmFtZQ0KCQkJCQkrICIgKCIgKyBhc05hbWVP cklkZW50Q29udGVudHMoKSArICIpIik7DQoJCQl9DQoJCQltaHBfbWhrKCk7DQoJCQlraWRzLnZh bGlkYXRlKCk7DQoJCQkvLyB2YWxpZGF0ZWQgPSB0cnVlOyAtLSBObywgZ2V0IGVhY2ggc3ViY2xh c3MgdG8gc2V0DQoJCQkvLyB2YWxpZGF0ZWQuIFRoYXQgZm9yY2VzIGFuIGV4cGxpY2l0IGNhbGwg dG8gYmFzZSgpIHdoaWNoDQoJCQkvLyBpcyBtb3JlIGNvZGUgYnV0IG9rLg0KCQl9DQoNCg0KCQlw dWJsaWMgYm9vbCBpc1ZhbGlkYXRlZCB7IGdldCA9PiB2YWxpZGF0ZWQ7IH0gIC8vIHRvZG8ganVz dCA9PiB2YWxpZGF0ZWQ7DQoNCg0KCQlwdWJsaWMgdmlydHVhbCBib29sIGlzVG9wTGV2ZWxJdGVt U2VxID0+IGZhbHNlOw0KDQoNCgkJcHVibGljIHZpcnR1YWwgdm9pZCBtaHBfbWhrKCkgeyAgLy8g ZG9uJ3QgdGhpbmsgdGhpcyBuZWVkIGJlIHZpcnR1YWwgLSB0b2RvPw0KCQkJCQkJCQkJCSAvLyA9 IG11c3QgaGF2ZSBwYXJlbnQsIG11c3QgaGF2ZSBraWRzLiBUaGUga2lkcyBtYXkgYmUgdGhlDQoJ CQkJCQkJCQkJIC8vIGVtcHR5IHNldCBhbmQgdGhlIHBhcmVudCBtYXkgYmUgbm9QYXJlbnQgYnV0 IHRoZXkgbXVzdA0KCQkJCQkJCQkJCSAvLyBleGlzdC4NCgkJCQkJCQkJCQkgLy8gV2h5IG5vdCBq dXN0IGlubGluZSB0aGlzIGludG8gdmFsaWRhdGUoKT8NCgkJCQkJCQkJCQkgLy8gQmVjYXVzZSBh IGZldyBjbGFzc2VzIG5lZWQgYmVzcG9rZSB2YWxpZGF0aW9uLCBidXQgc3RpbGwgbXVzdCBjaGVj ayB0aGlzLg0KCQkJaGFyZE11c3RQYXJlbnRJc1ByZXNlbnQoKTsNCgkJCWtpZHMuZWFjaEtpZFBh cmVudE11c3RCZSh0aGlzKTsNCgkJfQ0KDQoNCgkJcHVibGljIHN0cmluZyBhc05hbWVPcklkZW50 Q29udGVudHMoKSB7DQoJCQkvLyBmb3IgdmVyeSBjcnVkZSBkZWJ1Z2dpbmcgDQoJCQl2YXIgb3B0 TmFtZSA9IHRoaXMgaXMgSWlzTmFtZWRJdGVtIG5pID8gbmkubmFtZS50b1Jhd1N0cigpIDogIiI7 DQoJCQlvcHROYW1lID0gKG9wdE5hbWUgPT0gIiIgJiYgdGhpcyBpcyBQTVFJZGVudCkgPyB0aGlz LnRvUmF3U3RyKCkgOiAiIjsNCg0KCQkJdmFyIG9wdE5hbWUyID0gb3B0TmFtZSArICIgICh1aWQ6 IiArIHVpZC5Ub1N0cmluZygpICsgIikgIg0KCQkJCSsgZ2V0Rmlyc3RGZXdDaGFyc09mKHRvUmF3 U3RyKCkpOw0KCQkJcmV0dXJuIG9wdE5hbWUyOw0KCQl9DQoNCg0KCQlwdWJsaWMgdmlydHVhbCB2 b2lkIGdldEFsbFVJRHMoVUlEc2V0IHVpZHMpIHsNCgkJCXVpZHMuQWRkKHRoaXMpOw0KCQkJa2lk cy5Gb3JFYWNoKG5hbWVkS2lkID0+IG5hbWVkS2lkLmtpZC5nZXRBbGxVSURzKHVpZHMpKTsNCgkJ fQ0KDQoNCgkJcHVibGljIGJvb2wgaXNTdHViUGFyZW50IHsgZ2V0ID0+ICh0aGlzIGlzIE5vUGFy ZW50KSB8fCAodGhpcyBpcyBGYWtlUGFyZW50KTsgfQ0KDQoNCgkJcHVibGljIHZvaWQgdmFsaWRh dGVTcGVjaWZpY0l0ZW1zKHBhcmFtcyBMREJBU1RvYmpbXSBpdGVtcykgew0KCQkJQXJyYXkuRm9y RWFjaChpdGVtcywgaXRlbSA9PiBpdGVtLnZhbGlkYXRlKCkpOw0KCQl9DQoNCg0KCQlwdWJsaWMg VD8gb3B0Q2xpbWJUbzxUPigpIHdoZXJlIFQgOiBMREJBU1RvYmogew0KCQkJdmFyIHJlc0l0ZW0g PSB0aGlzOw0KCQkJd2hpbGUgKCEocmVzSXRlbSBpcyBUKSkgew0KCQkJCWlmIChyZXNJdGVtLnBh cmVudC5pc1N0dWJQYXJlbnQpIHsNCgkJCQkJcmV0dXJuIG51bGw7DQoJCQkJfQ0KCQkJCXJlc0l0 ZW0gPSByZXNJdGVtLnBhcmVudDsNCgkJCX0NCg0KCQkJdmFyIHJlcyA9IHJlc0l0ZW0gYXMgVDsN CgkJCXJldHVybiByZXM7DQoJCX0NCg0KDQoJCXB1YmxpYyBUIHJlcUNsaW1iVG88VD4oKSB3aGVy ZSBUIDogTERCQVNUb2JqIHsNCgkJCXZhciBsb2MgPSBjbGFzc05hbWUgKyAiLnJlcUNsaW1iVG88 VD4oKSI7DQoJCQl2YXIgcmVzID0gb3B0Q2xpbWJUbzxUPigpOw0KCQkJaGFyZE11c3QyKCEocmVz IGlzIG51bGwpLCANCgkJCQkvLyBUaGFua3MgU08gPGh0dHBzOi8vc3RhY2tvdmVyZmxvdy5jb20v cXVlc3Rpb25zLzI1ODE2NDIvaG93LWRvLWktZ2V0LXRoZS10eXBlLW5hbWUtb2YtYS1nZW5lcmlj LXR5cGUtYXJndW1lbnQ+DQoJCQkJLy8gVG9kbyAtIHVzZSB0aGlzIGVsc2V3aGVyZSwgcG9zcyBF eHBlY3RFeGNlcHRpb24/IHRvZG8NCgkJCQkoKSA9Pg0KCQkJCWxvYyANCgkJCQkrIG5sICsgIiwg Y2xpbWJlZCB0byB0b3AsIGRpZG4ndCBmaW5kIHR5cGUgIg0KCQkJCSsgdHlwZW9mKFQpLkZ1bGxO YW1lDQoJCQkJKyBubCArICJIaWVyYXJjaHkgaXM6ICINCgkJCQkrIG5sICsgZ2V0SXRlbVdpdGhQ YXJlbnRzKHRoaXMpKTsNCgkJCWlmIChyZXMgaXMgbnVsbCkgeyB0aHJvdyBuZXcgTk5RQygpOyB9 DQoJCQlyZXR1cm4gcmVzOw0KCQl9DQoNCg0KCQlwdWJsaWMgdm9pZCBoYXJkTXVzdFBhcmVudElz UHJlc2VudCgpIHsNCg0KCQkJaGFyZE11c3QyKCEocGFyZW50IGlzIG51bGwpLCANCgkJCQkoKSA9 Pg0KCQkJCSAiTlVMTCBwYXJlbnQgZm9yIGl0ZW0gb2YgdHlwZVxuIg0KCQkJCSArICQie0dldFR5 cGUoKX1cbi4iKTsNCg0KCQkJaGFyZE11c3QyKCEodGhpcy5wYXJlbnQgaXMgTm9QYXJlbnQpLA0K CQkJCSgpID0+DQoJCQkJIlBhcmVudCBpcyBOb1BhcmVudCBvbiBvYmplY3Qgb2YgdHlwZVxuIg0K CQkJCSsgJCIne3RoaXMuY2xhc3NOYW1lfSciKTsNCgkJfQ0KDQoNCgkJcHVibGljIHZvaWQgaGFy ZE11c3RQYXJlbnRJc0Fic2VudCgpIHsNCgkJCS8vIEZvciBjaGVja2luZyBjbG9uaW5nIC0gcGFy ZW50IHNob3VsZCBiZSBOb1BhcmVudCBpbW1lZGlhdGVseSANCgkJCS8vIGFmdGVyLCBiZWZvcmUg aXQncyBzZXQgYnkgcGFyZW50LCBhbmQgbmV2ZXIgbnVsbA0KCQkJaGFyZE11c3QoIShwYXJlbnQg aXMgbnVsbCksDQoJCQkJICJOVUxMIHBhcmVudCBmb3IgaXRlbSBvZiB0eXBlXG4iDQoJCQkJICsg JCJ7R2V0VHlwZSgpfVxuLiIpOw0KCQkJaGFyZE11c3QoKHRoaXMucGFyZW50IGlzIE5vUGFyZW50 KSwNCgkJCQkiUGFyZW50IHNob3VsZCBiZSBOb1BhcmVudCBvbiBvYmplY3Qgb2YgdHlwZVxuIg0K CQkJCSsgJCIne3RoaXMuY2xhc3NOYW1lfSciKTsNCgkJfQ0KDQoNCgkJcHVibGljIGJvb2wgaGFz UGFyZW50PFA+KCkgew0KCQkJaGFyZE11c3QoISh0aGlzIGlzIE5vUGFyZW50KSwgIkl0ZW0gaXMg Tm9QYXJlbnQiKTsNCgkJCXJldHVybiB0aGlzLnBhcmVudCBpcyBQOw0KCQl9DQoNCg0KCQlwdWJs aWMgYm9vbCBoYXNBbmNlc3RvcjxBPigpIHsNCgkJCWhhcmRNdXN0KCF0aGlzLmlzU3R1YlBhcmVu dCwgIkl0ZW0gaXMgTm9QYXJlbnQiKTsNCg0KCQkJLy8gaG93IHRvIGRvIHdpdGggYSBzd2l0Y2gg ZXhwcj8NCgkJCWlmICh0aGlzLnBhcmVudC5pc1N0dWJQYXJlbnQgLyogaXMgTm9QYXJlbnQgfHwg dGhpcy5wYXJlbnQgaXMgRmFrZVBhcmVudCovICkgeyAvLyB0b2RvIGRvIGFzIHguaGFzRnVkZ2Vk UGFyZW50KCkgLSB0b2RvDQoJCQkJcmV0dXJuIGZhbHNlOw0KCQkJfSBlbHNlIGlmICh0aGlzLnBh cmVudCBpcyBBKSB7DQoJCQkJcmV0dXJuIHRydWU7DQoJCQl9IGVsc2Ugew0KCQkJCXJldHVybiB0 aGlzLnBhcmVudC5oYXNBbmNlc3RvcjxBPigpOw0KCQkJfQ0KCQl9DQoNCgkJcHVibGljIGJvb2wg bm90SGFzQW5jZXN0b3I8QT4oKSA9Pg0KCQkJIWhhc0FuY2VzdG9yPEE+KCk7DQoNCg0KCQlwdWJs aWMgdm9pZCBzZXRNeVBhcmVudFRvKExEQkFTVG9iaiBwcm50KSB7DQoJCQkvLyBBbiBvYmplY3Qg bWF5IG9ubHkgc2V0IGl0cyBwYXJlbnQgaWYgaXRzIGN1cnJlbnQgcGFyZW50IGlzDQoJCQkvLyB0 aGUgZHVtbXkgJ25vUGFyZW50Jywgd2hpY2ggYWxtb3N0IGV2ZXJ5IG9iamVjdCdzIHBhcmVudCBp cw0KCQkJLy8gc2V0IHRvIG9uIGNyZWF0aW9uIChzZWUgTERCQVNUb2JqIHBhcmVudCBwcm9wZXJ0 eSBkZWYpLg0KDQoJCQkvLyBUaGUgdGVzdCBmb3IgbnVsbCBpcyBwZWN1bGlhciBnaXZlbiB0aGlz LiBCZWNhdXNlDQoJCQkvLyBub1BhcmVudCBpcyBjcmVhdGVkIHN0YXRpY2FsbHksIHNldHRpbmcg dGhlIHBhcmVudCBvZg0KCQkJLy8gbm9QYXJlbnQgaXMgZGlmZmljdWx0LCBwZXJoYXBzIGltcG9z c2libGUsIHRvIGRvIHN0YXRpY2FsbHkNCgkJCS8vIGFuZCByZWxpYWJseS5EZXNwaXRlIHRoZSBk ZWNsYXJhdGlvbiAnI251bGxhYmxlIGVuYWJsZScsIGl0DQoJCQkvLyBnZXRzIGNyZWF0ZWQgd2l0 aCBhIG51bGwgcGFycmVudCAocXVpdGUgcmVhc29uYWJseSksIGhlbmNlDQoJCQkvLyB0aGlzIGNo ZWNrLlRoZSBhY3R1YWwgc2V0dGluZyBvZiB0aGUgcGFyZW50IGhhcyB0byBiZSBkb25lDQoJCQkv LyBhdCBydW50aW1lIGkuZS5hZnRlciB0aGUgc3RhdGljIGNyZWF0aW9uIG9mICdub1BhcmVudCcu DQoNCgkJCWhhcmRNdXN0MigodGhpcy5wYXJlbnQgaXMgTm9QYXJlbnQpIHx8ICh0aGlzLnBhcmVu dCBpcyBudWxsKSwNCgkJCQkoKSA9Pg0KCQkJCSJ0cmllZCB0byByZS1zZXQgcGFyZW50IG9uIG9i amVjdCBvZiB0eXBlOiAiDQoJCQkJKyBubCArIHRoaXMuY2xhc3NOYW1lUQ0KCQkJCSsgbmwgKyAi T3JpZ2luYWwgcGFyZW50IHR5cGUgaXM6ICINCgkJCQkrICh0aGlzPy5wYXJlbnQ/LmNsYXNzTmFt ZVEgPT0gbnVsbCA/ICJudWxsIiA6IHRoaXMucGFyZW50LmNsYXNzTmFtZVEpDQoJCQkJKyBubCAr ICJhbmQgbmV3IHBhcmVudCB0eXBlIGlzOiAiDQoJCQkJKyBwcm50LmNsYXNzTmFtZVENCgkJCQkr IG5sICsgIkl0ZW0gaGF2aW5nIHBhcmVudCBzZXQgb24gaXQgaXM6ICINCgkJCQkvLyBiZWNhdXNl IG9iamVjdCBtYXkgbm90IGJlIGZ1bGx5IGNvbnN0cnVjdGVkIHlldCwgY2hlY2sgaG93dmVyIFRP RE8gdGhpcyBpcyBhIG1ham9yIGhhY2sgYW5kIG11c3QgYmUgZml4ZWQgc29tZXRpbWUuDQovLwkJ CQkrIG5sICsgKHRoaXMgaXMgbnVsbCA/ICIobnVsbCkiIDogdGhpcy50b1Jhd1N0cigpKSk7DQoJ CQkJKyBubCArIHRoaXMudG9SYXdTdHIoKSApOw0KDQoJCQlwYXJlbnQgPSBwcm50Ow0KCQl9DQoN Cg0KCQlwdWJsaWMgdm9pZCBmb3JjZU5ld1BhcmVudEZvclJvb3RPYmplY3QoKSB7DQoJCQkvLyBF dmVyeSBvYmplY3QgbXVzdCBoYXZlIHNvbWUgcGFyZW50LCBpbmNsdWRpbmcgdGhlDQoJCQkvLyBy b290IG9iamVjdCBvZiB0aGUgcGFyc2UsIHdoaWNoIGlzIExEQml0ZW1zDQoJCQkvLyAoYSBzZXF1 ZW5jZSBvZiBMREIgaXRlbXMpLCBzbyB0aGlzIGZvcmNlcyBvbmUuDQoJCQkvLyBJdCBpcyBvbmx5 IGZvciB0aGF0IHB1cnBvc2UhDQoJCQkvLyANCgkJCS8vIExEQml0ZW1zIG9iaiBleGlzdHMgZm9y IHN1YiBvYmpzIHN1Y2ggYXMgdGhlIHN0YXRlbWVudHMNCgkJCS8vIGluIGEgd2hpbGUgbG9vcCwg aW4gYSBwcm9jLCBpbiBhbiBpZi4uLiBldGMuLCBmb3INCgkJCS8vIHdoaWNoIHRoZWlyIHBhcmVu dCBpcyB0aGUgd2hpbGUvcHJvYy9pZiBldGMuDQoJCQloYXJkTXVzdFBhcmVudElzQWJzZW50KCk7 DQoJCQl0aGlzLnBhcmVudCA9IGZha2VQYXJlbnQ7DQoJCX0NCg0KDQoJCS8vcHVibGljIHZvaWQg cmVzZXRNeVBhcmVudFRvKExEQkFTVG9iaiBwcm50KSB7ICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8v Ly8vLy8vLy8vLy8vIGRlc3Ryb3khISEhISEgdG9kbw0KCQkvLwlwYXJlbnQgPSBwcm50Ow0KCQkv L30NCg0KCQkvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8geHh4eHh4eHh4eHh4eCBkZWxldGUgLSB0 b2RvDQoJCS8vcHJpdmF0ZSB2b2lkIHNldFBhcmVudE9uS2lkKExEQkFTVG9iaiBraWQpID0+IC8v IHRvZG8gbmVlZGVkPw0KCQkvLwkJCQkJCQkJCQkJICAvLyBjaGVjayBwYXJlbnRlIGRvZXNuJ3Qg ZXhpc3QgLSB0b2RvDQoJCS8vCWtpZC5wYXJlbnQgPSB0aGlzOw0KDQoJCXB1YmxpYyB2aXJ0dWFs IHZvaWQgc2V0UGFyZW50T25LaWRzQW5kTWFrZUtpZHNEaWN0KCAgLy8gdG9kbyAtIGFuZCBhZGQg dG8ga2lkcyBkaWN0DQoJCQkJCQkJCQkJCQkJCQkgLy8gdGhpcyBtaXhlcyB1cCBzZXR0aW5nIHBh cmVudCBhbmQgbWFraW5nIGNoaWxkIGRpY3QuIE5vdCBnb29kLiAtIHRvZG8NCgkJCQkJCXBhcmFt cyAoc3RyaW5nIGtpZE5hbWUsIExEQkFTVG9iaiBraWQpW10ga2lkc0luKSB7DQoJCQl2YXIgbG9j ID0gY2xhc3NOYW1lUGx1cygic2V0UGFyZW50T25LaWRzQW5kTWFrZUtpZHNEaWN0Iik7DQoNCgkJ CXZhciBraWRzVG9BZGQgPSBuZXcgTERCU3RydWN0c0NoaWxkcmVuKHRoaXMsIGtpZHNJbik7DQoJ CQloYXJkTXVzdDIoa2lkcy5pc0VtcHR5LA0KCQkJCSgpID0+DQoJCQkJJCJzZXR0aW5nIGtpZHMg b24gcGFyZW50ICd7Y2xhc3NOYW1lfSciIA0KCQkJCSsgIndoZW4ga2lkcyBpcyBub3QgZW1wdHks ICINCgkJCQkrICQia2lkcyBpcyAoe2tpZHMuQ291bnR9IGtpZHMpOiINCgkJCQkrIG5sICsga2lk cy50b0RlYnVnU3RyKCkNCgkJCQkrIG5sICsgJCJUcnlpbmcgdG8gYWRkXG57a2lkc1RvQWRkLnRv RGVidWdTdHIoKX1cbiINCgkJCQkrICQiaW4ge2NsYXNzTmFtZX0iKTsNCgkJCS8vIGlmIHRoZXJl IGlzIGFuIExEQlN0cnVjdHNDaGlsZHJlbiBhbmQgYW5vdGhlciBjaGlsZCwNCgkJCS8vIHRoaXMg d2lsbCBibG93IHVwIC0gd2lsbCBuZWVkIHRvIGRvIGtpZHMuQWRkIG9yDQoJCQkvLyBzb21ldGhp bmcgLSBpbiBmYWN0LCBraWRzIG5lZWRzIHRvIGJlIGNyZWF0ZWQgaW4gb25lDQoJCQkvLyBnbywg d2hpY2ggaXMgd2hhdCBoYXBwZW5zLg0KCQkJa2lkcyA9IGtpZHNUb0FkZDsgICAgLy8vLy8vLy8v Ly8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vIHdoeSB0aGlz PyB0b2RvDQoJCQlBcnJheS5Gb3JFYWNoKGtpZHNJbiwgeGtpZCA9PiBoYXJkTXVzdCghKHhraWQu a2lkIGlzIG51bGwpLCBsb2MsICJudWxsIGtpZCIpKTsNCgkJCUFycmF5LkZvckVhY2goa2lkc0lu LCB4a2lkID0+IHhraWQua2lkLnNldE15UGFyZW50VG8odGhpcykpOw0KCQl9DQoNCg0KCQlwdWJs aWMgdmlydHVhbCB2b2lkIHNldFBhcmVudE9uS2lkc0FuZEFkZFRvS2lkc0RpY3QoDQoJCQkJCXBh cmFtcyAoc3RyaW5nIGtpZE5hbWUsIExEQkFTVG9iaiBraWQpW10ga2lkc0luKSB7DQoJCQl2YXIg a2lkc1RvQWRkX2p1c3RGb3JFcnJSZXBvcnRpbmcgPSBuZXcgTERCU3RydWN0c0NoaWxkcmVuKHRo aXMsIGtpZHNJbik7DQoJCQloYXJkTXVzdDIoIWtpZHMuaXNFbXB0eSwgLy8gbWF5IGRpc2FibGUg dGhpcyBsYXRlciANCgkJCQkoKSA9Pg0KCQkJCSJhZGRpbmcgdG8ga2lkcyB3aGVuIGtpZHMgaXMg ZW1wdHksICINCgkJCQkgKyAkImtpZHMgaXNcbntraWRzLnRvRGVidWdTdHIoKX1cbiINCgkJCQkg KyAkIlRyeWluZyB0byBhZGRcbntraWRzVG9BZGRfanVzdEZvckVyclJlcG9ydGluZy50b0RlYnVn U3RyKCl9XG4iDQoJCQkJICsgJCJpbiB7Y2xhc3NOYW1lfSIpOw0KCQkJQXJyYXkuRm9yRWFjaChr aWRzSW4sIHhraWQgPT4gew0KLy8JCQkJc2V0UGFyZW50T25LaWQoeGtpZC5raWQpOw0KCQkJCXhr aWQua2lkLnNldE15UGFyZW50VG8odGhpcyk7DQoJCQkJa2lkcy5BZGQoeGtpZCk7DQoJCQl9KTsN CgkJfQ0KDQoNCgkJcHVibGljIHZpcnR1YWwgSWRlbnRzVXNlZCBnZXRBbGxJRHMoKSB7DQoJCS8q IFRoaXMgaXMgb3ZlcnJpZGRlbiBvbmx5IGluIFRlbXBsYXRlZEFnZywgYW5kIHRoYXQncyBvbmx5 IHRvIA0KCQkJZGVsaWJlcmF0ZWx5IGZhaWwuIFRoZXJlJ3Mgc29tZXRoaW5nIHdyb25nIHRoZXJl LCB0b2RvIC0gDQoJCQl1bi12aXJ0dWFsaXNlIHRoaXMgYW5kIHJlbW92ZSB0aGUgb25lIG92ZXJy aWRlLiAtIHRvZG8NCgkJKi8NCgkJCXZhciBpdSA9IG5ldyBJZGVudHNVc2VkKCk7DQoJCQl0aGlz Ll9nZXRBbGxJRHMoaXUpOw0KCQkJcmV0dXJuIGl1Ow0KCQl9DQoNCgkJcHVibGljIHZpcnR1YWwg dm9pZCBfZ2V0QWxsSURzKElkZW50c1VzZWQgaXUpIHsNCgkJLy8gR2V0cyBhbGwgdGhlIGlkZW50 aWZpZXJzIGV4cGxpY2l0bHkgdXNlZCAocmVhZCBvciB3cml0dGVuKSAgLS0tLS0gdG9kbyB1cGRh dGUgdGhpcw0KCQkvLyBhbnl3aGVyZSBpbiB0aGUgQVNULiAgRG9lcyBub3QgZ2V0IGlkZW50cyB3 aGljaCBhcmUNCgkJLy8gZGVjbGFyYXRpb25zIGllLiBwYXJhbWV0ZXJzLCBvciB2YXIvY29uc3Qg ZGVjbGFyYXRpb25zDQoJCS8vIHVubGVzcyB0aGVzZSBhcmUgY29tYmluZWQgd2l0aCBhbiBhc3Np Z25tZW50Lg0KCQkvLw0KCQkvLyBJbXBsaWVkIGlkZW50cyBzdWNoIGFzIHRob3NlIGZyb20gdGJs LiogYXJlIGltcGxpY2l0IGFuZCBpZ25vcmVkLg0KCQkvLw0KCQkvLyBSb290IGNhbGxlciBzdXBw bGllcyBuZXcsIGVtcHR5IGl1DQoJCS8vIG5lZWQgdXNhZ2UgaGVyZSAtIHRvZG8gZG9jcy8vDQoJ CQlraWRzLl9nZXRBbGxJRHMoaXUpOw0KCQl9DQoNCgkJcHVibGljIGFic3RyYWN0IGJvb2wgY2Fu R2V0QWxsSWRlbnRzVXNlZCB7DQoJCS8vIAlUaGlzIHNlZW1zIHRvIGJlIHRydWUgb24gbW9zdCBj bGFzc2VzIHNvIEkgY291bGQgc2V0IHRydWUgDQoJCS8vIGFzIGEgZGVmYXVsdCBoZXJlIGFuZCBv dmVycmlkZSBpdCB3aGVyZSBpdCdzIG5vdCB3YW50ZWQsIHNhdmluZyANCgkJLy8gYSBjaHVuayBv ZiBjb2RlLCBidXQgSSdkIHJhdGhlciBtYWtlIGl0IGV4cGxpY2l0IHRvIGZvcmNlIG1lIHRvIGNv bnNpZGVyIGVhY2ggY2FzZS4gQSBiaXQgbW9yZSBDJlAgZm9yIGxlc3MgY2hhbmNlIG9mIGJ1Z3Mu DQoJCQlnZXQ7DQoJCX0NCg0KDQoJCS8vIFByb2R1Y2VzIGEgc3RyaW5nIHRoYXQgc2hvdWxkIGJl IGlkZW50aWNhbCB0byAoZXhjZXB0aW5nDQoJCS8vIHdoaXRlc3BhY2VzKSB0aGUgaW5wdXQgaWUu IGVtaXQgTERCIGNvZGUgbm90IHZhbGlkIFNRTA0KCQkvLw0KCQkvLyBUb1N0cmluZyB3YXMgY2F1 c2luZyB0b28gbWFueSB3ZWlyZCBwcm9ibGVtcyAoZHVlIHRvIG15DQoJCS8vIGluZXhwZXJpZW5j ZSB3aXRoIGMjKSBzbyBqdXN0IHVzZWQgdG9SYXdTdHIoKQ0KCQlwdWJsaWMgYWJzdHJhY3Qgc3Ry aW5nIHRvUmF3U3RyKCk7DQoNCgkJcHVibGljIG92ZXJyaWRlIHN0cmluZyB0b0RlYnVnU3RyKCkg PT4gdG9SYXdTdHIoKTsNCg0KCX0gLy8gZW5kIExEQkFTVG9iag0KDQoNCg0KCXB1YmxpYyBpbnRl cmZhY2UgSWhhbmRsZVByZWZpeGVzPFQ+DQoJCQkJCQl3aGVyZSBUIDogTERCUm9vdCB7DQoNCgkJ cHVibGljIGJvb2wgaXNQcmVmaXhlZCB7IGdldDsgfQ0KDQoJCXB1YmxpYyBib29sIGlzRXhjZXNz UHJlZml4ZWQgeyBnZXQ7IH0NCg0KCQkvLyBUaGUgVCBpbiBhZGRQcmVmaXgvcmVQcmVmaXgvd2l0 aG91dFByZWZpeCBpcyBiZWNhdXNlIHdlIG1heSBiZSANCgkJLy8gcmV0dXJuaW5nIGVnLiBhIGxp c3Qgb2YgaXRlbXMgd2l0aCBwcmVmaXhlcyANCgkJLy8gdGh1cyBtb2RpZmllZCwgbm90IGEgc2lu Z2xlIFBNUUlkZW50DQoNCgkJcHVibGljIFQgYWRkUHJlZml4KFBNUUlkZW50IHBmeCk7DQoNCgkJ cHVibGljIFQgcmVQcmVmaXgoUE1RSWRlbnQgbmV3cGZ4KTsNCg0KLy8JCXB1YmxpYyBUIHN0cmlw UHJlZml4KFBNUUlkZW50IGlkKTsNCgl9DQoJLy8gdG9kbyAtIG1vdmUgdGhpcw0KDQoNCg0KDQoN CglwdWJsaWMgYWJzdHJhY3QgY2xhc3MgTERCUm9vdCB7DQoJCS8vIFJvb3Qgb2YgZXZlcnl0aGlu ZyBMREItaXNoDQoNCgkJcHVibGljIGJvb2wgRXF1YWxzKFtBbGxvd051bGxdIExEQlJvb3Qgb3Ro ZXIpIHsNCgkJCXRocm93IG5ldyBMREJTaG91bGROb3RCZUltcGxlbWVudGVkRXhjZXB0aW9uKA0K CQkJCQkJCQkJImNhbGxlZCBFcXVhbHMgb24gTERCUm9vdCIpOw0KCQl9DQoNCgkJcHVibGljIG92 ZXJyaWRlDQoJCQlib29sIEVxdWFscyhbQWxsb3dOdWxsXSBPYmplY3Qgb3RoZXIpIHsNCgkJCXRo cm93IG5ldyBMREJTaG91bGROb3RCZUltcGxlbWVudGVkRXhjZXB0aW9uKA0KCQkJCQkJCQkJImNh bGxlZCBFcXVhbHMgaW4gT2JqZWN0Iik7DQoJCX0NCg0KCQlwdWJsaWMgb3ZlcnJpZGUgaW50IEdl dEhhc2hDb2RlKCkgew0KCQkJdGhyb3cgbmV3IExEQlNob3VsZE5vdEJlSW1wbGVtZW50ZWRFeGNl cHRpb24oDQoJCQkJCQkJCQkiY2FsbGVkIEdldEhhc2hDb2RlIGluIExEQlJvb3QiKTsNCgkJfQ0K DQoJCXB1YmxpYyBzdGF0aWMgYm9vbCBvcGVyYXRvciA9PShMREJSb290IGxocywNCgkJCQkJCQkJ CSAgIExEQlJvb3QgcmhzKSB7DQoJCQl0aHJvdyBuZXcgTERCU2hvdWxkTm90QmVJbXBsZW1lbnRl ZEV4Y2VwdGlvbigNCgkJCQkJCQkJCSJjYWxsZWQgPT0gaW4gTERCUm9vdCIpOw0KCQl9DQoNCgkJ cHVibGljIHN0YXRpYyBib29sIG9wZXJhdG9yICE9KExEQlJvb3QgbGhzLA0KCQkJCQkJCQkJICAg TERCUm9vdCByaHMpIHsNCgkJCXRocm93IG5ldyBMREJTaG91bGROb3RCZUltcGxlbWVudGVkRXhj ZXB0aW9uKA0KCQkJCQkJCQkJImNhbGxlZCAhPSBpbiBMREJSb290Iik7DQoJCX0NCg0KDQoJCXB1 YmxpYyB2aXJ0dWFsIHN0cmluZyBjbGFzc05hbWUgew0KCQkJLy8gdG9kbyAtIHRoaXMgbmVlZHMg Y2hlY2tpbmcgaXQgd29ya3MgYXMgSSB3YW50DQoJCQkvLyBhbHNvIHJlbmFtZSB0byBsZGJjbGFz c25hbWUgLS0gdG9kbw0KCQkJZ2V0ID0+IHRoaXMuR2V0VHlwZSgpLkZ1bGxOYW1lID8/ICIodW5r bm93bikiOw0KCQl9DQoNCg0KCQlwdWJsaWMgdmlydHVhbCBzdHJpbmcgY2xhc3NOYW1lUSA9Pg0K CQkJIiciICsgY2xhc3NOYW1lICsgIiciOw0KDQoNCgkJcHVibGljIHZpcnR1YWwgc3RyaW5nIGNs YXNzTmFtZVBsdXMoc3RyaW5nIHBsdXMpID0+DQoJCQljbGFzc05hbWUgKyAiLiIgKyBwbHVzOw0K DQoJCXB1YmxpYyBvdmVycmlkZSBzdHJpbmcgVG9TdHJpbmcoKSB7DQoJCQkvLyBUaGlzIGltcGxp Y2l0IHRvLXN0cmluZyBjb252ZXJzaW9uIGNyYXAgY29zdCBtZSBhIGZldyBob3Vycywgc28gYXQg bGVhc3QNCgkJCS8vIGRvIHRoaXMgJiBibG93IHVwIGF0IHJ1bnRpbWUuIFdvdWxkIHByZWZlciBj b21waWxlIHRpbWUgYnV0IGl0IHNlZW1zDQoJCQkvLyBub3QgcG9zc2libGUuICBUaGlzIHR1cm5z IG91dCB0byBoYXZlIGJlZW4gYSBnb29kIGlkZWEsDQoJCQkvLyBzYXZlZCBtZSBxdWl0ZSBhIGJp dCBtb3JlIGRlYnVnZ2luZyENCgkJCS8vIDxodHRwczovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0 aW9ucy8xNTM0NTUxNy9pcy1pdC1wb3NzaWJsZS10by1kaXNhYmxlLWltcGxpY2l0LXRvc3RyaW5n LWNhbGw+DQoJCQkvLyBXaWxsIHRyeSA8aHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlv bnMvNTQzNTQzNDIvaG93LXRvLWdldC1hbi1lcnJvci1zaG93bi13aGVuLXVzaW5nLW5vbi1zdHJp bmdzLWFzLXN0cmluZ3MtaW5zdGVhZC1vZi1hbi1hdXRvbS81NDM1NTExNSM1NDM1NTExNSkNCgkJ CXZhciBtc2cgPSAiTERCUm9vdC5Ub1N0cmluZygpIjsNCgkJCXRocm93IG5ldyBMREJUb1N0cmlu Z0ltcGxpY3RDb252ZXJzaW9uRXhjZXB0aW9uKG1zZyk7DQoJCX0NCg0KCQlwdWJsaWMgYWJzdHJh Y3Qgc3RyaW5nIHRvRGVidWdTdHIoKTsNCgl9DQoNCg0KDQoJcHVibGljIGFic3RyYWN0IGNsYXNz IEVwaGVtZXJhbCA6IExEQlJvb3Qgew0KCQkvLyBmb3Igb2JqZWN0cyB0aGF0IGFyZSBub3QgcGFy dCBvZiB0aGUgQVNUDQoJfQ0KDQoNCg0KCXB1YmxpYyBpbnRlcmZhY2UgSVdpdGhMaW5lTlVtIHsg IC8vIHRvZG8gLSB1c2Ugb3IgcmVtb3ZlIC0gdG9kbw0KCQkvLwlwdWJsaWMgDQoJfQ0KDQoNCglw dWJsaWMgaW50ZXJmYWNlIElIYXNUYWJsZUFsaWFzIHsNCgkJLy8gSGFzIGEgdGFibGUgYWxpYXMg QVNUIG9iai4gTWF5IGJlIGEgLi4uTWlzc2luZyBzdWJ0eXBlIGluIHdoaWNoDQoJCS8vIGl0IGhh cyBubyBhbGlhcyBnaXZlbiBieSB0aGUgdXNlciwgYnV0IGFsaWFzIEFTVCBpcyB0aGVyZS4gTW9y ZQ0KCQkvLyBhY2N1cmF0ZWx5IGEgVGFibGVTb3VyY2UgYWxpYXMgYnV0IG9rDQoJCXB1YmxpYyBh YnN0cmFjdCBUYWJsZUFsaWFzIHRhIHsgZ2V0OyBzZXQ7IH0NCgl9DQoNCg0KCS8vIEJhc2UgY2xh c3MgZm9yIGFsbCBMREIgQVNUIG9iamVjdHMNCglwdWJsaWMgYWJzdHJhY3QgY2xhc3MgTERCQVNU b2JqIDogTERCUm9vdCB7DQoJCS8vIFRoaXMgb25lIGlzIGEgcHJvYmxlbS4gSWYgSSBkZWNsYXJl IHRoZSAncGFyZW50JyBwcm9wZXJ0eQ0KCQkvLyBhYnN0cmFjdCBJIHRoZW4gaGF2ZSB0byBpbXBs ZW1lbnQgaXQgbGl0ZXJhbGx5IGh1bmRyZWRzIG9mDQoJCS8vIHRpbWVzIGluIHRoZSBkZXJpdmVk IGNsYXNzZXMsIGFuZCBJIHJlYWxseSBkb24ndCB0aGluayBpdA0KCQkvLyB3b3VsZCBoZWxwIHNv IGp1c3Qgc2V0IGl0IHRvIGEgZGVmYXVsdCB3aGljaCBnZXRzIG92ZXJ3cml0dGVuIGxhdGVyLg0K CQkvLyANCgkJLy8gVGhlIHByb2JsZW0gaXMgdGhhdCB0aG9zZSBvYmplY3RzIHdlcmUgY3JlYXRl ZCBieSB0aGUNCgkJLy8gcGFyc2VyLCB3aGljaCBjcmVhdGVzIHRoZW0gYm90dG9tLXVwLCB3aGlj aCBtZWFucyB5b3UgY2FuJ3QNCgkJLy8ga25vdyB0aGUgcGFyZW50IHdoZW4gdGhleSBhcmUgY3Jl YXRlZC4gSXQgc2hvdWxkIGJlDQoJCS8vIHBvc3NpYmxlIHRvIHdvcmsgYXJvdW5kIHRoaXMgYnV0 IGl0IGRvZXMgbWVhbiByZXdvcmtpbmcgdGhlDQoJCS8vIHBhcnNlciBmdW5kYW1lbnRhbGx5LCBh bmQgSSdtIG5vdCBnb2luZyB0byBkbyB0aGF0DQoJCS8vIGFzc3VtZWluZyBpdCdzIGV2ZW4gcG9z c2libGUuDQoNCgkJLy8gdG9kbyAtIHJlYWQgdXAgb24gcHJpdi9wdWIvcHJvZyBhY2Nlc3NvcnMg SSByZWFsbHkgZG9uJ3QNCgkJLy8gZ2V0IHRoZXNlIGF0IGFsbA0KCQlwdWJsaWMgTERCQVNUb2Jq IHBhcmVudCB7IGdldDsgcHJpdmF0ZSBzZXQ7IH0NCgkJCQkJCT0gbm9QYXJlbnQ7DQoJCS8vIFVu aXF1ZSBJRCBwZXIgb2JqZWN0LCB1c2VmdWwgZm9yIGRpc3Rpbmd1aXNoaW5nIHRoZW0NCgkJLy8g d2l0aG91dCBnZW5lcmFsIGVxdWFsaXR5Lg0KCQlyZWFkb25seSBwdWJsaWMgdWxvbmcgdWlkID0g bmV3VUlEKCk7DQoNCgkJLy8gcHVibGljIGFic3RyYWN0IGludCBsaW5lTnVtIHsgZ2V0OyBzZXQ7 IH0NCg0KCQkvLyBJcyB2YWxpZGF0ZWQgaXMgYSBjaGVhcGlzaCBjaGVjayB0byBlbnN1cmUgZXZl cnl0aGluZyBnZXRzDQoJCS8vIHZhbGlkYXRlZA0KCQkvLyBjYW4gZG8gdGhpcyBhcyBhdXRvIHBy b3A/IHRvZG8NCgkJcHJpdmF0ZSBib29sIF92YWxpZGF0ZWQgPSBmYWxzZTsNCg0KCQlwcm90ZWN0 ZWQgYm9vbCB2YWxpZGF0ZWQgew0KCQkJZ2V0ID0+IF92YWxpZGF0ZWQ7DQoJCQlzZXQgew0KCQkJ CS8vIGhhcmRNdXN0KCF2YWxpZGF0ZWQsICIuLi4gYWxyZWFkeSB2YWxpZGF0ZWQuLi4gIik7IC0g bm8NCgkJCQkvLyBJdCdzIGhhcmQgdG8gYXZvaWQgdmFsaWRhdGluZyBhIHRoaW5nIHR3aWNlLCBz byBmb3Igbm93IGFsbG93IGl0DQoJCQkJLy8gTG9vayBpbnRvIGl0IGxhdGVyLCByZWFsbHkgc2hv dWxkbid0IGhhcHBlbg0KCQkJCV92YWxpZGF0ZWQgPSB0cnVlOw0KCQkJfQ0KCQl9DQoNCgkJcHVi bGljIExEQlN0cnVjdHNDaGlsZHJlbiBraWRzIHsgZ2V0OyBwcml2YXRlIHNldDsgfSA9DQoJCQkJ CW5ldyBMREJTdHJ1Y3RzQ2hpbGRyZW4obm9QYXJlbnQpOyAvLyBqdXN0IGVhc2llcg0KDQoJCXB1 YmxpYyBMREJBU1RvYmooKSB7ICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8v Ly8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vIHRvZG8gZGVhZD8NCgkJCQkJCQkgIC8vIFZTdHVk aW8gdGhpbmtzIHRoaXMgaGFzIHplcm8gcmVmZXJlbmNlcywgd2hpY2ggaXMgdHJ1ZSBleHBsaWNp dGx5LCBidXQgaXQncyANCgkJCQkJCQkgIC8vIGNhbGxlZCBpbXBsaWNpdGx5IG9uIGV2ZXJ5IG9i aiBjcmVhdGlvbiAtIG9yIHNob3VsZCBkbyB0b2RvLSBjaGVjaw0KCQkJaWYgKHJlY29yZE9iamVj dHNDcmVhdGVkKSB7DQoJCQkJQWxsQ3JlYXRlZEl0ZW1zLkFkZCh0aGlzKTsNCgkJCX0NCgkJfQ0K DQoNCgkJcHVibGljIHZpcnR1YWwgdm9pZCB2YWxpZGF0ZSgpIHsNCgkJCWlmIChyZXBvcnRBbHNv SWZWYWxpZGF0aW9uT0spIHsNCgkJCQlkZWJ1Z21zZygidmFsaWRhdGluZy4uLiIgKyBjbGFzc05h bWUNCgkJCQkJKyAiICgiICsgYXNOYW1lT3JJZGVudENvbnRlbnRzKCkgKyAiKSIpOw0KCQkJfQ0K CQkJbWhwX21oaygpOw0KCQkJa2lkcy52YWxpZGF0ZSgpOw0KCQkJLy8gdmFsaWRhdGVkID0gdHJ1 ZTsgLS0gTm8sIGdldCBlYWNoIHN1YmNsYXNzIHRvIHNldA0KCQkJLy8gdmFsaWRhdGVkLiBUaGF0 IGZvcmNlcyBhbiBleHBsaWNpdCBjYWxsIHRvIGJhc2UoKSB3aGljaA0KCQkJLy8gaXMgbW9yZSBj b2RlIGJ1dCBvay4NCgkJfQ0KDQoNCgkJcHVibGljIGJvb2wgaXNWYWxpZGF0ZWQgeyBnZXQgPT4g dmFsaWRhdGVkOyB9ICAvLyB0b2RvIGp1c3QgPT4gdmFsaWRhdGVkOw0KDQoNCgkJcHVibGljIHZp cnR1YWwgYm9vbCBpc1RvcExldmVsSXRlbVNlcSA9PiBmYWxzZTsNCg0KDQoJCXB1YmxpYyB2aXJ0 dWFsIHZvaWQgbWhwX21oaygpIHsgIC8vIGRvbid0IHRoaW5rIHRoaXMgbmVlZCBiZSB2aXJ0dWFs IC0gdG9kbz8NCgkJCQkJCQkJCQkgLy8gPSBtdXN0IGhhdmUgcGFyZW50LCBtdXN0IGhhdmUga2lk cy4gVGhlIGtpZHMgbWF5IGJlIHRoZQ0KCQkJCQkJCQkJCSAvLyBlbXB0eSBzZXQgYW5kIHRoZSBw YXJlbnQgbWF5IGJlIG5vUGFyZW50IGJ1dCB0aGV5IG11c3QNCgkJCQkJCQkJCQkgLy8gZXhpc3Qu DQoJCQkJCQkJCQkJIC8vIFdoeSBub3QganVzdCBpbmxpbmUgdGhpcyBpbnRvIHZhbGlkYXRlKCk/ DQoJCQkJCQkJCQkJIC8vIEJlY2F1c2UgYSBmZXcgY2xhc3NlcyBuZWVkIGJlc3Bva2UgdmFsaWRh dGlvbiwgYnV0IHN0aWxsIG11c3QgY2hlY2sgdGhpcy4NCgkJCWhhcmRNdXN0UGFyZW50SXNQcmVz ZW50KCk7DQoJCQlraWRzLmVhY2hLaWRQYXJlbnRNdXN0QmUodGhpcyk7DQoJCX0NCg0KDQoJCXB1 YmxpYyBzdHJpbmcgYXNOYW1lT3JJZGVudENvbnRlbnRzKCkgew0KCQkJLy8gZm9yIHZlcnkgY3J1 ZGUgZGVidWdnaW5nIA0KCQkJdmFyIG9wdE5hbWUgPSB0aGlzIGlzIElpc05hbWVkSXRlbSBuaSA/ IG5pLm5hbWUudG9SYXdTdHIoKSA6ICIiOw0KCQkJb3B0TmFtZSA9IChvcHROYW1lID09ICIiICYm IHRoaXMgaXMgUE1RSWRlbnQpID8gdGhpcy50b1Jhd1N0cigpIDogIiI7DQoNCgkJCXZhciBvcHRO YW1lMiA9IG9wdE5hbWUgKyAiICAodWlkOiIgKyB1aWQuVG9TdHJpbmcoKSArICIpICINCgkJCQkr IGdldEZpcnN0RmV3Q2hhcnNPZih0b1Jhd1N0cigpKTsNCgkJCXJldHVybiBvcHROYW1lMjsNCgkJ fQ0KDQoNCgkJcHVibGljIHZpcnR1YWwgdm9pZCBnZXRBbGxVSURzKFVJRHNldCB1aWRzKSB7DQoJ CQl1aWRzLkFkZCh0aGlzKTsNCgkJCWtpZHMuRm9yRWFjaChuYW1lZEtpZCA9PiBuYW1lZEtpZC5r aWQuZ2V0QWxsVUlEcyh1aWRzKSk7DQoJCX0NCg0KDQoJCXB1YmxpYyBib29sIGlzU3R1YlBhcmVu dCB7IGdldCA9PiAodGhpcyBpcyBOb1BhcmVudCkgfHwgKHRoaXMgaXMgRmFrZVBhcmVudCk7IH0N Cg0KDQoJCXB1YmxpYyB2b2lkIHZhbGlkYXRlU3BlY2lmaWNJdGVtcyhwYXJhbXMgTERCQVNUb2Jq W10gaXRlbXMpIHsNCgkJCUFycmF5LkZvckVhY2goaXRlbXMsIGl0ZW0gPT4gaXRlbS52YWxpZGF0 ZSgpKTsNCgkJfQ0KDQoNCgkJcHVibGljIFQ/IG9wdENsaW1iVG88VD4oKSB3aGVyZSBUIDogTERC QVNUb2JqIHsNCgkJCXZhciByZXNJdGVtID0gdGhpczsNCgkJCXdoaWxlICghKHJlc0l0ZW0gaXMg VCkpIHsNCgkJCQlpZiAocmVzSXRlbS5wYXJlbnQuaXNTdHViUGFyZW50KSB7DQoJCQkJCXJldHVy biBudWxsOw0KCQkJCX0NCgkJCQlyZXNJdGVtID0gcmVzSXRlbS5wYXJlbnQ7DQoJCQl9DQoNCgkJ CXZhciByZXMgPSByZXNJdGVtIGFzIFQ7DQoJCQlyZXR1cm4gcmVzOw0KCQl9DQoNCg0KCQlwdWJs aWMgVCByZXFDbGltYlRvPFQ+KCkgd2hlcmUgVCA6IExEQkFTVG9iaiB7DQoJCQl2YXIgbG9jID0g Y2xhc3NOYW1lICsgIi5yZXFDbGltYlRvPFQ+KCkiOw0KCQkJdmFyIHJlcyA9IG9wdENsaW1iVG88 VD4oKTsNCgkJCWhhcmRNdXN0MighKHJlcyBpcyBudWxsKSwgDQoJCQkJLy8gVGhhbmtzIFNPIDxo dHRwczovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy8yNTgxNjQyL2hvdy1kby1pLWdldC10 aGUtdHlwZS1uYW1lLW9mLWEtZ2VuZXJpYy10eXBlLWFyZ3VtZW50Pg0KCQkJCS8vIFRvZG8gLSB1 c2UgdGhpcyBlbHNld2hlcmUsIHBvc3MgRXhwZWN0RXhjZXB0aW9uPyB0b2RvDQoJCQkJKCkgPT4N CgkJCQlsb2MgDQoJCQkJKyBubCArICIsIGNsaW1iZWQgdG8gdG9wLCBkaWRuJ3QgZmluZCB0eXBl ICINCgkJCQkrIHR5cGVvZihUKS5GdWxsTmFtZQ0KCQkJCSsgbmwgKyAiSGllcmFyY2h5IGlzOiAi DQoJCQkJKyBubCArIGdldEl0ZW1XaXRoUGFyZW50cyh0aGlzKSk7DQoJCQlpZiAocmVzIGlzIG51 bGwpIHsgdGhyb3cgbmV3IE5OUUMoKTsgfQ0KCQkJcmV0dXJuIHJlczsNCgkJfQ0KDQoNCgkJcHVi bGljIHZvaWQgaGFyZE11c3RQYXJlbnRJc1ByZXNlbnQoKSB7DQoNCgkJCWhhcmRNdXN0MighKHBh cmVudCBpcyBudWxsKSwgDQoJCQkJKCkgPT4NCgkJCQkgIk5VTEwgcGFyZW50IGZvciBpdGVtIG9m IHR5cGVcbiINCgkJCQkgKyAkIntHZXRUeXBlKCl9XG4uIik7DQoNCgkJCWhhcmRNdXN0MighKHRo aXMucGFyZW50IGlzIE5vUGFyZW50KSwNCgkJCQkoKSA9Pg0KCQkJCSJQYXJlbnQgaXMgTm9QYXJl bnQgb24gb2JqZWN0IG9mIHR5cGVcbiINCgkJCQkrICQiJ3t0aGlzLmNsYXNzTmFtZX0nIik7DQoJ CX0NCg0KDQoJCXB1YmxpYyB2b2lkIGhhcmRNdXN0UGFyZW50SXNBYnNlbnQoKSB7DQoJCQkvLyBG b3IgY2hlY2tpbmcgY2xvbmluZyAtIHBhcmVudCBzaG91bGQgYmUgTm9QYXJlbnQgaW1tZWRpYXRl bHkgDQoJCQkvLyBhZnRlciwgYmVmb3JlIGl0J3Mgc2V0IGJ5IHBhcmVudCwgYW5kIG5ldmVyIG51 bGwNCgkJCWhhcmRNdXN0KCEocGFyZW50IGlzIG51bGwpLA0KCQkJCSAiTlVMTCBwYXJlbnQgZm9y IGl0ZW0gb2YgdHlwZVxuIg0KCQkJCSArICQie0dldFR5cGUoKX1cbi4iKTsNCgkJCWhhcmRNdXN0 KCh0aGlzLnBhcmVudCBpcyBOb1BhcmVudCksDQoJCQkJIlBhcmVudCBzaG91bGQgYmUgTm9QYXJl bnQgb24gb2JqZWN0IG9mIHR5cGVcbiINCgkJCQkrICQiJ3t0aGlzLmNsYXNzTmFtZX0nIik7DQoJ CX0NCg0KDQoJCXB1YmxpYyBib29sIGhhc1BhcmVudDxQPigpIHsNCgkJCWhhcmRNdXN0KCEodGhp cyBpcyBOb1BhcmVudCksICJJdGVtIGlzIE5vUGFyZW50Iik7DQoJCQlyZXR1cm4gdGhpcy5wYXJl bnQgaXMgUDsNCgkJfQ0KDQoNCgkJcHVibGljIGJvb2wgaGFzQW5jZXN0b3I8QT4oKSB7DQoJCQlo YXJkTXVzdCghdGhpcy5pc1N0dWJQYXJlbnQsICJJdGVtIGlzIE5vUGFyZW50Iik7DQoNCgkJCS8v IGhvdyB0byBkbyB3aXRoIGEgc3dpdGNoIGV4cHI/DQoJCQlpZiAodGhpcy5wYXJlbnQuaXNTdHVi UGFyZW50IC8qIGlzIE5vUGFyZW50IHx8IHRoaXMucGFyZW50IGlzIEZha2VQYXJlbnQqLyApIHsg Ly8gdG9kbyBkbyBhcyB4Lmhhc0Z1ZGdlZFBhcmVudCgpIC0gdG9kbw0KCQkJCXJldHVybiBmYWxz ZTsNCgkJCX0gZWxzZSBpZiAodGhpcy5wYXJlbnQgaXMgQSkgew0KCQkJCXJldHVybiB0cnVlOw0K CQkJfSBlbHNlIHsNCgkJCQlyZXR1cm4gdGhpcy5wYXJlbnQuaGFzQW5jZXN0b3I8QT4oKTsNCgkJ CX0NCgkJfQ0KDQoJCXB1YmxpYyBib29sIG5vdEhhc0FuY2VzdG9yPEE+KCkgPT4NCgkJCSFoYXNB bmNlc3RvcjxBPigpOw0KDQoNCgkJcHVibGljIHZvaWQgc2V0TXlQYXJlbnRUbyhMREJBU1RvYmog cHJudCkgew0KCQkJLy8gQW4gb2JqZWN0IG1heSBvbmx5IHNldCBpdHMgcGFyZW50IGlmIGl0cyBj dXJyZW50IHBhcmVudCBpcw0KCQkJLy8gdGhlIGR1bW15ICdub1BhcmVudCcsIHdoaWNoIGFsbW9z dCBldmVyeSBvYmplY3QncyBwYXJlbnQgaXMNCgkJCS8vIHNldCB0byBvbiBjcmVhdGlvbiAoc2Vl IExEQkFTVG9iaiBwYXJlbnQgcHJvcGVydHkgZGVmKS4NCg0KCQkJLy8gVGhlIHRlc3QgZm9yIG51 bGwgaXMgcGVjdWxpYXIgZ2l2ZW4gdGhpcy4gQmVjYXVzZQ0KCQkJLy8gbm9QYXJlbnQgaXMgY3Jl YXRlZCBzdGF0aWNhbGx5LCBzZXR0aW5nIHRoZSBwYXJlbnQgb2YNCgkJCS8vIG5vUGFyZW50IGlz IGRpZmZpY3VsdCwgcGVyaGFwcyBpbXBvc3NpYmxlLCB0byBkbyBzdGF0aWNhbGx5DQoJCQkvLyBh bmQgcmVsaWFibHkuRGVzcGl0ZSB0aGUgZGVjbGFyYXRpb24gJyNudWxsYWJsZSBlbmFibGUnLCBp dA0KCQkJLy8gZ2V0cyBjcmVhdGVkIHdpdGggYSBudWxsIHBhcnJlbnQgKHF1aXRlIHJlYXNvbmFi bHkpLCBoZW5jZQ0KCQkJLy8gdGhpcyBjaGVjay5UaGUgYWN0dWFsIHNldHRpbmcgb2YgdGhlIHBh cmVudCBoYXMgdG8gYmUgZG9uZQ0KCQkJLy8gYXQgcnVudGltZSBpLmUuYWZ0ZXIgdGhlIHN0YXRp YyBjcmVhdGlvbiBvZiAnbm9QYXJlbnQnLg0KDQoJCQloYXJkTXVzdDIoKHRoaXMucGFyZW50IGlz IE5vUGFyZW50KSB8fCAodGhpcy5wYXJlbnQgaXMgbnVsbCksDQoJCQkJKCkgPT4NCgkJCQkidHJp ZWQgdG8gcmUtc2V0IHBhcmVudCBvbiBvYmplY3Qgb2YgdHlwZTogIg0KCQkJCSsgbmwgKyB0aGlz LmNsYXNzTmFtZVENCgkJCQkrIG5sICsgIk9yaWdpbmFsIHBhcmVudCB0eXBlIGlzOiAiDQoJCQkJ KyAodGhpcz8ucGFyZW50Py5jbGFzc05hbWVRID09IG51bGwgPyAibnVsbCIgOiB0aGlzLnBhcmVu dC5jbGFzc05hbWVRKQ0KCQkJCSsgbmwgKyAiYW5kIG5ldyBwYXJlbnQgdHlwZSBpczogIg0KCQkJ CSsgcHJudC5jbGFzc05hbWVRDQoJCQkJKyBubCArICJJdGVtIGhhdmluZyBwYXJlbnQgc2V0IG9u IGl0IGlzOiAiDQoJCQkJLy8gYmVjYXVzZSBvYmplY3QgbWF5IG5vdCBiZSBmdWxseSBjb25zdHJ1 Y3RlZCB5ZXQsIGNoZWNrIGhvd3ZlciBUT0RPIHRoaXMgaXMgYSBtYWpvciBoYWNrIGFuZCBtdXN0 IGJlIGZpeGVkIHNvbWV0aW1lLg0KLy8JCQkJKyBubCArICh0aGlzIGlzIG51bGwgPyAiKG51bGwp IiA6IHRoaXMudG9SYXdTdHIoKSkpOw0KCQkJCSsgbmwgKyB0aGlzLnRvUmF3U3RyKCkgKTsNCg0K CQkJcGFyZW50ID0gcHJudDsNCgkJfQ0KDQoNCgkJcHVibGljIHZvaWQgZm9yY2VOZXdQYXJlbnRG b3JSb290T2JqZWN0KCkgew0KCQkJLy8gRXZlcnkgb2JqZWN0IG11c3QgaGF2ZSBzb21lIHBhcmVu dCwgaW5jbHVkaW5nIHRoZQ0KCQkJLy8gcm9vdCBvYmplY3Qgb2YgdGhlIHBhcnNlLCB3aGljaCBp cyBMREJpdGVtcw0KCQkJLy8gKGEgc2VxdWVuY2Ugb2YgTERCIGl0ZW1zKSwgc28gdGhpcyBmb3Jj ZXMgb25lLg0KCQkJLy8gSXQgaXMgb25seSBmb3IgdGhhdCBwdXJwb3NlIQ0KCQkJLy8gDQoJCQkv LyBMREJpdGVtcyBvYmogZXhpc3RzIGZvciBzdWIgb2JqcyBzdWNoIGFzIHRoZSBzdGF0ZW1lbnRz DQoJCQkvLyBpbiBhIHdoaWxlIGxvb3AsIGluIGEgcHJvYywgaW4gYW4gaWYuLi4gZXRjLiwgZm9y DQoJCQkvLyB3aGljaCB0aGVpciBwYXJlbnQgaXMgdGhlIHdoaWxlL3Byb2MvaWYgZXRjLg0KCQkJ aGFyZE11c3RQYXJlbnRJc0Fic2VudCgpOw0KCQkJdGhpcy5wYXJlbnQgPSBmYWtlUGFyZW50Ow0K CQl9DQoNCg0KCQkvL3B1YmxpYyB2b2lkIHJlc2V0TXlQYXJlbnRUbyhMREJBU1RvYmogcHJudCkg eyAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLyBkZXN0cm95ISEhISEhIHRvZG8N CgkJLy8JcGFyZW50ID0gcHJudDsNCgkJLy99DQoNCgkJLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8v IHh4eHh4eHh4eHh4eHggZGVsZXRlIC0gdG9kbw0KCQkvL3ByaXZhdGUgdm9pZCBzZXRQYXJlbnRP bktpZChMREJBU1RvYmoga2lkKSA9PiAvLyB0b2RvIG5lZWRlZD8NCgkJLy8JCQkJCQkJCQkJCSAg Ly8gY2hlY2sgcGFyZW50ZSBkb2Vzbid0IGV4aXN0IC0gdG9kbw0KCQkvLwlraWQucGFyZW50ID0g dGhpczsNCg0KCQlwdWJsaWMgdmlydHVhbCB2b2lkIHNldFBhcmVudE9uS2lkc0FuZE1ha2VLaWRz RGljdCggIC8vIHRvZG8gLSBhbmQgYWRkIHRvIGtpZHMgZGljdA0KCQkJCQkJCQkJCQkJCQkJIC8v IHRoaXMgbWl4ZXMgdXAgc2V0dGluZyBwYXJlbnQgYW5kIG1ha2luZyBjaGlsZCBkaWN0LiBOb3Qg Z29vZC4gLSB0b2RvDQoJCQkJCQlwYXJhbXMgKHN0cmluZyBraWROYW1lLCBMREJBU1RvYmoga2lk KVtdIGtpZHNJbikgew0KCQkJdmFyIGxvYyA9IGNsYXNzTmFtZVBsdXMoInNldFBhcmVudE9uS2lk c0FuZE1ha2VLaWRzRGljdCIpOw0KDQoJCQl2YXIga2lkc1RvQWRkID0gbmV3IExEQlN0cnVjdHND aGlsZHJlbih0aGlzLCBraWRzSW4pOw0KCQkJaGFyZE11c3QyKGtpZHMuaXNFbXB0eSwNCgkJCQko KSA9Pg0KCQkJCSQic2V0dGluZyBraWRzIG9uIHBhcmVudCAne2NsYXNzTmFtZX0nIiANCgkJCQkr ICJ3aGVuIGtpZHMgaXMgbm90IGVtcHR5LCAiDQoJCQkJKyAkImtpZHMgaXMgKHtraWRzLkNvdW50 fSBraWRzKToiDQoJCQkJKyBubCArIGtpZHMudG9EZWJ1Z1N0cigpDQoJCQkJKyBubCArICQiVHJ5 aW5nIHRvIGFkZFxue2tpZHNUb0FkZC50b0RlYnVnU3RyKCl9XG4iDQoJCQkJKyAkImluIHtjbGFz c05hbWV9Iik7DQoJCQkvLyBpZiB0aGVyZSBpcyBhbiBMREJTdHJ1Y3RzQ2hpbGRyZW4gYW5kIGFu b3RoZXIgY2hpbGQsDQoJCQkvLyB0aGlzIHdpbGwgYmxvdyB1cCAtIHdpbGwgbmVlZCB0byBkbyBr aWRzLkFkZCBvcg0KCQkJLy8gc29tZXRoaW5nIC0gaW4gZmFjdCwga2lkcyBuZWVkcyB0byBiZSBj cmVhdGVkIGluIG9uZQ0KCQkJLy8gZ28sIHdoaWNoIGlzIHdoYXQgaGFwcGVucy4NCgkJCWtpZHMg PSBraWRzVG9BZGQ7ICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8v Ly8vLy8vLy8vLy8vLy8vLyB3aHkgdGhpcz8gdG9kbw0KCQkJQXJyYXkuRm9yRWFjaChraWRzSW4s IHhraWQgPT4gaGFyZE11c3QoISh4a2lkLmtpZCBpcyBudWxsKSwgbG9jLCAibnVsbCBraWQiKSk7 DQoJCQlBcnJheS5Gb3JFYWNoKGtpZHNJbiwgeGtpZCA9PiB4a2lkLmtpZC5zZXRNeVBhcmVudFRv KHRoaXMpKTsNCgkJfQ0KDQoNCgkJcHVibGljIHZpcnR1YWwgdm9pZCBzZXRQYXJlbnRPbktpZHNB bmRBZGRUb0tpZHNEaWN0KA0KCQkJCQlwYXJhbXMgKHN0cmluZyBraWROYW1lLCBMREJBU1RvYmog a2lkKVtdIGtpZHNJbikgew0KCQkJdmFyIGtpZHNUb0FkZF9qdXN0Rm9yRXJyUmVwb3J0aW5nID0g bmV3IExEQlN0cnVjdHNDaGlsZHJlbih0aGlzLCBraWRzSW4pOw0KCQkJaGFyZE11c3QyKCFraWRz LmlzRW1wdHksIC8vIG1heSBkaXNhYmxlIHRoaXMgbGF0ZXIgDQoJCQkJKCkgPT4NCgkJCQkiYWRk aW5nIHRvIGtpZHMgd2hlbiBraWRzIGlzIGVtcHR5LCAiDQoJCQkJICsgJCJraWRzIGlzXG57a2lk cy50b0RlYnVnU3RyKCl9XG4iDQoJCQkJICsgJCJUcnlpbmcgdG8gYWRkXG57a2lkc1RvQWRkX2p1 c3RGb3JFcnJSZXBvcnRpbmcudG9EZWJ1Z1N0cigpfVxuIg0KCQkJCSArICQiaW4ge2NsYXNzTmFt ZX0iKTsNCgkJCUFycmF5LkZvckVhY2goa2lkc0luLCB4a2lkID0+IHsNCi8vCQkJCXNldFBhcmVu dE9uS2lkKHhraWQua2lkKTsNCgkJCQl4a2lkLmtpZC5zZXRNeVBhcmVudFRvKHRoaXMpOw0KCQkJ CWtpZHMuQWRkKHhraWQpOw0KCQkJfSk7DQoJCX0NCg0KDQoJCXB1YmxpYyB2aXJ0dWFsIElkZW50 c1VzZWQgZ2V0QWxsSURzKCkgew0KCQkvKiBUaGlzIGlzIG92ZXJyaWRkZW4gb25seSBpbiBUZW1w bGF0ZWRBZ2csIGFuZCB0aGF0J3Mgb25seSB0byANCgkJCWRlbGliZXJhdGVseSBmYWlsLiBUaGVy ZSdzIHNvbWV0aGluZyB3cm9uZyB0aGVyZSwgdG9kbyAtIA0KCQkJdW4tdmlydHVhbGlzZSB0aGlz IGFuZCByZW1vdmUgdGhlIG9uZSBvdmVycmlkZS4gLSB0b2RvDQoJCSovDQoJCQl2YXIgaXUgPSBu ZXcgSWRlbnRzVXNlZCgpOw0KCQkJdGhpcy5fZ2V0QWxsSURzKGl1KTsNCgkJCXJldHVybiBpdTsN CgkJfQ0KDQoJCXB1YmxpYyB2aXJ0dWFsIHZvaWQgX2dldEFsbElEcyhJZGVudHNVc2VkIGl1KSB7 DQoJCS8vIEdldHMgYWxsIHRoZSBpZGVudGlmaWVycyBleHBsaWNpdGx5IHVzZWQgKHJlYWQgb3Ig d3JpdHRlbikgIC0tLS0tIHRvZG8gdXBkYXRlIHRoaXMNCgkJLy8gYW55d2hlcmUgaW4gdGhlIEFT VC4gIERvZXMgbm90IGdldCBpZGVudHMgd2hpY2ggYXJlDQoJCS8vIGRlY2xhcmF0aW9ucyBpZS4g cGFyYW1ldGVycywgb3IgdmFyL2NvbnN0IGRlY2xhcmF0aW9ucw0KCQkvLyB1bmxlc3MgdGhlc2Ug YXJlIGNvbWJpbmVkIHdpdGggYW4gYXNzaWdubWVudC4NCgkJLy8NCgkJLy8gSW1wbGllZCBpZGVu dHMgc3VjaCBhcyB0aG9zZSBmcm9tIHRibC4qIGFyZSBpbXBsaWNpdCBhbmQgaWdub3JlZC4NCgkJ Ly8NCgkJLy8gUm9vdCBjYWxsZXIgc3VwcGxpZXMgbmV3LCBlbXB0eSBpdQ0KCQkvLyBuZWVkIHVz YWdlIGhlcmUgLSB0b2RvIGRvY3MvLw0KCQkJa2lkcy5fZ2V0QWxsSURzKGl1KTsNCgkJfQ0KDQoJ CXB1YmxpYyBhYnN0cmFjdCBib29sIGNhbkdldEFsbElkZW50c1VzZWQgew0KCQkvLyAJVGhpcyBz ZWVtcyB0byBiZSB0cnVlIG9uIG1vc3QgY2xhc3NlcyBzbyBJIGNvdWxkIHNldCB0cnVlIA0KCQkv LyBhcyBhIGRlZmF1bHQgaGVyZSBhbmQgb3ZlcnJpZGUgaXQgd2hlcmUgaXQncyBub3Qgd2FudGVk LCBzYXZpbmcgDQoJCS8vIGEgY2h1bmsgb2YgY29kZSwgYnV0IEknZCByYXRoZXIgbWFrZSBpdCBl eHBsaWNpdCB0byBmb3JjZSBtZSB0byBjb25zaWRlciBlYWNoIGNhc2UuIEEgYml0IG1vcmUgQyZQ IGZvciBsZXNzIGNoYW5jZSBvZiBidWdzLg0KCQkJZ2V0Ow0KCQl9DQoNCg0KCQkvLyBQcm9kdWNl cyBhIHN0cmluZyB0aGF0IHNob3VsZCBiZSBpZGVudGljYWwgdG8gKGV4Y2VwdGluZw0KCQkvLyB3 aGl0ZXNwYWNlcykgdGhlIGlucHV0IGllLiBlbWl0IExEQiBjb2RlIG5vdCB2YWxpZCBTUUwNCgkJ Ly8NCgkJLy8gVG9TdHJpbmcgd2FzIGNhdXNpbmcgdG9vIG1hbnkgd2VpcmQgcHJvYmxlbXMgKGR1 ZSB0byBteQ0KCQkvLyBpbmV4cGVyaWVuY2Ugd2l0aCBjIykgc28ganVzdCB1c2VkIHRvUmF3U3Ry KCkNCgkJcHVibGljIGFic3RyYWN0IHN0cmluZyB0b1Jhd1N0cigpOw0KDQoJCXB1YmxpYyBvdmVy cmlkZSBzdHJpbmcgdG9EZWJ1Z1N0cigpID0+IHRvUmF3U3RyKCk7DQoNCgl9IC8vIGVuZCBMREJB U1RvYmoNCg0KDQoNCglwdWJsaWMgaW50ZXJmYWNlIEloYW5kbGVQcmVmaXhlczxUPg0KCQkJCQkJ d2hlcmUgVCA6IExEQlJvb3Qgew0KDQoJCXB1YmxpYyBib29sIGlzUHJlZml4ZWQgeyBnZXQ7IH0N Cg0KCQlwdWJsaWMgYm9vbCBpc0V4Y2Vzc1ByZWZpeGVkIHsgZ2V0OyB9DQoNCgkJLy8gVGhlIFQg aW4gYWRkUHJlZml4L3JlUHJlZml4L3dpdGhvdXRQcmVmaXggaXMgYmVjYXVzZSB3ZSBtYXkgYmUg DQoJCS8vIHJldHVybmluZyBlZy4gYSBsaXN0IG9mIGl0ZW1zIHdpdGggcHJlZml4ZXMgDQoJCS8v IHRodXMgbW9kaWZpZWQsIG5vdCBhIHNpbmdsZSBQTVFJZGVudA0KDQoJCXB1YmxpYyBUIGFkZFBy ZWZpeChQTVFJZGVudCBwZngpOw0KDQoJCXB1YmxpYyBUIHJlUHJlZml4KFBNUUlkZW50IG5ld3Bm eCk7DQoNCi8vCQlwdWJsaWMgVCBzdHJpcFByZWZpeChQTVFJZGVudCBpZCk7DQoJfQ0KCS8vIHRv ZG8gLSBtb3ZlIHRoaXMNCg0KDQoNCg0KDQoJcHVibGljIGFic3RyYWN0IGNsYXNzIExEQlJvb3Qg ew0KCQkvLyBSb290IG9mIGV2ZXJ5dGhpbmcgTERCLWlzaA0KDQoJCXB1YmxpYyBib29sIEVxdWFs cyhbQWxsb3dOdWxsXSBMREJSb290IG90aGVyKSB7DQoJCQl0aHJvdyBuZXcgTERCU2hvdWxkTm90 QmVJbXBsZW1lbnRlZEV4Y2VwdGlvbigNCgkJCQkJCQkJCSJjYWxsZWQgRXF1YWxzIG9uIExEQlJv b3QiKTsNCgkJfQ0KDQoJCXB1YmxpYyBvdmVycmlkZQ0KCQkJYm9vbCBFcXVhbHMoW0FsbG93TnVs bF0gT2JqZWN0IG90aGVyKSB7DQoJCQl0aHJvdyBuZXcgTERCU2hvdWxkTm90QmVJbXBsZW1lbnRl ZEV4Y2VwdGlvbigNCgkJCQkJCQkJCSJjYWxsZWQgRXF1YWxzIGluIE9iamVjdCIpOw0KCQl9DQoN CgkJcHVibGljIG92ZXJyaWRlIGludCBHZXRIYXNoQ29kZSgpIHsNCgkJCXRocm93IG5ldyBMREJT aG91bGROb3RCZUltcGxlbWVudGVkRXhjZXB0aW9uKA0KCQkJCQkJCQkJImNhbGxlZCBHZXRIYXNo Q29kZSBpbiBMREJSb290Iik7DQoJCX0NCg0KCQlwdWJsaWMgc3RhdGljIGJvb2wgb3BlcmF0b3Ig PT0oTERCUm9vdCBsaHMsDQoJCQkJCQkJCQkgICBMREJSb290IHJocykgew0KCQkJdGhyb3cgbmV3 IExEQlNob3VsZE5vdEJlSW1wbGVtZW50ZWRFeGNlcHRpb24oDQoJCQkJCQkJCQkiY2FsbGVkID09 IGluIExEQlJvb3QiKTsNCgkJfQ0KDQoJCXB1YmxpYyBzdGF0aWMgYm9vbCBvcGVyYXRvciAhPShM REJSb290IGxocywNCgkJCQkJCQkJCSAgIExEQlJvb3QgcmhzKSB7DQoJCQl0aHJvdyBuZXcgTERC U2hvdWxkTm90QmVJbXBsZW1lbnRlZEV4Y2VwdGlvbigNCgkJCQkJCQkJCSJjYWxsZWQgIT0gaW4g TERCUm9vdCIpOw0KCQl9DQoNCg0KCQlwdWJsaWMgdmlydHVhbCBzdHJpbmcgY2xhc3NOYW1lIHsN CgkJCS8vIHRvZG8gLSB0aGlzIG5lZWRzIGNoZWNraW5nIGl0IHdvcmtzIGFzIEkgd2FudA0KCQkJ Ly8gYWxzbyByZW5hbWUgdG8gbGRiY2xhc3NuYW1lIC0tIHRvZG8NCgkJCWdldCA9PiB0aGlzLkdl dFR5cGUoKS5GdWxsTmFtZSA/PyAiKHVua25vd24pIjsNCgkJfQ0KDQoNCgkJcHVibGljIHZpcnR1 YWwgc3RyaW5nIGNsYXNzTmFtZVEgPT4NCgkJCSInIiArIGNsYXNzTmFtZSArICInIjsNCg0KDQoJ CXB1YmxpYyB2aXJ0dWFsIHN0cmluZyBjbGFzc05hbWVQbHVzKHN0cmluZyBwbHVzKSA9Pg0KCQkJ Y2xhc3NOYW1lICsgIi4iICsgcGx1czsNCg0KCQlwdWJsaWMgb3ZlcnJpZGUgc3RyaW5nIFRvU3Ry aW5nKCkgew0KCQkJLy8gVGhpcyBpbXBsaWNpdCB0by1zdHJpbmcgY29udmVyc2lvbiBjcmFwIGNv c3QgbWUgYSBmZXcgaG91cnMsIHNvIGF0IGxlYXN0DQoJCQkvLyBkbyB0aGlzICYgYmxvdyB1cCBh dCBydW50aW1lLiBXb3VsZCBwcmVmZXIgY29tcGlsZSB0aW1lIGJ1dCBpdCBzZWVtcw0KCQkJLy8g bm90IHBvc3NpYmxlLiAgVGhpcyB0dXJucyBvdXQgdG8gaGF2ZSBiZWVuIGEgZ29vZCBpZGVhLA0K CQkJLy8gc2F2ZWQgbWUgcXVpdGUgYSBiaXQgbW9yZSBkZWJ1Z2dpbmchDQoJCQkvLyA8aHR0cHM6 Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvMTUzNDU1MTcvaXMtaXQtcG9zc2libGUtdG8t ZGlzYWJsZS1pbXBsaWNpdC10b3N0cmluZy1jYWxsPg0KCQkJLy8gV2lsbCB0cnkgPGh0dHBzOi8v c3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzU0MzU0MzQyL2hvdy10by1nZXQtYW4tZXJyb3It c2hvd24td2hlbi11c2luZy1ub24tc3RyaW5ncy1hcy1zdHJpbmdzLWluc3RlYWQtb2YtYW4tYXV0 b20vNTQzNTUxMTUjNTQzNTUxMTUpDQoJCQl2YXIgbXNnID0gIkxEQlJvb3QuVG9TdHJpbmcoKSI7 DQoJCQl0aHJvdyBuZXcgTERCVG9TdHJpbmdJbXBsaWN0Q29udmVyc2lvbkV4Y2VwdGlvbihtc2cp Ow0KCQl9DQoNCgkJcHVibGljIGFic3RyYWN0IHN0cmluZyB0b0RlYnVnU3RyKCk7DQoJfQ0KDQoN Cg0KCXB1YmxpYyBhYnN0cmFjdCBjbGFzcyBFcGhlbWVyYWwgOiBMREJSb290IHsNCgkJLy8gZm9y IG9iamVjdHMgdGhhdCBhcmUgbm90IHBhcnQgb2YgdGhlIEFTVA0KCX0NCg0KDQoNCglwdWJsaWMg aW50ZXJmYWNlIElXaXRoTGluZU5VbSB7ICAvLyB0b2RvIC0gdXNlIG9yIHJlbW92ZSAtIHRvZG8N CgkJLy8JcHVibGljIA0KCX0NCg0KDQoJcHVibGljIGludGVyZmFjZSBJSGFzVGFibGVBbGlhcyB7 DQoJCS8vIEhhcyBhIHRhYmxlIGFsaWFzIEFTVCBvYmouIE1heSBiZSBhIC4uLk1pc3Npbmcgc3Vi dHlwZSBpbiB3aGljaA0KCQkvLyBpdCBoYXMgbm8gYWxpYXMgZ2l2ZW4gYnkgdGhlIHVzZXIsIGJ1 dCBhbGlhcyBBU1QgaXMgdGhlcmUuIE1vcmUNCgkJLy8gYWNjdXJhdGVseSBhIFRhYmxlU291cmNl IGFsaWFzIGJ1dCBvaw0KCQlwdWJsaWMgYWJzdHJhY3QgVGFibGVBbGlhcyB0YSB7IGdldDsgc2V0 OyB9DQoJfQ0KDQoNCgkvLyBCYXNlIGNsYXNzIGZvciBhbGwgTERCIEFTVCBvYmplY3RzDQoJcHVi bGljIGFic3RyYWN0IGNsYXNzIExEQkFTVG9iaiA6IExEQlJvb3Qgew0KCQkvLyBUaGlzIG9uZSBp cyBhIHByb2JsZW0uIElmIEkgZGVjbGFyZSB0aGUgJ3BhcmVudCcgcHJvcGVydHkNCgkJLy8gYWJz dHJhY3QgSSB0aGVuIGhhdmUgdG8gaW1wbGVtZW50IGl0IGxpdGVyYWxseSBodW5kcmVkcyBvZg0K CQkvLyB0aW1lcyBpbiB0aGUgZGVyaXZlZCBjbGFzc2VzLCBhbmQgSSByZWFsbHkgZG9uJ3QgdGhp bmsgaXQNCgkJLy8gd291bGQgaGVscCBzbyBqdXN0IHNldCBpdCB0byBhIGRlZmF1bHQgd2hpY2gg Z2V0cyBvdmVyd3JpdHRlbiBsYXRlci4NCgkJLy8gDQoJCS8vIFRoZSBwcm9ibGVtIGlzIHRoYXQg dGhvc2Ugb2JqZWN0cyB3ZXJlIGNyZWF0ZWQgYnkgdGhlDQoJCS8vIHBhcnNlciwgd2hpY2ggY3Jl YXRlcyB0aGVtIGJvdHRvbS11cCwgd2hpY2ggbWVhbnMgeW91IGNhbid0DQoJCS8vIGtub3cgdGhl IHBhcmVudCB3aGVuIHRoZXkgYXJlIGNyZWF0ZWQuIEl0IHNob3VsZCBiZQ0KCQkvLyBwb3NzaWJs ZSB0byB3b3JrIGFyb3VuZCB0aGlzIGJ1dCBpdCBkb2VzIG1lYW4gcmV3b3JraW5nIHRoZQ0KCQkv LyBwYXJzZXIgZnVuZGFtZW50YWxseSwgYW5kIEknbSBub3QgZ29pbmcgdG8gZG8gdGhhdA0KCQkv LyBhc3N1bWVpbmcgaXQncyBldmVuIHBvc3NpYmxlLg0KDQoJCS8vIHRvZG8gLSByZWFkIHVwIG9u IHByaXYvcHViL3Byb2cgYWNjZXNzb3JzIEkgcmVhbGx5IGRvbid0DQoJCS8vIGdldCB0aGVzZSBh dCBhbGwNCgkJcHVibGljIExEQkFTVG9iaiBwYXJlbnQgeyBnZXQ7IHByaXZhdGUgc2V0OyB9DQoJ CQkJCQk9IG5vUGFyZW50Ow0KCQkvLyBVbmlxdWUgSUQgcGVyIG9iamVjdCwgdXNlZnVsIGZvciBk aXN0aW5ndWlzaGluZyB0aGVtDQoJCS8vIHdpdGhvdXQgZ2VuZXJhbCBlcXVhbGl0eS4NCgkJcmVh ZG9ubHkgcHVibGljIHVsb25nIHVpZCA9IG5ld1VJRCgpOw0KDQoJCS8vIHB1YmxpYyBhYnN0cmFj dCBpbnQgbGluZU51bSB7IGdldDsgc2V0OyB9DQoNCgkJLy8gSXMgdmFsaWRhdGVkIGlzIGEgY2hl YXBpc2ggY2hlY2sgdG8gZW5zdXJlIGV2ZXJ5dGhpbmcgZ2V0cw0KCQkvLyB2YWxpZGF0ZWQNCgkJ Ly8gY2FuIGRvIHRoaXMgYXMgYXV0byBwcm9wPyB0b2RvDQoJCXByaXZhdGUgYm9vbCBfdmFsaWRh dGVkID0gZmFsc2U7DQoNCgkJcHJvdGVjdGVkIGJvb2wgdmFsaWRhdGVkIHsNCgkJCWdldCA9PiBf dmFsaWRhdGVkOw0KCQkJc2V0IHsNCgkJCQkvLyBoYXJkTXVzdCghdmFsaWRhdGVkLCAiLi4uIGFs cmVhZHkgdmFsaWRhdGVkLi4uICIpOyAtIG5vDQoJCQkJLy8gSXQncyBoYXJkIHRvIGF2b2lkIHZh bGlkYXRpbmcgYSB0aGluZyB0d2ljZSwgc28gZm9yIG5vdyBhbGxvdyBpdA0KCQkJCS8vIExvb2sg aW50byBpdCBsYXRlciwgcmVhbGx5IHNob3VsZG4ndCBoYXBwZW4NCgkJCQlfdmFsaWRhdGVkID0g dHJ1ZTsNCgkJCX0NCgkJfQ0KDQoJCXB1YmxpYyBMREJTdHJ1Y3RzQ2hpbGRyZW4ga2lkcyB7IGdl dDsgcHJpdmF0ZSBzZXQ7IH0gPQ0KCQkJCQluZXcgTERCU3RydWN0c0NoaWxkcmVuKG5vUGFyZW50 KTsgLy8ganVzdCBlYXNpZXINCg0KCQlwdWJsaWMgTERCQVNUb2JqKCkgeyAgLy8vLy8vLy8vLy8v Ly8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLyB0b2Rv IGRlYWQ/DQoJCQkJCQkJICAvLyBWU3R1ZGlvIHRoaW5rcyB0aGlzIGhhcyB6ZXJvIHJlZmVyZW5j ZXMsIHdoaWNoIGlzIHRydWUgZXhwbGljaXRseSwgYnV0IGl0J3MgDQoJCQkJCQkJICAvLyBjYWxs ZWQgaW1wbGljaXRseSBvbiBldmVyeSBvYmogY3JlYXRpb24gLSBvciBzaG91bGQgZG8gdG9kby0g Y2hlY2sNCgkJCWlmIChyZWNvcmRPYmplY3RzQ3JlYXRlZCkgew0KCQkJCUFsbENyZWF0ZWRJdGVt cy5BZGQodGhpcyk7DQoJCQl9DQoJCX0NCg0KDQoJCXB1YmxpYyB2aXJ0dWFsIHZvaWQgdmFsaWRh dGUoKSB7DQoJCQlpZiAocmVwb3J0QWxzb0lmVmFsaWRhdGlvbk9LKSB7DQoJCQkJZGVidWdtc2co InZhbGlkYXRpbmcuLi4iICsgY2xhc3NOYW1lDQoJCQkJCSsgIiAoIiArIGFzTmFtZU9ySWRlbnRD b250ZW50cygpICsgIikiKTsNCgkJCX0NCgkJCW1ocF9taGsoKTsNCgkJCWtpZHMudmFsaWRhdGUo KTsNCgkJCS8vIHZhbGlkYXRlZCA9IHRydWU7IC0tIE5vLCBnZXQgZWFjaCBzdWJjbGFzcyB0byBz ZXQNCgkJCS8vIHZhbGlkYXRlZC4gVGhhdCBmb3JjZXMgYW4gZXhwbGljaXQgY2FsbCB0byBiYXNl KCkgd2hpY2gNCgkJCS8vIGlzIG1vcmUgY29kZSBidXQgb2suDQoJCX0NCg0KDQoJCXB1YmxpYyBi b29sIGlzVmFsaWRhdGVkIHsgZ2V0ID0+IHZhbGlkYXRlZDsgfSAgLy8gdG9kbyBqdXN0ID0+IHZh bGlkYXRlZDsNCg0KDQoJCXB1YmxpYyB2aXJ0dWFsIGJvb2wgaXNUb3BMZXZlbEl0ZW1TZXEgPT4g ZmFsc2U7DQoNCg0KCQlwdWJsaWMgdmlydHVhbCB2b2lkIG1ocF9taGsoKSB7ICAvLyBkb24ndCB0 aGluayB0aGlzIG5lZWQgYmUgdmlydHVhbCAtIHRvZG8/DQoJCQkJCQkJCQkJIC8vID0gbXVzdCBo YXZlIHBhcmVudCwgbXVzdCBoYXZlIGtpZHMuIFRoZSBraWRzIG1heSBiZSB0aGUNCgkJCQkJCQkJ CQkgLy8gZW1wdHkgc2V0IGFuZCB0aGUgcGFyZW50IG1heSBiZSBub1BhcmVudCBidXQgdGhleSBt dXN0DQoJCQkJCQkJCQkJIC8vIGV4aXN0Lg0KCQkJCQkJCQkJCSAvLyBXaHkgbm90IGp1c3QgaW5s aW5lIHRoaXMgaW50byB2YWxpZGF0ZSgpPw0KCQkJCQkJCQkJCSAvLyBCZWNhdXNlIGEgZmV3IGNs YXNzZXMgbmVlZCBiZXNwb2tlIHZhbGlkYXRpb24sIGJ1dCBzdGlsbCBtdXN0IGNoZWNrIHRoaXMu DQoJCQloYXJkTXVzdFBhcmVudElzUHJlc2VudCgpOw0KCQkJa2lkcy5lYWNoS2lkUGFyZW50TXVz dEJlKHRoaXMpOw0KCQl9DQoNCg0KCQlwdWJsaWMgc3RyaW5nIGFzTmFtZU9ySWRlbnRDb250ZW50 cygpIHsNCgkJCS8vIGZvciB2ZXJ5IGNydWRlIGRlYnVnZ2luZyANCgkJCXZhciBvcHROYW1lID0g dGhpcyBpcyBJaXNOYW1lZEl0ZW0gbmkgPyBuaS5uYW1lLnRvUmF3U3RyKCkgOiAiIjsNCgkJCW9w dE5hbWUgPSAob3B0TmFtZSA9PSAiIiAmJiB0aGlzIGlzIFBNUUlkZW50KSA/IHRoaXMudG9SYXdT dHIoKSA6ICIiOw0KDQoJCQl2YXIgb3B0TmFtZTIgPSBvcHROYW1lICsgIiAgKHVpZDoiICsgdWlk LlRvU3RyaW5nKCkgKyAiKSAiDQoJCQkJKyBnZXRGaXJzdEZld0NoYXJzT2YodG9SYXdTdHIoKSk7 DQoJCQlyZXR1cm4gb3B0TmFtZTI7DQoJCX0NCg0KDQoJCXB1YmxpYyB2aXJ0dWFsIHZvaWQgZ2V0 QWxsVUlEcyhVSURzZXQgdWlkcykgew0KCQkJdWlkcy5BZGQodGhpcyk7DQoJCQlraWRzLkZvckVh Y2gobmFtZWRLaWQgPT4gbmFtZWRLaWQua2lkLmdldEFsbFVJRHModWlkcykpOw0KCQl9DQoNCg0K CQlwdWJsaWMgYm9vbCBpc1N0dWJQYXJlbnQgeyBnZXQgPT4gKHRoaXMgaXMgTm9QYXJlbnQpIHx8 ICh0aGlzIGlzIEZha2VQYXJlbnQpOyB9DQoNCg0KCQlwdWJsaWMgdm9pZCB2YWxpZGF0ZVNwZWNp ZmljSXRlbXMocGFyYW1zIExEQkFTVG9ialtdIGl0ZW1zKSB7DQoJCQlBcnJheS5Gb3JFYWNoKGl0 ZW1zLCBpdGVtID0+IGl0ZW0udmFsaWRhdGUoKSk7DQoJCX0NCg0KDQoJCXB1YmxpYyBUPyBvcHRD bGltYlRvPFQ+KCkgd2hlcmUgVCA6IExEQkFTVG9iaiB7DQoJCQl2YXIgcmVzSXRlbSA9IHRoaXM7 DQoJCQl3aGlsZSAoIShyZXNJdGVtIGlzIFQpKSB7DQoJCQkJaWYgKHJlc0l0ZW0ucGFyZW50Lmlz U3R1YlBhcmVudCkgew0KCQkJCQlyZXR1cm4gbnVsbDsNCgkJCQl9DQoJCQkJcmVzSXRlbSA9IHJl c0l0ZW0ucGFyZW50Ow0KCQkJfQ0KDQoJCQl2YXIgcmVzID0gcmVzSXRlbSBhcyBUOw0KCQkJcmV0 dXJuIHJlczsNCgkJfQ0KDQoNCgkJcHVibGljIFQgcmVxQ2xpbWJUbzxUPigpIHdoZXJlIFQgOiBM REJBU1RvYmogew0KCQkJdmFyIGxvYyA9IGNsYXNzTmFtZSArICIucmVxQ2xpbWJUbzxUPigpIjsN CgkJCXZhciByZXMgPSBvcHRDbGltYlRvPFQ+KCk7DQoJCQloYXJkTXVzdDIoIShyZXMgaXMgbnVs bCksIA0KCQkJCS8vIFRoYW5rcyBTTyA8aHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlv bnMvMjU4MTY0Mi9ob3ctZG8taS1nZXQtdGhlLXR5cGUtbmFtZS1vZi1hLWdlbmVyaWMtdHlwZS1h cmd1bWVudD4NCgkJCQkvLyBUb2RvIC0gdXNlIHRoaXMgZWxzZXdoZXJlLCBwb3NzIEV4cGVjdEV4 Y2VwdGlvbj8gdG9kbw0KCQkJCSgpID0+DQoJCQkJbG9jIA0KCQkJCSsgbmwgKyAiLCBjbGltYmVk IHRvIHRvcCwgZGlkbid0IGZpbmQgdHlwZSAiDQoJCQkJKyB0eXBlb2YoVCkuRnVsbE5hbWUNCgkJ CQkrIG5sICsgIkhpZXJhcmNoeSBpczogIg0KCQkJCSsgbmwgKyBnZXRJdGVtV2l0aFBhcmVudHMo dGhpcykpOw0KCQkJaWYgKHJlcyBpcyBudWxsKSB7IHRocm93IG5ldyBOTlFDKCk7IH0NCgkJCXJl dHVybiByZXM7DQoJCX0NCg0KDQoJCXB1YmxpYyB2b2lkIGhhcmRNdXN0UGFyZW50SXNQcmVzZW50 KCkgew0KDQoJCQloYXJkTXVzdDIoIShwYXJlbnQgaXMgbnVsbCksIA0KCQkJCSgpID0+DQoJCQkJ ICJOVUxMIHBhcmVudCBmb3IgaXRlbSBvZiB0eXBlXG4iDQoJCQkJICsgJCJ7R2V0VHlwZSgpfVxu LiIpOw0KDQoJCQloYXJkTXVzdDIoISh0aGlzLnBhcmVudCBpcyBOb1BhcmVudCksDQoJCQkJKCkg PT4NCgkJCQkiUGFyZW50IGlzIE5vUGFyZW50IG9uIG9iamVjdCBvZiB0eXBlXG4iDQoJCQkJKyAk Iid7dGhpcy5jbGFzc05hbWV9JyIpOw0KCQl9DQoNCg0KCQlwdWJsaWMgdm9pZCBoYXJkTXVzdFBh cmVudElzQWJzZW50KCkgew0KCQkJLy8gRm9yIGNoZWNraW5nIGNsb25pbmcgLSBwYXJlbnQgc2hv dWxkIGJlIE5vUGFyZW50IGltbWVkaWF0ZWx5IA0KCQkJLy8gYWZ0ZXIsIGJlZm9yZSBpdCdzIHNl dCBieSBwYXJlbnQsIGFuZCBuZXZlciBudWxsDQoJCQloYXJkTXVzdCghKHBhcmVudCBpcyBudWxs KSwNCgkJCQkgIk5VTEwgcGFyZW50IGZvciBpdGVtIG9mIHR5cGVcbiINCgkJCQkgKyAkIntHZXRU eXBlKCl9XG4uIik7DQoJCQloYXJkTXVzdCgodGhpcy5wYXJlbnQgaXMgTm9QYXJlbnQpLA0KCQkJ CSJQYXJlbnQgc2hvdWxkIGJlIE5vUGFyZW50IG9uIG9iamVjdCBvZiB0eXBlXG4iDQoJCQkJKyAk Iid7dGhpcy5jbGFzc05hbWV9JyIpOw0KCQl9DQoNCg0KCQlwdWJsaWMgYm9vbCBoYXNQYXJlbnQ8 UD4oKSB7DQoJCQloYXJkTXVzdCghKHRoaXMgaXMgTm9QYXJlbnQpLCAiSXRlbSBpcyBOb1BhcmVu dCIpOw0KCQkJcmV0dXJuIHRoaXMucGFyZW50IGlzIFA7DQoJCX0NCg0KDQoJCXB1YmxpYyBib29s IGhhc0FuY2VzdG9yPEE+KCkgew0KCQkJaGFyZE11c3QoIXRoaXMuaXNTdHViUGFyZW50LCAiSXRl bSBpcyBOb1BhcmVudCIpOw0KDQoJCQkvLyBob3cgdG8gZG8gd2l0aCBhIHN3aXRjaCBleHByPw0K CQkJaWYgKHRoaXMucGFyZW50LmlzU3R1YlBhcmVudCAvKiBpcyBOb1BhcmVudCB8fCB0aGlzLnBh cmVudCBpcyBGYWtlUGFyZW50Ki8gKSB7IC8vIHRvZG8gZG8gYXMgeC5oYXNGdWRnZWRQYXJlbnQo KSAtIHRvZG8NCgkJCQlyZXR1cm4gZmFsc2U7DQoJCQl9IGVsc2UgaWYgKHRoaXMucGFyZW50IGlz IEEpIHsNCgkJCQlyZXR1cm4gdHJ1ZTsNCgkJCX0gZWxzZSB7DQoJCQkJcmV0dXJuIHRoaXMucGFy ZW50Lmhhc0FuY2VzdG9yPEE+KCk7DQoJCQl9DQoJCX0NCg0KCQlwdWJsaWMgYm9vbCBub3RIYXNB bmNlc3RvcjxBPigpID0+DQoJCQkhaGFzQW5jZXN0b3I8QT4oKTsNCg0KDQoJCXB1YmxpYyB2b2lk IHNldE15UGFyZW50VG8oTERCQVNUb2JqIHBybnQpIHsNCgkJCS8vIEFuIG9iamVjdCBtYXkgb25s eSBzZXQgaXRzIHBhcmVudCBpZiBpdHMgY3VycmVudCBwYXJlbnQgaXMNCgkJCS8vIHRoZSBkdW1t eSAnbm9QYXJlbnQnLCB3aGljaCBhbG1vc3QgZXZlcnkgb2JqZWN0J3MgcGFyZW50IGlzDQoJCQkv LyBzZXQgdG8gb24gY3JlYXRpb24gKHNlZSBMREJBU1RvYmogcGFyZW50IHByb3BlcnR5IGRlZiku DQoNCgkJCS8vIFRoZSB0ZXN0IGZvciBudWxsIGlzIHBlY3VsaWFyIGdpdmVuIHRoaXMuIEJlY2F1 c2UNCgkJCS8vIG5vUGFyZW50IGlzIGNyZWF0ZWQgc3RhdGljYWxseSwgc2V0dGluZyB0aGUgcGFy ZW50IG9mDQoJCQkvLyBub1BhcmVudCBpcyBkaWZmaWN1bHQsIHBlcmhhcHMgaW1wb3NzaWJsZSwg dG8gZG8gc3RhdGljYWxseQ0KCQkJLy8gYW5kIHJlbGlhYmx5LkRlc3BpdGUgdGhlIGRlY2xhcmF0 aW9uICcjbnVsbGFibGUgZW5hYmxlJywgaXQNCgkJCS8vIGdldHMgY3JlYXRlZCB3aXRoIGEgbnVs bCBwYXJyZW50IChxdWl0ZSByZWFzb25hYmx5KSwgaGVuY2UNCgkJCS8vIHRoaXMgY2hlY2suVGhl IGFjdHVhbCBzZXR0aW5nIG9mIHRoZSBwYXJlbnQgaGFzIHRvIGJlIGRvbmUNCgkJCS8vIGF0IHJ1 bnRpbWUgaS5lLmFmdGVyIHRoZSBzdGF0aWMgY3JlYXRpb24gb2YgJ25vUGFyZW50Jy4NCg0KCQkJ aGFyZE11c3QyKCh0aGlzLnBhcmVudCBpcyBOb1BhcmVudCkgfHwgKHRoaXMucGFyZW50IGlzIG51 bGwpLA0KCQkJCSgpID0+DQoJCQkJInRyaWVkIHRvIHJlLXNldCBwYXJlbnQgb24gb2JqZWN0IG9m IHR5cGU6ICINCgkJCQkrIG5sICsgdGhpcy5jbGFzc05hbWVRDQoJCQkJKyBubCArICJPcmlnaW5h bCBwYXJlbnQgdHlwZSBpczogIg0KCQkJCSsgKHRoaXM/LnBhcmVudD8uY2xhc3NOYW1lUSA9PSBu dWxsID8gIm51bGwiIDogdGhpcy5wYXJlbnQuY2xhc3NOYW1lUSkNCgkJCQkrIG5sICsgImFuZCBu ZXcgcGFyZW50IHR5cGUgaXM6ICINCgkJCQkrIHBybnQuY2xhc3NOYW1lUQ0KCQkJCSsgbmwgKyAi SXRlbSBoYXZpbmcgcGFyZW50IHNldCBvbiBpdCBpczogIg0KCQkJCS8vIGJlY2F1c2Ugb2JqZWN0 IG1heSBub3QgYmUgZnVsbHkgY29uc3RydWN0ZWQgeWV0LCBjaGVjayBob3d2ZXIgVE9ETyB0aGlz IGlzIGEgbWFqb3IgaGFjayBhbmQgbXVzdCBiZSBmaXhlZCBzb21ldGltZS4NCi8vCQkJCSsgbmwg KyAodGhpcyBpcyBudWxsID8gIihudWxsKSIgOiB0aGlzLnRvUmF3U3RyKCkpKTsNCgkJCQkrIG5s ICsgdGhpcy50b1Jhd1N0cigpICk7DQoNCgkJCXBhcmVudCA9IHBybnQ7DQoJCX0NCg0KDQoJCXB1 YmxpYyB2b2lkIGZvcmNlTmV3UGFyZW50Rm9yUm9vdE9iamVjdCgpIHsNCgkJCS8vIEV2ZXJ5IG9i amVjdCBtdXN0IGhhdmUgc29tZSBwYXJlbnQsIGluY2x1ZGluZyB0aGUNCgkJCS8vIHJvb3Qgb2Jq ZWN0IG9mIHRoZSBwYXJzZSwgd2hpY2ggaXMgTERCaXRlbXMNCgkJCS8vIChhIHNlcXVlbmNlIG9m IExEQiBpdGVtcyksIHNvIHRoaXMgZm9yY2VzIG9uZS4NCgkJCS8vIEl0IGlzIG9ubHkgZm9yIHRo YXQgcHVycG9zZSENCgkJCS8vIA0KCQkJLy8gTERCaXRlbXMgb2JqIGV4aXN0cyBmb3Igc3ViIG9i anMgc3VjaCBhcyB0aGUgc3RhdGVtZW50cw0KCQkJLy8gaW4gYSB3aGlsZSBsb29wLCBpbiBhIHBy b2MsIGluIGFuIGlmLi4uIGV0Yy4sIGZvcg0KCQkJLy8gd2hpY2ggdGhlaXIgcGFyZW50IGlzIHRo ZSB3aGlsZS9wcm9jL2lmIGV0Yy4NCgkJCWhhcmRNdXN0UGFyZW50SXNBYnNlbnQoKTsNCgkJCXRo aXMucGFyZW50ID0gZmFrZVBhcmVudDsNCgkJfQ0KDQoNCgkJLy9wdWJsaWMgdm9pZCByZXNldE15 UGFyZW50VG8oTERCQVNUb2JqIHBybnQpIHsgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8v Ly8vLy8gZGVzdHJveSEhISEhISB0b2RvDQoJCS8vCXBhcmVudCA9IHBybnQ7DQoJCS8vfQ0KDQoJ CS8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLyB4eHh4eHh4eHh4eHh4IGRlbGV0ZSAtIHRvZG8NCgkJ Ly9wcml2YXRlIHZvaWQgc2V0UGFyZW50T25LaWQoTERCQVNUb2JqIGtpZCkgPT4gLy8gdG9kbyBu ZWVkZWQ/DQoJCS8vCQkJCQkJCQkJCQkgIC8vIGNoZWNrIHBhcmVudGUgZG9lc24ndCBleGlzdCAt IHRvZG8NCgkJLy8Ja2lkLnBhcmVudCA9IHRoaXM7DQoNCgkJcHVibGljIHZpcnR1YWwgdm9pZCBz ZXRQYXJlbnRPbktpZHNBbmRNYWtlS2lkc0RpY3QoICAvLyB0b2RvIC0gYW5kIGFkZCB0byBraWRz IGRpY3QNCgkJCQkJCQkJCQkJCQkJCSAvLyB0aGlzIG1peGVzIHVwIHNldHRpbmcgcGFyZW50IGFu ZCBtYWtpbmcgY2hpbGQgZGljdC4gTm90IGdvb2QuIC0gdG9kbw0KCQkJCQkJcGFyYW1zIChzdHJp bmcga2lkTmFtZSwgTERCQVNUb2JqIGtpZClbXSBraWRzSW4pIHsNCgkJCXZhciBsb2MgPSBjbGFz c05hbWVQbHVzKCJzZXRQYXJlbnRPbktpZHNBbmRNYWtlS2lkc0RpY3QiKTsNCg0KCQkJdmFyIGtp ZHNUb0FkZCA9IG5ldyBMREJTdHJ1Y3RzQ2hpbGRyZW4odGhpcywga2lkc0luKTsNCgkJCWhhcmRN dXN0MihraWRzLmlzRW1wdHksDQoJCQkJKCkgPT4NCgkJCQkkInNldHRpbmcga2lkcyBvbiBwYXJl bnQgJ3tjbGFzc05hbWV9JyIgDQoJCQkJKyAid2hlbiBraWRzIGlzIG5vdCBlbXB0eSwgIg0KCQkJ CSsgJCJraWRzIGlzICh7a2lkcy5Db3VudH0ga2lkcyk6Ig0KCQkJCSsgbmwgKyBraWRzLnRvRGVi dWdTdHIoKQ0KCQkJCSsgbmwgKyAkIlRyeWluZyB0byBhZGRcbntraWRzVG9BZGQudG9EZWJ1Z1N0 cigpfVxuIg0KCQkJCSsgJCJpbiB7Y2xhc3NOYW1lfSIpOw0KCQkJLy8gaWYgdGhlcmUgaXMgYW4g TERCU3RydWN0c0NoaWxkcmVuIGFuZCBhbm90aGVyIGNoaWxkLA0KCQkJLy8gdGhpcyB3aWxsIGJs b3cgdXAgLSB3aWxsIG5lZWQgdG8gZG8ga2lkcy5BZGQgb3INCgkJCS8vIHNvbWV0aGluZyAtIGlu IGZhY3QsIGtpZHMgbmVlZHMgdG8gYmUgY3JlYXRlZCBpbiBvbmUNCgkJCS8vIGdvLCB3aGljaCBp cyB3aGF0IGhhcHBlbnMuDQoJCQlraWRzID0ga2lkc1RvQWRkOyAgICAvLy8vLy8vLy8vLy8vLy8v Ly8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8gd2h5IHRoaXM/IHRvZG8N CgkJCUFycmF5LkZvckVhY2goa2lkc0luLCB4a2lkID0+IGhhcmRNdXN0KCEoeGtpZC5raWQgaXMg bnVsbCksIGxvYywgIm51bGwga2lkIikpOw0KCQkJQXJyYXkuRm9yRWFjaChraWRzSW4sIHhraWQg PT4geGtpZC5raWQuc2V0TXlQYXJlbnRUbyh0aGlzKSk7DQoJCX0NCg0KDQoJCXB1YmxpYyB2aXJ0 dWFsIHZvaWQgc2V0UGFyZW50T25LaWRzQW5kQWRkVG9LaWRzRGljdCgNCgkJCQkJcGFyYW1zIChz dHJpbmcga2lkTmFtZSwgTERCQVNUb2JqIGtpZClbXSBraWRzSW4pIHsNCgkJCXZhciBraWRzVG9B ZGRfanVzdEZvckVyclJlcG9ydGluZyA9IG5ldyBMREJTdHJ1Y3RzQ2hpbGRyZW4odGhpcywga2lk c0luKTsNCgkJCWhhcmRNdXN0Migha2lkcy5pc0VtcHR5LCAvLyBtYXkgZGlzYWJsZSB0aGlzIGxh dGVyIA0KCQkJCSgpID0+DQoJCQkJImFkZGluZyB0byBraWRzIHdoZW4ga2lkcyBpcyBlbXB0eSwg Ig0KCQkJCSArICQia2lkcyBpc1xue2tpZHMudG9EZWJ1Z1N0cigpfVxuIg0KCQkJCSArICQiVHJ5 aW5nIHRvIGFkZFxue2tpZHNUb0FkZF9qdXN0Rm9yRXJyUmVwb3J0aW5nLnRvRGVidWdTdHIoKX1c biINCgkJCQkgKyAkImluIHtjbGFzc05hbWV9Iik7DQoJCQlBcnJheS5Gb3JFYWNoKGtpZHNJbiwg eGtpZCA9PiB7DQovLwkJCQlzZXRQYXJlbnRPbktpZCh4a2lkLmtpZCk7DQoJCQkJeGtpZC5raWQu c2V0TXlQYXJlbnRUbyh0aGlzKTsNCgkJCQlraWRzLkFkZCh4a2lkKTsNCgkJCX0pOw0KCQl9DQoN Cg0KCQlwdWJsaWMgdmlydHVhbCBJZGVudHNVc2VkIGdldEFsbElEcygpIHsNCgkJLyogVGhpcyBp cyBvdmVycmlkZGVuIG9ubHkgaW4gVGVtcGxhdGVkQWdnLCBhbmQgdGhhdCdzIG9ubHkgdG8gDQoJ CQlkZWxpYmVyYXRlbHkgZmFpbC4gVGhlcmUncyBzb21ldGhpbmcgd3JvbmcgdGhlcmUsIHRvZG8g LSANCgkJCXVuLXZpcnR1YWxpc2UgdGhpcyBhbmQgcmVtb3ZlIHRoZSBvbmUgb3ZlcnJpZGUuIC0g dG9kbw0KCQkqLw0KCQkJdmFyIGl1ID0gbmV3IElkZW50c1VzZWQoKTsNCgkJCXRoaXMuX2dldEFs bElEcyhpdSk7DQoJCQlyZXR1cm4gaXU7DQoJCX0NCg0KCQlwdWJsaWMgdmlydHVhbCB2b2lkIF9n ZXRBbGxJRHMoSWRlbnRzVXNlZCBpdSkgew0KCQkvLyBHZXRzIGFsbCB0aGUgaWRlbnRpZmllcnMg ZXhwbGljaXRseSB1c2VkIChyZWFkIG9yIHdyaXR0ZW4pICAtLS0tLSB0b2RvIHVwZGF0ZSB0aGlz DQoJCS8vIGFueXdoZXJlIGluIHRoZSBBU1QuICBEb2VzIG5vdCBnZXQgaWRlbnRzIHdoaWNoIGFy ZQ0KCQkvLyBkZWNsYXJhdGlvbnMgaWUuIHBhcmFtZXRlcnMsIG9yIHZhci9jb25zdCBkZWNsYXJh dGlvbnMNCgkJLy8gdW5sZXNzIHRoZXNlIGFyZSBjb21iaW5lZCB3aXRoIGFuIGFzc2lnbm1lbnQu DQoJCS8vDQoJCS8vIEltcGxpZWQgaWRlbnRzIHN1Y2ggYXMgdGhvc2UgZnJvbSB0YmwuKiBhcmUg aW1wbGljaXQgYW5kIGlnbm9yZWQuDQoJCS8vDQoJCS8vIFJvb3QgY2FsbGVyIHN1cHBsaWVzIG5l dywgZW1wdHkgaXUNCgkJLy8gbmVlZCB1c2FnZSBoZXJlIC0gdG9kbyBkb2NzLy8NCgkJCWtpZHMu X2dldEFsbElEcyhpdSk7DQoJCX0NCg0KCQlwdWJsaWMgYWJzdHJhY3QgYm9vbCBjYW5HZXRBbGxJ ZGVudHNVc2VkIHsNCgkJLy8gCVRoaXMgc2VlbXMgdG8gYmUgdHJ1ZSBvbiBtb3N0IGNsYXNzZXMg c28gSSBjb3VsZCBzZXQgdHJ1ZSANCgkJLy8gYXMgYSBkZWZhdWx0IGhlcmUgYW5kIG92ZXJyaWRl IGl0IHdoZXJlIGl0J3Mgbm90IHdhbnRlZCwgc2F2aW5nIA0KCQkvLyBhIGNodW5rIG9mIGNvZGUs IGJ1dCBJJ2QgcmF0aGVyIG1ha2UgaXQgZXhwbGljaXQgdG8gZm9yY2UgbWUgdG8gY29uc2lkZXIg ZWFjaCBjYXNlLiBBIGJpdCBtb3JlIEMmUCBmb3IgbGVzcyBjaGFuY2Ugb2YgYnVncy4NCgkJCWdl dDsNCgkJfQ0KDQoNCgkJLy8gUHJvZHVjZXMgYSBzdHJpbmcgdGhhdCBzaG91bGQgYmUgaWRlbnRp Y2FsIHRvIChleGNlcHRpbmcNCgkJLy8gd2hpdGVzcGFjZXMpIHRoZSBpbnB1dCBpZS4gZW1pdCBM REIgY29kZSBub3QgdmFsaWQgU1FMDQoJCS8vDQoJCS8vIFRvU3RyaW5nIHdhcyBjYXVzaW5nIHRv byBtYW55IHdlaXJkIHByb2JsZW1zIChkdWUgdG8gbXkNCgkJLy8gaW5leHBlcmllbmNlIHdpdGgg YyMpIHNvIGp1c3QgdXNlZCB0b1Jhd1N0cigpDQoJCXB1YmxpYyBhYnN0cmFjdCBzdHJpbmcgdG9S YXdTdHIoKTsNCg0KCQlwdWJsaWMgb3ZlcnJpZGUgc3RyaW5nIHRvRGVidWdTdHIoKSA9PiB0b1Jh d1N0cigpOw0KDQoJfSAvLyBlbmQgTERCQVNUb2JqDQoNCg0KDQoNCglwdWJsaWMgaW50ZXJmYWNl IEloYW5kbGVQcmVmaXhlczxUPg0KCQkJCQkJd2hlcmUgVCA6IExEQlJvb3Qgew0KDQoJCXB1Ymxp YyBib29sIGlzUHJlZml4ZWQgeyBnZXQ7IH0NCg0KCQlwdWJsaWMgYm9vbCBpc0V4Y2Vzc1ByZWZp eGVkIHsgZ2V0OyB9DQoNCgkJLy8gVGhlIFQgaW4gYWRkUHJlZml4L3JlUHJlZml4L3dpdGhvdXRQ cmVmaXggaXMgYmVjYXVzZSB3ZSBtYXkgYmUgDQoJCS8vIHJldHVybmluZyBlZy4gYSBsaXN0IG9m IGl0ZW1zIHdpdGggcHJlZml4ZXMgDQoJCS8vIHRodXMgbW9kaWZpZWQsIG5vdCBhIHNpbmdsZSBQ TVFJZGVudA0KDQoJCXB1YmxpYyBUIGFkZFByZWZpeChQTVFJZGVudCBwZngpOw0KDQoJCXB1Ymxp YyBUIHJlUHJlZml4KFBNUUlkZW50IG5ld3BmeCk7DQoNCi8vCQlwdWJsaWMgVCBzdHJpcFByZWZp eChQTVFJZGVudCBpZCk7DQoJfQ0KCS8vIHRvZG8gLSBtb3ZlIHRoaXMNCg0KDQoNCg0KDQoJcHVi bGljIGFic3RyYWN0IGNsYXNzIExEQlJvb3Qgew0KCQkvLyBSb290IG9mIGV2ZXJ5dGhpbmcgTERC LWlzaA0KDQoJCXB1YmxpYyBib29sIEVxdWFscyhbQWxsb3dOdWxsXSBMREJSb290IG90aGVyKSB7 DQoJCQl0aHJvdyBuZXcgTERCU2hvdWxkTm90QmVJbXBsZW1lbnRlZEV4Y2VwdGlvbigNCgkJCQkJ CQkJCSJjYWxsZWQgRXF1YWxzIG9uIExEQlJvb3QiKTsNCgkJfQ0KDQoJCXB1YmxpYyBvdmVycmlk ZQ0KCQkJYm9vbCBFcXVhbHMoW0FsbG93TnVsbF0gT2JqZWN0IG90aGVyKSB7DQoJCQl0aHJvdyBu ZXcgTERCU2hvdWxkTm90QmVJbXBsZW1lbnRlZEV4Y2VwdGlvbigNCgkJCQkJCQkJCSJjYWxsZWQg RXF1YWxzIGluIE9iamVjdCIpOw0KCQl9DQoNCgkJcHVibGljIG92ZXJyaWRlIGludCBHZXRIYXNo Q29kZSgpIHsNCgkJCXRocm93IG5ldyBMREJTaG91bGROb3RCZUltcGxlbWVudGVkRXhjZXB0aW9u KA0KCQkJCQkJCQkJImNhbGxlZCBHZXRIYXNoQ29kZSBpbiBMREJSb290Iik7DQoJCX0NCg0KCQlw dWJsaWMgc3RhdGljIGJvb2wgb3BlcmF0b3IgPT0oTERCUm9vdCBsaHMsDQoJCQkJCQkJCQkgICBM REJSb290IHJocykgew0KCQkJdGhyb3cgbmV3IExEQlNob3VsZE5vdEJlSW1wbGVtZW50ZWRFeGNl cHRpb24oDQoJCQkJCQkJCQkiY2FsbGVkID09IGluIExEQlJvb3QiKTsNCgkJfQ0KDQoJCXB1Ymxp YyBzdGF0aWMgYm9vbCBvcGVyYXRvciAhPShMREJSb290IGxocywNCgkJCQkJCQkJCSAgIExEQlJv b3QgcmhzKSB7DQoJCQl0aHJvdyBuZXcgTERCU2hvdWxkTm90QmVJbXBsZW1lbnRlZEV4Y2VwdGlv bigNCgkJCQkJCQkJCSJjYWxsZWQgIT0gaW4gTERCUm9vdCIpOw0KCQl9DQoNCg0KCQlwdWJsaWMg dmlydHVhbCBzdHJpbmcgY2xhc3NOYW1lIHsNCgkJCS8vIHRvZG8gLSB0aGlzIG5lZWRzIGNoZWNr aW5nIGl0IHdvcmtzIGFzIEkgd2FudA0KCQkJLy8gYWxzbyByZW5hbWUgdG8gbGRiY2xhc3NuYW1l IC0tIHRvZG8NCgkJCWdldCA9PiB0aGlzLkdldFR5cGUoKS5GdWxsTmFtZSA/PyAiKHVua25vd24p IjsNCgkJfQ0KDQoNCgkJcHVibGljIHZpcnR1YWwgc3RyaW5nIGNsYXNzTmFtZVEgPT4NCgkJCSIn IiArIGNsYXNzTmFtZSArICInIjsNCg0KDQoJCXB1YmxpYyB2aXJ0dWFsIHN0cmluZyBjbGFzc05h bWVQbHVzKHN0cmluZyBwbHVzKSA9Pg0KCQkJY2xhc3NOYW1lICsgIi4iICsgcGx1czsNCg0KCQlw dWJsaWMgb3ZlcnJpZGUgc3RyaW5nIFRvU3RyaW5nKCkgew0KCQkJLy8gVGhpcyBpbXBsaWNpdCB0 by1zdHJpbmcgY29udmVyc2lvbiBjcmFwIGNvc3QgbWUgYSBmZXcgaG91cnMsIHNvIGF0IGxlYXN0 DQoJCQkvLyBkbyB0aGlzICYgYmxvdyB1cCBhdCBydW50aW1lLiBXb3VsZCBwcmVmZXIgY29tcGls ZSB0aW1lIGJ1dCBpdCBzZWVtcw0KCQkJLy8gbm90IHBvc3NpYmxlLiAgVGhpcyB0dXJucyBvdXQg dG8gaGF2ZSBiZWVuIGEgZ29vZCBpZGVhLA0KCQkJLy8gc2F2ZWQgbWUgcXVpdGUgYSBiaXQgbW9y ZSBkZWJ1Z2dpbmchDQoJCQkvLyA8aHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMv MTUzNDU1MTcvaXMtaXQtcG9zc2libGUtdG8tZGlzYWJsZS1pbXBsaWNpdC10b3N0cmluZy1jYWxs Pg0KCQkJLy8gV2lsbCB0cnkgPGh0dHBzOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzU0 MzU0MzQyL2hvdy10by1nZXQtYW4tZXJyb3Itc2hvd24td2hlbi11c2luZy1ub24tc3RyaW5ncy1h cy1zdHJpbmdzLWluc3RlYWQtb2YtYW4tYXV0b20vNTQzNTUxMTUjNTQzNTUxMTUpDQoJCQl2YXIg bXNnID0gIkxEQlJvb3QuVG9TdHJpbmcoKSI7DQoJCQl0aHJvdyBuZXcgTERCVG9TdHJpbmdJbXBs aWN0Q29udmVyc2lvbkV4Y2VwdGlvbihtc2cpOw0KCQl9DQoNCgkJcHVibGljIGFic3RyYWN0IHN0 cmluZyB0b0RlYnVnU3RyKCk7DQoJfQ0KDQoNCg0KCXB1YmxpYyBhYnN0cmFjdCBjbGFzcyBFcGhl bWVyYWwgOiBMREJSb290IHsNCgkJLy8gZm9yIG9iamVjdHMgdGhhdCBhcmUgbm90IHBhcnQgb2Yg dGhlIEFTVA0KCX0NCg0KDQoNCglwdWJsaWMgaW50ZXJmYWNlIElXaXRoTGluZU5VbSB7ICAvLyB0 b2RvIC0gdXNlIG9yIHJlbW92ZSAtIHRvZG8NCgkJLy8JcHVibGljIA0KCX0NCg0KDQoJcHVibGlj IGludGVyZmFjZSBJSGFzVGFibGVBbGlhcyB7DQoJCS8vIEhhcyBhIHRhYmxlIGFsaWFzIEFTVCBv YmouIE1heSBiZSBhIC4uLk1pc3Npbmcgc3VidHlwZSBpbiB3aGljaA0KCQkvLyBpdCBoYXMgbm8g YWxpYXMgZ2l2ZW4gYnkgdGhlIHVzZXIsIGJ1dCBhbGlhcyBBU1QgaXMgdGhlcmUuIE1vcmUNCgkJ Ly8gYWNjdXJhdGVseSBhIFRhYmxlU291cmNlIGFsaWFzIGJ1dCBvaw0KCQlwdWJsaWMgYWJzdHJh Y3QgVGFibGVBbGlhcyB0YSB7IGdldDsgc2V0OyB9DQoJfQ0KDQoNCgkvLyBCYXNlIGNsYXNzIGZv ciBhbGwgTERCIEFTVCBvYmplY3RzDQoJcHVibGljIGFic3RyYWN0IGNsYXNzIExEQkFTVG9iaiA6 IExEQlJvb3Qgew0KCQkvLyBUaGlzIG9uZSBpcyBhIHByb2JsZW0uIElmIEkgZGVjbGFyZSB0aGUg J3BhcmVudCcgcHJvcGVydHkNCgkJLy8gYWJzdHJhY3QgSSB0aGVuIGhhdmUgdG8gaW1wbGVtZW50 IGl0IGxpdGVyYWxseSBodW5kcmVkcyBvZg0KCQkvLyB0aW1lcyBpbiB0aGUgZGVyaXZlZCBjbGFz c2VzLCBhbmQgSSByZWFsbHkgZG9uJ3QgdGhpbmsgaXQNCgkJLy8gd291bGQgaGVscCBzbyBqdXN0 IHNldCBpdCB0byBhIGRlZmF1bHQgd2hpY2ggZ2V0cyBvdmVyd3JpdHRlbiBsYXRlci4NCgkJLy8g DQoJCS8vIFRoZSBwcm9ibGVtIGlzIHRoYXQgdGhvc2Ugb2JqZWN0cyB3ZXJlIGNyZWF0ZWQgYnkg dGhlDQoJCS8vIHBhcnNlciwgd2hpY2ggY3JlYXRlcyB0aGVtIGJvdHRvbS11cCwgd2hpY2ggbWVh bnMgeW91IGNhbid0DQoJCS8vIGtub3cgdGhlIHBhcmVudCB3aGVuIHRoZXkgYXJlIGNyZWF0ZWQu IEl0IHNob3VsZCBiZQ0KCQkvLyBwb3NzaWJsZSB0byB3b3JrIGFyb3VuZCB0aGlzIGJ1dCBpdCBk b2VzIG1lYW4gcmV3b3JraW5nIHRoZQ0KCQkvLyBwYXJzZXIgZnVuZGFtZW50YWxseSwgYW5kIEkn bSBub3QgZ29pbmcgdG8gZG8gdGhhdA0KCQkvLyBhc3N1bWVpbmcgaXQncyBldmVuIHBvc3NpYmxl Lg0KDQoJCS8vIHRvZG8gLSByZWFkIHVwIG9uIHByaXYvcHViL3Byb2cgYWNjZXNzb3JzIEkgcmVh bGx5IGRvbid0DQoJCS8vIGdldCB0aGVzZSBhdCBhbGwNCgkJcHVibGljIExEQkFTVG9iaiBwYXJl bnQgeyBnZXQ7IHByaXZhdGUgc2V0OyB9DQoJCQkJCQk9IG5vUGFyZW50Ow0KCQkvLyBVbmlxdWUg SUQgcGVyIG9iamVjdCwgdXNlZnVsIGZvciBkaXN0aW5ndWlzaGluZyB0aGVtDQoJCS8vIHdpdGhv dXQgZ2VuZXJhbCBlcXVhbGl0eS4NCgkJcmVhZG9ubHkgcHVibGljIHVsb25nIHVpZCA9IG5ld1VJ RCgpOw0KDQoJCS8vIHB1YmxpYyBhYnN0cmFjdCBpbnQgbGluZU51bSB7IGdldDsgc2V0OyB9DQoN CgkJLy8gSXMgdmFsaWRhdGVkIGlzIGEgY2hlYXBpc2ggY2hlY2sgdG8gZW5zdXJlIGV2ZXJ5dGhp bmcgZ2V0cw0KCQkvLyB2YWxpZGF0ZWQNCgkJLy8gY2FuIGRvIHRoaXMgYXMgYXV0byBwcm9wPyB0 b2RvDQoJCXByaXZhdGUgYm9vbCBfdmFsaWRhdGVkID0gZmFsc2U7DQoNCgkJcHJvdGVjdGVkIGJv b2wgdmFsaWRhdGVkIHsNCgkJCWdldCA9PiBfdmFsaWRhdGVkOw0KCQkJc2V0IHsNCgkJCQkvLyBo YXJkTXVzdCghdmFsaWRhdGVkLCAiLi4uIGFscmVhZHkgdmFsaWRhdGVkLi4uICIpOyAtIG5vDQoJ CQkJLy8gSXQncyBoYXJkIHRvIGF2b2lkIHZhbGlkYXRpbmcgYSB0aGluZyB0d2ljZSwgc28gZm9y IG5vdyBhbGxvdyBpdA0KCQkJCS8vIExvb2sgaW50byBpdCBsYXRlciwgcmVhbGx5IHNob3VsZG4n dCBoYXBwZW4NCgkJCQlfdmFsaWRhdGVkID0gdHJ1ZTsNCgkJCX0NCgkJfQ0KDQoJCXB1YmxpYyBM REJTdHJ1Y3RzQ2hpbGRyZW4ga2lkcyB7IGdldDsgcHJpdmF0ZSBzZXQ7IH0gPQ0KCQkJCQluZXcg TERCU3RydWN0c0NoaWxkcmVuKG5vUGFyZW50KTsgLy8ganVzdCBlYXNpZXINCg0KCQlwdWJsaWMg TERCQVNUb2JqKCkgeyAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8v Ly8vLy8vLy8vLy8vLy8vLy8vLy8vLyB0b2RvIGRlYWQ/DQoJCQkJCQkJICAvLyBWU3R1ZGlvIHRo aW5rcyB0aGlzIGhhcyB6ZXJvIHJlZmVyZW5jZXMsIHdoaWNoIGlzIHRydWUgZXhwbGljaXRseSwg YnV0IGl0J3MgDQoJCQkJCQkJICAvLyBjYWxsZWQgaW1wbGljaXRseSBvbiBldmVyeSBvYmogY3Jl YXRpb24gLSBvciBzaG91bGQgZG8gdG9kby0gY2hlY2sNCgkJCWlmIChyZWNvcmRPYmplY3RzQ3Jl YXRlZCkgew0KCQkJCUFsbENyZWF0ZWRJdGVtcy5BZGQodGhpcyk7DQoJCQl9DQoJCX0NCg0KDQoJ CXB1YmxpYyB2aXJ0dWFsIHZvaWQgdmFsaWRhdGUoKSB7DQoJCQlpZiAocmVwb3J0QWxzb0lmVmFs aWRhdGlvbk9LKSB7DQoJCQkJZGVidWdtc2coInZhbGlkYXRpbmcuLi4iICsgY2xhc3NOYW1lDQoJ CQkJCSsgIiAoIiArIGFzTmFtZU9ySWRlbnRDb250ZW50cygpICsgIikiKTsNCgkJCX0NCgkJCW1o cF9taGsoKTsNCgkJCWtpZHMudmFsaWRhdGUoKTsNCgkJCS8vIHZhbGlkYXRlZCA9IHRydWU7IC0t IE5vLCBnZXQgZWFjaCBzdWJjbGFzcyB0byBzZXQNCgkJCS8vIHZhbGlkYXRlZC4gVGhhdCBmb3Jj ZXMgYW4gZXhwbGljaXQgY2FsbCB0byBiYXNlKCkgd2hpY2gNCgkJCS8vIGlzIG1vcmUgY29kZSBi dXQgb2suDQoJCX0NCg0KDQoJCXB1YmxpYyBib29sIGlzVmFsaWRhdGVkIHsgZ2V0ID0+IHZhbGlk YXRlZDsgfSAgLy8gdG9kbyBqdXN0ID0+IHZhbGlkYXRlZDsNCg0KDQoJCXB1YmxpYyB2aXJ0dWFs IGJvb2wgaXNUb3BMZXZlbEl0ZW1TZXEgPT4gZmFsc2U7DQoNCg0KCQlwdWJsaWMgdmlydHVhbCB2 b2lkIG1ocF9taGsoKSB7ICAvLyBkb24ndCB0aGluayB0aGlzIG5lZWQgYmUgdmlydHVhbCAtIHRv ZG8/DQoJCQkJCQkJCQkJIC8vID0gbXVzdCBoYXZlIHBhcmVudCwgbXVzdCBoYXZlIGtpZHMuIFRo ZSBraWRzIG1heSBiZSB0aGUNCgkJCQkJCQkJCQkgLy8gZW1wdHkgc2V0IGFuZCB0aGUgcGFyZW50 IG1heSBiZSBub1BhcmVudCBidXQgdGhleSBtdXN0DQoJCQkJCQkJCQkJIC8vIGV4aXN0Lg0KCQkJ CQkJCQkJCSAvLyBXaHkgbm90IGp1c3QgaW5saW5lIHRoaXMgaW50byB2YWxpZGF0ZSgpPw0KCQkJ CQkJCQkJCSAvLyBCZWNhdXNlIGEgZmV3IGNsYXNzZXMgbmVlZCBiZXNwb2tlIHZhbGlkYXRpb24s IGJ1dCBzdGlsbCBtdXN0IGNoZWNrIHRoaXMuDQoJCQloYXJkTXVzdFBhcmVudElzUHJlc2VudCgp Ow0KCQkJa2lkcy5lYWNoS2lkUGFyZW50TXVzdEJlKHRoaXMpOw0KCQl9DQoNCg0KCQlwdWJsaWMg c3RyaW5nIGFzTmFtZU9ySWRlbnRDb250ZW50cygpIHsNCgkJCS8vIGZvciB2ZXJ5IGNydWRlIGRl YnVnZ2luZyANCgkJCXZhciBvcHROYW1lID0gdGhpcyBpcyBJaXNOYW1lZEl0ZW0gbmkgPyBuaS5u YW1lLnRvUmF3U3RyKCkgOiAiIjsNCgkJCW9wdE5hbWUgPSAob3B0TmFtZSA9PSAiIiAmJiB0aGlz IGlzIFBNUUlkZW50KSA/IHRoaXMudG9SYXdTdHIoKSA6ICIiOw0KDQoJCQl2YXIgb3B0TmFtZTIg PSBvcHROYW1lICsgIiAgKHVpZDoiICsgdWlkLlRvU3RyaW5nKCkgKyAiKSAiDQoJCQkJKyBnZXRG aXJzdEZld0NoYXJzT2YodG9SYXdTdHIoKSk7DQoJCQlyZXR1cm4gb3B0TmFtZTI7DQoJCX0NCg0K DQoJCXB1YmxpYyB2aXJ0dWFsIHZvaWQgZ2V0QWxsVUlEcyhVSURzZXQgdWlkcykgew0KCQkJdWlk cy5BZGQodGhpcyk7DQoJCQlraWRzLkZvckVhY2gobmFtZWRLaWQgPT4gbmFtZWRLaWQua2lkLmdl dEFsbFVJRHModWlkcykpOw0KCQl9DQoNCg0KCQlwdWJsaWMgYm9vbCBpc1N0dWJQYXJlbnQgeyBn ZXQgPT4gKHRoaXMgaXMgTm9QYXJlbnQpIHx8ICh0aGlzIGlzIEZha2VQYXJlbnQpOyB9DQoNCg0K CQlwdWJsaWMgdm9pZCB2YWxpZGF0ZVNwZWNpZmljSXRlbXMocGFyYW1zIExEQkFTVG9ialtdIGl0 ZW1zKSB7DQoJCQlBcnJheS5Gb3JFYWNoKGl0ZW1zLCBpdGVtID0+IGl0ZW0udmFsaWRhdGUoKSk7 DQoJCX0NCg0KDQoJCXB1YmxpYyBUPyBvcHRDbGltYlRvPFQ+KCkgd2hlcmUgVCA6IExEQkFTVG9i aiB7DQoJCQl2YXIgcmVzSXRlbSA9IHRoaXM7DQoJCQl3aGlsZSAoIShyZXNJdGVtIGlzIFQpKSB7 DQoJCQkJaWYgKHJlc0l0ZW0ucGFyZW50LmlzU3R1YlBhcmVudCkgew0KCQkJCQlyZXR1cm4gbnVs bDsNCgkJCQl9DQoJCQkJcmVzSXRlbSA9IHJlc0l0ZW0ucGFyZW50Ow0KCQkJfQ0KDQoJCQl2YXIg cmVzID0gcmVzSXRlbSBhcyBUOw0KCQkJcmV0dXJuIHJlczsNCgkJfQ0KDQoNCgkJcHVibGljIFQg cmVxQ2xpbWJUbzxUPigpIHdoZXJlIFQgOiBMREJBU1RvYmogew0KCQkJdmFyIGxvYyA9IGNsYXNz TmFtZSArICIucmVxQ2xpbWJUbzxUPigpIjsNCgkJCXZhciByZXMgPSBvcHRDbGltYlRvPFQ+KCk7 DQoJCQloYXJkTXVzdDIoIShyZXMgaXMgbnVsbCksIA0KCQkJCS8vIFRoYW5rcyBTTyA8aHR0cHM6 Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvMjU4MTY0Mi9ob3ctZG8taS1nZXQtdGhlLXR5 cGUtbmFtZS1vZi1hLWdlbmVyaWMtdHlwZS1hcmd1bWVudD4NCgkJCQkvLyBUb2RvIC0gdXNlIHRo aXMgZWxzZXdoZXJlLCBwb3NzIEV4cGVjdEV4Y2VwdGlvbj8gdG9kbw0KCQkJCSgpID0+DQoJCQkJ bG9jIA0KCQkJCSsgbmwgKyAiLCBjbGltYmVkIHRvIHRvcCwgZGlkbid0IGZpbmQgdHlwZSAiDQoJ CQkJKyB0eXBlb2YoVCkuRnVsbE5hbWUNCgkJCQkrIG5sICsgIkhpZXJhcmNoeSBpczogIg0KCQkJ CSsgbmwgKyBnZXRJdGVtV2l0aFBhcmVudHModGhpcykpOw0KCQkJaWYgKHJlcyBpcyBudWxsKSB7 IHRocm93IG5ldyBOTlFDKCk7IH0NCgkJCXJldHVybiByZXM7DQoJCX0NCg0KDQoJCXB1YmxpYyB2 b2lkIGhhcmRNdXN0UGFyZW50SXNQcmVzZW50KCkgew0KDQoJCQloYXJkTXVzdDIoIShwYXJlbnQg aXMgbnVsbCksIA0KCQkJCSgpID0+DQoJCQkJICJOVUxMIHBhcmVudCBmb3IgaXRlbSBvZiB0eXBl XG4iDQoJCQkJICsgJCJ7R2V0VHlwZSgpfVxuLiIpOw0KDQoJCQloYXJkTXVzdDIoISh0aGlzLnBh cmVudCBpcyBOb1BhcmVudCksDQoJCQkJKCkgPT4NCgkJCQkiUGFyZW50IGlzIE5vUGFyZW50IG9u IG9iamVjdCBvZiB0eXBlXG4iDQoJCQkJKyAkIid7dGhpcy5jbGFzc05hbWV9JyIpOw0KCQl9DQoN Cg0KCQlwdWJsaWMgdm9pZCBoYXJkTXVzdFBhcmVudElzQWJzZW50KCkgew0KCQkJLy8gRm9yIGNo ZWNraW5nIGNsb25pbmcgLSBwYXJlbnQgc2hvdWxkIGJlIE5vUGFyZW50IGltbWVkaWF0ZWx5IA0K CQkJLy8gYWZ0ZXIsIGJlZm9yZSBpdCdzIHNldCBieSBwYXJlbnQsIGFuZCBuZXZlciBudWxsDQoJ CQloYXJkTXVzdCghKHBhcmVudCBpcyBudWxsKSwNCgkJCQkgIk5VTEwgcGFyZW50IGZvciBpdGVt IG9mIHR5cGVcbiINCgkJCQkgKyAkIntHZXRUeXBlKCl9XG4uIik7DQoJCQloYXJkTXVzdCgodGhp cy5wYXJlbnQgaXMgTm9QYXJlbnQpLA0KCQkJCSJQYXJlbnQgc2hvdWxkIGJlIE5vUGFyZW50IG9u IG9iamVjdCBvZiB0eXBlXG4iDQoJCQkJKyAkIid7dGhpcy5jbGFzc05hbWV9JyIpOw0KCQl9DQoN Cg0KCQlwdWJsaWMgYm9vbCBoYXNQYXJlbnQ8UD4oKSB7DQoJCQloYXJkTXVzdCghKHRoaXMgaXMg Tm9QYXJlbnQpLCAiSXRlbSBpcyBOb1BhcmVudCIpOw0KCQkJcmV0dXJuIHRoaXMucGFyZW50IGlz IFA7DQoJCX0NCg0KDQoJCXB1YmxpYyBib29sIGhhc0FuY2VzdG9yPEE+KCkgew0KCQkJaGFyZE11 c3QoIXRoaXMuaXNTdHViUGFyZW50LCAiSXRlbSBpcyBOb1BhcmVudCIpOw0KDQoJCQkvLyBob3cg dG8gZG8gd2l0aCBhIHN3aXRjaCBleHByPw0KCQkJaWYgKHRoaXMucGFyZW50LmlzU3R1YlBhcmVu dCAvKiBpcyBOb1BhcmVudCB8fCB0aGlzLnBhcmVudCBpcyBGYWtlUGFyZW50Ki8gKSB7IC8vIHRv ZG8gZG8gYXMgeC5oYXNGdWRnZWRQYXJlbnQoKSAtIHRvZG8NCgkJCQlyZXR1cm4gZmFsc2U7DQoJ CQl9IGVsc2UgaWYgKHRoaXMucGFyZW50IGlzIEEpIHsNCgkJCQlyZXR1cm4gdHJ1ZTsNCgkJCX0g ZWxzZSB7DQoJCQkJcmV0dXJuIHRoaXMucGFyZW50Lmhhc0FuY2VzdG9yPEE+KCk7DQoJCQl9DQoJ CX0NCg0KCQlwdWJsaWMgYm9vbCBub3RIYXNBbmNlc3RvcjxBPigpID0+DQoJCQkhaGFzQW5jZXN0 b3I8QT4oKTsNCg0KDQoJCXB1YmxpYyB2b2lkIHNldE15UGFyZW50VG8oTERCQVNUb2JqIHBybnQp IHsNCgkJCS8vIEFuIG9iamVjdCBtYXkgb25seSBzZXQgaXRzIHBhcmVudCBpZiBpdHMgY3VycmVu dCBwYXJlbnQgaXMNCgkJCS8vIHRoZSBkdW1teSAnbm9QYXJlbnQnLCB3aGljaCBhbG1vc3QgZXZl cnkgb2JqZWN0J3MgcGFyZW50IGlzDQoJCQkvLyBzZXQgdG8gb24gY3JlYXRpb24gKHNlZSBMREJB U1RvYmogcGFyZW50IHByb3BlcnR5IGRlZikuDQoNCgkJCS8vIFRoZSB0ZXN0IGZvciBudWxsIGlz IHBlY3VsaWFyIGdpdmVuIHRoaXMuIEJlY2F1c2UNCgkJCS8vIG5vUGFyZW50IGlzIGNyZWF0ZWQg c3RhdGljYWxseSwgc2V0dGluZyB0aGUgcGFyZW50IG9mDQoJCQkvLyBub1BhcmVudCBpcyBkaWZm aWN1bHQsIHBlcmhhcHMgaW1wb3NzaWJsZSwgdG8gZG8gc3RhdGljYWxseQ0KCQkJLy8gYW5kIHJl bGlhYmx5LkRlc3BpdGUgdGhlIGRlY2xhcmF0aW9uICcjbnVsbGFibGUgZW5hYmxlJywgaXQNCgkJ CS8vIGdldHMgY3JlYXRlZCB3aXRoIGEgbnVsbCBwYXJyZW50IChxdWl0ZSByZWFzb25hYmx5KSwg aGVuY2UNCgkJCS8vIHRoaXMgY2hlY2suVGhlIGFjdHVhbCBzZXR0aW5nIG9mIHRoZSBwYXJlbnQg aGFzIHRvIGJlIGRvbmUNCgkJCS8vIGF0IHJ1bnRpbWUgaS5lLmFmdGVyIHRoZSBzdGF0aWMgY3Jl YXRpb24gb2YgJ25vUGFyZW50Jy4NCg0KCQkJaGFyZE11c3QyKCh0aGlzLnBhcmVudCBpcyBOb1Bh cmVudCkgfHwgKHRoaXMucGFyZW50IGlzIG51bGwpLA0KCQkJCSgpID0+DQoJCQkJInRyaWVkIHRv IHJlLXNldCBwYXJlbnQgb24gb2JqZWN0IG9mIHR5cGU6ICINCgkJCQkrIG5sICsgdGhpcy5jbGFz c05hbWVRDQoJCQkJKyBubCArICJPcmlnaW5hbCBwYXJlbnQgdHlwZSBpczogIg0KCQkJCSsgKHRo aXM/LnBhcmVudD8uY2xhc3NOYW1lUSA9PSBudWxsID8gIm51bGwiIDogdGhpcy5wYXJlbnQuY2xh c3NOYW1lUSkNCgkJCQkrIG5sICsgImFuZCBuZXcgcGFyZW50IHR5cGUgaXM6ICINCgkJCQkrIHBy bnQuY2xhc3NOYW1lUQ0KCQkJCSsgbmwgKyAiSXRlbSBoYXZpbmcgcGFyZW50IHNldCBvbiBpdCBp czogIg0KCQkJCS8vIGJlY2F1c2Ugb2JqZWN0IG1heSBub3QgYmUgZnVsbHkgY29uc3RydWN0ZWQg eWV0LCBjaGVjayBob3d2ZXIgVE9ETyB0aGlzIGlzIGEgbWFqb3IgaGFjayBhbmQgbXVzdCBiZSBm aXhlZCBzb21ldGltZS4NCi8vCQkJCSsgbmwgKyAodGhpcyBpcyBudWxsID8gIihudWxsKSIgOiB0 aGlzLnRvUmF3U3RyKCkpKTsNCgkJCQkrIG5sICsgdGhpcy50b1Jhd1N0cigpICk7DQoNCgkJCXBh cmVudCA9IHBybnQ7DQoJCX0NCg0KDQoJCXB1YmxpYyB2b2lkIGZvcmNlTmV3UGFyZW50Rm9yUm9v dE9iamVjdCgpIHsNCgkJCS8vIEV2ZXJ5IG9iamVjdCBtdXN0IGhhdmUgc29tZSBwYXJlbnQsIGlu Y2x1ZGluZyB0aGUNCgkJCS8vIHJvb3Qgb2JqZWN0IG9mIHRoZSBwYXJzZSwgd2hpY2ggaXMgTERC aXRlbXMNCgkJCS8vIChhIHNlcXVlbmNlIG9mIExEQiBpdGVtcyksIHNvIHRoaXMgZm9yY2VzIG9u ZS4NCgkJCS8vIEl0IGlzIG9ubHkgZm9yIHRoYXQgcHVycG9zZSENCgkJCS8vIA0KCQkJLy8gTERC aXRlbXMgb2JqIGV4aXN0cyBmb3Igc3ViIG9ianMgc3VjaCBhcyB0aGUgc3RhdGVtZW50cw0KCQkJ Ly8gaW4gYSB3aGlsZSBsb29wLCBpbiBhIHByb2MsIGluIGFuIGlmLi4uIGV0Yy4sIGZvcg0KCQkJ Ly8gd2hpY2ggdGhlaXIgcGFyZW50IGlzIHRoZSB3aGlsZS9wcm9jL2lmIGV0Yy4NCgkJCWhhcmRN dXN0UGFyZW50SXNBYnNlbnQoKTsNCgkJCXRoaXMucGFyZW50ID0gZmFrZVBhcmVudDsNCgkJfQ0K DQoNCgkJLy9wdWJsaWMgdm9pZCByZXNldE15UGFyZW50VG8oTERCQVNUb2JqIHBybnQpIHsgIC8v Ly8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8gZGVzdHJveSEhISEhISB0b2RvDQoJCS8v CXBhcmVudCA9IHBybnQ7DQoJCS8vfQ0KDQoJCS8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLyB4eHh4 eHh4eHh4eHh4IGRlbGV0ZSAtIHRvZG8NCgkJLy9wcml2YXRlIHZvaWQgc2V0UGFyZW50T25LaWQo TERCQVNUb2JqIGtpZCkgPT4gLy8gdG9kbyBuZWVkZWQ/DQoJCS8vCQkJCQkJCQkJCQkgIC8vIGNo ZWNrIHBhcmVudGUgZG9lc24ndCBleGlzdCAtIHRvZG8NCgkJLy8Ja2lkLnBhcmVudCA9IHRoaXM7 DQoNCgkJcHVibGljIHZpcnR1YWwgdm9pZCBzZXRQYXJlbnRPbktpZHNBbmRNYWtlS2lkc0RpY3Qo ICAvLyB0b2RvIC0gYW5kIGFkZCB0byBraWRzIGRpY3QNCgkJCQkJCQkJCQkJCQkJCSAvLyB0aGlz IG1peGVzIHVwIHNldHRpbmcgcGFyZW50IGFuZCBtYWtpbmcgY2hpbGQgZGljdC4gTm90IGdvb2Qu IC0gdG9kbw0KCQkJCQkJcGFyYW1zIChzdHJpbmcga2lkTmFtZSwgTERCQVNUb2JqIGtpZClbXSBr aWRzSW4pIHsNCgkJCXZhciBsb2MgPSBjbGFzc05hbWVQbHVzKCJzZXRQYXJlbnRPbktpZHNBbmRN YWtlS2lkc0RpY3QiKTsNCg0KCQkJdmFyIGtpZHNUb0FkZCA9IG5ldyBMREJTdHJ1Y3RzQ2hpbGRy ZW4odGhpcywga2lkc0luKTsNCgkJCWhhcmRNdXN0MihraWRzLmlzRW1wdHksDQoJCQkJKCkgPT4N CgkJCQkkInNldHRpbmcga2lkcyBvbiBwYXJlbnQgJ3tjbGFzc05hbWV9JyIgDQoJCQkJKyAid2hl biBraWRzIGlzIG5vdCBlbXB0eSwgIg0KCQkJCSsgJCJraWRzIGlzICh7a2lkcy5Db3VudH0ga2lk cyk6Ig0KCQkJCSsgbmwgKyBraWRzLnRvRGVidWdTdHIoKQ0KCQkJCSsgbmwgKyAkIlRyeWluZyB0 byBhZGRcbntraWRzVG9BZGQudG9EZWJ1Z1N0cigpfVxuIg0KCQkJCSsgJCJpbiB7Y2xhc3NOYW1l fSIpOw0KCQkJLy8gaWYgdGhlcmUgaXMgYW4gTERCU3RydWN0c0NoaWxkcmVuIGFuZCBhbm90aGVy IGNoaWxkLA0KCQkJLy8gdGhpcyB3aWxsIGJsb3cgdXAgLSB3aWxsIG5lZWQgdG8gZG8ga2lkcy5B ZGQgb3INCgkJCS8vIHNvbWV0aGluZyAtIGluIGZhY3QsIGtpZHMgbmVlZHMgdG8gYmUgY3JlYXRl ZCBpbiBvbmUNCgkJCS8vIGdvLCB3aGljaCBpcyB3aGF0IGhhcHBlbnMuDQoJCQlraWRzID0ga2lk c1RvQWRkOyAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8v Ly8vLy8vLy8vLy8gd2h5IHRoaXM/IHRvZG8NCgkJCUFycmF5LkZvckVhY2goa2lkc0luLCB4a2lk ID0+IGhhcmRNdXN0KCEoeGtpZC5raWQgaXMgbnVsbCksIGxvYywgIm51bGwga2lkIikpOw0KCQkJ QXJyYXkuRm9yRWFjaChraWRzSW4sIHhraWQgPT4geGtpZC5raWQuc2V0TXlQYXJlbnRUbyh0aGlz KSk7DQoJCX0NCg0KDQoJCXB1YmxpYyB2aXJ0dWFsIHZvaWQgc2V0UGFyZW50T25LaWRzQW5kQWRk VG9LaWRzRGljdCgNCgkJCQkJcGFyYW1zIChzdHJpbmcga2lkTmFtZSwgTERCQVNUb2JqIGtpZClb XSBraWRzSW4pIHsNCgkJCXZhciBraWRzVG9BZGRfanVzdEZvckVyclJlcG9ydGluZyA9IG5ldyBM REJTdHJ1Y3RzQ2hpbGRyZW4odGhpcywga2lkc0luKTsNCgkJCWhhcmRNdXN0Migha2lkcy5pc0Vt cHR5LCAvLyBtYXkgZGlzYWJsZSB0aGlzIGxhdGVyIA0KCQkJCSgpID0+DQoJCQkJImFkZGluZyB0 byBraWRzIHdoZW4ga2lkcyBpcyBlbXB0eSwgIg0KCQkJCSArICQia2lkcyBpc1xue2tpZHMudG9E ZWJ1Z1N0cigpfVxuIg0KCQkJCSArICQiVHJ5aW5nIHRvIGFkZFxue2tpZHNUb0FkZF9qdXN0Rm9y RXJyUmVwb3J0aW5nLnRvRGVidWdTdHIoKX1cbiINCgkJCQkgKyAkImluIHtjbGFzc05hbWV9Iik7 DQoJCQlBcnJheS5Gb3JFYWNoKGtpZHNJbiwgeGtpZCA9PiB7DQovLwkJCQlzZXRQYXJlbnRPbktp ZCh4a2lkLmtpZCk7DQoJCQkJeGtpZC5raWQuc2V0TXlQYXJlbnRUbyh0aGlzKTsNCgkJCQlraWRz LkFkZCh4a2lkKTsNCgkJCX0pOw0KCQl9DQoNCg0KCQlwdWJsaWMgdmlydHVhbCBJZGVudHNVc2Vk IGdldEFsbElEcygpIHsNCgkJLyogVGhpcyBpcyBvdmVycmlkZGVuIG9ubHkgaW4gVGVtcGxhdGVk QWdnLCBhbmQgdGhhdCdzIG9ubHkgdG8gDQoJCQlkZWxpYmVyYXRlbHkgZmFpbC4gVGhlcmUncyBz b21ldGhpbmcgd3JvbmcgdGhlcmUsIHRvZG8gLSANCgkJCXVuLXZpcnR1YWxpc2UgdGhpcyBhbmQg cmVtb3ZlIHRoZSBvbmUgb3ZlcnJpZGUuIC0gdG9kbw0KCQkqLw0KCQkJdmFyIGl1ID0gbmV3IElk ZW50c1VzZWQoKTsNCgkJCXRoaXMuX2dldEFsbElEcyhpdSk7DQoJCQlyZXR1cm4gaXU7DQoJCX0N Cg0KCQlwdWJsaWMgdmlydHVhbCB2b2lkIF9nZXRBbGxJRHMoSWRlbnRzVXNlZCBpdSkgew0KCQkv LyBHZXRzIGFsbCB0aGUgaWRlbnRpZmllcnMgZXhwbGljaXRseSB1c2VkIChyZWFkIG9yIHdyaXR0 ZW4pICAtLS0tLSB0b2RvIHVwZGF0ZSB0aGlzDQoJCS8vIGFueXdoZXJlIGluIHRoZSBBU1QuICBE b2VzIG5vdCBnZXQgaWRlbnRzIHdoaWNoIGFyZQ0KCQkvLyBkZWNsYXJhdGlvbnMgaWUuIHBhcmFt ZXRlcnMsIG9yIHZhci9jb25zdCBkZWNsYXJhdGlvbnMNCgkJLy8gdW5sZXNzIHRoZXNlIGFyZSBj b21iaW5lZCB3aXRoIGFuIGFzc2lnbm1lbnQuDQoJCS8vDQoJCS8vIEltcGxpZWQgaWRlbnRzIHN1 Y2ggYXMgdGhvc2UgZnJvbSB0YmwuKiBhcmUgaW1wbGljaXQgYW5kIGlnbm9yZWQuDQoJCS8vDQoJ CS8vIFJvb3QgY2FsbGVyIHN1cHBsaWVzIG5ldywgZW1wdHkgaXUNCgkJLy8gbmVlZCB1c2FnZSBo ZXJlIC0gdG9kbyBkb2NzLy8NCgkJCWtpZHMuX2dldEFsbElEcyhpdSk7DQoJCX0NCg0KCQlwdWJs aWMgYWJzdHJhY3QgYm9vbCBjYW5HZXRBbGxJZGVudHNVc2VkIHsNCgkJLy8gCVRoaXMgc2VlbXMg dG8gYmUgdHJ1ZSBvbiBtb3N0IGNsYXNzZXMgc28gSSBjb3VsZCBzZXQgdHJ1ZSANCgkJLy8gYXMg YSBkZWZhdWx0IGhlcmUgYW5kIG92ZXJyaWRlIGl0IHdoZXJlIGl0J3Mgbm90IHdhbnRlZCwgc2F2 aW5nIA0KCQkvLyBhIGNodW5rIG9mIGNvZGUsIGJ1dCBJJ2QgcmF0aGVyIG1ha2UgaXQgZXhwbGlj aXQgdG8gZm9yY2UgbWUgdG8gY29uc2lkZXIgZWFjaCBjYXNlLiBBIGJpdCBtb3JlIEMmUCBmb3Ig bGVzcyBjaGFuY2Ugb2YgYnVncy4NCgkJCWdldDsNCgkJfQ0KDQoNCgkJLy8gUHJvZHVjZXMgYSBz dHJpbmcgdGhhdCBzaG91bGQgYmUgaWRlbnRpY2FsIHRvIChleGNlcHRpbmcNCgkJLy8gd2hpdGVz cGFjZXMpIHRoZSBpbnB1dCBpZS4gZW1pdCBMREIgY29kZSBub3QgdmFsaWQgU1FMDQoJCS8vDQoJ CS8vIFRvU3RyaW5nIHdhcyBjYXVzaW5nIHRvbyBtYW55IHdlaXJkIHByb2JsZW1zIChkdWUgdG8g bXkNCgkJLy8gaW5leHBlcmllbmNlIHdpdGggYyMpIHNvIGp1c3QgdXNlZCB0b1Jhd1N0cigpDQoJ CXB1YmxpYyBhYnN0cmFjdCBzdHJpbmcgdG9SYXdTdHIoKTsNCg0KCQlwdWJsaWMgb3ZlcnJpZGUg c3RyaW5nIHRvRGVidWdTdHIoKSA9PiB0b1Jhd1N0cigpOw0KDQoJfSAvLyBlbmQgTERCQVNUb2Jq DQoNCg0KDQoJcHVibGljIGludGVyZmFjZSBJaGFuZGxlUHJlZml4ZXM8VD4NCgkJCQkJCXdoZXJl IFQgOiBMREJSb290IHsNCg0KCQlwdWJsaWMgYm9vbCBpc1ByZWZpeGVkIHsgZ2V0OyB9DQoNCgkJ cHVibGljIGJvb2wgaXNFeGNlc3NQcmVmaXhlZCB7IGdldDsgfQ0KDQoJCS8vIFRoZSBUIGluIGFk ZFByZWZpeC9yZVByZWZpeC93aXRob3V0UHJlZml4IGlzIGJlY2F1c2Ugd2UgbWF5IGJlIA0KCQkv LyByZXR1cm5pbmcgZWcuIGEgbGlzdCBvZiBpdGVtcyB3aXRoIHByZWZpeGVzIA0KCQkvLyB0aHVz IG1vZGlmaWVkLCBub3QgYSBzaW5nbGUgUE1RSWRlbnQNCg0KCQlwdWJsaWMgVCBhZGRQcmVmaXgo UE1RSWRlbnQgcGZ4KTsNCg0KCQlwdWJsaWMgVCByZVByZWZpeChQTVFJZGVudCBuZXdwZngpOw0K DQovLwkJcHVibGljIFQgc3RyaXBQcmVmaXgoUE1RSWRlbnQgaWQpOw0KCX0NCgkvLyB0b2RvIC0g bW92ZSB0aGlzDQoNCg0KDQoNCg0KCXB1YmxpYyBhYnN0cmFjdCBjbGFzcyBMREJSb290IHsNCgkJ Ly8gUm9vdCBvZiBldmVyeXRoaW5nIExEQi1pc2gNCg0KCQlwdWJsaWMgYm9vbCBFcXVhbHMoW0Fs bG93TnVsbF0gTERCUm9vdCBvdGhlcikgew0KCQkJdGhyb3cgbmV3IExEQlNob3VsZE5vdEJlSW1w bGVtZW50ZWRFeGNlcHRpb24oDQoJCQkJCQkJCQkiY2FsbGVkIEVxdWFscyBvbiBMREJSb290Iik7 DQoJCX0NCg0KCQlwdWJsaWMgb3ZlcnJpZGUNCgkJCWJvb2wgRXF1YWxzKFtBbGxvd051bGxdIE9i amVjdCBvdGhlcikgew0KCQkJdGhyb3cgbmV3IExEQlNob3VsZE5vdEJlSW1wbGVtZW50ZWRFeGNl cHRpb24oDQoJCQkJCQkJCQkiY2FsbGVkIEVxdWFscyBpbiBPYmplY3QiKTsNCgkJfQ0KDQoJCXB1 YmxpYyBvdmVycmlkZSBpbnQgR2V0SGFzaENvZGUoKSB7DQoJCQl0aHJvdyBuZXcgTERCU2hvdWxk Tm90QmVJbXBsZW1lbnRlZEV4Y2VwdGlvbigNCgkJCQkJCQkJCSJjYWxsZWQgR2V0SGFzaENvZGUg aW4gTERCUm9vdCIpOw0KCQl9DQoNCgkJcHVibGljIHN0YXRpYyBib29sIG9wZXJhdG9yID09KExE QlJvb3QgbGhzLA0KCQkJCQkJCQkJICAgTERCUm9vdCByaHMpIHsNCgkJCXRocm93IG5ldyBMREJT aG91bGROb3RCZUltcGxlbWVudGVkRXhjZXB0aW9uKA0KCQkJCQkJCQkJImNhbGxlZCA9PSBpbiBM REJSb290Iik7DQoJCX0NCg0KCQlwdWJsaWMgc3RhdGljIGJvb2wgb3BlcmF0b3IgIT0oTERCUm9v dCBsaHMsDQoJCQkJCQkJCQkgICBMREJSb290IHJocykgew0KCQkJdGhyb3cgbmV3IExEQlNob3Vs ZE5vdEJlSW1wbGVtZW50ZWRFeGNlcHRpb24oDQoJCQkJCQkJCQkiY2FsbGVkICE9IGluIExEQlJv b3QiKTsNCgkJfQ0KDQoNCgkJcHVibGljIHZpcnR1YWwgc3RyaW5nIGNsYXNzTmFtZSB7DQoJCQkv LyB0b2RvIC0gdGhpcyBuZWVkcyBjaGVja2luZyBpdCB3b3JrcyBhcyBJIHdhbnQNCgkJCS8vIGFs c28gcmVuYW1lIHRvIGxkYmNsYXNzbmFtZSAtLSB0b2RvDQoJCQlnZXQgPT4gdGhpcy5HZXRUeXBl KCkuRnVsbE5hbWUgPz8gIih1bmtub3duKSI7DQoJCX0NCg0KDQoJCXB1YmxpYyB2aXJ0dWFsIHN0 cmluZyBjbGFzc05hbWVRID0+DQoJCQkiJyIgKyBjbGFzc05hbWUgKyAiJyI7DQoNCg0KCQlwdWJs aWMgdmlydHVhbCBzdHJpbmcgY2xhc3NOYW1lUGx1cyhzdHJpbmcgcGx1cykgPT4NCgkJCWNsYXNz TmFtZSArICIuIiArIHBsdXM7DQoNCgkJcHVibGljIG92ZXJyaWRlIHN0cmluZyBUb1N0cmluZygp IHsNCgkJCS8vIFRoaXMgaW1wbGljaXQgdG8tc3RyaW5nIGNvbnZlcnNpb24gY3JhcCBjb3N0IG1l IGEgZmV3IGhvdXJzLCBzbyBhdCBsZWFzdA0KCQkJLy8gZG8gdGhpcyAmIGJsb3cgdXAgYXQgcnVu dGltZS4gV291bGQgcHJlZmVyIGNvbXBpbGUgdGltZSBidXQgaXQgc2VlbXMNCgkJCS8vIG5vdCBw b3NzaWJsZS4gIFRoaXMgdHVybnMgb3V0IHRvIGhhdmUgYmVlbiBhIGdvb2QgaWRlYSwNCgkJCS8v IHNhdmVkIG1lIHF1aXRlIGEgYml0IG1vcmUgZGVidWdnaW5nIQ0KCQkJLy8gPGh0dHBzOi8vc3Rh Y2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzE1MzQ1NTE3L2lzLWl0LXBvc3NpYmxlLXRvLWRpc2Fi bGUtaW1wbGljaXQtdG9zdHJpbmctY2FsbD4NCgkJCS8vIFdpbGwgdHJ5IDxodHRwczovL3N0YWNr b3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy81NDM1NDM0Mi9ob3ctdG8tZ2V0LWFuLWVycm9yLXNob3du LXdoZW4tdXNpbmctbm9uLXN0cmluZ3MtYXMtc3RyaW5ncy1pbnN0ZWFkLW9mLWFuLWF1dG9tLzU0 MzU1MTE1IzU0MzU1MTE1KQ0KCQkJdmFyIG1zZyA9ICJMREJSb290LlRvU3RyaW5nKCkiOw0KCQkJ dGhyb3cgbmV3IExEQlRvU3RyaW5nSW1wbGljdENvbnZlcnNpb25FeGNlcHRpb24obXNnKTsNCgkJ fQ0KDQoJCXB1YmxpYyBhYnN0cmFjdCBzdHJpbmcgdG9EZWJ1Z1N0cigpOw0KCX0NCg0KDQoNCglw dWJsaWMgYWJzdHJhY3QgY2xhc3MgRXBoZW1lcmFsIDogTERCUm9vdCB7DQoJCS8vIGZvciBvYmpl Y3RzIHRoYXQgYXJlIG5vdCBwYXJ0IG9mIHRoZSBBU1QNCgl9DQoNCg0KDQoJcHVibGljIGludGVy ZmFjZSBJV2l0aExpbmVOVW0geyAgLy8gdG9kbyAtIHVzZSBvciByZW1vdmUgLSB0b2RvDQoJCS8v CXB1YmxpYyANCgl9DQoNCg0KCXB1YmxpYyBpbnRlcmZhY2UgSUhhc1RhYmxlQWxpYXMgew0KCQkv LyBIYXMgYSB0YWJsZSBhbGlhcyBBU1Qgb2JqLiBNYXkgYmUgYSAuLi5NaXNzaW5nIHN1YnR5cGUg aW4gd2hpY2gNCgkJLy8gaXQgaGFzIG5vIGFsaWFzIGdpdmVuIGJ5IHRoZSB1c2VyLCBidXQgYWxp YXMgQVNUIGlzIHRoZXJlLiBNb3JlDQoJCS8vIGFjY3VyYXRlbHkgYSBUYWJsZVNvdXJjZSBhbGlh cyBidXQgb2sNCgkJcHVibGljIGFic3RyYWN0IFRhYmxlQWxpYXMgdGEgeyBnZXQ7IHNldDsgfQ0K CX0NCg0KDQoJLy8gQmFzZSBjbGFzcyBmb3IgYWxsIExEQiBBU1Qgb2JqZWN0cw0KCXB1YmxpYyBh YnN0cmFjdCBjbGFzcyBMREJBU1RvYmogOiBMREJSb290IHsNCgkJLy8gVGhpcyBvbmUgaXMgYSBw cm9ibGVtLiBJZiBJIGRlY2xhcmUgdGhlICdwYXJlbnQnIHByb3BlcnR5DQoJCS8vIGFic3RyYWN0 IEkgdGhlbiBoYXZlIHRvIGltcGxlbWVudCBpdCBsaXRlcmFsbHkgaHVuZHJlZHMgb2YNCgkJLy8g dGltZXMgaW4gdGhlIGRlcml2ZWQgY2xhc3NlcywgYW5kIEkgcmVhbGx5IGRvbid0IHRoaW5rIGl0 DQoJCS8vIHdvdWxkIGhlbHAgc28ganVzdCBzZXQgaXQgdG8gYSBkZWZhdWx0IHdoaWNoIGdldHMg b3ZlcndyaXR0ZW4gbGF0ZXIuDQoJCS8vIA0KCQkvLyBUaGUgcHJvYmxlbSBpcyB0aGF0IHRob3Nl IG9iamVjdHMgd2VyZSBjcmVhdGVkIGJ5IHRoZQ0KCQkvLyBwYXJzZXIsIHdoaWNoIGNyZWF0ZXMg dGhlbSBib3R0b20tdXAsIHdoaWNoIG1lYW5zIHlvdSBjYW4ndA0KCQkvLyBrbm93IHRoZSBwYXJl bnQgd2hlbiB0aGV5IGFyZSBjcmVhdGVkLiBJdCBzaG91bGQgYmUNCgkJLy8gcG9zc2libGUgdG8g d29yayBhcm91bmQgdGhpcyBidXQgaXQgZG9lcyBtZWFuIHJld29ya2luZyB0aGUNCgkJLy8gcGFy c2VyIGZ1bmRhbWVudGFsbHksIGFuZCBJJ20gbm90IGdvaW5nIHRvIGRvIHRoYXQNCgkJLy8gYXNz dW1laW5nIGl0J3MgZXZlbiBwb3NzaWJsZS4NCg0KCQkvLyB0b2RvIC0gcmVhZCB1cCBvbiBwcml2 L3B1Yi9wcm9nIGFjY2Vzc29ycyBJIHJlYWxseSBkb24ndA0KCQkvLyBnZXQgdGhlc2UgYXQgYWxs DQoJCXB1YmxpYyBMREJBU1RvYmogcGFyZW50IHsgZ2V0OyBwcml2YXRlIHNldDsgfQ0KCQkJCQkJ PSBub1BhcmVudDsNCgkJLy8gVW5pcXVlIElEIHBlciBvYmplY3QsIHVzZWZ1bCBmb3IgZGlzdGlu Z3Vpc2hpbmcgdGhlbQ0KCQkvLyB3aXRob3V0IGdlbmVyYWwgZXF1YWxpdHkuDQoJCXJlYWRvbmx5 IHB1YmxpYyB1bG9uZyB1aWQgPSBuZXdVSUQoKTsNCg0KCQkvLyBwdWJsaWMgYWJzdHJhY3QgaW50 IGxpbmVOdW0geyBnZXQ7IHNldDsgfQ0KDQoJCS8vIElzIHZhbGlkYXRlZCBpcyBhIGNoZWFwaXNo IGNoZWNrIHRvIGVuc3VyZSBldmVyeXRoaW5nIGdldHMNCgkJLy8gdmFsaWRhdGVkDQoJCS8vIGNh biBkbyB0aGlzIGFzIGF1dG8gcHJvcD8gdG9kbw0KCQlwcml2YXRlIGJvb2wgX3ZhbGlkYXRlZCA9 IGZhbHNlOw0KDQoJCXByb3RlY3RlZCBib29sIHZhbGlkYXRlZCB7DQoJCQlnZXQgPT4gX3ZhbGlk YXRlZDsNCgkJCXNldCB7DQoJCQkJLy8gaGFyZE11c3QoIXZhbGlkYXRlZCwgIi4uLiBhbHJlYWR5 IHZhbGlkYXRlZC4uLiAiKTsgLSBubw0KCQkJCS8vIEl0J3MgaGFyZCB0byBhdm9pZCB2YWxpZGF0 aW5nIGEgdGhpbmcgdHdpY2UsIHNvIGZvciBub3cgYWxsb3cgaXQNCgkJCQkvLyBMb29rIGludG8g aXQgbGF0ZXIsIHJlYWxseSBzaG91bGRuJ3QgaGFwcGVuDQoJCQkJX3ZhbGlkYXRlZCA9IHRydWU7 DQoJCQl9DQoJCX0NCg0KCQlwdWJsaWMgTERCU3RydWN0c0NoaWxkcmVuIGtpZHMgeyBnZXQ7IHBy aXZhdGUgc2V0OyB9ID0NCgkJCQkJbmV3IExEQlN0cnVjdHNDaGlsZHJlbihub1BhcmVudCk7IC8v IGp1c3QgZWFzaWVyDQoNCgkJcHVibGljIExEQkFTVG9iaigpIHsgIC8vLy8vLy8vLy8vLy8vLy8v Ly8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8gdG9kbyBkZWFk Pw0KCQkJCQkJCSAgLy8gVlN0dWRpbyB0aGlua3MgdGhpcyBoYXMgemVybyByZWZlcmVuY2VzLCB3 aGljaCBpcyB0cnVlIGV4cGxpY2l0bHksIGJ1dCBpdCdzIA0KCQkJCQkJCSAgLy8gY2FsbGVkIGlt cGxpY2l0bHkgb24gZXZlcnkgb2JqIGNyZWF0aW9uIC0gb3Igc2hvdWxkIGRvIHRvZG8tIGNoZWNr DQoJCQlpZiAocmVjb3JkT2JqZWN0c0NyZWF0ZWQpIHsNCgkJCQlBbGxDcmVhdGVkSXRlbXMuQWRk KHRoaXMpOw0KCQkJfQ0KCQl9DQoNCg0KCQlwdWJsaWMgdmlydHVhbCB2b2lkIHZhbGlkYXRlKCkg ew0KCQkJaWYgKHJlcG9ydEFsc29JZlZhbGlkYXRpb25PSykgew0KCQkJCWRlYnVnbXNnKCJ2YWxp ZGF0aW5nLi4uIiArIGNsYXNzTmFtZQ0KCQkJCQkrICIgKCIgKyBhc05hbWVPcklkZW50Q29udGVu dHMoKSArICIpIik7DQoJCQl9DQoJCQltaHBfbWhrKCk7DQoJCQlraWRzLnZhbGlkYXRlKCk7DQoJ CQkvLyB2YWxpZGF0ZWQgPSB0cnVlOyAtLSBObywgZ2V0IGVhY2ggc3ViY2xhc3MgdG8gc2V0DQoJ CQkvLyB2YWxpZGF0ZWQuIFRoYXQgZm9yY2VzIGFuIGV4cGxpY2l0IGNhbGwgdG8gYmFzZSgpIHdo aWNoDQoJCQkvLyBpcyBtb3JlIGNvZGUgYnV0IG9rLg0KCQl9DQoNCg0KCQlwdWJsaWMgYm9vbCBp c1ZhbGlkYXRlZCB7IGdldCA9PiB2YWxpZGF0ZWQ7IH0gIC8vIHRvZG8ganVzdCA9PiB2YWxpZGF0 ZWQ7DQoNCg0KCQlwdWJsaWMgdmlydHVhbCBib29sIGlzVG9wTGV2ZWxJdGVtU2VxID0+IGZhbHNl Ow0KDQoNCgkJcHVibGljIHZpcnR1YWwgdm9pZCBtaHBfbWhrKCkgeyAgLy8gZG9uJ3QgdGhpbmsg dGhpcyBuZWVkIGJlIHZpcnR1YWwgLSB0b2RvPw0KCQkJCQkJCQkJCSAvLyA9IG11c3QgaGF2ZSBw YXJlbnQsIG11c3QgaGF2ZSBraWRzLiBUaGUga2lkcyBtYXkgYmUgdGhlDQoJCQkJCQkJCQkJIC8v IGVtcHR5IHNldCBhbmQgdGhlIHBhcmVudCBtYXkgYmUgbm9QYXJlbnQgYnV0IHRoZXkgbXVzdA0K CQkJCQkJCQkJCSAvLyBleGlzdC4NCgkJCQkJCQkJCQkgLy8gV2h5IG5vdCBqdXN0IGlubGluZSB0 aGlzIGludG8gdmFsaWRhdGUoKT8NCgkJCQkJCQkJCQkgLy8gQmVjYXVzZSBhIGZldyBjbGFzc2Vz IG5lZWQgYmVzcG9rZSB2YWxpZGF0aW9uLCBidXQgc3RpbGwgbXVzdCBjaGVjayB0aGlzLg0KCQkJ aGFyZE11c3RQYXJlbnRJc1ByZXNlbnQoKTsNCgkJCWtpZHMuZWFjaEtpZFBhcmVudE11c3RCZSh0 aGlzKTsNCgkJfQ0KDQoNCgkJcHVibGljIHN0cmluZyBhc05hbWVPcklkZW50Q29udGVudHMoKSB7 DQoJCQkvLyBmb3IgdmVyeSBjcnVkZSBkZWJ1Z2dpbmcgDQoJCQl2YXIgb3B0TmFtZSA9IHRoaXMg aXMgSWlzTmFtZWRJdGVtIG5pID8gbmkubmFtZS50b1Jhd1N0cigpIDogIiI7DQoJCQlvcHROYW1l ID0gKG9wdE5hbWUgPT0gIiIgJiYgdGhpcyBpcyBQTVFJZGVudCkgPyB0aGlzLnRvUmF3U3RyKCkg OiAiIjsNCg0KCQkJdmFyIG9wdE5hbWUyID0gb3B0TmFtZSArICIgICh1aWQ6IiArIHVpZC5Ub1N0 cmluZygpICsgIikgIg0KCQkJCSsgZ2V0Rmlyc3RGZXdDaGFyc09mKHRvUmF3U3RyKCkpOw0KCQkJ cmV0dXJuIG9wdE5hbWUyOw0KCQl9DQoNCg0KCQlwdWJsaWMgdmlydHVhbCB2b2lkIGdldEFsbFVJ RHMoVUlEc2V0IHVpZHMpIHsNCgkJCXVpZHMuQWRkKHRoaXMpOw0KCQkJa2lkcy5Gb3JFYWNoKG5h bWVkS2lkID0+IG5hbWVkS2lkLmtpZC5nZXRBbGxVSURzKHVpZHMpKTsNCgkJfQ0KDQoNCgkJcHVi bGljIGJvb2wgaXNTdHViUGFyZW50IHsgZ2V0ID0+ICh0aGlzIGlzIE5vUGFyZW50KSB8fCAodGhp cyBpcyBGYWtlUGFyZW50KTsgfQ0KDQoNCgkJcHVibGljIHZvaWQgdmFsaWRhdGVTcGVjaWZpY0l0 ZW1zKHBhcmFtcyBMREJBU1RvYmpbXSBpdGVtcykgew0KCQkJQXJyYXkuRm9yRWFjaChpdGVtcywg aXRlbSA9PiBpdGVtLnZhbGlkYXRlKCkpOw0KCQl9DQoNCg0KCQlwdWJsaWMgVD8gb3B0Q2xpbWJU bzxUPigpIHdoZXJlIFQgOiBMREJBU1RvYmogew0KCQkJdmFyIHJlc0l0ZW0gPSB0aGlzOw0KCQkJ d2hpbGUgKCEocmVzSXRlbSBpcyBUKSkgew0KCQkJCWlmIChyZXNJdGVtLnBhcmVudC5pc1N0dWJQ YXJlbnQpIHsNCgkJCQkJcmV0dXJuIG51bGw7DQoJCQkJfQ0KCQkJCXJlc0l0ZW0gPSByZXNJdGVt LnBhcmVudDsNCgkJCX0NCg0KCQkJdmFyIHJlcyA9IHJlc0l0ZW0gYXMgVDsNCgkJCXJldHVybiBy ZXM7DQoJCX0NCg0KDQoJCXB1YmxpYyBUIHJlcUNsaW1iVG88VD4oKSB3aGVyZSBUIDogTERCQVNU b2JqIHsNCgkJCXZhciBsb2MgPSBjbGFzc05hbWUgKyAiLnJlcUNsaW1iVG88VD4oKSI7DQoJCQl2 YXIgcmVzID0gb3B0Q2xpbWJUbzxUPigpOw0KCQkJaGFyZE11c3QyKCEocmVzIGlzIG51bGwpLCAN CgkJCQkvLyBUaGFua3MgU08gPGh0dHBzOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzI1 ODE2NDIvaG93LWRvLWktZ2V0LXRoZS10eXBlLW5hbWUtb2YtYS1nZW5lcmljLXR5cGUtYXJndW1l bnQ+DQoJCQkJLy8gVG9kbyAtIHVzZSB0aGlzIGVsc2V3aGVyZSwgcG9zcyBFeHBlY3RFeGNlcHRp b24/IHRvZG8NCgkJCQkoKSA9Pg0KCQkJCWxvYyANCgkJCQkrIG5sICsgIiwgY2xpbWJlZCB0byB0 b3AsIGRpZG4ndCBmaW5kIHR5cGUgIg0KCQkJCSsgdHlwZW9mKFQpLkZ1bGxOYW1lDQoJCQkJKyBu bCArICJIaWVyYXJjaHkgaXM6ICINCgkJCQkrIG5sICsgZ2V0SXRlbVdpdGhQYXJlbnRzKHRoaXMp KTsNCgkJCWlmIChyZXMgaXMgbnVsbCkgeyB0aHJvdyBuZXcgTk5RQygpOyB9DQoJCQlyZXR1cm4g cmVzOw0KCQl9DQoNCg0KCQlwdWJsaWMgdm9pZCBoYXJkTXVzdFBhcmVudElzUHJlc2VudCgpIHsN Cg0KCQkJaGFyZE11c3QyKCEocGFyZW50IGlzIG51bGwpLCANCgkJCQkoKSA9Pg0KCQkJCSAiTlVM TCBwYXJlbnQgZm9yIGl0ZW0gb2YgdHlwZVxuIg0KCQkJCSArICQie0dldFR5cGUoKX1cbi4iKTsN Cg0KCQkJaGFyZE11c3QyKCEodGhpcy5wYXJlbnQgaXMgTm9QYXJlbnQpLA0KCQkJCSgpID0+DQoJ CQkJIlBhcmVudCBpcyBOb1BhcmVudCBvbiBvYmplY3Qgb2YgdHlwZVxuIg0KCQkJCSsgJCIne3Ro aXMuY2xhc3NOYW1lfSciKTsNCgkJfQ0KDQoNCgkJcHVibGljIHZvaWQgaGFyZE11c3RQYXJlbnRJ c0Fic2VudCgpIHsNCgkJCS8vIEZvciBjaGVja2luZyBjbG9uaW5nIC0gcGFyZW50IHNob3VsZCBi ZSBOb1BhcmVudCBpbW1lZGlhdGVseSANCgkJCS8vIGFmdGVyLCBiZWZvcmUgaXQncyBzZXQgYnkg cGFyZW50LCBhbmQgbmV2ZXIgbnVsbA0KCQkJaGFyZE11c3QoIShwYXJlbnQgaXMgbnVsbCksDQoJ CQkJICJOVUxMIHBhcmVudCBmb3IgaXRlbSBvZiB0eXBlXG4iDQoJCQkJICsgJCJ7R2V0VHlwZSgp fVxuLiIpOw0KCQkJaGFyZE11c3QoKHRoaXMucGFyZW50IGlzIE5vUGFyZW50KSwNCgkJCQkiUGFy ZW50IHNob3VsZCBiZSBOb1BhcmVudCBvbiBvYmplY3Qgb2YgdHlwZVxuIg0KCQkJCSsgJCIne3Ro aXMuY2xhc3NOYW1lfSciKTsNCgkJfQ0KDQoNCgkJcHVibGljIGJvb2wgaGFzUGFyZW50PFA+KCkg ew0KCQkJaGFyZE11c3QoISh0aGlzIGlzIE5vUGFyZW50KSwgIkl0ZW0gaXMgTm9QYXJlbnQiKTsN CgkJCXJldHVybiB0aGlzLnBhcmVudCBpcyBQOw0KCQl9DQoNCg0KCQlwdWJsaWMgYm9vbCBoYXNB bmNlc3RvcjxBPigpIHsNCgkJCWhhcmRNdXN0KCF0aGlzLmlzU3R1YlBhcmVudCwgIkl0ZW0gaXMg Tm9QYXJlbnQiKTsNCg0KCQkJLy8gaG93IHRvIGRvIHdpdGggYSBzd2l0Y2ggZXhwcj8NCgkJCWlm ICh0aGlzLnBhcmVudC5pc1N0dWJQYXJlbnQgLyogaXMgTm9QYXJlbnQgfHwgdGhpcy5wYXJlbnQg aXMgRmFrZVBhcmVudCovICkgeyAvLyB0b2RvIGRvIGFzIHguaGFzRnVkZ2VkUGFyZW50KCkgLSB0 b2RvDQoJCQkJcmV0dXJuIGZhbHNlOw0KCQkJfSBlbHNlIGlmICh0aGlzLnBhcmVudCBpcyBBKSB7 DQoJCQkJcmV0dXJuIHRydWU7DQoJCQl9IGVsc2Ugew0KCQkJCXJldHVybiB0aGlzLnBhcmVudC5o YXNBbmNlc3RvcjxBPigpOw0KCQkJfQ0KCQl9DQoNCgkJcHVibGljIGJvb2wgbm90SGFzQW5jZXN0 b3I8QT4oKSA9Pg0KCQkJIWhhc0FuY2VzdG9yPEE+KCk7DQoNCg0KCQlwdWJsaWMgdm9pZCBzZXRN eVBhcmVudFRvKExEQkFTVG9iaiBwcm50KSB7DQoJCQkvLyBBbiBvYmplY3QgbWF5IG9ubHkgc2V0 IGl0cyBwYXJlbnQgaWYgaXRzIGN1cnJlbnQgcGFyZW50IGlzDQoJCQkvLyB0aGUgZHVtbXkgJ25v UGFyZW50Jywgd2hpY2ggYWxtb3N0IGV2ZXJ5IG9iamVjdCdzIHBhcmVudCBpcw0KCQkJLy8gc2V0 IHRvIG9uIGNyZWF0aW9uIChzZWUgTERCQVNUb2JqIHBhcmVudCBwcm9wZXJ0eSBkZWYpLg0KDQoJ CQkvLyBUaGUgdGVzdCBmb3IgbnVsbCBpcyBwZWN1bGlhciBnaXZlbiB0aGlzLiBCZWNhdXNlDQoJ CQkvLyBub1BhcmVudCBpcyBjcmVhdGVkIHN0YXRpY2FsbHksIHNldHRpbmcgdGhlIHBhcmVudCBv Zg0KCQkJLy8gbm9QYXJlbnQgaXMgZGlmZmljdWx0LCBwZXJoYXBzIGltcG9zc2libGUsIHRvIGRv IHN0YXRpY2FsbHkNCgkJCS8vIGFuZCByZWxpYWJseS5EZXNwaXRlIHRoZSBkZWNsYXJhdGlvbiAn I251bGxhYmxlIGVuYWJsZScsIGl0DQoJCQkvLyBnZXRzIGNyZWF0ZWQgd2l0aCBhIG51bGwgcGFy cmVudCAocXVpdGUgcmVhc29uYWJseSksIGhlbmNlDQoJCQkvLyB0aGlzIGNoZWNrLlRoZSBhY3R1 YWwgc2V0dGluZyBvZiB0aGUgcGFyZW50IGhhcyB0byBiZSBkb25lDQoJCQkvLyBhdCBydW50aW1l IGkuZS5hZnRlciB0aGUgc3RhdGljIGNyZWF0aW9uIG9mICdub1BhcmVudCcuDQoNCgkJCWhhcmRN dXN0MigodGhpcy5wYXJlbnQgaXMgTm9QYXJlbnQpIHx8ICh0aGlzLnBhcmVudCBpcyBudWxsKSwN CgkJCQkoKSA9Pg0KCQkJCSJ0cmllZCB0byByZS1zZXQgcGFyZW50IG9uIG9iamVjdCBvZiB0eXBl OiAiDQoJCQkJKyBubCArIHRoaXMuY2xhc3NOYW1lUQ0KCQkJCSsgbmwgKyAiT3JpZ2luYWwgcGFy ZW50IHR5cGUgaXM6ICINCgkJCQkrICh0aGlzPy5wYXJlbnQ/LmNsYXNzTmFtZVEgPT0gbnVsbCA/ ICJudWxsIiA6IHRoaXMucGFyZW50LmNsYXNzTmFtZVEpDQoJCQkJKyBubCArICJhbmQgbmV3IHBh cmVudCB0eXBlIGlzOiAiDQoJCQkJKyBwcm50LmNsYXNzTmFtZVENCgkJCQkrIG5sICsgIkl0ZW0g aGF2aW5nIHBhcmVudCBzZXQgb24gaXQgaXM6ICINCgkJCQkvLyBiZWNhdXNlIG9iamVjdCBtYXkg bm90IGJlIGZ1bGx5IGNvbnN0cnVjdGVkIHlldCwgY2hlY2sgaG93dmVyIFRPRE8gdGhpcyBpcyBh IG1ham9yIGhhY2sgYW5kIG11c3QgYmUgZml4ZWQgc29tZXRpbWUuDQovLwkJCQkrIG5sICsgKHRo aXMgaXMgbnVsbCA/ICIobnVsbCkiIDogdGhpcy50b1Jhd1N0cigpKSk7DQoJCQkJKyBubCArIHRo aXMudG9SYXdTdHIoKSApOw0KDQoJCQlwYXJlbnQgPSBwcm50Ow0KCQl9DQoNCg0KCQlwdWJsaWMg dm9pZCBmb3JjZU5ld1BhcmVudEZvclJvb3RPYmplY3QoKSB7DQoJCQkvLyBFdmVyeSBvYmplY3Qg bXVzdCBoYXZlIHNvbWUgcGFyZW50LCBpbmNsdWRpbmcgdGhlDQoJCQkvLyByb290IG9iamVjdCBv ZiB0aGUgcGFyc2UsIHdoaWNoIGlzIExEQml0ZW1zDQoJCQkvLyAoYSBzZXF1ZW5jZSBvZiBMREIg aXRlbXMpLCBzbyB0aGlzIGZvcmNlcyBvbmUuDQoJCQkvLyBJdCBpcyBvbmx5IGZvciB0aGF0IHB1 cnBvc2UhDQoJCQkvLyANCgkJCS8vIExEQml0ZW1zIG9iaiBleGlzdHMgZm9yIHN1YiBvYmpzIHN1 Y2ggYXMgdGhlIHN0YXRlbWVudHMNCgkJCS8vIGluIGEgd2hpbGUgbG9vcCwgaW4gYSBwcm9jLCBp biBhbiBpZi4uLiBldGMuLCBmb3INCgkJCS8vIHdoaWNoIHRoZWlyIHBhcmVudCBpcyB0aGUgd2hp bGUvcHJvYy9pZiBldGMuDQoJCQloYXJkTXVzdFBhcmVudElzQWJzZW50KCk7DQoJCQl0aGlzLnBh cmVudCA9IGZha2VQYXJlbnQ7DQoJCX0NCg0KDQoJCS8vcHVibGljIHZvaWQgcmVzZXRNeVBhcmVu dFRvKExEQkFTVG9iaiBwcm50KSB7ICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8v IGRlc3Ryb3khISEhISEgdG9kbw0KCQkvLwlwYXJlbnQgPSBwcm50Ow0KCQkvL30NCg0KCQkvLy8v Ly8vLy8vLy8vLy8vLy8vLy8vLy8geHh4eHh4eHh4eHh4eCBkZWxldGUgLSB0b2RvDQoJCS8vcHJp dmF0ZSB2b2lkIHNldFBhcmVudE9uS2lkKExEQkFTVG9iaiBraWQpID0+IC8vIHRvZG8gbmVlZGVk Pw0KCQkvLwkJCQkJCQkJCQkJICAvLyBjaGVjayBwYXJlbnRlIGRvZXNuJ3QgZXhpc3QgLSB0b2Rv DQoJCS8vCWtpZC5wYXJlbnQgPSB0aGlzOw0KDQoJCXB1YmxpYyB2aXJ0dWFsIHZvaWQgc2V0UGFy ZW50T25LaWRzQW5kTWFrZUtpZHNEaWN0KCAgLy8gdG9kbyAtIGFuZCBhZGQgdG8ga2lkcyBkaWN0 DQoJCQkJCQkJCQkJCQkJCQkgLy8gdGhpcyBtaXhlcyB1cCBzZXR0aW5nIHBhcmVudCBhbmQgbWFr aW5nIGNoaWxkIGRpY3QuIE5vdCBnb29kLiAtIHRvZG8NCgkJCQkJCXBhcmFtcyAoc3RyaW5nIGtp ZE5hbWUsIExEQkFTVG9iaiBraWQpW10ga2lkc0luKSB7DQoJCQl2YXIgbG9jID0gY2xhc3NOYW1l UGx1cygic2V0UGFyZW50T25LaWRzQW5kTWFrZUtpZHNEaWN0Iik7DQoNCgkJCXZhciBraWRzVG9B ZGQgPSBuZXcgTERCU3RydWN0c0NoaWxkcmVuKHRoaXMsIGtpZHNJbik7DQoJCQloYXJkTXVzdDIo a2lkcy5pc0VtcHR5LA0KCQkJCSgpID0+DQoJCQkJJCJzZXR0aW5nIGtpZHMgb24gcGFyZW50ICd7 Y2xhc3NOYW1lfSciIA0KCQkJCSsgIndoZW4ga2lkcyBpcyBub3QgZW1wdHksICINCgkJCQkrICQi a2lkcyBpcyAoe2tpZHMuQ291bnR9IGtpZHMpOiINCgkJCQkrIG5sICsga2lkcy50b0RlYnVnU3Ry KCkNCgkJCQkrIG5sICsgJCJUcnlpbmcgdG8gYWRkXG57a2lkc1RvQWRkLnRvRGVidWdTdHIoKX1c biINCgkJCQkrICQiaW4ge2NsYXNzTmFtZX0iKTsNCgkJCS8vIGlmIHRoZXJlIGlzIGFuIExEQlN0 cnVjdHNDaGlsZHJlbiBhbmQgYW5vdGhlciBjaGlsZCwNCgkJCS8vIHRoaXMgd2lsbCBibG93IHVw IC0gd2lsbCBuZWVkIHRvIGRvIGtpZHMuQWRkIG9yDQoJCQkvLyBzb21ldGhpbmcgLSBpbiBmYWN0 LCBraWRzIG5lZWRzIHRvIGJlIGNyZWF0ZWQgaW4gb25lDQoJCQkvLyBnbywgd2hpY2ggaXMgd2hh dCBoYXBwZW5zLg0KCQkJa2lkcyA9IGtpZHNUb0FkZDsgICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8v Ly8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vIHdoeSB0aGlzPyB0b2RvDQoJCQlB cnJheS5Gb3JFYWNoKGtpZHNJbiwgeGtpZCA9PiBoYXJkTXVzdCghKHhraWQua2lkIGlzIG51bGwp LCBsb2MsICJudWxsIGtpZCIpKTsNCgkJCUFycmF5LkZvckVhY2goa2lkc0luLCB4a2lkID0+IHhr aWQua2lkLnNldE15UGFyZW50VG8odGhpcykpOw0KCQl9DQoNCg0KCQlwdWJsaWMgdmlydHVhbCB2 b2lkIHNldFBhcmVudE9uS2lkc0FuZEFkZFRvS2lkc0RpY3QoDQoJCQkJCXBhcmFtcyAoc3RyaW5n IGtpZE5hbWUsIExEQkFTVG9iaiBraWQpW10ga2lkc0luKSB7DQoJCQl2YXIga2lkc1RvQWRkX2p1 c3RGb3JFcnJSZXBvcnRpbmcgPSBuZXcgTERCU3RydWN0c0NoaWxkcmVuKHRoaXMsIGtpZHNJbik7 DQoJCQloYXJkTXVzdDIoIWtpZHMuaXNFbXB0eSwgLy8gbWF5IGRpc2FibGUgdGhpcyBsYXRlciAN CgkJCQkoKSA9Pg0KCQkJCSJhZGRpbmcgdG8ga2lkcyB3aGVuIGtpZHMgaXMgZW1wdHksICINCgkJ CQkgKyAkImtpZHMgaXNcbntraWRzLnRvRGVidWdTdHIoKX1cbiINCgkJCQkgKyAkIlRyeWluZyB0 byBhZGRcbntraWRzVG9BZGRfanVzdEZvckVyclJlcG9ydGluZy50b0RlYnVnU3RyKCl9XG4iDQoJ CQkJICsgJCJpbiB7Y2xhc3NOYW1lfSIpOw0KCQkJQXJyYXkuRm9yRWFjaChraWRzSW4sIHhraWQg PT4gew0KLy8JCQkJc2V0UGFyZW50T25LaWQoeGtpZC5raWQpOw0KCQkJCXhraWQua2lkLnNldE15 UGFyZW50VG8odGhpcyk7DQoJCQkJa2lkcy5BZGQoeGtpZCk7DQoJCQl9KTsNCgkJfQ0KDQoNCgkJ cHVibGljIHZpcnR1YWwgSWRlbnRzVXNlZCBnZXRBbGxJRHMoKSB7DQoJCS8qIFRoaXMgaXMgb3Zl cnJpZGRlbiBvbmx5IGluIFRlbXBsYXRlZEFnZywgYW5kIHRoYXQncyBvbmx5IHRvIA0KCQkJZGVs aWJlcmF0ZWx5IGZhaWwuIFRoZXJlJ3Mgc29tZXRoaW5nIHdyb25nIHRoZXJlLCB0b2RvIC0gDQoJ CQl1bi12aXJ0dWFsaXNlIHRoaXMgYW5kIHJlbW92ZSB0aGUgb25lIG92ZXJyaWRlLiAtIHRvZG8N CgkJKi8NCgkJCXZhciBpdSA9IG5ldyBJZGVudHNVc2VkKCk7DQoJCQl0aGlzLl9nZXRBbGxJRHMo aXUpOw0KCQkJcmV0dXJuIGl1Ow0KCQl9DQoNCgkJcHVibGljIHZpcnR1YWwgdm9pZCBfZ2V0QWxs SURzKElkZW50c1VzZWQgaXUpIHsNCgkJLy8gR2V0cyBhbGwgdGhlIGlkZW50aWZpZXJzIGV4cGxp Y2l0bHkgdXNlZCAocmVhZCBvciB3cml0dGVuKSAgLS0tLS0gdG9kbyB1cGRhdGUgdGhpcw0KCQkv LyBhbnl3aGVyZSBpbiB0aGUgQVNULiAgRG9lcyBub3QgZ2V0IGlkZW50cyB3aGljaCBhcmUNCgkJ Ly8gZGVjbGFyYXRpb25zIGllLiBwYXJhbWV0ZXJzLCBvciB2YXIvY29uc3QgZGVjbGFyYXRpb25z DQoJCS8vIHVubGVzcyB0aGVzZSBhcmUgY29tYmluZWQgd2l0aCBhbiBhc3NpZ25tZW50Lg0KCQkv Lw0KCQkvLyBJbXBsaWVkIGlkZW50cyBzdWNoIGFzIHRob3NlIGZyb20gdGJsLiogYXJlIGltcGxp Y2l0IGFuZCBpZ25vcmVkLg0KCQkvLw0KCQkvLyBSb290IGNhbGxlciBzdXBwbGllcyBuZXcsIGVt cHR5IGl1DQoJCS8vIG5lZWQgdXNhZ2UgaGVyZSAtIHRvZG8gZG9jcy8vDQoJCQlraWRzLl9nZXRB bGxJRHMoaXUpOw0KCQl9DQoNCgkJcHVibGljIGFic3RyYWN0IGJvb2wgY2FuR2V0QWxsSWRlbnRz VXNlZCB7DQoJCS8vIAlUaGlzIHNlZW1zIHRvIGJlIHRydWUgb24gbW9zdCBjbGFzc2VzIHNvIEkg Y291bGQgc2V0IHRydWUgDQoJCS8vIGFzIGEgZGVmYXVsdCBoZXJlIGFuZCBvdmVycmlkZSBpdCB3 aGVyZSBpdCdzIG5vdCB3YW50ZWQsIHNhdmluZyANCgkJLy8gYSBjaHVuayBvZiBjb2RlLCBidXQg SSdkIHJhdGhlciBtYWtlIGl0IGV4cGxpY2l0IHRvIGZvcmNlIG1lIHRvIGNvbnNpZGVyIGVhY2gg Y2FzZS4gQSBiaXQgbW9yZSBDJlAgZm9yIGxlc3MgY2hhbmNlIG9mIGJ1Z3MuDQoJCQlnZXQ7DQoJ CX0NCg0KDQoJCS8vIFByb2R1Y2VzIGEgc3RyaW5nIHRoYXQgc2hvdWxkIGJlIGlkZW50aWNhbCB0 byAoZXhjZXB0aW5nDQoJCS8vIHdoaXRlc3BhY2VzKSB0aGUgaW5wdXQgaWUuIGVtaXQgTERCIGNv ZGUgbm90IHZhbGlkIFNRTA0KCQkvLw0KCQkvLyBUb1N0cmluZyB3YXMgY2F1c2luZyB0b28gbWFu eSB3ZWlyZCBwcm9ibGVtcyAoZHVlIHRvIG15DQoJCS8vIGluZXhwZXJpZW5jZSB3aXRoIGMjKSBz byBqdXN0IHVzZWQgdG9SYXdTdHIoKQ0KCQlwdWJsaWMgYWJzdHJhY3Qgc3RyaW5nIHRvUmF3U3Ry KCk7DQoNCgkJcHVibGljIG92ZXJyaWRlIHN0cmluZyB0b0RlYnVnU3RyKCkgPT4gdG9SYXdTdHIo KTsNCg0KCX0gLy8gZW5kIExEQkFTVG9iag0KDQoNCg0KCXB1YmxpYyBpbnRlcmZhY2UgSWhhbmRs ZVByZWZpeGVzPFQ+DQoJCQkJCQl3aGVyZSBUIDogTERCUm9vdCB7DQoNCgkJcHVibGljIGJvb2wg aXNQcmVmaXhlZCB7IGdldDsgfQ0KDQoJCXB1YmxpYyBib29sIGlzRXhjZXNzUHJlZml4ZWQgeyBn ZXQ7IH0NCg0KCQkvLyBUaGUgVCBpbiBhZGRQcmVmaXgvcmVQcmVmaXgvd2l0aG91dFByZWZpeCBp cyBiZWNhdXNlIHdlIG1heSBiZSANCgkJLy8gcmV0dXJuaW5nIGVnLiBhIGxpc3Qgb2YgaXRlbXMg d2l0aCBwcmVmaXhlcyANCgkJLy8gdGh1cyBtb2RpZmllZCwgbm90IGEgc2luZ2xlIFBNUUlkZW50 DQoNCgkJcHVibGljIFQgYWRkUHJlZml4KFBNUUlkZW50IHBmeCk7DQoNCgkJcHVibGljIFQgcmVQ cmVmaXgoUE1RSWRlbnQgbmV3cGZ4KTsNCg0KLy8JCXB1YmxpYyBUIHN0cmlwUHJlZml4KFBNUUlk ZW50IGlkKTsNCgl9DQoJLy8gdG9kbyAtIG1vdmUgdGhpcw0KDQoNCg0KDQoNCglwdWJsaWMgYWJz dHJhY3QgY2xhc3MgTERCUm9vdCB7DQoJCS8vIFJvb3Qgb2YgZXZlcnl0aGluZyBMREItaXNoDQoN CgkJcHVibGljIGJvb2wgRXF1YWxzKFtBbGxvd051bGxdIExEQlJvb3Qgb3RoZXIpIHsNCgkJCXRo cm93IG5ldyBMREJTaG91bGROb3RCZUltcGxlbWVudGVkRXhjZXB0aW9uKA0KCQkJCQkJCQkJImNh bGxlZCBFcXVhbHMgb24gTERCUm9vdCIpOw0KCQl9DQoNCgkJcHVibGljIG92ZXJyaWRlDQoJCQli b29sIEVxdWFscyhbQWxsb3dOdWxsXSBPYmplY3Qgb3RoZXIpIHsNCgkJCXRocm93IG5ldyBMREJT aG91bGROb3RCZUltcGxlbWVudGVkRXhjZXB0aW9uKA0KCQkJCQkJCQkJImNhbGxlZCBFcXVhbHMg aW4gT2JqZWN0Iik7DQoJCX0NCg0KCQlwdWJsaWMgb3ZlcnJpZGUgaW50IEdldEhhc2hDb2RlKCkg ew0KCQkJdGhyb3cgbmV3IExEQlNob3VsZE5vdEJlSW1wbGVtZW50ZWRFeGNlcHRpb24oDQoJCQkJ CQkJCQkiY2FsbGVkIEdldEhhc2hDb2RlIGluIExEQlJvb3QiKTsNCgkJfQ0KDQoJCXB1YmxpYyBz dGF0aWMgYm9vbCBvcGVyYXRvciA9PShMREJSb290IGxocywNCgkJCQkJCQkJCSAgIExEQlJvb3Qg cmhzKSB7DQoJCQl0aHJvdyBuZXcgTERCU2hvdWxkTm90QmVJbXBsZW1lbnRlZEV4Y2VwdGlvbigN CgkJCQkJCQkJCSJjYWxsZWQgPT0gaW4gTERCUm9vdCIpOw0KCQl9DQoNCgkJcHVibGljIHN0YXRp YyBib29sIG9wZXJhdG9yICE9KExEQlJvb3QgbGhzLA0KCQkJCQkJCQkJICAgTERCUm9vdCByaHMp IHsNCgkJCXRocm93IG5ldyBMREJTaG91bGROb3RCZUltcGxlbWVudGVkRXhjZXB0aW9uKA0KCQkJ CQkJCQkJImNhbGxlZCAhPSBpbiBMREJSb290Iik7DQoJCX0NCg0KDQoJCXB1YmxpYyB2aXJ0dWFs IHN0cmluZyBjbGFzc05hbWUgew0KCQkJLy8gdG9kbyAtIHRoaXMgbmVlZHMgY2hlY2tpbmcgaXQg d29ya3MgYXMgSSB3YW50DQoJCQkvLyBhbHNvIHJlbmFtZSB0byBsZGJjbGFzc25hbWUgLS0gdG9k bw0KCQkJZ2V0ID0+IHRoaXMuR2V0VHlwZSgpLkZ1bGxOYW1lID8/ICIodW5rbm93bikiOw0KCQl9 DQoNCg0KCQlwdWJsaWMgdmlydHVhbCBzdHJpbmcgY2xhc3NOYW1lUSA9Pg0KCQkJIiciICsgY2xh c3NOYW1lICsgIiciOw0KDQoNCgkJcHVibGljIHZpcnR1YWwgc3RyaW5nIGNsYXNzTmFtZVBsdXMo c3RyaW5nIHBsdXMpID0+DQoJCQljbGFzc05hbWUgKyAiLiIgKyBwbHVzOw0KDQoJCXB1YmxpYyBv dmVycmlkZSBzdHJpbmcgVG9TdHJpbmcoKSB7DQoJCQkvLyBUaGlzIGltcGxpY2l0IHRvLXN0cmlu ZyBjb252ZXJzaW9uIGNyYXAgY29zdCBtZSBhIGZldyBob3Vycywgc28gYXQgbGVhc3QNCgkJCS8v IGRvIHRoaXMgJiBibG93IHVwIGF0IHJ1bnRpbWUuIFdvdWxkIHByZWZlciBjb21waWxlIHRpbWUg YnV0IGl0IHNlZW1zDQoJCQkvLyBub3QgcG9zc2libGUuICBUaGlzIHR1cm5zIG91dCB0byBoYXZl IGJlZW4gYSBnb29kIGlkZWEsDQoJCQkvLyBzYXZlZCBtZSBxdWl0ZSBhIGJpdCBtb3JlIGRlYnVn Z2luZyENCgkJCS8vIDxodHRwczovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy8xNTM0NTUx Ny9pcy1pdC1wb3NzaWJsZS10by1kaXNhYmxlLWltcGxpY2l0LXRvc3RyaW5nLWNhbGw+DQoJCQkv LyBXaWxsIHRyeSA8aHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvNTQzNTQzNDIv aG93LXRvLWdldC1hbi1lcnJvci1zaG93bi13aGVuLXVzaW5nLW5vbi1zdHJpbmdzLWFzLXN0cmlu Z3MtaW5zdGVhZC1vZi1hbi1hdXRvbS81NDM1NTExNSM1NDM1NTExNSkNCgkJCXZhciBtc2cgPSAi TERCUm9vdC5Ub1N0cmluZygpIjsNCgkJCXRocm93IG5ldyBMREJUb1N0cmluZ0ltcGxpY3RDb252 ZXJzaW9uRXhjZXB0aW9uKG1zZyk7DQoJCX0NCg0KCQlwdWJsaWMgYWJzdHJhY3Qgc3RyaW5nIHRv RGVidWdTdHIoKTsNCgl9DQoNCg0KDQoJcHVibGljIGFic3RyYWN0IGNsYXNzIEVwaGVtZXJhbCA6 IExEQlJvb3Qgew0KCQkvLyBmb3Igb2JqZWN0cyB0aGF0IGFyZSBub3QgcGFydCBvZiB0aGUgQVNU DQoJfQ0KDQoNCg0KCXB1YmxpYyBpbnRlcmZhY2UgSVdpdGhMaW5lTlVtIHsgIC8vIHRvZG8gLSB1 c2Ugb3IgcmVtb3ZlIC0gdG9kbw0KCQkvLwlwdWJsaWMgDQoJfQ0KDQoNCglwdWJsaWMgaW50ZXJm YWNlIElIYXNUYWJsZUFsaWFzIHsNCgkJLy8gSGFzIGEgdGFibGUgYWxpYXMgQVNUIG9iai4gTWF5 IGJlIGEgLi4uTWlzc2luZyBzdWJ0eXBlIGluIHdoaWNoDQoJCS8vIGl0IGhhcyBubyBhbGlhcyBn aXZlbiBieSB0aGUgdXNlciwgYnV0IGFsaWFzIEFTVCBpcyB0aGVyZS4gTW9yZQ0KCQkvLyBhY2N1 cmF0ZWx5IGEgVGFibGVTb3VyY2UgYWxpYXMgYnV0IG9rDQoJCXB1YmxpYyBhYnN0cmFjdCBUYWJs ZUFsaWFzIHRhIHsgZ2V0OyBzZXQ7IH0NCgl9DQoNCg0KCS8vIEJhc2UgY2xhc3MgZm9yIGFsbCBM REIgQVNUIG9iamVjdHMNCglwdWJsaWMgYWJzdHJhY3QgY2xhc3MgTERCQVNUb2JqIDogTERCUm9v dCB7DQoJCS8vIFRoaXMgb25lIGlzIGEgcHJvYmxlbS4gSWYgSSBkZWNsYXJlIHRoZSAncGFyZW50 JyBwcm9wZXJ0eQ0KCQkvLyBhYnN0cmFjdCBJIHRoZW4gaGF2ZSB0byBpbXBsZW1lbnQgaXQgbGl0 ZXJhbGx5IGh1bmRyZWRzIG9mDQoJCS8vIHRpbWVzIGluIHRoZSBkZXJpdmVkIGNsYXNzZXMsIGFu ZCBJIHJlYWxseSBkb24ndCB0aGluayBpdA0KCQkvLyB3b3VsZCBoZWxwIHNvIGp1c3Qgc2V0IGl0 IHRvIGEgZGVmYXVsdCB3aGljaCBnZXRzIG92ZXJ3cml0dGVuIGxhdGVyLg0KCQkvLyANCgkJLy8g VGhlIHByb2JsZW0gaXMgdGhhdCB0aG9zZSBvYmplY3RzIHdlcmUgY3JlYXRlZCBieSB0aGUNCgkJ Ly8gcGFyc2VyLCB3aGljaCBjcmVhdGVzIHRoZW0gYm90dG9tLXVwLCB3aGljaCBtZWFucyB5b3Ug Y2FuJ3QNCgkJLy8ga25vdyB0aGUgcGFyZW50IHdoZW4gdGhleSBhcmUgY3JlYXRlZC4gSXQgc2hv dWxkIGJlDQoJCS8vIHBvc3NpYmxlIHRvIHdvcmsgYXJvdW5kIHRoaXMgYnV0IGl0IGRvZXMgbWVh biByZXdvcmtpbmcgdGhlDQoJCS8vIHBhcnNlciBmdW5kYW1lbnRhbGx5LCBhbmQgSSdtIG5vdCBn b2luZyB0byBkbyB0aGF0DQoJCS8vIGFzc3VtZWluZyBpdCdzIGV2ZW4gcG9zc2libGUuDQoNCgkJ Ly8gdG9kbyAtIHJlYWQgdXAgb24gcHJpdi9wdWIvcHJvZyBhY2Nlc3NvcnMgSSByZWFsbHkgZG9u J3QNCgkJLy8gZ2V0IHRoZXNlIGF0IGFsbA0KCQlwdWJsaWMgTERCQVNUb2JqIHBhcmVudCB7IGdl dDsgcHJpdmF0ZSBzZXQ7IH0NCgkJCQkJCT0gbm9QYXJlbnQ7DQoJCS8vIFVuaXF1ZSBJRCBwZXIg b2JqZWN0LCB1c2VmdWwgZm9yIGRpc3Rpbmd1aXNoaW5nIHRoZW0NCgkJLy8gd2l0aG91dCBnZW5l cmFsIGVxdWFsaXR5Lg0KCQlyZWFkb25seSBwdWJsaWMgdWxvbmcgdWlkID0gbmV3VUlEKCk7DQoN CgkJLy8gcHVibGljIGFic3RyYWN0IGludCBsaW5lTnVtIHsgZ2V0OyBzZXQ7IH0NCg0KCQkvLyBJ cyB2YWxpZGF0ZWQgaXMgYSBjaGVhcGlzaCBjaGVjayB0byBlbnN1cmUgZXZlcnl0aGluZyBnZXRz DQoJCS8vIHZhbGlkYXRlZA0KCQkvLyBjYW4gZG8gdGhpcyBhcyBhdXRvIHByb3A/IHRvZG8NCgkJ cHJpdmF0ZSBib29sIF92YWxpZGF0ZWQgPSBmYWxzZTsNCg0KCQlwcm90ZWN0ZWQgYm9vbCB2YWxp ZGF0ZWQgew0KCQkJZ2V0ID0+IF92YWxpZGF0ZWQ7DQoJCQlzZXQgew0KCQkJCS8vIGhhcmRNdXN0 KCF2YWxpZGF0ZWQsICIuLi4gYWxyZWFkeSB2YWxpZGF0ZWQuLi4gIik7IC0gbm8NCgkJCQkvLyBJ dCdzIGhhcmQgdG8gYXZvaWQgdmFsaWRhdGluZyBhIHRoaW5nIHR3aWNlLCBzbyBmb3Igbm93IGFs bG93IGl0DQoJCQkJLy8gTG9vayBpbnRvIGl0IGxhdGVyLCByZWFsbHkgc2hvdWxkbid0IGhhcHBl bg0KCQkJCV92YWxpZGF0ZWQgPSB0cnVlOw0KCQkJfQ0KCQl9DQoNCgkJcHVibGljIExEQlN0cnVj dHNDaGlsZHJlbiBraWRzIHsgZ2V0OyBwcml2YXRlIHNldDsgfSA9DQoJCQkJCW5ldyBMREJTdHJ1 Y3RzQ2hpbGRyZW4obm9QYXJlbnQpOyAvLyBqdXN0IGVhc2llcg0KDQoJCXB1YmxpYyBMREJBU1Rv YmooKSB7ICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8v Ly8vLy8vLy8vLy8vLy8vIHRvZG8gZGVhZD8NCgkJCQkJCQkgIC8vIFZTdHVkaW8gdGhpbmtzIHRo aXMgaGFzIHplcm8gcmVmZXJlbmNlcywgd2hpY2ggaXMgdHJ1ZSBleHBsaWNpdGx5LCBidXQgaXQn cyANCgkJCQkJCQkgIC8vIGNhbGxlZCBpbXBsaWNpdGx5IG9uIGV2ZXJ5IG9iaiBjcmVhdGlvbiAt IG9yIHNob3VsZCBkbyB0b2RvLSBjaGVjaw0KCQkJaWYgKHJlY29yZE9iamVjdHNDcmVhdGVkKSB7 DQoJCQkJQWxsQ3JlYXRlZEl0ZW1zLkFkZCh0aGlzKTsNCgkJCX0NCgkJfQ0KDQoNCgkJcHVibGlj IHZpcnR1YWwgdm9pZCB2YWxpZGF0ZSgpIHsNCgkJCWlmIChyZXBvcnRBbHNvSWZWYWxpZGF0aW9u T0spIHsNCgkJCQlkZWJ1Z21zZygidmFsaWRhdGluZy4uLiIgKyBjbGFzc05hbWUNCgkJCQkJKyAi ICgiICsgYXNOYW1lT3JJZGVudENvbnRlbnRzKCkgKyAiKSIpOw0KCQkJfQ0KCQkJbWhwX21oaygp Ow0KCQkJa2lkcy52YWxpZGF0ZSgpOw0KCQkJLy8gdmFsaWRhdGVkID0gdHJ1ZTsgLS0gTm8sIGdl dCBlYWNoIHN1YmNsYXNzIHRvIHNldA0KCQkJLy8gdmFsaWRhdGVkLiBUaGF0IGZvcmNlcyBhbiBl eHBsaWNpdCBjYWxsIHRvIGJhc2UoKSB3aGljaA0KCQkJLy8gaXMgbW9yZSBjb2RlIGJ1dCBvay4N CgkJfQ0KDQoNCgkJcHVibGljIGJvb2wgaXNWYWxpZGF0ZWQgeyBnZXQgPT4gdmFsaWRhdGVkOyB9 ICAvLyB0b2RvIGp1c3QgPT4gdmFsaWRhdGVkOw0KDQoNCgkJcHVibGljIHZpcnR1YWwgYm9vbCBp c1RvcExldmVsSXRlbVNlcSA9PiBmYWxzZTsNCg0KDQoJCXB1YmxpYyB2aXJ0dWFsIHZvaWQgbWhw X21oaygpIHsgIC8vIGRvbid0IHRoaW5rIHRoaXMgbmVlZCBiZSB2aXJ0dWFsIC0gdG9kbz8NCgkJ CQkJCQkJCQkgLy8gPSBtdXN0IGhhdmUgcGFyZW50LCBtdXN0IGhhdmUga2lkcy4gVGhlIGtpZHMg bWF5IGJlIHRoZQ0KCQkJCQkJCQkJCSAvLyBlbXB0eSBzZXQgYW5kIHRoZSBwYXJlbnQgbWF5IGJl IG5vUGFyZW50IGJ1dCB0aGV5IG11c3QNCgkJCQkJCQkJCQkgLy8gZXhpc3QuDQoJCQkJCQkJCQkJ IC8vIFdoeSBub3QganVzdCBpbmxpbmUgdGhpcyBpbnRvIHZhbGlkYXRlKCk/DQoJCQkJCQkJCQkJ IC8vIEJlY2F1c2UgYSBmZXcgY2xhc3NlcyBuZWVkIGJlc3Bva2UgdmFsaWRhdGlvbiwgYnV0IHN0 aWxsIG11c3QgY2hlY2sgdGhpcy4NCgkJCWhhcmRNdXN0UGFyZW50SXNQcmVzZW50KCk7DQoJCQlr aWRzLmVhY2hLaWRQYXJlbnRNdXN0QmUodGhpcyk7DQoJCX0NCg0KDQoJCXB1YmxpYyBzdHJpbmcg YXNOYW1lT3JJZGVudENvbnRlbnRzKCkgew0KCQkJLy8gZm9yIHZlcnkgY3J1ZGUgZGVidWdnaW5n IA0KCQkJdmFyIG9wdE5hbWUgPSB0aGlzIGlzIElpc05hbWVkSXRlbSBuaSA/IG5pLm5hbWUudG9S YXdTdHIoKSA6ICIiOw0KCQkJb3B0TmFtZSA9IChvcHROYW1lID09ICIiICYmIHRoaXMgaXMgUE1R SWRlbnQpID8gdGhpcy50b1Jhd1N0cigpIDogIiI7DQoNCgkJCXZhciBvcHROYW1lMiA9IG9wdE5h bWUgKyAiICAodWlkOiIgKyB1aWQuVG9TdHJpbmcoKSArICIpICINCgkJCQkrIGdldEZpcnN0RmV3 Q2hhcnNPZih0b1Jhd1N0cigpKTsNCgkJCXJldHVybiBvcHROYW1lMjsNCgkJfQ0KDQoNCgkJcHVi bGljIHZpcnR1YWwgdm9pZCBnZXRBbGxVSURzKFVJRHNldCB1aWRzKSB7DQoJCQl1aWRzLkFkZCh0 aGlzKTsNCgkJCWtpZHMuRm9yRWFjaChuYW1lZEtpZCA9PiBuYW1lZEtpZC5raWQuZ2V0QWxsVUlE cyh1aWRzKSk7DQoJCX0NCg0KDQoJCXB1YmxpYyBib29sIGlzU3R1YlBhcmVudCB7IGdldCA9PiAo dGhpcyBpcyBOb1BhcmVudCkgfHwgKHRoaXMgaXMgRmFrZVBhcmVudCk7IH0NCg0KDQoJCXB1Ymxp YyB2b2lkIHZhbGlkYXRlU3BlY2lmaWNJdGVtcyhwYXJhbXMgTERCQVNUb2JqW10gaXRlbXMpIHsN CgkJCUFycmF5LkZvckVhY2goaXRlbXMsIGl0ZW0gPT4gaXRlbS52YWxpZGF0ZSgpKTsNCgkJfQ0K DQoNCgkJcHVibGljIFQ/IG9wdENsaW1iVG88VD4oKSB3aGVyZSBUIDogTERCQVNUb2JqIHsNCgkJ CXZhciByZXNJdGVtID0gdGhpczsNCgkJCXdoaWxlICghKHJlc0l0ZW0gaXMgVCkpIHsNCgkJCQlp ZiAocmVzSXRlbS5wYXJlbnQuaXNTdHViUGFyZW50KSB7DQoJCQkJCXJldHVybiBudWxsOw0KCQkJ CX0NCgkJCQlyZXNJdGVtID0gcmVzSXRlbS5wYXJlbnQ7DQoJCQl9DQoNCgkJCXZhciByZXMgPSBy ZXNJdGVtIGFzIFQ7DQoJCQlyZXR1cm4gcmVzOw0KCQl9DQoNCg0KCQlwdWJsaWMgVCByZXFDbGlt YlRvPFQ+KCkgd2hlcmUgVCA6IExEQkFTVG9iaiB7DQoJCQl2YXIgbG9jID0gY2xhc3NOYW1lICsg Ii5yZXFDbGltYlRvPFQ+KCkiOw0KCQkJdmFyIHJlcyA9IG9wdENsaW1iVG88VD4oKTsNCgkJCWhh cmRNdXN0MighKHJlcyBpcyBudWxsKSwgDQoJCQkJLy8gVGhhbmtzIFNPIDxodHRwczovL3N0YWNr b3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy8yNTgxNjQyL2hvdy1kby1pLWdldC10aGUtdHlwZS1uYW1l LW9mLWEtZ2VuZXJpYy10eXBlLWFyZ3VtZW50Pg0KCQkJCS8vIFRvZG8gLSB1c2UgdGhpcyBlbHNl d2hlcmUsIHBvc3MgRXhwZWN0RXhjZXB0aW9uPyB0b2RvDQoJCQkJKCkgPT4NCgkJCQlsb2MgDQoJ CQkJKyBubCArICIsIGNsaW1iZWQgdG8gdG9wLCBkaWRuJ3QgZmluZCB0eXBlICINCgkJCQkrIHR5 cGVvZihUKS5GdWxsTmFtZQ0KCQkJCSsgbmwgKyAiSGllcmFyY2h5IGlzOiAiDQoJCQkJKyBubCAr IGdldEl0ZW1XaXRoUGFyZW50cyh0aGlzKSk7DQoJCQlpZiAocmVzIGlzIG51bGwpIHsgdGhyb3cg bmV3IE5OUUMoKTsgfQ0KCQkJcmV0dXJuIHJlczsNCgkJfQ0KDQoNCgkJcHVibGljIHZvaWQgaGFy ZE11c3RQYXJlbnRJc1ByZXNlbnQoKSB7DQoNCgkJCWhhcmRNdXN0MighKHBhcmVudCBpcyBudWxs KSwgDQoJCQkJKCkgPT4NCgkJCQkgIk5VTEwgcGFyZW50IGZvciBpdGVtIG9mIHR5cGVcbiINCgkJ CQkgKyAkIntHZXRUeXBlKCl9XG4uIik7DQoNCgkJCWhhcmRNdXN0MighKHRoaXMucGFyZW50IGlz IE5vUGFyZW50KSwNCgkJCQkoKSA9Pg0KCQkJCSJQYXJlbnQgaXMgTm9QYXJlbnQgb24gb2JqZWN0 IG9mIHR5cGVcbiINCgkJCQkrICQiJ3t0aGlzLmNsYXNzTmFtZX0nIik7DQoJCX0NCg0KDQoJCXB1 YmxpYyB2b2lkIGhhcmRNdXN0UGFyZW50SXNBYnNlbnQoKSB7DQoJCQkvLyBGb3IgY2hlY2tpbmcg Y2xvbmluZyAtIHBhcmVudCBzaG91bGQgYmUgTm9QYXJlbnQgaW1tZWRpYXRlbHkgDQoJCQkvLyBh ZnRlciwgYmVmb3JlIGl0J3Mgc2V0IGJ5IHBhcmVudCwgYW5kIG5ldmVyIG51bGwNCgkJCWhhcmRN dXN0KCEocGFyZW50IGlzIG51bGwpLA0KCQkJCSAiTlVMTCBwYXJlbnQgZm9yIGl0ZW0gb2YgdHlw ZVxuIg0KCQkJCSArICQie0dldFR5cGUoKX1cbi4iKTsNCgkJCWhhcmRNdXN0KCh0aGlzLnBhcmVu dCBpcyBOb1BhcmVudCksDQoJCQkJIlBhcmVudCBzaG91bGQgYmUgTm9QYXJlbnQgb24gb2JqZWN0 IG9mIHR5cGVcbiINCgkJCQkrICQiJ3t0aGlzLmNsYXNzTmFtZX0nIik7DQoJCX0NCg0KDQoJCXB1 YmxpYyBib29sIGhhc1BhcmVudDxQPigpIHsNCgkJCWhhcmRNdXN0KCEodGhpcyBpcyBOb1BhcmVu dCksICJJdGVtIGlzIE5vUGFyZW50Iik7DQoJCQlyZXR1cm4gdGhpcy5wYXJlbnQgaXMgUDsNCgkJ fQ0KDQoNCgkJcHVibGljIGJvb2wgaGFzQW5jZXN0b3I8QT4oKSB7DQoJCQloYXJkTXVzdCghdGhp cy5pc1N0dWJQYXJlbnQsICJJdGVtIGlzIE5vUGFyZW50Iik7DQoNCgkJCS8vIGhvdyB0byBkbyB3 aXRoIGEgc3dpdGNoIGV4cHI/DQoJCQlpZiAodGhpcy5wYXJlbnQuaXNTdHViUGFyZW50IC8qIGlz IE5vUGFyZW50IHx8IHRoaXMucGFyZW50IGlzIEZha2VQYXJlbnQqLyApIHsgLy8gdG9kbyBkbyBh cyB4Lmhhc0Z1ZGdlZFBhcmVudCgpIC0gdG9kbw0KCQkJCXJldHVybiBmYWxzZTsNCgkJCX0gZWxz ZSBpZiAodGhpcy5wYXJlbnQgaXMgQSkgew0KCQkJCXJldHVybiB0cnVlOw0KCQkJfSBlbHNlIHsN CgkJCQlyZXR1cm4gdGhpcy5wYXJlbnQuaGFzQW5jZXN0b3I8QT4oKTsNCgkJCX0NCgkJfQ0KDQoJ CXB1YmxpYyBib29sIG5vdEhhc0FuY2VzdG9yPEE+KCkgPT4NCgkJCSFoYXNBbmNlc3RvcjxBPigp Ow0KDQoNCgkJcHVibGljIHZvaWQgc2V0TXlQYXJlbnRUbyhMREJBU1RvYmogcHJudCkgew0KCQkJ Ly8gQW4gb2JqZWN0IG1heSBvbmx5IHNldCBpdHMgcGFyZW50IGlmIGl0cyBjdXJyZW50IHBhcmVu dCBpcw0KCQkJLy8gdGhlIGR1bW15ICdub1BhcmVudCcsIHdoaWNoIGFsbW9zdCBldmVyeSBvYmpl Y3QncyBwYXJlbnQgaXMNCgkJCS8vIHNldCB0byBvbiBjcmVhdGlvbiAoc2VlIExEQkFTVG9iaiBw YXJlbnQgcHJvcGVydHkgZGVmKS4NCg0KCQkJLy8gVGhlIHRlc3QgZm9yIG51bGwgaXMgcGVjdWxp YXIgZ2l2ZW4gdGhpcy4gQmVjYXVzZQ0KCQkJLy8gbm9QYXJlbnQgaXMgY3JlYXRlZCBzdGF0aWNh bGx5LCBzZXR0aW5nIHRoZSBwYXJlbnQgb2YNCgkJCS8vIG5vUGFyZW50IGlzIGRpZmZpY3VsdCwg cGVyaGFwcyBpbXBvc3NpYmxlLCB0byBkbyBzdGF0aWNhbGx5DQoJCQkvLyBhbmQgcmVsaWFibHku RGVzcGl0ZSB0aGUgZGVjbGFyYXRpb24gJyNudWxsYWJsZSBlbmFibGUnLCBpdA0KCQkJLy8gZ2V0 cyBjcmVhdGVkIHdpdGggYSBudWxsIHBhcnJlbnQgKHF1aXRlIHJlYXNvbmFibHkpLCBoZW5jZQ0K CQkJLy8gdGhpcyBjaGVjay5UaGUgYWN0dWFsIHNldHRpbmcgb2YgdGhlIHBhcmVudCBoYXMgdG8g YmUgZG9uZQ0KCQkJLy8gYXQgcnVudGltZSBpLmUuYWZ0ZXIgdGhlIHN0YXRpYyBjcmVhdGlvbiBv ZiAnbm9QYXJlbnQnLg0KDQoJCQloYXJkTXVzdDIoKHRoaXMucGFyZW50IGlzIE5vUGFyZW50KSB8 fCAodGhpcy5wYXJlbnQgaXMgbnVsbCksDQoJCQkJKCkgPT4NCgkJCQkidHJpZWQgdG8gcmUtc2V0 IHBhcmVudCBvbiBvYmplY3Qgb2YgdHlwZTogIg0KCQkJCSsgbmwgKyB0aGlzLmNsYXNzTmFtZVEN CgkJCQkrIG5sICsgIk9yaWdpbmFsIHBhcmVudCB0eXBlIGlzOiAiDQoJCQkJKyAodGhpcz8ucGFy ZW50Py5jbGFzc05hbWVRID09IG51bGwgPyAibnVsbCIgOiB0aGlzLnBhcmVudC5jbGFzc05hbWVR KQ0KCQkJCSsgbmwgKyAiYW5kIG5ldyBwYXJlbnQgdHlwZSBpczogIg0KCQkJCSsgcHJudC5jbGFz c05hbWVRDQoJCQkJKyBubCArICJJdGVtIGhhdmluZyBwYXJlbnQgc2V0IG9uIGl0IGlzOiAiDQoJ CQkJLy8gYmVjYXVzZSBvYmplY3QgbWF5IG5vdCBiZSBmdWxseSBjb25zdHJ1Y3RlZCB5ZXQsIGNo ZWNrIGhvd3ZlciBUT0RPIHRoaXMgaXMgYSBtYWpvciBoYWNrIGFuZCBtdXN0IGJlIGZpeGVkIHNv bWV0aW1lLg0KLy8JCQkJKyBubCArICh0aGlzIGlzIG51bGwgPyAiKG51bGwpIiA6IHRoaXMudG9S YXdTdHIoKSkpOw0KCQkJCSsgbmwgKyB0aGlzLnRvUmF3U3RyKCkgKTsNCg0KCQkJcGFyZW50ID0g cHJudDsNCgkJfQ0KDQoNCgkJcHVibGljIHZvaWQgZm9yY2VOZXdQYXJlbnRGb3JSb290T2JqZWN0 KCkgew0KCQkJLy8gRXZlcnkgb2JqZWN0IG11c3QgaGF2ZSBzb21lIHBhcmVudCwgaW5jbHVkaW5n IHRoZQ0KCQkJLy8gcm9vdCBvYmplY3Qgb2YgdGhlIHBhcnNlLCB3aGljaCBpcyBMREJpdGVtcw0K CQkJLy8gKGEgc2VxdWVuY2Ugb2YgTERCIGl0ZW1zKSwgc28gdGhpcyBmb3JjZXMgb25lLg0KCQkJ Ly8gSXQgaXMgb25seSBmb3IgdGhhdCBwdXJwb3NlIQ0KCQkJLy8gDQoJCQkvLyBMREJpdGVtcyBv YmogZXhpc3RzIGZvciBzdWIgb2JqcyBzdWNoIGFzIHRoZSBzdGF0ZW1lbnRzDQoJCQkvLyBpbiBh IHdoaWxlIGxvb3AsIGluIGEgcHJvYywgaW4gYW4gaWYuLi4gZXRjLiwgZm9yDQoJCQkvLyB3aGlj aCB0aGVpciBwYXJlbnQgaXMgdGhlIHdoaWxlL3Byb2MvaWYgZXRjLg0KCQkJaGFyZE11c3RQYXJl bnRJc0Fic2VudCgpOw0KCQkJdGhpcy5wYXJlbnQgPSBmYWtlUGFyZW50Ow0KCQl9DQoNCg0KCQkv L3B1YmxpYyB2b2lkIHJlc2V0TXlQYXJlbnRUbyhMREJBU1RvYmogcHJudCkgeyAgLy8vLy8vLy8v Ly8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLyBkZXN0cm95ISEhISEhIHRvZG8NCgkJLy8JcGFyZW50 ID0gcHJudDsNCgkJLy99DQoNCgkJLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vIHh4eHh4eHh4eHh4 eHggZGVsZXRlIC0gdG9kbw0KCQkvL3ByaXZhdGUgdm9pZCBzZXRQYXJlbnRPbktpZChMREJBU1Rv Ymoga2lkKSA9PiAvLyB0b2RvIG5lZWRlZD8NCgkJLy8JCQkJCQkJCQkJCSAgLy8gY2hlY2sgcGFy ZW50ZSBkb2Vzbid0IGV4aXN0IC0gdG9kbw0KCQkvLwlraWQucGFyZW50ID0gdGhpczsNCg0KCQlw dWJsaWMgdmlydHVhbCB2b2lkIHNldFBhcmVudE9uS2lkc0FuZE1ha2VLaWRzRGljdCggIC8vIHRv ZG8gLSBhbmQgYWRkIHRvIGtpZHMgZGljdA0KCQkJCQkJCQkJCQkJCQkJIC8vIHRoaXMgbWl4ZXMg dXAgc2V0dGluZyBwYXJlbnQgYW5kIG1ha2luZyBjaGlsZCBkaWN0LiBOb3QgZ29vZC4gLSB0b2Rv DQoJCQkJCQlwYXJhbXMgKHN0cmluZyBraWROYW1lLCBMREJBU1RvYmoga2lkKVtdIGtpZHNJbikg ew0KCQkJdmFyIGxvYyA9IGNsYXNzTmFtZVBsdXMoInNldFBhcmVudE9uS2lkc0FuZE1ha2VLaWRz RGljdCIpOw0KDQoJCQl2YXIga2lkc1RvQWRkID0gbmV3IExEQlN0cnVjdHNDaGlsZHJlbih0aGlz LCBraWRzSW4pOw0KCQkJaGFyZE11c3QyKGtpZHMuaXNFbXB0eSwNCgkJCQkoKSA9Pg0KCQkJCSQi c2V0dGluZyBraWRzIG9uIHBhcmVudCAne2NsYXNzTmFtZX0nIiANCgkJCQkrICJ3aGVuIGtpZHMg aXMgbm90IGVtcHR5LCAiDQoJCQkJKyAkImtpZHMgaXMgKHtraWRzLkNvdW50fSBraWRzKToiDQoJ CQkJKyBubCArIGtpZHMudG9EZWJ1Z1N0cigpDQoJCQkJKyBubCArICQiVHJ5aW5nIHRvIGFkZFxu e2tpZHNUb0FkZC50b0RlYnVnU3RyKCl9XG4iDQoJCQkJKyAkImluIHtjbGFzc05hbWV9Iik7DQoJ CQkvLyBpZiB0aGVyZSBpcyBhbiBMREJTdHJ1Y3RzQ2hpbGRyZW4gYW5kIGFub3RoZXIgY2hpbGQs DQoJCQkvLyB0aGlzIHdpbGwgYmxvdyB1cCAtIHdpbGwgbmVlZCB0byBkbyBraWRzLkFkZCBvcg0K CQkJLy8gc29tZXRoaW5nIC0gaW4gZmFjdCwga2lkcyBuZWVkcyB0byBiZSBjcmVhdGVkIGluIG9u ZQ0KCQkJLy8gZ28sIHdoaWNoIGlzIHdoYXQgaGFwcGVucy4NCgkJCWtpZHMgPSBraWRzVG9BZGQ7 ICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8v Ly8vLyB3aHkgdGhpcz8gdG9kbw0KCQkJQXJyYXkuRm9yRWFjaChraWRzSW4sIHhraWQgPT4gaGFy ZE11c3QoISh4a2lkLmtpZCBpcyBudWxsKSwgbG9jLCAibnVsbCBraWQiKSk7DQoJCQlBcnJheS5G b3JFYWNoKGtpZHNJbiwgeGtpZCA9PiB4a2lkLmtpZC5zZXRNeVBhcmVudFRvKHRoaXMpKTsNCgkJ fQ0KDQoNCgkJcHVibGljIHZpcnR1YWwgdm9pZCBzZXRQYXJlbnRPbktpZHNBbmRBZGRUb0tpZHNE aWN0KA0KCQkJCQlwYXJhbXMgKHN0cmluZyBraWROYW1lLCBMREJBU1RvYmoga2lkKVtdIGtpZHNJ bikgew0KCQkJdmFyIGtpZHNUb0FkZF9qdXN0Rm9yRXJyUmVwb3J0aW5nID0gbmV3IExEQlN0cnVj dHNDaGlsZHJlbih0aGlzLCBraWRzSW4pOw0KCQkJaGFyZE11c3QyKCFraWRzLmlzRW1wdHksIC8v IG1heSBkaXNhYmxlIHRoaXMgbGF0ZXIgDQoJCQkJKCkgPT4NCgkJCQkiYWRkaW5nIHRvIGtpZHMg d2hlbiBraWRzIGlzIGVtcHR5LCAiDQoJCQkJICsgJCJraWRzIGlzXG57a2lkcy50b0RlYnVnU3Ry KCl9XG4iDQoJCQkJICsgJCJUcnlpbmcgdG8gYWRkXG57a2lkc1RvQWRkX2p1c3RGb3JFcnJSZXBv cnRpbmcudG9EZWJ1Z1N0cigpfVxuIg0KCQkJCSArICQiaW4ge2NsYXNzTmFtZX0iKTsNCgkJCUFy cmF5LkZvckVhY2goa2lkc0luLCB4a2lkID0+IHsNCi8vCQkJCXNldFBhcmVudE9uS2lkKHhraWQu a2lkKTsNCgkJCQl4a2lkLmtpZC5zZXRNeVBhcmVudFRvKHRoaXMpOw0KCQkJCWtpZHMuQWRkKHhr aWQpOw0KCQkJfSk7DQoJCX0NCg0KDQoJCXB1YmxpYyB2aXJ0dWFsIElkZW50c1VzZWQgZ2V0QWxs SURzKCkgew0KCQkvKiBUaGlzIGlzIG92ZXJyaWRkZW4gb25seSBpbiBUZW1wbGF0ZWRBZ2csIGFu ZCB0aGF0J3Mgb25seSB0byANCgkJCWRlbGliZXJhdGVseSBmYWlsLiBUaGVyZSdzIHNvbWV0aGlu ZyB3cm9uZyB0aGVyZSwgdG9kbyAtIA0KCQkJdW4tdmlydHVhbGlzZSB0aGlzIGFuZCByZW1vdmUg dGhlIG9uZSBvdmVycmlkZS4gLSB0b2RvDQoJCSovDQoJCQl2YXIgaXUgPSBuZXcgSWRlbnRzVXNl ZCgpOw0KCQkJdGhpcy5fZ2V0QWxsSURzKGl1KTsNCgkJCXJldHVybiBpdTsNCgkJfQ0KDQoJCXB1 YmxpYyB2aXJ0dWFsIHZvaWQgX2dldEFsbElEcyhJZGVudHNVc2VkIGl1KSB7DQoJCS8vIEdldHMg YWxsIHRoZSBpZGVudGlmaWVycyBleHBsaWNpdGx5IHVzZWQgKHJlYWQgb3Igd3JpdHRlbikgIC0t LS0tIHRvZG8gdXBkYXRlIHRoaXMNCgkJLy8gYW55d2hlcmUgaW4gdGhlIEFTVC4gIERvZXMgbm90 IGdldCBpZGVudHMgd2hpY2ggYXJlDQoJCS8vIGRlY2xhcmF0aW9ucyBpZS4gcGFyYW1ldGVycywg b3IgdmFyL2NvbnN0IGRlY2xhcmF0aW9ucw0KCQkvLyB1bmxlc3MgdGhlc2UgYXJlIGNvbWJpbmVk IHdpdGggYW4gYXNzaWdubWVudC4NCgkJLy8NCgkJLy8gSW1wbGllZCBpZGVudHMgc3VjaCBhcyB0 aG9zZSBmcm9tIHRibC4qIGFyZSBpbXBsaWNpdCBhbmQgaWdub3JlZC4NCgkJLy8NCgkJLy8gUm9v dCBjYWxsZXIgc3VwcGxpZXMgbmV3LCBlbXB0eSBpdQ0KCQkvLyBuZWVkIHVzYWdlIGhlcmUgLSB0 b2RvIGRvY3MvLw0KCQkJa2lkcy5fZ2V0QWxsSURzKGl1KTsNCgkJfQ0KDQoJCXB1YmxpYyBhYnN0 cmFjdCBib29sIGNhbkdldEFsbElkZW50c1VzZWQgew0KCQkvLyAJVGhpcyBzZWVtcyB0byBiZSB0 cnVlIG9uIG1vc3QgY2xhc3NlcyBzbyBJIGNvdWxkIHNldCB0cnVlIA0KCQkvLyBhcyBhIGRlZmF1 bHQgaGVyZSBhbmQgb3ZlcnJpZGUgaXQgd2hlcmUgaXQncyBub3Qgd2FudGVkLCBzYXZpbmcgDQoJ CS8vIGEgY2h1bmsgb2YgY29kZSwgYnV0IEknZCByYXRoZXIgbWFrZSBpdCBleHBsaWNpdCB0byBm b3JjZSBtZSB0byBjb25zaWRlciBlYWNoIGNhc2UuIEEgYml0IG1vcmUgQyZQIGZvciBsZXNzIGNo YW5jZSBvZiBidWdzLg0KCQkJZ2V0Ow0KCQl9DQoNCg0KCQkvLyBQcm9kdWNlcyBhIHN0cmluZyB0 aGF0IHNob3VsZCBiZSBpZGVudGljYWwgdG8gKGV4Y2VwdGluZw0KCQkvLyB3aGl0ZXNwYWNlcykg dGhlIGlucHV0IGllLiBlbWl0IExEQiBjb2RlIG5vdCB2YWxpZCBTUUwNCgkJLy8NCgkJLy8gVG9T dHJpbmcgd2FzIGNhdXNpbmcgdG9vIG1hbnkgd2VpcmQgcHJvYmxlbXMgKGR1ZSB0byBteQ0KCQkv LyBpbmV4cGVyaWVuY2Ugd2l0aCBjIykgc28ganVzdCB1c2VkIHRvUmF3U3RyKCkNCgkJcHVibGlj IGFic3RyYWN0IHN0cmluZyB0b1Jhd1N0cigpOw0KDQoJCXB1YmxpYyBvdmVycmlkZSBzdHJpbmcg dG9EZWJ1Z1N0cigpID0+IHRvUmF3U3RyKCk7DQoNCgl9IC8vIGVuZCBMREJBU1RvYmoNCg0KDQoN CglwdWJsaWMgaW50ZXJmYWNlIEloYW5kbGVQcmVmaXhlczxUPg0KCQkJCQkJd2hlcmUgVCA6IExE QlJvb3Qgew0KDQoJCXB1YmxpYyBib29sIGlzUHJlZml4ZWQgeyBnZXQ7IH0NCg0KCQlwdWJsaWMg Ym9vbCBpc0V4Y2Vzc1ByZWZpeGVkIHsgZ2V0OyB9DQoNCgkJLy8gVGhlIFQgaW4gYWRkUHJlZml4 L3JlUHJlZml4L3dpdGhvdXRQcmVmaXggaXMgYmVjYXVzZSB3ZSBtYXkgYmUgDQoJCS8vIHJldHVy bmluZyBlZy4gYSBsaXN0IG9mIGl0ZW1zIHdpdGggcHJlZml4ZXMgDQoJCS8vIHRodXMgbW9kaWZp ZWQsIG5vdCBhIHNpbmdsZSBQTVFJZGVudA0KDQoJCXB1YmxpYyBUIGFkZFByZWZpeChQTVFJZGVu dCBwZngpOw0KDQoJCXB1YmxpYyBUIHJlUHJlZml4KFBNUUlkZW50IG5ld3BmeCk7DQoNCi8vCQlw dWJsaWMgVCBzdHJpcFByZWZpeChQTVFJZGVudCBpZCk7DQoJfQ0KCS8vIHRvZG8gLSBtb3ZlIHRo aXMNCg0KDQoNCg0KDQoJcHVibGljIGFic3RyYWN0IGNsYXNzIExEQlJvb3Qgew0KCQkvLyBSb290 IG9mIGV2ZXJ5dGhpbmcgTERCLWlzaA0KDQoJCXB1YmxpYyBib29sIEVxdWFscyhbQWxsb3dOdWxs XSBMREJSb290IG90aGVyKSB7DQoJCQl0aHJvdyBuZXcgTERCU2hvdWxkTm90QmVJbXBsZW1lbnRl ZEV4Y2VwdGlvbigNCgkJCQkJCQkJCSJjYWxsZWQgRXF1YWxzIG9uIExEQlJvb3QiKTsNCgkJfQ0K DQoJCXB1YmxpYyBvdmVycmlkZQ0KCQkJYm9vbCBFcXVhbHMoW0FsbG93TnVsbF0gT2JqZWN0IG90 aGVyKSB7DQoJCQl0aHJvdyBuZXcgTERCU2hvdWxkTm90QmVJbXBsZW1lbnRlZEV4Y2VwdGlvbigN CgkJCQkJCQkJCSJjYWxsZWQgRXF1YWxzIGluIE9iamVjdCIpOw0KCQl9DQoNCgkJcHVibGljIG92 ZXJyaWRlIGludCBHZXRIYXNoQ29kZSgpIHsNCgkJCXRocm93IG5ldyBMREJTaG91bGROb3RCZUlt cGxlbWVudGVkRXhjZXB0aW9uKA0KCQkJCQkJCQkJImNhbGxlZCBHZXRIYXNoQ29kZSBpbiBMREJS b290Iik7DQoJCX0NCg0KCQlwdWJsaWMgc3RhdGljIGJvb2wgb3BlcmF0b3IgPT0oTERCUm9vdCBs aHMsDQoJCQkJCQkJCQkgICBMREJSb290IHJocykgew0KCQkJdGhyb3cgbmV3IExEQlNob3VsZE5v dEJlSW1wbGVtZW50ZWRFeGNlcHRpb24oDQoJCQkJCQkJCQkiY2FsbGVkID09IGluIExEQlJvb3Qi KTsNCgkJfQ0KDQoJCXB1YmxpYyBzdGF0aWMgYm9vbCBvcGVyYXRvciAhPShMREJSb290IGxocywN CgkJCQkJCQkJCSAgIExEQlJvb3QgcmhzKSB7DQoJCQl0aHJvdyBuZXcgTERCU2hvdWxkTm90QmVJ bXBsZW1lbnRlZEV4Y2VwdGlvbigNCgkJCQkJCQkJCSJjYWxsZWQgIT0gaW4gTERCUm9vdCIpOw0K CQl9DQoNCg0KCQlwdWJsaWMgdmlydHVhbCBzdHJpbmcgY2xhc3NOYW1lIHsNCgkJCS8vIHRvZG8g LSB0aGlzIG5lZWRzIGNoZWNraW5nIGl0IHdvcmtzIGFzIEkgd2FudA0KCQkJLy8gYWxzbyByZW5h bWUgdG8gbGRiY2xhc3NuYW1lIC0tIHRvZG8NCgkJCWdldCA9PiB0aGlzLkdldFR5cGUoKS5GdWxs TmFtZSA/PyAiKHVua25vd24pIjsNCgkJfQ0KDQoNCgkJcHVibGljIHZpcnR1YWwgc3RyaW5nIGNs YXNzTmFtZVEgPT4NCgkJCSInIiArIGNsYXNzTmFtZSArICInIjsNCg0KDQoJCXB1YmxpYyB2aXJ0 dWFsIHN0cmluZyBjbGFzc05hbWVQbHVzKHN0cmluZyBwbHVzKSA9Pg0KCQkJY2xhc3NOYW1lICsg Ii4iICsgcGx1czsNCg0KCQlwdWJsaWMgb3ZlcnJpZGUgc3RyaW5nIFRvU3RyaW5nKCkgew0KCQkJ Ly8gVGhpcyBpbXBsaWNpdCB0by1zdHJpbmcgY29udmVyc2lvbiBjcmFwIGNvc3QgbWUgYSBmZXcg aG91cnMsIHNvIGF0IGxlYXN0DQoJCQkvLyBkbyB0aGlzICYgYmxvdyB1cCBhdCBydW50aW1lLiBX b3VsZCBwcmVmZXIgY29tcGlsZSB0aW1lIGJ1dCBpdCBzZWVtcw0KCQkJLy8gbm90IHBvc3NpYmxl LiAgVGhpcyB0dXJucyBvdXQgdG8gaGF2ZSBiZWVuIGEgZ29vZCBpZGVhLA0KCQkJLy8gc2F2ZWQg bWUgcXVpdGUgYSBiaXQgbW9yZSBkZWJ1Z2dpbmchDQoJCQkvLyA8aHR0cHM6Ly9zdGFja292ZXJm bG93LmNvbS9xdWVzdGlvbnMvMTUzNDU1MTcvaXMtaXQtcG9zc2libGUtdG8tZGlzYWJsZS1pbXBs aWNpdC10b3N0cmluZy1jYWxsPg0KCQkJLy8gV2lsbCB0cnkgPGh0dHBzOi8vc3RhY2tvdmVyZmxv dy5jb20vcXVlc3Rpb25zLzU0MzU0MzQyL2hvdy10by1nZXQtYW4tZXJyb3Itc2hvd24td2hlbi11 c2luZy1ub24tc3RyaW5ncy1hcy1zdHJpbmdzLWluc3RlYWQtb2YtYW4tYXV0b20vNTQzNTUxMTUj NTQzNTUxMTUpDQoJCQl2YXIgbXNnID0gIkxEQlJvb3QuVG9TdHJpbmcoKSI7DQoJCQl0aHJvdyBu ZXcgTERCVG9TdHJpbmdJbXBsaWN0Q29udmVyc2lvbkV4Y2VwdGlvbihtc2cpOw0KCQl9DQoNCgkJ cHVibGljIGFic3RyYWN0IHN0cmluZyB0b0RlYnVnU3RyKCk7DQoJfQ0KDQoNCg0KCXB1YmxpYyBh YnN0cmFjdCBjbGFzcyBFcGhlbWVyYWwgOiBMREJSb290IHsNCgkJLy8gZm9yIG9iamVjdHMgdGhh dCBhcmUgbm90IHBhcnQgb2YgdGhlIEFTVA0KCX0NCg0KDQoNCglwdWJsaWMgaW50ZXJmYWNlIElX aXRoTGluZU5VbSB7ICAvLyB0b2RvIC0gdXNlIG9yIHJlbW92ZSAtIHRvZG8NCgkJLy8JcHVibGlj IA0KCX0NCg0KDQoJcHVibGljIGludGVyZmFjZSBJSGFzVGFibGVBbGlhcyB7DQoJCS8vIEhhcyBh IHRhYmxlIGFsaWFzIEFTVCBvYmouIE1heSBiZSBhIC4uLk1pc3Npbmcgc3VidHlwZSBpbiB3aGlj aA0KCQkvLyBpdCBoYXMgbm8gYWxpYXMgZ2l2ZW4gYnkgdGhlIHVzZXIsIGJ1dCBhbGlhcyBBU1Qg aXMgdGhlcmUuIE1vcmUNCgkJLy8gYWNjdXJhdGVseSBhIFRhYmxlU291cmNlIGFsaWFzIGJ1dCBv aw0KCQlwdWJsaWMgYWJzdHJhY3QgVGFibGVBbGlhcyB0YSB7IGdldDsgc2V0OyB9DQoJfQ0KDQoN CgkvLyBCYXNlIGNsYXNzIGZvciBhbGwgTERCIEFTVCBvYmplY3RzDQoJcHVibGljIGFic3RyYWN0 IGNsYXNzIExEQkFTVG9iaiA6IExEQlJvb3Qgew0KCQkvLyBUaGlzIG9uZSBpcyBhIHByb2JsZW0u IElmIEkgZGVjbGFyZSB0aGUgJ3BhcmVudCcgcHJvcGVydHkNCgkJLy8gYWJzdHJhY3QgSSB0aGVu IGhhdmUgdG8gaW1wbGVtZW50IGl0IGxpdGVyYWxseSBodW5kcmVkcyBvZg0KCQkvLyB0aW1lcyBp biB0aGUgZGVyaXZlZCBjbGFzc2VzLCBhbmQgSSByZWFsbHkgZG9uJ3QgdGhpbmsgaXQNCgkJLy8g d291bGQgaGVscCBzbyBqdXN0IHNldCBpdCB0byBhIGRlZmF1bHQgd2hpY2ggZ2V0cyBvdmVyd3Jp dHRlbiBsYXRlci4NCgkJLy8gDQoJCS8vIFRoZSBwcm9ibGVtIGlzIHRoYXQgdGhvc2Ugb2JqZWN0 cyB3ZXJlIGNyZWF0ZWQgYnkgdGhlDQoJCS8vIHBhcnNlciwgd2hpY2ggY3JlYXRlcyB0aGVtIGJv dHRvbS11cCwgd2hpY2ggbWVhbnMgeW91IGNhbid0DQoJCS8vIGtub3cgdGhlIHBhcmVudCB3aGVu IHRoZXkgYXJlIGNyZWF0ZWQuIEl0IHNob3VsZCBiZQ0KCQkvLyBwb3NzaWJsZSB0byB3b3JrIGFy b3VuZCB0aGlzIGJ1dCBpdCBkb2VzIG1lYW4gcmV3b3JraW5nIHRoZQ0KCQkvLyBwYXJzZXIgZnVu ZGFtZW50YWxseSwgYW5kIEknbSBub3QgZ29pbmcgdG8gZG8gdGhhdA0KCQkvLyBhc3N1bWVpbmcg aXQncyBldmVuIHBvc3NpYmxlLg0KDQoJCS8vIHRvZG8gLSByZWFkIHVwIG9uIHByaXYvcHViL3By b2cgYWNjZXNzb3JzIEkgcmVhbGx5IGRvbid0DQoJCS8vIGdldCB0aGVzZSBhdCBhbGwNCgkJcHVi bGljIExEQkFTVG9iaiBwYXJlbnQgeyBnZXQ7IHByaXZhdGUgc2V0OyB9DQoJCQkJCQk9IG5vUGFy ZW50Ow0KCQkvLyBVbmlxdWUgSUQgcGVyIG9iamVjdCwgdXNlZnVsIGZvciBkaXN0aW5ndWlzaGlu ZyB0aGVtDQoJCS8vIHdpdGhvdXQgZ2VuZXJhbCBlcXVhbGl0eS4NCgkJcmVhZG9ubHkgcHVibGlj IHVsb25nIHVpZCA9IG5ld1VJRCgpOw0KDQoJCS8vIHB1YmxpYyBhYnN0cmFjdCBpbnQgbGluZU51 bSB7IGdldDsgc2V0OyB9DQoNCgkJLy8gSXMgdmFsaWRhdGVkIGlzIGEgY2hlYXBpc2ggY2hlY2sg dG8gZW5zdXJlIGV2ZXJ5dGhpbmcgZ2V0cw0KCQkvLyB2YWxpZGF0ZWQNCgkJLy8gY2FuIGRvIHRo aXMgYXMgYXV0byBwcm9wPyB0b2RvDQoJCXByaXZhdGUgYm9vbCBfdmFsaWRhdGVkID0gZmFsc2U7 DQoNCgkJcHJvdGVjdGVkIGJvb2wgdmFsaWRhdGVkIHsNCgkJCWdldCA9PiBfdmFsaWRhdGVkOw0K CQkJc2V0IHsNCgkJCQkvLyBoYXJkTXVzdCghdmFsaWRhdGVkLCAiLi4uIGFscmVhZHkgdmFsaWRh dGVkLi4uICIpOyAtIG5vDQoJCQkJLy8gSXQncyBoYXJkIHRvIGF2b2lkIHZhbGlkYXRpbmcgYSB0 aGluZyB0d2ljZSwgc28gZm9yIG5vdyBhbGxvdyBpdA0KCQkJCS8vIExvb2sgaW50byBpdCBsYXRl ciwgcmVhbGx5IHNob3VsZG4ndCBoYXBwZW4NCgkJCQlfdmFsaWRhdGVkID0gdHJ1ZTsNCgkJCX0N CgkJfQ0KDQoJCXB1YmxpYyBMREJTdHJ1Y3RzQ2hpbGRyZW4ga2lkcyB7IGdldDsgcHJpdmF0ZSBz ZXQ7IH0gPQ0KCQkJCQluZXcgTERCU3RydWN0c0NoaWxkcmVuKG5vUGFyZW50KTsgLy8ganVzdCBl YXNpZXINCg0KCQlwdWJsaWMgTERCQVNUb2JqKCkgeyAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8v Ly8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLyB0b2RvIGRlYWQ/DQoJCQkJ CQkJICAvLyBWU3R1ZGlvIHRoaW5rcyB0aGlzIGhhcyB6ZXJvIHJlZmVyZW5jZXMsIHdoaWNoIGlz IHRydWUgZXhwbGljaXRseSwgYnV0IGl0J3MgDQoJCQkJCQkJICAvLyBjYWxsZWQgaW1wbGljaXRs eSBvbiBldmVyeSBvYmogY3JlYXRpb24gLSBvciBzaG91bGQgZG8gdG9kby0gY2hlY2sNCgkJCWlm IChyZWNvcmRPYmplY3RzQ3JlYXRlZCkgew0KCQkJCUFsbENyZWF0ZWRJdGVtcy5BZGQodGhpcyk7 DQoJCQl9DQoJCX0NCg0KDQoJCXB1YmxpYyB2aXJ0dWFsIHZvaWQgdmFsaWRhdGUoKSB7DQoJCQlp ZiAocmVwb3J0QWxzb0lmVmFsaWRhdGlvbk9LKSB7DQoJCQkJZGVidWdtc2coInZhbGlkYXRpbmcu Li4iICsgY2xhc3NOYW1lDQoJCQkJCSsgIiAoIiArIGFzTmFtZU9ySWRlbnRDb250ZW50cygpICsg IikiKTsNCgkJCX0NCgkJCW1ocF9taGsoKTsNCgkJCWtpZHMudmFsaWRhdGUoKTsNCgkJCS8vIHZh bGlkYXRlZCA9IHRydWU7IC0tIE5vLCBnZXQgZWFjaCBzdWJjbGFzcyB0byBzZXQNCgkJCS8vIHZh bGlkYXRlZC4gVGhhdCBmb3JjZXMgYW4gZXhwbGljaXQgY2FsbCB0byBiYXNlKCkgd2hpY2gNCgkJ CS8vIGlzIG1vcmUgY29kZSBidXQgb2suDQoJCX0NCg0KDQoJCXB1YmxpYyBib29sIGlzVmFsaWRh dGVkIHsgZ2V0ID0+IHZhbGlkYXRlZDsgfSAgLy8gdG9kbyBqdXN0ID0+IHZhbGlkYXRlZDsNCg0K DQoJCXB1YmxpYyB2aXJ0dWFsIGJvb2wgaXNUb3BMZXZlbEl0ZW1TZXEgPT4gZmFsc2U7DQoNCg0K CQlwdWJsaWMgdmlydHVhbCB2b2lkIG1ocF9taGsoKSB7ICAvLyBkb24ndCB0aGluayB0aGlzIG5l ZWQgYmUgdmlydHVhbCAtIHRvZG8/DQoJCQkJCQkJCQkJIC8vID0gbXVzdCBoYXZlIHBhcmVudCwg bXVzdCBoYXZlIGtpZHMuIFRoZSBraWRzIG1heSBiZSB0aGUNCgkJCQkJCQkJCQkgLy8gZW1wdHkg c2V0IGFuZCB0aGUgcGFyZW50IG1heSBiZSBub1BhcmVudCBidXQgdGhleSBtdXN0DQoJCQkJCQkJ CQkJIC8vIGV4aXN0Lg0KCQkJCQkJCQkJCSAvLyBXaHkgbm90IGp1c3QgaW5saW5lIHRoaXMgaW50 byB2YWxpZGF0ZSgpPw0KCQkJCQkJCQkJCSAvLyBCZWNhdXNlIGEgZmV3IGNsYXNzZXMgbmVlZCBi ZXNwb2tlIHZhbGlkYXRpb24sIGJ1dCBzdGlsbCBtdXN0IGNoZWNrIHRoaXMuDQoJCQloYXJkTXVz dFBhcmVudElzUHJlc2VudCgpOw0KCQkJa2lkcy5lYWNoS2lkUGFyZW50TXVzdEJlKHRoaXMpOw0K CQl9DQoNCg0KCQlwdWJsaWMgc3RyaW5nIGFzTmFtZU9ySWRlbnRDb250ZW50cygpIHsNCgkJCS8v IGZvciB2ZXJ5IGNydWRlIGRlYnVnZ2luZyANCgkJCXZhciBvcHROYW1lID0gdGhpcyBpcyBJaXNO YW1lZEl0ZW0gbmkgPyBuaS5uYW1lLnRvUmF3U3RyKCkgOiAiIjsNCgkJCW9wdE5hbWUgPSAob3B0 TmFtZSA9PSAiIiAmJiB0aGlzIGlzIFBNUUlkZW50KSA/IHRoaXMudG9SYXdTdHIoKSA6ICIiOw0K DQoJCQl2YXIgb3B0TmFtZTIgPSBvcHROYW1lICsgIiAgKHVpZDoiICsgdWlkLlRvU3RyaW5nKCkg KyAiKSAiDQoJCQkJKyBnZXRGaXJzdEZld0NoYXJzT2YodG9SYXdTdHIoKSk7DQoJCQlyZXR1cm4g b3B0TmFtZTI7DQoJCX0NCg0KDQoJCXB1YmxpYyB2aXJ0dWFsIHZvaWQgZ2V0QWxsVUlEcyhVSURz ZXQgdWlkcykgew0KCQkJdWlkcy5BZGQodGhpcyk7DQoJCQlraWRzLkZvckVhY2gobmFtZWRLaWQg PT4gbmFtZWRLaWQua2lkLmdldEFsbFVJRHModWlkcykpOw0KCQl9DQoNCg0KCQlwdWJsaWMgYm9v bCBpc1N0dWJQYXJlbnQgeyBnZXQgPT4gKHRoaXMgaXMgTm9QYXJlbnQpIHx8ICh0aGlzIGlzIEZh a2VQYXJlbnQpOyB9DQoNCg0KCQlwdWJsaWMgdm9pZCB2YWxpZGF0ZVNwZWNpZmljSXRlbXMocGFy YW1zIExEQkFTVG9ialtdIGl0ZW1zKSB7DQoJCQlBcnJheS5Gb3JFYWNoKGl0ZW1zLCBpdGVtID0+ IGl0ZW0udmFsaWRhdGUoKSk7DQoJCX0NCg0KDQoJCXB1YmxpYyBUPyBvcHRDbGltYlRvPFQ+KCkg d2hlcmUgVCA6IExEQkFTVG9iaiB7DQoJCQl2YXIgcmVzSXRlbSA9IHRoaXM7DQoJCQl3aGlsZSAo IShyZXNJdGVtIGlzIFQpKSB7DQoJCQkJaWYgKHJlc0l0ZW0ucGFyZW50LmlzU3R1YlBhcmVudCkg ew0KCQkJCQlyZXR1cm4gbnVsbDsNCgkJCQl9DQoJCQkJcmVzSXRlbSA9IHJlc0l0ZW0ucGFyZW50 Ow0KCQkJfQ0KDQoJCQl2YXIgcmVzID0gcmVzSXRlbSBhcyBUOw0KCQkJcmV0dXJuIHJlczsNCgkJ fQ0KDQoNCgkJcHVibGljIFQgcmVxQ2xpbWJUbzxUPigpIHdoZXJlIFQgOiBMREJBU1RvYmogew0K CQkJdmFyIGxvYyA9IGNsYXNzTmFtZSArICIucmVxQ2xpbWJUbzxUPigpIjsNCgkJCXZhciByZXMg PSBvcHRDbGltYlRvPFQ+KCk7DQoJCQloYXJkTXVzdDIoIShyZXMgaXMgbnVsbCksIA0KCQkJCS8v IFRoYW5rcyBTTyA8aHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvMjU4MTY0Mi9o b3ctZG8taS1nZXQtdGhlLXR5cGUtbmFtZS1vZi1hLWdlbmVyaWMtdHlwZS1hcmd1bWVudD4NCgkJ CQkvLyBUb2RvIC0gdXNlIHRoaXMgZWxzZXdoZXJlLCBwb3NzIEV4cGVjdEV4Y2VwdGlvbj8gdG9k bw0KCQkJCSgpID0+DQoJCQkJbG9jIA0KCQkJCSsgbmwgKyAiLCBjbGltYmVkIHRvIHRvcCwgZGlk bid0IGZpbmQgdHlwZSAiDQoJCQkJKyB0eXBlb2YoVCkuRnVsbE5hbWUNCgkJCQkrIG5sICsgIkhp ZXJhcmNoeSBpczogIg0KCQkJCSsgbmwgKyBnZXRJdGVtV2l0aFBhcmVudHModGhpcykpOw0KCQkJ aWYgKHJlcyBpcyBudWxsKSB7IHRocm93IG5ldyBOTlFDKCk7IH0NCgkJCXJldHVybiByZXM7DQoJ CX0NCg0KDQoJCXB1YmxpYyB2b2lkIGhhcmRNdXN0UGFyZW50SXNQcmVzZW50KCkgew0KDQoJCQlo YXJkTXVzdDIoIShwYXJlbnQgaXMgbnVsbCksIA0KCQkJCSgpID0+DQoJCQkJICJOVUxMIHBhcmVu dCBmb3IgaXRlbSBvZiB0eXBlXG4iDQoJCQkJICsgJCJ7R2V0VHlwZSgpfVxuLiIpOw0KDQoJCQlo YXJkTXVzdDIoISh0aGlzLnBhcmVudCBpcyBOb1BhcmVudCksDQoJCQkJKCkgPT4NCgkJCQkiUGFy ZW50IGlzIE5vUGFyZW50IG9uIG9iamVjdCBvZiB0eXBlXG4iDQoJCQkJKyAkIid7dGhpcy5jbGFz c05hbWV9JyIpOw0KCQl9DQoNCg0KCQlwdWJsaWMgdm9pZCBoYXJkTXVzdFBhcmVudElzQWJzZW50 KCkgew0KCQkJLy8gRm9yIGNoZWNraW5nIGNsb25pbmcgLSBwYXJlbnQgc2hvdWxkIGJlIE5vUGFy ZW50IGltbWVkaWF0ZWx5IA0KCQkJLy8gYWZ0ZXIsIGJlZm9yZSBpdCdzIHNldCBieSBwYXJlbnQs IGFuZCBuZXZlciBudWxsDQoJCQloYXJkTXVzdCghKHBhcmVudCBpcyBudWxsKSwNCgkJCQkgIk5V TEwgcGFyZW50IGZvciBpdGVtIG9mIHR5cGVcbiINCgkJCQkgKyAkIntHZXRUeXBlKCl9XG4uIik7 DQoJCQloYXJkTXVzdCgodGhpcy5wYXJlbnQgaXMgTm9QYXJlbnQpLA0KCQkJCSJQYXJlbnQgc2hv dWxkIGJlIE5vUGFyZW50IG9uIG9iamVjdCBvZiB0eXBlXG4iDQoJCQkJKyAkIid7dGhpcy5jbGFz c05hbWV9JyIpOw0KCQl9DQoNCg0KCQlwdWJsaWMgYm9vbCBoYXNQYXJlbnQ8UD4oKSB7DQoJCQlo YXJkTXVzdCghKHRoaXMgaXMgTm9QYXJlbnQpLCAiSXRlbSBpcyBOb1BhcmVudCIpOw0KCQkJcmV0 dXJuIHRoaXMucGFyZW50IGlzIFA7DQoJCX0NCg0KDQoJCXB1YmxpYyBib29sIGhhc0FuY2VzdG9y PEE+KCkgew0KCQkJaGFyZE11c3QoIXRoaXMuaXNTdHViUGFyZW50LCAiSXRlbSBpcyBOb1BhcmVu dCIpOw0KDQoJCQkvLyBob3cgdG8gZG8gd2l0aCBhIHN3aXRjaCBleHByPw0KCQkJaWYgKHRoaXMu cGFyZW50LmlzU3R1YlBhcmVudCAvKiBpcyBOb1BhcmVudCB8fCB0aGlzLnBhcmVudCBpcyBGYWtl UGFyZW50Ki8gKSB7IC8vIHRvZG8gZG8gYXMgeC5oYXNGdWRnZWRQYXJlbnQoKSAtIHRvZG8NCgkJ CQlyZXR1cm4gZmFsc2U7DQoJCQl9IGVsc2UgaWYgKHRoaXMucGFyZW50IGlzIEEpIHsNCgkJCQly ZXR1cm4gdHJ1ZTsNCgkJCX0gZWxzZSB7DQoJCQkJcmV0dXJuIHRoaXMucGFyZW50Lmhhc0FuY2Vz dG9yPEE+KCk7DQoJCQl9DQoJCX0NCg0KCQlwdWJsaWMgYm9vbCBub3RIYXNBbmNlc3RvcjxBPigp ID0+DQoJCQkhaGFzQW5jZXN0b3I8QT4oKTsNCg0KDQoJCXB1YmxpYyB2b2lkIHNldE15UGFyZW50 VG8oTERCQVNUb2JqIHBybnQpIHsNCgkJCS8vIEFuIG9iamVjdCBtYXkgb25seSBzZXQgaXRzIHBh cmVudCBpZiBpdHMgY3VycmVudCBwYXJlbnQgaXMNCgkJCS8vIHRoZSBkdW1teSAnbm9QYXJlbnQn LCB3aGljaCBhbG1vc3QgZXZlcnkgb2JqZWN0J3MgcGFyZW50IGlzDQoJCQkvLyBzZXQgdG8gb24g Y3JlYXRpb24gKHNlZSBMREJBU1RvYmogcGFyZW50IHByb3BlcnR5IGRlZikuDQoNCgkJCS8vIFRo ZSB0ZXN0IGZvciBudWxsIGlzIHBlY3VsaWFyIGdpdmVuIHRoaXMuIEJlY2F1c2UNCgkJCS8vIG5v UGFyZW50IGlzIGNyZWF0ZWQgc3RhdGljYWxseSwgc2V0dGluZyB0aGUgcGFyZW50IG9mDQoJCQkv LyBub1BhcmVudCBpcyBkaWZmaWN1bHQsIHBlcmhhcHMgaW1wb3NzaWJsZSwgdG8gZG8gc3RhdGlj YWxseQ0KCQkJLy8gYW5kIHJlbGlhYmx5LkRlc3BpdGUgdGhlIGRlY2xhcmF0aW9uICcjbnVsbGFi bGUgZW5hYmxlJywgaXQNCgkJCS8vIGdldHMgY3JlYXRlZCB3aXRoIGEgbnVsbCBwYXJyZW50IChx dWl0ZSByZWFzb25hYmx5KSwgaGVuY2UNCgkJCS8vIHRoaXMgY2hlY2suVGhlIGFjdHVhbCBzZXR0 aW5nIG9mIHRoZSBwYXJlbnQgaGFzIHRvIGJlIGRvbmUNCgkJCS8vIGF0IHJ1bnRpbWUgaS5lLmFm dGVyIHRoZSBzdGF0aWMgY3JlYXRpb24gb2YgJ25vUGFyZW50Jy4NCg0KCQkJaGFyZE11c3QyKCh0 aGlzLnBhcmVudCBpcyBOb1BhcmVudCkgfHwgKHRoaXMucGFyZW50IGlzIG51bGwpLA0KCQkJCSgp ID0+DQoJCQkJInRyaWVkIHRvIHJlLXNldCBwYXJlbnQgb24gb2JqZWN0IG9mIHR5cGU6ICINCgkJ CQkrIG5sICsgdGhpcy5jbGFzc05hbWVRDQoJCQkJKyBubCArICJPcmlnaW5hbCBwYXJlbnQgdHlw ZSBpczogIg0KCQkJCSsgKHRoaXM/LnBhcmVudD8uY2xhc3NOYW1lUSA9PSBudWxsID8gIm51bGwi IDogdGhpcy5wYXJlbnQuY2xhc3NOYW1lUSkNCgkJCQkrIG5sICsgImFuZCBuZXcgcGFyZW50IHR5 cGUgaXM6ICINCgkJCQkrIHBybnQuY2xhc3NOYW1lUQ0KCQkJCSsgbmwgKyAiSXRlbSBoYXZpbmcg cGFyZW50IHNldCBvbiBpdCBpczogIg0KCQkJCS8vIGJlY2F1c2Ugb2JqZWN0IG1heSBub3QgYmUg ZnVsbHkgY29uc3RydWN0ZWQgeWV0LCBjaGVjayBob3d2ZXIgVE9ETyB0aGlzIGlzIGEgbWFqb3Ig aGFjayBhbmQgbXVzdCBiZSBmaXhlZCBzb21ldGltZS4NCi8vCQkJCSsgbmwgKyAodGhpcyBpcyBu dWxsID8gIihudWxsKSIgOiB0aGlzLnRvUmF3U3RyKCkpKTsNCgkJCQkrIG5sICsgdGhpcy50b1Jh d1N0cigpICk7DQoNCgkJCXBhcmVudCA9IHBybnQ7DQoJCX0NCg0KDQoJCXB1YmxpYyB2b2lkIGZv cmNlTmV3UGFyZW50Rm9yUm9vdE9iamVjdCgpIHsNCgkJCS8vIEV2ZXJ5IG9iamVjdCBtdXN0IGhh dmUgc29tZSBwYXJlbnQsIGluY2x1ZGluZyB0aGUNCgkJCS8vIHJvb3Qgb2JqZWN0IG9mIHRoZSBw YXJzZSwgd2hpY2ggaXMgTERCaXRlbXMNCgkJCS8vIChhIHNlcXVlbmNlIG9mIExEQiBpdGVtcyks IHNvIHRoaXMgZm9yY2VzIG9uZS4NCgkJCS8vIEl0IGlzIG9ubHkgZm9yIHRoYXQgcHVycG9zZSEN CgkJCS8vIA0KCQkJLy8gTERCaXRlbXMgb2JqIGV4aXN0cyBmb3Igc3ViIG9ianMgc3VjaCBhcyB0 aGUgc3RhdGVtZW50cw0KCQkJLy8gaW4gYSB3aGlsZSBsb29wLCBpbiBhIHByb2MsIGluIGFuIGlm Li4uIGV0Yy4sIGZvcg0KCQkJLy8gd2hpY2ggdGhlaXIgcGFyZW50IGlzIHRoZSB3aGlsZS9wcm9j L2lmIGV0Yy4NCgkJCWhhcmRNdXN0UGFyZW50SXNBYnNlbnQoKTsNCgkJCXRoaXMucGFyZW50ID0g ZmFrZVBhcmVudDsNCgkJfQ0KDQoNCgkJLy9wdWJsaWMgdm9pZCByZXNldE15UGFyZW50VG8oTERC QVNUb2JqIHBybnQpIHsgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8gZGVzdHJv eSEhISEhISB0b2RvDQoJCS8vCXBhcmVudCA9IHBybnQ7DQoJCS8vfQ0KDQoJCS8vLy8vLy8vLy8v Ly8vLy8vLy8vLy8vLyB4eHh4eHh4eHh4eHh4IGRlbGV0ZSAtIHRvZG8NCgkJLy9wcml2YXRlIHZv aWQgc2V0UGFyZW50T25LaWQoTERCQVNUb2JqIGtpZCkgPT4gLy8gdG9kbyBuZWVkZWQ/DQoJCS8v CQkJCQkJCQkJCQkgIC8vIGNoZWNrIHBhcmVudGUgZG9lc24ndCBleGlzdCAtIHRvZG8NCgkJLy8J a2lkLnBhcmVudCA9IHRoaXM7DQoNCgkJcHVibGljIHZpcnR1YWwgdm9pZCBzZXRQYXJlbnRPbktp ZHNBbmRNYWtlS2lkc0RpY3QoICAvLyB0b2RvIC0gYW5kIGFkZCB0byBraWRzIGRpY3QNCgkJCQkJ CQkJCQkJCQkJCSAvLyB0aGlzIG1peGVzIHVwIHNldHRpbmcgcGFyZW50IGFuZCBtYWtpbmcgY2hp bGQgZGljdC4gTm90IGdvb2QuIC0gdG9kbw0KCQkJCQkJcGFyYW1zIChzdHJpbmcga2lkTmFtZSwg TERCQVNUb2JqIGtpZClbXSBraWRzSW4pIHsNCgkJCXZhciBsb2MgPSBjbGFzc05hbWVQbHVzKCJz ZXRQYXJlbnRPbktpZHNBbmRNYWtlS2lkc0RpY3QiKTsNCg0KCQkJdmFyIGtpZHNUb0FkZCA9IG5l dyBMREJTdHJ1Y3RzQ2hpbGRyZW4odGhpcywga2lkc0luKTsNCgkJCWhhcmRNdXN0MihraWRzLmlz RW1wdHksDQoJCQkJKCkgPT4NCgkJCQkkInNldHRpbmcga2lkcyBvbiBwYXJlbnQgJ3tjbGFzc05h bWV9JyIgDQoJCQkJKyAid2hlbiBraWRzIGlzIG5vdCBlbXB0eSwgIg0KCQkJCSsgJCJraWRzIGlz ICh7a2lkcy5Db3VudH0ga2lkcyk6Ig0KCQkJCSsgbmwgKyBraWRzLnRvRGVidWdTdHIoKQ0KCQkJ CSsgbmwgKyAkIlRyeWluZyB0byBhZGRcbntraWRzVG9BZGQudG9EZWJ1Z1N0cigpfVxuIg0KCQkJ CSsgJCJpbiB7Y2xhc3NOYW1lfSIpOw0KCQkJLy8gaWYgdGhlcmUgaXMgYW4gTERCU3RydWN0c0No aWxkcmVuIGFuZCBhbm90aGVyIGNoaWxkLA0KCQkJLy8gdGhpcyB3aWxsIGJsb3cgdXAgLSB3aWxs IG5lZWQgdG8gZG8ga2lkcy5BZGQgb3INCgkJCS8vIHNvbWV0aGluZyAtIGluIGZhY3QsIGtpZHMg bmVlZHMgdG8gYmUgY3JlYXRlZCBpbiBvbmUNCgkJCS8vIGdvLCB3aGljaCBpcyB3aGF0IGhhcHBl bnMuDQoJCQlraWRzID0ga2lkc1RvQWRkOyAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8v Ly8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8gd2h5IHRoaXM/IHRvZG8NCgkJCUFycmF5LkZv ckVhY2goa2lkc0luLCB4a2lkID0+IGhhcmRNdXN0KCEoeGtpZC5raWQgaXMgbnVsbCksIGxvYywg Im51bGwga2lkIikpOw0KCQkJQXJyYXkuRm9yRWFjaChraWRzSW4sIHhraWQgPT4geGtpZC5raWQu c2V0TXlQYXJlbnRUbyh0aGlzKSk7DQoJCX0NCg0KDQoJCXB1YmxpYyB2aXJ0dWFsIHZvaWQgc2V0 UGFyZW50T25LaWRzQW5kQWRkVG9LaWRzRGljdCgNCgkJCQkJcGFyYW1zIChzdHJpbmcga2lkTmFt ZSwgTERCQVNUb2JqIGtpZClbXSBraWRzSW4pIHsNCgkJCXZhciBraWRzVG9BZGRfanVzdEZvckVy clJlcG9ydGluZyA9IG5ldyBMREJTdHJ1Y3RzQ2hpbGRyZW4odGhpcywga2lkc0luKTsNCgkJCWhh cmRNdXN0Migha2lkcy5pc0VtcHR5LCAvLyBtYXkgZGlzYWJsZSB0aGlzIGxhdGVyIA0KCQkJCSgp ID0+DQoJCQkJImFkZGluZyB0byBraWRzIHdoZW4ga2lkcyBpcyBlbXB0eSwgIg0KCQkJCSArICQi a2lkcyBpc1xue2tpZHMudG9EZWJ1Z1N0cigpfVxuIg0KCQkJCSArICQiVHJ5aW5nIHRvIGFkZFxu e2tpZHNUb0FkZF9qdXN0Rm9yRXJyUmVwb3J0aW5nLnRvRGVidWdTdHIoKX1cbiINCgkJCQkgKyAk ImluIHtjbGFzc05hbWV9Iik7DQoJCQlBcnJheS5Gb3JFYWNoKGtpZHNJbiwgeGtpZCA9PiB7DQov LwkJCQlzZXRQYXJlbnRPbktpZCh4a2lkLmtpZCk7DQoJCQkJeGtpZC5raWQuc2V0TXlQYXJlbnRU byh0aGlzKTsNCgkJCQlraWRzLkFkZCh4a2lkKTsNCgkJCX0pOw0KCQl9DQoNCg0KCQlwdWJsaWMg dmlydHVhbCBJZGVudHNVc2VkIGdldEFsbElEcygpIHsNCgkJLyogVGhpcyBpcyBvdmVycmlkZGVu IG9ubHkgaW4gVGVtcGxhdGVkQWdnLCBhbmQgdGhhdCdzIG9ubHkgdG8gDQoJCQlkZWxpYmVyYXRl bHkgZmFpbC4gVGhlcmUncyBzb21ldGhpbmcgd3JvbmcgdGhlcmUsIHRvZG8gLSANCgkJCXVuLXZp cnR1YWxpc2UgdGhpcyBhbmQgcmVtb3ZlIHRoZSBvbmUgb3ZlcnJpZGUuIC0gdG9kbw0KCQkqLw0K CQkJdmFyIGl1ID0gbmV3IElkZW50c1VzZWQoKTsNCgkJCXRoaXMuX2dldEFsbElEcyhpdSk7DQoJ CQlyZXR1cm4gaXU7DQoJCX0NCg0KCQlwdWJsaWMgdmlydHVhbCB2b2lkIF9nZXRBbGxJRHMoSWRl bnRzVXNlZCBpdSkgew0KCQkvLyBHZXRzIGFsbCB0aGUgaWRlbnRpZmllcnMgZXhwbGljaXRseSB1 c2VkIChyZWFkIG9yIHdyaXR0ZW4pICAtLS0tLSB0b2RvIHVwZGF0ZSB0aGlzDQoJCS8vIGFueXdo ZXJlIGluIHRoZSBBU1QuICBEb2VzIG5vdCBnZXQgaWRlbnRzIHdoaWNoIGFyZQ0KCQkvLyBkZWNs YXJhdGlvbnMgaWUuIHBhcmFtZXRlcnMsIG9yIHZhci9jb25zdCBkZWNsYXJhdGlvbnMNCgkJLy8g dW5sZXNzIHRoZXNlIGFyZSBjb21iaW5lZCB3aXRoIGFuIGFzc2lnbm1lbnQuDQoJCS8vDQoJCS8v IEltcGxpZWQgaWRlbnRzIHN1Y2ggYXMgdGhvc2UgZnJvbSB0YmwuKiBhcmUgaW1wbGljaXQgYW5k IGlnbm9yZWQuDQoJCS8vDQoJCS8vIFJvb3QgY2FsbGVyIHN1cHBsaWVzIG5ldywgZW1wdHkgaXUN CgkJLy8gbmVlZCB1c2FnZSBoZXJlIC0gdG9kbyBkb2NzLy8NCgkJCWtpZHMuX2dldEFsbElEcyhp dSk7DQoJCX0NCg0KCQlwdWJsaWMgYWJzdHJhY3QgYm9vbCBjYW5HZXRBbGxJZGVudHNVc2VkIHsN CgkJLy8gCVRoaXMgc2VlbXMgdG8gYmUgdHJ1ZSBvbiBtb3N0IGNsYXNzZXMgc28gSSBjb3VsZCBz ZXQgdHJ1ZSANCgkJLy8gYXMgYSBkZWZhdWx0IGhlcmUgYW5kIG92ZXJyaWRlIGl0IHdoZXJlIGl0 J3Mgbm90IHdhbnRlZCwgc2F2aW5nIA0KCQkvLyBhIGNodW5rIG9mIGNvZGUsIGJ1dCBJJ2QgcmF0 aGVyIG1ha2UgaXQgZXhwbGljaXQgdG8gZm9yY2UgbWUgdG8gY29uc2lkZXIgZWFjaCBjYXNlLiBB IGJpdCBtb3JlIEMmUCBmb3IgbGVzcyBjaGFuY2Ugb2YgYnVncy4NCgkJCWdldDsNCgkJfQ0KDQoN CgkJLy8gUHJvZHVjZXMgYSBzdHJpbmcgdGhhdCBzaG91bGQgYmUgaWRlbnRpY2FsIHRvIChleGNl cHRpbmcNCgkJLy8gd2hpdGVzcGFjZXMpIHRoZSBpbnB1dCBpZS4gZW1pdCBMREIgY29kZSBub3Qg dmFsaWQgU1FMDQoJCS8vDQoJCS8vIFRvU3RyaW5nIHdhcyBjYXVzaW5nIHRvbyBtYW55IHdlaXJk IHByb2JsZW1zIChkdWUgdG8gbXkNCgkJLy8gaW5leHBlcmllbmNlIHdpdGggYyMpIHNvIGp1c3Qg dXNlZCB0b1Jhd1N0cigpDQoJCXB1YmxpYyBhYnN0cmFjdCBzdHJpbmcgdG9SYXdTdHIoKTsNCg0K CQlwdWJsaWMgb3ZlcnJpZGUgc3RyaW5nIHRvRGVidWdTdHIoKSA9PiB0b1Jhd1N0cigpOw0KDQoJ fSAvLyBlbmQgTERCQVNUb2JqDQoNCg0KDQoJcHVibGljIGludGVyZmFjZSBJaGFuZGxlUHJlZml4 ZXM8VD4NCgkJCQkJCXdoZXJlIFQgOiBMREJSb290IHsNCg0KCQlwdWJsaWMgYm9vbCBpc1ByZWZp eGVkIHsgZ2V0OyB9DQoNCgkJcHVibGljIGJvb2wgaXNFeGNlc3NQcmVmaXhlZCB7IGdldDsgfQ0K DQoJCS8vIFRoZSBUIGluIGFkZFByZWZpeC9yZVByZWZpeC93aXRob3V0UHJlZml4IGlzIGJlY2F1 c2Ugd2UgbWF5IGJlIA0KCQkvLyByZXR1cm5pbmcgZWcuIGEgbGlzdCBvZiBpdGVtcyB3aXRoIHBy ZWZpeGVzIA0KCQkvLyB0aHVzIG1vZGlmaWVkLCBub3QgYSBzaW5nbGUgUE1RSWRlbnQNCg0KCQlw dWJsaWMgVCBhZGRQcmVmaXgoUE1RSWRlbnQgcGZ4KTsNCg0KCQlwdWJsaWMgVCByZVByZWZpeChQ TVFJZGVudCBuZXdwZngpOw0KDQovLwkJcHVibGljIFQgc3RyaXBQcmVmaXgoUE1RSWRlbnQgaWQp Ow0KCX0NCgkvLyB0b2RvIC0gbW92ZSB0aGlzDQoNCg0KDQoNCg0KCXB1YmxpYyBhYnN0cmFjdCBj bGFzcyBMREJSb290IHsNCgkJLy8gUm9vdCBvZiBldmVyeXRoaW5nIExEQi1pc2gNCg0KCQlwdWJs aWMgYm9vbCBFcXVhbHMoW0FsbG93TnVsbF0gTERCUm9vdCBvdGhlcikgew0KCQkJdGhyb3cgbmV3 IExEQlNob3VsZE5vdEJlSW1wbGVtZW50ZWRFeGNlcHRpb24oDQoJCQkJCQkJCQkiY2FsbGVkIEVx dWFscyBvbiBMREJSb290Iik7DQoJCX0NCg0KCQlwdWJsaWMgb3ZlcnJpZGUNCgkJCWJvb2wgRXF1 YWxzKFtBbGxvd051bGxdIE9iamVjdCBvdGhlcikgew0KCQkJdGhyb3cgbmV3IExEQlNob3VsZE5v dEJlSW1wbGVtZW50ZWRFeGNlcHRpb24oDQoJCQkJCQkJCQkiY2FsbGVkIEVxdWFscyBpbiBPYmpl Y3QiKTsNCgkJfQ0KDQoJCXB1YmxpYyBvdmVycmlkZSBpbnQgR2V0SGFzaENvZGUoKSB7DQoJCQl0 aHJvdyBuZXcgTERCU2hvdWxkTm90QmVJbXBsZW1lbnRlZEV4Y2VwdGlvbigNCgkJCQkJCQkJCSJj YWxsZWQgR2V0SGFzaENvZGUgaW4gTERCUm9vdCIpOw0KCQl9DQoNCgkJcHVibGljIHN0YXRpYyBi b29sIG9wZXJhdG9yID09KExEQlJvb3QgbGhzLA0KCQkJCQkJCQkJICAgTERCUm9vdCByaHMpIHsN CgkJCXRocm93IG5ldyBMREJTaG91bGROb3RCZUltcGxlbWVudGVkRXhjZXB0aW9uKA0KCQkJCQkJ CQkJImNhbGxlZCA9PSBpbiBMREJSb290Iik7DQoJCX0NCg0KCQlwdWJsaWMgc3RhdGljIGJvb2wg b3BlcmF0b3IgIT0oTERCUm9vdCBsaHMsDQoJCQkJCQkJCQkgICBMREJSb290IHJocykgew0KCQkJ dGhyb3cgbmV3IExEQlNob3VsZE5vdEJlSW1wbGVtZW50ZWRFeGNlcHRpb24oDQoJCQkJCQkJCQki Y2FsbGVkICE9IGluIExEQlJvb3QiKTsNCgkJfQ0KDQoNCgkJcHVibGljIHZpcnR1YWwgc3RyaW5n IGNsYXNzTmFtZSB7DQoJCQkvLyB0b2RvIC0gdGhpcyBuZWVkcyBjaGVja2luZyBpdCB3b3JrcyBh cyBJIHdhbnQNCgkJCS8vIGFsc28gcmVuYW1lIHRvIGxkYmNsYXNzbmFtZSAtLSB0b2RvDQoJCQln ZXQgPT4gdGhpcy5HZXRUeXBlKCkuRnVsbE5hbWUgPz8gIih1bmtub3duKSI7DQoJCX0NCg0KDQoJ CXB1YmxpYyB2aXJ0dWFsIHN0cmluZyBjbGFzc05hbWVRID0+DQoJCQkiJyIgKyBjbGFzc05hbWUg KyAiJyI7DQoNCg0KCQlwdWJsaWMgdmlydHVhbCBzdHJpbmcgY2xhc3NOYW1lUGx1cyhzdHJpbmcg cGx1cykgPT4NCgkJCWNsYXNzTmFtZSArICIuIiArIHBsdXM7DQoNCgkJcHVibGljIG92ZXJyaWRl IHN0cmluZyBUb1N0cmluZygpIHsNCgkJCS8vIFRoaXMgaW1wbGljaXQgdG8tc3RyaW5nIGNvbnZl cnNpb24gY3JhcCBjb3N0IG1lIGEgZmV3IGhvdXJzLCBzbyBhdCBsZWFzdA0KCQkJLy8gZG8gdGhp cyAmIGJsb3cgdXAgYXQgcnVudGltZS4gV291bGQgcHJlZmVyIGNvbXBpbGUgdGltZSBidXQgaXQg c2VlbXMNCgkJCS8vIG5vdCBwb3NzaWJsZS4gIFRoaXMgdHVybnMgb3V0IHRvIGhhdmUgYmVlbiBh IGdvb2QgaWRlYSwNCgkJCS8vIHNhdmVkIG1lIHF1aXRlIGEgYml0IG1vcmUgZGVidWdnaW5nIQ0K CQkJLy8gPGh0dHBzOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzE1MzQ1NTE3L2lzLWl0 LXBvc3NpYmxlLXRvLWRpc2FibGUtaW1wbGljaXQtdG9zdHJpbmctY2FsbD4NCgkJCS8vIFdpbGwg dHJ5IDxodHRwczovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy81NDM1NDM0Mi9ob3ctdG8t Z2V0LWFuLWVycm9yLXNob3duLXdoZW4tdXNpbmctbm9uLXN0cmluZ3MtYXMtc3RyaW5ncy1pbnN0 ZWFkLW9mLWFuLWF1dG9tLzU0MzU1MTE1IzU0MzU1MTE1KQ0KCQkJdmFyIG1zZyA9ICJMREJSb290 LlRvU3RyaW5nKCkiOw0KCQkJdGhyb3cgbmV3IExEQlRvU3RyaW5nSW1wbGljdENvbnZlcnNpb25F eGNlcHRpb24obXNnKTsNCgkJfQ0KDQoJCXB1YmxpYyBhYnN0cmFjdCBzdHJpbmcgdG9EZWJ1Z1N0 cigpOw0KCX0NCg0KDQoNCglwdWJsaWMgYWJzdHJhY3QgY2xhc3MgRXBoZW1lcmFsIDogTERCUm9v dCB7DQoJCS8vIGZvciBvYmplY3RzIHRoYXQgYXJlIG5vdCBwYXJ0IG9mIHRoZSBBU1QNCgl9DQoN Cg0KDQoJcHVibGljIGludGVyZmFjZSBJV2l0aExpbmVOVW0geyAgLy8gdG9kbyAtIHVzZSBvciBy ZW1vdmUgLSB0b2RvDQoJCS8vCXB1YmxpYyANCgl9DQoNCg0KCXB1YmxpYyBpbnRlcmZhY2UgSUhh c1RhYmxlQWxpYXMgew0KCQkvLyBIYXMgYSB0YWJsZSBhbGlhcyBBU1Qgb2JqLiBNYXkgYmUgYSAu Li5NaXNzaW5nIHN1YnR5cGUgaW4gd2hpY2gNCgkJLy8gaXQgaGFzIG5vIGFsaWFzIGdpdmVuIGJ5 IHRoZSB1c2VyLCBidXQgYWxpYXMgQVNUIGlzIHRoZXJlLiBNb3JlDQoJCS8vIGFjY3VyYXRlbHkg YSBUYWJsZVNvdXJjZSBhbGlhcyBidXQgb2sNCgkJcHVibGljIGFic3RyYWN0IFRhYmxlQWxpYXMg dGEgeyBnZXQ7IHNldDsgfQ0KCX0NCg0KDQoJLy8gQmFzZSBjbGFzcyBmb3IgYWxsIExEQiBBU1Qg b2JqZWN0cw0KCXB1YmxpYyBhYnN0cmFjdCBjbGFzcyBMREJBU1RvYmogOiBMREJSb290IHsNCgkJ Ly8gVGhpcyBvbmUgaXMgYSBwcm9ibGVtLiBJZiBJIGRlY2xhcmUgdGhlICdwYXJlbnQnIHByb3Bl cnR5DQoJCS8vIGFic3RyYWN0IEkgdGhlbiBoYXZlIHRvIGltcGxlbWVudCBpdCBsaXRlcmFsbHkg aHVuZHJlZHMgb2YNCgkJLy8gdGltZXMgaW4gdGhlIGRlcml2ZWQgY2xhc3NlcywgYW5kIEkgcmVh bGx5IGRvbid0IHRoaW5rIGl0DQoJCS8vIHdvdWxkIGhlbHAgc28ganVzdCBzZXQgaXQgdG8gYSBk ZWZhdWx0IHdoaWNoIGdldHMgb3ZlcndyaXR0ZW4gbGF0ZXIuDQoJCS8vIA0KCQkvLyBUaGUgcHJv YmxlbSBpcyB0aGF0IHRob3NlIG9iamVjdHMgd2VyZSBjcmVhdGVkIGJ5IHRoZQ0KCQkvLyBwYXJz ZXIsIHdoaWNoIGNyZWF0ZXMgdGhlbSBib3R0b20tdXAsIHdoaWNoIG1lYW5zIHlvdSBjYW4ndA0K CQkvLyBrbm93IHRoZSBwYXJlbnQgd2hlbiB0aGV5IGFyZSBjcmVhdGVkLiBJdCBzaG91bGQgYmUN CgkJLy8gcG9zc2libGUgdG8gd29yayBhcm91bmQgdGhpcyBidXQgaXQgZG9lcyBtZWFuIHJld29y a2luZyB0aGUNCgkJLy8gcGFyc2VyIGZ1bmRhbWVudGFsbHksIGFuZCBJJ20gbm90IGdvaW5nIHRv IGRvIHRoYXQNCgkJLy8gYXNzdW1laW5nIGl0J3MgZXZlbiBwb3NzaWJsZS4NCg0KCQkvLyB0b2Rv IC0gcmVhZCB1cCBvbiBwcml2L3B1Yi9wcm9nIGFjY2Vzc29ycyBJIHJlYWxseSBkb24ndA0KCQkv LyBnZXQgdGhlc2UgYXQgYWxsDQoJCXB1YmxpYyBMREJBU1RvYmogcGFyZW50IHsgZ2V0OyBwcml2 YXRlIHNldDsgfQ0KCQkJCQkJPSBub1BhcmVudDsNCgkJLy8gVW5pcXVlIElEIHBlciBvYmplY3Qs IHVzZWZ1bCBmb3IgZGlzdGluZ3Vpc2hpbmcgdGhlbQ0KCQkvLyB3aXRob3V0IGdlbmVyYWwgZXF1 YWxpdHkuDQoJCXJlYWRvbmx5IHB1YmxpYyB1bG9uZyB1aWQgPSBuZXdVSUQoKTsNCg0KCQkvLyBw dWJsaWMgYWJzdHJhY3QgaW50IGxpbmVOdW0geyBnZXQ7IHNldDsgfQ0KDQoJCS8vIElzIHZhbGlk YXRlZCBpcyBhIGNoZWFwaXNoIGNoZWNrIHRvIGVuc3VyZSBldmVyeXRoaW5nIGdldHMNCgkJLy8g dmFsaWRhdGVkDQoJCS8vIGNhbiBkbyB0aGlzIGFzIGF1dG8gcHJvcD8gdG9kbw0KCQlwcml2YXRl IGJvb2wgX3ZhbGlkYXRlZCA9IGZhbHNlOw0KDQoJCXByb3RlY3RlZCBib29sIHZhbGlkYXRlZCB7 DQoJCQlnZXQgPT4gX3ZhbGlkYXRlZDsNCgkJCXNldCB7DQoJCQkJLy8gaGFyZE11c3QoIXZhbGlk YXRlZCwgIi4uLiBhbHJlYWR5IHZhbGlkYXRlZC4uLiAiKTsgLSBubw0KCQkJCS8vIEl0J3MgaGFy ZCB0byBhdm9pZCB2YWxpZGF0aW5nIGEgdGhpbmcgdHdpY2UsIHNvIGZvciBub3cgYWxsb3cgaXQN CgkJCQkvLyBMb29rIGludG8gaXQgbGF0ZXIsIHJlYWxseSBzaG91bGRuJ3QgaGFwcGVuDQoJCQkJ X3ZhbGlkYXRlZCA9IHRydWU7DQoJCQl9DQoJCX0NCg0KCQlwdWJsaWMgTERCU3RydWN0c0NoaWxk cmVuIGtpZHMgeyBnZXQ7IHByaXZhdGUgc2V0OyB9ID0NCgkJCQkJbmV3IExEQlN0cnVjdHNDaGls ZHJlbihub1BhcmVudCk7IC8vIGp1c3QgZWFzaWVyDQoNCgkJcHVibGljIExEQkFTVG9iaigpIHsg IC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8v Ly8vLy8vLy8gdG9kbyBkZWFkPw0KCQkJCQkJCSAgLy8gVlN0dWRpbyB0aGlua3MgdGhpcyBoYXMg emVybyByZWZlcmVuY2VzLCB3aGljaCBpcyB0cnVlIGV4cGxpY2l0bHksIGJ1dCBpdCdzIA0KCQkJ CQkJCSAgLy8gY2FsbGVkIGltcGxpY2l0bHkgb24gZXZlcnkgb2JqIGNyZWF0aW9uIC0gb3Igc2hv dWxkIGRvIHRvZG8tIGNoZWNrDQoJCQlpZiAocmVjb3JkT2JqZWN0c0NyZWF0ZWQpIHsNCgkJCQlB bGxDcmVhdGVkSXRlbXMuQWRkKHRoaXMpOw0KCQkJfQ0KCQl9DQoNCg0KCQlwdWJsaWMgdmlydHVh bCB2b2lkIHZhbGlkYXRlKCkgew0KCQkJaWYgKHJlcG9ydEFsc29JZlZhbGlkYXRpb25PSykgew0K CQkJCWRlYnVnbXNnKCJ2YWxpZGF0aW5nLi4uIiArIGNsYXNzTmFtZQ0KCQkJCQkrICIgKCIgKyBh c05hbWVPcklkZW50Q29udGVudHMoKSArICIpIik7DQoJCQl9DQoJCQltaHBfbWhrKCk7DQoJCQlr aWRzLnZhbGlkYXRlKCk7DQoJCQkvLyB2YWxpZGF0ZWQgPSB0cnVlOyAtLSBObywgZ2V0IGVhY2gg c3ViY2xhc3MgdG8gc2V0DQoJCQkvLyB2YWxpZGF0ZWQuIFRoYXQgZm9yY2VzIGFuIGV4cGxpY2l0 IGNhbGwgdG8gYmFzZSgpIHdoaWNoDQoJCQkvLyBpcyBtb3JlIGNvZGUgYnV0IG9rLg0KCQl9DQoN Cg0KCQlwdWJsaWMgYm9vbCBpc1ZhbGlkYXRlZCB7IGdldCA9PiB2YWxpZGF0ZWQ7IH0gIC8vIHRv ZG8ganVzdCA9PiB2YWxpZGF0ZWQ7DQoNCg0KCQlwdWJsaWMgdmlydHVhbCBib29sIGlzVG9wTGV2 ZWxJdGVtU2VxID0+IGZhbHNlOw0KDQoNCgkJcHVibGljIHZpcnR1YWwgdm9pZCBtaHBfbWhrKCkg eyAgLy8gZG9uJ3QgdGhpbmsgdGhpcyBuZWVkIGJlIHZpcnR1YWwgLSB0b2RvPw0KCQkJCQkJCQkJ CSAvLyA9IG11c3QgaGF2ZSBwYXJlbnQsIG11c3QgaGF2ZSBraWRzLiBUaGUga2lkcyBtYXkgYmUg dGhlDQoJCQkJCQkJCQkJIC8vIGVtcHR5IHNldCBhbmQgdGhlIHBhcmVudCBtYXkgYmUgbm9QYXJl bnQgYnV0IHRoZXkgbXVzdA0KCQkJCQkJCQkJCSAvLyBleGlzdC4NCgkJCQkJCQkJCQkgLy8gV2h5 IG5vdCBqdXN0IGlubGluZSB0aGlzIGludG8gdmFsaWRhdGUoKT8NCgkJCQkJCQkJCQkgLy8gQmVj YXVzZSBhIGZldyBjbGFzc2VzIG5lZWQgYmVzcG9rZSB2YWxpZGF0aW9uLCBidXQgc3RpbGwgbXVz dCBjaGVjayB0aGlzLg0KCQkJaGFyZE11c3RQYXJlbnRJc1ByZXNlbnQoKTsNCgkJCWtpZHMuZWFj aEtpZFBhcmVudE11c3RCZSh0aGlzKTsNCgkJfQ0KDQoNCgkJcHVibGljIHN0cmluZyBhc05hbWVP cklkZW50Q29udGVudHMoKSB7DQoJCQkvLyBmb3IgdmVyeSBjcnVkZSBkZWJ1Z2dpbmcgDQoJCQl2 YXIgb3B0TmFtZSA9IHRoaXMgaXMgSWlzTmFtZWRJdGVtIG5pID8gbmkubmFtZS50b1Jhd1N0cigp IDogIiI7DQoJCQlvcHROYW1lID0gKG9wdE5hbWUgPT0gIiIgJiYgdGhpcyBpcyBQTVFJZGVudCkg PyB0aGlzLnRvUmF3U3RyKCkgOiAiIjsNCg0KCQkJdmFyIG9wdE5hbWUyID0gb3B0TmFtZSArICIg ICh1aWQ6IiArIHVpZC5Ub1N0cmluZygpICsgIikgIg0KCQkJCSsgZ2V0Rmlyc3RGZXdDaGFyc09m KHRvUmF3U3RyKCkpOw0KCQkJcmV0dXJuIG9wdE5hbWUyOw0KCQl9DQoNCg0KCQlwdWJsaWMgdmly dHVhbCB2b2lkIGdldEFsbFVJRHMoVUlEc2V0IHVpZHMpIHsNCgkJCXVpZHMuQWRkKHRoaXMpOw0K CQkJa2lkcy5Gb3JFYWNoKG5hbWVkS2lkID0+IG5hbWVkS2lkLmtpZC5nZXRBbGxVSURzKHVpZHMp KTsNCgkJfQ0KDQoNCgkJcHVibGljIGJvb2wgaXNTdHViUGFyZW50IHsgZ2V0ID0+ICh0aGlzIGlz IE5vUGFyZW50KSB8fCAodGhpcyBpcyBGYWtlUGFyZW50KTsgfQ0KDQoNCgkJcHVibGljIHZvaWQg dmFsaWRhdGVTcGVjaWZpY0l0ZW1zKHBhcmFtcyBMREJBU1RvYmpbXSBpdGVtcykgew0KCQkJQXJy YXkuRm9yRWFjaChpdGVtcywgaXRlbSA9PiBpdGVtLnZhbGlkYXRlKCkpOw0KCQl9DQoNCg0KCQlw dWJsaWMgVD8gb3B0Q2xpbWJUbzxUPigpIHdoZXJlIFQgOiBMREJBU1RvYmogew0KCQkJdmFyIHJl c0l0ZW0gPSB0aGlzOw0KCQkJd2hpbGUgKCEocmVzSXRlbSBpcyBUKSkgew0KCQkJCWlmIChyZXNJ dGVtLnBhcmVudC5pc1N0dWJQYXJlbnQpIHsNCgkJCQkJcmV0dXJuIG51bGw7DQoJCQkJfQ0KCQkJ CXJlc0l0ZW0gPSByZXNJdGVtLnBhcmVudDsNCgkJCX0NCg0KCQkJdmFyIHJlcyA9IHJlc0l0ZW0g YXMgVDsNCgkJCXJldHVybiByZXM7DQoJCX0NCg0KDQoJCXB1YmxpYyBUIHJlcUNsaW1iVG88VD4o KSB3aGVyZSBUIDogTERCQVNUb2JqIHsNCgkJCXZhciBsb2MgPSBjbGFzc05hbWUgKyAiLnJlcUNs aW1iVG88VD4oKSI7DQoJCQl2YXIgcmVzID0gb3B0Q2xpbWJUbzxUPigpOw0KCQkJaGFyZE11c3Qy KCEocmVzIGlzIG51bGwpLCANCgkJCQkvLyBUaGFua3MgU08gPGh0dHBzOi8vc3RhY2tvdmVyZmxv dy5jb20vcXVlc3Rpb25zLzI1ODE2NDIvaG93LWRvLWktZ2V0LXRoZS10eXBlLW5hbWUtb2YtYS1n ZW5lcmljLXR5cGUtYXJndW1lbnQ+DQoJCQkJLy8gVG9kbyAtIHVzZSB0aGlzIGVsc2V3aGVyZSwg cG9zcyBFeHBlY3RFeGNlcHRpb24/IHRvZG8NCgkJCQkoKSA9Pg0KCQkJCWxvYyANCgkJCQkrIG5s ICsgIiwgY2xpbWJlZCB0byB0b3AsIGRpZG4ndCBmaW5kIHR5cGUgIg0KCQkJCSsgdHlwZW9mKFQp LkZ1bGxOYW1lDQoJCQkJKyBubCArICJIaWVyYXJjaHkgaXM6ICINCgkJCQkrIG5sICsgZ2V0SXRl bVdpdGhQYXJlbnRzKHRoaXMpKTsNCgkJCWlmIChyZXMgaXMgbnVsbCkgeyB0aHJvdyBuZXcgTk5R QygpOyB9DQoJCQlyZXR1cm4gcmVzOw0KCQl9DQoNCg0KCQlwdWJsaWMgdm9pZCBoYXJkTXVzdFBh cmVudElzUHJlc2VudCgpIHsNCg0KCQkJaGFyZE11c3QyKCEocGFyZW50IGlzIG51bGwpLCANCgkJ CQkoKSA9Pg0KCQkJCSAiTlVMTCBwYXJlbnQgZm9yIGl0ZW0gb2YgdHlwZVxuIg0KCQkJCSArICQi e0dldFR5cGUoKX1cbi4iKTsNCg0KCQkJaGFyZE11c3QyKCEodGhpcy5wYXJlbnQgaXMgTm9QYXJl bnQpLA0KCQkJCSgpID0+DQoJCQkJIlBhcmVudCBpcyBOb1BhcmVudCBvbiBvYmplY3Qgb2YgdHlw ZVxuIg0KCQkJCSsgJCIne3RoaXMuY2xhc3NOYW1lfSciKTsNCgkJfQ0KDQoNCgkJcHVibGljIHZv aWQgaGFyZE11c3RQYXJlbnRJc0Fic2VudCgpIHsNCgkJCS8vIEZvciBjaGVja2luZyBjbG9uaW5n IC0gcGFyZW50IHNob3VsZCBiZSBOb1BhcmVudCBpbW1lZGlhdGVseSANCgkJCS8vIGFmdGVyLCBi ZWZvcmUgaXQncyBzZXQgYnkgcGFyZW50LCBhbmQgbmV2ZXIgbnVsbA0KCQkJaGFyZE11c3QoIShw YXJlbnQgaXMgbnVsbCksDQoJCQkJICJOVUxMIHBhcmVudCBmb3IgaXRlbSBvZiB0eXBlXG4iDQoJ CQkJICsgJCJ7R2V0VHlwZSgpfVxuLiIpOw0KCQkJaGFyZE11c3QoKHRoaXMucGFyZW50IGlzIE5v UGFyZW50KSwNCgkJCQkiUGFyZW50IHNob3VsZCBiZSBOb1BhcmVudCBvbiBvYmplY3Qgb2YgdHlw ZVxuIg0KCQkJCSsgJCIne3RoaXMuY2xhc3NOYW1lfSciKTsNCgkJfQ0KDQoNCgkJcHVibGljIGJv b2wgaGFzUGFyZW50PFA+KCkgew0KCQkJaGFyZE11c3QoISh0aGlzIGlzIE5vUGFyZW50KSwgIkl0 ZW0gaXMgTm9QYXJlbnQiKTsNCgkJCXJldHVybiB0aGlzLnBhcmVudCBpcyBQOw0KCQl9DQoNCg0K CQlwdWJsaWMgYm9vbCBoYXNBbmNlc3RvcjxBPigpIHsNCgkJCWhhcmRNdXN0KCF0aGlzLmlzU3R1 YlBhcmVudCwgIkl0ZW0gaXMgTm9QYXJlbnQiKTsNCg0KCQkJLy8gaG93IHRvIGRvIHdpdGggYSBz d2l0Y2ggZXhwcj8NCgkJCWlmICh0aGlzLnBhcmVudC5pc1N0dWJQYXJlbnQgLyogaXMgTm9QYXJl bnQgfHwgdGhpcy5wYXJlbnQgaXMgRmFrZVBhcmVudCovICkgeyAvLyB0b2RvIGRvIGFzIHguaGFz RnVkZ2VkUGFyZW50KCkgLSB0b2RvDQoJCQkJcmV0dXJuIGZhbHNlOw0KCQkJfSBlbHNlIGlmICh0 aGlzLnBhcmVudCBpcyBBKSB7DQoJCQkJcmV0dXJuIHRydWU7DQoJCQl9IGVsc2Ugew0KCQkJCXJl dHVybiB0aGlzLnBhcmVudC5oYXNBbmNlc3RvcjxBPigpOw0KCQkJfQ0KCQl9DQoNCgkJcHVibGlj IGJvb2wgbm90SGFzQW5jZXN0b3I8QT4oKSA9Pg0KCQkJIWhhc0FuY2VzdG9yPEE+KCk7DQoNCg0K CQlwdWJsaWMgdm9pZCBzZXRNeVBhcmVudFRvKExEQkFTVG9iaiBwcm50KSB7DQoJCQkvLyBBbiBv YmplY3QgbWF5IG9ubHkgc2V0IGl0cyBwYXJlbnQgaWYgaXRzIGN1cnJlbnQgcGFyZW50IGlzDQoJ CQkvLyB0aGUgZHVtbXkgJ25vUGFyZW50Jywgd2hpY2ggYWxtb3N0IGV2ZXJ5IG9iamVjdCdzIHBh cmVudCBpcw0KCQkJLy8gc2V0IHRvIG9uIGNyZWF0aW9uIChzZWUgTERCQVNUb2JqIHBhcmVudCBw cm9wZXJ0eSBkZWYpLg0KDQoJCQkvLyBUaGUgdGVzdCBmb3IgbnVsbCBpcyBwZWN1bGlhciBnaXZl biB0aGlzLiBCZWNhdXNlDQoJCQkvLyBub1BhcmVudCBpcyBjcmVhdGVkIHN0YXRpY2FsbHksIHNl dHRpbmcgdGhlIHBhcmVudCBvZg0KCQkJLy8gbm9QYXJlbnQgaXMgZGlmZmljdWx0LCBwZXJoYXBz IGltcG9zc2libGUsIHRvIGRvIHN0YXRpY2FsbHkNCgkJCS8vIGFuZCByZWxpYWJseS5EZXNwaXRl IHRoZSBkZWNsYXJhdGlvbiAnI251bGxhYmxlIGVuYWJsZScsIGl0DQoJCQkvLyBnZXRzIGNyZWF0 ZWQgd2l0aCBhIG51bGwgcGFycmVudCAocXVpdGUgcmVhc29uYWJseSksIGhlbmNlDQoJCQkvLyB0 aGlzIGNoZWNrLlRoZSBhY3R1YWwgc2V0dGluZyBvZiB0aGUgcGFyZW50IGhhcyB0byBiZSBkb25l DQoJCQkvLyBhdCBydW50aW1lIGkuZS5hZnRlciB0aGUgc3RhdGljIGNyZWF0aW9uIG9mICdub1Bh cmVudCcuDQoNCgkJCWhhcmRNdXN0MigodGhpcy5wYXJlbnQgaXMgTm9QYXJlbnQpIHx8ICh0aGlz LnBhcmVudCBpcyBudWxsKSwNCgkJCQkoKSA9Pg0KCQkJCSJ0cmllZCB0byByZS1zZXQgcGFyZW50 IG9uIG9iamVjdCBvZiB0eXBlOiAiDQoJCQkJKyBubCArIHRoaXMuY2xhc3NOYW1lUQ0KCQkJCSsg bmwgKyAiT3JpZ2luYWwgcGFyZW50IHR5cGUgaXM6ICINCgkJCQkrICh0aGlzPy5wYXJlbnQ/LmNs YXNzTmFtZVEgPT0gbnVsbCA/ICJudWxsIiA6IHRoaXMucGFyZW50LmNsYXNzTmFtZVEpDQoJCQkJ KyBubCArICJhbmQgbmV3IHBhcmVudCB0eXBlIGlzOiAiDQoJCQkJKyBwcm50LmNsYXNzTmFtZVEN CgkJCQkrIG5sICsgIkl0ZW0gaGF2aW5nIHBhcmVudCBzZXQgb24gaXQgaXM6ICINCgkJCQkvLyBi ZWNhdXNlIG9iamVjdCBtYXkgbm90IGJlIGZ1bGx5IGNvbnN0cnVjdGVkIHlldCwgY2hlY2sgaG93 dmVyIFRPRE8gdGhpcyBpcyBhIG1ham9yIGhhY2sgYW5kIG11c3QgYmUgZml4ZWQgc29tZXRpbWUu DQovLwkJCQkrIG5sICsgKHRoaXMgaXMgbnVsbCA/ICIobnVsbCkiIDogdGhpcy50b1Jhd1N0cigp KSk7DQoJCQkJKyBubCArIHRoaXMudG9SYXdTdHIoKSApOw0KDQoJCQlwYXJlbnQgPSBwcm50Ow0K CQl9DQoNCg0KCQlwdWJsaWMgdm9pZCBmb3JjZU5ld1BhcmVudEZvclJvb3RPYmplY3QoKSB7DQoJ CQkvLyBFdmVyeSBvYmplY3QgbXVzdCBoYXZlIHNvbWUgcGFyZW50LCBpbmNsdWRpbmcgdGhlDQoJ CQkvLyByb290IG9iamVjdCBvZiB0aGUgcGFyc2UsIHdoaWNoIGlzIExEQml0ZW1zDQoJCQkvLyAo YSBzZXF1ZW5jZSBvZiBMREIgaXRlbXMpLCBzbyB0aGlzIGZvcmNlcyBvbmUuDQoJCQkvLyBJdCBp cyBvbmx5IGZvciB0aGF0IHB1cnBvc2UhDQoJCQkvLyANCgkJCS8vIExEQml0ZW1zIG9iaiBleGlz dHMgZm9yIHN1YiBvYmpzIHN1Y2ggYXMgdGhlIHN0YXRlbWVudHMNCgkJCS8vIGluIGEgd2hpbGUg bG9vcCwgaW4gYSBwcm9jLCBpbiBhbiBpZi4uLiBldGMuLCBmb3INCgkJCS8vIHdoaWNoIHRoZWly IHBhcmVudCBpcyB0aGUgd2hpbGUvcHJvYy9pZiBldGMuDQoJCQloYXJkTXVzdFBhcmVudElzQWJz ZW50KCk7DQoJCQl0aGlzLnBhcmVudCA9IGZha2VQYXJlbnQ7DQoJCX0NCg0KDQoJCS8vcHVibGlj IHZvaWQgcmVzZXRNeVBhcmVudFRvKExEQkFTVG9iaiBwcm50KSB7ICAvLy8vLy8vLy8vLy8vLy8v Ly8vLy8vLy8vLy8vLy8vLy8vIGRlc3Ryb3khISEhISEgdG9kbw0KCQkvLwlwYXJlbnQgPSBwcm50 Ow0KCQkvL30NCg0KCQkvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8geHh4eHh4eHh4eHh4eCBkZWxl dGUgLSB0b2RvDQoJCS8vcHJpdmF0ZSB2b2lkIHNldFBhcmVudE9uS2lkKExEQkFTVG9iaiBraWQp ID0+IC8vIHRvZG8gbmVlZGVkPw0KCQkvLwkJCQkJCQkJCQkJICAvLyBjaGVjayBwYXJlbnRlIGRv ZXNuJ3QgZXhpc3QgLSB0b2RvDQoJCS8vCWtpZC5wYXJlbnQgPSB0aGlzOw0KDQoJCXB1YmxpYyB2 aXJ0dWFsIHZvaWQgc2V0UGFyZW50T25LaWRzQW5kTWFrZUtpZHNEaWN0KCAgLy8gdG9kbyAtIGFu ZCBhZGQgdG8ga2lkcyBkaWN0DQoJCQkJCQkJCQkJCQkJCQkgLy8gdGhpcyBtaXhlcyB1cCBzZXR0 aW5nIHBhcmVudCBhbmQgbWFraW5nIGNoaWxkIGRpY3QuIE5vdCBnb29kLiAtIHRvZG8NCgkJCQkJ CXBhcmFtcyAoc3RyaW5nIGtpZE5hbWUsIExEQkFTVG9iaiBraWQpW10ga2lkc0luKSB7DQoJCQl2 YXIgbG9jID0gY2xhc3NOYW1lUGx1cygic2V0UGFyZW50T25LaWRzQW5kTWFrZUtpZHNEaWN0Iik7 DQoNCgkJCXZhciBraWRzVG9BZGQgPSBuZXcgTERCU3RydWN0c0NoaWxkcmVuKHRoaXMsIGtpZHNJ bik7DQoJCQloYXJkTXVzdDIoa2lkcy5pc0VtcHR5LA0KCQkJCSgpID0+DQoJCQkJJCJzZXR0aW5n IGtpZHMgb24gcGFyZW50ICd7Y2xhc3NOYW1lfSciIA0KCQkJCSsgIndoZW4ga2lkcyBpcyBub3Qg ZW1wdHksICINCgkJCQkrICQia2lkcyBpcyAoe2tpZHMuQ291bnR9IGtpZHMpOiINCgkJCQkrIG5s ICsga2lkcy50b0RlYnVnU3RyKCkNCgkJCQkrIG5sICsgJCJUcnlpbmcgdG8gYWRkXG57a2lkc1Rv QWRkLnRvRGVidWdTdHIoKX1cbiINCgkJCQkrICQiaW4ge2NsYXNzTmFtZX0iKTsNCgkJCS8vIGlm IHRoZXJlIGlzIGFuIExEQlN0cnVjdHNDaGlsZHJlbiBhbmQgYW5vdGhlciBjaGlsZCwNCgkJCS8v IHRoaXMgd2lsbCBibG93IHVwIC0gd2lsbCBuZWVkIHRvIGRvIGtpZHMuQWRkIG9yDQoJCQkvLyBz b21ldGhpbmcgLSBpbiBmYWN0LCBraWRzIG5lZWRzIHRvIGJlIGNyZWF0ZWQgaW4gb25lDQoJCQkv LyBnbywgd2hpY2ggaXMgd2hhdCBoYXBwZW5zLg0KCQkJa2lkcyA9IGtpZHNUb0FkZDsgICAgLy8v Ly8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vIHdo eSB0aGlzPyB0b2RvDQoJCQlBcnJheS5Gb3JFYWNoKGtpZHNJbiwgeGtpZCA9PiBoYXJkTXVzdCgh KHhraWQua2lkIGlzIG51bGwpLCBsb2MsICJudWxsIGtpZCIpKTsNCgkJCUFycmF5LkZvckVhY2go a2lkc0luLCB4a2lkID0+IHhraWQua2lkLnNldE15UGFyZW50VG8odGhpcykpOw0KCQl9DQoNCg0K CQlwdWJsaWMgdmlydHVhbCB2b2lkIHNldFBhcmVudE9uS2lkc0FuZEFkZFRvS2lkc0RpY3QoDQoJ CQkJCXBhcmFtcyAoc3RyaW5nIGtpZE5hbWUsIExEQkFTVG9iaiBraWQpW10ga2lkc0luKSB7DQoJ CQl2YXIga2lkc1RvQWRkX2p1c3RGb3JFcnJSZXBvcnRpbmcgPSBuZXcgTERCU3RydWN0c0NoaWxk cmVuKHRoaXMsIGtpZHNJbik7DQoJCQloYXJkTXVzdDIoIWtpZHMuaXNFbXB0eSwgLy8gbWF5IGRp c2FibGUgdGhpcyBsYXRlciANCgkJCQkoKSA9Pg0KCQkJCSJhZGRpbmcgdG8ga2lkcyB3aGVuIGtp ZHMgaXMgZW1wdHksICINCgkJCQkgKyAkImtpZHMgaXNcbntraWRzLnRvRGVidWdTdHIoKX1cbiIN CgkJCQkgKyAkIlRyeWluZyB0byBhZGRcbntraWRzVG9BZGRfanVzdEZvckVyclJlcG9ydGluZy50 b0RlYnVnU3RyKCl9XG4iDQoJCQkJICsgJCJpbiB7Y2xhc3NOYW1lfSIpOw0KCQkJQXJyYXkuRm9y RWFjaChraWRzSW4sIHhraWQgPT4gew0KLy8JCQkJc2V0UGFyZW50T25LaWQoeGtpZC5raWQpOw0K CQkJCXhraWQua2lkLnNldE15UGFyZW50VG8odGhpcyk7DQoJCQkJa2lkcy5BZGQoeGtpZCk7DQoJ CQl9KTsNCgkJfQ0KDQoNCgkJcHVibGljIHZpcnR1YWwgSWRlbnRzVXNlZCBnZXRBbGxJRHMoKSB7 DQoJCS8qIFRoaXMgaXMgb3ZlcnJpZGRlbiBvbmx5IGluIFRlbXBsYXRlZEFnZywgYW5kIHRoYXQn cyBvbmx5IHRvIA0KCQkJZGVsaWJlcmF0ZWx5IGZhaWwuIFRoZXJlJ3Mgc29tZXRoaW5nIHdyb25n IHRoZXJlLCB0b2RvIC0gDQoJCQl1bi12aXJ0dWFsaXNlIHRoaXMgYW5kIHJlbW92ZSB0aGUgb25l IG92ZXJyaWRlLiAtIHRvZG8NCgkJKi8NCgkJCXZhciBpdSA9IG5ldyBJZGVudHNVc2VkKCk7DQoJ CQl0aGlzLl9nZXRBbGxJRHMoaXUpOw0KCQkJcmV0dXJuIGl1Ow0KCQl9DQoNCgkJcHVibGljIHZp cnR1YWwgdm9pZCBfZ2V0QWxsSURzKElkZW50c1VzZWQgaXUpIHsNCgkJLy8gR2V0cyBhbGwgdGhl IGlkZW50aWZpZXJzIGV4cGxpY2l0bHkgdXNlZCAocmVhZCBvciB3cml0dGVuKSAgLS0tLS0gdG9k byB1cGRhdGUgdGhpcw0KCQkvLyBhbnl3aGVyZSBpbiB0aGUgQVNULiAgRG9lcyBub3QgZ2V0IGlk ZW50cyB3aGljaCBhcmUNCgkJLy8gZGVjbGFyYXRpb25zIGllLiBwYXJhbWV0ZXJzLCBvciB2YXIv Y29uc3QgZGVjbGFyYXRpb25zDQoJCS8vIHVubGVzcyB0aGVzZSBhcmUgY29tYmluZWQgd2l0aCBh biBhc3NpZ25tZW50Lg0KCQkvLw0KCQkvLyBJbXBsaWVkIGlkZW50cyBzdWNoIGFzIHRob3NlIGZy b20gdGJsLiogYXJlIGltcGxpY2l0IGFuZCBpZ25vcmVkLg0KCQkvLw0KCQkvLyBSb290IGNhbGxl ciBzdXBwbGllcyBuZXcsIGVtcHR5IGl1DQoJCS8vIG5lZWQgdXNhZ2UgaGVyZSAtIHRvZG8gZG9j cy8vDQoJCQlraWRzLl9nZXRBbGxJRHMoaXUpOw0KCQl9DQoNCgkJcHVibGljIGFic3RyYWN0IGJv b2wgY2FuR2V0QWxsSWRlbnRzVXNlZCB7DQoJCS8vIAlUaGlzIHNlZW1zIHRvIGJlIHRydWUgb24g bW9zdCBjbGFzc2VzIHNvIEkgY291bGQgc2V0IHRydWUgDQoJCS8vIGFzIGEgZGVmYXVsdCBoZXJl IGFuZCBvdmVycmlkZSBpdCB3aGVyZSBpdCdzIG5vdCB3YW50ZWQsIHNhdmluZyANCgkJLy8gYSBj aHVuayBvZiBjb2RlLCBidXQgSSdkIHJhdGhlciBtYWtlIGl0IGV4cGxpY2l0IHRvIGZvcmNlIG1l IHRvIGNvbnNpZGVyIGVhY2ggY2FzZS4gQSBiaXQgbW9yZSBDJlAgZm9yIGxlc3MgY2hhbmNlIG9m IGJ1Z3MuDQoJCQlnZXQ7DQoJCX0NCg0KDQoJCS8vIFByb2R1Y2VzIGEgc3RyaW5nIHRoYXQgc2hv dWxkIGJlIGlkZW50aWNhbCB0byAoZXhjZXB0aW5nDQoJCS8vIHdoaXRlc3BhY2VzKSB0aGUgaW5w dXQgaWUuIGVtaXQgTERCIGNvZGUgbm90IHZhbGlkIFNRTA0KCQkvLw0KCQkvLyBUb1N0cmluZyB3 YXMgY2F1c2luZyB0b28gbWFueSB3ZWlyZCBwcm9ibGVtcyAoZHVlIHRvIG15DQoJCS8vIGluZXhw ZXJpZW5jZSB3aXRoIGMjKSBzbyBqdXN0IHVzZWQgdG9SYXdTdHIoKQ0KCQlwdWJsaWMgYWJzdHJh Y3Qgc3RyaW5nIHRvUmF3U3RyKCk7DQoNCgkJcHVibGljIG92ZXJyaWRlIHN0cmluZyB0b0RlYnVn U3RyKCkgPT4gdG9SYXdTdHIoKTsNCg0KCX0gLy8gZW5kIExEQkFTVG9iag0KDQoNCg0KCXB1Ymxp YyBpbnRlcmZhY2UgSWhhbmRsZVByZWZpeGVzPFQ+DQoJCQkJCQl3aGVyZSBUIDogTERCUm9vdCB7 DQoNCgkJcHVibGljIGJvb2wgaXNQcmVmaXhlZCB7IGdldDsgfQ0KDQoJCXB1YmxpYyBib29sIGlz RXhjZXNzUHJlZml4ZWQgeyBnZXQ7IH0NCg0KCQkvLyBUaGUgVCBpbiBhZGRQcmVmaXgvcmVQcmVm aXgvd2l0aG91dFByZWZpeCBpcyBiZWNhdXNlIHdlIG1heSBiZSANCgkJLy8gcmV0dXJuaW5nIGVn LiBhIGxpc3Qgb2YgaXRlbXMgd2l0aCBwcmVmaXhlcyANCgkJLy8gdGh1cyBtb2RpZmllZCwgbm90 IGEgc2luZ2xlIFBNUUlkZW50DQoNCgkJcHVibGljIFQgYWRkUHJlZml4KFBNUUlkZW50IHBmeCk7 DQoNCgkJcHVibGljIFQgcmVQcmVmaXgoUE1RSWRlbnQgbmV3cGZ4KTsNCg0KLy8JCXB1YmxpYyBU IHN0cmlwUHJlZml4KFBNUUlkZW50IGlkKTsNCgl9DQoJLy8gdG9kbyAtIG1vdmUgdGhpcw0KDQoN Cg0KDQoNCglwdWJsaWMgYWJzdHJhY3QgY2xhc3MgTERCUm9vdCB7DQoJCS8vIFJvb3Qgb2YgZXZl cnl0aGluZyBMREItaXNoDQoNCgkJcHVibGljIGJvb2wgRXF1YWxzKFtBbGxvd051bGxdIExEQlJv b3Qgb3RoZXIpIHsNCgkJCXRocm93IG5ldyBMREJTaG91bGROb3RCZUltcGxlbWVudGVkRXhjZXB0 aW9uKA0KCQkJCQkJCQkJImNhbGxlZCBFcXVhbHMgb24gTERCUm9vdCIpOw0KCQl9DQoNCgkJcHVi bGljIG92ZXJyaWRlDQoJCQlib29sIEVxdWFscyhbQWxsb3dOdWxsXSBPYmplY3Qgb3RoZXIpIHsN CgkJCXRocm93IG5ldyBMREJTaG91bGROb3RCZUltcGxlbWVudGVkRXhjZXB0aW9uKA0KCQkJCQkJ CQkJImNhbGxlZCBFcXVhbHMgaW4gT2JqZWN0Iik7DQoJCX0NCg0KCQlwdWJsaWMgb3ZlcnJpZGUg aW50IEdldEhhc2hDb2RlKCkgew0KCQkJdGhyb3cgbmV3IExEQlNob3VsZE5vdEJlSW1wbGVtZW50 ZWRFeGNlcHRpb24oDQoJCQkJCQkJCQkiY2FsbGVkIEdldEhhc2hDb2RlIGluIExEQlJvb3QiKTsN CgkJfQ0KDQoJCXB1YmxpYyBzdGF0aWMgYm9vbCBvcGVyYXRvciA9PShMREJSb290IGxocywNCgkJ CQkJCQkJCSAgIExEQlJvb3QgcmhzKSB7DQoJCQl0aHJvdyBuZXcgTERCU2hvdWxkTm90QmVJbXBs ZW1lbnRlZEV4Y2VwdGlvbigNCgkJCQkJCQkJCSJjYWxsZWQgPT0gaW4gTERCUm9vdCIpOw0KCQl9 DQoNCgkJcHVibGljIHN0YXRpYyBib29sIG9wZXJhdG9yICE9KExEQlJvb3QgbGhzLA0KCQkJCQkJ CQkJICAgTERCUm9vdCByaHMpIHsNCgkJCXRocm93IG5ldyBMREJTaG91bGROb3RCZUltcGxlbWVu dGVkRXhjZXB0aW9uKA0KCQkJCQkJCQkJImNhbGxlZCAhPSBpbiBMREJSb290Iik7DQoJCX0NCg0K DQoJCXB1YmxpYyB2aXJ0dWFsIHN0cmluZyBjbGFzc05hbWUgew0KCQkJLy8gdG9kbyAtIHRoaXMg bmVlZHMgY2hlY2tpbmcgaXQgd29ya3MgYXMgSSB3YW50DQoJCQkvLyBhbHNvIHJlbmFtZSB0byBs ZGJjbGFzc25hbWUgLS0gdG9kbw0KCQkJZ2V0ID0+IHRoaXMuR2V0VHlwZSgpLkZ1bGxOYW1lID8/ ICIodW5rbm93bikiOw0KCQl9DQoNCg0KCQlwdWJsaWMgdmlydHVhbCBzdHJpbmcgY2xhc3NOYW1l USA9Pg0KCQkJIiciICsgY2xhc3NOYW1lICsgIiciOw0KDQoNCgkJcHVibGljIHZpcnR1YWwgc3Ry aW5nIGNsYXNzTmFtZVBsdXMoc3RyaW5nIHBsdXMpID0+DQoJCQljbGFzc05hbWUgKyAiLiIgKyBw bHVzOw0KDQoJCXB1YmxpYyBvdmVycmlkZSBzdHJpbmcgVG9TdHJpbmcoKSB7DQoJCQkvLyBUaGlz IGltcGxpY2l0IHRvLXN0cmluZyBjb252ZXJzaW9uIGNyYXAgY29zdCBtZSBhIGZldyBob3Vycywg c28gYXQgbGVhc3QNCgkJCS8vIGRvIHRoaXMgJiBibG93IHVwIGF0IHJ1bnRpbWUuIFdvdWxkIHBy ZWZlciBjb21waWxlIHRpbWUgYnV0IGl0IHNlZW1zDQoJCQkvLyBub3QgcG9zc2libGUuICBUaGlz IHR1cm5zIG91dCB0byBoYXZlIGJlZW4gYSBnb29kIGlkZWEsDQoJCQkvLyBzYXZlZCBtZSBxdWl0 ZSBhIGJpdCBtb3JlIGRlYnVnZ2luZyENCgkJCS8vIDxodHRwczovL3N0YWNrb3ZlcmZsb3cuY29t L3F1ZXN0aW9ucy8xNTM0NTUxNy9pcy1pdC1wb3NzaWJsZS10by1kaXNhYmxlLWltcGxpY2l0LXRv c3RyaW5nLWNhbGw+DQoJCQkvLyBXaWxsIHRyeSA8aHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9x dWVzdGlvbnMvNTQzNTQzNDIvaG93LXRvLWdldC1hbi1lcnJvci1zaG93bi13aGVuLXVzaW5nLW5v bi1zdHJpbmdzLWFzLXN0cmluZ3MtaW5zdGVhZC1vZi1hbi1hdXRvbS81NDM1NTExNSM1NDM1NTEx NSkNCgkJCXZhciBtc2cgPSAiTERCUm9vdC5Ub1N0cmluZygpIjsNCgkJCXRocm93IG5ldyBMREJU b1N0cmluZ0ltcGxpY3RDb252ZXJzaW9uRXhjZXB0aW9uKG1zZyk7DQoJCX0NCg0KCQlwdWJsaWMg YWJzdHJhY3Qgc3RyaW5nIHRvRGVidWdTdHIoKTsNCgl9DQoNCg0KDQoJcHVibGljIGFic3RyYWN0 IGNsYXNzIEVwaGVtZXJhbCA6IExEQlJvb3Qgew0KCQkvLyBmb3Igb2JqZWN0cyB0aGF0IGFyZSBu b3QgcGFydCBvZiB0aGUgQVNUDQoJfQ0KDQoNCg0KCXB1YmxpYyBpbnRlcmZhY2UgSVdpdGhMaW5l TlVtIHsgIC8vIHRvZG8gLSB1c2Ugb3IgcmVtb3ZlIC0gdG9kbw0KCQkvLwlwdWJsaWMgDQoJfQ0K DQoNCglwdWJsaWMgaW50ZXJmYWNlIElIYXNUYWJsZUFsaWFzIHsNCgkJLy8gSGFzIGEgdGFibGUg YWxpYXMgQVNUIG9iai4gTWF5IGJlIGEgLi4uTWlzc2luZyBzdWJ0eXBlIGluIHdoaWNoDQoJCS8v IGl0IGhhcyBubyBhbGlhcyBnaXZlbiBieSB0aGUgdXNlciwgYnV0IGFsaWFzIEFTVCBpcyB0aGVy ZS4gTW9yZQ0KCQkvLyBhY2N1cmF0ZWx5IGEgVGFibGVTb3VyY2UgYWxpYXMgYnV0IG9rDQoJCXB1 YmxpYyBhYnN0cmFjdCBUYWJsZUFsaWFzIHRhIHsgZ2V0OyBzZXQ7IH0NCgl9DQoNCg0KCS8vIEJh c2UgY2xhc3MgZm9yIGFsbCBMREIgQVNUIG9iamVjdHMNCglwdWJsaWMgYWJzdHJhY3QgY2xhc3Mg TERCQVNUb2JqIDogTERCUm9vdCB7DQoJCS8vIFRoaXMgb25lIGlzIGEgcHJvYmxlbS4gSWYgSSBk ZWNsYXJlIHRoZSAncGFyZW50JyBwcm9wZXJ0eQ0KCQkvLyBhYnN0cmFjdCBJIHRoZW4gaGF2ZSB0 byBpbXBsZW1lbnQgaXQgbGl0ZXJhbGx5IGh1bmRyZWRzIG9mDQoJCS8vIHRpbWVzIGluIHRoZSBk ZXJpdmVkIGNsYXNzZXMsIGFuZCBJIHJlYWxseSBkb24ndCB0aGluayBpdA0KCQkvLyB3b3VsZCBo ZWxwIHNvIGp1c3Qgc2V0IGl0IHRvIGEgZGVmYXVsdCB3aGljaCBnZXRzIG92ZXJ3cml0dGVuIGxh dGVyLg0KCQkvLyANCgkJLy8gVGhlIHByb2JsZW0gaXMgdGhhdCB0aG9zZSBvYmplY3RzIHdlcmUg Y3JlYXRlZCBieSB0aGUNCgkJLy8gcGFyc2VyLCB3aGljaCBjcmVhdGVzIHRoZW0gYm90dG9tLXVw LCB3aGljaCBtZWFucyB5b3UgY2FuJ3QNCgkJLy8ga25vdyB0aGUgcGFyZW50IHdoZW4gdGhleSBh cmUgY3JlYXRlZC4gSXQgc2hvdWxkIGJlDQoJCS8vIHBvc3NpYmxlIHRvIHdvcmsgYXJvdW5kIHRo aXMgYnV0IGl0IGRvZXMgbWVhbiByZXdvcmtpbmcgdGhlDQoJCS8vIHBhcnNlciBmdW5kYW1lbnRh bGx5LCBhbmQgSSdtIG5vdCBnb2luZyB0byBkbyB0aGF0DQoJCS8vIGFzc3VtZWluZyBpdCdzIGV2 ZW4gcG9zc2libGUuDQoNCgkJLy8gdG9kbyAtIHJlYWQgdXAgb24gcHJpdi9wdWIvcHJvZyBhY2Nl c3NvcnMgSSByZWFsbHkgZG9uJ3QNCgkJLy8gZ2V0IHRoZXNlIGF0IGFsbA0KCQlwdWJsaWMgTERC QVNUb2JqIHBhcmVudCB7IGdldDsgcHJpdmF0ZSBzZXQ7IH0NCgkJCQkJCT0gbm9QYXJlbnQ7DQoJ CS8vIFVuaXF1ZSBJRCBwZXIgb2JqZWN0LCB1c2VmdWwgZm9yIGRpc3Rpbmd1aXNoaW5nIHRoZW0N CgkJLy8gd2l0aG91dCBnZW5lcmFsIGVxdWFsaXR5Lg0KCQlyZWFkb25seSBwdWJsaWMgdWxvbmcg dWlkID0gbmV3VUlEKCk7DQoNCgkJLy8gcHVibGljIGFic3RyYWN0IGludCBsaW5lTnVtIHsgZ2V0 OyBzZXQ7IH0NCg0KCQkvLyBJcyB2YWxpZGF0ZWQgaXMgYSBjaGVhcGlzaCBjaGVjayB0byBlbnN1 cmUgZXZlcnl0aGluZyBnZXRzDQoJCS8vIHZhbGlkYXRlZA0KCQkvLyBjYW4gZG8gdGhpcyBhcyBh dXRvIHByb3A/IHRvZG8NCgkJcHJpdmF0ZSBib29sIF92YWxpZGF0ZWQgPSBmYWxzZTsNCg0KCQlw cm90ZWN0ZWQgYm9vbCB2YWxpZGF0ZWQgew0KCQkJZ2V0ID0+IF92YWxpZGF0ZWQ7DQoJCQlzZXQg ew0KCQkJCS8vIGhhcmRNdXN0KCF2YWxpZGF0ZWQsICIuLi4gYWxyZWFkeSB2YWxpZGF0ZWQuLi4g Iik7IC0gbm8NCgkJCQkvLyBJdCdzIGhhcmQgdG8gYXZvaWQgdmFsaWRhdGluZyBhIHRoaW5nIHR3 aWNlLCBzbyBmb3Igbm93IGFsbG93IGl0DQoJCQkJLy8gTG9vayBpbnRvIGl0IGxhdGVyLCByZWFs bHkgc2hvdWxkbid0IGhhcHBlbg0KCQkJCV92YWxpZGF0ZWQgPSB0cnVlOw0KCQkJfQ0KCQl9DQoN CgkJcHVibGljIExEQlN0cnVjdHNDaGlsZHJlbiBraWRzIHsgZ2V0OyBwcml2YXRlIHNldDsgfSA9 DQoJCQkJCW5ldyBMREJTdHJ1Y3RzQ2hpbGRyZW4obm9QYXJlbnQpOyAvLyBqdXN0IGVhc2llcg0K DQoJCXB1YmxpYyBMREJBU1RvYmooKSB7ICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8v Ly8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vIHRvZG8gZGVhZD8NCgkJCQkJCQkgIC8v IFZTdHVkaW8gdGhpbmtzIHRoaXMgaGFzIHplcm8gcmVmZXJlbmNlcywgd2hpY2ggaXMgdHJ1ZSBl eHBsaWNpdGx5LCBidXQgaXQncyANCgkJCQkJCQkgIC8vIGNhbGxlZCBpbXBsaWNpdGx5IG9uIGV2 ZXJ5IG9iaiBjcmVhdGlvbiAtIG9yIHNob3VsZCBkbyB0b2RvLSBjaGVjaw0KCQkJaWYgKHJlY29y ZE9iamVjdHNDcmVhdGVkKSB7DQoJCQkJQWxsQ3JlYXRlZEl0ZW1zLkFkZCh0aGlzKTsNCgkJCX0N CgkJfQ0KDQoNCgkJcHVibGljIHZpcnR1YWwgdm9pZCB2YWxpZGF0ZSgpIHsNCgkJCWlmIChyZXBv cnRBbHNvSWZWYWxpZGF0aW9uT0spIHsNCgkJCQlkZWJ1Z21zZygidmFsaWRhdGluZy4uLiIgKyBj bGFzc05hbWUNCgkJCQkJKyAiICgiICsgYXNOYW1lT3JJZGVudENvbnRlbnRzKCkgKyAiKSIpOw0K CQkJfQ0KCQkJbWhwX21oaygpOw0KCQkJa2lkcy52YWxpZGF0ZSgpOw0KCQkJLy8gdmFsaWRhdGVk ID0gdHJ1ZTsgLS0gTm8sIGdldCBlYWNoIHN1YmNsYXNzIHRvIHNldA0KCQkJLy8gdmFsaWRhdGVk LiBUaGF0IGZvcmNlcyBhbiBleHBsaWNpdCBjYWxsIHRvIGJhc2UoKSB3aGljaA0KCQkJLy8gaXMg bW9yZSBjb2RlIGJ1dCBvay4NCgkJfQ0KDQoNCgkJcHVibGljIGJvb2wgaXNWYWxpZGF0ZWQgeyBn ZXQgPT4gdmFsaWRhdGVkOyB9ICAvLyB0b2RvIGp1c3QgPT4gdmFsaWRhdGVkOw0KDQoNCgkJcHVi bGljIHZpcnR1YWwgYm9vbCBpc1RvcExldmVsSXRlbVNlcSA9PiBmYWxzZTsNCg0KDQoJCXB1Ymxp YyB2aXJ0dWFsIHZvaWQgbWhwX21oaygpIHsgIC8vIGRvbid0IHRoaW5rIHRoaXMgbmVlZCBiZSB2 aXJ0dWFsIC0gdG9kbz8NCgkJCQkJCQkJCQkgLy8gPSBtdXN0IGhhdmUgcGFyZW50LCBtdXN0IGhh dmUga2lkcy4gVGhlIGtpZHMgbWF5IGJlIHRoZQ0KCQkJCQkJCQkJCSAvLyBlbXB0eSBzZXQgYW5k IHRoZSBwYXJlbnQgbWF5IGJlIG5vUGFyZW50IGJ1dCB0aGV5IG11c3QNCgkJCQkJCQkJCQkgLy8g ZXhpc3QuDQoJCQkJCQkJCQkJIC8vIFdoeSBub3QganVzdCBpbmxpbmUgdGhpcyBpbnRvIHZhbGlk YXRlKCk/DQoJCQkJCQkJCQkJIC8vIEJlY2F1c2UgYSBmZXcgY2xhc3NlcyBuZWVkIGJlc3Bva2Ug dmFsaWRhdGlvbiwgYnV0IHN0aWxsIG11c3QgY2hlY2sgdGhpcy4NCgkJCWhhcmRNdXN0UGFyZW50 SXNQcmVzZW50KCk7DQoJCQlraWRzLmVhY2hLaWRQYXJlbnRNdXN0QmUodGhpcyk7DQoJCX0NCg0K DQoJCXB1YmxpYyBzdHJpbmcgYXNOYW1lT3JJZGVudENvbnRlbnRzKCkgew0KCQkJLy8gZm9yIHZl cnkgY3J1ZGUgZGVidWdnaW5nIA0KCQkJdmFyIG9wdE5hbWUgPSB0aGlzIGlzIElpc05hbWVkSXRl bSBuaSA/IG5pLm5hbWUudG9SYXdTdHIoKSA6ICIiOw0KCQkJb3B0TmFtZSA9IChvcHROYW1lID09 ICIiICYmIHRoaXMgaXMgUE1RSWRlbnQpID8gdGhpcy50b1Jhd1N0cigpIDogIiI7DQoNCgkJCXZh ciBvcHROYW1lMiA9IG9wdE5hbWUgKyAiICAodWlkOiIgKyB1aWQuVG9TdHJpbmcoKSArICIpICIN CgkJCQkrIGdldEZpcnN0RmV3Q2hhcnNPZih0b1Jhd1N0cigpKTsNCgkJCXJldHVybiBvcHROYW1l MjsNCgkJfQ0KDQoNCgkJcHVibGljIHZpcnR1YWwgdm9pZCBnZXRBbGxVSURzKFVJRHNldCB1aWRz KSB7DQoJCQl1aWRzLkFkZCh0aGlzKTsNCgkJCWtpZHMuRm9yRWFjaChuYW1lZEtpZCA9PiBuYW1l ZEtpZC5raWQuZ2V0QWxsVUlEcyh1aWRzKSk7DQoJCX0NCg0KDQoJCXB1YmxpYyBib29sIGlzU3R1 YlBhcmVudCB7IGdldCA9PiAodGhpcyBpcyBOb1BhcmVudCkgfHwgKHRoaXMgaXMgRmFrZVBhcmVu dCk7IH0NCg0KDQoJCXB1YmxpYyB2b2lkIHZhbGlkYXRlU3BlY2lmaWNJdGVtcyhwYXJhbXMgTERC QVNUb2JqW10gaXRlbXMpIHsNCgkJCUFycmF5LkZvckVhY2goaXRlbXMsIGl0ZW0gPT4gaXRlbS52 YWxpZGF0ZSgpKTsNCgkJfQ0KDQoNCgkJcHVibGljIFQ/IG9wdENsaW1iVG88VD4oKSB3aGVyZSBU IDogTERCQVNUb2JqIHsNCgkJCXZhciByZXNJdGVtID0gdGhpczsNCgkJCXdoaWxlICghKHJlc0l0 ZW0gaXMgVCkpIHsNCgkJCQlpZiAocmVzSXRlbS5wYXJlbnQuaXNTdHViUGFyZW50KSB7DQoJCQkJ CXJldHVybiBudWxsOw0KCQkJCX0NCgkJCQlyZXNJdGVtID0gcmVzSXRlbS5wYXJlbnQ7DQoJCQl9 DQoNCgkJCXZhciByZXMgPSByZXNJdGVtIGFzIFQ7DQoJCQlyZXR1cm4gcmVzOw0KCQl9DQoNCg0K CQlwdWJsaWMgVCByZXFDbGltYlRvPFQ+KCkgd2hlcmUgVCA6IExEQkFTVG9iaiB7DQoJCQl2YXIg bG9jID0gY2xhc3NOYW1lICsgIi5yZXFDbGltYlRvPFQ+KCkiOw0KCQkJdmFyIHJlcyA9IG9wdENs aW1iVG88VD4oKTsNCgkJCWhhcmRNdXN0MighKHJlcyBpcyBudWxsKSwgDQoJCQkJLy8gVGhhbmtz IFNPIDxodHRwczovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy8yNTgxNjQyL2hvdy1kby1p LWdldC10aGUtdHlwZS1uYW1lLW9mLWEtZ2VuZXJpYy10eXBlLWFyZ3VtZW50Pg0KCQkJCS8vIFRv ZG8gLSB1c2UgdGhpcyBlbHNld2hlcmUsIHBvc3MgRXhwZWN0RXhjZXB0aW9uPyB0b2RvDQoJCQkJ KCkgPT4NCgkJCQlsb2MgDQoJCQkJKyBubCArICIsIGNsaW1iZWQgdG8gdG9wLCBkaWRuJ3QgZmlu ZCB0eXBlICINCgkJCQkrIHR5cGVvZihUKS5GdWxsTmFtZQ0KCQkJCSsgbmwgKyAiSGllcmFyY2h5 IGlzOiAiDQoJCQkJKyBubCArIGdldEl0ZW1XaXRoUGFyZW50cyh0aGlzKSk7DQoJCQlpZiAocmVz IGlzIG51bGwpIHsgdGhyb3cgbmV3IE5OUUMoKTsgfQ0KCQkJcmV0dXJuIHJlczsNCgkJfQ0KDQoN CgkJcHVibGljIHZvaWQgaGFyZE11c3RQYXJlbnRJc1ByZXNlbnQoKSB7DQoNCgkJCWhhcmRNdXN0 MighKHBhcmVudCBpcyBudWxsKSwgDQoJCQkJKCkgPT4NCgkJCQkgIk5VTEwgcGFyZW50IGZvciBp dGVtIG9mIHR5cGVcbiINCgkJCQkgKyAkIntHZXRUeXBlKCl9XG4uIik7DQoNCgkJCWhhcmRNdXN0 MighKHRoaXMucGFyZW50IGlzIE5vUGFyZW50KSwNCgkJCQkoKSA9Pg0KCQkJCSJQYXJlbnQgaXMg Tm9QYXJlbnQgb24gb2JqZWN0IG9mIHR5cGVcbiINCgkJCQkrICQiJ3t0aGlzLmNsYXNzTmFtZX0n Iik7DQoJCX0NCg0KDQoJCXB1YmxpYyB2b2lkIGhhcmRNdXN0UGFyZW50SXNBYnNlbnQoKSB7DQoJ CQkvLyBGb3IgY2hlY2tpbmcgY2xvbmluZyAtIHBhcmVudCBzaG91bGQgYmUgTm9QYXJlbnQgaW1t ZWRpYXRlbHkgDQoJCQkvLyBhZnRlciwgYmVmb3JlIGl0J3Mgc2V0IGJ5IHBhcmVudCwgYW5kIG5l dmVyIG51bGwNCgkJCWhhcmRNdXN0KCEocGFyZW50IGlzIG51bGwpLA0KCQkJCSAiTlVMTCBwYXJl bnQgZm9yIGl0ZW0gb2YgdHlwZVxuIg0KCQkJCSArICQie0dldFR5cGUoKX1cbi4iKTsNCgkJCWhh cmRNdXN0KCh0aGlzLnBhcmVudCBpcyBOb1BhcmVudCksDQoJCQkJIlBhcmVudCBzaG91bGQgYmUg Tm9QYXJlbnQgb24gb2JqZWN0IG9mIHR5cGVcbiINCgkJCQkrICQiJ3t0aGlzLmNsYXNzTmFtZX0n Iik7DQoJCX0NCg0KDQoJCXB1YmxpYyBib29sIGhhc1BhcmVudDxQPigpIHsNCgkJCWhhcmRNdXN0 KCEodGhpcyBpcyBOb1BhcmVudCksICJJdGVtIGlzIE5vUGFyZW50Iik7DQoJCQlyZXR1cm4gdGhp cy5wYXJlbnQgaXMgUDsNCgkJfQ0KDQoNCgkJcHVibGljIGJvb2wgaGFzQW5jZXN0b3I8QT4oKSB7 DQoJCQloYXJkTXVzdCghdGhpcy5pc1N0dWJQYXJlbnQsICJJdGVtIGlzIE5vUGFyZW50Iik7DQoN CgkJCS8vIGhvdyB0byBkbyB3aXRoIGEgc3dpdGNoIGV4cHI/DQoJCQlpZiAodGhpcy5wYXJlbnQu aXNTdHViUGFyZW50IC8qIGlzIE5vUGFyZW50IHx8IHRoaXMucGFyZW50IGlzIEZha2VQYXJlbnQq LyApIHsgLy8gdG9kbyBkbyBhcyB4Lmhhc0Z1ZGdlZFBhcmVudCgpIC0gdG9kbw0KCQkJCXJldHVy biBmYWxzZTsNCgkJCX0gZWxzZSBpZiAodGhpcy5wYXJlbnQgaXMgQSkgew0KCQkJCXJldHVybiB0 cnVlOw0KCQkJfSBlbHNlIHsNCgkJCQlyZXR1cm4gdGhpcy5wYXJlbnQuaGFzQW5jZXN0b3I8QT4o KTsNCgkJCX0NCgkJfQ0KDQoJCXB1YmxpYyBib29sIG5vdEhhc0FuY2VzdG9yPEE+KCkgPT4NCgkJ CSFoYXNBbmNlc3RvcjxBPigpOw0KDQoNCgkJcHVibGljIHZvaWQgc2V0TXlQYXJlbnRUbyhMREJB U1RvYmogcHJudCkgew0KCQkJLy8gQW4gb2JqZWN0IG1heSBvbmx5IHNldCBpdHMgcGFyZW50IGlm IGl0cyBjdXJyZW50IHBhcmVudCBpcw0KCQkJLy8gdGhlIGR1bW15ICdub1BhcmVudCcsIHdoaWNo IGFsbW9zdCBldmVyeSBvYmplY3QncyBwYXJlbnQgaXMNCgkJCS8vIHNldCB0byBvbiBjcmVhdGlv biAoc2VlIExEQkFTVG9iaiBwYXJlbnQgcHJvcGVydHkgZGVmKS4NCg0KCQkJLy8gVGhlIHRlc3Qg Zm9yIG51bGwgaXMgcGVjdWxpYXIgZ2l2ZW4gdGhpcy4gQmVjYXVzZQ0KCQkJLy8gbm9QYXJlbnQg aXMgY3JlYXRlZCBzdGF0aWNhbGx5LCBzZXR0aW5nIHRoZSBwYXJlbnQgb2YNCgkJCS8vIG5vUGFy ZW50IGlzIGRpZmZpY3VsdCwgcGVyaGFwcyBpbXBvc3NpYmxlLCB0byBkbyBzdGF0aWNhbGx5DQoJ CQkvLyBhbmQgcmVsaWFibHkuRGVzcGl0ZSB0aGUgZGVjbGFyYXRpb24gJyNudWxsYWJsZSBlbmFi bGUnLCBpdA0KCQkJLy8gZ2V0cyBjcmVhdGVkIHdpdGggYSBudWxsIHBhcnJlbnQgKHF1aXRlIHJl YXNvbmFibHkpLCBoZW5jZQ0KCQkJLy8gdGhpcyBjaGVjay5UaGUgYWN0dWFsIHNldHRpbmcgb2Yg dGhlIHBhcmVudCBoYXMgdG8gYmUgZG9uZQ0KCQkJLy8gYXQgcnVudGltZSBpLmUuYWZ0ZXIgdGhl IHN0YXRpYyBjcmVhdGlvbiBvZiAnbm9QYXJlbnQnLg0KDQoJCQloYXJkTXVzdDIoKHRoaXMucGFy ZW50IGlzIE5vUGFyZW50KSB8fCAodGhpcy5wYXJlbnQgaXMgbnVsbCksDQoJCQkJKCkgPT4NCgkJ CQkidHJpZWQgdG8gcmUtc2V0IHBhcmVudCBvbiBvYmplY3Qgb2YgdHlwZTogIg0KCQkJCSsgbmwg KyB0aGlzLmNsYXNzTmFtZVENCgkJCQkrIG5sICsgIk9yaWdpbmFsIHBhcmVudCB0eXBlIGlzOiAi DQoJCQkJKyAodGhpcz8ucGFyZW50Py5jbGFzc05hbWVRID09IG51bGwgPyAibnVsbCIgOiB0aGlz LnBhcmVudC5jbGFzc05hbWVRKQ0KCQkJCSsgbmwgKyAiYW5kIG5ldyBwYXJlbnQgdHlwZSBpczog Ig0KCQkJCSsgcHJudC5jbGFzc05hbWVRDQoJCQkJKyBubCArICJJdGVtIGhhdmluZyBwYXJlbnQg c2V0IG9uIGl0IGlzOiAiDQoJCQkJLy8gYmVjYXVzZSBvYmplY3QgbWF5IG5vdCBiZSBmdWxseSBj b25zdHJ1Y3RlZCB5ZXQsIGNoZWNrIGhvd3ZlciBUT0RPIHRoaXMgaXMgYSBtYWpvciBoYWNrIGFu ZCBtdXN0IGJlIGZpeGVkIHNvbWV0aW1lLg0KLy8JCQkJKyBubCArICh0aGlzIGlzIG51bGwgPyAi KG51bGwpIiA6IHRoaXMudG9SYXdTdHIoKSkpOw0KCQkJCSsgbmwgKyB0aGlzLnRvUmF3U3RyKCkg KTsNCg0KCQkJcGFyZW50ID0gcHJudDsNCgkJfQ0KDQoNCgkJcHVibGljIHZvaWQgZm9yY2VOZXdQ YXJlbnRGb3JSb290T2JqZWN0KCkgew0KCQkJLy8gRXZlcnkgb2JqZWN0IG11c3QgaGF2ZSBzb21l IHBhcmVudCwgaW5jbHVkaW5nIHRoZQ0KCQkJLy8gcm9vdCBvYmplY3Qgb2YgdGhlIHBhcnNlLCB3 aGljaCBpcyBMREJpdGVtcw0KCQkJLy8gKGEgc2VxdWVuY2Ugb2YgTERCIGl0ZW1zKSwgc28gdGhp cyBmb3JjZXMgb25lLg0KCQkJLy8gSXQgaXMgb25seSBmb3IgdGhhdCBwdXJwb3NlIQ0KCQkJLy8g DQoJCQkvLyBMREJpdGVtcyBvYmogZXhpc3RzIGZvciBzdWIgb2JqcyBzdWNoIGFzIHRoZSBzdGF0 ZW1lbnRzDQoJCQkvLyBpbiBhIHdoaWxlIGxvb3AsIGluIGEgcHJvYywgaW4gYW4gaWYuLi4gZXRj LiwgZm9yDQoJCQkvLyB3aGljaCB0aGVpciBwYXJlbnQgaXMgdGhlIHdoaWxlL3Byb2MvaWYgZXRj Lg0KCQkJaGFyZE11c3RQYXJlbnRJc0Fic2VudCgpOw0KCQkJdGhpcy5wYXJlbnQgPSBmYWtlUGFy ZW50Ow0KCQl9DQoNCg0KCQkvL3B1YmxpYyB2b2lkIHJlc2V0TXlQYXJlbnRUbyhMREJBU1RvYmog cHJudCkgeyAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLyBkZXN0cm95ISEhISEh IHRvZG8NCgkJLy8JcGFyZW50ID0gcHJudDsNCgkJLy99DQoNCgkJLy8vLy8vLy8vLy8vLy8vLy8v Ly8vLy8vIHh4eHh4eHh4eHh4eHggZGVsZXRlIC0gdG9kbw0KCQkvL3ByaXZhdGUgdm9pZCBzZXRQ YXJlbnRPbktpZChMREJBU1RvYmoga2lkKSA9PiAvLyB0b2RvIG5lZWRlZD8NCgkJLy8JCQkJCQkJ CQkJCSAgLy8gY2hlY2sgcGFyZW50ZSBkb2Vzbid0IGV4aXN0IC0gdG9kbw0KCQkvLwlraWQucGFy ZW50ID0gdGhpczsNCg0KCQlwdWJsaWMgdmlydHVhbCB2b2lkIHNldFBhcmVudE9uS2lkc0FuZE1h a2VLaWRzRGljdCggIC8vIHRvZG8gLSBhbmQgYWRkIHRvIGtpZHMgZGljdA0KCQkJCQkJCQkJCQkJ CQkJIC8vIHRoaXMgbWl4ZXMgdXAgc2V0dGluZyBwYXJlbnQgYW5kIG1ha2luZyBjaGlsZCBkaWN0 LiBOb3QgZ29vZC4gLSB0b2RvDQoJCQkJCQlwYXJhbXMgKHN0cmluZyBraWROYW1lLCBMREJBU1Rv Ymoga2lkKVtdIGtpZHNJbikgew0KCQkJdmFyIGxvYyA9IGNsYXNzTmFtZVBsdXMoInNldFBhcmVu dE9uS2lkc0FuZE1ha2VLaWRzRGljdCIpOw0KDQoJCQl2YXIga2lkc1RvQWRkID0gbmV3IExEQlN0 cnVjdHNDaGlsZHJlbih0aGlzLCBraWRzSW4pOw0KCQkJaGFyZE11c3QyKGtpZHMuaXNFbXB0eSwN CgkJCQkoKSA9Pg0KCQkJCSQic2V0dGluZyBraWRzIG9uIHBhcmVudCAne2NsYXNzTmFtZX0nIiAN CgkJCQkrICJ3aGVuIGtpZHMgaXMgbm90IGVtcHR5LCAiDQoJCQkJKyAkImtpZHMgaXMgKHtraWRz LkNvdW50fSBraWRzKToiDQoJCQkJKyBubCArIGtpZHMudG9EZWJ1Z1N0cigpDQoJCQkJKyBubCAr ICQiVHJ5aW5nIHRvIGFkZFxue2tpZHNUb0FkZC50b0RlYnVnU3RyKCl9XG4iDQoJCQkJKyAkImlu IHtjbGFzc05hbWV9Iik7DQoJCQkvLyBpZiB0aGVyZSBpcyBhbiBMREJTdHJ1Y3RzQ2hpbGRyZW4g YW5kIGFub3RoZXIgY2hpbGQsDQoJCQkvLyB0aGlzIHdpbGwgYmxvdyB1cCAtIHdpbGwgbmVlZCB0 byBkbyBraWRzLkFkZCBvcg0KCQkJLy8gc29tZXRoaW5nIC0gaW4gZmFjdCwga2lkcyBuZWVkcyB0 byBiZSBjcmVhdGVkIGluIG9uZQ0KCQkJLy8gZ28sIHdoaWNoIGlzIHdoYXQgaGFwcGVucy4NCgkJ CWtpZHMgPSBraWRzVG9BZGQ7ICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8v Ly8vLy8vLy8vLy8vLy8vLy8vLy8vLyB3aHkgdGhpcz8gdG9kbw0KCQkJQXJyYXkuRm9yRWFjaChr aWRzSW4sIHhraWQgPT4gaGFyZE11c3QoISh4a2lkLmtpZCBpcyBudWxsKSwgbG9jLCAibnVsbCBr aWQiKSk7DQoJCQlBcnJheS5Gb3JFYWNoKGtpZHNJbiwgeGtpZCA9PiB4a2lkLmtpZC5zZXRNeVBh cmVudFRvKHRoaXMpKTsNCgkJfQ0KDQoNCgkJcHVibGljIHZpcnR1YWwgdm9pZCBzZXRQYXJlbnRP bktpZHNBbmRBZGRUb0tpZHNEaWN0KA0KCQkJCQlwYXJhbXMgKHN0cmluZyBraWROYW1lLCBMREJB U1RvYmoga2lkKVtdIGtpZHNJbikgew0KCQkJdmFyIGtpZHNUb0FkZF9qdXN0Rm9yRXJyUmVwb3J0 aW5nID0gbmV3IExEQlN0cnVjdHNDaGlsZHJlbih0aGlzLCBraWRzSW4pOw0KCQkJaGFyZE11c3Qy KCFraWRzLmlzRW1wdHksIC8vIG1heSBkaXNhYmxlIHRoaXMgbGF0ZXIgDQoJCQkJKCkgPT4NCgkJ CQkiYWRkaW5nIHRvIGtpZHMgd2hlbiBraWRzIGlzIGVtcHR5LCAiDQoJCQkJICsgJCJraWRzIGlz XG57a2lkcy50b0RlYnVnU3RyKCl9XG4iDQoJCQkJICsgJCJUcnlpbmcgdG8gYWRkXG57a2lkc1Rv QWRkX2p1c3RGb3JFcnJSZXBvcnRpbmcudG9EZWJ1Z1N0cigpfVxuIg0KCQkJCSArICQiaW4ge2Ns YXNzTmFtZX0iKTsNCgkJCUFycmF5LkZvckVhY2goa2lkc0luLCB4a2lkID0+IHsNCi8vCQkJCXNl dFBhcmVudE9uS2lkKHhraWQua2lkKTsNCgkJCQl4a2lkLmtpZC5zZXRNeVBhcmVudFRvKHRoaXMp Ow0KCQkJCWtpZHMuQWRkKHhraWQpOw0KCQkJfSk7DQoJCX0NCg0KDQoJCXB1YmxpYyB2aXJ0dWFs IElkZW50c1VzZWQgZ2V0QWxsSURzKCkgew0KCQkvKiBUaGlzIGlzIG92ZXJyaWRkZW4gb25seSBp biBUZW1wbGF0ZWRBZ2csIGFuZCB0aGF0J3Mgb25seSB0byANCgkJCWRlbGliZXJhdGVseSBmYWls LiBUaGVyZSdzIHNvbWV0aGluZyB3cm9uZyB0aGVyZSwgdG9kbyAtIA0KCQkJdW4tdmlydHVhbGlz ZSB0aGlzIGFuZCByZW1vdmUgdGhlIG9uZSBvdmVycmlkZS4gLSB0b2RvDQoJCSovDQoJCQl2YXIg aXUgPSBuZXcgSWRlbnRzVXNlZCgpOw0KCQkJdGhpcy5fZ2V0QWxsSURzKGl1KTsNCgkJCXJldHVy biBpdTsNCgkJfQ0KDQoJCXB1YmxpYyB2aXJ0dWFsIHZvaWQgX2dldEFsbElEcyhJZGVudHNVc2Vk IGl1KSB7DQoJCS8vIEdldHMgYWxsIHRoZSBpZGVudGlmaWVycyBleHBsaWNpdGx5IHVzZWQgKHJl YWQgb3Igd3JpdHRlbikgIC0tLS0tIHRvZG8gdXBkYXRlIHRoaXMNCgkJLy8gYW55d2hlcmUgaW4g dGhlIEFTVC4gIERvZXMgbm90IGdldCBpZGVudHMgd2hpY2ggYXJlDQoJCS8vIGRlY2xhcmF0aW9u cyBpZS4gcGFyYW1ldGVycywgb3IgdmFyL2NvbnN0IGRlY2xhcmF0aW9ucw0KCQkvLyB1bmxlc3Mg dGhlc2UgYXJlIGNvbWJpbmVkIHdpdGggYW4gYXNzaWdubWVudC4NCgkJLy8NCgkJLy8gSW1wbGll ZCBpZGVudHMgc3VjaCBhcyB0aG9zZSBmcm9tIHRibC4qIGFyZSBpbXBsaWNpdCBhbmQgaWdub3Jl ZC4NCgkJLy8NCgkJLy8gUm9vdCBjYWxsZXIgc3VwcGxpZXMgbmV3LCBlbXB0eSBpdQ0KCQkvLyBu ZWVkIHVzYWdlIGhlcmUgLSB0b2RvIGRvY3MvLw0KCQkJa2lkcy5fZ2V0QWxsSURzKGl1KTsNCgkJ fQ0KDQoJCXB1YmxpYyBhYnN0cmFjdCBib29sIGNhbkdldEFsbElkZW50c1VzZWQgew0KCQkvLyAJ VGhpcyBzZWVtcyB0byBiZSB0cnVlIG9uIG1vc3QgY2xhc3NlcyBzbyBJIGNvdWxkIHNldCB0cnVl IA0KCQkvLyBhcyBhIGRlZmF1bHQgaGVyZSBhbmQgb3ZlcnJpZGUgaXQgd2hlcmUgaXQncyBub3Qg d2FudGVkLCBzYXZpbmcgDQoJCS8vIGEgY2h1bmsgb2YgY29kZSwgYnV0IEknZCByYXRoZXIgbWFr ZSBpdCBleHBsaWNpdCB0byBmb3JjZSBtZSB0byBjb25zaWRlciBlYWNoIGNhc2UuIEEgYml0IG1v cmUgQyZQIGZvciBsZXNzIGNoYW5jZSBvZiBidWdzLg0KCQkJZ2V0Ow0KCQl9DQoNCg0KCQkvLyBQ cm9kdWNlcyBhIHN0cmluZyB0aGF0IHNob3VsZCBiZSBpZGVudGljYWwgdG8gKGV4Y2VwdGluZw0K CQkvLyB3aGl0ZXNwYWNlcykgdGhlIGlucHV0IGllLiBlbWl0IExEQiBjb2RlIG5vdCB2YWxpZCBT UUwNCgkJLy8NCgkJLy8gVG9TdHJpbmcgd2FzIGNhdXNpbmcgdG9vIG1hbnkgd2VpcmQgcHJvYmxl bXMgKGR1ZSB0byBteQ0KCQkvLyBpbmV4cGVyaWVuY2Ugd2l0aCBjIykgc28ganVzdCB1c2VkIHRv UmF3U3RyKCkNCgkJcHVibGljIGFic3RyYWN0IHN0cmluZyB0b1Jhd1N0cigpOw0KDQoJCXB1Ymxp YyBvdmVycmlkZSBzdHJpbmcgdG9EZWJ1Z1N0cigpID0+IHRvUmF3U3RyKCk7DQoNCgl9IC8vIGVu ZCBMREJBU1RvYmoNCg0KDQoNCglwdWJsaWMgaW50ZXJmYWNlIEloYW5kbGVQcmVmaXhlczxUPg0K CQkJCQkJd2hlcmUgVCA6IExEQlJvb3Qgew0KDQoJCXB1YmxpYyBib29sIGlzUHJlZml4ZWQgeyBn ZXQ7IH0NCg0KCQlwdWJsaWMgYm9vbCBpc0V4Y2Vzc1ByZWZpeGVkIHsgZ2V0OyB9DQoNCgkJLy8g VGhlIFQgaW4gYWRkUHJlZml4L3JlUHJlZml4L3dpdGhvdXRQcmVmaXggaXMgYmVjYXVzZSB3ZSBt YXkgYmUgDQoJCS8vIHJldHVybmluZyBlZy4gYSBsaXN0IG9mIGl0ZW1zIHdpdGggcHJlZml4ZXMg DQoJCS8vIHRodXMgbW9kaWZpZWQsIG5vdCBhIHNpbmdsZSBQTVFJZGVudA0KDQoJCXB1YmxpYyBU IGFkZFByZWZpeChQTVFJZGVudCBwZngpOw0KDQoJCXB1YmxpYyBUIHJlUHJlZml4KFBNUUlkZW50 IG5ld3BmeCk7DQoNCi8vCQlwdWJsaWMgVCBzdHJpcFByZWZpeChQTVFJZGVudCBpZCk7DQoJfQ0K CS8vIHRvZG8gLSBtb3ZlIHRoaXMNCg0KDQoNCg0KDQoJcHVibGljIGFic3RyYWN0IGNsYXNzIExE QlJvb3Qgew0KCQkvLyBSb290IG9mIGV2ZXJ5dGhpbmcgTERCLWlzaA0KDQoJCXB1YmxpYyBib29s IEVxdWFscyhbQWxsb3dOdWxsXSBMREJSb290IG90aGVyKSB7DQoJCQl0aHJvdyBuZXcgTERCU2hv dWxkTm90QmVJbXBsZW1lbnRlZEV4Y2VwdGlvbigNCgkJCQkJCQkJCSJjYWxsZWQgRXF1YWxzIG9u IExEQlJvb3QiKTsNCgkJfQ0KDQoJCXB1YmxpYyBvdmVycmlkZQ0KCQkJYm9vbCBFcXVhbHMoW0Fs bG93TnVsbF0gT2JqZWN0IG90aGVyKSB7DQoJCQl0aHJvdyBuZXcgTERCU2hvdWxkTm90QmVJbXBs ZW1lbnRlZEV4Y2VwdGlvbigNCgkJCQkJCQkJCSJjYWxsZWQgRXF1YWxzIGluIE9iamVjdCIpOw0K CQl9DQoNCgkJcHVibGljIG92ZXJyaWRlIGludCBHZXRIYXNoQ29kZSgpIHsNCgkJCXRocm93IG5l dyBMREJTaG91bGROb3RCZUltcGxlbWVudGVkRXhjZXB0aW9uKA0KCQkJCQkJCQkJImNhbGxlZCBH ZXRIYXNoQ29kZSBpbiBMREJSb290Iik7DQoJCX0NCg0KCQlwdWJsaWMgc3RhdGljIGJvb2wgb3Bl cmF0b3IgPT0oTERCUm9vdCBsaHMsDQoJCQkJCQkJCQkgICBMREJSb290IHJocykgew0KCQkJdGhy b3cgbmV3IExEQlNob3VsZE5vdEJlSW1wbGVtZW50ZWRFeGNlcHRpb24oDQoJCQkJCQkJCQkiY2Fs bGVkID09IGluIExEQlJvb3QiKTsNCgkJfQ0KDQoJCXB1YmxpYyBzdGF0aWMgYm9vbCBvcGVyYXRv ciAhPShMREJSb290IGxocywNCgkJCQkJCQkJCSAgIExEQlJvb3QgcmhzKSB7DQoJCQl0aHJvdyBu ZXcgTERCU2hvdWxkTm90QmVJbXBsZW1lbnRlZEV4Y2VwdGlvbigNCgkJCQkJCQkJCSJjYWxsZWQg IT0gaW4gTERCUm9vdCIpOw0KCQl9DQoNCg0KCQlwdWJsaWMgdmlydHVhbCBzdHJpbmcgY2xhc3NO YW1lIHsNCgkJCS8vIHRvZG8gLSB0aGlzIG5lZWRzIGNoZWNraW5nIGl0IHdvcmtzIGFzIEkgd2Fu dA0KCQkJLy8gYWxzbyByZW5hbWUgdG8gbGRiY2xhc3NuYW1lIC0tIHRvZG8NCgkJCWdldCA9PiB0 aGlzLkdldFR5cGUoKS5GdWxsTmFtZSA/PyAiKHVua25vd24pIjsNCgkJfQ0KDQoNCgkJcHVibGlj IHZpcnR1YWwgc3RyaW5nIGNsYXNzTmFtZVEgPT4NCgkJCSInIiArIGNsYXNzTmFtZSArICInIjsN Cg0KDQoJCXB1YmxpYyB2aXJ0dWFsIHN0cmluZyBjbGFzc05hbWVQbHVzKHN0cmluZyBwbHVzKSA9 Pg0KCQkJY2xhc3NOYW1lICsgIi4iICsgcGx1czsNCg0KCQlwdWJsaWMgb3ZlcnJpZGUgc3RyaW5n IFRvU3RyaW5nKCkgew0KCQkJLy8gVGhpcyBpbXBsaWNpdCB0by1zdHJpbmcgY29udmVyc2lvbiBj cmFwIGNvc3QgbWUgYSBmZXcgaG91cnMsIHNvIGF0IGxlYXN0DQoJCQkvLyBkbyB0aGlzICYgYmxv dyB1cCBhdCBydW50aW1lLiBXb3VsZCBwcmVmZXIgY29tcGlsZSB0aW1lIGJ1dCBpdCBzZWVtcw0K CQkJLy8gbm90IHBvc3NpYmxlLiAgVGhpcyB0dXJucyBvdXQgdG8gaGF2ZSBiZWVuIGEgZ29vZCBp ZGVhLA0KCQkJLy8gc2F2ZWQgbWUgcXVpdGUgYSBiaXQgbW9yZSBkZWJ1Z2dpbmchDQoJCQkvLyA8 aHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvMTUzNDU1MTcvaXMtaXQtcG9zc2li bGUtdG8tZGlzYWJsZS1pbXBsaWNpdC10b3N0cmluZy1jYWxsPg0KCQkJLy8gV2lsbCB0cnkgPGh0 dHBzOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzU0MzU0MzQyL2hvdy10by1nZXQtYW4t ZXJyb3Itc2hvd24td2hlbi11c2luZy1ub24tc3RyaW5ncy1hcy1zdHJpbmdzLWluc3RlYWQtb2Yt YW4tYXV0b20vNTQzNTUxMTUjNTQzNTUxMTUpDQoJCQl2YXIgbXNnID0gIkxEQlJvb3QuVG9TdHJp bmcoKSI7DQoJCQl0aHJvdyBuZXcgTERCVG9TdHJpbmdJbXBsaWN0Q29udmVyc2lvbkV4Y2VwdGlv bihtc2cpOw0KCQl9DQoNCgkJcHVibGljIGFic3RyYWN0IHN0cmluZyB0b0RlYnVnU3RyKCk7DQoJ fQ0KDQoNCg0KCXB1YmxpYyBhYnN0cmFjdCBjbGFzcyBFcGhlbWVyYWwgOiBMREJSb290IHsNCgkJ Ly8gZm9yIG9iamVjdHMgdGhhdCBhcmUgbm90IHBhcnQgb2YgdGhlIEFTVA0KCX0NCg0KDQoNCglw dWJsaWMgaW50ZXJmYWNlIElXaXRoTGluZU5VbSB7ICAvLyB0b2RvIC0gdXNlIG9yIHJlbW92ZSAt IHRvZG8NCgkJLy8JcHVibGljIA0KCX0NCg0KDQoJcHVibGljIGludGVyZmFjZSBJSGFzVGFibGVB bGlhcyB7DQoJCS8vIEhhcyBhIHRhYmxlIGFsaWFzIEFTVCBvYmouIE1heSBiZSBhIC4uLk1pc3Np bmcgc3VidHlwZSBpbiB3aGljaA0KCQkvLyBpdCBoYXMgbm8gYWxpYXMgZ2l2ZW4gYnkgdGhlIHVz ZXIsIGJ1dCBhbGlhcyBBU1QgaXMgdGhlcmUuIE1vcmUNCgkJLy8gYWNjdXJhdGVseSBhIFRhYmxl U291cmNlIGFsaWFzIGJ1dCBvaw0KCQlwdWJsaWMgYWJzdHJhY3QgVGFibGVBbGlhcyB0YSB7IGdl dDsgc2V0OyB9DQoJfQ0KDQoNCgkvLyBCYXNlIGNsYXNzIGZvciBhbGwgTERCIEFTVCBvYmplY3Rz DQoJcHVibGljIGFic3RyYWN0IGNsYXNzIExEQkFTVG9iaiA6IExEQlJvb3Qgew0KCQkvLyBUaGlz IG9uZSBpcyBhIHByb2JsZW0uIElmIEkgZGVjbGFyZSB0aGUgJ3BhcmVudCcgcHJvcGVydHkNCgkJ Ly8gYWJzdHJhY3QgSSB0aGVuIGhhdmUgdG8gaW1wbGVtZW50IGl0IGxpdGVyYWxseSBodW5kcmVk cyBvZg0KCQkvLyB0aW1lcyBpbiB0aGUgZGVyaXZlZCBjbGFzc2VzLCBhbmQgSSByZWFsbHkgZG9u J3QgdGhpbmsgaXQNCgkJLy8gd291bGQgaGVscCBzbyBqdXN0IHNldCBpdCB0byBhIGRlZmF1bHQg d2hpY2ggZ2V0cyBvdmVyd3JpdHRlbiBsYXRlci4NCgkJLy8gDQoJCS8vIFRoZSBwcm9ibGVtIGlz IHRoYXQgdGhvc2Ugb2JqZWN0cyB3ZXJlIGNyZWF0ZWQgYnkgdGhlDQoJCS8vIHBhcnNlciwgd2hp Y2ggY3JlYXRlcyB0aGVtIGJvdHRvbS11cCwgd2hpY2ggbWVhbnMgeW91IGNhbid0DQoJCS8vIGtu b3cgdGhlIHBhcmVudCB3aGVuIHRoZXkgYXJlIGNyZWF0ZWQuIEl0IHNob3VsZCBiZQ0KCQkvLyBw b3NzaWJsZSB0byB3b3JrIGFyb3VuZCB0aGlzIGJ1dCBpdCBkb2VzIG1lYW4gcmV3b3JraW5nIHRo ZQ0KCQkvLyBwYXJzZXIgZnVuZGFtZW50YWxseSwgYW5kIEknbSBub3QgZ29pbmcgdG8gZG8gdGhh dA0KCQkvLyBhc3N1bWVpbmcgaXQncyBldmVuIHBvc3NpYmxlLg0KDQoJCS8vIHRvZG8gLSByZWFk IHVwIG9uIHByaXYvcHViL3Byb2cgYWNjZXNzb3JzIEkgcmVhbGx5IGRvbid0DQoJCS8vIGdldCB0 aGVzZSBhdCBhbGwNCgkJcHVibGljIExEQkFTVG9iaiBwYXJlbnQgeyBnZXQ7IHByaXZhdGUgc2V0 OyB9DQoJCQkJCQk9IG5vUGFyZW50Ow0KCQkvLyBVbmlxdWUgSUQgcGVyIG9iamVjdCwgdXNlZnVs IGZvciBkaXN0aW5ndWlzaGluZyB0aGVtDQoJCS8vIHdpdGhvdXQgZ2VuZXJhbCBlcXVhbGl0eS4N CgkJcmVhZG9ubHkgcHVibGljIHVsb25nIHVpZCA9IG5ld1VJRCgpOw0KDQoJCS8vIHB1YmxpYyBh YnN0cmFjdCBpbnQgbGluZU51bSB7IGdldDsgc2V0OyB9DQoNCgkJLy8gSXMgdmFsaWRhdGVkIGlz IGEgY2hlYXBpc2ggY2hlY2sgdG8gZW5zdXJlIGV2ZXJ5dGhpbmcgZ2V0cw0KCQkvLyB2YWxpZGF0 ZWQNCgkJLy8gY2FuIGRvIHRoaXMgYXMgYXV0byBwcm9wPyB0b2RvDQoJCXByaXZhdGUgYm9vbCBf dmFsaWRhdGVkID0gZmFsc2U7DQoNCgkJcHJvdGVjdGVkIGJvb2wgdmFsaWRhdGVkIHsNCgkJCWdl dCA9PiBfdmFsaWRhdGVkOw0KCQkJc2V0IHsNCgkJCQkvLyBoYXJkTXVzdCghdmFsaWRhdGVkLCAi Li4uIGFscmVhZHkgdmFsaWRhdGVkLi4uICIpOyAtIG5vDQoJCQkJLy8gSXQncyBoYXJkIHRvIGF2 b2lkIHZhbGlkYXRpbmcgYSB0aGluZyB0d2ljZSwgc28gZm9yIG5vdyBhbGxvdyBpdA0KCQkJCS8v IExvb2sgaW50byBpdCBsYXRlciwgcmVhbGx5IHNob3VsZG4ndCBoYXBwZW4NCgkJCQlfdmFsaWRh dGVkID0gdHJ1ZTsNCgkJCX0NCgkJfQ0KDQoJCXB1YmxpYyBMREJTdHJ1Y3RzQ2hpbGRyZW4ga2lk cyB7IGdldDsgcHJpdmF0ZSBzZXQ7IH0gPQ0KCQkJCQluZXcgTERCU3RydWN0c0NoaWxkcmVuKG5v UGFyZW50KTsgLy8ganVzdCBlYXNpZXINCg0KCQlwdWJsaWMgTERCQVNUb2JqKCkgeyAgLy8vLy8v Ly8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8v LyB0b2RvIGRlYWQ/DQoJCQkJCQkJICAvLyBWU3R1ZGlvIHRoaW5rcyB0aGlzIGhhcyB6ZXJvIHJl ZmVyZW5jZXMsIHdoaWNoIGlzIHRydWUgZXhwbGljaXRseSwgYnV0IGl0J3MgDQoJCQkJCQkJICAv LyBjYWxsZWQgaW1wbGljaXRseSBvbiBldmVyeSBvYmogY3JlYXRpb24gLSBvciBzaG91bGQgZG8g dG9kby0gY2hlY2sNCgkJCWlmIChyZWNvcmRPYmplY3RzQ3JlYXRlZCkgew0KCQkJCUFsbENyZWF0 ZWRJdGVtcy5BZGQodGhpcyk7DQoJCQl9DQoJCX0NCg0KDQoJCXB1YmxpYyB2aXJ0dWFsIHZvaWQg dmFsaWRhdGUoKSB7DQoJCQlpZiAocmVwb3J0QWxzb0lmVmFsaWRhdGlvbk9LKSB7DQoJCQkJZGVi dWdtc2coInZhbGlkYXRpbmcuLi4iICsgY2xhc3NOYW1lDQoJCQkJCSsgIiAoIiArIGFzTmFtZU9y SWRlbnRDb250ZW50cygpICsgIikiKTsNCgkJCX0NCgkJCW1ocF9taGsoKTsNCgkJCWtpZHMudmFs aWRhdGUoKTsNCgkJCS8vIHZhbGlkYXRlZCA9IHRydWU7IC0tIE5vLCBnZXQgZWFjaCBzdWJjbGFz cyB0byBzZXQNCgkJCS8vIHZhbGlkYXRlZC4gVGhhdCBmb3JjZXMgYW4gZXhwbGljaXQgY2FsbCB0 byBiYXNlKCkgd2hpY2gNCgkJCS8vIGlzIG1vcmUgY29kZSBidXQgb2suDQoJCX0NCg0KDQoJCXB1 YmxpYyBib29sIGlzVmFsaWRhdGVkIHsgZ2V0ID0+IHZhbGlkYXRlZDsgfSAgLy8gdG9kbyBqdXN0 ID0+IHZhbGlkYXRlZDsNCg0KDQoJCXB1YmxpYyB2aXJ0dWFsIGJvb2wgaXNUb3BMZXZlbEl0ZW1T ZXEgPT4gZmFsc2U7DQoNCg0KCQlwdWJsaWMgdmlydHVhbCB2b2lkIG1ocF9taGsoKSB7ICAvLyBk b24ndCB0aGluayB0aGlzIG5lZWQgYmUgdmlydHVhbCAtIHRvZG8/DQoJCQkJCQkJCQkJIC8vID0g bXVzdCBoYXZlIHBhcmVudCwgbXVzdCBoYXZlIGtpZHMuIFRoZSBraWRzIG1heSBiZSB0aGUNCgkJ CQkJCQkJCQkgLy8gZW1wdHkgc2V0IGFuZCB0aGUgcGFyZW50IG1heSBiZSBub1BhcmVudCBidXQg dGhleSBtdXN0DQoJCQkJCQkJCQkJIC8vIGV4aXN0Lg0KCQkJCQkJCQkJCSAvLyBXaHkgbm90IGp1 c3QgaW5saW5lIHRoaXMgaW50byB2YWxpZGF0ZSgpPw0KCQkJCQkJCQkJCSAvLyBCZWNhdXNlIGEg ZmV3IGNsYXNzZXMgbmVlZCBiZXNwb2tlIHZhbGlkYXRpb24sIGJ1dCBzdGlsbCBtdXN0IGNoZWNr IHRoaXMuDQoJCQloYXJkTXVzdFBhcmVudElzUHJlc2VudCgpOw0KCQkJa2lkcy5lYWNoS2lkUGFy ZW50TXVzdEJlKHRoaXMpOw0KCQl9DQoNCg0KCQlwdWJsaWMgc3RyaW5nIGFzTmFtZU9ySWRlbnRD b250ZW50cygpIHsNCgkJCS8vIGZvciB2ZXJ5IGNydWRlIGRlYnVnZ2luZyANCgkJCXZhciBvcHRO YW1lID0gdGhpcyBpcyBJaXNOYW1lZEl0ZW0gbmkgPyBuaS5uYW1lLnRvUmF3U3RyKCkgOiAiIjsN CgkJCW9wdE5hbWUgPSAob3B0TmFtZSA9PSAiIiAmJiB0aGlzIGlzIFBNUUlkZW50KSA/IHRoaXMu dG9SYXdTdHIoKSA6ICIiOw0KDQoJCQl2YXIgb3B0TmFtZTIgPSBvcHROYW1lICsgIiAgKHVpZDoi ICsgdWlkLlRvU3RyaW5nKCkgKyAiKSAiDQoJCQkJKyBnZXRGaXJzdEZld0NoYXJzT2YodG9SYXdT dHIoKSk7DQoJCQlyZXR1cm4gb3B0TmFtZTI7DQoJCX0NCg0KDQoJCXB1YmxpYyB2aXJ0dWFsIHZv aWQgZ2V0QWxsVUlEcyhVSURzZXQgdWlkcykgew0KCQkJdWlkcy5BZGQodGhpcyk7DQoJCQlraWRz LkZvckVhY2gobmFtZWRLaWQgPT4gbmFtZWRLaWQua2lkLmdldEFsbFVJRHModWlkcykpOw0KCQl9 DQoNCg0KCQlwdWJsaWMgYm9vbCBpc1N0dWJQYXJlbnQgeyBnZXQgPT4gKHRoaXMgaXMgTm9QYXJl bnQpIHx8ICh0aGlzIGlzIEZha2VQYXJlbnQpOyB9DQoNCg0KCQlwdWJsaWMgdm9pZCB2YWxpZGF0 ZVNwZWNpZmljSXRlbXMocGFyYW1zIExEQkFTVG9ialtdIGl0ZW1zKSB7DQoJCQlBcnJheS5Gb3JF YWNoKGl0ZW1zLCBpdGVtID0+IGl0ZW0udmFsaWRhdGUoKSk7DQoJCX0NCg0KDQoJCXB1YmxpYyBU PyBvcHRDbGltYlRvPFQ+KCkgd2hlcmUgVCA6IExEQkFTVG9iaiB7DQoJCQl2YXIgcmVzSXRlbSA9 IHRoaXM7DQoJCQl3aGlsZSAoIShyZXNJdGVtIGlzIFQpKSB7DQoJCQkJaWYgKHJlc0l0ZW0ucGFy ZW50LmlzU3R1YlBhcmVudCkgew0KCQkJCQlyZXR1cm4gbnVsbDsNCgkJCQl9DQoJCQkJcmVzSXRl bSA9IHJlc0l0ZW0ucGFyZW50Ow0KCQkJfQ0KDQoJCQl2YXIgcmVzID0gcmVzSXRlbSBhcyBUOw0K CQkJcmV0dXJuIHJlczsNCgkJfQ0KDQoNCgkJcHVibGljIFQgcmVxQ2xpbWJUbzxUPigpIHdoZXJl IFQgOiBMREJBU1RvYmogew0KCQkJdmFyIGxvYyA9IGNsYXNzTmFtZSArICIucmVxQ2xpbWJUbzxU PigpIjsNCgkJCXZhciByZXMgPSBvcHRDbGltYlRvPFQ+KCk7DQoJCQloYXJkTXVzdDIoIShyZXMg aXMgbnVsbCksIA0KCQkJCS8vIFRoYW5rcyBTTyA8aHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9x dWVzdGlvbnMvMjU4MTY0Mi9ob3ctZG8taS1nZXQtdGhlLXR5cGUtbmFtZS1vZi1hLWdlbmVyaWMt dHlwZS1hcmd1bWVudD4NCgkJCQkvLyBUb2RvIC0gdXNlIHRoaXMgZWxzZXdoZXJlLCBwb3NzIEV4 cGVjdEV4Y2VwdGlvbj8gdG9kbw0KCQkJCSgpID0+DQoJCQkJbG9jIA0KCQkJCSsgbmwgKyAiLCBj bGltYmVkIHRvIHRvcCwgZGlkbid0IGZpbmQgdHlwZSAiDQoJCQkJKyB0eXBlb2YoVCkuRnVsbE5h bWUNCgkJCQkrIG5sICsgIkhpZXJhcmNoeSBpczogIg0KCQkJCSsgbmwgKyBnZXRJdGVtV2l0aFBh cmVudHModGhpcykpOw0KCQkJaWYgKHJlcyBpcyBudWxsKSB7IHRocm93IG5ldyBOTlFDKCk7IH0N CgkJCXJldHVybiByZXM7DQoJCX0NCg0KDQoJCXB1YmxpYyB2b2lkIGhhcmRNdXN0UGFyZW50SXNQ cmVzZW50KCkgew0KDQoJCQloYXJkTXVzdDIoIShwYXJlbnQgaXMgbnVsbCksIA0KCQkJCSgpID0+ DQoJCQkJICJOVUxMIHBhcmVudCBmb3IgaXRlbSBvZiB0eXBlXG4iDQoJCQkJICsgJCJ7R2V0VHlw ZSgpfVxuLiIpOw0KDQoJCQloYXJkTXVzdDIoISh0aGlzLnBhcmVudCBpcyBOb1BhcmVudCksDQoJ CQkJKCkgPT4NCgkJCQkiUGFyZW50IGlzIE5vUGFyZW50IG9uIG9iamVjdCBvZiB0eXBlXG4iDQoJ CQkJKyAkIid7dGhpcy5jbGFzc05hbWV9JyIpOw0KCQl9DQoNCg0KCQlwdWJsaWMgdm9pZCBoYXJk TXVzdFBhcmVudElzQWJzZW50KCkgew0KCQkJLy8gRm9yIGNoZWNraW5nIGNsb25pbmcgLSBwYXJl bnQgc2hvdWxkIGJlIE5vUGFyZW50IGltbWVkaWF0ZWx5IA0KCQkJLy8gYWZ0ZXIsIGJlZm9yZSBp dCdzIHNldCBieSBwYXJlbnQsIGFuZCBuZXZlciBudWxsDQoJCQloYXJkTXVzdCghKHBhcmVudCBp cyBudWxsKSwNCgkJCQkgIk5VTEwgcGFyZW50IGZvciBpdGVtIG9mIHR5cGVcbiINCgkJCQkgKyAk IntHZXRUeXBlKCl9XG4uIik7DQoJCQloYXJkTXVzdCgodGhpcy5wYXJlbnQgaXMgTm9QYXJlbnQp LA0KCQkJCSJQYXJlbnQgc2hvdWxkIGJlIE5vUGFyZW50IG9uIG9iamVjdCBvZiB0eXBlXG4iDQoJ CQkJKyAkIid7dGhpcy5jbGFzc05hbWV9JyIpOw0KCQl9DQoNCg0KCQlwdWJsaWMgYm9vbCBoYXNQ YXJlbnQ8UD4oKSB7DQoJCQloYXJkTXVzdCghKHRoaXMgaXMgTm9QYXJlbnQpLCAiSXRlbSBpcyBO b1BhcmVudCIpOw0KCQkJcmV0dXJuIHRoaXMucGFyZW50IGlzIFA7DQoJCX0NCg0KDQoJCXB1Ymxp YyBib29sIGhhc0FuY2VzdG9yPEE+KCkgew0KCQkJaGFyZE11c3QoIXRoaXMuaXNTdHViUGFyZW50 LCAiSXRlbSBpcyBOb1BhcmVudCIpOw0KDQoJCQkvLyBob3cgdG8gZG8gd2l0aCBhIHN3aXRjaCBl eHByPw0KCQkJaWYgKHRoaXMucGFyZW50LmlzU3R1YlBhcmVudCAvKiBpcyBOb1BhcmVudCB8fCB0 aGlzLnBhcmVudCBpcyBGYWtlUGFyZW50Ki8gKSB7IC8vIHRvZG8gZG8gYXMgeC5oYXNGdWRnZWRQ YXJlbnQoKSAtIHRvZG8NCgkJCQlyZXR1cm4gZmFsc2U7DQoJCQl9IGVsc2UgaWYgKHRoaXMucGFy ZW50IGlzIEEpIHsNCgkJCQlyZXR1cm4gdHJ1ZTsNCgkJCX0gZWxzZSB7DQoJCQkJcmV0dXJuIHRo aXMucGFyZW50Lmhhc0FuY2VzdG9yPEE+KCk7DQoJCQl9DQoJCX0NCg0KCQlwdWJsaWMgYm9vbCBu b3RIYXNBbmNlc3RvcjxBPigpID0+DQoJCQkhaGFzQW5jZXN0b3I8QT4oKTsNCg0KDQoJCXB1Ymxp YyB2b2lkIHNldE15UGFyZW50VG8oTERCQVNUb2JqIHBybnQpIHsNCgkJCS8vIEFuIG9iamVjdCBt YXkgb25seSBzZXQgaXRzIHBhcmVudCBpZiBpdHMgY3VycmVudCBwYXJlbnQgaXMNCgkJCS8vIHRo ZSBkdW1teSAnbm9QYXJlbnQnLCB3aGljaCBhbG1vc3QgZXZlcnkgb2JqZWN0J3MgcGFyZW50IGlz DQoJCQkvLyBzZXQgdG8gb24gY3JlYXRpb24gKHNlZSBMREJBU1RvYmogcGFyZW50IHByb3BlcnR5 IGRlZikuDQoNCgkJCS8vIFRoZSB0ZXN0IGZvciBudWxsIGlzIHBlY3VsaWFyIGdpdmVuIHRoaXMu IEJlY2F1c2UNCgkJCS8vIG5vUGFyZW50IGlzIGNyZWF0ZWQgc3RhdGljYWxseSwgc2V0dGluZyB0 aGUgcGFyZW50IG9mDQoJCQkvLyBub1BhcmVudCBpcyBkaWZmaWN1bHQsIHBlcmhhcHMgaW1wb3Nz aWJsZSwgdG8gZG8gc3RhdGljYWxseQ0KCQkJLy8gYW5kIHJlbGlhYmx5LkRlc3BpdGUgdGhlIGRl Y2xhcmF0aW9uICcjbnVsbGFibGUgZW5hYmxlJywgaXQNCgkJCS8vIGdldHMgY3JlYXRlZCB3aXRo IGEgbnVsbCBwYXJyZW50IChxdWl0ZSByZWFzb25hYmx5KSwgaGVuY2UNCgkJCS8vIHRoaXMgY2hl Y2suVGhlIGFjdHVhbCBzZXR0aW5nIG9mIHRoZSBwYXJlbnQgaGFzIHRvIGJlIGRvbmUNCgkJCS8v IGF0IHJ1bnRpbWUgaS5lLmFmdGVyIHRoZSBzdGF0aWMgY3JlYXRpb24gb2YgJ25vUGFyZW50Jy4N Cg0KCQkJaGFyZE11c3QyKCh0aGlzLnBhcmVudCBpcyBOb1BhcmVudCkgfHwgKHRoaXMucGFyZW50 IGlzIG51bGwpLA0KCQkJCSgpID0+DQoJCQkJInRyaWVkIHRvIHJlLXNldCBwYXJlbnQgb24gb2Jq ZWN0IG9mIHR5cGU6ICINCgkJCQkrIG5sICsgdGhpcy5jbGFzc05hbWVRDQoJCQkJKyBubCArICJP cmlnaW5hbCBwYXJlbnQgdHlwZSBpczogIg0KCQkJCSsgKHRoaXM/LnBhcmVudD8uY2xhc3NOYW1l USA9PSBudWxsID8gIm51bGwiIDogdGhpcy5wYXJlbnQuY2xhc3NOYW1lUSkNCgkJCQkrIG5sICsg ImFuZCBuZXcgcGFyZW50IHR5cGUgaXM6ICINCgkJCQkrIHBybnQuY2xhc3NOYW1lUQ0KCQkJCSsg bmwgKyAiSXRlbSBoYXZpbmcgcGFyZW50IHNldCBvbiBpdCBpczogIg0KCQkJCS8vIGJlY2F1c2Ug b2JqZWN0IG1heSBub3QgYmUgZnVsbHkgY29uc3RydWN0ZWQgeWV0LCBjaGVjayBob3d2ZXIgVE9E TyB0aGlzIGlzIGEgbWFqb3IgaGFjayBhbmQgbXVzdCBiZSBmaXhlZCBzb21ldGltZS4NCi8vCQkJ CSsgbmwgKyAodGhpcyBpcyBudWxsID8gIihudWxsKSIgOiB0aGlzLnRvUmF3U3RyKCkpKTsNCgkJ CQkrIG5sICsgdGhpcy50b1Jhd1N0cigpICk7DQoNCgkJCXBhcmVudCA9IHBybnQ7DQoJCX0NCg0K DQoJCXB1YmxpYyB2b2lkIGZvcmNlTmV3UGFyZW50Rm9yUm9vdE9iamVjdCgpIHsNCgkJCS8vIEV2 ZXJ5IG9iamVjdCBtdXN0IGhhdmUgc29tZSBwYXJlbnQsIGluY2x1ZGluZyB0aGUNCgkJCS8vIHJv b3Qgb2JqZWN0IG9mIHRoZSBwYXJzZSwgd2hpY2ggaXMgTERCaXRlbXMNCgkJCS8vIChhIHNlcXVl bmNlIG9mIExEQiBpdGVtcyksIHNvIHRoaXMgZm9yY2VzIG9uZS4NCgkJCS8vIEl0IGlzIG9ubHkg Zm9yIHRoYXQgcHVycG9zZSENCgkJCS8vIA0KCQkJLy8gTERCaXRlbXMgb2JqIGV4aXN0cyBmb3Ig c3ViIG9ianMgc3VjaCBhcyB0aGUgc3RhdGVtZW50cw0KCQkJLy8gaW4gYSB3aGlsZSBsb29wLCBp biBhIHByb2MsIGluIGFuIGlmLi4uIGV0Yy4sIGZvcg0KCQkJLy8gd2hpY2ggdGhlaXIgcGFyZW50 IGlzIHRoZSB3aGlsZS9wcm9jL2lmIGV0Yy4NCgkJCWhhcmRNdXN0UGFyZW50SXNBYnNlbnQoKTsN CgkJCXRoaXMucGFyZW50ID0gZmFrZVBhcmVudDsNCgkJfQ0KDQoNCgkJLy9wdWJsaWMgdm9pZCBy ZXNldE15UGFyZW50VG8oTERCQVNUb2JqIHBybnQpIHsgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8v Ly8vLy8vLy8vLy8gZGVzdHJveSEhISEhISB0b2RvDQoJCS8vCXBhcmVudCA9IHBybnQ7DQoJCS8v fQ0KDQoJCS8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLyB4eHh4eHh4eHh4eHh4IGRlbGV0ZSAtIHRv ZG8NCgkJLy9wcml2YXRlIHZvaWQgc2V0UGFyZW50T25LaWQoTERCQVNUb2JqIGtpZCkgPT4gLy8g dG9kbyBuZWVkZWQ/DQoJCS8vCQkJCQkJCQkJCQkgIC8vIGNoZWNrIHBhcmVudGUgZG9lc24ndCBl eGlzdCAtIHRvZG8NCgkJLy8Ja2lkLnBhcmVudCA9IHRoaXM7DQoNCgkJcHVibGljIHZpcnR1YWwg dm9pZCBzZXRQYXJlbnRPbktpZHNBbmRNYWtlS2lkc0RpY3QoICAvLyB0b2RvIC0gYW5kIGFkZCB0 byBraWRzIGRpY3QNCgkJCQkJCQkJCQkJCQkJCSAvLyB0aGlzIG1peGVzIHVwIHNldHRpbmcgcGFy ZW50IGFuZCBtYWtpbmcgY2hpbGQgZGljdC4gTm90IGdvb2QuIC0gdG9kbw0KCQkJCQkJcGFyYW1z IChzdHJpbmcga2lkTmFtZSwgTERCQVNUb2JqIGtpZClbXSBraWRzSW4pIHsNCgkJCXZhciBsb2Mg PSBjbGFzc05hbWVQbHVzKCJzZXRQYXJlbnRPbktpZHNBbmRNYWtlS2lkc0RpY3QiKTsNCg0KCQkJ dmFyIGtpZHNUb0FkZCA9IG5ldyBMREJTdHJ1Y3RzQ2hpbGRyZW4odGhpcywga2lkc0luKTsNCgkJ CWhhcmRNdXN0MihraWRzLmlzRW1wdHksDQoJCQkJKCkgPT4NCgkJCQkkInNldHRpbmcga2lkcyBv biBwYXJlbnQgJ3tjbGFzc05hbWV9JyIgDQoJCQkJKyAid2hlbiBraWRzIGlzIG5vdCBlbXB0eSwg Ig0KCQkJCSsgJCJraWRzIGlzICh7a2lkcy5Db3VudH0ga2lkcyk6Ig0KCQkJCSsgbmwgKyBraWRz LnRvRGVidWdTdHIoKQ0KCQkJCSsgbmwgKyAkIlRyeWluZyB0byBhZGRcbntraWRzVG9BZGQudG9E ZWJ1Z1N0cigpfVxuIg0KCQkJCSsgJCJpbiB7Y2xhc3NOYW1lfSIpOw0KCQkJLy8gaWYgdGhlcmUg aXMgYW4gTERCU3RydWN0c0NoaWxkcmVuIGFuZCBhbm90aGVyIGNoaWxkLA0KCQkJLy8gdGhpcyB3 aWxsIGJsb3cgdXAgLSB3aWxsIG5lZWQgdG8gZG8ga2lkcy5BZGQgb3INCgkJCS8vIHNvbWV0aGlu ZyAtIGluIGZhY3QsIGtpZHMgbmVlZHMgdG8gYmUgY3JlYXRlZCBpbiBvbmUNCgkJCS8vIGdvLCB3 aGljaCBpcyB3aGF0IGhhcHBlbnMuDQoJCQlraWRzID0ga2lkc1RvQWRkOyAgICAvLy8vLy8vLy8v Ly8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8gd2h5IHRoaXM/ IHRvZG8NCgkJCUFycmF5LkZvckVhY2goa2lkc0luLCB4a2lkID0+IGhhcmRNdXN0KCEoeGtpZC5r aWQgaXMgbnVsbCksIGxvYywgIm51bGwga2lkIikpOw0KCQkJQXJyYXkuRm9yRWFjaChraWRzSW4s IHhraWQgPT4geGtpZC5raWQuc2V0TXlQYXJlbnRUbyh0aGlzKSk7DQoJCX0NCg0KDQoJCXB1Ymxp YyB2aXJ0dWFsIHZvaWQgc2V0UGFyZW50T25LaWRzQW5kQWRkVG9LaWRzRGljdCgNCgkJCQkJcGFy YW1zIChzdHJpbmcga2lkTmFtZSwgTERCQVNUb2JqIGtpZClbXSBraWRzSW4pIHsNCgkJCXZhciBr aWRzVG9BZGRfanVzdEZvckVyclJlcG9ydGluZyA9IG5ldyBMREJTdHJ1Y3RzQ2hpbGRyZW4odGhp cywga2lkc0luKTsNCgkJCWhhcmRNdXN0Migha2lkcy5pc0VtcHR5LCAvLyBtYXkgZGlzYWJsZSB0 aGlzIGxhdGVyIA0KCQkJCSgpID0+DQoJCQkJImFkZGluZyB0byBraWRzIHdoZW4ga2lkcyBpcyBl bXB0eSwgIg0KCQkJCSArICQia2lkcyBpc1xue2tpZHMudG9EZWJ1Z1N0cigpfVxuIg0KCQkJCSAr ICQiVHJ5aW5nIHRvIGFkZFxue2tpZHNUb0FkZF9qdXN0Rm9yRXJyUmVwb3J0aW5nLnRvRGVidWdT dHIoKX1cbiINCgkJCQkgKyAkImluIHtjbGFzc05hbWV9Iik7DQoJCQlBcnJheS5Gb3JFYWNoKGtp ZHNJbiwgeGtpZCA9PiB7DQovLwkJCQlzZXRQYXJlbnRPbktpZCh4a2lkLmtpZCk7DQoJCQkJeGtp ZC5raWQuc2V0TXlQYXJlbnRUbyh0aGlzKTsNCgkJCQlraWRzLkFkZCh4a2lkKTsNCgkJCX0pOw0K CQl9DQoNCg0KCQlwdWJsaWMgdmlydHVhbCBJZGVudHNVc2VkIGdldEFsbElEcygpIHsNCgkJLyog VGhpcyBpcyBvdmVycmlkZGVuIG9ubHkgaW4gVGVtcGxhdGVkQWdnLCBhbmQgdGhhdCdzIG9ubHkg dG8gDQoJCQlkZWxpYmVyYXRlbHkgZmFpbC4gVGhlcmUncyBzb21ldGhpbmcgd3JvbmcgdGhlcmUs IHRvZG8gLSANCgkJCXVuLXZpcnR1YWxpc2UgdGhpcyBhbmQgcmVtb3ZlIHRoZSBvbmUgb3ZlcnJp ZGUuIC0gdG9kbw0KCQkqLw0KCQkJdmFyIGl1ID0gbmV3IElkZW50c1VzZWQoKTsNCgkJCXRoaXMu X2dldEFsbElEcyhpdSk7DQoJCQlyZXR1cm4gaXU7DQoJCX0NCg0KCQlwdWJsaWMgdmlydHVhbCB2 b2lkIF9nZXRBbGxJRHMoSWRlbnRzVXNlZCBpdSkgew0KCQkvLyBHZXRzIGFsbCB0aGUgaWRlbnRp ZmllcnMgZXhwbGljaXRseSB1c2VkIChyZWFkIG9yIHdyaXR0ZW4pICAtLS0tLSB0b2RvIHVwZGF0 ZSB0aGlzDQoJCS8vIGFueXdoZXJlIGluIHRoZSBBU1QuICBEb2VzIG5vdCBnZXQgaWRlbnRzIHdo aWNoIGFyZQ0KCQkvLyBkZWNsYXJhdGlvbnMgaWUuIHBhcmFtZXRlcnMsIG9yIHZhci9jb25zdCBk ZWNsYXJhdGlvbnMNCgkJLy8gdW5sZXNzIHRoZXNlIGFyZSBjb21iaW5lZCB3aXRoIGFuIGFzc2ln bm1lbnQuDQoJCS8vDQoJCS8vIEltcGxpZWQgaWRlbnRzIHN1Y2ggYXMgdGhvc2UgZnJvbSB0Ymwu KiBhcmUgaW1wbGljaXQgYW5kIGlnbm9yZWQuDQoJCS8vDQoJCS8vIFJvb3QgY2FsbGVyIHN1cHBs aWVzIG5ldywgZW1wdHkgaXUNCgkJLy8gbmVlZCB1c2FnZSBoZXJlIC0gdG9kbyBkb2NzLy8NCgkJ CWtpZHMuX2dldEFsbElEcyhpdSk7DQoJCX0NCg0KCQlwdWJsaWMgYWJzdHJhY3QgYm9vbCBjYW5H ZXRBbGxJZGVudHNVc2VkIHsNCgkJLy8gCVRoaXMgc2VlbXMgdG8gYmUgdHJ1ZSBvbiBtb3N0IGNs YXNzZXMgc28gSSBjb3VsZCBzZXQgdHJ1ZSANCgkJLy8gYXMgYSBkZWZhdWx0IGhlcmUgYW5kIG92 ZXJyaWRlIGl0IHdoZXJlIGl0J3Mgbm90IHdhbnRlZCwgc2F2aW5nIA0KCQkvLyBhIGNodW5rIG9m IGNvZGUsIGJ1dCBJJ2QgcmF0aGVyIG1ha2UgaXQgZXhwbGljaXQgdG8gZm9yY2UgbWUgdG8gY29u c2lkZXIgZWFjaCBjYXNlLiBBIGJpdCBtb3JlIEMmUCBmb3IgbGVzcyBjaGFuY2Ugb2YgYnVncy4N CgkJCWdldDsNCgkJfQ0KDQoNCgkJLy8gUHJvZHVjZXMgYSBzdHJpbmcgdGhhdCBzaG91bGQgYmUg aWRlbnRpY2FsIHRvIChleGNlcHRpbmcNCgkJLy8gd2hpdGVzcGFjZXMpIHRoZSBpbnB1dCBpZS4g ZW1pdCBMREIgY29kZSBub3QgdmFsaWQgU1FMDQoJCS8vDQoJCS8vIFRvU3RyaW5nIHdhcyBjYXVz aW5nIHRvbyBtYW55IHdlaXJkIHByb2JsZW1zIChkdWUgdG8gbXkNCgkJLy8gaW5leHBlcmllbmNl IHdpdGggYyMpIHNvIGp1c3QgdXNlZCB0b1Jhd1N0cigpDQoJCXB1YmxpYyBhYnN0cmFjdCBzdHJp bmcgdG9SYXdTdHIoKTsNCg0KCQlwdWJsaWMgb3ZlcnJpZGUgc3RyaW5nIHRvRGVidWdTdHIoKSA9 PiB0b1Jhd1N0cigpOw0KDQoJfSAvLyBlbmQgTERCQVNUb2JqDQoNCg0KCQ0KfQ0K --00000000000089580f05c41a1588--