From unknown Tue Jun 17 01:48:02 2025 X-Loop: help-debbugs@gnu.org Subject: bug#48871: 27.2; Unusably slow in C# mode Resent-From: jan Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sun, 06 Jun 2021 12:33:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: report 48871 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: To: 48871@debbugs.gnu.org X-Debbugs-Original-To: bug-gnu-emacs@gnu.org Received: via spool by submit@debbugs.gnu.org id=B.162298274318434 (code B ref -1); Sun, 06 Jun 2021 12:33:02 +0000 Received: (at submit) by debbugs.gnu.org; 6 Jun 2021 12:32:23 +0000 Received: from localhost ([127.0.0.1]:50929 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1lprwx-0004nD-51 for submit@debbugs.gnu.org; Sun, 06 Jun 2021 08:32:23 -0400 Received: from lists.gnu.org ([209.51.188.17]:34990) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1lprwr-0004n1-Ns for submit@debbugs.gnu.org; Sun, 06 Jun 2021 08:32:17 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60602) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lprwr-0001IC-Ew for bug-gnu-emacs@gnu.org; Sun, 06 Jun 2021 08:32:13 -0400 Received: from mail-pj1-x1029.google.com ([2607:f8b0:4864:20::1029]:41693) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1lprwp-0004SB-Hf for bug-gnu-emacs@gnu.org; Sun, 06 Jun 2021 08:32:13 -0400 Received: by mail-pj1-x1029.google.com with SMTP id b15-20020a17090a550fb029015dad75163dso8709735pji.0 for ; Sun, 06 Jun 2021 05:32:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=googlemail.com; s=20161025; h=mime-version:from:date:message-id:subject:to; bh=tPCrtcBu1mlybMNMACwuR/rJRbBlBgPBilm3/PQ1AH0=; b=UjezA78vtsKKuAEtBG55FqCY4Mc5INTQ3JHTsNy9YD0P1OH4JMo68uhJnSc+YCs7Xx WhicGp7m5GMQwoMmqtMbRCAsFN0vyK/GAj38vuFQPyi5tA41qG/yaDeWSQxXTWKx6wzm SfGHTJ7v5k4S5JqbeFsHChSqloFf9EcDWQunxX6ePR6tFXA6VcAQmbG5tB+DJhAE+DQB KBWqefnhd695diUuzKZtKsmOgbWeg6sFFrRkcoK+H8en8tzmVnM5tsaGjWXgHxe6RQHd S3OcXMGWD/AnmAs7WYJgSxhyyhUowYHRKUpUaTyAXfB1g0zvI8eQUJpkYGTKyRKvuue7 hLzg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:from:date:message-id:subject:to; bh=tPCrtcBu1mlybMNMACwuR/rJRbBlBgPBilm3/PQ1AH0=; b=nzHPtfaQE5gFdljVsFiq1yX6UWbPE6bvjV0cUdGMwLckHYP1qTKtWPbwNj2BVl5bzL SeDHb3MLOUHmq6NHFZsPo+Q+yLvzLl138ihb2BDpZ+oB3qwU9+II7VL5VlrF9H3CT2Ds 5Hr3zam+bUGhBIalBtfnF4Llia9tpwGmzM0hK7cLaDZF4Ht+JRskxoehkHJDieSDEs/S PaOHE00PnHbokrsL2PNwaMoulrw0Vg2jAh9Mb8CAMAU+jNZWpnJs7VWDgeNkwQ9i/F0i oVBSp1w4komcqiEmyHH5RA6zJQqlB+ucleHC/CqzknsUmwzmolyLk+T8fY9ipr2JQPRe zIdg== X-Gm-Message-State: AOAM530QxueeM/q2WncpB/NpHRN+9KRwsljsdwmVEu9DHKofmhHy7siv +jyYIbRs6XzWga/DHVNyQh1WxCzBlYPsYZETZe9rUN4C X-Google-Smtp-Source: ABdhPJylnRp9H3FwQInkOkwY174YAqr4JhaYvwxO5OXX/kQTn0SoWnzaO/3ZdgIRONJVchdY4fq2iH3HPG5Ur6Uuslo= X-Received: by 2002:a17:90a:a607:: with SMTP id c7mr15226873pjq.199.1622982729551; Sun, 06 Jun 2021 05:32:09 -0700 (PDT) MIME-Version: 1.0 Received: by 2002:a17:90a:aa06:0:0:0:0 with HTTP; Sun, 6 Jun 2021 05:32:09 -0700 (PDT) From: jan Date: Sun, 6 Jun 2021 13:32:09 +0100 Message-ID: Content-Type: text/plain; charset="UTF-8" Received-SPF: pass client-ip=2607:f8b0:4864:20::1029; envelope-from=rtm443x@googlemail.com; helo=mail-pj1-x1029.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-Spam-Score: -1.3 (-) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -2.3 (--) Hi, I use emacs, I'm not an expert. C# mode is slow beyond to the point of being completely unusable. This seems to have started when I upgraded from emacs 26 to emacs 27.2. The file is ~220K. At the start of the file, typing takes 3 or 4 secs *per character* to appear (at the end of the file, instantaneous). It's forcing me to use visual studio to do all simple text editing and I don't like that. If I turn off font lock mode it doesn't improve any. If I switch to fundamental mode it's back to it's snappy self. Turning off Syntactic Indentation and Electric Mode didn't help. I tried removing all comments to see what happened but no luck. I did find this quite recent issue but their solution didn't help because I couldn't find that text in the specified lisp file so couldn't comment it out. I looked on the emacs bug list but found nothing matching (not sure I was doing the search right though). I can provide the c# file but I'd prefer it to not be made public if possible. Turns out emacs has a profiler, thought I'd try it. From did profiler-start, typed some chars (probably 20 to 30 secs locked up before it was finished, immediately did profiler-stop, report is this (heavier parts expanded) - command-execute 1121 97% - call-interactively 1121 97% - funcall-interactively 1114 96% - self-insert-command 889 77% - c-before-change 878 76% - mapc 878 76% - # 878 76% - c-before-change-check-unbalanced-strings 877 76% c-pps-to-string-delim 865 75% - c-syntactic-re-search-forward 11 0% c-beginning-of-macro 4 0% - c-after-change 11 0% - mapc 11 0% - # 11 0% c-after-change-mark-abnormal-strings 4 0% - c-restore-<>-properties 4 0% c-syntactic-re-search-forward 3 0% - c-forward-<>-arglist 1 0% - c-forward-<>-arglist-recur 1 0% c-forward-sws 1 0% - c-change-expand-fl-region 2 0% - c-fl-decl-end 2 0% - c-literal-start 2 0% - c-semi-pp-to-literal 2 0% c-parse-ps-state-below 2 0% c-parse-quotes-after-change 1 0% - newline 223 19% - self-insert-command 223 19% - electric-indent-post-self-insert-function 112 9% - indent-according-to-mode 112 9% - c-indent-line 112 9% - c-shift-line-indentation 112 9% - c-before-change 110 9% + mapc 109 9% c-restore-string-fences 1 0% - c-after-change 2 0% - mapc 2 0% - # 2 0% c-after-change-mark-abnormal-strings 1 0% - c-restore-<>-properties 1 0% c-syntactic-re-search-forward 1 0% - c-before-change 110 9% - mapc 110 9% - # 110 9% - c-before-change-check-unbalanced-strings 110 9% c-pps-to-string-delim 109 9% c-syntactic-re-search-forward 1 0% - c-after-change 1 0% - mapc 1 0% - # 1 0% - c-restore-<>-properties 1 0% c-syntactic-re-search-forward 1 0% - execute-extended-command 2 0% - sit-for 2 0% redisplay 2 0% + byte-code 7 0% - ... 25 2% Automatic GC 25 2% + redisplay_internal (C function) 5 0% Not sure what to do. cheers jan From unknown Tue Jun 17 01:48:02 2025 X-Loop: help-debbugs@gnu.org Subject: bug#48871: 27.2; Unusably slow in C# mode Resent-From: Eli Zaretskii Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sun, 06 Jun 2021 12:50:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 48871 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: To: jan Cc: 48871@debbugs.gnu.org Received: via spool by 48871-submit@debbugs.gnu.org id=B48871.162298376120060 (code B ref 48871); Sun, 06 Jun 2021 12:50:01 +0000 Received: (at 48871) by debbugs.gnu.org; 6 Jun 2021 12:49:21 +0000 Received: from localhost ([127.0.0.1]:50945 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1lpsDO-0005DQ-2P for submit@debbugs.gnu.org; Sun, 06 Jun 2021 08:49:21 -0400 Received: from eggs.gnu.org ([209.51.188.92]:40830) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1lpsDH-0005D7-Lz for 48871@debbugs.gnu.org; Sun, 06 Jun 2021 08:49:16 -0400 Received: from fencepost.gnu.org ([2001:470:142:3::e]:50196) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lpsDC-0006iw-9u; Sun, 06 Jun 2021 08:49:06 -0400 Received: from 84.94.185.95.cable.012.net.il ([84.94.185.95]:1694 helo=home-c4e4a596f7) by fencepost.gnu.org with esmtpsa (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lpsDB-00047p-QN; Sun, 06 Jun 2021 08:49:06 -0400 Date: Sun, 06 Jun 2021 15:49:05 +0300 Message-Id: <835yyri2f2.fsf@gnu.org> From: Eli Zaretskii In-Reply-To: (bug-gnu-emacs@gnu.org) References: X-Spam-Score: -2.3 (--) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -3.3 (---) > Date: Sun, 6 Jun 2021 13:32:09 +0100 > From: jan via "Bug reports for GNU Emacs, > the Swiss army knife of text editors" > > C# mode is slow beyond to the point of being completely unusable. This > seems to have started when I upgraded from emacs 26 to emacs 27.2. The > file is ~220K. At the start of the file, typing takes 3 or 4 secs *per > character* to appear (at the end of the file, instantaneous). It's > forcing me to use visual studio to do all simple text editing and I > don't like that. > [...] > Turns out emacs has a profiler, thought I'd try it. Good start, thanks. > Not sure what to do. Post an example of a file where typing lags by several seconds, and let's see what people here can tell about that. But before that, start "emacs -Q", visit the C# file that gave you such trouble, and try typing there. If the lag disappears, then look for some of your customizations that could explain the slow responses. From unknown Tue Jun 17 01:48:02 2025 X-Loop: help-debbugs@gnu.org Subject: bug#48871: 27.2; Unusably slow in C# mode Resent-From: jan Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sun, 06 Jun 2021 13:35:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 48871 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: To: Eli Zaretskii Cc: 48871@debbugs.gnu.org Received: via spool by 48871-submit@debbugs.gnu.org id=B48871.1622986468442 (code B ref 48871); Sun, 06 Jun 2021 13:35:02 +0000 Received: (at 48871) by debbugs.gnu.org; 6 Jun 2021 13:34:28 +0000 Received: from localhost ([127.0.0.1]:51036 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1lpsv5-000074-Ox for submit@debbugs.gnu.org; Sun, 06 Jun 2021 09:34:27 -0400 Received: from mail-pl1-f171.google.com ([209.85.214.171]:45753) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1lpsv3-00006q-Uo for 48871@debbugs.gnu.org; Sun, 06 Jun 2021 09:34:26 -0400 Received: by mail-pl1-f171.google.com with SMTP id 11so7137349plk.12 for <48871@debbugs.gnu.org>; Sun, 06 Jun 2021 06:34:25 -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=7izs4l2u/69Kbi3uopL2f45ZYx5BP66qFHqe+/7wwbk=; b=YgzxWzSiJqYeODJ5Z7h8RNDsOftQhgh+c/vKGTYRFS1ZySxkEFqmxVV5/W0ysAqC1g MEMOMj5JOecQXggEXzDCzq3nhFkKUroMG+zHwfLW85TEBRsC5WgRXNHfk8XlvgQO2y6A +K4Zso+oYccDBYE71Qh25Tul2PV4Vbk1B+Ddb/B+ER/yopQZa4EtnRp8/3DGO79Veh/k 1O18qwYwMRAAiS7nTgqhxQaq3j8ua7qK7J1GYkclwPi0my98ULpyIL4XOxtQ4nI0WJpu p8vOAeu1Kf1AhW7lPDV5oSN5KvjtXz3uzvrBybQMR+5UL9XfUxbjmw8GWXDpAIb2Ed/1 fYwA== 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=7izs4l2u/69Kbi3uopL2f45ZYx5BP66qFHqe+/7wwbk=; b=SJhNghOSub10kCP/m0EJo1b6XWdW9gI1BoORt3yiOVLVdWZ6BblCwdkWibVxqIyHvy koYvls1aPMnf+mNJ6n/lI0WaGvFkaVkkCQSb0Ud+9b+km3sEEqjBHDeHGCNbt7dK+hG1 QSpFrMSl2RMk4ambvAfIUCxyLb8qyAfDt+rLCkUCIQ1z/amT4Oh2BJ8j2KOc2etD6HYm C6kV0NImGTPb5BB8K2txvxUq9PHZvyCk2EAWkcpUqkVaCnxmHDO4YBxL8rBf6x+ZO/v+ 856vijqJW5R+M9aoLAVIPIJmMD+1V88ozMGP94Ouhz8E3ClT9I2hFsR07LMSzMwx1MI/ TsBg== X-Gm-Message-State: AOAM533K8Sr0avlGlgmxETdPOMd/ojq7Nig68USk6JHs3t5Qf86pILSB OYnMP4vzSKY5UGRRUg1O/kJ/tcigDx6JApZs1Cs= X-Google-Smtp-Source: ABdhPJwcv2OEu2dUHPSLLiQgJ5SLW5UNjJNnIdOSA/6UkfTdOYSe/rGmyBUZcGKuJ2ExgIbBNx3fHbkM1aZb7LasdyU= X-Received: by 2002:a17:90b:4004:: with SMTP id ie4mr15798750pjb.102.1622986459991; Sun, 06 Jun 2021 06:34:19 -0700 (PDT) MIME-Version: 1.0 Received: by 2002:a17:90a:aa06:0:0:0:0 with HTTP; Sun, 6 Jun 2021 06:34:19 -0700 (PDT) In-Reply-To: <835yyri2f2.fsf@gnu.org> References: <835yyri2f2.fsf@gnu.org> From: jan Date: Sun, 6 Jun 2021 14:34:19 +0100 Message-ID: Content-Type: text/plain; charset="UTF-8" X-Spam-Score: 0.0 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) Hi Eli, 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. 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? cheers jan On 06/06/2021, Eli Zaretskii wrote: >> Date: Sun, 6 Jun 2021 13:32:09 +0100 >> From: jan via "Bug reports for GNU Emacs, >> the Swiss army knife of text editors" >> >> C# mode is slow beyond to the point of being completely unusable. This >> seems to have started when I upgraded from emacs 26 to emacs 27.2. The >> file is ~220K. At the start of the file, typing takes 3 or 4 secs *per >> character* to appear (at the end of the file, instantaneous). It's >> forcing me to use visual studio to do all simple text editing and I >> don't like that. >> [...] >> Turns out emacs has a profiler, thought I'd try it. > > Good start, thanks. > >> Not sure what to do. > > Post an example of a file where typing lags by several seconds, and > let's see what people here can tell about that. > > But before that, start "emacs -Q", visit the C# file that gave you > such trouble, and try typing there. If the lag disappears, then look > for some of your customizations that could explain the slow responses. > From unknown Tue Jun 17 01:48:02 2025 X-Loop: help-debbugs@gnu.org Subject: bug#48871: 27.2; Unusably slow in C# mode Resent-From: Eli Zaretskii Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sun, 06 Jun 2021 13:51:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 48871 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: To: jan Cc: 48871@debbugs.gnu.org Received: via spool by 48871-submit@debbugs.gnu.org id=B48871.16229874392211 (code B ref 48871); Sun, 06 Jun 2021 13:51:02 +0000 Received: (at 48871) by debbugs.gnu.org; 6 Jun 2021 13:50:39 +0000 Received: from localhost ([127.0.0.1]:51074 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1lptAl-0000ZZ-9k for submit@debbugs.gnu.org; Sun, 06 Jun 2021 09:50:39 -0400 Received: from eggs.gnu.org ([209.51.188.92]:48340) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1lptAi-0000ZM-TV for 48871@debbugs.gnu.org; Sun, 06 Jun 2021 09:50:38 -0400 Received: from fencepost.gnu.org ([2001:470:142:3::e]:51334) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lptAd-0002wo-Kj; Sun, 06 Jun 2021 09:50:31 -0400 Received: from 84.94.185.95.cable.012.net.il ([84.94.185.95]:1606 helo=home-c4e4a596f7) by fencepost.gnu.org with esmtpsa (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lptAd-0000Gs-7u; Sun, 06 Jun 2021 09:50:31 -0400 Date: Sun, 06 Jun 2021 16:50:28 +0300 Message-Id: <83y2bngl0b.fsf@gnu.org> From: Eli Zaretskii In-Reply-To: (message from jan on Sun, 6 Jun 2021 14:34:19 +0100) References: <835yyri2f2.fsf@gnu.org> X-Spam-Score: -2.3 (--) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -3.3 (---) > 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? From unknown Tue Jun 17 01:48:02 2025 X-Loop: help-debbugs@gnu.org Subject: bug#48871: 27.2; Unusably slow in C# mode 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 X-GNU-PR-Keywords: To: Eli Zaretskii Cc: 48871@debbugs.gnu.org Received: via spool by 48871-submit@debbugs.gnu.org id=B48871.162299120111159 (code B ref 48871); Sun, 06 Jun 2021 14:54:01 +0000 Received: (at 48871) by debbugs.gnu.org; 6 Jun 2021 14:53:21 +0000 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 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 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) MIME-Version: 1.0 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> References: <835yyri2f2.fsf@gnu.org> <83y2bngl0b.fsf@gnu.org> From: jan Date: Sun, 6 Jun 2021 15:53:11 +0100 Message-ID: Content-Type: multipart/mixed; boundary="00000000000089580f05c41a1588" X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" --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-- From unknown Tue Jun 17 01:48:02 2025 X-Loop: help-debbugs@gnu.org Subject: bug#48871: 27.2; Unusably slow in C# mode Resent-From: Eli Zaretskii Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sun, 06 Jun 2021 17:02:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 48871 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: To: jan , Alan Mackenzie Cc: 48871@debbugs.gnu.org Received: via spool by 48871-submit@debbugs.gnu.org id=B48871.162299886632453 (code B ref 48871); Sun, 06 Jun 2021 17:02:01 +0000 Received: (at 48871) by debbugs.gnu.org; 6 Jun 2021 17:01:06 +0000 Received: from localhost ([127.0.0.1]:53800 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1lpw93-0008RN-Lp for submit@debbugs.gnu.org; Sun, 06 Jun 2021 13:01:05 -0400 Received: from eggs.gnu.org ([209.51.188.92]:42992) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1lpw91-0008Qk-Q2 for 48871@debbugs.gnu.org; Sun, 06 Jun 2021 13:01:04 -0400 Received: from fencepost.gnu.org ([2001:470:142:3::e]:54390) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lpw8w-0007Hl-Do; Sun, 06 Jun 2021 13:00:58 -0400 Received: from 84.94.185.95.cable.012.net.il ([84.94.185.95]:1515 helo=home-c4e4a596f7) by fencepost.gnu.org with esmtpsa (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lpw8v-00015K-UR; Sun, 06 Jun 2021 13:00:58 -0400 Date: Sun, 06 Jun 2021 20:00:55 +0300 Message-Id: <83v96rgc6w.fsf@gnu.org> From: Eli Zaretskii In-Reply-To: (message from jan on Sun, 6 Jun 2021 15:53:11 +0100) References: <835yyri2f2.fsf@gnu.org> <83y2bngl0b.fsf@gnu.org> X-Spam-Score: -2.3 (--) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -3.3 (---) > From: jan > Date: Sun, 6 Jun 2021 15:53:11 +0100 > Cc: 48871@debbugs.gnu.org > > 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. Thanks. Alan, can you look into this? It could be some problem in csharp-mode, but the profiler says 97% of the time is spent in a CC mode code, so maybe you can shed some light on this? I see that almost the entire 6896-line file is enclosed in a single "namespace LDB { ... }" block, maybe this is the reason? Here's the main portion of a profile measured on my system from just inserting 3 characters at BOB of the file attached by the OP. An unoptimized build of Emacs 28 took about 2 min(!) to process those 3 self-inserting characters. 8693 98% - command-execute 8693 98% - call-interactively 8693 98% - funcall-interactively 8690 98% - self-insert-command 8627 98% - c-before-change 8627 98% - mapc 8627 98% - # 8627 98% - c-before-change-check-unbalanced-strings 8611 97% c-pps-to-string-delim 10 0% - c-syntactic-re-search-forward 2 0% - c-beginning-of-macro 2 0% back-to-indentation 1 0% # 1 0% c-clear-syn-tab 63 0% - c-after-change From unknown Tue Jun 17 01:48:02 2025 X-Loop: help-debbugs@gnu.org Subject: bug#48871: 27.2; Unusably slow in C# mode Resent-From: jan Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sun, 06 Jun 2021 18:02:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 48871 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: To: Eli Zaretskii Cc: Alan Mackenzie , 48871@debbugs.gnu.org Received: via spool by 48871-submit@debbugs.gnu.org id=B48871.16230024695977 (code B ref 48871); Sun, 06 Jun 2021 18:02:02 +0000 Received: (at 48871) by debbugs.gnu.org; 6 Jun 2021 18:01:09 +0000 Received: from localhost ([127.0.0.1]:53846 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1lpx5B-0001YK-8r for submit@debbugs.gnu.org; Sun, 06 Jun 2021 14:01:09 -0400 Received: from mail-pl1-f180.google.com ([209.85.214.180]:45792) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1lpx55-0001Xd-LK for 48871@debbugs.gnu.org; Sun, 06 Jun 2021 14:01:07 -0400 Received: by mail-pl1-f180.google.com with SMTP id 11so7357334plk.12 for <48871@debbugs.gnu.org>; Sun, 06 Jun 2021 11:01:03 -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=08PBCRVYtq58kIrSPB4FpZgH2hN+aNGLbKkuZQyH5bo=; b=leD4kR99nF9B4wou4SpuLY78TuaZA9dBqMQvwwG+Jf4DifLuDwd3PK1Qt9USEcAR7t rnp/221YwqQAP+hoY1qznsSJ5S88xNmlcz4h0B10wEgGrz3rXJmavbmzJHchpFlAtM7v 4uh4pt2ylX7fU51BmQ0GrsqsQrhhfk4WPJgsEkwH/wBvclpuVNrb+WzsDJ9IfmUwkTpQ m4BzO4JBzADjPFNssMk4t+XEjWe4j4XgdGRX3S5sdqwIUpJ5lJtFebeZA5vTBn7HyurO S1JRTsywbnBoMVt25IdtpRcD+wZyKK5dJUsSzWekpcFYHFNnb46Z8RHkkk5nWQ+sYYQ+ Ndew== 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=08PBCRVYtq58kIrSPB4FpZgH2hN+aNGLbKkuZQyH5bo=; b=k1tL6Ap3RuGWy5f6I1Vi+SklCWrc7U/uDkE5WO7pYBvJelM1fEkIGtim5OUqIeId9T MfS2MjeYDMKKcle4UIkvE+25Id6FRBnmN0BqB9H3UVIzo8hQLRmSwvo2eU1yxIIvxuSu uj1182d+TRwdDs/JPaQ8zvLoowQnQck3OnYMvOEvifuEtXqF1o0+mFWtKwzgtDEoDO49 reLnKZ9573mPqJWS7xyUvF+d5eyXywTon34Uab91IKfwhB+DmpZxcuqCT/zEDb3vfSXa IPzolcEdR3YdqCyrju07gbeCJwdlwAleGSyb+wV6+0AKBrT65XHpV4NXlX4zCZLQaW5G vs8g== X-Gm-Message-State: AOAM531CHTLx8AxuClG46N0GxZM2PmM0BofuQ4OPp43JD3A/Rv1H0+cg INaL2xA0lXpz2bXAfT8RI6+C1ooh1pJb21kmxRo= X-Google-Smtp-Source: ABdhPJyU+VX+9IadV+0k10AzBObFsfDQBiaU7P1rfhQWL8ti9p7pEmStOWzeq1pHTu6LSog71mLvaJcyh7sUkWlA9Es= X-Received: by 2002:a17:90b:f84:: with SMTP id ft4mr29000703pjb.104.1623002457528; Sun, 06 Jun 2021 11:00:57 -0700 (PDT) MIME-Version: 1.0 Received: by 2002:a17:90a:aa06:0:0:0:0 with HTTP; Sun, 6 Jun 2021 11:00:57 -0700 (PDT) In-Reply-To: <83v96rgc6w.fsf@gnu.org> References: <835yyri2f2.fsf@gnu.org> <83y2bngl0b.fsf@gnu.org> <83v96rgc6w.fsf@gnu.org> From: jan Date: Sun, 6 Jun 2021 19:00:57 +0100 Message-ID: Content-Type: text/plain; charset="UTF-8" X-Spam-Score: -0.0 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) Looks like strings doing it. Go to fundamental mode (or search&replace will take forever), completely remove all strings with regex replace: ".*?" -> Save file then close and reopen emacs, reopen file, ensure it's in csharp mode, char insertion is almost back to normal. That is, remove strings entirely. Just replacing them with empty strings "" didn't help. cheers jan On 06/06/2021, Eli Zaretskii wrote: >> From: jan >> Date: Sun, 6 Jun 2021 15:53:11 +0100 >> Cc: 48871@debbugs.gnu.org >> >> 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. > > Thanks. > > Alan, can you look into this? It could be some problem in > csharp-mode, but the profiler says 97% of the time is spent in a CC > mode code, so maybe you can shed some light on this? > > I see that almost the entire 6896-line file is enclosed in a single > "namespace LDB { ... }" block, maybe this is the reason? > > Here's the main portion of a profile measured on my system from just > inserting 3 characters at BOB of the file attached by the OP. An > unoptimized build of Emacs 28 took about 2 min(!) to process those 3 > self-inserting characters. > > 8693 98% - command-execute > 8693 98% - call-interactively > 8693 98% - funcall-interactively > 8690 98% - self-insert-command > 8627 98% - c-before-change > 8627 98% - mapc > 8627 98% - # > 8627 98% - c-before-change-check-unbalanced-strings > 8611 97% c-pps-to-string-delim > 10 0% - c-syntactic-re-search-forward > 2 0% - c-beginning-of-macro > 2 0% back-to-indentation > 1 0% # > 1 0% c-clear-syn-tab > 63 0% - c-after-change > From unknown Tue Jun 17 01:48:02 2025 X-Loop: help-debbugs@gnu.org Subject: bug#48871: 27.2; Unusably slow in C# mode Resent-From: Eli Zaretskii Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sun, 06 Jun 2021 18:10:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 48871 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: To: jan Cc: acm@muc.de, 48871@debbugs.gnu.org Received: via spool by 48871-submit@debbugs.gnu.org id=B48871.16230029436809 (code B ref 48871); Sun, 06 Jun 2021 18:10:01 +0000 Received: (at 48871) by debbugs.gnu.org; 6 Jun 2021 18:09:03 +0000 Received: from localhost ([127.0.0.1]:53858 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1lpxCo-0001ll-R0 for submit@debbugs.gnu.org; Sun, 06 Jun 2021 14:09:03 -0400 Received: from eggs.gnu.org ([209.51.188.92]:57788) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1lpxCm-0001lE-0l for 48871@debbugs.gnu.org; Sun, 06 Jun 2021 14:09:00 -0400 Received: from fencepost.gnu.org ([2001:470:142:3::e]:56048) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lpxCg-0005L2-Lo; Sun, 06 Jun 2021 14:08:54 -0400 Received: from 84.94.185.95.cable.012.net.il ([84.94.185.95]:1809 helo=home-c4e4a596f7) by fencepost.gnu.org with esmtpsa (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lpxCg-00087U-5m; Sun, 06 Jun 2021 14:08:54 -0400 Date: Sun, 06 Jun 2021 21:08:54 +0300 Message-Id: <83o8cihnm1.fsf@gnu.org> From: Eli Zaretskii In-Reply-To: (message from jan on Sun, 6 Jun 2021 19:00:57 +0100) References: <835yyri2f2.fsf@gnu.org> <83y2bngl0b.fsf@gnu.org> <83v96rgc6w.fsf@gnu.org> X-Spam-Score: -2.3 (--) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -3.3 (---) > From: jan > Date: Sun, 6 Jun 2021 19:00:57 +0100 > Cc: Alan Mackenzie , 48871@debbugs.gnu.org > > Looks like strings doing it. Well, the fact that c-pps-to-string-delim is the hot spot kinda says that... From unknown Tue Jun 17 01:48:02 2025 X-Loop: help-debbugs@gnu.org Subject: bug#48871: 27.2; Unusably slow in C# mode Resent-From: jan Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sun, 06 Jun 2021 18:23:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 48871 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: To: Eli Zaretskii Cc: acm@muc.de, 48871@debbugs.gnu.org Received: via spool by 48871-submit@debbugs.gnu.org id=B48871.16230037468331 (code B ref 48871); Sun, 06 Jun 2021 18:23:02 +0000 Received: (at 48871) by debbugs.gnu.org; 6 Jun 2021 18:22:26 +0000 Received: from localhost ([127.0.0.1]:53876 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1lpxPl-0002AJ-O5 for submit@debbugs.gnu.org; Sun, 06 Jun 2021 14:22:25 -0400 Received: from mail-pg1-f179.google.com ([209.85.215.179]:41497) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1lpxPj-0002A2-RH for 48871@debbugs.gnu.org; Sun, 06 Jun 2021 14:22:25 -0400 Received: by mail-pg1-f179.google.com with SMTP id r1so12082082pgk.8 for <48871@debbugs.gnu.org>; Sun, 06 Jun 2021 11:22:23 -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=Dxuv8tk3RcJs8mX7LZ2S51RWuR8IPwGIJFJVwDXD7NA=; b=Gj3JrAQkZP7QNKUl12Okppccd5S3PAl297b0n7qsUCmOngi1rBXUzlyytj/1FnoxTs V54wKr0/O8XHbA70lQbIdq9jFOKRMEfSpfGQI7kUkVtcmZhT4Dp4t8WnqBwQ+FUWUzM/ DOqpGtCI8lWFA3owoJ5w2FwbuhwtA7QpV/1b5O9GAhYUWK1LWRSk+k+aMu5sb5cUkYwp U5uCTVcKFhslnQHUX3oplcLVWDc7q5vLI2qi2akFhhy7yw1uoZ0YI6oan2LVpuwl5S63 E+2vrqYxENUVEex4L8ULU3a0NXwo2N8UiMaYiQXTvxDWou67mx0kJ5SL8lbcvSqF9OpQ gAtg== 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=Dxuv8tk3RcJs8mX7LZ2S51RWuR8IPwGIJFJVwDXD7NA=; b=T6oqys29evioiUiZWJyg2PZsWP1ag11txB7E2dOF5PMPoHzHLrzbPQlar/1adpbOSh lfKlQDGAjJbQPTKSGw1W5I2KZJJE0ia5eEyqyO90NnR4BhSdlhShqufmrTs+B/Tb6n2b vdJOqrxxfVGmJoGcYHNohTZStAoxccJv7eUpmivF13y0qh3l/0LCwiK9mnPx3uB2XUVl Fm/s/iGSfJe/hoKp3dC/VZ6/knRMk6wCXA4lXfWVGX2eEUgFL5rSuwPlHsIg0o69H7uQ ksLPLScPIThACwBVITqWY71b8oZ8R8gB0bw3+p6YS/n8dB/DZ/ZmPce58hW4BIyfeRFg 9wwA== X-Gm-Message-State: AOAM531UqnoO9kXBHpsL1Xl+L1hyukL7ylCxRCbOQuUgF7swmZC5mJNx Ll1sdT9CnjjiFiYweu8f5AKDy+mRaLPlgBuyi2s= X-Google-Smtp-Source: ABdhPJzqEKmnpJbrxmxizWb+51u2i05GFGpZAjNyKandytkWFfZQKnu5FADc9l9/c9mQhBmvsPTKXKYP/n7lGrnZC2c= X-Received: by 2002:a62:1481:0:b029:2c1:1e90:c54 with SMTP id 123-20020a6214810000b02902c11e900c54mr13922477pfu.55.1623003738048; Sun, 06 Jun 2021 11:22:18 -0700 (PDT) MIME-Version: 1.0 Received: by 2002:a17:90a:aa06:0:0:0:0 with HTTP; Sun, 6 Jun 2021 11:22:17 -0700 (PDT) In-Reply-To: <83o8cihnm1.fsf@gnu.org> References: <835yyri2f2.fsf@gnu.org> <83y2bngl0b.fsf@gnu.org> <83v96rgc6w.fsf@gnu.org> <83o8cihnm1.fsf@gnu.org> From: jan Date: Sun, 6 Jun 2021 19:22:17 +0100 Message-ID: Content-Type: text/plain; charset="UTF-8" X-Spam-Score: -0.0 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) Ah... well... yeah... searching for "c-pps-to-string-delim" finds this , similar to what I referenced in my initial post. Neither are very optimistic. If this is a wontfix I'll understand. cheers jan On 06/06/2021, Eli Zaretskii wrote: >> From: jan >> Date: Sun, 6 Jun 2021 19:00:57 +0100 >> Cc: Alan Mackenzie , 48871@debbugs.gnu.org >> >> Looks like strings doing it. > > Well, the fact that c-pps-to-string-delim is the hot spot kinda says > that... > From unknown Tue Jun 17 01:48:02 2025 X-Loop: help-debbugs@gnu.org Subject: bug#48871: 27.2; Unusably slow in C# mode Resent-From: Alan Mackenzie Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sun, 06 Jun 2021 19:28:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 48871 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: To: jan Cc: Eli Zaretskii , 48871@debbugs.gnu.org Received: via spool by 48871-submit@debbugs.gnu.org id=B48871.162300767914347 (code B ref 48871); Sun, 06 Jun 2021 19:28:02 +0000 Received: (at 48871) by debbugs.gnu.org; 6 Jun 2021 19:27:59 +0000 Received: from localhost ([127.0.0.1]:53950 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1lpyRD-0003jG-Dq for submit@debbugs.gnu.org; Sun, 06 Jun 2021 15:27:59 -0400 Received: from colin.muc.de ([193.149.48.1]:29900 helo=mail.muc.de) by debbugs.gnu.org with smtp (Exim 4.84_2) (envelope-from ) id 1lpyRA-0003iu-T9 for 48871@debbugs.gnu.org; Sun, 06 Jun 2021 15:27:57 -0400 Received: (qmail 93307 invoked by uid 3782); 6 Jun 2021 19:27:50 -0000 Received: from acm.muc.de (p2e5d5696.dip0.t-ipconnect.de [46.93.86.150]) (using STARTTLS) by colin.muc.de (tmda-ofmipd) with ESMTP; Sun, 06 Jun 2021 21:27:49 +0200 Received: (qmail 9299 invoked by uid 1000); 6 Jun 2021 19:27:49 -0000 Date: Sun, 6 Jun 2021 19:27:49 +0000 Message-ID: References: <835yyri2f2.fsf@gnu.org> <83y2bngl0b.fsf@gnu.org> <83v96rgc6w.fsf@gnu.org> <83o8cihnm1.fsf@gnu.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: X-Submission-Agent: TMDA/1.3.x (Ph3nix) From: Alan Mackenzie X-Primary-Address: acm@muc.de X-Spam-Score: 0.0 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) Hello, Jan and Eli. On Sun, Jun 06, 2021 at 19:22:17 +0100, jan wrote: > Ah... well... yeah... > searching for "c-pps-to-string-delim" finds this > , similar to > what I referenced in my initial post. > Neither are very optimistic. If this is a wontfix I'll understand. This is indeed a string problem in CC Mode. More precisely, it's a multi-line string problem, such being started in C# mode by @". For some very bad reason (which I've got written down somewhere) CC Mode is scanning to the end of the buffer for each character inserted. Sorry. As a workaround, if you don't have any multi-line strings in your source, put the following in your csharp-mode-hook: (setq c-multiline-string-start-char nil) .. That should get rid of the excessive scanning for the time being. I've spent much of the last few weeks adapting the C++ raw string mechanism also to handle multi-line strings in other languages such as C#. I'm hoping to have it up and running soon. Then, perhaps, the C# Mode maintainer will incorporate it into C# Mode, which should be a straightforward task. > cheers > jan > On 06/06/2021, Eli Zaretskii wrote: > >> From: jan > >> Date: Sun, 6 Jun 2021 19:00:57 +0100 > >> Cc: Alan Mackenzie , 48871@debbugs.gnu.org > >> Looks like strings doing it. > > Well, the fact that c-pps-to-string-delim is the hot spot kinda says > > that... -- Alan Mackenzie (Nuremberg, Germany). From unknown Tue Jun 17 01:48:02 2025 X-Loop: help-debbugs@gnu.org Subject: bug#48871: 27.2; Unusably slow in C# mode Resent-From: jan Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Wed, 09 Jun 2021 11:07:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 48871 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: To: Alan Mackenzie Cc: Eli Zaretskii , 48871@debbugs.gnu.org Received: via spool by 48871-submit@debbugs.gnu.org id=B48871.162323681420296 (code B ref 48871); Wed, 09 Jun 2021 11:07:01 +0000 Received: (at 48871) by debbugs.gnu.org; 9 Jun 2021 11:06:54 +0000 Received: from localhost ([127.0.0.1]:60629 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1lqw2v-0005HI-NF for submit@debbugs.gnu.org; Wed, 09 Jun 2021 07:06:53 -0400 Received: from mail-pl1-f170.google.com ([209.85.214.170]:45864) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1lqw2u-0005H4-5P for 48871@debbugs.gnu.org; Wed, 09 Jun 2021 07:06:52 -0400 Received: by mail-pl1-f170.google.com with SMTP id 11so12322212plk.12 for <48871@debbugs.gnu.org>; Wed, 09 Jun 2021 04:06:52 -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=+zDOls75gtRdEVL74JEs/ywzuZmBOnrD0/TJTv+iBEk=; b=qHqOfWfkCgxtf7dpnNf4FAiQxCjfMs2RfnwA23sK7jmGXBUc0lD29jHtvrrkKWdD0R 4rEDJNWPalapZDZ5MYfHD9FcvyJKdTHXDUqs25YpKcjCOReSQVs+/LNHKXuGdulEaszf H5EORTU9VZB8Bqe4VyiX62KHJDOwBbrOKkEiSHhdWvxvOR5kOLiHe1pB/Fh39SRE06+2 XsVkqnMWGBNuoPuC1QqLFTdCHj+bxvjOah45m08zKplxDuHSggnbxCtdERsXYwQPPltW XUH3LekJa4lcJvmpD+UXIc2PCVBS4xETWoBrw6XwpIqSkv6yTzV8iJOIk/no8TETLaPd mzCw== 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=+zDOls75gtRdEVL74JEs/ywzuZmBOnrD0/TJTv+iBEk=; b=shUA630qv89CfM7uN0MogYoGe+Go7t3xzMIuIomg8Hjj+ANfrr9XAU9Zfgo3847Cbv IUofAyisSowRWJyYjGSl2LQEmy2ed6d/7tu9KnsBu8V1+N2sbOvDHPBmG/Zh6DPw4YPg GtmW3kLxUsGxJuIeT9A9HoUXyFglgv7rXrsEBl/3SUNdtQ6jST28J40V7OzwUkJcfCVQ C3r2IxUKxkxK/eWs5fMK21GfC2+JU3Ry8kjJ7YF3BcXTbb64qZ77qHsWQfy4N2Gh24l5 7g08u//HWIU0QIZ/OLVkhAL7eeseX8Tf/V9f1x2+HcG2mXN+mmBom7NS8FbOfAd8VS9N G+oQ== X-Gm-Message-State: AOAM533zi4V0CZ6Wu0jPNILbm5Bc3wKxbZ1mC6vCIZILKOv1jA5QgYPN ptNGop9g8iqbZ/Y5ce7rzPgLNeR1mCW3gzgzniA= X-Google-Smtp-Source: ABdhPJyVjMxLG06ms2c5SfOBOss2oom0rctp9fPMVj/FS2zjY/Ae3qJnl6tlRUsiNhjp6ZrYPjKxgnHVqtFAHcpYYIo= X-Received: by 2002:a17:90a:a607:: with SMTP id c7mr31440059pjq.199.1623236806309; Wed, 09 Jun 2021 04:06:46 -0700 (PDT) MIME-Version: 1.0 Received: by 2002:a17:90a:e289:0:0:0:0 with HTTP; Wed, 9 Jun 2021 04:06:45 -0700 (PDT) In-Reply-To: References: <835yyri2f2.fsf@gnu.org> <83y2bngl0b.fsf@gnu.org> <83v96rgc6w.fsf@gnu.org> <83o8cihnm1.fsf@gnu.org> From: jan Date: Wed, 9 Jun 2021 12:06:45 +0100 Message-ID: Content-Type: text/plain; charset="UTF-8" X-Spam-Score: 0.0 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -1.0 (-) I forgot to provide feedback to this list, this workaround restored performance. jan (Thanks to Alan Mackenzie for this, and his continuing work to fix the underlying problem) On 06/06/2021, Alan Mackenzie wrote: > Hello, Jan and Eli. > > On Sun, Jun 06, 2021 at 19:22:17 +0100, jan wrote: >> Ah... well... yeah... > >> searching for "c-pps-to-string-delim" finds this >> , similar to >> what I referenced in my initial post. >> Neither are very optimistic. If this is a wontfix I'll understand. > > This is indeed a string problem in CC Mode. More precisely, it's a > multi-line string problem, such being started in C# mode by @". For > some very bad reason (which I've got written down somewhere) CC Mode is > scanning to the end of the buffer for each character inserted. Sorry. > > As a workaround, if you don't have any multi-line strings in your > source, put the following in your csharp-mode-hook: > > (setq c-multiline-string-start-char nil) > > .. That should get rid of the excessive scanning for the time being. > > I've spent much of the last few weeks adapting the C++ raw string > mechanism also to handle multi-line strings in other languages such as > C#. I'm hoping to have it up and running soon. Then, perhaps, the C# > Mode maintainer will incorporate it into C# Mode, which should be a > straightforward task. > >> cheers > >> jan > > >> On 06/06/2021, Eli Zaretskii wrote: >> >> From: jan >> >> Date: Sun, 6 Jun 2021 19:00:57 +0100 >> >> Cc: Alan Mackenzie , 48871@debbugs.gnu.org > >> >> Looks like strings doing it. > >> > Well, the fact that c-pps-to-string-delim is the hot spot kinda says >> > that... > > -- > Alan Mackenzie (Nuremberg, Germany). >