diff --git a/indra/integration_tests/llui_libtest/llui_libtest.cpp b/indra/integration_tests/llui_libtest/llui_libtest.cpp
index 217e26c3ca527380c91fd8bbc1e1d42d3debc83b..c34115ee8064a6d8a63b3ad03ad85e7d44b5dfed 100644
--- a/indra/integration_tests/llui_libtest/llui_libtest.cpp
+++ b/indra/integration_tests/llui_libtest/llui_libtest.cpp
@@ -33,7 +33,6 @@
 // linden library includes
 #include "llcontrol.h"		// LLControlGroup
 #include "lldir.h"
-#include "lldiriterator.h"
 #include "llerrorcontrol.h"
 #include "llfloater.h"
 #include "llfontfreetype.h"
@@ -175,9 +174,7 @@ void export_test_floaters()
 	std::string delim = gDirUtilp->getDirDelimiter();
 	std::string xui_dir = get_xui_dir() + "en" + delim;
 	std::string filename;
-
-	LLDirIterator iter(xui_dir, "floater_test_*.xml");
-	while (iter.next(filename))
+	while (gDirUtilp->getNextFileInDir(xui_dir, "floater_test_*.xml", filename))
 	{
 		if (filename.find("_new.xml") != std::string::npos)
 		{
diff --git a/indra/linux_updater/linux_updater.cpp b/indra/linux_updater/linux_updater.cpp
index 808ab3f64f81ab2da3d945212f7a510a251018ef..d909516bf8fbce6872458eec049e0b4c836df6ae 100644
--- a/indra/linux_updater/linux_updater.cpp
+++ b/indra/linux_updater/linux_updater.cpp
@@ -33,7 +33,6 @@
 #include "llerrorcontrol.h"
 #include "llfile.h"
 #include "lldir.h"
-#include "lldiriterator.h"
 #include "llxmlnode.h"
 #include "lltrans.h"
 
@@ -56,8 +55,6 @@ typedef struct _updater_app_state {
 	std::string strings_dirs;
 	std::string strings_file;
 
-	LLDirIterator *image_dir_iter;
-
 	GtkWidget *window;
 	GtkWidget *progress_bar;
 	GtkWidget *image;
@@ -111,7 +108,7 @@ bool translate_init(std::string comma_delim_path_list,
 void updater_app_ui_init(void);
 void updater_app_quit(UpdaterAppState *app_state);
 void parse_args_and_init(int argc, char **argv, UpdaterAppState *app_state);
-std::string next_image_filename(std::string& image_path, LLDirIterator& iter);
+std::string next_image_filename(std::string& image_path);
 void display_error(GtkWidget *parent, std::string title, std::string message);
 BOOL install_package(std::string package_file, std::string destination);
 BOOL spawn_viewer(UpdaterAppState *app_state);
@@ -177,7 +174,7 @@ void updater_app_ui_init(UpdaterAppState *app_state)
 
 		// load the first image
 		app_state->image = gtk_image_new_from_file
-			(next_image_filename(app_state->image_dir, *app_state->image_dir_iter).c_str());
+			(next_image_filename(app_state->image_dir).c_str());
 		gtk_widget_set_size_request(app_state->image, 340, 310);
 		gtk_container_add(GTK_CONTAINER(frame), app_state->image);
 
@@ -208,7 +205,7 @@ gboolean rotate_image_cb(gpointer data)
 	llassert(data != NULL);
 	app_state = (UpdaterAppState *) data;
 
-	filename = next_image_filename(app_state->image_dir, *app_state->image_dir_iter);
+	filename = next_image_filename(app_state->image_dir);
 
 	gdk_threads_enter();
 	gtk_image_set_from_file(GTK_IMAGE(app_state->image), filename.c_str());
@@ -217,10 +214,10 @@ gboolean rotate_image_cb(gpointer data)
 	return TRUE;
 }
 
-std::string next_image_filename(std::string& image_path, LLDirIterator& iter)
+std::string next_image_filename(std::string& image_path)
 {
 	std::string image_filename;
-	iter.next(image_filename);
+	gDirUtilp->getNextFileInDir(image_path, "/*.jpg", image_filename);
 	return image_path + "/" + image_filename;
 }
 
@@ -744,7 +741,6 @@ void parse_args_and_init(int argc, char **argv, UpdaterAppState *app_state)
 		else if ((!strcmp(argv[i], "--image-dir")) && (++i < argc))
 		{
 			app_state->image_dir = argv[i];
-			app_state->image_dir_iter = new LLDirIterator(argv[i], "/*.jpg");
 		}
 		else if ((!strcmp(argv[i], "--dest")) && (++i < argc))
 		{
@@ -829,7 +825,6 @@ int main(int argc, char **argv)
 	}
 
 	bool success = !app_state->failure;
-	delete app_state->image_dir_iter;
 	delete app_state;
 	return success ? 0 : 1;
 }
diff --git a/indra/llvfs/lldir.cpp b/indra/llvfs/lldir.cpp
index ab7d15dfefdcbec79c3d894b19dee81f0352b0a3..64556bcb4c34dcacd2b48f391dbfebf0eb528421 100644
--- a/indra/llvfs/lldir.cpp
+++ b/indra/llvfs/lldir.cpp
@@ -40,8 +40,6 @@
 #include "lltimer.h"	// ms_sleep()
 #include "lluuid.h"
 
-#include "lldiriterator.h"
-
 #if LL_WINDOWS
 #include "lldir_win32.h"
 LLDir_Win32 gDirUtil;
@@ -85,9 +83,7 @@ S32 LLDir::deleteFilesInDir(const std::string &dirname, const std::string &mask)
 	std::string filename; 
 	std::string fullpath;
 	S32 result;
-
-	LLDirIterator iter(dirname, mask);
-	while (iter.next(filename))
+	while (getNextFileInDir(dirname, mask, filename))
 	{
 		fullpath = dirname;
 		fullpath += getDirDelimiter();
diff --git a/indra/llvfs/lldir.h b/indra/llvfs/lldir.h
index 5ee8bdb542da2ebc4ee3d10ce114a7df3c1e20b6..42996fd051b9f5cc8ed949645fa7fda5c4c58f74 100644
--- a/indra/llvfs/lldir.h
+++ b/indra/llvfs/lldir.h
@@ -75,6 +75,31 @@ class LLDir
 // pure virtual functions
 	virtual U32 countFilesInDir(const std::string &dirname, const std::string &mask) = 0;
 
+    /// Walk the files in a directory, with file pattern matching
+	virtual BOOL getNextFileInDir(const std::string& dirname, ///< directory path - must end in trailing slash!
+                                  const std::string& mask,    ///< file pattern string (use "*" for all)
+                                  std::string& fname          ///< output: found file name
+                                  ) = 0;
+    /**<
+     * @returns true if a file was found, false if the entire directory has been scanned.
+     *
+     * @note that this function is NOT thread safe
+     *
+     * This function may not be used to scan part of a directory, then start a new search of a different
+     * directory, and then restart the first search where it left off; the entire search must run to
+     * completion or be abandoned - there is no restart.
+     *
+     * @bug: See http://jira.secondlife.com/browse/VWR-23697
+     *       and/or the tests in test/lldir_test.cpp
+     *       This is known to fail with patterns that have both:
+     *       a wildcard left of a . and more than one sequential ? right of a .
+     *       the pattern foo.??x appears to work
+     *       but *.??x or foo?.??x do not
+     *
+     * @todo this really should be rewritten as an iterator object, and the
+     *       filtering should be done in a platform-independent way.
+     */
+
 	virtual std::string getCurPath() = 0;
 	virtual BOOL fileExists(const std::string &filename) const = 0;
 
diff --git a/indra/llvfs/lldir_linux.cpp b/indra/llvfs/lldir_linux.cpp
index 4ba2f519b0f8080d700dd4c672abeac8ce803962..73f2336f94fa70bf2d43bc6b924ed6262b7bd2e8 100644
--- a/indra/llvfs/lldir_linux.cpp
+++ b/indra/llvfs/lldir_linux.cpp
@@ -242,6 +242,68 @@ U32 LLDir_Linux::countFilesInDir(const std::string &dirname, const std::string &
 	return (file_count);
 }
 
+// get the next file in the directory
+BOOL LLDir_Linux::getNextFileInDir(const std::string &dirname, const std::string &mask, std::string &fname)
+{
+	glob_t g;
+	BOOL result = FALSE;
+	fname = "";
+	
+	if(!(dirname == mCurrentDir))
+	{
+		// different dir specified, close old search
+		mCurrentDirIndex = -1;
+		mCurrentDirCount = -1;
+		mCurrentDir = dirname;
+	}
+	
+	std::string tmp_str;
+	tmp_str = dirname;
+	tmp_str += mask;
+
+	if(glob(tmp_str.c_str(), GLOB_NOSORT, NULL, &g) == 0)
+	{
+		if(g.gl_pathc > 0)
+		{
+			if((int)g.gl_pathc != mCurrentDirCount)
+			{
+				// Number of matches has changed since the last search, meaning a file has been added or deleted.
+				// Reset the index.
+				mCurrentDirIndex = -1;
+				mCurrentDirCount = g.gl_pathc;
+			}
+	
+			mCurrentDirIndex++;
+	
+			if(mCurrentDirIndex < (int)g.gl_pathc)
+			{
+//				llinfos << "getNextFileInDir: returning number " << mCurrentDirIndex << ", path is " << g.gl_pathv[mCurrentDirIndex] << llendl;
+
+				// The API wants just the filename, not the full path.
+				//fname = g.gl_pathv[mCurrentDirIndex];
+
+				char *s = strrchr(g.gl_pathv[mCurrentDirIndex], '/');
+				
+				if(s == NULL)
+					s = g.gl_pathv[mCurrentDirIndex];
+				else if(s[0] == '/')
+					s++;
+					
+				fname = s;
+				
+				result = TRUE;
+			}
+		}
+		
+		globfree(&g);
+	}
+	
+	return(result);
+}
+
+
+
+
 std::string LLDir_Linux::getCurPath()
 {
 	char tmp_str[LL_MAX_PATH];	/* Flawfinder: ignore */ 
diff --git a/indra/llvfs/lldir_linux.h b/indra/llvfs/lldir_linux.h
index ff4c48759a03327d6b04191d3b179451ad0fd3fd..451e81ae93c560114b83f556120f3fd42f6dbec9 100644
--- a/indra/llvfs/lldir_linux.h
+++ b/indra/llvfs/lldir_linux.h
@@ -43,6 +43,7 @@ class LLDir_Linux : public LLDir
 public:	
 	virtual std::string getCurPath();
 	virtual U32 countFilesInDir(const std::string &dirname, const std::string &mask);
+	virtual BOOL getNextFileInDir(const std::string &dirname, const std::string &mask, std::string &fname);
 	/*virtual*/ BOOL fileExists(const std::string &filename) const;
 
 	/*virtual*/ std::string getLLPluginLauncher();
diff --git a/indra/llvfs/lldir_mac.cpp b/indra/llvfs/lldir_mac.cpp
index 2d039527c06fa05286ddcbd04226a4425c0e85fb..445285aa43ac2c5dae2c11187e73280dc88614db 100644
--- a/indra/llvfs/lldir_mac.cpp
+++ b/indra/llvfs/lldir_mac.cpp
@@ -258,6 +258,67 @@ U32 LLDir_Mac::countFilesInDir(const std::string &dirname, const std::string &ma
 	return (file_count);
 }
 
+// get the next file in the directory
+BOOL LLDir_Mac::getNextFileInDir(const std::string &dirname, const std::string &mask, std::string &fname)
+{
+	glob_t g;
+	BOOL result = FALSE;
+	fname = "";
+	
+	if(!(dirname == mCurrentDir))
+	{
+		// different dir specified, close old search
+		mCurrentDirIndex = -1;
+		mCurrentDirCount = -1;
+		mCurrentDir = dirname;
+	}
+	
+	std::string tmp_str;
+	tmp_str = dirname;
+	tmp_str += mask;
+
+	if(glob(tmp_str.c_str(), GLOB_NOSORT, NULL, &g) == 0)
+	{
+		if(g.gl_pathc > 0)
+		{
+			if(g.gl_pathc != mCurrentDirCount)
+			{
+				// Number of matches has changed since the last search, meaning a file has been added or deleted.
+				// Reset the index.
+				mCurrentDirIndex = -1;
+				mCurrentDirCount = g.gl_pathc;
+			}
+	
+			mCurrentDirIndex++;
+	
+			if(mCurrentDirIndex < g.gl_pathc)
+			{
+//				llinfos << "getNextFileInDir: returning number " << mCurrentDirIndex << ", path is " << g.gl_pathv[mCurrentDirIndex] << llendl;
+
+				// The API wants just the filename, not the full path.
+				//fname = g.gl_pathv[mCurrentDirIndex];
+
+				char *s = strrchr(g.gl_pathv[mCurrentDirIndex], '/');
+				
+				if(s == NULL)
+					s = g.gl_pathv[mCurrentDirIndex];
+				else if(s[0] == '/')
+					s++;
+					
+				fname = s;
+				
+				result = TRUE;
+			}
+		}
+		
+		globfree(&g);
+	}
+	
+	return(result);
+}
+
+
+
 S32 LLDir_Mac::deleteFilesInDir(const std::string &dirname, const std::string &mask)
 {
 	glob_t g;
diff --git a/indra/llvfs/lldir_mac.h b/indra/llvfs/lldir_mac.h
index e60d5e41c2deca2e9aaca01d8f34306fbb896c1a..4eac3c3ae6fce824624bc7c048b8922c6c86e517 100644
--- a/indra/llvfs/lldir_mac.h
+++ b/indra/llvfs/lldir_mac.h
@@ -43,6 +43,7 @@ class LLDir_Mac : public LLDir
 	virtual S32 deleteFilesInDir(const std::string &dirname, const std::string &mask);
 	virtual std::string getCurPath();
 	virtual U32 countFilesInDir(const std::string &dirname, const std::string &mask);
+	virtual BOOL getNextFileInDir(const std::string &dirname, const std::string &mask, std::string &fname);
 	virtual BOOL fileExists(const std::string &filename) const;
 
 	/*virtual*/ std::string getLLPluginLauncher();
diff --git a/indra/llvfs/lldir_solaris.cpp b/indra/llvfs/lldir_solaris.cpp
index 21f8c3acdbeefa56272bac597cf5b1d1858ba46c..515fd66b6e9a9f4d2aef1647ad78134a15419f0c 100644
--- a/indra/llvfs/lldir_solaris.cpp
+++ b/indra/llvfs/lldir_solaris.cpp
@@ -260,6 +260,68 @@ U32 LLDir_Solaris::countFilesInDir(const std::string &dirname, const std::string
 	return (file_count);
 }
 
+// get the next file in the directory
+BOOL LLDir_Solaris::getNextFileInDir(const std::string &dirname, const std::string &mask, std::string &fname)
+{
+	glob_t g;
+	BOOL result = FALSE;
+	fname = "";
+	
+	if(!(dirname == mCurrentDir))
+	{
+		// different dir specified, close old search
+		mCurrentDirIndex = -1;
+		mCurrentDirCount = -1;
+		mCurrentDir = dirname;
+	}
+	
+	std::string tmp_str;
+	tmp_str = dirname;
+	tmp_str += mask;
+
+	if(glob(tmp_str.c_str(), GLOB_NOSORT, NULL, &g) == 0)
+	{
+		if(g.gl_pathc > 0)
+		{
+			if((int)g.gl_pathc != mCurrentDirCount)
+			{
+				// Number of matches has changed since the last search, meaning a file has been added or deleted.
+				// Reset the index.
+				mCurrentDirIndex = -1;
+				mCurrentDirCount = g.gl_pathc;
+			}
+	
+			mCurrentDirIndex++;
+	
+			if(mCurrentDirIndex < (int)g.gl_pathc)
+			{
+//				llinfos << "getNextFileInDir: returning number " << mCurrentDirIndex << ", path is " << g.gl_pathv[mCurrentDirIndex] << llendl;
+
+				// The API wants just the filename, not the full path.
+				//fname = g.gl_pathv[mCurrentDirIndex];
+
+				char *s = strrchr(g.gl_pathv[mCurrentDirIndex], '/');
+				
+				if(s == NULL)
+					s = g.gl_pathv[mCurrentDirIndex];
+				else if(s[0] == '/')
+					s++;
+					
+				fname = s;
+				
+				result = TRUE;
+			}
+		}
+		
+		globfree(&g);
+	}
+	
+	return(result);
+}
+
+
+
+
 std::string LLDir_Solaris::getCurPath()
 {
 	char tmp_str[LL_MAX_PATH];	/* Flawfinder: ignore */ 
diff --git a/indra/llvfs/lldir_solaris.h b/indra/llvfs/lldir_solaris.h
index f7e1a6301dbdc19a713e568d44cb28812b048427..4a1794f53950dab8f147dae3c4bc9cfe4e3b1088 100644
--- a/indra/llvfs/lldir_solaris.h
+++ b/indra/llvfs/lldir_solaris.h
@@ -43,6 +43,7 @@ class LLDir_Solaris : public LLDir
 public:	
 	virtual std::string getCurPath();
 	virtual U32 countFilesInDir(const std::string &dirname, const std::string &mask);
+	virtual BOOL getNextFileInDir(const std::string &dirname, const std::string &mask, std::string &fname);
 	/*virtual*/ BOOL fileExists(const std::string &filename) const;
 
 private:
diff --git a/indra/llvfs/lldir_win32.cpp b/indra/llvfs/lldir_win32.cpp
index 2f96fbbbc10d2aeee4a78a3c29742aacad05c6e2..33718e520d71b4c3e2595574187c22d0224c0ce7 100644
--- a/indra/llvfs/lldir_win32.cpp
+++ b/indra/llvfs/lldir_win32.cpp
@@ -236,6 +236,67 @@ U32 LLDir_Win32::countFilesInDir(const std::string &dirname, const std::string &
 	return (file_count);
 }
 
+
+// get the next file in the directory
+BOOL LLDir_Win32::getNextFileInDir(const std::string &dirname, const std::string &mask, std::string &fname)
+{
+    BOOL fileFound = FALSE;
+	fname = "";
+
+	WIN32_FIND_DATAW FileData;
+    llutf16string pathname = utf8str_to_utf16str(dirname) + utf8str_to_utf16str(mask);
+
+	if (pathname != mCurrentDir)
+	{
+		// different dir specified, close old search
+		if (mCurrentDir[0])
+		{
+			FindClose(mDirSearch_h);
+		}
+		mCurrentDir = pathname;
+
+		// and open new one
+		// Check error opening Directory structure
+		if ((mDirSearch_h = FindFirstFile(pathname.c_str(), &FileData)) != INVALID_HANDLE_VALUE)   
+		{
+           fileFound = TRUE;
+		}
+	}
+
+    // Loop to skip over the current (.) and parent (..) directory entries
+    // (apparently returned in Win7 but not XP)
+    do
+    {
+       if (   fileFound
+           && (  (lstrcmp(FileData.cFileName, (LPCTSTR)TEXT(".")) == 0)
+               ||(lstrcmp(FileData.cFileName, (LPCTSTR)TEXT("..")) == 0)
+               )
+           )
+       {
+          fileFound = FALSE;
+       }
+    } while (   mDirSearch_h != INVALID_HANDLE_VALUE
+             && !fileFound
+             && (fileFound = FindNextFile(mDirSearch_h, &FileData)
+                 )
+             );
+
+    if (!fileFound && GetLastError() == ERROR_NO_MORE_FILES)
+    {
+       // No more files, so reset to beginning of directory
+       FindClose(mDirSearch_h);
+       mCurrentDir[0] = '\000';
+    }
+
+    if (fileFound)
+    {
+        // convert from TCHAR to char
+        fname = utf16str_to_utf8str(FileData.cFileName);
+	}
+    
+	return fileFound;
+}
+
 std::string LLDir_Win32::getCurPath()
 {
 	WCHAR w_str[MAX_PATH];
diff --git a/indra/llvfs/lldir_win32.h b/indra/llvfs/lldir_win32.h
index 19c610eb8b2f6aeee28622a62568a7e14df7517d..4c932c932c8f06d6015c106f2b2cd8c9bd50e7f6 100644
--- a/indra/llvfs/lldir_win32.h
+++ b/indra/llvfs/lldir_win32.h
@@ -40,12 +40,15 @@ class LLDir_Win32 : public LLDir
 
 	/*virtual*/ std::string getCurPath();
 	/*virtual*/ U32 countFilesInDir(const std::string &dirname, const std::string &mask);
+	/*virtual*/ BOOL getNextFileInDir(const std::string &dirname, const std::string &mask, std::string &fname);
 	/*virtual*/ BOOL fileExists(const std::string &filename) const;
 
 	/*virtual*/ std::string getLLPluginLauncher();
 	/*virtual*/ std::string getLLPluginFilename(std::string base_name);
 
 private:
+	BOOL LLDir_Win32::getNextFileInDir(const llutf16string &dirname, const std::string &mask, std::string &fname);
+	
 	void* mDirSearch_h;
 	llutf16string mCurrentDir;
 };
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index f0711db3bd1ce67d478a96a14e34027958f7223e..729f83a2b1083df10311e40f779df650ee691d88 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -89,7 +89,6 @@
 
 // Linden library includes
 #include "llavatarnamecache.h"
-#include "lldiriterator.h"
 #include "llimagej2c.h"
 #include "llmemory.h"
 #include "llprimitive.h"
@@ -3292,9 +3291,7 @@ void LLAppViewer::migrateCacheDirectory()
 			S32 file_count = 0;
 			std::string file_name;
 			std::string mask = delimiter + "*.*";
-
-			LLDirIterator iter(old_cache_dir, mask);
-			while (iter.next(file_name))
+			while (gDirUtilp->getNextFileInDir(old_cache_dir, mask, file_name))
 			{
 				if (file_name == "." || file_name == "..") continue;
 				std::string source_path = old_cache_dir + delimiter + file_name;
@@ -3513,8 +3510,7 @@ bool LLAppViewer::initCache()
 		dir = gDirUtilp->getExpandedFilename(LL_PATH_CACHE,"");
 
 		std::string found_file;
-		LLDirIterator iter(dir, mask);
-		if (iter.next(found_file))
+		if (gDirUtilp->getNextFileInDir(dir, mask, found_file))
 		{
 			old_vfs_data_file = dir + gDirUtilp->getDirDelimiter() + found_file;
 
diff --git a/indra/newview/llappviewerlinux.cpp b/indra/newview/llappviewerlinux.cpp
index fc7a27e5e04ec302e8d0ff161e2de215c888717f..898cc1c0ba8686bc615b685e2d17353c5d51dbb9 100644
--- a/indra/newview/llappviewerlinux.cpp
+++ b/indra/newview/llappviewerlinux.cpp
@@ -30,7 +30,6 @@
 
 #include "llcommandlineparser.h"
 
-#include "lldiriterator.h"
 #include "llmemtype.h"
 #include "llurldispatcher.h"		// SLURL from other app instance
 #include "llviewernetwork.h"
@@ -505,9 +504,7 @@ std::string LLAppViewerLinux::generateSerialNumber()
 
 	// trawl /dev/disk/by-uuid looking for a good-looking UUID to grab
 	std::string this_name;
-
-	LLDirIterator iter(uuiddir, "*");
-	while (iter.next(this_name))
+	while (gDirUtilp->getNextFileInDir(uuiddir, "*", this_name))
 	{
 		if (this_name.length() > best.length() ||
 		    (this_name.length() == best.length() &&
diff --git a/indra/newview/llfloateruipreview.cpp b/indra/newview/llfloateruipreview.cpp
index 182d3d23f1a868355b19dfb6be4fe03959a2ade6..11b3379814a52d3de44e343675abd7196417e5e9 100644
--- a/indra/newview/llfloateruipreview.cpp
+++ b/indra/newview/llfloateruipreview.cpp
@@ -35,7 +35,6 @@
 #include "llfloateruipreview.h"			// Own header
 
 // Internal utility
-#include "lldiriterator.h"
 #include "lleventtimer.h"
 #include "llexternaleditor.h"
 #include "llrender.h"
@@ -482,11 +481,9 @@ BOOL LLFloaterUIPreview::postBuild()
 	std::string language_directory;
 	std::string xui_dir = get_xui_dir();	// directory containing localizations -- don't forget trailing delim
 	mLanguageSelection->removeall();																				// clear out anything temporarily in list from XML
-
-	LLDirIterator iter(xui_dir, "*");
 	while(found)																									// for every directory
 	{
-		if((found = iter.next(language_directory)))							// get next directory
+		if((found = gDirUtilp->getNextFileInDir(xui_dir, "*", language_directory)))							// get next directory
 		{
 			std::string full_path = xui_dir + language_directory;
 			if(LLFile::isfile(full_path.c_str()))																	// if it's not a directory, skip it
@@ -638,51 +635,42 @@ void LLFloaterUIPreview::refreshList()
 	mFileList->clearRows();		// empty list
 	std::string name;
 	BOOL found = TRUE;
-
-	LLDirIterator floater_iter(getLocalizedDirectory(), "floater_*.xml");
 	while(found)				// for every floater file that matches the pattern
 	{
-		if((found = floater_iter.next(name)))	// get next file matching pattern
+		if((found = gDirUtilp->getNextFileInDir(getLocalizedDirectory(), "floater_*.xml", name)))	// get next file matching pattern
 		{
 			addFloaterEntry(name.c_str());	// and add it to the list (file name only; localization code takes care of rest of path)
 		}
 	}
 	found = TRUE;
-
-	LLDirIterator inspect_iter(getLocalizedDirectory(), "inspect_*.xml");
 	while(found)				// for every inspector file that matches the pattern
 	{
-		if((found = inspect_iter.next(name)))	// get next file matching pattern
+		if((found = gDirUtilp->getNextFileInDir(getLocalizedDirectory(), "inspect_*.xml", name)))	// get next file matching pattern
 		{
 			addFloaterEntry(name.c_str());	// and add it to the list (file name only; localization code takes care of rest of path)
 		}
 	}
 	found = TRUE;
-
-	LLDirIterator menu_iter(getLocalizedDirectory(), "menu_*.xml");
 	while(found)				// for every menu file that matches the pattern
 	{
-		if((found = menu_iter.next(name)))	// get next file matching pattern
+		if((found = gDirUtilp->getNextFileInDir(getLocalizedDirectory(), "menu_*.xml", name)))	// get next file matching pattern
 		{
 			addFloaterEntry(name.c_str());	// and add it to the list (file name only; localization code takes care of rest of path)
 		}
 	}
 	found = TRUE;
-
-	LLDirIterator panel_iter(getLocalizedDirectory(), "panel_*.xml");
 	while(found)				// for every panel file that matches the pattern
 	{
-		if((found = panel_iter.next(name)))	// get next file matching pattern
+		if((found = gDirUtilp->getNextFileInDir(getLocalizedDirectory(), "panel_*.xml", name)))	// get next file matching pattern
 		{
 			addFloaterEntry(name.c_str());	// and add it to the list (file name only; localization code takes care of rest of path)
 		}
 	}
-	found = TRUE;
 
-	LLDirIterator sidepanel_iter(getLocalizedDirectory(), "sidepanel_*.xml");
+	found = TRUE;
 	while(found)				// for every sidepanel file that matches the pattern
 	{
-		if((found = sidepanel_iter.next(name)))	// get next file matching pattern
+		if((found = gDirUtilp->getNextFileInDir(getLocalizedDirectory(), "sidepanel_*.xml", name)))	// get next file matching pattern
 		{
 			addFloaterEntry(name.c_str());	// and add it to the list (file name only; localization code takes care of rest of path)
 		}
diff --git a/indra/newview/lllogchat.cpp b/indra/newview/lllogchat.cpp
index b09cfbe90754f7db7186b2d637b6d9db01023f8e..9adf374c71642fc0f3525b36453d93572c7af1b2 100644
--- a/indra/newview/lllogchat.cpp
+++ b/indra/newview/lllogchat.cpp
@@ -32,7 +32,6 @@
 #include "lltrans.h"
 #include "llviewercontrol.h"
 
-#include "lldiriterator.h"
 #include "llinstantmessage.h"
 #include "llsingleton.h" // for LLSingleton
 
@@ -602,8 +601,7 @@ std::string LLLogChat::oldLogFileName(std::string filename)
 	//LL_INFOS("") << "Checking:" << directory << " for " << pattern << LL_ENDL;/* uncomment if you want to verify step, delete on commit */
 	std::vector<std::string> allfiles;
 
-	LLDirIterator iter(directory, pattern);
-	while (iter.next(scanResult))
+    while (gDirUtilp->getNextFileInDir(directory, pattern, scanResult))
     {
 		//LL_INFOS("") << "Found   :" << scanResult << LL_ENDL;
         allfiles.push_back(scanResult);
diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp
index 8a0d0a6623b8138b67227c8225781656979a17be..d3b6dcd86f2f937121d61890f9c997ae0869fd08 100644
--- a/indra/newview/llviewermedia.cpp
+++ b/indra/newview/llviewermedia.cpp
@@ -54,7 +54,6 @@
 #include "llfilepicker.h"
 #include "llnotifications.h"
 
-#include "lldiriterator.h"
 #include "llevent.h"		// LLSimpleListener
 #include "llnotificationsutil.h"
 #include "lluuid.h"
@@ -1116,8 +1115,7 @@ void LLViewerMedia::clearAllCookies()
 	}
 	
 	// the hard part: iterate over all user directories and delete the cookie file from each one
-	LLDirIterator dir_iter(base_dir, "*_*");
-	while (dir_iter.next(filename))
+	while(gDirUtilp->getNextFileInDir(base_dir, "*_*", filename))
 	{
 		target = base_dir;
 		target += filename;
diff --git a/indra/newview/llwaterparammanager.cpp b/indra/newview/llwaterparammanager.cpp
index 4f6ec4ca616ccb4721b9eb7b82b016f97acf9817..d239347810648188b9b7dd2917a8030d8d6d99a7 100644
--- a/indra/newview/llwaterparammanager.cpp
+++ b/indra/newview/llwaterparammanager.cpp
@@ -33,7 +33,6 @@
 #include "pipeline.h"
 #include "llsky.h"
 
-#include "lldiriterator.h"
 #include "llfloaterreg.h"
 #include "llsliderctrl.h"
 #include "llspinctrl.h"
@@ -86,12 +85,11 @@ void LLWaterParamManager::loadAllPresets(const std::string& file_name)
 	std::string path_name(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight/water", ""));
 	LL_DEBUGS2("AppInit", "Shaders") << "Loading Default water settings from " << path_name << LL_ENDL;
 			
-	bool found = true;
-	LLDirIterator app_settings_iter(path_name, "*.xml");
+	bool found = true;			
 	while(found) 
 	{
 		std::string name;
-		found = app_settings_iter.next(name);
+		found = gDirUtilp->getNextFileInDir(path_name, "*.xml", name);
 		if(found)
 		{
 
@@ -113,12 +111,11 @@ void LLWaterParamManager::loadAllPresets(const std::string& file_name)
 	std::string path_name2(gDirUtilp->getExpandedFilename( LL_PATH_USER_SETTINGS , "windlight/water", ""));
 	LL_DEBUGS2("AppInit", "Shaders") << "Loading User water settings from " << path_name2 << LL_ENDL;
 			
-	found = true;
-	LLDirIterator user_settings_iter(path_name2, "*.xml");
+	found = true;			
 	while(found) 
 	{
 		std::string name;
-		found = user_settings_iter.next(name);
+		found = gDirUtilp->getNextFileInDir(path_name2, "*.xml", name);
 		if(found)
 		{
 			name=name.erase(name.length()-4);
diff --git a/indra/newview/llwlparammanager.cpp b/indra/newview/llwlparammanager.cpp
index 848efcbb49e5f8e28f3bd393df7767dd003b27ee..e5f52dfc979b5ef4cd09c8366d6b5263d541b9ba 100644
--- a/indra/newview/llwlparammanager.cpp
+++ b/indra/newview/llwlparammanager.cpp
@@ -31,7 +31,6 @@
 #include "pipeline.h"
 #include "llsky.h"
 
-#include "lldiriterator.h"
 #include "llfloaterreg.h"
 #include "llsliderctrl.h"
 #include "llspinctrl.h"
@@ -101,12 +100,11 @@ void LLWLParamManager::loadPresets(const std::string& file_name)
 	std::string path_name(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight/skies", ""));
 	LL_DEBUGS2("AppInit", "Shaders") << "Loading Default WindLight settings from " << path_name << LL_ENDL;
 			
-	bool found = true;
-	LLDirIterator app_settings_iter(path_name, "*.xml");
+	bool found = true;			
 	while(found) 
 	{
 		std::string name;
-		found = app_settings_iter.next(name);
+		found = gDirUtilp->getNextFileInDir(path_name, "*.xml", name);
 		if(found)
 		{
 
@@ -128,12 +126,11 @@ void LLWLParamManager::loadPresets(const std::string& file_name)
 	std::string path_name2(gDirUtilp->getExpandedFilename( LL_PATH_USER_SETTINGS , "windlight/skies", ""));
 	LL_DEBUGS2("AppInit", "Shaders") << "Loading User WindLight settings from " << path_name2 << LL_ENDL;
 			
-	found = true;
-	LLDirIterator user_settings_iter(path_name2, "*.xml");
+	found = true;			
 	while(found) 
 	{
 		std::string name;
-		found = user_settings_iter.next(name);
+		found = gDirUtilp->getNextFileInDir(path_name2, "*.xml", name);
 		if(found)
 		{
 			name=name.erase(name.length()-4);
diff --git a/indra/viewer_components/updater/tests/llupdaterservice_test.cpp b/indra/viewer_components/updater/tests/llupdaterservice_test.cpp
index e19d5724f172b5bdc552d2243007611b285076e6..88ab5a22845fe1b774dce553b4eb3c049d918ea6 100644
--- a/indra/viewer_components/updater/tests/llupdaterservice_test.cpp
+++ b/indra/viewer_components/updater/tests/llupdaterservice_test.cpp
@@ -59,6 +59,12 @@ class LLDir_Mock : public LLDir
 		return 0;
 	}
 
+	BOOL getNextFileInDir(const std::string &dirname, 
+						  const std::string &mask, 
+						  std::string &fname) 
+	{
+		return false;
+	}
 	void getRandomFileInDir(const std::string &dirname, 
 							const std::string &mask, 
 							std::string &fname) {}