<?xml version="1.0" encoding="UTF-8"?>
<install4j version="12.0" transformSequenceNumber="12">
  <directoryPresets config="." />
  <application name="Hello World Suite" applicationId="0804-2950-8354-4050" mediaDir="./media" lzmaCompression="true" shortName="hello" publisher="Hello Corporation" publisherWeb="http://www.hello.biz" version="12.0" allPathsRelative="true" macVolumeId="1eff23b94f1bb8c5" javaMinVersion="11">
    <jreBundles jdkProviderId="Adoptium" release="25/latest">
      <modules />
    </jreBundles>
  </application>
  <files>
    <filesets>
      <fileset name="VM options" id="1148" />
    </filesets>
    <roots>
      <root id="1149" fileset="1148" />
      <root id="1135" fileset="1148" location="${installer:vmoptionsTargetDirectory}" />
    </roots>
    <mountPoints>
      <mountPoint id="1" location="bin" />
      <mountPoint id="2" location="classes" />
      <mountPoint id="3" location="source" />
      <mountPoint id="1151" root="1135" />
    </mountPoints>
    <entries>
      <dirEntry mountPoint="2" file="./build" overrideFileMode="true" overrideOverwriteMode="true" overrideUninstallMode="true" overrideDirMode="true" />
      <dirEntry mountPoint="3" file="./src" subDirectory="src" />
      <fileEntry mountPoint="1151" file="./vmoptions/hello.vmoptions" overwriteMode="0" overrideFileMode="true" overrideOverwriteMode="true" overrideUninstallMode="true" />
    </entries>
    <components>
      <component name="Hello World Application" id="40" changeable="false">
        <description>The core application files necessary to run Hello World.</description>
        <include>
          <entry location="bin" />
          <entry location="classes" />
          <entry location="updater" fileType="installerApplication" />
          <entry location="configureGreeting" fileType="installerApplication" />
          <entry filesetId="1148" />
        </include>
      </component>
      <component name="Source Files" id="41">
        <description>The Java source files of the Hello World application.</description>
        <include>
          <entry location="source" />
        </include>
      </component>
    </components>
  </files>
  <launchers>
    <launcher name="Hello World Command Line" id="4" excludeFromMenu="true">
      <executable name="hello_cli" executableDir="bin" redirectStderr="false" executableMode="console" changeWorkingDirectory="false" dpiAware="false">
        <versionInfo include="true" fileDescription="Hello World Suite Command Line Launcher" legalCopyright="Copyright ej-technologies GmbH" internalName="helloCli" />
      </executable>
      <java mainClass="hello/cli.Hello" mainMode="module">
        <modulePath>
          <directory location="classes" />
        </modulePath>
        <vmOptions>
          <options version="24-" line="--enable-native-access=ALL-UNNAMED" />
        </vmOptions>
      </java>
      <vmOptionsFile mode="content">
        <content># Include the common .vmoptions file that is located in a user-writable location
-include-options ${installer:vmoptionsTargetDirectory}/hello.vmoptions</content>
      </vmOptionsFile>
    </launcher>
    <launcher name="Hello World GUI" id="5" icnsFile="./resources/hello.icns">
      <executable name="hello_gui" iconSet="true" executableDir="bin" executableMode="gui" singleInstance="true" checkConsoleParameter="true" dpiAware="true">
        <versionInfo include="true" fileDescription="Hello World Suite GUI Launcher" legalCopyright="Copyright ej-technologies GmbH" internalName="helloGUI" />
      </executable>
      <splashScreen show="true" width="400" height="230" bitmapFile="./resources/hello_splash.png" textOverlay="true">
        <text>
          <statusLine x="9" y="210" text="Loading application ..." />
          <versionLine x="279" y="169" text="version ${compiler:sys.version}" />
        </text>
      </splashScreen>
      <java mainClass="hello/gui.Hello" mainMode="module" vmParameters="-Dapple.laf.useScreenMenuBar=true">
        <modulePath>
          <directory location="classes" />
        </modulePath>
        <vmOptions>
          <options version="24-" line="--enable-native-access=ALL-UNNAMED" />
        </vmOptions>
      </java>
      <vmOptionsFile mode="content">
        <content># Include the common .vmoptions file that is located in a user-writable location
-include-options ${installer:vmoptionsTargetDirectory}/hello.vmoptions</content>
      </vmOptionsFile>
      <iconImageFiles>
        <file path="./resources/hello16x16.png" />
        <file path="./resources/hello32x32.png" />
        <file path="./resources/hello48x48.png" />
        <file path="./resources/hello128x128.png" />
        <file path="./resources/hello256x256.png" />
      </iconImageFiles>
    </launcher>
    <launcher name="Hello World Service" id="19" excludeFromMenu="true">
      <executable name="hello_service" executableDir="bin" redirectStdout="true" failOnStderrOutput="false" executableMode="service" dpiAware="false">
        <versionInfo include="true" fileDescription="Hello World Service" legalCopyright="Copyright ej-technologies GmbH" internalName="helloCli" />
      </executable>
      <java mainClass="hello/service.Hello" mainMode="module">
        <modulePath>
          <directory location="classes" />
        </modulePath>
      </java>
      <vmOptionsFile mode="content">
        <content># Include the common .vmoptions file that is located in a user-writable location
-include-options ${installer:vmoptionsTargetDirectory}/hello.vmoptions</content>
      </vmOptionsFile>
    </launcher>
  </launchers>
  <installerGui autoUpdateDescriptorUrl="https://download.ej-technologies.com/hello12/updates.xml">
    <applications>
      <application id="installer" beanClass="com.install4j.runtime.beans.applications.InstallerApplication" launchInNewProcess="false">
        <startup>
          <screen id="15" beanClass="com.install4j.runtime.beans.screens.StartupScreen" rollbackBarrierExitCode="0">
            <actions>
              <action id="2411" beanClass="com.install4j.runtime.beans.actions.control.SetInstallationDirectoryAction" actionElevationType="none">
                <serializedBean>
                  <property name="includeAllUsers" type="boolean" value="true" />
                  <property name="includeUserSpecific" type="boolean" value="true" />
                  <property name="installationScope" type="enum" class="com.install4j.runtime.beans.actions.control.InstallationScope" value="FULL_ADMIN" />
                </serializedBean>
              </action>
              <action name="Determine destination for .vmoption file" id="1146" beanClass="com.install4j.runtime.beans.actions.control.SetVariableAction">
                <serializedBean>
                  <property name="script">
                    <object class="com.install4j.api.beans.ScriptProperty">
                      <property name="value" type="string">if (Util.isWindows()) {
    // On Windows, the user-editable .vmoptions file will be installed to the APPDATA directory
    // which is a user-specific path, which is localized in some Windows versions
    return new File(WinFileSystem.getSpecialFolder(SpecialFolder.APPDATA, false), "Hello World").getPath();
} else {
    // On other platforms, we choose a hidden directory in the user home directory
    return new File(System.getProperty("user.home"), ".hello").getPath();
}</property>
                    </object>
                  </property>
                  <property name="variableName" type="string">vmoptionsTargetDirectory</property>
                </serializedBean>
              </action>
            </actions>
          </screen>
        </startup>
        <screens>
          <screen id="47" beanClass="com.install4j.runtime.beans.screens.WelcomeScreen" styleId="2394">
            <actions>
              <action id="1284" beanClass="com.install4j.runtime.beans.actions.misc.LoadResponseFileAction" multiExec="true">
                <serializedBean>
                  <property name="excludedVariables" type="array" elementType="string" length="1">
                    <element index="0">specialUserAccount</element>
                  </property>
                </serializedBean>
                <condition>context.getBooleanVariable("sys.streamlinedInstallation")</condition>
              </action>
            </actions>
            <formComponents>
              <formComponent id="1288" beanClass="com.install4j.runtime.beans.formcomponents.MultilineLabelComponent">
                <serializedBean>
                  <property name="labelText" type="string">${form:welcomeMessage}</property>
                </serializedBean>
                <visibilityScript>!context.isConsole()</visibilityScript>
              </formComponent>
              <formComponent id="1289" beanClass="com.install4j.runtime.beans.formcomponents.ConsoleHandlerFormComponent">
                <serializedBean>
                  <property name="consoleScript">
                    <object class="com.install4j.api.beans.ScriptProperty">
                      <property name="value" type="string">String message = context.getMessage("ConsoleWelcomeLabel", context.getApplicationName());
