JAL-4477 install4j 11 template
authorBen Soares <b.soares@dundee.ac.uk>
Tue, 29 Oct 2024 18:46:13 +0000 (18:46 +0000)
committerBen Soares <b.soares@dundee.ac.uk>
Tue, 29 Oct 2024 18:46:13 +0000 (18:46 +0000)
utils/install4j/install4j11_template.install4j [new file with mode: 0644]

diff --git a/utils/install4j/install4j11_template.install4j b/utils/install4j/install4j11_template.install4j
new file mode 100644 (file)
index 0000000..312ee1b
--- /dev/null
@@ -0,0 +1,3171 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<install4j version="11.0.1" transformSequenceNumber="11">
+  <directoryPresets config="." />
+  <application name="${compiler:JALVIEW_APPLICATION_NAME}" applicationId="${compiler:WINDOWS_APPLICATION_ID}" mediaDir="${compiler:JALVIEW_DIR}/${compiler:BUILD_DIR}" lzmaCompression="true" shortName="${compiler:INTERNAL_ID}" publisher="University of Dundee" publisherWeb="https://www.jalview.org/" version="${compiler:JALVIEW_VERSION}" allPathsRelative="true" macVolumeId="5aac4968c304f65" javaMinVersion="${compiler:JAVA_MIN_VERSION}" javaMaxVersion="${compiler:JAVA_MAX_VERSION}" allowBetaVM="true" jdkMode="jdk" jdkName="JDK 11.0">
+    <searchSequence>
+      <directory location="${compiler:JRE_DIR}" />
+      <installations />
+      <registry />
+      <envVar name="JAVA_HOME" />
+    </searchSequence>
+    <variables>
+      <variable name="JALVIEW_NAME" value="Jalview" />
+      <variable name="JALVIEW_APPLICATION_NAME" value="Jalview" />
+      <variable name="JALVIEW_DIR" value="../.." />
+      <variable name="BUILD_DIR" value="${compiler:JALVIEW_DIR}/build/install4j" />
+      <variable name="OSX_KEYSTORE" />
+      <variable name="OSX_APPLEID" />
+      <variable name="JSIGN_SH" value="echo" />
+      <variable name="JRE_DIR" value="jre" description="The folder under the app folder that the JRE will be either copied or unpacked into" />
+      <variable name="INSTALLER_TEMPLATE_VERSION" value="DEVELOPMENT_default" />
+      <variable name="JALVIEW_VERSION" value="DEVELOPMENT" />
+      <variable name="JAVA_MIN_VERSION" value="11" />
+      <variable name="JAVA_MAX_VERSION" value="11" />
+      <variable name="JAVA_VERSION" value="11" />
+      <variable name="JAVA_INTEGER_VERSION" value="11" />
+      <variable name="VERSION" value="DEVELOPMENT" />
+      <variable name="MACOS_X64_JAVA_VM_DIR" value="${compiler:env.HOME}/buildtools/jre/jre-${compiler:JAVA_INTEGER_VERSION}-mac-x/jre" />
+      <variable name="MACOS_AARCH64_JAVA_VM_DIR" value="${compiler:env.HOME}/buildtools/jre/jre-${compiler:JAVA_INTEGER_VERSION}-mac-aarch64/jre" />
+      <variable name="WINDOWS_X64_JAVA_VM_DIR" value="${compiler:env.HOME}/buildtools/jre/jre-${compiler:JAVA_INTEGER_VERSION}-windows-x64/jre" />
+      <variable name="LINUX_X64_JAVA_VM_DIR" value="${compiler:env.HOME}/buildtools/jre/jre-${compiler:JAVA_INTEGER_VERSION}-linux-x64/jre" />
+      <variable name="LINUX_AARCH64_JAVA_VM_DIR" value="${compiler:env.HOME}/buildtools/jre/jre-${compiler:JAVA_INTEGER_VERSION}-linux-aarch64/jre" />
+      <variable name="MACOS_X64_JAVA_VM_TGZ" value="${compiler:env.HOME}/buildtools/jre/tgz/jre_${compiler:JAVA_INTEGER_VERSION}_mac_x64.tar.gz" />
+      <variable name="MACOS_AARCH64_JAVA_VM_TGZ" value="${compiler:env.HOME}/buildtools/jre/tgz/jre_${compiler:JAVA_INTEGER_VERSION}_mac_aarch64.tar.gz" />
+      <variable name="WINDOWS_X64_JAVA_VM_TGZ" value="${compiler:env.HOME}/buildtools/jre/tgz/jre_${compiler:JAVA_INTEGER_VERSION}_windows_x64.tar.gz" />
+      <variable name="LINUX_X64_JAVA_VM_TGZ" value="${compiler:env.HOME}/buildtools/jre/tgz/jre_${compiler:JAVA_INTEGER_VERSION}_linux_x64.tar.gz" />
+      <variable name="LINUX_AARCH64_JAVA_VM_TGZ" value="${compiler:env.HOME}/buildtools/jre/tgz/jre_${compiler:JAVA_INTEGER_VERSION}_linux_aarch64.tar.gz" />
+      <variable name="COPYRIGHT_MESSAGE" value="..." />
+      <variable name="BUNDLE_ID" value="org.jalview.jalview-desktop" />
+      <variable name="INTERNAL_ID" value="Jalview" />
+      <variable name="WINDOWS_APPLICATION_ID" value="6595-2347-1923-0725" />
+      <variable name="MACOS_X64_DMG_DS_STORE" value="utils/channels/default/images/jalview_default_dmg_DS_Store" />
+      <variable name="MACOS_AARCH64_DMG_DS_STORE" value="utils/channels/default/images/jalview_default_dmg_DS_Store" />
+      <variable name="MACOS_DMG_DS_STORE" value="utils/channels/default/images/jalview_default_dmg_DS_Store" />
+      <variable name="MACOS_DMG_BG_IMAGE" value="utils/channels/default/images/jalview_default_dmg_background-72dpi.png" />
+      <variable name="MACOS_DMG_BG_FILENAME" value="background.png" />
+      <variable name="MACOSARCHIVE_VOLUMEICON" />
+      <variable name="WRAPPER_LINK" value="jalview" />
+      <variable name="BASH_WRAPPER_SCRIPT" value="jalview.sh" />
+      <variable name="POWERSHELL_WRAPPER_SCRIPT" value="jalview.ps1" />
+      <variable name="BASH_UPDATE_SCRIPT" value="update.sh" />
+      <variable name="POWERSHELL_UPDATE_SCRIPT" value="update.ps1" />
+      <variable name="WRAPPER_SCRIPT_BIN_DIR" value="bin" />
+      <variable name="MACOSARCHIVE_X64_NAME" value="Install Jalview (Intel)" />
+      <variable name="MACOSARCHIVE_AARCH64_NAME" value="Install Jalview (Apple Silicon)" />
+      <variable name="INSTALL4J_UTILS_DIR" value="utils/install4j" />
+      <variable name="GETDOWN_CHANNEL_DIR" value="build/website/docroot/getdown/default" />
+      <variable name="GETDOWN_FILES_DIR" value="getdown/files" />
+      <variable name="GETDOWN_RESOURCE_DIR" value="resource" />
+      <variable name="GETDOWN_DIST_DIR" value="dist" />
+      <variable name="GETDOWN_ALT_DIR" value="alt" />
+      <variable name="GETDOWN_INSTALL_DIR" value="install" />
+      <variable name="INFO_PLIST_FILE_ASSOCIATIONS_FILE" value="file_associations_auto-Info_plist.xml" />
+      <variable name="APPLICATION_CATEGORIES" value="Science;Biology;Java;" />
+      <variable name="APPLICATION_FOLDER" value="Jalview" />
+      <variable name="UNIX_APPLICATION_FOLDER" value="jalview" />
+      <variable name="EXECUTABLE_NAME" value="jalviewg" />
+      <variable name="EXTRA_SCHEME" value="jalviewx" />
+      <variable name="ICONS_DIR" value="utils/channels/release/images" />
+      <variable name="MAC_ICONS_FILE" value="jalview_logo.icns" />
+      <variable name="WINDOWS_ICONS_FILE" value="jalview_logo.ico" />
+      <variable name="PNG_ICON_FILE" value="jalview_logo.png" />
+      <variable name="BACKGROUND" value="utils/channels/release/images/jalview_logo_background_fade-640x480.png" />
+      <variable name="WIZARD_WIDTH" value="960" description="Default/initial width of installer wizard window.  Linux media types adapt this.&#xA;NOT USED" />
+      <variable name="WIZARD_HEIGHT" value="720" description="Default/initial width of installer wizard window.  Linux media types adapt this.&#xA;NOT USED" />
+      <variable name="MACOSARCHIVE_X64_DMG_FILENAME" value="${compiler:APPLICATION_FOLDER}-${compiler:JALVIEW_VERSION}-${compiler:sys.platform}-x64-java_${compiler:JAVA_INTEGER_VERSION}" />
+      <variable name="MACOSARCHIVE_AARCH64_DMG_FILENAME" value="${compiler:APPLICATION_FOLDER}-${compiler:JALVIEW_VERSION}-${compiler:sys.platform}-aarch64-java_${compiler:JAVA_INTEGER_VERSION}" />
+      <variable name="INSTALLER_ICON" value="jalview_installer.png" description="An icon with installation arrow.&#xA;NOT USED" />
+      <variable name="INSTALLER_MAC_ICON" value="jalview_installer.icns" description="An icon with installation arrow.&#xA;NOT USED" />
+      <variable name="INSTALLER_WINDOWS_ICON" value="jalview_installer.ico" description="An icon with installation arrow.&#xA;NOT USED" />
+      <variable name="TITLE_ICON" value="jalview_logo-64.png" description="Icon sized for the installer wizard title bar" />
+      <variable name="LOG_FILE" value=".jalview.log" />
+    </variables>
+    <codeSigning macEnabled="true" macPkcs12File="${compiler:OSX_KEYSTORE}">
+      <macAdditionalBinaries>
+        <entry>*.dylib</entry>
+        <entry>*.so</entry>
+        <entry>*.jnilib</entry>
+        <entry>unpack200</entry>
+        <entry>tnameserv</entry>
+        <entry>servertool</entry>
+        <entry>rmiregistry</entry>
+        <entry>rmid</entry>
+        <entry>policytool</entry>
+        <entry>pack200</entry>
+        <entry>orbd</entry>
+        <entry>keytool</entry>
+        <entry>jjs</entry>
+        <entry>java</entry>
+        <entry>jspawnhelper</entry>
+        <entry>libfreetype.dylib.6</entry>
+        <entry>applet</entry>
+        <entry>jaotc</entry>
+        <entry>jfr</entry>
+        <entry>jrunscript</entry>
+        <entry>libjli.dylib</entry>
+      </macAdditionalBinaries>
+    </codeSigning>
+  </application>
+  <files defaultUninstallMode="2">
+    <filesets>
+      <fileset name="Full file set" id="734" customizedId="FULL_FILE_SET" />
+      <fileset name="macOS x64 JVM" id="2801" customizedId="MACOS_X64_JVM" />
+      <fileset name="macOS aarch64 JVM" id="2803" customizedId="MACOS_AARCH64_JVM" />
+    </filesets>
+    <roots>
+      <root id="735" fileset="734" />
+      <root id="2802" fileset="2801" />
+      <root id="2804" fileset="2803" />
+    </roots>
+    <mountPoints>
+      <mountPoint id="736" root="735" />
+      <mountPoint id="2805" root="2802" />
+      <mountPoint id="2806" root="2804" />
+    </mountPoints>
+    <entries>
+      <dirEntry mountPoint="736" file="${compiler:JALVIEW_DIR}/${compiler:GETDOWN_CHANNEL_DIR}/${compiler:JAVA_VERSION}" uninstallMode="2" overrideOverwriteMode="true" overrideUninstallMode="true" subDirectory="files">
+        <exclude>
+          <entry location="${compiler:WRAPPER_SCRIPT_BIN_DIR}" />
+        </exclude>
+      </dirEntry>
+      <dirEntry mountPoint="736" file="${compiler:JALVIEW_DIR}/examples" overwriteMode="1" uninstallMode="2" overrideFileMode="true" overrideOverwriteMode="true" overrideUninstallMode="true" entryMode="subdir" subDirectory="examples" />
+      <dirEntry mountPoint="736" file="${compiler:JALVIEW_DIR}/${compiler:GETDOWN_CHANNEL_DIR}/${compiler:JAVA_VERSION}/${compiler:WRAPPER_SCRIPT_BIN_DIR}" fileMode="755" overrideFileMode="true" overrideUninstallMode="true" entryMode="subdir" subDirectory="${compiler:WRAPPER_SCRIPT_BIN_DIR}" overrideDirMode="true" />
+      <dirEntry mountPoint="2805" file="${compiler:MACOS_X64_JAVA_VM_DIR}" overwriteMode="1" fileMode="755" uninstallMode="2" overrideFileMode="true" overrideOverwriteMode="true" overrideUninstallMode="true" entryMode="subdir" subDirectory="${compiler:JRE_DIR}" />
+      <dirEntry mountPoint="2806" file="${compiler:MACOS_AARCH64_JAVA_VM_DIR}" overwriteMode="1" fileMode="755" uninstallMode="2" overrideFileMode="true" overrideOverwriteMode="true" overrideUninstallMode="true" entryMode="subdir" subDirectory="${compiler:JRE_DIR}" />
+    </entries>
+    <components>
+      <component name="jalview_getdown" id="1031" changeable="false" hidden="true">
+        <include>
+          <entry filesetId="734" />
+        </include>
+      </component>
+    </components>
+  </files>
+  <launchers>
+    <launcher name="Jalview User Launcher" id="2823" customizedId="JALVIEW" menuName="${compiler:JALVIEW_APPLICATION_NAME}" icnsFile="${compiler:JALVIEW_DIR}/${compiler:ICONS_DIR}/${compiler:MAC_ICONS_FILE}" customMacBundleIdentifier="true" macBundleIdentifier="${compiler:BUNDLE_ID}" fileset="734" addMacApplicationCategory="true" macApplicationCategory="public.app-category.education" useCustomMacosExecutableName="true" customMacosExecutableName="${compiler:JALVIEW_APPLICATION_NAME}">
+      <executable name="${compiler:EXECUTABLE_NAME}" iconSet="true" iconFile="${compiler:JALVIEW_DIR}/${compiler:ICONS_DIR}/${compiler:WINDOWS_ICONS_FILE}" stderrFile="~/.${compiler:LOG_FILE}" redirectStdout="true" stdoutFile="~/.${compiler:LOG_FILE}" executableMode="gui" changeWorkingDirectory="false" singleInstance="true" checkConsoleParameter="true">
+        <versionInfo include="true" fileDescription="${compiler:sys.fullName}" legalCopyright="${compiler:COPYRIGHT_MESSAGE}" internalName="${compiler:INTERNAL_ID}" productName="${compiler:sys.fullName}" />
+      </executable>
+      <splashScreen width="640" height="480" bitmapFile="${compiler:JALVIEW_DIR}/${compiler:BACKGROUND}" textOverlay="true">
+        <text>
+          <statusLine x="85" y="81" text="${compiler:sys.shortName}" fontSize="18" />
+          <versionLine x="85" y="109" text="version ${compiler:sys.version}" />
+        </text>
+      </splashScreen>
+      <java mainClass="com.threerings.getdown.launcher.GetdownApp" vmParameters="-Dsun.jnu.encoding=UTF-8 -Duserdefaultappdir=true -Dpopulatedefaultappdir=true -Dappid=jalview -Dinstaller.template_version=${compiler:INSTALLER_TEMPLATE_VERSION} -Dinstaller.appdir=&quot;${launcher:sys.launcherDirectory}&quot; -Dinstaller.application_folder=&quot;${compiler:APPLICATION_FOLDER}&quot; -Dchannel.app_name=&quot;${compiler:JALVIEW_APPLICATION_NAME}&quot; -Dinstaller.icon=&quot;${compiler:PNG_ICON_FILE}&quot; -Dinstaller.mac_icons=&quot;${compiler:MAC_ICONS_FILE}&quot; -Dinstaller.logfile=&quot;~/.${compiler:LOG_FILE}&quot; -Dinstaller.logfile_append=true" arguments="&quot;&quot; &quot;&quot;">
+        <classPath>
+          <archive location="getdown-launcher.jar" failOnError="false" />
+          <archive location="${compiler:GETDOWN_INSTALL_DIR}/getdown-launcher.jar" failOnError="false" />
+        </classPath>
+        <nativeLibraryDirectories>
+          <directory name="${compiler:JRE_DIR}/bin" />
+          <directory name="${compiler:GETDOWN_DIST_DIR}" />
+        </nativeLibraryDirectories>
+      </java>
+      <vmOptionsFile mode="content">
+        <content># Enter one VM parameter per line
+# For example, to adjust the maximum memory usage to 512 MB, uncomment the following line:
+# -Xmx512m
+# To include another file, uncomment the following line:
+# -include-options [path to other .vmoption file]
+
+# Jalview specific options below</content>
+      </vmOptionsFile>
+      <customScript>export LC_ALL=C.UTF-8</customScript>
+      <infoPlist>${compiler:file("${compiler:INFO_PLIST_FILE_ASSOCIATIONS_FILE}")}</infoPlist>
+      <iconImageFiles>
+        <file path="${compiler:JALVIEW_DIR}/${compiler:ICONS_DIR}/${compiler:PNG_ICON_FILE}" />
+      </iconImageFiles>
+      <macStaticAssociations>
+        <urlHandler scheme="jalview" />
+        <urlHandler scheme="jalviews" />
+        <urlHandler scheme="jalviewhttp" />
+        <urlHandler scheme="jalviewhttps" />
+        <urlHandler scheme="${compiler:EXTRA_SCHEME}" />
+      </macStaticAssociations>
+    </launcher>
+  </launchers>
+  <installerGui autoUpdateDescriptorUrl="https://www.jalview.org/install4j/updates.xml">
+    <staticMembers>/*
+
+import java.beans.BeanInfo;
+import java.beans.Introspector;
+import java.beans.PropertyDescriptor;
+import java.beans.IntrospectionException;
+import java.lang.reflect.Method;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Array;
+
+  public static String printDataType(Object o) {
+    return printDataType("", o);
+  }
+  
+  public static String printDataType(String prefix, Object o) {
+      return printDataType(prefix, o, 1);
+  }
+  public static String printDataType(String prefix, Object o, int iter) {
+      StringBuilder stringRep = new StringBuilder();
+    
+      try {
+        if (o != null) {
+          Class objectType = o.getClass();
+          if (objectType.isPrimitive() ||
+              objectType.equals(String.class) ||
+              objectType.equals(Date.class)) {
+            stringRep.append(prefix + " (" + objectType.getSimpleName() + 
+              ") = " + o.toString() + "\n");
+          } else if (objectType.isArray()) {
+            if (Array.getLength(o) == 0)  {
+              stringRep.append(prefix + " = empty array\n");
+            }
+            if (objectType.getComponentType().isPrimitive() ||
+              objectType.getComponentType().equals(String.class) ||
+                objectType.getComponentType().equals(Date.class))  {
+              for (int i = 0; i &lt; Array.getLength(o); i++) {
+                stringRep.append(prefix + "[" + i + "] = " + 
+                  Array.get(o, i).toString() + "\n");
+              }
+            } else {
+              for (int i = 0; i &lt; Array.getLength(o); i++) {
+                stringRep.append(printDataType(prefix + "[" + i + "]", 
+                  Array.get(o, i), iter + 1));
+              }
+            }
+          } else if (o instanceof Iterable) {
+            int i = 0;
+            Iterator it = ((Iterable) o).iterator();
+            if (!it.hasNext()) {
+              stringRep.append(prefix + " = empty set\n");
+            }
+            while (it.hasNext()) {
+              stringRep.append(printDataType(prefix + "[" + i++ + "]", 
+                it.next(), iter + 1));
+            }
+          } else if (o instanceof Map)  {
+            Set&lt;Object&gt; keys = ((Map) o).keySet();
+            if (keys.isEmpty()) {
+              stringRep.append(prefix + " = empty map\n");
+            }
+            for (Object key : keys)  {
+              stringRep.append(printDataType(prefix + "[" + key.toString() + "]", 
+                ((Map) o).get(key), iter + 1));
+            }
+          } else if (o instanceof Class) {
+            // Do nothing otherwise the stack blows up
+          } else {
+            Method[] methods = objectType.getMethods();
+    
+            for (Method method : methods)  {
+              if (method.getName().startsWith("get") &amp;&amp;
+                method.getParameterCount() == 0)  {
+                String propertyName = method.getName().substring(3,4).toLowerCase() + 
+                  method.getName().substring(4);
+                Object value = method.invoke(o, new Object[] {} );
+                // value.getClass().isPrimitive returns false, even if 
+                // method.getReturnType().isPrimitive returns true
+                if (method.getReturnType().isPrimitive())  {
+                  stringRep.append(prefix + "." + propertyName + " (" + 
+                    method.getReturnType().getSimpleName() + ") = " + 
+                    value.toString() + "\n");
+                } else {
+                  if (iter &lt; 10) {
+                    stringRep.append(printDataType(prefix + "." + propertyName, value, iter + 1));
+                  } else {
+                    stringRep.append("...");
+                  }
+                }
+              } else if (method.getName().startsWith("is") &amp;&amp;
+                    method.getParameterCount() == 0 &amp;&amp;
+                    method.getReturnType().equals(boolean.class))  {
+                String propertyName = method.getName().substring(2,3).toLowerCase() + 
+                  method.getName().substring(3);
+                stringRep.append(prefix + "." + propertyName + " (boolean) = " +
+                    (method.invoke(o, new Object[] {}).equals(true) ? "true" : "false") + "\n");
+              }
+            }
+          }
+        } else {
+          return prefix + " = null\n";
+        }
+      } catch (Exception e)  {
+        //e.printStackTrace();
+        //return e.toString();
+        stringRep.append("Exception("+e.getMessage()+")");
+      }
+    
+      return stringRep.toString();
+    }
+
+*/
+
+public static String getOsAppDataPath(Context context) {
+  Map&lt;String, String&gt; osAppDataPathMap = new HashMap&lt;&gt;();
+  osAppDataPathMap.put("macos", "Library/Application Support/Jalview-Desktop");
+  osAppDataPathMap.put("linux", ".local/share/jalview-desktop");
+  osAppDataPathMap.put("windows", "AppData\\Local\\Jalview-Desktop");
+  osAppDataPathMap.put("other", ".jalview-desktop");
+  String appDataPath;
+  String append;
+  if (Util.isMacOS()) {
+    appDataPath = osAppDataPathMap.get("macos");
+    append = context.getCompilerVariable("JALVIEW_APPLICATION_NAME");
+  } else if (Util.isWindows()) {
+    appDataPath = osAppDataPathMap.get("windows");
+    append = context.getCompilerVariable("APPLICATION_FOLDER");
+  } else if (Util.isLinux()) {
+    appDataPath = osAppDataPathMap.get("linux");
+    append = context.getCompilerVariable("APPLICATION_FOLDER").toLowerCase(Locale.ROOT);
+  } else {
+    appDataPath = osAppDataPathMap.get("other");
+    append = context.getCompilerVariable("APPLICATION_FOLDER").toLowerCase(Locale.ROOT);
+  }
+  return "~" + File.separator + appDataPath + File.separator + append;
+}
+
+// methods used in advanced options form validation
+public static void validateUserSpaceAdvancedOptionsForm(FormEnvironment formEnvironment) {
+    FormComponent fc_advancedOptions = formEnvironment.getFormComponentById("US_ADVANCED_OPTIONS");
+    FormComponent fc_notUsed = formEnvironment.getFormComponentById("US_NOT_USED");
+    FormComponent fc_userUpdates = formEnvironment.getFormComponentById("US_ALLOW_USER_APPDIR_UPDATES");
+    FormComponent fc_warning = formEnvironment.getFormComponentById("US_NO_UPDATES_WARNING");
+    LayoutGroup lg_advancedOptions = formEnvironment.getLayoutGroupById("US_ADVANCED_OPTIONS_GROUP");
+    
+    // get boolean status of "Enable advanced options" checkbox
+    JCheckBox jcb_advancedOptions = (JCheckBox) fc_advancedOptions.getConfigurationObject();
+    boolean advancedOptions = jcb_advancedOptions.isSelected();
+    
+    // set visibility of Advanced options layout group
+    lg_advancedOptions.setVisible(advancedOptions);
+    fc_notUsed.setVisible(!advancedOptions);
+    
+    if (!advancedOptions) {
+      return;
+    }
+    
+    JCheckBox jcb_userUpdates = (JCheckBox) fc_userUpdates.getConfigurationObject();
+    boolean userUpdates = fc_userUpdates.isEnabled() &amp;&amp; jcb_userUpdates.isSelected();
+    
+    boolean showWarning = advancedOptions &amp;&amp; (!userUpdates);
+    
+    fc_warning.setVisible(showWarning);
+}
+
+public static void validateSystemSpaceAdvancedOptionsForm(Context context, FormEnvironment formEnvironment) {
+    validateSystemSpaceAdvancedOptionsForm(context, formEnvironment, true);
+}
+
+public static boolean validateSystemSpaceAdvancedOptionsForm(Context context, FormEnvironment formEnvironment, boolean ret) {
+    FormComponent fc_advancedOptions = formEnvironment.getFormComponentById("SS_ADVANCED_OPTIONS");
+    FormComponent fc_notUsed = formEnvironment.getFormComponentById("SS_NOT_USED");
+    FormComponent fc_userUpdates = formEnvironment.getFormComponentById("SS_ALLOW_USER_APPDIR_UPDATES");
+    FormComponent fc_installerUpdates = formEnvironment.getFormComponentById("SS_ALLOW_INSTALLER_APPDIR_UPDATES");
+    FormComponent fc_allowUserAppdirPath = formEnvironment.getFormComponentById("SS_ALLOW_USER_APPDIR_PATH");
+    FormComponent fc_userAppdirPath = formEnvironment.getFormComponentById("SS_USER_APPDIR_PATH");
+    LayoutGroup lg_advancedGroup = formEnvironment.getLayoutGroupById("SS_ADVANCED_OPTIONS_GROUP");
+    LayoutGroup lg_setUserAppdirPath = formEnvironment.getLayoutGroupById("SS_SET_USER_APPDIR_PATH");
+    
+    
+    
+    // get boolean status of "Enable advanced options" checkbox
+    JCheckBox jcb_advancedOptions = (JCheckBox) fc_advancedOptions.getConfigurationObject();
+    boolean advancedOptions = jcb_advancedOptions.isSelected();
+    
+    // set visibility of Advanced options layout group
+    lg_advancedGroup.setVisible(advancedOptions);
+    fc_notUsed.setVisible(!advancedOptions);
+    
+    if (!advancedOptions) {
+      return ret;
+    }
+    
+    
+    
+    // get boolean status of "Allow user-space updates" checkbox
+    JCheckBox jcb_user = (JCheckBox) fc_userUpdates.getConfigurationObject();
+    boolean userUpdates = jcb_user.isSelected();
+    
+    // set enabled of customised user appdir path group
+    lg_setUserAppdirPath.setEnabled(advancedOptions &amp;&amp; userUpdates);
+    
+    // set enabled of allow installation updates checkbox
+    fc_installerUpdates.setEnabled(advancedOptions &amp;&amp; !userUpdates);
+    
+    
+    
+    // get boolean status of "Customise the user-space path" checkbox
+    JCheckBox jcb_allowUserAppdirPath = (JCheckBox) fc_allowUserAppdirPath.getConfigurationObject();
+    boolean allowUserAppdirPath = jcb_allowUserAppdirPath.isSelected();
+    
+    // set enabled of userAppdirPath text field
+    fc_userAppdirPath.setEnabled(advancedOptions &amp;&amp; allowUserAppdirPath &amp;&amp; fc_allowUserAppdirPath.isEnabled());
+    
+    // get String value of userAppdirPath text field
+    JTextField jtf_userAppdirPath = (JTextField) fc_userAppdirPath.getConfigurationObject();
+    String userAppdirPath = jtf_userAppdirPath.getText();
+    
+    
+    
+    // get boolean status of "Allow installation updates" checkbox
+    JCheckBox jcb_installer = (JCheckBox) fc_installerUpdates.getConfigurationObject();
+    boolean installerUpdates = jcb_installer.isSelected();
+
+
+
+    // should we show the No updates warning?
+    boolean showNoUpdatesWarning = advancedOptions &amp;&amp; !(userUpdates || installerUpdates);
+    FormComponent fc_noUpdatesWarning = formEnvironment.getFormComponentById("SS_NO_UPDATES_WARNING");
+    fc_noUpdatesWarning.setVisible(advancedOptions &amp;&amp; showNoUpdatesWarning);
+    
+    
+    
+    // should we show the invalid user-space path warning?
+    showInvalidUserAppdirPathWarning(context, formEnvironment);
+    
+    
+    
+    // set whether "Set defaults" button should be enabled
+    FormComponent fc_setDefaults = formEnvironment.getFormComponentById("SS_SET_DEFAULTS");
+    JButton jb_setDefaults = (JButton) fc_setDefaults.getConfigurationObject();
+    boolean enableSetDefaults = !( userUpdates &amp;&amp; !allowUserAppdirPath &amp;&amp; userAppdirPath.length() == 0 &amp;&amp; !installerUpdates );
+    jb_setDefaults.setEnabled(enableSetDefaults);
+    
+    
+    
+    return ret;
+}
+
+public static boolean isUserAppdirPathValid(Context context) { // this is only valid when form is updated
+    return isUserAppdirPathValid(context, (String) context.getVariable("userAppdirPath"));    
+}
+
+public static boolean isUserAppdirPathValid(Context context, FormComponent fc_userAppdirPath) {
+    // get String value of userAppdirPath text field
+    JTextField jtf_userAppdirPath = (JTextField) fc_userAppdirPath.getConfigurationObject();
+    String userAppdirPath = jtf_userAppdirPath.getText();
+    return isUserAppdirPathValid(context, userAppdirPath);
+}
+
+public static boolean isUserAppdirPathValid(Context context, String userAppdirPath) {
+    if (userAppdirPath == null || userAppdirPath.length() == 0) {
+      return true; // null will be switched to default
+    }
+    
+    boolean u = userAppdirPath.contains("%u");
+    boolean U = userAppdirPath.contains("%U");
+    boolean h = userAppdirPath.contains("%h");
+    boolean t = userAppdirPath.startsWith("~" + (String)context.getVariable("sys.fileSeparator"));
+    
+    return u || U || h || t;
+}
+
+public static void showInvalidUserAppdirPathWarning(Context context, FormEnvironment formEnvironment) {
+    FormComponent fc_advancedOptions = formEnvironment.getFormComponentById("SS_ADVANCED_OPTIONS");
+    FormComponent fc_userUpdates = formEnvironment.getFormComponentById("SS_ALLOW_USER_APPDIR_UPDATES");
+    FormComponent fc_allowUserAppdirPath = formEnvironment.getFormComponentById("SS_ALLOW_USER_APPDIR_PATH");
+    FormComponent fc_userAppdirPath = formEnvironment.getFormComponentById("SS_USER_APPDIR_PATH");
+    FormComponent fc_invalidPathWarning = formEnvironment.getFormComponentById("SS_INVALID_USER_APPDIR_PATH_WARNING");
+
+    // get boolean status of "Allow user-space updates" checkbox
+    boolean advancedOptions = ((JCheckBox) fc_advancedOptions.getConfigurationObject()).isSelected();
+
+    // get boolean status of "Allow user-space updates" checkbox
+    boolean userUpdates = ((JCheckBox) fc_userUpdates.getConfigurationObject()).isSelected();
+    
+    // get boolean status of "Customise the user-space path" checkbox
+    boolean allowUserAppdirPath = ((JCheckBox) fc_allowUserAppdirPath.getConfigurationObject()).isSelected();
+
+    // show/hide warning
+    boolean showInvalidPathWarning = advancedOptions &amp;&amp; userUpdates &amp;&amp; allowUserAppdirPath &amp;&amp;  !isUserAppdirPathValid(context, fc_userAppdirPath);
+    fc_invalidPathWarning.setVisible(showInvalidPathWarning);
+}
+
+// methods to get installer.appdir hash
+protected static final String XLATE = "0123456789abcdef";
+
+public static String hexlate (byte[] bytes, int count)
+{
+    if (bytes == null) {
+        return "";
+    }
+
+    count = Math.min(count, bytes.length);
+    char[] chars = new char[count*2];
+
+    for (int i = 0; i &lt; count; i++) {
+        int val = bytes[i];
+        if (val &lt; 0) {
+            val += 256;
+        }
+        chars[2*i] = XLATE.charAt(val/16);
+        chars[2*i+1] = XLATE.charAt(val%16);
+    }
+
+    return new String(chars);
+}
+
+public static String hexlate (byte[] bytes)
+{
+    return (bytes == null) ? "" : hexlate(bytes, bytes.length);
+}
+
+public static final String getFullPathToDirectoryHash(String install_app_dir)
+{
+  java.security.MessageDigest md;
+  try {
+    md = java.security.MessageDigest.getInstance("SHA-256");
+  } catch (java.security.NoSuchAlgorithmException nsae) {
+    throw new RuntimeException("JVM does not support SHA-256. Gurp!");
+  }
+  byte[] contents = install_app_dir.getBytes(java.nio.charset.StandardCharsets.UTF_8);
+  String hash = hexlate(md.digest(contents));
+  return hash.substring(0,8);
+}
+
+public static final String getCanonicalFullPathToDirectoryHash(String installerAppdir) {
+    try {
+        return getFullPathToDirectoryHash(new File(installerAppdir).getCanonicalPath());
+    }catch (IOException ioex) {
+        System.err.println("Unable to resolve '"+installerAppdir+"' as a proper path on this system.\nNot generating an installer appdir hash");
+        return "";
+    }
+}
+</staticMembers>
+    <applications>
+      <application id="installer" beanClass="com.install4j.runtime.beans.applications.InstallerApplication" actionElevationType="elevated" styleId="35" customIcnsFile="${compiler:JALVIEW_DIR}/${compiler:ICONS_DIR}/${compiler:MAC_ICONS_FILE}" customIcoFile="${compiler:JALVIEW_DIR}/${compiler:ICONS_DIR}/${compiler:WINDOWS_ICONS_FILE}">
+        <serializedBean>
+          <property name="frameHeight" type="int" value="720" />
+          <property name="frameWidth" type="int" value="960" />
+          <void id="Boolean0" method="isAllowConsole" />
+          <property name="useCustomIcon">
+            <object idref="Boolean0" />
+          </property>
+        </serializedBean>
+        <styleOverrides>
+          <styleOverride name="Customize banner image" enabled="true">
+            <group id="146" 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="java.awt.Color">
+                    <int>255</int>
+                    <int>255</int>
+                    <int>255</int>
+                    <int>255</int>
+                  </object>
+                </property>
+                <property name="imageEdgeBorder" type="boolean" value="true" />
+                <property name="imageFile">
+                  <object class="com.install4j.api.beans.ExternalFile">
+                    <string>${compiler:JALVIEW_DIR}/${compiler:BACKGROUND}</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>
+              <externalParametrizationPropertyNames>
+                <propertyName>imageAnchor</propertyName>
+                <propertyName>imageEdgeBackgroundColor</propertyName>
+                <propertyName>imageFile</propertyName>
+              </externalParametrizationPropertyNames>
+            </group>
+          </styleOverride>
+          <styleOverride name="Jalview" enabled="true">
+            <formComponent name="Watermark" id="352" beanClass="com.install4j.runtime.beans.formcomponents.SeparatorComponent" insetTop="0" insetLeft="5" insetBottom="0" useExternalParametrization="true" externalParametrizationName="Custom watermark" externalParametrizationMode="include">
+              <serializedBean>
+                <property name="enabledTitleText" type="boolean" value="false" />
+              </serializedBean>
+              <externalParametrizationPropertyNames>
+                <propertyName>labelText</propertyName>
+              </externalParametrizationPropertyNames>
+            </formComponent>
+          </styleOverride>
+          <styleOverride name="Customize title bar" enabled="true">
+            <group id="2831" 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>${compiler:JALVIEW_DIR}/${compiler:TITLE_ICON}</string>
+                  </object>
+                </property>
+                <void id="Integer0" property="cellSpacing" />
+                <void id="Integer1" property="borderWidth" />
+                <property name="imageInsets">
+                  <object class="java.awt.Insets">
+                    <object idref="Integer0" />
+                    <int>5</int>
+                    <object idref="Integer1" />
+                    <object idref="Integer1" />
+                  </object>
+                </property>
+                <property name="insets">
+                  <object class="java.awt.Insets">
+                    <object idref="Integer0" />
+                    <int>20</int>
+                    <object idref="Integer0" />
+                    <int>10</int>
+                  </object>
+                </property>
+              </serializedBean>
+              <externalParametrizationPropertyNames>
+                <propertyName>backgroundColor</propertyName>
+                <propertyName>foregroundColor</propertyName>
+                <propertyName>imageAnchor</propertyName>
+                <propertyName>imageFile</propertyName>
+                <propertyName>imageOverlap</propertyName>
+              </externalParametrizationPropertyNames>
+            </group>
+          </styleOverride>
+        </styleOverrides>
+        <infoPlist>${compiler:file("${compiler:INFO_PLIST_FILE_ASSOCIATIONS_FILE}")}</infoPlist>
+        <startup>
+          <screen id="1" beanClass="com.install4j.runtime.beans.screens.StartupScreen" rollbackBarrierExitCode="0">
+            <actions>
+              <action id="22" beanClass="com.install4j.runtime.beans.actions.misc.RequestPrivilegesAction" actionElevationType="none" rollbackBarrierExitCode="0">
+                <serializedBean>
+                  <void id="Boolean0" method="isFailIfNotObtainedLinux" />
+                  <property name="failIfNotObtainedMac">
+                    <object idref="Boolean0" />
+                  </property>
+                  <property name="failIfNotObtainedWin">
+                    <object idref="Boolean0" />
+                  </property>
+                </serializedBean>
+              </action>
+              <action name="BOTHSPACE: Set isAdmin flag" id="2970" beanClass="com.install4j.runtime.beans.actions.control.SetVariableAction" actionElevationType="elevated" rollbackBarrierExitCode="0">
+                <serializedBean>
+                  <property name="script">
+                    <object class="com.install4j.api.beans.ScriptProperty">
+                      <property name="value" type="string">Util.hasFullAdminRights() // this doesn't seem to work in some conditionals so creating our own boolean</property>
+                    </object>
+                  </property>
+                  <property name="variableName" type="string">isAdmin</property>
+                </serializedBean>
+              </action>
+              <action name="BOTHSPACE: Set makeSymbolicLink boolean variable?" id="2853" beanClass="com.install4j.runtime.beans.actions.control.SetVariableAction" rollbackBarrierExitCode="0">
+                <serializedBean>
+                  <property name="script">
+                    <object class="com.install4j.api.beans.ScriptProperty">
+                      <property name="value" type="string">Util.isLinux() || Util.isUnixInstaller() || ( Util.isMacosInstaller() &amp;&amp; context.getBooleanVariable("isAdmin") )</property>
+                    </object>
+                  </property>
+                  <property name="variableName" type="string">makeSymbolicLink</property>
+                </serializedBean>
+              </action>
+              <action name="BOTHSPACE: Set unixBinDir (Linux or Unix)" id="2845" beanClass="com.install4j.runtime.beans.actions.control.SetVariableAction" rollbackBarrierExitCode="0">
+                <serializedBean>
+                  <property name="responseFileVariable" type="boolean" value="true" />
+                  <property name="script">
+                    <object class="com.install4j.api.beans.ScriptProperty">
+                      <property name="value" type="string">ArrayList&lt;String&gt; tryPaths = new ArrayList&lt;&gt; ();
+
+if (Util.hasFullAdminRights()) {
+    tryPaths.add(File.separator + "opt" + File.separator + "bin");
+    tryPaths.add(File.separator + "usr" + File.separator + "local" + File.separator + "bin");
+} else {
+    String userHome = (String)context.getVariable("sys.userHome");
+    tryPaths.add(userHome + File.separator + "bin");
+    tryPaths.add(userHome + File.separator + "local" + File.separator + "bin");
+    tryPaths.add(userHome + File.separator + ".local" + File.separator + "bin");
+    tryPaths.add(userHome + File.separator + "opt" + File.separator + "bin");
+}
+
+for (int i = 0; i &lt; tryPaths.size(); i++) {
+    String tryPath = tryPaths.get(i);
+    File unixBinDir = new File(tryPath);
+    if (unixBinDir.exists()) {
+        return tryPath;
+    }
+}
+
+return null;
+</property>
+                    </object>
+                  </property>
+                  <property name="variableName" type="string">unixBinDir</property>
+                </serializedBean>
+                <condition>if (!context.getBooleanVariable("makeSymbolicLink")) {
+    return false;
+}
+String unixBinDir = (String) context.getVariable("unixBinDir");
+if (unixBinDir != null &amp;&amp; unixBinDir.length() &gt; 0) {
+    if (unixBinDir.startsWith("~/")) {
+        unixBinDir = (String)context.getVariable("sys.userHome") + unixBinDir.substring(1);
+        context.setVariable("unixBinDir", unixBinDir);
+    }
+    return false;
+}
+return true;</condition>
+              </action>
+              <action name="USERSPACE: Set MacOSDir (macOS)" id="2745" beanClass="com.install4j.runtime.beans.actions.control.SetVariableAction" rollbackBarrierExitCode="0">
+                <serializedBean>
+                  <property name="script">
+                    <object class="com.install4j.api.beans.ScriptProperty">
+                      <property name="value" type="string">String javaHome = System.getProperty("java.home");
+String appName = ((String)context.getCompilerVariable("JALVIEW_APPLICATION_NAME")) + ".app";
+int i = javaHome.indexOf(appName);
+String MacOSDir = null;
+if (i &gt; -1) {
+    MacOSDir = javaHome.substring(0, i) + appName + File.separator + "Contents" + File.separator + "MacOS";
+}
+return MacOSDir;
+</property>
+                    </object>
+                  </property>
+                  <property name="variableName" type="string">MacOSDir</property>
+                </serializedBean>
+                <condition>Util.isMacOS() &amp;&amp; !context.getBooleanVariable("isAdmin") // Admin on macOS will add path to /etc/paths.d in Create File action</condition>
+              </action>
+              <action name="BOTHSPACE: Set advancedOptions" id="3040" beanClass="com.install4j.runtime.beans.actions.control.SetVariableAction" rollbackBarrierExitCode="0">
+                <serializedBean>
+                  <property name="onlyIfUndefined" type="boolean" value="true" />
+                  <property name="responseFileVariable" type="boolean" value="true" />
+                  <property name="script">
+                    <object class="com.install4j.api.beans.ScriptProperty">
+                      <property name="value" type="string">Boolean.FALSE</property>
+                    </object>
+                  </property>
+                  <property name="variableName" type="string">advancedOptions</property>
+                </serializedBean>
+              </action>
+              <action name="BOTHSPACE: Set allowUserDefaultAppdirUpdates" id="2976" beanClass="com.install4j.runtime.beans.actions.control.SetVariableAction" rollbackBarrierExitCode="0">
+                <serializedBean>
+                  <property name="onlyIfUndefined" type="boolean" value="true" />
+                  <property name="responseFileVariable" type="boolean" value="true" />
+                  <property name="script">
+                    <object class="com.install4j.api.beans.ScriptProperty">
+                      <property name="value" type="string">Boolean.TRUE</property>
+                    </object>
+                  </property>
+                  <property name="variableName" type="string">allowUserDefaultAppdirUpdates</property>
+                </serializedBean>
+              </action>
+              <action name="BOTHSPACE: Set allowSetUserAppdirPath" id="3039" beanClass="com.install4j.runtime.beans.actions.control.SetVariableAction" rollbackBarrierExitCode="0">
+                <serializedBean>
+                  <property name="onlyIfUndefined" type="boolean" value="true" />
+                  <property name="responseFileVariable" type="boolean" value="true" />
+                  <property name="script">
+                    <object class="com.install4j.api.beans.ScriptProperty">
+                      <property name="value" type="string">Boolean.FALSE</property>
+                    </object>
+                  </property>
+                  <property name="variableName" type="string">allowSetUserAppdirPath</property>
+                </serializedBean>
+              </action>
+              <action name="BOTHSPACE: Set userAppdirPath" id="3038" beanClass="com.install4j.runtime.beans.actions.control.SetVariableAction" rollbackBarrierExitCode="0">
+                <serializedBean>
+                  <property name="onlyIfUndefined" type="boolean" value="true" />
+                  <property name="responseFileVariable" type="boolean" value="true" />
+                  <property name="script">
+                    <object class="com.install4j.api.beans.ScriptProperty">
+                      <property name="value" type="string">""</property>
+                    </object>
+                  </property>
+                  <property name="variableName" type="string">userAppdirPath</property>
+                </serializedBean>
+              </action>
+              <action name="BOTHSPACE: Set allowInstallerAppdirUpdates" id="2977" beanClass="com.install4j.runtime.beans.actions.control.SetVariableAction" rollbackBarrierExitCode="0">
+                <serializedBean>
+                  <property name="onlyIfUndefined" type="boolean" value="true" />
+                  <property name="responseFileVariable" type="boolean" value="true" />
+                  <property name="script">
+                    <object class="com.install4j.api.beans.ScriptProperty">
+                      <property name="value" type="string">Boolean.FALSE</property>
+                    </object>
+                  </property>
+                  <property name="variableName" type="string">allowInstallerAppdirUpdates</property>
+                </serializedBean>
+              </action>
+              <action name="BOTHSPACE: Set userDefaultAppdirBase for tooltip explanation" id="2981" beanClass="com.install4j.runtime.beans.actions.control.SetVariableAction" rollbackBarrierExitCode="0">
+                <serializedBean>
+                  <property name="script">
+                    <object class="com.install4j.api.beans.ScriptProperty">
+                      <property name="value" type="string">getOsAppDataPath(context)</property>
+                    </object>
+                  </property>
+                  <property name="variableName" type="string">userDefaultAppdirBase</property>
+                </serializedBean>
+              </action>
+              <action name="BOTHSPACE: Set osName variable for tooltip explanation" id="2982" beanClass="com.install4j.runtime.beans.actions.control.SetVariableAction" rollbackBarrierExitCode="0">
+                <serializedBean>
+                  <property name="script">
+                    <object class="com.install4j.api.beans.ScriptProperty">
+                      <property name="value" type="string">if (Util.isWindows()) {
+    return "Windows";
+} else if (Util.isMacOS()) {
+    return "macOS";
+} else if (Util.isLinux()) {
+    return "Linux";
+}
+return context.getCompilerVariable("sys.platform");</property>
+                    </object>
+                  </property>
+                  <property name="variableName" type="string">osName</property>
+                </serializedBean>
+              </action>
+              <action name="CONSOLE: Set consoleDisableUserAppdir" id="3075" beanClass="com.install4j.runtime.beans.actions.control.SetVariableAction" rollbackBarrierExitCode="0">
+                <serializedBean>
+                  <property name="script">
+                    <object class="com.install4j.api.beans.ScriptProperty">
+                      <property name="value" type="string">Boolean.FALSE</property>
+                    </object>
+                  </property>
+                  <property name="variableName" type="string">consoleDisableUserAppdir</property>
+                </serializedBean>
+              </action>
+              <action name="CONSOLE: Set consoleDisableAllUpdates" id="3076" beanClass="com.install4j.runtime.beans.actions.control.SetVariableAction" rollbackBarrierExitCode="0">
+                <serializedBean>
+                  <property name="script">
+                    <object class="com.install4j.api.beans.ScriptProperty">
+                      <property name="value" type="string">Boolean.FALSE</property>
+                    </object>
+                  </property>
+                  <property name="variableName" type="string">consoleDisableAllUpdates</property>
+                </serializedBean>
+              </action>
+              <action name="CONSOLE: Set consoleAllowUserAppdirPath" id="3077" beanClass="com.install4j.runtime.beans.actions.control.SetVariableAction" rollbackBarrierExitCode="0">
+                <serializedBean>
+                  <property name="script">
+                    <object class="com.install4j.api.beans.ScriptProperty">
+                      <property name="value" type="string">Boolean.FALSE</property>
+                    </object>
+                  </property>
+                  <property name="variableName" type="string">consoleAllowUserAppdirPath</property>
+                </serializedBean>
+              </action>
+              <action name="Extra Command Line Options" id="3074" beanClass="com.install4j.runtime.beans.actions.control.RunScriptAction" rollbackBarrierExitCode="0">
+                <serializedBean>
+                  <property name="script">
+                    <object class="com.install4j.api.beans.ScriptProperty">
+                      <property name="value" type="string">String[] args = context.getExtraCommandLineArguments();
+
+for (int i = 0; i &lt; args.length; i++) {
+    String arg = args[i];
+    switch(arg) {
+        case "-a":
+            if (args.length - 1 &lt; i + 1) {
+                System.out.println("Option " + arg + " requires a value.  Ignoring.");
+            }
+            context.setInstallationDirectory(new File(args[i + 1]));
+            i++;
+            break;
+        case "-u":
+            if (args.length - 1 &lt; i + 1) {
+                System.out.println("Option " + arg + " requires a value.  Ignoring.");
+            }
+            context.setVariable("userAppdirPath", args[i + 1]);
+            context.setVariable("consoleAllowUserAppdirPath", true);
+            i++;        
+            break;
+        case "-U":
+            context.setVariable("consoleDisableUserAppdir", true);
+            break;
+        case "-S":
+            context.setVariable("consoleDisableAllUpdates", true);
+            break;
+        default:
+            System.out.println("Option " + arg + " not recognised.  Ignoring.");
+            break;
+    }
+}
+
+return true;</property>
+                    </object>
+                  </property>
+                </serializedBean>
+                <condition>context.isConsole() || context.isUnattended()</condition>
+              </action>
+              <action name="Set sys.fileAssociation.launchers correctly" id="3080" beanClass="com.install4j.runtime.beans.actions.control.RunScriptAction" rollbackBarrierExitCode="0">
+                <serializedBean>
+                  <property name="script">
+                    <object class="com.install4j.api.beans.ScriptProperty">
+                      <property name="value" type="string">String[] extensions = (String[]) context.getVariable("sys.fileAssociation.extensions");
+if (extensions == null) {
+    return false;
+}
+int num = extensions.length;
+String[] launchers = new String[num];
+for (int i = 0; i &lt; num; i++) {
+    launchers[i] = "JALVIEW";
+}
+context.setVariable("sys.fileAssociation.launchers", launchers);
+return true;</property>
+                    </object>
+                  </property>
+                </serializedBean>
+              </action>
+            </actions>
+          </screen>
+        </startup>
+        <screens>
+          <screen id="2" beanClass="com.install4j.runtime.beans.screens.WelcomeScreen" rollbackBarrierExitCode="0">
+            <styleOverrides>
+              <styleOverride name="Customize banner image" enabled="true">
+                <group id="145" 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>
+                    <void id="Integer0" property="cellSpacing" />
+                    <property name="imageEdgeBackgroundColor">
+                      <object class="com.install4j.runtime.beans.LightOrDarkColor">
+                        <object class="java.awt.Color">
+                          <int>25</int>
+                          <int>143</int>
+                          <int>220</int>
+                          <int>255</int>
+                        </object>
+                        <object class="java.awt.Color">
+                          <object idref="Integer0" />
+                          <int>74</int>
+                          <int>151</int>
+                          <int>255</int>
+                        </object>
+                      </object>
+                    </property>
+                    <property name="imageEdgeBorder" type="boolean" value="true" />
+                    <property name="imageFile">
+                      <object class="com.install4j.api.beans.ExternalFile">
+                        <string>${compiler:JALVIEW_DIR}/${compiler:BACKGROUND}</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>
+                  <externalParametrizationPropertyNames>
+                    <propertyName>imageAnchor</propertyName>
+                    <propertyName>imageEdgeBackgroundColor</propertyName>
+                    <propertyName>imageFile</propertyName>
+                  </externalParametrizationPropertyNames>
+                </group>
+              </styleOverride>
+            </styleOverrides>
+            <actions>
+              <action id="7" beanClass="com.install4j.runtime.beans.actions.misc.LoadResponseFileAction" rollbackBarrierExitCode="0" multiExec="true">
+                <serializedBean>
+                  <property name="excludedVariables" type="array" elementType="string" length="5">
+                    <element index="0">sys.installationDir</element>
+                    <element index="1">sys.adminRights$Boolean</element>
+                    <element index="2">sys.adminRightsUiRootUnix$Boolean</element>
+                    <element index="3">sys.component.1031$Boolean</element>
+                    <element index="4">sys.fileAssociation.launchers$StringArray</element>
+                  </property>
+                </serializedBean>
+                <condition>context.getBooleanVariable("sys.confirmedUpdateInstallation")</condition>
+              </action>
+            </actions>
+            <formComponents>
+              <formComponent name="Administrator mode label" id="3028" beanClass="com.install4j.runtime.beans.formcomponents.MultilineHtmlLabelComponent" insetBottom="16">
+                <serializedBean>
+                  <property name="labelHtml" type="string">&lt;strong&gt;Administrator mode&lt;/strong&gt;</property>
+                </serializedBean>
+                <visibilityScript>context.getBooleanVariable("isAdmin")</visibilityScript>
+              </formComponent>
+              <formComponent id="3" beanClass="com.install4j.runtime.beans.formcomponents.MultilineLabelComponent">
+                <serializedBean>
+                  <property name="labelText" type="string">${form:welcomeMessage}</property>
+                </serializedBean>
+                <visibilityScript>!context.isConsole()</visibilityScript>
+              </formComponent>
+              <formComponent id="4" 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="5" beanClass="com.install4j.runtime.beans.formcomponents.UpdateAlertComponent" useExternalParametrization="true" externalParametrizationName="Update Alert" externalParametrizationMode="include">
+                <externalParametrizationPropertyNames>
+                  <propertyName>updateCheck</propertyName>
+                </externalParametrizationPropertyNames>
+              </formComponent>
+              <formComponent id="6" beanClass="com.install4j.runtime.beans.formcomponents.MultilineLabelComponent" insetTop="20">
+                <serializedBean>
+                  <property name="labelText" type="string">${i18n:ClickNext}</property>
+                </serializedBean>
+              </formComponent>
+            </formComponents>
+          </screen>
+          <screen id="8" customizedId="LOCATION_SCREEN" beanClass="com.install4j.runtime.beans.screens.InstallationDirectoryScreen" rollbackBarrierExitCode="0">
+            <condition>!context.getBooleanVariable("sys.confirmedUpdateInstallation")</condition>
+            <actions>
+              <action id="11" beanClass="com.install4j.runtime.beans.actions.misc.LoadResponseFileAction" rollbackBarrierExitCode="0" multiExec="true">
+                <serializedBean>
+                  <property name="excludedVariables" type="array" elementType="string" length="5">
+                    <element index="0">sys.installationDir</element>
+                    <element index="1">sys.adminRights$Boolean</element>
+                    <element index="2">sys.adminRightsUiRootUnix$Boolean</element>
+                    <element index="3">sys.component.1031$Boolean</element>
+                    <element index="4">sys.fileAssociation.launchers$StringArray</element>
+                  </property>
+                </serializedBean>
+                <condition>context.getVariable("sys.responseFile") == null</condition>
+              </action>
+            </actions>
+            <formComponents>
+              <formComponent name="Administrator mode label" id="3057" beanClass="com.install4j.runtime.beans.formcomponents.MultilineHtmlLabelComponent" insetBottom="16">
+                <serializedBean>
+                  <property name="labelHtml" type="string">&lt;strong&gt;Administrator mode&lt;/strong&gt;</property>
+                </serializedBean>
+                <visibilityScript>context.getBooleanVariable("isAdmin")</visibilityScript>
+              </formComponent>
+              <formComponent id="9" 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="10" beanClass="com.install4j.runtime.beans.formcomponents.InstallationDirectoryChooserComponent" useExternalParametrization="true" externalParametrizationName="Installation Directory Chooser" externalParametrizationMode="include">
+                <serializedBean>
+                  <void id="Boolean0" method="isCheckFreeSpace" />
+                  <property name="requestFocus">
+                    <object idref="Boolean0" />
+                  </property>
+                </serializedBean>
+                <externalParametrizationPropertyNames>
+                  <propertyName>allowSpacesOnUnix</propertyName>
+                  <propertyName>checkFreeSpace</propertyName>
+                  <propertyName>checkWritable</propertyName>
+                  <propertyName>existingDirWarning</propertyName>
+                  <propertyName>manualEntryAllowed</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="1692" beanClass="com.install4j.runtime.beans.screens.FileAssociationsScreen" rollbackBarrierExitCode="0">
+            <formComponents>
+              <formComponent name="Administrator mode label" id="3058" beanClass="com.install4j.runtime.beans.formcomponents.MultilineHtmlLabelComponent" insetBottom="16">
+                <serializedBean>
+                  <property name="labelHtml" type="string">&lt;strong&gt;Administrator mode&lt;/strong&gt;</property>
+                </serializedBean>
+                <visibilityScript>context.getBooleanVariable("isAdmin")</visibilityScript>
+              </formComponent>
+              <formComponent id="1693" beanClass="com.install4j.runtime.beans.formcomponents.MultilineLabelComponent">
+                <serializedBean>
+                  <property name="labelText" type="string">${i18n:SelectAssociationsLabel}</property>
+                </serializedBean>
+              </formComponent>
+              <formComponent id="3069" beanClass="com.install4j.runtime.beans.formcomponents.ButtonComponent" enabled="false" commentSet="true" comment="This button is desirable but not working.&#xA;The best that can be done is&#xA;&#xA;Screen s = formEnvironment.getScreen();&#xA;context.gotoScreen(s);&#xA;&#xA;but this adds extra &quot;File Association&quot; screens into the &quot;Back&quot; history (but not the &quot;Next&quot; stack).">
+                <serializedBean>
+                  <property name="actionScript">
+                    <object class="com.install4j.api.beans.ScriptProperty">
+                      <property name="value" type="string">Screen s = formEnvironment.getScreen();
+
+FormComponent fc = formEnvironment.getFormComponentById("FILE_ASSOCIATIONS_SELECTOR");
+com.install4j.api.actions.Action a0 = context.getActionById("FA_FILEASSOCIATION-CIF-false");
+Screen s2 = context.getScreenById("EXTENSIONS_REPLACED_BY_GRADLE_PARENT_GROUP");
+
+for (com.install4j.api.actions.Action a : context.getActions(s2)) {
+    String aid = context.getId(a);
+    if (aid.startsWith("FA_FILEASSOCIATION-")) {
+        com.install4j.runtime.beans.actions.desktop.CreateFileAssociationAction aa = (com.install4j.runtime.beans.actions.desktop.CreateFileAssociationAction) a;
+        boolean set = aid.endsWith("-true");
+        boolean got = aa.isSelected();
+        aa.setSelected(set);
+        System.err.println("Setting '"+aid+"' from "+got+" to "+set);
+    }
+}
+
+context.gotoScreen(s);
+//formEnvironment.reinitializeFormComponents();</property>
+                    </object>
+                  </property>
+                  <property name="buttonText" type="string">Reset</property>
+                </serializedBean>
+              </formComponent>
+              <formComponent id="1694" customizedId="FILE_ASSOCIATIONS_SELECTOR" beanClass="com.install4j.runtime.beans.formcomponents.FileAssociationsComponent" useExternalParametrization="true" externalParametrizationName="File Associations" externalParametrizationMode="include">
+                <serializedBean>
+                  <property name="fillVertical" type="boolean" value="true" />
+                  <property name="selectionButtonPosition" type="enum" class="com.install4j.runtime.beans.formcomponents.VerticalDockingPosition" value="TOP" />
+                  <property name="showSelectionButtons" type="boolean" value="true" />
+                </serializedBean>
+                <externalParametrizationPropertyNames>
+                  <propertyName>selectionButtonPosition</propertyName>
+                  <propertyName>showSelectionButtons</propertyName>
+                </externalParametrizationPropertyNames>
+              </formComponent>
+            </formComponents>
+          </screen>
+          <screen name="USERSPACE: Additional checkboxes" id="2893" beanClass="com.install4j.runtime.beans.screens.FormScreen" rollbackBarrierExitCode="0">
+            <serializedBean>
+              <property name="subTitle" type="string">Additional tasks for user installation (${installer:sys.userName})</property>
+              <property name="title" type="string">${i18n:WizardSelectTasks}</property>
+            </serializedBean>
+            <condition>!context.getBooleanVariable("isAdmin")</condition>
+            <formComponents>
+              <formComponent id="2894" beanClass="com.install4j.runtime.beans.formcomponents.MultilineLabelComponent" insetBottom="10">
+                <serializedBean>
+                  <property name="labelText" type="string">${i18n:SelectTasksLabel2(${compiler:JALVIEW_APPLICATION_NAME})}</property>
+                </serializedBean>
+              </formComponent>
+              <formComponent name="USERSPACE: Add a desktop link (not macOS)" id="2895" beanClass="com.install4j.runtime.beans.formcomponents.CheckboxComponent" resetInitOnPrevious="true">
+                <serializedBean>
+                  <property name="checkboxText" type="string">${i18n:CreateDesktopIcon}</property>
+                  <property name="variableName" type="string">createDesktopLinkAction</property>
+                </serializedBean>
+                <visibilityScript>!Util.isMacOS()</visibilityScript>
+              </formComponent>
+              <formComponent name="USERSPACE: Add an executable to the dock (macOS)" id="2896" beanClass="com.install4j.runtime.beans.formcomponents.CheckboxComponent">
+                <serializedBean>
+                  <property name="checkboxText" type="string">${i18n:AddToDock}</property>
+                  <property name="variableName" type="string">addToDockAction</property>
+                </serializedBean>
+                <visibilityScript>Util.isMacOS()</visibilityScript>
+              </formComponent>
+              <formComponent name="USERSPACE: Add jalview bin to the user's Path environment variable (Windows)" id="2897" beanClass="com.install4j.runtime.beans.formcomponents.CheckboxComponent">
+                <serializedBean>
+                  <property name="checkboxText" type="string">Add ${compiler:JALVIEW_APPLICATION_NAME}'s bin folder to your Path environment variable</property>
+                  <property name="initiallySelected" type="boolean" value="true" />
+                  <property name="variableName" type="string">appendToPathAction</property>
+                </serializedBean>
+                <visibilityScript>Util.isWindows()</visibilityScript>
+              </formComponent>
+              <formComponent name="BOTHSPACE: Make a symbolic link to jalview.sh bash script in the user's/system local bin (Linux or Unix)" id="2898" beanClass="com.install4j.runtime.beans.formcomponents.CheckboxComponent">
+                <serializedBean>
+                  <property name="checkboxText" type="string">Make a ${compiler:WRAPPER_LINK} symbolic link in ${installer:unixBinDir}</property>
+                  <property name="initiallySelected" type="boolean" value="true" />
+                  <property name="variableName" type="string">makeSymbolicLinkAction</property>
+                </serializedBean>
+                <visibilityScript>context.getBooleanVariable("makeSymbolicLink")
+&amp;&amp; context.getVariable("unixBinDir") != null
+&amp;&amp; (
+     Util.isLinux()
+     || Util.isUnixInstaller()
+     || (
+          ( Util.isMacOS() &amp;&amp; !Util.hasFullAdminRights() ) // Admin on macOS will add path to /etc/paths.d
+          &amp;&amp; context.getVariable("MacOSDir") != null
+        )
+    )</visibilityScript>
+              </formComponent>
+              <formComponent id="2983" beanClass="com.install4j.runtime.beans.formcomponents.SpacerComponent" />
+              <formComponent name="Enable ADVANCED OPTIONS" id="3006" customizedId="US_ADVANCED_OPTIONS" beanClass="com.install4j.runtime.beans.formcomponents.CheckboxComponent">
+                <serializedBean>
+                  <property name="checkboxText" type="string">Enable advanced options for user installation</property>
+                  <property name="coupledComponentIds">
+                    <add type="string">2980</add>
+                    <add type="string">3014</add>
+                    <add type="string">2975</add>
+                    <add type="string">2989</add>
+                  </property>
+                  <property name="selectionScript">
+                    <object class="com.install4j.api.beans.ScriptProperty">
+                      <property name="value" type="string">validateUserSpaceAdvancedOptionsForm(formEnvironment)</property>
+                    </object>
+                  </property>
+                  <property name="variableName" type="string">advancedOptions</property>
+                </serializedBean>
+              </formComponent>
+              <formComponent name="Advanced options not used label" id="3036" customizedId="US_NOT_USED" beanClass="com.install4j.runtime.beans.formcomponents.LabelComponent" insetLeft="20">
+                <serializedBean>
+                  <property name="labelColor">
+                    <object class="java.awt.Color">
+                      <int>128</int>
+                      <int>128</int>
+                      <int>128</int>
+                      <int>255</int>
+                    </object>
+                  </property>
+                  <property name="labelFontSizePercent" type="int" value="80" />
+                  <property name="labelFontType" type="enum" class="com.install4j.runtime.beans.formcomponents.FontType" value="DERIVED" />
+                  <property name="labelText" type="string">Advanced options will not be used</property>
+                </serializedBean>
+                <visibilityScript>!context.getBooleanVariable("advancedOptions")
+</visibilityScript>
+              </formComponent>
+              <group name="Advanced options (outer) group" id="3035" customizedId="US_ADVANCED_OPTIONS_GROUP" beanClass="com.install4j.runtime.beans.groups.VerticalFormComponentGroup">
+                <serializedBean>
+                  <property name="visibilityScript">
+                    <object class="com.install4j.api.beans.ScriptProperty">
+                      <property name="value" type="string">FormComponent fc_advancedOptions = formEnvironment.getFormComponentById("US_ADVANCED_OPTIONS");
+
+JCheckBox jcb_advancedOptions = (JCheckBox) fc_advancedOptions.getConfigurationObject();
+boolean advancedOptions = jcb_advancedOptions.isSelected();
+
+return advancedOptions;</property>
+                    </object>
+                  </property>
+                </serializedBean>
+                <beans>
+                  <group name="Advanced options (boxed) group" id="3034" beanClass="com.install4j.runtime.beans.groups.VerticalFormComponentGroup">
+                    <serializedBean>
+                      <property name="borderSides">
+                        <object class="com.install4j.runtime.beans.formcomponents.BorderSides">
+                          <property name="bottom" type="boolean" value="true" />
+                          <property name="left" type="boolean" value="true" />
+                          <property name="right" type="boolean" value="true" />
+                          <property name="top" type="boolean" value="true" />
+                        </object>
+                      </property>
+                      <property name="insets">
+                        <object class="java.awt.Insets">
+                          <int>4</int>
+                          <int>4</int>
+                          <int>4</int>
+                          <int>4</int>
+                        </object>
+                      </property>
+                    </serializedBean>
+                    <beans>
+                      <formComponent name="Strongly recommended text" id="2980" customizedId="US_LABEL" beanClass="com.install4j.runtime.beans.formcomponents.MultilineHtmlLabelComponent" insetLeft="16">
+                        <serializedBean>
+                          <property name="labelHtml" type="string">&lt;html&gt;The following option is &lt;strong&gt;strongly recommended&lt;/strong&gt;
+to be left as default unless there is a particular
+reason to change it.&lt;/html&gt;</property>
+                        </serializedBean>
+                      </formComponent>
+                      <formComponent id="3014" customizedId="US_VSPACE" beanClass="com.install4j.runtime.beans.formcomponents.SpacerComponent" insetLeft="16" />
+                      <formComponent name="BOTHSPACE: Allow automatic updates in user's home directory" id="2975" customizedId="US_ALLOW_USER_APPDIR_UPDATES" beanClass="com.install4j.runtime.beans.formcomponents.CheckboxComponent" insetLeft="16">
+                        <serializedBean>
+                          <property name="checkboxText" type="string">Allow user-space updates for ${compiler:JALVIEW_APPLICATION_NAME} components</property>
+                          <property name="helpText" type="string">&lt;html&gt;This option allows updates to ${compiler:JALVIEW_APPLICATION_NAME}
+&lt;br&gt;
+components to be automatically downloaded
+&lt;br&gt;
+under the user's home space, separately from
+&lt;br&gt;
+the installation location.
+&lt;br&gt;
+&lt;strong&gt;This option is strongly recommended.&lt;/strong&gt;
+&lt;br&gt;
+&lt;br&gt;
+On ${installer:osName}, user updates will be installed under
+&lt;br&gt;
+&lt;pre&gt;${installer:userDefaultAppdirBase}&lt;/pre&gt;
+&lt;/html&gt;</property>
+                          <property name="initiallySelected" type="boolean" value="true" />
+                          <property name="selectionScript">
+                            <object class="com.install4j.api.beans.ScriptProperty">
+                              <property name="value" type="string">validateUserSpaceAdvancedOptionsForm(formEnvironment)</property>
+                            </object>
+                          </property>
+                          <property name="variableName" type="string">allowUserDefaultAppdirUpdates</property>
+                        </serializedBean>
+                      </formComponent>
+                      <formComponent name="BOTHSPACE: No updates warning" id="2989" customizedId="US_NO_UPDATES_WARNING" beanClass="com.install4j.runtime.beans.formcomponents.LabelComponent" insetLeft="16">
+                        <serializedBean>
+                          <property name="labelIconFile">
+                            <object class="com.install4j.api.beans.ExternalFile">
+                              <string>${compiler:JALVIEW_DIR}/${compiler:INSTALL4J_UTILS_DIR}/warning.png</string>
+                            </object>
+                          </property>
+                          <property name="labelText" type="string">No automatic updates will occur when Jalview is launched</property>
+                        </serializedBean>
+                        <visibilityScript>!( context.getBooleanVariable("allowUserDefaultAppdirUpdates") || context.getBooleanVariable("allowInstallerAppdirUpdates") )</visibilityScript>
+                      </formComponent>
+                    </beans>
+                  </group>
+                </beans>
+              </group>
+            </formComponents>
+          </screen>
+          <screen name="SYSTEMSPACE: Additional checkboxes" id="2903" beanClass="com.install4j.runtime.beans.screens.FormScreen" rollbackBarrierExitCode="0">
+            <serializedBean>
+              <property name="subTitle" type="string">Additional tasks for administrator installation</property>
+              <property name="title" type="string">${i18n:WizardSelectTasks}</property>
+            </serializedBean>
+            <condition>context.getBooleanVariable("isAdmin")</condition>
+            <formComponents>
+              <formComponent name="Administrator mode label" id="3059" beanClass="com.install4j.runtime.beans.formcomponents.MultilineHtmlLabelComponent" insetBottom="16">
+                <serializedBean>
+                  <property name="labelHtml" type="string">&lt;strong&gt;Administrator mode&lt;/strong&gt;</property>
+                </serializedBean>
+                <visibilityScript>context.getBooleanVariable("isAdmin")</visibilityScript>
+              </formComponent>
+              <formComponent id="2904" beanClass="com.install4j.runtime.beans.formcomponents.MultilineLabelComponent" insetBottom="10">
+                <serializedBean>
+                  <property name="labelText" type="string">${i18n:SelectTasksLabel2(${compiler:JALVIEW_APPLICATION_NAME})}</property>
+                </serializedBean>
+              </formComponent>
+              <formComponent name="SYSTEMSPACE: Add jalview bin to all users' Path environment variable (Windows)" id="2909" beanClass="com.install4j.runtime.beans.formcomponents.CheckboxComponent">
+                <serializedBean>
+                  <property name="checkboxText" type="string">Add ${compiler:JALVIEW_APPLICATION_NAME}'s bin folder to the system Path environment variable</property>
+                  <property name="initiallySelected" type="boolean" value="true" />
+                  <property name="variableName" type="string">appendToPathAction</property>
+                </serializedBean>
+                <visibilityScript>Util.isWindows()</visibilityScript>
+              </formComponent>
+              <formComponent name="BOTHSPACE: Make a symbolic link to jalview.sh bash script in the user's/system local bin (Linux or Unix)" id="2908" beanClass="com.install4j.runtime.beans.formcomponents.CheckboxComponent">
+                <serializedBean>
+                  <property name="checkboxText" type="string">Make a ${compiler:WRAPPER_LINK} symbolic link in ${installer:unixBinDir}</property>
+                  <property name="initiallySelected" type="boolean" value="true" />
+                  <property name="variableName" type="string">makeSymbolicLinkAction</property>
+                </serializedBean>
+                <visibilityScript>context.getBooleanVariable("makeSymbolicLink")
+&amp;&amp; context.getVariable("unixBinDir") != null
+&amp;&amp; (
+     Util.isLinux()
+     || Util.isUnixInstaller()
+     || (
+          ( Util.isMacOS() &amp;&amp; !Util.hasFullAdminRights() ) // Admin on macOS will add path to /etc/paths.d
+          &amp;&amp; context.getVariable("MacOSDir") != null
+        )
+    )
+</visibilityScript>
+              </formComponent>
+              <formComponent id="2984" beanClass="com.install4j.runtime.beans.formcomponents.SpacerComponent" />
+              <formComponent name="Enable ADVANCED OPTIONS" id="3007" customizedId="SS_ADVANCED_OPTIONS" beanClass="com.install4j.runtime.beans.formcomponents.CheckboxComponent">
+                <serializedBean>
+                  <property name="checkboxText" type="string">Enable advanced options for system installation</property>
+                  <property name="coupledComponentIds">
+                    <add type="string">3030</add>
+                    <add type="string">2985</add>
+                    <add type="string">3013</add>
+                    <add type="string">2986</add>
+                    <add type="string">2974</add>
+                    <add type="string">2988</add>
+                  </property>
+                  <property name="selectionScript">
+                    <object class="com.install4j.api.beans.ScriptProperty">
+                      <property name="value" type="string">validateSystemSpaceAdvancedOptionsForm(context, formEnvironment)</property>
+                    </object>
+                  </property>
+                  <property name="variableName" type="string">advancedOptions</property>
+                </serializedBean>
+              </formComponent>
+              <formComponent name="Advanced options not used label" id="3032" customizedId="SS_NOT_USED" beanClass="com.install4j.runtime.beans.formcomponents.LabelComponent" insetLeft="20">
+                <serializedBean>
+                  <property name="labelColor">
+                    <object class="java.awt.Color">
+                      <int>128</int>
+                      <int>128</int>
+                      <int>128</int>
+                      <int>255</int>
+                    </object>
+                  </property>
+                  <property name="labelFontSizePercent" type="int" value="80" />
+                  <property name="labelFontType" type="enum" class="com.install4j.runtime.beans.formcomponents.FontType" value="DERIVED" />
+                  <property name="labelText" type="string">Advanced options will not be used</property>
+                </serializedBean>
+                <visibilityScript>!context.getBooleanVariable("advancedOptions")
+</visibilityScript>
+              </formComponent>
+              <group name="Advanced options (outer) group" id="3033" customizedId="SS_ADVANCED_OPTIONS_GROUP" beanClass="com.install4j.runtime.beans.groups.VerticalFormComponentGroup">
+                <serializedBean>
+                  <property name="visibilityScript">
+                    <object class="com.install4j.api.beans.ScriptProperty">
+                      <property name="value" type="string">context.getBooleanVariable("advancedOptions")
+</property>
+                    </object>
+                  </property>
+                </serializedBean>
+                <beans>
+                  <group name="Advanced options (boxed) group" id="3030" beanClass="com.install4j.runtime.beans.groups.VerticalFormComponentGroup">
+                    <serializedBean>
+                      <property name="borderSides">
+                        <object class="com.install4j.runtime.beans.formcomponents.BorderSides">
+                          <property name="bottom" type="boolean" value="true" />
+                          <property name="left" type="boolean" value="true" />
+                          <property name="right" type="boolean" value="true" />
+                          <property name="top" type="boolean" value="true" />
+                        </object>
+                      </property>
+                      <property name="insets">
+                        <object class="java.awt.Insets">
+                          <int>4</int>
+                          <int>4</int>
+                          <int>4</int>
+                          <int>4</int>
+                        </object>
+                      </property>
+                      <property name="visibilityScript">
+                        <object class="com.install4j.api.beans.ScriptProperty">
+                          <property name="value" type="string" />
+                        </object>
+                      </property>
+                    </serializedBean>
+                    <beans>
+                      <formComponent name="Strongly recommended text" id="2985" customizedId="SS_LABEL" beanClass="com.install4j.runtime.beans.formcomponents.MultilineHtmlLabelComponent" insetLeft="16">
+                        <serializedBean>
+                          <property name="labelHtml" type="string">&lt;html&gt;The following options are &lt;strong&gt;strongly recommended&lt;/strong&gt; to be left as default unless there is a particular reason to change them.&lt;/html&gt;</property>
+                        </serializedBean>
+                      </formComponent>
+                      <formComponent id="3013" customizedId="SS_VSPACE" beanClass="com.install4j.runtime.beans.formcomponents.SpacerComponent" insetLeft="16" />
+                      <formComponent name="BOTHSPACE: Allow automatic updates in user's home directory" id="2986" customizedId="SS_ALLOW_USER_APPDIR_UPDATES" beanClass="com.install4j.runtime.beans.formcomponents.CheckboxComponent" insetLeft="16">
+                        <serializedBean>
+                          <property name="checkboxText" type="string">Allow user-space updates for ${compiler:JALVIEW_APPLICATION_NAME} components</property>
+                          <property name="coupledComponentIds">
+                            <add type="string">3021</add>
+                          </property>
+                          <property name="helpText" type="string">&lt;html&gt;This option allows updates to ${compiler:JALVIEW_APPLICATION_NAME}
+&lt;br&gt;
+components to be automatically downloaded
+&lt;br&gt;
+under the user's home space, separately from
+&lt;br&gt;
+the installation location.
+&lt;br&gt;
+&lt;strong&gt;This option is strongly recommended.&lt;/strong&gt;
+&lt;br&gt;
+&lt;br&gt;
+On ${installer:osName}, user updates will be installed under
+&lt;pre&gt;${installer:userDefaultAppdirBase}&lt;/pre&gt;
+unless customised below.
+&lt;/html&gt;</property>
+                          <property name="selectionScript">
+                            <object class="com.install4j.api.beans.ScriptProperty">
+                              <property name="value" type="string">validateSystemSpaceAdvancedOptionsForm(context, formEnvironment)</property>
+                            </object>
+                          </property>
+                          <property name="variableName" type="string">allowUserDefaultAppdirUpdates</property>
+                        </serializedBean>
+                      </formComponent>
+                      <group name="SYSTEMSPACE: Customise user appDir path" id="3021" customizedId="SS_SET_USER_APPDIR_PATH" beanClass="com.install4j.runtime.beans.groups.HorizontalFormComponentGroup">
+                        <serializedBean>
+                          <property name="insets">
+                            <object class="java.awt.Insets">
+                              <int>0</int>
+                              <int>32</int>
+                              <int>0</int>
+                              <int>0</int>
+                            </object>
+                          </property>
+                          <property name="visibilityScript">
+                            <object class="com.install4j.api.beans.ScriptProperty">
+                              <property name="value" type="string" />
+                            </object>
+                          </property>
+                        </serializedBean>
+                        <beans>
+                          <formComponent name="SYSTEMSPACE: Allow setting userAppdirPath" id="3022" customizedId="SS_ALLOW_USER_APPDIR_PATH" beanClass="com.install4j.runtime.beans.formcomponents.CheckboxComponent">
+                            <serializedBean>
+                              <property name="checkboxText" type="string">Customise the user-space path</property>
+                              <property name="selectionScript">
+                                <object class="com.install4j.api.beans.ScriptProperty">
+                                  <property name="value" type="string">validateSystemSpaceAdvancedOptionsForm(context, formEnvironment)</property>
+                                </object>
+                              </property>
+                              <property name="variableName" type="string">allowSetUserAppdirPath</property>
+                            </serializedBean>
+                            <initScript>component.setEnabled( context.getBooleanVariable("allowUserDefaultAppdirUpdates") )</initScript>
+                          </formComponent>
+                          <formComponent name="SYSTEMSPACE: Set userAppdirPath" id="3024" customizedId="SS_USER_APPDIR_PATH" beanClass="com.install4j.runtime.beans.formcomponents.TextfieldComponent">
+                            <serializedBean>
+                              <property name="helpText" type="string">&lt;html&gt;The base path where individual users' updates
+&lt;br&gt;
+will be stored.
+&lt;br&gt;
+&lt;strong&gt;Only change this option if you need to!&lt;/strong&gt;
+&lt;br&gt;
+The following substitutions will be made:
+&lt;table&gt;
+&lt;tr&gt;&lt;td&gt;%u&lt;/td&gt;&lt;td&gt;The user's username&lt;/td&gt;&lt;/tr&gt;
+&lt;tr&gt;&lt;td&gt;%U&lt;/td&gt;&lt;td&gt;An ASCII string of the user's username&lt;/td&gt;&lt;/tr&gt;
+&lt;tr&gt;&lt;td&gt;%h&lt;/td&gt;&lt;td&gt;The user's home directory path&lt;/td&gt;&lt;/tr&gt;
+&lt;tr&gt;&lt;td&gt;~${installer:sys.fileSeparator}&lt;/td&gt;&lt;td&gt;(at start) The user's home directory path${installer:sys.fileSeparator}&lt;/td&gt;&lt;/tr&gt;
+&lt;/table&gt;
+At least one of the above substitutions should be
+&lt;br&gt;
+used, e.g. &lt;tt&gt;/tmp/${compiler:UNIX_APPLICATION_FOLDER}/%u/app&lt;/tt&gt;
+&lt;br&gt;
+The default value on ${installer:osName} is
+&lt;br&gt;
+&lt;pre&gt;${installer:userDefaultAppdirBase}&lt;/pre&gt;
+&lt;/html&gt;</property>
+                              <property name="inputVerifier">
+                                <object class="com.install4j.api.beans.ScriptProperty">
+                                  <property name="value" type="string">validateSystemSpaceAdvancedOptionsForm(context, formEnvironment, true)</property>
+                                </object>
+                              </property>
+                              <property name="keyListener">
+                                <object class="com.install4j.api.beans.ScriptProperty">
+                                  <property name="value" type="string">showInvalidUserAppdirPathWarning(context, formEnvironment)
+</property>
+                                </object>
+                              </property>
+                              <property name="keyValidator">
+                                <object class="com.install4j.api.beans.ScriptProperty">
+                                  <property name="value" type="string" />
+                                </object>
+                              </property>
+                              <property name="variableName" type="string">userAppdirPath</property>
+                            </serializedBean>
+                            <initScript>component.setEnabled( context.getBooleanVariable("allowUserDefaultAppdirUpdates") &amp;&amp; context.getBooleanVariable("allowSetUserAppdirPath") );
+</initScript>
+                          </formComponent>
+                        </beans>
+                      </group>
+                      <formComponent name="SYSTEMSPACE: Allow automatic updates in the installation directory" id="2974" customizedId="SS_ALLOW_INSTALLER_APPDIR_UPDATES" beanClass="com.install4j.runtime.beans.formcomponents.CheckboxComponent" insetLeft="16">
+                        <serializedBean>
+                          <property name="checkboxText" type="string">Allow installation updates for ${compiler:JALVIEW_APPLICATION_NAME} components</property>
+                          <property name="helpText" type="string">&lt;html&gt;This option allows updates to ${compiler:JALVIEW_APPLICATION_NAME}
+&lt;br&gt;
+components to be automatically downloaded
+&lt;br&gt;
+into the installation location.
+&lt;br&gt;
+If you are installing into a system location,
+&lt;br&gt;
+a non-administrator user may have problems
+&lt;br&gt;
+launching ${compiler:JALVIEW_APPLICATION_NAME}.
+&lt;br&gt;
+&lt;strong&gt;
+It is strongly recommended to use the
+&lt;br&gt;
+user-space updates option above.
+&lt;/strong&gt;
+&lt;br&gt;
+&lt;br&gt;
+Installation updates will be installed into
+&lt;br&gt;
+&lt;pre&gt;${installer:sys.contentDir}&lt;/pre&gt;
+&lt;/html&gt;</property>
+                          <property name="selectionScript">
+                            <object class="com.install4j.api.beans.ScriptProperty">
+                              <property name="value" type="string">validateSystemSpaceAdvancedOptionsForm(context, formEnvironment)</property>
+                            </object>
+                          </property>
+                          <property name="variableName" type="string">allowInstallerAppdirUpdates</property>
+                        </serializedBean>
+                        <initScript>component.setEnabled( !context.getBooleanVariable("allowUserDefaultAppdirUpdates") )</initScript>
+                      </formComponent>
+                      <formComponent name="Set defaults" id="3029" customizedId="SS_SET_DEFAULTS" beanClass="com.install4j.runtime.beans.formcomponents.ButtonComponent" insetTop="8" insetLeft="16">
+                        <serializedBean>
+                          <property name="actionScript">
+                            <object class="com.install4j.api.beans.ScriptProperty">
+                              <property name="value" type="string">FormComponent fc_userUpdates = formEnvironment.getFormComponentById("SS_ALLOW_USER_APPDIR_UPDATES");
+FormComponent fc_installerUpdates = formEnvironment.getFormComponentById("SS_ALLOW_INSTALLER_APPDIR_UPDATES");
+FormComponent fc_allowUserAppdirPath = formEnvironment.getFormComponentById("SS_ALLOW_USER_APPDIR_PATH");
+FormComponent fc_userAppdirPath = formEnvironment.getFormComponentById("SS_USER_APPDIR_PATH");
+
+// set defaults
+((JCheckBox) fc_userUpdates.getConfigurationObject()).setSelected(true);
+((JCheckBox) fc_allowUserAppdirPath.getConfigurationObject()).setSelected(false);
+((JTextField) fc_userAppdirPath.getConfigurationObject()).setText("");
+((JCheckBox) fc_installerUpdates.getConfigurationObject()).setSelected(false);
+
+// revalidate
+validateSystemSpaceAdvancedOptionsForm(context, formEnvironment);
+</property>
+                            </object>
+                          </property>
+                          <property name="buttonText" type="string">Reset advanced options to defaults</property>
+                        </serializedBean>
+                        <initScript>FormComponent fc_advancedOptions = formEnvironment.getFormComponentById("SS_ADVANCED_OPTIONS");
+FormComponent fc_userUpdates = formEnvironment.getFormComponentById("SS_ALLOW_USER_APPDIR_UPDATES");
+FormComponent fc_userAppdirPath = formEnvironment.getFormComponentById("SS_USER_APPDIR_PATH");
+FormComponent fc_installerUpdates = formEnvironment.getFormComponentById("SS_ALLOW_INSTALLER_APPDIR_UPDATES");
+FormComponent fc_allowUserAppdirPath = formEnvironment.getFormComponentById("SS_ALLOW_USER_APPDIR_PATH");
+
+JCheckBox jcb_user = (JCheckBox) fc_userUpdates.getConfigurationObject();
+boolean userUpdates = jcb_user.isSelected();
+
+JCheckBox jcb_allowUserAppdirPath = (JCheckBox) fc_allowUserAppdirPath.getConfigurationObject();
+boolean allowUserAppdirPath = jcb_allowUserAppdirPath.isSelected();
+
+JTextField jtf_userAppdirPath = (JTextField) fc_userAppdirPath.getConfigurationObject();
+String userAppdirPath = jtf_userAppdirPath.getText();
+
+JCheckBox jcb_installer = (JCheckBox) fc_installerUpdates.getConfigurationObject();
+boolean installerUpdates = jcb_installer.isSelected();
+
+
+// set whether "Set defaults" button should be enabled
+boolean enableSetDefaults = !( userUpdates &amp;&amp; !allowUserAppdirPath &amp;&amp; userAppdirPath.length() == 0 &amp;&amp; !installerUpdates );
+component.setEnabled(enableSetDefaults);</initScript>
+                      </formComponent>
+                      <formComponent name="BOTHSPACE: No updates warning" id="2988" customizedId="SS_NO_UPDATES_WARNING" beanClass="com.install4j.runtime.beans.formcomponents.LabelComponent" insetLeft="16">
+                        <serializedBean>
+                          <property name="labelIconFile">
+                            <object class="com.install4j.api.beans.ExternalFile">
+                              <string>${compiler:JALVIEW_DIR}/${compiler:INSTALL4J_UTILS_DIR}/warning.png</string>
+                            </object>
+                          </property>
+                          <property name="labelText" type="string">No automatic updates will occur when ${compiler:JALVIEW_APPLICATION_NAME} is launched</property>
+                        </serializedBean>
+                        <visibilityScript>!( context.getBooleanVariable("allowUserDefaultAppdirUpdates") || context.getBooleanVariable("allowInstallerAppdirUpdates") )</visibilityScript>
+                      </formComponent>
+                      <formComponent name="SYSTEMSPACE: Invalid user-space path warning" id="3027" customizedId="SS_INVALID_USER_APPDIR_PATH_WARNING" beanClass="com.install4j.runtime.beans.formcomponents.LabelComponent" insetLeft="16">
+                        <serializedBean>
+                          <property name="labelIconFile">
+                            <object class="com.install4j.api.beans.ExternalFile">
+                              <string>${compiler:JALVIEW_DIR}/${compiler:INSTALL4J_UTILS_DIR}/warning.png</string>
+                            </object>
+                          </property>
+                          <property name="labelText" type="string">The user-space path should contain one of "~${installer:sys.fileSeparator}" (at the start), "%u", "%U" or "%h"</property>
+                        </serializedBean>
+                        <visibilityScript>String userAppdirPath = (String) context.getVariable("userAppdirPath");
+
+if (userAppdirPath == null) {
+  return false;
+}
+
+boolean u = userAppdirPath.contains("%u");
+boolean U = userAppdirPath.contains("%U");
+boolean h = userAppdirPath.contains("%h");
+boolean t = userAppdirPath.startsWith("~" + (String)context.getVariable("sys.fileSeparator"));
+
+boolean showInvalidPathWarning = !( userAppdirPath.length() == 0 || u || U || h || t );
+
+return context.getBooleanVariable("allowUserDefaultAppdirUpdates") &amp;&amp; context.getBooleanVariable("allowSetUserAppdirPath") &amp;&amp; showInvalidPathWarning;</visibilityScript>
+                      </formComponent>
+                    </beans>
+                  </group>
+                </beans>
+              </group>
+            </formComponents>
+          </screen>
+          <screen id="15" customizedId="INSTALLATION" beanClass="com.install4j.runtime.beans.screens.InstallationScreen" rollbackBarrier="true" rollbackBarrierExitCode="0">
+            <actions>
+              <action id="17" beanClass="com.install4j.runtime.beans.actions.InstallFilesAction" rollbackBarrierExitCode="0" failureStrategy="quit" errorMessage="${i18n:FileCorrupted}" />
+              <action name="Create program group (RELEASE)" id="18" customizedId="PROGRAM_GROUP_RELEASE" beanClass="com.install4j.runtime.beans.actions.desktop.CreateProgramGroupAction" actionElevationType="elevated" rollbackBarrierExitCode="0">
+                <serializedBean>
+                  <void id="Boolean0" method="isAddUninstaller" />
+                  <property name="allUsers">
+                    <object idref="Boolean0" />
+                  </property>
+                  <property name="categories" type="string">${compiler:APPLICATION_CATEGORIES}</property>
+                  <property name="programGroupEntryConfigs">
+                    <add>
+                      <object class="com.install4j.runtime.beans.screens.components.ProgramGroupFileConfig">
+                        <property name="name" type="string">Examples</property>
+                        <property name="target">
+                          <object class="java.io.File">
+                            <string>examples</string>
+                          </object>
+                        </property>
+                      </object>
+                    </add>
+                  </property>
+                  <property name="programGroupName" type="string">${compiler:JALVIEW_NAME}</property>
+                  <property name="uninstallerMenuName" type="string">${i18n:UninstallerMenuEntry(${compiler:sys.fullName})}</property>
+                </serializedBean>
+                <condition>!context.getBooleanVariable("sys.programGroupDisabled")</condition>
+              </action>
+              <action name="Create program group (NON-RELEASE)" id="2730" customizedId="PROGRAM_GROUP_NON_RELEASE" beanClass="com.install4j.runtime.beans.actions.desktop.CreateProgramGroupAction" actionElevationType="elevated" rollbackBarrierExitCode="0">
+                <serializedBean>
+                  <void id="Boolean0" method="isAddUninstaller" />
+                  <property name="allUsers">
+                    <object idref="Boolean0" />
+                  </property>
+                  <property name="categories" type="string">${compiler:APPLICATION_CATEGORIES}</property>
+                  <property name="programGroupName" type="string">${compiler:JALVIEW_NAME}</property>
+                  <property name="uninstallerMenuName" type="string">${i18n:UninstallerMenuEntry(${compiler:sys.fullName})}</property>
+                </serializedBean>
+                <condition>!context.getBooleanVariable("sys.programGroupDisabled")</condition>
+              </action>
+              <action id="19" beanClass="com.install4j.runtime.beans.actions.desktop.RegisterAddRemoveAction" actionElevationType="elevated" rollbackBarrierExitCode="0">
+                <serializedBean>
+                  <property name="itemName" type="string">${compiler:sys.fullName} ${compiler:sys.version}</property>
+                </serializedBean>
+              </action>
+              <group name="File Associations" id="2251" customizedId="FA_SCREEN" beanClass="com.install4j.runtime.beans.groups.ActionGroup">
+                <beans>
+                  <action id="2253" beanClass="com.install4j.runtime.beans.actions.control.SetMessageAction" actionElevationType="none" rollbackBarrierExitCode="0">
+                    <serializedBean>
+                      <property name="statusMessage" type="string">Creating file associations...</property>
+                      <property name="useDetail" type="boolean" value="true" />
+                      <property name="useStatus" type="boolean" value="true" />
+                    </serializedBean>
+                  </action>
+                  <action id="2254" beanClass="com.install4j.runtime.beans.actions.control.SetProgressAction" actionElevationType="none" rollbackBarrierExitCode="0">
+                    <serializedBean>
+                      <property name="progressChangeType" type="enum" class="com.install4j.runtime.beans.actions.control.ProgressChangeType" value="SET_INDETERMINATE" />
+                    </serializedBean>
+                  </action>
+                  <group name="File Associations Replacement Group" id="2753" customizedId="EXTENSIONS_REPLACED_BY_GRADLE_PARENT_GROUP" beanClass="com.install4j.runtime.beans.groups.ActionGroup">
+                    <beans>
+                      <action name="EXTENSIONS_REPLACED_BY_GRADLE" id="1691" customizedId="EXTENSIONS" beanClass="com.install4j.runtime.beans.actions.desktop.CreateFileAssociationAction" actionElevationType="elevated" rollbackBarrierExitCode="0">
+                        <serializedBean>
+                          <property name="description" type="string">This action, identified by its name "EXTENSIONS_REPLACED_BY_GRADLE", will be replaced by gradle with the contents of file 'file_associations_auto_install4j.xml'.</property>
+                          <property name="extension" type="string">extensions_to_be_replaced_by_gradle</property>
+                          <property name="launcherId" type="string">JALVIEW</property>
+                        </serializedBean>
+                      </action>
+                    </beans>
+                  </group>
+                  <action id="2542" beanClass="com.install4j.runtime.beans.actions.control.SetMessageAction" actionElevationType="none" rollbackBarrierExitCode="0">
+                    <serializedBean>
+                      <property name="statusMessage" type="string">Finished creating file associations</property>
+                      <property name="useDetail" type="boolean" value="true" />
+                      <property name="useStatus" type="boolean" value="true" />
+                    </serializedBean>
+                  </action>
+                  <action id="2541" beanClass="com.install4j.runtime.beans.actions.control.SetProgressAction" actionElevationType="none" rollbackBarrierExitCode="0">
+                    <serializedBean>
+                      <property name="percentValue" type="int" value="99" />
+                    </serializedBean>
+                  </action>
+                </beans>
+              </group>
+              <action id="3017" beanClass="com.install4j.runtime.beans.actions.control.SetMessageAction" actionElevationType="none" rollbackBarrierExitCode="0">
+                <serializedBean>
+                  <property name="statusMessage" type="string">${i18n:FinishedHeadingLabel(${compiler:JALVIEW_APPLICATION_NAME})}</property>
+                  <property name="useDetail" type="boolean" value="true" />
+                  <property name="useStatus" type="boolean" value="true" />
+                </serializedBean>
+              </action>
+              <action id="3018" beanClass="com.install4j.runtime.beans.actions.control.SetProgressAction" actionElevationType="none" rollbackBarrierExitCode="0">
+                <serializedBean>
+                  <property name="progressChangeType" type="enum" class="com.install4j.runtime.beans.actions.control.ProgressChangeType" value="SET_INDETERMINATE" />
+                </serializedBean>
+              </action>
+              <group name="Register URL Handlers" id="2957" beanClass="com.install4j.runtime.beans.groups.ActionGroup">
+                <beans>
+                  <action id="2350" beanClass="com.install4j.runtime.beans.actions.desktop.UrlHandlerAction" actionElevationType="elevated" rollbackBarrierExitCode="0">
+                    <serializedBean>
+                      <property name="launcherId" type="string">2823</property>
+                      <property name="scheme" type="string">jalview</property>
+                    </serializedBean>
+                  </action>
+                  <action id="2822" beanClass="com.install4j.runtime.beans.actions.desktop.UrlHandlerAction" actionElevationType="elevated" rollbackBarrierExitCode="0">
+                    <serializedBean>
+                      <property name="launcherId" type="string">2823</property>
+                      <property name="scheme" type="string">jalviews</property>
+                    </serializedBean>
+                  </action>
+                  <action id="2819" beanClass="com.install4j.runtime.beans.actions.desktop.UrlHandlerAction" actionElevationType="elevated" rollbackBarrierExitCode="0">
+                    <serializedBean>
+                      <property name="launcherId" type="string">2823</property>
+                      <property name="scheme" type="string">jalviewhttp</property>
+                    </serializedBean>
+                  </action>
+                  <action id="2820" beanClass="com.install4j.runtime.beans.actions.desktop.UrlHandlerAction" actionElevationType="elevated" rollbackBarrierExitCode="0">
+                    <serializedBean>
+                      <property name="launcherId" type="string">2823</property>
+                      <property name="scheme" type="string">jalviewhttps</property>
+                    </serializedBean>
+                  </action>
+                  <action id="2641" beanClass="com.install4j.runtime.beans.actions.desktop.UrlHandlerAction" actionElevationType="elevated" rollbackBarrierExitCode="0">
+                    <serializedBean>
+                      <property name="launcherId" type="string">2823</property>
+                      <property name="scheme" type="string">${compiler:EXTRA_SCHEME}</property>
+                    </serializedBean>
+                  </action>
+                </beans>
+              </group>
+              <group name="USERSPACE: Actions" id="2921" beanClass="com.install4j.runtime.beans.groups.ActionGroup" actionElevationType="none">
+                <serializedBean>
+                  <property name="conditionExpression">
+                    <object class="com.install4j.api.beans.ScriptProperty">
+                      <property name="value" type="string">!context.getBooleanVariable("isAdmin")</property>
+                    </object>
+                  </property>
+                </serializedBean>
+                <beans>
+                  <action name="USERSPACE: Create Start Menu item" id="2916" beanClass="com.install4j.runtime.beans.actions.desktop.CreateStartMenuEntryAction" actionElevationType="elevated" rollbackBarrierExitCode="0">
+                    <serializedBean>
+                      <property name="allUsers" type="boolean" value="false" />
+                      <property name="categories" type="string">${compiler:APPLICATION_CATEGORIES}</property>
+                      <property name="entryName" type="string">${compiler:JALVIEW_APPLICATION_NAME}</property>
+                      <property name="file">
+                        <object class="java.io.File">
+                          <string>${installer:sys.contentDir}/${compiler:EXECUTABLE_NAME}</string>
+                        </object>
+                      </property>
+                      <property name="icon">
+                        <object class="com.install4j.api.beans.ExternalFile">
+                          <string>${compiler:JALVIEW_DIR}/${compiler:ICONS_DIR}/${compiler:WINDOWS_ICONS_FILE}</string>
+                        </object>
+                      </property>
+                      <property name="programGroupName" type="string">${compiler:JALVIEW_NAME}</property>
+                      <property name="unixIconFile">
+                        <object class="com.install4j.api.beans.ExternalFile">
+                          <string>${compiler:JALVIEW_DIR}/${compiler:ICONS_DIR}/${compiler:PNG_ICON_FILE}</string>
+                        </object>
+                      </property>
+                    </serializedBean>
+                    <condition>!context.getBooleanVariable("sys.programGroupDisabled")</condition>
+                  </action>
+                  <action name="USERSPACE: Add a desktop link" id="2917" beanClass="com.install4j.runtime.beans.actions.desktop.CreateDesktopLinkAction" actionElevationType="elevated" rollbackBarrierExitCode="0" errorMessage="Could not make desktop link">
+                    <serializedBean>
+                      <property name="allUsers" type="boolean" value="false" />
+                      <property name="description" type="string">${compiler:JALVIEW_APPLICATION_NAME}</property>
+                      <property name="file">
+                        <object class="java.io.File">
+                          <string>${installer:sys.contentDir}/${compiler:EXECUTABLE_NAME}</string>
+                        </object>
+                      </property>
+                      <property name="name" type="string">${compiler:JALVIEW_APPLICATION_NAME}</property>
+                      <property name="unixIconFile">
+                        <object class="com.install4j.api.beans.ExternalFile">
+                          <string>${compiler:JALVIEW_DIR}/${compiler:ICONS_DIR}/${compiler:PNG_ICON_FILE}</string>
+                        </object>
+                      </property>
+                      <property name="winIconFile">
+                        <object class="com.install4j.api.beans.ExternalFile">
+                          <string>${compiler:JALVIEW_DIR}/${compiler:ICONS_DIR}/${compiler:WINDOWS_ICONS_FILE}</string>
+                        </object>
+                      </property>
+                    </serializedBean>
+                    <condition>context.getBooleanVariable("createDesktopLinkAction")</condition>
+                  </action>
+                  <action name="USERSPACE: Add an executable to the dock (macOS)" id="2918" beanClass="com.install4j.runtime.beans.actions.desktop.AddToDockAction" actionElevationType="none" rollbackBarrierExitCode="0">
+                    <serializedBean>
+                      <property name="executable">
+                        <object class="java.io.File">
+                          <string>${compiler:JALVIEW_APPLICATION_NAME}.app</string>
+                        </object>
+                      </property>
+                    </serializedBean>
+                    <condition>context.getBooleanVariable("addToDockAction")</condition>
+                  </action>
+                  <action name="USERSPACE: Add Jalview bin to the user's path (Windows)" id="2919" beanClass="com.install4j.runtime.beans.actions.misc.ModifyEnvironmentVariableAction" actionElevationType="elevated" rollbackBarrierExitCode="0" errorMessage="Could not add &quot;${installer:sys.contentDir}\${compiler:WRAPPER_SCRIPT_BIN_DIR}&quot; to the Path environment variable">
+                    <serializedBean>
+                      <property name="type" type="enum" class="com.install4j.runtime.beans.actions.misc.ModifyStringType" value="APPEND" />
+                      <property name="value" type="string">${installer:sys.contentDir}\${compiler:WRAPPER_SCRIPT_BIN_DIR}</property>
+                      <property name="variableName" type="string">Path</property>
+                    </serializedBean>
+                    <condition>context.getBooleanVariable("appendToPathAction")</condition>
+                  </action>
+                  <action name="USERSPACE: Create macOS symbolic link to jalview.sh" id="2920" beanClass="com.install4j.runtime.beans.actions.files.CreateSymlinkAction" rollbackBarrierExitCode="0" errorMessage="Could not make a ${compiler:WRAPPER_LINK} symbolic link in ~/${installer:MacOSDir}">
+                    <serializedBean>
+                      <property name="file">
+                        <object class="java.io.File">
+                          <string>../Resources/app/${compiler:WRAPPER_SCRIPT_BIN_DIR}/${compiler:BASH_WRAPPER_SCRIPT}</string>
+                        </object>
+                      </property>
+                      <property name="linkFile">
+                        <object class="java.io.File">
+                          <string>${installer:MacOSDir}/${compiler:WRAPPER_LINK}</string>
+                        </object>
+                      </property>
+                    </serializedBean>
+                    <condition>Util.isMacOS() &amp;&amp;
+(
+  context.getBooleanVariable("makeSymbolicLinkAction")
+  &amp;&amp; context.getVariable("unixBinDir") != null
+  &amp;&amp; context.getVariable("MacOSDir") != null
+)</condition>
+                  </action>
+                  <action name="USERSPACE: Create macOS symbolic link to update.sh" id="3052" beanClass="com.install4j.runtime.beans.actions.files.CreateSymlinkAction" rollbackBarrierExitCode="0" errorMessage="Could not make a ${compiler:WRAPPER_LINK} symbolic link in ~/${installer:MacOSDir}">
+                    <serializedBean>
+                      <property name="file">
+                        <object class="java.io.File">
+                          <string>../Resources/app/${compiler:WRAPPER_SCRIPT_BIN_DIR}/${compiler:BASH_UPDATE_SCRIPT}</string>
+                        </object>
+                      </property>
+                      <property name="linkFile">
+                        <object class="java.io.File">
+                          <string>${installer:MacOSDir}/update_${compiler:WRAPPER_LINK}</string>
+                        </object>
+                      </property>
+                    </serializedBean>
+                    <condition>Util.isMacOS() &amp;&amp;
+(
+  context.getBooleanVariable("makeSymbolicLinkAction")
+  &amp;&amp; context.getVariable("unixBinDir") != null
+  &amp;&amp; context.getVariable("MacOSDir") != null
+)</condition>
+                  </action>
+                  <action name="USERSPACE: Create macOS symbolic link to jalview in user's local bin" id="3048" beanClass="com.install4j.runtime.beans.actions.files.CreateSymlinkAction" rollbackBarrierExitCode="0" errorMessage="Could not make a ${compiler:WRAPPER_LINK} symbolic link in ~/${installer:unixBinDir}">
+                    <serializedBean>
+                      <property name="file">
+                        <object class="java.io.File">
+                          <string>${installer:MacOSDir}/${compiler:WRAPPER_LINK}</string>
+                        </object>
+                      </property>
+                      <property name="linkFile">
+                        <object class="java.io.File">
+                          <string>${installer:unixBinDir}/${compiler:WRAPPER_LINK}</string>
+                        </object>
+                      </property>
+                    </serializedBean>
+                    <condition>Util.isMacOS() &amp;&amp;
+(
+  context.getBooleanVariable("makeSymbolicLinkAction")
+  &amp;&amp; context.getVariable("unixBinDir") != null
+  &amp;&amp; context.getVariable("MacOSDir") != null
+)</condition>
+                  </action>
+                  <action name="USERSPACE: Create macOS symbolic link to jalview_update in user's local bin" id="3049" beanClass="com.install4j.runtime.beans.actions.files.CreateSymlinkAction" rollbackBarrierExitCode="0" errorMessage="Could not make a ${compiler:WRAPPER_LINK} symbolic link in ~/${installer:unixBinDir}">
+                    <serializedBean>
+                      <property name="file">
+                        <object class="java.io.File">
+                          <string>${installer:MacOSDir}/update_${compiler:WRAPPER_LINK}</string>
+                        </object>
+                      </property>
+                      <property name="linkFile">
+                        <object class="java.io.File">
+                          <string>${installer:unixBinDir}/update_${compiler:WRAPPER_LINK}</string>
+                        </object>
+                      </property>
+                    </serializedBean>
+                    <condition>Util.isMacOS() &amp;&amp;
+(
+  context.getBooleanVariable("makeSymbolicLinkAction")
+  &amp;&amp; context.getVariable("unixBinDir") != null
+  &amp;&amp; context.getVariable("MacOSDir") != null
+)</condition>
+                  </action>
+                </beans>
+              </group>
+              <group name="SYSTEMSPACE: Actions" id="2954" beanClass="com.install4j.runtime.beans.groups.ActionGroup" actionElevationType="elevated">
+                <serializedBean>
+                  <property name="conditionExpression">
+                    <object class="com.install4j.api.beans.ScriptProperty">
+                      <property name="value" type="string">context.getBooleanVariable("isAdmin")</property>
+                    </object>
+                  </property>
+                </serializedBean>
+                <beans>
+                  <action name="SYSTEMSPACE: Create Start Menu item" id="2950" beanClass="com.install4j.runtime.beans.actions.desktop.CreateStartMenuEntryAction" actionElevationType="elevated" rollbackBarrierExitCode="0">
+                    <serializedBean>
+                      <property name="categories" type="string">${compiler:APPLICATION_CATEGORIES}</property>
+                      <property name="entryName" type="string">${compiler:JALVIEW_APPLICATION_NAME}</property>
+                      <property name="file">
+                        <object class="java.io.File">
+                          <string>${installer:sys.contentDir}/${compiler:EXECUTABLE_NAME}</string>
+                        </object>
+                      </property>
+                      <property name="icon">
+                        <object class="com.install4j.api.beans.ExternalFile">
+                          <string>${compiler:JALVIEW_DIR}/${compiler:ICONS_DIR}/${compiler:WINDOWS_ICONS_FILE}</string>
+                        </object>
+                      </property>
+                      <property name="programGroupName" type="string">${compiler:JALVIEW_NAME}</property>
+                      <void id="Boolean0" method="isAllUsers" />
+                      <property name="runAsAdministrator">
+                        <object idref="Boolean0" />
+                      </property>
+                      <property name="unixIconFile">
+                        <object class="com.install4j.api.beans.ExternalFile">
+                          <string>${compiler:JALVIEW_DIR}/${compiler:ICONS_DIR}/${compiler:PNG_ICON_FILE}</string>
+                        </object>
+                      </property>
+                    </serializedBean>
+                    <condition>!context.getBooleanVariable("sys.programGroupDisabled")</condition>
+                  </action>
+                  <action name="SYSTEMSPACE: Add a desktop link" id="2951" beanClass="com.install4j.runtime.beans.actions.desktop.CreateDesktopLinkAction" actionElevationType="elevated" rollbackBarrierExitCode="0" errorMessage="Could not make desktop link">
+                    <serializedBean>
+                      <property name="description" type="string">${compiler:JALVIEW_APPLICATION_NAME}</property>
+                      <property name="file">
+                        <object class="java.io.File">
+                          <string>${installer:sys.contentDir}/${compiler:EXECUTABLE_NAME}</string>
+                        </object>
+                      </property>
+                      <property name="name" type="string">${compiler:JALVIEW_APPLICATION_NAME}</property>
+                      <void id="Boolean0" method="isAllUsers" />
+                      <property name="runAsAdministrator">
+                        <object idref="Boolean0" />
+                      </property>
+                      <property name="unixIconFile">
+                        <object class="com.install4j.api.beans.ExternalFile">
+                          <string>${compiler:JALVIEW_DIR}/${compiler:ICONS_DIR}/${compiler:PNG_ICON_FILE}</string>
+                        </object>
+                      </property>
+                      <property name="winIconFile">
+                        <object class="com.install4j.api.beans.ExternalFile">
+                          <string>${compiler:JALVIEW_DIR}/${compiler:ICONS_DIR}/${compiler:WINDOWS_ICONS_FILE}</string>
+                        </object>
+                      </property>
+                    </serializedBean>
+                    <condition>context.getBooleanVariable("createDesktopLinkAction")</condition>
+                  </action>
+                  <action name="SYSTEMSPACE: Add Jalview bin to the system path (Windows)" id="2952" beanClass="com.install4j.runtime.beans.actions.misc.ModifyEnvironmentVariableAction" actionElevationType="elevated" rollbackBarrierExitCode="0" errorMessage="Could not add &quot;${installer:sys.contentDir}\${compiler:WRAPPER_SCRIPT_BIN_DIR}&quot; to the Path environment variable">
+                    <serializedBean>
+                      <property name="type" type="enum" class="com.install4j.runtime.beans.actions.misc.ModifyStringType" value="APPEND" />
+                      <void id="Boolean0" method="isRevertOnlyIfNotModified" />
+                      <property name="userSpecific">
+                        <object idref="Boolean0" />
+                      </property>
+                      <property name="value" type="string">${installer:sys.contentDir}\${compiler:WRAPPER_SCRIPT_BIN_DIR}</property>
+                      <property name="variableName" type="string">Path</property>
+                    </serializedBean>
+                    <condition>context.getBooleanVariable("appendToPathAction")</condition>
+                  </action>
+                  <action name="SYSTEMSPACE: Set installationAppdirHash" id="3041" beanClass="com.install4j.runtime.beans.actions.control.SetVariableAction" rollbackBarrierExitCode="0">
+                    <serializedBean>
+                      <property name="script">
+                        <object class="com.install4j.api.beans.ScriptProperty">
+                          <property name="value" type="string">String dir = (String)context.getVariable("sys.installationDir");
+String hash = getCanonicalFullPathToDirectoryHash(dir);
+return (Object) hash;
+</property>
+                        </object>
+                      </property>
+                      <property name="variableName" type="string">installationAppdirHash</property>
+                    </serializedBean>
+                  </action>
+                  <action name="SYSTEMSPACE: macOS /etc/paths.d entry" id="2953" beanClass="com.install4j.runtime.beans.actions.text.WriteTextFileAction" actionElevationType="elevated" rollbackBarrierExitCode="0">
+                    <serializedBean>
+                      <property name="file">
+                        <object class="java.io.File">
+                          <string>/etc/paths.d/${compiler:APPLICATION_FOLDER}-${installer:installationAppdirHash}</string>
+                        </object>
+                      </property>
+                      <property name="text" type="string">${installer:sys.installationDir}/${installer:sys.contentDir}/${compiler:JALVIEW_APPLICATION_NAME}.app/Contents/MacOS</property>
+                    </serializedBean>
+                    <condition>Util.isMacOS()</condition>
+                  </action>
+                </beans>
+              </group>
+              <group name="BOTHSPACE: Actions" id="2956" beanClass="com.install4j.runtime.beans.groups.ActionGroup" actionElevationType="elevated">
+                <beans>
+                  <action name="BOTHSPACE: Create Linux/Unix user symbolic link to jalview.sh in system/user bin" id="2955" beanClass="com.install4j.runtime.beans.actions.files.CreateSymlinkAction" rollbackBarrierExitCode="0" errorMessage="Could not make a ${compiler:WRAPPER_LINK} symbolic link in ~/${installer:unixBinDir}">
+                    <serializedBean>
+                      <property name="file">
+                        <object class="java.io.File">
+                          <string>${installer:sys.contentDir}/${compiler:WRAPPER_SCRIPT_BIN_DIR}/${compiler:BASH_WRAPPER_SCRIPT}</string>
+                        </object>
+                      </property>
+                      <property name="linkFile">
+                        <object class="java.io.File">
+                          <string>${installer:unixBinDir}/${compiler:WRAPPER_LINK}</string>
+                        </object>
+                      </property>
+                    </serializedBean>
+                    <condition>context.getBooleanVariable("makeSymbolicLink")
+&amp;&amp; context.getBooleanVariable("makeSymbolicLinkAction")
+&amp;&amp; context.getVariable("unixBinDir") != null</condition>
+                  </action>
+                </beans>
+              </group>
+              <group name="USER/SYSTEMSPACE: VMOPTIONS Getdown update properties" id="3000" beanClass="com.install4j.runtime.beans.groups.ActionGroup">
+                <beans>
+                  <action name="Set disableUserDefaultAppdirUpdates" id="3011" beanClass="com.install4j.runtime.beans.actions.control.SetVariableAction" rollbackBarrierExitCode="0">
+                    <serializedBean>
+                      <property name="script">
+                        <object class="com.install4j.api.beans.ScriptProperty">
+                          <property name="value" type="string">boolean advanced = context.getBooleanVariable("advancedOptions");
+boolean allowUser = context.getBooleanVariable("allowUserDefaultAppdirUpdates");
+boolean consoleDisableUserAppdir = context.getBooleanVariable("consoleDisableUserAppdir");
+if (consoleDisableUserAppdir) {
+    return true;
+}
+return advanced ? !allowUser : false;</property>
+                        </object>
+                      </property>
+                      <property name="variableName" type="string">disableUserDefaultAppdirUpdates</property>
+                    </serializedBean>
+                  </action>
+                  <action name="Set setUserAppdirPath" id="3025" beanClass="com.install4j.runtime.beans.actions.control.SetVariableAction" rollbackBarrierExitCode="0">
+                    <serializedBean>
+                      <property name="script">
+                        <object class="com.install4j.api.beans.ScriptProperty">
+                          <property name="value" type="string">boolean advanced = context.getBooleanVariable("advancedOptions");
+boolean allowUser = context.getBooleanVariable("allowUserDefaultAppdirUpdates");
+boolean allowSetUserAppdirPath = context.getBooleanVariable("allowSetUserAppdirPath");
+String userAppdirPath = (String)context.getVariable("userAppdirPath");
+boolean saneValue = userAppdirPath != null &amp;&amp; userAppdirPath.length() &gt; 0;
+boolean consoleAllowUserAppdirPath = context.getBooleanVariable("consoleAllowUserAppdirPath");
+if (consoleAllowUserAppdirPath &amp;&amp; saneValue) {
+    return userAppdirPath;
+}
+return advanced &amp;&amp; allowUser &amp;&amp; allowSetUserAppdirPath &amp;&amp; saneValue ? userAppdirPath : null;</property>
+                        </object>
+                      </property>
+                      <property name="variableName" type="string">setUserAppdirPath</property>
+                    </serializedBean>
+                  </action>
+                  <action name="Set disableUpdates" id="3012" beanClass="com.install4j.runtime.beans.actions.control.SetVariableAction" rollbackBarrierExitCode="0">
+                    <serializedBean>
+                      <property name="script">
+                        <object class="com.install4j.api.beans.ScriptProperty">
+                          <property name="value" type="string">boolean advanced = context.getBooleanVariable("advancedOptions");
+boolean allowUser = context.getBooleanVariable("allowUserDefaultAppdirUpdates");
+boolean allowInstaller = context.getBooleanVariable("allowInstallerAppdirUpdates");
+boolean consoleDisableAllUpdates = context.getBooleanVariable("consoleDisableAllUpdates");
+if (consoleDisableAllUpdates) {
+    return true;
+}
+return advanced ? !( allowUser || allowInstaller ) : false;</property>
+                        </object>
+                      </property>
+                      <property name="variableName" type="string">disableUpdates</property>
+                    </serializedBean>
+                  </action>
+                  <action name="Set installerFilename" id="3043" beanClass="com.install4j.runtime.beans.actions.control.SetVariableAction" rollbackBarrierExitCode="0">
+                    <serializedBean>
+                      <property name="script">
+                        <object class="com.install4j.api.beans.ScriptProperty">
+                          <property name="value" type="string">String file = (String)context.getVariable("sys.mediaFile");
+int i = file.lastIndexOf(File.separator);
+return file.substring(i+1);</property>
+                        </object>
+                      </property>
+                      <property name="variableName" type="string">installerFilename</property>
+                    </serializedBean>
+                  </action>
+                  <action name="Set installDateTime" id="3044" beanClass="com.install4j.runtime.beans.actions.control.SetVariableAction" rollbackBarrierExitCode="0">
+                    <serializedBean>
+                      <property name="script">
+                        <object class="com.install4j.api.beans.ScriptProperty">
+                          <property name="value" type="string">String date = (String)context.getVariable("sys.date");
+String time = (String)context.getVariable("sys.time");
+StringBuilder sb = new StringBuilder();
+sb.append(date.substring(0,4));
+sb.append("-");
+sb.append(date.substring(4,6));
+sb.append("-");
+sb.append(date.substring(6,8));
+sb.append(" ");
+sb.append(time.substring(0,2));
+sb.append(":");
+sb.append(time.substring(2,4));
+sb.append(":");
+sb.append(time.substring(4,6));
+return sb.toString();
+</property>
+                        </object>
+                      </property>
+                      <property name="variableName" type="string">installDateTime</property>
+                    </serializedBean>
+                  </action>
+                  <action name="Initial comment" id="3010" beanClass="com.install4j.runtime.beans.actions.misc.AddVmOptionsAction" actionElevationType="elevated" rollbackBarrierExitCode="0">
+                    <serializedBean>
+                      <property name="launcherId" type="string">2823</property>
+                      <property name="vmOptions" type="array" elementType="string" length="1">
+                        <element index="0"># Jalview options added by ${installer:installerFilename} at ${installer:installDateTime}</element>
+                      </property>
+                    </serializedBean>
+                  </action>
+                  <action name="Allow user-space updates" id="2996" beanClass="com.install4j.runtime.beans.actions.misc.AddVmOptionsAction" actionElevationType="elevated" rollbackBarrierExitCode="0">
+                    <serializedBean>
+                      <property name="launcherId" type="string">2823</property>
+                      <property name="vmOptions" type="array" elementType="string" length="3">
+                        <element index="0"># </element>
+                        <element index="1"># Uncomment the following line to disable user-space updates</element>
+                        <element index="2">#-Dnouserdefaultappdir=true</element>
+                      </property>
+                    </serializedBean>
+                    <condition>!context.getBooleanVariable("disableUserDefaultAppdirUpdates")</condition>
+                  </action>
+                  <action name="Disable user-space updates" id="2997" beanClass="com.install4j.runtime.beans.actions.misc.AddVmOptionsAction" actionElevationType="elevated" rollbackBarrierExitCode="0">
+                    <serializedBean>
+                      <property name="launcherId" type="string">2823</property>
+                      <property name="vmOptions" type="array" elementType="string" length="3">
+                        <element index="0"># </element>
+                        <element index="1"># Comment out the following line to allow user-space updates</element>
+                        <element index="2">-Dnouserdefaultappdir=true</element>
+                      </property>
+                    </serializedBean>
+                    <condition>context.getBooleanVariable("disableUserDefaultAppdirUpdates")</condition>
+                  </action>
+                  <action name="Set setUserAppdirPath property" id="3026" beanClass="com.install4j.runtime.beans.actions.misc.AddVmOptionsAction" actionElevationType="elevated" rollbackBarrierExitCode="0">
+                    <serializedBean>
+                      <property name="launcherId" type="string">2823</property>
+                      <property name="vmOptions" type="array" elementType="string" length="5">
+                        <element index="0"># </element>
+                        <element index="1"># The below line sets a custom path for user-space updates -- use with caution.</element>
+                        <element index="2"># A leading ~/ or %h anywhere will be substituted with the user's home path, %u by the username, and %U by an ASCII string of the username.</element>
+                        <element index="3"># If unset, the default is ${installer:userDefaultAppdirBase} for ${installer:osName}</element>
+                        <element index="4">-Dsetuserappdirpath=${installer:setUserAppdirPath}</element>
+                      </property>
+                    </serializedBean>
+                    <condition>(String)context.getVariable("setUserAppdirPath") != null</condition>
+                  </action>
+                  <action name="Don't set setUserAppdirPath property" id="3037" beanClass="com.install4j.runtime.beans.actions.misc.AddVmOptionsAction" actionElevationType="elevated" rollbackBarrierExitCode="0">
+                    <serializedBean>
+                      <property name="launcherId" type="string">2823</property>
+                      <property name="vmOptions" type="array" elementType="string" length="5">
+                        <element index="0"># </element>
+                        <element index="1"># Uncomment the below line to set a custom path for user-space updates -- use with caution.</element>
+                        <element index="2"># A leading ~/ or %h anywhere will be substituted with the user's home path, %u by the username, and %U by an ASCII string of the username.</element>
+                        <element index="3"># If not set, the default is ${installer:userDefaultAppdirBase} for ${installer:osName}</element>
+                        <element index="4">#-Dsetuserappdirpath=/tmp/jalview/%u</element>
+                      </property>
+                    </serializedBean>
+                    <condition>(String)context.getVariable("setUserAppdirPath") == null</condition>
+                  </action>
+                  <action name="Allow updates" id="2998" beanClass="com.install4j.runtime.beans.actions.misc.AddVmOptionsAction" actionElevationType="elevated" rollbackBarrierExitCode="0">
+                    <serializedBean>
+                      <property name="launcherId" type="string">2823</property>
+                      <property name="vmOptions" type="array" elementType="string" length="3">
+                        <element index="0"># </element>
+                        <element index="1"># Uncomment the following line to also disable all updates</element>
+                        <element index="2">#-Dsilent=noupdate </element>
+                      </property>
+                    </serializedBean>
+                    <condition>!context.getBooleanVariable("disableUpdates")</condition>
+                  </action>
+                  <action name="Disable updates" id="2999" beanClass="com.install4j.runtime.beans.actions.misc.AddVmOptionsAction" actionElevationType="elevated" rollbackBarrierExitCode="0">
+                    <serializedBean>
+                      <property name="launcherId" type="string">2823</property>
+                      <property name="vmOptions" type="array" elementType="string" length="3">
+                        <element index="0"># </element>
+                        <element index="1"># Comment out the following line to enable updates</element>
+                        <element index="2">-Dsilent=noupdate</element>
+                      </property>
+                    </serializedBean>
+                    <condition>context.getBooleanVariable("disableUpdates")</condition>
+                  </action>
+                </beans>
+              </group>
+              <group name="Java bin symlinks" id="2944" beanClass="com.install4j.runtime.beans.groups.ActionGroup">
+                <beans>
+                  <action name="macOS/Linux Jalview-&gt;java symlink" id="2942" beanClass="com.install4j.runtime.beans.actions.files.CreateSymlinkAction" rollbackBarrierExitCode="0" errorMessage="Could not make symlink to wrapper script">
+                    <serializedBean>
+                      <property name="file">
+                        <object class="java.io.File">
+                          <string>${compiler:JRE_DIR}/bin/java</string>
+                        </object>
+                      </property>
+                      <property name="linkFile">
+                        <object class="java.io.File">
+                          <string>${compiler:JRE_DIR}/bin/${compiler:JALVIEW_NAME}</string>
+                        </object>
+                      </property>
+                      <void id="Boolean0" method="isExecuteOnWindows" />
+                      <property name="removeOnUninstall">
+                        <object idref="Boolean0" />
+                      </property>
+                    </serializedBean>
+                    <condition>Util.isLinux() || ( Util.isMacOS() &amp;&amp; !Util.isUnixInstaller() )</condition>
+                  </action>
+                  <action name="macOS/Linux Jalview Appname-&gt;java symlink" id="2943" beanClass="com.install4j.runtime.beans.actions.files.CreateSymlinkAction" rollbackBarrierExitCode="0" errorMessage="Could not make symlink to wrapper script">
+                    <serializedBean>
+                      <property name="file">
+                        <object class="java.io.File">
+                          <string>${compiler:JRE_DIR}/bin/java</string>
+                        </object>
+                      </property>
+                      <property name="linkFile">
+                        <object class="java.io.File">
+                          <string>${compiler:JRE_DIR}/bin/${compiler:JALVIEW_APPLICATION_NAME}</string>
+                        </object>
+                      </property>
+                      <void id="Boolean0" method="isExecuteOnWindows" />
+                      <property name="removeOnUninstall">
+                        <object idref="Boolean0" />
+                      </property>
+                    </serializedBean>
+                    <condition>( Util.isLinux() || ( Util.isMacOS() &amp;&amp; !Util.isUnixInstaller() ) )
+&amp;&amp; !((String)context.getCompilerVariable("JALVIEW_APPLICATION_NAME")).equals((String)context.getCompilerVariable("JALVIEW_NAME"))</condition>
+                  </action>
+                </beans>
+              </group>
+              <group name="Jalview bin symlink" id="2946" beanClass="com.install4j.runtime.beans.groups.ActionGroup">
+                <beans>
+                  <action name="Linux/Unix jalview.sh bin dir symlink" id="2945" beanClass="com.install4j.runtime.beans.actions.files.CreateSymlinkAction" rollbackBarrierExitCode="0" errorMessage="Could not make symlink to wrapper script">
+                    <serializedBean>
+                      <property name="file">
+                        <object class="java.io.File">
+                          <string>${compiler:WRAPPER_SCRIPT_BIN_DIR}/${compiler:BASH_WRAPPER_SCRIPT}</string>
+                        </object>
+                      </property>
+                      <property name="linkFile">
+                        <object class="java.io.File">
+                          <string>${compiler:WRAPPER_SCRIPT_BIN_DIR}/${compiler:WRAPPER_LINK}</string>
+                        </object>
+                      </property>
+                    </serializedBean>
+                    <condition>Util.isLinux() || Util.isUnixInstaller() || Util.isMacOS()</condition>
+                  </action>
+                  <action name="Linux/Unix update.sh bin dir symlink" id="3079" beanClass="com.install4j.runtime.beans.actions.files.CreateSymlinkAction" rollbackBarrierExitCode="0" errorMessage="Could not make symlink to wrapper script">
+                    <serializedBean>
+                      <property name="file">
+                        <object class="java.io.File">
+                          <string>${compiler:WRAPPER_SCRIPT_BIN_DIR}/${compiler:BASH_UPDATE_SCRIPT}</string>
+                        </object>
+                      </property>
+                      <property name="linkFile">
+                        <object class="java.io.File">
+                          <string>${compiler:WRAPPER_SCRIPT_BIN_DIR}/${compiler:WRAPPER_LINK}_update</string>
+                        </object>
+                      </property>
+                    </serializedBean>
+                    <condition>Util.isLinux() || Util.isUnixInstaller() || Util.isMacOS()</condition>
+                  </action>
+                </beans>
+              </group>
+              <action id="3020" beanClass="com.install4j.runtime.beans.actions.control.SetProgressAction" actionElevationType="none" rollbackBarrierExitCode="0">
+                <serializedBean>
+                  <property name="percentValue" type="int" value="100" />
+                </serializedBean>
+              </action>
+              <action id="3065" beanClass="com.install4j.runtime.beans.actions.control.SleepAction" actionElevationType="none" rollbackBarrierExitCode="0">
+                <serializedBean>
+                  <property name="sleepTimeMs" type="int" value="250" />
+                </serializedBean>
+              </action>
+            </actions>
+            <formComponents>
+              <formComponent name="Administrator mode label" id="3061" beanClass="com.install4j.runtime.beans.formcomponents.MultilineHtmlLabelComponent" insetBottom="16">
+                <serializedBean>
+                  <property name="labelHtml" type="string">&lt;strong&gt;Administrator mode&lt;/strong&gt;</property>
+                </serializedBean>
+                <visibilityScript>context.getBooleanVariable("isAdmin")</visibilityScript>
+              </formComponent>
+              <formComponent id="16" beanClass="com.install4j.runtime.beans.formcomponents.ProgressComponent">
+                <serializedBean>
+                  <property name="initialStatusMessage" type="string">${i18n:WizardPreparing}</property>
+                </serializedBean>
+              </formComponent>
+            </formComponents>
+          </screen>
+          <screen id="20" beanClass="com.install4j.runtime.beans.screens.FinishedScreen" rollbackBarrierExitCode="0" finishScreen="true">
+            <formComponents>
+              <formComponent name="Administrator mode label" id="3060" beanClass="com.install4j.runtime.beans.formcomponents.MultilineHtmlLabelComponent" insetBottom="16">
+                <serializedBean>
+                  <property name="labelHtml" type="string">&lt;strong&gt;Administrator mode&lt;/strong&gt;</property>
+                </serializedBean>
+                <visibilityScript>context.getBooleanVariable("isAdmin")</visibilityScript>
+              </formComponent>
+              <formComponent id="21" beanClass="com.install4j.runtime.beans.formcomponents.MultilineLabelComponent" insetBottom="10">
+                <serializedBean>
+                  <property name="labelText" type="string">${form:finishedMessage}</property>
+                </serializedBean>
+              </formComponent>
+            </formComponents>
+          </screen>
+        </screens>
+      </application>
+      <application id="uninstaller" beanClass="com.install4j.runtime.beans.applications.UninstallerApplication" actionElevationType="elevated" styleId="35">
+        <serializedBean>
+          <property name="customMacosExecutableName" type="string">${i18n:UninstallerMenuEntry(${compiler:sys.fullName})}</property>
+          <property name="frameHeight" type="int" value="480" />
+          <property name="frameWidth" type="int" value="640" />
+          <void id="Boolean0" method="isAllowConsole" />
+          <property name="useCustomMacosExecutableName">
+            <object idref="Boolean0" />
+          </property>
+        </serializedBean>
+        <styleOverrides>
+          <styleOverride name="Customize banner image" enabled="true">
+            <group id="147" 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="java.awt.Color">
+                    <int>192</int>
+                    <int>192</int>
+                    <int>192</int>
+                    <int>255</int>
+                  </object>
+                </property>
+                <property name="imageEdgeBorder" type="boolean" value="true" />
+                <property name="imageFile">
+                  <object class="com.install4j.api.beans.ExternalFile">
+                    <string>${compiler:JALVIEW_DIR}/${compiler:BACKGROUND}</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>
+              <externalParametrizationPropertyNames>
+                <propertyName>imageAnchor</propertyName>
+                <propertyName>imageEdgeBackgroundColor</propertyName>
+                <propertyName>imageFile</propertyName>
+              </externalParametrizationPropertyNames>
+            </group>
+          </styleOverride>
+        </styleOverrides>
+        <startup>
+          <screen id="23" beanClass="com.install4j.runtime.beans.screens.StartupScreen" rollbackBarrierExitCode="0">
+            <actions>
+              <action id="33" beanClass="com.install4j.runtime.beans.actions.misc.LoadResponseFileAction" rollbackBarrierExitCode="0" />
+              <action id="34" beanClass="com.install4j.runtime.beans.actions.misc.RequireInstallerPrivilegesAction" actionElevationType="none" rollbackBarrierExitCode="0" />
+            </actions>
+          </screen>
+        </startup>
+        <screens>
+          <screen id="24" beanClass="com.install4j.runtime.beans.screens.UninstallWelcomeScreen" rollbackBarrierExitCode="0">
+            <formComponents>
+              <formComponent id="25" 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="26" 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 id="27" beanClass="com.install4j.runtime.beans.screens.UninstallationScreen" rollbackBarrierExitCode="0">
+            <actions>
+              <action id="659" beanClass="com.install4j.runtime.beans.actions.control.SetProgressAction" actionElevationType="none" rollbackBarrierExitCode="0">
+                <serializedBean>
+                  <property name="progressChangeType" type="enum" class="com.install4j.runtime.beans.actions.control.ProgressChangeType" value="SET_INDETERMINATE" />
+                </serializedBean>
+              </action>
+              <action id="29" beanClass="com.install4j.runtime.beans.actions.UninstallFilesAction" rollbackBarrierExitCode="0" />
+              <action id="660" beanClass="com.install4j.runtime.beans.actions.control.SetProgressAction" enabled="false" actionElevationType="none" rollbackBarrierExitCode="0">
+                <serializedBean>
+                  <property name="percentValue" type="int" value="95" />
+                </serializedBean>
+              </action>
+              <action id="1525" beanClass="com.install4j.runtime.beans.actions.files.DeleteFileAction" rollbackBarrierExitCode="0">
+                <serializedBean>
+                  <property name="files" type="array" class="java.io.File" length="40">
+                    <element index="0">
+                      <object class="java.io.File">
+                        <string>jre</string>
+                      </object>
+                    </element>
+                    <element index="1">
+                      <object class="java.io.File">
+                        <string>jre.jar</string>
+                      </object>
+                    </element>
+                    <element index="2">
+                      <object class="java.io.File">
+                        <string>.install4j</string>
+                      </object>
+                    </element>
+                    <element index="3">
+                      <object class="java.io.File">
+                        <string>getdown-launcher.jar</string>
+                      </object>
+                    </element>
+                    <element index="4">
+                      <object class="java.io.File">
+                        <string>getdown-launcher-old.jar</string>
+                      </object>
+                    </element>
+                    <element index="5">
+                      <object class="java.io.File">
+                        <string>getdown-launcher-new.jar</string>
+                      </object>
+                    </element>
+                    <element index="6">
+                      <object class="java.io.File">
+                        <string>gettingdown.lock</string>
+                      </object>
+                    </element>
+                    <element index="7">
+                      <object class="java.io.File">
+                        <string>jre.zip</string>
+                      </object>
+                    </element>
+                    <element index="8">
+                      <object class="java.io.File">
+                        <string>digest.txt</string>
+                      </object>
+                    </element>
+                    <element index="9">
+                      <object class="java.io.File">
+                        <string>digest2.txt</string>
+                      </object>
+                    </element>
+                    <element index="10">
+                      <object class="java.io.File">
+                        <string>getdown-launcher.jarv</string>
+                      </object>
+                    </element>
+                    <element index="11">
+                      <object class="java.io.File">
+                        <string>getdown-launcher-new.jarv</string>
+                      </object>
+                    </element>
+                    <element index="12">
+                      <object class="java.io.File">
+                        <string>launcher.log</string>
+                      </object>
+                    </element>
+                    <element index="13">
+                      <object class="java.io.File">
+                        <string>proxy.txt</string>
+                      </object>
+                    </element>
+                    <element index="14">
+                      <object class="java.io.File">
+                        <string>build_properties</string>
+                      </object>
+                    </element>
+                    <element index="15">
+                      <object class="java.io.File">
+                        <string>channel_launch*.jvl</string>
+                      </object>
+                    </element>
+                    <element index="16">
+                      <object class="java.io.File">
+                        <string>jalview*.jvl</string>
+                      </object>
+                    </element>
+                    <element index="17">
+                      <object class="java.io.File">
+                        <string>*.jarv</string>
+                      </object>
+                    </element>
+                    <element index="18">
+                      <object class="java.io.File">
+                        <string>*.log</string>
+                      </object>
+                    </element>
+                    <element index="19">
+                      <object class="java.io.File">
+                        <string>*.txt</string>
+                      </object>
+                    </element>
+                    <element index="20">
+                      <object class="java.io.File">
+                        <string>*_new</string>
+                      </object>
+                    </element>
+                    <element index="21">
+                      <object class="java.io.File">
+                        <string>hs_err_*.*</string>
+                      </object>
+                    </element>
+                    <element index="22">
+                      <object class="java.io.File">
+                        <string>${compiler:GETDOWN_DIST_DIR}</string>
+                      </object>
+                    </element>
+                    <element index="23">
+                      <object class="java.io.File">
+                        <string>${compiler:GETDOWN_ALT_DIR}</string>
+                      </object>
+                    </element>
+                    <element index="24">
+                      <object class="java.io.File">
+                        <string>${compiler:GETDOWN_RESOURCE_DIR}</string>
+                      </object>
+                    </element>
+                    <element index="25">
+                      <object class="java.io.File">
+                        <string>META-INF</string>
+                      </object>
+                    </element>
+                    <element index="26">
+                      <object class="java.io.File">
+                        <string>install</string>
+                      </object>
+                    </element>
+                    <element index="27">
+                      <object class="java.io.File">
+                        <string>resource</string>
+                      </object>
+                    </element>
+                    <element index="28">
+                      <object class="java.io.File">
+                        <string>dist</string>
+                      </object>
+                    </element>
+                    <element index="29">
+                      <object class="java.io.File">
+                        <string>release</string>
+                      </object>
+                    </element>
+                    <element index="30">
+                      <object class="java.io.File">
+                        <string>alt</string>
+                      </object>
+                    </element>
+                    <element index="31">
+                      <object class="java.io.File">
+                        <string>dev</string>
+                      </object>
+                    </element>
+                    <element index="32">
+                      <object class="java.io.File">
+                        <string>build</string>
+                      </object>
+                    </element>
+                    <element index="33">
+                      <object class="java.io.File">
+                        <string>alt_*</string>
+                      </object>
+                    </element>
+                    <element index="34">
+                      <object class="java.io.File">
+                        <string>dev_*</string>
+                      </object>
+                    </element>
+                    <element index="35">
+                      <object class="java.io.File">
+                        <string>build_*</string>
+                      </object>
+                    </element>
+                    <element index="36">
+                      <object class="java.io.File">
+                        <string>${compiler:WRAPPER_SCRIPT_BIN_DIR}</string>
+                      </object>
+                    </element>
+                    <element index="37">
+                      <object class="java.io.File">
+                        <string>bin</string>
+                      </object>
+                    </element>
+                    <element index="38">
+                      <object class="java.io.File">
+                        <string>channel.props</string>
+                      </object>
+                    </element>
+                    <element index="39">
+                      <object class="java.io.File">
+                        <string>channel.propsv</string>
+                      </object>
+                    </element>
+                  </property>
+                  <void id="Boolean0" method="isBackupForRollback" />
+                  <property name="recursive">
+                    <object idref="Boolean0" />
+                  </property>
+                </serializedBean>
+              </action>
+              <action id="1791" beanClass="com.install4j.runtime.beans.actions.control.SetProgressAction" actionElevationType="none" rollbackBarrierExitCode="0">
+                <serializedBean>
+                  <property name="percentValue" type="int" value="100" />
+                </serializedBean>
+              </action>
+            </actions>
+            <formComponents>
+              <formComponent id="28" beanClass="com.install4j.runtime.beans.formcomponents.ProgressComponent">
+                <serializedBean>
+                  <property name="initialStatusMessage" type="string">${i18n:UninstallerPreparing}</property>
+                </serializedBean>
+              </formComponent>
+            </formComponents>
+          </screen>
+          <screen id="32" beanClass="com.install4j.runtime.beans.screens.UninstallFailureScreen" rollbackBarrierExitCode="0" finishScreen="true" />
+          <screen id="30" beanClass="com.install4j.runtime.beans.screens.UninstallSuccessScreen" styleId="41" rollbackBarrierExitCode="0" finishScreen="true">
+            <formComponents>
+              <formComponent id="31" 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="MacOS Setup" id="2746" beanClass="com.install4j.runtime.beans.applications.CustomApplication" fileset="734" macEntitlementsFile="${compiler:JALVIEW_DIR}/utils/osx_signing/entitlements.txt">
+        <serializedBean>
+          <property name="executableDirectory">
+            <object class="java.io.File">
+              <string>.</string>
+            </object>
+          </property>
+          <property name="executableName" type="string">${compiler:WRAPPER_LINK}_setup</property>
+          <property name="frameHeight" type="int" value="600" />
+          <property name="frameWidth" type="int" value="800" />
+          <property name="windowTitle" type="string">${compiler:sys.fullName}</property>
+        </serializedBean>
+        <startup>
+          <screen id="2747" beanClass="com.install4j.runtime.beans.screens.StartupScreen" rollbackBarrierExitCode="0">
+            <actions>
+              <link id="2749" targetId="22" />
+              <link id="2751" targetId="2745" />
+            </actions>
+          </screen>
+        </startup>
+        <screens>
+          <screen id="2772" beanClass="com.install4j.runtime.beans.screens.FormScreen" rollbackBarrierExitCode="0" backButton="hidden" finishScreen="true">
+            <serializedBean>
+              <property name="title" type="string">Running ${i18n:SetupAppTitle}</property>
+            </serializedBean>
+            <formComponents>
+              <formComponent id="2773" beanClass="com.install4j.runtime.beans.formcomponents.MultilineLabelComponent" insetBottom="10">
+                <serializedBean>
+                  <property name="labelText" type="string">${i18n:FinishedLabel(${compiler:JALVIEW_APPLICATION_NAME})}</property>
+                </serializedBean>
+              </formComponent>
+              <formComponent name="Add an executable to the dock" id="2775" beanClass="com.install4j.runtime.beans.formcomponents.CheckboxComponent">
+                <serializedBean>
+                  <property name="checkboxText" type="string">${i18n:AddToDock}</property>
+                  <property name="initiallySelected" type="boolean" value="true" />
+                  <property name="variableName" type="string">addToDockAction</property>
+                </serializedBean>
+                <visibilityScript>Util.isMacOS()</visibilityScript>
+              </formComponent>
+              <formComponent name="Make a symbolic link to jalview.sh bash script in the user's local bin (Linux or Unix)" id="2777" beanClass="com.install4j.runtime.beans.formcomponents.CheckboxComponent">
+                <serializedBean>
+                  <property name="checkboxText" type="string">Make a ${compiler:WRAPPER_LINK} symbolic link in ${installer:unixBinDir}</property>
+                  <property name="initiallySelected" type="boolean" value="true" />
+                  <property name="variableName" type="string">makeSymbolicLinkAction</property>
+                </serializedBean>
+                <visibilityScript>
+
+( Util.isLinux()
+  || Util.isUnixInstaller()
+  || ( Util.isMacOS()
+       &amp;&amp; context.getVariable("MacOSDir") != null
+     )
+ )
+ &amp;&amp; context.getVariable("unixBinDir") != null</visibilityScript>
+              </formComponent>
+              <formComponent id="2780" beanClass="com.install4j.runtime.beans.formcomponents.MultilineLabelComponent">
+                <serializedBean>
+                  <property name="labelText" type="string">
+${i18n:ClickFinish}
+
+${compiler:JALVIEW_APPLICATION_NAME} will now launch.</property>
+                </serializedBean>
+              </formComponent>
+            </formComponents>
+          </screen>
+        </screens>
+      </application>
+    </applications>
+    <styles defaultStyleId="35">
+      <style name="Standard" id="35" beanClass="com.install4j.runtime.beans.styles.FormStyle">
+        <formComponents>
+          <formComponent name="Header" id="36" beanClass="com.install4j.runtime.beans.styles.NestedStyleComponent" insetTop="0" insetBottom="0">
+            <serializedBean>
+              <property name="styleId" type="string">48</property>
+            </serializedBean>
+          </formComponent>
+          <group name="Main" id="37" beanClass="com.install4j.runtime.beans.groups.VerticalFormComponentGroup">
+            <serializedBean>
+              <property name="imageEdgeAxisType" type="enum" class="com.install4j.runtime.beans.formcomponents.AxisType" value="HORIZONTAL" />
+              <property name="imageEdgeBackgroundColor">
+                <object class="java.awt.Color">
+                  <int>255</int>
+                  <int>255</int>
+                  <int>255</int>
+                  <int>255</int>
+                </object>
+              </property>
+              <property name="imageFile">
+                <object class="com.install4j.api.beans.ExternalFile">
+                  <string>${compiler:JALVIEW_DIR}/${compiler:BACKGROUND}</string>
+                </object>
+              </property>
+              <property name="imageOverlap" type="boolean" value="true" />
+            </serializedBean>
+            <beans>
+              <formComponent id="38" beanClass="com.install4j.runtime.beans.styles.ContentComponent" insetTop="10" insetLeft="20" insetBottom="10" insetRight="20" />
+              <formComponent name="Watermark" id="39" beanClass="com.install4j.runtime.beans.formcomponents.SeparatorComponent" insetTop="0" insetLeft="5" insetBottom="0" useExternalParametrization="true" externalParametrizationMode="include">
+                <serializedBean>
+                  <property name="enabledTitleText" type="boolean" value="false" />
+                </serializedBean>
+                <externalParametrizationPropertyNames>
+                  <propertyName>labelText</propertyName>
+                </externalParametrizationPropertyNames>
+              </formComponent>
+              <formComponent name="Footer" id="40" beanClass="com.install4j.runtime.beans.styles.NestedStyleComponent" insetTop="0" insetBottom="0">
+                <serializedBean>
+                  <property name="styleId" type="string">52</property>
+                </serializedBean>
+              </formComponent>
+            </beans>
+          </group>
+        </formComponents>
+      </style>
+      <style name="Banner" id="41" beanClass="com.install4j.runtime.beans.styles.FormStyle">
+        <formComponents>
+          <group id="42" 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>
+              <void id="Integer0" property="cellSpacing" />
+              <property name="imageEdgeBackgroundColor">
+                <object class="com.install4j.runtime.beans.LightOrDarkColor">
+                  <object class="java.awt.Color">
+                    <int>25</int>
+                    <int>143</int>
+                    <int>220</int>
+                    <int>255</int>
+                  </object>
+                  <object class="java.awt.Color">
+                    <object idref="Integer0" />
+                    <int>74</int>
+                    <int>151</int>
+                    <int>255</int>
+                  </object>
+                </object>
+              </property>
+              <property name="imageEdgeBorder" type="boolean" value="true" />
+              <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="43" beanClass="com.install4j.runtime.beans.styles.ScreenTitleComponent" insetTop="0">
+                <serializedBean>
+                  <property name="labelFontSizePercent" type="int" value="130" />
+                  <property name="labelFontStyle" type="enum" class="com.install4j.runtime.beans.formcomponents.FontStyle" value="BOLD" />
+                  <property name="labelFontType" type="enum" class="com.install4j.runtime.beans.formcomponents.FontType" value="DERIVED" />
+                </serializedBean>
+              </formComponent>
+              <formComponent id="44" beanClass="com.install4j.runtime.beans.formcomponents.SeparatorComponent" />
+              <formComponent id="45" 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="46" beanClass="com.install4j.runtime.beans.styles.NestedStyleComponent" insetBottom="0">
+            <serializedBean>
+              <property name="styleId" type="string">52</property>
+            </serializedBean>
+          </formComponent>
+        </formComponents>
+      </style>
+      <group name="Style components" id="47" beanClass="com.install4j.runtime.beans.groups.StyleGroup">
+        <beans>
+          <style name="Standard header" id="48" 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="49" 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>
+                  <void id="Integer0" property="cellSpacing" />
+                  <void id="Integer1" property="borderWidth" />
+                  <property name="imageInsets">
+                    <object class="java.awt.Insets">
+                      <object idref="Integer0" />
+                      <int>5</int>
+                      <object idref="Integer1" />
+                      <object idref="Integer1" />
+                    </object>
+                  </property>
+                  <property name="insets">
+                    <object class="java.awt.Insets">
+                      <object idref="Integer0" />
+                      <int>20</int>
+                      <object idref="Integer0" />
+                      <int>10</int>
+                    </object>
+                  </property>
+                </serializedBean>
+                <beans>
+                  <formComponent name="Title" id="50" beanClass="com.install4j.runtime.beans.styles.ScreenTitleComponent">
+                    <serializedBean>
+                      <property name="labelFontStyle" type="enum" class="com.install4j.runtime.beans.formcomponents.FontStyle" value="BOLD" />
+                      <property name="labelFontType" type="enum" class="com.install4j.runtime.beans.formcomponents.FontType" value="DERIVED" />
+                    </serializedBean>
+                  </formComponent>
+                  <formComponent name="Subtitle" id="51" 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="52" 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="53" beanClass="com.install4j.runtime.beans.groups.HorizontalFormComponentGroup">
+                <serializedBean>
+                  <property name="alignFirstLabel" type="boolean" value="false" />
+                  <void id="Integer0" property="cellSpacing" />
+                  <property name="insets">
+                    <object class="java.awt.Insets">
+                      <int>3</int>
+                      <object idref="Integer0" />
+                      <int>8</int>
+                      <object idref="Integer0" />
+                    </object>
+                  </property>
+                </serializedBean>
+                <beans>
+                  <formComponent id="54" beanClass="com.install4j.runtime.beans.formcomponents.SpringComponent" />
+                  <formComponent name="Back button" id="55" 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="56" 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="57" 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>
+  </installerGui>
+  <mediaSets>
+    <windows name="Windows x64 EXE Installer" id="743" customizedId="WINDOWS-X64-EXE" mediaFileName="${compiler:APPLICATION_FOLDER}-${compiler:JALVIEW_VERSION}-${compiler:sys.platform}-java_${compiler:JAVA_INTEGER_VERSION}" installDir="${compiler:APPLICATION_FOLDER}" runPostProcessor="true" postProcessor="${compiler:JSIGN_SH} $EXECUTABLE" architecture="64">
+      <excludedBeans>
+        <bean refId="2746" />
+      </excludedBeans>
+      <exclude>
+        <entry defaultFileset="true" />
+        <entry filesetId="2801" />
+        <entry filesetId="2803" />
+      </exclude>
+      <jreBundle jreBundleSource="preCreated" includedJre="${compiler:WINDOWS_X64_JAVA_VM_TGZ}" manualJreEntry="true" />
+    </windows>
+    <macosArchive name="macOS (Intel) Disk Image" id="878" customizedId="MACOS-X64-DMG" mediaFileName="${compiler:MACOSARCHIVE_X64_DMG_FILENAME}" volumeName="${compiler:MACOSARCHIVE_X64_NAME}" architecture="amd64" launcherId="2823" setupAppId="2746">
+      <excludedBeans>
+        <bean refId="2746" />
+      </excludedBeans>
+      <exclude>
+        <entry defaultFileset="true" />
+        <entry filesetId="2803" />
+      </exclude>
+      <jreBundle jreBundleSource="none" includedJre="${compiler:MACOS_X64_JAVA_VM_TGZ}" manualJreEntry="true" />
+      <topLevelFiles>
+        <symlink name="&quot; &quot;" target="/Applications" />
+        <file name=".background/${compiler:MACOS_DMG_BG_FILENAME}" file="${compiler:JALVIEW_DIR}/${compiler:MACOS_DMG_BG_IMAGE}" />
+        <file name=".DS_Store" file="${compiler:JALVIEW_DIR}/${compiler:MACOS_X64_DMG_DS_STORE}" />
+        <file name="${compiler:JALVIEW_APPLICATION_NAME}.app/Contents/Resources/Jalview-File.icns" file="${compiler:JALVIEW_DIR}/${compiler:INSTALL4J_UTILS_DIR}/Jalview-File.icns" />
+        <file name="${compiler:JALVIEW_APPLICATION_NAME}.app/Contents/Resources/jvl_file.icns" file="${compiler:JALVIEW_DIR}/${compiler:INSTALL4J_UTILS_DIR}/jvl_file.icns" />
+        <symlink name="${compiler:JALVIEW_APPLICATION_NAME}.app/Contents/MacOS/${compiler:WRAPPER_LINK}" target="../Resources/app/${compiler:WRAPPER_SCRIPT_BIN_DIR}/${compiler:BASH_WRAPPER_SCRIPT}" />
+        <symlink name="${compiler:JALVIEW_APPLICATION_NAME}.app/Contents/MacOS/${compiler:WRAPPER_LINK}_update" target="../Resources/app/${compiler:WRAPPER_SCRIPT_BIN_DIR}/${compiler:BASH_UPDATE_SCRIPT}" />
+        <symlink name="${compiler:JALVIEW_APPLICATION_NAME}.app/Contents/Resources/app/jre/Contents/Home/bin/${compiler:JALVIEW_APPLICATION_NAME}" target="java" />
+        <symlink name="${compiler:JALVIEW_APPLICATION_NAME}.app/Contents/Resources/app/jre/Contents/Home/bin/${compiler:JALVIEW_NAME}" target="java" />
+        <file name=".VolumeIcon.icns" file="${compiler:JALVIEW_DIR}/${compiler:MACOSARCHIVE_VOLUMEICON}" />
+        <file name="${compiler:JALVIEW_APPLICATION_NAME}.app/Contents/vmoptions.txt" file="${compiler:JALVIEW_DIR}/${compiler:BUILD_DIR}/tmp/default.vmoptions.X64" />
+        <file name=".jalview/build_properties" file="${compiler:JALVIEW_DIR}/build/resources/resources_build/.build_properties" />
+        <file name=".jalview/channel.props" file="${compiler:JALVIEW_DIR}/build/resources/resources_build/channel.props" />
+      </topLevelFiles>
+    </macosArchive>
+    <macosArchive name="macOS (Apple Silicon) Disk Image" id="2796" customizedId="MACOS-AARCH64-DMG" mediaFileName="${compiler:MACOSARCHIVE_AARCH64_DMG_FILENAME}" volumeName="${compiler:MACOSARCHIVE_AARCH64_NAME}" launcherId="2823" setupAppId="2746">
+      <excludedBeans>
+        <bean refId="2746" />
+      </excludedBeans>
+      <exclude>
+        <entry defaultFileset="true" />
+        <entry filesetId="2801" />
+      </exclude>
+      <jreBundle jreBundleSource="none" />
+      <topLevelFiles>
+        <symlink name="&quot; &quot;" target="/Applications" />
+        <file name=".background/${compiler:MACOS_DMG_BG_FILENAME}" file="${compiler:JALVIEW_DIR}/${compiler:MACOS_DMG_BG_IMAGE}" />
+        <file name=".DS_Store" file="${compiler:JALVIEW_DIR}/${compiler:MACOS_AARCH64_DMG_DS_STORE}" />
+        <file name="${compiler:JALVIEW_APPLICATION_NAME}.app/Contents/Resources/Jalview-File.icns" file="${compiler:JALVIEW_DIR}/${compiler:INSTALL4J_UTILS_DIR}/Jalview-File.icns" />
+        <file name="${compiler:JALVIEW_APPLICATION_NAME}.app/Contents/Resources/jvl_file.icns" file="${compiler:JALVIEW_DIR}/${compiler:INSTALL4J_UTILS_DIR}/jvl_file.icns" />
+        <symlink name="${compiler:JALVIEW_APPLICATION_NAME}.app/Contents/MacOS/${compiler:WRAPPER_LINK}" target="../Resources/app/${compiler:WRAPPER_SCRIPT_BIN_DIR}/${compiler:BASH_WRAPPER_SCRIPT}" />
+        <symlink name="${compiler:JALVIEW_APPLICATION_NAME}.app/Contents/MacOS/${compiler:WRAPPER_LINK}_update" target="../Resources/app/${compiler:WRAPPER_SCRIPT_BIN_DIR}/${compiler:BASH_UPDATE_SCRIPT}" />
+        <symlink name="${compiler:JALVIEW_APPLICATION_NAME}.app/Contents/Resources/app/jre/Contents/Home/bin/${compiler:JALVIEW_APPLICATION_NAME}" target="java" />
+        <symlink name="${compiler:JALVIEW_APPLICATION_NAME}.app/Contents/Resources/app/jre/Contents/Home/bin/${compiler:JALVIEW_NAME}" target="java" />
+        <file name=".VolumeIcon.icns" file="${compiler:JALVIEW_DIR}/${compiler:MACOSARCHIVE_VOLUMEICON}" />
+        <file name="${compiler:JALVIEW_APPLICATION_NAME}.app/Contents/vmoptions.txt" file="${compiler:JALVIEW_DIR}/${compiler:BUILD_DIR}/tmp/default.vmoptions.AARCH64" />
+        <file name=".jalview/build_properties" file="${compiler:JALVIEW_DIR}/build/resources/resources_build/.build_properties" />
+        <file name=".jalview/channel.props" file="${compiler:JALVIEW_DIR}/build/resources/resources_build/channel.props" />
+      </topLevelFiles>
+    </macosArchive>
+    <unixInstaller name="Linux x64 Shell Installer" id="1595" customizedId="LINUX-X64-SH" mediaFileName="${compiler:UNIX_APPLICATION_FOLDER}-${compiler:JALVIEW_VERSION}-linux-x64-java_${compiler:JAVA_INTEGER_VERSION}" installDir="${compiler:UNIX_APPLICATION_FOLDER}">
+      <excludedBeans>
+        <bean refId="2746" />
+      </excludedBeans>
+      <exclude>
+        <entry defaultFileset="true" />
+        <entry filesetId="2801" />
+        <entry filesetId="2803" />
+      </exclude>
+      <variables>
+        <variable name="variable" value="720" />
+        <variable name="WIZARD_HEIGHT" value="800" />
+      </variables>
+      <jreBundle jreBundleSource="preCreated" includedJre="${compiler:LINUX_X64_JAVA_VM_TGZ}" manualJreEntry="true" />
+    </unixInstaller>
+    <unixInstaller name="Linux aarch64 Shell Installer" id="2782" customizedId="LINUX-AARCH64-SH" mediaFileName="${compiler:UNIX_APPLICATION_FOLDER}-${compiler:JALVIEW_VERSION}-linux-aarch64-java_${compiler:JAVA_INTEGER_VERSION}" installDir="${compiler:UNIX_APPLICATION_FOLDER}">
+      <excludedBeans>
+        <bean refId="2746" />
+      </excludedBeans>
+      <exclude>
+        <entry defaultFileset="true" />
+        <entry filesetId="2801" />
+        <entry filesetId="2803" />
+      </exclude>
+      <variables>
+        <variable name="variable" value="720" />
+        <variable name="WIZARD_HEIGHT" value="800" />
+      </variables>
+      <jreBundle jreBundleSource="preCreated" includedJre="${compiler:LINUX_AARCH64_JAVA_VM_TGZ}" manualJreEntry="true" />
+    </unixInstaller>
+    <unixArchive name="Unix .tar.gz Archive" id="1596" customizedId="UNIX--TGZ" mediaFileName="${compiler:UNIX_APPLICATION_FOLDER}-${compiler:JALVIEW_VERSION}-${compiler:sys.platform}-java_${compiler:JAVA_INTEGER_VERSION}" installDir="${compiler:UNIX_APPLICATION_FOLDER}">
+      <excludedBeans>
+        <bean refId="2746" />
+      </excludedBeans>
+      <exclude>
+        <entry defaultFileset="true" />
+        <entry filesetId="2801" />
+        <entry filesetId="2803" />
+      </exclude>
+      <jreBundle jreBundleSource="none" includedJre="${compiler:LINUX_X64_JAVA_VM_TGZ}" manualJreEntry="true" />
+    </unixArchive>
+    <unixInstaller name="Unix Shell Installer" id="2639" customizedId="UNIX--SH" mediaFileName="${compiler:UNIX_APPLICATION_FOLDER}-${compiler:JALVIEW_VERSION}-${compiler:sys.platform}-java_${compiler:JAVA_INTEGER_VERSION}" installDir="${compiler:UNIX_APPLICATION_FOLDER}">
+      <excludedBeans>
+        <bean refId="2746" />
+      </excludedBeans>
+      <exclude>
+        <entry defaultFileset="true" />
+        <entry filesetId="2801" />
+        <entry filesetId="2803" />
+      </exclude>
+      <jreBundle jreBundleSource="none" includedJre="${compiler:LINUX_X64_JAVA_VM_TGZ}" manualJreEntry="true" />
+    </unixInstaller>
+  </mediaSets>
+  <buildIds buildAll="false">
+    <mediaSet refId="3042" />
+  </buildIds>
+</install4j>