diff --git a/BuildParams b/BuildParams
index 327530934d288942111ea437cda3ef7acb3c05d5..63812d33c1defc7f2474f3f50649d55dd5610323 100755
--- a/BuildParams
+++ b/BuildParams
@@ -26,8 +26,13 @@ codeticket_since = 3.3.0-release
 Linux.gcc_version = /usr/bin/gcc-4.6
 Linux.cxx_version = /usr/bin/g++-4.6
 
-# Setup default sourceid so Windows can pick up the TeamCity override
+# Setup default packaging parameters.
 sourceid = ""
+additional_packages = "Amazon Desura"
+Amazon_sourceid = "1207v_Amazon"
+Amazon_viewer_channel_suffix = " Amazon"
+Desura_sourceid = "1208_desura"
+Desura_viewer_channel_suffix = " Desura"
 
 ################################################################
 ####      Examples of how to set the viewer_channel         ####
diff --git a/build.sh b/build.sh
index a78f368e475aa9a52c1aa42ade842ff093fa29c4..4875ef39f770d5259cc25f998ea5d3c424769963 100755
--- a/build.sh
+++ b/build.sh
@@ -38,22 +38,22 @@ build_dir_CYGWIN()
 
 installer_Darwin()
 {
-  ls -1td "$(build_dir_Darwin ${last_built_variant:-Release})/newview/"*.dmg 2>/dev/null | sed 1q
+  ls -1tr "$(build_dir_Darwin ${last_built_variant:-Release})/newview/"*"$additional_package_name"*.dmg 2>/dev/null | sed 1q
 }
 
 installer_Linux()
 {
-  ls -1td "$(build_dir_Linux ${last_built_variant:-Release})/newview/"*.tar.bz2 2>/dev/null | sed 1q
+  ls -1tr "$(build_dir_Linux ${last_built_variant:-Release})/newview/"*"$additional_package_name"*.tar.bz2 2>/dev/null | grep -v symbols | sed 1q
 }
 
 installer_CYGWIN()
 {
   v=${last_built_variant:-Release}
   d=$(build_dir_CYGWIN $v)
-  if [ -r "$d/newview/$v/touched.bat" ]
+  if [ -r "$d/newview/$additional_package_name$v/touched.bat" ]
   then
-    p=$(sed 's:.*=::' "$d/newview/$v/touched.bat")
-    echo "$d/newview/$v/$p"
+    p=$(sed 's:.*=::' "$d/newview/$additional_package_name$v/touched.bat")
+    echo "$d/newview/$additional_package_name$v/$p"
   fi
 }
 
@@ -355,10 +355,28 @@ then
       # Coverity doesn't package, so it's ok, anything else is fail
       succeeded=$build_coverity
     else
+      # Upload base package.
       upload_item installer "$package" binary/octet-stream
       upload_item quicklink "$package" binary/octet-stream
       [ -f $build_dir/summary.json ] && upload_item installer $build_dir/summary.json text/plain
 
+      # 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)
+        if [ x"$package" != x ]
+        then
+          upload_item installer "$package" binary/octet-stream
+        else
+          record_failure "Failed to upload $package_id package."
+        fi
+      done
+      export additional_package_name=""
+
       case "$last_built_variant" in
       Release)
         # Upload crash reporter files
diff --git a/indra/lib/python/indra/util/llmanifest.py b/indra/lib/python/indra/util/llmanifest.py
index 54049b5545bf8ef9dae8321b5ded922b7240228a..52b4acbc94dd8974e3bf2c721e1e2e60f13c33cc 100755
--- a/indra/lib/python/indra/util/llmanifest.py
+++ b/indra/lib/python/indra/util/llmanifest.py
@@ -224,15 +224,98 @@ def main():
     for opt in args:
         print "Option:", opt, "=", args[opt]
 