return console.askOkCancel(message, true);
</property>
                    </object>
                  </property>
                </serializedBean>
              </formComponent>
              <formComponent id="1290" beanClass="com.install4j.runtime.beans.formcomponents.StreamlinedInstallationChooserComponent" useExternalParametrization="true" externalParametrizationName="Update Alert" externalParametrizationMode="include">
                <serializedBean>
                  <property name="streamlinedInstallationStrategy" type="enum" class="com.install4j.runtime.beans.formcomponents.StreamlinedInstallationStrategy" value="UPDATE_ONLY" />
                </serializedBean>
                <externalParametrizationPropertyNames>
                  <propertyName>streamlinedInstallationStrategy</propertyName>
                </externalParametrizationPropertyNames>
              </formComponent>
              <formComponent id="1291" beanClass="com.install4j.runtime.beans.formcomponents.MultilineLabelComponent" insetTop="20">
                <serializedBean>
                  <property name="labelText" type="string">${i18n:ClickNext}</property>
                </serializedBean>
              </formComponent>
            </formComponents>
          </screen>
          <screen id="2417" beanClass="com.install4j.runtime.beans.screens.InstallationScopeScreen" rollbackBarrierExitCode="0">
            <condition>!context.getBooleanVariable("sys.streamlinedInstallation") &amp;&amp; !Util.hasAllUserInstallationRights() &amp;&amp; !context.isUpdateInstallation()</condition>
            <actions>
              <action id="2418" beanClass="com.install4j.runtime.beans.actions.misc.RequestPrivilegesAction" actionElevationType="none" rollbackBarrierExitCode="0" multiExec="true" failureStrategy="returnToScreen" errorMessage="${i18n:InstallationScopePrivilegesError}">
                <serializedBean>
                  <property name="failIfNotObtainedMac" type="boolean" value="false" />
                  <property name="failIfNotObtainedWin" type="boolean" value="false" />
                  <property name="linuxPrivilegeRequirement" type="enum" class="com.install4j.runtime.beans.actions.misc.PrivilegeRequirement" value="OBTAIN" />
                  <property name="obtainIfNormalMac" type="boolean" value="true" />
                  <property name="obtainIfNormalWin" type="boolean" value="true" />
                </serializedBean>
                <condition>context.getBooleanVariable("sys.installForAllUsers")</condition>
              </action>
              <action id="2419" beanClass="com.install4j.runtime.beans.actions.control.SetInstallationDirectoryAction" actionElevationType="none" rollbackBarrierExitCode="0" multiExec="true">
                <serializedBean>
                  <property name="installationScope" type="enum" class="com.install4j.runtime.beans.actions.control.InstallationScope" value="ACCORDING_TO_VARIABLE" />
                </serializedBean>
              </action>
            </actions>
            <formComponents>
              <formComponent id="2420" beanClass="com.install4j.runtime.beans.formcomponents.MultilineLabelComponent">
                <serializedBean>
                  <property name="labelText" type="string">${form:installationScopeMessage}</property>
                </serializedBean>
                <visibilityScript>!context.isConsole()</visibilityScript>
              </formComponent>
              <formComponent id="2421" beanClass="com.install4j.runtime.beans.formcomponents.InstallationScopeChooserComponent" />
            </formComponents>
          </screen>
          <screen id="48" beanClass="com.install4j.runtime.beans.screens.InstallationDirectoryScreen">
            <condition>!context.getBooleanVariable("sys.streamlinedInstallation")</condition>
            <actions>
              <action id="1025" beanClass="com.install4j.runtime.beans.actions.misc.LoadResponseFileAction" multiExec="true">
                <condition>context.getVariable("sys.responseFile") == null</condition>
              </action>
              <action id="1282" beanClass="com.install4j.runtime.beans.actions.registry.LoadInstallerVariablesAction" commentSet="true" comment="This action loads the installer variables from the preference store that have been saved by the &quot;Save installer variables to the Java preference store&quot; action on the &quot;Installation&quot; screen. &#xA;&#xA;It overrides installer variables that are loaded from the response file. The response file holds the greeting settings as they were last made in the installer, but the settings that are actually usd by the application live in the preference store." actionElevationType="elevated" multiExec="true">
                <serializedBean>
                  <property name="packageName" type="string">${compiler:sys.applicationId}</property>
                </serializedBean>
              </action>
            </actions>
            <formComponents>
              <formComponent id="1296" beanClass="com.install4j.runtime.beans.formcomponents.MultilineLabelComponent" insetBottom="25">
                <serializedBean>
                  <property name="labelText" type="string">${i18n:SelectDirLabel(${compiler:sys.fullName})}</property>
                </serializedBean>
              </formComponent>
              <formComponent id="1297" beanClass="com.install4j.runtime.beans.formcomponents.InstallationDirectoryChooserComponent" useExternalParametrization="true" externalParametrizationName="Installation Directory Chooser" externalParametrizationMode="include">
                <serializedBean>
                  <property name="requestFocus" type="boolean" value="true" />
                </serializedBean>
                <externalParametrizationPropertyNames>
                  <propertyName>allowSpacesOnUnix</propertyName>
                  <propertyName>checkFreeSpace</propertyName>
                  <propertyName>checkWritable</propertyName>
                  <propertyName>existingDirWarning</propertyName>
                  <propertyName>manualEntryAllowed</propertyName>
                  <propertyName>noWritableCheckIfInstallingForAllUsers</propertyName>
                  <propertyName>showFreeDiskSpace</propertyName>
                  <propertyName>showRequiredDiskSpace</propertyName>
                  <propertyName>standardValidation</propertyName>
                  <propertyName>suggestAppDir</propertyName>
                  <propertyName>validateApplicationId</propertyName>
                  <propertyName>validationScript</propertyName>
                </externalParametrizationPropertyNames>
              </formComponent>
            </formComponents>
          </screen>
          <screen id="49" beanClass="com.install4j.runtime.beans.screens.ComponentsScreen">
            <condition>!context.getBooleanVariable("sys.streamlinedInstallation")</condition>
            <formComponents>
              <formComponent id="1300" beanClass="com.install4j.runtime.beans.formcomponents.MultilineLabelComponent">
                <serializedBean>
                  <property name="labelText" type="string">${i18n:SelectComponentsLabel2}</property>
                </serializedBean>
                <visibilityScript>!context.isConsole()</visibilityScript>
              </formComponent>
              <formComponent id="1301" beanClass="com.install4j.runtime.beans.formcomponents.ComponentSelectorComponent" useExternalParametrization="true" externalParametrizationName="Installation Components" externalParametrizationMode="include">
                <serializedBean>
                  <property name="fillVertical" type="boolean" value="true" />
                </serializedBean>
                <externalParametrizationPropertyNames>
                  <propertyName>selectionChangedScript</propertyName>
                </externalParametrizationPropertyNames>
              </formComponent>
            </formComponents>
          </screen>
          <screen name="Query greeting" id="73" beanClass="com.install4j.runtime.beans.screens.FormScreen">
            <serializedBean>
              <property name="subTitle" type="string">Who do you want to greet?</property>
              <property name="title" type="string">Greeting configuration</property>
            </serializedBean>
            <condition>!context.getBooleanVariable("sys.streamlinedInstallation")</condition>
            <validation>String greeting = ((String)context.getVariable("personName")).trim();

if (context.getVariable("greetingOption").equals("world")) {
    greeting = "world";
} else if (greeting.trim().length() == 0) {
    formEnvironment.getFormComponentById("77").requestFocus();
    Util.showMessage("Please enter a name.");
    return false;
}

