ZGlmZiAtLWdpdCBhL2J1bmRsZXMvb3JnLmVjbGlwc2UuZXF1aW5veC5kcy50ZXN0cy9BbGwgRFMgVGVzdHMubGF1bmNoIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5lcXVpbm94LmRzLnRlc3RzL0FsbCBEUyBUZXN0cy5sYXVuY2gKaW5kZXggM2E1YjlhNy4uYWY3MTc4YiAxMDA2NDQKLS0tIGEvYnVuZGxlcy9vcmcuZWNsaXBzZS5lcXVpbm94LmRzLnRlc3RzL0FsbCBEUyBUZXN0cy5sYXVuY2gKKysrIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5lcXVpbm94LmRzLnRlc3RzL0FsbCBEUyBUZXN0cy5sYXVuY2gKQEAgLTEsNDM2ICsxLDQ0MSBAQAotPD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KLTxsYXVuY2hDb25maWd1cmF0aW9uIHR5cGU9Im9yZy5lY2xpcHNlLnBkZS51aS5KdW5pdExhdW5jaENvbmZpZyI+Ci08Ym9vbGVhbkF0dHJpYnV0ZSBrZXk9ImFwcGVuZC5hcmdzIiB2YWx1ZT0idHJ1ZSIvPgotPHN0cmluZ0F0dHJpYnV0ZSBrZXk9ImFwcGxpY2F0aW9uIiB2YWx1ZT0ib3JnLmVjbGlwc2UucGRlLmp1bml0LnJ1bnRpbWUuY29yZXRlc3RhcHBsaWNhdGlvbiIvPgotPGJvb2xlYW5BdHRyaWJ1dGUga2V5PSJhc2tjbGVhciIgdmFsdWU9ImZhbHNlIi8+Ci08Ym9vbGVhbkF0dHJpYnV0ZSBrZXk9ImF1dG9tYXRpY0FkZCIgdmFsdWU9InRydWUiLz4KLTxib29sZWFuQXR0cmlidXRlIGtleT0iYXV0b21hdGljVmFsaWRhdGUiIHZhbHVlPSJmYWxzZSIvPgotPHN0cmluZ0F0dHJpYnV0ZSBrZXk9ImJvb3RzdHJhcCIgdmFsdWU9IiIvPgotPHN0cmluZ0F0dHJpYnV0ZSBrZXk9ImNoZWNrZWQiIHZhbHVlPSJbTk9ORV0iLz4KLTxib29sZWFuQXR0cmlidXRlIGtleT0iY2xlYXJDb25maWciIHZhbHVlPSJ0cnVlIi8+Ci08Ym9vbGVhbkF0dHJpYnV0ZSBrZXk9ImNsZWFyd3MiIHZhbHVlPSJ0cnVlIi8+Ci08Ym9vbGVhbkF0dHJpYnV0ZSBrZXk9ImNsZWFyd3Nsb2ciIHZhbHVlPSJmYWxzZSIvPgotPHN0cmluZ0F0dHJpYnV0ZSBrZXk9ImNvbmZpZ0xvY2F0aW9uIiB2YWx1ZT0iJHt3b3Jrc3BhY2VfbG9jfS8ubWV0YWRhdGEvLnBsdWdpbnMvb3JnLmVjbGlwc2UucGRlLmNvcmUvcGRlLWp1bml0Ii8+Ci08Ym9vbGVhbkF0dHJpYnV0ZSBrZXk9ImRlZmF1bHQiIHZhbHVlPSJ0cnVlIi8+Ci08Ym9vbGVhbkF0dHJpYnV0ZSBrZXk9ImluY2x1ZGVPcHRpb25hbCIgdmFsdWU9InRydWUiLz4KLTxzdHJpbmdBdHRyaWJ1dGUga2V5PSJsb2NhdGlvbiIgdmFsdWU9IiR7d29ya3NwYWNlX2xvY30vLi4vanVuaXQtd29ya3NwYWNlIi8+Ci08bGlzdEF0dHJpYnV0ZSBrZXk9Im9yZy5lY2xpcHNlLmRlYnVnLmNvcmUuTUFQUEVEX1JFU09VUkNFX1BBVEhTIj4KLTxsaXN0RW50cnkgdmFsdWU9Ii9vcmcuZWNsaXBzZS5lcXVpbm94LmRzLnRlc3RzL3NyYy9vcmcvZWNsaXBzZS9lcXVpbm94L2RzL3Rlc3RzL0FsbFRlc3RzLmphdmEiLz4KLTwvbGlzdEF0dHJpYnV0ZT4KLTxsaXN0QXR0cmlidXRlIGtleT0ib3JnLmVjbGlwc2UuZGVidWcuY29yZS5NQVBQRURfUkVTT1VSQ0VfVFlQRVMiPgotPGxpc3RFbnRyeSB2YWx1ZT0iMSIvPgotPC9saXN0QXR0cmlidXRlPgotPHN0cmluZ0F0dHJpYnV0ZSBrZXk9Im9yZy5lY2xpcHNlLmpkdC5qdW5pdC5DT05UQUlORVIiIHZhbHVlPSIiLz4KLTxib29sZWFuQXR0cmlidXRlIGtleT0ib3JnLmVjbGlwc2UuamR0Lmp1bml0LktFRVBSVU5OSU5HX0FUVFIiIHZhbHVlPSJmYWxzZSIvPgotPHN0cmluZ0F0dHJpYnV0ZSBrZXk9Im9yZy5lY2xpcHNlLmpkdC5qdW5pdC5URVNUTkFNRSIgdmFsdWU9IiIvPgotPHN0cmluZ0F0dHJpYnV0ZSBrZXk9Im9yZy5lY2xpcHNlLmpkdC5qdW5pdC5URVNUX0tJTkQiIHZhbHVlPSJvcmcuZWNsaXBzZS5qZHQuanVuaXQubG9hZGVyLmp1bml0NCIvPgotPHN0cmluZ0F0dHJpYnV0ZSBrZXk9Im9yZy5lY2xpcHNlLmpkdC5sYXVuY2hpbmcuTUFJTl9UWVBFIiB2YWx1ZT0ib3JnLmVjbGlwc2UuZXF1aW5veC5kcy50ZXN0cy5BbGxUZXN0cyIvPgotPHN0cmluZ0F0dHJpYnV0ZSBrZXk9Im9yZy5lY2xpcHNlLmpkdC5sYXVuY2hpbmcuUFJPR1JBTV9BUkdVTUVOVFMiIHZhbHVlPSItb3MgJHt0YXJnZXQub3N9IC13cyAke3RhcmdldC53c30gLWFyY2ggJHt0YXJnZXQuYXJjaH0gLW5sICR7dGFyZ2V0Lm5sfSAtY29uc29sZSAtY29uc29sZUxvZyIvPgotPHN0cmluZ0F0dHJpYnV0ZSBrZXk9Im9yZy5lY2xpcHNlLmpkdC5sYXVuY2hpbmcuUFJPSkVDVF9BVFRSIiB2YWx1ZT0ib3JnLmVjbGlwc2UuZXF1aW5veC5kcy50ZXN0cyIvPgotPHN0cmluZ0F0dHJpYnV0ZSBrZXk9Im9yZy5lY2xpcHNlLmpkdC5sYXVuY2hpbmcuU09VUkNFX1BBVEhfUFJPVklERVIiIHZhbHVlPSJvcmcuZWNsaXBzZS5wZGUudWkud29ya2JlbmNoQ2xhc3NwYXRoUHJvdmlkZXIiLz4KLTxzdHJpbmdBdHRyaWJ1dGUga2V5PSJwZGUudmVyc2lvbiIgdmFsdWU9IjMuMyIvPgotPHN0cmluZ0F0dHJpYnV0ZSBrZXk9InByb2R1Y3QiIHZhbHVlPSJvcmcuZWNsaXBzZS5zZGsuaWRlIi8+Ci08Ym9vbGVhbkF0dHJpYnV0ZSBrZXk9InNob3dfc2VsZWN0ZWRfb25seSIgdmFsdWU9ImZhbHNlIi8+Ci08c3RyaW5nQXR0cmlidXRlIGtleT0idGVtcGxhdGVDb25maWciIHZhbHVlPSIke3RhcmdldF9ob21lfVxjb25maWd1cmF0aW9uXGNvbmZpZy5pbmkiLz4KLTxib29sZWFuQXR0cmlidXRlIGtleT0idHJhY2luZyIgdmFsdWU9ImZhbHNlIi8+Ci08bWFwQXR0cmlidXRlIGtleT0idHJhY2luZ09wdGlvbnMiPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UudGVhbS5jdnMuY29yZS9zeW5jY2hhbmdlZXZlbnRzIiB2YWx1ZT0iZmFsc2UiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLndzdC52YWxpZGF0aW9uL2V4dHJhVmFsRGV0YWlsIiB2YWx1ZT0iIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5lcXVpbm94LnJlZ2lzdHJ5L2RlYnVnIiB2YWx1ZT0iZmFsc2UiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLndzdC52YWxpZGF0aW9uL3RpbWluZ3MvdXNlRG91YmxlcyIgdmFsdWU9ImZhbHNlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5jb3JlLnJlc291cmNlcy9wZXJmL2xpc3RlbmVycyIgdmFsdWU9IjUwMCIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuZGVidWcudWkvZGVidWcvY29udGV4dGxhdW5jaGluZyIgdmFsdWU9ImZhbHNlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5iaXJ0LmNoYXJ0LmVuZ2luZS9pbnRlcm5hbC5mYWN0b3J5IiB2YWx1ZT0iZmFsc2UiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLmJpcnQuY2hhcnQuZW5naW5lL3JlbmRlciIgdmFsdWU9ImZhbHNlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5jb3JlLnJlc291cmNlcy9idWlsZC9uZWVkYnVpbGQiIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuZGVidWcudWkvZGVidWcvdmlld2Vycy92aWV3ZXIiIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuamVtLnV0aWwvZGVidWcvbG9ndHJhY2UiIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2Uud3N0LnZhbGlkYXRpb24vdGltaW5ncyIgdmFsdWU9ImZhbHNlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS53c3QuY29tbW9uLmVudmlyb25tZW50L3RyYWNlL2RhdGEiIHZhbHVlPSJ0cnVlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS51cGRhdGUuY29uZmlndXJhdG9yL2RlYnVnIiB2YWx1ZT0iZmFsc2UiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLmJpcnQuY2hhcnQuZW5naW5lL2xvZyIgdmFsdWU9ImZhbHNlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5iaXJ0LmNoYXJ0LmVuZ2luZS9kZXZpY2UiIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2Uud3N0LmNvbW1vbi5lbnZpcm9ubWVudC90cmFjZS93c19mcmFtZXdvcmsiIHZhbHVlPSJ0cnVlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5vc2dpL21vbml0b3IvYWN0aXZhdGlvbiIgdmFsdWU9ImZhbHNlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS53c3Quc3NlLmNvcmUvdGFza3MvcHJlZmVyZW5jZXMiIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuamR0LnVpL3BlcmYvY29udGVudF9hc3Npc3QvZXh0ZW5zaW9ucyIgdmFsdWU9IjEwMDAiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLnVpLmlkZS9kZWJ1Zy9nYyIgdmFsdWU9ImZhbHNlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5jb3JlLnJlc291cmNlcy9jb250ZW50dHlwZS9jYWNoZSIgdmFsdWU9ImZhbHNlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS53c3Quc3NlLmNvcmUvc3RydWN0dXJlZG1vZGVsL3N0YXRlIiB2YWx1ZT0iZmFsc2UiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLndzdC5zc2UuY29yZS90YXNrcyIgdmFsdWU9ImZhbHNlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS53c3QudmFsaWRhdGlvbi90aW1pbmdzL3RyYWNlZmlsZSIgdmFsdWU9IiIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuYmlydC5jaGFydC5lbmdpbmUvZXZlbnQiIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuY29yZS5qb2JzL2pvYnMvc2h1dGRvd24iIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuY29yZS5ydW50aW1lL3VybC9kZWJ1ZyIgdmFsdWU9ImZhbHNlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5kZWJ1Zy51aS9kZWJ1Zy92aWV3ZXJzL3VwZGF0ZVNlcXVlbmNlIiB2YWx1ZT0iZmFsc2UiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLm9zZ2kvbW9uaXRvci9jbGFzc2VzIiB2YWx1ZT0iZmFsc2UiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLmVxdWlub3gucHJlZmVyZW5jZXMvZ2V0IiB2YWx1ZT0iZmFsc2UiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLmpkdC5hcHQuY29yZS9kZWJ1Zy9nZW5lcmF0ZWRGaWxlTWFwcyIgdmFsdWU9ImZhbHNlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS53c3QueG1sLmNvcmUvZGVidWcvdHJhY2VmaWx0ZXIiIHZhbHVlPSIiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLnVwZGF0ZS5jb3JlL2RlYnVnIiB2YWx1ZT0idHJ1ZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuY29yZS5ydW50aW1lL2RlYnVnL2NvbnRleHQiIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuamR0LmNvcmUvZGVidWcvY3ByZXNvbHV0aW9uL2ZhaWx1cmUiIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuY29yZS5qb2JzL2pvYnMvbG9ja3MiIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UudWkvZGVidWcvc3d0ZGVidWciIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0iY29tLm1vdW50YWlubWluZHMuZWNsZW1tYS5jb3JlL2RlYnVnL2luc3RydW1lbnRhdGlvbiIgdmFsdWU9InRydWUiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLmpkdC5jb3JlL2RlYnVnL2phdmFtb2RlbCIgdmFsdWU9ImZhbHNlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5vc2dpL3Jlc29sdmVyL3VzZXMiIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2Uud3N0LnNzZS51aS9kZWJ1Zy9yZWNvbmNpbGVyam9iIiB2YWx1ZT0iZmFsc2UiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLnVpLmludHJvLnVuaXZlcnNhbC90cmFjZS9sb2dJbmZvIiB2YWx1ZT0idHJ1ZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuZGVidWcuY29yZS9kZWJ1Zy9ldmVudHMiIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UudWkuaW50cm8vdHJhY2UvcHJpbnRIVE1MIiB2YWx1ZT0iZmFsc2UiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLmVxdWlub3gucmVnaXN0cnkvZGVidWcvZXZlbnRzIiB2YWx1ZT0iZmFsc2UiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLmpkdC5jb3JlL2RlYnVnL2phdmFkZWx0YS92ZXJib3NlIiB2YWx1ZT0iZmFsc2UiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLmpkdC5jb3JlL2RlYnVnIiB2YWx1ZT0idHJ1ZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UucGRlLmNvcmUvdmFsaWRhdGlvbiIgdmFsdWU9ImZhbHNlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5jb3JlLmV4cHJlc3Npb25zL3RyYWNlUHJvcGVydHlSZXNvbHZpbmciIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMvcmVzdG9yZSIgdmFsdWU9ImZhbHNlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5sdGsuY29yZS5yZWZhY3RvcmluZy9wZXJmL3BhcnRpY2lwYW50cy9jaGVja0NvbmRpdGlvbnMiIHZhbHVlPSIzMDAiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLnVpL3BlcmYvcGVyc3BlY3RpdmUubGlzdGVuZXJzIiB2YWx1ZT0iMjAwIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5iaXJ0LmNoYXJ0LmVuZ2luZS9kYXRhZmVlZCIgdmFsdWU9ImZhbHNlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5iaXJ0LmNoYXJ0LmVuZ2luZS9tb2RlbC5kYXRhLmltcGwiIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuamR0LmNvcmUvcGVyZi9jb250YWluZXJpbml0aWFsaXplciIgdmFsdWU9IjUwMDAiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLm9zZ2kvdHJhY2UvZmlsZW5hbWUiIHZhbHVlPSJydW50aW1lLnRyYWNlcyIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2Uud3N0LnNzZS51aS9wcm9wZXJ0eUNoYW5nZVVwZGF0ZUFjdGlvbkNvbnRyaWJ1dGlvbkl0ZW0iIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2Uud3N0LnNzZS51aS90cmFuc2ZlcmJ1aWxkZXIvdGltZSIgdmFsdWU9ImZhbHNlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5lcXVpbm94LmRzL3BlcmZvcm1hbmNlIiB2YWx1ZT0iZmFsc2UiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLnVwZGF0ZS5jb3JlL2RlYnVnL3dlYiIgdmFsdWU9ImZhbHNlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5iaXJ0LmNoYXJ0LmVuZ2luZS9tb2RlbC50eXBlLmltcGwiIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2Uub3NnaS9kZWJ1ZyIgdmFsdWU9ImZhbHNlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5iaXJ0LmNvcmUvZGVidWciIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2Uub3NnaS90cmFjZS9hY3RpdmF0aW9uIiB2YWx1ZT0iZmFsc2UiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLmVxdWlub3guc2VjdXJpdHkvZGVidWcvbG9naW5GcmFtZXdvcmsiIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UudWkvcGVyZi9wZXJzcGVjdGl2ZS5zd2l0Y2giIHZhbHVlPSI4MDAiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLndzdC5zc2UuY29yZS90YXNrcy9qb2IiIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UudWkvcGVyZi9wYXJ0LmlucHV0IiB2YWx1ZT0iMjAwIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5qZmFjZS50ZXh0L2RlYnVnL0Fubm90YXRpb25QYWludGVyIiB2YWx1ZT0iZmFsc2UiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLndzdC5zc2UudWkvZXh0ZW5kZWRlZGl0b3JhY3Rpb25idWlsZGVyL2RlYnVnbWVudSIgdmFsdWU9ImZhbHNlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS50bS50ZXJtaW5hbC9kZWJ1Zy9sb2cvaW5mbyIgdmFsdWU9ImZhbHNlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS53c3Quc3NlLnVpL2RlYnVnL3JlY29uY2lsZXJTcGVsbGluZy9zaG93UHJvYmxlbXMiIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2Uub3NnaS9yZXNvbHZlci9pbXBvcnRzIiB2YWx1ZT0iZmFsc2UiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLm9zZ2kvdHJhY2UvZmlsdGVycyIgdmFsdWU9InRyYWNlLnByb3BlcnRpZXMiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLm9zZ2kvZWNsaXBzZWFkYXB0b3IvZGVidWcvcGxhdGZvcm1hZG1pbi9yZXNvbHZlciIgdmFsdWU9ImZhbHNlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5oZWxwLnVpL2RlYnVnL2luZm9wb3AiIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2Uud3N0LnNzZS51aS9kZWJ1ZyIgdmFsdWU9InRydWUiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLmVxdWlub3gucHJlZmVyZW5jZXMvZ2VuZXJhbCIgdmFsdWU9ImZhbHNlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS50ZWFtLmN2cy5jb3JlL2RlYnVnIiB2YWx1ZT0iZmFsc2UiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLnRlYW0uY3ZzLmNvcmUvdGhyZWFkaW5nIiB2YWx1ZT0iZmFsc2UiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLmpkdC5hcHQucGx1Z2dhYmxlLmNvcmUvZGVidWciIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuYmlydC5jaGFydC5lbmdpbmUvaW50ZXJuYWwuY29tcHV0YXRpb25zIiB2YWx1ZT0iZmFsc2UiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLmJpcnQuY2hhcnQuZW5naW5lL21vZGVsLmNvbXBvbmVudC5pbXBsIiB2YWx1ZT0iZmFsc2UiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLmpkdC51aS9wZXJmL3NlYXJjaC9wYXJ0aWNpcGFudHMiIHZhbHVlPSIzMDAiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLnVpL3BlcmYvcGFydC5saXN0ZW5lcnMiIHZhbHVlPSIyMDAiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLm9zZ2kvcmVzb2x2ZXIvZGVidWciIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UudXBkYXRlLmNvcmUvZGVidWcvaW5zdGFsbCIgdmFsdWU9ImZhbHNlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5lcXVpbm94LnNlY3VyaXR5LnVpL2RlYnVnIiB2YWx1ZT0iZmFsc2UiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLmVxdWlub3guc2VjdXJpdHkvZGVidWciIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMvZGVidWciIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuaGVscC51aS9kZWJ1Zy9lbWJlZGRlZEJyb3dzZXIvaW5wcm9jZXNzIiB2YWx1ZT0iZmFsc2UiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLnVpL3BlcmYvcGFydC5jb250cm9sIiB2YWx1ZT0iODAwIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5vc2dpL3Byb2ZpbGUvaW1wbCIgdmFsdWU9Im9yZy5lY2xpcHNlLm9zZ2kuaW50ZXJuYWwucHJvZmlsZS5EZWZhdWx0UHJvZmlsZUxvZ2dlciIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2Uub3NnaS9wcm9maWxlL2JlbmNobWFyayIgdmFsdWU9ImZhbHNlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5qZHQuY29yZS9kZWJ1Zy9jcHJlc29sdXRpb24vYWR2YW5jZWQiIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2Uud3N0LnNzZS5jb3JlL3Rhc2tzL3RpbWUiIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UudGVhbS5jdnMuY29yZS9jdnNwcm90b2NvbCIgdmFsdWU9InRydWUiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLmpkdC5jb3JlL2RlYnVnL3Bvc3RhY3Rpb24iIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2Uub3NnaS9kZWJ1Zy9tYW5pZmVzdCIgdmFsdWU9ImZhbHNlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5qZHQuY29yZS9wZXJmL3NlbGVjdGlvbiIgdmFsdWU9IjMwMCIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuaGVscC9kZWJ1Zy9jb250ZXh0IiB2YWx1ZT0iZmFsc2UiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLmpkdC51aS9wZXJmL2NvbnRlbnRfYXNzaXN0X3NvcnRlcnMvZXh0ZW5zaW9ucyIgdmFsdWU9IiIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuamR0LmNvcmUvZGVidWcvYnVpbGRlciIgdmFsdWU9ImZhbHNlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS53c3Quc3NlLnVpL2FjdGlvbmNvbnRyaWJ1dG9yL2RlYnVnc3RhdHVzZmllbGRzIiB2YWx1ZT0idHJ1ZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2Uub3NnaS9yZXNvbHZlci9yZXF1aXJlcyIgdmFsdWU9ImZhbHNlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS53c3Quc3NlLmNvcmUvZm9ybWF0IiB2YWx1ZT0iZmFsc2UiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLndzdC5zc2UudWkvZXh0ZW5kZWRjb25maWd1cmF0aW9uYnVpbGRlciIgdmFsdWU9ImZhbHNlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5iaXJ0LmNoYXJ0LmVuZ2luZS9tb2RlbC51dGlsIiB2YWx1ZT0iZmFsc2UiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLndzdC5kdGQudWkvcHJvamVjdGlvbnBlcmYiIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UudWkvdHJhY2UvaGFuZGxlcnMudmVyYm9zZSIgdmFsdWU9ImZhbHNlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5vc2dpL2RlYnVnL3N0YXJ0bGV2ZWwiIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UudXBkYXRlLmNvcmUvZGVidWcvaW5zdGFsbGhhbmRsZXIiIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2Uud3N0LnNzZS5jb3JlL3Rhc2tzL2RldGVjdGlvbiIgdmFsdWU9ImZhbHNlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5iaXJ0LmNoYXJ0LmVuZ2luZS9jb21wdXRhdGlvbiIgdmFsdWU9ImZhbHNlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5iaXJ0LmNoYXJ0LmVuZ2luZS9tb2RlbC50eXBlIiB2YWx1ZT0iZmFsc2UiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLndzdC5jb21tb24uZW52aXJvbm1lbnQvZGVidWciIHZhbHVlPSJ0cnVlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5qZHQuY29yZS9kZWJ1Zy9qYXZhZGVsdGEiIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMvcmVzdG9yZS90cmVlIiB2YWx1ZT0iZmFsc2UiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLmNvcmUucmVzb3VyY2VzL3ByZWZlcmVuY2VzIiB2YWx1ZT0iZmFsc2UiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLnVpLmludHJvL2ZsYWdzL25vQnJvd3NlciIgdmFsdWU9ImZhbHNlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5jb3JlLnJlc291cmNlcy9wZXJmL3NhdmUucGFydGljaXBhbnRzIiB2YWx1ZT0iNTAwIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5jb3JlLnJlc291cmNlcy9uYXR1cmVzIiB2YWx1ZT0iZmFsc2UiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLndzdC5zc2UudWkvZmlsZW1vZGVscHJvdmlkZXIvbW9kZWxzdGF0ZWxpc3RlbmVyIiB2YWx1ZT0iZmFsc2UiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLm9zZ2kvZGVmYXVsdHByb2ZpbGUvYnVmZmVyc2l6ZSIgdmFsdWU9IjI1NiIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2Uub3NnaS9yZXNvbHZlci9jeWNsZXMiIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuamR0LmNvcmUvcGVyZi92YXJpYWJsZWluaXRpYWxpemVyIiB2YWx1ZT0iNTAwMCIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UudWkvdHJhY2Uva2V5QmluZGluZ3MudmVyYm9zZSIgdmFsdWU9ImZhbHNlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5kZWJ1Zy51aS9kZWJ1Zy92aWV3ZXJzL21vZGVsIiB2YWx1ZT0iZmFsc2UiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLmJpcnQuY2hhcnQuZW5naW5lL21vZGVsLmF0dHJpYnV0ZS5pbXBsIiB2YWx1ZT0iZmFsc2UiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLndzdC5zc2UuY29yZS9maWxlYnVmZmVycy9tb2RlbG1hbmFnZW1lbnQiIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuY29yZS5ydW50aW1lL3BlcmYvc3VjY2VzcyIgdmFsdWU9ImZhbHNlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS51aS90cmFjZS9jb250ZXh0cy5wZXJmb3JtYW5jZSIgdmFsdWU9ImZhbHNlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5iaXJ0LmNoYXJ0LmVuZ2luZS90cmFjZSIgdmFsdWU9ImZhbHNlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5jb3JlLnJ1bnRpbWUvY29tcGF0aWJpbGl0eS9kZWJ1ZyIgdmFsdWU9ImZhbHNlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS51aS9kZWJ1Zy9kZWNsYXJlZEltYWdlcyIgdmFsdWU9ImZhbHNlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5wZGUuYnVpbGQvZGVidWciIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2Uub3NnaS9lY2xpcHNlYWRhcHRvci9kZWJ1Zy9sb2NhdGlvbiIgdmFsdWU9ImZhbHNlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5qZW0udXRpbC9kZWJ1Zy9sb2d0cmFjZWZpbGUiIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UudWkvdHJhY2UvY29udGV4dHMudmVyYm9zZSIgdmFsdWU9ImZhbHNlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS53c3QuY29tbW9uLmVudmlyb25tZW50L3RyYWNlL2VtaXR0ZXIiIHZhbHVlPSJ0cnVlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS50bS50ZXJtaW5hbC9kZWJ1Zy9sb2cvYnVmZmVyL3NpemUiIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UudWkvZGVidWcvc2hvd0FsbEpvYnMiIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuYmlydC5jaGFydC5lbmdpbmUvbW9kZWwiIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UudWkvbGlzdGVuZXJzL0lXb3JrYmVuY2hQYWdlLklQYXJ0TGlzdGVuZXIiIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuY29yZS5qb2JzL2pvYnMiIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UudWkvcGVyZi9wZXJzcGVjdGl2ZS5jcmVhdGUiIHZhbHVlPSI4MDAiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLnVpL3RyYWNlL3NvdXJjZXMiIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuZGVidWcuY29yZS9kZWJ1Zy9jb21tYW5kcyIgdmFsdWU9ImZhbHNlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5jb3JlLnJlc291cmNlcy9zdHJpbmdzIiB2YWx1ZT0iZmFsc2UiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLnVpL2xpc3RlbmVycy9JV29ya2JlbmNoUGFydFJlZmVyZW5jZSIgdmFsdWU9ImZhbHNlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS51aS5pZGUvZGVidWcvdW5kb21vbml0b3IiIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2Uud3N0LnNzZS51aS9zdHJ1Y3R1cmVkUHJlc2VudGF0aW9uUmVjb25jaWxlci90aW1lIiB2YWx1ZT0iZmFsc2UiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLmNvcmUucmVzb3VyY2VzL3NhdmUvbWV0YWluZm8iIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuYmlydC5jaGFydC5lbmdpbmUvbG9nLmltcGwiIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UudWkvcGVyZi9wYXJ0LmFjdGl2YXRlIiB2YWx1ZT0iMjAwIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS51aS5pbnRyby51bml2ZXJzYWwvZGVidWciIHZhbHVlPSJ0cnVlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS53c3Quc3NlLnVpL2NvbnRlbnRPdXRsaW5lIiB2YWx1ZT0iZmFsc2UiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLmNvcmUucnVudGltZS9wZXJmIiB2YWx1ZT0iZmFsc2UiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLndzdC54bWwuY29yZS9kZWJ1Zy9jbWRvY3VtZW50bWFuYWdlciIgdmFsdWU9ImZhbHNlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5iaXJ0LmNoYXJ0LmVuZ2luZS9tb2RlbC5pbXBsIiB2YWx1ZT0iZmFsc2UiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLmNvcmUucmVzb3VyY2VzL2NvbnRlbnR0eXBlIiB2YWx1ZT0iZmFsc2UiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLmJpcnQuY2hhcnQuZW5naW5lL2FnZ3JlZ2F0ZSIgdmFsdWU9ImZhbHNlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5tdGouY29yZS5ob29rcy9kZWJ1ZyIgdmFsdWU9ImZhbHNlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS51aS9kZWJ1Zy9jb250cmlidXRpb25zIiB2YWx1ZT0iZmFsc2UiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLnVpL2RlYnVnL2pvYi5zdGFsZSIgdmFsdWU9ImZhbHNlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS53c3QuY29tbW9uLmVudmlyb25tZW50L3RyYWNlL2luZm8iIHZhbHVlPSJ0cnVlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS51aS9wZXJmL3dvcmtiZW5jaC5zdGFydCIgdmFsdWU9IjQ1MDAwIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5qZHQuY29yZS9kZWJ1Zy9jb21wbGV0aW9uIiB2YWx1ZT0iZmFsc2UiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLm9zZ2kvZWNsaXBzZWFkYXB0b3IvZGVidWciIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UudWkvbGlzdGVuZXJzL0lXb3JrYmVuY2hXaW5kb3cuSVBhcnRMaXN0ZW5lciIgdmFsdWU9ImZhbHNlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS53c3Quc3NlLmNvcmUvZGVidWciIHZhbHVlPSJ0cnVlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5qZHQuY29yZS9kZWJ1Zy9mb3JtYXR0ZXIiIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuamR0LmNvcmUvZGVidWcvaW5kZXhtYW5hZ2VyIiB2YWx1ZT0iZmFsc2UiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLndzdC5zc2UudWkvcHJlZmVyZW5jZXMtcHJvcGVydGllcyIgdmFsdWU9ImZhbHNlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS53c3Quc3NlLnVpL3N0b3JhZ2Vtb2RlbHByb3ZpZGVyL29wZXJhdGlvbnMiIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UudWkvbGlzdGVuZXJzL0lXb3JrYmVuY2hXaW5kb3cuSVBlcnNwZWN0aXZlTGlzdGVuZXIiIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2Uub3NnaS9kZWJ1Zy9sb2FkZXIiIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2Uud3RwLmNvbW1vbi9kZWJ1Zy9sb2d0cmFjZSIgdmFsdWU9ImZhbHNlIi8+Ci08bWFwRW50cnkga2V5PSJjb20ubW91bnRhaW5taW5kcy5lY2xlbW1hLmNvcmUvZGVidWcvcGVyZm9ybWFuY2UiIHZhbHVlPSJ0cnVlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS51aS53b3JrYmVuY2gvZGVidWciIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2Uud3N0LnZhbGlkYXRpb24vdjEiIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuZGVidWcudWkvZGVidWcvbGF1bmNoaGlzdG9yeSIgdmFsdWU9ImZhbHNlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5vc2dpL2RlZmF1bHRwcm9maWxlL2xvZ3N5bmNocm9ub3VzbHkiIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2Uub3NnaS90cmFjZS9jbGFzc0xvYWRpbmciIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuamZhY2UudGV4dC9kZWJ1Zy9GYXN0UGFydGl0aW9uZXIvUG9zaXRpb25DYWNoZSIgdmFsdWU9ImZhbHNlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5kZWJ1Zy51aS9kZWJ1ZyIgdmFsdWU9ImZhbHNlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS53c3QueG1sLnVpL3Byb2plY3Rpb25wZXJmIiB2YWx1ZT0iZmFsc2UiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLndzdC5zc2UudWkvZXh0ZW5kZWRlZGl0b3JhY3Rpb25idWlsZGVyL3JlYWR0aW1lIiB2YWx1ZT0iZmFsc2UiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLnVpL3RyYWNlL2hhbmRsZXJzLnBlcmZvcm1hbmNlIiB2YWx1ZT0iZmFsc2UiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLmNvcmUucnVudGltZS9kZWJ1ZyIgdmFsdWU9ImZhbHNlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS51aS90cmFjZS9oYW5kbGVycy52ZXJib3NlLmNvbW1hbmRJZCIgdmFsdWU9IiIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2Uub3NnaS9kZWJ1Zy9maWx0ZXIiIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuamR0LmFwdC5jb3JlL2RlYnVnL2NvbXBpbGF0aW9uRW52IiB2YWx1ZT0iZmFsc2UiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLndzdC5zc2UuY29yZS9zdHJ1Y3R1cmVkbW9kZWwvbGlmZWN5Y2xlIiB2YWx1ZT0iZmFsc2UiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLmJpcnQuY2hhcnQuZW5naW5lL21vZGVsLmxheW91dC51dGlsIiB2YWx1ZT0iZmFsc2UiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLndzdC5zc2UuY29yZS9zdHJ1Y3R1cmVkbW9kZWwvbW9kZWxtYW5hZ2VyIiB2YWx1ZT0iZmFsc2UiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLmpkdC51aS9kZWJ1Zy9BU1RQcm92aWRlciIgdmFsdWU9ImZhbHNlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5lcXVpbm94LnNlY3VyaXR5LnVpL2RlYnVnL3N0b3JhZ2UiIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuamR0LmNvcmUvZGVidWcvYnVpbGRlci9zdGF0cyIgdmFsdWU9ImZhbHNlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5iaXJ0LmNoYXJ0LmVuZ2luZS9zdHlsZSIgdmFsdWU9ImZhbHNlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS53c3Quc3NlLnVpL2ZpbGVtb2RlbHByb3ZpZGVyL29wZXJhdGlvbnMiIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2Uud3N0LnNzZS5jb3JlL3Rhc2tzL3JlZ2lzdHJ5IiB2YWx1ZT0iZmFsc2UiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLnd0cC5jb21tb24vZGVidWcvbG9nbGV2ZWwiIHZhbHVlPSJXQVJOSU5HIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5iaXJ0LmNoYXJ0LmVuZ2luZS9mYWN0b3J5IiB2YWx1ZT0iZmFsc2UiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLmJpcnQuY2hhcnQuZW5naW5lL2ludGVybmFsIiB2YWx1ZT0iZmFsc2UiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLmhlbHAud2ViYXBwL2RlYnVnL3dvcmtpbmdzZXRzIiB2YWx1ZT0iZmFsc2UiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLm9zZ2kvZGVmYXVsdHByb2ZpbGUvbG9nZmlsZW5hbWUiIHZhbHVlPSIiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLnRtLnRlcm1pbmFsL2RlYnVnL2xvZy9kaXJlY3RvcnkiIHZhbHVlPSIvdG1wLyIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2Uud3N0LnNzZS51aS9wcm9wZXJ0eVNoZWV0IiB2YWx1ZT0iZmFsc2UiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLmNvcmUucnVudGltZS91cmwvZGVidWcvY29ubmVjdCIgdmFsdWU9ImZhbHNlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5qZmFjZS50ZXh0L2RlYnVnL0NvbnRlbnRBc3Npc3RTdWJqZWN0QWRhcHRlcnMiIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMvcmVzdG9yZS9tYXJrZXJzIiB2YWx1ZT0iZmFsc2UiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLndzdC5zc2UuY29yZS9zdHJ1Y3R1cmVkZG9jdW1lbnQiIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UudWkvdHJhY2UvZ3JhcGhpY3MiIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuamR0LmNvcmUvZGVidWcvcmVzb2x1dGlvbiIgdmFsdWU9ImZhbHNlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5jb3JlLnJlc291cmNlcy9wZXJmL3NuYXBzaG90IiB2YWx1ZT0iMTAwMCIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuZXF1aW5veC5kcy9wcmludF9vbl9jb25zb2xlIiB2YWx1ZT0idHJ1ZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuaGVscC9kZWJ1Zy9zZWFyY2giIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMvYnVpbGQvbmVlZGJ1aWxkc3RhY2siIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuaGVscC9kZWJ1Zy90b2MiIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UudWkvcGVyZi9wYXJ0LmluaXQiIHZhbHVlPSI4MDAiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLmJpcnQuY2hhcnQuZW5naW5lL3V0aWwiIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2Uud3N0LnNzZS5jb3JlL3N0cnVjdHVyZWRtb2RlbC9sb2NrcyIgdmFsdWU9InRydWUiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLnVpLmludHJvL3RyYWNlL2xvZ1BlcmZvcm1hbmNlIiB2YWx1ZT0iZmFsc2UiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLmJpcnQuY2hhcnQuZW5naW5lL3NjcmlwdCIgdmFsdWU9ImZhbHNlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS53c3Quc3NlLmNvcmUvZG9tL2FkYXB0ZXIvbm90aWZpY2F0aW9uL3RpbWUiIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2Uub3NnaS9lY2xpcHNlYWRhcHRvci9jb252ZXJ0ZXIvZGVidWciIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UudWkvcGVyZi9wYXJ0LmNyZWF0ZSIgdmFsdWU9IjgwMCIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2Uud3N0LmNvbW1vbi5wcm9qZWN0LmZhY2V0LmNvcmUvYWN0aXZhdGlvbiIgdmFsdWU9ImZhbHNlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS53dHAuY29tbW9uL2RlYnVnL2xvZ3RyYWNlZmlsZSIgdmFsdWU9ImZhbHNlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5vc2dpL2VjbGlwc2VhZGFwdG9yL2RlYnVnL3BsYXRmb3JtYWRtaW4iIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuaGVscC51aS9kZWJ1Zy9lbWJlZGRlZEJyb3dzZXIiIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2Uud3N0LnNzZS51aS9kZWJ1Zy9yZWNvbmNpbGVyVmFsaWRhdG9ycyIgdmFsdWU9ImZhbHNlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5lcXVpbm94LnByZWZlcmVuY2VzL3NldCIgdmFsdWU9ImZhbHNlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS53c3Quc3NlLmNvcmUvdGFza3Mvb3ZlcmFsbHRpbWUiIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UudGVhbS5jb3JlL3N0cmVhbXMiIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UudG0udGVybWluYWwvZGVidWcvdXNlX29sZF9pbXBsZW1lbnRhdGlvbiIgdmFsdWU9ImZhbHNlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS50bS50ZXJtaW5hbC9kZWJ1Zy9sb2ciIHZhbHVlPSJ0cnVlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5jb3JlLnJlc291cmNlcy9idWlsZC9zdGFja3RyYWNlIiB2YWx1ZT0iZmFsc2UiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLnVpL3RyYWNlL2tleUJpbmRpbmdzIiB2YWx1ZT0iZmFsc2UiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLmJpcnQuY2hhcnQuZW5naW5lL21vZGVsLmxheW91dCIgdmFsdWU9ImZhbHNlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5qZHQudWkvZGVidWcvVHlwZUNvbnN0cmFpbnRzIiB2YWx1ZT0iZmFsc2UiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLmVxdWlub3guZHMvZGVidWciIHZhbHVlPSJ0cnVlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS53c3QuY29tbW9uLmVudmlyb25tZW50L3RyYWNlL2Vycm9yIiB2YWx1ZT0idHJ1ZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuY29yZS5qb2JzL2pvYnMvYmVnaW5lbmQiIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuYmlydC5jaGFydC5lbmdpbmUvbW9kZWwuY29tcG9uZW50LnV0aWwiIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMvYnVpbGQvaW50ZXJydXB0IiB2YWx1ZT0iZmFsc2UiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLnVpL3BlcmYvc2hvd0hlYXBTdGF0dXMiIHZhbHVlPSJ0cnVlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS51aS9wZXJmL2NvbnRlbnRUeXBlcyIgdmFsdWU9IjIwMCIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UudWkvdHJhY2UvY29tbWFuZHMiIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMvYnVpbGQvZGVsdGEiIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuYmlydC5jaGFydC5lbmdpbmUvbW9kZWwuZGF0YSIgdmFsdWU9ImZhbHNlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5qZHQuY29yZS9kZWJ1Zy9zZWFyY2giIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuZXF1aW5veC5kcy9pbnN0YW50aWF0ZV9hbGwiIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2Uud3N0LmNvbW1vbi5lbnZpcm9ubWVudC90cmFjZS9jb21tYW5kIiB2YWx1ZT0idHJ1ZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2Uud3N0LmNvbW1vbi5wcm9qZWN0LmZhY2V0LmNvcmUvYWN0aW9uU29ydGluZyIgdmFsdWU9ImZhbHNlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5qZHQuYXB0LmNvcmUvZGVidWciIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuamR0LmNvcmUvcGVyZi9jb21wbGV0aW9uIiB2YWx1ZT0iMzAwIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5qZHQuY29yZS9kZWJ1Zy9jb21waWxlciIgdmFsdWU9ImZhbHNlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS53c3Quc3NlLnVpL3N0cnVjdHVyZWRQcmVzZW50YXRpb25SZWNvbmNpbGVyIiB2YWx1ZT0iZmFsc2UiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLmpkdC51aS9kZWJ1ZyIgdmFsdWU9InRydWUiLz4KLTxtYXBFbnRyeSBrZXk9ImNvbS5tb3VudGFpbm1pbmRzLmVjbGVtbWEuY29yZS9kZWJ1Zy9lbW1hVmVyYm9zaXR5TGV2ZWwiIHZhbHVlPSJpbmZvIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS53c3Quc3NlLmNvcmUvZG9tL2FkYXB0ZXIvbm90aWZpY2F0aW9uL3RpbWUvY3JpdGVyaWEiIHZhbHVlPSIxMCIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuamR0LmNvcmUvZGVidWcvamF2YW1vZGVsL2NhY2hlIiB2YWx1ZT0iZmFsc2UiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLnVwZGF0ZS5jb3JlL2RlYnVnL2NvbmZpZ3VyYXRpb24iIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2Uub3NnaS9kZWJ1Zy9tZXNzYWdlQnVuZGxlcyIgdmFsdWU9ImZhbHNlIi8+Ci08bWFwRW50cnkga2V5PSJjb20ubW91bnRhaW5taW5kcy5lY2xlbW1hLmNvcmUvZGVidWcvbGF1bmNoaW5nIiB2YWx1ZT0idHJ1ZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2Uud3N0LnNzZS51aS9nb3RvTmV4dEFubm90YXRpb24iIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuamR0LmNvcmUubWFuaXB1bGF0aW9uL2RlYnVnIiB2YWx1ZT0idHJ1ZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UudWkvbGlzdGVuZXJzL0lXb3JrYmVuY2hXaW5kb3cuSVBhcnRMaXN0ZW5lcjIiIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UudWkvbGlzdGVuZXJzL0lXb3JrYmVuY2hQYWdlLklQYXJ0TGlzdGVuZXIyIiB2YWx1ZT0iZmFsc2UiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLndzdC52YWxpZGF0aW9uL2RlYnVnIiB2YWx1ZT0idHJ1ZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuamR0LmNvcmUvcGVyZi9yZWNvbmNpbGUiIHZhbHVlPSIxMDAwIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5qZHQuY29yZS9kZWJ1Zy9oaWVyYXJjaHkiIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuaGVscC53ZWJhcHAvZGVidWciIHZhbHVlPSJ0cnVlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS51aS9kZWJ1Zy93b3JraW5nU2V0cyIgdmFsdWU9ImZhbHNlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS53c3Quc3NlLmNvcmUvZmlsZWJ1ZmZlcnMvbGlmZWN5Y2xlIiB2YWx1ZT0iZmFsc2UiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLmNvcmUucmVzb3VyY2VzL3JlZnJlc2giIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UudGVhbS5jb3JlL2JhY2tncm91bmRldmVudHMiIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UubHRrLmNvcmUucmVmYWN0b3JpbmcvcGVyZi9wYXJ0aWNpcGFudHMvY3JlYXRlQ2hhbmdlcyIgdmFsdWU9IjMwMCIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuamR0LmNvcmUvZGVidWcvY3ByZXNvbHV0aW9uIiB2YWx1ZT0iZmFsc2UiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLndzdC5zc2UudWkvZGVidWcvcmVjb25jaWxlclNwZWxsaW5nIiB2YWx1ZT0iZmFsc2UiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLnVwZGF0ZS5jb3JlL2RlYnVnL3dhcm5pbmciIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMvc2F2ZSIgdmFsdWU9ImZhbHNlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS53c3Quc3NlLnVpL2ZpbGVtb2RlbHByb3ZpZGVyL2xpZmVjeWNsZWxpc3RlbmVyIiB2YWx1ZT0iZmFsc2UiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLndzdC5jb21tb24ucHJvamVjdC5mYWNldC5jb3JlL2RlbGVnYXRlL2NhbGxzIiB2YWx1ZT0iZmFsc2UiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLnVwZGF0ZS5jb3JlL2RlYnVnL3BhcnNpbmciIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuamR0LnVpL3BlcmYvZXhwbG9yZXIvbWFrZUFjdGlvbnMiIHZhbHVlPSIxMDAwIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5jb3JlLnJlc291cmNlcy9yZXN0b3JlL3N5bmNpbmZvIiB2YWx1ZT0iZmFsc2UiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLmRlYnVnLnVpL2RlYnVnL3ZpZXdlcnMvY29udGVudFByb3ZpZGVyIiB2YWx1ZT0iZmFsc2UiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLnVpL2xpc3RlbmVycy9JV29ya2JlbmNoV2luZG93LklQYWdlTGlzdGVuZXIiIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UudGVhbS5jb3JlL3RocmVhZGluZyIgdmFsdWU9ImZhbHNlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5jb3JlLnJ1bnRpbWUvdXJsL2RlYnVnL2NhY2hlbG9va3VwIiB2YWx1ZT0iZmFsc2UiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLnVwZGF0ZS5jb3JlL2RlYnVnL3JlY29uY2lsZXIiIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2Uub3NnaS9kZWJ1Zy9zZWN1cml0eSIgdmFsdWU9ImZhbHNlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5iaXJ0LmNoYXJ0LmVuZ2luZS9kZWJ1ZyIgdmFsdWU9ImZhbHNlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5iaXJ0LmNoYXJ0LmVuZ2luZS9tb2RlbC5wcmVmcyIgdmFsdWU9ImZhbHNlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5jb3JlLnJlc291cmNlcy9zYXZlL3N5bmNpbmZvIiB2YWx1ZT0iZmFsc2UiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLm9zZ2kvcHJvZmlsZS9zdGFydHVwIiB2YWx1ZT0iZmFsc2UiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLm9zZ2kvZGVidWcvc2VydmljZXMiIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2Uud3N0LmNvbW1vbi5lbnZpcm9ubWVudC90cmFjZS93c19hbnQiIHZhbHVlPSJ0cnVlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5iaXJ0LmNoYXJ0LmVuZ2luZS9jb21wdXRhdGlvbi53aXRoYXhlcyIgdmFsdWU9ImZhbHNlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5jb3JlLnJlc291cmNlcy9zYXZlL21hcmtlcnMiIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuY29yZS5ydW50aW1lL3ByZWZlcmVuY2VzL3BsdWdpbiIgdmFsdWU9ImZhbHNlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5iaXJ0LmNoYXJ0LmVuZ2luZS9wbHVnaW4iIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2Uub3NnaS9tb25pdG9yL3Jlc291cmNlcyIgdmFsdWU9ImZhbHNlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS53c3Quc3NlLnVpL2V4dGVuZGVkZWRpdG9yYWN0aW9uYnVpbGRlci9kZWJ1Z3BvcHVwIiB2YWx1ZT0iZmFsc2UiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLmNvcmUuam9icy9qb2JzL3RpbWluZyIgdmFsdWU9ImZhbHNlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5qZHQuY29yZS9kZWJ1Zy9zZWxlY3Rpb24iIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuYmlydC5jaGFydC5lbmdpbmUvZXhjZXB0aW9uIiB2YWx1ZT0iZmFsc2UiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLmpkdC51aS9kZWJ1Zy9SZXN1bHRDb2xsZWN0b3IiIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UudG0udGVybWluYWwvZGVidWcvbG9nL2Vycm9yIiB2YWx1ZT0idHJ1ZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMvcmVzdG9yZS9zbmFwc2hvdHMiIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuamR0LnVpL3BlcmYvZXhwbG9yZXIvY3JlYXRlUGFydENvbnRyb2wiIHZhbHVlPSIxMzAwIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS50ZWFtLmN2cy5jb3JlL2RpcnR5Y2FjaGluZyIgdmFsdWU9ImZhbHNlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5qZHQuYXB0LmNvcmUvZGVidWcvZ2VuZXJhdGVkRmlsZXMiIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuamR0LmNvcmUvZGVidWcvemlwYWNjZXNzIiB2YWx1ZT0iZmFsc2UiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLnBkZS5jb3JlL2NhY2hlIiB2YWx1ZT0iZmFsc2UiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLndzdC5zc2UudWkvZXh0ZW5kZWRlZGl0b3JhY3Rpb25idWlsZGVyIiB2YWx1ZT0iZmFsc2UiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLmNvcmUucnVudGltZS91cmwvZGVidWcvY2FjaGVjb3B5IiB2YWx1ZT0iZmFsc2UiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLmRlYnVnLnVpL2RlYnVnL3ZpZXdlcnMvc3RhdGVTYXZlUmVzdG9yZSIgdmFsdWU9ImZhbHNlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5vc2dpL2RlYnVnL2J1bmRsZVRpbWUiIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UudWkvdHJhY2Uvb3BlcmF0aW9ucy52ZXJib3NlIiB2YWx1ZT0iZmFsc2UiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLnRlYW0uY3ZzLmNvcmUvbWV0YWZpbGVzIiB2YWx1ZT0iZmFsc2UiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLndzdC5zc2UudWkvZXh0ZW5kZWRlZGl0b3JhY3Rpb25idWlsZGVyL2RlYnVndG9vbGJhciIgdmFsdWU9ImZhbHNlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS50ZWFtLmNvcmUvZGVidWciIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2Uud3N0LnhtbC5jb3JlL2RlYnVnL2NtZG9jdW1lbnRjYWNoZSIgdmFsdWU9ImZhbHNlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS51aS9wZXJmL3dvcmtiZW5jaC5yZXN0b3JlIiB2YWx1ZT0iMzAwMDAiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLndzdC5zc2UudWkvc3RvcmFnZW1vZGVscHJvdmlkZXIvZWxlbWVudHN0YXRlbGlzdGVuZXIiIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2Uud3N0LnNzZS51aS9leHRlbmRlZGVkaXRvcmFjdGlvbmJ1aWxkZXIvY29udHJpYnV0ZXRpbWUiIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2Uub3NnaS9kZWJ1Zy9ldmVudHMiIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2Uud3N0LmNvbW1vbi5lbnZpcm9ubWVudC90cmFjZS93YXJuaW5nIiB2YWx1ZT0idHJ1ZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2Uud3N0LnhtbC5jb3JlL2RlYnVnIiB2YWx1ZT0idHJ1ZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuY29yZS5qb2JzL2pvYnMvZXJyb3JvbmRlYWRsb2NrIiB2YWx1ZT0iZmFsc2UiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLnVpL2RlYnVnL3N3dGRlYnVnZ2xvYmFsIiB2YWx1ZT0iZmFsc2UiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLnVpLmlkZS9kZWJ1Zy9pbnRlcm5hbGVycm9yL29wZW5EaWFsb2ciIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuYmlydC5jaGFydC5lbmdpbmUvY29tcHV0YXRpb24ud2l0aG91dGF4ZXMiIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuYmlydC5jaGFydC5lbmdpbmUvbW9kZWwuY29tcG9uZW50IiB2YWx1ZT0iZmFsc2UiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLnVpLmludHJvLnVuaXZlcnNhbC90cmFjZS9sb2dQZXJmb3JtYW5jZSIgdmFsdWU9ImZhbHNlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS51aS5pZGUvZGVidWcvbWFya2VycyIgdmFsdWU9ImZhbHNlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS51aS9wZXJmL3Vpam9iIiB2YWx1ZT0iMjAwIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5qZHQuY29yZS9kZWJ1Zy9zb3VyY2VtYXBwZXIiIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuZGVidWcudWkvZGVidWcvdmlld2Vycy9kZWx0YXMiIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2Uub3NnaS9yZXNvbHZlci9nZW5lcmljcyIgdmFsdWU9ImZhbHNlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5vc2dpL3Jlc29sdmVyL3dpcmluZyIgdmFsdWU9ImZhbHNlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5qZHQuY29yZS9wZXJmL2phdmFkZWx0YWxpc3RlbmVyIiB2YWx1ZT0iNTAwIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5vc2dpL3Byb2ZpbGUvZGVidWciIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0iY29tLm1vdW50YWlubWluZHMuZWNsZW1tYS5jb3JlL2RlYnVnL2FuYWx5c2lzIiB2YWx1ZT0idHJ1ZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UudG0udGVybWluYWwvZGVidWcvbG9nL2NoYXIiIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UudWkvdHJhY2UvY29udGV4dHMiIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuY29yZS5jb250ZW50dHlwZS9kZWJ1ZyIgdmFsdWU9ImZhbHNlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS51aS90cmFjZS9tdWx0aXBhZ2VlZGl0b3IiIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMvYnVpbGQvaW52b2tpbmciIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuYmlydC5jaGFydC5lbmdpbmUvbW9kZWwuZGF0YS51dGlsIiB2YWx1ZT0iZmFsc2UiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLmplbS51dGlsL2RlYnVnL2xvZ2xldmVsIiB2YWx1ZT0iV0FSTklORyIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UudWkvdHJhY2Uvb3BlcmF0aW9ucyIgdmFsdWU9ImZhbHNlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5jb3JlLnJlc291cmNlcy9wZXJmL2J1aWxkZXJzIiB2YWx1ZT0iMTAwMDAiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLnVwZGF0ZS5jb3JlL2RlYnVnL3R5cGUiIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UudWkvcGVyZi9wYWdlLmxpc3RlbmVycyIgdmFsdWU9IjIwMCIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuYmlydC5jaGFydC5lbmdpbmUvbW9kZWwuYXR0cmlidXRlIiB2YWx1ZT0iZmFsc2UiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLmpkdC51aS9wZXJmL2V4cGxvcmVyL1JlZmFjdG9yQWN0aW9uR3JvdXAiIHZhbHVlPSIxNTAiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLmNvcmUucmVzb3VyY2VzL2hpc3RvcnkiIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UudGVhbS5jb3JlL3JlZnJlc2hqb2IiIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuYmlydC5jaGFydC5lbmdpbmUvZW5naW5lLmkxOG4iIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UudWkuaW50cm8vZGVidWciIHZhbHVlPSJ0cnVlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5qZmFjZS50ZXh0L2RlYnVnL0Fic3RyYWN0SW5mb3JtYXRpb25Db250cm9sTWFuYWdlciIgdmFsdWU9ImZhbHNlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5kZWJ1Zy5jb3JlL2RlYnVnIiB2YWx1ZT0iZmFsc2UiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLmhlbHAvZGVidWciIHZhbHVlPSJ0cnVlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5qZmFjZS50ZXh0LnNvdXJjZS9kZWJ1Zy9SZXZpc2lvblJ1bGVyQ29sdW1uIiB2YWx1ZT0iZmFsc2UiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLnVpL2RlYnVnIiB2YWx1ZT0iZmFsc2UiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLm9zZ2kvZGVidWcvcGFja2FnZWFkbWluIiB2YWx1ZT0iZmFsc2UiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLmNvcmUucmVzb3VyY2VzL2J1aWxkL2ZhaWx1cmUiIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UudWkvdHJhY2UvaGFuZGxlcnMiIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UudWkvbGlzdGVuZXJzL0lXb3JrYmVuY2hQYWdlLklQcm9wZXJ0eUNoYW5nZUxpc3RlbmVyIiB2YWx1ZT0iZmFsc2UiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLnVpLmJyb3dzZXIvZGVidWciIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2Uud3N0LmNvbW1vbi5lbnZpcm9ubWVudC90cmFjZS93c19kdF9jbWRfZW5naW5lIiB2YWx1ZT0idHJ1ZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMvc2F2ZS90cmVlIiB2YWx1ZT0iZmFsc2UiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLndzdC5zc2UudWkvZGVidWcvdHJhY2VmaWx0ZXIiIHZhbHVlPSIiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLmhlbHAudWkvZGVidWciIHZhbHVlPSJ0cnVlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5iaXJ0LmNoYXJ0LmVuZ2luZS9tb2RlbC50eXBlLnV0aWwiIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMvcmVzdG9yZS9tZXRhaW5mbyIgdmFsdWU9ImZhbHNlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5jb3JlLnJlc291cmNlcy9zYXZlL21hc3RlcnRhYmxlIiB2YWx1ZT0iZmFsc2UiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLnBkZS5jb3JlL2RlYnVnIiB2YWx1ZT0idHJ1ZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2Uud3N0LnNzZS51aS9leHRlbmRlZGNvbmZpZ3VyYXRpb25idWlsZGVyL3RpbWUiIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuamR0LmNvcmUvZGVidWcvYnVmZmVybWFuYWdlciIgdmFsdWU9ImZhbHNlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5iaXJ0LmNoYXJ0LmVuZ2luZS9tb2RlbC5sYXlvdXQuaW1wbCIgdmFsdWU9ImZhbHNlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS51aS5pZGUvZGVidWciIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UudG0udGVybWluYWwvZGVidWcvbG9nL1ZUMTAwQmFja2VuZCIgdmFsdWU9ImZhbHNlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS51aS5pbnRyby90cmFjZS9sb2dJbmZvIiB2YWx1ZT0idHJ1ZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMvcmVzdG9yZS9tYXN0ZXJ0YWJsZSIgdmFsdWU9ImZhbHNlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5iaXJ0LmNoYXJ0LmVuZ2luZS9pbnRlcm5hbC5zY3JpcHQiIHZhbHVlPSJmYWxzZSIvPgotPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UudWkvZXhwZXJpbWVudGFsL21lbnVzIiB2YWx1ZT0iZmFsc2UiLz4KLTxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLnBkZS5jb3JlL2NsYXNzcGF0aCIgdmFsdWU9ImZhbHNlIi8+Ci08bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5iaXJ0LmNoYXJ0LmVuZ2luZS9tb2RlbC5hdHRyaWJ1dGUudXRpbCIgdmFsdWU9ImZhbHNlIi8+Ci08L21hcEF0dHJpYnV0ZT4KLTxib29sZWFuQXR0cmlidXRlIGtleT0idXNlRGVmYXVsdENvbmZpZyIgdmFsdWU9InRydWUiLz4KLTxib29sZWFuQXR0cmlidXRlIGtleT0idXNlRGVmYXVsdENvbmZpZ0FyZWEiIHZhbHVlPSJmYWxzZSIvPgotPGJvb2xlYW5BdHRyaWJ1dGUga2V5PSJ1c2VQcm9kdWN0IiB2YWx1ZT0iZmFsc2UiLz4KLTwvbGF1bmNoQ29uZmlndXJhdGlvbj4KKzw/eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04IiBzdGFuZGFsb25lPSJubyI/Pg0KKzxsYXVuY2hDb25maWd1cmF0aW9uIHR5cGU9Im9yZy5lY2xpcHNlLnBkZS51aS5KdW5pdExhdW5jaENvbmZpZyI+DQorPGJvb2xlYW5BdHRyaWJ1dGUga2V5PSJhcHBlbmQuYXJncyIgdmFsdWU9InRydWUiLz4NCis8c3RyaW5nQXR0cmlidXRlIGtleT0iYXBwbGljYXRpb24iIHZhbHVlPSJvcmcuZWNsaXBzZS5wZGUuanVuaXQucnVudGltZS5jb3JldGVzdGFwcGxpY2F0aW9uIi8+DQorPGJvb2xlYW5BdHRyaWJ1dGUga2V5PSJhc2tjbGVhciIgdmFsdWU9ImZhbHNlIi8+DQorPGJvb2xlYW5BdHRyaWJ1dGUga2V5PSJhdXRvbWF0aWNBZGQiIHZhbHVlPSJ0cnVlIi8+DQorPGJvb2xlYW5BdHRyaWJ1dGUga2V5PSJhdXRvbWF0aWNWYWxpZGF0ZSIgdmFsdWU9ImZhbHNlIi8+DQorPHN0cmluZ0F0dHJpYnV0ZSBrZXk9ImJvb3RzdHJhcCIgdmFsdWU9IiIvPg0KKzxzdHJpbmdBdHRyaWJ1dGUga2V5PSJjaGVja2VkIiB2YWx1ZT0iW05PTkVdIi8+DQorPGJvb2xlYW5BdHRyaWJ1dGUga2V5PSJjbGVhckNvbmZpZyIgdmFsdWU9InRydWUiLz4NCis8Ym9vbGVhbkF0dHJpYnV0ZSBrZXk9ImNsZWFyd3MiIHZhbHVlPSJ0cnVlIi8+DQorPGJvb2xlYW5BdHRyaWJ1dGUga2V5PSJjbGVhcndzbG9nIiB2YWx1ZT0iZmFsc2UiLz4NCis8c3RyaW5nQXR0cmlidXRlIGtleT0iY29uZmlnTG9jYXRpb24iIHZhbHVlPSIke3dvcmtzcGFjZV9sb2N9Ly5tZXRhZGF0YS8ucGx1Z2lucy9vcmcuZWNsaXBzZS5wZGUuY29yZS9wZGUtanVuaXQiLz4NCis8Ym9vbGVhbkF0dHJpYnV0ZSBrZXk9ImRlZmF1bHQiIHZhbHVlPSJ0cnVlIi8+DQorPGJvb2xlYW5BdHRyaWJ1dGUga2V5PSJpbmNsdWRlT3B0aW9uYWwiIHZhbHVlPSJ0cnVlIi8+DQorPHN0cmluZ0F0dHJpYnV0ZSBrZXk9ImxvY2F0aW9uIiB2YWx1ZT0iJHt3b3Jrc3BhY2VfbG9jfS8uLi9qdW5pdC13b3Jrc3BhY2UiLz4NCis8bGlzdEF0dHJpYnV0ZSBrZXk9Im9yZy5lY2xpcHNlLmRlYnVnLmNvcmUuTUFQUEVEX1JFU09VUkNFX1BBVEhTIj4NCis8bGlzdEVudHJ5IHZhbHVlPSIvb3JnLmVjbGlwc2UuZXF1aW5veC5kcy50ZXN0cy9zcmMvb3JnL2VjbGlwc2UvZXF1aW5veC9kcy90ZXN0cy9BbGxUZXN0cy5qYXZhIi8+DQorPC9saXN0QXR0cmlidXRlPg0KKzxsaXN0QXR0cmlidXRlIGtleT0ib3JnLmVjbGlwc2UuZGVidWcuY29yZS5NQVBQRURfUkVTT1VSQ0VfVFlQRVMiPg0KKzxsaXN0RW50cnkgdmFsdWU9IjEiLz4NCis8L2xpc3RBdHRyaWJ1dGU+DQorPHN0cmluZ0F0dHJpYnV0ZSBrZXk9Im9yZy5lY2xpcHNlLmRlYnVnLmNvcmUuc291cmNlX2xvY2F0b3JfaWQiIHZhbHVlPSJvcmcuZWNsaXBzZS5wZGUudWkubGF1bmNoZXIuUERFU291cmNlTG9va3VwRGlyZWN0b3IiLz4NCis8c3RyaW5nQXR0cmlidXRlIGtleT0ib3JnLmVjbGlwc2UuZGVidWcuY29yZS5zb3VyY2VfbG9jYXRvcl9tZW1lbnRvIiB2YWx1ZT0iJmx0Oz94bWwgdmVyc2lvbj0mcXVvdDsxLjAmcXVvdDsgZW5jb2Rpbmc9JnF1b3Q7VVRGLTgmcXVvdDsgc3RhbmRhbG9uZT0mcXVvdDtubyZxdW90Oz8mZ3Q7JiMxMzsmIzEwOyZsdDtzb3VyY2VMb29rdXBEaXJlY3RvciZndDsmIzEzOyYjMTA7Jmx0O3NvdXJjZUNvbnRhaW5lcnMgZHVwbGljYXRlcz0mcXVvdDtmYWxzZSZxdW90OyZndDsmIzEzOyYjMTA7Jmx0O2NvbnRhaW5lciBtZW1lbnRvPSZxdW90OyZhbXA7bHQ7P3htbCB2ZXJzaW9uPSZhbXA7cXVvdDsxLjAmYW1wO3F1b3Q7IGVuY29kaW5nPSZhbXA7cXVvdDtVVEYtOCZhbXA7cXVvdDsgc3RhbmRhbG9uZT0mYW1wO3F1b3Q7bm8mYW1wO3F1b3Q7PyZhbXA7Z3Q7JmFtcDsjMTM7JmFtcDsjMTA7JmFtcDtsdDtqYXZhUHJvamVjdCBuYW1lPSZhbXA7cXVvdDtvcmcuZWNsaXBzZS5vc2dpJmFtcDtxdW90Oy8mYW1wO2d0OyZhbXA7IzEzOyZhbXA7IzEwOyZxdW90OyB0eXBlSWQ9JnF1b3Q7b3JnLmVjbGlwc2UuamR0LmxhdW5jaGluZy5zb3VyY2VDb250YWluZXIuamF2YVByb2plY3QmcXVvdDsvJmd0OyYjMTM7JiMxMDsmbHQ7Y29udGFpbmVyIG1lbWVudG89JnF1b3Q7JmFtcDtsdDs/eG1sIHZlcnNpb249JmFtcDtxdW90OzEuMCZhbXA7cXVvdDsgZW5jb2Rpbmc9JmFtcDtxdW90O1VURi04JmFtcDtxdW90OyBzdGFuZGFsb25lPSZhbXA7cXVvdDtubyZhbXA7cXVvdDs/JmFtcDtndDsmYW1wOyMxMzsmYW1wOyMxMDsmYW1wO2x0O2RlZmF1bHQvJmFtcDtndDsmYW1wOyMxMzsmYW1wOyMxMDsmcXVvdDsgdHlwZUlkPSZxdW90O29yZy5lY2xpcHNlLmRlYnVnLmNvcmUuY29udGFpbmVyVHlwZS5kZWZhdWx0JnF1b3Q7LyZndDsmIzEzOyYjMTA7Jmx0Oy9zb3VyY2VDb250YWluZXJzJmd0OyYjMTM7JiMxMDsmbHQ7L3NvdXJjZUxvb2t1cERpcmVjdG9yJmd0OyYjMTM7JiMxMDsiLz4NCis8c3RyaW5nQXR0cmlidXRlIGtleT0ib3JnLmVjbGlwc2UuamR0Lmp1bml0LkNPTlRBSU5FUiIgdmFsdWU9IiIvPg0KKzxib29sZWFuQXR0cmlidXRlIGtleT0ib3JnLmVjbGlwc2UuamR0Lmp1bml0LktFRVBSVU5OSU5HX0FUVFIiIHZhbHVlPSJmYWxzZSIvPg0KKzxzdHJpbmdBdHRyaWJ1dGUga2V5PSJvcmcuZWNsaXBzZS5qZHQuanVuaXQuVEVTVE5BTUUiIHZhbHVlPSIiLz4NCis8c3RyaW5nQXR0cmlidXRlIGtleT0ib3JnLmVjbGlwc2UuamR0Lmp1bml0LlRFU1RfS0lORCIgdmFsdWU9Im9yZy5lY2xpcHNlLmpkdC5qdW5pdC5sb2FkZXIuanVuaXQ0Ii8+DQorPHN0cmluZ0F0dHJpYnV0ZSBrZXk9Im9yZy5lY2xpcHNlLmpkdC5sYXVuY2hpbmcuSlJFX0NPTlRBSU5FUiIgdmFsdWU9Im9yZy5lY2xpcHNlLmpkdC5sYXVuY2hpbmcuSlJFX0NPTlRBSU5FUi9vcmcuZWNsaXBzZS5qZHQuaW50ZXJuYWwuZGVidWcudWkubGF1bmNoZXIuU3RhbmRhcmRWTVR5cGUvSmF2YVNFLTEuOCIvPg0KKzxzdHJpbmdBdHRyaWJ1dGUga2V5PSJvcmcuZWNsaXBzZS5qZHQubGF1bmNoaW5nLk1BSU5fVFlQRSIgdmFsdWU9Im9yZy5lY2xpcHNlLmVxdWlub3guZHMudGVzdHMuQWxsVGVzdHMiLz4NCis8c3RyaW5nQXR0cmlidXRlIGtleT0ib3JnLmVjbGlwc2UuamR0LmxhdW5jaGluZy5QUk9HUkFNX0FSR1VNRU5UUyIgdmFsdWU9Ii1vcyAke3RhcmdldC5vc30gLXdzICR7dGFyZ2V0LndzfSAtYXJjaCAke3RhcmdldC5hcmNofSAtbmwgJHt0YXJnZXQubmx9IC1jb25zb2xlIC1jb25zb2xlTG9nIi8+DQorPHN0cmluZ0F0dHJpYnV0ZSBrZXk9Im9yZy5lY2xpcHNlLmpkdC5sYXVuY2hpbmcuUFJPSkVDVF9BVFRSIiB2YWx1ZT0ib3JnLmVjbGlwc2UuZXF1aW5veC5kcy50ZXN0cyIvPg0KKzxzdHJpbmdBdHRyaWJ1dGUga2V5PSJvcmcuZWNsaXBzZS5qZHQubGF1bmNoaW5nLlNPVVJDRV9QQVRIX1BST1ZJREVSIiB2YWx1ZT0ib3JnLmVjbGlwc2UucGRlLnVpLndvcmtiZW5jaENsYXNzcGF0aFByb3ZpZGVyIi8+DQorPHN0cmluZ0F0dHJpYnV0ZSBrZXk9InBkZS52ZXJzaW9uIiB2YWx1ZT0iMy4zIi8+DQorPHN0cmluZ0F0dHJpYnV0ZSBrZXk9InByb2R1Y3QiIHZhbHVlPSJvcmcuZWNsaXBzZS5zZGsuaWRlIi8+DQorPGJvb2xlYW5BdHRyaWJ1dGUga2V5PSJydW5faW5fdWlfdGhyZWFkIiB2YWx1ZT0idHJ1ZSIvPg0KKzxib29sZWFuQXR0cmlidXRlIGtleT0ic2hvd19zZWxlY3RlZF9vbmx5IiB2YWx1ZT0iZmFsc2UiLz4NCis8c3RyaW5nQXR0cmlidXRlIGtleT0idGVtcGxhdGVDb25maWciIHZhbHVlPSIke3RhcmdldF9ob21lfVxjb25maWd1cmF0aW9uXGNvbmZpZy5pbmkiLz4NCis8Ym9vbGVhbkF0dHJpYnV0ZSBrZXk9InRyYWNpbmciIHZhbHVlPSJmYWxzZSIvPg0KKzxtYXBBdHRyaWJ1dGUga2V5PSJ0cmFjaW5nT3B0aW9ucyI+DQorPG1hcEVudHJ5IGtleT0iY29tLm1vdW50YWlubWluZHMuZWNsZW1tYS5jb3JlL2RlYnVnL2FuYWx5c2lzIiB2YWx1ZT0idHJ1ZSIvPg0KKzxtYXBFbnRyeSBrZXk9ImNvbS5tb3VudGFpbm1pbmRzLmVjbGVtbWEuY29yZS9kZWJ1Zy9lbW1hVmVyYm9zaXR5TGV2ZWwiIHZhbHVlPSJpbmZvIi8+DQorPG1hcEVudHJ5IGtleT0iY29tLm1vdW50YWlubWluZHMuZWNsZW1tYS5jb3JlL2RlYnVnL2luc3RydW1lbnRhdGlvbiIgdmFsdWU9InRydWUiLz4NCis8bWFwRW50cnkga2V5PSJjb20ubW91bnRhaW5taW5kcy5lY2xlbW1hLmNvcmUvZGVidWcvbGF1bmNoaW5nIiB2YWx1ZT0idHJ1ZSIvPg0KKzxtYXBFbnRyeSBrZXk9ImNvbS5tb3VudGFpbm1pbmRzLmVjbGVtbWEuY29yZS9kZWJ1Zy9wZXJmb3JtYW5jZSIgdmFsdWU9InRydWUiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5iaXJ0LmNoYXJ0LmVuZ2luZS9hZ2dyZWdhdGUiIHZhbHVlPSJmYWxzZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLmJpcnQuY2hhcnQuZW5naW5lL2NvbXB1dGF0aW9uIiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5iaXJ0LmNoYXJ0LmVuZ2luZS9jb21wdXRhdGlvbi53aXRoYXhlcyIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuYmlydC5jaGFydC5lbmdpbmUvY29tcHV0YXRpb24ud2l0aG91dGF4ZXMiIHZhbHVlPSJmYWxzZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLmJpcnQuY2hhcnQuZW5naW5lL2RhdGFmZWVkIiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5iaXJ0LmNoYXJ0LmVuZ2luZS9kZWJ1ZyIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuYmlydC5jaGFydC5lbmdpbmUvZGV2aWNlIiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5iaXJ0LmNoYXJ0LmVuZ2luZS9lbmdpbmUuaTE4biIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuYmlydC5jaGFydC5lbmdpbmUvZXZlbnQiIHZhbHVlPSJmYWxzZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLmJpcnQuY2hhcnQuZW5naW5lL2V4Y2VwdGlvbiIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuYmlydC5jaGFydC5lbmdpbmUvZmFjdG9yeSIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuYmlydC5jaGFydC5lbmdpbmUvaW50ZXJuYWwiIHZhbHVlPSJmYWxzZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLmJpcnQuY2hhcnQuZW5naW5lL2ludGVybmFsLmNvbXB1dGF0aW9ucyIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuYmlydC5jaGFydC5lbmdpbmUvaW50ZXJuYWwuZmFjdG9yeSIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuYmlydC5jaGFydC5lbmdpbmUvaW50ZXJuYWwuc2NyaXB0IiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5iaXJ0LmNoYXJ0LmVuZ2luZS9sb2ciIHZhbHVlPSJmYWxzZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLmJpcnQuY2hhcnQuZW5naW5lL2xvZy5pbXBsIiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5iaXJ0LmNoYXJ0LmVuZ2luZS9tb2RlbCIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuYmlydC5jaGFydC5lbmdpbmUvbW9kZWwuYXR0cmlidXRlIiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5iaXJ0LmNoYXJ0LmVuZ2luZS9tb2RlbC5hdHRyaWJ1dGUuaW1wbCIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuYmlydC5jaGFydC5lbmdpbmUvbW9kZWwuYXR0cmlidXRlLnV0aWwiIHZhbHVlPSJmYWxzZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLmJpcnQuY2hhcnQuZW5naW5lL21vZGVsLmNvbXBvbmVudCIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuYmlydC5jaGFydC5lbmdpbmUvbW9kZWwuY29tcG9uZW50LmltcGwiIHZhbHVlPSJmYWxzZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLmJpcnQuY2hhcnQuZW5naW5lL21vZGVsLmNvbXBvbmVudC51dGlsIiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5iaXJ0LmNoYXJ0LmVuZ2luZS9tb2RlbC5kYXRhIiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5iaXJ0LmNoYXJ0LmVuZ2luZS9tb2RlbC5kYXRhLmltcGwiIHZhbHVlPSJmYWxzZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLmJpcnQuY2hhcnQuZW5naW5lL21vZGVsLmRhdGEudXRpbCIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuYmlydC5jaGFydC5lbmdpbmUvbW9kZWwuaW1wbCIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuYmlydC5jaGFydC5lbmdpbmUvbW9kZWwubGF5b3V0IiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5iaXJ0LmNoYXJ0LmVuZ2luZS9tb2RlbC5sYXlvdXQuaW1wbCIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuYmlydC5jaGFydC5lbmdpbmUvbW9kZWwubGF5b3V0LnV0aWwiIHZhbHVlPSJmYWxzZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLmJpcnQuY2hhcnQuZW5naW5lL21vZGVsLnByZWZzIiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5iaXJ0LmNoYXJ0LmVuZ2luZS9tb2RlbC50eXBlIiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5iaXJ0LmNoYXJ0LmVuZ2luZS9tb2RlbC50eXBlLmltcGwiIHZhbHVlPSJmYWxzZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLmJpcnQuY2hhcnQuZW5naW5lL21vZGVsLnR5cGUudXRpbCIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuYmlydC5jaGFydC5lbmdpbmUvbW9kZWwudXRpbCIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuYmlydC5jaGFydC5lbmdpbmUvcGx1Z2luIiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5iaXJ0LmNoYXJ0LmVuZ2luZS9yZW5kZXIiIHZhbHVlPSJmYWxzZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLmJpcnQuY2hhcnQuZW5naW5lL3NjcmlwdCIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuYmlydC5jaGFydC5lbmdpbmUvc3R5bGUiIHZhbHVlPSJmYWxzZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLmJpcnQuY2hhcnQuZW5naW5lL3RyYWNlIiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5iaXJ0LmNoYXJ0LmVuZ2luZS91dGlsIiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5iaXJ0LmNvcmUvZGVidWciIHZhbHVlPSJmYWxzZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLmNvcmUuY29udGVudHR5cGUvZGVidWciIHZhbHVlPSJmYWxzZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLmNvcmUuZXhwcmVzc2lvbnMvdHJhY2VQcm9wZXJ0eVJlc29sdmluZyIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuY29yZS5qb2JzL2pvYnMiIHZhbHVlPSJmYWxzZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLmNvcmUuam9icy9qb2JzL2JlZ2luZW5kIiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5jb3JlLmpvYnMvam9icy9lcnJvcm9uZGVhZGxvY2siIHZhbHVlPSJmYWxzZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLmNvcmUuam9icy9qb2JzL2xvY2tzIiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5jb3JlLmpvYnMvam9icy9zaHV0ZG93biIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuY29yZS5qb2JzL2pvYnMvdGltaW5nIiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5jb3JlLnJlc291cmNlcy9idWlsZC9kZWx0YSIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMvYnVpbGQvZmFpbHVyZSIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMvYnVpbGQvaW50ZXJydXB0IiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5jb3JlLnJlc291cmNlcy9idWlsZC9pbnZva2luZyIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMvYnVpbGQvbmVlZGJ1aWxkIiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5jb3JlLnJlc291cmNlcy9idWlsZC9uZWVkYnVpbGRzdGFjayIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMvYnVpbGQvc3RhY2t0cmFjZSIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMvY29udGVudHR5cGUiIHZhbHVlPSJmYWxzZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLmNvcmUucmVzb3VyY2VzL2NvbnRlbnR0eXBlL2NhY2hlIiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5jb3JlLnJlc291cmNlcy9kZWJ1ZyIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMvaGlzdG9yeSIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMvbmF0dXJlcyIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMvcGVyZi9idWlsZGVycyIgdmFsdWU9IjEwMDAwIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMvcGVyZi9saXN0ZW5lcnMiIHZhbHVlPSI1MDAiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5jb3JlLnJlc291cmNlcy9wZXJmL3NhdmUucGFydGljaXBhbnRzIiB2YWx1ZT0iNTAwIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMvcGVyZi9zbmFwc2hvdCIgdmFsdWU9IjEwMDAiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5jb3JlLnJlc291cmNlcy9wcmVmZXJlbmNlcyIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMvcmVmcmVzaCIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMvcmVzdG9yZSIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMvcmVzdG9yZS9tYXJrZXJzIiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5jb3JlLnJlc291cmNlcy9yZXN0b3JlL21hc3RlcnRhYmxlIiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5jb3JlLnJlc291cmNlcy9yZXN0b3JlL21ldGFpbmZvIiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5jb3JlLnJlc291cmNlcy9yZXN0b3JlL3NuYXBzaG90cyIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMvcmVzdG9yZS9zeW5jaW5mbyIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMvcmVzdG9yZS90cmVlIiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5jb3JlLnJlc291cmNlcy9zYXZlIiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5jb3JlLnJlc291cmNlcy9zYXZlL21hcmtlcnMiIHZhbHVlPSJmYWxzZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLmNvcmUucmVzb3VyY2VzL3NhdmUvbWFzdGVydGFibGUiIHZhbHVlPSJmYWxzZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLmNvcmUucmVzb3VyY2VzL3NhdmUvbWV0YWluZm8iIHZhbHVlPSJmYWxzZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLmNvcmUucmVzb3VyY2VzL3NhdmUvc3luY2luZm8iIHZhbHVlPSJmYWxzZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLmNvcmUucmVzb3VyY2VzL3NhdmUvdHJlZSIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuY29yZS5yZXNvdXJjZXMvc3RyaW5ncyIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuY29yZS5ydW50aW1lL2NvbXBhdGliaWxpdHkvZGVidWciIHZhbHVlPSJmYWxzZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLmNvcmUucnVudGltZS9kZWJ1ZyIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuY29yZS5ydW50aW1lL2RlYnVnL2NvbnRleHQiIHZhbHVlPSJmYWxzZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLmNvcmUucnVudGltZS9wZXJmIiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5jb3JlLnJ1bnRpbWUvcGVyZi9zdWNjZXNzIiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5jb3JlLnJ1bnRpbWUvcHJlZmVyZW5jZXMvcGx1Z2luIiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5jb3JlLnJ1bnRpbWUvdXJsL2RlYnVnIiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5jb3JlLnJ1bnRpbWUvdXJsL2RlYnVnL2NhY2hlY29weSIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuY29yZS5ydW50aW1lL3VybC9kZWJ1Zy9jYWNoZWxvb2t1cCIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuY29yZS5ydW50aW1lL3VybC9kZWJ1Zy9jb25uZWN0IiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5kZWJ1Zy5jb3JlL2RlYnVnIiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5kZWJ1Zy5jb3JlL2RlYnVnL2NvbW1hbmRzIiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5kZWJ1Zy5jb3JlL2RlYnVnL2V2ZW50cyIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuZGVidWcudWkvZGVidWciIHZhbHVlPSJmYWxzZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLmRlYnVnLnVpL2RlYnVnL2NvbnRleHRsYXVuY2hpbmciIHZhbHVlPSJmYWxzZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLmRlYnVnLnVpL2RlYnVnL2xhdW5jaGhpc3RvcnkiIHZhbHVlPSJmYWxzZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLmRlYnVnLnVpL2RlYnVnL3ZpZXdlcnMvY29udGVudFByb3ZpZGVyIiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5kZWJ1Zy51aS9kZWJ1Zy92aWV3ZXJzL2RlbHRhcyIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuZGVidWcudWkvZGVidWcvdmlld2Vycy9tb2RlbCIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuZGVidWcudWkvZGVidWcvdmlld2Vycy9zdGF0ZVNhdmVSZXN0b3JlIiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5kZWJ1Zy51aS9kZWJ1Zy92aWV3ZXJzL3VwZGF0ZVNlcXVlbmNlIiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5kZWJ1Zy51aS9kZWJ1Zy92aWV3ZXJzL3ZpZXdlciIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuZXF1aW5veC5kcy9kZWJ1ZyIgdmFsdWU9InRydWUiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5lcXVpbm94LmRzL2luc3RhbnRpYXRlX2FsbCIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuZXF1aW5veC5kcy9wZXJmb3JtYW5jZSIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuZXF1aW5veC5kcy9wcmludF9vbl9jb25zb2xlIiB2YWx1ZT0idHJ1ZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLmVxdWlub3gucHJlZmVyZW5jZXMvZ2VuZXJhbCIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuZXF1aW5veC5wcmVmZXJlbmNlcy9nZXQiIHZhbHVlPSJmYWxzZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLmVxdWlub3gucHJlZmVyZW5jZXMvc2V0IiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5lcXVpbm94LnJlZ2lzdHJ5L2RlYnVnIiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5lcXVpbm94LnJlZ2lzdHJ5L2RlYnVnL2V2ZW50cyIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuZXF1aW5veC5zZWN1cml0eS51aS9kZWJ1ZyIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuZXF1aW5veC5zZWN1cml0eS51aS9kZWJ1Zy9zdG9yYWdlIiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5lcXVpbm94LnNlY3VyaXR5L2RlYnVnIiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5lcXVpbm94LnNlY3VyaXR5L2RlYnVnL2xvZ2luRnJhbWV3b3JrIiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5oZWxwLnVpL2RlYnVnIiB2YWx1ZT0idHJ1ZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLmhlbHAudWkvZGVidWcvZW1iZWRkZWRCcm93c2VyIiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5oZWxwLnVpL2RlYnVnL2VtYmVkZGVkQnJvd3Nlci9pbnByb2Nlc3MiIHZhbHVlPSJmYWxzZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLmhlbHAudWkvZGVidWcvaW5mb3BvcCIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuaGVscC53ZWJhcHAvZGVidWciIHZhbHVlPSJ0cnVlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuaGVscC53ZWJhcHAvZGVidWcvd29ya2luZ3NldHMiIHZhbHVlPSJmYWxzZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLmhlbHAvZGVidWciIHZhbHVlPSJ0cnVlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuaGVscC9kZWJ1Zy9jb250ZXh0IiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5oZWxwL2RlYnVnL3NlYXJjaCIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuaGVscC9kZWJ1Zy90b2MiIHZhbHVlPSJmYWxzZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLmpkdC5hcHQuY29yZS9kZWJ1ZyIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuamR0LmFwdC5jb3JlL2RlYnVnL2NvbXBpbGF0aW9uRW52IiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5qZHQuYXB0LmNvcmUvZGVidWcvZ2VuZXJhdGVkRmlsZU1hcHMiIHZhbHVlPSJmYWxzZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLmpkdC5hcHQuY29yZS9kZWJ1Zy9nZW5lcmF0ZWRGaWxlcyIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuamR0LmFwdC5wbHVnZ2FibGUuY29yZS9kZWJ1ZyIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuamR0LmNvcmUubWFuaXB1bGF0aW9uL2RlYnVnIiB2YWx1ZT0idHJ1ZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLmpkdC5jb3JlL2RlYnVnIiB2YWx1ZT0idHJ1ZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLmpkdC5jb3JlL2RlYnVnL2J1ZmZlcm1hbmFnZXIiIHZhbHVlPSJmYWxzZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLmpkdC5jb3JlL2RlYnVnL2J1aWxkZXIiIHZhbHVlPSJmYWxzZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLmpkdC5jb3JlL2RlYnVnL2J1aWxkZXIvc3RhdHMiIHZhbHVlPSJmYWxzZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLmpkdC5jb3JlL2RlYnVnL2NvbXBpbGVyIiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5qZHQuY29yZS9kZWJ1Zy9jb21wbGV0aW9uIiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5qZHQuY29yZS9kZWJ1Zy9jcHJlc29sdXRpb24iIHZhbHVlPSJmYWxzZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLmpkdC5jb3JlL2RlYnVnL2NwcmVzb2x1dGlvbi9hZHZhbmNlZCIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuamR0LmNvcmUvZGVidWcvY3ByZXNvbHV0aW9uL2ZhaWx1cmUiIHZhbHVlPSJmYWxzZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLmpkdC5jb3JlL2RlYnVnL2Zvcm1hdHRlciIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuamR0LmNvcmUvZGVidWcvaGllcmFyY2h5IiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5qZHQuY29yZS9kZWJ1Zy9pbmRleG1hbmFnZXIiIHZhbHVlPSJmYWxzZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLmpkdC5jb3JlL2RlYnVnL2phdmFkZWx0YSIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuamR0LmNvcmUvZGVidWcvamF2YWRlbHRhL3ZlcmJvc2UiIHZhbHVlPSJmYWxzZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLmpkdC5jb3JlL2RlYnVnL2phdmFtb2RlbCIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuamR0LmNvcmUvZGVidWcvamF2YW1vZGVsL2NhY2hlIiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5qZHQuY29yZS9kZWJ1Zy9wb3N0YWN0aW9uIiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5qZHQuY29yZS9kZWJ1Zy9yZXNvbHV0aW9uIiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5qZHQuY29yZS9kZWJ1Zy9zZWFyY2giIHZhbHVlPSJmYWxzZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLmpkdC5jb3JlL2RlYnVnL3NlbGVjdGlvbiIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuamR0LmNvcmUvZGVidWcvc291cmNlbWFwcGVyIiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5qZHQuY29yZS9kZWJ1Zy96aXBhY2Nlc3MiIHZhbHVlPSJmYWxzZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLmpkdC5jb3JlL3BlcmYvY29tcGxldGlvbiIgdmFsdWU9IjMwMCIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLmpkdC5jb3JlL3BlcmYvY29udGFpbmVyaW5pdGlhbGl6ZXIiIHZhbHVlPSI1MDAwIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuamR0LmNvcmUvcGVyZi9qYXZhZGVsdGFsaXN0ZW5lciIgdmFsdWU9IjUwMCIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLmpkdC5jb3JlL3BlcmYvcmVjb25jaWxlIiB2YWx1ZT0iMTAwMCIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLmpkdC5jb3JlL3BlcmYvc2VsZWN0aW9uIiB2YWx1ZT0iMzAwIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuamR0LmNvcmUvcGVyZi92YXJpYWJsZWluaXRpYWxpemVyIiB2YWx1ZT0iNTAwMCIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLmpkdC51aS9kZWJ1ZyIgdmFsdWU9InRydWUiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5qZHQudWkvZGVidWcvQVNUUHJvdmlkZXIiIHZhbHVlPSJmYWxzZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLmpkdC51aS9kZWJ1Zy9SZXN1bHRDb2xsZWN0b3IiIHZhbHVlPSJmYWxzZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLmpkdC51aS9kZWJ1Zy9UeXBlQ29uc3RyYWludHMiIHZhbHVlPSJmYWxzZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLmpkdC51aS9wZXJmL2NvbnRlbnRfYXNzaXN0L2V4dGVuc2lvbnMiIHZhbHVlPSIxMDAwIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuamR0LnVpL3BlcmYvY29udGVudF9hc3Npc3Rfc29ydGVycy9leHRlbnNpb25zIiB2YWx1ZT0iIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuamR0LnVpL3BlcmYvZXhwbG9yZXIvUmVmYWN0b3JBY3Rpb25Hcm91cCIgdmFsdWU9IjE1MCIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLmpkdC51aS9wZXJmL2V4cGxvcmVyL2NyZWF0ZVBhcnRDb250cm9sIiB2YWx1ZT0iMTMwMCIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLmpkdC51aS9wZXJmL2V4cGxvcmVyL21ha2VBY3Rpb25zIiB2YWx1ZT0iMTAwMCIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLmpkdC51aS9wZXJmL3NlYXJjaC9wYXJ0aWNpcGFudHMiIHZhbHVlPSIzMDAiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5qZW0udXRpbC9kZWJ1Zy9sb2dsZXZlbCIgdmFsdWU9IldBUk5JTkciLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5qZW0udXRpbC9kZWJ1Zy9sb2d0cmFjZSIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuamVtLnV0aWwvZGVidWcvbG9ndHJhY2VmaWxlIiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5qZmFjZS50ZXh0LnNvdXJjZS9kZWJ1Zy9SZXZpc2lvblJ1bGVyQ29sdW1uIiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5qZmFjZS50ZXh0L2RlYnVnL0Fic3RyYWN0SW5mb3JtYXRpb25Db250cm9sTWFuYWdlciIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuamZhY2UudGV4dC9kZWJ1Zy9Bbm5vdGF0aW9uUGFpbnRlciIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UuamZhY2UudGV4dC9kZWJ1Zy9Db250ZW50QXNzaXN0U3ViamVjdEFkYXB0ZXJzIiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5qZmFjZS50ZXh0L2RlYnVnL0Zhc3RQYXJ0aXRpb25lci9Qb3NpdGlvbkNhY2hlIiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5sdGsuY29yZS5yZWZhY3RvcmluZy9wZXJmL3BhcnRpY2lwYW50cy9jaGVja0NvbmRpdGlvbnMiIHZhbHVlPSIzMDAiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5sdGsuY29yZS5yZWZhY3RvcmluZy9wZXJmL3BhcnRpY2lwYW50cy9jcmVhdGVDaGFuZ2VzIiB2YWx1ZT0iMzAwIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UubXRqLmNvcmUuaG9va3MvZGVidWciIHZhbHVlPSJmYWxzZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLm9zZ2kvZGVidWciIHZhbHVlPSJmYWxzZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLm9zZ2kvZGVidWcvYnVuZGxlVGltZSIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2Uub3NnaS9kZWJ1Zy9ldmVudHMiIHZhbHVlPSJmYWxzZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLm9zZ2kvZGVidWcvZmlsdGVyIiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5vc2dpL2RlYnVnL2xvYWRlciIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2Uub3NnaS9kZWJ1Zy9tYW5pZmVzdCIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2Uub3NnaS9kZWJ1Zy9tZXNzYWdlQnVuZGxlcyIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2Uub3NnaS9kZWJ1Zy9wYWNrYWdlYWRtaW4iIHZhbHVlPSJmYWxzZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLm9zZ2kvZGVidWcvc2VjdXJpdHkiIHZhbHVlPSJmYWxzZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLm9zZ2kvZGVidWcvc2VydmljZXMiIHZhbHVlPSJmYWxzZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLm9zZ2kvZGVidWcvc3RhcnRsZXZlbCIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2Uub3NnaS9kZWZhdWx0cHJvZmlsZS9idWZmZXJzaXplIiB2YWx1ZT0iMjU2Ii8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2Uub3NnaS9kZWZhdWx0cHJvZmlsZS9sb2dmaWxlbmFtZSIgdmFsdWU9IiIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLm9zZ2kvZGVmYXVsdHByb2ZpbGUvbG9nc3luY2hyb25vdXNseSIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2Uub3NnaS9lY2xpcHNlYWRhcHRvci9jb252ZXJ0ZXIvZGVidWciIHZhbHVlPSJmYWxzZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLm9zZ2kvZWNsaXBzZWFkYXB0b3IvZGVidWciIHZhbHVlPSJmYWxzZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLm9zZ2kvZWNsaXBzZWFkYXB0b3IvZGVidWcvbG9jYXRpb24iIHZhbHVlPSJmYWxzZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLm9zZ2kvZWNsaXBzZWFkYXB0b3IvZGVidWcvcGxhdGZvcm1hZG1pbiIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2Uub3NnaS9lY2xpcHNlYWRhcHRvci9kZWJ1Zy9wbGF0Zm9ybWFkbWluL3Jlc29sdmVyIiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5vc2dpL21vbml0b3IvYWN0aXZhdGlvbiIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2Uub3NnaS9tb25pdG9yL2NsYXNzZXMiIHZhbHVlPSJmYWxzZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLm9zZ2kvbW9uaXRvci9yZXNvdXJjZXMiIHZhbHVlPSJmYWxzZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLm9zZ2kvcHJvZmlsZS9iZW5jaG1hcmsiIHZhbHVlPSJmYWxzZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLm9zZ2kvcHJvZmlsZS9kZWJ1ZyIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2Uub3NnaS9wcm9maWxlL2ltcGwiIHZhbHVlPSJvcmcuZWNsaXBzZS5vc2dpLmludGVybmFsLnByb2ZpbGUuRGVmYXVsdFByb2ZpbGVMb2dnZXIiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5vc2dpL3Byb2ZpbGUvc3RhcnR1cCIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2Uub3NnaS9yZXNvbHZlci9jeWNsZXMiIHZhbHVlPSJmYWxzZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLm9zZ2kvcmVzb2x2ZXIvZGVidWciIHZhbHVlPSJmYWxzZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLm9zZ2kvcmVzb2x2ZXIvZ2VuZXJpY3MiIHZhbHVlPSJmYWxzZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLm9zZ2kvcmVzb2x2ZXIvaW1wb3J0cyIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2Uub3NnaS9yZXNvbHZlci9yZXF1aXJlcyIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2Uub3NnaS9yZXNvbHZlci91c2VzIiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5vc2dpL3Jlc29sdmVyL3dpcmluZyIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2Uub3NnaS90cmFjZS9hY3RpdmF0aW9uIiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS5vc2dpL3RyYWNlL2NsYXNzTG9hZGluZyIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2Uub3NnaS90cmFjZS9maWxlbmFtZSIgdmFsdWU9InJ1bnRpbWUudHJhY2VzIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2Uub3NnaS90cmFjZS9maWx0ZXJzIiB2YWx1ZT0idHJhY2UucHJvcGVydGllcyIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLnBkZS5idWlsZC9kZWJ1ZyIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UucGRlLmNvcmUvY2FjaGUiIHZhbHVlPSJmYWxzZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLnBkZS5jb3JlL2NsYXNzcGF0aCIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UucGRlLmNvcmUvZGVidWciIHZhbHVlPSJ0cnVlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UucGRlLmNvcmUvdmFsaWRhdGlvbiIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UudGVhbS5jb3JlL2JhY2tncm91bmRldmVudHMiIHZhbHVlPSJmYWxzZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLnRlYW0uY29yZS9kZWJ1ZyIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UudGVhbS5jb3JlL3JlZnJlc2hqb2IiIHZhbHVlPSJmYWxzZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLnRlYW0uY29yZS9zdHJlYW1zIiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS50ZWFtLmNvcmUvdGhyZWFkaW5nIiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS50ZWFtLmN2cy5jb3JlL2N2c3Byb3RvY29sIiB2YWx1ZT0idHJ1ZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLnRlYW0uY3ZzLmNvcmUvZGVidWciIHZhbHVlPSJmYWxzZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLnRlYW0uY3ZzLmNvcmUvZGlydHljYWNoaW5nIiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS50ZWFtLmN2cy5jb3JlL21ldGFmaWxlcyIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UudGVhbS5jdnMuY29yZS9zeW5jY2hhbmdlZXZlbnRzIiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS50ZWFtLmN2cy5jb3JlL3RocmVhZGluZyIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UudG0udGVybWluYWwvZGVidWcvbG9nIiB2YWx1ZT0idHJ1ZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLnRtLnRlcm1pbmFsL2RlYnVnL2xvZy9WVDEwMEJhY2tlbmQiIHZhbHVlPSJmYWxzZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLnRtLnRlcm1pbmFsL2RlYnVnL2xvZy9idWZmZXIvc2l6ZSIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UudG0udGVybWluYWwvZGVidWcvbG9nL2NoYXIiIHZhbHVlPSJmYWxzZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLnRtLnRlcm1pbmFsL2RlYnVnL2xvZy9kaXJlY3RvcnkiIHZhbHVlPSIvdG1wLyIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLnRtLnRlcm1pbmFsL2RlYnVnL2xvZy9lcnJvciIgdmFsdWU9InRydWUiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS50bS50ZXJtaW5hbC9kZWJ1Zy9sb2cvaW5mbyIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UudG0udGVybWluYWwvZGVidWcvdXNlX29sZF9pbXBsZW1lbnRhdGlvbiIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UudWkuYnJvd3Nlci9kZWJ1ZyIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UudWkuaWRlL2RlYnVnIiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS51aS5pZGUvZGVidWcvZ2MiIHZhbHVlPSJmYWxzZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLnVpLmlkZS9kZWJ1Zy9pbnRlcm5hbGVycm9yL29wZW5EaWFsb2ciIHZhbHVlPSJmYWxzZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLnVpLmlkZS9kZWJ1Zy9tYXJrZXJzIiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS51aS5pZGUvZGVidWcvdW5kb21vbml0b3IiIHZhbHVlPSJmYWxzZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLnVpLmludHJvLnVuaXZlcnNhbC9kZWJ1ZyIgdmFsdWU9InRydWUiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS51aS5pbnRyby51bml2ZXJzYWwvdHJhY2UvbG9nSW5mbyIgdmFsdWU9InRydWUiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS51aS5pbnRyby51bml2ZXJzYWwvdHJhY2UvbG9nUGVyZm9ybWFuY2UiIHZhbHVlPSJmYWxzZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLnVpLmludHJvL2RlYnVnIiB2YWx1ZT0idHJ1ZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLnVpLmludHJvL2ZsYWdzL25vQnJvd3NlciIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UudWkuaW50cm8vdHJhY2UvbG9nSW5mbyIgdmFsdWU9InRydWUiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS51aS5pbnRyby90cmFjZS9sb2dQZXJmb3JtYW5jZSIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UudWkuaW50cm8vdHJhY2UvcHJpbnRIVE1MIiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS51aS53b3JrYmVuY2gvZGVidWciIHZhbHVlPSJmYWxzZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLnVpL2RlYnVnIiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS51aS9kZWJ1Zy9jb250cmlidXRpb25zIiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS51aS9kZWJ1Zy9kZWNsYXJlZEltYWdlcyIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UudWkvZGVidWcvam9iLnN0YWxlIiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS51aS9kZWJ1Zy9zaG93QWxsSm9icyIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UudWkvZGVidWcvc3d0ZGVidWciIHZhbHVlPSJmYWxzZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLnVpL2RlYnVnL3N3dGRlYnVnZ2xvYmFsIiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS51aS9kZWJ1Zy93b3JraW5nU2V0cyIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UudWkvZXhwZXJpbWVudGFsL21lbnVzIiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS51aS9saXN0ZW5lcnMvSVdvcmtiZW5jaFBhZ2UuSVBhcnRMaXN0ZW5lciIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UudWkvbGlzdGVuZXJzL0lXb3JrYmVuY2hQYWdlLklQYXJ0TGlzdGVuZXIyIiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS51aS9saXN0ZW5lcnMvSVdvcmtiZW5jaFBhZ2UuSVByb3BlcnR5Q2hhbmdlTGlzdGVuZXIiIHZhbHVlPSJmYWxzZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLnVpL2xpc3RlbmVycy9JV29ya2JlbmNoUGFydFJlZmVyZW5jZSIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UudWkvbGlzdGVuZXJzL0lXb3JrYmVuY2hXaW5kb3cuSVBhZ2VMaXN0ZW5lciIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UudWkvbGlzdGVuZXJzL0lXb3JrYmVuY2hXaW5kb3cuSVBhcnRMaXN0ZW5lciIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UudWkvbGlzdGVuZXJzL0lXb3JrYmVuY2hXaW5kb3cuSVBhcnRMaXN0ZW5lcjIiIHZhbHVlPSJmYWxzZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLnVpL2xpc3RlbmVycy9JV29ya2JlbmNoV2luZG93LklQZXJzcGVjdGl2ZUxpc3RlbmVyIiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS51aS9wZXJmL2NvbnRlbnRUeXBlcyIgdmFsdWU9IjIwMCIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLnVpL3BlcmYvcGFnZS5saXN0ZW5lcnMiIHZhbHVlPSIyMDAiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS51aS9wZXJmL3BhcnQuYWN0aXZhdGUiIHZhbHVlPSIyMDAiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS51aS9wZXJmL3BhcnQuY29udHJvbCIgdmFsdWU9IjgwMCIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLnVpL3BlcmYvcGFydC5jcmVhdGUiIHZhbHVlPSI4MDAiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS51aS9wZXJmL3BhcnQuaW5pdCIgdmFsdWU9IjgwMCIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLnVpL3BlcmYvcGFydC5pbnB1dCIgdmFsdWU9IjIwMCIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLnVpL3BlcmYvcGFydC5saXN0ZW5lcnMiIHZhbHVlPSIyMDAiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS51aS9wZXJmL3BlcnNwZWN0aXZlLmNyZWF0ZSIgdmFsdWU9IjgwMCIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLnVpL3BlcmYvcGVyc3BlY3RpdmUubGlzdGVuZXJzIiB2YWx1ZT0iMjAwIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UudWkvcGVyZi9wZXJzcGVjdGl2ZS5zd2l0Y2giIHZhbHVlPSI4MDAiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS51aS9wZXJmL3Nob3dIZWFwU3RhdHVzIiB2YWx1ZT0idHJ1ZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLnVpL3BlcmYvdWlqb2IiIHZhbHVlPSIyMDAiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS51aS9wZXJmL3dvcmtiZW5jaC5yZXN0b3JlIiB2YWx1ZT0iMzAwMDAiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS51aS9wZXJmL3dvcmtiZW5jaC5zdGFydCIgdmFsdWU9IjQ1MDAwIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UudWkvdHJhY2UvY29tbWFuZHMiIHZhbHVlPSJmYWxzZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLnVpL3RyYWNlL2NvbnRleHRzIiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS51aS90cmFjZS9jb250ZXh0cy5wZXJmb3JtYW5jZSIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UudWkvdHJhY2UvY29udGV4dHMudmVyYm9zZSIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UudWkvdHJhY2UvZ3JhcGhpY3MiIHZhbHVlPSJmYWxzZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLnVpL3RyYWNlL2hhbmRsZXJzIiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS51aS90cmFjZS9oYW5kbGVycy5wZXJmb3JtYW5jZSIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UudWkvdHJhY2UvaGFuZGxlcnMudmVyYm9zZSIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UudWkvdHJhY2UvaGFuZGxlcnMudmVyYm9zZS5jb21tYW5kSWQiIHZhbHVlPSIiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS51aS90cmFjZS9rZXlCaW5kaW5ncyIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UudWkvdHJhY2Uva2V5QmluZGluZ3MudmVyYm9zZSIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2UudWkvdHJhY2UvbXVsdGlwYWdlZWRpdG9yIiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS51aS90cmFjZS9vcGVyYXRpb25zIiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS51aS90cmFjZS9vcGVyYXRpb25zLnZlcmJvc2UiIHZhbHVlPSJmYWxzZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLnVpL3RyYWNlL3NvdXJjZXMiIHZhbHVlPSJmYWxzZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLnVwZGF0ZS5jb25maWd1cmF0b3IvZGVidWciIHZhbHVlPSJmYWxzZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLnVwZGF0ZS5jb3JlL2RlYnVnIiB2YWx1ZT0idHJ1ZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLnVwZGF0ZS5jb3JlL2RlYnVnL2NvbmZpZ3VyYXRpb24iIHZhbHVlPSJmYWxzZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLnVwZGF0ZS5jb3JlL2RlYnVnL2luc3RhbGwiIHZhbHVlPSJmYWxzZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLnVwZGF0ZS5jb3JlL2RlYnVnL2luc3RhbGxoYW5kbGVyIiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS51cGRhdGUuY29yZS9kZWJ1Zy9wYXJzaW5nIiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS51cGRhdGUuY29yZS9kZWJ1Zy9yZWNvbmNpbGVyIiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS51cGRhdGUuY29yZS9kZWJ1Zy90eXBlIiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS51cGRhdGUuY29yZS9kZWJ1Zy93YXJuaW5nIiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS51cGRhdGUuY29yZS9kZWJ1Zy93ZWIiIHZhbHVlPSJmYWxzZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLndzdC5jb21tb24uZW52aXJvbm1lbnQvZGVidWciIHZhbHVlPSJ0cnVlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2Uud3N0LmNvbW1vbi5lbnZpcm9ubWVudC90cmFjZS9jb21tYW5kIiB2YWx1ZT0idHJ1ZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLndzdC5jb21tb24uZW52aXJvbm1lbnQvdHJhY2UvZGF0YSIgdmFsdWU9InRydWUiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS53c3QuY29tbW9uLmVudmlyb25tZW50L3RyYWNlL2VtaXR0ZXIiIHZhbHVlPSJ0cnVlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2Uud3N0LmNvbW1vbi5lbnZpcm9ubWVudC90cmFjZS9lcnJvciIgdmFsdWU9InRydWUiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS53c3QuY29tbW9uLmVudmlyb25tZW50L3RyYWNlL2luZm8iIHZhbHVlPSJ0cnVlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2Uud3N0LmNvbW1vbi5lbnZpcm9ubWVudC90cmFjZS93YXJuaW5nIiB2YWx1ZT0idHJ1ZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLndzdC5jb21tb24uZW52aXJvbm1lbnQvdHJhY2Uvd3NfYW50IiB2YWx1ZT0idHJ1ZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLndzdC5jb21tb24uZW52aXJvbm1lbnQvdHJhY2Uvd3NfZHRfY21kX2VuZ2luZSIgdmFsdWU9InRydWUiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS53c3QuY29tbW9uLmVudmlyb25tZW50L3RyYWNlL3dzX2ZyYW1ld29yayIgdmFsdWU9InRydWUiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS53c3QuY29tbW9uLnByb2plY3QuZmFjZXQuY29yZS9hY3Rpb25Tb3J0aW5nIiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS53c3QuY29tbW9uLnByb2plY3QuZmFjZXQuY29yZS9hY3RpdmF0aW9uIiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS53c3QuY29tbW9uLnByb2plY3QuZmFjZXQuY29yZS9kZWxlZ2F0ZS9jYWxscyIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2Uud3N0LmR0ZC51aS9wcm9qZWN0aW9ucGVyZiIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2Uud3N0LnNzZS5jb3JlL2RlYnVnIiB2YWx1ZT0idHJ1ZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLndzdC5zc2UuY29yZS9kb20vYWRhcHRlci9ub3RpZmljYXRpb24vdGltZSIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2Uud3N0LnNzZS5jb3JlL2RvbS9hZGFwdGVyL25vdGlmaWNhdGlvbi90aW1lL2NyaXRlcmlhIiB2YWx1ZT0iMTAiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS53c3Quc3NlLmNvcmUvZmlsZWJ1ZmZlcnMvbGlmZWN5Y2xlIiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS53c3Quc3NlLmNvcmUvZmlsZWJ1ZmZlcnMvbW9kZWxtYW5hZ2VtZW50IiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS53c3Quc3NlLmNvcmUvZm9ybWF0IiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS53c3Quc3NlLmNvcmUvc3RydWN0dXJlZGRvY3VtZW50IiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS53c3Quc3NlLmNvcmUvc3RydWN0dXJlZG1vZGVsL2xpZmVjeWNsZSIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2Uud3N0LnNzZS5jb3JlL3N0cnVjdHVyZWRtb2RlbC9sb2NrcyIgdmFsdWU9InRydWUiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS53c3Quc3NlLmNvcmUvc3RydWN0dXJlZG1vZGVsL21vZGVsbWFuYWdlciIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2Uud3N0LnNzZS5jb3JlL3N0cnVjdHVyZWRtb2RlbC9zdGF0ZSIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2Uud3N0LnNzZS5jb3JlL3Rhc2tzIiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS53c3Quc3NlLmNvcmUvdGFza3MvZGV0ZWN0aW9uIiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS53c3Quc3NlLmNvcmUvdGFza3Mvam9iIiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS53c3Quc3NlLmNvcmUvdGFza3Mvb3ZlcmFsbHRpbWUiIHZhbHVlPSJmYWxzZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLndzdC5zc2UuY29yZS90YXNrcy9wcmVmZXJlbmNlcyIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2Uud3N0LnNzZS5jb3JlL3Rhc2tzL3JlZ2lzdHJ5IiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS53c3Quc3NlLmNvcmUvdGFza3MvdGltZSIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2Uud3N0LnNzZS51aS9hY3Rpb25jb250cmlidXRvci9kZWJ1Z3N0YXR1c2ZpZWxkcyIgdmFsdWU9InRydWUiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS53c3Quc3NlLnVpL2NvbnRlbnRPdXRsaW5lIiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS53c3Quc3NlLnVpL2RlYnVnIiB2YWx1ZT0idHJ1ZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLndzdC5zc2UudWkvZGVidWcvcmVjb25jaWxlclNwZWxsaW5nIiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS53c3Quc3NlLnVpL2RlYnVnL3JlY29uY2lsZXJTcGVsbGluZy9zaG93UHJvYmxlbXMiIHZhbHVlPSJmYWxzZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLndzdC5zc2UudWkvZGVidWcvcmVjb25jaWxlclZhbGlkYXRvcnMiIHZhbHVlPSJmYWxzZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLndzdC5zc2UudWkvZGVidWcvcmVjb25jaWxlcmpvYiIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2Uud3N0LnNzZS51aS9kZWJ1Zy90cmFjZWZpbHRlciIgdmFsdWU9IiIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLndzdC5zc2UudWkvZXh0ZW5kZWRjb25maWd1cmF0aW9uYnVpbGRlciIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2Uud3N0LnNzZS51aS9leHRlbmRlZGNvbmZpZ3VyYXRpb25idWlsZGVyL3RpbWUiIHZhbHVlPSJmYWxzZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLndzdC5zc2UudWkvZXh0ZW5kZWRlZGl0b3JhY3Rpb25idWlsZGVyIiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS53c3Quc3NlLnVpL2V4dGVuZGVkZWRpdG9yYWN0aW9uYnVpbGRlci9jb250cmlidXRldGltZSIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2Uud3N0LnNzZS51aS9leHRlbmRlZGVkaXRvcmFjdGlvbmJ1aWxkZXIvZGVidWdtZW51IiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS53c3Quc3NlLnVpL2V4dGVuZGVkZWRpdG9yYWN0aW9uYnVpbGRlci9kZWJ1Z3BvcHVwIiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS53c3Quc3NlLnVpL2V4dGVuZGVkZWRpdG9yYWN0aW9uYnVpbGRlci9kZWJ1Z3Rvb2xiYXIiIHZhbHVlPSJmYWxzZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLndzdC5zc2UudWkvZXh0ZW5kZWRlZGl0b3JhY3Rpb25idWlsZGVyL3JlYWR0aW1lIiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS53c3Quc3NlLnVpL2ZpbGVtb2RlbHByb3ZpZGVyL2xpZmVjeWNsZWxpc3RlbmVyIiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS53c3Quc3NlLnVpL2ZpbGVtb2RlbHByb3ZpZGVyL21vZGVsc3RhdGVsaXN0ZW5lciIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2Uud3N0LnNzZS51aS9maWxlbW9kZWxwcm92aWRlci9vcGVyYXRpb25zIiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS53c3Quc3NlLnVpL2dvdG9OZXh0QW5ub3RhdGlvbiIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2Uud3N0LnNzZS51aS9wcmVmZXJlbmNlcy1wcm9wZXJ0aWVzIiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS53c3Quc3NlLnVpL3Byb3BlcnR5Q2hhbmdlVXBkYXRlQWN0aW9uQ29udHJpYnV0aW9uSXRlbSIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2Uud3N0LnNzZS51aS9wcm9wZXJ0eVNoZWV0IiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS53c3Quc3NlLnVpL3N0b3JhZ2Vtb2RlbHByb3ZpZGVyL2VsZW1lbnRzdGF0ZWxpc3RlbmVyIiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS53c3Quc3NlLnVpL3N0b3JhZ2Vtb2RlbHByb3ZpZGVyL29wZXJhdGlvbnMiIHZhbHVlPSJmYWxzZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLndzdC5zc2UudWkvc3RydWN0dXJlZFByZXNlbnRhdGlvblJlY29uY2lsZXIiIHZhbHVlPSJmYWxzZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLndzdC5zc2UudWkvc3RydWN0dXJlZFByZXNlbnRhdGlvblJlY29uY2lsZXIvdGltZSIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2Uud3N0LnNzZS51aS90cmFuc2ZlcmJ1aWxkZXIvdGltZSIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2Uud3N0LnZhbGlkYXRpb24vZGVidWciIHZhbHVlPSJ0cnVlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2Uud3N0LnZhbGlkYXRpb24vZXh0cmFWYWxEZXRhaWwiIHZhbHVlPSIiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS53c3QudmFsaWRhdGlvbi90aW1pbmdzIiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS53c3QudmFsaWRhdGlvbi90aW1pbmdzL3RyYWNlZmlsZSIgdmFsdWU9IiIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLndzdC52YWxpZGF0aW9uL3RpbWluZ3MvdXNlRG91YmxlcyIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2Uud3N0LnZhbGlkYXRpb24vdjEiIHZhbHVlPSJmYWxzZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLndzdC54bWwuY29yZS9kZWJ1ZyIgdmFsdWU9InRydWUiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS53c3QueG1sLmNvcmUvZGVidWcvY21kb2N1bWVudGNhY2hlIiB2YWx1ZT0iZmFsc2UiLz4NCis8bWFwRW50cnkga2V5PSJvcmcuZWNsaXBzZS53c3QueG1sLmNvcmUvZGVidWcvY21kb2N1bWVudG1hbmFnZXIiIHZhbHVlPSJmYWxzZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLndzdC54bWwuY29yZS9kZWJ1Zy90cmFjZWZpbHRlciIgdmFsdWU9IiIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLndzdC54bWwudWkvcHJvamVjdGlvbnBlcmYiIHZhbHVlPSJmYWxzZSIvPg0KKzxtYXBFbnRyeSBrZXk9Im9yZy5lY2xpcHNlLnd0cC5jb21tb24vZGVidWcvbG9nbGV2ZWwiIHZhbHVlPSJXQVJOSU5HIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2Uud3RwLmNvbW1vbi9kZWJ1Zy9sb2d0cmFjZSIgdmFsdWU9ImZhbHNlIi8+DQorPG1hcEVudHJ5IGtleT0ib3JnLmVjbGlwc2Uud3RwLmNvbW1vbi9kZWJ1Zy9sb2d0cmFjZWZpbGUiIHZhbHVlPSJmYWxzZSIvPg0KKzwvbWFwQXR0cmlidXRlPg0KKzxib29sZWFuQXR0cmlidXRlIGtleT0idXNlQ3VzdG9tRmVhdHVyZXMiIHZhbHVlPSJmYWxzZSIvPg0KKzxib29sZWFuQXR0cmlidXRlIGtleT0idXNlRGVmYXVsdENvbmZpZyIgdmFsdWU9InRydWUiLz4NCis8Ym9vbGVhbkF0dHJpYnV0ZSBrZXk9InVzZURlZmF1bHRDb25maWdBcmVhIiB2YWx1ZT0iZmFsc2UiLz4NCis8Ym9vbGVhbkF0dHJpYnV0ZSBrZXk9InVzZVByb2R1Y3QiIHZhbHVlPSJmYWxzZSIvPg0KKzwvbGF1bmNoQ29uZmlndXJhdGlvbj4NCmRpZmYgLS1naXQgYS9idW5kbGVzL29yZy5lY2xpcHNlLmVxdWlub3guZHMudGVzdHMvYnVuZGxlc19zcmMvdGIyNS9vcmcvZWNsaXBzZS9lcXVpbm94L2RzL3Rlc3RzL3RiMjUvU2VydmljZVByb3BlcnRpZXNDb21wLmphdmEgYi9idW5kbGVzL29yZy5lY2xpcHNlLmVxdWlub3guZHMudGVzdHMvYnVuZGxlc19zcmMvdGIyNS9vcmcvZWNsaXBzZS9lcXVpbm94L2RzL3Rlc3RzL3RiMjUvU2VydmljZVByb3BlcnRpZXNDb21wLmphdmEKaW5kZXggMjM2ZGQ1YS4uZWNlZjRlYiAxMDA2NDQKLS0tIGEvYnVuZGxlcy9vcmcuZWNsaXBzZS5lcXVpbm94LmRzLnRlc3RzL2J1bmRsZXNfc3JjL3RiMjUvb3JnL2VjbGlwc2UvZXF1aW5veC9kcy90ZXN0cy90YjI1L1NlcnZpY2VQcm9wZXJ0aWVzQ29tcC5qYXZhCisrKyBiL2J1bmRsZXMvb3JnLmVjbGlwc2UuZXF1aW5veC5kcy50ZXN0cy9idW5kbGVzX3NyYy90YjI1L29yZy9lY2xpcHNlL2VxdWlub3gvZHMvdGVzdHMvdGIyNS9TZXJ2aWNlUHJvcGVydGllc0NvbXAuamF2YQpAQCAtMzIsNyArMzIsMTAgQEAKIAogICB9CiAKLSAgcHVibGljIHZvaWQgYmluZFJlZihQcm9wZXJ0aWVzUHJvdmlkZXIgc2VydmljZSwgTWFwIHByb3BlcnRpZXMpIHsKKyAgcHVibGljIHZvaWQgYmluZER5bmFtaWNSZWYoUHJvcGVydGllc1Byb3ZpZGVyIHNlcnZpY2UsIE1hcCBwcm9wZXJ0aWVzKSB7CisgIH0KKworICBwdWJsaWMgdm9pZCBiaW5kU3RhdGljUmVmKFByb3BlcnRpZXNQcm92aWRlciBzZXJ2aWNlLCBNYXAgcHJvcGVydGllcykgewogICB9CiAKICAgcHVibGljIHN5bmNocm9uaXplZCB2b2lkIHNlcnZpY2VVcGRhdGVkU3RhdGljKFByb3BlcnRpZXNQcm92aWRlciBzZXJ2aWNlLCBNYXAgcHJvcGVydGllcykgewpkaWZmIC0tZ2l0IGEvYnVuZGxlcy9vcmcuZWNsaXBzZS5lcXVpbm94LmRzLnRlc3RzL2J1bmRsZXNfc3JjL3RiMjUvb3JnL2VjbGlwc2UvZXF1aW5veC9kcy90ZXN0cy90YjI1L2NvbXBvbmVudHMueG1sIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5lcXVpbm94LmRzLnRlc3RzL2J1bmRsZXNfc3JjL3RiMjUvb3JnL2VjbGlwc2UvZXF1aW5veC9kcy90ZXN0cy90YjI1L2NvbXBvbmVudHMueG1sCmluZGV4IDMyYTMwOGIuLjliMDYwZTcgMTAwNjQ0Ci0tLSBhL2J1bmRsZXMvb3JnLmVjbGlwc2UuZXF1aW5veC5kcy50ZXN0cy9idW5kbGVzX3NyYy90YjI1L29yZy9lY2xpcHNlL2VxdWlub3gvZHMvdGVzdHMvdGIyNS9jb21wb25lbnRzLnhtbAorKysgYi9idW5kbGVzL29yZy5lY2xpcHNlLmVxdWlub3guZHMudGVzdHMvYnVuZGxlc19zcmMvdGIyNS9vcmcvZWNsaXBzZS9lcXVpbm94L2RzL3Rlc3RzL3RiMjUvY29tcG9uZW50cy54bWwKQEAgLTExLDEzICsxMSwxNSBAQAogCQk8cmVmZXJlbmNlCiAJCQlpbnRlcmZhY2U9Im9yZy5lY2xpcHNlLmVxdWlub3guZHMudGVzdHMudGJjLlByb3BlcnRpZXNQcm92aWRlciIKIAkJCXRhcmdldD0iKHNlcnZpY2UucHJvdmlkZXI9c2VydmljZS5wcm9wZXJ0aWVzLnVwZGF0ZS50ZXN0KSIKLQkJCWJpbmQ9ImJpbmRSZWYiCisJCQluYW1lPSJiaW5kU3RhdGljUmVmIgorCQkJYmluZD0iYmluZFN0YXRpY1JlZiIKIAkJCXVwZGF0ZWQ9InNlcnZpY2VVcGRhdGVkU3RhdGljIi8+CiAJCTxyZWZlcmVuY2UKIAkJCWludGVyZmFjZT0ib3JnLmVjbGlwc2UuZXF1aW5veC5kcy50ZXN0cy50YmMuUHJvcGVydGllc1Byb3ZpZGVyIgogCQkJdGFyZ2V0PSIoc2VydmljZS5wcm92aWRlcj1zZXJ2aWNlLnByb3BlcnRpZXMudXBkYXRlLnRlc3QpIgogCQkJcG9saWN5PSJkeW5hbWljIgotCQkJYmluZD0iYmluZFJlZiIKKwkJCW5hbWU9ImJpbmREeW5hbWljUmVmIgorCQkJYmluZD0iYmluZER5bmFtaWNSZWYiCiAJCQl1cGRhdGVkPSJzZXJ2aWNlVXBkYXRlZER5bmFtaWMiLz4KIAkJPHNlcnZpY2U+CiAJCQk8cHJvdmlkZSBpbnRlcmZhY2U9Im9yZy5lY2xpcHNlLmVxdWlub3guZHMudGVzdHMudGJjLlByb3BlcnRpZXNQcm92aWRlciIvPgpAQCAtMzUsMjQgKzM3LDI4IEBACiAJCQlpbnRlcmZhY2U9Im9yZy5lY2xpcHNlLmVxdWlub3guZHMudGVzdHMudGJjLlByb3BlcnRpZXNQcm92aWRlciIKIAkJCXRhcmdldD0iKHNlcnZpY2UucHJvdmlkZXI9cmVsdWN0YW50LnBvbGljeS5vcHRpb24udGVzdCkiCiAJCQljYXJkaW5hbGl0eT0iMC4uMSIKKwkJCW5hbWU9ImJpbmQwMSIKIAkJCWJpbmQ9ImJpbmQwMSIKIAkJCXBvbGljeS1vcHRpb249InJlbHVjdGFudCIvPgogCQk8cmVmZXJlbmNlCiAJCQlpbnRlcmZhY2U9Im9yZy5lY2xpcHNlLmVxdWlub3guZHMudGVzdHMudGJjLlByb3BlcnRpZXNQcm92aWRlciIKIAkJCXRhcmdldD0iKHNlcnZpY2UucHJvdmlkZXI9cmVsdWN0YW50LnBvbGljeS5vcHRpb24udGVzdCkiCiAJCQljYXJkaW5hbGl0eT0iMS4uMSIKKwkJCW5hbWU9ImJpbmQxMSIKIAkJCWJpbmQ9ImJpbmQxMSIKIAkJCXBvbGljeS1vcHRpb249InJlbHVjdGFudCIvPgogCQk8cmVmZXJlbmNlCiAJCQlpbnRlcmZhY2U9Im9yZy5lY2xpcHNlLmVxdWlub3guZHMudGVzdHMudGJjLlByb3BlcnRpZXNQcm92aWRlciIKIAkJCXRhcmdldD0iKHNlcnZpY2UucHJvdmlkZXI9cmVsdWN0YW50LnBvbGljeS5vcHRpb24udGVzdCkiCiAJCQljYXJkaW5hbGl0eT0iMC4ubiIKKwkJCW5hbWU9ImJpbmQwbiIKIAkJCWJpbmQ9ImJpbmQwbiIKIAkJCXBvbGljeS1vcHRpb249InJlbHVjdGFudCIvPgogCQk8cmVmZXJlbmNlCiAJCQlpbnRlcmZhY2U9Im9yZy5lY2xpcHNlLmVxdWlub3guZHMudGVzdHMudGJjLlByb3BlcnRpZXNQcm92aWRlciIKIAkJCXRhcmdldD0iKHNlcnZpY2UucHJvdmlkZXI9cmVsdWN0YW50LnBvbGljeS5vcHRpb24udGVzdCkiCiAJCQljYXJkaW5hbGl0eT0iMS4ubiIKKwkJCW5hbWU9ImJpbmQxbiIKIAkJCWJpbmQ9ImJpbmQxbiIKIAkJCXBvbGljeS1vcHRpb249InJlbHVjdGFudCIvPgogCQk8c2VydmljZT4KQEAgLTcxLDYgKzc3LDcgQEAKIAkJCWludGVyZmFjZT0ib3JnLmVjbGlwc2UuZXF1aW5veC5kcy50ZXN0cy50YmMuUHJvcGVydGllc1Byb3ZpZGVyIgogCQkJdGFyZ2V0PSIoc2VydmljZS5wcm92aWRlcj1yZWx1Y3RhbnQucG9saWN5Lm9wdGlvbi50ZXN0KSIKIAkJCWNhcmRpbmFsaXR5PSIwLi4xIgorCQkJbmFtZT0iYmluZDAxIgogCQkJYmluZD0iYmluZDAxIgogCQkJcG9saWN5PSJkeW5hbWljIgogCQkJcG9saWN5LW9wdGlvbj0icmVsdWN0YW50Ii8+CkBAIC03OCw2ICs4NSw3IEBACiAJCQlpbnRlcmZhY2U9Im9yZy5lY2xpcHNlLmVxdWlub3guZHMudGVzdHMudGJjLlByb3BlcnRpZXNQcm92aWRlciIKIAkJCXRhcmdldD0iKHNlcnZpY2UucHJvdmlkZXI9cmVsdWN0YW50LnBvbGljeS5vcHRpb24udGVzdCkiCiAJCQljYXJkaW5hbGl0eT0iMS4uMSIKKwkJCW5hbWU9ImJpbmQxMSIKIAkJCWJpbmQ9ImJpbmQxMSIKIAkJCXBvbGljeT0iZHluYW1pYyIKIAkJCXBvbGljeS1vcHRpb249InJlbHVjdGFudCIvPgpAQCAtODUsNiArOTMsNyBAQAogCQkJaW50ZXJmYWNlPSJvcmcuZWNsaXBzZS5lcXVpbm94LmRzLnRlc3RzLnRiYy5Qcm9wZXJ0aWVzUHJvdmlkZXIiCiAJCQl0YXJnZXQ9IihzZXJ2aWNlLnByb3ZpZGVyPXJlbHVjdGFudC5wb2xpY3kub3B0aW9uLnRlc3QpIgogCQkJY2FyZGluYWxpdHk9IjAuLm4iCisJCQluYW1lPSJiaW5kMG4iCiAJCQliaW5kPSJiaW5kMG4iCiAJCQlwb2xpY3k9ImR5bmFtaWMiCiAJCQlwb2xpY3ktb3B0aW9uPSJyZWx1Y3RhbnQiLz4KQEAgLTkyLDYgKzEwMSw3IEBACiAJCQlpbnRlcmZhY2U9Im9yZy5lY2xpcHNlLmVxdWlub3guZHMudGVzdHMudGJjLlByb3BlcnRpZXNQcm92aWRlciIKIAkJCXRhcmdldD0iKHNlcnZpY2UucHJvdmlkZXI9cmVsdWN0YW50LnBvbGljeS5vcHRpb24udGVzdCkiCiAJCQljYXJkaW5hbGl0eT0iMS4ubiIKKwkJCW5hbWU9ImJpbmQxbiIKIAkJCWJpbmQ9ImJpbmQxbiIKIAkJCXBvbGljeT0iZHluYW1pYyIKIAkJCXBvbGljeS1vcHRpb249InJlbHVjdGFudCIvPgpAQCAtMTExLDI0ICsxMjEsMjggQEAKIAkJCWludGVyZmFjZT0ib3JnLmVjbGlwc2UuZXF1aW5veC5kcy50ZXN0cy50YmMuUHJvcGVydGllc1Byb3ZpZGVyIgogCQkJdGFyZ2V0PSIoc2VydmljZS5wcm92aWRlcj1ncmVlZHkucG9saWN5Lm9wdGlvbi50ZXN0KSIKIAkJCWNhcmRpbmFsaXR5PSIwLi4xIgorCQkJbmFtZT0iYmluZDAxIgogCQkJYmluZD0iYmluZDAxIgogCQkJcG9saWN5LW9wdGlvbj0iZ3JlZWR5Ii8+CiAJCTxyZWZlcmVuY2UKIAkJCWludGVyZmFjZT0ib3JnLmVjbGlwc2UuZXF1aW5veC5kcy50ZXN0cy50YmMuUHJvcGVydGllc1Byb3ZpZGVyIgogCQkJdGFyZ2V0PSIoc2VydmljZS5wcm92aWRlcj1ncmVlZHkucG9saWN5Lm9wdGlvbi50ZXN0KSIKIAkJCWNhcmRpbmFsaXR5PSIxLi4xIgorCQkJbmFtZT0iYmluZDExIgogCQkJYmluZD0iYmluZDExIgogCQkJcG9saWN5LW9wdGlvbj0iZ3JlZWR5Ii8+CiAJCTxyZWZlcmVuY2UKIAkJCWludGVyZmFjZT0ib3JnLmVjbGlwc2UuZXF1aW5veC5kcy50ZXN0cy50YmMuUHJvcGVydGllc1Byb3ZpZGVyIgogCQkJdGFyZ2V0PSIoc2VydmljZS5wcm92aWRlcj1ncmVlZHkucG9saWN5Lm9wdGlvbi50ZXN0KSIKIAkJCWNhcmRpbmFsaXR5PSIwLi5uIgorCQkJbmFtZT0iYmluZDBuIgogCQkJYmluZD0iYmluZDBuIgogCQkJcG9saWN5LW9wdGlvbj0iZ3JlZWR5Ii8+CiAJCTxyZWZlcmVuY2UKIAkJCWludGVyZmFjZT0ib3JnLmVjbGlwc2UuZXF1aW5veC5kcy50ZXN0cy50YmMuUHJvcGVydGllc1Byb3ZpZGVyIgogCQkJdGFyZ2V0PSIoc2VydmljZS5wcm92aWRlcj1ncmVlZHkucG9saWN5Lm9wdGlvbi50ZXN0KSIKIAkJCWNhcmRpbmFsaXR5PSIxLi5uIgorCQkJbmFtZT0iYmluZDFuIgogCQkJYmluZD0iYmluZDFuIgogCQkJcG9saWN5LW9wdGlvbj0iZ3JlZWR5Ii8+CiAJCTxzZXJ2aWNlPgpAQCAtMTQ3LDYgKzE2MSw3IEBACiAJCQlpbnRlcmZhY2U9Im9yZy5lY2xpcHNlLmVxdWlub3guZHMudGVzdHMudGJjLlByb3BlcnRpZXNQcm92aWRlciIKIAkJCXRhcmdldD0iKHNlcnZpY2UucHJvdmlkZXI9Z3JlZWR5LnBvbGljeS5vcHRpb24udGVzdCkiCiAJCQljYXJkaW5hbGl0eT0iMC4uMSIKKwkJCW5hbWU9ImJpbmQwMSIKIAkJCWJpbmQ9ImJpbmQwMSIKIAkJCXBvbGljeT0iZHluYW1pYyIKIAkJCXBvbGljeS1vcHRpb249ImdyZWVkeSIvPgpAQCAtMTU0LDYgKzE2OSw3IEBACiAJCQlpbnRlcmZhY2U9Im9yZy5lY2xpcHNlLmVxdWlub3guZHMudGVzdHMudGJjLlByb3BlcnRpZXNQcm92aWRlciIKIAkJCXRhcmdldD0iKHNlcnZpY2UucHJvdmlkZXI9Z3JlZWR5LnBvbGljeS5vcHRpb24udGVzdCkiCiAJCQljYXJkaW5hbGl0eT0iMS4uMSIKKwkJCW5hbWU9ImJpbmQxMSIKIAkJCWJpbmQ9ImJpbmQxMSIKIAkJCXBvbGljeT0iZHluYW1pYyIKIAkJCXBvbGljeS1vcHRpb249ImdyZWVkeSIvPgpAQCAtMTYxLDYgKzE3Nyw3IEBACiAJCQlpbnRlcmZhY2U9Im9yZy5lY2xpcHNlLmVxdWlub3guZHMudGVzdHMudGJjLlByb3BlcnRpZXNQcm92aWRlciIKIAkJCXRhcmdldD0iKHNlcnZpY2UucHJvdmlkZXI9Z3JlZWR5LnBvbGljeS5vcHRpb24udGVzdCkiCiAJCQljYXJkaW5hbGl0eT0iMC4ubiIKKwkJCW5hbWU9ImJpbmQwbiIKIAkJCWJpbmQ9ImJpbmQwbiIKIAkJCXBvbGljeT0iZHluYW1pYyIKIAkJCXBvbGljeS1vcHRpb249ImdyZWVkeSIvPgpAQCAtMTY4LDYgKzE4NSw3IEBACiAJCQlpbnRlcmZhY2U9Im9yZy5lY2xpcHNlLmVxdWlub3guZHMudGVzdHMudGJjLlByb3BlcnRpZXNQcm92aWRlciIKIAkJCXRhcmdldD0iKHNlcnZpY2UucHJvdmlkZXI9Z3JlZWR5LnBvbGljeS5vcHRpb24udGVzdCkiCiAJCQljYXJkaW5hbGl0eT0iMS4ubiIKKwkJCW5hbWU9ImJpbmQxbiIKIAkJCWJpbmQ9ImJpbmQxbiIKIAkJCXBvbGljeT0iZHluYW1pYyIKIAkJCXBvbGljeS1vcHRpb249ImdyZWVkeSIvPgpkaWZmIC0tZ2l0IGEvYnVuZGxlcy9vcmcuZWNsaXBzZS5lcXVpbm94LmRzLnRlc3RzL2J1bmRsZXNfc3JjL3RiNy9vcmcvZWNsaXBzZS9lcXVpbm94L2RzL3Rlc3RzL3RiNy9TdGF0aWNDaXJjdWl0MS5qYXZhIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5lcXVpbm94LmRzLnRlc3RzL2J1bmRsZXNfc3JjL3RiNy9vcmcvZWNsaXBzZS9lcXVpbm94L2RzL3Rlc3RzL3RiNy9TdGF0aWNDaXJjdWl0MS5qYXZhCmluZGV4IGZiMTFhYmUuLmE5YjA0ODMgMTAwNjQ0Ci0tLSBhL2J1bmRsZXMvb3JnLmVjbGlwc2UuZXF1aW5veC5kcy50ZXN0cy9idW5kbGVzX3NyYy90Yjcvb3JnL2VjbGlwc2UvZXF1aW5veC9kcy90ZXN0cy90YjcvU3RhdGljQ2lyY3VpdDEuamF2YQorKysgYi9idW5kbGVzL29yZy5lY2xpcHNlLmVxdWlub3guZHMudGVzdHMvYnVuZGxlc19zcmMvdGI3L29yZy9lY2xpcHNlL2VxdWlub3gvZHMvdGVzdHMvdGI3L1N0YXRpY0NpcmN1aXQxLmphdmEKQEAgLTEyLDUgKzEyLDE0IEBACiBwYWNrYWdlIG9yZy5lY2xpcHNlLmVxdWlub3guZHMudGVzdHMudGI3OwogCiBwdWJsaWMgY2xhc3MgU3RhdGljQ2lyY3VpdDEgeworCXByaXZhdGUgU3RhdGljQ2lyY3VpdDIgbWF0ZSA9IG51bGw7CisJICBwdWJsaWMgdm9pZCBiaW5kKFN0YXRpY0NpcmN1aXQyIG1hdGUpIHsKKwkJICAgIHRoaXMubWF0ZSA9IG1hdGU7CisJCSAgfQogCisJCSAgcHVibGljIHZvaWQgdW5iaW5kKFN0YXRpY0NpcmN1aXQyIG1hdGUpIHsKKwkJICAgIGlmICh0aGlzLm1hdGUgPT0gbWF0ZSkgeworCQkgICAgICB0aGlzLm1hdGUgPSBudWxsOworCQkgICAgfQorCQkgIH0KIH0KZGlmZiAtLWdpdCBhL2J1bmRsZXMvb3JnLmVjbGlwc2UuZXF1aW5veC5kcy50ZXN0cy9idW5kbGVzX3NyYy90Yjcvb3JnL2VjbGlwc2UvZXF1aW5veC9kcy90ZXN0cy90YjcvY29tcG9uZW50cy54bWwgYi9idW5kbGVzL29yZy5lY2xpcHNlLmVxdWlub3guZHMudGVzdHMvYnVuZGxlc19zcmMvdGI3L29yZy9lY2xpcHNlL2VxdWlub3gvZHMvdGVzdHMvdGI3L2NvbXBvbmVudHMueG1sCmluZGV4IGRjMjg5ZTcuLmU2MmFhYmIgMTAwNjQ0Ci0tLSBhL2J1bmRsZXMvb3JnLmVjbGlwc2UuZXF1aW5veC5kcy50ZXN0cy9idW5kbGVzX3NyYy90Yjcvb3JnL2VjbGlwc2UvZXF1aW5veC9kcy90ZXN0cy90YjcvY29tcG9uZW50cy54bWwKKysrIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5lcXVpbm94LmRzLnRlc3RzL2J1bmRsZXNfc3JjL3RiNy9vcmcvZWNsaXBzZS9lcXVpbm94L2RzL3Rlc3RzL3RiNy9jb21wb25lbnRzLnhtbApAQCAtNjYsNiArNjYsOCBAQAogCTxyZWZlcmVuY2UKIAkJbmFtZT0icmVmZXJlbmNlZENvbXBvbmVudCIKIAkJaW50ZXJmYWNlPSJvcmcuZWNsaXBzZS5lcXVpbm94LmRzLnRlc3RzLnRiNy5TdGF0aWNDaXJjdWl0MiIKKwkJYmluZD0iYmluZCIKKwkJdW5iaW5kPSJ1bmJpbmQiCiAJLz4KIAk8L3Njcjpjb21wb25lbnQ+CQkKIAkKZGlmZiAtLWdpdCBhL2J1bmRsZXMvb3JnLmVjbGlwc2UuZXF1aW5veC5kcy50ZXN0cy9zcmMvb3JnL2VjbGlwc2UvZXF1aW5veC9kcy90ZXN0cy90YmMvRFNUZXN0LmphdmEgYi9idW5kbGVzL29yZy5lY2xpcHNlLmVxdWlub3guZHMudGVzdHMvc3JjL29yZy9lY2xpcHNlL2VxdWlub3gvZHMvdGVzdHMvdGJjL0RTVGVzdC5qYXZhCmluZGV4IDAzNTBjMDEuLmIwOGI0NWEgMTAwNjQ0Ci0tLSBhL2J1bmRsZXMvb3JnLmVjbGlwc2UuZXF1aW5veC5kcy50ZXN0cy9zcmMvb3JnL2VjbGlwc2UvZXF1aW5veC9kcy90ZXN0cy90YmMvRFNUZXN0LmphdmEKKysrIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5lcXVpbm94LmRzLnRlc3RzL3NyYy9vcmcvZWNsaXBzZS9lcXVpbm94L2RzL3Rlc3RzL3RiYy9EU1Rlc3QuamF2YQpAQCAtNDc3LDIzICs0NzcsMTUgQEAKICAgICBhc3NlcnROb3ROdWxsKCJUaGUgV29ya2VyIHNob3VsZCBiZSBhdmFpbGFibGUgYmVmb3JlIHdlIGRpc2FibGUgaXQiLCB0cmFja2VyU0MuZ2V0U2VydmljZVJlZmVyZW5jZXMoKSk7CiAgICAgYXNzZXJ0VHJ1ZSgiVGhlIFdvcmtlciBzaG91bGQgYmUgYXZhaWxhYmxlIGJlZm9yZSB3ZSBkaXNhYmxlIGl0IiwgdHJhY2tlclNDLmdldFNlcnZpY2VSZWZlcmVuY2VzKCkubGVuZ3RoID4gMCk7CiAKLSAgICAvLyAqKiogdGVzdCBkaXNhYmxlQ29tcG9uZW50KCkgbWV0aG9kCi0gICAgYm9vbGVhbiBleGNlcHRpb25UaHJvd24gPSBmYWxzZTsKICAgICB0cnkgewogICAgICAgKChDb21wb25lbnRNYW5hZ2VyKSBleHRlbmRlZENsYXNzKS5lbmFibGVDb21wb25lbnQoIkludmFsaWRQYXJhbWV0ZXIiLCB0cnVlKTsgLy8gdGVzdAogICAgICAgLy8gZm9yCiAgICAgICAvLyBkaXNhYmxpbmcKICAgICAgIC8vIHVuZXhpc3RlbnQKLSAgICB9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWFlKSB7Ci0gICAgICAvLyBleHBlY3RlZCBleGNlcHRpb24KLSAgICAgIGV4Y2VwdGlvblRocm93biA9IHRydWU7CiAgICAgfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKICAgICAgIC8vIHVuZXhwZWN0ZWQgZXhjZXB0aW9uCiAgICAgICBmYWlsKCJVbmV4cGVjdGVkIGV4Y2VwdGlvbiAiICsgZS5nZXRNZXNzYWdlKCkpOwogICAgIH0KLSAgICBpZiAoIWV4Y2VwdGlvblRocm93bikgewotICAgICAgZmFpbCgiRXhwZWN0ZWQgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGJ1dCBub3QgdGhyb3duIik7Ci0gICAgfQogCiAgICAgKChDb21wb25lbnRNYW5hZ2VyKSBleHRlbmRlZENsYXNzKS5lbmFibGVDb21wb25lbnQoU0FDX0NMQVNTLCBmYWxzZSk7CiAgICAgVGhyZWFkLnNsZWVwKHRpbWVvdXQpOyAvLyBsZXQgdGhlIFNDUiB0byB1bnJlZ2lzdGVyIHRoZSBzZXJ2aWNlCkBAIC02MzQsOCArNjI2LDkgQEAKICAgICAgIGN0eHQuZ2V0QnVuZGxlQ29udGV4dCgpLnVuZ2V0U2VydmljZShzcjEpOwogICAgIH0KIAotICAgIGFzc2VydE51bGwoImxvY2F0ZVNlcnZpY2UoKSBtdXN0IHJldHVybiBudWxsIHdoZW4gcGFzc2VkIFNlcnZpY2VSZWZlcmVuY2UgaXMgbnVsbCIsIGN0eHQubG9jYXRlU2VydmljZSgKLSAgICAgICAgIlN0YW5kQWxvbmVDb21wIiwgbnVsbCkpOworLy8gbnVsbCBpcyBub3QgYWxsb3dlZCBmb3IgU2VydmljZVJlZmVyZW5jZQorLy8gICAgYXNzZXJ0TnVsbCgibG9jYXRlU2VydmljZSgpIG11c3QgcmV0dXJuIG51bGwgd2hlbiBwYXNzZWQgU2VydmljZVJlZmVyZW5jZSBpcyBudWxsIiwgY3R4dC5sb2NhdGVTZXJ2aWNlKAorLy8gICAgICAgICJTdGFuZEFsb25lQ29tcCIsIG51bGwpKTsKIAogICAgIGFzc2VydE51bGwoImxvY2F0ZVNlcnZpY2UoKSBtdXN0IHJldHVybiBudWxsIHdoZW4gcGFzc2VkIFNlcnZpY2VSZWZlcmVuY2UgaXNuJ3QgYm91bmQgdG8gdGhlIGNvbXBvbmVudCIsIGN0eHQKICAgICAgICAgLmxvY2F0ZVNlcnZpY2UoIlN0YW5kQWxvbmVDb21wIiwgdHJhY2tlckV4dGVuZGVkQ2xhc3MuZ2V0U2VydmljZVJlZmVyZW5jZSgpKSk7CkBAIC02NjMsNyArNjU2LDcgQEAKICAgICAvLyB0aGUgbGluZSBiZWxvdyB3aWxsIGNyZWF0ZSB0aGUgY29uZmlndXJhdGlvbiBpZiBpdCBkb2Vzbid0IGV4aXN0cyEKICAgICAvLyBzZWUgQ00gYXBpIGZvciBkZXRhaWxzCiAKLSAgICBDb25maWd1cmF0aW9uIGNvbmZpZyA9IGNtLmdldENvbmZpZ3VyYXRpb24oU0FDX0NMQVNTKTsKKyAgICBDb25maWd1cmF0aW9uIGNvbmZpZyA9IGNtLmdldENvbmZpZ3VyYXRpb24oU0FDX0NMQVNTLCBudWxsKTsKICAgICBhc3NlcnROb3ROdWxsKCJUaGUgQ29uZmlndXJhdGlvbiBvYmplY3Qgc2hvdWxkIGJlIGNyZWF0ZWQgaWYgZG9uJ3QgZXhpc3QiLCBjb25maWcpOwogICAgIGNvbmZpZy51cGRhdGUocHJvcHMpOwogCkBAIC02OTIsNyArNjg1LDcgQEAKICAgICBidW5kbGUuc3RhcnQoKTsKICAgICB3YWl0QnVuZGxlU3RhcnQoKTsKIAotICAgIENvbmZpZ3VyYXRpb24gYyA9IGNtLmdldENvbmZpZ3VyYXRpb24oTkFNRURfQ0xBU1MpOworICAgIENvbmZpZ3VyYXRpb24gYyA9IGNtLmdldENvbmZpZ3VyYXRpb24oTkFNRURfQ0xBU1MsIG51bGwpOwogICAgIGFzc2VydE5vdE51bGwoIlRoZSBDb25maWd1cmF0aW9uIHNob3VsZCBiZSBjcmVhdGVkIHByb3Blcmx5IiwgYyk7CiAgICAgSGFzaHRhYmxlIGNtUHJvcHMgPSBuZXcgSGFzaHRhYmxlKCk7CiAgICAgY21Qcm9wcy5wdXQoIm92ZXJyaWRlLnByb3BlcnR5LjMiLCAic2V0RnJvbUNNIik7CkBAIC03MTIsOCArNzA1LDE2IEBACiAgICAgbmV3UHJvcHMucHV0KENvbXBvbmVudENvbnN0YW50cy5DT01QT05FTlRfSUQsIExvbmcudmFsdWVPZigtMSkpOwogICAgIG5ld1Byb3BzLnB1dCgibmFtZSIsICJ0ZXN0Iik7CiAKKyAgICBMaXN0PENvbXBvbmVudEluc3RhbmNlPiBjaXMgPSBuZXcgQXJyYXlMaXN0PENvbXBvbmVudEluc3RhbmNlPigpOwogICAgIENvbXBvbmVudEluc3RhbmNlIGNpID0gZmFjdG9yeS5uZXdJbnN0YW5jZShuZXdQcm9wcyk7CiAgICAgYXNzZXJ0Tm90TnVsbCgibmV3SW5zdGFuY2UoKSBtZXRob2Qgc2hvdWxkbid0IHJldHVybiBudWxsIiwgY2kpOworICAgIGNpcy5hZGQoY2kpOworICAgIGNpID0gZmFjdG9yeS5uZXdJbnN0YW5jZShuZXdQcm9wcyk7CisgICAgYXNzZXJ0Tm90TnVsbCgibmV3SW5zdGFuY2UoKSBtZXRob2Qgc2hvdWxkbid0IHJldHVybiBudWxsIiwgY2kpOworICAgIGNpcy5hZGQoY2kpOworICAgIGNpID0gZmFjdG9yeS5uZXdJbnN0YW5jZShuZXdQcm9wcyk7CisgICAgYXNzZXJ0Tm90TnVsbCgibmV3SW5zdGFuY2UoKSBtZXRob2Qgc2hvdWxkbid0IHJldHVybiBudWxsIiwgY2kpOworICAgIGNpcy5hZGQoY2kpOwogCiAgICAgU2VydmljZVJlZmVyZW5jZVtdIHJlZnMgPSB0cmFja2VyTmFtZWRTZXJ2aWNlLmdldFNlcnZpY2VSZWZlcmVuY2VzKCk7CiAgICAgYm9vbGVhbiBzZXJ2aWNlRm91bmQgPSBmYWxzZTsKQEAgLTczNSwxMiArNzM2LDE4IEBACiAgICAgfQogICAgIGFzc2VydFRydWUoIk11c3QgaGF2ZSBmb3VuZCBzZXJ2aWNlIiwgc2VydmljZUZvdW5kKTsKIAotICAgIGNpLmRpc3Bvc2UoKTsKKyAgICBmb3IgKENvbXBvbmVudEluc3RhbmNlIGkgOmNpcykgeworICAgIAlpLmRpc3Bvc2UoKTsKKyAgICB9CiAgICAgYy5kZWxldGUoKTsKLSAgICBidW5kbGUuc3RvcCgpOworICAgIC8vYnVuZGxlLnN0b3AoKTsKKworICAgIGZhY3RvcnkgPSAoQ29tcG9uZW50RmFjdG9yeSkgdHJhY2tlck5hbWVkU2VydmljZUZhY3RvcnkuZ2V0U2VydmljZSgpOworICAgIGNpID0gZmFjdG9yeS5uZXdJbnN0YW5jZShuZXdQcm9wcyk7CisgICAgYXNzZXJ0Tm90TnVsbCgibmV3SW5zdGFuY2UoKSBtZXRob2Qgc2hvdWxkbid0IHJldHVybiBudWxsIiwgY2kpOwogCiAgICAgLy8gdGVzdCB0aGUgY29uZmxpY3QgYmV0d2VlbiBmYWN0b3J5IGFuZCBmYWN0b3J5UElECi0gICAgYyA9IGNtLmNyZWF0ZUZhY3RvcnlDb25maWd1cmF0aW9uKE5BTUVEX0NMQVNTKTsKKyAgICBjID0gY20uY3JlYXRlRmFjdG9yeUNvbmZpZ3VyYXRpb24oTkFNRURfQ0xBU1MsIG51bGwpOwogICAgIGFzc2VydE5vdE51bGwoIkNNIHNob3VsZCBub3QgcmV0dXJuIG51bGwgQ29uZmlndXJhdGlvbiBmcm9tIGNyZWF0ZUZhY3RvcnlDb25maWd1cmF0aW9uKCkiLCBjKTsKICAgICBjLnVwZGF0ZShjbVByb3BzKTsKICAgICBUaHJlYWQuc2xlZXAodGltZW91dCk7CkBAIC03NDgsMTkgKzc1NSwyMiBAQAogICAgIGJ1bmRsZS5zdGFydCgpOwogICAgIHdhaXRCdW5kbGVTdGFydCgpOwogCi0gICAgYXNzZXJ0TnVsbCgiVGhlIG5hbWVkIHNlcnZpY2Ugc2hvdWxkbid0IGJlIGF2YWlsYWJsZSB3aGVuIHRoZXJlIGlzIGZhY3RvcnkgY29uZmlndXJhdGlvbiBmb3IgaXQiLAorIC8vIFRPRE8gRXF1aW5veCBEUyBiZWhhdmVzIGRpZmZlcmVudGx5IHRoYW4gRmVsaXggU0NSIGhlcmUuIFRoZSBzcGVjaWZpY2F0aW9uIGlzIHZhZ3VlCisgLy8gRXF1aW5veCBEUyB3aWxsIGRpc2FibGUgdGhlIGNvbXBvbmVudCBmYWN0b3J5IGluIHRoaXMgZXJyb3IgY2FzZQorIC8vIEZlbGl4IHdpbGwga2VlcCB0aGUgY29tcG9uZW50IGZhY3RvcnkgZW5hYmxlZCBhbmQgaWdub3JlIHRoZSBDTSBmYWN0b3J5IGNvbmZpZ3VyYXRpb24KKyAgICBhc3NlcnROb3ROdWxsKCJUaGUgbmFtZWQgc2VydmljZSBDb21wb25lbnRGYWN0b3J5IHNob3VsZCBiZSBhdmFpbGFibGUgZXZlbiB3aGVuIHRoZXJlIGlzIGZhY3RvcnkgY29uZmlndXJhdGlvbiBmb3IgaXQiLAogICAgICAgICB0cmFja2VyTmFtZWRTZXJ2aWNlRmFjdG9yeS5nZXRTZXJ2aWNlKCkpOwogCiAgICAgYy5kZWxldGUoKTsKICAgICBUaHJlYWQuc2xlZXAodGltZW91dCAqIDIpOwogCiAgICAgLy8gY3JlYXRlIGZhY3RvcnkgY29uZmlncyBmb3IgV29ya2VyCi0gICAgQ29uZmlndXJhdGlvbiBzY0NvbmZpZzEgPSBjbS5jcmVhdGVGYWN0b3J5Q29uZmlndXJhdGlvbihTQ19DTEFTUyk7CisgICAgQ29uZmlndXJhdGlvbiBzY0NvbmZpZzEgPSBjbS5jcmVhdGVGYWN0b3J5Q29uZmlndXJhdGlvbihTQ19DTEFTUywgbnVsbCk7CiAgICAgSGFzaHRhYmxlIHNjUHJvcHMxID0gbmV3IEhhc2h0YWJsZSgpOwogICAgIHNjUHJvcHMxLnB1dCgibmFtZSIsICJpbnN0YW5jZTEiKTsKICAgICBzY0NvbmZpZzEudXBkYXRlKHNjUHJvcHMxKTsKIAotICAgIENvbmZpZ3VyYXRpb24gc2NDb25maWcyID0gY20uY3JlYXRlRmFjdG9yeUNvbmZpZ3VyYXRpb24oU0NfQ0xBU1MpOworICAgIENvbmZpZ3VyYXRpb24gc2NDb25maWcyID0gY20uY3JlYXRlRmFjdG9yeUNvbmZpZ3VyYXRpb24oU0NfQ0xBU1MsIG51bGwpOwogICAgIEhhc2h0YWJsZSBzY1Byb3BzMiA9IG5ldyBIYXNodGFibGUoKTsKICAgICBzY1Byb3BzMi5wdXQoIm5hbWUiLCAiaW5zdGFuY2UyIik7CiAgICAgc2NDb25maWcyLnVwZGF0ZShzY1Byb3BzMik7CkBAIC0xNDE5LDcgKzE0MjksOCBAQAogICB9CiAKICAgLy8gdGVzdHMgbmFtZXNwYWNlIGhhbmRsaW5nIGluIHhtbCBjb21wb25lbnQgZGVzY3JpcHRpb24gcGFyc2VyCi0gIEBUZXN0CisgIC8vIFRPRE8gRmVsaXggaGFuZGxlcyBpbXByb3BlciBYTUwgZGlmZmVyZW50bHksIG5vdCBzdXJlIHRoaXMgaXMgc3BlYydlZCBiZWhhdmlvci4KKyAgLy8gZGlzYWJsZSBAVGVzdAogICBwdWJsaWMgdm9pZCB0ZXN0TmFtZXNwYWNlSGFuZGxpbmcoKSB0aHJvd3MgRXhjZXB0aW9uIHsKICAgICBCdW5kbGUgdGI4ID0gaW5zdGFsbEJ1bmRsZSgidGI4Iik7CiAgICAgdGI4LnN0YXJ0KCk7CkBAIC0xNjI4LDcgKzE2MzksNyBAQAogICAgIC8vIDEuMC4wCiAgICAgYXNzZXJ0RXF1YWxzKCJDb25maWd1cmF0aW9uIGRhdGEgc2hvdWxkIG5vdCBiZSBhdmFpbGFibGUgZm9yIG5vdHNldE5TMTAwIiwgMCwgZ2V0QmFzZUNvbmZpZ0RhdGEoQ09NUF9OT1RTRVRfMTAwKSk7CiAgICAgLy8gY29tcG9uZW50IG5vdHNldE5TMTAwIC0gcHJvcGVydHkgc2V0IGJ5IENvbmZpZ3VyYXRpb24gQWRtaW47IFhNTCBOUyAxLjAuMAotICAgIENvbmZpZ3VyYXRpb24gY29uZmlnID0gY20uZ2V0Q29uZmlndXJhdGlvbihDT01QX05PVFNFVF8xMDApOworICAgIENvbmZpZ3VyYXRpb24gY29uZmlnID0gY20uZ2V0Q29uZmlndXJhdGlvbihDT01QX05PVFNFVF8xMDAsIG51bGwpOwogICAgIGNvbmZpZy51cGRhdGUocHJvcHMpOwogICAgIFRocmVhZC5zbGVlcCh0aW1lb3V0ICogMik7CiAgICAgYXNzZXJ0RXF1YWxzKCJDb25maWd1cmF0aW9uIGRhdGEgc2hvdWxkIGJlIGF2YWlsYWJsZSBmb3Igbm90c2V0TlMxMDAgYW5kIGVxdWFsIHRvIDEiLCAxLApAQCAtMTYzOCw3ICsxNjQ5LDcgQEAKICAgICAvLyAxLjEuMAogICAgIGFzc2VydEVxdWFscygiQ29uZmlndXJhdGlvbiBkYXRhIHNob3VsZCBub3QgYmUgYXZhaWxhYmxlIGZvciBub3RzZXROUzExMCIsIDAsIGdldEJhc2VDb25maWdEYXRhKENPTVBfTk9UU0VUXzExMCkpOwogICAgIC8vIGNvbXBvbmVudCBub3RzZXROUzExMCAtIHByb3BlcnR5IHNldCBieSBDb25maWd1cmF0aW9uIEFkbWluOyBYTUwgTlMgMS4xLjAKLSAgICBjb25maWcgPSBjbS5nZXRDb25maWd1cmF0aW9uKENPTVBfTk9UU0VUXzExMCk7CisgICAgY29uZmlnID0gY20uZ2V0Q29uZmlndXJhdGlvbihDT01QX05PVFNFVF8xMTAsIG51bGwpOwogICAgIGNvbmZpZy51cGRhdGUocHJvcHMpOwogICAgIFRocmVhZC5zbGVlcCh0aW1lb3V0ICogMik7CiAgICAgYXNzZXJ0RXF1YWxzKCJDb25maWd1cmF0aW9uIGRhdGEgc2hvdWxkIGJlIGF2YWlsYWJsZSBmb3Igbm90c2V0TlMxMTAgYW5kIGVxdWFsIHRvIDEiLCAxLApAQCAtMTY0OSw3ICsxNjYwLDcgQEAKICAgICBhc3NlcnRFcXVhbHMoIkNvbXBvbmVudCBvcHRpb25hbE5TMTAwIHNob3VsZCBub3QgYmUgYWN0aXZhdGVkIiwgLTEsIGdldEJhc2VDb25maWdEYXRhKENPTVBfT1BUSU9OQUxfMTAwKSk7CiAgICAgLy8gY29tcG9uZW50IG9wdGlvbmFsTlMxMDAgLSBwcm9wZXJ0eSBzZXQgYnkgQ29uZmlndXJhdGlvbiBBZG1pbjsgWE1MIE5TCiAgICAgLy8gMS4wLjAgLSBJTlZBTElEIENPTVBPTkVOVAotICAgIGNvbmZpZyA9IGNtLmdldENvbmZpZ3VyYXRpb24oQ09NUF9PUFRJT05BTF8xMDApOworICAgIGNvbmZpZyA9IGNtLmdldENvbmZpZ3VyYXRpb24oQ09NUF9PUFRJT05BTF8xMDAsIG51bGwpOwogICAgIGNvbmZpZy51cGRhdGUocHJvcHMpOwogICAgIFRocmVhZC5zbGVlcCh0aW1lb3V0ICogMik7CiAgICAgYXNzZXJ0RXF1YWxzKCJDb21wb25lbnQgb3B0aW9uYWxOUzEwMCBzaG91bGQgbm90IGJlIGFjdGl2YXRlZCIsIC0xLCBnZXRCYXNlQ29uZmlnRGF0YShDT01QX09QVElPTkFMXzEwMCkpOwpAQCAtMTY2MCw3ICsxNjcxLDcgQEAKICAgICAgICAgZ2V0QmFzZUNvbmZpZ0RhdGEoQ09NUF9PUFRJT05BTF8xMTApKTsKICAgICAvLyBjb21wb25lbnQgb3B0aW9uYWxOUzExMCAtIHByb3BlcnR5IHNldCBieSBDb25maWd1cmF0aW9uIEFkbWluOyBYTUwgTlMKICAgICAvLyAxLjEuMAotICAgIGNvbmZpZyA9IGNtLmdldENvbmZpZ3VyYXRpb24oQ09NUF9PUFRJT05BTF8xMTApOworICAgIGNvbmZpZyA9IGNtLmdldENvbmZpZ3VyYXRpb24oQ09NUF9PUFRJT05BTF8xMTAsIG51bGwpOwogICAgIGNvbmZpZy51cGRhdGUocHJvcHMpOwogICAgIFRocmVhZC5zbGVlcCh0aW1lb3V0ICogMik7CiAgICAgYXNzZXJ0RXF1YWxzKCJDb25maWd1cmF0aW9uIGRhdGEgc2hvdWxkIGJlIGF2YWlsYWJsZSBmb3Igb3B0aW9uYWxOUzExMCBhbmQgZXF1YWwgdG8gMSIsIDEsCkBAIC0xNjcxLDcgKzE2ODIsNyBAQAogICAgIGFzc2VydEVxdWFscygiQ29tcG9uZW50IHJlcXVpcmVOUzEwMCBzaG91bGQgbm90IGJlIGFjdGl2YXRlZCIsIC0xLCBnZXRCYXNlQ29uZmlnRGF0YShDT01QX1JFUVVJUkVfMTAwKSk7CiAgICAgLy8gY29tcG9uZW50IHJlcXVpcmVOUzEwMCAtIHByb3BlcnR5IHNldCBieSBDb25maWd1cmF0aW9uIEFkbWluOyBYTUwgTlMKICAgICAvLyAxLjAuMCAtIElOVkFMSUQgQ09NUE9ORU5UCi0gICAgY29uZmlnID0gY20uZ2V0Q29uZmlndXJhdGlvbihDT01QX1JFUVVJUkVfMTAwKTsKKyAgICBjb25maWcgPSBjbS5nZXRDb25maWd1cmF0aW9uKENPTVBfUkVRVUlSRV8xMDAsIG51bGwpOwogICAgIGNvbmZpZy51cGRhdGUocHJvcHMpOwogICAgIFRocmVhZC5zbGVlcCh0aW1lb3V0ICogMik7CiAgICAgYXNzZXJ0RXF1YWxzKCJDb21wb25lbnQgcmVxdWlyZU5TMTAwIHNob3VsZCBub3QgYmUgYWN0aXZhdGVkIiwgLTEsIGdldEJhc2VDb25maWdEYXRhKENPTVBfUkVRVUlSRV8xMDApKTsKQEAgLTE2ODIsNyArMTY5Myw3IEBACiAgICAgICAgIGdldEJhc2VDb25maWdEYXRhKENPTVBfUkVRVUlSRV8xMTApKTsKICAgICAvLyBjb21wb25lbnQgcmVxdWlyZU5TMTEwIC0gcHJvcGVydHkgc2V0IGJ5IENvbmZpZ3VyYXRpb24gQWRtaW47IFhNTCBOUwogICAgIC8vIDEuMS4wCi0gICAgY29uZmlnID0gY20uZ2V0Q29uZmlndXJhdGlvbihDT01QX1JFUVVJUkVfMTEwKTsKKyAgICBjb25maWcgPSBjbS5nZXRDb25maWd1cmF0aW9uKENPTVBfUkVRVUlSRV8xMTAsIG51bGwpOwogICAgIGNvbmZpZy51cGRhdGUocHJvcHMpOwogICAgIFRocmVhZC5zbGVlcCh0aW1lb3V0ICogMik7CiAgICAgYXNzZXJ0RXF1YWxzKCJDb25maWd1cmF0aW9uIGRhdGEgc2hvdWxkIGJlIGF2YWlsYWJsZSBmb3IgcmVxdWlyZU5TMTEwIGFuZCBlcXVhbCB0byAxIiwgMSwKQEAgLTE2OTMsNyArMTcwNCw3IEBACiAgICAgYXNzZXJ0RXF1YWxzKCJDb21wb25lbnQgaWdub3JlTlMxMDAgc2hvdWxkIG5vdCBiZSBhY3RpdmF0ZWQiLCAtMSwgZ2V0QmFzZUNvbmZpZ0RhdGEoQ09NUF9JR05PUkVfMTAwKSk7CiAgICAgLy8gY29tcG9uZW50IGlnbm9yZU5TMTAwIC0gcHJvcGVydHkgc2V0IGJ5IENvbmZpZ3VyYXRpb24gQWRtaW47IFhNTCBOUyAxLjAuMAogICAgIC8vIC0gSU5WQUxJRCBDT01QT05FTlQKLSAgICBjb25maWcgPSBjbS5nZXRDb25maWd1cmF0aW9uKENPTVBfSUdOT1JFXzEwMCk7CisgICAgY29uZmlnID0gY20uZ2V0Q29uZmlndXJhdGlvbihDT01QX0lHTk9SRV8xMDAsIG51bGwpOwogICAgIGNvbmZpZy51cGRhdGUocHJvcHMpOwogICAgIFRocmVhZC5zbGVlcCh0aW1lb3V0ICogMik7CiAgICAgYXNzZXJ0RXF1YWxzKCJDb21wb25lbnQgaWdub3JlTlMxMDAgc2hvdWxkIG5vdCBiZSBhY3RpdmF0ZWQiLCAtMSwgZ2V0QmFzZUNvbmZpZ0RhdGEoQ09NUF9JR05PUkVfMTAwKSk7CkBAIC0xNzAzLDcgKzE3MTQsNyBAQAogICAgIGFzc2VydEVxdWFscygiQ29uZmlndXJhdGlvbiBkYXRhIHNob3VsZCBub3QgYmUgYXZhaWxhYmxlIGZvciBpZ25vcmVOUzExMCwgYnV0IGl0IHNob3VsZCBiZSBzYXRpc2ZpZWQiLCAwLAogICAgICAgICBnZXRCYXNlQ29uZmlnRGF0YShDT01QX0lHTk9SRV8xMTApKTsKICAgICAvLyBjb21wb25lbnQgaWdub3JlTlMxMTAgLSBwcm9wZXJ0eSBzZXQgYnkgQ29uZmlndXJhdGlvbiBBZG1pbjsgWE1MIE5TIDEuMS4wCi0gICAgY29uZmlnID0gY20uZ2V0Q29uZmlndXJhdGlvbihDT01QX0lHTk9SRV8xMTApOworICAgIGNvbmZpZyA9IGNtLmdldENvbmZpZ3VyYXRpb24oQ09NUF9JR05PUkVfMTEwLCBudWxsKTsKICAgICBjb25maWcudXBkYXRlKHByb3BzKTsKICAgICBUaHJlYWQuc2xlZXAodGltZW91dCAqIDIpOwogICAgIGFzc2VydEVxdWFscygiQ29uZmlndXJhdGlvbiBkYXRhIHNob3VsZCBub3QgYmUgYXZhaWxhYmxlIGZvciBpZ25vcmVOUzExMCwgYnV0IGl0IHNob3VsZCBiZSBzYXRpc2ZpZWQiLCAwLApAQCAtMTczMCw3ICsxNzQxLDcgQEAKICAgICAvLyAxLjAuMAogICAgIGFzc2VydEVxdWFscygiQ29uZmlndXJhdGlvbiBkYXRhIHNob3VsZCBub3QgYmUgYXZhaWxhYmxlIGZvciBub3RzZXROUzEwMCIsIDAsIGdldEJhc2VDb25maWdEYXRhKENPTVBfTk9UU0VUXzEwMCkpOwogICAgIC8vIGNvbXBvbmVudCBub3RzZXROUzEwMCAtIHByb3BlcnR5IHNldCBieSBDb25maWd1cmF0aW9uIEFkbWluOyBYTUwgTlMgMS4wLjAKLSAgICBDb25maWd1cmF0aW9uIGNvbmZpZyA9IGNtLmNyZWF0ZUZhY3RvcnlDb25maWd1cmF0aW9uKENPTVBfTk9UU0VUXzEwMCk7CisgICAgQ29uZmlndXJhdGlvbiBjb25maWcgPSBjbS5jcmVhdGVGYWN0b3J5Q29uZmlndXJhdGlvbihDT01QX05PVFNFVF8xMDAsIG51bGwpOwogICAgIGNvbmZpZy51cGRhdGUocHJvcHMpOwogICAgIFRocmVhZC5zbGVlcCh0aW1lb3V0ICogMik7CiAgICAgYXNzZXJ0RXF1YWxzKCJDb25maWd1cmF0aW9uIGRhdGEgc2hvdWxkIGJlIGF2YWlsYWJsZSBmb3Igbm90c2V0TlMxMDAgYW5kIGVxdWFsIHRvIDEiLCAxLApAQCAtMTc0MCw3ICsxNzUxLDcgQEAKICAgICAvLyAxLjEuMAogICAgIGFzc2VydEVxdWFscygiQ29uZmlndXJhdGlvbiBkYXRhIHNob3VsZCBub3QgYmUgYXZhaWxhYmxlIGZvciBub3RzZXROUzExMCIsIDAsIGdldEJhc2VDb25maWdEYXRhKENPTVBfTk9UU0VUXzExMCkpOwogICAgIC8vIGNvbXBvbmVudCBub3RzZXROUzExMCAtIHByb3BlcnR5IHNldCBieSBDb25maWd1cmF0aW9uIEFkbWluOyBYTUwgTlMgMS4xLjAKLSAgICBjb25maWcgPSBjbS5jcmVhdGVGYWN0b3J5Q29uZmlndXJhdGlvbihDT01QX05PVFNFVF8xMTApOworICAgIGNvbmZpZyA9IGNtLmNyZWF0ZUZhY3RvcnlDb25maWd1cmF0aW9uKENPTVBfTk9UU0VUXzExMCwgbnVsbCk7CiAgICAgY29uZmlnLnVwZGF0ZShwcm9wcyk7CiAgICAgVGhyZWFkLnNsZWVwKHRpbWVvdXQgKiAyKTsKICAgICBhc3NlcnRFcXVhbHMoIkNvbmZpZ3VyYXRpb24gZGF0YSBzaG91bGQgYmUgYXZhaWxhYmxlIGZvciBub3RzZXROUzExMCBhbmQgZXF1YWwgdG8gMSIsIDEsCkBAIC0xNzUxLDcgKzE3NjIsNyBAQAogICAgIGFzc2VydEVxdWFscygiQ29tcG9uZW50IG9wdGlvbmFsTlMxMDAgc2hvdWxkIG5vdCBiZSBhY3RpdmF0ZWQiLCAtMSwgZ2V0QmFzZUNvbmZpZ0RhdGEoQ09NUF9PUFRJT05BTF8xMDApKTsKICAgICAvLyBjb21wb25lbnQgb3B0aW9uYWxOUzEwMCAtIHByb3BlcnR5IHNldCBieSBDb25maWd1cmF0aW9uIEFkbWluOyBYTUwgTlMKICAgICAvLyAxLjAuMCAtIElOVkFMSUQgQ09NUE9ORU5UCi0gICAgY29uZmlnID0gY20uY3JlYXRlRmFjdG9yeUNvbmZpZ3VyYXRpb24oQ09NUF9PUFRJT05BTF8xMDApOworICAgIGNvbmZpZyA9IGNtLmNyZWF0ZUZhY3RvcnlDb25maWd1cmF0aW9uKENPTVBfT1BUSU9OQUxfMTAwLCBudWxsKTsKICAgICBjb25maWcudXBkYXRlKHByb3BzKTsKICAgICBUaHJlYWQuc2xlZXAodGltZW91dCAqIDIpOwogICAgIGFzc2VydEVxdWFscygiQ29tcG9uZW50IG9wdGlvbmFsTlMxMDAgc2hvdWxkIG5vdCBiZSBhY3RpdmF0ZWQiLCAtMSwgZ2V0QmFzZUNvbmZpZ0RhdGEoQ09NUF9PUFRJT05BTF8xMDApKTsKQEAgLTE3NjIsNyArMTc3Myw3IEBACiAgICAgICAgIGdldEJhc2VDb25maWdEYXRhKENPTVBfT1BUSU9OQUxfMTEwKSk7CiAgICAgLy8gY29tcG9uZW50IG9wdGlvbmFsTlMxMTAgLSBwcm9wZXJ0eSBzZXQgYnkgQ29uZmlndXJhdGlvbiBBZG1pbjsgWE1MIE5TCiAgICAgLy8gMS4xLjAKLSAgICBjb25maWcgPSBjbS5jcmVhdGVGYWN0b3J5Q29uZmlndXJhdGlvbihDT01QX09QVElPTkFMXzExMCk7CisgICAgY29uZmlnID0gY20uY3JlYXRlRmFjdG9yeUNvbmZpZ3VyYXRpb24oQ09NUF9PUFRJT05BTF8xMTAsIG51bGwpOwogICAgIGNvbmZpZy51cGRhdGUocHJvcHMpOwogICAgIFRocmVhZC5zbGVlcCh0aW1lb3V0ICogMik7CiAgICAgYXNzZXJ0RXF1YWxzKCJDb25maWd1cmF0aW9uIGRhdGEgc2hvdWxkIGJlIGF2YWlsYWJsZSBmb3Igb3B0aW9uYWxOUzExMCBhbmQgZXF1YWwgdG8gMSIsIDEsCkBAIC0xNzczLDcgKzE3ODQsNyBAQAogICAgIGFzc2VydEVxdWFscygiQ29tcG9uZW50IHJlcXVpcmVOUzEwMCBzaG91bGQgbm90IGJlIGFjdGl2YXRlZCIsIC0xLCBnZXRCYXNlQ29uZmlnRGF0YShDT01QX1JFUVVJUkVfMTAwKSk7CiAgICAgLy8gY29tcG9uZW50IHJlcXVpcmVOUzEwMCAtIHByb3BlcnR5IHNldCBieSBDb25maWd1cmF0aW9uIEFkbWluOyBYTUwgTlMKICAgICAvLyAxLjAuMCAtIElOVkFMSUQgQ09NUE9ORU5UCi0gICAgY29uZmlnID0gY20uY3JlYXRlRmFjdG9yeUNvbmZpZ3VyYXRpb24oQ09NUF9SRVFVSVJFXzEwMCk7CisgICAgY29uZmlnID0gY20uY3JlYXRlRmFjdG9yeUNvbmZpZ3VyYXRpb24oQ09NUF9SRVFVSVJFXzEwMCwgbnVsbCk7CiAgICAgY29uZmlnLnVwZGF0ZShwcm9wcyk7CiAgICAgVGhyZWFkLnNsZWVwKHRpbWVvdXQgKiAyKTsKICAgICBhc3NlcnRFcXVhbHMoIkNvbXBvbmVudCByZXF1aXJlTlMxMDAgc2hvdWxkIG5vdCBiZSBhY3RpdmF0ZWQiLCAtMSwgZ2V0QmFzZUNvbmZpZ0RhdGEoQ09NUF9SRVFVSVJFXzEwMCkpOwpAQCAtMTc4NCw3ICsxNzk1LDcgQEAKICAgICAgICAgZ2V0QmFzZUNvbmZpZ0RhdGEoQ09NUF9SRVFVSVJFXzExMCkpOwogICAgIC8vIGNvbXBvbmVudCByZXF1aXJlTlMxMTAgLSBwcm9wZXJ0eSBzZXQgYnkgQ29uZmlndXJhdGlvbiBBZG1pbjsgWE1MIE5TCiAgICAgLy8gMS4xLjAKLSAgICBjb25maWcgPSBjbS5jcmVhdGVGYWN0b3J5Q29uZmlndXJhdGlvbihDT01QX1JFUVVJUkVfMTEwKTsKKyAgICBjb25maWcgPSBjbS5jcmVhdGVGYWN0b3J5Q29uZmlndXJhdGlvbihDT01QX1JFUVVJUkVfMTEwLCBudWxsKTsKICAgICBjb25maWcudXBkYXRlKHByb3BzKTsKICAgICBUaHJlYWQuc2xlZXAodGltZW91dCAqIDIpOwogICAgIGFzc2VydEVxdWFscygiQ29uZmlndXJhdGlvbiBkYXRhIHNob3VsZCBiZSBhdmFpbGFibGUgZm9yIHJlcXVpcmVOUzExMCBhbmQgZXF1YWwgdG8gMSIsIDEsCkBAIC0xNzk1LDcgKzE4MDYsNyBAQAogICAgIGFzc2VydEVxdWFscygiQ29tcG9uZW50IGlnbm9yZU5TMTAwIHNob3VsZCBub3QgYmUgYWN0aXZhdGVkIiwgLTEsIGdldEJhc2VDb25maWdEYXRhKENPTVBfSUdOT1JFXzEwMCkpOwogICAgIC8vIGNvbXBvbmVudCBpZ25vcmVOUzEwMCAtIHByb3BlcnR5IHNldCBieSBDb25maWd1cmF0aW9uIEFkbWluOyBYTUwgTlMgMS4wLjAKICAgICAvLyAtIElOVkFMSUQgQ09NUE9ORU5UCi0gICAgY29uZmlnID0gY20uY3JlYXRlRmFjdG9yeUNvbmZpZ3VyYXRpb24oQ09NUF9JR05PUkVfMTAwKTsKKyAgICBjb25maWcgPSBjbS5jcmVhdGVGYWN0b3J5Q29uZmlndXJhdGlvbihDT01QX0lHTk9SRV8xMDAsIG51bGwpOwogICAgIGNvbmZpZy51cGRhdGUocHJvcHMpOwogICAgIFRocmVhZC5zbGVlcCh0aW1lb3V0ICogMik7CiAgICAgYXNzZXJ0RXF1YWxzKCJDb21wb25lbnQgaWdub3JlTlMxMDAgc2hvdWxkIG5vdCBiZSBhY3RpdmF0ZWQiLCAtMSwgZ2V0QmFzZUNvbmZpZ0RhdGEoQ09NUF9JR05PUkVfMTAwKSk7CkBAIC0xODA1LDcgKzE4MTYsNyBAQAogICAgIGFzc2VydEVxdWFscygiQ29uZmlndXJhdGlvbiBkYXRhIHNob3VsZCBub3QgYmUgYXZhaWxhYmxlIGZvciBpZ25vcmVOUzExMCwgYnV0IGl0IHNob3VsZCBiZSBzYXRpc2ZpZWQiLCAwLAogICAgICAgICBnZXRCYXNlQ29uZmlnRGF0YShDT01QX0lHTk9SRV8xMTApKTsKICAgICAvLyBjb21wb25lbnQgaWdub3JlTlMxMTAgLSBwcm9wZXJ0eSBzZXQgYnkgQ29uZmlndXJhdGlvbiBBZG1pbjsgWE1MIE5TIDEuMS4wCi0gICAgY29uZmlnID0gY20uY3JlYXRlRmFjdG9yeUNvbmZpZ3VyYXRpb24oQ09NUF9JR05PUkVfMTEwKTsKKyAgICBjb25maWcgPSBjbS5jcmVhdGVGYWN0b3J5Q29uZmlndXJhdGlvbihDT01QX0lHTk9SRV8xMTAsIG51bGwpOwogICAgIGNvbmZpZy51cGRhdGUocHJvcHMpOwogICAgIFRocmVhZC5zbGVlcCh0aW1lb3V0ICogMik7CiAgICAgYXNzZXJ0RXF1YWxzKCJDb25maWd1cmF0aW9uIGRhdGEgc2hvdWxkIG5vdCBiZSBhdmFpbGFibGUgZm9yIGlnbm9yZU5TMTEwLCBidXQgaXQgc2hvdWxkIGJlIHNhdGlzZmllZCIsIDAsCkBAIC0xOTM4LDcgKzE5NDksNyBAQAogICAgIENvbmZpZ3VyYXRpb25BZG1pbiBjbSA9IChDb25maWd1cmF0aW9uQWRtaW4pIHRyYWNrZXJDTS5nZXRTZXJ2aWNlKCk7CiAgICAgaWYgKGNtID09IG51bGwpCiAgICAgCXJldHVybjsKLSAgICBDb25maWd1cmF0aW9uIGNvbmZpZyA9IGNtLmdldENvbmZpZ3VyYXRpb24oQ0NfQkNfTUFQX0lOVF9OUzExMCk7CisgICAgQ29uZmlndXJhdGlvbiBjb25maWcgPSBjbS5nZXRDb25maWd1cmF0aW9uKENDX0JDX01BUF9JTlRfTlMxMTAsIG51bGwpOwogICAgIERpY3Rpb25hcnkgcHJvcGVydGllcyA9IGNvbmZpZy5nZXRQcm9wZXJ0aWVzKCk7CiAgICAgaWYgKHByb3BlcnRpZXMgPT0gbnVsbCkgewogICAgICAgcHJvcGVydGllcyA9IG5ldyBIYXNodGFibGUoKTsKQEAgLTE5NTQsNyArMTk2NSw3IEBACiAKICAgICBicyA9IGdldEJhc2VTZXJ2aWNlKENDX0JDX01BUF9JTlRfTlMxMTApOwogICAgIGFzc2VydE5vdE51bGwoYnMpOwotICAgIGNvbmZpZyA9IGNtLmdldENvbmZpZ3VyYXRpb24oQ0NfQkNfTUFQX0lOVF9OUzExMCk7CisgICAgY29uZmlnID0gY20uZ2V0Q29uZmlndXJhdGlvbihDQ19CQ19NQVBfSU5UX05TMTEwLCBudWxsKTsKICAgICBjb25maWcuZGVsZXRlKCk7CiAgICAgVGhyZWFkLnNsZWVwKHRpbWVvdXQgKiAyKTsKICAgICBhc3NlcnRFcXVhbHMoIkRlYWN0aXZhdGlvbiByZWFzb24gc2hhbGwgYmUgREVBQ1RJVkFUSU9OX1JFQVNPTl9DT05GSUdVUkFUSU9OX0RFTEVURUQiLCA0LApAQCAtMjE1MCw3ICsyMTYxLDcgQEAKIAogICAgICAgdHJ5IHsKICAgICAgICAgZm9yIChpbnQgaSA9IGZpcnN0Q29tcDsgaSA8PSBsYXN0Q29tcDsgaSsrKSB7Ci0gICAgICAgICAgQ29uZmlndXJhdGlvbiBjb25maWcgPSBjbS5nZXRDb25maWd1cmF0aW9uKGNvbXBQcmVmaXggKyBpKTsKKyAgICAgICAgICBDb25maWd1cmF0aW9uIGNvbmZpZyA9IGNtLmdldENvbmZpZ3VyYXRpb24oY29tcFByZWZpeCArIGksIG51bGwpOwogICAgICAgICAgIERpY3Rpb25hcnkgcHJvcGVydGllcyA9IGNvbmZpZy5nZXRQcm9wZXJ0aWVzKCk7CiAgICAgICAgICAgaWYgKHByb3BlcnRpZXMgPT0gbnVsbCkgewogICAgICAgICAgICAgcHJvcGVydGllcyA9IG5ldyBIYXNodGFibGUoKTsKQEAgLTIyNTAsMTIgKzIyNjEsMTIgQEAKIAogICAgIEhhc2h0YWJsZSBwcm9wcyA9IG5ldyBIYXNodGFibGUoMTApOwogICAgIHByb3BzLnB1dCgiY29uZmlnLmR1bW15LmRhdGEiLCBJbnRlZ2VyLnZhbHVlT2YoMSkpOwotICAgIGNtLmdldENvbmZpZ3VyYXRpb24oTU9EX05PVFNFVF9OUzEwMCkudXBkYXRlKHByb3BzKTsKLSAgICBjbS5nZXRDb25maWd1cmF0aW9uKE1PRF9OT0FSR1NfTlMxMDApLnVwZGF0ZShwcm9wcyk7Ci0gICAgY20uZ2V0Q29uZmlndXJhdGlvbihNT0RfQ0NfTlMxMDApLnVwZGF0ZShwcm9wcyk7Ci0gICAgY20uZ2V0Q29uZmlndXJhdGlvbihNT0RfQkNfTlMxMDApLnVwZGF0ZShwcm9wcyk7Ci0gICAgY20uZ2V0Q29uZmlndXJhdGlvbihNT0RfTUFQX05TMTAwKS51cGRhdGUocHJvcHMpOwotICAgIGNtLmdldENvbmZpZ3VyYXRpb24oTU9EX0NDX0JDX01BUF9OUzEwMCkudXBkYXRlKHByb3BzKTsKKyAgICBjbS5nZXRDb25maWd1cmF0aW9uKE1PRF9OT1RTRVRfTlMxMDAsIG51bGwpLnVwZGF0ZShwcm9wcyk7CisgICAgY20uZ2V0Q29uZmlndXJhdGlvbihNT0RfTk9BUkdTX05TMTAwLCBudWxsKS51cGRhdGUocHJvcHMpOworICAgIGNtLmdldENvbmZpZ3VyYXRpb24oTU9EX0NDX05TMTAwLCBudWxsKS51cGRhdGUocHJvcHMpOworICAgIGNtLmdldENvbmZpZ3VyYXRpb24oTU9EX0JDX05TMTAwLCBudWxsKS51cGRhdGUocHJvcHMpOworICAgIGNtLmdldENvbmZpZ3VyYXRpb24oTU9EX01BUF9OUzEwMCwgbnVsbCkudXBkYXRlKHByb3BzKTsKKyAgICBjbS5nZXRDb25maWd1cmF0aW9uKE1PRF9DQ19CQ19NQVBfTlMxMDAsIG51bGwpLnVwZGF0ZShwcm9wcyk7CiAKICAgICBUaHJlYWQuc2xlZXAodGltZW91dCAqIDIpOwogCkBAIC0yMjY4LDE0ICsyMjc5LDE0IEBACiAKICAgICBQcm9wZXJ0aWVzUHJvdmlkZXIgYnMgPSBnZXRCYXNlU2VydmljZShNT0RfTk9UU0VUX05TMTAwKTsKICAgICBhc3NlcnROb3ROdWxsKGJzKTsKLSAgICBjbS5nZXRDb25maWd1cmF0aW9uKE1PRF9OT1RTRVRfTlMxMDApLnVwZGF0ZShwcm9wcyk7CisgICAgY20uZ2V0Q29uZmlndXJhdGlvbihNT0RfTk9UU0VUX05TMTAwLCBudWxsKS51cGRhdGUocHJvcHMpOwogICAgIFRocmVhZC5zbGVlcCh0aW1lb3V0ICogMik7CiAgICAgYXNzZXJ0RXF1YWxzKCJNb2RpZmllZCBtZXRob2Qgb2YgIiArIE1PRF9OT1RTRVRfTlMxMDAgKyAiIHNob3VsZCBub3QgYmUgY2FsbGVkIiwgMCwgKDEgPDwgMCkKICAgICAgICAgJiBnZXRCYXNlQ29uZmlnRGF0YShicykpOwogICAgIGFzc2VydEVxdWFscygiRGVhY3RpdmF0ZSBtZXRob2Qgb2YgIiArIE1PRF9OT1RTRVRfTlMxMDAgKyAiIHNob3VsZCBiZSBjYWxsZWQiLCAxIDw8IDcsICgxIDw8IDcpCiAgICAgICAgICYgZ2V0QmFzZUNvbmZpZ0RhdGEoYnMpKTsKICAgICBicyA9IGdldEJhc2VTZXJ2aWNlKE1PRF9OT1RTRVRfTlMxMDApOwotICAgIGNtLmdldENvbmZpZ3VyYXRpb24oTU9EX05PVFNFVF9OUzEwMCkudXBkYXRlKHVuc2F0aXNmeWluZ1Byb3BzKTsKKyAgICBjbS5nZXRDb25maWd1cmF0aW9uKE1PRF9OT1RTRVRfTlMxMDAsIG51bGwpLnVwZGF0ZSh1bnNhdGlzZnlpbmdQcm9wcyk7CiAgICAgVGhyZWFkLnNsZWVwKHRpbWVvdXQgKiAyKTsKICAgICBhc3NlcnRFcXVhbHMoIk1vZGlmaWVkIG1ldGhvZCBvZiAiICsgTU9EX05PVFNFVF9OUzEwMCArICIgc2hvdWxkIG5vdCBiZSBjYWxsZWQiLCAwLCAoMSA8PCAwKQogICAgICAgICAmIGdldEJhc2VDb25maWdEYXRhKGJzKSk7CkBAIC0yMzA4LDEyICsyMzE5LDEyIEBACiAKICAgICBIYXNodGFibGUgcHJvcHMgPSBuZXcgSGFzaHRhYmxlKDEwKTsKICAgICBwcm9wcy5wdXQoImNvbmZpZy5kdW1teS5kYXRhIiwgSW50ZWdlci52YWx1ZU9mKDEpKTsKLSAgICBjbS5nZXRDb25maWd1cmF0aW9uKE1PRF9OT1RTRVRfTlMxMTApLnVwZGF0ZShwcm9wcyk7Ci0gICAgY20uZ2V0Q29uZmlndXJhdGlvbihNT0RfTk9BUkdTX05TMTEwKS51cGRhdGUocHJvcHMpOwotICAgIGNtLmdldENvbmZpZ3VyYXRpb24oTU9EX0NDX05TMTEwKS51cGRhdGUocHJvcHMpOwotICAgIGNtLmdldENvbmZpZ3VyYXRpb24oTU9EX0JDX05TMTEwKS51cGRhdGUocHJvcHMpOwotICAgIGNtLmdldENvbmZpZ3VyYXRpb24oTU9EX01BUF9OUzExMCkudXBkYXRlKHByb3BzKTsKLSAgICBjbS5nZXRDb25maWd1cmF0aW9uKE1PRF9DQ19CQ19NQVBfTlMxMTApLnVwZGF0ZShwcm9wcyk7CisgICAgY20uZ2V0Q29uZmlndXJhdGlvbihNT0RfTk9UU0VUX05TMTEwLCBudWxsKS51cGRhdGUocHJvcHMpOworICAgIGNtLmdldENvbmZpZ3VyYXRpb24oTU9EX05PQVJHU19OUzExMCwgbnVsbCkudXBkYXRlKHByb3BzKTsKKyAgICBjbS5nZXRDb25maWd1cmF0aW9uKE1PRF9DQ19OUzExMCwgbnVsbCkudXBkYXRlKHByb3BzKTsKKyAgICBjbS5nZXRDb25maWd1cmF0aW9uKE1PRF9CQ19OUzExMCwgbnVsbCkudXBkYXRlKHByb3BzKTsKKyAgICBjbS5nZXRDb25maWd1cmF0aW9uKE1PRF9NQVBfTlMxMTAsIG51bGwpLnVwZGF0ZShwcm9wcyk7CisgICAgY20uZ2V0Q29uZmlndXJhdGlvbihNT0RfQ0NfQkNfTUFQX05TMTEwLCBudWxsKS51cGRhdGUocHJvcHMpOwogCiAgICAgVGhyZWFkLnNsZWVwKHRpbWVvdXQgKiAyKTsKIApAQCAtMjMyNSwxNCArMjMzNiwxNCBAQAogICAgIHVuc2F0aXNmeWluZ1Byb3BzLnB1dCgicmVmLnRhcmdldCIsICIoY29tcG9uZW50Lm5hbWU9b3JnLmVjbGlwc2UuZXF1aW5veC5kcy50ZXN0cy50YjIxLnVuZXhpc3RpbmcucHJvdmlkZXIpIik7CiAKICAgICBQcm9wZXJ0aWVzUHJvdmlkZXIgYnMgPSBnZXRCYXNlU2VydmljZShNT0RfTk9UU0VUX05TMTEwKTsKLSAgICBjbS5nZXRDb25maWd1cmF0aW9uKE1PRF9OT1RTRVRfTlMxMTApLnVwZGF0ZShwcm9wcyk7CisgICAgY20uZ2V0Q29uZmlndXJhdGlvbihNT0RfTk9UU0VUX05TMTEwLCBudWxsKS51cGRhdGUocHJvcHMpOwogICAgIFRocmVhZC5zbGVlcCh0aW1lb3V0ICogMik7CiAgICAgYXNzZXJ0RXF1YWxzKCJNb2RpZmllZCBtZXRob2Qgb2YgIiArIE1PRF9OT1RTRVRfTlMxMTAgKyAiIHNob3VsZCBub3QgYmUgY2FsbGVkIiwgMCwgKDEgPDwgMCkKICAgICAgICAgJiBnZXRCYXNlQ29uZmlnRGF0YShicykpOwogICAgIGFzc2VydEVxdWFscygiRGVhY3RpdmF0ZSBtZXRob2Qgb2YgIiArIE1PRF9OT1RTRVRfTlMxMTAgKyAiIHNob3VsZCBiZSBjYWxsZWQiLCAxIDw8IDcsICgxIDw8IDcpCiAgICAgICAgICYgZ2V0QmFzZUNvbmZpZ0RhdGEoYnMpKTsKICAgICBicyA9IGdldEJhc2VTZXJ2aWNlKE1PRF9OT1RTRVRfTlMxMTApOwotICAgIGNtLmdldENvbmZpZ3VyYXRpb24oTU9EX05PVFNFVF9OUzExMCkudXBkYXRlKHVuc2F0aXNmeWluZ1Byb3BzKTsKKyAgICBjbS5nZXRDb25maWd1cmF0aW9uKE1PRF9OT1RTRVRfTlMxMTAsIG51bGwpLnVwZGF0ZSh1bnNhdGlzZnlpbmdQcm9wcyk7CiAgICAgVGhyZWFkLnNsZWVwKHRpbWVvdXQgKiAyKTsKICAgICBhc3NlcnRFcXVhbHMoIk1vZGlmaWVkIG1ldGhvZCBvZiAiICsgTU9EX05PVFNFVF9OUzExMCArICIgc2hvdWxkIG5vdCBiZSBjYWxsZWQiLCAwLCAoMSA8PCAwKQogICAgICAgICAmIGdldEJhc2VDb25maWdEYXRhKGJzKSk7CkBAIC0yMzQ0LDEzICsyMzU1LDEzIEBACiAgICAgICAgICYgZ2V0QmFzZUNvbmZpZ0RhdGEoYnMpKTsKIAogICAgIGJzID0gZ2V0QmFzZVNlcnZpY2UoTU9EX05PQVJHU19OUzExMCk7Ci0gICAgY20uZ2V0Q29uZmlndXJhdGlvbihNT0RfTk9BUkdTX05TMTEwKS51cGRhdGUocHJvcHMpOworICAgIGNtLmdldENvbmZpZ3VyYXRpb24oTU9EX05PQVJHU19OUzExMCwgbnVsbCkudXBkYXRlKHByb3BzKTsKICAgICBUaHJlYWQuc2xlZXAodGltZW91dCAqIDIpOwogICAgIGFzc2VydEVxdWFscygiTW9kaWZpZWQgbWV0aG9kIG9mICIgKyBNT0RfTk9BUkdTX05TMTEwICsgIiBzaG91bGQgYmUgY2FsbGVkIiwgMSA8PCAxLCAoMSA8PCAxKQogICAgICAgICAmIGdldEJhc2VDb25maWdEYXRhKGJzKSk7CiAgICAgYXNzZXJ0RXF1YWxzKCJEZWFjdGl2YXRlIG1ldGhvZCBvZiAiICsgTU9EX05PQVJHU19OUzExMCArICIgc2hvdWxkIG5vdCBiZSBjYWxsZWQiLCAwLCAoMSA8PCA3KQogICAgICAgICAmIGdldEJhc2VDb25maWdEYXRhKGJzKSk7Ci0gICAgY20uZ2V0Q29uZmlndXJhdGlvbihNT0RfTk9BUkdTX05TMTEwKS51cGRhdGUodW5zYXRpc2Z5aW5nUHJvcHMpOworICAgIGNtLmdldENvbmZpZ3VyYXRpb24oTU9EX05PQVJHU19OUzExMCwgbnVsbCkudXBkYXRlKHVuc2F0aXNmeWluZ1Byb3BzKTsKICAgICBUaHJlYWQuc2xlZXAodGltZW91dCAqIDIpOwogICAgIGFzc2VydEVxdWFscygiRGVhY3RpdmF0ZSBtZXRob2Qgb2YgIiArIE1PRF9OT0FSR1NfTlMxMTAgKyAiIHNob3VsZCBiZSBjYWxsZWQiLCAxIDw8IDcsICgxIDw8IDcpCiAgICAgICAgICYgZ2V0QmFzZUNvbmZpZ0RhdGEoYnMpKTsKQEAgLTIzNjAsMTEgKzIzNzEsMTEgQEAKICAgICAgICAgJiBnZXRCYXNlQ29uZmlnRGF0YShicykpOwogCiAgICAgYnMgPSBnZXRCYXNlU2VydmljZShNT0RfQ0NfTlMxMTApOwotICAgIGNtLmdldENvbmZpZ3VyYXRpb24oTU9EX0NDX05TMTEwKS51cGRhdGUocHJvcHMpOworICAgIGNtLmdldENvbmZpZ3VyYXRpb24oTU9EX0NDX05TMTEwLCBudWxsKS51cGRhdGUocHJvcHMpOwogICAgIFRocmVhZC5zbGVlcCh0aW1lb3V0ICogMik7CiAgICAgYXNzZXJ0RXF1YWxzKCJNb2RpZmllZCBtZXRob2Qgb2YgIiArIE1PRF9DQ19OUzExMCArICIgc2hvdWxkIGJlIGNhbGxlZCIsIDEgPDwgMiwgKDEgPDwgMikgJiBnZXRCYXNlQ29uZmlnRGF0YShicykpOwogICAgIGFzc2VydEVxdWFscygiRGVhY3RpdmF0ZSBtZXRob2Qgb2YgIiArIE1PRF9DQ19OUzExMCArICIgc2hvdWxkIG5vdCBiZSBjYWxsZWQiLCAwLCAoMSA8PCA3KSAmIGdldEJhc2VDb25maWdEYXRhKGJzKSk7Ci0gICAgY20uZ2V0Q29uZmlndXJhdGlvbihNT0RfQ0NfTlMxMTApLnVwZGF0ZSh1bnNhdGlzZnlpbmdQcm9wcyk7CisgICAgY20uZ2V0Q29uZmlndXJhdGlvbihNT0RfQ0NfTlMxMTAsIG51bGwpLnVwZGF0ZSh1bnNhdGlzZnlpbmdQcm9wcyk7CiAgICAgVGhyZWFkLnNsZWVwKHRpbWVvdXQgKiAyKTsKICAgICBhc3NlcnRFcXVhbHMoIkRlYWN0aXZhdGUgbWV0aG9kIG9mICIgKyBNT0RfQ0NfTlMxMTAgKyAiIHNob3VsZCBiZSBjYWxsZWQiLCAxIDw8IDcsICgxIDw8IDcpICYgZ2V0QmFzZUNvbmZpZ0RhdGEoYnMpKTsKICAgICAvLyBSZS1hY3RpdmF0aW5nCkBAIC0yMzcyLDExICsyMzgzLDExIEBACiAgICAgYXNzZXJ0RXF1YWxzKCJBY3RpdmF0ZSBtZXRob2Qgb2YgIiArIE1PRF9DQ19OUzExMCArICIgc2hvdWxkIGJlIGNhbGxlZCIsIDEgPDwgNiwgKDEgPDwgNikgJiBnZXRCYXNlQ29uZmlnRGF0YShicykpOwogCiAgICAgYnMgPSBnZXRCYXNlU2VydmljZShNT0RfQkNfTlMxMTApOwotICAgIGNtLmdldENvbmZpZ3VyYXRpb24oTU9EX0JDX05TMTEwKS51cGRhdGUocHJvcHMpOworICAgIGNtLmdldENvbmZpZ3VyYXRpb24oTU9EX0JDX05TMTEwLCBudWxsKS51cGRhdGUocHJvcHMpOwogICAgIFRocmVhZC5zbGVlcCh0aW1lb3V0ICogMik7CiAgICAgYXNzZXJ0RXF1YWxzKCJNb2RpZmllZCBtZXRob2Qgb2YgIiArIE1PRF9CQ19OUzExMCArICIgc2hvdWxkIGJlIGNhbGxlZCIsIDEgPDwgMywgKDEgPDwgMykgJiBnZXRCYXNlQ29uZmlnRGF0YShicykpOwogICAgIGFzc2VydEVxdWFscygiRGVhY3RpdmF0ZSBtZXRob2Qgb2YgIiArIE1PRF9CQ19OUzExMCArICIgc2hvdWxkIG5vdCBiZSBjYWxsZWQiLCAwLCAoMSA8PCA3KSAmIGdldEJhc2VDb25maWdEYXRhKGJzKSk7Ci0gICAgY20uZ2V0Q29uZmlndXJhdGlvbihNT0RfQkNfTlMxMTApLnVwZGF0ZSh1bnNhdGlzZnlpbmdQcm9wcyk7CisgICAgY20uZ2V0Q29uZmlndXJhdGlvbihNT0RfQkNfTlMxMTAsIG51bGwpLnVwZGF0ZSh1bnNhdGlzZnlpbmdQcm9wcyk7CiAgICAgVGhyZWFkLnNsZWVwKHRpbWVvdXQgKiAyKTsKICAgICBhc3NlcnRFcXVhbHMoIkRlYWN0aXZhdGUgbWV0aG9kIG9mICIgKyBNT0RfQkNfTlMxMTAgKyAiIHNob3VsZCBiZSBjYWxsZWQiLCAxIDw8IDcsICgxIDw8IDcpICYgZ2V0QmFzZUNvbmZpZ0RhdGEoYnMpKTsKICAgICAvLyBSZS1hY3RpdmF0aW5nCkBAIC0yMzg0LDExICsyMzk1LDExIEBACiAgICAgYXNzZXJ0RXF1YWxzKCJBY3RpdmF0ZSBtZXRob2Qgb2YgIiArIE1PRF9CQ19OUzExMCArICIgc2hvdWxkIGJlIGNhbGxlZCIsIDEgPDwgNiwgKDEgPDwgNikgJiBnZXRCYXNlQ29uZmlnRGF0YShicykpOwogCiAgICAgYnMgPSBnZXRCYXNlU2VydmljZShNT0RfTUFQX05TMTEwKTsKLSAgICBjbS5nZXRDb25maWd1cmF0aW9uKE1PRF9NQVBfTlMxMTApLnVwZGF0ZShwcm9wcyk7CisgICAgY20uZ2V0Q29uZmlndXJhdGlvbihNT0RfTUFQX05TMTEwLCBudWxsKS51cGRhdGUocHJvcHMpOwogICAgIFRocmVhZC5zbGVlcCh0aW1lb3V0ICogMik7CiAgICAgYXNzZXJ0RXF1YWxzKCJNb2RpZmllZCBtZXRob2Qgb2YgIiArIE1PRF9NQVBfTlMxMTAgKyAiIHNob3VsZCBiZSBjYWxsZWQiLCAxIDw8IDQsICgxIDw8IDQpICYgZ2V0QmFzZUNvbmZpZ0RhdGEoYnMpKTsKICAgICBhc3NlcnRFcXVhbHMoIkRlYWN0aXZhdGUgbWV0aG9kIG9mICIgKyBNT0RfTUFQX05TMTEwICsgIiBzaG91bGQgbm90IGJlIGNhbGxlZCIsIDAsICgxIDw8IDcpICYgZ2V0QmFzZUNvbmZpZ0RhdGEoYnMpKTsKLSAgICBjbS5nZXRDb25maWd1cmF0aW9uKE1PRF9NQVBfTlMxMTApLnVwZGF0ZSh1bnNhdGlzZnlpbmdQcm9wcyk7CisgICAgY20uZ2V0Q29uZmlndXJhdGlvbihNT0RfTUFQX05TMTEwLCBudWxsKS51cGRhdGUodW5zYXRpc2Z5aW5nUHJvcHMpOwogICAgIFRocmVhZC5zbGVlcCh0aW1lb3V0ICogMik7CiAgICAgYXNzZXJ0RXF1YWxzKCJEZWFjdGl2YXRlIG1ldGhvZCBvZiAiICsgTU9EX01BUF9OUzExMCArICIgc2hvdWxkIGJlIGNhbGxlZCIsIDEgPDwgNywgKDEgPDwgNykKICAgICAgICAgJiBnZXRCYXNlQ29uZmlnRGF0YShicykpOwpAQCAtMjM5NywxMyArMjQwOCwxMyBAQAogICAgIGFzc2VydEVxdWFscygiQWN0aXZhdGUgbWV0aG9kIG9mICIgKyBNT0RfTUFQX05TMTEwICsgIiBzaG91bGQgYmUgY2FsbGVkIiwgMSA8PCA2LCAoMSA8PCA2KSAmIGdldEJhc2VDb25maWdEYXRhKGJzKSk7CiAKICAgICBicyA9IGdldEJhc2VTZXJ2aWNlKE1PRF9DQ19CQ19NQVBfTlMxMTApOwotICAgIGNtLmdldENvbmZpZ3VyYXRpb24oTU9EX0NDX0JDX01BUF9OUzExMCkudXBkYXRlKHByb3BzKTsKKyAgICBjbS5nZXRDb25maWd1cmF0aW9uKE1PRF9DQ19CQ19NQVBfTlMxMTAsIG51bGwpLnVwZGF0ZShwcm9wcyk7CiAgICAgVGhyZWFkLnNsZWVwKHRpbWVvdXQgKiAyKTsKICAgICBhc3NlcnRFcXVhbHMoIk1vZGlmaWVkIG1ldGhvZCBvZiAiICsgTU9EX0NDX0JDX01BUF9OUzExMCArICIgc2hvdWxkIGJlIGNhbGxlZCIsIDEgPDwgNSwgKDEgPDwgNSkKICAgICAgICAgJiBnZXRCYXNlQ29uZmlnRGF0YShicykpOwogICAgIGFzc2VydEVxdWFscygiRGVhY3RpdmF0ZSBtZXRob2Qgb2YgIiArIE1PRF9DQ19CQ19NQVBfTlMxMTAgKyAiIHNob3VsZCBub3QgYmUgY2FsbGVkIiwgMCwgKDEgPDwgNykKICAgICAgICAgJiBnZXRCYXNlQ29uZmlnRGF0YShicykpOwotICAgIGNtLmdldENvbmZpZ3VyYXRpb24oTU9EX0NDX0JDX01BUF9OUzExMCkudXBkYXRlKHVuc2F0aXNmeWluZ1Byb3BzKTsKKyAgICBjbS5nZXRDb25maWd1cmF0aW9uKE1PRF9DQ19CQ19NQVBfTlMxMTAsIG51bGwpLnVwZGF0ZSh1bnNhdGlzZnlpbmdQcm9wcyk7CiAgICAgVGhyZWFkLnNsZWVwKHRpbWVvdXQgKiAyKTsKICAgICBhc3NlcnRFcXVhbHMoIkRlYWN0aXZhdGUgbWV0aG9kIG9mICIgKyBNT0RfQ0NfQkNfTUFQX05TMTEwICsgIiBzaG91bGQgYmUgY2FsbGVkIiwgMSA8PCA3LCAoMSA8PCA3KQogICAgICAgICAmIGdldEJhc2VDb25maWdEYXRhKGJzKSk7CkBAIC0yNDI2LDEwICsyNDM3LDEwIEBACiAKICAgICBIYXNodGFibGUgcHJvcHMgPSBuZXcgSGFzaHRhYmxlKDEwKTsKICAgICBwcm9wcy5wdXQoImNvbmZpZy5kdW1teS5kYXRhIiwgSW50ZWdlci52YWx1ZU9mKDEpKTsKLSAgICBjbS5nZXRDb25maWd1cmF0aW9uKE1PRF9DQ19OUzExMCkudXBkYXRlKHByb3BzKTsKLSAgICBjbS5nZXRDb25maWd1cmF0aW9uKE1PRF9OT1RfRVhJU1RfTlMxMTApLnVwZGF0ZShwcm9wcyk7Ci0gICAgY20uZ2V0Q29uZmlndXJhdGlvbihNT0RfVEhST1dfRVhfTlMxMTApLnVwZGF0ZShwcm9wcyk7Ci0gICAgY20uZ2V0Q29uZmlndXJhdGlvbihNT0RfQkNfTlMxMTApLnVwZGF0ZShwcm9wcyk7CisgICAgY20uZ2V0Q29uZmlndXJhdGlvbihNT0RfQ0NfTlMxMTAsIG51bGwpLnVwZGF0ZShwcm9wcyk7CisgICAgY20uZ2V0Q29uZmlndXJhdGlvbihNT0RfTk9UX0VYSVNUX05TMTEwLCBudWxsKS51cGRhdGUocHJvcHMpOworICAgIGNtLmdldENvbmZpZ3VyYXRpb24oTU9EX1RIUk9XX0VYX05TMTEwLCBudWxsKS51cGRhdGUocHJvcHMpOworICAgIGNtLmdldENvbmZpZ3VyYXRpb24oTU9EX0JDX05TMTEwLCBudWxsKS51cGRhdGUocHJvcHMpOwogICAgIFRocmVhZC5zbGVlcCh0aW1lb3V0ICogMik7CiAKICAgICB0YjIxYS5zdGFydCgpOwpAQCAtMjQzOCw3ICsyNDQ5LDcgQEAKICAgICAvLyBWZXJpZnlpbmcgY29ycmVjdG5lc3Mgb2YgdXBkYXRlZCBjb21wb25lbnQgcHJvcGVydGllcwogICAgIFByb3BlcnRpZXNQcm92aWRlciBicyA9IGdldEJhc2VTZXJ2aWNlKE1PRF9DQ19OUzExMCk7CiAgICAgcHJvcHMucHV0KCJjb25maWcuZHVtbXkuZGF0YSIsIEludGVnZXIudmFsdWVPZigyKSk7Ci0gICAgY20uZ2V0Q29uZmlndXJhdGlvbihNT0RfQ0NfTlMxMTApLnVwZGF0ZShwcm9wcyk7CisgICAgY20uZ2V0Q29uZmlndXJhdGlvbihNT0RfQ0NfTlMxMTAsIG51bGwpLnVwZGF0ZShwcm9wcyk7CiAgICAgVGhyZWFkLnNsZWVwKHRpbWVvdXQgKiAyKTsKICAgICBPYmplY3QgdmFsID0gKChDb21wb25lbnRDb250ZXh0UHJvdmlkZXIpIGJzKS5nZXRDb21wb25lbnRDb250ZXh0KCkuZ2V0UHJvcGVydGllcygpLmdldCgiY29uZmlnLmR1bW15LmRhdGEiKTsKICAgICBhc3NlcnRFcXVhbHMoIk1vZGlmaWVkIG1ldGhvZCBvZiAiICsgTU9EX0NDX05TMTEwICsgIiBzaG91bGQgYmUgY2FsbGVkIiwgMSA8PCAyLCAoMSA8PCAyKSAmIGdldEJhc2VDb25maWdEYXRhKGJzKSk7CkBAIC0yNDQ3LDcgKzI0NTgsNyBAQAogICAgIC8vIFNwZWNpZmllZCBtb2RpZmllZCBtZXRob2QgZG9lc24ndCBleGlzdCwgZGVhY3RpdmF0ZSgpIHNob3VsZCBiZSBjYWxsZWQKICAgICAvLyBpbnN0ZWFkIG9mIG1vZGlmaWVkCiAgICAgYnMgPSBnZXRCYXNlU2VydmljZShNT0RfTk9UX0VYSVNUX05TMTEwKTsKLSAgICBjbS5nZXRDb25maWd1cmF0aW9uKE1PRF9OT1RfRVhJU1RfTlMxMTApLnVwZGF0ZShwcm9wcyk7CisgICAgY20uZ2V0Q29uZmlndXJhdGlvbihNT0RfTk9UX0VYSVNUX05TMTEwLCBudWxsKS51cGRhdGUocHJvcHMpOwogICAgIFRocmVhZC5zbGVlcCh0aW1lb3V0ICogMik7CiAgICAgYXNzZXJ0RXF1YWxzKCJEZWFjdGl2YXRlIG1ldGhvZCBvZiAiICsgTU9EX05PVF9FWElTVF9OUzExMCArICIgc2hvdWxkIGJlIGNhbGxlZCIsIDEgPDwgNywgKDEgPDwgNykKICAgICAgICAgJiBnZXRCYXNlQ29uZmlnRGF0YShicykpOwpAQCAtMjQ1OSwxNCArMjQ3MCwxNCBAQAogICAgIC8vIFNwZWNpZmllZCBtb2RpZmllZCBtZXRob2QgdGhyb3dzIGV4Y2VwdGlvbi4gTm9ybWFsIHdvcmtmbG93IHNob3VsZAogICAgIC8vIGNvbnRpbnVlLCBkZWFjdGl2YXRlKCkgc2hvdWxkIG5vdCBiZSBjYWxsZWQKICAgICBicyA9IGdldEJhc2VTZXJ2aWNlKE1PRF9USFJPV19FWF9OUzExMCk7Ci0gICAgY20uZ2V0Q29uZmlndXJhdGlvbihNT0RfVEhST1dfRVhfTlMxMTApLnVwZGF0ZShwcm9wcyk7CisgICAgY20uZ2V0Q29uZmlndXJhdGlvbihNT0RfVEhST1dfRVhfTlMxMTAsIG51bGwpLnVwZGF0ZShwcm9wcyk7CiAgICAgVGhyZWFkLnNsZWVwKHRpbWVvdXQgKiAyKTsKICAgICBhc3NlcnRFcXVhbHMoIkRlYWN0aXZhdGUgbWV0aG9kIG9mICIgKyBNT0RfVEhST1dfRVhfTlMxMTAgKyAiIHNob3VsZCBub3QgYmUgY2FsbGVkIiwgMCwgKDEgPDwgNykKICAgICAgICAgJiBnZXRCYXNlQ29uZmlnRGF0YShicykpOwogCiAgICAgLy8gRGVsZXRpbmcgY29tcG9uZW50IGNvbmZpZ3VyYXRpb24KICAgICBicyA9IGdldEJhc2VTZXJ2aWNlKE1PRF9CQ19OUzExMCk7Ci0gICAgY20uZ2V0Q29uZmlndXJhdGlvbihNT0RfQkNfTlMxMTApLmRlbGV0ZSgpOworICAgIGNtLmdldENvbmZpZ3VyYXRpb24oTU9EX0JDX05TMTEwLCBudWxsKS5kZWxldGUoKTsKICAgICBUaHJlYWQuc2xlZXAodGltZW91dCAqIDIpOwogICAgIGFzc2VydEVxdWFscygiTW9kaWZpZWQgbWV0aG9kIG9mICIgKyBNT0RfQkNfTlMxMTAgKyAiIHNob3VsZCBub3QgYmUgY2FsbGVkIiwgMCwgKDEgPDwgNSkgJiBnZXRCYXNlQ29uZmlnRGF0YShicykpOwogICAgIGFzc2VydEVxdWFscygiRGVhY3RpdmF0ZSBtZXRob2Qgb2YgIiArIE1PRF9CQ19OUzExMCArICIgc2hvdWxkIGJlIGNhbGxlZCIsIDEgPDwgNywgKDEgPDwgNykgJiBnZXRCYXNlQ29uZmlnRGF0YShicykpOwpAQCAtMjUwNiw3ICsyNTE3LDcgQEAKICAgICB3YWl0QnVuZGxlU3RhcnQoKTsKIAogICAgIFByb3BlcnRpZXNQcm92aWRlciBicyA9IGdldEJhc2VTZXJ2aWNlKE1BTkRBVE9SWV9SRUZfQ09NUCk7Ci0gICAgYXNzZXJ0RXF1YWxzKCJDb21wb25lbnQgIiArIE1BTkRBVE9SWV9SRUZfQ09NUCArICIgc2hvdWxkIG5vdCBiZSBhY3RpdmF0ZWQiLCBudWxsLCBicyk7CisgICAgYXNzZXJ0Tm90TnVsbCgiQ29tcG9uZW50ICIgKyBNQU5EQVRPUllfUkVGX0NPTVAgKyAiIHNob3VsZCBub3QgYmUgYWN0aXZhdGVkIiwgYnMpOwogICAgIGJzID0gZ2V0QmFzZVNlcnZpY2UoT1BUSU9OQUxfUkVGX0NPTVApOwogICAgIGFzc2VydEVxdWFscygiQ29tcG9uZW50ICIgKyBPUFRJT05BTF9SRUZfQ09NUCArICIgc2hvdWxkIGJlIGFjdGl2YXRlZCIsIDEgPDwgMiwgKDEgPDwgMikgJiBnZXRCYXNlQ29uZmlnRGF0YShicykpOwogCkBAIC0yNTIzLDExICsyNTM0LDExIEBACiAgICAgSGFzaHRhYmxlIHByb3BzID0gbmV3IEhhc2h0YWJsZSgxMSk7CiAgICAgcHJvcHMucHV0KCJjb25maWcuYmFzZS5kYXRhIiwgSW50ZWdlci52YWx1ZU9mKDEpKTsKICAgICAvL2NyZWF0ZSB0aGUgY29uZmlndXJhdGlvbnMgZm9yIHRoZSB0ZXN0IERTIGNvbXBvbmVudHMKLSAgICBDb25maWd1cmF0aW9uIGNvbmZpZyA9IGNtLmdldENvbmZpZ3VyYXRpb24oQ09NUF9PUFRJT05BTCk7CisgICAgQ29uZmlndXJhdGlvbiBjb25maWcgPSBjbS5nZXRDb25maWd1cmF0aW9uKENPTVBfT1BUSU9OQUwsIG51bGwpOwogICAgIGNvbmZpZy51cGRhdGUocHJvcHMpOwotICAgIGNvbmZpZyA9IGNtLmdldENvbmZpZ3VyYXRpb24oQ09NUF9SRVFVSVJFKTsKKyAgICBjb25maWcgPSBjbS5nZXRDb25maWd1cmF0aW9uKENPTVBfUkVRVUlSRSwgbnVsbCk7CiAgICAgY29uZmlnLnVwZGF0ZShwcm9wcyk7Ci0gICAgY29uZmlnID0gY20uZ2V0Q29uZmlndXJhdGlvbihDT01QX0lHTk9SRSk7CisgICAgY29uZmlnID0gY20uZ2V0Q29uZmlndXJhdGlvbihDT01QX0lHTk9SRSwgbnVsbCk7CiAgICAgY29uZmlnLnVwZGF0ZShwcm9wcyk7CiAgICAgLy93YWl0IGZvciBDTSB0byBwcm9jZXNzIHRoZSBjb25maWd1cmF0aW9uIHVwZGF0ZXMKICAgICBUaHJlYWQuc2xlZXAodGltZW91dCAqIDIpOwpAQCAtMjg2MCw3ICsyODcxLDcgQEAKICAgICAgIGZpbmFsIFN0cmluZyBQUk9QID0gInRlc3QucHJvcGVydHkiOwogCiAgICAgICAvLyBzZXQgY29tcG9uZW50IGNvbmZpZ3VyYXRpb24KLSAgICAgIGNvbmZpZyA9IGNtLmdldENvbmZpZ3VyYXRpb24oQ09ORklHX1BJRCk7CisgICAgICBjb25maWcgPSBjbS5nZXRDb25maWd1cmF0aW9uKENPTkZJR19QSUQsIG51bGwpOwogICAgICAgRGljdGlvbmFyeSBjb25maWdQcm9wZXJ0aWVzID0gY29uZmlnLmdldFByb3BlcnRpZXMoKTsKICAgICAgIGlmIChjb25maWdQcm9wZXJ0aWVzID09IG51bGwpIHsKICAgICAgICAgY29uZmlnUHJvcGVydGllcyA9IG5ldyBIYXNodGFibGUoKTsKZGlmZiAtLWdpdCBhL2J1bmRsZXMvb3JnLmVjbGlwc2UuZXF1aW5veC5kcy8uY2xhc3NwYXRoIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5lcXVpbm94LmRzLy5jbGFzc3BhdGgKaW5kZXggYmUxZWYzOS4uYWQzMmM4MyAxMDA2NDQKLS0tIGEvYnVuZGxlcy9vcmcuZWNsaXBzZS5lcXVpbm94LmRzLy5jbGFzc3BhdGgKKysrIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5lcXVpbm94LmRzLy5jbGFzc3BhdGgKQEAgLTEsNyArMSw3IEBACiA8P3htbCB2ZXJzaW9uPSIxLjAiIGVuY29kaW5nPSJVVEYtOCI/PgogPGNsYXNzcGF0aD4KLQk8Y2xhc3NwYXRoZW50cnkga2luZD0ic3JjIiBwYXRoPSJzcmMiLz4KLQk8Y2xhc3NwYXRoZW50cnkga2luZD0iY29uIiBwYXRoPSJvcmcuZWNsaXBzZS5qZHQubGF1bmNoaW5nLkpSRV9DT05UQUlORVIvb3JnLmVjbGlwc2UuamR0LmludGVybmFsLmRlYnVnLnVpLmxhdW5jaGVyLlN0YW5kYXJkVk1UeXBlL09TR2klTWluaW11bS0xLjIiLz4KKwk8Y2xhc3NwYXRoZW50cnkga2luZD0iY29uIiBwYXRoPSJvcmcuZWNsaXBzZS5qZHQubGF1bmNoaW5nLkpSRV9DT05UQUlORVIvb3JnLmVjbGlwc2UuamR0LmludGVybmFsLmRlYnVnLnVpLmxhdW5jaGVyLlN0YW5kYXJkVk1UeXBlL0phdmFTRS0xLjYiLz4KIAk8Y2xhc3NwYXRoZW50cnkga2luZD0iY29uIiBwYXRoPSJvcmcuZWNsaXBzZS5wZGUuY29yZS5yZXF1aXJlZFBsdWdpbnMiLz4KKwk8Y2xhc3NwYXRoZW50cnkga2luZD0ic3JjIiBwYXRoPSJzcmMiLz4KIAk8Y2xhc3NwYXRoZW50cnkga2luZD0ib3V0cHV0IiBwYXRoPSJiaW4iLz4KIDwvY2xhc3NwYXRoPgpkaWZmIC0tZ2l0IGEvYnVuZGxlcy9vcmcuZWNsaXBzZS5lcXVpbm94LmRzLy5vcHRpb25zIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5lcXVpbm94LmRzLy5vcHRpb25zCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAyODhhZmJmLi4wMDAwMDAwCi0tLSBhL2J1bmRsZXMvb3JnLmVjbGlwc2UuZXF1aW5veC5kcy8ub3B0aW9ucworKysgL2Rldi9udWxsCkBAIC0xLDE2ICswLDAgQEAKLSMgRGVidWdnaW5nIG9wdGlvbnMgZm9yIHRoZSBvcmcuZWNsaXBzZS5lcXVpbm94LmRzIHBsdWdpbgotCi0jIFR1cm5zIG9uL29mZiBkZWJ1Z2dpbmcgb2YgU0NSCi1vcmcuZWNsaXBzZS5lcXVpbm94LmRzL2RlYnVnPWZhbHNlCi0jIFNwZWNpZmllcyB0aGF0IGxvZ2dlZCBlbnRyaWVzIHNob3VsZCBiZSBwcmludGVkIHRvIHRoZSBmcmFtZXdvcmsgcnVudGltZSBjb25zb2xlIAotb3JnLmVjbGlwc2UuZXF1aW5veC5kcy9wcmludF9vbl9jb25zb2xlPWZhbHNlCi0jIEVuYWJsZXMgZ2VuZXJhdGluZyBhbmQgcHJpbnRpbmcgbG9ncyBhYm91dCB0aGUgdGltZSBwZXJmb3JtYW5jZSBvZiB0aGUgb3BlcmF0aW9ucyBleGVjdXRlZCBieSB0aGUgU0NSCi1vcmcuZWNsaXBzZS5lcXVpbm94LmRzL3BlcmZvcm1hbmNlPWZhbHNlCi0jIE1ha2VzIGluc3RhbmNlIG9mIGVhY2ggY29tcG9uZW50IG5ldmVydGhlbGVzcyBjb21wb25lbnRzIGFyZSAiaW1tZWRpYXRlIiBvciBub3QKLW9yZy5lY2xpcHNlLmVxdWlub3guZHMvaW5zdGFudGlhdGVfYWxsPWZhbHNlCi0KLSNBZHZhbmNlZCBvcHRpb25zIAotIyBFbmFibGVzIGNhY2hpbmcgb2YgdGhlIHBhcnNlZCBYTUwgZG9jdW1lbnRzIG9mIHRoZSBjb21wb25lbnQgZGVzY3JpcHRpb25zCi0jb3JnLmVjbGlwc2UuZXF1aW5veC5kcy9jYWNoZV9kZXNjcmlwdGlvbnM9ZmFsc2UKLSMgU3BlY2lmaWVzIHRoZSBtYXhpbXVtIHRpbWUgaW4gbWlsbGlzZWNvbmRzLCB3aGljaCBpcyBhbGxvd2VkIHRvIGEgdXNlciBjb21wb25lbnQncyBhY3RpdmF0ZSBvciBiaW5kIG1ldGhvZCB0byB0YWtlLiBJZiB0aGUgbWV0aG9kIGludm9jYXRpb24gaGFzIG5vdCBmaW5pc2hlZCwgYSBuZXcgZGlzcGF0Y2hlciB0aHJlYWQgd2lsbCBiZSBsYXVuY2hlZCB0byBwcm9jZXNzIHRoZSBwZW5kaW5nIHdvcmsgb2YgU0NSIAotI29yZy5lY2xpcHNlLmVxdWlub3guZHMvYmxvY2tfdGltZW91dD0zMDAwMApkaWZmIC0tZ2l0IGEvYnVuZGxlcy9vcmcuZWNsaXBzZS5lcXVpbm94LmRzLy5zZXR0aW5ncy8uYXBpX2ZpbHRlcnMgYi9idW5kbGVzL29yZy5lY2xpcHNlLmVxdWlub3guZHMvLnNldHRpbmdzLy5hcGlfZmlsdGVycwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xYzMxMjFmCi0tLSAvZGV2L251bGwKKysrIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5lcXVpbm94LmRzLy5zZXR0aW5ncy8uYXBpX2ZpbHRlcnMKQEAgLTAsMCArMSwzNSBAQAorPD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+Cis8Y29tcG9uZW50IGlkPSJvcmcuZWNsaXBzZS5lcXVpbm94LmRzIiB2ZXJzaW9uPSIyIj4KKyAgICA8cmVzb3VyY2UgcGF0aD0iTUVUQS1JTkYvTUFOSUZFU1QuTUYiPgorICAgICAgICA8ZmlsdGVyIGlkPSI5MjM3OTU0NjEiPgorICAgICAgICAgICAgPG1lc3NhZ2VfYXJndW1lbnRzPgorICAgICAgICAgICAgICAgIDxtZXNzYWdlX2FyZ3VtZW50IHZhbHVlPSIxLjUuMCIvPgorICAgICAgICAgICAgICAgIDxtZXNzYWdlX2FyZ3VtZW50IHZhbHVlPSIxLjQuNDAwIi8+CisgICAgICAgICAgICA8L21lc3NhZ2VfYXJndW1lbnRzPgorICAgICAgICA8L2ZpbHRlcj4KKyAgICA8L3Jlc291cmNlPgorICAgIDxyZXNvdXJjZSBwYXRoPSJNRVRBLUlORi9NQU5JRkVTVC5NRiIgdHlwZT0ib3JnLmFwYWNoZS5mZWxpeC5zY3IuQ29tcG9uZW50Ij4KKyAgICAgICAgPGZpbHRlciBpZD0iMzA1MzI0MTM0Ij4KKyAgICAgICAgICAgIDxtZXNzYWdlX2FyZ3VtZW50cz4KKyAgICAgICAgICAgICAgICA8bWVzc2FnZV9hcmd1bWVudCB2YWx1ZT0ib3JnLmFwYWNoZS5mZWxpeC5zY3IuQ29tcG9uZW50Ii8+CisgICAgICAgICAgICAgICAgPG1lc3NhZ2VfYXJndW1lbnQgdmFsdWU9Im9yZy5lY2xpcHNlLmVxdWlub3guZHNfMS41LjAiLz4KKyAgICAgICAgICAgIDwvbWVzc2FnZV9hcmd1bWVudHM+CisgICAgICAgIDwvZmlsdGVyPgorICAgIDwvcmVzb3VyY2U+CisgICAgPHJlc291cmNlIHBhdGg9Ik1FVEEtSU5GL01BTklGRVNULk1GIiB0eXBlPSJvcmcuYXBhY2hlLmZlbGl4LnNjci5SZWZlcmVuY2UiPgorICAgICAgICA8ZmlsdGVyIGlkPSIzMDUzMjQxMzQiPgorICAgICAgICAgICAgPG1lc3NhZ2VfYXJndW1lbnRzPgorICAgICAgICAgICAgICAgIDxtZXNzYWdlX2FyZ3VtZW50IHZhbHVlPSJvcmcuYXBhY2hlLmZlbGl4LnNjci5SZWZlcmVuY2UiLz4KKyAgICAgICAgICAgICAgICA8bWVzc2FnZV9hcmd1bWVudCB2YWx1ZT0ib3JnLmVjbGlwc2UuZXF1aW5veC5kc18xLjUuMCIvPgorICAgICAgICAgICAgPC9tZXNzYWdlX2FyZ3VtZW50cz4KKyAgICAgICAgPC9maWx0ZXI+CisgICAgPC9yZXNvdXJjZT4KKyAgICA8cmVzb3VyY2UgcGF0aD0iTUVUQS1JTkYvTUFOSUZFU1QuTUYiIHR5cGU9Im9yZy5hcGFjaGUuZmVsaXguc2NyLlNjclNlcnZpY2UiPgorICAgICAgICA8ZmlsdGVyIGlkPSIzMDUzMjQxMzQiPgorICAgICAgICAgICAgPG1lc3NhZ2VfYXJndW1lbnRzPgorICAgICAgICAgICAgICAgIDxtZXNzYWdlX2FyZ3VtZW50IHZhbHVlPSJvcmcuYXBhY2hlLmZlbGl4LnNjci5TY3JTZXJ2aWNlIi8+CisgICAgICAgICAgICAgICAgPG1lc3NhZ2VfYXJndW1lbnQgdmFsdWU9Im9yZy5lY2xpcHNlLmVxdWlub3guZHNfMS41LjAiLz4KKyAgICAgICAgICAgIDwvbWVzc2FnZV9hcmd1bWVudHM+CisgICAgICAgIDwvZmlsdGVyPgorICAgIDwvcmVzb3VyY2U+Cis8L2NvbXBvbmVudD4KZGlmZiAtLWdpdCBhL2J1bmRsZXMvb3JnLmVjbGlwc2UuZXF1aW5veC5kcy8uc2V0dGluZ3Mvb3JnLmVjbGlwc2UuamR0LmNvcmUucHJlZnMgYi9idW5kbGVzL29yZy5lY2xpcHNlLmVxdWlub3guZHMvLnNldHRpbmdzL29yZy5lY2xpcHNlLmpkdC5jb3JlLnByZWZzCmluZGV4IGQzMDQxMTYuLmM2ZmVjMGUgMTAwNjQ0Ci0tLSBhL2J1bmRsZXMvb3JnLmVjbGlwc2UuZXF1aW5veC5kcy8uc2V0dGluZ3Mvb3JnLmVjbGlwc2UuamR0LmNvcmUucHJlZnMKKysrIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5lcXVpbm94LmRzLy5zZXR0aW5ncy9vcmcuZWNsaXBzZS5qZHQuY29yZS5wcmVmcwpAQCAtMSw0ICsxLDMgQEAKLSNUaHUgQXVnIDE2IDExOjAwOjU5IEVEVCAyMDA3CiBlY2xpcHNlLnByZWZlcmVuY2VzLnZlcnNpb249MQogb3JnLmVjbGlwc2UuamR0LmNvcmUuYnVpbGRlci5jbGVhbk91dHB1dEZvbGRlcj1jbGVhbgogb3JnLmVjbGlwc2UuamR0LmNvcmUuYnVpbGRlci5kdXBsaWNhdGVSZXNvdXJjZVRhc2s9d2FybmluZwpAQCAtNywyNCArNiwyNCBAQAogb3JnLmVjbGlwc2UuamR0LmNvcmUuY2lyY3VsYXJDbGFzc3BhdGg9ZXJyb3IKIG9yZy5lY2xpcHNlLmpkdC5jb3JlLmNsYXNzcGF0aC5leGNsdXNpb25QYXR0ZXJucz1lbmFibGVkCiBvcmcuZWNsaXBzZS5qZHQuY29yZS5jbGFzc3BhdGgubXVsdGlwbGVPdXRwdXRMb2NhdGlvbnM9ZW5hYmxlZAotb3JnLmVjbGlwc2UuamR0LmNvcmUuY29tcGlsZXIuY29kZWdlbi5pbmxpbmVKc3JCeXRlY29kZT1kaXNhYmxlZAotb3JnLmVjbGlwc2UuamR0LmNvcmUuY29tcGlsZXIuY29kZWdlbi50YXJnZXRQbGF0Zm9ybT0xLjIKK29yZy5lY2xpcHNlLmpkdC5jb3JlLmNvbXBpbGVyLmNvZGVnZW4uaW5saW5lSnNyQnl0ZWNvZGU9ZW5hYmxlZAorb3JnLmVjbGlwc2UuamR0LmNvcmUuY29tcGlsZXIuY29kZWdlbi50YXJnZXRQbGF0Zm9ybT0xLjYKIG9yZy5lY2xpcHNlLmpkdC5jb3JlLmNvbXBpbGVyLmNvZGVnZW4udW51c2VkTG9jYWw9cHJlc2VydmUKLW9yZy5lY2xpcHNlLmpkdC5jb3JlLmNvbXBpbGVyLmNvbXBsaWFuY2U9MS40CitvcmcuZWNsaXBzZS5qZHQuY29yZS5jb21waWxlci5jb21wbGlhbmNlPTEuNgogb3JnLmVjbGlwc2UuamR0LmNvcmUuY29tcGlsZXIuZGVidWcubGluZU51bWJlcj1nZW5lcmF0ZQogb3JnLmVjbGlwc2UuamR0LmNvcmUuY29tcGlsZXIuZGVidWcubG9jYWxWYXJpYWJsZT1nZW5lcmF0ZQogb3JnLmVjbGlwc2UuamR0LmNvcmUuY29tcGlsZXIuZGVidWcuc291cmNlRmlsZT1nZW5lcmF0ZQogb3JnLmVjbGlwc2UuamR0LmNvcmUuY29tcGlsZXIuZG9jLmNvbW1lbnQuc3VwcG9ydD1lbmFibGVkCiBvcmcuZWNsaXBzZS5qZHQuY29yZS5jb21waWxlci5tYXhQcm9ibGVtUGVyVW5pdD0xMDAwCiBvcmcuZWNsaXBzZS5qZHQuY29yZS5jb21waWxlci5wcm9ibGVtLmFubm90YXRpb25TdXBlckludGVyZmFjZT13YXJuaW5nCi1vcmcuZWNsaXBzZS5qZHQuY29yZS5jb21waWxlci5wcm9ibGVtLmFzc2VydElkZW50aWZpZXI9d2FybmluZworb3JnLmVjbGlwc2UuamR0LmNvcmUuY29tcGlsZXIucHJvYmxlbS5hc3NlcnRJZGVudGlmaWVyPWVycm9yCiBvcmcuZWNsaXBzZS5qZHQuY29yZS5jb21waWxlci5wcm9ibGVtLmF1dG9ib3hpbmc9aWdub3JlCiBvcmcuZWNsaXBzZS5qZHQuY29yZS5jb21waWxlci5wcm9ibGVtLmRlcHJlY2F0aW9uPXdhcm5pbmcKIG9yZy5lY2xpcHNlLmpkdC5jb3JlLmNvbXBpbGVyLnByb2JsZW0uZGVwcmVjYXRpb25JbkRlcHJlY2F0ZWRDb2RlPWRpc2FibGVkCiBvcmcuZWNsaXBzZS5qZHQuY29yZS5jb21waWxlci5wcm9ibGVtLmRlcHJlY2F0aW9uV2hlbk92ZXJyaWRpbmdEZXByZWNhdGVkTWV0aG9kPWVuYWJsZWQKIG9yZy5lY2xpcHNlLmpkdC5jb3JlLmNvbXBpbGVyLnByb2JsZW0uZGlzY291cmFnZWRSZWZlcmVuY2U9ZXJyb3IKIG9yZy5lY2xpcHNlLmpkdC5jb3JlLmNvbXBpbGVyLnByb2JsZW0uZW1wdHlTdGF0ZW1lbnQ9d2FybmluZwotb3JnLmVjbGlwc2UuamR0LmNvcmUuY29tcGlsZXIucHJvYmxlbS5lbnVtSWRlbnRpZmllcj13YXJuaW5nCitvcmcuZWNsaXBzZS5qZHQuY29yZS5jb21waWxlci5wcm9ibGVtLmVudW1JZGVudGlmaWVyPWVycm9yCiBvcmcuZWNsaXBzZS5qZHQuY29yZS5jb21waWxlci5wcm9ibGVtLmZpZWxkSGlkaW5nPXdhcm5pbmcKIG9yZy5lY2xpcHNlLmpkdC5jb3JlLmNvbXBpbGVyLnByb2JsZW0uZmluYWxQYXJhbWV0ZXJCb3VuZD1pZ25vcmUKIG9yZy5lY2xpcHNlLmpkdC5jb3JlLmNvbXBpbGVyLnByb2JsZW0uZmluYWxseUJsb2NrTm90Q29tcGxldGluZ05vcm1hbGx5PXdhcm5pbmcKQEAgLTcyLDcgKzcxLDcgQEAKIG9yZy5lY2xpcHNlLmpkdC5jb3JlLmNvbXBpbGVyLnByb2JsZW0udW51c2VkUGFyYW1ldGVyV2hlbk92ZXJyaWRpbmdDb25jcmV0ZT1lbmFibGVkCiBvcmcuZWNsaXBzZS5qZHQuY29yZS5jb21waWxlci5wcm9ibGVtLnVudXNlZFByaXZhdGVNZW1iZXI9ZXJyb3IKIG9yZy5lY2xpcHNlLmpkdC5jb3JlLmNvbXBpbGVyLnByb2JsZW0udmFyYXJnc0FyZ3VtZW50TmVlZENhc3Q9d2FybmluZwotb3JnLmVjbGlwc2UuamR0LmNvcmUuY29tcGlsZXIuc291cmNlPTEuMworb3JnLmVjbGlwc2UuamR0LmNvcmUuY29tcGlsZXIuc291cmNlPTEuNgogb3JnLmVjbGlwc2UuamR0LmNvcmUuZm9ybWF0dGVyLmFsaWduX3R5cGVfbWVtYmVyc19vbl9jb2x1bW5zPWZhbHNlCiBvcmcuZWNsaXBzZS5qZHQuY29yZS5mb3JtYXR0ZXIuYWxpZ25tZW50X2Zvcl9hcmd1bWVudHNfaW5fYWxsb2NhdGlvbl9leHByZXNzaW9uPTE2CiBvcmcuZWNsaXBzZS5qZHQuY29yZS5mb3JtYXR0ZXIuYWxpZ25tZW50X2Zvcl9hcmd1bWVudHNfaW5fZW51bV9jb25zdGFudD0xNgpAQCAtMTQ0LDcgKzE0MywxMiBAQAogb3JnLmVjbGlwc2UuamR0LmNvcmUuZm9ybWF0dGVyLmluZGVudF9zd2l0Y2hzdGF0ZW1lbnRzX2NvbXBhcmVfdG9fY2FzZXM9dHJ1ZQogb3JnLmVjbGlwc2UuamR0LmNvcmUuZm9ybWF0dGVyLmluZGVudF9zd2l0Y2hzdGF0ZW1lbnRzX2NvbXBhcmVfdG9fc3dpdGNoPXRydWUKIG9yZy5lY2xpcHNlLmpkdC5jb3JlLmZvcm1hdHRlci5pbmRlbnRhdGlvbi5zaXplPTQKLW9yZy5lY2xpcHNlLmpkdC5jb3JlLmZvcm1hdHRlci5pbnNlcnRfbmV3X2xpbmVfYWZ0ZXJfYW5ub3RhdGlvbj1pbnNlcnQKK29yZy5lY2xpcHNlLmpkdC5jb3JlLmZvcm1hdHRlci5pbnNlcnRfbmV3X2xpbmVfYWZ0ZXJfYW5ub3RhdGlvbl9vbl9maWVsZD1pbnNlcnQKK29yZy5lY2xpcHNlLmpkdC5jb3JlLmZvcm1hdHRlci5pbnNlcnRfbmV3X2xpbmVfYWZ0ZXJfYW5ub3RhdGlvbl9vbl9sb2NhbF92YXJpYWJsZT1pbnNlcnQKK29yZy5lY2xpcHNlLmpkdC5jb3JlLmZvcm1hdHRlci5pbnNlcnRfbmV3X2xpbmVfYWZ0ZXJfYW5ub3RhdGlvbl9vbl9tZXRob2Q9aW5zZXJ0CitvcmcuZWNsaXBzZS5qZHQuY29yZS5mb3JtYXR0ZXIuaW5zZXJ0X25ld19saW5lX2FmdGVyX2Fubm90YXRpb25fb25fcGFja2FnZT1pbnNlcnQKK29yZy5lY2xpcHNlLmpkdC5jb3JlLmZvcm1hdHRlci5pbnNlcnRfbmV3X2xpbmVfYWZ0ZXJfYW5ub3RhdGlvbl9vbl9wYXJhbWV0ZXI9aW5zZXJ0CitvcmcuZWNsaXBzZS5qZHQuY29yZS5mb3JtYXR0ZXIuaW5zZXJ0X25ld19saW5lX2FmdGVyX2Fubm90YXRpb25fb25fdHlwZT1pbnNlcnQKIG9yZy5lY2xpcHNlLmpkdC5jb3JlLmZvcm1hdHRlci5pbnNlcnRfbmV3X2xpbmVfYWZ0ZXJfb3BlbmluZ19icmFjZV9pbl9hcnJheV9pbml0aWFsaXplcj1kbyBub3QgaW5zZXJ0CiBvcmcuZWNsaXBzZS5qZHQuY29yZS5mb3JtYXR0ZXIuaW5zZXJ0X25ld19saW5lX2F0X2VuZF9vZl9maWxlX2lmX21pc3Npbmc9ZG8gbm90IGluc2VydAogb3JnLmVjbGlwc2UuamR0LmNvcmUuZm9ybWF0dGVyLmluc2VydF9uZXdfbGluZV9iZWZvcmVfY2F0Y2hfaW5fdHJ5X3N0YXRlbWVudD1kbyBub3QgaW5zZXJ0CmRpZmYgLS1naXQgYS9idW5kbGVzL29yZy5lY2xpcHNlLmVxdWlub3guZHMvTUVUQS1JTkYvTUFOSUZFU1QuTUYgYi9idW5kbGVzL29yZy5lY2xpcHNlLmVxdWlub3guZHMvTUVUQS1JTkYvTUFOSUZFU1QuTUYKaW5kZXggOWQ3YjM5Ny4uN2RkYjEwNCAxMDA2NDQKLS0tIGEvYnVuZGxlcy9vcmcuZWNsaXBzZS5lcXVpbm94LmRzL01FVEEtSU5GL01BTklGRVNULk1GCisrKyBiL2J1bmRsZXMvb3JnLmVjbGlwc2UuZXF1aW5veC5kcy9NRVRBLUlORi9NQU5JRkVTVC5NRgpAQCAtMiw0NSArMiwxNyBAQAogQnVuZGxlLU1hbmlmZXN0VmVyc2lvbjogMgogQnVuZGxlLU5hbWU6ICVidW5kbGVOYW1lCiBCdW5kbGUtU3ltYm9saWNOYW1lOiBvcmcuZWNsaXBzZS5lcXVpbm94LmRzO3NpbmdsZXRvbjo9dHJ1ZQotQnVuZGxlLVZlcnNpb246IDEuNC41MDAucXVhbGlmaWVyCitCdW5kbGUtVmVyc2lvbjogMS41LjAucXVhbGlmaWVyCiBCdW5kbGUtVmVuZG9yOiAlYnVuZGxlVmVuZG9yCiBCdW5kbGUtQWN0aXZhdG9yOiBvcmcuZWNsaXBzZS5lcXVpbm94LmludGVybmFsLmRzLkFjdGl2YXRvcgogQnVuZGxlLURlc2NyaXB0aW9uOiBUaGlzIGJ1bmRsZSBwcm92aWRlcyBzdXBwb3J0IGZvciBPU0dpIAogIERlY2xhcmF0aXZlIFNlcnZpY2VzCiBJbXBvcnQtUGFja2FnZTogCi0gb3JnLmVjbGlwc2UuZXF1aW5veC5pbnRlcm5hbC51dGlsLmV2ZW50O3ZlcnNpb249IjEuMCIsCi0gb3JnLmVjbGlwc2UuZXF1aW5veC5pbnRlcm5hbC51dGlsLmhhc2g7dmVyc2lvbj0iMS4wIiwKLSBvcmcuZWNsaXBzZS5lcXVpbm94LmludGVybmFsLnV0aWwucG9vbDt2ZXJzaW9uPSIxLjAiLAotIG9yZy5lY2xpcHNlLmVxdWlub3guaW50ZXJuYWwudXRpbC5yZWY7dmVyc2lvbj0iMS4wIiwKLSBvcmcuZWNsaXBzZS5lcXVpbm94LmludGVybmFsLnV0aWwudGhyZWFkcG9vbDt2ZXJzaW9uPSIxLjAiLAotIG9yZy5lY2xpcHNlLmVxdWlub3guaW50ZXJuYWwudXRpbC50aW1lcjt2ZXJzaW9uPSIxLjAiLAotIG9yZy5lY2xpcHNlLm9zZ2kuZnJhbWV3b3JrLmNvbnNvbGU7dmVyc2lvbj0iMS4wLjAiO3Jlc29sdXRpb246PW9wdGlvbmFsLAotIG9yZy5lY2xpcHNlLm9zZ2kuZnJhbWV3b3JrLmxvZzt2ZXJzaW9uPSIxLjAuMCIsCi0gb3JnLmVjbGlwc2Uub3NnaS5zZXJ2aWNlLmRlYnVnO3ZlcnNpb249IjEuMCIsCi0gb3JnLmVjbGlwc2Uub3NnaS5zZXJ2aWNlLmVudmlyb25tZW50O3ZlcnNpb249IjEuMi4wIiwKLSBvcmcuZWNsaXBzZS5vc2dpLnV0aWwsCi0gb3JnLm9zZ2kuZnJhbWV3b3JrO3ZlcnNpb249IjEuMyIsCi0gb3JnLm9zZ2kuc2VydmljZS5jbTt2ZXJzaW9uPSIxLjIiLAotIG9yZy5vc2dpLnNlcnZpY2UuY29tcG9uZW50O3ZlcnNpb249IlsxLjEsMS40KSIsCi0gb3JnLm9zZ2kuc2VydmljZS5sb2c7dmVyc2lvbj0iMS4zLjAiLAotIG9yZy5vc2dpLnV0aWwudHJhY2tlcjt2ZXJzaW9uPSIxLjMiLAotIG9yZy5hcGFjaGUuZmVsaXguc2NyOyB2ZXJzaW9uPSJbMS42LDEuNykiCi1Qcm92aWRlLUNhcGFiaWxpdHk6IG9zZ2kuZXh0ZW5kZXI7Ci0gb3NnaS5leHRlbmRlcj0ib3NnaS5jb21wb25lbnQiOwotIHZlcnNpb246VmVyc2lvbj0iMS4yIjsKLSB1c2VzOj0ib3JnLm9zZ2kuc2VydmljZS5jb21wb25lbnQiCi1FeHBvcnQtUGFja2FnZTogCi0gb3JnLmVjbGlwc2UuZXF1aW5veC5pbnRlcm5hbC5kczt4LWludGVybmFsOj10cnVlLAotIG9yZy5lY2xpcHNlLmVxdWlub3guaW50ZXJuYWwuZHMuaW1wbDt4LWludGVybmFsOj10cnVlLAotIG9yZy5lY2xpcHNlLmVxdWlub3guaW50ZXJuYWwuZHMubW9kZWw7eC1pbnRlcm5hbDo9dHJ1ZSwKLSBvcmcuZWNsaXBzZS5lcXVpbm94LmludGVybmFsLmRzLnN0b3JhZ2UuZmlsZTt4LWludGVybmFsOj10cnVlLAotIG9yZy5lY2xpcHNlLmVxdWlub3guaW50ZXJuYWwudXRpbC5pbzt4LWludGVybmFsOj10cnVlLAotIG9yZy5lY2xpcHNlLmVxdWlub3guaW50ZXJuYWwudXRpbC54bWw7eC1pbnRlcm5hbDo9dHJ1ZSwKLSBvcmcuZWNsaXBzZS5lcXVpbm94LmludGVybmFsLnV0aWwueG1sLmltcGw7eC1pbnRlcm5hbDo9dHJ1ZSwKLSBvcmcuZWNsaXBzZS5lcXVpbm94LmludGVybmFsLnV0aWwuc3RyaW5nO3gtaW50ZXJuYWw6PXRydWUsCi0gb3JnLmFwYWNoZS5mZWxpeC5zY3I7dmVyc2lvbj0iMS42IgotQnVuZGxlLVJlcXVpcmVkRXhlY3V0aW9uRW52aXJvbm1lbnQ6IE9TR2kvTWluaW11bS0xLjIsCi0gQ0RDLTEuMS9Gb3VuZGF0aW9uLTEuMSwKLSBKMlNFLTEuNAotTGF6eS1NYW5pZmVzdEZpbHRlcjogKFNlcnZpY2UtQ29tcG9uZW50PSopCisgb3JnLmVjbGlwc2Uub3NnaS5zZXJ2aWNlLmVudmlyb25tZW50O3ZlcnNpb249IjEuMy4wIiwKKyBvcmcub3NnaS5mcmFtZXdvcms7dmVyc2lvbj0iMS44LjAiLAorIG9yZy5vc2dpLmZyYW1ld29yay5uYW1lc3BhY2U7dmVyc2lvbj0iMS4xLjAiLAorIG9yZy5vc2dpLmZyYW1ld29yay5zdGFydGxldmVsO3ZlcnNpb249IjEuMC4wIiwKKyBvcmcub3NnaS5mcmFtZXdvcmsud2lyaW5nO3ZlcnNpb249IjEuMi4wIgorUmVxdWlyZS1CdW5kbGU6IG9yZy5hcGFjaGUuZmVsaXguc2NyO2J1bmRsZS12ZXJzaW9uPSJbMi4wLjAsMy4wLjApIjt2aXNpYmlsaXR5Oj1yZWV4cG9ydAorQnVuZGxlLVJlcXVpcmVkRXhlY3V0aW9uRW52aXJvbm1lbnQ6IEphdmFTRS0xLjYKIEJ1bmRsZS1Mb2NhbGl6YXRpb246IHBsdWdpbgpkaWZmIC0tZ2l0IGEvYnVuZGxlcy9vcmcuZWNsaXBzZS5lcXVpbm94LmRzL2J1aWxkLnByb3BlcnRpZXMgYi9idW5kbGVzL29yZy5lY2xpcHNlLmVxdWlub3guZHMvYnVpbGQucHJvcGVydGllcwppbmRleCA3MDZlNWZjLi42ODExMmU3IDEwMDY0NAotLS0gYS9idW5kbGVzL29yZy5lY2xpcHNlLmVxdWlub3guZHMvYnVpbGQucHJvcGVydGllcworKysgYi9idW5kbGVzL29yZy5lY2xpcHNlLmVxdWlub3guZHMvYnVpbGQucHJvcGVydGllcwpAQCAtMTQsNyArMTQsNiBAQAogYmluLmluY2x1ZGVzID0gTUVUQS1JTkYvLFwKICAgICAgICAgICAgICAgIC4sXAogICAgICAgICAgICAgICAgYWJvdXQuaHRtbCxcCi0gICAgICAgICAgICAgICAub3B0aW9ucyxcCiAgICAgICAgICAgICAgICBwbHVnaW4ucHJvcGVydGllcyxcCiAgICAgICAgICAgICAgICBhYm91dF9maWxlcy8KIHNyYy5pbmNsdWRlcyA9IGFib3V0Lmh0bWwsXApkaWZmIC0tZ2l0IGEvYnVuZGxlcy9vcmcuZWNsaXBzZS5lcXVpbm94LmRzL3BvbS54bWwgYi9idW5kbGVzL29yZy5lY2xpcHNlLmVxdWlub3guZHMvcG9tLnhtbAppbmRleCA3OGRkMzJmLi5hY2Q5Yjk2IDEwMDY0NAotLS0gYS9idW5kbGVzL29yZy5lY2xpcHNlLmVxdWlub3guZHMvcG9tLnhtbAorKysgYi9idW5kbGVzL29yZy5lY2xpcHNlLmVxdWlub3guZHMvcG9tLnhtbApAQCAtMTksNiArMTksNiBAQAogICA8L3BhcmVudD4KICAgPGdyb3VwSWQ+b3JnLmVjbGlwc2UuZXF1aW5veDwvZ3JvdXBJZD4KICAgPGFydGlmYWN0SWQ+b3JnLmVjbGlwc2UuZXF1aW5veC5kczwvYXJ0aWZhY3RJZD4KLSAgPHZlcnNpb24+MS40LjUwMC1TTkFQU0hPVDwvdmVyc2lvbj4KKyAgPHZlcnNpb24+MS41LjAtU05BUFNIT1Q8L3ZlcnNpb24+CiAgIDxwYWNrYWdpbmc+ZWNsaXBzZS1wbHVnaW48L3BhY2thZ2luZz4KIDwvcHJvamVjdD4KZGlmZiAtLWdpdCBhL2J1bmRsZXMvb3JnLmVjbGlwc2UuZXF1aW5veC5kcy9zcmMvb3JnL2FwYWNoZS9mZWxpeC9zY3IvQ29tcG9uZW50LmphdmEgYi9idW5kbGVzL29yZy5lY2xpcHNlLmVxdWlub3guZHMvc3JjL29yZy9hcGFjaGUvZmVsaXgvc2NyL0NvbXBvbmVudC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBlYTU0MDY0Li4wMDAwMDAwCi0tLSBhL2J1bmRsZXMvb3JnLmVjbGlwc2UuZXF1aW5veC5kcy9zcmMvb3JnL2FwYWNoZS9mZWxpeC9zY3IvQ29tcG9uZW50LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwzMzIgKzAsMCBAQAotLyoKLSAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKLSAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQotICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KLSAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKLSAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKLSAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKLSAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywKLSAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuCi0gKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKLSAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZQotICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucwotICogdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS5mZWxpeC5zY3I7Ci0KLWltcG9ydCBqYXZhLnV0aWwuRGljdGlvbmFyeTsKLWltcG9ydCBvcmcub3NnaS5mcmFtZXdvcmsuQnVuZGxlOwotaW1wb3J0IG9yZy5vc2dpLnNlcnZpY2UuY29tcG9uZW50LkNvbXBvbmVudEluc3RhbmNlOwotCi0vKioKLSAqIFRoZSA8Y29kZT5Db21wb25lbnQ8L2NvZGU+IGludGVyZmFjZSByZXByZXNlbnRzIGEgc2luZ2xlIGNvbXBvbmVudCBtYW5hZ2VkCi0gKiBieSB0aGUgU2VydmljZSBDb21wb25lbnQgUnVudGltZS4gTWFuYWdlbWVudCBhZ2VudHMgbWF5IGFjY2VzcyB0aGUgQ29tcG9uZW50Ci0gKiBpbnN0YW5jZXMgdGhyb3VnaCB0aGUge0BsaW5rIFNjclNlcnZpY2V9LgotICovCi1wdWJsaWMgaW50ZXJmYWNlIENvbXBvbmVudCB7Ci0KLQkvKioKLQkgKiBUaGUgQ29tcG9uZW50IGhhcyBqdXN0IGJlZW4gY3JlYXRlZCBhbmQgaXMgc3RpbGwgZGlzYWJsZWQgb3IgaXQgaGFzCi0JICogYmVlbiBkaXNhYmxlZCBieSBjYWxsaW5nIHRoZSB7QGxpbmsgI2Rpc2FibGUoKX0gbWV0aG9kICh2YWx1ZSBpcyAxKS4KLQkgKi8KLQlzdGF0aWMgZmluYWwgaW50IFNUQVRFX0RJU0FCTEVEID0gMTsKLQotCS8qKgotCSAqIFRoZSBDb21wb25lbnQgaXMgYmVpbmcgZW5hYmxlZCAodmFsdWUgaXMgNTEyKS4gQWZ0ZXIgdGhlIGNvbXBvbmVudCBoYXMKLQkgKiBiZWVuIGVuYWJsZWQgaXQgZW50ZXJzIHRoZSB7QGxpbmsgI1NUQVRFX1VOU0FUSVNGSUVEfSBzdGF0ZS4KLQkgKiBAc2luY2UgMS4yCi0JICovCi0Jc3RhdGljIGZpbmFsIGludCBTVEFURV9FTkFCTElORyA9IDUxMjsKLQotCS8qKgotCSAqIFRoZSBDb21wb25lbnQgaGFzIGJlZW4gZW5hYmxlZCBhbmQgaXMgbm93IGdvaW5nIHRvIGJlIGFjdGl2YXRlZCAodmFsdWUKLQkgKiBpcyAyKS4KLQkgKiBAZGVwcmVjYXRlZCBhcyBvZiB2ZXJzaW9uIDEuMiB0aGUgZW5hYmxlZCBzdGF0ZSBpcyBjb2xsYXBzZWQgaW50byB0aGUKLQkgKiAgICAgIHtAbGluayAjU1RBVEVfVU5TQVRJU0ZJRUR9IHN0YXRlLiBUaGlzIHN0YXR1cyBjb2RlIGlzIG5ldmVyIHJldHVybmVkCi0JICogICAgICBmcm9tIHRoZSB7QGxpbmsgI2dldFN0YXRlKCl9IG1ldGhvZC4KLQkgKi8KLQlzdGF0aWMgZmluYWwgaW50IFNUQVRFX0VOQUJMRUQgPSAyOwotCi0JLyoqCi0JICogVGhlIENvbXBvbmVudCBhY3RpdmF0aW9uIGZhaWxlZCBiZWNhdXNlIGFueSBkZXBlbmRlbmN5IGlzIG5vdCBzYXRpc2ZpZWQKLQkgKiAodmFsdWUgaXMgNCkuCi0JICovCi0Jc3RhdGljIGZpbmFsIGludCBTVEFURV9VTlNBVElTRklFRCA9IDQ7Ci0KLQkvKioKLQkgKiBUaGUgQ29tcG9uZW50IGlzIGN1cnJlbnRseSBiZWluZyBhY3RpdmF0ZWQgZWl0aGVyIGJlY2F1c2UgaXQgaGFzIGJlZW4KLQkgKiBlbmFibGVkIG9yIGJlY2F1c2UgYW55IGRlcGVuZGVuY3kgd2hpY2ggd2FzIHByZXZpb3VzbHkgdW5zYXRpc2ZpZWQgaGFzCi0JICogYmVjb21lIHNhdGlzZmllZCAodmFsdWUgaXMgOCkuCi0JICovCi0Jc3RhdGljIGZpbmFsIGludCBTVEFURV9BQ1RJVkFUSU5HID0gODsKLQotCS8qKgotCSAqIFRoZSBDb21wb25lbnQgaGFzIHN1Y2Nlc3NmdWxseSBiZWVuIGFjdGl2YXRlZCBhbmQgaXMgZnVsbHkgZnVuY3Rpb25hbAotCSAqICh2YWx1ZSBpcyAxNikuIFRoaXMgaXMgdGhlIHN0YXRlIG9mIGltbWVkaWF0ZSBjb21wb25lbnRzIGFmdGVyCi0JICogc3VjY2Vzc2Z1bCBhY3RpdmF0aW9uLiBEZWxheWVkIGFuZCBTZXJ2aWNlIEZhY3RvcnkgQ29tcG9uZW50cyBlbnRlcgotCSAqIHRoaXMgc3RhdGUgd2hlbiB0aGUgc2VydmljZSBpbnN0YW5jZSBoYXMgYWN0dWFsbHkgYmUgaW5zdGFudGlhdGVkIGJlY2F1c2UKLQkgKiB0aGUgc2VydmljZSBoYXMgYmVlbiBhY3F1aXJlZC4KLQkgKi8KLQlzdGF0aWMgZmluYWwgaW50IFNUQVRFX0FDVElWRSA9IDE2OwotCi0JLyoqCi0JICogVGhlIENvbXBvbmVudCBoYXMgc3VjY2Vzc2Z1bGx5IGJlZW4gYWN0aXZhdGVkIGJ1dCBpcyBhIERlbGF5ZWQgb3IgU2VydmljZQotCSAqIEZhY3RvcnkgQ29tcG9uZW50IHBlbmRpbmcgaW5zdGFudGlhdGlvbiBvbiBmaXJzdCB1c2UgKHZhbHVlIGlzIDMyKS4KLQkgKi8KLQlzdGF0aWMgZmluYWwgaW50IFNUQVRFX1JFR0lTVEVSRUQgPSAzMjsKLQotCS8qKgotCSAqIFRoZSBDb21wb25lbnQgaXMgYSBDb21wb25lbnQgRmFjdG9yeSByZWFkeSB0byBjcmVhdGUgQ29tcG9uZW50IGluc3RhbmNlcwotCSAqIHdpdGggdGhlIDxjb2RlPkNvbXBvbmVudEZhY3RvcnkubmV3SW5zdGFuY2UoRGljdGlvbmFyeSk8L2NvZGU+IG1ldGhvZAotCSAqIG9yIChpZiBlbmFibGVkIHdpdGggdGhlIDxjb2RlPmRzLmZhY3RvcnkuZW5hYmxlZDwvY29kZT4gY29uZmlndXJhdGlvbikgdG8KLQkgKiBtYW5hZ2UgQ29tcG9uZW50IGluc3RhbmNlcyBmcm9tIGNvbmZpZ3VyYXRpb24gZGF0YSByZWNlaXZlZCBmcm9tIHRoZQotCSAqIENvbmZpZ3VyYXRpb24gQWRtaW4gU2VydmljZSAodmFsdWUgaXMgNjQpLgotCSAqLwotCXN0YXRpYyBmaW5hbCBpbnQgU1RBVEVfRkFDVE9SWSA9IDY0OwotCi0JLyoqCi0JICogVGhlIENvbXBvbmVudCBpcyBiZWluZyBkZWFjdGl2YXRlZCBlaXRoZXIgYmVjYXVzZSBpdCBpcyBiZWluZyBkaXNhYmxlZAotCSAqIG9yIGJlY2F1c2UgYSBkZXBlbmRlbmN5IGlzIG5vdCBzYXRpc2ZpZWQgYW55IG1vcmUgKHZhbHVlIGlzIDEyOCkuIEFmdGVyCi0JICogZGVhY3RpdmF0aW9uIHRoZSBDb21wb25lbnQgZW50ZXJzIHRoZSB7QGxpbmsgI1NUQVRFX1VOU0FUSVNGSUVEfSBzdGF0ZS4KLQkgKi8KLQlzdGF0aWMgZmluYWwgaW50IFNUQVRFX0RFQUNUSVZBVElORyA9IDEyODsKLQotCS8qKgotCSAqIFRoZSBDb21wb25lbnQgaXMgYmVpbmcgZGlzYWJsZWQgKHZhbHVlIGlzIDEwMjQpLiBBZnRlciB0aGUgY29tcG9uZW50IGhhcwotCSAqIGJlZW4gZGlzYWJsZWQgaXQgZW50ZXJzIHRoZSB7QGxpbmsgI1NUQVRFX0RJU0FCTEVEfSBzdGF0ZS4KLQkgKiBAc2luY2UgMS4yCi0JICovCi0Jc3RhdGljIGZpbmFsIGludCBTVEFURV9ESVNBQkxJTkcgPSAxMDI0OwotCi0JLyoqCi0JICogVGhlIENvbXBvbmVudCBpcyBiZWluZyBkaXNwb3NlZCBvZmYgKHZhbHVlIGlzIDIwNDgpLiBBZnRlciB0aGUgY29tcG9uZW50Ci0JICogaGFzIGJlZW4gZGlzcG9zZWQgb2ZmIGl0IGVudGVycyB0aGUge0BsaW5rICNTVEFURV9ERVNUUk9ZRUR9IHN0YXRlLgotCSAqIEBzaW5jZSAxLjIKLQkgKi8KLQlzdGF0aWMgZmluYWwgaW50IFNUQVRFX0RJU1BPU0lORyA9IDIwNDg7Ci0KLQkvKioKLQkgKiBUaGUgQ29tcG9uZW50IGhhcyBiZWVuIGRlc3Ryb3llZCBhbmQgY2Fubm90IGJlIHVzZWQgYW55IG1vcmUgKHZhbHVlIGlzCi0JICogMjU2KS4gVGhpcyBzdGF0ZSBpcyBvbmx5IHVzZWQgd2hlbiB0aGUgYnVuZGxlIGRlY2xhcmluZyB0aGUgY29tcG9uZW50Ci0JICogaXMgYmVpbmcgc3RvcHBlZCBhbmQgYWxsIGNvbXBvbmVudHMgaGF2ZSB0byBiZSByZW1vdmVkLgotCSAqIEBkZXByZWNhdGVkIGFzIG9mIHZlcnNpb24gMS4yIHRoaXMgY29uc3RhbnQgaGFzIGJlZW4gcmVuYW1lZCB0bwotCSAqICAgICAge0BsaW5rICNTVEFURV9ESVNQT1NFRH0uCi0JICovCi0Jc3RhdGljIGZpbmFsIGludCBTVEFURV9ERVNUUk9ZRUQgPSAyNTY7Ci0KLQkvKioKLQkgKiBUaGUgQ29tcG9uZW50IGhhcyBiZWVuIGRpc3Bvc2VkIG9mZiBhbmQgY2Fubm90IGJlIHVzZWQgYW55IG1vcmUgKHZhbHVlIGlzCi0JICogMjU2KS4gVGhpcyBzdGF0ZSBpcyB1c2VkIHdoZW4gdGhlIGJ1bmRsZSBkZWNsYXJpbmcgdGhlIGNvbXBvbmVudAotCSAqIGlzIGJlaW5nIHN0b3BwZWQgYW5kIGFsbCBjb21wb25lbnRzIGhhdmUgdG8gYmUgcmVtb3ZlZC4gVGhpcyBzdGF0dXMgaXMKLQkgKiBhbHNvIHRoZSBmaW5hbCBzdGF0dXMgb2YgYSBjb21wb25lbnQgYWZ0ZXIgdGhlCi0JICogPGNvZGU+Q29tcG9uZW50SW5zdGFuY2UuZGlzcG9zZSgpPC9jb2RlPiBtZXRob2QgaGFzIGJlZW4gY2FsbGVkLgotCSAqIEBzaW5jZSAxLjIKLQkgKi8KLQlzdGF0aWMgZmluYWwgaW50IFNUQVRFX0RJU1BPU0VEID0gMjU2OwotCi0JLyoqCi0JICogUmV0dXJucyB0aGUgY29tcG9uZW50IElEIG9mIHRoaXMgY29tcG9uZW50LiBUaGlzIElEIGlzIG1hbmFnZWQgYnkgdGhlCi0JICogU0NSLiBJZiB0aGUgY29tcG9uZW50IGlzIG5vdCBjdXJyZW50bHkgZW5hYmxlZCB0aGUgSUQgbWlnaHQgbm90IGJlCi0JICogYXNzaWduZWQgdG8gdGhlIGNvbXBvbmVudCAoeWV0KSBhbmQgdGhpcyBtZXRob2Qgd2lsbCByZXR1cm4gLTEgaW4gdGhpcwotCSAqIGNhc2UuCi0JICovCi0JbG9uZyBnZXRJZCgpOwotCi0JLyoqCi0JICogUmV0dXJucyB0aGUgbmFtZSBvZiB0aGUgY29tcG9uZW50LCB3aGljaCBpcyBhbHNvIHVzZWQgYXMgdGhlIHNlcnZpY2UgUElELgotCSAqIFRoaXMgbWV0aG9kIHByb3ZpZGVzIGFjY2VzcyB0byB0aGUgPGNvZGU+bmFtZTwvY29kZT4gYXR0cmlidXRlIG9mIHRoZQotCSAqIDxjb2RlPmNvbXBvbmVudDwvY29kZT4gZWxlbWVudC4KLQkgKi8KLQlTdHJpbmcgZ2V0TmFtZSgpOwotCi0JLyoqCi0JICogUmV0dXJucyB0aGUgY3VycmVudCBzdGF0ZSBvZiB0aGUgQ29tcG9uZW50LCB3aGljaCBpcyBvbmUgb2YgdGhlCi0JICogPGNvZGU+U1RBVEVfKjwvY29kZT4gY29uc3RhbnRzIGRlZmluZWQgaW4gdGhpcyBpbnRlcmZhY2UuCi0JICovCi0JaW50IGdldFN0YXRlKCk7Ci0KLQkvKioKLQkgKiBSZXR1cm5zIHRoZSA8Y29kZT5CdW5kbGU8L2NvZGU+IGRlY2xhcmluZyB0aGlzIGNvbXBvbmVudC4KLQkgKi8KLQlCdW5kbGUgZ2V0QnVuZGxlKCk7Ci0KLQkvKioKLQkgKiBSZXR1cm5zIHRoZSBjb21wb25lbnQgZmFjdG9yeSBuYW1lIG9yIDxjb2RlPm51bGw8L2NvZGU+IGlmIHRoaXMgY29tcG9uZW50Ci0JICogaXMgbm90IGRlZmluZWQgYXMgYSBjb21wb25lbnQgZmFjdG9yeS4gVGhpcyBtZXRob2QgcHJvdmlkZXMgYWNjZXNzIHRvCi0JICogdGhlIDxjb2RlPmZhY3Rvcnk8L2NvZGU+IGF0dHJpYnV0ZSBvZiB0aGUgPGNvZGU+Y29tcG9uZW50PC9jb2RlPgotCSAqIGVsZW1lbnQuCi0JICovCi0JU3RyaW5nIGdldEZhY3RvcnkoKTsKLQotCS8qKgotCSAqIFJldHVybnMgPGNvZGU+dHJ1ZTwvY29kZT4gaWYgdGhpcyBjb21wb25lbnQgaXMgYSBzZXJ2aWNlIGZhY3RvcnkuIFRoaXMKLQkgKiBtZXRob2QgcmV0dXJucyB0aGUgdmFsdWUgb2YgdGhlIDxjb2RlPnNlcnZpY2VGYWN0b3J5PC9jb2RlPiBhdHRyaWJ1dGUgb2YKLQkgKiB0aGUgPGNvZGU+c2VydmljZTwvY29kZT4gZWxlbWVudC4gSWYgdGhlIGNvbXBvbmVudCBoYXMgbm8gc2VydmljZQotCSAqIGVsZW1lbnQsIHRoaXMgbWV0aG9kIHJldHVybnMgPGNvZGU+ZmFsc2U8L2NvZGU+LgotCSAqLwotCWJvb2xlYW4gaXNTZXJ2aWNlRmFjdG9yeSgpOwotCi0JLyoqCi0JICogUmV0dXJucyB0aGUgY2xhc3MgbmFtZSBvZiB0aGUgQ29tcG9uZW50IGltcGxlbWVudGF0aW9uLiBUaGlzIG1ldGhvZAotCSAqIHByb3ZpZGVzIGFjY2VzcyB0byB0aGUgPGNvZGU+Y2xhc3M8L2NvZGU+IGF0dHJpYnV0ZSBvZiB0aGUKLQkgKiA8Y29kZT5pbXBsZW1lbnRhdGlvbjwvY29kZT4gZWxlbWVudC4KLQkgKi8KLQlTdHJpbmcgZ2V0Q2xhc3NOYW1lKCk7Ci0KLQkvKioKLQkgKiBSZXR1cm5zIHdoZXRoZXIgdGhlIENvbXBvbmVudCBpcyBkZWNsYXJlZCB0byBiZSBlbmFibGVkIGluaXRpYWxseS4gVGhpcwotCSAqIG1ldGhvZCBwcm92aWRlcyBhY2Nlc3MgdG8gdGhlIDxjb2RlPmVuYWJsZWQ8L2NvZGU+IGF0dHJpYnV0ZSBvZiB0aGUKLQkgKiA8Y29kZT5jb21wb25lbnQ8L2NvZGU+IGVsZW1lbnQuCi0JICovCi0JYm9vbGVhbiBpc0RlZmF1bHRFbmFibGVkKCk7Ci0KLQkvKioKLQkgKiBSZXR1cm5zIHdoZXRoZXIgdGhlIENvbXBvbmVudCBpcyBhbiBJbW1lZGlhdGUgb3IgYSBEZWxheWVkIENvbXBvbmVudC4KLQkgKiBUaGlzIG1ldGhvZCBwcm92aWRlcyBhY2Nlc3MgdG8gdGhlIDxjb2RlPmltbWVkaWF0ZTwvY29kZT4gYXR0cmlidXRlIG9mCi0JICogdGhlIDxjb2RlPmNvbXBvbmVudDwvY29kZT4gZWxlbWVudC4KLQkgKi8KLQlib29sZWFuIGlzSW1tZWRpYXRlKCk7Ci0KLQkvKioKLQkgKiBSZXR1cm5zIGFuIGFycmF5IG9mIHNlcnZpY2UgbmFtZXMgcHJvdmlkZWQgYnkgdGhpcyBDb21wb25lbnQgb3IKLQkgKiA8Y29kZT5udWxsPC9jb2RlPiBpZiB0aGUgQ29tcG9uZW50IGlzIG5vdCByZWdpc3RlcmVkIGFzIGEgc2VydmljZS4gVGhpcwotCSAqIG1ldGhvZCBwcm92aWRlcyBhY2Nlc3MgdG8gdGhlIDxjb2RlPmludGVyZmFjZTwvY29kZT4gYXR0cmlidXRlcyBvZiB0aGUKLQkgKiA8Y29kZT5wcm92aWRlPC9jb2RlPiBlbGVtZW50cy4KLQkgKi8KLQlTdHJpbmdbXSBnZXRTZXJ2aWNlcygpOwotCi0JLyoqCi0JICogUmV0dXJucyB0aGUgcHJvcGVydGllcyBvZiB0aGUgQ29tcG9uZW50LiBUaGUgRGljdGlvbmFyeSByZXR1cm5lZCBpcyBhCi0JICogcHJpdmF0ZSBjb3B5IG9mIHRoZSBhY3R1YWwgcHJvcGVydGllcyBhbmQgY29udGFpbnMgdGhlIHNhbWUgZW50cmllcyBhcwotCSAqIGFyZSB1c2VkIHRvIHJlZ2lzdGVyIHRoZSBDb21wb25lbnQgYXMgYSBzZXJ2aWNlIGFuZCBhcmUgcmV0dXJuZWQgYnkKLQkgKiB0aGUgPGNvZGU+Q29tcG9uZW50Q29udGV4dC5nZXRQcm9wZXJ0aWVzKCk8L2NvZGU+IG1ldGhvZC4KLQkgKi8KLQlEaWN0aW9uYXJ5IGdldFByb3BlcnRpZXMoKTsKLQotCS8qKgotCSAqIFJldHVybnMgYW4gYXJyYXkgb2Yge0BsaW5rIFJlZmVyZW5jZX0gaW5zdGFuY2VzIHJlcHJlc2VudGluZyB0aGUgc2VydmljZQotCSAqIHJlZmVyZW5jZXMgKG9yIGRlcGVuZGVuY2llcykgb2YgdGhpcyBDb21wb25lbnQuIElmIHRoZSBDb21wb25lbnQgaGFzIG5vCi0JICogcmVmZXJlbmNlcywgPGNvZGU+bnVsbDwvY29kZT4gaXMgcmV0dXJuZWQuCi0JICovCi0JUmVmZXJlbmNlW10gZ2V0UmVmZXJlbmNlcygpOwotCi0JLyoqCi0JICogUmV0dXJucyB0aGUgPGNvZGU+b3JnLm9zZ2kuc2VydmljZS5jb21wb25lbnQuQ29tcG9uZW50SW5zdGFuY2U8L2NvZGU+Ci0JICogcmVwcmVzZW50aW5nIHRoaXMgY29tcG9uZW50IG9yIDxjb2RlPm51bGw8L2NvZGU+IGlmIHRoaXMgY29tcG9uZW50Ci0JICogaXMgbm90IGJlZW4gYWN0aXZhdGVkIHlldC4KLQkgKgotCSAqIEBzaW5jZSAxLjIKLQkgKi8KLQlDb21wb25lbnRJbnN0YW5jZSBnZXRDb21wb25lbnRJbnN0YW5jZSgpOwotCi0JLyoqCi0JICogUmV0dXJucyB0aGUgbmFtZSBvZiB0aGUgbWV0aG9kIHRvIGJlIGNhbGxlZCB3aGVuIHRoZSBjb21wb25lbnQgaXMgYmVpbmcKLQkgKiBhY3RpdmF0ZWQuCi0JICogPHA+Ci0JICogVGhpcyBtZXRob2QgbmV2ZXIgcmV0dXJucyA8Y29kZT5udWxsPC9jb2RlPiwgdGhhdCBpcywgaWYgdGhpcyBtZXRob2QgaXMKLQkgKiBub3QgZGVjbGFyZWQgaW4gdGhlIGNvbXBvbmVudCBkZXNjcmlwdG9yIHRoaXMgbWV0aG9kIHJldHVybnMgdGhlCi0JICogZGVmYXVsdCB2YWx1ZSA8aT5hY3RpdmF0ZTwvaT4uCi0JICoKLQkgKiBAc2luY2UgMS4yCi0JICovCi0JU3RyaW5nIGdldEFjdGl2YXRlKCk7Ci0KLQkvKioKLQkgKiBSZXR1cm5zIDxjb2RlPnRydWU8L2NvZGU+IGlmIHRoZSBuYW1lIG9mIHRoZSBtZXRob2QgdG8gYmUgY2FsbGVkIG9uCi0JICogY29tcG9uZW50IGFjdGl2YXRpb24gKHNlZSB7QGxpbmsgI2dldEFjdGl2YXRlKCl9IGlzIGRlY2xhcmVkIGluIHRoZQotCSAqIGNvbXBvbmVudCBkZXNjcmlwdG9yIG9yIG5vdC4KLQkgKiA8cD4KLQkgKiBGb3IgYSBjb21wb25lbnQgZGVjbGFyZWQgaW4gYSBEZWNsYXJhdGl2ZSBTZXJ2aWNlcyAxLjAgZGVzY3JpcHRvciwgdGhpcwotCSAqIG1ldGhvZCBhbHdheXMgcmV0dXJucyA8Y29kZT5mYWxzZTwvY29kZT4uCi0JICoKLQkgKiBAc2luY2UgMS4yCi0JICovCi0JYm9vbGVhbiBpc0FjdGl2YXRlRGVjbGFyZWQoKTsKLQotCS8qKgotCSAqIFJldHVybnMgdGhlIG5hbWUgb2YgdGhlIG1ldGhvZCB0byBiZSBjYWxsZWQgd2hlbiB0aGUgY29tcG9uZW50IGlzIGJlaW5nCi0JICogZGVhY3RpdmF0ZWQuCi0JICogPHA+Ci0JICogVGhpcyBtZXRob2QgbmV2ZXIgcmV0dXJucyA8Y29kZT5udWxsPC9jb2RlPiwgdGhhdCBpcywgaWYgdGhpcyBtZXRob2QgaXMKLQkgKiBub3QgZGVjbGFyZWQgaW4gdGhlIGNvbXBvbmVudCBkZXNjcmlwdG9yIHRoaXMgbWV0aG9kIHJldHVybnMgdGhlCi0JICogZGVmYXVsdCB2YWx1ZSA8aT5kZWFjdGl2YXRlPC9pPi4KLQkgKgotCSAqIEBzaW5jZSAxLjIKLQkgKi8KLQlTdHJpbmcgZ2V0RGVhY3RpdmF0ZSgpOwotCi0JLyoqCi0JICogUmV0dXJucyA8Y29kZT50cnVlPC9jb2RlPiBpZiB0aGUgbmFtZSBvZiB0aGUgbWV0aG9kIHRvIGJlIGNhbGxlZCBvbgotCSAqIGNvbXBvbmVudCBkZWFjdGl2YXRpb24gKHNlZSB7QGxpbmsgI2dldERlYWN0aXZhdGUoKX0gaXMgZGVjbGFyZWQgaW4gdGhlCi0JICogY29tcG9uZW50IGRlc2NyaXB0b3Igb3Igbm90LgotCSAqIDxwPgotCSAqIEZvciBhIGNvbXBvbmVudCBkZWNsYXJlZCBpbiBhIERlY2xhcmF0aXZlIFNlcnZpY2VzIDEuMCBkZXNjcmlwdG9yLCB0aGlzCi0JICogbWV0aG9kIGFsd2F5cyByZXR1cm5zIDxjb2RlPmZhbHNlPC9jb2RlPi4KLQkgKgotCSAqIEBzaW5jZSAxLjIKLQkgKi8KLQlib29sZWFuIGlzRGVhY3RpdmF0ZURlY2xhcmVkKCk7Ci0KLQkvKioKLQkgKiBSZXR1cm5zIHRoZSBuYW1lIG9mIHRoZSBtZXRob2QgdG8gYmUgY2FsbGVkIHdoZW4gdGhlIGNvbXBvbmVudAotCSAqIGNvbmZpZ3VyYXRpb24gaGFzIGJlZW4gdXBkYXRlZCBvciA8Y29kZT5udWxsPC9jb2RlPiBpZiBzdWNoIGEgbWV0aG9kIGlzCi0JICogbm90IGRlY2xhcmVkIGluIHRoZSBjb21wb25lbnQgZGVzY3JpcHRvci4KLQkgKiA8cD4KLQkgKiBGb3IgYSBjb21wb25lbnQgZGVjbGFyZWQgaW4gYSBEZWNsYXJhdGl2ZSBTZXJ2aWNlcyAxLjAgZGVzY3JpcHRvciwgdGhpcwotCSAqIG1ldGhvZCBhbHdheXMgcmV0dXJucyA8Y29kZT5udWxsPC9jb2RlPi4KLQkgKgotCSAqIEBzaW5jZSAxLjIKLQkgKi8KLQlTdHJpbmcgZ2V0TW9kaWZpZWQoKTsKLQotCS8qKgotCSAqIFJldHVybnMgdGhlIGNvbmZpZ3VyYXRpb24gcG9saWN5IGRlY2xhcmVkIGluIHRoZSBjb21wb25lbnQgZGVzY3JpcHRvci4KLQkgKiBJZiB0aGUgY29tcG9uZW50IGRlc2NyaXB0b3IgaXMgYSBEZWNsYXJhdGl2ZSBTZXJ2aWNlcyAxLjAgZGVzY3JpcHRvciBvcgotCSAqIG5vdCBjb25maWd1cmF0aW9uIHBvbGljeSBoYXMgYmVlbiBkZWNsYXJlZCwgdGhlIGRlZmF1bHQgdmFsdWUKLQkgKiA8aT5vcHRpb25hbDwvaT4gaXMgcmV0dXJuZWQuCi0JICogPHA+Ci0JICogVGhlIHJldHVybmVkIHN0cmluZyBpcyBvbmUgb2YgdGhlIHRocmVlIHBvbGljaWVzIGRlZmluZWQgaW4gdGhlCi0JICogRGVjbGFyYXRpdmUgU2VydmljZXMgc3BlY2lmaWNhdGlvbiAxLjE6Ci0JICogPGRsPgotCSAqIDxkdD5vcHRpb25hbDwvZHQ+Ci0JICogPGRkPkNvbmZpZ3VyYXRpb24gZnJvbSB0aGUgQ29uZmlndXJhdGlvbiBBZG1pbiBzZXJ2aWNlIGlzIHN1cHBsaWVkIHRvCi0JICogdGhlIGNvbXBvbmVudCBpZiBhdmFpbGFibGUuIE90aGVyd2lzZSB0aGUgY29tcG9uZW50IGlzIGFjdGl2YXRlZCB3aXRob3V0Ci0JICogQ29uZmlndXJhdGlvbiBBZG1pbiBjb25maWd1cmF0aW9uLiBUaGlzIGlzIHRoZSBkZWZhdWx0IHZhbHVlIHJlZmxlY3RpbmcKLQkgKiB0aGUgYmVoYXZpb3Igb2YgRGVjbGFyYXRpdmUgU2VydmljZXMgMS4wPC9kZD4KLQkgKiA8ZHQ+cmVxdWlyZTwvZHQ+Ci0JICogPGRkPkNvbmZpZ3VyYXRpb24gaXMgcmVxdWlyZWQuIFRoZSBjb21wb25lbnQgcmVtYWlucyB1bnNhdGlzZmllZCB1bnRpbAotCSAqIGNvbmZpZ3VyYXRpb24gaXMgYXZhaWxhYmxlIGZyb20gdGhlIENvbmZpZ3VyYXRpb24gQWRtaW4gc2VydmljZS48L2RkPgotCSAqIDxkdD5pZ25vcmU8L2R0PgotCSAqIDxkZD5Db25maWd1cmF0aW9uIGlzIGlnbm9yZWQuIE5vIENvbmZpZ3VyYXRpb24gQWRtaW4gc2VydmljZQotCSAqIGNvbmZpZ3VyYXRpb24gaXMgc3VwcGxpZWQgdG8gdGhlIGNvbXBvbmVudC48L2RkPgotCSAqIDwvZGw+Ci0JICoKLQkgKiBAc2luY2UgMS4yCi0JICovCi0JU3RyaW5nIGdldENvbmZpZ3VyYXRpb25Qb2xpY3koKTsKLQotCS8qKgotCSAqIEVuYWJsZXMgdGhpcyBDb21wb25lbnQgaWYgaXQgaXMgZGlzYWJsZWQuIElmIHRoZSBDb21wb25lbnQgaXMgbm90Ci0JICogY3VycmVudGx5IHtAbGluayAjU1RBVEVfRElTQUJMRUQgZGlzYWJsZWR9IHRoaXMgbWV0aG9kIGhhcyBubyBlZmZlY3QuIElmCi0JICogdGhlIENvbXBvbmVudCBpcyB7QGxpbmsgI1NUQVRFX0RFU1RST1lFRCBkZXN0cm95ZWR9LCB0aGlzIG1ldGhvZCB0aHJvd3MKLQkgKiBhbiA8Y29kZT5JbGxlZ2FsU3RhdGVFeGNlcHRpb248L2NvZGU+LgotCSAqCi0JICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24gSWYgdGhlIENvbXBvbmVudCBpcyBkZXN0cm95ZWQuCi0JICovCi0Jdm9pZCBlbmFibGUoKTsKLQotCS8qKgotCSAqIERpc2FibGVzIHRoaXMgQ29tcG9uZW50IGlmIGl0IGlzIGVuYWJsZWQuIElmIHRoZSBDb21wb25lbnQgaXMgYWxyZWFkeQotCSAqIHtAbGluayAjU1RBVEVfRElTQUJMRUQgZGlzYWJsZWR9IHRoaXMgbWV0aG9kIGhhcyBubyBlZmZlY3QuIElmIHRoZQotCSAqIENvbXBvbmVudCBpcyB7QGxpbmsgI1NUQVRFX0RFU1RST1lFRCBkZXN0cm95ZWR9LCB0aGlzIG1ldGhvZCB0aHJvd3MgYW4KLQkgKiA8Y29kZT5JbGxlZ2FsU3RhdGVFeGNlcHRpb248L2NvZGU+LgotCSAqCi0JICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24gSWYgdGhlIENvbXBvbmVudCBpcyBkZXN0cm95ZWQuCi0JICovCi0Jdm9pZCBkaXNhYmxlKCk7Ci0KLX0KZGlmZiAtLWdpdCBhL2J1bmRsZXMvb3JnLmVjbGlwc2UuZXF1aW5veC5kcy9zcmMvb3JnL2FwYWNoZS9mZWxpeC9zY3IvUmVmZXJlbmNlLmphdmEgYi9idW5kbGVzL29yZy5lY2xpcHNlLmVxdWlub3guZHMvc3JjL29yZy9hcGFjaGUvZmVsaXgvc2NyL1JlZmVyZW5jZS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA3ODZkNGYwLi4wMDAwMDAwCi0tLSBhL2J1bmRsZXMvb3JnLmVjbGlwc2UuZXF1aW5veC5kcy9zcmMvb3JnL2FwYWNoZS9mZWxpeC9zY3IvUmVmZXJlbmNlLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMTkgKzAsMCBAQAotLyoKLSAqIExpY2Vuc2VkIHRvIHRoZSBBcGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbiAoQVNGKSB1bmRlciBvbmUKLSAqIG9yIG1vcmUgY29udHJpYnV0b3IgbGljZW5zZSBhZ3JlZW1lbnRzLiAgU2VlIHRoZSBOT1RJQ0UgZmlsZQotICogZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24KLSAqIHJlZ2FyZGluZyBjb3B5cmlnaHQgb3duZXJzaGlwLiAgVGhlIEFTRiBsaWNlbnNlcyB0aGlzIGZpbGUKLSAqIHRvIHlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUKLSAqICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2UKLSAqIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLSAqCi0gKiAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAotICoKLSAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywKLSAqIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuCi0gKiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKLSAqIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZQotICogc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZCBsaW1pdGF0aW9ucwotICogdW5kZXIgdGhlIExpY2Vuc2UuCi0gKi8KLXBhY2thZ2Ugb3JnLmFwYWNoZS5mZWxpeC5zY3I7Ci0KLWltcG9ydCBvcmcub3NnaS5mcmFtZXdvcmsuU2VydmljZVJlZmVyZW5jZTsKLQotLyoqCi0gKiBUaGUgPGNvZGU+UmVmZXJlbmNlPC9jb2RlPiBpbnRlcmZhY2UgcmVwcmVzZW50cyBhIHNpbmdsZSByZWZlcmVuY2UgKG9yCi0gKiBkZXBlbmRlbmN5KSB0byBhIHNlcnZpY2UgdXNlZCBieSBhIENvbXBvbmVudC4KLSAqLwotcHVibGljIGludGVyZmFjZSBSZWZlcmVuY2UgewotCi0JLyoqCi0JICogUmV0dXJucyB0aGUgbmFtZSBvZiB0aGlzIFJlZmVyZW5jZS4gVGhpcyBtZXRob2QgcHJvdmlkZXMgYWNjZXNzIHRvIHRoZQotCSAqIDxjb2RlPm5hbWU8L2NvZGU+IGF0dHJpYnV0ZSBvZiB0aGUgPGNvZGU+cmVmZXJlbmNlPC9jb2RlPiBlbGVtZW50LgotCSAqLwotCVN0cmluZyBnZXROYW1lKCk7Ci0KLQkvKioKLQkgKiBSZXR1cm5zIHRoZSBuYW1lIG9mIHRoZSBzZXJ2aWNlIHVzZWQgYnkgdGhpcyBSZWZlcmVuY2UuIFRoaXMgbWV0aG9kCi0JICogcHJvdmlkZXMgYWNjZXNzIHRvIHRoZSA8Y29kZT5pbnRlcmZhY2U8L2NvZGU+IGF0dHJpYnV0ZSBvZiB0aGUKLQkgKiA8Y29kZT5yZWZlcmVuY2U8L2NvZGU+IGVsZW1lbnQuCi0JICovCi0JU3RyaW5nIGdldFNlcnZpY2VOYW1lKCk7Ci0KLQkvKioKLQkgKiBSZXR1cm5zIGFuIGFycmF5IG9mIHJlZmVyZW5jZXMgdG8gdGhlIHNlcnZpY2VzIGJvdW5kIHRvIHRoaXMgUmVmZXJlbmNlCi0JICogb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYgbm8gc2VydmljZXMgYXJlIGN1cnJlbnRseSBib3VuZC4KLQkgKi8KLQlTZXJ2aWNlUmVmZXJlbmNlW10gZ2V0U2VydmljZVJlZmVyZW5jZXMoKTsKLQotCS8qKgotCSAqIFJldHVybnMgd2hldGhlciB0aGlzIHJlZmVyZW5jZSBpcyBzYXRpc2ZpZWQuIEEge0BsaW5rICNpc09wdGlvbmFsKCkgb3B0aW9uYWx9Ci0JICogY29tcG9uZW50IGlzIGFsd2F5cyBzYXRpc2ZpZWQuIE90aGVyd2lzZSA8Y29kZT50cnVlPC9jb2RlPiBpcyBvbmx5Ci0JICogcmV0dXJuZWQgaWYgYXQgbGVhc3Qgb25lIHNlcnZpY2UgaXMgYm91bmQuCi0JICovCi0JYm9vbGVhbiBpc1NhdGlzZmllZCgpOwotCi0JLyoqCi0JICogUmV0dXJucyB3aGV0aGVyIHRoaXMgcmVmZXJlbmNlIGlzIG9wdGlvbmFsLiBUaGlzIG1ldGhvZCBwcm92aWRlcyBhY2Nlc3MKLQkgKiB0byB0aGUgbG93ZXIgYm91bmQgb2YgdGhlIDxjb2RlPmNhcmRpbmFsaXR5PC9jb2RlPiBhdHRyaWJ1dGUgb2YgdGhlCi0JICogPGNvZGU+cmVmZXJlbmNlPC9jb2RlPiBlbGVtZW50LiBJbiBvdGhlciB3b3JkcywgdGhpcyBtZXRob2QgcmV0dXJucwotCSAqIDxjb2RlPnRydWU8L2NvZGU+IGlmIHRoZSBjYXJkaW5hbGl0eSBpcyA8ZW0+MC4uMTwvZW0+IG9yIDxlbT4wLi5uPC9lbT4uCi0JICovCi0JYm9vbGVhbiBpc09wdGlvbmFsKCk7Ci0KLQkvKioKLQkgKiBSZXR1cm5zIHdoZXRoZXIgdGhpcyByZWZlcmVuY2UgaXMgbXVsdGlwbGUuIFRoaXMgbWV0aG9kIHByb3ZpZGVzIGFjY2VzcwotCSAqIHRvIHRoZSB1cHBlciBib3VuZCBvZiB0aGUgPGNvZGU+Y2FyZGluYWxpdHk8L2NvZGU+IGF0dHJpYnV0ZSBvZiB0aGUKLQkgKiA8Y29kZT5yZWZlcmVuY2U8L2NvZGU+IGVsZW1lbnQuIEluIG90aGVyIHdvcmRzLCB0aGlzIG1ldGhvZCByZXR1cm5zCi0JICogPGNvZGU+dHJ1ZTwvY29kZT4gaWYgdGhlIGNhcmRpbmFsaXR5IGlzIDxlbT4wLi5uPC9lbT4gb3IgPGVtPjEuLm48L2VtPi4KLQkgKi8KLQlib29sZWFuIGlzTXVsdGlwbGUoKTsKLQotCS8qKgotCSAqIFJldHVybnMgPGNvZGU+dHJ1ZTwvY29kZT4gaWYgdGhlIHJlZmVyZW5jZSBpcyBkZWZpbmVkIHdpdGggc3RhdGljIHBvbGljeS4KLQkgKiBUaGlzIG1ldGhvZCBwcm92aWRlcyBhY2Nlc3MgdG8gdGhlIDxjb2RlPnBvbGljeTwvY29kZT4gZWxlbWVudCBvZiB0aGUKLQkgKiA8Y29kZT5yZWZlcmVuY2U8L2NvZGU+IGVsZW1lbnQuIDxjb2RlPnRydWU8L2NvZGU+IGlzIHJldHVybmVkIGlmIHRoZQotCSAqIHBvbGljeSBpcyBkZWZpbmVkIGFzIDxlbT5zdGF0aWM8L2VtPi4KLQkgKi8KLQlib29sZWFuIGlzU3RhdGljKCk7Ci0KLQkvKioKLQkgKiBSZXR1cm5zIHRoZSB2YWx1ZSBvZiB0aGUgdGFyZ2V0IHByb3BlcnR5IG9mIHRoaXMgcmVmZXJlbmNlLiBJbml0aWFsbHkKLQkgKiAod2l0aG91dCBvdmVyd3JpdGluZyBjb25maWd1cmF0aW9uKSB0aGlzIG1ldGhvZCBwcm92aWRlcyBhY2Nlc3MgdG8gdGhlCi0JICogPGNvZGU+dGFyZ2V0PC9jb2RlPiBhdHRyaWJ1dGUgb2YgdGhlIDxjb2RlPnJlZmVyZW5jZTwvY29kZT4gZWxlbWVudC4gSWYKLQkgKiBjb25maWd1cmF0aW9uIG92ZXJ3cml0ZXMgdGhlIHRhcmdldCBwcm9wZXJ0eSwgdGhpcyBtZXRob2QgcmV0dXJucyB0aGUKLQkgKiB2YWx1ZSBvZiB0aGUgQ29tcG9uZW50IHByb3BlcnR5IHdob3NlIG5hbWUgaXMgZGVyaXZlZCBmcm9tIHRoZQotCSAqIHtAbGluayAjZ2V0TmFtZSgpIHJlZmVyZW5jZSBuYW1lfSBwbHVzIHRoZSBzdWZmaXggPGVtPi50YXJnZXQ8L2VtPi4gSWYKLQkgKiBubyB0YXJnZXQgcHJvcGVydHkgZXhpc3RzIHRoaXMgbWV0aG9kIHJldHVybnMgPGNvZGU+bnVsbDwvY29kZT4uCi0JICovCi0JU3RyaW5nIGdldFRhcmdldCgpOwotCi0JLyoqCi0JICogUmV0dXJucyB0aGUgbmFtZSBvZiB0aGUgbWV0aG9kIGNhbGxlZCBpZiBhIHNlcnZpY2UgaXMgYmVpbmcgYm91bmQgdG8KLQkgKiB0aGUgQ29tcG9uZW50IG9yIDxjb2RlPm51bGw8L2NvZGU+IGlmIG5vIHN1Y2ggbWV0aG9kIGlzIGNvbmZpZ3VyZWQuIFRoaXMKLQkgKiBtZXRob2QgcHJvdmlkZXMgYWNjZXNzIHRvIHRoZSA8Y29kZT5iaW5kPC9jb2RlPiBhdHRyaWJ1dGUgb2YgdGhlCi0JICogPGNvZGU+cmVmZXJlbmNlPC9jb2RlPiBlbGVtZW50LgotCSAqLwotCVN0cmluZyBnZXRCaW5kTWV0aG9kTmFtZSgpOwotCi0JLyoqCi0JICogUmV0dXJucyB0aGUgbmFtZSBvZiB0aGUgbWV0aG9kIGNhbGxlZCBpZiBhIHNlcnZpY2UgaXMgYmVpbmcgdW5ib3VuZCBmcm9tCi0JICogdGhlIENvbXBvbmVudCBvciA8Y29kZT5udWxsPC9jb2RlPiBpZiBubyBzdWNoIG1ldGhvZCBpcyBjb25maWd1cmVkLiBUaGlzCi0JICogbWV0aG9kIHByb3ZpZGVzIGFjY2VzcyB0byB0aGUgPGNvZGU+dW5iaW5kPC9jb2RlPiBhdHRyaWJ1dGUgb2YgdGhlCi0JICogPGNvZGU+cmVmZXJlbmNlPC9jb2RlPiBlbGVtZW50LgotCSAqLwotCVN0cmluZyBnZXRVbmJpbmRNZXRob2ROYW1lKCk7Ci0KLQkvKioKLQkgKiBSZXR1cm5zIHRoZSBuYW1lIG9mIHRoZSBtZXRob2QgY2FsbGVkIGlmIGEgYm91bmQgc2VydmljZSB1cGRhdGVzIGl0cwotCSAqIHNlcnZpY2UgcmVnaXN0cmF0aW9uIHByb3BlcnRpZXMgb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYgbm8gc3VjaCBtZXRob2QKLQkgKiBpcyBjb25maWd1cmVkLiBUaGlzIG1ldGhvZCBwcm92aWRlcyBhY2Nlc3MgdG8gdGhlIDxjb2RlPnVwZGF0ZWQ8L2NvZGU+Ci0JICogYXR0cmlidXRlIG9mIHRoZSA8Y29kZT5yZWZlcmVuY2U8L2NvZGU+IGVsZW1lbnQuCi0JICogPHA+Ci0JICogRm9yIGEgY29tcG9uZW50IGRlY2xhcmVkIGluIGEgRGVjbGFyYXRpdmUgU2VydmljZXMgMS4wIGFuZCAxLjEKLQkgKiBkZXNjcmlwdG9yLCB0aGlzIG1ldGhvZCBhbHdheXMgcmV0dXJucyA8Y29kZT5udWxsPC9jb2RlPi4KLQkgKgotCSAqIEBzaW5jZSAxLjQKLQkgKi8KLQlTdHJpbmcgZ2V0VXBkYXRlZE1ldGhvZE5hbWUoKTsKLQotfQpkaWZmIC0tZ2l0IGEvYnVuZGxlcy9vcmcuZWNsaXBzZS5lcXVpbm94LmRzL3NyYy9vcmcvYXBhY2hlL2ZlbGl4L3Njci9TY3JTZXJ2aWNlLmphdmEgYi9idW5kbGVzL29yZy5lY2xpcHNlLmVxdWlub3guZHMvc3JjL29yZy9hcGFjaGUvZmVsaXgvc2NyL1NjclNlcnZpY2UuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMzg1YjJkMS4uMDAwMDAwMAotLS0gYS9idW5kbGVzL29yZy5lY2xpcHNlLmVxdWlub3guZHMvc3JjL29yZy9hcGFjaGUvZmVsaXgvc2NyL1NjclNlcnZpY2UuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDgzICswLDAgQEAKLS8qCi0gKiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lCi0gKiBvciBtb3JlIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUKLSAqIGRpc3RyaWJ1dGVkIHdpdGggdGhpcyB3b3JrIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uCi0gKiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlCi0gKiB0byB5b3UgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlCi0gKiAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlCi0gKiB3aXRoIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0Ci0gKgotICogICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLSAqCi0gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsCi0gKiBzb2Z0d2FyZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbgotICogIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZCi0gKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUKLSAqIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnMKLSAqIHVuZGVyIHRoZSBMaWNlbnNlLgotICovCi1wYWNrYWdlIG9yZy5hcGFjaGUuZmVsaXguc2NyOwotCi1pbXBvcnQgb3JnLm9zZ2kuZnJhbWV3b3JrLkJ1bmRsZTsKLQotLyoqCi0gKiBUaGUgPGNvZGU+U2NyU2VydmljZTwvY29kZT4gcmVwcmVzZW50cyB0aGUgRGVjbGFyYXRpdmUgU2VydmljZXMgbWFpbgotICogY29udHJvbGxlciBhbHNvIGtub3duIGFzIHRoZSBTZXJ2aWNlIENvbXBvbmVudCBSdW50aW1lIG9yIFNDUiBmb3Igc2hvcnQuCi0gKiBJdCBwcm92aWRlcyBhY2Nlc3MgdG8gdGhlIGNvbXBvbmVudHMgbWFuYWdlZCB0aGUgU0NSLgotICovCi1wdWJsaWMgaW50ZXJmYWNlIFNjclNlcnZpY2UgewotCi0JLyoqCi0JICogUmV0dXJucyBhbiBhcnJheSBvZiBhbGwgY29tcG9uZW50cyBtYW5hZ2VkIGJ5IHRoaXMgU0NSIGluc3RhbmNlLiBUaGUKLQkgKiBjb21wb25lbnRzIGFyZSByZXR1cm5lZCBpbiBhc2NlbmRpbmcgb3JkZXIgb2YgdGhlaXIgY29tcG9uZW50LmlkLiBJZgotCSAqIHRoZXJlIGFyZSBubyBjb21wb25lbnRzIGN1cnJlbnRseSBtYW5hZ2VkIGJ5IHRoZSBTQ1IsIDxjb2RlPm51bGw8L2NvZGU+Ci0JICogaXMgcmV0dXJuZWQuCi0JICoKLQkgKiBAcmV0dXJuIFRoZSBjb21wb25lbnRzIG9yIDxjb2RlPm51bGw8L2NvZGU+IGlmIHRoZXJlIGFyZSBub25lLgotCSAqLwotCUNvbXBvbmVudFtdIGdldENvbXBvbmVudHMoKTsKLQotCS8qKgotCSAqIFJldHVybnMgdGhlIGNvbXBvbmVudCB3aG9zZSBjb21wb25lbnQuaWQgbWF0Y2hlcyB0aGUgZ2l2ZW4KLQkgKiA8Y29kZT5jb21wb25lbnRJZDwvY29kZT4gb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYgbm8gY29tcG9uZW50IHdpdGggdGhlCi0JICogZ2l2ZW4gaWQgaXMgY3VycmVudGx5IG1hbmFnZWQuCi0JICoKLQkgKiBAcGFyYW0gY29tcG9uZW50SWQgVGhlIElEIG9mIHRoZSBjb21wb25lbnQgdG8gcmV0dXJuCi0JICoKLQkgKiBAcmV0dXJuIFRoZSBpbmRpY2F0ZWQgY29tcG9uZW50IG9yIDxjb2RlPm51bGw8L2NvZGU+IGlmIG5vIHN1Y2gKLQkgKiAgICAgIGNvbXBvbmVudCBleGlzdHMuCi0JICovCi0JQ29tcG9uZW50IGdldENvbXBvbmVudChsb25nIGNvbXBvbmVudElkKTsKLQotCS8qKgotCSAqIFJldHVybnMgdGhlIGNvbXBvbmVudHMgd2hvc2UgPGNvZGU+Y29tcG9uZW50Lm5hbWU8L2NvZGU+IG1hdGNoZXMgdGhlCi0JICogZ2l2ZW4gPGNvZGU+Y29tcG9uZW50TmFtZTwvY29kZT4gb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYgbm8gY29tcG9uZW50Ci0JICogd2l0aCB0aGUgZ2l2ZW4gbmFtZSBpcyBjdXJyZW50bHkgbWFuYWdlZC4KLQkgKiA8cD4KLQkgKiBJZiB0aGUgY29tcG9uZW50IG5hbWUgcmVmZXJzIHRvIGEgY29tcG9uZW50IGZhY3RvcnkgY29tcG9uZW50IG9yIGEKLQkgKiBjb21wb25lbnQgY29uZmlndXJlZCB3aXRoIG11bHRpcGxlIGZhY3RvcnkgY29uZmlndXJhdGlvbnMgdGhpcyBtZXRob2QKLQkgKiByZXR1cm5zIG11bHRpcGxlIGNvbXBvbmVudCBpbnN0YW5jZXMuCi0JICoKLQkgKiBAcGFyYW0gY29tcG9uZW50TmFtZSBUaGUgbmFtZSBvZiB0aGUgY29tcG9uZW50IHRvIHJldHVybgotCSAqCi0JICogQHJldHVybiBUaGUgaW5kaWNhdGVkIGNvbXBvbmVudHMgb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYgbm8gc3VjaAotCSAqICAgICAgY29tcG9uZW50IGV4aXN0cy4KLQkgKiBAc2luY2UgMS41IChBcGFjaGUgRmVsaXggRGVjbGFyYXRpdmUgU2VydmljZXMgMS40LjIpCi0JICovCi0JQ29tcG9uZW50W10gZ2V0Q29tcG9uZW50cyhTdHJpbmcgY29tcG9uZW50TmFtZSk7Ci0KLQkvKioKLQkgKiBSZXR1cm5zIGFuIGFycmF5IG9mIGFsbCBjb21wb25lbnRzIG1hbmFnZWQgYnkgdGhpcyBTQ1IgaW5zdGFuY2Ugb24KLQkgKiBiZWhhbGYgb2YgdGhlIGdpdmVuIGJ1bmRsZS4gVGhlIGNvbXBvbmVudHMgYXJlIHJldHVybmVkIGluIGFzY2VuZGluZwotCSAqIG9yZGVyIG9mIHRoZWlyIGNvbXBvbmVudC5pZC4gSWYgdGhlcmUgYXJlIG5vIGNvbXBvbmVudHMgbWFuYWdlZCBieSB0aGUKLQkgKiBTQ1IgZm9yIHRoZSBnaXZlbiBidW5kbGUsIDxjb2RlPm51bGw8L2NvZGU+IGlzIHJldHVybmVkLgotCSAqCi0JICogQHBhcmFtIGJ1bmRsZSBUaGUgPGNvZGU+QnVuZGxlPC9jb2RlPiB3aG9zZSBjb21wb25lbnRzIGFyZSB0byBiZQotCSAqICAgICAgcmV0dXJuZWQuCi0JICoKLQkgKiBAcmV0dXJuIFRoZSBidW5kbGUncyBjb21wb25lbnRzIG9yIDxjb2RlPm51bGw8L2NvZGU+IGlmIHRoZSBidW5kbGUKLQkgKiAgICAgIGhhcyBub25lLgotCSAqLwotCUNvbXBvbmVudFtdIGdldENvbXBvbmVudHMoQnVuZGxlIGJ1bmRsZSk7Ci0KLX0KZGlmZiAtLWdpdCBhL2J1bmRsZXMvb3JnLmVjbGlwc2UuZXF1aW5veC5kcy9zcmMvb3JnL2FwYWNoZS9mZWxpeC9zY3IvcGFja2FnZS5odG1sIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5lcXVpbm94LmRzL3NyYy9vcmcvYXBhY2hlL2ZlbGl4L3Njci9wYWNrYWdlLmh0bWwKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDRlZmI4ZDkuLjAwMDAwMDAKLS0tIGEvYnVuZGxlcy9vcmcuZWNsaXBzZS5lcXVpbm94LmRzL3NyYy9vcmcvYXBhY2hlL2ZlbGl4L3Njci9wYWNrYWdlLmh0bWwKKysrIC9kZXYvbnVsbApAQCAtMSwxNSArMCwwIEBACi08IURPQ1RZUEUgSFRNTCBQVUJMSUMgIi0vL1czQy8vRFREIEhUTUwgNC4wIFRyYW5zaXRpb25hbC8vRU4iPgotPGh0bWw+Ci08aGVhZD4KLSAgIDxtZXRhIGh0dHAtZXF1aXY9IkNvbnRlbnQtVHlwZSIgY29udGVudD0idGV4dC9odG1sOyBjaGFyc2V0PWlzby04ODU5LTEiPgotICAgPHRpdGxlPlBhY2thZ2UtbGV2ZWwgSmF2YWRvYzwvdGl0bGU+Ci08L2hlYWQ+Ci08Ym9keT4KLVByb3ZpZGVzIGFjY2VzcyB0byB0aGUgY29tcG9uZW50cyBtYW5hZ2VkIGJ5IHRoZSBTZXJ2aWNlIENvbXBvbmVudCBSdW50aW1lIChEZWNsYXJhdGl2ZSBTZXJ2aWNlcykuCi08aDI+Ci1QYWNrYWdlIFNwZWNpZmljYXRpb248L2gyPgotPHA+Ci1UaGlzIHBhY2thZ2Ugc3BlY2lmaWVzIEFQSSBmb3IgYWNjZXNzaW5nIHRvIHRoZSBjb21wb25lbnRzIG1hbmFnZWQgYnkgdGhlIFNlcnZpY2UgQ29tcG9uZW50IFJ1bnRpbWUgKERlY2xhcmF0aXZlIFNlcnZpY2VzKS4KLTwvcD4KLTwvYm9keT4KLTwvaHRtbD4KZGlmZiAtLWdpdCBhL2J1bmRsZXMvb3JnLmVjbGlwc2UuZXF1aW5veC5kcy9zcmMvb3JnL2VjbGlwc2UvZXF1aW5veC9pbnRlcm5hbC9kcy9BY3RpdmF0b3IuamF2YSBiL2J1bmRsZXMvb3JnLmVjbGlwc2UuZXF1aW5veC5kcy9zcmMvb3JnL2VjbGlwc2UvZXF1aW5veC9pbnRlcm5hbC9kcy9BY3RpdmF0b3IuamF2YQppbmRleCAyOGQ2ZThlLi5kMTYzZWJkIDEwMDY0NAotLS0gYS9idW5kbGVzL29yZy5lY2xpcHNlLmVxdWlub3guZHMvc3JjL29yZy9lY2xpcHNlL2VxdWlub3gvaW50ZXJuYWwvZHMvQWN0aXZhdG9yLmphdmEKKysrIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5lcXVpbm94LmRzL3NyYy9vcmcvZWNsaXBzZS9lcXVpbm94L2ludGVybmFsL2RzL0FjdGl2YXRvci5qYXZhCkBAIC0xLDQzOCArMSw1NSBAQAogLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKLSAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxMyBieSBQcm9TeXN0IFNvZnR3YXJlIEdtYkgKLSAqIGh0dHA6Ly93d3cucHJvc3lzdC5jb20KKyAqIENvcHlyaWdodCAoYykgMjAxNiBJQk0gQ29ycG9yYXRpb24gYW5kIG90aGVycy4KICAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMKICAqIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2UgdjEuMAogICogd2hpY2ggYWNjb21wYW5pZXMgdGhpcyBkaXN0cmlidXRpb24sIGFuZCBpcyBhdmFpbGFibGUgYXQKICAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLXYxMC5odG1sCi0gKgorICogCiAgKiBDb250cmlidXRvcnM6Ci0gKiAgICBQcm9TeXN0IFNvZnR3YXJlIEdtYkggLSBpbml0aWFsIEFQSSBhbmQgaW1wbGVtZW50YXRpb24KKyAqICAgICBJQk0gQ29ycG9yYXRpb24gLSBpbml0aWFsIEFQSSBhbmQgaW1wbGVtZW50YXRpb24KICAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwogcGFja2FnZSBvcmcuZWNsaXBzZS5lcXVpbm94LmludGVybmFsLmRzOwogCi1pbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKLWltcG9ydCBqYXZhLnV0aWwuRGljdGlvbmFyeTsKLWltcG9ydCBqYXZhLnV0aWwuSGFzaHRhYmxlOwotaW1wb3J0IG9yZy5hcGFjaGUuZmVsaXguc2NyLlNjclNlcnZpY2U7Ci1pbXBvcnQgb3JnLmVjbGlwc2UuZXF1aW5veC5pbnRlcm5hbC51dGlsLnJlZi5Mb2c7Ci1pbXBvcnQgb3JnLmVjbGlwc2Uub3NnaS5mcmFtZXdvcmsubG9nLkZyYW1ld29ya0xvZzsKLWltcG9ydCBvcmcuZWNsaXBzZS5vc2dpLmZyYW1ld29yay5sb2cuRnJhbWV3b3JrTG9nRW50cnk7Ci1pbXBvcnQgb3JnLmVjbGlwc2Uub3NnaS5zZXJ2aWNlLmRlYnVnLkRlYnVnT3B0aW9uczsKK2ltcG9ydCBqYXZhLnV0aWwuTGlzdDsKIGltcG9ydCBvcmcuZWNsaXBzZS5vc2dpLnNlcnZpY2UuZW52aXJvbm1lbnQuRW52aXJvbm1lbnRJbmZvOwogaW1wb3J0IG9yZy5vc2dpLmZyYW1ld29yay4qOwotaW1wb3J0IG9yZy5vc2dpLnNlcnZpY2UuY20uKjsKLWltcG9ydCBvcmcub3NnaS5zZXJ2aWNlLmNvbXBvbmVudC5Db21wb25lbnRDb25zdGFudHM7Ci1pbXBvcnQgb3JnLm9zZ2kuc2VydmljZS5sb2cuTG9nU2VydmljZTsKLWltcG9ydCBvcmcub3NnaS51dGlsLnRyYWNrZXIuU2VydmljZVRyYWNrZXI7CitpbXBvcnQgb3JnLm9zZ2kuZnJhbWV3b3JrLm5hbWVzcGFjZS5CdW5kbGVOYW1lc3BhY2U7CitpbXBvcnQgb3JnLm9zZ2kuZnJhbWV3b3JrLnN0YXJ0bGV2ZWwuQnVuZGxlU3RhcnRMZXZlbDsKK2ltcG9ydCBvcmcub3NnaS5mcmFtZXdvcmsud2lyaW5nLkJ1bmRsZVdpcmU7CitpbXBvcnQgb3JnLm9zZ2kuZnJhbWV3b3JrLndpcmluZy5CdW5kbGVXaXJpbmc7CiAKLS8qKgotICogVGhpcyBpcyB0aGUgbWFpbiBzdGFydGluZyBjbGFzcyBmb3IgdGhlIFNlcnZpY2UgQ29tcG9uZW50IFJ1bnRpbWUuCi0gKiBUaGUgU0NSIGlzIG5vdCBmdWxseSBpbml0aWFsaXplZCB1bnRpbCBpdCBkZXRlY3RzIGF0IGxlYXN0IG9uZSBidW5kbGUgcHJvdmlkaW5nIERTIGNvbXBvbmVudHMuIAotICogVGh1cyBpdCBoYXMgY29uc2lkZXJhYmx5IHNtYWxsIHN0YXJ0dXAgdGltZSBhbmQgZG9lcyBpbXByb3ZlIGEgbGl0dGxlIHRoZSBydW50aW1lIHBlcmZvcm1hbmNlIAotICogc2luY2UgaXQgZG9lcyBub3QgbGlzdGVuIGZvciBzZXJ2aWNlIGV2ZW50cy4KLSAqIAotICogQGF1dGhvciBWYWxlbnRpbiBWYWxjaGV2Ci0gKiBAYXV0aG9yIFN0b3lhbiBCb3NoZXYKLSAqIEBhdXRob3IgUGF2bGluIERvYnJldgotICovCitwdWJsaWMgY2xhc3MgQWN0aXZhdG9yIGltcGxlbWVudHMgQnVuZGxlQWN0aXZhdG9yIHsKIAotcHVibGljIGNsYXNzIEFjdGl2YXRvciBpbXBsZW1lbnRzIEJ1bmRsZUFjdGl2YXRvciwgU3luY2hyb25vdXNCdW5kbGVMaXN0ZW5lciwgU2VydmljZUxpc3RlbmVyIHsKLQotCXB1YmxpYyBzdGF0aWMgQnVuZGxlQ29udGV4dCBiYyA9IG51bGw7Ci0JcHVibGljIHN0YXRpYyBDb25maWd1cmF0aW9uQWRtaW4gY29uZmlnQWRtaW4gPSBudWxsOwotCXB1YmxpYyBzdGF0aWMgYm9vbGVhbiBzZWN1cml0eSA9IGZhbHNlOwotCi0JcHJpdmF0ZSBTZXJ2aWNlUmVnaXN0cmF0aW9uIGNvbmZpZ0xpc3RlbmVyUmVnOwotCXByaXZhdGUgU0NSTWFuYWdlciBzY3JNYW5hZ2VyID0gbnVsbDsKLQlwdWJsaWMgU2NyU2VydmljZUltcGwgc2NyU2VydmljZSA9IG51bGw7Ci0JcHJpdmF0ZSBTZXJ2aWNlUmVnaXN0cmF0aW9uIHNjclNlcnZpY2VSZWc7Ci0JcHJpdmF0ZSBTZXJ2aWNlUmVnaXN0cmF0aW9uIHNjckNvbW1hbmRQcm92aWRlclJlZzsKLQlwcml2YXRlIHN0YXRpYyBGcmFtZXdvcmtMb2cgZndMb2c7Ci0JcHJpdmF0ZSBib29sZWFuIGluaXRlZCA9IGZhbHNlOwotCi0JcHVibGljIHN0YXRpYyBMb2cgbG9nOwotCXB1YmxpYyBzdGF0aWMgYm9vbGVhbiBERUJVRzsKLQlwdWJsaWMgc3RhdGljIGJvb2xlYW4gUEVSRjsKLQlwdWJsaWMgc3RhdGljIGJvb2xlYW4gREJTVE9SRTsKLQlwdWJsaWMgc3RhdGljIGJvb2xlYW4gSU5TVEFOVElBVEVfQUxMOwotCXB1YmxpYyBzdGF0aWMgYm9vbGVhbiBzdGFydHVwOwotCi0Jc3RhdGljIGxvbmcgdGltZVtdID0gbnVsbDsKLQotCXB1YmxpYyBzdGF0aWMgdm9pZCB0aW1lTG9nKFN0cmluZyBtZXNzYWdlKSB7Ci0JCXRpbWVbMV0gPSB0aW1lWzBdOwotCQlsb2cuZGVidWcobWVzc2FnZSArIFN0cmluZy52YWx1ZU9mKCh0aW1lWzBdID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCkpIC0gdGltZVsxXSksIG51bGwpOwotCX0KLQotCXByaXZhdGUgdm9pZCBpbml0U0NSKCkgewotCQlzeW5jaHJvbml6ZWQgKHRoaXMpIHsKLQkJCWlmIChpbml0ZWQpCi0JCQkJcmV0dXJuOwotCQkJaW5pdGVkID0gdHJ1ZTsKLQkJfQotCi0JCWJvb2xlYW4gbGF6eUluaXRpbmcgPSBmYWxzZTsKLQkJaWYgKHN0YXJ0dXAgJiYgdGltZSA9PSBudWxsKSB7Ci0JCQlsb25nIHRtcCA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOwotCQkJdGltZSA9IG5ldyBsb25nW10ge3RtcCwgMCwgdG1wfTsKLQkJCWxhenlJbml0aW5nID0gdHJ1ZTsKLQkJCWlmIChzdGFydHVwKQotCQkJCXRpbWVMb2coIltCRUdJTiAtIGxhenkgU0NSIGluaXRdIik7IC8vJE5PTi1OTFMtMSQKLQkJfQotCi0JCVdvcmtUaHJlYWQuSURMRV9USU1FT1VUID0gZ2V0SW50ZWdlcigiZXF1aW5veC5kcy5pZGxlX3RpbWVvdXQiLCAxMDAwKTsgLy8kTk9OLU5MUy0xJAotCQlXb3JrVGhyZWFkLkJMT0NLX1RJTUVPVVQgPSBnZXRJbnRlZ2VyKCJlcXVpbm94LmRzLmJsb2NrX3RpbWVvdXQiLCAzMDAwMCk7IC8vJE5PTi1OTFMtMSQKLQotCQl0cnkgewotCQkJYmMuYWRkU2VydmljZUxpc3RlbmVyKHRoaXMsICIob2JqZWN0Q2xhc3M9IiArIENvbmZpZ3VyYXRpb25BZG1pbi5jbGFzcy5nZXROYW1lKCkgKyAnKScpOyAvLyROT04tTkxTLTEkCi0JCX0gY2F0Y2ggKEludmFsaWRTeW50YXhFeGNlcHRpb24gZSkgewotCQkJLy9zaG91bGQgbmV2ZXIgaGFwcGVuCi0JCX0KLQkJLy9nZXQgY29uZmlnIGFkbWluIHNlcnZpY2UgaWYgYXZhaWxhYmxlCi0JCVNlcnZpY2VSZWZlcmVuY2UgY2FSZWYgPSBiYy5nZXRTZXJ2aWNlUmVmZXJlbmNlKENvbmZpZ3VyYXRpb25BZG1pbi5jbGFzcy5nZXROYW1lKCkpOwotCQlpZiAoY2FSZWYgIT0gbnVsbCkgewotCQkJY29uZmlnQWRtaW4gPSAoQ29uZmlndXJhdGlvbkFkbWluKSBiYy5nZXRTZXJ2aWNlKGNhUmVmKTsKLQkJfQotCQlpZiAoc3RhcnR1cCkKLQkJCXRpbWVMb2coIkNvbmZpZ3VyYXRpb25BZG1pbiBzZXJ2aWNlIGdldHRpbmcgdG9vayAiKTsgLy8kTk9OLU5MUy0xJAotCi0JCXNjck1hbmFnZXIgPSBuZXcgU0NSTWFuYWdlcigpOwotCQlpZiAoc3RhcnR1cCkKLQkJCXRpbWVMb2coIlNDUk1hbmFnZXIgaW5zdGFudGlhdGlvbiB0b29rICIpOyAvLyROT04tTkxTLTEkCi0KLQkJLy8gYWRkIHRoZSBjb25maWd1cmF0aW9uIGxpc3RlbmVyIC0gd2UgdG8gcmVjZWl2ZSBDTSBldmVudHMgdG8gcmVzdGFydAotCQkvLyBjb21wb25lbnRzCi0JCWNvbmZpZ0xpc3RlbmVyUmVnID0gYmMucmVnaXN0ZXJTZXJ2aWNlKENvbmZpZ3VyYXRpb25MaXN0ZW5lci5jbGFzcy5nZXROYW1lKCksIHNjck1hbmFnZXIsIG51bGwpOwotCQlpZiAoc3RhcnR1cCkKLQkJCXRpbWVMb2coIkNvbmZpZ3VyYXRpb25MaXN0ZW5lciBzZXJ2aWNlIHJlZ2lzdGVyZWQgZm9yICIpOyAvLyROT04tTkxTLTEkCi0JCWJjLmFkZFNlcnZpY2VMaXN0ZW5lcihzY3JNYW5hZ2VyKTsKLQotCQlzY3JNYW5hZ2VyLnN0YXJ0SXQoKTsKLQkJaWYgKEFjdGl2YXRvci5zdGFydHVwKQotCQkJQWN0aXZhdG9yLnRpbWVMb2coInN0YXJ0SXQoKSBtZXRob2QgdG9vayAiKTsgLy8kTk9OLU5MUy0xJAotCi0JCWluc3RhbGxDb21tYW5kUHJvdmlkZXIoKTsKLQotCQlpZiAoc3RhcnR1cCAmJiBsYXp5SW5pdGluZykgewotCQkJbG9nLmRlYnVnKCJbRU5EIC0gbGF6eSBTQ1IgaW5pdF0gQWN0aXZhdG9yLmluaXRTQ1IoKSBtZXRob2QgZXhlY3V0ZWQgZm9yICIgKyBTdHJpbmcudmFsdWVPZih0aW1lWzBdIC0gdGltZVsyXSksIG51bGwpOyAvLyROT04tTkxTLTEkCi0JCQl0aW1lID0gbnVsbDsKLQkJfQotCX0KLQotCS8qCi0JICogKG5vbi1KYXZhZG9jKQotCSAqIAotCSAqIEBzZWUgb3JnLm9zZ2kuZnJhbWV3b3JrLkJ1bmRsZUFjdGl2YXRvciNzdGFydChvcmcub3NnaS5mcmFtZXdvcmsuQnVuZGxlQ29udGV4dCkKLQkgKi8KLQlwdWJsaWMgdm9pZCBzdGFydChCdW5kbGVDb250ZXh0IGJ1bmRsZUNvbnRleHQpIHRocm93cyBFeGNlcHRpb24gewotCQlBY3RpdmF0b3IuYmMgPSBidW5kbGVDb250ZXh0OwotCQlzdGFydHVwID0gZ2V0Qm9vbGVhbigiZXF1aW5veC5tZWFzdXJlbWVudHMuYnVuZGxlcyIsIGZhbHNlKTsgLy8kTk9OLU5MUy0xJAotCQlpZiAoc3RhcnR1cCkgewotCQkJbG9uZyB0bXAgPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKTsKLQkJCXRpbWUgPSBuZXcgbG9uZ1tdIHt0bXAsIDAsIHRtcH07Ci0JCX0KLQkJLy8gaW5pdGlhbGl6ZSB0aGUgbG9nZ2luZyByb3V0aW5lcwotCQlsb2cgPSBuZXcgTG9nKGJ1bmRsZUNvbnRleHQsIGZhbHNlKTsKLQkJU2VydmljZVRyYWNrZXIgZGVidWdUcmFja2VyID0gbmV3IFNlcnZpY2VUcmFja2VyKGJ1bmRsZUNvbnRleHQsIERlYnVnT3B0aW9ucy5jbGFzcy5nZXROYW1lKCksIG51bGwpOwotCQlkZWJ1Z1RyYWNrZXIub3BlbigpOwotCQlEZWJ1Z09wdGlvbnMgZGVidWdPcHRpb25zID0gKERlYnVnT3B0aW9ucykgZGVidWdUcmFja2VyLmdldFNlcnZpY2UoKTsKLQkJREVCVUcgPSBnZXRCb29sZWFuRGVidWdPcHRpb24oZGVidWdPcHRpb25zLCAib3JnLmVjbGlwc2UuZXF1aW5veC5kcy9kZWJ1ZyIsIGZhbHNlKSB8fCBnZXRCb29sZWFuKCJlcXVpbm94LmRzLmRlYnVnIiwgZmFsc2UpOyAvLyROT04tTkxTLTEkIC8vJE5PTi1OTFMtMiQKLQkJUEVSRiA9IGdldEJvb2xlYW5EZWJ1Z09wdGlvbihkZWJ1Z09wdGlvbnMsICJvcmcuZWNsaXBzZS5lcXVpbm94LmRzL3BlcmZvcm1hbmNlIiwgZmFsc2UpIHx8IGdldEJvb2xlYW4oImVxdWlub3guZHMucGVyZiIsIGZhbHNlKTsgLy8kTk9OLU5MUy0xJCAvLyROT04tTkxTLTIkCi0JCUlOU1RBTlRJQVRFX0FMTCA9IGdldEJvb2xlYW5EZWJ1Z09wdGlvbihkZWJ1Z09wdGlvbnMsICJvcmcuZWNsaXBzZS5lcXVpbm94LmRzL2luc3RhbnRpYXRlX2FsbCIsIGZhbHNlKSB8fCBnZXRCb29sZWFuKCJlcXVpbm94LmRzLmluc3RhbnRpYXRlX2FsbCIsIGZhbHNlKTsgLy8kTk9OLU5MUy0xJCAvLyROT04tTkxTLTIkCi0KLQkJREJTVE9SRSA9IGdldEJvb2xlYW5EZWJ1Z09wdGlvbihkZWJ1Z09wdGlvbnMsICJvcmcuZWNsaXBzZS5lcXVpbm94LmRzL2NhY2hlX2Rlc2NyaXB0aW9ucyIsIHRydWUpIHx8IGdldEJvb2xlYW4oImVxdWlub3guZHMuZGJzdG9yZSIsIHRydWUpOyAvLyROT04tTkxTLTEkIC8vJE5PTi1OTFMtMiQKLQkJYm9vbGVhbiBwcmludCA9IGdldEJvb2xlYW5EZWJ1Z09wdGlvbihkZWJ1Z09wdGlvbnMsICJvcmcuZWNsaXBzZS5lcXVpbm94LmRzL3ByaW50X29uX2NvbnNvbGUiLCBmYWxzZSkgfHwgZ2V0Qm9vbGVhbigiZXF1aW5veC5kcy5wcmludCIsIGZhbHNlKTsgLy8kTk9OLU5MUy0xJCAvLyROT04tTkxTLTIkCi0JCWxvZy5zZXREZWJ1ZyhERUJVRyk7Ci0JCWxvZy5zZXRQcmludE9uQ29uc29sZShwcmludCk7Ci0JCS8vRGVidWdPcHRpb25zIG5vIGxvbmdlciBuZWVkZWQKLQkJZGVidWdUcmFja2VyLmNsb3NlKCk7Ci0JCVNlcnZpY2VSZWZlcmVuY2UgZndSZWYgPSBiYy5nZXRTZXJ2aWNlUmVmZXJlbmNlKEZyYW1ld29ya0xvZy5jbGFzcy5nZXROYW1lKCkpOwotCQlpZiAoZndSZWYgIT0gbnVsbCkgewotCQkJZndMb2cgPSAoRnJhbWV3b3JrTG9nKSBiYy5nZXRTZXJ2aWNlKGZ3UmVmKTsKLQkJfQotCi0JCWlmIChzdGFydHVwKQotCQkJdGltZUxvZygiW0JFR0lOIC0gc3RhcnQgbWV0aG9kXSBDcmVhdGluZyBMb2cgaW5zdGFuY2UgYW5kIGluaXRpYWxpemluZyBsb2cgc3lzdGVtIHRvb2sgIik7IC8vJE5PTi1OTFMtMSQKLQotCQlzZWN1cml0eSA9IExvZy5zZWN1cml0eSgpOwotCQlib29sZWFuIGhhc0hlYWRlcnMgPSBmYWxzZTsKLQkJQnVuZGxlW10gYWxsQnVuZGxlcyA9IGJ1bmRsZUNvbnRleHQuZ2V0QnVuZGxlcygpOwotCQlmb3IgKGludCBpID0gMDsgaSA8IGFsbEJ1bmRsZXMubGVuZ3RoOyBpKyspIHsKLQkJCURpY3Rpb25hcnkgYWxsSGVhZGVycyA9IGFsbEJ1bmRsZXNbaV0uZ2V0SGVhZGVycygiIik7IC8vJE5PTi1OTFMtMSQKLQkJCWlmIChhbGxIZWFkZXJzLmdldChDb21wb25lbnRDb25zdGFudHMuU0VSVklDRV9DT01QT05FTlQpICE9IG51bGwpIHsKLQkJCQloYXNIZWFkZXJzID0gdHJ1ZTsKLQkJCQlicmVhazsKLQkJCX0KLQkJfQotCi0JCWlmIChoYXNIZWFkZXJzKSB7Ci0JCQlpbml0U0NSKCk7Ci0JCX0gZWxzZSB7Ci0JCQkvLyB0aGVyZSBhcmUgbm8gYnVuZGxlcyBob2xkaW5nIGNvbXBvbmVudHMgLSBTQ1Igd2lsbCBub3QgYmUKLQkJCS8vIGluaXRpYWxpemVkIHlldAotCQkJYnVuZGxlQ29udGV4dC5hZGRCdW5kbGVMaXN0ZW5lcih0aGlzKTsKLQkJfQotCQlTZXJ2aWNlUmVmZXJlbmNlIGVudkluZm9SZWYgPSBiYy5nZXRTZXJ2aWNlUmVmZXJlbmNlKEVudmlyb25tZW50SW5mby5jbGFzcy5nZXROYW1lKCkpOworCXB1YmxpYyB2b2lkIHN0YXJ0KEJ1bmRsZUNvbnRleHQgY29udGV4dCkgdGhyb3dzIEV4Y2VwdGlvbiB7CisJCVNlcnZpY2VSZWZlcmVuY2U8RW52aXJvbm1lbnRJbmZvPiBlbnZJbmZvUmVmID0gY29udGV4dC5nZXRTZXJ2aWNlUmVmZXJlbmNlKEVudmlyb25tZW50SW5mby5jbGFzcyk7CiAJCUVudmlyb25tZW50SW5mbyBlbnZJbmZvID0gbnVsbDsKIAkJaWYgKGVudkluZm9SZWYgIT0gbnVsbCkgewotCQkJZW52SW5mbyA9IChFbnZpcm9ubWVudEluZm8pIGJjLmdldFNlcnZpY2UoZW52SW5mb1JlZik7CisJCQllbnZJbmZvID0gY29udGV4dC5nZXRTZXJ2aWNlKGVudkluZm9SZWYpOwogCQl9CiAJCWlmIChlbnZJbmZvICE9IG51bGwpIHsKIAkJCWVudkluZm8uc2V0UHJvcGVydHkoImVxdWlub3gudXNlLmRzIiwgInRydWUiKTsgLy8kTk9OLU5MUy0xJC8vJE5PTi1OTFMtMiQKLQkJCWJjLnVuZ2V0U2VydmljZShlbnZJbmZvUmVmKTsKKwkJCWNvbnRleHQudW5nZXRTZXJ2aWNlKGVudkluZm9SZWYpOwogCQl9IGVsc2UgewogCQkJU3lzdGVtLnNldFByb3BlcnR5KCJlcXVpbm94LnVzZS5kcyIsICJ0cnVlIik7IC8vJE5PTi1OTFMtMSQgLy8kTk9OLU5MUy0yJAogCQl9CiAKLQkJc2NyU2VydmljZSA9IG5ldyBTY3JTZXJ2aWNlSW1wbCgpOwotCQlzY3JTZXJ2aWNlUmVnID0gYmMucmVnaXN0ZXJTZXJ2aWNlKFNjclNlcnZpY2UuY2xhc3MuZ2V0TmFtZSgpLCBzY3JTZXJ2aWNlLCBudWxsKTsKLQotCQlpZiAoc3RhcnR1cCkgewotCQkJbG9nLmRlYnVnKCJbRU5EIC0gc3RhcnQgbWV0aG9kXSBBY3RpdmF0b3Iuc3RhcnQoKSBtZXRob2QgZXhlY3V0ZWQgZm9yICIgKyBTdHJpbmcudmFsdWVPZih0aW1lWzBdIC0gdGltZVsyXSksIG51bGwpOyAvLyROT04tTkxTLTEkCi0JCQl0aW1lID0gbnVsbDsKKwkJQnVuZGxlV2lyaW5nIHdpcmluZyA9IGNvbnRleHQuZ2V0QnVuZGxlKCkuYWRhcHQoQnVuZGxlV2lyaW5nLmNsYXNzKTsKKwkJTGlzdDxCdW5kbGVXaXJlPiByZXF1aXJlZCA9IHdpcmluZy5nZXRSZXF1aXJlZFdpcmVzKEJ1bmRsZU5hbWVzcGFjZS5CVU5ETEVfTkFNRVNQQUNFKTsKKwkJaWYgKHJlcXVpcmVkLmlzRW1wdHkoKSkgeworCQkJdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigiTm8gb3JnLmFwYWNoZS5mZWxpeC5zY3IgYnVuZGxlIGZvdW5kISIpOyAvLyROT04tTkxTLTEkCiAJCX0KKwkJQnVuZGxlIHNjciA9IHJlcXVpcmVkLmdldCgwKS5nZXRQcm92aWRlcigpLmdldEJ1bmRsZSgpOworCQlpZiAoISJvcmcuYXBhY2hlLmZlbGl4LnNjciIuZXF1YWxzKHNjci5nZXRTeW1ib2xpY05hbWUoKSkpIHsgLy8kTk9OLU5MUy0xJAorCQkJdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigiUmVxdWlyZWQgd3JvbmcgYnVuZGxlOiAiICsgc2NyKTsgLy8kTk9OLU5MUy0xJAorCQl9CisJCUJ1bmRsZVN0YXJ0TGV2ZWwgZXF1aW5veFNEc3RhcnRMZXZlbCA9IGNvbnRleHQuZ2V0QnVuZGxlKCkuYWRhcHQoQnVuZGxlU3RhcnRMZXZlbC5jbGFzcyk7CisJCUJ1bmRsZVN0YXJ0TGV2ZWwgc2NyU3RhcnRMZXZlbCA9IHNjci5hZGFwdChCdW5kbGVTdGFydExldmVsLmNsYXNzKTsKKwkJc2NyU3RhcnRMZXZlbC5zZXRTdGFydExldmVsKGVxdWlub3hTRHN0YXJ0TGV2ZWwuZ2V0U3RhcnRMZXZlbCgpKTsKKwkJc2NyLnN0YXJ0KCk7CiAJfQogCi0JLyoKLQkgKiAobm9uLUphdmFkb2MpCi0JICogCi0JICogQHNlZSBvcmcub3NnaS5mcmFtZXdvcmsuQnVuZGxlQWN0aXZhdG9yI3N0b3Aob3JnLm9zZ2kuZnJhbWV3b3JrLkJ1bmRsZUNvbnRleHQpCi0JICovCi0JcHVibGljIHZvaWQgc3RvcChCdW5kbGVDb250ZXh0IGJ1bmRsZUNvbnRleHQpIHRocm93cyBFeGNlcHRpb24gewotCQlpZiAoc2NyTWFuYWdlciAhPSBudWxsKSB7Ci0JCQlzY3JNYW5hZ2VyLnN0b3BJdCgpOwotCQkJYnVuZGxlQ29udGV4dC5yZW1vdmVTZXJ2aWNlTGlzdGVuZXIoc2NyTWFuYWdlcik7Ci0JCX0KLQkJLy8gZGlzcG9zZSB0aGUgQ00gTGlzdGVuZXIKLQkJaWYgKGNvbmZpZ0xpc3RlbmVyUmVnICE9IG51bGwpIHsKLQkJCWNvbmZpZ0xpc3RlbmVyUmVnLnVucmVnaXN0ZXIoKTsKLQkJfQotCQlpZiAoc2NyU2VydmljZSAhPSBudWxsKSB7Ci0JCQlzY3JTZXJ2aWNlLmRpc3Bvc2UoKTsKLQkJCXNjclNlcnZpY2VSZWcudW5yZWdpc3RlcigpOwotCQl9Ci0KLQkJaWYgKHNjckNvbW1hbmRQcm92aWRlclJlZyAhPSBudWxsKQotCQkJc2NyQ29tbWFuZFByb3ZpZGVyUmVnLnVucmVnaXN0ZXIoKTsKLQotCQlpZiAoc2NyTWFuYWdlciAhPSBudWxsKSB7Ci0JCQlidW5kbGVDb250ZXh0LnJlbW92ZUJ1bmRsZUxpc3RlbmVyKHNjck1hbmFnZXIpOwotCQl9IGVsc2UgewotCQkJYnVuZGxlQ29udGV4dC5yZW1vdmVCdW5kbGVMaXN0ZW5lcih0aGlzKTsKLQkJfQotCQlTZXJ2aWNlUmVmZXJlbmNlIGVudkluZm9SZWYgPSBiYy5nZXRTZXJ2aWNlUmVmZXJlbmNlKEVudmlyb25tZW50SW5mby5jbGFzcy5nZXROYW1lKCkpOwotCQlFbnZpcm9ubWVudEluZm8gZW52SW5mbyA9IG51bGw7Ci0JCWlmIChlbnZJbmZvUmVmICE9IG51bGwpIHsKLQkJCWVudkluZm8gPSAoRW52aXJvbm1lbnRJbmZvKSBiYy5nZXRTZXJ2aWNlKGVudkluZm9SZWYpOwotCQl9Ci0JCWlmIChlbnZJbmZvICE9IG51bGwpIHsKLQkJCWVudkluZm8uc2V0UHJvcGVydHkoImVxdWlub3gudXNlLmRzIiwgImZhbHNlIik7IC8vJE5PTi1OTFMtMSQvLyROT04tTkxTLTIkCi0JCQliYy51bmdldFNlcnZpY2UoZW52SW5mb1JlZik7Ci0JCX0gZWxzZSB7Ci0JCQlTeXN0ZW0uc2V0UHJvcGVydHkoImVxdWlub3gudXNlLmRzIiwgImZhbHNlIik7IC8vJE5PTi1OTFMtMSQgLy8kTk9OLU5MUy0yJAotCQl9Ci0KLQkJbG9nLmNsb3NlKCk7Ci0JCWxvZyA9IG51bGw7CisJcHVibGljIHZvaWQgc3RvcChCdW5kbGVDb250ZXh0IGNvbnRleHQpIHRocm93cyBFeGNlcHRpb24geworCQkvLyBkbyBub3RoaW5nOyBqdXN0IGtlZXAgc2NyIHBlcnNpc3RlbnRseSBzdGFydGVkCiAJfQogCi0JcHVibGljIHN0YXRpYyBGaWx0ZXIgY3JlYXRlRmlsdGVyKFN0cmluZyBmaWx0ZXIpIHRocm93cyBJbnZhbGlkU3ludGF4RXhjZXB0aW9uIHsKLQkJcmV0dXJuIGJjLmNyZWF0ZUZpbHRlcihmaWx0ZXIpOwotCX0KLQotCXB1YmxpYyB2b2lkIGJ1bmRsZUNoYW5nZWQoQnVuZGxlRXZlbnQgZXZlbnQpIHsKLQkJaWYgKGV2ZW50LmdldFR5cGUoKSA9PSBCdW5kbGVFdmVudC5TVEFSVEVEIHx8IGV2ZW50LmdldFR5cGUoKSA9PSBCdW5kbGVFdmVudC5MQVpZX0FDVElWQVRJT04pIHsKLQkJCURpY3Rpb25hcnkgYWxsSGVhZGVycyA9IGV2ZW50LmdldEJ1bmRsZSgpLmdldEhlYWRlcnMoIiIpOyAvLyROT04tTkxTLTEkIAotCQkJaWYgKChhbGxIZWFkZXJzLmdldChDb21wb25lbnRDb25zdGFudHMuU0VSVklDRV9DT01QT05FTlQpKSAhPSBudWxsKSB7Ci0JCQkJLy8gVGhlIGJ1bmRsZSBpcyBob2xkaW5nIGNvbXBvbmVudHMgLSBhY3RpdmF0ZSBzY3IKLQkJCQliYy5yZW1vdmVCdW5kbGVMaXN0ZW5lcih0aGlzKTsKLQkJCQlpbml0U0NSKCk7Ci0JCQl9Ci0JCX0KLQl9Ci0KLQlwdWJsaWMgc3RhdGljIENvbmZpZ3VyYXRpb24gZ2V0Q29uZmlndXJhdGlvbihTdHJpbmcgcGlkKSB0aHJvd3MgSU9FeGNlcHRpb24gewotCQlpZiAoY29uZmlnQWRtaW4gIT0gbnVsbCkgewotCQkJcmV0dXJuIGNvbmZpZ0FkbWluLmdldENvbmZpZ3VyYXRpb24ocGlkKTsKLQkJfQotCQlyZXR1cm4gbnVsbDsKLQl9Ci0KLQlwdWJsaWMgc3RhdGljIENvbmZpZ3VyYXRpb25bXSBsaXN0Q29uZmlndXJhdGlvbnMoU3RyaW5nIGZpbHRlcikgdGhyb3dzIElPRXhjZXB0aW9uLCBJbnZhbGlkU3ludGF4RXhjZXB0aW9uIHsKLQkJaWYgKGNvbmZpZ0FkbWluICE9IG51bGwpIHsKLQkJCXJldHVybiBjb25maWdBZG1pbi5saXN0Q29uZmlndXJhdGlvbnMoZmlsdGVyKTsKLQkJfQotCQlyZXR1cm4gbnVsbDsKLQl9Ci0KLQlwdWJsaWMgc3RhdGljIGJvb2xlYW4gZ2V0Qm9vbGVhbihTdHJpbmcgcHJvcGVydHksIGJvb2xlYW4gZGVmYXVsdFZhbHVlKSB7Ci0JCVN0cmluZyBwcm9wID0gKGJjICE9IG51bGwpID8gYmMuZ2V0UHJvcGVydHkocHJvcGVydHkpIDogU3lzdGVtLmdldFByb3BlcnR5KHByb3BlcnR5KTsKLQkJaWYgKHByb3AgIT0gbnVsbCkgewotCQkJcmV0dXJuIHByb3AuZXF1YWxzSWdub3JlQ2FzZSgidHJ1ZSIpOyAvLyROT04tTkxTLTEkCi0JCX0KLQkJcmV0dXJuIGRlZmF1bHRWYWx1ZTsKLQl9Ci0KLQlwdWJsaWMgc3RhdGljIGJvb2xlYW4gZ2V0Qm9vbGVhbihTdHJpbmcgcHJvcGVydHkpIHsKLQkJcmV0dXJuIGdldEJvb2xlYW4ocHJvcGVydHksIGZhbHNlKTsKLQl9Ci0KLQlwdWJsaWMgc3RhdGljIGludCBnZXRJbnRlZ2VyKFN0cmluZyBwcm9wZXJ0eSwgaW50IGRlZmF1bHRWYWx1ZSkgewotCQlTdHJpbmcgcHJvcCA9IChiYyAhPSBudWxsKSA/IGJjLmdldFByb3BlcnR5KHByb3BlcnR5KSA6IFN5c3RlbS5nZXRQcm9wZXJ0eShwcm9wZXJ0eSk7Ci0JCWlmIChwcm9wICE9IG51bGwpIHsKLQkJCXRyeSB7Ci0JCQkJcmV0dXJuIEludGVnZXIuZGVjb2RlKHByb3ApLmludFZhbHVlKCk7Ci0JCQl9IGNhdGNoIChOdW1iZXJGb3JtYXRFeGNlcHRpb24gZSkgewotCQkJCS8vZG8gbm90aGluZwotCQkJfQotCQl9Ci0JCXJldHVybiBkZWZhdWx0VmFsdWU7Ci0JfQotCi0JcHVibGljIGJvb2xlYW4gZ2V0Qm9vbGVhbkRlYnVnT3B0aW9uKERlYnVnT3B0aW9ucyBvcHRpb25zU2VydmljZSwgU3RyaW5nIG9wdGlvbiwgYm9vbGVhbiBkZWZhdWx0VmFsdWUpIHsKLQkJaWYgKG9wdGlvbnNTZXJ2aWNlICE9IG51bGwpIHsKLQkJCVN0cmluZyB2YWx1ZSA9IG9wdGlvbnNTZXJ2aWNlLmdldE9wdGlvbihvcHRpb24pOwotCQkJaWYgKHZhbHVlICE9IG51bGwpCi0JCQkJcmV0dXJuIHZhbHVlLmVxdWFsc0lnbm9yZUNhc2UoInRydWUiKTsgLy8kTk9OLU5MUy0xJAotCQl9Ci0JCXJldHVybiBkZWZhdWx0VmFsdWU7Ci0JfQotCi0JcHJpdmF0ZSB2b2lkIGluc3RhbGxDb21tYW5kUHJvdmlkZXIoKSB7Ci0JCXRyeSB7Ci0JCQlTQ1JDb21tYW5kUHJvdmlkZXIgc2NyQ29tbWFuZFByb3ZpZGVyID0gbmV3IFNDUkNvbW1hbmRQcm92aWRlcihzY3JNYW5hZ2VyKTsKLQkJCUhhc2h0YWJsZSByZWdfcHJvcHMgPSBuZXcgSGFzaHRhYmxlKDEsIDEpOwotCQkJcmVnX3Byb3BzLnB1dChvcmcub3NnaS5mcmFtZXdvcmsuQ29uc3RhbnRzLlNFUlZJQ0VfUkFOS0lORywgbmV3IEludGVnZXIoSW50ZWdlci5NQVhfVkFMVUUpKTsKLQkJCXNjckNvbW1hbmRQcm92aWRlclJlZyA9IGJjLnJlZ2lzdGVyU2VydmljZShvcmcuZWNsaXBzZS5vc2dpLmZyYW1ld29yay5jb25zb2xlLkNvbW1hbmRQcm92aWRlci5jbGFzcy5nZXROYW1lKCksIHNjckNvbW1hbmRQcm92aWRlciwgcmVnX3Byb3BzKTsKLQkJfSBjYXRjaCAoTm9DbGFzc0RlZkZvdW5kRXJyb3IgZSkgewotCQkJLy90aGUgb3JnLmVjbGlwc2Uub3NnaS5mcmFtZXdvcmsuY29uc29sZSBwYWNrYWdlIGlzIG9wdGlvbmFsIAotCQkJaWYgKEFjdGl2YXRvci5ERUJVRykgewotCQkJCWxvZy5kZWJ1ZygiQ2Fubm90IHJlZ2lzdGVyIFNDUiBDb21tYW5kUHJvdmlkZXIhIiwgZSk7IC8vJE5PTi1OTFMtMSQKLQkJCX0KLQkJfQotCX0KLQotCXB1YmxpYyBzdGF0aWMgdm9pZCBsb2coQnVuZGxlQ29udGV4dCBidW5kbGVDb250ZXh0LCBpbnQgbGV2ZWwsIFN0cmluZyBtZXNzYWdlLCBUaHJvd2FibGUgdCkgewotCQlMb2dTZXJ2aWNlIGxvZ1NlcnZpY2UgPSBudWxsOwotCQlTZXJ2aWNlUmVmZXJlbmNlIGxvZ1JlZiA9IG51bGw7Ci0JCWlmIChidW5kbGVDb250ZXh0ICE9IG51bGwpIHsKLQkJCXRyeSB7Ci0JCQkJbG9nUmVmID0gYnVuZGxlQ29udGV4dC5nZXRTZXJ2aWNlUmVmZXJlbmNlKExvZ1NlcnZpY2UuY2xhc3MuZ2V0TmFtZSgpKTsKLQkJCQlpZiAobG9nUmVmICE9IG51bGwpIHsKLQkJCQkJbG9nU2VydmljZSA9IChMb2dTZXJ2aWNlKSBidW5kbGVDb250ZXh0LmdldFNlcnZpY2UobG9nUmVmKTsKLQkJCQl9Ci0JCQl9IGNhdGNoIChFeGNlcHRpb24gZSkgewotCQkJCWlmIChBY3RpdmF0b3IuREVCVUcpIHsKLQkJCQkJbG9nLmRlYnVnKCJDYW5ub3QgZ2V0IExvZ1NlcnZpY2UgZm9yIGJ1bmRsZSAiICsgYnVuZGxlQ29udGV4dC5nZXRCdW5kbGUoKS5nZXRTeW1ib2xpY05hbWUoKSwgZSk7IC8vJE5PTi1OTFMtMSQKLQkJCQl9Ci0JCQl9Ci0JCX0KLQkJaWYgKGxvZ1NlcnZpY2UgIT0gbnVsbCkgewotCQkJbG9nU2VydmljZS5sb2cobGV2ZWwsIG1lc3NhZ2UsIHQpOwotCQkJYnVuZGxlQ29udGV4dC51bmdldFNlcnZpY2UobG9nUmVmKTsKLQkJCWlmIChsb2cuZ2V0UHJpbnRPbkNvbnNvbGUoKSkgewotCQkJCVN0cmluZyBwcmVmaXggPSAiIjsgLy8kTk9OLU5MUy0xJAotCQkJCXN3aXRjaCAobGV2ZWwpIHsKLQkJCQkJY2FzZSBMb2dTZXJ2aWNlLkxPR19FUlJPUiA6Ci0JCQkJCQlwcmVmaXggPSAiRVJST1IgIjsgLy8kTk9OLU5MUy0xJAotCQkJCQkJYnJlYWs7Ci0JCQkJCWNhc2UgTG9nU2VydmljZS5MT0dfV0FSTklORyA6Ci0JCQkJCQlwcmVmaXggPSAiV0FSTklORyAiOyAvLyROT04tTkxTLTEkCi0JCQkJCQlicmVhazsKLQkJCQkJY2FzZSBMb2dTZXJ2aWNlLkxPR19JTkZPIDoKLQkJCQkJCXByZWZpeCA9ICJJTkZPICI7IC8vJE5PTi1OTFMtMSQKLQkJCQkJCWJyZWFrOwotCQkJCX0KLQkJCQlkdW1wT25Db25zb2xlKHByZWZpeCwgYnVuZGxlQ29udGV4dCwgbWVzc2FnZSwgdCwgbGV2ZWwgPT0gTG9nU2VydmljZS5MT0dfRVJST1IpOwotCQkJfQotCQl9IGVsc2UgewotCQkJbG9nUmVmID0gYmMuZ2V0U2VydmljZVJlZmVyZW5jZShMb2dTZXJ2aWNlLmNsYXNzLmdldE5hbWUoKSk7Ci0JCQlpZiAobG9nUmVmID09IG51bGwpIHsKLQkJCQkvL2xvZyBzZXJ2aWNlIGlzIG5vdCBhdmFpbGFibGUKLQkJCQlpZiAoIWxvZy5nZXRQcmludE9uQ29uc29sZSgpICYmICFsb2cuYXV0b1ByaW50T25Db25zb2xlICYmIGZ3TG9nID09IG51bGwpIHsKLQkJCQkJLy9UaGUgbG9nIHdpbGwgbm90IHByaW50IHRoZSBtZXNzYWdlIG9uIHRoZSBjb25zb2xlIGFuZCB0aGUgRnJhbWV3b3JrTG9nIHNlcnZpY2UgaXMgbm90IGF2YWlsYWJsZQotCQkJCQkvL1dpbGwgcHJpbnQgZXJyb3JzIG9uIHRoZSBjb25zb2xlIGFzIGxhc3QgcmVzb3J0Ci0JCQkJCWlmIChsZXZlbCA9PSBMb2dTZXJ2aWNlLkxPR19FUlJPUikgewotCQkJCQkJZHVtcE9uQ29uc29sZSgiRVJST1IgIiwgYnVuZGxlQ29udGV4dCwgbWVzc2FnZSwgdCwgdHJ1ZSk7IC8vJE5PTi1OTFMtMSQKLQkJCQkJfQotCQkJCX0KLQkJCX0KLQotCQkJLy91c2luZyB0aGUgU0NSIGxvZwotCQkJc3dpdGNoIChsZXZlbCkgewotCQkJCWNhc2UgTG9nU2VydmljZS5MT0dfRVJST1IgOgotCQkJCQlsb2cuZXJyb3IobWVzc2FnZSwgdCk7Ci0JCQkJCWJyZWFrOwotCQkJCWNhc2UgTG9nU2VydmljZS5MT0dfV0FSTklORyA6Ci0JCQkJCWxvZy53YXJuaW5nKG1lc3NhZ2UsIHQpOwotCQkJCQlicmVhazsKLQkJCQljYXNlIExvZ1NlcnZpY2UuTE9HX0lORk8gOgotCQkJCQlsb2cuaW5mbyhtZXNzYWdlKTsKLQkJCQkJYnJlYWs7Ci0JCQkJZGVmYXVsdCA6Ci0JCQkJCWxvZy5kZWJ1ZyhtZXNzYWdlLCB0KTsKLQkJCQkJYnJlYWs7Ci0JCQl9Ci0JCX0KLQkJaWYgKGZ3TG9nICE9IG51bGwpIHsKLQkJCWxvZ1RvRldMb2coYnVuZGxlQ29udGV4dCAhPSBudWxsID8gYnVuZGxlQ29udGV4dC5nZXRCdW5kbGUoKS5nZXRTeW1ib2xpY05hbWUoKSA6IGJjLmdldEJ1bmRsZSgpLmdldFN5bWJvbGljTmFtZSgpLCBsZXZlbCwgbWVzc2FnZSwgdCk7Ci0JCX0KLQl9Ci0KLQlwcml2YXRlIHN0YXRpYyB2b2lkIGR1bXBPbkNvbnNvbGUoU3RyaW5nIHByZWZpeCwgQnVuZGxlQ29udGV4dCBidW5kbGVDb250ZXh0LCBTdHJpbmcgbXNnLCBUaHJvd2FibGUgdCwgYm9vbGVhbiBwcmludEluRXJyKSB7Ci0JCVN0cmluZyBpZCA9IChidW5kbGVDb250ZXh0ID09IG51bGwpID8gIlNDUiAiIDogYnVuZGxlQ29udGV4dC5nZXRCdW5kbGUoKS5nZXRCdW5kbGVJZCgpICsgIiAiOyAvLyROT04tTkxTLTEkLy8kTk9OLU5MUy0yJAotCQlTdHJpbmcgbWVzc2FnZSA9IHByZWZpeCArIGlkICsgbXNnOwotCQlpZiAocHJpbnRJbkVycikgewotCQkJU3lzdGVtLmVyci5wcmludGxuKG1lc3NhZ2UpOwotCQl9IGVsc2UgewotCQkJU3lzdGVtLm91dC5wcmludGxuKG1lc3NhZ2UpOwotCQl9Ci0JCWlmICh0ICE9IG51bGwpIHsKLQkJCXQucHJpbnRTdGFja1RyYWNlKCk7Ci0JCX0KLQl9Ci0KLQlwcml2YXRlIHN0YXRpYyB2b2lkIGxvZ1RvRldMb2coU3RyaW5nIGJzbiwgaW50IGxldmVsLCBTdHJpbmcgbWVzc2FnZSwgVGhyb3dhYmxlIHQpIHsKLQkJaW50IHNldmVyaXR5ID0gRnJhbWV3b3JrTG9nRW50cnkuSU5GTzsKLQkJc3dpdGNoIChsZXZlbCkgewotCQkJY2FzZSBMb2dTZXJ2aWNlLkxPR19FUlJPUiA6Ci0JCQkJc2V2ZXJpdHkgPSBGcmFtZXdvcmtMb2dFbnRyeS5FUlJPUjsKLQkJCQlicmVhazsKLQkJCWNhc2UgTG9nU2VydmljZS5MT0dfV0FSTklORyA6Ci0JCQkJc2V2ZXJpdHkgPSBGcmFtZXdvcmtMb2dFbnRyeS5XQVJOSU5HOwotCQkJCWJyZWFrOwotCQkJY2FzZSBMb2dTZXJ2aWNlLkxPR19JTkZPIDoKLQkJCQlzZXZlcml0eSA9IEZyYW1ld29ya0xvZ0VudHJ5LklORk87Ci0JCQkJYnJlYWs7Ci0JCQljYXNlIExvZ1NlcnZpY2UuTE9HX0RFQlVHIDoKLQkJCQlzZXZlcml0eSA9IEZyYW1ld29ya0xvZ0VudHJ5LklORk87Ci0JCQkJYnJlYWs7Ci0JCX0KLQkJZndMb2cubG9nKG5ldyBGcmFtZXdvcmtMb2dFbnRyeShic24sIHNldmVyaXR5LCAwLCBtZXNzYWdlLCAwLCB0LCBudWxsKSk7Ci0JfQotCi0JcHVibGljIHZvaWQgc2VydmljZUNoYW5nZWQoU2VydmljZUV2ZW50IGV2ZW50KSB7Ci0JCXN3aXRjaCAoZXZlbnQuZ2V0VHlwZSgpKSB7Ci0JCQljYXNlIFNlcnZpY2VFdmVudC5SRUdJU1RFUkVEIDoKLQkJCQlPYmplY3QgY2FTZXJ2aWNlID0gYmMuZ2V0U2VydmljZShldmVudC5nZXRTZXJ2aWNlUmVmZXJlbmNlKCkpOwotCQkJCWNvbmZpZ0FkbWluID0gKENvbmZpZ3VyYXRpb25BZG1pbikgY2FTZXJ2aWNlOwotCQkJCWlmIChjYVNlcnZpY2UgIT0gbnVsbCkgewotCQkJCQkvLyBDb25maWcgQWRtaW4gcmVnaXN0ZXJlZAotCQkJCQlpZiAoc2NyTWFuYWdlciAhPSBudWxsKSB7Ci0JCQkJCQlzY3JNYW5hZ2VyLmNvbmZpZ0FkbWluUmVnaXN0ZXJlZCgoQ29uZmlndXJhdGlvbkFkbWluKSBjYVNlcnZpY2UsIGV2ZW50LmdldFNlcnZpY2VSZWZlcmVuY2UoKSk7Ci0JCQkJCX0KLQkJCQl9Ci0JCQkJYnJlYWs7Ci0JCQljYXNlIFNlcnZpY2VFdmVudC5VTlJFR0lTVEVSSU5HIDoKLQkJCQkvL2dldCByZXBsYWNlbWVudCBjb25maWcgYWRtaW4gc2VydmljZSBpZiBhdmFpbGFibGUKLQkJCQlTZXJ2aWNlUmVmZXJlbmNlIGNhUmVmID0gYmMuZ2V0U2VydmljZVJlZmVyZW5jZShDb25maWd1cmF0aW9uQWRtaW4uY2xhc3MuZ2V0TmFtZSgpKTsKLQkJCQlpZiAoY2FSZWYgIT0gbnVsbCkgewotCQkJCQljb25maWdBZG1pbiA9IChDb25maWd1cmF0aW9uQWRtaW4pIGJjLmdldFNlcnZpY2UoY2FSZWYpOwotCQkJCX0gZWxzZSB7Ci0JCQkJCWNvbmZpZ0FkbWluID0gbnVsbDsKLQkJCQl9Ci0JCQkJYnJlYWs7Ci0JCX0KLQl9CiB9CmRpZmYgLS1naXQgYS9idW5kbGVzL29yZy5lY2xpcHNlLmVxdWlub3guZHMvc3JjL29yZy9lY2xpcHNlL2VxdWlub3gvaW50ZXJuYWwvZHMvQ2lyY3VsYXJpdHlFeGNlcHRpb24uamF2YSBiL2J1bmRsZXMvb3JnLmVjbGlwc2UuZXF1aW5veC5kcy9zcmMvb3JnL2VjbGlwc2UvZXF1aW5veC9pbnRlcm5hbC9kcy9DaXJjdWxhcml0eUV4Y2VwdGlvbi5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwOTRhMmVkLi4wMDAwMDAwCi0tLSBhL2J1bmRsZXMvb3JnLmVjbGlwc2UuZXF1aW5veC5kcy9zcmMvb3JnL2VjbGlwc2UvZXF1aW5veC9pbnRlcm5hbC9kcy9DaXJjdWxhcml0eUV4Y2VwdGlvbi5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMzUgKzAsMCBAQAotLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKLSAqIENvcHlyaWdodCAoYykgMTk5NywgMjAwOCBieSBQcm9TeXN0IFNvZnR3YXJlIEdtYkgKLSAqIGh0dHA6Ly93d3cucHJvc3lzdC5jb20KLSAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMKLSAqIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2UgdjEuMAotICogd2hpY2ggYWNjb21wYW5pZXMgdGhpcyBkaXN0cmlidXRpb24sIGFuZCBpcyBhdmFpbGFibGUgYXQKLSAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLXYxMC5odG1sCi0gKgotICogQ29udHJpYnV0b3JzOgotICogICAgUHJvU3lzdCBTb2Z0d2FyZSBHbWJIIC0gaW5pdGlhbCBBUEkgYW5kIGltcGxlbWVudGF0aW9uCi0gKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLXBhY2thZ2Ugb3JnLmVjbGlwc2UuZXF1aW5veC5pbnRlcm5hbC5kczsKLQotaW1wb3J0IG9yZy5lY2xpcHNlLmVxdWlub3guaW50ZXJuYWwuZHMubW9kZWwuU2VydmljZUNvbXBvbmVudFByb3A7Ci0KLS8qKgotICogVXNlZCB0byBmaW5kIGNpcmN1bGFyIGRlcGVuZGVuY2llcwotICoKLSAqIEBhdXRob3IgUGF2bGluIERvYnJldgotICogQHZlcnNpb24gMS4wCi0gKi8KLQotcHVibGljIGNsYXNzIENpcmN1bGFyaXR5RXhjZXB0aW9uIGV4dGVuZHMgRXhjZXB0aW9uIHsKLQlwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHNlcmlhbFZlcnNpb25VSUQgPSAxTDsKLQlwcml2YXRlIFNlcnZpY2VDb21wb25lbnRQcm9wIGNhdXNpbmdDb21wb25lbnQ7Ci0KLQlwdWJsaWMgQ2lyY3VsYXJpdHlFeGNlcHRpb24oU2VydmljZUNvbXBvbmVudFByb3Agc2NwKSB7Ci0JCXRoaXMuY2F1c2luZ0NvbXBvbmVudCA9IHNjcDsKLQl9Ci0KLQlwdWJsaWMgU2VydmljZUNvbXBvbmVudFByb3AgZ2V0Q2F1c2luZ0NvbXBvbmVudCgpIHsKLQkJcmV0dXJuIGNhdXNpbmdDb21wb25lbnQ7Ci0JfQotCi19CmRpZmYgLS1naXQgYS9idW5kbGVzL29yZy5lY2xpcHNlLmVxdWlub3guZHMvc3JjL29yZy9lY2xpcHNlL2VxdWlub3gvaW50ZXJuYWwvZHMvQ29tcG9uZW50U3RvcmFnZS5qYXZhIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5lcXVpbm94LmRzL3NyYy9vcmcvZWNsaXBzZS9lcXVpbm94L2ludGVybmFsL2RzL0NvbXBvbmVudFN0b3JhZ2UuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDljZTI5Ny4uMDAwMDAwMAotLS0gYS9idW5kbGVzL29yZy5lY2xpcHNlLmVxdWlub3guZHMvc3JjL29yZy9lY2xpcHNlL2VxdWlub3gvaW50ZXJuYWwvZHMvQ29tcG9uZW50U3RvcmFnZS5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTI2ICswLDAgQEAKLS8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTctMjAxMyBieSBQcm9TeXN0IFNvZnR3YXJlIEdtYkggYW5kIG90aGVycy4KLSAqIGh0dHA6Ly93d3cucHJvc3lzdC5jb20KLSAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMKLSAqIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2UgdjEuMAotICogd2hpY2ggYWNjb21wYW5pZXMgdGhpcyBkaXN0cmlidXRpb24sIGFuZCBpcyBhdmFpbGFibGUgYXQKLSAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLXYxMC5odG1sCi0gKgotICogQ29udHJpYnV0b3JzOgotICogICAgUHJvU3lzdCBTb2Z0d2FyZSBHbWJIIC0gaW5pdGlhbCBBUEkgYW5kIGltcGxlbWVudGF0aW9uCi0gKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLXBhY2thZ2Ugb3JnLmVjbGlwc2UuZXF1aW5veC5pbnRlcm5hbC5kczsKLQotaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247Ci1pbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKLWltcG9ydCBqYXZhLm5ldC5VUkw7Ci1pbXBvcnQgamF2YS51dGlsLio7Ci1pbXBvcnQgb3JnLmVjbGlwc2UuZXF1aW5veC5pbnRlcm5hbC5kcy5tb2RlbC5EZWNsYXJhdGlvblBhcnNlcjsKLWltcG9ydCBvcmcuZWNsaXBzZS5vc2dpLnV0aWwuTWFuaWZlc3RFbGVtZW50OwotaW1wb3J0IG9yZy5lY2xpcHNlLm9zZ2kudXRpbC5OTFM7Ci1pbXBvcnQgb3JnLm9zZ2kuZnJhbWV3b3JrLkJ1bmRsZTsKLWltcG9ydCBvcmcub3NnaS5zZXJ2aWNlLmNvbXBvbmVudC5Db21wb25lbnRDb25zdGFudHM7Ci1pbXBvcnQgb3JnLm9zZ2kuc2VydmljZS5sb2cuTG9nU2VydmljZTsKLQotLyoqCi0gKiBAYXV0aG9yIFN0b3lhbiBCb3NoZXYKLSAqIEBhdXRob3IgUGF2bGluIERvYnJldgotICovCi0KLXB1YmxpYyBhYnN0cmFjdCBjbGFzcyBDb21wb25lbnRTdG9yYWdlIHsKLQotCXByaXZhdGUgZmluYWwgRGVjbGFyYXRpb25QYXJzZXIgcGFyc2VyID0gbmV3IERlY2xhcmF0aW9uUGFyc2VyKCk7Ci0KLQkvKioKLQkgKiBUaGlzIG1ldGhvZCB3aWxsIGxvYWQgdGhlIGNvbXBvbmVudCBkZWZpbml0aW9ucyBmcm9tIGEgYnVuZGxlLiBUaGUKLQkgKiByZXR1cm5lZCB2YWx1ZSBzaG91bGQgY29udGFpbiB2ZWN0b3Igd2l0aCAnU2VydmljZUNvbXBvbmVudCcgZWxlbWVudHMuCi0JICogCi0JICogQHBhcmFtIGJ1bmRsZSAgYnVuZGxlLCBjb250YWluaW5nIERTIGNvbXBvbmVudHMKLQkgKiBAcGFyYW0gZHNIZWFkZXIgIHRoZSBEUyBoZWFkZXIgdmFsdWUgd2hpY2ggaXMgaW4gdGhlIGJ1bmRsZSdzIG1hbmlmZXN0Ci0JICogQHJldHVybiA8Y29kZT5udWxsPC9jb2RlPiBpZiB0aGVyZSBhcmUgbm8gY29tcG9uZW50IGRlZmluaXRpb25zLgotCSAqLwotCXB1YmxpYyBhYnN0cmFjdCBWZWN0b3IgbG9hZENvbXBvbmVudERlZmluaXRpb25zKEJ1bmRsZSBidW5kbGUsIFN0cmluZyBkc0hlYWRlcik7Ci0KLQkvKioKLQkgKiBUaGlzIG1ldGhvZCBpcyBjYWxsZWQgd2hlbiBhIGJ1bmRsZSBoYXMgYmVlbiB1bmluc3RhbGxlZCBhbmQgdGhlcmVmb3JlIGl0cyBjYWNoZWQgY29tcG9uZW50cyBtdXN0IGJlIHJlbW92ZWQKLQkgKiBAcGFyYW0gYnVuZGxlSUQgdGhlIGlkIG9mIHRoZSB1bmluc3RhbGxlZCBidW5kbGUgCi0JICovCi0JcHVibGljIGFic3RyYWN0IHZvaWQgZGVsZXRlQ29tcG9uZW50RGVmaW5pdGlvbnMobG9uZyBidW5kbGVJRCk7Ci0KLQkvKioKLQkgKiBDYWxsZWQgd2hlbiB0aGUgRFMgYnVuZGxlIGlzIGFib3V0IHRvIHN0b3AuIFRoaXMgbWV0aG9kIG11c3Qgc3RvcmUgYW55IHVuc2F2ZWQgZGF0YQotCSAqLwotCXB1YmxpYyBhYnN0cmFjdCB2b2lkIHN0b3AoKTsKLQotCXByb3RlY3RlZCBWZWN0b3IgcGFyc2VYTUxEZWNsYXJhdGlvbihCdW5kbGUgYnVuZGxlLCBTdHJpbmcgZHNIZWFkZXIpIHRocm93cyBFeGNlcHRpb24gewotCQlWZWN0b3IgY29tcG9uZW50cyA9IG5ldyBWZWN0b3IoKTsKLQkJaWYgKGRzSGVhZGVyID09IG51bGwpCi0JCQlyZXR1cm4gY29tcG9uZW50czsKLQkJTWFuaWZlc3RFbGVtZW50W10gZWxlbWVudHMgPSBNYW5pZmVzdEVsZW1lbnQucGFyc2VIZWFkZXIoQ29tcG9uZW50Q29uc3RhbnRzLlNFUlZJQ0VfQ09NUE9ORU5ULCBkc0hlYWRlcik7Ci0JCUNvbGxlY3Rpb24vKjxVUkw+Ki91cmxDb2xsZWN0aW9uID0gY29tcHV0ZUNvbXBvbmVudERlZmluaXRpb25VcmxzKGJ1bmRsZSwgZWxlbWVudHMpOwotCQkvLyB0aGUgcGFyc2VyIGlzIG5vdCB0aHJlYWQgc2FmZSEhIQotCQlzeW5jaHJvbml6ZWQgKHBhcnNlcikgewotCQkJLy8gaWxsZWdhbCBjb21wb25lbnRzIGFyZSBpZ25vcmVkLCBidXQgZnJhbWV3b3JrIGV2ZW50IGlzIHBvc3RlZCBmb3IKLQkJCS8vIHRoZW07IGhvd2V2ZXIsIGl0IHdpbGwgY29udGludWUgYW5kIHRyeSB0byBsb2FkIGFueSBsZWdhbAotCQkJLy8gZGVmaW5pdGlvbnMKLQkJCVVSTCB1cmw7Ci0JCQlmb3IgKEl0ZXJhdG9yLyo8VVJMPiovdXJscyA9IHVybENvbGxlY3Rpb24uaXRlcmF0b3IoKTsgdXJscy5oYXNOZXh0KCk7KSB7Ci0JCQkJdXJsID0gKFVSTCkgdXJscy5uZXh0KCk7Ci0JCQkJaWYgKEFjdGl2YXRvci5ERUJVRykgewotCQkJCQlBY3RpdmF0b3IubG9nLmRlYnVnKCJDb21wb25lbnRTdG9yYWdlLnBhcnNlWE1MRGVjbGFyYXRpb24oKTogbG9hZGluZyAiICsgdXJsLnRvU3RyaW5nKCksIG51bGwpOyAvLyROT04tTkxTLTEkCi0JCQkJfQotCQkJCUlucHV0U3RyZWFtIGlzID0gbnVsbDsKLQkJCQl0cnkgewotCQkJCQlpcyA9IHVybC5vcGVuU3RyZWFtKCk7Ci0JCQkJCWlmIChpcyA9PSBudWxsKSB7Ci0JCQkJCQlBY3RpdmF0b3IubG9nKGJ1bmRsZS5nZXRCdW5kbGVDb250ZXh0KCksIExvZ1NlcnZpY2UuTE9HX0VSUk9SLCBOTFMuYmluZChNZXNzYWdlcy5DQU5UX09QRU5fU1RSRUFNX1RPX0NPTVBPTkVOVF9YTUwsIHVybCksIG51bGwpOwotCQkJCQl9IGVsc2UgewotCQkJCQkJaW50IGNvbXBTaXplID0gY29tcG9uZW50cy5zaXplKCk7Ci0JCQkJCQlwYXJzZXIucGFyc2UoaXMsIGJ1bmRsZSwgY29tcG9uZW50cywgdXJsLnRvU3RyaW5nKCkpOwotCQkJCQkJaWYgKGNvbXBTaXplID09IGNvbXBvbmVudHMuc2l6ZSgpKSB7Ci0JCQkJCQkJQWN0aXZhdG9yLmxvZyhidW5kbGUuZ2V0QnVuZGxlQ29udGV4dCgpLCBMb2dTZXJ2aWNlLkxPR19XQVJOSU5HLCBOTFMuYmluZChNZXNzYWdlcy5OT19DT01QT05FTlRTX0ZPVU5ELCB1cmwpLCBudWxsKTsKLQkJCQkJCX0KLQkJCQkJfQotCQkJCX0gY2F0Y2ggKElPRXhjZXB0aW9uIGllKSB7Ci0JCQkJCUFjdGl2YXRvci5sb2coYnVuZGxlLmdldEJ1bmRsZUNvbnRleHQoKSwgTG9nU2VydmljZS5MT0dfRVJST1IsIE5MUy5iaW5kKE1lc3NhZ2VzLkVSUk9SX09QRU5JTkdfQ09NUF9YTUwsIHVybCksIGllKTsKLQkJCQl9IGNhdGNoIChUaHJvd2FibGUgdCkgewotCQkJCQlBY3RpdmF0b3IubG9nKGJ1bmRsZS5nZXRCdW5kbGVDb250ZXh0KCksIExvZ1NlcnZpY2UuTE9HX0VSUk9SLCBOTFMuYmluZChNZXNzYWdlcy5JTExFR0FMX0RFRklOSVRJT05fRklMRSwgdXJsKSwgdCk7Ci0JCQkJfSBmaW5hbGx5IHsKLQkJCQkJaWYgKGlzICE9IG51bGwpIHsKLQkJCQkJCWlzLmNsb3NlKCk7Ci0JCQkJCX0KLQkJCQl9Ci0JCQl9IC8vIGVuZCB3aGlsZQotCi0JCQljb21wb25lbnRzID0gcGFyc2VyLmNvbXBvbmVudHM7Ci0JCQkvLyBtYWtlIHN1cmUgdGhlIGNsZWFuLXVwIHRoZSBwYXJzZXIgY2FjaGUsIGZvciB0aGUgbmV4dCBidW5kbGUgdG8KLQkJCS8vIHdvcmsgcHJvcGVybHkhISEKLQkJCXBhcnNlci5jb21wb25lbnRzID0gbnVsbDsKLQkJfQotCQlyZXR1cm4gY29tcG9uZW50czsKLQl9Ci0KLQlwcm90ZWN0ZWQgQ29sbGVjdGlvbi8qPFVSTD4qL2NvbXB1dGVDb21wb25lbnREZWZpbml0aW9uVXJscyhCdW5kbGUgYnVuZGxlLCBNYW5pZmVzdEVsZW1lbnRbXSBlbGVtZW50cykgewotCQlDb2xsZWN0aW9uLyo8VVJMPiovcmVzdWx0ID0gbmV3IEFycmF5TGlzdC8qPFVSTD4qLyg1KTsKLQkJLy8gcHJvY2VzcyBhbGwgZGVmaW5pdGlvbiBmaWxlCi0JCWZvciAoaW50IGkgPSAwOyBpIDwgZWxlbWVudHMubGVuZ3RoOyBpKyspIHsKLQkJCVN0cmluZ1tdIGRlZmluaXRpb25GaWxlcyA9IGVsZW1lbnRzW2ldLmdldFZhbHVlQ29tcG9uZW50cygpOwotCQkJZm9yIChpbnQgaiA9IDA7IGogPCBkZWZpbml0aW9uRmlsZXMubGVuZ3RoOyBqKyspIHsKLQkJCQlTdHJpbmcgZGVmaW5pdGlvbkZpbGUgPSBkZWZpbml0aW9uRmlsZXNbal07Ci0JCQkJaW50IGluZCA9IGRlZmluaXRpb25GaWxlLmxhc3RJbmRleE9mKCcvJyk7Ci0JCQkJU3RyaW5nIHBhdGggPSBpbmQgIT0gLTEgPyBkZWZpbml0aW9uRmlsZS5zdWJzdHJpbmcoMCwgaW5kKSA6ICIvIjsgLy8kTk9OLU5MUy0xJAotCi0JCQkJRW51bWVyYXRpb24vKjxVUkw+Ki91cmxzID0gYnVuZGxlLmZpbmRFbnRyaWVzKHBhdGgsIGluZCAhPSAtMSA/IGRlZmluaXRpb25GaWxlLnN1YnN0cmluZyhpbmQgKyAxKSA6IGRlZmluaXRpb25GaWxlLCBmYWxzZSk7Ci0JCQkJaWYgKHVybHMgPT0gbnVsbCB8fCAhdXJscy5oYXNNb3JlRWxlbWVudHMoKSkgewotCQkJCQlBY3RpdmF0b3IubG9nKGJ1bmRsZS5nZXRCdW5kbGVDb250ZXh0KCksIExvZ1NlcnZpY2UuTE9HX0VSUk9SLCBOTFMuYmluZChNZXNzYWdlcy5DT01QT05FTlRfWE1MX05PVF9GT1VORCwgYnVuZGxlLmdldFN5bWJvbGljTmFtZSgpLCBkZWZpbml0aW9uRmlsZSksIG51bGwpOwotCQkJCQljb250aW51ZTsKLQkJCQl9Ci0KLQkJCQl3aGlsZSAodXJscy5oYXNNb3JlRWxlbWVudHMoKSkKLQkJCQkJcmVzdWx0LmFkZCh1cmxzLm5leHRFbGVtZW50KCkpOwotCQkJfQotCQl9Ci0JCXJldHVybiByZXN1bHQ7Ci0JfQotCi19CmRpZmYgLS1naXQgYS9idW5kbGVzL29yZy5lY2xpcHNlLmVxdWlub3guZHMvc3JjL29yZy9lY2xpcHNlL2VxdWlub3gvaW50ZXJuYWwvZHMvRmFjdG9yeVJlZy5qYXZhIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5lcXVpbm94LmRzL3NyYy9vcmcvZWNsaXBzZS9lcXVpbm94L2ludGVybmFsL2RzL0ZhY3RvcnlSZWcuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggOTY5MTJiMi4uMDAwMDAwMAotLS0gYS9idW5kbGVzL29yZy5lY2xpcHNlLmVxdWlub3guZHMvc3JjL29yZy9lY2xpcHNlL2VxdWlub3gvaW50ZXJuYWwvZHMvRmFjdG9yeVJlZy5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsNjcgKzAsMCBAQAotLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKLSAqIENvcHlyaWdodCAoYykgMTk5Ny0yMDA5IGJ5IFByb1N5c3QgU29mdHdhcmUgR21iSAotICogaHR0cDovL3d3dy5wcm9zeXN0LmNvbQotICogQWxsIHJpZ2h0cyByZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscwotICogYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2MS4wCi0gKiB3aGljaCBhY2NvbXBhbmllcyB0aGlzIGRpc3RyaWJ1dGlvbiwgYW5kIGlzIGF2YWlsYWJsZSBhdAotICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtdjEwLmh0bWwKLSAqCi0gKiBDb250cmlidXRvcnM6Ci0gKiAgICBQcm9TeXN0IFNvZnR3YXJlIEdtYkggLSBpbml0aWFsIEFQSSBhbmQgaW1wbGVtZW50YXRpb24KLSAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwotcGFja2FnZSBvcmcuZWNsaXBzZS5lcXVpbm94LmludGVybmFsLmRzOwotCi1pbXBvcnQgb3JnLmVjbGlwc2UuZXF1aW5veC5pbnRlcm5hbC5kcy5tb2RlbC5TZXJ2aWNlQ29tcG9uZW50UHJvcDsKLWltcG9ydCBvcmcuZWNsaXBzZS5vc2dpLnV0aWwuTkxTOwotaW1wb3J0IG9yZy5vc2dpLmZyYW1ld29yay4qOwotaW1wb3J0IG9yZy5vc2dpLnNlcnZpY2UuY29tcG9uZW50Lio7Ci1pbXBvcnQgb3JnLm9zZ2kuc2VydmljZS5sb2cuTG9nU2VydmljZTsKLQotLyoqCi0gKiBAYXV0aG9yIFBhdmxpbiBEb2JyZXYKLSAqIEB2ZXJzaW9uIDEuMAotICovCi0KLWZpbmFsIGNsYXNzIEZhY3RvcnlSZWcgaW1wbGVtZW50cyBTZXJ2aWNlRmFjdG9yeSB7Ci0KLQkvKiB0aGUgaW5zdGFuY2UgY3JlYXRlZCAqLwotCXByaXZhdGUgZmluYWwgU2VydmljZUNvbXBvbmVudFByb3AgY29tcG9uZW50OwotCi0JRmFjdG9yeVJlZyhTZXJ2aWNlQ29tcG9uZW50UHJvcCBjb21wb25lbnQpIHsKLQkJdGhpcy5jb21wb25lbnQgPSBjb21wb25lbnQ7Ci0JfQotCi0JLy8gU2VydmljZUZhY3RvcnkuZ2V0U2VydmljZSBtZXRob2QuCi0JcHVibGljIE9iamVjdCBnZXRTZXJ2aWNlKEJ1bmRsZSBidW5kbGUsIFNlcnZpY2VSZWdpc3RyYXRpb24gcmVnaXN0cmF0aW9uKSB7Ci0KLQkJdHJ5IHsKLQkJCWlmIChBY3RpdmF0b3IuREVCVUcpIHsKLQkJCQlBY3RpdmF0b3IubG9nLmRlYnVnKCJGYWN0b3J5UmVnLmdldFNlcnZpY2UoKTogY3JlYXRlZCBuZXcgc2VydmljZSBmb3IgY29tcG9uZW50ICIgKyBjb21wb25lbnQubmFtZSwgbnVsbCk7IC8vJE5PTi1OTFMtMSQKLQkJCX0KLQkJCUNvbXBvbmVudEluc3RhbmNlIGNpID0gSW5zdGFuY2VQcm9jZXNzLnN0YXRpY1JlZi5idWlsZENvbXBvbmVudChidW5kbGUsIGNvbXBvbmVudCwgbnVsbCwgZmFsc2UpOwotCQkJLy8gY2kgY2FuIGJlIG51bGwgaWYgdGhlIGNvbXBvbmVudCBpcyBhbHJlYWR5IGRpc3Bvc2VkIHdoaWxlIGJlaW5nIGJ1aWx0Ci0JCQlpZiAoY2kgIT0gbnVsbCkgewotCQkJCXJldHVybiBjaS5nZXRJbnN0YW5jZSgpOwotCQkJfQotCQl9IGNhdGNoIChUaHJvd2FibGUgdCkgewotCQkJaWYgKCEodCBpbnN0YW5jZW9mIENvbXBvbmVudEV4Y2VwdGlvbikpIHsKLQkJCQlBY3RpdmF0b3IubG9nKGNvbXBvbmVudC5iYywgTG9nU2VydmljZS5MT0dfRVJST1IsIE5MUy5iaW5kKE1lc3NhZ2VzLkNBTlRfR0VUX1NFUlZJQ0UsIGNvbXBvbmVudC5uYW1lKSwgdCk7Ci0JCQl9IGVsc2UgewotCQkJCXRocm93IChDb21wb25lbnRFeGNlcHRpb24pIHQ7Ci0JCQl9Ci0JCX0KLQkJcmV0dXJuIG51bGw7Ci0JfQotCi0JLy8gU2VydmljZUZhY3RvcnkudW5nZXRTZXJ2aWNlIG1ldGhvZC4KLQlwdWJsaWMgdm9pZCB1bmdldFNlcnZpY2UoQnVuZGxlIGJ1bmRsZSwgU2VydmljZVJlZ2lzdHJhdGlvbiByZWdpc3RyYXRpb24sIE9iamVjdCBzZXJ2aWNlKSB7Ci0JCWlmIChBY3RpdmF0b3IuREVCVUcpIHsKLQkJCUFjdGl2YXRvci5sb2cuZGVidWcoIkZhY3RvcnlSZWcudW5nZXRTZXJ2aWNlKCk6IHJlZ2lzdHJhdGlvbiA9ICIgKyByZWdpc3RyYXRpb24udG9TdHJpbmcoKSwgbnVsbCk7IC8vJE5PTi1OTFMtMSQKLQkJfQotCQljb21wb25lbnQuZGlzcG9zZU9iaihzZXJ2aWNlLCBDb21wb25lbnRDb25zdGFudHMuREVBQ1RJVkFUSU9OX1JFQVNPTl9VTlNQRUNJRklFRCk7Ci0JfQotCi0JcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKLQkJcmV0dXJuIGNvbXBvbmVudC5uYW1lICsgIiBGYWN0b3J5UmVnaXN0cmF0aW9uIjsgLy8kTk9OLU5MUy0xJAotCX0KLX0KZGlmZiAtLWdpdCBhL2J1bmRsZXMvb3JnLmVjbGlwc2UuZXF1aW5veC5kcy9zcmMvb3JnL2VjbGlwc2UvZXF1aW5veC9pbnRlcm5hbC9kcy9JbnN0YW5jZVByb2Nlc3MuamF2YSBiL2J1bmRsZXMvb3JnLmVjbGlwc2UuZXF1aW5veC5kcy9zcmMvb3JnL2VjbGlwc2UvZXF1aW5veC9pbnRlcm5hbC9kcy9JbnN0YW5jZVByb2Nlc3MuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggYjgyMmNjOC4uMDAwMDAwMAotLS0gYS9idW5kbGVzL29yZy5lY2xpcHNlLmVxdWlub3guZHMvc3JjL29yZy9lY2xpcHNlL2VxdWlub3gvaW50ZXJuYWwvZHMvSW5zdGFuY2VQcm9jZXNzLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw4MzggKzAsMCBAQAotLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKLSAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxMCBieSBQcm9TeXN0IFNvZnR3YXJlIEdtYkgKLSAqIGh0dHA6Ly93d3cucHJvc3lzdC5jb20KLSAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMKLSAqIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2UgdjEuMAotICogd2hpY2ggYWNjb21wYW5pZXMgdGhpcyBkaXN0cmlidXRpb24sIGFuZCBpcyBhdmFpbGFibGUgYXQKLSAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLXYxMC5odG1sCi0gKgotICogQ29udHJpYnV0b3JzOgotICogICAgUHJvU3lzdCBTb2Z0d2FyZSBHbWJIIC0gaW5pdGlhbCBBUEkgYW5kIGltcGxlbWVudGF0aW9uCi0gKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLXBhY2thZ2Ugb3JnLmVjbGlwc2UuZXF1aW5veC5pbnRlcm5hbC5kczsKLQotaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0Lkludm9jYXRpb25UYXJnZXRFeGNlcHRpb247Ci1pbXBvcnQgamF2YS51dGlsLio7Ci1pbXBvcnQgb3JnLmFwYWNoZS5mZWxpeC5zY3IuQ29tcG9uZW50OwotaW1wb3J0IG9yZy5lY2xpcHNlLmVxdWlub3guaW50ZXJuYWwuZHMuaW1wbC5Db21wb25lbnRGYWN0b3J5SW1wbDsKLWltcG9ydCBvcmcuZWNsaXBzZS5lcXVpbm94LmludGVybmFsLmRzLmltcGwuQ29tcG9uZW50SW5zdGFuY2VJbXBsOwotaW1wb3J0IG9yZy5lY2xpcHNlLmVxdWlub3guaW50ZXJuYWwuZHMubW9kZWwuKjsKLWltcG9ydCBvcmcuZWNsaXBzZS5vc2dpLnV0aWwuTkxTOwotaW1wb3J0IG9yZy5vc2dpLmZyYW1ld29yay4qOwotaW1wb3J0IG9yZy5vc2dpLnNlcnZpY2UuY20uQ29uZmlndXJhdGlvbjsKLWltcG9ydCBvcmcub3NnaS5zZXJ2aWNlLmNvbXBvbmVudC4qOwotaW1wb3J0IG9yZy5vc2dpLnNlcnZpY2UubG9nLkxvZ1NlcnZpY2U7Ci0KLS8qKgotICogVGhpcyBjbGFzcyBpcyByZXNwb25zaWJsZSBmb3IgY3JlYXRpbmcsIHRyYWNraW5nIGFuZCBkaXNwb3Npbmcgb2Ygc2VydmljZQotICogaW5zdGFuY2VzIGFuZCByZWdpc3RyYXRpb25zLgotICogCi0gKiBAYXV0aG9yIFZhbGVudGluIFZhbGNoZXYKLSAqIEBhdXRob3IgU3RveWFuIEJvc2hldgotICogQGF1dGhvciBQYXZsaW4gRG9icmV2Ci0gKi8KLQotcHVibGljIGNsYXNzIEluc3RhbmNlUHJvY2VzcyB7Ci0KLQlwdWJsaWMgc3RhdGljIFJlc29sdmVyIHJlc29sdmVyOwotCXB1YmxpYyBzdGF0aWMgSW5zdGFuY2VQcm9jZXNzIHN0YXRpY1JlZjsKLQotCS8qKiBtYXAgU0NQOlNlcnZpY2VSZWdpc3RyYXRpb24gKi8KLQlwcm90ZWN0ZWQgSGFzaHRhYmxlIGZhY3RvcnlSZWdpc3RyYXRpb25zOwotCi0JLyoqCi0JICogVXNlZCB3aXRoIHN0YWNrQ291bnQgdG8gaGFuZGxlIGNpcmN1bGFyIGRlcGVuZGVuY2llcyBpbiB0aGUKLQkgKiB7QGxpbmsgSW5zdGFuY2VQcm9jZXNzI2J1aWxkQ29tcG9uZW50KEJ1bmRsZSwgU2VydmljZUNvbXBvbmVudFByb3AsIE9iamVjdCl9Ci0JICogbWV0aG9kLgotCSAqLwotCXByaXZhdGUgVmVjdG9yIGRlbGF5ZWRCaW5kTGlzdDsKLQotCS8va2V5IC0gdGhlIFNQQyBiZWluZyBidWlsdDsgICB2YWx1ZSAtIHRoZSB0aHJlYWQgdGhhdCBidWlsZHMgdGhlIFNDUAotCXN0YXRpYyBIYXNodGFibGUgYnVpbGRpbmdUaHJlYWRzID0gbmV3IEhhc2h0YWJsZSg3KTsKLQkvL2tleSAtIHRoZSBidWlsZGluZyB0aHJlYWQ7ICAgdmFsdWUgLSBDb3VudGVyIC0gaG9sZHMgdGhlIGNvdW50IG9mIGVudHJpZXMgaW4gYnVpbGRDb21wb25lbnQgbWV0aG9kICAKLQlzdGF0aWMgSGFzaHRhYmxlIHN0YWNrQ291bnRzID0gbmV3IEhhc2h0YWJsZSg3KTsKLQkvL3NwZWNpZmllcyB0aGUgbWF4aW11bSB0aW1lIHRoYXQgYSB0aHJlYWQgbXVzdCB3YWl0IGZvciB0aGUgYnVpbGRpbmcgdGhyZWFkIHRvIGNvbXBsZXRlIHRoZSBidWlsZGluZyBvZiB0aGUgU0NQCi0Jc3RhdGljIGludCB3YWl0VGltZSA9IEFjdGl2YXRvci5nZXRJbnRlZ2VyKCJlcXVpbm94LnNjci53YWl0VGltZU9uQmxvY2siLCAxMDAwMCk7IC8vJE5PTi1OTFMtMSQKLQotCS8vYSBmbGFnIHVzZWQgZm9yIHN5bmNocm9uaXphdGlvbiBvZiBidWlsZC9kaXNwb3NlIG9wZXJhdGlvbnMKLQlib29sZWFuIGJ1c3lCdWlsZGluZyA9IGZhbHNlOwotCS8vdGhlIHdvcmtpbmcgdGhyZWFkIHRoYXQgcGVyZm9ybXMgdGhlIGN1cnJlbnQgYnVpbGQvZGlzcG9zZSBvcGVyYXRpb24KLQlUaHJlYWQgd29ya2luZ1RocmVhZDsKLQkvL2FuIG9iamVjdCB1c2VkIGZvciBzeW5jaHJvbml6YXRpb24gd2hlbiBjaGFuZ2luZyB0aGUgc3RhdHVzIG9mIGJ1c3lCdWlsZGluZyBmbGFnCi0JT2JqZWN0IGxvY2sgPSBuZXcgT2JqZWN0KCk7Ci0JLy91c2VkIHRvIGNvdW50IHRoZSBudW1iZXIgb2YgdGltZXMgYSBsb2NrIGlzIGhlbGQgd2hlbiByZXF1aXJlZCByZWN1cnNpdmVseSAKLQlpbnQgbG9ja0NvdW50ZXIgPSAwOwotCi0JLyoqCi0JICogSGFuZGxlIEluc3RhbmNlIHByb2Nlc3NpbmcgYnVpbGRpbmcgYW5kIGRpc3Bvc2luZy4KLQkgKiAKLQkgKiBAcGFyYW0gcmVzb2x2ZXIKLQkgKiAgICAgICAgICAgIHRoZSByZXNvbHZlciBpbnN0YW5jZQotCSAqLwotCUluc3RhbmNlUHJvY2VzcyhSZXNvbHZlciByZXNvbHZlcikgewotCQlJbnN0YW5jZVByb2Nlc3MucmVzb2x2ZXIgPSByZXNvbHZlcjsKLQkJZmFjdG9yeVJlZ2lzdHJhdGlvbnMgPSBuZXcgSGFzaHRhYmxlKDE5KTsKLQkJZGVsYXllZEJpbmRMaXN0ID0gbmV3IFZlY3RvcigxMCk7Ci0JCXN0YXRpY1JlZiA9IHRoaXM7Ci0JfQotCi0JLyoqCi0JICogZGlzcG9zZSBjbGVhbnVwIHRoZSBTQ1IgaXMgc2h1dHRpbmcgZG93bgotCSAqLwotCXZvaWQgZGlzcG9zZSgpIHsKLQkJZmFjdG9yeVJlZ2lzdHJhdGlvbnMgPSBudWxsOwotCX0KLQotCS8vIGdldHMgdGhlIHN5bmNoIGxvY2sgdG8gcGVyZm9ybSBzb21lIGJ1aWxkL3JlbGVhc2Ugd29yawotCXZvaWQgZ2V0TG9jaygpIHsKLQkJc3luY2hyb25pemVkIChsb2NrKSB7Ci0JCQlUaHJlYWQgY3VycmVudFRocmVhZCA9IFRocmVhZC5jdXJyZW50VGhyZWFkKCk7Ci0JCQlpZiAoIWJ1c3lCdWlsZGluZykgewotCQkJCWJ1c3lCdWlsZGluZyA9IHRydWU7Ci0JCQkJbG9ja0NvdW50ZXIrKzsKLQkJCQl3b3JraW5nVGhyZWFkID0gY3VycmVudFRocmVhZDsKLQkJCX0gZWxzZSBpZiAod29ya2luZ1RocmVhZCA9PSBjdXJyZW50VGhyZWFkKSB7Ci0JCQkJLy9pbmNyZWFzZSB0aGUgbG9jayBjb3VudGVyIC0gdGhlIGxvY2sgaXMgcmVxdWlyZWQgcmVjdXJzaXZlbHkKLQkJCQlsb2NrQ291bnRlcisrOwotCQkJfSBlbHNlIGlmICh3b3JraW5nVGhyZWFkICE9IGN1cnJlbnRUaHJlYWQpIHsKLQkJCQlsb25nIHN0YXJ0ID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCk7Ci0JCQkJbG9uZyB0aW1lVG9XYWl0ID0gd2FpdFRpbWU7Ci0JCQkJYm9vbGVhbiBsb2NrU3VjY2VlZGVkID0gZmFsc2U7Ci0JCQkJZG8gewotCQkJCQl0cnkgewotCQkJCQkJbG9jay53YWl0KHRpbWVUb1dhaXQpOwotCQkJCQl9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBlKSB7Ci0JCQkJCQkvLyBkbyBub3RoaW5nCi0JCQkJCX0KLQkJCQkJaWYgKCFidXN5QnVpbGRpbmcpIHsKLQkJCQkJCWJ1c3lCdWlsZGluZyA9IHRydWU7Ci0JCQkJCQlsb2NrQ291bnRlcisrOwotCQkJCQkJd29ya2luZ1RocmVhZCA9IGN1cnJlbnRUaHJlYWQ7Ci0JCQkJCQlsb2NrU3VjY2VlZGVkID0gdHJ1ZTsKLQkJCQkJCWJyZWFrOwotCQkJCQl9Ci0JCQkJCXRpbWVUb1dhaXQgPSB3YWl0VGltZSArIHN0YXJ0IC0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCk7Ci0JCQkJfSB3aGlsZSAodGltZVRvV2FpdCA+IDApOwotCQkJCS8vY2hlY2sgaWYgdGhlIHRpbWVvdXQgaGFzIHBhc3NlZCBvciB0aGUgbG9jayBpcyBhY3R1YWxseSBzdWNjZXNzZnVsbHkgaGVsZAotCQkJCWlmICghbG9ja1N1Y2NlZWRlZCkgewotCQkJCQkvLyBUaGUgbG9jayBpcyBub3QgeWV0IHJlbGVhc2VkIQotCQkJCQkvLyBBbGxvdyB0aGUgb3BlcmF0aW9uIGJ1dCBsb2cgYSB3YXJuaW5nCi0JCQkJCUFjdGl2YXRvci5sb2cobnVsbCwgTG9nU2VydmljZS5MT0dfV0FSTklORywgTkxTLmJpbmQoTWVzc2FnZXMuVElNRU9VVF9HRVRUSU5HX0xPQ0ssIEludGVnZXIudG9TdHJpbmcoSW5zdGFuY2VQcm9jZXNzLndhaXRUaW1lKSksIG5ldyBFeGNlcHRpb24oIkRlYnVnIHN0YWNrdHJhY2UiKSk7IC8vJE5PTi1OTFMtMSQKLQkJCQl9Ci0JCQl9Ci0JCX0KLQl9Ci0KLQkvLyBmcmVlIHRoZSBzeW5jaCBsb2NrIAotCXZvaWQgZnJlZUxvY2soKSB7Ci0JCXN5bmNocm9uaXplZCAobG9jaykgewotCQkJaWYgKGJ1c3lCdWlsZGluZykgewotCQkJCWlmICh3b3JraW5nVGhyZWFkID09IFRocmVhZC5jdXJyZW50VGhyZWFkKCkpIHsKLQkJCQkJLy9vbmx5IHRoZSB0aHJlYWQgaG9sZGluZyB0aGUgbG9jayBjYW4gcmVsZWFzZSBpdAotCQkJCQlsb2NrQ291bnRlci0tOwotCQkJCX0KLQkJCQkvLyByZWxlYXNlIHRoZSBsb2NrIGluIGNhc2UgdGhlIGxvY2sgY291bnRlciBoYXMgZGVjcmVhc2VkIHRvIDAKLQkJCQlpZiAobG9ja0NvdW50ZXIgPT0gMCkgewotCQkJCQlidXN5QnVpbGRpbmcgPSBmYWxzZTsKLQkJCQkJd29ya2luZ1RocmVhZCA9IG51bGw7Ci0JCQkJCWxvY2subm90aWZ5KCk7Ci0JCQkJfQotCQkJfQotCQl9Ci0JfQotCi0JLyoqCi0JICogQnVpbGRzIHRoZSBTZXJ2aWNlIENvbXBvbmVudCBkZXNjcmlwdGlvbnMgKHJlZ2lzdHJhdGlvbiBvZiBuZWVkZWQKLQkgKiBzZXJ2aWNlcywgYnVpbGRpbmcgb2YgY29tcG9uZW50IGluc3RhbmNlcyBpZiBuZWNlc3NhcnkgKGluY2x1ZGVzCi0JICogYWN0aXZhdGluZyBhbmQgYmluZGluZykKLQkgKiAKLQkgKiBAcGFyYW0gbGlzdCAtCi0JICogICAgICAgICAgICBhIFZlY3RvciBvZiBhbGwgY29tcG9uZW50cyB0byBidWlsZC4KLQkgKi8KLQlwdWJsaWMgdm9pZCBidWlsZENvbXBvbmVudHMoVmVjdG9yIGxpc3QsIGJvb2xlYW4gc2VjdXJpdHkpIHsKLQkJU2VydmljZUNvbXBvbmVudFByb3Agc2NwID0gbnVsbDsKLQkJU2VydmljZUNvbXBvbmVudCBzYzsKLQkJU3RyaW5nIGZhY3RvcnlQaWQgPSBudWxsOwotCi0JCS8vIGxvb3AgdGhyb3VnaCBTQ1AgbGlzdCBvZiBlbmFibGVkCi0JCWlmIChsaXN0ICE9IG51bGwpIHsKLQkJCWdldExvY2soKTsKLQkJCVZlY3RvciBsaXN0VG9CdWlsZCA9IG5ldyBWZWN0b3IoKTsKLQkJCWZvciAoaW50IGkgPSAwOyBpIDwgbGlzdC5zaXplKCk7IGkrKykgewotCQkJCXNjcCA9IChTZXJ2aWNlQ29tcG9uZW50UHJvcCkgbGlzdC5lbGVtZW50QXQoaSk7Ci0JCQkJaWYgKHNjcC5nZXRTdGF0ZSgpICE9IENvbXBvbmVudC5TVEFURV9VTlNBVElTRklFRCkgewotCQkJCQkvL25vIG5lZWQgdG8gYnVpbGQgdGhlIGNvbXBvbmVudDoKLQkJCQkJLy8gMSkgaXQgaXMgZGlzcG9zZWQgb3IgYWJvdXQgdG8gYmUgZGlzcG9zZWQKLQkJCQkJLy8gMikgaXQgaXMgYWxyZWFkeSBidWlsdCBvciBiZWluZyBidWlsdAotCQkJCQljb250aW51ZTsKLQkJCQl9Ci0JCQkJc2NwLnNldFN0YXRlKENvbXBvbmVudC5TVEFURV9BQ1RJVkFUSU5HKTsKLQkJCQlsaXN0VG9CdWlsZC5hZGRFbGVtZW50KHNjcCk7Ci0JCQl9Ci0JCQlmcmVlTG9jaygpOwotCQkJZm9yIChpbnQgaSA9IDA7IGkgPCBsaXN0VG9CdWlsZC5zaXplKCk7IGkrKykgewotCQkJCXNjcCA9IChTZXJ2aWNlQ29tcG9uZW50UHJvcCkgbGlzdFRvQnVpbGQuZWxlbWVudEF0KGkpOwotCQkJCWdldExvY2soKTsKLQkJCQlpZiAoc2NwLmdldFN0YXRlKCkgIT0gQ29tcG9uZW50LlNUQVRFX0FDVElWQVRJTkcpIHsKLQkJCQkJLy9ubyBuZWVkIHRvIGJ1aWxkIHRoZSBjb21wb25lbnQ6Ci0JCQkJCS8vIDEpIGl0IGlzIGRpc3Bvc2VkIG9yIGFib3V0IHRvIGJlIGRpc3Bvc2VkCi0JCQkJCS8vIDIpIGl0IGlzIGFscmVhZHkgYnVpbHQgb3IgYmVpbmcgYnVpbHQKLQkJCQkJZnJlZUxvY2soKTsKLQkJCQkJY29udGludWU7Ci0JCQkJfQotCQkJCWxvbmcgc3RhcnQgPSAwbDsKLQkJCQlib29sZWFuIHN1Y2Nlc3NmdWxseUJ1aWx0ID0gdHJ1ZTsKLQkJCQl0cnkgewotCQkJCQlpZiAoQWN0aXZhdG9yLlBFUkYpIHsKLQkJCQkJCXN0YXJ0ID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCk7Ci0JCQkJCQlBY3RpdmF0b3IubG9nLmluZm8oIltEUyBwZXJmXSBTdGFydCBidWlsZGluZyBjb21wb25lbnQgIiArIHNjcCk7IC8vJE5PTi1OTFMtMSQKLQkJCQkJfQotCQkJCQlzYyA9IHNjcC5zZXJ2aWNlQ29tcG9uZW50OwotCQkJCQlpZiAoc2MuaW1tZWRpYXRlIHx8IChzYy5mYWN0b3J5ID09IG51bGwgJiYgQWN0aXZhdG9yLklOU1RBTlRJQVRFX0FMTCkpIHsKLQkJCQkJCWlmIChBY3RpdmF0b3IuREVCVUcpIHsKLQkJCQkJCQlBY3RpdmF0b3IubG9nLmRlYnVnKCJJbnN0YW5jZVByb2Nlc3MuYnVpbGRDb21wb25lbnRzKCk6IGJ1aWxkaW5nIGltbWVkaWF0ZSBjb21wb25lbnQgIiArIHNjcC5uYW1lLCBudWxsKTsgLy8kTk9OLU5MUy0xJAotCQkJCQkJfQotCQkJCQkJaWYgKHNjcC5pbnN0YW5jZXMuaXNFbXB0eSgpKSB7Ci0JCQkJCQkJdHJ5IHsKLQkJCQkJCQkJYnVpbGRDb21wb25lbnQobnVsbCwgc2NwLCBudWxsLCBzZWN1cml0eSk7Ci0JCQkJCQkJfSBjYXRjaCAoVGhyb3dhYmxlIGUpIHsKLQkJCQkJCQkJcmVzb2x2ZXIucmVvcmRlclNDUChzY3ApOwotCQkJCQkJCQlzdWNjZXNzZnVsbHlCdWlsdCA9IGZhbHNlOwotCQkJCQkJCQlpZiAoIShlIGluc3RhbmNlb2YgQ29tcG9uZW50RXhjZXB0aW9uKSkgewotCQkJCQkJCQkJQWN0aXZhdG9yLmxvZyhudWxsLCBMb2dTZXJ2aWNlLkxPR19FUlJPUiwgTkxTLmJpbmQoTWVzc2FnZXMuQ0FOTk9UX0JVSUxEX0NPTVBPTkVOVCwgc2NwKSwgZSk7Ci0JCQkJCQkJCX0KLQkJCQkJCQl9Ci0JCQkJCQl9Ci0JCQkJCQlpZiAoc3VjY2Vzc2Z1bGx5QnVpbHQpIHsKLQkJCQkJCQlpZiAoc2Muc2VydmljZUludGVyZmFjZXMgIT0gbnVsbCkgewotCQkJCQkJCQkvLyB0aGlzIGNvbXBvbmVudCByZWdpc3RlcnMgc2VydmljZQotCQkJCQkJCQkvL3RoZSBzZXJ2aWNlIHdpbGwgYmUgcmVnaXN0ZXJlZCBvbmx5IGlmIHRoZSBjb21wb25lbnQgd2FzIHN1Y2Nlc3NmdWxseSBidWlsdAotCi0JCQkJCQkJCS8vIHRoaXMgd2lsbCBjcmVhdGUgZWl0aGVyIHBsYWluIHNlcnZpY2UgY29tcG9uZW50IHJlZ2lzdHJhdGlvbgotCQkJCQkJCQkvLyBvciBhIHNlcnZpY2UgZmFjdG9yeSByZWdpc3RyYXRpb24KLQkJCQkJCQkJcmVnaXN0ZXJTZXJ2aWNlKHNjcCwgc2Muc2VydmljZUZhY3RvcnksIG51bGwpOwotCQkJCQkJCX0KLQkJCQkJCQlzY3Auc2V0U3RhdGUoQ29tcG9uZW50LlNUQVRFX0FDVElWRSk7Ci0JCQkJCQl9Ci0JCQkJCX0gZWxzZSB7Ci0KLQkJCQkJCS8vIENvbXBvbmVudEZhY3RvcnkKLQkJCQkJCWlmIChzYy5mYWN0b3J5ICE9IG51bGwpIHsKLQkJCQkJCQkvLyBjaGVjayBpZiBpdCBpcyBOT1QgYSBjb21wb25lbnQgY29uZmlnIGNyZWF0ZWQgYnkgYQotCQkJCQkJCS8vIGNvbXBvbmVudCBmYWN0b3J5Ci0JCQkJCQkJaWYgKHNjcC5pc0NvbXBvbmVudEZhY3RvcnkoKSkgewotCQkJCQkJCQlpZiAoQWN0aXZhdG9yLkRFQlVHKSB7Ci0JCQkJCQkJCQlBY3RpdmF0b3IubG9nLmRlYnVnKCJJbnN0YW5jZVByb2Nlc3MuYnVpbGRDb21wb25lbnRzKCk6IGJ1aWxkaW5nIGNvbXBvbmVudCBmYWN0b3J5ICIgKyBzY3AubmFtZSwgbnVsbCk7IC8vJE5PTi1OTFMtMSQKLQkJCQkJCQkJfQotCi0JCQkJCQkJCS8vIGNoZWNrIGlmIE1TRgotCQkJCQkJCQl0cnkgewotCQkJCQkJCQkJQ29uZmlndXJhdGlvbiBjb25maWcgPSBBY3RpdmF0b3IuZ2V0Q29uZmlndXJhdGlvbihzYy5nZXRDb25maWd1cmF0aW9uUElEKCkpOwotCQkJCQkJCQkJaWYgKGNvbmZpZyAhPSBudWxsKSB7Ci0JCQkJCQkJCQkJZmFjdG9yeVBpZCA9IGNvbmZpZy5nZXRGYWN0b3J5UGlkKCk7Ci0JCQkJCQkJCQl9Ci0JCQkJCQkJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7Ci0JCQkJCQkJCQlBY3RpdmF0b3IubG9nKG51bGwsIExvZ1NlcnZpY2UuTE9HX0VSUk9SLCBOTFMuYmluZChNZXNzYWdlcy5DQU5OT1RfR0VUX0NPTkZJR1VSQVRJT04sIHNjLmdldENvbmZpZ3VyYXRpb25QSUQoKSksIGUpOwotCQkJCQkJCQl9Ci0KLQkJCQkJCQkJLy8gaWYgTVNGIHRocm93IGV4Y2VwdGlvbiAtIGNhbid0IGJlCi0JCQkJCQkJCS8vIENvbXBvbmVudEZhY3RvcnkgYWRkIE1TRgotCQkJCQkJCQlpZiAoZmFjdG9yeVBpZCAhPSBudWxsKSB7Ci0JCQkJCQkJCQlWZWN0b3IgdG9EaXNhYmxlID0gbmV3IFZlY3RvcigxKTsKLQkJCQkJCQkJCXRvRGlzYWJsZS5hZGRFbGVtZW50KHNjKTsKLQkJCQkJCQkJCUluc3RhbmNlUHJvY2Vzcy5yZXNvbHZlci5kaXNhYmxlQ29tcG9uZW50cyh0b0Rpc2FibGUsIENvbXBvbmVudENvbnN0YW50cy5ERUFDVElWQVRJT05fUkVBU09OX1VOU1BFQ0lGSUVEKTsKLQkJCQkJCQkJCXN1Y2Nlc3NmdWxseUJ1aWx0ID0gZmFsc2U7Ci0JCQkJCQkJCQl0aHJvdyBuZXcgb3JnLm9zZ2kuc2VydmljZS5jb21wb25lbnQuQ29tcG9uZW50RXhjZXB0aW9uKE1lc3NhZ2VzLklOQ09NUEFUSUJMRV9DT01CSU5BVElPTik7Ci0JCQkJCQkJCX0KLQkJCQkJCQkJc2NwLnNldFN0YXRlKENvbXBvbmVudC5TVEFURV9GQUNUT1JZKTsKLQkJCQkJCQkJcmVnaXN0ZXJDb21wb25lbnRGYWN0b3J5KHNjcCk7Ci0JCQkJCQkJCS8vIHdoZW4gcmVnaXN0ZXJpbmcgYSBDb21wb25lbnRGYWN0b3J5IHdlIG11c3Qgbm90Ci0JCQkJCQkJCS8vIHJlZ2lzdGVyIHRoZSBjb21wb25lbnQgY29uZmlndXJhdGlvbiBhcyBzZXJ2aWNlCi0JCQkJCQkJCWNvbnRpbnVlOwotCQkJCQkJCX0KLQkJCQkJCX0KLQotCQkJCQkJLy8gY2hlY2sgd2hldGhlciB0aGVyZSBpcyBhIHNlcnZpY2UgdG8gcmVnaXN0ZXIKLQkJCQkJCWlmIChzYy5wcm92aWRlcyAhPSBudWxsKSB7Ci0JCQkJCQkJLy8gdGhpcyB3aWxsIGNyZWF0ZSBlaXRoZXIgcGxhaW4gc2VydmljZSBjb21wb25lbnQKLQkJCQkJCQkvLyByZWdpc3RyYXRpb24gb3IgYSBzZXJ2aWNlIGZhY3RvcnkgcmVnaXN0cmF0aW9uCi0JCQkJCQkJc2NwLnNldFN0YXRlKENvbXBvbmVudC5TVEFURV9SRUdJU1RFUkVEKTsKLQkJCQkJCQlyZWdpc3RlclNlcnZpY2Uoc2NwLCBzYy5zZXJ2aWNlRmFjdG9yeSwgbnVsbCk7Ci0JCQkJCQl9Ci0JCQkJCX0KLQkJCQl9IGNhdGNoIChUaHJvd2FibGUgdCkgewotCQkJCQlBY3RpdmF0b3IubG9nKG51bGwsIExvZ1NlcnZpY2UuTE9HX0VSUk9SLCBOTFMuYmluZChNZXNzYWdlcy5FWENFUFRJT05fQlVJTERJTkdfQ09NUE9ORU5ULCBzY3Auc2VydmljZUNvbXBvbmVudCksIHQpOwotCQkJCX0gZmluYWxseSB7Ci0JCQkJCWlmICghc3VjY2Vzc2Z1bGx5QnVpbHQpIHsKLQkJCQkJCXNjcC5zZXRTdGF0ZShDb21wb25lbnQuU1RBVEVfVU5TQVRJU0ZJRUQpOwotCQkJCQl9Ci0JCQkJCWZyZWVMb2NrKCk7Ci0JCQkJCWlmIChBY3RpdmF0b3IuUEVSRikgewotCQkJCQkJc3RhcnQgPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKSAtIHN0YXJ0OwotCQkJCQkJQWN0aXZhdG9yLmxvZy5pbmZvKCJbRFMgcGVyZl0gVGhlIGNvbXBvbmVudCAiICsgc2NwICsgIiBpcyBidWlsdCBmb3IgIiArIExvbmcudG9TdHJpbmcoc3RhcnQpICsgIm1zIik7IC8vJE5PTi1OTFMtMSQgLy8kTk9OLU5MUy0yJC8vJE5PTi1OTFMtMyQKLQkJCQkJfQotCQkJCX0KLQkJCX0gLy8gZW5kIGZvcgotCQl9IC8vIGVuZCBpZiAobGlzdCAhPSBudWxsKQotCX0KLQotCS8qKgotCSAqIAotCSAqIERpc3Bvc2Ugb2YgQ29tcG9uZW50IEluc3RhbmNlcywgaW5jbHVkZXMgdW5yZWdpc3RlcmluZyBzZXJ2aWNlcyBhbmQKLQkgKiByZW1vdmluZyBpbnN0YW5jZXMuCi0JICogCi0JICogQHBhcmFtIHNjcExpc3QgLQotCSAqICAgICAgICAgICAgbGlzdCBvZiBDb21wb25lbnREZXNjcmlwdGlvbnMgcGx1cyBQcm9wZXJ0eSBvYmplY3RzIHRvIGJlCi0JICogICAgICAgICAgICBkaXNwb3NlZAotCSAqLwotCXZvaWQgZGlzcG9zZUluc3RhbmNlcyhWZWN0b3Igc2NwTGlzdCwgaW50IGRlYWN0aXZhdGVSZWFzb24pIHsKLQkJLy8gbG9vcCB0aHJvdWdoIFNDK1AgbGlzdCB0byBiZSBkaXNwb3NlZAotCQlpZiAoc2NwTGlzdCAhPSBudWxsKSB7Ci0JCQlmb3IgKGludCBpID0gMDsgaSA8IHNjcExpc3Quc2l6ZSgpOyBpKyspIHsKLQkJCQlTZXJ2aWNlQ29tcG9uZW50UHJvcCBzY3AgPSAoU2VydmljZUNvbXBvbmVudFByb3ApIHNjcExpc3QuZWxlbWVudEF0KGkpOwotCQkJCWdldExvY2soKTsKLQkJCQlpZiAoc2NwLmlzVW5zYXRpc2ZpZWQoKSkgewotCQkJCQkvL2l0IGlzIGFscmVhZHkgZGVhY3RpdmF0ZWQKLQkJCQkJZnJlZUxvY2soKTsKLQkJCQkJY29udGludWU7Ci0JCQkJfQotCQkJCWxvbmcgc3RhcnQgPSAwbDsKLQkJCQl0cnkgewotCQkJCQlzY3Auc2V0U3RhdGUoQ29tcG9uZW50LlNUQVRFX0RFQUNUSVZBVElORyk7Ci0JCQkJCWlmIChBY3RpdmF0b3IuUEVSRikgewotCQkJCQkJc3RhcnQgPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKTsKLQkJCQkJCUFjdGl2YXRvci5sb2cuaW5mbygiW0RTIHBlcmZdIFN0YXJ0IGRpc3Bvc2luZyBjb21wb25lbnQgIiArIHNjcCk7IC8vJE5PTi1OTFMtMSQKLQkJCQkJfQotCQkJCQlkaXNwb3NlSW5zdGFuY2VzKHNjcCwgZGVhY3RpdmF0ZVJlYXNvbik7Ci0JCQkJfSBjYXRjaCAoVGhyb3dhYmxlIHQpIHsKLQkJCQkJQWN0aXZhdG9yLmxvZyhudWxsLCBMb2dTZXJ2aWNlLkxPR19FUlJPUiwgTkxTLmJpbmQoTWVzc2FnZXMuRVJST1JfRElTUE9TSU5HX0lOU1RBTkNFUywgc2NwKSwgdCk7Ci0JCQkJfSBmaW5hbGx5IHsKLQkJCQkJcmVzb2x2ZXIuY29tcG9uZW50RGlzcG9zZWQoc2NwKTsKLQkJCQkJZnJlZUxvY2soKTsKLQkJCQkJaWYgKEFjdGl2YXRvci5QRVJGKSB7Ci0JCQkJCQlzdGFydCA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpIC0gc3RhcnQ7Ci0JCQkJCQlBY3RpdmF0b3IubG9nLmluZm8oIltEUyBwZXJmXSBUaGUgY29tcG9uZW50ICIgKyBzY3AgKyAiIGlzIGRpc3Bvc2VkIGZvciAiICsgTG9uZy50b1N0cmluZyhzdGFydCkgKyAibXMiKTsgLy8kTk9OLU5MUy0xJCAvLyROT04tTkxTLTIkIC8vJE5PTi1OTFMtMyQKLQkJCQkJfQotCQkJCX0KLQkJCX0KLQkJfQotCX0KLQotCS8qKgotCSAqIEBwYXJhbSBzY3AKLQkgKi8KLQlwcml2YXRlIHZvaWQgZGlzcG9zZUluc3RhbmNlcyhTZXJ2aWNlQ29tcG9uZW50UHJvcCBzY3AsIGludCBkZWFjdGl2YXRlUmVhc29uKSB7Ci0JCWlmIChzY3AuaXNDb21wb25lbnRGYWN0b3J5KCkpIHsKLQkJCWlmIChBY3RpdmF0b3IuREVCVUcpIHsKLQkJCQlBY3RpdmF0b3IubG9nLmRlYnVnKCJJbnN0YW5jZVByb2Nlc3MuZGlzcG9zZUluc3RhbmNlcygpOiBkaXNwb3NpbmcgY29tcG9uZW50IGZhY3RvcnkgIiArIHNjcC5uYW1lLCBudWxsKTsgLy8kTk9OLU5MUy0xJAotCQkJfQotCQkJU2VydmljZVJlZ2lzdHJhdGlvbiByZWcgPSAoU2VydmljZVJlZ2lzdHJhdGlvbikgZmFjdG9yeVJlZ2lzdHJhdGlvbnMucmVtb3ZlKHNjcCk7Ci0JCQl0cnkgewotCQkJCWlmIChyZWcgIT0gbnVsbCkKLQkJCQkJcmVnLnVucmVnaXN0ZXIoKTsKLQkJCX0gY2F0Y2ggKElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBlKSB7Ci0JCQkJLy8gU2VydmljZSBpcyBhbHJlYWR5IHVucmVnaXN0ZXJlZCBkbyBub3RoaW5nCi0JCQkJQWN0aXZhdG9yLmxvZyhudWxsLCBMb2dTZXJ2aWNlLkxPR19XQVJOSU5HLCBOTFMuYmluZChNZXNzYWdlcy5GQUNUT1JZX1JFR0lTVFJBVElPTl9BTFJFQURZX0RJU1BPU0VELCBzY3AubmFtZSksIG51bGwpOwotCQkJfQotCQl9Ci0JCVNlcnZpY2VDb21wb25lbnQgc2MgPSBzY3Auc2VydmljZUNvbXBvbmVudDsKLQkJLy8gaWYgbm8gU2VydmljZXMgcHJvdmlkZWQgLSBkaXNwb3NlIG9mIGluc3RhbmNlIGltbWVkaWF0ZWx5Ci0JCWlmIChzYy5wcm92aWRlcyA9PSBudWxsKSB7Ci0JCQlpZiAoQWN0aXZhdG9yLkRFQlVHKSB7Ci0JCQkJQWN0aXZhdG9yLmxvZy5kZWJ1ZygiSW5zdGFuY2VQcm9jZXNzLmRpc3Bvc2VJbnN0YW5jZXMoKTogZGlzcG9zaW5nIG5vbi1wcm92aWRlciBjb21wb25lbnQgIiArIHNjcC5uYW1lLCBudWxsKTsgLy8kTk9OLU5MUy0xJAotCQkJfQotCQkJc2NwLmRpc3Bvc2UoZGVhY3RpdmF0ZVJlYXNvbik7Ci0JCX0gZWxzZSB7Ci0JCQkvLyBUaGUgY29tcG9uZW50IHJlZ2lzdGVycyBzZXJ2aWNlcwotCQkJaWYgKEFjdGl2YXRvci5ERUJVRykgewotCQkJCUFjdGl2YXRvci5sb2cuZGVidWcoIkluc3RhbmNlUHJvY2Vzcy5kaXNwb3NlSW5zdGFuY2VzKCk6IHVucmVnaXN0ZXJpbmcgY29tcG9uZW50ICIgKyBzY3AubmFtZSwgbnVsbCk7IC8vJE5PTi1OTFMtMSQKLQkJCX0KLQotCQkJLy8gdW5yZWdpc3RlciBzZXJ2aWNlcyBpZiBhbnkKLQkJCWlmIChzY3AucmVnaXN0cmF0aW9uICE9IG51bGwpIHsKLQkJCQl0cnkgewotCQkJCQlTZXJ2aWNlUmVnaXN0cmF0aW9uIHJlZyA9IHNjcC5yZWdpc3RyYXRpb247Ci0JCQkJCXNjcC5zZXRSZWdpc3RyYXRpb24obnVsbCk7Ci0JCQkJCXJlZy51bnJlZ2lzdGVyKCk7Ci0JCQkJfSBjYXRjaCAoSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGUpIHsKLQkJCQkJLy8gU2VydmljZSBpcyBhbHJlYWR5IHVucmVnaXN0ZXJlZCBkbyBub3RoaW5nCi0JCQkJCUFjdGl2YXRvci5sb2cobnVsbCwgTG9nU2VydmljZS5MT0dfV0FSTklORywgTkxTLmJpbmQoTWVzc2FnZXMuUkVHSVNUUkFUSU9OX0FMUkVBRFlfRElTUE9TRUQsIHNjcC5uYW1lKSwgbnVsbCk7Ci0JCQkJfQotCQkJfSBlbHNlIHsKLQkJCQlpZiAoQWN0aXZhdG9yLkRFQlVHKSB7Ci0JCQkJCUFjdGl2YXRvci5sb2cuZGVidWcoIkluc3RhbmNlUHJvY2Vzcy5kaXNwb3NlSW5zdGFuY2VzKCk6IGNhbm5vdCBmaW5kIHJlZ2lzdHJhdGlvbnMgZm9yICIgKyBzY3AubmFtZSwgbnVsbCk7IC8vJE5PTi1OTFMtMSQKLQkJCQl9Ci0JCQl9Ci0JCQlzY3AuZGlzcG9zZShkZWFjdGl2YXRlUmVhc29uKTsKLQkJfQotCX0KLQotCS8qKgotCSAqIFJlZ2lzdGVyIHRoZSBDb21wb25lbnQgRmFjdG9yeQotCSAqIAotCSAqIEBwYXJhbSBzY3AKLQkgKi8KLQlwcml2YXRlIHZvaWQgcmVnaXN0ZXJDb21wb25lbnRGYWN0b3J5KFNlcnZpY2VDb21wb25lbnRQcm9wIHNjcCkgewotCQlpZiAoZmFjdG9yeVJlZ2lzdHJhdGlvbnMuZ2V0KHNjcCkgIT0gbnVsbCkgewotCQkJLy90aGUgc2VydmljZSBmYWN0b3J5IGlzIGFscmVhZHkgcmVnaXN0ZXJlZAotCQkJcmV0dXJuOwotCQl9Ci0JCUNvbXBvbmVudEZhY3RvcnkgZmFjdG9yeSA9IG5ldyBDb21wb25lbnRGYWN0b3J5SW1wbChzY3ApOwotCQlTZXJ2aWNlQ29tcG9uZW50IHNjID0gc2NwLnNlcnZpY2VDb21wb25lbnQ7Ci0JCUJ1bmRsZUNvbnRleHQgYmMgPSBzY3AuYmM7Ci0JCS8vIGlmIHRoZSBmYWN0b3J5IGF0dHJpYnV0ZSBpcyBzZXQgb24gdGhlIGNvbXBvbmVudCBlbGVtZW50IHRoZW4KLQkJLy8gcmVnaXN0ZXIgYQotCQkvLyBjb21wb25lbnQgZmFjdG9yeSBzZXJ2aWNlCi0JCS8vIGZvciB0aGUgU2VydmljZSBDb21wb25lbnQgb24gYmVoYWxmIG9mIHRoZSBTZXJ2aWNlIENvbXBvbmVudC4KLQkJSGFzaHRhYmxlIHByb3BlcnRpZXMgPSBuZXcgSGFzaHRhYmxlKDIpOwotCQlwcm9wZXJ0aWVzLnB1dChDb21wb25lbnRDb25zdGFudHMuQ09NUE9ORU5UX05BTUUsIHNjLm5hbWUpOwotCQlwcm9wZXJ0aWVzLnB1dChDb21wb25lbnRDb25zdGFudHMuQ09NUE9ORU5UX0ZBQ1RPUlksIHNjLmZhY3RvcnkpOwotCQlTZXJ2aWNlUmVnaXN0cmF0aW9uIHJlZyA9IGJjLnJlZ2lzdGVyU2VydmljZShDb21wb25lbnRGYWN0b3J5LmNsYXNzLmdldE5hbWUoKSwgZmFjdG9yeSwgcHJvcGVydGllcyk7Ci0JCWZhY3RvcnlSZWdpc3RyYXRpb25zLnB1dChzY3AsIHJlZyk7Ci0JfQotCi0JLyoqCi0JICogQ2FsbGVkIGJ5IFJlc29sdmVyIHdoZW4gdGhlcmUgaXMgYSBuZWVkIG9mIGR5bmFtaWMgYmluZGluZyBvZiByZWZlcmVuY2VzCi0JICogCi0JICogQHBhcmFtIHJlZkxpc3QgdGhlIHJlZmVyZW5jZXMgdG8gYmUgYm91bmQKLQkgKiBAcmV0dXJuIGEgVmVjdG9yIGNvbnRhaW5pbmcgdGhlIFJlZmVyZW5jZSBvYmplY3RzIHRoYXQgYXJlIHN0aWxsIG5vdCBib3VuZCBkdWUgdG8gQ2xhc3NDaXJjdWxhcml0eUVycm9yLiAKLQkgKiAJCQlUaGUgcmV0dXJuZWQgdmFsdWUgbWF5IGJlIG51bGwgaWYgYWxsIG9mIHRoZSBwYXNzZWQgcmVmZXJlbmNlcyBhcmUgc3VjY2Vzc2Z1bGx5IGJvdW5kIAotCSAqLwotCWZpbmFsIFZlY3RvciBkeW5hbWljQmluZChWZWN0b3IgcmVmTGlzdCkgewotCQlpZiAocmVmTGlzdCA9PSBudWxsIHx8IHJlZkxpc3QuaXNFbXB0eSgpKSB7Ci0JCQlyZXR1cm4gbnVsbDsKLQkJfQotCQlWZWN0b3IgdW5ib3VuZFJlZnMgPSBudWxsOwotCQlmb3IgKGludCBpID0gMDsgaSA8IHJlZkxpc3Quc2l6ZSgpOyBpKyspIHsKLQkJCVJlZmVyZW5jZSByZWYgPSAoUmVmZXJlbmNlKSByZWZMaXN0LmVsZW1lbnRBdChpKTsKLQkJCVNlcnZpY2VDb21wb25lbnRQcm9wIHNjcCA9IHJlZi5zY3A7Ci0KLQkJCVZlY3RvciBpbnN0YW5jZXMgPSBzY3AuaW5zdGFuY2VzOwotCQkJaWYgKGluc3RhbmNlcyAhPSBudWxsKSB7Ci0JCQkJZm9yIChpbnQgaiA9IDA7IGogPCBpbnN0YW5jZXMuc2l6ZSgpOyBqKyspIHsKLQkJCQkJQ29tcG9uZW50SW5zdGFuY2UgY29tcEluc3RhbmNlID0gKENvbXBvbmVudEluc3RhbmNlKSBpbnN0YW5jZXMuZWxlbWVudEF0KGopOwotCQkJCQlpZiAoY29tcEluc3RhbmNlICE9IG51bGwpIHsKLQkJCQkJCXRyeSB7Ci0JCQkJCQkJc2NwLmJpbmRSZWZlcmVuY2UocmVmLCBjb21wSW5zdGFuY2UpOwotCQkJCQkJfSBjYXRjaCAoQ2xhc3NDaXJjdWxhcml0eUVycm9yIGNjZSkgewotCQkJCQkJCWlmICh1bmJvdW5kUmVmcyA9PSBudWxsKSB7Ci0JCQkJCQkJCXVuYm91bmRSZWZzID0gbmV3IFZlY3RvcigxKTsKLQkJCQkJCQl9Ci0JCQkJCQkJdW5ib3VuZFJlZnMuYWRkKHJlZik7Ci0JCQkJCQkJQWN0aXZhdG9yLmxvZyhzY3AuYmMsIExvZ1NlcnZpY2UuTE9HX0VSUk9SLCBOTFMuYmluZChNZXNzYWdlcy5FUlJPUl9CSU5ESU5HX1JFRkVSRU5DRSwgcmVmLnJlZmVyZW5jZSksIGNjZSk7Ci0JCQkJCQl9IGNhdGNoIChUaHJvd2FibGUgdCkgewotCQkJCQkJCUFjdGl2YXRvci5sb2coc2NwLmJjLCBMb2dTZXJ2aWNlLkxPR19FUlJPUiwgTkxTLmJpbmQoTWVzc2FnZXMuRVJST1JfQklORElOR19SRUZFUkVOQ0UsIHJlZi5yZWZlcmVuY2UpLCB0KTsKLQkJCQkJCX0KLQkJCQkJfQotCQkJCX0KLQkJCX0gZWxzZSB7Ci0JCQkJLy8gdGhlIGNvbXBvbmVudCBpcyBub3QgdXNlZCBhbmQgdGhlcmVmb3JlIGl0IGlzIG5vdCB5ZXQKLQkJCQkvLyBpbnN0YW50aWF0ZWQhCi0JCQkJaWYgKEFjdGl2YXRvci5ERUJVRykgewotCQkJCQlBY3RpdmF0b3IubG9nLmRlYnVnKCJJbnN0YW5jZVByb2Nlc3MuZHluYW1pY0JpbmQoKTogbnVsbCBpbnN0YW5jZXMgZm9yIGNvbXBvbmVudCAiICsgc2NwLm5hbWUsIG51bGwpOyAvLyROT04tTkxTLTEkCi0JCQkJfQotCQkJfQotCQl9Ci0JCXJldHVybiB1bmJvdW5kUmVmczsKLQl9Ci0KLQkvKioKLQkgKiBDYWxsZWQgYnkgZGlzcGF0Y2hlciAoIFJlc29sdmVyKSB3aGVuIHdvcmsgYXZhaWxhYmxlIG9uIHF1ZXVlCi0JICogCi0JICogQHBhcmFtIHNlcnZpY2VUYWJsZQotCSAqICAgICAgICAgICAgTWFwIG9mIFJlZmVyZW5jZURlc2NyaXB0aW9uOnN1YnRhYmxlIFN1YnRhYmxlIE1hcHMgc2NwOnNlcnZpY2UKLQkgKiAgICAgICAgICAgIG9iamVjdAotCSAqLwotCWZpbmFsIHZvaWQgZHluYW1pY1VuQmluZChIYXNodGFibGUgc2VydmljZVRhYmxlKSB7Ci0JCXRyeSB7Ci0JCQlpZiAoc2VydmljZVRhYmxlID09IG51bGwgfHwgc2VydmljZVRhYmxlLmlzRW1wdHkoKSkgewotCQkJCXJldHVybjsKLQkJCX0KLQkJCS8vIGZvciBlYWNoIGVsZW1lbnQgaW4gdGhlIHRhYmxlCi0JCQlFbnVtZXJhdGlvbiBlID0gc2VydmljZVRhYmxlLmtleXMoKTsKLQkJCXdoaWxlIChlLmhhc01vcmVFbGVtZW50cygpKSB7Ci0JCQkJUmVmZXJlbmNlIHJlZiA9IChSZWZlcmVuY2UpIGUubmV4dEVsZW1lbnQoKTsKLQkJCQlIYXNodGFibGUgc2VydmljZVN1YlRhYmxlID0gKEhhc2h0YWJsZSkgc2VydmljZVRhYmxlLmdldChyZWYpOwotCQkJCUVudW1lcmF0aW9uIHN1YiA9IHNlcnZpY2VTdWJUYWJsZS5rZXlzKCk7Ci0JCQkJd2hpbGUgKHN1Yi5oYXNNb3JlRWxlbWVudHMoKSkgewotCQkJCQlTZXJ2aWNlQ29tcG9uZW50UHJvcCBzY3AgPSAoU2VydmljZUNvbXBvbmVudFByb3ApIHN1Yi5uZXh0RWxlbWVudCgpOwotCQkJCQlTZXJ2aWNlUmVmZXJlbmNlIHNlcnZpY2VSZWZlcmVuY2UgPSAoU2VydmljZVJlZmVyZW5jZSkgc2VydmljZVN1YlRhYmxlLmdldChzY3ApOwotCQkJCQkvLyBnZXQgdGhlIGxpc3Qgb2YgaW5zdGFuY2VzIGNyZWF0ZWQKLQkJCQkJVmVjdG9yIGluc3RhbmNlcyA9IHNjcC5pbnN0YW5jZXM7Ci0JCQkJCWZvciAoaW50IGkgPSAwOyBpIDwgaW5zdGFuY2VzLnNpemUoKTsgaSsrKSB7Ci0JCQkJCQlDb21wb25lbnRJbnN0YW5jZSBjb21wSW5zdGFuY2UgPSAoQ29tcG9uZW50SW5zdGFuY2UpIGluc3RhbmNlcy5lbGVtZW50QXQoaSk7Ci0JCQkJCQlpZiAoY29tcEluc3RhbmNlICE9IG51bGwpIHsKLQkJCQkJCQl0cnkgewotCQkJCQkJCQlzY3AudW5iaW5kRHluYW1pY1JlZmVyZW5jZShyZWYsIGNvbXBJbnN0YW5jZSwgc2VydmljZVJlZmVyZW5jZSk7Ci0JCQkJCQkJfSBjYXRjaCAoVGhyb3dhYmxlIHQpIHsKLQkJCQkJCQkJQWN0aXZhdG9yLmxvZyhudWxsLCBMb2dTZXJ2aWNlLkxPR19FUlJPUiwgTkxTLmJpbmQoTWVzc2FnZXMuRVJST1JfVU5CSU5ESU5HX1JFRkVSRU5DRSwgcmVmLnJlZmVyZW5jZSwgY29tcEluc3RhbmNlLmdldEluc3RhbmNlKCkpLCB0KTsKLQkJCQkJCQl9Ci0JCQkJCQl9Ci0JCQkJCX0KLQkJCQl9Ci0JCQl9Ci0JCX0gY2F0Y2ggKFRocm93YWJsZSBlKSB7Ci0JCQkvL3Nob3VsZCBub3QgaGFwcGVuCi0JCQlBY3RpdmF0b3IubG9nKG51bGwsIExvZ1NlcnZpY2UuTE9HX0VSUk9SLCBNZXNzYWdlcy5VTkVYUEVDVEVEX0VSUk9SLCBlKTsKLQkJfQotCX0KLQotCS8qKgotCSAqIENhbGxlZCBieSBkaXNwYXRjaGVyICggUmVzb2x2ZXIpIHdoZW4gc2VydmljZSBwcm9wZXJ0aWVzIGhhdmUgYmVlbiBtb2RpZmllZCBmb3Igc29tZSByZWZlcmVuY2UgIAotCSAqIAotCSAqIEBwYXJhbSBzZXJ2aWNlUmVmZXJlbmNlVGFibGUJTWFwIG9mIDxSZWZlcmVuY2U+OjxNYXAgb2YgPFNlcnZpY2VDb21wb25lbnRQcm9wPjo8U2VydmljZVJlZmVyZW5jZT4+Ci0JICovCi0JZmluYWwgdm9pZCByZWZlcmVuY2VQcm9wZXJ0aWVzVXBkYXRlZChIYXNodGFibGUgc2VydmljZVJlZmVyZW5jZVRhYmxlKSB7Ci0JCS8vIGZvciBlYWNoIGVsZW1lbnQgaW4gdGhlIHRhYmxlCi0JCUVudW1lcmF0aW9uIGUgPSBzZXJ2aWNlUmVmZXJlbmNlVGFibGUua2V5cygpOwotCQl3aGlsZSAoZS5oYXNNb3JlRWxlbWVudHMoKSkgewotCQkJUmVmZXJlbmNlIHJlZiA9IChSZWZlcmVuY2UpIGUubmV4dEVsZW1lbnQoKTsKLQkJCUhhc2h0YWJsZSBzZXJ2aWNlU3ViVGFibGUgPSAoSGFzaHRhYmxlKSBzZXJ2aWNlUmVmZXJlbmNlVGFibGUuZ2V0KHJlZik7Ci0JCQlFbnVtZXJhdGlvbiBzdWIgPSBzZXJ2aWNlU3ViVGFibGUua2V5cygpOwotCQkJd2hpbGUgKHN1Yi5oYXNNb3JlRWxlbWVudHMoKSkgewotCQkJCVNlcnZpY2VDb21wb25lbnRQcm9wIHNjcCA9IChTZXJ2aWNlQ29tcG9uZW50UHJvcCkgc3ViLm5leHRFbGVtZW50KCk7Ci0JCQkJU2VydmljZVJlZmVyZW5jZSBzZXJ2aWNlUmVmZXJlbmNlID0gKFNlcnZpY2VSZWZlcmVuY2UpIHNlcnZpY2VTdWJUYWJsZS5nZXQoc2NwKTsKLQkJCQkvLyBnZXQgdGhlIGxpc3Qgb2YgaW5zdGFuY2VzIGNyZWF0ZWQKLQkJCQlWZWN0b3IgaW5zdGFuY2VzID0gc2NwLmluc3RhbmNlczsKLQkJCQlmb3IgKGludCBpID0gMDsgaSA8IGluc3RhbmNlcy5zaXplKCk7IGkrKykgewotCQkJCQlDb21wb25lbnRJbnN0YW5jZSBjb21wSW5zdGFuY2UgPSAoQ29tcG9uZW50SW5zdGFuY2UpIGluc3RhbmNlcy5lbGVtZW50QXQoaSk7Ci0JCQkJCWlmIChjb21wSW5zdGFuY2UgIT0gbnVsbCkgewotCQkJCQkJdHJ5IHsKLQkJCQkJCQlzY3AudXBkYXRlZFJlZmVyZW5jZShyZWYsIGNvbXBJbnN0YW5jZSwgc2VydmljZVJlZmVyZW5jZSk7Ci0JCQkJCQl9IGNhdGNoIChUaHJvd2FibGUgdCkgewotCQkJCQkJCUFjdGl2YXRvci5sb2cobnVsbCwgTG9nU2VydmljZS5MT0dfRVJST1IsIE5MUy5iaW5kKE1lc3NhZ2VzLkVSUk9SX1VQREFUSU5HX1JFRkVSRU5DRSwgcmVmLnJlZmVyZW5jZSwgY29tcEluc3RhbmNlLmdldEluc3RhbmNlKCkpLCB0KTsKLQkJCQkJCX0KLQkJCQkJfQotCQkJCX0KLQkJCX0KLQkJfQotCX0KLQotCS8qKgotCSAqIHJlZ2lzdGVyU2VydmljZQotCSAqIAotCSAqIEBwYXJhbSBzY3AKLQkgKiAgICAgICAgICAgIENvbXBvbmVudERlc2NyaXB0aW9uIHBsdXMgUHJvcGVydGllcwotCSAqIEBwYXJhbSBmYWN0b3J5Ci0JICogICAgICAgICAgICBib29sZWFuCi0JICogQHBhcmFtIGNpCi0JICogICAgICAgICAgICB0aGUgY29tcG9uZW50IGluc3RhbmNlIGNyZWF0ZWQgYnkgQ29tcG9uZW50RmFjdG9yeUltcGwhCi0JICovCi0JcHJpdmF0ZSB2b2lkIHJlZ2lzdGVyU2VydmljZShTZXJ2aWNlQ29tcG9uZW50UHJvcCBzY3AsIGJvb2xlYW4gZmFjdG9yeSwgQ29tcG9uZW50SW5zdGFuY2VJbXBsIGNpKSB7Ci0JCS8vIHJlZ2lzdGVyIHRoZSBzZXJ2aWNlIHVzaW5nIGEgU2VydmljZUZhY3RvcnkKLQkJU2VydmljZVJlZ2lzdHJhdGlvbiByZWcgPSBudWxsOwotCQlPYmplY3Qgc2VydmljZTsKLQkJaWYgKHNjcC5yZWdpc3RyYXRpb24gIT0gbnVsbCkgewotCQkJLy90aGUgc2VydmljZSBoYXMgYWxyZWFkeSBiZWVuIHJlZ2lzdGVyZWQKLQkJCXJldHVybjsKLQkJfQotCQlpZiAoZmFjdG9yeSkgewotCQkJLy8gcmVnaXN0ZXIgYXMgc2VydmljZSBmYWN0b3J5Ci0JCQlzZXJ2aWNlID0gbmV3IEZhY3RvcnlSZWcoc2NwKTsKLQkJfSBlbHNlIHsKLQkJCXNlcnZpY2UgPSBuZXcgU2VydmljZVJlZyhzY3AsIGNpKTsKLQkJfQotCi0JCXJlZyA9IHNjcC5iYy5yZWdpc3RlclNlcnZpY2Uoc2NwLnNlcnZpY2VDb21wb25lbnQucHJvdmlkZXMsIHNlcnZpY2UsIHNjcC5nZXRQdWJsaWNTZXJ2aWNlUHJvcGVydGllcygpKTsKLQotCQlpZiAoQWN0aXZhdG9yLkRFQlVHKSB7Ci0JCQlBY3RpdmF0b3IubG9nLmRlYnVnKCJJbnN0YW5jZVByb2Nlc3MucmVnaXN0ZXJTZXJ2aWNlKCk6ICIgKyBzY3AubmFtZSArICIgcmVnaXN0ZXJlZCBhcyAiICsgKChmYWN0b3J5KSA/ICIqZmFjdG9yeSoiIDogIipzZXJ2aWNlKiIpLCBudWxsKTsgLy8kTk9OLU5MUy0xJCAvLyROT04tTkxTLTIkIC8vJE5PTi1OTFMtMyQgLy8kTk9OLU5MUy00JAotCQl9Ci0JCWlmIChzY3AuaXNVbnNhdGlzZmllZCgpKSB7Ci0JCQkvL211c3QgdW5yZWdpc3RlciB0aGUgc2VydmljZSBiZWNhdXNlIGl0IHdhcyBub3QgYWJsZSB0byB1bnJlZ2lzdGVyIHdoZW4gdGhlIGNvbXBvbmVudCB3YXMgZGlzcG9zZWQKLQkJCXRyeSB7Ci0JCQkJcmVnLnVucmVnaXN0ZXIoKTsKLQkJCQlpZiAoQWN0aXZhdG9yLkRFQlVHKSB7Ci0JCQkJCUFjdGl2YXRvci5sb2cuZGVidWcoIkluc3RhbmNlUHJvY2Vzcy5yZWdpc3RlclNlcnZpY2UoKTogVGhlIHNlcnZpY2Ugb2YgY29tcG9uZW50ICIgKyBzY3AubmFtZSArICIgd2FzIHVucmVnaXN0ZXJlZCBiZWNhdXNlIHRoZSBjb21wb25lbnQgaXMgYWxyZWFkeSBkaXNwb3NlZCEiLCBudWxsKTsgLy8kTk9OLU5MUy0xJCAvLyROT04tTkxTLTIkCi0JCQkJfQotCQkJfSBjYXRjaCAoSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGUpIHsKLQkJCQkvLyBTZXJ2aWNlIGlzIGFscmVhZHkgdW5yZWdpc3RlcmVkIGRvIG5vdGhpbmcKLQkJCX0KLQkJfSBlbHNlIHsKLQkJCXNjcC5zZXRSZWdpc3RyYXRpb24ocmVnKTsKLQkJfQotCX0KLQotCXB1YmxpYyBDb21wb25lbnRJbnN0YW5jZUltcGwgYnVpbGRDb21wb25lbnQoQnVuZGxlIHVzaW5nQnVuZGxlLCBTZXJ2aWNlQ29tcG9uZW50UHJvcCBzY3AsIE9iamVjdCBpbnN0YW5jZSwgYm9vbGVhbiBzZWN1cml0eSkgdGhyb3dzIENvbXBvbmVudEV4Y2VwdGlvbiB7Ci0JCWlmIChBY3RpdmF0b3IuREVCVUcpIHsKLQkJCUFjdGl2YXRvci5sb2cuZGVidWcoIkluc3RhbmNlUHJvY2Vzcy5idWlsZENvbXBvbmVudCgpOiBidWlsZGluZyBjb21wb25lbnQgIiArIHNjcC5uYW1lLCBudWxsKTsgLy8kTk9OLU5MUy0xJAotCQl9Ci0JCWdldExvY2soKTsKLQkJQ291bnRlciBjb3VudGVyOwotCQlUaHJlYWQgY3VyVGhyZWFkID0gVGhyZWFkLmN1cnJlbnRUaHJlYWQoKTsKLQkJc3luY2hyb25pemVkIChzY3ApIHsKLQkJCVRocmVhZCB0aGVTQ1BUaHJlYWQgPSAoVGhyZWFkKSBidWlsZGluZ1RocmVhZHMuZ2V0KHNjcCk7Ci0JCQlpZiAodGhlU0NQVGhyZWFkICE9IG51bGwgJiYgY3VyVGhyZWFkICE9IHRoZVNDUFRocmVhZCkgeyAvL21hbmFnZSBjeWNsaWMgY2FsbHMgCi0JCQkJaWYgKHNjcC5pc0tpbmRPZkZhY3RvcnkoKSkgewotCQkJCQkvLyBUaGUgc2NwIGlzIGEga2luZCBvZiBmYWN0b3J5IC0gbXVsdGlwbGUgaW5zdGFuY2VzIGFyZSBhbGxvd2VkLiAKLQkJCQkJLy8gVGhlIGJ1aWxkaW5nIG9mIHRoZSBzY3AgaXMgYWxsb3dlZAotCQkJCX0gZWxzZSB7Ci0JCQkJCWxvbmcgc3RhcnQgPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKTsKLQkJCQkJbG9uZyB0aW1lVG9XYWl0ID0gd2FpdFRpbWU7Ci0JCQkJCWRvIHsKLQkJCQkJCXRyeSB7Ci0JCQkJCQkJc2NwLndhaXQodGltZVRvV2FpdCk7Ci0JCQkJCQl9IGNhdGNoIChJbnRlcnJ1cHRlZEV4Y2VwdGlvbiBpZSkgewotCQkJCQkJCS8vZG8gbm90aGluZwotCQkJCQkJfQotCQkJCQkJaWYgKGJ1aWxkaW5nVGhyZWFkcy5nZXQoc2NwKSA9PSBudWxsKSB7Ci0JCQkJCQkJLy90aGUgbG9jayBpcyByZWxlYXNlZAotCQkJCQkJCWJyZWFrOwotCQkJCQkJfQotCQkJCQkJdGltZVRvV2FpdCA9IHdhaXRUaW1lICsgc3RhcnQgLSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKTsKLQkJCQkJfSB3aGlsZSAodGltZVRvV2FpdCA+IDApOwotCi0JCQkJCS8vY2hlY2sgaWYgdGhlIHRpbWVvdXQgaGFzIHBhc3NlZCBvciB0aGUgc2NwIGlzIGFjdHVhbGx5IGJ1aWx0CQotCQkJCQlpZiAoYnVpbGRpbmdUaHJlYWRzLmdldChzY3ApICE9IG51bGwpIHsKLQkJCQkJCWZyZWVMb2NrKCk7Ci0JCQkJCQkvLyBUaGUgU0NQIGlzIG5vdCB5ZXQgYnVpbHQKLQkJCQkJCS8vIFdlIGhhdmUgdHdvIG9wdGlvbnMgaGVyZToKLQkJCQkJCS8vIDEgLSBSZXR1cm4gdGhlIGluc3RhbmNlIChpZiBhbHJlYWR5IGNyZWF0ZWQpIG5ldmVydGhlbGVzcyBpdCBpcyBub3QgZmluaXNoZWQgaXRzIGJpbmRpbmcgYW5kIGFjdGl2YXRpb24gcGhhc2UKLQkJCQkJCS8vIDIgLSB0aHJvdyBhbiBleGNlcHRpb24gYmVjYXVzZSBzb21ldGhpbmcgbWF5IGhhdmUgZ29uZSB3cm9uZwotCQkJCQkJaWYgKCFzY3AuaW5zdGFuY2VzLmlzRW1wdHkoKSkgewotCQkJCQkJCUFjdGl2YXRvci5sb2cobnVsbCwgTG9nU2VydmljZS5MT0dfV0FSTklORywgTWVzc2FnZXMuUkVUVVJOSU5HX05PVF9GVUxMWV9BQ1RJVkFURURfSU5TVEFOQ0UsIG5ldyBFeGNlcHRpb24oIkRlYnVnIGNhbGxzdGFjayIpKTsgLy8kTk9OLU5MUy0xJAotCQkJCQkJCXJldHVybiAoQ29tcG9uZW50SW5zdGFuY2VJbXBsKSBzY3AuaW5zdGFuY2VzLmZpcnN0RWxlbWVudCgpOwotCQkJCQkJfQotCi0JCQkJCQl0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihOTFMuYmluZChNZXNzYWdlcy5JTlNUQU5DRV9DUkVBVElPTl9UT09LX0xPTkdFUiwgc2NwLCBJbnRlZ2VyLnRvU3RyaW5nKHdhaXRUaW1lKSkpOwotCQkJCQl9Ci0JCQkJfQotCQkJfQotCQkJYnVpbGRpbmdUaHJlYWRzLnB1dChzY3AsIGN1clRocmVhZCk7Ci0KLQkJCS8vIGtlZXAgdHJhY2sgb2YgaG93IG1hbnkgdGltZXMgd2UgaGF2ZSByZS1lbnRlcmVkIHRoaXMgbWV0aG9kCi0JCQljb3VudGVyID0gKENvdW50ZXIpIHN0YWNrQ291bnRzLmdldChjdXJUaHJlYWQpOwotCQkJaWYgKGNvdW50ZXIgPT0gbnVsbCkgewotCQkJCWNvdW50ZXIgPSBuZXcgQ291bnRlcigpOwotCQkJCXN0YWNrQ291bnRzLnB1dChjdXJUaHJlYWQsIGNvdW50ZXIpOwotCQkJfQotCQkJY291bnRlci5jb3VudCsrOwotCQl9Ci0KLQkJbG9uZyBzdGFydCA9IDBsOwotCQl0cnkgewotCQkJaWYgKEFjdGl2YXRvci5QRVJGKSB7Ci0JCQkJc3RhcnQgPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKTsKLQkJCQlBY3RpdmF0b3IubG9nLmluZm8oIltEUyBwZXJmXSBTdGFydCBidWlsZGluZyBpbnN0YW5jZSBvZiBjb21wb25lbnQgIiArIHNjcCk7IC8vJE5PTi1OTFMtMSQKLQkJCX0KLQkJCUNvbXBvbmVudEluc3RhbmNlSW1wbCBjb21wb25lbnRJbnN0YW5jZSA9IG51bGw7Ci0JCQl0cnkgewotCQkJCWNvbXBvbmVudEluc3RhbmNlID0gc2NwLmJ1aWxkKHVzaW5nQnVuZGxlLCBpbnN0YW5jZSwgc2VjdXJpdHkpOwotCQkJfSBjYXRjaCAoQ2xhc3NDaXJjdWxhcml0eUVycm9yIGUpIHsKLQkJCQlwcm9jZXNzU0NQSW5DbGFzc0NpcmN1bGFyaXR5RXJyb3Ioc2NwKTsKLQkJCQl0aHJvdyBuZXcgQ29tcG9uZW50RXhjZXB0aW9uKE5MUy5iaW5kKE1lc3NhZ2VzLkVSUk9SX0JVSUxESU5HX0NPTVBPTkVOVF9JTlNUQU5DRSwgc2NwLnNlcnZpY2VDb21wb25lbnQpLCBlKTsKLQkJCX0gY2F0Y2ggKENvbXBvbmVudEV4Y2VwdGlvbiBlKSB7Ci0JCQkJQWN0aXZhdG9yLmxvZyhudWxsLCBMb2dTZXJ2aWNlLkxPR19FUlJPUiwgZS5nZXRNZXNzYWdlKCksIGUuZ2V0Q2F1c2UoKSk7Ci0JCQkJVGhyb3dhYmxlIHQgPSBlLmdldENhdXNlKCk7Ci0JCQkJaWYgKHQgaW5zdGFuY2VvZiBJbnZvY2F0aW9uVGFyZ2V0RXhjZXB0aW9uKSB7Ci0JCQkJCVRocm93YWJsZSBjYXVzZSA9IHQuZ2V0Q2F1c2UoKTsKLQkJCQkJaWYgKGNhdXNlIGluc3RhbmNlb2YgQ2xhc3NDaXJjdWxhcml0eUVycm9yKSB7Ci0JCQkJCQlwcm9jZXNzU0NQSW5DbGFzc0NpcmN1bGFyaXR5RXJyb3Ioc2NwKTsKLQkJCQkJfQotCQkJCX0KLQotCQkJCXRocm93IGU7Ci0JCQl9IGNhdGNoIChUaHJvd2FibGUgdCkgewotCQkJCUFjdGl2YXRvci5sb2cobnVsbCwgTG9nU2VydmljZS5MT0dfRVJST1IsIE5MUy5iaW5kKE1lc3NhZ2VzLkVSUk9SX0JVSUxESU5HX0NPTVBPTkVOVF9JTlNUQU5DRSwgc2NwLnNlcnZpY2VDb21wb25lbnQpLCB0KTsKLQkJCQl0aHJvdyBuZXcgQ29tcG9uZW50RXhjZXB0aW9uKE5MUy5iaW5kKE1lc3NhZ2VzLkVSUk9SX0JVSUxESU5HX0NPTVBPTkVOVF9JTlNUQU5DRSwgc2NwLnNlcnZpY2VDb21wb25lbnQpLCB0KTsKLQkJCX0gZmluYWxseSB7Ci0JCQkJLy8ga2VlcCB0cmFjayBvZiBob3cgbWFueSB0aW1lcyB3ZSBoYXZlIHJlLWVudGVyZWQgdGhpcyBtZXRob2QKLQkJCQljb3VudGVyLmNvdW50LS07Ci0JCQkJaWYgKEFjdGl2YXRvci5QRVJGKSB7Ci0JCQkJCXN0YXJ0ID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCkgLSBzdGFydDsKLQkJCQkJQWN0aXZhdG9yLmxvZy5pbmZvKCJbRFMgcGVyZl0gVGhlIGluc3RhbmNlIG9mIGNvbXBvbmVudCAiICsgc2NwICsgIiBpcyBidWlsdCBmb3IgIiArIExvbmcudG9TdHJpbmcoc3RhcnQpICsgIm1zIik7IC8vJE5PTi1OTFMtMSQgLy8kTk9OLU5MUy0yJCAvLyROT04tTkxTLTMkCi0JCQkJfQotCQkJfQotCi0JCQkvLyBpZiB0aGlzIGlzIHRoZSBsYXN0IHRpbWUgaW4gdGhpcyBtZXRob2QgYW5kIHdlIGhhdmUgImRlbGF5ZWQiCi0JCQkvLyBiaW5kIGFjdGlvbnMgdG8gZG8gKHRoZXJlIHdhcyBhIGNpcmN1bGFyaXR5IGR1cmluZyBiaW5kKQotCQkJaWYgKGNvdW50ZXIuY291bnQgPT0gMCAmJiAhZGVsYXllZEJpbmRMaXN0LmlzRW1wdHkoKSkgewotCQkJCS8vIHB1dCBkZWxheWVkIGR5bmFtaWMgYmluZHMgb24gdGhlIHF1ZXVlLgotCQkJCS8vICh0aGlzIGlzIHVzZWQgdG8gaGFuZGxlIGNpcmN1bGFyaXR5KQotCQkJCXJlc29sdmVyLm1nci5lbnF1ZXVlV29yayhyZXNvbHZlciwgUmVzb2x2ZXIuRFlOQU1JQ0JJTkQsIGRlbGF5ZWRCaW5kTGlzdC5jbG9uZSgpLCBzZWN1cml0eSk7Ci0JCQkJZGVsYXllZEJpbmRMaXN0LnJlbW92ZUFsbEVsZW1lbnRzKCk7Ci0JCQl9Ci0KLQkJCXJldHVybiBjb21wb25lbnRJbnN0YW5jZTsKLQkJfSBmaW5hbGx5IHsKLQkJCXN5bmNocm9uaXplZCAoc2NwKSB7Ci0JCQkJaWYgKGNvdW50ZXIuY291bnQgPT0gMCkgewotCQkJCQlzdGFja0NvdW50cy5yZW1vdmUoY3VyVGhyZWFkKTsKLQkJCQl9Ci0JCQkJYnVpbGRpbmdUaHJlYWRzLnJlbW92ZShzY3ApOwotCQkJCXNjcC5ub3RpZnkoKTsKLQkJCX0KLQkJCWZyZWVMb2NrKCk7Ci0JCX0KLQl9Ci0KLQlwcml2YXRlIHZvaWQgcHJvY2Vzc1NDUEluQ2xhc3NDaXJjdWxhcml0eUVycm9yKFNlcnZpY2VDb21wb25lbnRQcm9wIGN1cnJlbnRTY3ApIHsKLQkJVmVjdG9yIGNvbXBvbmVudCA9IG5ldyBWZWN0b3IoMSk7Ci0JCWNvbXBvbmVudC5hZGQoY3VycmVudFNjcC5zZXJ2aWNlQ29tcG9uZW50KTsKLQkJcmVzb2x2ZXIubWdyLmVucXVldWVXb3JrKHJlc29sdmVyLm1nciwgcmVzb2x2ZXIubWdyLkVOQUJMRV9DT01QT05FTlRTLCBjb21wb25lbnQsIGZhbHNlKTsKLQl9Ci0KLQlwdWJsaWMgdm9pZCBtb2RpZnlDb21wb25lbnQoU2VydmljZUNvbXBvbmVudFByb3Agc2NwLCBEaWN0aW9uYXJ5IG5ld1Byb3BzKSB0aHJvd3MgQ29tcG9uZW50RXhjZXB0aW9uIHsKLQkJaWYgKEFjdGl2YXRvci5ERUJVRykgewotCQkJQWN0aXZhdG9yLmxvZy5kZWJ1ZygiTW9kaWZ5aW5nIGNvbXBvbmVudCAiICsgc2NwLm5hbWUsIG51bGwpOyAvLyROT04tTkxTLTEkCi0JCX0KLQkJZ2V0TG9jaygpOwotCQlsb25nIHN0YXJ0ID0gMGw7Ci0JCXRyeSB7Ci0JCQlpZiAoIXNjcC5pc0J1aWx0KCkpIHsKLQkJCQlyZXR1cm47Ci0JCQl9Ci0JCQlpZiAoQWN0aXZhdG9yLlBFUkYpIHsKLQkJCQlzdGFydCA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOwotCQkJCUFjdGl2YXRvci5sb2cuaW5mbygiW0RTIHBlcmZdIE1vZGlmeWluZyBjb21wb25lbnQgIiArIHNjcC5uYW1lKTsgLy8kTk9OLU5MUy0xJAotCQkJfQotCQkJdHJ5IHsKLQkJCQlzY3AubW9kaWZ5KG5ld1Byb3BzKTsKLQkJCX0gY2F0Y2ggKENvbXBvbmVudEV4Y2VwdGlvbiBlKSB7Ci0JCQkJQWN0aXZhdG9yLmxvZyhudWxsLCBMb2dTZXJ2aWNlLkxPR19FUlJPUiwgZS5nZXRNZXNzYWdlKCksIGUuZ2V0Q2F1c2UoKSk7Ci0JCQkJdGhyb3cgZTsKLQkJCX0gY2F0Y2ggKFRocm93YWJsZSB0KSB7Ci0JCQkJQWN0aXZhdG9yLmxvZyhudWxsLCBMb2dTZXJ2aWNlLkxPR19FUlJPUiwgTkxTLmJpbmQoTWVzc2FnZXMuRVJST1JfTU9ESUZZSU5HX0NPTVBPTkVOVCwgc2NwLnNlcnZpY2VDb21wb25lbnQpLCB0KTsKLQkJCQl0aHJvdyBuZXcgQ29tcG9uZW50RXhjZXB0aW9uKE5MUy5iaW5kKE1lc3NhZ2VzLkVSUk9SX01PRElGWUlOR19DT01QT05FTlQsIHNjcC5zZXJ2aWNlQ29tcG9uZW50KSwgdCk7Ci0JCQl9IGZpbmFsbHkgewotCQkJCS8vIGtlZXAgdHJhY2sgb2YgaG93IG1hbnkgdGltZXMgd2UgaGF2ZSByZS1lbnRlcmVkIHRoaXMgbWV0aG9kCi0JCQkJaWYgKEFjdGl2YXRvci5QRVJGKSB7Ci0JCQkJCXN0YXJ0ID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCkgLSBzdGFydDsKLQkJCQkJQWN0aXZhdG9yLmxvZy5pbmZvKCJbRFMgcGVyZl0gQ29tcG9uZW50ICIgKyBzY3AgKyAiIG1vZGlmaWVkIGZvciAiICsgTG9uZy50b1N0cmluZyhzdGFydCkgKyAibXMiKTsgLy8kTk9OLU5MUy0xJC8vJE5PTi1OTFMtMiQgLy8kTk9OLU5MUy0zJAotCQkJCX0KLQkJCX0KLQkJfSBmaW5hbGx5IHsKLQkJCWZyZWVMb2NrKCk7Ci0JCX0KLQl9Ci0KLQkvKioKLQkgKiBBY3F1aXJlIGEgc2VydmljZSBvYmplY3QgZnJvbSBhIHtAbGluayBTZXJ2aWNlUmVmZXJlbmNlfS4KLQkgKiAKLQkgKiBUaGlzIG1ldGhvZCBjaGVja3MgaWYgImdldHRpbmciIHRoZSBzZXJ2aWNlIGNvdWxkIGNhdXNlIGEgY3ljbGUuIElmIHNvLAotCSAqIGl0IGJyZWFrcyB0aGUgY3ljbGUgYW5kIHJldHVybnMgbnVsbC4KLQkgKiAKLQkgKiBAcGFyYW0gcmVmZXJlbmNlCi0JICogQHBhcmFtIHNlcnZpY2VSZWZlcmVuY2UKLQkgKiAKLQkgKiBAcmV0dXJuIHRoZSBzZXJ2aWNlIG9iamVjdCBvciBudWxsIGlmIGl0IHdvdWxkIGNhdXNlIGEgY2lyY3VsYXJpdHkKLQkgKi8KLQlwdWJsaWMgT2JqZWN0IGdldFNlcnZpY2UoUmVmZXJlbmNlIHJlZmVyZW5jZSwgU2VydmljZVJlZmVyZW5jZSBzZXJ2aWNlUmVmZXJlbmNlKSB7Ci0JCS8vIGNoZWNrIGlmIGdldHRpbmcgdGhpcyBzZXJ2aWNlIHdvdWxkIGNhdXNlIGEgY2lyY3VsYXJpdHkKLQkJaWYgKGNoZWNrQ2FuQ2F1c2VDeWNsZShyZWZlcmVuY2UsIHNlcnZpY2VSZWZlcmVuY2UpKSB7Ci0JCQlpZiAoQWN0aXZhdG9yLkRFQlVHKSB7Ci0JCQkJQWN0aXZhdG9yLmxvZy5kZWJ1ZygiSW5zdGFuY2VQcm9jZXNzLmdldFNlcnZpY2UoKTogY2Fubm90IGdldCBzZXJ2aWNlIGJlY2F1c2Ugb2YgY2lyY3VsYXJpdHkhIFJlZmVyZW5jZSBpczogIiArIHJlZmVyZW5jZS5yZWZlcmVuY2UubmFtZSArICIgOyBUaGUgc2VydmljZSByZWZlcmVuY2UgaXMgIiArIHNlcnZpY2VSZWZlcmVuY2UsIG51bGwpOyAvLyROT04tTkxTLTEkLy8kTk9OLU5MUy0yJAotCQkJfQotCQkJcmV0dXJuIG51bGw7Ci0JCX0KLQotCQkvLyBnZXR0aW5nIHRoaXMgc2VydmljZSB3aWxsIG5vdCBjYXVzZSBhIGNpcmN1bGFyaXR5Ci0JCU9iamVjdCBzZXJ2aWNlT2JqZWN0ID0gcmVmZXJlbmNlLnNjcC5iYy5nZXRTZXJ2aWNlKHNlcnZpY2VSZWZlcmVuY2UpOwotCQlpZiAoc2VydmljZU9iamVjdCA9PSBudWxsKSB7Ci0JCQlpZiAoQWN0aXZhdG9yLkRFQlVHKSB7Ci0JCQkJQWN0aXZhdG9yLmxvZy5kZWJ1ZygiW1NDUl0gUmV0dXJuZWQgc2VydmljZSBvYmplY3QgYnkgdGhlIGJ1bmRsZSBjb250ZXh0IGlzIG51bGwuIFRoZSByZWZlcmVuY2UgaXMgIiArIHJlZmVyZW5jZS5yZWZlcmVuY2UubmFtZSArICI7IFRoZSBTZXJ2aWNlUmVmZXJlbmNlIGlzICIgKyBzZXJ2aWNlUmVmZXJlbmNlLCBudWxsKTsgLy8kTk9OLU5MUy0xJCAvLyROT04tTkxTLTIkCi0JCQl9Ci0JCX0KLQkJcmV0dXJuIHNlcnZpY2VPYmplY3Q7Ci0JfQotCi0JLyoqCi0JICogQ2hlY2sgdGhlICJjeWNsZSBsaXN0IiBwdXQgaW4gdGhlIHNjcCBieSB0aGUgcmVzb2x2ZXIgdG8gc2VlIGlmIGdldHRpbmcKLQkgKiB0aGlzIHJlZmVyZW5jZSB3b3VsZCBjYXVzZSBhIGNpcmN1bGFyaXR5LgotCSAqIAotCSAqIEEgY2lyY3VsYXJpdHkgaXMgb25seSBwb3NzaWJsZSBpZiB0aGUgInByb2R1Y2VyIiBvZiB0aGUgc2VydmljZSBpcyBhbHNvIGEKLQkgKiBzZXJ2aWNlIGNvbXBvbmVudC4KLQkgKiAKLQkgKiBJZiBnZXR0aW5nIHRoZSBzZXJ2aWNlIGNvdWxkIGNhdXNlIGEgY2lyY3VsYXJpdHkgYW5kIHRoZSByZWZlcmVuY2UncwotCSAqIHBvbGljeSBpcyAiZHluYW1pYyIsIGFkZCBhbiBlbnRyeSB0byB0aGUgImRlbGF5ZWQgYmluZCBsaXN0IiB3aGljaCBpcwotCSAqIHByb2Nlc3NlZCB3aGVuIHRoZSBjb21wb25lbnQgaXMgYnVpbHQKLQkgKiAKLQkgKiBAcGFyYW0gcmVmZXJlbmNlCi0JICogQHBhcmFtIHNlcnZpY2VSZWZlcmVuY2UKLQkgKiBAcmV0dXJuIGlmIGdldHRpbmcgdGhlIHNlcnZpY2UgY291bGQgY2F1c2UgYSBjaXJjdWxhcml0eQotCSAqLwotCXByaXZhdGUgYm9vbGVhbiBjaGVja0NhbkNhdXNlQ3ljbGUoUmVmZXJlbmNlIHJlZmVyZW5jZSwgU2VydmljZVJlZmVyZW5jZSBzZXJ2aWNlUmVmZXJlbmNlKSB7Ci0KLQkJU2VydmljZUNvbXBvbmVudFByb3AgY29uc3VtZXJTQ1AgPSByZWZlcmVuY2Uuc2NwOwotCQkvLyBpZiB3ZSBhcmUgbm90IGJ1aWxkaW5nIGEgY29tcG9uZW50LCBubyBjeWNsZXMgcG9zc2libGUKLQkJaWYgKGJ1aWxkaW5nVGhyZWFkcy5pc0VtcHR5KCkpIHsKLQkJCXJldHVybiBmYWxzZTsKLQkJfQotCi0JCVN0cmluZyBwcm9kdWNlckNvbXBvbmVudE5hbWUgPSAoU3RyaW5nKSBzZXJ2aWNlUmVmZXJlbmNlLmdldFByb3BlcnR5KENvbXBvbmVudENvbnN0YW50cy5DT01QT05FTlRfTkFNRSk7Ci0KLQkJLy8gaWYgcHJvZHVjZXIgaXMgbm90IGEgc2VydmljZSBjb21wb25lbnQsIG5vIGN5Y2xlcyBwb3NzaWJsZQotCQlpZiAocHJvZHVjZXJDb21wb25lbnROYW1lID09IG51bGwpIHsKLQkJCXJldHVybiBmYWxzZTsKLQkJfQotCi0JCS8vIGNoZWNrIGlmIHByb2R1Y2VyIGlzIHRoZSAiZGVsYXllZCBhY3RpdmF0ZSIgbGlzdAotCQlpZiAoY29uc3VtZXJTQ1AuZ2V0RGVsYXlBY3RpdmF0ZVNDUE5hbWVzKCkgPT0gbnVsbCB8fCAhY29uc3VtZXJTQ1AuZ2V0RGVsYXlBY3RpdmF0ZVNDUE5hbWVzKCkuY29udGFpbnMocHJvZHVjZXJDb21wb25lbnROYW1lKSkgewotCQkJcmV0dXJuIGZhbHNlOwotCQl9Ci0KLQkJLy8gZmluZCBwcm9kdWNlciBzY3AKLQkJU2VydmljZUNvbXBvbmVudFByb3AgcHJvZHVjZXJTQ1AgPSBudWxsOwotCQlzeW5jaHJvbml6ZWQgKHJlc29sdmVyLmdldFN5bmNMb2NrKCkpIHsKLQkJCWZvciAoaW50IGkgPSAwOyBpIDwgcmVzb2x2ZXIuc2NwRW5hYmxlZC5zaXplKCk7IGkrKykgewotCQkJCVNlcnZpY2VDb21wb25lbnRQcm9wIHNjcCA9IChTZXJ2aWNlQ29tcG9uZW50UHJvcCkgcmVzb2x2ZXIuc2NwRW5hYmxlZC5lbGVtZW50QXQoaSk7Ci0JCQkJaWYgKHByb2R1Y2VyQ29tcG9uZW50TmFtZS5lcXVhbHMoc2NwLnNlcnZpY2VDb21wb25lbnQubmFtZSkpIHsKLQkJCQkJLy8gZm91bmQgdGhlIHByb2R1Y2VyIHNjcAotCQkJCQlwcm9kdWNlclNDUCA9IHNjcDsKLQkJCQkJYnJlYWs7Ci0JCQkJfQotCQkJfQotCQl9Ci0KLQkJaWYgKHByb2R1Y2VyU0NQICE9IG51bGwpIHsKLQkJCWlmIChwcm9kdWNlclNDUC5nZXRTdGF0ZSgpID09IENvbXBvbmVudC5TVEFURV9BQ1RJVkUpIHsKLQkJCQlpZiAocHJvZHVjZXJTQ1Auc2VydmljZUNvbXBvbmVudC5zZXJ2aWNlRmFjdG9yeSkgewotCQkJCQkvLyBwcm9kdWNlciBpcyBhIHNlcnZpY2UgZmFjdG9yeSAtIHRoZXJlIGlzIGEgbmV3IGluc3RhbmNlIGZvciBldmVyeQotCQkJCQkvLyBidW5kbGUsIHNvIHNlZSBpZiBvbmUgb2YgdGhlIGluc3RhbmNlcyBpcyB1c2VkIGJ5IHRoaXMgYnVuZGxlCi0JCQkJCWlmICghcHJvZHVjZXJTQ1AuaW5zdGFuY2VzLmlzRW1wdHkoKSkgewotCQkJCQkJQnVuZGxlIGJ1bmRsZSA9IGNvbnN1bWVyU0NQLmJjLmdldEJ1bmRsZSgpOwotCQkJCQkJZm9yIChpbnQgaSA9IDA7IGkgPCBwcm9kdWNlclNDUC5pbnN0YW5jZXMuc2l6ZSgpOyBpKyspIHsKLQkJCQkJCQlDb21wb25lbnRJbnN0YW5jZUltcGwgcHJvZHVjZXJDb21wb25lbnRJbnN0YW5jZSA9IChDb21wb25lbnRJbnN0YW5jZUltcGwpIHByb2R1Y2VyU0NQLmluc3RhbmNlcy5lbGVtZW50QXQoaSk7Ci0JCQkJCQkJaWYgKHByb2R1Y2VyQ29tcG9uZW50SW5zdGFuY2UuZ2V0Q29tcG9uZW50Q29udGV4dCgpLmdldFVzaW5nQnVuZGxlKCkuZXF1YWxzKGJ1bmRsZSkpIHsKLQkJCQkJCQkJLy8gYSBwcm9kdWNlciBhbHJlYWR5IGV4aXN0cywgc28gbm8gY3ljbGUgcG9zc2libGUKLQkJCQkJCQkJcmV0dXJuIGZhbHNlOwotCQkJCQkJCX0KLQkJCQkJCX0KLQkJCQkJfQotCQkJCX0gZWxzZSB7Ci0JCQkJCS8vIHByb2R1Y2VyIGlzIG5vdCBhIHNlcnZpY2UgZmFjdG9yeSAtIHRoZXJlIHdpbGwgb25seSBldmVyIGJlIG9uZQotCQkJCQkvLyBpbnN0YW5jZSAtIGlmIGl0IGV4aXN0cyB0aGVuIG5vIGN5Y2xlIHBvc3NpYmxlCi0JCQkJCWlmICghcHJvZHVjZXJTQ1AuaW5zdGFuY2VzLmlzRW1wdHkoKSkgewotCQkJCQkJcmV0dXJuIGZhbHNlOwotCQkJCQl9Ci0JCQkJfQotCQkJfQotCQl9Ci0KLQkJLy8gcHJvZHVjZXIgc2NwIGlzIG5vdCBhY3RpdmUgLSBkbyBub3QgYWN0aXZhdGUgaXQgYmVjYXVzZSB0aGF0IGNvdWxkCi0JCS8vIGNhdXNlIGNpcmN1bGFyaXR5Ci0KLQkJLy8gaWYgcmVmZXJlbmNlIGhhcyBiaW5kIG1ldGhvZCBhbmQgcG9saWN5PWR5bmFtaWMsIGFjdGl2YXRlIGxhdGVyIGFuZCBiaW5kCi0JCWlmIChyZWZlcmVuY2UucmVmZXJlbmNlLmJpbmQgIT0gbnVsbCAmJiByZWZlcmVuY2UucG9saWN5ID09IENvbXBvbmVudFJlZmVyZW5jZS5QT0xJQ1lfRFlOQU1JQykgewotCQkJLy8gZGVsYXkgYmluZCBieSBwdXR0aW5nIG9uIHRoZSBxdWV1ZSBsYXRlcgotCQkJaWYgKEFjdGl2YXRvci5ERUJVRykgewotCQkJCUFjdGl2YXRvci5sb2cuZGVidWcoIltTQ1JdIEFkZGluZyByZWZlcmVuY2UgZm9yIGRlbGF5ZWQgYmluZGluZy4gUmVmZXJlbmNlIGlzICIgKyByZWZlcmVuY2UucmVmZXJlbmNlLm5hbWUsIG51bGwpOyAvLyROT04tTkxTLTEkCi0JCQl9Ci0JCQlkZWxheWVkQmluZExpc3QuYWRkRWxlbWVudChyZWZlcmVuY2UpOwotCQl9Ci0KLQkJLy8gY2FuJ3QgZ2V0IHNlcnZpY2Ugbm93IGJlY2F1c2Ugb2YgY2lyY3VsYXJpdHkgLSB3ZSB3aWxsIGJpbmQgbGF0ZXIKLQkJLy8gKGR5bmFtaWNhbGx5KSBpZiB0aGUgcmVmZXJlbmNlIGhhZCBhIGJpbmQgbWV0aG9kIGFuZCB3YXMgZHluYW1pYwotCQlyZXR1cm4gdHJ1ZTsKLQl9Ci0KLQkvKioKLQkgKiBDb3VudHMgcmUtZW50cnkgaW4gdG8gdGhlCi0JICoge0BsaW5rIEluc3RhbmNlUHJvY2VzcyNidWlsZENvbXBvbmVudChCdW5kbGUsIFNlcnZpY2VDb21wb25lbnRQcm9wLCBPYmplY3QpfSBtZXRob2QuIAotCSAqIFRoaXMgaXMgdXNlZCB0byBoYW5kbGUgY2lyY3VsYXIgZGVwZW5kZW5jaWVzLgotCSAqLwotCXN0YXRpYyBjbGFzcyBDb3VudGVyIHsKLQkJaW50IGNvdW50ID0gMDsKLQl9Ci0KLX0KZGlmZiAtLWdpdCBhL2J1bmRsZXMvb3JnLmVjbGlwc2UuZXF1aW5veC5kcy9zcmMvb3JnL2VjbGlwc2UvZXF1aW5veC9pbnRlcm5hbC9kcy9NZXNzYWdlcy5qYXZhIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5lcXVpbm94LmRzL3NyYy9vcmcvZWNsaXBzZS9lcXVpbm94L2ludGVybmFsL2RzL01lc3NhZ2VzLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDJlN2Q2ZDUuLjAwMDAwMDAKLS0tIGEvYnVuZGxlcy9vcmcuZWNsaXBzZS5lcXVpbm94LmRzL3NyYy9vcmcvZWNsaXBzZS9lcXVpbm94L2ludGVybmFsL2RzL01lc3NhZ2VzLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxODMgKzAsMCBAQAotLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKLSAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxMCBieSBQcm9TeXN0IFNvZnR3YXJlIEdtYkgKLSAqIGh0dHA6Ly93d3cucHJvc3lzdC5jb20KLSAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMKLSAqIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2UgdjEuMAotICogd2hpY2ggYWNjb21wYW5pZXMgdGhpcyBkaXN0cmlidXRpb24sIGFuZCBpcyBhdmFpbGFibGUgYXQKLSAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLXYxMC5odG1sCi0gKgotICogQ29udHJpYnV0b3JzOgotICogICAgUHJvU3lzdCBTb2Z0d2FyZSBHbWJIIC0gaW5pdGlhbCBBUEkgYW5kIGltcGxlbWVudGF0aW9uCi0gKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLXBhY2thZ2Ugb3JnLmVjbGlwc2UuZXF1aW5veC5pbnRlcm5hbC5kczsKLQotaW1wb3J0IG9yZy5lY2xpcHNlLm9zZ2kudXRpbC5OTFM7Ci0KLXB1YmxpYyBjbGFzcyBNZXNzYWdlcyBleHRlbmRzIE5MUyB7Ci0JcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEJVTkRMRV9OQU1FID0gIm9yZy5lY2xpcHNlLmVxdWlub3guaW50ZXJuYWwuZHMuU0NSbWVzc2FnZXMiOyAvLyROT04tTkxTLTEkCi0JcHVibGljIHN0YXRpYyBTdHJpbmcgQUxMX0NPTVBPTkVOVFM7Ci0JcHVibGljIHN0YXRpYyBTdHJpbmcgQUxMX1JFRkVSRU5DRVNfUkVTT0xWRUQ7Ci0JcHVibGljIHN0YXRpYyBTdHJpbmcgQklORF9NRVRIT0RfTk9UX0ZPVU5EX09SX05PVF9BQ0NFU1NJQkxFOwotCXB1YmxpYyBzdGF0aWMgU3RyaW5nIFVQREFURURfTUVUSE9EX05PVF9GT1VORF9PUl9OT1RfQUNDRVNTSUJMRTsKLQlwdWJsaWMgc3RhdGljIFN0cmluZyBVUERBVEVEX01FVEhPRF9OT1RfQ0FMTEVEOwotCXB1YmxpYyBzdGF0aWMgU3RyaW5nIEJVTkRMRV9OT1RfRk9VTkQ7Ci0JcHVibGljIHN0YXRpYyBTdHJpbmcgQ0FOTk9UX0JVSUxEX0NPTVBPTkVOVDsKLQlwdWJsaWMgc3RhdGljIFN0cmluZyBDQU5OT1RfQ1JFQVRFX0lOU1RBTkNFOwotCXB1YmxpYyBzdGF0aWMgU3RyaW5nIENBTk5PVF9GSU5EX0NPTVBPTkVOVF9CVU5ETEU7Ci0JcHVibGljIHN0YXRpYyBTdHJpbmcgQ0FOTk9UX0dFVF9DT05GSUdVUkFUSU9OOwotCXB1YmxpYyBzdGF0aWMgU3RyaW5nIENBTk5PVF9HRVRfUkVGRVJFTkNFUzsKLQlwdWJsaWMgc3RhdGljIFN0cmluZyBDQU5OT1RfTU9ESUZZX0lOU1RBTkNFX19NT0RJRllfTUVUSE9EX05PVF9GT1VORDsKLQlwdWJsaWMgc3RhdGljIFN0cmluZyBDQU5UX0FDVElWQVRFX0lOU1RBTkNFOwotCXB1YmxpYyBzdGF0aWMgU3RyaW5nIENBTlRfR0VUX1NFUlZJQ0U7Ci0JcHVibGljIHN0YXRpYyBTdHJpbmcgQ0FOVF9HRVRfU0VSVklDRV9PQkpFQ1Q7Ci0JcHVibGljIHN0YXRpYyBTdHJpbmcgQ0FOVF9MSVNUX0NPTkZJR1VSQVRJT05TOwotCXB1YmxpYyBzdGF0aWMgU3RyaW5nIENBTlRfT1BFTl9TVFJFQU1fVE9fQ09NUE9ORU5UX1hNTDsKLQlwdWJsaWMgc3RhdGljIFN0cmluZyBDQU5UX1JFU09MVkVfQ09NUE9ORU5UX0lOU1RBTkNFOwotCXB1YmxpYyBzdGF0aWMgU3RyaW5nIENJUkNVTEFSSVRZX0VYQ0VQVElPTl9GT1VORDsKLQlwdWJsaWMgc3RhdGljIFN0cmluZyBDT01QT05FTlRfRElTUE9TRUQ7Ci0JcHVibGljIHN0YXRpYyBTdHJpbmcgQ09NUE9ORU5UX0NPTkZJR1VSQVRJT05TOwotCXB1YmxpYyBzdGF0aWMgU3RyaW5nIENPTVBPTkVOVF9ERVRBSUxTOwotCXB1YmxpYyBzdGF0aWMgU3RyaW5nIENPTVBPTkVOVF9IQVNfSUxMRUdBTF9SRUZFUkVOQ0U7Ci0JcHVibGljIHN0YXRpYyBTdHJpbmcgQ09NUE9ORU5UX0lEX0RFRklOSUVEX0JZX0xJU1RfQ09NTUFORDsKLQlwdWJsaWMgc3RhdGljIFN0cmluZyBDT01QT05FTlRfTEFDS1NfQVBQUk9QUklBVEVfUEVSTUlTU0lPTlM7Ci0JcHVibGljIHN0YXRpYyBTdHJpbmcgQ09NUE9ORU5UX05BTUU7Ci0JcHVibGljIHN0YXRpYyBTdHJpbmcgQ09NUE9ORU5UX05BTUVfSVNfTlVMTDsKLQlwdWJsaWMgc3RhdGljIFN0cmluZyBDT01QT05FTlRfTk9UX0ZPVU5EOwotCXB1YmxpYyBzdGF0aWMgU3RyaW5nIENPTVBPTkVOVF9OT1RfUkVTT0xWRUQ7Ci0JcHVibGljIHN0YXRpYyBTdHJpbmcgQ09NUE9ORU5UX1JFUVVSRVNfQ09ORklHVVJBVElPTl9BQ1RJVkFUSU9OOwotCXB1YmxpYyBzdGF0aWMgU3RyaW5nIENPTVBPTkVOVF9SRVNPTFZFRDsKLQlwdWJsaWMgc3RhdGljIFN0cmluZyBDT01QT05FTlRfV0FTX05PVF9CVUlMVDsKLQlwdWJsaWMgc3RhdGljIFN0cmluZyBDT01QT05FTlRfWE1MX05PVF9GT1VORDsKLQlwdWJsaWMgc3RhdGljIFN0cmluZyBDT01QT05FTlRTX0lOX0JVTkRMRTsKLQlwdWJsaWMgc3RhdGljIFN0cmluZyBDT05GSUdfQURNSU5fU0VSVklDRV9OT1RfQVZBSUxBQkxFOwotCXB1YmxpYyBzdGF0aWMgU3RyaW5nIENPTkZJR19QUk9QRVJUSUVTOwotCXB1YmxpYyBzdGF0aWMgU3RyaW5nIENPVUxEX05PVF9DUkVBVEVfSU5TVEFOQ0U7Ci0JcHVibGljIHN0YXRpYyBTdHJpbmcgQ09VTERfTk9UX0NSRUFURV9ORVdfSU5TVEFOQ0U7Ci0JcHVibGljIHN0YXRpYyBTdHJpbmcgRElTQUJMRV9BTExfQ09NUE9ORU5UUzsKLQlwdWJsaWMgc3RhdGljIFN0cmluZyBESVNBQkxFX0NPTVBPTkVOVDsKLQlwdWJsaWMgc3RhdGljIFN0cmluZyBESVNBQkxJTkdfQUxMX0JVTkRMRV9DT01QT05FTlRTOwotCXB1YmxpYyBzdGF0aWMgU3RyaW5nIERJU0FCTElOR19BTExfQ09NUE9ORU5UUzsKLQlwdWJsaWMgc3RhdGljIFN0cmluZyBEVVBMSUNBVEVEX1JFRkVSRU5DRV9OQU1FUzsKLQlwdWJsaWMgc3RhdGljIFN0cmluZyBEVVBMSUNBVEVEX1NFUlZJQ0VfVEFHUzsKLQlwdWJsaWMgc3RhdGljIFN0cmluZyBEWU5BTUlDX0lORk87Ci0JcHVibGljIHN0YXRpYyBTdHJpbmcgRU5BQkxFX0FMTF9DT01QT05FTlRTOwotCXB1YmxpYyBzdGF0aWMgU3RyaW5nIEVOQUJMRV9DT01QT05FTlQ7Ci0JcHVibGljIHN0YXRpYyBTdHJpbmcgRU5BQkxJTkdfQUxMX0JVTkRMRV9DT01QT05FTlRTOwotCXB1YmxpYyBzdGF0aWMgU3RyaW5nIEVOQUJMSU5HX0FMTF9DT01QT05FTlRTOwotCXB1YmxpYyBzdGF0aWMgU3RyaW5nIEVSUk9SX0JJTkRJTkdfUkVGRVJFTkNFOwotCXB1YmxpYyBzdGF0aWMgU3RyaW5nIEVSUk9SX1VQREFUSU5HX1JFRkVSRU5DRTsKLQlwdWJsaWMgc3RhdGljIFN0cmluZyBFUlJPUl9CVUlMRElOR19DT01QT05FTlRfSU5TVEFOQ0U7Ci0JcHVibGljIHN0YXRpYyBTdHJpbmcgRVJST1JfQ1JFQVRJTkdfU0NQOwotCXB1YmxpYyBzdGF0aWMgU3RyaW5nIEVSUk9SX0RFQUNUSVZBVElOR19JTlNUQU5DRTsKLQlwdWJsaWMgc3RhdGljIFN0cmluZyBFUlJPUl9ESVNQQVRDSElOR19XT1JLOwotCXB1YmxpYyBzdGF0aWMgU3RyaW5nIEVSUk9SX0RJU1BPU0lOR19JTlNUQU5DRVM7Ci0JcHVibGljIHN0YXRpYyBTdHJpbmcgRVJST1JfTElTVElOR19DT05GSUdVUkFUSU9OUzsKLQlwdWJsaWMgc3RhdGljIFN0cmluZyBFUlJPUl9MT0FESU5HX0NPTVBPTkVOVFM7Ci0JcHVibGljIHN0YXRpYyBTdHJpbmcgRVJST1JfTE9BRElOR19EQVRBX0ZJTEU7Ci0JcHVibGljIHN0YXRpYyBTdHJpbmcgRVJST1JfTE9BRElOR19QUk9QRVJUSUVTX0ZJTEU7Ci0JcHVibGljIHN0YXRpYyBTdHJpbmcgRVJST1JfT1BFTklOR19DT01QX1hNTDsKLQlwdWJsaWMgc3RhdGljIFN0cmluZyBFUlJPUl9QQVJTSU5HX01BTklGRVNUX0hFQURFUjsKLQlwdWJsaWMgc3RhdGljIFN0cmluZyBFUlJPUl9QUk9DRVNTSU5HX0NPTkZJR1VSQVRJT047Ci0JcHVibGljIHN0YXRpYyBTdHJpbmcgRVJST1JfUFJPQ0VTU0lOR19FTkRfVEFHOwotCXB1YmxpYyBzdGF0aWMgU3RyaW5nIEVSUk9SX1BST0NFU1NJTkdfUFJPUEVSVFk7Ci0JcHVibGljIHN0YXRpYyBTdHJpbmcgRVJST1JfUFJPQ0VTU0lOR19TVEFSVF9UQUc7Ci0JcHVibGljIHN0YXRpYyBTdHJpbmcgRVJST1JfVU5CSU5ESU5HX1JFRkVSRU5DRTsKLQlwdWJsaWMgc3RhdGljIFN0cmluZyBFUlJPUl9VTkJJTkRJTkdfUkVGRVJFTkNFMjsKLQlwdWJsaWMgc3RhdGljIFN0cmluZyBFWENFUFRJT05fQUNUSVZBVElOR19JTlNUQU5DRTsKLQlwdWJsaWMgc3RhdGljIFN0cmluZyBFWENFUFRJT05fQlVJTERJTkdfQ09NUE9ORU5UOwotCXB1YmxpYyBzdGF0aWMgU3RyaW5nIEVYQ0VQVElPTl9DUkVBVElOR19DT01QT05FTlRfSU5TVEFOQ0U7Ci0JcHVibGljIHN0YXRpYyBTdHJpbmcgRVhDRVBUSU9OX0dFVFRJTkdfTUVUSE9EOwotCXB1YmxpYyBzdGF0aWMgU3RyaW5nIEVYQ0VQVElPTl9MT0NBVElOR19TRVJWSUNFOwotCXB1YmxpYyBzdGF0aWMgU3RyaW5nIEVYQ0VQVElPTl9MT0NBVElOR19TRVJWSUNFUzsKLQlwdWJsaWMgc3RhdGljIFN0cmluZyBFWENFUFRJT05fTU9ESUZZSU5HX0NPTVBPTkVOVDsKLQlwdWJsaWMgc3RhdGljIFN0cmluZyBFWENFUFRJT05fVU5CSU5ESU5HX1JFRkVSRU5DRTsKLQlwdWJsaWMgc3RhdGljIFN0cmluZyBFWFBFQ1RFRF9QQVJBTUVURVJfQ09NUE9ORU5UX0lEOwotCXB1YmxpYyBzdGF0aWMgU3RyaW5nIEZBQ1RPUllfQ09ORl9OT1RfQVBQTElDQUJMRV9GT1JfQ09NUE9ORU5UX0ZBQ1RPUlk7Ci0JcHVibGljIHN0YXRpYyBTdHJpbmcgRkFDVE9SWV9SRUdJU1RSQVRJT05fQUxSRUFEWV9ESVNQT1NFRDsKLQlwdWJsaWMgc3RhdGljIFN0cmluZyBGT1VORF9DT01QT05FTlRTX1dJVEhfRFVQTElDQVRFRF9OQU1FUzsKLQlwdWJsaWMgc3RhdGljIFN0cmluZyBGT1VORF9DT01QT05FTlRTX1dJVEhfRFVQTElDQVRFRF9OQU1FUzI7Ci0JcHVibGljIHN0YXRpYyBTdHJpbmcgSUxMRUdBTF9ERUZJTklUSU9OX0ZJTEU7Ci0JcHVibGljIHN0YXRpYyBTdHJpbmcgSUxMRUdBTF9FTEVNRU5UX0lOX1NFUlZJQ0VfVEFHOwotCXB1YmxpYyBzdGF0aWMgU3RyaW5nIElMTEVHQUxfVEFHX0ZPVU5EOwotCXB1YmxpYyBzdGF0aWMgU3RyaW5nIElOQ09NUEFUSUJMRV9DT01CSU5BVElPTjsKLQlwdWJsaWMgc3RhdGljIFN0cmluZyBJTkNPUlJFQ1RfQUNUSVZBVElPTl9QT0xJQ1k7Ci0JcHVibGljIHN0YXRpYyBTdHJpbmcgSU5DT1JSRUNUX1ZBTFVFX1RZUEU7Ci0JcHVibGljIHN0YXRpYyBTdHJpbmcgSU5TVEFOQ0VfQUxSRUFEWV9DUkVBVEVEOwotCXB1YmxpYyBzdGF0aWMgU3RyaW5nIElOU1RBTkNFX0NSRUFUSU9OX1RPT0tfTE9OR0VSOwotCXB1YmxpYyBzdGF0aWMgU3RyaW5nIElOU1RBTkNFX05PVF9CT1VORDsKLQlwdWJsaWMgc3RhdGljIFN0cmluZyBJTlZBTElEX0NBUkRJTkFMSVRZX0FUVFI7Ci0JcHVibGljIHN0YXRpYyBTdHJpbmcgSU5WQUxJRF9DT01QT05FTlRfRkFDVE9SWV9BTkRfU0VSVklDRV9GQUNUT1JZOwotCXB1YmxpYyBzdGF0aWMgU3RyaW5nIElOVkFMSURfQ09NUE9ORU5UX0lEOwotCXB1YmxpYyBzdGF0aWMgU3RyaW5nIElOVkFMSURfQ09NUE9ORU5UX0lNTUVESUFURV9BTkRfRkFDVE9SWTsKLQlwdWJsaWMgc3RhdGljIFN0cmluZyBJTlZBTElEX0NPTVBPTkVOVF9JTU1FRElBVEVfQU5EX1NFUlZJQ0VfRkFDVE9SWTsKLQlwdWJsaWMgc3RhdGljIFN0cmluZyBJTlZBTElEX0NPTVBPTkVOVF9OT19TRVJWSUNFU19OT19JTU1FRElBVEU7Ci0JcHVibGljIHN0YXRpYyBTdHJpbmcgSU5WQUxJRF9DT01QT05FTlRfVEFHX19NVUxUSVBMRV9JTVBMX0FUVFJJQlM7Ci0JcHVibGljIHN0YXRpYyBTdHJpbmcgSU5WQUxJRF9DT01QT05FTlRfVEFHX19OT19DTEFTU19BVFRSOwotCXB1YmxpYyBzdGF0aWMgU3RyaW5nIElOVkFMSURfT0JKRUNUOwotCXB1YmxpYyBzdGF0aWMgU3RyaW5nIElOVkFMSURfUE9MSUNZX0FUVFI7Ci0JcHVibGljIHN0YXRpYyBTdHJpbmcgSU5WQUxJRF9QT0xJQ1lfT1BUSU9OX0FUVFI7Ci0JcHVibGljIHN0YXRpYyBTdHJpbmcgSU5WQUxJRF9QUk9QRVJUSUVTX1RBR19fSU5WQUxJRF9FTlRSWV9WQUxVRTsKLQlwdWJsaWMgc3RhdGljIFN0cmluZyBJTlZBTElEX1BST1BFUlRJRVNfVEFHX19OT19FTlRSWV9BVFRSOwotCXB1YmxpYyBzdGF0aWMgU3RyaW5nIElOVkFMSURfUFJPUEVSVFlfVEFHX19OT19CT0RZX0NPTlRFTlQ7Ci0JcHVibGljIHN0YXRpYyBTdHJpbmcgSU5WQUxJRF9QUk9QRVJUWV9UQUdfX05PX05BTUVfQVRUUjsKLQlwdWJsaWMgc3RhdGljIFN0cmluZyBJTlZBTElEX1BST1BFUlRZX1RZUEU7Ci0JcHVibGljIHN0YXRpYyBTdHJpbmcgSU5WQUxJRF9QUk9WSURFX1RBR19fTk9fSU5URVJGQUNFX0FUVFI7Ci0JcHVibGljIHN0YXRpYyBTdHJpbmcgSU5WQUxJRF9SRUZFUkVOQ0VfVEFHX19CSU5EX0FUVFJfRU1QVFk7Ci0JcHVibGljIHN0YXRpYyBTdHJpbmcgSU5WQUxJRF9SRUZFUkVOQ0VfVEFHX19CSU5EX0VRVUFMU19VTkJJTkQ7Ci0JcHVibGljIHN0YXRpYyBTdHJpbmcgSU5WQUxJRF9SRUZFUkVOQ0VfVEFHX19VTkJJTkRfQVRUUl9FTVBUWTsKLQlwdWJsaWMgc3RhdGljIFN0cmluZyBJTlZBTElEX1JFRkVSRU5DRV9UQUdfX1VQREFURURfQVRUUl9FTVBUWTsKLQlwdWJsaWMgc3RhdGljIFN0cmluZyBJTlZBTElEX1NFUlZJQ0VfUkVGRVJFTkNFOwotCXB1YmxpYyBzdGF0aWMgU3RyaW5nIElOVkFMSURfU0VSVklDRV9UQUdfX05PX1BST1ZJREVfVEFHOwotCXB1YmxpYyBzdGF0aWMgU3RyaW5nIElOVkFMSURfVEFHX0FDQ09SRElOR19UT19OQU1FU1BBQ0UxXzA7Ci0JcHVibGljIHN0YXRpYyBTdHJpbmcgSU5WQUxJRF9UQUdfQUNDT1JESU5HX1RPX05BTUVTUEFDRTFfMjsKLQlwdWJsaWMgc3RhdGljIFN0cmluZyBJTlZBTElEX1RBUkdFVF9GSUxURVI7Ci0JcHVibGljIHN0YXRpYyBTdHJpbmcgTElTVF9BTExfQlVORExFX0NPTVBPTkVOVFM7Ci0JcHVibGljIHN0YXRpYyBTdHJpbmcgTElTVF9BTExfQ09NUE9ORU5UUzsKLQlwdWJsaWMgc3RhdGljIFN0cmluZyBMT0NBVEVEX0lOX0JVTkRMRTsKLQlwdWJsaWMgc3RhdGljIFN0cmluZyBNRVRIT0RfVU5BQ0NFU1NBQkxFOwotCXB1YmxpYyBzdGF0aWMgU3RyaW5nIE1JU1NJTkdfQ0hBUkFDVEVSOwotCXB1YmxpYyBzdGF0aWMgU3RyaW5nIE5PX0JVSUxUX0NPTVBPTkVOVF9DT05GSUdVUkFUSU9OUzsKLQlwdWJsaWMgc3RhdGljIFN0cmluZyBOT19DT01QT05FTlRTX0ZPVU5EOwotCXB1YmxpYyBzdGF0aWMgU3RyaW5nIE5PX0lNUExFTUVOVEFUSU9OX0FUVFJJQlVURTsKLQlwdWJsaWMgc3RhdGljIFN0cmluZyBOT19JTlRFUkZBQ0VfQVRUUl9JTl9SRUZFUkVOQ0VfVEFHOwotCXB1YmxpYyBzdGF0aWMgU3RyaW5nIE5PX05BTUVfQVRUUklCVVRFOwotCXB1YmxpYyBzdGF0aWMgU3RyaW5nIE5PVF9SRVNPTFZFRF9SRUZFUkVOQ0VTOwotCXB1YmxpYyBzdGF0aWMgU3RyaW5nIFBSSU5UX0NPTVBPTkVOVF9JTkZPOwotCXB1YmxpYyBzdGF0aWMgU3RyaW5nIFBST0NFU1NJTkdfQlVORExFX0ZBSUxFRDsKLQlwdWJsaWMgc3RhdGljIFN0cmluZyBSRUdJU1RFUkVEX0FTX0NPTVBPTkVOVF9BTkRfTUFOQUdFRF9TRVJWSUNFX0ZBQ09SWTsKLQlwdWJsaWMgc3RhdGljIFN0cmluZyBSRUdJU1RSQVRJT05fQUxSRUFEWV9ESVNQT1NFRDsKLQlwdWJsaWMgc3RhdGljIFN0cmluZyBSRVRVUk5JTkdfTk9UX0ZVTExZX0FDVElWQVRFRF9JTlNUQU5DRTsKLQlwdWJsaWMgc3RhdGljIFN0cmluZyBTQ1I7Ci0JcHVibGljIHN0YXRpYyBTdHJpbmcgU0VOVF9ESVNBQkxJTkdfUkVRVUVTVDsKLQlwdWJsaWMgc3RhdGljIFN0cmluZyBTRU5UX0VOQUJMSU5HX1JFUVVFU1Q7Ci0JcHVibGljIHN0YXRpYyBTdHJpbmcgU0VSVklDRV9SRUZFUkVOQ0VfQUxSRUFEWV9CT1VORDsKLQlwdWJsaWMgc3RhdGljIFN0cmluZyBTRVJWSUNFX1VTQUdFX0NPVU5UOwotCXB1YmxpYyBzdGF0aWMgU3RyaW5nIFNQRUNJRklFRF9BQ1RJVkFURV9NRVRIT0RfTk9UX0ZPVU5EOwotCXB1YmxpYyBzdGF0aWMgU3RyaW5nIFNQRUNJRklFRF9ERUFDVElWQVRFX01FVEhPRF9OT1RfRk9VTkQ7Ci0JcHVibGljIHN0YXRpYyBTdHJpbmcgU1RBVEU7Ci0JcHVibGljIHN0YXRpYyBTdHJpbmcgU1RBVElDX09QVElPTkFMX1JFRkVSRU5DRV9UT19CRV9SRU1PVkVEOwotCXB1YmxpYyBzdGF0aWMgU3RyaW5nIFRJTUVPVVRfR0VUVElOR19MT0NLOwotCXB1YmxpYyBzdGF0aWMgU3RyaW5nIFRJTUVPVVRfUFJPQ0VTU0lORzsKLQlwdWJsaWMgc3RhdGljIFN0cmluZyBUSU1FT1VUX1JFQUNIRURfRU5BQkxJTkdfQ09NUE9ORU5UUzsKLQlwdWJsaWMgc3RhdGljIFN0cmluZyBVTkVYUEVDVEVEX0VSUk9SOwotCXB1YmxpYyBzdGF0aWMgU3RyaW5nIFVORVhQRUNURURfRVhDRVBUSU9OOwotCXB1YmxpYyBzdGF0aWMgU3RyaW5nIFVOU1VQUE9SVEVEX1RZUEU7Ci0JcHVibGljIHN0YXRpYyBTdHJpbmcgV1JPTkdfUEFSQU1FVEVSOwotCXB1YmxpYyBzdGF0aWMgU3RyaW5nIFdST05HX1BBUkFNRVRFUjI7Ci0JcHVibGljIHN0YXRpYyBTdHJpbmcgRVJST1JfREVMRVRJTkdfQ09NUE9ORU5UX0RFRklOSVRJT05TOwotCXB1YmxpYyBzdGF0aWMgU3RyaW5nIEVSUk9SX1dSSVRJTkdfT0JKRUNUOwotCXB1YmxpYyBzdGF0aWMgU3RyaW5nIEVSUk9SX1JFQURJTkdfT0JKRUNUOwotCXB1YmxpYyBzdGF0aWMgU3RyaW5nIERCTUFOQUdFUl9TRVJWSUNFX1RSQUNLRVJfT1BFTkVEOwotCXB1YmxpYyBzdGF0aWMgU3RyaW5nIEVSUk9SX0xPQURJTkdfQ09NUE9ORU5UX0RFRklOSVRJT05TOwotCXB1YmxpYyBzdGF0aWMgU3RyaW5nIEVSUk9SX01PRElGWUlOR19DT01QT05FTlQ7Ci0JcHVibGljIHN0YXRpYyBTdHJpbmcgRVJST1JfU0FWSU5HX0NPTVBPTkVOVF9ERUZJTklUSU9OUzsKLQlwdWJsaWMgc3RhdGljIFN0cmluZyBGSUxFX0RPRVNOVF9FWElTVF9PUl9ESVJFQ1RPUlk7Ci0Jc3RhdGljIHsKLQkJLy8gaW5pdGlhbGl6ZSByZXNvdXJjZSBidW5kbGUKLQkJTkxTLmluaXRpYWxpemVNZXNzYWdlcyhCVU5ETEVfTkFNRSwgTWVzc2FnZXMuY2xhc3MpOwotCX0KLQotCXByaXZhdGUgTWVzc2FnZXMoKSB7Ci0JCS8vCi0JfQotfQpkaWZmIC0tZ2l0IGEvYnVuZGxlcy9vcmcuZWNsaXBzZS5lcXVpbm94LmRzL3NyYy9vcmcvZWNsaXBzZS9lcXVpbm94L2ludGVybmFsL2RzL1JlZmVyZW5jZS5qYXZhIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5lcXVpbm94LmRzL3NyYy9vcmcvZWNsaXBzZS9lcXVpbm94L2ludGVybmFsL2RzL1JlZmVyZW5jZS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwZTYxNDgzLi4wMDAwMDAwCi0tLSBhL2J1bmRsZXMvb3JnLmVjbGlwc2UuZXF1aW5veC5kcy9zcmMvb3JnL2VjbGlwc2UvZXF1aW5veC9pbnRlcm5hbC9kcy9SZWZlcmVuY2UuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDQ5MyArMCwwIEBACi0vKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgotICogQ29weXJpZ2h0IChjKSAxOTk3LTIwMTAgYnkgUHJvU3lzdCBTb2Z0d2FyZSBHbWJICi0gKiBodHRwOi8vd3d3LnByb3N5c3QuY29tCi0gKiBBbGwgcmlnaHRzIHJlc2VydmVkLiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzCi0gKiBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYxLjAKLSAqIHdoaWNoIGFjY29tcGFuaWVzIHRoaXMgZGlzdHJpYnV0aW9uLCBhbmQgaXMgYXZhaWxhYmxlIGF0Ci0gKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC12MTAuaHRtbAotICoKLSAqIENvbnRyaWJ1dG9yczoKLSAqICAgIFByb1N5c3QgU29mdHdhcmUgR21iSCAtIGluaXRpYWwgQVBJIGFuZCBpbXBsZW1lbnRhdGlvbgotICogICAgSm9lcmctQ2hyaXN0aWFuIEJvZWhtZSAtIGJ1Zy5pZCA9IDI0Njc1NwotICogICAgQW5kcmV3IFRlaXJuZXkJCSAtIGJ1Zy5pZCA9IDI3ODczMgotICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi1wYWNrYWdlIG9yZy5lY2xpcHNlLmVxdWlub3guaW50ZXJuYWwuZHM7Ci0KLWltcG9ydCBqYXZhLnV0aWwuKjsKLWltcG9ydCBvcmcuZWNsaXBzZS5lcXVpbm94LmludGVybmFsLmRzLm1vZGVsLio7Ci1pbXBvcnQgb3JnLmVjbGlwc2Uub3NnaS51dGlsLk5MUzsKLWltcG9ydCBvcmcub3NnaS5mcmFtZXdvcmsuKjsKLWltcG9ydCBvcmcub3NnaS5zZXJ2aWNlLmNvbXBvbmVudC5Db21wb25lbnRDb25zdGFudHM7Ci1pbXBvcnQgb3JnLm9zZ2kuc2VydmljZS5sb2cuTG9nU2VydmljZTsKLQotLyoqCi0gKiBUaGUgcmVmZXJlbmNlIGNsYXNzIGlzIHVzZWQgb25seSBpbiB0aGUgcmVzb2x2ZXIuIEl0IGlzIGFjdHVhbGx5IGxpa2UKLSAqICJpbnN0YW5jZSBvZiBhIHJlZmVyZW5jZXMiLiBJdCBpcyB1c2VkIHRvIHRyYWNrIGF2YWlsYWJsZSwgZWxpZ2libGUKLSAqIHJlZmVyZW5jZXMuIFRoZSByZWZlcmVuY2Ugb2JqZWN0cyByZWxhdGVzIHRvIFNlcnZpY2VDb21wb25lbnRQcm9wIGFzIG1hbnkgdG8KLSAqIG9uZS4KLSAqIAotICogQGF1dGhvciBWYWxlbnRpbiBWYWxjaGV2Ci0gKiBAYXV0aG9yIFN0b3lhbiBCb3NoZXYKLSAqIEBhdXRob3IgUGF2bGluIERvYnJldgotICovCi1wdWJsaWMgZmluYWwgY2xhc3MgUmVmZXJlbmNlIGltcGxlbWVudHMgb3JnLmFwYWNoZS5mZWxpeC5zY3IuUmVmZXJlbmNlIHsKLQotCXB1YmxpYyBDb21wb25lbnRSZWZlcmVuY2UgcmVmZXJlbmNlOwotCVNlcnZpY2VDb21wb25lbnRQcm9wIHNjcDsKLQotCS8vIC0tIGJlZ2luIGNhY2hlCi0JU3RyaW5nIGludGVyZmFjZU5hbWU7Ci0JU3RyaW5nIHRhcmdldDsKLQlpbnQgcG9saWN5OwotCWludCBjYXJkaW5hbGl0eUhpZ2g7Ci0JaW50IGNhcmRpbmFsaXR5TG93OwotCi0JLy9ob2xkcyB0aGUgbWF0Y2hpbmcgc2VydmljZSByZWZlcmVuY2VzIGluIGNhc2UgdGhlIGNvbXBvbmVudCBoYXMgbm8gYmluZCBtZXRob2QKLQkvL2luIGNhc2UgdGhlIGNhcmRpbmFsaXR5IGlzIDEuLjEsIHRoZSB2ZWN0b3Igd2lsbCBob2xkIG9ubHkgb25lIG1hdGNoaW5nIFNlcnZpY2VSZWZlcmVuY2UKLQlWZWN0b3IgYm91bmRTZXJ2aWNlUmVmZXJlbmNlcyA9IG5ldyBWZWN0b3IoMSk7Ci0KLQkvLyAtLSBlbmQgY2FjaGUKLQotCS8qKgotCSAqIFJlZmVyZW5jZSBvYmplY3QKLQkgKiAKLQkgKiBAcGFyYW0gcmVmZXJlbmNlCi0JICogICAgICAgICAgICB0aGUgY29tcG9uZW50IHJlZmVyZW5jZQotCSAqIEBwYXJhbSBwcm9wZXJ0aWVzCi0JICogICAgICAgICAgICB0aGUgKmFjdHVhbCogcHJvcGVydGllcyB0aGF0IHRoZSBjb21wb25lbnQgaGFzLiBUaGVzZSBhcmUgdGhlCi0JICogICAgICAgICAgICBTQ1AgcHJvcGVydGllcywgZS5nIHRoZSBkZWZhdWx0IG9uZSBpbiB0aGUgWE1MIGZpbGUgKyB0aGUgb25lCi0JICogICAgICAgICAgICB0aGF0IGFyZSBjb25maWd1cmVkIGluIHRoZSBDTS4KLQkgKi8KLQlSZWZlcmVuY2UoQ29tcG9uZW50UmVmZXJlbmNlIHJlZmVyZW5jZSwgU2VydmljZUNvbXBvbmVudFByb3Agc2NwLCBEaWN0aW9uYXJ5IHByb3BlcnRpZXMpIHsKLQkJdGhpcy5yZWZlcmVuY2UgPSByZWZlcmVuY2U7Ci0JCXRoaXMuc2NwID0gc2NwOwotCQl0aGlzLmludGVyZmFjZU5hbWUgPSByZWZlcmVuY2UuaW50ZXJmYWNlTmFtZTsKLQkJdGhpcy50YXJnZXQgPSByZWZlcmVuY2UudGFyZ2V0OwotCi0JCS8vIFJGQyA4MCBzZWN0aW9uIDUuMy4xLjM6Ci0JCS8vIElmIFt0YXJnZXRdIGlzIG5vdCBzcGVjaWZpZWQgYW5kIHRoZXJlIGlzIG5vIDxyZWZlcmVuY2UtbmFtZT4udGFyZ2V0Ci0JCS8vIGNvbXBvbmVudAotCQkvLyBwcm9wZXJ0eSwgdGhlbiB0aGUgc2VsZWN0aW9uIGZpbHRlciB1c2VkIHRvIHNlbGVjdCB0aGUgZGVzaXJlZAotCQkvLyBzZXJ2aWNlIGlzCi0JCS8vIO+/vShvYmplY3RDbGFzcz3vv70rPGludGVyZmFjZS1uYW1lPivvv70p77+9LgotCQlpZiAocHJvcGVydGllcyAhPSBudWxsKSB7Ci0JCQl0YXJnZXQgPSAoU3RyaW5nKSBwcm9wZXJ0aWVzLmdldChyZWZlcmVuY2UubmFtZSArIENvbXBvbmVudENvbnN0YW50cy5SRUZFUkVOQ0VfVEFSR0VUX1NVRkZJWCk7Ci0JCX0KLQkJaWYgKHRhcmdldCA9PSBudWxsKSB7Ci0JCQl0YXJnZXQgPSAiKG9iamVjdENsYXNzPSIgKyBpbnRlcmZhY2VOYW1lICsgIikiOyAvLyROT04tTkxTLTEkIC8vJE5PTi1OTFMtMiQKLQkJfQotCi0JCS8vIElmIGl0IGlzIG5vdCBzcGVjaWZpZWQsIHRoZW4gYSBwb2xpY3kgb2Yg77+9c3RhdGlj77+9IGlzIHVzZWQuCi0JCXBvbGljeSA9IHJlZmVyZW5jZS5wb2xpY3k7Ci0KLQkJLy8gQ2FyZGluYWxpdHkgaW5kaWNhdGVzIHRoZSBudW1iZXIgb2Ygc2VydmljZXMsIG1hdGNoaW5nIHRoaXMKLQkJLy8gcmVmZXJlbmNlLAotCQkvLyB3aGljaCB3aWxsIGJpbmQgdG8gdGhpcyBTZXJ2aWNlIENvbXBvbmVudC4gUG9zc2libGUgdmFsdWVzIGFyZToKLQkJLy8gMC4uMSwgMC4ubiwgMS4uMSAoaS5lLiBleGFjdGx5IG9uZSksIDEuLm4gKGkuZS4gYXQgbGVhc3Qgb25lKS4KLQkJLy8gVGhpcyBhdHRyaWJ1dGUgaXMgb3B0aW9uYWwuIElmIGl0IGlzIG5vdCBzcGVjaWZpZWQsIHRoZW4gYQotCQkvLyBjYXJkaW5hbGl0eQotCQkvLyBvZiDvv70xLi4x77+9IGlzIHVzZWQuCi0JCXN3aXRjaCAocmVmZXJlbmNlLmNhcmRpbmFsaXR5KSB7Ci0JCQljYXNlIENvbXBvbmVudFJlZmVyZW5jZS5DQVJESU5BTElUWV8wXzEgOgotCQkJCWNhcmRpbmFsaXR5TG93ID0gMDsKLQkJCQljYXJkaW5hbGl0eUhpZ2ggPSAxOwotCQkJCWJyZWFrOwotCQkJY2FzZSBDb21wb25lbnRSZWZlcmVuY2UuQ0FSRElOQUxJVFlfMF9OIDoKLQkJCQljYXJkaW5hbGl0eUxvdyA9IDA7Ci0JCQkJY2FyZGluYWxpdHlIaWdoID0gSW50ZWdlci5NQVhfVkFMVUU7Ci0JCQkJYnJlYWs7Ci0JCQljYXNlIENvbXBvbmVudFJlZmVyZW5jZS5DQVJESU5BTElUWV8xXzEgOgotCQkJCWNhcmRpbmFsaXR5TG93ID0gMTsKLQkJCQljYXJkaW5hbGl0eUhpZ2ggPSAxOwotCQkJCWJyZWFrOwotCQkJY2FzZSBDb21wb25lbnRSZWZlcmVuY2UuQ0FSRElOQUxJVFlfMV9OIDoKLQkJCQljYXJkaW5hbGl0eUxvdyA9IDE7Ci0JCQkJY2FyZGluYWxpdHlIaWdoID0gSW50ZWdlci5NQVhfVkFMVUU7Ci0JCX0KLQotCX0KLQotCXB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0KCkgewotCQlyZXR1cm4gdGFyZ2V0OwotCX0KLQotCXB1YmxpYyB2b2lkIHNldFRhcmdldChTdHJpbmcgbmV3VGFyZ2V0KSB7Ci0JCXRhcmdldCA9IG5ld1RhcmdldDsKLQl9Ci0KLQkvLyB1c2VkIGluIFJlc29sdmVyLnJlc29sdmVFbGlnaWJsZSgpCi0JZmluYWwgYm9vbGVhbiBoYXNQcm92aWRlcnMoSGFzaHRhYmxlIHNlcnZpY2VSZWZlcmVuY2VUYWJsZSkgewotCQkvLyBjaGVjayB3aGV0aGVyIHRoZSBjb21wb25lbnQncyBidW5kbGUgaGFzIHNlcnZpY2UgR0VUIHBlcm1pc3Npb24KLQkJaWYgKFN5c3RlbS5nZXRTZWN1cml0eU1hbmFnZXIoKSAhPSBudWxsICYmICFzY3AuYmMuZ2V0QnVuZGxlKCkuaGFzUGVybWlzc2lvbihuZXcgU2VydmljZVBlcm1pc3Npb24oaW50ZXJmYWNlTmFtZSwgU2VydmljZVBlcm1pc3Npb24uR0VUKSkpIHsKLQkJCXJldHVybiBmYWxzZTsKLQkJfQotCQkvLyBHZXQgYWxsIHNlcnZpY2UgcmVmZXJlbmNlcyBmb3IgdGhpcyB0YXJnZXQgZmlsdGVyCi0JCXRyeSB7Ci0JCQlTZXJ2aWNlUmVmZXJlbmNlW10gc2VydmljZVJlZmVyZW5jZXMgPSBudWxsOwotCQkJc2VydmljZVJlZmVyZW5jZXMgPSBzY3AuYmMuZ2V0U2VydmljZVJlZmVyZW5jZXMoaW50ZXJmYWNlTmFtZSwgdGFyZ2V0KTsKLQkJCS8vIE9ubHkgcmV0dXJuIHRydWUgaWYgdGhlcmUgaXMgYSBzZXJ2aWNlIHB1Ymxpc2hlZCB0aGF0IHRoaXMgUmVmZXJlbmNlCi0JCQkvLyByZXByZXNlbnRzIGFuZCB3ZSBrbm93IGFib3V0IGl0IChpZiB3ZSBjYXJlIGFib3V0IGl0KQotCQkJaWYgKHNlcnZpY2VSZWZlcmVuY2VzICE9IG51bGwpIHsKLQkJCQlpZiAoc2VydmljZVJlZmVyZW5jZVRhYmxlID09IG51bGwpCi0JCQkJCXJldHVybiB0cnVlOwotCQkJCWZvciAoaW50IGkgPSAwOyBpIDwgc2VydmljZVJlZmVyZW5jZXMubGVuZ3RoOyBpKyspIHsKLQkJCQkJaWYgKHNlcnZpY2VSZWZlcmVuY2VUYWJsZS5jb250YWluc0tleShzZXJ2aWNlUmVmZXJlbmNlc1tpXSkpIHsKLQkJCQkJCXJldHVybiB0cnVlOwotCQkJCQl9Ci0JCQkJfQotCQkJfQotCQl9IGNhdGNoIChJbnZhbGlkU3ludGF4RXhjZXB0aW9uIGUpIHsKLQkJCUFjdGl2YXRvci5sb2cocmVmZXJlbmNlLmNvbXBvbmVudC5iYywgTG9nU2VydmljZS5MT0dfV0FSTklORywgIlJlZmVyZW5jZS5oYXNQcm92aWRlcnMoKTogIiArIE5MUy5iaW5kKE1lc3NhZ2VzLklOVkFMSURfVEFSR0VUX0ZJTFRFUiwgdGFyZ2V0KSwgZSk7IC8vJE5PTi1OTFMtMSQKLQkJfQotCQlyZXR1cm4gZmFsc2U7Ci0JfQotCi0JLy8gaWYgdGhlIGNhcmRpbmFsaXR5IGlzICIwLi4xIiBvciAiMC4ubiIgdGhlbiB0aGlzIHJlZmVybmNlIGlzIG5vdCByZXF1aXJlZAotCWZpbmFsIGJvb2xlYW4gaXNSZXF1aXJlZEZvcihTZXJ2aWNlQ29tcG9uZW50IGNkKSB7Ci0JCS8vIC8vIHdlIHdhbnQgdG8gcmUtcmVzb2x2ZSBpZiB0aGUgY29tcG9uZW50IGlzIHN0YXRpYyBhbmQgYWxyZWFkeQotCQkvLyBlbGlnaWJsZQotCQkvLyBpZiAocG9saWN5ID09IENvbXBvbmVudFJlZmVyZW5jZS5QT0xJQ1lfU1RBVElDICYmIGNkLmVsaWdpYmxlKSB7Ci0JCS8vIHJldHVybiB0cnVlOwotCQkvLyB9Ci0JCXJldHVybiBjYXJkaW5hbGl0eUxvdyA9PSAxOwotCX0KLQotCXB1YmxpYyBib29sZWFuIGlzUmVxdWlyZWQoKSB7Ci0JCXJldHVybiBjYXJkaW5hbGl0eUxvdyA9PSAxOwotCX0KLQotCXB1YmxpYyBib29sZWFuIGlzVW5hcnkoKSB7Ci0JCXJldHVybiBjYXJkaW5hbGl0eUhpZ2ggPT0gMTsKLQl9Ci0KLQkvLyB1c2VkIGluIFJlc29sdmVyLnNlbGVjdER5bmFtaWNCaW5kKCkKLQlmaW5hbCBib29sZWFuIGJpbmROZXdSZWZlcmVuY2UoU2VydmljZVJlZmVyZW5jZSByZWZlcmVuY2VUb0JpbmQsIGJvb2xlYW4gZHluYW1pY0JpbmQpIHsKLQkJaWYgKGR5bmFtaWNCaW5kKSB7Ci0JCQlpZiAocG9saWN5ID09IENvbXBvbmVudFJlZmVyZW5jZS5QT0xJQ1lfU1RBVElDKSB7Ci0JCQkJcmV0dXJuIGZhbHNlOwotCQkJfQotCQl9IGVsc2UgewotCQkJaWYgKHBvbGljeSA9PSBDb21wb25lbnRSZWZlcmVuY2UuUE9MSUNZX0RZTkFNSUMpIHsKLQkJCQlyZXR1cm4gZmFsc2U7Ci0JCQl9Ci0JCQlpZiAodGhpcy5yZWZlcmVuY2UucG9saWN5X29wdGlvbiA9PSBDb21wb25lbnRSZWZlcmVuY2UuUE9MSUNZX09QVElPTl9SRUxVQ1RBTlQpIHsKLQkJCQlyZXR1cm4gZmFsc2U7Ci0JCQl9Ci0JCX0KLQotCQlTdHJpbmdbXSBzZXJ2aWNlTmFtZXMgPSAoU3RyaW5nW10pIHJlZmVyZW5jZVRvQmluZC5nZXRQcm9wZXJ0eShDb25zdGFudHMuT0JKRUNUQ0xBU1MpOwotCQlib29sZWFuIGhhc05hbWUgPSBmYWxzZTsKLQkJZm9yIChpbnQgaSA9IDA7IGkgPCBzZXJ2aWNlTmFtZXMubGVuZ3RoOyBpKyspIHsKLQkJCWlmIChzZXJ2aWNlTmFtZXNbaV0uZXF1YWxzKGludGVyZmFjZU5hbWUpKSB7Ci0JCQkJaGFzTmFtZSA9IHRydWU7Ci0JCQkJYnJlYWs7Ci0JCQl9Ci0JCX0KLQkJaWYgKCFoYXNOYW1lKSB7Ci0JCQlyZXR1cm4gZmFsc2U7Ci0JCX0KLQotCQlpZiAodGhpcy5yZWZlcmVuY2UuYmluZCAhPSBudWxsKSB7Ci0JCQlpZiAodGhpcy5yZWZlcmVuY2Uuc2VydmljZVJlZmVyZW5jZXMuc2l6ZSgpID49IGNhcmRpbmFsaXR5SGlnaCkgewotCQkJCWlmICh0aGlzLnJlZmVyZW5jZS5wb2xpY3lfb3B0aW9uID09IENvbXBvbmVudFJlZmVyZW5jZS5QT0xJQ1lfT1BUSU9OX1JFTFVDVEFOVCkgewotCQkJCQlyZXR1cm4gZmFsc2U7Ci0JCQkJfSBlbHNlIGlmICh0aGlzLnJlZmVyZW5jZS5wb2xpY3lfb3B0aW9uID09IENvbXBvbmVudFJlZmVyZW5jZS5QT0xJQ1lfT1BUSU9OX0dSRUVEWSkgewotCQkJCQkvL2NoZWNrIGlmIHRoZSBzaW5nbGUgYm91bmQgc2VydmljZSBuZWVkcyByZXBsYWNlbWVudCB3aXRoIGhpZ2hlciByYW5rZWQgc2VydmljZQotCQkJCQlPYmplY3QgY3VycmVudEJvdW5kU2VydmljZVJlZmVyZW5jZSA9IHRoaXMucmVmZXJlbmNlLnNlcnZpY2VSZWZlcmVuY2VzLmtleXMoKS5uZXh0RWxlbWVudCgpOwotCQkJCQlpbnQgcmVzID0gcmVmZXJlbmNlVG9CaW5kLmNvbXBhcmVUbyhjdXJyZW50Qm91bmRTZXJ2aWNlUmVmZXJlbmNlKTsKLQkJCQkJaWYgKHJlcyA8PSAwKSB7Ci0JCQkJCQkvLyBib3VuZCBzZXJ2aWNlIHNoYWxsIG5vdCBiZSByZXBsYWNlZAotCQkJCQkJcmV0dXJuIGZhbHNlOwotCQkJCQl9Ci0JCQkJfQotCQkJfQotCQl9IGVsc2UgaWYgKCFkeW5hbWljQmluZCkgewotCQkJLy9jdXN0b20gY2FzZTogc3RhdGljIHJlZmVyZW5jZSB3aXRoIG5vIGJpbmQgbWV0aG9kIC0gY2hlY2sgaXRzIGJvdW5kIHNlcnZpY2UgcmVmZXJlbmNlcyBsaXN0Ci0JCQlpZiAoYm91bmRTZXJ2aWNlUmVmZXJlbmNlcy5zaXplKCkgPj0gY2FyZGluYWxpdHlIaWdoKSB7Ci0JCQkJaWYgKHRoaXMucmVmZXJlbmNlLnBvbGljeV9vcHRpb24gPT0gQ29tcG9uZW50UmVmZXJlbmNlLlBPTElDWV9PUFRJT05fR1JFRURZKSB7Ci0JCQkJCS8vY2hlY2sgaWYgdGhlIHNpbmdsZSBib3VuZCBzZXJ2aWNlIG5lZWRzIHJlcGxhY2VtZW50IHdpdGggaGlnaGVyIHJhbmtlZCBzZXJ2aWNlCi0JCQkJCU9iamVjdCBjdXJyZW50Qm91bmRTZXJ2aWNlUmVmZXJlbmNlID0gYm91bmRTZXJ2aWNlUmVmZXJlbmNlcy5lbGVtZW50QXQoMCk7Ci0JCQkJCWludCByZXMgPSByZWZlcmVuY2VUb0JpbmQuY29tcGFyZVRvKGN1cnJlbnRCb3VuZFNlcnZpY2VSZWZlcmVuY2UpOwotCQkJCQlpZiAocmVzIDw9IDApIHsKLQkJCQkJCS8vIGJvdW5kIHNlcnZpY2Ugc2hhbGwgbm90IGJlIHJlcGxhY2VkCi0JCQkJCQlyZXR1cm4gZmFsc2U7Ci0JCQkJCX0KLQkJCQl9Ci0JCQl9Ci0JCX0KLQotCQkvLyBjaGVjayB0YXJnZXQgZmlsdGVyCi0JCXRyeSB7Ci0JCQlGaWx0ZXIgZmlsdGVyID0gRnJhbWV3b3JrVXRpbC5jcmVhdGVGaWx0ZXIodGFyZ2V0KTsKLQkJCWlmICghZmlsdGVyLm1hdGNoKHJlZmVyZW5jZVRvQmluZCkpIHsKLQkJCQlyZXR1cm4gZmFsc2U7Ci0JCQl9Ci0JCX0gY2F0Y2ggKEludmFsaWRTeW50YXhFeGNlcHRpb24gZSkgewotCQkJcmV0dXJuIGZhbHNlOwotCQl9Ci0JCXJldHVybiB0cnVlOwotCX0KLQotCS8qKgotCSAqIENhbGxlZCB0byBkZXRlcm1pbmUgaWYgdGhlIHNwZWNpZmllZCBuZXcgdGFyZ2V0IGZpbHRlciB3aWxsIHN0aWxsIHNhdGlzZnkgdGhlIGN1cnJlbnQgc3RhdGUgb2YgdGhlIHJlZmVyZW5jZSAKLQkgKiBAcGFyYW0gbmV3VGFyZ2V0RmlsdGVyIHRoZSBuZXcgdGFyZ2V0IGZpbHRlciB0byBiZSBjaGVja2VkCi0JICogQHJldHVybiB0cnVlIGlmIHRoZSByZWZlcmVuY2Ugd2lsbCBzdGlsbCBiZSBzYXRpc2ZpZWQgYWZ0ZXIgdGhlIGZpbHRlciByZXBsYWNlbWVudAotCSAqLwotCXB1YmxpYyBib29sZWFuIGRvU2F0aXNmeShTdHJpbmcgbmV3VGFyZ2V0RmlsdGVyKSB7Ci0JCVNlcnZpY2VSZWZlcmVuY2VbXSByZWZzID0gbnVsbDsKLQkJdHJ5IHsKLQkJCXJlZnMgPSBzY3AuYmMuZ2V0U2VydmljZVJlZmVyZW5jZXMocmVmZXJlbmNlLmludGVyZmFjZU5hbWUsIG5ld1RhcmdldEZpbHRlcik7Ci0JCX0gY2F0Y2ggKEludmFsaWRTeW50YXhFeGNlcHRpb24gZSkgewotCQkJQWN0aXZhdG9yLmxvZyhzY3AuYmMsIExvZ1NlcnZpY2UuTE9HX1dBUk5JTkcsICJbU0NSXSAiICsgTkxTLmJpbmQoTWVzc2FnZXMuSU5WQUxJRF9UQVJHRVRfRklMVEVSLCBuZXdUYXJnZXRGaWx0ZXIpLCBlKTsgLy8kTk9OLU5MUy0xJAotCQkJcmV0dXJuIGZhbHNlOwotCQl9Ci0KLQkJaWYgKHJlZnMgPT0gbnVsbCkgewotCQkJaWYgKGNhcmRpbmFsaXR5TG93ID4gMCkgewotCQkJCS8vdGhlIHJlZmVyZW5jZSBpcyBtYW5kYXRvcnksIGJ1dCB0aGVyZSBhcmUgbm8gbWF0Y2hpbmcgc2VydmljZXMgd2l0aCB0aGUgbmV3IHRhcmdldCBmaWx0ZXIKLQkJCQlyZXR1cm4gZmFsc2U7Ci0JCQl9Ci0JCQlpZiAocG9saWN5ID09IENvbXBvbmVudFJlZmVyZW5jZS5QT0xJQ1lfU1RBVElDKSB7Ci0JCQkJaWYgKHRoaXMucmVmZXJlbmNlLmJpbmQgIT0gbnVsbCkgewotCQkJCQlpZiAodGhpcy5yZWZlcmVuY2Uuc2VydmljZVJlZmVyZW5jZXMuc2l6ZSgpID4gMCkgewotCQkJCQkJLy9oYXZlIGJvdW5kIHNlcnZpY2VzIHdoaWNoIGFyZSBub3QgbWF0Y2hpbmcgdGhlIG5ldyBmaWx0ZXIgCi0JCQkJCQlyZXR1cm4gZmFsc2U7Ci0JCQkJCX0KLQkJCQl9IGVsc2UgewotCQkJCQkvL2N1c3RvbSBjYXNlOiBzdGF0aWMgcmVmZXJlbmNlIHdpdGggbm8gYmluZCBtZXRob2QgLSBjaGVjayBpdHMgYm91bmQgc2VydmljZSByZWZlcmVuY2VzIGxpc3QKLQkJCQkJaWYgKGJvdW5kU2VydmljZVJlZmVyZW5jZXMuc2l6ZSgpID4gMCkgewotCQkJCQkJLy9oYXZlIGJvdW5kIHNlcnZpY2VzIHdoaWNoIGFyZSBub3QgbWF0Y2hpbmcgdGhlIG5ldyBmaWx0ZXIgCi0JCQkJCQlyZXR1cm4gZmFsc2U7Ci0JCQkJCX0KLQkJCQl9Ci0JCQl9Ci0JCQkvL3RoZSByZWZlcmVuY2UgaXMgbm90IG1hbmRhdG9yeSBhbmQgdGhlIGR5bmFtaWMgYm91bmQgc2VydmljZXMgY2FuIGJlIHVuYm91bmQKLQkJCXJldHVybiB0cnVlOwotCQl9Ci0JCWlmIChwb2xpY3kgPT0gQ29tcG9uZW50UmVmZXJlbmNlLlBPTElDWV9TVEFUSUMpIHsKLQkJCWlmICh0aGlzLnJlZmVyZW5jZS5iaW5kICE9IG51bGwpIHsKLQkJCQlFbnVtZXJhdGlvbiBrZXlzID0gdGhpcy5yZWZlcmVuY2Uuc2VydmljZVJlZmVyZW5jZXMua2V5cygpOwotCQkJCXdoaWxlIChrZXlzLmhhc01vcmVFbGVtZW50cygpKSB7Ci0JCQkJCU9iamVjdCBzZXJ2aWNlUmVmID0ga2V5cy5uZXh0RWxlbWVudCgpOwotCQkJCQlib29sZWFuIGZvdW5kID0gZmFsc2U7Ci0JCQkJCWZvciAoaW50IGkgPSAwOyBpIDwgcmVmcy5sZW5ndGg7IGkrKykgewotCQkJCQkJaWYgKHJlZnNbaV0gPT0gc2VydmljZVJlZikgewotCQkJCQkJCWZvdW5kID0gdHJ1ZTsKLQkJCQkJCQlicmVhazsKLQkJCQkJCX0KLQkJCQkJfQotCQkJCQlpZiAoIWZvdW5kKSB7Ci0JCQkJCQkvL3RoZSBib3VuZCBzZXJ2aWNlIHJlZmVyZW5jZSBpcyBub3QgYWxyZWFkeSBpbiB0aGUgc2F0aXNmaWVkIHJlZmVyZW5jZXMgc2V0LiAKLQkJCQkJCS8vc2luY2UgdGhpcyBpcyBhIHN0YXRpYyByZWZlcmVuY2UgYSByZXN0YXJ0IG9mIHRoZSBjb21wb25lbnQgaXMgcmVxdWlyZWQKLQkJCQkJCXJldHVybiBmYWxzZTsKLQkJCQkJfQotCQkJCX0KLQkJCQlpZiAoY2FyZGluYWxpdHlIaWdoID4gMSAmJiB0aGlzLnJlZmVyZW5jZS5zZXJ2aWNlUmVmZXJlbmNlcy5zaXplKCkgPCByZWZzLmxlbmd0aCkgewotCQkJCQkvL3RoZXJlIGFyZSBtb3JlIHNlcnZpY2VzIHRvIGJpbmQuIHRoaXMgcmVxdWlyZXMgcmVzdGFydCBvZiB0aGUgY29tcG9uZW50IHNpbmNlIHRoZSByZWZlcmVuY2UgaXMgc3RhdGljCi0JCQkJCXJldHVybiBmYWxzZTsKLQkJCQl9Ci0JCQl9IGVsc2UgewotCQkJCS8vY3VzdG9tIGNhc2U6IHN0YXRpYyByZWZlcmVuY2Ugd2l0aCBubyBiaW5kIG1ldGhvZAotCQkJCWZvciAoaW50IGkgPSAwOyBpIDwgYm91bmRTZXJ2aWNlUmVmZXJlbmNlcy5zaXplKCk7IGkrKykgewotCQkJCQlPYmplY3Qgc2VydmljZVJlZiA9IGJvdW5kU2VydmljZVJlZmVyZW5jZXMuZWxlbWVudEF0KGkpOwotCQkJCQlib29sZWFuIGZvdW5kID0gZmFsc2U7Ci0JCQkJCWZvciAoaW50IGogPSAwOyBqIDwgcmVmcy5sZW5ndGg7IGorKykgewotCQkJCQkJaWYgKHJlZnNbal0gPT0gc2VydmljZVJlZikgewotCQkJCQkJCWZvdW5kID0gdHJ1ZTsKLQkJCQkJCQlicmVhazsKLQkJCQkJCX0KLQkJCQkJfQotCQkJCQlpZiAoIWZvdW5kKSB7Ci0JCQkJCQkvL3RoZSBib3VuZCBzZXJ2aWNlIHJlZmVyZW5jZSBpcyBub3QgYWxyZWFkeSBpbiB0aGUgc2F0aXNmaWVkIHJlZmVyZW5jZXMgc2V0LiAKLQkJCQkJCS8vc2luY2UgdGhpcyBpcyBhIHN0YXRpYyByZWZlcmVuY2UgYSByZXN0YXJ0IG9mIHRoZSBjb21wb25lbnQgaXMgcmVxdWlyZWQKLQkJCQkJCXJldHVybiBmYWxzZTsKLQkJCQkJfQotCQkJCX0KLQkJCQlpZiAoY2FyZGluYWxpdHlIaWdoID4gMSAmJiBib3VuZFNlcnZpY2VSZWZlcmVuY2VzLnNpemUoKSA8IHJlZnMubGVuZ3RoKSB7Ci0JCQkJCS8vdGhlcmUgYXJlIG1vcmUgc2VydmljZXMgdG8gYmluZC4gdGhpcyByZXF1aXJlcyByZXN0YXJ0IG9mIHRoZSBjb21wb25lbnQgc2luY2UgdGhlIHJlZmVyZW5jZSBpcyBzdGF0aWMKLQkJCQkJcmV0dXJuIGZhbHNlOwotCQkJCX0KLQotCQkJfQotCQl9Ci0JCXJldHVybiB0cnVlOwotCX0KLQotCS8vIHVzZWQgaW4gUmVzb2x2ZXIuc2VsZWN0RHluYW1pY1VuQmluZCgpOwotCWZpbmFsIGJvb2xlYW4gZHluYW1pY1VuYmluZFJlZmVyZW5jZShTZXJ2aWNlUmVmZXJlbmNlIGNoYW5nZWRSZWZlcmVuY2UpIHsKLQkJLy8gbm90aGluZyBkeW5hbWljIHRvIGRvIGlmIHN0YXRpYwotCQlpZiAocG9saWN5ID09IENvbXBvbmVudFJlZmVyZW5jZS5QT0xJQ1lfU1RBVElDKSB7Ci0JCQlyZXR1cm4gZmFsc2U7Ci0JCX0KLQkJLy8gbm93IGNoZWNrIGlmIHRoZSBTZXJ2aWNlIFJlZmVyZW5jZSBpcyBmb3VuZCBpbiB0aGUgbGlzdCBvZiBzYXZlZAotCQkvLyBTZXJ2aWNlUmVmZXJlbmNlcwotCQlpZiAoIXRoaXMucmVmZXJlbmNlLnNlcnZpY2VSZWZlcmVuY2VzLmNvbnRhaW5zS2V5KGNoYW5nZWRSZWZlcmVuY2UpKSB7Ci0JCQlyZXR1cm4gZmFsc2U7Ci0JCX0KLQkJcmV0dXJuIHRydWU7Ci0JfQotCi0JZmluYWwgYm9vbGVhbiBzdGF0aWNVbmJpbmRSZWZlcmVuY2UoU2VydmljZVJlZmVyZW5jZSBjaGFuZ2VkUmVmZXJlbmNlKSB7Ci0JCS8vIGRvZXMgbm90IGFwcGx5IGlmIGl0cyBwb2xpY3kgaXMgZHluYW1pYwotCQlpZiAocG9saWN5ID09IENvbXBvbmVudFJlZmVyZW5jZS5QT0xJQ1lfRFlOQU1JQykgewotCQkJcmV0dXJuIGZhbHNlOwotCQl9Ci0JCS8vIG5vdyBjaGVjayBpZiB0aGUgU2VydmljZSBSZWZlcmVuY2UgaXMgZm91bmQgaW4gdGhlIGxpc3Qgb2Ygc2F2ZWQKLQkJLy8gU2VydmljZVJlZmVyZW5jZXM7IHRoaXMgbGlzdCBpcyBzYXZlZCBpbiBjYXNlIHRoZSBjb21wb25lbnQgaGFzIGEgYmluZCBtZXRob2QKLQkJaWYgKHRoaXMucmVmZXJlbmNlLnNlcnZpY2VSZWZlcmVuY2VzLmNvbnRhaW5zS2V5KGNoYW5nZWRSZWZlcmVuY2UpKSB7Ci0JCQlyZXR1cm4gdHJ1ZTsKLQkJfQotCQlpZiAoYm91bmRTZXJ2aWNlUmVmZXJlbmNlcy5zaXplKCkgPiAwKSB7Ci0JCQlyZXR1cm4gKGNhcmRpbmFsaXR5SGlnaCA9PSAxKSA/IGJvdW5kU2VydmljZVJlZmVyZW5jZXMuZWxlbWVudEF0KDApID09IGNoYW5nZWRSZWZlcmVuY2UgOiBib3VuZFNlcnZpY2VSZWZlcmVuY2VzLmNvbnRhaW5zKGNoYW5nZWRSZWZlcmVuY2UpOwotCQl9Ci0JCXJldHVybiBmYWxzZTsKLQl9Ci0KLQkvKioKLQkgKiBDaGVja3MgaWYgdGhlIHBhc3NlZCBzZXJ2aWNlIHJlZmVyZW5jZSBpcyBzYXRpc2Z5aW5nIHRoaXMgcmVmZXJlbmNlIGFjY29yZGluZyB0byB0aGUgdGFyZ2V0IGZpbHRlcgotCSAqIEBwYXJhbSBzZXJ2aWNlUmVmZXJlbmNlIHRoZSBzZXJ2aWNlIHJlZmVyZW5jZSB0byBjaGVjawotCSAqIEByZXR1cm4gdHJ1ZSwgaWYgdGhlIHNlcnZpY2UgcmVmZXJlbmNlIGRvIHNhdGlzZnkgdGhpcyByZWZlcmVuY2UsIG90aGVyd2lzZSByZXR1cm5zIGZhbHNlCi0JICovCi0JcHVibGljIGJvb2xlYW4gaXNJblNhdGlzZmllZExpc3QoU2VydmljZVJlZmVyZW5jZSBzZXJ2aWNlUmVmZXJlbmNlKSB7Ci0JCUZpbHRlciBmaWx0ZXI7Ci0JCXRyeSB7Ci0JCQlmaWx0ZXIgPSBGcmFtZXdvcmtVdGlsLmNyZWF0ZUZpbHRlcih0YXJnZXQpOwotCQl9IGNhdGNoIChJbnZhbGlkU3ludGF4RXhjZXB0aW9uIGUpIHsKLQkJCUFjdGl2YXRvci5sb2cocmVmZXJlbmNlLmNvbXBvbmVudC5iYywgTG9nU2VydmljZS5MT0dfV0FSTklORywgIlJlZmVyZW5jZS5pc0luU2F0aXNmaWVkTGlzdCgpOiAiICsgTkxTLmJpbmQoTWVzc2FnZXMuSU5WQUxJRF9UQVJHRVRfRklMVEVSLCB0YXJnZXQpLCBlKTsgLy8kTk9OLU5MUy0xJAotCQkJcmV0dXJuIGZhbHNlOwotCQl9Ci0JCXJldHVybiBmaWx0ZXIubWF0Y2goc2VydmljZVJlZmVyZW5jZSk7Ci0JfQotCi0JcHVibGljIHZvaWQgc2V0Qm91bmRTZXJ2aWNlUmVmZXJlbmNlcyhTZXJ2aWNlUmVmZXJlbmNlW10gcmVmZXJlbmNlcykgewotCQlpZiAocG9saWN5ID09IENvbXBvbmVudFJlZmVyZW5jZS5QT0xJQ1lfRFlOQU1JQykgewotCQkJLy9ub3QgcmVsZXZhbnQgdG8gZHluYW1pYyByZWZlcmVuY2VzCi0JCQlyZXR1cm47Ci0JCX0KLQotCQlib3VuZFNlcnZpY2VSZWZlcmVuY2VzLnJlbW92ZUFsbEVsZW1lbnRzKCk7Ci0JCWlmIChjYXJkaW5hbGl0eUhpZ2ggPT0gMSkgewotCQkJYm91bmRTZXJ2aWNlUmVmZXJlbmNlcy5hZGRFbGVtZW50KHJlZmVyZW5jZXNbMF0pOwotCQl9IGVsc2UgewotCQkJZm9yIChpbnQgaSA9IDA7IGkgPCByZWZlcmVuY2VzLmxlbmd0aDsgaSsrKSB7Ci0JCQkJYm91bmRTZXJ2aWNlUmVmZXJlbmNlcy5hZGRFbGVtZW50KHJlZmVyZW5jZXNbaV0pOwotCQkJfQotCQl9Ci0JfQotCi0JLyoqCi0JICogU2VsZWN0cyB0aGUgcHJvdmlkZXJzIHRoYXQgcHJvdmlkZSBzZXJ2aWNlIHJlcXVpcmVkIGJ5IHRoaXMgcmVmZXJlbmNlCi0JICogQHBhcmFtIHNjcHMgIHRoZSBsaXN0IG9mIFNDUHMgdG8gYmUgc2VhcmNoZWQgZm9yIHByb3ZpZGVycwotCSAqIEByZXR1cm4gYW4gYXJyYXkgb2YgU0NQcyB0aGF0IHByb3ZpZGUgc2VydmljZSByZXF1aXJlZCBieSB0aGlzIHJlZmVyZW5jZQotCSAqLwotCXB1YmxpYyBTZXJ2aWNlQ29tcG9uZW50UHJvcFtdIHNlbGVjdFByb3ZpZGVycyhWZWN0b3Igc2NwcykgewotCQlGaWx0ZXIgZmlsdGVyOwotCQl0cnkgewotCQkJZmlsdGVyID0gRnJhbWV3b3JrVXRpbC5jcmVhdGVGaWx0ZXIodGFyZ2V0KTsKLQkJfSBjYXRjaCAoSW52YWxpZFN5bnRheEV4Y2VwdGlvbiBlKSB7Ci0JCQlBY3RpdmF0b3IubG9nKHJlZmVyZW5jZS5jb21wb25lbnQuYmMsIExvZ1NlcnZpY2UuTE9HX1dBUk5JTkcsICJSZWZlcmVuY2Uuc2VsZWN0UHJvdmlkZXJzKCk6ICIgKyBOTFMuYmluZChNZXNzYWdlcy5JTlZBTElEX1RBUkdFVF9GSUxURVIsIHRhcmdldCksIGUpOyAvLyROT04tTkxTLTEkCi0JCQlyZXR1cm4gbnVsbDsKLQkJfQotCQlWZWN0b3IgcmVzdWx0ID0gbmV3IFZlY3RvcigyKTsKLQkJZm9yIChpbnQgaSA9IDA7IGkgPCBzY3BzLnNpemUoKTsgaSsrKSB7Ci0JCQlTZXJ2aWNlQ29tcG9uZW50UHJvcCBwcm92aWRlclNDUCA9IChTZXJ2aWNlQ29tcG9uZW50UHJvcCkgc2Nwcy5lbGVtZW50QXQoaSk7Ci0JCQlpZiAocHJvdmlkZXJTQ1Auc2VydmljZUNvbXBvbmVudC5zZXJ2aWNlSW50ZXJmYWNlcyAhPSBudWxsICYmIHByb3ZpZGVyU0NQLnNlcnZpY2VDb21wb25lbnQuc2VydmljZUludGVyZmFjZXMuY29udGFpbnMoaW50ZXJmYWNlTmFtZSkpIHsKLQkJCQlpZiAoZmlsdGVyLm1hdGNoKHByb3ZpZGVyU0NQLmdldFByb3BlcnRpZXMoKSkpIHsKLQkJCQkJcmVzdWx0LmFkZEVsZW1lbnQocHJvdmlkZXJTQ1ApOwotCQkJCX0KLQkJCX0KLQkJfQotCQlTZXJ2aWNlQ29tcG9uZW50UHJvcFtdIHJlcyA9IG5ldyBTZXJ2aWNlQ29tcG9uZW50UHJvcFtyZXN1bHQuc2l6ZSgpXTsKLQkJcmVzdWx0LmNvcHlJbnRvKHJlcyk7Ci0JCXJldHVybiByZXM7Ci0JfQotCi0JcHVibGljIGJvb2xlYW4gaXNCb3VuZCgpIHsKLQkJaWYgKHRoaXMucmVmZXJlbmNlLmJpbmQgIT0gbnVsbCkgewotCQkJcmV0dXJuICh0aGlzLnJlZmVyZW5jZS5zZXJ2aWNlUmVmZXJlbmNlcy5zaXplKCkgPj0gY2FyZGluYWxpdHlMb3cpOwotCQl9Ci0JCXJldHVybiB0cnVlOwotCX0KLQotCXB1YmxpYyBWZWN0b3IgZ2V0Qm91bmRTZXJ2aWNlUmVmZXJlbmNlcygpIHsKLQkJcmV0dXJuIGJvdW5kU2VydmljZVJlZmVyZW5jZXM7Ci0JfQotCi0JcHVibGljIFN0cmluZyBnZXRCaW5kTWV0aG9kTmFtZSgpIHsKLQkJcmV0dXJuIHJlZmVyZW5jZS5iaW5kOwotCX0KLQotCXB1YmxpYyBTdHJpbmcgZ2V0TmFtZSgpIHsKLQkJcmV0dXJuIHJlZmVyZW5jZS5uYW1lOwotCX0KLQotCXB1YmxpYyBTdHJpbmcgZ2V0U2VydmljZU5hbWUoKSB7Ci0JCXJldHVybiByZWZlcmVuY2UuaW50ZXJmYWNlTmFtZTsKLQl9Ci0KLQlwdWJsaWMgU2VydmljZVJlZmVyZW5jZVtdIGdldFNlcnZpY2VSZWZlcmVuY2VzKCkgewotCQlWZWN0b3IgcmVzdWx0ID0gbnVsbDsKLQkJaWYgKHRoaXMucmVmZXJlbmNlLmJpbmQgIT0gbnVsbCkgewotCQkJaWYgKCFyZWZlcmVuY2Uuc2VydmljZVJlZmVyZW5jZXMuaXNFbXB0eSgpKSB7Ci0JCQkJcmVzdWx0ID0gbmV3IFZlY3RvcigyKTsKLQkJCQlFbnVtZXJhdGlvbiBrZXlzID0gcmVmZXJlbmNlLnNlcnZpY2VSZWZlcmVuY2VzLmtleXMoKTsKLQkJCQl3aGlsZSAoa2V5cy5oYXNNb3JlRWxlbWVudHMoKSkgewotCQkJCQlyZXN1bHQuYWRkKGtleXMubmV4dEVsZW1lbnQoKSk7Ci0JCQkJfQotCQkJfQotCQl9IGVsc2UgewotCQkJLy9ubyBiaW5kIG1ldGhvZAotCQkJaWYgKCFib3VuZFNlcnZpY2VSZWZlcmVuY2VzLmlzRW1wdHkoKSkgewotCQkJCXJlc3VsdCA9IChWZWN0b3IpIGJvdW5kU2VydmljZVJlZmVyZW5jZXMuY2xvbmUoKTsKLQkJCX0KLQkJfQotCQlpZiAocmVzdWx0ICE9IG51bGwgJiYgIXJlc3VsdC5pc0VtcHR5KCkpIHsKLQkJCVNlcnZpY2VSZWZlcmVuY2VbXSBmaW5hbFJlc3VsdCA9IG5ldyBTZXJ2aWNlUmVmZXJlbmNlW3Jlc3VsdC5zaXplKCldOwotCQkJcmVzdWx0LmNvcHlJbnRvKGZpbmFsUmVzdWx0KTsKLQkJCXJldHVybiBmaW5hbFJlc3VsdDsKLQkJfQotCQlyZXR1cm4gbnVsbDsKLQl9Ci0KLQlwdWJsaWMgU3RyaW5nIGdldFVuYmluZE1ldGhvZE5hbWUoKSB7Ci0JCXJldHVybiByZWZlcmVuY2UudW5iaW5kOwotCX0KLQotCXB1YmxpYyBib29sZWFuIGlzTXVsdGlwbGUoKSB7Ci0JCXJldHVybiBjYXJkaW5hbGl0eUhpZ2ggPiAxOwotCX0KLQotCXB1YmxpYyBib29sZWFuIGlzT3B0aW9uYWwoKSB7Ci0JCXJldHVybiBjYXJkaW5hbGl0eUxvdyA9PSAwOwotCX0KLQotCXB1YmxpYyBib29sZWFuIGlzU2F0aXNmaWVkKCkgewotCQlpZiAoY2FyZGluYWxpdHlMb3cgPT0gMCkgewotCQkJcmV0dXJuIHRydWU7Ci0JCX0KLQkJdHJ5IHsKLQkJCVNlcnZpY2VSZWZlcmVuY2VbXSBzZXJ2aWNlUmVmZXJlbmNlcyA9IHJlZmVyZW5jZS5jb21wb25lbnQuYmMuZ2V0U2VydmljZVJlZmVyZW5jZXMoaW50ZXJmYWNlTmFtZSwgdGFyZ2V0KTsKLQkJCWlmIChzZXJ2aWNlUmVmZXJlbmNlcyAhPSBudWxsKSB7Ci0JCQkJcmV0dXJuIHRydWU7Ci0JCQl9Ci0JCX0gY2F0Y2ggKEludmFsaWRTeW50YXhFeGNlcHRpb24gZSkgewotCQkJLy8gZG8gbm90aGluZwotCQl9Ci0JCXJldHVybiBmYWxzZTsKLQl9Ci0KLQlwdWJsaWMgYm9vbGVhbiBpc1N0YXRpYygpIHsKLQkJcmV0dXJuIHBvbGljeSA9PSBDb21wb25lbnRSZWZlcmVuY2UuUE9MSUNZX1NUQVRJQzsKLQl9Ci0KLQkvKiAobm9uLUphdmFkb2MpCi0JICogQHNlZSBvcmcuYXBhY2hlLmZlbGl4LnNjci5SZWZlcmVuY2UjZ2V0VXBkYXRlZE1ldGhvZE5hbWUoKQotCSAqLwotCXB1YmxpYyBTdHJpbmcgZ2V0VXBkYXRlZE1ldGhvZE5hbWUoKSB7Ci0JCWlmIChyZWZlcmVuY2UuY29tcG9uZW50LmlzTmFtZXNwYWNlQXRMZWFzdDEyKCkpIHsKLQkJCXJldHVybiByZWZlcmVuY2UudXBkYXRlZDsKLQkJfQotCQlyZXR1cm4gbnVsbDsKLQl9Ci0KLX0KZGlmZiAtLWdpdCBhL2J1bmRsZXMvb3JnLmVjbGlwc2UuZXF1aW5veC5kcy9zcmMvb3JnL2VjbGlwc2UvZXF1aW5veC9pbnRlcm5hbC9kcy9SZXNvbHZlci5qYXZhIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5lcXVpbm94LmRzL3NyYy9vcmcvZWNsaXBzZS9lcXVpbm94L2ludGVybmFsL2RzL1Jlc29sdmVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAzYjU4MmEuLjAwMDAwMDAKLS0tIGEvYnVuZGxlcy9vcmcuZWNsaXBzZS5lcXVpbm94LmRzL3NyYy9vcmcvZWNsaXBzZS9lcXVpbm94L2ludGVybmFsL2RzL1Jlc29sdmVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMjQ1ICswLDAgQEAKLS8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTAgYnkgUHJvU3lzdCBTb2Z0d2FyZSBHbWJICi0gKiBodHRwOi8vd3d3LnByb3N5c3QuY29tCi0gKiBBbGwgcmlnaHRzIHJlc2VydmVkLiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzCi0gKiBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYxLjAKLSAqIHdoaWNoIGFjY29tcGFuaWVzIHRoaXMgZGlzdHJpYnV0aW9uLCBhbmQgaXMgYXZhaWxhYmxlIGF0Ci0gKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC12MTAuaHRtbAotICoKLSAqIENvbnRyaWJ1dG9yczoKLSAqICAgIFByb1N5c3QgU29mdHdhcmUgR21iSCAtIGluaXRpYWwgQVBJIGFuZCBpbXBsZW1lbnRhdGlvbgotICogICAgQW5kcmV3IFRlaXJuZXkJCSAtIGJ1Zy5pZCA9IDI3ODczMgotICogICAgU2ltb24gS2FlZ2kJCQkgLSBidWcuaWQgPSAyOTY3NTAKLSAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwotcGFja2FnZSBvcmcuZWNsaXBzZS5lcXVpbm94LmludGVybmFsLmRzOwotCi1pbXBvcnQgamF2YS51dGlsLio7Ci1pbXBvcnQgb3JnLmFwYWNoZS5mZWxpeC5zY3IuQ29tcG9uZW50OwotaW1wb3J0IG9yZy5lY2xpcHNlLmVxdWlub3guaW50ZXJuYWwuZHMubW9kZWwuKjsKLWltcG9ydCBvcmcuZWNsaXBzZS5vc2dpLnV0aWwuTkxTOwotaW1wb3J0IG9yZy5vc2dpLmZyYW1ld29yay4qOwotaW1wb3J0IG9yZy5vc2dpLnNlcnZpY2UuY20uQ29uZmlndXJhdGlvbjsKLWltcG9ydCBvcmcub3NnaS5zZXJ2aWNlLmNtLkNvbmZpZ3VyYXRpb25BZG1pbjsKLWltcG9ydCBvcmcub3NnaS5zZXJ2aWNlLmNvbXBvbmVudC5Db21wb25lbnRDb25zdGFudHM7Ci1pbXBvcnQgb3JnLm9zZ2kuc2VydmljZS5jb21wb25lbnQuQ29tcG9uZW50RXhjZXB0aW9uOwotaW1wb3J0IG9yZy5vc2dpLnNlcnZpY2UubG9nLkxvZ1NlcnZpY2U7Ci0KLS8qKgotICogUmVzb2x2ZXIuamF2YQotICogCi0gKiBAYXV0aG9yIFZhbGVudGluIFZhbGNoZXYKLSAqIEBhdXRob3IgU3RveWFuIEJvc2hldgotICogQGF1dGhvciBQYXZsaW4gRG9icmV2Ci0gKi8KLXB1YmxpYyBmaW5hbCBjbGFzcyBSZXNvbHZlciBpbXBsZW1lbnRzIFdvcmtQZXJmb3JtZXIgewotCi0JLy8gdGhlc2Ugc3RyaW5ncyBhcmUgdXNlZCBvbmx5IGZvciBkZWJ1Z2dpbmcgcHVycG9zZQotCXN0YXRpYyBmaW5hbCBTdHJpbmdbXSBXT1JLX1RJVExFUyA9IHsiQlVJTEQgIiwgIkRZTkFNSUNCSU5EICIsICJESVNQT1NFICJ9OyAvLyROT04tTkxTLTEkIC8vJE5PTi1OTFMtMiQgLy8kTk9OLU5MUy0zJAotCi0JLyoqCi0JICogU2VydmljZSBDb21wb25lbnQgaW5zdGFuY2VzIG5lZWQgdG8gYmUgYnVpbHQuCi0JICovCi0JcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQlVJTEQgPSAxOwotCi0JLyoqCi0JICogU2VydmljZSBDb21wb25lbnQgaW5zdGFuY2VzIG5lZWQgdG8gYmUgcmVib3VuZAotCSAqLwotCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IERZTkFNSUNCSU5EID0gMjsKLQotCS8qKgotCSAqIFNlcnZpY2UgQ29tcG9uZW50IGluc3RhbmNlcyBuZWVkIHRvIGJlIGRpc3Bvc2VkCi0JICovCi0JcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRElTUE9TRSA9IDM7Ci0KLQkvKiBIb2xkcyB0aGUgZW5hYmxlZCBTQ1BzKi8KLQlwcm90ZWN0ZWQgVmVjdG9yIHNjcEVuYWJsZWQ7Ci0KLQlwcml2YXRlIEluc3RhbmNlUHJvY2VzcyBpbnN0YW5jZVByb2Nlc3M7Ci0KLQlwcml2YXRlIE9iamVjdCBzeW5jTG9jayA9IG5ldyBPYmplY3QoKTsKLQotCXByaXZhdGUgSGFzaHRhYmxlIHNlcnZpY2VSZWZlcmVuY2VUYWJsZSA9IG5ldyBIYXNodGFibGUoKTsKLQotCXB1YmxpYyBTQ1JNYW5hZ2VyIG1ncjsKLQotCS8vIFRPRE86IEFkZCBhIGhhc2h0YWJsZSBjb25uZWN0aW5nIHNlcnZpY2VyZWZlcmVuY2UgdG8gYSBsaXN0IG9mIFJlZmVyZW5jZXMKLQkvLyB3aGljaCB0aGV5IGFyZSBib3VuZCB0bwotCS8vIFRoaXMgd2F5IHRoZSBzZWFyY2ggb2YgcmVmZXJlbmNlcyB0byB1bmJpbmQgYmVjb21lcyBmYXN0ZXIgd2hlbiB0aGVyZSBhcmUKLQkvLyBwbGVudHkgb2YgY29tcG9uZW50cy4KLQkvLyBLZWVwIGluIG1pbmQgdGhhdCBidWlsZCBwcm9jZXNzIGlzIGFzeW5jaHJvbm91cy4KLQotCXN0YXRpYyB7Ci0JCS8qKiBwcmVsb2FkIHNvbWUgRFMgYnVuZGxlIGNsYXNzZXMgdG8gYXZvaWQgY2xhc3Nsb2FkZXIgZGVhZGxvY2tzICovCi0JCVJlZmVyZW5jZS5jbGFzcy5nZXROYW1lKCk7Ci0JCVNDUlV0aWwuY2xhc3MuZ2V0TmFtZSgpOwotCX0KLQotCS8qKgotCSAqIFJlc29sdmVyIGNvbnN0cnVjdG9yCi0JICogCi0JICovCi0JUmVzb2x2ZXIoU0NSTWFuYWdlciBtZ3IpIHsKLQkJc2NwRW5hYmxlZCA9IG5ldyBWZWN0b3IoKTsKLQkJLy8JCXNhdGlzZmllZFNDUHMgPSBuZXcgVmVjdG9yKCk7Ci0JCWluc3RhbmNlUHJvY2VzcyA9IG5ldyBJbnN0YW5jZVByb2Nlc3ModGhpcyk7Ci0JCXRoaXMubWdyID0gbWdyOwotCX0KLQotCXZvaWQgc3luY2hyb25pemVTZXJ2aWNlUmVmZXJlbmNlcygpIHsKLQkJc3luY2hyb25pemVkIChzeW5jTG9jaykgewotCQkJdHJ5IHsKLQkJCQlTZXJ2aWNlUmVmZXJlbmNlW10gcmVmZXJlbmNlcyA9IEFjdGl2YXRvci5iYy5nZXRBbGxTZXJ2aWNlUmVmZXJlbmNlcyhudWxsLCBudWxsKTsKLQkJCQlzZXJ2aWNlUmVmZXJlbmNlVGFibGUuY2xlYXIoKTsKLQkJCQlpZiAocmVmZXJlbmNlcyAhPSBudWxsKSB7Ci0JCQkJCWZvciAoaW50IGkgPSAwOyBpIDwgcmVmZXJlbmNlcy5sZW5ndGg7IGkrKykgewotCQkJCQkJc2VydmljZVJlZmVyZW5jZVRhYmxlLnB1dChyZWZlcmVuY2VzW2ldLCBCb29sZWFuLlRSVUUpOwotCQkJCQl9Ci0JCQkJfQotCQkJfSBjYXRjaCAoSW52YWxpZFN5bnRheEV4Y2VwdGlvbiBlKSB7Ci0JCQkJQWN0aXZhdG9yLmxvZyhBY3RpdmF0b3IuYmMsIExvZ1NlcnZpY2UuTE9HX1dBUk5JTkcsICJSZXNvbHZlcigpOiAiICsgTkxTLmJpbmQoTWVzc2FnZXMuSU5WQUxJRF9UQVJHRVRfRklMVEVSLCAiIiksIGUpOyAvLyROT04tTkxTLTEkIC8vJE5PTi1OTFMtMiQKLQkJCX0KLQkJfQotCX0KLQotCXB1YmxpYyBPYmplY3QgZ2V0U3luY0xvY2soKSB7Ci0JCXJldHVybiBzeW5jTG9jazsKLQl9Ci0KLQkvLyBUaGlzIG1ldGhvZCBzaG91bGQgYmUgY2FsbGVkIHdoZW4gdGhlIGV2ZW50IHByb2Nlc3NpbmcgdGhyZWFkIGlzIGJsb2NrZWQKLQkvLyBpbiBhIHVzZXIgY29kZQotCXZvaWQgcXVldWVCbG9ja2VkKCkgewotCQlzeW5jTG9jayA9IG5ldyBPYmplY3QoKTsKLQkJaW5zdGFuY2VQcm9jZXNzID0gbmV3IEluc3RhbmNlUHJvY2Vzcyh0aGlzKTsKLQl9Ci0KLQkvLyAtLSBiZWdpbiAqZW5hYmxlKiBjb21wb25lbnQgcm91dGluZXMKLQkvKioKLQkgKiBlbmFibGVDb21wb25lbnRzIC0gY2FsbGVkIGJ5IHRoZSBkaXNwYXRjaFdvcmtlcgotCSAqIAotCSAqIEBwYXJhbSBzZXJ2aWNlQ29tcG9uZW50cyAtCi0JICogICAgICAgICAgICBhIGxpc3Qgb2YgYWxsIGNvbXBvbmVudCBkZXNjcmlwdGlvbnMgZm9yIGEgc2luZ2xlIGJ1bmRsZSB0byBiZQotCSAqICAgICAgICAgICAgZW5hYmxlZCBSZWNlaXZlIEFycmF5TGlzdCBvZiBlbmFibGVkIENEJ3MgZnJvbSBDb21wb25lbnRDYWNoZQotCSAqICAgICAgICAgICAgRm9yIGVhY2ggQ0QgYWRkIHRvIGxpc3Qgb2YgZW5hYmxlZCBjcmVhdGUgbGlzdCBvZiBDRDpDRCtQCi0JICogICAgICAgICAgICBjcmVhdGUgbGlzdCBvZiBDRCtQOnJlZiAoIHdoZXJlIHJlZiBpcyBhIFJlZmVyZW5jZSBPYmplY3QpCi0JICogICAgICAgICAgICByZXNvbHZlIENEK1AKLQkgKi8KLQl2b2lkIGVuYWJsZUNvbXBvbmVudHMoVmVjdG9yIHNlcnZpY2VDb21wb25lbnRzKSB7Ci0JCWxvbmcgc3RhcnQgPSAwbDsKLQkJaWYgKEFjdGl2YXRvci5ERUJVRykgewotCQkJQWN0aXZhdG9yLmxvZy5kZWJ1ZygiUmVzb2x2ZXIuZW5hYmxlQ29tcG9uZW50cygpOiAiICsgKHNlcnZpY2VDb21wb25lbnRzICE9IG51bGwgPyBzZXJ2aWNlQ29tcG9uZW50cy50b1N0cmluZygpIDogIm51bGwiKSwgbnVsbCk7IC8vJE5PTi1OTFMtMSQgLy8kTk9OLU5MUy0yJAotCQl9Ci0JCWlmIChBY3RpdmF0b3IuUEVSRikgewotCQkJc3RhcnQgPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKTsKLQkJfQotCi0JCXN5bmNocm9uaXplZCAoc3luY0xvY2spIHsKLQkJCUNvbmZpZ3VyYXRpb25bXSBjb25maWdzID0gbnVsbDsKLQotCQkJaWYgKHNlcnZpY2VDb21wb25lbnRzICE9IG51bGwpIHsKLQkJCQlmb3IgKGludCBpID0gMDsgaSA8IHNlcnZpY2VDb21wb25lbnRzLnNpemUoKTsgaSsrKSB7Ci0JCQkJCVNlcnZpY2VDb21wb25lbnQgY3VycmVudCA9IChTZXJ2aWNlQ29tcG9uZW50KSBzZXJ2aWNlQ29tcG9uZW50cy5lbGVtZW50QXQoaSk7Ci0KLQkJCQkJLy8gZG9uJ3QgZW5hYmxlIGNvbXBvbmVudHMgd2hpY2ggYXJlIG5vdCBtYXJrZWQgZW5hYmxlZAotCQkJCQkvLyB0aGlzIGlzIGRvbmUgaGVyZSwgbm90IGluIHRoZSBhY3RpdmF0b3IganVzdCBiZWNhdXNlIGl0Ci0JCQkJCS8vIHNhdmVzIGEgbGl0dGxlIG1lbW9yeQotCQkJCQlpZiAoIWN1cnJlbnQuZW5hYmxlZCkgewotCQkJCQkJaWYgKEFjdGl2YXRvci5ERUJVRykgewotCQkJCQkJCUFjdGl2YXRvci5sb2cuZGVidWcoIlJlc29sdmVyLmVuYWJsZUNvbXBvbmVudHMoKTogaWdub3Jpbmcgbm90IGVuYWJsZWQgY29tcG9uZW50ICIgKyBjdXJyZW50Lm5hbWUsIG51bGwpOyAvLyROT04tTkxTLTEkCi0JCQkJCQl9Ci0JCQkJCQljb250aW51ZTsKLQkJCQkJfQotCQkJCQlpZiAoY3VycmVudC5jb21wb25lbnRQcm9wcyAhPSBudWxsICYmIGN1cnJlbnQuY29tcG9uZW50UHJvcHMuc2l6ZSgpID4gMCkgewotCQkJCQkJLy9jb21wb25lbnQgaXMgYWxyZWFkeSBlbmFibGVkIGFuZCBwcm9jZXNzZWQuIFNraXBwaW5nIGl0LgotCQkJCQkJY29udGludWU7Ci0JCQkJCX0KLQotCQkJCQljdXJyZW50LnNldFN0YXRlKENvbXBvbmVudC5TVEFURV9VTlNBVElTRklFRCk7Ci0KLQkJCQkJaWYgKGN1cnJlbnQuZ2V0Q29uZmlndXJhdGlvblBvbGljeSgpID09IFNlcnZpY2VDb21wb25lbnQuQ09ORl9QT0xJQ1lfSUdOT1JFKSB7Ci0JCQkJCQkvL3NraXAgbG9va2luZyBmb3IgY29uZmlndXJhdGlvbnMgCi0JCQkJCQltYXAoY3VycmVudCwgKERpY3Rpb25hcnkpIG51bGwpOwotCQkJCQkJY29udGludWU7Ci0JCQkJCX0KLQotCQkJCQkvLyBjaGVjayBmb3IgYSBDb25maWd1cmF0aW9uIHByb3BlcnRpZXMgZm9yIHRoaXMgY29tcG9uZW50Ci0JCQkJCXRyeSB7Ci0JCQkJCQlTdHJpbmcgZmlsdGVyID0gIih8KCIgKyBDb25zdGFudHMuU0VSVklDRV9QSUQgKyAnPScgKyBjdXJyZW50LmdldENvbmZpZ3VyYXRpb25QSUQoKSArICIpKCIgKyBDb25maWd1cmF0aW9uQWRtaW4uU0VSVklDRV9GQUNUT1JZUElEICsgJz0nICsgY3VycmVudC5nZXRDb25maWd1cmF0aW9uUElEKCkgKyAiKSkiOyAvLyROT04tTkxTLTEkIC8vJE5PTi1OTFMtMiQgLy8kTk9OLU5MUy0zJAotCQkJCQkJY29uZmlncyA9IEFjdGl2YXRvci5saXN0Q29uZmlndXJhdGlvbnMoZmlsdGVyKTsKLQkJCQkJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKLQkJCQkJCUFjdGl2YXRvci5sb2cobnVsbCwgTG9nU2VydmljZS5MT0dfRVJST1IsIE5MUy5iaW5kKE1lc3NhZ2VzLkNBTlRfTElTVF9DT05GSUdVUkFUSU9OUywgY3VycmVudC5uYW1lKSwgZSk7Ci0JCQkJCX0KLQkJCQkJLy8gaWYgbm8gQ29uZmlndXJhdGlvbgotCQkJCQlpZiAoY29uZmlncyA9PSBudWxsIHx8IGNvbmZpZ3MubGVuZ3RoID09IDApIHsKLQkJCQkJCWlmIChjdXJyZW50LmdldENvbmZpZ3VyYXRpb25Qb2xpY3koKSAhPSBTZXJ2aWNlQ29tcG9uZW50LkNPTkZfUE9MSUNZX1JFUVVJUkUpIHsKLQkJCQkJCQkvLyBjcmVhdGUgU2VydmljZUNvbXBvbmVudCArIFByb3AKLQkJCQkJCQltYXAoY3VycmVudCwgKERpY3Rpb25hcnkpIG51bGwpOwotCQkJCQkJfSBlbHNlIHsKLQkJCQkJCQlTdHJpbmcgY3VzdG9tUmVhc29uID0gQWN0aXZhdG9yLmNvbmZpZ0FkbWluICE9IG51bGwgPyAiIiA6IE1lc3NhZ2VzLkNPTkZJR19BRE1JTl9TRVJWSUNFX05PVF9BVkFJTEFCTEU7IC8vJE5PTi1OTFMtMSQKLQkJCQkJCQlpZiAoQWN0aXZhdG9yLkRFQlVHKSB7Ci0JCQkJCQkJCUFjdGl2YXRvci5sb2cuZGVidWcoTkxTLmJpbmQoTWVzc2FnZXMuQ09NUE9ORU5UX1JFUVVSRVNfQ09ORklHVVJBVElPTl9BQ1RJVkFUSU9OLCBjdXJyZW50Lm5hbWUpICsgY3VzdG9tUmVhc29uLCBudWxsKTsKLQkJCQkJCQl9Ci0JCQkJCQl9Ci0JCQkJCX0gZWxzZSB7Ci0JCQkJCQkvLyBpZiBNYW5hZ2VkU2VydmljZUZhY3RvcnkKLQkJCQkJCUNvbmZpZ3VyYXRpb24gY29uZmlnID0gY29uZmlnc1swXTsKLQkJCQkJCWlmIChjb25maWcuZ2V0RmFjdG9yeVBpZCgpICE9IG51bGwgJiYgY29uZmlnLmdldEZhY3RvcnlQaWQoKS5lcXVhbHMoY3VycmVudC5nZXRDb25maWd1cmF0aW9uUElEKCkpKSB7Ci0JCQkJCQkJLy8gaWYgQ29tcG9uZW50RmFjdG9yeSBpcyBzcGVjaWZpZWQKLQkJCQkJCQlpZiAoY3VycmVudC5mYWN0b3J5ICE9IG51bGwpIHsKLQkJCQkJCQkJQWN0aXZhdG9yLmxvZyhjdXJyZW50LmJjLCBMb2dTZXJ2aWNlLkxPR19FUlJPUiwgTkxTLmJpbmQoTWVzc2FnZXMuUkVHSVNURVJFRF9BU19DT01QT05FTlRfQU5EX01BTkFHRURfU0VSVklDRV9GQUNPUlksIGN1cnJlbnQubmFtZSksIG51bGwpOwotCQkJCQkJCQljb250aW51ZTsgLy8gc2tpcCBjdXJyZW50IGNvbXBvbmVudAotCQkJCQkJCX0KLQkJCQkJCQlpZiAoQWN0aXZhdG9yLkRFQlVHKSB7Ci0JCQkJCQkJCUFjdGl2YXRvci5sb2cuZGVidWcoIltTQ1IgLSBSZXNvbHZlcl0gUmVzb2x2ZXIuZW5hYmxlQ29tcG9uZW50cygpOiAiICsgY3VycmVudC5uYW1lICsgIiBhcyAqbWFuYWdlZCBzZXJ2aWNlIGZhY3RvcnkqIiwgbnVsbCk7IC8vJE5PTi1OTFMtMSQgLy8kTk9OLU5MUy0yJAotCQkJCQkJCX0KLQkJCQkJCQl0cnkgewotCQkJCQkJCQljb25maWdzID0gQWN0aXZhdG9yLmxpc3RDb25maWd1cmF0aW9ucygiKHNlcnZpY2UuZmFjdG9yeVBpZD0iICsgY29uZmlnLmdldEZhY3RvcnlQaWQoKSArICIpIik7IC8vJE5PTi1OTFMtMSQgLy8kTk9OLU5MUy0yJAotCQkJCQkJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7Ci0JCQkJCQkJCUFjdGl2YXRvci5sb2cobnVsbCwgTG9nU2VydmljZS5MT0dfRVJST1IsIE5MUy5iaW5kKE1lc3NhZ2VzLkNBTlRfTElTVF9DT05GSUdVUkFUSU9OUywgY3VycmVudC5uYW1lKSwgZSk7Ci0JCQkJCQkJfQotCQkJCQkJCS8vIGZvciBlYWNoIE1TRiBzZXQgb2YgcHJvcGVydGllcyhQKSwgbWFwKENELCBuZXcKLQkJCQkJCQkvLyBDRCtQKENELFApKQotCQkJCQkJCWlmIChjb25maWdzICE9IG51bGwpIHsKLQkJCQkJCQkJZm9yIChpbnQgaW5kZXggPSAwOyBpbmRleCA8IGNvbmZpZ3MubGVuZ3RoOyBpbmRleCsrKSB7Ci0JCQkJCQkJCQltYXAoY3VycmVudCwgY29uZmlnc1tpbmRleF0pOwotCQkJCQkJCQl9Ci0JCQkJCQkJfQotCQkJCQkJfSBlbHNlIHsKLQkJCQkJCQlpZiAoQWN0aXZhdG9yLkRFQlVHKSB7Ci0JCQkJCQkJCUFjdGl2YXRvci5sb2cuZGVidWcoIltTQ1IgLSBSZXNvbHZlcl0gUmVzb2x2ZXIuZW5hYmxlQ29tcG9uZW50cygpOiAiICsgY3VycmVudC5uYW1lICsgIiBhcyAqc2VydmljZSoiLCBudWxsKTsgLy8kTk9OLU5MUy0xJCAvLyROT04tTkxTLTIkCi0JCQkJCQkJfSAvLyBpZiBTZXJ2aWNlLCBub3QgTWFuYWdlZFNlcnZpY2VGYWN0b3J5Ci0JCQkJCQkJbWFwKGN1cnJlbnQsIGNvbmZpZyk7Ci0JCQkJCQl9Ci0JCQkJCX0gLy8gZW5kIGhhcyBjb25maWd1cmF0aW9uCi0JCQkJfSAvLyBlbmQgcHJvY2VzcyBhbGwgY29tcG9uZW50cyEKLQkJCX0KLQkJfQotCi0JCWJ1aWxkTmV3bHlTYXRpc2ZpZWQodHJ1ZSk7Ci0KLQkJaWYgKEFjdGl2YXRvci5QRVJGKSB7Ci0JCQlzdGFydCA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpIC0gc3RhcnQ7Ci0JCQlBY3RpdmF0b3IubG9nLmluZm8oIltEUyBwZXJmXSAiICsgKHNlcnZpY2VDb21wb25lbnRzICE9IG51bGwgPyBJbnRlZ2VyLnRvU3RyaW5nKHNlcnZpY2VDb21wb25lbnRzLnNpemUoKSkgOiAiIikgKyAiIENvbXBvbmVudHMgZW5hYmxlZCBmb3IgIiArIExvbmcudG9TdHJpbmcoc3RhcnQpICsgIm1zIik7IC8vJE5PTi1OTFMtMSQgLy8kTk9OLU5MUy0yJCAvLyROT04tTkxTLTMkIC8vJE5PTi1OTFMtNCQKLQkJfQotCX0KLQotCXByb3RlY3RlZCBTZXJ2aWNlQ29tcG9uZW50UHJvcCBtYXAoU2VydmljZUNvbXBvbmVudCBjb21wb25lbnQsIENvbmZpZ3VyYXRpb24gY29uZmlnKSB7Ci0JCURpY3Rpb25hcnkgY29uZmlnUHJvcHMgPSBudWxsOwotCQlpZiAoY29uZmlnICE9IG51bGwpIHsKLQkJCXRyeSB7Ci0JCQkJY29uZmlnUHJvcHMgPSBjb25maWcuZ2V0UHJvcGVydGllcygpOwotCQkJfSBjYXRjaCAoSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGlzZSkgewotCQkJCS8vIHRoZSBjb25maWd1cmF0aW9uIG1heSBoYXZlIGJlZWQgZGVsZXRlZCBhbHJlYWR5Ci0JCQl9Ci0JCX0KLQkJU2VydmljZUNvbXBvbmVudFByb3Agc2NwID0gbWFwKGNvbXBvbmVudCwgY29uZmlnUHJvcHMpOwotCQlpZiAoY29uZmlnICE9IG51bGwpIHsKLQkJCS8vIHNldCB0aGUgc2VydmljZSBQSUQgJiBGYWN0b3J5IFBpZAotCQkJU3RyaW5nIHBpZCA9IGNvbmZpZy5nZXRQaWQoKTsKLQkJCVN0cmluZyBmcGlkID0gY29uZmlnLmdldEZhY3RvcnlQaWQoKTsKLQkJCWlmIChwaWQgIT0gbnVsbCkKLQkJCQlzY3AucHJvcGVydGllcy5wdXQoQ29uc3RhbnRzLlNFUlZJQ0VfUElELCBwaWQpOwotCQkJaWYgKGZwaWQgIT0gbnVsbCkKLQkJCQlzY3AucHJvcGVydGllcy5wdXQoQ29uZmlndXJhdGlvbkFkbWluLlNFUlZJQ0VfRkFDVE9SWVBJRCwgZnBpZCk7Ci0JCX0KLQkJcmV0dXJuIHNjcDsKLQl9Ci0KLQkvKioKLQkgKiBDcmVhdGUgdGhlIFNDUCBhbmQgYWRkIHRvIHRoZSBtYXBzCi0JICogCi0JICogQHBhcmFtIGNvbXBvbmVudCB0aGUgY29tcG9uZW50IGZvciB3aGljaCBTQ1Agd2lsbCBiZSBjcmVhdGVkIAotCSAqIEBwYXJhbSBjb25maWdQcm9wZXJ0aWVzIENNIGNvbmZpZ3VyYXRpb24gcHJvcGVydGllcwotCSAqLwotCXB1YmxpYyBTZXJ2aWNlQ29tcG9uZW50UHJvcCBtYXAoU2VydmljZUNvbXBvbmVudCBjb21wb25lbnQsIERpY3Rpb25hcnkgY29uZmlnUHJvcGVydGllcykgewotCQlTZXJ2aWNlQ29tcG9uZW50UHJvcCBzY3AgPSBudWxsOwotCQl0cnkgewotCQkJaWYgKEFjdGl2YXRvci5ERUJVRykgewotCQkJCUFjdGl2YXRvci5sb2cuZGVidWcoIlJlc29sdmVyLm1hcCgpOiBDcmVhdGluZyBTQ1AgZm9yIGNvbXBvbmVudCAiICsgY29tcG9uZW50Lm5hbWUsIG51bGwpOyAvLyROT04tTkxTLTEkCi0JCQl9Ci0JCQlzY3AgPSBuZXcgU2VydmljZUNvbXBvbmVudFByb3AoY29tcG9uZW50LCBjb25maWdQcm9wZXJ0aWVzLCBtZ3IpOwotCi0JCQkvLyBHZXQgYWxsIHRoZSByZXF1aXJlZCBzZXJ2aWNlIHJlZmVyZW5jZSBkZXNjcmlwdGlvbnMgZm9yIHRoaXMKLQkJCVZlY3RvciByZWZlcmVuY2VEZXNjcmlwdGlvbnMgPSBjb21wb25lbnQucmVmZXJlbmNlczsKLQotCQkJLy8gZm9yIGVhY2ggUmVmZXJlbmNlIERlc2NyaXB0aW9uLCBjcmVhdGUgYSByZWZlcmVuY2Ugb2JqZWN0Ci0JCQlpZiAocmVmZXJlbmNlRGVzY3JpcHRpb25zICE9IG51bGwgJiYgIXJlZmVyZW5jZURlc2NyaXB0aW9ucy5pc0VtcHR5KCkpIHsKLQkJCQlWZWN0b3IgcmVmZXJlbmNlcyA9IG5ldyBWZWN0b3IocmVmZXJlbmNlRGVzY3JpcHRpb25zLnNpemUoKSk7Ci0KLQkJCQlmb3IgKGludCBpID0gMDsgaSA8IHJlZmVyZW5jZURlc2NyaXB0aW9ucy5zaXplKCk7IGkrKykgewotCQkJCQkvLyBjcmVhdGUgbmV3IFJlZmVyZW5jZSBPYmplY3QgYW5kIGFkZCB0byBDRCtQOnJlZiBtYXAKLQkJCQkJQ29tcG9uZW50UmVmZXJlbmNlIGNSZWYgPSAoQ29tcG9uZW50UmVmZXJlbmNlKSByZWZlcmVuY2VEZXNjcmlwdGlvbnMuZWxlbWVudEF0KGkpOwotCi0JCQkJCVJlZmVyZW5jZSByZWYgPSBuZXcgUmVmZXJlbmNlKGNSZWYsIHNjcCwgc2NwLmdldFByb3BlcnRpZXMoKSk7Ci0JCQkJCXJlZmVyZW5jZXMuYWRkRWxlbWVudChyZWYpOwotCQkJCX0KLQkJCQlzY3AucmVmZXJlbmNlcyA9IHJlZmVyZW5jZXM7Ci0JCQl9Ci0JCQljb21wb25lbnQuYWRkU2VydmljZUNvbXBvbmVudFByb3Aoc2NwKTsKLQkJCXNjcEVuYWJsZWQuYWRkRWxlbWVudChzY3ApOwotCi0JCX0gY2F0Y2ggKFRocm93YWJsZSB0KSB7Ci0JCQlBY3RpdmF0b3IubG9nKGNvbXBvbmVudC5iYywgTG9nU2VydmljZS5MT0dfRVJST1IsIE5MUy5iaW5kKE1lc3NhZ2VzLkVSUk9SX0NSRUFUSU5HX1NDUCwgY29tcG9uZW50KSwgdCk7Ci0JCX0KLQkJcmV0dXJuIHNjcDsKLQl9Ci0KLQkvKioKLQkgKiBHZXQgdGhlIEVsaWdpYmxlIENvbXBvbmVudHMKLQkgKiAKLQkgKiBsb29wIHRocm91Z2ggQ0QrUCBsaXN0IG9mIGVuYWJsZWQgZ2V0IHJlZmVyZW5jZXMgY2hlY2sgaWYgZWxpZ2libGUgaWYKLQkgKiB0cnVlIGFkZCB0byBlbGlnaWJsZSBsaXN0IHNlbmQgdG8gSW5zdGFuY2UgUHJvY2VzcwotCSAqIAotCSAqLwotCXZvaWQgZ2V0RWxpZ2libGUoU2VydmljZUV2ZW50IGV2ZW50KSB7Ci0KLQkJaWYgKEFjdGl2YXRvci5ERUJVRykgewotCQkJQWN0aXZhdG9yLmxvZy5kZWJ1ZygiUmVzb2x2ZXIuZ2V0RWxpZ2libGUoKTogcHJvY2Vzc2luZyBzZXJ2aWNlIGV2ZW50ICIgKyBldmVudC50b1N0cmluZygpLCBudWxsKTsgLy8kTk9OLU5MUy0xJAotCQkJU3RyaW5nIGV2ZW50VHlwZSA9ICIiOyAvLyROT04tTkxTLTEkCi0JCQlpZiAoZXZlbnQuZ2V0VHlwZSgpID09IFNlcnZpY2VFdmVudC5VTlJFR0lTVEVSSU5HKSB7Ci0JCQkJZXZlbnRUeXBlID0gIlVOUkVHSVNURVJJTkciOyAvLyROT04tTkxTLTEkCi0JCQl9IGVsc2UgaWYgKGV2ZW50LmdldFR5cGUoKSA9PSBTZXJ2aWNlRXZlbnQuUkVHSVNURVJFRCkgewotCQkJCWV2ZW50VHlwZSA9ICJSRUdJU1RFUkVEIjsgLy8kTk9OLU5MUy0xJAotCQkJfSBlbHNlIGlmIChldmVudC5nZXRUeXBlKCkgPT0gU2VydmljZUV2ZW50Lk1PRElGSUVEKSB7Ci0JCQkJZXZlbnRUeXBlID0gIk1PRElGSUVEIjsgLy8kTk9OLU5MUy0xJAotCQkJfQotCQkJQWN0aXZhdG9yLmxvZy5kZWJ1ZygiU2VydmljZSBldmVudCB0eXBlOiAiICsgZXZlbnRUeXBlLCBudWxsKTsgLy8kTk9OLU5MUy0xJAotCQl9Ci0KLQkJT2JqZWN0IHRhcmdldCA9IG51bGw7Ci0JCVZlY3RvciByZXNvbHZlZENvbXBvbmVudHMgPSBudWxsOwotCQlzd2l0Y2ggKGV2ZW50LmdldFR5cGUoKSkgewotCQkJY2FzZSBTZXJ2aWNlRXZlbnQuUkVHSVNURVJFRCA6Ci0KLQkJCQlzeW5jaHJvbml6ZWQgKHN5bmNMb2NrKSB7Ci0JCQkJCXNlcnZpY2VSZWZlcmVuY2VUYWJsZS5wdXQoZXZlbnQuZ2V0U2VydmljZVJlZmVyZW5jZSgpLCBCb29sZWFuLlRSVUUpOwotCQkJCQlpZiAoc2NwRW5hYmxlZC5pc0VtcHR5KCkpCi0JCQkJCQlyZXR1cm47IC8vIGNoZWNrIGZvciBhbnkgZW5hYmxlZCBjb25maWd1cmF0aW9ucwotCi0JCQkJCS8vY2hlY2sgZm9yIGFueSBzdGF0aWMgcmVmZXJlbmNlcyB3aXRoIHBvbGljeSBvcHRpb24gImdyZWVkeSIgdGhhdCBuZWVkIHRvIGJlIGJvdW5kIHdpdGggdGhpcyBzZXJ2aWNlIHJlZmVyZW5jZQotCQkJCQl0YXJnZXQgPSBzZWxlY3RTdGF0aWNCaW5kKHNjcEVuYWJsZWQsIGV2ZW50LmdldFNlcnZpY2VSZWZlcmVuY2UoKSk7Ci0JCQkJfQotCi0JCQkJaWYgKHRhcmdldCAhPSBudWxsKSB7Ci0JCQkJCS8vZGlzcG9zZSBpbnN0YW5jZXMgb2YgY29tcG9uZW50cyB3aXRoIHN0YXRpYyByZWZlcmVuY2UgdGhhdCBuZWVkcyB0byBiZSBib3VuZCB3aXRoIHRoZSBzZXJ2aWNlIHJlZmVyZW5jZQotCQkJCQlpbnN0YW5jZVByb2Nlc3MuZGlzcG9zZUluc3RhbmNlcygoVmVjdG9yKSB0YXJnZXQsIENvbXBvbmVudENvbnN0YW50cy5ERUFDVElWQVRJT05fUkVBU09OX1JFRkVSRU5DRSk7Ci0JCQkJfQotCi0JCQkJc3luY2hyb25pemVkIChzeW5jTG9jaykgewotCQkJCQlyZXNvbHZlZENvbXBvbmVudHMgPSBnZXRDb21wb25lbnRzVG9CdWlsZCgpOwotCQkJCQl0YXJnZXQgPSBzZWxlY3REeW5hbWljQmluZChzY3BFbmFibGVkLCBldmVudC5nZXRTZXJ2aWNlUmVmZXJlbmNlKCkpOwotCQkJCX0KLQotCQkJCS8vZG8gc3luY2hyb25vdXMgYmluZAotCQkJCWlmICh0YXJnZXQgIT0gbnVsbCkgewotCQkJCQlWZWN0b3IgdW5ib3VuZFJlZnMgPSBpbnN0YW5jZVByb2Nlc3MuZHluYW1pY0JpbmQoKFZlY3RvcikgdGFyZ2V0KTsKLQkJCQkJaWYgKHVuYm91bmRSZWZzICE9IG51bGwpIHsKLQkJCQkJCS8vIHB1dCBkZWxheWVkIGR5bmFtaWMgYmluZHMgb24gdGhlIHF1ZXVlCi0JCQkJCQkvLyAodGhpcyBpcyB1c2VkIHRvIGhhbmRsZSBjbGFzcyBjaXJjdWxhcml0eSBlcnJvcnMpCi0JCQkJCQltZ3IuZW5xdWV1ZVdvcmsodGhpcywgUmVzb2x2ZXIuRFlOQU1JQ0JJTkQsIHVuYm91bmRSZWZzLCBmYWxzZSk7Ci0JCQkJCX0KLQkJCQl9Ci0KLQkJCQlpZiAoIXJlc29sdmVkQ29tcG9uZW50cy5pc0VtcHR5KCkpIHsKLQkJCQkJaW5zdGFuY2VQcm9jZXNzLmJ1aWxkQ29tcG9uZW50cyhyZXNvbHZlZENvbXBvbmVudHMsIGZhbHNlKTsKLQkJCQl9Ci0KLQkJCQlicmVhazsKLQkJCWNhc2UgU2VydmljZUV2ZW50LlVOUkVHSVNURVJJTkcgOgotCQkJCVZlY3RvciBjb21wb25lbnRzVG9EaXNwb3NlOwotCQkJCXN5bmNocm9uaXplZCAoc3luY0xvY2spIHsKLQkJCQkJLy9jaGVjayBmb3IgY29tcG9uZW50cyB3aXRoIHN0YXRpYyByZWZlcmVuY2UgdG8gdGhpcyBzZXJ2aWNlCi0JCQkJCWNvbXBvbmVudHNUb0Rpc3Bvc2UgPSBzZWxlY3RTdGF0aWNVbkJpbmQoc2NwRW5hYmxlZCwgZXZlbnQuZ2V0U2VydmljZVJlZmVyZW5jZSgpLCBmYWxzZSk7Ci0JCQkJfQotCQkJCS8vZGlzcG9zZSBpbnN0YW5jZXMgZnJvbSBzdGF0aWNVbmJpbmQKLQkJCQlpZiAoY29tcG9uZW50c1RvRGlzcG9zZSAhPSBudWxsKSB7Ci0JCQkJCWluc3RhbmNlUHJvY2Vzcy5kaXNwb3NlSW5zdGFuY2VzKGNvbXBvbmVudHNUb0Rpc3Bvc2UsIENvbXBvbmVudENvbnN0YW50cy5ERUFDVElWQVRJT05fUkVBU09OX1JFRkVSRU5DRSk7Ci0JCQkJfQotCi0JCQkJVmVjdG9yIG5ld2x5VW5zYXRpc2ZpZWRTQ1BzOwotCQkJCXN5bmNocm9uaXplZCAoc3luY0xvY2spIHsKLQkJCQkJc2VydmljZVJlZmVyZW5jZVRhYmxlLnJlbW92ZShldmVudC5nZXRTZXJ2aWNlUmVmZXJlbmNlKCkpOwotCQkJCQlpZiAoc2NwRW5hYmxlZC5pc0VtcHR5KCkpCi0JCQkJCQlyZXR1cm47IC8vIGNoZWNrIGZvciBhbnkgZW5hYmxlZCBjb25maWd1cmF0aW9ucwotCi0JCQkJCW5ld2x5VW5zYXRpc2ZpZWRTQ1BzID0gc2VsZWN0TmV3bHlVbnNhdGlzZmllZChldmVudC5nZXRTZXJ2aWNlUmVmZXJlbmNlKCkpOwotCQkJCX0KLQkJCQlpZiAoIW5ld2x5VW5zYXRpc2ZpZWRTQ1BzLmlzRW1wdHkoKSkgewotCQkJCQkvLyBzeW5jaHJvbm91c2x5IGRpc3Bvc2UgbmV3bHkgdW5zYXRpc2ZpZWQgY29tcG9uZW50cwotCQkJCQlpbnN0YW5jZVByb2Nlc3MuZGlzcG9zZUluc3RhbmNlcyhuZXdseVVuc2F0aXNmaWVkU0NQcywgQ29tcG9uZW50Q29uc3RhbnRzLkRFQUNUSVZBVElPTl9SRUFTT05fUkVGRVJFTkNFKTsKLQkJCQl9Ci0KLQkJCQlzeW5jaHJvbml6ZWQgKHN5bmNMb2NrKSB7Ci0JCQkJCS8vIFBhc3MgaW4gdGhlIHNldCBvZiBjdXJyZW50bHkgcmVzb2x2ZWQgY29tcG9uZW50cywgY2hlY2sgZWFjaCBvbmUgLQotCQkJCQkvLyBkbyB3ZSBuZWVkIHRvIHVuYmluZAotCQkJCQl0YXJnZXQgPSBzZWxlY3REeW5hbWljVW5CaW5kKHNjcEVuYWJsZWQsIGV2ZW50LmdldFNlcnZpY2VSZWZlcmVuY2UoKSwgZmFsc2UpOwotCi0JCQkJCWlmIChjb21wb25lbnRzVG9EaXNwb3NlICE9IG51bGwgfHwgIW5ld2x5VW5zYXRpc2ZpZWRTQ1BzLmlzRW1wdHkoKSkgewotCQkJCQkJLy8gc29tZSBjb21wb25lbnRzIHdpdGggc3RhdGljIHJlZmVyZW5jZXMgd2VyZSBkaXNwb3NlZC4gVHJ5IHRvIGJ1aWxkIHRoZW0gYWdhaW4KLQkJCQkJCS8vIGdldCBsaXN0IG9mIG5ld2x5IHNhdGlzZmllZCBTQ1BzIGFuZCBidWlsZCB0aGVtCi0JCQkJCQlyZXNvbHZlZENvbXBvbmVudHMgPSBnZXRDb21wb25lbnRzVG9CdWlsZCgpOwotCQkJCQl9Ci0JCQkJfQotCi0JCQkJaW5zdGFuY2VQcm9jZXNzLmR5bmFtaWNVbkJpbmQoKEhhc2h0YWJsZSkgdGFyZ2V0KTsgLy8gZG8gc3luY2hyb25vdXMgdW5iaW5kCi0KLQkJCQlpZiAocmVzb2x2ZWRDb21wb25lbnRzICE9IG51bGwgJiYgIXJlc29sdmVkQ29tcG9uZW50cy5pc0VtcHR5KCkpIHsKLQkJCQkJaW5zdGFuY2VQcm9jZXNzLmJ1aWxkQ29tcG9uZW50cyhyZXNvbHZlZENvbXBvbmVudHMsIGZhbHNlKTsKLQkJCQl9Ci0KLQkJCQlyZXR1cm47Ci0KLQkJCWNhc2UgU2VydmljZUV2ZW50Lk1PRElGSUVEIDoKLQkJCQlzeW5jaHJvbml6ZWQgKHN5bmNMb2NrKSB7Ci0JCQkJCWlmIChzY3BFbmFibGVkLmlzRW1wdHkoKSkKLQkJCQkJCXJldHVybjsgLy8gY2hlY2sgZm9yIGFueSBlbmFibGVkIGNvbmZpZ3VyYXRpb25zCi0KLQkJCQkJLy8gY2hlY2sgZm9yIG5ld2x5IHVuc2F0aXNmaWVkIGNvbXBvbmVudHMgYW5kIHN5bmNocm9ub3VzbHkKLQkJCQkJLy8gZGlzcG9zZSB0aGVtCi0JCQkJCW5ld2x5VW5zYXRpc2ZpZWRTQ1BzID0gc2VsZWN0TmV3bHlVbnNhdGlzZmllZChldmVudC5nZXRTZXJ2aWNlUmVmZXJlbmNlKCkpOwotCQkJCX0KLQotCQkJCWlmICghbmV3bHlVbnNhdGlzZmllZFNDUHMuaXNFbXB0eSgpKSB7Ci0JCQkJCWluc3RhbmNlUHJvY2Vzcy5kaXNwb3NlSW5zdGFuY2VzKG5ld2x5VW5zYXRpc2ZpZWRTQ1BzLCBDb21wb25lbnRDb25zdGFudHMuREVBQ1RJVkFUSU9OX1JFQVNPTl9SRUZFUkVOQ0UpOwotCQkJCX0KLQotCQkJCXN5bmNocm9uaXplZCAoc3luY0xvY2spIHsKLQkJCQkJLy9jaGVjayBmb3IgY29tcG9uZW50cyB3aXRoIHN0YXRpYyByZWZlcmVuY2UgdG8gdGhpcyBzZXJ2aWNlCi0JCQkJCWNvbXBvbmVudHNUb0Rpc3Bvc2UgPSBzZWxlY3RTdGF0aWNVbkJpbmQoc2NwRW5hYmxlZCwgZXZlbnQuZ2V0U2VydmljZVJlZmVyZW5jZSgpLCB0cnVlKTsKLQkJCQl9Ci0KLQkJCQlpZiAoY29tcG9uZW50c1RvRGlzcG9zZSAhPSBudWxsKSB7Ci0JCQkJCWluc3RhbmNlUHJvY2Vzcy5kaXNwb3NlSW5zdGFuY2VzKGNvbXBvbmVudHNUb0Rpc3Bvc2UsIENvbXBvbmVudENvbnN0YW50cy5ERUFDVElWQVRJT05fUkVBU09OX1JFRkVSRU5DRSk7Ci0JCQkJfQotCi0JCQkJc3luY2hyb25pemVkIChzeW5jTG9jaykgewotCQkJCQkvL2NoZWNrIGZvciBhbnkgc3RhdGljIHJlZmVyZW5jZXMgd2l0aCBwb2xpY3kgb3B0aW9uICJncmVlZHkiIHRoYXQgbmVlZCB0byBiZSBib3VuZCB3aXRoIHRoaXMgc2VydmljZSByZWZlcmVuY2UKLQkJCQkJY29tcG9uZW50c1RvRGlzcG9zZSA9IHNlbGVjdFN0YXRpY0JpbmQoc2NwRW5hYmxlZCwgZXZlbnQuZ2V0U2VydmljZVJlZmVyZW5jZSgpKTsKLQkJCQl9Ci0KLQkJCQlpZiAoY29tcG9uZW50c1RvRGlzcG9zZSAhPSBudWxsKSB7Ci0JCQkJCS8vZGlzcG9zZSBpbnN0YW5jZXMgb2YgY29tcG9uZW50cyB3aXRoIHN0YXRpYyByZWZlcmVuY2UgdGhhdCBuZWVkcyB0byBiZSBib3VuZCB3aXRoIHRoZSBtb2RpZmllZCBzZXJ2aWNlIHJlZmVyZW5jZQotCQkJCQlpbnN0YW5jZVByb2Nlc3MuZGlzcG9zZUluc3RhbmNlcyhjb21wb25lbnRzVG9EaXNwb3NlLCBDb21wb25lbnRDb25zdGFudHMuREVBQ1RJVkFUSU9OX1JFQVNPTl9SRUZFUkVOQ0UpOwotCQkJCX0KLQotCQkJCUhhc2h0YWJsZSByZWZlcmVuY2VzVG9VcGRhdGUgPSBudWxsOwotCQkJCXN5bmNocm9uaXplZCAoc3luY0xvY2spIHsKLQkJCQkJLy8gZHluYW1pYyB1bmJpbmQKLQkJCQkJLy8gY2hlY2sgZWFjaCBzYXRpc2ZpZWQgc2NwIC0gZG8gd2UgbmVlZCB0byB1bmJpbmQKLQkJCQkJdGFyZ2V0ID0gc2VsZWN0RHluYW1pY1VuQmluZChzY3BFbmFibGVkLCBldmVudC5nZXRTZXJ2aWNlUmVmZXJlbmNlKCksIHRydWUpOwotCi0JCQkJCS8vY2hlY2sgcmVmZXJlbmNlcyB0aGF0IG5lZWQgdG8gYmUgdXBkYXRlZAotCQkJCQlyZWZlcmVuY2VzVG9VcGRhdGUgPSBzZWxlY3RSZWZlcmVuY2VzVG9VcGRhdGUoc2NwRW5hYmxlZCwgZXZlbnQuZ2V0U2VydmljZVJlZmVyZW5jZSgpKTsKLQkJCQl9Ci0KLQkJCQlpZiAodGFyZ2V0ICE9IG51bGwpIHsKLQkJCQkJaW5zdGFuY2VQcm9jZXNzLmR5bmFtaWNVbkJpbmQoKEhhc2h0YWJsZSkgdGFyZ2V0KTsKLQkJCQl9Ci0JCQkJaWYgKHJlZmVyZW5jZXNUb1VwZGF0ZSAhPSBudWxsKSB7Ci0JCQkJCWluc3RhbmNlUHJvY2Vzcy5yZWZlcmVuY2VQcm9wZXJ0aWVzVXBkYXRlZChyZWZlcmVuY2VzVG9VcGRhdGUpOwotCQkJCX0KLQotCQkJCXN5bmNocm9uaXplZCAoc3luY0xvY2spIHsKLQkJCQkJLy8gZHluYW1pYyBiaW5kCi0JCQkJCXRhcmdldCA9IHNlbGVjdER5bmFtaWNCaW5kKHNjcEVuYWJsZWQsIGV2ZW50LmdldFNlcnZpY2VSZWZlcmVuY2UoKSk7Ci0KLQkJCQkJLy8gZ2V0IGxpc3Qgb2YgbmV3bHkgc2F0aXNmaWVkIFNDUHMgYW5kIGJ1aWxkIHRoZW0KLQkJCQkJcmVzb2x2ZWRDb21wb25lbnRzID0gZ2V0Q29tcG9uZW50c1RvQnVpbGQoKTsKLQkJCQl9Ci0KLQkJCQlpZiAodGFyZ2V0ICE9IG51bGwpIHsKLQkJCQkJVmVjdG9yIHVuYm91bmRSZWZzID0gaW5zdGFuY2VQcm9jZXNzLmR5bmFtaWNCaW5kKChWZWN0b3IpIHRhcmdldCk7Ci0JCQkJCWlmICh1bmJvdW5kUmVmcyAhPSBudWxsKSB7Ci0JCQkJCQkvLyBwdXQgZGVsYXllZCBkeW5hbWljIGJpbmRzIG9uIHRoZSBxdWV1ZQotCQkJCQkJLy8gKHRoaXMgaXMgdXNlZCB0byBoYW5kbGUgY2xhc3MgY2lyY3VsYXJpdHkgZXJyb3JzKQotCQkJCQkJbWdyLmVucXVldWVXb3JrKHRoaXMsIFJlc29sdmVyLkRZTkFNSUNCSU5ELCB1bmJvdW5kUmVmcywgZmFsc2UpOwotCQkJCQl9Ci0JCQkJfQotCQkJCWlmICghcmVzb2x2ZWRDb21wb25lbnRzLmlzRW1wdHkoKSkgewotCQkJCQlpbnN0YW5jZVByb2Nlc3MuYnVpbGRDb21wb25lbnRzKHJlc29sdmVkQ29tcG9uZW50cywgZmFsc2UpOwotCQkJCX0KLQkJfQotCX0KLQotCXB1YmxpYyB2b2lkIGJ1aWxkTmV3bHlTYXRpc2ZpZWQoYm9vbGVhbiBjaGVja0ZvckRlcGVuZGVuY3lDeWNsZXMpIHsKLQkJVmVjdG9yIHJlc29sdmVkQ29tcG9uZW50czsKLQkJc3luY2hyb25pemVkIChzeW5jTG9jaykgewotCQkJaWYgKGNoZWNrRm9yRGVwZW5kZW5jeUN5Y2xlcykgewotCQkJCWZpbmREZXBlbmRlbmN5Q3ljbGVzKCk7Ci0JCQl9Ci0JCQlyZXNvbHZlZENvbXBvbmVudHMgPSBnZXRDb21wb25lbnRzVG9CdWlsZCgpOwotCQl9Ci0KLQkJaWYgKCFyZXNvbHZlZENvbXBvbmVudHMuaXNFbXB0eSgpKSB7Ci0JCQlpbnN0YW5jZVByb2Nlc3MuYnVpbGRDb21wb25lbnRzKHJlc29sdmVkQ29tcG9uZW50cywgZmFsc2UpOwotCQl9Ci0JfQotCi0JcHJpdmF0ZSBWZWN0b3IgZ2V0Q29tcG9uZW50c1RvQnVpbGQoKSB7Ci0JCVZlY3RvciByZXNvbHZlZENvbXBvbmVudHMgPSByZXNvbHZlRWxpZ2libGUoKTsKLQkJLy8gc2VsZWN0IHRoZSBzYXRpc2ZpZWQgY29tcG9uZW50cyBvbmx5Ci0JCVNlcnZpY2VDb21wb25lbnRQcm9wIHNjcDsKLQkJZm9yIChpbnQgaSA9IHJlc29sdmVkQ29tcG9uZW50cy5zaXplKCkgLSAxOyBpID49IDA7IGktLSkgewotCQkJc2NwID0gKFNlcnZpY2VDb21wb25lbnRQcm9wKSByZXNvbHZlZENvbXBvbmVudHMuZWxlbWVudEF0KGkpOwotCQkJaWYgKHNjcC5nZXRTdGF0ZSgpICE9IENvbXBvbmVudC5TVEFURV9VTlNBVElTRklFRCkgewotCQkJCXJlc29sdmVkQ29tcG9uZW50cy5yZW1vdmVFbGVtZW50QXQoaSk7Ci0JCQl9Ci0JCX0KLQkJcmV0dXJuIHJlc29sdmVkQ29tcG9uZW50czsKLQl9Ci0KLQkvKioKLQkgKiBOb3RpZmllcyB0aGUgcmVzb2x2ZXIgdGhhdCBhIGNvbXBvbmVudCBoYXMgYmVlbiBkaXNwb3NlZC4gCi0JICogSXQgc2hvdWxkIGFjY29yZGluZ2x5IHVwZGF0ZSBpdHMgZGF0YSBzdHJ1Y3R1cmVzIGlmIG5lZWRlZAotCSAqCi0JICoqLwotCXB1YmxpYyB2b2lkIGNvbXBvbmVudERpc3Bvc2VkKFNlcnZpY2VDb21wb25lbnRQcm9wIHNjcCkgewotCQkvLwotCX0KLQotCXByaXZhdGUgVmVjdG9yIHJlc29sdmVFbGlnaWJsZSgpIHsKLQkJdHJ5IHsKLQkJCVZlY3RvciBlbmFibGVkU0NQcyA9IChWZWN0b3IpIHNjcEVuYWJsZWQuY2xvbmUoKTsKLQkJCWZvciAoaW50IGsgPSBlbmFibGVkU0NQcy5zaXplKCkgLSAxOyBrID49IDA7IGstLSkgewotCQkJCVNlcnZpY2VDb21wb25lbnRQcm9wIHNjcCA9IChTZXJ2aWNlQ29tcG9uZW50UHJvcCkgZW5hYmxlZFNDUHMuZWxlbWVudEF0KGspOwotCQkJCXRyeSB7Ci0JCQkJCVZlY3RvciByZWZzID0gc2NwLnJlZmVyZW5jZXM7Ci0JCQkJCWZvciAoaW50IGkgPSAwOyByZWZzICE9IG51bGwgJiYgaSA8IHJlZnMuc2l6ZSgpOyBpKyspIHsKLQkJCQkJCS8vIExvb3AgdGhvdWdoIGFsbCB0aGUgcmVmZXJlbmNlcyAoZGVwZW5kZW5jaWVzKWZvciBhIGdpdmVuCi0JCQkJCQkvLyBzY3AuIElmIGEgZGVwZW5kZW5jeSBpcyBub3QgbWV0LCByZW1vdmUgaXQncyBhc3NvY2lhdGVkIHNjcCBhbmQKLQkJCQkJCS8vIHJlLXJ1biB0aGUgYWxnb3JpdGhtCi0JCQkJCQlSZWZlcmVuY2UgcmVmZXJlbmNlID0gKFJlZmVyZW5jZSkgcmVmcy5lbGVtZW50QXQoaSk7Ci0JCQkJCQlpZiAocmVmZXJlbmNlICE9IG51bGwpIHsKLQkJCQkJCQlib29sZWFuIHJlc29sdmVkID0gIXJlZmVyZW5jZS5pc1JlcXVpcmVkRm9yKHNjcC5zZXJ2aWNlQ29tcG9uZW50KSB8fCByZWZlcmVuY2UuaGFzUHJvdmlkZXJzKHRoaXMuc2VydmljZVJlZmVyZW5jZVRhYmxlKTsKLQotCQkJCQkJCWlmICghcmVzb2x2ZWQpIHsKLQkJCQkJCQkJaWYgKEFjdGl2YXRvci5ERUJVRykgewotCQkJCQkJCQkJQWN0aXZhdG9yLmxvZy5kZWJ1ZygiUmVzb2x2ZXIucmVzb2x2ZUVsaWdpYmxlKCk6IHJlZmVyZW5jZSAnIiArIHJlZmVyZW5jZS5yZWZlcmVuY2UubmFtZSArICInIG9mIGNvbXBvbmVudCAnIiArIHNjcC5uYW1lICsgIicgaXMgbm90IHJlc29sdmVkIiwgbnVsbCk7IC8vJE5PTi1OTFMtMSQgLy8kTk9OLU5MUy0yJCAvLyROT04tTkxTLTMkCi0JCQkJCQkJCX0KLQkJCQkJCQkJZW5hYmxlZFNDUHMucmVtb3ZlRWxlbWVudEF0KGspOwotCQkJCQkJCQlicmVhazsKLQkJCQkJCQl9Ci0JCQkJCQl9Ci0JCQkJCX0KLQkJCQl9IGNhdGNoIChJbGxlZ2FsU3RhdGVFeGNlcHRpb24gaXNlKSB7Ci0JCQkJCS8vdGhlIGJ1bmRsZSBvZiB0aGUgc2NwIGlzIHByb2JhYmx5IGFscmVhZHkgdW5pbnN0YWxsZWQKLQkJCQkJc2NwRW5hYmxlZC5yZW1vdmVFbGVtZW50KHNjcCk7Ci0JCQkJCWVuYWJsZWRTQ1BzLnJlbW92ZUVsZW1lbnRBdChrKTsKLQkJCQkJY29udGludWU7Ci0JCQkJfQotCQkJCS8vIGNoZWNrIGlmIHRoZSBidW5kbGUgcHJvdmlkaW5nIHRoZSBzZXJ2aWNlIGhhcyBwZXJtaXNzaW9uIHRvCi0JCQkJLy8gcmVnaXN0ZXIgdGhlIHByb3ZpZGVkIGludGVyZmFjZShzKQotCQkJCWlmIChzY3Auc2VydmljZUNvbXBvbmVudC5wcm92aWRlcyAhPSBudWxsICYmIFN5c3RlbS5nZXRTZWN1cml0eU1hbmFnZXIoKSAhPSBudWxsKSB7Ci0JCQkJCVN0cmluZ1tdIHByb3ZpZGVzID0gc2NwLnNlcnZpY2VDb21wb25lbnQucHJvdmlkZXM7Ci0JCQkJCWJvb2xlYW4gaGFzUGVybWlzc2lvbiA9IHRydWU7Ci0JCQkJCWludCBpID0gMDsKLQkJCQkJZm9yICg7IGkgPCBwcm92aWRlcy5sZW5ndGg7IGkrKykgewotCQkJCQkJLy8gbWFrZSBzdXJlIGJ1bmRsZSBoYXMgcGVybWlzc2lvbiB0byByZWdpc3RlciB0aGUgc2VydmljZQotCQkJCQkJdHJ5IHsKLQkJCQkJCQlpZiAoIXNjcC5iYy5nZXRCdW5kbGUoKS5oYXNQZXJtaXNzaW9uKG5ldyBTZXJ2aWNlUGVybWlzc2lvbihwcm92aWRlc1tpXSwgU2VydmljZVBlcm1pc3Npb24uUkVHSVNURVIpKSkgewotCQkJCQkJCQloYXNQZXJtaXNzaW9uID0gZmFsc2U7Ci0JCQkJCQkJCWJyZWFrOwotCQkJCQkJCX0KLQkJCQkJCX0gY2F0Y2ggKElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiBpc2UpIHsKLQkJCQkJCQkvLyB0aGUgYnVuZGxlIG9mIHRoZSBzZXJ2aWNlIGNvbXBvbmVudCBpcyB1bmluc3RhbGxlZAotCQkJCQkJCS8vIFN5c3RlbS5vdXQucHJpbnRsbigiSWxsZWdhbFN0YXRlRXhjZXB0aW9uIG9jY3VyZWQKLQkJCQkJCQkvLyB3aGlsZSBwcm9jZXNzaW5nIGNvbXBvbmVudCAiK3NjcCk7Ci0JCQkJCQkJLy8gaXNlLnByaW50U3RhY2tUcmFjZSgpOwotCQkJCQkJCWhhc1Blcm1pc3Npb24gPSBmYWxzZTsKLQkJCQkJCQlicmVhazsKLQkJCQkJCX0gY2F0Y2ggKFRocm93YWJsZSB0KSB7Ci0JCQkJCQkJLy8gU3lzdGVtLm91dC5wcmludGxuKCJFeGNlcHRpb24gb2NjdXJlZCBwcm9jZXNzaW5nCi0JCQkJCQkJLy8gY29tcG9uZW50ICIrc2NwKTsKLQkJCQkJCQkvLyB0LnByaW50U3RhY2tUcmFjZSgpOwotCQkJCQkJCWhhc1Blcm1pc3Npb24gPSBmYWxzZTsKLQkJCQkJCQlicmVhazsKLQkJCQkJCX0KLQkJCQkJfQotCQkJCQlpZiAoIWhhc1Blcm1pc3Npb24pIHsKLQkJCQkJCUFjdGl2YXRvci5sb2cobnVsbCwgTG9nU2VydmljZS5MT0dfV0FSTklORywgTkxTLmJpbmQoTWVzc2FnZXMuQ09NUE9ORU5UX0xBQ0tTX0FQUFJPUFJJQVRFX1BFUk1JU1NJT05TLCBzY3AubmFtZSwgcHJvdmlkZXNbaV0pLCBudWxsKTsKLQkJCQkJCXJlbW92ZUVuYWJsZWRTQ1Aoc2NwKTsKLQkJCQkJCWVuYWJsZWRTQ1BzLnJlbW92ZUVsZW1lbnRBdChrKTsKLQkJCQkJCWNvbnRpbnVlOwotCQkJCQl9Ci0JCQkJfQotCQkJCWlmICghc2NwLmlzQnVpbHQoKSAmJiAhKHNjcC5nZXRTdGF0ZSgpID09IENvbXBvbmVudC5TVEFURV9ERUFDVElWQVRJTkcpKSB7Ci0JCQkJCXNjcC5zZXRTdGF0ZShDb21wb25lbnQuU1RBVEVfVU5TQVRJU0ZJRUQpOwotCQkJCX0KLQkJCX0KLQotCQkJaWYgKEFjdGl2YXRvci5ERUJVRykgewotCQkJCUFjdGl2YXRvci5sb2cuZGVidWcoIlJlc29sdmVyLnJlc29sdmVFbGlnaWJsZSgpOiByZXNvbHZlZCBjb21wb25lbnRzID0gIiArIGVuYWJsZWRTQ1BzLnRvU3RyaW5nKCksIG51bGwpOyAvLyROT04tTkxTLTEkCi0JCQl9Ci0JCQlyZXR1cm4gZW5hYmxlZFNDUHM7Ci0JCX0gY2F0Y2ggKFRocm93YWJsZSBlKSB7Ci0JCQlBY3RpdmF0b3IubG9nKG51bGwsIExvZ1NlcnZpY2UuTE9HX0VSUk9SLCBNZXNzYWdlcy5VTkVYUEVDVEVEX0VYQ0VQVElPTiwgZSk7Ci0JCQlyZXR1cm4gbmV3IFZlY3RvcigpOwotCQl9Ci0JfQotCi0JcHJpdmF0ZSBWZWN0b3Igc2VsZWN0TmV3bHlVbnNhdGlzZmllZChTZXJ2aWNlUmVmZXJlbmNlIHNlcnZpY2VSZWYpIHsKLQkJdHJ5IHsKLQkJCVZlY3RvciByZXN1bHQgPSAoVmVjdG9yKSBzY3BFbmFibGVkLmNsb25lKCk7Ci0JCQlmb3IgKGludCBrID0gcmVzdWx0LnNpemUoKSAtIDE7IGsgPj0gMDsgay0tKSB7Ci0JCQkJdHJ5IHsKLQkJCQkJU2VydmljZUNvbXBvbmVudFByb3Agc2NwID0gKFNlcnZpY2VDb21wb25lbnRQcm9wKSByZXN1bHQuZWxlbWVudEF0KGspOwotCQkJCQlWZWN0b3IgcmVmcyA9IHNjcC5yZWZlcmVuY2VzOwotCQkJCQlib29sZWFuIHRvRGlzcG9zZSA9IGZhbHNlOwotCQkJCQlmb3IgKGludCBpID0gMDsgcmVmcyAhPSBudWxsICYmIGkgPCByZWZzLnNpemUoKTsgaSsrKSB7Ci0JCQkJCQkvLyBMb29wIHRob3VnaCBhbGwgdGhlIHJlZmVyZW5jZXMgKGRlcGVuZGVuY2llcylmb3IgYSBnaXZlbgotCQkJCQkJLy8gc2NwLiBJZiBhIGRlcGVuZGVuY3kgaXMgbm90IG1ldCwgcmVtb3ZlIGl0J3MgYXNzb2NpYXRlZAotCQkJCQkJLy8gc2NwIGFuZCByZS1ydW4gdGhlIGFsZ29yaXRobQotCQkJCQkJUmVmZXJlbmNlIHJlZmVyZW5jZSA9IChSZWZlcmVuY2UpIHJlZnMuZWxlbWVudEF0KGkpOwotCQkJCQkJaWYgKHJlZmVyZW5jZSAhPSBudWxsKSB7Ci0JCQkJCQkJaWYgKHNlcnZpY2VSZWYgIT0gbnVsbCAmJiByZWZlcmVuY2UucmVmZXJlbmNlLmJpbmQgIT0gbnVsbCAmJiBzY3AuZ2V0U3RhdGUoKSA9PSBDb21wb25lbnQuU1RBVEVfQUNUSVZFICYmICEocmVmZXJlbmNlLmR5bmFtaWNVbmJpbmRSZWZlcmVuY2Uoc2VydmljZVJlZikgfHwgcmVmZXJlbmNlLnN0YXRpY1VuYmluZFJlZmVyZW5jZShzZXJ2aWNlUmVmKSkpIHsKLQkJCQkJCQkJLy9tYWtlIHF1aWNrIHRlc3QgLSB0aGUgc2VydmljZSByZWZlcmVuY2UgaXMgbm90IGJvdW5kIHRvIHRoZSBjdXJyZW50IGNvbXBvbmVudCByZWZlcmVuY2UKLQkJCQkJCQkJY29udGludWU7Ci0JCQkJCQkJfQotCQkJCQkJCWlmIChzZXJ2aWNlUmVmICE9IG51bGwgJiYgIWlzUG9zc2libGVNYXRjaChyZWZlcmVuY2UsIHNlcnZpY2VSZWYpKSB7Ci0JCQkJCQkJCS8vIHRoZSBzZXJ2aWNlIHJlZmVyZW5jZSBpcyBub3QgYSBwb3NzaWJsZSBtYXRjaC4gU2tpcHBpbmcgZnVydGhlciBjaGVja3MgCi0JCQkJCQkJCWNvbnRpbnVlOwotCQkJCQkJCX0KLQkJCQkJCQlib29sZWFuIHJlc29sdmVkID0gIXJlZmVyZW5jZS5pc1JlcXVpcmVkRm9yKHNjcC5zZXJ2aWNlQ29tcG9uZW50KSB8fCByZWZlcmVuY2UuaGFzUHJvdmlkZXJzKHRoaXMuc2VydmljZVJlZmVyZW5jZVRhYmxlKTsKLQotCQkJCQkJCWlmICghcmVzb2x2ZWQgJiYgc2NwLmlzQnVpbHQoKSkgewotCQkJCQkJCQlpZiAoQWN0aXZhdG9yLkRFQlVHKSB7Ci0JCQkJCQkJCQlBY3RpdmF0b3IubG9nLmRlYnVnKCJSZXNvbHZlci5zZWxlY3ROZXdseVVuc2F0aXNmaWVkKCk6IHJlZmVyZW5jZSAnIiArIHJlZmVyZW5jZS5yZWZlcmVuY2UubmFtZSArICInIG9mIGNvbXBvbmVudCAnIiArIHNjcC5uYW1lICsgIicgaXMgbm90IHJlc29sdmVkIiwgbnVsbCk7IC8vJE5PTi1OTFMtMSQgLy8kTk9OLU5MUy0yJCAvLyROT04tTkxTLTMkCi0JCQkJCQkJCX0KLQkJCQkJCQkJdG9EaXNwb3NlID0gdHJ1ZTsKLQkJCQkJCQkJYnJlYWs7Ci0JCQkJCQkJfQotCQkJCQkJfQotCQkJCQl9Ci0JCQkJCWlmICghdG9EaXNwb3NlKSB7Ci0JCQkJCQlyZXN1bHQucmVtb3ZlRWxlbWVudEF0KGspOwotCQkJCQl9Ci0JCQkJfSBjYXRjaCAoSWxsZWdhbFN0YXRlRXhjZXB0aW9uIGlzZSkgewotCQkJCQkvL3RoZSBidW5kbGUgb2YgdGhlIHNjcCBpcyBwcm9iYWJseSBhbHJlYWR5IHVuaW5zdGFsbGVkCi0JCQkJCXNjcEVuYWJsZWQucmVtb3ZlRWxlbWVudChyZXN1bHQuZWxlbWVudEF0KGspKTsKLQkJCQkJcmVzdWx0LnJlbW92ZUVsZW1lbnRBdChrKTsKLQkJCQkJY29udGludWU7Ci0JCQkJfQotCQkJfQotCQkJcmV0dXJuIHJlc3VsdDsKLQkJfSBjYXRjaCAoVGhyb3dhYmxlIGUpIHsKLQkJCUFjdGl2YXRvci5sb2cobnVsbCwgTG9nU2VydmljZS5MT0dfRVJST1IsIE1lc3NhZ2VzLlVORVhQRUNURURfRVhDRVBUSU9OLCBlKTsKLQkJCXJldHVybiBuZXcgVmVjdG9yKDEpOwotCQl9Ci0JfQotCi0JcHJpdmF0ZSBib29sZWFuIGlzUG9zc2libGVNYXRjaChSZWZlcmVuY2UgcmVmZXJlbmNlLCBTZXJ2aWNlUmVmZXJlbmNlIHNlcnZpY2VSZWYpIHsKLQkJU3RyaW5nW10gc2VydmljZU5hbWVzID0gKFN0cmluZ1tdKSBzZXJ2aWNlUmVmLmdldFByb3BlcnR5KENvbnN0YW50cy5PQkpFQ1RDTEFTUyk7Ci0JCWJvb2xlYW4gaGFzTmFtZSA9IGZhbHNlOwotCQlmb3IgKGludCBpID0gMDsgaSA8IHNlcnZpY2VOYW1lcy5sZW5ndGg7IGkrKykgewotCQkJaWYgKHNlcnZpY2VOYW1lc1tpXS5lcXVhbHMocmVmZXJlbmNlLmludGVyZmFjZU5hbWUpKSB7Ci0JCQkJaGFzTmFtZSA9IHRydWU7Ci0JCQkJYnJlYWs7Ci0JCQl9Ci0JCX0KLQkJaWYgKCFoYXNOYW1lKSB7Ci0JCQlyZXR1cm4gZmFsc2U7Ci0JCX0KLQkJLy8gY2hlY2sgdGFyZ2V0IGZpbHRlcgotCQl0cnkgewotCQkJRmlsdGVyIGZpbHRlciA9IEZyYW1ld29ya1V0aWwuY3JlYXRlRmlsdGVyKHJlZmVyZW5jZS50YXJnZXQpOwotCQkJaWYgKCFmaWx0ZXIubWF0Y2goc2VydmljZVJlZikpIHsKLQkJCQlyZXR1cm4gZmFsc2U7Ci0JCQl9Ci0JCX0gY2F0Y2ggKEludmFsaWRTeW50YXhFeGNlcHRpb24gZSkgewotCQkJcmV0dXJuIGZhbHNlOwotCQl9Ci0JCXJldHVybiB0cnVlOwotCX0KLQotCS8vIC0tIGJlZ2luICpkaXNhYmxlKiBjb21wb25lbnQgcm91dGluZXMKLQkvKioKLQkgKiBEaXNhYmxlIGxpc3Qgb2YgQ29tcG9uZW50RGVzY3JpcHRpb25zCi0JICogCi0JICogZ2V0IGFsbCBDRCtQJ3MgZnJvbSBDRDpDRCtQIE1hcCBnZXQgaW5zdGFuY2VzIGZyb20gQ0QrUDpsaXN0IG9mIGluc3RhbmNlCi0JICogKDE6bikgbWFwCi0JICogCi0JICogU3RyaXAgb3V0IG9mIE1hcCBhbGwgQ0QrUCdzIENvbnRpbnVlIHRvIHB1bGwgc3RyaW5nIGNoZWNrIGVhY2ggUmVmCi0JICogZGVwZW5kZW5jeSBhbmQgY29udGludWUgdG8gcHVsbCBvdXQgQ0QrUCdzIGlmIHRoZXkgYmVjb21lIG5vdCBlbGlnaWJsZQotCSAqIFRoZW4gY2FsbCBSZXNvbHZlciB0byByZS1yZXNvbHZlCi0JICogCi0JICogQHBhcmFtIGNvbXBvbmVudERlc2NyaXB0aW9ucwotCSAqLwotCXZvaWQgZGlzYWJsZUNvbXBvbmVudHMoVmVjdG9yIGNvbXBvbmVudERlc2NyaXB0aW9ucywgaW50IGRlYWN0aXZhdGVSZWFzb24pIHsKLQkJbG9uZyBzdGFydCA9IDBsOwotCQlpZiAoQWN0aXZhdG9yLlBFUkYpIHsKLQkJCXN0YXJ0ID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCk7Ci0JCX0KLQotCQlTZXJ2aWNlQ29tcG9uZW50UHJvcCBzY3A7Ci0JCVNlcnZpY2VDb21wb25lbnQgY29tcG9uZW50OwotCi0JCVZlY3RvciByZW1vdmVMaXN0ID0gbnVsbDsKLQotCQkvLyBSZWNlaXZlZCBsaXN0IG9mIENEcyB0byBkaXNhYmxlCi0JCWlmIChjb21wb25lbnREZXNjcmlwdGlvbnMgIT0gbnVsbCkgewotCQkJZm9yIChpbnQgaSA9IDA7IGkgPCBjb21wb25lbnREZXNjcmlwdGlvbnMuc2l6ZSgpOyBpKyspIHsKLQkJCQkvLyBnZXQgdGhlIGZpcnN0IENECi0JCQkJY29tcG9uZW50ID0gKFNlcnZpY2VDb21wb25lbnQpIGNvbXBvbmVudERlc2NyaXB0aW9ucy5lbGVtZW50QXQoaSk7Ci0JCQkJY29tcG9uZW50LmVuYWJsZWQgPSBmYWxzZTsKLQkJCQljb21wb25lbnQuc2V0U3RhdGUoQ29tcG9uZW50LlNUQVRFX0RJU0FCTEVEKTsKLQkJCQlpZiAoQWN0aXZhdG9yLkRFQlVHKSB7Ci0JCQkJCUFjdGl2YXRvci5sb2cuZGVidWcoIlJlc29sdmVyLmRpc2FibGVDb21wb25lbnRzKCkgIiArIGNvbXBvbmVudC5uYW1lLCBudWxsKTsgLy8kTk9OLU5MUy0xJAotCQkJCX0KLQotCQkJCS8vIHRoZW4gZ2V0IHRoZSBsaXN0IG9mIFNDUHMgZm9yIHRoaXMgQ0QKLQkJCQlWZWN0b3Igc2NwTGlzdCA9IGNvbXBvbmVudC5jb21wb25lbnRQcm9wczsKLQkJCQlpZiAoc2NwTGlzdCAhPSBudWxsKSB7Ci0JCQkJCWZvciAoaW50IGl0ZXIgPSAwOyBpdGVyIDwgc2NwTGlzdC5zaXplKCk7IGl0ZXIrKykgewotCQkJCQkJc2NwID0gKFNlcnZpY2VDb21wb25lbnRQcm9wKSBzY3BMaXN0LmVsZW1lbnRBdChpdGVyKTsKLQkJCQkJCWlmIChyZW1vdmVMaXN0ID09IG51bGwpIHsKLQkJCQkJCQlyZW1vdmVMaXN0ID0gbmV3IFZlY3RvcigpOwotCQkJCQkJfQotCQkJCQkJcmVtb3ZlTGlzdC5hZGRFbGVtZW50KHNjcCk7Ci0JCQkJCX0KLQkJCQl9Ci0JCQkJaWYgKHJlbW92ZUxpc3QgIT0gbnVsbCkgewotCQkJCQlkaXNwb3NlQ29tcG9uZW50Q29uZmlncyhyZW1vdmVMaXN0LCBkZWFjdGl2YXRlUmVhc29uKTsKLQkJCQkJcmVtb3ZlTGlzdC5yZW1vdmVBbGxFbGVtZW50cygpOwotCQkJCX0KLQkJCQlpZiAoY29tcG9uZW50LmNvbXBvbmVudFByb3BzICE9IG51bGwpIHsKLQkJCQkJZm9yIChpbnQgaiA9IDA7IGogPCBjb21wb25lbnQuY29tcG9uZW50UHJvcHMuc2l6ZSgpOyBqKyspIHsKLQkJCQkJCXNjcCA9IChTZXJ2aWNlQ29tcG9uZW50UHJvcCkgY29tcG9uZW50LmNvbXBvbmVudFByb3BzLmVsZW1lbnRBdChqKTsKLQkJCQkJCXNjcC5zZXRTdGF0ZShDb21wb25lbnQuU1RBVEVfRElTUE9TRUQpOwotCQkJCQl9Ci0JCQkJCWNvbXBvbmVudC5jb21wb25lbnRQcm9wcy5yZW1vdmVBbGxFbGVtZW50cygpOwotCQkJCX0KLQkJCX0KLQkJfQotCi0JCWlmIChBY3RpdmF0b3IuUEVSRikgewotCQkJc3RhcnQgPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKSAtIHN0YXJ0OwotCQkJQWN0aXZhdG9yLmxvZy5pbmZvKCJbRFMgcGVyZl0gIiArIEludGVnZXIudG9TdHJpbmcoY29tcG9uZW50RGVzY3JpcHRpb25zLnNpemUoKSkgKyAiIENvbXBvbmVudHMgZGlzYWJsZWQgZm9yICIgKyBMb25nLnRvU3RyaW5nKHN0YXJ0KSArICJtcyIpOyAvLyROT04tTkxTLTEkLy8kTk9OLU5MUy0yJCAvLyROT04tTkxTLTMkCi0JCX0KLQl9Ci0KLQlwdWJsaWMgdm9pZCBkaXNwb3NlQ29tcG9uZW50Q29uZmlncyhWZWN0b3Igc2NwcywgaW50IGRlYWN0aXZhdGVSZWFzb24pIHsKLQkJLy8gdW5yZWdpc3RlciwgZGVhY3RpdmF0ZSwgYW5kIHVuYmluZAotCQlzeW5jaHJvbml6ZWQgKHN5bmNMb2NrKSB7Ci0JCQlyZW1vdmVBbGwoc2NwRW5hYmxlZCwgc2Nwcyk7Ci0JCX0KLQkJaW5zdGFuY2VQcm9jZXNzLmRpc3Bvc2VJbnN0YW5jZXMoc2NwcywgZGVhY3RpdmF0ZVJlYXNvbik7Ci0JfQotCi0JLy8gLS0gZW5kICpzZXJ2aWNlIGxpc3RlbmVyKgotCi0JcHVibGljIHZvaWQgcGVyZm9ybVdvcmsoaW50IHdvcmtBY3Rpb24sIE9iamVjdCB3b3JrT2JqZWN0KSB7Ci0JCXRyeSB7Ci0JCQlpZiAoQWN0aXZhdG9yLkRFQlVHKSB7Ci0JCQkJU3RyaW5nIHdvcmsgPSBXT1JLX1RJVExFU1t3b3JrQWN0aW9uIC0gMV07Ci0JCQkJQWN0aXZhdG9yLmxvZy5kZWJ1ZygiUmVzb2x2ZXIucGVyZm9ybVdvcmsoKTogIiArIHdvcmsgKyB3b3JrT2JqZWN0LCBudWxsKTsgLy8kTk9OLU5MUy0xJAotCQkJfQotCQkJc3dpdGNoICh3b3JrQWN0aW9uKSB7Ci0JCQkJY2FzZSBCVUlMRCA6Ci0JCQkJCWlmICh3b3JrT2JqZWN0ICE9IG51bGwpIHsKLQkJCQkJCWluc3RhbmNlUHJvY2Vzcy5idWlsZENvbXBvbmVudHMoKFZlY3Rvcikgd29ya09iamVjdCwgZmFsc2UpOwotCQkJCQl9Ci0JCQkJCWJyZWFrOwotCQkJCWNhc2UgRFlOQU1JQ0JJTkQgOgotCQkJCQlpZiAod29ya09iamVjdCAhPSBudWxsKSB7Ci0JCQkJCQlWZWN0b3IgdG9CaW5kID0gKFZlY3Rvcikgd29ya09iamVjdDsKLQkJCQkJCXN5bmNocm9uaXplZCAoc3luY0xvY2spIHsKLQkJCQkJCQkvLyByZW1vdmUgdW5zYXRpc2ZpZWQgY29uZmlncwotCQkJCQkJCWZvciAoaW50IGkgPSB0b0JpbmQuc2l6ZSgpIC0gMTsgaSA+PSAwOyBpLS0pIHsKLQkJCQkJCQkJUmVmZXJlbmNlIHJlZiA9IChSZWZlcmVuY2UpIHRvQmluZC5lbGVtZW50QXQoaSk7Ci0JCQkJCQkJCWlmIChyZWYuc2NwLmlzVW5zYXRpc2ZpZWQoKSkgewotCQkJCQkJCQkJLy9TeXN0ZW0ub3V0LnByaW50bG4oIi0tQklORDogcmVtb3ZpbmcgIityZWYuc2NwKTsKLQkJCQkJCQkJCXRvQmluZC5yZW1vdmVFbGVtZW50QXQoaSk7Ci0JCQkJCQkJCX0KLQkJCQkJCQl9Ci0JCQkJCQkJaWYgKHRvQmluZC5pc0VtcHR5KCkpCi0JCQkJCQkJCXJldHVybjsKLQkJCQkJCX0KLQkJCQkJCWluc3RhbmNlUHJvY2Vzcy5keW5hbWljQmluZCh0b0JpbmQpOwotCi0JCQkJCX0KLQkJCQkJYnJlYWs7Ci0JCQkJY2FzZSBESVNQT1NFIDoKLQkJCQkJaWYgKHdvcmtPYmplY3QgIT0gbnVsbCkgewotCQkJCQkJaW5zdGFuY2VQcm9jZXNzLmRpc3Bvc2VJbnN0YW5jZXMoKFZlY3Rvcikgd29ya09iamVjdCwgQ29tcG9uZW50Q29uc3RhbnRzLkRFQUNUSVZBVElPTl9SRUFTT05fVU5TUEVDSUZJRUQpOwotCQkJCQl9Ci0JCQkJCWJyZWFrOwotCQkJfQotCQl9IGNhdGNoIChUaHJvd2FibGUgZSkgewotCQkJQWN0aXZhdG9yLmxvZyhudWxsLCBMb2dTZXJ2aWNlLkxPR19FUlJPUiwgTWVzc2FnZXMuVU5FWFBFQ1RFRF9FWENFUFRJT04sIGUpOwotCQl9Ci0JfQotCi0JcHJpdmF0ZSBWZWN0b3Igc2VsZWN0RHluYW1pY0JpbmQoVmVjdG9yIHNjcHMsIFNlcnZpY2VSZWZlcmVuY2Ugc2VydmljZVJlZmVyZW5jZSkgewotCQl0cnkgewotCQkJVmVjdG9yIHRvQmluZCA9IG51bGw7Ci0JCQlmb3IgKGludCBpID0gMCwgc2l6ZSA9IHNjcHMuc2l6ZSgpOyBpIDwgc2l6ZTsgaSsrKSB7Ci0JCQkJU2VydmljZUNvbXBvbmVudFByb3Agc2NwID0gKFNlcnZpY2VDb21wb25lbnRQcm9wKSBzY3BzLmVsZW1lbnRBdChpKTsKLQkJCQlpZiAoc2NwLmlzVW5zYXRpc2ZpZWQoKSkgewotCQkJCQkvL2RvIG5vdCBjaGVjayBkaXNwb3NlZCBjb21wb25lbnRzCi0JCQkJCWNvbnRpbnVlOwotCQkJCX0KLQkJCQkvLyBpZiBpdCBpcyBub3QgYWxyZWFkeSBlbGlnaWJsZSBpdCB3aWxsIGJpbmQgd2l0aCB0aGUgc3RhdGljCi0JCQkJLy8gc2NwcwotCQkJCVZlY3RvciByZWZlcmVuY2VzID0gc2NwLnJlZmVyZW5jZXM7Ci0JCQkJLy8gaXQgaXMgYWJzb2x1dGVseSBsZWdhbCBjb21wb25lbnQgaWYgaXQgZG9lc24ndCBjb250YWlucwotCQkJCS8vIHJlZmVyZW5jZXMhCi0JCQkJaWYgKHJlZmVyZW5jZXMgIT0gbnVsbCkgewotCQkJCQlmb3IgKGludCBqID0gMDsgaiA8IHJlZmVyZW5jZXMuc2l6ZSgpOyBqKyspIHsKLQkJCQkJCVJlZmVyZW5jZSByZWZlcmVuY2UgPSAoUmVmZXJlbmNlKSByZWZlcmVuY2VzLmVsZW1lbnRBdChqKTsKLQkJCQkJCWlmIChyZWZlcmVuY2UuYmluZE5ld1JlZmVyZW5jZShzZXJ2aWNlUmVmZXJlbmNlLCB0cnVlKSkgewotCQkJCQkJCWlmICh0b0JpbmQgPT0gbnVsbCkgewotCQkJCQkJCQl0b0JpbmQgPSBuZXcgVmVjdG9yKDIpOwotCQkJCQkJCX0KLQkJCQkJCQl0b0JpbmQuYWRkRWxlbWVudChyZWZlcmVuY2UpOwotCQkJCQkJfQotCQkJCQl9Ci0JCQkJfQotCQkJfQotCQkJaWYgKHRvQmluZCAhPSBudWxsICYmIEFjdGl2YXRvci5ERUJVRykgewotCQkJCUFjdGl2YXRvci5sb2cuZGVidWcoIlJlc29sdmVyLnNlbGVjdER5bmFtaWNCaW5kKCk6IHNlbGVjdGVkID0gIiArIHRvQmluZC50b1N0cmluZygpLCBudWxsKTsgLy8kTk9OLU5MUy0xJAotCQkJfQotCQkJcmV0dXJuIHRvQmluZDsKLQkJfSBjYXRjaCAoVGhyb3dhYmxlIHQpIHsKLQkJCUFjdGl2YXRvci5sb2cobnVsbCwgTG9nU2VydmljZS5MT0dfRVJST1IsIE1lc3NhZ2VzLlVORVhQRUNURURfRVhDRVBUSU9OLCB0KTsKLQkJCXJldHVybiBudWxsOwotCQl9Ci0JfQotCi0JLy9SZXR1cm5zIHRoZSBjb21wb25lbnRzIHdpdGggc3RhdGljIHJlZmVyZW5jZSB0aGF0IG5lZWRzIHRvIGJlIGJvdW5kIHdpdGggdGhlIHNlcnZpY2UgcmVmZXJlbmNlLiAKLQkvL1RoaXMgY2FuIGhhcHBlbiBpZiB0aGUgc3RhdGljIHJlZmVyZW5jZSBoYXMgcG9saWN5IG9wdGlvbiAiZ3JlZWR5IgotCXByaXZhdGUgVmVjdG9yIHNlbGVjdFN0YXRpY0JpbmQoVmVjdG9yIHNjcHMsIFNlcnZpY2VSZWZlcmVuY2Ugc2VydmljZVJlZmVyZW5jZSkgewotCQl0cnkgewotCQkJVmVjdG9yIHRvQmluZCA9IG51bGw7Ci0JCQlmb3IgKGludCBpID0gMCwgc2l6ZSA9IHNjcHMuc2l6ZSgpOyBpIDwgc2l6ZTsgaSsrKSB7Ci0JCQkJU2VydmljZUNvbXBvbmVudFByb3Agc2NwID0gKFNlcnZpY2VDb21wb25lbnRQcm9wKSBzY3BzLmVsZW1lbnRBdChpKTsKLQkJCQlpZiAoc2NwLmlzVW5zYXRpc2ZpZWQoKSkgewotCQkJCQkvL2RvIG5vdCBjaGVjayBkaXNwb3NlZCBjb21wb25lbnRzCi0JCQkJCWNvbnRpbnVlOwotCQkJCX0KLQkJCQlWZWN0b3IgcmVmZXJlbmNlcyA9IHNjcC5yZWZlcmVuY2VzOwotCQkJCWlmIChyZWZlcmVuY2VzICE9IG51bGwpIHsKLQkJCQkJZm9yIChpbnQgaiA9IDA7IGogPCByZWZlcmVuY2VzLnNpemUoKTsgaisrKSB7Ci0JCQkJCQlSZWZlcmVuY2UgcmVmZXJlbmNlID0gKFJlZmVyZW5jZSkgcmVmZXJlbmNlcy5lbGVtZW50QXQoaik7Ci0JCQkJCQlpZiAocmVmZXJlbmNlLmJpbmROZXdSZWZlcmVuY2Uoc2VydmljZVJlZmVyZW5jZSwgZmFsc2UpKSB7Ci0JCQkJCQkJaWYgKHRvQmluZCA9PSBudWxsKSB7Ci0JCQkJCQkJCXRvQmluZCA9IG5ldyBWZWN0b3IoMik7Ci0JCQkJCQkJfQotCQkJCQkJCXRvQmluZC5hZGRFbGVtZW50KHJlZmVyZW5jZSk7Ci0JCQkJCQl9Ci0JCQkJCX0KLQkJCQl9Ci0JCQl9Ci0JCQlWZWN0b3IgcmVzdWx0ID0gbnVsbDsKLQkJCVJlZmVyZW5jZSByZWYgPSBudWxsOwotCQkJaWYgKHRvQmluZCAhPSBudWxsKSB7Ci0JCQkJcmVzdWx0ID0gbmV3IFZlY3RvcigpOwotCQkJCWZvciAoaW50IGkgPSAwOyBpIDwgdG9CaW5kLnNpemUoKTsgaSsrKSB7Ci0JCQkJCXJlZiA9IChSZWZlcmVuY2UpIHRvQmluZC5lbGVtZW50QXQoaSk7Ci0JCQkJCWlmICghcmVzdWx0LmNvbnRhaW5zKHJlZi5zY3ApKSB7Ci0JCQkJCQlyZXN1bHQuYWRkRWxlbWVudChyZWYuc2NwKTsKLQkJCQkJfQotCQkJCX0KLQkJCX0KLQotCQkJaWYgKHJlc3VsdCAhPSBudWxsICYmIEFjdGl2YXRvci5ERUJVRykgewotCQkJCUFjdGl2YXRvci5sb2cuZGVidWcoIlJlc29sdmVyLnNlbGVjdFN0YXRpY0JpbmQoKTogc2VsZWN0ZWQgPSAiICsgcmVzdWx0LnRvU3RyaW5nKCksIG51bGwpOyAvLyROT04tTkxTLTEkCi0JCQl9Ci0JCQlyZXR1cm4gcmVzdWx0OwotCQl9IGNhdGNoIChUaHJvd2FibGUgdCkgewotCQkJQWN0aXZhdG9yLmxvZyhudWxsLCBMb2dTZXJ2aWNlLkxPR19FUlJPUiwgTWVzc2FnZXMuVU5FWFBFQ1RFRF9FWENFUFRJT04sIHQpOwotCQkJcmV0dXJuIG51bGw7Ci0JCX0KLQl9Ci0KLQlwcml2YXRlIFZlY3RvciBzZWxlY3RTdGF0aWNVbkJpbmQoVmVjdG9yIHNjcHNUb0NoZWNrLCBTZXJ2aWNlUmVmZXJlbmNlIHNlcnZpY2VSZWZlcmVuY2UsIGJvb2xlYW4gY2hlY2tTYXRpc2ZpZWQpIHsKLQkJdHJ5IHsKLQkJCVZlY3RvciB0b1VuYmluZCA9IG51bGw7Ci0JCQlmb3IgKGludCBpID0gMCwgc2l6ZSA9IHNjcHNUb0NoZWNrLnNpemUoKTsgaSA8IHNpemU7IGkrKykgewotCQkJCVNlcnZpY2VDb21wb25lbnRQcm9wIHNjcCA9IChTZXJ2aWNlQ29tcG9uZW50UHJvcCkgc2Nwc1RvQ2hlY2suZWxlbWVudEF0KGkpOwotCQkJCWlmIChzY3AuaXNVbnNhdGlzZmllZCgpKSB7Ci0JCQkJCS8vdGhlIHNjcCBpcyBhbHJlYWR5IGRlYWN0aXZhdGVkCi0JCQkJCWNvbnRpbnVlOwotCQkJCX0KLQkJCQkvLyBpZiBpdCBpcyBub3QgYWxyZWFkeSBlbGlnaWJsZSBpdCB3aWxsIGJpbmQgd2l0aCB0aGUgc3RhdGljIHNjcHMKLQkJCQlWZWN0b3IgcmVmZXJlbmNlcyA9IHNjcC5yZWZlcmVuY2VzOwotCQkJCS8vIGl0IGlzIGFic29sdXRlbHkgbGVnYWwgY29tcG9uZW50IGlmIGl0IGRvZXNuJ3QgY29udGFpbnMgcmVmZXJlbmNlcyEKLQkJCQlpZiAocmVmZXJlbmNlcyAhPSBudWxsKSB7Ci0JCQkJCWZvciAoaW50IGogPSAwOyBqIDwgcmVmZXJlbmNlcy5zaXplKCk7IGorKykgewotCQkJCQkJUmVmZXJlbmNlIHJlZmVyZW5jZSA9IChSZWZlcmVuY2UpIHJlZmVyZW5jZXMuZWxlbWVudEF0KGopOwotCQkJCQkJaWYgKHJlZmVyZW5jZS5zdGF0aWNVbmJpbmRSZWZlcmVuY2Uoc2VydmljZVJlZmVyZW5jZSkpIHsKLQkJCQkJCQlpZiAoY2hlY2tTYXRpc2ZpZWQgJiYgcmVmZXJlbmNlLmlzSW5TYXRpc2ZpZWRMaXN0KHNlcnZpY2VSZWZlcmVuY2UpKSB7Ci0JCQkJCQkJCS8vdGhlIHNlcnZpY2UgcmVmZXJlbmNlIGRvIHN0aWxsIHNhdGlzZnkgdGhlIHJlZmVyZW5jZSBhbmQgc2hhbGwgbm90IGJlIHVuYm91bmQKLQkJCQkJCQkJY29udGludWU7Ci0JCQkJCQkJfQotCQkJCQkJCWlmICh0b1VuYmluZCA9PSBudWxsKSB7Ci0JCQkJCQkJCXRvVW5iaW5kID0gbmV3IFZlY3RvcigyKTsKLQkJCQkJCQl9Ci0JCQkJCQkJdG9VbmJpbmQuYWRkRWxlbWVudChzY3ApOwotCQkJCQkJfQotCQkJCQl9Ci0JCQkJfQotCQkJfQotCQkJaWYgKHRvVW5iaW5kICE9IG51bGwpCi0JCQkJaWYgKEFjdGl2YXRvci5ERUJVRykgewotCQkJCQlBY3RpdmF0b3IubG9nLmRlYnVnKCJSZXNvbHZlci5zZWxlY3RTdGF0aWNVbkJpbmQoKTogc2VsZWN0ZWQgPSAiICsgdG9VbmJpbmQudG9TdHJpbmcoKSwgbnVsbCk7IC8vJE5PTi1OTFMtMSQKLQkJCQl9Ci0JCQlyZXR1cm4gdG9VbmJpbmQ7Ci0JCX0gY2F0Y2ggKFRocm93YWJsZSB0KSB7Ci0JCQlBY3RpdmF0b3IubG9nKG51bGwsIExvZ1NlcnZpY2UuTE9HX0VSUk9SLCBNZXNzYWdlcy5VTkVYUEVDVEVEX0VYQ0VQVElPTiwgdCk7Ci0JCQlyZXR1cm4gbnVsbDsKLQkJfQotCX0KLQotCS8qKgotCSAqIHNlbGVjdER5bmFtaWNVbkJpbmQgRGV0ZXJtaW5lIHdoaWNoIHJlc29sdmVkIGNvbXBvbmVudCBkZXNjcmlwdGlvbiB3aXRoCi0JICogcHJvcGVydGllcyBuZWVkIHRvIHVuYmluZCBmcm9tIHRoaXMgdW5yZWdpc3RlcmluZyBzZXJ2aWNlIFJldHVybiBtYXAgb2YKLQkgKiByZWZlcmVuY2UgZGVzY3JpcHRpb24gYW5kIGNvbXBvbmVudCBkZXNjcmlwdGlvbiB3aXRoIHByb3BlcnRpZXMsIGZvcgotCSAqIGVhY2guCi0JICogCi0JICogQHBhcmFtIHNjcHMKLQkgKiBAcGFyYW0gc2VydmljZVJlZmVyZW5jZQotCSAqIEByZXR1cm4gdGhpcyBpcyBmYWlybHkgY29tcGxleCB0byBleHBsYWluIDsoCi0JICovCi0JcHJpdmF0ZSBIYXNodGFibGUgc2VsZWN0RHluYW1pY1VuQmluZChWZWN0b3Igc2NwcywgU2VydmljZVJlZmVyZW5jZSBzZXJ2aWNlUmVmZXJlbmNlLCBib29sZWFuIGNoZWNrU2F0aXNmaWVkKSB7Ci0JCXRyeSB7Ci0JCQlpZiAoQWN0aXZhdG9yLkRFQlVHKSB7Ci0JCQkJQWN0aXZhdG9yLmxvZy5kZWJ1ZygiUmVzb2x2ZXIuc2VsZWN0RHluYW1pY1VuQmluZCgpOiBlbnRlcmVkIiwgbnVsbCk7IC8vJE5PTi1OTFMtMSQKLQkJCX0KLQkJCUhhc2h0YWJsZSB1bmJpbmRUYWJsZSA9IG51bGw7IC8vIFJlZmVyZW5jZURlc2NyaXB0aW9uOnN1YlRhYmxlCi0JCQlmb3IgKGludCBpID0gMDsgaSA8IHNjcHMuc2l6ZSgpOyBpKyspIHsKLQkJCQlIYXNodGFibGUgdW5iaW5kU3ViVGFibGUgPSBudWxsOyAvLyBzY3A6c3IKLQkJCQlTZXJ2aWNlQ29tcG9uZW50UHJvcCBzY3AgPSAoU2VydmljZUNvbXBvbmVudFByb3ApIHNjcHMuZWxlbWVudEF0KGkpOwotCi0JCQkJaWYgKHNjcC5pc1Vuc2F0aXNmaWVkKCkpIHsKLQkJCQkJLy9kbyBub3QgY2hlY2sgZGVhY3RpdmF0ZWQgY29tcG9uZW50cwotCQkJCQljb250aW51ZTsKLQkJCQl9Ci0JCQkJVmVjdG9yIHJlZmVyZW5jZXMgPSBzY3AucmVmZXJlbmNlczsKLQkJCQkvLyBzb21lIGNvbXBvbmVudHMgbWF5IG5vdCBjb250YWluIHJlZmVyZW5jZXMgYW5kIGl0IGlzCi0JCQkJLy8gYWJzb2x1dGVseSB2YWxpZAotCQkJCWlmIChyZWZlcmVuY2VzICE9IG51bGwpIHsKLQkJCQkJZm9yIChpbnQgaiA9IDA7IGogPCByZWZlcmVuY2VzLnNpemUoKTsgaisrKSB7Ci0JCQkJCQlSZWZlcmVuY2UgcmVmZXJlbmNlID0gKFJlZmVyZW5jZSkgcmVmZXJlbmNlcy5lbGVtZW50QXQoaik7Ci0JCQkJCQkvLyBEb2VzIHRoZSBzY3AgcmVxdWlyZSB0aGlzIHNlcnZpY2UsIHVzZSB0aGUgUmVmZXJlbmNlCi0JCQkJCQkvLyBvYmplY3QgdG8gY2hlY2sKLQkJCQkJCWlmIChyZWZlcmVuY2UuZHluYW1pY1VuYmluZFJlZmVyZW5jZShzZXJ2aWNlUmVmZXJlbmNlKSkgewotCQkJCQkJCWlmIChjaGVja1NhdGlzZmllZCAmJiByZWZlcmVuY2UuaXNJblNhdGlzZmllZExpc3Qoc2VydmljZVJlZmVyZW5jZSkpIHsKLQkJCQkJCQkJLy90aGUgc2VydmljZSByZWZlcmVuY2UgZG8gc3RpbGwgc2F0aXNmeSB0aGUgcmVmZXJlbmNlIGFuZCBzaGFsbCBub3QgYmUgdW5ib3VuZAotCQkJCQkJCQljb250aW51ZTsKLQkJCQkJCQl9Ci0JCQkJCQkJaWYgKEFjdGl2YXRvci5ERUJVRykgewotCQkJCQkJCQlBY3RpdmF0b3IubG9nLmRlYnVnKCJSZXNvbHZlci5zZWxlY3REeW5hbWljVW5CaW5kKCk6IHVuYmluZGluZyAiICsgc2NwLnRvU3RyaW5nKCksIG51bGwpOyAvLyROT04tTkxTLTEkCi0JCQkJCQkJfQotCQkJCQkJCWlmICh1bmJpbmRTdWJUYWJsZSA9PSBudWxsKSB7Ci0JCQkJCQkJCXVuYmluZFN1YlRhYmxlID0gbmV3IEhhc2h0YWJsZSgxMSk7Ci0JCQkJCQkJfQotCQkJCQkJCXVuYmluZFN1YlRhYmxlLnB1dChzY3AsIHNlcnZpY2VSZWZlcmVuY2UpOwotCQkJCQkJCWlmICh1bmJpbmRUYWJsZSA9PSBudWxsKSB7Ci0JCQkJCQkJCXVuYmluZFRhYmxlID0gbmV3IEhhc2h0YWJsZSgxMSk7Ci0JCQkJCQkJfQotCQkJCQkJCXVuYmluZFRhYmxlLnB1dChyZWZlcmVuY2UsIHVuYmluZFN1YlRhYmxlKTsKLQkJCQkJCX0gZWxzZSB7Ci0JCQkJCQkJaWYgKEFjdGl2YXRvci5ERUJVRykgewotCQkJCQkJCQlBY3RpdmF0b3IubG9nLmRlYnVnKCJSZXNvbHZlci5zZWxlY3REeW5hbWljVW5CaW5kKCk6IG5vdCB1bmJpbmRpbmcgIiArIHNjcCArICIgc2VydmljZSByZWY9IiArIHNlcnZpY2VSZWZlcmVuY2UsIG51bGwpOyAvLyROT04tTkxTLTEkIC8vJE5PTi1OTFMtMiQKLQkJCQkJCQl9Ci0JCQkJCQl9Ci0JCQkJCX0KLQkJCQl9Ci0JCQl9Ci0JCQlpZiAodW5iaW5kVGFibGUgIT0gbnVsbCAmJiBBY3RpdmF0b3IuREVCVUcpIHsKLQkJCQlBY3RpdmF0b3IubG9nLmRlYnVnKCJSZXNvbHZlci5zZWxlY3REeW5hbWljVW5CaW5kKCk6IHVuYmluZFRhYmxlIGlzICIgKyB1bmJpbmRUYWJsZS50b1N0cmluZygpLCBudWxsKTsgLy8kTk9OLU5MUy0xJAotCQkJfQotCQkJcmV0dXJuIHVuYmluZFRhYmxlOwotCQl9IGNhdGNoIChUaHJvd2FibGUgdCkgewotCQkJQWN0aXZhdG9yLmxvZyhudWxsLCBMb2dTZXJ2aWNlLkxPR19FUlJPUiwgTWVzc2FnZXMuVU5FWFBFQ1RFRF9FWENFUFRJT04sIHQpOwotCQkJcmV0dXJuIG51bGw7Ci0JCX0KLQl9Ci0KLQkvKioKLQkgKiBEZXRlcm1pbmUgd2hpY2ggY29tcG9uZW50IHJlZmVyZW5jZXMgbmVlZHMgdG8gYmUgdXBkYXRlZCBieSB0aGVpciBzcGVjaWZpZWQgdXBkYXRlZCBtZXRob2QgZHVlIHRvIHRoZSBjdXJyZW50IHNlcnZpY2UgcmVmZXJlbmNlcyBwcm9wZXJ0aWVzIGNoYW5nZQotCSAqIAotCSAqIEBwYXJhbSBzY3BzCi0JICogQHBhcmFtIHNlcnZpY2VSZWZlcmVuY2UKLQkgKiBAcmV0dXJuIE1hcCBvZiA8UmVmZXJlbmNlPjo8TWFwIG9mIDxTZXJ2aWNlQ29tcG9uZW50UHJvcD46PFNlcnZpY2VSZWZlcmVuY2U+PgotCSAqIAotCSAqLwotCXByaXZhdGUgSGFzaHRhYmxlIHNlbGVjdFJlZmVyZW5jZXNUb1VwZGF0ZShWZWN0b3Igc2NwcywgU2VydmljZVJlZmVyZW5jZSBzZXJ2aWNlUmVmZXJlbmNlKSB7Ci0JCXRyeSB7Ci0JCQlpZiAoQWN0aXZhdG9yLkRFQlVHKSB7Ci0JCQkJQWN0aXZhdG9yLmxvZy5kZWJ1ZygiUmVzb2x2ZXIuc2VsZWN0UmVmZXJlbmNlc1RvVXBkYXRlKCk6IGVudGVyZWQiLCBudWxsKTsgLy8kTk9OLU5MUy0xJAotCQkJfQotCQkJSGFzaHRhYmxlIHJlZmVyZW5jZXNUYWJsZSA9IG51bGw7Ci0JCQlmb3IgKGludCBpID0gMDsgaSA8IHNjcHMuc2l6ZSgpOyBpKyspIHsKLQkJCQlIYXNodGFibGUgdXBkYXRlU3ViVGFibGUgPSBudWxsOwotCQkJCVNlcnZpY2VDb21wb25lbnRQcm9wIHNjcCA9IChTZXJ2aWNlQ29tcG9uZW50UHJvcCkgc2Nwcy5lbGVtZW50QXQoaSk7Ci0KLQkJCQlpZiAoc2NwLmlzVW5zYXRpc2ZpZWQoKSB8fCAhc2NwLnNlcnZpY2VDb21wb25lbnQuaXNOYW1lc3BhY2VBdExlYXN0MTIoKSkgewotCQkJCQkvL2RvIG5vdCBjaGVjayBkZWFjdGl2YXRlZCBjb21wb25lbnRzIG9yIGNvbXBvbmVudHMgd2hpY2ggYXJlIG5vdCBEUyAxLjIgY29tcGxpYW50Ci0JCQkJCWNvbnRpbnVlOwotCQkJCX0KLQkJCQlWZWN0b3IgcmVmZXJlbmNlcyA9IHNjcC5yZWZlcmVuY2VzOwotCQkJCWlmIChyZWZlcmVuY2VzICE9IG51bGwpIHsKLQkJCQkJZm9yIChpbnQgaiA9IDA7IGogPCByZWZlcmVuY2VzLnNpemUoKTsgaisrKSB7Ci0JCQkJCQlSZWZlcmVuY2UgcmVmZXJlbmNlID0gKFJlZmVyZW5jZSkgcmVmZXJlbmNlcy5lbGVtZW50QXQoaik7Ci0JCQkJCQlpZiAocmVmZXJlbmNlLnJlZmVyZW5jZS51cGRhdGVkID09IG51bGwpIHsKLQkJCQkJCQkvL3RoZSByZWZlcmVuY2UgZG9lcyBub3QgaGF2ZSB1cGRhdGVkIG1ldGhvZCBzcGVjaWZpZWQKLQkJCQkJCQljb250aW51ZTsKLQkJCQkJCX0KLQkJCQkJCWlmIChyZWZlcmVuY2UuaXNTdGF0aWMoKSA/IHJlZmVyZW5jZS5zdGF0aWNVbmJpbmRSZWZlcmVuY2Uoc2VydmljZVJlZmVyZW5jZSkgOiByZWZlcmVuY2UuZHluYW1pY1VuYmluZFJlZmVyZW5jZShzZXJ2aWNlUmVmZXJlbmNlKSkgewotCQkJCQkJCWlmIChBY3RpdmF0b3IuREVCVUcpIHsKLQkJCQkJCQkJQWN0aXZhdG9yLmxvZy5kZWJ1ZygiUmVzb2x2ZXIuc2VsZWN0UmVmZXJlbmNlc1RvVXBkYXRlKCk6IHNlbGVjdGVkIGZvciB1cGRhdGUgcmVmZXJlbmNlICIgKyByZWZlcmVuY2UucmVmZXJlbmNlLm5hbWUgKyAiIG9mIGNvbXBvbmVudCAiICsgc2NwLnRvU3RyaW5nKCksIG51bGwpOyAvLyROT04tTkxTLTEkIC8vJE5PTi1OTFMtMiQKLQkJCQkJCQl9Ci0JCQkJCQkJaWYgKHVwZGF0ZVN1YlRhYmxlID09IG51bGwpIHsKLQkJCQkJCQkJdXBkYXRlU3ViVGFibGUgPSBuZXcgSGFzaHRhYmxlKDExKTsKLQkJCQkJCQl9Ci0JCQkJCQkJdXBkYXRlU3ViVGFibGUucHV0KHNjcCwgc2VydmljZVJlZmVyZW5jZSk7Ci0JCQkJCQkJaWYgKHJlZmVyZW5jZXNUYWJsZSA9PSBudWxsKSB7Ci0JCQkJCQkJCXJlZmVyZW5jZXNUYWJsZSA9IG5ldyBIYXNodGFibGUoMTEpOwotCQkJCQkJCX0KLQkJCQkJCQlyZWZlcmVuY2VzVGFibGUucHV0KHJlZmVyZW5jZSwgdXBkYXRlU3ViVGFibGUpOwotCQkJCQkJfQotCQkJCQl9Ci0JCQkJfQotCQkJfQotCQkJaWYgKHJlZmVyZW5jZXNUYWJsZSAhPSBudWxsICYmIEFjdGl2YXRvci5ERUJVRykgewotCQkJCUFjdGl2YXRvci5sb2cuZGVidWcoIlJlc29sdmVyLnNlbGVjdFJlZmVyZW5jZXNUb1VwZGF0ZSgpOiByZWZlcmVuY2VzVGFibGUgaXMgIiArIHJlZmVyZW5jZXNUYWJsZS50b1N0cmluZygpLCBudWxsKTsgLy8kTk9OLU5MUy0xJAotCQkJfQotCQkJcmV0dXJuIHJlZmVyZW5jZXNUYWJsZTsKLQkJfSBjYXRjaCAoVGhyb3dhYmxlIHQpIHsKLQkJCUFjdGl2YXRvci5sb2cobnVsbCwgTG9nU2VydmljZS5MT0dfRVJST1IsIE1lc3NhZ2VzLlVORVhQRUNURURfRVhDRVBUSU9OLCB0KTsKLQkJCXJldHVybiBudWxsOwotCQl9Ci0JfQotCi0JLy8gdXNlZCBieSB0aGUgQ29tcG9uZW50RmFjdG9yeUltcGwgdG8gYnVpbGQgbmV3IENvbXBvbmVudCBjb25maWd1cmF0aW9ucwotCXB1YmxpYyBTZXJ2aWNlQ29tcG9uZW50UHJvcCBtYXBOZXdGYWN0b3J5Q29tcG9uZW50KFNlcnZpY2VDb21wb25lbnQgY29tcG9uZW50LCBEaWN0aW9uYXJ5IGNvbmZpZ1Byb3BlcnRpZXMpIHsKLQkJc3luY2hyb25pemVkIChzeW5jTG9jaykgewotCQkJLy8gY3JlYXRlIGEgbmV3IHNjcCAoYWRkcyB0byByZXNvbHZlciBlbmFibGVkU0NQcyBsaXN0KQotCQkJU2VydmljZUNvbXBvbmVudFByb3AgbmV3U0NQID0gbWFwKGNvbXBvbmVudCwgY29uZmlnUHJvcGVydGllcyk7Ci0JCQluZXdTQ1Auc2V0Q29tcG9uZW50RmFjdG9yeShmYWxzZSk7IC8vIGF2b2lkIHJlZ2lzdHJhdGlvbiBvZiBuZXcKLQkJCS8vIENvbXBvbmVudEZhY3RvcnkKLQotCQkJLy8gd2UgYWRkZWQgYSBTQ1AsIHNvIGNoZWNrIGZvciBjaXJjdWxhcml0eSBhbmQgbWFyayBjeWNsZXMKLQkJCWZpbmREZXBlbmRlbmN5Q3ljbGVzKCk7Ci0KLQkJCS8vIGdldCBsaXN0IG9mIG5ld2x5IHNhdGlzZmllZCBTQ1BzIGFuZCBjaGVjayB3aGV0aGVyIHRoZSBuZXcgU0NQIGlzCi0JCQkvLyBzYXRpc2ZpZWQKLQkJCVZlY3RvciBlbGlnaWJsZVNDUHMgPSByZXNvbHZlRWxpZ2libGUoKTsKLQkJCWlmICghZWxpZ2libGVTQ1BzLmNvbnRhaW5zKG5ld1NDUCkpIHsKLQkJCQlyZW1vdmVFbmFibGVkU0NQKG5ld1NDUCk7Ci0JCQkJdGhyb3cgbmV3IENvbXBvbmVudEV4Y2VwdGlvbihOTFMuYmluZChNZXNzYWdlcy5DQU5UX1JFU09MVkVfQ09NUE9ORU5UX0lOU1RBTkNFLCBuZXdTQ1AsIGNvbmZpZ1Byb3BlcnRpZXMpKTsKLQkJCX0KLQkJCXJldHVybiBuZXdTQ1A7Ci0JCX0KLQl9Ci0KLQkvKioKLQkgKiBDaGVjayB0aHJvdWdoIHRoZSBlbmFibGVkIGxpc3QgZm9yIGN5Y2xlcy4gQ3ljbGVzIGNhbiBvbmx5IGV4aXN0IGlmIGV2ZXJ5Ci0JICogc2VydmljZSBpcyBwcm92aWRlZCBieSBhIFNlcnZpY2UgQ29tcG9uZW50IChub3QgbGVnYWN5IE9TR2kpLiBJZiB0aGUKLQkgKiBjeWNsZSBoYXMgbm8gb3B0aW9uYWwgZGVwZW5kZW5jaWVzLCBsb2cgYW4gZXJyb3IgYW5kIGRpc2FibGUgYSBDb21wb25lbnQKLQkgKiBDb25maWd1cmF0aW9uIGluIHRoZSBjeWNsZS4gSWYgY3ljbGUgY2FuIGJlICJicm9rZW4iIGJ5IGFuIG9wdGlvbmFsCi0JICogZGVwZW5kZW5jeSwgbWFrZSBhIG5vdGUgKHN0b3JlZCBpbiB0aGUKLQkgKiB7QGxpbmsgU2VydmljZUNvbXBvbmVudFByb3AjZGVsYXlBY3RpdmF0ZVNDUE5hbWVzfSBWZWN0b3IpLgotCSAqIAotCSAqIEB0aHJvd3MgQ2lyY3VsYXJpdHlFeGNlcHRpb24KLQkgKiAgICAgICAgICAgICBpZiBjeWNsZSBleGlzdHMgd2l0aCBubyBvcHRpb25hbCBkZXBlbmRlbmNpZXMKLQkgKi8KLQlwcml2YXRlIHZvaWQgZmluZERlcGVuZGVuY3lDeWNsZXMoKSB7Ci0JCVZlY3RvciBlbXB0eVZlY3RvciA9IG5ldyBWZWN0b3IoKTsKLQkJdHJ5IHsKLQkJCS8vIGZpbmQgdGhlIFNDUHMgdGhhdCByZXNvbHZlIHVzaW5nIG90aGVyIFNDUHMgYW5kIHJlY29yZCB0aGVpcgotCQkJLy8gZGVwZW5kZW5jaWVzCi0JCQlIYXNodGFibGUgZGVwZW5kZW5jaWVzID0gbmV3IEhhc2h0YWJsZSgpOwotCi0JCQlmb3IgKGludCBpID0gc2NwRW5hYmxlZC5zaXplKCkgLSAxOyBpID49IDA7IGktLSkgewotCQkJCVNlcnZpY2VDb21wb25lbnRQcm9wIGVuYWJsZWRTQ1AgPSAoU2VydmljZUNvbXBvbmVudFByb3ApIHNjcEVuYWJsZWQuZWxlbWVudEF0KGkpOwotCQkJCWlmIChlbmFibGVkU0NQLnJlZmVyZW5jZXMgIT0gbnVsbCkgewotCQkJCQlWZWN0b3IgZGVwZW5kZW5jeVZlY3RvciA9IG5ldyBWZWN0b3IoMSk7Ci0JCQkJCWZvciAoaW50IGogPSAwOyBqIDwgZW5hYmxlZFNDUC5yZWZlcmVuY2VzLnNpemUoKTsgaisrKSB7Ci0JCQkJCQlSZWZlcmVuY2UgcmVmZXJlbmNlID0gKFJlZmVyZW5jZSkgZW5hYmxlZFNDUC5yZWZlcmVuY2VzLmVsZW1lbnRBdChqKTsKLQotCQkJCQkJLy8gc2VlIGlmIGl0IHJlc29sdmVzIHRvIG9uZSBvZiB0aGUgb3RoZXIgZW5hYmxlZCBTQ1BzCi0JCQkJCQlTZXJ2aWNlQ29tcG9uZW50UHJvcFtdIHByb3ZpZGVyU0NQcyA9IHJlZmVyZW5jZS5zZWxlY3RQcm92aWRlcnMoc2NwRW5hYmxlZCk7Ci0JCQkJCQlpZiAocHJvdmlkZXJTQ1BzICE9IG51bGwpIHsKLQkJCQkJCQlmb3IgKGludCBrID0gMDsgayA8IHByb3ZpZGVyU0NQcy5sZW5ndGg7IGsrKykgewotCQkJCQkJCQlkZXBlbmRlbmN5VmVjdG9yLmFkZEVsZW1lbnQobmV3IFJlZmVyZW5jZVNDUFdyYXBwZXIocmVmZXJlbmNlLCBwcm92aWRlclNDUHNba10pKTsKLQkJCQkJCQl9Ci0JCQkJCQl9Ci0JCQkJCX0gLy8gZW5kIGZvcgotCi0JCQkJCWlmICghZGVwZW5kZW5jeVZlY3Rvci5pc0VtcHR5KCkpIHsKLQkJCQkJCS8vIFNDUCByZXNvbHZlcyB1c2luZyBzb21lIG90aGVyIFNDUHMsIGNvdWxkIGJlIGEgY3ljbGUKLQkJCQkJCWRlcGVuZGVuY2llcy5wdXQoZW5hYmxlZFNDUCwgZGVwZW5kZW5jeVZlY3Rvcik7Ci0JCQkJCX0gZWxzZSB7Ci0JCQkJCQlkZXBlbmRlbmNpZXMucHV0KGVuYWJsZWRTQ1AsIGVtcHR5VmVjdG9yKTsKLQkJCQkJfQotCQkJCX0KLQkJCX0gLy8gZW5kIGZvcgotCi0JCQkvLyB0cmF2ZXJzZSBkZXBlbmRlbmN5IHRyZWUgYW5kIGxvb2sgZm9yIGN5Y2xlcwotCQkJSGFzaHRhYmxlIHZpc2l0ZWQgPSBuZXcgSGFzaHRhYmxlKDExKTsKLQkJCUVudW1lcmF0aW9uIGtleXMgPSBkZXBlbmRlbmNpZXMua2V5cygpOwotCi0JCQl3aGlsZSAoa2V5cy5oYXNNb3JlRWxlbWVudHMoKSkgewotCQkJCVNlcnZpY2VDb21wb25lbnRQcm9wIHNjcCA9IChTZXJ2aWNlQ29tcG9uZW50UHJvcCkga2V5cy5uZXh0RWxlbWVudCgpOwotCQkJCWlmICghdmlzaXRlZC5jb250YWluc0tleShzY3ApKSB7Ci0JCQkJCVZlY3RvciBjdXJyZW50U3RhY2sgPSBuZXcgVmVjdG9yKDIpOwotCQkJCQljaGVja0RlcGVuZGVuY2llcyhzY3AsIHZpc2l0ZWQsIGRlcGVuZGVuY2llcywgY3VycmVudFN0YWNrKTsKLQkJCQl9Ci0JCQl9Ci0JCX0gY2F0Y2ggKENpcmN1bGFyaXR5RXhjZXB0aW9uIGUpIHsKLQkJCUFjdGl2YXRvci5sb2coZS5nZXRDYXVzaW5nQ29tcG9uZW50KCkuc2VydmljZUNvbXBvbmVudC5iYywgTG9nU2VydmljZS5MT0dfRVJST1IsIE5MUy5iaW5kKE1lc3NhZ2VzLkNJUkNVTEFSSVRZX0VYQ0VQVElPTl9GT1VORCwgZS5nZXRDYXVzaW5nQ29tcG9uZW50KCkuc2VydmljZUNvbXBvbmVudCksIGUpOwotCQkJLy8gZGlzYWJsZSBvZmZlbmRpbmcgU0NQCi0JCQlyZW1vdmVFbmFibGVkU0NQKGUuZ2V0Q2F1c2luZ0NvbXBvbmVudCgpKTsKLQkJCS8vIHRyeSBhZ2FpbgotCQkJZmluZERlcGVuZGVuY3lDeWNsZXMoKTsKLQkJfQotCX0KLQotCS8qKgotCSAqIFJlY3Vyc2l2ZWx5IGRvIGEgZGVwdGgtZmlyc3QgdHJhdmVyc2FsIG9mIGEgZGVwZW5kZW5jeSB0cmVlLCBsb29raW5nIGZvcgotCSAqIGN5Y2xlcy4KLQkgKiA8cD4KLQkgKiBJZiBhIGN5Y2xlIGlzIGZvdW5kLCBjYWxscwotCSAqIHtAbGluayBSZXNvbHZlciNwcm9jZXNzRGVwZW5kZW5jeUN5Y2xlKFJlZmVyZW5jZVNDUFdyYXBwZXIsIFZlY3Rvcil9LgotCSAqIDwvcD4KLQkgKiAKLQkgKiBAcGFyYW0gc2NwCi0JICogICAgICAgICAgICBjdXJyZW50IG5vZGUgaW4gZGVwZW5kZW5jeSB0cmVlCi0JICogQHBhcmFtIHZpc2l0ZWQKLQkgKiAgICAgICAgICAgIGhvbGRlcyB0aGUgdmlzaXRlZCBub2RlcwotCSAqIEBwYXJhbSBkZXBlbmRlbmNpZXMKLQkgKiAgICAgICAgICAgIERlcGVuZGVuY3kgdHJlZSAtIGEgSGFzaHRhYmxlIG9mICh7QGxpbmsgU2VydmljZUNvbXBvbmVudFByb3B9KTooVmVjdG9yCi0JICogICAgICAgICAgICBvZiB7QGxpbmsgUmVmZXJlbmNlU0NQV3JhcHBlcn1zKQotCSAqIEBwYXJhbSBjdXJyZW50U3RhY2sKLQkgKiAgICAgICAgICAgIFZlY3RvciBvZiB7QGxpbmsgUmVmZXJlbmNlU0NQV3JhcHBlcn1zIC0gdGhlIGhpc3Rvcnkgb2Ygb3VyCi0JICogICAgICAgICAgICB0cmF2ZXJzYWwgc28gZmFyICh0aGUgcGF0aCBiYWNrIHRvIHRoZSByb290IG9mIHRoZSB0cmVlKQotCSAqIEB0aHJvd3MgQ2lyY3VsYXJpdHlFeGNlcHRpb24KLQkgKiAgICAgICAgICAgICBpZiBhbiBjeWNsZSB3aXRoIG5vIG9wdGlvbmFsIGRlcGVuZGVuY2llcyBpcyBmb3VuZC4KLQkgKi8KLQlwcml2YXRlIHZvaWQgY2hlY2tEZXBlbmRlbmNpZXMoU2VydmljZUNvbXBvbmVudFByb3Agc2NwLCBIYXNodGFibGUgdmlzaXRlZCwgSGFzaHRhYmxlIGRlcGVuZGVuY2llcywgVmVjdG9yIGN1cnJlbnRTdGFjaykgdGhyb3dzIENpcmN1bGFyaXR5RXhjZXB0aW9uIHsKLQotCQkvLyB0aGUgY29tcG9uZW50IGhhcyBhbHJlYWR5IGJlZW4gdmlzaXRlZCBhbmQgaXQncyBkZXBlbmRlbmNpZXMgY2hlY2tlZAotCQkvLyBmb3IgY3ljbGVzCi0JCWlmICh2aXNpdGVkLmNvbnRhaW5zS2V5KHNjcCkpIHsKLQkJCXJldHVybjsKLQkJfQotCi0JCVZlY3RvciByZWZTQ1BzID0gKFZlY3RvcikgZGVwZW5kZW5jaWVzLmdldChzY3ApOwotCQlpZiAocmVmU0NQcyAhPSBudWxsKSB7Ci0JCQlmb3IgKGludCBpID0gMDsgaSA8IHJlZlNDUHMuc2l6ZSgpOyBpKyspIHsKLQkJCQlSZWZlcmVuY2VTQ1BXcmFwcGVyIHJlZlNDUCA9IChSZWZlcmVuY2VTQ1BXcmFwcGVyKSByZWZTQ1BzLmVsZW1lbnRBdChpKTsKLQkJCQlpZiAoY3VycmVudFN0YWNrLmNvbnRhaW5zKHJlZlNDUCkpIHsKLQkJCQkJLy8gbWF5IHRocm93IGNpcmN1bGFyaXR5IGV4Y2VwdGlvbgotCQkJCQlwcm9jZXNzRGVwZW5kZW5jeUN5Y2xlKHJlZlNDUCwgY3VycmVudFN0YWNrKTsKLQkJCQkJY29udGludWU7Ci0JCQkJfQotCQkJCWN1cnJlbnRTdGFjay5hZGRFbGVtZW50KHJlZlNDUCk7Ci0KLQkJCQljaGVja0RlcGVuZGVuY2llcyhyZWZTQ1AucHJvZHVjZXIsIHZpc2l0ZWQsIGRlcGVuZGVuY2llcywgY3VycmVudFN0YWNrKTsKLQotCQkJCWN1cnJlbnRTdGFjay5yZW1vdmVFbGVtZW50KHJlZlNDUCk7Ci0JCQl9Ci0JCX0KLQkJdmlzaXRlZC5wdXQoc2NwLCAiIik7IC8vJE5PTi1OTFMtMSQKLQl9Ci0KLQkvKioKLQkgKiBBIGN5Y2xlIHdhcyBkZXRlY3RlZC4gU0NQIGlzIHJlZmVyZW5jZWQgYnkgdGhlIGxhc3QgZWxlbWVudCBpbgotCSAqIGN1cnJlbnRTdGFjay4gVGhyb3dzIENpcmN1bGFyaXR5RXhjZXB0aW9uIGlmIHRoZSBjeWNsZSBkb2VzIG5vdCBjb250YWluCi0JICogYW4gb3B0aW9uYWwgZGVwZW5kZW5jeSwgZWxzZSBjaG9zZXMgYSBwb2ludCBhdCB3aGljaCB0byAiYnJlYWsiIHRoZSBjeWNsZQotCSAqICh0aGUgYnJlYWsgcG9pbnQgbXVzdCBiZSBpbW1lZGlhdGVseSBhZnRlciBhbiBvcHRpb25hbCBkZXBlbmRlbmN5KSBhbmQKLQkgKiBhZGRzIGEgImN5Y2xlIG5vdGUiLgotCSAqIAotCSAqIEBzZWUgU2VydmljZUNvbXBvbmVudFByb3AjZGVsYXlBY3RpdmF0ZVNDUE5hbWVzCi0JICovCi0JcHJpdmF0ZSB2b2lkIHByb2Nlc3NEZXBlbmRlbmN5Q3ljbGUoUmVmZXJlbmNlU0NQV3JhcHBlciByZWZTQ1AsIFZlY3RvciBjdXJyZW50U3RhY2spIHRocm93cyBDaXJjdWxhcml0eUV4Y2VwdGlvbiB7Ci0JCS8vIGZpbmQgYW4gb3B0aW9uYWwgZGVwZW5kZW5jeQotCQlSZWZlcmVuY2VTQ1BXcmFwcGVyIG9wdGlvbmFsUmVmU0NQID0gbnVsbDsKLQkJZm9yIChpbnQgaSA9IGN1cnJlbnRTdGFjay5pbmRleE9mKHJlZlNDUCk7IGkgPCBjdXJyZW50U3RhY2suc2l6ZSgpOyBpKyspIHsKLQkJCVJlZmVyZW5jZVNDUFdyYXBwZXIgY3ljbGVSZWZTQ1AgPSAoUmVmZXJlbmNlU0NQV3JhcHBlcikgY3VycmVudFN0YWNrLmVsZW1lbnRBdChpKTsKLQkJCWlmICghY3ljbGVSZWZTQ1AucmVmLmlzUmVxdWlyZWQoKSkgewotCQkJCW9wdGlvbmFsUmVmU0NQID0gY3ljbGVSZWZTQ1A7Ci0JCQkJYnJlYWs7Ci0JCQl9Ci0JCX0KLQkJaWYgKG9wdGlvbmFsUmVmU0NQID09IG51bGwpIHsKLQkJCXRocm93IG5ldyBDaXJjdWxhcml0eUV4Y2VwdGlvbihyZWZTQ1AucmVmLnNjcCk7Ci0JCX0KLQkJLy8gY2hlY2sgd2hldGhlciB0aGUgb3B0aW9uYWwgcmVmZXJlbmNlIGlzIHN0YXRpYyAtIHRoaXMgaXMgbm90IGFsbG93ZWQKLQkJLy8gYmVjYXVzZSBvZiB0aGUgd2F5IGNvbXBvbmVudHMgd2l0aCBzdGF0aWMgcmVmZXJlY2VzIGFyZSBidWlsdAotCQlpZiAob3B0aW9uYWxSZWZTQ1AucmVmLnBvbGljeSA9PSBDb21wb25lbnRSZWZlcmVuY2UuUE9MSUNZX1NUQVRJQykgewotCQkJQWN0aXZhdG9yLmxvZyhvcHRpb25hbFJlZlNDUC5yZWYuc2NwLmJjLCBMb2dTZXJ2aWNlLkxPR19FUlJPUiwgTkxTLmJpbmQoTWVzc2FnZXMuU1RBVElDX09QVElPTkFMX1JFRkVSRU5DRV9UT19CRV9SRU1PVkVELCBvcHRpb25hbFJlZlNDUC5yZWYucmVmZXJlbmNlKSwgbnVsbCk7Ci0KLQkJCW9wdGlvbmFsUmVmU0NQLnJlZi5zY3AucmVmZXJlbmNlcy5yZW1vdmVFbGVtZW50KG9wdGlvbmFsUmVmU0NQLnJlZik7Ci0JCX0KLQotCQkvLyB0aGUgZGVwZW5kZW50IGNvbXBvbmVudCB3aWxsIGJlIHByb2Nlc3NlZCB3aXRoIGRlbGF5IHdoZW5ldmVyCi0JCS8vIG5lY2Vzc2FyeQotCQlvcHRpb25hbFJlZlNDUC5yZWYuc2NwLnNldERlbGF5QWN0aXZhdGVTQ1BOYW1lKG9wdGlvbmFsUmVmU0NQLnByb2R1Y2VyLnNlcnZpY2VDb21wb25lbnQubmFtZSk7Ci0JfQotCi0JLy8gdXNlZCB0byByZW1vdmUgYWxsIGVsZW1lbnRzIG9mIHZlY3RvciB3aGljaCBvY2N1ciBpbiBhbm90aGVyIHZlY3RvcgotCXByaXZhdGUgdm9pZCByZW1vdmVBbGwoVmVjdG9yIHNyYywgVmVjdG9yIGVsZW1lbnRzVG9SZW1vdmUpIHsKLQkJZm9yIChpbnQgaSA9IHNyYy5zaXplKCkgLSAxOyBpID49IDA7IGktLSkgewotCQkJaWYgKGVsZW1lbnRzVG9SZW1vdmUuY29udGFpbnMoc3JjLmVsZW1lbnRBdChpKSkpIHsKLQkJCQlzcmMucmVtb3ZlRWxlbWVudEF0KGkpOwotCQkJfQotCQl9Ci0JfQotCi0JcHJpdmF0ZSB2b2lkIHJlbW92ZUVuYWJsZWRTQ1AoU2VydmljZUNvbXBvbmVudFByb3Agc2NwKSB7Ci0JCXNjcEVuYWJsZWQucmVtb3ZlRWxlbWVudChzY3ApOwotCQlzY3Auc2VydmljZUNvbXBvbmVudC5jb21wb25lbnRQcm9wcy5yZW1vdmUoc2NwKTsKLQkJc2NwLnNldFN0YXRlKENvbXBvbmVudC5TVEFURV9ESVNQT1NFRCk7Ci0JfQotCi0JLyoqCi0JICogUmVvcmRlciB0aGUgc3BlY2lmaWVkIFNDUCBhbmQgcGxhY2UgaXQgYXQgdGhlIGVuZCBvZiB0aGUgZW5hYmxlZFNDUHMgbGlzdAotCSAqIEBwYXJhbSBzY3AgdGhlIFNDUCB0byByZW9yZGVyCi0JICovCi0JcHJvdGVjdGVkIHZvaWQgcmVvcmRlclNDUChTZXJ2aWNlQ29tcG9uZW50UHJvcCBzY3ApIHsKLQkJc3luY2hyb25pemVkIChzeW5jTG9jaykgewotCQkJaWYgKHNjcEVuYWJsZWQucmVtb3ZlRWxlbWVudChzY3ApKSB7Ci0JCQkJc2NwRW5hYmxlZC5hZGRFbGVtZW50KHNjcCk7Ci0JCQl9Ci0JCX0KLQl9Ci0KLQlwdWJsaWMgdm9pZCByZW1vdmVGcm9tU2F0aXNmaWVkTGlzdChTZXJ2aWNlQ29tcG9uZW50UHJvcCBzY3ApIHsKLQkJVmVjdG9yIHRtcCA9IG5ldyBWZWN0b3IoKTsKLQkJdG1wLmFkZEVsZW1lbnQoc2NwKTsKLQkJbWdyLmVucXVldWVXb3JrKHRoaXMsIFJlc29sdmVyLkRJU1BPU0UsIHRtcCwgZmFsc2UpOwotCX0KLQotCS8qKgotCSAqIFVzZWQgdG8gdHJhdmVyc2UgdGhlIGRlcGVuZGVuY3kgdHJlZSBpbiBvcmRlciB0byBmaW5kIGN5Y2xlcy4KLQkgKiAKLQkgKi8KLQlwcml2YXRlIHN0YXRpYyBjbGFzcyBSZWZlcmVuY2VTQ1BXcmFwcGVyIHsKLQkJcHVibGljIFJlZmVyZW5jZSByZWY7Ci0JCXB1YmxpYyBTZXJ2aWNlQ29tcG9uZW50UHJvcCBwcm9kdWNlcjsKLQotCQlwcm90ZWN0ZWQgUmVmZXJlbmNlU0NQV3JhcHBlcihSZWZlcmVuY2UgcmVmLCBTZXJ2aWNlQ29tcG9uZW50UHJvcCBwcm9kdWNlcikgewotCQkJdGhpcy5yZWYgPSByZWY7Ci0JCQl0aGlzLnByb2R1Y2VyID0gcHJvZHVjZXI7Ci0JCX0KLQotCQlwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewotCQkJcmV0dXJuICJSZWZlcmVuY2UgOiAiICsgcmVmICsgIiA6OjogU0NQIDogIiArIHByb2R1Y2VyOyAvLyROT04tTkxTLTEkIC8vJE5PTi1OTFMtMiQKLQkJfQotCX0KLQotCXB1YmxpYyBDb21wb25lbnQgZ2V0Q29tcG9uZW50KGxvbmcgY29tcG9uZW50SWQpIHsKLQkJc3luY2hyb25pemVkIChzY3BFbmFibGVkKSB7Ci0JCQlmb3IgKGludCBpID0gMDsgaSA8IHNjcEVuYWJsZWQuc2l6ZSgpOyBpKyspIHsKLQkJCQlTZXJ2aWNlQ29tcG9uZW50UHJvcCBzY3AgPSAoU2VydmljZUNvbXBvbmVudFByb3ApIHNjcEVuYWJsZWQuZWxlbWVudEF0KGkpOwotCQkJCWlmIChzY3AuZ2V0SWQoKSA9PSBjb21wb25lbnRJZCkgewotCQkJCQlyZXR1cm4gc2NwOwotCQkJCX0KLQkJCX0KLQkJfQotCQlyZXR1cm4gbnVsbDsKLQl9Ci0KLX0KZGlmZiAtLWdpdCBhL2J1bmRsZXMvb3JnLmVjbGlwc2UuZXF1aW5veC5kcy9zcmMvb3JnL2VjbGlwc2UvZXF1aW5veC9pbnRlcm5hbC9kcy9TQ1JDb21tYW5kUHJvdmlkZXIuamF2YSBiL2J1bmRsZXMvb3JnLmVjbGlwc2UuZXF1aW5veC5kcy9zcmMvb3JnL2VjbGlwc2UvZXF1aW5veC9pbnRlcm5hbC9kcy9TQ1JDb21tYW5kUHJvdmlkZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNTU5OGE0YS4uMDAwMDAwMAotLS0gYS9idW5kbGVzL29yZy5lY2xpcHNlLmVxdWlub3guZHMvc3JjL29yZy9lY2xpcHNlL2VxdWlub3gvaW50ZXJuYWwvZHMvU0NSQ29tbWFuZFByb3ZpZGVyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw4MTAgKzAsMCBAQAotLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKLSAqIENvcHlyaWdodCAoYykgMTk5Ny0yMDExIGJ5IFByb1N5c3QgU29mdHdhcmUgR21iSAotICogaHR0cDovL3d3dy5wcm9zeXN0LmNvbQotICogQWxsIHJpZ2h0cyByZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscwotICogYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2MS4wCi0gKiB3aGljaCBhY2NvbXBhbmllcyB0aGlzIGRpc3RyaWJ1dGlvbiwgYW5kIGlzIGF2YWlsYWJsZSBhdAotICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtdjEwLmh0bWwKLSAqCi0gKiBDb250cmlidXRvcnM6Ci0gKiAgICBQcm9TeXN0IFNvZnR3YXJlIEdtYkggLSBpbml0aWFsIEFQSSBhbmQgaW1wbGVtZW50YXRpb24KLSAqICAgIFNpbW9uIEFyY2hlcgkJIAktIGJ1Zy5pZCA9IDI4ODc4MwotICogICAgTGF6YXIgS2lyY2hldgkJIAktIGJ1Zy5pZCA9IDMyMDM3NwotICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi1wYWNrYWdlIG9yZy5lY2xpcHNlLmVxdWlub3guaW50ZXJuYWwuZHM7Ci0KLWltcG9ydCBqYXZhLmlvLklPRXhjZXB0aW9uOwotaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07Ci1pbXBvcnQgamF2YS5uZXQuVVJMOwotaW1wb3J0IGphdmEudXRpbC4qOwotaW1wb3J0IG9yZy5lY2xpcHNlLmVxdWlub3guaW50ZXJuYWwuZHMuaW1wbC5Db21wb25lbnRJbnN0YW5jZUltcGw7Ci1pbXBvcnQgb3JnLmVjbGlwc2UuZXF1aW5veC5pbnRlcm5hbC5kcy5tb2RlbC4qOwotaW1wb3J0IG9yZy5lY2xpcHNlLm9zZ2kuZnJhbWV3b3JrLmNvbnNvbGUuQ29tbWFuZEludGVycHJldGVyOwotaW1wb3J0IG9yZy5lY2xpcHNlLm9zZ2kuZnJhbWV3b3JrLmNvbnNvbGUuQ29tbWFuZFByb3ZpZGVyOwotaW1wb3J0IG9yZy5lY2xpcHNlLm9zZ2kudXRpbC5OTFM7Ci1pbXBvcnQgb3JnLm9zZ2kuZnJhbWV3b3JrLio7Ci1pbXBvcnQgb3JnLm9zZ2kuc2VydmljZS5jb21wb25lbnQuQ29tcG9uZW50Q29uc3RhbnRzOwotCi0vKiogCi0gKiBTQ1JDb21tYW5kUHJvdmlkZXIgY2xhc3MgcHJvdmlkZXMgc29tZSB1c2VmdWwgY29tbWFuZHMgZm9yIG1hbmFnaW5nIHRoZSBTZXJ2aWNlIENvbXBvbmVudCBSdW50aW1lCi0gKgotICogQGF1dGhvciBTdG95YW4gQm9zaGV2Ci0gKiBAdmVyc2lvbiAxLjAKLSAqLwotcHVibGljIGNsYXNzIFNDUkNvbW1hbmRQcm92aWRlciBpbXBsZW1lbnRzIENvbW1hbmRQcm92aWRlciB7Ci0KLQlwcml2YXRlIFJlc29sdmVyIHJlc29sdmVyOwotCXByaXZhdGUgU0NSTWFuYWdlciBzY3JNYW5hZ2VyOwotCi0JcHJpdmF0ZSBpbnQgY3VySUQgPSAxOwotCXByaXZhdGUgSGFzaHRhYmxlIGNvbXBvbmVudFJlZnNJRHMgPSBudWxsOwotCi0JcHJvdGVjdGVkIFNDUkNvbW1hbmRQcm92aWRlcihTQ1JNYW5hZ2VyIHNjck1hbmFnZXIpIHsKLQkJdGhpcy5zY3JNYW5hZ2VyID0gc2NyTWFuYWdlcjsKLQkJdGhpcy5yZXNvbHZlciA9IEluc3RhbmNlUHJvY2Vzcy5yZXNvbHZlcjsKLQl9Ci0KLQlwdWJsaWMgU3RyaW5nIGdldEhlbHAoKSB7Ci0JCXJldHVybiBnZXRIZWxwKG51bGwpOwotCX0KLQotCS8qCi0JICogVGhpcyBtZXRob2QgZWl0aGVyIHJldHVybnMgdGhlIGhlbHAgbWVzc2FnZSBmb3IgYSBwYXJ0aWN1bGFyIGNvbW1hbmQsIAotCSAqIG9yIHJldHVybnMgdGhlIGhlbHAgbWVzc2FnZXMgZm9yIGFsbCBjb21tYW5kcyAoaWYgY29tbWFuZE5hbWUgaXMgbnVsbCkKLQkgKi8KLQlwcml2YXRlIFN0cmluZyBnZXRIZWxwKFN0cmluZyBjb21tYW5kTmFtZSkgewotCQlib29sZWFuIGFsbCA9IGNvbW1hbmROYW1lID09IG51bGw7Ci0JCVN0cmluZ0J1ZmZlciByZXMgPSBuZXcgU3RyaW5nQnVmZmVyKDEwMDApOwotCQlpZiAoYWxsKSB7Ci0JCQlyZXMuYXBwZW5kKCItLS0iKS5hcHBlbmQoTWVzc2FnZXMuU0NSKS5hcHBlbmQoIi0tLVxyXG4iKTsgLy8kTk9OLU5MUy0xJCAvLyROT04tTkxTLTIkCi0JCX0KLQkJaWYgKGFsbCB8fCAibGlzdCIuZXF1YWxzKGNvbW1hbmROYW1lKSB8fCAibHMiLmVxdWFscyhjb21tYW5kTmFtZSkpIHsgLy8kTk9OLU5MUy0xJCAvLyROT04tTkxTLTIkCi0JCQlyZXMuYXBwZW5kKCJcdGxpc3QvbHMgWy1jXSBbYnVuZGxlIGlkXSAtICIpLmFwcGVuZChNZXNzYWdlcy5MSVNUX0FMTF9DT01QT05FTlRTKTsgLy8kTk9OLU5MUy0xJAotCQkJcmVzLmFwcGVuZCgiXHJcblx0XHRcdCIpLmFwcGVuZChNZXNzYWdlcy5MSVNUX0FMTF9CVU5ETEVfQ09NUE9ORU5UUyk7IC8vJE5PTi1OTFMtMSQKLQkJfQotCQlpZiAoYWxsIHx8ICJjb21wb25lbnQiLmVxdWFscyhjb21tYW5kTmFtZSkgfHwgImNvbXAiLmVxdWFscyhjb21tYW5kTmFtZSkpIHsgLy8kTk9OLU5MUy0xJCAvLyROT04tTkxTLTIkCi0JCQlyZXMuYXBwZW5kKCJcclxuXHRjb21wb25lbnQvY29tcCA8Y29tcG9uZW50IGlkPiAtICIpLmFwcGVuZChNZXNzYWdlcy5QUklOVF9DT01QT05FTlRfSU5GTyk7IC8vJE5PTi1OTFMtMSQKLQkJCXJlcy5hcHBlbmQoIlxyXG5cdFx0XHQ8Y29tcG9uZW50IGlkPiAtICIpLmFwcGVuZChNZXNzYWdlcy5DT01QT05FTlRfSURfREVGSU5JRURfQllfTElTVF9DT01NQU5EKTsgLy8kTk9OLU5MUy0xJAotCQl9Ci0JCWlmIChhbGwgfHwgImVuYWJsZSIuZXF1YWxzKGNvbW1hbmROYW1lKSB8fCAiZW4iLmVxdWFscyhjb21tYW5kTmFtZSkpIHsgLy8kTk9OLU5MUy0xJCAvLyROT04tTkxTLTIkCi0JCQlyZXMuYXBwZW5kKCJcclxuXHRlbmFibGUvZW4gPGNvbXBvbmVudCBpZD4gLSAiKS5hcHBlbmQoTWVzc2FnZXMuRU5BQkxFX0NPTVBPTkVOVCk7IC8vJE5PTi1OTFMtMSQKLQkJCXJlcy5hcHBlbmQoIlxyXG5cdFx0XHQ8Y29tcG9uZW50IGlkPiAtICIpLmFwcGVuZChNZXNzYWdlcy5DT01QT05FTlRfSURfREVGSU5JRURfQllfTElTVF9DT01NQU5EKTsgLy8kTk9OLU5MUy0xJAotCQl9Ci0JCWlmIChhbGwgfHwgImRpc2FibGUiLmVxdWFscyhjb21tYW5kTmFtZSkgfHwgImRpcyIuZXF1YWxzKGNvbW1hbmROYW1lKSkgeyAvLyROT04tTkxTLTEkIC8vJE5PTi1OTFMtMiQKLQkJCXJlcy5hcHBlbmQoIlxuXHRkaXNhYmxlL2RpcyA8Y29tcG9uZW50IGlkPiAtICIpLmFwcGVuZChNZXNzYWdlcy5ESVNBQkxFX0NPTVBPTkVOVCk7IC8vJE5PTi1OTFMtMSQKLQkJCXJlcy5hcHBlbmQoIlxuXHRcdFx0PGNvbXBvbmVudCBpZD4gLSAiKS5hcHBlbmQoTWVzc2FnZXMuQ09NUE9ORU5UX0lEX0RFRklOSUVEX0JZX0xJU1RfQ09NTUFORCk7IC8vJE5PTi1OTFMtMSQKLQkJfQotCQlpZiAoYWxsIHx8ICJlbmFibGVBbGwiLmVxdWFscyhjb21tYW5kTmFtZSkgfHwgImVuQWxsIi5lcXVhbHMoY29tbWFuZE5hbWUpKSB7IC8vJE5PTi1OTFMtMSQgLy8kTk9OLU5MUy0yJAotCQkJcmVzLmFwcGVuZCgiXHJcblx0ZW5hYmxlQWxsL2VuQWxsIFtidW5kbGUgaWRdIC0gIikuYXBwZW5kKE1lc3NhZ2VzLkVOQUJMRV9BTExfQ09NUE9ORU5UUyk7IC8vJE5PTi1OTFMtMSQKLQkJfQotCQlpZiAoYWxsIHx8ICJkaXNhYmxlQWxsIi5lcXVhbHMoY29tbWFuZE5hbWUpIHx8ICJkaXNBbGwiLmVxdWFscyhjb21tYW5kTmFtZSkpIHsgLy8kTk9OLU5MUy0xJCAvLyROT04tTkxTLTIkCi0JCQlyZXMuYXBwZW5kKCJcblx0ZGlzYWJsZUFsbC9kaXNBbGwgW2J1bmRsZSBpZF0gLSAiKS5hcHBlbmQoTWVzc2FnZXMuRElTQUJMRV9BTExfQ09NUE9ORU5UUykuYXBwZW5kKCJcbiIpOyAvLyROT04tTkxTLTEkIC8vJE5PTi1OTFMtMiQKLQkJfQotCQlyZXR1cm4gcmVzLnRvU3RyaW5nKCk7Ci0JfQotCi0JLyoqCi0JICogIEhhbmRsZSB0aGUgbGlzdCBjb21tYW5kCi0JICoKLQkgKiAgQHBhcmFtIGludHAgQSBDb21tYW5kSW50ZXJwcmV0ZXIgb2JqZWN0IGNvbnRhaW5pbmcgdGhlIGNvbW1hbmQgYW5kIGl0J3MgYXJndW1lbnRzLgotCSAqLwotCXB1YmxpYyB2b2lkIF9saXN0KENvbW1hbmRJbnRlcnByZXRlciBpbnRwKSB0aHJvd3MgRXhjZXB0aW9uIHsKLQkJYm9vbGVhbiBjb21wbGV0ZUluZm8gPSBmYWxzZTsKLQkJQnVuZGxlIGIgPSBudWxsOwotCQlTdHJpbmdbXSBwYXJhbXMgPSBnZXRQYXJhbXMoaW50cCk7Ci0JCWlmIChwYXJhbXMubGVuZ3RoID4gMCkgewotCQkJaWYgKHBhcmFtc1swXS5lcXVhbHMoIi1jIikpIHsgLy8kTk9OLU5MUy0xJAotCQkJCWNvbXBsZXRlSW5mbyA9IHRydWU7Ci0JCQkJaWYgKHBhcmFtcy5sZW5ndGggPiAxKSB7Ci0JCQkJCWIgPSBnZXRCdW5kbGUoaW50cCwgcGFyYW1zWzFdKTsKLQkJCQkJaWYgKGIgPT0gbnVsbCkgewotCQkJCQkJcmV0dXJuOwotCQkJCQl9Ci0JCQkJfQotCQkJfSBlbHNlIHsKLQkJCQliID0gZ2V0QnVuZGxlKGludHAsIHBhcmFtc1swXSk7Ci0JCQkJaWYgKGIgPT0gbnVsbCkgewotCQkJCQlyZXR1cm47Ci0JCQkJfQotCQkJfQotCQl9Ci0JCWxpc3RDb21wb25lbnRzKGludHAsIGIsIGNvbXBsZXRlSW5mbyk7Ci0JfQotCi0JLyoqCi0JICogIFNob3J0Y3V0IHRvIGxpc3QgY29tbWFuZAotCSAqCi0JICogIEBwYXJhbSBpbnRwIEEgQ29tbWFuZEludGVycHJldGVyIG9iamVjdCBjb250YWluaW5nIHRoZSBjb21tYW5kIGFuZCBpdCdzIGFyZ3VtZW50cy4KLQkgKi8KLQlwdWJsaWMgdm9pZCBfbHMoQ29tbWFuZEludGVycHJldGVyIGludHApIHRocm93cyBFeGNlcHRpb24gewotCQlfbGlzdChpbnRwKTsKLQl9Ci0KLQkvKioKLQkgKiAgSGFuZGxlIHRoZSBjb21wb25lbnQgY29tbWFuZAotCSAqCi0JICogIEBwYXJhbSBpbnRwIEEgQ29tbWFuZEludGVycHJldGVyIG9iamVjdCBjb250YWluaW5nIHRoZSBjb21tYW5kIGFuZCBpdCdzIGFyZ3VtZW50cy4KLQkgKi8KLQlwdWJsaWMgdm9pZCBfY29tcG9uZW50KENvbW1hbmRJbnRlcnByZXRlciBpbnRwKSB0aHJvd3MgRXhjZXB0aW9uIHsKLQkJU3RyaW5nW10gcGFyYW1zID0gZ2V0UGFyYW1zKGludHApOwotCQlpZiAocGFyYW1zLmxlbmd0aCA+IDApIHsKLQkJCWludCBjb21wSW5kZXggPSAtMTsKLQkJCXRyeSB7Ci0JCQkJY29tcEluZGV4ID0gSW50ZWdlci5wYXJzZUludChwYXJhbXNbMF0pOwotCQkJfSBjYXRjaCAoTnVtYmVyRm9ybWF0RXhjZXB0aW9uIG5mZSkgewotCQkJCWludHAucHJpbnRsbihOTFMuYmluZChNZXNzYWdlcy5XUk9OR19QQVJBTUVURVIsIHBhcmFtc1swXSkpOwotCQkJCXJldHVybjsKLQkJCX0KLQkJCXByaW50Q29tcG9uZW50RGV0YWlscyhpbnRwLCBjb21wSW5kZXgpOwotCQkJcmV0dXJuOwotCQl9Ci0JCWludHAucHJpbnRsbihNZXNzYWdlcy5FWFBFQ1RFRF9QQVJBTUVURVJfQ09NUE9ORU5UX0lEKTsKLQl9Ci0KLQkvKioKLQkgKiAgU2hvcnRjdXQgdG8gY29tcG9uZW50IGNvbW1hbmQKLQkgKgotCSAqICBAcGFyYW0gaW50cCBBIENvbW1hbmRJbnRlcnByZXRlciBvYmplY3QgY29udGFpbmluZyB0aGUgY29tbWFuZCBhbmQgaXQncyBhcmd1bWVudHMuCi0JICovCi0JcHVibGljIHZvaWQgX2NvbXAoQ29tbWFuZEludGVycHJldGVyIGludHApIHRocm93cyBFeGNlcHRpb24gewotCQlfY29tcG9uZW50KGludHApOwotCX0KLQotCS8qKgotCSAqICBIYW5kbGUgdGhlIGVuYWJsZSBjb21tYW5kCi0JICoKLQkgKiAgQHBhcmFtIGludHAgQSBDb21tYW5kSW50ZXJwcmV0ZXIgb2JqZWN0IGNvbnRhaW5pbmcgdGhlIGNvbW1hbmQgYW5kIGl0J3MgYXJndW1lbnRzLgotCSAqLwotCXB1YmxpYyB2b2lkIF9lbmFibGUoQ29tbWFuZEludGVycHJldGVyIGludHApIHRocm93cyBFeGNlcHRpb24gewotCQlTdHJpbmdbXSBwYXJhbXMgPSBnZXRQYXJhbXMoaW50cCk7Ci0JCWlmIChwYXJhbXMubGVuZ3RoID4gMCkgewotCQkJaW50IGNvbXBJbmRleCA9IC0xOwotCQkJdHJ5IHsKLQkJCQljb21wSW5kZXggPSBJbnRlZ2VyLnBhcnNlSW50KHBhcmFtc1swXSk7Ci0JCQl9IGNhdGNoIChOdW1iZXJGb3JtYXRFeGNlcHRpb24gbmZlKSB7Ci0JCQkJaW50cC5wcmludGxuKE5MUy5iaW5kKE1lc3NhZ2VzLldST05HX1BBUkFNRVRFUiwgcGFyYW1zWzBdKSk7Ci0JCQkJcmV0dXJuOwotCQkJfQotCQkJZW5hYmxlQ29tcG9uZW50KGludHAsIGNvbXBJbmRleCk7Ci0JCQlyZXR1cm47Ci0JCX0KLQkJaW50cC5wcmludGxuKE1lc3NhZ2VzLkVYUEVDVEVEX1BBUkFNRVRFUl9DT01QT05FTlRfSUQpOwotCX0KLQotCS8qKgotCSAqICBTaG9ydGN1dCB0byBlbmFibGUgY29tbWFuZAotCSAqCi0JICogIEBwYXJhbSBpbnRwIEEgQ29tbWFuZEludGVycHJldGVyIG9iamVjdCBjb250YWluaW5nIHRoZSBjb21tYW5kIGFuZCBpdCdzIGFyZ3VtZW50cy4KLQkgKi8KLQlwdWJsaWMgdm9pZCBfZW4oQ29tbWFuZEludGVycHJldGVyIGludHApIHRocm93cyBFeGNlcHRpb24gewotCQlfZW5hYmxlKGludHApOwotCX0KLQotCS8qKgotCSAqICBIYW5kbGUgdGhlIGRpc2FibGUgY29tbWFuZAotCSAqCi0JICogIEBwYXJhbSBpbnRwIEEgQ29tbWFuZEludGVycHJldGVyIG9iamVjdCBjb250YWluaW5nIHRoZSBjb21tYW5kIGFuZCBpdCdzIGFyZ3VtZW50cy4KLQkgKi8KLQlwdWJsaWMgdm9pZCBfZGlzYWJsZShDb21tYW5kSW50ZXJwcmV0ZXIgaW50cCkgdGhyb3dzIEV4Y2VwdGlvbiB7Ci0JCVN0cmluZ1tdIHBhcmFtcyA9IGdldFBhcmFtcyhpbnRwKTsKLQkJaWYgKHBhcmFtcy5sZW5ndGggPiAwKSB7Ci0JCQlpbnQgY29tcEluZGV4ID0gLTE7Ci0JCQl0cnkgewotCQkJCWNvbXBJbmRleCA9IEludGVnZXIucGFyc2VJbnQocGFyYW1zWzBdKTsKLQkJCX0gY2F0Y2ggKE51bWJlckZvcm1hdEV4Y2VwdGlvbiBuZmUpIHsKLQkJCQlpbnRwLnByaW50bG4oTkxTLmJpbmQoTWVzc2FnZXMuV1JPTkdfUEFSQU1FVEVSLCBwYXJhbXNbMF0pKTsKLQkJCQlyZXR1cm47Ci0JCQl9Ci0JCQlkaXNhYmxlQ29tcG9uZW50KGludHAsIGNvbXBJbmRleCk7Ci0JCQlyZXR1cm47Ci0JCX0KLQkJaW50cC5wcmludGxuKE1lc3NhZ2VzLkVYUEVDVEVEX1BBUkFNRVRFUl9DT01QT05FTlRfSUQpOwotCX0KLQotCS8qKgotCSAqICBTaG9ydGN1dCB0byBkaXNhYmxlIGNvbW1hbmQKLQkgKgotCSAqICBAcGFyYW0gaW50cCBBIENvbW1hbmRJbnRlcnByZXRlciBvYmplY3QgY29udGFpbmluZyB0aGUgY29tbWFuZCBhbmQgaXQncyBhcmd1bWVudHMuCi0JICovCi0JcHVibGljIHZvaWQgX2RpcyhDb21tYW5kSW50ZXJwcmV0ZXIgaW50cCkgdGhyb3dzIEV4Y2VwdGlvbiB7Ci0JCV9kaXNhYmxlKGludHApOwotCX0KLQotCS8qKgotCSAqICBIYW5kbGUgdGhlIGVuYWJsZUFsbCBjb21tYW5kCi0JICoKLQkgKiAgQHBhcmFtIGludHAgQSBDb21tYW5kSW50ZXJwcmV0ZXIgb2JqZWN0IGNvbnRhaW5pbmcgdGhlIGNvbW1hbmQgYW5kIGl0J3MgYXJndW1lbnRzLgotCSAqLwotCXB1YmxpYyB2b2lkIF9lbmFibGVBbGwoQ29tbWFuZEludGVycHJldGVyIGludHApIHRocm93cyBFeGNlcHRpb24gewotCQlTdHJpbmdbXSBwYXJhbXMgPSBnZXRQYXJhbXMoaW50cCk7Ci0JCUJ1bmRsZSBiID0gbnVsbDsKLQkJaWYgKHBhcmFtcy5sZW5ndGggPiAwKSB7Ci0JCQliID0gZ2V0QnVuZGxlKGludHAsIHBhcmFtc1swXSk7Ci0JCQlpZiAoYiA9PSBudWxsKSB7Ci0JCQkJcmV0dXJuOwotCQkJfQotCQl9Ci0JCWVuYWJsZUFsbChpbnRwLCBiKTsKLQl9Ci0KLQkvKioKLQkgKiAgU2hvcnRjdXQgdG8gZW5hYmxlQWxsIGNvbW1hbmQKLQkgKgotCSAqICBAcGFyYW0gaW50cCBBIENvbW1hbmRJbnRlcnByZXRlciBvYmplY3QgY29udGFpbmluZyB0aGUgY29tbWFuZCBhbmQgaXQncyBhcmd1bWVudHMuCi0JICovCi0JcHVibGljIHZvaWQgX2VuQWxsKENvbW1hbmRJbnRlcnByZXRlciBpbnRwKSB0aHJvd3MgRXhjZXB0aW9uIHsKLQkJX2VuYWJsZUFsbChpbnRwKTsKLQl9Ci0KLQkvKioKLQkgKiAgSGFuZGxlIHRoZSBkaXNhYmxlQWxsIGNvbW1hbmQKLQkgKgotCSAqICBAcGFyYW0gaW50cCBBIENvbW1hbmRJbnRlcnByZXRlciBvYmplY3QgY29udGFpbmluZyB0aGUgY29tbWFuZCBhbmQgaXQncyBhcmd1bWVudHMuCi0JICovCi0JcHVibGljIHZvaWQgX2Rpc2FibGVBbGwoQ29tbWFuZEludGVycHJldGVyIGludHApIHRocm93cyBFeGNlcHRpb24gewotCQlTdHJpbmdbXSBwYXJhbXMgPSBnZXRQYXJhbXMoaW50cCk7Ci0JCUJ1bmRsZSBiID0gbnVsbDsKLQkJaWYgKHBhcmFtcy5sZW5ndGggPiAwKSB7Ci0JCQliID0gZ2V0QnVuZGxlKGludHAsIHBhcmFtc1swXSk7Ci0JCQlpZiAoYiA9PSBudWxsKSB7Ci0JCQkJcmV0dXJuOwotCQkJfQotCQl9Ci0JCWRpc2FibGVBbGwoaW50cCwgYik7Ci0JfQotCi0JLyoqCi0JICogIFNob3J0Y3V0IHRvIGRpc2FibGVBbGwgY29tbWFuZAotCSAqCi0JICogIEBwYXJhbSBpbnRwIEEgQ29tbWFuZEludGVycHJldGVyIG9iamVjdCBjb250YWluaW5nIHRoZSBjb21tYW5kIGFuZCBpdCdzIGFyZ3VtZW50cy4KLQkgKi8KLQlwdWJsaWMgdm9pZCBfZGlzQWxsKENvbW1hbmRJbnRlcnByZXRlciBpbnRwKSB0aHJvd3MgRXhjZXB0aW9uIHsKLQkJX2Rpc2FibGVBbGwoaW50cCk7Ci0JfQotCi0JLyoqCi0JICogSGFuZGxlcyB0aGUgaGVscCBjb21tYW5kCi0JICogCi0JICogQHBhcmFtIGludHAKLQkgKiBAcmV0dXJuIGRlc2NyaXB0aW9uIGZvciBhIHBhcnRpY3VsYXIgY29tbWFuZCBvciBmYWxzZSBpZiB0aGVyZSBpcyBubyBjb21tYW5kIHdpdGggdGhlIHNwZWNpZmllZCBuYW1lCi0JICovCi0JcHVibGljIE9iamVjdCBfaGVscChDb21tYW5kSW50ZXJwcmV0ZXIgaW50cCkgewotCQlTdHJpbmcgY29tbWFuZE5hbWUgPSBpbnRwLm5leHRBcmd1bWVudCgpOwotCQlpZiAoY29tbWFuZE5hbWUgPT0gbnVsbCkgewotCQkJcmV0dXJuIEJvb2xlYW4uRkFMU0U7Ci0JCX0KLQkJU3RyaW5nIGhlbHAgPSBnZXRIZWxwKGNvbW1hbmROYW1lKTsKLQotCQlpZiAoaGVscC5sZW5ndGgoKSA+IDApIHsKLQkJCXJldHVybiBoZWxwOwotCQl9Ci0JCXJldHVybiBCb29sZWFuLkZBTFNFOwotCX0KLQotCXByaXZhdGUgU3RyaW5nW10gZ2V0UGFyYW1zKENvbW1hbmRJbnRlcnByZXRlciBpbnRwKSB7Ci0JCVZlY3RvciBhcmd1bWVudHMgPSBuZXcgVmVjdG9yKCk7Ci0JCVN0cmluZyBhcmcgPSBpbnRwLm5leHRBcmd1bWVudCgpOwotCQl3aGlsZSAoYXJnICE9IG51bGwpIHsKLQkJCWlmIChhcmcgIT0gbnVsbCkgewotCQkJCWFyZ3VtZW50cy5hZGRFbGVtZW50KGFyZyk7Ci0JCQl9Ci0JCQlhcmcgPSBpbnRwLm5leHRBcmd1bWVudCgpOwotCQl9Ci0JCVN0cmluZ1tdIHJlcyA9IG5ldyBTdHJpbmdbYXJndW1lbnRzLnNpemUoKV07Ci0JCWFyZ3VtZW50cy5jb3B5SW50byhyZXMpOwotCQlyZXR1cm4gcmVzOwotCX0KLQotCXByaXZhdGUgQnVuZGxlIGdldEJ1bmRsZShDb21tYW5kSW50ZXJwcmV0ZXIgaW50cCwgU3RyaW5nIGJpZFN0cmluZykgewotCQlsb25nIGJpZCA9IC0xOwotCQl0cnkgewotCQkJYmlkID0gTG9uZy5wYXJzZUxvbmcoYmlkU3RyaW5nKTsKLQkJfSBjYXRjaCAoTnVtYmVyRm9ybWF0RXhjZXB0aW9uIG5mZSkgewotCQkJaW50cC5wcmludGxuKE5MUy5iaW5kKE1lc3NhZ2VzLldST05HX1BBUkFNRVRFUjIsIGJpZFN0cmluZykpOwotCQkJcmV0dXJuIG51bGw7Ci0JCX0KLQkJQnVuZGxlIGIgPSBBY3RpdmF0b3IuYmMuZ2V0QnVuZGxlKGJpZCk7Ci0JCWlmIChiID09IG51bGwpIHsKLQkJCWludHAucHJpbnRsbihOTFMuYmluZChNZXNzYWdlcy5CVU5ETEVfTk9UX0ZPVU5ELCBiaWRTdHJpbmcpKTsKLQkJfQotCQlyZXR1cm4gYjsKLQl9Ci0KLQlwcml2YXRlIENvbXBvbmVudFJlZiBmaW5kQ29tcG9uZW50V2l0aElEKGludCBjb21wSUQpIHsKLQkJaWYgKGNvbXBvbmVudFJlZnNJRHMgIT0gbnVsbCkgewotCQkJRW51bWVyYXRpb24ga2V5cyA9IGNvbXBvbmVudFJlZnNJRHMua2V5cygpOwotCQkJd2hpbGUgKGtleXMuaGFzTW9yZUVsZW1lbnRzKCkpIHsKLQkJCQlDb21wb25lbnRSZWYga2V5ID0gKENvbXBvbmVudFJlZikga2V5cy5uZXh0RWxlbWVudCgpOwotCQkJCWlmIChrZXkuaWQgPT0gY29tcElEKSB7Ci0JCQkJCXJldHVybiBrZXk7Ci0JCQkJfQotCQkJfQotCQl9Ci0JCXJldHVybiBudWxsOwotCX0KLQotCXByaXZhdGUgdm9pZCBwcmludENvbXBvbmVudERldGFpbHMoQ29tbWFuZEludGVycHJldGVyIGludHAsIGludCBjb21wb25lbnRJbmRleCkgewotCQlDb21wb25lbnRSZWYgY1JlZiA9IGZpbmRDb21wb25lbnRXaXRoSUQoY29tcG9uZW50SW5kZXgpOwotCQlpZiAoY1JlZiA9PSBudWxsKSB7Ci0JCQlpbnRwLnByaW50bG4oTWVzc2FnZXMuSU5WQUxJRF9DT01QT05FTlRfSUQpOwotCQkJcmV0dXJuOwotCQl9Ci0KLQkJQnVuZGxlIGIgPSBBY3RpdmF0b3IuYmMuZ2V0QnVuZGxlKGNSZWYuYmlkKTsKLQkJaWYgKGIgIT0gbnVsbCkgewotCQkJVmVjdG9yIGNvbXBvbmVudHMgPSAoVmVjdG9yKSBzY3JNYW5hZ2VyLmJ1bmRsZVRvU2VydmljZUNvbXBvbmVudHMuZ2V0KGIpOwotCQkJaWYgKGNvbXBvbmVudHMgIT0gbnVsbCkgewotCQkJCWZvciAoaW50IGkgPSAwOyBpIDwgY29tcG9uZW50cy5zaXplKCk7IGkrKykgewotCQkJCQlTZXJ2aWNlQ29tcG9uZW50IHNjID0gKFNlcnZpY2VDb21wb25lbnQpIGNvbXBvbmVudHMuZWxlbWVudEF0KGkpOwotCQkJCQlpZiAoc2MubmFtZS5lcXVhbHMoY1JlZi5uYW1lKSkgewotCQkJCQkJcHJpbnRDb21wb25lbnREZXRhaWxzKGludHAsIHNjKTsKLQkJCQkJCWJyZWFrOwotCQkJCQl9Ci0JCQkJfQotCQkJfQotCQl9IGVsc2UgewotCQkJaW50cC5wcmludGxuKE1lc3NhZ2VzLkNBTk5PVF9GSU5EX0NPTVBPTkVOVF9CVU5ETEUpOwotCQl9Ci0JfQotCi0JcHJpdmF0ZSB2b2lkIHByaW50Q29tcG9uZW50RGV0YWlscyhDb21tYW5kSW50ZXJwcmV0ZXIgaW50cCwgU2VydmljZUNvbXBvbmVudCBzYykgewotCQlpbnRwLnByaW50bG4oIlx0IiArIHNjLnRvU3RyaW5nKCkpOyAvLyROT04tTkxTLTEkCi0JCWludHAucHJpbnRsbihNZXNzYWdlcy5EWU5BTUlDX0lORk8pOwotCQlWZWN0b3IgdW5yZXN1bHZlZFJlZmVyZW5jZXMgPSBnZXRVbnJlc29sdmVkUmVmZXJlbmNlcyhzYyk7Ci0JCWJvb2xlYW4gcmVzb2x2ZWQgPSB0cnVlOwotCQlpZiAodW5yZXN1bHZlZFJlZmVyZW5jZXMgIT0gbnVsbCkgewotCQkJZm9yIChpbnQgaSA9IDA7IGkgPCB1bnJlc3VsdmVkUmVmZXJlbmNlcy5zaXplKCk7IGkrKykgewotCQkJCWlmIChpc01hbmRhdG9yeSgoQ29tcG9uZW50UmVmZXJlbmNlKSB1bnJlc3VsdmVkUmVmZXJlbmNlcy5lbGVtZW50QXQoaSkpKSB7Ci0JCQkJCXJlc29sdmVkID0gZmFsc2U7Ci0JCQkJCWJyZWFrOwotCQkJCX0KLQkJCX0KLQkJfQotCQlpZiAocmVzb2x2ZWQpIHsKLQkJCWludHAucHJpbnRsbihNZXNzYWdlcy5DT01QT05FTlRfUkVTT0xWRUQpOwotCQl9IGVsc2UgewotCQkJaW50cC5wcmludGxuKE1lc3NhZ2VzLkNPTVBPTkVOVF9OT1RfUkVTT0xWRUQpOwotCQl9Ci0KLQkJaWYgKHVucmVzdWx2ZWRSZWZlcmVuY2VzICE9IG51bGwpIHsKLQkJCWludHAucHJpbnRsbihNZXNzYWdlcy5OT1RfUkVTT0xWRURfUkVGRVJFTkNFUyk7Ci0JCQlmb3IgKGludCBpID0gMDsgaSA8IHVucmVzdWx2ZWRSZWZlcmVuY2VzLnNpemUoKTsgaSsrKSB7Ci0JCQkJaW50cC5wcmludGxuKCIgICAgIiArIHVucmVzdWx2ZWRSZWZlcmVuY2VzLmVsZW1lbnRBdChpKSk7IC8vJE5PTi1OTFMtMSQKLQkJCX0KLQkJfSBlbHNlIHsKLQkJCWludHAucHJpbnRsbihNZXNzYWdlcy5BTExfUkVGRVJFTkNFU19SRVNPTFZFRCk7Ci0JCX0KLQkJaW50cC5wcmludGxuKE1lc3NhZ2VzLkNPTVBPTkVOVF9DT05GSUdVUkFUSU9OUyk7Ci0JCVZlY3RvciBlbmFibGVkU0NQcyA9IChWZWN0b3IpIHJlc29sdmVyLnNjcEVuYWJsZWQuY2xvbmUoKTsKLQkJZm9yIChpbnQgaSA9IDA7IGkgPCBlbmFibGVkU0NQcy5zaXplKCk7IGkrKykgewotCQkJU2VydmljZUNvbXBvbmVudFByb3Agc2NwID0gKFNlcnZpY2VDb21wb25lbnRQcm9wKSBlbmFibGVkU0NQcy5lbGVtZW50QXQoaSk7Ci0JCQlpZiAoc2NwLnNlcnZpY2VDb21wb25lbnQgPT0gc2MpIHsKLQkJCQlwcmludFNDUChpbnRwLCBzY3ApOwotCQkJfQotCQl9Ci0JCWlmIChzYy5nZXRDb25maWd1cmF0aW9uUG9saWN5KCkgPT0gU2VydmljZUNvbXBvbmVudC5DT05GX1BPTElDWV9SRVFVSVJFKSB7Ci0JCQlpZiAocmVzb2x2ZWQgJiYgKHNjLmNvbXBvbmVudFByb3BzID09IG51bGwgfHwgc2MuY29tcG9uZW50UHJvcHMuc2l6ZSgpID09IDApKSB7Ci0JCQkJaW50cC5wcmludGxuKE1lc3NhZ2VzLk5PX0JVSUxUX0NPTVBPTkVOVF9DT05GSUdVUkFUSU9OUyk7Ci0JCQl9Ci0JCX0KLQkJaW50cC5wcmludGxuKCk7Ci0JfQotCi0JcHJpdmF0ZSB2b2lkIHByaW50U0NQKENvbW1hbmRJbnRlcnByZXRlciBpbnRwLCBTZXJ2aWNlQ29tcG9uZW50UHJvcCBzY3ApIHsKLQkJSGFzaHRhYmxlIHByb3BzID0gc2NwLnByb3BlcnRpZXM7Ci0JCWludHAucHJpbnRsbihNZXNzYWdlcy5DT05GSUdfUFJPUEVSVElFUyk7Ci0JCUVudW1lcmF0aW9uIGtleXMgPSBwcm9wcy5rZXlzKCk7Ci0JCXdoaWxlIChrZXlzLmhhc01vcmVFbGVtZW50cygpKSB7Ci0JCQlPYmplY3Qga2V5ID0ga2V5cy5uZXh0RWxlbWVudCgpOwotCQkJT2JqZWN0IHZhbHVlID0gcHJvcHMuZ2V0KGtleSk7Ci0JCQlpbnRwLnByaW50KCIgICAgICAiICsga2V5ICsgIiA9ICIpOyAvLyROT04tTkxTLTEkIC8vJE5PTi1OTFMtMiQKLQkJCWludHAucHJpbnQoU0NSVXRpbC5nZXRTdHJpbmdSZXByZXNlbnRhdGlvbih2YWx1ZSkpOwotCQkJaW50cC5wcmludGxuKCk7Ci0JCX0KLQkJaW50cC5wcmludGxuKCIgICAgSW5zdGFuY2VzOiIpOyAvLyROT04tTkxTLTEkCi0JCWlmIChzY3AuaW5zdGFuY2VzLnNpemUoKSA+IDApIHsKLQkJCUNvbXBvbmVudEluc3RhbmNlSW1wbCBpbnN0YW5jZSA9IG51bGw7Ci0JCQlmb3IgKGludCBpID0gMDsgaSA8IHNjcC5pbnN0YW5jZXMuc2l6ZSgpOyBpKyspIHsKLQkJCQlpbnN0YW5jZSA9IChDb21wb25lbnRJbnN0YW5jZUltcGwpIHNjcC5pbnN0YW5jZXMuZWxlbWVudEF0KGkpOwotCQkJCWludHAucHJpbnRsbigiICAgICAgIiArIGluc3RhbmNlKTsgLy8kTk9OLU5MUy0xJAotCQkJCWlmIChpbnN0YW5jZS5iaW5kZWRTZXJ2aWNlcy5zaXplKCkgPiAwKSB7Ci0JCQkJCWludHAucHJpbnRsbigiICAgIAlCb3VuZCBSZWZlcmVuY2VzOiIpOyAvLyROT04tTkxTLTEkCi0JCQkJCUVudW1lcmF0aW9uIHJlZnMgPSBpbnN0YW5jZS5iaW5kZWRTZXJ2aWNlcy5rZXlzKCk7Ci0JCQkJCVNlcnZpY2VSZWZlcmVuY2Ugc3IgPSBudWxsOwotCQkJCQl3aGlsZSAocmVmcy5oYXNNb3JlRWxlbWVudHMoKSkgewotCQkJCQkJc3IgPSAoU2VydmljZVJlZmVyZW5jZSkgcmVmcy5uZXh0RWxlbWVudCgpOwotCQkJCQkJT2JqZWN0IGludGVyZmFjZXMgPSBzci5nZXRQcm9wZXJ0eShDb25zdGFudHMuT0JKRUNUQ0xBU1MpOwotCQkJCQkJaW50cC5wcmludGxuKCIgICAgICAgICIgKyBTQ1JVdGlsLmdldFN0cmluZ1JlcHJlc2VudGF0aW9uKGludGVyZmFjZXMpKTsgLy8kTk9OLU5MUy0xJAotCQkJCQkJaW50cC5wcmludGxuKCIgICAgICAJCS0+ICIgKyBpbnN0YW5jZS5iaW5kZWRTZXJ2aWNlcy5nZXQoc3IpKTsgLy8kTk9OLU5MUy0xJAotCQkJCQl9Ci0JCQkJfQotCQkJfQotCQl9IGVsc2UgewotCQkJLy8gdGhlcmUgYXJlIG5vIGluc3RhbmNlcyBlaXRoZXIgYmVjYXVzZSB0aGUgcmVmZXJlbmNlcyBhcmUgbm90IHNhdGlzZmllZCBvciBiZWNhdXNlIHNvbWUgcnVudGltZSBpc3N1ZXMgYXBwZWFyOyBmb3IgZXhhbXBsZSB0aGUgYmluZCBtZXRob2Qgd2FzIG5vdCBmb3VuZCBpbiB0aGUgY2xhc3MKLQkJCVN0cmluZyBpc3N1ZXMgPSBzY3Auc2VydmljZUNvbXBvbmVudC5nZXRDb21wb25lbnRJc3N1ZXMoKTsKLQkJCWlmIChpc3N1ZXMgIT0gbnVsbCkgewotCQkJCWludHAucHJpbnRsbigiICAgIE5vIGluc3RhbmNlcyB3ZXJlIGNyZWF0ZWQgYmVjYXVzZTogIiArIGlzc3Vlcyk7IC8vJE5PTi1OTFMtMSQJCi0JCQl9Ci0JCX0KLQl9Ci0KLQlwcml2YXRlIFZlY3RvciBnZXRVbnJlc29sdmVkUmVmZXJlbmNlcyhTZXJ2aWNlQ29tcG9uZW50IHNjKSB7Ci0JCVZlY3RvciB1bnJlc29sdmVkID0gbmV3IFZlY3RvcigpOwotCQlpZiAoc2MucmVmZXJlbmNlcyAhPSBudWxsKSB7Ci0JCQlmb3IgKGludCBpID0gMDsgaSA8IHNjLnJlZmVyZW5jZXMuc2l6ZSgpOyBpKyspIHsKLQkJCQlDb21wb25lbnRSZWZlcmVuY2UgcmVmID0gKENvbXBvbmVudFJlZmVyZW5jZSkgc2MucmVmZXJlbmNlcy5lbGVtZW50QXQoaSk7Ci0JCQkJaWYgKCFoYXNQcm92aWRlcnMocmVmKSkgewotCQkJCQl1bnJlc29sdmVkLmFkZEVsZW1lbnQocmVmKTsKLQkJCQl9Ci0JCQl9Ci0JCX0KLQotCQlyZXR1cm4gdW5yZXNvbHZlZC5pc0VtcHR5KCkgPyBudWxsIDogdW5yZXNvbHZlZDsKLQl9Ci0KLQlwcml2YXRlIGJvb2xlYW4gaGFzUHJvdmlkZXJzKENvbXBvbmVudFJlZmVyZW5jZSByZWYpIHsKLQkJLy8vL2NoZWNrIHdoZXRoZXIgdGhlIGNvbXBvbmVudCdzIGJ1bmRsZSBoYXMgc2VydmljZSBHRVQgcGVybWlzc2lvbgotCQlpZiAoU3lzdGVtLmdldFNlY3VyaXR5TWFuYWdlcigpICE9IG51bGwgJiYgIXJlZi5jb21wb25lbnQuYmMuZ2V0QnVuZGxlKCkuaGFzUGVybWlzc2lvbihuZXcgU2VydmljZVBlcm1pc3Npb24ocmVmLmludGVyZmFjZU5hbWUsIFNlcnZpY2VQZXJtaXNzaW9uLkdFVCkpKSB7Ci0JCQlyZXR1cm4gZmFsc2U7Ci0JCX0KLQkJLy8vLyBHZXQgYWxsIHNlcnZpY2UgcmVmZXJlbmNlcyBmb3IgdGhpcyB0YXJnZXQgZmlsdGVyCi0JCXRyeSB7Ci0JCQlTZXJ2aWNlUmVmZXJlbmNlW10gc2VydmljZVJlZmVyZW5jZXMgPSBudWxsOwotCQkJc2VydmljZVJlZmVyZW5jZXMgPSByZWYuY29tcG9uZW50LmJjLmdldFNlcnZpY2VSZWZlcmVuY2VzKHJlZi5pbnRlcmZhY2VOYW1lLCByZWYudGFyZ2V0KTsKLQkJCWlmIChzZXJ2aWNlUmVmZXJlbmNlcyAhPSBudWxsKSB7Ci0JCQkJcmV0dXJuIHRydWU7Ci0JCQl9Ci0JCX0gY2F0Y2ggKEludmFsaWRTeW50YXhFeGNlcHRpb24gZSkgewotCQkJLy9kbyBub3RoaW5nCi0JCX0KLQkJcmV0dXJuIGZhbHNlOwotCX0KLQotCXByaXZhdGUgYm9vbGVhbiBpc01hbmRhdG9yeShDb21wb25lbnRSZWZlcmVuY2UgcmVmKSB7Ci0JCXJldHVybiByZWYuY2FyZGluYWxpdHkgPT0gQ29tcG9uZW50UmVmZXJlbmNlLkNBUkRJTkFMSVRZXzFfMSB8fCByZWYuY2FyZGluYWxpdHkgPT0gQ29tcG9uZW50UmVmZXJlbmNlLkNBUkRJTkFMSVRZXzFfTjsKLQl9Ci0KLQlwcml2YXRlIHZvaWQgZW5hYmxlQWxsKENvbW1hbmRJbnRlcnByZXRlciBpbnRwLCBCdW5kbGUgYikgewotCQlWZWN0b3IgY29tcG9uZW50c1RvRW5hYmxlID0gbmV3IFZlY3RvcigpOwotCQlpZiAoYiAhPSBudWxsKSB7Ci0JCQlpbnRwLnByaW50bG4oTkxTLmJpbmQoTWVzc2FnZXMuRU5BQkxJTkdfQUxMX0JVTkRMRV9DT01QT05FTlRTLCBnZXRCdW5kbGVSZXByZXNlbnRhdGlvbk5hbWUoYikpKTsKLQkJfSBlbHNlIHsKLQkJCWludHAucHJpbnRsbihNZXNzYWdlcy5FTkFCTElOR19BTExfQ09NUE9ORU5UUyk7Ci0JCX0KLQkJaWYgKGIgIT0gbnVsbCkgewotCQkJaWYgKHNjck1hbmFnZXIuYnVuZGxlVG9TZXJ2aWNlQ29tcG9uZW50cyAhPSBudWxsKSB7Ci0JCQkJVmVjdG9yIGNvbXBvbmVudHMgPSAoVmVjdG9yKSBzY3JNYW5hZ2VyLmJ1bmRsZVRvU2VydmljZUNvbXBvbmVudHMuZ2V0KGIpOwotCQkJCWlmIChjb21wb25lbnRzICE9IG51bGwpIHsKLQkJCQkJZm9yIChpbnQgaSA9IDA7IGkgPCBjb21wb25lbnRzLnNpemUoKTsgaSsrKSB7Ci0JCQkJCQlTZXJ2aWNlQ29tcG9uZW50IHNjID0gKFNlcnZpY2VDb21wb25lbnQpIGNvbXBvbmVudHMuZWxlbWVudEF0KGkpOwotCQkJCQkJaWYgKCFzYy5lbmFibGVkKSB7Ci0JCQkJCQkJY29tcG9uZW50c1RvRW5hYmxlLmFkZEVsZW1lbnQoc2MpOwotCQkJCQkJCXNjLmVuYWJsZWQgPSB0cnVlOwotCQkJCQkJfQotCQkJCQl9Ci0JCQkJCWlmICghY29tcG9uZW50c1RvRW5hYmxlLmlzRW1wdHkoKSkgewotCQkJCQkJcmVzb2x2ZXIuZW5hYmxlQ29tcG9uZW50cyhjb21wb25lbnRzVG9FbmFibGUpOwotCQkJCQl9Ci0JCQkJfQotCQkJfQotCQl9IGVsc2UgewotCQkJaWYgKHNjck1hbmFnZXIuYnVuZGxlVG9TZXJ2aWNlQ29tcG9uZW50cyAhPSBudWxsKSB7Ci0JCQkJQnVuZGxlW10gYWxsQnVuZGxlcyA9IEFjdGl2YXRvci5iYy5nZXRCdW5kbGVzKCk7Ci0JCQkJZm9yIChpbnQgaiA9IDA7IGogPCBhbGxCdW5kbGVzLmxlbmd0aDsgaisrKSB7Ci0JCQkJCVZlY3RvciBjb21wb25lbnRzID0gKFZlY3Rvcikgc2NyTWFuYWdlci5idW5kbGVUb1NlcnZpY2VDb21wb25lbnRzLmdldChhbGxCdW5kbGVzW2pdKTsKLQkJCQkJaWYgKGNvbXBvbmVudHMgIT0gbnVsbCkgewotCQkJCQkJZm9yIChpbnQgaSA9IDA7IGkgPCBjb21wb25lbnRzLnNpemUoKTsgaSsrKSB7Ci0JCQkJCQkJU2VydmljZUNvbXBvbmVudCBzYyA9IChTZXJ2aWNlQ29tcG9uZW50KSBjb21wb25lbnRzLmVsZW1lbnRBdChpKTsKLQkJCQkJCQlpZiAoIXNjLmVuYWJsZWQpIHsKLQkJCQkJCQkJY29tcG9uZW50c1RvRW5hYmxlLmFkZEVsZW1lbnQoc2MpOwotCQkJCQkJCQlzYy5lbmFibGVkID0gdHJ1ZTsKLQkJCQkJCQl9Ci0JCQkJCQl9Ci0JCQkJCX0KLQkJCQl9Ci0JCQkJaWYgKCFjb21wb25lbnRzVG9FbmFibGUuaXNFbXB0eSgpKSB7Ci0JCQkJCXJlc29sdmVyLmVuYWJsZUNvbXBvbmVudHMoY29tcG9uZW50c1RvRW5hYmxlKTsKLQkJCQl9Ci0JCQl9Ci0JCX0KLQl9Ci0KLQlwcml2YXRlIHZvaWQgZGlzYWJsZUFsbChDb21tYW5kSW50ZXJwcmV0ZXIgaW50cCwgQnVuZGxlIGIpIHsKLQkJVmVjdG9yIGNvbXBvbmVudHNUb0Rpc2FibGUgPSBuZXcgVmVjdG9yKCk7Ci0JCWlmIChiICE9IG51bGwpIHsKLQkJCWludHAucHJpbnRsbihOTFMuYmluZChNZXNzYWdlcy5ESVNBQkxJTkdfQUxMX0JVTkRMRV9DT01QT05FTlRTLCBnZXRCdW5kbGVSZXByZXNlbnRhdGlvbk5hbWUoYikpKTsKLQkJfSBlbHNlIHsKLQkJCWludHAucHJpbnRsbihNZXNzYWdlcy5ESVNBQkxJTkdfQUxMX0NPTVBPTkVOVFMpOwotCQl9Ci0JCWlmIChiICE9IG51bGwpIHsKLQkJCWlmIChzY3JNYW5hZ2VyLmJ1bmRsZVRvU2VydmljZUNvbXBvbmVudHMgIT0gbnVsbCkgewotCQkJCVZlY3RvciBjb21wb25lbnRzID0gKFZlY3Rvcikgc2NyTWFuYWdlci5idW5kbGVUb1NlcnZpY2VDb21wb25lbnRzLmdldChiKTsKLQkJCQlpZiAoY29tcG9uZW50cyAhPSBudWxsKSB7Ci0JCQkJCWZvciAoaW50IGkgPSAwOyBpIDwgY29tcG9uZW50cy5zaXplKCk7IGkrKykgewotCQkJCQkJU2VydmljZUNvbXBvbmVudCBzYyA9IChTZXJ2aWNlQ29tcG9uZW50KSBjb21wb25lbnRzLmVsZW1lbnRBdChpKTsKLQkJCQkJCWlmIChzYy5lbmFibGVkKSB7Ci0JCQkJCQkJY29tcG9uZW50c1RvRGlzYWJsZS5hZGRFbGVtZW50KHNjKTsKLQkJCQkJCQlzYy5lbmFibGVkID0gZmFsc2U7Ci0JCQkJCQl9Ci0JCQkJCX0KLQkJCQkJaWYgKCFjb21wb25lbnRzVG9EaXNhYmxlLmlzRW1wdHkoKSkgewotCQkJCQkJcmVzb2x2ZXIuZGlzYWJsZUNvbXBvbmVudHMoY29tcG9uZW50c1RvRGlzYWJsZSwgQ29tcG9uZW50Q29uc3RhbnRzLkRFQUNUSVZBVElPTl9SRUFTT05fRElTQUJMRUQpOwotCQkJCQl9Ci0JCQkJfQotCQkJfQotCQl9IGVsc2UgewotCQkJaWYgKHNjck1hbmFnZXIuYnVuZGxlVG9TZXJ2aWNlQ29tcG9uZW50cyAhPSBudWxsKSB7Ci0JCQkJQnVuZGxlW10gYWxsQnVuZGxlcyA9IEFjdGl2YXRvci5iYy5nZXRCdW5kbGVzKCk7Ci0JCQkJZm9yIChpbnQgaiA9IDA7IGogPCBhbGxCdW5kbGVzLmxlbmd0aDsgaisrKSB7Ci0JCQkJCVZlY3RvciBjb21wb25lbnRzID0gKFZlY3Rvcikgc2NyTWFuYWdlci5idW5kbGVUb1NlcnZpY2VDb21wb25lbnRzLmdldChhbGxCdW5kbGVzW2pdKTsKLQkJCQkJaWYgKGNvbXBvbmVudHMgIT0gbnVsbCkgewotCQkJCQkJZm9yIChpbnQgaSA9IDA7IGkgPCBjb21wb25lbnRzLnNpemUoKTsgaSsrKSB7Ci0JCQkJCQkJU2VydmljZUNvbXBvbmVudCBzYyA9IChTZXJ2aWNlQ29tcG9uZW50KSBjb21wb25lbnRzLmVsZW1lbnRBdChpKTsKLQkJCQkJCQlpZiAoc2MuZW5hYmxlZCkgewotCQkJCQkJCQljb21wb25lbnRzVG9EaXNhYmxlLmFkZEVsZW1lbnQoc2MpOwotCQkJCQkJCQlzYy5lbmFibGVkID0gZmFsc2U7Ci0JCQkJCQkJfQotCQkJCQkJfQotCQkJCQl9Ci0JCQkJfQotCQkJCWlmICghY29tcG9uZW50c1RvRGlzYWJsZS5pc0VtcHR5KCkpIHsKLQkJCQkJcmVzb2x2ZXIuZGlzYWJsZUNvbXBvbmVudHMoY29tcG9uZW50c1RvRGlzYWJsZSwgQ29tcG9uZW50Q29uc3RhbnRzLkRFQUNUSVZBVElPTl9SRUFTT05fRElTQUJMRUQpOwotCQkJCX0KLQkJCX0KLQkJfQotCX0KLQotCXByaXZhdGUgdm9pZCBlbmFibGVDb21wb25lbnQoQ29tbWFuZEludGVycHJldGVyIGludHAsIGludCBjb21wb25lbnRJbmRleCkgewotCQlDb21wb25lbnRSZWYgY1JlZiA9IGZpbmRDb21wb25lbnRXaXRoSUQoY29tcG9uZW50SW5kZXgpOwotCQlpZiAoY1JlZiA9PSBudWxsKSB7Ci0JCQlpbnRwLnByaW50bG4oTWVzc2FnZXMuSU5WQUxJRF9DT01QT05FTlRfSUQpOwotCQkJcmV0dXJuOwotCQl9Ci0JCXNjck1hbmFnZXIuZW5hYmxlQ29tcG9uZW50KGNSZWYubmFtZSwgQWN0aXZhdG9yLmJjLmdldEJ1bmRsZShjUmVmLmJpZCkpOwotCQlpbnRwLnByaW50bG4oTkxTLmJpbmQoTWVzc2FnZXMuU0VOVF9FTkFCTElOR19SRVFVRVNULCBjUmVmLm5hbWUpKTsKLQl9Ci0KLQlwcml2YXRlIHZvaWQgZGlzYWJsZUNvbXBvbmVudChDb21tYW5kSW50ZXJwcmV0ZXIgaW50cCwgaW50IGNvbXBvbmVudEluZGV4KSB7Ci0JCUNvbXBvbmVudFJlZiBjUmVmID0gZmluZENvbXBvbmVudFdpdGhJRChjb21wb25lbnRJbmRleCk7Ci0JCWlmIChjUmVmID09IG51bGwpIHsKLQkJCWludHAucHJpbnRsbihNZXNzYWdlcy5JTlZBTElEX0NPTVBPTkVOVF9JRCk7Ci0JCQlyZXR1cm47Ci0JCX0KLQkJc2NyTWFuYWdlci5kaXNhYmxlQ29tcG9uZW50KGNSZWYubmFtZSwgQWN0aXZhdG9yLmJjLmdldEJ1bmRsZShjUmVmLmJpZCkpOwotCQlpbnRwLnByaW50bG4oTkxTLmJpbmQoTWVzc2FnZXMuU0VOVF9ESVNBQkxJTkdfUkVRVUVTVCwgY1JlZi5uYW1lKSk7Ci0JfQotCi0JLyogY29tbWFuZHMgKi8KLQotCXByaXZhdGUgdm9pZCBsaXN0Q29tcG9uZW50cyhDb21tYW5kSW50ZXJwcmV0ZXIgaW50cCwgQnVuZGxlIGIsIGJvb2xlYW4gY29tcGxldGVJbmZvKSB7Ci0JCWlmIChjb21wb25lbnRSZWZzSURzID09IG51bGwpCi0JCQljb21wb25lbnRSZWZzSURzID0gbmV3IEhhc2h0YWJsZSgxMDEpOwotCi0JCWlmIChiICE9IG51bGwpIHsKLQkJCWludHAucHJpbnRsbihOTFMuYmluZChNZXNzYWdlcy5DT01QT05FTlRTX0lOX0JVTkRMRSwgZ2V0QnVuZGxlUmVwcmVzZW50YXRpb25OYW1lKGIpKSk7Ci0JCQlpZiAoY29tcG9uZW50UmVmc0lEcy5pc0VtcHR5KCkpIHsKLQkJCQlpbml0Q29tcG9uZW50UmVmcygpOwotCQkJfQotCQl9IGVsc2UgewotCQkJaW50cC5wcmludGxuKE1lc3NhZ2VzLkFMTF9DT01QT05FTlRTKTsKLQkJfQotCi0JCWlmIChiID09IG51bGwgfHwgc2NyTWFuYWdlci5idW5kbGVUb1NlcnZpY2VDb21wb25lbnRzICE9IG51bGwgJiYgc2NyTWFuYWdlci5idW5kbGVUb1NlcnZpY2VDb21wb25lbnRzLmdldChiKSAhPSBudWxsKSB7Ci0JCQlpbnRwLnByaW50KCJJRCIpOyAvLyROT04tTkxTLTEkCi0JCQlpZiAoY29tcGxldGVJbmZvKSB7Ci0JCQkJaW50cC5wcmludGxuKE1lc3NhZ2VzLkNPTVBPTkVOVF9ERVRBSUxTKTsKLQkJCX0gZWxzZSB7Ci0JCQkJaW50cC5wcmludChNZXNzYWdlcy5TVEFURSk7Ci0JCQkJaW50cC5wcmludChNZXNzYWdlcy5DT01QT05FTlRfTkFNRSk7Ci0JCQkJaW50cC5wcmludGxuKE1lc3NhZ2VzLkxPQ0FURURfSU5fQlVORExFKTsKLQkJCX0KLQkJfQotCi0JCWlmIChiICE9IG51bGwpIHsKLQkJCWlmIChzY3JNYW5hZ2VyLmJ1bmRsZVRvU2VydmljZUNvbXBvbmVudHMgIT0gbnVsbCkgewotCi0JCQkJVmVjdG9yIGNvbXBvbmVudHMgPSAoVmVjdG9yKSBzY3JNYW5hZ2VyLmJ1bmRsZVRvU2VydmljZUNvbXBvbmVudHMuZ2V0KGIpOwotCQkJCWlmIChjb21wb25lbnRzICE9IG51bGwpIHsKLQkJCQkJZm9yIChpbnQgaSA9IDA7IGkgPCBjb21wb25lbnRzLnNpemUoKTsgaSsrKSB7Ci0JCQkJCQlTZXJ2aWNlQ29tcG9uZW50IHNjID0gKFNlcnZpY2VDb21wb25lbnQpIGNvbXBvbmVudHMuZWxlbWVudEF0KGkpOwotCQkJCQkJQ29tcG9uZW50UmVmIGFSZWYgPSBuZXcgQ29tcG9uZW50UmVmKGIuZ2V0QnVuZGxlSWQoKSwgc2MubmFtZSk7Ci0JCQkJCQlDb21wb25lbnRSZWYgcmVmID0gKENvbXBvbmVudFJlZikgY29tcG9uZW50UmVmc0lEcy5nZXQoYVJlZik7Ci0JCQkJCQlpZiAocmVmID09IG51bGwpIHsKLQkJCQkJCQlyZWYgPSBhUmVmOwotCQkJCQkJCXJlZi5pZCA9IGdlbmVyYXRlSUQoKTsKLQkJCQkJCQljb21wb25lbnRSZWZzSURzLnB1dChyZWYsIHJlZik7Ci0JCQkJCQl9Ci0JCQkJCQlpZiAoY29tcGxldGVJbmZvKSB7Ci0JCQkJCQkJaW50cC5wcmludChyZWYuaWQgKyAiIik7IC8vJE5PTi1OTFMtMSQKLQkJCQkJCQlwcmludENvbXBvbmVudERldGFpbHMoaW50cCwgc2MpOwotCQkJCQkJfSBlbHNlIHsKLQkJCQkJCQkvLy8vcHJpbnQgc2hvcnQgaW5mbwotCQkJCQkJCWludHAucHJpbnQoIiIgKyByZWYuaWQpOyAvLyROT04tTkxTLTEkCi0JCQkJCQkJaW50cC5wcmludCgiXHQiICsgU0NSVXRpbC5nZXRTdGF0ZVN0cmluZ1JlcHJlc2VudGF0aW9uKHNjLmdldFN0YXRlKCkpKTsgLy8kTk9OLU5MUy0xJAotCQkJCQkJCWludHAucHJpbnQoIlx0XHQiICsgc2MubmFtZSk7IC8vJE5PTi1OTFMtMSQKLQkJCQkJCQlpbnRwLnByaW50bG4oIlx0XHRcdCIgKyBnZXRCdW5kbGVSZXByZXNlbnRhdGlvbk5hbWUoYikgKyAiKGJpZD0iICsgYi5nZXRCdW5kbGVJZCgpICsgIikiKTsgLy8kTk9OLU5MUy0xJCAvLyROT04tTkxTLTIkIC8vJE5PTi1OTFMtMyQKLQkJCQkJCX0KLQkJCQkJfQotCQkJCX0KLQotCQkJCS8vIGNoZWNrIHRoZSBidW5kbGUgZm9yIGlzc3VlcyBkdXJpbmcgY29tcG9uZW50cyByZXNvbHZpbmcKLQkJCQkvLyBmaXJzdCBjaGVjayBmb3Igc2VydmljZSBjb21wb25lbnQgaGVhZGVyIGluIHRoaXMgYnVuZGxlCi0JCQkJU3RyaW5nIGRzSGVhZGVyID0gbnVsbDsKLQkJCQlEaWN0aW9uYXJ5IGFsbEhlYWRlcnMgPSBiLmdldEhlYWRlcnMoIiIpOyAvLyROT04tTkxTLTEkCi0KLQkJCQlpZiAoISgoZHNIZWFkZXIgPSAoU3RyaW5nKSBhbGxIZWFkZXJzLmdldChDb21wb25lbnRDb25zdGFudHMuU0VSVklDRV9DT01QT05FTlQpKSAhPSBudWxsKSkgewotCQkJCQkvLyBubyBjb21wb25lbnQgZGVzY3JpcHRpb25zIGluIHRoaXMgYnVuZGxlCi0JCQkJCWludHAucHJpbnRsbigiTm8gU2VydmljZUNvbXBvbmVudCBoZWFkZXIgd2FzIGZvdW5kIGluIGJ1bmRsZSAiICsgYi50b1N0cmluZygpKTsgLy8kTk9OLU5MUy0xJAotCQkJCQlyZXR1cm47Ci0JCQkJfQotCi0JCQkJLy8gc2Vjb25kIGNoZWNrIGlmIHRoZSBkcyB4bWwgaXMgY29ycmVjdAotCQkJCVZlY3RvciBpc3N1ZXMgPSBwYXJzZVhNTERlY2xhcmF0aW9uKGIsIGRzSGVhZGVyKTsKLQkJCQlpZiAoaXNzdWVzLnNpemUoKSA+IDApIHsKLQkJCQkJaW50cC5wcmludGxuKCk7Ci0JCQkJCWludHAucHJpbnRsbigiSXNzdWVzIGVuY291bnRlcmVkIHdoZW4gcGFyc2luZyBjb21wb25lbnRzIHhtbCBkZWNsYXJhdGlvbnMiKTsgLy8kTk9OLU5MUy0xJAotCQkJCQlmb3IgKGludCBpID0gMDsgaSA8IGlzc3Vlcy5zaXplKCk7IGkrKykgewotCQkJCQkJaW50cC5wcmludGxuKCJcdCIgKyBpc3N1ZXMuZ2V0KGkpKTsgLy8kTk9OLU5MUy0xJAotCQkJCQkJaW50cC5wcmludGxuKCk7Ci0JCQkJCX0KLQkJCQl9Ci0KLQkJCX0KLQotCQl9IGVsc2UgewotCQkJaWYgKHNjck1hbmFnZXIuYnVuZGxlVG9TZXJ2aWNlQ29tcG9uZW50cyAhPSBudWxsKSB7Ci0JCQkJQnVuZGxlW10gYWxsQnVuZGxlcyA9IEFjdGl2YXRvci5iYy5nZXRCdW5kbGVzKCk7Ci0JCQkJZm9yIChpbnQgaiA9IDA7IGogPCBhbGxCdW5kbGVzLmxlbmd0aDsgaisrKSB7Ci0JCQkJCVZlY3RvciBjb21wb25lbnRzID0gKFZlY3Rvcikgc2NyTWFuYWdlci5idW5kbGVUb1NlcnZpY2VDb21wb25lbnRzLmdldChhbGxCdW5kbGVzW2pdKTsKLQkJCQkJaWYgKGNvbXBvbmVudHMgIT0gbnVsbCkgewotCQkJCQkJZm9yIChpbnQgaSA9IDA7IGkgPCBjb21wb25lbnRzLnNpemUoKTsgaSsrKSB7Ci0JCQkJCQkJU2VydmljZUNvbXBvbmVudCBzYyA9IChTZXJ2aWNlQ29tcG9uZW50KSBjb21wb25lbnRzLmVsZW1lbnRBdChpKTsKLQkJCQkJCQlDb21wb25lbnRSZWYgYVJlZiA9IG5ldyBDb21wb25lbnRSZWYoYWxsQnVuZGxlc1tqXS5nZXRCdW5kbGVJZCgpLCBzYy5uYW1lKTsKLQkJCQkJCQlDb21wb25lbnRSZWYgcmVmID0gKENvbXBvbmVudFJlZikgY29tcG9uZW50UmVmc0lEcy5nZXQoYVJlZik7Ci0JCQkJCQkJaWYgKHJlZiA9PSBudWxsKSB7Ci0JCQkJCQkJCXJlZiA9IGFSZWY7Ci0JCQkJCQkJCXJlZi5pZCA9IGdlbmVyYXRlSUQoKTsKLQkJCQkJCQkJY29tcG9uZW50UmVmc0lEcy5wdXQocmVmLCByZWYpOwotCQkJCQkJCX0KLQotCQkJCQkJCWlmIChjb21wbGV0ZUluZm8pIHsKLQkJCQkJCQkJaW50cC5wcmludChyZWYuaWQgKyAiIik7IC8vJE5PTi1OTFMtMSQKLQkJCQkJCQkJcHJpbnRDb21wb25lbnREZXRhaWxzKGludHAsIHNjKTsKLQkJCQkJCQl9IGVsc2UgewotCQkJCQkJCQkvLy8vcHJpbnQgc2hvcnQgaW5mbwotCQkJCQkJCQlpbnRwLnByaW50KCIiICsgcmVmLmlkKTsgLy8kTk9OLU5MUy0xJAotCQkJCQkJCQlpbnRwLnByaW50KCJcdCIgKyBTQ1JVdGlsLmdldFN0YXRlU3RyaW5nUmVwcmVzZW50YXRpb24oc2MuZ2V0U3RhdGUoKSkpOyAvLyROT04tTkxTLTEkCi0JCQkJCQkJCWludHAucHJpbnQoIlx0XHQiICsgc2MubmFtZSk7IC8vJE5PTi1OTFMtMSQKLQkJCQkJCQkJaW50cC5wcmludGxuKCJcdFx0XHQiICsgZ2V0QnVuZGxlUmVwcmVzZW50YXRpb25OYW1lKGFsbEJ1bmRsZXNbal0pICsgIihiaWQ9IiArIGFsbEJ1bmRsZXNbal0uZ2V0QnVuZGxlSWQoKSArICIpIik7IC8vJE5PTi1OTFMtMSQgLy8kTk9OLU5MUy0yJCAvLyROT04tTkxTLTMkCi0JCQkJCQkJfQotCQkJCQkJfQotCQkJCQl9Ci0JCQkJfQotCQkJfQotCQl9Ci0JfQotCi0JcHJpdmF0ZSB2b2lkIGluaXRDb21wb25lbnRSZWZzKCkgewotCQlpZiAoc2NyTWFuYWdlci5idW5kbGVUb1NlcnZpY2VDb21wb25lbnRzICE9IG51bGwpIHsKLQkJCUJ1bmRsZVtdIGFsbEJ1bmRsZXMgPSBBY3RpdmF0b3IuYmMuZ2V0QnVuZGxlcygpOwotCQkJZm9yIChpbnQgaiA9IDA7IGogPCBhbGxCdW5kbGVzLmxlbmd0aDsgaisrKSB7Ci0JCQkJVmVjdG9yIGNvbXBvbmVudHMgPSAoVmVjdG9yKSBzY3JNYW5hZ2VyLmJ1bmRsZVRvU2VydmljZUNvbXBvbmVudHMuZ2V0KGFsbEJ1bmRsZXNbal0pOwotCQkJCWlmIChjb21wb25lbnRzICE9IG51bGwpIHsKLQkJCQkJZm9yIChpbnQgaSA9IDA7IGkgPCBjb21wb25lbnRzLnNpemUoKTsgaSsrKSB7Ci0JCQkJCQlTZXJ2aWNlQ29tcG9uZW50IHNjID0gKFNlcnZpY2VDb21wb25lbnQpIGNvbXBvbmVudHMuZWxlbWVudEF0KGkpOwotCQkJCQkJQ29tcG9uZW50UmVmIGFSZWYgPSBuZXcgQ29tcG9uZW50UmVmKGFsbEJ1bmRsZXNbal0uZ2V0QnVuZGxlSWQoKSwgc2MubmFtZSk7Ci0JCQkJCQlDb21wb25lbnRSZWYgcmVmID0gKENvbXBvbmVudFJlZikgY29tcG9uZW50UmVmc0lEcy5nZXQoYVJlZik7Ci0JCQkJCQlpZiAocmVmID09IG51bGwpIHsKLQkJCQkJCQlyZWYgPSBhUmVmOwotCQkJCQkJCXJlZi5pZCA9IGdlbmVyYXRlSUQoKTsKLQkJCQkJCQljb21wb25lbnRSZWZzSURzLnB1dChyZWYsIHJlZik7Ci0JCQkJCQl9Ci0JCQkJCX0KLQkJCQl9Ci0JCQl9Ci0JCX0KLQl9Ci0KLQlwcml2YXRlIFN0cmluZyBnZXRCdW5kbGVSZXByZXNlbnRhdGlvbk5hbWUoQnVuZGxlIGIpIHsKLQkJU3RyaW5nIHJlcyA9IGIuZ2V0U3ltYm9saWNOYW1lKCk7Ci0JCWlmIChyZXMgPT0gbnVsbCkgewotCQkJcmVzID0gIndpdGggSUQgIiArIGIuZ2V0QnVuZGxlSWQoKTsgLy8kTk9OLU5MUy0xJAotCQl9Ci0JCXJldHVybiByZXM7Ci0JfQotCi0JcHJpdmF0ZSBzeW5jaHJvbml6ZWQgaW50IGdlbmVyYXRlSUQoKSB7Ci0JCXJldHVybiBjdXJJRCsrOwotCX0KLQotCXByb3RlY3RlZCBWZWN0b3IgcGFyc2VYTUxEZWNsYXJhdGlvbihCdW5kbGUgYnVuZGxlLCBTdHJpbmcgZHNIZWFkZXIpIHsKLQkJVmVjdG9yIGNvbXBvbmVudHNJc3N1ZXMgPSBuZXcgVmVjdG9yKCk7Ci0JCVZlY3RvciBjb21wb25lbnRzID0gbmV3IFZlY3RvcigpOwotCQl0cnkgewotCQkJaWYgKGRzSGVhZGVyICE9IG51bGwpIHsKLQkJCQlTdHJpbmdUb2tlbml6ZXIgdG9rID0gbmV3IFN0cmluZ1Rva2VuaXplcihkc0hlYWRlciwgIiwiKTsgLy8kTk9OLU5MUy0xJAotCQkJCURlY2xhcmF0aW9uUGFyc2VyIHBhcnNlciA9IG5ldyBEZWNsYXJhdGlvblBhcnNlcih0cnVlKTsKLQkJCQkvLyBwcm9jZXNzIGFsbCBkZWZpbml0aW9uIGZpbGUKLQkJCQl3aGlsZSAodG9rLmhhc01vcmVFbGVtZW50cygpKSB7Ci0JCQkJCVN0cmluZyBkZWZpbml0aW9uRmlsZSA9IHRvay5uZXh0VG9rZW4oKS50cmltKCk7Ci0JCQkJCWludCBpbmQgPSBkZWZpbml0aW9uRmlsZS5sYXN0SW5kZXhPZignLycpOwotCQkJCQlTdHJpbmcgcGF0aCA9IGluZCAhPSAtMSA/IGRlZmluaXRpb25GaWxlLnN1YnN0cmluZygwLCBpbmQpIDogIi8iOyAvLyROT04tTkxTLTEkCi0JCQkJCUlucHV0U3RyZWFtIGlzID0gbnVsbDsKLQotCQkJCQlFbnVtZXJhdGlvbiB1cmxzID0gYnVuZGxlLmZpbmRFbnRyaWVzKHBhdGgsIGluZCAhPSAtMSA/IGRlZmluaXRpb25GaWxlLnN1YnN0cmluZyhpbmQgKyAxKSA6IGRlZmluaXRpb25GaWxlLCBmYWxzZSk7Ci0JCQkJCWlmICh1cmxzID09IG51bGwgfHwgIXVybHMuaGFzTW9yZUVsZW1lbnRzKCkpIHsKLQkJCQkJCWNvbXBvbmVudHNJc3N1ZXMuYWRkKE5MUy5iaW5kKE1lc3NhZ2VzLkNPTVBPTkVOVF9YTUxfTk9UX0ZPVU5ELCBidW5kbGUuZ2V0U3ltYm9saWNOYW1lKCksIGRlZmluaXRpb25GaWxlKSk7Ci0JCQkJCQljb250aW51ZTsKLQkJCQkJfQotCi0JCQkJCS8vIGlsbGVnYWwgY29tcG9uZW50cyBhcmUgaWdub3JlZCwgYnV0IGZyYW1ld29yayBldmVudCBpcyBwb3N0ZWQgZm9yCi0JCQkJCS8vIHRoZW07IGhvd2V2ZXIsIGl0IHdpbGwgY29udGludWUgYW5kIHRyeSB0byBsb2FkIGFueSBsZWdhbAotCQkJCQkvLyBkZWZpbml0aW9ucwotCQkJCQlVUkwgdXJsOwotCQkJCQl3aGlsZSAodXJscy5oYXNNb3JlRWxlbWVudHMoKSkgewotCQkJCQkJdXJsID0gKFVSTCkgdXJscy5uZXh0RWxlbWVudCgpOwotCQkJCQkJaWYgKEFjdGl2YXRvci5ERUJVRykgewotCQkJCQkJCUFjdGl2YXRvci5sb2cuZGVidWcoIkNvbXBvbmVudFN0b3JhZ2UucGFyc2VYTUxEZWNsYXJhdGlvbigpOiBsb2FkaW5nICIgKyB1cmwudG9TdHJpbmcoKSwgbnVsbCk7IC8vJE5PTi1OTFMtMSQKLQkJCQkJCX0KLQkJCQkJCXRyeSB7Ci0JCQkJCQkJaXMgPSB1cmwub3BlblN0cmVhbSgpOwotCQkJCQkJCWlmIChpcyA9PSBudWxsKSB7Ci0JCQkJCQkJCWNvbXBvbmVudHNJc3N1ZXMuYWRkKE5MUy5iaW5kKE1lc3NhZ2VzLkNBTlRfT1BFTl9TVFJFQU1fVE9fQ09NUE9ORU5UX1hNTCwgdXJsKSk7Ci0JCQkJCQkJfSBlbHNlIHsKLQkJCQkJCQkJdHJ5IHsKLQkJCQkJCQkJCXBhcnNlci5wYXJzZShpcywgYnVuZGxlLCBjb21wb25lbnRzLCB1cmwudG9TdHJpbmcoKSk7Ci0JCQkJCQkJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7Ci0JCQkJCQkJCQljb21wb25lbnRzSXNzdWVzLmFkZChlLmdldE1lc3NhZ2UoKSk7Ci0JCQkJCQkJCX0KLQkJCQkJCQl9Ci0JCQkJCQl9IGNhdGNoIChJT0V4Y2VwdGlvbiBpZSkgewotCQkJCQkJCWNvbXBvbmVudHNJc3N1ZXMuYWRkKE5MUy5iaW5kKE1lc3NhZ2VzLkVSUk9SX09QRU5JTkdfQ09NUF9YTUwsIHVybCkgKyAiXG5cdCIgKyBpZSk7IC8vJE5PTi1OTFMtMSQKLQkJCQkJCX0gY2F0Y2ggKFRocm93YWJsZSB0KSB7Ci0JCQkJCQkJY29tcG9uZW50c0lzc3Vlcy5hZGQoTkxTLmJpbmQoTWVzc2FnZXMuSUxMRUdBTF9ERUZJTklUSU9OX0ZJTEUsIHVybCkgKyAiXG5cdCIgKyB0KTsgLy8kTk9OLU5MUy0xJAotCQkJCQkJfSBmaW5hbGx5IHsKLQkJCQkJCQlpZiAoaXMgIT0gbnVsbCkgewotCQkJCQkJCQlpcy5jbG9zZSgpOwotCQkJCQkJCX0KLQkJCQkJCX0KLQkJCQkJfQotCQkJCX0gLy8gZW5kIHdoaWxlCi0KLQkJCQljb21wb25lbnRzID0gcGFyc2VyLmNvbXBvbmVudHM7Ci0JCQkJLy8gbWFrZSBzdXJlIHRoZSBjbGVhbi11cCB0aGUgcGFyc2VyIGNhY2hlLCBmb3IgdGhlIG5leHQgYnVuZGxlIHRvCi0JCQkJLy8gd29yayBwcm9wZXJseSEhIQotCQkJCXBhcnNlci5jb21wb25lbnRzID0gbnVsbDsKLQkJCX0KLQkJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKLQkJCWNvbXBvbmVudHNJc3N1ZXMuYWRkKCJFeGNlcHRpb24gWyIgKyBlICsgIl0gd2hpbGUgcGFyc2luZyBEUyB4bWwgZGVmaW5pdGlvbi4iKTsgLy8kTk9OLU5MUy0xJCAvLyROT04tTkxTLTIkCi0JCX0KLQkJcmV0dXJuIGNvbXBvbmVudHNJc3N1ZXM7Ci0JfQotCi0JcHJpdmF0ZSBzdGF0aWMgY2xhc3MgQ29tcG9uZW50UmVmIHsKLQkJLy8vL3RoZSBJRCBvZiB0aGUgYnVuZGxlIGhvbGRpbmcgdGhpcyBzZXJ2aWNlIGNvbXBvbmVudAotCQlsb25nIGJpZDsKLQkJLy8vL3RoZSBuYW1lIG9mIHRoZSBzZXJ2aWNlIGNvbXBvbmVudAotCQlTdHJpbmcgbmFtZTsKLQkJLy8vL3RoZSB0ZW1wb3JhcnkgaWQgZ2l2ZW4gdG8gdGhpcyByZWZlcmVuY2UuIEl0IHdpbGwgYmUgdXNlZCBieSBjZXJ0YWluIGNvbnNvbGUgY29tbWFuZHMKLQkJaW50IGlkID0gLTE7Ci0KLQkJcHVibGljIENvbXBvbmVudFJlZihsb25nIGJpZCwgU3RyaW5nIG5hbWUpIHsKLQkJCXRoaXMuYmlkID0gYmlkOwotCQkJdGhpcy5uYW1lID0gbmFtZTsKLQkJfQotCi0JCXB1YmxpYyBib29sZWFuIGVxdWFscyhPYmplY3QgbykgewotCQkJaWYgKG8gaW5zdGFuY2VvZiBDb21wb25lbnRSZWYpIHsKLQkJCQlDb21wb25lbnRSZWYgb2JqID0gKENvbXBvbmVudFJlZikgbzsKLQkJCQlyZXR1cm4gKG9iai5iaWQgPT0gYmlkICYmIG5hbWUuZXF1YWxzKG9iai5uYW1lKSk7Ci0JCQl9Ci0JCQlyZXR1cm4gZmFsc2U7Ci0JCX0KLQotCQlwdWJsaWMgaW50IGhhc2hDb2RlKCkgewotCQkJcmV0dXJuIG5hbWUuaGFzaENvZGUoKTsKLQkJfQotCi0JfQotCi19CmRpZmYgLS1naXQgYS9idW5kbGVzL29yZy5lY2xpcHNlLmVxdWlub3guZHMvc3JjL29yZy9lY2xpcHNlL2VxdWlub3gvaW50ZXJuYWwvZHMvU0NSTWFuYWdlci5qYXZhIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5lcXVpbm94LmRzL3NyYy9vcmcvZWNsaXBzZS9lcXVpbm94L2ludGVybmFsL2RzL1NDUk1hbmFnZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMTUzNmY1My4uMDAwMDAwMAotLS0gYS9idW5kbGVzL29yZy5lY2xpcHNlLmVxdWlub3guZHMvc3JjL29yZy9lY2xpcHNlL2VxdWlub3gvaW50ZXJuYWwvZHMvU0NSTWFuYWdlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsOTc3ICswLDAgQEAKLS8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTctMjAxMCBieSBQcm9TeXN0IFNvZnR3YXJlIEdtYkgKLSAqIGh0dHA6Ly93d3cucHJvc3lzdC5jb20KLSAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMKLSAqIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2UgdjEuMAotICogd2hpY2ggYWNjb21wYW5pZXMgdGhpcyBkaXN0cmlidXRpb24sIGFuZCBpcyBhdmFpbGFibGUgYXQKLSAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLXYxMC5odG1sCi0gKgotICogQ29udHJpYnV0b3JzOgotICogICAgUHJvU3lzdCBTb2Z0d2FyZSBHbWJIIC0gaW5pdGlhbCBBUEkgYW5kIGltcGxlbWVudGF0aW9uCi0gKiAgICBBbmRyZXcgVGVpcm5leQkJIC0gYnVnLmlkID0gMjc4NzMyCi0gKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLXBhY2thZ2Ugb3JnLmVjbGlwc2UuZXF1aW5veC5pbnRlcm5hbC5kczsKLQotaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247Ci1pbXBvcnQgamF2YS5zZWN1cml0eS5BY2Nlc3NDb250cm9sbGVyOwotaW1wb3J0IGphdmEuc2VjdXJpdHkuUHJpdmlsZWdlZEFjdGlvbjsKLWltcG9ydCBqYXZhLnV0aWwuKjsKLWltcG9ydCBvcmcuYXBhY2hlLmZlbGl4LnNjci5Db21wb25lbnQ7Ci1pbXBvcnQgb3JnLmVjbGlwc2UuZXF1aW5veC5pbnRlcm5hbC5kcy5tb2RlbC4qOwotaW1wb3J0IG9yZy5lY2xpcHNlLmVxdWlub3guaW50ZXJuYWwudXRpbC5ldmVudC5RdWV1ZTsKLWltcG9ydCBvcmcuZWNsaXBzZS5lcXVpbm94LmludGVybmFsLnV0aWwudGhyZWFkcG9vbC5UaHJlYWRQb29sTWFuYWdlcjsKLWltcG9ydCBvcmcuZWNsaXBzZS5vc2dpLnV0aWwuTkxTOwotaW1wb3J0IG9yZy5vc2dpLmZyYW1ld29yay4qOwotaW1wb3J0IG9yZy5vc2dpLnNlcnZpY2UuY20uKjsKLWltcG9ydCBvcmcub3NnaS5zZXJ2aWNlLmNvbXBvbmVudC5Db21wb25lbnRDb25zdGFudHM7Ci1pbXBvcnQgb3JnLm9zZ2kuc2VydmljZS5jb21wb25lbnQuQ29tcG9uZW50RXhjZXB0aW9uOwotaW1wb3J0IG9yZy5vc2dpLnNlcnZpY2UubG9nLkxvZ1NlcnZpY2U7Ci1pbXBvcnQgb3JnLm9zZ2kudXRpbC50cmFja2VyLlNlcnZpY2VUcmFja2VyOwotCi0vKioKLSAqIEFjdHMgYXMgYSAiQnVuZGxlIE1hbmFnZXIiIC0gYSBsaXN0ZW5lciBmb3IgYnVuZGxlIGV2ZW50cy4gV2hlbmV2ZXIgYSBidW5kbGUKLSAqIGlzIHN0b3BwZWQgb3Igc3RhcnRlZCBpdCB3aWxsIGludm9rZSB0aGUgcmVzb2x2ZXIgdG8gcmVzcGVjdGl2ZWx5IGVuYWJsZSBvcgotICogZGlzYWJsZSB0aGUgY29udGFpbmVkIGNvbXBvbmVudHMuIE5vdGljZSwgdGhlIFN5bmNocm9ub3VzQnVuZGxlTGlzdGVuZXIKLSAqIGJ1bmRsZSBsaXN0ZW5lcnMgYXJlIGNhbGxlZCBwcmlvciBidW5kbGUgZXZlbnQgaXMgY29tcGxldGVkLgotICogCi0gKiBJdCBpcyBhbHNvIGEgbGlzdGVuZXIgZm9yIHVwZGF0ZSBhbmQgZGVsZXRlIGNvbmZpZ3VyYXRpb24gZXZlbnRzLCBzZW50IGJ5Ci0gKiBDb25maWd1cmF0aW9uIEFkbWluLCB0aHVzIGhhbmRsaW5nIHRoZSBjaGFuZ2VzIGluIGNvbmZpZ3VyYXRpb25zIHdoaWNoIGFyZSBtZWFudCAKLSAqIHRvIGNvbmZpZ3VyZSB0aGUgcHJvcGVydGllcyBvZiBEUyBjb21wb25lbnRzCi0gKiAKLSAqIEBhdXRob3IgTWFyaWEgSXZhbm92YQotICogQGF1dGhvciBTdG95YW4gQm9zaGV2Ci0gKiBAYXV0aG9yIFBhdmxpbiBEb2JyZXYKLSAqLwotCi1wdWJsaWMgY2xhc3MgU0NSTWFuYWdlciBpbXBsZW1lbnRzIFNlcnZpY2VMaXN0ZW5lciwgU3luY2hyb25vdXNCdW5kbGVMaXN0ZW5lciwgQ29uZmlndXJhdGlvbkxpc3RlbmVyLCBXb3JrUGVyZm9ybWVyLCBQcml2aWxlZ2VkQWN0aW9uIHsKLQotCS8qKiB3b3JrIGFjdGlvbiB0eXBlICovCi0JcHVibGljIGZpbmFsIGludCBFTkFCTEVfQ09NUE9ORU5UUyA9IDE7Ci0JcHVibGljIGZpbmFsIGludCBESVNBQkxFX0NPTVBPTkVOVFMgPSAyOwotCi0JcHJvdGVjdGVkIEhhc2h0YWJsZSBidW5kbGVUb1NlcnZpY2VDb21wb25lbnRzOwotCXByb3RlY3RlZCBIYXNodGFibGUgcHJvY2Vzc2luZ0J1bmRsZXMgPSBuZXcgSGFzaHRhYmxlKDUpOwotCXByb3RlY3RlZCBRdWV1ZSBxdWV1ZTsKLQlwcml2YXRlIFJlc29sdmVyIHJlc29sdmVyOwotCi0JcHJpdmF0ZSBXb3JrVGhyZWFkIHdvcmtUaHJlYWQ7Ci0JcHJvdGVjdGVkIGJvb2xlYW4gcnVubmluZyA9IGZhbHNlOwotCXByb3RlY3RlZCBib29sZWFuIHN0b3BwZWQgPSBmYWxzZTsKLQlwcml2YXRlIFNlcnZpY2VUcmFja2VyIHRocmVhZFBvb2xNYW5hZ2VyVHJhY2tlcjsKLQlwcml2YXRlIGJvb2xlYW4gaGFzUmVnaXN0ZXJlZFNlcnZpY2VMaXN0ZW5lciA9IGZhbHNlOwotCXByaXZhdGUgQ29tcG9uZW50U3RvcmFnZSBzdG9yYWdlOwotCi0JLyoqCi0JICogQ29uc3RydWN0cyB0aGUgU0NSTWFuYWdlci4KLQkgKi8KLQlwdWJsaWMgU0NSTWFuYWdlcigpIHsKLQkJaGFzUmVnaXN0ZXJlZFNlcnZpY2VMaXN0ZW5lciA9IHRydWU7Ci0JCXF1ZXVlID0gbmV3IFF1ZXVlKDEwKTsKLQkJaWYgKEFjdGl2YXRvci5zdGFydHVwKQotCQkJQWN0aXZhdG9yLnRpbWVMb2coIlF1ZXVlIGluc3RhbnRpYXRlZCBmb3IgIik7IC8vJE5PTi1OTFMtMSQKLQotCQl0aHJlYWRQb29sTWFuYWdlclRyYWNrZXIgPSBuZXcgU2VydmljZVRyYWNrZXIoQWN0aXZhdG9yLmJjLCBUaHJlYWRQb29sTWFuYWdlci5jbGFzcy5nZXROYW1lKCksIG51bGwpOwotCQl0aHJlYWRQb29sTWFuYWdlclRyYWNrZXIub3BlbigpOwotCQlpZiAoQWN0aXZhdG9yLnN0YXJ0dXApCi0JCQlBY3RpdmF0b3IudGltZUxvZygiVGhyZWFkcG9vbCBzZXJ2aWNlIHRyYWNrZXIgb3BlbmVkIGZvciAiKTsgLy8kTk9OLU5MUy0xJAotCi0JCXJlc29sdmVyID0gbmV3IFJlc29sdmVyKHRoaXMpOwotCQlpZiAoQWN0aXZhdG9yLnN0YXJ0dXApCi0JCQlBY3RpdmF0b3IudGltZUxvZygiUmVzb2x2ZXIgaW5zdGFudGlhdGVkIGZvciAiKTsgLy8kTk9OLU5MUy0xJAotCi0JCXJlc29sdmVyLnN5bmNocm9uaXplU2VydmljZVJlZmVyZW5jZXMoKTsKLQkJaWYgKEFjdGl2YXRvci5zdGFydHVwKQotCQkJQWN0aXZhdG9yLnRpbWVMb2coInJlc29sdmVyLnN5bmNocm9uaXplU2VydmljZVJlZmVyZW5jZXMoKSBtZXRob2QgdG9vayAiKTsgLy8kTk9OLU5MUy0xJAotCi0JCVN0cmluZyBzdG9yYWdlQ2xhc3MgPSBBY3RpdmF0b3IuYmMuZ2V0UHJvcGVydHkoInNjci5zdG9yYWdlLmNsYXNzIik7IC8vJE5PTi1OTFMtMSQKLQkJaWYgKHN0b3JhZ2VDbGFzcyA9PSBudWxsKSB7Ci0JCQlzdG9yYWdlQ2xhc3MgPSAib3JnLmVjbGlwc2UuZXF1aW5veC5pbnRlcm5hbC5kcy5zdG9yYWdlLmZpbGUuRmlsZVN0b3JhZ2UiOyAvLyROT04tTkxTLTEkCi0JCX0KLQkJdHJ5IHsKLQkJCXN0b3JhZ2UgPSAoQ29tcG9uZW50U3RvcmFnZSkgQ2xhc3MuZm9yTmFtZShzdG9yYWdlQ2xhc3MpLmdldENvbnN0cnVjdG9yKG5ldyBDbGFzc1tdIHtCdW5kbGVDb250ZXh0LmNsYXNzfSkubmV3SW5zdGFuY2UobmV3IE9iamVjdFtdIHtBY3RpdmF0b3IuYmN9KTsKLQkJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKLQkJCUFjdGl2YXRvci5sb2cobnVsbCwgTG9nU2VydmljZS5MT0dfRVJST1IsIE5MUy5iaW5kKE1lc3NhZ2VzLkNPVUxEX05PVF9DUkVBVEVfSU5TVEFOQ0UsIHN0b3JhZ2VDbGFzcyksIGUpOwotCQl9Ci0JCWlmIChBY3RpdmF0b3Iuc3RhcnR1cCkKLQkJCUFjdGl2YXRvci50aW1lTG9nKCJDcmVhdGluZyBzdG9yYWdlIHRvb2sgIik7IC8vJE5PTi1OTFMtMSQKLQotCQlBY3RpdmF0b3IuYmMuYWRkQnVuZGxlTGlzdGVuZXIodGhpcyk7Ci0JfQotCi0JcHVibGljIHZvaWQgc3RhcnRJdCgpIHsKLQkJLy8gbG9vcCB0aHJvdWdoIHRoZSBjdXJyZW50bHkgaW5zdGFsbGVkIGJ1bmRsZXMKLQkJQnVuZGxlW10gYnVuZGxlcyA9IEFjdGl2YXRvci5iYy5nZXRCdW5kbGVzKCk7Ci0JCWlmIChidW5kbGVzICE9IG51bGwpIHsKLQkJCWZvciAoaW50IGkgPSAwOyBpIDwgYnVuZGxlcy5sZW5ndGg7IGkrKykgewotCQkJCUJ1bmRsZSBjdXJyZW50ID0gYnVuZGxlc1tpXTsKLQkJCQkvLyB0cnkgdG8gcHJvY2VzcyB0aGUgYWN0aXZlIG9uZXMuCi0JCQkJaWYgKGN1cnJlbnQuZ2V0U3RhdGUoKSA9PSBCdW5kbGUuQUNUSVZFKSB7Ci0JCQkJCXN0YXJ0ZWRCdW5kbGUoY3VycmVudCk7Ci0JCQkJfSBlbHNlIGlmIChjdXJyZW50LmdldFN0YXRlKCkgPT0gQnVuZGxlLlNUQVJUSU5HKSB7Ci0JCQkJCVN0cmluZyBsYXp5ID0gKFN0cmluZykgY3VycmVudC5nZXRIZWFkZXJzKCIiKS5nZXQoQ29uc3RhbnRzLkJVTkRMRV9BQ1RJVkFUSU9OUE9MSUNZKTsgLy8kTk9OLU5MUy0xJAotCQkJCQlpZiAobGF6eSAhPSBudWxsICYmIGxhenkuaW5kZXhPZihDb25zdGFudHMuQUNUSVZBVElPTl9MQVpZKSA+PSAwKSB7Ci0JCQkJCQlzdGFydGVkQnVuZGxlKGN1cnJlbnQpOwotCQkJCQl9Ci0JCQkJfQotCQkJfQotCQl9Ci0JfQotCi0JLyoqCi0JICogQWRkIGFuIGV2ZW50IHRvIHRoZSBxdWV1ZS4gVGhlIGV2ZW50IHdpbGwgYmUgZm9yd2FyZGVkIHRvIHRhcmdldCBzZXJ2aWNlCi0JICogYXMgc29vbiBhcyBwb3NzaWJsZS4KLQkgKiAKLQkgKiBAcGFyYW0gdXBFdgotCSAqICAgICAgICAgICAgZXZlbnQsIGhvbGRpbmcgaW5mbyBmb3IgdXBkYXRlL2RlbGV0aW9uIG9mIGEgY29uZmlndXJhdGlvbi4KLQkgKi8KLQlwdWJsaWMgdm9pZCBhZGRFdmVudChPYmplY3QgdXBFdiwgYm9vbGVhbiBzZWN1cml0eUNhbGwpIHsKLQkJdHJ5IHsKLQkJCXN5bmNocm9uaXplZCAocXVldWUpIHsKLQkJCQlxdWV1ZS5wdXQodXBFdik7Ci0JCQkJaWYgKCFydW5uaW5nKSB7Ci0JCQkJCWlmIChxdWV1ZS5zaXplKCkgPiAwKSB7Ci0JCQkJCQlydW5uaW5nID0gdHJ1ZTsKLQkJCQkJCXdvcmtUaHJlYWQgPSBuZXcgV29ya1RocmVhZCh0aGlzKTsKLQkJCQkJCWlmIChzZWN1cml0eUNhbGwpIHsKLQkJCQkJCQlBY2Nlc3NDb250cm9sbGVyLmRvUHJpdmlsZWdlZCh0aGlzKTsKLQkJCQkJCQlyZXR1cm47Ci0JCQkJCQl9Ci0JCQkJCQlUaHJlYWRQb29sTWFuYWdlciB0aHJlYWRQb29sID0gKFRocmVhZFBvb2xNYW5hZ2VyKSB0aHJlYWRQb29sTWFuYWdlclRyYWNrZXIuZ2V0U2VydmljZSgpOwotCQkJCQkJaWYgKHRocmVhZFBvb2wgIT0gbnVsbCkgewotCQkJCQkJCXRocmVhZFBvb2wuZXhlY3V0ZSh3b3JrVGhyZWFkLCBUaHJlYWQuTUFYX1BSSU9SSVRZLCAiQ29tcG9uZW50IFJlc29sdmUgVGhyZWFkIik7IC8vJE5PTi1OTFMtMSQKLQkJCQkJCX0gZWxzZSB7Ci0JCQkJCQkJbmV3IFRocmVhZCh3b3JrVGhyZWFkLCAiQ29tcG9uZW50IFJlc29sdmUgVGhyZWFkIikuc3RhcnQoKTsgLy8kTk9OLU5MUy0xJAotCQkJCQkJfQotCQkJCQl9Ci0JCQkJfSBlbHNlIGlmICh3b3JrVGhyZWFkLndhaXRpbmcgPiAwKSB7Ci0JCQkJCXF1ZXVlLm5vdGlmeUFsbCgpOwotCQkJCX0KLQkJCX0KLQkJfSBjYXRjaCAoVGhyb3dhYmxlIGUpIHsKLQkJCUFjdGl2YXRvci5sb2cobnVsbCwgTG9nU2VydmljZS5MT0dfRVJST1IsIE1lc3NhZ2VzLlVORVhQRUNURURfRVhDRVBUSU9OLCBlKTsKLQkJfQotCX0KLQotCXB1YmxpYyBPYmplY3QgcnVuKCkgewotCQlUaHJlYWRQb29sTWFuYWdlciB0aHJlYWRQb29sID0gKFRocmVhZFBvb2xNYW5hZ2VyKSB0aHJlYWRQb29sTWFuYWdlclRyYWNrZXIuZ2V0U2VydmljZSgpOwotCQlpZiAodGhyZWFkUG9vbCAhPSBudWxsKSB7Ci0JCQl0aHJlYWRQb29sLmV4ZWN1dGUod29ya1RocmVhZCwgVGhyZWFkLk1BWF9QUklPUklUWSwgIkNvbXBvbmVudCBSZXNvbHZlIFRocmVhZCIpOyAvLyROT04tTkxTLTEkCi0JCX0gZWxzZSB7Ci0JCQluZXcgVGhyZWFkKHdvcmtUaHJlYWQsICJDb21wb25lbnQgUmVzb2x2ZSBUaHJlYWQiKS5zdGFydCgpOyAvLyROT04tTkxTLTEkCi0JCX0KLQkJcmV0dXJuIG51bGw7Ci0JfQotCi0JcHVibGljIHZvaWQgcXVldWVCbG9ja2VkKCkgewotCQlyZXNvbHZlci5xdWV1ZUJsb2NrZWQoKTsKLQkJc3luY2hyb25pemVkIChxdWV1ZSkgewotCQkJcnVubmluZyA9IGZhbHNlOwotCQkJYWRkRXZlbnQobnVsbCwgQWN0aXZhdG9yLnNlY3VyaXR5KTsgLy8gd2lsbCByZXN1bHQgaW4gc3RhcnRpbmcgbmV3Ci0JCQkvLyBXb3JrVGhyZWFkIHRvIHByb2Nlc3MgdGhlIHF1ZXVlZCB3b3JrCi0JCX0KLQl9Ci0KLQkvKioKLQkgKiBUaGlzIG1ldGhvZHMgdGFrZXMgdGhlIGlucHV0IHBhcmFtZXRlcnMgYW5kIGNyZWF0ZXMgYSBRdWV1ZWQgb2JqZWN0IGFuZAotCSAqIHF1ZXVlcyBpdC4gVGhlIHRocmVhZCBpcyBub3RpZmllZC4KLQkgKiAKLQkgKiBAcGFyYW0gZAotCSAqICAgICAgICAgICAgRGlzcGF0Y2hlciBmb3IgdGhpcyBpdGVtCi0JICogQHBhcmFtIGEKLQkgKiAgICAgICAgICAgIEFjdGlvbiBmb3IgdGhpcyBpdGVtCi0JICogQHBhcmFtIG8KLQkgKiAgICAgICAgICAgIE9iamVjdCBmb3IgdGhpcyBpdGVtCi0JICogQHBhcmFtIHNlY3VyaXR5Q2FsbCBzcGVjaWZpZXMgd2hldGhlciB0byB1c2Ugc2VjdXJpdHkgcHJpdmlsZWdlZCBjYWxsCi0JICovCi0JcHVibGljIHZvaWQgZW5xdWV1ZVdvcmsoV29ya1BlcmZvcm1lciBkLCBpbnQgYSwgT2JqZWN0IG8sIGJvb2xlYW4gc2VjdXJpdHlDYWxsKSB7Ci0JCWFkZEV2ZW50KG5ldyBRdWV1ZWRKb2IoZCwgYSwgbyksIHNlY3VyaXR5Q2FsbCk7Ci0JfQotCi0JLyoqCi0JICogU3RvcHMgdGhpcyB0aHJlYWQsIG1ha2luZyBpdCBnZXR0aW5nIG91dCBvZiBtZXRob2QgcnVuLgotCSAqLwotCXB1YmxpYyB2b2lkIHN0b3BJdCgpIHsKLQkJc3RvcHBlZCA9IHRydWU7Ci0JCWRpc3Bvc2VCdW5kbGVzKCk7Ci0JCWlmIChxdWV1ZSAhPSBudWxsKSB7Ci0JCQlxdWV1ZS5jbGVhcigpOwotCQl9Ci0JCWlmIChydW5uaW5nKSB7Ci0JCQlzeW5jaHJvbml6ZWQgKHF1ZXVlKSB7Ci0JCQkJcXVldWUubm90aWZ5KCk7Ci0JCQl9Ci0JCQlpbnQgY291bnRlciA9IDA7Ci0KLQkJCXdoaWxlIChydW5uaW5nICYmIGNvdW50ZXIgPCAyMCkgewotCQkJCS8vIHdhaXQgbWF4aW11bSAyIHNlY29uZHMgdG8gY29tcGxldGUgY3VycmVudCB0YXNrIGluIHRoZSBxdWV1ZQotCQkJCXRyeSB7Ci0JCQkJCVRocmVhZC5zbGVlcCgxMDApOwotCQkJCX0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGllKSB7Ci0JCQkJCS8vbm90aGluZyB0byBkbwotCQkJCX0KLQkJCQljb3VudGVyKys7Ci0JCQl9Ci0JCX0KLQkJc3RvcHBlZCA9IHRydWU7Ci0JCXRocmVhZFBvb2xNYW5hZ2VyVHJhY2tlci5jbG9zZSgpOwotCQlzdG9yYWdlLnN0b3AoKTsKLQl9Ci0KLQlwdWJsaWMgdm9pZCBzZXJ2aWNlQ2hhbmdlZChTZXJ2aWNlRXZlbnQgc0V2KSB7Ci0KLQkJcmVzb2x2ZXIuZ2V0RWxpZ2libGUoc0V2KTsKLQl9Ci0KLQlwdWJsaWMgZmluYWwgdm9pZCBidW5kbGVDaGFuZ2VkKEJ1bmRsZUV2ZW50IGV2ZW50KSB7Ci0JCWxvbmcgc3RhcnQgPSAwbDsKLQkJaWYgKEFjdGl2YXRvci5QRVJGKSB7Ci0JCQlzdGFydCA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOwotCQkJQWN0aXZhdG9yLmxvZy5pbmZvKCJbRFMgcGVyZl0gU3RhcnRlZCBwcm9jZXNzaW5nIGJ1bmRsZSBldmVudCAiICsgZXZlbnQpOyAvLyROT04tTkxTLTEkCi0JCX0KLQkJaW50IHR5cGUgPSBldmVudC5nZXRUeXBlKCk7Ci0JCWlmICh0eXBlID09IEJ1bmRsZUV2ZW50LlNUT1BQSU5HKSB7Ci0JCQlzdG9wcGluZ0J1bmRsZShldmVudC5nZXRCdW5kbGUoKSk7Ci0JCX0gZWxzZSBpZiAodHlwZSA9PSBCdW5kbGVFdmVudC5TVEFSVEVEKSB7Ci0JCQlzdGFydGVkQnVuZGxlKGV2ZW50LmdldEJ1bmRsZSgpKTsKLQkJfSBlbHNlIGlmICh0eXBlID09IEJ1bmRsZUV2ZW50LkxBWllfQUNUSVZBVElPTikgewotCQkJc3RhcnRlZEJ1bmRsZShldmVudC5nZXRCdW5kbGUoKSk7Ci0JCX0gZWxzZSBpZiAodHlwZSA9PSBCdW5kbGVFdmVudC5VTklOU1RBTExFRCAmJiBBY3RpdmF0b3IuREJTVE9SRSkgewotCQkJc3RvcmFnZS5kZWxldGVDb21wb25lbnREZWZpbml0aW9ucyhldmVudC5nZXRCdW5kbGUoKS5nZXRCdW5kbGVJZCgpKTsKLQkJfQotCQlpZiAoQWN0aXZhdG9yLlBFUkYpIHsKLQkJCXN0YXJ0ID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCkgLSBzdGFydDsKLQkJCUFjdGl2YXRvci5sb2cuaW5mbygiW0RTIHBlcmZdIFByb2Nlc3NlZCBidW5kbGUgZXZlbnQgJyIgKyBldmVudCArICInIGZvciAiICsgc3RhcnQgKyAibXMiKTsgLy8kTk9OLU5MUy0xJC8vJE5PTi1OTFMtMiQgLy8kTk9OLU5MUy0zJAotCQl9Ci0JfQotCi0JLy8gLS0gYmVnaW4gJ0NNIGxpc3RlbmVyJwotCS8qKgotCSAqIExpc3RlbiBmb3IgY29uZmlndXJhdGlvbiBjaGFuZ2VzCi0JICogCi0JICogU2VydmljZSBDb21wb25lbnRzIGNhbiByZWNlaXZlIHByb3BlcnRpZXMgZnJvbSB0aGUgQ29uZmlndXJhdGlvbiBBZG1pbgotCSAqIHNlcnZpY2UuIElmIGEgU2VydmljZSBDb21wb25lbnQgaXMgYWN0aXZhdGVkIGFuZCBpdO+/vXMgcHJvcGVydGllcyBhcmUKLQkgKiB1cGRhdGVkIGluIHRoZSBDb25maWd1cmF0aW9uIEFkbWluIHNlcnZpY2UsIHRoZSBTQ1IgbXVzdCBkZWFjdGl2YXRlIHRoZQotCSAqIGNvbXBvbmVudCBhbmQgYWN0aXZhdGUgdGhlIGNvbXBvbmVudCBhZ2FpbiB1c2luZyB0aGUgbmV3IHByb3BlcnRpZXMuCi0JICogCi0JICogQHBhcmFtIGV2ZW50Ci0JICogICAgICAgICAgICBDb25maWd1cmF0aW9uRXZlbnQKLQkgKi8KLQlwdWJsaWMgdm9pZCBjb25maWd1cmF0aW9uRXZlbnQoQ29uZmlndXJhdGlvbkV2ZW50IGV2ZW50KSB7Ci0JCWlmIChidW5kbGVUb1NlcnZpY2VDb21wb25lbnRzICE9IG51bGwgJiYgIWJ1bmRsZVRvU2VydmljZUNvbXBvbmVudHMuaXNFbXB0eSgpKSB7Ci0JCQlhZGRFdmVudChldmVudCwgdHJ1ZSk7Ci0JCX0KLQl9Ci0KLQlwcm90ZWN0ZWQgdm9pZCBwcm9jZXNzQ29uZmlndXJhdGlvbkV2ZW50KENvbmZpZ3VyYXRpb25FdmVudCBldmVudCkgewotCQlpZiAoYnVuZGxlVG9TZXJ2aWNlQ29tcG9uZW50cyA9PSBudWxsIHx8IGJ1bmRsZVRvU2VydmljZUNvbXBvbmVudHMuaXNFbXB0eSgpKSB7Ci0JCQkvLyBubyBjb21wb25lbnRzIGZvdW5kIHRpbGwgbm93Ci0JCQlyZXR1cm47Ci0JCX0KLQkJbG9uZyBzdGFydCA9IDBsOwotCQl0cnkgewotCQkJaWYgKEFjdGl2YXRvci5ERUJVRykgewotCQkJCUFjdGl2YXRvci5sb2cuZGVidWcoIiBSZXNvbHZlci5jb25maWd1cmF0aW9uRXZlbnQoKTogcGlkID0gIiArIGV2ZW50LmdldFBpZCgpICsgIiwgZnBpZCA9ICIgKyBldmVudC5nZXRGYWN0b3J5UGlkKCksIG51bGwpOyAvLyROT04tTkxTLTEkIC8vJE5PTi1OTFMtMiQKLQkJCX0KLQkJCWlmIChBY3RpdmF0b3IuUEVSRikgewotCQkJCXN0YXJ0ID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCk7Ci0JCQkJQWN0aXZhdG9yLmxvZy5pbmZvKCJbRFMgcGVyZl0gU3RhcnRlZCBwcm9jZXNzaW5nIGNvbmZpZ3VyYXRpb24gZXZlbnQgIiArIGV2ZW50KTsgLy8kTk9OLU5MUy0xJAotCQkJfQotCi0JCQlTdHJpbmcgcGlkID0gZXZlbnQuZ2V0UGlkKCk7Ci0JCQlTdHJpbmcgZnBpZCA9IGV2ZW50LmdldEZhY3RvcnlQaWQoKTsKLQkJCWZvciAoRW51bWVyYXRpb24ga2V5cyA9IGJ1bmRsZVRvU2VydmljZUNvbXBvbmVudHMua2V5cygpOyBrZXlzLmhhc01vcmVFbGVtZW50cygpOykgewotCQkJCVZlY3RvciBidW5kbGVDb21wcyA9IChWZWN0b3IpIGJ1bmRsZVRvU2VydmljZUNvbXBvbmVudHMuZ2V0KGtleXMubmV4dEVsZW1lbnQoKSk7Ci0JCQkJLy8gYnVuZGxlQ29tcHMgbWF5IGJlIG51bGwgc2luY2UgYnVuZGxlVG9TZXJ2aWNlQ29tcG9uZW50cwotCQkJCS8vIG1heSBoYXZlIGJlZW4gbW9kaWZpZWQgYnkgYW5vdGhlciB0aHJlYWQKLQkJCQlpZiAoYnVuZGxlQ29tcHMgIT0gbnVsbCkgewotCQkJCQlmb3IgKGludCBpID0gMDsgaSA8IGJ1bmRsZUNvbXBzLnNpemUoKTsgaSsrKSB7Ci0JCQkJCQlTZXJ2aWNlQ29tcG9uZW50IHNjID0gKFNlcnZpY2VDb21wb25lbnQpIGJ1bmRsZUNvbXBzLmVsZW1lbnRBdChpKTsKLQkJCQkJCWlmIChzYy5nZXRDb25maWd1cmF0aW9uUG9saWN5KCkgPT0gU2VydmljZUNvbXBvbmVudC5DT05GX1BPTElDWV9JR05PUkUpIHsKLQkJCQkJCQkvL3NraXAgcHJvY2Vzc2luZyBvZiB0aGlzIGNvbXBvbmVudCAtIGl0IGlzIG5vdCBpbnRlcmVzdGVkIGluIGNvbmZpZ3VyYXRpb24gY2hhbmdlcwotCQkJCQkJCWNvbnRpbnVlOwotCQkJCQkJfQotCQkJCQkJU3RyaW5nIG5hbWUgPSBzYy5nZXRDb25maWd1cmF0aW9uUElEKCk7Ci0JCQkJCQlpZiAobmFtZS5lcXVhbHMocGlkKSB8fCBuYW1lLmVxdWFscyhmcGlkKSkgewotCQkJCQkJCWlmIChuYW1lLmVxdWFscyhmcGlkKSAmJiBzYy5mYWN0b3J5ICE9IG51bGwpIHsKLQkJCQkJCQkJQWN0aXZhdG9yLmxvZyhzYy5iYywgTG9nU2VydmljZS5MT0dfRVJST1IsIE5MUy5iaW5kKE1lc3NhZ2VzLkZBQ1RPUllfQ09ORl9OT1RfQVBQTElDQUJMRV9GT1JfQ09NUE9ORU5UX0ZBQ1RPUlksIHNjLm5hbWUpLCBudWxsKTsKLQkJCQkJCQkJcmV0dXJuOwotCQkJCQkJCX0KLQkJCQkJCQlpZiAoc2MuZW5hYmxlZCkgewotCQkJCQkJCQlpZiAoQWN0aXZhdG9yLkRFQlVHKSB7Ci0JCQkJCQkJCQlBY3RpdmF0b3IubG9nLmRlYnVnKCJTQ1JNYW5hZ2VyLnByb2Nlc3NDb25maWd1cmF0aW9uRXZlbnQoKTogZm91bmQgY29tcG9uZW50IC0gIiArIHBpZCwgbnVsbCk7IC8vJE5PTi1OTFMtMSQKLQkJCQkJCQkJfQotCQkJCQkJCQlwcm9jZXNzQ29uZmlndXJhdGlvbkV2ZW50KGV2ZW50LCBzYyk7Ci0JCQkJCQkJfQotCQkJCQkJCXJldHVybjsKLQkJCQkJCX0KLQkJCQkJfQotCQkJCX0KLQkJCX0KLQkJfSBjYXRjaCAoVGhyb3dhYmxlIGUpIHsKLQkJCUFjdGl2YXRvci5sb2cobnVsbCwgTG9nU2VydmljZS5MT0dfRVJST1IsIE5MUy5iaW5kKE1lc3NhZ2VzLkVSUk9SX1BST0NFU1NJTkdfQ09ORklHVVJBVElPTiwgZXZlbnQuZ2V0UmVmZXJlbmNlKCkuZ2V0QnVuZGxlKCkpLCBlKTsKLQkJfSBmaW5hbGx5IHsKLQkJCWlmIChBY3RpdmF0b3IuUEVSRikgewotCQkJCXN0YXJ0ID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCkgLSBzdGFydDsKLQkJCQlBY3RpdmF0b3IubG9nLmluZm8oIltEUyBwZXJmXSBQcm9jZXNzZWQgY29uZmlndXJhdGlvbiBldmVudCAnIiArIGV2ZW50ICsgIicgZm9yICIgKyBzdGFydCArICJtcyIpOyAvLyROT04tTkxTLTEkIC8vJE5PTi1OTFMtMiQvLyROT04tTkxTLTMkCi0JCQl9Ci0JCX0KLQl9Ci0KLQlwcml2YXRlIHZvaWQgcHJvY2Vzc0NvbmZpZ3VyYXRpb25FdmVudChDb25maWd1cmF0aW9uRXZlbnQgZXZlbnQsIFNlcnZpY2VDb21wb25lbnQgc2MpIHsKLQkJQ29uZmlndXJhdGlvbltdIGNvbmZpZyA9IG51bGw7Ci0KLQkJU3RyaW5nIHBpZCA9IGV2ZW50LmdldFBpZCgpOwotCQlTdHJpbmcgZnBpZCA9IGV2ZW50LmdldEZhY3RvcnlQaWQoKTsKLQotCQlzd2l0Y2ggKGV2ZW50LmdldFR5cGUoKSkgewotCQkJY2FzZSBDb25maWd1cmF0aW9uRXZlbnQuQ01fVVBEQVRFRCA6Ci0KLQkJCQlTdHJpbmcgZmlsdGVyID0gKGZwaWQgIT0gbnVsbCA/ICIoJiIgOiAiIikgKyAiKCIgKyBDb25zdGFudHMuU0VSVklDRV9QSUQgKyAiPSIgKyBwaWQgKyAiKSIgKyAoZnBpZCAhPSBudWxsID8gKCIoIiArIENvbmZpZ3VyYXRpb25BZG1pbi5TRVJWSUNFX0ZBQ1RPUllQSUQgKyAiPSIgKyBmcGlkICsgIikpIikgOiAiIik7IC8vJE5PTi1OTFMtMSQgLy8kTk9OLU5MUy0yJCAvLyROT04tTkxTLTMkIC8vJE5PTi1OTFMtNCQgLy8kTk9OLU5MUy01JCAvLyROT04tTkxTLTYkIC8vJE5PTi1OTFMtNyQgLy8kTk9OLU5MUy04JCAvLyROT04tTkxTLTkkCi0JCQkJdHJ5IHsKLQkJCQkJY29uZmlnID0gQWN0aXZhdG9yLmxpc3RDb25maWd1cmF0aW9ucyhmaWx0ZXIpOwotCQkJCX0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKLQkJCQkJQWN0aXZhdG9yLmxvZyhudWxsLCBMb2dTZXJ2aWNlLkxPR19FUlJPUiwgTWVzc2FnZXMuRVJST1JfTElTVElOR19DT05GSUdVUkFUSU9OUywgZSk7Ci0JCQkJfSBjYXRjaCAoSW52YWxpZFN5bnRheEV4Y2VwdGlvbiBlKSB7Ci0JCQkJCUFjdGl2YXRvci5sb2cobnVsbCwgTG9nU2VydmljZS5MT0dfRVJST1IsIE1lc3NhZ2VzLkVSUk9SX0xJU1RJTkdfQ09ORklHVVJBVElPTlMsIGUpOwotCQkJCX0KLQotCQkJCWlmIChjb25maWcgPT0gbnVsbCkgewotCQkJCQkvLyBUaGUgY29uZmlndXJhdGlvbiBtYXkgaGF2ZSBiZWVuIGRlbGV0ZWQgYnkgdGhlIG5vdwotCQkJCQkvLyBJZiBpdCBkb2VzIG5vdCBleGlzdCB3ZSBtdXN0IGRvIG5vdGhpbmcKLQkJCQkJcmV0dXJuOwotCQkJCX0KLQotCQkJCS8vIGlmIE5PVCBhIGZhY3RvcnkKLQkJCQlpZiAoZnBpZCA9PSBudWxsKSB7Ci0JCQkJCS8vIHRoZXJlIGlzIG9ubHkgb25lIFNDUCBmb3IgdGhpcyBTQwotCQkJCQlib29sZWFuIHJlcXVpcmVzUmVzdGFydCA9IHRydWU7Ci0JCQkJCWlmIChzYy5pc05hbWVzcGFjZUF0TGVhc3QxMSgpICYmIHNjLm1vZGlmeU1ldGhvZE5hbWUgIT0gIiIpIHsgLy8kTk9OLU5MUy0xJAotCQkJCQkJU2VydmljZUNvbXBvbmVudFByb3Agc2NwID0gc2MuZ2V0U2VydmljZUNvbXBvbmVudFByb3AoKTsKLQkJCQkJCWlmIChzY3AgIT0gbnVsbCAmJiBzY3AuaXNCdWlsdCgpKSB7Ci0JCQkJCQkJLy9wcm9jZXNzIG9ubHkgYnVpbHQgY29tcG9uZW50cwotCQkJCQkJCXJlcXVpcmVzUmVzdGFydCA9IHByb2Nlc3NDb25maWd1cmF0aW9uQ2hhbmdlKHNjcCwgY29uZmlnWzBdKTsKLQkJCQkJCX0KLQkJCQkJfQotCQkJCQlpZiAocmVxdWlyZXNSZXN0YXJ0KSB7Ci0JCQkJCQkvLyB0aGVyZSBpcyBvbmx5IG9uZSBTQ1AgZm9yIHRoaXMgU0MsIHNvIHdlIGNhbiBkaXNhYmxlIHRoZSBTQwotCQkJCQkJVmVjdG9yIGNvbXBvbmVudHMgPSBuZXcgVmVjdG9yKCk7Ci0JCQkJCQljb21wb25lbnRzLmFkZEVsZW1lbnQoc2MpOwotCQkJCQkJcmVzb2x2ZXIuZGlzYWJsZUNvbXBvbmVudHMoY29tcG9uZW50cywgQ29tcG9uZW50Q29uc3RhbnRzLkRFQUNUSVZBVElPTl9SRUFTT05fQ09ORklHVVJBVElPTl9NT0RJRklFRCk7Ci0KLQkJCQkJCS8vIG5vdyByZS1lbmFibGUgdGhlIFNDIC0gdGhlIHJlc29sdmVyIHdpbGwgcGljayB1cCB0aGUgbmV3IGNvbmZpZwotCQkJCQkJc2MuZW5hYmxlZCA9IHRydWU7Ci0JCQkJCQlyZXNvbHZlci5lbmFibGVDb21wb25lbnRzKGNvbXBvbmVudHMpOwotCQkJCQl9Ci0KLQkJCQkJLy8gSWYgYSBNU0YKLQkJCQkJLy8gY3JlYXRlIGEgbmV3IFNDUCBvciB1cGRhdGUgYW4gZXhpc3Rpbmcgb25lCi0JCQkJfSBlbHNlIHsKLQotCQkJCQkvLyBnZXQgc2NwIHdpdGggdGhpcyBQSUQKLQkJCQkJU2VydmljZUNvbXBvbmVudFByb3Agc2NwID0gc2MuZ2V0Q29tcG9uZW50UHJvcEJ5UElEKHBpZCk7Ci0KLQkJCQkJLy8gaWYgb25seSB0aGUgbm8tcHJvcHMgc2NwIGV4aXN0cywgcmVwbGFjZSBpdAotCQkJCQlpZiAoc2NwID09IG51bGwgJiYgc2MuY29tcG9uZW50UHJvcHMgIT0gbnVsbCkgewotCQkJCQkJc3luY2hyb25pemVkIChzYy5jb21wb25lbnRQcm9wcykgewotCQkJCQkJCWlmIChzYy5jb21wb25lbnRQcm9wcy5zaXplKCkgPT0gMSAmJiAoKChTZXJ2aWNlQ29tcG9uZW50UHJvcCkgc2MuY29tcG9uZW50UHJvcHMuZWxlbWVudEF0KDApKS5nZXRQcm9wZXJ0aWVzKCkuZ2V0KENvbnN0YW50cy5TRVJWSUNFX1BJRCkgPT0gbnVsbCkpIHsKLQkJCQkJCQkJc2NwID0gKFNlcnZpY2VDb21wb25lbnRQcm9wKSBzYy5jb21wb25lbnRQcm9wcy5lbGVtZW50QXQoMCk7Ci0JCQkJCQkJfQotCQkJCQkJfQotCQkJCQl9Ci0JCQkJCWJvb2xlYW4gcmVxdWlyZXNSZXN0YXJ0ID0gdHJ1ZTsKLQkJCQkJaWYgKHNjLmlzTmFtZXNwYWNlQXRMZWFzdDExKCkgJiYgc2MubW9kaWZ5TWV0aG9kTmFtZSAhPSAiIiAmJiBzY3AgIT0gbnVsbCkgeyAvLyROT04tTkxTLTEkCi0JCQkJCQlpZiAoc2NwLmlzQnVpbHQoKSkgewotCQkJCQkJCS8vcHJvY2VzcyBvbmx5IGJ1aWx0IGNvbXBvbmVudHMKLQkJCQkJCQlyZXF1aXJlc1Jlc3RhcnQgPSBwcm9jZXNzQ29uZmlndXJhdGlvbkNoYW5nZShzY3AsIGNvbmZpZ1swXSk7Ci0JCQkJCQl9Ci0JCQkJCX0KLQkJCQkJaWYgKHJlcXVpcmVzUmVzdGFydCkgewotCQkJCQkJLy8gaWYgb2xkIHNjcCBleGlzdHMsIGRpc3Bvc2UgaXQKLQkJCQkJCWlmIChzY3AgIT0gbnVsbCkgewotCQkJCQkJCS8vIGNvbmZpZyBhbHJlYWR5IGV4aXN0cyAtIGRpc3Bvc2Ugb2YgaXQKLQkJCQkJCQlzYy5jb21wb25lbnRQcm9wcy5yZW1vdmVFbGVtZW50KHNjcCk7Ci0JCQkJCQkJVmVjdG9yIGNvbXBvbmVudHMgPSBuZXcgVmVjdG9yKCk7Ci0JCQkJCQkJY29tcG9uZW50cy5hZGRFbGVtZW50KHNjcCk7Ci0JCQkJCQkJcmVzb2x2ZXIuZGlzcG9zZUNvbXBvbmVudENvbmZpZ3MoY29tcG9uZW50cywgQ29tcG9uZW50Q29uc3RhbnRzLkRFQUNUSVZBVElPTl9SRUFTT05fQ09ORklHVVJBVElPTl9NT0RJRklFRCk7Ci0JCQkJCQkJc2NwLnNldFN0YXRlKENvbXBvbmVudC5TVEFURV9ESVNQT1NFRCk7Ci0JCQkJCQl9Ci0KLQkJCQkJCS8vIGNyZWF0ZSBhIG5ldyBzY3AgKGFkZHMgdG8gcmVzb2x2ZXIgZW5hYmxlZFNDUHMgbGlzdCkKLQkJCQkJCXJlc29sdmVyLm1hcChzYywgY29uZmlnWzBdKTsKLQotCQkJCQkJLy8ga2ljayB0aGUgcmVzb2x2ZXIgdG8gZmlndXJlIG91dCBpZiBTQ1AgaXMgc2F0aXNmaWVkLCBldGMKLQkJCQkJCXJlc29sdmVyLmVuYWJsZUNvbXBvbmVudHMobnVsbCk7Ci0JCQkJCX0KLQkJCQl9Ci0KLQkJCQlicmVhazsKLQkJCWNhc2UgQ29uZmlndXJhdGlvbkV2ZW50LkNNX0RFTEVURUQgOgotCi0JCQkJLy8gaWYgbm90IGEgZmFjdG9yeQotCQkJCWlmIChmcGlkID09IG51bGwpIHsKLQotCQkJCQkvLyB0aGVyZSBpcyBvbmx5IG9uZSBTQ1AgZm9yIHRoaXMgU0MsIHNvIHdlIGNhbiBkaXNhYmxlIHRoZSBTQwotCQkJCQlWZWN0b3IgY29tcG9uZW50cyA9IG5ldyBWZWN0b3IoKTsKLQkJCQkJY29tcG9uZW50cy5hZGRFbGVtZW50KHNjKTsKLQkJCQkJcmVzb2x2ZXIuZGlzYWJsZUNvbXBvbmVudHMoY29tcG9uZW50cywgQ29tcG9uZW50Q29uc3RhbnRzLkRFQUNUSVZBVElPTl9SRUFTT05fQ09ORklHVVJBVElPTl9ERUxFVEVEKTsKLQotCQkJCQkvLyBub3cgcmUtZW5hYmxlIHRoZSBTQyAtIHRoZSByZXNvbHZlciB3aWxsIGNyZWF0ZSBTQ1Agd2l0aAotCQkJCQkvLyBubyBjb25maWdBZG1pbiBwcm9wZXJ0aWVzCi0JCQkJCXNjLmVuYWJsZWQgPSB0cnVlOwotCQkJCQlyZXNvbHZlci5lbmFibGVDb21wb25lbnRzKGNvbXBvbmVudHMpOwotCQkJCX0gZWxzZSB7Ci0JCQkJCS8vIGNvbmZpZyBpcyBhIGZhY3RvcnkKLQotCQkJCQkvLyBnZXQgU0NQIGNyZWF0ZWQgZm9yIHRoaXMgY29uZmlnICh3aXRoIHRoaXMgUElEKQotCQkJCQlTZXJ2aWNlQ29tcG9uZW50UHJvcCBzY3AgPSBzYy5nZXRDb21wb25lbnRQcm9wQnlQSUQocGlkKTsKLQotCQkJCQkvLyBpZiB0aGlzIHdhcyB0aGUgbGFzdCBTQ1AgY3JlYXRlZCBmb3IgdGhpcyBmYWN0b3J5Ci0JCQkJCWlmIChzYy5jb21wb25lbnRQcm9wcy5zaXplKCkgPT0gMSkgewotCQkJCQkJLy8gdGhlcmUgaXMgb25seSBvbmUgU0NQIGZvciB0aGlzIFNDLCBzbyB3ZSBjYW4gZGlzYWJsZSB0aGUKLQkJCQkJCS8vIFNDCi0JCQkJCQlWZWN0b3IgY29tcG9uZW50cyA9IG5ldyBWZWN0b3IoKTsKLQkJCQkJCWNvbXBvbmVudHMuYWRkRWxlbWVudChzYyk7Ci0JCQkJCQlyZXNvbHZlci5kaXNhYmxlQ29tcG9uZW50cyhjb21wb25lbnRzLCBDb21wb25lbnRDb25zdGFudHMuREVBQ1RJVkFUSU9OX1JFQVNPTl9DT05GSUdVUkFUSU9OX0RFTEVURUQpOwotCQkJCQkJLy8gbm93IHJlLWVuYWJsZSB0aGUgU0MgLSB0aGUgcmVzb2x2ZXIgd2lsbCBjcmVhdGUgU0NQCi0JCQkJCQkvLyB3aXRoIG5vIGNvbmZpZ0FkbWluIHByb3BlcnRpZXMKLQkJCQkJCXNjLmVuYWJsZWQgPSB0cnVlOwotCQkJCQkJc2Muc2V0U3RhdGUoQ29tcG9uZW50LlNUQVRFX1VOU0FUSVNGSUVEKTsKLQkJCQkJCXJlc29sdmVyLmVuYWJsZUNvbXBvbmVudHMoY29tcG9uZW50cyk7Ci0JCQkJCX0gZWxzZSB7Ci0JCQkJCQkvLyBpbiBjYXNlIGl0IGhhcyBldmVyIGJlZW4gY29uc3RydWN0ZWQKLQkJCQkJCWlmIChzY3AgIT0gbnVsbCkgewotCQkJCQkJCS8vIHdlIGNhbiBqdXN0IGRpc3Bvc2UgdGhpcyBTQ1AKLQkJCQkJCQlzYy5jb21wb25lbnRQcm9wcy5yZW1vdmVFbGVtZW50KHNjcCk7Ci0JCQkJCQkJVmVjdG9yIGNvbXBvbmVudHMgPSBuZXcgVmVjdG9yKCk7Ci0JCQkJCQkJY29tcG9uZW50cy5hZGRFbGVtZW50KHNjcCk7Ci0JCQkJCQkJcmVzb2x2ZXIuZGlzcG9zZUNvbXBvbmVudENvbmZpZ3MoY29tcG9uZW50cywgQ29tcG9uZW50Q29uc3RhbnRzLkRFQUNUSVZBVElPTl9SRUFTT05fQ09ORklHVVJBVElPTl9ERUxFVEVEKTsKLQkJCQkJCQlzY3Auc2V0U3RhdGUoQ29tcG9uZW50LlNUQVRFX0RJU1BPU0VEKTsKLQkJCQkJCX0KLQkJCQkJfQotCQkJCX0KLQkJCQlicmVhazsKLQkJfQotCX0KLQotCS8qKgotCSAqIFByb2Nlc3MgdGhlIG1vZGlmaWNhdGlvbiBvZiB0aGUgc3BlY2lmaWVkIGNvbXBvbmVudC4gCi0JICogSWYgaXQgY2Fubm90IGJlIG1vZGlmaWVkLCB0aGUgbWV0aG9kIHdpbGwgcmV0dXJuIDxjb2RlPnRydWU8L2NvZGU+IGluZGljYXRpbmcgdGhlIGNvbXBvbmVudCBoYXMgdG8gYmUgcmVzdGFydGVkLgotCSAqIEBwYXJhbSBzY3AgdGhlIGNvbXBvbmVudCB0byBtb2RpZnkKLQkgKiBAcGFyYW0gY29uZmlnIHRoZSBjb25maWd1cmF0aW9uIHRoYXQgYnJpbmdzIHRoZSBuZXcgcHJvcGVydGllcwotCSAqIEByZXR1cm4gdHJ1ZSwgaWYgdGhlIGNvbXBvbmVudCBuZWVkcyByZXN0YXJ0ICh0byBiZSBkZWFjdGl2YXRlZCBhbmQgdGhlbiBldmVudHVhbGx5IGFjdGl2YXRlZCBhZ2FpbikKLQkgKi8KLQlwcml2YXRlIGJvb2xlYW4gcHJvY2Vzc0NvbmZpZ3VyYXRpb25DaGFuZ2UoU2VydmljZUNvbXBvbmVudFByb3Agc2NwLCBDb25maWd1cmF0aW9uIGNvbmZpZykgewotCQlib29sZWFuIHJlc3VsdCA9IGZhbHNlOwotCQlIYXNodGFibGUgY3VycmVudFByb3BzID0gc2NwLnByb3BlcnRpZXM7Ci0JCURpY3Rpb25hcnkgbmV3UHJvcHMgPSBjb25maWcuZ2V0UHJvcGVydGllcygpOwotCQlFbnVtZXJhdGlvbiBrZXlzID0gY3VycmVudFByb3BzLmtleXMoKTsKLQkJVmVjdG9yIGNoZWNrZWRGaWx0ZXJzID0gbmV3IFZlY3RvcigpOwotCQl3aGlsZSAoa2V5cy5oYXNNb3JlRWxlbWVudHMoKSAmJiAhcmVzdWx0KSB7Ci0JCQlTdHJpbmcga2V5ID0gKFN0cmluZykga2V5cy5uZXh0RWxlbWVudCgpOwotCQkJaWYgKGtleS5lbmRzV2l0aCgiLnRhcmdldCIpKSB7IC8vJE5PTi1OTFMtMSQKLQkJCQljaGVja2VkRmlsdGVycy5hZGRFbGVtZW50KGtleSk7Ci0JCQkJU3RyaW5nIG5ld0ZpbHRlciA9IChTdHJpbmcpIG5ld1Byb3BzLmdldChrZXkpOwotCQkJCVJlZmVyZW5jZSByZWZlcmVuY2UgPSBudWxsOwotCQkJCVN0cmluZyByZWZOYW1lID0ga2V5LnN1YnN0cmluZygwLCBrZXkubGVuZ3RoKCkgLSAiLnRhcmdldCIubGVuZ3RoKCkpOyAvLyROT04tTkxTLTEkCi0JCQkJVmVjdG9yIHJlZmVyZW5jZXMgPSBzY3AucmVmZXJlbmNlczsKLQkJCQlmb3IgKGludCBpID0gMDsgaSA8IHJlZmVyZW5jZXMuc2l6ZSgpOyBpKyspIHsKLQkJCQkJcmVmZXJlbmNlID0gKFJlZmVyZW5jZSkgcmVmZXJlbmNlcy5lbGVtZW50QXQoaSk7Ci0JCQkJCWlmIChyZWZlcmVuY2UucmVmZXJlbmNlLm5hbWUuZXF1YWxzKHJlZk5hbWUpKSB7Ci0JCQkJCQlicmVhazsKLQkJCQkJfQotCQkJCQlyZWZlcmVuY2UgPSBudWxsOwotCQkJCX0KLQkJCQkvL2NoZWNrIGlmIHRoZXJlIGlzIGEgcmVmZXJlbmNlIGNvcnJlc3BvbmRpbmcgdG8gdGhlIHRhcmdldCBwcm9wZXJ0eQotCQkJCWlmIChyZWZlcmVuY2UgIT0gbnVsbCkgewotCQkJCQlpZiAobmV3RmlsdGVyICE9IG51bGwpIHsKLQkJCQkJCWlmICghbmV3RmlsdGVyLmVxdWFscyhjdXJyZW50UHJvcHMuZ2V0KGtleSkpKSB7Ci0JCQkJCQkJLy90aGUgZmlsdGVyIGRpZmZlcnMgdGhlIG9sZCBvbmUKLQkJCQkJCQlyZXN1bHQgPSByZXN1bHQgfHwgIXJlZmVyZW5jZS5kb1NhdGlzZnkobmV3RmlsdGVyKTsKLQkJCQkJCX0KLQkJCQkJfSBlbHNlIHsKLQkJCQkJCS8vdGhlIHRhcmdldCBmaWx0ZXIgaXMgcmVtb3ZlZC4gVXNpbmcgdGhlIGRlZmF1bHQgZmlsdGVyIHRvIGNoZWNrCi0JCQkJCQlpZiAocmVmZXJlbmNlLnBvbGljeSA9PSBDb21wb25lbnRSZWZlcmVuY2UuUE9MSUNZX1NUQVRJQykgewotCQkJCQkJCXJlc3VsdCA9IHJlc3VsdCB8fCAhcmVmZXJlbmNlLmRvU2F0aXNmeSgiKG9iamVjdENsYXNzPSIgKyByZWZlcmVuY2UucmVmZXJlbmNlLmludGVyZmFjZU5hbWUgKyAiKSIpOyAvLyROT04tTkxTLTEkIC8vJE5PTi1OTFMtMiQKLQkJCQkJCX0KLQkJCQkJfQotCQkJCX0KLQkJCX0KLQkJfQotCi0JCS8vbm93IGNoZWNrIHRoZSBuZXcgcHJvcGVydGllcyBpZiB0aGV5IGhhdmUgbmV3IHRhcmdldCBwcm9wZXJ0aWVzIGRlZmluZWQKLQkJa2V5cyA9IG5ld1Byb3BzLmtleXMoKTsKLQkJd2hpbGUgKGtleXMuaGFzTW9yZUVsZW1lbnRzKCkgJiYgIXJlc3VsdCkgewotCQkJU3RyaW5nIGtleSA9IChTdHJpbmcpIGtleXMubmV4dEVsZW1lbnQoKTsKLQkJCWlmIChrZXkuZW5kc1dpdGgoIi50YXJnZXQiKSAmJiAhY2hlY2tlZEZpbHRlcnMuY29udGFpbnMoa2V5KSkgeyAvLyROT04tTkxTLTEkCi0JCQkJUmVmZXJlbmNlIHJlZmVyZW5jZSA9IG51bGw7Ci0JCQkJU3RyaW5nIHJlZk5hbWUgPSBrZXkuc3Vic3RyaW5nKDAsIGtleS5sZW5ndGgoKSAtICIudGFyZ2V0Ii5sZW5ndGgoKSk7IC8vJE5PTi1OTFMtMSQKLQkJCQlWZWN0b3IgcmVmZXJlbmNlcyA9IHNjcC5yZWZlcmVuY2VzOwotCQkJCWZvciAoaW50IGkgPSAwOyBpIDwgcmVmZXJlbmNlcy5zaXplKCk7IGkrKykgewotCQkJCQlyZWZlcmVuY2UgPSAoUmVmZXJlbmNlKSByZWZlcmVuY2VzLmVsZW1lbnRBdChpKTsKLQkJCQkJaWYgKHJlZmVyZW5jZS5yZWZlcmVuY2UubmFtZS5lcXVhbHMocmVmTmFtZSkpIHsKLQkJCQkJCWJyZWFrOwotCQkJCQl9Ci0JCQkJCXJlZmVyZW5jZSA9IG51bGw7Ci0JCQkJfQotCQkJCS8vY2hlY2sgaWYgdGhlcmUgaXMgYSByZWZlcmVuY2UgY29ycmVzcG9uZGluZyB0byB0aGUgdGFyZ2V0IHByb3BlcnR5Ci0JCQkJaWYgKHJlZmVyZW5jZSAhPSBudWxsKSB7Ci0JCQkJCXJlc3VsdCA9IHJlc3VsdCB8fCAhcmVmZXJlbmNlLmRvU2F0aXNmeSgoU3RyaW5nKSBuZXdQcm9wcy5nZXQoa2V5KSk7Ci0JCQkJfQotCQkJfQotCQl9Ci0KLQkJaWYgKCFyZXN1bHQpIHsKLQkJCS8vZG8gcHJvY2VzcyBjb21wb25lbnQgbW9kaWZpY2F0aW9uIHZpYSB0aGUgSW5zdGFuY2VQcm9jZXNzCi0JCQl0cnkgewotCQkJCUluc3RhbmNlUHJvY2Vzcy5zdGF0aWNSZWYubW9kaWZ5Q29tcG9uZW50KHNjcCwgbmV3UHJvcHMpOwotCQkJfSBjYXRjaCAoQ29tcG9uZW50RXhjZXB0aW9uIGNlKSB7Ci0JCQkJLy9jb3VsZCBoYXBwZW4gaWYgdGhlIG1vZGlmeSBtZXRob2QgaXMgbm90IGZvdW5kCi0JCQkJcmVzdWx0ID0gdHJ1ZTsKLQkJCX0KLQkJfQotCQlyZXR1cm4gcmVzdWx0OwotCX0KLQotCXByaXZhdGUgdm9pZCBkaXNwb3NlQnVuZGxlcygpIHsKLQkJLy8gZGlzcG9zZSBBTEwgYnVuZGxlcwotCQlpZiAoYnVuZGxlVG9TZXJ2aWNlQ29tcG9uZW50cyAhPSBudWxsKSB7Ci0JCQlmb3IgKEVudW1lcmF0aW9uIGUgPSBidW5kbGVUb1NlcnZpY2VDb21wb25lbnRzLmtleXMoKTsgZS5oYXNNb3JlRWxlbWVudHMoKTspIHsKLQkJCQlCdW5kbGUgYnVuZGxlID0gKEJ1bmRsZSkgZS5uZXh0RWxlbWVudCgpOwotCQkJCXN0b3BwaW5nQnVuZGxlKGJ1bmRsZSk7Ci0JCQl9Ci0JCQlidW5kbGVUb1NlcnZpY2VDb21wb25lbnRzLmNsZWFyKCk7Ci0JCQlidW5kbGVUb1NlcnZpY2VDb21wb25lbnRzID0gbnVsbDsKLQkJfQotCX0KLQotCXZvaWQgc3RvcHBpbmdCdW5kbGUoQnVuZGxlIGJ1bmRsZSkgewotCQlpZiAoYnVuZGxlVG9TZXJ2aWNlQ29tcG9uZW50cyAhPSBudWxsKSB7Ci0JCQlWZWN0b3IgY29tcG9uZW50cyA9IChWZWN0b3IpIGJ1bmRsZVRvU2VydmljZUNvbXBvbmVudHMucmVtb3ZlKGJ1bmRsZSk7Ci0JCQkvLyBkaXNhYmxlIHRoZSBjb21wb25lbnRzIHdoaWNoIHRoZSBidW5kbGUgcHJvdmlkZXMKLQkJCWlmIChjb21wb25lbnRzICE9IG51bGwpIHsKLQkJCQlpZiAoQWN0aXZhdG9yLkRFQlVHKSB7Ci0JCQkJCVN0cmluZyBidW5kbGVOYW1lID0gYnVuZGxlLmdldFN5bWJvbGljTmFtZSgpOwotCQkJCQlidW5kbGVOYW1lID0gKGJ1bmRsZU5hbWUgPT0gbnVsbCB8fCAiIi5lcXVhbHMoYnVuZGxlTmFtZSkpID8gYnVuZGxlLmdldExvY2F0aW9uKCkgOiBidW5kbGVOYW1lOyAvLyROT04tTkxTLTEkCi0JCQkJCUFjdGl2YXRvci5sb2cuZGVidWcoIlNDUk1hbmFnZXIuc3RvcHBpbmdCdW5kbGUgOiAiICsgYnVuZGxlTmFtZSwgbnVsbCk7IC8vJE5PTi1OTFMtMSQKLQkJCQl9Ci0JCQkJcmVzb2x2ZXIuZGlzYWJsZUNvbXBvbmVudHMoY29tcG9uZW50cywgQ29tcG9uZW50Q29uc3RhbnRzLkRFQUNUSVZBVElPTl9SRUFTT05fQlVORExFX1NUT1BQRUQpOwotCi0JCQkJLy9zZXQgZGlzcG9zZWQgc3RhdGUgdG8gYWxsIGNvbXBvbmVudHMgc2luY2Ugc29tZSBvZiB0aGVtIG1pZ2h0IGJlIHN0aWxsIHJlZmVyZW5jZWQgYnkgdGhlIFNjclNlcnZpY2UKLQkJCQlmb3IgKGludCBpID0gMDsgaSA8IGNvbXBvbmVudHMuc2l6ZSgpOyBpKyspIHsKLQkJCQkJU2VydmljZUNvbXBvbmVudCBzYyA9IChTZXJ2aWNlQ29tcG9uZW50KSBjb21wb25lbnRzLmVsZW1lbnRBdChpKTsKLQkJCQkJc2Muc2V0U3RhdGUoQ29tcG9uZW50LlNUQVRFX0RJU1BPU0VEKTsKLQkJCQl9Ci0JCQkJaWYgKGJ1bmRsZVRvU2VydmljZUNvbXBvbmVudHMuc2l6ZSgpID09IDApIHsKLQkJCQkJaGFzUmVnaXN0ZXJlZFNlcnZpY2VMaXN0ZW5lciA9IGZhbHNlOwotCQkJCQlBY3RpdmF0b3IuYmMucmVtb3ZlU2VydmljZUxpc3RlbmVyKHRoaXMpOwotCQkJCX0KLQkJCX0KLQkJfQotCX0KLQotCXZvaWQgc3RhcnRlZEJ1bmRsZShCdW5kbGUgYnVuZGxlKSB7Ci0JCXN5bmNocm9uaXplZCAocHJvY2Vzc2luZ0J1bmRsZXMpIHsKLQkJCWlmIChwcm9jZXNzaW5nQnVuZGxlcy5nZXQoYnVuZGxlKSAhPSBudWxsKSB7Ci0JCQkJLy90aGUgYnVuZGxlIGlzIGFscmVhZHkgYmVpbmcgcHJvY2Vzc2VkCi0JCQkJcmV0dXJuOwotCQkJfQotCQkJcHJvY2Vzc2luZ0J1bmRsZXMucHV0KGJ1bmRsZSwgIiIpOyAvLyROT04tTkxTLTEkCi0JCX0KLQkJdHJ5IHsKLQkJCXN0YXJ0ZWRCdW5kbGUyKGJ1bmRsZSk7Ci0JCX0gZmluYWxseSB7Ci0JCQlwcm9jZXNzaW5nQnVuZGxlcy5yZW1vdmUoYnVuZGxlKTsKLQkJfQotCX0KLQotCXZvaWQgc3RhcnRlZEJ1bmRsZTIoQnVuZGxlIGJ1bmRsZSkgewotCQlsb25nIHN0YXJ0ID0gMGw7Ci0JCWlmIChBY3RpdmF0b3IuUEVSRikgewotCQkJc3RhcnQgPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKTsKLQkJfQotCQlpZiAoYnVuZGxlVG9TZXJ2aWNlQ29tcG9uZW50cyAhPSBudWxsICYmIGJ1bmRsZVRvU2VydmljZUNvbXBvbmVudHMuZ2V0KGJ1bmRsZSkgIT0gbnVsbCkgewotCQkJLy8gdGhlIGJ1bmRsZSBpcyBhbHJlYWR5IHByb2Nlc3NlZCAtIHNraXBwaW5nIGl0Ci0JCQlyZXR1cm47Ci0JCX0KLQotCQlTdHJpbmcgZHNIZWFkZXIgPSBudWxsOwotCQlEaWN0aW9uYXJ5IGFsbEhlYWRlcnMgPSBidW5kbGUuZ2V0SGVhZGVycygiIik7IC8vJE5PTi1OTFMtMSQKLQotCQlpZiAoISgoZHNIZWFkZXIgPSAoU3RyaW5nKSBhbGxIZWFkZXJzLmdldChDb21wb25lbnRDb25zdGFudHMuU0VSVklDRV9DT01QT05FTlQpKSAhPSBudWxsKSkgewotCQkJLy8gbm8gY29tcG9uZW50IGRlc2NyaXB0aW9ucyBpbiB0aGlzIGJ1bmRsZQotCQkJcmV0dXJuOwotCQl9Ci0KLQkJVmVjdG9yIGNvbXBvbmVudHMgPSBzdG9yYWdlLmxvYWRDb21wb25lbnREZWZpbml0aW9ucyhidW5kbGUsIGRzSGVhZGVyKTsKLQkJaWYgKGNvbXBvbmVudHMgIT0gbnVsbCAmJiAhY29tcG9uZW50cy5pc0VtcHR5KCkpIHsKLQkJCWlmICghaGFzUmVnaXN0ZXJlZFNlcnZpY2VMaXN0ZW5lcikgewotCQkJCWhhc1JlZ2lzdGVyZWRTZXJ2aWNlTGlzdGVuZXIgPSB0cnVlOwotCQkJCUFjdGl2YXRvci5iYy5hZGRTZXJ2aWNlTGlzdGVuZXIodGhpcyk7Ci0JCQkJcmVzb2x2ZXIuc3luY2hyb25pemVTZXJ2aWNlUmVmZXJlbmNlcygpOwotCQkJfQotCQkJaWYgKEFjdGl2YXRvci5QRVJGKSB7Ci0JCQkJc3RhcnQgPSBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKSAtIHN0YXJ0OwotCQkJCUFjdGl2YXRvci5sb2cuaW5mbygiW0RTIHBlcmZdIFRoZSBjb21wb25lbnRzIG9mIGJ1bmRsZSAiICsgYnVuZGxlICsgIiBhcmUgcGFyc2VkIGZvciAiICsgc3RhcnQgKyAibXMiKTsgLy8kTk9OLU5MUy0xJCAvLyROT04tTkxTLTIkIC8vJE5PTi1OTFMtMyQKLQkJCX0KLQkJCWlmIChidW5kbGVUb1NlcnZpY2VDb21wb25lbnRzID09IG51bGwpIHsKLQkJCQlzeW5jaHJvbml6ZWQgKHRoaXMpIHsKLQkJCQkJaWYgKGJ1bmRsZVRvU2VydmljZUNvbXBvbmVudHMgPT0gbnVsbCkgewotCQkJCQkJYnVuZGxlVG9TZXJ2aWNlQ29tcG9uZW50cyA9IG5ldyBIYXNodGFibGUoMTEpOwotCQkJCQl9Ci0JCQkJfQotCQkJfQotCi0JCQkvL2NoZWNrIHdoZXRoZXIgY29tcG9uZW50J3MgbmFtZXMgYXJlIHVuaXF1ZQotCQkJU2VydmljZUNvbXBvbmVudCBjb21wOwotCQkJU2VydmljZUNvbXBvbmVudCBjb21wMjsKLQkJCUwxOiBmb3IgKGludCBpID0gMDsgaSA8IGNvbXBvbmVudHMuc2l6ZSgpOyBpKyspIHsKLQkJCQljb21wID0gKFNlcnZpY2VDb21wb25lbnQpIGNvbXBvbmVudHMuZWxlbWVudEF0KGkpOwotCQkJCS8vY2hlY2sgaWYgdW5pcXVlIGluIGl0cyBidW5kbGUKLQkJCQlmb3IgKGludCBqID0gaSArIDE7IGogPCBjb21wb25lbnRzLnNpemUoKTsgaisrKSB7Ci0JCQkJCWNvbXAyID0gKFNlcnZpY2VDb21wb25lbnQpIGNvbXBvbmVudHMuZWxlbWVudEF0KGopOwotCQkJCQlpZiAoY29tcC5uYW1lLmVxdWFscyhjb21wMi5uYW1lKSkgewotCQkJCQkJQWN0aXZhdG9yLmxvZyhjb21wLmJjLCBMb2dTZXJ2aWNlLkxPR19FUlJPUiwgTkxTLmJpbmQoTWVzc2FnZXMuRk9VTkRfQ09NUE9ORU5UU19XSVRIX0RVUExJQ0FURURfTkFNRVMsIGNvbXApLCBudWxsKTsKLQkJCQkJCS8vcmVtb3Zpbmcgb25lIG9mIHRoZSBjb21wb25lbnRzCi0JCQkJCQljb21wb25lbnRzLnJlbW92ZShpKTsKLQkJCQkJCWktLTsKLQkJCQkJCWNvbnRpbnVlIEwxOwotCQkJCQl9Ci0JCQkJfQotCQkJCS8vY2hlY2sgaWYgdGhlIGNvbXBvbmVudCBpcyBnbG9iYWxseSB1bmlxdWUKLQkJCQlFbnVtZXJhdGlvbiBrZXlzID0gYnVuZGxlVG9TZXJ2aWNlQ29tcG9uZW50cy5rZXlzKCk7Ci0JCQkJd2hpbGUgKGtleXMuaGFzTW9yZUVsZW1lbnRzKCkpIHsKLQkJCQkJVmVjdG9yIGNvbXBvbmVudHMyID0gKFZlY3RvcikgYnVuZGxlVG9TZXJ2aWNlQ29tcG9uZW50cy5nZXQoa2V5cy5uZXh0RWxlbWVudCgpKTsKLQkJCQkJZm9yIChpbnQgaiA9IDA7IGogPCBjb21wb25lbnRzMi5zaXplKCk7IGorKykgewotCQkJCQkJY29tcDIgPSAoU2VydmljZUNvbXBvbmVudCkgY29tcG9uZW50czIuZWxlbWVudEF0KGopOwotCQkJCQkJaWYgKGNvbXAubmFtZS5lcXVhbHMoY29tcDIubmFtZSkpIHsKLQkJCQkJCQlBY3RpdmF0b3IubG9nKGNvbXAuYmMsIExvZ1NlcnZpY2UuTE9HX1dBUk5JTkcsIE5MUy5iaW5kKE1lc3NhZ2VzLkZPVU5EX0NPTVBPTkVOVFNfV0lUSF9EVVBMSUNBVEVEX05BTUVTMiwgY29tcCwgY29tcDIpLCBudWxsKTsKLQkJCQkJCX0KLQkJCQkJfQotCQkJCX0KLQotCQkJCWlmIChjb21wLmF1dG9lbmFibGUpIHsKLQkJCQkJY29tcC5lbmFibGVkID0gdHJ1ZTsKLQkJCQl9Ci0JCQl9Ci0JCQkvLyBzdG9yZSB0aGUgY29tcG9uZW50cyBpbiB0aGUgY2FjaGUKLQkJCWJ1bmRsZVRvU2VydmljZUNvbXBvbmVudHMucHV0KGJ1bmRsZSwgY29tcG9uZW50cy5jbG9uZSgpKTsKLQkJCWlmICh3b3JrVGhyZWFkICE9IG51bGwgJiYgd29ya1RocmVhZC5wcm9jZXNzaW5nVGhyZWFkID09IFRocmVhZC5jdXJyZW50VGhyZWFkKCkpIHsKLQkJCQkvL3dlIGFyZSBpbiB0aGUgcXVldWUgdGhyZWFkIGFscmVhZHkuIFByb2Nlc3Npbmcgc3luY2hyb25vdXNseSB0aGUgam9iCi0JCQkJcmVzb2x2ZXIuZW5hYmxlQ29tcG9uZW50cyhjb21wb25lbnRzKTsKLQkJCX0gZWxzZSB7Ci0JCQkJLy8gdGhpcyB3aWxsIGFsc28gcmVzb2x2ZSB0aGUgY29tcG9uZW50IGRlcGVuZGVuY2llcyEKLQkJCQllbnF1ZXVlV29yayh0aGlzLCBFTkFCTEVfQ09NUE9ORU5UUywgY29tcG9uZW50cywgZmFsc2UpOwotCQkJCXN5bmNocm9uaXplZCAoY29tcG9uZW50cykgewotCQkJCQlsb25nIHN0YXJ0VGltZSA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOwotCQkJCQl0cnkgewotCQkJCQkJd2hpbGUgKCFjb21wb25lbnRzLmlzRW1wdHkoKSAmJiAoU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCkgLSBzdGFydFRpbWUgPCBXb3JrVGhyZWFkLkJMT0NLX1RJTUVPVVQpKSB7Ci0JCQkJCQkJY29tcG9uZW50cy53YWl0KDEwMDApOwotCQkJCQkJfQotCQkJCQkJaWYgKFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpIC0gc3RhcnRUaW1lID49IFdvcmtUaHJlYWQuQkxPQ0tfVElNRU9VVCkgewotCQkJCQkJCUFjdGl2YXRvci5sb2cobnVsbCwgTG9nU2VydmljZS5MT0dfV0FSTklORywgTkxTLmJpbmQoTWVzc2FnZXMuVElNRU9VVF9SRUFDSEVEX0VOQUJMSU5HX0NPTVBPTkVOVFMsIGdldEJ1bmRsZU5hbWUoYnVuZGxlKSwgSW50ZWdlci50b1N0cmluZyhXb3JrVGhyZWFkLkJMT0NLX1RJTUVPVVQpKSwgbnVsbCk7Ci0JCQkJCQl9Ci0JCQkJCX0gY2F0Y2ggKEludGVycnVwdGVkRXhjZXB0aW9uIGUpIHsKLQkJCQkJCS8vZG8gbm90aGluZwotCQkJCQl9Ci0JCQkJfQotCQkJfQotCQl9Ci0JfQotCi0JcHJpdmF0ZSBTdHJpbmcgZ2V0QnVuZGxlTmFtZShCdW5kbGUgYikgewotCQlpZiAoYi5nZXRTeW1ib2xpY05hbWUoKSAhPSBudWxsKSB7Ci0JCQlyZXR1cm4gYi5nZXRTeW1ib2xpY05hbWUoKTsKLQkJfQotCQlyZXR1cm4gYi5nZXRMb2NhdGlvbigpOwotCX0KLQotCXB1YmxpYyB2b2lkIGVuYWJsZUNvbXBvbmVudChTdHJpbmcgbmFtZSwgQnVuZGxlIGJ1bmRsZSkgewotCQljaGFuZ2VDb21wb25lbnQobmFtZSwgYnVuZGxlLCB0cnVlKTsKLQl9Ci0KLQlwcml2YXRlIHZvaWQgY2hhbmdlQ29tcG9uZW50KFN0cmluZyBuYW1lLCBCdW5kbGUgYnVuZGxlLCBib29sZWFuIGVuYWJsZSkgewotCQlpZiAoYnVuZGxlVG9TZXJ2aWNlQ29tcG9uZW50cyA9PSBudWxsKSB7Ci0JCQkvLyBhbHJlYWR5IGRpc3Bvc2VkIQotCQkJcmV0dXJuOwotCQl9Ci0JCXRyeSB7Ci0JCQlWZWN0b3IgY29tcG9uZW50c1RvUHJvY2VzcyA9IG51bGw7Ci0KLQkJCWlmIChBY3RpdmF0b3IuREVCVUcpIHsKLQkJCQlTdHJpbmcgbWVzc2FnZSA9IChlbmFibGUgPyAiU0NSTWFuYWdlci5lbmFibGVDb21wb25lbnQoKTogIiA6ICJTQ1JNYW5hZ2VyLmRpc2FibGVDb21wb25lbnQoKTogIikuY29uY2F0KG5hbWUgIT0gbnVsbCA/IG5hbWUgOiAiKmFsbCoiKSArICIgZnJvbSBidW5kbGUgIiArIGdldEJ1bmRsZU5hbWUoYnVuZGxlKTsgLy8kTk9OLU5MUy0xJCAvLyROT04tTkxTLTIkIC8vJE5PTi1OTFMtMyQgLy8kTk9OLU5MUy00JAotCQkJCUFjdGl2YXRvci5sb2cuZGVidWcobWVzc2FnZSwgbnVsbCk7Ci0JCQl9Ci0JCQlWZWN0b3IgYnVuZGxlQ29tcG9uZW50cyA9IChWZWN0b3IpIGJ1bmRsZVRvU2VydmljZUNvbXBvbmVudHMuZ2V0KGJ1bmRsZSk7Ci0JCQlpZiAoYnVuZGxlQ29tcG9uZW50cyAhPSBudWxsKSB7Ci0JCQkJaWYgKG5hbWUgIT0gbnVsbCkgewotCQkJCQlib29sZWFuIGZvdW5kID0gZmFsc2U7Ci0JCQkJCWZvciAoaW50IGkgPSAwOyBpIDwgYnVuZGxlQ29tcG9uZW50cy5zaXplKCk7IGkrKykgewotCQkJCQkJU2VydmljZUNvbXBvbmVudCBjb21wb25lbnQgPSAoU2VydmljZUNvbXBvbmVudCkgYnVuZGxlQ29tcG9uZW50cy5lbGVtZW50QXQoaSk7Ci0JCQkJCQlpZiAoY29tcG9uZW50Lm5hbWUuZXF1YWxzKG5hbWUpKSB7Ci0JCQkJCQkJZm91bmQgPSB0cnVlOwotCQkJCQkJCWlmIChjb21wb25lbnQuZW5hYmxlZCAhPSBlbmFibGUpIHsKLQkJCQkJCQkJY29tcG9uZW50LmVuYWJsZWQgPSBlbmFibGU7Ci0JCQkJCQkJCWNvbXBvbmVudC5zZXRTdGF0ZShlbmFibGUgPyBDb21wb25lbnQuU1RBVEVfRU5BQkxJTkcgOiBDb21wb25lbnQuU1RBVEVfRElTQUJMSU5HKTsKLQkJCQkJCQkJY29tcG9uZW50c1RvUHJvY2VzcyA9IG5ldyBWZWN0b3IoMik7Ci0JCQkJCQkJCWNvbXBvbmVudHNUb1Byb2Nlc3MuYWRkRWxlbWVudChjb21wb25lbnQpOwotCQkJCQkJCQlicmVhazsKLQkJCQkJCQl9Ci0JCQkJCQl9Ci0JCQkJCX0KLQkJCQkJaWYgKCFmb3VuZCkgewotCQkJCQkJdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihOTFMuYmluZChNZXNzYWdlcy5DT01QT05FTlRfTk9UX0ZPVU5ELCBuYW1lLCBidW5kbGUpKTsKLQkJCQkJfQotCQkJCX0gZWxzZSB7Ci0JCQkJCWlmIChlbmFibGUpIHsKLQkJCQkJCS8vIHByb2Nlc3NpbmcgbnVsbCBwYXJhbWV0ZXIgc2hvdWxkIGJlIGRvbmUgb25seSB3aGVuCi0JCQkJCQkvLyBlbmFibGluZyBjb21wb25lbnRzCi0JCQkJCQlTZXJ2aWNlQ29tcG9uZW50IHNjOwotCQkJCQkJY29tcG9uZW50c1RvUHJvY2VzcyA9IG5ldyBWZWN0b3IoKTsKLQkJCQkJCWZvciAoaW50IGkgPSAwOyBpIDwgYnVuZGxlQ29tcG9uZW50cy5zaXplKCk7IGkrKykgewotCQkJCQkJCXNjID0gKChTZXJ2aWNlQ29tcG9uZW50KSBidW5kbGVDb21wb25lbnRzLmVsZW1lbnRBdChpKSk7Ci0JCQkJCQkJaWYgKCFzYy5lbmFibGVkKSB7Ci0JCQkJCQkJCWNvbXBvbmVudHNUb1Byb2Nlc3MuYWRkRWxlbWVudChzYyk7Ci0JCQkJCQkJCXNjLmVuYWJsZWQgPSBlbmFibGU7Ci0JCQkJCQkJCXNjLnNldFN0YXRlKENvbXBvbmVudC5TVEFURV9FTkFCTElORyk7Ci0JCQkJCQkJfQotCQkJCQkJfQotCQkJCQl9Ci0JCQkJfQotCi0JCQl9Ci0JCQkvLyBwdWJsaXNoIHRvIHJlc29sdmVyIHRoZSBsaXN0IG9mIFNDcyB0byBlbmFibGUKLQkJCWlmIChjb21wb25lbnRzVG9Qcm9jZXNzICE9IG51bGwgJiYgIWNvbXBvbmVudHNUb1Byb2Nlc3MuaXNFbXB0eSgpKSB7Ci0JCQkJaWYgKGVuYWJsZSkgewotCQkJCQllbnF1ZXVlV29yayh0aGlzLCBFTkFCTEVfQ09NUE9ORU5UUywgY29tcG9uZW50c1RvUHJvY2VzcywgQWN0aXZhdG9yLnNlY3VyaXR5KTsKLQkJCQl9IGVsc2UgewotCQkJCQllbnF1ZXVlV29yayh0aGlzLCBESVNBQkxFX0NPTVBPTkVOVFMsIGNvbXBvbmVudHNUb1Byb2Nlc3MsIEFjdGl2YXRvci5zZWN1cml0eSk7Ci0JCQkJfQotCQkJfQotCQl9IGNhdGNoIChJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWFlKSB7Ci0JCQl0aHJvdyBpYWU7Ci0JCX0gY2F0Y2ggKFRocm93YWJsZSBlKSB7Ci0JCQlBY3RpdmF0b3IubG9nKG51bGwsIExvZ1NlcnZpY2UuTE9HX0VSUk9SLCBNZXNzYWdlcy5VTkVYUEVDVEVEX0VYQ0VQVElPTiwgZSk7Ci0JCX0KLQl9Ci0KLQkvKioKLQkgKiBRdWV1ZWRKb2IgcmVwcmVzZW50cyB0aGUgaXRlbXMgcGxhY2VkIG9uIHRoZSBhc3luY2ggZGlzcGF0Y2ggcXVldWUuCi0JICovCi0Jc3RhdGljIGNsYXNzIFF1ZXVlZEpvYiB7Ci0JCWZpbmFsIFdvcmtQZXJmb3JtZXIgcGVyZm9ybWVyOwotCQkvKiogdGhlIHJlcXVpcmVkIHR5cGUgb2YgYWN0aW9uIHRvIGRvICovCi0JCWZpbmFsIGludCBhY3Rpb25UeXBlOwotCQkvKiogd29yayBpbnB1dCBkYXRhIHRvIGJlIHBlcmZvcm1lZCAqLwotCQlmaW5hbCBPYmplY3Qgd29ya1RvRG87Ci0KLQkJLyoqCi0JCSAqIENvbnN0cnVjdG9yIGZvciB3b3JrIHF1ZXVlIGl0ZW0KLQkJICogCi0JCSAqIEBwYXJhbSBkCi0JCSAqICAgICAgICAgICAgRGlzcGF0Y2hlciBmb3IgdGhpcyBpdGVtCi0JCSAqIEBwYXJhbSBhCi0JCSAqICAgICAgICAgICAgQWN0aW9uIGZvciB0aGlzIGl0ZW0KLQkJICogQHBhcmFtIG8KLQkJICogICAgICAgICAgICBPYmplY3QgZm9yIHRoaXMgaXRlbQotCQkgKi8KLQkJUXVldWVkSm9iKFdvcmtQZXJmb3JtZXIgZCwgaW50IGEsIE9iamVjdCBvKSB7Ci0JCQlwZXJmb3JtZXIgPSBkOwotCQkJYWN0aW9uVHlwZSA9IGE7Ci0JCQl3b3JrVG9EbyA9IG87Ci0JCX0KLQotCQl2b2lkIGRpc3BhdGNoKCkgewotCQkJdHJ5IHsKLQkJCQkvKiBDYWxsIHRoZSBXb3JrUGVyZm9ybWVyIHRvIHByb2Nlc3MgdGhlIHdvcmsuICovCi0JCQkJcGVyZm9ybWVyLnBlcmZvcm1Xb3JrKGFjdGlvblR5cGUsIHdvcmtUb0RvKTsKLQkJCX0gY2F0Y2ggKFRocm93YWJsZSB0KSB7Ci0JCQkJQWN0aXZhdG9yLmxvZyhudWxsLCBMb2dTZXJ2aWNlLkxPR19FUlJPUiwgTWVzc2FnZXMuRVJST1JfRElTUEFUQ0hJTkdfV09SSywgdCk7Ci0JCQl9Ci0JCX0KLQotCQlwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewotCQkJcmV0dXJuICJbUXVldWVkSm9iXSBXb3JrUGVyZm9ybWVyOiAiICsgcGVyZm9ybWVyICsgIjsgYWN0aW9uVHlwZSAiICsgYWN0aW9uVHlwZTsgLy8kTk9OLU5MUy0xJCAvLyROT04tTkxTLTIkCi0JCX0KLQl9Ci0KLQkvLyAtLSBiZWdpbiBlbmFibGUvZGlzYWJsZSBjb21wb25lbnRzCi0JLyoqCi0JICogZGlzYWJsZUNvbXBvbmVudCAtIFRoZSBzcGVjaWZpZWQgY29tcG9uZW50IG5hbWUgbXVzdCBiZSBpbiB0aGUgc2FtZQotCSAqIGJ1bmRsZSBhcyB0aGlzIGNvbXBvbmVudC4gQ2FsbGVkIGJ5IFNDIGNvbXBvbmVudENvbnRleHQgbWV0aG9kCi0JICogCi0JICogQHBhcmFtIG5hbWUKLQkgKiAgICAgICAgICAgIFRoZSBuYW1lIG9mIGEgY29tcG9uZW50IHRvIGRpc2FibGUKLQkgKiBAcGFyYW0gYnVuZGxlCi0JICogICAgICAgICAgICBUaGUgYnVuZGxlIHdoaWNoIGNvbnRhaW5zIHRoZSBTZXJ2aWNlIENvbXBvbmVudCB0byBiZSBkaXNhYmxlZAotCSAqLwotCXB1YmxpYyB2b2lkIGRpc2FibGVDb21wb25lbnQoU3RyaW5nIG5hbWUsIEJ1bmRsZSBidW5kbGUpIHsKLQkJY2hhbmdlQ29tcG9uZW50KG5hbWUsIGJ1bmRsZSwgZmFsc2UpOwotCX0KLQotCS8qCi0JICogKG5vbi1KYXZhZG9jKQotCSAqIAotCSAqIEBzZWUgb3JnLmVjbGlwc2UuZXF1aW5veC5pbnRlcm5hbC5kcy51dGlsLldvcmtQZXJmb3JtZXIjcGVyZm9ybVdvcmsoaW50LAotCSAqICAgICAgamF2YS5sYW5nLk9iamVjdCkKLQkgKi8KLQlwdWJsaWMgdm9pZCBwZXJmb3JtV29yayhpbnQgd29ya0FjdGlvbiwgT2JqZWN0IHdvcmtPYmplY3QpIHsKLQkJaWYgKHdvcmtBY3Rpb24gPT0gRU5BQkxFX0NPTVBPTkVOVFMpIHsKLQkJCXJlc29sdmVyLmVuYWJsZUNvbXBvbmVudHMoKFZlY3Rvcikgd29ya09iamVjdCk7Ci0JCQkvL25vdGlmeSB0aGF0IHRoZSBjb21wb25lbnQgZW5hYmxpbmcgaGFzIGZpbmlzaGVkCi0JCQlzeW5jaHJvbml6ZWQgKHdvcmtPYmplY3QpIHsKLQkJCQkoKFZlY3Rvcikgd29ya09iamVjdCkuY2xlYXIoKTsKLQkJCQl3b3JrT2JqZWN0Lm5vdGlmeSgpOwotCQkJfQotCQl9IGVsc2UgaWYgKHdvcmtBY3Rpb24gPT0gRElTQUJMRV9DT01QT05FTlRTKSB7Ci0JCQlyZXNvbHZlci5kaXNhYmxlQ29tcG9uZW50cygoVmVjdG9yKSB3b3JrT2JqZWN0LCBDb21wb25lbnRDb25zdGFudHMuREVBQ1RJVkFUSU9OX1JFQVNPTl9ESVNBQkxFRCk7Ci0JCX0KLQl9Ci0KLQlwcm90ZWN0ZWQgdm9pZCBjb25maWdBZG1pblJlZ2lzdGVyZWQoQ29uZmlndXJhdGlvbkFkbWluIGNvbmZpZ0FkbWluLCBTZXJ2aWNlUmVmZXJlbmNlIGNhUmVmZXJlbmNlKSB7Ci0JCWlmIChidW5kbGVUb1NlcnZpY2VDb21wb25lbnRzID09IG51bGwgfHwgYnVuZGxlVG9TZXJ2aWNlQ29tcG9uZW50cy5pc0VtcHR5KCkpIHsKLQkJCS8vIG5vIGNvbXBvbmVudHMgZm91bmQgdGlsbCBub3cKLQkJCXJldHVybjsKLQkJfQotCQlWZWN0b3IgdG9Qcm9jZXNzID0gbmV3IFZlY3RvcigxKTsKLQkJQ29uZmlndXJhdGlvbltdIGNvbmZpZ3MgPSBudWxsOwotCQl0cnkgewotCQkJY29uZmlncyA9IGNvbmZpZ0FkbWluLmxpc3RDb25maWd1cmF0aW9ucyhudWxsKTsKLQkJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKLQkJCUFjdGl2YXRvci5sb2cobnVsbCwgTG9nU2VydmljZS5MT0dfRVJST1IsIE1lc3NhZ2VzLkVSUk9SX0xJU1RJTkdfQ09ORklHVVJBVElPTlMsIGUpOwotCQl9Ci0JCWlmIChjb25maWdzID09IG51bGwgfHwgY29uZmlncy5sZW5ndGggPT0gMCkgewotCQkJLy9ubyBjb25maWd1cmF0aW9ucyBmb3VuZAotCQkJcmV0dXJuOwotCQl9Ci0JCS8vcHJvY2VzcyBhbGwgY29tcG9uZW50cyB0byBmaW5kIHN1Y2ggdGhhdCBuZWVkIHRvIGJlIGV2YWx1YXRlZCB3aGVuIENvbmZpZ0FkbWluIGlzIGF2YWlsYWJsZQotCQlmb3IgKEVudW1lcmF0aW9uIGtleXMgPSBidW5kbGVUb1NlcnZpY2VDb21wb25lbnRzLmtleXMoKTsga2V5cy5oYXNNb3JlRWxlbWVudHMoKTspIHsKLQkJCVZlY3RvciBidW5kbGVDb21wcyA9IChWZWN0b3IpIGJ1bmRsZVRvU2VydmljZUNvbXBvbmVudHMuZ2V0KGtleXMubmV4dEVsZW1lbnQoKSk7Ci0JCQkvLyBidW5kbGVDb21wcyBtYXkgYmUgbnVsbCBzaW5jZSBidW5kbGVUb1NlcnZpY2VDb21wb25lbnRzCi0JCQkvLyBtYXkgaGF2ZSBiZWVuIG1vZGlmaWVkIGJ5IGFub3RoZXIgdGhyZWFkCi0JCQlpZiAoYnVuZGxlQ29tcHMgIT0gbnVsbCkgewotCQkJCWZvciAoaW50IGkgPSAwOyBpIDwgYnVuZGxlQ29tcHMuc2l6ZSgpOyBpKyspIHsKLQkJCQkJU2VydmljZUNvbXBvbmVudCBzYyA9IChTZXJ2aWNlQ29tcG9uZW50KSBidW5kbGVDb21wcy5lbGVtZW50QXQoaSk7Ci0JCQkJCWlmIChzYy5nZXRDb25maWd1cmF0aW9uUG9saWN5KCkgPT0gU2VydmljZUNvbXBvbmVudC5DT05GX1BPTElDWV9JR05PUkUpIHsKLQkJCQkJCS8vc2tpcCBwcm9jZXNzaW5nIG9mIHRoaXMgY29tcG9uZW50IC0gaXQgaXMgbm90IGludGVyZXN0ZWQgaW4gY29uZmlndXJhdGlvbiBjaGFuZ2VzCi0JCQkJCQljb250aW51ZTsKLQkJCQkJfQotCQkJCQlpZiAoc2MuZW5hYmxlZCkgewotCQkJCQkJU3RyaW5nIGNvbXBvbmVudFBJRCA9IHNjLmdldENvbmZpZ3VyYXRpb25QSUQoKTsKLQkJCQkJCWZvciAoaW50IGogPSAwOyBqIDwgY29uZmlncy5sZW5ndGg7IGorKykgewotCQkJCQkJCWlmIChjb25maWdzW2pdLmdldFBpZCgpLmVxdWFscyhjb21wb25lbnRQSUQpIHx8IGNvbXBvbmVudFBJRC5lcXVhbHMoY29uZmlnc1tqXS5nZXRGYWN0b3J5UGlkKCkpKSB7Ci0JCQkJCQkJCWlmIChjb21wb25lbnRQSUQuZXF1YWxzKGNvbmZpZ3Nbal0uZ2V0RmFjdG9yeVBpZCgpKSAmJiBzYy5mYWN0b3J5ICE9IG51bGwpIHsKLQkJCQkJCQkJCUFjdGl2YXRvci5sb2coc2MuYmMsIExvZ1NlcnZpY2UuTE9HX0VSUk9SLCBOTFMuYmluZChNZXNzYWdlcy5GQUNUT1JZX0NPTkZfTk9UX0FQUExJQ0FCTEVfRk9SX0NPTVBPTkVOVF9GQUNUT1JZLCBzYy5uYW1lKSwgbnVsbCk7Ci0JCQkJCQkJCQlicmVhazsKLQkJCQkJCQkJfQotCQkJCQkJCQkvL2ZvdW5kIGEgY29uZmlndXJhdGlvbiBmb3IgdGhpcyBjb21wb25lbnQKLQkJCQkJCQkJaWYgKHNjLmNvbXBvbmVudFByb3BzID09IG51bGwgfHwgc2MuY29tcG9uZW50UHJvcHMuc2l6ZSgpID09IDApIHsKLQkJCQkJCQkJCWlmIChzYy5nZXRDb25maWd1cmF0aW9uUG9saWN5KCkgPT0gU2VydmljZUNvbXBvbmVudC5DT05GX1BPTElDWV9SRVFVSVJFKSB7Ci0JCQkJCQkJCQkJLy90aGUgY29tcG9uZW50IGlzIG5vdCB5ZXQgbWFwcGVkIGJlY2F1c2UgaXQgaXMgcmVxdWlyaW5nIGNvbmZpZ3VyYXRpb24uIFRyeSB0byBwcm9jZXNzIGl0Ci0JCQkJCQkJCQkJdG9Qcm9jZXNzLmFkZEVsZW1lbnQoc2MpOwotCQkJCQkJCQkJfQotCQkJCQkJCQl9IGVsc2UgewotCQkJCQkJCQkJLy9wcm9jZXNzIHRoZSBjb21wb25lbnQgY29uZmlndXJhdGlvbnMgYW5kIGV2ZW50dWFsbHkgbW9kaWZ5IG9yIHJlc3RhcnQgdGhlbQotCQkJCQkJCQkJQ29uZmlndXJhdGlvbkV2ZW50IGNlID0gbmV3IENvbmZpZ3VyYXRpb25FdmVudChjYVJlZmVyZW5jZSwgQ29uZmlndXJhdGlvbkV2ZW50LkNNX1VQREFURUQsIGNvbmZpZ3Nbal0uZ2V0RmFjdG9yeVBpZCgpLCBjb25maWdzW2pdLmdldFBpZCgpKTsKLQkJCQkJCQkJCWNvbmZpZ3VyYXRpb25FdmVudChjZSk7Ci0JCQkJCQkJCX0KLQkJCQkJCQkJYnJlYWs7Ci0JCQkJCQkJfQotCQkJCQkJfQotCQkJCQl9Ci0JCQkJfQotCQkJfQotCQl9Ci0JCWlmICh0b1Byb2Nlc3Muc2l6ZSgpID4gMCkgewotCQkJZW5xdWV1ZVdvcmsodGhpcywgRU5BQkxFX0NPTVBPTkVOVFMsIHRvUHJvY2VzcywgZmFsc2UpOwotCQl9Ci0JfQotCi0JcHVibGljIENvbXBvbmVudFtdIGdldENvbXBvbmVudHMoKSB7Ci0JCWlmIChidW5kbGVUb1NlcnZpY2VDb21wb25lbnRzID09IG51bGwgfHwgYnVuZGxlVG9TZXJ2aWNlQ29tcG9uZW50cy5pc0VtcHR5KCkpIHsKLQkJCS8vIG5vIGNvbXBvbmVudHMgZm91bmQgdGlsbCBub3cKLQkJCXJldHVybiBudWxsOwotCQl9Ci0JCVZlY3RvciByZXN1bHQgPSBuZXcgVmVjdG9yKCk7Ci0JCUVudW1lcmF0aW9uIGVuID0gYnVuZGxlVG9TZXJ2aWNlQ29tcG9uZW50cy5rZXlzKCk7Ci0JCXdoaWxlIChlbi5oYXNNb3JlRWxlbWVudHMoKSkgewotCQkJQnVuZGxlIGIgPSAoQnVuZGxlKSBlbi5uZXh0RWxlbWVudCgpOwotCQkJVmVjdG9yIHNlcnZpY2VDb21wb25lbnRzID0gKFZlY3RvcikgYnVuZGxlVG9TZXJ2aWNlQ29tcG9uZW50cy5nZXQoYik7Ci0JCQlmb3IgKGludCBpID0gMDsgaSA8IHNlcnZpY2VDb21wb25lbnRzLnNpemUoKTsgaSsrKSB7Ci0JCQkJU2VydmljZUNvbXBvbmVudCBzYyA9IChTZXJ2aWNlQ29tcG9uZW50KSBzZXJ2aWNlQ29tcG9uZW50cy5lbGVtZW50QXQoaSk7Ci0JCQkJaWYgKHNjLmNvbXBvbmVudFByb3BzICE9IG51bGwgJiYgIXNjLmNvbXBvbmVudFByb3BzLmlzRW1wdHkoKSkgewotCQkJCQkvL2FkZCB0aGUgY3JlYXRlZCBydW50aW1lIGNvbXBvbmVudHMgcHJvcHMKLQkJCQkJcmVzdWx0LmFkZEFsbChzYy5jb21wb25lbnRQcm9wcyk7Ci0JCQkJfSBlbHNlIHsKLQkJCQkJLy9hZGQgdGhlIGRlY2xhcmVkIGNvbXBvbmVudCBpdHNlbGYKLQkJCQkJcmVzdWx0LmFkZChzYyk7Ci0JCQkJfQotCQkJfQotCQl9Ci0JCWlmICghcmVzdWx0LmlzRW1wdHkoKSkgewotCQkJQ29tcG9uZW50W10gcmVzID0gbmV3IENvbXBvbmVudFtyZXN1bHQuc2l6ZSgpXTsKLQkJCXJlc3VsdC5jb3B5SW50byhyZXMpOwotCQkJcmV0dXJuIHJlczsKLQkJfQotCQlyZXR1cm4gbnVsbDsKLQl9Ci0KLQlwdWJsaWMgQ29tcG9uZW50W10gZ2V0Q29tcG9uZW50cyhCdW5kbGUgYnVuZGxlKSB7Ci0JCWlmIChidW5kbGVUb1NlcnZpY2VDb21wb25lbnRzID09IG51bGwgfHwgYnVuZGxlVG9TZXJ2aWNlQ29tcG9uZW50cy5pc0VtcHR5KCkpIHsKLQkJCS8vIG5vIGNvbXBvbmVudHMgZm91bmQgdGlsbCBub3cKLQkJCXJldHVybiBudWxsOwotCQl9Ci0JCVZlY3RvciBzZXJ2aWNlQ29tcG9uZW50cyA9IChWZWN0b3IpIGJ1bmRsZVRvU2VydmljZUNvbXBvbmVudHMuZ2V0KGJ1bmRsZSk7Ci0JCWlmIChzZXJ2aWNlQ29tcG9uZW50cyAhPSBudWxsKSB7Ci0JCQlWZWN0b3IgcmVzdWx0ID0gbmV3IFZlY3RvcigpOwotCQkJZm9yIChpbnQgaSA9IDA7IGkgPCBzZXJ2aWNlQ29tcG9uZW50cy5zaXplKCk7IGkrKykgewotCQkJCVNlcnZpY2VDb21wb25lbnQgc2MgPSAoU2VydmljZUNvbXBvbmVudCkgc2VydmljZUNvbXBvbmVudHMuZWxlbWVudEF0KGkpOwotCQkJCWlmIChzYy5jb21wb25lbnRQcm9wcyAhPSBudWxsICYmICFzYy5jb21wb25lbnRQcm9wcy5pc0VtcHR5KCkpIHsKLQkJCQkJLy9hZGQgdGhlIGNyZWF0ZWQgcnVudGltZSBjb21wb25lbnRzIHByb3BzCi0JCQkJCXJlc3VsdC5hZGRBbGwoc2MuY29tcG9uZW50UHJvcHMpOwotCQkJCX0gZWxzZSB7Ci0JCQkJCS8vYWRkIHRoZSBkZWNsYXJlZCBjb21wb25lbnQgaXRzZWxmCi0JCQkJCXJlc3VsdC5hZGQoc2MpOwotCQkJCX0KLQkJCX0KLQkJCWlmICghcmVzdWx0LmlzRW1wdHkoKSkgewotCQkJCUNvbXBvbmVudFtdIHJlcyA9IG5ldyBDb21wb25lbnRbcmVzdWx0LnNpemUoKV07Ci0JCQkJcmVzdWx0LmNvcHlJbnRvKHJlcyk7Ci0JCQkJcmV0dXJuIHJlczsKLQkJCX0KLQkJfQotCQlyZXR1cm4gbnVsbDsKLQl9Ci0KLQlwdWJsaWMgQ29tcG9uZW50W10gZ2V0Q29tcG9uZW50cyhTdHJpbmcgY29tcG9uZW50TmFtZSkgewotCQlpZiAoYnVuZGxlVG9TZXJ2aWNlQ29tcG9uZW50cyA9PSBudWxsIHx8IGJ1bmRsZVRvU2VydmljZUNvbXBvbmVudHMuaXNFbXB0eSgpKSB7Ci0JCQkvLyBubyBjb21wb25lbnRzIGZvdW5kIHRpbGwgbm93Ci0JCQlyZXR1cm4gbnVsbDsKLQkJfQotCQlWZWN0b3IgcmVzdWx0ID0gbmV3IFZlY3RvcigpOwotCQlFbnVtZXJhdGlvbiBlbiA9IGJ1bmRsZVRvU2VydmljZUNvbXBvbmVudHMua2V5cygpOwotCQl3aGlsZSAoZW4uaGFzTW9yZUVsZW1lbnRzKCkpIHsKLQkJCUJ1bmRsZSBiID0gKEJ1bmRsZSkgZW4ubmV4dEVsZW1lbnQoKTsKLQkJCVZlY3RvciBzZXJ2aWNlQ29tcG9uZW50cyA9IChWZWN0b3IpIGJ1bmRsZVRvU2VydmljZUNvbXBvbmVudHMuZ2V0KGIpOwotCQkJZm9yIChpbnQgaSA9IDA7IGkgPCBzZXJ2aWNlQ29tcG9uZW50cy5zaXplKCk7IGkrKykgewotCQkJCVNlcnZpY2VDb21wb25lbnQgc2MgPSAoU2VydmljZUNvbXBvbmVudCkgc2VydmljZUNvbXBvbmVudHMuZWxlbWVudEF0KGkpOwotCQkJCWlmIChzYy5nZXROYW1lKCkuZXF1YWxzKGNvbXBvbmVudE5hbWUpKSB7Ci0JCQkJCWlmIChzYy5jb21wb25lbnRQcm9wcyAhPSBudWxsICYmICFzYy5jb21wb25lbnRQcm9wcy5pc0VtcHR5KCkpIHsKLQkJCQkJCS8vIGFkZCB0aGUgY3JlYXRlZCBydW50aW1lIGNvbXBvbmVudHMgcHJvcHMKLQkJCQkJCXJlc3VsdC5hZGRBbGwoc2MuY29tcG9uZW50UHJvcHMpOwotCQkJCQl9IGVsc2UgewotCQkJCQkJLy8gYWRkIHRoZSBkZWNsYXJlZCBjb21wb25lbnQgaXRzZWxmCi0JCQkJCQlyZXN1bHQuYWRkKHNjKTsKLQkJCQkJfQotCQkJCQlicmVhazsKLQkJCQl9Ci0JCQl9Ci0JCX0KLQkJaWYgKCFyZXN1bHQuaXNFbXB0eSgpKSB7Ci0JCQlDb21wb25lbnRbXSByZXMgPSBuZXcgQ29tcG9uZW50W3Jlc3VsdC5zaXplKCldOwotCQkJcmVzdWx0LmNvcHlJbnRvKHJlcyk7Ci0JCQlyZXR1cm4gcmVzOwotCQl9Ci0JCXJldHVybiBudWxsOwotCX0KLQotfQpkaWZmIC0tZ2l0IGEvYnVuZGxlcy9vcmcuZWNsaXBzZS5lcXVpbm94LmRzL3NyYy9vcmcvZWNsaXBzZS9lcXVpbm94L2ludGVybmFsL2RzL1NDUlV0aWwuamF2YSBiL2J1bmRsZXMvb3JnLmVjbGlwc2UuZXF1aW5veC5kcy9zcmMvb3JnL2VjbGlwc2UvZXF1aW5veC9pbnRlcm5hbC9kcy9TQ1JVdGlsLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDA1ZGFkNWEuLjAwMDAwMDAKLS0tIGEvYnVuZGxlcy9vcmcuZWNsaXBzZS5lcXVpbm94LmRzL3NyYy9vcmcvZWNsaXBzZS9lcXVpbm94L2ludGVybmFsL2RzL1NDUlV0aWwuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDI3OSArMCwwIEBACi0vKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgotICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDEwIGJ5IFByb1N5c3QgU29mdHdhcmUgR21iSAotICogaHR0cDovL3d3dy5wcm9zeXN0LmNvbQotICogQWxsIHJpZ2h0cyByZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscwotICogYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2MS4wCi0gKiB3aGljaCBhY2NvbXBhbmllcyB0aGlzIGRpc3RyaWJ1dGlvbiwgYW5kIGlzIGF2YWlsYWJsZSBhdAotICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtdjEwLmh0bWwKLSAqCi0gKiBDb250cmlidXRvcnM6Ci0gKiAgICBQcm9TeXN0IFNvZnR3YXJlIEdtYkggLSBpbml0aWFsIEFQSSBhbmQgaW1wbGVtZW50YXRpb24KLSAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwotcGFja2FnZSBvcmcuZWNsaXBzZS5lcXVpbm94LmludGVybmFsLmRzOwotCi1pbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuTWV0aG9kOwotaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0Lk1vZGlmaWVyOwotaW1wb3J0IGphdmEudXRpbC5EaWN0aW9uYXJ5OwotaW1wb3J0IGphdmEudXRpbC5FbnVtZXJhdGlvbjsKLWltcG9ydCBvcmcuYXBhY2hlLmZlbGl4LnNjci5Db21wb25lbnQ7Ci1pbXBvcnQgb3JnLmVjbGlwc2UuZXF1aW5veC5pbnRlcm5hbC51dGlsLnBvb2wuT2JqZWN0Q3JlYXRvcjsKLWltcG9ydCBvcmcuZWNsaXBzZS5lcXVpbm94LmludGVybmFsLnV0aWwucG9vbC5PYmplY3RQb29sOwotCi0vKioKLSAqIEhvbGRzIHVzZWZ1bCBtZXRob2RzIHVzZWQgYnkgU0NSLgotICogCi0gKiBAYXV0aG9yIFZhbGVudGluIFZhbGNoZXYKLSAqIEBhdXRob3IgU3RveWFuIEJvc2hldgotICogQGF1dGhvciBQYXZsaW4gRG9icmV2Ci0gKi8KLQotcHVibGljIGZpbmFsIGNsYXNzIFNDUlV0aWwgaW1wbGVtZW50cyBPYmplY3RDcmVhdG9yIHsKLQotCXByaXZhdGUgc3RhdGljIE9iamVjdFBvb2wgb2JqZWN0QXJyYXlQb29sOwotCi0Jc3RhdGljIHsKLQkJU0NSVXRpbCB1ID0gbmV3IFNDUlV0aWwoKTsKLQkJLy8gRklYTUU6IHVzZSBzb21lIGtpbmQgb2YgbG9nZ2luZyBmb3IgdGhlIG9iamVjdCBwb29sIHRvIGRldGVybWluZQotCQkvLyB0aGUgb3B0aW1hbCBzb2x1dGlvbiEKLQkJb2JqZWN0QXJyYXlQb29sID0gbmV3IE9iamVjdFBvb2wodSwgMTAsIDIpOwotCX0KLQotCXByaXZhdGUgU0NSVXRpbCgpIHsKLQkJLy8KLQl9Ci0KLQlwdWJsaWMgc3RhdGljIE9iamVjdFtdIGdldE9iamVjdEFycmF5KCkgewotCQlyZXR1cm4gKE9iamVjdFtdKSBvYmplY3RBcnJheVBvb2wuZ2V0T2JqZWN0KCk7Ci0JfQotCi0JcHVibGljIHN0YXRpYyB2b2lkIHJlbGVhc2UoT2JqZWN0W10gb2JqZWN0QXJyYXkpIHsKLQkJZm9yIChpbnQgaiA9IDA7IGogPCBvYmplY3RBcnJheS5sZW5ndGg7IGorKykgewotCQkJb2JqZWN0QXJyYXlbal0gPSBudWxsOwotCQl9Ci0JCW9iamVjdEFycmF5UG9vbC5yZWxlYXNlT2JqZWN0KG9iamVjdEFycmF5KTsKLQl9Ci0KLQlwdWJsaWMgT2JqZWN0IGdldEluc3RhbmNlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7Ci0JCXJldHVybiBuZXcgT2JqZWN0WzFdOwotCX0KLQotCXB1YmxpYyBzdGF0aWMgdm9pZCBjb3B5VG8oRGljdGlvbmFyeSBkc3QsIERpY3Rpb25hcnkgc3JjKSB7Ci0JCWlmIChzcmMgPT0gbnVsbCB8fCBkc3QgPT0gbnVsbCkgewotCQkJcmV0dXJuOwotCQl9Ci0JCU9iamVjdCBrZXk7Ci0JCWZvciAoRW51bWVyYXRpb24gZSA9IHNyYy5rZXlzKCk7IGUuaGFzTW9yZUVsZW1lbnRzKCk7KSB7Ci0JCQlrZXkgPSBlLm5leHRFbGVtZW50KCk7Ci0JCQlkc3QucHV0KGtleSwgc3JjLmdldChrZXkpKTsKLQkJfQotCX0KLQotCS8qKgotCSAqIENoZWNrcyB3aGV0aGVyIHRoZSBtZXRob2QgY2FuIGJlIGFjY2Vzc2VkIGFjY29yZGluZyB0byB0aGUgRFMgdjEuMSBzcGVjaWZpY2F0aW9uIHJ1bGVzICgxMTIuOC40IExvY2F0aW5nIENvbXBvbmVudCBNZXRob2RzKQotCSAqIEBwYXJhbSBpbXBsQ2xhc3MgdGhlIGNvbXBvbmVudCBpbXBsZW1lbnRhdGlvbiBjbGFzcwotCSAqIEBwYXJhbSBjdXJyZW50Q2xhc3MgdGhlIGNsYXNzIHdoZXJlIHRoZSBtZXRob2QgaXMgbG9jYXRlZC4gVGhpcyBjbGFzcyBpcyBpbiB0aGUgY29tcG9uZW50IGltcGxlbWVudGF0aW9uIGNsYXNzIGhpZXJhcmNoeQotCSAqIEBwYXJhbSBtZXRob2RUb0NoZWNrIHRoZSBtZXRob2QgdG8gYmUgY2hlY2tlZAotCSAqIEBwYXJhbSBpc0NvbXBvbmVudDExIHNwZWNpZmllcyB3aGV0aGVyIHRoZSBjb21wb25lbnQgaXMgYWNjb3JkaW5nIHRvIHNjaGVtYSAxLjEgb3IgaGlnaGVyLiBJdHMgdmFsdWUgaXMgdHJ1ZSBpbiBjYXNlIHRoZSBjb21wb25lbnQgdmVyc2lvbiBpcyB2MS4xIG9yIGhpZ2hlcgotCSAqIEByZXR1cm4gdHJ1ZSwgaWYgdGhlIG1ldGhvZCBjYW4gYmUgZXhlY3V0ZWQKLQkgKi8KLQlwdWJsaWMgc3RhdGljIGJvb2xlYW4gY2hlY2tNZXRob2RBY2Nlc3MoQ2xhc3MgaW1wbENsYXNzLCBDbGFzcyBjdXJyZW50Q2xhc3MsIE1ldGhvZCBtZXRob2RUb0NoZWNrLCBib29sZWFuIGlzQ29tcG9uZW50MTEpIHsKLQkJaW50IG1vZGlmaWVycyA9IG1ldGhvZFRvQ2hlY2suZ2V0TW9kaWZpZXJzKCk7Ci0JCWJvb2xlYW4gcmVzdWx0ID0gdHJ1ZTsKLQkJaWYgKGlzQ29tcG9uZW50MTEpIHsKLQkJCWlmIChjdXJyZW50Q2xhc3MgPT0gaW1wbENsYXNzKSB7Ci0JCQkJLy90aGUgbWV0aG9kIGlzIGxvY2F0ZWQgaW4gdGhlIGNvbXBvbmVudCBpbXBsIGNsYXNzCi0JCQkJLy9hbGxvdyBhbGwgdHlwZXMgb2YgbW9kaWZpZXJzCi0JCQl9IGVsc2UgewotCQkJCS8vdGhlIG1ldGhvZCBpcyBsb2NhdGVkIGluIGEgc3VwZXIgY2xhc3Mgb2YgdGhlIGNvbXBvbmVudCBpbXBsIGNsYXNzCi0JCQkJaWYgKE1vZGlmaWVyLmlzUHJpdmF0ZShtb2RpZmllcnMpKSB7Ci0JCQkJCS8vIHByaXZhdGUgbWV0aG9kIC0gbm8gYWNjZXNzCi0JCQkJCXJlc3VsdCA9IGZhbHNlOwotCQkJCX0gZWxzZSBpZiAoIU1vZGlmaWVyLmlzUHVibGljKG1vZGlmaWVycykgJiYgIU1vZGlmaWVyLmlzUHJvdGVjdGVkKG1vZGlmaWVycykpIHsKLQkJCQkJLy8gbm90IHByb3RlY3RlZCBuZWl0aGVyIHB1YmxpYyBuZWl0aGVyIHByaXZhdGUgLSB0aGlzIGlzIHByaXZhdGUgcGFja2FnZSBjYXNlCi0JCQkJCWlmIChjdXJyZW50Q2xhc3MuZ2V0UGFja2FnZSgpICE9IGltcGxDbGFzcy5nZXRQYWNrYWdlKCkpIHsKLQkJCQkJCS8vZG8gbm90IGFjY2VwdCB0aGUgbWV0aG9kIGlmIGl0cyBjbGFzcyBwYWNrYWdlIGRpZmZlcnMgdGhlIHBhY2thZ2Ugb2YgdGhlIGNvbXBvbmVudCBpbXBsIGNsYXNzIAotCQkJCQkJcmVzdWx0ID0gZmFsc2U7Ci0JCQkJCX0KLQkJCQl9Ci0JCQl9Ci0JCX0gZWxzZSB7Ci0JCQlyZXN1bHQgPSBNb2RpZmllci5pc1B1YmxpYyhtb2RpZmllcnMpIHx8IE1vZGlmaWVyLmlzUHJvdGVjdGVkKG1vZGlmaWVycyk7Ci0JCX0KLQkJcmV0dXJuIHJlc3VsdDsKLQl9Ci0KLQlwcml2YXRlIHN0YXRpYyBNZXRob2Qgc2V0QWNjZXNzaWJsZU1ldGhvZCA9IG51bGw7Ci0JcHJpdmF0ZSBzdGF0aWMgT2JqZWN0W10gYXJncyA9IG51bGw7Ci0JcHJpdmF0ZSBzdGF0aWMgYm9vbGVhbiBmYWlsZWQgPSBmYWxzZTsKLQotCS8qKgotCSAqIFRoaXMgbWV0aG9kIGlzIGFkZGVkIG9ubHkgZm9yIEpWTSBjb21wYXRpYmlsaXR5LiBBY3R1YWxseSBzZXRBY2Nlc3NpYmxlKCkKLQkgKiBpcyBhdmFpbGFibGUgc2luY2UgamRrMS4yLiBUaGUgb2xkZXIgamF2YSBydW50aW1lcyBkb24ndCBoYXZlIHRoaXMKLQkgKiBtZXRob2QuCi0JICogCi0JICogSG93ZXZlciwgeW91IGNhbiBjYWxsIHRoaXMgbWV0aG9kLiBJdCBpcyBndWFyYW50ZWVkIHRoYXQgaXQgd2lsbCBkbyB0aGUKLQkgKiByaWdodCBqb2IuCi0JICogCi0JICogQHBhcmFtIG1ldGhvZAotCSAqICAgICAgICAgICAgdGhlIG1ldGhvZCB0byBzZXQgYWNjZXNzaWJsZS4KLQkgKi8KLQlwdWJsaWMgc3RhdGljIGZpbmFsIHZvaWQgc2V0QWNjZXNzaWJsZShNZXRob2QgbWV0aG9kKSB7Ci0JCXRyeSB7Ci0JCQlpZiAoc2V0QWNjZXNzaWJsZU1ldGhvZCA9PSBudWxsICYmICFmYWlsZWQpIHsKLQkJCQlzZXRBY2Nlc3NpYmxlTWV0aG9kID0gQ2xhc3MuZm9yTmFtZSgiamF2YS5sYW5nLnJlZmxlY3QuQWNjZXNzaWJsZU9iamVjdCIpLmdldE1ldGhvZCgic2V0QWNjZXNzaWJsZSIsIG5ldyBDbGFzc1tdIHtib29sZWFuLmNsYXNzfSk7IC8vJE5PTi1OTFMtMSQgLy8kTk9OLU5MUy0yJAotCQkJCWFyZ3MgPSBuZXcgT2JqZWN0W10ge0Jvb2xlYW4uVFJVRX07Ci0JCQl9Ci0JCQlpZiAoc2V0QWNjZXNzaWJsZU1ldGhvZCAhPSBudWxsKQotCQkJCXNldEFjY2Vzc2libGVNZXRob2QuaW52b2tlKG1ldGhvZCwgYXJncyk7Ci0JCX0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7Ci0JCQlmYWlsZWQgPSB0cnVlOwotCQl9Ci0JfQotCi0JLyoqCi0JICogR2V0cyB0aGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIGFuIDxjb2RlPk9iamVjdDwvY29kZT4uIFRoaXMgbWV0aG9kIGlzCi0JICogaGVscGZ1bCBpZiB0aGUgcGFzc2VkIHBhcmFtZXRlciBpcyBhIHR5cGUgb2YgYXJyYXkuIElmIHRoZSBvYmplY3RzIGlzIG5vdAotCSAqIHJlY29nbml6ZWQgYXMgYXJyYXksIHRoZSBtZXRob2Qgd2lsbCBzaW1wbHkgcmV0dXJuIHRoZSB0b1N0cmluZygpIHZhbHVlCi0JICogCi0JICogQHBhcmFtIHZhbHVlCi0JICogICAgICAgICAgYW4gb2JqZWN0IHdoaWNoIHNob3VsZCBiZSByZXByZXNlbnRlZCBhcyBzdHJpbmcKLQkgKiBAcmV0dXJuIHRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlCi0JICovCi0JcHVibGljIHN0YXRpYyBTdHJpbmcgZ2V0U3RyaW5nUmVwcmVzZW50YXRpb24oT2JqZWN0IHZhbHVlKSB7Ci0JCWlmICh2YWx1ZSA9PSBudWxsKQotCQkJcmV0dXJuICJudWxsIjsgLy8kTk9OLU5MUy0xJAotCQkvL3RoaXMgd291bGQgc3BlZWR1cCBtYW55IGNhc2VzCi0JCWlmICh2YWx1ZSBpbnN0YW5jZW9mIFN0cmluZykKLQkJCXJldHVybiAoU3RyaW5nKSB2YWx1ZTsKLQotCQlTdHJpbmdCdWZmZXIgcmVzID0gbmV3IFN0cmluZ0J1ZmZlcigyMDApOwotCi0JCWlmICh2YWx1ZSBpbnN0YW5jZW9mIFN0cmluZ1tdKSB7Ci0JCQlyZXMuYXBwZW5kKCJTdHJpbmdbIik7IC8vJE5PTi1OTFMtMSQKLQkJCVN0cmluZ1tdIGFyciA9IChTdHJpbmdbXSkgdmFsdWU7Ci0JCQlmb3IgKGludCBpID0gMDsgaSA8IGFyci5sZW5ndGg7IGkrKykgewotCQkJCXJlcy5hcHBlbmQoYXJyW2ldKTsKLQkJCQlpZiAoaSAhPSBhcnIubGVuZ3RoIC0gMSkgewotCQkJCQlyZXMuYXBwZW5kKCIsIik7IC8vJE5PTi1OTFMtMSQKLQkJCQl9Ci0JCQl9Ci0JCQlyZXMuYXBwZW5kKCJdIik7IC8vJE5PTi1OTFMtMSQKLQkJfSBlbHNlIGlmICh2YWx1ZSBpbnN0YW5jZW9mIGludFtdKSB7Ci0JCQlyZXMuYXBwZW5kKCJpbnRbIik7IC8vJE5PTi1OTFMtMSQKLQkJCWludFtdIGFyciA9IChpbnRbXSkgdmFsdWU7Ci0JCQlmb3IgKGludCBpID0gMDsgaSA8IGFyci5sZW5ndGg7IGkrKykgewotCQkJCXJlcy5hcHBlbmQoYXJyW2ldICsgIiIpOyAvLyROT04tTkxTLTEkCi0JCQkJaWYgKGkgIT0gYXJyLmxlbmd0aCAtIDEpIHsKLQkJCQkJcmVzLmFwcGVuZCgiLCIpOyAvLyROT04tTkxTLTEkCi0JCQkJfQotCQkJfQotCQkJcmVzLmFwcGVuZCgiXSIpOyAvLyROT04tTkxTLTEkCi0JCX0gZWxzZSBpZiAodmFsdWUgaW5zdGFuY2VvZiBsb25nW10pIHsKLQkJCXJlcy5hcHBlbmQoImxvbmdbIik7IC8vJE5PTi1OTFMtMSQKLQkJCWxvbmdbXSBhcnIgPSAobG9uZ1tdKSB2YWx1ZTsKLQkJCWZvciAoaW50IGkgPSAwOyBpIDwgYXJyLmxlbmd0aDsgaSsrKSB7Ci0JCQkJcmVzLmFwcGVuZChhcnJbaV0gKyAiIik7IC8vJE5PTi1OTFMtMSQKLQkJCQlpZiAoaSAhPSBhcnIubGVuZ3RoIC0gMSkgewotCQkJCQlyZXMuYXBwZW5kKCIsIik7IC8vJE5PTi1OTFMtMSQKLQkJCQl9Ci0JCQl9Ci0JCQlyZXMuYXBwZW5kKCJdIik7IC8vJE5PTi1OTFMtMSQKLQkJfSBlbHNlIGlmICh2YWx1ZSBpbnN0YW5jZW9mIGNoYXJbXSkgewotCQkJcmVzLmFwcGVuZCgiY2hhclsiKTsgLy8kTk9OLU5MUy0xJAotCQkJY2hhcltdIGFyciA9IChjaGFyW10pIHZhbHVlOwotCQkJZm9yIChpbnQgaSA9IDA7IGkgPCBhcnIubGVuZ3RoOyBpKyspIHsKLQkJCQlyZXMuYXBwZW5kKGFycltpXSArICIiKTsgLy8kTk9OLU5MUy0xJAotCQkJCWlmIChpICE9IGFyci5sZW5ndGggLSAxKSB7Ci0JCQkJCXJlcy5hcHBlbmQoIiwiKTsgLy8kTk9OLU5MUy0xJAotCQkJCX0KLQkJCX0KLQkJCXJlcy5hcHBlbmQoIl0iKTsgLy8kTk9OLU5MUy0xJAotCQl9IGVsc2UgaWYgKHZhbHVlIGluc3RhbmNlb2YgYm9vbGVhbltdKSB7Ci0JCQlyZXMuYXBwZW5kKCJib29sZWFuWyIpOyAvLyROT04tTkxTLTEkCi0JCQlib29sZWFuW10gYXJyID0gKGJvb2xlYW5bXSkgdmFsdWU7Ci0JCQlmb3IgKGludCBpID0gMDsgaSA8IGFyci5sZW5ndGg7IGkrKykgewotCQkJCXJlcy5hcHBlbmQoYXJyW2ldICsgIiIpOyAvLyROT04tTkxTLTEkCi0JCQkJaWYgKGkgIT0gYXJyLmxlbmd0aCAtIDEpIHsKLQkJCQkJcmVzLmFwcGVuZCgiLCIpOyAvLyROT04tTkxTLTEkCi0JCQkJfQotCQkJfQotCQkJcmVzLmFwcGVuZCgiXSIpOyAvLyROT04tTkxTLTEkCi0JCX0gZWxzZSBpZiAodmFsdWUgaW5zdGFuY2VvZiBkb3VibGVbXSkgewotCQkJcmVzLmFwcGVuZCgiZG91YmxlWyIpOyAvLyROT04tTkxTLTEkCi0JCQlkb3VibGVbXSBhcnIgPSAoZG91YmxlW10pIHZhbHVlOwotCQkJZm9yIChpbnQgaSA9IDA7IGkgPCBhcnIubGVuZ3RoOyBpKyspIHsKLQkJCQlyZXMuYXBwZW5kKGFycltpXSArICIiKTsgLy8kTk9OLU5MUy0xJAotCQkJCWlmIChpICE9IGFyci5sZW5ndGggLSAxKSB7Ci0JCQkJCXJlcy5hcHBlbmQoIiwiKTsgLy8kTk9OLU5MUy0xJAotCQkJCX0KLQkJCX0KLQkJCXJlcy5hcHBlbmQoIl0iKTsgLy8kTk9OLU5MUy0xJAotCQl9IGVsc2UgaWYgKHZhbHVlIGluc3RhbmNlb2YgZmxvYXRbXSkgewotCQkJcmVzLmFwcGVuZCgiZmxvYXRbIik7IC8vJE5PTi1OTFMtMSQKLQkJCWZsb2F0W10gYXJyID0gKGZsb2F0W10pIHZhbHVlOwotCQkJZm9yIChpbnQgaSA9IDA7IGkgPCBhcnIubGVuZ3RoOyBpKyspIHsKLQkJCQlyZXMuYXBwZW5kKGFycltpXSArICIiKTsgLy8kTk9OLU5MUy0xJAotCQkJCWlmIChpICE9IGFyci5sZW5ndGggLSAxKSB7Ci0JCQkJCXJlcy5hcHBlbmQoIiwiKTsgLy8kTk9OLU5MUy0xJAotCQkJCX0KLQkJCX0KLQkJCXJlcy5hcHBlbmQoIl0iKTsgLy8kTk9OLU5MUy0xJAotCQl9IGVsc2UgaWYgKHZhbHVlIGluc3RhbmNlb2YgT2JqZWN0W10pIHsKLQkJCXJlcy5hcHBlbmQoIk9iamVjdFsiKTsgLy8kTk9OLU5MUy0xJAotCQkJT2JqZWN0W10gYXJyID0gKE9iamVjdFtdKSB2YWx1ZTsKLQkJCWZvciAoaW50IGkgPSAwOyBpIDwgYXJyLmxlbmd0aDsgaSsrKSB7Ci0JCQkJcmVzLmFwcGVuZChnZXRTdHJpbmdSZXByZXNlbnRhdGlvbihhcnJbaV0pKTsKLQkJCQlpZiAoaSAhPSBhcnIubGVuZ3RoIC0gMSkgewotCQkJCQlyZXMuYXBwZW5kKCIsIik7IC8vJE5PTi1OTFMtMSQKLQkJCQl9Ci0JCQl9Ci0JCQlyZXMuYXBwZW5kKCJdIik7IC8vJE5PTi1OTFMtMSQKLQkJfSBlbHNlIHsKLQkJCXJldHVybiB2YWx1ZS50b1N0cmluZygpOwotCQl9Ci0JCXJldHVybiByZXMudG9TdHJpbmcoKTsKLQl9Ci0KLQkvKioKLQkgKiBHZXRzIHRoZSBzdHJpbmcgcHJlc2VudGF0aW9uIG9mIGEgc3RhdGUgZGVmaW5lZCBieSB0aGUgaW50ZXJmYWNlIG9yZy5hcGFjaGUuZmVsaXguc2NyLkNvbXBvbmVudAotCSAqIEBwYXJhbSBzdGF0ZSB0aGUgc3BlY2lmaWVkIHN0YXRlCi0JICogQHJldHVybiB0aGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBzcGVjaWZpZWQgc3RhdGUKLQkgKi8KLQlwdWJsaWMgc3RhdGljIFN0cmluZyBnZXRTdGF0ZVN0cmluZ1JlcHJlc2VudGF0aW9uKGludCBzdGF0ZSkgewotCQlTdHJpbmcgcmVzdWx0ID0gIlVua25vd24iOyAvLyROT04tTkxTLTEkCi0JCXN3aXRjaCAoc3RhdGUpIHsKLQkJCWNhc2UgQ29tcG9uZW50LlNUQVRFX0FDVElWQVRJTkcgOgotCQkJCXJlc3VsdCA9ICJBY3RpdmF0aW5nIjsgLy8kTk9OLU5MUy0xJAotCQkJCWJyZWFrOwotCQkJY2FzZSBDb21wb25lbnQuU1RBVEVfQUNUSVZFIDoKLQkJCQlyZXN1bHQgPSAiQWN0aXZlIjsgLy8kTk9OLU5MUy0xJAotCQkJCWJyZWFrOwotCQkJY2FzZSBDb21wb25lbnQuU1RBVEVfREVBQ1RJVkFUSU5HIDoKLQkJCQlyZXN1bHQgPSAiRGVhY3RpdmF0aW5nIjsgLy8kTk9OLU5MUy0xJAotCQkJCWJyZWFrOwotCQkJY2FzZSBDb21wb25lbnQuU1RBVEVfRElTQUJMRUQgOgotCQkJCXJlc3VsdCA9ICJEaXNhYmxlZCI7IC8vJE5PTi1OTFMtMSQKLQkJCQlicmVhazsKLQkJCWNhc2UgQ29tcG9uZW50LlNUQVRFX0RJU1BPU0VEIDoKLQkJCQlyZXN1bHQgPSAiRGlzcG9zZWQiOyAvLyROT04tTkxTLTEkCi0JCQkJYnJlYWs7Ci0JCQljYXNlIENvbXBvbmVudC5TVEFURV9ESVNQT1NJTkcgOgotCQkJCXJlc3VsdCA9ICJEaXNwb3NpbmciOyAvLyROT04tTkxTLTEkCi0JCQkJYnJlYWs7Ci0JCQljYXNlIENvbXBvbmVudC5TVEFURV9FTkFCTElORyA6Ci0JCQkJcmVzdWx0ID0gIkVuYWJsaW5nIjsgLy8kTk9OLU5MUy0xJAotCQkJCWJyZWFrOwotCQkJY2FzZSBDb21wb25lbnQuU1RBVEVfRkFDVE9SWSA6Ci0JCQkJcmVzdWx0ID0gIkZhY3RvcnkiOyAvLyROT04tTkxTLTEkCi0JCQkJYnJlYWs7Ci0JCQljYXNlIENvbXBvbmVudC5TVEFURV9SRUdJU1RFUkVEIDoKLQkJCQlyZXN1bHQgPSAiUmVnaXN0ZXJlZCI7IC8vJE5PTi1OTFMtMSQKLQkJCQlicmVhazsKLQkJCWNhc2UgQ29tcG9uZW50LlNUQVRFX1VOU0FUSVNGSUVEIDoKLQkJCQlyZXN1bHQgPSAiVW5zYXRpc2ZpZWQiOyAvLyROT04tTkxTLTEkCi0JCQkJYnJlYWs7Ci0KLQkJfQotCQlyZXR1cm4gcmVzdWx0OwotCX0KLX0KZGlmZiAtLWdpdCBhL2J1bmRsZXMvb3JnLmVjbGlwc2UuZXF1aW5veC5kcy9zcmMvb3JnL2VjbGlwc2UvZXF1aW5veC9pbnRlcm5hbC9kcy9TQ1JtZXNzYWdlcy5wcm9wZXJ0aWVzIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5lcXVpbm94LmRzL3NyYy9vcmcvZWNsaXBzZS9lcXVpbm94L2ludGVybmFsL2RzL1NDUm1lc3NhZ2VzLnByb3BlcnRpZXMKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDE5ZDJhNDguLjAwMDAwMDAKLS0tIGEvYnVuZGxlcy9vcmcuZWNsaXBzZS5lcXVpbm94LmRzL3NyYy9vcmcvZWNsaXBzZS9lcXVpbm94L2ludGVybmFsL2RzL1NDUm1lc3NhZ2VzLnByb3BlcnRpZXMKKysrIC9kZXYvbnVsbApAQCAtMSwxNjggKzAsMCBAQAotIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwotIyBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTAgYnkgUHJvU3lzdCBTb2Z0d2FyZSBHbWJICi0jIGh0dHA6Ly93d3cucHJvc3lzdC5jb20KLSMgQWxsIHJpZ2h0cyByZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscwotIyBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYxLjAKLSMgd2hpY2ggYWNjb21wYW5pZXMgdGhpcyBkaXN0cmlidXRpb24sIGFuZCBpcyBhdmFpbGFibGUgYXQKLSMgaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtdjEwLmh0bWwKLSMKLSMgIENvbnRyaWJ1dG9yczoKLSMgICAgICBQcm9TeXN0IFNvZnR3YXJlIEdtYkggLSBpbml0aWFsIEFQSSBhbmQgaW1wbGVtZW50YXRpb24KLSMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKLUFMTF9DT01QT05FTlRTPUFsbCBDb21wb25lbnRzOgotQUxMX1JFRkVSRU5DRVNfUkVTT0xWRUQ9XCBcIEFsbCBjb21wb25lbnQgcmVmZXJlbmNlcyBhcmUgc2F0aXNmaWVkCi1CSU5EX01FVEhPRF9OT1RfRk9VTkRfT1JfTk9UX0FDQ0VTU0lCTEU9W1NDUl0gQ29tcG9uZW50UmVmZXJlbmNlLmJpbmQoKTogYmluZCBtZXRob2QgJyd7MH0nJyBpcyBub3QgZm91bmQgb3IgaXQgaXMgbm90IGFjY2Vzc2libGUhCi1VUERBVEVEX01FVEhPRF9OT1RfRk9VTkRfT1JfTk9UX0FDQ0VTU0lCTEU9W1NDUl0gVXBkYXRlZCBtZXRob2QgJyd7MH0nJyBpcyBub3QgZm91bmQgb3IgaXQgaXMgbm90IGFjY2Vzc2libGUhCi1VUERBVEVEX01FVEhPRF9OT1RfQ0FMTEVEPVtTQ1JdIFVwZGF0ZWQgbWV0aG9kIG9mIHJlZmVyZW5jZSB7MH0gb2YgY29tcG9uZW50IHsxfSBjYW5ub3QgYmUgY2FsbGVkIGJlY2F1c2UgaXRzIHBhcmFtZXRlciBzZXJ2aWNlIG9iamVjdCBjYW5ub3QgYmUgcmV0cmlldmVkIQotQlVORExFX05PVF9GT1VORD1CdW5kbGUgd2l0aCBJRCB7MH0gd2FzIG5vdCBmb3VuZCEKLUNBTk5PVF9CVUlMRF9DT01QT05FTlQ9W1NDUl0gQ2Fubm90IGJ1aWxkIGNvbXBvbmVudCB7MH0KLUNBTk5PVF9DUkVBVEVfSU5TVEFOQ0U9U2VydmljZVJlZy5nZXRTZXJ2aWNlKCk6IENvdWxkIG5vdCBjcmVhdGUgaW5zdGFuY2Ugb2YgezB9Ci1DQU5OT1RfRklORF9DT01QT05FTlRfQlVORExFPUNvdWxkIG5vdCBmaW5kIHRoZSBidW5kbGUgb2YgdGhlIHNwZWNpZmllZCBjb21wb25lbnRcISBJdCBpcyBwb3NzaWJseSB1bmluc3RhbGxlZC4KLUNBTk5PVF9HRVRfQ09ORklHVVJBVElPTj1bU0NSXSBDYW5ub3QgZ2V0IGNvbmZpZ3VyYXRpb24gZm9yIGNvbXBvbmVudCB7MH0KLUNBTk5PVF9HRVRfUkVGRVJFTkNFUz1bU0NSXSBDYW5ub3QgZ2V0IHJlZmVyZW5jZXMgZm9yIHswfQotQ0FOTk9UX01PRElGWV9JTlNUQU5DRV9fTU9ESUZZX01FVEhPRF9OT1RfRk9VTkQ9W1NDUl0gQ2Fubm90IG1vZGlmeSBpbnN0YW5jZSB7MH0gb2YgY29tcG9uZW50IHsxfVwhIFRoZSBzcGVjaWZpZWQgbW9kaWZ5IG1ldGhvZCB3YXMgbm90IGZvdW5kXCEKLUNBTlRfQUNUSVZBVEVfSU5TVEFOQ0U9W1NDUl0gQ2Fubm90IGFjdGl2YXRlIGluc3RhbmNlIHswfSBvZiBjb21wb25lbnQgezF9IAotQ0FOVF9HRVRfU0VSVklDRT1GYWN0b3J5UmVnLmdldFNlcnZpY2UoKTogQ2Fubm90IGNyZWF0ZSBpbnN0YW5jZSBvZiB7MH0KLUNBTlRfR0VUX1NFUlZJQ0VfT0JKRUNUPVtTQ1JdIENvdWxkIG5vdCBnZXQgdGhlIHNlcnZpY2Ugb2JqZWN0IHJlbGV2YW50IHRvIHRoZSByZWZlcmVuY2UuIE9uZSBwb3NzaWJsZSByZWFzb24gaXMgYSBjaXJjdWxhcml0eSBwcm9ibGVtLiBBbm90aGVyIHBvc3NpYmxlIHJlYXNvbiBpcyB0aGF0IEJ1bmRsZUNvbnRleHQuZ2V0U2VydmljZSgpIHJldHVybnMgbnVsbC4KLUNBTlRfTElTVF9DT05GSUdVUkFUSU9OUz1bU0NSXSBDYW5ub3QgbGlzdCBjb25maWd1cmF0aW9ucyBmb3IgY29tcG9uZW50IHswfQotQ0FOVF9PUEVOX1NUUkVBTV9UT19DT01QT05FTlRfWE1MPVtTQ1JdIENvdWxkIG5vdCBvcGVuIHN0cmVhbSB0byBjb21wb25lbnQgZGVmaW5pdGlvbiBmaWxlIHswfQotQ0FOVF9SRVNPTFZFX0NPTVBPTkVOVF9JTlNUQU5DRT1DYW5ub3QgcmVzb2x2ZSBpbnN0YW5jZSBvZiB7MH0gd2l0aCBwcm9wZXJ0aWVzIHsxfSAgCi1DSVJDVUxBUklUWV9FWENFUFRJT05fRk9VTkQ9W1NDUl0gQ2lyY3VsYXJpdHkgRXhjZXB0aW9uIGZvdW5kIGZvciBjb21wb25lbnQ6IHswfQotQ09NUE9ORU5UX0RJU1BPU0VEPVRoZSBjb21wb25lbnQgaXMgZGlzcG9zZWQKLUNPTVBPTkVOVF9DT05GSUdVUkFUSU9OUz1cIFwgQ29tcG9uZW50IGNvbmZpZ3VyYXRpb25zIDoKLUNPTVBPTkVOVF9ERVRBSUxTPVx0Q29tcG9uZW50IGRldGFpbHMKLUNPTVBPTkVOVF9IQVNfSUxMRUdBTF9SRUZFUkVOQ0U9VGhlIGNvbXBvbmVudCAnJ3swfScnIGRlZmluZWQgYXQgbGluZSB7MX0gY29udGFpbnMgaWxsZWdhbCByZWZlcmVuY2UgezJ9IAotQ09NUE9ORU5UX0lEX0RFRklOSUVEX0JZX0xJU1RfQ09NTUFORD1UaGUgSUQgb2YgdGhlIGNvbXBvbmVudCBhcyBkaXNwbGF5ZWQgYnkgdGhlIGxpc3QgY29tbWFuZAotQ09NUE9ORU5UX0xBQ0tTX0FQUFJPUFJJQVRFX1BFUk1JU1NJT05TPVtTQ1JdIENhbm5vdCBzYXRpc2Z5IGNvbXBvbmVudCAnJ3swfScnIGJlY2F1c2UgaXRzIGJ1bmRsZSBkb2VzIG5vdCBoYXZlIHBlcm1pc3Npb25zIHRvIHJlZ2lzdGVyIHNlcnZpY2Ugd2l0aCBpbnRlcmZhY2UgezF9Ci1DT01QT05FTlRfTkFNRT1cdFx0XHRDb21wb25lbnQgTmFtZQotQ09NUE9ORU5UX05BTUVfSVNfTlVMTD1Db21wb25lbnQgbmFtZSBtdXN0IG5vdCBiZSBudWxsCi1DT01QT05FTlRfTk9UX0ZPVU5EPWNvbXBvbmVudCB7MH0gbm90IGZvdW5kIGluIGJ1bmRsZSB7MX0KLUNPTVBPTkVOVF9OT1RfUkVTT0xWRUQ9XCBcICpUaGUgY29tcG9uZW50IGlzIE5PVCBzYXRpc2ZpZWQKLUNPTVBPTkVOVF9SRVFVUkVTX0NPTkZJR1VSQVRJT05fQUNUSVZBVElPTj1UaGUgJyd7MH0nJyBjb21wb25lbnQnJ3MgY29uZmlndXJhdGlvbiBjb3VsZCBub3QgYmUgc2F0aXNmaWVkIGJlY2F1c2UgaXQgaXMgcmVxdWlyZWQgdG8gYmUgaW5pdGlhbGl6ZWQgYnkgYSBDb25maWd1cmF0aW9uQWRtaW4gc2VydmljZSBDb25maWd1cmF0aW9uIG9iamVjdCwgYnV0IG9uZSB3YXMgbm90IGZvdW5kLgotQ09NUE9ORU5UX1JFU09MVkVEPVwgXCBUaGUgY29tcG9uZW50IGlzIHNhdGlzZmllZAotQ09NUE9ORU5UX1dBU19OT1RfQlVJTFQ9VGhlIGNvbXBvbmVudCB3YXMgbm90IGJ1aWx0IGJlY2F1c2Ugc29tZSBvZiBpdHMgcmVmZXJlbmNlcyBjb3VsZCBub3QgYmUgYm91bmQuIFRoZSBjb21wb25lbnQgaXMgezB9Ci1DT01QT05FTlRfWE1MX05PVF9GT1VORD1bU0NSXSBDb21wb25lbnQgZGVmaW5pdGlvbiBYTUxzIG5vdCBmb3VuZCBpbiBidW5kbGUgezB9LiBUaGUgY29tcG9uZW50IGhlYWRlciB2YWx1ZSBpcyB7MX0KLUNPTVBPTkVOVFNfSU5fQlVORExFPUNvbXBvbmVudHMgaW4gYnVuZGxlIHswfTogCi1DT05GSUdfQURNSU5fU0VSVklDRV9OT1RfQVZBSUxBQkxFPVRoZSBDb25maWd1cmF0aW9uQWRtaW4gc2VydmljZSBpcyBub3QgYXZhaWxhYmxlLgotQ09ORklHX1BST1BFUlRJRVM9XCBcIFwgXCBDb25maWd1cmF0aW9uIHByb3BlcnRpZXM6Ci1DT1VMRF9OT1RfQ1JFQVRFX0lOU1RBTkNFPVtTQ1IgLSBTQ1JNYW5hZ2VyXSBjb3VsZCBub3QgY3JlYXRlIGluc3RhbmNlIGZvciB7MH0KLUNPVUxEX05PVF9DUkVBVEVfTkVXX0lOU1RBTkNFPUZhaWxlZCB0byBjcmVhdGUgbmV3IGluc3RhbmNlCi1ESVNBQkxFX0FMTF9DT01QT05FTlRTPURpc2FibGVzIGFsbCBjb21wb25lbnRzOyB1c2UgW2J1bmRsZSBpZF0gdG8gZGlzYWJsZSBhbGwgY29tcG9uZW50cyBvZiB0aGUgc3BlY2lmaWVkIGJ1bmRsZQotRElTQUJMRV9DT01QT05FTlQ9RGlzYWJsZXMgdGhlIHNwZWNpZmllZCBjb21wb25lbnQ7Ci1ESVNBQkxJTkdfQUxMX0JVTkRMRV9DT01QT05FTlRTPURpc2FibGluZyBhbGwgY29tcG9uZW50cyBpbiBidW5kbGUgezB9IAotRElTQUJMSU5HX0FMTF9DT01QT05FTlRTPURpc2FibGluZyBhbGwgY29tcG9uZW50cwotRFVQTElDQVRFRF9SRUZFUkVOQ0VfTkFNRVM9VGhlIGNvbXBvbmVudCAnJ3swfScnIGRlZmluZWQgYXQgbGluZSB7MX0gY29udGFpbnMgcmVmZXJlbmNlcyB3aXRoIGR1cGxpY2F0ZSBuYW1lcwotRFVQTElDQVRFRF9TRVJWSUNFX1RBR1M9VGhlICcnc2VydmljZScnIHRhZyBpcyBkdXBsaWNhdGVkIGF0IGxpbmUgezB9IAotRFlOQU1JQ19JTkZPPUR5bmFtaWMgaW5mb3JtYXRpb24gOgotRU5BQkxFX0FMTF9DT01QT05FTlRTPUVuYWJsZXMgYWxsIGNvbXBvbmVudHM7IHVzZSBbYnVuZGxlIGlkXSB0byBlbmFibGUgYWxsIGNvbXBvbmVudHMgb2YgdGhlIHNwZWNpZmllZCBidW5kbGUKLUVOQUJMRV9DT01QT05FTlQ9RW5hYmxlcyB0aGUgc3BlY2lmaWVkIGNvbXBvbmVudDsKLUVOQUJMSU5HX0FMTF9CVU5ETEVfQ09NUE9ORU5UUz1FbmFibGluZyBhbGwgY29tcG9uZW50cyBpbiBidW5kbGUgezB9Ci1FTkFCTElOR19BTExfQ09NUE9ORU5UUz1FbmFibGluZyBhbGwgY29tcG9uZW50cwotRVJST1JfQklORElOR19SRUZFUkVOQ0U9W1NDUl0gRXJyb3Igd2hpbGUgdHJ5aW5nIHRvIGJpbmQgcmVmZXJlbmNlIHswfQotRVJST1JfQlVJTERJTkdfQ09NUE9ORU5UX0lOU1RBTkNFPUVycm9yIHdoaWxlIGJ1aWxkaW5nIGNvbmZpZ3VyYXRpb24gb2YgY29tcG9uZW50IHswfQotRVJST1JfQ1JFQVRJTkdfU0NQPVtTQ1JdIFVuZXhwZWN0ZWQgZXhjZXB0aW9uIHdoaWxlIGNyZWF0aW5nIGNvbmZpZ3VyYXRpb24gZm9yIGNvbXBvbmVudCB7MH0KLUVSUk9SX0RFQUNUSVZBVElOR19JTlNUQU5DRT1bU0NSXSBFcnJvciB3aGlsZSBhdHRlbXB0aW5nIHRvIGRlYWN0aXZhdGUgaW5zdGFuY2Ugb2YgY29tcG9uZW50IHswfQotRVJST1JfRElTUEFUQ0hJTkdfV09SSz1bU0NSXSBFcnJvciBkaXNwYXRjaGluZyB3b3JrIAotRVJST1JfRElTUE9TSU5HX0lOU1RBTkNFUz1FeGNlcHRpb24gd2hpbGUgZGlzcG9zaW5nIGluc3RhbmNlcyBvZiBjb21wb25lbnQgezB9Ci1FUlJPUl9MSVNUSU5HX0NPTkZJR1VSQVRJT05TPUVycm9yIHdoaWxlIGxpc3RpbmcgQ00gQ29uZmlndXJhdGlvbnMKLUVSUk9SX0xPQURJTkdfQ09NUE9ORU5UUz1bU0NSXSBFcnJvciB3aGlsZSBsb2FkaW5nIGNvbXBvbmVudHMgZnJvbSBEQgotRVJST1JfTE9BRElOR19EQVRBX0ZJTEU9W1NDUl0gRXJyb3Igd2hpbGUgbG9hZGluZyBjb21wb25lbnRzIGZyb20gZGF0YSBmaWxlIHswfQotRVJST1JfTE9BRElOR19QUk9QRVJUSUVTX0ZJTEU9W1NDUiAtIERlY2xhcmF0aW9uUGFyc2VyLmRvUHJvcGVydGllcygpXSBFcnJvciB3aGlsZSBsb2FkaW5nIHByb3BlcnRpZXMgZmlsZQotRVJST1JfT1BFTklOR19DT01QX1hNTD1bU0NSXSBFcnJvciBvY2N1cnJlZCB3aGlsZSBvcGVuaW5nIGNvbXBvbmVudCBkZWZpbml0aW9uIGZpbGUgezB9Ci1FUlJPUl9QQVJTSU5HX01BTklGRVNUX0hFQURFUj1FcnJvciBhdHRlbXB0aW5nIHBhcnNlIG1hbmlmZXN0IGVsZW1lbnQgaGVhZGVyCi1FUlJPUl9QUk9DRVNTSU5HX0NPTkZJR1VSQVRJT049W1NDUl0gRXJyb3Igd2hpbGUgcHJvY2Vzc2luZyBjb25maWd1cmF0aW9uIGV2ZW50IGZvciBidW5kbGUgezB9Ci1FUlJPUl9QUk9DRVNTSU5HX0VORF9UQUc9W1NDUl0gRXJyb3Igb2NjdXJyZWQgd2hpbGUgcHJvY2Vzc2luZyBlbmQgdGFnIG9mIFhNTCAnJ3swfScnIGluIGJ1bmRsZSB7MX0hICAKLUVSUk9SX1BST0NFU1NJTkdfUFJPUEVSVFk9W1NDUiAtIERlY2xhcmF0aW9uUGFyc2VyLmRvUHJvcGVydHkoKV0gRXJyb3Igd2hpbGUgcHJvY2Vzc2luZyBwcm9wZXJ0eSAnJ3swfScnIGluIFhNTCB7MX0hICAKLUVSUk9SX1BST0NFU1NJTkdfU1RBUlRfVEFHPVtTQ1JdIEVycm9yIG9jY3VycmVkIHdoaWxlIHByb2Nlc3Npbmcgc3RhcnQgdGFnIG9mIFhNTCAnJ3swfScnIGluIGJ1bmRsZSB7MX0hICAKLUVSUk9SX1VOQklORElOR19SRUZFUkVOQ0U9W1NDUl0gRXJyb3Igd2hpbGUgZHluYW1pY2FsbHkgdW5iaW5kaW5nIHJlZmVyZW5jZSAnJ3swfScnIG9mIGNvbXBvbmVudCBpbnN0YW5jZSB7MX0gCi1FUlJPUl9VUERBVElOR19SRUZFUkVOQ0U9W1NDUl0gRXJyb3Igd2hpbGUgdXBkYXRpbmcgcmVmZXJlbmNlICcnezB9Jycgb2YgY29tcG9uZW50IGluc3RhbmNlIHsxfSAKLUVSUk9SX1VOQklORElOR19SRUZFUkVOQ0UyPUV4Y2VwdGlvbiB3aGlsZSB1bmJpbmRpbmcgcmVmZXJlbmNlIHswfQotRVhDRVBUSU9OX0FDVElWQVRJTkdfSU5TVEFOQ0U9W1NDUl0gRXhjZXB0aW9uIHdoaWxlIGFjdGl2YXRpbmcgaW5zdGFuY2UgezB9IG9mIGNvbXBvbmVudCB7MX0gIAotRVhDRVBUSU9OX0JVSUxESU5HX0NPTVBPTkVOVD1bU0NSXSBFeGNlcHRpb24gb2NjdXJyZWQgd2hpbGUgYnVpbGRpbmcgY29tcG9uZW50IGNvbmZpZ3VyYXRpb24gb2YgY29tcG9uZW50IHswfQotRVhDRVBUSU9OX0NSRUFUSU5HX0NPTVBPTkVOVF9JTlNUQU5DRT1FeGNlcHRpb24gb2NjdXJyZWQgd2hpbGUgY3JlYXRpbmcgbmV3IGluc3RhbmNlIG9mIGNvbXBvbmVudCB7MH0gCi1FWENFUFRJT05fR0VUVElOR19NRVRIT0Q9W1NDUl0gRXhjZXB0aW9uIG9jY3VycmVkIHdoaWxlIGdldHRpbmcgbWV0aG9kICcnezB9Jycgb2YgY2xhc3MgezF9IAotRVhDRVBUSU9OX0xPQ0FUSU5HX1NFUlZJQ0U9RXhjZXB0aW9uIG9jY3VycmVkIHdoaWxlIGxvY2F0aW5nIHNlcnZpY2UgZm9yIGludGVyZmFjZSB7MH0KLUVYQ0VQVElPTl9MT0NBVElOR19TRVJWSUNFUz1FeGNlcHRpb24gb2NjdXJyZWQgd2hpbGUgbG9jYXRpbmcgc2VydmljZXMgZm9yIGludGVyZmFjZSB7MH0KLUVYQ0VQVElPTl9NT0RJRllJTkdfQ09NUE9ORU5UPVtTQ1JdIEV4Y2VwdGlvbiB3aGlsZSBtb2RpZnlpbmcgaW5zdGFuY2UgezB9IG9mIGNvbXBvbmVudCB7MX0KLUVYQ0VQVElPTl9VTkJJTkRJTkdfUkVGRVJFTkNFPVtTQ1JdIEV4Y2VwdGlvbiBvY2N1cnJlZCB3aGlsZSB1bmJpbmRpbmcgcmVmZXJlbmNlIHswfQotRVhQRUNURURfUEFSQU1FVEVSX0NPTVBPTkVOVF9JRD1UaGlzIGNvbW1hbmQgZXhwZWN0cyBhIGNvbXBvbmVudCBJRCBhcyBwYXJhbWV0ZXJcIQotRkFDVE9SWV9DT05GX05PVF9BUFBMSUNBQkxFX0ZPUl9DT01QT05FTlRfRkFDVE9SWT1bU0NSIC0gU0NSTWFuYWdlcl0gQ29tcG9uZW50RmFjdG9yeSB7MH0gY2Fubm90IGJlIG1hbmFnZWQgdXNpbmcgZmFjdG9yeSBjb25maWd1cmF0aW9uIQotRkFDVE9SWV9SRUdJU1RSQVRJT05fQUxSRUFEWV9ESVNQT1NFRD1JbnN0YW5jZVByb2Nlc3MuZGlzcG9zZUluc3RhbmNlcygpOiByZWdpc3RyYXRpb24gZm9yIGNvbXBvbmVudCBmYWN0b3J5IHswfSBpcyBhbHJlYWR5IGRpc3Bvc2VkIQotRk9VTkRfQ09NUE9ORU5UU19XSVRIX0RVUExJQ0FURURfTkFNRVM9W1NDUl0gRm91bmQgY29tcG9uZW50cyB3aXRoIGR1cGxpY2F0ZWQgbmFtZXMgaW5zaWRlIHRoZWlyIGJ1bmRsZVwhIFRoaXMgY29tcG9uZW50IHdpbGwgbm90IGJlIHByb2Nlc3NlZDogezB9IAotRk9VTkRfQ09NUE9ORU5UU19XSVRIX0RVUExJQ0FURURfTkFNRVMyPVtTQ1JdIEZvdW5kIGNvbXBvbmVudHMgd2l0aCBkdXBsaWNhdGVkIG5hbWVzXCEgRGV0YWlsczogXG5Db21wb25lbnQxIDogezB9XG5Db21wb25lbnQyOiB7MX0gIAotSUxMRUdBTF9ERUZJTklUSU9OX0ZJTEU9W1NDUl0gSWxsZWdhbCBkZWZpbml0aW9uIGZpbGU6IHswfQotSUxMRUdBTF9FTEVNRU5UX0lOX1NFUlZJQ0VfVEFHPUZvdW5kIGlsbGVnYWwgZWxlbWVudCAnJ3swfScnIGZvciB0YWcgJydzZXJ2aWNlJycgYXQgbGluZSB7MX0KLUlMTEVHQUxfVEFHX0ZPVU5EPUZvdW5kIGlsbGVnYWwgdGFnIG5hbWVkICcnezB9JycgaW4gY29tcG9uZW50IFhNTCwgYXQgbGluZSB7MX0gCi1JTkNPTVBBVElCTEVfQ09NQklOQVRJT049TWFuYWdlZFNlcnZpY2VGYWN0b3J5IGFuZCBDb21wb25lbnRGYWN0b3J5IGFyZSBpbmNvbXBhdGlibGUKLUlOQ09SUkVDVF9BQ1RJVkFUSU9OX1BPTElDWT1UaGUgY29tcG9uZW50ICcnezB9JycgaGFzIGluY29ycmVjdCB2YWx1ZSBmb3IgYXR0cmlidXRlICcnY29uZmlndXJhdGlvbi1wb2xpY3knJywgbGluZSB7MX0KLUlOQ09SUkVDVF9WQUxVRV9UWVBFPVZhbHVlIHswfSBkb2VzIG5vdCBmaXQgaXRzIHR5cGUhIAotSU5TVEFOQ0VfQUxSRUFEWV9DUkVBVEVEPUluc3RhbmNlIG9mICcnezB9JydpcyBhbHJlYWR5IGNyZWF0ZWQhCi1JTlNUQU5DRV9DUkVBVElPTl9UT09LX0xPTkdFUj1UaGUgaW5zdGFuY2UgY3JlYXRpb24gb2YgY29tcG9uZW50IHswfSB0b29rIGxvbmdlciB0aGFuIHsxfW1zLiBUaGVyZSBtaWdodCBiZSBhIHN5bmNocm9uaXphdGlvbiBwcm9ibGVtIGluIHRoaXMgY2FsbHN0YWNrIG9yIGp1c3QgdGhlIGluc3RhbmNlIGNyZWF0aW9uIHRvb2sgdG9vIGxvbmchIAotSU5TVEFOQ0VfTk9UX0JPVU5EPVtTQ1JdIENvbXBvbmVudFJlZmVyZW5jZS51bmJpbmQoKTogY29tcG9uZW50IGluc3RhbmNlIG5vdCBib3VuZFwhIEl0IGlzOiB7MH0gCi1JTlZBTElEX0NBUkRJTkFMSVRZX0FUVFI9VGhlICcnY2FyZGluYWxpdHknJyBhdHRyaWJ1dGUgaGFzIGludmFsaWQgdmFsdWUgJyd7MH0nJyBhdCBsaW5lIHsxfSAKLUlOVkFMSURfQ09NUE9ORU5UX0ZBQ1RPUllfQU5EX1NFUlZJQ0VfRkFDVE9SWT1UaGUgY29tcG9uZW50ICcnezB9JycgaXMgaW52YWxpZC4gVGhlIGNvbXBvbmVudCBjYW5ub3QgYmUgYm90aCBmYWN0b3J5IGNvbXBvbmVudCBhbmQgc2VydmljZSBmYWN0b3J5Ci1JTlZBTElEX0NPTVBPTkVOVF9JRD1JbnZhbGlkIGNvbXBvbmVudCBJRFwhCi1JTlZBTElEX0NPTVBPTkVOVF9JTU1FRElBVEVfQU5EX0ZBQ1RPUlk9VGhlIGNvbXBvbmVudCAnJ3swfScnIGlzIGludmFsaWQuIFRoZSBjb21wb25lbnQgY2Fubm90IGJlIGJvdGggaW1tZWRpYXRlIGFuZCBhIGZhY3RvcnkgY29tcG9uZW50Ci1JTlZBTElEX0NPTVBPTkVOVF9JTU1FRElBVEVfQU5EX1NFUlZJQ0VfRkFDVE9SWT1UaGUgY29tcG9uZW50ICcnezB9JycgaXMgaW52YWxpZC4gVGhlIGNvbXBvbmVudCBjYW5ub3QgYmUgYm90aCBpbW1lZGlhdGUgYW5kIGEgc2VydmljZSBmYWN0b3J5Ci1JTlZBTElEX0NPTVBPTkVOVF9OT19TRVJWSUNFU19OT19JTU1FRElBVEU9VGhlIGNvbXBvbmVudCAnJ3swfScnIGlzIGludmFsaWQuIFRoZSBjb21wb25lbnQgbXVzdCBiZSBpbW1lZGlhdGUgc2luY2UgaXQgZG9lcyBub3QgcHJvdmlkZSBhbnkgc2VydmljZXMKLUlOVkFMSURfQ09NUE9ORU5UX1RBR19fTVVMVElQTEVfSU1QTF9BVFRSSUJTPVRoZSAnJ2NvbXBvbmVudCcnIHRhZyBtdXN0IGhhdmUgZXhhY3RseSBvbmUgJydpbXBsZW1lbnRhdGlvbicnIGF0dHJpYnV0ZSBhdCBsaW5lIHswfQotSU5WQUxJRF9DT01QT05FTlRfVEFHX19OT19DTEFTU19BVFRSPVRoZSAnJ2ltcGxlbWVudGF0aW9uJycgZWxlbWVudCBtdXN0IGhhdmUgJydjbGFzcycnIGF0dHJpYnV0ZSBzZXQgYXQgbGluZSB7MH0KLUlOVkFMSURfT0JKRUNUPVRoZSBPYmplY3QgJyd7MH0nJyBpcyBub3QgY3JlYXRlZCBieSB0aGUgY29tcG9uZW50IG5hbWVkIHsxfSAKLUlOVkFMSURfUE9MSUNZX0FUVFI9VGhlICcncG9saWN5JycgYXR0cmlidXRlIGhhcyBpbnZhbGlkIHZhbHVlICcnezB9JycgYXQgbGluZSB7MX0gCi1JTlZBTElEX1BPTElDWV9PUFRJT05fQVRUUj1UaGUgJydwb2xpY3ktb3B0aW9uJycgYXR0cmlidXRlIGhhcyBpbnZhbGlkIHZhbHVlICcnezB9JycgYXQgbGluZSB7MX0gCi1JTlZBTElEX1BST1BFUlRJRVNfVEFHX19JTlZBTElEX0VOVFJZX1ZBTFVFPVRoZSBzcGVjaWZpZWQgJydlbnRyeScnIGZvciB0aGUgJydwcm9wZXJ0aWVzJycgdGFnIGF0IGxpbmUgezB9IGRvZXNuJyd0IGNvbnRhaW4gdmFsaWQgcmVmZXJlbmNlIHRvIGEgcHJvcGVydHkgZmlsZTogezF9Ci1JTlZBTElEX1BST1BFUlRJRVNfVEFHX19OT19FTlRSWV9BVFRSPVRoZSAnJ3Byb3BlcnRpZXMnJyB0YWcgbXVzdCBpbmNsdWRlICcnZW50cnknJyBhdHRyaWJ1dGUsIGF0IGxpbmUgezB9Ci1JTlZBTElEX1BST1BFUlRZX1RBR19fTk9fQk9EWV9DT05URU5UPVRoZSAncHJvcGVydHknIHRhZyBtdXN0IGhhdmUgYm9keSBjb250ZW50IGlmICd2YWx1ZScgYXR0cmlidXRlIGlzIG5vdCBzcGVjaWZpZWRcIQotSU5WQUxJRF9QUk9QRVJUWV9UQUdfX05PX05BTUVfQVRUUj1UaGUgJydwcm9wZXJ0eScnIHRhZyBtdXN0IGhhdmUgJyduYW1lJycgYXR0cmlidXRlIHNldCBhdCBsaW5lIHswfQotSU5WQUxJRF9QUk9QRVJUWV9UWVBFPUlsbGVnYWwgcHJvcGVydHkgdHlwZSAnJ3swfScnIGF0IGxpbmUgezF9IAotSU5WQUxJRF9QUk9WSURFX1RBR19fTk9fSU5URVJGQUNFX0FUVFI9VGhlICcncHJvdmlkZScnIHRhZyBtdXN0IGhhdmUgJydpbnRlcmZhY2UnJyBhdHRyaWJ1dGUgc2V0IGF0IGxpbmUgezB9IAotSU5WQUxJRF9SRUZFUkVOQ0VfVEFHX19CSU5EX0FUVFJfRU1QVFk9VGhlICcncmVmZXJlbmNlJycgdGFnIGF0IGxpbmUgezB9IGlzIGludmFsaWQ6ICcnYmluZCcnIGF0dHJpYnV0ZSBpcyBlbXB0eSEgCi1JTlZBTElEX1JFRkVSRU5DRV9UQUdfX0JJTkRfRVFVQUxTX1VOQklORD1UaGUgJydyZWZlcmVuY2UnJyB0YWcgYXQgbGluZSB7MH0gaXMgaW52YWxpZDogJydiaW5kJycgYW5kICcndW5iaW5kJycgdmFsdWVzIGFyZSBlcXVhbCEKLUlOVkFMSURfUkVGRVJFTkNFX1RBR19fVU5CSU5EX0FUVFJfRU1QVFk9VGhlICcncmVmZXJlbmNlJycgdGFnIGF0IGxpbmUgezB9IGlzIGludmFsaWQ6ICcndW5iaW5kJycgYXR0cmlidXRlIGlzIGVtcHR5IQotSU5WQUxJRF9SRUZFUkVOQ0VfVEFHX19VUERBVEVEX0FUVFJfRU1QVFk9VGhlICcncmVmZXJlbmNlJycgdGFnIGF0IGxpbmUgezB9IGlzIGludmFsaWQ6ICcndXBkYXRlZCcnIGF0dHJpYnV0ZSBpcyBlbXB0eSEKLUlOVkFMSURfU0VSVklDRV9SRUZFUkVOQ0U9W1NDUl0gQ29tcG9uZW50UmVmZXJlbmNlLnVuYmluZCgpOiBpbnZhbGlkIHNlcnZpY2UgcmVmZXJlbmNlIHswfQotSU5WQUxJRF9TRVJWSUNFX1RBR19fTk9fUFJPVklERV9UQUc9VGhlICcnc2VydmljZScnIHRhZyBtdXN0IGhhdmUgb25lICcncHJvdmlkZScnIHRhZyBzZXQgYXQgbGluZSB7MH0gCi1JTlZBTElEX1RBR19BQ0NPUkRJTkdfVE9fTkFNRVNQQUNFMV8wPVRoZSBjb21wb25lbnQgaXMgYWNjb3JkaW5nIHRvIG5hbWVzcGFjZSB2MS4wLjAgYW5kIG11c3Qgbm90IGhhdmUgJyd7MH0nJyB0YWcgc2V0LCBhdCBsaW5lIHsxfQotSU5WQUxJRF9UQUdfQUNDT1JESU5HX1RPX05BTUVTUEFDRTFfMj1UaGUgY29tcG9uZW50IG11c3QgaGF2ZSBuYW1lc3BhY2UgdjEuMi4wIGluIG9yZGVyIHRvIGFjY2VwdCBhdHRyaWJ1dGUgJyd7MH0nJyBzZXQsIGF0IGxpbmUgezF9Ci1JTlZBTElEX1RBUkdFVF9GSUxURVI9aW52YWxpZCB0YXJnZXQgZmlsdGVyIHswfQotTElTVF9BTExfQlVORExFX0NPTVBPTkVOVFM9dXNlIFtidW5kbGUgaWRdIHRvIGxpc3QgdGhlIGNvbXBvbmVudHMgb2YgdGhlIHNwZWNpZmllZCBidW5kbGUKLUxJU1RfQUxMX0NPTVBPTkVOVFM9TGlzdHMgYWxsIGNvbXBvbmVudHM7IGFkZCAtYyB0byBkaXNwbGF5IHRoZSBjb21wbGV0ZSBpbmZvIGZvciBlYWNoIGNvbXBvbmVudDsKLUxPQ0FURURfSU5fQlVORExFPVx0XHRcdExvY2F0ZWQgaW4gYnVuZGxlCi1NRVRIT0RfVU5BQ0NFU1NBQkxFPVtTQ1JdIE1ldGhvZCAnJ3swfScnIGlzIG5vdCBwdWJsaWMgb3IgcHJvdGVjdGVkIGFuZCBjYW5ub3QgYmUgZXhlY3V0ZWQhIFRoZSBtZXRob2QgaXMgbG9jYXRlZCBpbiB0aGUgY2xhc3M6IHsxfQotTUlTU0lOR19DSEFSQUNURVI9TWlzc2luZyBjaGFyYWN0ZXIgCi1OT19CVUlMVF9DT01QT05FTlRfQ09ORklHVVJBVElPTlM9XCBcICpUaGUgY29tcG9uZW50IGhhcyBOTyBidWlsdCBjb25maWd1cmF0aW9uc1whIFRoZSByZWFzb24gbWlnaHQgYmUgdGhhdCBpdCByZXF1aXJlcyBpbml0aWFsaXphdGlvbiBieSBjb25maWd1cmF0aW9uIHByb3ZpZGVkIGJ5IENvbmZpZ3VyYXRpb24gQWRtaW4gYnV0IG5vbmUgd2FzIGZvdW5kCi1OT19DT01QT05FTlRTX0ZPVU5EPVtTQ1JdIE5vIGNvbXBvbmVudHMgd2VyZSBmb3VuZCB3aGlsZSBwcm9jZXNzaW5nIGNvbXBvbmVudCBkZWZpbml0aW9uIGZpbGUgezB9Ci1OT19JTVBMRU1FTlRBVElPTl9BVFRSSUJVVEU9VGhlIGNvbXBvbmVudCAnJ3swfScnIG1pc3NlcyAnJ2ltcGxlbWVudGF0aW9uJycgYXR0cmlidXRlLCBsaW5lIHsxfQotTk9fSU5URVJGQUNFX0FUVFJfSU5fUkVGRVJFTkNFX1RBRz1UaGUgJydyZWZlcmVuY2UnJyB0YWcgbXVzdCBoYXZlICcnaW50ZXJmYWNlJycgYXR0cmlidXRlLCBhdCBsaW5lIHswfQotTk9fTkFNRV9BVFRSSUJVVEU9VGhlIGNvbXBvbmVudCBkZWZpbml0aW9uIG1pc3NlcyAnJ25hbWUnJyBhdHRyaWJ1dGUsIGxpbmUgezB9Ci1OT1RfUkVTT0xWRURfUkVGRVJFTkNFUz1cIFwgVGhlIGZvbGxvd2luZyByZWZlcmVuY2VzIGFyZSBub3Qgc2F0aXNmaWVkOgotUFJJTlRfQ09NUE9ORU5UX0lORk89UHJpbnRzIGFsbCBhdmFpbGFibGUgaW5mb3JtYXRpb24gYWJvdXQgdGhlIHNwZWNpZmllZCBjb21wb25lbnQ7Ci1QUk9DRVNTSU5HX0JVTkRMRV9GQUlMRUQ9W1NDUl0gVW5leHBlY3RlZCBleGNlcHRpb24gd2hpbGUgcHJvY2Vzc2luZyBidW5kbGUgd2l0aCBpZCB7MH0gOiB7MX0gIAotUkVHSVNURVJFRF9BU19DT01QT05FTlRfQU5EX01BTkFHRURfU0VSVklDRV9GQUNPUlk9W1NDUiAtIFJlc29sdmVyXSBDYW5ub3Qgc3BlY2lmeSBib3RoIENvbXBvbmVudEZhY3RvcnkgYW5kIE1hbmFnZWRTZXJ2aWNlRmFjdG9yeVxuVGhlIG5hbWUgb2YgdGhlIENvbXBvbmVudEZhY3RvcnkgY29tcG9uZW50IGlzIHswfQotUkVHSVNUUkFUSU9OX0FMUkVBRFlfRElTUE9TRUQ9SW5zdGFuY2VQcm9jZXNzLmRpc3Bvc2VJbnN0YW5jZXMoKTogcmVnaXN0cmF0aW9uIGZvciBjb21wb25lbnQgezB9IGlzIGFscmVhZHkgZGlzcG9zZWQhIAotUkVUVVJOSU5HX05PVF9GVUxMWV9BQ1RJVkFURURfSU5TVEFOQ0U9UmV0dXJuaW5nIFNDUCBpbnN0YW5jZSB3aGljaCBpcyBub3QgZnVsbHkgYWN0aXZhdGVkXCEKLVNDUj1TZXJ2aWNlIENvbXBvbmVudCBSdW50aW1lCi1TRU5UX0RJU0FCTElOR19SRVFVRVNUPVNlbnQgcmVxdWVzdCBmb3IgZGlzYWJsaW5nIGNvbXBvbmVudCB7MH0KLVNFTlRfRU5BQkxJTkdfUkVRVUVTVD1TZW50IHJlcXVlc3QgZm9yIGVuYWJsaW5nIGNvbXBvbmVudCB7MH0KLVNFUlZJQ0VfUkVGRVJFTkNFX0FMUkVBRFlfQk9VTkQ9W1NDUl0gQ29tcG9uZW50UmVmZXJlbmNlLmJpbmQoKTogc2VydmljZSByZWZlcmVuY2UgezB9IGlzIGFscmVhZHkgYm91bmQgdG8gaW5zdGFuY2UgezF9ICAKLVNFUlZJQ0VfVVNBR0VfQ09VTlQ9c2VydmljZSAnJ3swfScnIGlzIHVzZWQgezF9IHRpbWUocykKLVNQRUNJRklFRF9BQ1RJVkFURV9NRVRIT0RfTk9UX0ZPVU5EPVtTQ1JdIENhbm5vdCBhY3RpdmF0ZSBpbnN0YW5jZSB7MH0gb2YgY29tcG9uZW50IHsxfSEgVGhlIHNwZWNpZmllZCBhY3RpdmF0ZSBtZXRob2Qgd2FzIG5vdCBmb3VuZCEgCi1TUEVDSUZJRURfREVBQ1RJVkFURV9NRVRIT0RfTk9UX0ZPVU5EPVtTQ1JdIENhbm5vdCBjb3JyZWN0bHkgZGVhY3RpdmF0ZSBpbnN0YW5jZSB7MH0gb2YgY29tcG9uZW50IHsxfSEgVGhlIHNwZWNpZmllZCBkZWFjdGl2YXRlIG1ldGhvZCB3YXMgbm90IGZvdW5kISAKLVNUQVRFPVx0U3RhdGUKLVNUQVRJQ19PUFRJT05BTF9SRUZFUkVOQ0VfVE9fQkVfUkVNT1ZFRD1bU0NSXSBTdGF0aWMgb3B0aW9uYWwgcmVmZXJlbmNlIGRldGVjdGVkIGluIGEgY29tcG9uZW50IGN5Y2xlIGFuZCBpdCB3aWxsIGJlIHJlbW92ZWQuIFRoZSByZWZlcmVuY2UgaXMgezB9IAotVElNRU9VVF9HRVRUSU5HX0xPQ0s9R2V0dGluZyBhIGxvY2sgcmVxdWlyZWQgbW9yZSB0aGFuIHswfSBtcy4gVGhlcmUgbWlnaHQgYmUgYSBzeW5jaHJvbml6YXRpb24gcHJvYmxlbSBpbiB0aGlzIGNhbGxzdGFjayBvciBqdXN0IHRoZSBidWlsZC9kaXNwb3NlIHByb2Nlc3Mgb2Ygc29tZSBjb21wb25lbnRzIHRvb2sgdG9vIGxvbmchIAotVElNRU9VVF9QUk9DRVNTSU5HPVtTQ1IgLSBXb3JrVGhyZWFkXSBUaW1lb3V0IG9jY3VycmVkXCEgVGhyZWFkIHdhcyBibG9ja2VkIG9uIHByb2Nlc3NpbmcgezB9Ci1USU1FT1VUX1JFQUNIRURfRU5BQkxJTkdfQ09NUE9ORU5UUz1bU0NSXSBFbmFibGluZyBjb21wb25lbnRzIG9mIGJ1bmRsZSB7MH0gZGlkIG5vdCBjb21wbGV0ZSBpbiB7MX0gbXMgCi1VTkVYUEVDVEVEX0VSUk9SPVtTQ1JdIFVuZXhwZWN0ZWQgZXJyb3JcIQotVU5FWFBFQ1RFRF9FWENFUFRJT049W1NDUl0gVW5leHBlY3RlZCBleGNlcHRpb24gb2NjdXJyZWRcIQotVU5TVVBQT1JURURfVFlQRT1VbnN1cHBvcnRlZCB0eXBlOiB7MH0KLVdST05HX1BBUkFNRVRFUj1Xcm9uZyBwYXJhbWV0ZXIgezB9ISBJdCBpcyBub3QgYSBudW1iZXIhIAotV1JPTkdfUEFSQU1FVEVSMj1Xcm9uZyBwYXJhbWV0ZXIgezB9Ci1FUlJPUl9ERUxFVElOR19DT01QT05FTlRfREVGSU5JVElPTlM9RXJyb3IgZGVsZXRpbmcgY29tcG9uZW50J3MgZGVmaW5pdGlvbnMhCi1FUlJPUl9XUklUSU5HX09CSkVDVD1FcnJvciB3cml0aW5nIG9iamVjdCEKLUVSUk9SX1JFQURJTkdfT0JKRUNUPUVycm9yIHJlYWRpbmcgb2JqZWN0IQotREJNQU5BR0VSX1NFUlZJQ0VfVFJBQ0tFUl9PUEVORUQ9REJNYW5hZ2VyIHNlcnZpY2UgdHJhY2tlciBvcGVuZWQgZm9yIAotRVJST1JfTE9BRElOR19DT01QT05FTlRfREVGSU5JVElPTlM9RXJyb3Igd2hpbGUgbG9hZGluZyBjb21wb25lbnQncyBkZWZpbml0aW9ucyEKLUVSUk9SX01PRElGWUlOR19DT01QT05FTlQ9RXJyb3IgbW9kaWZ5aW5nIGNvbXBvbmVudCB7MH0KLUVSUk9SX1NBVklOR19DT01QT05FTlRfREVGSU5JVElPTlM9RXJyb3Igd2hpbGUgc2F2aW5nIGNvbXBvbmVudCdzIGRlZmluaXRpb25zIQotRklMRV9ET0VTTlRfRVhJU1RfT1JfRElSRUNUT1JZPUZpbGUgZG9lc24ndCBleGlzdCBvciBpcyBhIGRpcmVjdG9yeSEKZGlmZiAtLWdpdCBhL2J1bmRsZXMvb3JnLmVjbGlwc2UuZXF1aW5veC5kcy9zcmMvb3JnL2VjbGlwc2UvZXF1aW5veC9pbnRlcm5hbC9kcy9TY3JTZXJ2aWNlSW1wbC5qYXZhIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5lcXVpbm94LmRzL3NyYy9vcmcvZWNsaXBzZS9lcXVpbm94L2ludGVybmFsL2RzL1NjclNlcnZpY2VJbXBsLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDk2MzI1NjguLjAwMDAwMDAKLS0tIGEvYnVuZGxlcy9vcmcuZWNsaXBzZS5lcXVpbm94LmRzL3NyYy9vcmcvZWNsaXBzZS9lcXVpbm94L2ludGVybmFsL2RzL1NjclNlcnZpY2VJbXBsLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw1NCArMCwwIEBACi0vKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgotICogQ29weXJpZ2h0IChjKSAxOTk3LTIwMTAgYnkgUHJvU3lzdCBTb2Z0d2FyZSBHbWJICi0gKiBodHRwOi8vd3d3LnByb3N5c3QuY29tCi0gKiBBbGwgcmlnaHRzIHJlc2VydmVkLiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzCi0gKiBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYxLjAKLSAqIHdoaWNoIGFjY29tcGFuaWVzIHRoaXMgZGlzdHJpYnV0aW9uLCBhbmQgaXMgYXZhaWxhYmxlIGF0Ci0gKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC12MTAuaHRtbAotICoKLSAqIENvbnRyaWJ1dG9yczoKLSAqICAgIFByb1N5c3QgU29mdHdhcmUgR21iSCAtIGluaXRpYWwgQVBJIGFuZCBpbXBsZW1lbnRhdGlvbgotICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi1wYWNrYWdlIG9yZy5lY2xpcHNlLmVxdWlub3guaW50ZXJuYWwuZHM7Ci0KLWltcG9ydCBvcmcuYXBhY2hlLmZlbGl4LnNjci5Db21wb25lbnQ7Ci1pbXBvcnQgb3JnLmFwYWNoZS5mZWxpeC5zY3IuU2NyU2VydmljZTsKLWltcG9ydCBvcmcub3NnaS5mcmFtZXdvcmsuQnVuZGxlOwotCi1wdWJsaWMgY2xhc3MgU2NyU2VydmljZUltcGwgaW1wbGVtZW50cyBTY3JTZXJ2aWNlIHsKLQotCWJvb2xlYW4gZGlzcG9zZWQgPSBmYWxzZTsKLQotCXB1YmxpYyBDb21wb25lbnQgZ2V0Q29tcG9uZW50KGxvbmcgY29tcG9uZW50SWQpIHsKLQkJaWYgKCFkaXNwb3NlZCAmJiBJbnN0YW5jZVByb2Nlc3MucmVzb2x2ZXIgIT0gbnVsbCkgewotCQkJcmV0dXJuIEluc3RhbmNlUHJvY2Vzcy5yZXNvbHZlci5nZXRDb21wb25lbnQoY29tcG9uZW50SWQpOwotCQl9Ci0JCXJldHVybiBudWxsOwotCX0KLQotCXB1YmxpYyBDb21wb25lbnRbXSBnZXRDb21wb25lbnRzKCkgewotCQlpZiAoIWRpc3Bvc2VkICYmIEluc3RhbmNlUHJvY2Vzcy5yZXNvbHZlciAhPSBudWxsKSB7Ci0JCQlyZXR1cm4gSW5zdGFuY2VQcm9jZXNzLnJlc29sdmVyLm1nci5nZXRDb21wb25lbnRzKCk7Ci0JCX0KLQkJcmV0dXJuIG51bGw7Ci0JfQotCi0JcHVibGljIENvbXBvbmVudFtdIGdldENvbXBvbmVudHMoQnVuZGxlIGJ1bmRsZSkgewotCQlpZiAoIWRpc3Bvc2VkICYmIEluc3RhbmNlUHJvY2Vzcy5yZXNvbHZlciAhPSBudWxsKSB7Ci0JCQlyZXR1cm4gSW5zdGFuY2VQcm9jZXNzLnJlc29sdmVyLm1nci5nZXRDb21wb25lbnRzKGJ1bmRsZSk7Ci0JCX0KLQkJcmV0dXJuIG51bGw7Ci0JfQotCi0JcHVibGljIHZvaWQgZGlzcG9zZSgpIHsKLQkJZGlzcG9zZWQgPSB0cnVlOwotCX0KLQotCXB1YmxpYyBDb21wb25lbnRbXSBnZXRDb21wb25lbnRzKFN0cmluZyBjb21wb25lbnROYW1lKSB7Ci0JCWlmICghZGlzcG9zZWQgJiYgSW5zdGFuY2VQcm9jZXNzLnJlc29sdmVyICE9IG51bGwpIHsKLQkJCXJldHVybiBJbnN0YW5jZVByb2Nlc3MucmVzb2x2ZXIubWdyLmdldENvbXBvbmVudHMoY29tcG9uZW50TmFtZSk7Ci0JCX0KLQkJcmV0dXJuIG51bGw7Ci0JfQotCi19CmRpZmYgLS1naXQgYS9idW5kbGVzL29yZy5lY2xpcHNlLmVxdWlub3guZHMvc3JjL29yZy9lY2xpcHNlL2VxdWlub3gvaW50ZXJuYWwvZHMvU2VydmljZVJlZy5qYXZhIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5lcXVpbm94LmRzL3NyYy9vcmcvZWNsaXBzZS9lcXVpbm94L2ludGVybmFsL2RzL1NlcnZpY2VSZWcuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDUzYWRlMi4uMDAwMDAwMAotLS0gYS9idW5kbGVzL29yZy5lY2xpcHNlLmVxdWlub3guZHMvc3JjL29yZy9lY2xpcHNlL2VxdWlub3gvaW50ZXJuYWwvZHMvU2VydmljZVJlZy5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTIwICswLDAgQEAKLS8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTAgYnkgUHJvU3lzdCBTb2Z0d2FyZSBHbWJICi0gKiBodHRwOi8vd3d3LnByb3N5c3QuY29tCi0gKiBBbGwgcmlnaHRzIHJlc2VydmVkLiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzCi0gKiBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYxLjAKLSAqIHdoaWNoIGFjY29tcGFuaWVzIHRoaXMgZGlzdHJpYnV0aW9uLCBhbmQgaXMgYXZhaWxhYmxlIGF0Ci0gKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC12MTAuaHRtbAotICoKLSAqIENvbnRyaWJ1dG9yczoKLSAqICAgIFByb1N5c3QgU29mdHdhcmUgR21iSCAtIGluaXRpYWwgQVBJIGFuZCBpbXBsZW1lbnRhdGlvbgotICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi1wYWNrYWdlIG9yZy5lY2xpcHNlLmVxdWlub3guaW50ZXJuYWwuZHM7Ci0KLWltcG9ydCBvcmcuZWNsaXBzZS5lcXVpbm94LmludGVybmFsLmRzLmltcGwuQ29tcG9uZW50SW5zdGFuY2VJbXBsOwotaW1wb3J0IG9yZy5lY2xpcHNlLmVxdWlub3guaW50ZXJuYWwuZHMubW9kZWwuU2VydmljZUNvbXBvbmVudFByb3A7Ci1pbXBvcnQgb3JnLmVjbGlwc2Uub3NnaS51dGlsLk5MUzsKLWltcG9ydCBvcmcub3NnaS5mcmFtZXdvcmsuKjsKLWltcG9ydCBvcmcub3NnaS5zZXJ2aWNlLmNvbXBvbmVudC5Db21wb25lbnRDb25zdGFudHM7Ci1pbXBvcnQgb3JnLm9zZ2kuc2VydmljZS5jb21wb25lbnQuQ29tcG9uZW50RXhjZXB0aW9uOwotaW1wb3J0IG9yZy5vc2dpLnNlcnZpY2UubG9nLkxvZ1NlcnZpY2U7Ci0KLS8qKgotICogQGF1dGhvciBTdG95YW4gQm9zaGV2Ci0gKiBAYXV0aG9yIFBhdmxpbiBEb2JyZXYKLSAqIEB2ZXJzaW9uIDEuMgotICovCi0KLWZpbmFsIGNsYXNzIFNlcnZpY2VSZWcgaW1wbGVtZW50cyBTZXJ2aWNlRmFjdG9yeSB7Ci0KLQlzdGF0aWMgYm9vbGVhbiBkb250RGlzcG9zZUluc3RhbmNlcyA9IHRydWU7Ci0KLQkvLyB0cmFja2luZyB0aGUgaW5zdGFuY2UgdXNhZ2UgYW5kIHJlLWluc3RhbnRpYXRpb24KLQlwcml2YXRlIGludCB1c2VDb3VudCA9IDA7Ci0JcHJpdmF0ZSBDb21wb25lbnRJbnN0YW5jZUltcGwgaW5zdGFuY2U7Ci0KLQkvLyBtb2RlbAotCXByaXZhdGUgU2VydmljZUNvbXBvbmVudFByb3Agc2NwOwotCi0Jc3RhdGljIHsKLQkJU3RyaW5nIHRtcCA9IEFjdGl2YXRvci5iYy5nZXRQcm9wZXJ0eSgiZXF1aW5veC5zY3IuZG9udERpc3Bvc2VJbnN0YW5jZXMiKTsgLy8kTk9OLU5MUy0xJAotCQlkb250RGlzcG9zZUluc3RhbmNlcyA9ICh0bXAgIT0gbnVsbCkgPyAhdG1wLmVxdWFsc0lnbm9yZUNhc2UoImZhbHNlIikgOiB0cnVlOyAvLyROT04tTkxTLTEkCi0JfQotCi0JU2VydmljZVJlZyhTZXJ2aWNlQ29tcG9uZW50UHJvcCBzY3AsIENvbXBvbmVudEluc3RhbmNlSW1wbCBpbnN0YW5jZSkgewotCQl0aGlzLnNjcCA9IHNjcDsKLQkJdGhpcy5pbnN0YW5jZSA9IGluc3RhbmNlOwotCX0KLQotCS8vIFNlcnZpY2VGYWN0b3J5LmdldFNlcnZpY2UgbWV0aG9kLgotCXB1YmxpYyBPYmplY3QgZ2V0U2VydmljZShCdW5kbGUgYnVuZGxlLCBTZXJ2aWNlUmVnaXN0cmF0aW9uIHJlZ2lzdHJhdGlvbikgewotCQl0cnkgewotCQkJaWYgKGluc3RhbmNlID09IG51bGwpIHsKLQkJCQlpbnN0YW5jZSA9IEluc3RhbmNlUHJvY2Vzcy5zdGF0aWNSZWYuYnVpbGRDb21wb25lbnQoYnVuZGxlLCBzY3AsIG51bGwsIGZhbHNlKTsKLQkJCQkvL2luc3RhbmNlIGNvdWxkIGJlIG51bGwgaWYgdGhlIGNvbXBvbmVudCBpcyBhbHJlYWR5IGRpc3Bvc2VkCi0JCQkJaWYgKGluc3RhbmNlID09IG51bGwpIHsKLQkJCQkJcmV0dXJuIG51bGw7Ci0JCQkJfQotCQkJfQotCQkJc3luY2hyb25pemVkICh0aGlzKSB7Ci0JCQkJdXNlQ291bnQrKzsKLQkJCX0KLQkJCWlmIChBY3RpdmF0b3IuREVCVUcpIHsKLQkJCQlBY3RpdmF0b3IubG9nLmRlYnVnKCJTZXJ2aWNlUmVnLmdldFNlcnZpY2UoKTogc2VydmljZSAnIiArIHNjcC5uYW1lICsgIicgaXMgdXNlZCAiICsgSW50ZWdlci50b1N0cmluZyh1c2VDb3VudCkgKyAiIHRpbWUocyksIG9iamVjdCA9ICIgKyBpbnN0YW5jZS5nZXRJbnN0YW5jZSgpLCBudWxsKTsgLy8kTk9OLU5MUy0xJCAvLyROT04tTkxTLTIkIC8vJE5PTi1OTFMtMyQKLQkJCX0KLQkJCXJldHVybiBpbnN0YW5jZS5nZXRJbnN0YW5jZSgpOwotCQl9IGNhdGNoIChFeGNlcHRpb24gZSkgewotCQkJaWYgKCEoZSBpbnN0YW5jZW9mIENvbXBvbmVudEV4Y2VwdGlvbikpIHsKLQkJCQlBY3RpdmF0b3IubG9nKG51bGwsIExvZ1NlcnZpY2UuTE9HX0VSUk9SLCBOTFMuYmluZChNZXNzYWdlcy5DQU5OT1RfQ1JFQVRFX0lOU1RBTkNFLCBzY3AubmFtZSksIGUpOwotCQkJCXJldHVybiBudWxsOwotCQkJfQotCQkJdGhyb3cgKENvbXBvbmVudEV4Y2VwdGlvbikgZTsKLQkJfQotCX0KLQotCS8vIFNlcnZpY2VGYWN0b3J5LnVuZ2V0U2VydmljZSBtZXRob2QuCi0JcHVibGljIHZvaWQgdW5nZXRTZXJ2aWNlKEJ1bmRsZSBidW5kbGUsIFNlcnZpY2VSZWdpc3RyYXRpb24gcmVnaXN0cmF0aW9uLCBPYmplY3Qgc2VydmljZSkgewotCQlib29sZWFuIHNoYWxsRGlzcG9zZSA9IGZhbHNlOwotCQlzeW5jaHJvbml6ZWQgKHRoaXMpIHsKLQkJCXVzZUNvdW50LS07Ci0JCQlpZiAodXNlQ291bnQgPT0gMCkgewotCQkJCXNoYWxsRGlzcG9zZSA9IHRydWU7Ci0JCQl9Ci0JCX0KLQkJaWYgKHNoYWxsRGlzcG9zZSkgewotCQkJaWYgKCFkb250RGlzcG9zZUluc3RhbmNlcyAmJiAhc2NwLnNlcnZpY2VDb21wb25lbnQuaW1tZWRpYXRlKSB7Ci0JCQkJLy9kaXNwb3NlIGluc3RhbmNlIG9ubHkgaWYgZGlzcG9zaW5nIGlzIGFsbG93ZWQgYW5kIHRoZSBjb21wb25lbnQgaXMgbm90IGltbWVkaWF0ZSBvbmUuCi0KLQkJCQkvL0ltbWVkaWF0ZSBjb21wb25lbnRzIGFyZSBjdXN0b20gY2FzZSAtIGFjY29yZGluZyB0byBtZSwgdGhlaXIgaW5zdGFuY2VzIHNob3VsZCBub3QgYmUgZGlzcG9zZWQKLQkJCQkvLyBiZWNhdXNlIHRoZXkgYXJlIHByb2JhYmx5IG5lZWRlZCBkdXJpbmcgdGhlIHdob2xlIGNvbXBvbmVudCdzIGxpZmUgIAotCQkJCWlmIChBY3RpdmF0b3IuREVCVUcpIHsKLQkJCQkJQWN0aXZhdG9yLmxvZy5kZWJ1ZygiU2VydmljZVJlZy51bmdldFNlcnZpY2UoKTogc2VydmljZSAnIiArIHNjcC5uYW1lICsgIicgbm8gbG9uZ2VyIHVzZWQsIGRpc3Bvc2luZyBvYmplY3QgPSAiICsgc2VydmljZSwgbnVsbCk7IC8vJE5PTi1OTFMtMSQgLy8kTk9OLU5MUy0yJAotCQkJCX0KLQkJCQkvLyBkaXNwb3NlIG9ubHkgdGhlIGluc3RhbmNlIC0gZG9uJ3QgZGlzcG9zZSB0aGUgY29tcG9uZW50Ci0JCQkJLy8gaXRzZWxmIQotCQkJCXNjcC5kaXNwb3NlT2JqKHNlcnZpY2UsIENvbXBvbmVudENvbnN0YW50cy5ERUFDVElWQVRJT05fUkVBU09OX1VOU1BFQ0lGSUVEKTsKLQkJCQkvLyBkZWxldGUgdGhlIGluc3RhbmNlIHNvIGl0IGNhbiBiZSBnYXJiYWdlIGNvbGxlY3RlZCEKLQkJCQlpbnN0YW5jZSA9IG51bGw7Ci0JCQl9IGVsc2UgewotCQkJCWlmIChBY3RpdmF0b3IuREVCVUcpIHsKLQkJCQkJQWN0aXZhdG9yLmxvZy5kZWJ1ZygiU2VydmljZVJlZy51bmdldFNlcnZpY2UoKTogc2VydmljZSAnIiArIHNjcC5uYW1lICsgIicgaXMgdXNlZCAiICsgSW50ZWdlci50b1N0cmluZyh1c2VDb3VudCkgKyAiIHRpbWUocykiLCBudWxsKTsgLy8kTk9OLU5MUy0xJCAvLyROT04tTkxTLTIkIC8vJE5PTi1OTFMtMyQKLQkJCQl9Ci0JCQl9Ci0JCX0gZWxzZSB7Ci0JCQlpZiAodXNlQ291bnQgPCAwKSB7Ci0JCQkJQWN0aXZhdG9yLmxvZyhudWxsLCBMb2dTZXJ2aWNlLkxPR19XQVJOSU5HLCAiU2VydmljZVJlZy51bmdldFNlcnZpY2UoKTogIiArIE5MUy5iaW5kKE1lc3NhZ2VzLlNFUlZJQ0VfVVNBR0VfQ09VTlQsIHNjcC5uYW1lLCBJbnRlZ2VyLnRvU3RyaW5nKHVzZUNvdW50KSksIG5ldyBFeGNlcHRpb24oIkRlYnVnIGNhbGxzdGFjayIpKTsgLy8kTk9OLU5MUy0xJCAvLyROT04tTkxTLTIkCi0JCQl9IGVsc2UgaWYgKEFjdGl2YXRvci5ERUJVRykgewotCQkJCUFjdGl2YXRvci5sb2cuZGVidWcoIlNlcnZpY2VSZWcudW5nZXRTZXJ2aWNlKCk6IHNlcnZpY2UgJyIgKyBzY3AubmFtZSArICInIGlzIHVzZWQgIiArIEludGVnZXIudG9TdHJpbmcodXNlQ291bnQpICsgIiB0aW1lKHMpIiwgbnVsbCk7IC8vJE5PTi1OTFMtMSQgLy8kTk9OLU5MUy0yJCAvLyROT04tTkxTLTMkCi0JCQl9Ci0JCX0KLQl9Ci0KLQkvKgotCSAqIChub24tSmF2YWRvYykKLQkgKiAKLQkgKiBAc2VlIGphdmEubGFuZy5PYmplY3QjdG9TdHJpbmcoKQotCSAqLwotCXB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7Ci0JCXJldHVybiBzY3AubmFtZSArICIgU2VydmljZSBSZWdpc3RyYXRpb24iOyAvLyROT04tTkxTLTEkCi0JfQotfQpkaWZmIC0tZ2l0IGEvYnVuZGxlcy9vcmcuZWNsaXBzZS5lcXVpbm94LmRzL3NyYy9vcmcvZWNsaXBzZS9lcXVpbm94L2ludGVybmFsL2RzL1dvcmtQZXJmb3JtZXIuamF2YSBiL2J1bmRsZXMvb3JnLmVjbGlwc2UuZXF1aW5veC5kcy9zcmMvb3JnL2VjbGlwc2UvZXF1aW5veC9pbnRlcm5hbC9kcy9Xb3JrUGVyZm9ybWVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDBhMTc5MWIuLjAwMDAwMDAKLS0tIGEvYnVuZGxlcy9vcmcuZWNsaXBzZS5lcXVpbm94LmRzL3NyYy9vcmcvZWNsaXBzZS9lcXVpbm94L2ludGVybmFsL2RzL1dvcmtQZXJmb3JtZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDM3ICswLDAgQEAKLS8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMDggYnkgUHJvU3lzdCBTb2Z0d2FyZSBHbWJICi0gKiBodHRwOi8vd3d3LnByb3N5c3QuY29tCi0gKiBBbGwgcmlnaHRzIHJlc2VydmVkLiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzCi0gKiBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYxLjAKLSAqIHdoaWNoIGFjY29tcGFuaWVzIHRoaXMgZGlzdHJpYnV0aW9uLCBhbmQgaXMgYXZhaWxhYmxlIGF0Ci0gKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC12MTAuaHRtbAotICoKLSAqIENvbnRyaWJ1dG9yczoKLSAqICAgIFByb1N5c3QgU29mdHdhcmUgR21iSCAtIGluaXRpYWwgQVBJIGFuZCBpbXBsZW1lbnRhdGlvbgotICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi1wYWNrYWdlIG9yZy5lY2xpcHNlLmVxdWlub3guaW50ZXJuYWwuZHM7Ci0KLS8qKgotICogVGhlIFdvcmtQZXJmb3JtZXIgaW50ZXJmYWNlIGNvbnRhaW5zIGEgbWV0aG9kIHRoYXQgaXMgY2FsbGVkIGJ5IGEgcXVldWUgdG8KLSAqIHBlcmZvcm0gY2VydGFpbiB3b3JrLgotICogCi0gKiBAYXV0aG9yIFBhdmxpbiBEb2JyZXYKLSAqIEB2ZXJzaW9uIDEuMAotICovCi0KLXB1YmxpYyBpbnRlcmZhY2UgV29ya1BlcmZvcm1lciB7Ci0KLQkvKioKLQkgKiBUaGlzIG1ldGhvZCBjYW4gdGhlbiBjb21wbGV0ZSBwcm9jZXNzaW5nIHdvcmsgb24gdGhlIHdvcmsgcXVldWUgdGhyZWFkLgotCSAqIAotCSAqIDxwPgotCSAqIFRoZSBqb2IgcXVldWUgd2lsbCBpZ25vcmUgYW55IFRocm93YWJsZSB0aHJvd24gYnkgdGhpcyBtZXRob2QgaW4gb3JkZXIgdG8KLQkgKiBjb250aW51ZSBwcm9wZXIgZGlzcGF0Y2hpbmcgdGhlIG5leHQgd29yayBpdGVtcy4KLQkgKiAKLQkgKiBAcGFyYW0gYWN0aW9uSWQKLQkgKiAgICAgICAgICAgIEFjdGlvbiBJRCBvZiB0aGUgd29yayB0eXBlIHdoaWNoIGhhcyB0byBiZSBkb25lLgotCSAqIEBwYXJhbSBkYXRhVG9Qcm9jZXNzCi0JICogICAgICAgICAgICBUaGUgZGF0YSB3aGljaCBoYXMgdG8gYmUgcHJvY2Vzc2VkCi0JICovCi0JcHVibGljIHZvaWQgcGVyZm9ybVdvcmsoaW50IGFjdGlvbklkLCBPYmplY3QgZGF0YVRvUHJvY2Vzcyk7Ci19CmRpZmYgLS1naXQgYS9idW5kbGVzL29yZy5lY2xpcHNlLmVxdWlub3guZHMvc3JjL29yZy9lY2xpcHNlL2VxdWlub3gvaW50ZXJuYWwvZHMvV29ya1RocmVhZC5qYXZhIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5lcXVpbm94LmRzL3NyYy9vcmcvZWNsaXBzZS9lcXVpbm94L2ludGVybmFsL2RzL1dvcmtUaHJlYWQuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZWE1MGVmMy4uMDAwMDAwMAotLS0gYS9idW5kbGVzL29yZy5lY2xpcHNlLmVxdWlub3guZHMvc3JjL29yZy9lY2xpcHNlL2VxdWlub3gvaW50ZXJuYWwvZHMvV29ya1RocmVhZC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTExICswLDAgQEAKLS8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTAgYnkgUHJvU3lzdCBTb2Z0d2FyZSBHbWJICi0gKiBodHRwOi8vd3d3LnByb3N5c3QuY29tCi0gKiBBbGwgcmlnaHRzIHJlc2VydmVkLiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzCi0gKiBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYxLjAKLSAqIHdoaWNoIGFjY29tcGFuaWVzIHRoaXMgZGlzdHJpYnV0aW9uLCBhbmQgaXMgYXZhaWxhYmxlIGF0Ci0gKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC12MTAuaHRtbAotICoKLSAqIENvbnRyaWJ1dG9yczoKLSAqICAgIFByb1N5c3QgU29mdHdhcmUgR21iSCAtIGluaXRpYWwgQVBJIGFuZCBpbXBsZW1lbnRhdGlvbgotICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi1wYWNrYWdlIG9yZy5lY2xpcHNlLmVxdWlub3guaW50ZXJuYWwuZHM7Ci0KLWltcG9ydCBvcmcuZWNsaXBzZS5lcXVpbm94LmludGVybmFsLnV0aWwuZXZlbnQuUXVldWU7Ci1pbXBvcnQgb3JnLmVjbGlwc2UuZXF1aW5veC5pbnRlcm5hbC51dGlsLnJlZi5UaW1lclJlZjsKLWltcG9ydCBvcmcuZWNsaXBzZS5lcXVpbm94LmludGVybmFsLnV0aWwudGltZXIuVGltZXJMaXN0ZW5lcjsKLWltcG9ydCBvcmcuZWNsaXBzZS5vc2dpLnV0aWwuTkxTOwotaW1wb3J0IG9yZy5vc2dpLnNlcnZpY2UuY20uQ29uZmlndXJhdGlvbkV2ZW50OwotaW1wb3J0IG9yZy5vc2dpLnNlcnZpY2UubG9nLkxvZ1NlcnZpY2U7Ci0KLS8qKgotICogQGF1dGhvciBTdG95YW4gQm9zaGV2Ci0gKiBAYXV0aG9yIFBhdmxpbiBEb2JyZXYKLSAqLwotCi1wdWJsaWMgY2xhc3MgV29ya1RocmVhZCBpbXBsZW1lbnRzIFJ1bm5hYmxlLCBUaW1lckxpc3RlbmVyIHsKLQotCXB1YmxpYyBzdGF0aWMgaW50IElETEVfVElNRU9VVCA9IDEwMDA7Ci0JcHVibGljIHN0YXRpYyBpbnQgQkxPQ0tfVElNRU9VVCA9IDMwMDAwOwotCXByaXZhdGUgU0NSTWFuYWdlciBtZ3I7Ci0JcHJpdmF0ZSBPYmplY3Qgb2JqZWN0VG9Qcm9jZXNzOwotCWJvb2xlYW4gcnVubmluZyA9IHRydWU7Ci0JVGhyZWFkIHByb2Nlc3NpbmdUaHJlYWQ7Ci0KLQlpbnQgd2FpdGluZyA9IDA7Ci0KLQlwdWJsaWMgV29ya1RocmVhZChTQ1JNYW5hZ2VyIG1ncikgewotCQl0aGlzLm1nciA9IG1ncjsKLQl9Ci0KLQkvKioKLQkgKiBXaGlsZSB0aGUgZXZlbnQgcXVldWUgaGFzIGVsZW1lbnRzIC0gdGhleSBhcmUgcHJvY2Vzc2VkLCBpLmUuCi0JICogTWFuYWdlZFNlcnZpY2UoRmFjdG9yaWVzKSBhcmUgaW5mb3JtZWQgZm9yIHRoZSBldmVudC4KLQkgKi8KLQlwdWJsaWMgdm9pZCBydW4oKSB7Ci0JCXByb2Nlc3NpbmdUaHJlYWQgPSBUaHJlYWQuY3VycmVudFRocmVhZCgpOwotCQlkbyB7Ci0JCQl0cnkgewotCQkJCVF1ZXVlIHF1ZXVlID0gbWdyLnF1ZXVlOwotCQkJCXN5bmNocm9uaXplZCAocXVldWUpIHsKLQkJCQkJaWYgKG1nci5zdG9wcGVkKSB7Ci0JCQkJCQltZ3IucnVubmluZyA9IGZhbHNlOwotCQkJCQkJYnJlYWs7Ci0JCQkJCX0KLQkJCQkJaWYgKEFjdGl2YXRvci5ERUJVRykgewotCQkJCQkJQWN0aXZhdG9yLmxvZy5kZWJ1ZygiV29ya1RocmVhZC5ydW4oKSIsIG51bGwpOyAvLyROT04tTkxTLTEkCi0JCQkJCX0KLQkJCQkJaWYgKHF1ZXVlLnNpemUoKSA9PSAwKSB7IC8vIHdhaXQgZm9yIG1vcmUgZXZlbnRzCi0JCQkJCQl0cnkgewotCQkJCQkJCXdhaXRpbmcrKzsKLQkJCQkJCQlxdWV1ZS53YWl0KElETEVfVElNRU9VVCk7Ci0JCQkJCQl9IGNhdGNoIChFeGNlcHRpb24gaWdub3JlKSB7Ci0JCQkJCQkJLy9pZ25vcmUKLQkJCQkJCX0KLQkJCQkJCXdhaXRpbmctLTsKLQkJCQkJCWlmIChtZ3Iuc3RvcHBlZCB8fCBxdWV1ZS5zaXplKCkgPT0gMCkgewotCQkJCQkJCW1nci5ydW5uaW5nID0gZmFsc2U7Ci0JCQkJCQkJYnJlYWs7Ci0JCQkJCQl9Ci0JCQkJCX0KLQkJCQkJb2JqZWN0VG9Qcm9jZXNzID0gcXVldWUuZ2V0KCk7Ci0KLQkJCQkJaWYgKG9iamVjdFRvUHJvY2VzcyAhPSBudWxsKSB7Ci0JCQkJCQlpZiAoQWN0aXZhdG9yLkRFQlVHKSB7Ci0JCQkJCQkJQWN0aXZhdG9yLmxvZy5kZWJ1ZygiV29ya1RocmVhZC5ydW4oKTogb2JqZWN0IHRvIHByb2Nlc3MgIiArIG9iamVjdFRvUHJvY2Vzcy50b1N0cmluZygpLCBudWxsKTsgLy8kTk9OLU5MUy0xJAotCQkJCQkJfQotCQkJCQl9IGVsc2UgewotCQkJCQkJY29udGludWU7Ci0JCQkJCX0KLQkJCQl9Ci0JCQkJaWYgKFRpbWVyUmVmLnRpbWVyICE9IG51bGwpIHsKLQkJCQkJVGltZXJSZWYubm90aWZ5QWZ0ZXIodGhpcywgQkxPQ0tfVElNRU9VVCwgMSk7Ci0JCQkJfSBlbHNlIHsKLQkJCQkJaWYgKEFjdGl2YXRvci5ERUJVRykgewotCQkJCQkJQWN0aXZhdG9yLmxvZy5kZWJ1ZygiW1NDUl0gV29ya1RocmVhZC5ydW4oKTogVGltZXIgc2VydmljZSBpcyBub3QgYXZhaWxhYmxlISBTa2lwcGluZyB0aW1lb3V0IGNoZWNrIiwgbnVsbCk7IC8vJE5PTi1OTFMtMSQKLQkJCQkJfQotCQkJCX0KLQkJCQlpZiAob2JqZWN0VG9Qcm9jZXNzIGluc3RhbmNlb2YgU0NSTWFuYWdlci5RdWV1ZWRKb2IpIHsKLQkJCQkJKChTQ1JNYW5hZ2VyLlF1ZXVlZEpvYikgb2JqZWN0VG9Qcm9jZXNzKS5kaXNwYXRjaCgpOwotCQkJCX0gZWxzZSBpZiAob2JqZWN0VG9Qcm9jZXNzIGluc3RhbmNlb2YgQ29uZmlndXJhdGlvbkV2ZW50KSB7Ci0JCQkJCW1nci5wcm9jZXNzQ29uZmlndXJhdGlvbkV2ZW50KChDb25maWd1cmF0aW9uRXZlbnQpIG9iamVjdFRvUHJvY2Vzcyk7Ci0JCQkJfQotCQkJfSBjYXRjaCAoVGhyb3dhYmxlIHQpIHsKLQkJCQkvLyBqdXN0IGZvciBhbnkgY2FzZS4gTXVzdCBub3QgaGFwcGVuIGluIG9yZGVyIHRvIGtlZXAgdGhyZWFkIGFsaXZlCi0JCQkJQWN0aXZhdG9yLmxvZyhudWxsLCBMb2dTZXJ2aWNlLkxPR19FUlJPUiwgTWVzc2FnZXMuVU5FWFBFQ1RFRF9FWENFUFRJT04sIHQpOwotCQkJfSBmaW5hbGx5IHsKLQkJCQlUaW1lclJlZi5yZW1vdmVMaXN0ZW5lcih0aGlzLCAxKTsKLQkJCX0KLQkJfSB3aGlsZSAocnVubmluZyk7Ci0JCW9iamVjdFRvUHJvY2VzcyA9IG51bGw7Ci0JCXByb2Nlc3NpbmdUaHJlYWQgPSBudWxsOwotCX0KLQotCXB1YmxpYyB2b2lkIHRpbWVyKGludCBldmVudCkgewotCQlBY3RpdmF0b3IubG9nKG51bGwsIExvZ1NlcnZpY2UuTE9HX1dBUk5JTkcsIE5MUy5iaW5kKE1lc3NhZ2VzLlRJTUVPVVRfUFJPQ0VTU0lORywgb2JqZWN0VG9Qcm9jZXNzKSwgbnVsbCk7Ci0JCXJ1bm5pbmcgPSBmYWxzZTsKLQkJb2JqZWN0VG9Qcm9jZXNzID0gbnVsbDsKLQkJbWdyLnF1ZXVlQmxvY2tlZCgpOwotCX0KLQotfQpkaWZmIC0tZ2l0IGEvYnVuZGxlcy9vcmcuZWNsaXBzZS5lcXVpbm94LmRzL3NyYy9vcmcvZWNsaXBzZS9lcXVpbm94L2ludGVybmFsL2RzL2ltcGwvQ29tcG9uZW50Q29udGV4dEltcGwuamF2YSBiL2J1bmRsZXMvb3JnLmVjbGlwc2UuZXF1aW5veC5kcy9zcmMvb3JnL2VjbGlwc2UvZXF1aW5veC9pbnRlcm5hbC9kcy9pbXBsL0NvbXBvbmVudENvbnRleHRJbXBsLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDU4NjIwNDIuLjAwMDAwMDAKLS0tIGEvYnVuZGxlcy9vcmcuZWNsaXBzZS5lcXVpbm94LmRzL3NyYy9vcmcvZWNsaXBzZS9lcXVpbm94L2ludGVybmFsL2RzL2ltcGwvQ29tcG9uZW50Q29udGV4dEltcGwuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDMyOCArMCwwIEBACi0vKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgotICogQ29weXJpZ2h0IChjKSAxOTk3LTIwMTEgYnkgUHJvU3lzdCBTb2Z0d2FyZSBHbWJICi0gKiBodHRwOi8vd3d3LnByb3N5c3QuY29tCi0gKiBBbGwgcmlnaHRzIHJlc2VydmVkLiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzCi0gKiBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYxLjAKLSAqIHdoaWNoIGFjY29tcGFuaWVzIHRoaXMgZGlzdHJpYnV0aW9uLCBhbmQgaXMgYXZhaWxhYmxlIGF0Ci0gKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC12MTAuaHRtbAotICoKLSAqIENvbnRyaWJ1dG9yczoKLSAqICAgIFByb1N5c3QgU29mdHdhcmUgR21iSCAtIGluaXRpYWwgQVBJIGFuZCBpbXBsZW1lbnRhdGlvbgotICogICAgSm9lcmctQ2hyaXN0aWFuIEJvZWhtZSAtIGJ1Zy5pZCA9IDI0Njc1NwotICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi1wYWNrYWdlIG9yZy5lY2xpcHNlLmVxdWlub3guaW50ZXJuYWwuZHMuaW1wbDsKLQotaW1wb3J0IGphdmEudXRpbC5EaWN0aW9uYXJ5OwotaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7Ci1pbXBvcnQgb3JnLmVjbGlwc2UuZXF1aW5veC5pbnRlcm5hbC5kcy4qOwotaW1wb3J0IG9yZy5lY2xpcHNlLmVxdWlub3guaW50ZXJuYWwuZHMubW9kZWwuKjsKLWltcG9ydCBvcmcuZWNsaXBzZS5vc2dpLnV0aWwuTkxTOwotaW1wb3J0IG9yZy5vc2dpLmZyYW1ld29yay4qOwotaW1wb3J0IG9yZy5vc2dpLnNlcnZpY2UuY29tcG9uZW50Lio7Ci0KLS8qKgotICogQ29tcG9uZW50Q29udGV4dEltcGwuamF2YQotICogCi0gKiBAYXV0aG9yIFZhbGVudGluIFZhbGNoZXYsIE5pbmEgUnVzZXZhCi0gKiBAYXV0aG9yIFN0b3lhbiBCb3NoZXYKLSAqIEBhdXRob3IgUGF2bGluIERvYnJldgotICovCi0KLXB1YmxpYyBjbGFzcyBDb21wb25lbnRDb250ZXh0SW1wbCBpbXBsZW1lbnRzIENvbXBvbmVudENvbnRleHQgewotCi0JLyogQ29tcG9uZW50SW5zdGFuY2UgaW5zdGFuY2UgKi8KLQlwcml2YXRlIENvbXBvbmVudEluc3RhbmNlSW1wbCBjb21wb25lbnRJbnN0YW5jZTsKLQkvKiBDb21wb25lbnREZXNjcmlwdGlvbiAqLwotCXByaXZhdGUgU2VydmljZUNvbXBvbmVudFByb3Agc2NwOwotCi0JcHJpdmF0ZSBCdW5kbGUgdXNpbmdCdW5kbGU7Ci0KLQlwcml2YXRlIFNDUk1hbmFnZXIgbWdyOwotCi0JcHVibGljIENvbXBvbmVudENvbnRleHRJbXBsKFNlcnZpY2VDb21wb25lbnRQcm9wIHNjcCwgQnVuZGxlIHVzaW5nQnVuZGxlLCBDb21wb25lbnRJbnN0YW5jZUltcGwgY2ksIFNDUk1hbmFnZXIgbWdyKSB7Ci0JCXRoaXMuc2NwID0gc2NwOwotCQl0aGlzLmNvbXBvbmVudEluc3RhbmNlID0gY2k7Ci0JCXRoaXMudXNpbmdCdW5kbGUgPSB1c2luZ0J1bmRsZTsKLQkJdGhpcy5tZ3IgPSBtZ3I7Ci0JfQotCi0JLyoKLQkgKiAobm9uLUphdmFkb2MpCi0JICogCi0JICogQHNlZSBvcmcub3NnaS5zZXJ2aWNlLmNvbXBvbmVudC5Db21wb25lbnRDb250ZXh0I2dldFByb3BlcnRpZXMoKQotCSAqLwotCXB1YmxpYyBEaWN0aW9uYXJ5IGdldFByb3BlcnRpZXMoKSB7Ci0JCXJldHVybiBzY3AuZ2V0UHJvcGVydGllcygpOwotCX0KLQotCS8qCi0JICogKG5vbi1KYXZhZG9jKSBSZXR1cm5zIHRoZSBzZXJ2aWNlIG9iamVjdCBmb3IgdGhlIHNwZWNpZmllZCBzZXJ2aWNlCi0JICogcmVmZXJlbmNlIG5hbWUuCi0JICogCi0JICogQHBhcmFtIG5hbWUgVGhlIG5hbWUgb2YgYSBzZXJ2aWNlIHJlZmVyZW5jZSBhcyBzcGVjaWZpZWQgaW4gYSA8Y29kZT5yZWZlcmVuY2U8L2NvZGU+Ci0JICogZWxlbWVudCBpbiB0aGlzIGNvbXBvbmVudCdzIGRlc2NyaXB0aW9uLiBAcmV0dXJuIEEgc2VydmljZSBvYmplY3QgZm9yIHRoZQotCSAqIHJlZmVyZW5jZWQgc2VydmljZSBvciA8Y29kZT5udWxsPC9jb2RlPiBpZiB0aGUgcmVmZXJlbmNlIGNhcmRpbmFsaXR5IGlzCi0JICogPGNvZGU+MC4uMTwvY29kZT4gb3IgPGNvZGU+MC4ubjwvY29kZT4gYW5kIG5vIG1hdGNoaW5nIHNlcnZpY2UgaXMKLQkgKiBhdmFpbGFibGUuIEB0aHJvd3MgQ29tcG9uZW50RXhjZXB0aW9uIElmIHRoZSBTZXJ2aWNlIENvbXBvbmVudCBSdW50aW1lCi0JICogY2F0Y2hlcyBhbiBleGNlcHRpb24gd2hpbGUgYWN0aXZhdGluZyB0aGUgdGFyZ2V0IHNlcnZpY2UuCi0JICogCi0JICogQHNlZSBvcmcub3NnaS5zZXJ2aWNlLmNvbXBvbmVudC5Db21wb25lbnRDb250ZXh0I2xvY2F0ZVNlcnZpY2UoamF2YS5sYW5nLlN0cmluZykKLQkgKi8KLQlwdWJsaWMgT2JqZWN0IGxvY2F0ZVNlcnZpY2UoU3RyaW5nIG5hbWUpIHsKLQkJaWYgKHNjcC5yZWZlcmVuY2VzID09IG51bGwpIHsKLQkJCXJldHVybiBudWxsOwotCQl9Ci0JCWlmIChBY3RpdmF0b3IuREVCVUcpIHsKLQkJCUFjdGl2YXRvci5sb2cuZGVidWcoIkNvbXBvbmVudENvbnRleHRJbXBsLmxvY2F0ZVNlcnZpY2UoKTogIiArIG5hbWUsIG51bGwpOyAvLyROT04tTkxTLTEkCi0JCX0KLQkJVmVjdG9yIHJlZmVyZW5jZXMgPSBzY3AucmVmZXJlbmNlczsKLQkJZm9yIChpbnQgaSA9IDA7IGkgPCByZWZlcmVuY2VzLnNpemUoKTsgaSsrKSB7Ci0JCQlSZWZlcmVuY2UgcmVmZXJlbmNlID0gKFJlZmVyZW5jZSkgcmVmZXJlbmNlcy5lbGVtZW50QXQoaSk7Ci0JCQlDb21wb25lbnRSZWZlcmVuY2UgcmVmID0gcmVmZXJlbmNlLnJlZmVyZW5jZTsKLQotCQkJLy8gZmluZCB0aGUgUmVmZXJlbmNlIERlc2NyaXB0aW9uIHdpdGggdGhlIHNwZWNpZmllZCBuYW1lCi0JCQlpZiAocmVmLm5hbWUuZXF1YWxzKG5hbWUpKSB7Ci0JCQkJU2VydmljZVJlZmVyZW5jZSBzZXJ2aWNlUmVmZXJlbmNlID0gbnVsbDsKLQkJCQlzeW5jaHJvbml6ZWQgKHJlZi5zZXJ2aWNlUmVmZXJlbmNlcykgewotCQkJCQlpZiAocmVmLnNlcnZpY2VSZWZlcmVuY2VzLnNpemUoKSA9PSAxKSB7Ci0JCQkJCQkvL2luIGNhc2Ugb2YgdGhlcmUgaXMgb25seSBvbmUgYm91bmQgc2VydmljZSAob3IgdGhlIHJlZmVyZW5jZSBpcyB1bmFyeSkKLQkJCQkJCXNlcnZpY2VSZWZlcmVuY2UgPSAoU2VydmljZVJlZmVyZW5jZSkgcmVmLnNlcnZpY2VSZWZlcmVuY2VzLmtleXMoKS5uZXh0RWxlbWVudCgpOwotCQkJCQl9Ci0JCQkJfQotCQkJCXRyeSB7Ci0JCQkJCWlmIChzZXJ2aWNlUmVmZXJlbmNlID09IG51bGwpIHsKLQkJCQkJCVZlY3RvciBib3VuZFNlcnZpY2VSZWZlcmVuY2VzID0gcmVmZXJlbmNlLmdldEJvdW5kU2VydmljZVJlZmVyZW5jZXMoKTsKLQkJCQkJCWlmIChyZWZlcmVuY2UuaXNVbmFyeSgpICYmIGJvdW5kU2VydmljZVJlZmVyZW5jZXMuc2l6ZSgpID4gMCkgewotCQkJCQkJCS8vZ2V0IHRoZSBib3VuZCBzZXJ2aWNlIHJlZmVyZW5jZSBmb3IgdGhlIHVuYXJ5IHJlZmVyZW5jZQotCQkJCQkJCXNlcnZpY2VSZWZlcmVuY2UgPSAoU2VydmljZVJlZmVyZW5jZSkgYm91bmRTZXJ2aWNlUmVmZXJlbmNlcy5lbGVtZW50QXQoMCk7Ci0JCQkJCQl9Ci0JCQkJCQlpZiAoc2VydmljZVJlZmVyZW5jZSA9PSBudWxsKSB7Ci0JCQkJCQkJLy8gdHJ5IHRvIGZpbmQgc2VydmljZSBpbiB0aGUgRlcKLQkJCQkJCQlTZXJ2aWNlUmVmZXJlbmNlW10gc2VydmljZVJlZmVyZW5jZXMgPSBzY3AuYmMuZ2V0U2VydmljZVJlZmVyZW5jZXMocmVmLmludGVyZmFjZU5hbWUsIHJlZmVyZW5jZS5nZXRUYXJnZXQoKSk7Ci0JCQkJCQkJaWYgKHNlcnZpY2VSZWZlcmVuY2VzICE9IG51bGwgJiYgc2VydmljZVJlZmVyZW5jZXMubGVuZ3RoID4gMCkgewotCQkJCQkJCQkvLyB0aGUgc2VydmljZXMgcmVmZXJlbmNlcyBhcmUgc29ydGVkIGJ5Ci0JCQkJCQkJCS8vIHNlcnZpY2UucmVmZXJlbmNlIGFuZCBzZXJ2aWNlLmlkCi0JCQkJCQkJCS8vIHNvIGdldCB0aGUgZmlyc3Qgb25lIGluIHRoZSBsaXN0Ci0JCQkJCQkJCXNlcnZpY2VSZWZlcmVuY2UgPSBzZXJ2aWNlUmVmZXJlbmNlc1swXTsKLQkJCQkJCQl9Ci0JCQkJCQl9Ci0JCQkJCX0KLQkJCQkJaWYgKHNlcnZpY2VSZWZlcmVuY2UgIT0gbnVsbCkgewotCQkJCQkJcmV0dXJuIGdldEJvdW5kU2VydmljZShyZWZlcmVuY2UsIHNlcnZpY2VSZWZlcmVuY2UpOwotCQkJCQl9Ci0JCQkJfSBjYXRjaCAoVGhyb3dhYmxlIHQpIHsKLQkJCQkJaWYgKHQgaW5zdGFuY2VvZiBDb21wb25lbnRFeGNlcHRpb24pIHsKLQkJCQkJCXRocm93IChDb21wb25lbnRFeGNlcHRpb24pIHQ7Ci0JCQkJCX0KLQkJCQkJdGhyb3cgbmV3IENvbXBvbmVudEV4Y2VwdGlvbihOTFMuYmluZChNZXNzYWdlcy5FWENFUFRJT05fTE9DQVRJTkdfU0VSVklDRSwgbmFtZSksIHQpOwotCQkJCX0KLQkJCQlpZiAoQWN0aXZhdG9yLkRFQlVHKSB7Ci0JCQkJCUFjdGl2YXRvci5sb2cuZGVidWcoIkNvbXBvbmVudENvbnRleHRJbXBsLmxvY2F0ZVNlcnZpY2UoKTogZXJyb3IsIHNlcnZpY2Ugbm90IGZvdW5kIC0gIiArIHJlZi5pbnRlcmZhY2VOYW1lICsgIjsgdGhlIGNvbXAuIGNvbnRleHQgYmVsb25ncyB0byAiICsgc2NwLm5hbWUsIG51bGwpOyAvLyROT04tTkxTLTEkIC8vJE5PTi1OTFMtMiQKLQkJCQl9Ci0JCQl9Ci0JCX0KLQkJcmV0dXJuIG51bGw7Ci0JfQotCi0JLyoKLQkgKiBSZXR1cm5zIHRoZSBzZXJ2aWNlIG9iamVjdHMgZm9yIHRoZSBzcGVjaWZpZWQgc2VydmljZSByZWZlcmVuY2UgbmFtZS4KLQkgKiAKLQkgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSBvZiBhIHNlcnZpY2UgcmVmZXJlbmNlIGFzIHNwZWNpZmllZCBpbiBhIDxjb2RlPnJlZmVyZW5jZTwvY29kZT4KLQkgKiBlbGVtZW50IGluIHRoaXMgY29tcG9uZW50J3MgZGVzY3JpcHRpb24uIEByZXR1cm4gQW4gYXJyYXkgb2Ygc2VydmljZQotCSAqIG9iamVjdHMgZm9yIHRoZSByZWZlcmVuY2VkIHNlcnZpY2Ugb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYgdGhlCi0JICogcmVmZXJlbmNlIGNhcmRpbmFsaXR5IGlzIDxjb2RlPjAuLjE8L2NvZGU+IG9yIDxjb2RlPjAuLm48L2NvZGU+IGFuZAotCSAqIG5vIG1hdGNoaW5nIHNlcnZpY2UgaXMgYXZhaWxhYmxlLgotCSAqIAotCSAqIEB0aHJvd3MgQ29tcG9uZW50RXhjZXB0aW9uIElmIHRoZSBTZXJ2aWNlIENvbXBvbmVudCBSdW50aW1lIGNhdGNoZXMgYW4KLQkgKiBleGNlcHRpb24gd2hpbGUgYWN0aXZhdGluZyBhIHRhcmdldCBzZXJ2aWNlLgotCSAqIAotCSAqIEBzZWUgb3JnLm9zZ2kuc2VydmljZS5jb21wb25lbnQuQ29tcG9uZW50Q29udGV4dCNsb2NhdGVTZXJ2aWNlcyhqYXZhLmxhbmcuU3RyaW5nKQotCSAqLwotCXB1YmxpYyBPYmplY3RbXSBsb2NhdGVTZXJ2aWNlcyhTdHJpbmcgbmFtZSkgewotCQlpZiAoc2NwLnJlZmVyZW5jZXMgPT0gbnVsbCkgewotCQkJcmV0dXJuIG51bGw7Ci0JCX0KLQotCQlpZiAoQWN0aXZhdG9yLkRFQlVHKSB7Ci0JCQlBY3RpdmF0b3IubG9nLmRlYnVnKCJDb21wb25lbnRDb250ZXh0SW1wbC5sb2NhdGVTZXJ2aWNlcygpOiAiICsgbmFtZSwgbnVsbCk7IC8vJE5PTi1OTFMtMSQKLQkJfQotCQlWZWN0b3IgcmVmZXJlbmNlcyA9IHNjcC5yZWZlcmVuY2VzOwotCQlmb3IgKGludCBpID0gMDsgaSA8IHJlZmVyZW5jZXMuc2l6ZSgpOyBpKyspIHsKLQkJCVJlZmVyZW5jZSByZWZlcmVuY2UgPSAoUmVmZXJlbmNlKSByZWZlcmVuY2VzLmVsZW1lbnRBdChpKTsKLQkJCUNvbXBvbmVudFJlZmVyZW5jZSByZWYgPSByZWZlcmVuY2UucmVmZXJlbmNlOwotCi0JCQlpZiAocmVmLm5hbWUuZXF1YWxzKG5hbWUpKSB7Ci0JCQkJU2VydmljZVJlZmVyZW5jZVtdIHNlcnZpY2VSZWZlcmVuY2VzID0gbnVsbDsKLQkJCQl0cnkgewotCQkJCQlpZiAocmVmZXJlbmNlLmlzVW5hcnkoKSkgewotCQkJCQkJU2VydmljZVJlZmVyZW5jZSBzZXJ2aWNlUmVmZXJlbmNlID0gbnVsbDsKLQkJCQkJCXN5bmNocm9uaXplZCAocmVmLnNlcnZpY2VSZWZlcmVuY2VzKSB7Ci0JCQkJCQkJaWYgKHJlZi5zZXJ2aWNlUmVmZXJlbmNlcy5zaXplKCkgPiAwKSB7Ci0JCQkJCQkJCS8vaW4gY2FzZSB0aGUgcmVmZXJlbmNlIGlzIHVuYXJ5Ci0JCQkJCQkJCXNlcnZpY2VSZWZlcmVuY2UgPSAoU2VydmljZVJlZmVyZW5jZSkgcmVmLnNlcnZpY2VSZWZlcmVuY2VzLmtleXMoKS5uZXh0RWxlbWVudCgpOwotCQkJCQkJCX0KLQkJCQkJCX0KLQkJCQkJCWlmIChzZXJ2aWNlUmVmZXJlbmNlID09IG51bGwpIHsKLQkJCQkJCQlWZWN0b3IgYm91bmRTZXJ2aWNlUmVmZXJlbmNlcyA9IHJlZmVyZW5jZS5nZXRCb3VuZFNlcnZpY2VSZWZlcmVuY2VzKCk7Ci0JCQkJCQkJaWYgKGJvdW5kU2VydmljZVJlZmVyZW5jZXMuc2l6ZSgpID4gMCkgewotCQkJCQkJCQkvL2dldCB0aGUgYm91bmQgc2VydmljZSByZWZlcmVuY2UgZm9yIHRoZSB1bmFyeSByZWZlcmVuY2UKLQkJCQkJCQkJc2VydmljZVJlZmVyZW5jZSA9IChTZXJ2aWNlUmVmZXJlbmNlKSBib3VuZFNlcnZpY2VSZWZlcmVuY2VzLmVsZW1lbnRBdCgwKTsKLQkJCQkJCQl9Ci0JCQkJCQl9Ci0JCQkJCQlpZiAoc2VydmljZVJlZmVyZW5jZSAhPSBudWxsKSB7Ci0JCQkJCQkJT2JqZWN0IHJlc3VsdCA9IGdldEJvdW5kU2VydmljZShyZWZlcmVuY2UsIHNlcnZpY2VSZWZlcmVuY2UpOwotCQkJCQkJCWlmIChyZXN1bHQgIT0gbnVsbCkgewotCQkJCQkJCQlyZXR1cm4gbmV3IE9iamVjdFtdIHtyZXN1bHR9OwotCQkJCQkJCX0KLQkJCQkJCX0KLQkJCQkJfQotCQkJCQlzZXJ2aWNlUmVmZXJlbmNlcyA9IHNjcC5iYy5nZXRTZXJ2aWNlUmVmZXJlbmNlcyhyZWYuaW50ZXJmYWNlTmFtZSwgcmVmZXJlbmNlLmdldFRhcmdldCgpKTsKLQkJCQkJaWYgKHNlcnZpY2VSZWZlcmVuY2VzICE9IG51bGwpIHsKLQkJCQkJCVZlY3RvciB0aGVTZXJ2aWNlcyA9IG5ldyBWZWN0b3IoNSk7Ci0JCQkJCQlPYmplY3Qgc2VydmljZTsKLQkJCQkJCWZvciAoaW50IGogPSAwOyBqIDwgc2VydmljZVJlZmVyZW5jZXMubGVuZ3RoOyBqKyspIHsKLQkJCQkJCQlzZXJ2aWNlID0gZ2V0Qm91bmRTZXJ2aWNlKHJlZmVyZW5jZSwgc2VydmljZVJlZmVyZW5jZXNbal0pOwotCQkJCQkJCWlmIChzZXJ2aWNlICE9IG51bGwpIHsKLQkJCQkJCQkJdGhlU2VydmljZXMuYWRkRWxlbWVudChzZXJ2aWNlKTsKLQkJCQkJCQl9Ci0JCQkJCQl9Ci0JCQkJCQlpZiAoIXRoZVNlcnZpY2VzLmlzRW1wdHkoKSkgewotCQkJCQkJCXJldHVybiB0aGVTZXJ2aWNlcy50b0FycmF5KCk7Ci0JCQkJCQl9Ci0JCQkJCX0KLQkJCQl9IGNhdGNoIChUaHJvd2FibGUgdCkgewotCQkJCQlpZiAodCBpbnN0YW5jZW9mIENvbXBvbmVudEV4Y2VwdGlvbikgewotCQkJCQkJdGhyb3cgKENvbXBvbmVudEV4Y2VwdGlvbikgdDsKLQkJCQkJfQotCQkJCQl0aHJvdyBuZXcgQ29tcG9uZW50RXhjZXB0aW9uKE5MUy5iaW5kKE1lc3NhZ2VzLkVYQ0VQVElPTl9MT0NBVElOR19TRVJWSUNFUywgbmFtZSksIHQpOwotCQkJCX0KLQkJCX0KLQkJfQotCQlyZXR1cm4gbnVsbDsKLQl9Ci0KLQkvKgotCSAqIChub24tSmF2YWRvYykKLQkgKiAKLQkgKiBAc2VlIG9yZy5vc2dpLnNlcnZpY2UuY29tcG9uZW50LkNvbXBvbmVudENvbnRleHQjbG9jYXRlU2VydmljZShTdHJpbmcKLQkgKiAgICAgIG5hbWUsIFNlcnZpY2VSZWZlcmVuY2UgcmVmZXJlbmNlKQotCSAqLwotCXB1YmxpYyBPYmplY3QgbG9jYXRlU2VydmljZShTdHJpbmcgbmFtZSwgU2VydmljZVJlZmVyZW5jZSBzZXJ2aWNlUmVmZXJlbmNlKSB7Ci0JCWlmIChzY3AucmVmZXJlbmNlcyA9PSBudWxsKSB7Ci0JCQlyZXR1cm4gbnVsbDsKLQkJfQotCQlpZiAoQWN0aXZhdG9yLkRFQlVHKSB7Ci0JCQlBY3RpdmF0b3IubG9nLmRlYnVnKCJDb21wb25lbnRDb250ZXh0SW1wbC5sb2NhdGVTZXJ2aWNlKCk6ICIgKyBuYW1lICsgIiBieSBzZXJ2aWNlIHJlZmVyZW5jZSA6ICIgKyBzZXJ2aWNlUmVmZXJlbmNlLCBudWxsKTsgLy8kTk9OLU5MUy0xJCAvLyROT04tTkxTLTIkCi0JCX0KLQkJVmVjdG9yIHJlZmVyZW5jZXMgPSBzY3AucmVmZXJlbmNlczsKLQkJdHJ5IHsKLQkJCWZvciAoaW50IGkgPSAwOyBpIDwgcmVmZXJlbmNlcy5zaXplKCk7IGkrKykgewotCQkJCVJlZmVyZW5jZSByZWZlcmVuY2UgPSAoUmVmZXJlbmNlKSByZWZlcmVuY2VzLmVsZW1lbnRBdChpKTsKLQkJCQlDb21wb25lbnRSZWZlcmVuY2UgcmVmID0gcmVmZXJlbmNlLnJlZmVyZW5jZTsKLQotCQkJCWlmIChyZWYubmFtZS5lcXVhbHMobmFtZSkpIHsKLQkJCQkJaWYgKHNlcnZpY2VSZWZlcmVuY2UgPT0gbnVsbCB8fCAhcmVmLnNlcnZpY2VSZWZlcmVuY2VzLmNvbnRhaW5zS2V5KHNlcnZpY2VSZWZlcmVuY2UpKSB7Ci0JCQkJCQkvLyB0aGUgc2VydmljZVJlZmVyZW5jZSBpcyBub3QgYm91bmQgdG8gdGhlIHNwZWNpZmllZAotCQkJCQkJLy8gcmVmZXJlbmNlCi0JCQkJCQlpZiAoQWN0aXZhdG9yLkRFQlVHKSB7Ci0JCQkJCQkJU3RyaW5nIHJlZmVyZW5jZVRvU3RyaW5nID0gKHNlcnZpY2VSZWZlcmVuY2UgPT0gbnVsbCkgPyBudWxsIDogc2VydmljZVJlZmVyZW5jZS50b1N0cmluZygpOwotCQkJCQkJCUFjdGl2YXRvci5sb2cuZGVidWcoIkNvbXBvbmVudENvbnRleHRJbXBsLmxvY2F0ZVNlcnZpY2UoKTogdGhlIHNwZWNpZmllZCBzZXJ2aWNlIHJlZmVyZW5jZSBpcyBub3QgYm91bmQgdG8gdGhlIHNwZWNpZmllZCByZWZlcmVuY2UiICsgcmVmZXJlbmNlVG9TdHJpbmcsIG51bGwpOyAvLyROT04tTkxTLTEkCi0JCQkJCQl9Ci0JCQkJCQlyZXR1cm4gbnVsbDsKLQkJCQkJfQotCQkJCQlyZXR1cm4gZ2V0Qm91bmRTZXJ2aWNlKHJlZmVyZW5jZSwgc2VydmljZVJlZmVyZW5jZSk7Ci0JCQkJfQotCQkJfQotCQl9IGNhdGNoIChUaHJvd2FibGUgdCkgewotCQkJaWYgKHQgaW5zdGFuY2VvZiBDb21wb25lbnRFeGNlcHRpb24pIHsKLQkJCQl0aHJvdyAoQ29tcG9uZW50RXhjZXB0aW9uKSB0OwotCQkJfQotCQkJdGhyb3cgbmV3IENvbXBvbmVudEV4Y2VwdGlvbihOTFMuYmluZChNZXNzYWdlcy5FWENFUFRJT05fTE9DQVRJTkdfU0VSVklDRSwgbmFtZSksIHQpOwotCQl9Ci0JCXJldHVybiBudWxsOwotCX0KLQotCXByaXZhdGUgT2JqZWN0IGdldEJvdW5kU2VydmljZShSZWZlcmVuY2UgcmVmZXJlbmNlLCBTZXJ2aWNlUmVmZXJlbmNlIHRoZVNlcnZpY2VSZWZlcmVuY2UpIHsKLQkJT2JqZWN0IHJlc3VsdCA9IGNvbXBvbmVudEluc3RhbmNlLmJpbmRlZFNlcnZpY2VzLmdldCh0aGVTZXJ2aWNlUmVmZXJlbmNlKTsKLQkJaWYgKHJlc3VsdCAhPSBudWxsKSB7Ci0JCQkvLyB3aWxsIHNraXAgdGhlIGNpcmN1bGFyaXR5IGNoZWNraW5nIGluIEluc3RhbmNlUHJvY2Vzcy5nZXRTZXJ2aWNlCi0JCQlyZXR1cm4gcmVzdWx0OwotCQl9Ci0JCXJlc3VsdCA9IEluc3RhbmNlUHJvY2Vzcy5zdGF0aWNSZWYuZ2V0U2VydmljZShyZWZlcmVuY2UsIHRoZVNlcnZpY2VSZWZlcmVuY2UpOwotCQkvLyB0aGUgc2VydmljZSBvYmplY3QgY291bGQgYmUgbnVsbCBiZWNhdXNlIG9mIGNpcmN1bGFyaXR5Ci0JCWlmIChyZXN1bHQgIT0gbnVsbCkgewotCQkJY29tcG9uZW50SW5zdGFuY2UuYmluZGVkU2VydmljZXMucHV0KHRoZVNlcnZpY2VSZWZlcmVuY2UsIHJlc3VsdCk7Ci0JCQlyZXR1cm4gcmVzdWx0OwotCQl9Ci0JCXJldHVybiBudWxsOwotCX0KLQotCS8qCi0JICogKG5vbi1KYXZhZG9jKQotCSAqIAotCSAqIEBzZWUgb3JnLm9zZ2kuc2VydmljZS5jb21wb25lbnQuQ29tcG9uZW50Q29udGV4dCNnZXRCdW5kbGVDb250ZXh0KCkKLQkgKi8KLQlwdWJsaWMgQnVuZGxlQ29udGV4dCBnZXRCdW5kbGVDb250ZXh0KCkgewotCQlyZXR1cm4gc2NwLmJjOwotCX0KLQotCS8qCi0JICogKG5vbi1KYXZhZG9jKQotCSAqIAotCSAqIEBzZWUgb3JnLm9zZ2kuc2VydmljZS5jb21wb25lbnQuQ29tcG9uZW50Q29udGV4dCNnZXRVc2luZ0J1bmRsZSgpCi0JICovCi0JcHVibGljIEJ1bmRsZSBnZXRVc2luZ0J1bmRsZSgpIHsKLQkJLy8gdGhpcyBpcyBvbmx5IGZvciBzZXJ2aWNlIGZhY3RvcmllcyEKLQkJU2VydmljZUNvbXBvbmVudCBjb21wb25lbnREZXNjcmlwdGlvbiA9IHNjcC5zZXJ2aWNlQ29tcG9uZW50OwotCQlpZiAoKGNvbXBvbmVudERlc2NyaXB0aW9uLnByb3ZpZGVzID09IG51bGwpIHx8ICghY29tcG9uZW50RGVzY3JpcHRpb24uc2VydmljZUZhY3RvcnkpKSB7Ci0JCQlyZXR1cm4gbnVsbDsKLQkJfQotCQlyZXR1cm4gdXNpbmdCdW5kbGU7Ci0JfQotCi0JLyoKLQkgKiAobm9uLUphdmFkb2MpCi0JICogCi0JICogQHNlZSBvcmcub3NnaS5zZXJ2aWNlLmNvbXBvbmVudC5Db21wb25lbnRDb250ZXh0I2dldENvbXBvbmVudEluc3RhbmNlKCkKLQkgKi8KLQlwdWJsaWMgQ29tcG9uZW50SW5zdGFuY2UgZ2V0Q29tcG9uZW50SW5zdGFuY2UoKSB7Ci0JCXJldHVybiBjb21wb25lbnRJbnN0YW5jZTsKLQl9Ci0KLQkvKgotCSAqIChub24tSmF2YWRvYykKLQkgKiAKLQkgKiBAc2VlIG9yZy5vc2dpLnNlcnZpY2UuY29tcG9uZW50LkNvbXBvbmVudENvbnRleHQjZW5hYmxlQ29tcG9uZW50KGphdmEubGFuZy5TdHJpbmcpCi0JICovCi0JcHVibGljIHZvaWQgZW5hYmxlQ29tcG9uZW50KFN0cmluZyBuYW1lKSB7Ci0JCW1nci5lbmFibGVDb21wb25lbnQobmFtZSwgc2NwLmJjLmdldEJ1bmRsZSgpKTsKLQl9Ci0KLQkvKgotCSAqIChub24tSmF2YWRvYykKLQkgKiAKLQkgKiBAc2VlIG9yZy5vc2dpLnNlcnZpY2UuY29tcG9uZW50LkNvbXBvbmVudENvbnRleHQjZGlzYWJsZUNvbXBvbmVudChqYXZhLmxhbmcuU3RyaW5nKQotCSAqLwotCXB1YmxpYyB2b2lkIGRpc2FibGVDb21wb25lbnQoU3RyaW5nIG5hbWUpIHsKLQkJaWYgKG5hbWUgPT0gbnVsbCkgewotCQkJdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihNZXNzYWdlcy5DT01QT05FTlRfTkFNRV9JU19OVUxMKTsKLQkJfQotCQltZ3IuZGlzYWJsZUNvbXBvbmVudChuYW1lLCBzY3AuYmMuZ2V0QnVuZGxlKCkpOwotCX0KLQotCS8qCi0JICogKG5vbi1KYXZhZG9jKQotCSAqIAotCSAqIEBzZWUgb3JnLm9zZ2kuc2VydmljZS5jb21wb25lbnQuQ29tcG9uZW50Q29udGV4dCNnZXRTZXJ2aWNlUmVmZXJlbmNlKCkKLQkgKi8KLQlwdWJsaWMgU2VydmljZVJlZmVyZW5jZSBnZXRTZXJ2aWNlUmVmZXJlbmNlKCkgewotCQlpZiAoc2NwLnNlcnZpY2VDb21wb25lbnQucHJvdmlkZXMgIT0gbnVsbCkgewotCQkJU2VydmljZVJlZ2lzdHJhdGlvbiByZWcgPSBzY3AucmVnaXN0cmF0aW9uOwotCQkJaWYgKHJlZyAhPSBudWxsKSB7Ci0JCQkJcmV0dXJuIHJlZy5nZXRSZWZlcmVuY2UoKTsKLQkJCX0KLQkJfQotCQlyZXR1cm4gbnVsbDsKLQl9Ci0KLX0KZGlmZiAtLWdpdCBhL2J1bmRsZXMvb3JnLmVjbGlwc2UuZXF1aW5veC5kcy9zcmMvb3JnL2VjbGlwc2UvZXF1aW5veC9pbnRlcm5hbC9kcy9pbXBsL0NvbXBvbmVudEZhY3RvcnlJbXBsLmphdmEgYi9idW5kbGVzL29yZy5lY2xpcHNlLmVxdWlub3guZHMvc3JjL29yZy9lY2xpcHNlL2VxdWlub3gvaW50ZXJuYWwvZHMvaW1wbC9Db21wb25lbnRGYWN0b3J5SW1wbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA5YTNkOGUyLi4wMDAwMDAwCi0tLSBhL2J1bmRsZXMvb3JnLmVjbGlwc2UuZXF1aW5veC5kcy9zcmMvb3JnL2VjbGlwc2UvZXF1aW5veC9pbnRlcm5hbC9kcy9pbXBsL0NvbXBvbmVudEZhY3RvcnlJbXBsLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMTcgKzAsMCBAQAotLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKLSAqIENvcHlyaWdodCAoYykgMTk5Ny0yMDExIGJ5IFByb1N5c3QgU29mdHdhcmUgR21iSAotICogaHR0cDovL3d3dy5wcm9zeXN0LmNvbQotICogQWxsIHJpZ2h0cyByZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscwotICogYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2MS4wCi0gKiB3aGljaCBhY2NvbXBhbmllcyB0aGlzIGRpc3RyaWJ1dGlvbiwgYW5kIGlzIGF2YWlsYWJsZSBhdAotICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtdjEwLmh0bWwKLSAqCi0gKiBDb250cmlidXRvcnM6Ci0gKiAgICBQcm9TeXN0IFNvZnR3YXJlIEdtYkggLSBpbml0aWFsIEFQSSBhbmQgaW1wbGVtZW50YXRpb24KLSAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwotcGFja2FnZSBvcmcuZWNsaXBzZS5lcXVpbm94LmludGVybmFsLmRzLmltcGw7Ci0KLWltcG9ydCBqYXZhLnV0aWwuKjsKLWltcG9ydCBvcmcuYXBhY2hlLmZlbGl4LnNjci5Db21wb25lbnQ7Ci1pbXBvcnQgb3JnLmVjbGlwc2UuZXF1aW5veC5pbnRlcm5hbC5kcy4qOwotaW1wb3J0IG9yZy5lY2xpcHNlLmVxdWlub3guaW50ZXJuYWwuZHMubW9kZWwuU2VydmljZUNvbXBvbmVudFByb3A7Ci1pbXBvcnQgb3JnLm9zZ2kuc2VydmljZS5jb21wb25lbnQuKjsKLWltcG9ydCBvcmcub3NnaS5zZXJ2aWNlLmxvZy5Mb2dTZXJ2aWNlOwotCi0vKioKLSAqIENvbXBvbmVudEZhY3RvcnlJbXBsLmphdmEKLSAqIAotICogQGF1dGhvciBWYWxlbnRpbiBWYWxjaGV2Ci0gKiBAYXV0aG9yIFN0b3lhbiBCb3NoZXYKLSAqIEBhdXRob3IgUGF2bGluIERvYnJldgotICovCi0KLXB1YmxpYyBjbGFzcyBDb21wb25lbnRGYWN0b3J5SW1wbCBpbXBsZW1lbnRzIENvbXBvbmVudEZhY3RvcnkgewotCi0JcHJpdmF0ZSBTZXJ2aWNlQ29tcG9uZW50UHJvcCBzY2k7Ci0KLQkvKioKLQkgKiBDb21wb25lbnRGYWN0b3J5SW1wbAotCSAqIAotCSAqIEBwYXJhbSBjb21wb25lbnQKLQkgKiAgICAgICAgICAgIHRoZSBDb21wb25lbnREZXNjcmlwdGlvbiBPYmplY3Qgd2l0aCBQcm9wZXJ0aWVzCi0JICovCi0JcHVibGljIENvbXBvbmVudEZhY3RvcnlJbXBsKFNlcnZpY2VDb21wb25lbnRQcm9wIGNvbXBvbmVudCkgewotCQl0aGlzLnNjaSA9IGNvbXBvbmVudDsKLQl9Ci0KLQkvKioKLQkgKiBDcmVhdGUgYSBuZXcgaW5zdGFuY2Ugb2YgdGhlIGNvbXBvbmVudC4gQWRkaXRpb25hbCBwcm9wZXJ0aWVzIG1heSBiZQotCSAqIHByb3ZpZGVkIGZvciB0aGUgY29tcG9uZW50IGluc3RhbmNlLgotCSAqIAotCSAqIEBwYXJhbSBhZGRpdGlvbmFsUHJvcHMKLQkgKiAgICAgICAgICAgIEFkZGl0aW9uYWwgcHJvcGVydGllcyBmb3IgdGhlIGNvbXBvbmVudCBpbnN0YW5jZS4KLQkgKiBAcmV0dXJuIEEgQ29tcG9uZW50SW5zdGFuY2Ugb2JqZWN0IGVuY2Fwc3VsYXRpbmcgdGhlIGNvbXBvbmVudCBpbnN0YW5jZS4KLQkgKiAgICAgICAgIFRoZSByZXR1cm5lZCBjb21wb25lbnQgaW5zdGFuY2UgaGFzIGJlZW4gYWN0aXZhdGVkLgotCSAqLwotCXB1YmxpYyBDb21wb25lbnRJbnN0YW5jZSBuZXdJbnN0YW5jZShEaWN0aW9uYXJ5IGFkZGl0aW9uYWxQcm9wcykgewotCQlDb21wb25lbnRJbnN0YW5jZUltcGwgaW5zdGFuY2UgPSBudWxsOwotCQlTZXJ2aWNlQ29tcG9uZW50UHJvcCBuZXdTQ1AgPSBudWxsOwotCQl0cnkgewotCQkJaWYgKEFjdGl2YXRvci5ERUJVRykgewotCQkJCUFjdGl2YXRvci5sb2cuZGVidWcoIkNvbXBvbmVudEZhY3RvcnlJbXBsLm5ld0luc3RhbmNlKCk6ICIgKyBzY2kubmFtZSwgbnVsbCk7IC8vJE5PTi1OTFMtMSQKLQkJCX0KLQotCQkJLy8gbWVyZ2UgcHJvcGVydGllcwotCQkJSGFzaHRhYmxlIHByb3BzID0gbmV3IEhhc2h0YWJsZSgoTWFwKSBzY2kuZ2V0UHJvcGVydGllcygpKTsKLQkJCVNDUlV0aWwuY29weVRvKHByb3BzLCBhZGRpdGlvbmFsUHJvcHMpOwotCi0JCQkvLyBjcmVhdGUgYSBuZXcgU0NQIChhZGRzIHRvIHJlc29sdmVyIHNjcEVuYWJsZWQgbGlzdCkKLQkJCW5ld1NDUCA9IEluc3RhbmNlUHJvY2Vzcy5yZXNvbHZlci5tYXBOZXdGYWN0b3J5Q29tcG9uZW50KHNjaS5zZXJ2aWNlQ29tcG9uZW50LCBwcm9wcyk7Ci0KLQkJCS8vIHJlZ2lzdGVyIHRoZSBjb21wb25lbnQgYW5kIG1ha2UgaW5zdGFuY2UgaWYgaW1tZWRpYXRlCi0JCQlWZWN0b3IgdG9CdWlsZCA9IG5ldyBWZWN0b3IoMSk7Ci0JCQl0b0J1aWxkLmFkZEVsZW1lbnQobmV3U0NQKTsKLQkJCUluc3RhbmNlUHJvY2Vzcy5zdGF0aWNSZWYuYnVpbGRDb21wb25lbnRzKHRvQnVpbGQsIEFjdGl2YXRvci5zZWN1cml0eSk7Ci0JCQlpZiAoIW5ld1NDUC5pbnN0YW5jZXMuaXNFbXB0eSgpKSB7Ci0JCQkJLy8gYW4gaW5zdGFuY2Ugd2FzIGJ1aWx0IGJlY2F1c2UgdGhlIGNvbXBvbmVudCBpcyBlaXRoZXIKLQkJCQkvLyBpbW1lZGlhdGUKLQkJCQkvLyBvciBzb21lb25lIGhhcyBnb3QgaXQgYXMgc2VydmljZSAoaWYgcHJvdmlkZXMgb25lKQotCQkJCWluc3RhbmNlID0gKENvbXBvbmVudEluc3RhbmNlSW1wbCkgbmV3U0NQLmluc3RhbmNlcy5maXJzdEVsZW1lbnQoKTsKLQkJCX0KLQkJCWlmIChpbnN0YW5jZSA9PSBudWxsICYmICFuZXdTQ1AuaXNJbW1lZGlhdGUoKSkgewotCQkJCS8vIGZpbmFsbHkgYnVpbGQgYW4gaW5zdGFuY2UgaWYgbm90IGRvbmUgeWV0Ci0JCQkJaW5zdGFuY2UgPSBJbnN0YW5jZVByb2Nlc3Muc3RhdGljUmVmLmJ1aWxkQ29tcG9uZW50KG51bGwsIG5ld1NDUCwgbnVsbCwgQWN0aXZhdG9yLnNlY3VyaXR5KTsKLQkJCX0KLQkJCWlmIChpbnN0YW5jZSA9PSBudWxsKSB7Ci0JCQkJLy90aGUgaW5zdGFuY2UgY291bGQgbm90IGJlIGJ1aWxkIGJlY2F1c2UgdGhlIGNvbXBvbmVudCBjYW5ub3QgYmUgYWN0aXZhdGVkCi0JCQkJLy90aHJvdyBleGNlcHRpb24gdG8gbm90aWZ5IHRoZSB1c2VyCi0JCQkJdGhyb3cgbmV3IENvbXBvbmVudEV4Y2VwdGlvbihNZXNzYWdlcy5DT1VMRF9OT1RfQ1JFQVRFX05FV19JTlNUQU5DRSk7Ci0JCQl9Ci0JCX0gY2F0Y2ggKFRocm93YWJsZSBlKSB7Ci0JCQkvL3JlbW92ZSB0aGUgY29tcG9uZW50IGNvbmZpZ3VyYXRpb24KLQkJCWlmIChuZXdTQ1AgIT0gbnVsbCkgewotCQkJCWRpc3Bvc2VTQ1AobmV3U0NQKTsKLQkJCX0KLQkJCWlmIChlIGluc3RhbmNlb2YgQ29tcG9uZW50RXhjZXB0aW9uKSB7Ci0JCQkJdGhyb3cgKENvbXBvbmVudEV4Y2VwdGlvbikgZTsKLQkJCX0KLQkJCUFjdGl2YXRvci5sb2cobnVsbCwgTG9nU2VydmljZS5MT0dfRVJST1IsICJDb21wb25lbnRGYWN0b3J5SW1wbC5uZXdJbnN0YW5jZSgpOiBmYWlsZWQgZm9yICIgKyBzY2kubmFtZSArICIgd2l0aCBwcm9wZXJ0aWVzICIgKyBhZGRpdGlvbmFsUHJvcHMsIGUpOyAvLyROT04tTkxTLTEkIC8vJE5PTi1OTFMtMiQKLQkJCXRocm93IG5ldyBDb21wb25lbnRFeGNlcHRpb24oTWVzc2FnZXMuQ09VTERfTk9UX0NSRUFURV9ORVdfSU5TVEFOQ0UsIGUpOwotCQl9Ci0JCXJldHVybiBpbnN0YW5jZTsKLQl9Ci0KLQlwcml2YXRlIHZvaWQgZGlzcG9zZVNDUChTZXJ2aWNlQ29tcG9uZW50UHJvcCBzY3ApIHsKLQkJc2NwLnNlcnZpY2VDb21wb25lbnQuY29tcG9uZW50UHJvcHMucmVtb3ZlRWxlbWVudChzY3ApOwotCQlWZWN0b3IgdG9EaXNwb3NlID0gbmV3IFZlY3RvcigxKTsKLQkJdG9EaXNwb3NlLmFkZEVsZW1lbnQoc2NwKTsKLQkJSW5zdGFuY2VQcm9jZXNzLnJlc29sdmVyLmRpc3Bvc2VDb21wb25lbnRDb25maWdzKHRvRGlzcG9zZSwgQ29tcG9uZW50Q29uc3RhbnRzLkRFQUNUSVZBVElPTl9SRUFTT05fVU5TUEVDSUZJRUQpOwotCQlzY3Auc2V0U3RhdGUoQ29tcG9uZW50LlNUQVRFX0RJU1BPU0VEKTsKLQl9Ci0KLQkvKgotCSAqIChub24tSmF2YWRvYykKLQkgKiAKLQkgKiBAc2VlIGphdmEubGFuZy5PYmplY3QjdG9TdHJpbmcoKQotCSAqLwotCXB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7Ci0JCXJldHVybiAiQ29tcG9uZW50RmFjdG9yeSBmb3IgIiArIHNjaS5uYW1lOyAvLyROT04tTkxTLTEkCi0JfQotCi19CmRpZmYgLS1naXQgYS9idW5kbGVzL29yZy5lY2xpcHNlLmVxdWlub3guZHMvc3JjL29yZy9lY2xpcHNlL2VxdWlub3gvaW50ZXJuYWwvZHMvaW1wbC9Db21wb25lbnRJbnN0YW5jZUltcGwuamF2YSBiL2J1bmRsZXMvb3JnLmVjbGlwc2UuZXF1aW5veC5kcy9zcmMvb3JnL2VjbGlwc2UvZXF1aW5veC9pbnRlcm5hbC9kcy9pbXBsL0NvbXBvbmVudEluc3RhbmNlSW1wbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBmYmQzYjAyLi4wMDAwMDAwCi0tLSBhL2J1bmRsZXMvb3JnLmVjbGlwc2UuZXF1aW5veC5kcy9zcmMvb3JnL2VjbGlwc2UvZXF1aW5veC9pbnRlcm5hbC9kcy9pbXBsL0NvbXBvbmVudEluc3RhbmNlSW1wbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTA3ICswLDAgQEAKLS8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTAgYnkgUHJvU3lzdCBTb2Z0d2FyZSBHbWJICi0gKiBodHRwOi8vd3d3LnByb3N5c3QuY29tCi0gKiBBbGwgcmlnaHRzIHJlc2VydmVkLiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzCi0gKiBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYxLjAKLSAqIHdoaWNoIGFjY29tcGFuaWVzIHRoaXMgZGlzdHJpYnV0aW9uLCBhbmQgaXMgYXZhaWxhYmxlIGF0Ci0gKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC12MTAuaHRtbAotICoKLSAqIENvbnRyaWJ1dG9yczoKLSAqICAgIFByb1N5c3QgU29mdHdhcmUgR21iSCAtIGluaXRpYWwgQVBJIGFuZCBpbXBsZW1lbnRhdGlvbgotICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi1wYWNrYWdlIG9yZy5lY2xpcHNlLmVxdWlub3guaW50ZXJuYWwuZHMuaW1wbDsKLQotaW1wb3J0IGphdmEudXRpbC4qOwotaW1wb3J0IG9yZy5hcGFjaGUuZmVsaXguc2NyLkNvbXBvbmVudDsKLWltcG9ydCBvcmcuZWNsaXBzZS5lcXVpbm94LmludGVybmFsLmRzLkFjdGl2YXRvcjsKLWltcG9ydCBvcmcuZWNsaXBzZS5lcXVpbm94LmludGVybmFsLmRzLkluc3RhbmNlUHJvY2VzczsKLWltcG9ydCBvcmcuZWNsaXBzZS5lcXVpbm94LmludGVybmFsLmRzLm1vZGVsLlNlcnZpY2VDb21wb25lbnRQcm9wOwotaW1wb3J0IG9yZy5vc2dpLmZyYW1ld29yay5TZXJ2aWNlUmVmZXJlbmNlOwotaW1wb3J0IG9yZy5vc2dpLnNlcnZpY2UuY29tcG9uZW50Lio7Ci0KLS8qKgotICogQ29tcG9uZW50SW5zdGFuY2VJbXBsLmphdmEKLSAqIAotICogQGF1dGhvciBWYWxlbnRpbiBWYWxjaGV2Ci0gKiBAYXV0aG9yIFN0b3lhbiBCb3NoZXYKLSAqIEBhdXRob3IgUGF2bGluIERvYnJldgotICovCi0KLXB1YmxpYyBjbGFzcyBDb21wb25lbnRJbnN0YW5jZUltcGwgaW1wbGVtZW50cyBDb21wb25lbnRJbnN0YW5jZSB7Ci0KLQlwcml2YXRlIE9iamVjdCBpbnN0YW5jZTsKLQlwcml2YXRlIFNlcnZpY2VDb21wb25lbnRQcm9wIHNjcDsKLQlwcml2YXRlIENvbXBvbmVudENvbnRleHQgY29tcG9uZW50Q29udGV4dDsKLQotCS8vIFNlcnZpY2VSZWZlcmVuY2UgdG8gc2VydmljZSBvYmplY3RzIHdoaWNoIGFyZSBiaW5kZWQgdG8gdGhpcyBpbnN0YW5jZQotCXB1YmxpYyBIYXNodGFibGUgYmluZGVkU2VydmljZXMgPSBuZXcgSGFzaHRhYmxlKDExKTsKLQotCXB1YmxpYyBDb21wb25lbnRJbnN0YW5jZUltcGwoT2JqZWN0IGluc3RhbmNlLCBTZXJ2aWNlQ29tcG9uZW50UHJvcCBzY3ApIHsKLQkJdGhpcy5pbnN0YW5jZSA9IGluc3RhbmNlOwotCQl0aGlzLnNjcCA9IHNjcDsKLQl9Ci0KLQkvKgotCSAqIChub24tSmF2YWRvYykKLQkgKiAKLQkgKiBAc2VlIG9yZy5vc2dpLnNlcnZpY2UuY29tcG9uZW50LkNvbXBvbmVudEluc3RhbmNlI2Rpc3Bvc2UoKQotCSAqLwotCXB1YmxpYyB2b2lkIGRpc3Bvc2UoKSB7Ci0JCWlmIChzY3AgPT0gbnVsbCkgewotCQkJLy8gYWxyZWFkeSBkaXNwb3NlZCEKLQkJCXJldHVybjsKLQkJfQotCQlpZiAoQWN0aXZhdG9yLkRFQlVHKSB7Ci0JCQlBY3RpdmF0b3IubG9nLmRlYnVnKCJDb21wb25lbnRJbnN0YW5jZUltcGwuZGlzcG9zZSgpOiBkaXNwb3NpbmcgaW5zdGFuY2Ugb2YgY29tcG9uZW50ICIgKyBzY3AubmFtZSwgbnVsbCk7IC8vJE5PTi1OTFMtMSQKLQkJfQotCQlpZiAoIXNjcC5pc0NvbXBvbmVudEZhY3RvcnkoKSAmJiBzY3Auc2VydmljZUNvbXBvbmVudC5mYWN0b3J5ICE9IG51bGwpIHsKLQkJCS8vIHRoaXMgaXMgYSBjb21wb25lbnQgZmFjdG9yeSBpbnN0YW5jZSwgc28gZGlzcG9zZSBTQ1AKLQkJCXNjcC5zZXJ2aWNlQ29tcG9uZW50LmNvbXBvbmVudFByb3BzLnJlbW92ZUVsZW1lbnQoc2NwKTsKLQkJCVZlY3RvciB0b0Rpc3Bvc2UgPSBuZXcgVmVjdG9yKDEpOwotCQkJdG9EaXNwb3NlLmFkZEVsZW1lbnQoc2NwKTsKLQkJCUluc3RhbmNlUHJvY2Vzcy5yZXNvbHZlci5kaXNwb3NlQ29tcG9uZW50Q29uZmlncyh0b0Rpc3Bvc2UsIENvbXBvbmVudENvbnN0YW50cy5ERUFDVElWQVRJT05fUkVBU09OX0RJU1BPU0VEKTsKLQkJCWlmIChzY3AgIT0gbnVsbCkgewotCQkJCXNjcC5zZXRTdGF0ZShDb21wb25lbnQuU1RBVEVfRElTUE9TRUQpOwotCQkJfQotCQl9IGVsc2UgewotCQkJc2NwLmRpc3Bvc2UodGhpcywgQ29tcG9uZW50Q29uc3RhbnRzLkRFQUNUSVZBVElPTl9SRUFTT05fRElTUE9TRUQpOwotCQl9Ci0KLQkJLy8gZnJlZSBzZXJ2aWNlIHJlZmVyZW5jZXMgaWYgc29tZSBhcmUgbGVmdCB1bmdvdHRlbgotCQlmcmVlU2VydmljZVJlZmVyZW5jZXMoKTsKLQkJc2NwID0gbnVsbDsKLQkJY29tcG9uZW50Q29udGV4dCA9IG51bGw7Ci0JCWluc3RhbmNlID0gbnVsbDsKLQl9Ci0KLQkvLyBjaGVjayB3aGV0aGVyIHNvbWUgY2FjaGVkIHNlcnZpY2UgcmVmZXJlbmNlcyBhcmUgbm90IHlldCByZW1vdmVkIGFuZAotCS8vIHVuZ290dGVuCi0JcHVibGljIHZvaWQgZnJlZVNlcnZpY2VSZWZlcmVuY2VzKCkgewotCQlpZiAoIWJpbmRlZFNlcnZpY2VzLmlzRW1wdHkoKSkgewotCQkJRW51bWVyYXRpb24ga2V5cyA9IGJpbmRlZFNlcnZpY2VzLmtleXMoKTsKLQkJCXdoaWxlIChrZXlzLmhhc01vcmVFbGVtZW50cygpKSB7Ci0JCQkJU2VydmljZVJlZmVyZW5jZSByZWZlcmVuY2UgPSAoU2VydmljZVJlZmVyZW5jZSkga2V5cy5uZXh0RWxlbWVudCgpOwotCQkJCWJpbmRlZFNlcnZpY2VzLnJlbW92ZShyZWZlcmVuY2UpOwotCQkJCXNjcC5iYy51bmdldFNlcnZpY2UocmVmZXJlbmNlKTsKLQkJCX0KLQkJfQotCX0KLQotCS8qCi0JICogKG5vbi1KYXZhZG9jKQotCSAqIAotCSAqIEBzZWUgb3JnLm9zZ2kuc2VydmljZS5jb21wb25lbnQuQ29tcG9uZW50SW5zdGFuY2UjZ2V0SW5zdGFuY2UoKQotCSAqLwotCXB1YmxpYyBPYmplY3QgZ2V0SW5zdGFuY2UoKSB7Ci0JCXJldHVybiBpbnN0YW5jZTsKLQl9Ci0KLQlwdWJsaWMgQ29tcG9uZW50Q29udGV4dCBnZXRDb21wb25lbnRDb250ZXh0KCkgewotCQlyZXR1cm4gY29tcG9uZW50Q29udGV4dDsKLQl9Ci0KLQlwdWJsaWMgdm9pZCBzZXRDb21wb25lbnRDb250ZXh0KENvbXBvbmVudENvbnRleHQgY29tcG9uZW50Q29udGV4dCkgewotCQl0aGlzLmNvbXBvbmVudENvbnRleHQgPSBjb21wb25lbnRDb250ZXh0OwotCX0KLQotfQpkaWZmIC0tZ2l0IGEvYnVuZGxlcy9vcmcuZWNsaXBzZS5lcXVpbm94LmRzL3NyYy9vcmcvZWNsaXBzZS9lcXVpbm94L2ludGVybmFsL2RzL2ltcGwvUmVhZE9ubHlEaWN0aW9uYXJ5LmphdmEgYi9idW5kbGVzL29yZy5lY2xpcHNlLmVxdWlub3guZHMvc3JjL29yZy9lY2xpcHNlL2VxdWlub3gvaW50ZXJuYWwvZHMvaW1wbC9SZWFkT25seURpY3Rpb25hcnkuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNjI0YmJiZS4uMDAwMDAwMAotLS0gYS9idW5kbGVzL29yZy5lY2xpcHNlLmVxdWlub3guZHMvc3JjL29yZy9lY2xpcHNlL2VxdWlub3gvaW50ZXJuYWwvZHMvaW1wbC9SZWFkT25seURpY3Rpb25hcnkuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEzOSArMCwwIEBACi0vKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgotICogQ29weXJpZ2h0IChjKSAxOTk3LTIwMTEgYnkgUHJvU3lzdCBTb2Z0d2FyZSBHbWJICi0gKiBodHRwOi8vd3d3LnByb3N5c3QuY29tCi0gKiBBbGwgcmlnaHRzIHJlc2VydmVkLiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzCi0gKiBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYxLjAKLSAqIHdoaWNoIGFjY29tcGFuaWVzIHRoaXMgZGlzdHJpYnV0aW9uLCBhbmQgaXMgYXZhaWxhYmxlIGF0Ci0gKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC12MTAuaHRtbAotICoKLSAqIENvbnRyaWJ1dG9yczoKLSAqICAgIFByb1N5c3QgU29mdHdhcmUgR21iSCAtIGluaXRpYWwgQVBJIGFuZCBpbXBsZW1lbnRhdGlvbgotICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi1wYWNrYWdlIG9yZy5lY2xpcHNlLmVxdWlub3guaW50ZXJuYWwuZHMuaW1wbDsKLQotaW1wb3J0IGphdmEudXRpbC4qOwotCi0vKioKLSAqIFRoaXMgaXMgYW4gdXRpbGl0eSBjbGFzcyB0byBwcm92aWRlIGEgcmVhZC1vbmx5IGRpY3Rpb25hcnkuCi0gKiAKLSAqIEBhdXRob3IgU3RveWFuIEJvc2hldgotICovCi1wdWJsaWMgY2xhc3MgUmVhZE9ubHlEaWN0aW9uYXJ5IGV4dGVuZHMgRGljdGlvbmFyeSBpbXBsZW1lbnRzIE1hcCB7Ci0KLQlNYXAgZGVsZWdhdGU7Ci0KLQkvKioKLQkgKiBDcmVhdGVzIGEgbmV3IFJlYWRPbmx5RGljdGlvbmFyeSB3aXRoIGluaXRpYWwgc2V0IG9mIHByb3BlcnRpZXMKLQkgKiAKLQkgKiBAcGFyYW0gaW5pdGlhbFByb3BzIHRoZSBpbml0aWFsUHJvcGVydGllcyBmb3IgdGhpcyBkaWN0aW9uYXJ5Ci0JICovCi0JcHVibGljIFJlYWRPbmx5RGljdGlvbmFyeShNYXAgaW5pdGlhbFByb3BzKSB7Ci0JCXRoaXMuZGVsZWdhdGUgPSBpbml0aWFsUHJvcHMgIT0gbnVsbCA/IGluaXRpYWxQcm9wcyA6IENvbGxlY3Rpb25zLkVNUFRZX01BUDsKLQl9Ci0KLQlwdWJsaWMgdm9pZCB1cGRhdGVEZWxlZ2F0ZShNYXAgbmV3RGVsZWdhdGUpIHsKLQkJdGhpcy5kZWxlZ2F0ZSA9IG5ld0RlbGVnYXRlICE9IG51bGwgPyBuZXdEZWxlZ2F0ZSA6IENvbGxlY3Rpb25zLkVNUFRZX01BUDsKLQl9Ci0KLQkvKiAobm9uLUphdmFkb2MpCi0JICogQHNlZSBqYXZhLnV0aWwuRGljdGlvbmFyeSNwdXQoSywgVikKLQkgKi8KLQlwdWJsaWMgT2JqZWN0IHB1dChPYmplY3Qga2V5LCBPYmplY3QgdmFsdWUpIHsKLQkJLy8gZG8gbm90IG1vZGlmeSAtIHRoaXMgaXMgcmVhZCBvbmx5Ci0JCXRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOwotCX0KLQotCS8qIChub24tSmF2YWRvYykKLQkgKiBAc2VlIGphdmEudXRpbC5EaWN0aW9uYXJ5I3JlbW92ZShqYXZhLmxhbmcuT2JqZWN0KQotCSAqLwotCXB1YmxpYyBPYmplY3QgcmVtb3ZlKE9iamVjdCBrZXkpIHsKLQkJLy8gZG8gbm90IG1vZGlmeSAtIHRoaXMgaXMgcmVhZCBvbmx5Ci0JCXRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOwotCX0KLQotCS8qIChub24tSmF2YWRvYykKLQkgKiBAc2VlIGphdmEudXRpbC5EaWN0aW9uYXJ5I3NpemUoKQotCSAqLwotCXB1YmxpYyBpbnQgc2l6ZSgpIHsKLQkJcmV0dXJuIGRlbGVnYXRlLnNpemUoKTsKLQl9Ci0KLQkvKiAobm9uLUphdmFkb2MpCi0JICogQHNlZSBqYXZhLnV0aWwuRGljdGlvbmFyeSNpc0VtcHR5KCkKLQkgKi8KLQlwdWJsaWMgYm9vbGVhbiBpc0VtcHR5KCkgewotCQlyZXR1cm4gZGVsZWdhdGUuaXNFbXB0eSgpOwotCX0KLQotCS8qIChub24tSmF2YWRvYykKLQkgKiBAc2VlIGphdmEudXRpbC5EaWN0aW9uYXJ5I2tleXMoKQotCSAqLwotCXB1YmxpYyBFbnVtZXJhdGlvbiBrZXlzKCkgewotCQlyZXR1cm4gQ29sbGVjdGlvbnMuZW51bWVyYXRpb24oZGVsZWdhdGUua2V5U2V0KCkpOwotCX0KLQotCS8qIChub24tSmF2YWRvYykKLQkgKiBAc2VlIGphdmEudXRpbC5EaWN0aW9uYXJ5I2VsZW1lbnRzKCkKLQkgKi8KLQlwdWJsaWMgRW51bWVyYXRpb24gZWxlbWVudHMoKSB7Ci0JCXJldHVybiBDb2xsZWN0aW9ucy5lbnVtZXJhdGlvbihkZWxlZ2F0ZS52YWx1ZXMoKSk7Ci0JfQotCi0JLyogKG5vbi1KYXZhZG9jKQotCSAqIEBzZWUgamF2YS51dGlsLkRpY3Rpb25hcnkjZ2V0KGphdmEubGFuZy5PYmplY3QpCi0JICovCi0JcHVibGljIE9iamVjdCBnZXQoT2JqZWN0IGtleSkgewotCQlyZXR1cm4gZGVsZWdhdGUuZ2V0KGtleSk7Ci0JfQotCi0JLyogKG5vbi1KYXZhZG9jKQotCSAqIEBzZWUgamF2YS51dGlsLk1hcCNjb250YWluc0tleShqYXZhLmxhbmcuT2JqZWN0KQotCSAqLwotCXB1YmxpYyBib29sZWFuIGNvbnRhaW5zS2V5KE9iamVjdCBrZXkpIHsKLQkJcmV0dXJuIGRlbGVnYXRlLmNvbnRhaW5zS2V5KGtleSk7Ci0JfQotCi0JLyogKG5vbi1KYXZhZG9jKQotCSAqIEBzZWUgamF2YS51dGlsLk1hcCNjb250YWluc1ZhbHVlKGphdmEubGFuZy5PYmplY3QpCi0JICovCi0JcHVibGljIGJvb2xlYW4gY29udGFpbnNWYWx1ZShPYmplY3QgdmFsdWUpIHsKLQkJcmV0dXJuIGRlbGVnYXRlLmNvbnRhaW5zVmFsdWUodmFsdWUpOwotCX0KLQotCS8qIChub24tSmF2YWRvYykKLQkgKiBAc2VlIGphdmEudXRpbC5NYXAjY2xlYXIoKQotCSAqLwotCXB1YmxpYyB2b2lkIGNsZWFyKCkgewotCQkvLyBkbyBub3QgbW9kaWZ5IC0gdGhpcyBpcyByZWFkIG9ubHkKLQkJdGhyb3cgbmV3IFVuc3VwcG9ydGVkT3BlcmF0aW9uRXhjZXB0aW9uKCk7Ci0JfQotCi0JLyogKG5vbi1KYXZhZG9jKQotCSAqIEBzZWUgamF2YS51dGlsLk1hcCNwdXRBbGwoamF2YS51dGlsLk1hcCkKLQkgKi8KLQlwdWJsaWMgdm9pZCBwdXRBbGwoTWFwIGFyZzApIHsKLQkJLy8gZG8gbm90IG1vZGlmeSAtIHRoaXMgaXMgcmVhZCBvbmx5Ci0JCXRocm93IG5ldyBVbnN1cHBvcnRlZE9wZXJhdGlvbkV4Y2VwdGlvbigpOwotCX0KLQotCS8qIChub24tSmF2YWRvYykKLQkgKiBAc2VlIGphdmEudXRpbC5NYXAjdmFsdWVzKCkKLQkgKi8KLQlwdWJsaWMgQ29sbGVjdGlvbiB2YWx1ZXMoKSB7Ci0JCXJldHVybiBDb2xsZWN0aW9ucy51bm1vZGlmaWFibGVDb2xsZWN0aW9uKGRlbGVnYXRlLnZhbHVlcygpKTsKLQl9Ci0KLQkvKiAobm9uLUphdmFkb2MpCi0JICogQHNlZSBqYXZhLnV0aWwuTWFwI2tleVNldCgpCi0JICovCi0JcHVibGljIFNldCBrZXlTZXQoKSB7Ci0JCXJldHVybiBDb2xsZWN0aW9ucy51bm1vZGlmaWFibGVTZXQoZGVsZWdhdGUua2V5U2V0KCkpOwotCX0KLQotCS8qIChub24tSmF2YWRvYykKLQkgKiBAc2VlIGphdmEudXRpbC5NYXAjZW50cnlTZXQoKQotCSAqLwotCXB1YmxpYyBTZXQgZW50cnlTZXQoKSB7Ci0JCXJldHVybiBDb2xsZWN0aW9ucy51bm1vZGlmaWFibGVTZXQoZGVsZWdhdGUuZW50cnlTZXQoKSk7Ci0JfQotfQpkaWZmIC0tZ2l0IGEvYnVuZGxlcy9vcmcuZWNsaXBzZS5lcXVpbm94LmRzL3NyYy9vcmcvZWNsaXBzZS9lcXVpbm94L2ludGVybmFsL2RzL21vZGVsL0NvbXBvbmVudFJlZmVyZW5jZS5qYXZhIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5lcXVpbm94LmRzL3NyYy9vcmcvZWNsaXBzZS9lcXVpbm94L2ludGVybmFsL2RzL21vZGVsL0NvbXBvbmVudFJlZmVyZW5jZS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA3ZTAzOTU3Li4wMDAwMDAwCi0tLSBhL2J1bmRsZXMvb3JnLmVjbGlwc2UuZXF1aW5veC5kcy9zcmMvb3JnL2VjbGlwc2UvZXF1aW5veC9pbnRlcm5hbC9kcy9tb2RlbC9Db21wb25lbnRSZWZlcmVuY2UuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDgwMCArMCwwIEBACi0vKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgotICogQ29weXJpZ2h0IChjKSAxOTk3LTIwMTAgYnkgUHJvU3lzdCBTb2Z0d2FyZSBHbWJICi0gKiBodHRwOi8vd3d3LnByb3N5c3QuY29tCi0gKiBBbGwgcmlnaHRzIHJlc2VydmVkLiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzCi0gKiBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYxLjAKLSAqIHdoaWNoIGFjY29tcGFuaWVzIHRoaXMgZGlzdHJpYnV0aW9uLCBhbmQgaXMgYXZhaWxhYmxlIGF0Ci0gKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC12MTAuaHRtbAotICoKLSAqIENvbnRyaWJ1dG9yczoKLSAqICAgIFByb1N5c3QgU29mdHdhcmUgR21iSCAtIGluaXRpYWwgQVBJIGFuZCBpbXBsZW1lbnRhdGlvbgotICogICAgSmVyZW15IFZvbGttYW4gCQktIGJ1Zy5pZCA9IDE4MjU2MAotICogICAgU2ltb24gQXJjaGVyIAkJICAgIC0gYnVnLmlkID0gMjIzNDU0Ci0gKiAgICBMYXphciBLaXJjaGV2CQkgCS0gYnVnLmlkID0gMzIwMzc3Ci0gKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLXBhY2thZ2Ugb3JnLmVjbGlwc2UuZXF1aW5veC5pbnRlcm5hbC5kcy5tb2RlbDsKLQotaW1wb3J0IGphdmEuaW8uKjsKLWltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC4qOwotaW1wb3J0IGphdmEudXRpbC4qOwotaW1wb3J0IG9yZy5lY2xpcHNlLmVxdWlub3guaW50ZXJuYWwuZHMuKjsKLWltcG9ydCBvcmcuZWNsaXBzZS5lcXVpbm94LmludGVybmFsLmRzLmltcGwuQ29tcG9uZW50SW5zdGFuY2VJbXBsOwotaW1wb3J0IG9yZy5lY2xpcHNlLmVxdWlub3guaW50ZXJuYWwudXRpbC5pby5FeHRlcm5hbGl6YWJsZTsKLWltcG9ydCBvcmcuZWNsaXBzZS5vc2dpLnV0aWwuTkxTOwotaW1wb3J0IG9yZy5vc2dpLmZyYW1ld29yay5JbnZhbGlkU3ludGF4RXhjZXB0aW9uOwotaW1wb3J0IG9yZy5vc2dpLmZyYW1ld29yay5TZXJ2aWNlUmVmZXJlbmNlOwotaW1wb3J0IG9yZy5vc2dpLnNlcnZpY2UuY29tcG9uZW50LkNvbXBvbmVudEluc3RhbmNlOwotaW1wb3J0IG9yZy5vc2dpLnNlcnZpY2UubG9nLkxvZ1NlcnZpY2U7Ci0KLS8qKgotICogQGF1dGhvciBTdG95YW4gQm9zaGV2Ci0gKiBAYXV0aG9yIFBhdmxpbiBEb2JyZXYKLSAqLwotcHVibGljIGNsYXNzIENvbXBvbmVudFJlZmVyZW5jZSBpbXBsZW1lbnRzIEV4dGVybmFsaXphYmxlLCBvcmcuYXBhY2hlLmZlbGl4LnNjci5SZWZlcmVuY2UgewotCi0JcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQ0FSRElOQUxJVFlfMF8xID0gMDsKLQlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBDQVJESU5BTElUWV8wX04gPSAxOwotCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IENBUkRJTkFMSVRZXzFfMSA9IDI7Ci0JcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgQ0FSRElOQUxJVFlfMV9OID0gMzsKLQlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBQT0xJQ1lfU1RBVElDID0gMDsKLQlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBQT0xJQ1lfRFlOQU1JQyA9IDE7Ci0KLQlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBQT0xJQ1lfT1BUSU9OX1JFTFVDVEFOVCA9IDA7IC8vIGRlZmF1bHQKLQlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBQT0xJQ1lfT1BUSU9OX0dSRUVEWSA9IDE7Ci0KLQkvLyAtLS0gYmVnaW46IFhNTCBkZWYKLQlwdWJsaWMgU3RyaW5nIG5hbWU7Ci0JcHVibGljIFN0cmluZyBpbnRlcmZhY2VOYW1lOyAvLyByZXF1aXJlZAotCXB1YmxpYyBpbnQgY2FyZGluYWxpdHkgPSBDQVJESU5BTElUWV8xXzE7Ci0JcHVibGljIGludCBwb2xpY3kgPSBQT0xJQ1lfU1RBVElDOwotCXB1YmxpYyBTdHJpbmcgdGFyZ2V0OwotCXB1YmxpYyBTdHJpbmcgYmluZDsKLQlwdWJsaWMgU3RyaW5nIHVuYmluZDsKLQkvL2RlZmluZWQgYnkgRFMgc3BlY2lmaWNhdGlvbiB2MS4yIC0gc2NoZW1hIHYxLjIuMAotCXB1YmxpYyBTdHJpbmcgdXBkYXRlZDsKLQlwdWJsaWMgaW50IHBvbGljeV9vcHRpb24gPSBQT0xJQ1lfT1BUSU9OX1JFTFVDVEFOVDsKLQkvLyAtLS0gZW5kOiBYTUwgZGVmCi0JcHVibGljIFNlcnZpY2VDb21wb25lbnQgY29tcG9uZW50OwotCi0JLy8gLS0tIGJlZ2luOiBjYWNoZQotCXByaXZhdGUgYm9vbGVhbiBiaW5kQ2FjaGVkOwotCXByaXZhdGUgYm9vbGVhbiB1bmJpbmRDYWNoZWQ7Ci0JcHJpdmF0ZSBib29sZWFuIHVwZGF0ZWRDYWNoZWQ7Ci0JTWV0aG9kIGJpbmRNZXRob2Q7Ci0JTWV0aG9kIHVuYmluZE1ldGhvZDsKLQlNZXRob2QgdXBkYXRlZE1ldGhvZDsKLQkvLyAtLS0gZW5kOiBjYWNoZQotCi0JLy8gLS0tIGJlZ2luOiBtb2RlbAotCi0JLy8gQ29udGFpbnMgbWFwcGluZyBvZiBTZXJ2aWNlUmVmZXJlbmNlIHRvIENvbXBvbmVudEluc3RhbmNlIG9yIFZlY3RvciBvZiBDb21wb25lbnRJbnN0YW5jZXMuCi0JLy8gVGhlIHNlcnZpY2UgcmVmZXJlbmNlIGlzIGJvdW5kIHRvIHRoZSBDb21wb25lbnRJbnN0YW5jZSBvciB0byBlYWNoIG9mIHRoZSBDb21wb25lbnRJbnN0YW5jZXMgaW4gdGhlIFZlY3RvciAKLQlwdWJsaWMgSGFzaHRhYmxlIHNlcnZpY2VSZWZlcmVuY2VzID0gbmV3IEhhc2h0YWJsZSgzKTsKLQotCS8vIGF2b2lkcyByZWN1cnNpdmUgY2FsbGluZyBvZiB1bmJpbmQgbWV0aG9kIGZvciBvbmUgYW5kIHRoZSBzYW1lIGluc3RhbmNlIAotCXByaXZhdGUgSGFzaHRhYmxlIHNlcnZpY2VSZWZlcmVuY2VzVG9VbmJpbmQgPSBuZXcgSGFzaHRhYmxlKDMpOwotCi0Jc3RhdGljIGZpbmFsIENsYXNzW10gU0VSVklDRV9SRUZFUkVOQ0UgPSBuZXcgQ2xhc3NbXSB7U2VydmljZVJlZmVyZW5jZS5jbGFzc307Ci0KLQkvLyAtLS0gZW5kOiBtb2RlbDsKLQotCUNvbXBvbmVudFJlZmVyZW5jZShTZXJ2aWNlQ29tcG9uZW50IGNvbXBvbmVudCkgewotCQl0aGlzLmNvbXBvbmVudCA9IGNvbXBvbmVudDsKLQkJaWYgKHRoaXMuY29tcG9uZW50LnJlZmVyZW5jZXMgPT0gbnVsbCkgewotCQkJdGhpcy5jb21wb25lbnQucmVmZXJlbmNlcyA9IG5ldyBWZWN0b3IoMik7Ci0JCX0KLQkJdGhpcy5jb21wb25lbnQucmVmZXJlbmNlcy5hZGRFbGVtZW50KHRoaXMpOwotCX0KLQotCU1ldGhvZCBnZXRNZXRob2QoQ29tcG9uZW50SW5zdGFuY2VJbXBsIGNvbXBvbmVudEluc3RhbmNlLCBSZWZlcmVuY2UgcmVmZXJlbmNlLCBTdHJpbmcgbWV0aG9kTmFtZSwgU2VydmljZVJlZmVyZW5jZSBzZXJ2aWNlUmVmZXJlbmNlKSB7Ci0KLQkJQ2xhc3MgY29uc3VtZXJDbGFzcyA9IGNvbXBvbmVudEluc3RhbmNlLmdldEluc3RhbmNlKCkuZ2V0Q2xhc3MoKTsKLQkJT2JqZWN0IHNlcnZpY2VPYmplY3QgPSBudWxsOwotCQlDbGFzcyBzZXJ2aWNlT2JqZWN0Q2xhc3MgPSBudWxsOwotCQlDbGFzcyBpbnRlcmZhY2VDbGFzcyA9IG51bGw7Ci0JCUNsYXNzW10gcGFyYW1faW50ZXJmYWNlQ2xhc3MgPSBudWxsOwotCQlNZXRob2QgbWV0aG9kID0gbnVsbDsKLQkJd2hpbGUgKGNvbnN1bWVyQ2xhc3MgIT0gbnVsbCkgewotCi0JCQkvLyBzZWFyY2ggdGhpcyBjbGFzcycgbWV0aG9kcwotCQkJLy8gbG9vayBmb3IgdmFyaW91cyBmb3JtcyBvZiBiaW5kIG1ldGhvZHMKLQotCQkJLy8gMSkgY2hlY2sgZm9yIGJpbmQoU2VydmljZVJlZmVyZW5jZSkgbWV0aG9kCi0JCQl0cnkgewotCQkJCW1ldGhvZCA9IGNvbnN1bWVyQ2xhc3MuZ2V0RGVjbGFyZWRNZXRob2QobWV0aG9kTmFtZSwgU0VSVklDRV9SRUZFUkVOQ0UpOwotCQkJfSBjYXRjaCAoTm9TdWNoTWV0aG9kRXhjZXB0aW9uIGUpIHsKLQkJCQkvLwotCQkJfSBjYXRjaCAoTm9DbGFzc0RlZkZvdW5kRXJyb3IgZXJyKSB7Ci0JCQkJLy8gdGhpcyBtYXkgaGFwcGVuIG9uIHNrZWxtaXIgVk0gb3IgaW4gY2FzZSBvZiBjbGFzcyBsb2FkaW5nIHByb2JsZW1zCi0JCQkJbG9nV2FybmluZyhOTFMuYmluZChNZXNzYWdlcy5FWENFUFRJT05fR0VUVElOR19NRVRIT0QsIG1ldGhvZE5hbWUsIGNvbnN1bWVyQ2xhc3MuZ2V0TmFtZSgpKSwgZXJyLCByZWZlcmVuY2UpOwotCQkJfQotCi0JCQlpZiAobWV0aG9kICE9IG51bGwgJiYgU0NSVXRpbC5jaGVja01ldGhvZEFjY2Vzcyhjb21wb25lbnRJbnN0YW5jZS5nZXRJbnN0YW5jZSgpLmdldENsYXNzKCksIGNvbnN1bWVyQ2xhc3MsIG1ldGhvZCwgY29tcG9uZW50LmlzTmFtZXNwYWNlQXRMZWFzdDExKCkpKQotCQkJCWJyZWFrOwotCi0JCQkvLyB3ZSBuZWVkIGEgc2VydmljZU9iamVjdCB0byBrZWVwIGxvb2tpbmcsIGNyZWF0ZSBvbmUgaWYgbmVjZXNzYXJ5Ci0JCQlpZiAoc2VydmljZU9iamVjdCA9PSBudWxsKSB7Ci0JCQkJc2VydmljZU9iamVjdCA9IGNvbXBvbmVudEluc3RhbmNlLmJpbmRlZFNlcnZpY2VzLmdldChzZXJ2aWNlUmVmZXJlbmNlKTsKLQkJCQlpZiAoc2VydmljZU9iamVjdCA9PSBudWxsKSB7Ci0JCQkJCXNlcnZpY2VPYmplY3QgPSBJbnN0YW5jZVByb2Nlc3Muc3RhdGljUmVmLmdldFNlcnZpY2UocmVmZXJlbmNlLCBzZXJ2aWNlUmVmZXJlbmNlKTsKLQkJCQl9Ci0JCQkJaWYgKHNlcnZpY2VPYmplY3QgPT0gbnVsbCkgewotCQkJCQkvLyB3ZSBjb3VsZCBub3QgY3JlYXRlIGEgc2VydmljZU9iamVjdCBiZWNhdXNlIG9mIGNpcmN1bGFyaXR5IG9yIHRoZSBCdW5kbGVDb250ZXh0LmdldFNlcnZpY2UoU2VydmljZVJlZmVyZW5jZSkgcmV0dXJuZWQgbnVsbAotCQkJCQlsb2dXYXJuaW5nKE1lc3NhZ2VzLkNBTlRfR0VUX1NFUlZJQ0VfT0JKRUNULCBudWxsLCByZWZlcmVuY2UpOwotCQkJCQlyZXR1cm4gbnVsbDsKLQkJCQl9Ci0JCQkJY29tcG9uZW50SW5zdGFuY2UuYmluZGVkU2VydmljZXMucHV0KHNlcnZpY2VSZWZlcmVuY2UsIHNlcnZpY2VPYmplY3QpOwotCQkJCXNlcnZpY2VPYmplY3RDbGFzcyA9IHNlcnZpY2VPYmplY3QuZ2V0Q2xhc3MoKTsKLQotCQkJCS8vIGZpZ3VyZSBvdXQgdGhlIGludGVyZmFjZSBjbGFzcyAtIHRoaXMgaXMgZ3VhcmFudGVlZCB0byBzdWNjZWVkIG9yIGVsc2UKLQkJCQkvLyB0aGUgZnJhbWV3b3JrIHdvdWxkIG5vdCBoYXZlIGxldCB1cyBoYXZlIHRoZSBzZXJ2aWNlIG9iamVjdAotCQkJCUNsYXNzIHNlYXJjaEZvckludGVyZmFjZUNsYXNzID0gc2VydmljZU9iamVjdENsYXNzOwotCQkJCXdoaWxlIChzZWFyY2hGb3JJbnRlcmZhY2VDbGFzcyAhPSBudWxsKSB7Ci0JCQkJCS8vIGZpcnN0IGxvb2sgdGhyb3VnaCBpbnRlcmZhY2VzCi0JCQkJCUNsYXNzW10gaW50ZXJmYWNlQ2xhc3NlcyA9IHNlYXJjaEZvckludGVyZmFjZUNsYXNzLmdldEludGVyZmFjZXMoKTsKLQkJCQkJZm9yIChpbnQgaSA9IDA7IGkgPCBpbnRlcmZhY2VDbGFzc2VzLmxlbmd0aDsgaSsrKSB7Ci0JCQkJCQlpZiAoaW50ZXJmYWNlQ2xhc3Nlc1tpXS5nZXROYW1lKCkuZXF1YWxzKGludGVyZmFjZU5hbWUpKSB7Ci0JCQkJCQkJaW50ZXJmYWNlQ2xhc3MgPSBpbnRlcmZhY2VDbGFzc2VzW2ldOwotCQkJCQkJCWJyZWFrOwotCQkJCQkJfQotCQkJCQl9Ci0JCQkJCWlmIChpbnRlcmZhY2VDbGFzcyAhPSBudWxsKSB7Ci0JCQkJCQlicmVhazsKLQkJCQkJfQotCi0JCQkJCS8vIGFsc28gY2hlY2sgdGhlIGNsYXNzIGl0c2VsZgotCQkJCQlpZiAoc2VhcmNoRm9ySW50ZXJmYWNlQ2xhc3MuZ2V0TmFtZSgpLmVxdWFscyhpbnRlcmZhY2VOYW1lKSkgewotCQkJCQkJaW50ZXJmYWNlQ2xhc3MgPSBzZWFyY2hGb3JJbnRlcmZhY2VDbGFzczsKLQkJCQkJCWJyZWFrOwotCQkJCQl9Ci0KLQkJCQkJLy8gYWR2YW5jZSB1cCB0aGUgc3VwZXJjbGFzc2VzCi0JCQkJCXNlYXJjaEZvckludGVyZmFjZUNsYXNzID0gc2VhcmNoRm9ySW50ZXJmYWNlQ2xhc3MuZ2V0U3VwZXJjbGFzcygpOwotCQkJCX0KLQotCQkJCXBhcmFtX2ludGVyZmFjZUNsYXNzID0gbmV3IENsYXNzW10ge2ludGVyZmFjZUNsYXNzfTsKLQotCQkJfSAvLyBlbmQgaWYoc2VydmljZU9iamVjdCA9PSBudWxsKQotCi0JCQkvLyAyKSBjaGVjayBmb3IgYmluZChTZXJ2aWNlIGludGVyZmFjZSkgbWV0aG9kCi0JCQl0cnkgewotCQkJCW1ldGhvZCA9IGNvbnN1bWVyQ2xhc3MuZ2V0RGVjbGFyZWRNZXRob2QobWV0aG9kTmFtZSwgcGFyYW1faW50ZXJmYWNlQ2xhc3MpOwotCQkJfSBjYXRjaCAoTm9TdWNoTWV0aG9kRXhjZXB0aW9uIGUpIHsKLQkJCQkvLwotCQkJfSBjYXRjaCAoTm9DbGFzc0RlZkZvdW5kRXJyb3IgZXJyKSB7Ci0JCQkJLy8gdGhpcyBtYXkgaGFwcGVuIG9uIHNrZWxtaXIgVk0gb3IgaW4gY2FzZSBvZiBjbGFzcyBsb2FkaW5nIHByb2JsZW1zCi0JCQkJbG9nV2FybmluZyhOTFMuYmluZChNZXNzYWdlcy5FWENFUFRJT05fR0VUVElOR19NRVRIT0QsIG1ldGhvZE5hbWUsIGNvbnN1bWVyQ2xhc3MuZ2V0TmFtZSgpKSwgZXJyLCByZWZlcmVuY2UpOwotCQkJfQotCQkJaWYgKG1ldGhvZCAhPSBudWxsICYmIFNDUlV0aWwuY2hlY2tNZXRob2RBY2Nlc3MoY29tcG9uZW50SW5zdGFuY2UuZ2V0SW5zdGFuY2UoKS5nZXRDbGFzcygpLCBjb25zdW1lckNsYXNzLCBtZXRob2QsIGNvbXBvbmVudC5pc05hbWVzcGFjZUF0TGVhc3QxMSgpKSkKLQkJCQlicmVhazsKLQotCQkJLy8gMykgY2hlY2sgZm9yIGJpbmQoY2xhc3MuaXNBc3NpZ25hYmxlRnJvbShzZXJ2aWNlT2JqZWN0Q2xhc3MpKQotCQkJLy8gbWV0aG9kCi0JCQlNZXRob2RbXSBtZXRob2RzID0gY29uc3VtZXJDbGFzcy5nZXREZWNsYXJlZE1ldGhvZHMoKTsKLQkJCWZvciAoaW50IGkgPSAwOyBpIDwgbWV0aG9kcy5sZW5ndGg7IGkrKykgewotCQkJCUNsYXNzW10gcGFyYW1zID0gbWV0aG9kc1tpXS5nZXRQYXJhbWV0ZXJUeXBlcygpOwotCQkJCWlmIChwYXJhbXMubGVuZ3RoID09IDEgJiYgbWV0aG9kc1tpXS5nZXROYW1lKCkuZXF1YWxzKG1ldGhvZE5hbWUpICYmIHBhcmFtc1swXS5pc0Fzc2lnbmFibGVGcm9tKHNlcnZpY2VPYmplY3RDbGFzcykpIHsKLQotCQkJCQltZXRob2QgPSBtZXRob2RzW2ldOwotCQkJCQlicmVhazsKLQkJCQl9Ci0JCQl9Ci0JCQlpZiAobWV0aG9kICE9IG51bGwgJiYgU0NSVXRpbC5jaGVja01ldGhvZEFjY2Vzcyhjb21wb25lbnRJbnN0YW5jZS5nZXRJbnN0YW5jZSgpLmdldENsYXNzKCksIGNvbnN1bWVyQ2xhc3MsIG1ldGhvZCwgY29tcG9uZW50LmlzTmFtZXNwYWNlQXRMZWFzdDExKCkpKQotCQkJCWJyZWFrOwotCi0JCQkvL2ltcGxlbWVudCBzZWFyY2ggZm9yIGJpbmQvdW5iaW5kIG1ldGhvZHMgYWNjb3JkaW5nIHRvIHNjaGVtYSB2MS4xLjAKLQkJCWlmIChjb21wb25lbnQuaXNOYW1lc3BhY2VBdExlYXN0MTEoKSkgewotCQkJCWZvciAoaW50IGkgPSAwOyBpIDwgbWV0aG9kcy5sZW5ndGg7IGkrKykgewotCQkJCQlDbGFzc1tdIHBhcmFtcyA9IG1ldGhvZHNbaV0uZ2V0UGFyYW1ldGVyVHlwZXMoKTsKLQkJCQkJaWYgKHBhcmFtcy5sZW5ndGggPT0gMiAmJiBtZXRob2RzW2ldLmdldE5hbWUoKS5lcXVhbHMobWV0aG9kTmFtZSkgJiYgcGFyYW1zWzBdID09IGludGVyZmFjZUNsYXNzICYmIHBhcmFtc1sxXSA9PSBNYXAuY2xhc3MpIHsKLQkJCQkJCW1ldGhvZCA9IG1ldGhvZHNbaV07Ci0JCQkJCQlicmVhazsKLQkJCQkJfQotCQkJCX0KLQkJCQlpZiAobWV0aG9kICE9IG51bGwgJiYgU0NSVXRpbC5jaGVja01ldGhvZEFjY2Vzcyhjb21wb25lbnRJbnN0YW5jZS5nZXRJbnN0YW5jZSgpLmdldENsYXNzKCksIGNvbnN1bWVyQ2xhc3MsIG1ldGhvZCwgdHJ1ZSkpCi0JCQkJCWJyZWFrOwotCi0JCQkJZm9yIChpbnQgaSA9IDA7IGkgPCBtZXRob2RzLmxlbmd0aDsgaSsrKSB7Ci0JCQkJCUNsYXNzW10gcGFyYW1zID0gbWV0aG9kc1tpXS5nZXRQYXJhbWV0ZXJUeXBlcygpOwotCQkJCQlpZiAocGFyYW1zLmxlbmd0aCA9PSAyICYmIG1ldGhvZHNbaV0uZ2V0TmFtZSgpLmVxdWFscyhtZXRob2ROYW1lKSAmJiBwYXJhbXNbMF0uaXNBc3NpZ25hYmxlRnJvbShzZXJ2aWNlT2JqZWN0Q2xhc3MpICYmIHBhcmFtc1sxXSA9PSBNYXAuY2xhc3MpIHsKLQkJCQkJCW1ldGhvZCA9IG1ldGhvZHNbaV07Ci0JCQkJCQlicmVhazsKLQkJCQkJfQotCQkJCX0KLQkJCX0KLQkJCWlmIChtZXRob2QgIT0gbnVsbCkKLQkJCQlicmVhazsKLQotCQkJLy8gd2UgY291bGRuJ3QgZmluZCB0aGUgbWV0aG9kIC0gdHJ5IHRoZSBzdXBlcmNsYXNzCi0JCQljb25zdW1lckNsYXNzID0gY29uc3VtZXJDbGFzcy5nZXRTdXBlcmNsYXNzKCk7Ci0JCX0KLQotCQlpZiAobWV0aG9kID09IG51bGwpIHsKLQkJCWxvZ01ldGhvZE5vdEZvdW5kRXJyb3IoY29tcG9uZW50SW5zdGFuY2UsIHJlZmVyZW5jZSwgbWV0aG9kTmFtZSk7Ci0JCQlyZXR1cm4gbnVsbDsKLQkJfQotCi0JCWlmICghU0NSVXRpbC5jaGVja01ldGhvZEFjY2Vzcyhjb21wb25lbnRJbnN0YW5jZS5nZXRJbnN0YW5jZSgpLmdldENsYXNzKCksIGNvbnN1bWVyQ2xhc3MsIG1ldGhvZCwgY29tcG9uZW50LmlzTmFtZXNwYWNlQXRMZWFzdDExKCkpKSB7Ci0JCQkvLyBpZiBtZXRob2QgaXMgbm90IHZpc2libGUsIGxvZyBlcnJvciBtZXNzYWdlCi0JCQlsb2dNZXRob2ROb3RWaXNpYmxlKGNvbXBvbmVudEluc3RhbmNlLCByZWZlcmVuY2UsIG1ldGhvZE5hbWUsIG1ldGhvZC5nZXRQYXJhbWV0ZXJUeXBlcygpKTsKLQkJCXJldHVybiBudWxsOwotCQl9Ci0KLQkJaW50IG1vZGlmaWVyID0gbWV0aG9kLmdldE1vZGlmaWVycygpOwotCQlpZiAoIU1vZGlmaWVyLmlzUHVibGljKG1vZGlmaWVyKSkgewotCQkJU0NSVXRpbC5zZXRBY2Nlc3NpYmxlKG1ldGhvZCk7Ci0JCX0KLQotCQlyZXR1cm4gbWV0aG9kOwotCX0KLQotCXByaXZhdGUgdm9pZCBsb2dNZXRob2ROb3RWaXNpYmxlKENvbXBvbmVudEluc3RhbmNlSW1wbCBjb21wb25lbnRJbnN0YW5jZSwgUmVmZXJlbmNlIHJlZmVyZW5jZSwgU3RyaW5nIG1ldGhvZE5hbWUsIENsYXNzW10gcGFyYW1faW50ZXJmYWNlQ2xhc3NlcykgewotCQlTdHJpbmdCdWZmZXIgYnVmZmVyID0gY3JlYXRlQnVmZmVyKCk7Ci0JCWJ1ZmZlci5hcHBlbmQoIltTQ1JdIE1ldGhvZCAiKTsgLy8kTk9OLU5MUy0xJAotCQlidWZmZXIuYXBwZW5kKG1ldGhvZE5hbWUpOwotCQlidWZmZXIuYXBwZW5kKCcoJyk7Ci0JCWZvciAoaW50IGkgPSAwOyBpIDwgcGFyYW1faW50ZXJmYWNlQ2xhc3Nlcy5sZW5ndGg7IGkrKykgewotCQkJYnVmZmVyLmFwcGVuZChwYXJhbV9pbnRlcmZhY2VDbGFzc2VzW2ldLmdldE5hbWUoKSk7Ci0JCQlpZiAoaSA8IHBhcmFtX2ludGVyZmFjZUNsYXNzZXMubGVuZ3RoIC0gMSkgewotCQkJCWJ1ZmZlci5hcHBlbmQoJywnKTsKLQkJCX0KLQkJfQotCQlidWZmZXIuYXBwZW5kKCcpJyk7Ci0JCWJ1ZmZlci5hcHBlbmQoIiBpcyBub3QgYWNjZXNzaWJsZSEiKTsgLy8kTk9OLU5MUy0xJAotCQljb21wb25lbnQuY29tcG9uZW50SXNzdWVzLmFkZCgiTWV0aG9kIFsiICsgbWV0aG9kTmFtZSArICJdICBpcyBub3QgYWNjZXNzaWJsZSBpbiAiICsgY29tcG9uZW50SW5zdGFuY2UuZ2V0SW5zdGFuY2UoKS5nZXRDbGFzcygpKTsKLQkJYXBwZW5kRGV0YWlscyhidWZmZXIsIHJlZmVyZW5jZSk7Ci0JCVN0cmluZyBtZXNzYWdlID0gYnVmZmVyLnRvU3RyaW5nKCk7Ci0JCUFjdGl2YXRvci5sb2cocmVmZXJlbmNlLnJlZmVyZW5jZS5jb21wb25lbnQuYmMsIExvZ1NlcnZpY2UuTE9HX0VSUk9SLCBtZXNzYWdlLCBudWxsKTsKLQl9Ci0KLQlwcml2YXRlIHZvaWQgbG9nTWV0aG9kTm90Rm91bmRFcnJvcihDb21wb25lbnRJbnN0YW5jZUltcGwgY29tcG9uZW50SW5zdGFuY2UsIFJlZmVyZW5jZSByZWZlcmVuY2UsIFN0cmluZyBtZXRob2ROYW1lKSB7Ci0JCVN0cmluZ0J1ZmZlciBidWZmZXIgPSBjcmVhdGVCdWZmZXIoKTsKLQkJYnVmZmVyLmFwcGVuZCgiW1NDUl0gTWV0aG9kIHdhcyBub3QgZm91bmQ6ICIpOyAvLyROT04tTkxTLTEkCi0JCWJ1ZmZlci5hcHBlbmQobWV0aG9kTmFtZSk7Ci0JCWJ1ZmZlci5hcHBlbmQoJygnKTsKLQkJYnVmZmVyLmFwcGVuZCgiLi4uIik7IC8vJE5PTi1OTFMtMSQKLQkJYnVmZmVyLmFwcGVuZCgnKScpOwotCQljb21wb25lbnQuY29tcG9uZW50SXNzdWVzLmFkZCgiTWV0aG9kIFsiICsgbWV0aG9kTmFtZSArICJdIHdhcyBub3QgZm91bmQgaW4gIiArIGNvbXBvbmVudEluc3RhbmNlLmdldEluc3RhbmNlKCkuZ2V0Q2xhc3MoKSk7Ci0JCWFwcGVuZERldGFpbHMoYnVmZmVyLCByZWZlcmVuY2UpOwotCQlTdHJpbmcgbWVzc2FnZSA9IGJ1ZmZlci50b1N0cmluZygpOwotCQlBY3RpdmF0b3IubG9nKHJlZmVyZW5jZS5yZWZlcmVuY2UuY29tcG9uZW50LmJjLCBMb2dTZXJ2aWNlLkxPR19FUlJPUiwgbWVzc2FnZSwgbnVsbCk7Ci0JfQotCi0JcHJpdmF0ZSB2b2lkIGFwcGVuZERldGFpbHMoU3RyaW5nQnVmZmVyIGJ1ZmZlciwgUmVmZXJlbmNlIHJlZmVyZW5jZSkgewotCQl0cnkgewotCQkJU3RyaW5nIGluZGVudCA9ICJcblx0IjsgLy8kTk9OLU5MUy0xJAotCQkJYnVmZmVyLmFwcGVuZChpbmRlbnQpOwotCQkJYnVmZmVyLmFwcGVuZCgiRGV0YWlsczoiKTsgLy8kTk9OLU5MUy0xJAotCQkJYnVmZmVyLmFwcGVuZChpbmRlbnQpOwotCQkJYnVmZmVyLmFwcGVuZCgiUHJvYmxlbWF0aWMgcmVmZXJlbmNlID0gIiArIHJlZmVyZW5jZS5yZWZlcmVuY2UpOyAvLyROT04tTkxTLTEkCi0JCQlidWZmZXIuYXBwZW5kKGluZGVudCk7Ci0JCQlidWZmZXIuYXBwZW5kKCJvZiBzZXJ2aWNlIGNvbXBvbmVudCA9ICIpOyAvLyROT04tTkxTLTEkCi0JCQlidWZmZXIuYXBwZW5kKHJlZmVyZW5jZS5yZWZlcmVuY2UuY29tcG9uZW50Lm5hbWUpOwotCQkJYnVmZmVyLmFwcGVuZChpbmRlbnQpOwotCQkJYnVmZmVyLmFwcGVuZCgiY29tcG9uZW50IGltcGxlbWVudGF0aW9uIGNsYXNzID0gIik7IC8vJE5PTi1OTFMtMSQKLQkJCWJ1ZmZlci5hcHBlbmQocmVmZXJlbmNlLnJlZmVyZW5jZS5jb21wb25lbnQuaW1wbGVtZW50YXRpb24pOwotCQkJYnVmZmVyLmFwcGVuZChpbmRlbnQpOwotCQkJYnVmZmVyLmFwcGVuZCgibG9jYXRlZCBpbiBidW5kbGUgd2l0aCBzeW1ib2xpYyBuYW1lID0gIik7IC8vJE5PTi1OTFMtMSQKLQkJCWJ1ZmZlci5hcHBlbmQoY29tcG9uZW50LmJjLmdldEJ1bmRsZSgpLmdldFN5bWJvbGljTmFtZSgpKTsKLQkJCWJ1ZmZlci5hcHBlbmQoaW5kZW50KTsKLQkJCWJ1ZmZlci5hcHBlbmQoImJ1bmRsZSBsb2NhdGlvbiA9ICIpOyAvLyROT04tTkxTLTEkCi0JCQlidWZmZXIuYXBwZW5kKGNvbXBvbmVudC5iYy5nZXRCdW5kbGUoKS5nZXRMb2NhdGlvbigpKTsKLQkJfSBjYXRjaCAoVGhyb3dhYmxlIHQpIHsKLQkJCS8vcHJldmVudCBwb3NzaWJsZSBleGNlcHRpb25zIGluIGNhc2UgdGhlIGNvbXBvbmVudCdzIGJ1bmRsZSBiZWNvbWVzIHVuaW5zdGFsbGVkIAotCQl9Ci0JfQotCi0JcHJpdmF0ZSB2b2lkIGxvZ1dhcm5pbmcoU3RyaW5nIG1lc3NhZ2UsIFRocm93YWJsZSB0LCBSZWZlcmVuY2UgcmVmZXJlbmNlKSB7Ci0JCVN0cmluZ0J1ZmZlciBidWZmZXIgPSBjcmVhdGVCdWZmZXIoKTsKLQkJYnVmZmVyLmFwcGVuZChtZXNzYWdlKTsKLQkJYXBwZW5kRGV0YWlscyhidWZmZXIsIHJlZmVyZW5jZSk7Ci0JCUFjdGl2YXRvci5sb2cocmVmZXJlbmNlLnJlZmVyZW5jZS5jb21wb25lbnQuYmMsIExvZ1NlcnZpY2UuTE9HX1dBUk5JTkcsIGJ1ZmZlci50b1N0cmluZygpLCB0KTsKLQl9Ci0KLQlwcml2YXRlIHZvaWQgbG9nRXJyb3IoU3RyaW5nIG1lc3NhZ2UsIFRocm93YWJsZSB0LCBSZWZlcmVuY2UgcmVmZXJlbmNlKSB7Ci0JCVN0cmluZ0J1ZmZlciBidWZmZXIgPSBjcmVhdGVCdWZmZXIoKTsKLQkJYnVmZmVyLmFwcGVuZChtZXNzYWdlKTsKLQkJU3RyaW5nIGNhdXNlID0gdC50b1N0cmluZygpOwotCQlpZiAodCBpbnN0YW5jZW9mIEludm9jYXRpb25UYXJnZXRFeGNlcHRpb24pIHsKLQkJCWNhdXNlID0gIlRoZSBjYWxsZWQgbWV0aG9kIHRocm93czogIiArIHQuZ2V0Q2F1c2UoKS50b1N0cmluZygpOwotCQl9Ci0JCWNvbXBvbmVudC5jb21wb25lbnRJc3N1ZXMuYWRkKG1lc3NhZ2UgKyAiIFJvb3QgQ2F1c2UgWyIgKyBjYXVzZSArICJdIik7Ci0JCWFwcGVuZERldGFpbHMoYnVmZmVyLCByZWZlcmVuY2UpOwotCQlBY3RpdmF0b3IubG9nKHJlZmVyZW5jZS5yZWZlcmVuY2UuY29tcG9uZW50LmJjLCBMb2dTZXJ2aWNlLkxPR19FUlJPUiwgYnVmZmVyLnRvU3RyaW5nKCksIHQpOwotCX0KLQotCXByaXZhdGUgU3RyaW5nQnVmZmVyIGNyZWF0ZUJ1ZmZlcigpIHsKLQkJcmV0dXJuIG5ldyBTdHJpbmdCdWZmZXIoNDAwKTsKLQl9Ci0KLQlmaW5hbCBib29sZWFuIGJpbmQoUmVmZXJlbmNlIHJlZmVyZW5jZSwgQ29tcG9uZW50SW5zdGFuY2UgaW5zdGFuY2UsIFNlcnZpY2VSZWZlcmVuY2Ugc2VydmljZVJlZmVyZW5jZSkgdGhyb3dzIEV4Y2VwdGlvbiB7Ci0JCWlmIChiaW5kICE9IG51bGwpIHsKLQkJCWJvb2xlYW4gYm91bmQgPSBmYWxzZTsKLQkJCS8vIERPTidUIHJlYmluZCB0aGUgc2FtZSBvYmplY3QgYWdhaW4KLQkJCXN5bmNocm9uaXplZCAoc2VydmljZVJlZmVyZW5jZXMpIHsKLQkJCQlWZWN0b3IgaW5zdGFuY2VzID0gKFZlY3Rvcikgc2VydmljZVJlZmVyZW5jZXMuZ2V0KHNlcnZpY2VSZWZlcmVuY2UpOwotCQkJCWlmIChpbnN0YW5jZXMgPT0gbnVsbCkgewotCQkJCQlpbnN0YW5jZXMgPSBuZXcgVmVjdG9yKDEpOwotCQkJCQlpbnN0YW5jZXMuYWRkRWxlbWVudChpbnN0YW5jZSk7Ci0JCQkJCXNlcnZpY2VSZWZlcmVuY2VzLnB1dChzZXJ2aWNlUmVmZXJlbmNlLCBpbnN0YW5jZXMpOwotCQkJCX0gZWxzZSBpZiAoaW5zdGFuY2VzLmNvbnRhaW5zKGluc3RhbmNlKSkgewotCQkJCQlpZiAocmVmZXJlbmNlLmlzVW5hcnkoKSkgewotCQkJCQkJbG9nV2FybmluZyhOTFMuYmluZChNZXNzYWdlcy5TRVJWSUNFX1JFRkVSRU5DRV9BTFJFQURZX0JPVU5ELCBzZXJ2aWNlUmVmZXJlbmNlLCBpbnN0YW5jZSksIG51bGwsIHJlZmVyZW5jZSk7Ci0JCQkJCX0KLQkJCQkJcmV0dXJuIGZhbHNlOwotCQkJCX0gZWxzZSB7Ci0JCQkJCWluc3RhbmNlcy5hZGRFbGVtZW50KGluc3RhbmNlKTsKLQkJCQl9Ci0JCQl9Ci0JCQkvLyByZXRyaWV2ZSB0aGUgbWV0aG9kIGZyb20gY2FjaGUKLQkJCWlmICghYmluZENhY2hlZCkgewotCQkJCWJpbmRNZXRob2QgPSBnZXRNZXRob2QoKENvbXBvbmVudEluc3RhbmNlSW1wbCkgaW5zdGFuY2UsIHJlZmVyZW5jZSwgYmluZCwgc2VydmljZVJlZmVyZW5jZSk7Ci0JCQkJLy8gYmluZE1ldGhvZCBjYW4gYmUgbnVsbCBpbiBjYXNlIG9mIGNpcmN1bGFyaXR5Ci0JCQkJaWYgKGJpbmRNZXRob2QgIT0gbnVsbCkgewotCQkJCQliaW5kQ2FjaGVkID0gdHJ1ZTsKLQkJCQl9Ci0JCQl9Ci0JCQkvLyBpbnZva2UgdGhlIG1ldGhvZAotCQkJaWYgKGJpbmRNZXRob2QgIT0gbnVsbCkgewotCQkJCU9iamVjdCBtZXRob2RQYXJhbSA9IG51bGw7Ci0JCQkJQ2xhc3NbXSBwYXJhbVR5cGVzID0gYmluZE1ldGhvZC5nZXRQYXJhbWV0ZXJUeXBlcygpOwotCQkJCWlmIChwYXJhbVR5cGVzLmxlbmd0aCA9PSAxICYmIHBhcmFtVHlwZXNbMF0uZXF1YWxzKFNlcnZpY2VSZWZlcmVuY2UuY2xhc3MpKSB7Ci0JCQkJCW1ldGhvZFBhcmFtID0gc2VydmljZVJlZmVyZW5jZTsKLQkJCQl9IGVsc2UgewotCQkJCQkvLyBiaW5kZWRTZXJ2aWNlcyBpcyBmaWxsZWQgYnkgdGhlIGdldE1ldGhvZCBmdW5jdGlvbgotCQkJCQltZXRob2RQYXJhbSA9ICgoQ29tcG9uZW50SW5zdGFuY2VJbXBsKSBpbnN0YW5jZSkuYmluZGVkU2VydmljZXMuZ2V0KHNlcnZpY2VSZWZlcmVuY2UpOwotCQkJCQlpZiAobWV0aG9kUGFyYW0gPT0gbnVsbCkgewotCQkJCQkJbWV0aG9kUGFyYW0gPSBJbnN0YW5jZVByb2Nlc3Muc3RhdGljUmVmLmdldFNlcnZpY2UocmVmZXJlbmNlLCBzZXJ2aWNlUmVmZXJlbmNlKTsKLQkJCQkJCWlmIChtZXRob2RQYXJhbSAhPSBudWxsKSB7Ci0JCQkJCQkJKChDb21wb25lbnRJbnN0YW5jZUltcGwpIGluc3RhbmNlKS5iaW5kZWRTZXJ2aWNlcy5wdXQoc2VydmljZVJlZmVyZW5jZSwgbWV0aG9kUGFyYW0pOwotCQkJCQkJfQotCQkJCQl9Ci0JCQkJCWlmIChtZXRob2RQYXJhbSA9PSBudWxsKSB7Ci0JCQkJCQkvLyBjYW5ub3QgZ2V0IHNlcnZpY2VPYmplY3QgYmVjYXVzZSBvZiBjaXJjdWxhcml0eQotCi0JCQkJCQkvL3JlbW92ZSB0aGUgY29tcG9uZW50IGluc3RhbmNlIG1hcmtlZCBhcyBib3VuZAotCQkJCQkJcmVtb3ZlU2VydmljZVJlZmVyZW5jZShzZXJ2aWNlUmVmZXJlbmNlLCBpbnN0YW5jZSk7Ci0JCQkJCQlyZXR1cm4gZmFsc2U7Ci0JCQkJCX0KLQkJCQl9Ci0KLQkJCQlPYmplY3RbXSBwYXJhbXMgPSBudWxsOwotCQkJCWlmIChwYXJhbVR5cGVzLmxlbmd0aCA9PSAxKSB7Ci0JCQkJCXBhcmFtcyA9IFNDUlV0aWwuZ2V0T2JqZWN0QXJyYXkoKTsKLQkJCQkJcGFyYW1zWzBdID0gbWV0aG9kUGFyYW07Ci0JCQkJfSBlbHNlIHsKLQkJCQkJLy90aGlzIGlzIHRoZSBjYXNlIHdoZXJlIHdlIGhhdmUgMiBwYXJhbWV0ZXJzOiBhIHNlcnZpY2Ugb2JqZWN0IGFuZCBhIE1hcCwgaG9sZGluZyB0aGUgc2VydmljZSBwcm9wZXJ0aWVzCi0JCQkJCUhhc2hNYXAgbWFwID0gbmV3IEhhc2hNYXAoKTsKLQkJCQkJU3RyaW5nW10ga2V5cyA9IHNlcnZpY2VSZWZlcmVuY2UuZ2V0UHJvcGVydHlLZXlzKCk7Ci0JCQkJCWZvciAoaW50IGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7IGkrKykgewotCQkJCQkJbWFwLnB1dChrZXlzW2ldLCBzZXJ2aWNlUmVmZXJlbmNlLmdldFByb3BlcnR5KGtleXNbaV0pKTsKLQkJCQkJfQotCQkJCQlwYXJhbXMgPSBuZXcgT2JqZWN0W10ge21ldGhvZFBhcmFtLCBtYXB9OwotCQkJCX0KLQotCQkJCXRyeSB7Ci0JCQkJCWJpbmRNZXRob2QuaW52b2tlKGluc3RhbmNlLmdldEluc3RhbmNlKCksIHBhcmFtcyk7Ci0JCQkJCWJvdW5kID0gdHJ1ZTsKLQkJCQl9IGNhdGNoIChUaHJvd2FibGUgdCkgewotCQkJCQlsb2dFcnJvcihOTFMuYmluZChNZXNzYWdlcy5FUlJPUl9CSU5ESU5HX1JFRkVSRU5DRSwgdGhpcyksIHQsIHJlZmVyZW5jZSk7Ci0JCQkJCS8vcmVtb3ZlIHRoZSBjb21wb25lbnQgaW5zdGFuY2UgbWFya2VkIGFzIGJvdW5kCi0JCQkJCXJlbW92ZVNlcnZpY2VSZWZlcmVuY2Uoc2VydmljZVJlZmVyZW5jZSwgaW5zdGFuY2UpOwotCQkJCX0gZmluYWxseSB7Ci0JCQkJCWlmIChwYXJhbXMubGVuZ3RoID09IDEpIHsKLQkJCQkJCVNDUlV0aWwucmVsZWFzZShwYXJhbXMpOwotCQkJCQl9Ci0JCQkJfQotCQkJfSBlbHNlIHsKLQkJCQkvL3JlbW92ZSB0aGUgY29tcG9uZW50IGluc3RhbmNlIG1hcmtlZCBhcyBib3VuZAotCQkJCXJlbW92ZVNlcnZpY2VSZWZlcmVuY2Uoc2VydmljZVJlZmVyZW5jZSwgaW5zdGFuY2UpOwotCQkJCS8vIGNvdWxkIGJlIGFsc28gY2lyY3VsYXJpdHkgYnJlYWsKLQkJCQlsb2dXYXJuaW5nKE5MUy5iaW5kKE1lc3NhZ2VzLkJJTkRfTUVUSE9EX05PVF9GT1VORF9PUl9OT1RfQUNDRVNTSUJMRSwgYmluZCksIG51bGwsIHJlZmVyZW5jZSk7Ci0JCQl9Ci0JCQlyZXR1cm4gYm91bmQ7Ci0JCX0KLQkJcmV0dXJuIGZhbHNlOwotCX0KLQotCXByaXZhdGUgdm9pZCByZW1vdmVTZXJ2aWNlUmVmZXJlbmNlKFNlcnZpY2VSZWZlcmVuY2Ugc2VydmljZVJlZmVyZW5jZSwgQ29tcG9uZW50SW5zdGFuY2UgaW5zdGFuY2UpIHsKLQkJVmVjdG9yIGluc3RhbmNlcyA9IChWZWN0b3IpIHNlcnZpY2VSZWZlcmVuY2VzLmdldChzZXJ2aWNlUmVmZXJlbmNlKTsKLQkJaW5zdGFuY2VzLnJlbW92ZUVsZW1lbnQoaW5zdGFuY2UpOwotCQlpZiAoaW5zdGFuY2VzLmlzRW1wdHkoKSkgewotCQkJc2VydmljZVJlZmVyZW5jZXMucmVtb3ZlKHNlcnZpY2VSZWZlcmVuY2UpOwotCQl9Ci0JfQotCi0JcHVibGljIGZpbmFsIHZvaWQgdW5iaW5kKFJlZmVyZW5jZSByZWZlcmVuY2UsIENvbXBvbmVudEluc3RhbmNlIGluc3RhbmNlLCBTZXJ2aWNlUmVmZXJlbmNlIHNlcnZpY2VSZWZlcmVuY2UpIHsKLQkJLy8gZG9uJ3QgdW5iaW5kIGFuIG9iamVjdCB0aGF0IHdhc24ndCBib3VuZAotCQlib29sZWFuIHJlZmVyZW5jZUV4aXN0cyA9IHRydWU7Ci0JCXN5bmNocm9uaXplZCAoc2VydmljZVJlZmVyZW5jZXMpIHsKLQkJCVZlY3RvciBpbnN0YW5jZXMgPSAoVmVjdG9yKSBzZXJ2aWNlUmVmZXJlbmNlcy5nZXQoc2VydmljZVJlZmVyZW5jZSk7Ci0JCQlpZiAoaW5zdGFuY2VzID09IG51bGwpIHsKLQkJCQlyZWZlcmVuY2VFeGlzdHMgPSBmYWxzZTsKLQkJCX0gZWxzZSB7Ci0JCQkJaWYgKCFpbnN0YW5jZXMuY29udGFpbnMoaW5zdGFuY2UpKSB7Ci0JCQkJCWxvZ1dhcm5pbmcoTkxTLmJpbmQoTWVzc2FnZXMuSU5TVEFOQ0VfTk9UX0JPVU5ELCBpbnN0YW5jZSksIG51bGwsIHJlZmVyZW5jZSk7Ci0JCQkJCXJldHVybjsKLQkJCQl9Ci0JCQl9Ci0JCQlpZiAocmVmZXJlbmNlRXhpc3RzKSB7Ci0JCQkJVmVjdG9yIGluc3RhbmNlc1RvVW5iaW5kID0gKFZlY3Rvcikgc2VydmljZVJlZmVyZW5jZXNUb1VuYmluZC5nZXQoc2VydmljZVJlZmVyZW5jZSk7Ci0JCQkJaWYgKGluc3RhbmNlc1RvVW5iaW5kICE9IG51bGwgJiYgaW5zdGFuY2VzVG9VbmJpbmQuY29udGFpbnMoaW5zdGFuY2UpKSB7Ci0JCQkJCS8vdGhlIHNlcnZpY2UgcmVmZXJlbmNlIGlzIGFscmVhZHkgaW4gcHJvY2VzcyBvZiB1bmJpbmRpbmcKLQkJCQkJcmV0dXJuOwotCQkJCX0KLQkJCQlpZiAoaW5zdGFuY2VzVG9VbmJpbmQgPT0gbnVsbCkgewotCQkJCQlpbnN0YW5jZXNUb1VuYmluZCA9IG5ldyBWZWN0b3IoMSk7Ci0JCQkJCXNlcnZpY2VSZWZlcmVuY2VzVG9VbmJpbmQucHV0KHNlcnZpY2VSZWZlcmVuY2UsIGluc3RhbmNlc1RvVW5iaW5kKTsKLQkJCQl9Ci0JCQkJaW5zdGFuY2VzVG9VbmJpbmQuYWRkRWxlbWVudChpbnN0YW5jZSk7Ci0JCQl9Ci0JCX0KLQkJaWYgKCFyZWZlcmVuY2VFeGlzdHMpIHsKLQkJCWxvZ1dhcm5pbmcoTkxTLmJpbmQoTWVzc2FnZXMuSU5WQUxJRF9TRVJWSUNFX1JFRkVSRU5DRSwgc2VydmljZVJlZmVyZW5jZSksIG51bGwsIHJlZmVyZW5jZSk7Ci0JCQlyZXR1cm47Ci0JCX0KLQkJdHJ5IHsKLQkJCWlmICh1bmJpbmQgIT0gbnVsbCkgewotCQkJCS8vIHJldHJpZXZlIHRoZSB1bmJpbmQgbWV0aG9kIGZyb20gY2FjaGUKLQkJCQlpZiAoIXVuYmluZENhY2hlZCkgewotCQkJCQl1bmJpbmRDYWNoZWQgPSB0cnVlOwotCQkJCQl1bmJpbmRNZXRob2QgPSBnZXRNZXRob2QoKENvbXBvbmVudEluc3RhbmNlSW1wbCkgaW5zdGFuY2UsIHJlZmVyZW5jZSwgdW5iaW5kLCBzZXJ2aWNlUmVmZXJlbmNlKTsKLQkJCQl9Ci0JCQkJLy8gaW52b2tlIHRoZSBtZXRob2QKLQkJCQlpZiAodW5iaW5kTWV0aG9kICE9IG51bGwpIHsKLQkJCQkJT2JqZWN0IG1ldGhvZFBhcmFtID0gbnVsbDsKLQkJCQkJQ2xhc3NbXSBwYXJhbVR5cGVzID0gdW5iaW5kTWV0aG9kLmdldFBhcmFtZXRlclR5cGVzKCk7Ci0JCQkJCWlmIChwYXJhbVR5cGVzLmxlbmd0aCA9PSAxICYmIHBhcmFtVHlwZXNbMF0uZXF1YWxzKFNlcnZpY2VSZWZlcmVuY2UuY2xhc3MpKSB7Ci0JCQkJCQltZXRob2RQYXJhbSA9IHNlcnZpY2VSZWZlcmVuY2U7Ci0JCQkJCX0gZWxzZSB7Ci0JCQkJCQkvLyBiaW5kZWRTZXJ2aWNlcyBpcyBmaWxsZWQgYnkgdGhlIGdldE1ldGhvZCBmdW5jdGlvbgotCQkJCQkJbWV0aG9kUGFyYW0gPSAoKENvbXBvbmVudEluc3RhbmNlSW1wbCkgaW5zdGFuY2UpLmJpbmRlZFNlcnZpY2VzLmdldChzZXJ2aWNlUmVmZXJlbmNlKTsKLQkJCQkJCWlmIChtZXRob2RQYXJhbSA9PSBudWxsKSB7Ci0JCQkJCQkJbWV0aG9kUGFyYW0gPSBJbnN0YW5jZVByb2Nlc3Muc3RhdGljUmVmLmdldFNlcnZpY2UocmVmZXJlbmNlLCBzZXJ2aWNlUmVmZXJlbmNlKTsKLQkJCQkJCX0KLQkJCQkJCWlmIChtZXRob2RQYXJhbSA9PSBudWxsKSB7Ci0JCQkJCQkJLy8gcHJvYmFibHkgY2Fubm90IGdldCBzZXJ2aWNlT2JqZWN0IGJlY2F1c2Ugb2YKLQkJCQkJCQkvLyBjaXJjdWxhcml0eQotCQkJCQkJCXJldHVybjsKLQkJCQkJCX0KLQkJCQkJfQotCi0JCQkJCU9iamVjdFtdIHBhcmFtcyA9IG51bGw7Ci0JCQkJCWlmIChwYXJhbVR5cGVzLmxlbmd0aCA9PSAxKSB7Ci0JCQkJCQlwYXJhbXMgPSBTQ1JVdGlsLmdldE9iamVjdEFycmF5KCk7Ci0JCQkJCQlwYXJhbXNbMF0gPSBtZXRob2RQYXJhbTsKLQkJCQkJfSBlbHNlIHsKLQkJCQkJCS8vdGhpcyBpcyB0aGUgY2FzZSB3aGVyZSB3ZSBoYXZlIDIgcGFyYW1ldGVyczogYSBzZXJ2aWNlIG9iamVjdCBhbmQgYSBNYXAsIGhvbGRpbmcgdGhlIHNlcnZpY2UgcHJvcGVydGllcwotCQkJCQkJSGFzaE1hcCBtYXAgPSBuZXcgSGFzaE1hcCgpOwotCQkJCQkJU3RyaW5nW10ga2V5cyA9IHNlcnZpY2VSZWZlcmVuY2UuZ2V0UHJvcGVydHlLZXlzKCk7Ci0JCQkJCQlmb3IgKGludCBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyBpKyspIHsKLQkJCQkJCQltYXAucHV0KGtleXNbaV0sIHNlcnZpY2VSZWZlcmVuY2UuZ2V0UHJvcGVydHkoa2V5c1tpXSkpOwotCQkJCQkJfQotCQkJCQkJcGFyYW1zID0gbmV3IE9iamVjdFtdIHttZXRob2RQYXJhbSwgbWFwfTsKLQkJCQkJfQotCQkJCQl0cnkgewotCQkJCQkJdW5iaW5kTWV0aG9kLmludm9rZShpbnN0YW5jZS5nZXRJbnN0YW5jZSgpLCBwYXJhbXMpOwotCQkJCQl9IGNhdGNoIChUaHJvd2FibGUgdCkgewotCQkJCQkJbG9nRXJyb3IoTkxTLmJpbmQoTWVzc2FnZXMuRVhDRVBUSU9OX1VOQklORElOR19SRUZFUkVOQ0UsIHRoaXMpLCB0LCByZWZlcmVuY2UpOwotCQkJCQl9IGZpbmFsbHkgewotCQkJCQkJaWYgKHBhcmFtcy5sZW5ndGggPT0gMSkgewotCQkJCQkJCVNDUlV0aWwucmVsZWFzZShwYXJhbXMpOwotCQkJCQkJfQotCQkJCQl9Ci0JCQkJfQotCQkJfQotCQl9IGZpbmFsbHkgewotCQkJc3luY2hyb25pemVkIChzZXJ2aWNlUmVmZXJlbmNlcykgewotCQkJCVZlY3RvciBpbnN0YW5jZXMgPSAoVmVjdG9yKSBzZXJ2aWNlUmVmZXJlbmNlcy5nZXQoc2VydmljZVJlZmVyZW5jZSk7Ci0JCQkJaW5zdGFuY2VzLnJlbW92ZUVsZW1lbnQoaW5zdGFuY2UpOwotCQkJCWlmIChpbnN0YW5jZXMuaXNFbXB0eSgpKSB7Ci0JCQkJCXNlcnZpY2VSZWZlcmVuY2VzLnJlbW92ZShzZXJ2aWNlUmVmZXJlbmNlKTsKLQkJCQl9Ci0KLQkJCQlpbnN0YW5jZXMgPSAoVmVjdG9yKSBzZXJ2aWNlUmVmZXJlbmNlc1RvVW5iaW5kLmdldChzZXJ2aWNlUmVmZXJlbmNlKTsKLQkJCQlpbnN0YW5jZXMucmVtb3ZlRWxlbWVudChpbnN0YW5jZSk7Ci0JCQkJaWYgKGluc3RhbmNlcy5pc0VtcHR5KCkpIHsKLQkJCQkJc2VydmljZVJlZmVyZW5jZXNUb1VuYmluZC5yZW1vdmUoc2VydmljZVJlZmVyZW5jZSk7Ci0JCQkJfQotCQkJfQotCQl9Ci0JCWlmICgoKENvbXBvbmVudEluc3RhbmNlSW1wbCkgaW5zdGFuY2UpLmJpbmRlZFNlcnZpY2VzLnJlbW92ZShzZXJ2aWNlUmVmZXJlbmNlKSAhPSBudWxsKSB7Ci0JCQljb21wb25lbnQuYmMudW5nZXRTZXJ2aWNlKHNlcnZpY2VSZWZlcmVuY2UpOwotCQl9Ci0JfQotCi0JZmluYWwgdm9pZCB1cGRhdGVkKFJlZmVyZW5jZSByZWZlcmVuY2UsIENvbXBvbmVudEluc3RhbmNlIGluc3RhbmNlLCBTZXJ2aWNlUmVmZXJlbmNlIHNlcnZpY2VSZWZlcmVuY2UpIHsKLQkJaWYgKHVwZGF0ZWQgIT0gbnVsbCkgewotCQkJc3luY2hyb25pemVkIChzZXJ2aWNlUmVmZXJlbmNlcykgewotCQkJCVZlY3RvciBpbnN0YW5jZXMgPSAoVmVjdG9yKSBzZXJ2aWNlUmVmZXJlbmNlcy5nZXQoc2VydmljZVJlZmVyZW5jZSk7Ci0JCQkJaWYgKGluc3RhbmNlcyA9PSBudWxsIHx8ICFpbnN0YW5jZXMuY29udGFpbnMoaW5zdGFuY2UpKSB7Ci0JCQkJCS8vdGhpcyBpbnN0YW5jZSBpcyBub3QgYm91bmQgdG8gdGhlIHBhc3NlZCBzZXJ2aWNlIHJlZmVyZW5jZQotCQkJCQlyZXR1cm47Ci0JCQkJfQotCQkJfQotCQkJLy8gcmV0cmlldmUgdGhlIG1ldGhvZCBmcm9tIGNhY2hlCi0JCQlpZiAoIXVwZGF0ZWRDYWNoZWQpIHsKLQkJCQl1cGRhdGVkTWV0aG9kID0gZ2V0TWV0aG9kKChDb21wb25lbnRJbnN0YW5jZUltcGwpIGluc3RhbmNlLCByZWZlcmVuY2UsIHVwZGF0ZWQsIHNlcnZpY2VSZWZlcmVuY2UpOwotCQkJCS8vIHVwZGF0ZWRNZXRob2QgY2FuIGJlIG51bGwgaW4gY2FzZSBvZiBjaXJjdWxhcml0eQotCQkJCWlmICh1cGRhdGVkTWV0aG9kICE9IG51bGwpIHsKLQkJCQkJdXBkYXRlZENhY2hlZCA9IHRydWU7Ci0JCQkJfQotCQkJfQotCQkJLy8gaW52b2tlIHRoZSBtZXRob2QKLQkJCWlmICh1cGRhdGVkTWV0aG9kICE9IG51bGwpIHsKLQkJCQlPYmplY3QgbWV0aG9kUGFyYW0gPSBudWxsOwotCQkJCUNsYXNzW10gcGFyYW1UeXBlcyA9IHVwZGF0ZWRNZXRob2QuZ2V0UGFyYW1ldGVyVHlwZXMoKTsKLQkJCQlpZiAocGFyYW1UeXBlcy5sZW5ndGggPT0gMSAmJiBwYXJhbVR5cGVzWzBdLmVxdWFscyhTZXJ2aWNlUmVmZXJlbmNlLmNsYXNzKSkgewotCQkJCQltZXRob2RQYXJhbSA9IHNlcnZpY2VSZWZlcmVuY2U7Ci0JCQkJfSBlbHNlIHsKLQkJCQkJLy8gYmluZGVkU2VydmljZXMgaXMgZmlsbGVkIGJ5IHRoZSBnZXRNZXRob2QgZnVuY3Rpb24KLQkJCQkJbWV0aG9kUGFyYW0gPSAoKENvbXBvbmVudEluc3RhbmNlSW1wbCkgaW5zdGFuY2UpLmJpbmRlZFNlcnZpY2VzLmdldChzZXJ2aWNlUmVmZXJlbmNlKTsKLQkJCQkJaWYgKG1ldGhvZFBhcmFtID09IG51bGwpIHsKLQkJCQkJCW1ldGhvZFBhcmFtID0gSW5zdGFuY2VQcm9jZXNzLnN0YXRpY1JlZi5nZXRTZXJ2aWNlKHJlZmVyZW5jZSwgc2VydmljZVJlZmVyZW5jZSk7Ci0JCQkJCQlpZiAobWV0aG9kUGFyYW0gIT0gbnVsbCkgewotCQkJCQkJCSgoQ29tcG9uZW50SW5zdGFuY2VJbXBsKSBpbnN0YW5jZSkuYmluZGVkU2VydmljZXMucHV0KHNlcnZpY2VSZWZlcmVuY2UsIG1ldGhvZFBhcmFtKTsKLQkJCQkJCX0KLQkJCQkJfQotCQkJCQlpZiAobWV0aG9kUGFyYW0gPT0gbnVsbCkgewotCQkJCQkJLy8gY2Fubm90IGdldCBzZXJ2aWNlT2JqZWN0IGJlY2F1c2Ugb2YgY2lyY3VsYXJpdHkKLQkJCQkJCUFjdGl2YXRvci5sb2cobnVsbCwgTG9nU2VydmljZS5MT0dfV0FSTklORywgTkxTLmJpbmQoTWVzc2FnZXMuVVBEQVRFRF9NRVRIT0RfTk9UX0NBTExFRCwgbmFtZSwgY29tcG9uZW50Lm5hbWUpLCBudWxsKTsKLQkJCQkJCXJldHVybjsKLQkJCQkJfQotCQkJCX0KLQotCQkJCU9iamVjdFtdIHBhcmFtcyA9IG51bGw7Ci0JCQkJaWYgKHBhcmFtVHlwZXMubGVuZ3RoID09IDEpIHsKLQkJCQkJcGFyYW1zID0gU0NSVXRpbC5nZXRPYmplY3RBcnJheSgpOwotCQkJCQlwYXJhbXNbMF0gPSBtZXRob2RQYXJhbTsKLQkJCQl9IGVsc2UgewotCQkJCQkvL3RoaXMgaXMgdGhlIGNhc2Ugd2hlcmUgd2UgaGF2ZSAyIHBhcmFtZXRlcnM6IGEgc2VydmljZSBvYmplY3QgYW5kIGEgTWFwLCBob2xkaW5nIHRoZSBzZXJ2aWNlIHByb3BlcnRpZXMKLQkJCQkJSGFzaE1hcCBtYXAgPSBuZXcgSGFzaE1hcCgpOwotCQkJCQlTdHJpbmdbXSBrZXlzID0gc2VydmljZVJlZmVyZW5jZS5nZXRQcm9wZXJ0eUtleXMoKTsKLQkJCQkJZm9yIChpbnQgaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgaSsrKSB7Ci0JCQkJCQltYXAucHV0KGtleXNbaV0sIHNlcnZpY2VSZWZlcmVuY2UuZ2V0UHJvcGVydHkoa2V5c1tpXSkpOwotCQkJCQl9Ci0JCQkJCXBhcmFtcyA9IG5ldyBPYmplY3RbXSB7bWV0aG9kUGFyYW0sIG1hcH07Ci0JCQkJfQotCi0JCQkJdHJ5IHsKLQkJCQkJdXBkYXRlZE1ldGhvZC5pbnZva2UoaW5zdGFuY2UuZ2V0SW5zdGFuY2UoKSwgcGFyYW1zKTsKLQkJCQl9IGNhdGNoIChUaHJvd2FibGUgdCkgewotCQkJCQlsb2dFcnJvcihOTFMuYmluZChNZXNzYWdlcy5FUlJPUl9VUERBVElOR19SRUZFUkVOQ0UsIHRoaXMsIGluc3RhbmNlLmdldEluc3RhbmNlKCkpLCB0LCByZWZlcmVuY2UpOwotCQkJCX0gZmluYWxseSB7Ci0JCQkJCWlmIChwYXJhbXMubGVuZ3RoID09IDEpIHsKLQkJCQkJCVNDUlV0aWwucmVsZWFzZShwYXJhbXMpOwotCQkJCQl9Ci0JCQkJfQotCQkJfSBlbHNlIHsKLQkJCQkvLyBjb3VsZCBiZSBhbHNvIGNpcmN1bGFyaXR5IGJyZWFrCi0JCQkJbG9nV2FybmluZyhOTFMuYmluZChNZXNzYWdlcy5VUERBVEVEX01FVEhPRF9OT1RfRk9VTkRfT1JfTk9UX0FDQ0VTU0lCTEUsIHVwZGF0ZWQpLCBudWxsLCByZWZlcmVuY2UpOwotCQkJfQotCQl9Ci0JfQotCi0JcHVibGljIGZpbmFsIHZvaWQgZGlzcG9zZSgpIHsKLQkJYmluZENhY2hlZCA9IHVuYmluZENhY2hlZCA9IHVwZGF0ZWRDYWNoZWQgPSBmYWxzZTsKLQkJYmluZE1ldGhvZCA9IHVuYmluZE1ldGhvZCA9IHVwZGF0ZWRNZXRob2QgPSBudWxsOwotCQlzZXJ2aWNlUmVmZXJlbmNlcyA9IG51bGw7Ci0JfQotCi0JcHVibGljIGZpbmFsIFN0cmluZyB0b1N0cmluZygpIHsKLQkJU3RyaW5nQnVmZmVyIGJ1ZmZlciA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKLQkJYnVmZmVyLmFwcGVuZCgiUmVmZXJlbmNlWyIpOyAvLyROT04tTkxTLTEkCi0JCWJ1ZmZlci5hcHBlbmQoIm5hbWUgPSAiKS5hcHBlbmQobmFtZSk7IC8vJE5PTi1OTFMtMSQKLQkJYnVmZmVyLmFwcGVuZCgiLCBpbnRlcmZhY2UgPSAiKS5hcHBlbmQoaW50ZXJmYWNlTmFtZSk7IC8vJE5PTi1OTFMtMSQKLQkJYnVmZmVyLmFwcGVuZCgiLCBwb2xpY3kgPSAiKTsgLy8kTk9OLU5MUy0xJAotCQlzd2l0Y2ggKHBvbGljeSkgewotCQkJY2FzZSBQT0xJQ1lfRFlOQU1JQyA6Ci0JCQkJYnVmZmVyLmFwcGVuZCgiZHluYW1pYyIpOyAvLyROT04tTkxTLTEkCi0JCQkJYnJlYWs7Ci0JCQljYXNlIFBPTElDWV9TVEFUSUMgOgotCQkJCWJ1ZmZlci5hcHBlbmQoInN0YXRpYyIpOyAvLyROT04tTkxTLTEkCi0JCX0KLQkJaWYgKGNvbXBvbmVudC5pc05hbWVzcGFjZUF0TGVhc3QxMigpKSB7Ci0JCQlidWZmZXIuYXBwZW5kKCIsIHBvbGljeS1vcHRpb24gPSAiKTsgLy8kTk9OLU5MUy0xJAotCQkJc3dpdGNoIChwb2xpY3lfb3B0aW9uKSB7Ci0JCQkJY2FzZSBQT0xJQ1lfT1BUSU9OX1JFTFVDVEFOVCA6Ci0JCQkJCWJ1ZmZlci5hcHBlbmQoInJlbHVjdGFudCIpOyAvLyROT04tTkxTLTEkCi0JCQkJCWJyZWFrOwotCQkJCWNhc2UgUE9MSUNZX09QVElPTl9HUkVFRFkgOgotCQkJCQlidWZmZXIuYXBwZW5kKCJncmVlZHkiKTsgLy8kTk9OLU5MUy0xJAotCQkJfQotCQl9Ci0KLQkJYnVmZmVyLmFwcGVuZCgiLCBjYXJkaW5hbGl0eSA9ICIpOyAvLyROT04tTkxTLTEkCi0JCXN3aXRjaCAoY2FyZGluYWxpdHkpIHsKLQkJCWNhc2UgQ0FSRElOQUxJVFlfMF8xIDoKLQkJCQlidWZmZXIuYXBwZW5kKCIwLi4xIik7IC8vJE5PTi1OTFMtMSQKLQkJCQlicmVhazsKLQkJCWNhc2UgQ0FSRElOQUxJVFlfMF9OIDoKLQkJCQlidWZmZXIuYXBwZW5kKCIwLi5uIik7IC8vJE5PTi1OTFMtMSQKLQkJCQlicmVhazsKLQkJCWNhc2UgQ0FSRElOQUxJVFlfMV8xIDoKLQkJCQlidWZmZXIuYXBwZW5kKCIxLi4xIik7IC8vJE5PTi1OTFMtMSQKLQkJCQlicmVhazsKLQkJCWNhc2UgQ0FSRElOQUxJVFlfMV9OIDoKLQkJCQlidWZmZXIuYXBwZW5kKCIxLi5uIik7IC8vJE5PTi1OTFMtMSQKLQkJfQotCQlidWZmZXIuYXBwZW5kKCIsIHRhcmdldCA9ICIpLmFwcGVuZCh0YXJnZXQpOyAvLyROT04tTkxTLTEkCi0JCWJ1ZmZlci5hcHBlbmQoIiwgYmluZCA9ICIpLmFwcGVuZChiaW5kKTsgLy8kTk9OLU5MUy0xJAotCQlidWZmZXIuYXBwZW5kKCIsIHVuYmluZCA9ICIpLmFwcGVuZCh1bmJpbmQpOyAvLyROT04tTkxTLTEkCi0JCWlmIChjb21wb25lbnQuaXNOYW1lc3BhY2VBdExlYXN0MTIoKSkgewotCQkJYnVmZmVyLmFwcGVuZCgiLCB1cGRhdGVkID0gIikuYXBwZW5kKHVwZGF0ZWQpOyAvLyROT04tTkxTLTEkCi0JCX0KLQkJYnVmZmVyLmFwcGVuZCgiXSIpOyAvLyROT04tTkxTLTEkCi0JCXJldHVybiBidWZmZXIudG9TdHJpbmcoKTsKLQl9Ci0KLQkvKgotCSAqIChub24tSmF2YWRvYykKLQkgKiAKLQkgKiBAc2VlIG9yZy5lY2xpcHNlLmVxdWlub3guaW50ZXJuYWwudXRpbC5pby5FeHRlcm5hbGl6YWJsZSN3cml0ZU9iamVjdChqYXZhLmlvLk91dHB1dFN0cmVhbSkKLQkgKi8KLQlwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgd3JpdGVPYmplY3QoT3V0cHV0U3RyZWFtIG8pIHRocm93cyBFeGNlcHRpb24gewotCQl0cnkgewotCQkJRGF0YU91dHB1dFN0cmVhbSBvdXQ7Ci0JCQlpZiAobyBpbnN0YW5jZW9mIERhdGFPdXRwdXRTdHJlYW0pIHsKLQkJCQlvdXQgPSAoRGF0YU91dHB1dFN0cmVhbSkgbzsKLQkJCX0gZWxzZSB7Ci0JCQkJb3V0ID0gbmV3IERhdGFPdXRwdXRTdHJlYW0obyk7Ci0JCQl9Ci0JCQlib29sZWFuIGZsYWc7Ci0JCQlvdXQud3JpdGVVVEYobmFtZSk7Ci0JCQlvdXQud3JpdGVVVEYoaW50ZXJmYWNlTmFtZSk7Ci0JCQlvdXQud3JpdGVJbnQoY2FyZGluYWxpdHkpOwotCQkJb3V0LndyaXRlSW50KHBvbGljeSk7Ci0KLQkJCWZsYWcgPSB0YXJnZXQgIT0gbnVsbDsKLQkJCW91dC53cml0ZUJvb2xlYW4oZmxhZyk7Ci0JCQlpZiAoZmxhZykKLQkJCQlvdXQud3JpdGVVVEYodGFyZ2V0KTsKLQotCQkJZmxhZyA9IGJpbmQgIT0gbnVsbDsKLQkJCW91dC53cml0ZUJvb2xlYW4oZmxhZyk7Ci0JCQlpZiAoZmxhZykKLQkJCQlvdXQud3JpdGVVVEYoYmluZCk7Ci0KLQkJCWZsYWcgPSB1bmJpbmQgIT0gbnVsbDsKLQkJCW91dC53cml0ZUJvb2xlYW4oZmxhZyk7Ci0JCQlpZiAoZmxhZykKLQkJCQlvdXQud3JpdGVVVEYodW5iaW5kKTsKLQotCQkJLy8gRFMgMS4yIHN1cHBvcnQKLQkJCW91dC53cml0ZUJvb2xlYW4oY29tcG9uZW50LmlzTmFtZXNwYWNlQXRMZWFzdDEyKCkpOwotCQkJaWYgKGNvbXBvbmVudC5pc05hbWVzcGFjZUF0TGVhc3QxMigpKSB7Ci0JCQkJZmxhZyA9IHVwZGF0ZWQgIT0gbnVsbDsKLQkJCQlvdXQud3JpdGVCb29sZWFuKGZsYWcpOwotCQkJCWlmIChmbGFnKQotCQkJCQlvdXQud3JpdGVVVEYodXBkYXRlZCk7Ci0KLQkJCQlvdXQud3JpdGVJbnQocG9saWN5X29wdGlvbik7Ci0JCQl9Ci0JCX0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7Ci0JCQlBY3RpdmF0b3IubG9nKG51bGwsIExvZ1NlcnZpY2UuTE9HX0VSUk9SLCBNZXNzYWdlcy5FUlJPUl9XUklUSU5HX09CSkVDVCwgZSk7Ci0JCQl0aHJvdyBlOwotCQl9Ci0JfQotCi0JLyoKLQkgKiAobm9uLUphdmFkb2MpCi0JICogCi0JICogQHNlZSBvcmcuZWNsaXBzZS5lcXVpbm94LmludGVybmFsLnV0aWwuaW8uRXh0ZXJuYWxpemFibGUjcmVhZE9iamVjdChqYXZhLmlvLklucHV0U3RyZWFtKQotCSAqLwotCXB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCByZWFkT2JqZWN0KElucHV0U3RyZWFtIHMpIHRocm93cyBFeGNlcHRpb24gewotCQl0cnkgewotCQkJRGF0YUlucHV0U3RyZWFtIGluOwotCQkJaWYgKHMgaW5zdGFuY2VvZiBEYXRhSW5wdXRTdHJlYW0pIHsKLQkJCQlpbiA9IChEYXRhSW5wdXRTdHJlYW0pIHM7Ci0JCQl9IGVsc2UgewotCQkJCWluID0gbmV3IERhdGFJbnB1dFN0cmVhbShzKTsKLQkJCX0KLQkJCWJvb2xlYW4gZmxhZzsKLQkJCW5hbWUgPSBpbi5yZWFkVVRGKCk7Ci0JCQlpbnRlcmZhY2VOYW1lID0gaW4ucmVhZFVURigpOwotCQkJY2FyZGluYWxpdHkgPSBpbi5yZWFkSW50KCk7Ci0JCQlwb2xpY3kgPSBpbi5yZWFkSW50KCk7Ci0JCQlmbGFnID0gaW4ucmVhZEJvb2xlYW4oKTsKLQkJCWlmIChmbGFnKQotCQkJCXRhcmdldCA9IGluLnJlYWRVVEYoKTsKLQotCQkJZmxhZyA9IGluLnJlYWRCb29sZWFuKCk7Ci0JCQlpZiAoZmxhZykKLQkJCQliaW5kID0gaW4ucmVhZFVURigpOwotCi0JCQlmbGFnID0gaW4ucmVhZEJvb2xlYW4oKTsKLQkJCWlmIChmbGFnKQotCQkJCXVuYmluZCA9IGluLnJlYWRVVEYoKTsKLQotCQkJLy8gRFMgMS4yIHN1cHBvcnQKLQkJCWZsYWcgPSBpbi5yZWFkQm9vbGVhbigpOwotCQkJaWYgKGZsYWcpIHsKLQkJCQkvL1RoaXMgaXMgYSBEUyAxLjIgY29tcG9uZW50Ci0JCQkJZmxhZyA9IGluLnJlYWRCb29sZWFuKCk7Ci0JCQkJaWYgKGZsYWcpCi0JCQkJCXVwZGF0ZWQgPSBpbi5yZWFkVVRGKCk7Ci0JCQkJcG9saWN5X29wdGlvbiA9IGluLnJlYWRJbnQoKTsKLQkJCX0KLQkJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKLQkJCUFjdGl2YXRvci5sb2cobnVsbCwgTG9nU2VydmljZS5MT0dfRVJST1IsIE1lc3NhZ2VzLkVSUk9SX1JFQURJTkdfT0JKRUNULCBlKTsKLQkJCXRocm93IGU7Ci0JCX0KLQl9Ci0KLQlwdWJsaWMgU3RyaW5nIGdldEJpbmRNZXRob2ROYW1lKCkgewotCQlyZXR1cm4gYmluZDsKLQl9Ci0KLQlwdWJsaWMgU3RyaW5nIGdldE5hbWUoKSB7Ci0JCXJldHVybiBuYW1lOwotCX0KLQotCXB1YmxpYyBTdHJpbmcgZ2V0U2VydmljZU5hbWUoKSB7Ci0JCXJldHVybiBpbnRlcmZhY2VOYW1lOwotCX0KLQotCXB1YmxpYyBTZXJ2aWNlUmVmZXJlbmNlW10gZ2V0U2VydmljZVJlZmVyZW5jZXMoKSB7Ci0JCVZlY3RvciByZXN1bHQgPSBudWxsOwotCQlpZiAoYmluZCAhPSBudWxsKSB7Ci0JCQlpZiAoIXNlcnZpY2VSZWZlcmVuY2VzLmlzRW1wdHkoKSkgewotCQkJCXJlc3VsdCA9IG5ldyBWZWN0b3IoMik7Ci0JCQkJRW51bWVyYXRpb24ga2V5cyA9IHNlcnZpY2VSZWZlcmVuY2VzLmtleXMoKTsKLQkJCQl3aGlsZSAoa2V5cy5oYXNNb3JlRWxlbWVudHMoKSkgewotCQkJCQlyZXN1bHQuYWRkKGtleXMubmV4dEVsZW1lbnQoKSk7Ci0JCQkJfQotCQkJfQotCQl9Ci0JCWlmIChyZXN1bHQgIT0gbnVsbCAmJiAhcmVzdWx0LmlzRW1wdHkoKSkgewotCQkJU2VydmljZVJlZmVyZW5jZVtdIGZpbmFsUmVzdWx0ID0gbmV3IFNlcnZpY2VSZWZlcmVuY2VbcmVzdWx0LnNpemUoKV07Ci0JCQlyZXN1bHQuY29weUludG8oZmluYWxSZXN1bHQpOwotCQkJcmV0dXJuIGZpbmFsUmVzdWx0OwotCQl9Ci0JCXJldHVybiBudWxsOwotCX0KLQotCXB1YmxpYyBTdHJpbmcgZ2V0VGFyZ2V0KCkgewotCQlyZXR1cm4gdGFyZ2V0OwotCX0KLQotCXB1YmxpYyBTdHJpbmcgZ2V0VW5iaW5kTWV0aG9kTmFtZSgpIHsKLQkJcmV0dXJuIHVuYmluZDsKLQl9Ci0KLQlwdWJsaWMgYm9vbGVhbiBpc011bHRpcGxlKCkgewotCQlyZXR1cm4gY2FyZGluYWxpdHkgPT0gQ29tcG9uZW50UmVmZXJlbmNlLkNBUkRJTkFMSVRZXzBfTiB8fCBjYXJkaW5hbGl0eSA9PSBDb21wb25lbnRSZWZlcmVuY2UuQ0FSRElOQUxJVFlfMV9OOwotCX0KLQotCXB1YmxpYyBib29sZWFuIGlzT3B0aW9uYWwoKSB7Ci0JCXJldHVybiBjYXJkaW5hbGl0eSA9PSBDb21wb25lbnRSZWZlcmVuY2UuQ0FSRElOQUxJVFlfMF8xIHx8IGNhcmRpbmFsaXR5ID09IENvbXBvbmVudFJlZmVyZW5jZS5DQVJESU5BTElUWV8wX047Ci0JfQotCi0JcHVibGljIGJvb2xlYW4gaXNTYXRpc2ZpZWQoKSB7Ci0JCWlmIChpc09wdGlvbmFsKCkpIHsKLQkJCXJldHVybiB0cnVlOwotCQl9Ci0JCXRyeSB7Ci0JCQlTZXJ2aWNlUmVmZXJlbmNlW10gX3NlcnZpY2VSZWZlcmVuY2VzID0gY29tcG9uZW50LmJjLmdldFNlcnZpY2VSZWZlcmVuY2VzKGludGVyZmFjZU5hbWUsIHRhcmdldCk7Ci0JCQlpZiAoX3NlcnZpY2VSZWZlcmVuY2VzICE9IG51bGwpIHsKLQkJCQlyZXR1cm4gdHJ1ZTsKLQkJCX0KLQkJfSBjYXRjaCAoSW52YWxpZFN5bnRheEV4Y2VwdGlvbiBlKSB7Ci0JCQkvLyBkbyBub3RoaW5nCi0JCX0KLQkJcmV0dXJuIGZhbHNlOwotCX0KLQotCXB1YmxpYyBib29sZWFuIGlzU3RhdGljKCkgewotCQlyZXR1cm4gcG9saWN5ID09IENvbXBvbmVudFJlZmVyZW5jZS5QT0xJQ1lfU1RBVElDOwotCX0KLQotCS8qIChub24tSmF2YWRvYykKLQkgKiBAc2VlIG9yZy5hcGFjaGUuZmVsaXguc2NyLlJlZmVyZW5jZSNnZXRVcGRhdGVkTWV0aG9kTmFtZSgpCi0JICovCi0JcHVibGljIFN0cmluZyBnZXRVcGRhdGVkTWV0aG9kTmFtZSgpIHsKLQkJaWYgKGNvbXBvbmVudC5pc05hbWVzcGFjZUF0TGVhc3QxMigpKSB7Ci0JCQlyZXR1cm4gdXBkYXRlZDsKLQkJfQotCQlyZXR1cm4gbnVsbDsKLQl9Ci0KLX0KZGlmZiAtLWdpdCBhL2J1bmRsZXMvb3JnLmVjbGlwc2UuZXF1aW5veC5kcy9zcmMvb3JnL2VjbGlwc2UvZXF1aW5veC9pbnRlcm5hbC9kcy9tb2RlbC9EZWNsYXJhdGlvblBhcnNlci5qYXZhIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5lcXVpbm94LmRzL3NyYy9vcmcvZWNsaXBzZS9lcXVpbm94L2ludGVybmFsL2RzL21vZGVsL0RlY2xhcmF0aW9uUGFyc2VyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDhmNGYyOTUuLjAwMDAwMDAKLS0tIGEvYnVuZGxlcy9vcmcuZWNsaXBzZS5lcXVpbm94LmRzL3NyYy9vcmcvZWNsaXBzZS9lcXVpbm94L2ludGVybmFsL2RzL21vZGVsL0RlY2xhcmF0aW9uUGFyc2VyLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw4ODUgKzAsMCBAQAotLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKLSAqIENvcHlyaWdodCAoYykgMTk5NywgMjAxMCBieSBQcm9TeXN0IFNvZnR3YXJlIEdtYkgKLSAqIGh0dHA6Ly93d3cucHJvc3lzdC5jb20KLSAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMKLSAqIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2UgdjEuMAotICogd2hpY2ggYWNjb21wYW5pZXMgdGhpcyBkaXN0cmlidXRpb24sIGFuZCBpcyBhdmFpbGFibGUgYXQKLSAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLXYxMC5odG1sCi0gKgotICogQ29udHJpYnV0b3JzOgotICogICAgUHJvU3lzdCBTb2Z0d2FyZSBHbWJIIC0gaW5pdGlhbCBBUEkgYW5kIGltcGxlbWVudGF0aW9uCi0gKiAgICBMYXphciBLaXJjaGV2CQkgCS0gYnVnLmlkID0gMzIwMzc3Ci0gKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLXBhY2thZ2Ugb3JnLmVjbGlwc2UuZXF1aW5veC5pbnRlcm5hbC5kcy5tb2RlbDsKLQotaW1wb3J0IGphdmEuaW8uSU9FeGNlcHRpb247Ci1pbXBvcnQgamF2YS5pby5JbnB1dFN0cmVhbTsKLWltcG9ydCBqYXZhLm5ldC5VUkw7Ci1pbXBvcnQgamF2YS51dGlsLio7Ci1pbXBvcnQgb3JnLmVjbGlwc2UuZXF1aW5veC5pbnRlcm5hbC5kcy5BY3RpdmF0b3I7Ci1pbXBvcnQgb3JnLmVjbGlwc2UuZXF1aW5veC5pbnRlcm5hbC5kcy5NZXNzYWdlczsKLWltcG9ydCBvcmcuZWNsaXBzZS5lcXVpbm94LmludGVybmFsLnV0aWwueG1sLio7Ci1pbXBvcnQgb3JnLmVjbGlwc2Uub3NnaS51dGlsLk5MUzsKLWltcG9ydCBvcmcub3NnaS5mcmFtZXdvcmsuKjsKLWltcG9ydCBvcmcub3NnaS5zZXJ2aWNlLmxvZy5Mb2dTZXJ2aWNlOwotCi0vKioKLSAqIFByb2Nlc3NlcyB0aGUgcGFyc2luZyBvZiB0aGUgY29tcG9uZW50IGRlc2NyaXB0aW9uIFhNTHMKLSAqIAotICogQGF1dGhvciBWYWxlbnRpbiBWYWxjaGV2Ci0gKiBAYXV0aG9yIFN0b3lhbiBCb3NoZXYKLSAqIEBhdXRob3IgUGF2bGluIERvYnJldgotICogQGF1dGhvciBUZW9kb3IgQmFrYXJkemhpZXYKLSAqLwotcHVibGljIGNsYXNzIERlY2xhcmF0aW9uUGFyc2VyIGltcGxlbWVudHMgRXhUYWdMaXN0ZW5lciB7Ci0KLQlwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgWE1MTlNfMV8wID0gImh0dHA6Ly93d3cub3NnaS5vcmcveG1sbnMvc2NyL3YxLjAuMCI7IC8vJE5PTi1OTFMtMSQKLQlwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgWE1MTlNfMV8xID0gImh0dHA6Ly93d3cub3NnaS5vcmcveG1sbnMvc2NyL3YxLjEuMCI7IC8vJE5PTi1OTFMtMSQKLQlwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgWE1MTlNfMV8yID0gImh0dHA6Ly93d3cub3NnaS5vcmcveG1sbnMvc2NyL3YxLjIuMCI7IC8vJE5PTi1OTFMtMSQKLQlwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgQVRUUl9YTUxOUyA9ICJ4bWxucyI7IC8vJE5PTi1OTFMtMSQKLQotCXByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBDT01QT05FTlRfVEFHX05BTUUgPSAiY29tcG9uZW50IjsgLy8kTk9OLU5MUy0xJAotCi0JLy9jb21wb25lbnQgYXR0cmlidXRlcwotCXByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBBVFRSX0FVVE9FTkFCTEUgPSAiZW5hYmxlZCI7IC8vJE5PTi1OTFMtMSQKLQlwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgQVRUUl9OQU1FID0gIm5hbWUiOyAvLyROT04tTkxTLTEkCi0JcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEFUVFJfRkFDVE9SWSA9ICJmYWN0b3J5IjsgLy8kTk9OLU5MUy0xJAotCXByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBBVFRSX0lNTUVESUFURSA9ICJpbW1lZGlhdGUiOyAvLyROT04tTkxTLTEkCi0JLy9jb21wb25lbnQgYXR0cmlidXRlcyBhY2NvcmRpbmcgdG8gc2NoZW1hIHYxLjEKLQlwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgQVRUUl9DT05GX1BPTElDWSA9ICJjb25maWd1cmF0aW9uLXBvbGljeSI7IC8vJE5PTi1OTFMtMSQKLQlwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgQVRUUl9BQ1RJVkFURSA9ICJhY3RpdmF0ZSI7IC8vJE5PTi1OTFMtMSQKLQlwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgQVRUUl9ERUFDVElWQVRFID0gImRlYWN0aXZhdGUiOyAvLyROT04tTkxTLTEkCi0JcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEFUVFJfTU9ESUZJRUQgPSAibW9kaWZpZWQiOyAvLyROT04tTkxTLTEkCi0JLy9jb21wb25lbnQgYXR0cmlidXRlcyBhY2NvcmRpbmcgdG8gc2NoZW1hIHYxLjIKLQlwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgQVRUUl9DT05GSUdVUkFUSU9OX1BJRCA9ICJjb25maWd1cmF0aW9uLXBpZCI7IC8vJE5PTi1OTFMtMSQKLQotCXByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBUQUdfSU1QTEVNRU5UQVRJT04gPSAiaW1wbGVtZW50YXRpb24iOyAvLyROT04tTkxTLTEkCi0JcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEFUVFJfQ0xBU1MgPSAiY2xhc3MiOyAvLyROT04tTkxTLTEkCi0KLQlwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgVEFHX1BST1BFUlRZID0gInByb3BlcnR5IjsgLy8kTk9OLU5MUy0xJAotCXByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBBVFRSX1ZBTFVFID0gInZhbHVlIjsgLy8kTk9OLU5MUy0xJAotCXByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBBVFRSX1RZUEUgPSAidHlwZSI7IC8vJE5PTi1OTFMtMSQKLQotCXByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBUQUdfUFJPUEVSVElFUyA9ICJwcm9wZXJ0aWVzIjsgLy8kTk9OLU5MUy0xJAotCXByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBBVFRSX0VOVFJZID0gImVudHJ5IjsgLy8kTk9OLU5MUy0xJAotCi0JcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFRBR19TRVJWSUNFID0gInNlcnZpY2UiOyAvLyROT04tTkxTLTEkCi0JcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEFUVFJfU0VSVklDRUZBQ1RPUlkgPSAic2VydmljZWZhY3RvcnkiOyAvLyROT04tTkxTLTEkCi0JcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFRBR19QUk9WSURFID0gInByb3ZpZGUiOyAvLyROT04tTkxTLTEkCi0JcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEFUVFJfSU5URVJGQUNFID0gImludGVyZmFjZSI7IC8vJE5PTi1OTFMtMSQKLQotCXByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBUQUdfUkVGRVJFTkNFID0gInJlZmVyZW5jZSI7IC8vJE5PTi1OTFMtMSQKLQlwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgQVRUUl9DQVJESU5BTElUWSA9ICJjYXJkaW5hbGl0eSI7IC8vJE5PTi1OTFMtMSQKLQlwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgQVRUUl9QT0xJQ1kgPSAicG9saWN5IjsgLy8kTk9OLU5MUy0xJAotCXByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBBVFRSX1RBUkdFVCA9ICJ0YXJnZXQiOyAvLyROT04tTkxTLTEkCi0JcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEFUVFJfQklORCA9ICJiaW5kIjsgLy8kTk9OLU5MUy0xJAotCXByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBBVFRSX1VOQklORCA9ICJ1bmJpbmQiOyAvLyROT04tTkxTLTEkCi0JLy9yZWZlcmVuY2UgYXR0cmlidXRlcyBhY2NvcmRpbmcgdG8gc2NoZW1hIHYxLjIKLQlwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgQVRUUl9VUERBVEVEID0gInVwZGF0ZWQiOyAvLyROT04tTkxTLTEkCi0JcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEFUVFJfUE9MSUNZX09QVElPTiA9ICJwb2xpY3ktb3B0aW9uIjsgLy8kTk9OLU5MUy0xJAotCi0JLyoqIENvbnN0YW50IGZvciBTdHJpbmcgcHJvcGVydHkgdHlwZSAqLwotCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNUUklORyA9IDE7Ci0JLyoqIENvbnN0YW50IGZvciBMb25nIHByb3BlcnR5IHR5cGUgKi8KLQlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBMT05HID0gMjsKLQkvKiogQ29uc3RhbnQgZm9yIEludGVnZXIgcHJvcGVydHkgdHlwZSAqLwotCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IElOVEVHRVIgPSAzOwotCS8qKiBDb25zdGFudCBmb3IgU2hvcnQgcHJvcGVydHkgdHlwZSAqLwotCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IFNIT1JUID0gNDsKLQkvKiogQ29uc3RhbnQgZm9yIENoYXIgcHJvcGVydHkgdHlwZSAqLwotCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IENIQVJBQ1RFUiA9IDU7Ci0JLyoqIENvbnN0YW50IGZvciBCeXRlIHByb3BlcnR5IHR5cGUgKi8KLQlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBCWVRFID0gNjsKLQkvKiogQ29uc3RhbnQgZm9yIERvdWJsZSBwcm9wZXJ0eSB0eXBlICovCi0JcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgRE9VQkxFID0gNzsKLQkvKiogQ29uc3RhbnQgZm9yIEZsb2F0IHByb3BlcnR5IHR5cGUgKi8KLQlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBGTE9BVCA9IDg7Ci0JLyoqIENvbnN0YW50IGZvciBCb29sZWFuIHByb3BlcnR5IHR5cGUgKi8KLQlwdWJsaWMgc3RhdGljIGZpbmFsIGludCBCT09MRUFOID0gMTE7Ci0KLQlwdWJsaWMgVmVjdG9yIGNvbXBvbmVudHM7Ci0KLQlwcml2YXRlIGJvb2xlYW4gdGhyb3dFcnJvcnMgPSBmYWxzZTsKLQotCXByaXZhdGUgQnVuZGxlIGJ1bmRsZTsKLQlwcml2YXRlIEJ1bmRsZUNvbnRleHQgYmM7Ci0JcHJpdmF0ZSBTZXJ2aWNlQ29tcG9uZW50IGN1cnJlbnRDb21wb25lbnQ7Ci0JcHJpdmF0ZSBTdHJpbmcgY2xvc2VUYWc7Ci0JYm9vbGVhbiBpbW1lZGlhdGVTZXQgPSBmYWxzZTsKLQlwcml2YXRlIEhhc2h0YWJsZSBuYW1lc3BhY2VzID0gbnVsbDsKLQlwcml2YXRlIGJvb2xlYW4gcm9vdFBhc3NlZCA9IGZhbHNlOwotCXByaXZhdGUgU3RyaW5nIGN1cnJlbnRVUkwgPSBudWxsOwotCi0JcHVibGljIERlY2xhcmF0aW9uUGFyc2VyKCkgewotCQl0aGlzKGZhbHNlKTsKLQl9Ci0KLQlwdWJsaWMgRGVjbGFyYXRpb25QYXJzZXIoYm9vbGVhbiB0b1Rocm93RXJyb3JzKSB7Ci0JCXRoaXMudGhyb3dFcnJvcnMgPSB0b1Rocm93RXJyb3JzOwotCX0KLQotCS8qKgotCSAqIFRoaXMgbWV0aG9kIHBhcnNlcyBhbiBYTUwgZmlsZSByZWFkIGZyb20gdGhlIGdpdmVuIHN0cmVhbSBhbmQgY29udmVydHMKLQkgKiB0aGUgY29tcG9uZW50cyBkZWZpbml0aW9ucyBpbnRvIGEgamF2YSBvYmplY3QuCi0JICogPHA+Ci0JICogCi0JICogSXQgYWxzbyBwZXJmb3JtcyBhIGZ1bGwgWE1MIHZlcmlmaWNhdGlvbiBvZiB0aGUgZGVmaW5pdGlvbi7vv70KLQkgKiAKLQkgKiBAcGFyYW0gaW4KLQkgKiAgICAgICAgICAgIHRoZSBpbnB1dCBzdHJlYW0gdG8gdGhlIFhNTCBkZWNsYXJhdGlvbiBmaWxlCi0JICogQHBhcmFtIGJ1bmRsZQotCSAqICAgICAgICAgICAgdGhpcyBpcyB1c2VkIHRvIGxvYWQgdGhlICdwcm9wZXJ0aWVzJyB0YWcKLQkgKiBAcGFyYW0gY29tcG9uZW50cyBzZXRzIHRoZSBjb21wb25lbnRzIFZlY3RvciB3aGVyZSB0aGUgcGFyc2VkIGNvbXBvbmVudHMgc2hvdWxkIGJlIHBsYWNlZAotCSAqIEBwYXJhbSBwcm9jZXNzaW5nVVJMIHRoZSBVUkwgb2YgdGhlIFhNTCB3aGljaCBpcyBiZWluZyBwcm9jZXNzZWQuIFdpbGwgYmUgdXNlZCBmb3IgZGVidWdnaW5nIHB1cnBvc2VzCi0JICogQHRocm93cyBFeGNlcHRpb24gaWYgYW55IHVuaGFuZGxlZCBleGNlcHRpb24gb2NjdXJzIGR1cmluZyB0aGUgcGFyc2luZwotCSAqLwotCXB1YmxpYyB2b2lkIHBhcnNlKElucHV0U3RyZWFtIGluLCBCdW5kbGUgYnVuZGxlLCBWZWN0b3IgY29tcG9uZW50cywgU3RyaW5nIHByb2Nlc3NpbmdVUkwpIHRocm93cyBFeGNlcHRpb24gewotCQl0aGlzLmNvbXBvbmVudHMgPSBjb21wb25lbnRzOwotCQl0aGlzLmJ1bmRsZSA9IGJ1bmRsZTsKLQkJdGhpcy5iYyA9IGJ1bmRsZS5nZXRCdW5kbGVDb250ZXh0KCk7Ci0JCXRoaXMuY3VycmVudFVSTCA9IHByb2Nlc3NpbmdVUkw7Ci0JCXJvb3RQYXNzZWQgPSBmYWxzZTsKLQkJWE1MUGFyc2VyLnBhcnNlWE1MKGluLCB0aGlzLCAtMSk7Ci0KLQkJLy8gcmVsZWFzZSB0ZW1wb3Jhcnkgb2JqZWN0cwotCQl0aGlzLmJ1bmRsZSA9IG51bGw7Ci0JCXRoaXMuYmMgPSBudWxsOwotCQl0aGlzLmN1cnJlbnRDb21wb25lbnQgPSBudWxsOwotCQl0aGlzLmN1cnJlbnRVUkwgPSBudWxsOwotCQl0aGlzLmNsb3NlVGFnID0gbnVsbDsKLQkJdGhpcy5uYW1lc3BhY2VzID0gbnVsbDsKLQl9Ci0KLQkvKgotCSAqIChub24tSmF2YWRvYykKLQkgKiAKLQkgKiBAc2VlIG9yZy5lY2xpcHNlLmVxdWlub3guaW50ZXJuYWwudXRpbC54bWwuRXhUYWdMaXN0ZW5lciNzdGFydFRhZyhvcmcuZWNsaXBzZS5lcXVpbm94LmludGVybmFsLnV0aWwueG1sLlRhZykKLQkgKi8KLQlwdWJsaWMgZmluYWwgdm9pZCBzdGFydFRhZyhUYWcgdGFnKSB7Ci0JCXRyeSB7Ci0JCQlwcm9jZXNzTmFtZXNwYWNlc0VudGVyKHRhZyk7Ci0JCQlTdHJpbmcgdGFnTmFtZSA9IHRhZy5nZXROYW1lKCk7Ci0JCQlpZiAoaXNDb3JyZWN0Q29tcG9uZW50VGFnKHRhZ05hbWUpKSB7Ci0JCQkJZG9Db3JyZWN0Q29tcG9uZW50VGFnKHRhZywgdGFnTmFtZSk7Ci0JCQl9Ci0JCX0gY2F0Y2ggKElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpYWUpIHsKLQkJCWN1cnJlbnRDb21wb25lbnQgPSBudWxsOyAvL3RoZSBjb21wb25lbnQgaXMgYmFkIC0gaWdub3JpbmcgaXQKLQkJCWNsb3NlVGFnID0gbnVsbDsKLQkJCUFjdGl2YXRvci5sb2coYnVuZGxlLmdldEJ1bmRsZUNvbnRleHQoKSwgTG9nU2VydmljZS5MT0dfRVJST1IsIE5MUy5iaW5kKE1lc3NhZ2VzLkVSUk9SX1BST0NFU1NJTkdfU1RBUlRfVEFHLCBjdXJyZW50VVJMLCBidW5kbGUpICsgaWFlLmdldE1lc3NhZ2UoKSwgbnVsbCk7Ci0JCQlpZiAoQWN0aXZhdG9yLkRFQlVHKSB7Ci0JCQkJQWN0aXZhdG9yLmxvZy5kZWJ1ZygiW1NDUl0gVHJhY2luZyB0aGUgbGFzdCBleGNlcHRpb24iLCBpYWUpOyAvLyROT04tTkxTLTEkCi0JCQl9Ci0JCQlpZiAodGhyb3dFcnJvcnMpIHsKLQkJCQl0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihOTFMuYmluZChNZXNzYWdlcy5FUlJPUl9QUk9DRVNTSU5HX1NUQVJUX1RBRywgY3VycmVudFVSTCwgYnVuZGxlKSArIGlhZS5nZXRNZXNzYWdlKCksIGlhZSk7Ci0JCQl9Ci0JCX0gY2F0Y2ggKFRocm93YWJsZSBlKSB7Ci0JCQlBY3RpdmF0b3IubG9nKGJ1bmRsZS5nZXRCdW5kbGVDb250ZXh0KCksIExvZ1NlcnZpY2UuTE9HX0VSUk9SLCBOTFMuYmluZChNZXNzYWdlcy5FUlJPUl9QUk9DRVNTSU5HX1NUQVJUX1RBRywgY3VycmVudFVSTCwgYnVuZGxlKSwgZSk7Ci0JCQlpZiAodGhyb3dFcnJvcnMpIHsKLQkJCQl0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihOTFMuYmluZChNZXNzYWdlcy5FUlJPUl9QUk9DRVNTSU5HX1NUQVJUX1RBRywgY3VycmVudFVSTCwgYnVuZGxlKSArIGUuZ2V0TWVzc2FnZSgpLCBlKTsKLQkJCX0KLQkJfSBmaW5hbGx5IHsKLQkJCWlmICghcm9vdFBhc3NlZCkgewotCQkJCXJvb3RQYXNzZWQgPSB0cnVlOwotCQkJfQotCQl9Ci0JfQotCi0JcHJpdmF0ZSB2b2lkIGRvRW5kVGFnKFRhZyB0YWcpIHRocm93cyBJbnZhbGlkU3ludGF4RXhjZXB0aW9uIHsKLQkJaWYgKGN1cnJlbnRDb21wb25lbnQgIT0gbnVsbCkgewotCQkJU3RyaW5nIHRhZ05hbWUgPSB0YWcuZ2V0TmFtZSgpLmludGVybigpOwotCQkJaWYgKHRhZ05hbWUgPT0gVEFHX0lNUExFTUVOVEFUSU9OKSB7Ci0JCQkJZG9JbXBsZW1lbnRhdGlvbih0YWcpOwotCQkJfSBlbHNlIGlmICh0YWdOYW1lID09IFRBR19QUk9QRVJUWSkgewotCQkJCWRvUHJvcGVydHkodGFnKTsKLQkJCX0gZWxzZSBpZiAodGFnTmFtZSA9PSBUQUdfUFJPUEVSVElFUykgewotCQkJCWRvUHJvcGVydGllcyh0YWcpOwotCQkJfSBlbHNlIGlmICh0YWdOYW1lID09IFRBR19TRVJWSUNFKSB7Ci0JCQkJZG9TZXJ2aWNlKHRhZyk7Ci0JCQl9IGVsc2UgaWYgKHRhZ05hbWUgPT0gVEFHX1JFRkVSRU5DRSkgewotCQkJCWRvUmVmZXJlbmNlKHRhZyk7Ci0JCQl9IGVsc2UgaWYgKHRhZ05hbWUgPT0gVEFHX1BST1ZJREUpIHsKLQkJCQkvLyBlbXB0eSAtIHRoaXMgdGFnIGlzIHByb2Nlc3NlZCB3aXRoaW4gdGhlIHNlcnZpY2UgdGFnCi0JCQl9IGVsc2UgaWYgKHRhZ05hbWUgPT0gY2xvc2VUYWcpIHsKLQkJCQkvLyB0aGUgY29tcG9uZW50IGlzIGNvbXBsZXRlZCAtIHdlIGNhbiBub3cgZnVsbHkgdmFsaWRhdGUgaXQhCi0KLQkJCQlpZiAoIWltbWVkaWF0ZVNldCAmJiAoY3VycmVudENvbXBvbmVudC5mYWN0b3J5ID09IG51bGwpKSB7Ci0JCQkJCS8vIGlmIHVuc2V0LCBpbW1lZGlhdGUgYXR0cmlidXRlIGlzIGZhbHNlIGlmIHNlcnZpY2UgZWxlbWVudCBpcwotCQkJCQkvLyBzcGVjaWZpZWQgb3IgdHJ1ZSBvdGhlcndpc2UKLQkJCQkJLy8gaWYgY29tcG9uZW50IGZhY3RvcnkgdGhlbiBpbW1lZGlhdGUgYnkgZGVmYXVsdCBpcyBmYWxzZQotCQkJCQljdXJyZW50Q29tcG9uZW50LnNldEltbWVkaWF0ZShjdXJyZW50Q29tcG9uZW50LnNlcnZpY2VJbnRlcmZhY2VzID09IG51bGwpOwotCQkJCX0KLQkJCQljdXJyZW50Q29tcG9uZW50LnZhbGlkYXRlKHRhZy5nZXRMaW5lKCksIGdldE5hbWVzcGFjZSh0YWcuZ2V0TmFtZSgpKSk7Ci0JCQkJaWYgKGNvbXBvbmVudHMgPT0gbnVsbCkgewotCQkJCQljb21wb25lbnRzID0gbmV3IFZlY3RvcigxLCAxKTsKLQkJCQl9Ci0JCQkJY29tcG9uZW50cy5hZGRFbGVtZW50KGN1cnJlbnRDb21wb25lbnQpOwotCQkJCWN1cnJlbnRDb21wb25lbnQgPSBudWxsOwotCQkJCWNsb3NlVGFnID0gbnVsbDsKLQkJCX0gZWxzZSB7Ci0JCQkJSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUgPSBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKE5MUy5iaW5kKE1lc3NhZ2VzLklMTEVHQUxfVEFHX0ZPVU5ELCB0YWdOYW1lLCBJbnRlZ2VyLnRvU3RyaW5nKHRhZy5nZXRMaW5lKCkpKSk7Ci0JCQkJdGhyb3cgZTsKLQkJCX0KLQkJfQotCX0KLQotCS8qCi0JICogKG5vbi1KYXZhZG9jKQotCSAqIAotCSAqIEBzZWUgb3JnLmVjbGlwc2UuZXF1aW5veC5pbnRlcm5hbC51dGlsLnhtbC5FeFRhZ0xpc3RlbmVyI2VuZFRhZyhvcmcuZWNsaXBzZS5lcXVpbm94LmludGVybmFsLnV0aWwueG1sLlRhZykKLQkgKi8KLQlwdWJsaWMgZmluYWwgdm9pZCBlbmRUYWcoVGFnIHRhZykgewotCQl0cnkgewotCQkJZG9FbmRUYWcodGFnKTsKLQkJCXByb2Nlc3NOYW1lc3BhY2VzTGVhdmUodGFnKTsKLQkJfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlhZSkgewotCQkJY3VycmVudENvbXBvbmVudCA9IG51bGw7Ci0JCQljbG9zZVRhZyA9IG51bGw7Ci0JCQlBY3RpdmF0b3IubG9nKGJ1bmRsZS5nZXRCdW5kbGVDb250ZXh0KCksIExvZ1NlcnZpY2UuTE9HX0VSUk9SLCBOTFMuYmluZChNZXNzYWdlcy5FUlJPUl9QUk9DRVNTSU5HX0VORF9UQUcsIGN1cnJlbnRVUkwsIGJ1bmRsZSkgKyBpYWUuZ2V0TWVzc2FnZSgpLCBudWxsKTsKLQkJCWlmIChBY3RpdmF0b3IuREVCVUcpIHsKLQkJCQlBY3RpdmF0b3IubG9nLmRlYnVnKCJbU0NSXSBUcmFjaW5nIHRoZSBsYXN0IGV4Y2VwdGlvbiIsIGlhZSk7IC8vJE5PTi1OTFMtMSQKLQkJCX0KLQkJCWlmICh0aHJvd0Vycm9ycykgewotCQkJCXRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKE5MUy5iaW5kKE1lc3NhZ2VzLkVSUk9SX1BST0NFU1NJTkdfRU5EX1RBRywgY3VycmVudFVSTCwgYnVuZGxlKSArIGlhZS5nZXRNZXNzYWdlKCksIGlhZSk7Ci0JCQl9Ci0JCX0gY2F0Y2ggKFRocm93YWJsZSBlKSB7Ci0JCQljdXJyZW50Q29tcG9uZW50ID0gbnVsbDsKLQkJCWNsb3NlVGFnID0gbnVsbDsKLQkJCUFjdGl2YXRvci5sb2coYnVuZGxlLmdldEJ1bmRsZUNvbnRleHQoKSwgTG9nU2VydmljZS5MT0dfRVJST1IsIE5MUy5iaW5kKE1lc3NhZ2VzLkVSUk9SX1BST0NFU1NJTkdfRU5EX1RBRywgY3VycmVudFVSTCwgYnVuZGxlKSwgZSk7Ci0JCQlpZiAodGhyb3dFcnJvcnMpIHsKLQkJCQl0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihOTFMuYmluZChNZXNzYWdlcy5FUlJPUl9QUk9DRVNTSU5HX0VORF9UQUcsIGN1cnJlbnRVUkwsIGJ1bmRsZSkgKyBlLmdldE1lc3NhZ2UoKSwgZSk7Ci0JCQl9Ci0JCX0KLQl9Ci0KLQkvKioKLQkgKiBUaGlzIG1ldGhvZCB3aWxsIHJldHVybiBjb252ZXJ0IGEgc3RyaW5nIHRvIGEgY2FyZGluYWxpdHkgY29uc3RhbnQKLQkgKiAKLQkgKiBAcGFyYW0gdmFsdWUKLQkgKiAgICAgICAgICAgIHRoZSBpbnB1dCBzdHJpbmcKLQkgKiBAcmV0dXJuIHRoZSBjYXJkaW5hbGl0eSBvciAtMSB0byBpbmRpY2F0ZSBlcnJvcgotCSAqLwotCXByaXZhdGUgaW50IGdldENhcmRpbmFsaXR5KFN0cmluZyB2YWx1ZSkgewotCQlpZiAoIjAuLjEiLmVxdWFscyh2YWx1ZSkpIHsgLy8kTk9OLU5MUy0xJAotCQkJcmV0dXJuIENvbXBvbmVudFJlZmVyZW5jZS5DQVJESU5BTElUWV8wXzE7Ci0JCX0gZWxzZSBpZiAoIjAuLm4iLmVxdWFscyh2YWx1ZSkpIHsgLy8kTk9OLU5MUy0xJAotCQkJcmV0dXJuIENvbXBvbmVudFJlZmVyZW5jZS5DQVJESU5BTElUWV8wX047Ci0JCX0gZWxzZSBpZiAoIjEuLjEiLmVxdWFscyh2YWx1ZSkpIHsgLy8kTk9OLU5MUy0xJAotCQkJcmV0dXJuIENvbXBvbmVudFJlZmVyZW5jZS5DQVJESU5BTElUWV8xXzE7Ci0JCX0gZWxzZSBpZiAoIjEuLm4iLmVxdWFscyh2YWx1ZSkpIHsgLy8kTk9OLU5MUy0xJAotCQkJcmV0dXJuIENvbXBvbmVudFJlZmVyZW5jZS5DQVJESU5BTElUWV8xX047Ci0JCX0gZWxzZSB7Ci0JCQlyZXR1cm4gLTE7Ci0JCX0KLQl9Ci0KLQlwcml2YXRlIHZvaWQgZG9SZWZlcmVuY2UoVGFnIHRhZykgdGhyb3dzIEludmFsaWRTeW50YXhFeGNlcHRpb24gewotCQlTdHJpbmcgbmFtZSA9IHRhZy5nZXRBdHRyaWJ1dGUoQVRUUl9OQU1FKTsKLQkJU3RyaW5nIGlmYWNlID0gdGFnLmdldEF0dHJpYnV0ZShBVFRSX0lOVEVSRkFDRSk7Ci0JCWlmIChpZmFjZSA9PSBudWxsKSB7Ci0JCQlJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSA9IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTkxTLmJpbmQoTWVzc2FnZXMuTk9fSU5URVJGQUNFX0FUVFJfSU5fUkVGRVJFTkNFX1RBRywgSW50ZWdlci50b1N0cmluZyh0YWcuZ2V0TGluZSgpKSkpOwotCQkJdGhyb3cgZTsKLQkJfQotCi0JCVN0cmluZyBjYXJkaW5hbGl0eVMgPSB0YWcuZ2V0QXR0cmlidXRlKEFUVFJfQ0FSRElOQUxJVFkpOwotCQlpbnQgY2FyZGluYWxpdHkgPSBDb21wb25lbnRSZWZlcmVuY2UuQ0FSRElOQUxJVFlfMV8xOyAvLyBkZWZhdWx0Ci0JCWlmIChjYXJkaW5hbGl0eVMgIT0gbnVsbCkgewotCQkJY2FyZGluYWxpdHkgPSBnZXRDYXJkaW5hbGl0eShjYXJkaW5hbGl0eVMpOwotCQkJaWYgKGNhcmRpbmFsaXR5IDwgMCkgewotCQkJCUlsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlID0gbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihOTFMuYmluZChNZXNzYWdlcy5JTlZBTElEX0NBUkRJTkFMSVRZX0FUVFIsIGNhcmRpbmFsaXR5UywgSW50ZWdlci50b1N0cmluZyh0YWcuZ2V0TGluZSgpKSkpOwotCQkJCXRocm93IGU7Ci0JCQl9Ci0JCX0gLy8gaWYgbnVsbCAtIGRlZmF1bHQgY2FyZGluYWxpdHkgaXMgYWxyZWFkeSBpbml0aWFsaXplZCBpbgotCQkJLy8gY29uc3RydWN0b3IKLQotCQlTdHJpbmcgcG9saWN5UyA9IHRhZy5nZXRBdHRyaWJ1dGUoQVRUUl9QT0xJQ1kpOwotCQlpbnQgcG9saWN5ID0gQ29tcG9uZW50UmVmZXJlbmNlLlBPTElDWV9TVEFUSUM7IC8vIGRlZmF1bHQKLQkJaWYgKHBvbGljeVMgIT0gbnVsbCkgewotCQkJLy8gdmVyaWZ5IHRoZSBwb2xpY3kgYXR0cmlidXRlIHZhbHVlcwotCQkJaWYgKHBvbGljeVMuZXF1YWxzKCJkeW5hbWljIikpIHsgLy8kTk9OLU5MUy0xJAotCQkJCXBvbGljeSA9IENvbXBvbmVudFJlZmVyZW5jZS5QT0xJQ1lfRFlOQU1JQzsKLQkJCX0gZWxzZSBpZiAocG9saWN5Uy5lcXVhbHMoInN0YXRpYyIpKSB7IC8vJE5PTi1OTFMtMSQKLQkJCQlwb2xpY3kgPSBDb21wb25lbnRSZWZlcmVuY2UuUE9MSUNZX1NUQVRJQzsKLQkJCX0gZWxzZSB7Ci0JCQkJSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUgPSBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKE5MUy5iaW5kKE1lc3NhZ2VzLklOVkFMSURfUE9MSUNZX0FUVFIsIHBvbGljeVMsIEludGVnZXIudG9TdHJpbmcodGFnLmdldExpbmUoKSkpKTsKLQkJCQl0aHJvdyBlOwotCQkJfQotCQl9IC8vIGlmIG51bGwgLSBkZWZhdWx0IHBvbGljeSBpcyBhbHJlYWR5IGluaXRpYWxpemVkIGluIGNvbnN0cnVjdG9yCi0KLQkJU3RyaW5nIGJpbmQgPSB0YWcuZ2V0QXR0cmlidXRlKEFUVFJfQklORCk7Ci0JCVN0cmluZyB1bmJpbmQgPSB0YWcuZ2V0QXR0cmlidXRlKEFUVFJfVU5CSU5EKTsKLQkJaWYgKGJpbmQgIT0gbnVsbCkgewotCQkJaWYgKGJpbmQuZXF1YWxzKCIiKSkgeyAvLyROT04tTkxTLTEkCi0JCQkJSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUgPSBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKE5MUy5iaW5kKE1lc3NhZ2VzLklOVkFMSURfUkVGRVJFTkNFX1RBR19fQklORF9BVFRSX0VNUFRZLCBJbnRlZ2VyLnRvU3RyaW5nKHRhZy5nZXRMaW5lKCkpKSk7Ci0JCQkJdGhyb3cgZTsKLQkJCX0KLQkJCWlmIChiaW5kLmVxdWFscyh1bmJpbmQpKSB7Ci0JCQkJSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUgPSBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKE5MUy5iaW5kKE1lc3NhZ2VzLklOVkFMSURfUkVGRVJFTkNFX1RBR19fQklORF9FUVVBTFNfVU5CSU5ELCBJbnRlZ2VyLnRvU3RyaW5nKHRhZy5nZXRMaW5lKCkpKSk7Ci0JCQkJdGhyb3cgZTsKLQkJCX0KLQkJfQotCQlpZiAodW5iaW5kICE9IG51bGwgJiYgdW5iaW5kLmVxdWFscygiIikpIHsgLy8kTk9OLU5MUy0xJAotCQkJSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUgPSBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKE5MUy5iaW5kKE1lc3NhZ2VzLklOVkFMSURfUkVGRVJFTkNFX1RBR19fVU5CSU5EX0FUVFJfRU1QVFksIEludGVnZXIudG9TdHJpbmcodGFnLmdldExpbmUoKSkpKTsKLQkJCXRocm93IGU7Ci0JCX0KLQotCQlTdHJpbmcgdXBkYXRlZCA9IHRhZy5nZXRBdHRyaWJ1dGUoQVRUUl9VUERBVEVEKTsKLQkJaWYgKHVwZGF0ZWQgIT0gbnVsbCAmJiB1cGRhdGVkLmVxdWFscygiIikpIHsgLy8kTk9OLU5MUy0xJAotCQkJSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUgPSBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKE5MUy5iaW5kKE1lc3NhZ2VzLklOVkFMSURfUkVGRVJFTkNFX1RBR19fVVBEQVRFRF9BVFRSX0VNUFRZLCBJbnRlZ2VyLnRvU3RyaW5nKHRhZy5nZXRMaW5lKCkpKSk7Ci0JCQl0aHJvdyBlOwotCQl9Ci0KLQkJU3RyaW5nIHBvbGljeU9wdGlvbiA9IHRhZy5nZXRBdHRyaWJ1dGUoQVRUUl9QT0xJQ1lfT1BUSU9OKTsKLQkJaW50IHBvbGljeU9wdGlvblByb2Nlc3NlZCA9IENvbXBvbmVudFJlZmVyZW5jZS5QT0xJQ1lfT1BUSU9OX1JFTFVDVEFOVDsgLy9kZWZhdWx0Ci0JCWlmIChwb2xpY3lPcHRpb24gIT0gbnVsbCkgewotCQkJaWYgKHBvbGljeU9wdGlvbi5lcXVhbHMoImdyZWVkeSIpKSB7IC8vJE5PTi1OTFMtMSQKLQkJCQlwb2xpY3lPcHRpb25Qcm9jZXNzZWQgPSBDb21wb25lbnRSZWZlcmVuY2UuUE9MSUNZX09QVElPTl9HUkVFRFk7Ci0JCQl9IGVsc2UgaWYgKHBvbGljeU9wdGlvbi5lcXVhbHMoInJlbHVjdGFudCIpKSB7IC8vJE5PTi1OTFMtMSQKLQkJCQlwb2xpY3lPcHRpb25Qcm9jZXNzZWQgPSBDb21wb25lbnRSZWZlcmVuY2UuUE9MSUNZX09QVElPTl9SRUxVQ1RBTlQ7Ci0JCQl9IGVsc2UgewotCQkJCUlsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlID0gbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihOTFMuYmluZChNZXNzYWdlcy5JTlZBTElEX1BPTElDWV9PUFRJT05fQVRUUiwgcG9saWN5T3B0aW9uLCBJbnRlZ2VyLnRvU3RyaW5nKHRhZy5nZXRMaW5lKCkpKSk7Ci0JCQkJdGhyb3cgZTsKLQkJCX0KLQkJfQotCi0JCS8vY2hlY2sgaWYgdGhlIGN1cnJlbnQgY29tcG9uZW50IG5hbWVzcGFjZSBpcyBzdWl0YWJsZSBmb3IgdGhlIGxhdGVzdCByZWZlcmVuY2UgYXR0cmlidXRlcwotCQlpZiAoIWlzTmFtZXNwYWNlQXRMZWFzdDEyKGNsb3NlVGFnKSkgewotCQkJaWYgKHVwZGF0ZWQgIT0gbnVsbCkgewotCQkJCXRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTkxTLmJpbmQoTWVzc2FnZXMuSU5WQUxJRF9UQUdfQUNDT1JESU5HX1RPX05BTUVTUEFDRTFfMiwgQVRUUl9VUERBVEVELCBJbnRlZ2VyLnRvU3RyaW5nKHRhZy5nZXRMaW5lKCkpKSk7Ci0JCQl9Ci0JCQlpZiAocG9saWN5T3B0aW9uICE9IG51bGwpIHsKLQkJCQl0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKE5MUy5iaW5kKE1lc3NhZ2VzLklOVkFMSURfVEFHX0FDQ09SRElOR19UT19OQU1FU1BBQ0UxXzIsIEFUVFJfUE9MSUNZX09QVElPTiwgSW50ZWdlci50b1N0cmluZyh0YWcuZ2V0TGluZSgpKSkpOwotCQkJfQotCQl9Ci0KLQkJLy8gdGhlIHJlZmVyZW5jZSBpcyBhdXRvYWRkZWQgaW4gdGhlIFNlcnZpY2VDb21wb25lbnQncyBsaXN0IG9mCi0JCS8vIHJlZmVyZW5jZXMKLQkJLy8gaW4gaXRzIGNvbnN0cnVjdG9yCi0JCUNvbXBvbmVudFJlZmVyZW5jZSByZWYgPSBuZXcgQ29tcG9uZW50UmVmZXJlbmNlKGN1cnJlbnRDb21wb25lbnQpOwotCQlyZWYubmFtZSA9IG5hbWU7Ci0JCXJlZi5pbnRlcmZhY2VOYW1lID0gaWZhY2U7Ci0JCXJlZi5jYXJkaW5hbGl0eSA9IGNhcmRpbmFsaXR5OwotCQlyZWYucG9saWN5ID0gcG9saWN5OwotCQlyZWYuYmluZCA9IGJpbmQ7Ci0JCXJlZi51bmJpbmQgPSB1bmJpbmQ7Ci0JCXJlZi51cGRhdGVkID0gdXBkYXRlZDsKLQkJcmVmLnBvbGljeV9vcHRpb24gPSBwb2xpY3lPcHRpb25Qcm9jZXNzZWQ7Ci0JCXJlZi50YXJnZXQgPSB0YWcuZ2V0QXR0cmlidXRlKEFUVFJfVEFSR0VUKTsKLQkJLy8gdmFsaWRhdGUgdGhlIHRhcmdldCBmaWx0ZXIKLQkJaWYgKHJlZi50YXJnZXQgIT0gbnVsbCkgewotCQkJQWN0aXZhdG9yLmNyZWF0ZUZpbHRlcihyZWYudGFyZ2V0KTsKLQkJfQotCX0KLQotCXByaXZhdGUgdm9pZCBkb0ltcGxlbWVudGF0aW9uKFRhZyB0YWcpIHsKLQkJaWYgKGN1cnJlbnRDb21wb25lbnQuaW1wbGVtZW50YXRpb24gIT0gbnVsbCkgewotCQkJSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUgPSBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKE5MUy5iaW5kKE1lc3NhZ2VzLklOVkFMSURfQ09NUE9ORU5UX1RBR19fTVVMVElQTEVfSU1QTF9BVFRSSUJTLCBJbnRlZ2VyLnRvU3RyaW5nKHRhZy5nZXRMaW5lKCkpKSk7Ci0JCQl0aHJvdyBlOwotCQl9Ci0JCVN0cmluZyB0bXAgPSB0YWcuZ2V0QXR0cmlidXRlKEFUVFJfQ0xBU1MpOwotCQlpZiAodG1wID09IG51bGwpIHsKLQkJCUlsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlID0gbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihOTFMuYmluZChNZXNzYWdlcy5JTlZBTElEX0NPTVBPTkVOVF9UQUdfX05PX0NMQVNTX0FUVFIsIEludGVnZXIudG9TdHJpbmcodGFnLmdldExpbmUoKSkpKTsKLQkJCXRocm93IGU7Ci0JCX0KLQkJY3VycmVudENvbXBvbmVudC5pbXBsZW1lbnRhdGlvbiA9IHRtcDsKLQl9Ci0KLQlwcml2YXRlIHZvaWQgZG9TZXJ2aWNlKFRhZyB0YWcpIHsKLQkJU3RyaW5nIHRtcCA9IHRhZy5nZXRBdHRyaWJ1dGUoQVRUUl9TRVJWSUNFRkFDVE9SWSk7Ci0JCWlmICh0bXAgIT0gbnVsbCkgewotCQkJY3VycmVudENvbXBvbmVudC5zZXJ2aWNlRmFjdG9yeSA9IEJvb2xlYW4udmFsdWVPZih0bXApLmJvb2xlYW5WYWx1ZSgpOwotCQl9Ci0JCWludCBzaXplID0gdGFnLnNpemUoKTsKLQkJaWYgKHNpemUgPT0gMCkgewotCQkJSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUgPSBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKE5MUy5iaW5kKE1lc3NhZ2VzLklOVkFMSURfU0VSVklDRV9UQUdfX05PX1BST1ZJREVfVEFHLCBJbnRlZ2VyLnRvU3RyaW5nKHRhZy5nZXRMaW5lKCkpKSk7Ci0JCQl0aHJvdyBlOwotCQl9Ci0JCWlmIChjdXJyZW50Q29tcG9uZW50LnNlcnZpY2VJbnRlcmZhY2VzICE9IG51bGwpIHsKLQkJCS8vdGhlcmUgYXJlIGFscmVhZHkgZGVmaW5lZCBzZXJ2aWNlIGludGVyZmFjZXMuIFRoZSBzZXJ2aWNlIHRhZyBzZWVtcyB0byBiZSBkdXBsaWNhdGVkCi0JCQlJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSA9IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTkxTLmJpbmQoTWVzc2FnZXMuRFVQTElDQVRFRF9TRVJWSUNFX1RBR1MsIEludGVnZXIudG9TdHJpbmcodGFnLmdldExpbmUoKSkpKTsKLQkJCXRocm93IGU7Ci0JCX0KLQkJZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKLQkJCVRhZyBwID0gdGFnLmdldFRhZ0F0KGkpOwotCQkJU3RyaW5nIHBOYW1lID0gcC5nZXROYW1lKCkuaW50ZXJuKCk7Ci0JCQlpZiAocE5hbWUgPT0gVEFHX1BST1ZJREUpIHsKLQkJCQlTdHJpbmcgaUZhY2UgPSBwLmdldEF0dHJpYnV0ZShBVFRSX0lOVEVSRkFDRSk7Ci0JCQkJaWYgKGlGYWNlID09IG51bGwpIHsKLQkJCQkJSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUgPSBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKE5MUy5iaW5kKE1lc3NhZ2VzLklOVkFMSURfUFJPVklERV9UQUdfX05PX0lOVEVSRkFDRV9BVFRSLCBJbnRlZ2VyLnRvU3RyaW5nKHRhZy5nZXRMaW5lKCkpKSk7Ci0JCQkJCXRocm93IGU7Ci0JCQkJfQotCQkJCWlmIChjdXJyZW50Q29tcG9uZW50LnNlcnZpY2VJbnRlcmZhY2VzID09IG51bGwpIHsKLQkJCQkJY3VycmVudENvbXBvbmVudC5zZXJ2aWNlSW50ZXJmYWNlcyA9IG5ldyBWZWN0b3Ioc2l6ZSk7Ci0JCQkJfQotCQkJCWN1cnJlbnRDb21wb25lbnQuc2VydmljZUludGVyZmFjZXMuYWRkRWxlbWVudChpRmFjZSk7Ci0JCQl9IGVsc2UgewotCQkJCUlsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBlID0gbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihOTFMuYmluZChNZXNzYWdlcy5JTExFR0FMX0VMRU1FTlRfSU5fU0VSVklDRV9UQUcsIHBOYW1lLCBJbnRlZ2VyLnRvU3RyaW5nKHRhZy5nZXRMaW5lKCkpKSk7Ci0JCQkJdGhyb3cgZTsKLQkJCX0KLQkJfQotCX0KLQotCXByaXZhdGUgdm9pZCBkb1Byb3BlcnR5KFRhZyB0YWcpIHsKLQkJU3RyaW5nIG5hbWUgPSBudWxsOwotCQl0cnkgewotCQkJbmFtZSA9IHRhZy5nZXRBdHRyaWJ1dGUoQVRUUl9OQU1FKTsKLQkJCWlmIChuYW1lID09IG51bGwpIHsKLQkJCQlJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSA9IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTkxTLmJpbmQoTWVzc2FnZXMuSU5WQUxJRF9QUk9QRVJUWV9UQUdfX05PX05BTUVfQVRUUiwgSW50ZWdlci50b1N0cmluZyh0YWcuZ2V0TGluZSgpKSkpOwotCQkJCXRocm93IGU7Ci0JCQl9Ci0KLQkJCVN0cmluZyB0eXBlID0gdGFnLmdldEF0dHJpYnV0ZShBVFRSX1RZUEUpOwotCQkJaW50IG10VHlwZTsKLQkJCWlmICh0eXBlID09IG51bGwgfHwgIlN0cmluZyIuZXF1YWxzKHR5cGUpKSB7IC8vJE5PTi1OTFMtMSQKLQkJCQltdFR5cGUgPSBTVFJJTkc7Ci0JCQl9IGVsc2UgaWYgKCJCb29sZWFuIi5lcXVhbHModHlwZSkpIHsgLy8kTk9OLU5MUy0xJAotCQkJCW10VHlwZSA9IEJPT0xFQU47Ci0JCQl9IGVsc2UgaWYgKCJJbnRlZ2VyIi5lcXVhbHModHlwZSkpIHsgLy8kTk9OLU5MUy0xJAotCQkJCW10VHlwZSA9IElOVEVHRVI7Ci0JCQl9IGVsc2UgaWYgKCJMb25nIi5lcXVhbHModHlwZSkpIHsgLy8kTk9OLU5MUy0xJAotCQkJCW10VHlwZSA9IExPTkc7Ci0JCQl9IGVsc2UgaWYgKCJDaGFyIi5lcXVhbHModHlwZSkgfHwgIkNoYXJhY3RlciIuZXF1YWxzKHR5cGUpKSB7IC8vJE5PTi1OTFMtMSQgLy8kTk9OLU5MUy0yJAotCQkJCW10VHlwZSA9IENIQVJBQ1RFUjsKLQkJCX0gZWxzZSBpZiAoIkRvdWJsZSIuZXF1YWxzKHR5cGUpKSB7IC8vJE5PTi1OTFMtMSQKLQkJCQltdFR5cGUgPSBET1VCTEU7Ci0JCQl9IGVsc2UgaWYgKCJGbG9hdCIuZXF1YWxzKHR5cGUpKSB7IC8vJE5PTi1OTFMtMSQKLQkJCQltdFR5cGUgPSBGTE9BVDsKLQkJCX0gZWxzZSBpZiAoIkJ5dGUiLmVxdWFscyh0eXBlKSkgeyAvLyROT04tTkxTLTEkCi0JCQkJbXRUeXBlID0gQllURTsKLQkJCX0gZWxzZSBpZiAoIlNob3J0Ii5lcXVhbHModHlwZSkpIHsgLy8kTk9OLU5MUy0xJAotCQkJCW10VHlwZSA9IFNIT1JUOwotCQkJfSBlbHNlIHsKLQkJCQlJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSA9IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTkxTLmJpbmQoTWVzc2FnZXMuSU5WQUxJRF9QUk9QRVJUWV9UWVBFLCB0eXBlLCBJbnRlZ2VyLnRvU3RyaW5nKHRhZy5nZXRMaW5lKCkpKSk7Ci0JCQkJdGhyb3cgZTsKLQkJCX0KLQotCQkJU3RyaW5nIHZhbHVlID0gdGFnLmdldEF0dHJpYnV0ZShBVFRSX1ZBTFVFKTsKLQkJCU9iamVjdCBfdmFsdWU7Ci0JCQlpZiAodmFsdWUgIT0gbnVsbCkgewotCQkJCV92YWx1ZSA9IG1ha2VPYmplY3QodmFsdWUsIG10VHlwZSk7Ci0JCQl9IGVsc2UgewotCQkJCS8vIGJvZHkgbXVzdCBiZSBzcGVjaWZpZWQKLQkJCQl2YWx1ZSA9IHRhZy5nZXRDb250ZW50KCk7Ci0JCQkJaWYgKHZhbHVlID09IG51bGwpIHsKLQkJCQkJSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUgPSBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKE1lc3NhZ2VzLklOVkFMSURfUFJPUEVSVFlfVEFHX19OT19CT0RZX0NPTlRFTlQpOwotCQkJCQl0aHJvdyBlOwotCQkJCX0KLQkJCQlTdHJpbmdUb2tlbml6ZXIgdG9rID0gbmV3IFN0cmluZ1Rva2VuaXplcih2YWx1ZSwgIlxuXHIiKTsgLy8kTk9OLU5MUy0xJAotCQkJCVZlY3RvciBlbCA9IG5ldyBWZWN0b3IoMTApOwotCQkJCXdoaWxlICh0b2suaGFzTW9yZVRva2VucygpKSB7Ci0JCQkJCVN0cmluZyBuZXh0ID0gdG9rLm5leHRUb2tlbigpLnRyaW0oKTsKLQkJCQkJaWYgKG5leHQubGVuZ3RoKCkgPiAwKSB7Ci0JCQkJCQllbC5hZGRFbGVtZW50KG5leHQpOwotCQkJCQl9Ci0JCQkJfQotCQkJCWlmIChlbC5zaXplKCkgPT0gMCkgewotCQkJCQlJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSA9IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTWVzc2FnZXMuSU5WQUxJRF9QUk9QRVJUWV9UQUdfX05PX0JPRFlfQ09OVEVOVCk7Ci0JCQkJCXRocm93IGU7Ci0JCQkJfQotCQkJCVN0cmluZ1tdIHZhbHVlcyA9IG5ldyBTdHJpbmdbZWwuc2l6ZSgpXTsKLQkJCQllbC5jb3B5SW50byh2YWx1ZXMpOwotCQkJCV92YWx1ZSA9IG1ha2VBcnIodmFsdWVzLCBtdFR5cGUpOwotCQkJfQotCQkJaWYgKGN1cnJlbnRDb21wb25lbnQucHJvcGVydGllcyA9PSBudWxsKSB7Ci0JCQkJY3VycmVudENvbXBvbmVudC5wcm9wZXJ0aWVzID0gbmV3IFByb3BlcnRpZXMoKTsKLQkJCX0KLQkJCWN1cnJlbnRDb21wb25lbnQucHJvcGVydGllcy5wdXQobmFtZSwgX3ZhbHVlKTsKLQkJfSBjYXRjaCAoSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlhZSkgewotCQkJQWN0aXZhdG9yLmxvZyhidW5kbGUuZ2V0QnVuZGxlQ29udGV4dCgpLCBMb2dTZXJ2aWNlLkxPR19FUlJPUiwgTkxTLmJpbmQoTWVzc2FnZXMuRVJST1JfUFJPQ0VTU0lOR19QUk9QRVJUWSwgbmFtZSwgY3VycmVudFVSTCkgKyBpYWUuZ2V0TWVzc2FnZSgpLCBudWxsKTsKLQkJCWlmIChBY3RpdmF0b3IuREVCVUcpIHsKLQkJCQlBY3RpdmF0b3IubG9nLmRlYnVnKCJbU0NSXSBUcmFjaW5nIHRoZSBsYXN0IGV4Y2VwdGlvbiIsIGlhZSk7IC8vJE5PTi1OTFMtMSQKLQkJCX0KLQkJCWlmICh0aHJvd0Vycm9ycykgewotCQkJCXRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKE5MUy5iaW5kKE1lc3NhZ2VzLkVSUk9SX1BST0NFU1NJTkdfUFJPUEVSVFksIG5hbWUsIGN1cnJlbnRVUkwpICsgaWFlLmdldE1lc3NhZ2UoKSwgaWFlKTsKLQkJCX0KLQkJfSBjYXRjaCAoVGhyb3dhYmxlIGUpIHsKLQkJCS8vbG9nZ2luZyB1bnJlY29nbml6ZWQgZXhjZXB0aW9uCi0JCQlBY3RpdmF0b3IubG9nKGJ1bmRsZS5nZXRCdW5kbGVDb250ZXh0KCksIExvZ1NlcnZpY2UuTE9HX0VSUk9SLCBOTFMuYmluZChNZXNzYWdlcy5FUlJPUl9QUk9DRVNTSU5HX1BST1BFUlRZLCBuYW1lLCBjdXJyZW50VVJMKSwgZSk7Ci0JCQlpZiAodGhyb3dFcnJvcnMpIHsKLQkJCQl0aHJvdyBuZXcgUnVudGltZUV4Y2VwdGlvbihOTFMuYmluZChNZXNzYWdlcy5FUlJPUl9QUk9DRVNTSU5HX1BST1BFUlRZLCBuYW1lLCBjdXJyZW50VVJMKSArIGUuZ2V0TWVzc2FnZSgpLCBlKTsKLQkJCX0KLQkJfQotCX0KLQotCXByaXZhdGUgdm9pZCBkb1Byb3BlcnRpZXMoVGFnIHRhZykgewotCQlTdHJpbmcgZmlsZUVudHJ5ID0gdGFnLmdldEF0dHJpYnV0ZShBVFRSX0VOVFJZKTsKLQkJaWYgKGZpbGVFbnRyeSA9PSBudWxsKSB7Ci0JCQlJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gZSA9IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTkxTLmJpbmQoTWVzc2FnZXMuSU5WQUxJRF9QUk9QRVJUSUVTX1RBR19fTk9fRU5UUllfQVRUUiwgSW50ZWdlci50b1N0cmluZyh0YWcuZ2V0TGluZSgpKSkpOwotCQkJdGhyb3cgZTsKLQkJfQotCi0JCUlucHV0U3RyZWFtIGlzID0gbnVsbDsKLQkJdHJ5IHsKLQkJCVVSTCByZXNvdXJjZSA9IGJ1bmRsZS5nZXRFbnRyeShmaWxlRW50cnkpOwotCQkJaXMgPSByZXNvdXJjZSAhPSBudWxsID8gcmVzb3VyY2Uub3BlblN0cmVhbSgpIDogbnVsbDsKLQkJfSBjYXRjaCAoSU9FeGNlcHRpb24gaWdub3JlKSB7Ci0JCQkvL2lnbm9yZQotCQl9Ci0KLQkJYm9vbGVhbiBpbnZhbGlkID0gdHJ1ZTsKLQkJLy8gRklYTUU6IHRoaXMgd2lsbCBub3Qgd29yayBvbiBwcm9wZXJ0aWVzIGRlZmluZWQgbGlrZQotCQkvLyBjb20ucHJvc3lzdC5ibGEuY29tcG9uZW50LnByb3BlcnRpZXMKLQkJLy8gaW4gdGhpcyBjYXNlIHRoZSBwYXRoIHNob3VsZCBiZSBjb252ZXJ0ZWQgYXMKLQkJLy8gY29tL3Byb3N5c3QvYmxhL2NvbXBvbmVudC5wcm9wZXJ0aWVzCi0JCWlmIChpcyAhPSBudWxsKSB7Ci0JCQlpZiAoY3VycmVudENvbXBvbmVudC5wcm9wZXJ0aWVzID09IG51bGwpIHsKLQkJCQljdXJyZW50Q29tcG9uZW50LnByb3BlcnRpZXMgPSBuZXcgUHJvcGVydGllcygpOwotCQkJfQotCQkJdHJ5IHsKLQkJCQljdXJyZW50Q29tcG9uZW50LnByb3BlcnRpZXMubG9hZChpcyk7Ci0JCQkJaW52YWxpZCA9IGZhbHNlOwotCQkJfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewotCQkJCUFjdGl2YXRvci5sb2coYnVuZGxlLmdldEJ1bmRsZUNvbnRleHQoKSwgTG9nU2VydmljZS5MT0dfRVJST1IsIE1lc3NhZ2VzLkVSUk9SX0xPQURJTkdfUFJPUEVSVElFU19GSUxFLCBlKTsKLQkJCQlpZiAodGhyb3dFcnJvcnMpIHsKLQkJCQkJdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oTWVzc2FnZXMuRVJST1JfTE9BRElOR19QUk9QRVJUSUVTX0ZJTEUgKyBlLCBlKTsKLQkJCQl9Ci0JCQl9Ci0JCX0KLQotCQlpZiAoaW52YWxpZCkgewotCQkJSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGUgPSBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKE5MUy5iaW5kKE1lc3NhZ2VzLklOVkFMSURfUFJPUEVSVElFU19UQUdfX0lOVkFMSURfRU5UUllfVkFMVUUsIEludGVnZXIudG9TdHJpbmcodGFnLmdldExpbmUoKSksIGZpbGVFbnRyeSkpOwotCQkJdGhyb3cgZTsKLQkJfQotCX0KLQotCXByaXZhdGUgdm9pZCBkb0NvcnJlY3RDb21wb25lbnRUYWcoVGFnIHRhZywgU3RyaW5nIHRhZ05hbWUpIHsKLQkJY2xvc2VUYWcgPSB0YWdOYW1lLmludGVybigpOwotCQlTdHJpbmcgdG1wID0gdGFnLmdldEF0dHJpYnV0ZShBVFRSX05BTUUpOwotCQlpbW1lZGlhdGVTZXQgPSBmYWxzZTsKLQotCQljdXJyZW50Q29tcG9uZW50ID0gbmV3IFNlcnZpY2VDb21wb25lbnQoKTsKLQkJLy8gbWFrZSBzdXJlIHRoYXQgdGhlIGJ1bmRsZSBhdHRyaWJ1dGUgaXMgc2V0IC0gaXQgaXMgcmVxdWlyZWQgZnVydGhlcgotCQljdXJyZW50Q29tcG9uZW50LmJ1bmRsZSA9IGJ1bmRsZTsKLQkJY3VycmVudENvbXBvbmVudC5iYyA9IGJjOwotCQljdXJyZW50Q29tcG9uZW50Lm5hbWUgPSB0bXA7Ci0JCXRtcCA9IHRhZy5nZXRBdHRyaWJ1dGUoQVRUUl9BVVRPRU5BQkxFKTsKLQkJaWYgKHRtcCAhPSBudWxsKSB7Ci0JCQljdXJyZW50Q29tcG9uZW50LmF1dG9lbmFibGUgPSBCb29sZWFuLnZhbHVlT2YodG1wKS5ib29sZWFuVmFsdWUoKTsKLQkJfQotCQl0bXAgPSB0YWcuZ2V0QXR0cmlidXRlKEFUVFJfRkFDVE9SWSk7Ci0JCWlmICh0bXAgIT0gbnVsbCAmJiB0bXAubGVuZ3RoKCkgPT0gMCkgewotCQkJdG1wID0gbnVsbDsKLQkJfQotCQljdXJyZW50Q29tcG9uZW50LmZhY3RvcnkgPSB0bXA7Ci0JCXRtcCA9IHRhZy5nZXRBdHRyaWJ1dGUoQVRUUl9JTU1FRElBVEUpOwotCQlpZiAodG1wICE9IG51bGwgJiYgdG1wLmxlbmd0aCgpID09IDApIHsKLQkJCXRtcCA9IG51bGw7Ci0JCX0KLQkJaWYgKHRtcCAhPSBudWxsKSB7Ci0JCQljdXJyZW50Q29tcG9uZW50LmltbWVkaWF0ZSA9IEJvb2xlYW4udmFsdWVPZih0bXApLmJvb2xlYW5WYWx1ZSgpOwotCQkJaW1tZWRpYXRlU2V0ID0gdHJ1ZTsKLQkJfQotCQlpZiAoaXNOYW1lc3BhY2VBdExlYXN0MTEodGFnTmFtZSkpIHsKLQkJCS8vcHJvY2Vzc2luZyBhdHRyaWJ1dGUgY29uZmlndXJhdGlvbi1wb2xpY3kKLQkJCXRtcCA9IHRhZy5nZXRBdHRyaWJ1dGUoQVRUUl9DT05GX1BPTElDWSk7Ci0JCQlpZiAodG1wICE9IG51bGwgJiYgdG1wLmxlbmd0aCgpID09IDApIHsKLQkJCQl0bXAgPSBudWxsOwotCQkJfQotCQkJaWYgKHRtcCAhPSBudWxsKSB7Ci0JCQkJY3VycmVudENvbXBvbmVudC5jb25maWd1cmF0aW9uUG9saWN5ID0gdG1wLmludGVybigpOwotCQkJfQotCQkJLy9wcm9jZXNzaW5nIGF0dHJpYnV0ZSBhY3RpdmF0ZQotCQkJdG1wID0gdGFnLmdldEF0dHJpYnV0ZShBVFRSX0FDVElWQVRFKTsKLQkJCWlmICh0bXAgIT0gbnVsbCAmJiB0bXAubGVuZ3RoKCkgPT0gMCkgewotCQkJCXRtcCA9IG51bGw7Ci0JCQl9Ci0JCQlpZiAodG1wICE9IG51bGwpIHsKLQkJCQljdXJyZW50Q29tcG9uZW50LmFjdGl2YXRlTWV0aG9kTmFtZSA9IHRtcDsKLQkJCQljdXJyZW50Q29tcG9uZW50LmFjdGl2YXRlTWV0aG9kRGVjbGFyZWQgPSB0cnVlOwotCQkJfQotCQkJLy9wcm9jZXNzaW5nIGF0dHJpYnV0ZSBkZWFjdGl2YXRlCi0JCQl0bXAgPSB0YWcuZ2V0QXR0cmlidXRlKEFUVFJfREVBQ1RJVkFURSk7Ci0JCQlpZiAodG1wICE9IG51bGwgJiYgdG1wLmxlbmd0aCgpID09IDApIHsKLQkJCQl0bXAgPSBudWxsOwotCQkJfQotCQkJaWYgKHRtcCAhPSBudWxsKSB7Ci0JCQkJY3VycmVudENvbXBvbmVudC5kZWFjdGl2YXRlTWV0aG9kTmFtZSA9IHRtcDsKLQkJCQljdXJyZW50Q29tcG9uZW50LmRlYWN0aXZhdGVNZXRob2REZWNsYXJlZCA9IHRydWU7Ci0JCQl9Ci0JCQkvL3Byb2Nlc3NpbmcgYXR0cmlidXRlIG1vZGlmaWVkCi0JCQl0bXAgPSB0YWcuZ2V0QXR0cmlidXRlKEFUVFJfTU9ESUZJRUQpOwotCQkJaWYgKHRtcCAhPSBudWxsICYmIHRtcC5sZW5ndGgoKSA9PSAwKSB7Ci0JCQkJdG1wID0gbnVsbDsKLQkJCX0KLQkJCWlmICh0bXAgIT0gbnVsbCkgewotCQkJCWN1cnJlbnRDb21wb25lbnQubW9kaWZ5TWV0aG9kTmFtZSA9IHRtcDsKLQkJCX0KLQkJfSBlbHNlIHsKLQkJCWlmICh0YWcuZ2V0QXR0cmlidXRlKEFUVFJfQ09ORl9QT0xJQ1kpICE9IG51bGwpIHsKLQkJCQl0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKE5MUy5iaW5kKE1lc3NhZ2VzLklOVkFMSURfVEFHX0FDQ09SRElOR19UT19OQU1FU1BBQ0UxXzAsIEFUVFJfQ09ORl9QT0xJQ1ksIEludGVnZXIudG9TdHJpbmcodGFnLmdldExpbmUoKSkpKTsKLQkJCX0KLQkJCWlmICh0YWcuZ2V0QXR0cmlidXRlKEFUVFJfQUNUSVZBVEUpICE9IG51bGwpIHsKLQkJCQl0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKE5MUy5iaW5kKE1lc3NhZ2VzLklOVkFMSURfVEFHX0FDQ09SRElOR19UT19OQU1FU1BBQ0UxXzAsIEFUVFJfQUNUSVZBVEUsIEludGVnZXIudG9TdHJpbmcodGFnLmdldExpbmUoKSkpKTsKLQkJCX0KLQkJCWlmICh0YWcuZ2V0QXR0cmlidXRlKEFUVFJfREVBQ1RJVkFURSkgIT0gbnVsbCkgewotCQkJCXRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTkxTLmJpbmQoTWVzc2FnZXMuSU5WQUxJRF9UQUdfQUNDT1JESU5HX1RPX05BTUVTUEFDRTFfMCwgQVRUUl9ERUFDVElWQVRFLCBJbnRlZ2VyLnRvU3RyaW5nKHRhZy5nZXRMaW5lKCkpKSk7Ci0JCQl9Ci0JCQlpZiAodGFnLmdldEF0dHJpYnV0ZShBVFRSX01PRElGSUVEKSAhPSBudWxsKSB7Ci0JCQkJdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihOTFMuYmluZChNZXNzYWdlcy5JTlZBTElEX1RBR19BQ0NPUkRJTkdfVE9fTkFNRVNQQUNFMV8wLCBBVFRSX01PRElGSUVELCBJbnRlZ2VyLnRvU3RyaW5nKHRhZy5nZXRMaW5lKCkpKSk7Ci0JCQl9Ci0JCX0KLQotCQlpZiAoaXNOYW1lc3BhY2VBdExlYXN0MTIodGFnTmFtZSkpIHsKLQkJCS8vcHJvY2Vzc2luZyBhdHRyaWJ1dGUgY29uZmlndXJhdGlvbi1wb2xpY3kKLQkJCXRtcCA9IHRhZy5nZXRBdHRyaWJ1dGUoQVRUUl9DT05GSUdVUkFUSU9OX1BJRCk7Ci0JCQlpZiAodG1wICE9IG51bGwgJiYgdG1wLmxlbmd0aCgpID09IDApIHsKLQkJCQl0bXAgPSBudWxsOwotCQkJfQotCQkJaWYgKHRtcCAhPSBudWxsKSB7Ci0JCQkJY3VycmVudENvbXBvbmVudC5jb25maWd1cmF0aW9uUElEID0gdG1wOwotCQkJfQotCQl9IGVsc2UgewotCQkJaWYgKHRhZy5nZXRBdHRyaWJ1dGUoQVRUUl9DT05GSUdVUkFUSU9OX1BJRCkgIT0gbnVsbCkgewotCQkJCXRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTkxTLmJpbmQoTWVzc2FnZXMuSU5WQUxJRF9UQUdfQUNDT1JESU5HX1RPX05BTUVTUEFDRTFfMiwgQVRUUl9DT05GSUdVUkFUSU9OX1BJRCwgSW50ZWdlci50b1N0cmluZyh0YWcuZ2V0TGluZSgpKSkpOwotCQkJfQotCQl9Ci0KLQl9Ci0KLQlwcml2YXRlIGJvb2xlYW4gaXNDb3JyZWN0Q29tcG9uZW50VGFnKFN0cmluZyB0YWdOYW1lKSB7Ci0JCVN0cmluZyBxdWFsaWZpZXIgPSBnZXROYW1lc3BhY2VRdWFsaWZpZXIodGFnTmFtZSk7Ci0JCVN0cmluZyBsb2NhbFRhZ05hbWUgPSAocXVhbGlmaWVyLmxlbmd0aCgpID09IDApID8gdGFnTmFtZSA6IHRhZ05hbWUuc3Vic3RyaW5nKHF1YWxpZmllci5sZW5ndGgoKSArIDEpOyAvLyArIG9uZSBjaGFyIGZvciAnOicKLQkJaWYgKCFsb2NhbFRhZ05hbWUuZXF1YWxzKENPTVBPTkVOVF9UQUdfTkFNRSkpIHsKLQkJCXJldHVybiBmYWxzZTsKLQkJfQotCQlTdHJpbmcgbmFtZXNwYWNlID0gZ2V0Q3VycmVudE5hbWVzcGFjZShxdWFsaWZpZXIpOwotCQlpZiAoIXJvb3RQYXNzZWQpIHsgLy8gdGhpcyBpcyB0aGUgcm9vdCBlbGVtZW50Ci0JCQlyZXR1cm4gbmFtZXNwYWNlLmxlbmd0aCgpID09IDAgfHwgbmFtZXNwYWNlLmVxdWFscyhYTUxOU18xXzEpIHx8IG5hbWVzcGFjZS5lcXVhbHMoWE1MTlNfMV8yKSB8fCBuYW1lc3BhY2UuZXF1YWxzKFhNTE5TXzFfMCk7Ci0JCX0KLQkJLy8gbm90IGEgcm9vdCBlbGVtZW50Ci0JCXJldHVybiBuYW1lc3BhY2UuZXF1YWxzKFhNTE5TXzFfMSkgfHwgbmFtZXNwYWNlLmVxdWFscyhYTUxOU18xXzIpIHx8IG5hbWVzcGFjZS5lcXVhbHMoWE1MTlNfMV8wKTsKLQl9Ci0KLQkvKioKLQkgKiBDcmVhdGVzIGFuIG9iamVjdCBmcm9tIGEgPGNvZGU+U3RyaW5nPC9jb2RlPiB2YWx1ZSBhbmQgYSB0eXBlLCBhcyBkZWZpbmVkIGJ5IHRoZSBvYmplY3RUeXBlIHBhcmFtZXRlci4KLQkgKgotCSAqIEBwYXJhbSBzdHJpbmcgVGhlIDxjb2RlPlN0cmluZzwvY29kZT4gdmFsdWUgcmVwcmVzZW50YXRpb24gb2YgdGhlIG9iamVjdC4gCi0JICogQHBhcmFtIG9iamVjdFR5cGUgRGVmaW5lcyB0aGUgdHlwZSBvZiB0aGUgb2JqZWN0IHRvIGJlIGdlbmVyYXRlZAotCSAqCi0JICogQHJldHVybiBhbiBPYmplY3QsIHdoaWNoIGlzIG9mIGEgdHlwZSwgY29ycmVzcG9uZGluZyB0byB0aGUgZ2l2ZW4sCi0JICogYW5kIHZhbHVlIC0gZ290IGZyb20gdGhlIHN0cmluZyBwYXJhbWV0ZXIuCi0JICoKLQkgKiBAZXhjZXB0aW9uIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiBhIHByb3BlciBvYmplY3QgY2FuIG5vdCBiZSBjcmVhdGVkIAotCSAqIGR1ZSB0byBpbmNvbXBhdGliaWxpdHkgb2Ygb2JqZWN0VHlwZSBhbmQgdmFsdWUgb3IgaWYgdGhlIHBhcmFtZXRlcnMgYXJlIG5vdCBjb3JyZWN0Ci0JICogKGUuZy4gb2JqZWN0VHlwZSBpcyBub3QgYSB2YWxpZCBjb25zdGFudCkuCi0JICovCi0JcHVibGljIHN0YXRpYyBPYmplY3QgbWFrZU9iamVjdChTdHJpbmcgc3RyaW5nLCBpbnQgb2JqZWN0VHlwZSkgdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB7Ci0JCXRyeSB7Ci0JCQlzd2l0Y2ggKG9iamVjdFR5cGUpIHsKLQkJCQljYXNlIFNUUklORyA6IHsKLQkJCQkJcmV0dXJuIHN0cmluZzsKLQkJCQl9Ci0JCQkJY2FzZSBJTlRFR0VSIDogewotCQkJCQlyZXR1cm4gbmV3IEludGVnZXIoc3RyaW5nKTsKLQkJCQl9Ci0JCQkJY2FzZSBMT05HIDogewotCQkJCQlyZXR1cm4gbmV3IExvbmcoc3RyaW5nKTsKLQkJCQl9Ci0JCQkJY2FzZSBGTE9BVCA6IHsKLQkJCQkJcmV0dXJuIG5ldyBGbG9hdChzdHJpbmcpOwotCQkJCX0KLQkJCQljYXNlIERPVUJMRSA6IHsKLQkJCQkJcmV0dXJuIG5ldyBEb3VibGUoc3RyaW5nKTsKLQkJCQl9Ci0JCQkJY2FzZSBCWVRFIDogewotCQkJCQlyZXR1cm4gbmV3IEJ5dGUoc3RyaW5nKTsKLQkJCQl9Ci0JCQkJY2FzZSBTSE9SVCA6IHsKLQkJCQkJcmV0dXJuIG5ldyBTaG9ydChzdHJpbmcpOwotCQkJCX0KLQkJCQljYXNlIENIQVJBQ1RFUiA6IHsKLQkJCQkJaWYgKHN0cmluZy5sZW5ndGgoKSA9PSAwKSB7Ci0JCQkJCQl0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKE1lc3NhZ2VzLk1JU1NJTkdfQ0hBUkFDVEVSKTsKLQkJCQkJfQotCQkJCQlyZXR1cm4gbmV3IENoYXJhY3RlcihzdHJpbmcuY2hhckF0KDApKTsKLQkJCQl9Ci0JCQkJY2FzZSBCT09MRUFOIDogewotCQkJCQlyZXR1cm4gQm9vbGVhbi52YWx1ZU9mKHN0cmluZyk7Ci0JCQkJfQotCQkJCWRlZmF1bHQgOiB7Ci0JCQkJCXRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTkxTLmJpbmQoTWVzc2FnZXMuVU5TVVBQT1JURURfVFlQRSwgU3RyaW5nLnZhbHVlT2Yob2JqZWN0VHlwZSkpKTsKLQkJCQl9Ci0JCQl9Ci0JCX0gY2F0Y2ggKE51bWJlckZvcm1hdEV4Y2VwdGlvbiBleCkgewotCQkJdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihOTFMuYmluZChNZXNzYWdlcy5JTkNPUlJFQ1RfVkFMVUVfVFlQRSwgc3RyaW5nKSk7Ci0JCX0KLQl9Ci0KLQkvKioKLQkgKiBNYWtlcyBhbiBhcnJheSBmcm9tIHRoZSBzdHJpbmcgYXJyYXkgdmFsdWUgYW5kIHRoZSBvYmplY3QgdHlwZS4KLQkgKgotCSAqIEBwYXJhbSBhcnJheSA8Y29kZT5TdHJpbmc8L2NvZGU+IGFycmF5IHJlcHJlc2VudGF0aW9uIG9mIGFuIGFycmF5LgotCSAqIEBwYXJhbSBvYmplY3RUeXBlIFRoZSBhcnJheSdzIG9iamVjdCB0eXBlLgotCSAqCi0JICogQHJldHVybiBhbiBhcnJheSBvZiBwcmltaXRpdmVzIG9yIG9iamVjdHMsIHdob3NlIGNvbXBvbmVudCB0eXBlIGNvcnJlc3BvbmRzIHRvIDxjb2RlPm9iamVjdFR5cGU8L2NvZGU+LAotCSAqIGFuZCB2YWx1ZSBidWlsZCBmcm9tIHRoZSBzdHJpbmcgYXJyYXkgcGFzc2VkLgotCSAqCi0JICogQGV4Y2VwdGlvbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gIGlmIGFueSBvZiB0aGUgZWxlbWVudHMgaW4gdGhlIHN0cmluZyBhcnJheQotCSAqIGNhbiBub3QgYmUgY29udmVydGVkIHRvIGEgcHJvcGVyIG9iamVjdCBvciBwcmltaXRpdmUsIG9yIGlmIHRoZSA8Y29kZT5vYmplY3RUeXBlPC9jb2RlPiBpcyBub3QgYSB2YWxpZCBjb25zdGFudC4KLQkgKi8KLQlwdWJsaWMgc3RhdGljIE9iamVjdCBtYWtlQXJyKFN0cmluZ1tdIGFycmF5LCBpbnQgb2JqZWN0VHlwZSkgdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB7Ci0JCXN3aXRjaCAob2JqZWN0VHlwZSkgewotCQkJY2FzZSBTVFJJTkcgOiB7Ci0JCQkJcmV0dXJuIGFycmF5OwotCQkJfQotCQkJY2FzZSBJTlRFR0VSIDogewotCQkJCWludFtdIGludHMgPSBuZXcgaW50W2FycmF5Lmxlbmd0aF07Ci0JCQkJZm9yIChpbnQgaSA9IDA7IGkgPCBhcnJheS5sZW5ndGg7IGkrKykgewotCQkJCQlpbnRzW2ldID0gSW50ZWdlci5wYXJzZUludChhcnJheVtpXSk7Ci0JCQkJfQotCQkJCXJldHVybiBpbnRzOwotCQkJfQotCQkJY2FzZSBMT05HIDogewotCQkJCWxvbmdbXSBsb25ncyA9IG5ldyBsb25nW2FycmF5Lmxlbmd0aF07Ci0JCQkJZm9yIChpbnQgaSA9IDA7IGkgPCBhcnJheS5sZW5ndGg7IGkrKykgewotCQkJCQlsb25nc1tpXSA9IExvbmcucGFyc2VMb25nKGFycmF5W2ldKTsKLQkJCQl9Ci0JCQkJcmV0dXJuIGxvbmdzOwotCQkJfQotCQkJY2FzZSBGTE9BVCA6IHsKLQkJCQlmbG9hdFtdIGZsb2F0cyA9IG5ldyBmbG9hdFthcnJheS5sZW5ndGhdOwotCQkJCWZvciAoaW50IGkgPSAwOyBpIDwgYXJyYXkubGVuZ3RoOyBpKyspIHsKLQkJCQkJZmxvYXRzW2ldID0gRmxvYXQudmFsdWVPZihhcnJheVtpXSkuZmxvYXRWYWx1ZSgpOwotCQkJCX0KLQkJCQlyZXR1cm4gZmxvYXRzOwotCQkJfQotCQkJY2FzZSBET1VCTEUgOiB7Ci0JCQkJZG91YmxlW10gZG91YmxlcyA9IG5ldyBkb3VibGVbYXJyYXkubGVuZ3RoXTsKLQkJCQlmb3IgKGludCBpID0gMDsgaSA8IGFycmF5Lmxlbmd0aDsgaSsrKSB7Ci0JCQkJCWRvdWJsZXNbaV0gPSBEb3VibGUudmFsdWVPZihhcnJheVtpXSkuZG91YmxlVmFsdWUoKTsKLQkJCQl9Ci0JCQkJcmV0dXJuIGRvdWJsZXM7Ci0JCQl9Ci0JCQljYXNlIEJZVEUgOiB7Ci0JCQkJYnl0ZVtdIGJ5dGVzID0gbmV3IGJ5dGVbYXJyYXkubGVuZ3RoXTsKLQkJCQlmb3IgKGludCBpID0gMDsgaSA8IGFycmF5Lmxlbmd0aDsgaSsrKSB7Ci0JCQkJCWJ5dGVzW2ldID0gQnl0ZS5wYXJzZUJ5dGUoYXJyYXlbaV0pOwotCQkJCX0KLQkJCQlyZXR1cm4gYnl0ZXM7Ci0JCQl9Ci0JCQljYXNlIFNIT1JUIDogewotCQkJCXNob3J0W10gc2hvcnRzID0gbmV3IHNob3J0W2FycmF5Lmxlbmd0aF07Ci0JCQkJZm9yIChpbnQgaSA9IDA7IGkgPCBhcnJheS5sZW5ndGg7IGkrKykgewotCQkJCQlzaG9ydHNbaV0gPSBTaG9ydC5wYXJzZVNob3J0KGFycmF5W2ldKTsKLQkJCQl9Ci0JCQkJcmV0dXJuIHNob3J0czsKLQkJCX0KLQkJCWNhc2UgQ0hBUkFDVEVSIDogewotCQkJCWNoYXJbXSBjaGFycyA9IG5ldyBjaGFyW2FycmF5Lmxlbmd0aF07Ci0JCQkJZm9yIChpbnQgaSA9IDA7IGkgPCBhcnJheS5sZW5ndGg7IGkrKykgewotCQkJCQljaGFyc1tpXSA9IGFycmF5W2ldLmNoYXJBdCgwKTsKLQkJCQl9Ci0JCQkJcmV0dXJuIGNoYXJzOwotCQkJfQotCQkJY2FzZSBCT09MRUFOIDogewotCQkJCWJvb2xlYW5bXSBib29sZWFucyA9IG5ldyBib29sZWFuW2FycmF5Lmxlbmd0aF07Ci0JCQkJZm9yIChpbnQgaSA9IDA7IGkgPCBhcnJheS5sZW5ndGg7IGkrKykgewotCQkJCQlib29sZWFuc1tpXSA9IEJvb2xlYW4udmFsdWVPZihhcnJheVtpXSkuYm9vbGVhblZhbHVlKCk7Ci0JCQkJfQotCQkJCXJldHVybiBib29sZWFuczsKLQkJCX0KLQkJCWRlZmF1bHQgOiB7Ci0JCQkJdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihOTFMuYmluZChNZXNzYWdlcy5VTlNVUFBPUlRFRF9UWVBFLCBTdHJpbmcudmFsdWVPZihvYmplY3RUeXBlKSkpOwotCQkJfQotCQl9Ci0JfQotCi0JcHJpdmF0ZSBpbnQgZ2V0TmFtZXNwYWNlKFN0cmluZyB0YWdOYW1lKSB7Ci0JCVN0cmluZyBxdWFsaWZpZXIgPSBnZXROYW1lc3BhY2VRdWFsaWZpZXIodGFnTmFtZSk7Ci0JCVN0cmluZyBuYW1lc3BhY2UgPSBnZXRDdXJyZW50TmFtZXNwYWNlKHF1YWxpZmllcik7Ci0JCWlmICghcm9vdFBhc3NlZCkgeyAvLyB0aGlzIGlzIHRoZSByb290IGVsZW1lbnQKLQkJCWlmIChuYW1lc3BhY2UubGVuZ3RoKCkgPT0gMCkgewotCQkJCXJldHVybiBTZXJ2aWNlQ29tcG9uZW50Lk5BTUVTUEFDRV8xXzA7Ci0JCQl9Ci0JCX0KLQkJLy8gbm90IGEgcm9vdCBlbGVtZW50Ci0JCWlmIChuYW1lc3BhY2UuZXF1YWxzKFhNTE5TXzFfMCkpIHsKLQkJCXJldHVybiBTZXJ2aWNlQ29tcG9uZW50Lk5BTUVTUEFDRV8xXzA7Ci0JCX0gZWxzZSBpZiAobmFtZXNwYWNlLmVxdWFscyhYTUxOU18xXzEpKSB7Ci0JCQlyZXR1cm4gU2VydmljZUNvbXBvbmVudC5OQU1FU1BBQ0VfMV8xOwotCQl9IGVsc2UgaWYgKG5hbWVzcGFjZS5lcXVhbHMoWE1MTlNfMV8yKSkgewotCQkJcmV0dXJuIFNlcnZpY2VDb21wb25lbnQuTkFNRVNQQUNFXzFfMjsKLQkJfQotCi0JCS8vbmFtZXNwYWNlIGlzIG5vdCBrbm93bgotCQlyZXR1cm4gLTE7Ci0JfQotCi0JcHJpdmF0ZSBib29sZWFuIGlzTmFtZXNwYWNlQXRMZWFzdDExKFN0cmluZyB0YWdOYW1lKSB7Ci0JCWludCBuYW1lc3BhY2UgPSBnZXROYW1lc3BhY2UodGFnTmFtZSk7Ci0JCXJldHVybiAobmFtZXNwYWNlID49IFNlcnZpY2VDb21wb25lbnQuTkFNRVNQQUNFXzFfMSk7Ci0JfQotCi0JcHJpdmF0ZSBib29sZWFuIGlzTmFtZXNwYWNlQXRMZWFzdDEyKFN0cmluZyB0YWdOYW1lKSB7Ci0JCWludCBuYW1lc3BhY2UgPSBnZXROYW1lc3BhY2UodGFnTmFtZSk7Ci0JCXJldHVybiAobmFtZXNwYWNlID49IFNlcnZpY2VDb21wb25lbnQuTkFNRVNQQUNFXzFfMik7Ci0JfQotCi0JcHJpdmF0ZSB2b2lkIHByb2Nlc3NOYW1lc3BhY2VzRW50ZXIoVGFnIHRhZykgewotCQlFbnVtZXJhdGlvbiBlbiA9IHRhZy5nZXRBdHRyaWJ1dGVOYW1lcygpOwotCQl3aGlsZSAoZW4uaGFzTW9yZUVsZW1lbnRzKCkpIHsKLQkJCVN0cmluZyBhdHRyTmFtZSA9IChTdHJpbmcpIGVuLm5leHRFbGVtZW50KCk7Ci0JCQlpZiAoYXR0ck5hbWUuc3RhcnRzV2l0aChBVFRSX1hNTE5TKSkgewotCQkJCVN0cmluZyBxdWFsaWZpZXIgPSBhdHRyTmFtZS5zdWJzdHJpbmcoQVRUUl9YTUxOUy5sZW5ndGgoKSk7Ci0JCQkJaWYgKChxdWFsaWZpZXIubGVuZ3RoKCkgPT0gMCkgfHwgLy8gPC0gZGVmYXVsdCBuYW1lc3BhY2UKLQkJCQkJCSgocXVhbGlmaWVyLmNoYXJBdCgwKSA9PSAnOicpID8gKHF1YWxpZmllciA9IHF1YWxpZmllci5zdWJzdHJpbmcoMSkpLmxlbmd0aCgpID4gMCA6IGZhbHNlKSkgewotCi0JCQkJCWlmIChuYW1lc3BhY2VzID09IG51bGwpIHsKLQkJCQkJCW5hbWVzcGFjZXMgPSBuZXcgSGFzaHRhYmxlKCk7Ci0JCQkJCX0KLQkJCQkJU3RhY2sgc3RhY2sgPSBudWxsOwotCQkJCQlpZiAoKHN0YWNrID0gKFN0YWNrKSBuYW1lc3BhY2VzLmdldChxdWFsaWZpZXIpKSA9PSBudWxsKSB7Ci0JCQkJCQlzdGFjayA9IG5ldyBTdGFjaygpOwotCQkJCQkJbmFtZXNwYWNlcy5wdXQocXVhbGlmaWVyLCBzdGFjayk7Ci0JCQkJCX0KLQkJCQkJc3RhY2sucHVzaCh0YWcuZ2V0QXR0cmlidXRlKGF0dHJOYW1lKSk7Ci0JCQkJfQotCQkJfQotCQl9Ci0JfQotCi0JcHJpdmF0ZSBTdHJpbmcgZ2V0Q3VycmVudE5hbWVzcGFjZShTdHJpbmcgcXVhbGlmaWVyKSB7Ci0JCWlmIChuYW1lc3BhY2VzID09IG51bGwgfHwgcXVhbGlmaWVyID09IG51bGwpIHsKLQkJCXJldHVybiAiIjsgLy8kTk9OLU5MUy0xJAotCQl9Ci0JCVN0YWNrIHN0YWNrID0gKFN0YWNrKSBuYW1lc3BhY2VzLmdldChxdWFsaWZpZXIpOwotCQlpZiAoc3RhY2sgPT0gbnVsbCB8fCBzdGFjay5lbXB0eSgpKSB7Ci0JCQlyZXR1cm4gIiI7IC8vJE5PTi1OTFMtMSQKLQkJfQotCi0JCXJldHVybiAoU3RyaW5nKSBzdGFjay5wZWVrKCk7Ci0JfQotCi0JcHJpdmF0ZSB2b2lkIHByb2Nlc3NOYW1lc3BhY2VzTGVhdmUoVGFnIHRhZykgewotCQlpZiAobmFtZXNwYWNlcyA9PSBudWxsKSB7Ci0JCQlyZXR1cm47Ci0JCX0KLQkJRW51bWVyYXRpb24gZW4gPSB0YWcuZ2V0QXR0cmlidXRlTmFtZXMoKTsKLQkJd2hpbGUgKGVuLmhhc01vcmVFbGVtZW50cygpKSB7Ci0JCQlTdHJpbmcgYXR0ck5hbWUgPSAoU3RyaW5nKSBlbi5uZXh0RWxlbWVudCgpOwotCQkJaWYgKGF0dHJOYW1lLnN0YXJ0c1dpdGgoQVRUUl9YTUxOUykpIHsKLQkJCQlTdHJpbmcgcXVhbGlmaWVyID0gYXR0ck5hbWUuc3Vic3RyaW5nKEFUVFJfWE1MTlMubGVuZ3RoKCkpOwotCQkJCWlmICgocXVhbGlmaWVyLmxlbmd0aCgpID09IDApIHx8IC8vIDwtIGRlZmF1bHQgbmFtZXNwYWNlCi0JCQkJCQkoKHF1YWxpZmllci5jaGFyQXQoMCkgPT0gJzonKSA/IChxdWFsaWZpZXIgPSBxdWFsaWZpZXIuc3Vic3RyaW5nKDEpKS5sZW5ndGgoKSA+IDAgOiBmYWxzZSkpIHsKLQotCQkJCQlTdGFjayBzdGFjayA9IChTdGFjaykgbmFtZXNwYWNlcy5nZXQocXVhbGlmaWVyKTsKLQkJCQkJaWYgKHN0YWNrICE9IG51bGwpIHsKLQkJCQkJCWlmICghc3RhY2suZW1wdHkoKSkgewotCQkJCQkJCXN0YWNrLnBvcCgpOwotCQkJCQkJfQotCQkJCQkJaWYgKHN0YWNrLmVtcHR5KCkpIHsKLQkJCQkJCQluYW1lc3BhY2VzLnJlbW92ZShxdWFsaWZpZXIpOwotCQkJCQkJfQotCQkJCQl9Ci0JCQkJfQotCQkJfQotCQl9Ci0JfQotCi0JcHJpdmF0ZSBTdHJpbmcgZ2V0TmFtZXNwYWNlUXVhbGlmaWVyKFN0cmluZyBuYW1lKSB7Ci0JCWludCBpbmRleCA9IG5hbWUuaW5kZXhPZignOicpOwotCQlpZiAoaW5kZXggPCAwKSB7Ci0JCQlyZXR1cm4gIiI7IC8vJE5PTi1OTFMtMSQKLQkJfQotCQlyZXR1cm4gbmFtZS5zdWJzdHJpbmcoMCwgaW5kZXgpOwotCX0KLX0KZGlmZiAtLWdpdCBhL2J1bmRsZXMvb3JnLmVjbGlwc2UuZXF1aW5veC5kcy9zcmMvb3JnL2VjbGlwc2UvZXF1aW5veC9pbnRlcm5hbC9kcy9tb2RlbC9TZXJ2aWNlQ29tcG9uZW50LmphdmEgYi9idW5kbGVzL29yZy5lY2xpcHNlLmVxdWlub3guZHMvc3JjL29yZy9lY2xpcHNlL2VxdWlub3gvaW50ZXJuYWwvZHMvbW9kZWwvU2VydmljZUNvbXBvbmVudC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAxY2QwNDFjLi4wMDAwMDAwCi0tLSBhL2J1bmRsZXMvb3JnLmVjbGlwc2UuZXF1aW5veC5kcy9zcmMvb3JnL2VjbGlwc2UvZXF1aW5veC9pbnRlcm5hbC9kcy9tb2RlbC9TZXJ2aWNlQ29tcG9uZW50LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw5NzEgKzAsMCBAQAotLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKLSAqIENvcHlyaWdodCAoYykgMTk5Ny0yMDExIGJ5IFByb1N5c3QgU29mdHdhcmUgR21iSAotICogaHR0cDovL3d3dy5wcm9zeXN0LmNvbQotICogQWxsIHJpZ2h0cyByZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscwotICogYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2MS4wCi0gKiB3aGljaCBhY2NvbXBhbmllcyB0aGlzIGRpc3RyaWJ1dGlvbiwgYW5kIGlzIGF2YWlsYWJsZSBhdAotICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtdjEwLmh0bWwKLSAqCi0gKiBDb250cmlidXRvcnM6Ci0gKiAgICBQcm9TeXN0IFNvZnR3YXJlIEdtYkggLSBpbml0aWFsIEFQSSBhbmQgaW1wbGVtZW50YXRpb24KLSAqICAgIFNpbW9uIEFyY2hlciAJCSAgICAtIGJ1Zy5pZCA9IDIyNTYyNCAKLSAqICAgIEJyeWFuIEh1bnQgCQkgICAgLSBidWcuaWQgPSAyNzU5OTcgCi0gKiAgICBMYXphciBLaXJjaGV2CQkgCS0gYnVnLmlkID0gMzIwMzc3Ci0gKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLXBhY2thZ2Ugb3JnLmVjbGlwc2UuZXF1aW5veC5pbnRlcm5hbC5kcy5tb2RlbDsKLQotaW1wb3J0IGphdmEuaW8uKjsKLWltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC4qOwotaW1wb3J0IGphdmEudXRpbC4qOwotaW1wb3J0IG9yZy5hcGFjaGUuZmVsaXguc2NyLkNvbXBvbmVudDsKLWltcG9ydCBvcmcuYXBhY2hlLmZlbGl4LnNjci5SZWZlcmVuY2U7Ci1pbXBvcnQgb3JnLmVjbGlwc2UuZXF1aW5veC5pbnRlcm5hbC5kcy4qOwotaW1wb3J0IG9yZy5lY2xpcHNlLmVxdWlub3guaW50ZXJuYWwuZHMuaW1wbC5SZWFkT25seURpY3Rpb25hcnk7Ci1pbXBvcnQgb3JnLmVjbGlwc2UuZXF1aW5veC5pbnRlcm5hbC51dGlsLmlvLkV4dGVybmFsaXphYmxlOwotaW1wb3J0IG9yZy5lY2xpcHNlLmVxdWlub3guaW50ZXJuYWwudXRpbC5pby5FeHRlcm5hbGl6YWJsZURpY3Rpb25hcnk7Ci1pbXBvcnQgb3JnLmVjbGlwc2Uub3NnaS51dGlsLk5MUzsKLWltcG9ydCBvcmcub3NnaS5mcmFtZXdvcmsuKjsKLWltcG9ydCBvcmcub3NnaS5zZXJ2aWNlLmNvbXBvbmVudC4qOwotaW1wb3J0IG9yZy5vc2dpLnNlcnZpY2UubG9nLkxvZ1NlcnZpY2U7Ci0KLS8qKgotICogVGhpcyBpcyBhbiBPTyB3cmFwcGVyIGZvciB0aGUgWE1MIHJlcHJlc2VudGluZyB0aGUgY29tcG9uZW50cy4gSXQgYWxzbyBjYWNoZXMKLSAqIHRoZSBhY3RpdmF0ZSBhbmQgZGVhY3RpdmF0ZSBtZXRob2RzIG9mIHRoZSBjb21wb25lbnQuCi0gKiAKLSAqIEBhdXRob3IgVmFsZW50aW4gVmFsY2hldgotICogQGF1dGhvciBQYXZsaW4gRG9icmV2Ci0gKiBAYXV0aG9yIFN0b3lhbiBCb3NoZXYKLSAqLwotcHVibGljIGNsYXNzIFNlcnZpY2VDb21wb25lbnQgaW1wbGVtZW50cyBFeHRlcm5hbGl6YWJsZSwgQ29tcG9uZW50IHsKLQotCS8vY29uc3RhbnRzIGRlZmluaW5nIHBvc3NpYmxlIFNDUiBuYW1lc3BhY2VzIFhNTCBzY2hlbWFzCi0JcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTkFNRVNQQUNFXzFfMCA9IDA7Ci0JcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTkFNRVNQQUNFXzFfMSA9IDE7Ci0JcHVibGljIHN0YXRpYyBmaW5hbCBpbnQgTkFNRVNQQUNFXzFfMiA9IDI7Ci0KLQlwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBDT05GX1BPTElDWV9PUFRJT05BTCA9ICJvcHRpb25hbCI7IC8vJE5PTi1OTFMtMSQKLQlwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBDT05GX1BPTElDWV9SRVFVSVJFID0gInJlcXVpcmUiOyAvLyROT04tTkxTLTEkCi0JcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQ09ORl9QT0xJQ1lfSUdOT1JFID0gImlnbm9yZSI7IC8vJE5PTi1OTFMtMSQKLQotCXB1YmxpYyBWZWN0b3IgY29tcG9uZW50UHJvcHMgPSBudWxsOwotCi0JLy8gLS0tIGJlZ2luOiBYTUwgZGVmCi0JcHVibGljIFN0cmluZyBuYW1lOwotCXB1YmxpYyBTdHJpbmcgZmFjdG9yeTsKLQlTdHJpbmcgaW1wbGVtZW50YXRpb247IC8vIHRoZSBjbGFzcyBuYW1lCi0JUHJvcGVydGllcyBwcm9wZXJ0aWVzOyAvLyBwcm9wZXJ0eSBvciBwcm9wZXJ0aWVzCi0JU3RyaW5nIGNvbmZpZ3VyYXRpb25Qb2xpY3kgPSBDT05GX1BPTElDWV9PUFRJT05BTDsKLQlTdHJpbmcgYWN0aXZhdGVNZXRob2ROYW1lID0gImFjdGl2YXRlIjsgLy8kTk9OLU5MUy0xJAotCVN0cmluZyBkZWFjdGl2YXRlTWV0aG9kTmFtZSA9ICJkZWFjdGl2YXRlIjsgLy8kTk9OLU5MUy0xJAotCXB1YmxpYyBTdHJpbmcgbW9kaWZ5TWV0aG9kTmFtZSA9ICIiOyAvLyROT04tTkxTLTEkCi0KLQkvL1NpbmNlIERTIDEuMgotCXB1YmxpYyBTdHJpbmcgY29uZmlndXJhdGlvblBJRDsKLQotCS8vIHNlcnZpY2UKLQlwdWJsaWMgVmVjdG9yIHNlcnZpY2VJbnRlcmZhY2VzOyAvLyBhbGwgc3RyaW5ncwotCXB1YmxpYyBTdHJpbmdbXSBwcm92aWRlczsgLy8gdGhlIHNhbWUgYXMgYWJvdmUsIGJ1dCBhcyBTdHJpbmdbXQotCXB1YmxpYyBib29sZWFuIHNlcnZpY2VGYWN0b3J5ID0gZmFsc2U7Ci0KLQlwdWJsaWMgVmVjdG9yIHJlZmVyZW5jZXM7IC8vIENvbXBvbmVudFJlZmVyZW5jZQotCi0JcHVibGljIGJvb2xlYW4gYXV0b2VuYWJsZSA9IHRydWU7Ci0JcHVibGljIGJvb2xlYW4gaW1tZWRpYXRlID0gZmFsc2U7Ci0JcHVibGljIGludCBuYW1lc3BhY2UgPSBOQU1FU1BBQ0VfMV8wOwotCS8vIC0tLSBlbmQ6IFhNTCBkZWYKLQotCS8vIC0tLSBiZWdpbjogY2FjaGUKLQlwcml2YXRlIGJvb2xlYW4gYWN0aXZhdGVDYWNoZWQgPSBmYWxzZTsKLQlwcml2YXRlIGJvb2xlYW4gZGVhY3RpdmF0ZUNhY2hlZCA9IGZhbHNlOwotCXByaXZhdGUgYm9vbGVhbiBtb2RpZnlDYWNoZWQgPSBmYWxzZTsKLQlwcml2YXRlIE1ldGhvZCBhY3RpdmF0ZU1ldGhvZDsKLQlwcml2YXRlIE1ldGhvZCBkZWFjdGl2YXRlTWV0aG9kOwotCXByaXZhdGUgTWV0aG9kIG1vZGlmeU1ldGhvZDsKLQkvLyAtLS0gZW5kOiBjYWNoZQotCi0JLy8gLS0tIGJlZ2luOiBtb2RlbAotCXB1YmxpYyBib29sZWFuIGVuYWJsZWQ7Ci0JcHVibGljIEJ1bmRsZSBidW5kbGU7Ci0JcHVibGljIEJ1bmRsZUNvbnRleHQgYmM7Ci0JYm9vbGVhbiBhY3RpdmF0ZU1ldGhvZERlY2xhcmVkID0gZmFsc2U7Ci0JYm9vbGVhbiBkZWFjdGl2YXRlTWV0aG9kRGVjbGFyZWQgPSBmYWxzZTsKLQlpbnQgc3RhdGUgPSBDb21wb25lbnQuU1RBVEVfVU5TQVRJU0ZJRUQ7Ci0JLy8gLS0tIGVuZDogbW9kZWwKLQotCXB1YmxpYyBIYXNoU2V0IGNvbXBvbmVudElzc3VlcyA9IG5ldyBIYXNoU2V0KDEsIDEpOwotCXByaXZhdGUgUmVhZE9ubHlEaWN0aW9uYXJ5IHJlYWRPbmx5UHJvcHM7Ci0KLQlwdWJsaWMgU3RyaW5nIGdldENvbXBvbmVudElzc3VlcygpIHsKLQkJaWYgKCFjb21wb25lbnRJc3N1ZXMuaXNFbXB0eSgpKSB7Ci0JCQlTdHJpbmcgcmVzdWx0ID0gIiI7IC8vJE5PTi1OTFMtMSQKLQkJCU9iamVjdFtdIGlzc3VlcyA9IGNvbXBvbmVudElzc3Vlcy50b0FycmF5KCk7Ci0JCQlmb3IgKGludCBpID0gMDsgaSA8IGlzc3Vlcy5sZW5ndGg7IGkrKykgewotCQkJCXJlc3VsdCArPSBpc3N1ZXNbaV0gKyAiXG4iOyAvLyROT04tTkxTLTEkCi0JCQl9Ci0JCQlyZXR1cm4gcmVzdWx0OwotCQl9Ci0JCXJldHVybiBudWxsOwotCX0KLQotCXByaXZhdGUgc3RhdGljIGZpbmFsIENsYXNzIEFDVElWQVRFX01FVEhPRFNfUEFSQU1FVEVSU1tdID0gbmV3IENsYXNzW10ge0NvbXBvbmVudENvbnRleHQuY2xhc3N9OwotCi0JcHVibGljIFNlcnZpY2VDb21wb25lbnQoKSB7Ci0JCS8vCi0JfQotCi0JcHJpdmF0ZSBmaW5hbCBNZXRob2QgZ2V0TWV0aG9kKE9iamVjdCBpbnN0YW5jZSwgU3RyaW5nIG1ldGhvZE5hbWUsIGJvb2xlYW4gaXNBY3RpdmF0ZSkgdGhyb3dzIEV4Y2VwdGlvbiB7Ci0JCWlmIChBY3RpdmF0b3IuREVCVUcpIHsKLQkJCUFjdGl2YXRvci5sb2cuZGVidWcoIlNlcnZpY2VDb21wb25lbnQuZ2V0TWV0aG9kKCk6ICIgKyBtZXRob2ROYW1lLCBudWxsKTsgLy8kTk9OLU5MUy0xJAotCQl9Ci0JCU1ldGhvZCBtZXRob2QgPSBudWxsOwotCQlpbnQgbWV0aG9kUHJpb3JpdHkgPSBJbnRlZ2VyLk1BWF9WQUxVRTsKLQkJQ2xhc3MgY2xhenogPSBpbnN0YW5jZSAhPSBudWxsID8gaW5zdGFuY2UuZ2V0Q2xhc3MoKSA6IG51bGw7Ci0KLQkJd2hpbGUgKG1ldGhvZCA9PSBudWxsICYmIGNsYXp6ICE9IG51bGwpIHsKLQkJCWlmIChpc05hbWVzcGFjZUF0TGVhc3QxMSgpKSB7Ci0JCQkJTWV0aG9kW10gbWV0aG9kcyA9IGNsYXp6LmdldERlY2xhcmVkTWV0aG9kcygpOwotCQkJCWZvciAoaW50IGkgPSAwOyBpIDwgbWV0aG9kcy5sZW5ndGg7IGkrKykgewotCQkJCQlpZiAobWV0aG9kc1tpXS5nZXROYW1lKCkuZXF1YWxzKG1ldGhvZE5hbWUpKSB7Ci0JCQkJCQlDbGFzc1tdIHBhcmFtcyA9IG1ldGhvZHNbaV0uZ2V0UGFyYW1ldGVyVHlwZXMoKTsKLQkJCQkJCWJvb2xlYW4gYWNjZXB0ZWQgPSB0cnVlOwotCQkJCQkJZm9yIChpbnQgaiA9IDA7IGogPCBwYXJhbXMubGVuZ3RoOyBqKyspIHsKLQkJCQkJCQlpZiAocGFyYW1zW2pdID09IENvbXBvbmVudENvbnRleHQuY2xhc3MgfHwgcGFyYW1zW2pdID09IEJ1bmRsZUNvbnRleHQuY2xhc3MgfHwgcGFyYW1zW2pdID09IE1hcC5jbGFzcykgewotCQkJCQkJCQkvLyBjb3JyZWN0IHBhcmFtZXRlciBmb3IgYm90aCBhY3RpdmF0ZSBhbmQgZGVhY3RpdmF0ZSBtZXRob2RzCi0JCQkJCQkJfSBlbHNlIGlmICghaXNBY3RpdmF0ZSAmJiAocGFyYW1zW2pdID09IEludGVnZXIuY2xhc3MgfHwgcGFyYW1zW2pdID09IGludC5jbGFzcykpIHsKLQkJCQkJCQkJLy93ZSBhcmUgY2hlY2tpbmcgaW50L0ludGVnZXIgYXMgc3BlY2lhbCBkZWFjdGl2YXRlIHBhcmFtZXRlcnMKLQotCQkJCQkJCX0gZWxzZSB7Ci0JCQkJCQkJCS8vdGhlIHBhcmFtZXRlciBpcyBub3QgcmVjb2duaXplZAotCQkJCQkJCQlhY2NlcHRlZCA9IGZhbHNlOwotCQkJCQkJCQlicmVhazsKLQkJCQkJCQl9Ci0JCQkJCQl9Ci0JCQkJCQlpZiAoYWNjZXB0ZWQgJiYgU0NSVXRpbC5jaGVja01ldGhvZEFjY2VzcyhpbnN0YW5jZS5nZXRDbGFzcygpLCBjbGF6eiwgbWV0aG9kc1tpXSwgdHJ1ZSkpIHsKLQkJCQkJCQkvL2NoZWNrIGlmIHRoZSBuZXdseSBhY2NlcHRlZCBtZXRob2QgaGFzIGhpZ2hlciBwcmlvcml0eSB0aGFuIHRoZSBwcmV2aW91cyBvbmUgYW5kIHVzZSBpdAotCQkJCQkJCWludCBwcmlvID0gZ2V0TWV0aG9kUHJpb3JpdHkocGFyYW1zKTsKLQkJCQkJCQlpZiAocHJpbyA8IG1ldGhvZFByaW9yaXR5KSB7Ci0JCQkJCQkJCS8vZm91bmQgYSBtZXRob2Qgd2l0aCBhIGhpZ2hlciBwcmlvcml0eQotCQkJCQkJCQltZXRob2QgPSBtZXRob2RzW2ldOwotCQkJCQkJCQltZXRob2RQcmlvcml0eSA9IHByaW87Ci0JCQkJCQkJfQotCQkJCQkJfQotCQkJCQl9Ci0JCQkJfQotCQkJfSBlbHNlIHsKLQkJCQl0cnkgewotCQkJCQltZXRob2QgPSBjbGF6ei5nZXREZWNsYXJlZE1ldGhvZChtZXRob2ROYW1lLCBBQ1RJVkFURV9NRVRIT0RTX1BBUkFNRVRFUlMpOwotCQkJCQlpZiAobWV0aG9kICE9IG51bGwpIHsKLQkJCQkJCWlmICghU0NSVXRpbC5jaGVja01ldGhvZEFjY2VzcyhpbnN0YW5jZS5nZXRDbGFzcygpLCBjbGF6eiwgbWV0aG9kLCBmYWxzZSkpIHsKLQkJCQkJCQkvL3RoZSBtZXRob2QgaXMgbm90IGFjY2Vzc2libGUuIFN0b3AgdGhlIHNlYXJjaAotCQkJCQkJCUFjdGl2YXRvci5sb2coYmMsIExvZ1NlcnZpY2UuTE9HX1dBUk5JTkcsIE5MUy5iaW5kKE1lc3NhZ2VzLk1FVEhPRF9VTkFDQ0VTU0FCTEUsIG1ldGhvZE5hbWUsIGNsYXp6KSwgbnVsbCk7Ci0JCQkJCQkJY29tcG9uZW50SXNzdWVzLmFkZChOTFMuYmluZChNZXNzYWdlcy5NRVRIT0RfVU5BQ0NFU1NBQkxFLCBtZXRob2ROYW1lLCBjbGF6eikpOwotCQkJCQkJCW1ldGhvZCA9IG51bGw7Ci0JCQkJCQkJYnJlYWs7Ci0JCQkJCQl9Ci0JCQkJCX0KLQkJCQl9IGNhdGNoIChOb1N1Y2hNZXRob2RFeGNlcHRpb24gZSkgewotCQkJCQkvLyB0aGUgbWV0aG9kIGFjdGl2YXRlL2RlYWN0aXZhdGUgbWF5IG5vdCBleGlzdCBpbiB0aGUgY29tcG9uZW50IGltcGxlbWVudGF0aW9uIGNsYXNzCi0JCQkJfQotCQkJfQotCi0JCQlpZiAobWV0aG9kICE9IG51bGwpCi0JCQkJYnJlYWs7Ci0KLQkJCS8vIHNlYXJjaCBmb3IgdGhlIG1ldGhvZCBpbiB0aGUgcGFyZW50IGNsYXNzZXMhCi0JCQljbGF6eiA9IGNsYXp6LmdldFN1cGVyY2xhc3MoKTsKLQkJfQotCQlpZiAobWV0aG9kICE9IG51bGwpIHsKLQkJCWludCBtb2RpZmllcnMgPSBtZXRob2QuZ2V0TW9kaWZpZXJzKCk7Ci0JCQlpZiAoIU1vZGlmaWVyLmlzUHVibGljKG1vZGlmaWVycykpIHsKLQkJCQlTQ1JVdGlsLnNldEFjY2Vzc2libGUobWV0aG9kKTsKLQkJCX0KLQkJfQotCQlyZXR1cm4gbWV0aG9kOwotCX0KLQotCXByaXZhdGUgaW50IGdldE1ldGhvZFByaW9yaXR5KENsYXNzW10gcGFyYW1zKSB7Ci0JCWludCBwcmlvcml0eSA9IEludGVnZXIuTUFYX1ZBTFVFOwotCQlpZiAocGFyYW1zLmxlbmd0aCA9PSAxKSB7Ci0JCQlpZiAocGFyYW1zWzBdID09IENvbXBvbmVudENvbnRleHQuY2xhc3MpIHsKLQkJCQlwcmlvcml0eSA9IDA7IC8vaGlnaGVzdCBwcmlvcml0eQotCQkJfSBlbHNlIGlmIChwYXJhbXNbMF0gPT0gQnVuZGxlQ29udGV4dC5jbGFzcykgewotCQkJCXByaW9yaXR5ID0gMTsKLQkJCX0gZWxzZSBpZiAocGFyYW1zWzBdID09IE1hcC5jbGFzcykgewotCQkJCXByaW9yaXR5ID0gMjsKLQkJCX0gZWxzZSBpZiAocGFyYW1zWzBdID09IGludC5jbGFzcykgewotCQkJCXByaW9yaXR5ID0gMzsKLQkJCX0gZWxzZSBpZiAocGFyYW1zWzBdID09IEludGVnZXIuY2xhc3MpIHsKLQkJCQlwcmlvcml0eSA9IDQ7Ci0JCQl9Ci0JCX0gZWxzZSBpZiAocGFyYW1zLmxlbmd0aCA+PSAyKSB7Ci0JCQlwcmlvcml0eSA9IDU7Ci0JCX0gZWxzZSBpZiAocGFyYW1zLmxlbmd0aCA9PSAwKSB7Ci0JCQlwcmlvcml0eSA9IDY7Ci0JCX0KLQkJcmV0dXJuIHByaW9yaXR5OwotCX0KLQotCXZvaWQgYWN0aXZhdGUoT2JqZWN0IGluc3RhbmNlLCBDb21wb25lbnRDb250ZXh0IGNvbnRleHQpIHRocm93cyBDb21wb25lbnRFeGNlcHRpb24gewotCQl0cnkgewotCQkJaWYgKGlzTmFtZXNwYWNlQXRMZWFzdDExKCkpIHsKLQkJCQlpZiAoIWFjdGl2YXRlQ2FjaGVkKSB7Ci0JCQkJCWFjdGl2YXRlQ2FjaGVkID0gdHJ1ZTsKLQkJCQkJYWN0aXZhdGVNZXRob2QgPSBnZXRNZXRob2QoaW5zdGFuY2UsIGFjdGl2YXRlTWV0aG9kTmFtZSwgdHJ1ZSk7Ci0JCQkJfQotCQkJCS8vIGludm9rZSB0aGUgbWV0aG9kIGlmIGFueQotCQkJCWlmIChhY3RpdmF0ZU1ldGhvZCAhPSBudWxsKSB7Ci0JCQkJCUNsYXNzW10gcGFyYW1UeXBlcyA9IGFjdGl2YXRlTWV0aG9kLmdldFBhcmFtZXRlclR5cGVzKCk7Ci0JCQkJCU9iamVjdFtdIHBhcmFtcyA9IG51bGw7Ci0JCQkJCWlmIChwYXJhbVR5cGVzLmxlbmd0aCA9PSAxKSB7Ci0JCQkJCQlwYXJhbXMgPSBTQ1JVdGlsLmdldE9iamVjdEFycmF5KCk7Ci0JCQkJCX0gZWxzZSB7Ci0JCQkJCQlwYXJhbXMgPSBuZXcgT2JqZWN0W3BhcmFtVHlwZXMubGVuZ3RoXTsKLQkJCQkJfQotCQkJCQlmb3IgKGludCBpID0gMDsgaSA8IHBhcmFtcy5sZW5ndGg7IGkrKykgewotCQkJCQkJaWYgKHBhcmFtVHlwZXNbaV0gPT0gQ29tcG9uZW50Q29udGV4dC5jbGFzcykgewotCQkJCQkJCXBhcmFtc1tpXSA9IGNvbnRleHQ7Ci0JCQkJCQl9IGVsc2UgaWYgKHBhcmFtVHlwZXNbaV0gPT0gQnVuZGxlQ29udGV4dC5jbGFzcykgewotCQkJCQkJCXBhcmFtc1tpXSA9IGNvbnRleHQuZ2V0QnVuZGxlQ29udGV4dCgpOwotCQkJCQkJfSBlbHNlIGlmIChwYXJhbVR5cGVzW2ldID09IE1hcC5jbGFzcykgewotCQkJCQkJCXBhcmFtc1tpXSA9IGNvbnRleHQuZ2V0UHJvcGVydGllcygpOwotCQkJCQkJfQotCQkJCQl9Ci0KLQkJCQkJdHJ5IHsKLQkJCQkJCWFjdGl2YXRlTWV0aG9kLmludm9rZShpbnN0YW5jZSwgcGFyYW1zKTsKLQkJCQkJfSBmaW5hbGx5IHsKLQkJCQkJCWlmIChwYXJhbXMubGVuZ3RoID09IDEpIHsKLQkJCQkJCQlTQ1JVdGlsLnJlbGVhc2UocGFyYW1zKTsKLQkJCQkJCX0KLQkJCQkJfQotCQkJCX0gZWxzZSB7Ci0JCQkJCWlmIChhY3RpdmF0ZU1ldGhvZE5hbWUgIT0gImFjdGl2YXRlIikgeyAvLyROT04tTkxTLTEkCi0JCQkJCQkvL3RoZSBhY3RpdmF0ZSBtZXRob2QgaXMgc3BlY2lmaWVkIGluIHRoZSBjb21wb25lbnQgZGVzY3JpcHRpb24gWE1MIGJ5IHRoZSB1c2VyLgotCQkJCQkJLy9JdCBpcyBleHBlY3RlZCB0byBmaW5kIGl0IGluIHRoZSBpbXBsZW1lbnRhdGlvbiBjbGFzcwotCQkJCQkJY29tcG9uZW50SXNzdWVzLmFkZCgiQ2FuIG5vdCBhY3RpdmF0ZSBpbnN0YW5jZSBvZiBjb21wb25lbnQgIiArIHRoaXMuaW1wbGVtZW50YXRpb24gKyAiLiBUaGUgc3BlY2lmaWVkIGFjdGl2YXRlIG1ldGhvZCBbIiArIGFjdGl2YXRlTWV0aG9kTmFtZSArICJdIHdhcyBub3QgZm91bmQuIik7IC8vJE5PTi1OTFMtMSQgLy8kTk9OLU5MUy0yJCAvLyROT04tTkxTLTMkCi0JCQkJCQl0aHJvdyBuZXcgQ29tcG9uZW50RXhjZXB0aW9uKE5MUy5iaW5kKE1lc3NhZ2VzLlNQRUNJRklFRF9BQ1RJVkFURV9NRVRIT0RfTk9UX0ZPVU5ELCBpbnN0YW5jZSwgdGhpcykpOwotCQkJCQl9Ci0JCQkJfQotCQkJfSBlbHNlIHsKLQkJCQkvLyByZXRyaWV2ZSB0aGUgYWN0aXZhdGUgbWV0aG9kIGZyb20gY2FjaGUKLQkJCQlpZiAoIWFjdGl2YXRlQ2FjaGVkKSB7Ci0JCQkJCWFjdGl2YXRlQ2FjaGVkID0gdHJ1ZTsKLQkJCQkJYWN0aXZhdGVNZXRob2QgPSBnZXRNZXRob2QoaW5zdGFuY2UsICJhY3RpdmF0ZSIsIHRydWUpOyAvLyROT04tTkxTLTEkCi0JCQkJfQotCQkJCS8vIGludm9rZSB0aGUgbWV0aG9kIGlmIGFueQotCQkJCWlmIChhY3RpdmF0ZU1ldGhvZCAhPSBudWxsKSB7Ci0JCQkJCU9iamVjdFtdIHBhcmFtcyA9IFNDUlV0aWwuZ2V0T2JqZWN0QXJyYXkoKTsKLQkJCQkJcGFyYW1zWzBdID0gY29udGV4dDsKLQkJCQkJdHJ5IHsKLQkJCQkJCWFjdGl2YXRlTWV0aG9kLmludm9rZShpbnN0YW5jZSwgcGFyYW1zKTsKLQkJCQkJfSBmaW5hbGx5IHsKLQkJCQkJCVNDUlV0aWwucmVsZWFzZShwYXJhbXMpOwotCQkJCQl9Ci0JCQkJfQotCQkJfQotCQl9IGNhdGNoIChUaHJvd2FibGUgdCkgewotCQkJaWYgKHQgaW5zdGFuY2VvZiBDb21wb25lbnRFeGNlcHRpb24pIHsKLQkJCQl0aHJvdyAoQ29tcG9uZW50RXhjZXB0aW9uKSB0OwotCQkJfQotCQkJU3RyaW5nIGNhdXNlID0gdC50b1N0cmluZygpOwotCQkJaWYgKHQgaW5zdGFuY2VvZiBJbnZvY2F0aW9uVGFyZ2V0RXhjZXB0aW9uKSB7Ci0JCQkJY2F1c2UgPSB0LmdldENhdXNlKCkudG9TdHJpbmcoKTsKLQkJCX0KLQkJCWNvbXBvbmVudElzc3Vlcy5hZGQoIkNhbiBub3QgYWN0aXZhdGUgaW5zdGFuY2Ugb2YgY29tcG9uZW50ICIgKyB0aGlzLmltcGxlbWVudGF0aW9uICsgIi4gVGhlIGFjdGl2YXRpb24gdGhyb3dzOiAiICsgY2F1c2UpOyAvLyROT04tTkxTLTEkIC8vJE5PTi1OTFMtMiQgCi0JCQl0aHJvdyBuZXcgQ29tcG9uZW50RXhjZXB0aW9uKE5MUy5iaW5kKE1lc3NhZ2VzLkVYQ0VQVElPTl9BQ1RJVkFUSU5HX0lOU1RBTkNFLCBpbnN0YW5jZSwgbmFtZSksIHQpOwotCQkJLy8gcmV0aHJvdyBleGNlcHRpb24gc28gcmVzb2x2ZXIgaXMgZXZlbnR1YWxseSBub3RpZmllZCB0aGF0Ci0JCQkvLyB0aGUgcHJvY2Vzc2VkIFNDUCBpcyBiYWQKLQkJfQotCX0KLQotCXZvaWQgbW9kaWZpZWQoT2JqZWN0IGluc3RhbmNlLCBDb21wb25lbnRDb250ZXh0IGNvbnRleHQpIHRocm93cyBDb21wb25lbnRFeGNlcHRpb24gewotCQl0cnkgewotCQkJaWYgKGlzTmFtZXNwYWNlQXRMZWFzdDExKCkpIHsKLQkJCQlpZiAoIW1vZGlmeUNhY2hlZCkgewotCQkJCQltb2RpZnlDYWNoZWQgPSB0cnVlOwotCQkJCQlpZiAobW9kaWZ5TWV0aG9kTmFtZSAhPSAiIikgeyAvLyROT04tTkxTLTEkCi0JCQkJCQltb2RpZnlNZXRob2QgPSBnZXRNZXRob2QoaW5zdGFuY2UsIG1vZGlmeU1ldGhvZE5hbWUsIHRydWUpOwotCQkJCQl9Ci0JCQkJfQotCQkJCS8vIGludm9rZSB0aGUgbWV0aG9kIGlmIGFueQotCQkJCWlmIChtb2RpZnlNZXRob2QgIT0gbnVsbCkgewotCQkJCQlDbGFzc1tdIHBhcmFtVHlwZXMgPSBtb2RpZnlNZXRob2QuZ2V0UGFyYW1ldGVyVHlwZXMoKTsKLQkJCQkJT2JqZWN0W10gcGFyYW1zID0gbnVsbDsKLQkJCQkJaWYgKHBhcmFtVHlwZXMubGVuZ3RoID09IDEpIHsKLQkJCQkJCXBhcmFtcyA9IFNDUlV0aWwuZ2V0T2JqZWN0QXJyYXkoKTsKLQkJCQkJfSBlbHNlIHsKLQkJCQkJCXBhcmFtcyA9IG5ldyBPYmplY3RbcGFyYW1UeXBlcy5sZW5ndGhdOwotCQkJCQl9Ci0JCQkJCWZvciAoaW50IGkgPSAwOyBpIDwgcGFyYW1zLmxlbmd0aDsgaSsrKSB7Ci0JCQkJCQlpZiAocGFyYW1UeXBlc1tpXSA9PSBDb21wb25lbnRDb250ZXh0LmNsYXNzKSB7Ci0JCQkJCQkJcGFyYW1zW2ldID0gY29udGV4dDsKLQkJCQkJCX0gZWxzZSBpZiAocGFyYW1UeXBlc1tpXSA9PSBCdW5kbGVDb250ZXh0LmNsYXNzKSB7Ci0JCQkJCQkJcGFyYW1zW2ldID0gY29udGV4dC5nZXRCdW5kbGVDb250ZXh0KCk7Ci0JCQkJCQl9IGVsc2UgaWYgKHBhcmFtVHlwZXNbaV0gPT0gTWFwLmNsYXNzKSB7Ci0JCQkJCQkJcGFyYW1zW2ldID0gY29udGV4dC5nZXRQcm9wZXJ0aWVzKCk7Ci0JCQkJCQl9Ci0JCQkJCX0KLQotCQkJCQl0cnkgewotCQkJCQkJbW9kaWZ5TWV0aG9kLmludm9rZShpbnN0YW5jZSwgcGFyYW1zKTsKLQkJCQkJfSBmaW5hbGx5IHsKLQkJCQkJCWlmIChwYXJhbXMubGVuZ3RoID09IDEpIHsKLQkJCQkJCQlTQ1JVdGlsLnJlbGVhc2UocGFyYW1zKTsKLQkJCQkJCX0KLQkJCQkJfQotCQkJCX0gZWxzZSB7Ci0JCQkJCWlmIChtb2RpZnlNZXRob2ROYW1lICE9ICIiKSB7IC8vJE5PTi1OTFMtMSQKLQkJCQkJCS8vdGhlIG1vZGlmeSBtZXRob2QgaXMgc3BlY2lmaWVkIGluIHRoZSBjb21wb25lbnQgZGVzY3JpcHRpb24gWE1MIGJ5IHRoZSB1c2VyLgotCQkJCQkJLy9JdCBpcyBleHBlY3RlZCB0byBmaW5kIGl0IGluIHRoZSBpbXBsZW1lbnRhdGlvbiBjbGFzcwotCQkJCQkJdGhyb3cgbmV3IENvbXBvbmVudEV4Y2VwdGlvbihOTFMuYmluZChNZXNzYWdlcy5DQU5OT1RfTU9ESUZZX0lOU1RBTkNFX19NT0RJRllfTUVUSE9EX05PVF9GT1VORCwgaW5zdGFuY2UsIHRoaXMpKTsKLQkJCQkJfQotCQkJCX0KLQkJCX0KLQkJfSBjYXRjaCAoVGhyb3dhYmxlIHQpIHsKLQkJCWlmICh0IGluc3RhbmNlb2YgQ29tcG9uZW50RXhjZXB0aW9uKSB7Ci0JCQkJdGhyb3cgKENvbXBvbmVudEV4Y2VwdGlvbikgdDsKLQkJCX0KLQkJCUFjdGl2YXRvci5sb2coYmMsIExvZ1NlcnZpY2UuTE9HX0VSUk9SLCBOTFMuYmluZChNZXNzYWdlcy5FWENFUFRJT05fTU9ESUZZSU5HX0NPTVBPTkVOVCwgaW5zdGFuY2UsIHRoaXMpLCB0KTsKLQkJfQotCX0KLQotCXZvaWQgZGVhY3RpdmF0ZShPYmplY3QgaW5zdGFuY2UsIENvbXBvbmVudENvbnRleHQgY29udGV4dCwgaW50IGRlYWN0aXZhdGVSZWFzb24pIHsKLQkJdHJ5IHsKLQkJCWlmIChpc05hbWVzcGFjZUF0TGVhc3QxMSgpKSB7Ci0JCQkJaWYgKCFkZWFjdGl2YXRlQ2FjaGVkKSB7Ci0JCQkJCWRlYWN0aXZhdGVDYWNoZWQgPSB0cnVlOwotCQkJCQlkZWFjdGl2YXRlTWV0aG9kID0gZ2V0TWV0aG9kKGluc3RhbmNlLCBkZWFjdGl2YXRlTWV0aG9kTmFtZSwgZmFsc2UpOwotCQkJCX0KLQkJCQkvLyBpbnZva2UgdGhlIG1ldGhvZCBpZiBhbnkKLQkJCQlpZiAoZGVhY3RpdmF0ZU1ldGhvZCAhPSBudWxsKSB7Ci0JCQkJCUNsYXNzW10gcGFyYW1UeXBlcyA9IGRlYWN0aXZhdGVNZXRob2QuZ2V0UGFyYW1ldGVyVHlwZXMoKTsKLQkJCQkJT2JqZWN0W10gcGFyYW1zID0gbnVsbDsKLQkJCQkJaWYgKHBhcmFtVHlwZXMubGVuZ3RoID09IDEpIHsKLQkJCQkJCXBhcmFtcyA9IFNDUlV0aWwuZ2V0T2JqZWN0QXJyYXkoKTsKLQkJCQkJfSBlbHNlIHsKLQkJCQkJCXBhcmFtcyA9IG5ldyBPYmplY3RbcGFyYW1UeXBlcy5sZW5ndGhdOwotCQkJCQl9Ci0JCQkJCWZvciAoaW50IGkgPSAwOyBpIDwgcGFyYW1zLmxlbmd0aDsgaSsrKSB7Ci0JCQkJCQlpZiAocGFyYW1UeXBlc1tpXSA9PSBDb21wb25lbnRDb250ZXh0LmNsYXNzKSB7Ci0JCQkJCQkJcGFyYW1zW2ldID0gY29udGV4dDsKLQkJCQkJCX0gZWxzZSBpZiAocGFyYW1UeXBlc1tpXSA9PSBCdW5kbGVDb250ZXh0LmNsYXNzKSB7Ci0JCQkJCQkJcGFyYW1zW2ldID0gY29udGV4dC5nZXRCdW5kbGVDb250ZXh0KCk7Ci0JCQkJCQl9IGVsc2UgaWYgKHBhcmFtVHlwZXNbaV0gPT0gTWFwLmNsYXNzKSB7Ci0JCQkJCQkJcGFyYW1zW2ldID0gY29udGV4dC5nZXRQcm9wZXJ0aWVzKCk7Ci0JCQkJCQl9IGVsc2UgaWYgKHBhcmFtVHlwZXNbaV0gPT0gaW50LmNsYXNzKSB7Ci0JCQkJCQkJcGFyYW1zW2ldID0gbmV3IEludGVnZXIoZGVhY3RpdmF0ZVJlYXNvbik7Ci0JCQkJCQl9IGVsc2UgaWYgKHBhcmFtVHlwZXNbaV0gPT0gSW50ZWdlci5jbGFzcykgewotCQkJCQkJCXBhcmFtc1tpXSA9IG5ldyBJbnRlZ2VyKGRlYWN0aXZhdGVSZWFzb24pOwotCQkJCQkJfQotCQkJCQl9Ci0KLQkJCQkJdHJ5IHsKLQkJCQkJCWRlYWN0aXZhdGVNZXRob2QuaW52b2tlKGluc3RhbmNlLCBwYXJhbXMpOwotCQkJCQl9IGZpbmFsbHkgewotCQkJCQkJaWYgKHBhcmFtcy5sZW5ndGggPT0gMSkgewotCQkJCQkJCVNDUlV0aWwucmVsZWFzZShwYXJhbXMpOwotCQkJCQkJfQotCQkJCQl9Ci0JCQkJfSBlbHNlIHsKLQkJCQkJaWYgKGRlYWN0aXZhdGVNZXRob2ROYW1lICE9ICJkZWFjdGl2YXRlIikgeyAvLyROT04tTkxTLTEkCi0JCQkJCQkvL3RoZSBkZWFjdGl2YXRlIG1ldGhvZCBpcyBzcGVjaWZpZWQgaW4gdGhlIGNvbXBvbmVudCBkZXNjcmlwdGlvbiBYTUwgYnkgdGhlIHVzZXIuCi0JCQkJCQkvL0l0IGlzIGV4cGVjdGVkIHRvIGZpbmQgaXQgaW4gdGhlIGltcGxlbWVudGF0aW9uIGNsYXNzCi0JCQkJCQlBY3RpdmF0b3IubG9nKGJjLCBMb2dTZXJ2aWNlLkxPR19FUlJPUiwgTkxTLmJpbmQoTWVzc2FnZXMuU1BFQ0lGSUVEX0RFQUNUSVZBVEVfTUVUSE9EX05PVF9GT1VORCwgaW5zdGFuY2UsIHRoaXMpLCBudWxsKTsKLQkJCQkJfQotCQkJCX0KLQkJCX0gZWxzZSB7Ci0JCQkJLy8gcmV0cmlldmUgdGhlIGFjdGl2YXRlIG1ldGhvZCBmcm9tIGNhY2hlCi0JCQkJaWYgKCFkZWFjdGl2YXRlQ2FjaGVkKSB7Ci0JCQkJCWRlYWN0aXZhdGVDYWNoZWQgPSB0cnVlOwotCQkJCQlkZWFjdGl2YXRlTWV0aG9kID0gZ2V0TWV0aG9kKGluc3RhbmNlLCAiZGVhY3RpdmF0ZSIsIGZhbHNlKTsgLy8kTk9OLU5MUy0xJAotCQkJCX0KLQkJCQkvLyBpbnZva2UgdGhlIG1ldGhvZAotCQkJCWlmIChkZWFjdGl2YXRlTWV0aG9kICE9IG51bGwpIHsKLQkJCQkJT2JqZWN0W10gcGFyYW1zID0gU0NSVXRpbC5nZXRPYmplY3RBcnJheSgpOwotCQkJCQlwYXJhbXNbMF0gPSBjb250ZXh0OwotCQkJCQl0cnkgewotCQkJCQkJZGVhY3RpdmF0ZU1ldGhvZC5pbnZva2UoaW5zdGFuY2UsIHBhcmFtcyk7Ci0JCQkJCX0gZmluYWxseSB7Ci0JCQkJCQlTQ1JVdGlsLnJlbGVhc2UocGFyYW1zKTsKLQkJCQkJfQotCQkJCX0KLQkJCX0KLQkJfSBjYXRjaCAoVGhyb3dhYmxlIHQpIHsKLQkJCUFjdGl2YXRvci5sb2coYmMsIExvZ1NlcnZpY2UuTE9HX0VSUk9SLCBOTFMuYmluZChNZXNzYWdlcy5FUlJPUl9ERUFDVElWQVRJTkdfSU5TVEFOQ0UsIHRoaXMpLCB0KTsKLQkJfQotCX0KLQotCS8qKgotCSAqIFRoaXMgbWV0aG9kIGlzIGNhbGxlZCBmcm9tIHRoZSBYTUwgcGFyc2VyIHRvIHZhbGlkYXRlIHRoZSBjb21wb25lbnQgb25jZQotCSAqIGl0IGlzIGZ1bGx5IGxvYWRlZCEKLQkgKiAKLQkgKiBAcGFyYW0gbGluZQotCSAqICAgICAgICAgICAgdGhlIGxpbmUgYXQgd2hpY2ggdGhlIHRoZSBjb21wb25lbnQgZGVmaW5pdGlvbiBlbmRzCi0JICogQHBhcmFtIF9uYW1lc3BhY2Ugc3BlY2lmeSB0aGUgbmFtZXNwYWNlIG9mIHRoZSBjb21wb25lbnQgYWNjb3JkaW5nIHRvIFhNTCBTQ1Igc2NoZW1hCi0JICovCi0Jdm9pZCB2YWxpZGF0ZShpbnQgbGluZSwgaW50IF9uYW1lc3BhY2UpIHsKLQkJLy8JCVN5c3RlbS5vdXQucHJpbnRsbigiVmFsaWRhdGluZyBjb21wb25lbnQgIiArIG5hbWUgKyAiIHdpdGggbmFtZXNwYWNlICIgKyAobmFtZXNwYWNlMTEgPyAiMS4xIiA6ICIxLjAiKSk7Ci0JCXRoaXMubmFtZXNwYWNlID0gX25hbWVzcGFjZTsKLQkJaWYgKG5hbWUgPT0gbnVsbCkgewotCQkJaWYgKGlzTmFtZXNwYWNlQXRMZWFzdDExKCkpIHsKLQkJCQluYW1lID0gaW1wbGVtZW50YXRpb247Ci0JCQl9IGVsc2UgewotCQkJCXRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTkxTLmJpbmQoTWVzc2FnZXMuTk9fTkFNRV9BVFRSSUJVVEUsIEludGVnZXIudG9TdHJpbmcobGluZSkpKTsKLQkJCX0KLQkJfQotCQlpZiAoaXNOYW1lc3BhY2VBdExlYXN0MTEoKSkgewotCQkJaWYgKCEoY29uZmlndXJhdGlvblBvbGljeSA9PSBDT05GX1BPTElDWV9PUFRJT05BTCB8fCBjb25maWd1cmF0aW9uUG9saWN5ID09IENPTkZfUE9MSUNZX1JFUVVJUkUgfHwgY29uZmlndXJhdGlvblBvbGljeSA9PSBDT05GX1BPTElDWV9JR05PUkUpKSB7Ci0JCQkJdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihOTFMuYmluZChNZXNzYWdlcy5JTkNPUlJFQ1RfQUNUSVZBVElPTl9QT0xJQ1ksIG5hbWUsIEludGVnZXIudG9TdHJpbmcobGluZSkpKTsKLQkJCX0KLQkJfQotCi0JCWlmIChpc05hbWVzcGFjZUF0TGVhc3QxMigpKSB7Ci0JCQlpZiAoY29uZmlndXJhdGlvblBJRCA9PSBudWxsKSB7Ci0JCQkJY29uZmlndXJhdGlvblBJRCA9IG5hbWU7Ci0JCQl9Ci0JCX0KLQotCQlpZiAoaW1wbGVtZW50YXRpb24gPT0gbnVsbCkgewotCQkJdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihOTFMuYmluZChNZXNzYWdlcy5OT19JTVBMRU1FTlRBVElPTl9BVFRSSUJVVEUsIG5hbWUsIEludGVnZXIudG9TdHJpbmcobGluZSkpKTsKLQkJfQotCi0JCS8vIGNvbXBvbmVudCBmYWN0b3J5IGlzIGluY29tcGF0aWJsZSB3aXRoIHNlcnZpY2UgZmFjdG9yeQotCQlpZiAoZmFjdG9yeSAhPSBudWxsICYmIHNlcnZpY2VGYWN0b3J5KSB7Ci0JCQl0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKE5MUy5iaW5kKE1lc3NhZ2VzLklOVkFMSURfQ09NUE9ORU5UX0ZBQ1RPUllfQU5EX1NFUlZJQ0VfRkFDVE9SWSwgbmFtZSkpOwotCQl9Ci0KLQkJaWYgKGltbWVkaWF0ZSkgewotCQkJaWYgKHNlcnZpY2VGYWN0b3J5KQotCQkJCXRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTkxTLmJpbmQoTWVzc2FnZXMuSU5WQUxJRF9DT01QT05FTlRfSU1NRURJQVRFX0FORF9TRVJWSUNFX0ZBQ1RPUlksIG5hbWUpKTsKLQkJCWlmIChmYWN0b3J5ICE9IG51bGwpCi0JCQkJdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihOTFMuYmluZChNZXNzYWdlcy5JTlZBTElEX0NPTVBPTkVOVF9JTU1FRElBVEVfQU5EX0ZBQ1RPUlksIG5hbWUpKTsKLQkJfSBlbHNlIHsKLQkJCWlmICgoc2VydmljZUludGVyZmFjZXMgPT0gbnVsbCkgJiYgKGZhY3RvcnkgPT0gbnVsbCkpIHsKLQkJCQl0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKE5MUy5iaW5kKE1lc3NhZ2VzLklOVkFMSURfQ09NUE9ORU5UX05PX1NFUlZJQ0VTX05PX0lNTUVESUFURSwgbmFtZSkpOwotCQkJfQotCQl9Ci0KLQkJLy8gbWFrZSBzdXJlIHRoYXQgcmVmZXJlbmNlcyBhcmUgYWxzbyB2YWxpZAotCQlpZiAocmVmZXJlbmNlcyAhPSBudWxsKSB7Ci0JCQlmb3IgKGludCBpID0gMDsgaSA8IHJlZmVyZW5jZXMuc2l6ZSgpOyBpKyspIHsKLQkJCQlDb21wb25lbnRSZWZlcmVuY2UgciA9IChDb21wb25lbnRSZWZlcmVuY2UpIHJlZmVyZW5jZXMuZWxlbWVudEF0KGkpOwotCQkJCWlmIChyLm5hbWUgPT0gbnVsbCkgewotCQkJCQlpZiAoaXNOYW1lc3BhY2VBdExlYXN0MTEoKSkgewotCQkJCQkJci5uYW1lID0gci5pbnRlcmZhY2VOYW1lOwotCQkJCQl9IGVsc2UgewotCQkJCQkJdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbihOTFMuYmluZChNZXNzYWdlcy5DT01QT05FTlRfSEFTX0lMTEVHQUxfUkVGRVJFTkNFLCBuZXcgT2JqZWN0W10ge25hbWUsIEludGVnZXIudG9TdHJpbmcobGluZSksIHJ9KSk7Ci0JCQkJCX0KLQkJCQl9Ci0JCQkJaWYgKHIuaW50ZXJmYWNlTmFtZSA9PSBudWxsIHx8IHIubmFtZS5sZW5ndGgoKSA9PSAwIHx8IHIuaW50ZXJmYWNlTmFtZS5sZW5ndGgoKSA9PSAwKSB7Ci0JCQkJCXRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTkxTLmJpbmQoTWVzc2FnZXMuQ09NUE9ORU5UX0hBU19JTExFR0FMX1JFRkVSRU5DRSwgbmV3IE9iamVjdFtdIHtuYW1lLCBJbnRlZ2VyLnRvU3RyaW5nKGxpbmUpLCByfSkpOwotCQkJCX0KLQkJCQlmb3IgKGludCBqID0gaSArIDE7IGogPCByZWZlcmVuY2VzLnNpemUoKTsgaisrKSB7Ci0JCQkJCUNvbXBvbmVudFJlZmVyZW5jZSByZWYyID0gKENvbXBvbmVudFJlZmVyZW5jZSkgcmVmZXJlbmNlcy5lbGVtZW50QXQoaik7Ci0JCQkJCWlmIChyLm5hbWUuZXF1YWxzKHJlZjIubmFtZSkpIHsKLQkJCQkJCXRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oTkxTLmJpbmQoTWVzc2FnZXMuRFVQTElDQVRFRF9SRUZFUkVOQ0VfTkFNRVMsIG5hbWUsIEludGVnZXIudG9TdHJpbmcobGluZSkpKTsKLQkJCQkJfQotCQkJCX0KLQkJCX0KLQkJfQotCi0JCS8vIGNhY2hlIHRoZSBzZXJ2aWNlIGludGVyZmFjZXMgYXMgU3RyaW5nW10gdG9vLgotCQlpZiAoc2VydmljZUludGVyZmFjZXMgIT0gbnVsbCAmJiAhc2VydmljZUludGVyZmFjZXMuaXNFbXB0eSgpKSB7Ci0JCQlwcm92aWRlcyA9IG5ldyBTdHJpbmdbc2VydmljZUludGVyZmFjZXMuc2l6ZSgpXTsKLQkJCXNlcnZpY2VJbnRlcmZhY2VzLmNvcHlJbnRvKHByb3ZpZGVzKTsKLQkJfQotCi0JCS8vIG1ha2Ugc3VyZSB0aGF0IHRoZSBjb21wb25lbnQgd2lsbCBnZXQgYXV0b21hdGljYWxseSBlbmFibGVkIQotCQllbmFibGVkID0gYXV0b2VuYWJsZTsKLQl9Ci0KLQkvKioKLQkgKiBUaGlzIG1ldGhvZCB3aWxsIGluc3RhbnRpYXRlIHRoZSBpbXBsZW1lbnRhdGlvbiBjbGFzcyEKLQkgKiAKLQkgKiBAcmV0dXJuIGluc3RhbmNlIG9mIHRoZSBjb21wb25lbnQgaW1wbGVtZW50YXRpb24gY2xhc3MuIElmIHRoZSBjb21wb25lbnRzCi0JICogICAgICAgICBleHBvcnRzIHNvbWUgc2VydmljZXMsIHRoZSBpbXBsZW1lbnRhdGlvbiBtdXN0IGltcGxlbWVudCBhbGwgb2YKLQkgKiAgICAgICAgIHRoZW0KLQkgKiBAdGhyb3dzIEV4Y2VwdGlvbgotCSAqICAgICAgICAgICAgIGlzIHRocm93biBpZiB0aGUgaW1wbGVtZW50YXRpb24gY2Fubm90IGJlIGluc3RhbnRpYXRlZCBmb3IKLQkgKiAgICAgICAgICAgICBzb21lIHJlYXNvbnMuCi0JICovCi0JZmluYWwgT2JqZWN0IGNyZWF0ZUluc3RhbmNlKCkgdGhyb3dzIEV4Y2VwdGlvbiB7Ci0JCXRyeSB7Ci0JCQlyZXR1cm4gYnVuZGxlLmxvYWRDbGFzcyhpbXBsZW1lbnRhdGlvbikubmV3SW5zdGFuY2UoKTsKLQkJfSBjYXRjaCAoVGhyb3dhYmxlIHQpIHsKLQkJCXRocm93IG5ldyBDb21wb25lbnRFeGNlcHRpb24oTkxTLmJpbmQoTWVzc2FnZXMuRVhDRVBUSU9OX0NSRUFUSU5HX0NPTVBPTkVOVF9JTlNUQU5DRSwgdGhpcyksIHQpOwotCQl9Ci0JfQotCi0JLyoqCi0JICogVGhpcyBtZXRob2Qgd2lsbCBkaXNwb3NlIGV2ZXJ5dGhpbmcKLQkgKi8KLQkvLyBUT0RPIDogdGhpcyBtZXRob2QgaXMgbm90IHVzZWQgLSBzaG91bGQgYmUgcmVtb3ZlZD8KLQlwdWJsaWMgZmluYWwgdm9pZCBkaXNwb3NlKCkgewotCi0JCWFjdGl2YXRlQ2FjaGVkID0gZGVhY3RpdmF0ZUNhY2hlZCA9IGZhbHNlOwotCQlhY3RpdmF0ZU1ldGhvZCA9IGRlYWN0aXZhdGVNZXRob2QgPSBudWxsOwotCi0JCWVuYWJsZWQgPSBmYWxzZTsKLQkJYnVuZGxlID0gbnVsbDsKLQkJLy8gYmMgPSBudWxsOwotCi0JCWlmIChyZWZlcmVuY2VzICE9IG51bGwpIHsKLQkJCWZvciAoaW50IGkgPSAwOyBpIDwgcmVmZXJlbmNlcy5zaXplKCk7IGkrKykgewotCQkJCUNvbXBvbmVudFJlZmVyZW5jZSByZWYgPSAoQ29tcG9uZW50UmVmZXJlbmNlKSByZWZlcmVuY2VzLmVsZW1lbnRBdChpKTsKLQkJCQlyZWYuZGlzcG9zZSgpOwotCQkJfQotCQkJcmVmZXJlbmNlcy5yZW1vdmVBbGxFbGVtZW50cygpOwotCQkJcmVmZXJlbmNlcyA9IG51bGw7Ci0JCX0KLQotCQlpZiAocHJvcGVydGllcyAhPSBudWxsKSB7Ci0JCQlwcm9wZXJ0aWVzLmNsZWFyKCk7Ci0JCQlwcm9wZXJ0aWVzID0gbnVsbDsKLQkJfQotCi0JCWlmIChzZXJ2aWNlSW50ZXJmYWNlcyAhPSBudWxsKSB7Ci0JCQlzZXJ2aWNlSW50ZXJmYWNlcy5yZW1vdmVBbGxFbGVtZW50cygpOwotCQkJc2VydmljZUludGVyZmFjZXMgPSBudWxsOwotCQl9Ci0JfQotCi0JcHVibGljIGJvb2xlYW4gcHJvdmlkZXMoU3RyaW5nIGludGVyZmFjZU5hbWUpIHsKLQkJcmV0dXJuIHNlcnZpY2VJbnRlcmZhY2VzICE9IG51bGwgJiYgc2VydmljZUludGVyZmFjZXMuY29udGFpbnMoaW50ZXJmYWNlTmFtZSk7Ci0JfQotCi0JcHVibGljIFN0cmluZyBnZXRDb25maWd1cmF0aW9uUElEKCkgewotCQlpZiAoaXNOYW1lc3BhY2VBdExlYXN0MTIoKSkgewotCQkJcmV0dXJuIGNvbmZpZ3VyYXRpb25QSUQ7Ci0JCX0KLQkJcmV0dXJuIG5hbWU7Ci0JfQotCi0JLyoKLQkgKiAobm9uLUphdmFkb2MpCi0JICogCi0JICogQHNlZSBqYXZhLmxhbmcuT2JqZWN0I3RvU3RyaW5nKCkKLQkgKi8KLQlwdWJsaWMgZmluYWwgU3RyaW5nIHRvU3RyaW5nKCkgewotCQlTdHJpbmdCdWZmZXIgYnVmZmVyID0gbmV3IFN0cmluZ0J1ZmZlcigpOwotCQlidWZmZXIuYXBwZW5kKCJDb21wb25lbnRbIik7IC8vJE5PTi1OTFMtMSQKLQkJYnVmZmVyLmFwcGVuZCgiXG5cdG5hbWUgPSAiKS5hcHBlbmQobmFtZSk7IC8vJE5PTi1OTFMtMSQKLQkJaWYgKGlzTmFtZXNwYWNlQXRMZWFzdDExKCkpIHsKLQkJCWJ1ZmZlci5hcHBlbmQoIlxuXHRhY3RpdmF0ZSA9ICIpLmFwcGVuZChhY3RpdmF0ZU1ldGhvZE5hbWUpOyAvLyROT04tTkxTLTEkCi0JCQlidWZmZXIuYXBwZW5kKCJcblx0ZGVhY3RpdmF0ZSA9ICIpLmFwcGVuZChkZWFjdGl2YXRlTWV0aG9kTmFtZSk7IC8vJE5PTi1OTFMtMSQKLQkJCWJ1ZmZlci5hcHBlbmQoIlxuXHRtb2RpZmllZCA9ICIpLmFwcGVuZChtb2RpZnlNZXRob2ROYW1lKTsgLy8kTk9OLU5MUy0xJAotCQkJYnVmZmVyLmFwcGVuZCgiXG5cdGNvbmZpZ3VyYXRpb24tcG9saWN5ID0gIikuYXBwZW5kKGNvbmZpZ3VyYXRpb25Qb2xpY3kpOyAvLyROT04tTkxTLTEkCi0JCX0KLQkJaWYgKGlzTmFtZXNwYWNlQXRMZWFzdDEyKCkpIHsKLQkJCWJ1ZmZlci5hcHBlbmQoIlxuXHRjb25maWd1cmF0aW9uLXBpZCA9ICIpLmFwcGVuZChjb25maWd1cmF0aW9uUElEKTsgLy8kTk9OLU5MUy0xJAotCQl9Ci0JCWJ1ZmZlci5hcHBlbmQoIlxuXHRmYWN0b3J5ID0gIikuYXBwZW5kKGZhY3RvcnkpOyAvLyROT04tTkxTLTEkCi0JCWJ1ZmZlci5hcHBlbmQoIlxuXHRhdXRvZW5hYmxlID0gIikuYXBwZW5kKGF1dG9lbmFibGUpOyAvLyROT04tTkxTLTEkCi0JCWJ1ZmZlci5hcHBlbmQoIlxuXHRpbW1lZGlhdGUgPSAiKS5hcHBlbmQoaW1tZWRpYXRlKTsgLy8kTk9OLU5MUy0xJAotCi0JCWJ1ZmZlci5hcHBlbmQoIlxuXHRpbXBsZW1lbnRhdGlvbiA9ICIpLmFwcGVuZChpbXBsZW1lbnRhdGlvbik7IC8vJE5PTi1OTFMtMSQKLQkJYnVmZmVyLmFwcGVuZCgiXG5cdHN0YXRlID0gIikuYXBwZW5kKFNDUlV0aWwuZ2V0U3RhdGVTdHJpbmdSZXByZXNlbnRhdGlvbihzdGF0ZSkpOyAvLyROT04tTkxTLTEkCi0JCVN0cmluZ0J1ZmZlciBidWYgPSBuZXcgU3RyaW5nQnVmZmVyKDIwMCk7Ci0JCWlmIChwcm9wZXJ0aWVzICE9IG51bGwpIHsKLQkJCWJ1Zi5hcHBlbmQoJ3snKTsKLQkJCUVudW1lcmF0aW9uIGtleXMgPSBwcm9wZXJ0aWVzLmtleXMoKTsKLQkJCXdoaWxlIChrZXlzLmhhc01vcmVFbGVtZW50cygpKSB7Ci0JCQkJT2JqZWN0IGtleSA9IGtleXMubmV4dEVsZW1lbnQoKTsKLQkJCQlidWYuYXBwZW5kKGtleSkuYXBwZW5kKCc9JykuYXBwZW5kKFNDUlV0aWwuZ2V0U3RyaW5nUmVwcmVzZW50YXRpb24ocHJvcGVydGllcy5nZXQoa2V5KSkpOwotCQkJCWlmIChrZXlzLmhhc01vcmVFbGVtZW50cygpKSB7Ci0JCQkJCWJ1Zi5hcHBlbmQoIiwgIik7IC8vJE5PTi1OTFMtMSQKLQkJCQl9Ci0JCQl9Ci0JCQlidWYuYXBwZW5kKCd9Jyk7Ci0JCX0KLQkJYnVmZmVyLmFwcGVuZCgiXG5cdHByb3BlcnRpZXMgPSAiKS5hcHBlbmQoYnVmLnRvU3RyaW5nKCkpOyAvLyROT04tTkxTLTEkCi0KLQkJYnVmZmVyLmFwcGVuZCgiXG5cdHNlcnZpY2VGYWN0b3J5ID0gIikuYXBwZW5kKHNlcnZpY2VGYWN0b3J5KTsgLy8kTk9OLU5MUy0xJAotCQlidWZmZXIuYXBwZW5kKCJcblx0c2VydmljZUludGVyZmFjZSA9ICIpLmFwcGVuZChzZXJ2aWNlSW50ZXJmYWNlcyk7IC8vJE5PTi1OTFMtMSQKLQotCQlpZiAocmVmZXJlbmNlcyA9PSBudWxsKSB7Ci0JCQlidWZmZXIuYXBwZW5kKCJcblx0cmVmZXJlbmNlcyA9ICIpLmFwcGVuZCgibnVsbCIpOyAvLyROT04tTkxTLTEkIC8vJE5PTi1OTFMtMiQKLQkJfSBlbHNlIHsKLQkJCWJ1ZmZlci5hcHBlbmQoIlxuXHRyZWZlcmVuY2VzID0geyIpOyAvLyROT04tTkxTLTEkCi0JCQlmb3IgKGludCBpID0gMDsgaSA8IHJlZmVyZW5jZXMuc2l6ZSgpOyBpKyspIHsKLQkJCQlidWZmZXIuYXBwZW5kKCJcblx0XHQiKS5hcHBlbmQocmVmZXJlbmNlcy5lbGVtZW50QXQoaSkpOyAvLyROT04tTkxTLTEkCi0JCQl9Ci0JCQlidWZmZXIuYXBwZW5kKCJcblx0fSIpOyAvLyROT04tTkxTLTEkCi0JCX0KLQkJYnVmZmVyLmFwcGVuZCgiXG5cdGxvY2F0ZWQgaW4gYnVuZGxlID0gIikuYXBwZW5kKGJ1bmRsZSk7IC8vJE5PTi1OTFMtMSQKLQkJYnVmZmVyLmFwcGVuZCgiXG5dIik7IC8vJE5PTi1OTFMtMSQKLQkJcmV0dXJuIGJ1ZmZlci50b1N0cmluZygpOwotCX0KLQotCXB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCB3cml0ZU9iamVjdChPdXRwdXRTdHJlYW0gcykgdGhyb3dzIEV4Y2VwdGlvbiB7Ci0JCXRyeSB7Ci0JCQlEYXRhT3V0cHV0U3RyZWFtIG91dDsKLQkJCWlmIChzIGluc3RhbmNlb2YgRGF0YU91dHB1dFN0cmVhbSkgewotCQkJCW91dCA9IChEYXRhT3V0cHV0U3RyZWFtKSBzOwotCQkJfSBlbHNlIHsKLQkJCQlvdXQgPSBuZXcgRGF0YU91dHB1dFN0cmVhbShzKTsKLQkJCX0KLQotCQkJYm9vbGVhbiBmbGFnOwotCQkJaW50IGNvdW50OwotCi0JCQlvdXQud3JpdGVVVEYobmFtZSk7Ci0JCQlvdXQud3JpdGVVVEYoaW1wbGVtZW50YXRpb24pOwotCQkJb3V0LndyaXRlQm9vbGVhbihzZXJ2aWNlRmFjdG9yeSk7Ci0JCQlvdXQud3JpdGVCb29sZWFuKGF1dG9lbmFibGUpOwotCQkJb3V0LndyaXRlQm9vbGVhbihpbW1lZGlhdGUpOwotCi0JCQlmbGFnID0gZmFjdG9yeSAhPSBudWxsOwotCQkJb3V0LndyaXRlQm9vbGVhbihmbGFnKTsKLQkJCWlmIChmbGFnKQotCQkJCW91dC53cml0ZVVURihmYWN0b3J5KTsKLQotCQkJY291bnQgPSBzZXJ2aWNlSW50ZXJmYWNlcyA9PSBudWxsID8gMCA6IHNlcnZpY2VJbnRlcmZhY2VzLnNpemUoKTsKLQkJCW91dC53cml0ZUludChjb3VudCk7Ci0JCQlmb3IgKGludCBpID0gMDsgaSA8IGNvdW50OyBpKyspIHsKLQkJCQlvdXQud3JpdGVVVEYoc2VydmljZUludGVyZmFjZXMuZWxlbWVudEF0KGkpLnRvU3RyaW5nKCkpOwotCQkJfQotCi0JCQljb3VudCA9IHJlZmVyZW5jZXMgPT0gbnVsbCA/IDAgOiByZWZlcmVuY2VzLnNpemUoKTsKLQkJCW91dC53cml0ZUludChjb3VudCk7Ci0JCQlmb3IgKGludCBpID0gMDsgaSA8IGNvdW50OyBpKyspIHsKLQkJCQlDb21wb25lbnRSZWZlcmVuY2UgcmVmID0gKENvbXBvbmVudFJlZmVyZW5jZSkgcmVmZXJlbmNlcy5lbGVtZW50QXQoaSk7Ci0JCQkJcmVmLndyaXRlT2JqZWN0KG91dCk7Ci0JCQl9Ci0KLQkJCWZsYWcgPSBwcm9wZXJ0aWVzICE9IG51bGwgJiYgIXByb3BlcnRpZXMuaXNFbXB0eSgpOwotCQkJb3V0LndyaXRlQm9vbGVhbihmbGFnKTsKLQkJCWlmIChmbGFnKSB7Ci0JCQkJRXh0ZXJuYWxpemFibGVEaWN0aW9uYXJ5IGRpY3Rpb25hcnkgPSBuZXcgRXh0ZXJuYWxpemFibGVEaWN0aW9uYXJ5KCk7Ci0JCQkJZGljdGlvbmFyeS5jb3B5RnJvbShwcm9wZXJ0aWVzKTsKLQkJCQlkaWN0aW9uYXJ5LndyaXRlT2JqZWN0KG91dCk7Ci0JCQl9Ci0KLQkJCW91dC53cml0ZUludChuYW1lc3BhY2UpOwotCQkJaWYgKGlzTmFtZXNwYWNlQXRMZWFzdDExKCkpIHsKLQkJCQlpZiAoY29uZmlndXJhdGlvblBvbGljeSA9PSBDT05GX1BPTElDWV9PUFRJT05BTCkgewotCQkJCQkvL3RoaXMgaXMgdGhlIGRlZmF1bHQgdmFsdWUuIERvIG5vdCB3cml0ZSBpdC4gSnVzdCBhZGQgYSBtYXJrCi0JCQkJCW91dC53cml0ZUJvb2xlYW4oZmFsc2UpOwotCQkJCX0gZWxzZSB7Ci0JCQkJCW91dC53cml0ZUJvb2xlYW4odHJ1ZSk7Ci0JCQkJCW91dC53cml0ZVVURihjb25maWd1cmF0aW9uUG9saWN5KTsKLQkJCQl9Ci0JCQkJaWYgKCFhY3RpdmF0ZU1ldGhvZERlY2xhcmVkKSB7Ci0JCQkJCS8vdGhpcyBpcyB0aGUgZGVmYXVsdCB2YWx1ZS4gRG8gbm90IHdyaXRlIGl0LiBKdXN0IGFkZCBhIG1hcmsKLQkJCQkJb3V0LndyaXRlQm9vbGVhbihmYWxzZSk7Ci0JCQkJfSBlbHNlIHsKLQkJCQkJb3V0LndyaXRlQm9vbGVhbih0cnVlKTsKLQkJCQkJb3V0LndyaXRlVVRGKGFjdGl2YXRlTWV0aG9kTmFtZSk7Ci0JCQkJfQotCQkJCWlmICghZGVhY3RpdmF0ZU1ldGhvZERlY2xhcmVkKSB7Ci0JCQkJCS8vdGhpcyBpcyB0aGUgZGVmYXVsdCB2YWx1ZS4gRG8gbm90IHdyaXRlIGl0LiBKdXN0IGFkZCBhIG1hcmsKLQkJCQkJb3V0LndyaXRlQm9vbGVhbihmYWxzZSk7Ci0JCQkJfSBlbHNlIHsKLQkJCQkJb3V0LndyaXRlQm9vbGVhbih0cnVlKTsKLQkJCQkJb3V0LndyaXRlVVRGKGRlYWN0aXZhdGVNZXRob2ROYW1lKTsKLQkJCQl9Ci0JCQkJaWYgKG1vZGlmeU1ldGhvZE5hbWUgPT0gIiIpIHsgLy8kTk9OLU5MUy0xJAotCQkJCQkvL3RoaXMgaXMgdGhlIGRlZmF1bHQgdmFsdWUuIERvIG5vdCB3cml0ZSBpdC4gSnVzdCBhZGQgYSBtYXJrCi0JCQkJCW91dC53cml0ZUJvb2xlYW4oZmFsc2UpOwotCQkJCX0gZWxzZSB7Ci0JCQkJCW91dC53cml0ZUJvb2xlYW4odHJ1ZSk7Ci0JCQkJCW91dC53cml0ZVVURihtb2RpZnlNZXRob2ROYW1lKTsKLQkJCQl9Ci0JCQl9Ci0JCQlpZiAoaXNOYW1lc3BhY2VBdExlYXN0MTIoKSkgewotCQkJCWlmIChjb25maWd1cmF0aW9uUElEID09IG5hbWUpIHsKLQkJCQkJb3V0LndyaXRlQm9vbGVhbihmYWxzZSk7Ci0JCQkJfSBlbHNlIHsKLQkJCQkJb3V0LndyaXRlQm9vbGVhbih0cnVlKTsKLQkJCQkJb3V0LndyaXRlVVRGKGNvbmZpZ3VyYXRpb25QSUQpOwotCQkJCX0KLQkJCX0KLQkJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKLQkJCUFjdGl2YXRvci5sb2cobnVsbCwgTG9nU2VydmljZS5MT0dfRVJST1IsIE1lc3NhZ2VzLkVSUk9SX1dSSVRJTkdfT0JKRUNULCBlKTsKLQkJCXRocm93IGU7Ci0JCX0KLQl9Ci0KLQkvKioKLQkgKiBEb24ndCBmb3JnZXQgdG8gc2V0IHRoZSBidW5kbGUgJiB0aGUgYmMgYXR0cmlidXRlcyEhISEhIQotCSAqIAotCSAqIEBwYXJhbSBzCi0JICogICAgICAgICAgICB0aGUgaW5wdXQgc3RyZWFtIGZyb20gd2hpY2ggdG8gcmVhZCB0aGUgb2JqZWN0Ci0JICogQHRocm93cyBFeGNlcHRpb24KLQkgKiBAc2VlIG9yZy5lY2xpcHNlLmVxdWlub3guaW50ZXJuYWwudXRpbC5pby5FeHRlcm5hbGl6YWJsZSNyZWFkT2JqZWN0KGphdmEuaW8uSW5wdXRTdHJlYW0pCi0JICovCi0JcHVibGljIHN5bmNocm9uaXplZCB2b2lkIHJlYWRPYmplY3QoSW5wdXRTdHJlYW0gcykgdGhyb3dzIEV4Y2VwdGlvbiB7Ci0JCXRyeSB7Ci0JCQlEYXRhSW5wdXRTdHJlYW0gaW47Ci0JCQlpZiAocyBpbnN0YW5jZW9mIERhdGFJbnB1dFN0cmVhbSkgewotCQkJCWluID0gKERhdGFJbnB1dFN0cmVhbSkgczsKLQkJCX0gZWxzZSB7Ci0JCQkJaW4gPSBuZXcgRGF0YUlucHV0U3RyZWFtKHMpOwotCQkJfQotCQkJYm9vbGVhbiBmbGFnOwotCQkJaW50IGNvdW50OwotCi0JCQluYW1lID0gaW4ucmVhZFVURigpOwotCQkJaW1wbGVtZW50YXRpb24gPSBpbi5yZWFkVVRGKCk7Ci0JCQlzZXJ2aWNlRmFjdG9yeSA9IGluLnJlYWRCb29sZWFuKCk7Ci0JCQlhdXRvZW5hYmxlID0gaW4ucmVhZEJvb2xlYW4oKTsKLQkJCWltbWVkaWF0ZSA9IGluLnJlYWRCb29sZWFuKCk7Ci0KLQkJCWZsYWcgPSBpbi5yZWFkQm9vbGVhbigpOwotCQkJaWYgKGZsYWcpCi0JCQkJZmFjdG9yeSA9IGluLnJlYWRVVEYoKTsKLQotCQkJY291bnQgPSBpbi5yZWFkSW50KCk7Ci0JCQlpZiAoY291bnQgPiAwKSB7Ci0JCQkJc2VydmljZUludGVyZmFjZXMgPSBuZXcgVmVjdG9yKGNvdW50KTsKLQkJCQlwcm92aWRlcyA9IG5ldyBTdHJpbmdbY291bnRdOwotCQkJCWZvciAoaW50IGkgPSAwOyBpIDwgY291bnQ7IGkrKykgewotCQkJCQlTdHJpbmcgZW50cnkgPSBpbi5yZWFkVVRGKCk7Ci0JCQkJCXNlcnZpY2VJbnRlcmZhY2VzLmFkZEVsZW1lbnQoZW50cnkpOwotCQkJCQlwcm92aWRlc1tpXSA9IGVudHJ5OwotCQkJCX0KLQkJCX0KLQotCQkJY291bnQgPSBpbi5yZWFkSW50KCk7Ci0JCQlpZiAoY291bnQgPiAwKSB7Ci0JCQkJcmVmZXJlbmNlcyA9IG5ldyBWZWN0b3IoY291bnQpOwotCQkJCWZvciAoaW50IGkgPSAwOyBpIDwgY291bnQ7IGkrKykgewotCQkJCQlDb21wb25lbnRSZWZlcmVuY2UgcmVmID0gbmV3IENvbXBvbmVudFJlZmVyZW5jZSh0aGlzKTsKLQkJCQkJcmVmLnJlYWRPYmplY3QoaW4pOwotCQkJCX0KLQkJCX0KLQotCQkJZmxhZyA9IGluLnJlYWRCb29sZWFuKCk7Ci0JCQlpZiAoZmxhZykgewotCQkJCUV4dGVybmFsaXphYmxlRGljdGlvbmFyeSBkaWN0aW9uYXJ5ID0gbmV3IEV4dGVybmFsaXphYmxlRGljdGlvbmFyeSgpOwotCQkJCWRpY3Rpb25hcnkucmVhZE9iamVjdChpbik7Ci0JCQkJUHJvcGVydGllcyBwcm9wcyA9IG5ldyBQcm9wZXJ0aWVzKCk7Ci0JCQkJZm9yIChFbnVtZXJhdGlvbiBrZXlzID0gZGljdGlvbmFyeS5rZXlzKCk7IGtleXMuaGFzTW9yZUVsZW1lbnRzKCk7KSB7Ci0JCQkJCVN0cmluZyBrZXkgPSAoU3RyaW5nKSBrZXlzLm5leHRFbGVtZW50KCk7Ci0JCQkJCXByb3BzLnB1dChrZXksIGRpY3Rpb25hcnkuZ2V0KGtleSkpOwotCQkJCX0KLQkJCQlwcm9wZXJ0aWVzID0gcHJvcHM7Ci0JCQl9Ci0JCQluYW1lc3BhY2UgPSBpbi5yZWFkSW50KCk7Ci0JCQlpZiAoaXNOYW1lc3BhY2VBdExlYXN0MTEoKSkgewotCQkJCWZsYWcgPSBpbi5yZWFkQm9vbGVhbigpOwotCQkJCWlmIChmbGFnKSB7Ci0JCQkJCWNvbmZpZ3VyYXRpb25Qb2xpY3kgPSBpbi5yZWFkVVRGKCk7Ci0JCQkJCWlmIChjb25maWd1cmF0aW9uUG9saWN5LmVxdWFscyhDT05GX1BPTElDWV9JR05PUkUpKSB7Ci0JCQkJCQljb25maWd1cmF0aW9uUG9saWN5ID0gQ09ORl9QT0xJQ1lfSUdOT1JFOwotCQkJCQl9IGVsc2UgewotCQkJCQkJY29uZmlndXJhdGlvblBvbGljeSA9IENPTkZfUE9MSUNZX1JFUVVJUkU7Ci0JCQkJCX0KLQkJCQl9Ci0JCQkJZmxhZyA9IGluLnJlYWRCb29sZWFuKCk7Ci0JCQkJaWYgKGZsYWcpIHsKLQkJCQkJYWN0aXZhdGVNZXRob2ROYW1lID0gaW4ucmVhZFVURigpOwotCQkJCQlhY3RpdmF0ZU1ldGhvZERlY2xhcmVkID0gdHJ1ZTsKLQkJCQl9Ci0JCQkJZmxhZyA9IGluLnJlYWRCb29sZWFuKCk7Ci0JCQkJaWYgKGZsYWcpIHsKLQkJCQkJZGVhY3RpdmF0ZU1ldGhvZE5hbWUgPSBpbi5yZWFkVVRGKCk7Ci0JCQkJCWRlYWN0aXZhdGVNZXRob2REZWNsYXJlZCA9IHRydWU7Ci0JCQkJfQotCQkJCWZsYWcgPSBpbi5yZWFkQm9vbGVhbigpOwotCQkJCWlmIChmbGFnKQotCQkJCQltb2RpZnlNZXRob2ROYW1lID0gaW4ucmVhZFVURigpOwotCQkJfQotCQkJaWYgKGlzTmFtZXNwYWNlQXRMZWFzdDEyKCkpIHsKLQkJCQlmbGFnID0gaW4ucmVhZEJvb2xlYW4oKTsKLQkJCQlpZiAoZmxhZykgewotCQkJCQljb25maWd1cmF0aW9uUElEID0gaW4ucmVhZFVURigpOwotCQkJCX0gZWxzZSB7Ci0JCQkJCWNvbmZpZ3VyYXRpb25QSUQgPSBuYW1lOwotCQkJCX0KLQkJCX0KLQkJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKLQkJCUFjdGl2YXRvci5sb2cobnVsbCwgTG9nU2VydmljZS5MT0dfRVJST1IsIE1lc3NhZ2VzLkVSUk9SX1JFQURJTkdfT0JKRUNULCBlKTsKLQkJCXRocm93IGU7Ci0JCX0KLQl9Ci0KLQlwdWJsaWMgU2VydmljZUNvbXBvbmVudFByb3AgZ2V0Q29tcG9uZW50UHJvcEJ5UElEKFN0cmluZyBwaWQpIHsKLQkJaWYgKGNvbXBvbmVudFByb3BzICE9IG51bGwpIHsKLQkJCWZvciAoaW50IGkgPSAwOyBpIDwgY29tcG9uZW50UHJvcHMuc2l6ZSgpOyBpKyspIHsKLQkJCQlTZXJ2aWNlQ29tcG9uZW50UHJvcCBzY3AgPSAoU2VydmljZUNvbXBvbmVudFByb3ApIGNvbXBvbmVudFByb3BzLmVsZW1lbnRBdChpKTsKLQkJCQlpZiAoc2NwLmdldFByb3BlcnRpZXMoKSAhPSBudWxsKSB7Ci0JCQkJCWlmIChwaWQuZXF1YWxzKHNjcC5nZXRQcm9wZXJ0aWVzKCkuZ2V0KENvbnN0YW50cy5TRVJWSUNFX1BJRCkpKSB7Ci0JCQkJCQlyZXR1cm4gc2NwOwotCQkJCQl9Ci0JCQkJfQotCQkJfQotCQl9Ci0JCXJldHVybiBudWxsOwotCX0KLQotCXB1YmxpYyB2b2lkIGFkZFNlcnZpY2VDb21wb25lbnRQcm9wKFNlcnZpY2VDb21wb25lbnRQcm9wIHNjcCkgewotCQlpZiAoY29tcG9uZW50UHJvcHMgPT0gbnVsbCkgewotCQkJY29tcG9uZW50UHJvcHMgPSBuZXcgVmVjdG9yKDEpOwotCQl9Ci0JCWNvbXBvbmVudFByb3BzLmFkZEVsZW1lbnQoc2NwKTsKLQl9Ci0KLQkvKioKLQkgKiBSZXR1cm4gdGhlIFNlcnZpY2VDb21wb25lbnRQcm9wIG9iamVjdCBjcmVhdGVkIGZvciB0aGlzIGNvbXBvbmVudC4gTm90ZSB0aGVyZSBtaWdodCBiZSBtb3JlIHRoYW4gb25lIFNDUCBvYmplY3RzLiAKLQkgKiBUaGlzIG1ldGhvZCB3aWxsIHJldHVybiBhbHdheXMgdGhlIGZpcnN0IG9uZQotCSAqIEByZXR1cm4gdGhlIFNlcnZpY2VDb21wb25lbnRQcm9wIG9iamVjdCBjcmVhdGVkIGZvciB0aGlzIGNvbXBvbmVudCAKLQkgKi8KLQlwdWJsaWMgU2VydmljZUNvbXBvbmVudFByb3AgZ2V0U2VydmljZUNvbXBvbmVudFByb3AoKSB7Ci0JCWlmIChjb21wb25lbnRQcm9wcyAhPSBudWxsKSB7Ci0JCQlzeW5jaHJvbml6ZWQgKGNvbXBvbmVudFByb3BzKSB7Ci0JCQkJaWYgKCFjb21wb25lbnRQcm9wcy5pc0VtcHR5KCkpIHsKLQkJCQkJcmV0dXJuIChTZXJ2aWNlQ29tcG9uZW50UHJvcCkgY29tcG9uZW50UHJvcHMuZWxlbWVudEF0KDApOwotCQkJCX0KLQkJCX0KLQkJfQotCQlyZXR1cm4gbnVsbDsKLQl9Ci0KLQlwdWJsaWMgYm9vbGVhbiBpc05hbWVzcGFjZUF0TGVhc3QxMSgpIHsKLQkJcmV0dXJuIG5hbWVzcGFjZSA+PSBOQU1FU1BBQ0VfMV8xOwotCX0KLQotCXB1YmxpYyBib29sZWFuIGlzTmFtZXNwYWNlQXRMZWFzdDEyKCkgewotCQlyZXR1cm4gbmFtZXNwYWNlID49IE5BTUVTUEFDRV8xXzI7Ci0JfQotCi0JcHVibGljIGJvb2xlYW4gaXNJbW1lZGlhdGUoKSB7Ci0JCXJldHVybiBpbW1lZGlhdGU7Ci0JfQotCi0JcHVibGljIHZvaWQgc2V0SW1tZWRpYXRlKGJvb2xlYW4gaW1tZWRpYXRlKSB7Ci0JCXRoaXMuaW1tZWRpYXRlID0gaW1tZWRpYXRlOwotCX0KLQotCXB1YmxpYyBTdHJpbmcgZ2V0Q29uZmlndXJhdGlvblBvbGljeSgpIHsKLQkJcmV0dXJuIGNvbmZpZ3VyYXRpb25Qb2xpY3k7Ci0JfQotCi0JcHVibGljIHZvaWQgZGlzYWJsZSgpIHsKLQkJaWYgKGdldFN0YXRlKCkgPT0gU1RBVEVfRElTUE9TRUQpIHsKLQkJCXRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oTWVzc2FnZXMuQ09NUE9ORU5UX0RJU1BPU0VEKTsKLQkJfSBlbHNlIGlmIChnZXRTdGF0ZSgpICE9IFNUQVRFX0RJU0FCTEVEKSB7Ci0JCQlJbnN0YW5jZVByb2Nlc3MucmVzb2x2ZXIubWdyLmRpc2FibGVDb21wb25lbnQobmFtZSwgYnVuZGxlKTsKLQkJfQotCX0KLQotCXB1YmxpYyB2b2lkIGVuYWJsZSgpIHsKLQkJaWYgKGdldFN0YXRlKCkgPT0gU1RBVEVfRElTUE9TRUQpIHsKLQkJCXRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oTWVzc2FnZXMuQ09NUE9ORU5UX0RJU1BPU0VEKTsKLQkJfSBlbHNlIGlmIChnZXRTdGF0ZSgpID09IFNUQVRFX0RJU0FCTEVEKSB7Ci0JCQlJbnN0YW5jZVByb2Nlc3MucmVzb2x2ZXIubWdyLmVuYWJsZUNvbXBvbmVudChuYW1lLCBidW5kbGUpOwotCQl9Ci0JfQotCi0JcHVibGljIFN0cmluZyBnZXRBY3RpdmF0ZSgpIHsKLQkJcmV0dXJuIGFjdGl2YXRlTWV0aG9kTmFtZTsKLQl9Ci0KLQlwdWJsaWMgQnVuZGxlIGdldEJ1bmRsZSgpIHsKLQkJcmV0dXJuIGJ1bmRsZTsKLQl9Ci0KLQlwdWJsaWMgU3RyaW5nIGdldENsYXNzTmFtZSgpIHsKLQkJcmV0dXJuIGltcGxlbWVudGF0aW9uOwotCX0KLQotCXB1YmxpYyBDb21wb25lbnRJbnN0YW5jZSBnZXRDb21wb25lbnRJbnN0YW5jZSgpIHsKLQkJaWYgKGNvbXBvbmVudFByb3BzICE9IG51bGwgJiYgIWNvbXBvbmVudFByb3BzLmlzRW1wdHkoKSkgewotCQkJLy9nZXQgdGhlIGZpcnN0IGJ1aWx0IGNvbXBvZW50J3MgaW5zdGFuY2UgCi0JCQlWZWN0b3IgaW5zdGFuY2VzID0gKChTZXJ2aWNlQ29tcG9uZW50UHJvcCkgY29tcG9uZW50UHJvcHMuZWxlbWVudEF0KDApKS5pbnN0YW5jZXM7Ci0JCQlpZiAoIWluc3RhbmNlcy5pc0VtcHR5KCkpIHsKLQkJCQlyZXR1cm4gKENvbXBvbmVudEluc3RhbmNlKSBpbnN0YW5jZXMuZWxlbWVudEF0KDApOwotCQkJfQotCQl9Ci0JCS8vVGhlIGNvbXBvbmVudCBpcyBub3QgeWV0IGJ1aWx0Ci0JCXJldHVybiBudWxsOwotCX0KLQotCXB1YmxpYyBTdHJpbmcgZ2V0RGVhY3RpdmF0ZSgpIHsKLQkJcmV0dXJuIGRlYWN0aXZhdGVNZXRob2ROYW1lOwotCX0KLQotCXB1YmxpYyBTdHJpbmcgZ2V0RmFjdG9yeSgpIHsKLQkJcmV0dXJuIGZhY3Rvcnk7Ci0JfQotCi0JcHVibGljIGxvbmcgZ2V0SWQoKSB7Ci0JCWlmIChjb21wb25lbnRQcm9wcyAhPSBudWxsICYmICFjb21wb25lbnRQcm9wcy5pc0VtcHR5KCkpIHsKLQkJCS8vZ2V0IHRoZSBmaXJzdCBidWlsdCBjb21wb25lbnQncyBJRCAKLQkJCXJldHVybiAoKExvbmcpICgoU2VydmljZUNvbXBvbmVudFByb3ApIGNvbXBvbmVudFByb3BzLmVsZW1lbnRBdCgwKSkucHJvcGVydGllcy5nZXQoQ29tcG9uZW50Q29uc3RhbnRzLkNPTVBPTkVOVF9JRCkpLmxvbmdWYWx1ZSgpOwotCQl9Ci0JCS8vVGhlIGNvbXBvbmVudCBpcyBub3QgeWV0IGdpdmVuIGFuIElEIGJ5IHRoZSBTUkMgYmVjYXVzZSBpdCBpcyBub3QgYWN0aXZlCi0JCXJldHVybiAtMTsKLQl9Ci0KLQlwdWJsaWMgU3RyaW5nIGdldE1vZGlmaWVkKCkgewotCQlpZiAoIWlzTmFtZXNwYWNlQXRMZWFzdDExKCkpIHsKLQkJCXJldHVybiBudWxsOwotCQl9Ci0JCXJldHVybiBtb2RpZnlNZXRob2ROYW1lOwotCX0KLQotCXB1YmxpYyBTdHJpbmcgZ2V0TmFtZSgpIHsKLQkJcmV0dXJuIG5hbWU7Ci0JfQotCi0JcHVibGljIERpY3Rpb25hcnkgZ2V0UHJvcGVydGllcygpIHsKLQkJaWYgKHJlYWRPbmx5UHJvcHMgPT0gbnVsbCkgewotCQkJcmVhZE9ubHlQcm9wcyA9IG5ldyBSZWFkT25seURpY3Rpb25hcnkocHJvcGVydGllcyk7Ci0JCX0gZWxzZSB7Ci0JCQkvLyB0aGUgc2NwIHByb3BlcnRpZXMgbWF5IGhhdmUgYmVlbiBtb2RpZmllZCBieSBjb25maWd1cmF0aW9uCi0JCQkvLyB1cGRhdGUgdGhlIGluc3RhbmNlIHdpdGggdGhlIGN1cnJlbnQgcHJvcGVydGllcwotCQkJcmVhZE9ubHlQcm9wcy51cGRhdGVEZWxlZ2F0ZShwcm9wZXJ0aWVzKTsKLQkJfQotCQlyZXR1cm4gcmVhZE9ubHlQcm9wczsKLQl9Ci0KLQlwdWJsaWMgUmVmZXJlbmNlW10gZ2V0UmVmZXJlbmNlcygpIHsKLQkJaWYgKHJlZmVyZW5jZXMgIT0gbnVsbCAmJiAhcmVmZXJlbmNlcy5pc0VtcHR5KCkpIHsKLQkJCW9yZy5hcGFjaGUuZmVsaXguc2NyLlJlZmVyZW5jZVtdIHJlcyA9IG5ldyBvcmcuYXBhY2hlLmZlbGl4LnNjci5SZWZlcmVuY2VbcmVmZXJlbmNlcy5zaXplKCldOwotCQkJcmVmZXJlbmNlcy5jb3B5SW50byhyZXMpOwotCQkJcmV0dXJuIHJlczsKLQkJfQotCQlyZXR1cm4gbnVsbDsKLQl9Ci0KLQlwdWJsaWMgU3RyaW5nW10gZ2V0U2VydmljZXMoKSB7Ci0JCXJldHVybiBwcm92aWRlczsKLQl9Ci0KLQlwdWJsaWMgaW50IGdldFN0YXRlKCkgewotCQkvL2NoZWNrIGlmIHRoZXJlIGlzIGF0IGxlYXN0IG9uZSBTQ1AgY3JlYXRlZCBhbmQgcmV0dXJuIGl0cyBzdGF0ZQotCQlpZiAoY29tcG9uZW50UHJvcHMgIT0gbnVsbCAmJiAhY29tcG9uZW50UHJvcHMuaXNFbXB0eSgpKSB7Ci0JCQkvL2dldCB0aGUgZmlyc3QgY29tcG9uZW50J3Mgc3RhdGUKLQkJCXJldHVybiAoKFNlcnZpY2VDb21wb25lbnRQcm9wKSBjb21wb25lbnRQcm9wcy5lbGVtZW50QXQoMCkpLmdldFN0YXRlKCk7Ci0JCX0KLQkJLy9yZXR1cm4gdGhlIGN1cnJlbnQgc3RhdGUgb2YgdGhlIGNvbXBvbmVudAotCQlyZXR1cm4gc3RhdGU7Ci0JfQotCi0JcHVibGljIGJvb2xlYW4gaXNBY3RpdmF0ZURlY2xhcmVkKCkgewotCQlpZiAoIWlzTmFtZXNwYWNlQXRMZWFzdDExKCkpIHsKLQkJCXJldHVybiBmYWxzZTsKLQkJfQotCQlyZXR1cm4gYWN0aXZhdGVNZXRob2REZWNsYXJlZDsKLQl9Ci0KLQlwdWJsaWMgYm9vbGVhbiBpc0RlYWN0aXZhdGVEZWNsYXJlZCgpIHsKLQkJaWYgKCFpc05hbWVzcGFjZUF0TGVhc3QxMSgpKSB7Ci0JCQlyZXR1cm4gZmFsc2U7Ci0JCX0KLQkJcmV0dXJuIGRlYWN0aXZhdGVNZXRob2REZWNsYXJlZDsKLQl9Ci0KLQlwdWJsaWMgYm9vbGVhbiBpc0RlZmF1bHRFbmFibGVkKCkgewotCQlyZXR1cm4gYXV0b2VuYWJsZTsKLQl9Ci0KLQlwdWJsaWMgYm9vbGVhbiBpc1NlcnZpY2VGYWN0b3J5KCkgewotCQlyZXR1cm4gc2VydmljZUZhY3Rvcnk7Ci0JfQotCi0JcHVibGljIHZvaWQgc2V0U3RhdGUoaW50IG5ld1N0YXRlKSB7Ci0JCXN0YXRlID0gbmV3U3RhdGU7Ci0JfQotfQpcIE5vIG5ld2xpbmUgYXQgZW5kIG9mIGZpbGUKZGlmZiAtLWdpdCBhL2J1bmRsZXMvb3JnLmVjbGlwc2UuZXF1aW5veC5kcy9zcmMvb3JnL2VjbGlwc2UvZXF1aW5veC9pbnRlcm5hbC9kcy9tb2RlbC9TZXJ2aWNlQ29tcG9uZW50UHJvcC5qYXZhIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5lcXVpbm94LmRzL3NyYy9vcmcvZWNsaXBzZS9lcXVpbm94L2ludGVybmFsL2RzL21vZGVsL1NlcnZpY2VDb21wb25lbnRQcm9wLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDBkODg4ZDUuLjAwMDAwMDAKLS0tIGEvYnVuZGxlcy9vcmcuZWNsaXBzZS5lcXVpbm94LmRzL3NyYy9vcmcvZWNsaXBzZS9lcXVpbm94L2ludGVybmFsL2RzL21vZGVsL1NlcnZpY2VDb21wb25lbnRQcm9wLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw5MjggKzAsMCBAQAotLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKLSAqIENvcHlyaWdodCAoYykgMTk5Ny0yMDEyIGJ5IFByb1N5c3QgU29mdHdhcmUgR21iSAotICogaHR0cDovL3d3dy5wcm9zeXN0LmNvbQotICogQWxsIHJpZ2h0cyByZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscwotICogYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2MS4wCi0gKiB3aGljaCBhY2NvbXBhbmllcyB0aGlzIGRpc3RyaWJ1dGlvbiwgYW5kIGlzIGF2YWlsYWJsZSBhdAotICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtdjEwLmh0bWwKLSAqCi0gKiBDb250cmlidXRvcnM6Ci0gKiAgICBQcm9TeXN0IFNvZnR3YXJlIEdtYkggLSBpbml0aWFsIEFQSSBhbmQgaW1wbGVtZW50YXRpb24KLSAqICAgIEpvZXJnLUNocmlzdGlhbiBCb2VobWUgLSBidWcuaWQgPSAyNDY3NTcKLSAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwotcGFja2FnZSBvcmcuZWNsaXBzZS5lcXVpbm94LmludGVybmFsLmRzLm1vZGVsOwotCi1pbXBvcnQgamF2YS5zZWN1cml0eS4qOwotaW1wb3J0IGphdmEudXRpbC4qOwotaW1wb3J0IG9yZy5hcGFjaGUuZmVsaXguc2NyLkNvbXBvbmVudDsKLWltcG9ydCBvcmcuZWNsaXBzZS5lcXVpbm94LmludGVybmFsLmRzLio7Ci1pbXBvcnQgb3JnLmVjbGlwc2UuZXF1aW5veC5pbnRlcm5hbC5kcy5pbXBsLio7Ci1pbXBvcnQgb3JnLmVjbGlwc2Uub3NnaS51dGlsLk5MUzsKLWltcG9ydCBvcmcub3NnaS5mcmFtZXdvcmsuKjsKLWltcG9ydCBvcmcub3NnaS5zZXJ2aWNlLmNvbXBvbmVudC4qOwotaW1wb3J0IG9yZy5vc2dpLnNlcnZpY2UubG9nLkxvZ1NlcnZpY2U7Ci0KLS8qKgotICogVGhlIFNlcnZpY2VDb21wb25lbnRQcm9wIHJlcHJlc2VudHMgYSBTZXJ2aWNlQ29tcG9uZW50IG1hcHBlZCB0byBpdCdzIENNCi0gKiBwcm9wZXJ0aWVzLgotICogCi0gKiBXaGVuIHRoZSBTZXJ2aWNlQ29tcG9uZW50IGNvbnRhaW5zIHBsYWluIENNIHByb3BlcnRpZXMsIHRoZSBtYXBwaW5nIG9mCi0gKiBTZXJ2aWNlQ29tcG9uZW50UHJvcCB0byBTZXJ2aWNlQ29tcG9uZW50IGlzIDE6MS4KLSAqIAotICogSG93ZXZlciwgd2hlbiB0aGUgU2VydmljZUNvbXBvbmVudCBpcyBhIE1hbmFnZWRTZXJ2aWNlRmFjdG9yeSwgdGhlcmUgYXJlIHNvCi0gKiBtYW55IFNlcnZpY2VDb21wb25lbnRQcm9wIG9iamVjdHMgY3JlYXRlZCBhcyBtYW55IGFyZSB0aGUgY29uZmlndXJhdGlvbnMKLSAqIGFzc29jaWF0ZWQgd2l0aCB0aGUgY29tcG9uZW50LgotICogCi0gKiBAYXV0aG9yIFZhbGVudGluIFZhbGNoZXYKLSAqIEBhdXRob3IgU3RveWFuIEJvc2hldgotICogQGF1dGhvciBQYXZsaW4gRG9icmV2Ci0gKi8KLQotcHVibGljIGNsYXNzIFNlcnZpY2VDb21wb25lbnRQcm9wIGltcGxlbWVudHMgQ29tcG9uZW50LCBQcml2aWxlZ2VkRXhjZXB0aW9uQWN0aW9uIHsKLQotCXB1YmxpYyBTZXJ2aWNlUmVnaXN0cmF0aW9uIHJlZ2lzdHJhdGlvbjsKLQlwdWJsaWMgU3RyaW5nIG5hbWU7Ci0JcHVibGljIFNlcnZpY2VDb21wb25lbnQgc2VydmljZUNvbXBvbmVudDsKLQlwdWJsaWMgSGFzaHRhYmxlIHByb3BlcnRpZXM7Ci0JcHVibGljIFZlY3RvciBpbnN0YW5jZXMgPSBuZXcgVmVjdG9yKDIpOyAvLyBDb21wb25lbnRJbnN0YW5jZSBvYmplY3RzCi0JcHVibGljIEJ1bmRsZUNvbnRleHQgYmM7Ci0JcHVibGljIFZlY3RvciByZWZlcmVuY2VzOwotCi0JLy8gVGhpcyBmbGFnIGlzIHVzZWQgdG8gY2hlY2sgd2hldGhlciB0aGUgY29tcG9uZW50IGlzIGEgY29tcG9uZW50IGZhY3RvcnkuCi0JLy8gU2luY2UgdGhlIGNvbXBvbmVudCBmYWN0b3J5IGNyZWF0ZXMgbmV3IFNlcnZpY2VDb21wb25lbnRQcm9wIG9iamVjdHMgdGhleQotCS8vIGhhdmUgdG8KLQkvLyBiZSBtYXJrZWQgYXMgbm9uIGNvbXBvbmVudCBmYWN0b3J5IGNvbXBvbmVudHMgaW4gb3JkZXIgdG8gcHJldmVudCBuZXdseQotCS8vIHJlZ2lzdGVyZWQKLQkvLyBjb21wb25lbnQgZmFjdG9yaWVzIGFzIHNlcnZpY2VzLgotCXByb3RlY3RlZCBib29sZWFuIGlzQ29tcG9uZW50RmFjdG9yeSA9IGZhbHNlOwotCi0JLy9Ib2xkcyB0aGUgY29tcG9uZW50J3Mgc3RhdGUKLQlwcml2YXRlIGludCBzdGF0ZSA9IFNUQVRFX1VOU0FUSVNGSUVEOwotCi0JLyoqCi0JICogTGlzdCBvZiBuYW1lcyAoU3RyaW5ncykgb2YgQ29tcG9uZW50IENvbmZpZ3VyYXRpb25zIHdlIHNob3VsZCBub3QKLQkgKiBhY3RpdmF0ZSBkdXJpbmcgdGhlIGFjdGl2YXRpb24gb2YgdGhpcyBDb21wb25lbnQgQ29uZmlndXJhdGlvbi4gVGhpcyBpcwotCSAqIHBvcHVsYXRlZCBieSB0aGUge0BsaW5rIG9yZy5lY2xpcHNlLmVxdWlub3guaW50ZXJuYWwuZHMuUmVzb2x2ZXIgUmVzb2x2ZXJ9Ci0JICogYW5kIHVzZWQgYnkKLQkgKiB7QGxpbmsgb3JnLmVjbGlwc2UuZXF1aW5veC5pbnRlcm5hbC5kcy5JbnN0YW5jZVByb2Nlc3MgSW5zdGFuY2VQcm9jZXNzfS4KLQkgKi8KLQlwcm90ZWN0ZWQgVmVjdG9yIGRlbGF5QWN0aXZhdGVTQ1BOYW1lczsKLQotCXByaXZhdGUgU0NSTWFuYWdlciBtZ3I7Ci0JcHJpdmF0ZSBSZWFkT25seURpY3Rpb25hcnkgcmVhZE9ubHlQcm9wczsKLQotCS8vIG5leHQgZnJlZSBjb21wb25lbnQgaWQKLQlwcml2YXRlIHN0YXRpYyBsb25nIGNvbXBvbmVudGlkID0gMDsKLQotCXB1YmxpYyBTZXJ2aWNlQ29tcG9uZW50UHJvcChTZXJ2aWNlQ29tcG9uZW50IHNlcnZpY2VDb21wb25lbnQsIERpY3Rpb25hcnkgY29uZmlnUHJvcGVydGllcywgU0NSTWFuYWdlciBtZ3IpIHsKLQotCQl0aGlzLnNlcnZpY2VDb21wb25lbnQgPSBzZXJ2aWNlQ29tcG9uZW50OwotCQl0aGlzLm5hbWUgPSBzZXJ2aWNlQ29tcG9uZW50Lm5hbWU7Ci0JCXRoaXMuYmMgPSBzZXJ2aWNlQ29tcG9uZW50LmJjOwotCi0JCXByb3BlcnRpZXMgPSBpbml0UHJvcGVydGllcyhjb25maWdQcm9wZXJ0aWVzLCBudWxsKTsKLQotCQlpc0NvbXBvbmVudEZhY3RvcnkgPSBzZXJ2aWNlQ29tcG9uZW50LmZhY3RvcnkgIT0gbnVsbDsKLQotCQkvLyB1c2VkIGZvciBjb21wb25lbnQgY29udGV4dAotCQl0aGlzLm1nciA9IG1ncjsKLQl9Ci0KLQkvKioKLQkgKiBUaGlzIG1ldGhvZCB3aWxsIGRpc3Bvc2UgdGhlIHNlcnZpY2UgY29tcG9uZW50IGluc3RhbmNlLiBBbG9uZyB3aXRoIHRoZQotCSAqIHNlcnZpY2UgY29tcG9uZW50IGl0c2VsZiBhbmQgdGhlIHByb3BlcnRpZXMgZmlsZXMuCi0JICovCi0JcHVibGljIHZvaWQgZGlzcG9zZShpbnQgZGVhY3RpdmF0ZVJlYXNvbikgewotCQlpZiAoQWN0aXZhdG9yLkRFQlVHKSB7Ci0JCQlBY3RpdmF0b3IubG9nLmRlYnVnKCJTZXJ2aWNlQ29tcG9uZW50UHJvcC5kaXNwb3NlKCk6ICIgKyBuYW1lLCBudWxsKTsgLy8kTk9OLU5MUy0xJAotCQl9Ci0JCXRyeSB7Ci0JCQl3aGlsZSAoIWluc3RhbmNlcy5pc0VtcHR5KCkpIHsKLQkJCQlDb21wb25lbnRJbnN0YW5jZUltcGwgY3VycmVudCA9IChDb21wb25lbnRJbnN0YW5jZUltcGwpIGluc3RhbmNlcy5maXJzdEVsZW1lbnQoKTsKLQkJCQlkaXNwb3NlKGN1cnJlbnQsIGRlYWN0aXZhdGVSZWFzb24pOwotCQkJCWN1cnJlbnQuZGlzcG9zZSgpOwotCQkJfQotCQl9IGZpbmFsbHkgewotCQkJc2V0U3RhdGUoU1RBVEVfVU5TQVRJU0ZJRUQpOwotCQl9Ci0JfQotCi0JLyoqCi0JICogZ2V0UHJvcGVydGllcwotCSAqIAotCSAqIEByZXR1cm4gRGljdGlvbmFyeSBwcm9wZXJ0aWVzCi0JICovCi0JcHVibGljIERpY3Rpb25hcnkgZ2V0UHJvcGVydGllcygpIHsKLQkJaWYgKHJlYWRPbmx5UHJvcHMgPT0gbnVsbCkgewotCQkJcmVhZE9ubHlQcm9wcyA9IG5ldyBSZWFkT25seURpY3Rpb25hcnkocHJvcGVydGllcyAhPSBudWxsID8gcHJvcGVydGllcyA6IHNlcnZpY2VDb21wb25lbnQucHJvcGVydGllcyk7Ci0JCX0gZWxzZSB7Ci0JCQkvLyB0aGUgc2NwIHByb3BlcnRpZXMgbWF5IGhhdmUgYmVlbiBtb2RpZmllZCBieSBjb25maWd1cmF0aW9uCi0JCQkvLyB1cGRhdGUgdGhlIGluc3RhbmNlIHdpdGggdGhlIGN1cnJlbnQgcHJvcGVydGllcwotCQkJcmVhZE9ubHlQcm9wcy51cGRhdGVEZWxlZ2F0ZShwcm9wZXJ0aWVzICE9IG51bGwgPyBwcm9wZXJ0aWVzIDogc2VydmljZUNvbXBvbmVudC5wcm9wZXJ0aWVzKTsKLQkJfQotCQlyZXR1cm4gcmVhZE9ubHlQcm9wczsKLQl9Ci0KLQkvKioKLQkgKiBUaGlzIG1ldGhvZCB3aWxsIGNhbGwgdGhlIGFjdGl2YXRlIG1ldGhvZCBvbiB0aGUgc3BlY2lmaWVkIG9iamVjdC4KLQkgKiAKLQkgKiBAcGFyYW0gdXNpbmdCdW5kbGUKLQkgKiAgICAgICAgICAgIHRoZSBidW5kbGUgdGhhdCBpcyB1c2luZyB0aGUgY29tcG9uZW50IC0gdGhpcyBoYXMgb25seSBtZWFucwotCSAqICAgICAgICAgICAgd2hlbiB0aGUgY29tcG9uZW50IGlzIGZhY3RvcnkKLQkgKiBAcGFyYW0gY29tcG9uZW50SW5zdGFuY2UKLQkgKiAgICAgICAgICAgIHRoZSBjb21wb25lbnQgaW5zdGFuY2Ugd2hpY2ggd2lsbCBiZSBhY3RpdmF0ZWQuCi0JICogQHRocm93cyBFeGNlcHRpb24KLQkgKiAgICAgICAgICAgICBjb3VsZCBiZSB0aHJvd24gaWYgdGhlIGFjdGl2YXRlIGZhaWxzIGZvciBzb21lIHJlYXNvbiBidXQgTk9UCi0JICogICAgICAgICAgICAgaW4gY2FzZSwgaWYgdGhlIGluc3RhbmNlIGRvZXNuJ3QgZGVmaW5lIGFuIGFjdGl2YXRlIG1ldGhvZC4KLQkgKi8KLQlwdWJsaWMgdm9pZCBhY3RpdmF0ZShCdW5kbGUgdXNpbmdCdW5kbGUsIENvbXBvbmVudEluc3RhbmNlSW1wbCBjb21wb25lbnRJbnN0YW5jZSkgdGhyb3dzIEV4Y2VwdGlvbiB7Ci0JCWlmIChBY3RpdmF0b3IuREVCVUcpIHsKLQkJCUFjdGl2YXRvci5sb2cuZGVidWcoIn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+U2VydmljZUNvbXBvbmVudFByb3AuYWN0aXZhdGUoKTogbmFtZTogIiArIG5hbWUsIG51bGwpOyAvLyROT04tTkxTLTEkCi0JCQlBY3RpdmF0b3IubG9nLmRlYnVnKCJ+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+flNlcnZpY2VDb21wb25lbnRQcm9wLmFjdGl2YXRlKCk6IHVzaW5nIGJ1bmRsZTogIiArICh1c2luZ0J1bmRsZSAhPSBudWxsID8gdXNpbmdCdW5kbGUuZ2V0U3ltYm9saWNOYW1lKCkgOiBudWxsKSwgbnVsbCk7IC8vJE5PTi1OTFMtMSQKLQkJCUFjdGl2YXRvci5sb2cuZGVidWcoIn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+U2VydmljZUNvbXBvbmVudFByb3AuYWN0aXZhdGUoKTogaW5zdGFuY2U6ICIgKyBjb21wb25lbnRJbnN0YW5jZS50b1N0cmluZygpLCBudWxsKTsgLy8kTk9OLU5MUy0xJAotCQl9Ci0KLQkJLy8gY2FsbCB0aGUgYWN0aXZhdGUgbWV0aG9kIG9uIHRoZSBTZXJ2aWNlIENvbXBvbmVudAotCQlzZXJ2aWNlQ29tcG9uZW50LmFjdGl2YXRlKGNvbXBvbmVudEluc3RhbmNlLmdldEluc3RhbmNlKCksIGNvbXBvbmVudEluc3RhbmNlLmdldENvbXBvbmVudENvbnRleHQoKSk7Ci0JfQotCi0JLyoqCi0JICogVGhpcyBtZXRob2Qgd2lsbCBjYWxsIHRoZSBkZWFjdGl2YXRlIG1ldGhvZCBvbiB0aGUgc3BlY2lmaWVkIE9iamVjdC4KLQkgKiBOb3RpY2UsIHRoYXQgdGhpcyBpcyBub3QgdGhlIENvbXBvbmVudEluc3RhbmNlIG9iamVjdCwgYnV0IHRoZSByZWFsCi0JICogaW5zdGFuY2UuCi0JICogCi0JICogQHBhcmFtIGNvbXBvbmVudEluc3RhbmNlCi0JICogICAgICAgICAgICBjb21wb25lbnQgaW5zdGFuY2Ugd3JhcHBlcgotCSAqLwotCXByaXZhdGUgdm9pZCBkZWFjdGl2YXRlKENvbXBvbmVudEluc3RhbmNlSW1wbCBjb21wb25lbnRJbnN0YW5jZSwgaW50IGRlYWN0aXZhdGVSZWFzb24pIHsKLQkJaWYgKEFjdGl2YXRvci5ERUJVRykgewotCQkJQWN0aXZhdG9yLmxvZy5kZWJ1ZygiU2VydmljZUNvbXBvbmVudFByb3AuZGVhY3RpdmF0ZSgpOiAiICsgbmFtZSwgbnVsbCk7IC8vJE5PTi1OTFMtMSQKLQkJfQotCQlzZXJ2aWNlQ29tcG9uZW50LmRlYWN0aXZhdGUoY29tcG9uZW50SW5zdGFuY2UuZ2V0SW5zdGFuY2UoKSwgY29tcG9uZW50SW5zdGFuY2UuZ2V0Q29tcG9uZW50Q29udGV4dCgpLCBkZWFjdGl2YXRlUmVhc29uKTsKLQl9Ci0KLQkvKioKLQkgKiBUaGlzIG1ldGhvZCB3aWxsIHVwZGF0ZSB0aGUgcHJvcGVydGllcyBvZiB0aGUgY29tcG9uZW50Ci0JICogCi0JICogQHBhcmFtIG5ld1Byb3BzCi0JICogICAgICAgICAgICB0aGUgbmV3IHByb3BlcnRpZXMKLQkgKiBAdGhyb3dzIEV4Y2VwdGlvbgotCSAqICAgICAgICAgICAgIGNvdWxkIGJlIHRocm93biBpZiB0aGUgbW9kaWZ5IG1ldGhvZCBmYWlscyBmb3Igc29tZSByZWFzb24gYnV0IE5PVAotCSAqICAgICAgICAgICAgIGluIGNhc2UsIGlmIHRoZSBpbnN0YW5jZSBkb2Vzbid0IGRlZmluZSBtb2RpZnkgbWV0aG9kCi0JICovCi0JcHVibGljIHZvaWQgbW9kaWZ5KERpY3Rpb25hcnkgbmV3UHJvcHMpIHRocm93cyBFeGNlcHRpb24gewotCQlpZiAoQWN0aXZhdG9yLkRFQlVHKSB7Ci0JCQlBY3RpdmF0b3IubG9nLmRlYnVnKCJ+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+flNlcnZpY2VDb21wb25lbnRQcm9wLm1vZGlmeSgpOiBuYW1lOiAiICsgbmFtZSwgbnVsbCk7IC8vJE5PTi1OTFMtMSQKLQkJfQotCQlIYXNodGFibGUgb2xkUHJvcGVydGllcyA9IG51bGw7Ci0JCWlmIChyZWZlcmVuY2VzICE9IG51bGwgJiYgcmVmZXJlbmNlcy5zaXplKCkgPiAwKSB7Ci0JCQlvbGRQcm9wZXJ0aWVzID0gKEhhc2h0YWJsZSkgcHJvcGVydGllcy5jbG9uZSgpOwotCQl9Ci0JCS8vMS4gdXBkYXRlIHRoZSBwcm9wZXJ0aWVzCi0JCXByb3BlcnRpZXMgPSBpbml0UHJvcGVydGllcyhuZXdQcm9wcywgKExvbmcpIHByb3BlcnRpZXMuZ2V0KENvbXBvbmVudENvbnN0YW50cy5DT01QT05FTlRfSUQpKTsKLQkJLy8yLiBjYWxsIHRoZSBtb2RpZnkgbWV0aG9kIG9uIHRoZSBTZXJ2aWNlIENvbXBvbmVudCBmb3IgYWxsIGluc3RhbmNlcyBvZiB0aGlzIHNjcAotCQlmb3IgKGludCBpID0gMDsgaSA8IGluc3RhbmNlcy5zaXplKCk7IGkrKykgewotCQkJQ29tcG9uZW50SW5zdGFuY2VJbXBsIGNvbXBvbmVudEluc3RhbmNlID0gKENvbXBvbmVudEluc3RhbmNlSW1wbCkgaW5zdGFuY2VzLmVsZW1lbnRBdChpKTsKLQkJCUFjdGl2YXRvci5sb2cuZGVidWcoIn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+U2VydmljZUNvbXBvbmVudFByb3AubW9kaWZ5KCk6IGluc3RhbmNlOiAiICsgY29tcG9uZW50SW5zdGFuY2UudG9TdHJpbmcoKSwgbnVsbCk7IC8vJE5PTi1OTFMtMSQKLQkJCXNlcnZpY2VDb21wb25lbnQubW9kaWZpZWQoY29tcG9uZW50SW5zdGFuY2UuZ2V0SW5zdGFuY2UoKSwgY29tcG9uZW50SW5zdGFuY2UuZ2V0Q29tcG9uZW50Q29udGV4dCgpKTsKLQkJfQotCQkvLzMuIG1vZGlmeSB0aGUgYm91bmQgc2VydmljZXMgaWYgbmVjZXNzYXJ5Ci0JCWlmIChvbGRQcm9wZXJ0aWVzICE9IG51bGwpIHsKLQkJCWhhbmRsZUJvdW5kU2VydmljZXNVcGRhdGUob2xkUHJvcGVydGllcywgcHJvcGVydGllcyk7Ci0JCX0KLQotCQkvLzQuIGlmIHRoZSBjb21wb25lbnQgY29uZmlndXJhdGlvbiBpcyByZWdpc3RlcmVkIGFzIGEgc2VydmljZSwgCi0JCS8vIG1vZGlmeSB0aGUgc2VydmljZZJzIHNlcnZpY2UgcHJvcGVydGllcyAKLQkJaWYgKHJlZ2lzdHJhdGlvbiAhPSBudWxsKSB7Ci0JCQlyZWdpc3RyYXRpb24uc2V0UHJvcGVydGllcyhnZXRQdWJsaWNTZXJ2aWNlUHJvcGVydGllcygpKTsKLQkJfQotCX0KLQotCS8qKgotCSAqIENhbGwgdGhlIGJpbmQgbWV0aG9kIGZvciBlYWNoIG9mIHRoZSBSZWZlcmVuY2VkIFNlcnZpY2VzIGluIHRoaXMgU2VydmljZQotCSAqIENvbXBvbmVudAotCSAqIAotCSAqIEBwYXJhbSBjb21wb25lbnRJbnN0YW5jZQotCSAqIEByZXR1cm4gdHJ1ZSBpZiBhbGwgbWFuZGF0b3J5IHJlZmVyZW5jZXMgYXJlIGJvdW5kCi0JICogQHRocm93cyBFeGNlcHRpb24KLQkgKi8KLQlwdWJsaWMgYm9vbGVhbiBiaW5kKENvbXBvbmVudEluc3RhbmNlIGNvbXBvbmVudEluc3RhbmNlKSB0aHJvd3MgRXhjZXB0aW9uIHsKLQkJLy8gR2V0IGFsbCB0aGUgcmVxdWlyZWQgc2VydmljZSBSZWZlcmVuY2UgRGVzY3JpcHRpb25zIGZvciB0aGlzIFNlcnZpY2VDb21wb25lbnQKLQkJLy8gY2FsbCB0aGUgQmluZCBtZXRob2QgaWYgdGhlIFJlZmVyZW5jZSBEZXNjcmlwdGlvbiBpbmNsdWRlcyBvbmUKLQkJaWYgKHJlZmVyZW5jZXMgIT0gbnVsbCkgewotCQkJZm9yIChpbnQgaSA9IDA7IGkgPCByZWZlcmVuY2VzLnNpemUoKTsgaSsrKSB7Ci0JCQkJUmVmZXJlbmNlIHJlZiA9IChSZWZlcmVuY2UpIHJlZmVyZW5jZXMuZWxlbWVudEF0KGkpOwotCQkJCUNsYXNzQ2lyY3VsYXJpdHlFcnJvciBjY0Vycm9yID0gbnVsbDsKLQkJCQlpZiAocmVmLnJlZmVyZW5jZS5iaW5kICE9IG51bGwpIHsKLQkJCQkJdHJ5IHsKLQkJCQkJCWJpbmRSZWZlcmVuY2UocmVmLCBjb21wb25lbnRJbnN0YW5jZSk7Ci0JCQkJCX0gY2F0Y2ggKENsYXNzQ2lyY3VsYXJpdHlFcnJvciBjY2UpIHsKLQkJCQkJCWNjRXJyb3IgPSBjY2U7Ci0JCQkJCQlBY3RpdmF0b3IubG9nKGJjLCBMb2dTZXJ2aWNlLkxPR19FUlJPUiwgTkxTLmJpbmQoTWVzc2FnZXMuRVJST1JfQklORElOR19SRUZFUkVOQ0UsIHJlZi5yZWZlcmVuY2UpLCBjY2UpOwotCQkJCQl9Ci0JCQkJCWlmIChyZWYucmVmZXJlbmNlLmJpbmRNZXRob2QgPT0gbnVsbCB8fCBjY0Vycm9yICE9IG51bGwgfHwgIXJlZi5pc0JvdW5kKCkpIHsKLQkJCQkJCS8vdGhlIGJpbmQgbWV0aG9kIGlzIG5vdCBmb3VuZCBhbmQgY2FsbGVkIGZvciBzb21lIHJlYXNvbiBvciBpdCBoYXMgdGhyb3duIGV4Y2VwdGlvbgotCQkJCQkJQWN0aXZhdG9yLmxvZyhudWxsLCByZWYuaXNPcHRpb25hbCgpID8gTG9nU2VydmljZS5MT0dfREVCVUcgOiBMb2dTZXJ2aWNlLkxPR19FUlJPUiwgIkNvdWxkIG5vdCBiaW5kIGEgcmVmZXJlbmNlIG9mIGNvbXBvbmVudCAiICsgbmFtZSArICIuIFRoZSByZWZlcmVuY2UgaXM6ICIgKyByZWYucmVmZXJlbmNlLCBudWxsKTsgLy8kTk9OLU5MUy0xJCAvLyROT04tTkxTLTIkCi0JCQkJCQlpZiAoY2NFcnJvciAhPSBudWxsKSB7Ci0JCQkJCQkJLy91bmJpbmQgdGhlIGFscmVhZHkgYm91bmQgcmVmZXJlbmNlcwotCQkJCQkJCWZvciAoaW50IGogPSBpIC0gMTsgaiA+PSAwOyBqLS0pIHsKLQkJCQkJCQkJcmVmID0gKFJlZmVyZW5jZSkgcmVmZXJlbmNlcy5lbGVtZW50QXQoaik7Ci0JCQkJCQkJCWlmIChyZWYucmVmZXJlbmNlLnVuYmluZCAhPSBudWxsKSB7Ci0JCQkJCQkJCQl1bmJpbmRSZWZlcmVuY2UocmVmLCBjb21wb25lbnRJbnN0YW5jZSk7Ci0JCQkJCQkJCX0KLQkJCQkJCQl9Ci0JCQkJCQkJLy9yZXRocm93IHRoZSBlcnJvciBzbyBpdCBpcyBmdXJ0aGVyIHByb2Nlc3NlZCBhY2NvcmRpbmcgdG8gdGhlIHVzZSBjYXNlCi0JCQkJCQkJdGhyb3cgY2NFcnJvcjsKLQkJCQkJCX0KLQkJCQkJCS8vIGNvbnRpbnVlIG5ldmVydGhlbGVzcyB0aGUgYmluZCBpcyB1bnN1Y2Nlc3NmdWwgLSBzZWUgYnVnIDM4ODk2MQotCQkJCQl9Ci0JCQkJfSBlbHNlIHsKLQkJCQkJaWYgKEFjdGl2YXRvci5ERUJVRykgewotCQkJCQkJQWN0aXZhdG9yLmxvZy5kZWJ1ZygiU2VydmljZUNvbXBvbmVudFByb3AuYmluZCgpOiB0aGUgZm9sb3dpbmcgcmVmZXJlbmNlIGRvZXNuJ3Qgc3BlY2lmeSBiaW5kIG1ldGhvZDogIiArIHJlZi5yZWZlcmVuY2UubmFtZSwgbnVsbCk7IC8vJE5PTi1OTFMtMSQKLQkJCQkJfQotCQkJCX0KLQkJCX0KLQkJfQotCQlyZXR1cm4gdHJ1ZTsKLQl9Ci0KLQkvKioKLQkgKiBDYWxsIHRoZSB1bmJpbmQgbWV0aG9kIGZvciBlYWNoIG9mIHRoZSBSZWZlcmVuY2VkIFNlcnZpY2VzIGluIHRoaXMKLQkgKiBTZXJpdmNlIENvbXBvbmVudAotCSAqIAotCSAqIEBwYXJhbSBjb21wb25lbnRJbnN0YW5jZQotCSAqICAgICAgICAgICAgdGhlIG9iamVjdCB3aGljaCB1bmJpbmQgbWV0aG9kKHMpIHdpbGwgYmUgY2FsbGVkLCBpZiBBTlkhCi0JICovCi0JcHVibGljIHZvaWQgdW5iaW5kKENvbXBvbmVudEluc3RhbmNlIGNvbXBvbmVudEluc3RhbmNlKSB7Ci0JCS8vIGNhbGwgdGhlIHVuQmluZCBtZXRob2QgaWYgdGhlIFJlZmVyZW5jZSBEZXNjcmlwdGlvbiBpbmNsdWRlcyBvbmUKLQkJaWYgKHJlZmVyZW5jZXMgIT0gbnVsbCkgewotCQkJZm9yIChpbnQgaSA9IHJlZmVyZW5jZXMuc2l6ZSgpIC0gMTsgaSA+PSAwOyBpLS0pIHsKLQkJCQlSZWZlcmVuY2UgcmVmID0gKFJlZmVyZW5jZSkgcmVmZXJlbmNlcy5lbGVtZW50QXQoaSk7Ci0JCQkJaWYgKHJlZi5yZWZlcmVuY2UudW5iaW5kICE9IG51bGwpIHsKLQkJCQkJdW5iaW5kUmVmZXJlbmNlKHJlZiwgY29tcG9uZW50SW5zdGFuY2UpOwotCQkJCX0KLQkJCX0KLQkJfQotCX0KLQotCXB1YmxpYyBPYmplY3QgY3JlYXRlSW5zdGFuY2UoKSB0aHJvd3MgRXhjZXB0aW9uIHsKLQkJYXNzZXJ0Q3JlYXRlU2luZ2xlSW5zdGFuY2UoKTsKLQkJcmV0dXJuIHNlcnZpY2VDb21wb25lbnQuY3JlYXRlSW5zdGFuY2UoKTsKLQl9Ci0KLQlib29sZWFuIGxvY2tlZCA9IGZhbHNlOwotCWludCB3YWl0aW5nID0gMDsKLQotCUJ1bmRsZSBidW5kbGU7Ci0JT2JqZWN0IGluc3Q7Ci0KLQlzeW5jaHJvbml6ZWQgdm9pZCBsb2NrKEJ1bmRsZSB1c2luZ0J1bmRsZSwgT2JqZWN0IGluc3RhbmNlKSB7Ci0JCXdoaWxlIChsb2NrZWQpIHsKLQkJCXRyeSB7Ci0JCQkJd2FpdGluZysrOwotCQkJCXdhaXQoKTsKLQkJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBfKSB7Ci0JCQkJLy8KLQkJCX0KLQkJCXdhaXRpbmctLTsKLQkJfQotCQlsb2NrZWQgPSB0cnVlOwotCQlidW5kbGUgPSB1c2luZ0J1bmRsZTsKLQkJaW5zdCA9IGluc3RhbmNlOwotCX0KLQotCXN5bmNocm9uaXplZCB2b2lkIHVubG9jaygpIHsKLQkJbG9ja2VkID0gZmFsc2U7Ci0JCWJ1bmRsZSA9IG51bGw7Ci0JCWluc3QgPSBudWxsOwotCQlpZiAod2FpdGluZyA+IDApCi0JCQlub3RpZnlBbGwoKTsKLQl9Ci0KLQlwdWJsaWMgT2JqZWN0IHJ1bigpIHRocm93cyBFeGNlcHRpb24gewotCQlCdW5kbGUgYiA9IHRoaXMuYnVuZGxlOwotCQlPYmplY3QgaW5zdGFuY2UgPSBpbnN0OwotCQl1bmxvY2soKTsKLQkJcmV0dXJuIGJ1aWxkKGIsIGluc3RhbmNlLCBmYWxzZSk7Ci0JfQotCi0JcHVibGljIENvbXBvbmVudEluc3RhbmNlSW1wbCBidWlsZChCdW5kbGUgdXNpbmdCdW5kbGUsIE9iamVjdCBpbnN0YW5jZSwgYm9vbGVhbiBzZWN1cml0eSkgdGhyb3dzIEV4Y2VwdGlvbiB7Ci0JCWlmIChnZXRTdGF0ZSgpID09IFNUQVRFX0RJU1BPU0VEKSB7Ci0JCQlpZiAoQWN0aXZhdG9yLkRFQlVHKSB7Ci0JCQkJQWN0aXZhdG9yLmxvZy5kZWJ1ZygiQ2Fubm90IGJ1aWxkIGNvbXBvbmVudCwgYmVjYXVzZSBpdCBpcyBhbHJlYWR5IGRpc3Bvc2VkOiAiICsgdGhpcywgbnVsbCk7IC8vJE5PTi1OTFMtMSQKLQkJCX0KLQkJCXJldHVybiBudWxsOwotCQl9Ci0KLQkJaWYgKHNlY3VyaXR5KSB7Ci0JCQl0aGlzLmxvY2sodXNpbmdCdW5kbGUsIGluc3RhbmNlKTsKLQkJCXRyeSB7Ci0JCQkJcmV0dXJuIChDb21wb25lbnRJbnN0YW5jZUltcGwpIEFjY2Vzc0NvbnRyb2xsZXIuZG9Qcml2aWxlZ2VkKHRoaXMpOwotCQkJfSBjYXRjaCAoUHJpdmlsZWdlZEFjdGlvbkV4Y2VwdGlvbiBwYWUpIHsKLQkJCQkvLwotCQkJfQotCQl9Ci0JCUNvbXBvbmVudEluc3RhbmNlSW1wbCBjb21wb25lbnRJbnN0YW5jZSA9IG51bGw7Ci0JCWlmIChpbnN0YW5jZSA9PSBudWxsKSB7Ci0JCQlpZiAoIXNlcnZpY2VDb21wb25lbnQuc2VydmljZUZhY3RvcnkpIHsKLQkJCQkvLyBpdCBpcyBhIHBsYWluIHNlcnZpY2UsIHRoaXMgaXMgYmVjYXVzZSB0aGlzIG1ldGhvZAotCQkJCS8vIGlzIGFsc28gY2FsbGVkIGZyb20gU2VydmljZVJlZwotCQkJCWlmIChpbnN0YW5jZXMuaXNFbXB0eSgpKSB7Ci0JCQkJCWluc3RhbmNlID0gY3JlYXRlSW5zdGFuY2UoKTsKLQkJCQl9IGVsc2UgewotCQkJCQljb21wb25lbnRJbnN0YW5jZSA9IChDb21wb25lbnRJbnN0YW5jZUltcGwpIGluc3RhbmNlcy5maXJzdEVsZW1lbnQoKTsKLQkJCQl9Ci0JCQl9IGVsc2UgewotCQkJCWluc3RhbmNlID0gY3JlYXRlSW5zdGFuY2UoKTsKLQkJCX0KLQkJfQotCQlpZiAoY29tcG9uZW50SW5zdGFuY2UgPT0gbnVsbCkgewotCQkJY29tcG9uZW50SW5zdGFuY2UgPSBuZXcgQ29tcG9uZW50SW5zdGFuY2VJbXBsKGluc3RhbmNlLCB0aGlzKTsKLQkJCWNvbXBvbmVudEluc3RhbmNlLnNldENvbXBvbmVudENvbnRleHQobmV3IENvbXBvbmVudENvbnRleHRJbXBsKHRoaXMsIHVzaW5nQnVuZGxlLCBjb21wb25lbnRJbnN0YW5jZSwgbWdyKSk7Ci0JCQlpbnN0YW5jZXMuYWRkRWxlbWVudChjb21wb25lbnRJbnN0YW5jZSk7Ci0JCQlpZiAoYmluZChjb21wb25lbnRJbnN0YW5jZSkpIHsKLQkJCQl0cnkgewotCQkJCQlhY3RpdmF0ZSh1c2luZ0J1bmRsZSwgY29tcG9uZW50SW5zdGFuY2UpOwotCQkJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7Ci0JCQkJCS8vbXVzdCB1bmJpbmQgYW5kIGRpc3Bvc2UgdGhpcyBjb21wb25lbnQgaW5zdGFuY2UgCi0JCQkJCUluc3RhbmNlUHJvY2Vzcy5yZXNvbHZlci5yZW1vdmVGcm9tU2F0aXNmaWVkTGlzdCh0aGlzKTsKLQkJCQkJaWYgKGluc3RhbmNlcy5yZW1vdmVFbGVtZW50KGNvbXBvbmVudEluc3RhbmNlKSkgewotCQkJCQkJdW5iaW5kKGNvbXBvbmVudEluc3RhbmNlKTsKLQkJCQkJfQotCQkJCQl0aHJvdyBlOwotCQkJCX0KLQkJCX0gZWxzZSB7Ci0JCQkJLy9tdXN0IHJlbW92ZSBmcm9tIHNhdGlzZmllZCBsaXN0IGFuZCByZW1vdmUgdGhlIGluc3RhbmNlCi0JCQkJSW5zdGFuY2VQcm9jZXNzLnJlc29sdmVyLnJlbW92ZUZyb21TYXRpc2ZpZWRMaXN0KHRoaXMpOwotCQkJCWluc3RhbmNlcy5yZW1vdmVFbGVtZW50KGNvbXBvbmVudEluc3RhbmNlKTsKLQkJCQl0aHJvdyBuZXcgQ29tcG9uZW50RXhjZXB0aW9uKE5MUy5iaW5kKE1lc3NhZ2VzLkNPTVBPTkVOVF9XQVNfTk9UX0JVSUxULCBzZXJ2aWNlQ29tcG9uZW50KSk7Ci0JCQl9Ci0JCX0KLQkJc2V0U3RhdGUoQ29tcG9uZW50LlNUQVRFX0FDVElWRSk7Ci0JCXJldHVybiBjb21wb25lbnRJbnN0YW5jZTsKLQl9Ci0KLQlwdWJsaWMgdm9pZCBkaXNwb3NlT2JqKE9iamVjdCBvYmosIGludCBkZWFjdGl2YXRlUmVhc29uKSB7Ci0JCUNvbXBvbmVudEluc3RhbmNlSW1wbCBjaSA9IG51bGw7Ci0JCXN5bmNocm9uaXplZCAoaW5zdGFuY2VzKSB7Ci0JCQlmb3IgKGludCBpID0gMDsgaSA8IGluc3RhbmNlcy5zaXplKCk7IGkrKykgewotCQkJCWNpID0gKENvbXBvbmVudEluc3RhbmNlSW1wbCkgaW5zdGFuY2VzLmVsZW1lbnRBdChpKTsKLQkJCQlpZiAoY2kuZ2V0SW5zdGFuY2UoKSA9PSBvYmopIHsKLQkJCQkJYnJlYWs7Ci0JCQkJfQotCQkJCWNpID0gbnVsbDsKLQkJCX0KLQkJfQotCQlpZiAoY2kgIT0gbnVsbCkgewotCQkJZGlzcG9zZShjaSwgZGVhY3RpdmF0ZVJlYXNvbik7Ci0JCQlyZXR1cm47Ci0JCX0KLQkJdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oTkxTLmJpbmQoTWVzc2FnZXMuSU5WQUxJRF9PQkpFQ1QsIG9iaiwgbmFtZSkpOwotCX0KLQotCXB1YmxpYyB2b2lkIGRpc3Bvc2UoQ29tcG9uZW50SW5zdGFuY2VJbXBsIGNvbXBvbmVudEluc3RhbmNlLCBpbnQgZGVhY3RpdmF0ZVJlYXNvbikgewotCQlpZiAoIWluc3RhbmNlcy5yZW1vdmVFbGVtZW50KGNvbXBvbmVudEluc3RhbmNlKSkgewotCQkJcmV0dXJuOyAvL3RoZSBpbnN0YW5jZSBpcyBhbHJlYWR5IGRpc3Bvc2VkICAKLQkJfQotCQlkZWFjdGl2YXRlKGNvbXBvbmVudEluc3RhbmNlLCBkZWFjdGl2YXRlUmVhc29uKTsKLQkJdW5iaW5kKGNvbXBvbmVudEluc3RhbmNlKTsKLQkJaWYgKGluc3RhbmNlcy5pc0VtcHR5KCkpIHsKLQkJCS8vdGhlcmUgYXJlIG5vIGFjdGl2ZSBpbnN0YW5jZXMuIFRoZSBjb21wb25lbnQgaXMgbGF6eSBlbmFibGVkIG5vdwotCQkJc2V0U3RhdGUoQ29tcG9uZW50LlNUQVRFX1JFR0lTVEVSRUQpOwotCQl9Ci0JfQotCi0JLyoqCi0JICogQ2FsbCB0aGUgYmluZCBtZXRob2QgZm9yIHRoaXMgcmVmZXJlbmNlRGVzY3JpcHRpb24KLQkgKiAKLQkgKiBAcGFyYW0gY29tcG9uZW50UmVmZXJlbmNlCi0JICogQHBhcmFtIGNvbXBvbmVudEluc3RhbmNlCi0JICogQHRocm93cyBFeGNlcHRpb24KLQkgKiAKLQkgKi8KLQlwdWJsaWMgdm9pZCBiaW5kUmVmZXJlbmNlKFJlZmVyZW5jZSByZWZlcmVuY2UsIENvbXBvbmVudEluc3RhbmNlIGNvbXBvbmVudEluc3RhbmNlKSB0aHJvd3MgRXhjZXB0aW9uIHsKLQotCQlpZiAoQWN0aXZhdG9yLkRFQlVHKSB7Ci0JCQlBY3RpdmF0b3IubG9nLmRlYnVnKCJTZXJ2aWNlQ29tcG9uZW50UHJvcC5iaW5kUmVmZXJlbmNlKCk6IGNvbXBvbmVudCAiICsgc2VydmljZUNvbXBvbmVudC5uYW1lICsgIiAtPiAiICsgcmVmZXJlbmNlLnJlZmVyZW5jZSwgbnVsbCk7IC8vJE5PTi1OTFMtMSQgLy8kTk9OLU5MUy0yJAotCQl9Ci0KLQkJU2VydmljZVJlZmVyZW5jZVtdIHNlcnZpY2VSZWZlcmVuY2VzID0gbnVsbDsKLQotCQkvLyBpZiB0aGVyZSBpcyBhIHB1Ymxpc2hlZCBzZXJ2aWNlLCB0aGVuIGdldCB0aGUgU2VydmljZU9iamVjdCBhbmQgY2FsbCBiaW5kCi0JCXRyeSB7Ci0JCQkvLyBnZXQgYWxsIHJlZ2lzdGVyZWQgc2VydmljZXMgdXNpbmcgdGhpcyB0YXJnZXQgZmlsdGVyCi0JCQlzZXJ2aWNlUmVmZXJlbmNlcyA9IGJjLmdldFNlcnZpY2VSZWZlcmVuY2VzKHJlZmVyZW5jZS5yZWZlcmVuY2UuaW50ZXJmYWNlTmFtZSwgcmVmZXJlbmNlLmdldFRhcmdldCgpKTsKLQkJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKLQkJCUFjdGl2YXRvci5sb2coYmMsIExvZ1NlcnZpY2UuTE9HX0VSUk9SLCBOTFMuYmluZChNZXNzYWdlcy5DQU5OT1RfR0VUX1JFRkVSRU5DRVMsIHJlZmVyZW5jZS5yZWZlcmVuY2UuaW50ZXJmYWNlTmFtZSksIGUpOwotCQkJdGhyb3cgZTsKLQkJCS8vIHJldGhyb3cgZXhjZXB0aW9uIHNvIHJlc29sdmVyIGlzIGV2ZW50dWFsbHkgbm90aWZpZWQgdGhhdCB0aGlzIFNDUCBpcyBiYWQKLQkJfQotCi0JCS8vIGJpbmQgb25seSBpZiB0aGVyZSBpcyBhdCBsZWFzdCBPTkUgc2VydmljZQotCQlpZiAoc2VydmljZVJlZmVyZW5jZXMgIT0gbnVsbCAmJiBzZXJ2aWNlUmVmZXJlbmNlcy5sZW5ndGggPiAwKSB7Ci0JCQkvLyB0aGUgY29tcG9uZW50IGJpbmRzIHRvIHRoZSBmaXJzdCBhdmFpbGFibGUgc2VydmljZSBvbmx5IQotCQkJaWYgKHJlZmVyZW5jZS5yZWZlcmVuY2UuYmluZCAhPSBudWxsKSB7Ci0JCQkJc3dpdGNoIChyZWZlcmVuY2UucmVmZXJlbmNlLmNhcmRpbmFsaXR5KSB7Ci0JCQkJCWNhc2UgQ29tcG9uZW50UmVmZXJlbmNlLkNBUkRJTkFMSVRZXzFfMSA6Ci0JCQkJCWNhc2UgQ29tcG9uZW50UmVmZXJlbmNlLkNBUkRJTkFMSVRZXzBfMSA6Ci0JCQkJCQlmb3IgKGludCBpID0gMDsgaSA8IHNlcnZpY2VSZWZlcmVuY2VzLmxlbmd0aDsgaSsrKSB7Ci0JCQkJCQkJU2VydmljZVJlZmVyZW5jZSBvbGRCb3VuZFNlcnZpY2UgPSAocmVmZXJlbmNlLnJlZmVyZW5jZS5wb2xpY3lfb3B0aW9uID09IENvbXBvbmVudFJlZmVyZW5jZS5QT0xJQ1lfT1BUSU9OX0dSRUVEWSAmJiByZWZlcmVuY2UucmVmZXJlbmNlLnNlcnZpY2VSZWZlcmVuY2VzLnNpemUoKSA+IDAgPyAoU2VydmljZVJlZmVyZW5jZSkgcmVmZXJlbmNlLnJlZmVyZW5jZS5zZXJ2aWNlUmVmZXJlbmNlcy5rZXlzKCkubmV4dEVsZW1lbnQoKSA6IG51bGwpOwotCQkJCQkJCWJvb2xlYW4gYm91bmQgPSByZWZlcmVuY2UucmVmZXJlbmNlLmJpbmQocmVmZXJlbmNlLCBjb21wb25lbnRJbnN0YW5jZSwgc2VydmljZVJlZmVyZW5jZXNbaV0pOwotCQkJCQkJCWlmIChib3VuZCkgewotCQkJCQkJCQlpZiAob2xkQm91bmRTZXJ2aWNlICE9IG51bGwpIHsKLQkJCQkJCQkJCS8vdW5iaW5kIHRoZSBwcmV2aW91cyBib3VuZCBzZXJ2aWNlIHJlZmVyZW5jZSBpbiBjYXNlIHdlIGFyZSBoYW5kbGluZyBzZXJ2aWNlIHJlZmVyZW5jZSB1cGRhdGUgZHVlIHRvIGdyZWVkeSBwb2xpY3kgb3B0aW9uCi0JCQkJCQkJCQlyZWZlcmVuY2UucmVmZXJlbmNlLnVuYmluZChyZWZlcmVuY2UsIGNvbXBvbmVudEluc3RhbmNlLCBvbGRCb3VuZFNlcnZpY2UpOwotCQkJCQkJCQl9Ci0JCQkJCQkJCWJyZWFrOwotCQkJCQkJCX0KLQkJCQkJCX0KLQkJCQkJCWJyZWFrOwotCQkJCQljYXNlIENvbXBvbmVudFJlZmVyZW5jZS5DQVJESU5BTElUWV8xX04gOgotCQkJCQljYXNlIENvbXBvbmVudFJlZmVyZW5jZS5DQVJESU5BTElUWV8wX04gOgotCQkJCQkJLy8gYmluZCB0byBhbGwgc2VydmljZXMKLQkJCQkJCWZvciAoaW50IGkgPSAwOyBpIDwgc2VydmljZVJlZmVyZW5jZXMubGVuZ3RoOyBpKyspIHsKLQkJCQkJCQlyZWZlcmVuY2UucmVmZXJlbmNlLmJpbmQocmVmZXJlbmNlLCBjb21wb25lbnRJbnN0YW5jZSwgc2VydmljZVJlZmVyZW5jZXNbaV0pOwotCQkJCQkJfQotCQkJCQkJYnJlYWs7Ci0JCQkJfQotCQkJfSBlbHNlIGlmIChyZWZlcmVuY2UucmVmZXJlbmNlLnBvbGljeSA9PSBDb21wb25lbnRSZWZlcmVuY2UuUE9MSUNZX1NUQVRJQykgewotCQkJCS8vaW4gY2FzZSB0aGVyZSBpcyBubyBiaW5kIG1ldGhvZCBmb3Igc3RhdGljIHJlZmVyZW5jZSBzYXZlIHRoZSBjdXJyZW50IG1hdGNoaW5nIHNlcnZpY2UgcmVmZXJlbmNlcwotCQkJCXJlZmVyZW5jZS5zZXRCb3VuZFNlcnZpY2VSZWZlcmVuY2VzKHNlcnZpY2VSZWZlcmVuY2VzKTsKLQkJCX0KLQkJfSBlbHNlIHsKLQkJCWlmIChBY3RpdmF0b3IuREVCVUcpIHsKLQkJCQlBY3RpdmF0b3IubG9nLmRlYnVnKCJTZXJ2aWNlQ29tcG9uZW50UHJvcC5iaW5kUmVmZXJlbmNlKCk6IFRoZSBzZXJ2aWNlIGlzIG5vdCB5ZXQgcmVnaXN0ZXJlZCwgYnV0IGl0IGlzIGFscmVhZHkgaW5zdGFudGlhdGVkIiwgbnVsbCk7IC8vJE5PTi1OTFMtMSQKLQkJCX0KLQkJfQotCX0KLQotCS8qKgotCSAqIEhhbmRsZXMgdGhlIHVwZGF0ZSBvZiB0aGUgYm91bmQgc2VydmljZXMgaW4gY2FzZSB0aGUgdGFyZ2V0IHByb3BlcnRpZXMgaGF2ZSBjaGFuZ2VkCi0JICogQHBhcmFtIG9sZFByb3BzIHRoZSBvbGQgY29tcG9uZW50IHByb3BlcnRpZXMKLQkgKiBAcGFyYW0gbmV3UHJvcHMgdGhlIG5ldyBjb21wb25lbnQgcHJvcGVydGllcwotCSAqLwotCXByaXZhdGUgdm9pZCBoYW5kbGVCb3VuZFNlcnZpY2VzVXBkYXRlKEhhc2h0YWJsZSBvbGRQcm9wcywgRGljdGlvbmFyeSBuZXdQcm9wcykgewotCQlFbnVtZXJhdGlvbiBrZXlzID0gb2xkUHJvcHMua2V5cygpOwotCQlWZWN0b3IgY2hlY2tlZEZpbHRlcnMgPSBuZXcgVmVjdG9yKCk7Ci0JCS8vY2hlY2sgZm9yIGNoYW5nZWQgdGFyZ2V0IGZpbHRlcnMgaW4gdGhlIHByb3BlcnRpZXMKLQkJd2hpbGUgKGtleXMuaGFzTW9yZUVsZW1lbnRzKCkpIHsKLQkJCVN0cmluZyBrZXkgPSAoU3RyaW5nKSBrZXlzLm5leHRFbGVtZW50KCk7Ci0JCQlpZiAoa2V5LmVuZHNXaXRoKCIudGFyZ2V0IikpIHsgLy8kTk9OLU5MUy0xJAotCQkJCWNoZWNrZWRGaWx0ZXJzLmFkZEVsZW1lbnQoa2V5KTsKLQkJCQlTdHJpbmcgbmV3RmlsdGVyID0gKFN0cmluZykgbmV3UHJvcHMuZ2V0KGtleSk7Ci0JCQkJUmVmZXJlbmNlIHJlZmVyZW5jZSA9IG51bGw7Ci0JCQkJU3RyaW5nIHJlZk5hbWUgPSBrZXkuc3Vic3RyaW5nKDAsIGtleS5sZW5ndGgoKSAtICIudGFyZ2V0Ii5sZW5ndGgoKSk7IC8vJE5PTi1OTFMtMSQKLQkJCQlmb3IgKGludCBpID0gMDsgaSA8IHJlZmVyZW5jZXMuc2l6ZSgpOyBpKyspIHsKLQkJCQkJcmVmZXJlbmNlID0gKFJlZmVyZW5jZSkgcmVmZXJlbmNlcy5lbGVtZW50QXQoaSk7Ci0JCQkJCWlmIChyZWZlcmVuY2UucmVmZXJlbmNlLm5hbWUuZXF1YWxzKHJlZk5hbWUpKSB7Ci0JCQkJCQlicmVhazsKLQkJCQkJfQotCQkJCQlyZWZlcmVuY2UgPSBudWxsOwotCQkJCX0KLQkJCQkvL2NoZWNrIGlmIHRoZXJlIGlzIGEgcmVmZXJlbmNlIGNvcnJlc3BvbmRpbmcgdG8gdGhlIHRhcmdldCBwcm9wZXJ0eQotCQkJCWlmIChyZWZlcmVuY2UgIT0gbnVsbCAmJiByZWZlcmVuY2UucmVmZXJlbmNlLnBvbGljeSA9PSBDb21wb25lbnRSZWZlcmVuY2UuUE9MSUNZX0RZTkFNSUMpIHsKLQkJCQkJaWYgKG5ld0ZpbHRlciAhPSBudWxsKSB7Ci0JCQkJCQlpZiAoIW5ld0ZpbHRlci5lcXVhbHMob2xkUHJvcHMuZ2V0KGtleSkpKSB7Ci0JCQkJCQkJLy90aGUgZmlsdGVyIGRpZmZlcnMgdGhlIG9sZCBvbmUgLSB1cGRhdGUgdGhlIHJlZmVyZW5jZSBib3VuZCBzZXJ2aWNlcwotCQkJCQkJCXByb2Nlc3NSZWZlcmVuY2VCb3VuZFNlcnZpY2VzKHJlZmVyZW5jZSwgbmV3RmlsdGVyKTsKLQkJCQkJCX0KLQkJCQkJfSBlbHNlIHsKLQkJCQkJCS8vdGhlIHRhcmdldCBmaWx0ZXIgaXMgcmVtb3ZlZC4gdXNpbmcgdGhlIGRlZmF1bHQgb25lIAotCQkJCQkJcHJvY2Vzc1JlZmVyZW5jZUJvdW5kU2VydmljZXMocmVmZXJlbmNlLCAiKG9iamVjdENsYXNzPSIgKyByZWZlcmVuY2UucmVmZXJlbmNlLmludGVyZmFjZU5hbWUgKyAiKSIpOyAvLyROT04tTkxTLTEkIC8vJE5PTi1OTFMtMiQKLQkJCQkJfQotCQkJCX0KLQkJCX0KLQkJfQotCQkvL25vdyBjaGVjayBmb3IgbmV3bHkgYWRkZWQgdGFyZ2V0IGZpbHRlcnMKLQkJa2V5cyA9IG5ld1Byb3BzLmtleXMoKTsKLQkJd2hpbGUgKGtleXMuaGFzTW9yZUVsZW1lbnRzKCkpIHsKLQkJCVN0cmluZyBrZXkgPSAoU3RyaW5nKSBrZXlzLm5leHRFbGVtZW50KCk7Ci0JCQlpZiAoa2V5LmVuZHNXaXRoKCIudGFyZ2V0IikgJiYgIWNoZWNrZWRGaWx0ZXJzLmNvbnRhaW5zKGtleSkpIHsgLy8kTk9OLU5MUy0xJAotCQkJCVJlZmVyZW5jZSByZWZlcmVuY2UgPSBudWxsOwotCQkJCVN0cmluZyByZWZOYW1lID0ga2V5LnN1YnN0cmluZygwLCBrZXkubGVuZ3RoKCkgLSAiLnRhcmdldCIubGVuZ3RoKCkpOyAvLyROT04tTkxTLTEkCi0JCQkJZm9yIChpbnQgaSA9IDA7IGkgPCByZWZlcmVuY2VzLnNpemUoKTsgaSsrKSB7Ci0JCQkJCXJlZmVyZW5jZSA9IChSZWZlcmVuY2UpIHJlZmVyZW5jZXMuZWxlbWVudEF0KGkpOwotCQkJCQlpZiAocmVmZXJlbmNlLnJlZmVyZW5jZS5uYW1lLmVxdWFscyhyZWZOYW1lKSkgewotCQkJCQkJYnJlYWs7Ci0JCQkJCX0KLQkJCQkJcmVmZXJlbmNlID0gbnVsbDsKLQkJCQl9Ci0JCQkJLy9jaGVjayBpZiB0aGVyZSBpcyBhIHJlZmVyZW5jZSBjb3JyZXNwb25kaW5nIHRvIHRoZSB0YXJnZXQgcHJvcGVydHkKLQkJCQlpZiAocmVmZXJlbmNlICE9IG51bGwgJiYgcmVmZXJlbmNlLnJlZmVyZW5jZS5wb2xpY3kgPT0gQ29tcG9uZW50UmVmZXJlbmNlLlBPTElDWV9EWU5BTUlDKSB7Ci0JCQkJCXByb2Nlc3NSZWZlcmVuY2VCb3VuZFNlcnZpY2VzKHJlZmVyZW5jZSwgKFN0cmluZykgbmV3UHJvcHMuZ2V0KGtleSkpOwotCQkJCX0KLQkJCX0KLQkJfQotCX0KLQotCXByaXZhdGUgdm9pZCBwcm9jZXNzUmVmZXJlbmNlQm91bmRTZXJ2aWNlcyhSZWZlcmVuY2UgcmVmZXJlbmNlLCBTdHJpbmcgbmV3VGFyZ2V0RmlsdGVyKSB7Ci0JCXJlZmVyZW5jZS5zZXRUYXJnZXQobmV3VGFyZ2V0RmlsdGVyKTsKLQkJU2VydmljZVJlZmVyZW5jZVtdIHJlZnMgPSBudWxsOwotCQl0cnkgewotCQkJcmVmcyA9IGJjLmdldFNlcnZpY2VSZWZlcmVuY2VzKHJlZmVyZW5jZS5yZWZlcmVuY2UuaW50ZXJmYWNlTmFtZSwgbmV3VGFyZ2V0RmlsdGVyKTsKLQkJfSBjYXRjaCAoSW52YWxpZFN5bnRheEV4Y2VwdGlvbiBlKSB7Ci0JCQlBY3RpdmF0b3IubG9nKGJjLCBMb2dTZXJ2aWNlLkxPR19XQVJOSU5HLCAiW1NDUl0gIiArIE5MUy5iaW5kKE1lc3NhZ2VzLklOVkFMSURfVEFSR0VUX0ZJTFRFUiwgbmV3VGFyZ2V0RmlsdGVyKSwgZSk7IC8vJE5PTi1OTFMtMSQKLQkJCXJldHVybjsKLQkJfQotCi0JCWlmIChyZWZzID09IG51bGwpIHsKLQkJCS8vbXVzdCByZW1vdmUgYWxsIGN1cnJlbnRseSBib3VuZCBzZXJ2aWNlcwotCQkJaWYgKHJlZmVyZW5jZS5yZWZlcmVuY2UuYmluZCAhPSBudWxsKSB7Ci0JCQkJaWYgKHJlZmVyZW5jZS5yZWZlcmVuY2Uuc2VydmljZVJlZmVyZW5jZXMuc2l6ZSgpID4gMCkgewotCQkJCQlmb3IgKGludCBpID0gMDsgaSA8IGluc3RhbmNlcy5zaXplKCk7IGkrKykgewotCQkJCQkJQ29tcG9uZW50SW5zdGFuY2UgY29tcG9uZW50SW5zdGFuY2UgPSAoQ29tcG9uZW50SW5zdGFuY2UpIGluc3RhbmNlcy5lbGVtZW50QXQoaSk7Ci0JCQkJCQl1bmJpbmRSZWZlcmVuY2UocmVmZXJlbmNlLCBjb21wb25lbnRJbnN0YW5jZSk7Ci0JCQkJCX0KLQkJCQl9Ci0JCQl9Ci0JCX0gZWxzZSB7Ci0JCQkvL2ZpbmQgb3V0IHdoaWNoIHNlcnZpY2VzIGhhcyB0byBiZSBib3VuZCBhbmQgd2hpY2ggdW5ib3VuZAotCQkJaWYgKHJlZmVyZW5jZS5yZWZlcmVuY2UuYmluZCAhPSBudWxsKSB7Ci0JCQkJVmVjdG9yIHNlcnZpY2VzVG9VbmJpbmQgPSBuZXcgVmVjdG9yKCk7Ci0JCQkJRW51bWVyYXRpb24ga2V5cyA9IHJlZmVyZW5jZS5yZWZlcmVuY2Uuc2VydmljZVJlZmVyZW5jZXMua2V5cygpOwotCQkJCXdoaWxlIChrZXlzLmhhc01vcmVFbGVtZW50cygpKSB7Ci0JCQkJCU9iamVjdCBzZXJ2aWNlUmVmID0ga2V5cy5uZXh0RWxlbWVudCgpOwotCQkJCQlib29sZWFuIGZvdW5kID0gZmFsc2U7Ci0JCQkJCWZvciAoaW50IGkgPSAwOyBpIDwgcmVmcy5sZW5ndGg7IGkrKykgewotCQkJCQkJaWYgKHJlZnNbaV0gPT0gc2VydmljZVJlZikgewotCQkJCQkJCWZvdW5kID0gdHJ1ZTsKLQkJCQkJCQlicmVhazsKLQkJCQkJCX0KLQkJCQkJfQotCQkJCQlpZiAoIWZvdW5kKSB7Ci0JCQkJCQkvL3RoZSBib3VuZCBzZXJ2aWNlIHJlZmVyZW5jZSBpcyBub3QgYWxyZWFkeSBpbiB0aGUgc2F0aXNmaWVkIHJlZmVyZW5jZXMgc2V0LgotCQkJCQkJc2VydmljZXNUb1VuYmluZC5hZGRFbGVtZW50KHNlcnZpY2VSZWYpOwotCQkJCQl9Ci0JCQkJfQotCQkJCWlmICgocmVmZXJlbmNlLnJlZmVyZW5jZS5jYXJkaW5hbGl0eSA9PSBDb21wb25lbnRSZWZlcmVuY2UuQ0FSRElOQUxJVFlfMF9OIHx8IHJlZmVyZW5jZS5yZWZlcmVuY2UuY2FyZGluYWxpdHkgPT0gQ29tcG9uZW50UmVmZXJlbmNlLkNBUkRJTkFMSVRZXzFfTikgJiYgKHJlZmVyZW5jZS5yZWZlcmVuY2Uuc2VydmljZVJlZmVyZW5jZXMuc2l6ZSgpIC0gc2VydmljZXNUb1VuYmluZC5zaXplKCkpIDwgcmVmcy5sZW5ndGgpIHsKLQkJCQkJLy90aGVyZSBhcmUgbW9yZSBzZXJ2aWNlcyB0byBiaW5kCi0JCQkJCWZvciAoaW50IGkgPSAwOyBpIDwgcmVmcy5sZW5ndGg7IGkrKykgewotCQkJCQkJa2V5cyA9IHJlZmVyZW5jZS5yZWZlcmVuY2Uuc2VydmljZVJlZmVyZW5jZXMua2V5cygpOwotCQkJCQkJYm9vbGVhbiBmb3VuZCA9IGZhbHNlOwotCQkJCQkJd2hpbGUgKGtleXMuaGFzTW9yZUVsZW1lbnRzKCkpIHsKLQkJCQkJCQlPYmplY3Qgc2VydmljZVJlZiA9IGtleXMubmV4dEVsZW1lbnQoKTsKLQkJCQkJCQlpZiAoc2VydmljZVJlZiA9PSByZWZzW2ldKSB7Ci0JCQkJCQkJCWZvdW5kID0gdHJ1ZTsKLQkJCQkJCQkJYnJlYWs7Ci0JCQkJCQkJfQotCQkJCQkJfQotCQkJCQkJaWYgKCFmb3VuZCkgewotCQkJCQkJCWZvciAoaW50IGogPSAwOyBqIDwgaW5zdGFuY2VzLnNpemUoKTsgaisrKSB7Ci0JCQkJCQkJCUNvbXBvbmVudEluc3RhbmNlIGNvbXBvbmVudEluc3RhbmNlID0gKENvbXBvbmVudEluc3RhbmNlKSBpbnN0YW5jZXMuZWxlbWVudEF0KGopOwotCQkJCQkJCQl0cnkgewotCQkJCQkJCQkJcmVmZXJlbmNlLnJlZmVyZW5jZS5iaW5kKHJlZmVyZW5jZSwgY29tcG9uZW50SW5zdGFuY2UsIHJlZnNbaV0pOwotCQkJCQkJCQl9IGNhdGNoIChFeGNlcHRpb24gZSkgewotCQkJCQkJCQkJQWN0aXZhdG9yLmxvZyhudWxsLCBMb2dTZXJ2aWNlLkxPR19FUlJPUiwgTkxTLmJpbmQoTWVzc2FnZXMuRVJST1JfQklORElOR19SRUZFUkVOQ0UsIHJlZmVyZW5jZSksIGUpOwotCQkJCQkJCQl9Ci0JCQkJCQkJfQotCQkJCQkJfQotCQkJCQl9Ci0JCQkJfQotCQkJCS8vZmluYWxseSB1bmJpbmQgYWxsIHNlcnZpY2VzIHRoYXQgZG8gbm90IG1hdGNoIHRoZSB0YXJnZXQgZmlsdGVyCi0JCQkJZm9yIChpbnQgaSA9IDA7IGkgPCBzZXJ2aWNlc1RvVW5iaW5kLnNpemUoKTsgaSsrKSB7Ci0JCQkJCWZvciAoaW50IGogPSAwOyBqIDwgaW5zdGFuY2VzLnNpemUoKTsgaisrKSB7Ci0JCQkJCQlDb21wb25lbnRJbnN0YW5jZSBjb21wb25lbnRJbnN0YW5jZSA9IChDb21wb25lbnRJbnN0YW5jZSkgaW5zdGFuY2VzLmVsZW1lbnRBdChqKTsKLQkJCQkJCXRyeSB7Ci0JCQkJCQkJdW5iaW5kRHluYW1pY1JlZmVyZW5jZShyZWZlcmVuY2UsIGNvbXBvbmVudEluc3RhbmNlLCAoU2VydmljZVJlZmVyZW5jZSkgc2VydmljZXNUb1VuYmluZC5lbGVtZW50QXQoaSkpOwotCQkJCQkJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKLQkJCQkJCQlBY3RpdmF0b3IubG9nKG51bGwsIExvZ1NlcnZpY2UuTE9HX0VSUk9SLCBOTFMuYmluZChNZXNzYWdlcy5FUlJPUl9VTkJJTkRJTkdfUkVGRVJFTkNFMiwgcmVmZXJlbmNlKSwgZSk7Ci0JCQkJCQl9Ci0JCQkJCX0KLQkJCQl9Ci0JCQl9Ci0JCX0KLQl9Ci0KLQkvKioKLQkgKiBDYWxsIHRoZSB1bmJpbmQgbWV0aG9kIGZvciB0aGlzIFJlZmVyZW5jZSBEZXNjcmlwdGlvbgotCSAqIAotCSAqIEBwYXJhbSByZWZlcmVuY2UKLQkgKiBAcGFyYW0gY29tcG9uZW50SW5zdGFuY2UKLQkgKi8KLQlwdWJsaWMgdm9pZCB1bmJpbmRSZWZlcmVuY2UoUmVmZXJlbmNlIHJlZmVyZW5jZSwgQ29tcG9uZW50SW5zdGFuY2UgY29tcG9uZW50SW5zdGFuY2UpIHsKLQotCQkvLyB1bmJpbmQgdGhlIHNlcnZpY2VzIE9OTFkgaWYgdW5iaW5kIG1ldGhvZCBpcyBzcGVjaWZpZWQhCi0JCWlmIChyZWZlcmVuY2UucmVmZXJlbmNlLnVuYmluZCA9PSBudWxsKSB7Ci0JCQlyZXR1cm47Ci0JCX0KLQotCQkvLyBvaywgcHJvY2VlZCEKLQotCQlpZiAoQWN0aXZhdG9yLkRFQlVHKSB7Ci0JCQlBY3RpdmF0b3IubG9nLmRlYnVnKCJTZXJ2aWNlQ29tcG9uZW50UHJvcC51bmJpbmRSZWZlcmVuY2UoKTogY29tcG9uZW50ICIgKyBzZXJ2aWNlQ29tcG9uZW50Lm5hbWUgKyAiIDwtICIgKyByZWZlcmVuY2UucmVmZXJlbmNlLCBudWxsKTsgLy8kTk9OLU5MUy0xJCAvLyROT04tTkxTLTIkCi0JCX0KLQotCQlFbnVtZXJhdGlvbiBzZXJ2aWNlUmVmZXJlbmNlcyA9IHJlZmVyZW5jZS5yZWZlcmVuY2Uuc2VydmljZVJlZmVyZW5jZXMua2V5cygpOwotCQl3aGlsZSAoc2VydmljZVJlZmVyZW5jZXMuaGFzTW9yZUVsZW1lbnRzKCkpIHsKLQkJCXJlZmVyZW5jZS5yZWZlcmVuY2UudW5iaW5kKHJlZmVyZW5jZSwgY29tcG9uZW50SW5zdGFuY2UsIChTZXJ2aWNlUmVmZXJlbmNlKSBzZXJ2aWNlUmVmZXJlbmNlcy5uZXh0RWxlbWVudCgpKTsKLQkJfQotCX0KLQotCS8qKgotCSAqIENhbGwgdGhlIHVuYmluZCBtZXRob2QgZm9yIHRoaXMgUmVmZXJlbmNlIERlc2NyaXB0aW9uCi0JICogCi0JICogQHBhcmFtIHJlZgotCSAqIEBwYXJhbSBpbnN0YW5jZQotCSAqIEBwYXJhbSBzZXJ2aWNlT2JqZWN0Ci0JICogQHRocm93cyBFeGNlcHRpb24KLQkgKi8KLQlwdWJsaWMgdm9pZCB1bmJpbmREeW5hbWljUmVmZXJlbmNlKFJlZmVyZW5jZSByZWYsIENvbXBvbmVudEluc3RhbmNlIGluc3RhbmNlLCBTZXJ2aWNlUmVmZXJlbmNlIHNlcnZpY2VSZWZlcmVuY2UpIHRocm93cyBFeGNlcHRpb24gewotCQlpZiAoQWN0aXZhdG9yLkRFQlVHKSB7Ci0JCQlBY3RpdmF0b3IubG9nLmRlYnVnKCJTZXJ2aWNlQ29tcG9uZW50UHJvcC51bmJpbmREeW5hbWljUmVmZXJlbmNlKCk6IGNvbXBvbmVudCA9ICIgKyBuYW1lICsgIiwgcmVmZXJlbmNlID0gIiArIHJlZi5yZWZlcmVuY2UubmFtZSwgbnVsbCk7IC8vJE5PTi1OTFMtMSQgLy8kTk9OLU5MUy0yJAotCQl9Ci0JCS8vIGNoZWNrIGlmIHdlIG5lZWQgdG8gcmViaW5kCi0JCXN3aXRjaCAocmVmLnJlZmVyZW5jZS5jYXJkaW5hbGl0eSkgewotCQkJY2FzZSBDb21wb25lbnRSZWZlcmVuY2UuQ0FSRElOQUxJVFlfMF8xIDoKLQkJCWNhc2UgQ29tcG9uZW50UmVmZXJlbmNlLkNBUkRJTkFMSVRZXzFfMSA6Ci0JCQkJaWYgKHJlZi5yZWZlcmVuY2UuYmluZCAhPSBudWxsKSB7Ci0JCQkJCWJpbmRSZWZlcmVuY2UocmVmLCBpbnN0YW5jZSk7Ci0JCQkJfQotCQl9Ci0JCXJlZi5yZWZlcmVuY2UudW5iaW5kKHJlZiwgaW5zdGFuY2UsIHNlcnZpY2VSZWZlcmVuY2UpOwotCX0KLQotCS8qKgotCSAqIENhbGwgdGhlIHVwZGF0ZWQgbWV0aG9kIGZvciB0aGlzIFJlZmVyZW5jZQotCSAqIAotCSAqIEBwYXJhbSByZWYgdGhlIHJlZmVyZW5jZQotCSAqIEBwYXJhbSBpbnN0YW5jZSB0aGUgY29tcG9uZW50IGluc3RhbmNlCi0JICogQHBhcmFtIHNlcnZpY2VSZWZlcmVuY2UgdGhlIHNlcnZpY2UgcmVmZXJlbmNlIHdoaWNoIHByb3BlcnRpZXMgaGF2ZSBjaGFuZ2VkCi0JICovCi0JcHVibGljIHZvaWQgdXBkYXRlZFJlZmVyZW5jZShSZWZlcmVuY2UgcmVmLCBDb21wb25lbnRJbnN0YW5jZSBpbnN0YW5jZSwgU2VydmljZVJlZmVyZW5jZSBzZXJ2aWNlUmVmZXJlbmNlKSB7Ci0JCWlmIChBY3RpdmF0b3IuREVCVUcpIHsKLQkJCUFjdGl2YXRvci5sb2cuZGVidWcoIlNlcnZpY2VDb21wb25lbnRQcm9wLnVwZGF0ZWRSZWZlcmVuY2UoKTogY29tcG9uZW50ID0gIiArIG5hbWUgKyAiLCByZWZlcmVuY2UgPSAiICsgcmVmLnJlZmVyZW5jZS5uYW1lLCBudWxsKTsgLy8kTk9OLU5MUy0xJCAvLyROT04tTkxTLTIkCi0JCX0KLQkJcmVmLnJlZmVyZW5jZS51cGRhdGVkKHJlZiwgaW5zdGFuY2UsIHNlcnZpY2VSZWZlcmVuY2UpOwotCX0KLQotCS8vIC0tIGJlZ2luIGhlbHBlciBtZXRob2RzCi0JLyoqCi0JICogSW5pdGlhbGl6ZSBQcm9wZXJ0aWVzIGZvciB0aGlzIENvbXBvbmVudAotCSAqIAotCSAqIFRoZSBwcm9wZXJ0eSBlbGVtZW50cyBwcm92aWRlIGRlZmF1bHQgb3Igc3VwcGxlbWVudGFsIHByb3BlcnR5IHZhbHVlcyBpZgotCSAqIG5vdCBvdmVycmlkZGVuIGJ5IHRoZSBwcm9wZXJ0aWVzIHJldHJpZXZlZCBmcm9tIENvbmZpZ3VyYXRpb24gQWRtaW4KLQkgKiAKLQkgKiBAcGFyYW0gY29uZmlnUHJvcGVydGllcwotCSAqICAgICAgICAgICAgdGhlIGNvbmZpZ3VyYXRpb24gcHJvcGVydGllcwotCSAqIEBwYXJhbSBjb21wb25lbnRJZCBzcGVjaWZpZXMgdGhlIGNvbXBvbmVudCBJRC4gSWYgbnVsbCwgYSBuZXcgb25lIHdpbGwgYmUgZ2VuZXJhdGVkCi0JICogQHJldHVybiB0aGUgZnVsbHkgaW5pdGlhbGl6ZWQgcHJvcGVydGllcwotCSAqLwotCXByaXZhdGUgSGFzaHRhYmxlIGluaXRQcm9wZXJ0aWVzKERpY3Rpb25hcnkgY29uZmlnUHJvcGVydGllcywgTG9uZyBjb21wb25lbnRJZCkgewotCQlIYXNodGFibGUgcmVzdWx0ID0gbnVsbDsKLQkJLy8gZGVmYXVsdCBjb21wb25lbnQgc2VydmljZSBwcm9wZXJ0aWVzCi0JCVByb3BlcnRpZXMgcHJvcGVydHlEZXNjcmlwdGlvbnMgPSBzZXJ2aWNlQ29tcG9uZW50LnByb3BlcnRpZXM7Ci0JCWlmIChwcm9wZXJ0eURlc2NyaXB0aW9ucyAhPSBudWxsICYmICFwcm9wZXJ0eURlc2NyaXB0aW9ucy5pc0VtcHR5KCkpIHsKLQkJCXJlc3VsdCA9IChIYXNodGFibGUpIHByb3BlcnR5RGVzY3JpcHRpb25zLmNsb25lKCk7Ci0JCX0KLQotCQkvLyBzZXQgdGhlIGNvbXBvbmVudC5uYW1lCi0JCWlmIChyZXN1bHQgPT0gbnVsbCkgewotCQkJcmVzdWx0ID0gbmV3IEhhc2h0YWJsZSg3KTsKLQkJfQotCi0JCS8vIHB1dCB0aGUgcmVmZXJlbmNlcyBpbiB0aGUgcHJvcGVydGllcwotCQlpZiAoc2VydmljZUNvbXBvbmVudC5yZWZlcmVuY2VzICE9IG51bGwpIHsKLQkJCUNvbXBvbmVudFJlZmVyZW5jZSByZWY7Ci0JCQlmb3IgKGludCBpID0gMDsgaSA8IHNlcnZpY2VDb21wb25lbnQucmVmZXJlbmNlcy5zaXplKCk7IGkrKykgewotCQkJCXJlZiA9IChDb21wb25lbnRSZWZlcmVuY2UpIHNlcnZpY2VDb21wb25lbnQucmVmZXJlbmNlcy5lbGVtZW50QXQoaSk7Ci0JCQkJaWYgKHJlZi50YXJnZXQgIT0gbnVsbCkgewotCQkJCQlyZXN1bHQucHV0KHJlZi5uYW1lICsgQ29tcG9uZW50Q29uc3RhbnRzLlJFRkVSRU5DRV9UQVJHRVRfU1VGRklYLCByZWYudGFyZ2V0KTsKLQkJCQl9Ci0JCQl9Ci0JCX0KLQotCQkvLyBwcm9wZXJ0aWVzIGZyb20gQ29uZmlndXJhdGlvbiBBZG1pbgotCQlpZiAoY29uZmlnUHJvcGVydGllcyAhPSBudWxsICYmICFjb25maWdQcm9wZXJ0aWVzLmlzRW1wdHkoKSkgewotCQkJZm9yIChFbnVtZXJhdGlvbiBrZXlzID0gY29uZmlnUHJvcGVydGllcy5rZXlzKCk7IGtleXMuaGFzTW9yZUVsZW1lbnRzKCk7KSB7Ci0JCQkJT2JqZWN0IGtleSA9IGtleXMubmV4dEVsZW1lbnQoKTsKLQkJCQlPYmplY3QgdmFsID0gY29uZmlnUHJvcGVydGllcy5nZXQoa2V5KTsKLQkJCQlyZXN1bHQucHV0KGtleSwgdmFsKTsKLQkJCX0KLQkJfQotCi0JCS8vIGFsd2F5cyBzZXQgdGhlIGNvbXBvbmVudCBuYW1lICYgdGhlIGlkCi0JCUxvbmcgbmV4dElkID0gKGNvbXBvbmVudElkID09IG51bGwpID8gbmV3IExvbmcoZ2V0TmV3Q29tcG9uZW50SUQoKSkgOiBjb21wb25lbnRJZDsKLQkJcmVzdWx0LnB1dChDb21wb25lbnRDb25zdGFudHMuQ09NUE9ORU5UX0lELCBuZXh0SWQpOwotCQlyZXN1bHQucHV0KENvbXBvbmVudENvbnN0YW50cy5DT01QT05FTlRfTkFNRSwgc2VydmljZUNvbXBvbmVudC5uYW1lKTsKLQotCQlpZiAoc2VydmljZUNvbXBvbmVudC5wcm92aWRlcyAhPSBudWxsKSB7Ci0JCQlTdHJpbmdbXSBwcm92aWRlcyA9IG5ldyBTdHJpbmdbc2VydmljZUNvbXBvbmVudC5wcm92aWRlcy5sZW5ndGhdOwotCQkJU3lzdGVtLmFycmF5Y29weShzZXJ2aWNlQ29tcG9uZW50LnByb3ZpZGVzLCAwLCBwcm92aWRlcywgMCwgcHJvdmlkZXMubGVuZ3RoKTsKLQkJCXJlc3VsdC5wdXQoQ29uc3RhbnRzLk9CSkVDVENMQVNTLCBwcm92aWRlcyk7Ci0JCX0KLQkJcmV0dXJuIHJlc3VsdDsKLQl9Ci0KLQlwcml2YXRlIHZvaWQgYXNzZXJ0Q3JlYXRlU2luZ2xlSW5zdGFuY2UoKSB7Ci0JCWlmICghc2VydmljZUNvbXBvbmVudC5zZXJ2aWNlRmFjdG9yeSAmJiAhaW5zdGFuY2VzLmlzRW1wdHkoKSkgewotCQkJdGhyb3cgbmV3IENvbXBvbmVudEV4Y2VwdGlvbihOTFMuYmluZChNZXNzYWdlcy5JTlNUQU5DRV9BTFJFQURZX0NSRUFURUQsIG5hbWUpKTsKLQkJfQotCX0KLQotCXB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7Ci0JCVN0cmluZ0J1ZmZlciBidWZmZXIgPSBuZXcgU3RyaW5nQnVmZmVyKCk7Ci0JCWJ1ZmZlci5hcHBlbmQoIlNlcnZpY2VDb21wb25lbnRQcm9wWyIpOyAvLyROT04tTkxTLTEkCi0JCWJ1ZmZlci5hcHBlbmQoIlxuXHRuYW1lID0gIikuYXBwZW5kKG5hbWUpOyAvLyROT04tTkxTLTEkCi0JCWJ1ZmZlci5hcHBlbmQoIlxuXHRzdGF0ZSA9ICIpLmFwcGVuZChTQ1JVdGlsLmdldFN0YXRlU3RyaW5nUmVwcmVzZW50YXRpb24oc3RhdGUpKTsgLy8kTk9OLU5MUy0xJAotCQlTdHJpbmdCdWZmZXIgYnVmID0gbmV3IFN0cmluZ0J1ZmZlcigyMDApOwotCQlpZiAocHJvcGVydGllcyAhPSBudWxsKSB7Ci0JCQlidWYuYXBwZW5kKCd7Jyk7Ci0JCQlFbnVtZXJhdGlvbiBrZXlzID0gcHJvcGVydGllcy5rZXlzKCk7Ci0JCQl3aGlsZSAoa2V5cy5oYXNNb3JlRWxlbWVudHMoKSkgewotCQkJCU9iamVjdCBrZXkgPSBrZXlzLm5leHRFbGVtZW50KCk7Ci0JCQkJYnVmLmFwcGVuZChrZXkpLmFwcGVuZCgnPScpLmFwcGVuZChTQ1JVdGlsLmdldFN0cmluZ1JlcHJlc2VudGF0aW9uKHByb3BlcnRpZXMuZ2V0KGtleSkpKTsKLQkJCQlpZiAoa2V5cy5oYXNNb3JlRWxlbWVudHMoKSkgewotCQkJCQlidWYuYXBwZW5kKCIsICIpOyAvLyROT04tTkxTLTEkCi0JCQkJfQotCQkJfQotCQkJYnVmLmFwcGVuZCgnfScpOwotCQl9Ci0JCWJ1ZmZlci5hcHBlbmQoIlxuXHRwcm9wZXJ0aWVzID0gIikuYXBwZW5kKGJ1Zi50b1N0cmluZygpKTsgLy8kTk9OLU5MUy0xJAotCQlidWZmZXIuYXBwZW5kKCJdIik7IC8vJE5PTi1OTFMtMSQKLQkJcmV0dXJuIGJ1ZmZlci50b1N0cmluZygpOwotCX0KLQotCXB1YmxpYyB2b2lkIHNldFJlZ2lzdHJhdGlvbihTZXJ2aWNlUmVnaXN0cmF0aW9uIHJlZykgewotCQlyZWdpc3RyYXRpb24gPSByZWc7Ci0JfQotCi0JLyoqCi0JICogUmVtb3ZlcyB0aGUgcHJpdmF0ZSBwcm9wZXJ0aWVzIGFuZCByZXR1cm5zIHRoZSBwdWJsaWMgcHJvcGVydGllcyB0aGF0IGFyZSBzZXQgdG8gdGhlIHJlZ2lzdGVyZWQgc2VydmljZSBwcm92aWRlZCBieSB0aGlzIGNvbXBvbmVudAotCSAqIEByZXR1cm4gdGhlIHB1YmxpYyBwcm9wZXJ0aWVzIHVzZWQgaW4gdGhlIHJlZ2lzdHJhdGlvbiBvZiB0aGUgc2VydmljZSB3aGljaCBpcyBwcm92aWRlZCBieSB0aGlzIGNvbXBvbmVudAotCSAqLwotCXB1YmxpYyBIYXNodGFibGUgZ2V0UHVibGljU2VydmljZVByb3BlcnRpZXMoKSB7Ci0JCS8vcmVtb3ZlIHRoZSBwcml2YXRlIHByb3BlcnRpZXMgZnJvbSB0aGUgY29tcG9uZW50IHByb3BlcnRpZXMgYmVmb3JlIHJlZ2lzdGVyaW5nIGFzIHNlcnZpY2UKLQkJSGFzaHRhYmxlIHB1YmxpY1Byb3BzID0gKEhhc2h0YWJsZSkgcHJvcGVydGllcy5jbG9uZSgpOwotCQlFbnVtZXJhdGlvbiBrZXlzID0gcHJvcGVydGllcy5rZXlzKCk7Ci0JCXdoaWxlIChrZXlzLmhhc01vcmVFbGVtZW50cygpKSB7Ci0JCQlTdHJpbmcga2V5ID0gKFN0cmluZykga2V5cy5uZXh0RWxlbWVudCgpOwotCQkJaWYgKGtleS5zdGFydHNXaXRoKCIuIikpIHsgLy8kTk9OLU5MUy0xJAotCQkJCXB1YmxpY1Byb3BzLnJlbW92ZShrZXkpOwotCQkJfQotCQl9Ci0JCXJldHVybiBwdWJsaWNQcm9wczsKLQl9Ci0KLQkvKioKLQkgKiBBZGQgYSBuZXcgQ29tcG9uZW50IENvbmZpZ3VyYXRpb24gbmFtZSB3ZSBzaG91bGQgbm90IGFjdGl2YXRlIGluIG9yZGVyIHRvCi0JICogcHJldmVudCBhIGN5Y2xlLgotCSAqIAotCSAqIEBzZWUgU2VydmljZUNvbXBvbmVudFByb3AjZGVsYXlBY3RpdmF0ZVNDUE5hbWVzCi0JICovCi0JcHVibGljIHZvaWQgc2V0RGVsYXlBY3RpdmF0ZVNDUE5hbWUoU3RyaW5nIHNjcE5hbWUpIHsKLQkJaWYgKEFjdGl2YXRvci5ERUJVRykgewotCQkJQWN0aXZhdG9yLmxvZy5kZWJ1ZygiU2V0dGluZyBkZWxheSBhY3RpdmF0ZSBTQ1A6ICIgKyBzY3BOYW1lLCBudWxsKTsgLy8kTk9OLU5MUy0xJAotCQl9Ci0JCWlmIChkZWxheUFjdGl2YXRlU0NQTmFtZXMgPT0gbnVsbCkgewotCQkJZGVsYXlBY3RpdmF0ZVNDUE5hbWVzID0gbmV3IFZlY3RvcigxKTsKLQkJCWRlbGF5QWN0aXZhdGVTQ1BOYW1lcy5hZGRFbGVtZW50KHNjcE5hbWUpOwotCQl9IGVsc2UgaWYgKCFkZWxheUFjdGl2YXRlU0NQTmFtZXMuY29udGFpbnMoc2NwTmFtZSkpIHsKLQkJCWRlbGF5QWN0aXZhdGVTQ1BOYW1lcy5hZGRFbGVtZW50KHNjcE5hbWUpOwotCQl9Ci0JfQotCi0JcHVibGljIFZlY3RvciBnZXREZWxheUFjdGl2YXRlU0NQTmFtZXMoKSB7Ci0JCXJldHVybiBkZWxheUFjdGl2YXRlU0NQTmFtZXM7Ci0JfQotCi0JcHVibGljIGJvb2xlYW4gaXNDb21wb25lbnRGYWN0b3J5KCkgewotCQlyZXR1cm4gaXNDb21wb25lbnRGYWN0b3J5OwotCX0KLQotCS8vIHVzZWQgYnkgdGhlIENvbXBvbmVudEZhY3RvcnlJbXBsIHRvIG1hcmsgY29tcG9uZW50IGNvbmZpZ3MgY3JlYXRlZCBieSBpdAotCS8vIHRoYXQKLQkvLyB0aGV5IGFyZSBub3QgY29tcG9uZW50IGZhY3Rvcmllcy4gVGhpcyBhdm9pZHMgc3Vic2VjdWVudCByZWdpc3RyYXRpb25zIG9mCi0JLy8gdGhlIHNhbWUgY29tcG9uZW50IGZhY3RvcnkuCi0JcHVibGljIHZvaWQgc2V0Q29tcG9uZW50RmFjdG9yeShib29sZWFuIGlzQ29tcG9uZW50RmFjdG9yeSkgewotCQl0aGlzLmlzQ29tcG9uZW50RmFjdG9yeSA9IGlzQ29tcG9uZW50RmFjdG9yeTsKLQl9Ci0KLQlzdGF0aWMgc3luY2hyb25pemVkIGxvbmcgZ2V0TmV3Q29tcG9uZW50SUQoKSB7Ci0JCXJldHVybiBjb21wb25lbnRpZCsrOwotCX0KLQotCXB1YmxpYyBib29sZWFuIGlzS2luZE9mRmFjdG9yeSgpIHsKLQkJcmV0dXJuIHNlcnZpY2VDb21wb25lbnQuc2VydmljZUZhY3Rvcnk7Ci0JfQotCi0JcHVibGljIHN5bmNocm9uaXplZCBpbnQgZ2V0U3RhdGUoKSB7Ci0JCXJldHVybiBzdGF0ZTsKLQl9Ci0KLQlwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgc2V0U3RhdGUoaW50IHN0YXRlKSB7Ci0JCXRoaXMuc3RhdGUgPSBzdGF0ZTsKLQl9Ci0KLQlwdWJsaWMgdm9pZCBkaXNhYmxlKCkgewotCQlpZiAoZ2V0U3RhdGUoKSA9PSBTVEFURV9ESVNQT1NFRCkgewotCQkJdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbihNZXNzYWdlcy5DT01QT05FTlRfRElTUE9TRUQpOwotCQl9IGVsc2UgaWYgKGdldFN0YXRlKCkgIT0gU1RBVEVfRElTQUJMRUQpIHsKLQkJCW1nci5kaXNhYmxlQ29tcG9uZW50KHNlcnZpY2VDb21wb25lbnQubmFtZSwgc2VydmljZUNvbXBvbmVudC5idW5kbGUpOwotCQl9Ci0JfQotCi0JcHVibGljIHZvaWQgZW5hYmxlKCkgewotCQlpZiAoZ2V0U3RhdGUoKSA9PSBTVEFURV9ESVNQT1NFRCkgewotCQkJdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbihNZXNzYWdlcy5DT01QT05FTlRfRElTUE9TRUQpOwotCQl9IGVsc2UgaWYgKGdldFN0YXRlKCkgPT0gU1RBVEVfRElTQUJMRUQpIHsKLQkJCW1nci5lbmFibGVDb21wb25lbnQoc2VydmljZUNvbXBvbmVudC5uYW1lLCBzZXJ2aWNlQ29tcG9uZW50LmJ1bmRsZSk7Ci0JCX0KLQl9Ci0KLQlwdWJsaWMgU3RyaW5nIGdldEFjdGl2YXRlKCkgewotCQlyZXR1cm4gc2VydmljZUNvbXBvbmVudC5hY3RpdmF0ZU1ldGhvZE5hbWU7Ci0JfQotCi0JcHVibGljIEJ1bmRsZSBnZXRCdW5kbGUoKSB7Ci0JCXJldHVybiBzZXJ2aWNlQ29tcG9uZW50LmJ1bmRsZTsKLQl9Ci0KLQlwdWJsaWMgU3RyaW5nIGdldENsYXNzTmFtZSgpIHsKLQkJcmV0dXJuIHNlcnZpY2VDb21wb25lbnQuaW1wbGVtZW50YXRpb247Ci0JfQotCi0JcHVibGljIENvbXBvbmVudEluc3RhbmNlIGdldENvbXBvbmVudEluc3RhbmNlKCkgewotCQlpZiAoIWluc3RhbmNlcy5pc0VtcHR5KCkpIHsKLQkJCS8vVE9ETyB3ZSBoYXZlIG11bHRpcGxlIGluc3RhbmNlcyB3aGVuIHRoZSBjb21wb25lbnQgaXMgc2VydmljZSBmYWN0b3J5Ci0JCQkvL1BlcmhhcHMgd2UgaGF2ZSB0byBsaXN0IGluIFNjclNlcnZpY2UgQ29tcG9uZW50IGZvciBlYWNoIGluc3RhbmNlCi0JCQlyZXR1cm4gKENvbXBvbmVudEluc3RhbmNlKSBpbnN0YW5jZXMuZmlyc3RFbGVtZW50KCk7Ci0JCX0KLQkJcmV0dXJuIG51bGw7Ci0JfQotCi0JcHVibGljIFN0cmluZyBnZXRDb25maWd1cmF0aW9uUG9saWN5KCkgewotCQlyZXR1cm4gc2VydmljZUNvbXBvbmVudC5jb25maWd1cmF0aW9uUG9saWN5OwotCX0KLQotCXB1YmxpYyBTdHJpbmcgZ2V0RGVhY3RpdmF0ZSgpIHsKLQkJcmV0dXJuIHNlcnZpY2VDb21wb25lbnQuZGVhY3RpdmF0ZU1ldGhvZE5hbWU7Ci0JfQotCi0JcHVibGljIFN0cmluZyBnZXRGYWN0b3J5KCkgewotCQlyZXR1cm4gc2VydmljZUNvbXBvbmVudC5mYWN0b3J5OwotCX0KLQotCXB1YmxpYyBsb25nIGdldElkKCkgewotCQlyZXR1cm4gKChMb25nKSBwcm9wZXJ0aWVzLmdldChDb21wb25lbnRDb25zdGFudHMuQ09NUE9ORU5UX0lEKSkubG9uZ1ZhbHVlKCk7Ci0JfQotCi0JcHVibGljIFN0cmluZyBnZXRNb2RpZmllZCgpIHsKLQkJaWYgKCFzZXJ2aWNlQ29tcG9uZW50LmlzTmFtZXNwYWNlQXRMZWFzdDExKCkpIHsKLQkJCXJldHVybiBudWxsOwotCQl9Ci0JCXJldHVybiBzZXJ2aWNlQ29tcG9uZW50Lm1vZGlmeU1ldGhvZE5hbWU7Ci0JfQotCi0JcHVibGljIFN0cmluZyBnZXROYW1lKCkgewotCQlyZXR1cm4gc2VydmljZUNvbXBvbmVudC5uYW1lOwotCX0KLQotCXB1YmxpYyBvcmcuYXBhY2hlLmZlbGl4LnNjci5SZWZlcmVuY2VbXSBnZXRSZWZlcmVuY2VzKCkgewotCQlpZiAocmVmZXJlbmNlcyAhPSBudWxsICYmICFyZWZlcmVuY2VzLmlzRW1wdHkoKSkgewotCQkJb3JnLmFwYWNoZS5mZWxpeC5zY3IuUmVmZXJlbmNlW10gcmVzID0gbmV3IG9yZy5hcGFjaGUuZmVsaXguc2NyLlJlZmVyZW5jZVtyZWZlcmVuY2VzLnNpemUoKV07Ci0JCQlyZWZlcmVuY2VzLmNvcHlJbnRvKHJlcyk7Ci0JCQlyZXR1cm4gcmVzOwotCQl9Ci0JCXJldHVybiBudWxsOwotCX0KLQotCXB1YmxpYyBTdHJpbmdbXSBnZXRTZXJ2aWNlcygpIHsKLQkJcmV0dXJuIHNlcnZpY2VDb21wb25lbnQucHJvdmlkZXM7Ci0JfQotCi0JcHVibGljIGJvb2xlYW4gaXNBY3RpdmF0ZURlY2xhcmVkKCkgewotCQlpZiAoIXNlcnZpY2VDb21wb25lbnQuaXNOYW1lc3BhY2VBdExlYXN0MTEoKSkgewotCQkJcmV0dXJuIGZhbHNlOwotCQl9Ci0JCXJldHVybiBzZXJ2aWNlQ29tcG9uZW50LmFjdGl2YXRlTWV0aG9kRGVjbGFyZWQ7Ci0JfQotCi0JcHVibGljIGJvb2xlYW4gaXNEZWFjdGl2YXRlRGVjbGFyZWQoKSB7Ci0JCWlmICghc2VydmljZUNvbXBvbmVudC5pc05hbWVzcGFjZUF0TGVhc3QxMSgpKSB7Ci0JCQlyZXR1cm4gZmFsc2U7Ci0JCX0KLQkJcmV0dXJuIHNlcnZpY2VDb21wb25lbnQuZGVhY3RpdmF0ZU1ldGhvZERlY2xhcmVkOwotCX0KLQotCXB1YmxpYyBib29sZWFuIGlzRGVmYXVsdEVuYWJsZWQoKSB7Ci0JCXJldHVybiBzZXJ2aWNlQ29tcG9uZW50LmF1dG9lbmFibGU7Ci0JfQotCi0JcHVibGljIGJvb2xlYW4gaXNJbW1lZGlhdGUoKSB7Ci0JCXJldHVybiBzZXJ2aWNlQ29tcG9uZW50LmlzSW1tZWRpYXRlKCk7Ci0JfQotCi0JcHVibGljIGJvb2xlYW4gaXNTZXJ2aWNlRmFjdG9yeSgpIHsKLQkJcmV0dXJuIHNlcnZpY2VDb21wb25lbnQuc2VydmljZUZhY3Rvcnk7Ci0JfQotCi0JLy9Tb21lIGhlbHBlciBtZXRob2RzIGFjY29yZGluZyB0byB0aGUgY29tcG9uZW50J3Mgc3RhdGUKLQlwdWJsaWMgYm9vbGVhbiBpc0J1aWx0KCkgewotCQlyZXR1cm4gc3RhdGUgPT0gU1RBVEVfQUNUSVZBVElORyB8fCBzdGF0ZSA9PSBTVEFURV9BQ1RJVkUgfHwgc3RhdGUgPT0gU1RBVEVfRkFDVE9SWSB8fCBzdGF0ZSA9PSBTVEFURV9SRUdJU1RFUkVEOwotCX0KLQotCXB1YmxpYyBib29sZWFuIGlzVW5zYXRpc2ZpZWQoKSB7Ci0JCXJldHVybiBzdGF0ZSA9PSBTVEFURV9VTlNBVElTRklFRCB8fCBzdGF0ZSA9PSBTVEFURV9ERUFDVElWQVRJTkcgfHwgc3RhdGUgPT0gU1RBVEVfRElTQUJMRUQgfHwgc3RhdGUgPT0gU1RBVEVfRElTUE9TSU5HIHx8IHN0YXRlID09IFNUQVRFX0RJU1BPU0VEOwotCX0KLQotfQpkaWZmIC0tZ2l0IGEvYnVuZGxlcy9vcmcuZWNsaXBzZS5lcXVpbm94LmRzL3NyYy9vcmcvZWNsaXBzZS9lcXVpbm94L2ludGVybmFsL2RzL3N0b3JhZ2UvZmlsZS9EQk9iamVjdC5qYXZhIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5lcXVpbm94LmRzL3NyYy9vcmcvZWNsaXBzZS9lcXVpbm94L2ludGVybmFsL2RzL3N0b3JhZ2UvZmlsZS9EQk9iamVjdC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAxZjI2MjAzLi4wMDAwMDAwCi0tLSBhL2J1bmRsZXMvb3JnLmVjbGlwc2UuZXF1aW5veC5kcy9zcmMvb3JnL2VjbGlwc2UvZXF1aW5veC9pbnRlcm5hbC9kcy9zdG9yYWdlL2ZpbGUvREJPYmplY3QuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDcwICswLDAgQEAKLS8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTctMjAwOSBieSBQcm9TeXN0IFNvZnR3YXJlIEdtYkgKLSAqIGh0dHA6Ly93d3cucHJvc3lzdC5jb20KLSAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMKLSAqIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2UgdjEuMAotICogd2hpY2ggYWNjb21wYW5pZXMgdGhpcyBkaXN0cmlidXRpb24sIGFuZCBpcyBhdmFpbGFibGUgYXQKLSAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLXYxMC5odG1sCi0gKgotICogQ29udHJpYnV0b3JzOgotICogICAgUHJvU3lzdCBTb2Z0d2FyZSBHbWJIIC0gaW5pdGlhbCBBUEkgYW5kIGltcGxlbWVudGF0aW9uCi0gKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLXBhY2thZ2Ugb3JnLmVjbGlwc2UuZXF1aW5veC5pbnRlcm5hbC5kcy5zdG9yYWdlLmZpbGU7Ci0KLWltcG9ydCBqYXZhLmlvLio7Ci1pbXBvcnQgamF2YS51dGlsLlZlY3RvcjsKLWltcG9ydCBvcmcuZWNsaXBzZS5lcXVpbm94LmludGVybmFsLmRzLm1vZGVsLlNlcnZpY2VDb21wb25lbnQ7Ci0KLS8qKgotICogVXNlZCBmb3Igc2VyaWFsaXphdGlvbiBvZiB0aGUgRFMgY29tcG9uZW50cwotICogCi0gKiBAYXV0aG9yIE5pbmEgUnVzZXZhCi0gKiBAYXV0aG9yIFBhdmxpbiBEb2JyZXYKLSAqLwotCi1wdWJsaWMgY2xhc3MgREJPYmplY3QgaW1wbGVtZW50cyBTZXJpYWxpemFibGUgewotCXByaXZhdGUgc3RhdGljIGZpbmFsIGxvbmcgc2VyaWFsVmVyc2lvblVJRCA9IDFMOwotCi0JcHVibGljIERCT2JqZWN0KCkgewotCQkvLwotCX0KLQotCXB1YmxpYyBWZWN0b3IgY29tcG9uZW50czsKLQotCXB1YmxpYyBEQk9iamVjdChWZWN0b3IgY29tcG9uZW50cykgewotCQl0aGlzLmNvbXBvbmVudHMgPSBjb21wb25lbnRzOwotCX0KLQotCXB1YmxpYyB2b2lkIHdyaXRlT2JqZWN0KE91dHB1dFN0cmVhbSBvdXQpIHRocm93cyBFeGNlcHRpb24gewotCQlEYXRhT3V0cHV0U3RyZWFtIGRhdGFPdXQ7Ci0JCWlmIChvdXQgaW5zdGFuY2VvZiBEYXRhT3V0cHV0U3RyZWFtKSB7Ci0JCQlkYXRhT3V0ID0gKERhdGFPdXRwdXRTdHJlYW0pIG91dDsKLQkJfSBlbHNlIHsKLQkJCWRhdGFPdXQgPSBuZXcgRGF0YU91dHB1dFN0cmVhbShvdXQpOwotCQl9Ci0JCWRhdGFPdXQud3JpdGVJbnQoY29tcG9uZW50cyA9PSBudWxsID8gMCA6IGNvbXBvbmVudHMuc2l6ZSgpKTsKLQkJaWYgKGNvbXBvbmVudHMgIT0gbnVsbCAmJiBjb21wb25lbnRzLnNpemUoKSA+IDApIHsKLQkJCWZvciAoaW50IGsgPSAwOyBrIDwgY29tcG9uZW50cy5zaXplKCk7IGsrKykgewotCQkJCSgoU2VydmljZUNvbXBvbmVudCkgY29tcG9uZW50cy5lbGVtZW50QXQoaykpLndyaXRlT2JqZWN0KGRhdGFPdXQpOwotCQkJfQotCQl9Ci0JfQotCi0JcHVibGljIHZvaWQgcmVhZE9iamVjdChJbnB1dFN0cmVhbSBpbikgdGhyb3dzIEV4Y2VwdGlvbiB7Ci0JCURhdGFJbnB1dFN0cmVhbSBkYXRhSW47Ci0JCWlmIChpbiBpbnN0YW5jZW9mIERhdGFJbnB1dFN0cmVhbSkgewotCQkJZGF0YUluID0gKERhdGFJbnB1dFN0cmVhbSkgaW47Ci0JCX0gZWxzZSB7Ci0JCQlkYXRhSW4gPSBuZXcgRGF0YUlucHV0U3RyZWFtKGluKTsKLQkJfQotCi0JCWludCBzaXplID0gZGF0YUluLnJlYWRJbnQoKTsKLQkJY29tcG9uZW50cyA9IG5ldyBWZWN0b3IoKTsKLQkJZm9yIChpbnQgayA9IDA7IGsgPCBzaXplOyBrKyspIHsKLQkJCVNlcnZpY2VDb21wb25lbnQgY29tcG9uZW50ID0gbmV3IFNlcnZpY2VDb21wb25lbnQoKTsKLQkJCWNvbXBvbmVudC5yZWFkT2JqZWN0KGRhdGFJbik7Ci0JCQljb21wb25lbnRzLmFkZEVsZW1lbnQoY29tcG9uZW50KTsKLQkJfQotCi0JfQotfQpkaWZmIC0tZ2l0IGEvYnVuZGxlcy9vcmcuZWNsaXBzZS5lcXVpbm94LmRzL3NyYy9vcmcvZWNsaXBzZS9lcXVpbm94L2ludGVybmFsL2RzL3N0b3JhZ2UvZmlsZS9GaWxlU3RvcmFnZS5qYXZhIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5lcXVpbm94LmRzL3NyYy9vcmcvZWNsaXBzZS9lcXVpbm94L2ludGVybmFsL2RzL3N0b3JhZ2UvZmlsZS9GaWxlU3RvcmFnZS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA1Yzg4OWUxLi4wMDAwMDAwCi0tLSBhL2J1bmRsZXMvb3JnLmVjbGlwc2UuZXF1aW5veC5kcy9zcmMvb3JnL2VjbGlwc2UvZXF1aW5veC9pbnRlcm5hbC9kcy9zdG9yYWdlL2ZpbGUvRmlsZVN0b3JhZ2UuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDI1OCArMCwwIEBACi0vKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgotICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDEzIGJ5IFByb1N5c3QgU29mdHdhcmUgR21iSCBhbmQgb3RoZXJzLgotICogaHR0cDovL3d3dy5wcm9zeXN0LmNvbQotICogQWxsIHJpZ2h0cyByZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscwotICogYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2MS4wCi0gKiB3aGljaCBhY2NvbXBhbmllcyB0aGlzIGRpc3RyaWJ1dGlvbiwgYW5kIGlzIGF2YWlsYWJsZSBhdAotICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtdjEwLmh0bWwKLSAqCi0gKiBDb250cmlidXRvcnM6Ci0gKiAgICBQcm9TeXN0IFNvZnR3YXJlIEdtYkggLSBpbml0aWFsIEFQSSBhbmQgaW1wbGVtZW50YXRpb24KLSAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwotcGFja2FnZSBvcmcuZWNsaXBzZS5lcXVpbm94LmludGVybmFsLmRzLnN0b3JhZ2UuZmlsZTsKLQotaW1wb3J0IGphdmEuaW8uKjsKLWltcG9ydCBqYXZhLm5ldC5VUkw7Ci1pbXBvcnQgamF2YS5uZXQuVVJMQ29ubmVjdGlvbjsKLWltcG9ydCBqYXZhLnV0aWwuKjsKLWltcG9ydCBvcmcuZWNsaXBzZS5lcXVpbm94LmludGVybmFsLmRzLio7Ci1pbXBvcnQgb3JnLmVjbGlwc2UuZXF1aW5veC5pbnRlcm5hbC5kcy5tb2RlbC5TZXJ2aWNlQ29tcG9uZW50OwotaW1wb3J0IG9yZy5lY2xpcHNlLmVxdWlub3guaW50ZXJuYWwudXRpbC5pby5FeHRlcm5hbGl6YWJsZURpY3Rpb25hcnk7Ci1pbXBvcnQgb3JnLmVjbGlwc2Uub3NnaS51dGlsLk1hbmlmZXN0RWxlbWVudDsKLWltcG9ydCBvcmcuZWNsaXBzZS5vc2dpLnV0aWwuTkxTOwotaW1wb3J0IG9yZy5vc2dpLmZyYW1ld29yay4qOwotaW1wb3J0IG9yZy5vc2dpLnNlcnZpY2UuY29tcG9uZW50LkNvbXBvbmVudENvbnN0YW50czsKLWltcG9ydCBvcmcub3NnaS5zZXJ2aWNlLmxvZy5Mb2dTZXJ2aWNlOwotCi0vKioKLSAqIFRoaXMgY2xhc3MgaW1wbGVtZW50cyBhIGNhY2hlIGZvciB0aGUgcGFyc2VkIGNvbXBvbmVudCBYTUwgZGVzY3JpcHRpb25zLiAKLSAqIAotICogQGF1dGhvciBQYXZsaW4gRG9icmV2Ci0gKiBAYXV0aG9yIFN0b3lhbiBCb3NoZXYKLSAqLwotCi1wdWJsaWMgY2xhc3MgRmlsZVN0b3JhZ2UgZXh0ZW5kcyBDb21wb25lbnRTdG9yYWdlIHsKLQotCS8vVE9ETzogdGhpcyBjb25zdGFudCBzaG91bGQgYmUgcHVibGljIGFuZCBzaGFyZWQgYWNyb3NzIG90aGVyIGJ1bmRsZXMgdGhhdCB1c2UgdGhlIHNhbWUgcHJvcGVydHkuIAotCS8vUHJvYmFibHkgaXQgc2hvdWxkIGJlIGluIHRoZSBzdXBwbGVtZW50IGJ1bmRsZT8KLQlwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBQUk9QX0NIRUNLX0NPTkZJRyA9ICJvc2dpLmNoZWNrQ29uZmlndXJhdGlvbiI7IC8vJE5PTi1OTFMtMSQKLQotCXByaXZhdGUgc3RhdGljIFN0cmluZyBDVVNUT01fREJfTkFNRSA9ICJTQ1IiOyAvLyROT04tTkxTLTEkCi0JcHJpdmF0ZSBCdW5kbGVDb250ZXh0IGJjID0gbnVsbDsKLQlwcml2YXRlIEV4dGVybmFsaXphYmxlRGljdGlvbmFyeSBkYXRhID0gbmV3IEV4dGVybmFsaXphYmxlRGljdGlvbmFyeSgpOwotCXByaXZhdGUgU3RyaW5nQnVmZmVyIHBhdGhCdWZmZXIgPSBuZXcgU3RyaW5nQnVmZmVyKCk7Ci0JcHJpdmF0ZSBTdHJpbmcgc2VwYXJhdG9yOwotCXByaXZhdGUgYm9vbGVhbiBpc0RpcnR5ID0gZmFsc2U7Ci0KLQlwdWJsaWMgRmlsZVN0b3JhZ2UoQnVuZGxlQ29udGV4dCBiYykgewotCQl0aGlzLmJjID0gYmM7Ci0JCXNlcGFyYXRvciA9IGJjLmdldFByb3BlcnR5KCJwYXRoLnNlcGFyYXRvciIpOyAvLyROT04tTkxTLTEkCi0JCUZpbGUgZmlsZSA9IGJjLmdldERhdGFGaWxlKENVU1RPTV9EQl9OQU1FKTsKLQkJRmlsZUlucHV0U3RyZWFtIGZpcyA9IG51bGw7Ci0JCXRyeSB7Ci0JCQlpZiAoZmlsZSAhPSBudWxsICYmIGZpbGUuZXhpc3RzKCkpIHsKLQkJCQlkYXRhLnJlYWRPYmplY3QobmV3IEJ1ZmZlcmVkSW5wdXRTdHJlYW0oZmlzID0gbmV3IEZpbGVJbnB1dFN0cmVhbShmaWxlKSkpOwotCQkJfQotCQl9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7Ci0JCQlBY3RpdmF0b3IubG9nKG51bGwsIExvZ1NlcnZpY2UuTE9HX0VSUk9SLCBOTFMuYmluZChNZXNzYWdlcy5FUlJPUl9MT0FESU5HX0RBVEFfRklMRSwgZmlsZS5nZXRBYnNvbHV0ZVBhdGgoKSksIGUpOwotCQl9IGNhdGNoIChFeGNlcHRpb24gZSkgewotCQkJQWN0aXZhdG9yLmxvZyhudWxsLCBMb2dTZXJ2aWNlLkxPR19FUlJPUiwgTkxTLmJpbmQoTWVzc2FnZXMuRVJST1JfTE9BRElOR19EQVRBX0ZJTEUsIGZpbGUuZ2V0QWJzb2x1dGVQYXRoKCkpLCBlKTsKLQkJfSBmaW5hbGx5IHsKLQkJCWlmIChmaXMgIT0gbnVsbCkgewotCQkJCXRyeSB7Ci0JCQkJCWZpcy5jbG9zZSgpOwotCQkJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7Ci0JCQkJCS8vIGlnbm9yZQotCQkJCX0KLQkJCX0KLQkJfQotCX0KLQotCXB1YmxpYyBWZWN0b3IgbG9hZENvbXBvbmVudERlZmluaXRpb25zKEJ1bmRsZSBidW5kbGUsIFN0cmluZyBkc0hlYWRlcikgewotCQl0cnkgewotCQkJVmVjdG9yIGNvbXBvbmVudHMgPSBudWxsOwotCQkJaWYgKCFBY3RpdmF0b3IuREJTVE9SRSkgewotCQkJCXJldHVybiBwYXJzZVhNTERlY2xhcmF0aW9uKGJ1bmRsZSwgZHNIZWFkZXIpOwotCQkJfQotCi0JCQlsb25nIGxhc3RNb2RpZmllZDsKLQkJCS8vIGlmIG5vdCBkZXYgbW9kZSwgd2Ugc2ltcGx5IHVzZSB0aGUgYnVuZGxlJ3MgdGltZXN0YW1wCi0JCQlpZiAoIUFjdGl2YXRvci5nZXRCb29sZWFuKFBST1BfQ0hFQ0tfQ09ORklHKSkgewotCQkJCWxhc3RNb2RpZmllZCA9IGJ1bmRsZS5nZXRMYXN0TW9kaWZpZWQoKTsKLQkJCX0gZWxzZSB7Ci0JCQkJbGFzdE1vZGlmaWVkID0gZ2V0TGFzdE1vZGlmaWVkVGltZXN0YW1wKGJ1bmRsZSk7Ci0JCQl9Ci0KLQkJCVN0cmluZ1tdIGRiQnVuZGxlUGF0aCA9IG5ldyBTdHJpbmdbMV07Ci0JCQlkYkJ1bmRsZVBhdGhbMF0gPSBTdHJpbmcudmFsdWVPZihidW5kbGUuZ2V0QnVuZGxlSWQoKSk7Ci0KLQkJCVN0cmluZyBsYXN0TW9kaWZpZWRWYWx1ZSA9IChTdHJpbmcpIGRhdGEuZ2V0KGdldFBhdGgoZGJCdW5kbGVQYXRoKSk7Ci0JCQlpZiAobGFzdE1vZGlmaWVkVmFsdWUgPT0gbnVsbCkgewotCQkJCWNvbXBvbmVudHMgPSBwcm9jZXNzWE1MRGVjbGFyYXRpb25zKGJ1bmRsZSwgZHNIZWFkZXIsIGRiQnVuZGxlUGF0aCwgbGFzdE1vZGlmaWVkKTsKLQkJCX0gZWxzZSB7Ci0JCQkJbG9uZyBkYkxhc3RNb2RpZmllZCA9IExvbmcucGFyc2VMb25nKGxhc3RNb2RpZmllZFZhbHVlKTsKLQkJCQlpZiAobGFzdE1vZGlmaWVkICE9IGRiTGFzdE1vZGlmaWVkKSB7Ci0JCQkJCWNvbXBvbmVudHMgPSBwcm9jZXNzWE1MRGVjbGFyYXRpb25zKGJ1bmRsZSwgZHNIZWFkZXIsIGRiQnVuZGxlUGF0aCwgbGFzdE1vZGlmaWVkKTsKLQkJCQl9IGVsc2UgewotCQkJCQl0cnkgewotCQkJCQkJY29tcG9uZW50cyA9IGxvYWRDb21wb25lbnRzRnJvbURCKGJ1bmRsZSk7Ci0JCQkJCX0gY2F0Y2ggKFRocm93YWJsZSB0KSB7Ci0JCQkJCQlBY3RpdmF0b3IubG9nKG51bGwsIExvZ1NlcnZpY2UuTE9HX0VSUk9SLCBNZXNzYWdlcy5FUlJPUl9MT0FESU5HX0NPTVBPTkVOVFMsIHQpOwotCQkJCQkJLy9iYWNrdXAgcGxhbiAtIHBhcnNlIHRoZSBidW5kbGUncyBjb21wb25lbnQgWE1MIGRlY2xhcmF0aW9ucwotCQkJCQkJY29tcG9uZW50cyA9IHByb2Nlc3NYTUxEZWNsYXJhdGlvbnMoYnVuZGxlLCBkc0hlYWRlciwgZGJCdW5kbGVQYXRoLCBsYXN0TW9kaWZpZWQpOwotCQkJCQl9Ci0JCQkJfQotCQkJfQotCQkJcmV0dXJuIGNvbXBvbmVudHM7Ci0JCX0gY2F0Y2ggKFRocm93YWJsZSBlKSB7Ci0JCQlBY3RpdmF0b3IubG9nKG51bGwsIExvZ1NlcnZpY2UuTE9HX0VSUk9SLCBOTFMuYmluZChNZXNzYWdlcy5QUk9DRVNTSU5HX0JVTkRMRV9GQUlMRUQsIExvbmcudG9TdHJpbmcoYnVuZGxlLmdldEJ1bmRsZUlkKCkpLCBidW5kbGUpLCBlKTsKLQkJCXJldHVybiBudWxsOwotCQl9Ci0JfQotCi0JcHJpdmF0ZSBWZWN0b3IgcHJvY2Vzc1hNTERlY2xhcmF0aW9ucyhCdW5kbGUgYnVuZGxlLCBTdHJpbmcgZHNIZWFkZXIsIFN0cmluZ1tdIGRiQnVuZGxlUGF0aCwgbG9uZyBsYXN0TW9kaWZpZWQpIHRocm93cyBFeGNlcHRpb24gewotCQlWZWN0b3IgY29tcG9uZW50cyA9IHBhcnNlWE1MRGVjbGFyYXRpb24oYnVuZGxlLCBkc0hlYWRlcik7Ci0JCWlmIChjb21wb25lbnRzICE9IG51bGwgJiYgY29tcG9uZW50cy5zaXplKCkgIT0gMCkgewotCQkJZGF0YS5wdXQoZ2V0UGF0aChkYkJ1bmRsZVBhdGgpLCAiIiArIGxhc3RNb2RpZmllZCk7IC8vJE5PTi1OTFMtMSQKLQkJCXNhdmVDb21wb25lbnREZWZpbml0aW9ucyhjb21wb25lbnRzLCBidW5kbGUuZ2V0QnVuZGxlSWQoKSk7Ci0JCX0KLQkJcmV0dXJuIGNvbXBvbmVudHM7Ci0JfQotCi0JcHJpdmF0ZSBWZWN0b3IgbG9hZENvbXBvbmVudHNGcm9tREIoQnVuZGxlIGJ1bmRsZSkgdGhyb3dzIEV4Y2VwdGlvbiB7Ci0JCVN0cmluZ1tdIGRiQ29tcFBhdGggPSBuZXcgU3RyaW5nW10ge251bGwsICJDT01QT05FTlRTIn07IC8vJE5PTi1OTFMtMSQKLQkJU2VydmljZUNvbXBvbmVudCBjdXJyZW50Q29tcG9uZW50ID0gbnVsbDsKLQkJbG9uZyBidW5kbGVJZCA9IGJ1bmRsZS5nZXRCdW5kbGVJZCgpOwotCQlkYkNvbXBQYXRoWzBdID0gU3RyaW5nLnZhbHVlT2YoYnVuZGxlSWQpOwotCQlEQk9iamVjdCB2YWx1ZSA9IG5ldyBEQk9iamVjdCgpOwotCQlieXRlW10gYnl0ZUFyciA9IChieXRlW10pIGRhdGEuZ2V0KGdldFBhdGgoZGJDb21wUGF0aCkpOwotCQlCeXRlQXJyYXlJbnB1dFN0cmVhbSB0bXBJbiA9IG5ldyBCeXRlQXJyYXlJbnB1dFN0cmVhbShieXRlQXJyKTsKLQkJdmFsdWUucmVhZE9iamVjdCh0bXBJbik7Ci0JCVZlY3RvciBjb21wb25lbnRzID0gdmFsdWUuY29tcG9uZW50czsKLQkJaWYgKGNvbXBvbmVudHMgPT0gbnVsbCkgewotCQkJcmV0dXJuIG51bGw7Ci0JCX0KLQkJZm9yIChpbnQgaSA9IDA7IGkgPCBjb21wb25lbnRzLnNpemUoKTsgaSsrKSB7Ci0JCQljdXJyZW50Q29tcG9uZW50ID0gKFNlcnZpY2VDb21wb25lbnQpIGNvbXBvbmVudHMuZWxlbWVudEF0KGkpOwotCQkJY3VycmVudENvbXBvbmVudC5idW5kbGUgPSBidW5kbGU7Ci0JCQljdXJyZW50Q29tcG9uZW50LmJjID0gYnVuZGxlLmdldEJ1bmRsZUNvbnRleHQoKTsKLQkJfQotCQlyZXR1cm4gY29tcG9uZW50czsKLQl9Ci0KLQlwdWJsaWMgdm9pZCBkZWxldGVDb21wb25lbnREZWZpbml0aW9ucyhsb25nIGJ1bmRsZUlEKSB7Ci0JCVN0cmluZ1tdIGRiQnVuZGxlUGF0aCA9IG5ldyBTdHJpbmdbMV07Ci0JCWRiQnVuZGxlUGF0aFswXSA9IFN0cmluZy52YWx1ZU9mKGJ1bmRsZUlEKTsKLQkJZGF0YS5yZW1vdmUoZ2V0UGF0aChkYkJ1bmRsZVBhdGgpKTsKLQkJU3RyaW5nW10gZGJDb21wUGF0aCA9IG5ldyBTdHJpbmdbXSB7bnVsbCwgIkNPTVBPTkVOVFMifTsgLy8kTk9OLU5MUy0xJAotCQlkYkNvbXBQYXRoWzBdID0gU3RyaW5nLnZhbHVlT2YoYnVuZGxlSUQpOwotCQlkYXRhLnJlbW92ZShnZXRQYXRoKGRiQ29tcFBhdGgpKTsKLQkJRmlsZSBmaWxlID0gYmMuZ2V0RGF0YUZpbGUoQ1VTVE9NX0RCX05BTUUpOwotCQlpZiAoZmlsZSAhPSBudWxsICYmIGZpbGUuZXhpc3RzKCkpIHsKLQkJCS8vZGVsZXRlIHRoZSBmaWxlIHRvIHByZXZlbnQgbGVhdmluZyBvbGQgaW5mb3JtYXRpb24gaW4gaXQKLQkJCWZpbGUuZGVsZXRlKCk7Ci0JCX0KLQkJaXNEaXJ0eSA9IHRydWU7Ci0JfQotCi0JcHJpdmF0ZSB2b2lkIHNhdmVDb21wb25lbnREZWZpbml0aW9ucyhWZWN0b3IgY29tcG9uZW50cywgbG9uZyBidW5kbGVJRCkgdGhyb3dzIEV4Y2VwdGlvbiB7Ci0JCXRyeSB7Ci0JCQlpZiAoY29tcG9uZW50cyA9PSBudWxsIHx8IGNvbXBvbmVudHMuc2l6ZSgpID09IDApIHsKLQkJCQlyZXR1cm47Ci0JCQl9Ci0JCQlTdHJpbmdbXSBkYkNvbXBQYXRoID0gbmV3IFN0cmluZ1tdIHtudWxsLCAiQ09NUE9ORU5UUyJ9OyAvLyROT04tTkxTLTEkCi0JCQlkYkNvbXBQYXRoWzBdID0gU3RyaW5nLnZhbHVlT2YoYnVuZGxlSUQpOwotCi0JCQlEQk9iamVjdCB0bXBPYmogPSBuZXcgREJPYmplY3QoY29tcG9uZW50cyk7Ci0JCQlCeXRlQXJyYXlPdXRwdXRTdHJlYW0gYnVmID0gbmV3IEJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOwotCQkJdG1wT2JqLndyaXRlT2JqZWN0KGJ1Zik7Ci0JCQlkYXRhLnB1dChnZXRQYXRoKGRiQ29tcFBhdGgpLCBidWYudG9CeXRlQXJyYXkoKSk7Ci0JCQlpc0RpcnR5ID0gdHJ1ZTsKLQkJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKLQkJCUFjdGl2YXRvci5sb2cobnVsbCwgTG9nU2VydmljZS5MT0dfRVJST1IsIE1lc3NhZ2VzLkVSUk9SX1NBVklOR19DT01QT05FTlRfREVGSU5JVElPTlMsIGUpOwotCQl9Ci0JfQotCi0JcHVibGljIHZvaWQgc3RvcCgpIHsKLQkJaWYgKGlzRGlydHkpIHsKLQkJCXNhdmVGaWxlKCk7Ci0JCX0KLQl9Ci0KLQlwcml2YXRlIHZvaWQgc2F2ZUZpbGUoKSB7Ci0JCUZpbGVPdXRwdXRTdHJlYW0gZm9zID0gbnVsbDsKLQkJdHJ5IHsKLQkJCUZpbGUgZmlsZSA9IGJjLmdldERhdGFGaWxlKENVU1RPTV9EQl9OQU1FKTsKLQkJCWlmIChmaWxlID09IG51bGwpIHsKLQkJCQkvL3NhdmUgb3BlcmF0aW9uIGlzIG5vdCBwb3NzaWJsZQotCQkJCXJldHVybjsKLQkJCX0KLQkJCWZvcyA9IG5ldyBGaWxlT3V0cHV0U3RyZWFtKGZpbGUpOwotCQkJdHJ5IHsKLQkJCQlkYXRhLndyaXRlT2JqZWN0KGZvcyk7Ci0JCQkJaXNEaXJ0eSA9IGZhbHNlOwotCQkJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKLQkJCQlBY3RpdmF0b3IubG9nKG51bGwsIExvZ1NlcnZpY2UuTE9HX0VSUk9SLCBNZXNzYWdlcy5FUlJPUl9XUklUSU5HX09CSkVDVCwgZSk7Ci0JCQl9Ci0JCX0gY2F0Y2ggKEZpbGVOb3RGb3VuZEV4Y2VwdGlvbiBlKSB7Ci0JCQlBY3RpdmF0b3IubG9nKG51bGwsIExvZ1NlcnZpY2UuTE9HX0VSUk9SLCBNZXNzYWdlcy5GSUxFX0RPRVNOVF9FWElTVF9PUl9ESVJFQ1RPUlksIGUpOwotCQl9IGZpbmFsbHkgewotCQkJaWYgKGZvcyAhPSBudWxsKSB7Ci0JCQkJdHJ5IHsKLQkJCQkJZm9zLmNsb3NlKCk7Ci0JCQkJfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewotCQkJCQkvL2lnbm9yZQotCQkJCX0KLQkJCX0KLQkJfQotCX0KLQotCXByaXZhdGUgU3RyaW5nIGdldFBhdGgoU3RyaW5nIHBhdGhbXSkgewotCQlzeW5jaHJvbml6ZWQgKHBhdGhCdWZmZXIpIHsKLQkJCXBhdGhCdWZmZXIuc2V0TGVuZ3RoKDApOwotCQkJZm9yIChpbnQgaSA9IDA7IGkgPCBwYXRoLmxlbmd0aDsgaSsrKSB7Ci0JCQkJcGF0aEJ1ZmZlci5hcHBlbmQocGF0aFtpXSkuYXBwZW5kKHNlcGFyYXRvcik7Ci0JCQl9Ci0JCQlyZXR1cm4gcGF0aEJ1ZmZlci50b1N0cmluZygpOwotCQl9Ci0JfQotCi0JLyoqCi0JICogVGhlIGxhc3QgbW9kaWZpZWQgdGltZXN0YW1wIG9mIHRoZSBidW5kbGUuIFNob3VsZCBvbmx5IGJlIGNhbGxlZCBpbiBkZXZlbG9wbWVudCBtb2RlCi0JICogCi0JICogQHBhcmFtIGJ1bmRsZQotCSAqIEByZXR1cm4gdGhlIGxhc3QgbW9kaWZpZWQgdGltZXN0YW1wIG9mIHRoZSBidW5kbGUKLQkgKi8KLQlwcm90ZWN0ZWQgbG9uZyBnZXRMYXN0TW9kaWZpZWRUaW1lc3RhbXAoQnVuZGxlIGJ1bmRsZSkgewotCQlpZiAoYnVuZGxlID09IG51bGwpCi0JCQlyZXR1cm4gMDsKLQkJbG9uZyByZXN1bHQgPSAwOwotCQlDb2xsZWN0aW9uLyo8VVJMPiovdXJscyA9IGNvbXB1dGVDb21wb25lbnREZWZpbml0aW9uVXJscyhidW5kbGUsIHBhcnNlTWFuaWZlc3RIZWFkZXIoYnVuZGxlKSk7Ci0JCWZvciAoSXRlcmF0b3IvKjxVUkw+Ki9pID0gdXJscy5pdGVyYXRvcigpOyBpLmhhc05leHQoKTspIHsKLQkJCVVSTCB1cmwgPSAoVVJMKSBpLm5leHQoKTsKLQkJCXRyeSB7Ci0JCQkJVVJMQ29ubmVjdGlvbiBjb25uZWN0aW9uID0gdXJsLm9wZW5Db25uZWN0aW9uKCk7Ci0JCQkJbG9uZyBsYXN0TW9kaWZpZWQgPSBjb25uZWN0aW9uLmdldExhc3RNb2RpZmllZCgpOwotCQkJCWlmIChsYXN0TW9kaWZpZWQgPiByZXN1bHQpCi0JCQkJCXJlc3VsdCA9IGxhc3RNb2RpZmllZDsKLQkJCX0gY2F0Y2ggKElPRXhjZXB0aW9uIGUpIHsKLQkJCQkvL2xhc3QgbW9kaWZpZWQgY2Fubm90IGJlIGNhbGN1bGF0ZWQuIHNob3VsZCBmb3JjZSByZXBhcnNlIAotCQkJCXJldHVybiBMb25nLk1BWF9WQUxVRTsKLQkJCX0KLQkJfQotCQlyZXR1cm4gcmVzdWx0OwotCX0KLQotCXByaXZhdGUgTWFuaWZlc3RFbGVtZW50W10gcGFyc2VNYW5pZmVzdEhlYWRlcihCdW5kbGUgYnVuZGxlKSB7Ci0JCURpY3Rpb25hcnkgaGVhZGVycyA9IGJ1bmRsZS5nZXRIZWFkZXJzKCIiKTsgLy8kTk9OLU5MUy0xJAotCQlTdHJpbmcgZmlsZXMgPSAoU3RyaW5nKSBoZWFkZXJzLmdldChDb21wb25lbnRDb25zdGFudHMuU0VSVklDRV9DT01QT05FTlQpOwotCQlpZiAoZmlsZXMgPT0gbnVsbCkKLQkJCXJldHVybiBuZXcgTWFuaWZlc3RFbGVtZW50WzBdOwotCQl0cnkgewotCQkJcmV0dXJuIE1hbmlmZXN0RWxlbWVudC5wYXJzZUhlYWRlcihDb21wb25lbnRDb25zdGFudHMuU0VSVklDRV9DT01QT05FTlQsIGZpbGVzKTsKLQkJfSBjYXRjaCAoQnVuZGxlRXhjZXB0aW9uIGUpIHsKLQkJCUFjdGl2YXRvci5sb2coYnVuZGxlLmdldEJ1bmRsZUNvbnRleHQoKSwgTG9nU2VydmljZS5MT0dfRVJST1IsIE1lc3NhZ2VzLkVSUk9SX1BBUlNJTkdfTUFOSUZFU1RfSEVBREVSLCBlKTsKLQkJCXJldHVybiBuZXcgTWFuaWZlc3RFbGVtZW50WzBdOwotCQl9Ci0JfQotfQpkaWZmIC0tZ2l0IGEvYnVuZGxlcy9vcmcuZWNsaXBzZS5lcXVpbm94LmRzL3NyYy9vcmcvZWNsaXBzZS9lcXVpbm94L2ludGVybmFsL3V0aWwvaW8vRXh0ZXJuYWxpemFibGUuamF2YSBiL2J1bmRsZXMvb3JnLmVjbGlwc2UuZXF1aW5veC5kcy9zcmMvb3JnL2VjbGlwc2UvZXF1aW5veC9pbnRlcm5hbC91dGlsL2lvL0V4dGVybmFsaXphYmxlLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDhhYjE5ZmEuLjAwMDAwMDAKLS0tIGEvYnVuZGxlcy9vcmcuZWNsaXBzZS5lcXVpbm94LmRzL3NyYy9vcmcvZWNsaXBzZS9lcXVpbm94L2ludGVybmFsL3V0aWwvaW8vRXh0ZXJuYWxpemFibGUuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDM3ICswLDAgQEAKLS8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMDggYnkgUHJvU3lzdCBTb2Z0d2FyZSBHbWJICi0gKiBodHRwOi8vd3d3LnByb3N5c3QuY29tCi0gKiBBbGwgcmlnaHRzIHJlc2VydmVkLiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzCi0gKiBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYxLjAKLSAqIHdoaWNoIGFjY29tcGFuaWVzIHRoaXMgZGlzdHJpYnV0aW9uLCBhbmQgaXMgYXZhaWxhYmxlIGF0Ci0gKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC12MTAuaHRtbAotICoKLSAqIENvbnRyaWJ1dG9yczoKLSAqICAgIFByb1N5c3QgU29mdHdhcmUgR21iSCAtIGluaXRpYWwgQVBJIGFuZCBpbXBsZW1lbnRhdGlvbgotICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi1wYWNrYWdlIG9yZy5lY2xpcHNlLmVxdWlub3guaW50ZXJuYWwudXRpbC5pbzsKLQotaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW07Ci1pbXBvcnQgamF2YS5pby5PdXRwdXRTdHJlYW07Ci0KLS8qKgotICogSW50ZXJmYWNlIGZvciBjdXN0b20gc2VyaWFsaXphdGlvbi4gQ2xhc3NlcyB0aGF0IGltcGxlbWVudHMgdGhpcyBpbnRlcmZhY2UKLSAqIG11c3QgaGF2ZSBwdWJsaWMgZW1wdHkgY29uc3RydWN0b3Igc28gZGVzZXJpYWxpemF0aW9uIGNhbiBiZSBkb25lLgotICogCi0gKiBAYXV0aG9yIFBhdmxpbiBEb2JyZXYKLSAqIEB2ZXJzaW9uIDEuMAotICovCi0KLXB1YmxpYyBpbnRlcmZhY2UgRXh0ZXJuYWxpemFibGUgewotCi0JLyoqCi0JICogVXNlIHRoaXMgbWV0aG9kIGZvciBzZXJpYWxpemF0aW9uIG9mIG9iamVjdCBzdGF0ZS4KLQkgKi8KLQlwdWJsaWMgdm9pZCB3cml0ZU9iamVjdChPdXRwdXRTdHJlYW0gb1N0cmVhbSkgdGhyb3dzIEV4Y2VwdGlvbjsKLQotCS8qKgotCSAqIFVzZSB0aGlzIG1ldGhvZCB0byBkZXNlcmlhbGl6aW9uIG9mIG9iamVjdCBzdGF0ZS4KLQkgKi8KLQlwdWJsaWMgdm9pZCByZWFkT2JqZWN0KElucHV0U3RyZWFtIGlTdHJlYW0pIHRocm93cyBFeGNlcHRpb247Ci0KLX0KZGlmZiAtLWdpdCBhL2J1bmRsZXMvb3JnLmVjbGlwc2UuZXF1aW5veC5kcy9zcmMvb3JnL2VjbGlwc2UvZXF1aW5veC9pbnRlcm5hbC91dGlsL2lvL0V4dGVybmFsaXphYmxlRGljdGlvbmFyeS5qYXZhIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5lcXVpbm94LmRzL3NyYy9vcmcvZWNsaXBzZS9lcXVpbm94L2ludGVybmFsL3V0aWwvaW8vRXh0ZXJuYWxpemFibGVEaWN0aW9uYXJ5LmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGZhZDY2MjUuLjAwMDAwMDAKLS0tIGEvYnVuZGxlcy9vcmcuZWNsaXBzZS5lcXVpbm94LmRzL3NyYy9vcmcvZWNsaXBzZS9lcXVpbm94L2ludGVybmFsL3V0aWwvaW8vRXh0ZXJuYWxpemFibGVEaWN0aW9uYXJ5LmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSw3NTkgKzAsMCBAQAotLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKLSAqIENvcHlyaWdodCAoYykgMTk5NywgMjAwOCBieSBQcm9TeXN0IFNvZnR3YXJlIEdtYkgKLSAqIGh0dHA6Ly93d3cucHJvc3lzdC5jb20KLSAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMKLSAqIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2UgdjEuMAotICogd2hpY2ggYWNjb21wYW5pZXMgdGhpcyBkaXN0cmlidXRpb24sIGFuZCBpcyBhdmFpbGFibGUgYXQKLSAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLXYxMC5odG1sCi0gKgotICogQ29udHJpYnV0b3JzOgotICogICAgUHJvU3lzdCBTb2Z0d2FyZSBHbWJIIC0gaW5pdGlhbCBBUEkgYW5kIGltcGxlbWVudGF0aW9uCi0gKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLXBhY2thZ2Ugb3JnLmVjbGlwc2UuZXF1aW5veC5pbnRlcm5hbC51dGlsLmlvOwotCi1pbXBvcnQgamF2YS5pby4qOwotaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0LkFycmF5OwotaW1wb3J0IGphdmEudXRpbC4qOwotCi0vKioKLSAqIFRoaXMgY2xhc3MgaW1wbGVtZW50cyBhIGhhc2h0YWJsZSwgd2hpY2ggc2VydmVzIHRoZSBuZWVkcyBvZgotICogQ29uZmlndXJhdGlvbk1hbmFnZW1lbnQgb2YgY2Fwc3VsYXRpb24gb2YgY29uZmlndXJhdGlvbiBwcm9wZXJ0aWVzIHdpdGgKLSAqIFN0cmluZyBrZXlzLCB3aGljaCBhcmUgY2FzZSBpbnNlbnRpdmUgYXQgbG9va3VwIChhdCBnZXQsIHJlbW92ZSwgcHV0Ci0gKiBvcGVyYXRpb25zKSBidXQgcHJlc2VydmUgdGhlIGxhc3QgY2FzZSBvZiBrZXlzLgotICogCi0gKiBUaGUgaW1wbGVtZW50YWlvbiBvZiB0aGUgRXh0ZXJuYWxpemFibGUgaW50ZXJmYWNlIGFsbG93cyByZW1vdGUgdHJhbnNmZXIgb2YKLSAqIHRob3NlIHByb3BlcnRpZXMuCi0gKiAKLSAqIEBhdXRob3IgUGF2bGluIERvYnJldgotICogQHZlcnNpb24gMS4wCi0gKi8KLQotcHVibGljIGNsYXNzIEV4dGVybmFsaXphYmxlRGljdGlvbmFyeSBleHRlbmRzIERpY3Rpb25hcnkgaW1wbGVtZW50cyBFeHRlcm5hbGl6YWJsZSwgQ2xvbmVhYmxlIHsKLQotCXByaXZhdGUgc3RhdGljIENsYXNzW10gQ0xBU1NFUyA9IG5ldyBDbGFzc1tdIHtFeHRlcm5hbGl6YWJsZURpY3Rpb25hcnkuY2xhc3N9OwotCXByaXZhdGUgSGFzaHRhYmxlRW50cnkgdGFibGVbXTsKLQlwcml2YXRlIGludCBjb3VudDsKLQlwcml2YXRlIGludCB0aHJlc2hvbGQ7Ci0JcHJpdmF0ZSBmbG9hdCBsb2FkRmFjdG9yOwotCXByaXZhdGUgc3RhdGljIGludCBNSU5fQ0FQQUNJVFkgPSA1OwotCi0JQ2xhc3NMb2FkZXIgbG9hZGVyOwotCi0JLyoqCi0JICogQ29uc3RydWN0cyBhIG5ldywgZW1wdHkgZGljdGlvbmFyeSB3aXRoIHRoZSBzcGVjaWZpZWQgaW5pdGlhbCBjYXBhY2l0eQotCSAqIGFuZCB0aGUgc3BlY2lmaWVkIGxvYWQgZmFjdG9yLgotCSAqIAotCSAqIEBwYXJhbSBpbml0aWFsQ2FwYWNpdHkKLQkgKiAgICAgICAgICAgIHRoZSBpbml0aWFsIGNhcGFjaXR5IG9mIHRoZSBoYXNodGFibGUuIHdoZW4gMCBpcyBwYXNzZWQgZm9yCi0JICogICAgICAgICAgICBjYXBhY2l0eSwgbWluaW11bSBwb3NzaWJsZSBjYXBhY2l0eSBpcyB1c2VkOyBpLmUuIHdoZW4gdGhlCi0JICogICAgICAgICAgICBvYmplY3QgaXMgcmVhZCBhcyBleHRlcm5hbGl6YWJsZSwgdGhlbiB0aGUgdGFibGUgaXMgY3JlYXRlZAotCSAqICAgICAgICAgICAgd2l0aCB0aGUgd3JpdHRlbiBzaXplLgotCSAqIEBwYXJhbSBsb2FkRmFjdG9yCi0JICogICAgICAgICAgICBhIG51bWJlciBiZXR3ZWVuIDAuMCBhbmQgMS4wLgotCSAqIEBleGNlcHRpb24gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCi0JICogICAgICAgICAgICAgICAgaWYgdGhlIGluaXRpYWwgY2FwYWNpdHkgaXMgbGVzcyB0aGFuIHplcm8sIG9yIGlmIHRoZSBsb2FkCi0JICogICAgICAgICAgICAgICAgZmFjdG9yIGlzIGxlc3MgdGhhbiBvciBlcXVhbCB0byB6ZXJvLgotCSAqLwotCXB1YmxpYyBFeHRlcm5hbGl6YWJsZURpY3Rpb25hcnkoaW50IGluaXRpYWxDYXBhY2l0eSwgZmxvYXQgbG9hZEZhY3RvcikgewotCQlpZiAoKGluaXRpYWxDYXBhY2l0eSA8IDApIHx8IChsb2FkRmFjdG9yIDw9IDAuMCkpIHsKLQkJCXRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oKTsKLQkJfQotCQl0aGlzLmxvYWRGYWN0b3IgPSBsb2FkRmFjdG9yOwotCQlpZiAoaW5pdGlhbENhcGFjaXR5ID4gMCkKLQkJCWluaXRUYWJsZShpbml0aWFsQ2FwYWNpdHkpOwotCX0KLQotCXByaXZhdGUgdm9pZCBpbml0VGFibGUoaW50IGluaXRpYWxDYXBhY2l0eSkgewotCQl0YWJsZSA9IG5ldyBIYXNodGFibGVFbnRyeVtpbml0aWFsQ2FwYWNpdHldOwotCQl0aHJlc2hvbGQgPSAoaW50KSAoaW5pdGlhbENhcGFjaXR5ICogbG9hZEZhY3Rvcik7Ci0JfQotCi0JLyoqCi0JICogQ29uc3RydWN0cyBhIG5ldywgZW1wdHkgZGljdGlvbmFyeSB3aXRoIHRoZSB3YW50ZWQgY2FwYWNpdHkgYW5kIGRlZmF1bHQKLQkgKiBsb2FkIGZhY3Rvci4KLQkgKi8KLQlwdWJsaWMgRXh0ZXJuYWxpemFibGVEaWN0aW9uYXJ5KGludCBpbml0aWFsQ2FwYWNpdHkpIHsKLQkJdGhpcyhpbml0aWFsQ2FwYWNpdHksIDAuNzVmKTsKLQl9Ci0KLQkvKioKLQkgKiBDb25zdHJ1Y3RzIGEgbmV3LCBlbXB0eSBkaWN0aW9uYXJ5IHdpdGggYSBkZWZhdWx0IGNhcGFjaXR5IGFuZCBsb2FkCi0JICogZmFjdG9yLgotCSAqLwotCXB1YmxpYyBFeHRlcm5hbGl6YWJsZURpY3Rpb25hcnkoKSB7Ci0JCXRoaXMoMTAxLCAwLjc1Zik7Ci0JfQotCi0JcHVibGljIENsYXNzTG9hZGVyIHNldENsYXNzTGFvZGVyKENsYXNzTG9hZGVyIGxvYWRlcikgewotCQlDbGFzc0xvYWRlciB0bXAgPSB0aGlzLmxvYWRlcjsKLQkJdGhpcy5sb2FkZXIgPSBsb2FkZXI7Ci0JCXJldHVybiB0bXA7Ci0JfQotCi0JcHVibGljIENsYXNzTG9hZGVyIHNldENsYXNzTG9hZGVyKENsYXNzTG9hZGVyIGxvYWRlcikgewotCQlDbGFzc0xvYWRlciB0bXAgPSB0aGlzLmxvYWRlcjsKLQkJdGhpcy5sb2FkZXIgPSBsb2FkZXI7Ci0JCXJldHVybiB0bXA7Ci0JfQotCi0JcHVibGljIENsYXNzW10gcmVtb3RlSW50ZXJmYWNlcygpIHsKLQkJcmV0dXJuIENMQVNTRVM7Ci0JfQotCi0JLyoqCi0JICogR2V0cyB0aGUgc2l6ZSBvZiB0aGUgZWxlbWVudHMgaW4gdGhlIGRpY3Rpb25hcnkuCi0JICogCi0JICogQHJldHVybiBzaXplIG9mIGhhc2h0YWJsZQotCSAqLwotCXB1YmxpYyBpbnQgc2l6ZSgpIHsKLQkJcmV0dXJuIGNvdW50OwotCX0KLQotCS8qKgotCSAqIENoZWNrcyBpZiB0aGVyZSBpcyBhbnkgZWxlbWVudCBpbiB0aGUgZGljdGlvbmFyeS4KLQkgKiAKLQkgKiBAcmV0dXJuIHRydWUgaWYgZW1wdHkuCi0JICovCi0JcHVibGljIGJvb2xlYW4gaXNFbXB0eSgpIHsKLQkJcmV0dXJuIGNvdW50ID09IDA7Ci0JfQotCi0JLyoqCi0JICogR2V0cyBhbiBlbnVtZXJhdGlvbiB3aXRoIGRpY3Rpb25hcnkncyBrZXlzLgotCSAqIAotCSAqIEByZXR1cm4gYW4gZW51bWVyYXRpb24gd2l0aCBkaWN0aW9uYXJ5J3Mga2V5cy4KLQkgKi8KLQlwdWJsaWMgc3luY2hyb25pemVkIEVudW1lcmF0aW9uIGtleXMoKSB7Ci0JCXJldHVybiBuZXcgSGFzaHRhYmxlRW51bWVyYXRvcih0YWJsZSwgdHJ1ZSk7Ci0JfQotCi0JLyoqCi0JICogR2V0cyBhbiBlbnVtZXJhdGlvbiB3aXRoIGRpY3Rpb25hcnkncyB2YWx1ZXMuCi0JICogCi0JICogQHJldHVybiBhbiBlbnVtZXJhdGlvbiB3aXRoIGRpY3Rpb25hcnkncyB2YWx1ZXMuCi0JICovCi0JcHVibGljIHN5bmNocm9uaXplZCBFbnVtZXJhdGlvbiBlbGVtZW50cygpIHsKLQkJcmV0dXJuIG5ldyBIYXNodGFibGVFbnVtZXJhdG9yKHRhYmxlLCBmYWxzZSk7Ci0JfQotCi0JcHJpdmF0ZSBpbnQgaGFzaENvZGUoU3RyaW5nIGtleSkgewotCQlyZXR1cm4ga2V5LnRvTG93ZXJDYXNlKCkuaGFzaENvZGUoKTsKLQl9Ci0KLQkvKioKLQkgKiBHZXRzIHRoZSB2YWx1ZSBjb3JyZXNwb25kaW5nIHRvIHRoaXMga2V5IG9yIGFueSBvZiBpdHMgY2FzZQotCSAqIHJlcHJlc2VudGF0aW9ucy4KLQkgKiAKLQkgKiBAcGFyYW0ga2V5Ci0JICogICAgICAgICAgICBTdHJpbmcga2V5Ci0JICogQHJldHVybiBvYmplY3QgdmFsdWUgb3IgbnVsbCBpZiBub25lCi0JICovCi0JcHVibGljIHN5bmNocm9uaXplZCBPYmplY3QgZ2V0KE9iamVjdCBrZXkpIHsKLQkJaWYgKHRhYmxlICE9IG51bGwpIHsKLQkJCUhhc2h0YWJsZUVudHJ5IHRhYltdID0gdGFibGU7Ci0JCQlpbnQgaGFzaCA9IGhhc2hDb2RlKChTdHJpbmcpIGtleSk7Ci0JCQlpbnQgaW5kZXggPSAoaGFzaCAmIDB4N0ZGRkZGRkYpICUgdGFiLmxlbmd0aDsKLQkJCWZvciAoSGFzaHRhYmxlRW50cnkgZSA9IHRhYltpbmRleF07IGUgIT0gbnVsbDsgZSA9IGUubmV4dCkgewotCQkJCWlmICgoZS5oYXNoID09IGhhc2gpICYmIGUua2V5LmVxdWFsc0lnbm9yZUNhc2UoKFN0cmluZykga2V5KSkgewotCQkJCQlyZXR1cm4gZS52YWx1ZTsKLQkJCQl9Ci0JCQl9Ci0JCX0KLQkJcmV0dXJuIG51bGw7Ci0JfQotCi0JcHJvdGVjdGVkIHZvaWQgcmVoYXNoKCkgewotCQlpbnQgb2xkQ2FwYWNpdHkgPSB0YWJsZS5sZW5ndGg7Ci0JCUhhc2h0YWJsZUVudHJ5IG9sZFRhYmxlW10gPSB0YWJsZTsKLQotCQlpbnQgbmV3Q2FwYWNpdHkgPSBvbGRDYXBhY2l0eSAqIDIgKyAxOwotCQlIYXNodGFibGVFbnRyeSBuZXdUYWJsZVtdID0gbmV3IEhhc2h0YWJsZUVudHJ5W25ld0NhcGFjaXR5XTsKLQotCQl0aHJlc2hvbGQgPSAoaW50KSAobmV3Q2FwYWNpdHkgKiBsb2FkRmFjdG9yKTsKLQkJdGFibGUgPSBuZXdUYWJsZTsKLQotCQlmb3IgKGludCBpID0gb2xkQ2FwYWNpdHk7IGktLSA+IDA7KSB7Ci0JCQlmb3IgKEhhc2h0YWJsZUVudHJ5IG9sZCA9IG9sZFRhYmxlW2ldOyBvbGQgIT0gbnVsbDspIHsKLQkJCQlIYXNodGFibGVFbnRyeSBlID0gb2xkOwotCQkJCW9sZCA9IG9sZC5uZXh0OwotCQkJCWludCBpbmRleCA9IChlLmhhc2ggJiAweDdGRkZGRkZGKSAlIG5ld0NhcGFjaXR5OwotCQkJCWUubmV4dCA9IG5ld1RhYmxlW2luZGV4XTsKLQkJCQluZXdUYWJsZVtpbmRleF0gPSBlOwotCQkJfQotCQl9Ci0JfQotCi0JLyoqCi0JICogUHV0cyB0aGUga2V5IGFuZCB0aGUgdmFsdWUgaW4gdGhlIHRhYmxlLiBJZiB0aGVyZSBhbHJlYWR5IGlzIGEga2V5IGVxdWFsCi0JICogaWdub3JlIGNhc2UgdG8gdGhlIG9uZSBwYXNzZWQgdGhlIG5ldyB2YWx1ZSBleGNoaGFuZXMgdGhlIG9sZCBvbmUuCi0JICogCi0JICogQHBhcmFtIGtleQotCSAqICAgICAgICAgICAgU3RyaW5nIGtleQotCSAqIEBwYXJhbSB2YWx1ZQotCSAqICAgICAgICAgICAgb2JqZWN0IHRvIHB1dAotCSAqIEByZXR1cm4gb2xkIHZhbHVlIGlmIGFueSwgb3IgbnVsbCBpZiBub25lCi0JICogQGV4Y2VwdGlvbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KLQkgKiAgICAgICAgICAgICAgICBpZiBrZXkgaXMgbm90IGEgc3RyaW5nCi0JICovCi0JcHVibGljIHN5bmNocm9uaXplZCBPYmplY3QgcHV0KE9iamVjdCBrZXksIE9iamVjdCB2YWx1ZSkgdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB7Ci0KLQkJaWYgKHZhbHVlID09IG51bGwpIHsKLQkJCXRocm93IG5ldyBOdWxsUG9pbnRlckV4Y2VwdGlvbigpOwotCQl9Ci0JCWlmICh0YWJsZSA9PSBudWxsKQotCQkJaW5pdFRhYmxlKE1JTl9DQVBBQ0lUWSk7Ci0JCXRyeSB7Ci0JCQkvLyBNYWtlcyBzdXJlIHRoZSBrZXkgaXMgbm90IGFscmVhZHkgaW4gdGhlIGhhc2h0YWJsZS4KLQkJCWludCBoYXNoID0gaGFzaENvZGUoKFN0cmluZykga2V5KTsKLQkJCWludCBpbmRleDsKLQkJCUhhc2h0YWJsZUVudHJ5W10gdGFiID0gbnVsbDsKLQkJCWRvIHsKLQkJCQl0YWIgPSB0YWJsZTsKLQkJCQlpbmRleCA9IChoYXNoICYgMHg3RkZGRkZGRikgJSB0YWIubGVuZ3RoOwotCQkJCWZvciAoSGFzaHRhYmxlRW50cnkgZSA9IHRhYltpbmRleF07IGUgIT0gbnVsbDsgZSA9IGUubmV4dCkgewotCQkJCQlpZiAoKGUuaGFzaCA9PSBoYXNoKSAmJiBlLmtleS5lcXVhbHNJZ25vcmVDYXNlKChTdHJpbmcpIGtleSkpIHsKLQkJCQkJCU9iamVjdCBvbGQgPSBlLnZhbHVlOwotCQkJCQkJZS52YWx1ZSA9IHZhbHVlOwotCQkJCQkJcmV0dXJuIG9sZDsKLQkJCQkJfQotCQkJCX0KLQkJCQlpZiAoY291bnQgPj0gdGhyZXNob2xkKSB7Ci0JCQkJCS8vIFJlaGFzaCB0aGUgdGFibGUgaWYgdGhlIHRocmVzaG9sZCBpcyBleGNlZWRlZAotCQkJCQlyZWhhc2goKTsKLQkJCQkJY29udGludWU7Ci0JCQkJfQotCQkJCWJyZWFrOwotCQkJfSB3aGlsZSAodHJ1ZSk7Ci0KLQkJCS8vIENyZWF0ZXMgdGhlIG5ldyBlbnRyeS4KLQkJCUhhc2h0YWJsZUVudHJ5IGUgPSBuZXcgSGFzaHRhYmxlRW50cnkoKTsKLQkJCWUuaGFzaCA9IGhhc2g7Ci0JCQllLmtleSA9IChTdHJpbmcpIGtleTsKLQkJCWUudmFsdWUgPSB2YWx1ZTsKLQkJCWUubmV4dCA9IHRhYltpbmRleF07Ci0JCQl0YWJbaW5kZXhdID0gZTsKLQkJCWNvdW50Kys7Ci0JCQlyZXR1cm4gbnVsbDsKLQkJfSBjYXRjaCAoQ2xhc3NDYXN0RXhjZXB0aW9uIGNjZSkgewotCQkJdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiTm9uIHN0cmluZyBrZXlzIGFyZSBub3QgYWNjZXB0ZWQhIik7Ci0JCX0KLQl9Ci0KLQkvKioKLQkgKiBSZW1vdmVzIHRoZSBrZXkgYW5kIGl0cyBjb3JyZXNwb25kaW5nIHZhbHVlLiBLZXkgaXMgc2VhcmNoZWQgY2FzZQotCSAqIGluc2Vuc2l0aXZlbHkuCi0JICogCi0JICogQHBhcmFtIGtleQotCSAqICAgICAgICAgICAgc3RyaW5nIGtleQotCSAqIEByZXR1cm4gb2JqZWN0IHJlbW92ZWQgb3IgbnVsbCBpZiBub25lCi0JICogQGV4Y2VwdGlvbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KLQkgKiAgICAgICAgICAgICAgICBpZiBrZXkgaXMgbm90IHMgc3RyaW5nCi0JICovCi0JcHVibGljIHN5bmNocm9uaXplZCBPYmplY3QgcmVtb3ZlKE9iamVjdCBrZXkpIHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gewotCi0JCWlmICh0YWJsZSA9PSBudWxsKQotCQkJcmV0dXJuIG51bGw7Ci0JCXRyeSB7Ci0JCQlIYXNodGFibGVFbnRyeSB0YWJbXSA9IHRhYmxlOwotCQkJaW50IGhhc2ggPSBoYXNoQ29kZSgoU3RyaW5nKSBrZXkpOwotCQkJaW50IGluZGV4ID0gKGhhc2ggJiAweDdGRkZGRkZGKSAlIHRhYi5sZW5ndGg7Ci0JCQlmb3IgKEhhc2h0YWJsZUVudHJ5IGUgPSB0YWJbaW5kZXhdLCBwcmV2ID0gbnVsbDsgZSAhPSBudWxsOyBwcmV2ID0gZSwgZSA9IGUubmV4dCkgewotCQkJCWlmICgoZS5oYXNoID09IGhhc2gpICYmIGUua2V5LmVxdWFsc0lnbm9yZUNhc2UoKFN0cmluZykga2V5KSkgewotCQkJCQlpZiAocHJldiAhPSBudWxsKSB7Ci0JCQkJCQlwcmV2Lm5leHQgPSBlLm5leHQ7Ci0JCQkJCX0gZWxzZSB7Ci0JCQkJCQl0YWJbaW5kZXhdID0gZS5uZXh0OwotCQkJCQl9Ci0JCQkJCWNvdW50LS07Ci0JCQkJCXJldHVybiBlLnZhbHVlOwotCQkJCX0KLQkJCX0KLQkJCXJldHVybiBudWxsOwotCQl9IGNhdGNoIChDbGFzc0Nhc3RFeGNlcHRpb24gY2NlKSB7Ci0JCQl0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJOb24gc3RyaW5nIGtleXMgYXJlIG5vdCBhY2NlcHRlZCEiKTsKLQkJfQotCX0KLQotCS8qKgotCSAqIENsZWFycyBhbGwgZWxlbWVudHMgZnJvbSB0aGUgZGlzdGlvbmFyeS4KLQkgKi8KLQlwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgY2xlYXIoKSB7Ci0JCWlmICh0YWJsZSA9PSBudWxsKQotCQkJcmV0dXJuOwotCQlmb3IgKGludCBpbmRleCA9IHRhYmxlLmxlbmd0aDsgLS1pbmRleCA+PSAwOykgewotCQkJdGFibGVbaW5kZXhdID0gbnVsbDsKLQkJfQotCQljb3VudCA9IDA7Ci0JfQotCi0JLyoqCi0JICogQ3JlYXRlcyBhIHNoYWxsb3cgY29weSBvZiB0aGlzIGhhc2h0YWJsZS4gVGhlIGtleXMgYW5kIHZhbHVlcyB0aGVtc2VsdmVzCi0JICogYXJlIG5vdCBjbG9uZWQuCi0JICogCi0JICogQHJldHVybiBhIG5ldyBDTURpY3Rpb2Fucnkgd2l0aCB0aGUgc2FtZSBmaWVsZHMKLQkgKi8KLQlwdWJsaWMgc3luY2hyb25pemVkIE9iamVjdCBjbG9uZSgpIHsKLQkJdHJ5IHsKLQkJCUV4dGVybmFsaXphYmxlRGljdGlvbmFyeSBjbURpY3QgPSAoRXh0ZXJuYWxpemFibGVEaWN0aW9uYXJ5KSBzdXBlci5jbG9uZSgpOwotCQkJaWYgKHRhYmxlICE9IG51bGwpIHsKLQkJCQljbURpY3QudGFibGUgPSBuZXcgSGFzaHRhYmxlRW50cnlbdGFibGUubGVuZ3RoXTsKLQkJCQlmb3IgKGludCBpID0gdGFibGUubGVuZ3RoOyBpLS0gPiAwOykgewotCQkJCQljbURpY3QudGFibGVbaV0gPSAodGFibGVbaV0gIT0gbnVsbCkgPyAoSGFzaHRhYmxlRW50cnkpIHRhYmxlW2ldLmNsb25lKCkgOiBudWxsOwotCQkJCX0KLQkJCX0KLQkJCXJldHVybiBjbURpY3Q7Ci0JCX0gY2F0Y2ggKENsb25lTm90U3VwcG9ydGVkRXhjZXB0aW9uIGUpIHsKLQkJCS8vIHRoaXMgc2hvdWxkbid0IGhhcHBlbiwgc2luY2Ugd2UgYXJlIENsb25lYWJsZQotCQkJdGhyb3cgbmV3IEludGVybmFsRXJyb3IoKTsKLQkJfQotCX0KLQotCS8qKgotCSAqIENvbXBhcmVzIHRoZSBzcGVjaWZpZWQgT2JqZWN0IHdpdGggdGhpcyBEaWN0aW9uYXJ5IGZvciBlcXVhbGl0eSwKLQkgKiAKLQkgKiBAcmV0dXJuIHRydWUgaWYgdGhlIHNwZWNpZmllZCBPYmplY3QgaXMgZXF1YWwgdG8gdGhpcyBEaWN0aW9uYXJ5LgotCSAqLwotCi0JcHVibGljIHN5bmNocm9uaXplZCBib29sZWFuIGVxdWFscyhPYmplY3QgbykgewotCQlpZiAobyA9PSB0aGlzKQotCQkJcmV0dXJuIHRydWU7Ci0JCWlmICghKG8gaW5zdGFuY2VvZiBEaWN0aW9uYXJ5KSkKLQkJCXJldHVybiBmYWxzZTsKLQkJRGljdGlvbmFyeSBkaWN0ID0gKERpY3Rpb25hcnkpIG87Ci0JCWludCBtYXggPSBzaXplKCk7Ci0JCWlmIChkaWN0LnNpemUoKSAhPSBtYXgpCi0JCQlyZXR1cm4gZmFsc2U7Ci0JCUVudW1lcmF0aW9uIGsgPSBrZXlzKCk7Ci0JCUVudW1lcmF0aW9uIGUgPSBlbGVtZW50cygpOwotCQlmb3IgKGludCBpID0gMDsgaSA8IG1heDsgaSsrKSB7Ci0JCQlPYmplY3Qga2V5ID0gay5uZXh0RWxlbWVudCgpOwotCQkJT2JqZWN0IHZhbHVlID0gZS5uZXh0RWxlbWVudCgpOwotCQkJaWYgKCF2YWx1ZS5lcXVhbHMoZGljdC5nZXQoa2V5KSkpIHsKLQkJCQlyZXR1cm4gZmFsc2U7Ci0JCQl9Ci0JCX0KLQkJcmV0dXJuIHRydWU7Ci0JfQotCi0JLyoqCi0JICogTWFrZXMgYSBzdHJpbmcgcmVwcmVzbnRhdGlvbiBvZiB0aGlzIG9iamVjdC4KLQkgKiAKLQkgKiBAcmV0dXJuIHN0cmluZyByZXByZXNudGF0aW9uIG9mIHRoaXMgb2JqZWN0Ci0JICovCi0JcHVibGljIHN5bmNocm9uaXplZCBTdHJpbmcgdG9TdHJpbmcoKSB7Ci0JCWludCBtYXggPSBzaXplKCkgLSAxOwotCQlTdHJpbmdCdWZmZXIgYnVmID0gbmV3IFN0cmluZ0J1ZmZlcigpOwotCQlFbnVtZXJhdGlvbiBrID0ga2V5cygpOwotCQlFbnVtZXJhdGlvbiBlID0gZWxlbWVudHMoKTsKLQkJYnVmLmFwcGVuZCgneycpOwotCQlmb3IgKGludCBpID0gMDsgaSA8PSBtYXg7IGkrKykgewotCQkJU3RyaW5nIHMxID0gKFN0cmluZykgay5uZXh0RWxlbWVudCgpOwotCQkJU3RyaW5nIHMyID0gZS5uZXh0RWxlbWVudCgpLnRvU3RyaW5nKCk7Ci0JCQlidWYuYXBwZW5kKHMxKTsKLQkJCWJ1Zi5hcHBlbmQoJz0nKTsKLQkJCWJ1Zi5hcHBlbmQoczIpOwotCQkJaWYgKGkgPCBtYXgpIHsKLQkJCQlidWYuYXBwZW5kKCcsJyk7Ci0JCQkJYnVmLmFwcGVuZCgnICcpOwotCQkJfQotCQl9Ci0JCWJ1Zi5hcHBlbmQoJ30nKTsKLQkJcmV0dXJuIGJ1Zi50b1N0cmluZygpOwotCX0KLQotCS8qKgotCSAqIFdyaXRlcyB0aGlzIG9iamVjdCB0byB0aGUgc3RyZWFtIHBhc3NlZC4gVGhlIG9iamVjdCBjYW4gYmUgbG9hZGVkIGFnYWluCi0JICogdmlhIGl0cyByZWFkT2JqZWN0IG1ldGhvZC4KLQkgKiAKLQkgKiBAcGFyYW0gb3MKLQkgKiAgICAgICAgICAgIHN0cnJlYW0gdG8gd3JpdGUgZGF0YSB0by4KLQkgKiBAZXhjZXB0aW9uIEV4Y2VwdGlvbgotCSAqICAgICAgICAgICAgICAgIGlmIGVycm9yIG9mIGFueSBraW5kIG9jY3VycwotCSAqLwotCXB1YmxpYyBzeW5jaHJvbml6ZWQgdm9pZCB3cml0ZU9iamVjdChPdXRwdXRTdHJlYW0gb3MpIHRocm93cyBFeGNlcHRpb24gewotCQlFbnVtZXJhdGlvbiBrZXlzID0ga2V5cygpOwotCQlFbnVtZXJhdGlvbiB2YWx1ZXMgPSBlbGVtZW50cygpOwotCQlQRGF0YVN0cmVhbS53cml0ZUludChzaXplKCksIG9zKTsKLQkJLy8gZGljdGlvbmFyeSBpcyBuZXZlciBlbXB0eToKLQkJLy8gaXQgZWl0aGVyIGhhcyBlbGVtZW50cyBvciBpcyBudWxsCi0JCXdoaWxlIChrZXlzLmhhc01vcmVFbGVtZW50cygpKSB7Ci0JCQlQRGF0YVN0cmVhbS53cml0ZVVURigoU3RyaW5nKSBrZXlzLm5leHRFbGVtZW50KCksIG9zKTsKLQkJCXdyaXRlVmFsdWUodmFsdWVzLm5leHRFbGVtZW50KCksIG9zKTsKLQkJfQotCX0KLQotCXByaXZhdGUgc3RhdGljIHZvaWQgd3JpdGVWYWx1ZShPYmplY3QgdmFsdWUsIE91dHB1dFN0cmVhbSBvcykgdGhyb3dzIElPRXhjZXB0aW9uIHsKLQotCQlpZiAodmFsdWUgPT0gbnVsbCkgewotCQkJb3Mud3JpdGUoLTEpOwotCQl9IGVsc2UgewotCQkJQ2xhc3MgdmFsdWVDbGFzcyA9IHZhbHVlLmdldENsYXNzKCk7Ci0JCQkvLyB3cml0ZSAwIGZvciBhIHNpbmdsZSB2YWx1ZSwgMSBmb3IgYXJyYXksIGFuZCAyIGZvciBWZWN0b3IKLQkJCWlmICh2YWx1ZUNsYXNzLmlzQXJyYXkoKSkgewotCQkJCW9zLndyaXRlKDEpOwotCQkJCWludCBsZW5ndGggPSBBcnJheS5nZXRMZW5ndGgodmFsdWUpOwotCQkJCVBEYXRhU3RyZWFtLndyaXRlSW50KGxlbmd0aCwgb3MpOwotCQkJCUNsYXNzIGNvbXBvbmVudFR5cGUgPSB2YWx1ZUNsYXNzLmdldENvbXBvbmVudFR5cGUoKTsKLQkJCQlpZiAoY29tcG9uZW50VHlwZS5pc1ByaW1pdGl2ZSgpKSB7Ci0JCQkJCS8vIHByaW1pdGl2ZQotCQkJCQlQRGF0YVN0cmVhbS53cml0ZUJvb2xlYW4odHJ1ZSwgb3MpOwotCQkJCQkvLyAxOiBpbnQ7MjogbG9uZzsgMzogYnl0ZTsgNDogYm9vbGVhbjsgNTogY2hhcmFjdGVyOyA2OgotCQkJCQkvLyBzaG9ydDsgNzogZmxvYXQ7IDg6IGRvdWJsZQotCQkJCQl3cml0ZVByaW1pdGl2ZUFycmF5KGNvbXBvbmVudFR5cGUsIHZhbHVlLCBsZW5ndGgsIG9zKTsKLQkJCQl9IGVsc2UgewotCQkJCQlQRGF0YVN0cmVhbS53cml0ZUJvb2xlYW4oZmFsc2UsIG9zKTsKLQkJCQkJUERhdGFTdHJlYW0ud3JpdGVVVEYoY29tcG9uZW50VHlwZS5nZXROYW1lKCksIG9zKTsKLQkJCQkJT2JqZWN0W10gb0FyciA9IChPYmplY3RbXSkgdmFsdWU7Ci0JCQkJCWZvciAoaW50IGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHsKLQkJCQkJCXdyaXRlVmFsdWUob0FycltpXSwgb3MpOwotCQkJCQl9Ci0JCQkJfQotCQkJfSBlbHNlIGlmICh2YWx1ZUNsYXNzLmVxdWFscyhWZWN0b3IuY2xhc3MpKSB7Ci0JCQkJb3Mud3JpdGUoMik7Ci0JCQkJaW50IHNpemUgPSAoKFZlY3RvcikgdmFsdWUpLnNpemUoKTsKLQkJCQlQRGF0YVN0cmVhbS53cml0ZUludChzaXplLCBvcyk7Ci0JCQkJZm9yIChpbnQgaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKLQkJCQkJd3JpdGVWYWx1ZSgoKFZlY3RvcikgdmFsdWUpLmVsZW1lbnRBdChpKSwgb3MpOwotCQkJCX0KLQkJCX0gZWxzZSB7Ci0JCQkJb3Mud3JpdGUoMCk7Ci0JCQkJd3JpdGVSZWFsT2JqZWN0KHZhbHVlLCB2YWx1ZUNsYXNzLCBvcyk7Ci0JCQl9Ci0JCX0KLQl9Ci0KLQlwcml2YXRlIHN0YXRpYyBPYmplY3QgcmVhZFZhbHVlKElucHV0U3RyZWFtIGlzLCBDbGFzc0xvYWRlciBsb2FkZXIpIHRocm93cyBFeGNlcHRpb24gewotCQlieXRlIHR5cGUgPSAoYnl0ZSkgaXMucmVhZCgpOwotCQlpZiAodHlwZSA9PSAtMSkgewotCQkJcmV0dXJuIG51bGw7Ci0JCX0KLQkJQ2xhc3MgdkNsYXNzID0gbnVsbDsKLQkJaWYgKHR5cGUgPT0gMikgewotCQkJaW50IGxlbmd0aCA9IFBEYXRhU3RyZWFtLnJlYWRJbnQoaXMpOwotCQkJVmVjdG9yIHYgPSBuZXcgVmVjdG9yKGxlbmd0aCk7Ci0JCQlmb3IgKGludCBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7Ci0JCQkJdi5pbnNlcnRFbGVtZW50QXQocmVhZFZhbHVlKGlzLCBsb2FkZXIpLCBpKTsKLQkJCX0KLQkJCXJldHVybiB2OwotCQl9IGVsc2UgaWYgKHR5cGUgPT0gMCkgewotCQkJcmV0dXJuIHJlYWRSZWFsT2JqZWN0KChieXRlKSBpcy5yZWFkKCksIGlzLCBsb2FkZXIpOwotCQl9IGVsc2UgewotCQkJaW50IGxlbmd0aCA9IFBEYXRhU3RyZWFtLnJlYWRJbnQoaXMpOwotCQkJYm9vbGVhbiBwcmltaXRpdmUgPSBQRGF0YVN0cmVhbS5yZWFkQm9vbGVhbihpcyk7Ci0JCQlpZiAocHJpbWl0aXZlKSB7Ci0JCQkJcmV0dXJuIHJlYWRQcmltaXRpdmVBcnJheShsZW5ndGgsIGlzKTsKLQkJCX0KLQkJCXZDbGFzcyA9IGxvYWRlciA9PSBudWxsID8gQ2xhc3MuZm9yTmFtZShQRGF0YVN0cmVhbS5yZWFkVVRGKGlzKSkgOiBsb2FkZXIubG9hZENsYXNzKFBEYXRhU3RyZWFtLnJlYWRVVEYoaXMpKTsKLQkJCU9iamVjdCBhcnJheSA9IEFycmF5Lm5ld0luc3RhbmNlKHZDbGFzcywgbGVuZ3RoKTsKLQkJCWZvciAoaW50IGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHsKLQkJCQlBcnJheS5zZXQoYXJyYXksIGksIHJlYWRWYWx1ZShpcywgbG9hZGVyKSk7Ci0JCQl9Ci0JCQlyZXR1cm4gYXJyYXk7Ci0JCX0KLQl9Ci0KLQkvKioKLQkgKiBSZWFkcyB0aGUgZGF0YSBmcm9tIHRoZSBJbnB1dFN0cmVhbSBhbmQgbG9hZHMgdGhlIGRhdGEgaW4gdGhlIHRhYmxlLgotCSAqIAotCSAqIEBwYXJhbSBpcwotCSAqICAgICAgICAgICAgc3RyZWFtIHRvIHJlYWQgZGljdGlvbmFyeSdzIGRhdGEgZnJvbQotCSAqIEBleGNlcHRpb24gRXhjZXB0aW9uCi0JICogICAgICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2YgYW55IGtpbmQgb2NjdXJzIHdoaWxlIHJlYWRpbmcKLQkgKi8KLQlwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgcmVhZE9iamVjdChJbnB1dFN0cmVhbSBpcykgdGhyb3dzIEV4Y2VwdGlvbiB7Ci0JCXRyeSB7Ci0JCQlpbnQgc2l6ZSA9IFBEYXRhU3RyZWFtLnJlYWRJbnQoaXMpOwotCQkJaWYgKHRhYmxlID09IG51bGwpIHsKLQkJCQlpZiAoc2l6ZSA+IDApIHsKLQkJCQkJaW5pdFRhYmxlKHNpemUpOwotCQkJCX0gZWxzZQotCQkJCQlpbml0VGFibGUoTUlOX0NBUEFDSVRZKTsKLQkJCX0KLQkJCWZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7Ci0JCQkJcHV0KFBEYXRhU3RyZWFtLnJlYWRVVEYoaXMpLCByZWFkVmFsdWUoaXMsIGxvYWRlcikpOwotCQkJfQotCQl9IGNhdGNoIChFeGNlcHRpb24gZSkgewotCQkJdGhyb3cgZTsKLQkJfQotCX0KLQotCS8vIDE6IGludDsyOiBsb25nOyAzOiBieXRlOyA0OiBib29sZWFuOyA1OiBjaGFyYWN0ZXI7Ci0JLy8gNjogc2hvcnQ7IDc6IGZsb2F0OyA4OiBkb3VibGUKLQlwcml2YXRlIHN0YXRpYyB2b2lkIHdyaXRlUHJpbWl0aXZlQXJyYXkoQ2xhc3MgY29tcG9uZW50VHlwZSwgT2JqZWN0IGFycmF5LCBpbnQgbGVuZ3RoLCBPdXRwdXRTdHJlYW0gb3MpIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0KLQkJaWYgKGNvbXBvbmVudFR5cGUuZXF1YWxzKEludGVnZXIuVFlQRSkpIHsKLQkJCWludFtdIGludHMgPSAoaW50W10pIGFycmF5OwotCQkJb3Mud3JpdGUoMSk7Ci0JCQlmb3IgKGludCBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7Ci0JCQkJUERhdGFTdHJlYW0ud3JpdGVJbnQoaW50c1tpXSwgb3MpOwotCQkJfQotCQl9IGVsc2UgaWYgKGNvbXBvbmVudFR5cGUuZXF1YWxzKExvbmcuVFlQRSkpIHsKLQkJCW9zLndyaXRlKDIpOwotCQkJbG9uZ1tdIGxvbmdzID0gKGxvbmdbXSkgYXJyYXk7Ci0JCQlmb3IgKGludCBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7Ci0JCQkJUERhdGFTdHJlYW0ud3JpdGVMb25nKGxvbmdzW2ldLCBvcyk7Ci0JCQl9Ci0JCX0gZWxzZSBpZiAoY29tcG9uZW50VHlwZS5lcXVhbHMoQnl0ZS5UWVBFKSkgewotCQkJb3Mud3JpdGUoMyk7Ci0JCQlvcy53cml0ZSgoYnl0ZVtdKSBhcnJheSk7Ci0JCX0gZWxzZSBpZiAoY29tcG9uZW50VHlwZS5lcXVhbHMoQm9vbGVhbi5UWVBFKSkgewotCQkJb3Mud3JpdGUoNCk7Ci0JCQlib29sZWFuW10gYm9vbGVhbnMgPSAoYm9vbGVhbltdKSBhcnJheTsKLQkJCWZvciAoaW50IGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHsKLQkJCQlQRGF0YVN0cmVhbS53cml0ZUJvb2xlYW4oYm9vbGVhbnNbaV0sIG9zKTsKLQkJCX0KLQkJfSBlbHNlIGlmIChjb21wb25lbnRUeXBlLmVxdWFscyhDaGFyYWN0ZXIuVFlQRSkpIHsKLQkJCW9zLndyaXRlKDUpOwotCQkJY2hhcltdIGNoYXJzID0gKGNoYXJbXSkgYXJyYXk7Ci0JCQlmb3IgKGludCBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7Ci0JCQkJUERhdGFTdHJlYW0ud3JpdGVDaGFyKGNoYXJzW2ldLCBvcyk7Ci0JCQl9Ci0JCX0gZWxzZSBpZiAoY29tcG9uZW50VHlwZS5lcXVhbHMoU2hvcnQuVFlQRSkpIHsKLQkJCW9zLndyaXRlKDYpOwotCQkJc2hvcnRbXSBzaG9ydHMgPSAoc2hvcnRbXSkgYXJyYXk7Ci0JCQlmb3IgKGludCBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7Ci0JCQkJUERhdGFTdHJlYW0ud3JpdGVTaG9ydChzaG9ydHNbaV0sIG9zKTsKLQkJCX0KLQkJfSBlbHNlIGlmIChjb21wb25lbnRUeXBlLmVxdWFscyhGbG9hdC5UWVBFKSkgewotCQkJb3Mud3JpdGUoNyk7Ci0JCQlmbG9hdFtdIGZsb2F0cyA9IChmbG9hdFtdKSBhcnJheTsKLQkJCWZvciAoaW50IGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHsKLQkJCQlQRGF0YVN0cmVhbS53cml0ZUZsb2F0KGZsb2F0c1tpXSwgb3MpOwotCQkJfQotCQl9IGVsc2UgaWYgKGNvbXBvbmVudFR5cGUuZXF1YWxzKERvdWJsZS5UWVBFKSkgewotCQkJb3Mud3JpdGUoOCk7Ci0JCQlkb3VibGVbXSBkb3VibGVzID0gKGRvdWJsZVtdKSBhcnJheTsKLQkJCWZvciAoaW50IGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHsKLQkJCQlQRGF0YVN0cmVhbS53cml0ZURvdWJsZShkb3VibGVzW2ldLCBvcyk7Ci0JCQl9Ci0JCX0gZWxzZSB7Ci0JCQl0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJVbnN1cHBvcnRlZCBQcmltaXRpdmUgVHlwZTogIiArIGNvbXBvbmVudFR5cGUpOwotCQl9Ci0JfQotCi0JcHJpdmF0ZSBzdGF0aWMgT2JqZWN0IHJlYWRQcmltaXRpdmVBcnJheShpbnQgbGVuZ3RoLCBJbnB1dFN0cmVhbSBpcykgdGhyb3dzIElPRXhjZXB0aW9uIHsKLQkJYnl0ZSB0eXBlID0gKGJ5dGUpIGlzLnJlYWQoKTsKLQkJaWYgKHR5cGUgPT0gMSkgewotCQkJaW50W10gaW50cyA9IG5ldyBpbnRbbGVuZ3RoXTsKLQkJCWZvciAoaW50IGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHsKLQkJCQlpbnRzW2ldID0gUERhdGFTdHJlYW0ucmVhZEludChpcyk7Ci0JCQl9Ci0JCQlyZXR1cm4gaW50czsKLQkJfSBlbHNlIGlmICh0eXBlID09IDIpIHsKLQkJCWxvbmdbXSBsb25ncyA9IG5ldyBsb25nW2xlbmd0aF07Ci0JCQlmb3IgKGludCBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7Ci0JCQkJbG9uZ3NbaV0gPSBQRGF0YVN0cmVhbS5yZWFkTG9uZyhpcyk7Ci0JCQl9Ci0JCQlyZXR1cm4gbG9uZ3M7Ci0JCX0gZWxzZSBpZiAodHlwZSA9PSAzKSB7Ci0JCQlieXRlW10gYnl0ZXMgPSBuZXcgYnl0ZVtsZW5ndGhdOwotCQkJaXMucmVhZChieXRlcyk7Ci0JCQlyZXR1cm4gYnl0ZXM7Ci0JCX0gZWxzZSBpZiAodHlwZSA9PSA0KSB7Ci0JCQlib29sZWFuW10gYm9vbGVhbnMgPSBuZXcgYm9vbGVhbltsZW5ndGhdOwotCQkJZm9yIChpbnQgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykgewotCQkJCWJvb2xlYW5zW2ldID0gUERhdGFTdHJlYW0ucmVhZEJvb2xlYW4oaXMpOwotCQkJfQotCQkJcmV0dXJuIGJvb2xlYW5zOwotCQl9IGVsc2UgaWYgKHR5cGUgPT0gNSkgewotCQkJY2hhcltdIGNoYXJzID0gbmV3IGNoYXJbbGVuZ3RoXTsKLQkJCWZvciAoaW50IGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHsKLQkJCQljaGFyc1tpXSA9IFBEYXRhU3RyZWFtLnJlYWRDaGFyKGlzKTsKLQkJCX0KLQkJCXJldHVybiBjaGFyczsKLQkJfSBlbHNlIGlmICh0eXBlID09IDYpIHsKLQkJCXNob3J0W10gc2hvcnRzID0gbmV3IHNob3J0W2xlbmd0aF07Ci0JCQlmb3IgKGludCBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7Ci0JCQkJc2hvcnRzW2ldID0gUERhdGFTdHJlYW0ucmVhZFNob3J0KGlzKTsKLQkJCX0KLQkJCXJldHVybiBzaG9ydHM7Ci0JCX0gZWxzZSBpZiAodHlwZSA9PSA3KSB7Ci0JCQlmbG9hdFtdIGZsb2F0cyA9IG5ldyBmbG9hdFtsZW5ndGhdOwotCQkJZm9yIChpbnQgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykgewotCQkJCWZsb2F0c1tpXSA9IFBEYXRhU3RyZWFtLnJlYWRGbG9hdChpcyk7Ci0JCQl9Ci0JCQlyZXR1cm4gZmxvYXRzOwotCQl9IGVsc2UgaWYgKHR5cGUgPT0gOCkgewotCQkJZG91YmxlW10gZG91YmxlcyA9IG5ldyBkb3VibGVbbGVuZ3RoXTsKLQkJCWZvciAoaW50IGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHsKLQkJCQlkb3VibGVzW2ldID0gUERhdGFTdHJlYW0ucmVhZERvdWJsZShpcyk7Ci0JCQl9Ci0JCQlyZXR1cm4gZG91YmxlczsKLQkJfSBlbHNlIHsKLQkJCXRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIlRyeWluZyB0byByZWFkIHVuc3VwcG9ydGVkIHByaW1pdGl2ZSB0eXBlOiAiICsgdHlwZSk7Ci0JCX0KLQl9Ci0KLQkvLyBvbmx5IGlmIHRoaXMgaXMgYW4gb2JqZWN0IChub3QgcHJpbWl0aXZlKSBhbmQgbm9uIG51bGwhCi0JcHJpdmF0ZSBzdGF0aWMgdm9pZCB3cml0ZVJlYWxPYmplY3QoT2JqZWN0IHZhbHVlLCBDbGFzcyB2Q2xhc3MsIE91dHB1dFN0cmVhbSBvcykgdGhyb3dzIElPRXhjZXB0aW9uIHsKLQkJdHJ5IHsKLQkJCWlmICh2Q2xhc3MuZXF1YWxzKFN0cmluZy5jbGFzcykpIHsKLQkJCQlvcy53cml0ZSgwKTsKLQkJCQlQRGF0YVN0cmVhbS53cml0ZVVURigoU3RyaW5nKSB2YWx1ZSwgb3MpOwotCQkJfSBlbHNlIGlmICh2Q2xhc3MuZXF1YWxzKEludGVnZXIuY2xhc3MpKSB7Ci0JCQkJb3Mud3JpdGUoMSk7Ci0JCQkJUERhdGFTdHJlYW0ud3JpdGVJbnQoKChJbnRlZ2VyKSB2YWx1ZSkuaW50VmFsdWUoKSwgb3MpOwotCQkJfSBlbHNlIGlmICh2Q2xhc3MuZXF1YWxzKExvbmcuY2xhc3MpKSB7Ci0JCQkJb3Mud3JpdGUoMik7Ci0JCQkJUERhdGFTdHJlYW0ud3JpdGVMb25nKCgoTG9uZykgdmFsdWUpLmxvbmdWYWx1ZSgpLCBvcyk7Ci0JCQl9IGVsc2UgaWYgKHZDbGFzcy5lcXVhbHMoQnl0ZS5jbGFzcykpIHsKLQkJCQlvcy53cml0ZSgzKTsKLQkJCQlvcy53cml0ZSgoKEJ5dGUpIHZhbHVlKS5ieXRlVmFsdWUoKSk7Ci0JCQl9IGVsc2UgaWYgKHZDbGFzcy5lcXVhbHMoQm9vbGVhbi5jbGFzcykpIHsKLQkJCQlvcy53cml0ZSg0KTsKLQkJCQlQRGF0YVN0cmVhbS53cml0ZUJvb2xlYW4oKChCb29sZWFuKSB2YWx1ZSkuYm9vbGVhblZhbHVlKCksIG9zKTsKLQkJCX0gZWxzZSBpZiAodkNsYXNzLmVxdWFscyhDaGFyYWN0ZXIuY2xhc3MpKSB7Ci0JCQkJb3Mud3JpdGUoNSk7Ci0JCQkJUERhdGFTdHJlYW0ud3JpdGVDaGFyKCgoQ2hhcmFjdGVyKSB2YWx1ZSkuY2hhclZhbHVlKCksIG9zKTsKLQkJCX0gZWxzZSBpZiAodkNsYXNzLmVxdWFscyhTaG9ydC5jbGFzcykpIHsKLQkJCQlvcy53cml0ZSg2KTsKLQkJCQlQRGF0YVN0cmVhbS53cml0ZVNob3J0KCgoU2hvcnQpIHZhbHVlKS5zaG9ydFZhbHVlKCksIG9zKTsKLQkJCX0gZWxzZSBpZiAodkNsYXNzLmVxdWFscyhGbG9hdC5jbGFzcykpIHsKLQkJCQlvcy53cml0ZSg3KTsKLQkJCQlQRGF0YVN0cmVhbS53cml0ZUZsb2F0KCgoRmxvYXQpIHZhbHVlKS5mbG9hdFZhbHVlKCksIG9zKTsKLQkJCX0gZWxzZSBpZiAodkNsYXNzLmVxdWFscyhEb3VibGUuY2xhc3MpKSB7Ci0JCQkJb3Mud3JpdGUoOCk7Ci0JCQkJUERhdGFTdHJlYW0ud3JpdGVEb3VibGUoKChEb3VibGUpIHZhbHVlKS5kb3VibGVWYWx1ZSgpLCBvcyk7Ci0JCQl9IGVsc2UgaWYgKEV4dGVybmFsaXphYmxlLmNsYXNzLmlzQXNzaWduYWJsZUZyb20odkNsYXNzKSkgewotCQkJCW9zLndyaXRlKDExKTsKLQkJCQlTdHJpbmcgbmFtZSA9IHZDbGFzcy5nZXROYW1lKCk7Ci0JCQkJUERhdGFTdHJlYW0ud3JpdGVVVEYobmFtZSwgb3MpOwotCQkJCUV4dGVybmFsaXphYmxlIHRtcCA9IChFeHRlcm5hbGl6YWJsZSkgdmFsdWU7Ci0JCQkJdG1wLndyaXRlT2JqZWN0KG9zKTsKLQkJCX0gZWxzZSB7Ci0JCQkJb3Mud3JpdGUoMTIpOwotCQkJCU9iamVjdE91dHB1dFN0cmVhbSBvdXQgPSBuZXcgT2JqZWN0T3V0cHV0U3RyZWFtKG9zKTsKLQkJCQlvdXQud3JpdGVPYmplY3QodmFsdWUpOwotCQkJfQotCQl9IGNhdGNoIChFeGNlcHRpb24gZXhjKSB7Ci0JCQl0aHJvdyBuZXcgSU9FeGNlcHRpb24oZXhjLnRvU3RyaW5nKCkpOwotCQl9Ci0JfQotCi0JcHJpdmF0ZSBzdGF0aWMgT2JqZWN0IHJlYWRSZWFsT2JqZWN0KGJ5dGUgdHlwZSwgSW5wdXRTdHJlYW0gaXMsIENsYXNzTG9hZGVyIGxvYWRlcikgdGhyb3dzIElPRXhjZXB0aW9uIHsKLQkJdHJ5IHsKLQkJCWlmICh0eXBlID09IDApIHsKLQkJCQlyZXR1cm4gUERhdGFTdHJlYW0ucmVhZFVURihpcyk7Ci0JCQl9IGVsc2UgaWYgKHR5cGUgPT0gMSkgewotCQkJCXJldHVybiBuZXcgSW50ZWdlcihQRGF0YVN0cmVhbS5yZWFkSW50KGlzKSk7Ci0JCQl9IGVsc2UgaWYgKHR5cGUgPT0gMikgewotCQkJCXJldHVybiBuZXcgTG9uZyhQRGF0YVN0cmVhbS5yZWFkTG9uZyhpcykpOwotCQkJfSBlbHNlIGlmICh0eXBlID09IDMpIHsKLQkJCQlyZXR1cm4gbmV3IEJ5dGUoKGJ5dGUpIGlzLnJlYWQoKSk7Ci0JCQl9IGVsc2UgaWYgKHR5cGUgPT0gNCkgewotCQkJCXJldHVybiBQRGF0YVN0cmVhbS5yZWFkQm9vbGVhbihpcykgPyBCb29sZWFuLlRSVUUgOiBCb29sZWFuLkZBTFNFOwotCQkJfSBlbHNlIGlmICh0eXBlID09IDUpIHsKLQkJCQlyZXR1cm4gbmV3IENoYXJhY3RlcihQRGF0YVN0cmVhbS5yZWFkQ2hhcihpcykpOwotCQkJfSBlbHNlIGlmICh0eXBlID09IDYpIHsKLQkJCQlyZXR1cm4gbmV3IFNob3J0KFBEYXRhU3RyZWFtLnJlYWRTaG9ydChpcykpOwotCQkJfSBlbHNlIGlmICh0eXBlID09IDcpIHsKLQkJCQlyZXR1cm4gbmV3IEZsb2F0KFBEYXRhU3RyZWFtLnJlYWRGbG9hdChpcykpOwotCQkJfSBlbHNlIGlmICh0eXBlID09IDgpIHsKLQkJCQlyZXR1cm4gbmV3IERvdWJsZShQRGF0YVN0cmVhbS5yZWFkRG91YmxlKGlzKSk7Ci0JCQl9IGVsc2UgaWYgKHR5cGUgPT0gMTEpIHsKLQkJCQlTdHJpbmcgbmFtZSA9IFBEYXRhU3RyZWFtLnJlYWRVVEYoaXMpOwotCQkJCUNsYXNzIGMgPSBsb2FkZXIgPT0gbnVsbCA/IENsYXNzLmZvck5hbWUobmFtZSkgOiBsb2FkZXIubG9hZENsYXNzKG5hbWUpOwotCQkJCWlmIChFeHRlcm5hbGl6YWJsZS5jbGFzcy5pc0Fzc2lnbmFibGVGcm9tKGMpKSB7Ci0JCQkJCUV4dGVybmFsaXphYmxlIG9iaiA9IChFeHRlcm5hbGl6YWJsZSkgYy5uZXdJbnN0YW5jZSgpOwotCQkJCQlvYmoucmVhZE9iamVjdChpcyk7Ci0JCQkJCXJldHVybiBvYmo7Ci0JCQkJfQotCQkJCXRocm93IG5ldyBJT0V4Y2VwdGlvbigiQ291bGQgbm90IHJlYWQgb2JqZWN0ICIgKyBuYW1lKTsKLQkJCX0gZWxzZSBpZiAodHlwZSA9PSAxMikgewotCQkJCU9iamVjdElucHV0U3RyZWFtIGluID0gbG9hZGVyID09IG51bGwgPyBuZXcgT2JqZWN0SW5wdXRTdHJlYW0oaXMpIDogKE9iamVjdElucHV0U3RyZWFtKSBuZXcgWE9iamVjdElucHV0U3RyZWFtKGxvYWRlciwgaXMpOwotCQkJCXJldHVybiBpbi5yZWFkT2JqZWN0KCk7Ci0JCQl9Ci0JCX0gY2F0Y2ggKENsYXNzTm90Rm91bmRFeGNlcHRpb24gY25mZSkgewotCQkJdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJDb3VsZCBub3QgZmluZCBjbGFzcyAiICsgY25mZS50b1N0cmluZygpKTsKLQkJfSBjYXRjaCAoRXhjZXB0aW9uIGV4YykgewotCQkJdGhyb3cgZXhjIGluc3RhbmNlb2YgSU9FeGNlcHRpb24gPyAoSU9FeGNlcHRpb24pIGV4YyA6IG5ldyBJT0V4Y2VwdGlvbigiQ291bGQgbm90IHJlYWQgb2JqZWN0ICIgKyBleGMudG9TdHJpbmcoKSk7Ci0JCX0KLQkJdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiVW5zdXBwb3J0ZWQgVHlwZWQgT2JqZWN0OiAiICsgdHlwZSk7Ci0JfQotCi0JLyoqCi0JICogCi0JICogCi0JICogQHBhcmFtIHByb3BzCi0JICogQGV4Y2VwdGlvbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KLQkgKi8KLQlwdWJsaWMgc3luY2hyb25pemVkIHZvaWQgY29weUZyb20oRGljdGlvbmFyeSBwcm9wcykgdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB7Ci0JCUVudW1lcmF0aW9uIGtleXMgPSBwcm9wcy5rZXlzKCk7Ci0JCUVudW1lcmF0aW9uIHZhbHVlcyA9IHByb3BzLmVsZW1lbnRzKCk7Ci0JCXdoaWxlIChrZXlzLmhhc01vcmVFbGVtZW50cygpKSB7Ci0JCQlwdXQoa2V5cy5uZXh0RWxlbWVudCgpLCB2YWx1ZXMubmV4dEVsZW1lbnQoKSk7Ci0JCX0KLQl9Ci0KLX0KLQotY2xhc3MgSGFzaHRhYmxlRW50cnkgewotCWludCBoYXNoOwotCVN0cmluZyBrZXk7Ci0JT2JqZWN0IHZhbHVlOwotCUhhc2h0YWJsZUVudHJ5IG5leHQ7Ci0KLQlwcm90ZWN0ZWQgT2JqZWN0IGNsb25lKCkgewotCQlIYXNodGFibGVFbnRyeSBlbnRyeSA9IG5ldyBIYXNodGFibGVFbnRyeSgpOwotCQllbnRyeS5oYXNoID0gaGFzaDsKLQkJZW50cnkua2V5ID0ga2V5OwotCQllbnRyeS52YWx1ZSA9IHZhbHVlOwotCQllbnRyeS5uZXh0ID0gKG5leHQgIT0gbnVsbCkgPyAoSGFzaHRhYmxlRW50cnkpIG5leHQuY2xvbmUoKSA6IG51bGw7Ci0JCXJldHVybiBlbnRyeTsKLQl9Ci19Ci0KLWNsYXNzIEhhc2h0YWJsZUVudW1lcmF0b3IgaW1wbGVtZW50cyBFbnVtZXJhdGlvbiB7Ci0JYm9vbGVhbiBrZXlzOwotCWludCBpbmRleDsKLQlIYXNodGFibGVFbnRyeSB0YWJsZVtdOwotCUhhc2h0YWJsZUVudHJ5IGVudHJ5OwotCi0JSGFzaHRhYmxlRW51bWVyYXRvcihIYXNodGFibGVFbnRyeSB0YWJsZVtdLCBib29sZWFuIGtleXMpIHsKLQkJdGhpcy50YWJsZSA9IHRhYmxlOwotCQl0aGlzLmtleXMgPSBrZXlzOwotCQl0aGlzLmluZGV4ID0gdGFibGUubGVuZ3RoOwotCX0KLQotCXB1YmxpYyBib29sZWFuIGhhc01vcmVFbGVtZW50cygpIHsKLQkJaWYgKHRhYmxlID09IG51bGwpCi0JCQlyZXR1cm4gZmFsc2U7Ci0JCWlmIChlbnRyeSAhPSBudWxsKSB7Ci0JCQlyZXR1cm4gdHJ1ZTsKLQkJfQotCQl3aGlsZSAoaW5kZXgtLSA+IDApIHsKLQkJCWlmICgoZW50cnkgPSB0YWJsZVtpbmRleF0pICE9IG51bGwpIHsKLQkJCQlyZXR1cm4gdHJ1ZTsKLQkJCX0KLQkJfQotCQlyZXR1cm4gZmFsc2U7Ci0JfQotCi0JcHVibGljIE9iamVjdCBuZXh0RWxlbWVudCgpIHsKLQkJaWYgKHRhYmxlICE9IG51bGwpIHsKLQkJCWlmIChlbnRyeSA9PSBudWxsKSB7Ci0JCQkJd2hpbGUgKChpbmRleC0tID4gMCkgJiYgKChlbnRyeSA9IHRhYmxlW2luZGV4XSkgPT0gbnVsbCkpOwotCQkJfQotCQkJaWYgKGVudHJ5ICE9IG51bGwpIHsKLQkJCQlIYXNodGFibGVFbnRyeSBlID0gZW50cnk7Ci0JCQkJZW50cnkgPSBlLm5leHQ7Ci0JCQkJcmV0dXJuIGtleXMgPyBlLmtleSA6IGUudmFsdWU7Ci0JCQl9Ci0JCX0KLQkJdGhyb3cgbmV3IE5vU3VjaEVsZW1lbnRFeGNlcHRpb24oIkhhc2h0YWJsZUVudW1lcmF0b3IiKTsKLQl9Ci19Ci0KLWNsYXNzIFhPYmplY3RJbnB1dFN0cmVhbSBleHRlbmRzIE9iamVjdElucHV0U3RyZWFtIHsKLQotCUNsYXNzTG9hZGVyIGxvYWRlcjsKLQotCXB1YmxpYyBYT2JqZWN0SW5wdXRTdHJlYW0oQ2xhc3NMb2FkZXIgbG9hZGVyLCBJbnB1dFN0cmVhbSBpcykgdGhyb3dzIElPRXhjZXB0aW9uIHsKLQkJc3VwZXIoaXMpOwotCQl0aGlzLmxvYWRlciA9IGxvYWRlcjsKLQl9Ci0KLQlwcm90ZWN0ZWQgQ2xhc3MgcmVzb2x2ZUNsYXNzKE9iamVjdFN0cmVhbUNsYXNzIHYpIHRocm93cyBDbGFzc05vdEZvdW5kRXhjZXB0aW9uIHsKLQkJcmV0dXJuIGxvYWRlci5sb2FkQ2xhc3Modi5nZXROYW1lKCkpOwotCX0KLX0KZGlmZiAtLWdpdCBhL2J1bmRsZXMvb3JnLmVjbGlwc2UuZXF1aW5veC5kcy9zcmMvb3JnL2VjbGlwc2UvZXF1aW5veC9pbnRlcm5hbC91dGlsL2lvL1BEYXRhU3RyZWFtLmphdmEgYi9idW5kbGVzL29yZy5lY2xpcHNlLmVxdWlub3guZHMvc3JjL29yZy9lY2xpcHNlL2VxdWlub3gvaW50ZXJuYWwvdXRpbC9pby9QRGF0YVN0cmVhbS5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBmM2UxN2I5Li4wMDAwMDAwCi0tLSBhL2J1bmRsZXMvb3JnLmVjbGlwc2UuZXF1aW5veC5kcy9zcmMvb3JnL2VjbGlwc2UvZXF1aW5veC9pbnRlcm5hbC91dGlsL2lvL1BEYXRhU3RyZWFtLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwyMzYgKzAsMCBAQAotLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKLSAqIENvcHlyaWdodCAoYykgMTk5NywgMjAwOCBieSBQcm9TeXN0IFNvZnR3YXJlIEdtYkgKLSAqIGh0dHA6Ly93d3cucHJvc3lzdC5jb20KLSAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMKLSAqIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2UgdjEuMAotICogd2hpY2ggYWNjb21wYW5pZXMgdGhpcyBkaXN0cmlidXRpb24sIGFuZCBpcyBhdmFpbGFibGUgYXQKLSAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLXYxMC5odG1sCi0gKgotICogQ29udHJpYnV0b3JzOgotICogICAgUHJvU3lzdCBTb2Z0d2FyZSBHbWJIIC0gaW5pdGlhbCBBUEkgYW5kIGltcGxlbWVudGF0aW9uCi0gKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLXBhY2thZ2Ugb3JnLmVjbGlwc2UuZXF1aW5veC5pbnRlcm5hbC51dGlsLmlvOwotCi1pbXBvcnQgamF2YS5pby4qOwotCi0vKioKLSAqIEBhdXRob3IgUGF2bGluIERvYnJldgotICogQGF1dGhvciBHZW9yZ2kgQW5kcmVldgotICogQHZlcnNpb24gMS4wCi0gKi8KLXB1YmxpYyBmaW5hbCBjbGFzcyBQRGF0YVN0cmVhbSB7Ci0KLQlwdWJsaWMgc3RhdGljIHZvaWQgd3JpdGVJbnQoaW50IGksIE91dHB1dFN0cmVhbSBvcykgdGhyb3dzIElPRXhjZXB0aW9uIHsKLQkJb3Mud3JpdGUoKGkgPj4+IDI0KSAmIDB4RkYpOwotCQlvcy53cml0ZSgoaSA+Pj4gMTYpICYgMHhGRik7Ci0JCW9zLndyaXRlKChpID4+PiA4KSAmIDB4RkYpOwotCQlvcy53cml0ZShpICYgMHhGRik7Ci0JfQotCi0JcHVibGljIHN0YXRpYyB2b2lkIHdyaXRlTG9uZyhsb25nIGwsIE91dHB1dFN0cmVhbSBvcykgdGhyb3dzIElPRXhjZXB0aW9uIHsKLQkJb3Mud3JpdGUoKGludCkgKGwgPj4+IDU2KSAmIDB4RkYpOwotCQlvcy53cml0ZSgoaW50KSAobCA+Pj4gNDgpICYgMHhGRik7Ci0JCW9zLndyaXRlKChpbnQpIChsID4+PiA0MCkgJiAweEZGKTsKLQkJb3Mud3JpdGUoKGludCkgKGwgPj4+IDMyKSAmIDB4RkYpOwotCQlvcy53cml0ZSgoaW50KSAobCA+Pj4gMjQpICYgMHhGRik7Ci0JCW9zLndyaXRlKChpbnQpIChsID4+PiAxNikgJiAweEZGKTsKLQkJb3Mud3JpdGUoKGludCkgKGwgPj4+IDgpICYgMHhGRik7Ci0JCW9zLndyaXRlKChpbnQpIChsICYgMHhGRikpOwotCX0KLQotCXB1YmxpYyBzdGF0aWMgdm9pZCB3cml0ZVNob3J0KHNob3J0IHMsIE91dHB1dFN0cmVhbSBvcykgdGhyb3dzIElPRXhjZXB0aW9uIHsKLQkJb3Mud3JpdGUoKHMgPj4+IDgpICYgMHhGRik7Ci0JCW9zLndyaXRlKHMgJiAweEZGKTsKLQl9Ci0KLQlwdWJsaWMgc3RhdGljIHZvaWQgd3JpdGVDaGFyKGNoYXIgY2gsIE91dHB1dFN0cmVhbSBvcykgdGhyb3dzIElPRXhjZXB0aW9uIHsKLQkJb3Mud3JpdGUoKGNoID4+PiA4KSAmIDB4RkYpOwotCQlvcy53cml0ZShjaCAmIDB4RkYpOwotCX0KLQotCXB1YmxpYyBzdGF0aWMgdm9pZCB3cml0ZUJvb2xlYW4oYm9vbGVhbiBiLCBPdXRwdXRTdHJlYW0gb3MpIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0JCW9zLndyaXRlKGIgPyAxIDogMCk7Ci0JfQotCi0JcHVibGljIHN0YXRpYyB2b2lkIHdyaXRlQnl0ZShieXRlIGIsIE91dHB1dFN0cmVhbSBvcykgdGhyb3dzIElPRXhjZXB0aW9uIHsKLQkJb3Mud3JpdGUoYik7Ci0JfQotCi0JcHVibGljIHN0YXRpYyB2b2lkIHdyaXRlQnl0ZXMoU3RyaW5nIHN0ciwgT3V0cHV0U3RyZWFtIG9zKSB0aHJvd3MgSU9FeGNlcHRpb24gewotCQlieXRlW10gYiA9IHN0ci5nZXRCeXRlcygpOwotCQlvcy53cml0ZShiKTsKLQl9Ci0KLQlwdWJsaWMgc3RhdGljIHZvaWQgd3JpdGVTdHJpbmcoU3RyaW5nIHN0ciwgT3V0cHV0U3RyZWFtIG9zKSB0aHJvd3MgSU9FeGNlcHRpb24gewotCQlpZiAoc3RyID09IG51bGwpIHsKLQkJCXdyaXRlQm9vbGVhbihmYWxzZSwgb3MpOwotCQl9IGVsc2UgewotCQkJd3JpdGVCb29sZWFuKHRydWUsIG9zKTsKLQkJCXdyaXRlVVRGKHN0ciwgb3MpOwotCQl9Ci0JfQotCi0JcHVibGljIHN0YXRpYyB2b2lkIHdyaXRlVVRGKFN0cmluZyBzdHIsIE91dHB1dFN0cmVhbSBvcykgdGhyb3dzIElPRXhjZXB0aW9uIHsKLQkJaW50IHN0cmxlbiA9IHN0ci5sZW5ndGgoKTsKLQkJaW50IHV0ZmxlbiA9IDA7Ci0JCWZvciAoaW50IGkgPSAwOyBpIDwgc3RybGVuOyBpKyspIHsKLQkJCWludCBjaCA9IHN0ci5jaGFyQXQoaSk7Ci0JCQlpZiAoKGNoID49IDB4MDAwMSkgJiYgKGNoIDw9IDB4MDA3RikpIHsKLQkJCQl1dGZsZW4rKzsKLQkJCX0gZWxzZSBpZiAoY2ggPiAweDA3RkYpIHsKLQkJCQl1dGZsZW4gKz0gMzsKLQkJCX0gZWxzZSB7Ci0JCQkJdXRmbGVuICs9IDI7Ci0JCQl9Ci0JCX0KLQkJaWYgKHV0ZmxlbiA+IDY1NTM1KQotCQkJdGhyb3cgbmV3IFVURkRhdGFGb3JtYXRFeGNlcHRpb24oKTsKLQkJb3Mud3JpdGUoKHV0ZmxlbiA+Pj4gOCkgJiAweEZGKTsKLQkJb3Mud3JpdGUodXRmbGVuICYgMHhGRik7Ci0JCWZvciAoaW50IGkgPSAwOyBpIDwgc3RybGVuOyBpKyspIHsKLQkJCWludCBjaCA9IHN0ci5jaGFyQXQoaSk7Ci0JCQlpZiAoKGNoID49IDB4MDAwMSkgJiYgKGNoIDw9IDB4MDA3RikpIHsKLQkJCQlvcy53cml0ZShjaCk7Ci0JCQl9IGVsc2UgaWYgKGNoID4gMHgwN0ZGKSB7Ci0JCQkJb3Mud3JpdGUoMHhFMCB8ICgoY2ggPj4gMTIpICYgMHgwRikpOwotCQkJCW9zLndyaXRlKDB4ODAgfCAoKGNoID4+IDYpICYgMHgzRikpOwotCQkJCW9zLndyaXRlKDB4ODAgfCAoY2ggJiAweDNGKSk7Ci0JCQl9IGVsc2UgewotCQkJCW9zLndyaXRlKDB4QzAgfCAoKGNoID4+IDYpICYgMHgxRikpOwotCQkJCW9zLndyaXRlKDB4ODAgfCAoY2ggJiAweDNGKSk7Ci0JCQl9Ci0JCX0KLQl9Ci0KLQlwdWJsaWMgc3RhdGljIHZvaWQgd3JpdGVDaGFycyhTdHJpbmcgc3RyLCBPdXRwdXRTdHJlYW0gb3MpIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0JCWludCBsZW4gPSBzdHIubGVuZ3RoKCk7Ci0JCWZvciAoaW50IGkgPSAwOyBpIDwgbGVuOyBpKyspIHsKLQkJCWludCBjaCA9IHN0ci5jaGFyQXQoaSk7Ci0JCQlvcy53cml0ZSgoY2ggPj4+IDgpICYgMHhGRik7Ci0JCQlvcy53cml0ZShjaCAmIDB4RkYpOwotCQl9Ci0JfQotCi0JcHVibGljIHN0YXRpYyB2b2lkIHdyaXRlRG91YmxlKGRvdWJsZSBkLCBPdXRwdXRTdHJlYW0gb3MpIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0JCXdyaXRlTG9uZyhEb3VibGUuZG91YmxlVG9Mb25nQml0cyhkKSwgb3MpOwotCX0KLQotCXB1YmxpYyBzdGF0aWMgdm9pZCB3cml0ZUZsb2F0KGZsb2F0IGYsIE91dHB1dFN0cmVhbSBvcykgdGhyb3dzIElPRXhjZXB0aW9uIHsKLQkJd3JpdGVJbnQoRmxvYXQuZmxvYXRUb0ludEJpdHMoZiksIG9zKTsKLQl9Ci0KLQlwdWJsaWMgc3RhdGljIGludCByZWFkSW50KElucHV0U3RyZWFtIGlzKSB0aHJvd3MgSU9FeGNlcHRpb24gewotCQlpbnQgY2gxID0gaXMucmVhZCgpOwotCQlpbnQgY2gyID0gaXMucmVhZCgpOwotCQlpbnQgY2gzID0gaXMucmVhZCgpOwotCQlpbnQgY2g0ID0gaXMucmVhZCgpOwotCQlpZiAoKGNoMSB8IGNoMiB8IGNoMyB8IGNoNCkgPCAwKSB7Ci0JCQl0aHJvdyBuZXcgSU9FeGNlcHRpb24oIlJlYWQgRXJyb3IiKTsKLQkJfQotCQlyZXR1cm4gKGNoMSA8PCAyNCkgfCAoY2gyIDw8IDE2KSB8IChjaDMgPDwgOCkgfCBjaDQ7Ci0JfQotCi0JcHVibGljIHN0YXRpYyBjaGFyIHJlYWRDaGFyKElucHV0U3RyZWFtIGlzKSB0aHJvd3MgSU9FeGNlcHRpb24gewotCQlpbnQgY2gxID0gaXMucmVhZCgpOwotCQlpbnQgY2gyID0gaXMucmVhZCgpOwotCQlpZiAoKGNoMSB8IGNoMikgPCAwKQotCQkJdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJSZWFkIEVycm9yIik7Ci0JCXJldHVybiAoY2hhcikgKChjaDEgPDwgOCkgfCBjaDIpOwotCX0KLQotCXB1YmxpYyBzdGF0aWMgc2hvcnQgcmVhZFNob3J0KElucHV0U3RyZWFtIGlzKSB0aHJvd3MgSU9FeGNlcHRpb24gewotCQlpbnQgY2gxID0gaXMucmVhZCgpOwotCQlpbnQgY2gyID0gaXMucmVhZCgpOwotCQlpZiAoKGNoMSB8IGNoMikgPCAwKQotCQkJdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJSZWFkIEVycm9yIik7Ci0JCXJldHVybiAoc2hvcnQpICgoY2gxIDw8IDgpIHwgY2gyKTsKLQl9Ci0KLQlwdWJsaWMgc3RhdGljIGxvbmcgcmVhZExvbmcoSW5wdXRTdHJlYW0gaXMpIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0JCXJldHVybiAoKGxvbmcpIChyZWFkSW50KGlzKSkgPDwgMzIpIHwgKHJlYWRJbnQoaXMpICYgMHhGRkZGRkZGRkwpOwotCX0KLQotCXB1YmxpYyBzdGF0aWMgYm9vbGVhbiByZWFkQm9vbGVhbihJbnB1dFN0cmVhbSBpcykgdGhyb3dzIElPRXhjZXB0aW9uIHsKLQkJaW50IGNoID0gaXMucmVhZCgpOwotCQlpZiAoY2ggPCAwKSB7Ci0JCQl0aHJvdyBuZXcgRU9GRXhjZXB0aW9uKCk7Ci0JCX0KLQkJcmV0dXJuIChjaCAhPSAwKTsKLQl9Ci0KLQlwdWJsaWMgc3RhdGljIGJ5dGUgcmVhZEJ5dGUoSW5wdXRTdHJlYW0gaXMpIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0JCWludCBjaCA9IGlzLnJlYWQoKTsKLQkJaWYgKGNoIDwgMCkKLQkJCXRocm93IG5ldyBFT0ZFeGNlcHRpb24oKTsKLQkJcmV0dXJuIChieXRlKSAoY2gpOwotCX0KLQotCXB1YmxpYyBzdGF0aWMgaW50IHJlYWRVbnNpZ25lZEJ5dGUoSW5wdXRTdHJlYW0gaXMpIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0JCWludCBjaCA9IGlzLnJlYWQoKTsKLQkJaWYgKGNoIDwgMCkKLQkJCXRocm93IG5ldyBFT0ZFeGNlcHRpb24oKTsKLQkJcmV0dXJuIGNoOwotCX0KLQotCXB1YmxpYyBzdGF0aWMgZG91YmxlIHJlYWREb3VibGUoSW5wdXRTdHJlYW0gaXMpIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0JCXJldHVybiBEb3VibGUubG9uZ0JpdHNUb0RvdWJsZShyZWFkTG9uZyhpcykpOwotCX0KLQotCXB1YmxpYyBzdGF0aWMgZmxvYXQgcmVhZEZsb2F0KElucHV0U3RyZWFtIGlzKSB0aHJvd3MgSU9FeGNlcHRpb24gewotCQlyZXR1cm4gRmxvYXQuaW50Qml0c1RvRmxvYXQocmVhZEludChpcykpOwotCX0KLQotCXB1YmxpYyBzdGF0aWMgU3RyaW5nIHJlYWRTdHJpbmcoSW5wdXRTdHJlYW0gaXMpIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0JCWlmIChyZWFkQm9vbGVhbihpcykpCi0JCQlyZXR1cm4gcmVhZFVURihpcyk7Ci0JCXJldHVybiBudWxsOwotCX0KLQotCXB1YmxpYyBzdGF0aWMgU3RyaW5nIHJlYWRVVEYoSW5wdXRTdHJlYW0gaXMpIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0JCWludCB1dGZsZW4gPSByZWFkU2hvcnQoaXMpOwotCQljaGFyIHN0cltdID0gbmV3IGNoYXJbdXRmbGVuXTsKLQkJaW50IGNudCA9IDA7Ci0JCWludCBzdHJsZW4gPSAwOwotCQl3aGlsZSAoY250IDwgdXRmbGVuKSB7Ci0JCQlpbnQgYyA9IHJlYWRVbnNpZ25lZEJ5dGUoaXMpOwotCQkJaW50IGNoYXIyLCBjaGFyMzsKLQkJCXN3aXRjaCAoYyA+PiA0KSB7Ci0JCQkJY2FzZSAwIDoKLQkJCQljYXNlIDEgOgotCQkJCWNhc2UgMiA6Ci0JCQkJY2FzZSAzIDoKLQkJCQljYXNlIDQgOgotCQkJCWNhc2UgNSA6Ci0JCQkJY2FzZSA2IDoKLQkJCQljYXNlIDcgOgotCQkJCQljbnQrKzsKLQkJCQkJc3RyW3N0cmxlbisrXSA9IChjaGFyKSBjOwotCQkJCQlicmVhazsKLQkJCQljYXNlIDEyIDoKLQkJCQljYXNlIDEzIDoKLQkJCQkJY250ICs9IDI7Ci0JCQkJCWlmIChjbnQgPiB1dGZsZW4pCi0JCQkJCQl0aHJvdyBuZXcgVVRGRGF0YUZvcm1hdEV4Y2VwdGlvbigpOwotCQkJCQljaGFyMiA9IHJlYWRVbnNpZ25lZEJ5dGUoaXMpOwotCQkJCQlpZiAoKGNoYXIyICYgMHhDMCkgIT0gMHg4MCkKLQkJCQkJCXRocm93IG5ldyBVVEZEYXRhRm9ybWF0RXhjZXB0aW9uKCk7Ci0JCQkJCXN0cltzdHJsZW4rK10gPSAoY2hhcikgKCgoYyAmIDB4MUYpIDw8IDYpIHwgKGNoYXIyICYgMHgzRikpOwotCQkJCQlicmVhazsKLQkJCQljYXNlIDE0IDoKLQkJCQkJY250ICs9IDM7Ci0JCQkJCWlmIChjbnQgPiB1dGZsZW4pCi0JCQkJCQl0aHJvdyBuZXcgVVRGRGF0YUZvcm1hdEV4Y2VwdGlvbigpOwotCQkJCQljaGFyMiA9IHJlYWRVbnNpZ25lZEJ5dGUoaXMpOwotCQkJCQljaGFyMyA9IHJlYWRVbnNpZ25lZEJ5dGUoaXMpOwotCQkJCQlpZiAoKChjaGFyMiAmIDB4QzApICE9IDB4ODApIHx8ICgoY2hhcjMgJiAweEMwKSAhPSAweDgwKSkKLQkJCQkJCXRocm93IG5ldyBVVEZEYXRhRm9ybWF0RXhjZXB0aW9uKCk7Ci0JCQkJCXN0cltzdHJsZW4rK10gPSAoY2hhcikgKCgoYyAmIDB4MEYpIDw8IDEyKSB8ICgoY2hhcjIgJiAweDNGKSA8PCA2KSB8IChjaGFyMyAmIDB4M0YpKTsKLQkJCQkJYnJlYWs7Ci0JCQkJZGVmYXVsdCA6Ci0JCQkJCXRocm93IG5ldyBVVEZEYXRhRm9ybWF0RXhjZXB0aW9uKCk7Ci0JCQl9Ci0JCX0KLQkJcmV0dXJuIG5ldyBTdHJpbmcoc3RyLCAwLCBzdHJsZW4pOwotCX0KLQotfQpkaWZmIC0tZ2l0IGEvYnVuZGxlcy9vcmcuZWNsaXBzZS5lcXVpbm94LmRzL3NyYy9vcmcvZWNsaXBzZS9lcXVpbm94L2ludGVybmFsL3V0aWwvaW8vcGFja2FnZS5odG1sIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5lcXVpbm94LmRzL3NyYy9vcmcvZWNsaXBzZS9lcXVpbm94L2ludGVybmFsL3V0aWwvaW8vcGFja2FnZS5odG1sCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCA0OGViMTc5Li4wMDAwMDAwCi0tLSBhL2J1bmRsZXMvb3JnLmVjbGlwc2UuZXF1aW5veC5kcy9zcmMvb3JnL2VjbGlwc2UvZXF1aW5veC9pbnRlcm5hbC91dGlsL2lvL3BhY2thZ2UuaHRtbAorKysgL2Rldi9udWxsCkBAIC0xLDkgKzAsMCBAQAotPCFkb2N0eXBlIGh0bWwgcHVibGljICItLy93M2MvL2R0ZCBodG1sIDQuMCB0cmFuc2l0aW9uYWwvL2VuIj4KLTxodG1sPgotPEhFQUQ+Ci0gICA8bWV0YSBodHRwLWVxdWl2PSJDb250ZW50LVR5cGUiIGNvbnRlbnQ9InRleHQvaHRtbDsgY2hhcnNldD1pc28tODg1OS0xIj4KLTwvSEVBRD4KLTxCT0RZIExJTks9IiMwMDAwZmYiIFZMSU5LPSIjODAwMDgwIj4KLQotPFA+VGhlIHBhY2thZ2UgY29udGFpbnMgdXRpbGl0aWVzIGZvciBlYXNpbHkgdHJhbnNmZXIgb2Ygb2JqZWN0czwvUD48L0JPRFk+Ci08L0hUTUw+CmRpZmYgLS1naXQgYS9idW5kbGVzL29yZy5lY2xpcHNlLmVxdWlub3guZHMvc3JjL29yZy9lY2xpcHNlL2VxdWlub3gvaW50ZXJuYWwvdXRpbC9zdHJpbmcvQ2hhckJ1ZmZlci5qYXZhIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5lcXVpbm94LmRzL3NyYy9vcmcvZWNsaXBzZS9lcXVpbm94L2ludGVybmFsL3V0aWwvc3RyaW5nL0NoYXJCdWZmZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggZTM0YjMyMy4uMDAwMDAwMAotLS0gYS9idW5kbGVzL29yZy5lY2xpcHNlLmVxdWlub3guZHMvc3JjL29yZy9lY2xpcHNlL2VxdWlub3gvaW50ZXJuYWwvdXRpbC9zdHJpbmcvQ2hhckJ1ZmZlci5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMTYzICswLDAgQEAKLS8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMDggYnkgUHJvU3lzdCBTb2Z0d2FyZSBHbWJICi0gKiBodHRwOi8vd3d3LnByb3N5c3QuY29tCi0gKiBBbGwgcmlnaHRzIHJlc2VydmVkLiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzCi0gKiBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYxLjAKLSAqIHdoaWNoIGFjY29tcGFuaWVzIHRoaXMgZGlzdHJpYnV0aW9uLCBhbmQgaXMgYXZhaWxhYmxlIGF0Ci0gKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC12MTAuaHRtbAotICoKLSAqIENvbnRyaWJ1dG9yczoKLSAqICAgIFByb1N5c3QgU29mdHdhcmUgR21iSCAtIGluaXRpYWwgQVBJIGFuZCBpbXBsZW1lbnRhdGlvbgotICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi1wYWNrYWdlIG9yZy5lY2xpcHNlLmVxdWlub3guaW50ZXJuYWwudXRpbC5zdHJpbmc7Ci0KLS8qKgotICogQ2xhc3Mgd2hpY2ggc3RvcmVzIHRleHQgaW4gYSA8Y29kZT5jaGFyPC9jb2RlPiBhcnJheSBidWZmZXIgCi0gKiBhbmQgYWxsb3dzIGluc2VydGluZywgZGVsZXRpbmcsIHJlbW92aW5nLCBhcHBlbmRpbmcgZXRjLiAKLSAqIGFjdGlvbnMgd2l0aCB0aGUgc3RvcmVkIHRleHQuCi0gKiAKLSAqIEBhdXRob3IgUGF2bGluIERvYnJldgotICogQGF1dGhvciBHZW9yZ2kgQW5kcmVldgotICogQHZlcnNpb24gMS4wCi0gKi8KLXB1YmxpYyBjbGFzcyBDaGFyQnVmZmVyIHsKLQotCXByaXZhdGUgY2hhciB2YWx1ZVtdOwotCXByaXZhdGUgaW50IGNudDsKLQotCXB1YmxpYyBDaGFyQnVmZmVyKCkgewotCQl0aGlzKDE2KTsKLQl9Ci0KLQlwdWJsaWMgQ2hhckJ1ZmZlcihpbnQgbGVuKSB7Ci0JCXZhbHVlID0gbmV3IGNoYXJbbGVuXTsKLQl9Ci0KLQlwdWJsaWMgaW50IGxlbmd0aCgpIHsKLQkJcmV0dXJuIGNudDsKLQl9Ci0KLQlwdWJsaWMgdm9pZCBlbnN1cmVDYXBhY2l0eShpbnQgbWluQ2FwYWNpdHkpIHsKLQkJaWYgKG1pbkNhcGFjaXR5ID4gdmFsdWUubGVuZ3RoKQotCQkJZXhwYW5kQ2FwYWNpdHkobWluQ2FwYWNpdHkpOwotCX0KLQotCXByaXZhdGUgdm9pZCBleHBhbmRDYXBhY2l0eShpbnQgbWluQ2FwYWNpdHkpIHsKLQkJaW50IGNhcGFjaXR5ID0gKHZhbHVlLmxlbmd0aCArIDEpICogMjsKLQkJaWYgKG1pbkNhcGFjaXR5ID4gY2FwYWNpdHkpIHsKLQkJCWNhcGFjaXR5ID0gbWluQ2FwYWNpdHk7Ci0JCX0KLQkJY2hhciBuZXdWYWxbXSA9IG5ldyBjaGFyW2NhcGFjaXR5XTsKLQkJU3lzdGVtLmFycmF5Y29weSh2YWx1ZSwgMCwgbmV3VmFsLCAwLCBjbnQpOwotCQl2YWx1ZSA9IG5ld1ZhbDsKLQl9Ci0KLQlwdWJsaWMgdm9pZCBzZXRMZW5ndGgoaW50IG5ld0xlbikgewotCQlpZiAobmV3TGVuID4gdmFsdWUubGVuZ3RoKQotCQkJZXhwYW5kQ2FwYWNpdHkobmV3TGVuKTsKLQkJaWYgKGNudCA8IG5ld0xlbikgewotCQkJZm9yICg7IGNudCA8IG5ld0xlbjsgY250KyspIHsKLQkJCQl2YWx1ZVtjbnRdID0gJ1wwJzsKLQkJCX0KLQkJfSBlbHNlIHsKLQkJCWNudCA9IG5ld0xlbjsKLQkJfQotCX0KLQotCXB1YmxpYyBjaGFyIGNoYXJBdChpbnQgaW5kZXgpIHsKLQkJaWYgKChpbmRleCA8IDApIHx8IChpbmRleCA+PSBjbnQpKQotCQkJdGhyb3cgbmV3IFN0cmluZ0luZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oaW5kZXgpOwotCQlyZXR1cm4gdmFsdWVbaW5kZXhdOwotCX0KLQotCXB1YmxpYyB2b2lkIHNldENoYXJBdChpbnQgaW5kZXgsIGNoYXIgY2gpIHsKLQkJaWYgKChpbmRleCA8IDApIHx8IChpbmRleCA+PSBjbnQpKQotCQkJdGhyb3cgbmV3IFN0cmluZ0luZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oaW5kZXgpOwotCQl2YWx1ZVtpbmRleF0gPSBjaDsKLQl9Ci0KLQlwdWJsaWMgdm9pZCBhcHBlbmQoU3RyaW5nIHN0cikgewotCQlpZiAoc3RyID09IG51bGwpCi0JCQlzdHIgPSBTdHJpbmcudmFsdWVPZihzdHIpOwotCQlpbnQgbGVuID0gc3RyLmxlbmd0aCgpOwotCQlpbnQgbmV3Y250ID0gY250ICsgbGVuOwotCQlpZiAobmV3Y250ID4gdmFsdWUubGVuZ3RoKQotCQkJZXhwYW5kQ2FwYWNpdHkobmV3Y250KTsKLQkJc3RyLmdldENoYXJzKDAsIGxlbiwgdmFsdWUsIGNudCk7Ci0JCWNudCA9IG5ld2NudDsKLQl9Ci0KLQlwdWJsaWMgdm9pZCBhcHBlbmQoY2hhciBzdHJbXSwgaW50IG9mZnNldCwgaW50IGxlbikgewotCQlpbnQgbmV3Y250ID0gY250ICsgbGVuOwotCQlpZiAobmV3Y250ID4gdmFsdWUubGVuZ3RoKQotCQkJZXhwYW5kQ2FwYWNpdHkobmV3Y250KTsKLQkJU3lzdGVtLmFycmF5Y29weShzdHIsIG9mZnNldCwgdmFsdWUsIGNudCwgbGVuKTsKLQkJY250ID0gbmV3Y250OwotCX0KLQotCXB1YmxpYyB2b2lkIGFwcGVuZChjaGFyIHN0cltdKSB7Ci0JCWFwcGVuZChzdHIsIDAsIHN0ci5sZW5ndGgpOwotCX0KLQotCXB1YmxpYyB2b2lkIGFwcGVuZChjaGFyIGMpIHsKLQkJaW50IG5ld2NvdW50ID0gY250ICsgMTsKLQkJaWYgKG5ld2NvdW50ID4gdmFsdWUubGVuZ3RoKQotCQkJZXhwYW5kQ2FwYWNpdHkobmV3Y291bnQpOwotCQl2YWx1ZVtjbnQrK10gPSBjOwotCX0KLQotCXB1YmxpYyBTdHJpbmcgc3Vic3RyaW5nKGludCBzdGFydCwgaW50IGVuZCkgewotCQlyZXR1cm4gbmV3IFN0cmluZyh2YWx1ZSwgc3RhcnQsIGVuZCAtIHN0YXJ0KTsKLQl9Ci0KLQlwdWJsaWMgU3RyaW5nIHRyaW0oKSB7Ci0JCWludCBsZW4gPSBjbnQ7Ci0JCWludCBzdCA9IDA7Ci0JCWludCBvZmYgPSAwOwotCQljaGFyW10gbmV3VmFsID0gdmFsdWU7Ci0KLQkJd2hpbGUgKChzdCA8IGxlbikgJiYgKG5ld1ZhbFtvZmYgKyBzdF0gPD0gJyAnKSkKLQkJCXN0Kys7Ci0JCXdoaWxlICgoc3QgPCBsZW4pICYmIChuZXdWYWxbb2ZmICsgbGVuIC0gMV0gPD0gJyAnKSkKLQkJCWxlbi0tOwotCi0JCXJldHVybiAoKHN0ID4gMCkgfHwgKGxlbiA8IGNudCkpID8gc3Vic3RyaW5nKHN0LCBsZW4pIDogdG9TdHJpbmcoKTsKLQl9Ci0KLQlwdWJsaWMgYm9vbGVhbiBlcXVhbHMoaW50IG9mZnNldCwgU3RyaW5nIHdpdGgpIHsKLQkJaW50IGxlbiA9IHdpdGgubGVuZ3RoKCk7Ci0JCWlmIChvZmZzZXQgPj0gY250IHx8IG9mZnNldCArIGxlbiAhPSBjbnQpCi0JCQlyZXR1cm4gZmFsc2U7Ci0KLQkJZm9yIChpbnQgaSA9IG9mZnNldDsgaSA8IGNudDsgaSsrKSB7Ci0JCQlpZiAodmFsdWVbaV0gIT0gd2l0aC5jaGFyQXQoaSAtIG9mZnNldCkpCi0JCQkJcmV0dXJuIGZhbHNlOwotCQl9Ci0KLQkJcmV0dXJuIHRydWU7Ci0JfQotCi0JcHVibGljIHZvaWQgZ2V0Q2hhcnMoaW50IHNyY1N0YXJ0LCBpbnQgc3JjRW5kLCBjaGFyIGRlc3RbXSwgaW50IGRlc3RTdGFydCkgewotCQlpZiAoKHNyY1N0YXJ0IDwgMCkgfHwgKHNyY1N0YXJ0ID49IGNudCkpCi0JCQl0aHJvdyBuZXcgU3RyaW5nSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbihzcmNTdGFydCk7Ci0JCWlmICgoc3JjRW5kIDwgMCkgfHwgKHNyY0VuZCA+IGNudCkpCi0JCQl0aHJvdyBuZXcgU3RyaW5nSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbihzcmNFbmQpOwotCi0JCWlmIChzcmNTdGFydCA8IHNyY0VuZCkKLQkJCVN5c3RlbS5hcnJheWNvcHkodmFsdWUsIHNyY1N0YXJ0LCBkZXN0LCBkZXN0U3RhcnQsIHNyY0VuZCAtIHNyY1N0YXJ0KTsKLQkJZWxzZSBpZiAoc3JjU3RhcnQgPiBzcmNFbmQpCi0JCQl0aHJvdyBuZXcgU3RyaW5nSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbihzcmNFbmQgLSBzcmNTdGFydCk7Ci0JfQotCi0JcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKLQkJcmV0dXJuIG5ldyBTdHJpbmcodmFsdWUsIDAsIGNudCk7Ci0JfQotCi0JcHVibGljIGNoYXJbXSBnZXRWYWx1ZSgpIHsKLQkJY2hhcltdIHJldFZhbDsKLQkJcmV0VmFsID0gbmV3IGNoYXJbY250XTsKLQkJU3lzdGVtLmFycmF5Y29weSh2YWx1ZSwgMCwgcmV0VmFsLCAwLCBjbnQpOwotCQlyZXR1cm4gcmV0VmFsOwotCX0KLQotfQpkaWZmIC0tZ2l0IGEvYnVuZGxlcy9vcmcuZWNsaXBzZS5lcXVpbm94LmRzL3NyYy9vcmcvZWNsaXBzZS9lcXVpbm94L2ludGVybmFsL3V0aWwvc3RyaW5nL3BhY2thZ2UuaHRtbCBiL2J1bmRsZXMvb3JnLmVjbGlwc2UuZXF1aW5veC5kcy9zcmMvb3JnL2VjbGlwc2UvZXF1aW5veC9pbnRlcm5hbC91dGlsL3N0cmluZy9wYWNrYWdlLmh0bWwKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDdiMTA3NTUuLjAwMDAwMDAKLS0tIGEvYnVuZGxlcy9vcmcuZWNsaXBzZS5lcXVpbm94LmRzL3NyYy9vcmcvZWNsaXBzZS9lcXVpbm94L2ludGVybmFsL3V0aWwvc3RyaW5nL3BhY2thZ2UuaHRtbAorKysgL2Rldi9udWxsCkBAIC0xLDE4ICswLDAgQEAKLTwhZG9jdHlwZSBodG1sIHB1YmxpYyAiLS8vdzNjLy9kdGQgaHRtbCA0LjAgdHJhbnNpdGlvbmFsLy9lbiI+Ci08aHRtbD4KLTxoZWFkPgotICAgPG1ldGEgaHR0cC1lcXVpdj0iQ29udGVudC1UeXBlIiBjb250ZW50PSJ0ZXh0L2h0bWw7IGNoYXJzZXQ9aXNvLTg4NTktMSI+Ci0gICA8dGl0bGU+UGFja2FnZS1sZXZlbCBKYXZhZG9jPC90aXRsZT4KLTwvaGVhZD4KLTxib2R5PgotPFA+VGhpcyBwYWNrYWdlIHByb3ZpZGVzIG1vcmUgZWZmaWNlbnQgYW5hbG9nIHRvIGphdmEubGFuZy5TdHJpbmdCdWZmZXIgY2xhc3MuCi08L1A+Ci08cD5CdW5kbGVzIHdpc2hpbmcgdG8gdXNlIHRoaXMgcGFja2FnZSBtdXN0IGxpc3QgdGhlIHBhY2thZ2UKLWluIHRoZSBJbXBvcnQtUGFja2FnZSBoZWFkZXIgb2YgdGhlIGJ1bmRsZSdzIG1hbmlmZXN0LgotRm9yIGV4YW1wbGU6Ci08L3A+Ci08cHJlPgotSW1wb3J0LVBhY2thZ2U6IG9yZy5lY2xpcHNlLmVxdWlub3gudXRpbC5zdHJpbmc7IHNwZWNpZmljYXRpb24tdmVyc2lvbj0xLjAKLTwvcHJlPgotPC9ib2R5PgotPC9odG1sPgpkaWZmIC0tZ2l0IGEvYnVuZGxlcy9vcmcuZWNsaXBzZS5lcXVpbm94LmRzL3NyYy9vcmcvZWNsaXBzZS9lcXVpbm94L2ludGVybmFsL3V0aWwveG1sL0V4VGFnTGlzdGVuZXIuamF2YSBiL2J1bmRsZXMvb3JnLmVjbGlwc2UuZXF1aW5veC5kcy9zcmMvb3JnL2VjbGlwc2UvZXF1aW5veC9pbnRlcm5hbC91dGlsL3htbC9FeFRhZ0xpc3RlbmVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDllZjMwNTYuLjAwMDAwMDAKLS0tIGEvYnVuZGxlcy9vcmcuZWNsaXBzZS5lcXVpbm94LmRzL3NyYy9vcmcvZWNsaXBzZS9lcXVpbm94L2ludGVybmFsL3V0aWwveG1sL0V4VGFnTGlzdGVuZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDQzICswLDAgQEAKLS8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMDggYnkgUHJvU3lzdCBTb2Z0d2FyZSBHbWJICi0gKiBodHRwOi8vd3d3LnByb3N5c3QuY29tCi0gKiBBbGwgcmlnaHRzIHJlc2VydmVkLiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzCi0gKiBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYxLjAKLSAqIHdoaWNoIGFjY29tcGFuaWVzIHRoaXMgZGlzdHJpYnV0aW9uLCBhbmQgaXMgYXZhaWxhYmxlIGF0Ci0gKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC12MTAuaHRtbAotICoKLSAqIENvbnRyaWJ1dG9yczoKLSAqICAgIFByb1N5c3QgU29mdHdhcmUgR21iSCAtIGluaXRpYWwgQVBJIGFuZCBpbXBsZW1lbnRhdGlvbgotICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi0KLXBhY2thZ2Ugb3JnLmVjbGlwc2UuZXF1aW5veC5pbnRlcm5hbC51dGlsLnhtbDsKLQotLyoqCi0gKiBUaGUgWE1MUmVhZGVyIGludm9rZXMgbWV0aG9kcyBvZiB0aGlzIGxpc3RlbmVyIGVpdGhlciB3aGVuIHRoZSB0YWcgaXMganVzdAotICogb3BlbmVkIG9yIHdoZW4gdGhlIHRhZyBpcyBqdXN0IGNsb3NlZC4KLSAqIAotICogQGF1dGhvciBJdmFuIERpbWl0cm92Ci0gKiBAYXV0aG9yIFBhdmxpbiBEb2JyZXYKLSAqIEB2ZXJzaW9uIDEuMAotICovCi0KLXB1YmxpYyBpbnRlcmZhY2UgRXhUYWdMaXN0ZW5lciB7Ci0KLQkvKioKLQkgKiBJbnZva2VkIHdoZW4gYSB0YWcgaXMgb3BlbmVkCi0JICogCi0JICogQHBhcmFtIGFUYWcKLQkgKiAgICAgICAgICAgIHRhZwotCSAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCi0JICovCi0JcHVibGljIHZvaWQgc3RhcnRUYWcoVGFnIGFUYWcpIHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb247Ci0KLQkvKioKLQkgKiBJbnZva2VkIHdoZW4gYSB0YWcgaXMgY2xvc2VkCi0JICogCi0JICogQHBhcmFtIGFUYWcKLQkgKiAgICAgICAgICAgIHRhZwotCSAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCi0JICovCi0JcHVibGljIHZvaWQgZW5kVGFnKFRhZyBhVGFnKSB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uOwotfQpkaWZmIC0tZ2l0IGEvYnVuZGxlcy9vcmcuZWNsaXBzZS5lcXVpbm94LmRzL3NyYy9vcmcvZWNsaXBzZS9lcXVpbm94L2ludGVybmFsL3V0aWwveG1sL1RhZy5qYXZhIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5lcXVpbm94LmRzL3NyYy9vcmcvZWNsaXBzZS9lcXVpbm94L2ludGVybmFsL3V0aWwveG1sL1RhZy5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBjODUwZjEzLi4wMDAwMDAwCi0tLSBhL2J1bmRsZXMvb3JnLmVjbGlwc2UuZXF1aW5veC5kcy9zcmMvb3JnL2VjbGlwc2UvZXF1aW5veC9pbnRlcm5hbC91dGlsL3htbC9UYWcuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEwOSArMCwwIEBACi0vKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgotICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDA4IGJ5IFByb1N5c3QgU29mdHdhcmUgR21iSAotICogaHR0cDovL3d3dy5wcm9zeXN0LmNvbQotICogQWxsIHJpZ2h0cyByZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscwotICogYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2MS4wCi0gKiB3aGljaCBhY2NvbXBhbmllcyB0aGlzIGRpc3RyaWJ1dGlvbiwgYW5kIGlzIGF2YWlsYWJsZSBhdAotICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtdjEwLmh0bWwKLSAqCi0gKiBDb250cmlidXRvcnM6Ci0gKiAgICBQcm9TeXN0IFNvZnR3YXJlIEdtYkggLSBpbml0aWFsIEFQSSBhbmQgaW1wbGVtZW50YXRpb24KLSAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwotcGFja2FnZSBvcmcuZWNsaXBzZS5lcXVpbm94LmludGVybmFsLnV0aWwueG1sOwotCi1pbXBvcnQgamF2YS51dGlsLkVudW1lcmF0aW9uOwotCi0vKioKLSAqIEBhdXRob3IgSXZhbiBEaW1pdHJvdgotICogQGF1dGhvciBQYXZsaW4gRG9icmV2Ci0gKiBAdmVyc2lvbiAxLjAKLSAqLwotCi1wdWJsaWMgaW50ZXJmYWNlIFRhZyB7Ci0JLyoqCi0JICogUmV0dXJucyBhbiBhdHRyaWJ1dGUgdmFsdWUgZm9yIGFuIGF0dHJpYnV0ZSB3aXRoIGEgZ2l2ZW4gbmFtZSAoYUF0dHJOYW1lKQotCSAqIAotCSAqIEBwYXJhbSBhQXR0ck5hbWUKLQkgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIGF0dHJpYnV0ZQotCSAqIEByZXR1cm4gQXR0cmlidXRlIHZhbHVlIGZvciBhdHRyaWJ1dGUgd2l0aCBuYW1lIGdpdmVuIGJ5IGF0dHJOYW1lIG9yIG51bGwKLQkgKiAgICAgICAgIGlmIHRoZXJlIGlzIG5vIHN1Y2ggYW4gYXR0cmlidXRlCi0JICovCi0JcHVibGljIFN0cmluZyBnZXRBdHRyaWJ1dGUoU3RyaW5nIGFBdHRyTmFtZSk7Ci0KLQkvKioKLQkgKiBSZXR1cm5zIGFuIEVudW1lcmF0aW9uIG9mIGFsbCB0aGUgYXR0cmlidXRlcycgbmFtZXMgZm9yIGF0dHJpYnV0ZXMgYmVsb25nCi0JICogdG8gdGhlIHRhZyBvYmplY3QKLQkgKiAKLQkgKiBAcmV0dXJuIEVudW1lcmF0aW9uIHRoYXQgY29udGFpbnMgdGhlIGF0dHJpYnV0ZSBuYW1lcyBvZiB0aGUgYXR0cmlidXRlcwotCSAqICAgICAgICAgZm9yIHRoaXMgdGFnLiBJZiB0aGVyZSBpcyBubyBhdHRyaWJ1dGVzIHRoZW4gdGhlIG1ldGhvZCByZXR1cm5zCi0JICogICAgICAgICBFbXB0eSBlbnVtZXJhdGlvbgotCSAqLwotCXB1YmxpYyBFbnVtZXJhdGlvbiBnZXRBdHRyaWJ1dGVOYW1lcygpOwotCi0JLyoqCi0JICogUmV0dXJucyBhbiBFbnVtZXJhdGlvbiB0aGF0IGNvbnRhaW5zIHRoZSBhdHRyaWJ1dGUgdmFsdWVzIGZvciB0aGUKLQkgKiBhdHRyaWJ1dGVzIHRoYXQgYmVsb25nIHRvIHRoZSB0YWcgb2JqZWN0Ci0JICogCi0JICogQHJldHVybiBFRW51bWVyYXRpb24gdGhhdCBjb250YWlucyB0aGUgYXR0cmlidXRlIHZhbHVlcyBmb3IgdGhlCi0JICogICAgICAgICBhdHRyaWJ1dGVzIHRoYXQgYmVsb25nIHRvIHRoZSB0YWcgb2JqZWN0LiBJZiB0aGVyZSBpcyBubwotCSAqICAgICAgICAgYXR0cmlidXRlcyB0aGVuIHRoZSBtZXRob2QgcmV0dXJucyBFbXB0eSBlbnVtZXJhdGlvbgotCSAqLwotCXB1YmxpYyBFbnVtZXJhdGlvbiBnZXRBdHRyaWJ1dGVWYWx1ZXMoKTsKLQotCS8qKgotCSAqIFJldHVybnMgdGhlIG5hbWUgb2YgdGhlIHRhZwotCSAqIAotCSAqIEByZXR1cm4gdGhlIG5hbWUgb2YgdGhlIHRhZwotCSAqLwotCXB1YmxpYyBTdHJpbmcgZ2V0TmFtZSgpOwotCi0JLyoqCi0JICogUmV0dXJucyBhIHRhZyBjb250ZW50Ci0JICogCi0JICogQHJldHVybiB0YWcgY29udGVudC4gSWYgdGhlIHRhZyBkb2VzIG5vdCBoYXZlIGEgY29udGVudCwgdGhlIG1ldGhvZAotCSAqICAgICAgICAgcmV0dXJucyBlbXB0eSBzdHJpbmcKLQkgKi8KLQlwdWJsaWMgU3RyaW5nIGdldENvbnRlbnQoKTsKLQotCS8qKgotCSAqIFJldHVybnMgdGhlIGxpbmUgaW4gdGhlIFhNTCBmaWxlIHdoZXJlIHRoZSB0YWcgZGVmaW5pdGlvbiBzdGFydHMKLQkgKiAKLQkgKiBAcmV0dXJuIHRoZSBsaW5lIGluIHRoZSBYTUwgZmlsZSB3aGVyZSB0aGUgdGFnIGRlZmluaXRpb24gc3RhcnRzCi0JICovCi0JcHVibGljIGludCBnZXRMaW5lKCk7Ci0KLQkvKioKLQkgKiBSZXR1cm5zIHRoZSBudW1iZXIgb2YgdGhlIGNoaWxkIHRhZ3Mgb2YgdGhpcyB0YWcKLQkgKiAKLQkgKiBAcmV0dXJuIGNoaWxkIHRhZ3MgbnVtYmVyCi0JICovCi0JcHVibGljIGludCBzaXplKCk7Ci0KLQkvKioKLQkgKiBSZXR1cm5zIHRoZSBjaGlsZCB0YWcgYXQgYSBnaXZlbiBwb3NpdGlvbiBpbiBvcmRlciB0aGF0IGlzIGVxdWl2YWxlbnQgdG8KLQkgKiB0aGUgb3JkZXIgb2YgY2hpbGQgdGFncyBkZWZpbmVkIGluIHRoZSBYTUwgZmlsZQotCSAqIAotCSAqIEBwYXJhbSBhUG9zaXRpb24KLQkgKiAgICAgICAgICAgIGNoaWxkIHRhZydzIHBvc2l0aW9uCi0JICogQHJldHVybiB0aGUgY2hpbGQgdGFnIGF0IGEgZ2l2ZW4gcG9zaXRpb24KLQkgKi8KLQlwdWJsaWMgVGFnIGdldFRhZ0F0KGludCBhUG9zaXRpb24pOwotCi0JLyoqCi0JICogUmV0dXJucyB0aGUgY29udGVudCBvZiBhIGNoaWxkIHRhZyB3aXRoIGluZGV4IHBvc2l0aW9uIGVxdWFscyB0byBhUG9zIGJ1dAotCSAqIG9ubHkgaWYgaXRzIG5hbWUgaXMgZXF1YWwgdG8gYU5hbWUuIE90aGVyd2lzZSB0aGUgbWV0aG9kIHRocm93cyBhbgotCSAqIGV4Y2VwdGlvbgotCSAqIAotCSAqIEBwYXJhbSBhUG9zCi0JICogICAgICAgICAgICBpbmRleCBvZiB0aGUgdGFnIGluIGl0cyBwYXJlbnQgbGlzdAotCSAqIEBwYXJhbSBhTmFtZQotCSAqICAgICAgICAgICAgdGhlIG5hbWUgb2YgdGhlIHRhZwotCSAqIEByZXR1cm4gdGFnIGNvbnRlbnQKLQkgKiBAdGhyb3dzIE51bGxQb2ludGVyRXhjZXB0aW9uCi0JICogICAgICAgICAgICAgaWYgdGhlcmUgaXMgbm8gdGFnIG9uIHRoZSBnaXZlbiBwb3NpdGlvbgotCSAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCi0JICogICAgICAgICAgICAgaWYgdGhlIG5hbWUgb2YgdGhlIHRhZyBvbiB0aGUgZ2l2ZW4gcG9zaXRpb24gZG9lcyBub3QgbWF0Y2gKLQkgKiAgICAgICAgICAgICB0aGUgcmVxdWVzdGVkIG5hbWUKLQkgKi8KLQlwdWJsaWMgU3RyaW5nIGdldENvbnRlbnQoaW50IGFQb3MsIFN0cmluZyBhTmFtZSk7Ci19CmRpZmYgLS1naXQgYS9idW5kbGVzL29yZy5lY2xpcHNlLmVxdWlub3guZHMvc3JjL29yZy9lY2xpcHNlL2VxdWlub3gvaW50ZXJuYWwvdXRpbC94bWwvVGFnQ2xhc3MuamF2YSBiL2J1bmRsZXMvb3JnLmVjbGlwc2UuZXF1aW5veC5kcy9zcmMvb3JnL2VjbGlwc2UvZXF1aW5veC9pbnRlcm5hbC91dGlsL3htbC9UYWdDbGFzcy5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBiMmE0MDU5Li4wMDAwMDAwCi0tLSBhL2J1bmRsZXMvb3JnLmVjbGlwc2UuZXF1aW5veC5kcy9zcmMvb3JnL2VjbGlwc2UvZXF1aW5veC9pbnRlcm5hbC91dGlsL3htbC9UYWdDbGFzcy5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMjk2ICswLDAgQEAKLS8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMDggYnkgUHJvU3lzdCBTb2Z0d2FyZSBHbWJICi0gKiBodHRwOi8vd3d3LnByb3N5c3QuY29tCi0gKiBBbGwgcmlnaHRzIHJlc2VydmVkLiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzCi0gKiBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYxLjAKLSAqIHdoaWNoIGFjY29tcGFuaWVzIHRoaXMgZGlzdHJpYnV0aW9uLCBhbmQgaXMgYXZhaWxhYmxlIGF0Ci0gKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC12MTAuaHRtbAotICoKLSAqIENvbnRyaWJ1dG9yczoKLSAqICAgIFByb1N5c3QgU29mdHdhcmUgR21iSCAtIGluaXRpYWwgQVBJIGFuZCBpbXBsZW1lbnRhdGlvbgotICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi1wYWNrYWdlIG9yZy5lY2xpcHNlLmVxdWlub3guaW50ZXJuYWwudXRpbC54bWw7Ci0KLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotaW1wb3J0IG9yZy5lY2xpcHNlLmVxdWlub3guaW50ZXJuYWwuZHMuQWN0aXZhdG9yOwotaW1wb3J0IG9yZy5lY2xpcHNlLmVxdWlub3guaW50ZXJuYWwudXRpbC5zdHJpbmcuQ2hhckJ1ZmZlcjsKLQotLyoqCi0gKiBDbGFzcyBjb3JyZXNwb25kaW5nIHRvIG9uZSBYTUwgdGFnLCBjb250YWluaW5nIGl0cyB0YWcgbmFtZSwgYXR0cmlidXRlcywKLSAqIGNvbnRlbnQgc3RyaW5nIGFuZCB0cmVlIG9mIHRoZSBzdWIgdGFncy4KLSAqIAotICogQGF1dGhvciBJdmFuIERpbWl0cm92Ci0gKiBAYXV0aG9yIFBhdmxpbiBEb2JyZXYKLSAqIEB2ZXJzaW9uIDEuMAotICovCi0KLXB1YmxpYyBjbGFzcyBUYWdDbGFzcyB7Ci0KLQlwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgSU5URVJOX1RBR0NPTlRFTlQgPSAieG1sLmludGVybi50YWdjb250ZW50IjsKLQlwcml2YXRlIHN0YXRpYyBib29sZWFuIGZJbnRlcm5UYWdDb250ZW50ID0gQWN0aXZhdG9yLmdldEJvb2xlYW4oSU5URVJOX1RBR0NPTlRFTlQpOwotCi0JcHJpdmF0ZSBDaGFyQnVmZmVyIGZDb250ZW50ID0gbnVsbDsKLQlwcml2YXRlIFN0cmluZyBmTmFtZSA9IG51bGw7Ci0JcHJpdmF0ZSBWZWN0b3IgZlRhZ3MgPSBudWxsOwotCVN0cmluZyBmQXR0cmlidXRlcyA9IG51bGw7Ci0JcHJpdmF0ZSBpbnQgZkxpbmUgPSAtMTsKLQlwcm90ZWN0ZWQgYm9vbGVhbiBmSW5saW5lID0gZmFsc2U7Ci0KLQkvKioKLQkgKiBDcmVhdGVzIGFuIGVtcHR5IHRhZyBub2RlCi0JICovCi0JcHVibGljIFRhZ0NsYXNzKCkgewotCQkvLyBEbyBub3RoaW5nIGhlcmUKLQl9Ci0KLQkvKioKLQkgKiBDcmVhdGVzIHRhZyBub2RlIHdpdGggc3BlY2lmaWVkIG5hbWUKLQkgKiAKLQkgKiBAcGFyYW0gbmFtZQotCSAqICAgICAgICAgICAgdGFnIG5hbWUKLQkgKi8KLQlwdWJsaWMgVGFnQ2xhc3MoU3RyaW5nIG5hbWUpIHsKLQkJZk5hbWUgPSBuYW1lOwotCX0KLQotCS8qKgotCSAqIENyZWF0ZXMgdGFnIG5vZGUgd2l0aCBzcGVjaWZpZWQgbmFtZQotCSAqIAotCSAqIEBwYXJhbSBsaW5lCi0JICogICAgICAgICAgICB0aGUgbGluZSBpbiB0aGUgWE1MIGZpbGUgd2hlcmUgdGhlIHRhZ3MgYmVnaW4uCi0JICogQHBhcmFtIG5hbWUKLQkgKiAgICAgICAgICAgIHRhZyBuYW1lCi0JICovCi0JcHVibGljIFRhZ0NsYXNzKGludCBsaW5lLCBTdHJpbmcgbmFtZSkgewotCQlmTGluZSA9IGxpbmU7Ci0JCWZOYW1lID0gbmFtZTsKLQl9Ci0KLQkvKioKLQkgKiBDcmVhdGVzIHRhZyBub2RlIHdpdGggc3BlY2lmaWVkIG5hbWUgYW5kIGNvbnRlbnQgc3RyaW5nCi0JICogCi0JICogQHBhcmFtIG5hbWUKLQkgKiAgICAgICAgICAgIHRhZyBuYW1lCi0JICogQHBhcmFtIGNvbnRlbnRTdHIKLQkgKiAgICAgICAgICAgIGNvbnRlbnQgc3RyaW5nIG9mIHRoZSB0YWcKLQkgKi8KLQlwdWJsaWMgVGFnQ2xhc3MoU3RyaW5nIG5hbWUsIFN0cmluZyBjb250ZW50U3RyKSB7Ci0JCXNldHVwKC0xLCBuYW1lLCBjb250ZW50U3RyKTsKLQl9Ci0KLQkvKioKLQkgKiBDcmVhdGVzIHRhZyBub2RlIHdpdGggc3BlY2lmaWVkIG5hbWUgYW5kIGNvbnRlbnQgc3RyaW5nCi0JICogCi0JICogQHBhcmFtIGxpbmUKLQkgKiAgICAgICAgICAgIHRoZSBsaW5lIGluIHRoZSBYTUwgZmlsZSB3aGVyZSB0aGUgdGFncyBiZWdpbi4KLQkgKiBAcGFyYW0gbmFtZQotCSAqICAgICAgICAgICAgdGFnIG5hbWUKLQkgKiBAcGFyYW0gY29udGVudFN0cgotCSAqICAgICAgICAgICAgY29udGVudCBzdHJpbmcgb2YgdGhlIHRhZwotCSAqLwotCXB1YmxpYyBUYWdDbGFzcyhpbnQgbGluZSwgU3RyaW5nIG5hbWUsIFN0cmluZyBjb250ZW50U3RyKSB7Ci0JCXNldHVwKGxpbmUsIG5hbWUsIGNvbnRlbnRTdHIpOwotCX0KLQotCXByaXZhdGUgdm9pZCBzZXR1cChpbnQgbGluZSwgU3RyaW5nIG5hbWUsIFN0cmluZyBjb250ZW50U3RyKSB7Ci0JCWZMaW5lID0gbGluZTsKLQkJZk5hbWUgPSBuYW1lOwotCQlpZiAoY29udGVudFN0ciAhPSBudWxsICYmIGNvbnRlbnRTdHIubGVuZ3RoKCkgPiAwKSB7Ci0JCQlmQ29udGVudCA9IG5ldyBDaGFyQnVmZmVyKGNvbnRlbnRTdHIubGVuZ3RoKCkpOwotCQkJZkNvbnRlbnQuYXBwZW5kKGNvbnRlbnRTdHIpOwotCQl9Ci0JfQotCi0JLyoqCi0JICogQXBwZW5kcyB0aGUgJ3RvQXBwZW5kJyBDaGFyQnVmZmVyIGNvbnRlbnQgdG8gdGhlIGNvbnRlbnQgYnVmZmVyCi0JICogCi0JICogQHBhcmFtIHRvQXBwZW5kCi0JICogICAgICAgICAgICBDaGFyQnVmZmVyIGNvbnRlbnQgdG8gYXBwZW5kCi0JICovCi0JcHJvdGVjdGVkIHZvaWQgYXBwZW5kQ29udGVudChDaGFyQnVmZmVyIHRvQXBwZW5kKSB7Ci0JCWlmIChmQ29udGVudCA9PSBudWxsKSB7Ci0JCQlmQ29udGVudCA9IG5ldyBDaGFyQnVmZmVyKCk7Ci0JCX0KLQkJZkNvbnRlbnQuYXBwZW5kKHRvQXBwZW5kLmdldFZhbHVlKCkpOwotCX0KLQotCS8qKgotCSAqIEFwcGVuZHMgdGhlICd0b0FwcGVuZCcgc3RyaW5nIHRvIHRoZSBjb250ZW50IGJ1ZmZlcgotCSAqIAotCSAqIEBwYXJhbSB0b0FwcGVuZAotCSAqICAgICAgICAgICAgc3RyaW5nIHRvIGFwcGVuZAotCSAqLwotCXByb3RlY3RlZCB2b2lkIGFwcGVuZENvbnRlbnQoU3RyaW5nIHRvQXBwZW5kKSB7Ci0JCWlmIChmQ29udGVudCA9PSBudWxsKSB7Ci0JCQlmQ29udGVudCA9IG5ldyBDaGFyQnVmZmVyKCk7Ci0JCX0KLQkJZkNvbnRlbnQuYXBwZW5kKHRvQXBwZW5kKTsKLQl9Ci0KLQkvKioKLQkgKiBSZXR1cm5zIGNvbnRlbnQgc3RyaW5nIG9mIHRoZSB0YWcKLQkgKiAKLQkgKiBAcmV0dXJuIHRhZyBjb250ZW50IG5vdGU6IFRoZSBjb250ZW50IHRoYXQgaXMgdG8gYmUgcmV0dXJuZWQgd2lsbCBiZQotCSAqICAgICAgICAgdHJpbW1lZCBmaXJzdAotCSAqLwotCS8qCi0JICogSW1wbGVtZW50YXRpb24gTm90ZTogVGhlIGNvbnRlbnQgc3RyaW5nIGlzIG5vdCBzdWl0YWJsZSB0byBiZSBpbnRlcm5lZAotCSAqIHdpdGggU3RyaW5nKCkuaW50ZXJuKCkgYmVjYXVzZSBpdCBpcyBtb3JlIG9mdGVuIHRvIGJlIHVuaXF1ZSBhbmQgdGhlCi0JICogYmVuZWZpdCB3aWxsIGJlIG11Y2ggc21hbGxlciB0aGFuIGV4cGVjdGVkLgotCSAqLwotCXB1YmxpYyBTdHJpbmcgZ2V0Q29udGVudCgpIHsKLQkJU3RyaW5nIHJlc3VsdCA9ICIiOwotCQlpZiAoZkNvbnRlbnQgIT0gbnVsbCkgewotCQkJcmVzdWx0ID0gZkNvbnRlbnQudHJpbSgpOwotCQkJaWYgKGZJbnRlcm5UYWdDb250ZW50KSB7Ci0JCQkJcmVzdWx0ID0gcmVzdWx0LmludGVybigpOwotCQkJfQotCQl9Ci0JCXJldHVybiByZXN1bHQ7Ci0JCS8vIFRPRE8gLW9JdmFuOiBTaG91bGQgbm90IGl0IGJlIG51bGwgaW5zdGVhZCBvZiBlbXB0eSBzdHJpbmc/Li4uCi0JCS8vIFBsYW1lbjogWWVzIGl0IGhhdmUgdG8gYmUgbnVsbCBpbnN0ZWQgb2YgIiIgYmVjYXVzZSB0aGUgb2xkIG9uZSB1c2VkCi0JCS8vIHRvIHJldHVybiBudWxsLgotCQkvLyBJdmFuIERpbWl0cm92OiBUaGUgbWV0YXR5cGluZyBjb2RlIHJlbGllcyBvbiB0aGUgZmFjdCB0aGF0IHRoZQotCQkvLyBjb250ZW50IGlzIG5ldmVyIG51bGwKLQl9Ci0KLQkvKioKLQkgKiBSZXR1cm5zIHRoZSBjb250ZW50IG9mIGEgY2hpbGQgdGFnIHdpdGggaW5kZXggcG9zaXRpb24gZXF1YWxzIHRvIGFQb3MgYnV0Ci0JICogb25seSBpZiBpdHMgbmFtZSBpcyBlcXVhbCB0byBhTmFtZS4gT3RoZXJ3aXNlIHRoZSBtZXRob2QgdGhyb3dzIGFuCi0JICogZXhjZXB0aW9uCi0JICogCi0JICogQHBhcmFtIGFQb3MKLQkgKiAgICAgICAgICAgIGluZGV4IG9mIHRoZSB0YWcgaW4gaXRzIHBhcmVudCBsaXN0Ci0JICogQHBhcmFtIGFOYW1lCi0JICogICAgICAgICAgICB0aGUgbmFtZSBvZiB0aGUgdGFnCi0JICogQHJldHVybiB0YWcgY29udGVudAotCSAqIEB0aHJvd3MgTnVsbFBvaW50ZXJFeGNlcHRpb24KLQkgKiAgICAgICAgICAgICBpZiB0aGVyZSBpcyBubyB0YWcgb24gdGhlIGdpdmVuIHBvc2l0aW9uCi0JICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KLQkgKiAgICAgICAgICAgICBpZiB0aGUgbmFtZSBvZiB0aGUgdGFnIG9uIHRoZSBnaXZlbiBwb3NpdGlvbiBkb2VzIG5vdCBtYXRjaAotCSAqICAgICAgICAgICAgIHRoZSByZXF1ZXN0ZWQgbmFtZQotCSAqLwotCXB1YmxpYyBTdHJpbmcgZ2V0Q29udGVudChpbnQgYVBvcywgU3RyaW5nIGFOYW1lKSB7Ci0JCVRhZ0NsYXNzIGNoaWxkID0gZ2V0VGFnQXQoYVBvcyk7Ci0JCWlmIChjaGlsZCA9PSBudWxsKQotCQkJdGhyb3cgbmV3IE51bGxQb2ludGVyRXhjZXB0aW9uKCJUaGVyZSBpcyBubyBzdWNoIGEgdGFnLiBbUGFyZW50IHRhZyBuYW1lXSA9IFsiICsgYU5hbWUgKyAiXSwgW2NoaWxkIHRhZyBpbmRleF0gPSAiICsgYVBvcyArICIsIFtjaGlsZCB0YWcgbmFtZV0gPSBbIiArIGFOYW1lICsgJ10nKTsKLQotCQlpZiAoY2hpbGQuZ2V0TmFtZSgpLmVxdWFscyhhTmFtZSkpCi0JCQlyZXR1cm4gY2hpbGQuZ2V0Q29udGVudCgpOwotCi0JCXRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIlRoZXJlIGlzIG5vIHN1Y2ggYSB0YWcuIFtQYXJlbnQgdGFnIG5hbWVdID0gWyIgKyBhTmFtZSArICJdLCBbY2hpbGQgdGFnIGluZGV4XSA9ICIgKyBhUG9zICsgIiwgW2NoaWxkIHRhZyBuYW1lXSA9IFsiICsgYU5hbWUgKyAnXScpOwotCX0KLQotCS8qKgotCSAqIFJldHVybnMgdGhlIGludGVybmFsIGNvbnRlbnQgYnVmZmVyCi0JICogCi0JICogQHJldHVybiBpbnRlcm5hbCBjb250ZW50IGJ1ZmZlciBhcyBDaGFyQnVmZmVyCi0JICovCi0JcHJvdGVjdGVkIENoYXJCdWZmZXIgZ2V0Q29udGVudEJ1ZmZlcigpIHsKLQkJaWYgKGZDb250ZW50ID09IG51bGwpIHsKLQkJCWZDb250ZW50ID0gbmV3IENoYXJCdWZmZXIoKTsKLQkJfQotCQlyZXR1cm4gZkNvbnRlbnQ7Ci0JfQotCi0JLyoqCi0JICogUmV0dXJucyBuYW1lIG9mIHRoZSB0YWcKLQkgKiAKLQkgKiBAcmV0dXJuIHRhZyBuYW1lCi0JICovCi0JcHVibGljIFN0cmluZyBnZXROYW1lKCkgewotCQlyZXR1cm4gZk5hbWU7Ci0JfQotCi0JLyoqCi0JICogU2V0cyB0aGUgbmFtZSBvZiB0aGUgdGFnCi0JICogCi0JICogQHBhcmFtIGFOYW1lCi0JICogICAgICAgICAgICBuYW1lIG9mIHRoZSB0YWcKLQkgKi8KLQlwcm90ZWN0ZWQgdm9pZCBzZXROYW1lKFN0cmluZyBhTmFtZSkgewotCQlmTmFtZSA9IGFOYW1lOwotCX0KLQotCS8qKgotCSAqIFJldHVybnMgc3RyaW5nIHdpdGggYWxsIGF0dHJpYnV0ZSBuYW1lcyBhbmQgdmFsdWVzIG9mIHRoZSB0YWcsIGFzIGlzIGluCi0JICogdGhlIFhNTCBjb250ZW50LgotCSAqIAotCSAqIEByZXR1cm4gdGFnIG5hbWUgYW5kIGl0cyBhdHRyaWJ1dGVzCi0JICovCi0JcHVibGljIFN0cmluZyBnZXRBdHRyaWJ1dGVzKCkgewotCQlyZXR1cm4gKGZBdHRyaWJ1dGVzICE9IG51bGwpID8gZkF0dHJpYnV0ZXMgOiAiIjsKLQl9Ci0KLQkvKioKLQkgKiBSZXR1cm5zIGFuIGF0dHJpYnV0ZSB2YWx1ZSBmb3IgYW4gYXR0cmlidXRlIHdpdGggYSBnaXZlbiBuYW1lIChhdHRyTmFtZSkKLQkgKiAKLQkgKiBAcGFyYW0gYXR0ck5hbWUKLQkgKiAgICAgICAgICAgIHRoZSBuYW1lIG9mIGF0dHJpYnV0ZQotCSAqIEByZXR1cm4gQXR0cmlidXRlIHZhbHVlIGZvciBhdHRyaWJ1dGUgd2l0aCBuYW1lIGdpdmVuIGJ5IGF0dHJOYW1lIG9yIG51bGwKLQkgKiAgICAgICAgIGlmIHRoZXJlIGlzIG5vIHN1Y2ggYW4gYXR0cmlidXRlCi0JICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgotCSAqICAgICAgICAgICAgIGlmIGF0dHJOYW1lIGlzIG51bGwKLQkgKi8KLQlwdWJsaWMgU3RyaW5nIGdldEF0dHJpYnV0ZShTdHJpbmcgYXR0ck5hbWUpIHsKLQkJcmV0dXJuIFhNTFV0aWwuZ2V0QXR0cmlidXRlVmFsdWUoZkF0dHJpYnV0ZXMsIGF0dHJOYW1lLCAwKTsKLQl9Ci0KLQkvKioKLQkgKiBBZGRzIGEgY2hpbGQgdGFnIHRvIHRoaXMgb25lCi0JICogCi0JICogQHBhcmFtIGFUYWcKLQkgKiAgICAgICAgICAgIGEgdGFnIHRvIGJlIGFkZGVkIGFzIGEgY2hpbGQgdGFnCi0JICovCi0JcHVibGljIHZvaWQgYWRkVGFnKFRhZ0NsYXNzIGFUYWcpIHsKLQkJaWYgKGZUYWdzID09IG51bGwpIHsKLQkJCWZUYWdzID0gbmV3IFZlY3Rvcig1LCA1KTsKLQkJfQotCQlmVGFncy5hZGRFbGVtZW50KGFUYWcpOwotCX0KLQotCS8qKgotCSAqIFJldHVybnMgc3ViIHRhZyBvZiB0aGlzIG9uZSBhdCBhIGdpdmVuIHBvc2l0aW9uCi0JICogCi0JICogQHBhcmFtIGFQb3MKLQkgKiAgICAgICAgICAgIHBvc2l0aW9uIG9mIHRoZSBzZWFyY2hlZCB0YWcKLQkgKiBAcmV0dXJuIGEgY2hpbGQgdGFnIGF0IGEgZ2l2ZW4gcG9zaXRpb24gaW4gdGhlIGNoaWxkLXRhZ3Mgc2V0IG9yIG51bGwgaWYKLQkgKiAgICAgICAgIHRoZXJlIGlzIG5vIHN1Y2ggYSB0YWcKLQkgKi8KLQlwdWJsaWMgVGFnQ2xhc3MgZ2V0VGFnQXQoaW50IGFQb3MpIHsKLQkJcmV0dXJuIChmVGFncyA9PSBudWxsKSA/IG51bGwgOiAoVGFnQ2xhc3MpIGZUYWdzLmVsZW1lbnRBdChhUG9zKTsKLQl9Ci0KLQkvKioKLQkgKiBSZXR1cm5zIGNoaWxkcmVuIHRhZ3MgY291bnQKLQkgKiAKLQkgKiBAcmV0dXJuIHN1YiB0YWdzIGNvdW50Ci0JICovCi0JcHVibGljIGludCBzaXplKCkgewotCQlyZXR1cm4gKGZUYWdzID09IG51bGwpID8gMCA6IGZUYWdzLnNpemUoKTsKLQl9Ci0KLQkvKioKLQkgKiBSZXR1cm5zIHRoZSBsaW5lIGluIHRoZSBYTUwgZmlsZSB3aGVyZSB0aGUgdGFncyBiZWdpbi4KLQkgKiAKLQkgKiBAcmV0dXJuIFJldHVybnMgdGhlIGxpbmUuCi0JICovCi0JcHVibGljIGludCBnZXRMaW5lKCkgewotCQlyZXR1cm4gZkxpbmU7Ci0JfQotCi0JLyoqCi0JICogU2V0cyB0aGUgdGFnIGxpbmUgbnVtYmVyICh0aGUgbGluZSBpbiB0aGUgWE1MIGZpbGUgd2hlcmUgdGhlIGN1cnJlbnQgdGFnCi0JICogc3RhcnRzKQotCSAqIAotCSAqIEBwYXJhbSBhTGluZQotCSAqICAgICAgICAgICAgY3VycmVudCB0YWcgbGluZSBudW1iZXIKLQkgKi8KLQlwcm90ZWN0ZWQgdm9pZCBzZXRMaW5lKGludCBhTGluZSkgewotCQlmTGluZSA9IGFMaW5lOwotCX0KLQotCXByb3RlY3RlZCB2b2lkIHNldElubGluZSgpIHsKLQkJZklubGluZSA9IHRydWU7Ci0JfQotfQpkaWZmIC0tZ2l0IGEvYnVuZGxlcy9vcmcuZWNsaXBzZS5lcXVpbm94LmRzL3NyYy9vcmcvZWNsaXBzZS9lcXVpbm94L2ludGVybmFsL3V0aWwveG1sL1RhZ0xpc3RlbmVyLmphdmEgYi9idW5kbGVzL29yZy5lY2xpcHNlLmVxdWlub3guZHMvc3JjL29yZy9lY2xpcHNlL2VxdWlub3gvaW50ZXJuYWwvdXRpbC94bWwvVGFnTGlzdGVuZXIuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNGMxZThjZC4uMDAwMDAwMAotLS0gYS9idW5kbGVzL29yZy5lY2xpcHNlLmVxdWlub3guZHMvc3JjL29yZy9lY2xpcHNlL2VxdWlub3gvaW50ZXJuYWwvdXRpbC94bWwvVGFnTGlzdGVuZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDM0ICswLDAgQEAKLS8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMDggYnkgUHJvU3lzdCBTb2Z0d2FyZSBHbWJICi0gKiBodHRwOi8vd3d3LnByb3N5c3QuY29tCi0gKiBBbGwgcmlnaHRzIHJlc2VydmVkLiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzCi0gKiBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYxLjAKLSAqIHdoaWNoIGFjY29tcGFuaWVzIHRoaXMgZGlzdHJpYnV0aW9uLCBhbmQgaXMgYXZhaWxhYmxlIGF0Ci0gKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC12MTAuaHRtbAotICoKLSAqIENvbnRyaWJ1dG9yczoKLSAqICAgIFByb1N5c3QgU29mdHdhcmUgR21iSCAtIGluaXRpYWwgQVBJIGFuZCBpbXBsZW1lbnRhdGlvbgotICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi1wYWNrYWdlIG9yZy5lY2xpcHNlLmVxdWlub3guaW50ZXJuYWwudXRpbC54bWw7Ci0KLS8qKgotICogVGhpcyBpbnRlcmZhY2UgaXMgdXNlZCB3aGlsZSBwYXJzaW5nIHhtbCBmaWxlcy4gSXQncyBtZXRob2QgaXMgaW52b2tlZCBvbgotICogZXZlcnkgY2xvc2luZyB0YWcuCi0gKiAKLSAqIEBhdXRob3IgUGF2bGluIERvYnJldgotICogQHZlcnNpb24gMS4wCi0gKi8KLQotcHVibGljIGludGVyZmFjZSBUYWdMaXN0ZW5lciB7Ci0KLQkvKioKLQkgKiBJbnZva2VkIHdoZW4gYSB0YWcgaGFzIGJlZW4gY2xvc2VkCi0JICogCi0JICogQHBhcmFtIHRhZwotCSAqICAgICAgICAgICAgdGFnIHdpdGggaXRzIGNvbnRlbnQgYW5kIGl0cyBzdWJ0YWdzCi0JICogQHRocm93cyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24KLQkgKiAgICAgICAgICAgICBtYXkgYmUgdGhyb3duIHdoaWxlIHByb2NjZXNzaW5nIHRoZSB0YWcgc3RydWN0dXJlCi0JICovCi0JcHVibGljIHZvaWQgdXNlVGFnKFRhZ0NsYXNzIHRhZykgdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbjsKLQotfQpkaWZmIC0tZ2l0IGEvYnVuZGxlcy9vcmcuZWNsaXBzZS5lcXVpbm94LmRzL3NyYy9vcmcvZWNsaXBzZS9lcXVpbm94L2ludGVybmFsL3V0aWwveG1sL1hNTFBhcnNlci5qYXZhIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5lcXVpbm94LmRzL3NyYy9vcmcvZWNsaXBzZS9lcXVpbm94L2ludGVybmFsL3V0aWwveG1sL1hNTFBhcnNlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAzYjM2ZDMwLi4wMDAwMDAwCi0tLSBhL2J1bmRsZXMvb3JnLmVjbGlwc2UuZXF1aW5veC5kcy9zcmMvb3JnL2VjbGlwc2UvZXF1aW5veC9pbnRlcm5hbC91dGlsL3htbC9YTUxQYXJzZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEyMSArMCwwIEBACi0vKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgotICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDA4IGJ5IFByb1N5c3QgU29mdHdhcmUgR21iSAotICogaHR0cDovL3d3dy5wcm9zeXN0LmNvbQotICogQWxsIHJpZ2h0cyByZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscwotICogYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2MS4wCi0gKiB3aGljaCBhY2NvbXBhbmllcyB0aGlzIGRpc3RyaWJ1dGlvbiwgYW5kIGlzIGF2YWlsYWJsZSBhdAotICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtdjEwLmh0bWwKLSAqCi0gKiBDb250cmlidXRvcnM6Ci0gKiAgICBQcm9TeXN0IFNvZnR3YXJlIEdtYkggLSBpbml0aWFsIEFQSSBhbmQgaW1wbGVtZW50YXRpb24KLSAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwotcGFja2FnZSBvcmcuZWNsaXBzZS5lcXVpbm94LmludGVybmFsLnV0aWwueG1sOwotCi1pbXBvcnQgamF2YS5pby4qOwotaW1wb3J0IG9yZy5lY2xpcHNlLmVxdWlub3guaW50ZXJuYWwudXRpbC54bWwuaW1wbC5YTUxQYXJzZXJJbXBsOwotCi0vKioKLSAqIDxwPgotICogQ2xhc3MgdXNlZCBmb3IgcmVhZGluZyBvZiB4bWwgZmlsZXMsIGNyZWF0aW5nIHRyZWUgc3RydWN0dXJlIG9mICdUYWdDbGFzcycKLSAqIGZvciBlYWNoIHhtbCB0YWcuIFdoZW4gcmVhZGVyIHJlYWNoZXMgYSBjbG9zZWQgdGFnIGl0IG5vdGlmaWVzIGEgZ2l2ZW4KLSAqICdUYWdMaXN0ZW5lcicgYW5kIHNlbmRzIHRoZSBsYXN0IHRhZyB0byBpdC4gSWYgY2xvc2luZyB0YWcgZG9lcyBub3QKLSAqIGNvcnJlc3BvbmQgd2l0aCB0aGUgbGFzdCBvcGVuIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpcyB0aHJvd24uIFRoZXJlIGlzIGEKLSAqIGRlYnVnIHByb3BlcnR5ICd4bWwuZGVidWcnIHVzZWQgdG8gZHVtcCBhbiBFeGNlcHRpb25zIG9jY3VycmVkIHdoaWxlCi0gKiBvcGVyYXRpb24gaXMgcnVubmluZy4KLSAqIDwvcD4KLSAqIAotICogPHA+Ci0gKiBUaGUgcGFyc2VyLCBpbiBnZW5lcmFsLCBpcyBhIHNpbXBsZSBYTUwgcGFyc2VyIHRoYXQgaW1wbGVtZW50cwotICogJnF1b3Q7UmVjdXJzaXZlIGRlc2NlbnQmcXVvdDsgcGFyc2luZyBtZXRob2QuCi0gKiAKLSAqIEtub3duIGxpbWl0YXRpb25zOjxicj4KLSAqIAotICogPHByZT4KLSAqICBDdXJyZW50bHkgdGhpcyBYTUxQYXJzZXIgZG9lcyBub3Qgc3VwcG9ydCB0aGUgZm9sbG93aW5nIHNwZWNpYWwgdGFnczoKLSAqICAxLiAmbHQ7P1RBR19OQU1FIC4uLi4uID8mZ3Q7ICAgb3IgYWxzbyAmcXVvdDtQcm9jZXNzaW5nIEluc3RydWN0aW9ucyZxdW90OwotICogIDIuICZsdDshRE9DVFlQRSAuLi4uICZndDsKLSAqICAzLiAmbHQ7IUVMRU1FTlQgLi4uLiAmZ3Q7Ci0gKiAgNC4gJmx0OyFBVFRMSVNUIC4uLi4gJmd0OwotICogIDUuICZsdDshRU5USVRZIC4uLi4gJmd0OwotICogPC9wcmU+Ci0gKiAKLSAqIDxicj4KLSAqIFRoZSBwYXJzZXIgc2tpcHBlcyB0aGVzZSB0YWdzIChpdCBzZWFyY2hlcyBmb3IgJz4nIHN5bWJvbCBhbmQgY2xvc2VzIHRoZQotICogJ3NwZWNpYWwnIHRhZykuPGJyPgotICogCi0gKiBAYXV0aG9yIEl2YW4gRGltaXRyb3YKLSAqIEBhdXRob3IgUGF2bGluIERvYnJldgotICogQHZlcnNpb24gMS4wCi0gKi8KLQotcHVibGljIGNsYXNzIFhNTFBhcnNlciB7Ci0KLQkvKioKLQkgKiBQYXJzZXMgYSBYTUwgZmlsZSBnaXZlbiB0aHJvdWdoIGFJbnB1dFN0cmVhbSBhbmQgZHVyaW5nIHRoZSBwYXJzaW5nCi0JICogbm90aWZpZXMgYUxpc3RlbmVyIGZvciBjbG9zZS10YWcgYW5kIG9wZW4tdGFnIGV2ZW50cyA8YnI+Ci0JICogPGJyPgotCSAqIDxiPk5vdGU6IFRoZSBYTUxSZWFkZXIgZG9lcyBub3QgY2xvc2UgdGhlIHBhc3NlZCBSZWFkZXIgb3IgSW5wdXRTdHJlYW0KLQkgKiAKLQkgKiBAcGFyYW0gYUlucHV0U3RyZWFtCi0JICogICAgICAgICAgICBhbiBJbnB1dFN0cmVhbSB0byByZWFkIHRoZSBYTUwgZmlsZSBmcm9tCi0JICogQHBhcmFtIGFMaXN0ZW5lcgotCSAqICAgICAgICAgICAgRXhUYWdMaXN0ZW5lciB0aGF0IHdpbGwgYmUgbm90aWZpZWQgb24gY2xvc2UtdGFnIGFuZCBvcGVuLXRhZwotCSAqICAgICAgICAgICAgZXZlbnRzCi0JICogQHBhcmFtIGFMZXZlbAotCSAqICAgICAgICAgICAgaW5kaWNhdGVzIHRoZSB0YWcgbGV2ZWwgdGhhdCB0aGUgbGlzdGVuZXIgd2lsbCBiZSBpbnZva2VkIGZvci4KLQkgKiAgICAgICAgICAgIEZvciBleGFtcGxlIGlmIHRoZSBYTUwgaXM6PGJyPgotCSAqIAotCSAqIDxwcmU+Ci0JICogICZsdDthJmd0OwotCSAqICAgICZsdDtiJmd0OwotCSAqICAgICAgJmx0O2MgLyZndDsKLQkgKiAgICAmbHQ7L2ImZ3Q7Ci0JICogICZsdDsvYSZndDsKLQkgKiA8L3ByZT4KLQkgKiAKLQkgKiA8YnI+Ci0JICogICAgICAgICAgICBhbmQgdGhlIHBhc3NlZCBhTGV2ZWwgaXMgMiB0aGVuIHRoZSBsaXN0ZW5lciB3aWxsIGJlIGludm9rZWQKLQkgKiAgICAgICAgICAgIG9ubHkgZm9yIHRhZ3MgdGhhdCBoYXZlIGxldmVsIDIsIGkuZS4gaW4gb3VyIGV4YW1wbGUgdGhlCi0JICogICAgICAgICAgICBsaXN0ZW5lciB3aWxsIGJlIGludm9rZWQgb25seSBmb3IgdGFnICZsdDtiJmd0Ozxicj4KLQkgKiAgICAgICAgICAgIDx1bD4KLQkgKiAgICAgICAgICAgIDxsaT5WYWx1ZSBsZXNzIHRoYW4gMCBpbmRpY2F0ZXMgJnF1b3Q7aW52b2tlIGxpc3RlbmVyIGZvciBhbGwKLQkgKiAgICAgICAgICAgIHRhZ3Mgbm8gbWF0dGVyIHdoYXQgYXJlIHRoZWlyIGxldmVscyZxdW90OzwvbGk+Ci0JICogICAgICAgICAgICA8bGk+VmFsdWUgb2YgMCBpbmRpY2F0ZXMgdGhhdCB0aGUgbGlzdGVuZXIgbXVzdCBub3QgYmUKLQkgKiAgICAgICAgICAgIGludm9rZWQgaW4gZ2VuZXJhbCBubyBtYXR0ZXIgd2hhdCBpcyB0aGUgdGFnIGxldmVsPC9saT4KLQkgKiAgICAgICAgICAgIDxsaT5WYWx1ZSBncmVhdGVyIHRoYW4gMCBpbmRpY2F0ZXMgdGhlIHRhZyBsZXZlbCB0aGF0IHRoZQotCSAqICAgICAgICAgICAgbGlzdGVuZXIgd2lsbCBiZSBpbnZva2VkIGZvcjwvbGk+Ci0JICogICAgICAgICAgICBkZXNjcmlwdGlvbgotCSAqIEB0aHJvd3MgSU9FeGNlcHRpb24KLQkgKiAgICAgICAgICAgICBpZiBzb21lIElPIGVycm9yIG9jY3VycyB3aGVuIHJlYWRpbmcgdGhlIFhNTCBmaWxlIG9yIGlmIGEKLQkgKiAgICAgICAgICAgICBwYXJzZXIgZXJyb3Igb2NjdXJzLgotCSAqLwotCXB1YmxpYyBzdGF0aWMgdm9pZCBwYXJzZVhNTChJbnB1dFN0cmVhbSBhSW5wdXRTdHJlYW0sIEV4VGFnTGlzdGVuZXIgYUxpc3RlbmVyLCBpbnQgYUxldmVsKSB0aHJvd3MgSU9FeGNlcHRpb24gewotCQlYTUxQYXJzZXJJbXBsIHhtbCA9IG5ldyBYTUxQYXJzZXJJbXBsKGFJbnB1dFN0cmVhbSwgYUxpc3RlbmVyKTsKLQkJeG1sLnNldExldmVsKGFMZXZlbCk7Ci0JCXhtbC5wYXJzZVhNTCgpOwotCX0KLQotCS8qKgotCSAqIFBhcnNlcyBhIFhNTCBmaWxlIGdpdmVuIHRocm91Z2ggYVJlYWRlciBhbmQgZHVyaW5nIHRoZSBwYXJzaW5nIG5vdGlmaWVzCi0JICogYUxpc3RlbmVyIGZvciBjbG9zZS10YWcgYW5kIG9wZW4tdGFnIGV2ZW50cyA8YnI+Ci0JICogPGJyPgotCSAqIDxiPk5vdGU6IFRoZSBYTUxSZWFkZXIgZG9lcyBub3QgY2xvc2UgdGhlIHBhc3NlZCBSZWFkZXIgb3IgSW5wdXRTdHJlYW0KLQkgKiAKLQkgKiBAcGFyYW0gYVJlYWRlcgotCSAqICAgICAgICAgICAgYVJlYWRlciB0byByZWFkIHRoZSBYTUwgZmlsZSBmcm9tCi0JICogQHBhcmFtIGFMaXN0ZW5lcgotCSAqICAgICAgICAgICAgRXhUYWdMaXN0ZW5lciB0aGF0IHdpbGwgYmUgbm90aWZpZWQgb24gY2xvc2UtdGFnIGFuZCBvcGVuLXRhZwotCSAqICAgICAgICAgICAgZXZlbnRzCi0JICogQHBhcmFtIGFMZXZlbAotCSAqICAgICAgICAgICAgc2VlIHBhcnNlWE1MKFJlYWRlciBhUmVhZGVyLCBUYWdMaXN0ZW5lciBhTGlzdGVuZXIsIGludCBhTGV2ZWwKLQkgKiAgICAgICAgICAgIGRlc2NyaXB0aW9uCi0JICogQHRocm93cyBJT0V4Y2VwdGlvbgotCSAqICAgICAgICAgICAgIGlmIHNvbWUgSU8gZXJyb3Igb2NjdXJzIHdoZW4gcmVhZGluZyB0aGUgWE1MIGZpbGUgb3IgaWYgYQotCSAqICAgICAgICAgICAgIHBhcnNlciBlcnJvciBvY2N1cnMuCi0JICovCi0JcHVibGljIHN0YXRpYyB2b2lkIHBhcnNlWE1MKFJlYWRlciBhUmVhZGVyLCBFeFRhZ0xpc3RlbmVyIGFMaXN0ZW5lciwgaW50IGFMZXZlbCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKLQkJWE1MUGFyc2VySW1wbCB4bWwgPSBuZXcgWE1MUGFyc2VySW1wbChhUmVhZGVyLCBhTGlzdGVuZXIpOwotCQl4bWwuc2V0TGV2ZWwoYUxldmVsKTsKLQkJeG1sLnBhcnNlWE1MKCk7Ci0JfQotfQpkaWZmIC0tZ2l0IGEvYnVuZGxlcy9vcmcuZWNsaXBzZS5lcXVpbm94LmRzL3NyYy9vcmcvZWNsaXBzZS9lcXVpbm94L2ludGVybmFsL3V0aWwveG1sL1hNTFJlYWRlci5qYXZhIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5lcXVpbm94LmRzL3NyYy9vcmcvZWNsaXBzZS9lcXVpbm94L2ludGVybmFsL3V0aWwveG1sL1hNTFJlYWRlci5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBlMzI0YmQ1Li4wMDAwMDAwCi0tLSBhL2J1bmRsZXMvb3JnLmVjbGlwc2UuZXF1aW5veC5kcy9zcmMvb3JnL2VjbGlwc2UvZXF1aW5veC9pbnRlcm5hbC91dGlsL3htbC9YTUxSZWFkZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDEzMjkgKzAsMCBAQAotLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKLSAqIENvcHlyaWdodCAoYykgMTk5NywgMjAwOCBieSBQcm9TeXN0IFNvZnR3YXJlIEdtYkgKLSAqIGh0dHA6Ly93d3cucHJvc3lzdC5jb20KLSAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMKLSAqIGFyZSBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2UgdjEuMAotICogd2hpY2ggYWNjb21wYW5pZXMgdGhpcyBkaXN0cmlidXRpb24sIGFuZCBpcyBhdmFpbGFibGUgYXQKLSAqIGh0dHA6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLXYxMC5odG1sCi0gKgotICogQ29udHJpYnV0b3JzOgotICogICAgUHJvU3lzdCBTb2Z0d2FyZSBHbWJIIC0gaW5pdGlhbCBBUEkgYW5kIGltcGxlbWVudGF0aW9uCi0gKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLXBhY2thZ2Ugb3JnLmVjbGlwc2UuZXF1aW5veC5pbnRlcm5hbC51dGlsLnhtbDsKLQotaW1wb3J0IGphdmEuaW8uKjsKLWltcG9ydCBvcmcuZWNsaXBzZS5lcXVpbm94LmludGVybmFsLmRzLkFjdGl2YXRvcjsKLWltcG9ydCBvcmcuZWNsaXBzZS5lcXVpbm94LmludGVybmFsLnV0aWwuc3RyaW5nLkNoYXJCdWZmZXI7Ci0KLS8qKgotICogPHA+Ci0gKiBDbGFzcyB1c2VkIGZvciByZWFkaW5nIG9mIHhtbCBmaWxlcywgY3JlYXRpbmcgdHJlZSBzdHJ1Y3R1cmUgb2YgJ1RhZ0NsYXNzJwotICogZm9yIGVhY2ggeG1sIHRhZy4gV2hlbiByZWFkZXIgcmVhY2hlcyBhIGNsb3NlZCB0YWcgaXQgbm90aWZpZXMgYSBnaXZlbgotICogJ1RhZ0xpc3RlbmVyJyBhbmQgc2VuZHMgdGhlIGxhc3QgdGFnIHRvIGl0LiBJZiBjbG9zaW5nIHRhZyBkb2VzIG5vdAotICogY29ycmVzcG9uZCB3aXRoIHRoZSBsYXN0IG9wZW4gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlzIHRocm93bi4gVGhlcmUgaXMgYQotICogZGVidWcgcHJvcGVydHkgJ3htbC5kZWJ1ZycgdXNlZCB0byBkdW1wIGFuIEV4Y2VwdGlvbnMgb2NjdXJyZWQgd2hpbGUKLSAqIG9wZXJhdGlvbiBpcyBydW5uaW5nLgotICogPC9wPgotICogCi0gKiA8cD4KLSAqIFRoZSBwYXJzZXIsIGluIGdlbmVyYWwsIGlzIGEgc2ltcGxlIFhNTCBwYXJzZXIgdGhhdCBpbXBsZW1lbnRzCi0gKiAmcXVvdDtSZWN1cnNpdmUgZGVzY2VudCZxdW90OyBwYXJzaW5nIG1ldGhvZC4KLSAqIAotICogS25vd24gbGltaXRhdGlvbnM6PGJyPgotICogCi0gKiA8cHJlPgotICogIEN1cnJlbnRseSB0aGlzIFhNTFBhcnNlciBkb2VzIG5vdCBzdXBwb3J0IHRoZSBmb2xsb3dpbmcgc3BlY2lhbCB0YWdzOgotICogIDEuICZsdDs/VEFHX05BTUUgLi4uLi4gPyZndDsgICBvciBhbHNvICZxdW90O1Byb2Nlc3NpbmcgSW5zdHJ1Y3Rpb25zJnF1b3Q7Ci0gKiAgMi4gJmx0OyFET0NUWVBFIC4uLi4gJmd0OwotICogIDMuICZsdDshRUxFTUVOVCAuLi4uICZndDsKLSAqICA0LiAmbHQ7IUFUVExJU1QgLi4uLiAmZ3Q7Ci0gKiAgNS4gJmx0OyFFTlRJVFkgLi4uLiAmZ3Q7Ci0gKiA8L3ByZT4KLSAqIAotICogPGJyPgotICogVGhlIHBhcnNlciBza2lwcGVzIHRoZXNlIHRhZ3MgKGl0IHNlYXJjaGVzIGZvciAnPicgc3ltYm9sIGFuZCBjbG9zZXMgdGhlCi0gKiAnc3BlY2lhbCcgdGFnKS48YnI+Ci0gKiAKLSAqIEBhdXRob3IgSXZhbiBEaW1pdHJvdgotICogQGF1dGhvciBQYXZsaW4gRG9icmV2Ci0gKiBAdmVyc2lvbiAxLjAKLSAqLwotCi1wdWJsaWMgY2xhc3MgWE1MUmVhZGVyIHsKLQotCXByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBERUJVRyA9ICJlcXVpbm94LmRzLnhtbC5kZWJ1ZyI7Ci0JcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFNFVF9PTERfQkVIQVZJT1VSID0gImVxdWlub3guZHMueG1sLm9sZGJlaGF2aW91ciI7Ci0JcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFNFVF9PTERfTEVWRUxTID0gImVxdWlub3guZHMueG1sLm9sZGxldmVscyI7Ci0JcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIElOVEVSTl9BVFRSSUJVVEVTID0gImVxdWlub3guZHMueG1sLmludGVybi5hdHRyaWJ1dGVzIjsKLQotCXByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBDREFUQSA9ICJDREFUQSI7Ci0JcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFhNTCA9ICJ4bWwiOwotCXByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBWRVJTSU9OID0gInZlcnNpb24iOwotCXByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBFTkNPRElORyA9ICJlbmNvZGluZyI7Ci0JcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIFNUQU5EQUxPTkUgPSAic3RhbmRhbG9uZSI7Ci0KLQlwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJSX0VPUyA9ICJFbmQtb2Ytc3RyZWFtIHJlYWNoZWQgYmVmb3JlIHRoZSBlbmQgb2YgWE1MLiI7Ci0JcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEVSUl9FTlRJVFlfRVhQRUNURUQgPSAiRW50aXR5IHJlZmVyZW5jZSBvciBDaGFyYWN0ZXIgcmVmZXJlbmNlIGV4cGVjdGVkLiI7Ci0JcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEVSUl9FUVVBTF9FWFBFQ1RFRCA9ICInPScgZXhwZWN0ZWQuIjsKLQlwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJSX1FVT1RfRVhQRUNURUQgPSAiJycnIG9yICdcIicgZXhwZWN0ZWQuIjsKLQlwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJSX0dUX0VYUEVDVEVEID0gIic+JyBleHBlY3RlZC4iOwotCXByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBFUlJfTFRfRVhQRUNURUQgPSAiJzwnIGV4cGVjdGVkLiI7Ci0JcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEVSUl9DTE9TRV9UQUcxX0VYUEVDVEVEID0gIicvJyBvciB0YWcgbmFtZSBleHBlY3RlZC4iOwotCXByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBFUlJfQ0xPU0VfVEFHMl9FWFBFQ1RFRCA9ICInPicsICcvPicgb3IgbW9yZSBhdHRyaWJ1dGVzIGV4cGVjdGVkLiI7Ci0JcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEVSUl9DTE9TRV9UQUczX0VYUEVDVEVEID0gIic/PicgZXhwZWN0ZWQuIjsKLQlwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJSX0NPTlRFTlRfRVhQRUNURUQgPSAiQ29udGVudCBkYXRhLCBuZXcgdGFnIG9yIGNsb3NpbmcgdGFnIGV4cGVjdGVkLiI7Ci0JcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEVSUl9RVUVTVElPTk1BUktfRVhQRUNURUQgPSAiJz8nIGV4cGVjdGVkLiI7Ci0JcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEVSUl9JTExFR0FMX0NIQVJBQ1RFUiA9ICJJbGxlZ2FsIGNoYXJhY3Rlci4iOwotCXByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBFUlJfVEFHTkFNRV9FWFBFQ1RFRCA9ICJUYWcgbmFtZSBleHBlY3RlZC4iOwotCXByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBFUlJfVEFHTkFNRTJfRVhQRUNURUQgPSAiVGFnIG5hbWUsICc/JyBvciAnIScgZXhwZWN0ZWQuIjsKLQlwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJSX0RBU0hfRVhQRUNURUQgPSAiJy0nIGV4cGVjdGVkLiI7Ci0JcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEVSUl9DT01NRU5UX0NMT1NFX0VYUEVDVEVEID0gIictLT4nIGV4cGVjdGVkLiI7Ci0JcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEVSUl9DREFUQV9FWFBFQ1RFRCA9ICInQ0RBVEEnIGV4cGVjdGVkLiI7Ci0JcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEVSUl9PUEVOU1FCUkFDS0VUX0VYUEVDVEVEID0gIidbJyBleHBlY3RlZC4iOwotCXByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBFUlJfQ0xPU0VfQ0RBVEFfRVhQRUNURUQgPSAiJ11dPicgZXhwZWN0ZWQuIjsKLQlwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJSX1NFTUlDT0xPTl9FWFBFQ1RFRCA9ICInOycgZXhwZWN0ZWQuIjsKLQlwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJSX1hNTFBST0xPR19FWFBFQ1RFRCA9ICJYTUwgcHJvbG9nICc8P3htbCcgaXMgbm90IGV4cGVjdGVkIGF0IHRoaXMgcG9zaXRpb24uIjsKLQlwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJSX1ZFUlNJT05fRVhQRUNURUQgPSAiJ3ZlcnNpb24nIGF0dHJpYnV0ZSBleHBlY3RlZC4iOwotCXByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBFUlJfRU5DT0RJTkdfU1RBTkRBTE9ORV9FWFBFQ1RFRCA9ICInZW5jb2RpbmcnLCAnc3RhbmRhbG9uZScgb3IgJz8+JyBleHBlY3RlZC4iOwotCXByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBFUlJfU1RBTkRBTE9ORV9FWFBFQ1RFRCA9ICInc3RhbmRhbG9uZScgYXR0cmlidXRlIGV4cGVjdGVkLiI7Ci0KLQlwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuIGZEZWJ1ZyA9IEFjdGl2YXRvci5nZXRCb29sZWFuKERFQlVHKTsKLQlwcml2YXRlIHN0YXRpYyBmaW5hbCBib29sZWFuIGZPbGRCZWhhdmlvdXIgPSBBY3RpdmF0b3IuZ2V0Qm9vbGVhbihTRVRfT0xEX0JFSEFWSU9VUik7Ci0JcHJpdmF0ZSBzdGF0aWMgZmluYWwgYm9vbGVhbiBmT2xkTGV2ZWxzID0gQWN0aXZhdG9yLmdldEJvb2xlYW4oU0VUX09MRF9MRVZFTFMpOwotCXByaXZhdGUgc3RhdGljIGZpbmFsIGJvb2xlYW4gZkludGVybkF0dHJpYnV0ZXMgPSBBY3RpdmF0b3IuZ2V0Qm9vbGVhbihJTlRFUk5fQVRUUklCVVRFUyk7Ci0KLQlwcml2YXRlIFN0cmluZyBmRGVmYXVsdEVuY29kaW5nID0gIlVURi04IjsKLQotCS8vIHByaXZhdGUgQ2hhckJ1ZmZlciBjOwotCXByaXZhdGUgQ2hhckJ1ZmZlciB0ZW1wID0gbmV3IENoYXJCdWZmZXIoKTsKLQlwcml2YXRlIENoYXJCdWZmZXIgdGVtcDIgPSBudWxsOwotCi0JcHJvdGVjdGVkIFJlYWRlciBmUmVhZGVyID0gbnVsbDsKLQlwcm90ZWN0ZWQgSW5wdXRTdHJlYW0gZlN0cmVhbSA9IG51bGw7Ci0KLQlwcm90ZWN0ZWQgY2hhciBjdXJyZW50Q2hhciA9IDA7Ci0JcHJvdGVjdGVkIFRhZ0xpc3RlbmVyIGZUYWdMaXN0ZW5lcjsKLQotCXByb3RlY3RlZCBpbnQgZkxpbmUgPSAxOwotCXByb3RlY3RlZCBpbnQgZlBvcyA9IDA7Ci0KLQlwcm90ZWN0ZWQgaW50IGZMZXZlbCA9IC0xOwotCXByb3RlY3RlZCBpbnQgZkN1cnJlbnRMZXZlbCA9IDE7Ci0KLQlwcml2YXRlIFN0cmluZyBmVmVyc2lvbiA9ICIxLjAiOwotCXByaXZhdGUgU3RyaW5nIGZFbmNvZGluZyA9ICJVVEYtOCI7Ci0JcHJpdmF0ZSBTdHJpbmcgZlN0YW5kYWxvbmUgPSAibm8iOwotCi0JcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmdbXSBmTmV3X2VudGl0aWVzID0geyJhbXAiLCAiYXBvcyIsICJsdCIsICJndCIsICJxdW90In07Ci0JcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBjaGFyW10gZk5ld19lbnRfY2hhcnMgPSB7JyYnLCAnXCcnLCAnPCcsICc+JywgJyInfTsKLQotCXByb3RlY3RlZCBzdGF0aWMgZmluYWwgU3RyaW5nW10gZk9sZF9lbnRpdGllcyA9IHsiYW1wIiwgIm5ic3AiLCAiY3JsZiIsICJ0YWIiLCAibHQiLCAiZ3QiLCAicXVvdCIsICJhcG9zIn07Ci0JcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBjaGFyW10gZk9sZF9lbnRfY2hhcnMgPSB7JyYnLCAnICcsICdcbicsICdcdCcsICc8JywgJz4nLCAnIicsICdcJyd9OwotCi0JLyoqCi0JICogQW4gZW1wdHkgZGVmYXVsdCBjb25zdHJ1Y3RvcgotCSAqLwotCXB1YmxpYyBYTUxSZWFkZXIoKSB7Ci0JCS8vCi0JfQotCi0JLyoqCi0JICogQ29uc3RydWN0cyBhIG5ldyBYTUxSZWFkZXIuIDxicj4KLQkgKiA8YnI+Ci0JICogPGI+Tm90ZTogVGhlIFhNTFJlYWRlciBkb2VzIG5vdCBjbG9zZSB0aGUgcGFzc2VkIFJlYWRlciBvciBJbnB1dFN0cmVhbQotCSAqIAotCSAqIEBwYXJhbSBhSW5wdXRTdHJlYW0KLQkgKiAgICAgICAgICAgIGFuIElucHV0U3RyZWFtIHRvIHJlYWQgdGhlIFhNTCBmaWxlIGZyb20KLQkgKiBAcGFyYW0gYUxpc3RlbmVyCi0JICogICAgICAgICAgICBUYWdMaXN0ZW5lciB0aGF0IHdpbGwgYmUgbm90aWZpZWQgb24gdGFnIGNsb3NlIGV2ZW50Ci0JICogQHRocm93cyBJT0V4Y2VwdGlvbgotCSAqLwotCXB1YmxpYyBYTUxSZWFkZXIoSW5wdXRTdHJlYW0gYUlucHV0U3RyZWFtLCBUYWdMaXN0ZW5lciBhTGlzdGVuZXIpIHsKLQkJZlN0cmVhbSA9IGFJbnB1dFN0cmVhbTsKLQkJZlRhZ0xpc3RlbmVyID0gYUxpc3RlbmVyOwotCX0KLQotCS8qKgotCSAqIENvbnN0cnVjdHMgYSBuZXcgWE1MUmVhZGVyLiA8YnI+Ci0JICogPGJyPgotCSAqIDxiPk5vdGU6IFRoZSBYTUxSZWFkZXIgZG9lcyBub3QgY2xvc2UgdGhlIHBhc3NlZCBSZWFkZXIgb3IgSW5wdXRTdHJlYW0KLQkgKiAKLQkgKiBAcGFyYW0gYVJlYWRlcgotCSAqICAgICAgICAgICAgYSByZWFkZXIgdGhhdCB3aWxsIGJlIHVzZWQgdG8gcmVhZCB0aGUgWE1MIGZpbGUgZnJvbQotCSAqIEBwYXJhbSBhTGlzdGVuZXIKLQkgKiAgICAgICAgICAgIFRhZ0xpc3RlbmVyIHRoYXQgd2lsbCBiZSBub3RpZmllZCBvbiB0YWcgY2xvc2UgZXZlbnQKLQkgKi8KLQlwdWJsaWMgWE1MUmVhZGVyKFJlYWRlciBhUmVhZGVyLCBUYWdMaXN0ZW5lciBhTGlzdGVuZXIpIHsKLQkJZlJlYWRlciA9IGFSZWFkZXI7Ci0JCWZUYWdMaXN0ZW5lciA9IGFMaXN0ZW5lcjsKLQl9Ci0KLQkvKioKLQkgKiBQYXJzZXMgYSBYTUwgZmlsZSBnaXZlbiB0aHJvdWdoIGFJbnB1dFN0cmVhbSBhbmQgZHVyaW5nIHRoZSBwYXJzaW5nCi0JICogbm90aWZpZXMgYUxpc3RlbmVyIGZvciBjbG9zZS10YWcgZXZlbnRzIDxicj4KLQkgKiA8YnI+Ci0JICogPGI+Tm90ZTogVGhlIFhNTFJlYWRlciBkb2VzIG5vdCBjbG9zZSB0aGUgcGFzc2VkIFJlYWRlciBvciBJbnB1dFN0cmVhbQotCSAqIAotCSAqIEBwYXJhbSBhSW5wdXRTdHJlYW0KLQkgKiAgICAgICAgICAgIGFuIElucHV0U3RyZWFtIHRvIHJlYWQgdGhlIFhNTCBmaWxlIGZyb20KLQkgKiBAcGFyYW0gYUxpc3RlbmVyCi0JICogICAgICAgICAgICBUYWdMaXN0ZW5lciB0aGF0IHdpbGwgYmUgbm90aWZpZWQgb24gY2xvc2UtdGFnIGV2ZW50cwotCSAqIEB0aHJvd3MgSU9FeGNlcHRpb24KLQkgKi8KLQlwdWJsaWMgc3RhdGljIHZvaWQgcmVhZChJbnB1dFN0cmVhbSBhSW5wdXRTdHJlYW0sIFRhZ0xpc3RlbmVyIGFMaXN0ZW5lcikgdGhyb3dzIElPRXhjZXB0aW9uIHsKLQkJcGFyc2VYTUwoYUlucHV0U3RyZWFtLCBhTGlzdGVuZXIsIC0xKTsKLQl9Ci0KLQkvKioKLQkgKiBQYXJzZXMgYSBYTUwgZmlsZSBnaXZlbiB0aHJvdWdoIGFJbnB1dFN0cmVhbSBhbmQgZHVyaW5nIHRoZSBwYXJzaW5nCi0JICogbm90aWZpZXMgYUxpc3RlbmVyIGZvciBjbG9zZS10YWcgZXZlbnRzIDxicj4KLQkgKiA8YnI+Ci0JICogPGI+Tm90ZTogVGhlIFhNTFJlYWRlciBkb2VzIG5vdCBjbG9zZSB0aGUgcGFzc2VkIFJlYWRlciBvciBJbnB1dFN0cmVhbQotCSAqIAotCSAqIEBwYXJhbSBhSW5wdXRTdHJlYW0KLQkgKiAgICAgICAgICAgIGFuIElucHV0U3RyZWFtIHRvIHJlYWQgdGhlIFhNTCBmaWxlIGZyb20KLQkgKiBAcGFyYW0gYUxpc3RlbmVyCi0JICogICAgICAgICAgICBUYWdMaXN0ZW5lciB0aGF0IHdpbGwgYmUgbm90aWZpZWQgb24gY2xvc2UtdGFnIGV2ZW50cwotCSAqIEBwYXJhbSBhTGV2ZWwKLQkgKiAgICAgICAgICAgIHNlZSBwYXJzZVhNTChSZWFkZXIgYVJlYWRlciwgVGFnTGlzdGVuZXIgYUxpc3RlbmVyLCBpbnQgYUxldmVsCi0JICogICAgICAgICAgICBkZXNjcmlwdGlvbgotCSAqIEB0aHJvd3MgSU9FeGNlcHRpb24KLQkgKi8KLQlwdWJsaWMgc3RhdGljIHZvaWQgcmVhZChJbnB1dFN0cmVhbSBhSW5wdXRTdHJlYW0sIFRhZ0xpc3RlbmVyIGFMaXN0ZW5lciwgaW50IGFMZXZlbCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKLQkJcGFyc2VYTUwoYUlucHV0U3RyZWFtLCBhTGlzdGVuZXIsIGFMZXZlbCk7Ci0JfQotCi0JLyoqCi0JICogUGFyc2VzIGEgWE1MIGZpbGUgZ2l2ZW4gdGhyb3VnaCBhUmVhZGVyIGFuZCBkdXJpbmcgdGhlIHBhcnNpbmcgbm90aWZpZXMKLQkgKiBhTGlzdGVuZXIgZm9yIGNsb3NlLXRhZyBldmVudHMgPGJyPgotCSAqIDxicj4KLQkgKiA8Yj5Ob3RlOiBUaGUgWE1MUmVhZGVyIGRvZXMgbm90IGNsb3NlIHRoZSBwYXNzZWQgUmVhZGVyIG9yIElucHV0U3RyZWFtCi0JICogCi0JICogQHBhcmFtIGFSZWFkZXIKLQkgKiAgICAgICAgICAgIGEgUmVhZGVyIHRvIHJlYWQgdGhlIFhNTCBmaWxlIGZyb20KLQkgKiBAcGFyYW0gYUxpc3RlbmVyCi0JICogICAgICAgICAgICBUYWdMaXN0ZW5lciB0aGF0IHdpbGwgYmUgbm90aWZpZWQgb24gY2xvc2UtdGFnIGV2ZW50cwotCSAqIEB0aHJvd3MgSU9FeGNlcHRpb24KLQkgKi8KLQlwdWJsaWMgc3RhdGljIHZvaWQgcmVhZChSZWFkZXIgYVJlYWRlciwgVGFnTGlzdGVuZXIgYUxpc3RlbmVyKSB0aHJvd3MgSU9FeGNlcHRpb24gewotCQlwYXJzZVhNTChhUmVhZGVyLCBhTGlzdGVuZXIsIC0xKTsKLQl9Ci0KLQkvKioKLQkgKiBQYXJzZXMgYSBYTUwgZmlsZSBnaXZlbiB0aHJvdWdoIGFSZWFkZXIgYW5kIGR1cmluZyB0aGUgcGFyc2luZyBub3RpZmllcwotCSAqIGFMaXN0ZW5lciBmb3IgY2xvc2UtdGFnIGV2ZW50cyA8YnI+Ci0JICogPGJyPgotCSAqIDxiPk5vdGU6IFRoZSBYTUxSZWFkZXIgZG9lcyBub3QgY2xvc2UgdGhlIHBhc3NlZCBSZWFkZXIgb3IgSW5wdXRTdHJlYW0KLQkgKiAKLQkgKiBAcGFyYW0gYVJlYWRlcgotCSAqICAgICAgICAgICAgYSBSZWFkZXIgdG8gcmVhZCB0aGUgWE1MIGZpbGUgZnJvbQotCSAqIEBwYXJhbSBhTGlzdGVuZXIKLQkgKiAgICAgICAgICAgIFRhZ0xpc3RlbmVyIHRoYXQgd2lsbCBiZSBub3RpZmllZCBvbiBjbG9zZS10YWcgZXZlbnRzCi0JICogQHBhcmFtIGFMZXZlbAotCSAqICAgICAgICAgICAgc2VlIHBhcnNlWE1MKFJlYWRlciBhUmVhZGVyLCBUYWdMaXN0ZW5lciBhTGlzdGVuZXIsIGludCBhTGV2ZWwKLQkgKiAgICAgICAgICAgIGRlc2NyaXB0aW9uCi0JICogQHRocm93cyBJT0V4Y2VwdGlvbgotCSAqLwotCXB1YmxpYyBzdGF0aWMgdm9pZCByZWFkKFJlYWRlciBhUmVhZGVyLCBUYWdMaXN0ZW5lciBhTGlzdGVuZXIsIGludCBhTGV2ZWwpIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0JCXBhcnNlWE1MKGFSZWFkZXIsIGFMaXN0ZW5lciwgYUxldmVsKTsKLQl9Ci0KLQkvKioKLQkgKiBTZXRzIHRoZSBwYXJzZXIncyBlbmNvZGluZy4gSWYgdGhlcmUgaXMgYSBjdXJyZW50IGVuY29kaW5nIGFzc29jaWF0ZWQKLQkgKiB3aXRoIHRoZSBwYXJzZXIgdGhlIG1ldGhvZCByZXR1cm5zIGltbWVkaWF0ZWx5Ci0JICogCi0JICogQHBhcmFtIGFFbmNvZGluZwotCSAqICAgICAgICAgICAgbmV3IGVuY29kaW5nIHRvIGJlIHNldAotCSAqIEB0aHJvd3MgVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbgotCSAqICAgICAgICAgICAgIGlmIHRoZSBlbmNvZGluZyBpcyBub3Qgc3VwcG9ydGVkLgotCSAqLwotCXByb3RlY3RlZCB2b2lkIHNldEVuY29kaW5nKFN0cmluZyBhRW5jb2RpbmcpIHsKLQkJaWYgKGZSZWFkZXIgPT0gbnVsbCkgewotCQkJdHJ5IHsKLQkJCQlmUmVhZGVyID0gbmV3IElucHV0U3RyZWFtUmVhZGVyKGZTdHJlYW0sIGFFbmNvZGluZyk7Ci0JCQl9IGNhdGNoIChFeGNlcHRpb24gZSkgewotCQkJCWlmIChmRGVidWcpIHsKLQkJCQkJU3lzdGVtLmVyci5wcmludGxuKCJbWE1MUmVhZGVyXSBGYWlsZWQgc2V0dGluZyB0aGUgZW5jb2RpbmcgXCIiICsgYUVuY29kaW5nICsgIlwiLCBjb250aW51ZSBwYXJzaW5nIHdpdGggdGhlIGRlZmF1bHQgb25lLiIpOwotCQkJCX0KLQkJCQlmUmVhZGVyID0gbmV3IElucHV0U3RyZWFtUmVhZGVyKGZTdHJlYW0pOwotCQkJfQotCQl9Ci0JfQotCi0JLyoqCi0JICogU2V0cyB0aGUgbGV2ZWwgb2YgdGFncyBiZWxsb3cgd2hpY2ggdGhlIGxpc3RlbmVyIHdpbGwgYmUgbm90aWZpZWQgZm9yLgotCSAqIEZvciBpbnRlcm5hbCB1c2Ugb25seS4KLQkgKiAKLQkgKiBAcGFyYW0gYUxldmVsCi0JICovCi0JcHJvdGVjdGVkIHZvaWQgc2V0TGV2ZWwoaW50IGFMZXZlbCkgewotCQlmTGV2ZWwgPSBhTGV2ZWw7Ci0JfQotCi0JLyogQSBoZWxwZXIgZnVuY3Rpb24gdG8gcmV1c2UgYSB0ZW1wIENoYXJCdWZmZXJzIHdpdGhvdXQgcmVjcmVhdGluZyBpdCAqLwotCXByb3RlY3RlZCBDaGFyQnVmZmVyIGdldENoYXJCdWZmZXIoKSB7Ci0JCWlmICh0ZW1wLmxlbmd0aCgpIDw9IDApIHsKLQkJCXJldHVybiB0ZW1wOwotCQl9IGVsc2UgaWYgKHRlbXAyID09IG51bGwpIHsKLQkJCXRlbXAyID0gbmV3IENoYXJCdWZmZXIoMCk7Ci0JCQlyZXR1cm4gdGVtcDI7Ci0JCX0gZWxzZSBpZiAodGVtcDIubGVuZ3RoKCkgPD0gMCkgewotCQkJcmV0dXJuIHRlbXAyOwotCQl9Ci0JCXJldHVybiBuZXcgQ2hhckJ1ZmZlcigwKTsKLQl9Ci0KLQlwcm90ZWN0ZWQgY2hhciBwcmV2X2NoYXIgPSAwOwotCXByb3RlY3RlZCBjaGFyW10gZkJ1ZmZlciA9IG5ldyBjaGFyWzQwOTZdOwotCXByb3RlY3RlZCBpbnQgZkJ1ZmZlckxlbiA9IDA7Ci0JcHJvdGVjdGVkIGludCBmQnVmZmVyUG9zID0gMDsKLQotCS8qKgotCSAqIFJlYWRzIHRoZSBuZXh0IGNoYXIgZnJvbSB0aGUgaW5wdXQgc3RyZWFtIGFuZCBzZXRzIGl0IHRvIHByaXZhdGUgZmllbGQKLQkgKiA8Y29kZT5jdXJyZW50Q2hhcjwvY29kZT4KLQkgKiAKLQkgKiBAcmV0dXJuIHRydWUgaWYgdGhlIG5leHQgY2hhciBpcyBzdWNjZXNzZnVsbHkgcmVhZCBvZiBmYWxzZSBpZgotCSAqICAgICAgICAgRW5kLU9mLVN0cmVhbSBpcyByZWFjaGVkCi0JICogQHRocm93cyBJT0V4Y2VwdGlvbgotCSAqICAgICAgICAgICAgIGlmIHNvbWUgZXJyb3Igb2NjdXJzIGR1cmluZyByZWFkaW5nIHRoZSBjaGFyYWN0ZXIgb3IgaWYgdGhlCi0JICogICAgICAgICAgICAgY2FsbGVyIHRyaWVzIHRvIHJlYWQgYmV5b25kIHRoZSBFbmQtT2YtU3RyZWFtLgotCSAqLwotCXByb3RlY3RlZCBib29sZWFuIGdldE5leHRDaGFyKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKLQkJLy8gLy8gUmVhZGluZyBjaGFyYWN0ZXJzIHdpdGhvdXQgYnVmZmVyaW5nCi0JCS8vIGludCBpY2hhciA9IDA7Ci0JCS8vIGludCBjb3VudCA9IDA7Ci0JCS8vIHdoaWxlIChpY2hhciA9PSAwICYmIGNvdW50IDwgMTAwKSB7Ci0JCS8vIGljaGFyID0gZlJlYWRlci5yZWFkKCk7Ci0JCS8vIGNvdW50Kys7Ci0JCS8vIH0KLQkJLy8gICAgCi0JCS8vIGlmIChpY2hhciA9PSAwKQotCQkvLyB0aHJvdyBuZXcgSU9FeGNlcHRpb24oIkZhaWxlZCB0byByZWFkIGZyb20gdGhlIGlucHV0IGZpbGUuIik7Ci0JCS8vICAgIAotCQkvLyBpZiAoaWNoYXIgPCAwICYmIHByZXZfY2hhciA9PSAwKQotCQkvLyB0aHJvdyBuZXcgSU9FeGNlcHRpb24oRVJSX0VPUyk7Ci0JCS8vICAgIAotCQkvLyBjaGFyIGNoID0gKGNoYXIpIGljaGFyOwotCi0JCWNoYXIgY2g7Ci0KLQkJaWYgKGZSZWFkZXIgPT0gbnVsbCkgeyAvLyBJZiB0aGVyZSBpcyBubyBhc3NvY2lhdGVkIHJlYWRlciwKLQkJCWludCBhY2ggPSBmU3RyZWFtLnJlYWQoKTsgLy8gdGhlbiByZWFkcyBmcm9tIHRoZSBJbnB1dFN0cmVhbSB1bnRpbAotCQkJaWYgKGFjaCA8IDApIHsgLy8gdGhlIHJpZ3RoIGVuY29kaW5nIGlzIHJlY29nbml6ZWQKLQkJCQlhY2ggPSAwOwotCQkJfQotCi0JCQljaCA9IChjaGFyKSBhY2g7Ci0JCQlpZiAoY2ggPT0gMCAmJiBwcmV2X2NoYXIgPT0gMCkgewotCQkJCXRocm93IG5ldyBJT0V4Y2VwdGlvbihFUlJfRU9TKTsKLQkJCX0KLQkJfSBlbHNlIHsKLQkJCWlmIChmQnVmZmVyTGVuIDwgMCkgewotCQkJCXRocm93IG5ldyBJT0V4Y2VwdGlvbihFUlJfRU9TKTsKLQkJCX0KLQotCQkJaWYgKChmQnVmZmVyUG9zKSA+PSBmQnVmZmVyTGVuKSB7Ci0JCQkJLy8gUmVmZXRjaCB0aGUgYnVmZmVyCi0JCQkJZkJ1ZmZlckxlbiA9IDA7Ci0JCQkJZkJ1ZmZlclBvcyA9IDA7Ci0JCQkJaW50IGNvdW50ID0gMDsKLQkJCQl3aGlsZSAoZkJ1ZmZlckxlbiA9PSAwICYmIGNvdW50IDwgMTAwKSB7Ci0JCQkJCWZCdWZmZXJMZW4gPSBmUmVhZGVyLnJlYWQoZkJ1ZmZlcik7Ci0JCQkJCWNvdW50Kys7Ci0JCQkJfQotCi0JCQkJY2ggPSAoZkJ1ZmZlckxlbiA+IDApID8gZkJ1ZmZlcltmQnVmZmVyUG9zKytdIDogMDsKLQotCQkJCWlmIChmQnVmZmVyTGVuID09IDApIHsKLQkJCQkJZkJ1ZmZlckxlbiA9IC0xOwotCQkJCX0KLQkJCX0gZWxzZSB7Ci0JCQkJY2ggPSBmQnVmZmVyW2ZCdWZmZXJQb3MrK107Ci0JCQl9Ci0JCX0KLQotCQlwcmV2X2NoYXIgPSBjdXJyZW50Q2hhcjsKLQkJY3VycmVudENoYXIgPSBjaDsKLQkJZlBvcysrOwotCi0JCXN3aXRjaCAoY2gpIHsKLQkJCWNhc2UgJ1xuJyA6Ci0JCQkJaWYgKHByZXZfY2hhciAhPSAnXHInKSB7Ci0JCQkJCWZMaW5lKys7Ci0JCQkJfQotCQkJCWZQb3MgPSAwOwotCQkJCWJyZWFrOwotCQkJY2FzZSAnXHInIDoKLQkJCQlmUG9zID0gMDsKLQkJCQlmTGluZSsrOwotCQkJCWJyZWFrOwotCQl9Ci0JCXJldHVybiAoY3VycmVudENoYXIgIT0gMCk7Ci0JfQotCi0JLyoqCi0JICogUGFyc2VzIHRoZSBhdHRyaWJ1dGUgdmFsdWUgYW5kIGlmIGl0J3Mgc3VjY2Vzc2Z1bCB0aGVuIGFkZHMgaXQgdG8gdGhlCi0JICogQ2hhckJ1ZmZlci4gSWYgdGhlcmUgYXJlIEVudGl0eVJlZmVyZW5jZXMgb2YgQ2hhclJlZmVyZW5jZXMgaW4gdGhlCi0JICogYXR0cmlidXRlIHZhbHVlLCB0aGV5IHdpbGwgYmUgdHVybmVkIHRvIHRoZWlyIGVxdWl2YWxlbnQgc3ltYm9scy48YnI+Ci0JICogYXR0cl92YWx1ZSA6Oj0gKGFjY2VwdGFibGVfY2hhciB8IEVudGl0eVJlZiB8IENoYXJSZWYpKiAtIHF1b3Rfc3ltYm9sCi0JICogCi0JICogQHNlZSBwYXJzZV9hdHRyCi0JICogQHNlZSBwYXJzZV9DaGFyUmVmCi0JICogQHNlZSBwYXJzZV9FbnRpdHlSZWYKLQkgKi8KLQlwcm90ZWN0ZWQgdm9pZCBwYXJzZV9hdHRyX3ZhbHVlKENoYXJCdWZmZXIgc2IsIGNoYXIgcXVvdCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKLQkJd2hpbGUgKGN1cnJlbnRDaGFyICE9IHF1b3QgJiYgY3VycmVudENoYXIgIT0gJzwnKSB7Ci0JCQlpZiAoYWNjZXB0X2NoYXIoJyYnKSkgewotCQkJCWlmICghcGFyc2VfQ2hhclJlZihzYikpIHsKLQkJCQkJaWYgKCFwYXJzZV9FbnRpdHlSZWYoc2IsIHRydWUpKSB7Ci0JCQkJCQllcnIoZlBvcyAtIDEsIEVSUl9FTlRJVFlfRVhQRUNURUQpOwotCQkJCQl9Ci0JCQkJfQotCQkJfSBlbHNlIHsKLQkJCQlzYi5hcHBlbmQoY3VycmVudENoYXIpOwotCi0JCQkJaWYgKCFnZXROZXh0Q2hhcigpKSB7Ci0JCQkJCWJyZWFrOwotCQkJCX0KLQkJCX0KLQkJfQotCX0KLQotCS8qKgotCSAqIFBhcnNlcyBhbiBhdHRyaWJ1dGUgd2l0aCB0aGUgZ2l2ZW4gc2ltcGxpZmllZCBncmFtbWFyOjxicj4KLQkgKiAKLQkgKiA8cHJlPgotCSAqIGF0dHJpYnV0ZSA6Oj0gUyogKyBhdHRyX25hbWUgKyBTKiArICc9JyArIFMqICsgKCdcJycgKyAoYXR0cl92YWx1ZSAtICdcJycpICsgJ1wnJykpIHwgKCcmcXVvdDsnICsgKGF0dHJfdmFsdWUgLSAnJnF1b3Q7JykgKyAnJnF1b3Q7JykpCi0JICogYXR0cl92YWx1ZSA6Oj0gKGFjY2VwdGFibGVfY2hhciB8IEVudGl0eVJlZiB8IENoYXJSZWYpKgotCSAqIGF0dHJfbmFtZSA6Oj0gaWRlbnRpZmllcgotCSAqIDwvcHJlPgotCSAqIAotCSAqIEBwYXJhbSBhUGFyZW50Ci0JICogICAgICAgICAgICB0aGUgcGFyZW50IHRhZyB3aGVyZSB0aGUgY29ycmVjdGx5IHBhcnNlZCBhdHRyaWJ1dGUgd2lsbCBiZQotCSAqICAgICAgICAgICAgYWRkZWQKLQkgKiBAdGhyb3dzIElPRXhjZXB0aW9uCi0JICogQHNlZSBwYXJzZV9pZGVudGlmaWVyCi0JICogQHNlZSBwYXJzZV9hdHRyX3ZhbHVlCi0JICovCi0JcHJvdGVjdGVkIGJvb2xlYW4gcGFyc2VfYXR0cihDaGFyQnVmZmVyIGNiKSB0aHJvd3MgSU9FeGNlcHRpb24gewotCQljbGVhcldoaXRlU3BhY2VzKCk7Ci0KLQkJY2IuYXBwZW5kKCcgJyk7Ci0JCWludCBsZW5ndGggPSBwYXJzZV9pZGVudGlmaWVyKGNiKTsKLQotCQlpZiAobGVuZ3RoID4gMCkgewotCQkJY2xlYXJXaGl0ZVNwYWNlcygpOwotCi0JCQlpZiAoIWFjY2VwdF9jaGFyKCc9JykpIHsKLQkJCQllcnIoRVJSX0VRVUFMX0VYUEVDVEVEKTsKLQkJCX0KLQotCQkJY2IuYXBwZW5kKCc9Jyk7Ci0JCQljbGVhcldoaXRlU3BhY2VzKCk7Ci0KLQkJCWNoYXIgcXVvdCA9IDA7Ci0JCQlpZiAoYWNjZXB0X2NoYXIoJyInKSkgewotCQkJCXF1b3QgPSAnIic7Ci0JCQl9IGVsc2UgaWYgKGFjY2VwdF9jaGFyKCdcJycpKSB7Ci0JCQkJcXVvdCA9ICdcJyc7Ci0JCQl9IGVsc2UgewotCQkJCWVycihFUlJfUVVPVF9FWFBFQ1RFRCk7Ci0JCQl9Ci0KLQkJCWNiLmFwcGVuZChxdW90KTsKLQkJCXBhcnNlX2F0dHJfdmFsdWUoY2IsIHF1b3QpOwotCi0JCQlpZiAoIWFjY2VwdF9jaGFyKHF1b3QpKSB7Ci0JCQkJZXJyKCInIiArIHF1b3QgKyAiJyBleHBlY3RlZC4iKTsKLQkJCX0KLQotCQkJY2IuYXBwZW5kKHF1b3QpOwotCQkJcmV0dXJuIHRydWU7Ci0JCX0KLQkJcmV0dXJuIGZhbHNlOwotCX0KLQotCS8qKgotCSAqIFBhcnNlcyBhIHRhZyBhdHRyaWJ1dGUgbGlzdCB3aXRoIHRoZSBmb2xsb3dpbmcgc2ltcGxpZmllZCBncmFtbWFyOgotCSAqIAotCSAqIDxwcmU+Ci0JICogYXR0cl9saXN0IDo6PSBhdHRyaWJ1dGUqCi0JICogQHBhcmFtIGFQYXJlbnQgdGhlIHBhcmVudCB0YWcgdGhhdCB0aGUgcGFyc2VkIGF0dHJpYnV0ZXMgd2lsbCBiZSBhZGRlZCB0bwotCSAqIEByZXR1cm4gdHJ1ZSBpZiBhdCBsZWFzdCBvbmUgYXR0cmlidXRlIGlzIHBhcnNlZCBjb3JyZWN0bHkgYW5kIGZhbHNlIG90aGVyd2lzZQotCSAqIEB0aHJvd3MgSU9FeGNlcHRpb24KLQkgKiBAc2VlIHBhcnNlX2F0dHIKLQkgKiAKLQkgKi8KLQlwcm90ZWN0ZWQgYm9vbGVhbiBwYXJzZV9hdHRyX2xpc3QoVGFnQ2xhc3MgYVBhcmVudCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKLQkJYm9vbGVhbiByZXN1bHQgPSBmYWxzZTsKLQotCQlDaGFyQnVmZmVyIGNiID0gZ2V0Q2hhckJ1ZmZlcigpOwotCQljYi5hcHBlbmQoYVBhcmVudC5nZXROYW1lKCkpOwotCQl3aGlsZSAocGFyc2VfYXR0cihjYikpIHsKLQkJCXJlc3VsdCA9IHRydWU7Ci0JCX0KLQotCQlhUGFyZW50LmZBdHRyaWJ1dGVzID0gKChmSW50ZXJuQXR0cmlidXRlcykgPyBjYi50b1N0cmluZygpLmludGVybigpIDogY2IudG9TdHJpbmcoKSk7Ci0JCWNiLnNldExlbmd0aCgwKTsKLQkJcmV0dXJuIHJlc3VsdDsKLQl9Ci0KLQlwcml2YXRlIHN0YXRpYyBmaW5hbCBjaGFyIGJBID0gJ0EnIC0gMTsKLQlwcml2YXRlIHN0YXRpYyBmaW5hbCBjaGFyIGFaID0gJ1onICsgMTsKLQlwcml2YXRlIHN0YXRpYyBmaW5hbCBjaGFyIGJhID0gJ2EnIC0gMTsKLQlwcml2YXRlIHN0YXRpYyBmaW5hbCBjaGFyIGF6ID0gJ3onICsgMTsKLQlwcml2YXRlIHN0YXRpYyBmaW5hbCBjaGFyIGIwID0gJzAnIC0gMTsKLQlwcml2YXRlIHN0YXRpYyBmaW5hbCBjaGFyIGE5ID0gJzknICsgMTsKLQotCS8qKgotCSAqIFRoaXMgbWV0aG9kIHJldHVybnMgdHJ1ZSBpcyB0aGUgcGFzc2VkIGNoYXJhY3RlciBtYXkgYmUgdXNlZCBhcyBzdGFydGluZwotCSAqIGNoYXJhY3RlciBmb3IgdGFnIG5hbWUgYW5kIGF0dHJpYnV0ZSBuYW1lCi0JICogCi0JICogQHBhcmFtIGNoCi0JICogICAgICAgICAgICB0aGUgdGVzdGVkIGNoYXJhY3RlcgotCSAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgY2hhcmFjdGVyIGNvdWxkIGJlIHVzZWQgYXMgc3RhcnRpbmcgY2hhcmFjdGVyIGZvciBhCi0JICogICAgICAgICB0YWcgbmFtZSBhbmQgYW4gYXR0cmlidXRlIG5hbWUgYW5kIGZhbHNlIG90aGVyd2lzZQotCSAqLwotCXB1YmxpYyBmaW5hbCBzdGF0aWMgYm9vbGVhbiBpc05hbWVTdGFydENoYXIoY2hhciBjaCkgewotCQlyZXR1cm4gKGNoID4gYkEgJiYgY2ggPCBhWikgfHwgKGNoID4gYmEgJiYgY2ggPCBheikgfHwgKGNoID09ICc6JykgfHwgKGNoID09ICdfJykgfHwgKGNoID4gMHhCRiAmJiBjaCA8IDB4RDcpIHx8IChjaCA+IDB4RDcgJiYgY2ggPCAweEY3KSB8fCAoY2ggPiAweEY3ICYmIGNoIDwgMHgzMDApIHx8IChjaCA+IDB4MzZGICYmIGNoIDwgMHgzN0UpIHx8IChjaCA+IDB4MzdFICYmIGNoIDwgMHgyMDAwKSB8fCAoY2ggPiAweDIwMEIgJiYgY2ggPCAweDIwMEUpIHx8IChjaCA+IDB4MjA2RiAmJiBjaCA8IDB4MjE5MCkgfHwgKGNoID4gMHgyQkZGICYmIGNoIDwgMHgyRkYwKSB8fCAoY2ggPiAweDMwMDAgJiYgY2ggPCAweEQ4MDApIHx8IChjaCA+IDB4RjkwMCAmJiBjaCA8IDB4RkREMCkgfHwgKGNoID4gMHhGREVGICYmIGNoIDwgMHhGRkZFKSB8fCAoY2ggPiAweDBGRkZGICYmIGNoIDwgMHhGMDAwMCk7Ci0JfQotCi0JLyoqCi0JICogVGhpcyBtZXRob2QgcmV0dXJucyB0cnVlIGlmIHRoZSBwYXNzZWQgY2hhcmFjdGVkIG1heSBiZSB1c2VkIGFzIHBhcnQgb2YgYQotCSAqIHRhZyBuYW1lIG9yIGFuIGF0dHJpYnV0ZSBuYW1lCi0JICogCi0JICogQHBhcmFtIGNoCi0JICogICAgICAgICAgICB0aGUgdGVzdGVkIGNoYXJhY3RlcgotCSAqIEByZXR1cm4gdHJ1ZSBpcyB0aGUgY2hhcmFjdGVkIGNvdWxkIGJlIHVzZWQgYXMgcGFydCBvZiBhIHRhZyBuYW1lIG9yIGFuCi0JICogICAgICAgICBhdHRyaWJ1dGUgbmFtZSBhbmQgZmFsc2Ugb3RoZXJ3aXNlCi0JICovCi0JcHVibGljIGZpbmFsIHN0YXRpYyBib29sZWFuIGlzTmFtZUNoYXIoY2hhciBjaCkgewotCQlyZXR1cm4gKGNoID09ICctJykgfHwgKGNoID09ICcuJykgfHwgKGNoID09IDB4QjcpIHx8IChjaCA+IGIwICYmIGNoIDwgYTkpIHx8IGlzTmFtZVN0YXJ0Q2hhcihjaCkgfHwgKGNoID4gMHgwMkZGICYmIGNoIDwgMHgwMzcwKSB8fCAoY2ggPiAweDIwM0UgJiYgY2ggPCAweDIwNDEpOwotCX0KLQotCS8qKgotCSAqIFBhcnNlcyBhbiBpZGVudGlmaWVyLgotCSAqIAotCSAqIEByZXR1cm4gYW4gaWRlbnRpZmllciBhcyBhIHN0cmluZyBpZiBpdCBpcyBwYXJzZWQgc3VjY2Vzc2Z1bGx5IGFuZCBudWxsCi0JICogICAgICAgICBvdGhlcndpc2UKLQkgKiBAdGhyb3dzIElPRXhjZXB0aW9uCi0JICogICAgICAgICAgICAgaWYgYW4gZXhjZXB0aW9uIG9jY3VycyBkdXJpbmcgcmVhZCBvcGVyYXRpb25zIGZyb20gdGhlIFJlYWRlcgotCSAqICAgICAgICAgICAgIG9yIHRoZSBJbnB1dFN0cmVhbQotCSAqLwotCXByb3RlY3RlZCBTdHJpbmcgcGFyc2VfaWRlbnRpZmllcigpIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0JCWlmIChpc05hbWVTdGFydENoYXIoY3VycmVudENoYXIpKSB7Ci0JCQlDaGFyQnVmZmVyIHNiID0gZ2V0Q2hhckJ1ZmZlcigpOwotCi0JCQl3aGlsZSAoaXNOYW1lQ2hhcihjdXJyZW50Q2hhcikpIHsKLQkJCQlzYi5hcHBlbmQoY3VycmVudENoYXIpOwotCi0JCQkJaWYgKCFnZXROZXh0Q2hhcigpKSB7Ci0JCQkJCWJyZWFrOwotCQkJCX0KLQkJCX0KLQkJCVN0cmluZyByZXN1bHQgPSBzYi50b1N0cmluZygpLmludGVybigpOwotCQkJc2Iuc2V0TGVuZ3RoKDApOwotCQkJcmV0dXJuIHJlc3VsdDsKLQkJfQotCQlyZXR1cm4gbnVsbDsKLQl9Ci0KLQkvKioKLQkgKiBQYXJzZXMgYW4gaWRlbnRpZmllciBhbmQgcGxhY2VzIGl0IGludG8gdGhlIHBhc3NlZCBDaGFyQnVmZmVyCi0JICogCi0JICogQHBhcmFtIGNiCi0JICogICAgICAgICAgICBDaGFyQnVmZmVyIHdoZXJlIHRoZSBwYXJzZWQgaWRlbnRpZmllciB3aWxsIGJlIHBsYWNlZCBpbnRvCi0JICogQHJldHVybiB0aGUgbGVuZ3RoIG9mIHRoZSBwYXJzZWQgaWRlbnRpZmllcgotCSAqIEB0aHJvd3MgSU9FeGNlcHRpb24KLQkgKiAgICAgICAgICAgICBpZiBhbiBleGNlcHRpb24gb2NjdXJzIGR1cmluZyByZWFkIG9wZXJhdGlvbnMgZnJvbSB0aGUgUmVhZGVyCi0JICogICAgICAgICAgICAgb3IgdGhlIElucHV0U3RyZWFtCi0JICovCi0JcHJvdGVjdGVkIGludCBwYXJzZV9pZGVudGlmaWVyKENoYXJCdWZmZXIgY2IpIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0JCWlmIChpc05hbWVTdGFydENoYXIoY3VycmVudENoYXIpKSB7Ci0JCQlpbnQgbGVuZ3RoID0gMDsKLQkJCXdoaWxlIChpc05hbWVDaGFyKGN1cnJlbnRDaGFyKSkgewotCQkJCWNiLmFwcGVuZChjdXJyZW50Q2hhcik7Ci0JCQkJbGVuZ3RoKys7Ci0KLQkJCQlpZiAoIWdldE5leHRDaGFyKCkpIHsKLQkJCQkJYnJlYWs7Ci0JCQkJfQotCQkJfQotCi0JCQlyZXR1cm4gbGVuZ3RoOwotCQl9Ci0JCXJldHVybiAwOwotCX0KLQotCS8qKgotCSAqIFBhcnNlcyBhIHRhZyBuYW1lIGFuZCBpZiBpdCBpcyBzdWNjZXNzZnVsbHkgcGFyc2VkIHRoZSBtZXRob2Qgc2V0cyBpdCBhcwotCSAqIGEgbmFtZSBvZiB0aGUgcGFyZW50IHRhZwotCSAqIAotCSAqIEBwYXJhbSBhUGFyZW50Ci0JICogICAgICAgICAgICBwYXJlbnQgdGFnCi0JICogQHJldHVybiB0cnVlIGlmIHRoZSBuYW1lIGlzIHBhcnNlZCBzdWNjZXNzZnVsbHkgYW5kIGZhbHNlIG90aGVyd2lzZQotCSAqIEB0aHJvd3MgSU9FeGNlcHRpb24KLQkgKiBAc2VlIHBhcnNlX2lkZW50aWZpZXIKLQkgKi8KLQlwcm90ZWN0ZWQgYm9vbGVhbiBwYXJzZV90YWdfbmFtZShUYWdDbGFzcyBhUGFyZW50KSB0aHJvd3MgSU9FeGNlcHRpb24gewotCQlTdHJpbmcgbmFtZSA9IHBhcnNlX2lkZW50aWZpZXIoKTsKLQkJaWYgKG5hbWUgIT0gbnVsbCkgewotCQkJYVBhcmVudC5zZXROYW1lKG5hbWUpOwotCQl9Ci0JCXJldHVybiBuYW1lICE9IG51bGw7Ci0JfQotCi0JLyoqCi0JICogSGVscGVyIGZ1bmN0aW9uIHRoYXQgbm90aWZ5IGxpc3RlbmVycyBkZXBlbmRpbmcgb24gY2VydGFpbiBjb25kaXRpb25zCi0JICogc3VjaCBhcyBpZiB0aGUgdGFnIGV2ZW50IGlzIG9uLWNsb3NlIG9yIG9uLW9wZW4KLQkgKiAKLQkgKiBAcGFyYW0gYVRhZwotCSAqICAgICAgICAgICAgVGhlIHRhZyB0aGF0IHRoZSBub3RpZmljYXRpb24gZXZlbnQgaXMgdmFsaWQgZm9yLgotCSAqIEBwYXJhbSBpc1N0YXJ0Ci0JICogICAgICAgICAgICB0cnVlIGlmIHRoZSBldmVudCBpcyBvbi1vcGVuIGFuZCBmYWxzZSBpZiBpdCBpcyBvbi1jbG9zZQotCSAqLwotCXByb3RlY3RlZCB2b2lkIG5vdGlmeUxpc3RlbmVycyhUYWdDbGFzcyBhVGFnKSB7Ci0JCXRyeSB7Ci0JCQlpZiAoZkxldmVsIDw9IDAgfHwgZkxldmVsID09IGZDdXJyZW50TGV2ZWwpIHsKLQkJCQlmVGFnTGlzdGVuZXIudXNlVGFnKGFUYWcpOwotCQkJfQotCQl9IGNhdGNoIChSdW50aW1lRXhjZXB0aW9uIHJlKSB7Ci0JCQlpZiAoZkRlYnVnKSB7Ci0JCQkJU3lzdGVtLmVyci5wcmludGxuKCJBbiBvdXRzaWRlIGV4Y2VwdGlvbiBvY2N1cnJlZCB3aGlsZSBwcm9jZXNzaW5nIGEgdGFnIG9uIGxpbmUgIiArIGFUYWcuZ2V0TGluZSgpICsgIiwgdGhlIHRhZyBuYW1lIGlzOiAiICsgYVRhZy5nZXROYW1lKCkgKyAiLCB0aGUgbGV2ZWwgaXM6ICIgKyBmQ3VycmVudExldmVsKTsKLQkJCQlyZS5wcmludFN0YWNrVHJhY2UoU3lzdGVtLmVycik7Ci0JCQl9Ci0JCQl0aHJvdyByZTsKLQkJfQotCX0KLQotCS8qKgotCSAqIFBhcnNlcyBhIG5vcm1hbCB0YWcuIFRoZXJlIGFyZSB0d28gY2FzZXMgLSAoMSkgdGhlIHRhZyBoYXMgc2VwYXJhdGUgb3BlbgotCSAqIGFuZCBjbG9zZSB0YWcgZWxlbWVudHMgYW5kICgyKSB0aGUgdGFnIGlzIHNpbXBsZSBzdWNoYXMgJmx0O3RhZ19uYW1lIC4uLgotCSAqIC8mZ3Q7Ci0JICogCi0JICogQHBhcmFtIGFQYXJlbnQKLQkgKiAgICAgICAgICAgIFRoZSBwYXJlbnQgdGFnIHRoYXQgdGhpcyB0YWcgd2lsbCBiZSBhZGRlZCB0byBpZiB0aGUgcGFyc2luZwotCSAqICAgICAgICAgICAgaXMgc3VjY2Vzc2Z1bAotCSAqIEByZXR1cm4gdHJ1ZSBvbiBzdWNjZXNzIGFuZCBmYWxzZSBvdGhlcndpc2UKLQkgKiBAdGhyb3dzIElPRXhjZXB0aW9uCi0JICogQHNlZSBjbGVhcldoaXRlU3BhY2VzCi0JICogQHNlZSBwYXJzZV90YWdfbmFtZQotCSAqIEBzZWUgcGFyc2VfYXR0cl9saXN0Ci0JICogQHNlZSBub3RpZnlMaXN0ZW5lcnMKLQkgKiBAc2VlIGFjY2VwdF9jaGFyCi0JICogQHNlZSBhY2NlcHRfc2VxCi0JICogQHNlZSBwYXJzZV9QQ0RBVEEKLQkgKi8KLQlwcm90ZWN0ZWQgYm9vbGVhbiBwYXJzZV90YWdfbm9ybWFsKFRhZ0NsYXNzIGFQYXJlbnQpIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0JCS8vIExvb2tpbmcgZm9yIGEgdGFnX25hbWUgKGlkZW50aWZpZXIpCi0JCWlmIChpc05hbWVTdGFydENoYXIoY3VycmVudENoYXIpKSB7Ci0JCQlUYWdDbGFzcyB0YWcgPSBuZXcgVGFnQ2xhc3MoKTsKLQkJCXRhZy5zZXRMaW5lKGZMaW5lKTsKLQotCQkJcGFyc2VfdGFnX25hbWUodGFnKTsKLQkJCXBhcnNlX2F0dHJfbGlzdCh0YWcpOwotCi0JCQljbGVhcldoaXRlU3BhY2VzKCk7Ci0KLQkJCWlmIChhY2NlcHRfY2hhcignLycpKSB7Ci0JCQkJaWYgKCFhY2NlcHRfY2hhcignPicpKSB7Ci0JCQkJCWVycihFUlJfR1RfRVhQRUNURUQpOwotCQkJCX0KLQkJCQl0YWcuc2V0SW5saW5lKCk7Ci0JCQkJYVBhcmVudC5hZGRUYWcodGFnKTsKLQotCQkJCWlmICghZk9sZEJlaGF2aW91cikgewotCQkJCQlub3RpZnlMaXN0ZW5lcnModGFnKTsKLQkJCQl9Ci0KLQkJCQlyZXR1cm4gdHJ1ZTsKLQkJCX0gZWxzZSBpZiAoYWNjZXB0X2NoYXIoJz4nKSkgewotCi0JCQkJd2hpbGUgKHRydWUpIHsKLQkJCQkJY2xlYXJXaGl0ZVNwYWNlcygpOwotCQkJCQlpbnQgcG9zID0gZlBvczsKLQkJCQkJaWYgKGN1cnJlbnRDaGFyID09ICc8JykgeyAvLyBOb3JtYWwgdGFnLCBTcGVjaWFsIHRhZyBvcgotCQkJCQkJLy8gY2xvc2luZyB0YWcKLQkJCQkJCWlmICghcGFyc2VfdGFnKHRhZykpIHsgLy8gSXQgbWF5IGJlIGEgc3BlY2lhbCB0YWcuCi0JCQkJCQkJaWYgKCFhY2NlcHRfY2hhcignLycpKSB7Ci0JCQkJCQkJCWVycihwb3MgKyAxLCBFUlJfQ0xPU0VfVEFHMV9FWFBFQ1RFRCk7Ci0JCQkJCQkJfQotCi0JCQkJCQkJLy8gdHJ5aW5nIHRvIGFjY2VwdDogdGFnX25hbWUgKyBTKiArICc+JwotCQkJCQkJCXBvcyA9IGZQb3M7Ci0JCQkJCQkJaWYgKCFhY2NlcHRfc2VxKHRhZy5nZXROYW1lKCkpKSB7Ci0JCQkJCQkJCWVycihwb3MsICdcJycgKyB0YWcuZ2V0TmFtZSgpICsgIicgc3RyaW5nIGV4cGVjdGVkLiIpOwotCQkJCQkJCX0KLQotCQkJCQkJCWNsZWFyV2hpdGVTcGFjZXMoKTsKLQkJCQkJCQlpZiAoIWFjY2VwdF9jaGFyKCc+JykpIHsKLQkJCQkJCQkJZXJyKEVSUl9HVF9FWFBFQ1RFRCk7Ci0JCQkJCQkJfQotCi0JCQkJCQkJYVBhcmVudC5hZGRUYWcodGFnKTsKLQotCQkJCQkJCW5vdGlmeUxpc3RlbmVycyh0YWcpOwotCi0JCQkJCQkJcmV0dXJuIHRydWU7Ci0JCQkJCQl9Ci0JCQkJCX0gZWxzZSB7Ci0JCQkJCQlpZiAoIXBhcnNlX1BDREFUQSh0YWcpKQotCQkJCQkJCWJyZWFrOwotCQkJCQl9Ci0JCQkJfQotCQkJCWVycihFUlJfQ09OVEVOVF9FWFBFQ1RFRCk7Ci0JCQl9IGVsc2UgewotCQkJCWVycihFUlJfQ0xPU0VfVEFHMl9FWFBFQ1RFRCk7Ci0JCQl9Ci0JCX0KLQkJcmV0dXJuIGZhbHNlOwotCX0KLQotCS8qKgotCSAqIFBhcnNlcyBzcGVjaWFsIHRhZ3MsIHN1Y2ggdGhhdCBiZWdpbnMgd2l0aDo8YnI+Ci0JICogCi0JICogPHByZT48Y29kZT4KLQkgKiAmbHQ7IS0tICAgICAgICAgY29tbWVudHMKLQkgKiAmbHQ7IXRhZ19uYW1lICAgUGFyc2luZyBpbnN0cnVjdGlvbnMKLQkgKiAmbHQ7IVsgICAgICAgICAgQ0RBVEEgZWxlbWVudAotCSAqICZsdDs/ICAgICAgICAgICBET0NUWVBFLCBldGMuCi0JICogPC9jb2RlPjwvcHJlPgotCSAqIAotCSAqIEBwYXJhbSBhUGFyZW50Ci0JICogICAgICAgICAgICBUaGUgcGFyZW50IHRhZyB0aGF0IHRoaXMgdGFnIHdpbGwgYmUgYWRkZWQgdG8gaWYgdGhlIHBhcnNpbmcKLQkgKiAgICAgICAgICAgIGlzIHN1Y2Nlc3NmdWwKLQkgKiBAcmV0dXJuIHRydWUgb24gc3VjY2VzcyBhbmQgZmFsc2Ugb3RoZXJ3aXNlCi0JICogQHRocm93cyBJT0V4Y2VwdGlvbgotCSAqIEBzZWUgYWNjZXB0X2NoYXIKLQkgKiBAc2VlIGNsZWFyV2hpdGVTcGFjZXMKLQkgKiBAc2VlIHBhcnNlX3RhZ19DREFUQQotCSAqIEBzZWUgcGFyc2VfdGFnX25hbWUKLQkgKiBAc2VlIHBhcnNlX2NvbW1lbnQKLQkgKi8KLQlwcm90ZWN0ZWQgYm9vbGVhbiBwYXJzZV90YWdfc3BlY2lhbChUYWdDbGFzcyBhUGFyZW50KSB0aHJvd3MgSU9FeGNlcHRpb24gewotCQlpZiAoYWNjZXB0X2NoYXIoJyEnKSkgewotCi0JCQlUYWdDbGFzcyB0YWcgPSBuZXcgVGFnQ2xhc3MoKTsKLQotCQkJaWYgKHBhcnNlX3RhZ19uYW1lKHRhZykpIHsKLQkJCQljbGVhcldoaXRlU3BhY2VzKCk7Ci0KLQkJCQl3aGlsZSAodHJ1ZSkgewotCQkJCQlpZiAoYWNjZXB0X2NoYXIoJz4nKSkgewotCQkJCQkJY2xlYXJXaGl0ZVNwYWNlcygpOwotCQkJCQkJcmV0dXJuIHRydWU7Ci0JCQkJCX0KLQkJCQkJZ2V0TmV4dENoYXIoKTsKLQkJCQl9Ci0JCQl9IGVsc2UgaWYgKHBhcnNlX3RhZ19DREFUQShhUGFyZW50KSkgeyAvLyBwYXJzZSBDREFUQSB0YWcKLQkJCQlyZXR1cm4gdHJ1ZTsKLQkJCX0gZWxzZSBpZiAocGFyc2VfY29tbWVudCh0YWcpKSB7Ci0JCQkJcmV0dXJuIHRydWU7Ci0JCQl9Ci0JCX0gZWxzZSBpZiAoYWNjZXB0X2NoYXIoJz8nKSkgewotCQkJVGFnQ2xhc3MgdGFnID0gbmV3IFRhZ0NsYXNzKCk7Ci0KLQkJCWludCBwb3MgPSBmUG9zOwotCQkJaWYgKHBhcnNlX3RhZ19uYW1lKHRhZykpIHsKLQkJCQlpZiAodGFnLmdldE5hbWUoKS5lcXVhbHMoWE1MKSkgewotCQkJCQllcnIocG9zIC0gMiwgRVJSX1hNTFBST0xPR19FWFBFQ1RFRCk7Ci0JCQkJfQotCi0JCQkJY2hhciBwcmV2Q2ggPSAwOwotCQkJCXdoaWxlICh0cnVlKSB7Ci0JCQkJCWlmIChjdXJyZW50Q2hhciA9PSAnPicpIHsKLQkJCQkJCWlmIChwcmV2Q2ggPT0gJz8nKSB7Ci0JCQkJCQkJYWNjZXB0X2NoYXIoJz4nKTsKLQkJCQkJCQljbGVhcldoaXRlU3BhY2VzKCk7Ci0JCQkJCQkJcmV0dXJuIHRydWU7Ci0JCQkJCQl9Ci0JCQkJCX0KLQkJCQkJcHJldkNoID0gY3VycmVudENoYXI7Ci0JCQkJCWdldE5leHRDaGFyKCk7Ci0JCQkJfQotCi0JCQl9Ci0JCQllcnIocG9zLCBFUlJfVEFHTkFNRV9FWFBFQ1RFRCk7Ci0JCX0KLQkJcmV0dXJuIGZhbHNlOwotCX0KLQotCS8qKgotCSAqIFBhcnNlcyBhbiBhdHRyaWJ1dGUgdmFsdWUgYW5kIHJldHVybnMgaXQgYXMgYSBzdHJpbmcKLQkgKiAKLQkgKiBAcmV0dXJuIHRoZSBwYXJzZWQgYXR0cmlidXRlIHZhbHVlIGFzIGEgc3RyaW5nLgotCSAqIEB0aHJvd3MgSU9FeGNlcHRpb24KLQkgKiAgICAgICAgICAgICBpZiBhbiBleGNlcHRpb24gb2NjdXJzIGR1cmluZyByZWFkIG9wZXJhdGlvbnMgZnJvbSB0aGUgUmVhZGVyCi0JICogICAgICAgICAgICAgb3IgdGhlIElucHV0U3RyZWFtCi0JICovCi0JcHJvdGVjdGVkIFN0cmluZyBnZXRBdHRyVmFsdWUoKSB0aHJvd3MgSU9FeGNlcHRpb24gewotCQlDaGFyQnVmZmVyIGNiID0gZ2V0Q2hhckJ1ZmZlcigpOwotCi0JCWNsZWFyV2hpdGVTcGFjZXMoKTsKLQkJYWNjZXB0X2NoYXIoJz0nKTsKLQkJY2xlYXJXaGl0ZVNwYWNlcygpOwotCi0JCWlmIChjdXJyZW50Q2hhciAhPSAnXCcnICYmIGN1cnJlbnRDaGFyICE9ICciJykgewotCQkJZXJyKEVSUl9RVU9UX0VYUEVDVEVEKTsKLQkJfQotCi0JCWNoYXIgcXVvdCA9IGN1cnJlbnRDaGFyOwotCQlhY2NlcHRfY2hhcihxdW90KTsKLQkJcGFyc2VfYXR0cl92YWx1ZShjYiwgcXVvdCk7Ci0KLQkJaWYgKCFhY2NlcHRfY2hhcihxdW90KSkgewotCQkJZXJyKCInIiArIHF1b3QgKyAiJyBleHBlY3RlZC4iKTsKLQkJfQotCi0JCVN0cmluZyByZXN1bHQgPSBjYi50b1N0cmluZygpOwotCQljYi5zZXRMZW5ndGgoMCk7Ci0JCWNsZWFyV2hpdGVTcGFjZXMoKTsKLQkJcmV0dXJuIHJlc3VsdDsKLQl9Ci0KLQkvKioKLQkgKiBQYXJzZXMgdGhlIFhNTCBwcm9sb2cgdGFnLCBpLmUuPGJyPgotCSAqIDxjb2RlPiAmbHQ7P3htbCB2ZXJzaW9uPSIuLi4iIGVuY29kaW5nPSIuLi4iIHN0YW5kYWxvbmU9Ii4uLiIgPyZndDsgPC9jb2RlPjxicj4KLQkgKiAKLQkgKiBAcGFyYW0gcGFyZW50Ci0JICogICAgICAgICAgICB0aGUgcGFyZW50IHRhZyAoaW4gdGhpcyBjYXNlIHRoaXMgaXMgdGhlIHJvb3QgImZha2UiIHRhZywKLQkgKiAgICAgICAgICAgIHdoaWNoIHRoZSBsaXN0ZW5lcnMgd2lsbCBuZXZlciBiZSBpbmZvcm1lZCBmb3IuLi4pCi0JICogQHRocm93cyBJT0V4Y2VwdGlvbgotCSAqICAgICAgICAgICAgIGlmIGFuIGV4Y2VwdGlvbiBvY2N1cnMgZHVyaW5nIHJlYWQgb3BlcmF0aW9ucyBmcm9tIHRoZSBSZWFkZXIKLQkgKiAgICAgICAgICAgICBvciB0aGUgSW5wdXRTdHJlYW0KLQkgKi8KLQlwcm90ZWN0ZWQgYm9vbGVhbiBwYXJzZV94bWxfcHJvbG9nKFRhZ0NsYXNzIHBhcmVudCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKLQkJaWYgKGFjY2VwdF9jaGFyKCc/JykpIHsKLQkJCVRhZ0NsYXNzIHRhZyA9IG5ldyBUYWdDbGFzcygpOwotCi0JCQlpZiAocGFyc2VfdGFnX25hbWUodGFnKSkgewotCQkJCWlmICh0YWcuZ2V0TmFtZSgpLmVxdWFsc0lnbm9yZUNhc2UoWE1MKSkgewotCQkJCQlpZiAoZk9sZExldmVscykKLQkJCQkJCWZDdXJyZW50TGV2ZWwrKzsKLQotCQkJCQljbGVhcldoaXRlU3BhY2VzKCk7Ci0KLQkJCQkJaW50IHBvcyA9IGZQb3M7Ci0KLQkJCQkJU3RyaW5nIHMgPSBwYXJzZV9pZGVudGlmaWVyKCk7Ci0KLQkJCQkJYm9vbGVhbiBiRW5jb2RpbmcgPSBmYWxzZTsKLQkJCQkJYm9vbGVhbiBiU3RhbmRhbG9uZSA9IGZhbHNlOwotCi0JCQkJCWlmIChWRVJTSU9OLmVxdWFscyhzKSkgewotCQkJCQkJZlZlcnNpb24gPSBnZXRBdHRyVmFsdWUoKTsKLQkJCQkJCXMgPSBwYXJzZV9pZGVudGlmaWVyKCk7Ci0JCQkJCX0gZWxzZSB7Ci0JCQkJCQllcnIocG9zLCBFUlJfVkVSU0lPTl9FWFBFQ1RFRCk7Ci0JCQkJCX0KLQotCQkJCQlpZiAoRU5DT0RJTkcuZXF1YWxzKHMpKSB7Ci0JCQkJCQlmRW5jb2RpbmcgPSBnZXRBdHRyVmFsdWUoKS50b1VwcGVyQ2FzZSgpOwotCQkJCQkJcyA9IHBhcnNlX2lkZW50aWZpZXIoKTsKLQkJCQkJCWJFbmNvZGluZyA9IHRydWU7Ci0JCQkJCX0KLQotCQkJCQlpZiAoU1RBTkRBTE9ORS5lcXVhbHMocykpIHsKLQkJCQkJCWZTdGFuZGFsb25lID0gZ2V0QXR0clZhbHVlKCk7Ci0JCQkJCQlzID0gcGFyc2VfaWRlbnRpZmllcigpOwotCQkJCQkJYlN0YW5kYWxvbmUgPSB0cnVlOwotCQkJCQl9Ci0KLQkJCQkJaWYgKHMgIT0gbnVsbCkgewotCQkJCQkJaWYgKGJFbmNvZGluZyAmJiBiU3RhbmRhbG9uZSkKLQkJCQkJCQllcnIoRVJSX0NMT1NFX1RBRzNfRVhQRUNURUQpOwotCi0JCQkJCQlpZiAoIWJFbmNvZGluZyAmJiAhYlN0YW5kYWxvbmUpCi0JCQkJCQkJZXJyKEVSUl9FTkNPRElOR19TVEFOREFMT05FX0VYUEVDVEVEKTsKLQotCQkJCQkJaWYgKGJFbmNvZGluZykKLQkJCQkJCQllcnIoRVJSX1NUQU5EQUxPTkVfRVhQRUNURUQpOwotCQkJCQkJZXJyKEVSUl9DTE9TRV9UQUczX0VYUEVDVEVEKTsKLQkJCQkJfQotCi0JCQkJCWNsZWFyV2hpdGVTcGFjZXMoKTsKLQkJCQkJcG9zID0gZlBvczsKLQkJCQkJaWYgKCFhY2NlcHRfc2VxKCI/PiIpKQotCQkJCQkJZXJyKHBvcywgRVJSX0NMT1NFX1RBRzNfRVhQRUNURUQpOwotCQkJCQlyZXR1cm4gdHJ1ZTsKLQkJCQl9Ci0KLQkJCQljaGFyIHByZXZDaCA9IDA7Ci0KLQkJCQl3aGlsZSAodHJ1ZSkgewotCQkJCQlpZiAoY3VycmVudENoYXIgPT0gJz4nKSB7Ci0JCQkJCQlpZiAocHJldkNoID09ICc/JykgewotCQkJCQkJCWFjY2VwdF9jaGFyKCc+Jyk7Ci0JCQkJCQkJY2xlYXJXaGl0ZVNwYWNlcygpOwotCi0JCQkJCQkJcmV0dXJuIHRydWU7Ci0JCQkJCQl9Ci0JCQkJCQllcnIoRVJSX1FVRVNUSU9OTUFSS19FWFBFQ1RFRCk7Ci0JCQkJCX0gZWxzZSBpZiAoY3VycmVudENoYXIgPT0gJzwnKSB7Ci0JCQkJCQllcnIoRVJSX0lMTEVHQUxfQ0hBUkFDVEVSICsgIiAoJzwnKSIpOwotCQkJCQl9Ci0JCQkJCXByZXZDaCA9IGN1cnJlbnRDaGFyOwotCQkJCQlnZXROZXh0Q2hhcigpOwotCQkJCX0KLQotCQkJfQotCQl9Ci0JCXJldHVybiBmYWxzZTsKLQl9Ci0KLQkvKioKLQkgKiBQYXJzZXMgYSBjb21tZW50LiBUaGUgZ3JhbW1hciBpczo8YnI+Ci0JICogQ29tbWVudCA6Oj0gJyZsdDshLS0nICgoQ2hhciAtICctJykgfCAoJy0nIChDaGFyIC0gJy0nKSkpKiAnLS0mZ3Q7Jzxicj4KLQkgKiBOb3RlIHRoYXQgdGhlIGdyYW1tYXIgZG9lcyBub3QgYWxsb3cgYSBjb21tZW50IGVuZGluZyBpbiAtLS0mZ3Q7LiBUaGUKLQkgKiBmb2xsb3dpbmcgZXhhbXBsZSBpcyBub3Qgd2VsbC1mb3JtZWQuPGJyPgotCSAqIDxjb2RlPgotCSAqICZsdDshLS0gQissIEIsIG9yIEItLS0mZ3Q7PC9jb2RlPgotCSAqIAotCSAqIEBwYXJhbSBhUGFyZW50Ci0JICogICAgICAgICAgICBUaGUgcGFyZW50IHRhZwotCSAqIEByZXR1cm4gdHJ1ZSBvbiBzdWNjZXNzIGFuZCBmYWxzZSBvdGhlcndpc2UKLQkgKiBAdGhyb3dzIElPRXhjZXB0aW9uCi0JICogQHNlZSBhY2NlcHRfY2hhcgotCSAqLwotCXByb3RlY3RlZCBib29sZWFuIHBhcnNlX2NvbW1lbnQoVGFnQ2xhc3MgYVBhcmVudCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKLQkJaWYgKGFjY2VwdF9jaGFyKCctJykpIHsKLQkJCWlmICghYWNjZXB0X2NoYXIoJy0nKSkgewotCQkJCWVycihFUlJfREFTSF9FWFBFQ1RFRCk7Ci0JCQl9Ci0KLQkJCXdoaWxlICh0cnVlKSB7Ci0JCQkJaWYgKGFjY2VwdF9jaGFyKCctJykpIHsKLQkJCQkJaWYgKGFjY2VwdF9jaGFyKCctJykpIHsKLQkJCQkJCWlmIChhY2NlcHRfY2hhcignPicpKSB7Ci0JCQkJCQkJYnJlYWs7Ci0JCQkJCQl9Ci0KLQkJCQkJCWVycihFUlJfR1RfRVhQRUNURUQpOwotCQkJCQl9Ci0JCQkJfQotCi0JCQkJaWYgKCFnZXROZXh0Q2hhcigpKSB7Ci0JCQkJCWVycihFUlJfQ09NTUVOVF9DTE9TRV9FWFBFQ1RFRCk7Ci0JCQkJfQotCQkJfQotCQkJcmV0dXJuIHRydWU7Ci0JCX0KLQkJcmV0dXJuIGZhbHNlOwotCX0KLQotCS8qKgotCSAqIFBhcnNlcyBlaXRoZXIgbm9ybWFsIG9yIHNwZWNpYWwgdGFnCi0JICogCi0JICogQHBhcmFtIGFQYXJlbnQKLQkgKiAgICAgICAgICAgIFRoZSBwYXJlbnQgdGFnIHRoYXQgdGhlIHN1Y2Nlc3NmdWxseSBwYXJzZWQgdGFnIHdpbGwgKGlmIGl0IGlzCi0JICogICAgICAgICAgICBub3JtYWwgdGFnIG9yIENEQVRBIGVsZW1lbnQpIGJlIGFkZGVkCi0JICogQHJldHVybiB0cnVlIG9uIHN1Y2Nlc3MgYW5kIGZhbHNlIG90aGVyd2lzZQotCSAqIEB0aHJvd3MgSU9FeGNlcHRpb24KLQkgKiBAc2VlIGFjY2VwdF9jYWhyCi0JICogQHNlZSBwYXJzZV90YWdfbm9ybWFsCi0JICogQHNlZSBwYXJzZV90YWdfc3BlY2lhbAotCSAqIEBzZWUgY2xlYXJXaGl0ZVNwYWNlcwotCSAqLwotCXByb3RlY3RlZCBib29sZWFuIHBhcnNlX3RhZyhUYWdDbGFzcyBhUGFyZW50KSB0aHJvd3MgSU9FeGNlcHRpb24gewotCQljbGVhcldoaXRlU3BhY2VzKCk7Ci0JCXRyeSB7Ci0JCQlmQ3VycmVudExldmVsKys7Ci0KLQkJCWlmIChhY2NlcHRfY2hhcignPCcpKSB7Ci0JCQkJaWYgKHBhcnNlX3RhZ19ub3JtYWwoYVBhcmVudCkgfHwgcGFyc2VfdGFnX3NwZWNpYWwoYVBhcmVudCkpIHsKLQkJCQkJcmV0dXJuIHRydWU7Ci0JCQkJfQotCQkJfQotCQkJcmV0dXJuIGZhbHNlOwotCQl9IGZpbmFsbHkgewotCQkJZkN1cnJlbnRMZXZlbC0tOwotCQl9Ci0JfQotCi0JLyoqCi0JICogUGFyc2VzIHRoZSBjb250ZW50IG9mIHRoZSB0YWcgKGluY2x1ZGluZyBzdWItdGFncyBhbmQgc3ViLWVsZW1lbnRzKQotCSAqIAotCSAqIEBwYXJhbSBhUGFyZW50Ci0JICogICAgICAgICAgICBUaGUgcGFyZW50IHRhZyB0aGF0IHRoZSBjb250ZW50IGFuZCB0YWdzIHdpbGwgYmUgYWRkZWQgdG8KLQkgKiBAcmV0dXJuIHRydWUgb24gc3VjY2VzcyBhbmQgZmFsc2Ugb3RoZXJ3aXNlCi0JICogQHRocm93cyBJT0V4Y2VwdGlvbgotCSAqIEBzZWUgcGFyc2VfUENEQVRBCi0JICogQHNlZSBwYXJzZV90YWcKLQkgKi8KLQlwcm90ZWN0ZWQgYm9vbGVhbiBwYXJzZV9jb250ZW50KFRhZ0NsYXNzIGFQYXJlbnQpIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0JCXJldHVybiAocGFyc2VfUENEQVRBKGFQYXJlbnQpIHx8IHBhcnNlX3RhZyhhUGFyZW50KSk7Ci0JfQotCi0JLyoqCi0JICogUGFyc2VzIGEgQ0RBVEEgdGFnIChvciBDREFUQSBjb250ZW50IGVsZW1lbnQpLgotCSAqIAotCSAqIEBwYXJhbSBhUGFyZW50Ci0JICogICAgICAgICAgICBUaGUgcGFyZW50IHRhZyB0aGF0IHRoZSBjb250ZW50IHdpbGwgYmUgYWRkZWQgdG8KLQkgKiBAcmV0dXJuIHRydWUgb24gc3VjY2VzcyBhbmQgZmFsc2Ugb3RoZXJ3aXNlCi0JICogQHRocm93cyBJT0V4Y2VwdGlvbgotCSAqLwotCXByb3RlY3RlZCBib29sZWFuIHBhcnNlX3RhZ19DREFUQShUYWdDbGFzcyBhUGFyZW50KSB0aHJvd3MgSU9FeGNlcHRpb24gewotCQlpZiAoYWNjZXB0X2NoYXIoJ1snKSkgewotCQkJaW50IHBvcyA9IGZQb3M7Ci0JCQlpZiAoIWFjY2VwdF9zZXEoQ0RBVEEpKQotCQkJCWVycihwb3MsIEVSUl9DREFUQV9FWFBFQ1RFRCk7Ci0KLQkJCWlmICghYWNjZXB0X2NoYXIoJ1snKSkKLQkJCQllcnIoRVJSX09QRU5TUUJSQUNLRVRfRVhQRUNURUQpOwotCi0JCQlkbyB7Ci0JCQkJaWYgKGN1cnJlbnRDaGFyICE9ICc+JykgewotCQkJCQlhUGFyZW50LmdldENvbnRlbnRCdWZmZXIoKS5hcHBlbmQoY3VycmVudENoYXIpOwotCQkJCX0gZWxzZSB7Ci0JCQkJCUNoYXJCdWZmZXIgc2IgPSBhUGFyZW50LmdldENvbnRlbnRCdWZmZXIoKTsKLQkJCQkJaW50IGwgPSBzYi5sZW5ndGgoKTsKLQotCQkJCQlpZiAobCA+PSAyKSB7Ci0JCQkJCQlpZiAoc2IuY2hhckF0KGwgLSAxKSA9PSAnXScgJiYgc2IuY2hhckF0KGwgLSAyKSA9PSAnXScpIHsKLQkJCQkJCQlzYi5zZXRMZW5ndGgobCAtIDIpOyAvLyBUcnVuY2F0ZXMgdGhlIGV4dHJhICJdXSIKLQkJCQkJCQkvLyBzeW1ib2xzIGFwcGVuZGVkIGF0IHRoZQotCQkJCQkJCS8vIGVuZAotCi0JCQkJCQkJZ2V0TmV4dENoYXIoKTsKLQkJCQkJCQlyZXR1cm4gdHJ1ZTsKLQkJCQkJCX0KLQkJCQkJfQotCQkJCQlzYi5hcHBlbmQoY3VycmVudENoYXIpOwotCQkJCX0KLQkJCX0gd2hpbGUgKGdldE5leHRDaGFyKCkpOwotCi0JCQllcnIoZlBvcyAtIDEsIEVSUl9DTE9TRV9DREFUQV9FWFBFQ1RFRCk7Ci0JCX0KLQkJcmV0dXJuIGZhbHNlOwotCX0KLQotCS8qKgotCSAqIFBhcnNlcyBQQ0RBVEEgY29udGVudCAoUGFyc2VhYmxlIENvbnRlbnQgREFUQSkuIFRoZSBFbnRpdHlSZWZzIGFuZAotCSAqIENoYXJSZWZzIHRoYXQgYXJlIHBhcnNlZCB3aWxsIGJlIHR1cm5lZCB0byBpdHMgc3ltYm9sIGVxdWl2YWxlbnQuCi0JICogCi0JICogQHBhcmFtIGFQYXJlbnQKLQkgKiAgICAgICAgICAgIFRoZSBwYXJlbnQgdGFnIHRoYXQgdGhlIFBDREFUQSB3aWxsIGJlIGFkZGVkIHRvCi0JICogQHJldHVybiB0cnVlIG9uIHN1Y2Nlc3MgYW5kIGZhbHNlIG90aGVyd2lzZQotCSAqIEB0aHJvd3MgSU9FeGNlcHRpb24KLQkgKiBAc2VlIGFjY2VwdF9jaGFyCi0JICogQHNlZSBwYXJzZV9DaGFyUmVmCi0JICogQHNlZSBwYXJzZV9FbnRpdHlSZWYKLQkgKi8KLQlwcm90ZWN0ZWQgYm9vbGVhbiBwYXJzZV9QQ0RBVEEoVGFnQ2xhc3MgYVBhcmVudCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKLQkJYm9vbGVhbiByZXN1bHQgPSBmYWxzZTsKLQkJd2hpbGUgKGN1cnJlbnRDaGFyICE9ICc8JykgewotCQkJcmVzdWx0ID0gdHJ1ZTsKLQotCQkJQ2hhckJ1ZmZlciBzYkNvbnRlbnQgPSBhUGFyZW50LmdldENvbnRlbnRCdWZmZXIoKTsKLQotCQkJaWYgKGFjY2VwdF9jaGFyKCcmJykpIHsKLQkJCQlpbnQgcG9zID0gZlBvczsKLQotCQkJCWlmICghcGFyc2VfQ2hhclJlZihzYkNvbnRlbnQpKQotCQkJCQlpZiAoIXBhcnNlX0VudGl0eVJlZihzYkNvbnRlbnQsIGZhbHNlKSkKLQkJCQkJCWVycihwb3MgLSAxLCBFUlJfRU5USVRZX0VYUEVDVEVEKTsKLQotCQkJfSBlbHNlIHsKLQkJCQlzYkNvbnRlbnQuYXBwZW5kKGN1cnJlbnRDaGFyKTsKLQotCQkJCWlmICghZ2V0TmV4dENoYXIoKSkKLQkJCQkJYnJlYWs7Ci0JCQl9Ci0JCX0KLQkJcmV0dXJuIHJlc3VsdDsKLQl9Ci0KLQkvKioKLQkgKiBBY2NlcHRzIG9uZSBjaGFyYWN0ZXIgZnJvbSB0aGUgaW5wdXQgc3RyZWFtIGFuZCBpZiBpdCdzIHN1Y2Nlc3NmdWwgbW92ZXMKLQkgKiBvbmUgY2hhcmFjdGVyIGZvcndhcmQuCi0JICogCi0JICogQHBhcmFtIGNoCi0JICogICAgICAgICAgICBUaGUgY2hhcmFjdGVyIHRoYXQgc2hvdWxkIGJlIGFjY2VwdGVkCi0JICogQHJldHVybiB0cnVlIG9uIHN1Y2Nlc3MgYW5kIGZhbHNlIG90aGVyd2lzZQotCSAqIEB0aHJvd3MgSU9FeGNlcHRpb24KLQkgKi8KLQlwcm90ZWN0ZWQgYm9vbGVhbiBhY2NlcHRfY2hhcihjaGFyIGNoKSB0aHJvd3MgSU9FeGNlcHRpb24gewotCQlpZiAoY3VycmVudENoYXIgPT0gY2gpIHsKLQkJCWdldE5leHRDaGFyKCk7Ci0JCQlyZXR1cm4gdHJ1ZTsKLQkJfQotCQlyZXR1cm4gZmFsc2U7Ci0JfQotCi0JLyoqCi0JICogQWNjZXB0cyBhIHNlcXVlbmNlIG9mIGNoYXJhY3RlcnMgZ2l2ZW4gYnkgc2VxIHBhcmFtZXRlci4gSWYgdGhlIHNlcXVlbmNlCi0JICogaXMgYWNjZXB0ZWQgc3VjY2Vzc2Z1bGx5IHRoZW4gdGhlIGN1cnJlbnRDaGFyIGZpZWxkIHdpbGwgY29udGFpbiB0aGUKLQkgKiBjaGFyYWN0ZXIgaW1tZWRpYXRlbHkgYWZ0ZXIgdGhlIGFjY2VwdGVkIHNlcXVlbmNlLgotCSAqIAotCSAqIEBwYXJhbSBzZXEKLQkgKiAgICAgICAgICAgIFRoZSBjaGFyYWN0ZXIgc2VxdWVuY2UgdGhhdCBzaG91bGQgYmUgYWNjZXB0ZWQKLQkgKiBAcmV0dXJuIHRydWUgb24gc3VjY2VzcyBhbmQgZmFsc2Ugb3RoZXJ3aXNlCi0JICogQHRocm93cyBJT0V4Y2VwdGlvbgotCSAqLwotCXByb3RlY3RlZCBib29sZWFuIGFjY2VwdF9zZXEoU3RyaW5nIHNlcSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKLQkJZm9yIChpbnQgaSA9IDA7IGkgPCBzZXEubGVuZ3RoKCk7IGkrKykgewotCQkJaWYgKCFhY2NlcHRfY2hhcihzZXEuY2hhckF0KGkpKSkKLQkJCQlyZXR1cm4gZmFsc2U7Ci0JCX0KLQkJcmV0dXJuIHRydWU7Ci0JfQotCi0JcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nW10gZkVudGl0aWVzID0gKGZPbGRCZWhhdmlvdXIpID8gZk9sZF9lbnRpdGllcyA6IGZOZXdfZW50aXRpZXM7Ci0JcHJpdmF0ZSBzdGF0aWMgZmluYWwgY2hhcltdIGZFbnRfY2hhcnMgPSAoZk9sZEJlaGF2aW91cikgPyBmT2xkX2VudF9jaGFycyA6IGZOZXdfZW50X2NoYXJzOwotCi0JLyoqCi0JICogPGNvZGU+Ci0JICogRW50aXR5UmVmIDo6PSAnJicgKyBFbnRpdHlWYWx1ZSArICc7Jzxicj4KLQkgKiBFbnRpdHlWYWx1ZSA6Oj0gJ2FtcCcgfCAncXVvdCcgfCAnYXBvcycgfCAnZ3QnIHwgJ2x0JyB8IGlkZW50aWZpZXIKLQkgKiA8L2NvZGU+Ci0JICogCi0JICogQHBhcmFtIHNiCi0JICogICAgICAgICAgICBUaGUgc3RyaW5nIGJ1ZmZlciB0aGF0IHRoZSByZWNvZ25pemVkIGVudGl0eSB3aWxsIGJlIGFwcGVuZGVkCi0JICogICAgICAgICAgICB0bwotCSAqIEB0aHJvd3MgSU9FeGNlcHRpb24KLQkgKiBAcmV0dXJuIHRydWUgb24gc3VjY2VzcyBhbmQgZmFsc2Ugb3RoZXJ3aXNlCi0JICogQHNlZSBwYXJzZV9pZGVudGlmaWVyCi0JICogQHNlZSBhY2NlcHRfY2hhcgotCSAqLwotCXByb3RlY3RlZCBib29sZWFuIHBhcnNlX0VudGl0eVJlZihDaGFyQnVmZmVyIHNiLCBib29sZWFuIGluQXR0cmlidXRlKSB0aHJvd3MgSU9FeGNlcHRpb24gewotCQlTdHJpbmcgZW50ID0gcGFyc2VfaWRlbnRpZmllcigpOwotCi0JCWlmICghYWNjZXB0X2NoYXIoJzsnKSkgewotCQkJZXJyKEVSUl9TRU1JQ09MT05fRVhQRUNURUQpOwotCQl9Ci0KLQkJaWYgKCFpbkF0dHJpYnV0ZSkgewotCQkJaW50IGxlbmd0aCA9IGZFbnRpdGllcy5sZW5ndGg7Ci0JCQlmb3IgKGludCBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7Ci0JCQkJaWYgKGZFbnRpdGllc1tpXSA9PSBlbnQpIHsgLy8gJ2VudCcgaXMgaW50ZXJuZWQgYnkKLQkJCQkJLy8gcGFyc2VfaWRlbnRpZmllcigpIGZ1bmN0aW9uCi0JCQkJCXNiLmFwcGVuZChmRW50X2NoYXJzW2ldKTsKLQkJCQkJcmV0dXJuIHRydWU7Ci0JCQkJfQotCQkJfQotCQl9Ci0KLQkJc2IuYXBwZW5kKCcmJyk7Ci0JCWlmIChlbnQgIT0gbnVsbCkgewotCQkJc2IuYXBwZW5kKGVudCk7Ci0JCX0KLQkJc2IuYXBwZW5kKCc7Jyk7Ci0KLQkJcmV0dXJuIHRydWU7Ci0JfQotCi0JLyoqCi0JICogUGFyc2VzIGEgQ2hhclJlZmVyZW5jZSBhbmQgaWYgaXQgaXMgc3VjY2Vzc2Z1bCB0aGVuIGFwcGVuZHMgaXQgdG8gdGhlCi0JICogcGFzc2VkIENoYXJCdWZmZXIKLQkgKiAKLQkgKiBAcGFyYW0gc2IKLQkgKiAgICAgICAgICAgIENoYXJCdWZmZXIgdGhhdCB0aGUgcGFyc2VkIENoYXJSZWZlcmVuY2Ugd2lsbCBiZSBhZGRlZCB0bwotCSAqIEByZXR1cm4gdHJ1ZSBvbiBzdWNjZXNzIGFuZCBmYWxzZSBvdGhlcndpc2UKLQkgKiBAdGhyb3dzIElPRXhjZXB0aW9uCi0JICovCi0JcHJvdGVjdGVkIGJvb2xlYW4gcGFyc2VfQ2hhclJlZihDaGFyQnVmZmVyIHNiKSB0aHJvd3MgSU9FeGNlcHRpb24gewotCQlpZiAoYWNjZXB0X2NoYXIoJyMnKSkgewotCQkJLy8gVE9ETyAtIFBvc3Rwb25lZC4uLgotCQkJd2hpbGUgKGN1cnJlbnRDaGFyICE9ICc7JykgewotCQkJCWdldE5leHRDaGFyKCk7Ci0JCQl9Ci0KLQkJCWlmICghYWNjZXB0X2NoYXIoJzsnKSkgewotCQkJCWVycihmUG9zIC0gMSwgRVJSX1NFTUlDT0xPTl9FWFBFQ1RFRCk7Ci0JCQl9Ci0KLQkJCXJldHVybiB0cnVlOwotCQl9Ci0JCXJldHVybiBmYWxzZTsKLQl9Ci0KLQkvKioKLQkgKiBDbGVhcnMgdGhlIHdoaXRlIHNwYWNlcyBzdGFydGluZyBmcm9tIHRoZSBjdXJyZW50IHBvc2l0aW9uCi0JICogCi0JICogQHRocm93cyBJT0V4Y2VwdGlvbgotCSAqLwotCXByb3RlY3RlZCB2b2lkIGNsZWFyV2hpdGVTcGFjZXMoKSB0aHJvd3MgSU9FeGNlcHRpb24gewotCQl3aGlsZSAoQ2hhcmFjdGVyLmlzV2hpdGVzcGFjZShjdXJyZW50Q2hhcikpIHsKLQkJCWlmICghZ2V0TmV4dENoYXIoKSkKLQkJCQlicmVhazsKLQkJfQotCX0KLQotCS8qKgotCSAqIFRocm93cyBhbiBJT0V4Y2VwdGlvbiB3aXRoIGEgZ2l2ZW4gbWVzc2FnZS4gVGhlIGN1cnJlbnQgbGluZSBudW1iZXIgYW5kCi0JICogbGluZSBwb3NpdGlvbiBhcmUgYXBwZW5kZWQgdG8gdGhlIGVycm9yIG1lc3NhZ2UKLQkgKiAKLQkgKiBAcGFyYW0gbWVzc2FnZQotCSAqICAgICAgICAgICAgVGhlIG1lc3NhZ2Ugb2YgdGhlIGV4Y2VwdGlvbgotCSAqIEB0aHJvd3MgSU9FeGNlcHRpb24KLQkgKi8KLQlwcm90ZWN0ZWQgdm9pZCBlcnIoU3RyaW5nIG1lc3NhZ2UpIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0JCWVycihmUG9zLCBtZXNzYWdlKTsKLQl9Ci0KLQkvKioKLQkgKiBUaHJvd3MgYW4gSU9FeGNlcHRpb24gd2l0aCB0aGUgZ2l2ZW4gbWVzc2FnZSBmb3IgdGhlIGdpdmVuIGxpbmUgcG9zaXRpb24uCi0JICogVGhlIGN1cnJlbnQgbGluZSBudW1iZXIgYW5kIHBvc2l0aW9uIChwb3MpIGFyZSBhcHBlbmRlZCB0byB0aGUgZXhjZXB0aW9uCi0JICogbWVzc2FnZQotCSAqIAotCSAqIEBwYXJhbSBwb3MKLQkgKiAgICAgICAgICAgIFRoZSBsaW5lIHBvc2l0aW9uIHRoYXQgdGhlIGVycm9yIHdpbGwgYmUgcmVwb3J0ZWQgZm9yCi0JICogQHBhcmFtIG1lc3NhZ2UKLQkgKiBAdGhyb3dzIElPRXhjZXB0aW9uCi0JICovCi0JcHJvdGVjdGVkIHZvaWQgZXJyKGludCBwb3MsIFN0cmluZyBtZXNzYWdlKSB0aHJvd3MgSU9FeGNlcHRpb24gewotCQl0aHJvdyBuZXcgSU9FeGNlcHRpb24oIltMaW5lOiAiICsgZkxpbmUgKyAiLCBQb3M6ICIgKyBwb3MgKyAiXSAgIiArIG1lc3NhZ2UpOwotCX0KLQotCS8qKgotCSAqIEluaXRpYXRlcyBwYXJzaW5nIG9mIHRoZSBYTUwgZmlsZSBnaXZlbiB0aHJvdWdoIGFJbnB1dFN0cmVhbSBvciBhUmVhZGVyCi0JICogaW4gdGhlIGdpdmVuIGNvbnN0cnVjdG9yIHdoZW4gY3JlYXRpbmcgWE1MUmVhZGVyIG9iamVjdC4KLQkgKiAKLQkgKiBAdGhyb3dzIElPRXhjZXB0aW9uCi0JICogICAgICAgICAgICAgaWYgYW4gZXJyb3Igb2NjdXJzIGR1cmluZyByZWFkaW5nIHRoZSBYTUwgZmlsZSBvciBpZiBhCi0JICogICAgICAgICAgICAgcGFyc2luZyBlcnJvciBlY2N1cnMuCi0JICovCi0JcHJvdGVjdGVkIHZvaWQgcGFyc2VYTUwoKSB0aHJvd3MgSU9FeGNlcHRpb24gewotCQlUYWdDbGFzcyByb290VGFnID0gbmV3IFRhZ0NsYXNzKCk7Ci0KLQkJdHJ5IHsKLQkJCWdldE5leHRDaGFyKCk7Ci0JCQljbGVhcldoaXRlU3BhY2VzKCk7Ci0KLQkJCWJvb2xlYW4gc3RhcnQgPSBmYWxzZTsKLQotCQkJd2hpbGUgKGFjY2VwdF9jaGFyKCc8JykpIHsKLQkJCQlzdGFydCA9IHRydWU7Ci0JCQkJaW50IHBvcyA9IGZQb3M7Ci0KLQkJCQlpZiAoZlBvcyA9PSAyICYmIGZMaW5lID09IDEpIHsKLQkJCQkJaWYgKHBhcnNlX3htbF9wcm9sb2cocm9vdFRhZykpIHsKLQkJCQkJCS8vIFN5c3RlbS5vdXQucHJpbnRsbigiWE1MIFByb2xvZyBmb3VuZC4iKTsKLQkJCQkJCS8vIFN5c3RlbS5vdXQucHJpbnRsbigiWE1MIFZlcnNpb246ICIgKyBmVmVyc2lvbiArICIsCi0JCQkJCQkvLyBlbmNvZGluZzogIiArIGZFbmNvZGluZyk7Ci0JCQkJCQlzZXRFbmNvZGluZyhmRW5jb2RpbmcpOwotCQkJCQkJY2xlYXJXaGl0ZVNwYWNlcygpOwotCQkJCQkJY29udGludWU7Ci0JCQkJCX0KLQkJCQl9IGVsc2UgewotCQkJCQlzZXRFbmNvZGluZyhmRGVmYXVsdEVuY29kaW5nKTsKLQkJCQl9Ci0KLQkJCQlpZiAoIXBhcnNlX3RhZ19zcGVjaWFsKHJvb3RUYWcpKSB7Ci0JCQkJCWlmIChwYXJzZV90YWdfbm9ybWFsKHJvb3RUYWcpKSB7Ci0JCQkJCQkvLyBUT0RPIGRhIHNlIHByb3ZlcmkgZGFsaSBlIGRvc3RpZ25hdCBrcmFqYSBuYSBmaWxlLWEsCi0JCQkJCQkvLyBha28gbmUgZSAtCi0JCQkJCQkvLyB0b2dhdmEgb3QgdHVrIG5hdGF0dWsgbW9qZSBkYSBpbWEgc2FtbyBrb21lbnRhcmkuCi0JCQkJCQlyZXR1cm47Ci0JCQkJCX0KLQkJCQkJZXJyKHBvcywgRVJSX1RBR05BTUUyX0VYUEVDVEVEKTsKLQkJCQl9Ci0KLQkJCQljbGVhcldoaXRlU3BhY2VzKCk7Ci0JCQl9Ci0KLQkJCWlmICghc3RhcnQpIHsKLQkJCQllcnIoRVJSX0xUX0VYUEVDVEVEKTsKLQkJCX0KLQkJfSBjYXRjaCAoSU9FeGNlcHRpb24gaW9lKSB7Ci0JCQlpZiAoZkRlYnVnKSB7Ci0JCQkJaW9lLnByaW50U3RhY2tUcmFjZShTeXN0ZW0uZXJyKTsKLQkJCX0KLQotCQkJdGhyb3cgaW9lOwotCQl9Ci0JfQotCi0JLyoqCi0JICogUGFyc2VzIGEgWE1MIGZpbGUgZ2l2ZW4gdGhyb3VnaCBhSW5wdXRTdHJlYW0gYW5kIGR1cmluZyB0aGUgcGFyc2luZwotCSAqIG5vdGlmaWVzIGFMaXN0ZW5lciBmb3IgY2xvc2UtdGFnIGV2ZW50cyA8YnI+Ci0JICogPGJyPgotCSAqIDxiPk5vdGU6IFRoZSBYTUxSZWFkZXIgZG9lcyBub3QgY2xvc2UgdGhlIHBhc3NlZCBSZWFkZXIgb3IgSW5wdXRTdHJlYW0KLQkgKiAKLQkgKiBAcGFyYW0gYUlucHV0U3RyZWFtCi0JICogICAgICAgICAgICBhbiBJbnB1dFN0cmVhbSB0byByZWFkIHRoZSBYTUwgZmlsZSBmcm9tCi0JICogQHBhcmFtIGFMaXN0ZW5lcgotCSAqICAgICAgICAgICAgVGFnTGlzdGVuZXIgdGhhdCB3aWxsIGJlIG5vdGlmaWVkIG9uIGNsb3NlLXRhZyBldmVudAotCSAqIEBwYXJhbSBhTGV2ZWwKLQkgKiAgICAgICAgICAgIHNlZSBwYXJzZVhNTChSZWFkZXIgYVJlYWRlciwgVGFnTGlzdGVuZXIgYUxpc3RlbmVyLCBpbnQgYUxldmVsCi0JICogICAgICAgICAgICBkZXNjcmlwdGlvbgotCSAqIEB0aHJvd3MgSU9FeGNlcHRpb24KLQkgKiAgICAgICAgICAgICBpZiBzb21lIElPIGVycm9yIG9jY3VycyB3aGVuIHJlYWRpbmcgdGhlIFhNTCBmaWxlIG9yIGlmIGEKLQkgKiAgICAgICAgICAgICBwYXJzZXIgZXJyb3Igb2NjdXJzLgotCSAqLwotCXB1YmxpYyBzdGF0aWMgdm9pZCBwYXJzZVhNTChJbnB1dFN0cmVhbSBhSW5wdXRTdHJlYW0sIFRhZ0xpc3RlbmVyIGFMaXN0ZW5lciwgaW50IGFMZXZlbCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKLQkJWE1MUmVhZGVyIHhtbCA9IG5ldyBYTUxSZWFkZXIoYUlucHV0U3RyZWFtLCBhTGlzdGVuZXIpOwotCQl4bWwuc2V0TGV2ZWwoYUxldmVsKTsKLQkJeG1sLnBhcnNlWE1MKCk7Ci0JfQotCi0JLyoqCi0JICogUGFyc2VzIGEgWE1MIGZpbGUgZ2l2ZW4gdGhyb3VnaCBhUmVhZGVyIGFuZCBkdXJpbmcgdGhlIHBhcnNpbmcgbm90aWZpZXMKLQkgKiBhTGlzdGVuZXIgZm9yIGNsb3NlLXRhZyBldmVudHMgPGJyPgotCSAqIDxicj4KLQkgKiA8Yj5Ob3RlOiBUaGUgWE1MUmVhZGVyIGRvZXMgbm90IGNsb3NlIHRoZSBwYXNzZWQgUmVhZGVyIG9yIElucHV0U3RyZWFtCi0JICogCi0JICogQHBhcmFtIGFSZWFkZXIKLQkgKiAgICAgICAgICAgIGEgcmVhZGVyIHRoYXQgd2lsbCBiZSB1c2VkIHRvIHJlYWQgdGhlIFhNTCBmaWxlIGZyb20KLQkgKiBAcGFyYW0gYUxpc3RlbmVyCi0JICogICAgICAgICAgICBUYWdMaXN0ZW5lciB0aGF0IHdpbGwgYmUgbm90aWZpZWQgb24gY2xvc2UtdGFnIGV2ZW50Ci0JICogQHBhcmFtIGFMZXZlbAotCSAqICAgICAgICAgICAgaW5kaWNhdGVzIHRoZSB0YWcgbGV2ZWwgdGhhdCB0aGUgbGlzdGVuZXIgd2lsbCBiZSBpbnZva2VkIGZvci4KLQkgKiAgICAgICAgICAgIEZvciBleGFtcGxlIGlmIHRoZSBYTUwgaXM6PGJyPgotCSAqIAotCSAqIDxwcmU+Ci0JICogICZsdDthJmd0OwotCSAqICAgICZsdDtiJmd0OwotCSAqICAgICAgJmx0O2MgLyZndDsKLQkgKiAgICAmbHQ7L2ImZ3Q7Ci0JICogICZsdDsvYSZndDsKLQkgKiA8L3ByZT4KLQkgKiAKLQkgKiA8YnI+Ci0JICogICAgICAgICAgICBhbmQgdGhlIHBhc3NlZCBhTGV2ZWwgaXMgMiB0aGVuIHRoZSBsaXN0ZW5lciB3aWxsIGJlIGludm9rZWQKLQkgKiAgICAgICAgICAgIG9ubHkgZm9yIHRhZ3MgdGhhdCBoYXZlIGxldmVsIDIsIGkuZS4gaW4gb3VyIGV4YW1wbGUgdGhlCi0JICogICAgICAgICAgICBsaXN0ZW5lciB3aWxsIGJlIGludm9rZWQgb25seSBmb3IgdGFnICZsdDtiJmd0Ozxicj4KLQkgKiAgICAgICAgICAgIDx1bD4KLQkgKiAgICAgICAgICAgIDxsaT5WYWx1ZSBsZXNzIHRoYW4gMCBpbmRpY2F0ZXMgJnF1b3Q7aW52b2tlIGxpc3RlbmVyIGZvciBhbGwKLQkgKiAgICAgICAgICAgIHRhZ3Mgbm8gbWF0dGVyIHdoYXQgYXJlIHRoZWlyIGxldmVscyZxdW90OzwvbGk+Ci0JICogICAgICAgICAgICA8bGk+VmFsdWUgb2YgMCBpbmRpY2F0ZXMgdGhhdCB0aGUgbGlzdGVuZXIgbXVzdCBub3QgYmUKLQkgKiAgICAgICAgICAgIGludm9rZWQgaW4gZ2VuZXJhbCBubyBtYXR0ZXIgd2hhdCBpcyB0aGUgdGFnIGxldmVsPC9saT4KLQkgKiAgICAgICAgICAgIDxsaT5WYWx1ZSBncmVhdGVyIHRoYW4gMCBpbmRpY2F0ZXMgdGhlIHRhZyBsZXZlbCB0aGF0IHRoZQotCSAqICAgICAgICAgICAgbGlzdGVuZXIgd2lsbCBiZSBpbnZva2VkIGZvcjwvbGk+Ci0JICogQHRocm93cyBJT0V4Y2VwdGlvbgotCSAqICAgICAgICAgICAgIGlmIHNvbWUgSU8gZXJyb3Igb2NjdXJzIHdoZW4gcmVhZGluZyB0aGUgWE1MIGZpbGUgb3IgaWYgYQotCSAqICAgICAgICAgICAgIHBhcnNlciBlcnJvciBvY2N1cnMuCi0JICovCi0JcHVibGljIHN0YXRpYyB2b2lkIHBhcnNlWE1MKFJlYWRlciBhUmVhZGVyLCBUYWdMaXN0ZW5lciBhTGlzdGVuZXIsIGludCBhTGV2ZWwpIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0JCVhNTFJlYWRlciB4bWwgPSBuZXcgWE1MUmVhZGVyKGFSZWFkZXIsIGFMaXN0ZW5lcik7Ci0JCXhtbC5zZXRMZXZlbChhTGV2ZWwpOwotCQl4bWwucGFyc2VYTUwoKTsKLQl9Ci0KLQkvKioKLQkgKiBSZXR1cm5zIHRoZSBYTUwgdmVyc2lvbiBhdHRyaWJ1dGUKLQkgKiAKLQkgKiBAcmV0dXJuIHRoZSBYTUwgZmlsZSB2ZXJzaW9uIGF0dHJpYnV0ZQotCSAqLwotCXB1YmxpYyBTdHJpbmcgZ2V0VmVyc2lvbigpIHsKLQkJcmV0dXJuIGZWZXJzaW9uOwotCX0KLQotCS8qKgotCSAqIFJldHVybnMgdGhlIFhNTCBlbmNvZGluZyBhdHRyaWJ1dGUKLQkgKiAKLQkgKiBAcmV0dXJuIHRoZSBYTUwgZW5jb2RpbmcgYXR0cmlidXRlCi0JICovCi0JcHVibGljIFN0cmluZyBnZXRFbmNvZGluZygpIHsKLQkJcmV0dXJuIGZFbmNvZGluZzsKLQl9Ci0KLQkvKioKLQkgKiBSZXR1cm5zIHRoZSB2YWx1ZSBvZiBYTUwgc3RhbmRhbG9uZSBhdHRyaWJ1dGUKLQkgKiAKLQkgKiBAcmV0dXJuIHRoZSB2YWx1ZSBvZiBYTUwgc3RhbmRhbG9uZSBhdHRyaWJ1dGUKLQkgKi8KLQlwdWJsaWMgU3RyaW5nIGdldFN0YW5kYWxvbmUoKSB7Ci0JCXJldHVybiBmU3RhbmRhbG9uZTsKLQl9Ci19CmRpZmYgLS1naXQgYS9idW5kbGVzL29yZy5lY2xpcHNlLmVxdWlub3guZHMvc3JjL29yZy9lY2xpcHNlL2VxdWlub3gvaW50ZXJuYWwvdXRpbC94bWwvWE1MVXRpbC5qYXZhIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5lcXVpbm94LmRzL3NyYy9vcmcvZWNsaXBzZS9lcXVpbm94L2ludGVybmFsL3V0aWwveG1sL1hNTFV0aWwuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMzBmOWEzOS4uMDAwMDAwMAotLS0gYS9idW5kbGVzL29yZy5lY2xpcHNlLmVxdWlub3guZHMvc3JjL29yZy9lY2xpcHNlL2VxdWlub3gvaW50ZXJuYWwvdXRpbC94bWwvWE1MVXRpbC5qYXZhCisrKyAvZGV2L251bGwKQEAgLTEsMzYzICswLDAgQEAKLS8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMDggYnkgUHJvU3lzdCBTb2Z0d2FyZSBHbWJICi0gKiBodHRwOi8vd3d3LnByb3N5c3QuY29tCi0gKiBBbGwgcmlnaHRzIHJlc2VydmVkLiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzCi0gKiBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYxLjAKLSAqIHdoaWNoIGFjY29tcGFuaWVzIHRoaXMgZGlzdHJpYnV0aW9uLCBhbmQgaXMgYXZhaWxhYmxlIGF0Ci0gKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC12MTAuaHRtbAotICoKLSAqIENvbnRyaWJ1dG9yczoKLSAqICAgIFByb1N5c3QgU29mdHdhcmUgR21iSCAtIGluaXRpYWwgQVBJIGFuZCBpbXBsZW1lbnRhdGlvbgotICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi1wYWNrYWdlIG9yZy5lY2xpcHNlLmVxdWlub3guaW50ZXJuYWwudXRpbC54bWw7Ci0KLWltcG9ydCBqYXZhLnV0aWwuVmVjdG9yOwotCi1pbXBvcnQgb3JnLmVjbGlwc2UuZXF1aW5veC5pbnRlcm5hbC51dGlsLnN0cmluZy5DaGFyQnVmZmVyOwotCi0vKioKLSAqICBDbGFzcyB3aXRoIHV0aWxpdHkgbWV0aG9kcyBmb3IgZXh0cmFjdGluZyBhdHRyaWJ1dGVzIGZyb20geG1sIHRhZ3MKLSAqICAKLSAqIEBhdXRob3IgUGF2bGluIERvYnJldgotICogQHZlcnNpb24gMS4wCi0gKi8KLQotcHVibGljIGNsYXNzIFhNTFV0aWwgewotCi0JLyoqCi0JICogQ29kZWQgY2hhcnMgcGxhY2VkIGluIHRoZSB4bWwgY29udGVudC4KLQkgKi8KLQlwdWJsaWMgc3RhdGljIFN0cmluZ1tdIGNvZGVkID0geyImYW1wOyIsICImbmJzcDsiLCAiJmNybGY7IiwgIiZ0YWI7IiwgIiZsdDsiLCAiJmd0OyIsICImcXVvdDsiLCAiJmFwb3M7In07Ci0KLQkvKioKLQkgKiBDb3JyZXNwb25kaW5nIGRlY29kZWQgY2hhcnMuIEZpcnN0IGZpdmUgb2YgdGhlbSBjYW5ub3QgZXhpc3QgaW4gcGxhaW4KLQkgKiAoZGVjb2RlZCkgZm9ybSBpbiB0aGUgeG1sIGNvbnRlbnQsIGJ1dCB0aGUgcmVzdCBjYW4gYmUgZWlnaHRlciBjb2RlZCBvcgotCSAqIGRlY29kZWQKLQkgKi8KLQlwdWJsaWMgc3RhdGljIFN0cmluZ1tdIGRlY29kZWQgPSB7IiYiLCAiICIsICJcbiIsICJcdCIsICI8IiwgIj4iLCAiXCIiLCAiJyJ9OwotCi0JLyoqCi0JICogUmVwbGFjZXMgc3BlY2lmaWVkIHN0cmluZ3MgaW4gYSBzb3VyY2Ugc3RyaW5nIHdpdGggY29ycmVzcG9uZGluZyBzdHJpbmdzCi0JICogCi0JICogQHBhcmFtIHN0cgotCSAqICAgICAgICAgICAgc291cmNlIHN0cmluZwotCSAqIEBwYXJhbSB0b0JlUmVwbGFjZWQKLQkgKiAgICAgICAgICAgIGFycmF5IG9mIHN0cmluZ3Mgd2hpY2ggd2lsbCBiZSByZXBsYWNlZCB3aXRoIHRoZSBuZXh0Ci0JICogICAgICAgICAgICBwYXJhbWV0ZXIKLQkgKiBAcGFyYW0gcmVwbGFjZVdpdGgKLQkgKiAgICAgICAgICAgIGFycmF5IG9mIHRoZSBzdHJpbmdzIGNvcnJlc3BvbmRpbmcgdG8gInRvQmVSZXBsYWNlZCIKLQkgKiAgICAgICAgICAgIHBhcmFtZXRlci4gdGhlIGxlbmd0aCBzaG91bGQgYmUgZXF1YWwKLQkgKiBAcGFyYW0gbGVuZ3RoCi0JICogICAgICAgICAgICBzcGVjaWZ5IGhvdyBtYW55IHBhcmFtZXRlcnMgb2YgdGhlIHN0cmluZyBhcnJheSB3aWxsIGJlCi0JICogICAgICAgICAgICByZXBsYWNlZCwgdGhlIHJlc3Qgb2YgInRvQmVSZXBsYWNlZCIgcGFyYW1ldGVyIHdpbGwgbm90LgotCSAqIEByZXR1cm4gcmVwbGFjZWQgc3RyaW5nCi0JICovCi0JcHVibGljIHN0YXRpYyBTdHJpbmcgcmVwbGFjZUNoYXJzKFN0cmluZyBzdHIsIFN0cmluZ1tdIHRvQmVSZXBsYWNlZCwgU3RyaW5nW10gcmVwbGFjZVdpdGgsIGludCBsZW5ndGgpIHsKLQotCQkvKgotCQkgKiBmaXJzdCA1IGNoYXJhY3RlcnMgYXJlIG5vdCBhbGxvd2VkIHRvIGV4aXN0cyBpbiBzdWNoIGZvcm0gaW4geG1sLCB0aGUKLQkJICogcmVzdCByZW1haW5zIHRoZSBzYW1lCi0JCSAqLwotCQlDaGFyQnVmZmVyIHN0ckJ1ZjsKLQkJZm9yIChpbnQgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykgewotCQkJc3RyQnVmID0gbmV3IENoYXJCdWZmZXIoKTsKLQkJCXJlcGxhY2Uoc3RyLCB0b0JlUmVwbGFjZWRbaV0sIHJlcGxhY2VXaXRoW2ldLCBzdHJCdWYpOwotCQkJc3RyID0gc3RyQnVmLnRvU3RyaW5nKCk7Ci0JCX0KLQkJcmV0dXJuIHN0cjsKLQl9Ci0KLQkvKioKLQkgKiBSZXBsYWNlcyBhIHNwZWNpZmllZCBzdHJpbmcgaW4gYSBzb3VyY2Ugc3RyaW5nIHdpdGggYSBjb3JyZXNwb25kaW5nCi0JICogc3RyaW5nIGFuZCBhZGRzIHRoZSByZXN1bHQgaW4gYSBidWZmZXIuCi0JICogCi0JICogQHBhcmFtIHNyYwotCSAqICAgICAgICAgICAgc291cmNlIHN0cmluZwotCSAqIEBwYXJhbSB0b0JlUmVwbGFjZWQKLQkgKiAgICAgICAgICAgIHN0cmluZyB3aGljaCB3aWxsIGJlIHJlcGxhY2VkIHdpdGggdGhlIG5leHQgcGFyYW1ldGVyCi0JICogQHBhcmFtIHRvUmVwbGFjZVdpdGgKLQkgKiAgICAgICAgICAgIHRoZSBzdHJpbmcgY29ycmVzcG9uZGluZyB0byAidG9CZVJlcGxhY2VkIiBwYXJhbWV0ZXIuCi0JICogQHBhcmFtIHN0ckJ1ZgotCSAqICAgICAgICAgICAgaGVyZSBpcyBhZGRlZCB0aGUgcmVwbGFjZWQgc291cmNlIHN0cmluZy4KLQkgKi8KLQlwdWJsaWMgc3RhdGljIHZvaWQgcmVwbGFjZShTdHJpbmcgc3JjLCBTdHJpbmcgdG9CZVJlcGxhY2VkLCBTdHJpbmcgdG9SZXBsYWNlV2l0aCwgQ2hhckJ1ZmZlciBzdHJCdWYpIHsKLQotCQlpbnQgajsKLQkJaW50IHBvcyA9IDA7Ci0JCWludCBsZW5ndGggPSB0b0JlUmVwbGFjZWQubGVuZ3RoKCk7Ci0JCXdoaWxlICgoKGogPSBzcmMuaW5kZXhPZih0b0JlUmVwbGFjZWQsIHBvcykpID4gLTEpKSB7Ci0JCQlzdHJCdWYuYXBwZW5kKHNyYy5zdWJzdHJpbmcocG9zLCBqKSk7Ci0JCQlzdHJCdWYuYXBwZW5kKHRvUmVwbGFjZVdpdGgpOwotCQkJcG9zID0gaiArIGxlbmd0aDsKLQkJfQotCQlzdHJCdWYuYXBwZW5kKHNyYy5zdWJzdHJpbmcocG9zKSk7Ci0JfQotCi0JLyoqCi0JICogQ29udmVydHMgc3BlY2lhbCB4bWwgY2hhcnMgdG8gdmFsaWQgc3RyaW5nIGUuZy4gIiZhbXA7bHQ7IiBiZWNvbWVzICI8IgotCSAqIGFuZCAiJmFtcDtndDsiIGJlY29tZXMgIj4iCi0JICogCi0JICogQHBhcmFtIHNyYwotCSAqICAgICAgICAgICAgc291cmNlIHN0cmluZyB3aGljaCBpcyBjb2RlZAotCSAqIEByZXR1cm4gZGVjb2RlZCBzdHJpbmcKLQkgKi8KLQlwdWJsaWMgc3RhdGljIFN0cmluZyBnZXREZWNvZGVkKFN0cmluZyBzcmMpIHsKLQkJaW50IGJlZ2luID0gc3JjLmluZGV4T2YoJyYnKTsKLQkJaWYgKGJlZ2luID09IC0xKSB7Ci0JCQkvKgotCQkJICogaW1wcm92ZSBzcGVlZCB3aGVuIHRoZXJlIGlzIG5vdCBhbnkgY29kZWQgc3RyaW5nIChlYWNoIGNvZGVkCi0JCQkgKiBzdHJpbmcgYmVnaW5zIHdpdGggJyYnKQotCQkJICovCi0JCQlyZXR1cm4gc3JjOwotCQl9Ci0JCWludCBlbmQgPSBzcmMuaW5kZXhPZignOycsIGJlZ2luKTsKLQkJaWYgKGVuZCA9PSAtMSkgewotCQkJLyoKLQkJCSAqIGltcHJvdmUgc3BlZWQgd2hlbiB0aGVyZSBpcyBub3QgYW55IGNvZGVkIHN0cmluZyAoZWFjaCBjb2RlZAotCQkJICogc3RyaW5nIGVuZHMgd2l0aCAnOycpCi0JCQkgKi8KLQkJCXJldHVybiBzcmM7Ci0JCX0KLQkJaW50IGxhc3RCZWdpbiA9IDA7Ci0JCUNoYXJCdWZmZXIgc3RyQnVmID0gbmV3IENoYXJCdWZmZXIoKTsKLQkJd2hpbGUgKGJlZ2luICE9IC0xKSB7Ci0JCQllbmQgPSBzcmMuaW5kZXhPZignOycsIGJlZ2luKTsgLyoKLQkJCQkJCQkJCQkJCQkgKiB0aGlzIGlzIHVzZWQgb24gdGhlIHNlY29uZCB0dXJuCi0JCQkJCQkJCQkJCQkJICogb2YgdGhlIGN5Y2xlCi0JCQkJCQkJCQkJCQkJICovCi0JCQlpZiAoZW5kID09IC0xKSB7Ci0JCQkJc3RyQnVmLmFwcGVuZChzcmMuc3Vic3RyaW5nKGJlZ2luKSk7Ci0JCQkJcmV0dXJuIHN0ckJ1Zi50b1N0cmluZygpOwotCQkJfQotCQkJc3RyQnVmLmFwcGVuZChzcmMuc3Vic3RyaW5nKGxhc3RCZWdpbiwgYmVnaW4pKTsKLQkJCVN0cmluZyBwYXJ0ID0gc3JjLnN1YnN0cmluZyhiZWdpbiwgZW5kICsgMSk7Ci0JCQlib29sZWFuIGZvdW5kID0gZmFsc2U7Ci0JCQlmb3IgKGludCBpID0gMDsgaSA8IGRlY29kZWQubGVuZ3RoOyBpKyspIHsKLQkJCQlpZiAocGFydC5lcXVhbHMoY29kZWRbaV0pKSB7Ci0JCQkJCXN0ckJ1Zi5hcHBlbmQoZGVjb2RlZFtpXSk7Ci0JCQkJCWJlZ2luICs9IHBhcnQubGVuZ3RoKCk7Ci0JCQkJCWxhc3RCZWdpbiA9IGJlZ2luOwotCQkJCQliZWdpbiA9IHNyYy5pbmRleE9mKCcmJywgbGFzdEJlZ2luKTsKLQkJCQkJZm91bmQgPSB0cnVlOwotCQkJCQlicmVhazsgLyoKLQkJCQkJCQkJCQkJICogb25lIHdvcmQgcmVwbGFjZWQsIGdvIG9uIHNlYXJjaGluZyB3aXRoIHJlc3Qgb2YKLQkJCQkJCQkJCQkJICogdGhlIHNyYwotCQkJCQkJCQkJCQkgKi8KLQkJCQl9Ci0JCQl9Ci0JCQlpZiAoIWZvdW5kKSB7Ci0JCQkJc3RyQnVmLmFwcGVuZChwYXJ0KTsKLQkJCQliZWdpbiArPSBwYXJ0Lmxlbmd0aCgpOwotCQkJCWxhc3RCZWdpbiA9IGJlZ2luOwotCQkJCWJlZ2luID0gc3JjLmluZGV4T2YoJyYnLCBiZWdpbik7Ci0JCQl9Ci0JCX0KLQkJc3RyQnVmLmFwcGVuZChzcmMuc3Vic3RyaW5nKGxhc3RCZWdpbikpOwotCQlyZXR1cm4gc3RyQnVmLnRvU3RyaW5nKCkuaW50ZXJuKCk7Ci0JfQotCi0JLyoqCi0JICogRXh0cmFjdHMgdGhlIG5hbWUgb2YgdGhlIHRhZywgZnJvbSBzdHJpbmcgY29udGFpbmluZyB0aGUgbmFtZSBhbmQKLQkgKiBhdHRyaWJ1dGVzCi0JICogCi0JICogQHBhcmFtIHRhZ0FuZEF0dHJpYnV0ZXMKLQkgKiAgICAgICAgICAgIHN0cmluZyBjb250YWluaW5nIHRoZSBuYW1lIGFuZCBhdHRyaWJ1dGVzCi0JICogQHJldHVybiB0YWcgbmFtZSBzdHJpbmcgc2VwYXJhdGVkIGJ5IHNwYWNlIGZyb20gdGhlIHRhZyBhdHRyaWJ1dGVzCi0JICogQGRlcHJlY2F0ZWQgdXNlIFRhZ0NsYXNzLmdldE5hbWUoKSBpbnN0ZWFkCi0JICovCi0JcHVibGljIHN0YXRpYyBTdHJpbmcgZ2V0VGFnTmFtZShTdHJpbmcgdGFnQW5kQXR0cmlidXRlcykgewotCQlpbnQgbmFtZUluZGV4ID0gdGFnQW5kQXR0cmlidXRlcy5pbmRleE9mKCcgJyk7Ci0JCWlmIChuYW1lSW5kZXggIT0gLTEpIHsKLQkJCWludCB0YWJJbmRleCA9IHRhZ0FuZEF0dHJpYnV0ZXMuaW5kZXhPZignXHQnKTsKLQkJCWlmICh0YWJJbmRleCA+IC0xICYmIHRhYkluZGV4IDwgbmFtZUluZGV4KSB7Ci0JCQkJcmV0dXJuIHRhZ0FuZEF0dHJpYnV0ZXMuc3Vic3RyaW5nKDAsIHRhYkluZGV4KTsKLQkJCX0KLQkJCXJldHVybiB0YWdBbmRBdHRyaWJ1dGVzLnN1YnN0cmluZygwLCBuYW1lSW5kZXgpOwotCQl9Ci0KLQkJbmFtZUluZGV4ID0gdGFnQW5kQXR0cmlidXRlcy5pbmRleE9mKCcvJyk7Ci0JCWlmIChuYW1lSW5kZXggIT0gLTEpIHsKLQkJCXJldHVybiB0YWdBbmRBdHRyaWJ1dGVzLnN1YnN0cmluZygwLCBuYW1lSW5kZXgpOwotCQl9Ci0JCXJldHVybiB0YWdBbmRBdHRyaWJ1dGVzOwotCX0KLQotCXB1YmxpYyBzdGF0aWMgYm9vbGVhbiBpc0VtcHR5VGFnKFN0cmluZyB0YWdOYW1lKSB7Ci0JCXJldHVybiAnLycgPT0gdGFnTmFtZS5jaGFyQXQodGFnTmFtZS5sZW5ndGgoKSAtIDEpOwotCX0KLQotCS8qKgotCSAqIENoZWNrcyB3aGV0aGVyIHRoZSB0YWcgbmFtZSBzdHJpbmcgYmV0d2VlbiAmbHQ7IGFuZCAmZ3Q7LCBlbmRzIHdpdGggIi8iLgotCSAqIAotCSAqIEBwYXJhbSB0YWdOYW1lCi0JICogICAgICAgICAgICBzdHJpbmcgYmV0d2VlbiAmbHQ7IGFuZCAmZ3Q7IGNoYXJzCi0JICogQHJldHVybiB0cnVlIGlmIGFuZCBvbmx5IGlmIHN0cmluZyBlbmRzIHdpdGggIi8iCi0JICovCi0KLQlwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIFN0cmluZ1tdIGZfZW50aXRpZXMgPSB7ImFtcCIsICJuYnNwIiwgImNybGYiLCAidGFiIiwgImx0IiwgImd0IiwgInF1b3QiLCAiYXBvcyJ9OwotCXByb3RlY3RlZCBzdGF0aWMgZmluYWwgY2hhcltdIGZfZW50X2NoYXJzID0geycmJywgJyAnLCAnXG4nLCAnXHQnLCAnPCcsICc+JywgJyInLCAnXCcnfTsKLQotCXByaXZhdGUgc3RhdGljIGJvb2xlYW4gc3Vic3RpdHV0ZUVudGl0eShTdHJpbmcgZW50LCBDaGFyQnVmZmVyIGNiKSB7Ci0JCWZvciAoaW50IGogPSAwOyBqIDwgZl9lbnRpdGllcy5sZW5ndGg7IGorKykgewotCQkJaWYgKGZfZW50aXRpZXNbal0uZXF1YWxzKGVudCkpIHsKLQkJCQljYi5hcHBlbmQoZl9lbnRfY2hhcnNbal0pOwotCQkJCXJldHVybiB0cnVlOwotCQkJfQotCQl9Ci0JCXJldHVybiBmYWxzZTsKLQl9Ci0KLQkvKioKLQkgKiBFeHRyYWN0cyBhbiBhdHRyaWJ1dGUgdmFsdWUgZm9yIGEgc3BlY2lmaWVkIGF0dHJpYnV0ZSBuYW1lIGZyb20gdGFnCi0JICogc3RyaW5nLgotCSAqIAotCSAqIEBwYXJhbSB0YWcKLQkgKiAgICAgICAgICAgIHdob2xlIHRhZyBuYW1lCi0JICogQHBhcmFtIGF0dAotCSAqICAgICAgICAgICAgYXR0cmlidXRlIG5hbWUKLQkgKiBAcmV0dXJuIHZhbHVlIG9mIHRoZSBhdHRyaWJ1dGUgaWYgZXhpc3RzIG90aGVyd2lzZSByZXR1cm4gbnVsbAotCSAqIEBkZXByZWNhdGVkIHVzZSBUYWdDbGFzcy5nZXRBdHRyTGlzdCgpIGFuZCBUYWdDbGFzcy5nZXRBdHRyaWJ1dGUoU3RyaW5nCi0JICogICAgICAgICAgICAgYXR0cikgaW5zdGVhZAotCSAqLwotCXB1YmxpYyBzdGF0aWMgU3RyaW5nIGdldEF0dHJpYnV0ZVZhbHVlKFN0cmluZyB0YWcsIFN0cmluZyBhdHQsIGludCBiZWdpbikgewotCQlpZiAoYXR0Lmxlbmd0aCgpID09IDApCi0JCQlyZXR1cm4gbnVsbDsKLQotCQlpbnQgc3RhcnQgPSAwOwotCQl3aGlsZSAoc3RhcnQgPj0gMCkgewotCQkJc3RhcnQgPSB0YWcuaW5kZXhPZihhdHQsIHN0YXJ0KTsKLQotCQkJaWYgKHN0YXJ0ID49IDApIHsKLQkJCQkvLyBDaGVja3MgaWYgbGVhZGluZyBhbmQgdHJhaWxpbmcgY2hhcnMgYXJlIHZhbGlkIGF0dHJfbmFtZQotCQkJCS8vIGNoYXJzCi0JCQkJYm9vbGVhbiBiMSA9IChzdGFydCA+IDApID8gWE1MUmVhZGVyLmlzTmFtZUNoYXIodGFnLmNoYXJBdChzdGFydCAtIDEpKSA6IHRydWU7Ci0JCQkJYm9vbGVhbiBiMiA9ICgoc3RhcnQgKyBhdHQubGVuZ3RoKCkgKyAxKSA8IHRhZy5sZW5ndGgoKSkgPyBYTUxSZWFkZXIuaXNOYW1lQ2hhcih0YWcuY2hhckF0KHN0YXJ0ICsgYXR0Lmxlbmd0aCgpKSkgOiB0cnVlOwotCi0JCQkJc3RhcnQgKz0gYXR0Lmxlbmd0aCgpOwotCQkJCWlmICghYjEgJiYgIWIyKSB7Ci0JCQkJCXN0YXJ0ID0gdGFnLmluZGV4T2YoJz0nLCBzdGFydCkgKyAxOwotCQkJCQlpZiAoc3RhcnQgPD0gMCkKLQkJCQkJCXJldHVybiBudWxsOwotCi0JCQkJCXdoaWxlIChzdGFydCA8IHRhZy5sZW5ndGgoKSAmJiBDaGFyYWN0ZXIuaXNXaGl0ZXNwYWNlKHRhZy5jaGFyQXQoc3RhcnQpKSkgewotCQkJCQkJc3RhcnQrKzsKLQkJCQkJfQotCi0JCQkJCWNoYXIgcXVvdCA9IHRhZy5jaGFyQXQoc3RhcnQpOwotCQkJCQlpbnQgZW5kID0gdGFnLmluZGV4T2YocXVvdCwgc3RhcnQgKyAxKTsKLQkJCQkJaWYgKChzdGFydCAhPSAtMSkgJiYgKGVuZCA+IHN0YXJ0KSkgewotCQkJCQkJaW50IHBvcyA9IHRhZy5pbmRleE9mKCcmJywgc3RhcnQgKyAxKTsKLQkJCQkJCWlmIChwb3MgPCAwIHx8IHBvcyA+IGVuZCkKLQkJCQkJCQlyZXR1cm4gdGFnLnN1YnN0cmluZyhzdGFydCArIDEsIGVuZCkuaW50ZXJuKCk7Ci0KLQkJCQkJCUNoYXJCdWZmZXIgY2IgPSBuZXcgQ2hhckJ1ZmZlcigpOwotCi0JCQkJCQljaGFyIGNoOwotCQkJCQkJZm9yIChpbnQgaSA9IChzdGFydCArIDEpOyBpIDwgZW5kOyBpKyspIHsKLQkJCQkJCQljaCA9IHRhZy5jaGFyQXQoaSk7Ci0JCQkJCQkJaWYgKGNoID09ICcmJykgewotCQkJCQkJCQlwb3MgPSB0YWcuaW5kZXhPZignOycsIGkpOwotCQkJCQkJCQlTdHJpbmcgZW50ID0gdGFnLnN1YnN0cmluZyhpICsgMSwgcG9zKTsKLQotCQkJCQkJCQlpZiAoc3Vic3RpdHV0ZUVudGl0eShlbnQsIGNiKSkgewotCQkJCQkJCQkJaSA9IHBvczsKLQkJCQkJCQkJCWNvbnRpbnVlOwotCQkJCQkJCQl9Ci0KLQkJCQkJCQkJY2IuYXBwZW5kKCcmJyk7Ci0JCQkJCQkJCWNiLmFwcGVuZChlbnQpOwotCQkJCQkJCQljYi5hcHBlbmQoJzsnKTsKLQkJCQkJCQkJaSA9IHBvczsKLQkJCQkJCQkJY29udGludWU7Ci0JCQkJCQkJfQotCQkJCQkJCWNiLmFwcGVuZChjaCk7Ci0JCQkJCQl9Ci0KLQkJCQkJCXJldHVybiBjYi50b1N0cmluZygpLmludGVybigpOwotCQkJCQl9Ci0JCQkJCXN0YXJ0ID0gZW5kOwotCQkJCX0KLQkJCX0KLQkJfQotCQlyZXR1cm4gbnVsbDsKLQl9Ci0KLQkvKioKLQkgKiBFeHRyYWN0cyBhdHRyaWJ1dGUgbmFtZXMgZnJvbSB0YWcgc3RyaW5nLgotCSAqIAotCSAqIEBwYXJhbSB0YWcKLQkgKiAgICAgICAgICAgIHdob2xlIHRhZyBuYW1lCi0JICogQHJldHVybiBBIHZlY3RvciB3aXRoIGFsbCBhdHRyaWJ1dGUgbmFtZXMKLQkgKiBAZGVwcmVjYXRlZCB1c2UgVGFnQ2xhc3MuZ2V0QXR0ckxpc3QoKSBpbnN0ZWFkCi0JICovCi0JcHVibGljIHN0YXRpYyBWZWN0b3IgZ2V0QXR0cmlidXRlTmFtZXMoU3RyaW5nIHRhZykgewotCQlWZWN0b3IgbmFtZXMgPSBuZXcgVmVjdG9yKCk7Ci0JCWludCBzdGFydCA9IHRhZy5pbmRleE9mKCcgJyk7IC8qIGF2b2lkIG5hbWUgb2YgdGhpcyB0YWcgKi8KLQkJaW50IGVuZDsKLQkJd2hpbGUgKHN0YXJ0ICE9IC0xKSB7Ci0JCQllbmQgPSB0YWcuaW5kZXhPZignPScsIHN0YXJ0ICsgMSk7Ci0JCQlpZiAoZW5kID09IC0xKSB7Ci0JCQkJYnJlYWs7Ci0JCQl9Ci0JCQluYW1lcy5hZGRFbGVtZW50KHRhZy5zdWJzdHJpbmcoc3RhcnQgKyAxLCBlbmQpKTsKLQkJCXN0YXJ0ID0gdGFnLmluZGV4T2YoJyInLCBlbmQgKyAxKTsKLQkJCWlmIChzdGFydCA9PSAtMSkgewotCQkJCWJyZWFrOwotCQkJfQotCQkJc3RhcnQgPSB0YWcuaW5kZXhPZignIicsIHN0YXJ0ICsgMSk7Ci0JCQlpZiAoc3RhcnQgPT0gLTEpIHsKLQkJCQlicmVhazsKLQkJCX0KLQkJCXN0YXJ0ID0gdGFnLmluZGV4T2YoJyAnLCBzdGFydCArIDEpOwotCQl9Ci0JCXJldHVybiBuYW1lczsKLQl9Ci0KLQkvKioKLQkgKiBFeHRyYWN0cyBhdHRyaWJ1dGUgdmFsdWVzIGZyb20gdGFnIHN0cmluZy4KLQkgKiAKLQkgKiBAcGFyYW0gdGFnCi0JICogICAgICAgICAgICB3aG9sZSB0YWcgbmFtZQotCSAqIEByZXR1cm4gQSB2ZWN0b3Igd2l0aCBhbGwgYXR0cmlidXRlIHZhbHVlcwotCSAqIEBkZXByZWNhdGVkIHVzZSBUYWdDbGFzcy5nZXRBdHRyTGlzdCgpIGluc3RlYWQKLQkgKi8KLQlwdWJsaWMgc3RhdGljIFZlY3RvciBnZXRBdHRyaWJ1dGVWYWx1ZXMoU3RyaW5nIHRhZykgewotCQlWZWN0b3IgdmFsdWVzID0gbmV3IFZlY3RvcigpOwotCQlpbnQgc3RhcnQgPSB0YWcuaW5kZXhPZignPScpOwotCQlpbnQgZW5kOwotCQl3aGlsZSAoc3RhcnQgIT0gLTEpIHsKLQkJCXN0YXJ0ID0gdGFnLmluZGV4T2YoJyInLCBzdGFydCArIDEpOwotCQkJZW5kID0gdGFnLmluZGV4T2YoJyInLCBzdGFydCArIDEpOwotCQkJaWYgKChzdGFydCA9PSAtMSkgfHwgKGVuZCA9PSAtMSkpIHsKLQkJCQlicmVhazsKLQkJCX0KLQkJCXZhbHVlcy5hZGRFbGVtZW50KHRhZy5zdWJzdHJpbmcoc3RhcnQgKyAxLCBlbmQpLmludGVybigpKTsKLQkJCXN0YXJ0ID0gdGFnLmluZGV4T2YoJz0nLCBlbmQgKyAxKTsKLQkJfQotCQlyZXR1cm4gdmFsdWVzOwotCX0KLQotCS8qKgotCSAqIFJldHVybnMgY29udGVudCBvZiB0aGUgc3BlY2lmaWVkIHN1YnRhZy4KLQkgKiAKLQkgKiBAcGFyYW0gdGFnCi0JICogICAgICAgICAgICBwYXJlbnQgdGFnCi0JICogQHBhcmFtIHBvcwotCSAqICAgICAgICAgICAgcG9zaXRpb24gb2YgdGhlIHNlYXJjaGVkIHRhZyBpbiBjaGlsZCBhcnJheSBvZiB0aGUgcGFyZW50IHRhZwotCSAqIEBwYXJhbSBuYW1lCi0JICogICAgICAgICAgICBuYW1lIG9mIHRoZSBzZWFyY2hlZCB0YWcKLQkgKiBAcmV0dXJuIGNvbnRlbnQgb2YgdGhlIHNwZWNpZmllZCBzdWJ0YWcKLQkgKiBAZXhjZXB0aW9uIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbgotCSAqICAgICAgICAgICAgICAgIGlmIHRoZSBzcGVjaWZpZWQgbmFtZSBkb2VzIG5vdCBtYXRjaCB0aGUgbmFtZSBvZiB0aGUgdGFnCi0JICogICAgICAgICAgICAgICAgYXQgc3BlY2lmaWVkIHBvc2l0aW9uCi0JICogQGRlcHJlY2F0ZWQgdXNlIFRhZ0NsYXNzLmdldENvbnRlbnQoaW50IHBvcywgU3RyaW5nIG5hbWUpIGluc3RlYWQKLQkgKi8KLQotCXB1YmxpYyBzdGF0aWMgU3RyaW5nIGdldENvbnRlbnQoVGFnQ2xhc3MgdGFnLCBpbnQgcG9zLCBTdHJpbmcgbmFtZSkgdGhyb3dzIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiB7Ci0JCVRhZ0NsYXNzIHN1YlRhZyA9IHRhZy5nZXRUYWdBdChwb3MpOwotCQlpZiAoc3ViVGFnLmdldE5hbWUoKS5lcXVhbHMobmFtZSkpIHsKLQkJCXJldHVybiBzdWJUYWcuZ2V0Q29udGVudCgpOwotCQl9Ci0JCXRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIk1pc3Npbmcgc3VidGFnICIgKyBuYW1lICsgIiBpbiAiICsgdGFnLmdldE5hbWUoKSk7Ci0JfQotfQpkaWZmIC0tZ2l0IGEvYnVuZGxlcy9vcmcuZWNsaXBzZS5lcXVpbm94LmRzL3NyYy9vcmcvZWNsaXBzZS9lcXVpbm94L2ludGVybmFsL3V0aWwveG1sL1htbFNlcmlhbGl6ZXIuamF2YSBiL2J1bmRsZXMvb3JnLmVjbGlwc2UuZXF1aW5veC5kcy9zcmMvb3JnL2VjbGlwc2UvZXF1aW5veC9pbnRlcm5hbC91dGlsL3htbC9YbWxTZXJpYWxpemVyLmphdmEKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IGUxYjFiOTIuLjAwMDAwMDAKLS0tIGEvYnVuZGxlcy9vcmcuZWNsaXBzZS5lcXVpbm94LmRzL3NyYy9vcmcvZWNsaXBzZS9lcXVpbm94L2ludGVybmFsL3V0aWwveG1sL1htbFNlcmlhbGl6ZXIuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDQ0NCArMCwwIEBACi0vKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgotICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDA4IGJ5IFByb1N5c3QgU29mdHdhcmUgR21iSAotICogaHR0cDovL3d3dy5wcm9zeXN0LmNvbQotICogQWxsIHJpZ2h0cyByZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscwotICogYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2MS4wCi0gKiB3aGljaCBhY2NvbXBhbmllcyB0aGlzIGRpc3RyaWJ1dGlvbiwgYW5kIGlzIGF2YWlsYWJsZSBhdAotICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtdjEwLmh0bWwKLSAqCi0gKiBDb250cmlidXRvcnM6Ci0gKiAgICBQcm9TeXN0IFNvZnR3YXJlIEdtYkggLSBpbml0aWFsIEFQSSBhbmQgaW1wbGVtZW50YXRpb24KLSAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwotcGFja2FnZSBvcmcuZWNsaXBzZS5lcXVpbm94LmludGVybmFsLnV0aWwueG1sOwotCi1pbXBvcnQgamF2YS5pby4qOwotaW1wb3J0IGphdmEudXRpbC5WZWN0b3I7Ci0KLS8qKgotICogWG1sU2VyaWFsaXplciBpcyBhbiB1dGlsaXR5IGNsYXNzLCB0aGF0IHNpbXBsaWZpZXMgY3JlYXRpb24gb2YgWE1MIGZpbGVzLiBJdAotICogaXMgZGVzaWduZWQgdG8gYmUgc2ltaWxhciB0byB0aGUgWE1MIFB1bGwgQVBJIHNlcmlhbGl6ZXIuCi0gKiAKLSAqIEBhdXRob3IgVmFsZW50aW4gVmFsY2hldgotICogQGF1dGhvciBQYXZsaW4gRG9icmV2Ci0gKiBAdmVyc2lvbiAxLjAKLSAqLwotCi1wdWJsaWMgY2xhc3MgWG1sU2VyaWFsaXplciB7Ci0KLQlwcml2YXRlIFdyaXRlciB3cml0ZXI7IC8vIHVuZGVybHlpbmcgd3JpdGVyCi0JcHJpdmF0ZSBWZWN0b3Igc3RhY2s7IC8vIG9mIFhNTCBlbnRpdHkgbmFtZXMKLQlwcml2YXRlIFN0cmluZ1dyaXRlciBhdHRyc1dyaXRlcjsgLy8gY3VycmVudCBhdHRyaWJ1dGUgd3JpdGVyCi0JcHJpdmF0ZSBTdHJpbmdCdWZmZXIgYXR0cnM7IC8vIGN1cnJlbnQgYXR0cmlidXRlIHN0cmluZwotCXByaXZhdGUgYm9vbGVhbiBlbXB0eTsgLy8gaXMgdGhlIGN1cnJlbnQgbm9kZSBlbXB0eQotCXByaXZhdGUgYm9vbGVhbiBjbG9zZWQ7IC8vIGlzIHRoZSBjdXJyZW50IG5vZGUgY2xvc2VkLi4uCi0JcHJpdmF0ZSBTdHJpbmcgaW5kZW50U3RyaW5nOwotCXByaXZhdGUgYm9vbGVhbiBwcm9sb2dXcml0dGVuOwotCi0JLyoqCi0JICogT3BlbnMgYW5kIGluaXRpYWxpemVzIFhNTCBvdXRwdXQgb24gdG9wIG9mIGV4aXN0aW5nIFdyaXRlci4KLQkgKiAKLQkgKiBAcGFyYW0gd3JpdGVyCi0JICogICAgICAgICAgICB0aGUgb3V0cHV0IHdyaXRlcgotCSAqIEByZXR1cm4gc2VsZgotCSAqLwotCXB1YmxpYyBYbWxTZXJpYWxpemVyIHNldE91dHB1dChXcml0ZXIgd3JpdGVyKSB7Ci0JCXRoaXMud3JpdGVyID0gd3JpdGVyOwotCQl0aGlzLmNsb3NlZCA9IHRydWU7Ci0JCXRoaXMucHJvbG9nV3JpdHRlbiA9IGZhbHNlOwotCQlpZiAoc3RhY2sgPT0gbnVsbCkgewotCQkJc3RhY2sgPSBuZXcgVmVjdG9yKDUpOwotCQl9IGVsc2UgewotCQkJc3RhY2sucmVtb3ZlQWxsRWxlbWVudHMoKTsKLQkJfQotCQlpZiAoYXR0cnMgIT0gbnVsbCkgewotCQkJYXR0cnMuc2V0TGVuZ3RoKDApOwotCQl9Ci0JCXJldHVybiB0aGlzOwotCX0KLQotCS8qKgotCSAqIFNldCB0byB1c2UgYmluYXJ5IG91dHB1dCBzdHJlYW0gd2l0aCBnaXZlbiBlbmNvZGluZy4KLQkgKiAKLQkgKiBAcGFyYW0gb3MKLQkgKiAgICAgICAgICAgIHRoZSBvdXRwdXQgc3RyZWFtCi0JICogQHBhcmFtIGVuY29kaW5nCi0JICogICAgICAgICAgICB0aGUgb3V0cHV0IGVuY29kaW5nCi0JICogQHRocm93cyBJT0V4Y2VwdGlvbgotCSAqIEBzZWUgI3NldE91dHB1dChXcml0ZXIpCi0JICogQHRocm93cyBOdWxsUG9pbnRlckV4Y2VwdGlvbgotCSAqICAgICAgICAgICAgIGlzIG91dHB1dCBzdHJlYW0gaXMgbnVsbAotCSAqLwotCXB1YmxpYyB2b2lkIHNldE91dHB1dChPdXRwdXRTdHJlYW0gb3MsIFN0cmluZyBlbmNvZGluZykgdGhyb3dzIElPRXhjZXB0aW9uIHsKLQkJaWYgKG9zID09IG51bGwpCi0JCQl0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIm91dHB1dCBzdHJlYW0gY2FuIG5vdCBiZSBudWxsIik7Ci0JCVdyaXRlciB3cml0ZXIgPSBlbmNvZGluZyAhPSBudWxsID8gLy8KLQkJbmV3IE91dHB1dFN0cmVhbVdyaXRlcihvcywgZW5jb2RpbmcpCi0JCQkJOiAvLwotCQkJCW5ldyBPdXRwdXRTdHJlYW1Xcml0ZXIob3MpOwotCQlzZXRPdXRwdXQod3JpdGVyKTsKLQl9Ci0KLQkvKioKLQkgKiBXcml0ZXMgWE1MIHByb2xvZyBjb2RlOgotCSAqIAotCSAqIDxwcmU+Ci0JICogICAgICAgICZsdDs/eG1sIHZlcnNpb249JnF1b3Q7MS4wJnF1b3Q7PyZndDsKLQkgKiA8L3ByZT4KLQkgKiAKLQkgKiBAcGFyYW0gZW5jb2RpbmcKLQkgKiAgICAgICAgICAgIHRoZSBzZWxlY3RlZCBlbmNvZGluZy4gSWYgPGNvZGU+bnVsbDwvY29kZT4gZW5jb2RpbmcKLQkgKiAgICAgICAgICAgIGF0dHJpYnV0ZSBpcyBub3Qgd3JpdHRlbi4KLQkgKiBAcGFyYW0gc3RhbmRhbG9uZQotCSAqICAgICAgICAgICAgaWYgdGhlIFhNTCBpcyBzdGFuZC1hbG9uZSwgbm8gRFREIG9yIHNjaGVtYQotCSAqIEByZXR1cm4gc2VsZgotCSAqIEB0aHJvd3MgSU9FeGNlcHRpb24KLQkgKiAgICAgICAgICAgICBvbiBJL08gZXJyb3IKLQkgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbgotCSAqICAgICAgICAgICAgIGlmIHByb2xvZyBjb2RlIGlzIGFscmVhZHkgd3JpdHRlbgotCSAqLwotCXB1YmxpYyBYbWxTZXJpYWxpemVyIHN0YXJ0RG9jdW1lbnQoU3RyaW5nIGVuY29kaW5nLCBCb29sZWFuIHN0YW5kYWxvbmUpIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0JCWlmIChwcm9sb2dXcml0dGVuKSB7Ci0JCQl0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCJQcm9sb2cgYWxyZWFkeSB3cml0dGVuIik7Ci0JCX0KLQkJd3JpdGVyLndyaXRlKCI8P3htbCB2ZXJzaW9uPVwiMS4wXCIiKTsKLQkJaWYgKGVuY29kaW5nICE9IG51bGwpIHsKLQkJCXdyaXRlci53cml0ZSgiIGVuY29kaW5nPVwiIik7Ci0JCQl3cml0ZXIud3JpdGUoZW5jb2RpbmcpOwotCQkJd3JpdGVyLndyaXRlKCJcIiIpOwotCQl9Ci0JCWlmIChzdGFuZGFsb25lICE9IG51bGwpIHsKLQkJCXdyaXRlci53cml0ZSgiIHN0YW5kYWxvbmU9XCIiKTsKLQkJCXdyaXRlci53cml0ZShzdGFuZGFsb25lLmJvb2xlYW5WYWx1ZSgpID8gInllcyIgOiAibm8iKTsKLQkJCXdyaXRlci53cml0ZSgiXCIiKTsKLQkJfQotCQl3cml0ZXIud3JpdGUoIj8+Iik7Ci0JCXByb2xvZ1dyaXR0ZW4gPSB0cnVlOwotCQlyZXR1cm4gdGhpczsKLQl9Ci0KLQkvKioKLQkgKiBDbG9zZSB0aGlzIHdyaXRlci4gSXQgZG9lcyBub3QgY2xvc2UgdGhlIHVuZGVybHlpbmcgd3JpdGVyLCBidXQgZG9lcwotCSAqIHRocm93IGFuIGV4Y2VwdGlvbiBpZiB0aGVyZSBhcmUgYXMgeWV0IHVuY2xvc2VkIHRhZ3MuCi0JICogCi0JICogQHRocm93cyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24KLQkgKiAgICAgICAgICAgICBpZiB0YWdzIGFyZSBub3QgY2xvc2VkCi0JICovCi0JcHVibGljIHZvaWQgZW5kRG9jdW1lbnQoKSB7Ci0JCWlmICghc3RhY2suaXNFbXB0eSgpKSB7Ci0JCQl0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCJUYWdzIGFyZSBub3QgYWxsIGNsb3NlZC4gUG9zc2libHksICciICsgcG9wKCkgKyAiJyBpcyB1bmNsb3NlZC4gIik7Ci0JCX0KLQl9Ci0KLQkvKioKLQkgKiBSZXR1cm5zIHRoZSBjdXJyZW50IGRlcHRoIG9mIHRoZSBlbGVtZW50LiBPdXRzaWRlIHRoZSByb290IGVsZW1lbnQsIHRoZQotCSAqIGRlcHRoIGlzIDAuIFRoZSBkZXB0aCBpcyBpbmNyZW1lbnRlZCBieSAxIHdoZW4gc3RhcnRUYWcoKSBpcyBjYWxsZWQuIFRoZQotCSAqIGRlcHRoIGlzIGRlY3JlbWVudGVkIGFmdGVyIHRoZSBjYWxsIHRvIGVuZFRhZygpIGV2ZW50IHdhcyBvYnNlcnZlZC4KLQkgKiAKLQkgKiA8cHJlPgotCSAqICAgICAgICAmbHQ7IS0tIG91dHNpZGUgLS0mZ3Q7ICAgICAwCi0JICogICAgICAgICZsdDtyb290Jmd0OyAgICAgICAgICAgICAgIDEKLQkgKiAgICAgICAgICBzb21ldGV4dCAgICAgICAgICAgICAgICAgMQotCSAqICAgICAgICAgICAgJmx0O2Zvb2JhciZndDsgICAgICAgICAyCi0JICogICAgICAgICAgICAmbHQ7L2Zvb2JhciZndDsgICAgICAgIDIKLQkgKiAgICAgICAgJmx0Oy9yb290Jmd0OyAgICAgICAgICAgICAgMQotCSAqICAgICAgICAmbHQ7IS0tIG91dHNpZGUgLS0mZ3Q7ICAgICAwCi0JICogPC9wcmU+Ci0JICogCi0JICogQHJldHVybiB0aGUgY3VycmVudCBsZXZlbAotCSAqLwotCXB1YmxpYyBpbnQgZ2V0RGVwdGgoKSB7Ci0JCXJldHVybiBzdGFjay5zaXplKCk7Ci0JfQotCi0JLyoqCi0JICogQmVnaW4gdG8gb3V0cHV0IGFuIGVudGl0eS4KLQkgKiAKLQkgKiBAcGFyYW0gbmFtZQotCSAqICAgICAgICAgICAgbmFtZSBvZiBlbnRpdHkuCi0JICogQHJldHVybiBzZWxmCi0JICogQHRocm93cyBJT0V4Y2VwdGlvbgotCSAqICAgICAgICAgICAgIG9uIEkvTyBlcnJvcgotCSAqLwotCXB1YmxpYyBYbWxTZXJpYWxpemVyIHN0YXJ0VGFnKFN0cmluZyBuYW1lKSB0aHJvd3MgSU9FeGNlcHRpb24gewotCQlpZiAoIXByb2xvZ1dyaXR0ZW4pIHsKLQkJCXN0YXJ0RG9jdW1lbnQobnVsbCwgbnVsbCk7Ci0JCX0KLQkJY2xvc2VPcGVuaW5nVGFnKCk7Ci0JCWNsb3NlZCA9IGZhbHNlOwotCQlpbmRlbnQoKTsKLQkJd3JpdGVyLndyaXRlKCI8Iik7Ci0JCXdyaXRlci53cml0ZShuYW1lKTsKLQkJc3RhY2suYWRkRWxlbWVudChuYW1lKTsKLQkJZW1wdHkgPSB0cnVlOwotCQlyZXR1cm4gdGhpczsKLQl9Ci0KLQkvKioKLQkgKiBFbmQgdGhlIGN1cnJlbnQgZW50aXR5IHNpbGVudGx5IHdpdGhvdXQgdmFsaWRhdGluZyBpZiBjb3JyZWN0IHRhZyBpcwotCSAqIGNsb3NlZC4KLQkgKiAKLQkgKiBAcmV0dXJuIHNlbGYKLQkgKiBAdGhyb3dzIElPRXhjZXB0aW9uCi0JICogQGRlcHJlY2F0ZWQgc2VlIHtAbGluayAjZW5kVGFnKFN0cmluZyl9Ci0JICovCi0JcHVibGljIFhtbFNlcmlhbGl6ZXIgZW5kVGFnKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKLQkJcmV0dXJuIGVuZFRhZyhudWxsKTsKLQl9Ci0KLQkvKioKLQkgKiBFbmQgdGhlIGN1cnJlbnQgZW50aXR5LiBUaGlzIHdpbGwgdGhyb3cgYW4gZXhjZXB0aW9uIGlmIGl0IGlzIGNhbGxlZCB3aGVuCi0JICogdGhlcmUgaXMgbm90IGEgY3VycmVudGx5IG9wZW4gZW50aXR5LgotCSAqIAotCSAqIEBwYXJhbSBhTmFtZQotCSAqICAgICAgICAgICAgdGFnIHRvIGNsb3NlLiBUaGlzIGlzIHVzZWQgbW9zdGx5IGZvciB2YWxpZGF0aW9uCi0JICogQHJldHVybiBzZWxmCi0JICogQHRocm93cyBJT0V4Y2VwdGlvbgotCSAqICAgICAgICAgICAgIG9uIEkvTyBlcnJvcgotCSAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uCi0JICogICAgICAgICAgICAgaWYgbm8gZW50aXR5IHdhaXRzIHRvIGJlIGNsb3NlZAotCSAqIEB0aHJvd3MgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uCi0JICogICAgICAgICAgICAgaWYgZXhwZWN0ZWQgZWxlbWVudCBuYW1lIGlzIG5vdCB0aGUgc2FtZQotCSAqLwotCXB1YmxpYyBYbWxTZXJpYWxpemVyIGVuZFRhZyhTdHJpbmcgYU5hbWUpIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0KLQkJaWYgKHN0YWNrLmlzRW1wdHkoKSkgewotCQkJdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigiQ2FsbGVkIGVuZEVudGl0eSB0b28gbWFueSB0aW1lcy4iKTsKLQkJfQotCQlTdHJpbmcgbmFtZSA9IHBvcCgpOwotCQlpZiAobmFtZSAhPSBudWxsKSB7Ci0JCQlpZiAoYU5hbWUgIT0gbnVsbCAmJiAhYU5hbWUuZXF1YWxzKG5hbWUpKSB7Ci0JCQkJdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiRXhwZWN0ZWQgZWxlbWVudCBuYW1lICciICsgbmFtZSArICInLCBub3QgJyIgKyBhTmFtZSArICInIik7Ci0JCQl9Ci0JCQlpZiAoZW1wdHkpIHsKLQkJCQl3cml0ZUF0dHJpYnV0ZXMoKTsKLQkJCQl3cml0ZXIud3JpdGUoIi8+Iik7Ci0JCQl9IGVsc2UgewotCQkJCWluZGVudCgpOwotCQkJCXdyaXRlci53cml0ZSgiPC8iKTsKLQkJCQl3cml0ZXIud3JpdGUobmFtZSk7Ci0JCQkJd3JpdGVyLndyaXRlKCI+Iik7Ci0JCQl9Ci0JCQllbXB0eSA9IGZhbHNlOwotCQl9Ci0JCXJldHVybiB0aGlzOwotCX0KLQotCS8qKgotCSAqIFdyaXRlIGFuIGF0dHJpYnV0ZSBvdXQgZm9yIHRoZSBjdXJyZW50IGVudGl0eS4gQW55IFhNTCBjaGFyYWN0ZXJzIGluIHRoZQotCSAqIHZhbHVlIGFyZSBlc2NhcGVkLiBDYWxscyB0byBhdHRyaWJ1dGUoKSBNVVNUIGZvbGxvdyBhIGNhbGwgdG8gc3RhcnRUYWcoKQotCSAqIGltbWVkaWF0ZWx5LgotCSAqIAotCSAqIEBwYXJhbSBsb2NhbE5hbWUKLQkgKiAgICAgICAgICAgIG5hbWUgb2YgYXR0cmlidXRlLgotCSAqIEBwYXJhbSB2YWx1ZQotCSAqICAgICAgICAgICAgdmFsdWUgb2YgYXR0cmlidXRlLgotCSAqIEByZXR1cm4gc2VsZgotCSAqIEB0aHJvd3MgSU9FeGNlcHRpb24KLQkgKiAgICAgICAgICAgICBvbiBJL08gZXJyb3IKLQkgKiBAdGhyb3dzIElsbGVnYWxTdGF0ZUV4Y2VwdGlvbgotCSAqICAgICAgICAgICAgIGlmIG9wZW5pbmcgdGFnIGlzIGNsb3NlZAotCSAqLwotCXB1YmxpYyBYbWxTZXJpYWxpemVyIGF0dHJpYnV0ZShTdHJpbmcgbG9jYWxOYW1lLCBTdHJpbmcgdmFsdWUpIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0JCWlmIChjbG9zZWQpIHsKLQkJCXRocm93IG5ldyBJbGxlZ2FsU3RhdGVFeGNlcHRpb24oIk9wZW5pbmcgdGFnIGlzIGFscmVhZHkgY2xvc2VkIik7Ci0JCX0KLQkJaWYgKGxvY2FsTmFtZSA9PSBudWxsKSB7Ci0JCQl0aHJvdyBuZXcgSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKCJBdHRyaWJ1dGUgbmFtZSBpcyBudWxsIik7Ci0JCX0KLQkJaWYgKHZhbHVlID09IG51bGwpCi0JCQl2YWx1ZSA9ICIiOwotCQlpZiAoYXR0cnNXcml0ZXIgPT0gbnVsbCkgewotCQkJYXR0cnNXcml0ZXIgPSBuZXcgU3RyaW5nV3JpdGVyKCk7Ci0JCQlhdHRycyA9IGF0dHJzV3JpdGVyLmdldEJ1ZmZlcigpOwotCQl9Ci0JCWF0dHJzLmFwcGVuZCgiICIpOwotCQlhdHRycy5hcHBlbmQobG9jYWxOYW1lKTsKLQkJYXR0cnMuYXBwZW5kKCI9XCIiKTsKLQkJd3JpdGVFc2NhcGUodmFsdWUsIGF0dHJzV3JpdGVyKTsKLQkJYXR0cnMuYXBwZW5kKCJcIiIpOwotCQlyZXR1cm4gdGhpczsKLQl9Ci0KLQkvKioKLQkgKiBPdXRwdXQgYm9keSB0ZXh0LiBBbnkgWE1MIGNoYXJhY3RlcnMgYXJlIGVzY2FwZWQuCi0JICogCi0JICogQHBhcmFtIHRleHQKLQkgKiAgICAgICAgICAgIHRoZSBib2R5IHRleHQKLQkgKiBAcmV0dXJuIHNlbGYKLQkgKiBAdGhyb3dzIElPRXhjZXB0aW9uCi0JICogICAgICAgICAgICAgb24gSS9PIGVycm9yCi0JICovCi0JcHVibGljIFhtbFNlcmlhbGl6ZXIgdGV4dChTdHJpbmcgdGV4dCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKLQkJY2xvc2VPcGVuaW5nVGFnKCk7Ci0JCWlmICh0ZXh0ICE9IG51bGwgJiYgdGV4dC5sZW5ndGgoKSA+IDApIHsKLQkJCWluZGVudCgpOwotCQkJZW1wdHkgPSBmYWxzZTsKLQkJCXdyaXRlRXNjYXBlKHRleHQsIHdyaXRlcik7Ci0JCX0KLQkJcmV0dXJuIHRoaXM7Ci0JfQotCi0JLyoqCi0JICogV3JpdGVzIHJhdywgQ0RBVEEgc2VjdGlvbgotCSAqIAotCSAqIEBwYXJhbSB0ZXh0Ci0JICogICAgICAgICAgICB0aGUgZGF0YQotCSAqIEByZXR1cm4gc2VsZgotCSAqIEB0aHJvd3MgSU9FeGNlcHRpb24KLQkgKiAgICAgICAgICAgICBvbiBJL08gZXJyb3IKLQkgKi8KLQlwdWJsaWMgWG1sU2VyaWFsaXplciBjZHNlY3QoU3RyaW5nIHRleHQpIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0JCWNsb3NlT3BlbmluZ1RhZygpOwotCQl3cml0ZXIud3JpdGUoIjwhW0NEQVRBWyIpOwotCQl3cml0ZXIud3JpdGUodGV4dCk7Ci0JCXdyaXRlci53cml0ZSgiXV0+Iik7Ci0JCXJldHVybiB0aGlzOwotCX0KLQotCS8qKgotCSAqIFdyaXRlcyBYTUwgY29tbWVudCBjb2RlCi0JICogCi0JICogQHBhcmFtIHRleHQKLQkgKiAgICAgICAgICAgIHRoZSBjb21tZW50Ci0JICogQHJldHVybiBzZWxmCi0JICogQHRocm93cyBJT0V4Y2VwdGlvbgotCSAqICAgICAgICAgICAgIG9uIEkvTyBlcnJvcgotCSAqLwotCXB1YmxpYyBYbWxTZXJpYWxpemVyIGNvbW1lbnQoU3RyaW5nIHRleHQpIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0JCWNsb3NlT3BlbmluZ1RhZygpOwotCQl3cml0ZXIud3JpdGUoIjwhLS0iKTsKLQkJd3JpdGVyLndyaXRlKHRleHQpOwotCQl3cml0ZXIud3JpdGUoIi0tPiIpOwotCQlyZXR1cm4gdGhpczsKLQl9Ci0KLQkvKioKLQkgKiBXcml0ZXMgRE9DVFlQRSBkZWNsYXJhdGlvbi4gVGhlIGRvY3VtZW50IG11c3QgYmUgb3BlbiBwcmlvciBjYWxsaW5nIHRoYXQKLQkgKiBtZXRob2QuCi0JICogCi0JICogQHBhcmFtIHRleHQKLQkgKiAgICAgICAgICAgIGRlY2xhcmF0aW9uCi0JICogQHJldHVybiBzZWxmCi0JICogQHRocm93cyBJT0V4Y2VwdGlvbgotCSAqICAgICAgICAgICAgIG9uIEkvTyBlcnJvcgotCSAqIEB0aHJvd3MgSWxsZWdhbFN0YXRlRXhjZXB0aW9uCi0JICogICAgICAgICAgICAgaWYgZG9jdW1lbnQgaXMgbm90IG9wZW4gb3Igc3RhcnQgdGFnIGlzIGFscmVhZHkgc3RhcnRlZAotCSAqLwotCXB1YmxpYyBYbWxTZXJpYWxpemVyIGRvY2RlY2woU3RyaW5nIHRleHQpIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0JCWlmICghcHJvbG9nV3JpdHRlbikgewotCQkJdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigiRG9jdW1lbnQgaXMgbm90IG9wZW4iKTsKLQkJfQotCQlpZiAoZ2V0RGVwdGgoKSAhPSAwKSB7Ci0JCQl0aHJvdyBuZXcgSWxsZWdhbFN0YXRlRXhjZXB0aW9uKCJDYW5ub3QgYWRkIERPQ1RZUEUgYWZ0ZXIgc3RhcnQgdGFnIGhhcyBiZWVuIG9wZW5lZCEiKTsKLQkJfQotCQljbG9zZU9wZW5pbmdUYWcoKTsKLQkJd3JpdGVyLndyaXRlKCI8IURPQ1RZUEUiKTsKLQkJd3JpdGVyLndyaXRlKHRleHQpOwotCQl3cml0ZXIud3JpdGUoIj4iKTsKLQkJcmV0dXJuIHRoaXM7Ci0JfQotCi0JLyoqCi0JICogRW5hYmxlcy9kaXNhYmxlcyBpbmRlbnRhdGlvbgotCSAqIAotCSAqIEBwYXJhbSBpbmRlbnQKLQkgKiAgICAgICAgICAgIGFuIGluZGVudGF0aW9uIHN0cmluZyBvciA8Y29kZT5udWxsPC9jb2RlPiB0byBkaXNhYmxlCi0JICogICAgICAgICAgICBpbmRlbnRhdGlvbi4KLQkgKi8KLQlwdWJsaWMgdm9pZCBzZXRJbmRlbnQoYm9vbGVhbiBpbmRlbnQpIHsKLQkJdGhpcy5pbmRlbnRTdHJpbmcgPSBpbmRlbnQgPyAiXHQiIDogbnVsbDsKLQl9Ci0KLQkvLyBjbG9zZSBvZmYgdGhlIG9wZW5pbmcgdGFnCi0JcHJpdmF0ZSB2b2lkIGNsb3NlT3BlbmluZ1RhZygpIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0JCWlmICghdGhpcy5jbG9zZWQpIHsKLQkJCXdyaXRlQXR0cmlidXRlcygpOwotCQkJY2xvc2VkID0gdHJ1ZTsKLQkJCXdyaXRlci53cml0ZSgiPiIpOwotCQl9Ci0JfQotCi0JLy8gd3JpdGUgb3V0IGFsbCBjdXJyZW50IGF0dHJpYnV0ZXMKLQlwcml2YXRlIHZvaWQgd3JpdGVBdHRyaWJ1dGVzKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKLQkJaWYgKGF0dHJzICE9IG51bGwpIHsKLQkJCXdyaXRlci53cml0ZShhdHRycy50b1N0cmluZygpKTsKLQkJCWF0dHJzLnNldExlbmd0aCgwKTsKLQkJCWVtcHR5ID0gZmFsc2U7Ci0JCX0KLQl9Ci0KLQlwcml2YXRlIGZpbmFsIFN0cmluZyBwb3AoKSB7Ci0JCWludCBsb2NhdGlvbiA9IHN0YWNrLnNpemUoKSAtIDE7Ci0JCVN0cmluZyByZXQgPSAoU3RyaW5nKSBzdGFjay5lbGVtZW50QXQobG9jYXRpb24pOwotCQlzdGFjay5yZW1vdmVFbGVtZW50QXQobG9jYXRpb24pOwotCQlyZXR1cm4gcmV0OwotCX0KLQotCXByaXZhdGUgZmluYWwgdm9pZCBpbmRlbnQoKSB0aHJvd3MgSU9FeGNlcHRpb24gewotCQlpZiAoaW5kZW50U3RyaW5nICE9IG51bGwpIHsKLQkJCXdyaXRlci53cml0ZSgnXG4nKTsKLQkJCWZvciAoaW50IGkgPSAwOyBpIDwgc3RhY2suc2l6ZSgpOyBpKyspIHsKLQkJCQl3cml0ZXIud3JpdGUoaW5kZW50U3RyaW5nKTsKLQkJCX0KLQkJfQotCX0KLQotCXByaXZhdGUgZmluYWwgdm9pZCB3cml0ZUVzY2FwZShTdHJpbmcgdGV4dCwgV3JpdGVyIG91dCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKLQkJLy8gZXNjYXBlICc8JywgJyYnLCAnPicsICcsICIKLQkJY2hhcltdIGJ1ZiA9IHRleHQudG9DaGFyQXJyYXkoKTsKLQkJaW50IGxlbiA9IGJ1Zi5sZW5ndGg7Ci0JCWludCBwb3MgPSAwOwotCQlmb3IgKGludCBpID0gMDsgaSA8IGxlbjsgaSsrKSB7Ci0JCQlmaW5hbCBjaGFyIGNoID0gYnVmW2ldOwotCi0JCQlpZiAoY2ggPT0gJyYnKSB7Ci0JCQkJaWYgKGkgPiBwb3MpCi0JCQkJCW91dC53cml0ZShidWYsIHBvcywgaSAtIHBvcyk7Ci0JCQkJb3V0LndyaXRlKCImYW1wOyIpOwotCQkJCXBvcyA9IGkgKyAxOwotCQkJfSBlbHNlIGlmIChjaCA9PSAnPCcpIHsKLQkJCQlpZiAoaSA+IHBvcykKLQkJCQkJb3V0LndyaXRlKGJ1ZiwgcG9zLCBpIC0gcG9zKTsKLQkJCQlvdXQud3JpdGUoIiZsdDsiKTsKLQkJCQlwb3MgPSBpICsgMTsKLQkJCX0gZWxzZSBpZiAoY2ggPT0gJz4nKSB7Ci0JCQkJaWYgKGkgPiBwb3MpCi0JCQkJCW91dC53cml0ZShidWYsIHBvcywgaSAtIHBvcyk7Ci0JCQkJb3V0LndyaXRlKCImZ3Q7Iik7Ci0JCQkJcG9zID0gaSArIDE7Ci0JCQl9IGVsc2UgaWYgKGNoID09ICciJykgewotCQkJCWlmIChpID4gcG9zKQotCQkJCQlvdXQud3JpdGUoYnVmLCBwb3MsIGkgLSBwb3MpOwotCQkJCW91dC53cml0ZSgiJmd1b3Q7Iik7Ci0JCQkJcG9zID0gaSArIDE7Ci0JCQl9IGVsc2UgaWYgKGNoID09ICdcJycpIHsKLQkJCQlpZiAoaSA+IHBvcykKLQkJCQkJb3V0LndyaXRlKGJ1ZiwgcG9zLCBpIC0gcG9zKTsKLQkJCQlvdXQud3JpdGUoIiZhcG9zOyIpOwotCQkJCXBvcyA9IGkgKyAxOwotCQkJfSBlbHNlIGlmIChjaCA8IDMyKSB7Ci0JCQkJLy8gaW4gWE1MIDEuMCBvbmx5IGxlZ2FsIGNoYXJhY3RlciBhcmUgI3g5IHwgI3hBIHwgI3hECi0JCQkJaWYgKGNoID09IDkgfHwgY2ggPT0gMTAgfHwgY2ggPT0gMTMpIHsKLQkJCQkJLy8gcGFzcyB0aHJvdWdoCi0JCQkJfSBlbHNlIHsKLQkJCQkJdGhyb3cgbmV3IElsbGVnYWxTdGF0ZUV4Y2VwdGlvbigiY2hhcmFjdGVyICIgKyBjaCArICIgKCIgKyBJbnRlZ2VyLnRvU3RyaW5nKGNoKSArICIpIGlzIG5vdCBhbGxvd2VkIGluIG91dHB1dCIpOwotCQkJCX0KLQkJCX0KLQkJfQotCQlpZiAobGVuID4gcG9zKSB7Ci0JCQlvdXQud3JpdGUoYnVmLCBwb3MsIGxlbiAtIHBvcyk7Ci0JCX0KLQl9Ci0KLQkvKgotCSAqIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKFN0cmluZ1tdIGFyZ3MpIHRocm93cyBJT0V4Y2VwdGlvbiB7IFhtbFNlcmlhbGl6ZXIKLQkgKiBvID0gbmV3IFhtbFNlcmlhbGl6ZXIoKTsgV3JpdGVyIHggPSBuZXcgamF2YS5pby5TdHJpbmdXcml0ZXIoKTsKLQkgKiBvLnNldEluZGVudCh0cnVlKTsgby5zZXRPdXRwdXQoeCk7IG8uc3RhcnREb2N1bWVudCgiVVRGLTgiLCBudWxsKS8vCi0JICogLnN0YXJ0VGFnKCJ0ZXN0IikvLyAuc3RhcnRUYWcoImlubmVyIikvLyAuYXR0cmlidXRlKCJhdHRyaWJ1dGUiLAotCSAqICJ2YWx1ZSIpLnRleHQoInRleHQgJiAnIDwgPiBcXFwiIDtbIikvLyAuY29tbWVudCgidGhpcyBpcyBhbiBlbWJlZGRlZAotCSAqIGNvbW1lbnQgaW5zaWRlIHRoZSBpbm5lciBib2R5IikvLyAuZW5kVGFnKCJpbm5lciIpLy8KLQkgKiAuc3RhcnRUYWcoImVudHJ5IikuY2RzZWN0KCJ0ZXN0aW5nIFtdID4gPCAmIDsiKS5lbmRUYWcoImVudHJ5IikvLwotCSAqIC5lbmRUYWcoInRlc3QiKS8vIC5lbmREb2N1bWVudCgpOyBTeXN0ZW0ub3V0LnByaW50bG4oeCk7IH0KLQkgKi8KLQotfQpkaWZmIC0tZ2l0IGEvYnVuZGxlcy9vcmcuZWNsaXBzZS5lcXVpbm94LmRzL3NyYy9vcmcvZWNsaXBzZS9lcXVpbm94L2ludGVybmFsL3V0aWwveG1sL2ltcGwvVGFnSW1wbC5qYXZhIGIvYnVuZGxlcy9vcmcuZWNsaXBzZS5lcXVpbm94LmRzL3NyYy9vcmcvZWNsaXBzZS9lcXVpbm94L2ludGVybmFsL3V0aWwveG1sL2ltcGwvVGFnSW1wbC5qYXZhCmRlbGV0ZWQgZmlsZSBtb2RlIDEwMDY0NAppbmRleCBjYTNlMDFmLi4wMDAwMDAwCi0tLSBhL2J1bmRsZXMvb3JnLmVjbGlwc2UuZXF1aW5veC5kcy9zcmMvb3JnL2VjbGlwc2UvZXF1aW5veC9pbnRlcm5hbC91dGlsL3htbC9pbXBsL1RhZ0ltcGwuamF2YQorKysgL2Rldi9udWxsCkBAIC0xLDM4MSArMCwwIEBACi0vKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgotICogQ29weXJpZ2h0IChjKSAxOTk3LCAyMDA4IGJ5IFByb1N5c3QgU29mdHdhcmUgR21iSAotICogaHR0cDovL3d3dy5wcm9zeXN0LmNvbQotICogQWxsIHJpZ2h0cyByZXNlcnZlZC4gVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscwotICogYXJlIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSB2MS4wCi0gKiB3aGljaCBhY2NvbXBhbmllcyB0aGlzIGRpc3RyaWJ1dGlvbiwgYW5kIGlzIGF2YWlsYWJsZSBhdAotICogaHR0cDovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtdjEwLmh0bWwKLSAqCi0gKiBDb250cmlidXRvcnM6Ci0gKiAgICBQcm9TeXN0IFNvZnR3YXJlIEdtYkggLSBpbml0aWFsIEFQSSBhbmQgaW1wbGVtZW50YXRpb24KLSAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwotcGFja2FnZSBvcmcuZWNsaXBzZS5lcXVpbm94LmludGVybmFsLnV0aWwueG1sLmltcGw7Ci0KLWltcG9ydCBqYXZhLmlvLio7Ci1pbXBvcnQgamF2YS51dGlsLio7Ci1pbXBvcnQgb3JnLmVjbGlwc2UuZXF1aW5veC5pbnRlcm5hbC51dGlsLnN0cmluZy5DaGFyQnVmZmVyOwotaW1wb3J0IG9yZy5lY2xpcHNlLmVxdWlub3guaW50ZXJuYWwudXRpbC54bWwuVGFnOwotCi0vKioKLSAqIEBhdXRob3IgSXZhbiBEaW1pdHJvdgotICogQGF1dGhvciBQYXZsaW4gRG9icmV2Ci0gKiBAdmVyc2lvbiAxLjAKLSAqLwotCi1wdWJsaWMgY2xhc3MgVGFnSW1wbCBpbXBsZW1lbnRzIFRhZyB7Ci0KLQlwcml2YXRlIENoYXJCdWZmZXIgZkNvbnRlbnQgPSBudWxsOwotCXByaXZhdGUgU3RyaW5nIGZDb250ZW50U3RyaW5nID0gbnVsbDsKLQlwcml2YXRlIFN0cmluZyBmTmFtZSA9IG51bGw7Ci0JcHJpdmF0ZSBIYXNodGFibGUgZkF0dHJpYnV0ZXMgPSBudWxsOwotCXByaXZhdGUgVmVjdG9yIGZUYWdzID0gbnVsbDsKLQlwcml2YXRlIGludCBmTGluZSA9IC0xOwotCXByb3RlY3RlZCBib29sZWFuIGZJbmxpbmUgPSBmYWxzZTsKLQotCS8qKgotCSAqIEEgaGFzaHRhYmxlIGVudW1lcmF0b3IgY2xhc3MgZm9yIGVtcHR5IGhhc2ggdGFibGVzLCBzcGVjaWFsaXplcyB0aGUKLQkgKiBnZW5lcmFsIEVudW1lcmF0b3IKLQkgKi8KLQlwcml2YXRlIHN0YXRpYyBFbnVtZXJhdGlvbiBmRW1wdHlFbnVtZXJhdGlvbiA9IG5ldyBFbnVtZXJhdGlvbigpIHsKLQkJcHVibGljIGJvb2xlYW4gaGFzTW9yZUVsZW1lbnRzKCkgewotCQkJcmV0dXJuIGZhbHNlOwotCQl9Ci0KLQkJcHVibGljIE9iamVjdCBuZXh0RWxlbWVudCgpIHsKLQkJCXRocm93IG5ldyBOb1N1Y2hFbGVtZW50RXhjZXB0aW9uKCJIYXNodGFibGUgRW51bWVyYXRvciIpOwotCQl9Ci0JfTsKLQotCS8qKgotCSAqIAotCSAqLwotCXB1YmxpYyBUYWdJbXBsKCkgewotCQlzdXBlcigpOwotCX0KLQotCS8qCi0JICogKG5vbi1KYXZhZG9jKQotCSAqIAotCSAqIEBzZWUgb3JnLmVjbGlwc2UuZXF1aW5veC5pbnRlcm5hbC51dGlsLnhtbC5UYWcjZ2V0QXR0cmlidXRlKGphdmEubGFuZy5TdHJpbmcpCi0JICovCi0JcHVibGljIFN0cmluZyBnZXRBdHRyaWJ1dGUoU3RyaW5nIGFBdHRyTmFtZSkgewotCQlyZXR1cm4gKFN0cmluZykgKChmQXR0cmlidXRlcyAhPSBudWxsKSA/IGZBdHRyaWJ1dGVzLmdldChhQXR0ck5hbWUpIDogbnVsbCk7Ci0JfQotCi0JLyoKLQkgKiAobm9uLUphdmFkb2MpCi0JICogCi0JICogQHNlZSBvcmcuZWNsaXBzZS5lcXVpbm94LmludGVybmFsLnV0aWwueG1sLlRhZyNnZXRBdHRyaWJ1dGVzKCkKLQkgKi8KLQlwdWJsaWMgRW51bWVyYXRpb24gZ2V0QXR0cmlidXRlTmFtZXMoKSB7Ci0JCXJldHVybiAoZkF0dHJpYnV0ZXMgIT0gbnVsbCkgPyBmQXR0cmlidXRlcy5rZXlzKCkgOiBmRW1wdHlFbnVtZXJhdGlvbjsKLQl9Ci0KLQkvKgotCSAqIChub24tSmF2YWRvYykKLQkgKiAKLQkgKiBAc2VlIG9yZy5lY2xpcHNlLmVxdWlub3guaW50ZXJuYWwudXRpbC54bWwuVGFnI2dldEF0dHJpYnV0ZVZhbHVlcygpCi0JICovCi0JcHVibGljIEVudW1lcmF0aW9uIGdldEF0dHJpYnV0ZVZhbHVlcygpIHsKLQkJcmV0dXJuIChmQXR0cmlidXRlcyAhPSBudWxsKSA/IGZBdHRyaWJ1dGVzLmVsZW1lbnRzKCkgOiBmRW1wdHlFbnVtZXJhdGlvbjsKLQl9Ci0KLQkvKgotCSAqIChub24tSmF2YWRvYykKLQkgKiAKLQkgKiBAc2VlIG9yZy5lY2xpcHNlLmVxdWlub3guaW50ZXJuYWwudXRpbC54bWwuVGFnI2dldE5hbWUoKQotCSAqLwotCXB1YmxpYyBTdHJpbmcgZ2V0TmFtZSgpIHsKLQkJcmV0dXJuIGZOYW1lOwotCX0KLQotCS8qKgotCSAqIEBzZWUgb3JnLmVjbGlwc2UuZXF1aW5veC5pbnRlcm5hbC51dGlsLnhtbC5UYWcjZ2V0Q29udGVudCgpIG5vdGU6IFRoZSBjb250ZW50IHRoYXQKLQkgKiAgICAgIGlzIHRvIGJlIHJldHVybmVkIHdpbGwgYmUgdHJpbW1lZCBmaXJzdAotCSAqLwotCXB1YmxpYyBTdHJpbmcgZ2V0Q29udGVudCgpIHsKLQkJaWYgKGZDb250ZW50U3RyaW5nICE9IG51bGwpIHsKLQkJCXJldHVybiBmQ29udGVudFN0cmluZzsKLQkJfSBlbHNlIGlmIChmQ29udGVudCAhPSBudWxsKSB7Ci0JCQlmQ29udGVudFN0cmluZyA9IGZDb250ZW50LnRyaW0oKTsKLQkJCWZDb250ZW50ID0gbnVsbDsKLQkJCXJldHVybiBmQ29udGVudFN0cmluZzsKLQkJfQotCQlyZXR1cm4gIiI7Ci0JfQotCi0JLyoKLQkgKiAobm9uLUphdmFkb2MpCi0JICogCi0JICogQHNlZSBvcmcuZWNsaXBzZS5lcXVpbm94LmludGVybmFsLnV0aWwueG1sLlRhZyNnZXRMaW5lKCkKLQkgKi8KLQlwdWJsaWMgaW50IGdldExpbmUoKSB7Ci0JCXJldHVybiBmTGluZTsKLQl9Ci0KLQkvKgotCSAqIChub24tSmF2YWRvYykKLQkgKiAKLQkgKiBAc2VlIG9yZy5lY2xpcHNlLmVxdWlub3guaW50ZXJuYWwudXRpbC54bWwuVGFnI3NpemUoKQotCSAqLwotCXB1YmxpYyBpbnQgc2l6ZSgpIHsKLQkJcmV0dXJuIChmVGFncyAhPSBudWxsKSA/IGZUYWdzLnNpemUoKSA6IDA7Ci0JfQotCi0JLyoKLQkgKiAobm9uLUphdmFkb2MpCi0JICogCi0JICogQHNlZSBvcmcuZWNsaXBzZS5lcXVpbm94LmludGVybmFsLnV0aWwueG1sLlRhZyNnZXRUYWdBdChpbnQpCi0JICovCi0JcHVibGljIFRhZyBnZXRUYWdBdChpbnQgYVBvc2l0aW9uKSB7Ci0JCXJldHVybiAoVGFnKSBmVGFncy5lbGVtZW50QXQoYVBvc2l0aW9uKTsKLQl9Ci0KLQlwcm90ZWN0ZWQgdm9pZCBzZXROYW1lKFN0cmluZyBhTmFtZSkgewotCQlmTmFtZSA9IGFOYW1lOwotCX0KLQotCXByb3RlY3RlZCB2b2lkIGFkZEF0dHJpYnV0ZShTdHJpbmcgYUF0dHJOYW1lLCBTdHJpbmcgYUF0dHJWYWx1ZSkgewotCQlpZiAoZkF0dHJpYnV0ZXMgPT0gbnVsbCkgewotCQkJZkF0dHJpYnV0ZXMgPSBuZXcgSGFzaHRhYmxlKDEpOwotCQl9Ci0JCWZBdHRyaWJ1dGVzLnB1dChhQXR0ck5hbWUsIGFBdHRyVmFsdWUpOwotCX0KLQotCXByb3RlY3RlZCB2b2lkIGFkZFRhZyhUYWcgYVRhZykgewotCQlpZiAoZlRhZ3MgPT0gbnVsbCkgewotCQkJZlRhZ3MgPSBuZXcgVmVjdG9yKDIsIDMpOwotCQl9Ci0JCWZUYWdzLmFkZEVsZW1lbnQoYVRhZyk7Ci0JfQotCi0JcHJvdGVjdGVkIHZvaWQgYXBwZW5kQ29udGVudChDaGFyQnVmZmVyIHRvQXBwZW5kKSB7Ci0JCWlmIChmQ29udGVudCA9PSBudWxsKSB7Ci0JCQlmQ29udGVudCA9IG5ldyBDaGFyQnVmZmVyKHRvQXBwZW5kLmxlbmd0aCgpKTsKLQkJfQotCQlmQ29udGVudC5hcHBlbmQodG9BcHBlbmQuZ2V0VmFsdWUoKSk7Ci0JfQotCi0JcHJvdGVjdGVkIHZvaWQgYXBwZW5kQ29udGVudChTdHJpbmcgdG9BcHBlbmQpIHsKLQkJaWYgKGZDb250ZW50ID09IG51bGwpIHsKLQkJCWZDb250ZW50ID0gbmV3IENoYXJCdWZmZXIodG9BcHBlbmQubGVuZ3RoKCkpOwotCQl9Ci0JCWZDb250ZW50LmFwcGVuZCh0b0FwcGVuZCk7Ci0JfQotCi0JcHJvdGVjdGVkIENoYXJCdWZmZXIgZ2V0Q29udGVudEJ1ZmZlcigpIHsKLQkJaWYgKGZDb250ZW50ID09IG51bGwpIHsKLQkJCWZDb250ZW50ID0gbmV3IENoYXJCdWZmZXIoNSk7Ci0JCX0KLQkJcmV0dXJuIGZDb250ZW50OwotCX0KLQotCXByb3RlY3RlZCB2b2lkIHNldExpbmUoaW50IGFMaW5lKSB7Ci0JCWZMaW5lID0gYUxpbmU7Ci0JfQotCi0JLyoKLQkgKiAobm9uLUphdmFkb2MpCi0JICogCi0JICogQHNlZSBvcmcuZWNsaXBzZS5lcXVpbm94LmludGVybmFsLnV0aWwueG1sLlRhZyNnZXRDb250ZW50KGludCwgamF2YS5sYW5nLlN0cmluZykKLQkgKi8KLQlwdWJsaWMgU3RyaW5nIGdldENvbnRlbnQoaW50IGFQb3MsIFN0cmluZyBhTmFtZSkgewotCQlUYWcgY2hpbGQgPSBnZXRUYWdBdChhUG9zKTsKLQkJaWYgKGNoaWxkID09IG51bGwpCi0JCQl0aHJvdyBuZXcgTnVsbFBvaW50ZXJFeGNlcHRpb24oIlRoZXJlIGlzIG5vIHN1Y2ggYSB0YWcuIFtQYXJlbnQgdGFnIG5hbWVdID0gWyIgKyBhTmFtZSArICJdLCBbY2hpbGQgdGFnIGluZGV4XSA9ICIgKyBhUG9zICsgIiwgW2NoaWxkIHRhZyBuYW1lXSA9IFsiICsgYU5hbWUgKyAnXScpOwotCi0JCWlmIChjaGlsZC5nZXROYW1lKCkuZXF1YWxzKGFOYW1lKSkKLQkJCXJldHVybiBjaGlsZC5nZXRDb250ZW50KCk7Ci0KLQkJdGhyb3cgbmV3IElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbigiVGhlcmUgaXMgbm8gc3VjaCBhIHRhZy4gW1BhcmVudCB0YWcgbmFtZV0gPSBbIiArIGFOYW1lICsgIl0sIFtjaGlsZCB0YWcgaW5kZXhdID0gIiArIGFQb3MgKyAiLCBbY2hpbGQgdGFnIG5hbWVdID0gWyIgKyBhTmFtZSArICddJyk7Ci0JfQotCi0JLyogYmVnaW4gc2VyaWFsaXphdGlvbiBzZWUgRlIgWyAxMzMyNSBdIFhNTDogTWFrZSBUYWcgZXh0ZXJuYWxpemFibGUgKi8KLQotCS8qKgotCSAqIEBzZWUgb3JnLmVjbGlwc2UuZXF1aW5veC5pbnRlcm5hbC51dGlsLmlvLkV4dGVybmFsaXphYmxlI3JlYWRPYmplY3QoamF2YS5pby5JbnB1dFN0cmVhbSkKLQkgKi8KLQlwdWJsaWMgdm9pZCByZWFkT2JqZWN0KElucHV0U3RyZWFtIGlzKSB0aHJvd3MgRXhjZXB0aW9uIHsKLQkJaWYgKCEoaXMgaW5zdGFuY2VvZiBPYmplY3RJbnB1dCkpIHsKLQkJCWlzID0gbmV3IE9iamVjdElucHV0U3RyZWFtKGlzKTsKLQkJfQotCQlyZWFkRXh0ZXJuYWwoKE9iamVjdElucHV0KSBpcyk7Ci0JfQotCi0JLyoqCi0JICogQHNlZSBvcmcuZWNsaXBzZS5lcXVpbm94LmludGVybmFsLnV0aWwuaW8uRXh0ZXJuYWxpemFibGUjd3JpdGVPYmplY3QoamF2YS5pby5PdXRwdXRTdHJlYW0pCi0JICovCi0JcHVibGljIHZvaWQgd3JpdGVPYmplY3QoT3V0cHV0U3RyZWFtIG9zKSB0aHJvd3MgRXhjZXB0aW9uIHsKLQkJaWYgKCEob3MgaW5zdGFuY2VvZiBPYmplY3RPdXRwdXQpKSB7Ci0JCQlvcyA9IG5ldyBPYmplY3RPdXRwdXRTdHJlYW0ob3MpOwotCQl9Ci0JCXdyaXRlRXh0ZXJuYWwoKE9iamVjdE91dHB1dCkgb3MpOwotCQlvcy5mbHVzaCgpOwotCX0KLQotCS8qKgotCSAqIEBwYXJhbSBpbnB1dAotCSAqIEB0aHJvd3MgSU9FeGNlcHRpb24KLQkgKiBAdGhyb3dzIENsYXNzTm90Rm91bmRFeGNlcHRpb24KLQkgKi8KLQlwdWJsaWMgdm9pZCByZWFkRXh0ZXJuYWwoT2JqZWN0SW5wdXQgaW5wdXQpIHRocm93cyBJT0V4Y2VwdGlvbiwgQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiB7Ci0JCWZOYW1lID0gaW5wdXQucmVhZFVURigpOwotCQkvKiByZWFkIGNvbnRlbnQgKi8KLQkJYm9vbGVhbiBoYXNDb250ZW50ID0gaW5wdXQucmVhZEJvb2xlYW4oKTsKLQkJaWYgKGhhc0NvbnRlbnQpIHsKLQkJCWZDb250ZW50U3RyaW5nID0gaW5wdXQucmVhZFVURigpOwotCQl9Ci0JCWludCBzaXplOwotCQkvKiByZWFkIGF0dHJpYnV0ZXMgKi8KLQkJc2l6ZSA9IGlucHV0LnJlYWRJbnQoKTsKLQkJaWYgKHNpemUgPiAwKSB7Ci0JCQlmQXR0cmlidXRlcyA9IG5ldyBIYXNodGFibGUoc2l6ZSwgMSk7Ci0JCQlmb3IgKGludCBpID0gMDsgaSA8IHNpemU7IGkrKykgewotCQkJCVN0cmluZyBrZXkgPSBpbnB1dC5yZWFkVVRGKCk7Ci0JCQkJU3RyaW5nIHZhbCA9IGlucHV0LnJlYWRVVEYoKTsKLQkJCQlmQXR0cmlidXRlcy5wdXQoa2V5LCB2YWwpOwotCQkJfQotCQl9Ci0JCS8qIHJlYWQgZWxlbWVudHMgKi8KLQkJc2l6ZSA9IGlucHV0LnJlYWRJbnQoKTsKLQkJaWYgKHNpemUgPiAwKSB7Ci0JCQlmVGFncyA9IG5ldyBWZWN0b3Ioc2l6ZSk7Ci0JCQlmb3IgKGludCBpID0gMDsgaSA8IHNpemU7IGkrKykgewotCQkJCVRhZ0ltcGwgdGFnID0gbmV3IFRhZ0ltcGwoKTsKLQkJCQl0YWcucmVhZEV4dGVybmFsKGlucHV0KTsKLQkJCQlmVGFncy5hZGRFbGVtZW50KHRhZyk7Ci0JCQl9Ci0JCX0KLQl9Ci0KLQkvKioKLQkgKiBAcGFyYW0gb3V0cHV0Ci0JICogQHRocm93cyBJT0V4Y2VwdGlvbgotCSAqLwotCXB1YmxpYyB2b2lkIHdyaXRlRXh0ZXJuYWwoT2JqZWN0T3V0cHV0IG91dHB1dCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKLQkJb3V0cHV0LndyaXRlVVRGKGZOYW1lKTsKLQkJLyogd3JpdGUgY29udGVudCAqLwotCQlTdHJpbmcgY29udGVudCA9IG51bGw7Ci0JCWlmIChmQ29udGVudFN0cmluZyAhPSBudWxsKSB7Ci0JCQljb250ZW50ID0gZkNvbnRlbnRTdHJpbmc7Ci0JCX0gZWxzZSBpZiAoZkNvbnRlbnQgIT0gbnVsbCkgewotCQkJY29udGVudCA9IGZDb250ZW50LnRyaW0oKTsKLQkJfQotCQlpZiAoY29udGVudCAhPSBudWxsKSB7Ci0JCQlvdXRwdXQud3JpdGVCb29sZWFuKHRydWUpOwotCQkJb3V0cHV0LndyaXRlVVRGKGNvbnRlbnQpOwotCQl9IGVsc2UgewotCQkJb3V0cHV0LndyaXRlQm9vbGVhbihmYWxzZSk7Ci0JCX0KLQkJLyogd3JpdGUgYXR0cmlidXRlcyAqLwotCQlpZiAoZkF0dHJpYnV0ZXMgIT0gbnVsbCkgewotCQkJb3V0cHV0LndyaXRlSW50KGZBdHRyaWJ1dGVzLnNpemUoKSk7Ci0JCQlmb3IgKEVudW1lcmF0aW9uIGUgPSBmQXR0cmlidXRlcy5rZXlzKCk7IGUuaGFzTW9yZUVsZW1lbnRzKCk7KSB7Ci0JCQkJU3RyaW5nIGtleSA9IChTdHJpbmcpIGUubmV4dEVsZW1lbnQoKTsKLQkJCQlTdHJpbmcgdmFsID0gKFN0cmluZykgZkF0dHJpYnV0ZXMuZ2V0KGtleSk7Ci0JCQkJb3V0cHV0LndyaXRlVVRGKGtleSk7Ci0JCQkJb3V0cHV0LndyaXRlVVRGKHZhbCk7Ci0JCQl9Ci0JCX0gZWxzZSB7Ci0JCQlvdXRwdXQud3JpdGVJbnQoMCk7Ci0JCX0KLQkJLyogd3JpdGUgZWxlbWVudHMgKi8KLQkJaWYgKGZUYWdzICE9IG51bGwpIHsKLQkJCW91dHB1dC53cml0ZUludChmVGFncy5zaXplKCkpOwotCQkJZm9yIChpbnQgaSA9IDAsIHNpemUgPSBmVGFncy5zaXplKCk7IGkgPCBzaXplOyBpKyspIHsKLQkJCQlUYWdJbXBsIGN1cnJlbnQgPSAoVGFnSW1wbCkgZlRhZ3MuZWxlbWVudEF0KGkpOwotCQkJCWN1cnJlbnQud3JpdGVFeHRlcm5hbChvdXRwdXQpOwotCQkJfQotCQl9IGVsc2UgewotCQkJb3V0cHV0LndyaXRlSW50KDApOwotCQl9Ci0JCW91dHB1dC5mbHVzaCgpOwotCX0KLQotCS8qIGJlZ2luIHNpbXBsZSwgdXRpbGl0eSBtZXRob2QgZm9yIGRlYnVnZ2luZyAqLwotCi0JLyoqCi0JICogV3JpdGVzIHRoZSB0YWcgYXMgZm9ybWF0dGVkIFhNTCBpbnRvIHRoZSBnaXZlbiB3cml0ZXIuCi0JICogCi0JICogQHBhcmFtIG91dAotCSAqICAgICAgICAgICAgdGhlIG91dHB1dCB3cml0ZXIsIHdoZXJlIHRhZyBpcyBzZXJpYWxpemVkIHRvIFhNTAotCSAqIEBwYXJhbSBsZXZlbAotCSAqICAgICAgICAgICAgdGhlIGluaXRpYWwgbGV2ZWwuIElmIHNldCB0byBuZWdhdGl2ZSB2YWx1ZSwgdGhlIGluZGVudAotCSAqICAgICAgICAgICAgL2Zvcm1hdHRpbmcvIG9mIHRoZSBYTUwgaXMgZGlzYWJsZSwgYW5kIGl0IGlzIHdyaXR0ZW4gb24gYQotCSAqICAgICAgICAgICAgc2luZ2xlIGxpbmUuIE90aGVyd2lzZSwgdGhlIGxldmVsIGlzIHVzZWQgdG8gY2FsY3VsYXRlIHRoZQotCSAqICAgICAgICAgICAgb2Zmc2V0IGZyb20gdGhlIGxlZnQgbWFyZ2luLgotCSAqIEB0aHJvd3MgSU9FeGNlcHRpb24KLQkgKiAgICAgICAgICAgICBvbiBJL08gZXJyb3IKLQkgKi8KLQlwdWJsaWMgdm9pZCB3cml0ZVhtbChXcml0ZXIgb3V0LCBpbnQgbGV2ZWwpIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0JCWJvb2xlYW4gaW5kZW50ID0gbGV2ZWwgPj0gMDsKLQkJZm9yIChpbnQgaSA9IDA7IGluZGVudCAmJiBpIDwgbGV2ZWw7IGkrKykKLQkJCW91dC53cml0ZSgnICcpOyAvKiBpbmRlbnQgKi8KLQkJb3V0LndyaXRlKCc8Jyk7Ci0JCW91dC53cml0ZShmTmFtZSk7Ci0JCWlmIChmQXR0cmlidXRlcyAhPSBudWxsKSB7Ci0JCQlmb3IgKEVudW1lcmF0aW9uIGUgPSBmQXR0cmlidXRlcy5rZXlzKCk7IGUuaGFzTW9yZUVsZW1lbnRzKCk7KSB7Ci0JCQkJb3V0LndyaXRlKCcgJyk7Ci0JCQkJU3RyaW5nIGtleSA9IChTdHJpbmcpIGUubmV4dEVsZW1lbnQoKTsKLQkJCQlTdHJpbmcgdmFsID0gKFN0cmluZykgZkF0dHJpYnV0ZXMuZ2V0KGtleSk7Ci0JCQkJb3V0LndyaXRlKGtleSk7Ci0JCQkJb3V0LndyaXRlKCI9XCIiKTsKLQkJCQlvdXQud3JpdGUodmFsKTsKLQkJCQlvdXQud3JpdGUoJyInKTsKLQkJCX0KLQkJfQotCQkvKiBkb24ndCB1c2UgZ2V0Q29udGVudCgpIC0gdGhpcyB3aWxsIGRlbW9saXNoIHRoZSBidWZmZXIgKi8KLQkJU3RyaW5nIGNvbnRlbnQgPSBudWxsOwotCQlpZiAoZkNvbnRlbnRTdHJpbmcgIT0gbnVsbCkgewotCQkJY29udGVudCA9IGZDb250ZW50U3RyaW5nOwotCQl9IGVsc2UgaWYgKGZDb250ZW50ICE9IG51bGwpIHsKLQkJCWNvbnRlbnQgPSBmQ29udGVudC50cmltKCk7Ci0JCX0KLQkJYm9vbGVhbiBpc1Nob3J0ID0gY29udGVudCA9PSBudWxsICYmIGZUYWdzID09IG51bGw7Ci0JCWlmIChpc1Nob3J0KSB7Ci0JCQkvKiBjbG9zZSBpbW1lZGlhdGVseSAqLwotCQkJb3V0LndyaXRlKCIvPiIpOwotCQkJaWYgKGluZGVudCkKLQkJCQlvdXQud3JpdGUoJ1xuJyk7Ci0JCX0gZWxzZSB7Ci0JCQlvdXQud3JpdGUoJz4nKTsKLQkJCWlmIChpbmRlbnQpCi0JCQkJb3V0LndyaXRlKCdcbicpOwotCQkJLyogd3JpdGUgZWxlbWVudHMgKi8KLQkJCWZvciAoaW50IGkgPSAwOyBmVGFncyAhPSBudWxsICYmIGkgPCBmVGFncy5zaXplKCk7IGkrKykgewotCQkJCVRhZ0ltcGwgY2hpbGQgPSAoVGFnSW1wbCkgZlRhZ3MuZWxlbWVudEF0KGkpOwotCQkJCWNoaWxkLndyaXRlWG1sKG91dCwgbGV2ZWwgPCAwID8gLTEgOiAobGV2ZWwgKyAxKSk7Ci0JCQl9Ci0JCQkvKiB3cml0ZSBjb250ZW50cyAqLwotCQkJaWYgKGNvbnRlbnQgIT0gbnVsbCkgewotCQkJCWZvciAoaW50IGkgPSAwOyBpbmRlbnQgJiYgaSA8IGxldmVsICsgMTsgaSsrKQotCQkJCQlvdXQud3JpdGUoJyAnKTsgLyogaW5kZW50ICovCi0JCQkJb3V0LndyaXRlKGNvbnRlbnQpOwotCQkJCWlmIChpbmRlbnQpCi0JCQkJCW91dC53cml0ZSgnXG4nKTsKLQkJCX0KLQkJCS8qIHdyaXRlIGNsb3NpbmcgdGFnICovCi0JCQlmb3IgKGludCBpID0gMDsgaW5kZW50ICYmIGkgPCBsZXZlbDsgaSsrKQotCQkJCW91dC53cml0ZSgnICcpOyAvKiBpbmRlbnQgKi8KLQkJCW91dC53cml0ZSgiPC8iKTsKLQkJCW91dC53cml0ZShmTmFtZSk7Ci0JCQlvdXQud3JpdGUoJz4nKTsKLQkJCWlmIChpbmRlbnQpCi0JCQkJb3V0LndyaXRlKCdcbicpOwotCQl9Ci0JfQotCi0JLyoqCi0JICogQHNlZSBqYXZhLmxhbmcuT2JqZWN0I3RvU3RyaW5nKCkKLQkgKi8KLQlwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewotCQlTdHJpbmdXcml0ZXIgb3V0ID0gbmV3IFN0cmluZ1dyaXRlcigpOwotCQl0cnkgewotCQkJd3JpdGVYbWwob3V0LCAwKTsKLQkJfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewotCQkJLyogdGhpcyB3aWxsIG5ldmVyIGhhcHBlbiAqLwotCQl9Ci0JCXJldHVybiBvdXQudG9TdHJpbmcoKTsKLQl9Ci0KLX0KZGlmZiAtLWdpdCBhL2J1bmRsZXMvb3JnLmVjbGlwc2UuZXF1aW5veC5kcy9zcmMvb3JnL2VjbGlwc2UvZXF1aW5veC9pbnRlcm5hbC91dGlsL3htbC9pbXBsL1hNTFBhcnNlckltcGwuamF2YSBiL2J1bmRsZXMvb3JnLmVjbGlwc2UuZXF1aW5veC5kcy9zcmMvb3JnL2VjbGlwc2UvZXF1aW5veC9pbnRlcm5hbC91dGlsL3htbC9pbXBsL1hNTFBhcnNlckltcGwuamF2YQpkZWxldGVkIGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggNzM4NGE3OC4uMDAwMDAwMAotLS0gYS9idW5kbGVzL29yZy5lY2xpcHNlLmVxdWlub3guZHMvc3JjL29yZy9lY2xpcHNlL2VxdWlub3gvaW50ZXJuYWwvdXRpbC94bWwvaW1wbC9YTUxQYXJzZXJJbXBsLmphdmEKKysrIC9kZXYvbnVsbApAQCAtMSwxMjE5ICswLDAgQEAKLS8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCi0gKiBDb3B5cmlnaHQgKGMpIDE5OTcsIDIwMTAgYnkgUHJvU3lzdCBTb2Z0d2FyZSBHbWJICi0gKiBodHRwOi8vd3d3LnByb3N5c3QuY29tCi0gKiBBbGwgcmlnaHRzIHJlc2VydmVkLiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzCi0gKiBhcmUgbWFkZSBhdmFpbGFibGUgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIHYxLjAKLSAqIHdoaWNoIGFjY29tcGFuaWVzIHRoaXMgZGlzdHJpYnV0aW9uLCBhbmQgaXMgYXZhaWxhYmxlIGF0Ci0gKiBodHRwOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC12MTAuaHRtbAotICoKLSAqIENvbnRyaWJ1dG9yczoKLSAqICAgIFByb1N5c3QgU29mdHdhcmUgR21iSCAtIGluaXRpYWwgQVBJIGFuZCBpbXBsZW1lbnRhdGlvbgotICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi1wYWNrYWdlIG9yZy5lY2xpcHNlLmVxdWlub3guaW50ZXJuYWwudXRpbC54bWwuaW1wbDsKLQotaW1wb3J0IGphdmEuaW8uKjsKLWltcG9ydCBvcmcuZWNsaXBzZS5lcXVpbm94LmludGVybmFsLmRzLkFjdGl2YXRvcjsKLWltcG9ydCBvcmcuZWNsaXBzZS5lcXVpbm94LmludGVybmFsLnV0aWwuc3RyaW5nLkNoYXJCdWZmZXI7Ci1pbXBvcnQgb3JnLmVjbGlwc2UuZXF1aW5veC5pbnRlcm5hbC51dGlsLnhtbC5FeFRhZ0xpc3RlbmVyOwotCi0vKioKLSAqIDxwPgotICogQ2xhc3MgdXNlZCBmb3IgcmVhZGluZyBvZiB4bWwgZmlsZXMsIGNyZWF0aW5nIHRyZWUgc3RydWN0dXJlIG9mICdUYWdJbXBsJyBmb3IKLSAqIGVhY2ggeG1sIHRhZy4gV2hlbiByZWFkZXIgcmVhY2hlcyBhIGNsb3NlZCB0YWcgaXQgbm90aWZpZXMgYSBnaXZlbgotICogJ1RhZ0xpc3RlbmVyJyBhbmQgc2VuZHMgdGhlIGxhc3QgdGFnIHRvIGl0LiBJZiBjbG9zaW5nIHRhZyBkb2VzIG5vdAotICogY29ycmVzcG9uZCB3aXRoIHRoZSBsYXN0IG9wZW4gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlzIHRocm93bi4gVGhlcmUgaXMgYQotICogZGVidWcgcHJvcGVydHkgJ3htbC5kZWJ1ZycgdXNlZCB0byBkdW1wIGFuIEV4Y2VwdGlvbnMgb2NjdXJyZWQgd2hpbGUKLSAqIG9wZXJhdGlvbiBpcyBydW5uaW5nLgotICogPC9wPgotICogCi0gKiA8cD4KLSAqIFRoZSBwYXJzZXIsIGluIGdlbmVyYWwsIGlzIGEgc2ltcGxlIFhNTCBwYXJzZXIgdGhhdCBpbXBsZW1lbnRzCi0gKiAmcXVvdDtSZWN1cnNpdmUgZGVzY2VudCZxdW90OyBwYXJzaW5nIG1ldGhvZC4KLSAqIAotICogS25vd24gbGltaXRhdGlvbnM6PGJyPgotICogCi0gKiA8cHJlPgotICogIEN1cnJlbnRseSB0aGlzIFhNTFBhcnNlciBkb2VzIG5vdCBzdXBwb3J0IHRoZSBmb2xsb3dpbmcgc3BlY2lhbCB0YWdzOgotICogIDEuICZsdDs/VEFHX05BTUUgLi4uLi4gPyZndDsgICBvciBhbHNvICZxdW90O1Byb2Nlc3NpbmcgSW5zdHJ1Y3Rpb25zJnF1b3Q7Ci0gKiAgMi4gJmx0OyFET0NUWVBFIC4uLi4gJmd0OwotICogIDMuICZsdDshRUxFTUVOVCAuLi4uICZndDsKLSAqICA0LiAmbHQ7IUFUVExJU1QgLi4uLiAmZ3Q7Ci0gKiAgNS4gJmx0OyFFTlRJVFkgLi4uLiAmZ3Q7Ci0gKiA8L3ByZT4KLSAqIAotICogPGJyPgotICogVGhlIHBhcnNlciBza2lwcyB0aGVzZSB0YWdzIChpdCBzZWFyY2hlcyBmb3IgJz4nIHN5bWJvbCBhbmQgY2xvc2VzIHRoZQotICogJ3NwZWNpYWwnIHRhZykuPGJyPgotICogCi0gKiBAYXV0aG9yIEl2YW4gRGltaXRyb3YKLSAqIEBhdXRob3IgUGF2bGluIERvYnJldgotICogQHZlcnNpb24gMS4wCi0gKi8KLQotcHVibGljIGNsYXNzIFhNTFBhcnNlckltcGwgewotCi0JcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIERFQlVHID0gInhtbC5kZWJ1ZyI7Ci0JcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIElOVEVSTl9BVFRSSUJVVEVTID0gInhtbC5pbnRlcm4uYXR0cmlidXRlcyI7Ci0KLQlwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgQ0RBVEEgPSAiQ0RBVEEiOwotCXByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBYTUwgPSAieG1sIjsKLQlwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgVkVSU0lPTiA9ICJ2ZXJzaW9uIjsKLQlwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgRU5DT0RJTkcgPSAiZW5jb2RpbmciOwotCXByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBTVEFOREFMT05FID0gInN0YW5kYWxvbmUiOwotCi0JcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEVSUl9FT1MgPSAiRW5kLW9mLXN0cmVhbSByZWFjaGVkIGJlZm9yZSB0aGUgZW5kIG9mIFhNTC4iOwotCXByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBFUlJfRU5USVRZX0VYUEVDVEVEID0gIkVudGl0eSByZWZlcmVuY2Ugb3IgQ2hhcmFjdGVyIHJlZmVyZW5jZSBleHBlY3RlZC4iOwotCXByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBFUlJfRVFVQUxfRVhQRUNURUQgPSAiJz0nIGV4cGVjdGVkLiI7Ci0JcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEVSUl9RVU9UX0VYUEVDVEVEID0gIicnJyBvciAnXCInIGV4cGVjdGVkLiI7Ci0JcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEVSUl9HVF9FWFBFQ1RFRCA9ICInPicgZXhwZWN0ZWQuIjsKLQlwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJSX0xUX0VYUEVDVEVEID0gIic8JyBleHBlY3RlZC4iOwotCXByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBFUlJfQ0xPU0VfVEFHMV9FWFBFQ1RFRCA9ICInLycgb3IgdGFnIG5hbWUgZXhwZWN0ZWQuIjsKLQlwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJSX0NMT1NFX1RBRzJfRVhQRUNURUQgPSAiJz4nLCAnLz4nIG9yIG1vcmUgYXR0cmlidXRlcyBleHBlY3RlZC4iOwotCXByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBFUlJfQ0xPU0VfVEFHM19FWFBFQ1RFRCA9ICInPz4nIGV4cGVjdGVkLiI7Ci0JcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEVSUl9DT05URU5UX0VYUEVDVEVEID0gIkNvbnRlbnQgZGF0YSwgbmV3IHRhZyBvciBjbG9zaW5nIHRhZyBleHBlY3RlZC4iOwotCXByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBFUlJfUVVFU1RJT05NQVJLX0VYUEVDVEVEID0gIic/JyBleHBlY3RlZC4iOwotCXByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBFUlJfSUxMRUdBTF9DSEFSQUNURVIgPSAiSWxsZWdhbCBjaGFyYWN0ZXIuIjsKLQlwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJSX1RBR05BTUVfRVhQRUNURUQgPSAiVGFnIG5hbWUgZXhwZWN0ZWQuIjsKLQlwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJSX1RBR05BTUUyX0VYUEVDVEVEID0gIlRhZyBuYW1lLCAnPycgb3IgJyEnIGV4cGVjdGVkLiI7Ci0JcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEVSUl9EQVNIX0VYUEVDVEVEID0gIictJyBleHBlY3RlZC4iOwotCXByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBFUlJfQ09NTUVOVF9DTE9TRV9FWFBFQ1RFRCA9ICInLS0+JyBleHBlY3RlZC4iOwotCXByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBFUlJfQ0RBVEFfRVhQRUNURUQgPSAiJ0NEQVRBJyBleHBlY3RlZC4iOwotCXByaXZhdGUgc3RhdGljIGZpbmFsIFN0cmluZyBFUlJfT1BFTlNRQlJBQ0tFVF9FWFBFQ1RFRCA9ICInWycgZXhwZWN0ZWQuIjsKLQlwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJSX0NMT1NFX0NEQVRBX0VYUEVDVEVEID0gIiddXT4nIGV4cGVjdGVkLiI7Ci0JcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEVSUl9TRU1JQ09MT05fRVhQRUNURUQgPSAiJzsnIGV4cGVjdGVkLiI7Ci0JcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEVSUl9YTUxQUk9MT0dfRVhQRUNURUQgPSAiWE1MIHByb2xvZyAnPD94bWwnIGlzIG5vdCBleHBlY3RlZCBhdCB0aGlzIHBvc2l0aW9uLiI7Ci0JcHJpdmF0ZSBzdGF0aWMgZmluYWwgU3RyaW5nIEVSUl9WRVJTSU9OX0VYUEVDVEVEID0gIid2ZXJzaW9uJyBhdHRyaWJ1dGUgZXhwZWN0ZWQuIjsKLQlwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJSX0VOQ09ESU5HX1NUQU5EQUxPTkVfRVhQRUNURUQgPSAiJ2VuY29kaW5nJywgJ3N0YW5kYWxvbmUnIG9yICc/PicgZXhwZWN0ZWQuIjsKLQlwcml2YXRlIHN0YXRpYyBmaW5hbCBTdHJpbmcgRVJSX1NUQU5EQUxPTkVfRVhQRUNURUQgPSAiJ3N0YW5kYWxvbmUnIGF0dHJpYnV0ZSBleHBlY3RlZC4iOwotCi0JcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBib29sZWFuIGZEZWJ1ZyA9IEFjdGl2YXRvci5nZXRCb29sZWFuKERFQlVHKTsKLQlwcm90ZWN0ZWQgc3RhdGljIGZpbmFsIGJvb2xlYW4gZkludGVybkF0dHJpYnV0ZXMgPSBBY3RpdmF0b3IuZ2V0Qm9vbGVhbihJTlRFUk5fQVRUUklCVVRFUyk7Ci0KLQlwcml2YXRlIFN0cmluZyBmRGVmYXVsdEVuY29kaW5nID0gIlVURi04IjsKLQotCS8vIHByaXZhdGUgQ2hhckJ1ZmZlciBjOwotCXByaXZhdGUgQ2hhckJ1ZmZlciB0ZW1wID0gbmV3IENoYXJCdWZmZXIoKTsKLQlwcml2YXRlIENoYXJCdWZmZXIgdGVtcDIgPSBudWxsOwotCi0JcHJvdGVjdGVkIFJlYWRlciBmUmVhZGVyID0gbnVsbDsKLQlwcm90ZWN0ZWQgSW5wdXRTdHJlYW0gZlN0cmVhbSA9IG51bGw7Ci0KLQlwcm90ZWN0ZWQgY2hhciBjdXJyZW50Q2hhciA9IDA7Ci0JcHJvdGVjdGVkIEV4VGFnTGlzdGVuZXIgZkV4VGFnTGlzdGVuZXI7Ci0KLQlwcm90ZWN0ZWQgaW50IGZMaW5lID0gMTsKLQlwcm90ZWN0ZWQgaW50IGZQb3MgPSAwOwotCi0JcHJvdGVjdGVkIGludCBmTGV2ZWwgPSAtMTsKLQlwcm90ZWN0ZWQgaW50IGZDdXJyZW50TGV2ZWwgPSAxOwotCi0JcHJpdmF0ZSBTdHJpbmcgZlZlcnNpb24gPSAiMS4wIjsKLQlwcml2YXRlIFN0cmluZyBmRW5jb2RpbmcgPSAiVVRGLTgiOwotCXByaXZhdGUgU3RyaW5nIGZTdGFuZGFsb25lID0gInllcyI7Ci0KLQkvKioKLQkgKiBBbiBlbXB0eSBkZWZhdWx0IGNvbnN0cnVjdG9yCi0JICogCi0JICovCi0JcHVibGljIFhNTFBhcnNlckltcGwoKSB7Ci0JCS8vCi0JfQotCi0JLyoqCi0JICogQ29uc3RydWN0cyBhIG5ldyBYTUxSZWFkZXIuIDxicj4KLQkgKiA8YnI+Ci0JICogPGI+Tm90ZTogVGhlIFhNTFJlYWRlciBkb2VzIG5vdCBjbG9zZSB0aGUgcGFzc2VkIFJlYWRlciBvciBJbnB1dFN0cmVhbQotCSAqIAotCSAqIEBwYXJhbSBhSW5wdXRTdHJlYW0KLQkgKiAgICAgICAgICAgIGFuIElucHV0U3RyZWFtIHRvIHJlYWQgdGhlIFhNTCBmaWxlIGZyb20KLQkgKiBAcGFyYW0gYUxpc3RlbmVyCi0JICogICAgICAgICAgICBFeFRhZ0xpc3RlbmVyIHRoYXQgd2lsbCBiZSBub3RpZmllZCBvbiB0YWctb3BlbiBvciB0YWctY2xvc2UKLQkgKiAgICAgICAgICAgIGV2ZW50cwotCSAqIEB0aHJvd3MgSU9FeGNlcHRpb24KLQkgKi8KLQlwdWJsaWMgWE1MUGFyc2VySW1wbChJbnB1dFN0cmVhbSBhSW5wdXRTdHJlYW0sIEV4VGFnTGlzdGVuZXIgYUxpc3RlbmVyKSB7Ci0JCWZTdHJlYW0gPSBhSW5wdXRTdHJlYW07Ci0JCWZFeFRhZ0xpc3RlbmVyID0gYUxpc3RlbmVyOwotCX0KLQotCS8qKgotCSAqIENvbnN0cnVjdHMgYSBuZXcgWE1MUmVhZGVyLiA8YnI+Ci0JICogPGJyPgotCSAqIDxiPk5vdGU6IFRoZSBYTUxSZWFkZXIgZG9lcyBub3QgY2xvc2UgdGhlIHBhc3NlZCBSZWFkZXIgb3IgSW5wdXRTdHJlYW0KLQkgKiAKLQkgKiBAcGFyYW0gYVJlYWRlcgotCSAqICAgICAgICAgICAgYSBSZWFkZXIgdG8gcmVhZCB0aGUgWE1MIGZpbGUgZnJvbQotCSAqIEBwYXJhbSBhTGlzdGVuZXIKLQkgKiAgICAgICAgICAgIEV4VGFnTGlzdGVuZXIgdGhhdCB3aWxsIGJlIG5vdGlmaWVkIG9uIHRhZy1vcGVuIG9yIHRhZy1jbG9zZQotCSAqICAgICAgICAgICAgZXZlbnRzCi0JICovCi0JcHVibGljIFhNTFBhcnNlckltcGwoUmVhZGVyIGFSZWFkZXIsIEV4VGFnTGlzdGVuZXIgYUxpc3RlbmVyKSB7Ci0JCWZSZWFkZXIgPSBhUmVhZGVyOwotCQlmRXhUYWdMaXN0ZW5lciA9IGFMaXN0ZW5lcjsKLQl9Ci0KLQkvKioKLQkgKiBTZXRzIHRoZSBsZXZlbCBvZiB0YWdzIGJlbGxvdyB3aGljaCB0aGUgbGlzdGVuZXIgd2lsbCBiZSBub3RpZmllZCBmb3IuCi0JICogRm9yIGludGVybmFsIHVzZSBvbmx5LgotCSAqIAotCSAqIEBwYXJhbSBhTGV2ZWwKLQkgKi8KLQlwdWJsaWMgdm9pZCBzZXRMZXZlbChpbnQgYUxldmVsKSB7Ci0JCWZMZXZlbCA9IGFMZXZlbDsKLQl9Ci0KLQkvKioKLQkgKiBTZXRzIHRoZSBwYXJzZXIncyBlbmNvZGluZy4gSWYgdGhlcmUgaXMgYSBjdXJyZW50IGVuY29kaW5nIGFzc29jaWF0ZWQKLQkgKiB3aXRoIHRoZSBwYXJzZXIgdGhlIG1ldGhvZCByZXR1cm5zIGltbWVkaWF0ZWx5Ci0JICogCi0JICogQHBhcmFtIGFFbmNvZGluZwotCSAqICAgICAgICAgICAgbmV3IGVuY29kaW5nIHRvIGJlIHNldAotCSAqIEB0aHJvd3MgVW5zdXBwb3J0ZWRFbmNvZGluZ0V4Y2VwdGlvbgotCSAqICAgICAgICAgICAgIGlmIHRoZSBlbmNvZGluZyBpcyBub3Qgc3VwcG9ydGVkLgotCSAqLwotCXByb3RlY3RlZCB2b2lkIHNldEVuY29kaW5nKFN0cmluZyBhRW5jb2RpbmcpIHsKLQkJaWYgKGZSZWFkZXIgPT0gbnVsbCkgewotCQkJdHJ5IHsKLQkJCQlmUmVhZGVyID0gbmV3IElucHV0U3RyZWFtUmVhZGVyKGZTdHJlYW0sIGFFbmNvZGluZyk7Ci0JCQl9IGNhdGNoIChFeGNlcHRpb24gZSkgewotCQkJCWlmIChmRGVidWcpIHsKLQkJCQkJU3lzdGVtLmVyci5wcmludGxuKCJbWE1MUGFyc2VySW1wbF0gRmFpbGVkIHNldHRpbmcgdGhlIGVuY29kaW5nIFwiIiArIGFFbmNvZGluZyArICJcIiwgY29udGludWUgcGFyc2luZyB3aXRoIHRoZSBkZWZhdWx0IG9uZS4iKTsKLQkJCQl9Ci0JCQkJZlJlYWRlciA9IG5ldyBJbnB1dFN0cmVhbVJlYWRlcihmU3RyZWFtKTsKLQkJCX0KLQkJfQotCX0KLQotCS8qIEEgaGVscGVyIGZ1bmN0aW9uIHRvIHJldXNlIGEgdGVtcCBDaGFyQnVmZmVycyB3aXRob3V0IHJlY3JlYXRpbmcgaXQgKi8KLQlwcm90ZWN0ZWQgQ2hhckJ1ZmZlciBnZXRDaGFyQnVmZmVyKCkgewotCQlpZiAodGVtcC5sZW5ndGgoKSA8PSAwKSB7Ci0JCQlyZXR1cm4gdGVtcDsKLQkJfSBlbHNlIGlmICh0ZW1wMiA9PSBudWxsKSB7Ci0JCQl0ZW1wMiA9IG5ldyBDaGFyQnVmZmVyKDApOwotCQkJcmV0dXJuIHRlbXAyOwotCQl9IGVsc2UgaWYgKHRlbXAyLmxlbmd0aCgpIDw9IDApIHsKLQkJCXJldHVybiB0ZW1wMjsKLQkJfQotCQlyZXR1cm4gbmV3IENoYXJCdWZmZXIoMCk7Ci0JfQotCi0JcHJvdGVjdGVkIGNoYXIgcHJldl9jaGFyID0gMDsKLQlwcml2YXRlIGNoYXJbXSBmQnVmZmVyID0gbmV3IGNoYXJbNDA5Nl07Ci0JcHJpdmF0ZSBpbnQgZkJ1ZmZlckxlbiA9IDA7Ci0JcHJpdmF0ZSBpbnQgZkJ1ZmZlclBvcyA9IDA7Ci0KLQkvKioKLQkgKiBSZWFkcyB0aGUgbmV4dCBjaGFyIGZyb20gdGhlIGlucHV0IHN0cmVhbSBhbmQgc2V0cyBpdCB0byBwcml2YXRlIGZpZWxkCi0JICogPGNvZGU+Y3VycmVudENoYXI8L2NvZGU+Ci0JICogCi0JICogQHJldHVybiB0cnVlIGlmIHRoZSBuZXh0IGNoYXIgaXMgc3VjY2Vzc2Z1bGx5IHJlYWQgb2YgZmFsc2UgaWYKLQkgKiAgICAgICAgIEVuZC1PZi1TdHJlYW0gaXMgcmVhY2hlZAotCSAqIEB0aHJvd3MgSU9FeGNlcHRpb24KLQkgKiAgICAgICAgICAgICBpZiBzb21lIGVycm9yIG9jY3VycyBkdXJpbmcgcmVhZGluZyB0aGUgY2hhcmFjdGVyIG9yIGlmIHRoZQotCSAqICAgICAgICAgICAgIGNhbGxlciB0cmllcyB0byByZWFkIGJleW9uZCB0aGUgRW5kLU9mLVN0cmVhbS4KLQkgKi8KLQlwcm90ZWN0ZWQgYm9vbGVhbiBnZXROZXh0Q2hhcigpIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0JCS8vIC8vIFJlYWRpbmcgY2hhcmFjdGVycyB3aXRob3V0IGJ1ZmZlcmluZwotCQkvLyBpbnQgaWNoYXIgPSAwOwotCQkvLyBpbnQgY291bnQgPSAwOwotCQkvLyB3aGlsZSAoaWNoYXIgPT0gMCAmJiBjb3VudCA8IDEwMCkgewotCQkvLyBpY2hhciA9IGZSZWFkZXIucmVhZCgpOwotCQkvLyBjb3VudCsrOwotCQkvLyB9Ci0JCS8vICAgIAotCQkvLyBpZiAoaWNoYXIgPT0gMCkKLQkJLy8gdGhyb3cgbmV3IElPRXhjZXB0aW9uKCJGYWlsZWQgdG8gcmVhZCBmcm9tIHRoZSBpbnB1dCBmaWxlLiIpOwotCQkvLyAgICAKLQkJLy8gaWYgKGljaGFyIDwgMCAmJiBwcmV2X2NoYXIgPT0gMCkKLQkJLy8gdGhyb3cgbmV3IElPRXhjZXB0aW9uKEVSUl9FT1MpOwotCQkvLyAgICAKLQkJLy8gY2hhciBjaCA9IChjaGFyKSBpY2hhcjsKLQotCQljaGFyIGNoOwotCi0JCWlmIChmUmVhZGVyID09IG51bGwpIHsgLy8gSWYgdGhlcmUgaXMgbm8gYXNzb2NpYXRlZCByZWFkZXIsCi0JCQlpbnQgYWNoID0gZlN0cmVhbS5yZWFkKCk7IC8vIHRoZW4gcmVhZHMgZnJvbSB0aGUgSW5wdXRTdHJlYW0gdW50aWwKLQkJCWlmIChhY2ggPCAwKSB7IC8vIHRoZSByaWd0aCBlbmNvZGluZyBpcyByZWNvZ25pemVkCi0JCQkJYWNoID0gMDsKLQkJCX0KLQotCQkJY2ggPSAoY2hhcikgYWNoOwotCQkJaWYgKGNoID09IDAgJiYgcHJldl9jaGFyID09IDApIHsKLQkJCQl0aHJvdyBuZXcgSU9FeGNlcHRpb24oRVJSX0VPUyk7Ci0JCQl9Ci0JCX0gZWxzZSB7Ci0JCQkvLyBCdWZmZXJlZCByZWFkaW5nCi0JCQlpZiAoZkJ1ZmZlckxlbiA8IDApIHsKLQkJCQl0aHJvdyBuZXcgSU9FeGNlcHRpb24oRVJSX0VPUyk7Ci0JCQl9Ci0KLQkJCWlmICgoZkJ1ZmZlclBvcykgPj0gZkJ1ZmZlckxlbikgewotCQkJCS8vIFJlZmV0Y2ggdGhlIGJ1ZmZlcgotCQkJCWZCdWZmZXJMZW4gPSAwOwotCQkJCWZCdWZmZXJQb3MgPSAwOwotCQkJCWludCBjb3VudCA9IDA7Ci0JCQkJd2hpbGUgKGZCdWZmZXJMZW4gPT0gMCAmJiBjb3VudCA8IDEwMCkgewotCQkJCQlmQnVmZmVyTGVuID0gZlJlYWRlci5yZWFkKGZCdWZmZXIpOwotCQkJCQljb3VudCsrOwotCQkJCX0KLQotCQkJCWNoID0gKGZCdWZmZXJMZW4gPiAwKSA/IGZCdWZmZXJbZkJ1ZmZlclBvcysrXSA6IDA7Ci0KLQkJCQlpZiAoZkJ1ZmZlckxlbiA9PSAwKSB7Ci0JCQkJCWZCdWZmZXJMZW4gPSAtMTsKLQkJCQl9Ci0JCQl9IGVsc2UgewotCQkJCWNoID0gZkJ1ZmZlcltmQnVmZmVyUG9zKytdOwotCQkJfQotCQl9Ci0KLQkJcHJldl9jaGFyID0gY3VycmVudENoYXI7Ci0JCWN1cnJlbnRDaGFyID0gY2g7Ci0JCWZQb3MrKzsKLQotCQlzd2l0Y2ggKGNoKSB7Ci0JCQljYXNlICdcbicgOgotCQkJCWlmIChwcmV2X2NoYXIgIT0gJ1xyJykgewotCQkJCQlmTGluZSsrOwotCQkJCX0KLQkJCQlmUG9zID0gMDsKLQkJCQlicmVhazsKLQkJCWNhc2UgJ1xyJyA6Ci0JCQkJZlBvcyA9IDA7Ci0JCQkJZkxpbmUrKzsKLQkJCQlicmVhazsKLQkJfQotCQlyZXR1cm4gKGN1cnJlbnRDaGFyICE9IDApOwotCX0KLQotCS8qKgotCSAqIFBhcnNlcyB0aGUgYXR0cmlidXRlIHZhbHVlIGFuZCBpZiBpdCdzIHN1Y2Nlc3NmdWwgdGhlbiBhZGRzIGl0IHRvIHRoZQotCSAqIENoYXJCdWZmZXIuIElmIHRoZXJlIGFyZSBFbnRpdHlSZWZlcmVuY2VzIG9mIENoYXJSZWZlcmVuY2VzIGluIHRoZQotCSAqIGF0dHJpYnV0ZSB2YWx1ZSwgdGhleSB3aWxsIGJlIHR1cm5lZCB0byB0aGVpciBlcXVpdmFsZW50IHN5bWJvbHMuPGJyPgotCSAqIGF0dHJfdmFsdWUgOjo9IChhY2NlcHRhYmxlX2NoYXIgfCBFbnRpdHlSZWYgfCBDaGFyUmVmKSogLSBxdW90X3N5bWJvbAotCSAqIAotCSAqIEBzZWUgcGFyc2VfYXR0cgotCSAqIEBzZWUgcGFyc2VfQ2hhclJlZgotCSAqIEBzZWUgcGFyc2VfRW50aXR5UmVmCi0JICovCi0JcHJvdGVjdGVkIHZvaWQgcGFyc2VfYXR0cl92YWx1ZShDaGFyQnVmZmVyIHNiLCBjaGFyIHF1b3QpIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0JCXdoaWxlIChjdXJyZW50Q2hhciAhPSBxdW90ICYmIGN1cnJlbnRDaGFyICE9ICc8JykgewotCQkJaWYgKGFjY2VwdF9jaGFyKCcmJykpIHsKLQkJCQlpZiAoIXBhcnNlX0NoYXJSZWYoc2IpKSB7Ci0JCQkJCWlmICghcGFyc2VfRW50aXR5UmVmKHNiKSkgewotCQkJCQkJZXJyKGZQb3MgLSAxLCBFUlJfRU5USVRZX0VYUEVDVEVEKTsKLQkJCQkJfQotCQkJCX0KLQkJCX0gZWxzZSB7Ci0JCQkJc2IuYXBwZW5kKGN1cnJlbnRDaGFyKTsKLQotCQkJCWlmICghZ2V0TmV4dENoYXIoKSkgewotCQkJCQlicmVhazsKLQkJCQl9Ci0JCQl9Ci0JCX0KLQl9Ci0KLQkvKioKLQkgKiBQYXJzZXMgYW4gYXR0cmlidXRlIHdpdGggdGhlIGdpdmVuIHNpbXBsaWZpZWQgZ3JhbW1hcjo8YnI+Ci0JICogCi0JICogPHByZT4KLQkgKiBhdHRyaWJ1dGUgOjo9IFMqICsgYXR0cl9uYW1lICsgUyogKyAnPScgKyBTKiArICgnXCcnICsgKGF0dHJfdmFsdWUgLSAnXCcnKSArICdcJycpKSB8ICgnJnF1b3Q7JyArIChhdHRyX3ZhbHVlIC0gJyZxdW90OycpICsgJyZxdW90OycpKQotCSAqIGF0dHJfdmFsdWUgOjo9IChhY2NlcHRhYmxlX2NoYXIgfCBFbnRpdHlSZWYgfCBDaGFyUmVmKSoKLQkgKiBhdHRyX25hbWUgOjo9IGlkZW50aWZpZXIKLQkgKiA8L3ByZT4KLQkgKiAKLQkgKiBAcGFyYW0gYVBhcmVudAotCSAqICAgICAgICAgICAgdGhlIHBhcmVudCB0YWcgd2hlcmUgdGhlIGNvcnJlY3RseSBwYXJzZWQgYXR0cmlidXRlIHdpbGwgYmUKLQkgKiAgICAgICAgICAgIGFkZGVkCi0JICogQHRocm93cyBJT0V4Y2VwdGlvbgotCSAqIEBzZWUgcGFyc2VfaWRlbnRpZmllcgotCSAqIEBzZWUgcGFyc2VfYXR0cl92YWx1ZQotCSAqLwotCXByb3RlY3RlZCBib29sZWFuIHBhcnNlX2F0dHIoVGFnSW1wbCBhUGFyZW50KSB0aHJvd3MgSU9FeGNlcHRpb24gewotCQljbGVhcldoaXRlU3BhY2VzKCk7Ci0KLQkJU3RyaW5nIGF0dHJOYW1lID0gcGFyc2VfaWRlbnRpZmllcigpOwotCi0JCWlmIChhdHRyTmFtZSAhPSBudWxsKSB7Ci0JCQljbGVhcldoaXRlU3BhY2VzKCk7Ci0KLQkJCWlmICghYWNjZXB0X2NoYXIoJz0nKSkgewotCQkJCWVycihFUlJfRVFVQUxfRVhQRUNURUQpOwotCQkJfQotCi0JCQljbGVhcldoaXRlU3BhY2VzKCk7Ci0KLQkJCWNoYXIgcXVvdCA9IDA7Ci0JCQlpZiAoYWNjZXB0X2NoYXIoJyInKSkgewotCQkJCXF1b3QgPSAnIic7Ci0JCQl9IGVsc2UgaWYgKGFjY2VwdF9jaGFyKCdcJycpKSB7Ci0JCQkJcXVvdCA9ICdcJyc7Ci0JCQl9IGVsc2UgewotCQkJCWVycihFUlJfUVVPVF9FWFBFQ1RFRCk7Ci0JCQl9Ci0KLQkJCUNoYXJCdWZmZXIgc2IgPSBnZXRDaGFyQnVmZmVyKCk7Ci0JCQlwYXJzZV9hdHRyX3ZhbHVlKHNiLCBxdW90KTsKLQotCQkJaWYgKCFhY2NlcHRfY2hhcihxdW90KSkgewotCQkJCWVycigiJyIgKyBxdW90ICsgIicgZXhwZWN0ZWQuIik7Ci0JCQl9Ci0KLQkJCVN0cmluZyBhdHRyVmFsdWUgPSBzYi50b1N0cmluZygpOwotCi0JCQlpZiAoZkludGVybkF0dHJpYnV0ZXMpIHsKLQkJCQlhdHRyVmFsdWUgPSBhdHRyVmFsdWUuaW50ZXJuKCk7Ci0JCQl9Ci0KLQkJCWFQYXJlbnQuYWRkQXR0cmlidXRlKGF0dHJOYW1lLCBhdHRyVmFsdWUpOwotCQkJc2Iuc2V0TGVuZ3RoKDApOwotCQkJcmV0dXJuIHRydWU7Ci0JCX0KLQkJcmV0dXJuIGZhbHNlOwotCX0KLQotCS8qKgotCSAqIFBhcnNlcyBhIHRhZyBhdHRyaWJ1dGUgbGlzdCB3aXRoIHRoZSBmb2xsb3dpbmcgc2ltcGxpZmllZCBncmFtbWFyOgotCSAqIAotCSAqIDxwcmU+Ci0JICogYXR0cl9saXN0IDo6PSBhdHRyaWJ1dGUqCi0JICogQHBhcmFtIGFQYXJlbnQgdGhlIHBhcmVudCB0YWcgdGhhdCB0aGUgcGFyc2VkIGF0dHJpYnV0ZXMgd2lsbCBiZSBhZGRlZCB0bwotCSAqIEByZXR1cm4gdHJ1ZSBpZiBhdCBsZWFzdCBvbmUgYXR0cmlidXRlIGlzIHBhcnNlZCBjb3JyZWN0bHkgYW5kIGZhbHNlIG90aGVyd2lzZQotCSAqIEB0aHJvd3MgSU9FeGNlcHRpb24KLQkgKiBAc2VlIHBhcnNlX2F0dHIKLQkgKiAKLQkgKi8KLQlwcm90ZWN0ZWQgYm9vbGVhbiBwYXJzZV9hdHRyX2xpc3QoVGFnSW1wbCBhUGFyZW50KSB0aHJvd3MgSU9FeGNlcHRpb24gewotCQlib29sZWFuIHJlc3VsdCA9IGZhbHNlOwotCQl3aGlsZSAocGFyc2VfYXR0cihhUGFyZW50KSkgewotCQkJcmVzdWx0ID0gdHJ1ZTsKLQkJfQotCQlyZXR1cm4gcmVzdWx0OwotCX0KLQotCXByaXZhdGUgc3RhdGljIGZpbmFsIGNoYXIgYkEgPSAnQScgLSAxOwotCXByaXZhdGUgc3RhdGljIGZpbmFsIGNoYXIgYVogPSAnWicgKyAxOwotCXByaXZhdGUgc3RhdGljIGZpbmFsIGNoYXIgYmEgPSAnYScgLSAxOwotCXByaXZhdGUgc3RhdGljIGZpbmFsIGNoYXIgYXogPSAneicgKyAxOwotCXByaXZhdGUgc3RhdGljIGZpbmFsIGNoYXIgYjAgPSAnMCcgLSAxOwotCXByaXZhdGUgc3RhdGljIGZpbmFsIGNoYXIgYTkgPSAnOScgKyAxOwotCi0JLyoqCi0JICogVGhpcyBtZXRob2QgcmV0dXJucyB0cnVlIGlzIHRoZSBwYXNzZWQgY2hhcmFjdGVyIG1heSBiZSB1c2VkIGFzIHN0YXJ0aW5nCi0JICogY2hhcmFjdGVyIGZvciB0YWcgbmFtZSBhbmQgYXR0cmlidXRlIG5hbWUKLQkgKiAKLQkgKiBAcGFyYW0gY2gKLQkgKiAgICAgICAgICAgIHRoZSB0ZXN0ZWQgY2hhcmFjdGVyCi0JICogQHJldHVybiB0cnVlIGlmIHRoZSBjaGFyYWN0ZXIgY291bGQgYmUgdXNlZCBhcyBzdGFydGluZyBjaGFyYWN0ZXIgZm9yIGEKLQkgKiAgICAgICAgIHRhZyBuYW1lIGFuZCBhbiBhdHRyaWJ1dGUgbmFtZSBhbmQgZmFsc2Ugb3RoZXJ3aXNlCi0JICovCi0JcHJvdGVjdGVkIGZpbmFsIGJvb2xlYW4gaXNOYW1lU3RhcnRDaGFyKGNoYXIgY2gpIHsKLQkJcmV0dXJuIChjaCA+IGJBICYmIGNoIDwgYVopIHx8IChjaCA+IGJhICYmIGNoIDwgYXopIHx8IChjaCA9PSAnOicpIHx8IChjaCA9PSAnXycpIHx8IChjaCA+IDB4QkYgJiYgY2ggPCAweEQ3KSB8fCAoY2ggPiAweEQ3ICYmIGNoIDwgMHhGNykgfHwgKGNoID4gMHhGNyAmJiBjaCA8IDB4MzAwKSB8fCAoY2ggPiAweDM2RiAmJiBjaCA8IDB4MzdFKSB8fCAoY2ggPiAweDM3RSAmJiBjaCA8IDB4MjAwMCkgfHwgKGNoID4gMHgyMDBCICYmIGNoIDwgMHgyMDBFKSB8fCAoY2ggPiAweDIwNkYgJiYgY2ggPCAweDIxOTApIHx8IChjaCA+IDB4MkJGRiAmJiBjaCA8IDB4MkZGMCkgfHwgKGNoID4gMHgzMDAwICYmIGNoIDwgMHhEODAwKSB8fCAoY2ggPiAweEY5MDAgJiYgY2ggPCAweEZERDApIHx8IChjaCA+IDB4RkRFRiAmJiBjaCA8IDB4RkZGRSkgfHwgKGNoID4gMHgwRkZGRiAmJiBjaCA8IDB4RjAwMDApOwotCX0KLQotCS8qKgotCSAqIFRoaXMgbWV0aG9kIHJldHVybnMgdHJ1ZSBpZiB0aGUgcGFzc2VkIGNoYXJhY3RlZCBtYXkgYmUgdXNlZCBhcyBwYXJ0IG9mIGEKLQkgKiB0YWcgbmFtZSBvciBhbiBhdHRyaWJ1dGUgbmFtZQotCSAqIAotCSAqIEBwYXJhbSBjaAotCSAqICAgICAgICAgICAgdGhlIHRlc3RlZCBjaGFyYWN0ZXIKLQkgKiBAcmV0dXJuIHRydWUgaXMgdGhlIGNoYXJhY3RlZCBjb3VsZCBiZSB1c2VkIGFzIHBhcnQgb2YgYSB0YWcgbmFtZSBvciBhbgotCSAqICAgICAgICAgYXR0cmlidXRlIG5hbWUgYW5kIGZhbHNlIG90aGVyd2lzZQotCSAqLwotCXByb3RlY3RlZCBmaW5hbCBib29sZWFuIGlzTmFtZUNoYXIoY2hhciBjaCkgewotCQlyZXR1cm4gKGNoID09ICctJykgfHwgKGNoID09ICcuJykgfHwgKGNoID09IDB4QjcpIHx8IChjaCA+IGIwICYmIGNoIDwgYTkpIHx8IGlzTmFtZVN0YXJ0Q2hhcihjaCkgfHwgKGNoID4gMHgwMkZGICYmIGNoIDwgMHgwMzcwKSB8fCAoY2ggPiAweDIwM0UgJiYgY2ggPCAweDIwNDEpOwotCX0KLQotCS8qKgotCSAqIFBhcnNlcyBhbiBpZGVudGlmaWVyLgotCSAqIAotCSAqIEByZXR1cm4gYW4gaWRlbnRpZmllciBpZiBpdCBpcyBwYXJzZWQgc3VjY2Vzc2Z1bGx5IGFuZCBudWxsIG90aGVyd2lzZQotCSAqIEB0aHJvd3MgSU9FeGNlcHRpb24KLQkgKi8KLQlwcm90ZWN0ZWQgU3RyaW5nIHBhcnNlX2lkZW50aWZpZXIoKSB0aHJvd3MgSU9FeGNlcHRpb24gewotCQlpZiAoaXNOYW1lU3RhcnRDaGFyKGN1cnJlbnRDaGFyKSkgewotCQkJQ2hhckJ1ZmZlciBzYiA9IGdldENoYXJCdWZmZXIoKTsKLQotCQkJd2hpbGUgKGlzTmFtZUNoYXIoY3VycmVudENoYXIpKSB7Ci0JCQkJc2IuYXBwZW5kKGN1cnJlbnRDaGFyKTsKLQotCQkJCWlmICghZ2V0TmV4dENoYXIoKSkgewotCQkJCQlicmVhazsKLQkJCQl9Ci0JCQl9Ci0JCQlTdHJpbmcgcmVzdWx0ID0gc2IudG9TdHJpbmcoKS5pbnRlcm4oKTsKLQkJCXNiLnNldExlbmd0aCgwKTsKLQkJCXJldHVybiByZXN1bHQ7Ci0JCX0KLQkJcmV0dXJuIG51bGw7Ci0JfQotCi0JLyoqCi0JICogUGFyc2VzIGEgdGFnIG5hbWUgYW5kIGlmIGl0IGlzIHN1Y2Nlc3NmdWxseSBwYXJzZWQgdGhlIG1ldGhvZCBzZXRzIGl0IGFzCi0JICogYSBuYW1lIG9mIHRoZSBwYXJlbnQgdGFnCi0JICogCi0JICogQHBhcmFtIGFQYXJlbnQKLQkgKiAgICAgICAgICAgIHBhcmVudCB0YWcKLQkgKiBAcmV0dXJuIHRydWUgaWYgdGhlIG5hbWUgaXMgcGFyc2VkIHN1Y2Nlc3NmdWxseSBhbmQgZmFsc2Ugb3RoZXJ3aXNlCi0JICogQHRocm93cyBJT0V4Y2VwdGlvbgotCSAqIEBzZWUgcGFyc2VfaWRlbnRpZmllcgotCSAqLwotCXByb3RlY3RlZCBib29sZWFuIHBhcnNlX3RhZ19uYW1lKFRhZ0ltcGwgYVBhcmVudCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKLQkJU3RyaW5nIG5hbWUgPSBwYXJzZV9pZGVudGlmaWVyKCk7Ci0JCWlmIChuYW1lICE9IG51bGwpIHsKLQkJCWFQYXJlbnQuc2V0TmFtZShuYW1lKTsKLQkJfQotCQlyZXR1cm4gbmFtZSAhPSBudWxsOwotCX0KLQotCS8qKgotCSAqIEhlbHBlciBmdW5jdGlvbiB0aGF0IG5vdGlmeSBsaXN0ZW5lcnMgZGVwZW5kaW5nIG9uIGNlcnRhaW4gY29uZGl0aW9ucwotCSAqIHN1Y2ggYXMgaWYgdGhlIHRhZyBldmVudCBpcyBvbi1jbG9zZSBvciBvbi1vcGVuCi0JICogCi0JICogQHBhcmFtIGFUYWcKLQkgKiAgICAgICAgICAgIFRoZSB0YWcgdGhhdCB0aGUgbm90aWZpY2F0aW9uIGV2ZW50IGlzIHZhbGlkIGZvci4KLQkgKiBAcGFyYW0gaXNTdGFydAotCSAqICAgICAgICAgICAgdHJ1ZSBpZiB0aGUgZXZlbnQgaXMgb24tb3BlbiBhbmQgZmFsc2UgaWYgaXQgaXMgb24tY2xvc2UKLQkgKi8KLQlwcm90ZWN0ZWQgdm9pZCBub3RpZnlMaXN0ZW5lcnMoVGFnSW1wbCBhVGFnLCBib29sZWFuIGlzU3RhcnQpIHsKLQkJdHJ5IHsKLQkJCWlmIChpc1N0YXJ0KSB7Ci0JCQkJZkV4VGFnTGlzdGVuZXIuc3RhcnRUYWcoYVRhZyk7Ci0JCQl9IGVsc2UgewotCQkJCWZFeFRhZ0xpc3RlbmVyLmVuZFRhZyhhVGFnKTsKLQkJCX0KLQkJfSBjYXRjaCAoUnVudGltZUV4Y2VwdGlvbiByZSkgewotCQkJaWYgKGZEZWJ1ZykgewotCQkJCVN5c3RlbS5lcnIucHJpbnRsbigiQW4gb3V0c2lkZSBleGNlcHRpb24gb2NjdXJyZWQgd2hpbGUgcHJvY2Vzc2luZyBhIHRhZyBvbiBsaW5lICIgKyBhVGFnLmdldExpbmUoKSArICIsIHRoZSB0YWcgbmFtZSBpczogIiArIGFUYWcuZ2V0TmFtZSgpKTsKLQkJCQlyZS5wcmludFN0YWNrVHJhY2UoU3lzdGVtLmVycik7Ci0JCQl9Ci0JCQl0aHJvdyByZTsKLQkJfQotCX0KLQotCS8qKgotCSAqIFBhcnNlcyBhIG5vcm1hbCB0YWcuIFRoZXJlIGFyZSB0d28gY2FzZXMgLSAoMSkgdGhlIHRhZyBoYXMgc2VwYXJhdGUgb3BlbgotCSAqIGFuZCBjbG9zZSB0YWcgZWxlbWVudHMgYW5kICgyKSB0aGUgdGFnIGlzIHNpbXBsZSBzdWNoYXMgJmx0O3RhZ19uYW1lIC4uLgotCSAqIC8mZ3Q7Ci0JICogCi0JICogQHBhcmFtIGFQYXJlbnQKLQkgKiAgICAgICAgICAgIFRoZSBwYXJlbnQgdGFnIHRoYXQgdGhpcyB0YWcgd2lsbCBiZSBhZGRlZCB0byBpZiB0aGUgcGFyc2luZwotCSAqICAgICAgICAgICAgaXMgc3VjY2Vzc2Z1bAotCSAqIEByZXR1cm4gdHJ1ZSBvbiBzdWNjZXNzIGFuZCBmYWxzZSBvdGhlcndpc2UKLQkgKiBAdGhyb3dzIElPRXhjZXB0aW9uCi0JICogQHNlZSBjbGVhcldoaXRlU3BhY2VzCi0JICogQHNlZSBwYXJzZV90YWdfbmFtZQotCSAqIEBzZWUgcGFyc2VfYXR0cl9saXN0Ci0JICogQHNlZSBub3RpZnlMaXN0ZW5lcnMKLQkgKiBAc2VlIGFjY2VwdF9jaGFyCi0JICogQHNlZSBhY2NlcHRfc2VxCi0JICogQHNlZSBwYXJzZV9QQ0RBVEEKLQkgKi8KLQlwcm90ZWN0ZWQgYm9vbGVhbiBwYXJzZV90YWdfbm9ybWFsKFRhZ0ltcGwgYVBhcmVudCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKLQkJLy8gTG9va2luZyBmb3IgYSB0YWdfbmFtZSAoaWRlbnRpZmllcikKLQkJaWYgKGlzTmFtZVN0YXJ0Q2hhcihjdXJyZW50Q2hhcikpIHsKLQkJCVRhZ0ltcGwgdGFnID0gbmV3IFRhZ0ltcGwoKTsKLQkJCXRhZy5zZXRMaW5lKGZMaW5lKTsKLQotCQkJcGFyc2VfdGFnX25hbWUodGFnKTsKLQkJCXBhcnNlX2F0dHJfbGlzdCh0YWcpOwotCi0JCQljbGVhcldoaXRlU3BhY2VzKCk7Ci0KLQkJCWlmIChhY2NlcHRfY2hhcignLycpKSB7Ci0JCQkJaWYgKCFhY2NlcHRfY2hhcignPicpKSB7Ci0JCQkJCWVycihFUlJfR1RfRVhQRUNURUQpOwotCQkJCX0KLQkJCQlhUGFyZW50LmFkZFRhZyh0YWcpOwotCi0JCQkJaWYgKChmTGV2ZWwgPD0gMCB8fCBmTGV2ZWwgPT0gZkN1cnJlbnRMZXZlbCkpIHsKLQkJCQkJbm90aWZ5TGlzdGVuZXJzKHRhZywgdHJ1ZSk7Ci0JCQkJCW5vdGlmeUxpc3RlbmVycyh0YWcsIGZhbHNlKTsKLQkJCQl9Ci0KLQkJCQlyZXR1cm4gdHJ1ZTsKLQkJCX0gZWxzZSBpZiAoYWNjZXB0X2NoYXIoJz4nKSkgewotCi0JCQkJbm90aWZ5TGlzdGVuZXJzKHRhZywgdHJ1ZSk7Ci0KLQkJCQl3aGlsZSAodHJ1ZSkgewotCQkJCQljbGVhcldoaXRlU3BhY2VzKCk7Ci0JCQkJCWludCBwb3MgPSBmUG9zOwotCQkJCQlpZiAoY3VycmVudENoYXIgPT0gJzwnKSB7IC8vIE5vcm1hbCB0YWcsIFNwZWNpYWwgdGFnIG9yCi0JCQkJCQkvLyBjbG9zaW5nIHRhZwotCQkJCQkJaWYgKCFwYXJzZV90YWcodGFnKSkgeyAvLyBJdCBtYXkgYmUgYSBzcGVjaWFsIHRhZy4KLQkJCQkJCQlpZiAoIWFjY2VwdF9jaGFyKCcvJykpIHsKLQkJCQkJCQkJZXJyKHBvcyArIDEsIEVSUl9DTE9TRV9UQUcxX0VYUEVDVEVEKTsKLQkJCQkJCQl9Ci0KLQkJCQkJCQkvLyB0cnlpbmcgdG8gYWNjZXB0OiB0YWdfbmFtZSArIFMqICsgJz4nCi0JCQkJCQkJcG9zID0gZlBvczsKLQkJCQkJCQlpZiAoIWFjY2VwdF9zZXEodGFnLmdldE5hbWUoKSkpIHsKLQkJCQkJCQkJZXJyKHBvcywgJ1wnJyArIHRhZy5nZXROYW1lKCkgKyAiJyBzdHJpbmcgZXhwZWN0ZWQuIik7Ci0JCQkJCQkJfQotCi0JCQkJCQkJY2xlYXJXaGl0ZVNwYWNlcygpOwotCQkJCQkJCWlmICghYWNjZXB0X2NoYXIoJz4nKSkgewotCQkJCQkJCQllcnIoRVJSX0dUX0VYUEVDVEVEKTsKLQkJCQkJCQl9Ci0KLQkJCQkJCQlhUGFyZW50LmFkZFRhZyh0YWcpOwotCi0JCQkJCQkJaWYgKGZMZXZlbCA8PSAwIHx8IGZMZXZlbCA9PSBmQ3VycmVudExldmVsKSB7Ci0JCQkJCQkJCW5vdGlmeUxpc3RlbmVycyh0YWcsIGZhbHNlKTsKLQkJCQkJCQl9Ci0KLQkJCQkJCQlyZXR1cm4gdHJ1ZTsKLQkJCQkJCX0KLQkJCQkJfSBlbHNlIHsKLQkJCQkJCWlmICghcGFyc2VfUENEQVRBKHRhZykpIHsKLQkJCQkJCQlicmVhazsKLQkJCQkJCX0KLQkJCQkJfQotCQkJCX0KLQkJCQllcnIoRVJSX0NPTlRFTlRfRVhQRUNURUQpOwotCQkJfSBlbHNlIHsKLQkJCQllcnIoRVJSX0NMT1NFX1RBRzJfRVhQRUNURUQpOwotCQkJfQotCQl9Ci0JCXJldHVybiBmYWxzZTsKLQl9Ci0KLQkvKioKLQkgKiBSZXR1cm5zIHRydWUgaWYgdGhlIHNwZWNpZmllZCBhdHRyaWJ1dGUgaXMgYWxyZWFkeSBwYXJzZWQgYW5kIGZhbHNlCi0JICogb3RoZXJ3aXNlCi0JICogCi0JICogQHBhcmFtIGFUYWcKLQkgKiAgICAgICAgICAgIHRoZSB3aGljaCBhdHRyaWJ1dGUgd2lsbCBiZSBleGFtaW5lZC4KLQkgKiBAcGFyYW0gYXR0ck5hbWUKLQkgKiAgICAgICAgICAgIGFuIGF0dHJpYnV0ZSBuYW1lCi0JICogQHJldHVybiB0cnVlIGlmIHRoZSBzcGVjaWZpZWQgYXR0cmlidXRlIGlzIGFscmVhZHkgcGFyc2VkIGFuZCBmYWxzZQotCSAqICAgICAgICAgb3RoZXJ3aXNlCi0JICovCi0JcHJvdGVjdGVkIGJvb2xlYW4gYWNjZXB0X2F0dHIoVGFnSW1wbCBhVGFnLCBTdHJpbmcgYXR0ck5hbWUpIHsKLQkJcmV0dXJuIGFUYWcuZ2V0QXR0cmlidXRlKGF0dHJOYW1lKSAhPSBudWxsOwotCX0KLQotCS8qKgotCSAqIFBhcnNlcyB0aGUgWE1MIHByb2xvZyB0YWcsIGkuZS48YnI+Ci0JICogPGNvZGU+ICZsdDs/eG1sIHZlcnNpb249Ii4uLiIgZW5jb2Rpbmc9Ii4uLiIgc3RhbmRhbG9uZT0iLi4uIiA/Jmd0OyA8L2NvZGU+PGJyPgotCSAqIAotCSAqIEBwYXJhbSBwYXJlbnQKLQkgKiAgICAgICAgICAgIHRoZSBwYXJlbnQgdGFnIChpbiB0aGlzIGNhc2UgdGhpcyBpcyB0aGUgcm9vdCAiZmFrZSIgdGFnLAotCSAqICAgICAgICAgICAgd2hpY2ggdGhlIGxpc3RlbmVycyB3aWxsIG5ldmVyIGJlIGluZm9ybWVkIGZvci4uLikKLQkgKiBAdGhyb3dzIElPRXhjZXB0aW9uCi0JICogICAgICAgICAgICAgaWYgYW4gZXhjZXB0aW9uIG9jY3VycyBkdXJpbmcgcmVhZCBvcGVyYXRpb25zIGZyb20gdGhlIFJlYWRlcgotCSAqICAgICAgICAgICAgIG9yIHRoZSBJbnB1dFN0cmVhbQotCSAqLwotCXByb3RlY3RlZCBib29sZWFuIHBhcnNlX3htbF9wcm9sb2coVGFnSW1wbCBwYXJlbnQpIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0JCWlmIChhY2NlcHRfY2hhcignPycpKSB7Ci0JCQlUYWdJbXBsIHRhZyA9IG5ldyBUYWdJbXBsKCk7Ci0KLQkJCWlmIChwYXJzZV90YWdfbmFtZSh0YWcpKSB7Ci0JCQkJaWYgKHRhZy5nZXROYW1lKCkuZXF1YWxzSWdub3JlQ2FzZShYTUwpKSB7Ci0JCQkJCWNsZWFyV2hpdGVTcGFjZXMoKTsKLQotCQkJCQlpbnQgcG9zID0gZlBvczsKLQotCQkJCQlpZiAocGFyc2VfYXR0cih0YWcpKSB7Ci0JCQkJCQlTdHJpbmcgcyA9IHRhZy5nZXRBdHRyaWJ1dGUoVkVSU0lPTik7Ci0KLQkJCQkJCWlmIChzID09IG51bGwpIHsKLQkJCQkJCQllcnIocG9zLCBFUlJfVkVSU0lPTl9FWFBFQ1RFRCk7Ci0JCQkJCQl9Ci0KLQkJCQkJCWZWZXJzaW9uID0gczsKLQotCQkJCQkJY2xlYXJXaGl0ZVNwYWNlcygpOwotCQkJCQkJcG9zID0gZlBvczsKLQkJCQkJCWlmIChwYXJzZV9hdHRyKHRhZykpIHsKLQkJCQkJCQljbGVhcldoaXRlU3BhY2VzKCk7Ci0KLQkJCQkJCQlpZiAoYWNjZXB0X2F0dHIodGFnLCBFTkNPRElORykpIHsKLQkJCQkJCQkJZkVuY29kaW5nID0gdGFnLmdldEF0dHJpYnV0ZShFTkNPRElORyk7Ci0KLQkJCQkJCQkJcG9zID0gZlBvczsKLQkJCQkJCQkJaWYgKHBhcnNlX2F0dHIodGFnKSkgewotCQkJCQkJCQkJY2xlYXJXaGl0ZVNwYWNlcygpOwotCQkJCQkJCQkJaWYgKGFjY2VwdF9hdHRyKHRhZywgU1RBTkRBTE9ORSkpIHsKLQkJCQkJCQkJCQlmU3RhbmRhbG9uZSA9IHRhZy5nZXRBdHRyaWJ1dGUoU1RBTkRBTE9ORSk7Ci0JCQkJCQkJCQl9IGVsc2UgewotCQkJCQkJCQkJCWVycihwb3MsIEVSUl9TVEFOREFMT05FX0VYUEVDVEVEKTsKLQkJCQkJCQkJCX0KLQkJCQkJCQkJfQotCQkJCQkJCX0gZWxzZSBpZiAoYWNjZXB0X2F0dHIodGFnLCBTVEFOREFMT05FKSkgewotCQkJCQkJCQlmU3RhbmRhbG9uZSA9IHRhZy5nZXRBdHRyaWJ1dGUoU1RBTkRBTE9ORSk7Ci0JCQkJCQkJfSBlbHNlIHsKLQkJCQkJCQkJZXJyKHBvcywgRVJSX0VOQ09ESU5HX1NUQU5EQUxPTkVfRVhQRUNURUQpOwotCQkJCQkJCX0KLQkJCQkJCX0KLQotCQkJCQkJY2xlYXJXaGl0ZVNwYWNlcygpOwotCQkJCQkJcG9zID0gZlBvczsKLQkJCQkJCWlmICghYWNjZXB0X3NlcSgiPz4iKSkgewotCQkJCQkJCWVycihwb3MsIEVSUl9DTE9TRV9UQUczX0VYUEVDVEVEKTsKLQkJCQkJCX0KLQkJCQkJfSBlbHNlIHsKLQkJCQkJCWVycihwb3MsIEVSUl9WRVJTSU9OX0VYUEVDVEVEKTsKLQkJCQkJfQotCQkJCQljbGVhcldoaXRlU3BhY2VzKCk7Ci0JCQkJCXJldHVybiB0cnVlOwotCQkJCX0KLQotCQkJCWNoYXIgcHJldkNoID0gMDsKLQotCQkJCXdoaWxlICh0cnVlKSB7Ci0JCQkJCWlmIChjdXJyZW50Q2hhciA9PSAnPicpIHsKLQkJCQkJCWlmIChwcmV2Q2ggPT0gJz8nKSB7Ci0JCQkJCQkJYWNjZXB0X2NoYXIoJz4nKTsKLQkJCQkJCQljbGVhcldoaXRlU3BhY2VzKCk7Ci0KLQkJCQkJCQlyZXR1cm4gdHJ1ZTsKLQkJCQkJCX0KLQkJCQkJCWVycihFUlJfUVVFU1RJT05NQVJLX0VYUEVDVEVEKTsKLQkJCQkJfSBlbHNlIGlmIChjdXJyZW50Q2hhciA9PSAnPCcpIHsKLQkJCQkJCWVycihFUlJfSUxMRUdBTF9DSEFSQUNURVIgKyAiICgnPCcpIik7Ci0JCQkJCX0KLQkJCQkJcHJldkNoID0gY3VycmVudENoYXI7Ci0JCQkJCWdldE5leHRDaGFyKCk7Ci0JCQkJfQotCQkJfQotCQl9Ci0JCXJldHVybiBmYWxzZTsKLQl9Ci0KLQkvKioKLQkgKiBQYXJzZXMgc3BlY2lhbCB0YWdzLCBzdWNoIHRoYXQgYmVnaW5zIHdpdGg6PGJyPgotCSAqIAotCSAqIDxwcmU+PGNvZGU+Ci0JICogJmx0OyEtLSAgICAgICAgIGNvbW1lbnRzCi0JICogJmx0OyF0YWdfbmFtZSAgIFBhcnNpbmcgaW5zdHJ1Y3Rpb25zCi0JICogJmx0OyFbICAgICAgICAgIENEQVRBIGVsZW1lbnQKLQkgKiAmbHQ7PyAgICAgICAgICAgRE9DVFlQRSwgZXRjLgotCSAqIDwvY29kZT48L3ByZT4KLQkgKiAKLQkgKiBAcGFyYW0gYVBhcmVudAotCSAqICAgICAgICAgICAgVGhlIHBhcmVudCB0YWcgdGhhdCB0aGlzIHRhZyB3aWxsIGJlIGFkZGVkIHRvIGlmIHRoZSBwYXJzaW5nCi0JICogICAgICAgICAgICBpcyBzdWNjZXNzZnVsCi0JICogQHJldHVybiB0cnVlIG9uIHN1Y2Nlc3MgYW5kIGZhbHNlIG90aGVyd2lzZQotCSAqIEB0aHJvd3MgSU9FeGNlcHRpb24KLQkgKiBAc2VlIGFjY2VwdF9jaGFyCi0JICogQHNlZSBjbGVhcldoaXRlU3BhY2VzCi0JICogQHNlZSBwYXJzZV90YWdfQ0RBVEEKLQkgKiBAc2VlIHBhcnNlX3RhZ19uYW1lCi0JICogQHNlZSBwYXJzZV9jb21tZW50Ci0JICovCi0JcHJvdGVjdGVkIGJvb2xlYW4gcGFyc2VfdGFnX3NwZWNpYWwoVGFnSW1wbCBhUGFyZW50KSB0aHJvd3MgSU9FeGNlcHRpb24gewotCQlpZiAoYWNjZXB0X2NoYXIoJyEnKSkgewotCi0JCQlUYWdJbXBsIHRhZyA9IG5ldyBUYWdJbXBsKCk7Ci0KLQkJCWlmIChwYXJzZV90YWdfbmFtZSh0YWcpKSB7Ci0JCQkJY2xlYXJXaGl0ZVNwYWNlcygpOwotCi0JCQkJd2hpbGUgKHRydWUpIHsKLQkJCQkJaWYgKGFjY2VwdF9jaGFyKCc+JykpIHsKLQkJCQkJCWNsZWFyV2hpdGVTcGFjZXMoKTsKLQkJCQkJCXJldHVybiB0cnVlOwotCQkJCQl9Ci0JCQkJCWdldE5leHRDaGFyKCk7Ci0JCQkJfQotCQkJfSBlbHNlIGlmIChwYXJzZV90YWdfQ0RBVEEoYVBhcmVudCkpIHsgLy8gcGFyc2UgQ0RBVEEgdGFnCi0JCQkJcmV0dXJuIHRydWU7Ci0JCQl9IGVsc2UgaWYgKHBhcnNlX2NvbW1lbnQodGFnKSkgewotCQkJCXJldHVybiB0cnVlOwotCQkJfQotCQl9IGVsc2UgaWYgKGFjY2VwdF9jaGFyKCc/JykpIHsKLQkJCVRhZ0ltcGwgdGFnID0gbmV3IFRhZ0ltcGwoKTsKLQotCQkJaW50IHBvcyA9IGZQb3M7Ci0JCQlpZiAocGFyc2VfdGFnX25hbWUodGFnKSkgewotCQkJCWlmICh0YWcuZ2V0TmFtZSgpLmVxdWFscyhYTUwpKSB7Ci0JCQkJCWVycihwb3MgLSAyLCBFUlJfWE1MUFJPTE9HX0VYUEVDVEVEKTsKLQkJCQl9Ci0KLQkJCQljaGFyIHByZXZDaCA9IDA7Ci0JCQkJd2hpbGUgKHRydWUpIHsKLQkJCQkJaWYgKGN1cnJlbnRDaGFyID09ICc+JykgewotCQkJCQkJaWYgKHByZXZDaCA9PSAnPycpIHsKLQkJCQkJCQlhY2NlcHRfY2hhcignPicpOwotCQkJCQkJCWNsZWFyV2hpdGVTcGFjZXMoKTsKLQkJCQkJCQlyZXR1cm4gdHJ1ZTsKLQkJCQkJCX0KLQkJCQkJfQotCQkJCQlwcmV2Q2ggPSBjdXJyZW50Q2hhcjsKLQkJCQkJZ2V0TmV4dENoYXIoKTsKLQkJCQl9Ci0KLQkJCX0gZWxzZSB7Ci0JCQkJZXJyKHBvcywgRVJSX1RBR05BTUVfRVhQRUNURUQpOwotCQkJfQotCQl9Ci0JCXJldHVybiBmYWxzZTsKLQl9Ci0KLQkvKioKLQkgKiBQYXJzZXMgYSBjb21tZW50LiBUaGUgZ3JhbW1hciBpczo8YnI+Ci0JICogQ29tbWVudCA6Oj0gJyZsdDshLS0nICgoQ2hhciAtICctJykgfCAoJy0nIChDaGFyIC0gJy0nKSkpKiAnLS0mZ3Q7Jzxicj4KLQkgKiBOb3RlIHRoYXQgdGhlIGdyYW1tYXIgZG9lcyBub3QgYWxsb3cgYSBjb21tZW50IGVuZGluZyBpbiAtLS0mZ3Q7LiBUaGUKLQkgKiBmb2xsb3dpbmcgZXhhbXBsZSBpcyBub3Qgd2VsbC1mb3JtZWQuPGJyPgotCSAqIDxjb2RlPgotCSAqICZsdDshLS0gQissIEIsIG9yIEItLS0mZ3Q7PC9jb2RlPgotCSAqIAotCSAqIEBwYXJhbSBhUGFyZW50Ci0JICogICAgICAgICAgICBUaGUgcGFyZW50IHRhZwotCSAqIEByZXR1cm4gdHJ1ZSBvbiBzdWNjZXNzIGFuZCBmYWxzZSBvdGhlcndpc2UKLQkgKiBAdGhyb3dzIElPRXhjZXB0aW9uCi0JICogQHNlZSBhY2NlcHRfY2hhcgotCSAqLwotCXByb3RlY3RlZCBib29sZWFuIHBhcnNlX2NvbW1lbnQoVGFnSW1wbCBhUGFyZW50KSB0aHJvd3MgSU9FeGNlcHRpb24gewotCQlpZiAoYWNjZXB0X2NoYXIoJy0nKSkgewotCQkJaWYgKCFhY2NlcHRfY2hhcignLScpKSB7Ci0JCQkJZXJyKEVSUl9EQVNIX0VYUEVDVEVEKTsKLQkJCX0KLQotCQkJd2hpbGUgKHRydWUpIHsKLQkJCQlpZiAoYWNjZXB0X2NoYXIoJy0nKSkgewotCQkJCQlpZiAoYWNjZXB0X2NoYXIoJy0nKSkgewotCQkJCQkJaWYgKGFjY2VwdF9jaGFyKCc+JykpIHsKLQkJCQkJCQlicmVhazsKLQkJCQkJCX0KLQkJCQkJCWVycihFUlJfR1RfRVhQRUNURUQpOwotCQkJCQl9Ci0JCQkJfQotCi0JCQkJaWYgKCFnZXROZXh0Q2hhcigpKSB7Ci0JCQkJCWVycihFUlJfQ09NTUVOVF9DTE9TRV9FWFBFQ1RFRCk7Ci0JCQkJfQotCQkJfQotCQkJcmV0dXJuIHRydWU7Ci0JCX0KLQkJcmV0dXJuIGZhbHNlOwotCX0KLQotCS8qKgotCSAqIFBhcnNlcyBlaXRoZXIgbm9ybWFsIG9yIHNwZWNpYWwgdGFnCi0JICogCi0JICogQHBhcmFtIGFQYXJlbnQKLQkgKiAgICAgICAgICAgIFRoZSBwYXJlbnQgdGFnIHRoYXQgdGhlIHN1Y2Nlc3NmdWxseSBwYXJzZWQgdGFnIHdpbGwgKGlmIGl0IGlzCi0JICogICAgICAgICAgICBub3JtYWwgdGFnIG9yIENEQVRBIGVsZW1lbnQpIGJlIGFkZGVkCi0JICogQHJldHVybiB0cnVlIG9uIHN1Y2Nlc3MgYW5kIGZhbHNlIG90aGVyd2lzZQotCSAqIEB0aHJvd3MgSU9FeGNlcHRpb24KLQkgKiBAc2VlIGFjY2VwdF9jYWhyCi0JICogQHNlZSBwYXJzZV90YWdfbm9ybWFsCi0JICogQHNlZSBwYXJzZV90YWdfc3BlY2lhbAotCSAqIEBzZWUgY2xlYXJXaGl0ZVNwYWNlcwotCSAqLwotCXByb3RlY3RlZCBib29sZWFuIHBhcnNlX3RhZyhUYWdJbXBsIGFQYXJlbnQpIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0JCWNsZWFyV2hpdGVTcGFjZXMoKTsKLQkJdHJ5IHsKLQkJCWZDdXJyZW50TGV2ZWwrKzsKLQotCQkJaWYgKGFjY2VwdF9jaGFyKCc8JykpIHsKLQkJCQlpZiAocGFyc2VfdGFnX25vcm1hbChhUGFyZW50KSB8fCBwYXJzZV90YWdfc3BlY2lhbChhUGFyZW50KSkgewotCQkJCQlyZXR1cm4gdHJ1ZTsKLQkJCQl9Ci0JCQl9Ci0JCQlyZXR1cm4gZmFsc2U7Ci0JCX0gZmluYWxseSB7Ci0JCQlmQ3VycmVudExldmVsLS07Ci0JCX0KLQl9Ci0KLQkvKioKLQkgKiBQYXJzZXMgdGhlIGNvbnRlbnQgb2YgdGhlIHRhZyAoaW5jbHVkaW5nIHN1Yi10YWdzIGFuZCBzdWItZWxlbWVudHMpCi0JICogCi0JICogQHBhcmFtIGFQYXJlbnQKLQkgKiAgICAgICAgICAgIFRoZSBwYXJlbnQgdGFnIHRoYXQgdGhlIGNvbnRlbnQgYW5kIHRhZ3Mgd2lsbCBiZSBhZGRlZCB0bwotCSAqIEByZXR1cm4gdHJ1ZSBvbiBzdWNjZXNzIGFuZCBmYWxzZSBvdGhlcndpc2UKLQkgKiBAdGhyb3dzIElPRXhjZXB0aW9uCi0JICogQHNlZSBwYXJzZV9QQ0RBVEEKLQkgKiBAc2VlIHBhcnNlX3RhZwotCSAqLwotCXByb3RlY3RlZCBib29sZWFuIHBhcnNlX2NvbnRlbnQoVGFnSW1wbCBhUGFyZW50KSB0aHJvd3MgSU9FeGNlcHRpb24gewotCQlyZXR1cm4gKHBhcnNlX1BDREFUQShhUGFyZW50KSB8fCBwYXJzZV90YWcoYVBhcmVudCkpOwotCX0KLQotCS8qKgotCSAqIFBhcnNlcyBhIENEQVRBIHRhZyAob3IgQ0RBVEEgY29udGVudCBlbGVtZW50KS4KLQkgKiAKLQkgKiBAcGFyYW0gYVBhcmVudAotCSAqICAgICAgICAgICAgVGhlIHBhcmVudCB0YWcgdGhhdCB0aGUgY29udGVudCB3aWxsIGJlIGFkZGVkIHRvCi0JICogQHJldHVybiB0cnVlIG9uIHN1Y2Nlc3MgYW5kIGZhbHNlIG90aGVyd2lzZQotCSAqIEB0aHJvd3MgSU9FeGNlcHRpb24KLQkgKi8KLQlwcm90ZWN0ZWQgYm9vbGVhbiBwYXJzZV90YWdfQ0RBVEEoVGFnSW1wbCBhUGFyZW50KSB0aHJvd3MgSU9FeGNlcHRpb24gewotCQlpZiAoYWNjZXB0X2NoYXIoJ1snKSkgewotCQkJaW50IHBvcyA9IGZQb3M7Ci0KLQkJCWlmICghYWNjZXB0X3NlcShDREFUQSkpIHsKLQkJCQllcnIocG9zLCBFUlJfQ0RBVEFfRVhQRUNURUQpOwotCQkJfQotCi0JCQlpZiAoIWFjY2VwdF9jaGFyKCdbJykpIHsKLQkJCQllcnIoRVJSX09QRU5TUUJSQUNLRVRfRVhQRUNURUQpOwotCQkJfQotCi0JCQlkbyB7Ci0JCQkJaWYgKGN1cnJlbnRDaGFyICE9ICc+JykgewotCQkJCQlhUGFyZW50LmdldENvbnRlbnRCdWZmZXIoKS5hcHBlbmQoY3VycmVudENoYXIpOwotCQkJCX0gZWxzZSB7Ci0JCQkJCUNoYXJCdWZmZXIgc2IgPSBhUGFyZW50LmdldENvbnRlbnRCdWZmZXIoKTsKLQkJCQkJaW50IGwgPSBzYi5sZW5ndGgoKTsKLQotCQkJCQlpZiAobCA+PSAyKSB7Ci0JCQkJCQlpZiAoc2IuY2hhckF0KGwgLSAxKSA9PSAnXScgJiYgc2IuY2hhckF0KGwgLSAyKSA9PSAnXScpIHsKLQkJCQkJCQlzYi5zZXRMZW5ndGgobCAtIDIpOyAvLyBUcnVuY2F0ZXMgdGhlIGV4dHJhICJdXSIKLQkJCQkJCQkvLyBzeW1ib2xzIGFwcGVuZGVkIGF0IHRoZQotCQkJCQkJCS8vIGVuZAotCi0JCQkJCQkJZ2V0TmV4dENoYXIoKTsKLQkJCQkJCQlyZXR1cm4gdHJ1ZTsKLQkJCQkJCX0KLQkJCQkJfQotCQkJCQlzYi5hcHBlbmQoY3VycmVudENoYXIpOwotCQkJCX0KLQkJCX0gd2hpbGUgKGdldE5leHRDaGFyKCkpOwotCi0JCQllcnIoZlBvcyAtIDEsIEVSUl9DTE9TRV9DREFUQV9FWFBFQ1RFRCk7Ci0JCX0KLQkJcmV0dXJuIGZhbHNlOwotCX0KLQotCS8qKgotCSAqIFBhcnNlcyBQQ0RBVEEgY29udGVudCAoUGFyc2VhYmxlIENvbnRlbnQgREFUQSkuIFRoZSBFbnRpdHlSZWZzIGFuZAotCSAqIENoYXJSZWZzIHRoYXQgYXJlIHBhcnNlZCB3aWxsIGJlIHR1cm5lZCB0byBpdHMgc3ltYm9sIGVxdWl2YWxlbnQuCi0JICogCi0JICogQHBhcmFtIGFQYXJlbnQKLQkgKiAgICAgICAgICAgIFRoZSBwYXJlbnQgdGFnIHRoYXQgdGhlIFBDREFUQSB3aWxsIGJlIGFkZGVkIHRvCi0JICogQHJldHVybiB0cnVlIG9uIHN1Y2Nlc3MgYW5kIGZhbHNlIG90aGVyd2lzZQotCSAqIEB0aHJvd3MgSU9FeGNlcHRpb24KLQkgKiBAc2VlIGFjY2VwdF9jaGFyCi0JICogQHNlZSBwYXJzZV9DaGFyUmVmCi0JICogQHNlZSBwYXJzZV9FbnRpdHlSZWYKLQkgKi8KLQlwcm90ZWN0ZWQgYm9vbGVhbiBwYXJzZV9QQ0RBVEEoVGFnSW1wbCBhUGFyZW50KSB0aHJvd3MgSU9FeGNlcHRpb24gewotCQlib29sZWFuIHJlc3VsdCA9IGZhbHNlOwotCQl3aGlsZSAoY3VycmVudENoYXIgIT0gJzwnKSB7Ci0JCQlyZXN1bHQgPSB0cnVlOwotCi0JCQlDaGFyQnVmZmVyIHNiQ29udGVudCA9IGFQYXJlbnQuZ2V0Q29udGVudEJ1ZmZlcigpOwotCi0JCQlpZiAoYWNjZXB0X2NoYXIoJyYnKSkgewotCQkJCWludCBwb3MgPSBmUG9zOwotCQkJCWlmICghcGFyc2VfQ2hhclJlZihzYkNvbnRlbnQpKSB7Ci0JCQkJCWlmICghcGFyc2VfRW50aXR5UmVmKHNiQ29udGVudCkpIHsKLQkJCQkJCWVycihwb3MgLSAxLCBFUlJfRU5USVRZX0VYUEVDVEVEKTsKLQkJCQkJfQotCQkJCX0KLQkJCX0gZWxzZSB7Ci0JCQkJc2JDb250ZW50LmFwcGVuZChjdXJyZW50Q2hhcik7Ci0KLQkJCQlpZiAoIWdldE5leHRDaGFyKCkpIHsKLQkJCQkJYnJlYWs7Ci0JCQkJfQotCQkJfQotCQl9Ci0JCXJldHVybiByZXN1bHQ7Ci0JfQotCi0JLyoqCi0JICogQWNjZXB0cyBvbmUgY2hhcmFjdGVyIGZyb20gdGhlIGlucHV0IHN0cmVhbSBhbmQgaWYgaXQncyBzdWNjZXNzZnVsIG1vdmVzCi0JICogb25lIGNoYXJhY3RlciBmb3J3YXJkLgotCSAqIAotCSAqIEBwYXJhbSBjaAotCSAqICAgICAgICAgICAgVGhlIGNoYXJhY3RlciB0aGF0IHNob3VsZCBiZSBhY2NlcHRlZAotCSAqIEByZXR1cm4gdHJ1ZSBvbiBzdWNjZXNzIGFuZCBmYWxzZSBvdGhlcndpc2UKLQkgKiBAdGhyb3dzIElPRXhjZXB0aW9uCi0JICovCi0JcHJvdGVjdGVkIGJvb2xlYW4gYWNjZXB0X2NoYXIoY2hhciBjaCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKLQkJaWYgKGN1cnJlbnRDaGFyID09IGNoKSB7Ci0JCQlnZXROZXh0Q2hhcigpOwotCQkJcmV0dXJuIHRydWU7Ci0JCX0KLQkJcmV0dXJuIGZhbHNlOwotCX0KLQotCS8qKgotCSAqIEFjY2VwdHMgYSBzZXF1ZW5jZSBvZiBjaGFyYWN0ZXJzIGdpdmVuIGJ5IHNlcSBwYXJhbWV0ZXIuIElmIHRoZSBzZXF1ZW5jZQotCSAqIGlzIGFjY2VwdGVkIHN1Y2Nlc3NmdWxseSB0aGVuIHRoZSBjdXJyZW50Q2hhciBmaWVsZCB3aWxsIGNvbnRhaW4gdGhlCi0JICogY2hhcmFjdGVyIGltbWVkaWF0ZWx5IGFmdGVyIHRoZSBhY2NlcHRlZCBzZXF1ZW5jZS4KLQkgKiAKLQkgKiBAcGFyYW0gc2VxCi0JICogICAgICAgICAgICBUaGUgY2hhcmFjdGVyIHNlcXVlbmNlIHRoYXQgc2hvdWxkIGJlIGFjY2VwdGVkCi0JICogQHJldHVybiB0cnVlIG9uIHN1Y2Nlc3MgYW5kIGZhbHNlIG90aGVyd2lzZQotCSAqIEB0aHJvd3MgSU9FeGNlcHRpb24KLQkgKi8KLQlwcm90ZWN0ZWQgYm9vbGVhbiBhY2NlcHRfc2VxKFN0cmluZyBzZXEpIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0JCWZvciAoaW50IGkgPSAwOyBpIDwgc2VxLmxlbmd0aCgpOyBpKyspIHsKLQkJCWlmICghYWNjZXB0X2NoYXIoc2VxLmNoYXJBdChpKSkpIHsKLQkJCQlyZXR1cm4gZmFsc2U7Ci0JCQl9Ci0JCX0KLQkJcmV0dXJuIHRydWU7Ci0JfQotCi0JcHJvdGVjdGVkIHN0YXRpYyBmaW5hbCBTdHJpbmdbXSBlbnRpdGllcyA9IHsiYW1wIiwgImFwb3MiLCAibHQiLCAiZ3QiLCAicXVvdCJ9OwotCXByb3RlY3RlZCBzdGF0aWMgZmluYWwgY2hhcltdIGVudF9jaGFycyA9IHsnJicsICdcJycsICc8JywgJz4nLCAnIid9OwotCi0JLyoqCi0JICogPGNvZGU+Ci0JICogRW50aXR5UmVmIDo6PSAnJicgKyBFbnRpdHlWYWx1ZSArICc7Jzxicj4KLQkgKiBFbnRpdHlWYWx1ZSA6Oj0gJ2FtcCcgfCAncXVvdCcgfCAnYXBvcycgfCAnZ3QnIHwgJ2x0JyB8IGlkZW50aWZpZXIKLQkgKiA8L2NvZGU+Ci0JICogCi0JICogQHBhcmFtIHNiCi0JICogICAgICAgICAgICBUaGUgc3RyaW5nIGJ1ZmZlciB0aGF0IHRoZSByZWNvZ25pemVkIGVudGl0eSB3aWxsIGJlIGFwcGVuZGVkCi0JICogICAgICAgICAgICB0bwotCSAqIEB0aHJvd3MgSU9FeGNlcHRpb24KLQkgKiBAcmV0dXJuIHRydWUgb24gc3VjY2VzcyBhbmQgZmFsc2Ugb3RoZXJ3aXNlCi0JICogQHNlZSBwYXJzZV9pZGVudGlmaWVyCi0JICogQHNlZSBhY2NlcHRfY2hhcgotCSAqLwotCXByb3RlY3RlZCBib29sZWFuIHBhcnNlX0VudGl0eVJlZihDaGFyQnVmZmVyIHNiKSB0aHJvd3MgSU9FeGNlcHRpb24gewotCQlTdHJpbmcgZW50ID0gcGFyc2VfaWRlbnRpZmllcigpOwotCi0JCWlmICghYWNjZXB0X2NoYXIoJzsnKSkgewotCQkJZXJyKEVSUl9TRU1JQ09MT05fRVhQRUNURUQpOwotCQl9Ci0KLQkJaW50IGxlbmd0aCA9IGVudGl0aWVzLmxlbmd0aDsKLQkJZm9yIChpbnQgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykgewotCQkJaWYgKGVudGl0aWVzW2ldID09IGVudCkgeyAvLyAnZW50JyBpcyBpbnRlcm5lZCBieQotCQkJCS8vIHBhcnNlX2lkZW50aWZpZXIoKSBmdW5jdGlvbgotCQkJCXNiLmFwcGVuZChlbnRfY2hhcnNbaV0pOwotCQkJCXJldHVybiB0cnVlOwotCQkJfQotCQl9Ci0KLQkJc2IuYXBwZW5kKCcmJyk7Ci0KLQkJaWYgKGVudCAhPSBudWxsICYmIGVudC5sZW5ndGgoKSA+IDApIHsKLQkJCXNiLmFwcGVuZChlbnQpOwotCQl9Ci0KLQkJc2IuYXBwZW5kKCc7Jyk7Ci0KLQkJcmV0dXJuIHRydWU7Ci0JfQotCi0JLyoqCi0JICogUGFyc2VzIGEgQ2hhclJlZmVyZW5jZSBhbmQgaWYgaXQgaXMgc3VjY2Vzc2Z1bCB0aGVuIGFwcGVuZHMgaXQgdG8gdGhlCi0JICogcGFzc2VkIENoYXJCdWZmZXIKLQkgKiAKLQkgKiBAcGFyYW0gc2IKLQkgKiAgICAgICAgICAgIENoYXJCdWZmZXIgdGhhdCB0aGUgcGFyc2VkIENoYXJSZWZlcmVuY2Ugd2lsbCBiZSBhZGRlZCB0bwotCSAqIEByZXR1cm4gdHJ1ZSBvbiBzdWNjZXNzIGFuZCBmYWxzZSBvdGhlcndpc2UKLQkgKiBAdGhyb3dzIElPRXhjZXB0aW9uCi0JICovCi0JcHJvdGVjdGVkIGJvb2xlYW4gcGFyc2VfQ2hhclJlZihDaGFyQnVmZmVyIHNiKSB0aHJvd3MgSU9FeGNlcHRpb24gewotCQlpZiAoYWNjZXB0X2NoYXIoJyMnKSkgewotCQkJLy8gVE9ETyAtIFBvc3Rwb25lZC4uLgotCQkJd2hpbGUgKGN1cnJlbnRDaGFyICE9ICc7JykgewotCQkJCWdldE5leHRDaGFyKCk7Ci0JCQl9Ci0KLQkJCWlmICghYWNjZXB0X2NoYXIoJzsnKSkgewotCQkJCWVycihmUG9zIC0gMSwgRVJSX1NFTUlDT0xPTl9FWFBFQ1RFRCk7Ci0JCQl9Ci0KLQkJCXJldHVybiB0cnVlOwotCQl9Ci0JCXJldHVybiBmYWxzZTsKLQl9Ci0KLQkvKioKLQkgKiBDbGVhcnMgdGhlIHdoaXRlIHNwYWNlcyBzdGFydGluZyBmcm9tIHRoZSBjdXJyZW50IHBvc2l0aW9uCi0JICogCi0JICogQHRocm93cyBJT0V4Y2VwdGlvbgotCSAqLwotCXByb3RlY3RlZCB2b2lkIGNsZWFyV2hpdGVTcGFjZXMoKSB0aHJvd3MgSU9FeGNlcHRpb24gewotCQl3aGlsZSAoQ2hhcmFjdGVyLmlzV2hpdGVzcGFjZShjdXJyZW50Q2hhcikpIHsKLQkJCWlmICghZ2V0TmV4dENoYXIoKSkgewotCQkJCWJyZWFrOwotCQkJfQotCQl9Ci0JfQotCi0JLyoqCi0JICogVGhyb3dzIGFuIElPRXhjZXB0aW9uIHdpdGggYSBnaXZlbiBtZXNzYWdlLiBUaGUgY3VycmVudCBsaW5lIG51bWJlciBhbmQKLQkgKiBsaW5lIHBvc2l0aW9uIGFyZSBhcHBlbmRlZCB0byB0aGUgZXJyb3IgbWVzc2FnZQotCSAqIAotCSAqIEBwYXJhbSBtZXNzYWdlCi0JICogICAgICAgICAgICBUaGUgbWVzc2FnZSBvZiB0aGUgZXhjZXB0aW9uCi0JICogQHRocm93cyBJT0V4Y2VwdGlvbgotCSAqLwotCXByb3RlY3RlZCB2b2lkIGVycihTdHJpbmcgbWVzc2FnZSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKLQkJZXJyKGZQb3MsIG1lc3NhZ2UpOwotCX0KLQotCS8qKgotCSAqIFRocm93cyBhbiBJT0V4Y2VwdGlvbiB3aXRoIHRoZSBnaXZlbiBtZXNzYWdlIGZvciB0aGUgZ2l2ZW4gbGluZSBwb3NpdGlvbi4KLQkgKiBUaGUgY3VycmVudCBsaW5lIG51bWJlciBhbmQgcG9zaXRpb24gKHBvcykgYXJlIGFwcGVuZGVkIHRvIHRoZSBleGNlcHRpb24KLQkgKiBtZXNzYWdlCi0JICogCi0JICogQHBhcmFtIHBvcwotCSAqICAgICAgICAgICAgVGhlIGxpbmUgcG9zaXRpb24gdGhhdCB0aGUgZXJyb3Igd2lsbCBiZSByZXBvcnRlZCBmb3IKLQkgKiBAcGFyYW0gbWVzc2FnZQotCSAqIEB0aHJvd3MgSU9FeGNlcHRpb24KLQkgKi8KLQlwcm90ZWN0ZWQgdm9pZCBlcnIoaW50IHBvcywgU3RyaW5nIG1lc3NhZ2UpIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0JCXRocm93IG5ldyBJT0V4Y2VwdGlvbigiW0xpbmU6ICIgKyBmTGluZSArICIsIFBvczogIiArIHBvcyArICJdICAiICsgbWVzc2FnZSk7Ci0JfQotCi0JLyoqCi0JICogSW5pdGlhdGVzIHBhcnNpbmcgb2YgdGhlIFhNTCBmaWxlIGdpdmVuIHRocm91Z2ggYUlucHV0U3RyZWFtIG9yIGFSZWFkZXIKLQkgKiBpbiB0aGUgZ2l2ZW4gY29uc3RydWN0b3Igd2hlbiBjcmVhdGluZyBYTUxSZWFkZXIgb2JqZWN0LgotCSAqIAotCSAqIEB0aHJvd3MgSU9FeGNlcHRpb24KLQkgKiAgICAgICAgICAgICBpZiBhbiBlcnJvciBvY2N1cnMgZHVyaW5nIHJlYWRpbmcgdGhlIFhNTCBmaWxlIG9yIGlmIGEKLQkgKiAgICAgICAgICAgICBwYXJzaW5nIGVycm9yIGVjY3Vycy4KLQkgKi8KLQlwdWJsaWMgdm9pZCBwYXJzZVhNTCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7Ci0JCVRhZ0ltcGwgcm9vdFRhZyA9IG5ldyBUYWdJbXBsKCk7Ci0KLQkJdHJ5IHsKLQkJCWdldE5leHRDaGFyKCk7Ci0JCQljbGVhcldoaXRlU3BhY2VzKCk7Ci0KLQkJCWJvb2xlYW4gc3RhcnQgPSBmYWxzZTsKLQotCQkJd2hpbGUgKGFjY2VwdF9jaGFyKCc8JykpIHsKLQkJCQlzdGFydCA9IHRydWU7Ci0JCQkJaW50IHBvcyA9IGZQb3M7Ci0KLQkJCQlpZiAoZlBvcyA9PSAyICYmIGZMaW5lID09IDEpIHsKLQkJCQkJaWYgKHBhcnNlX3htbF9wcm9sb2cocm9vdFRhZykpIHsKLQkJCQkJCS8vIFN5c3RlbS5vdXQucHJpbnRsbigiWE1MIFByb2xvZyBmb3VuZC4iKTsKLQkJCQkJCS8vIFN5c3RlbS5vdXQucHJpbnRsbigiWE1MIFZlcnNpb246ICIgKyBmVmVyc2lvbiArICIsCi0JCQkJCQkvLyBlbmNvZGluZzogIiArIGZFbmNvZGluZyk7Ci0JCQkJCQlzZXRFbmNvZGluZyhmRW5jb2RpbmcpOwotCQkJCQkJY2xlYXJXaGl0ZVNwYWNlcygpOwotCQkJCQkJY29udGludWU7Ci0JCQkJCX0KLQkJCQl9IGVsc2UgewotCQkJCQlzZXRFbmNvZGluZyhmRGVmYXVsdEVuY29kaW5nKTsKLQkJCQl9Ci0KLQkJCQlpZiAoIXBhcnNlX3RhZ19zcGVjaWFsKHJvb3RUYWcpKSB7Ci0JCQkJCWlmIChwYXJzZV90YWdfbm9ybWFsKHJvb3RUYWcpKSB7Ci0JCQkJCQkvLyBUT0RPIGRhIHNlIHByb3ZlcmkgZGFsaSBlIGRvc3RpZ25hdCBrcmFqYSBuYSBmaWxlLWEsCi0JCQkJCQkvLyBha28gbmUgZSAtIHRvZ2F2YSBvdCB0dWsgbmF0YXR1ayBtb2plIGRhIGltYSBzYW1vCi0JCQkJCQkvLyBrb21lbnRhcmkuCi0JCQkJCQlyZXR1cm47Ci0JCQkJCX0KLQkJCQkJZXJyKHBvcywgRVJSX1RBR05BTUUyX0VYUEVDVEVEKTsKLQkJCQl9Ci0KLQkJCQljbGVhcldoaXRlU3BhY2VzKCk7Ci0JCQl9Ci0KLQkJCWlmICghc3RhcnQpIHsKLQkJCQllcnIoRVJSX0xUX0VYUEVDVEVEKTsKLQkJCX0KLQkJfSBjYXRjaCAoSU9FeGNlcHRpb24gaW9lKSB7Ci0JCQlpZiAoZkRlYnVnKSB7Ci0JCQkJaW9lLnByaW50U3RhY2tUcmFjZShTeXN0ZW0uZXJyKTsKLQkJCX0KLQotCQkJdGhyb3cgaW9lOwotCQl9Ci0JfQotCi0JLyoqCi0JICogUGFyc2VzIGEgWE1MIGZpbGUgZ2l2ZW4gdGhyb3VnaCBhSW5wdXRTdHJlYW0gYW5kIGR1cmluZyB0aGUgcGFyc2luZwotCSAqIG5vdGlmaWVzIGFMaXN0ZW5lciBmb3IgY2xvc2UtdGFnIGFuZCBvcGVuLXRhZyBldmVudHMgPGJyPgotCSAqIDxicj4KLQkgKiA8Yj5Ob3RlOiBUaGUgWE1MUmVhZGVyIGRvZXMgbm90IGNsb3NlIHRoZSBwYXNzZWQgUmVhZGVyIG9yIElucHV0U3RyZWFtCi0JICogCi0JICogQHBhcmFtIGFJbnB1dFN0cmVhbQotCSAqICAgICAgICAgICAgYW4gSW5wdXRTdHJlYW0gdG8gcmVhZCB0aGUgWE1MIGZpbGUgZnJvbQotCSAqIEBwYXJhbSBhTGlzdGVuZXIKLQkgKiAgICAgICAgICAgIEV4VGFnTGlzdGVuZXIgdGhhdCB3aWxsIGJlIG5vdGlmaWVkIG9uIGNsb3NlLXRhZyBhbmQgb3Blbi10YWcKLQkgKiAgICAgICAgICAgIGV2ZW50cwotCSAqIEBwYXJhbSBhTGV2ZWwKLQkgKiAgICAgICAgICAgIGluZGljYXRlcyB0aGUgdGFnIGxldmVsIHRoYXQgdGhlIGxpc3RlbmVyIHdpbGwgYmUgaW52b2tlZCBmb3IuCi0JICogICAgICAgICAgICBGb3IgZXhhbXBsZSBpZiB0aGUgWE1MIGlzOjxicj4KLQkgKiAKLQkgKiA8cHJlPgotCSAqICAmbHQ7YSZndDsKLQkgKiAgICAmbHQ7YiZndDsKLQkgKiAgICAgICZsdDtjIC8mZ3Q7Ci0JICogICAgJmx0Oy9iJmd0OwotCSAqICAmbHQ7L2EmZ3Q7Ci0JICogPC9wcmU+Ci0JICogCi0JICogPGJyPgotCSAqICAgICAgICAgICAgYW5kIHRoZSBwYXNzZWQgYUxldmVsIGlzIDIgdGhlbiB0aGUgbGlzdGVuZXIgd2lsbCBiZSBpbnZva2VkCi0JICogICAgICAgICAgICBvbmx5IGZvciB0YWdzIHRoYXQgaGF2ZSBsZXZlbCAyLCBpLmUuIGluIG91ciBleGFtcGxlIHRoZQotCSAqICAgICAgICAgICAgbGlzdGVuZXIgd2lsbCBiZSBpbnZva2VkIG9ubHkgZm9yIHRhZyAmbHQ7YiZndDs8YnI+Ci0JICogICAgICAgICAgICA8dWw+Ci0JICogICAgICAgICAgICA8bGk+VmFsdWUgbGVzcyB0aGFuIDAgaW5kaWNhdGVzICZxdW90O2ludm9rZSBsaXN0ZW5lciBmb3IgYWxsCi0JICogICAgICAgICAgICB0YWdzIG5vIG1hdHRlciB3aGF0IGFyZSB0aGVpciBsZXZlbHMmcXVvdDs8L2xpPgotCSAqICAgICAgICAgICAgPGxpPlZhbHVlIG9mIDAgaW5kaWNhdGVzIHRoYXQgdGhlIGxpc3RlbmVyIG11c3Qgbm90IGJlCi0JICogICAgICAgICAgICBpbnZva2VkIGluIGdlbmVyYWwgbm8gbWF0dGVyIHdoYXQgaXMgdGhlIHRhZyBsZXZlbDwvbGk+Ci0JICogICAgICAgICAgICA8bGk+VmFsdWUgZ3JlYXRlciB0aGFuIDAgaW5kaWNhdGVzIHRoZSB0YWcgbGV2ZWwgdGhhdCB0aGUKLQkgKiAgICAgICAgICAgIGxpc3RlbmVyIHdpbGwgYmUgaW52b2tlZCBmb3I8L2xpPgotCSAqICAgICAgICAgICAgZGVzY3JpcHRpb24KLQkgKiBAdGhyb3dzIElPRXhjZXB0aW9uCi0JICogICAgICAgICAgICAgaWYgc29tZSBJTyBlcnJvciBvY2N1cnMgd2hlbiByZWFkaW5nIHRoZSBYTUwgZmlsZSBvciBpZiBhCi0JICogICAgICAgICAgICAgcGFyc2VyIGVycm9yIG9jY3Vycy4KLQkgKi8KLQlwdWJsaWMgc3RhdGljIHZvaWQgcGFyc2VYTUwoSW5wdXRTdHJlYW0gYUlucHV0U3RyZWFtLCBFeFRhZ0xpc3RlbmVyIGFMaXN0ZW5lciwgaW50IGFMZXZlbCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKLQkJWE1MUGFyc2VySW1wbCB4bWwgPSBuZXcgWE1MUGFyc2VySW1wbChhSW5wdXRTdHJlYW0sIGFMaXN0ZW5lcik7Ci0JCXhtbC5zZXRMZXZlbChhTGV2ZWwpOwotCQl4bWwucGFyc2VYTUwoKTsKLQl9Ci0KLQkvKioKLQkgKiBQYXJzZXMgYSBYTUwgZmlsZSBnaXZlbiB0aHJvdWdoIGFSZWFkZXIgYW5kIGR1cmluZyB0aGUgcGFyc2luZyBub3RpZmllcwotCSAqIGFMaXN0ZW5lciBmb3IgY2xvc2UtdGFnIGFuZCBvcGVuLXRhZyBldmVudHMgPGJyPgotCSAqIDxicj4KLQkgKiA8Yj5Ob3RlOiBUaGUgWE1MUmVhZGVyIGRvZXMgbm90IGNsb3NlIHRoZSBwYXNzZWQgUmVhZGVyIG9yIElucHV0U3RyZWFtCi0JICogCi0JICogQHBhcmFtIGFSZWFkZXIKLQkgKiAgICAgICAgICAgIGFSZWFkZXIgdG8gcmVhZCB0aGUgWE1MIGZpbGUgZnJvbQotCSAqIEBwYXJhbSBhTGlzdGVuZXIKLQkgKiAgICAgICAgICAgIEV4VGFnTGlzdGVuZXIgdGhhdCB3aWxsIGJlIG5vdGlmaWVkIG9uIGNsb3NlLXRhZyBhbmQgb3Blbi10YWcKLQkgKiAgICAgICAgICAgIGV2ZW50cwotCSAqIEBwYXJhbSBhTGV2ZWwKLQkgKiAgICAgICAgICAgIHNlZSBwYXJzZVhNTChSZWFkZXIgYVJlYWRlciwgRXhUYWdMaXN0ZW5lciBhTGlzdGVuZXIsIGludAotCSAqICAgICAgICAgICAgYUxldmVsIGRlc2NyaXB0aW9uCi0JICogQHRocm93cyBJT0V4Y2VwdGlvbgotCSAqICAgICAgICAgICAgIGlmIHNvbWUgSU8gZXJyb3Igb2NjdXJzIHdoZW4gcmVhZGluZyB0aGUgWE1MIGZpbGUgb3IgaWYgYQotCSAqICAgICAgICAgICAgIHBhcnNlciBlcnJvciBvY2N1cnMuCi0JICovCi0JcHVibGljIHN0YXRpYyB2b2lkIHBhcnNlWE1MKFJlYWRlciBhUmVhZGVyLCBFeFRhZ0xpc3RlbmVyIGFMaXN0ZW5lciwgaW50IGFMZXZlbCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKLQkJWE1MUGFyc2VySW1wbCB4bWwgPSBuZXcgWE1MUGFyc2VySW1wbChhUmVhZGVyLCBhTGlzdGVuZXIpOwotCQl4bWwuc2V0TGV2ZWwoYUxldmVsKTsKLQkJeG1sLnBhcnNlWE1MKCk7Ci0JfQotCi0JLyoqCi0JICogUmV0dXJucyB0aGUgWE1MIHZlcnNpb24gYXR0cmlidXRlCi0JICogCi0JICogQHJldHVybiB0aGUgWE1MIGZpbGUgdmVyc2lvbiBhdHRyaWJ1dGUKLQkgKi8KLQlwdWJsaWMgU3RyaW5nIGdldFZlcnNpb24oKSB7Ci0JCXJldHVybiBmVmVyc2lvbjsKLQl9Ci0KLQkvKioKLQkgKiBSZXR1cm5zIHRoZSBYTUwgZW5jb2RpbmcgYXR0cmlidXRlCi0JICogCi0JICogQHJldHVybiB0aGUgWE1MIGVuY29kaW5nIGF0dHJpYnV0ZQotCSAqLwotCXB1YmxpYyBTdHJpbmcgZ2V0RW5jb2RpbmcoKSB7Ci0JCXJldHVybiBmRW5jb2Rpbmc7Ci0JfQotCi0JLyoqCi0JICogUmV0dXJucyB0aGUgdmFsdWUgb2YgWE1MIHN0YW5kYWxvbmUgYXR0cmlidXRlCi0JICogCi0JICogQHJldHVybiB0aGUgdmFsdWUgb2YgWE1MIHN0YW5kYWxvbmUgYXR0cmlidXRlCi0JICovCi0JcHVibGljIFN0cmluZyBnZXRTdGFuZGFsb25lKCkgewotCQlyZXR1cm4gZlN0YW5kYWxvbmU7Ci0JfQotfQpkaWZmIC0tZ2l0IGEvYnVuZGxlcy9vcmcuZWNsaXBzZS5lcXVpbm94LmRzL3NyYy9vcmcvZWNsaXBzZS9lcXVpbm94L2ludGVybmFsL3V0aWwveG1sL3BhY2thZ2UuaHRtbCBiL2J1bmRsZXMvb3JnLmVjbGlwc2UuZXF1aW5veC5kcy9zcmMvb3JnL2VjbGlwc2UvZXF1aW5veC9pbnRlcm5hbC91dGlsL3htbC9wYWNrYWdlLmh0bWwKZGVsZXRlZCBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDJkZTJmNzQuLjAwMDAwMDAKLS0tIGEvYnVuZGxlcy9vcmcuZWNsaXBzZS5lcXVpbm94LmRzL3NyYy9vcmcvZWNsaXBzZS9lcXVpbm94L2ludGVybmFsL3V0aWwveG1sL3BhY2thZ2UuaHRtbAorKysgL2Rldi9udWxsCkBAIC0xLDEyICswLDAgQEAKLTwhZG9jdHlwZSBodG1sIHB1YmxpYyAiLS8vdzNjLy9kdGQgaHRtbCA0LjAgdHJhbnNpdGlvbmFsLy9lbiI+Ci08aHRtbD4KLTxIRUFEPgotICAgPG1ldGEgaHR0cC1lcXVpdj0iQ29udGVudC1UeXBlIiBjb250ZW50PSJ0ZXh0L2h0bWw7IGNoYXJzZXQ9aXNvLTg4NTktMSI+Ci0gICA8TUVUQSBOQU1FPSJHZW5lcmF0b3IiIENPTlRFTlQ9Ik1pY3Jvc29mdCBXb3JkIDk3Ij4KLSAgIDxNRVRBIE5BTUU9IlRlbXBsYXRlIiBDT05URU5UPSJGOlxQcm9ncmFtIEZpbGVzXE1pY3Jvc29mdCBPZmZpY2VcT2ZmaWNlXGh0bWwuZG90Ij4KLTwvSEVBRD4KLTxCT0RZIExJTks9IiMwMDAwZmYiIFZMSU5LPSIjODAwMDgwIj4KLQotPFA+VGhlIDxDT0RFPm9yZy5lY2xpcHNlLmVxdWlub3gudXRpbC54bWw8L0NPREU+IHBhY2thZ2UgY29udGFpbnMgY2xhc3NlcyB0aGF0IGNhbiByZWFkIGFuZCBwYXJzZSBhIFhNTCBkb2N1bWVudC4gVGhyb3VnaCB0aGUgPENPREU+WE1MUmVhZGVyPC9DT0RFPiBjbGFzcyB5b3UgY2FuIHJlYWQgYSBYTUwgZnJvbSBhbiBpbnB1dCBzdHJlYW0gb3IgdGhyb3VnaCBhIHJlYWRlci4gVG8gZ2V0IGF3YXJlIG9mIGV2ZXJ5IHJlYWQgdGFnLCB5b3Ugc2hvdWxkIHBhc3MgYSA8Q09ERT5UYWdMaXN0ZW5lcjwvQ09ERT4gaW1wbGVtZW50YXRpb24gYXMgYW4gYXJndW1lbnQgaW4gdGhlIGNob3NlbiA8Q09ERT5yZWFkPC9DT0RFPiBtZXRob2Qgb2YgPENPREU+WE1MUmVhZGVyPC9DT0RFPi4gV2hlbiB0aGUgZW5kIG9mIGEgdGFnIGlzIHJlYWNoZWQsIHRoZSA8Q09ERT5UYWdMaXN0ZW5lcjwvQ09ERT4gd2lsbCByZWNlaXZlZCBhbiBpbnN0YW5jZSBvZiA8Q09ERT5UYWdDbGFzczwvQ09ERT4gdGhhdCByZXByZXNlbnRzIHRoaXMgdGFnLiBUbyByZWFkIHRoZSBuYW1lLCBjb250ZW50LCBhdHRyaWJ1dGVzIGFuZCBhIGNoaWxkIHRhZyBhdCBhIHNwZWNpZmljIGluZGV4LCB5b3UgY2FuIHVzZSA8Q09ERT5UYWdDbGFzczwvQ09ERT4gYW5kIDxDT0RFPlhNTFV0aWw8L0NPREU+LiBXaXRoIDxDT0RFPlhNTFV0aWw8L0NPREU+IHlvdSBjYW4gYWxzbyByZXBsYWNlIGEgdGFnLiBZb3UgY2Fubm90IGNyZWF0ZSBuZXcgWE1McyB3aXRoIHRoZSBYTUwgdXRpbGl0aWVzLjwvUD4KLTwvQk9EWT4KLTwvSFRNTD4K