diff --git a/doc/contributions.txt b/doc/contributions.txt
index 2b39e15e2a9cf0635d08011a0d993a61eab2ac21..9daef4035a0726350ccd2c55ea8cdf2302d03b2e 100644
--- a/doc/contributions.txt
+++ b/doc/contributions.txt
@@ -482,6 +482,7 @@ Ima Mechanique
 	OPEN-76
 	STORM-959
 	STORM-1175
+	STORM-1708
 Imnotgoing Sideways
 Inma Rau
 Innula Zenovka
diff --git a/indra/newview/llfilepicker.cpp b/indra/newview/llfilepicker.cpp
index 4897cf18859602201274e9f328231f2bb4d40bd0..0801871409fa0fe7e517010228eef85c2a2e277a 100644
--- a/indra/newview/llfilepicker.cpp
+++ b/indra/newview/llfilepicker.cpp
@@ -58,6 +58,7 @@ LLFilePicker LLFilePicker::sInstance;
 #define SLOBJECT_FILTER L"Objects (*.slobject)\0*.slobject\0"
 #define RAW_FILTER L"RAW files (*.raw)\0*.raw\0"
 #define MODEL_FILTER L"Model files (*.dae)\0*.dae\0"
+#define SCRIPT_FILTER L"Script files (*.lsl; *.txt)\0*.lsl;*.txt\0"
 #endif
 
 //
@@ -213,6 +214,10 @@ BOOL LLFilePicker::setupFilter(ELoadFilter filter)
 		mOFN.lpstrFilter = MODEL_FILTER \
 			L"\0";
 		break;
+	case FFLOAD_SCRIPT:
+		mOFN.lpstrFilter = SCRIPT_FILTER \
+			L"\0";
+		break;
 	default:
 		res = FALSE;
 		break;
@@ -497,6 +502,16 @@ BOOL LLFilePicker::getSaveFile(ESaveFilter filter, const std::string& filename)
 			L"Compressed Images (*.j2c)\0*.j2c\0" \
 			L"\0";
 		break;
+	case FFSAVE_SCRIPT:
+		if (filename.empty())
+		{
+			wcsncpy( mFilesW,L"untitled.lsl", FILENAME_BUFFER_SIZE);
+		}
+		mOFN.lpstrDefExt = L"txt";
+		mOFN.lpstrFilter = 
+			L"LSL Files (*.lsl; *.txt)\0*.lsl;*.txt\0"
+			L"\0";
+		break;
 	default:
 		return FALSE;
 	}
diff --git a/indra/newview/llfilepicker.h b/indra/newview/llfilepicker.h
index cd843a8f33f322e5cf3a50f44c4eea49fdf22f79..a4d5d68ff58f51ddb93b15266de9856e5eaf492e 100644
--- a/indra/newview/llfilepicker.h
+++ b/indra/newview/llfilepicker.h
@@ -84,6 +84,7 @@ class LLFilePicker
 		FFLOAD_RAW = 8,
 		FFLOAD_MODEL = 9,
 		FFLOAD_COLLADA = 10,
+		FFLOAD_SCRIPT = 11,
 	};
 
 	enum ESaveFilter
@@ -103,6 +104,7 @@ class LLFilePicker
 		FFSAVE_J2C = 12,
 		FFSAVE_PNG = 13,
 		FFSAVE_JPEG = 14,
+		FFSAVE_SCRIPT = 15,
 	};
 
 	// open the dialog. This is a modal operation
diff --git a/indra/newview/llfloaternamedesc.cpp b/indra/newview/llfloaternamedesc.cpp
index ae95d4392accfcd2641fd5c23d3a216ab416bc90..4d4f9f57bf2e6c7474ac5d08e4b8aa15dd17738b 100644
--- a/indra/newview/llfloaternamedesc.cpp
+++ b/indra/newview/llfloaternamedesc.cpp
@@ -204,3 +204,24 @@ BOOL LLFloaterSoundPreview::postBuild()
 	getChild<LLUICtrl>("ok_btn")->setCommitCallback(boost::bind(&LLFloaterNameDesc::onBtnOK, this));
 	return TRUE;
 }