context.setVariable("greeting", greeting);
return true;</validation>
            <formComponents>
              <formComponent name="world" id="483" beanClass="com.install4j.runtime.beans.formcomponents.SingleRadiobuttonComponent" insetBottom="0">
                <serializedBean>
                  <property name="initiallySelected" type="boolean" value="true" />
                  <property name="radioButtonLabel" type="string">Greet the whole world</property>
                  <property name="variableName" type="string">greetingOption</property>
                  <property name="variableValue" type="string">world</property>
                </serializedBean>
              </formComponent>
              <formComponent name="person" id="484" beanClass="com.install4j.runtime.beans.formcomponents.SingleRadiobuttonComponent" insetTop="0" insetBottom="0">
                <serializedBean>
                  <property name="coupledComponentIds">
                    <add type="string">77</add>
                  </property>
                  <property name="radioButtonLabel" type="string">Greet a single person</property>
                  <property name="variableName" type="string">greetingOption</property>
                  <property name="variableValue" type="string">person</property>
                </serializedBean>
              </formComponent>
              <formComponent id="77" beanClass="com.install4j.runtime.beans.formcomponents.TextfieldComponent" insetLeft="20">
                <serializedBean>
                  <property name="enterGoesToNextScreen" type="boolean" value="true" />
                  <property name="labelText" type="string">Name of the person:</property>
                  <property name="requestFocus" type="boolean" value="true" />
                  <property name="variableName" type="string">personName</property>
                </serializedBean>
              </formComponent>
            </formComponents>
          </screen>
          <screen name="Service options" id="1565" beanClass="com.install4j.runtime.beans.screens.FormScreen">
            <serializedBean>
              <property name="subTitle" type="string">Please choose options for the service</property>
              <property name="title" type="string">Service Options</property>
            </serializedBean>
            <condition>context.getBooleanVariable("sys.installForAllUsers")</condition>
            <validation>if (!context.getBooleanVariable("specialUserAccount")) {
    context.setVariable("serviceAccount", "NT AUTHORITY\\System");
    context.setVariable("servicePassword", "");
}
return true;</validation>
            <formComponents>
              <formComponent id="1568" beanClass="com.install4j.runtime.beans.formcomponents.MultilineHtmlLabelComponent">
                <serializedBean>
                  <property name="labelHtml" type="string">The Hello World suite includes a service that says hello every 2 seconds</property>
                </serializedBean>
              </formComponent>
              <formComponent id="1566" beanClass="com.install4j.runtime.beans.formcomponents.CheckboxComponent">
                <serializedBean>
                  <property name="checkboxText" type="string">Install Hello World service</property>
                  <property name="coupledComponentIds">
                    <add type="string">1572</add>
                  </property>
                  <property name="initiallySelected" type="boolean" value="true" />
                  <property name="variableName" type="string">installService</property>
                </serializedBean>
              </formComponent>
              <group id="1573" beanClass="com.install4j.runtime.beans.groups.VerticalFormComponentGroup">
                <serializedBean>
                  <property name="insets">
                    <object class="java.awt.Insets">
                      <int>0</int>
                      <int>20</int>
                      <int>0</int>
                      <int>0</int>
                    </object>
                  </property>
                </serializedBean>
                <beans>
                  <formComponent id="1572" beanClass="com.install4j.runtime.beans.formcomponents.CheckboxComponent">
                    <serializedBean>
                      <property name="checkboxText" type="string">Use a special user account for running the service</property>
                      <property name="coupledComponentIds">
                        <add type="string">1571</add>
                      </property>
                      <property name="variableName" type="string">specialUserAccount</property>
                    </serializedBean>
                    <visibilityScript>Util.isWindows()</visibilityScript>
                  </formComponent>
                  <group id="1571" beanClass="com.install4j.runtime.beans.groups.VerticalFormComponentGroup">
                    <serializedBean>
                      <property name="insets">
                        <object class="java.awt.Insets">
                          <int>0</int>
                          <int>20</int>
                          <int>0</int>
                          <int>0</int>
                        </object>
                      </property>
                    </serializedBean>
                    <beans>
                      <formComponent id="1569" beanClass="com.install4j.runtime.beans.formcomponents.UserSelectorComponent">
                        <serializedBean>
                          <property name="groupCreatedVariableName" type="string">groupCreated</property>
                          <property name="labelText" type="string">Account name:</property>
                          <property name="localGroupVariableName" type="string">localGroupForCreatedUser</property>
                          <property name="onlyLocal" type="boolean" value="true" />
                          <property name="passwordFormComponentId" type="string">1570</property>
                          <property name="showCreateButton" type="boolean" value="true" />
                          <property name="showWellKnownPrincipals" type="boolean" value="true" />
                          <property name="userCreatedVariableName" type="string">userCreated</property>
                          <property name="variableName" type="string">serviceAccount</property>
                        </serializedBean>
                        <visibilityScript>Util.isWindows()</visibilityScript>
                      </formComponent>
                      <formComponent id="1570" beanClass="com.install4j.runtime.beans.formcomponents.PasswordComponent">
                        <serializedBean>
                          <property name="labelText" type="string">Password:</property>
                          <property name="variableName" type="string">servicePassword</property>
                        </serializedBean>
                        <visibilityScript>Util.isWindows()</visibilityScript>
                      </formComponent>
                    </beans>
                  </group>
                </beans>
              </group>
            </formComponents>
          </screen>
          <screen id="53" beanClass="com.install4j.runtime.beans.screens.InstallationScreen" rollbackBarrier="true">
            <actions>
              <action name="Request privileges for update installation" id="2427" beanClass="com.install4j.runtime.beans.actions.misc.RequestPrivilegesAction" actionElevationType="none" rollbackBarrierExitCode="0">
                <serializedBean>
                  <property name="failIfNotObtainedLinux" type="boolean" value="true" />
                  <property name="failIfNotRootUnix" type="boolean" value="true" />
                  <property name="linuxPrivilegeRequirement" type="enum" class="com.install4j.runtime.beans.actions.misc.PrivilegeRequirement" value="OBTAIN" />
                  <property name="obtainIfNormalMac" type="boolean" value="true" />
                  <property name="obtainIfNormalWin" type="boolean" value="true" />
                </serializedBean>
                <condition>context.getBooleanVariable("sys.installForAllUsers") || !Util.isDirectoryWritable(context.getInstallationDirectory())</condition>
              </action>
              <group name="Stop Services" id="1682" beanClass="com.install4j.runtime.beans.groups.ActionGroup">
                <serializedBean>
                  <property name="conditionExpression">
                    <object class="com.install4j.api.beans.ScriptProperty">
                      <property name="value" type="string">context.getBooleanVariable("sys.installForAllUsers")</property>
                    </object>
                  </property>
                </serializedBean>
                <beans>
                  <action id="325" beanClass="com.install4j.runtime.beans.actions.control.SetMessageAction" actionElevationType="none">
                    <serializedBean>
                      <property name="statusMessage" type="string">${i18n:StatusStoppingServices}</property>
                      <property name="useDetail" type="boolean" value="true" />
                      <property name="useStatus" type="boolean" value="true" />
                    </serializedBean>
                  </action>
                  <action id="326" beanClass="com.install4j.runtime.beans.actions.control.SetProgressAction" actionElevationType="none">
                    <serializedBean>
                      <property name="progressChangeType" type="enum" class="com.install4j.runtime.beans.actions.control.ProgressChangeType" value="SET_INDETERMINATE" />
                    </serializedBean>
                  </action>
                  <action id="101" beanClass="com.install4j.runtime.beans.actions.services.StopServiceAction" commentSet="true" comment="This action is necessary otherwise the following &quot;Delete a file an directories&quot; action might fail on Windows, since the files that are to be deleted might be in use.&#xA;&#xA;Otherwise, you do not have to stop services explicitly, the &quot;Uninstall files&quot; action will stop all services." actionElevationType="elevated">
                    <serializedBean>
                      <property name="launcherId" type="string">19</property>
                    </serializedBean>
                  </action>
                  <action id="1955" beanClass="com.install4j.runtime.beans.actions.control.SetProgressAction" actionElevationType="none">
                    <serializedBean>
                      <property name="progressChangeType" type="enum" class="com.install4j.runtime.beans.actions.control.ProgressChangeType" value="SET_DETERMINATE" />
                    </serializedBean>
                  </action>
                </beans>
              </group>
              <action id="1467" beanClass="com.install4j.runtime.beans.actions.misc.CheckRunningProcessesAction" commentSet="true" comment="Note that the &quot;Install Files&quot; action always checks that no process that are started from affected files are running. However, if you want to give your users the ability to close the applications automatically, you have to add this action before the &quot;Install Files&quot; action." actionElevationType="none" failureStrategy="quit">
                <serializedBean>
                  <property name="closeStrategy" type="enum" class="com.install4j.runtime.beans.actions.misc.CloseStrategy" value="ASK_FOR_CLOSE_AND_TERMINATE" />
                </serializedBean>
              </action>
              <action id="55" beanClass="com.install4j.runtime.beans.actions.InstallFilesAction" actionElevationType="elevated" failureStrategy="quit" errorMessage="${i18n:FileCorrupted}" />
              <action id="56" beanClass="com.install4j.runtime.beans.actions.desktop.CreateDefaultStartMenuEntriesAction" actionElevationType="elevated" />
              <action id="57" beanClass="com.install4j.runtime.beans.actions.desktop.RegisterAddRemoveAction" actionElevationType="elevated">
                <serializedBean>
                  <property name="icon">
                    <object class="com.install4j.api.beans.ExternalFile">
                      <string>./resources/hello.ico</string>
                    </object>
                  </property>
                  <property name="iconSource" type="enum" class="com.install4j.runtime.beans.actions.desktop.IconSource" value="CUSTOM" />
                  <property name="itemName" type="string">${compiler:sys.fullName} ${compiler:sys.version}</property>
                </serializedBean>
              </action>
              <action id="58" beanClass="com.install4j.runtime.beans.actions.services.InstallServiceAction" actionElevationType="elevated">
                <serializedBean>
                  <property name="accountNameOrSid" type="string">${installer:serviceAccount}</property>
                  <property name="description" type="string">A service that says hello every 2 seconds</property>
                  <property name="launcherId" type="string">19</property>
                  <property name="macosIdentifier" type="string">com.ejt.hello</property>
                  <property name="password" type="string">${installer:servicePassword}</property>
                  <property name="serviceAccount" type="enum" class="com.install4j.runtime.beans.actions.services.ServiceAccount" value="OTHER" />
                </serializedBean>
                <condition>context.getBooleanVariable("sys.installForAllUsers") &amp;&amp; context.getBooleanVariable("installService")</condition>
              </action>
              <action name="Modify .vmoption files" id="1155" beanClass="com.install4j.runtime.beans.actions.text.ReplaceInstallerVariablesAction" actionElevationType="elevated">
                <serializedBean>
                  <property name="files" type="array" class="java.io.File" length="3">
                    <element index="0">
                      <object class="java.io.File">
                        <string>bin/hello_cli.vmoptions</string>
                      </object>
                    </element>
                    <element index="1">
                      <object class="java.io.File">
                        <string>bin/hello_gui.vmoptions</string>
                      </object>
                    </element>
                    <element index="2">
                      <object class="java.io.File">
                        <string>bin/hello_service.vmoptions</string>
                      </object>
                    </element>
                  </property>
                </serializedBean>
              </action>
              <action name="Save greeting to the Java preference store" id="1145" beanClass="com.install4j.runtime.beans.actions.registry.SaveInstallerVariablesAction" commentSet="true" comment="The launchers will access the user-defined greeting by loading the installer variables saved to the preference store by this action. They do this through a helper class provided by the install4j API.&#xA;&#xA;Another way would have been to load the variable from the automatically created response file (through the same helper class). However, we want to save the greeting on a per-user basis and make it editable by the custom installer application named &quot;Configure greeting&quot;." actionElevationType="elevated">
                <serializedBean>
                  <property name="installerVariables" type="array" elementType="string" length="3">
                    <element index="0">greeting</element>
                    <element index="1">personName</element>
                    <element index="2">greetingOption</element>
                  </property>
                  <property name="packageName" type="string">${compiler:sys.applicationId}</property>
                </serializedBean>
              </action>
              <action id="1956" beanClass="com.install4j.runtime.beans.actions.text.FixCrLfAction" actionElevationType="elevated">
                <serializedBean>
                  <property name="files" type="array" class="java.io.File" length="1">
                    <element index="0">
                      <object class="java.io.File">
                        <string>${installer:vmoptionsTargetDirectory}/hello.vmoptions</string>
                      </object>
                    </element>
                  </property>
                </serializedBean>
              </action>
              <action id="59" beanClass="com.install4j.runtime.beans.actions.services.StartServiceAction" actionElevationType="elevated">
                <serializedBean>
                  <property name="launcherId" type="string">19</property>
                </serializedBean>
                <condition>context.getBooleanVariable("sys.installForAllUsers") &amp;&amp; context.getBooleanVariable("installService")</condition>
              </action>
            </actions>
            <formComponents>
              <formComponent id="1966" beanClass="com.install4j.runtime.beans.formcomponents.ProgressComponent">
                <serializedBean>
                  <property name="initialStatusMessage" type="string">${i18n:WizardPreparing}</property>
                </serializedBean>
              </formComponent>
            </formComponents>
          </screen>
          <screen id="60" beanClass="com.install4j.runtime.beans.screens.FinishedScreen" styleId="2394" finishScreen="true">
            <actions>
              <action id="465" beanClass="com.install4j.runtime.beans.actions.finish.ExecuteLauncherAction" actionElevationType="none">
                <serializedBean>
                  <property name="launcherId" type="string">5</property>
                </serializedBean>
                <condition>context.getBooleanVariable("executeLauncherAction") &amp;&amp; context.isGui()</condition>
              </action>
            </actions>
            <formComponents>
              <formComponent id="1970" beanClass="com.install4j.runtime.beans.formcomponents.MultilineLabelComponent" insetBottom="10">
                <serializedBean>
                  <property name="labelText" type="string">${form:finishedMessage}</property>
                </serializedBean>
              </formComponent>
              <formComponent name="Execute launcher" id="72" beanClass="com.install4j.runtime.beans.formcomponents.CheckboxComponent">
                <serializedBean>
                  <property name="checkboxText" type="string">${i18n:RunEntryExec("${compiler:sys.fullName}")}</property>
                  <property name="initiallySelected" type="boolean" value="true" />
                  <property name="variableName" type="string">executeLauncherAction</property>
                </serializedBean>
                <visibilityScript>context.isGui()</visibilityScript>
              </formComponent>
            </formComponents>
          </screen>
        </screens>
      </application>
      <application id="uninstaller" beanClass="com.install4j.runtime.beans.applications.UninstallerApplication" launchInNewProcess="false">
        <serializedBean>
          <property name="customMacosExecutableName" type="string">${i18n:UninstallerMenuEntry(${compiler:sys.fullName})}</property>
          <property name="unixMode" type="string">755</property>
          <property name="useCustomMacosExecutableName" type="boolean" value="true" />
        </serializedBean>
        <startup>
          <screen id="16" beanClass="com.install4j.runtime.beans.screens.StartupScreen" rollbackBarrierExitCode="0">
            <actions>
              <action id="1784" beanClass="com.install4j.runtime.beans.actions.misc.LoadResponseFileAction" multiExec="true">
                <condition>context.getVariable("sys.responseFile") == null</condition>
              </action>
              <action id="1285" beanClass="com.install4j.runtime.beans.actions.misc.RequireInstallerPrivilegesAction" actionElevationType="none" />
            </actions>
          </screen>
        </startup>
        <screens>
          <screen id="61" beanClass="com.install4j.runtime.beans.screens.UninstallWelcomeScreen" styleId="2394">
            <formComponents>
              <formComponent id="1976" beanClass="com.install4j.runtime.beans.formcomponents.MultilineLabelComponent" insetBottom="10">
                <serializedBean>
                  <property name="labelText" type="string">${form:welcomeMessage}</property>
                </serializedBean>
                <visibilityScript>!context.isConsole()</visibilityScript>
              </formComponent>
              <formComponent id="1977" beanClass="com.install4j.runtime.beans.formcomponents.ConsoleHandlerFormComponent">
                <serializedBean>
                  <property name="consoleScript">
                    <object class="com.install4j.api.beans.ScriptProperty">
                      <property name="value" type="string">String message = context.getMessage("ConfirmUninstall", context.getApplicationName());
