diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 81caf9fbd4a46b42f890804a891aeb6033914c1f..b87f3bf3d4d7e00fd03c6933ddb397908e8f894e 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -123,6 +123,7 @@ set(viewer_SOURCE_FILES
     llcurrencyuimanager.cpp
     llcylinder.cpp
     lldateutil.cpp
+    lldaycyclemanager.cpp
     lldebugmessagebox.cpp
     lldebugview.cpp
     lldelayedgestureerror.cpp
@@ -670,6 +671,7 @@ set(viewer_HEADER_FILES
     llcurrencyuimanager.h
     llcylinder.h
     lldateutil.h
+    lldaycyclemanager.h
     lldebugmessagebox.h
     lldebugview.h
     lldelayedgestureerror.h
diff --git a/indra/newview/lldaycyclemanager.cpp b/indra/newview/lldaycyclemanager.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..c0eae8cd3cd575853e7db293ec2fbbb4118e26c6
--- /dev/null
+++ b/indra/newview/lldaycyclemanager.cpp
@@ -0,0 +1,122 @@
+/**
+ * @file lldaycyclemanager.cpp
+ * @brief Implementation for the LLDayCycleManager class.
+ *
+ * $LicenseInfo:firstyear=2011&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2011, 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 "lldaycyclemanager.h"
+
+#include "lldiriterator.h"
+
+const LLDayCycleManager::dc_map_t& LLDayCycleManager::getPresets()
+{
+	// Refresh day cycles.
+	loadAllPresets();
+
+	return mDayCycleMap;
+}
+
+bool LLDayCycleManager::getPreset(const std::string name, LLWLDayCycle& day_cycle)
+{
+	dc_map_t::const_iterator it = mDayCycleMap.find(name);
+	if (it == mDayCycleMap.end())
+	{
+		return false;
+	}
+
+	day_cycle = it->second;
+	return true;
+}
+
+bool LLDayCycleManager::getPreset(const std::string name, LLSD& day_cycle)
+{
+	LLWLDayCycle dc;
+	if (!getPreset(name, dc))
+	{
+		return false;
+	}
+
+	day_cycle = dc.asLLSD();
+	return true;
+}
+
+// virtual
+void LLDayCycleManager::initSingleton()
+{
+	LL_DEBUGS("Windlight") << "Loading all day cycles" << LL_ENDL;
+	loadAllPresets();
+}
+
+void LLDayCycleManager::loadAllPresets()
+{
+	mDayCycleMap.clear();
+
+	// First, load system (coming out of the box) day cycles.
+	loadPresets(getSysDir());
+
+	// Then load user presets. Note that user day cycles will modify any system ones already loaded.
+	loadPresets(getUserDir());
+}
+
+void LLDayCycleManager::loadPresets(const std::string& dir)
+{
+	LLDirIterator dir_iter(dir, "*.xml");
+
+	while (1)
+	{
+		std::string file;
+		if (!dir_iter.next(file)) break; // no more files
+		loadPreset(dir + file);
+	}
+}
+
+bool LLDayCycleManager::loadPreset(const std::string& path)
+{
+	LLSD data = LLWLDayCycle::loadDayCycleFromPath(path);
+	if (data.isUndefined())
+	{
+		LL_WARNS("Windlight") << "Error loading day cycle from " << path << LL_ENDL;
+		return false;
+	}
+
+	std::string name(gDirUtilp->getBaseFileName(LLURI::unescape(path), /*strip_exten = */ true));
+	LLWLDayCycle day_cycle;
+	day_cycle.loadDayCycle(data, LLEnvKey::SCOPE_LOCAL);
+	mDayCycleMap[name] = day_cycle;
+
+	return true;
+}
+
+// static
+std::string LLDayCycleManager::getSysDir()
+{
+	return gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight/days", "");
+}
+
+// static
+std::string LLDayCycleManager::getUserDir()
+{
+	return gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS , "windlight/days", "");
+}
diff --git a/indra/newview/lldaycyclemanager.h b/indra/newview/lldaycyclemanager.h
new file mode 100644
index 0000000000000000000000000000000000000000..e49e4986fecf92dcd6bb3fab06451b8dc0f94166
--- /dev/null
+++ b/indra/newview/lldaycyclemanager.h
@@ -0,0 +1,66 @@
+/**
+ * @file lldaycyclemanager.h
+ * @brief Implementation for the LLDayCycleManager class.
+ *
+ * $LicenseInfo:firstyear=2011&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2011, 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_LLDAYCYCLEMANAGER_H
+#define LL_LLDAYCYCLEMANAGER_H
+
+#include <map>
+#include <string>
+
+#include "llwldaycycle.h"
+#include "llwlparammanager.h"
+
+/**
+ * WindLight day cycles manager class
+ *
+ * Provides interface for accessing, loading and saving day cycles.
+ */
+class LLDayCycleManager : public LLSingleton<LLDayCycleManager>
+{
+	LOG_CLASS(LLDayCycleManager);
+
+public:
+	typedef std::map<std::string, LLWLDayCycle> dc_map_t;
+
+	const dc_map_t& getPresets();
+	bool getPreset(const std::string name, LLWLDayCycle& day_cycle);
+	bool getPreset(const std::string name, LLSD& day_cycle);
+
+private:
+	friend class LLSingleton<LLDayCycleManager>;
+	/*virtual*/ void initSingleton();
+
+	void loadAllPresets();
+	void loadPresets(const std::string& dir);
+	bool loadPreset(const std::string& path);
+
+	static std::string getSysDir();
+	static std::string getUserDir();
+
+	dc_map_t mDayCycleMap;
+};
+
+#endif // LL_LLDAYCYCLEMANAGER_H
diff --git a/indra/newview/llenvmanager.cpp b/indra/newview/llenvmanager.cpp
index a08ca884595d41404f09eee8dfdd920ba51943a2..f12c3e54ffdcf17eda4f7a21e3b20bcfe8325076 100644
--- a/indra/newview/llenvmanager.cpp
+++ b/indra/newview/llenvmanager.cpp
@@ -764,12 +764,6 @@ void LLEnvManagerNew::dumpUserPrefs()
 	LL_DEBUGS("Windlight") << "UseDayCycle: "				<< gSavedSettings.getBOOL("UseDayCycle") << LL_ENDL;
 }
 