+
+
+//-----------------------------------------------------------------------------
+// LLFloaterScriptPreview()
+//-----------------------------------------------------------------------------
+
+LLFloaterScriptPreview::LLFloaterScriptPreview(const LLSD& filename )
+	: LLFloaterNameDesc(filename)
+{
+	mIsAudio = TRUE;
+}
+
+BOOL LLFloaterScriptPreview::postBuild()
+{
+	if (!LLFloaterNameDesc::postBuild())
+	{
+		return FALSE;
+	}
+	getChild<LLUICtrl>("ok_btn")->setCommitCallback(boost::bind(&LLFloaterNameDesc::onBtnOK, this));
+	return TRUE;
+}
diff --git a/indra/newview/llfloaternamedesc.h b/indra/newview/llfloaternamedesc.h
index 7381a6334a993867bdd1eade9f3b2dcb7edb141c..69bbccaf8047762f01a3ab5162e5ecc39d560d75 100644
--- a/indra/newview/llfloaternamedesc.h
+++ b/indra/newview/llfloaternamedesc.h
@@ -51,6 +51,7 @@ class LLFloaterNameDesc : public LLFloater
 
 protected:
 	BOOL        mIsAudio;
+	bool		mIsText;
 
 	std::string		mFilenameAndPath;
 	std::string		mFilename;
@@ -62,5 +63,12 @@ class LLFloaterSoundPreview : public LLFloaterNameDesc
 	LLFloaterSoundPreview(const LLSD& filename );
 	virtual BOOL postBuild();
 };
-	
+
+class LLFloaterScriptPreview : public LLFloaterNameDesc
+{
+public:
+	LLFloaterScriptPreview(const LLSD& filename );
+	virtual BOOL postBuild();
+};
+
 #endif  // LL_LLFLOATERNAMEDESC_H
diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp
index b19bf5d234c36544e12aee92ac14709ccc038add..072df39514b8fac29edf9c9f982d9b54ada81efb 100644
--- a/indra/newview/llpreviewscript.cpp
+++ b/indra/newview/llpreviewscript.cpp
@@ -35,6 +35,7 @@
 #include "llcombobox.h"
 #include "lldir.h"
 #include "llexternaleditor.h"
+#include "llfilepicker.h"
 #include "llfloaterreg.h"
 #include "llinventorydefines.h"
 #include "llinventorymodel.h"
@@ -89,15 +90,15 @@
 const std::string HELLO_LSL =
 	"default\n"
 	"{\n"
-	"    state_entry()\n"
-    "    {\n"
-    "        llSay(0, \"Hello, Avatar!\");\n"
-    "    }\n"
+	"\tstate_entry()\n"
+    "\t{\n"
+    "\t\tllOwnerSay(\"Hello, Avatar!\");\n"
+    "\t}\n"
 	"\n"
-	"    touch_start(integer total_number)\n"
-	"    {\n"
-	"        llSay(0, \"Touched.\");\n"
-	"    }\n"
+	"\ttouch_start(integer total_number)\n"
+	"\t{\n"
+	"\t\tllSay(llDetectedKey(0), \"Touched.\");\n"
+	"\t}\n"
 	"}\n";
 const std::string HELP_LSL_PORTAL_TOPIC = "LSL_Portal";
 
@@ -503,6 +504,14 @@ void LLScriptEdCore::initMenu()
 
 	menuItem = getChild<LLMenuItemCallGL>("Keyword Help...");
 	menuItem->setClickCallback(boost::bind(&LLScriptEdCore::onBtnDynamicHelp, this));