return console.askYesNo(message, true);
</property>
                    </object>
                  </property>
                </serializedBean>
              </formComponent>
            </formComponents>
          </screen>
          <screen name="Delete Created User" id="1783" beanClass="com.install4j.runtime.beans.screens.FormScreen">
            <serializedBean>
              <property name="subTitle" type="string">Do you want to delete the created user account?</property>
              <property name="title" type="string">Delete Created User Account</property>
            </serializedBean>
            <condition>if (context.getBooleanVariable("userCreated")) {
    context.setVariable("groupName", null);
    if (context.getBooleanVariable("groupCreated")) {
        String groupSid = (String)context.getVariable("localGroupForCreatedUser");
        if (groupSid != null) {
            String groupName = WinUser.getAccountName(groupSid);
            if (groupName != null) {
                context.setVariable("groupName", groupName);
            }
        }
    }

    String accountSid = (String)context.getVariable("serviceAccount");
    if (accountSid != null) {
        String userName = WinUser.getAccountName(accountSid);
        if (userName != null) {
            context.setVariable("userName", userName);
            return true;
        }
    }
}
return false;</condition>
            <formComponents>
              <formComponent id="1869" beanClass="com.install4j.runtime.beans.formcomponents.MultilineLabelComponent">
                <serializedBean>
                  <property name="labelText" type="string">A new user has been created by the installer for running services. Do you want to remove the created account?</property>
                </serializedBean>
              </formComponent>
              <formComponent name="Remove account" id="1870" beanClass="com.install4j.runtime.beans.formcomponents.CheckboxComponent">
                <serializedBean>
                  <property name="checkboxText" type="string">Remove account "${installer:userName}"</property>
                  <property name="coupledComponentIds">
                    <add type="string">1871</add>
                  </property>
                  <property name="variableName" type="string">removeUser</property>
                </serializedBean>
              </formComponent>
              <formComponent name="Remove Group" id="1871" beanClass="com.install4j.runtime.beans.formcomponents.CheckboxComponent">
                <serializedBean>
                  <property name="checkboxText" type="string">Remove local group "${installer:groupName}"</property>
                  <property name="variableName" type="string">removeGroup</property>
                </serializedBean>
                <visibilityScript>context.getVariable("groupName") != null</visibilityScript>
              </formComponent>
            </formComponents>
          </screen>
          <screen id="62" beanClass="com.install4j.runtime.beans.screens.UninstallationScreen">
            <actions>
              <link id="1683" targetId="1682" />
              <action name="Delete files created by the application" id="862" beanClass="com.install4j.runtime.beans.actions.files.DeleteFileAction" actionElevationType="elevated">
                <serializedBean>
                  <property name="files" type="array" class="java.io.File" length="3">
                    <element index="0">
                      <object class="java.io.File">
                        <string>${installer:sys.userHome}/hello.properties</string>
                      </object>
                    </element>
                    <element index="1">
                      <object class="java.io.File">
                        <string>bin/service_demo.log</string>
                      </object>
                    </element>
                    <element index="2">
                      <object class="java.io.File">
                        <string>bin/nohup.out</string>
                      </object>
                    </element>
                  </property>
                </serializedBean>
              </action>
              <action id="63" beanClass="com.install4j.runtime.beans.actions.UninstallFilesAction" actionElevationType="elevated" rollbackBarrier="true" />
              <action name="Delete created user" id="1872" beanClass="com.install4j.runtime.beans.actions.control.RunScriptAction">
                <serializedBean>
                  <property name="script">
                    <object class="com.install4j.api.beans.ScriptProperty">
                      <property name="value" type="string">if (context.getBooleanVariable("removeUser")) {
    String accountSid = (String)context.getVariable("serviceAccount");
    if (accountSid != null) {
        WinUser.deleteUser(accountSid);
    }
    if (context.getBooleanVariable("removeGroup")) {
        String groupSid = (String)context.getVariable("localGroupForCreatedUser");
        if (groupSid != null) {
            WinUser.deleteLocalGroup(groupSid);
        }
    }
}
return true;
</property>
                    </object>
                  </property>
                </serializedBean>
              </action>
            </actions>
            <formComponents>
              <formComponent id="1988" beanClass="com.install4j.runtime.beans.formcomponents.ProgressComponent">
                <serializedBean>
                  <property name="initialStatusMessage" type="string">${i18n:UninstallerPreparing}</property>
                </serializedBean>
              </formComponent>
            </formComponents>
          </screen>
          <screen id="64" beanClass="com.install4j.runtime.beans.screens.UninstallFailureScreen" finishScreen="true" />
          <screen id="65" beanClass="com.install4j.runtime.beans.screens.UninstallSuccessScreen" styleId="2394" finishScreen="true">
            <formComponents>
              <formComponent id="1991" beanClass="com.install4j.runtime.beans.formcomponents.MultilineLabelComponent" insetBottom="10">
                <serializedBean>
                  <property name="labelText" type="string">${form:successMessage}</property>
                </serializedBean>
              </formComponent>
            </formComponents>
          </screen>
        </screens>
      </application>
      <application name="Standalone update downloader" id="535" beanClass="com.install4j.runtime.beans.applications.CustomApplication" customIcnsFile="${compiler:sys.install4jHome}/resource/macos/updater.icns" launchInNewProcess="false">
        <serializedBean>
          <property name="customIconImageFiles">
            <add>
              <object class="com.install4j.api.beans.ExternalFile">
                <string>${compiler:sys.install4jHome}/resource/updater_16.png</string>
              </object>
            </add>
            <add>
              <object class="com.install4j.api.beans.ExternalFile">
                <string>${compiler:sys.install4jHome}/resource/updater_32.png</string>
              </object>
            </add>
            <add>
              <object class="com.install4j.api.beans.ExternalFile">
                <string>${compiler:sys.install4jHome}/resource/updater_48.png</string>
              </object>
            </add>
            <add>
              <object class="com.install4j.api.beans.ExternalFile">
                <string>${compiler:sys.install4jHome}/resource/updater_128.png</string>
              </object>
            </add>
            <add>
              <object class="com.install4j.api.beans.ExternalFile">
                <string>${compiler:sys.install4jHome}/resource/updater_256.png</string>
              </object>
            </add>
          </property>
          <property name="executableDirectory">
            <object class="java.io.File">
              <string>.</string>
            </object>
          </property>
          <property name="executableName" type="string">updater</property>
          <property name="useCustomIcon" type="boolean" value="true" />
          <property name="windowTitle" type="string">${i18n:updater.WindowTitle("${compiler:sys.fullName}")}</property>
        </serializedBean>
        <startup>
          <screen id="2133" beanClass="com.install4j.runtime.beans.screens.StartupScreen" rollbackBarrierExitCode="0" />
        </startup>
        <screens>
          <screen name="Welcome" id="2134" beanClass="com.install4j.runtime.beans.screens.FormScreen" styleId="2394">
            <serializedBean>
              <property name="title" type="string">${i18n:updater.WelcomeTitle("${compiler:sys.fullName}")}</property>
            </serializedBean>
            <formComponents>
              <formComponent id="2136" beanClass="com.install4j.runtime.beans.formcomponents.MultilineLabelComponent" useExternalParametrization="true" externalParametrizationName="Header" externalParametrizationMode="include">
                <serializedBean>
                  <property name="hideIfBlank" type="boolean" value="true" />
                  <property name="labelText" type="string">${i18n:updater.WelcomeInfoText("${compiler:sys.fullName}")}

The updater can be fully customized and templates for various update scenarios are available in the install4j IDE.</property>
                </serializedBean>
                <visibilityScript>!context.isConsole()</visibilityScript>
                <externalParametrizationPropertyNames>
                  <propertyName>labelText</propertyName>
                </externalParametrizationPropertyNames>
              </formComponent>
            </formComponents>
          </screen>
          <screen name="Check for update" id="2135" beanClass="com.install4j.runtime.beans.screens.FormScreen">
            <serializedBean>
              <property name="subTitle" type="string">${i18n:updater.CheckForUpdateSubtitle}</property>
              <property name="title" type="string">${i18n:updater.CheckForUpdateTitle}</property>
            </serializedBean>
            <postActivation>context.goForward(1, true, true);
</postActivation>
            <actions>
              <action id="2136" beanClass="com.install4j.runtime.beans.actions.control.SetProgressAction" actionElevationType="none">
                <serializedBean>
                  <property name="progressChangeType" type="enum" class="com.install4j.runtime.beans.actions.control.ProgressChangeType" value="SET_INDETERMINATE" />
                </serializedBean>
              </action>
              <action id="2137" beanClass="com.install4j.runtime.beans.actions.update.CheckForUpdateAction" actionElevationType="none" failureStrategy="quit">
                <serializedBean>
                  <property name="url" type="string">${compiler:sys.updatesUrl}</property>
                  <property name="variable" type="string">updateDescriptor</property>
                </serializedBean>
              </action>
              <action id="2138" beanClass="com.install4j.runtime.beans.actions.control.SleepAction" actionElevationType="none" />
              <action name="Update descriptor entry" id="2139" beanClass="com.install4j.runtime.beans.actions.control.SetVariableAction">
                <serializedBean>
                  <property name="script">
                    <object class="com.install4j.api.beans.ScriptProperty">
                      <property name="value" type="string">((UpdateDescriptor)context.getVariable("updateDescriptor")).getPossibleUpdateEntry()</property>
                    </object>
                  </property>
                  <property name="variableName" type="string">updateDescriptorEntry</property>
                </serializedBean>
              </action>
              <group name="Update available" id="2140" beanClass="com.install4j.runtime.beans.groups.ActionGroup">
                <serializedBean>
                  <property name="conditionExpression">
                    <object class="com.install4j.api.beans.ScriptProperty">
                      <property name="value" type="string">context.getVariable("updateDescriptorEntry") != null</property>
                    </object>
                  </property>
                </serializedBean>
                <beans>
                  <action name="New version" id="2141" beanClass="com.install4j.runtime.beans.actions.control.SetVariableAction">
                    <serializedBean>
                      <property name="script">
                        <object class="com.install4j.api.beans.ScriptProperty">
                          <property name="value" type="string">((UpdateDescriptorEntry)context.getVariable("updateDescriptorEntry")).getNewVersion()</property>
                        </object>
                      </property>
                      <property name="variableName" type="string">updaterNewVersion</property>
                    </serializedBean>
                  </action>
                  <action name="Download size" id="2142" beanClass="com.install4j.runtime.beans.actions.control.SetVariableAction">
                    <serializedBean>
                      <property name="script">
                        <object class="com.install4j.api.beans.ScriptProperty">
                          <property name="value" type="string">((UpdateDescriptorEntry)context.getVariable("updateDescriptorEntry")).getFileSizeVerbose()</property>
                        </object>
                      </property>
                      <property name="variableName" type="string">updaterDownloadSize</property>
                    </serializedBean>
                  </action>
                  <action name="Comment" id="2143" beanClass="com.install4j.runtime.beans.actions.control.SetVariableAction">
                    <serializedBean>
                      <property name="script">
                        <object class="com.install4j.api.beans.ScriptProperty">
                          <property name="value" type="string">((UpdateDescriptorEntry)context.getVariable("updateDescriptorEntry")).getComment()</property>
                        </object>
                      </property>
                      <property name="variableName" type="string">updaterComment</property>
                    </serializedBean>
                  </action>
                  <action name="Download URL" id="2145" beanClass="com.install4j.runtime.beans.actions.control.SetVariableAction">
                    <serializedBean>
                      <property name="script">
                        <object class="com.install4j.api.beans.ScriptProperty">
                          <property name="value" type="string">((UpdateDescriptorEntry)context.getVariable("updateDescriptorEntry")).getURL().toExternalForm()</property>
                        </object>
                      </property>
                      <property name="variableName" type="string">updaterDownloadUrl</property>
                    </serializedBean>
                  </action>
                  <action name="Archive" id="2146" beanClass="com.install4j.runtime.beans.actions.control.SetVariableAction">
                    <serializedBean>
                      <property name="script">
                        <object class="com.install4j.api.beans.ScriptProperty">
                          <property name="value" type="string">((UpdateDescriptorEntry)context.getVariable("updateDescriptorEntry")).isArchive() ? Boolean.TRUE : Boolean.FALSE</property>
                        </object>
                      </property>
                      <property name="variableName" type="string">isArchive</property>
                    </serializedBean>
                  </action>
                  <action name="DMG" id="2147" beanClass="com.install4j.runtime.beans.actions.control.SetVariableAction">
                    <serializedBean>
                      <property name="script">
                        <object class="com.install4j.api.beans.ScriptProperty">
                          <property name="value" type="string">((UpdateDescriptorEntry)context.getVariable("updateDescriptorEntry")).getFileName().toLowerCase().endsWith(".dmg")</property>
                        </object>
                      </property>
                      <property name="variableName" type="string">isDmg</property>
                    </serializedBean>
                  </action>
                </beans>
              </group>
            </actions>
            <formComponents>
              <formComponent id="2150" beanClass="com.install4j.runtime.beans.formcomponents.ProgressComponent" useExternalParametrization="true" externalParametrizationName="Directory" externalParametrizationMode="include">
                <serializedBean>
                  <property name="initialStatusMessage" type="string">${i18n:updater.CheckForUpdateLabel}</property>
                </serializedBean>
                <externalParametrizationPropertyNames>
                  <propertyName>statusVisible</propertyName>
                  <propertyName>initialStatusMessage</propertyName>
                </externalParametrizationPropertyNames>
              </formComponent>
            </formComponents>
          </screen>
          <group name="Up to date" id="2148" beanClass="com.install4j.runtime.beans.groups.ScreenGroup">
            <serializedBean>
              <property name="conditionExpression">
                <object class="com.install4j.api.beans.ScriptProperty">
                  <property name="value" type="string">context.getVariable("updateDescriptorEntry") == null</property>
                </object>
              </property>
            </serializedBean>
            <beans>
              <screen name="Up to date notification" id="2149" beanClass="com.install4j.runtime.beans.screens.FormScreen" styleId="2394" finishScreen="true">
                <serializedBean>
                  <property name="title" type="string">${i18n:updater.UpToDateTitle}</property>
                </serializedBean>
                <formComponents>
                  <formComponent id="2154" beanClass="com.install4j.runtime.beans.formcomponents.MultilineLabelComponent" useExternalParametrization="true" externalParametrizationName="Header" externalParametrizationMode="include">
                    <serializedBean>
                      <property name="hideIfBlank" type="boolean" value="true" />
                      <property name="labelText" type="string">${i18n:updater.UpToDateInfoText("${compiler:sys.fullName}")}</property>
                    </serializedBean>
                    <visibilityScript>!context.isConsole()</visibilityScript>
                    <externalParametrizationPropertyNames>
                      <propertyName>labelText</propertyName>
                    </externalParametrizationPropertyNames>
                  </formComponent>
                </formComponents>
              </screen>
            </beans>
          </group>
          <group name="Update available" id="2150" beanClass="com.install4j.runtime.beans.groups.ScreenGroup">
            <serializedBean>
              <property name="conditionExpression">
                <object class="com.install4j.api.beans.ScriptProperty">
                  <property name="value" type="string">context.getVariable("updateDescriptorEntry") != null</property>
                </object>
              </property>
            </serializedBean>
            <beans>
              <screen name="New version available" id="2151" beanClass="com.install4j.runtime.beans.screens.FormScreen">
                <serializedBean>
                  <property name="subTitle" type="string">${i18n:updater.NewVersionAvailableSubtitle("${compiler:sys.fullName}")}</property>
                  <property name="title" type="string">${i18n:updater.NewVersionAvailableTitle}</property>
                </serializedBean>
                <formComponents>
                  <formComponent id="2152" beanClass="com.install4j.runtime.beans.formcomponents.KeyValuePairComponent">
                    <serializedBean>
                      <property name="labelText" type="string">${i18n:updater.CurrentVersionLabel}</property>
                      <property name="valueLabelText" type="string">${installer:sys.version}</property>
                      <property name="valueLabelWidgetStyle" id="LabelWidgetStyle0">
                        <property name="fontDescriptor">
                          <property name="font">
                            <object class="java.awt.Font">
                              <string>dialog</string>
                              <int>1</int>
                              <int>0</int>
                            </object>
                          </property>
                          <property name="fontType" type="enum" class="com.install4j.runtime.beans.formcomponents.FontType" value="CUSTOM" />
                        </property>
                        <property name="foregroundColor">
                          <object class="java.awt.Color">
                            <int>128</int>
                            <int>0</int>
                            <int>0</int>
                            <int>255</int>
                          </object>
                        </property>
                      </property>
                      <property name="valueLabelWidgetStyleId" type="null" />
                    </serializedBean>
                  </formComponent>
                  <group id="2153" beanClass="com.install4j.runtime.beans.groups.HorizontalFormComponentGroup">
                    <beans>
                      <formComponent id="2154" beanClass="com.install4j.runtime.beans.formcomponents.KeyValuePairComponent">
                        <serializedBean>
                          <property name="labelText" type="string">${i18n:updater.NewVersionLabel}</property>
                          <property name="valueLabelText" type="string">${installer:updaterNewVersion}</property>
                          <property name="valueLabelWidgetStyle" id="LabelWidgetStyle0">
                            <property name="fontDescriptor">
                              <property name="font">
                                <object class="java.awt.Font">
                                  <string>dialog</string>
                                  <int>1</int>
                                  <int>0</int>
                                </object>
                              </property>
                              <property name="fontType" type="enum" class="com.install4j.runtime.beans.formcomponents.FontType" value="CUSTOM" />
                            </property>
                            <property name="foregroundColor">
                              <object class="java.awt.Color">
                                <int>0</int>
                                <int>128</int>
                                <int>0</int>
                                <int>255</int>
                              </object>
                            </property>
                          </property>
                          <property name="valueLabelWidgetStyleId" type="null" />
                        </serializedBean>
                      </formComponent>
                      <formComponent id="2155" beanClass="com.install4j.runtime.beans.formcomponents.HyperlinkActionLabelComponent" insetLeft="5">
                        <serializedBean>
                          <property name="actionScript">
                            <object class="com.install4j.api.beans.ScriptProperty">
                              <property name="value" type="string">context.goForward(1, false, false);</property>
                            </object>
                          </property>
                          <property name="hyperlinkText" type="string">${i18n:updater.ShowComments}</property>
                        </serializedBean>
                        <visibilityScript> ((String)context.getVariable("updaterComment")).length() &gt; 0</visibilityScript>
                      </formComponent>
                    </beans>
                  </group>
                  <formComponent id="2156" beanClass="com.install4j.runtime.beans.formcomponents.SpacerComponent" />
                  <formComponent id="2157" beanClass="com.install4j.runtime.beans.formcomponents.MultilineLabelComponent">
                    <serializedBean>
                      <property name="labelText" type="string">${i18n:updater.DownloadLocationLabel}</property>
                    </serializedBean>
                  </formComponent>
                  <formComponent id="2158" beanClass="com.install4j.runtime.beans.formcomponents.DirectoryChooserComponent">
                    <serializedBean>
                      <property name="initialFile" type="string">${installer:sys.downloadsDir}</property>
                      <property name="labelText" type="string">${i18n:updater.DownloadToLabel}</property>
                      <property name="manualEntryAllowed" type="boolean" value="false" />
                      <property name="variableName" type="string">updaterDownloadLocation</property>
                    </serializedBean>
                  </formComponent>
                  <formComponent id="2159" beanClass="com.install4j.runtime.beans.formcomponents.KeyValuePairComponent">
                    <serializedBean>
                      <property name="labelText" type="string">${i18n:updater.DownloadSizeLabel}</property>
                      <property name="valueLabelText" type="string">${installer:updaterDownloadSize}</property>
                    </serializedBean>
                  </formComponent>
                </formComponents>
              </screen>
              <screen name="Update message" id="2160" beanClass="com.install4j.runtime.beans.screens.FormScreen">
                <serializedBean>
                  <property name="scrollable" type="boolean" value="false" />
                  <property name="subTitle" type="string">${i18n:updater.CommentsSubTitle}</property>
                  <property name="title" type="string">${i18n:updater.CommentsTitle}</property>
                </serializedBean>
                <condition>false // This screen is only shown if the user clicks the "Show comments" hyperlink label in the previous screen.