-// static
-LLSD LLEnvManagerNew::getDayCycleByName(const std::string name)
-{
-	return LLWLDayCycle::loadCycleDataFromFile(name + ".xml");
-}
-
 void LLEnvManagerNew::requestRegionSettings()
 {
 	LLEnvironmentRequest::initiate();
diff --git a/indra/newview/llenvmanager.h b/indra/newview/llenvmanager.h
index 52b645b5352a67fa7699cf4283c878e1c0b70fad..223654151bce5c1ff9a6fa03c3be728347bdcb66 100644
--- a/indra/newview/llenvmanager.h
+++ b/indra/newview/llenvmanager.h
@@ -293,9 +293,6 @@ class LLEnvManagerNew : public LLSingleton<LLEnvManagerNew>
 		bool use_region_settings);
 	void dumpUserPrefs();
 
-	// Common interface to the wl/water managers.
-	static LLSD getDayCycleByName(const std::string name);
-
 	// Misc.
 	void requestRegionSettings();
 	bool sendRegionSettings(const LLEnvironmentSettings& new_settings);
diff --git a/indra/newview/llfloaterenvironmentsettings.cpp b/indra/newview/llfloaterenvironmentsettings.cpp
index cbbbed983016266d83b6728760cf96a217fe95b5..f097f70143596cfe612d5f8f5d1c14bc0c2beb35 100644
--- a/indra/newview/llfloaterenvironmentsettings.cpp
+++ b/indra/newview/llfloaterenvironmentsettings.cpp
@@ -31,6 +31,7 @@
 #include "llcombobox.h"
 #include "llradiogroup.h"
 
+#include "lldaycyclemanager.h"
 #include "llenvmanager.h"
 #include "llwaterparammanager.h"
 #include "llwlparamset.h"
