diff --git a/indra/newview/llfilepicker.cpp b/indra/newview/llfilepicker.cpp
index 3669fb1eeb000e103e5a2187ac829b901d39a810..06cb78741ed4abecee35d091dcc756d9c94a3087 100644
--- a/indra/newview/llfilepicker.cpp
+++ b/indra/newview/llfilepicker.cpp
@@ -678,6 +678,30 @@ bool	LLFilePicker::doNavChooseDialog(ELoadFilter filter)
 	return false;
 }
 
+bool    LLFilePicker::doNavChooseDialogModeless(ELoadFilter filter,
+                                                void (*callback)(bool, std::vector<std::string> &,void*),
+                                                void *userdata)
+{
+    // if local file browsing is turned off, return without opening dialog
+    if ( check_local_file_access_enabled() == false )
+    {
+        return false;
+    }
+    
+    gViewerWindow->getWindow()->beforeDialog();
+    
+    std::vector<std::string> *allowed_types=navOpenFilterProc(filter);
+    
+    doLoadDialogModeless(allowed_types,
+                                                    mPickOptions,
+                                                    callback,
+                                                    userdata);
+
+    gViewerWindow->getWindow()->afterDialog();
+    
+    return true;
+}
+
 bool	LLFilePicker::doNavSaveDialog(ESaveFilter filter, const std::string& filename)
 {
 	
@@ -852,18 +876,52 @@ BOOL LLFilePicker::getOpenFile(ELoadFilter filter, bool blocking)
 	return success;
 }
 
+
+BOOL LLFilePicker::getOpenFileModeless(ELoadFilter filter,
+                                       void (*callback)(bool, std::vector<std::string> &, void*),
+                                       void *userdata)
+{
+    if( mLocked )
+        return FALSE;
+
+    // if local file browsing is turned off, return without opening dialog
+    if ( check_local_file_access_enabled() == false )
+    {
+        return FALSE;
+    }
+
+    reset();
+    
+    mPickOptions &= ~F_MULTIPLE;
+    mPickOptions |= F_FILE;
+ 
+    if (filter == FFLOAD_DIRECTORY) //This should only be called from lldirpicker.
+    {
+
+        mPickOptions |= ( F_NAV_SUPPORT | F_DIRECTORY );
+        mPickOptions &= ~F_FILE;
+    }
+
+    if (filter == FFLOAD_ALL)    // allow application bundles etc. to be traversed; important for DEV-16869, but generally useful
+    {
+        mPickOptions |= F_NAV_SUPPORT;
+    }
+
+    return doNavChooseDialogModeless(filter, callback, userdata);
+}
+
 BOOL LLFilePicker::getMultipleOpenFiles(ELoadFilter filter, bool blocking)
 {
 	if( mLocked )
 		return FALSE;
 
-	BOOL success = FALSE;
-
 	// if local file browsing is turned off, return without opening dialog
 	if ( check_local_file_access_enabled() == false )
 	{
 		return FALSE;
 	}
+    
+    BOOL success = FALSE;
 
 	reset();
     
@@ -897,6 +955,27 @@ BOOL LLFilePicker::getMultipleOpenFiles(ELoadFilter filter, bool blocking)
 	return success;
 }
 