</condition>
                <validation>if (context.isConsole()) {
    context.goBackInHistory(1);
}
return true;</validation>
                <postActivation>WizardContext wizardContext = context.getWizardContext();
wizardContext.setControlButtonVisible(ControlButtonType.NEXT, false);
wizardContext.setControlButtonVisible(ControlButtonType.CANCEL, false);</postActivation>
                <formComponents>
                  <formComponent id="2168" beanClass="com.install4j.runtime.beans.formcomponents.MultilineLabelComponent" useExternalParametrization="true" externalParametrizationName="Header" externalParametrizationMode="include">
                    <serializedBean>
                      <property name="hideIfBlank" type="boolean" value="true" />
                      <property name="labelText" type="string">${i18n:updater.CommentsLabel}</property>
                    </serializedBean>
                    <visibilityScript>!context.isConsole()</visibilityScript>
                    <externalParametrizationPropertyNames>
                      <propertyName>labelText</propertyName>
                    </externalParametrizationPropertyNames>
                  </formComponent>
                  <formComponent id="2169" beanClass="com.install4j.runtime.beans.formcomponents.HtmlDisplayFormComponent" useExternalParametrization="true" externalParametrizationName="HTML display" externalParametrizationMode="include">
                    <serializedBean>
                      <property name="displayedText" type="string">${installer:updaterComment}</property>
                      <property name="fillVertical" type="boolean" value="true" />
                      <property name="textSource" type="enum" class="com.install4j.runtime.beans.screens.components.TextSource" value="DIRECT" />
                    </serializedBean>
                    <externalParametrizationPropertyNames>
                      <propertyName>textSource</propertyName>
                      <propertyName>displayedText</propertyName>
                      <propertyName>displayedTextFile</propertyName>
                      <propertyName>variableName</propertyName>
                    </externalParametrizationPropertyNames>
                  </formComponent>
                  <formComponent id="2170" beanClass="com.install4j.runtime.beans.formcomponents.ConsoleHandlerFormComponent">
                    <serializedBean>
                      <property name="consoleScript">
                        <object class="com.install4j.api.beans.ScriptProperty">
                          <property name="value" type="string">console.waitForEnter();
return true;
</property>
                        </object>
                      </property>
                    </serializedBean>
                  </formComponent>
                </formComponents>
              </screen>
              <screen name="Download new version" id="2161" beanClass="com.install4j.runtime.beans.screens.FormScreen">
                <serializedBean>
                  <property name="subTitle" type="string">${i18n:updater.DownloadSubTitle}</property>
                  <property name="title" type="string">${i18n:updater.DownloadTitle}</property>
                </serializedBean>
                <postActivation>context.goForward(1, true, true);
</postActivation>
                <actions>
                  <action name="Download location" id="2162" beanClass="com.install4j.runtime.beans.actions.control.SetVariableAction">
                    <serializedBean>
                      <property name="script">
                        <object class="com.install4j.api.beans.ScriptProperty">
                          <property name="value" type="string">context.getVariable("updaterDownloadLocation") + File.separator + ((UpdateDescriptorEntry)context.getVariable("updateDescriptorEntry")).getFileName()</property>
                        </object>
                      </property>
                      <property name="variableName" type="string">updaterDownloadFile</property>
                    </serializedBean>
                  </action>
                  <action id="2163" beanClass="com.install4j.runtime.beans.actions.net.DownloadFileAction" actionElevationType="elevated" failureStrategy="quit">
                    <serializedBean>
                      <property name="targetFile">
                        <object class="java.io.File">
                          <string>${installer:updaterDownloadFile}</string>
                        </object>
                      </property>
                      <property name="url" type="string">${installer:updaterDownloadUrl}</property>
                    </serializedBean>
                  </action>
                  <action id="2164" beanClass="com.install4j.runtime.beans.actions.files.SetModeAction" actionElevationType="elevated">
                    <serializedBean>
                      <property name="files" type="array" class="java.io.File" length="1">
                        <element index="0">
                          <object class="java.io.File">
                            <string>${installer:updaterDownloadFile}</string>
                          </object>
                        </element>
                      </property>
                      <property name="mode" type="string">755</property>
                    </serializedBean>
                  </action>
                </actions>
                <formComponents>
                  <formComponent id="2176" beanClass="com.install4j.runtime.beans.formcomponents.ProgressComponent" useExternalParametrization="true" externalParametrizationName="Directory" externalParametrizationMode="include">
                    <externalParametrizationPropertyNames>
                      <propertyName>statusVisible</propertyName>
                      <propertyName>initialStatusMessage</propertyName>
                    </externalParametrizationPropertyNames>
                  </formComponent>
                </formComponents>
              </screen>
              <group name="Finish" id="2165" beanClass="com.install4j.runtime.beans.groups.ScreenGroup">
                <beans>
                  <screen name="Finish" id="2166" beanClass="com.install4j.runtime.beans.screens.FormScreen" styleId="2394" finishScreen="true">
                    <serializedBean>
                      <property name="title" type="string">${i18n:updater.FinishTitle}</property>
                    </serializedBean>
                    <condition>!(context.getBooleanVariable("isArchive") &amp;&amp; context.getBooleanVariable("isDmg"))</condition>
                    <actions>
                      <group name="Execute installer" id="2167" beanClass="com.install4j.runtime.beans.groups.ActionGroup">
                        <serializedBean>
                          <property name="conditionExpression">
                            <object class="com.install4j.api.beans.ScriptProperty">
                              <property name="value" type="string">!context.getBooleanVariable("isArchive") &amp;&amp; ((Integer)context.getVariable("updaterLaunchSelection")).intValue() == 0</property>
                            </object>
                          </property>
                        </serializedBean>
                        <beans>
                          <action name="Set installer arguments" id="2168" beanClass="com.install4j.runtime.beans.actions.control.SetVariableAction">
                            <serializedBean>
                              <property name="script">
                                <object class="com.install4j.api.beans.ScriptProperty">
                                  <property name="value" type="string">List&lt;String&gt; args = new ArrayList&lt;String&gt;();