@@ -204,6 +205,9 @@ void LLFloaterEnvironmentSettings::populateDayCyclePresetsList()
 {
 	mDayCyclePresetCombo->removeall();
 
-	std::string day_cycle_name = LLEnvManagerNew::getInstance()->getDayCycleName();
-	mDayCyclePresetCombo->add(day_cycle_name);
+	const LLDayCycleManager::dc_map_t& map = LLDayCycleManager::instance().getPresets();
+	for (LLDayCycleManager::dc_map_t::const_iterator it = map.begin(); it != map.end(); ++it)
+	{
+		mDayCyclePresetCombo->add(it->first);
+	}
 }
diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp
index ff34e21c2ff067b0a97f89cc6eb405b88fd36902..6a5b5773969eb4074f5f36cbe733f98fc9b35392 100644
--- a/indra/newview/llfloaterregioninfo.cpp
+++ b/indra/newview/llfloaterregioninfo.cpp
@@ -52,6 +52,7 @@
 #include "llbutton.h" 
 #include "llcheckboxctrl.h"
 #include "llcombobox.h"
+#include "lldaycyclemanager.h"
 #include "llenvmanager.h"
 #include "llfilepicker.h"
 #include "llfloaterdaycycle.h"
@@ -3350,14 +3351,18 @@ void LLPanelEnvironmentInfo::populateDayCyclesList()
 		llassert(region != NULL);
 
 		LLWLParamKey key(region->getName(), LLEnvKey::SCOPE_REGION);
-		mDayCyclePresetCombo->add(region->getName(), key.toLLSD());
+		mDayCyclePresetCombo->add(region->getName(), key.toStringVal());
 		mDayCyclePresetCombo->addSeparator();
 	}
 
 	// Add local day cycles.
-	// *TODO: multiple local day cycles support
-	LLWLParamKey key("Default", LLEnvKey::SCOPE_LOCAL);
-	mDayCyclePresetCombo->add("Default", key.toLLSD());
+	const LLDayCycleManager::dc_map_t& map = LLDayCycleManager::instance().getPresets();
+	for (LLDayCycleManager::dc_map_t::const_iterator it = map.begin(); it != map.end(); ++it)
+	{
+		std::string name = it->first;
+		LLWLParamKey key(name, LLEnvKey::SCOPE_LOCAL);
+		mDayCyclePresetCombo->add(name, key.toStringVal());
+	}
 
 	// Current day cycle is already selected.
 }
