[Engine-devel] UI Plugins: PoC patch revision 5 is here
by Vojtech Szocs
------=_Part_2529172_1797931071.1348259851826
Content-Type: multipart/alternative;
boundary="----=_Part_2529173_585113360.1348259851826"
------=_Part_2529173_585113360.1348259851826
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 7bit
Hi guys,
it's been a while but here comes the latest revision of UI Plugins proof-of-concept patch (please find it attached).
This revision was originally meant to focus solely on server-side components of the plugin infrastructure. However, I ended up implementing all the major concepts and ideas as discussed on engine-devel mailing list, impacting both client-side and server-side parts of the plugin infrastructure. As a result, UI plugin infrastructure should be pretty much complete now, so we can focus on specific plugin API features in upcoming PoC revisions.
There's a whole bunch of changes and improvements in this revision, so I'll try to cover all the relevant parts step by step. If you have any comments, questions or ideas, please let me know!
So here we go... (or if you just want to get the patch, find the link at the end of this message)
0. Added new Engine configuration values
UI plugin data path is represented by ConfigValues.UIPluginDataPath enum option ("UIPluginDataPath" in vdc_options table), and resolved relative to ConfigValues.DataDir if possible. Following (default) values:
* UIPluginDataPath = ui-plugins
* DataDir = /usr/share/ovirt-engine
result in UI plugin data path: /usr/share/ovirt-engine/ui-plugins
UI plugin config path is represented by ConfigValues.UIPluginConfigPath enum option ("UIPluginConfigPath" in vdc_options table), and resolved relative to ConfigValues.ConfigDir if possible. Following (default) values:
* UIPluginConfigPath = ui-plugins
* ConfigDir = /etc/ovirt-engine
result in UI plugin config path: /etc/ovirt-engine/ ui-plugins
1. Processing UI plugin data on the server
PluginDataManager is the class responsible for reading, validating and caching UI plugin descriptor/configuration data on the server (Engine). It has two main responsibilities:
* return a snapshot of currently valid plugin data ( getCurrentData method )
* reload plugin data from local file system if necessary ( reloadData method)
The reloadData method doesn't modify "live" plugin data directly. Instead, it creates a local working copy of current plugin data, updates this copy as it reads/validates plugin descriptor and configuration files, and attempts to update "live" plugin data through conditional reference re-assignment (using java.util.concurrent.atomic.AtomicReference.compareAndSet method).
In other words, reloadData method makes no attempts with regard to Java lock-based synchronization, in favor of dealing with "live" data through AtomicReference (reference that involves atomic volatile reads and writes):
* In the best case, a thread will succeed in updating "live" data ( AtomicReference.compareAndSet == true), which means that "live" data remained unchanged since this thread acquired a reference of current plugin data.
* In the worst case, a thread will NOT succeed in updating "live" data ( AtomicReference.compareAndSet == false), which means that "live" data was already changed by another thread since this thread acquired a reference of current plugin data.
In my opinion, when dealing with external resources like the local file system, this is a good compromise between performance and up-to-date data. While we might not get "completely-up-to-date" data at the given point in time ( reloadData + getCurrentData ), we are guaranteed to get "recently-up-to-date" and consistent data. In other words, the requirement of "completely-up-to-date" data would involve synchronized statements that would hurt performance. In my (very humble) opinion, the benefit of having "completely-up-to-date" data , at the cost of reduced performance, is not really worth it, especially in our case when the user can just hit refresh (F5) to reload WebAdmin and its plugin data.
Plugin descriptor files are expected to be placed in UI plugin data path , for example: /usr/share/ovirt-engine/ui-plugins/foo.json
Following descriptor file attributes are implemented and recognized by the plugin infrastructure:
* name : A name that uniquely identifies the plugin (required attribute).
* url : URL of plugin host page that invokes the plugin code (required attribute).
* config : Default configuration object associated with the plugin (optional attribute).
* resourcePath : Path to plugin static resources, relative to UI plugin data path (optional attribute). This is used when serving plugin files through Engine PluginResourceServlet (more on this below).
Plugin configuration files are expected to be placed in UI plugin config path, for example: /etc/engine/ui-plugins/foo-config.json
Note that plugin configuration files follow the "<descriptorFileName>-config.json" convention.
Following configuration file attributes are implemented and recognized by the plugin infrastructure:
* config : Custom configuration object associated with the plugin (optional attribute). This overrides the default plugin descriptor configuration, if any.
* enabled : Indicates whether the plugin should be loaded on WebAdmin startup (optional attribute). Default value is 'true'.
* order : Defines the relative order in which the plugin will be loaded on WebAdmin startup (optional attribute). Default value is Integer.MAX_VALUE (lowest order).
The concept of merging custom configuration ( config attribute in foo-config.json ), if any, on top of default configuration ( config attribute in foo.json ), if any, remains unchanged. This makes the plugin configuration quite flexible - in my opinion, the added complexity of handling/merging such configuration is definitely worth the effort.
The enabled attribute is straight-forward, allowing users to turn the given plugin off, if necessary. In future, users should still be able to load such plugins through WebAdmin GUI.
The order attribute controls the order in which plugins are loaded on WebAdmin startup. Since plugin resources are fetched asynchronously by the browser, this is basically a way of imposing some degree of determinism in the "generally-non-deterministic" plugin environment, which is helpful when troubleshooting problems with multiple plugins. This attribute is also helpful due to file listing methods in java.io.File giving no guarantees that files would be listed in any particular order (otherwise we could just go for the "NN-<descriptorFileName>.json" convention, with NN being the order number).
2. Modified behavior of WebadminDynamicHostingServlet
WebadminDynamicHostingServlet is the servlet used to serve WebAdmin application host page (HTML page that bootstraps WebAdmin JavaScript code).
In addition to its former behavior, as part of handling the given request, WebadminDynamicHostingServlet :
* reloads descriptor/configuration data from local file system if necessary, and obtains a snapshot of currently valid plugin data ( PluginDataManager.reloadAndGetCurrentData )
* embeds all plugin meta-data, suitable for use in client-side plugin infrastructure , into WebAdmin host page as "pluginDefinitions" JavaScript a rray ( PluginDefinitions )
As a result, reloading UI plugin descriptor/configuration data is as simple as refreshing (F5) WebAdmin application in the browser (no need to restart Engine).
3. Added servlet for serving plugin static resources
PluginResourceServlet is the servlet used to serve UI plugin static files (plugin host page, 3rd party JavaScript, etc.) from the local file system.
For example, requesting URL:
* http://<EngineManagerHost>:8700/webadmin/webadmin/plugin/foo/content/start.html
will send the content of:
* /usr/share/ovirt-engine/ui-plugins/<resourcePath>/ content/start.html
to the client.
As shown in the above example:
* /webadmin/webadmin/plugin/ is the servlet root path for PluginResourceServlet
* in the extra path beyond the servlet root path ( /foo/content/start.html ):
* /foo represents the name of the plugin
* /content/start.html represents the path to requested resource, relative to " UIPluginDataPath / < resourcePath >"
Note that each plugin using PluginResourceServlet to serve its static files must declare non-empty resourcePath attribute in within the plugin descriptor.
Also note that PluginResourceServlet , unlike WebadminDynamicHostingServlet , does NOT reload descriptor/configuration data from local file system as part of handling the given request. In other words, it's assumed that plugin data has already been (re)loaded when serving WebAdmin application host page, with subsequent requests to PluginResourceServlet reading the current plugin information.
Until we solve the cross-origin issue in a clean way, PluginResourceServlet should be used to serve all plugin resources from local file system.
4. Plugin lifecycle improved to deal with misbehaving plugins
PluginState enum has been modified to deal with plugins that allow uncaught exceptions to escape from plugin event handler functions (e.g. "UiInit"):
* removed state INITIALIZED
* added state INITIALIZING : The plugin is (currently) being initialized by calling UiInit event handler function.
* added state IN_USE : Plugin's UiInit event handler function has completed successfully, we can now call other event handler functions as necessary. The plugin is in use now.
* added state FAILED : An uncaught exception escaped while calling an event handler function, which indicates internal error within the plugin code. The plugin is removed from service.
I've attached a simple state diagram that illustrates different states and transitions between them (green color is initial state, red color is end state).
Uncaught exceptions in plugin event handler functions will be caught and handled by the plugin infrastructure. This prevents a misbehaving plugin from breaking WebAdmin application, since WebAdmin is the caller (initiator) of the function call. In such case, the plugin will be removed from service.
Update on cross-origin issue (consequence of same-origin policy)
In order for the plugin to access WebAdmin plugin API, plugin host page (e.g. start.html ) must be served from URL on same origin as Engine origin. Otherwise, plugin code running in the context of an iframe'd host page will fail to evaluate "parent.pluginApi" expression, with "parent" being top-level (WebAdmin) window, and "pluginApi" being the global plugin API object exposed by WebAdmin.
This is why PluginResourceServlet , available on Engine origin, should be used to serve all plugin resources from local file system.
There's only one issue that remains to be solved: cross-origin "plugin vs. remote service" communication, with "remote service" being anything other than Engine (REST API). In future, we'll address this with Apache reverse proxy configuration, so that users can configure Apache server (placed in front of Engine JBoss AS) to put arbitrary (local or remote non-Engine) services on same origin. However, this requires a change in current Apache configuration. Until then, users can manually edit the Engine Apache configuration file ( /etc/httpd/conf.d/ovirt-engine.conf ).
I've attached some sample plugin files for you to experiment with. Instead of attaching actual patch file (92 kB) to this email, I've submitted the patch to oVirt Gerrit: http://gerrit.ovirt.org/8120
Let me know what you think!
Cheers,
Vojtech
------=_Part_2529173_585113360.1348259851826
Content-Type: text/html; charset=utf-8
Content-Transfer-Encoding: quoted-printable
<html><head><style type=3D'text/css'>p { margin: 0; }</style></head><body><=
div style=3D'font-family: times new roman,new york,times,serif; font-size: =
12pt; color: #000000'>Hi guys,<br><br>it's been a while but here comes the=
latest revision of UI Plugins proof-of-concept patch (please find it attac=
hed).<br><br>This revision was originally meant to focus solely on server-s=
ide components of the plugin infrastructure. However, I ended up implementi=
ng all the major concepts and ideas as discussed on engine-devel mailing li=
st, impacting both client-side and server-side parts of the plugin infrastr=
ucture. As a result, UI plugin infrastructure should be pretty much complet=
e now, so we can focus on specific plugin API features in upcoming PoC rev=
isions.<br><br>There's a whole bunch of changes and improvements in this re=
vision, so I'll try to cover all the relevant parts step by step. If you ha=
ve any comments, questions or ideas, please let me know!<br><br>So here we =
go... (or if you just want to get the patch, find the link at the end of th=
is message)<br><br><hr style=3D"width: 100%; height: 2px;"><br><strong>0. A=
dded new Engine configuration values</strong><br style=3D"font-weight: bold=
;"><br><u>UI plugin data path</u> is represented by <em>ConfigValues.UIPlug=
inDataPath</em> enum option ("UIPluginDataPath" in <span style=3D"font-styl=
e: italic;">vdc_options</span> table), and resolved relative to <span style=
=3D"font-style: italic;">ConfigValues.DataDir</span> if possible. Following=
(default) values:<br><ul><li><span style=3D"font-style: italic;">UIPluginD=
ataPath =3D ui-plugins</span></li><li><span style=3D"font-style: italic;">D=
ataDir =3D /usr/share/ovirt-engine<br></span></li></ul>result in UI plugin =
data path: <span style=3D"font-style: italic;">/usr/share/ovirt-engine/ui-p=
lugins</span><br><br><span style=3D"text-decoration: underline;">UI plugin =
config path</span> is represented by <span style=3D"font-style: italic;">Co=
nfigValues.UIPluginConfigPath</span> enum option ("UIPluginConfigPath" in <=
span style=3D"font-style: italic;">vdc_options</span> table), and resolved =
relative to <span style=3D"font-style: italic;">ConfigValues.ConfigDir</spa=
n> if possible. Following (default) values:<br><ul><li><span style=3D"font-=
style: italic;">UIPluginConfigPath =3D ui-plugins</span></li><li><span styl=
e=3D"font-style: italic;">ConfigDir =3D /etc/ovirt-engine</span></li></ul><=
p>result in UI plugin config path: <span style=3D"font-style: italic;">/etc=
/ovirt-engine/</span><span style=3D"font-style: italic;">ui-plugins</span><=
/p><br><span style=3D"font-weight: bold;">1. Processing UI plugin data on t=
he server</span><br style=3D"font-weight: bold;"><br><span style=3D"font-st=
yle: italic;">PluginDataManager</span> is the class responsible for reading=
, validating and caching UI plugin descriptor/configuration data on the ser=
ver (Engine). It has two main responsibilities:<br><ul><li>return a snapsho=
t of currently valid plugin data (<span style=3D"font-style: italic;">getCu=
rrentData</span> method)<br></li><li>reload plugin data from local file sys=
tem if necessary (<span style=3D"font-style: italic;">reloadData</span> met=
hod)</li></ul><p></p><p>The <span style=3D"font-style: italic;">reloadData<=
/span> method doesn't modify "live" plugin data directly. Instead, it creat=
es a local working copy of current plugin data, updates this copy as it rea=
ds/validates plugin descriptor and configuration files, and attempts to upd=
ate "live" plugin data through conditional reference re-assignment (using <=
span style=3D"font-style: italic;">java.util.concurrent.atomic.AtomicRefere=
nce.compareAndSet</span> method).</p><p><br></p><p>In other words, <span st=
yle=3D"font-style: italic;">reloadData</span> method makes no attempts with=
regard to Java lock-based synchronization, in favor of dealing with "live"=
data through <span style=3D"font-style: italic;">AtomicReference</span> (r=
eference that involves atomic <span style=3D"font-style: italic;">volatile<=
/span> reads and writes):</p><ul><li> In the best case, a thread will succe=
ed in updating "live" data (<span style=3D"font-style: italic;">AtomicRefer=
ence.compareAndSet</span> =3D=3D true), which means that "live" data remain=
ed unchanged since this thread acquired a reference of current plugin data.=
</li><li>In the worst case, a thread will NOT succeed in updating "live" da=
ta (<span style=3D"font-style: italic;">AtomicReference.compareAndSet</span=
> =3D=3D false), which means that "live" data was already changed by anothe=
r thread since this thread acquired a reference of current plugin data.</li=
></ul><p>In my opinion, when dealing with external resources like the local=
file system, this is a good compromise between performance and up-to-date =
data. While we might not get "completely-up-to-date" data at the given poin=
t in time (<span style=3D"font-style: italic;">reloadData + </span><span st=
yle=3D"font-style: italic;">getCurrentData</span>), we are guaranteed to ge=
t "recently-up-to-date" and consistent data. In other words, the requiremen=
t of "completely-up-to-date" data would involve <span style=3D"font-style: =
italic;">synchronized</span> statements that would hurt performance. In my =
(very humble) opinion, the benefit of having "completely-up-to-date" data,=
at the cost of reduced performance, is not really worth it, especially in =
our case when the user can just hit refresh (F5) to reload WebAdmin and its=
plugin data.<br></p><p><br></p><p><span style=3D"text-decoration: underlin=
e;">Plugin descriptor files</span> are expected to be placed in UI plugin d=
ata path, for example: <span style=3D"font-style: italic;">/usr/share/ovirt=
-engine/ui-plugins/foo.json</span></p><p><br></p><p>Following descriptor fi=
le attributes are implemented and recognized by the plugin infrastructure:<=
/p><ul><li><span style=3D"font-style: italic;">name</span>: A name that uni=
quely identifies the plugin (required attribute).</li><li><span style=3D"fo=
nt-style: italic;">url</span>: URL of plugin host page that invokes the plu=
gin code (required attribute).</li><li><span style=3D"font-style: italic;">=
config</span>: Default configuration object associated with the plugin (opt=
ional attribute).</li><li><span style=3D"font-style: italic;">resourcePath<=
/span>: Path to plugin static resources, relative to UI plugin data path (o=
ptional attribute). This is used when serving plugin files through Engine <=
span style=3D"font-style: italic;">PluginResourceServlet</span> (more on th=
is below).<br></li></ul><p></p><p><span style=3D"text-decoration: underline=
;">Plugin configuration files</span> are expected to be placed in UI plugin=
config path, for example: <span style=3D"font-style: italic;">/etc/engine/=
ui-plugins/foo-config.json</span><br></p><p><br></p><p>Note that plugin con=
figuration files follow the "<descriptorFileName>-config.json" conven=
tion.</p><p><br></p><p>Following configuration file attributes are implemen=
ted and recognized by the plugin infrastructure:</p><ul><li><span style=3D"=
font-style: italic;">config</span>: Custom configuration object associated =
with the plugin (optional attribute). This overrides the default plugin des=
criptor configuration, if any.</li><li><span style=3D"font-style: italic;">=
enabled</span>: Indicates whether the plugin should be loaded on WebAdmin s=
tartup (optional attribute). Default value is 'true'.</li><li><span style=
=3D"font-style: italic;">order</span>: Defines the relative order in which =
the plugin will be loaded on WebAdmin startup (optional attribute). Default=
value is <span style=3D"font-style: italic;">Integer.MAX_VALUE</span> (low=
est order).</li></ul><p>The concept of merging custom configuration (<span =
style=3D"font-style: italic;">config</span> attribute in <span style=3D"fon=
t-style: italic;">foo-config.json</span>), if any, on top of default config=
uration (<span style=3D"font-style: italic;">config</span> attribute in <sp=
an style=3D"font-style: italic;">foo.json</span>), if any, remains unchange=
d. This makes the plugin configuration quite flexible - in my opinion, the =
added complexity of handling/merging such configuration is definitely worth=
the effort.<br></p><p><br></p><p>The <span style=3D"font-style: italic;">e=
nabled</span> attribute is straight-forward, allowing users to turn the giv=
en plugin off, if necessary. In future, users should still be able to load =
such plugins through WebAdmin GUI.<br></p><p><br></p><p>The <span style=3D"=
font-style: italic;">order</span> attribute controls the order in which plu=
gins are loaded on WebAdmin startup. Since plugin resources are fetched asy=
nchronously by the browser, this is basically a way of imposing some degree=
of determinism in the "generally-non-deterministic" plugin environment, wh=
ich is helpful when troubleshooting problems with multiple plugins. This at=
tribute is also helpful due to file listing methods in <span style=3D"font-=
style: italic;">java.io.File</span> giving no guarantees that files would b=
e listed in any particular order (otherwise we could just go for the "NN-&l=
t;descriptorFileName>.json" convention, with NN being the order number).=
<br></p><br><span style=3D"font-weight: bold;">2. Modified behavior of Weba=
dminDynamicHostingServlet</span><br style=3D"font-weight: bold;"><br><span =
style=3D"font-style: italic;">WebadminDynamicHostingServlet</span> is the s=
ervlet used to serve WebAdmin application host page (HTML page that bootstr=
aps WebAdmin JavaScript code).<br><br>In addition to its former behavior, a=
s part of handling the given request, <span style=3D"font-style: italic;">W=
ebadminDynamicHostingServlet</span>:<br><ul><li><span style=3D"font-style: =
italic;"></span>reloads descriptor/configuration data from local file syste=
m if necessary, and obtains a snapshot of currently valid plugin data (<spa=
n style=3D"font-style: italic;">PluginDataManager.reloadAndGetCurrentData</=
span>)</li><li>embeds all plugin meta-data, suitable for use in client-side=
plugin infrastructure, into WebAdmin host page as "pluginDefinitions" Java=
Script array (<span style=3D"font-style: italic;">PluginDefinitions</span>)=
<br></li></ul>As a result, reloading UI plugin descriptor/configuration dat=
a is as simple as refreshing (F5) WebAdmin application in the browser (no n=
eed to restart Engine).<br><br><span style=3D"font-weight: bold;">3. Added =
servlet for serving plugin static resources</span><br style=3D"font-weight:=
bold;"><br><span style=3D"font-style: italic;">PluginResourceServlet</span=
> is the servlet used to serve UI plugin static files (plugin host page, 3r=
d party JavaScript, etc.) from the local file system.<br><br>For example, r=
equesting URL:<br><ul><li><span style=3D"font-style: italic;">http://<En=
gineManagerHost>:8700/webadmin/webadmin/plugin/foo/content/start.html</s=
pan></li></ul><p>will send the content of:</p><ul><li><span style=3D"font-s=
tyle: italic;">/usr/share/ovirt-engine/ui-plugins/<resourcePath>/</sp=
an><span style=3D"font-style: italic;">content/start.html</span></li></ul><=
p>to the client.</p><p><br></p><p>As shown in the above example:</p><ul><li=
><span style=3D"font-style: italic;">/webadmin/webadmin/plugin/</span> is t=
he servlet root path for <span style=3D"font-style: italic;">PluginResource=
Servlet</span><br></li><li>in the extra path beyond the servlet root path (=
<span style=3D"font-style: italic;">/foo/content/start.html</span>):<span s=
tyle=3D"white-space:pre"></span></li><ul><li><span style=3D"font-style: ita=
lic;">/foo</span> represents the name of the plugin</li><li><span style=3D"=
font-style: italic;">/content/start.html</span> represents the path to requ=
ested resource, relative to "UIPluginDataPath / <resourcePath>"<br></=
li></ul></ul>Note that each plugin using <span style=3D"font-style: italic;=
">PluginResourceServlet</span> to serve its static files must declare non-e=
mpty <span style=3D"font-style: italic;">resourcePath</span> attribute in w=
ithin the plugin descriptor.<br><br>Also note that <span style=3D"font-styl=
e: italic;">PluginResourceServlet</span>, unlike <span style=3D"font-style:=
italic;">WebadminDynamicHostingServlet</span>, does NOT reload descriptor/=
configuration data from local file system as part of handling the given req=
uest. In other words, it's assumed that plugin data has already been (re)lo=
aded when serving WebAdmin application host page, with subsequent requests =
to <span style=3D"font-style: italic;">PluginResourceServlet</span> reading=
the current plugin information.<br><br>Until we solve the cross-origin iss=
ue in a clean way, <span style=3D"font-style: italic;">PluginResourceServle=
t</span> should be used to serve all plugin resources from local file syste=
m.<br><br><span style=3D"font-weight: bold;">4. Plugin lifecycle improved t=
o deal with misbehaving plugins</span><br><br><span style=3D"font-style: it=
alic;">PluginState</span> enum has been modified to deal with plugins that =
allow uncaught exceptions to escape from plugin event handler functions (e.=
g. "UiInit"):<br><ul><li>removed state <span style=3D"font-style: italic;">=
INITIALIZED</span></li><li>added state <span style=3D"font-style: italic;">=
INITIALIZING</span>: The plugin is (currently) being initialized by calling=
UiInit event handler function.</li><li>added state <span style=3D"font-sty=
le: italic;">IN_USE</span>: Plugin's UiInit event handler function has comp=
leted successfully, we can now call other event handler functions as necess=
ary. The plugin is in use now.</li><li>added state <span style=3D"font-styl=
e: italic;">FAILED</span>: An uncaught exception escaped while calling an e=
vent handler function, which indicates internal error within the plugin cod=
e. The plugin is removed from service.<br></li></ul>I've attached a simple =
state diagram that illustrates different states and transitions between the=
m (green color is initial state, red color is end state).<br><br>Uncaught e=
xceptions in plugin event handler functions will be caught and handled by t=
he plugin infrastructure. This prevents a misbehaving plugin from breaking =
WebAdmin application, since WebAdmin is the caller (initiator) of the funct=
ion call. In such case, the plugin will be removed from service.<br><br><sp=
an style=3D"font-weight: bold;">Update on cross-origin issue (consequence o=
f same-origin policy)</span><br><br>In order for the plugin to access WebAd=
min plugin API, plugin host page (e.g. <span style=3D"font-style: italic;">=
start.html</span>) must be served from URL on same origin as Engine origin.=
Otherwise, plugin code running in the context of an iframe'd host page wil=
l fail to evaluate "parent.pluginApi" expression, with "parent" being top-l=
evel (WebAdmin) window, and "pluginApi" being the global plugin API object =
exposed by WebAdmin.<br><br>This is why <span style=3D"font-style: italic;"=
>PluginResourceServlet</span>, available on Engine origin, should be used t=
o serve all plugin resources from local file system.<br><br>There's only on=
e issue that remains to be solved: cross-origin "plugin vs. remote service"=
communication, with "remote service" being anything other than Engine (RES=
T API). In future, we'll address this with Apache reverse proxy configurati=
on, so that users can configure Apache server (placed in front of Engine JB=
oss AS) to put arbitrary (local or remote non-Engine) services on same orig=
in. However, this requires a change in current Apache configuration. Until =
then, users can manually edit the Engine Apache configuration file (<span s=
tyle=3D"font-style: italic;">/etc/httpd/conf.d/ovirt-engine.conf</span>).<b=
r><br><span style=3D"font-weight: bold;"></span><hr style=3D"width: 100%; h=
eight: 2px;"><br>I've attached some sample plugin files for you to experime=
nt with. Instead of attaching actual patch file (92 kB) to this email, I've=
submitted the patch to oVirt Gerrit: http://gerrit.ovirt.org/8120<br><br>L=
et me know what you think!<br><br>Cheers,<br>Vojtech<br><br></div></body></=
html>
------=_Part_2529173_585113360.1348259851826--
------=_Part_2529172_1797931071.1348259851826
Content-Type: application/x-compressed-tar;
name=ui-plugin-sample-files.tar.gz
Content-Disposition: attachment; filename=ui-plugin-sample-files.tar.gz
Content-Transfer-Encoding: base64
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
------=_Part_2529172_1797931071.1348259851826
Content-Type: image/png; name=ui-plugin-lifecycle.png
Content-Disposition: attachment; filename=ui-plugin-lifecycle.png
Content-Transfer-Encoding: base64
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
hNBWMKGVGApNRM+5wMXNkx6Bi5GyhcLsZC4urk5HrV69Oj8/f8OGDampqWgr+q+VsLKyGgpNRM+5
ICQsnBTmi32CHUT7eY4cObL7tiIrK8vQ0NDT01NQUJDN24qTJ07oaWlxcHBQBghJScnQ0FDKgCIk
KGhiYvL48eNP3To9XOfD917ArOmOh+7mDJeWxzuThXJSo39yNb9w4cKiRT3fgNPf39/V1fX9+/fj
x48/fvy4oaEhW63L27y8xbNmhSclSQsKLtLRMZeTs1ZS4uXkxFbuQyU1NUHZ2U/y8m5mZtLq6pY4
O3teuNBnuUAIkZCSptFoOy/FSytpotyssnGSsPgwsby8vN4/xdXV1cvLi06nb9q0iX2+B+V/6dL8
lStrGxpOOTq6jB2LLcsEq/z8ziYkCAoK3rx1y9bWtm9yITw83MraWlxG6cDtlygxS3hssEuOeHD/
/v1ebtRWGRkZS5cujYuLExEROXfuXPdXGWGCx5cv2yxdKiMkdNvJSV9aGluWecdoFRV6p07R6utj
Y2P19PT6IBcIIalpGbo6Y5R1zda6+/ELiqLKzOS5beazkDtubm67d+/+zP+i/2krTE1N3d3dWdZW
0GjCUlLD+PhyN2zAZmVB+evqpH/5RUJKKu/Nmx4n7tX3F7THaK5bt+51atQWWymfP7ajxMyR9tR/
i83wuLB733777WeHAiHEwcGhsLBw9erVMTExJiYmW7duZcHK0OlOtrZVDQ1/Tp2KLcsSory83l99
lV9QMGPGjL45Xvgn7mnTZ3719HG4uLScntUcRa3xaoaWgqLiqHhfvn2amjJjH77PSoy+d+Ft3qth
w4bdvHlz4sSJffLirW2FmJjYmTNnmNlW5AUHK9nbz9XSujZnDrYyC20MCvrt2bO0tDRNTc2+yYW/
D2s9PX/66ac3b/JraqopFFy2vF9QqVQpKanZs2f//vvvff7i/v7+ixcvLisrGzt2rIeHB3PaCmdz
c/+EhNJt27BxWU7wyJGp06bduHGjL3MBBoetW7f++uuvVCp1+/bt+/fv7+8mQkJY2EZJ6crs2ag8
y824eTOqqKi4uPhLzy/A4HP06NGoqChNTU03NzcpKSl///78tntp6Yfq6mmqqig7Oxg7YkQ3N8tB
Lgx1hoaGSUlJt27dqq+vnzZtmpGRUUZGRj/1RYSQcd1+WROYZv6YMT1vMZRpiJs1a1ZZWdl3332X
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
YKD5P2BJEIkFxk/7AAAAAElFTkSuQmCC
------=_Part_2529172_1797931071.1348259851826--
12 years, 3 months
[Engine-devel] Duplicities in tranlations
by David Jaša
Hi,
given that my language is not yet included in language set in Zanata
(why?), I've had a look at existing translation - and I noticed
non-negligible number of duplicities in the translation: for example,
just trio of "Create", "Delete" and "Edit Properties" was repeated six
times on the first page of LocalizedEnums!
This is a recipe for translater frutration at best and translation
errors at worst. Can there be some guideline and effort to limit
proliferation of new strings by reusing existing ones?
David
--
David Jaša, RHCE
SPICE QE based in Brno
GPG Key: 22C33E24
Fingerprint: 513A 060B D1B4 2A72 7F0D 0278 B125 CD00 22C3 3E24
12 years, 3 months
Re: [Engine-devel] [Users] base url of ovirt
by Juan Hernandez
Copying engine-devel, as I think this is something we should discuss and
maybe do.
On 09/18/2012 10:50 PM, Jon Thomas wrote:
> Is there some config in the engine to set up the web interface base url
> so that instead of https://localhost.localdomain/ it is
> https://localhost.localdomain/ovirt ?
No, there is no such config.
I think this should be the default, I mean, we should have this /ovirt
prefix in all our URLs, to make coexistence with other users of the web
server easy.
--
Dirección Comercial: C/Jose Bardasano Baos, 9, Edif. Gorbea 3, planta
3ºD, 28016 Madrid, Spain
Inscrita en el Reg. Mercantil de Madrid – C.I.F. B82657941 - Red Hat S.L.
12 years, 3 months
[Engine-devel] ovirt-cli 3.2.0.3 - important changes
by Michael Pasternak
Two commands renamed:
--------------------
- "create" command renamed with "add" #855773.
- "delete" command renamed with "remove" #855769.
Changed authentication procedure:
--------------------------------
- added username/password prompt/conf-file functionality (see [1] for more details).
[1] http://wiki.ovirt.org/wiki/CLI#Connect
* For complete list of changes, see change log.
--
Michael Pasternak
RedHat, ENG-Virtualization R&D
12 years, 3 months
[Engine-devel] Upstream git repo hung
by Dhandapani
This is a multi-part message in MIME format.
--------------050104080601090706000007
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit
I got,
/fatal: The remote end hung up unexpectedly/
--
Regards,
Dhandapani
--------------050104080601090706000007
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
</head>
<body bgcolor="#FFFFFF" text="#000000">
<tt>I got, <br>
</tt><tt><i>fatal: The remote end hung up unexpectedly</i></tt><tt><br>
</tt><tt><br>
</tt><tt>--</tt><tt><br>
</tt><tt>Regards,</tt><tt><br>
</tt><tt>Dhandapani</tt><tt><br>
</tt>
</body>
</html>
--------------050104080601090706000007--
12 years, 3 months
[Engine-devel] gwt error with nightly engine builds and IE8/9
by Dead Horse
I have been seeing this issue with the latest nightly engine builds for
quite a few weeks now with Internet Explorer Version 8 and 9.
ERROR: Possible problem with your *.gwt.xml module file.
The compile time user.agent value (gecko1_8) does not match the runtime
user.agent value (ie9). Expect more errors.
Is this a known issue?
- DHC
12 years, 3 months
[Engine-devel] oVirt Workshop Europe 2012: Call For Participation
by workshop-pc@ovirt.org
=================================================================
oVirt Workshop Europe 2012: Call For Participation
November 7-9, 2012 - Hotel Fira Palace - Barcelona, Spain
(All submissions must be received before midnight Sep 14th, 2012)
=================================================================
The oVirt Project is an open virtualization project for anyone who cares
about Linux-based KVM virtualization. Providing a feature-rich server
virtualization management system with advanced capabilities for hosts
and guests, including high availability, live migration, storage
management, system scheduler, and more. By open we mean open source &
open governance, done right.
During this workshop you’ll learn about the technical background and
direction of the oVirt project. You’ll meet the developers, and have an
opportunity to see and dive into the code right away. The workshop is
open to all who want to use, get involved with, or learn about the
comprehensive open virtualization management platform, oVirt. The
sessions cover the technical projects details, governance, getting
involved, usage, and much more. If you have any interest in an Open
Virtualization Management platform, this workshop is for you!
We are excited to announce that this oVirt Workshop will be held in
conjunction with the KVM Forum.
http://events.linuxfoundation.org/events/kvm-forum/
The KVM Forum and oVirt Workshop are co-located with the Linux
Foundation's 2012 LinuxCon Europe in Barcelona, Spain.
oVirt Workshop attendees will be able to attend KVM Forum sessions and
are eligible to attend LinuxCon Europe for a discounted rate.
http://events.linuxfoundation.org/events/kvm-forum/register
We invite you to lead part of the discussion by submitting a speaking
proposal for oVirt Workshop 2012.
http://events.linuxfoundation.org/cfp
Suggested topics:
- community use case/stories
- roadmaps
- deep dives into features/areas
- deep dives into code/debugging/tuning
- integration and extensions
- components: engine, vdsm, node, sdk/cli, reports, mom, guest agent, etc.
- subjects: network, storage, vm life cycle, scheduling & sla, gluster, etc.
- packaging, installation and distributions
- community infrastructure and services
SUBMISSION REQUIREMENTS
Abstracts due: Sep 14th, 2012
Notification: Sep 28th, 2012
Please submit a short abstract (~150 words) describing your presentation
proposal. In your submission please note how long your talk will take.
Slots vary in length up to 45 minutes. Also include in your proposal
the proposal type -- one of:
- technical talk
- end-user talk
- birds of a feather (BOF) session
Submit your proposal here:
http://events.linuxfoundation.org/cfp
You will receive a notification whether or not your presentation proposal
was accepted by Sep 14th.
END-USER COLLABORATION
One of the big challenges as developers is to know what, where and how
people actually use our software. We will reserve a few slots for end
users talking about their deployment challenges and achievements.
If you are using oVirt in production you are encouraged submit a speaking
proposal. Simply mark it as an end-user collaboration proposal. As an
end user, this is a unique opportunity to get your input to developers.
BOF SESSION
We will reserve some slots in the evening after the main conference
tracks, for birds of a feather (BOF) sessions. These sessions will be
less formal than presentation tracks and targetted for people who would
like to discuss specific issues with other developers and/or users.
If you are interested in getting developers and/or uses together to
discuss a specific problem, please submit a BOF proposal.
LIGHTNING TALKS
In addition to submitted talks we will also have some room for lightning
talks. These are short (5 minute) discussions to highlight new work or
ideas that aren't complete enough to warrant a full presentation slot.
Lightning talk submissions and scheduling will be handled on-site at
oVirt Workshop.
HOTEL / TRAVEL
The oVirt Workshop Europe 2012 will be held in Barcelona, Spain at the
Hotel Fira Palace.
http://events.linuxfoundation.org/events/kvm-forum/hotel
Thank you for your interest in oVirt. We're looking forward to your
submissions and seeing you at the oVirt Workshop Europe 2012 in November!
Thanks,
your oVirt Workshop Europe 2012 Program Commitee
Please contact us with any questions or comments.
workshop-pc(a)ovirt.org
12 years, 3 months
[Engine-devel] [RFC] ovirt-engine - vdc_config default options
by Alon Bar-Lev
Hello All,
I would like to discuss the method we use to manage default options. I believe it can be significantly simplified.
Please read though and comment.
Thank you,
Alon Bar-Lev
---
CURRENT STATE
Most options are located in three different locations.
Let's explain by example... The FenceQuietTimeBetweenOperationsInSec option.
---
ConfigValues.java
---
public enum ConfigValues {
<snip>
@Reloadable
@TypeConverterAttribute(Integer.class)
@DefaultValueAttribute("180")
FenceQuietTimeBetweenOperationsInSec(30),
<snip>
}
---
---
0000_config.sql
---
<snip>
select fn_db_add_config_value('FenceQuietTimeBetweenOperationsInSec','180','general');
<snip>
---
---
engine-config.properties
---
<snip>
FenceQuietTimeBetweenOperationsInSec.type=Integer
FenceQuietTimeBetweenOperationsInSec.validValues=60..600
FenceQuietTimeBetweenOperationsInSec.description="Fence quiet time between operations (in seconds)"
FenceQuietTimeBetweenOperationsInSec.alternateKey=Fence_Quiet_Time
<snip>
---
ConfigValues.java is the base, it defines all options and appropriate metadata as annotations. It defines the option name, type, default value, and if reloadable.
0000_config.sql adds all parameters into the database using their default value, we actually duplicate the parameter name and default value into the sql script. Please note that even if we do not add the parameter to the database the engine infrastructure will use the default value specify at ConfigValues.
engine-config.properties is used as an interface to engine-config utility, a command-line utility that can manipulate engine options. engine-config manages only options that are specified in this property files. Property files specifies user friendly description, valid values, alias, but duplicate the option name and type that already specified in ConfigValues. engine-config will only manage options that exists in database.
QUESTIONS
1. Why do we store default values in database?
>From what I managed to gather, we store default values in database under the assumption that we need to keep defaults when we upgrade from one version to another.
However, in most cases when upgrading an application the new defaults should apply as long as they were not overridden by user. Keeping old default as a new value is an exception that can be taken care of during the upgrade process for selected options.
2. Why do we keep properties file?
In practice we could specify the metadata within the property files as annotations in ConfigValues.java. So why do we actually need the properties file?
>From what I managed to gather, we use the property file as an interface to support personal, to allow adding/removing options exposed to the engine-config utility. An addition of option to the property file exposes it.
SUGGESTED STATE
Establish a single place to manage options.
Do not store default values in database.
Provide alternate method of exposing internal options to engine-config utility.
---
ConfigValues.java
---
public enum ConfigValues {
<snip>
@Reloadable
@Public
@TypeConverterAttribute(Integer.class)
@Restriction.IntegerRange(60, 600)
@DefaultValueAttribute("180")
@Description("Fence quiet time between operations (in seconds)")
FenceQuietTimeBetweenOperationsInSec(30),
<snip>
}
---
BENEFITS
No duplication of option name, type, default value, etc... between multiple files. One place to role them all.
Simpler upgrade sequence, in most cases as we do want the new defaults to apply.
METHOD
1. Add @Public annotation for ConfigValues, to expose options to engine-config instead of the properties file.
2. Add @Restrict annotation for ConfigValues, instead of validValues of properties file.
3. Add @Description annotation for ConfigValues, instead of description of properties file.
4. Add engine-config --internal parameter to allow get/set/list of none @Public option, instead of the need to update the properties file.
5. Modify enigne-config [set] to add option if does not exist in database and does not match default value.
6. Modify engine-config [set] to delete option if value matches default value.
7. Modify engine-config [get] to retrieve default from ConfigValues if value is missing from database.
8. Create upgrade script which deletes all options with value that matches the default from the database.
IMPLICATIONS
The option alias is removed. Can be added at later time if required using own @Alias annotation. Not sure it is actually required.
12 years, 3 months
[Engine-devel] Update on UI Plugins: PoC patch revision 4
by Vojtech Szocs
------=_Part_15477537_1702327251.1346339532819
Content-Type: multipart/alternative;
boundary="----=_Part_15477538_89478576.1346339532819"
------=_Part_15477538_89478576.1346339532819
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 7bit
Hello everyone,
as a follow-up to my last email on improving plugin API, here comes the latest revision of UI Plugins proof-of-concept patch (please find it attached).
This patch is focused on improving JavaScript plugin API, along with important changes and improvements made to plugin infrastructure ( PluginManager ). Let's walk through the changes step by step.
Improved plugin API, taking some inspiration from jQuery
Following is a sample plugin code that uses new plugin API:
var myPlugin = pluginApi('myPlugin'); // Obtain plugin API instance for 'myPlugin'
var myPluginConfig = myPlugin.configObject(); // Obtain plugin-specific configuration
// Register event handler functions to be invoked by WebAdmin
// Note: all functions are optional, the plugin only defines functions for events it wants to handle
myPlugin.register({
UiInit: function() {
var testUrl = 'http://www.example.com/' + myPluginConfig.foo; // Assume plugin configuration has 'foo' attribute
myPlugin.ui.addMainTab('Custom Tab', 'custom-tab', testUrl); // Invoke some operation using plugin API
}
});
myPlugin.ready(); // Event handler functions are registered, we are now ready to get initialized (UiInit)
UI plugin life-cycle, enforced by plugin infrastructure
The PluginState enumeration lists possible states of a plugin during its runtime:
* DEFINED : This is the initial state for all plugins. Plugin meta-data has been read by PluginManager and the corresponding iframe element has been created for the plugin. Note that at this point, the iframe element is not attached to DOM yet.
* LOADING : The iframe element for the plugin has been attached to DOM, which causes plugin host page (previously known as plugin source page) to be fetched asynchronously in the background. We are now waiting for plugin to report in as ready. In practice, due to JavaScript runtime being single-threaded, WebAdmin startup logic will continue to execute until the JavaScript runtime is "idle" (browser event loop returns), and at this point JavaScript plugin code gets invoked through the plugin host page.
* READY : The plugin has indicated that it is ready for use. We assume the plugin has already registered its event handler object (object containing various event handler functions to be called by WebAdmin) at this point. We can now proceed with plugin initialization.
* INITIALIZED : The plugin has been initialized by calling UiInit function on its event handler object. We can now call other event handler functions, the plugin is now initialized and in use.
Note on plugin initialization: the UiInit function will be called just once during the lifetime of the plugin, after the plugin reports in as ready AND WebAdmin enters the state that allows plugins to be invoked (entering main section for logged-in users), and before other event handler functions are invoked by the plugin infrastructure.
Plugin meta-data is now passed to client using different format
Previously, plugin meta-data was embedded into WebAdmin host page as a simple JavaScript object, like so:
var pluginDefinitions = { myPlugin: "<URL>", anotherPlugin: "<URL>" }
Now, plugin meta-data is embedded into WebAdmin host page as a JavaScript array, like so:
var pluginDefinitions = [
{ name: "myPlugin", url: "<URL>", config: { "foo": 1, "bar": "whatever" } },
{ name: "anotherPlugin", url: "<URL>" }
];
As you can see, pluginDefinitions is now an array of JavaScript objects, with each object representing plugin meta-data . The "name" and "url" attributes are mandatory (we need to check them when loading plugin descriptors). "config" is the plugin configuration (JSON) object, obtained by merging default plugin configuration (defined in plugin descriptor) with custom plugin configuration (defined in external plugin configuration file) . Note that the "config" attribute is optional.
In terms of Java classes, pluginDefinitions is mapped to PluginDefinitions overlay type, and each meta-data object within the array is mapped to PluginMetaData overlay type.
Note on using assert statements in client code : you might notice that I'm using a lot of assert statements in Plugin class. This is to ensure consistency and guard against corrupted state during development. In GWT, assert statements work in a different way than in standard Java VM. When debugging GWT application using Development Mode, assert statements are checked and throw assertion errors during runtime (they are displayed in Development Mode console). However, when compiling GWT application to JavaScript (Production Mode), assert statements are removed by GWT compiler, so they don't affect the application running in Production Mode.
Let me know what you think guys.
Cheers,
Vojtech
------=_Part_15477538_89478576.1346339532819
Content-Type: text/html; charset=utf-8
Content-Transfer-Encoding: quoted-printable
<html><head><style type=3D'text/css'>p { margin: 0; }</style></head><body><=
div style=3D'font-family: times new roman,new york,times,serif; font-size: =
12pt; color: #000000'>Hello everyone,<br><br>as a follow-up to my last emai=
l on improving plugin API, here comes the latest revision of UI Plugins pro=
of-of-concept patch (please find it attached).<br><br>This patch is focused=
on improving JavaScript plugin API, along with important changes and impro=
vements made to plugin infrastructure (<em>PluginManager</em>). Let's walk =
through the changes step by step.<br><br><hr style=3D"width: 100%; height: =
2px;"><br><strong>Improved plugin API, taking some inspiration from jQuery<=
/strong><br style=3D"font-weight: bold;"><br>Following is a sample plugin c=
ode that uses new plugin API:<br><br><span style=3D"font-family: courier ne=
w,courier,monaco,monospace,sans-serif;">var myPlugin =3D pluginApi('myPlugi=
n'); // Obtain plugin API instance for 'myPlugin'</span><br style=3D"font-f=
amily: courier new,courier,monaco,monospace,sans-serif;"><span style=3D"fon=
t-family: courier new,courier,monaco,monospace,sans-serif;">var myPluginCon=
fig =3D myPlugin.configObject(); // Obtain plugin-specific configuration</s=
pan><br style=3D"font-family: courier new,courier,monaco,monospace,sans-ser=
if;"><br style=3D"font-family: courier new,courier,monaco,monospace,sans-se=
rif;"><span style=3D"font-family: courier new,courier,monaco,monospace,sans=
-serif;">// Register event handler functions to be invoked by WebAdmin</spa=
n><br style=3D"font-family: courier new,courier,monaco,monospace,sans-serif=
;"><span style=3D"font-family: courier new,courier,monaco,monospace,sans-se=
rif;">// Note: all functions are optional, the plugin only defines function=
s for events it wants to handle</span><br style=3D"font-family: courier new=
,courier,monaco,monospace,sans-serif;"><span style=3D"font-family: courier =
new,courier,monaco,monospace,sans-serif;">myPlugin.register({</span><br sty=
le=3D"font-family: courier new,courier,monaco,monospace,sans-serif;"><span =
style=3D"font-family: courier new,courier,monaco,monospace,sans-serif;">&nb=
sp; UiInit: function() {</span><br style=3D"font-family: courier new,courie=
r,monaco,monospace,sans-serif;"><span style=3D"font-family: courier new,cou=
rier,monaco,monospace,sans-serif;"> var testUrl =3D 'http=
://www.example.com/' + myPluginConfig.foo; // Assume plugin configuration h=
as 'foo' attribute</span><br style=3D"font-family: courier new,courier,mona=
co,monospace,sans-serif;"><span style=3D"font-family: courier new,courier,m=
onaco,monospace,sans-serif;"> myPlugin.ui.addMainTab('Cus=
tom Tab', 'custom-tab', testUrl); // Invoke some operation using plugin API=
</span><br style=3D"font-family: courier new,courier,monaco,monospace,sans-=
serif;"><span style=3D"font-family: courier new,courier,monaco,monospace,sa=
ns-serif;"> }</span><br style=3D"font-family: courier new,courier,mon=
aco,monospace,sans-serif;"><span style=3D"font-family: courier new,courier,=
monaco,monospace,sans-serif;">});</span><br style=3D"font-family: courier n=
ew,courier,monaco,monospace,sans-serif;"><br style=3D"font-family: courier =
new,courier,monaco,monospace,sans-serif;"><span style=3D"font-family: couri=
er new,courier,monaco,monospace,sans-serif;">myPlugin.ready(); // Event han=
dler functions are registered, we are now ready to get initialized (UiInit)=
</span><br style=3D"font-family: courier new,courier,monaco,monospace,sans-=
serif;"><br><hr style=3D"width: 100%; height: 2px;"><br><span style=3D"font=
-weight: bold;">UI plugin life-cycle, enforced by plugin infrastructure</sp=
an><br style=3D"font-weight: bold;"><br>The <span style=3D"font-style: ital=
ic;">PluginState</span> enumeration lists possible states of a plugin durin=
g its runtime:<br><ul><li><span style=3D"font-weight: bold;">DEFINED</span>=
: This is the initial state for all plugins. Plugin meta-data has been read=
by <span style=3D"font-style: italic;">PluginManager</span> and the corres=
ponding iframe element has been created for the plugin. Note that at this p=
oint, the iframe element is not attached to DOM yet.<br><br></li><li><span =
style=3D"font-weight: bold;">LOADING</span>: The iframe element for the plu=
gin has been attached to DOM, which causes <u>plugin host page</u> (previou=
sly known as plugin source page) to be fetched asynchronously in the backgr=
ound. We are now waiting for plugin to report in as ready. In practice, due=
to JavaScript runtime being single-threaded, WebAdmin startup logic will c=
ontinue to execute until the JavaScript runtime is "idle" (browser event lo=
op returns), and at this point JavaScript plugin code gets invoked through =
the plugin host page.<br><br></li><li><span style=3D"font-weight: bold;">RE=
ADY</span>: The plugin has indicated that it is ready for use. We assume th=
e plugin has already registered its event handler object (object containing=
various event handler functions to be called by WebAdmin) at this point. W=
e can now proceed with plugin initialization.<br><br></li><li><span style=
=3D"font-weight: bold;">INITIALIZED</span>: The plugin has been initialized=
by calling <span style=3D"font-style: italic;">UiInit</span> function on i=
ts event handler object. We can now call other event handler functions, the=
plugin is now initialized and in use.</li></ul><p><span style=3D"font-styl=
e: italic; text-decoration: underline;">Note on plugin initialization:</spa=
n> the <span style=3D"font-style: italic;">UiInit</span> function will be c=
alled just once during the lifetime of the plugin, after the plugin reports=
in as ready AND WebAdmin enters the state that allows plugins to be invoke=
d (entering main section for logged-in users), and before other event handl=
er functions are invoked by the plugin infrastructure.</p><p><br></p><hr st=
yle=3D"width: 100%; height: 2px;"><br><p style=3D"font-weight: bold;">Plugi=
n meta-data is now passed to client using different format</p><p><br></p><p=
>Previously, plugin meta-data was embedded into WebAdmin host page as a sim=
ple JavaScript object, like so:</p><p><br></p><p style=3D"font-family: cour=
ier new,courier,monaco,monospace,sans-serif;">var pluginDefinitions =3D { m=
yPlugin: "<URL>", anotherPlugin: "<URL>" }<br></p><p><br></p><p=
>Now, plugin meta-data is embedded into WebAdmin host page as a JavaScript =
array, like so:<br></p><p><br></p><p style=3D"font-family: courier new,cour=
ier,monaco,monospace,sans-serif;">var pluginDefinitions =3D [</p><p style=
=3D"font-family: courier new,courier,monaco,monospace,sans-serif;"> {=
name: "myPlugin", url: "<URL>", config: { "foo": 1, "bar": "whatever=
" } },</p><p style=3D"font-family: courier new,courier,monaco,monospace,san=
s-serif;"> { name: "anotherPlugin", url: "<URL>" }<br></p><p st=
yle=3D"font-family: courier new,courier,monaco,monospace,sans-serif;">];</p=
><p><br></p><p>As you can see, <span style=3D"font-style: italic;">pluginDe=
finitions</span> is now an array of JavaScript objects, with each object re=
presenting plugin meta-data. The "name" and "url" attributes are mandatory =
(we need to check them when loading plugin descriptors). "config" is the pl=
ugin configuration (JSON) object, obtained by merging default plugin config=
uration (defined in plugin descriptor) with custom plugin configuration (de=
fined in external plugin configuration file). Note that the "config" attrib=
ute is optional.<br></p><p><br></p><p>In terms of Java classes, <span style=
=3D"font-style: italic;">pluginDefinitions</span> is mapped to <span style=
=3D"font-style: italic;">PluginDefinitions</span> overlay type, and each me=
ta-data object within the array is mapped to <span style=3D"font-style: ita=
lic;">PluginMetaData</span> overlay type.<br></p><p><br></p><hr style=3D"wi=
dth: 100%; height: 2px;"><br><p><span style=3D"font-style: italic; text-dec=
oration: underline;">Note on using assert statements in client code:</span>=
you might notice that I'm using a lot of assert statements in <span style=
=3D"font-style: italic;">Plugin</span> class. This is to ensure consistency=
and guard against corrupted state during development. In GWT, assert state=
ments work in a different way than in standard Java VM. When debugging GWT =
application using Development Mode, assert statements are checked and throw=
assertion errors during runtime (they are displayed in Development Mode co=
nsole). However, when compiling GWT application to JavaScript (Production M=
ode), assert statements are removed by GWT compiler, so they don't affect t=
he application running in Production Mode.<br></p><p><br></p><p>Let me know=
what you think guys.<br></p><p><br></p><p>Cheers,</p><p>Vojtech</p><p><br>=
</p><p></p></div></body></html>
------=_Part_15477538_89478576.1346339532819--
------=_Part_15477537_1702327251.1346339532819
Content-Type: text/x-patch; name=WIP-UI-Plugins-PoC-revision-4.patch
Content-Disposition: attachment; filename=WIP-UI-Plugins-PoC-revision-4.patch
Content-Transfer-Encoding: base64
RnJvbSBlYjQ3NzlkYTZjODUxMmIwNjA3Mzk5ZTg4MzAwMWQxYmUwMzA1OGI4IE1vbiBTZXAgMTcg
MDA6MDA6MDAgMjAwMQpGcm9tOiBWb2p0ZWNoIFN6b2NzIDx2c3pvY3NAcmVkaGF0LmNvbT4KRGF0
ZTogVGh1LCAxOSBKdWwgMjAxMiAxNDo0ODo0MCArMDIwMApTdWJqZWN0OiBbUEFUQ0hdIFdJUDog
VUkgUGx1Z2lucyBQb0MsIHJldmlzaW9uIDQKCkNoYW5nZS1JZDogSWJiZjc2NTlmMDIzZDg5Mjlm
YjBhODMwMzA2MTg1MWJiN2VlNTU1YmMKU2lnbmVkLW9mZi1ieTogVm9qdGVjaCBTem9jcyA8dnN6
b2NzQHJlZGhhdC5jb20+Ci0tLQogLi4uL3NlcnZlci9nd3QvR3d0RHluYW1pY0hvc3RQYWdlU2Vy
dmxldC5qYXZhICAgICAgfCAgICAxICsKIC4uLi9zZXJ2ZXIvZ3d0L1BsdWdpblNvdXJjZVBhZ2VT
ZXJ2bGV0LmphdmEgICAgICAgIHwgIDEwNiArKysrKysrCiAuLi4vc2VydmVyL2d3dC9XZWJhZG1p
bkR5bmFtaWNIb3N0aW5nU2VydmxldC5qYXZhICB8ICAgIDggKy0KIC4uLi9lbmdpbmUvdWkvd2Vi
YWRtaW4vZ2luL0NsaWVudEdpbmplY3Rvci5qYXZhICAgIHwgICAgMiArLQogLi4uL292aXJ0L2Vu
Z2luZS91aS93ZWJhZG1pbi9naW4vUGx1Z2luTW9kdWxlLmphdmEgfCAgIDMwICsrCiAuLi4vb3Zp
cnQvZW5naW5lL3VpL3dlYmFkbWluL3BsdWdpbi9QbHVnaW4uamF2YSAgICB8ICAgNjcgKysrKysK
IC4uLi91aS93ZWJhZG1pbi9wbHVnaW4vUGx1Z2luRGVmaW5pdGlvbnMuamF2YSAgICAgIHwgICAy
NCArKwogLi4uL3VpL3dlYmFkbWluL3BsdWdpbi9QbHVnaW5FdmVudEhhbmRsZXIuamF2YSAgICAg
fCAgIDE5ICsrCiAuLi4vZW5naW5lL3VpL3dlYmFkbWluL3BsdWdpbi9QbHVnaW5NYW5hZ2VyLmph
dmEgICB8ICAyOTEgKysrKysrKysrKysrKysrKysrKysKIC4uLi9lbmdpbmUvdWkvd2ViYWRtaW4v
cGx1Z2luL1BsdWdpbk1ldGFEYXRhLmphdmEgIHwgICAzNiArKysKIC4uLi9lbmdpbmUvdWkvd2Vi
YWRtaW4vcGx1Z2luL1BsdWdpblN0YXRlLmphdmEgICAgIHwgICAzMyArKysKIC4uLi91aS93ZWJh
ZG1pbi9wbHVnaW4vUGx1Z2luVWlGdW5jdGlvbnMuamF2YSAgICAgIHwgICAyNiArKwogLi4uL21h
aW4vcHJlc2VudGVyL01haW5TZWN0aW9uUHJlc2VudGVyLmphdmEgICAgICAgfCAgIDE3ICstCiAu
Li4vbWFpbi9wcmVzZW50ZXIvTWFpblRhYlBhbmVsUHJlc2VudGVyLmphdmEgICAgICB8ICAgMTAg
KwogLi4uL21haW4vcHJlc2VudGVyL3RhYi9NYWluVGFiQ3VzdG9tUHJlc2VudGVyLmphdmEgfCAg
IDQzICsrKwogLi4uL3RhYi9NYWluVGFiQ3VzdG9tUHJlc2VudGVyUHJvdmlkZXIuamF2YSAgICAg
ICAgfCAgIDQ3ICsrKysKIC4uLi9tYWluL3ByZXNlbnRlci90YWIvTWFpblRhYkN1c3RvbVByb3h5
LmphdmEgICAgIHwgICA0NSArKysKIC4uLi9wcmVzZW50ZXIvdGFiL01haW5UYWJDdXN0b21Qcm94
eUZhY3RvcnkuamF2YSAgIHwgICAzNCArKysKIC4uLi9zZWN0aW9uL21haW4vdmlldy90YWIvTWFp
blRhYkN1c3RvbVZpZXcuamF2YSAgIHwgICAzMiArKysKIC4uLi9zZWN0aW9uL21haW4vdmlldy90
YWIvTWFpblRhYkN1c3RvbVZpZXcudWkueG1sIHwgICAxMCArCiAuLi4vd2ViYWRtaW4vc3JjL21h
aW4vd2ViYXBwL1dFQi1JTkYvd2ViLnhtbCAgICAgICB8ICAgMTAgKwogMjEgZmlsZXMgY2hhbmdl
ZCwgODg3IGluc2VydGlvbnMoKyksIDQgZGVsZXRpb25zKC0pCiBjcmVhdGUgbW9kZSAxMDA2NDQg
ZnJvbnRlbmQvd2ViYWRtaW4vbW9kdWxlcy9mcm9udGVuZC9zcmMvbWFpbi9qYXZhL29yZy9vdmly
dC9lbmdpbmUvdWkvZnJvbnRlbmQvc2VydmVyL2d3dC9QbHVnaW5Tb3VyY2VQYWdlU2VydmxldC5q
YXZhCiBjcmVhdGUgbW9kZSAxMDA2NDQgZnJvbnRlbmQvd2ViYWRtaW4vbW9kdWxlcy93ZWJhZG1p
bi9zcmMvbWFpbi9qYXZhL29yZy9vdmlydC9lbmdpbmUvdWkvd2ViYWRtaW4vZ2luL1BsdWdpbk1v
ZHVsZS5qYXZhCiBjcmVhdGUgbW9kZSAxMDA2NDQgZnJvbnRlbmQvd2ViYWRtaW4vbW9kdWxlcy93
ZWJhZG1pbi9zcmMvbWFpbi9qYXZhL29yZy9vdmlydC9lbmdpbmUvdWkvd2ViYWRtaW4vcGx1Z2lu
L1BsdWdpbi5qYXZhCiBjcmVhdGUgbW9kZSAxMDA2NDQgZnJvbnRlbmQvd2ViYWRtaW4vbW9kdWxl
cy93ZWJhZG1pbi9zcmMvbWFpbi9qYXZhL29yZy9vdmlydC9lbmdpbmUvdWkvd2ViYWRtaW4vcGx1
Z2luL1BsdWdpbkRlZmluaXRpb25zLmphdmEKIGNyZWF0ZSBtb2RlIDEwMDY0NCBmcm9udGVuZC93
ZWJhZG1pbi9tb2R1bGVzL3dlYmFkbWluL3NyYy9tYWluL2phdmEvb3JnL292aXJ0L2VuZ2luZS91
aS93ZWJhZG1pbi9wbHVnaW4vUGx1Z2luRXZlbnRIYW5kbGVyLmphdmEKIGNyZWF0ZSBtb2RlIDEw
MDY0NCBmcm9udGVuZC93ZWJhZG1pbi9tb2R1bGVzL3dlYmFkbWluL3NyYy9tYWluL2phdmEvb3Jn
L292aXJ0L2VuZ2luZS91aS93ZWJhZG1pbi9wbHVnaW4vUGx1Z2luTWFuYWdlci5qYXZhCiBjcmVh
dGUgbW9kZSAxMDA2NDQgZnJvbnRlbmQvd2ViYWRtaW4vbW9kdWxlcy93ZWJhZG1pbi9zcmMvbWFp
bi9qYXZhL29yZy9vdmlydC9lbmdpbmUvdWkvd2ViYWRtaW4vcGx1Z2luL1BsdWdpbk1ldGFEYXRh
LmphdmEKIGNyZWF0ZSBtb2RlIDEwMDY0NCBmcm9udGVuZC93ZWJhZG1pbi9tb2R1bGVzL3dlYmFk
bWluL3NyYy9tYWluL2phdmEvb3JnL292aXJ0L2VuZ2luZS91aS93ZWJhZG1pbi9wbHVnaW4vUGx1
Z2luU3RhdGUuamF2YQogY3JlYXRlIG1vZGUgMTAwNjQ0IGZyb250ZW5kL3dlYmFkbWluL21vZHVs
ZXMvd2ViYWRtaW4vc3JjL21haW4vamF2YS9vcmcvb3ZpcnQvZW5naW5lL3VpL3dlYmFkbWluL3Bs
dWdpbi9QbHVnaW5VaUZ1bmN0aW9ucy5qYXZhCiBjcmVhdGUgbW9kZSAxMDA2NDQgZnJvbnRlbmQv
d2ViYWRtaW4vbW9kdWxlcy93ZWJhZG1pbi9zcmMvbWFpbi9qYXZhL29yZy9vdmlydC9lbmdpbmUv
dWkvd2ViYWRtaW4vc2VjdGlvbi9tYWluL3ByZXNlbnRlci90YWIvTWFpblRhYkN1c3RvbVByZXNl
bnRlci5qYXZhCiBjcmVhdGUgbW9kZSAxMDA2NDQgZnJvbnRlbmQvd2ViYWRtaW4vbW9kdWxlcy93
ZWJhZG1pbi9zcmMvbWFpbi9qYXZhL29yZy9vdmlydC9lbmdpbmUvdWkvd2ViYWRtaW4vc2VjdGlv
bi9tYWluL3ByZXNlbnRlci90YWIvTWFpblRhYkN1c3RvbVByZXNlbnRlclByb3ZpZGVyLmphdmEK
IGNyZWF0ZSBtb2RlIDEwMDY0NCBmcm9udGVuZC93ZWJhZG1pbi9tb2R1bGVzL3dlYmFkbWluL3Ny
Yy9tYWluL2phdmEvb3JnL292aXJ0L2VuZ2luZS91aS93ZWJhZG1pbi9zZWN0aW9uL21haW4vcHJl
c2VudGVyL3RhYi9NYWluVGFiQ3VzdG9tUHJveHkuamF2YQogY3JlYXRlIG1vZGUgMTAwNjQ0IGZy
b250ZW5kL3dlYmFkbWluL21vZHVsZXMvd2ViYWRtaW4vc3JjL21haW4vamF2YS9vcmcvb3ZpcnQv
ZW5naW5lL3VpL3dlYmFkbWluL3NlY3Rpb24vbWFpbi9wcmVzZW50ZXIvdGFiL01haW5UYWJDdXN0
b21Qcm94eUZhY3RvcnkuamF2YQogY3JlYXRlIG1vZGUgMTAwNjQ0IGZyb250ZW5kL3dlYmFkbWlu
L21vZHVsZXMvd2ViYWRtaW4vc3JjL21haW4vamF2YS9vcmcvb3ZpcnQvZW5naW5lL3VpL3dlYmFk
bWluL3NlY3Rpb24vbWFpbi92aWV3L3RhYi9NYWluVGFiQ3VzdG9tVmlldy5qYXZhCiBjcmVhdGUg
bW9kZSAxMDA2NDQgZnJvbnRlbmQvd2ViYWRtaW4vbW9kdWxlcy93ZWJhZG1pbi9zcmMvbWFpbi9q
YXZhL29yZy9vdmlydC9lbmdpbmUvdWkvd2ViYWRtaW4vc2VjdGlvbi9tYWluL3ZpZXcvdGFiL01h
aW5UYWJDdXN0b21WaWV3LnVpLnhtbAoKZGlmZiAtLWdpdCBhL2Zyb250ZW5kL3dlYmFkbWluL21v
ZHVsZXMvZnJvbnRlbmQvc3JjL21haW4vamF2YS9vcmcvb3ZpcnQvZW5naW5lL3VpL2Zyb250ZW5k
L3NlcnZlci9nd3QvR3d0RHluYW1pY0hvc3RQYWdlU2VydmxldC5qYXZhIGIvZnJvbnRlbmQvd2Vi
YWRtaW4vbW9kdWxlcy9mcm9udGVuZC9zcmMvbWFpbi9qYXZhL29yZy9vdmlydC9lbmdpbmUvdWkv
ZnJvbnRlbmQvc2VydmVyL2d3dC9Hd3REeW5hbWljSG9zdFBhZ2VTZXJ2bGV0LmphdmEKaW5kZXgg
ZjE5NzM5YS4uNjg1ZTY4NSAxMDA2NDQKLS0tIGEvZnJvbnRlbmQvd2ViYWRtaW4vbW9kdWxlcy9m
cm9udGVuZC9zcmMvbWFpbi9qYXZhL29yZy9vdmlydC9lbmdpbmUvdWkvZnJvbnRlbmQvc2VydmVy
L2d3dC9Hd3REeW5hbWljSG9zdFBhZ2VTZXJ2bGV0LmphdmEKKysrIGIvZnJvbnRlbmQvd2ViYWRt
aW4vbW9kdWxlcy9mcm9udGVuZC9zcmMvbWFpbi9qYXZhL29yZy9vdmlydC9lbmdpbmUvdWkvZnJv
bnRlbmQvc2VydmVyL2d3dC9Hd3REeW5hbWljSG9zdFBhZ2VTZXJ2bGV0LmphdmEKQEAgLTQ2LDYg
KzQ2LDcgQEAgcHVibGljIGFic3RyYWN0IGNsYXNzIEd3dER5bmFtaWNIb3N0UGFnZVNlcnZsZXQg
ZXh0ZW5kcyBIdHRwU2VydmxldCB7CiAgICAgcHJvdGVjdGVkIHZvaWQgZG9HZXQoSHR0cFNlcnZs
ZXRSZXF1ZXN0IHJlcXVlc3QsIEh0dHBTZXJ2bGV0UmVzcG9uc2UgcmVzcG9uc2UpIHRocm93cyBJ
T0V4Y2VwdGlvbiB7CiAgICAgICAgIFByaW50V3JpdGVyIHdyaXRlciA9IHJlc3BvbnNlLmdldFdy
aXRlcigpOwogICAgICAgICByZXNwb25zZS5zZXRDb250ZW50VHlwZSgidGV4dC9odG1sOyBjaGFy
c2V0PVVURi04Iik7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgcmVzcG9uc2Uuc2V0SGVhZGVyKCJD
YWNoZS1Db250cm9sIiwgIm5vLWNhY2hlIik7IC8vJE5PTi1OTFMtMSQgLy8kTk9OLU5MUy0yJAog
CiAgICAgICAgIHdyaXRlci5hcHBlbmQoIjwhRE9DVFlQRSBodG1sPjxodG1sPjxoZWFkPiIpOyAv
LyROT04tTkxTLTEkCiAgICAgICAgIHdyaXRlci5hcHBlbmQoIjxtZXRhIGh0dHAtZXF1aXY9XCJj
b250ZW50LXR5cGVcIiBjb250ZW50PVwidGV4dC9odG1sOyBjaGFyc2V0PVVURi04XCI+Iik7IC8v
JE5PTi1OTFMtMSQKZGlmZiAtLWdpdCBhL2Zyb250ZW5kL3dlYmFkbWluL21vZHVsZXMvZnJvbnRl
bmQvc3JjL21haW4vamF2YS9vcmcvb3ZpcnQvZW5naW5lL3VpL2Zyb250ZW5kL3NlcnZlci9nd3Qv
UGx1Z2luU291cmNlUGFnZVNlcnZsZXQuamF2YSBiL2Zyb250ZW5kL3dlYmFkbWluL21vZHVsZXMv
ZnJvbnRlbmQvc3JjL21haW4vamF2YS9vcmcvb3ZpcnQvZW5naW5lL3VpL2Zyb250ZW5kL3NlcnZl
ci9nd3QvUGx1Z2luU291cmNlUGFnZVNlcnZsZXQuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NApp
bmRleCAwMDAwMDAwLi4xNTlmYWQ4Ci0tLSAvZGV2L251bGwKKysrIGIvZnJvbnRlbmQvd2ViYWRt
aW4vbW9kdWxlcy9mcm9udGVuZC9zcmMvbWFpbi9qYXZhL29yZy9vdmlydC9lbmdpbmUvdWkvZnJv
bnRlbmQvc2VydmVyL2d3dC9QbHVnaW5Tb3VyY2VQYWdlU2VydmxldC5qYXZhCkBAIC0wLDAgKzEs
MTA2IEBACitwYWNrYWdlIG9yZy5vdmlydC5lbmdpbmUudWkuZnJvbnRlbmQuc2VydmVyLmd3dDsK
KworaW1wb3J0IGphdmEuaW8uQnVmZmVyZWRSZWFkZXI7CitpbXBvcnQgamF2YS5pby5CdWZmZXJl
ZFdyaXRlcjsKK2ltcG9ydCBqYXZhLmlvLkZpbGU7CitpbXBvcnQgamF2YS5pby5GaWxlSW5wdXRT
dHJlYW07CitpbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKK2ltcG9ydCBqYXZhLmlvLklucHV0
U3RyZWFtUmVhZGVyOworaW1wb3J0IGphdmEuaW8uT3V0cHV0U3RyZWFtV3JpdGVyOworaW1wb3J0
IGphdmEuaW8uUmVhZGVyOworaW1wb3J0IGphdmEuaW8uV3JpdGVyOworaW1wb3J0IGphdmEudXRp
bC5BcnJheXM7CitpbXBvcnQgamF2YS51dGlsLkxpc3Q7CisKK2ltcG9ydCBqYXZheC5zZXJ2bGV0
Lmh0dHAuSHR0cFNlcnZsZXQ7CitpbXBvcnQgamF2YXguc2VydmxldC5odHRwLkh0dHBTZXJ2bGV0
UmVxdWVzdDsKK2ltcG9ydCBqYXZheC5zZXJ2bGV0Lmh0dHAuSHR0cFNlcnZsZXRSZXNwb25zZTsK
KworaW1wb3J0IG9yZy5hcGFjaGUuY29tbW9ucy5sb2dnaW5nLkxvZzsKK2ltcG9ydCBvcmcuYXBh
Y2hlLmNvbW1vbnMubG9nZ2luZy5Mb2dGYWN0b3J5OworCisvKioKKyAqIFJlbmRlcnMgdGhlIEhU
TUwgc291cmNlIHBhZ2UgZm9yIHRoZSBnaXZlbiBVSSBwbHVnaW4uCisgKi8KK3B1YmxpYyBjbGFz
cyBQbHVnaW5Tb3VyY2VQYWdlU2VydmxldCBleHRlbmRzIEh0dHBTZXJ2bGV0IHsKKworICAgIHBy
aXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDFMOworCisgICAgcHJp
dmF0ZSBzdGF0aWMgTG9nIGxvZ2dlciA9IExvZ0ZhY3RvcnkuZ2V0TG9nKFBsdWdpblNvdXJjZVBh
Z2VTZXJ2bGV0LmNsYXNzKTsKKworICAgIEBPdmVycmlkZQorICAgIHByb3RlY3RlZCB2b2lkIGRv
R2V0KEh0dHBTZXJ2bGV0UmVxdWVzdCByZXF1ZXN0LCBIdHRwU2VydmxldFJlc3BvbnNlIHJlc3Bv
bnNlKSB0aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICAvLyBSZWFkIHBsdWdpbiBuYW1lIGFz
IEhUVFAgcmVxdWVzdCBwYXJhbWV0ZXIKKyAgICAgICAgU3RyaW5nIHBsdWdpbk5hbWUgPSByZXF1
ZXN0LmdldFBhcmFtZXRlcigicGx1Z2luIik7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgaWYgKHBs
dWdpbk5hbWUgPT0gbnVsbCkgeworICAgICAgICAgICAgbG9nZ2VyLmVycm9yKCJNaXNzaW5nIHBs
dWdpbiBuYW1lIHJlcXVlc3QgcGFyYW1ldGVyIik7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgICAg
IHJlc3BvbnNlLnNlbmRFcnJvcihIdHRwU2VydmxldFJlc3BvbnNlLlNDX0JBRF9SRVFVRVNUKTsK
KyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorCisgICAgICAgIC8vIExvY2F0ZSBwbHVn
aW4gY29kZSBpbiBsb2NhbCBmaWxlIHN5c3RlbQorICAgICAgICAvLyBUT0RPIGhhcmQtY29kZWQg
cGx1Z2luIGxvY2F0aW9uCisgICAgICAgIEZpbGUgcGx1Z2luQ29kZUxvY2F0aW9uID0gbmV3IEZp
bGUoIi9ob21lL3Zzem9jcy9Eb3dubG9hZHMiKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICBGaWxl
IHBsdWdpbkNvZGVGaWxlID0gbmV3IEZpbGUocGx1Z2luQ29kZUxvY2F0aW9uLCBwbHVnaW5OYW1l
ICsgIi5qcyIpOyAvLyROT04tTkxTLTEkCisgICAgICAgIGlmICghcGx1Z2luQ29kZUZpbGUuaXNG
aWxlKCkgfHwgIXBsdWdpbkNvZGVGaWxlLmNhblJlYWQoKSkgeworICAgICAgICAgICAgbG9nZ2Vy
LmVycm9yKCJDYW5ub3QgcmVhZCBwbHVnaW4gY29kZTogIiArIHBsdWdpbkNvZGVGaWxlLmdldEFi
c29sdXRlUGF0aCgpKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICAgICAgcmVzcG9uc2Uuc2VuZEVy
cm9yKEh0dHBTZXJ2bGV0UmVzcG9uc2UuU0NfTk9UX0ZPVU5EKTsKKyAgICAgICAgICAgIHJldHVy
bjsKKyAgICAgICAgfQorCisgICAgICAgIC8vIFRPRE8gc2ltdWxhdGUgcGx1Z2luIGRlcGVuZGVu
Y2llcworICAgICAgICBMaXN0PFN0cmluZz4gcGx1Z2luRGVwZW5kZW5jeUxpc3QgPQorICAgICAg
ICAgICAgICAgIEFycmF5cy5hc0xpc3QoImh0dHBzOi8vYWpheC5nb29nbGVhcGlzLmNvbS9hamF4
L2xpYnMvanF1ZXJ5LzEuNy4yL2pxdWVyeS5taW4uanMiKTsgLy8kTk9OLU5MUy0xJAorCisgICAg
ICAgIC8vIFJlbmRlciBIVE1MIHNvdXJjZSBwYWdlIHRvIHRoZSBvdXRwdXQKKyAgICAgICAgcmVz
cG9uc2Uuc2V0Q29udGVudFR5cGUoInRleHQvaHRtbDsgY2hhcnNldD1VVEYtOCIpOyAvLyROT04t
TkxTLTEkCisgICAgICAgIHJlc3BvbnNlLnNldEhlYWRlcigiQ2FjaGUtQ29udHJvbCIsICJuby1j
YWNoZSIpOyAvLyROT04tTkxTLTEkIC8vJE5PTi1OTFMtMiQKKworICAgICAgICBSZWFkZXIgaW4g
PSBudWxsOworICAgICAgICBXcml0ZXIgb3V0ID0gbnVsbDsKKworICAgICAgICB0cnkgeworICAg
ICAgICAgICAgaW4gPSBuZXcgQnVmZmVyZWRSZWFkZXIobmV3IElucHV0U3RyZWFtUmVhZGVyKG5l
dyBGaWxlSW5wdXRTdHJlYW0ocGx1Z2luQ29kZUZpbGUpLCAiVVRGLTgiKSk7IC8vJE5PTi1OTFMt
MSQKKyAgICAgICAgICAgIG91dCA9IG5ldyBCdWZmZXJlZFdyaXRlcihuZXcgT3V0cHV0U3RyZWFt
V3JpdGVyKHJlc3BvbnNlLmdldE91dHB1dFN0cmVhbSgpLCAiVVRGLTgiKSk7IC8vJE5PTi1OTFMt
MSQKKworICAgICAgICAgICAgcmVuZGVyUGx1Z2luU291cmNlUGFnZShpbiwgcGx1Z2luRGVwZW5k
ZW5jeUxpc3QsIG91dCk7CisgICAgICAgICAgICBvdXQuZmx1c2goKTsKKyAgICAgICAgfSBmaW5h
bGx5IHsKKyAgICAgICAgICAgIGlmIChpbiAhPSBudWxsKSB7CisgICAgICAgICAgICAgICAgaW4u
Y2xvc2UoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIHZvaWQgcmVu
ZGVyUGx1Z2luU291cmNlUGFnZShSZWFkZXIgcGx1Z2luQ29kZUlucHV0LCBMaXN0PFN0cmluZz4g
cGx1Z2luRGVwZW5kZW5jeUxpc3QsIFdyaXRlciBvdXRwdXQpCisgICAgICAgICAgICB0aHJvd3Mg
SU9FeGNlcHRpb24geworICAgICAgICBvdXRwdXQud3JpdGUoIjwhRE9DVFlQRSBodG1sPjxodG1s
PjxoZWFkPiIpOyAvLyROT04tTkxTLTEkCisgICAgICAgIG91dHB1dC53cml0ZSgiPG1ldGEgaHR0
cC1lcXVpdj1cImNvbnRlbnQtdHlwZVwiIGNvbnRlbnQ9XCJ0ZXh0L2h0bWw7IGNoYXJzZXQ9VVRG
LThcIj4iKTsgLy8kTk9OLU5MUy0xJAorCisgICAgICAgIGZvciAoU3RyaW5nIGRlcGVuZGVuY3kg
OiBwbHVnaW5EZXBlbmRlbmN5TGlzdCkgeworICAgICAgICAgICAgb3V0cHV0LndyaXRlKCI8c2Ny
aXB0IHR5cGU9XCJ0ZXh0L2phdmFzY3JpcHRcIiBzcmM9XCIiKTsgLy8kTk9OLU5MUy0xJAorICAg
ICAgICAgICAgb3V0cHV0LndyaXRlKGRlcGVuZGVuY3kpOworICAgICAgICAgICAgb3V0cHV0Lndy
aXRlKCJcIj48L3NjcmlwdD4iKTsgLy8kTk9OLU5MUy0xJAorICAgICAgICB9CisKKyAgICAgICAg
b3V0cHV0LndyaXRlKCI8L2hlYWQ+PGJvZHk+Iik7IC8vJE5PTi1OTFMtMSQKKyAgICAgICAgb3V0
cHV0LndyaXRlKCI8c2NyaXB0IHR5cGU9XCJ0ZXh0L2phdmFzY3JpcHRcIj4iKTsgLy8kTk9OLU5M
Uy0xJAorICAgICAgICBvdXRwdXQud3JpdGUoIihmdW5jdGlvbiggcGx1Z2luQXBpICkgeyIpOyAv
LyROT04tTkxTLTEkCisKKyAgICAgICAgY29weUNoYXJzKHBsdWdpbkNvZGVJbnB1dCwgb3V0cHV0
KTsKKworICAgICAgICBvdXRwdXQud3JpdGUoIn0pICggcGFyZW50LnBsdWdpbkFwaSApOyIpOyAv
LyROT04tTkxTLTEkCisgICAgICAgIG91dHB1dC53cml0ZSgiPC9zY3JpcHQ+Iik7IC8vJE5PTi1O
TFMtMSQKKyAgICAgICAgb3V0cHV0LndyaXRlKCI8L2JvZHk+PC9odG1sPiIpOyAvLyROT04tTkxT
LTEkCisgICAgfQorCisgICAgdm9pZCBjb3B5Q2hhcnMoUmVhZGVyIGluLCBXcml0ZXIgb3V0KSB0
aHJvd3MgSU9FeGNlcHRpb24geworICAgICAgICBjaGFyW10gYnVmZmVyID0gbmV3IGNoYXJbNCAq
IDEwMjRdOyAvLyBVc2UgNCBrQiBidWZmZXIKKyAgICAgICAgaW50IG51bVJlYWQgPSAwOworCisg
ICAgICAgIHdoaWxlICgobnVtUmVhZCA9IGluLnJlYWQoYnVmZmVyLCAwLCBidWZmZXIubGVuZ3Ro
KSkgPiAwKSB7CisgICAgICAgICAgICBvdXQud3JpdGUoYnVmZmVyLCAwLCBudW1SZWFkKTsKKyAg
ICAgICAgfQorICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvZnJvbnRlbmQvd2ViYWRtaW4vbW9kdWxl
cy9mcm9udGVuZC9zcmMvbWFpbi9qYXZhL29yZy9vdmlydC9lbmdpbmUvdWkvZnJvbnRlbmQvc2Vy
dmVyL2d3dC9XZWJhZG1pbkR5bmFtaWNIb3N0aW5nU2VydmxldC5qYXZhIGIvZnJvbnRlbmQvd2Vi
YWRtaW4vbW9kdWxlcy9mcm9udGVuZC9zcmMvbWFpbi9qYXZhL29yZy9vdmlydC9lbmdpbmUvdWkv
ZnJvbnRlbmQvc2VydmVyL2d3dC9XZWJhZG1pbkR5bmFtaWNIb3N0aW5nU2VydmxldC5qYXZhCmlu
ZGV4IDQyOGRjYzUuLjY4M2NiNjggMTAwNjQ0Ci0tLSBhL2Zyb250ZW5kL3dlYmFkbWluL21vZHVs
ZXMvZnJvbnRlbmQvc3JjL21haW4vamF2YS9vcmcvb3ZpcnQvZW5naW5lL3VpL2Zyb250ZW5kL3Nl
cnZlci9nd3QvV2ViYWRtaW5EeW5hbWljSG9zdGluZ1NlcnZsZXQuamF2YQorKysgYi9mcm9udGVu
ZC93ZWJhZG1pbi9tb2R1bGVzL2Zyb250ZW5kL3NyYy9tYWluL2phdmEvb3JnL292aXJ0L2VuZ2lu
ZS91aS9mcm9udGVuZC9zZXJ2ZXIvZ3d0L1dlYmFkbWluRHluYW1pY0hvc3RpbmdTZXJ2bGV0Lmph
dmEKQEAgLTMwLDE4ICszMCwyMiBAQCBwdWJsaWMgY2xhc3MgV2ViYWRtaW5EeW5hbWljSG9zdGlu
Z1NlcnZsZXQgZXh0ZW5kcyBHd3REeW5hbWljSG9zdFBhZ2VTZXJ2bGV0IHsKICAgICAgICAgc3Vw
ZXIud3JpdGVBZGRpdGlvbmFsSnNEYXRhKHJlcXVlc3QsIHdyaXRlcik7CiAKICAgICAgICAgSW50
ZWdlciBhcHBsaWNhdGlvbk1vZGUgPSBnZXRBcHBsaWNhdGlvbk1vZGUocmVxdWVzdCk7Ci0KICAg
ICAgICAgaWYgKGFwcGxpY2F0aW9uTW9kZSAhPSBudWxsKSB7CiAgICAgICAgICAgICBNYXA8U3Ry
aW5nLCBTdHJpbmc+IGFwcE1vZGVEYXRhID0gbmV3IEhhc2hNYXA8U3RyaW5nLCBTdHJpbmc+KCk7
CiAgICAgICAgICAgICBhcHBNb2RlRGF0YS5wdXQoInZhbHVlIiwgU3RyaW5nLnZhbHVlT2YoYXBw
bGljYXRpb25Nb2RlKSk7IC8vJE5PTi1OTFMtMSQKICAgICAgICAgICAgIHdyaXRlSnNPYmplY3Qo
d3JpdGVyLCAiYXBwbGljYXRpb25Nb2RlIiwgYXBwTW9kZURhdGEpOyAvLyROT04tTkxTLTEkCiAg
ICAgICAgIH0KKworICAgICAgICBTdHJpbmdCdWlsZGVyIHBsdWdpbkRlZmluaXRpb25zID0gbmV3
IFN0cmluZ0J1aWxkZXIoIiB2YXIgcGx1Z2luRGVmaW5pdGlvbnMgPSBbICIpOyAvLyROT04tTkxT
LTEkCisgICAgICAgIHBsdWdpbkRlZmluaXRpb25zLmFwcGVuZCgieyBuYW1lOiBcIm15UGx1Z2lu
XCIsIHVybDogXCIvd2ViYWRtaW4vd2ViYWRtaW4vUGx1Z2luU291cmNlUGFnZT9wbHVnaW49bXlQ
bHVnaW5cIiwgY29uZmlnOiB7IFwiZm9vXCI6IDEgfSB9Iik7IC8vJE5PTi1OTFMtMSQKKyAgICAg
ICAgcGx1Z2luRGVmaW5pdGlvbnMuYXBwZW5kKCIgXTsgIik7IC8vJE5PTi1OTFMtMSQKKyAgICAg
ICAgd3JpdGVyLmFwcGVuZChwbHVnaW5EZWZpbml0aW9ucy50b1N0cmluZygpKTsKICAgICB9CiAK
ICAgICBwcml2YXRlIEludGVnZXIgZ2V0QXBwbGljYXRpb25Nb2RlKEh0dHBTZXJ2bGV0UmVxdWVz
dCByZXF1ZXN0KSB7CiAgICAgICAgIHJldHVybiAoSW50ZWdlcikgcnVuUHVibGljUXVlcnkoVmRj
UXVlcnlUeXBlLkdldENvbmZpZ3VyYXRpb25WYWx1ZSwKICAgICAgICAgICAgICAgICBuZXcgR2V0
Q29uZmlndXJhdGlvblZhbHVlUGFyYW1ldGVycyhDb25maWd1cmF0aW9uVmFsdWVzLkFwcGxpY2F0
aW9uTW9kZSwKLSAgICAgICAgICAgICAgICBDb25maWcuRGVmYXVsdENvbmZpZ3VyYXRpb25WZXJz
aW9uKSwgcmVxdWVzdCk7CisgICAgICAgICAgICAgICAgICAgICAgICBDb25maWcuRGVmYXVsdENv
bmZpZ3VyYXRpb25WZXJzaW9uKSwgcmVxdWVzdCk7CiAgICAgfQogCiB9CmRpZmYgLS1naXQgYS9m
cm9udGVuZC93ZWJhZG1pbi9tb2R1bGVzL3dlYmFkbWluL3NyYy9tYWluL2phdmEvb3JnL292aXJ0
L2VuZ2luZS91aS93ZWJhZG1pbi9naW4vQ2xpZW50R2luamVjdG9yLmphdmEgYi9mcm9udGVuZC93
ZWJhZG1pbi9tb2R1bGVzL3dlYmFkbWluL3NyYy9tYWluL2phdmEvb3JnL292aXJ0L2VuZ2luZS91
aS93ZWJhZG1pbi9naW4vQ2xpZW50R2luamVjdG9yLmphdmEKaW5kZXggZDI3MmMyYi4uYmFiZGRm
MSAxMDA2NDQKLS0tIGEvZnJvbnRlbmQvd2ViYWRtaW4vbW9kdWxlcy93ZWJhZG1pbi9zcmMvbWFp
bi9qYXZhL29yZy9vdmlydC9lbmdpbmUvdWkvd2ViYWRtaW4vZ2luL0NsaWVudEdpbmplY3Rvci5q
YXZhCisrKyBiL2Zyb250ZW5kL3dlYmFkbWluL21vZHVsZXMvd2ViYWRtaW4vc3JjL21haW4vamF2
YS9vcmcvb3ZpcnQvZW5naW5lL3VpL3dlYmFkbWluL2dpbi9DbGllbnRHaW5qZWN0b3IuamF2YQpA
QCAtOSw3ICs5LDcgQEAgaW1wb3J0IGNvbS5nd3RwbGF0Zm9ybS5tdnAuY2xpZW50LmFubm90YXRp
b25zLkRlZmF1bHRHYXRla2VlcGVyOwogLyoqCiAgKiBDbGllbnQtc2lkZSBpbmplY3RvciBjb25m
aWd1cmF0aW9uIHVzZWQgdG8gYm9vdHN0cmFwIEdJTi4KICAqLwotQEdpbk1vZHVsZXMoeyBTeXN0
ZW1Nb2R1bGUuY2xhc3MsIFByZXNlbnRlck1vZHVsZS5jbGFzcywgVWlDb21tb25Nb2R1bGUuY2xh
c3MgfSkKK0BHaW5Nb2R1bGVzKHsgU3lzdGVtTW9kdWxlLmNsYXNzLCBQcmVzZW50ZXJNb2R1bGUu
Y2xhc3MsIFVpQ29tbW9uTW9kdWxlLmNsYXNzLCBQbHVnaW5Nb2R1bGUuY2xhc3MgfSkKIHB1Ymxp
YyBpbnRlcmZhY2UgQ2xpZW50R2luamVjdG9yIGV4dGVuZHMgQmFzZUNsaWVudEdpbmplY3Rvciwg
TWFuYWdlZENvbXBvbmVudHMgewogCiAgICAgQERlZmF1bHRHYXRla2VlcGVyCmRpZmYgLS1naXQg
YS9mcm9udGVuZC93ZWJhZG1pbi9tb2R1bGVzL3dlYmFkbWluL3NyYy9tYWluL2phdmEvb3JnL292
aXJ0L2VuZ2luZS91aS93ZWJhZG1pbi9naW4vUGx1Z2luTW9kdWxlLmphdmEgYi9mcm9udGVuZC93
ZWJhZG1pbi9tb2R1bGVzL3dlYmFkbWluL3NyYy9tYWluL2phdmEvb3JnL292aXJ0L2VuZ2luZS91
aS93ZWJhZG1pbi9naW4vUGx1Z2luTW9kdWxlLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5k
ZXggMDAwMDAwMC4uMzU4NDRjMAotLS0gL2Rldi9udWxsCisrKyBiL2Zyb250ZW5kL3dlYmFkbWlu
L21vZHVsZXMvd2ViYWRtaW4vc3JjL21haW4vamF2YS9vcmcvb3ZpcnQvZW5naW5lL3VpL3dlYmFk
bWluL2dpbi9QbHVnaW5Nb2R1bGUuamF2YQpAQCAtMCwwICsxLDMwIEBACitwYWNrYWdlIG9yZy5v
dmlydC5lbmdpbmUudWkud2ViYWRtaW4uZ2luOworCitpbXBvcnQgb3JnLm92aXJ0LmVuZ2luZS51
aS53ZWJhZG1pbi5wbHVnaW4uUGx1Z2luRXZlbnRIYW5kbGVyOworaW1wb3J0IG9yZy5vdmlydC5l
bmdpbmUudWkud2ViYWRtaW4ucGx1Z2luLlBsdWdpbk1hbmFnZXI7CitpbXBvcnQgb3JnLm92aXJ0
LmVuZ2luZS51aS53ZWJhZG1pbi5wbHVnaW4uUGx1Z2luVWlGdW5jdGlvbnM7CitpbXBvcnQgb3Jn
Lm92aXJ0LmVuZ2luZS51aS53ZWJhZG1pbi5zZWN0aW9uLm1haW4ucHJlc2VudGVyLnRhYi5NYWlu
VGFiQ3VzdG9tUHJlc2VudGVyOworaW1wb3J0IG9yZy5vdmlydC5lbmdpbmUudWkud2ViYWRtaW4u
c2VjdGlvbi5tYWluLnByZXNlbnRlci50YWIuTWFpblRhYkN1c3RvbVByb3h5RmFjdG9yeTsKK2lt
cG9ydCBvcmcub3ZpcnQuZW5naW5lLnVpLndlYmFkbWluLnNlY3Rpb24ubWFpbi52aWV3LnRhYi5N
YWluVGFiQ3VzdG9tVmlldzsKKworaW1wb3J0IGNvbS5nb29nbGUuZ3d0LmluamVjdC5jbGllbnQu
QWJzdHJhY3RHaW5Nb2R1bGU7CitpbXBvcnQgY29tLmdvb2dsZS5pbmplY3QuU2luZ2xldG9uOwor
CisvKioKKyAqIEdJTiBtb2R1bGUgY29udGFpbmluZyBXZWJBZG1pbiBVSSBwbHVnaW4gaW5mcmFz
dHJ1Y3R1cmUgYmluZGluZ3MuCisgKi8KK3B1YmxpYyBjbGFzcyBQbHVnaW5Nb2R1bGUgZXh0ZW5k
cyBBYnN0cmFjdEdpbk1vZHVsZSB7CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgdm9p
ZCBjb25maWd1cmUoKSB7CisgICAgICAgIGJpbmQoUGx1Z2luTWFuYWdlci5jbGFzcykuYXNFYWdl
clNpbmdsZXRvbigpOworICAgICAgICBiaW5kKFBsdWdpbkV2ZW50SGFuZGxlci5jbGFzcykuYXNF
YWdlclNpbmdsZXRvbigpOworICAgICAgICBiaW5kKFBsdWdpblVpRnVuY3Rpb25zLmNsYXNzKS5p
bihTaW5nbGV0b24uY2xhc3MpOworCisgICAgICAgIC8vIEJpbmQgTWFpblRhYkN1c3RvbVZpZXcg
dG8gaXRzIHZpZXcgaW50ZXJmYWNlIGFzIG5vbi1zaW5nbGV0b24sIHdpdGhvdXQgcHJlc2VudGVy
IGJpbmRpbmcKKyAgICAgICAgLy8gKE1haW5UYWJDdXN0b21QcmVzZW50ZXIgaXMgY3JlYXRlZCBt
YW51YWxseSBkdXJpbmcgcnVudGltZSBieSBNYWluVGFiQ3VzdG9tUHJlc2VudGVyUHJvdmlkZXIp
CisgICAgICAgIGJpbmQoTWFpblRhYkN1c3RvbVByZXNlbnRlci5WaWV3RGVmLmNsYXNzKS50byhN
YWluVGFiQ3VzdG9tVmlldy5jbGFzcyk7CisgICAgICAgIGJpbmQoTWFpblRhYkN1c3RvbVByb3h5
RmFjdG9yeS5jbGFzcykuaW4oU2luZ2xldG9uLmNsYXNzKTsKKyAgICB9CisKK30KZGlmZiAtLWdp
dCBhL2Zyb250ZW5kL3dlYmFkbWluL21vZHVsZXMvd2ViYWRtaW4vc3JjL21haW4vamF2YS9vcmcv
b3ZpcnQvZW5naW5lL3VpL3dlYmFkbWluL3BsdWdpbi9QbHVnaW4uamF2YSBiL2Zyb250ZW5kL3dl
YmFkbWluL21vZHVsZXMvd2ViYWRtaW4vc3JjL21haW4vamF2YS9vcmcvb3ZpcnQvZW5naW5lL3Vp
L3dlYmFkbWluL3BsdWdpbi9QbHVnaW4uamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAw
MDAwMDAwLi41NjI0YjA4Ci0tLSAvZGV2L251bGwKKysrIGIvZnJvbnRlbmQvd2ViYWRtaW4vbW9k
dWxlcy93ZWJhZG1pbi9zcmMvbWFpbi9qYXZhL29yZy9vdmlydC9lbmdpbmUvdWkvd2ViYWRtaW4v
cGx1Z2luL1BsdWdpbi5qYXZhCkBAIC0wLDAgKzEsNjcgQEAKK3BhY2thZ2Ugb3JnLm92aXJ0LmVu
Z2luZS51aS53ZWJhZG1pbi5wbHVnaW47CisKK2ltcG9ydCBjb20uZ29vZ2xlLmd3dC5jb3JlLmNs
aWVudC5KYXZhU2NyaXB0T2JqZWN0OworaW1wb3J0IGNvbS5nb29nbGUuZ3d0LmRvbS5jbGllbnQu
SUZyYW1lRWxlbWVudDsKKworLyoqCisgKiBSZXByZXNlbnRzIGEgVUkgcGx1Z2luLCBjb250YWlu
aW5nIG1ldGEtZGF0YSBhcyB3ZWxsIGFzIHJ1bnRpbWUgc3RhdGUuCisgKi8KK3B1YmxpYyBjbGFz
cyBQbHVnaW4geworCisgICAgcHJpdmF0ZSBmaW5hbCBQbHVnaW5NZXRhRGF0YSBtZXRhRGF0YTsK
KyAgICBwcml2YXRlIFBsdWdpblN0YXRlIHN0YXRlOworCisgICAgLy8gVGhlIGlmcmFtZSBlbGVt
ZW50IHVzZWQgdG8gbG9hZCB0aGUgcGx1Z2luIGhvc3QgcGFnZQorICAgIHByaXZhdGUgZmluYWwg
SUZyYW1lRWxlbWVudCBpZnJhbWU7CisKKyAgICAvLyBUaGUgb2JqZWN0IGNvbnRhaW5pbmcgcGx1
Z2luIGV2ZW50IGhhbmRsZXIgZnVuY3Rpb25zCisgICAgcHJpdmF0ZSBKYXZhU2NyaXB0T2JqZWN0
IGV2ZW50SGFuZGxlck9iamVjdDsKKworICAgIHB1YmxpYyBQbHVnaW4oUGx1Z2luTWV0YURhdGEg
bWV0YURhdGEsIElGcmFtZUVsZW1lbnQgaWZyYW1lKSB7CisgICAgICAgIGFzc2VydCBtZXRhRGF0
YSAhPSBudWxsIDogIlBsdWdpbiBtZXRhLWRhdGEgY2Fubm90IGJlIG51bGwiOyAvLyROT04tTkxT
LTEkCisgICAgICAgIGFzc2VydCBpZnJhbWUgIT0gbnVsbCA6ICJQbHVnaW4gaWZyYW1lIGVsZW1l
bnQgY2Fubm90IGJlIG51bGwiOyAvLyROT04tTkxTLTEkCisgICAgICAgIGFzc2VydCBpZnJhbWUu
Z2V0UGFyZW50RWxlbWVudCgpID09IG51bGwgOiAiUGx1Z2luIGlmcmFtZSBlbGVtZW50IG11c3Qg
YmUgZGV0YWNoZWQgZnJvbSBET00iOyAvLyROT04tTkxTLTEkCisgICAgICAgIHRoaXMubWV0YURh
dGEgPSBtZXRhRGF0YTsKKyAgICAgICAgdGhpcy5zdGF0ZSA9IFBsdWdpblN0YXRlLkRFRklORUQ7
CisgICAgICAgIHRoaXMuaWZyYW1lID0gaWZyYW1lOworICAgIH0KKworICAgIHB1YmxpYyBQbHVn
aW5NZXRhRGF0YSBnZXRNZXRhRGF0YSgpIHsKKyAgICAgICAgcmV0dXJuIG1ldGFEYXRhOworICAg
IH0KKworICAgIHB1YmxpYyBib29sZWFuIGlzSW5TdGF0ZShQbHVnaW5TdGF0ZSBzdGF0ZSkgewor
ICAgICAgICByZXR1cm4gdGhpcy5zdGF0ZSA9PSBzdGF0ZTsKKyAgICB9CisKKyAgICBwdWJsaWMg
dm9pZCBtYXJrQXNMb2FkaW5nKCkgeworICAgICAgICBhc3NlcnQgc3RhdGUgPT0gUGx1Z2luU3Rh
dGUuREVGSU5FRCA6ICJVbmV4cGVjdGVkIHN0YXRlIHRyYW5zaXRpb24iOyAvLyROT04tTkxTLTEk
CisgICAgICAgIGFzc2VydCBpZnJhbWUuZ2V0UGFyZW50RWxlbWVudCgpICE9IG51bGwgOiAiUGx1
Z2luIGlmcmFtZSBlbGVtZW50IG11c3QgYmUgYXR0YWNoZWQgdG8gRE9NIjsgLy8kTk9OLU5MUy0x
JAorICAgICAgICBzdGF0ZSA9IFBsdWdpblN0YXRlLkxPQURJTkc7CisgICAgfQorCisgICAgcHVi
bGljIHZvaWQgbWFya0FzUmVhZHkoKSB7CisgICAgICAgIGFzc2VydCBzdGF0ZSA9PSBQbHVnaW5T
dGF0ZS5MT0FESU5HIDogIlVuZXhwZWN0ZWQgc3RhdGUgdHJhbnNpdGlvbiI7IC8vJE5PTi1OTFMt
MSQKKyAgICAgICAgYXNzZXJ0IGV2ZW50SGFuZGxlck9iamVjdCAhPSBudWxsIDogIkV2ZW50IGhh
bmRsZXIgb2JqZWN0IG11c3QgYmUgYXNzaWduZWQiOyAvLyROT04tTkxTLTEkCisgICAgICAgIHN0
YXRlID0gUGx1Z2luU3RhdGUuUkVBRFk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgbWFya0Fz
SW5pdGlhbGl6ZWQoKSB7CisgICAgICAgIGFzc2VydCBzdGF0ZSA9PSBQbHVnaW5TdGF0ZS5SRUFE
WSA6ICJVbmV4cGVjdGVkIHN0YXRlIHRyYW5zaXRpb24iOyAvLyROT04tTkxTLTEkCisgICAgICAg
IHN0YXRlID0gUGx1Z2luU3RhdGUuSU5JVElBTElaRUQ7CisgICAgfQorCisgICAgcHVibGljIElG
cmFtZUVsZW1lbnQgZ2V0SUZyYW1lRWxlbWVudCgpIHsKKyAgICAgICAgcmV0dXJuIGlmcmFtZTsK
KyAgICB9CisKKyAgICBwdWJsaWMgSmF2YVNjcmlwdE9iamVjdCBnZXRFdmVudEhhbmRsZXJPYmpl
Y3QoKSB7CisgICAgICAgIHJldHVybiBldmVudEhhbmRsZXJPYmplY3Q7CisgICAgfQorCisgICAg
cHVibGljIHZvaWQgc2V0RXZlbnRIYW5kbGVyT2JqZWN0KEphdmFTY3JpcHRPYmplY3QgZXZlbnRI
YW5kbGVyT2JqZWN0KSB7CisgICAgICAgIGFzc2VydCBldmVudEhhbmRsZXJPYmplY3QgIT0gbnVs
bCA6ICJFdmVudCBoYW5kbGVyIG9iamVjdCBjYW5ub3QgYmUgbnVsbCI7IC8vJE5PTi1OTFMtMSQK
KyAgICAgICAgdGhpcy5ldmVudEhhbmRsZXJPYmplY3QgPSBldmVudEhhbmRsZXJPYmplY3Q7Cisg
ICAgfQorCit9CmRpZmYgLS1naXQgYS9mcm9udGVuZC93ZWJhZG1pbi9tb2R1bGVzL3dlYmFkbWlu
L3NyYy9tYWluL2phdmEvb3JnL292aXJ0L2VuZ2luZS91aS93ZWJhZG1pbi9wbHVnaW4vUGx1Z2lu
RGVmaW5pdGlvbnMuamF2YSBiL2Zyb250ZW5kL3dlYmFkbWluL21vZHVsZXMvd2ViYWRtaW4vc3Jj
L21haW4vamF2YS9vcmcvb3ZpcnQvZW5naW5lL3VpL3dlYmFkbWluL3BsdWdpbi9QbHVnaW5EZWZp
bml0aW9ucy5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjgyYzhkOTgK
LS0tIC9kZXYvbnVsbAorKysgYi9mcm9udGVuZC93ZWJhZG1pbi9tb2R1bGVzL3dlYmFkbWluL3Ny
Yy9tYWluL2phdmEvb3JnL292aXJ0L2VuZ2luZS91aS93ZWJhZG1pbi9wbHVnaW4vUGx1Z2luRGVm
aW5pdGlvbnMuamF2YQpAQCAtMCwwICsxLDI0IEBACitwYWNrYWdlIG9yZy5vdmlydC5lbmdpbmUu
dWkud2ViYWRtaW4ucGx1Z2luOworCitpbXBvcnQgY29tLmdvb2dsZS5nd3QuY29yZS5jbGllbnQu
SmF2YVNjcmlwdE9iamVjdDsKK2ltcG9ydCBjb20uZ29vZ2xlLmd3dC5jb3JlLmNsaWVudC5Kc0Fy
cmF5OworCisvKioKKyAqIE92ZXJsYXkgdHlwZSBmb3Ige0Bjb2RlIHBsdWdpbkRlZmluaXRpb25z
fSBnbG9iYWwgSlMgb2JqZWN0LgorICogPHA+CisgKiBTZXJ2ZXMgYXMge0BsaW5rIFBsdWdpbk1l
dGFEYXRhfSBhZ2dyZWdhdGUgb2JqZWN0ICh1c2luZyBuYXRpdmUgYXJyYXkgcmVwcmVzZW50YXRp
b24pLgorICovCitwdWJsaWMgZmluYWwgY2xhc3MgUGx1Z2luRGVmaW5pdGlvbnMgZXh0ZW5kcyBK
YXZhU2NyaXB0T2JqZWN0IHsKKworICAgIHByb3RlY3RlZCBQbHVnaW5EZWZpbml0aW9ucygpIHsK
KyAgICB9CisKKyAgICBwdWJsaWMgc3RhdGljIG5hdGl2ZSBQbHVnaW5EZWZpbml0aW9ucyBpbnN0
YW5jZSgpIC8qLXsKKyAgICAgICAgcmV0dXJuICR3bmQucGx1Z2luRGVmaW5pdGlvbnM7CisgICAg
fS0qLzsKKworICAgIHB1YmxpYyBuYXRpdmUgSnNBcnJheTxQbHVnaW5NZXRhRGF0YT4gZ2V0TWV0
YURhdGFBcnJheSgpICAvKi17CisgICAgICAgIHJldHVybiB0aGlzOworICAgIH0tKi87CisKK30K
ZGlmZiAtLWdpdCBhL2Zyb250ZW5kL3dlYmFkbWluL21vZHVsZXMvd2ViYWRtaW4vc3JjL21haW4v
amF2YS9vcmcvb3ZpcnQvZW5naW5lL3VpL3dlYmFkbWluL3BsdWdpbi9QbHVnaW5FdmVudEhhbmRs
ZXIuamF2YSBiL2Zyb250ZW5kL3dlYmFkbWluL21vZHVsZXMvd2ViYWRtaW4vc3JjL21haW4vamF2
YS9vcmcvb3ZpcnQvZW5naW5lL3VpL3dlYmFkbWluL3BsdWdpbi9QbHVnaW5FdmVudEhhbmRsZXIu
amF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hMjVmYzc1Ci0tLSAvZGV2
L251bGwKKysrIGIvZnJvbnRlbmQvd2ViYWRtaW4vbW9kdWxlcy93ZWJhZG1pbi9zcmMvbWFpbi9q
YXZhL29yZy9vdmlydC9lbmdpbmUvdWkvd2ViYWRtaW4vcGx1Z2luL1BsdWdpbkV2ZW50SGFuZGxl
ci5qYXZhCkBAIC0wLDAgKzEsMTkgQEAKK3BhY2thZ2Ugb3JnLm92aXJ0LmVuZ2luZS51aS53ZWJh
ZG1pbi5wbHVnaW47CisKK2ltcG9ydCBjb20uZ29vZ2xlLmd3dC5ldmVudC5zaGFyZWQuRXZlbnRC
dXM7CitpbXBvcnQgY29tLmdvb2dsZS5pbmplY3QuSW5qZWN0OworCisvKioKKyAqIEhhbmRsZXMg
V2ViQWRtaW4gYXBwbGljYXRpb24gZXZlbnRzIChleHRlbnNpb24gcG9pbnRzKSB0byBiZSBjb25z
dW1lZCBieSBVSSBwbHVnaW5zLgorICogPHA+CisgKiBTaG91bGQgYmUgYm91bmQgYXMgR0lOIGVh
Z2VyIHNpbmdsZXRvbiwgY3JlYXRlZCBlYXJseSBvbiBkdXJpbmcgYXBwbGljYXRpb24gc3RhcnR1
cC4KKyAqLworcHVibGljIGNsYXNzIFBsdWdpbkV2ZW50SGFuZGxlciB7CisKKyAgICBASW5qZWN0
CisgICAgcHVibGljIFBsdWdpbkV2ZW50SGFuZGxlcihFdmVudEJ1cyBldmVudEJ1cywgUGx1Z2lu
TWFuYWdlciBtYW5hZ2VyKSB7CisgICAgICAgIC8vIFRPRE8gY2FsbCBFdmVudEJ1cy5hZGRIYW5k
bGVyIGZvciBlYWNoIGV4dGVuc2lvbiBwb2ludCAoZXZlbnQpLAorICAgICAgICAvLyB3aXRoIHRo
ZSBoYW5kbGVyIGltcGxlbWVudGF0aW9uIHVzaW5nIFBsdWdpbk1hbmFnZXIgdG8gY2FsbCBwbHVn
aW5zCisgICAgfQorCit9CmRpZmYgLS1naXQgYS9mcm9udGVuZC93ZWJhZG1pbi9tb2R1bGVzL3dl
YmFkbWluL3NyYy9tYWluL2phdmEvb3JnL292aXJ0L2VuZ2luZS91aS93ZWJhZG1pbi9wbHVnaW4v
UGx1Z2luTWFuYWdlci5qYXZhIGIvZnJvbnRlbmQvd2ViYWRtaW4vbW9kdWxlcy93ZWJhZG1pbi9z
cmMvbWFpbi9qYXZhL29yZy9vdmlydC9lbmdpbmUvdWkvd2ViYWRtaW4vcGx1Z2luL1BsdWdpbk1h
bmFnZXIuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44ZmIzZTM0Ci0t
LSAvZGV2L251bGwKKysrIGIvZnJvbnRlbmQvd2ViYWRtaW4vbW9kdWxlcy93ZWJhZG1pbi9zcmMv
bWFpbi9qYXZhL29yZy9vdmlydC9lbmdpbmUvdWkvd2ViYWRtaW4vcGx1Z2luL1BsdWdpbk1hbmFn
ZXIuamF2YQpAQCAtMCwwICsxLDI5MSBAQAorcGFja2FnZSBvcmcub3ZpcnQuZW5naW5lLnVpLndl
YmFkbWluLnBsdWdpbjsKKworaW1wb3J0IGphdmEudXRpbC5Db2xsZWN0aW9uOworaW1wb3J0IGph
dmEudXRpbC5IYXNoTWFwOworaW1wb3J0IGphdmEudXRpbC5NYXA7CitpbXBvcnQgamF2YS51dGls
LmxvZ2dpbmcuTG9nZ2VyOworCitpbXBvcnQgY29tLmdvb2dsZS5nd3QuY29yZS5jbGllbnQuSmF2
YVNjcmlwdE9iamVjdDsKK2ltcG9ydCBjb20uZ29vZ2xlLmd3dC5jb3JlLmNsaWVudC5Kc0FycmF5
OworaW1wb3J0IGNvbS5nb29nbGUuZ3d0LmRvbS5jbGllbnQuRG9jdW1lbnQ7CitpbXBvcnQgY29t
Lmdvb2dsZS5nd3QuZG9tLmNsaWVudC5JRnJhbWVFbGVtZW50OworaW1wb3J0IGNvbS5nb29nbGUu
Z3d0LmRvbS5jbGllbnQuU3R5bGUuQm9yZGVyU3R5bGU7CitpbXBvcnQgY29tLmdvb2dsZS5nd3Qu
ZG9tLmNsaWVudC5TdHlsZS5Qb3NpdGlvbjsKK2ltcG9ydCBjb20uZ29vZ2xlLmd3dC5kb20uY2xp
ZW50LlN0eWxlLlVuaXQ7CitpbXBvcnQgY29tLmdvb2dsZS5pbmplY3QuSW5qZWN0OworCisvKioK
KyAqIFRoZSBtYWluIGNvbXBvbmVudCBvZiBXZWJBZG1pbiBVSSBwbHVnaW4gaW5mcmFzdHJ1Y3R1
cmUuCisgKiA8cD4KKyAqIFNob3VsZCBiZSBib3VuZCBhcyBHSU4gZWFnZXIgc2luZ2xldG9uLCBj
cmVhdGVkIGVhcmx5IG9uIGR1cmluZyBhcHBsaWNhdGlvbiBzdGFydHVwLgorICovCitwdWJsaWMg
Y2xhc3MgUGx1Z2luTWFuYWdlciB7CisKKyAgICBwcml2YXRlIHN0YXRpYyBmaW5hbCBMb2dnZXIg
bG9nZ2VyID0gTG9nZ2VyLmdldExvZ2dlcihQbHVnaW5NYW5hZ2VyLmNsYXNzLmdldE5hbWUoKSk7
CisKKyAgICAvLyBNYXBzIHBsdWdpbiBuYW1lcyB0byBjb3JyZXNwb25kaW5nIG9iamVjdCByZXBy
ZXNlbnRhdGlvbnMKKyAgICBwcml2YXRlIGZpbmFsIE1hcDxTdHJpbmcsIFBsdWdpbj4gcGx1Z2lu
cyA9IG5ldyBIYXNoTWFwPFN0cmluZywgUGx1Z2luPigpOworCisgICAgLy8gQ29udHJvbHMgcGx1
Z2luIGludm9jYXRpb24sIGFsbG93aW5nIFdlYkFkbWluIHRvIGNhbGwgcGx1Z2lucyBvbmx5IGlu
IGEgc3BlY2lmaWMgY29udGV4dAorICAgIHByaXZhdGUgYm9vbGVhbiBjYW5JbnZva2VQbHVnaW5z
ID0gZmFsc2U7CisKKyAgICBwcml2YXRlIGZpbmFsIFBsdWdpblVpRnVuY3Rpb25zIHVpRnVuY3Rp
b25zOworCisgICAgQEluamVjdAorICAgIHB1YmxpYyBQbHVnaW5NYW5hZ2VyKFBsdWdpblVpRnVu
Y3Rpb25zIHVpRnVuY3Rpb25zKSB7CisgICAgICAgIHRoaXMudWlGdW5jdGlvbnMgPSB1aUZ1bmN0
aW9uczsKKyAgICAgICAgZXhwb3NlUGx1Z2luQXBpKCk7CisgICAgICAgIGRlZmluZUFuZExvYWRQ
bHVnaW5zKCk7CisgICAgfQorCisgICAgUGx1Z2luIGdldFBsdWdpbihTdHJpbmcgcGx1Z2luTmFt
ZSkgeworICAgICAgICByZXR1cm4gcGx1Z2lucy5nZXQocGx1Z2luTmFtZSk7CisgICAgfQorCisg
ICAgQ29sbGVjdGlvbjxQbHVnaW4+IGdldFBsdWdpbnMoKSB7CisgICAgICAgIHJldHVybiBwbHVn
aW5zLnZhbHVlcygpOworICAgIH0KKworICAgIHZvaWQgYWRkUGx1Z2luKFN0cmluZyBwbHVnaW5O
YW1lLCBQbHVnaW4gcGx1Z2luKSB7CisgICAgICAgIHBsdWdpbnMucHV0KHBsdWdpbk5hbWUsIHBs
dWdpbik7CisgICAgfQorCisgICAgLyoqCisgICAgICogRGVmaW5lcyBhbGwgcGx1Z2lucyB0aGF0
IHdlcmUgZGV0ZWN0ZWQgd2hlbiBzZXJ2aW5nIFdlYkFkbWluIGhvc3QgcGFnZSBhbmQgbG9hZHMg
dGhlbSBhcyBuZWNlc3NhcnkuCisgICAgICovCisgICAgdm9pZCBkZWZpbmVBbmRMb2FkUGx1Z2lu
cygpIHsKKyAgICAgICAgUGx1Z2luRGVmaW5pdGlvbnMgZGVmaW5pdGlvbnMgPSBQbHVnaW5EZWZp
bml0aW9ucy5pbnN0YW5jZSgpOworCisgICAgICAgIGlmIChkZWZpbml0aW9ucyAhPSBudWxsKSB7
CisgICAgICAgICAgICBKc0FycmF5PFBsdWdpbk1ldGFEYXRhPiBtZXRhRGF0YUFycmF5ID0gZGVm
aW5pdGlvbnMuZ2V0TWV0YURhdGFBcnJheSgpOworCisgICAgICAgICAgICBmb3IgKGludCBpID0g
MDsgaSA8IG1ldGFEYXRhQXJyYXkubGVuZ3RoKCk7IGkrKykgeworICAgICAgICAgICAgICAgIFBs
dWdpbk1ldGFEYXRhIHBsdWdpbk1ldGFEYXRhID0gbWV0YURhdGFBcnJheS5nZXQoaSk7CisKKyAg
ICAgICAgICAgICAgICBpZiAocGx1Z2luTWV0YURhdGEgIT0gbnVsbCkgeworICAgICAgICAgICAg
ICAgICAgICBkZWZpbmVBbmRMb2FkUGx1Z2luKHBsdWdpbk1ldGFEYXRhKTsKKyAgICAgICAgICAg
ICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAg
KiBEZWZpbmVzIGEgcGx1Z2luIGZyb20gdGhlIGdpdmVuIG1ldGEtZGF0YSBhbmQgbG9hZHMgaXQg
YXMgbmVjZXNzYXJ5LgorICAgICAqLworICAgIHZvaWQgZGVmaW5lQW5kTG9hZFBsdWdpbihQbHVn
aW5NZXRhRGF0YSBwbHVnaW5NZXRhRGF0YSkgeworICAgICAgICBTdHJpbmcgcGx1Z2luTmFtZSA9
IHBsdWdpbk1ldGFEYXRhLmdldE5hbWUoKTsKKyAgICAgICAgU3RyaW5nIHBsdWdpbkhvc3RQYWdl
VXJsID0gcGx1Z2luTWV0YURhdGEuZ2V0SG9zdFBhZ2VVcmwoKTsKKworICAgICAgICBpZiAoZ2V0
UGx1Z2luKHBsdWdpbk5hbWUpICE9IG51bGwpIHsKKyAgICAgICAgICAgIGxvZ2dlci53YXJuaW5n
KCJQbHVnaW4gIiArIHBsdWdpbk5hbWUgKyAiIGlzIGFscmVhZHkgZGVmaW5lZCIpOyAvLyROT04t
TkxTLTEkIC8vJE5PTi1OTFMtMiQKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorCisg
ICAgICAgIC8vIENyZWF0ZSBhbiBpZnJhbWUgZWxlbWVudCB1c2VkIHRvIGxvYWQgdGhlIHBsdWdp
biBob3N0IHBhZ2UKKyAgICAgICAgSUZyYW1lRWxlbWVudCBpZnJhbWUgPSBEb2N1bWVudC5nZXQo
KS5jcmVhdGVJRnJhbWVFbGVtZW50KCk7CisgICAgICAgIGlmcmFtZS5zZXRTcmMocGx1Z2luSG9z
dFBhZ2VVcmwpOworICAgICAgICBpZnJhbWUuc2V0RnJhbWVCb3JkZXIoMCk7CisgICAgICAgIGlm
cmFtZS5nZXRTdHlsZSgpLnNldFBvc2l0aW9uKFBvc2l0aW9uLkFCU09MVVRFKTsKKyAgICAgICAg
aWZyYW1lLmdldFN0eWxlKCkuc2V0V2lkdGgoMCwgVW5pdC5QVCk7CisgICAgICAgIGlmcmFtZS5n
ZXRTdHlsZSgpLnNldEhlaWdodCgwLCBVbml0LlBUKTsKKyAgICAgICAgaWZyYW1lLmdldFN0eWxl
KCkuc2V0Qm9yZGVyU3R5bGUoQm9yZGVyU3R5bGUuTk9ORSk7CisKKyAgICAgICAgUGx1Z2luIHBs
dWdpbiA9IG5ldyBQbHVnaW4ocGx1Z2luTWV0YURhdGEsIGlmcmFtZSk7CisgICAgICAgIGFkZFBs
dWdpbihwbHVnaW5OYW1lLCBwbHVnaW4pOworICAgICAgICBsb2dnZXIuaW5mbygiUGx1Z2luICIg
KyBwbHVnaW5OYW1lICsgIiBpcyBkZWZpbmVkIHRvIGJlIGxvYWRlZCBmcm9tIFVSTCAiICsgcGx1
Z2luSG9zdFBhZ2VVcmwpOyAvLyROT04tTkxTLTEkIC8vJE5PTi1OTFMtMiQKKworICAgICAgICAv
LyBUT0RPIGludHJvZHVjZSBzb21lICdsb2FkT25TdGFydHVwJyBhdHRyaWJ1dGUgaW4gZnV0dXJl
CisgICAgICAgIGxvYWRQbHVnaW4ocGx1Z2luKTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBM
b2FkcyB0aGUgZ2l2ZW4gcGx1Z2luIGJ5IGF0dGFjaGluZyB0aGUgY29ycmVzcG9uZGluZyBpZnJh
bWUgZWxlbWVudCB0byBET00uCisgICAgICovCisgICAgdm9pZCBsb2FkUGx1Z2luKFBsdWdpbiBw
bHVnaW4pIHsKKyAgICAgICAgaWYgKHBsdWdpbi5pc0luU3RhdGUoUGx1Z2luU3RhdGUuREVGSU5F
RCkpIHsKKyAgICAgICAgICAgIERvY3VtZW50LmdldCgpLmdldEJvZHkoKS5hcHBlbmRDaGlsZChw
bHVnaW4uZ2V0SUZyYW1lRWxlbWVudCgpKTsKKyAgICAgICAgICAgIHBsdWdpbi5tYXJrQXNMb2Fk
aW5nKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBDYWxsZWQgd2hlbiBX
ZWJBZG1pbiBlbnRlcnMgdGhlIHN0YXRlIHRoYXQgYWxsb3dzIHBsdWdpbnMgdG8gYmUgaW52b2tl
ZC4KKyAgICAgKi8KKyAgICBwdWJsaWMgdm9pZCBlbmFibGVQbHVnaW5JbnZvY2F0aW9uKCkgewor
ICAgICAgICBjYW5JbnZva2VQbHVnaW5zID0gdHJ1ZTsKKworICAgICAgICAvLyBUcnkgdG8gaW5p
dGlhbGl6ZSBhbGwgcGx1Z2lucyB3aGljaCBhcmUgY3VycmVudGx5IHJlYWR5CisgICAgICAgIGZv
ciAoUGx1Z2luIHBsdWdpbiA6IGdldFBsdWdpbnMoKSkgeworICAgICAgICAgICAgaWYgKHBsdWdp
bi5pc0luU3RhdGUoUGx1Z2luU3RhdGUuUkVBRFkpKSB7CisgICAgICAgICAgICAgICAgaW5pdFBs
dWdpbihwbHVnaW4uZ2V0TWV0YURhdGEoKS5nZXROYW1lKCkpOworICAgICAgICAgICAgfQorICAg
ICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQ2FsbGVkIHdoZW4gV2ViQWRtaW4gbGVh
dmVzIHRoZSBzdGF0ZSB0aGF0IGFsbG93cyBwbHVnaW5zIHRvIGJlIGludm9rZWQuCisgICAgICov
CisgICAgcHVibGljIHZvaWQgZGlzYWJsZVBsdWdpbkludm9jYXRpb24oKSB7CisgICAgICAgIGNh
bkludm9rZVBsdWdpbnMgPSBmYWxzZTsKKyAgICB9CisKKyAgICAvKioKKyAgICAgKiBJbnZva2Vz
IGFuIGV2ZW50IGhhbmRsZXIgZnVuY3Rpb24gb24gYWxsIHBsdWdpbnMgd2hpY2ggYXJlIGN1cnJl
bnRseSBpbml0aWFsaXplZC4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUge0Bjb2RlIGNvbnRleHRP
YmplY3R9IHJlcHJlc2VudHMgdGhlIGxvY2FsIGNvbnRleHQgb2YgdGhlIGdpdmVuIGZ1bmN0aW9u
IGNhbGwsIHVzZWQgdG8gcGFzcyBhZGRpdGlvbmFsCisgICAgICogY29udGV4dC1zZW5zaXRpdmUg
aW5mb3JtYXRpb24gYXMgbmVjZXNzYXJ5IChjYW4gYmUge0Bjb2RlIG51bGx9KS4KKyAgICAgKi8K
KyAgICBwdWJsaWMgdm9pZCBpbnZva2VQbHVnaW5zKFN0cmluZyBmdW5jdGlvbk5hbWUsIEphdmFT
Y3JpcHRPYmplY3QgY29udGV4dE9iamVjdCkgeworICAgICAgICBpZiAoY2FuSW52b2tlUGx1Z2lu
cykgeworICAgICAgICAgICAgZm9yIChQbHVnaW4gcGx1Z2luIDogZ2V0UGx1Z2lucygpKSB7Cisg
ICAgICAgICAgICAgICAgaWYgKHBsdWdpbi5pc0luU3RhdGUoUGx1Z2luU3RhdGUuSU5JVElBTEla
RUQpKSB7CisgICAgICAgICAgICAgICAgICAgIGludm9rZVBsdWdpbihwbHVnaW4uZ2V0RXZlbnRI
YW5kbGVyT2JqZWN0KCksIGZ1bmN0aW9uTmFtZSwgY29udGV4dE9iamVjdCk7CisgICAgICAgICAg
ICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAg
ICogSW52b2tlcyBhbiBldmVudCBoYW5kbGVyIGZ1bmN0aW9uIG9uIHRoZSBnaXZlbiBvYmplY3Qu
CisgICAgICovCisgICAgcHJpdmF0ZSBuYXRpdmUgdm9pZCBpbnZva2VQbHVnaW4oSmF2YVNjcmlw
dE9iamVjdCBwbHVnaW5FdmVudEhhbmRsZXJPYmplY3QsIFN0cmluZyBmdW5jdGlvbk5hbWUsIEph
dmFTY3JpcHRPYmplY3QgY29udGV4dE9iamVjdCkgLyoteworICAgICAgICB2YXIgaGFuZGxlckZ1
bmN0aW9uID0gcGx1Z2luRXZlbnRIYW5kbGVyT2JqZWN0W2Z1bmN0aW9uTmFtZV07CisKKyAgICAg
ICAgaWYgKHR5cGVvZiBoYW5kbGVyRnVuY3Rpb24gPT09ICdmdW5jdGlvbicpIHsKKyAgICAgICAg
ICAgIGlmIChjb250ZXh0T2JqZWN0ICE9IG51bGwpIHsKKyAgICAgICAgICAgICAgICBoYW5kbGVy
RnVuY3Rpb24oY29udGV4dE9iamVjdCk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAg
ICAgICAgIGhhbmRsZXJGdW5jdGlvbigpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAg
fS0qLzsKKworICAgIC8qKgorICAgICAqIFJldHVybnMge0Bjb2RlIHRydWV9IHdoZW4gcGx1Z2lu
IGludm9jYXRpb24gaXMgZW5hYmxlZCBhbmQgdGhlIGdpdmVuIHBsdWdpbiBoYXMgYmVlbiBpbml0
aWFsaXplZC4KKyAgICAgKi8KKyAgICBib29sZWFuIGNhbkRvUGx1Z2luQWN0aW9uKFN0cmluZyBw
bHVnaW5OYW1lKSB7CisgICAgICAgIFBsdWdpbiBwbHVnaW4gPSBnZXRQbHVnaW4ocGx1Z2luTmFt
ZSk7CisgICAgICAgIHJldHVybiBjYW5JbnZva2VQbHVnaW5zICYmIHBsdWdpbiAhPSBudWxsICYm
IHBsdWdpbi5pc0luU3RhdGUoUGx1Z2luU3RhdGUuSU5JVElBTElaRUQpOworICAgIH0KKworICAg
IC8qKgorICAgICAqIFJlZ2lzdGVycyBhbiBldmVudCBoYW5kbGVyIG9iamVjdCAob2JqZWN0IGNv
bnRhaW5pbmcgcGx1Z2luIGV2ZW50IGhhbmRsZXIgZnVuY3Rpb25zKSBmb3IgdGhlIGdpdmVuIHBs
dWdpbi4KKyAgICAgKi8KKyAgICB2b2lkIHJlZ2lzdGVyUGx1Z2luRXZlbnRIYW5kbGVyT2JqZWN0
KFN0cmluZyBwbHVnaW5OYW1lLCBKYXZhU2NyaXB0T2JqZWN0IHBsdWdpbkV2ZW50SGFuZGxlck9i
amVjdCkgeworICAgICAgICBQbHVnaW4gcGx1Z2luID0gZ2V0UGx1Z2luKHBsdWdpbk5hbWUpOwor
CisgICAgICAgIGlmIChwbHVnaW4gIT0gbnVsbCAmJiBwbHVnaW5FdmVudEhhbmRsZXJPYmplY3Qg
IT0gbnVsbCkgeworICAgICAgICAgICAgcGx1Z2luLnNldEV2ZW50SGFuZGxlck9iamVjdChwbHVn
aW5FdmVudEhhbmRsZXJPYmplY3QpOworICAgICAgICAgICAgbG9nZ2VyLmluZm8oIlBsdWdpbiAi
ICsgcGx1Z2luTmFtZSArICIgaGFzIHJlZ2lzdGVyZWQgdGhlIGV2ZW50IGhhbmRsZXIgb2JqZWN0
Iik7IC8vJE5PTi1OTFMtMSQgLy8kTk9OLU5MUy0yJAorICAgICAgICB9CisgICAgfQorCisgICAg
LyoqCisgICAgICogSW5kaWNhdGVzIHRoYXQgdGhlIGdpdmVuIHBsdWdpbiBpcyByZWFkeSBmb3Ig
dXNlLgorICAgICAqLworICAgIHZvaWQgcGx1Z2luUmVhZHkoU3RyaW5nIHBsdWdpbk5hbWUpIHsK
KyAgICAgICAgUGx1Z2luIHBsdWdpbiA9IGdldFBsdWdpbihwbHVnaW5OYW1lKTsKKworICAgICAg
ICBpZiAocGx1Z2luICE9IG51bGwgJiYgcGx1Z2luLmlzSW5TdGF0ZShQbHVnaW5TdGF0ZS5MT0FE
SU5HKSkgeworICAgICAgICAgICAgaWYgKHBsdWdpbi5nZXRFdmVudEhhbmRsZXJPYmplY3QoKSA9
PSBudWxsKSB7CisgICAgICAgICAgICAgICAgbG9nZ2VyLndhcm5pbmcoIlBsdWdpbiAiICsgcGx1
Z2luTmFtZSAvLyROT04tTkxTLTEkCisgICAgICAgICAgICAgICAgICAgICAgICArICIgcmVwb3J0
cyBpbiBhcyByZWFkeSwgYnV0IGhhcyBubyBldmVudCBoYW5kbGVyIG9iamVjdCBhc3NpZ25lZCIp
OyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgfQor
CisgICAgICAgICAgICBwbHVnaW4ubWFya0FzUmVhZHkoKTsKKyAgICAgICAgICAgIGxvZ2dlci5p
bmZvKCJQbHVnaW4gIiArIHBsdWdpbk5hbWUgKyAiIHJlcG9ydHMgaW4gYXMgcmVhZHkiKTsgLy8k
Tk9OLU5MUy0xJCAvLyROT04tTkxTLTIkCisgICAgICAgICAgICBpbml0UGx1Z2luKHBsdWdpbk5h
bWUpOworICAgICAgICB9CisgICAgfQorCisgICAgLyoqCisgICAgICogQXR0ZW1wdHMgdG8gaW5p
dGlhbGl6ZSB0aGUgZ2l2ZW4gcGx1Z2luIGJ5IGNhbGxpbmcgVWlJbml0IGV2ZW50IGhhbmRsZXIg
ZnVuY3Rpb24gb24gdGhlIGNvcnJlc3BvbmRpbmcgZXZlbnQKKyAgICAgKiBoYW5kbGVyIG9iamVj
dC4KKyAgICAgKiA8cD4KKyAgICAgKiBUaGUgVWlJbml0IGZ1bmN0aW9uIHdpbGwgYmUgY2FsbGVk
IGp1c3Qgb25jZSBkdXJpbmcgdGhlIGxpZmV0aW1lIG9mIGEgcGx1Z2luLiBNb3JlIHByZWNpc2Vs
eSwgVWlJbml0IGZ1bmN0aW9uCisgICAgICogd2lsbCBiZSBjYWxsZWQ6CisgICAgICogPHVsPgor
ICAgICAqIDxsaT5hZnRlciB0aGUgcGx1Z2luIHJlcG9ydHMgaW4gYXMgcmVhZHkgYW5kIFdlYkFk
bWluIGVudGVycyB0aGUgc3RhdGUgdGhhdCBhbGxvd3MgcGx1Z2lucyB0byBiZSBpbnZva2VkCisg
ICAgICogPGxpPmJlZm9yZSBhbnkgb3RoZXIgZXZlbnQgaGFuZGxlciBmdW5jdGlvbnMgYXJlIGlu
dm9rZWQgYnkgdGhlIHBsdWdpbiBpbmZyYXN0cnVjdHVyZQorICAgICAqIDwvdWw+CisgICAgICov
CisgICAgdm9pZCBpbml0UGx1Z2luKFN0cmluZyBwbHVnaW5OYW1lKSB7CisgICAgICAgIFBsdWdp
biBwbHVnaW4gPSBnZXRQbHVnaW4ocGx1Z2luTmFtZSk7CisKKyAgICAgICAgaWYgKGNhbkludm9r
ZVBsdWdpbnMgJiYgcGx1Z2luICE9IG51bGwgJiYgcGx1Z2luLmlzSW5TdGF0ZShQbHVnaW5TdGF0
ZS5SRUFEWSkpIHsKKyAgICAgICAgICAgIHBsdWdpbi5tYXJrQXNJbml0aWFsaXplZCgpOworICAg
ICAgICAgICAgaW52b2tlUGx1Z2luKHBsdWdpbi5nZXRFdmVudEhhbmRsZXJPYmplY3QoKSwgIlVp
SW5pdCIsIG51bGwpOyAvLyROT04tTkxTLTEkCisgICAgICAgICAgICBsb2dnZXIuaW5mbygiUGx1
Z2luICIgKyBwbHVnaW5OYW1lICsgIiBpcyBpbml0aWFsaXplZCBhbmQgaW4gdXNlIG5vdyIpOyAv
LyROT04tTkxTLTEkIC8vJE5PTi1OTFMtMiQKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qKgor
ICAgICAqIFJldHVybnMgdGhlIGNvbmZpZ3VyYXRpb24gb2JqZWN0IGFzc29jaWF0ZWQgd2l0aCB0
aGUgZ2l2ZW4gcGx1Z2luLCBvciB7QGNvZGUgbnVsbH0gaWYgbm8gc3VjaCBvYmplY3QgZXhpc3Rz
LgorICAgICAqLworICAgIEphdmFTY3JpcHRPYmplY3QgZ2V0Q29uZmlnT2JqZWN0KFN0cmluZyBw
bHVnaW5OYW1lKSB7CisgICAgICAgIFBsdWdpbiBwbHVnaW4gPSBnZXRQbHVnaW4ocGx1Z2luTmFt
ZSk7CisgICAgICAgIHJldHVybiBwbHVnaW4gIT0gbnVsbCA/IHBsdWdpbi5nZXRNZXRhRGF0YSgp
LmdldENvbmZpZ09iamVjdCgpIDogbnVsbDsKKyAgICB9CisKKyAgICBwcml2YXRlIG5hdGl2ZSB2
b2lkIGV4cG9zZVBsdWdpbkFwaSgpIC8qLXsKKyAgICAgICAgdmFyIGN0eCA9IHRoaXM7CisgICAg
ICAgIHZhciB1aUZ1bmN0aW9ucyA9IGN0eC5Ab3JnLm92aXJ0LmVuZ2luZS51aS53ZWJhZG1pbi5w
bHVnaW4uUGx1Z2luTWFuYWdlcjo6dWlGdW5jdGlvbnM7CisKKyAgICAgICAgdmFyIGNhbkRvUGx1
Z2luQWN0aW9uID0gZnVuY3Rpb24ocGx1Z2luTmFtZSkgeworICAgICAgICAgICAgcmV0dXJuIGN0
eC5Ab3JnLm92aXJ0LmVuZ2luZS51aS53ZWJhZG1pbi5wbHVnaW4uUGx1Z2luTWFuYWdlcjo6Y2Fu
RG9QbHVnaW5BY3Rpb24oTGphdmEvbGFuZy9TdHJpbmc7KShwbHVnaW5OYW1lKTsKKyAgICAgICAg
fTsKKworICAgICAgICAvLyBEZWZpbmUgcGx1Z2luQXBpIGZ1bmN0aW9uIHVzZWQgdG8gY29uc3Ry
dWN0IHNwZWNpZmljIFBsdWdpbiBBUEkgaW5zdGFuY2VzCisgICAgICAgIHZhciBwbHVnaW5BcGkg
PSBmdW5jdGlvbihwbHVnaW5OYW1lKSB7CisgICAgICAgICAgICByZXR1cm4gbmV3IHBsdWdpbkFw
aS5mbi5pbml0KHBsdWdpbk5hbWUpOworICAgICAgICB9OworCisgICAgICAgIC8vIERlZmluZSBw
bHVnaW5BcGkuZm4gYXMgYW4gYWxpYXMgdG8gcGx1Z2luQXBpIHByb3RvdHlwZQorICAgICAgICBw
bHVnaW5BcGkuZm4gPSBwbHVnaW5BcGkucHJvdG90eXBlID0geworCisgICAgICAgICAgICBwbHVn
aW5OYW1lOiBudWxsLCAvLyBJbml0aWFsaXplZCBpbiBjb25zdHJ1Y3RvciBmdW5jdGlvbgorCisg
ICAgICAgICAgICAvLyBDb25zdHJ1Y3RvciBmdW5jdGlvbgorICAgICAgICAgICAgaW5pdDogZnVu
Y3Rpb24ocGx1Z2luTmFtZSkgeworICAgICAgICAgICAgICAgIHRoaXMucGx1Z2luTmFtZSA9IHBs
dWdpbk5hbWU7CisgICAgICAgICAgICAgICAgdGhpcy51aS5vd25lciA9IHRoaXM7CisgICAgICAg
ICAgICAgICAgcmV0dXJuIHRoaXM7CisgICAgICAgICAgICB9LAorCisgICAgICAgICAgICAvLyBS
ZWdpc3RlcnMgcGx1Z2luIGV2ZW50IGhhbmRsZXIgZnVuY3Rpb25zIGZvciBsYXRlciBpbnZvY2F0
aW9uCisgICAgICAgICAgICByZWdpc3RlcjogZnVuY3Rpb24ocGx1Z2luRXZlbnRIYW5kbGVyT2Jq
ZWN0KSB7CisgICAgICAgICAgICAgICAgY3R4LkBvcmcub3ZpcnQuZW5naW5lLnVpLndlYmFkbWlu
LnBsdWdpbi5QbHVnaW5NYW5hZ2VyOjpyZWdpc3RlclBsdWdpbkV2ZW50SGFuZGxlck9iamVjdChM
amF2YS9sYW5nL1N0cmluZztMY29tL2dvb2dsZS9nd3QvY29yZS9jbGllbnQvSmF2YVNjcmlwdE9i
amVjdDspKHRoaXMucGx1Z2luTmFtZSxwbHVnaW5FdmVudEhhbmRsZXJPYmplY3QpOworICAgICAg
ICAgICAgfSwKKworICAgICAgICAgICAgLy8gSW5kaWNhdGVzIHRoYXQgdGhlIHBsdWdpbiBpcyBy
ZWFkeSBmb3IgdXNlCisgICAgICAgICAgICByZWFkeTogZnVuY3Rpb24oKSB7CisgICAgICAgICAg
ICAgICAgY3R4LkBvcmcub3ZpcnQuZW5naW5lLnVpLndlYmFkbWluLnBsdWdpbi5QbHVnaW5NYW5h
Z2VyOjpwbHVnaW5SZWFkeShMamF2YS9sYW5nL1N0cmluZzspKHRoaXMucGx1Z2luTmFtZSk7Cisg
ICAgICAgICAgICB9LAorCisgICAgICAgICAgICAvLyBSZXR1cm5zIHRoZSBjb25maWd1cmF0aW9u
IG9iamVjdCBhc3NvY2lhdGVkIHdpdGggdGhlIHBsdWdpbgorICAgICAgICAgICAgY29uZmlnT2Jq
ZWN0OiBmdW5jdGlvbigpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gY3R4LkBvcmcub3ZpcnQu
ZW5naW5lLnVpLndlYmFkbWluLnBsdWdpbi5QbHVnaW5NYW5hZ2VyOjpnZXRDb25maWdPYmplY3Qo
TGphdmEvbGFuZy9TdHJpbmc7KSh0aGlzLnBsdWdpbk5hbWUpOworICAgICAgICAgICAgfSwKKwor
ICAgICAgICAgICAgLy8gTmFtZXNwYWNlIGZvciBpbnZva2luZyBQbHVnaW5VaUZ1bmN0aW9ucwor
ICAgICAgICAgICAgdWk6IHsKKworICAgICAgICAgICAgICAgIGFkZE1haW5UYWI6IGZ1bmN0aW9u
KGxhYmVsLCBoaXN0b3J5VG9rZW4sIGNvbnRlbnRVcmwpIHsKKyAgICAgICAgICAgICAgICAgICAg
aWYgKGNhbkRvUGx1Z2luQWN0aW9uKHRoaXMub3duZXIucGx1Z2luTmFtZSkpIHsKKyAgICAgICAg
ICAgICAgICAgICAgICAgIHVpRnVuY3Rpb25zLkBvcmcub3ZpcnQuZW5naW5lLnVpLndlYmFkbWlu
LnBsdWdpbi5QbHVnaW5VaUZ1bmN0aW9uczo6YWRkTWFpblRhYihMamF2YS9sYW5nL1N0cmluZztM
amF2YS9sYW5nL1N0cmluZztMamF2YS9sYW5nL1N0cmluZzspKGxhYmVsLGhpc3RvcnlUb2tlbixj
b250ZW50VXJsKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKwor
ICAgICAgICAgICAgfQorCisgICAgICAgIH07CisKKyAgICAgICAgLy8gR2l2ZSBpbml0IGZ1bmN0
aW9uIHRoZSBwbHVnaW5BcGkgcHJvdG90eXBlIGZvciBsYXRlciBpbnN0YW50aWF0aW9uCisgICAg
ICAgIHBsdWdpbkFwaS5mbi5pbml0LnByb3RvdHlwZSA9IHBsdWdpbkFwaS5mbjsKKworICAgICAg
ICAvLyBFeHBvc2UgcGx1Z2luQXBpIGZ1bmN0aW9uIGFzIGEgZ2xvYmFsIG9iamVjdAorICAgICAg
ICAkd25kLnBsdWdpbkFwaSA9IHBsdWdpbkFwaTsKKyAgICB9LSovOworCit9CmRpZmYgLS1naXQg
YS9mcm9udGVuZC93ZWJhZG1pbi9tb2R1bGVzL3dlYmFkbWluL3NyYy9tYWluL2phdmEvb3JnL292
aXJ0L2VuZ2luZS91aS93ZWJhZG1pbi9wbHVnaW4vUGx1Z2luTWV0YURhdGEuamF2YSBiL2Zyb250
ZW5kL3dlYmFkbWluL21vZHVsZXMvd2ViYWRtaW4vc3JjL21haW4vamF2YS9vcmcvb3ZpcnQvZW5n
aW5lL3VpL3dlYmFkbWluL3BsdWdpbi9QbHVnaW5NZXRhRGF0YS5qYXZhCm5ldyBmaWxlIG1vZGUg
MTAwNjQ0CmluZGV4IDAwMDAwMDAuLmE2ZjMxYjkKLS0tIC9kZXYvbnVsbAorKysgYi9mcm9udGVu
ZC93ZWJhZG1pbi9tb2R1bGVzL3dlYmFkbWluL3NyYy9tYWluL2phdmEvb3JnL292aXJ0L2VuZ2lu
ZS91aS93ZWJhZG1pbi9wbHVnaW4vUGx1Z2luTWV0YURhdGEuamF2YQpAQCAtMCwwICsxLDM2IEBA
CitwYWNrYWdlIG9yZy5vdmlydC5lbmdpbmUudWkud2ViYWRtaW4ucGx1Z2luOworCitpbXBvcnQg
Y29tLmdvb2dsZS5nd3QuY29yZS5jbGllbnQuSmF2YVNjcmlwdE9iamVjdDsKKworLyoqCisgKiBD
b250YWlucyBtZXRhLWRhdGEgZGVzY3JpYmluZyBhIFVJIHBsdWdpbi4KKyAqIDxwPgorICogV2Ug
ZXhwZWN0IHRoZSBtZXRhLWRhdGEgdG8gYmUgcmVhZCBkdXJpbmcgV2ViQWRtaW4gc3RhcnR1cCBh
cyBwYXJ0IG9mIHtAbGluayBQbHVnaW5EZWZpbml0aW9uc30uCisgKi8KK3B1YmxpYyBmaW5hbCBj
bGFzcyBQbHVnaW5NZXRhRGF0YSBleHRlbmRzIEphdmFTY3JpcHRPYmplY3QgeworCisgICAgcHJv
dGVjdGVkIFBsdWdpbk1ldGFEYXRhKCkgeworICAgIH0KKworICAgIC8qKgorICAgICAqIEEgbmFt
ZSB0aGF0IHVuaXF1ZWx5IGlkZW50aWZpZXMgdGhlIHBsdWdpbiAobWFuZGF0b3J5KS4KKyAgICAg
Ki8KKyAgICBwdWJsaWMgbmF0aXZlIFN0cmluZyBnZXROYW1lKCkgIC8qLXsKKyAgICAgICAgcmV0
dXJuIHRoaXMubmFtZTsKKyAgICB9LSovOworCisgICAgLyoqCisgICAgICogVVJMIG9mIHBsdWdp
biBob3N0IHBhZ2UgdGhhdCBpbnZva2VzIHRoZSBwbHVnaW4gY29kZSAobWFuZGF0b3J5KS4KKyAg
ICAgKi8KKyAgICBwdWJsaWMgbmF0aXZlIFN0cmluZyBnZXRIb3N0UGFnZVVybCgpIC8qLXsKKyAg
ICAgICAgcmV0dXJuIHRoaXMudXJsOworICAgIH0tKi87CisKKyAgICAvKioKKyAgICAgKiBDb25m
aWd1cmF0aW9uIG9iamVjdCBhc3NvY2lhdGVkIHdpdGggdGhlIHBsdWdpbiAob3B0aW9uYWwpLgor
ICAgICAqLworICAgIHB1YmxpYyBuYXRpdmUgSmF2YVNjcmlwdE9iamVjdCBnZXRDb25maWdPYmpl
Y3QoKSAvKi17CisgICAgICAgIHJldHVybiB0aGlzLmNvbmZpZzsKKyAgICB9LSovOworCit9CmRp
ZmYgLS1naXQgYS9mcm9udGVuZC93ZWJhZG1pbi9tb2R1bGVzL3dlYmFkbWluL3NyYy9tYWluL2ph
dmEvb3JnL292aXJ0L2VuZ2luZS91aS93ZWJhZG1pbi9wbHVnaW4vUGx1Z2luU3RhdGUuamF2YSBi
L2Zyb250ZW5kL3dlYmFkbWluL21vZHVsZXMvd2ViYWRtaW4vc3JjL21haW4vamF2YS9vcmcvb3Zp
cnQvZW5naW5lL3VpL3dlYmFkbWluL3BsdWdpbi9QbHVnaW5TdGF0ZS5qYXZhCm5ldyBmaWxlIG1v
ZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjA1YzZiOTgKLS0tIC9kZXYvbnVsbAorKysgYi9mcm9u
dGVuZC93ZWJhZG1pbi9tb2R1bGVzL3dlYmFkbWluL3NyYy9tYWluL2phdmEvb3JnL292aXJ0L2Vu
Z2luZS91aS93ZWJhZG1pbi9wbHVnaW4vUGx1Z2luU3RhdGUuamF2YQpAQCAtMCwwICsxLDMzIEBA
CitwYWNrYWdlIG9yZy5vdmlydC5lbmdpbmUudWkud2ViYWRtaW4ucGx1Z2luOworCisvKioKKyAq
IEVudW1lcmF0ZXMgcG9zc2libGUgc3RhdGVzIGR1cmluZyB0aGUgcnVudGltZSBvZiBhIFVJIHBs
dWdpbi4KKyAqLworcHVibGljIGVudW0gUGx1Z2luU3RhdGUgeworCisgICAgLyoqCisgICAgICog
VGhlIHBsdWdpbiBoYXMgYmVlbiBkZWZpbmVkIHRocm91Z2ggaXRzIG1ldGEtZGF0YSBhbmQgdGhl
IGNvcnJlc3BvbmRpbmcgaWZyYW1lIGVsZW1lbnQgaGFzIGJlZW4gY3JlYXRlZC4KKyAgICAgKiA8
cD4KKyAgICAgKiBUaGlzIGlzIHRoZSBpbml0aWFsIHN0YXRlIGZvciBhbGwgcGx1Z2lucy4KKyAg
ICAgKi8KKyAgICBERUZJTkVELAorCisgICAgLyoqCisgICAgICogVGhlIGlmcmFtZSBlbGVtZW50
IGhhcyBiZWVuIGF0dGFjaGVkIHRvIERPTSwgd2l0aCBwbHVnaW4gaG9zdCBwYWdlIGJlaW5nIGZl
dGNoZWQgYXN5bmNocm9ub3VzbHkgaW4gdGhlCisgICAgICogYmFja2dyb3VuZC4gV2UgYXJlIG5v
dyB3YWl0aW5nIGZvciB0aGUgcGx1Z2luIHRvIHJlcG9ydCBpbiBhcyByZWFkeS4KKyAgICAgKi8K
KyAgICBMT0FESU5HLAorCisgICAgLyoqCisgICAgICogVGhlIHBsdWdpbiBoYXMgaW5kaWNhdGVk
IHRoYXQgaXQgaXMgcmVhZHkgZm9yIHVzZS4gV2UgZXhwZWN0IHRoZSBldmVudCBoYW5kbGVyIG9i
amVjdCAob2JqZWN0IGNvbnRhaW5pbmcgcGx1Z2luCisgICAgICogZXZlbnQgaGFuZGxlciBmdW5j
dGlvbnMpIHRvIGJlIHJlZ2lzdGVyZWQgYXQgdGhpcyBwb2ludC4gV2UgY2FuIG5vdyBwcm9jZWVk
IHdpdGggcGx1Z2luIGluaXRpYWxpemF0aW9uLgorICAgICAqLworICAgIFJFQURZLAorCisgICAg
LyoqCisgICAgICogVGhlIHBsdWdpbiBoYXMgYmVlbiBpbml0aWFsaXplZCBieSBjYWxsaW5nIFVp
SW5pdCBldmVudCBoYW5kbGVyIGZ1bmN0aW9uLiBXZSBjYW4gbm93IGNhbGwgb3RoZXIgZXZlbnQg
aGFuZGxlcgorICAgICAqIGZ1bmN0aW9ucyAodGhlIHBsdWdpbiBpcyBpbiB1c2UpLgorICAgICAq
LworICAgIElOSVRJQUxJWkVECisKK30KZGlmZiAtLWdpdCBhL2Zyb250ZW5kL3dlYmFkbWluL21v
ZHVsZXMvd2ViYWRtaW4vc3JjL21haW4vamF2YS9vcmcvb3ZpcnQvZW5naW5lL3VpL3dlYmFkbWlu
L3BsdWdpbi9QbHVnaW5VaUZ1bmN0aW9ucy5qYXZhIGIvZnJvbnRlbmQvd2ViYWRtaW4vbW9kdWxl
cy93ZWJhZG1pbi9zcmMvbWFpbi9qYXZhL29yZy9vdmlydC9lbmdpbmUvdWkvd2ViYWRtaW4vcGx1
Z2luL1BsdWdpblVpRnVuY3Rpb25zLmphdmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAw
MDAwMC4uZGE1NTBmNgotLS0gL2Rldi9udWxsCisrKyBiL2Zyb250ZW5kL3dlYmFkbWluL21vZHVs
ZXMvd2ViYWRtaW4vc3JjL21haW4vamF2YS9vcmcvb3ZpcnQvZW5naW5lL3VpL3dlYmFkbWluL3Bs
dWdpbi9QbHVnaW5VaUZ1bmN0aW9ucy5qYXZhCkBAIC0wLDAgKzEsMjYgQEAKK3BhY2thZ2Ugb3Jn
Lm92aXJ0LmVuZ2luZS51aS53ZWJhZG1pbi5wbHVnaW47CisKK2ltcG9ydCBvcmcub3ZpcnQuZW5n
aW5lLnVpLndlYmFkbWluLnNlY3Rpb24ubWFpbi5wcmVzZW50ZXIudGFiLk1haW5UYWJDdXN0b21Q
cm94eUZhY3Rvcnk7CisKK2ltcG9ydCBjb20uZ29vZ2xlLmluamVjdC5JbmplY3Q7CisKKy8qKgor
ICogQ29udGFpbnMgVUkgcmVsYXRlZCBmdW5jdGlvbmFsaXR5IGV4cG9zZWQgdG8gVUkgcGx1Z2lu
cy4KKyAqLworcHVibGljIGNsYXNzIFBsdWdpblVpRnVuY3Rpb25zIHsKKworICAgIHByaXZhdGUg
ZmluYWwgTWFpblRhYkN1c3RvbVByb3h5RmFjdG9yeSBtYWluVGFiQ3VzdG9tUHJveHlGYWN0b3J5
OworCisgICAgQEluamVjdAorICAgIHB1YmxpYyBQbHVnaW5VaUZ1bmN0aW9ucyhNYWluVGFiQ3Vz
dG9tUHJveHlGYWN0b3J5IG1haW5UYWJDdXN0b21Qcm94eUZhY3RvcnkpIHsKKyAgICAgICAgdGhp
cy5tYWluVGFiQ3VzdG9tUHJveHlGYWN0b3J5ID0gbWFpblRhYkN1c3RvbVByb3h5RmFjdG9yeTsK
KyAgICB9CisKKyAgICAvKioKKyAgICAgKiBBZGRzIG5ldyBtYWluIHRhYiB0aGF0IHNob3dzIGNv
bnRlbnRzIG9mIHRoZSBnaXZlbiBVUkwuCisgICAgICovCisgICAgcHVibGljIHZvaWQgYWRkTWFp
blRhYihTdHJpbmcgbGFiZWwsIFN0cmluZyBoaXN0b3J5VG9rZW4sIFN0cmluZyBjb250ZW50VXJs
KSB7CisgICAgICAgIG1haW5UYWJDdXN0b21Qcm94eUZhY3RvcnkuY3JlYXRlKGxhYmVsLCBoaXN0
b3J5VG9rZW4sIGNvbnRlbnRVcmwpOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvZnJvbnRlbmQv
d2ViYWRtaW4vbW9kdWxlcy93ZWJhZG1pbi9zcmMvbWFpbi9qYXZhL29yZy9vdmlydC9lbmdpbmUv
dWkvd2ViYWRtaW4vc2VjdGlvbi9tYWluL3ByZXNlbnRlci9NYWluU2VjdGlvblByZXNlbnRlci5q
YXZhIGIvZnJvbnRlbmQvd2ViYWRtaW4vbW9kdWxlcy93ZWJhZG1pbi9zcmMvbWFpbi9qYXZhL29y
Zy9vdmlydC9lbmdpbmUvdWkvd2ViYWRtaW4vc2VjdGlvbi9tYWluL3ByZXNlbnRlci9NYWluU2Vj
dGlvblByZXNlbnRlci5qYXZhCmluZGV4IDcxOGQ4ZmMuLjE1Yjg4N2MgMTAwNjQ0Ci0tLSBhL2Zy
b250ZW5kL3dlYmFkbWluL21vZHVsZXMvd2ViYWRtaW4vc3JjL21haW4vamF2YS9vcmcvb3ZpcnQv
ZW5naW5lL3VpL3dlYmFkbWluL3NlY3Rpb24vbWFpbi9wcmVzZW50ZXIvTWFpblNlY3Rpb25QcmVz
ZW50ZXIuamF2YQorKysgYi9mcm9udGVuZC93ZWJhZG1pbi9tb2R1bGVzL3dlYmFkbWluL3NyYy9t
YWluL2phdmEvb3JnL292aXJ0L2VuZ2luZS91aS93ZWJhZG1pbi9zZWN0aW9uL21haW4vcHJlc2Vu
dGVyL01haW5TZWN0aW9uUHJlc2VudGVyLmphdmEKQEAgLTEsNSArMSw3IEBACiBwYWNrYWdlIG9y
Zy5vdmlydC5lbmdpbmUudWkud2ViYWRtaW4uc2VjdGlvbi5tYWluLnByZXNlbnRlcjsKIAoraW1w
b3J0IG9yZy5vdmlydC5lbmdpbmUudWkud2ViYWRtaW4ucGx1Z2luLlBsdWdpbk1hbmFnZXI7CisK
IGltcG9ydCBjb20uZ29vZ2xlLmd3dC5ldmVudC5zaGFyZWQuRXZlbnRCdXM7CiBpbXBvcnQgY29t
Lmdvb2dsZS5nd3QuZXZlbnQuc2hhcmVkLkd3dEV2ZW50LlR5cGU7CiBpbXBvcnQgY29tLmdvb2ds
ZS5pbmplY3QuSW5qZWN0OwpAQCAtMjgsMTEgKzMwLDEzIEBAIHB1YmxpYyBjbGFzcyBNYWluU2Vj
dGlvblByZXNlbnRlciBleHRlbmRzIFByZXNlbnRlcjxNYWluU2VjdGlvblByZXNlbnRlci5WaWV3
RGVmCiAgICAgcHVibGljIHN0YXRpYyBmaW5hbCBUeXBlPFJldmVhbENvbnRlbnRIYW5kbGVyPD8+
PiBUWVBFX1NldE1haW5Db250ZW50ID0gbmV3IFR5cGU8UmV2ZWFsQ29udGVudEhhbmRsZXI8Pz4+
KCk7CiAKICAgICBwcml2YXRlIGZpbmFsIEhlYWRlclByZXNlbnRlcldpZGdldCBoZWFkZXI7Cisg
ICAgcHJpdmF0ZSBmaW5hbCBQbHVnaW5NYW5hZ2VyIHBsdWdpbk1hbmFnZXI7CiAKICAgICBASW5q
ZWN0Ci0gICAgcHVibGljIE1haW5TZWN0aW9uUHJlc2VudGVyKEV2ZW50QnVzIGV2ZW50QnVzLCBW
aWV3RGVmIHZpZXcsIFByb3h5RGVmIHByb3h5LCBIZWFkZXJQcmVzZW50ZXJXaWRnZXQgaGVhZGVy
KSB7CisgICAgcHVibGljIE1haW5TZWN0aW9uUHJlc2VudGVyKEV2ZW50QnVzIGV2ZW50QnVzLCBW
aWV3RGVmIHZpZXcsIFByb3h5RGVmIHByb3h5LCBIZWFkZXJQcmVzZW50ZXJXaWRnZXQgaGVhZGVy
LCBQbHVnaW5NYW5hZ2VyIHBsdWdpbk1hbmFnZXIpIHsKICAgICAgICAgc3VwZXIoZXZlbnRCdXMs
IHZpZXcsIHByb3h5KTsKICAgICAgICAgdGhpcy5oZWFkZXIgPSBoZWFkZXI7CisgICAgICAgIHRo
aXMucGx1Z2luTWFuYWdlciA9IHBsdWdpbk1hbmFnZXI7CiAgICAgICAgIGdldFZpZXcoKS5zZXRV
aUhhbmRsZXJzKGhlYWRlcik7CiAgICAgfQogCkBAIC00Niw2ICs1MCwxNyBAQCBwdWJsaWMgY2xh
c3MgTWFpblNlY3Rpb25QcmVzZW50ZXIgZXh0ZW5kcyBQcmVzZW50ZXI8TWFpblNlY3Rpb25QcmVz
ZW50ZXIuVmlld0RlZgogICAgICAgICBzdXBlci5vblJldmVhbCgpOwogCiAgICAgICAgIHNldElu
U2xvdChUWVBFX1NldEhlYWRlciwgaGVhZGVyKTsKKworICAgICAgICAvLyBFbmFibGUgcGx1Z2lu
IGludm9jYXRpb24gd2l0aGluIHRoZSBzY29wZSBvZiBtYWluIHNlY3Rpb24KKyAgICAgICAgcGx1
Z2luTWFuYWdlci5lbmFibGVQbHVnaW5JbnZvY2F0aW9uKCk7CisgICAgfQorCisgICAgQE92ZXJy
aWRlCisgICAgcHJvdGVjdGVkIHZvaWQgb25IaWRlKCkgeworICAgICAgICBzdXBlci5vbkhpZGUo
KTsKKworICAgICAgICAvLyBEaXNhYmxlIHBsdWdpbiBpbnZvY2F0aW9uIG91dHNpZGUgdGhlIHNj
b3BlIG9mIG1haW4gc2VjdGlvbgorICAgICAgICBwbHVnaW5NYW5hZ2VyLmRpc2FibGVQbHVnaW5J
bnZvY2F0aW9uKCk7CiAgICAgfQogCiB9CmRpZmYgLS1naXQgYS9mcm9udGVuZC93ZWJhZG1pbi9t
b2R1bGVzL3dlYmFkbWluL3NyYy9tYWluL2phdmEvb3JnL292aXJ0L2VuZ2luZS91aS93ZWJhZG1p
bi9zZWN0aW9uL21haW4vcHJlc2VudGVyL01haW5UYWJQYW5lbFByZXNlbnRlci5qYXZhIGIvZnJv
bnRlbmQvd2ViYWRtaW4vbW9kdWxlcy93ZWJhZG1pbi9zcmMvbWFpbi9qYXZhL29yZy9vdmlydC9l
bmdpbmUvdWkvd2ViYWRtaW4vc2VjdGlvbi9tYWluL3ByZXNlbnRlci9NYWluVGFiUGFuZWxQcmVz
ZW50ZXIuamF2YQppbmRleCBhYzA0MDAxLi42MTEyZDM4IDEwMDY0NAotLS0gYS9mcm9udGVuZC93
ZWJhZG1pbi9tb2R1bGVzL3dlYmFkbWluL3NyYy9tYWluL2phdmEvb3JnL292aXJ0L2VuZ2luZS91
aS93ZWJhZG1pbi9zZWN0aW9uL21haW4vcHJlc2VudGVyL01haW5UYWJQYW5lbFByZXNlbnRlci5q
YXZhCisrKyBiL2Zyb250ZW5kL3dlYmFkbWluL21vZHVsZXMvd2ViYWRtaW4vc3JjL21haW4vamF2
YS9vcmcvb3ZpcnQvZW5naW5lL3VpL3dlYmFkbWluL3NlY3Rpb24vbWFpbi9wcmVzZW50ZXIvTWFp
blRhYlBhbmVsUHJlc2VudGVyLmphdmEKQEAgLTUsNiArNSw3IEBAIGltcG9ydCBvcmcub3ZpcnQu
ZW5naW5lLnVpLmNvbW1vbi53aWRnZXQudGFiLkFic3RyYWN0SGVhZGxlc3NUYWJQYW5lbC5UYWJX
aWRnZXRICiBpbXBvcnQgY29tLmdvb2dsZS5nd3QuZXZlbnQuc2hhcmVkLkV2ZW50QnVzOwogaW1w
b3J0IGNvbS5nb29nbGUuZ3d0LmV2ZW50LnNoYXJlZC5Hd3RFdmVudC5UeXBlOwogaW1wb3J0IGNv
bS5nb29nbGUuaW5qZWN0LkluamVjdDsKK2ltcG9ydCBjb20uZ3d0cGxhdGZvcm0ubXZwLmNsaWVu
dC5SZXF1ZXN0VGFic0V2ZW50OwogaW1wb3J0IGNvbS5nd3RwbGF0Zm9ybS5tdnAuY2xpZW50LlJl
cXVlc3RUYWJzSGFuZGxlcjsKIGltcG9ydCBjb20uZ3d0cGxhdGZvcm0ubXZwLmNsaWVudC5UYWJD
b250YWluZXJQcmVzZW50ZXI7CiBpbXBvcnQgY29tLmd3dHBsYXRmb3JtLm12cC5jbGllbnQuVGFi
VmlldzsKQEAgLTQ1LDQgKzQ2LDEzIEBAIHB1YmxpYyBjbGFzcyBNYWluVGFiUGFuZWxQcmVzZW50
ZXIgZXh0ZW5kcyBUYWJDb250YWluZXJQcmVzZW50ZXI8TWFpblRhYlBhbmVsUHJlCiAgICAgICAg
IFJldmVhbENvbnRlbnRFdmVudC5maXJlKHRoaXMsIE1haW5Db250ZW50UHJlc2VudGVyLlRZUEVf
U2V0TWFpblRhYlBhbmVsQ29udGVudCwgdGhpcyk7CiAgICAgfQogCisgICAgQE92ZXJyaWRlCisg
ICAgcHJvdGVjdGVkIHZvaWQgb25SZXZlYWwoKSB7CisgICAgICAgIHN1cGVyLm9uUmV2ZWFsKCk7
CisKKyAgICAgICAgLy8gUmVmcmVzaCB0YWJzIGVhY2ggdGltZSB0aGlzIHRhYiBjb250YWluZXIg
aXMgcmV2ZWFsZWQKKyAgICAgICAgZ2V0VmlldygpLnJlbW92ZVRhYnMoKTsKKyAgICAgICAgUmVx
dWVzdFRhYnNFdmVudC5maXJlKHRoaXMsIFRZUEVfUmVxdWVzdFRhYnMsIHRoaXMpOworICAgIH0K
KwogfQpkaWZmIC0tZ2l0IGEvZnJvbnRlbmQvd2ViYWRtaW4vbW9kdWxlcy93ZWJhZG1pbi9zcmMv
bWFpbi9qYXZhL29yZy9vdmlydC9lbmdpbmUvdWkvd2ViYWRtaW4vc2VjdGlvbi9tYWluL3ByZXNl
bnRlci90YWIvTWFpblRhYkN1c3RvbVByZXNlbnRlci5qYXZhIGIvZnJvbnRlbmQvd2ViYWRtaW4v
bW9kdWxlcy93ZWJhZG1pbi9zcmMvbWFpbi9qYXZhL29yZy9vdmlydC9lbmdpbmUvdWkvd2ViYWRt
aW4vc2VjdGlvbi9tYWluL3ByZXNlbnRlci90YWIvTWFpblRhYkN1c3RvbVByZXNlbnRlci5qYXZh
Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjJiOWMyZjUKLS0tIC9kZXYvbnVs
bAorKysgYi9mcm9udGVuZC93ZWJhZG1pbi9tb2R1bGVzL3dlYmFkbWluL3NyYy9tYWluL2phdmEv
b3JnL292aXJ0L2VuZ2luZS91aS93ZWJhZG1pbi9zZWN0aW9uL21haW4vcHJlc2VudGVyL3RhYi9N
YWluVGFiQ3VzdG9tUHJlc2VudGVyLmphdmEKQEAgLTAsMCArMSw0MyBAQAorcGFja2FnZSBvcmcu
b3ZpcnQuZW5naW5lLnVpLndlYmFkbWluLnNlY3Rpb24ubWFpbi5wcmVzZW50ZXIudGFiOworCitp
bXBvcnQgb3JnLm92aXJ0LmVuZ2luZS51aS53ZWJhZG1pbi5zZWN0aW9uLm1haW4ucHJlc2VudGVy
Lk1haW5UYWJQYW5lbFByZXNlbnRlcjsKKworaW1wb3J0IGNvbS5nb29nbGUuZ3d0LmV2ZW50LnNo
YXJlZC5FdmVudEJ1czsKK2ltcG9ydCBjb20uZ3d0cGxhdGZvcm0ubXZwLmNsaWVudC5QcmVzZW50
ZXI7CitpbXBvcnQgY29tLmd3dHBsYXRmb3JtLm12cC5jbGllbnQuVmlldzsKK2ltcG9ydCBjb20u
Z3d0cGxhdGZvcm0ubXZwLmNsaWVudC5wcm94eS5SZXZlYWxDb250ZW50RXZlbnQ7CitpbXBvcnQg
Y29tLmd3dHBsYXRmb3JtLm12cC5jbGllbnQucHJveHkuVGFiQ29udGVudFByb3h5UGxhY2U7CisK
K3B1YmxpYyBjbGFzcyBNYWluVGFiQ3VzdG9tUHJlc2VudGVyIGV4dGVuZHMgUHJlc2VudGVyPE1h
aW5UYWJDdXN0b21QcmVzZW50ZXIuVmlld0RlZiwgTWFpblRhYkN1c3RvbVByZXNlbnRlci5Qcm94
eURlZj4geworCisgICAgLy8gTm8gbmVlZCBmb3IgQFByb3h5Q29kZVNwbGl0LCB3ZSB3aWxsIHBy
b3ZpZGUgb3VyIG93biBwcm94eSBpbXBsZW1lbnRhdGlvbgorICAgIHB1YmxpYyBpbnRlcmZhY2Ug
UHJveHlEZWYgZXh0ZW5kcyBUYWJDb250ZW50UHJveHlQbGFjZTxNYWluVGFiQ3VzdG9tUHJlc2Vu
dGVyPiB7CisgICAgfQorCisgICAgcHVibGljIGludGVyZmFjZSBWaWV3RGVmIGV4dGVuZHMgVmll
dyB7CisKKyAgICAgICAgdm9pZCBzZXRDb250ZW50VXJsKFN0cmluZyB1cmwpOworCisgICAgfQor
CisgICAgcHJpdmF0ZSBmaW5hbCBTdHJpbmcgY29udGVudFVybDsKKworICAgIC8vIE5vIG5lZWQg
Zm9yIEBJbmplY3QsIHRoaXMgcHJlc2VudGVyIHdpbGwgYmUgY3JlYXRlZCBtYW51YWxseSBieSBN
YWluVGFiQ3VzdG9tUHJlc2VudGVyUHJvdmlkZXIKKyAgICBwdWJsaWMgTWFpblRhYkN1c3RvbVBy
ZXNlbnRlcihFdmVudEJ1cyBldmVudEJ1cywgVmlld0RlZiB2aWV3LCBQcm94eURlZiBwcm94eSwg
U3RyaW5nIGNvbnRlbnRVcmwpIHsKKyAgICAgICAgc3VwZXIoZXZlbnRCdXMsIHZpZXcsIHByb3h5
KTsKKyAgICAgICAgdGhpcy5jb250ZW50VXJsID0gY29udGVudFVybDsKKyAgICB9CisKKyAgICBA
T3ZlcnJpZGUKKyAgICBwcm90ZWN0ZWQgdm9pZCByZXZlYWxJblBhcmVudCgpIHsKKyAgICAgICAg
UmV2ZWFsQ29udGVudEV2ZW50LmZpcmUodGhpcywgTWFpblRhYlBhbmVsUHJlc2VudGVyLlRZUEVf
U2V0VGFiQ29udGVudCwgdGhpcyk7CisgICAgfQorCisgICAgQE92ZXJyaWRlCisgICAgcHJvdGVj
dGVkIHZvaWQgb25CaW5kKCkgeworICAgICAgICBzdXBlci5vbkJpbmQoKTsKKworICAgICAgICBn
ZXRWaWV3KCkuc2V0Q29udGVudFVybChjb250ZW50VXJsKTsKKyAgICB9CisKK30KZGlmZiAtLWdp
dCBhL2Zyb250ZW5kL3dlYmFkbWluL21vZHVsZXMvd2ViYWRtaW4vc3JjL21haW4vamF2YS9vcmcv
b3ZpcnQvZW5naW5lL3VpL3dlYmFkbWluL3NlY3Rpb24vbWFpbi9wcmVzZW50ZXIvdGFiL01haW5U
YWJDdXN0b21QcmVzZW50ZXJQcm92aWRlci5qYXZhIGIvZnJvbnRlbmQvd2ViYWRtaW4vbW9kdWxl
cy93ZWJhZG1pbi9zcmMvbWFpbi9qYXZhL29yZy9vdmlydC9lbmdpbmUvdWkvd2ViYWRtaW4vc2Vj
dGlvbi9tYWluL3ByZXNlbnRlci90YWIvTWFpblRhYkN1c3RvbVByZXNlbnRlclByb3ZpZGVyLmph
dmEKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNGMwYmU1NAotLS0gL2Rldi9u
dWxsCisrKyBiL2Zyb250ZW5kL3dlYmFkbWluL21vZHVsZXMvd2ViYWRtaW4vc3JjL21haW4vamF2
YS9vcmcvb3ZpcnQvZW5naW5lL3VpL3dlYmFkbWluL3NlY3Rpb24vbWFpbi9wcmVzZW50ZXIvdGFi
L01haW5UYWJDdXN0b21QcmVzZW50ZXJQcm92aWRlci5qYXZhCkBAIC0wLDAgKzEsNDcgQEAKK3Bh
Y2thZ2Ugb3JnLm92aXJ0LmVuZ2luZS51aS53ZWJhZG1pbi5zZWN0aW9uLm1haW4ucHJlc2VudGVy
LnRhYjsKKworaW1wb3J0IGNvbS5nb29nbGUuZ3d0LmV2ZW50LnNoYXJlZC5FdmVudEJ1czsKK2lt
cG9ydCBjb20uZ29vZ2xlLmluamVjdC5JbmplY3Q7CitpbXBvcnQgY29tLmdvb2dsZS5pbmplY3Qu
UHJvdmlkZXI7CisKKy8qKgorICogUHJvdmlkZXIgb2Yge0BsaW5rIE1haW5UYWJDdXN0b21QcmVz
ZW50ZXJ9IGluc3RhbmNlcyAobm9uLXNpbmdsZXRvbikuCisgKi8KK3B1YmxpYyBjbGFzcyBNYWlu
VGFiQ3VzdG9tUHJlc2VudGVyUHJvdmlkZXIgaW1wbGVtZW50cyBQcm92aWRlcjxNYWluVGFiQ3Vz
dG9tUHJlc2VudGVyPiB7CisKKyAgICBwcml2YXRlIE1haW5UYWJDdXN0b21QcmVzZW50ZXIgcHJl
c2VudGVyOworICAgIHByaXZhdGUgTWFpblRhYkN1c3RvbVByZXNlbnRlci5Qcm94eURlZiBwcm94
eTsKKworICAgIHByaXZhdGUgZmluYWwgUHJvdmlkZXI8TWFpblRhYkN1c3RvbVByZXNlbnRlci5W
aWV3RGVmPiB2aWV3UHJvdmlkZXI7CisgICAgcHJpdmF0ZSBmaW5hbCBFdmVudEJ1cyBldmVudEJ1
czsKKworICAgIHByaXZhdGUgU3RyaW5nIGNvbnRlbnRVcmw7CisKKyAgICBASW5qZWN0CisgICAg
cHVibGljIE1haW5UYWJDdXN0b21QcmVzZW50ZXJQcm92aWRlcihQcm92aWRlcjxNYWluVGFiQ3Vz
dG9tUHJlc2VudGVyLlZpZXdEZWY+IHZpZXdQcm92aWRlciwgRXZlbnRCdXMgZXZlbnRCdXMpIHsK
KyAgICAgICAgdGhpcy52aWV3UHJvdmlkZXIgPSB2aWV3UHJvdmlkZXI7CisgICAgICAgIHRoaXMu
ZXZlbnRCdXMgPSBldmVudEJ1czsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJsaWMg
TWFpblRhYkN1c3RvbVByZXNlbnRlciBnZXQoKSB7CisgICAgICAgIGFzc2VydCBwcm94eSAhPSBu
dWxsIDogIllvdSBtdXN0IGNhbGwgc2V0UHJveHkgZmlyc3QiOyAvLyROT04tTkxTLTEkCisKKyAg
ICAgICAgaWYgKHByZXNlbnRlciA9PSBudWxsKSB7CisgICAgICAgICAgICAvLyBDcmVhdGUgYW5k
IGJpbmQgdGhlIHByZXNlbnRlcgorICAgICAgICAgICAgcHJlc2VudGVyID0gbmV3IE1haW5UYWJD
dXN0b21QcmVzZW50ZXIoZXZlbnRCdXMsIHZpZXdQcm92aWRlci5nZXQoKSwgcHJveHksIGNvbnRl
bnRVcmwpOworICAgICAgICAgICAgcHJlc2VudGVyLmJpbmQoKTsKKyAgICAgICAgfQorCisgICAg
ICAgIHJldHVybiBwcmVzZW50ZXI7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0UHJveHko
TWFpblRhYkN1c3RvbVByZXNlbnRlci5Qcm94eURlZiBwcm94eSkgeworICAgICAgICB0aGlzLnBy
b3h5ID0gcHJveHk7CisgICAgfQorCisgICAgcHVibGljIHZvaWQgc2V0Q29udGVudFVybChTdHJp
bmcgY29udGVudFVybCkgeworICAgICAgICB0aGlzLmNvbnRlbnRVcmwgPSBjb250ZW50VXJsOwor
ICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvZnJvbnRlbmQvd2ViYWRtaW4vbW9kdWxlcy93ZWJhZG1p
bi9zcmMvbWFpbi9qYXZhL29yZy9vdmlydC9lbmdpbmUvdWkvd2ViYWRtaW4vc2VjdGlvbi9tYWlu
L3ByZXNlbnRlci90YWIvTWFpblRhYkN1c3RvbVByb3h5LmphdmEgYi9mcm9udGVuZC93ZWJhZG1p
bi9tb2R1bGVzL3dlYmFkbWluL3NyYy9tYWluL2phdmEvb3JnL292aXJ0L2VuZ2luZS91aS93ZWJh
ZG1pbi9zZWN0aW9uL21haW4vcHJlc2VudGVyL3RhYi9NYWluVGFiQ3VzdG9tUHJveHkuamF2YQpu
ZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lZDYzMjhjCi0tLSAvZGV2L251bGwK
KysrIGIvZnJvbnRlbmQvd2ViYWRtaW4vbW9kdWxlcy93ZWJhZG1pbi9zcmMvbWFpbi9qYXZhL29y
Zy9vdmlydC9lbmdpbmUvdWkvd2ViYWRtaW4vc2VjdGlvbi9tYWluL3ByZXNlbnRlci90YWIvTWFp
blRhYkN1c3RvbVByb3h5LmphdmEKQEAgLTAsMCArMSw0NSBAQAorcGFja2FnZSBvcmcub3ZpcnQu
ZW5naW5lLnVpLndlYmFkbWluLnNlY3Rpb24ubWFpbi5wcmVzZW50ZXIudGFiOworCitpbXBvcnQg
b3JnLm92aXJ0LmVuZ2luZS51aS53ZWJhZG1pbi5naW4uQ2xpZW50R2luamVjdG9yOworaW1wb3J0
IG9yZy5vdmlydC5lbmdpbmUudWkud2ViYWRtaW4uc2VjdGlvbi5tYWluLnByZXNlbnRlci5NYWlu
VGFiUGFuZWxQcmVzZW50ZXI7CisKK2ltcG9ydCBjb20uZ29vZ2xlLmd3dC5ldmVudC5zaGFyZWQu
RXZlbnRCdXM7CitpbXBvcnQgY29tLmdvb2dsZS5pbmplY3QuUHJvdmlkZXI7CitpbXBvcnQgY29t
Lmd3dHBsYXRmb3JtLmNvbW1vbi5jbGllbnQuU3RhbmRhcmRQcm92aWRlcjsKK2ltcG9ydCBjb20u
Z3d0cGxhdGZvcm0ubXZwLmNsaWVudC5UYWJEYXRhQmFzaWM7CitpbXBvcnQgY29tLmd3dHBsYXRm
b3JtLm12cC5jbGllbnQucHJveHkuUGxhY2VNYW5hZ2VyOworaW1wb3J0IGNvbS5nd3RwbGF0Zm9y
bS5tdnAuY2xpZW50LnByb3h5LlBsYWNlV2l0aEdhdGVrZWVwZXI7CitpbXBvcnQgY29tLmd3dHBs
YXRmb3JtLm12cC5jbGllbnQucHJveHkuVGFiQ29udGVudFByb3h5SW1wbDsKK2ltcG9ydCBjb20u
Z3d0cGxhdGZvcm0ubXZwLmNsaWVudC5wcm94eS5UYWJDb250ZW50UHJveHlQbGFjZUltcGw7CisK
Ky8qKgorICogQ3VzdG9tIHtAbGluayBNYWluVGFiQ3VzdG9tUHJlc2VudGVyfSBwcm94eSBpbXBs
ZW1lbnRhdGlvbi4KKyAqLworcHVibGljIGNsYXNzIE1haW5UYWJDdXN0b21Qcm94eSBleHRlbmRz
IFRhYkNvbnRlbnRQcm94eVBsYWNlSW1wbDxNYWluVGFiQ3VzdG9tUHJlc2VudGVyPiBpbXBsZW1l
bnRzIE1haW5UYWJDdXN0b21QcmVzZW50ZXIuUHJveHlEZWYgeworCisgICAgcHVibGljIHN0YXRp
YyBjbGFzcyBXcmFwcGVkUHJveHkgZXh0ZW5kcyBUYWJDb250ZW50UHJveHlJbXBsPE1haW5UYWJD
dXN0b21QcmVzZW50ZXI+IHsKKworICAgICAgICBwdWJsaWMgV3JhcHBlZFByb3h5KFBsYWNlTWFu
YWdlciBwbGFjZU1hbmFnZXIsIEV2ZW50QnVzIGV2ZW50QnVzLAorICAgICAgICAgICAgICAgIFBy
b3ZpZGVyPE1haW5UYWJDdXN0b21QcmVzZW50ZXI+IHByZXNlbnRlclByb3ZpZGVyLAorICAgICAg
ICAgICAgICAgIFN0cmluZyBsYWJlbCwgZmxvYXQgcHJpb3JpdHksIFN0cmluZyBoaXN0b3J5VG9r
ZW4pIHsKKyAgICAgICAgICAgIGJpbmQocGxhY2VNYW5hZ2VyLCBldmVudEJ1cyk7CisgICAgICAg
ICAgICByZXF1ZXN0VGFic0V2ZW50VHlwZSA9IE1haW5UYWJQYW5lbFByZXNlbnRlci5UWVBFX1Jl
cXVlc3RUYWJzOworICAgICAgICAgICAgdGFiRGF0YSA9IG5ldyBUYWJEYXRhQmFzaWMobGFiZWws
IHByaW9yaXR5KTsKKyAgICAgICAgICAgIHRhcmdldEhpc3RvcnlUb2tlbiA9IGhpc3RvcnlUb2tl
bjsKKyAgICAgICAgICAgIGFkZFJlcXVlc3RUYWJzSGFuZGxlcigpOworICAgICAgICAgICAgcHJl
c2VudGVyID0gbmV3IFN0YW5kYXJkUHJvdmlkZXI8TWFpblRhYkN1c3RvbVByZXNlbnRlcj4ocHJl
c2VudGVyUHJvdmlkZXIpOworICAgICAgICB9CisKKyAgICB9CisKKyAgICBwdWJsaWMgTWFpblRh
YkN1c3RvbVByb3h5KENsaWVudEdpbmplY3RvciBnaW5qZWN0b3IsCisgICAgICAgICAgICBNYWlu
VGFiQ3VzdG9tUHJlc2VudGVyUHJvdmlkZXIgcHJlc2VudGVyUHJvdmlkZXIsCisgICAgICAgICAg
ICBTdHJpbmcgbGFiZWwsIGZsb2F0IHByaW9yaXR5LCBTdHJpbmcgaGlzdG9yeVRva2VuKSB7Cisg
ICAgICAgIGJpbmQoZ2luamVjdG9yLmdldFBsYWNlTWFuYWdlcigpLCBnaW5qZWN0b3IuZ2V0RXZl
bnRCdXMoKSk7CisgICAgICAgIHByb3h5ID0gbmV3IFdyYXBwZWRQcm94eShnaW5qZWN0b3IuZ2V0
UGxhY2VNYW5hZ2VyKCksIGdpbmplY3Rvci5nZXRFdmVudEJ1cygpLAorICAgICAgICAgICAgICAg
IHByZXNlbnRlclByb3ZpZGVyLCBsYWJlbCwgcHJpb3JpdHksIGhpc3RvcnlUb2tlbik7CisgICAg
ICAgIHBsYWNlID0gbmV3IFBsYWNlV2l0aEdhdGVrZWVwZXIoaGlzdG9yeVRva2VuLCBnaW5qZWN0
b3IuZ2V0RGVmYXVsdEdhdGVrZWVwZXIoKSk7CisgICAgICAgIHByZXNlbnRlclByb3ZpZGVyLnNl
dFByb3h5KHRoaXMpOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvZnJvbnRlbmQvd2ViYWRtaW4v
bW9kdWxlcy93ZWJhZG1pbi9zcmMvbWFpbi9qYXZhL29yZy9vdmlydC9lbmdpbmUvdWkvd2ViYWRt
aW4vc2VjdGlvbi9tYWluL3ByZXNlbnRlci90YWIvTWFpblRhYkN1c3RvbVByb3h5RmFjdG9yeS5q
YXZhIGIvZnJvbnRlbmQvd2ViYWRtaW4vbW9kdWxlcy93ZWJhZG1pbi9zcmMvbWFpbi9qYXZhL29y
Zy9vdmlydC9lbmdpbmUvdWkvd2ViYWRtaW4vc2VjdGlvbi9tYWluL3ByZXNlbnRlci90YWIvTWFp
blRhYkN1c3RvbVByb3h5RmFjdG9yeS5qYXZhCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAw
MDAwMDAuLmYxNjdjOTYKLS0tIC9kZXYvbnVsbAorKysgYi9mcm9udGVuZC93ZWJhZG1pbi9tb2R1
bGVzL3dlYmFkbWluL3NyYy9tYWluL2phdmEvb3JnL292aXJ0L2VuZ2luZS91aS93ZWJhZG1pbi9z
ZWN0aW9uL21haW4vcHJlc2VudGVyL3RhYi9NYWluVGFiQ3VzdG9tUHJveHlGYWN0b3J5LmphdmEK
QEAgLTAsMCArMSwzNCBAQAorcGFja2FnZSBvcmcub3ZpcnQuZW5naW5lLnVpLndlYmFkbWluLnNl
Y3Rpb24ubWFpbi5wcmVzZW50ZXIudGFiOworCitpbXBvcnQgb3JnLm92aXJ0LmVuZ2luZS51aS53
ZWJhZG1pbi5naW4uQ2xpZW50R2luamVjdG9yOworCitpbXBvcnQgY29tLmdvb2dsZS5pbmplY3Qu
SW5qZWN0OworaW1wb3J0IGNvbS5nb29nbGUuaW5qZWN0LlByb3ZpZGVyOworCisvKioKKyAqIENy
ZWF0ZXMgYW5kIGJpbmRzIHtAbGluayBNYWluVGFiQ3VzdG9tUHJveHl9IGluc3RhbmNlcy4KKyAq
LworcHVibGljIGNsYXNzIE1haW5UYWJDdXN0b21Qcm94eUZhY3RvcnkgeworCisgICAgcHJpdmF0
ZSBmaW5hbCBDbGllbnRHaW5qZWN0b3IgZ2luamVjdG9yOworICAgIHByaXZhdGUgZmluYWwgUHJv
dmlkZXI8TWFpblRhYkN1c3RvbVByZXNlbnRlclByb3ZpZGVyPiBwcm92aWRlcjsKKworICAgIEBJ
bmplY3QKKyAgICBwdWJsaWMgTWFpblRhYkN1c3RvbVByb3h5RmFjdG9yeShDbGllbnRHaW5qZWN0
b3IgZ2luamVjdG9yLAorICAgICAgICAgICAgUHJvdmlkZXI8TWFpblRhYkN1c3RvbVByZXNlbnRl
clByb3ZpZGVyPiBwcm92aWRlcikgeworICAgICAgICB0aGlzLmdpbmplY3RvciA9IGdpbmplY3Rv
cjsKKyAgICAgICAgdGhpcy5wcm92aWRlciA9IHByb3ZpZGVyOworICAgIH0KKworICAgIHB1Ymxp
YyBNYWluVGFiQ3VzdG9tUHJveHkgY3JlYXRlKFN0cmluZyBsYWJlbCwgU3RyaW5nIGhpc3RvcnlU
b2tlbiwgU3RyaW5nIGNvbnRlbnRVcmwpIHsKKyAgICAgICAgTWFpblRhYkN1c3RvbVByZXNlbnRl
clByb3ZpZGVyIHByZXNlbnRlclByb3ZpZGVyID0gcHJvdmlkZXIuZ2V0KCk7CisgICAgICAgIHBy
ZXNlbnRlclByb3ZpZGVyLnNldENvbnRlbnRVcmwoY29udGVudFVybCk7CisKKyAgICAgICAgLy8g
Q3JlYXRlIGFuZCBiaW5kIHRoZSBwcm94eSBpbnN0YW5jZQorICAgICAgICBNYWluVGFiQ3VzdG9t
UHJveHkgcHJveHkgPSBuZXcgTWFpblRhYkN1c3RvbVByb3h5KAorICAgICAgICAgICAgICAgIGdp
bmplY3RvciwgcHJlc2VudGVyUHJvdmlkZXIsIGxhYmVsLCBGbG9hdC5NQVhfVkFMVUUsIGhpc3Rv
cnlUb2tlbik7CisKKyAgICAgICAgcmV0dXJuIHByb3h5OworICAgIH0KKworfQpkaWZmIC0tZ2l0
IGEvZnJvbnRlbmQvd2ViYWRtaW4vbW9kdWxlcy93ZWJhZG1pbi9zcmMvbWFpbi9qYXZhL29yZy9v
dmlydC9lbmdpbmUvdWkvd2ViYWRtaW4vc2VjdGlvbi9tYWluL3ZpZXcvdGFiL01haW5UYWJDdXN0
b21WaWV3LmphdmEgYi9mcm9udGVuZC93ZWJhZG1pbi9tb2R1bGVzL3dlYmFkbWluL3NyYy9tYWlu
L2phdmEvb3JnL292aXJ0L2VuZ2luZS91aS93ZWJhZG1pbi9zZWN0aW9uL21haW4vdmlldy90YWIv
TWFpblRhYkN1c3RvbVZpZXcuamF2YQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAw
Li5jOGU5NjgzCi0tLSAvZGV2L251bGwKKysrIGIvZnJvbnRlbmQvd2ViYWRtaW4vbW9kdWxlcy93
ZWJhZG1pbi9zcmMvbWFpbi9qYXZhL29yZy9vdmlydC9lbmdpbmUvdWkvd2ViYWRtaW4vc2VjdGlv
bi9tYWluL3ZpZXcvdGFiL01haW5UYWJDdXN0b21WaWV3LmphdmEKQEAgLTAsMCArMSwzMiBAQAor
cGFja2FnZSBvcmcub3ZpcnQuZW5naW5lLnVpLndlYmFkbWluLnNlY3Rpb24ubWFpbi52aWV3LnRh
YjsKKworaW1wb3J0IG9yZy5vdmlydC5lbmdpbmUudWkuY29tbW9uLnZpZXcuQWJzdHJhY3RWaWV3
OworaW1wb3J0IG9yZy5vdmlydC5lbmdpbmUudWkud2ViYWRtaW4uc2VjdGlvbi5tYWluLnByZXNl
bnRlci50YWIuTWFpblRhYkN1c3RvbVByZXNlbnRlcjsKKworaW1wb3J0IGNvbS5nb29nbGUuZ3d0
LmNvcmUuY2xpZW50LkdXVDsKK2ltcG9ydCBjb20uZ29vZ2xlLmd3dC51aWJpbmRlci5jbGllbnQu
VWlCaW5kZXI7CitpbXBvcnQgY29tLmdvb2dsZS5nd3QudWliaW5kZXIuY2xpZW50LlVpRmllbGQ7
CitpbXBvcnQgY29tLmdvb2dsZS5nd3QudXNlci5jbGllbnQudWkuSW5saW5lTGFiZWw7CitpbXBv
cnQgY29tLmdvb2dsZS5nd3QudXNlci5jbGllbnQudWkuV2lkZ2V0OworaW1wb3J0IGNvbS5nb29n
bGUuaW5qZWN0LkluamVjdDsKKworcHVibGljIGNsYXNzIE1haW5UYWJDdXN0b21WaWV3IGV4dGVu
ZHMgQWJzdHJhY3RWaWV3IGltcGxlbWVudHMgTWFpblRhYkN1c3RvbVByZXNlbnRlci5WaWV3RGVm
IHsKKworICAgIGludGVyZmFjZSBWaWV3VWlCaW5kZXIgZXh0ZW5kcyBVaUJpbmRlcjxXaWRnZXQs
IE1haW5UYWJDdXN0b21WaWV3PiB7CisgICAgICAgIFZpZXdVaUJpbmRlciB1aUJpbmRlciA9IEdX
VC5jcmVhdGUoVmlld1VpQmluZGVyLmNsYXNzKTsKKyAgICB9CisKKyAgICBAVWlGaWVsZAorICAg
IElubGluZUxhYmVsIHVybExhYmVsOworCisgICAgQEluamVjdAorICAgIHB1YmxpYyBNYWluVGFi
Q3VzdG9tVmlldygpIHsKKyAgICAgICAgaW5pdFdpZGdldChWaWV3VWlCaW5kZXIudWlCaW5kZXIu
Y3JlYXRlQW5kQmluZFVpKHRoaXMpKTsKKyAgICB9CisKKyAgICBAT3ZlcnJpZGUKKyAgICBwdWJs
aWMgdm9pZCBzZXRDb250ZW50VXJsKFN0cmluZyB1cmwpIHsKKyAgICAgICAgdXJsTGFiZWwuc2V0
VGV4dCh1cmwpOworICAgIH0KKworfQpkaWZmIC0tZ2l0IGEvZnJvbnRlbmQvd2ViYWRtaW4vbW9k
dWxlcy93ZWJhZG1pbi9zcmMvbWFpbi9qYXZhL29yZy9vdmlydC9lbmdpbmUvdWkvd2ViYWRtaW4v
c2VjdGlvbi9tYWluL3ZpZXcvdGFiL01haW5UYWJDdXN0b21WaWV3LnVpLnhtbCBiL2Zyb250ZW5k
L3dlYmFkbWluL21vZHVsZXMvd2ViYWRtaW4vc3JjL21haW4vamF2YS9vcmcvb3ZpcnQvZW5naW5l
L3VpL3dlYmFkbWluL3NlY3Rpb24vbWFpbi92aWV3L3RhYi9NYWluVGFiQ3VzdG9tVmlldy51aS54
bWwKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDczMWJlMgotLS0gL2Rldi9u
dWxsCisrKyBiL2Zyb250ZW5kL3dlYmFkbWluL21vZHVsZXMvd2ViYWRtaW4vc3JjL21haW4vamF2
YS9vcmcvb3ZpcnQvZW5naW5lL3VpL3dlYmFkbWluL3NlY3Rpb24vbWFpbi92aWV3L3RhYi9NYWlu
VGFiQ3VzdG9tVmlldy51aS54bWwKQEAgLTAsMCArMSwxMCBAQAorPD94bWwgdmVyc2lvbj0iMS4w
IiBlbmNvZGluZz0iVVRGLTgiPz4KKzwhRE9DVFlQRSB1aTpVaUJpbmRlciBTWVNURU0gImh0dHA6
Ly9kbC5nb29nbGUuY29tL2d3dC9EVEQveGh0bWwuZW50Ij4KKzx1aTpVaUJpbmRlciB4bWxuczp1
aT0idXJuOnVpOmNvbS5nb29nbGUuZ3d0LnVpYmluZGVyIiB4bWxuczpnPSJ1cm46aW1wb3J0OmNv
bS5nb29nbGUuZ3d0LnVzZXIuY2xpZW50LnVpIj4KKworCTxnOkhUTUxQYW5lbD4KKwkJVE9ETyBk
aXNwbGF5IHRoaXMgVVJMOgorCQk8ZzpJbmxpbmVMYWJlbCB1aTpmaWVsZD0idXJsTGFiZWwiIC8+
CisJPC9nOkhUTUxQYW5lbD4KKworPC91aTpVaUJpbmRlcj4KZGlmZiAtLWdpdCBhL2Zyb250ZW5k
L3dlYmFkbWluL21vZHVsZXMvd2ViYWRtaW4vc3JjL21haW4vd2ViYXBwL1dFQi1JTkYvd2ViLnht
bCBiL2Zyb250ZW5kL3dlYmFkbWluL21vZHVsZXMvd2ViYWRtaW4vc3JjL21haW4vd2ViYXBwL1dF
Qi1JTkYvd2ViLnhtbAppbmRleCA1MzlkM2Q4Li5kYmY5M2EyIDEwMDY0NAotLS0gYS9mcm9udGVu
ZC93ZWJhZG1pbi9tb2R1bGVzL3dlYmFkbWluL3NyYy9tYWluL3dlYmFwcC9XRUItSU5GL3dlYi54
bWwKKysrIGIvZnJvbnRlbmQvd2ViYWRtaW4vbW9kdWxlcy93ZWJhZG1pbi9zcmMvbWFpbi93ZWJh
cHAvV0VCLUlORi93ZWIueG1sCkBAIC0yMyw2ICsyMywxNiBAQAogCQk8dXJsLXBhdHRlcm4+L3dl
YmFkbWluL1dlYkFkbWluLmh0bWw8L3VybC1wYXR0ZXJuPgogCTwvc2VydmxldC1tYXBwaW5nPgog
CisJPHNlcnZsZXQ+CisJCTxzZXJ2bGV0LW5hbWU+UGx1Z2luU291cmNlUGFnZTwvc2VydmxldC1u
YW1lPgorCQk8c2VydmxldC1jbGFzcz5vcmcub3ZpcnQuZW5naW5lLnVpLmZyb250ZW5kLnNlcnZl
ci5nd3QuUGx1Z2luU291cmNlUGFnZVNlcnZsZXQ8L3NlcnZsZXQtY2xhc3M+CisJPC9zZXJ2bGV0
PgorCisJPHNlcnZsZXQtbWFwcGluZz4KKwkJPHNlcnZsZXQtbmFtZT5QbHVnaW5Tb3VyY2VQYWdl
PC9zZXJ2bGV0LW5hbWU+CisJCTx1cmwtcGF0dGVybj4vd2ViYWRtaW4vUGx1Z2luU291cmNlUGFn
ZTwvdXJsLXBhdHRlcm4+CisJPC9zZXJ2bGV0LW1hcHBpbmc+CisKIAk8IS0tIERlZmF1bHQgcGFn
ZSB0byBzZXJ2ZSAtLT4KIAk8d2VsY29tZS1maWxlLWxpc3Q+CiAJCTx3ZWxjb21lLWZpbGU+aW5k
ZXguaHRtbDwvd2VsY29tZS1maWxlPgotLSAKMS43LjQuNAoK
------=_Part_15477537_1702327251.1346339532819--
12 years, 3 months