diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 05483c460882c5e186ee21752c50e5bff5f2fb1b..3056b5d74962ba57cbe92fe275970d63be2abbdf 100755
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -2051,6 +2051,8 @@ endif (LINUX)
 if (DARWIN)
   # These all get set with PROPERTIES
   set(product "Second Life")
+  # this is the setting for the Python wrapper, see SL-322 and WRAPPER line in Info-SecondLife.plist
+  set(MACOSX_WRAPPER_EXECUTABLE_NAME "SL_Launcher")
   set(MACOSX_BUNDLE_INFO_STRING "Second Life Viewer")
   set(MACOSX_BUNDLE_ICON_FILE "secondlife.icns")
   set(MACOSX_BUNDLE_GUI_IDENTIFIER "com.secondlife.indra.viewer")
diff --git a/indra/newview/Info-SecondLife.plist b/indra/newview/Info-SecondLife.plist
index 9b8136a827e0d209778572c3faefe84ad2b46faf..8aabd6818b5028ae674999f304ff81053c71fef8 100755
--- a/indra/newview/Info-SecondLife.plist
+++ b/indra/newview/Info-SecondLife.plist
@@ -5,7 +5,7 @@
 	<key>CFBundleDevelopmentRegion</key>
 	<string>English</string>
 	<key>CFBundleExecutable</key>
-	<string>${MACOSX_BUNDLE_EXECUTABLE_NAME}</string>
+	<string>${MACOSX_WRAPPER_EXECUTABLE_NAME}</string>
 	<key>CFBundleGetInfoString</key>
 	<string>${MACOSX_BUNDLE_INFO_STRING}</string>
 	<key>CFBundleIconFile</key>
diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index f7992dba9033dd3ddadf40c9aab34cad5c28db36..60042706e4d79c119506ff88aca681d867008fef 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -703,6 +703,8 @@ def construct(self):
 
             if self.prefix(dst="MacOS"):
                 self.path2basename("../viewer_components/updater/scripts/darwin", "*.py")
+                #this copies over the python wrapper script, see SL-322
+                self.path2basename("../viewer_components/manager","SL_Launcher")
                 self.end_prefix()
 
             # most everything goes in the Resources directory
@@ -885,12 +887,6 @@ def path_optional(src, dst):
             self.run_command('strip -S %(viewer_binary)r' %
                              { 'viewer_binary' : self.dst_path_of('Contents/MacOS/Second Life')})
 
-    def copy_finish(self):
-        # Force executable permissions to be set for scripts
-        # see CHOP-223 and http://mercurial.selenic.com/bts/issue1802
-        for script in 'Contents/MacOS/update_install.py',:
-            self.run_command("chmod +x %r" % os.path.join(self.get_dst_prefix(), script))
-
     def package_finish(self):
         global CHANNEL_VENDOR_BASE
         # MBW -- If the mounted volume name changes, it breaks the .DS_Store's background image and icon positioning.
@@ -1091,12 +1087,6 @@ def construct(self):
 
         self.path("featuretable_linux.txt")
 
-    def copy_finish(self):
-        # Force executable permissions to be set for scripts
-        # see CHOP-223 and http://mercurial.selenic.com/bts/issue1802
-        for script in 'secondlife', 'bin/update_install':
-            self.run_command("chmod +x %r" % os.path.join(self.get_dst_prefix(), script))
-
     def package_finish(self):
         installer_name = self.installer_base_name()
 
diff --git a/indra/viewer_components/manager/SL_Launcher b/indra/viewer_components/manager/SL_Launcher
new file mode 100755
index 0000000000000000000000000000000000000000..3c5d45d6e56c9866f65645e9661996bfdf846f34
--- /dev/null
+++ b/indra/viewer_components/manager/SL_Launcher
@@ -0,0 +1,41 @@
+#!/usr/bin/env python
+
+# $LicenseInfo:firstyear=2016&license=internal$
+# 
+# Copyright (c) 2016, Linden Research, Inc.
+# 
+# The following source code is PROPRIETARY AND CONFIDENTIAL. Use of
+# this source code is governed by the Linden Lab Source Code Disclosure
+# Agreement ("Agreement") previously entered between you and Linden
+# Lab. By accessing, using, copying, modifying or distributing this
+# software, you acknowledge that you have been informed of your
+# obligations under the Agreement and agree to abide by those obligations.
+# 
+# ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+# WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+# COMPLETENESS OR PERFORMANCE.
+# $/LicenseInfo$
+
+import argparse
+import os
+import sys
+import subprocess
+import Tkinter as tk 
+
+viewer_binary = os.path.join(os.path.dirname(os.path.abspath(sys.argv[0])),"Second Life") 
+
+#to prove we are launching from the script, launch a Tkinter window first
+root = tk.Tk()
+w = tk.Label(root, text=viewer_binary)
+w.pack()
+root.after(10000, lambda: root.destroy()) # Destroy the widget after 10 seconds
+root.mainloop()
+
+parser = argparse.ArgumentParser()
+#parser.add_argument('--f', action='store_const', const=42)
+args = parser.parse_known_args(sys.argv)
+args_list_to_pass = args[1][1:]
+args_list_to_pass.insert(0,viewer_binary)
+#print args_list_to_pass
+
+viewer_process = subprocess.Popen(args_list_to_pass)
\ No newline at end of file