diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index e8f4144e70dbc1b2ca70c4c23ab69e4a83f7949e..e95cbf391de7d64511b4e87769d28821298467ee 100755
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -490,6 +490,7 @@ set(viewer_SOURCE_FILES
     llplacesfolderview.cpp
     llpopupview.cpp
     llpostcard.cpp
+    llpresetsmanager.cpp
     llpreview.cpp
     llpreviewanim.cpp
     llpreviewgesture.cpp
@@ -1084,6 +1085,7 @@ set(viewer_HEADER_FILES
     llplacesfolderview.h
     llpopupview.h
     llpostcard.h
+    llpresetsmanager.h
     llpreview.h
     llpreviewanim.h
     llpreviewgesture.h
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index 3b64ffcf4c1f2151dd5fa1f0645ea21f44552d62..cea17aeef441ab2c00d52836fcb0577cbbb91fe1 100755
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -108,6 +108,7 @@
 
 #include "lllogininstance.h"        // to check if logged in yet
 #include "llsdserialize.h"
+#include "llpresetsmanager.h"
 
 const F32 MAX_USER_FAR_CLIP = 512.f;
 const F32 MIN_USER_FAR_CLIP = 64.f;
@@ -661,7 +662,7 @@ void LLFloaterPreference::cancel()
 
 void LLFloaterPreference::onOpen(const LLSD& key)
 {
-	
+
 	// this variable and if that follows it are used to properly handle do not disturb mode response message
 	static bool initialized = FALSE;
 	// if user is logged in and we haven't initialized do not disturb mode response yet, do it
@@ -739,6 +740,9 @@ void LLFloaterPreference::onOpen(const LLSD& key)
 	// when the floater is opened.  That will make cancel do its
 	// job
 	saveSettings();
+
+	// Make sure there is a default preference file
+
 }
 
 void LLFloaterPreference::onVertexShaderEnable()
@@ -1179,7 +1183,7 @@ void LLFloaterPreference::refreshEnabledState()
 
 	LLCheckBoxCtrl* ctrl_ssao = getChild<LLCheckBoxCtrl>("UseSSAO");
 	LLCheckBoxCtrl* ctrl_dof = getChild<LLCheckBoxCtrl>("UseDoF");
-	LLComboBox* ctrl_shadow = getChild<LLComboBox>("ShadowDetail");
+	LLUICtrl* ctrl_shadow = getChild<LLUICtrl>("ShadowDetail");
 
 	// note, okay here to get from ctrl_deferred as it's twin, ctrl_deferred2 will alway match it
 	enabled = enabled && LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferredSSAO") && (ctrl_deferred->get() ? TRUE : FALSE);
@@ -1213,7 +1217,7 @@ void LLFloaterPreference::disableUnavailableSettings()
 	LLCheckBoxCtrl* ctrl_avatar_impostors = getChild<LLCheckBoxCtrl>("AvatarImpostors");
 	LLCheckBoxCtrl* ctrl_deferred = getChild<LLCheckBoxCtrl>("UseLightShaders");
 	LLCheckBoxCtrl* ctrl_deferred2 = getChild<LLCheckBoxCtrl>("UseLightShaders2");
-	LLComboBox* ctrl_shadows = getChild<LLComboBox>("ShadowDetail");
+	LLUICtrl* ctrl_shadows = getChild<LLUICtrl>("ShadowDetail");
 	LLCheckBoxCtrl* ctrl_ssao = getChild<LLCheckBoxCtrl>("UseSSAO");
 	LLCheckBoxCtrl* ctrl_dof = getChild<LLCheckBoxCtrl>("UseDoF");
 
@@ -1372,7 +1376,7 @@ void LLFloaterPreference::refresh()
 	updateSliderText(getChild<LLSliderCtrl>("SkyMeshDetail",		true), getChild<LLTextBox>("SkyMeshDetailText",			true));
 	updateSliderText(getChild<LLSliderCtrl>("TerrainDetail",		true), getChild<LLTextBox>("TerrainDetailText",			true));	
 	updateReflectionsText(getChild<LLSliderCtrl>("Reflections",		true), getChild<LLTextBox>("ReflectionsText",			true));	
-	updateRenderShadowDetailText(getChild<LLSliderCtrl>("RenderShadowDetail",		true), getChild<LLTextBox>("RenderShadowDetailText",			true));	
+	updateShadowDetailText(getChild<LLSliderCtrl>("ShadowDetail",		true), getChild<LLTextBox>("RenderShadowDetailText",			true));	
 }
 
 void LLFloaterPreference::onCommitWindowedMode()
@@ -1632,7 +1636,7 @@ void LLFloaterPreference::updateReflectionsText(LLSliderCtrl* ctrl, LLTextBox* t
 	U32 value = (U32)ctrl->getValue().asInteger();
 	text_box->setText(getString("Reflections" + llformat("%d", value)));
 }
-void LLFloaterPreference::updateRenderShadowDetailText(LLSliderCtrl* ctrl, LLTextBox* text_box)
+void LLFloaterPreference::updateShadowDetailText(LLSliderCtrl* ctrl, LLTextBox* text_box)
 {
 	if (text_box == NULL || ctrl== NULL)
 		return;
@@ -2112,8 +2116,18 @@ BOOL LLPanelPreferenceGraphics::postBuild()
 	LLComboBox* graphic_preset = getChild<LLComboBox>("graphic_preset_combo");
 	graphic_preset->setLabel(getString("graphic_preset_combo_label"));
 
+	std::string presets_dir = LLPresetsManager::getGraphicPresetsDir();
+	if (!presets_dir.empty())
+	{
+		LLPresetsManager::getInstance()->getPresetsFromDir(presets_dir);
+	}
+	else {
+		LL_WARNS() << "Could not obtain graphic presets path" << LL_ENDL;
+	}
+
 	return LLPanelPreference::postBuild();
 }
+
 void LLPanelPreferenceGraphics::draw()
 {
 	LLPanelPreference::draw();
diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h
index 3ac5b2ad81032660e6a21a2f3c951802c8b7349e..1b42444c9e51ad17e2295613a734533db2c90fc0 100755
--- a/indra/newview/llfloaterpreference.h
+++ b/indra/newview/llfloaterpreference.h
@@ -158,7 +158,7 @@ class LLFloaterPreference : public LLFloater, public LLAvatarPropertiesObserver,
 	
 	void updateSliderText(LLSliderCtrl* ctrl, LLTextBox* text_box);
 	void updateReflectionsText(LLSliderCtrl* ctrl, LLTextBox* text_box);
-	void updateRenderShadowDetailText(LLSliderCtrl* ctrl, LLTextBox* text_box);
+	void updateShadowDetailText(LLSliderCtrl* ctrl, LLTextBox* text_box);
 	void refreshUI();
 
 	void onCommitParcelMediaAutoPlayEnable();
@@ -248,6 +248,7 @@ class LLPanelPreferenceGraphics : public LLPanelPreference
 	void cancel();
 	void saveSettings();
 	void setHardwareDefaults();
+	static const std::string getPresetsPath();
 protected:
 	bool hasDirtyChilds();
 	void resetDirtyChilds();
diff --git a/indra/newview/llpresetsmanager.cpp b/indra/newview/llpresetsmanager.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..6ebb111be19e71ae4d511a18d342e9dcc92fbe2a
--- /dev/null
+++ b/indra/newview/llpresetsmanager.cpp
@@ -0,0 +1,142 @@
+/**
+ * @file llpresetsmanager.cpp
+ * @brief Implementation for the LLPresetsManager class.
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llpresetsmanager.h"
+
+#include "lldiriterator.h"
+#include "lluictrlfactory.h"
+#include "llsdserialize.h"
+#include "llviewercontrol.h"
+
+static const std::string PRESETS_DIR = "presets";
+static const std::string GRAPHIC_DIR = "graphic";
+static const std::string CAMERA_DIR = "camera";
+
+LLPresetsManager::LLPresetsManager()
+{
+}
+
+LLPresetsManager::~LLPresetsManager()
+{
+}
+
+std::string LLPresetsManager::getUserDir(const std::string& subdirectory)
+{
+	std::string presets_path = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, PRESETS_DIR);
+	std::string full_path;
+
+	if (!gDirUtilp->fileExists(presets_path))
+	{
+		LLFile::mkdir(presets_path);
+
+		full_path = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, PRESETS_DIR, subdirectory);
+		if (!gDirUtilp->fileExists(full_path))
+		{
+			LLFile::mkdir(full_path);
+		}
+	}
+
+	return full_path;
+}
+
+std::string LLPresetsManager::getGraphicPresetsDir()
+{
+	return getUserDir(GRAPHIC_DIR);
+}
+
+void LLPresetsManager::getPresetsFromDir(const std::string& dir)
+{
+	LL_INFOS("AppInit") << "Loading presets from " << dir << LL_ENDL;
+
+	mPresetNames.clear();
+
+	LLDirIterator dir_iter(dir, "*.xml");
+	while (1)
+	{
+		std::string file;
+		if (!dir_iter.next(file))
+		{
+			break; // no more files
+		}
+
+		std::string path = gDirUtilp->add(dir, file);
+		std::string name(gDirUtilp->getBaseFileName(LLURI::unescape(path), /*strip_exten = */ true));
+		mPresetNames.push_back(name);
+llwarns << "DBG " << name << llendl;
+	}
+}
+
+void LLPresetsManager::savePreset(const std::string & name)
+{
+	llassert(!name.empty());
+
+	// make an empty llsd
+	LLSD paramsData(LLSD::emptyMap());
+	std::string pathName(getUserDir(GRAPHIC_DIR) + LLURI::escape(name) + ".xml");
+
+// Get all graphic settings
+//	paramsData = mParamList[name].getAll();
+
+	// write to file
+	llofstream presetsXML(pathName);
+	LLPointer<LLSDFormatter> formatter = new LLSDXMLFormatter();
+	formatter->format(paramsData, presetsXML, LLSDFormatter::OPTIONS_PRETTY);
+	presetsXML.close();
+}
+
+bool LLPresetsManager::removeParamSet(const std::string& name, bool delete_from_disk)
+{
+	// remove from param list
+	preset_name_list_t::iterator it = find(mPresetNames.begin(), mPresetNames.end(), name);
+	if (it == mPresetNames.end())
+	{
+		LL_WARNS("Presets") << "No preset named " << name << LL_ENDL;
+		return false;
+	}
+
+	mPresetNames.erase(it);
+
+	// remove from file system if requested
+	if (delete_from_disk)
+	{
+		if (gDirUtilp->deleteFilesInDir(getUserDir(GRAPHIC_DIR), LLURI::escape(name) + ".xml") < 1)
+		{
+			LL_WARNS("Presets") << "Error removing preset " << name << " from disk" << LL_ENDL;
+		}
+	}
+
+	// signal interested parties
+	mPresetListChangeSignal();
+
+	return true;
+}
+
+boost::signals2::connection LLPresetsManager::setPresetListChangeCallback(const preset_list_signal_t::slot_type& cb)
+{
+	return mPresetListChangeSignal.connect(cb);
+}
diff --git a/indra/newview/llpresetsmanager.h b/indra/newview/llpresetsmanager.h
new file mode 100644
index 0000000000000000000000000000000000000000..2d6dd4fd1ba6df1665f09f231079b50fb584b6b0
--- /dev/null
+++ b/indra/newview/llpresetsmanager.h
@@ -0,0 +1,57 @@
+/**
+ * @file llpresetsmanager.h
+ * @brief Implementation for the LLPresetsManager class.
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_PRESETSMANAGER_H
+#define LL_PRESETSMANAGER_H
+
+#include <list>
+
+class LLPresetsManager : public LLSingleton<LLPresetsManager>
+{
+public:
+	typedef std::list<std::string> preset_name_list_t;
+	typedef boost::signals2::signal<void()> preset_list_signal_t;
+
+	void getPresetsFromDir(const std::string& dir);
+	void savePreset(const std::string & name);
+	static std::string getGraphicPresetsDir();
+	bool removeParamSet(const std::string& name, bool delete_from_disk);
+
+	/// Emitted when a preset gets added or deleted.
+	boost::signals2::connection setPresetListChangeCallback(const preset_list_signal_t::slot_type& cb);
+
+	preset_name_list_t mPresetNames;
+
+private:
+	LLPresetsManager();
+	~LLPresetsManager();
+
+	static std::string getUserDir(const std::string& subdirectory);
+
+	preset_list_signal_t mPresetListChangeSignal;
+};
+
+#endif LL_PRESETSMANAGER_H
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml
index bd61f2c4fa316620fae3c9bc52968807d9f5809e..371a5fd48e75c2d897262cd106564fa3cf76c856 100755
--- a/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml
@@ -916,7 +916,7 @@
             left="70"
             min_val="0"
             max_val="2"
-            name="RenderShadowDetail"
+            name="ShadowDetail"
             show_text="false"
             top_delta="16"
             width="260">