String installationDirectory = context.getInstallationDirectory().getPath();
if (context.isUnattended()) {
    args.add("-q");
    args.add("-wait");
    args.add("20");
    ProgressInterface progressInterface = context.getProgressInterface();
    if (progressInterface.isUnattendedProgressDialog()) {
        if (progressInterface.isAlertsShown()) {
            args.add("-alerts");
        }
        args.add("-splash");
        args.add("Installing");
    }
} else if (context.isConsole()) {
    args.add("-c");
}
 args.add("-dir");
 args.add(installationDirectory);

 return args.toArray(new String[args.size()]);
</property>
                                </object>
                              </property>
                              <property name="variableName" type="string">installerArguments</property>
                            </serializedBean>
                          </action>
                          <action id="2169" beanClass="com.install4j.runtime.beans.actions.update.ShutdownCallingLauncherAction" actionElevationType="none" />
                          <action id="2170" beanClass="com.install4j.runtime.beans.actions.misc.RunExecutableAction" actionElevationType="elevated" failureStrategy="quit" errorMessage="${i18n:updater.LaunchError}">
                            <serializedBean>
                              <property name="arguments" type="array" elementType="string" length="1">
                                <element index="0">${installer:installerArguments}</element>
                              </property>
                              <property name="executable">
                                <object class="java.io.File">
                                  <string>${installer:updaterDownloadFile}</string>
                                </object>
                              </property>
                              <property name="workingDirectory">
                                <object class="java.io.File">
                                  <string>${installer:updaterDownloadLocation}</string>
                                </object>
                              </property>
                            </serializedBean>
                          </action>
                        </beans>
                      </group>
                    </actions>
                    <formComponents>
                      <formComponent id="2189" beanClass="com.install4j.runtime.beans.formcomponents.MultilineLabelComponent" useExternalParametrization="true" externalParametrizationName="Header" externalParametrizationMode="include">
                        <serializedBean>
                          <property name="hideIfBlank" type="boolean" value="true" />
                          <property name="labelText" type="string">${i18n:updater.FinishInfoText("${compiler:sys.fullName}")}</property>
                        </serializedBean>
                        <visibilityScript>!context.isConsole()</visibilityScript>
                        <externalParametrizationPropertyNames>
                          <propertyName>labelText</propertyName>
                        </externalParametrizationPropertyNames>
                      </formComponent>
                      <formComponent id="2171" beanClass="com.install4j.runtime.beans.formcomponents.LabelComponent">
                        <serializedBean>
                          <property name="labelText" type="string">${i18n:updater.LaunchUpdaterQuestion}</property>
                        </serializedBean>
                      </formComponent>
                      <formComponent id="2172" beanClass="com.install4j.runtime.beans.formcomponents.SpacerComponent">
                        <serializedBean>
                          <property name="height" type="int" value="5" />
                        </serializedBean>
                      </formComponent>
                      <formComponent id="2173" beanClass="com.install4j.runtime.beans.formcomponents.RadiobuttonsComponent">
                        <serializedBean>
                          <property name="radioButtonLabels" type="array" elementType="string" length="2">
                            <element index="0">${i18n:updater.LaunchUpdaterLabel}</element>
                            <element index="1">${i18n:updater.DoNotLaunchUpdaterLabel}</element>
                          </property>
                          <property name="variableName" type="string">updaterLaunchSelection</property>
                        </serializedBean>
                        <visibilityScript>!context.getBooleanVariable("isArchive")</visibilityScript>
                      </formComponent>
                      <formComponent id="2174" beanClass="com.install4j.runtime.beans.formcomponents.HyperlinkActionLabelComponent">
                        <serializedBean>
                          <property name="actionScript">
                            <object class="com.install4j.api.beans.ScriptProperty">
                              <property name="value" type="string">Util.showPath((String)context.getVariable("updaterDownloadFile"));</property>
                            </object>
                          </property>
                          <property name="hyperlinkText" type="string">${i18n:updater.OpenContainingFolderLabel}</property>
                        </serializedBean>
                        <visibilityScript>!context.isConsole()</visibilityScript>
                      </formComponent>
                      <formComponent id="2175" beanClass="com.install4j.runtime.beans.formcomponents.ProgressComponent">
                        <serializedBean>
                          <property name="detailVisible" type="boolean" value="false" />
                          <property name="hideInitially" type="boolean" value="true" />
                        </serializedBean>
                      </formComponent>
                    </formComponents>
                  </screen>
                  <screen name="Finish DMG Archive" id="2176" beanClass="com.install4j.runtime.beans.screens.FormScreen" styleId="2394" finishScreen="true">
                    <serializedBean>
                      <property name="title" type="string">${i18n:updater.FinishTitle}</property>
                    </serializedBean>
                    <condition>context.getBooleanVariable("isArchive") &amp;&amp; context.getBooleanVariable("isDmg")</condition>
                    <actions>
                      <group name="Execute installer" id="2177" beanClass="com.install4j.runtime.beans.groups.ActionGroup">
                        <serializedBean>
                          <property name="conditionExpression">
                            <object class="com.install4j.api.beans.ScriptProperty">
                              <property name="value" type="string">context.getBooleanVariable("updaterOpenDmg")</property>
                            </object>
                          </property>
                        </serializedBean>
                        <beans>
                          <action id="2178" beanClass="com.install4j.runtime.beans.actions.update.ShutdownCallingLauncherAction" actionElevationType="none" />
                          <action name="Open DMG" id="2179" beanClass="com.install4j.runtime.beans.actions.control.RunScriptAction">
                            <serializedBean>
                              <property name="script">
                                <object class="com.install4j.api.beans.ScriptProperty">
                                  <property name="value" type="string">Util.showPath((String)context.getVariable("updaterDownloadFile"));
return true;</property>
                                </object>
                              </property>
                            </serializedBean>
                          </action>
                        </beans>
                      </group>
                    </actions>
                    <formComponents>
                      <formComponent id="2220" beanClass="com.install4j.runtime.beans.formcomponents.MultilineLabelComponent" useExternalParametrization="true" externalParametrizationName="Header" externalParametrizationMode="include">
                        <serializedBean>
                          <property name="hideIfBlank" type="boolean" value="true" />
                          <property name="labelText" type="string">${i18n:updater.FinishInfoText("${compiler:sys.fullName}")}</property>
                        </serializedBean>
                        <visibilityScript>!context.isConsole()</visibilityScript>
                        <externalParametrizationPropertyNames>
                          <propertyName>labelText</propertyName>
                        </externalParametrizationPropertyNames>
                      </formComponent>
                      <formComponent id="2180" beanClass="com.install4j.runtime.beans.formcomponents.LabelComponent">
                        <serializedBean>
                          <property name="labelText" type="string">${i18n:updater.LaunchUpdaterQuestion}</property>
                        </serializedBean>
                      </formComponent>
                      <formComponent id="2181" beanClass="com.install4j.runtime.beans.formcomponents.SpacerComponent">
                        <serializedBean>
                          <property name="height" type="int" value="5" />
                        </serializedBean>
                      </formComponent>
                      <formComponent id="2218" beanClass="com.install4j.runtime.beans.formcomponents.CheckboxComponent">
                        <serializedBean>
                          <property name="checkboxText" type="string">${i18n:updater.OpenContainingFolderLabel}</property>
                          <property name="initiallySelected" type="boolean" value="true" />
                          <property name="variableName" type="string">updaterOpenDmg</property>
                        </serializedBean>
                      </formComponent>
                      <formComponent id="2183" beanClass="com.install4j.runtime.beans.formcomponents.ProgressComponent">
                        <serializedBean>
                          <property name="detailVisible" type="boolean" value="false" />
                          <property name="hideInitially" type="boolean" value="true" />
                        </serializedBean>
                      </formComponent>
                    </formComponents>
                  </screen>
                </beans>
              </group>
            </beans>
          </group>
        </screens>
      </application>
      <application name="Background update downloader" id="2297" beanClass="com.install4j.runtime.beans.applications.CustomApplication" customIcnsFile="${compiler:sys.install4jHome}/resource/macos/updater.icns">
        <serializedBean>
          <property name="customIconImageFiles">
            <add>
              <object class="com.install4j.api.beans.ExternalFile">
                <string>${compiler:sys.install4jHome}/resource/updater_16.png</string>
              </object>
            </add>
            <add>
              <object class="com.install4j.api.beans.ExternalFile">
                <string>${compiler:sys.install4jHome}/resource/updater_32.png</string>
              </object>
            </add>
            <add>
              <object class="com.install4j.api.beans.ExternalFile">
                <string>${compiler:sys.install4jHome}/resource/updater_48.png</string>
              </object>
            </add>
            <add>
              <object class="com.install4j.api.beans.ExternalFile">
                <string>${compiler:sys.install4jHome}/resource/updater_128.png</string>
              </object>
            </add>
            <add>
              <object class="com.install4j.api.beans.ExternalFile">
                <string>${compiler:sys.install4jHome}/resource/updater_256.png</string>
              </object>
            </add>
          </property>
          <property name="executableName" type="string">bgupdater</property>
          <property name="useCustomIcon" type="boolean" value="true" />
          <property name="vmParameters" type="string">-Dapple.awt.UIElement=true</property>
          <property name="windowTitle" type="string">${compiler:sys.fullName}</property>
        </serializedBean>
        <startup>
          <screen id="2298" beanClass="com.install4j.runtime.beans.screens.StartupScreen" rollbackBarrierExitCode="0">
            <actions>
              <action name="Check prerequisites" id="2299" beanClass="com.install4j.runtime.beans.actions.control.RunScriptAction" rollbackBarrierExitCode="0" failureStrategy="quit">
                <serializedBean>
                  <property name="script">
                    <object class="com.install4j.api.beans.ScriptProperty">
                      <property name="value" type="string">import java.nio.file.*;

Path dir = context.getInstallationDirectory().toPath();
// quit if the current installation is on a read only file system, for example a disk image on macOS
// or if the directory is not writable on Linux/Unix.
// If there is no "Request privileges" action in the installer, the condition should also
// check Files.isWritable(dir)
return !Files.getFileStore(dir).isReadOnly() &amp;&amp; ((Util.isWindows() &amp;&amp; !Util.isArchive()) || Util.isMacOS() || (Util.isLinux() &amp;&amp; !Util.isArchive()));
</property>
                    </object>
                  </property>
                </serializedBean>
              </action>
              <action id="2300" beanClass="com.install4j.runtime.beans.actions.update.CheckForUpdateAction" actionElevationType="none" failureStrategy="quit">
                <serializedBean>
                  <property name="url" type="string">${compiler:sys.updatesUrl}</property>
                  <property name="variable" type="string">updateDescriptor</property>
                </serializedBean>
              </action>
              <action name="Update descriptor entry" id="2301" beanClass="com.install4j.runtime.beans.actions.control.SetVariableAction" failureStrategy="quit">
                <serializedBean>
                  <property name="failIfNull" type="boolean" value="true" />
                  <property name="script">
                    <object class="com.install4j.api.beans.ScriptProperty">
                      <property name="value" type="string">UpdateDescriptorEntry entry = ((UpdateDescriptor)context.getVariable("updateDescriptor")).getPossibleUpdateEntry();