+    # pass in sourceid as an argument now instead of an environment variable
+    try:
+        args['sourceid'] = os.environ["sourceid"]
+    except KeyError:
+        args['sourceid'] = ""
+
+    # Build base package.
+    touch = args.get('touch')
+    if touch:
+        print 'Creating base package'
+    args['package_id'] = "" # base package has no package ID
     wm = LLManifest.for_platform(args['platform'], args.get('arch'))(args)
     wm.do(*args['actions'])
-
+    # Store package file for later if making touched file.
+    base_package_file = ""
+    if touch:
+        print 'Created base package ', wm.package_file
+        base_package_file = "" + wm.package_file
+
+    # handle multiple packages if set
+    try:
+        additional_packages = os.environ["additional_packages"]
+    except KeyError:
+        additional_packages = ""
+    if additional_packages:
+        # Determine destination prefix / suffix for additional packages.
+        base_dest_postfix = args['dest']
+        base_dest_prefix = ""
+        base_dest_parts = args['dest'].split(os.sep)
+        if len(base_dest_parts) > 1:
+            base_dest_postfix = base_dest_parts[len(base_dest_parts) - 1]
+            base_dest_prefix = base_dest_parts[0]
+            i = 1
+            while i < len(base_dest_parts) - 1:
+                base_dest_prefix = base_dest_prefix + os.sep + base_dest_parts[i]
+                i = i + 1
+        # Determine touched prefix / suffix for additional packages.
+        base_touch_postfix = ""
+        base_touch_prefix = ""
+        if touch:
+            base_touch_postfix = touch
+            base_touch_parts = touch.split('/')
+            if "arwin" in args['platform']:
+                if len(base_touch_parts) > 1:
+                    base_touch_postfix = base_touch_parts[len(base_touch_parts) - 1]
+                    base_touch_prefix = base_touch_parts[0]
+                    i = 1
+                    while i < len(base_touch_parts) - 1:
+                        base_touch_prefix = base_touch_prefix + '/' + base_touch_parts[i]
+                        i = i + 1
+            else:
+                if len(base_touch_parts) > 2:
+                    base_touch_postfix = base_touch_parts[len(base_touch_parts) - 2] + '/' + base_touch_parts[len(base_touch_parts) - 1]
+                    base_touch_prefix = base_touch_parts[0]
+                    i = 1
+                    while i < len(base_touch_parts) - 2:
+                        base_touch_prefix = base_touch_prefix + '/' + base_touch_parts[i]
+                        i = i + 1
+        # Store base channel name.
+        base_channel_name = args['channel']
+        # Build each additional package.
+        package_id_list = additional_packages.split(" ")
+        for package_id in package_id_list:
+            try:
+                args['package_id'] = package_id
+                args['channel'] = base_channel_name + os.environ[package_id + "_viewer_channel_suffix"]
+                if package_id + "_sourceid" in os.environ:
+                    args['sourceid'] = os.environ[package_id + "_sourceid"]
+                else:
+                    args['sourceid'] = ""
+                args['dest'] = base_dest_prefix + os.sep + package_id + os.sep + base_dest_postfix
+            except KeyError:
+                sys.stderr.write("Failed to create package for package_id: %s" % package_id)
+                sys.stderr.flush()
+                continue
+            if touch:
+                print 'Creating additional package for ', package_id, ' in ', args['dest']
+            wm = LLManifest.for_platform(args['platform'], args.get('arch'))(args)
+            wm.do(*args['actions'])
+            if touch:
+                print 'Created additional package ', wm.package_file, ' for ', package_id
+                faketouch = base_touch_prefix + '/' + package_id + '/' + base_touch_postfix
+                fp = open(faketouch, 'w')
+                fp.write('set package_file=%s\n' % wm.package_file)
+                fp.close()
+    
     # Write out the package file in this format, so that it can easily be called
     # and used in a .bat file - yeah, it sucks, but this is the simplest...
     touch = args.get('touch')
     if touch:
         fp = open(touch, 'w')
-        fp.write('set package_file=%s\n' % wm.package_file)
+        fp.write('set package_file=%s\n' % base_package_file)
         fp.close()
         print 'touched', touch
     return 0
diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index 19863dd84548f7eb077899f97dfb55a2fdcaeb7a..effe3994a38cf362c514c7b08e79bbabf1a7e52e 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -106,24 +106,18 @@ def construct(self):
 
                 # CHOP-955: If we have "sourceid" in the build process
                 # environment, generate it into settings_install.xml.
-                try:
-                    sourceid = os.environ["sourceid"]
-                except KeyError:
-                    # no sourceid, no settings_install.xml file
-                    pass
-                else:
-                    if sourceid:
-                        # Single-entry subset of the LLSD content of settings.xml
-                        content = dict(sourceid=dict(Comment='Identify referring agency to Linden web servers',
-                                                     Persist=1,
-                                                     Type='String',
-                                                     Value=sourceid))
-                        # put_in_file(src=) need not be an actual pathname; it
-                        # only needs to be non-empty
-                        settings_install = self.put_in_file(llsd.format_pretty_xml(content),
-                                                            "settings_install.xml",
-                                                            src="environment")
-                        print "Put sourceid '%s' in %s" % (sourceid, settings_install)
+                if self.args['sourceid']:
+                    # Single-entry subset of the LLSD content of settings.xml
+                    content = dict(sourceid=dict(Comment='Identify referring agency to Linden web servers',
+                                                 Persist=1,
+                                                 Type='String',
+                                                 Value=self.args['sourceid']))
+                    # put_in_file(src=) need not be an actual pathname; it
+                    # only needs to be non-empty
+                    settings_install = self.put_in_file(llsd.format_pretty_xml(content),
+                                                        "settings_install.xml",
+                                                        src="environment")
+                    print "Put sourceid '%s' in %s" % (self.args['sourceid'], settings_install)
 
                 self.end_prefix("app_settings")
 
@@ -611,6 +605,9 @@ def package_finish(self):
             installer_file = self.args['installer_name']
         else:
             installer_file = installer_file % substitution_strings
+        if len(self.args['package_id']) > 0:
+            installer_file = installer_file.replace(self.args['package_id'], "")
+            installer_file = installer_file.replace(".exe", self.args['package_id'] + ".exe")
         substitution_strings['installer_file'] = installer_file
 
         tempfile = "secondlife_setup_tmp.nsi"
@@ -838,7 +835,9 @@ def package_finish(self):
 
         volname="Second Life Installer"  # DO NOT CHANGE without understanding comment above
 
-        if self.default_channel():
+        if len(self.args['package_id']) > 0:
+            imagename = imagename + self.args['package_id']
+        elif self.default_channel():
             if not self.default_grid():
                 # beta case
                 imagename = imagename + '_' + self.args['grid'].upper()
@@ -851,7 +850,7 @@ def package_finish(self):
         # make sure we don't have stale files laying about
         self.remove(sparsename, finalname)
 
-        self.run_command('hdiutil create %(sparse)r -volname %(vol)r -fs HFS+ -type SPARSE -megabytes 700 -layout SPUD' % {
+        self.run_command('hdiutil create %(sparse)r -volname %(vol)r -fs HFS+ -type SPARSE -megabytes 1000 -layout SPUD' % {
                 'sparse':sparsename,
                 'vol':volname})
 
@@ -926,6 +925,7 @@ def package_finish(self):
 
         print "Converting temp disk image to final disk image"
         self.run_command('hdiutil convert %(sparse)r -format UDZO -imagekey zlib-level=9 -o %(final)r' % {'sparse':sparsename, 'final':finalname})
+        self.run_command('hdiutil internet-enable -yes %(final)r' % {'final':finalname})
         # get rid of the temp file
         self.package_file = finalname
         self.remove(sparsename)
@@ -998,6 +998,7 @@ def package_finish(self):
                     installer_name += '_' + self.args['grid'].upper()
             else:
                 installer_name += '_' + self.channel_oneword().upper()
+        installer_name = installer_name + self.args['package_id']
 
         self.strip_binaries()