diff --git a/.hgtags b/.hgtags
index 07ddf93c11858f1c5952b42e0e18501b5d6de1f0..0f67e5c3d3c2b64bca7ca5484393597e9720da8a 100755
--- a/.hgtags
+++ b/.hgtags
@@ -471,3 +471,4 @@ d40c66e410741de7e90b1ed6dac28dd8a2d7e1f6 3.6.8-release
 5b54b36862ff8bc3b6935673c9d1c1f22ee8d521 3.6.10-release
 2feb70a4cfde43f2898d95ff8fcae3e67805c7c2 3.6.11-release
 88bbfd7a6971033f3aa103f3a3500ceb4c73521b 3.6.12-release
+0d9b9e50f1a8880e05f15688a9ec7d09e0e81013 3.6.13-release
diff --git a/BuildParams b/BuildParams
index 6b63448c52743cc83987552425d1addb5d8981f5..ede2595cd349f5ad78c6d3230b7342c3d067a09b 100755
--- a/BuildParams
+++ b/BuildParams
@@ -49,11 +49,13 @@ viewer_channel = "Second Life Test"
 
 # Setup default packaging parameters.
 sourceid = ""
-additional_packages = "Amazon Desura B C"
+additional_packages = "Amazon Desura A B C"
 Amazon_sourceid = "1207v_Amazon"
 Amazon_viewer_channel_suffix = "Amazon"
 Desura_sourceid = "1208_desura"
 Desura_viewer_channel_suffix = "Desura"
+A_sourceid = "1300_A"
+A_viewer_channel_suffix = "A"
 B_sourceid = "1301_B"
 B_viewer_channel_suffix = "B"
 C_sourceid = "1302_C"
diff --git a/build.sh b/build.sh
index ccc8476ceafb0e4c3edc5ea12692a1712211b647..1fd2cd802be4eda94fcf1b359eddf3a247b8d64b 100755
--- a/build.sh
+++ b/build.sh
@@ -36,24 +36,59 @@ build_dir_CYGWIN()
   echo build-vc100
 }
 
+viewer_channel_suffix()
+{
+    local package_name="$1"
+    local suffix_var="${package_name}_viewer_channel_suffix"
+    local suffix=$(eval "echo \$${suffix_var}")
+    if [ "$suffix"x = ""x ]
+    then
+        echo ""
+    else
+        echo "_$suffix"
+    fi
+}
+
 installer_Darwin()
 {
-  ls -1tr "$(build_dir_Darwin ${last_built_variant:-Release})/newview/"*"$additional_package_name"*.dmg 2>/dev/null | sed 1q
+  local package_name="$1"
+  local package_dir="$(build_dir_Darwin ${last_built_variant:-Release})/newview/"
+  local pattern=".*$(viewer_channel_suffix ${package_name})_[0-9]+_[0-9]+_[0-9]+_[0-9]+_i386\\.dmg\$"
+  # since the additional packages are built after the base package,
+  # sorting oldest first ensures that the unqualified package is returned
+  # even if someone makes a qualified name that duplicates the last word of the base name
+  local package=$(ls -1tr "$package_dir" 2>/dev/null | grep -E "$pattern" | head -n 1)
+  test "$package"x != ""x && echo "$package_dir/$package"
 }
 
 installer_Linux()
 {
-  ls -1tr "$(build_dir_Linux ${last_built_variant:-Release})/newview/"*"$additional_package_name"*.tar.bz2 2>/dev/null | grep -v symbols | sed 1q
+  local package_name="$1"
+  local package_dir="$(build_dir_Linux ${last_built_variant:-Release})/newview/"
+  local pattern=".*$(viewer_channel_suffix ${package_name})_[0-9]+_[0-9]+_[0-9]+_[0-9]+_i686\\.tar\\.bz2\$"
+  # since the additional packages are built after the base package,
+  # sorting oldest first ensures that the unqualified package is returned
+  # even if someone makes a qualified name that duplicates the last word of the base name
+  package=$(ls -1tr "$package_dir" 2>/dev/null | grep -E "$pattern" | head -n 1)
+  test "$package"x != ""x && echo "$package_dir/$package"
 }
 
 installer_CYGWIN()
 {
-  v=${last_built_variant:-Release}
-  d=$(build_dir_CYGWIN $v)
-  if [ -r "$d/newview/$additional_package_name$v/touched.bat" ]
+  local package_name="$1"
+  local variant=${last_built_variant:-Release}
+  local build_dir=$(build_dir_CYGWIN ${variant})
+  local package_dir
+  if [ "$package_name"x = ""x ]
+  then
+      package_dir="${build_dir}/newview/${variant}"
+  else
+      package_dir="${build_dir}/newview/${package_name}/${variant}"
+  fi
+  if [ -r "${package_dir}/touched.bat" ]
   then
-    p=$(sed 's:.*=::' "$d/newview/$additional_package_name$v/touched.bat")
-    echo "$d/newview/$additional_package_name$v/$p"
+    local package_file=$(sed 's:.*=::' "${package_dir}/touched.bat")
+    echo "${package_dir}/${package_file}"
   fi
 }
 