+
+	menuItem = getChild<LLMenuItemCallGL>("LoadFromFile");
+	menuItem->setClickCallback(boost::bind(&LLScriptEdCore::onBtnLoadFromFile, this));
+//	menuItem->setEnabledCallback(NULL);
+
+	menuItem = getChild<LLMenuItemCallGL>("SaveToFile");
+	menuItem->setClickCallback(boost::bind(&LLScriptEdCore::onBtnSaveToFile, this));
+	menuItem->setEnableCallback(boost::bind(&LLScriptEdCore::hasChanged, this));
 }
 
 void LLScriptEdCore::setScriptText(const std::string& text, BOOL is_valid)
@@ -1096,6 +1105,59 @@ BOOL LLScriptEdCore::handleKeyHere(KEY key, MASK mask)
 	return FALSE;
 }
 
+void LLScriptEdCore::onBtnLoadFromFile( void* data )
+{
+
+	LLScriptEdCore* self = (LLScriptEdCore*) data;
+	
+	LLFilePicker& file_picker = LLFilePicker::instance();
+	if( !file_picker.getOpenFile( LLFilePicker::FFLOAD_SCRIPT ) )
+	{
+		return;
+	}
+
+	std::string filename = file_picker.getFirstFile();
+
+	std::ifstream fin(filename.c_str());
+
+	std::string line;
+	std::string linetotal;
+	self->mEditor->clear();
+	while (!fin.eof())
+	{ 
+		getline(fin,line);
+		line=line+"\n";
+		self->mEditor->insertText(line);
+
+	}
+	fin.close();
+}
+
+void LLScriptEdCore::onBtnSaveToFile( void* userdata )
+{
+
+	LLViewerStats::getInstance()->incStat( LLViewerStats::ST_LSL_SAVE_COUNT );
+
+	LLScriptEdCore* self = (LLScriptEdCore*) userdata;
+
+	if( self->mSaveCallback )
+	{
+		LLFilePicker& file_picker = LLFilePicker::instance();
+		if( !file_picker.getSaveFile( LLFilePicker::FFSAVE_SCRIPT ) )
+		{
+			return;
+		}
+
+		std::string filename = file_picker.getFirstFile();
+		std::string scriptText=self->mEditor->getText();
+		std::ofstream fout(filename.c_str());
+		fout<<(scriptText);
+		fout.close();
+		self->mSaveCallback( self->mUserdata, FALSE );
+	}
+}
+
+
 /// ---------------------------------------------------------------------------
 /// LLScriptEdContainer
 /// ---------------------------------------------------------------------------
diff --git a/indra/newview/llpreviewscript.h b/indra/newview/llpreviewscript.h
index f86be615c44ce396f69d295b7480ae545aeadf13..f50e9322b061510a86686312a190759db295da3f 100644
--- a/indra/newview/llpreviewscript.h
+++ b/indra/newview/llpreviewscript.h
@@ -98,6 +98,8 @@ class LLScriptEdCore : public LLPanel
 	static void		onClickForward(void* userdata);
 	static void		onBtnInsertSample(void*);
 	static void		onBtnInsertFunction(LLUICtrl*, void*);
+	static void		onBtnLoadFromFile(void*);
+	static void		onBtnSaveToFile(void*);
 
 	virtual bool	hasAccelerators() const { return true; }
 
diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index 273bf822bcf532c109503b87a1f3b8fd3888c10f..56c79f5b9f42c07062aed8f29254ec5a24c0a26d 100644
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -292,9 +292,10 @@ void LLViewerFloaterReg::registerFloaters()
 	LLFloaterUIPreviewUtil::registerFloater();
 	LLFloaterReg::add("upload_anim", "floater_animation_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterAnimPreview>, "upload");
 	LLFloaterReg::add("upload_image", "floater_image_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterImagePreview>, "upload");
-	LLFloaterReg::add("upload_sound", "floater_sound_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSoundPreview>, "upload");
 	LLFloaterReg::add("upload_model", "floater_model_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterModelPreview>, "upload");
 	LLFloaterReg::add("upload_model_wizard", "floater_model_wizard.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterModelWizard>);
+	LLFloaterReg::add("upload_script", "floater_script_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterScriptPreview>, "upload");
+	LLFloaterReg::add("upload_sound", "floater_sound_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSoundPreview>, "upload");
 
 	LLFloaterReg::add("voice_controls", "floater_voice_controls.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLCallFloater>);
 	LLFloaterReg::add("voice_effect", "floater_voice_effect.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterVoiceEffect>);
diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp
index 7e830e14bf2b0d8ea5d4b9ea10003dc58e334478..f23d0f6b72efe6479d5711caea8a5ada01b9c436 100644
--- a/indra/newview/llviewermenufile.cpp
+++ b/indra/newview/llviewermenufile.cpp
@@ -87,6 +87,14 @@ class LLFileEnableUpload : public view_listener_t
 	}
 };
 
+class LLFileEnableUploadScript : public view_listener_t
+{
+	bool handleEvent(const LLSD& userdata)
+	{
+		return true;
+	}
+};
+
 class LLFileEnableUploadModel : public view_listener_t
 {
 	bool handleEvent(const LLSD& userdata)
@@ -391,6 +399,20 @@ class LLFileUploadAnim : public view_listener_t
 	}
 };
 
+class LLFileUploadScript : public view_listener_t
+{
+	bool handleEvent(const LLSD& userdata)
+	{
+		const std::string filename = upload_pick((void*)LLFilePicker::FFLOAD_SCRIPT);
+		if (!filename.empty())
+		{
+			LLFloaterReg::showInstance("upload_script", LLSD(filename));
+		}
+
+		return true;
+	}
+};
+
 class LLFileUploadBulk : public view_listener_t
 {
 	bool handleEvent(const LLSD& userdata)
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index 263d961be1fff1efe8ea5a909de847989920338c..b9605e1edec016f72db8645d2b654e6278afe523 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -1101,7 +1101,20 @@
             <menu_item_call.on_visible
             function="File.VisibleUploadModel"/>
             </menu_item_call>
-	   <menu_item_call
+          <menu_item_call
+           label="Script (L$ 0)..."
+           layout="topleft"
+           name="Upload Script">
+            <menu_item_call.on_click
+             function="File.UploadScript"
+             parameter="" />
+            <menu_item_call.on_enable
+             function="File.EnableUploadScript" />
+            <!--menu_item_call.on_visible
+             function="Upload.CalculateCosts"
+             parameter="Upload Script" /-->
+          </menu_item_call>
+          <menu_item_call
              label="Bulk (L$[COST] per file)..."
              layout="topleft"
              name="Bulk Upload">
diff --git a/indra/newview/skins/default/xui/en/panel_script_ed.xml b/indra/newview/skins/default/xui/en/panel_script_ed.xml
index 8d420243864c56e4cda3fa1d0f53e2b7ad2e00d1..f6a8af097355f99a354ba45868823b708b595416 100644
--- a/indra/newview/skins/default/xui/en/panel_script_ed.xml
+++ b/indra/newview/skins/default/xui/en/panel_script_ed.xml
@@ -54,12 +54,22 @@
              label="Save"
              layout="topleft"
              name="Save" />
-            <menu_item_separator
-             layout="topleft" />
-            <menu_item_call
-             label="Revert All Changes"
-             layout="topleft"
-             name="Revert All Changes" />
+          <menu_item_separator
+           layout="topleft" />
+          <menu_item_call
+           label="Revert All Changes"
+           layout="topleft"
+           name="Revert All Changes" />
+          <menu_item_separator
+           layout="topleft" />
+          <menu_item_call
+           label="Load from file..."
+           layout="topleft"
+           name="LoadFromFile" />
+          <menu_item_call
+           label="Save to file..."
+           layout="topleft"
+           name="SaveToFile" />
         </menu>
         <menu
          top="0"