@@ -3421,7 +3426,8 @@ void LLPanelEnvironmentInfo::onBtnSave()
 		}
 		else // use day cycle
 		{
-			LLWLParamKey dc(mDayCyclePresetCombo->getValue());
+			std::string preset_key(mDayCyclePresetCombo->getValue().asString());
+			LLWLParamKey dc(preset_key);
 			LL_DEBUGS("Windlight") << "Use day cycle: " << dc.toLLSD() << LL_ENDL;
 
 			if (dc.scope == LLEnvKey::SCOPE_REGION) // current region day cycle
@@ -3431,8 +3437,11 @@ void LLPanelEnvironmentInfo::onBtnSave()
 			}
 			else // a local day cycle
 			{
-				// *TODO: multiple local day cycles support
-				day_cycle = LLEnvManagerNew::instance().getDayCycleByName("Default");
+				if (!LLDayCycleManager::instance().getPreset(dc.name, day_cycle))
+				{
+					llwarns << "Error getting day cycle " << dc.name << llendl;
+					return;
+				}
 
 				// Create sky map from the day cycle.
 				{
diff --git a/indra/newview/llwldaycycle.cpp b/indra/newview/llwldaycycle.cpp
index 73633920422545e5a1dac90a352e9c9287f80ebe..6ac63fb99e858393b8de59fa4be185b1c2043de1 100644
--- a/indra/newview/llwldaycycle.cpp
+++ b/indra/newview/llwldaycycle.cpp
@@ -100,9 +100,16 @@ void LLWLDayCycle::loadDayCycleFromFile(const std::string & fileName)
 	// now load the file
 	std::string pathName(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, 
 		"windlight/days", fileName));
-	llinfos << "Loading DayCycle settings from " << pathName << llendl;
+
+	return loadDayCycleFromPath(pathName);
+}
+
+// static
+LLSD LLWLDayCycle::loadDayCycleFromPath(const std::string& file_path)
+{
+	LL_INFOS("Windlight") << "Loading DayCycle settings from " << file_path << LL_ENDL;
 	
-	llifstream day_cycle_xml(pathName);
+	llifstream day_cycle_xml(file_path);
 	if (day_cycle_xml.is_open())
 	{
 		// load and parse it
diff --git a/indra/newview/llwldaycycle.h b/indra/newview/llwldaycycle.h
index 36b5160a58febd65ba87dd0a22fa25b8a85936e4..56bd66f114aa2f19b4b457530d52599ac13e3cd8 100644
--- a/indra/newview/llwldaycycle.h
+++ b/indra/newview/llwldaycycle.h
@@ -68,6 +68,9 @@ class LLWLDayCycle
 	/// load the LLSD data from a file (returns the undefined LLSD if not found)
 	static LLSD loadCycleDataFromFile(const std::string & fileName);
 
+	/// load the LLSD data from a file specified by full path
+	static LLSD loadDayCycleFromPath(const std::string& file_path);
+
 	/// get the LLSD data for this day cycle
 	LLSD asLLSD();
 
diff --git a/indra/newview/llwlparammanager.cpp b/indra/newview/llwlparammanager.cpp
index ec7889cb93096f06ff36ca1761602ea79219135d..396c61b4b6ddfd8b90de1915841c110416b2c280 100644
--- a/indra/newview/llwlparammanager.cpp
+++ b/indra/newview/llwlparammanager.cpp
@@ -50,6 +50,7 @@
 #include "llagent.h"
 #include "llviewerregion.h"
 
+#include "lldaycyclemanager.h"
 #include "llenvmanager.h"
 #include "llwlparamset.h"
 #include "llpostprocess.h"
@@ -613,7 +614,11 @@ void LLWLParamManager::applyUserPrefs(bool interpolate)
 	{
 		if (LLEnvManagerNew::instance().getUseDayCycle())
 		{
-			applyDayCycle(LLEnvManagerNew::instance().getDayCycleName());
+			if (!applyDayCycle(LLEnvManagerNew::instance().getDayCycleName()))
+			{
+				// *TODO: fix user prefs
+				applyDefaults();
+			}
 		}
 		else
 		{
@@ -627,14 +632,21 @@ void LLWLParamManager::applyUserPrefs(bool interpolate)
 
 void LLWLParamManager::applyDefaults()
 {
-	applyDayCycle("Default");
+	llassert(applyDayCycle("Default") == true);
 }
 
-void LLWLParamManager::applyDayCycle(const std::string& day_cycle)
+bool LLWLParamManager::applyDayCycle(const std::string& day_cycle)
 {
 	LL_DEBUGS("Windlight") << "Applying day cycle [" << day_cycle << "]" << LL_ENDL;
-	mDay.loadDayCycleFromFile(day_cycle + ".xml");
+
+	if (!LLDayCycleManager::instance().getPreset(day_cycle, mDay))
+	{
+		llwarns << "No day cycle named " << day_cycle << llendl;
+		return false;
+	}
+
 	resetAnimator(0.5, true); // set to noon and start animator
+	return true;
 }
 
 void LLWLParamManager::resetAnimator(F32 curTime, bool run)
diff --git a/indra/newview/llwlparammanager.h b/indra/newview/llwlparammanager.h
index 35acb7c5d6deef6d3e08bd6ec61059f29471ab2e..eb810a408648ab026d619387cd5054bb87d4dc11 100644
--- a/indra/newview/llwlparammanager.h
+++ b/indra/newview/llwlparammanager.h
@@ -246,7 +246,7 @@ class LLWLParamManager : public LLSingleton<LLWLParamManager>
 	void applyDefaults();
 
 	/// apply default sky params
-	void applyDayCycle(const std::string& day);
+	bool applyDayCycle(const std::string& day);
 
 	// get where the light is pointing
 	inline LLVector4 getLightDir(void) const;