+
+BOOL LLFilePicker::getMultipleOpenFilesModeless( ELoadFilter filter, void (*callback)(bool, std::vector<std::string> &, void*), void *userdata )
+{
+    if( mLocked )
+        return FALSE;
+
+    // if local file browsing is turned off, return without opening dialog
+    if ( check_local_file_access_enabled() == false )
+    {
+        return FALSE;
+    }
+
+    reset();
+    
+    mPickOptions |= F_FILE;
+
+    mPickOptions |= F_MULTIPLE;
+
+    return doNavChooseDialogModeless(filter, callback, userdata);
+}
+
 BOOL LLFilePicker::getSaveFile(ESaveFilter filter, const std::string& filename, bool blocking)
 {
 
diff --git a/indra/newview/llfilepicker.h b/indra/newview/llfilepicker.h
index 04ba4416d7ef2e379b0c40fa8749592bc6dd1e61..04adeb852639bb41b186adb93db73a3999bdb865 100644
--- a/indra/newview/llfilepicker.h
+++ b/indra/newview/llfilepicker.h
@@ -115,7 +115,11 @@ class LLFilePicker
 	// open the dialog. This is a modal operation
 	BOOL getSaveFile( ESaveFilter filter = FFSAVE_ALL, const std::string& filename = LLStringUtil::null, bool blocking = true);
 	BOOL getOpenFile( ELoadFilter filter = FFLOAD_ALL, bool blocking = true  );
+    // Todo: implement getOpenFileModeless and getMultipleOpenFilesModeless
+    // for windows and use directly instead of ugly LLFilePickerThread
+    BOOL getOpenFileModeless( ELoadFilter filter, void (*callback)(bool, std::vector<std::string> &, void*), void *userdata); // MAC only.
 	BOOL getMultipleOpenFiles( ELoadFilter filter = FFLOAD_ALL, bool blocking = true );
+    BOOL getMultipleOpenFilesModeless( ELoadFilter filter, void (*callback)(bool, std::vector<std::string> &, void*), void *userdata ); // MAC only
 
 	// Get the filename(s) found. getFirstFile() sets the pointer to
 	// the start of the structure and allows the start of iteration.
@@ -166,6 +170,7 @@ class LLFilePicker
 	std::vector<std::string> mFileVector;
 	
 	bool doNavChooseDialog(ELoadFilter filter);
+	bool doNavChooseDialogModeless(ELoadFilter filter, void (*callback)(bool, std::vector<std::string>&, void*), void *userdata);
 	bool doNavSaveDialog(ESaveFilter filter, const std::string& filename);
     std::vector<std::string>* navOpenFilterProc(ELoadFilter filter);
 #endif
diff --git a/indra/newview/llfilepicker_mac.h b/indra/newview/llfilepicker_mac.h
index e0b7e2e8ce01105c6004824087d46ffc944523d8..d6b69bb8564070d9c906fec0a4357e6aa5cc1020 100644
--- a/indra/newview/llfilepicker_mac.h
+++ b/indra/newview/llfilepicker_mac.h
@@ -41,6 +41,12 @@
 //void modelessPicker();
 std::vector<std::string>* doLoadDialog(const std::vector<std::string>* allowed_types, 
                  unsigned int flags);
+
+void doLoadDialogModeless(const std::vector<std::string>* allowed_types,
+                unsigned int flags,
+                void (*callback)(bool, std::vector<std::string>&, void*),
+                void *userdata);
+
 std::string* doSaveDialog(const std::string* file, 
                   const std::string* type,
                   const std::string* creator,
diff --git a/indra/newview/llfilepicker_mac.mm b/indra/newview/llfilepicker_mac.mm
index 1438e4dc0a993c69d23bae424a2b0363a0452bb2..f6892f40fade5e0e17d3f00343ae1793b347c0a8 100644
--- a/indra/newview/llfilepicker_mac.mm
+++ b/indra/newview/llfilepicker_mac.mm
@@ -29,27 +29,22 @@
 #include <iostream>
 #include "llfilepicker_mac.h"
 
-std::vector<std::string>* doLoadDialog(const std::vector<std::string>* allowed_types, 
-                 unsigned int flags)
+NSOpenPanel *init_panel(const std::vector<std::string>* allowed_types, unsigned int flags)
 {
-    int i, result;
-    
-    //Aura TODO:  We could init a small window and release it at the end of this routine
-    //for a modeless interface.
+    int i;
     
     NSOpenPanel *panel = [NSOpenPanel openPanel];
-    //NSString *fileName = nil;
     NSMutableArray *fileTypes = nil;
     
     
-    if ( allowed_types && !allowed_types->empty()) 
+    if ( allowed_types && !allowed_types->empty())
     {
         fileTypes = [[NSMutableArray alloc] init];
         
         for (i=0;i<allowed_types->size();++i)
         {
-            [fileTypes addObject: 
-             [NSString stringWithCString:(*allowed_types)[i].c_str() 
+            [fileTypes addObject:
+             [NSString stringWithCString:(*allowed_types)[i].c_str()
                                 encoding:[NSString defaultCStringEncoding]]];
         }
     }
@@ -62,21 +57,30 @@ std::vector<std::string>* doLoadDialog(const std::vector<std::string>* allowed_t
     [panel setCanChooseFiles: ( (flags & F_FILE)?true:false )];
     [panel setTreatsFilePackagesAsDirectories: ( flags & F_NAV_SUPPORT ) ];
     
-    std::vector<std::string>* outfiles = NULL; 
-    
     if (fileTypes)
     {
         [panel setAllowedFileTypes:fileTypes];
-        result = [panel runModal];
     }
-    else 
+    else
     {
         // I suggest it's better to open the last path and let this default to home dir as necessary
         // for consistency with other OS X apps
         //
         //[panel setDirectoryURL: fileURLWithPath(NSHomeDirectory()) ];
-        result = [panel runModal];
     }
+    return panel;
+}
+
+std::vector<std::string>* doLoadDialog(const std::vector<std::string>* allowed_types, 
+                 unsigned int flags)
+{
+    int result;
+    
+    NSOpenPanel *panel = init_panel(allowed_types,flags);
+    
+    result = [panel runModal];
+    
+    std::vector<std::string>* outfiles = NULL;
     
     if (result == NSOKButton) 
     {
@@ -97,6 +101,40 @@ std::vector<std::string>* doLoadDialog(const std::vector<std::string>* allowed_t
     return outfiles;
 }
 
+void doLoadDialogModeless(const std::vector<std::string>* allowed_types,
+                 unsigned int flags,
+                 void (*callback)(bool, std::vector<std::string> &, void*),
+                 void *userdata)
+{
+    // Note: might need to return and save this panel
+    // so that it does not close immediately
+    NSOpenPanel *panel = init_panel(allowed_types,flags);
+    
+    [panel beginWithCompletionHandler:^(NSModalResponse result)
+        {
+            if (result == NSOKButton)
+            {
+                std::vector<std::string> outfiles;
+                NSArray *filesToOpen = [panel URLs];
+                int i, count = [filesToOpen count];
+                
+                if (count > 0)
+                {
+                    
+                    for (i=0; i<count; i++) {
+                        NSString *aFile = [[filesToOpen objectAtIndex:i] path];
+                        std::string *afilestr = new std::string([aFile UTF8String]);
+                        outfiles.push_back(*afilestr);
+                    }
+                    callback(true, outfiles, userdata);
+                }
+                else
+                {
+                    callback(false, outfiles, userdata);
+                }
+            }
+        }];
+}
 
 std::string* doSaveDialog(const std::string* file, 
                   const std::string* type,
diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp
index fdf1d04c0961369e12afd28e413c6f3ed3511c59..259ae7c1fb0eebfcb3cb76167cec0d1248fa2f0d 100644
--- a/indra/newview/llviewermenufile.cpp
+++ b/indra/newview/llviewermenufile.cpp
@@ -124,6 +124,16 @@ void LLFilePickerThread::getFile()
 {
 #if LL_WINDOWS
 	start();
+#elif LL_DARWIN
+    if (!mIsSaveDialog)
+    {
+        runModeless();
+    }
+    else
+    {
+        // Todo: implement Modeless
+        run();
+    }
 #else
 	run();
 #endif
@@ -166,7 +176,70 @@ void LLFilePickerThread::run()
 		LLMutexLock lock(sMutex);
 		sDeadQ.push(this);
 	}
+}
+
+void LLFilePickerThread::runModeless()
+{
+    BOOL result = FALSE;
+    LLFilePicker picker;
 
+    if (mIsSaveDialog)
+    {
+        // TODO: not implemented
+        /*if (picker.getSaveFile(mSaveFilter, mProposedName, blocking))
+        {
+            mResponses.push_back(picker.getFirstFile());
+        }*/
+    }
+    else
+    {
+        if (mIsGetMultiple)
+        {
+            result = picker.getMultipleOpenFilesModeless(mLoadFilter, modelessCallback, this);
+        }
+        else
+        {
+            result = picker.getOpenFileModeless(mLoadFilter, modelessCallback, this);
+        }
+    }
+    
+    if (!result)
+    {
+        LLMutexLock lock(sMutex);
+        sDeadQ.push(this);
+    }
+}
+
+void LLFilePickerThread::modelessCallback(bool result,
+                                          std::vector<std::string> &responses,
+                                          void *user_data)
+{
+    LLFilePickerThread *picker = (LLFilePickerThread*)user_data;
+    if (result)
+    {
+        if (picker->mIsGetMultiple)
+        {
+            picker->mResponses = responses;
+        }
+        else
+        {
+            std::vector<std::string>::iterator iter = responses.begin();
+            while (iter != responses.end())
+            {
+                if (!iter->empty())
+                {
+                    picker->mResponses.push_back(*iter);
+                    break;
+                }
+                iter++;
+            }
+        }
+    }
+    
+    {
+        LLMutexLock lock(sMutex);
+        sDeadQ.push(picker);
+    }
 }
 
 //static
diff --git a/indra/newview/llviewermenufile.h b/indra/newview/llviewermenufile.h
index beeac418d9377945338cb22c1a7f0e072509e924..7cb2cf0d114961d32649cd0d3c0d09dac4c46ed6 100644
--- a/indra/newview/llviewermenufile.h
+++ b/indra/newview/llviewermenufile.h
@@ -105,6 +105,8 @@ class LLFilePickerThread : public LLThread
 	void getFile();
 
 	virtual void run();
+    void runModeless();
+    static void modelessCallback(bool result, std::vector<std::string> &responses, void *user_data);
 
 	virtual void notify(const std::vector<std::string>& filenames) = 0;
 };