if (entry == null) {
    return null;
} else if (entry.isArchive() &amp;&amp; !entry.isSingleBundle()) {
    // only installers and single bundle archives on macOS are supported
    return null;
} else if (entry.isDownloaded()) {
    // update has been downloaded already
    return null;
} else {
    return entry;
}</property>
                    </object>
                  </property>
                  <property name="variableName" type="string">updateDescriptorEntry</property>
                </serializedBean>
              </action>
              <group name="Update available" id="2302" beanClass="com.install4j.runtime.beans.groups.ActionGroup">
                <serializedBean>
                  <property name="conditionExpression">
                    <object class="com.install4j.api.beans.ScriptProperty">
                      <property name="value" type="string">context.getVariable("updateDescriptorEntry") != null</property>
                    </object>
                  </property>
                </serializedBean>
                <beans>
                  <action name="New version" id="2303" beanClass="com.install4j.runtime.beans.actions.control.SetVariableAction">
                    <serializedBean>
                      <property name="script">
                        <object class="com.install4j.api.beans.ScriptProperty">
                          <property name="value" type="string">((UpdateDescriptorEntry)context.getVariable("updateDescriptorEntry")).getNewVersion()</property>
                        </object>
                      </property>
                      <property name="variableName" type="string">updaterNewVersion</property>
                    </serializedBean>
                  </action>
                  <action name="Download URL" id="2304" beanClass="com.install4j.runtime.beans.actions.control.SetVariableAction">
                    <serializedBean>
                      <property name="script">
                        <object class="com.install4j.api.beans.ScriptProperty">
                          <property name="value" type="string">((UpdateDescriptorEntry)context.getVariable("updateDescriptorEntry")).getURL().toExternalForm()</property>
                        </object>
                      </property>
                      <property name="variableName" type="string">updaterDownloadUrl</property>
                    </serializedBean>
                  </action>
                  <action name="Download location" id="2305" beanClass="com.install4j.runtime.beans.actions.control.SetVariableAction">
                    <serializedBean>
                      <property name="script">
                        <object class="com.install4j.api.beans.ScriptProperty">
                          <property name="value" type="string">context.getVariable("sys.updateStorageDir") + File.separator + ((UpdateDescriptorEntry)context.getVariable("updateDescriptorEntry")).getFileName()</property>
                        </object>
                      </property>
                      <property name="variableName" type="string">updaterDownloadFile</property>
                    </serializedBean>
                  </action>
                  <action id="2306" customizedId="downloadFile" beanClass="com.install4j.runtime.beans.actions.net.DownloadFileAction" failureStrategy="quit">
                    <serializedBean>
                      <property name="targetFile">
                        <object class="java.io.File">
                          <string>${installer:updaterDownloadFile}</string>
                        </object>
                      </property>
                      <property name="url" type="string">${installer:updaterDownloadUrl}</property>
                    </serializedBean>
                  </action>
                  <group name="Installer" id="2307" beanClass="com.install4j.runtime.beans.groups.ActionGroup">
                    <serializedBean>
                      <property name="conditionExpression">
                        <object class="com.install4j.api.beans.ScriptProperty">
                          <property name="value" type="string">!((UpdateDescriptorEntry)context.getVariable("updateDescriptorEntry")).isArchive()</property>
                        </object>
                      </property>
                    </serializedBean>
                    <beans>
                      <action id="2308" beanClass="com.install4j.runtime.beans.actions.files.SetModeAction" actionElevationType="elevated">
                        <serializedBean>
                          <property name="files" type="array" class="java.io.File" length="1">
                            <element index="0">
                              <object class="java.io.File">
                                <string>${installer:updaterDownloadFile}</string>
                              </object>
                            </element>
                          </property>
                          <property name="mode" type="string">755</property>
                        </serializedBean>
                      </action>
                      <action id="2309" beanClass="com.install4j.runtime.beans.actions.update.ScheduleUpdateAction" actionElevationType="none" failureStrategy="quit">
                        <serializedBean>
                          <property name="installerFile">
                            <object class="java.io.File">
                              <string>${installer:updaterDownloadFile}</string>
                            </object>
                          </property>
                          <property name="version" type="string">${installer:updaterNewVersion}</property>
                        </serializedBean>
                      </action>
                    </beans>
                  </group>
                  <group name="Single Bundle Archive" id="2310" beanClass="com.install4j.runtime.beans.groups.ActionGroup">
                    <serializedBean>
                      <property name="conditionExpression">
                        <object class="com.install4j.api.beans.ScriptProperty">
                          <property name="value" type="string">((UpdateDescriptorEntry)context.getVariable("updateDescriptorEntry")).isArchive()</property>
                        </object>
                      </property>
                    </serializedBean>
                    <beans>
                      <action name="Staging Directory" id="2311" beanClass="com.install4j.runtime.beans.actions.control.SetVariableAction">
                        <serializedBean>
                          <property name="script">
                            <object class="com.install4j.api.beans.ScriptProperty">
                              <property name="value" type="string">String dirName = context.getVariable("updaterDownloadFile") + "_dir";
new File(dirName).mkdirs();
return dirName;</property>
                            </object>
                          </property>
                          <property name="variableName" type="string">updaterStagingDir</property>
                        </serializedBean>
                      </action>
                      <action name="Delete Staging Directory" id="2312" beanClass="com.install4j.runtime.beans.actions.files.DeleteFileAction" actionElevationType="elevated" rollbackBarrierExitCode="0">
                        <serializedBean>
                          <property name="backupForRollback" type="boolean" value="false" />
                          <property name="files" type="array" class="java.io.File" length="1">
                            <element index="0">
                              <object class="java.io.File">
                                <string>${installer:updaterStagingDir}</string>
                              </object>
                            </element>
                          </property>
                          <property name="recursive" type="boolean" value="true" />
                        </serializedBean>
                        <condition>new File((String)context.getVariable("updaterStagingDir")).exists()</condition>
                      </action>
                      <action id="2313" beanClass="com.install4j.runtime.beans.actions.files.ExtractDmgFileAction" actionElevationType="elevated" rollbackBarrierExitCode="0" failureStrategy="quit">
                        <serializedBean>
                          <property name="archiveFile">
                            <object class="java.io.File">
                              <string>${installer:updaterDownloadFile}</string>
                            </object>
                          </property>
                          <property name="destinationDirectory">
                            <object class="java.io.File">
                              <string>${installer:updaterStagingDir}</string>
                            </object>
                          </property>
                          <property name="fileFilter">
                            <object class="com.install4j.api.beans.ScriptProperty">
                              <property name="value" type="string">// only extract app bundle, no other top level files

import com.install4j.api.unix.UnixFileSystem;

File realFile = new File(dmgMountPoint, file.getPath());

return file.getParent() != null || (file.getName().endsWith(".app") &amp;&amp; realFile.isDirectory() &amp;&amp; !UnixFileSystem.getFileInformation(realFile).isLink());</property>
                            </object>
                          </property>
                        </serializedBean>
                        <condition>((String)context.getVariable("updaterDownloadFile")).endsWith(".dmg")</condition>
                      </action>
                      <action id="2314" beanClass="com.install4j.runtime.beans.actions.files.ExtractTarFileAction" actionElevationType="elevated" rollbackBarrierExitCode="0" failureStrategy="quit">
                        <serializedBean>
                          <property name="archiveFile">
                            <object class="java.io.File">
                              <string>${installer:updaterDownloadFile}</string>
                            </object>
                          </property>
                          <property name="destinationDirectory">
                            <object class="java.io.File">
                              <string>${installer:updaterStagingDir}</string>
                            </object>
                          </property>
                          <property name="fileFilter">
                            <object class="com.install4j.api.beans.ScriptProperty">
                              <property name="value" type="string">// only extract app bundle, no other top level files