@@ -275,7 +310,7 @@ then
     if $build_viewer_deb && [ "$last_built_variant" == "Release" ]
     then
       begin_section "Build Viewer Debian Package"
-      local have_private_repo=false
+      have_private_repo=false
       # mangle the changelog
       dch --force-bad-version \
           --distribution unstable \
@@ -362,19 +397,14 @@ then
       # Upload additional packages.
       for package_id in $additional_packages
       do
-        case $arch in
-        CYGWIN) export additional_package_name="$package_id/" ;;
-        *) export additional_package_name=$package_id ;;
-        esac
-        package=$(installer_$arch)
+        package=$(installer_$arch "$package_id")
         if [ x"$package" != x ]
         then
           upload_item installer "$package" binary/octet-stream
         else
-          record_failure "Failed to upload $package_id package ($package::$additional_package_name)."
+          record_failure "Failed to find additional package for '$package_id'."
         fi
       done
-      export additional_package_name=""
 
       case "$last_built_variant" in
       Release)
diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt
index 3609cf77078c22803a5732ba2871c3414b95d826..f5c2a4050b3e55a479221e4cd85cab830dc098fe 100644
--- a/indra/newview/VIEWER_VERSION.txt
+++ b/indra/newview/VIEWER_VERSION.txt
@@ -1 +1 @@
-3.6.13
+3.6.14
diff --git a/indra/newview/installers/windows/installer_template.nsi b/indra/newview/installers/windows/installer_template.nsi
index dd316cdbdf420ca77d9947d5baa8fd9d10a7c8c0..c4f503ef4e2daaf1bbad96e716874edab9bbaaa7 100755
--- a/indra/newview/installers/windows/installer_template.nsi
+++ b/indra/newview/installers/windows/installer_template.nsi
@@ -301,6 +301,23 @@ Function CheckNetworkConnection
     Return
 FunctionEnd
 
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; Function CheckOldExeName
+; Viewer versions < 3.6.12 used the name 'SecondLife.exe'
+; If that name is found in the install folder, delete it to invalidate any
+; old shortcuts to it that may be in non-standard locations, so that the user
+; does not end up running the old version (potentially getting caught in an 
+; infinite update loop). See MAINT-3575
+; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+Function CheckOldExeName
+  IfFileExists "$INSTDIR\SecondLife.exe" CHECKOLDEXE_FOUND CHECKOLDEXE_DONE
+
+CHECKOLDEXE_FOUND:
+  Delete "$INSTDIR\SecondLife.exe"
+CHECKOLDEXE_DONE:
+FunctionEnd
+
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ; Function CheckWillUninstallV2               
@@ -673,6 +690,9 @@ Delete "$INSTDIR\*.glsl"
 Delete "$INSTDIR\motions\*.lla"
 Delete "$INSTDIR\trial\*.html"
 Delete "$INSTDIR\newview.exe"
+Delete "$INSTDIR\SecondLife.exe"
+;; MAINT-3099 workaround - prevent these log files, if present, from causing a user alert
+Delete "$INSTDIR\VivoxVoiceService-*.log"
 ;; Remove entire help directory
 Delete "$INSTDIR\help\Advanced\*"
 RMDir  "$INSTDIR\help\Advanced"
@@ -920,6 +940,7 @@ Call CheckIfAlreadyCurrent		; Make sure that we haven't already installed this v
 Call CloseSecondLife			; Make sure we're not running
 Call CheckNetworkConnection		; ping secondlife.com
 Call CheckWillUninstallV2               ; See if a V2 install exists and will be removed.
+Call CheckOldExeName                    ; Clean up a previous version of the exe
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 StrCmp $DO_UNINSTALL_V2 "" PRESERVE_DONE
diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index 9e8623c1f9c12910a6eff8c81ea8bdde5bb8c09f..9a617c2a138ce4acbf7b37085ed731846d0a0fe9 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -136,13 +136,11 @@ def construct(self):
                     settings_install['CmdLineGridChoice']['Value'] = self.grid()
                     print "Set CmdLineGridChoice in settings_install.xml to '%s'" % self.grid()
 
-                # did we actually copy anything into settings_install dict?
-                if settings_install:
-                    # put_in_file(src=) need not be an actual pathname; it
-                    # only needs to be non-empty
-                    self.put_in_file(llsd.format_pretty_xml(settings_install),
-                                     "settings_install.xml",
-                                     src="environment")
+                # put_in_file(src=) need not be an actual pathname; it
+                # only needs to be non-empty
+                self.put_in_file(llsd.format_pretty_xml(settings_install),
+                                 "settings_install.xml",
+                                 src="environment")
 
                 self.end_prefix("app_settings")