file.getParent() != null || (file.getName().endsWith(".app") &amp;&amp; directory)</property>
                            </object>
                          </property>
                        </serializedBean>
                        <condition>!((String)context.getVariable("updaterDownloadFile")).endsWith(".dmg")</condition>
                      </action>
                      <action id="2315" beanClass="com.install4j.runtime.beans.actions.update.ScheduleUpdateAction" actionElevationType="none" failureStrategy="quit">
                        <serializedBean>
                          <property name="installerFile">
                            <object class="java.io.File">
                              <string>${installer:updaterStagingDir}</string>
                            </object>
                          </property>
                          <property name="version" type="string">${installer:updaterNewVersion}</property>
                        </serializedBean>
                      </action>
                      <action name="Delete archive" id="2316" beanClass="com.install4j.runtime.beans.actions.files.DeleteFileAction" actionElevationType="elevated" rollbackBarrierExitCode="0">
                        <serializedBean>
                          <property name="backupForRollback" type="boolean" value="false" />
                          <property name="files" type="array" class="java.io.File" length="1">
                            <element index="0">
                              <object class="java.io.File">
                                <string>${installer:updaterDownloadFile}</string>
                              </object>
                            </element>
                          </property>
                        </serializedBean>
                      </action>
                    </beans>
                  </group>
                </beans>
              </group>
            </actions>
          </screen>
        </startup>
      </application>
      <application name="Configure greeting" id="594" beanClass="com.install4j.runtime.beans.applications.CustomApplication" commentSet="true" comment="This is a maintenance application that the user can invoke after the application has been installed. A link is placed into the program group on Windows, the &quot;Hello GUI&quot; launcher also has a menu item that invokes this installer application and updates the greeting." customIcnsFile="./resources/preferences.icns" launchInNewProcess="false">
        <serializedBean>
          <property name="changeWorkingDir" type="boolean" value="true" />
          <property name="customIconImageFiles">
            <add>
              <object class="com.install4j.api.beans.ExternalFile">
                <string>./resources/preferences16x16.png</string>
              </object>
            </add>
            <add>
              <object class="com.install4j.api.beans.ExternalFile">
                <string>./resources/preferences32x32.png</string>
              </object>
            </add>
            <add>
              <object class="com.install4j.api.beans.ExternalFile">
                <string>./resources/preferences48x48.png</string>
              </object>
            </add>
            <add>
              <object class="com.install4j.api.beans.ExternalFile">
                <string>./resources/preferences128x128.png</string>
              </object>
            </add>
            <add>
              <object class="com.install4j.api.beans.ExternalFile">
                <string>./resources/preferences256x256.png</string>
              </object>
            </add>
          </property>
          <property name="executableDirectory">
            <object class="java.io.File">
              <string>.</string>
            </object>
          </property>
          <property name="executableName" type="string">configureGreeting</property>
          <property name="useCustomIcon" type="boolean" value="true" />
          <property name="windowTitle" type="string">Configure Greeting</property>
        </serializedBean>
        <startup>
          <screen id="595" beanClass="com.install4j.runtime.beans.screens.StartupScreen" rollbackBarrierExitCode="0">
            <actions>
              <action id="1280" beanClass="com.install4j.runtime.beans.actions.registry.LoadInstallerVariablesAction" actionElevationType="elevated">
                <serializedBean>
                  <property name="packageName" type="string">${compiler:sys.applicationId}</property>
                </serializedBean>
              </action>
            </actions>
          </screen>
        </startup>
        <screens>
          <link id="596" targetId="73" />
          <screen name="Finish" id="598" beanClass="com.install4j.runtime.beans.screens.FormScreen" styleId="2394" finishScreen="true">
            <serializedBean>
              <property name="title" type="string">Configuration Updated</property>
            </serializedBean>
            <actions>
              <link id="1278" targetId="1145" />
            </actions>
            <formComponents>
              <formComponent id="2228" beanClass="com.install4j.runtime.beans.formcomponents.MultilineLabelComponent" useExternalParametrization="true" externalParametrizationName="Header" externalParametrizationMode="include">
                <serializedBean>
                  <property name="hideIfBlank" type="boolean" value="true" />
                  <property name="labelText" type="string">Your greeting name has been updated in the Hello World Suite Greeting database.</property>
                </serializedBean>
                <visibilityScript>!context.isConsole()</visibilityScript>
                <externalParametrizationPropertyNames>
                  <propertyName>labelText</propertyName>
                </externalParametrizationPropertyNames>
              </formComponent>
            </formComponents>
          </screen>
        </screens>
      </application>
    </applications>
    <styles defaultStyleId="2388">
      <style name="Standard" id="2388" beanClass="com.install4j.runtime.beans.styles.FormStyle">
        <formComponents>
          <formComponent name="Header" id="2389" beanClass="com.install4j.runtime.beans.styles.NestedStyleComponent" insetTop="0" insetBottom="0">
            <serializedBean>
              <property name="styleId" type="string">2401</property>
            </serializedBean>
          </formComponent>
          <group name="Main" id="2390" beanClass="com.install4j.runtime.beans.groups.VerticalFormComponentGroup">
            <beans>
              <formComponent id="2391" beanClass="com.install4j.runtime.beans.styles.ContentComponent" insetTop="10" insetLeft="20" insetBottom="10" insetRight="20" />
              <formComponent name="Watermark" id="2392" beanClass="com.install4j.runtime.beans.formcomponents.SeparatorComponent" insetTop="0" insetLeft="5" insetBottom="0">
                <serializedBean>
                  <property name="enabledTitleText" type="boolean" value="false" />
                  <property name="labelText" type="string">install4j</property>
                </serializedBean>
              </formComponent>
              <formComponent name="Footer" id="2393" beanClass="com.install4j.runtime.beans.styles.NestedStyleComponent" insetTop="0" insetBottom="0">
                <serializedBean>
                  <property name="styleId" type="string">2405</property>
                </serializedBean>
              </formComponent>
            </beans>
          </group>
        </formComponents>
      </style>
      <style name="Banner" id="2394" beanClass="com.install4j.runtime.beans.styles.FormStyle">
        <formComponents>
          <group id="2395" beanClass="com.install4j.runtime.beans.groups.VerticalFormComponentGroup" useExternalParametrization="true" externalParametrizationName="Customize banner image" externalParametrizationMode="include">
            <serializedBean>
              <property name="backgroundColor">
                <object class="com.install4j.runtime.beans.LightOrDarkColor">
                  <object class="java.awt.Color">
                    <int>255</int>
                    <int>255</int>
                    <int>255</int>
                    <int>255</int>
                  </object>
                  <object class="java.awt.Color">
                    <int>49</int>
                    <int>52</int>
                    <int>53</int>
                    <int>255</int>
                  </object>
                </object>
              </property>
              <property name="borderSides">
                <object class="com.install4j.runtime.beans.formcomponents.BorderSides">
                  <property name="bottom" type="boolean" value="true" />
                </object>
              </property>
              <property name="imageEdgeBackgroundColor">
                <object class="com.install4j.runtime.beans.LightOrDarkColor">
                  <object class="java.awt.Color">
                    <int>27</int>
                    <int>143</int>
                    <int>220</int>
                    <int>255</int>
                  </object>
                  <object class="java.awt.Color">
                    <int>0</int>
                    <int>73</int>
                    <int>150</int>
                    <int>255</int>
                  </object>
                </object>
              </property>
              <property name="imageFile">
                <object class="com.install4j.api.beans.ExternalFile">
                  <string>${compiler:sys.install4jHome}/resource/styles/wizard.png</string>
                </object>
              </property>
              <property name="insets">
                <object class="java.awt.Insets">
                  <int>5</int>
                  <int>10</int>
                  <int>10</int>
                  <int>10</int>
                </object>
              </property>
            </serializedBean>
            <beans>
              <formComponent id="2396" beanClass="com.install4j.runtime.beans.styles.ScreenTitleComponent" insetTop="0">
                <serializedBean>
                  <property name="labelWidgetStyle" id="LabelWidgetStyle0">
                    <property name="fontDescriptor">
                      <property name="fontSizePercent" type="int" value="130" />
                      <property name="fontStyle" type="enum" class="com.install4j.runtime.beans.formcomponents.FontStyle" value="BOLD" />
                      <property name="fontType" type="enum" class="com.install4j.runtime.beans.formcomponents.FontType" value="DERIVED" />
                    </property>
                  </property>
                  <property name="labelWidgetStyleId" type="null" />
                </serializedBean>
              </formComponent>
              <formComponent id="2397" beanClass="com.install4j.runtime.beans.formcomponents.SeparatorComponent" />
              <formComponent id="2398" beanClass="com.install4j.runtime.beans.styles.ContentComponent" insetTop="10" insetBottom="0" />
            </beans>
            <externalParametrizationPropertyNames>
              <propertyName>imageAnchor</propertyName>
              <propertyName>imageEdgeBackgroundColor</propertyName>
              <propertyName>imageFile</propertyName>
            </externalParametrizationPropertyNames>
          </group>
          <formComponent id="2399" beanClass="com.install4j.runtime.beans.styles.NestedStyleComponent" insetBottom="0">
            <serializedBean>
              <property name="styleId" type="string">2405</property>
            </serializedBean>
          </formComponent>
        </formComponents>
      </style>
      <group name="Style components" id="2400" beanClass="com.install4j.runtime.beans.groups.StyleGroup">
        <beans>
          <style name="Standard header" id="2401" beanClass="com.install4j.runtime.beans.styles.FormStyle">
            <serializedBean>
              <property name="fillVertical" type="boolean" value="false" />
              <property name="standalone" type="boolean" value="false" />
              <property name="verticalAnchor" type="enum" class="com.install4j.api.beans.Anchor" value="NORTH" />
            </serializedBean>
            <formComponents>
              <group id="2402" beanClass="com.install4j.runtime.beans.groups.VerticalFormComponentGroup" useExternalParametrization="true" externalParametrizationName="Customize title bar" externalParametrizationMode="include">
                <serializedBean>
                  <property name="backgroundColor">
                    <object class="com.install4j.runtime.beans.LightOrDarkColor">
                      <object class="java.awt.Color">
                        <int>255</int>
                        <int>255</int>
                        <int>255</int>
                        <int>255</int>
                      </object>
                      <object class="java.awt.Color">
                        <int>49</int>
                        <int>52</int>
                        <int>53</int>
                        <int>255</int>
                      </object>
                    </object>
                  </property>
                  <property name="borderSides">
                    <object class="com.install4j.runtime.beans.formcomponents.BorderSides">
                      <property name="bottom" type="boolean" value="true" />
                    </object>
                  </property>
                  <property name="imageAnchor" type="enum" class="com.install4j.api.beans.Anchor" value="NORTHEAST" />
                  <property name="imageEdgeBorderWidth" type="int" value="2" />
                  <property name="imageFile">
                    <object class="com.install4j.api.beans.ExternalFile">
                      <string>icon:${installer:sys.installerApplicationMode}_header.png</string>
                    </object>
                  </property>
                  <property name="imageInsets">
                    <object class="java.awt.Insets">
                      <int>0</int>
                      <int>5</int>
                      <int>1</int>
                      <int>1</int>
                    </object>
                  </property>
                  <property name="insets">
                    <object class="java.awt.Insets">
                      <int>0</int>
                      <int>20</int>
                      <int>0</int>
                      <int>10</int>
                    </object>
                  </property>
                </serializedBean>
                <beans>
                  <formComponent name="Title" id="2403" beanClass="com.install4j.runtime.beans.styles.ScreenTitleComponent">
                    <serializedBean>
                      <property name="labelWidgetStyle" id="LabelWidgetStyle0">
                        <property name="fontDescriptor">
                          <property name="fontStyle" type="enum" class="com.install4j.runtime.beans.formcomponents.FontStyle" value="BOLD" />
                          <property name="fontType" type="enum" class="com.install4j.runtime.beans.formcomponents.FontType" value="DERIVED" />
                        </property>
                      </property>
                      <property name="labelWidgetStyleId" type="null" />
                    </serializedBean>
                  </formComponent>
                  <formComponent name="Subtitle" id="2404" beanClass="com.install4j.runtime.beans.styles.ScreenTitleComponent" insetLeft="8">
                    <serializedBean>
                      <property name="titleType" type="enum" class="com.install4j.runtime.beans.styles.TitleType" value="SUB_TITLE" />
                    </serializedBean>
                  </formComponent>
                </beans>
                <externalParametrizationPropertyNames>
                  <propertyName>backgroundColor</propertyName>
                  <propertyName>foregroundColor</propertyName>
                  <propertyName>imageAnchor</propertyName>
                  <propertyName>imageFile</propertyName>
                  <propertyName>imageOverlap</propertyName>
                </externalParametrizationPropertyNames>
              </group>
            </formComponents>
          </style>
          <style name="Standard footer" id="2405" beanClass="com.install4j.runtime.beans.styles.FormStyle">
            <serializedBean>
              <property name="fillVertical" type="boolean" value="false" />
              <property name="standalone" type="boolean" value="false" />
              <property name="verticalAnchor" type="enum" class="com.install4j.api.beans.Anchor" value="SOUTH" />
            </serializedBean>
            <formComponents>
              <group id="2406" beanClass="com.install4j.runtime.beans.groups.HorizontalFormComponentGroup">
                <serializedBean>
                  <property name="alignFirstLabel" type="boolean" value="false" />
                  <property name="insets">
                    <object class="java.awt.Insets">
                      <int>3</int>
                      <int>5</int>
                      <int>8</int>
                      <int>5</int>
                    </object>
                  </property>
                </serializedBean>
                <beans>
                  <formComponent id="2407" beanClass="com.install4j.runtime.beans.formcomponents.SpringComponent" />
                  <formComponent name="Back button" id="2408" beanClass="com.install4j.runtime.beans.styles.StandardControlButtonComponent">
                    <serializedBean>
                      <property name="buttonText" type="string">&lt; ${i18n:ButtonBack}</property>
                      <property name="controlButtonType" type="enum" class="com.install4j.api.context.ControlButtonType" value="PREVIOUS" />
                    </serializedBean>
                  </formComponent>
                  <formComponent name="Next button" id="2409" beanClass="com.install4j.runtime.beans.styles.StandardControlButtonComponent">
                    <serializedBean>
                      <property name="buttonText" type="string">${i18n:ButtonNext} &gt;</property>
                      <property name="controlButtonType" type="enum" class="com.install4j.api.context.ControlButtonType" value="NEXT" />
                    </serializedBean>
                  </formComponent>
                  <formComponent name="Cancel button" id="2410" beanClass="com.install4j.runtime.beans.styles.StandardControlButtonComponent" insetLeft="5">
                    <serializedBean>
                      <property name="buttonText" type="string">${i18n:ButtonCancel}</property>
                      <property name="controlButtonType" type="enum" class="com.install4j.api.context.ControlButtonType" value="CANCEL" />
                    </serializedBean>
                  </formComponent>
                </beans>
              </group>
            </formComponents>
          </style>
        </beans>
      </group>
    </styles>
    <widgetStyles defaultWidgetStyleId="229">
      <widgetStyle name="Standard" id="229" beanClass="com.install4j.runtime.beans.widgets.WidgetStyleCollection" />
    </widgetStyles>
  </installerGui>
  <mediaSets>
    <windows name="Windows 64-bit" id="463" mediaFileName="${compiler:sys.shortName}_${compiler:sys.platform}_${compiler:sys.version}" installDir="hello" architecture="64" />
    <linuxRPM name="Linux RPM" id="9" installDir="/opt/hello">
      <exclude>
        <entry filesetId="1148" />
      </exclude>
      <jreBundle jreBundleSource="none" />
    </linuxRPM>
    <linuxDeb name="Linux Deb Archive" id="1677" installDir="/opt/hello" bzip="true" description="Hello Sample Project" maintainerEmail="info@ej-technologies.com">
      <exclude>
        <entry filesetId="1148" />
      </exclude>
      <jreBundle jreBundleSource="none" />
    </linuxDeb>
    <macosFolder name="macOS Folder" id="11" mediaFileName="${compiler:sys.shortName}_${compiler:sys.platform}_${compiler:sys.version}_folder" installDir="hello" architecture="universal">
      <exclude>
        <entry filesetId="1148" />
      </exclude>
    </macosFolder>
    <macosArchive name="macOS Single Bundle Archive" id="2060" architecture="universal" launcherId="5">
      <exclude>
        <entry filesetId="1148" />
      </exclude>
    </macosArchive>
    <unixInstaller name="Unix Installer" id="12" installDir="hello">
      <jreBundle jreBundleSource="none" />
    </unixInstaller>
  </mediaSets>
</install4j>
