diff --git a/pgadmin/dlg/dlgForeignServer.cpp b/pgadmin/dlg/dlgForeignServer.cpp
index 9bbf3a1..4b642cb 100644
--- a/pgadmin/dlg/dlgForeignServer.cpp
+++ b/pgadmin/dlg/dlgForeignServer.cpp
@@ -34,13 +34,11 @@
 
 dlgProperty *pgForeignServerFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent)
 {
-	return new dlgForeignServer(this, frame, (pgForeignServer *)node);
+	return new dlgForeignServer(this, frame, (pgForeignServer *)node, (pgForeignDataWrapper *)parent);
 }
 
 
 BEGIN_EVENT_TABLE(dlgForeignServer, dlgSecurityProperty)
-	EVT_TEXT(XRCID("cbForeignDataWrapper"),     dlgForeignServer::OnChange)
-	EVT_COMBOBOX(XRCID("cbForeignDataWrapper"), dlgForeignServer::OnChange)
 	EVT_LIST_ITEM_SELECTED(XRCID("lstOptions"), dlgForeignServer::OnSelChangeOption)
 	EVT_TEXT(XRCID("txtOption"),                dlgForeignServer::OnChangeOptionName)
 	EVT_BUTTON(wxID_ADD,                        dlgForeignServer::OnAddOption)
@@ -48,9 +46,10 @@ BEGIN_EVENT_TABLE(dlgForeignServer, dlgSecurityProperty)
 END_EVENT_TABLE();
 
 
-dlgForeignServer::dlgForeignServer(pgaFactory *f, frmMain *frame, pgForeignServer *node)
+dlgForeignServer::dlgForeignServer(pgaFactory *f, frmMain *frame, pgForeignServer *node, pgForeignDataWrapper *parent)
 	: dlgSecurityProperty(f, frame, node, wxT("dlgForeignServer"), wxT("USAGE"), "U")
 {
+    foreigndatawrapper = parent;
 	foreignserver = node;
 }
 
@@ -70,25 +69,6 @@ int dlgForeignServer::Go(bool modal)
 	AddGroups();
 	AddUsers(cbOwner);
 
-	// Fill validator combobox
-	if (!foreignserver)
-		cbForeignDataWrapper->Append(wxT(""));
-	pgSet *set = connection->ExecuteSet(
-	                 wxT("SELECT fdwname\n")
-	                 wxT("  FROM pg_foreign_data_wrapper\n")
-	                 wxT("  ORDER BY fdwname"));
-	if (set)
-	{
-		while (!set->Eof())
-		{
-			wxString fdwname = set->GetVal(wxT("fdwname"));
-			cbForeignDataWrapper->Append(fdwname);
-			set->MoveNext();
-		}
-		delete set;
-	}
-	cbForeignDataWrapper->SetSelection(0);
-
 	// Initialize options listview and buttons
 	lstOptions->AddColumn(_("Option"), 80);
 	lstOptions->AddColumn(_("Value"), 40);
@@ -106,8 +86,6 @@ int dlgForeignServer::Go(bool modal)
 		txtType->SetValue(foreignserver->GetType());
 		txtVersion->SetValue(foreignserver->GetVersion());
 
-		cbForeignDataWrapper->SetValue(foreignserver->GetFdw());
-
 		wxString options = foreignserver->GetOptions();
 		wxString option, optionname, optionvalue;
 		while (options.Length() > 0)
@@ -150,7 +128,7 @@ void dlgForeignServer::CheckChange()
 		            || cbOwner->GetValue() != foreignserver->GetOwner()
 		            || txtType->GetValue() != foreignserver->GetType()
 		            || txtVersion->GetValue() != foreignserver->GetVersion()
-		            || cbForeignDataWrapper->GetValue() != foreignserver->GetFdw();
+		            || GetOptionsSql().Length() > 0;
 		EnableOK(didChange);
 	}
 	else
@@ -158,7 +136,6 @@ void dlgForeignServer::CheckChange()
 		bool enable = true;
 
 		CheckValid(enable, !name.IsEmpty(), _("Please specify name."));
-		CheckValid(enable, !cbForeignDataWrapper->GetValue().IsEmpty(), _("Please specify foreign data wrapper."));
 		EnableOK(enable);
 	}
 }
@@ -328,7 +305,7 @@ wxString dlgForeignServer::GetSql()
 			sql += wxT("\n   TYPE ") + qtDbString(txtType->GetValue());
 		if (!(txtVersion->GetValue()).IsEmpty())
 			sql += wxT("\n   VERSION ") + qtDbString(txtVersion->GetValue());
-		sql += wxT("\n   FOREIGN DATA WRAPPER ") + qtIdent(cbForeignDataWrapper->GetValue());
+		sql += wxT("\n   FOREIGN DATA WRAPPER ") + qtIdent(foreigndatawrapper->GetName());
 
 		// check for options
 		if (lstOptions->GetItemCount() > 0)
diff --git a/pgadmin/dlg/dlgUserMapping.cpp b/pgadmin/dlg/dlgUserMapping.cpp
new file mode 100644
index 0000000..48edeeb
--- /dev/null
+++ b/pgadmin/dlg/dlgUserMapping.cpp
@@ -0,0 +1,319 @@
+//////////////////////////////////////////////////////////////////////////
+//
+// pgAdmin III - PostgreSQL Tools
+// RCS-ID:      $Id$
+// Copyright (C) 2002 - 2010, The pgAdmin Development Team
+// This software is released under the PostgreSQL Licence
+//
+// dlgUserMapping.cpp - PostgreSQL User Mapping Property
+//
+//////////////////////////////////////////////////////////////////////////
+
+// wxWindows headers
+#include <wx/wx.h>
+
+// App headers
+#include "pgAdmin3.h"
+#include "utils/misc.h"
+#include "utils/pgDefs.h"
+
+#include "dlg/dlgUserMapping.h"
+#include "schema/pgUserMapping.h"
+
+
+// pointer to controls
+#define cbUser               CTRL_COMBOBOX("cbUser")
+#define lstOptions           CTRL_LISTVIEW("lstOptions")
+#define txtOption            CTRL_TEXT("txtOption")
+#define txtValue             CTRL_TEXT("txtValue")
+#define btnAdd               CTRL_BUTTON("wxID_ADD")
+#define btnRemove            CTRL_BUTTON("wxID_REMOVE")
+
+
+dlgProperty *pgUserMappingFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent)
+{
+	return new dlgUserMapping(this, frame, (pgUserMapping *)node, (pgForeignServer *)parent);
+}
+
+
+BEGIN_EVENT_TABLE(dlgUserMapping, dlgProperty)
+	EVT_TEXT(XRCID("cbUser"),                   dlgUserMapping::OnChange)
+	EVT_COMBOBOX(XRCID("cbUser"),               dlgUserMapping::OnChange)
+	EVT_LIST_ITEM_SELECTED(XRCID("lstOptions"), dlgUserMapping::OnSelChangeOption)
+	EVT_TEXT(XRCID("txtOption"),                dlgUserMapping::OnChangeOptionName)
+	EVT_BUTTON(wxID_ADD,                        dlgUserMapping::OnAddOption)
+	EVT_BUTTON(wxID_REMOVE,                     dlgUserMapping::OnRemoveOption)
+END_EVENT_TABLE();
+
+
+dlgUserMapping::dlgUserMapping(pgaFactory *f, frmMain *frame, pgUserMapping *node, pgForeignServer *parent)
+	: dlgProperty(f, frame, wxT("dlgUserMapping"))
+{
+    foreignserver = parent;
+	usermapping = node;
+}
+
+
+pgObject *dlgUserMapping::GetObject()
+{
+	return usermapping;
+}
+
+
+int dlgUserMapping::Go(bool modal)
+{
+	// Fill user combobox
+	cbUser->Append(wxT("CURRENT_USER"));
+	cbUser->Append(wxT("PUBLIC"));
+	pgSet *set = connection->ExecuteSet(
+	                 wxT("SELECT rolname\n")
+	                 wxT("  FROM pg_roles\n")
+	                 wxT("  ORDER BY rolname"));
+	if (set)
+	{
+		while (!set->Eof())
+		{
+			wxString rolname = set->GetVal(wxT("rolname"));
+			cbUser->Append(rolname);
+			set->MoveNext();
+		}
+		delete set;
+	}
+	cbUser->SetSelection(0);
+
+	// Initialize options listview and buttons
+	lstOptions->AddColumn(_("Option"), 80);
+	lstOptions->AddColumn(_("Value"), 40);
+	txtOption->SetValue(wxT(""));
+	txtValue->SetValue(wxT(""));
+	btnAdd->Disable();
+	btnRemove->Disable();
+
+	if (usermapping)
+	{
+		// edit mode
+		cbUser->SetValue(usermapping->GetUsr());
+        cbUser->Disable();
+
+		wxString options = usermapping->GetOptions();
+		wxString option, optionname, optionvalue;
+		while (options.Length() > 0)
+		{
+			option = options.BeforeFirst(',');
+			optionname = option.BeforeFirst(wxT('=')).Trim(false).Trim();
+			optionvalue = option.AfterFirst(wxT('=')).Trim(false).Trim();
+			lstOptions->AppendItem(optionname, optionvalue);
+			options = options.AfterFirst(',');
+		}
+	}
+	else
+	{
+		// create mode
+	}
+
+	txtComment->Disable();
+
+	return dlgProperty::Go(modal);
+}
+
+
+pgObject *dlgUserMapping::CreateObject(pgCollection *collection)
+{
+	pgObject *obj = userMappingFactory.CreateObjects(collection, 0, wxT("\n   AND true")); //srvname ILIKE ") + qtDbString(name));
+	return obj;
+}
+
+
+void dlgUserMapping::CheckChange()
+{
+	bool didChange = true;
+	if (usermapping)
+	{
+		didChange = GetOptionsSql().Length() > 0;
+		EnableOK(didChange);
+	}
+	else
+	{
+		bool enable = true;
+
+		CheckValid(enable, !cbUser->GetValue().IsEmpty(), _("Please specify user."));
+		EnableOK(enable);
+	}
+}
+
+
+
+void dlgUserMapping::OnChange(wxCommandEvent &ev)
+{
+	CheckChange();
+}
+
+
+void dlgUserMapping::OnChangeOptionName(wxCommandEvent &ev)
+{
+	btnAdd->Enable(txtOption->GetValue().Length() > 0);
+}
+
+
+void dlgUserMapping::OnSelChangeOption(wxListEvent &ev)
+{
+	int row = lstOptions->GetSelection();
+	if (row >= 0)
+	{
+		txtOption->SetValue(lstOptions->GetText(row, 0));
+		txtValue->SetValue(lstOptions->GetText(row, 1));
+	}
+
+	btnRemove->Enable(row >= 0);
+}
+
+
+void dlgUserMapping::OnAddOption(wxCommandEvent &ev)
+{
+	bool found = false;
+
+	for (int pos = 0 ; pos < lstOptions->GetItemCount() ; pos++)
+	{
+		if (lstOptions->GetText(pos).IsSameAs(txtOption->GetValue(), false))
+		{
+			lstOptions->SetItem(pos, 1, txtValue->GetValue());
+			found = true;
+			break;
+		}
+	}
+
+	if (!found)
+	{
+		lstOptions->AppendItem(txtOption->GetValue(), txtValue->GetValue());
+	}
+
+	txtOption->SetValue(wxT(""));
+	txtValue->SetValue(wxT(""));
+	btnAdd->Disable();
+
+	CheckChange();
+}
+
+
+void dlgUserMapping::OnRemoveOption(wxCommandEvent &ev)
+{
+	int sel = lstOptions->GetSelection();
+	lstOptions->DeleteItem(sel);
+
+	txtOption->SetValue(wxT(""));
+	txtValue->SetValue(wxT(""));
+	btnRemove->Disable();
+
+	CheckChange();
+}
+
+
+wxString dlgUserMapping::GetOptionsSql()
+{
+	wxString options = usermapping->GetOptions();
+	wxString option, optionname, optionvalue, sqloptions;
+	bool found;
+	int pos;
+
+	while (options.Length() > 0)
+	{
+		option = options.BeforeFirst(',');
+		optionname = option.BeforeFirst(wxT('=')).Trim(false).Trim();
+		optionvalue = option.AfterFirst(wxT('=')).Trim(false).Trim();
+
+		// check for options
+		found = false;
+		for (pos = 0 ; pos < lstOptions->GetItemCount() && !found; pos++)
+		{
+			found = lstOptions->GetText(pos, 0).Cmp(optionname) == 0;
+			if (found) break;
+		}
+
+		if (found)
+		{
+			if (lstOptions->GetText(pos, 1).Cmp(optionvalue) != 0)
+			{
+				if (sqloptions.Length() > 0)
+					sqloptions += wxT(", ");
+				sqloptions += wxT("SET ") + optionname + wxT(" '") + lstOptions->GetText(pos, 1) + wxT("'");
+			}
+		}
+		else
+		{
+			if (sqloptions.Length() > 0)
+				sqloptions += wxT(", ");
+			sqloptions += wxT("DROP ") + optionname;
+		}
+
+		options = options.AfterFirst(',');
+	}
+
+	for (pos = 0 ; pos < lstOptions->GetItemCount() ; pos++)
+	{
+		options = usermapping->GetOptions();
+		found = false;
+
+		while (options.Length() > 0 && !found)
+		{
+			option = options.BeforeFirst(',');
+			optionname = option.BeforeFirst(wxT('=')).Trim(false).Trim();
+			found = lstOptions->GetText(pos, 0).Cmp(optionname) == 0;
+			options = options.AfterFirst(',');
+		}
+
+		if (!found)
+		{
+			optionvalue = option.AfterFirst(wxT('=')).Trim(false).Trim();
+
+			if (sqloptions.Length() > 0)
+				sqloptions += wxT(", ");
+			sqloptions += wxT("ADD ") + lstOptions->GetText(pos, 0) + wxT(" '") + lstOptions->GetText(pos, 1) + wxT("'");
+		}
+	}
+
+	return sqloptions;
+}
+
+
+wxString dlgUserMapping::GetSql()
+{
+	wxString sql;
+
+	if (usermapping)
+	{
+		// edit mode
+		wxString sqloptions = GetOptionsSql();
+		if (sqloptions.Length() > 0)
+		{
+			sql += wxT("ALTER USER MAPPING FOR ") + usermapping->GetUsr() + wxT(" SERVER ") + foreignserver->GetName()
+			       + wxT(" OPTIONS (") + sqloptions + wxT(");\n");
+		}
+	}
+	else
+	{
+		// create mode
+		sql = wxT("CREATE USER MAPPING FOR ") + cbUser->GetValue() + wxT(" SERVER ") + foreignserver->GetName();
+
+		// check for options
+		if (lstOptions->GetItemCount() > 0)
+		{
+			wxString options = wxEmptyString;
+			for (int pos = 0 ; pos < lstOptions->GetItemCount() ; pos++)
+			{
+				if (options.Length() > 0)
+					options += wxT(", ");
+
+				options += lstOptions->GetText(pos, 0)
+				           + wxT(" '") + lstOptions->GetText(pos, 1) + wxT("' ");
+			}
+			sql += wxT("\n  OPTIONS (") + options + wxT(")");
+		}
+
+		sql += wxT(";\n");
+	}
+
+	return sql;
+}
+
+
+
diff --git a/pgadmin/dlg/module.mk b/pgadmin/dlg/module.mk
index 2252957..6cb7766 100644
--- a/pgadmin/dlg/module.mk
+++ b/pgadmin/dlg/module.mk
@@ -54,6 +54,7 @@ pgadmin3_SOURCES += \
 	$(srcdir)/dlg/dlgTrigger.cpp \
 	$(srcdir)/dlg/dlgType.cpp \
 	$(srcdir)/dlg/dlgUser.cpp \
+	$(srcdir)/dlg/dlgUserMapping.cpp \
 	$(srcdir)/dlg/dlgView.cpp \
 	$(srcdir)/dlg/dlgManageMacros.cpp \
 	$(srcdir)/dlg/dlgExtTable.cpp \
diff --git a/pgadmin/include/dlg/dlgForeignServer.h b/pgadmin/include/dlg/dlgForeignServer.h
index ad64a53..fd77771 100644
--- a/pgadmin/include/dlg/dlgForeignServer.h
+++ b/pgadmin/include/dlg/dlgForeignServer.h
@@ -15,12 +15,13 @@
 
 #include "dlg/dlgProperty.h"
 
+class pgForeignDataWrapper;
 class pgForeignServer;
 
 class dlgForeignServer : public dlgSecurityProperty
 {
 public:
-	dlgForeignServer(pgaFactory *factory, frmMain *frame, pgForeignServer *_foreignserver);
+	dlgForeignServer(pgaFactory *factory, frmMain *frame, pgForeignServer *node, pgForeignDataWrapper *parent);
 	int Go(bool modal);
 
 	void CheckChange();
@@ -29,6 +30,7 @@ public:
 	pgObject *GetObject();
 
 private:
+    pgForeignDataWrapper *foreigndatawrapper;
 	pgForeignServer *foreignserver;
 
 #ifdef __WXMAC__
diff --git a/pgadmin/include/dlg/dlgUserMapping.h b/pgadmin/include/dlg/dlgUserMapping.h
new file mode 100644
index 0000000..9fff757
--- /dev/null
+++ b/pgadmin/include/dlg/dlgUserMapping.h
@@ -0,0 +1,53 @@
+//////////////////////////////////////////////////////////////////////////
+//
+// pgAdmin III - PostgreSQL Tools
+// RCS-ID:      $Id$
+// Copyright (C) 2002 - 2010, The pgAdmin Development Team
+// This software is released under the PostgreSQL Licence
+//
+// dlgUserMapping.h - User Mapping property
+//
+//////////////////////////////////////////////////////////////////////////
+
+
+#ifndef __DLG_USERMAPPINGPROP
+#define __DLG_USERMAPPINGPROP
+
+#include "dlg/dlgProperty.h"
+
+class pgForeignServer;
+class pgUserMapping;
+
+class dlgUserMapping : public dlgProperty
+{
+public:
+	dlgUserMapping(pgaFactory *factory, frmMain *frame, pgUserMapping *node, pgForeignServer *parent);
+	int Go(bool modal);
+
+	void CheckChange();
+	wxString GetSql();
+	pgObject *CreateObject(pgCollection *collection);
+	pgObject *GetObject();
+
+private:
+    pgForeignServer *foreignserver;
+	pgUserMapping *usermapping;
+
+#ifdef __WXMAC__
+	void OnChangeSize(wxSizeEvent &ev);
+#endif
+
+	void OnSelChangeOption(wxListEvent &ev);
+	void OnChange(wxCommandEvent &ev);
+	void OnChangeOptionName(wxCommandEvent &ev);
+	void OnAddOption(wxCommandEvent &ev);
+	void OnChangeOption(wxCommandEvent &ev);
+	void OnRemoveOption(wxCommandEvent &ev);
+
+	wxString GetOptionsSql();
+
+	DECLARE_EVENT_TABLE()
+};
+
+
+#endif
diff --git a/pgadmin/include/dlg/module.mk b/pgadmin/include/dlg/module.mk
index 4bf7cd1..9ac52af 100644
--- a/pgadmin/include/dlg/module.mk
+++ b/pgadmin/include/dlg/module.mk
@@ -54,6 +54,7 @@ pgadmin3_SOURCES += \
 	$(srcdir)/include/dlg/dlgTrigger.h \
 	$(srcdir)/include/dlg/dlgType.h \
 	$(srcdir)/include/dlg/dlgUser.h \
+	$(srcdir)/include/dlg/dlgUserMapping.h \
 	$(srcdir)/include/dlg/dlgView.h \
 	$(srcdir)/include/dlg/dlgManageMacros.h \
 	$(srcdir)/include/dlg/dlgExtTable.h \
diff --git a/pgadmin/include/images/usermapping-sm.png b/pgadmin/include/images/usermapping-sm.png
new file mode 100644
index 0000000..2467ccf
Binary files /dev/null and b/pgadmin/include/images/usermapping-sm.png differ
diff --git a/pgadmin/include/images/usermapping.png b/pgadmin/include/images/usermapping.png
new file mode 100644
index 0000000..acc1d95
Binary files /dev/null and b/pgadmin/include/images/usermapping.png differ
diff --git a/pgadmin/include/images/usermappings.png b/pgadmin/include/images/usermappings.png
new file mode 100644
index 0000000..b8b5104
Binary files /dev/null and b/pgadmin/include/images/usermappings.png differ
diff --git a/pgadmin/include/precomp.h b/pgadmin/include/precomp.h
index 82da403..c4c31da 100644
--- a/pgadmin/include/precomp.h
+++ b/pgadmin/include/precomp.h
@@ -111,6 +111,7 @@
 #include "dlg/dlgTrigger.h"
 #include "dlg/dlgType.h"
 #include "dlg/dlgUser.h"
+#include "dlg/dlgUserMapping.h"
 #include "dlg/dlgView.h"
 #include "dlg/dlgExtTable.h"
 
@@ -212,6 +213,7 @@
 #include "schema/pgTrigger.h"
 #include "schema/pgType.h"
 #include "schema/pgUser.h"
+#include "schema/pgUserMapping.h"
 #include "schema/pgView.h"
 #include "schema/gpExtTable.h"
 #include "schema/gpPartition.h"
diff --git a/pgadmin/include/schema/module.mk b/pgadmin/include/schema/module.mk
index e897e37..5a92db0 100644
--- a/pgadmin/include/schema/module.mk
+++ b/pgadmin/include/schema/module.mk
@@ -28,7 +28,7 @@ pgadmin3_SOURCES += \
 	$(srcdir)/include/schema/pgDomain.h \
 	$(srcdir)/include/schema/pgForeignDataWrapper.h \
 	$(srcdir)/include/schema/pgForeignKey.h \
-    $(subdir)/pgForeignServer.h \
+    $(srcdir)/include/schema/pgForeignServer.h \
 	$(srcdir)/include/schema/pgFunction.h \
 	$(srcdir)/include/schema/pgGroup.h \
 	$(srcdir)/include/schema/pgIndex.h \
@@ -52,6 +52,7 @@ pgadmin3_SOURCES += \
 	$(srcdir)/include/schema/pgTrigger.h \
 	$(srcdir)/include/schema/pgType.h \
 	$(srcdir)/include/schema/pgUser.h \
+	$(srcdir)/include/schema/pgUserMapping.h \
 	$(srcdir)/include/schema/pgView.h \
 	$(srcdir)/include/schema/gpExtTable.h \
 	$(srcdir)/include/schema/gpResQueue.h \
diff --git a/pgadmin/include/schema/pgCollection.h b/pgadmin/include/schema/pgCollection.h
index 9805704..cabef5b 100644
--- a/pgadmin/include/schema/pgCollection.h
+++ b/pgadmin/include/schema/pgCollection.h
@@ -21,6 +21,8 @@ class pgDatabase;
 class pgaJob;
 class pgSchema;
 class pgForeignDataWrapper;
+class pgForeignServer;
+class pgUserMapping;
 
 // Class declarations
 class pgCollection : public pgObject
@@ -51,6 +53,14 @@ public:
 	{
 		return fdw;
 	}
+	pgForeignServer *GetForeignServer() const
+	{
+		return fsrv;
+	}
+	pgUserMapping *GetUserMapping() const
+	{
+		return um;
+	}
 	pgaJob *GetJob() const
 	{
 		return job;
@@ -87,6 +97,8 @@ protected:
 	pgSchema *schema;
 	pgaJob *job;
 	pgForeignDataWrapper *fdw;
+    pgForeignServer *fsrv;
+    pgUserMapping *um;
 };
 
 
diff --git a/pgadmin/include/schema/pgForeignDataWrapper.h b/pgadmin/include/schema/pgForeignDataWrapper.h
index b37e511..1c5469a 100644
--- a/pgadmin/include/schema/pgForeignDataWrapper.h
+++ b/pgadmin/include/schema/pgForeignDataWrapper.h
@@ -89,7 +89,7 @@ public:
 class pgForeignDataWrapperObject : public pgDatabaseObject
 {
 public:
-	pgForeignDataWrapperObject(pgForeignDataWrapper *newForeignDataWrapper, pgaFactory &factory, const wxString &newName = wxEmptyString) : pgDatabaseObject(factory, newName)
+    pgForeignDataWrapperObject(pgForeignDataWrapper *newForeignDataWrapper, pgaFactory &factory, const wxString &newName = wxEmptyString) : pgDatabaseObject(factory, newName)
 	{
 		SetForeignDataWrapper(newForeignDataWrapper);
 	}
@@ -127,7 +127,7 @@ protected:
 class pgForeignDataWrapperObjCollection : public pgCollection
 {
 public:
-	pgForeignDataWrapperObjCollection(pgaFactory *factory, pgForeignDataWrapper *fdw);
+	pgForeignDataWrapperObjCollection(pgaFactory *factory, pgForeignDataWrapper *newfdw);
 	wxString GetTranslatedMessage(int kindOfMessage) const;
 	virtual bool CanCreate();
 };
diff --git a/pgadmin/include/schema/pgForeignServer.h b/pgadmin/include/schema/pgForeignServer.h
index 13f5c32..f462418 100644
--- a/pgadmin/include/schema/pgForeignServer.h
+++ b/pgadmin/include/schema/pgForeignServer.h
@@ -15,7 +15,6 @@
 #include "pgForeignDataWrapper.h"
 
 class pgCollection;
-
 class pgForeignServerFactory : public pgForeignDataWrapperObjFactory
 {
 public:
@@ -33,6 +32,7 @@ public:
 	wxString GetTranslatedMessage(int kindOfMessage) const;
 
 	void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0);
+	wxMenu *GetNewMenu();
 	bool CanDropCascaded()
 	{
 		return true;
@@ -41,15 +41,6 @@ public:
 	{
 		return true;
 	}
-
-	wxString GetFdw() const
-	{
-		return fdw;
-	}
-	void iSetFdw(const wxString &s)
-	{
-		fdw = s;
-	}
 	wxString GetType() const
 	{
 		return type;
@@ -94,13 +85,60 @@ public:
 	}
 
 private:
-	wxString fdw, type, version, options;
+	wxString type, version, options;
+};
+
+
+class pgForeignServerObjFactory : public pgForeignDataWrapperObjFactory
+{
+public:
+	pgForeignServerObjFactory(const wxChar *tn, const wxChar *ns, const wxChar *nls, wxImage *img, wxImage *imgSm = 0)
+		: pgForeignDataWrapperObjFactory(tn, ns, nls, img, imgSm) {}
+	virtual pgCollection *CreateCollection(pgObject *obj);
 };
 
-class pgForeignServerCollection : public pgForeignDataWrapperObjCollection
+
+// Object that lives in a foreign server
+class pgForeignServerObject : public pgForeignDataWrapperObject
+{
+public:
+	pgForeignServerObject(pgForeignServer *newForeignServer, pgaFactory &factory, const wxString &newName = wxEmptyString) : pgForeignDataWrapperObject(newForeignServer->GetForeignDataWrapper(), factory, newName)
+	{
+		SetForeignServer(newForeignServer);
+	}
+	pgForeignServerObject(pgForeignServer *newForeignServer, int newType, const wxString &newName = wxT("")) : pgForeignDataWrapperObject(newForeignServer->GetForeignDataWrapper(), newType, newName)
+	{
+		SetForeignServer(newForeignServer);
+	}
+
+	bool CanDrop();
+	bool CanEdit()
+	{
+		return true;
+	}
+	bool CanCreate();
+
+	void SetForeignServer(pgForeignServer *newForeignServer);
+	virtual pgForeignServer *GetForeignServer() const
+	{
+		return srv;
+	}
+	pgSet *ExecuteSet(const wxString &sql);
+	wxString ExecuteScalar(const wxString &sql);
+	bool ExecuteVoid(const wxString &sql);
+
+
+protected:
+	virtual void SetContextInfo(frmMain *form);
+
+	pgForeignServer *srv;
+};
+
+
+class pgForeignServerObjCollection : public pgCollection
 {
 public:
-	pgForeignServerCollection(pgaFactory *factory, pgSchema *sch);
+	pgForeignServerObjCollection(pgaFactory *factory, pgForeignServer *newsrv);
 	wxString GetTranslatedMessage(int kindOfMessage) const;
 };
 
diff --git a/pgadmin/include/schema/pgUserMapping.h b/pgadmin/include/schema/pgUserMapping.h
new file mode 100644
index 0000000..fc7db79
--- /dev/null
+++ b/pgadmin/include/schema/pgUserMapping.h
@@ -0,0 +1,99 @@
+//////////////////////////////////////////////////////////////////////////
+//
+// pgAdmin III - PostgreSQL Tools
+// RCS-ID:      $Id$
+// Copyright (C) 2002 - 2010, The pgAdmin Development Team
+// This software is released under the PostgreSQL Licence
+//
+// pgUserMapping.h PostgreSQL User Mapping
+//
+//////////////////////////////////////////////////////////////////////////
+
+#ifndef PGUSERMAPPING_H
+#define PGUSERMAPPING_H
+
+#include "pgForeignServer.h"
+
+class pgCollection;
+class pgUserMappingFactory : public pgForeignServerObjFactory
+{
+public:
+	pgUserMappingFactory();
+	virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent);
+	virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString);
+};
+extern pgUserMappingFactory userMappingFactory;
+
+
+class pgUserMapping : public pgForeignServerObject
+{
+public:
+	pgUserMapping(pgForeignServer *newForeignServer, const wxString &newName = wxT(""));
+	wxString GetTranslatedMessage(int kindOfMessage) const;
+
+	void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0);
+	bool CanDropCascaded()
+	{
+		return true;
+	}
+	bool CanCreate()
+	{
+		return true;
+	}
+
+	wxString GetUsr() const
+	{
+		return user;
+	}
+	void iSetUsr(const wxString &s)
+	{
+		user = s;
+	}
+	wxString GetOptions() const
+	{
+		return options;
+	}
+	wxString GetCreateOptions();
+	void iSetOptions(const wxString &s)
+	{
+		options = s;
+	}
+
+	bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded);
+	wxString GetSql(ctlTree *browser);
+	pgObject *Refresh(ctlTree *browser, const wxTreeItemId item);
+
+	bool HasStats()
+	{
+		return false;
+	}
+	bool HasDepends()
+	{
+		return true;
+	}
+	bool HasReferences()
+	{
+		return true;
+	}
+
+private:
+	wxString user, options;
+};
+
+class pgUserMappingObjFactory : public pgForeignServerObjFactory
+{
+public:
+	pgUserMappingObjFactory(const wxChar *tn, const wxChar *ns, const wxChar *nls, wxImage *img, wxImage *imgSm = 0)
+		: pgForeignServerObjFactory(tn, ns, nls, img, imgSm) {}
+	virtual pgCollection *CreateCollection(pgObject *obj);
+};
+
+
+class pgUserMappingCollection : public pgCollection
+{
+public:
+	pgUserMappingCollection(pgaFactory *factory, pgUserMapping *um);
+	wxString GetTranslatedMessage(int kindOfMessage) const;
+};
+
+#endif
diff --git a/pgadmin/include/utils/misc.h b/pgadmin/include/utils/misc.h
index 49ecb05..a301a13 100644
--- a/pgadmin/include/utils/misc.h
+++ b/pgadmin/include/utils/misc.h
@@ -209,6 +209,7 @@ enum
 	PGM_EXCLUDE,
 	PGM_FOREIGNKEY,
 	PGM_FOREIGNSERVER,
+	PGM_USERMAPPING,
 	PGM_FUNCTION,
 	PGM_INDEX,
 	PGM_OPCLASS,
diff --git a/pgadmin/schema/module.mk b/pgadmin/schema/module.mk
index bbcd106..8172c51 100644
--- a/pgadmin/schema/module.mk
+++ b/pgadmin/schema/module.mk
@@ -54,6 +54,7 @@ pgadmin3_SOURCES += \
         $(subdir)/pgTrigger.cpp \
         $(subdir)/pgType.cpp \
         $(subdir)/pgUser.cpp \
+        $(subdir)/pgUserMapping.cpp \
         $(subdir)/pgView.cpp \
         $(subdir)/gpExtTable.cpp \
         $(subdir)/gpResQueue.cpp \
diff --git a/pgadmin/schema/pgCollection.cpp b/pgadmin/schema/pgCollection.cpp
index 66dacc8..420f7ee 100644
--- a/pgadmin/schema/pgCollection.cpp
+++ b/pgadmin/schema/pgCollection.cpp
@@ -25,7 +25,9 @@
 pgCollection::pgCollection(pgaFactory *factory)
 	: pgObject(*factory)
 {
-	fdw = 0;
+    um = 0;
+	fsrv = 0;
+    fdw = 0;
 	job = 0;
 	schema = 0;
 	database = 0;
diff --git a/pgadmin/schema/pgForeignServer.cpp b/pgadmin/schema/pgForeignServer.cpp
index db1151d..60607a9 100644
--- a/pgadmin/schema/pgForeignServer.cpp
+++ b/pgadmin/schema/pgForeignServer.cpp
@@ -16,6 +16,7 @@
 #include "pgAdmin3.h"
 #include "utils/misc.h"
 #include "schema/pgForeignServer.h"
+#include "schema/pgUserMapping.h"
 #include "schema/pgDatatype.h"
 
 
@@ -75,7 +76,7 @@ wxString pgForeignServer::GetSql(ctlTree *browser)
 		sql = wxT("-- Server: ") + GetQuotedFullIdentifier() + wxT("\n\n")
 		      + wxT("-- DROP SERVER ") + GetQuotedFullIdentifier() + wxT(";")
 		      + wxT("\n\nCREATE SERVER ") + GetName()
-		      + wxT("\n   FOREIGN DATA WRAPPER ") + qtIdent(GetFdw());
+		      + wxT("\n   FOREIGN DATA WRAPPER ") + qtIdent(GetForeignDataWrapper()->GetName());
 
 		if (!GetType().IsEmpty())
 			sql += wxT("\n  TYPE ") + qtDbString(GetType());
@@ -96,6 +97,18 @@ wxString pgForeignServer::GetSql(ctlTree *browser)
 
 void pgForeignServer::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane)
 {
+	if (!expandedKids)
+	{
+		expandedKids = true;
+
+		browser->RemoveDummyChild(this);
+
+		// Log
+		wxLogInfo(wxT("Adding child object to foreign server %s"), GetIdentifier().c_str());
+
+		browser->AppendCollection(this, userMappingFactory);
+	}
+
 	if (properties)
 	{
 		CreateListColumns(properties);
@@ -104,7 +117,6 @@ void pgForeignServer::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListVie
 		properties->AppendItem(_("OID"), GetOid());
 		properties->AppendItem(_("Owner"), GetOwner());
 		properties->AppendItem(_("ACL"), GetAcl());
-		properties->AppendItem(_("Foreign Data Wrapper"), GetFdw());
 		properties->AppendItem(_("Type"), GetType());
 		properties->AppendItem(_("Version"), GetVersion());
 		properties->AppendItem(_("Options"), GetOptions());
@@ -118,12 +130,23 @@ pgObject *pgForeignServer::Refresh(ctlTree *browser, const wxTreeItemId item)
 	pgObject *fs = 0;
 	pgCollection *coll = browser->GetParentCollection(item);
 	if (coll)
-		fs = foreignServerFactory.CreateObjects(coll, 0, wxT("\n WHERE srv.oid=") + GetOidStr());
+		fs = foreignServerFactory.CreateObjects(coll, 0, wxT(" AND srv.oid=") + GetOidStr());
 
 	return fs;
 }
 
 
+wxMenu *pgForeignServer::GetNewMenu()
+{
+	wxMenu *menu = pgObject::GetNewMenu();
+	if (database->GetCreatePrivilege())
+	{
+		userMappingFactory.AppendMenu(menu);
+	}
+	return menu;
+}
+
+
 ////////////////////////////////////////////////////
 
 
@@ -138,6 +161,7 @@ pgObject *pgForeignServerFactory::CreateObjects(pgCollection *collection, ctlTre
 	      wxT("  FROM pg_foreign_server srv\n")
 	      wxT("  LEFT OUTER JOIN pg_foreign_data_wrapper fdw on fdw.oid=srvfdw\n")
 	      wxT("  LEFT OUTER JOIN pg_description des ON des.objoid=srv.oid AND des.objsubid=0\n")
+          wxT(" WHERE srvfdw = ") + collection->GetOidStr()
 	      + restriction + wxT("\n")
 	      wxT(" ORDER BY srvname");
 	pgSet *foreignservers = collection->GetDatabase()->ExecuteSet(sql);
@@ -148,7 +172,6 @@ pgObject *pgForeignServerFactory::CreateObjects(pgCollection *collection, ctlTre
 			fs = new pgForeignServer(collection->GetForeignDataWrapper(), foreignservers->GetVal(wxT("srvname")));
 			fs->iSetOid(foreignservers->GetOid(wxT("oid")));
 			fs->iSetOwner(foreignservers->GetVal(wxT("srvowner")));
-			fs->iSetFdw(foreignservers->GetVal(wxT("fdwname")));
 			fs->iSetAcl(foreignservers->GetVal(wxT("srvacl")));
 			fs->iSetComment(foreignservers->GetVal(wxT("description")));
 			fs->iSetType(foreignservers->GetVal(wxT("srvtype")));
@@ -196,7 +219,18 @@ wxString pgForeignServer::GetCreateOptions()
 
 /////////////////////////////
 
-wxString pgForeignServerCollection::GetTranslatedMessage(int kindOfMessage) const
+pgForeignServerObjCollection::pgForeignServerObjCollection(pgaFactory *factory, pgForeignServer *newsrv)
+	: pgCollection(factory)
+{
+    fsrv = newsrv;
+	fdw = fsrv->GetForeignDataWrapper();
+	database = fdw->GetDatabase();
+	server = database->GetServer();
+	iSetOid(fsrv->GetOid());
+}
+
+
+wxString pgForeignServerObjCollection::GetTranslatedMessage(int kindOfMessage) const
 {
 	wxString message = wxEmptyString;
 
@@ -213,6 +247,54 @@ wxString pgForeignServerCollection::GetTranslatedMessage(int kindOfMessage) cons
 	return message;
 }
 
+pgCollection *pgForeignServerObjFactory::CreateCollection(pgObject *obj)
+{
+	return new pgForeignServerObjCollection(GetCollectionFactory(), (pgForeignServer *)obj);
+}
+
+
+///////////////////////////////////////////////////////////////
+
+void pgForeignServerObject::SetForeignServer(pgForeignServer *newForeignServer)
+{
+	srv = newForeignServer;
+	database = fdw->GetDatabase();
+}
+
+bool pgForeignServerObject::CanDrop()
+{
+	return true; //fdw->GetCreatePrivilege();
+}
+
+
+bool pgForeignServerObject::CanCreate()
+{
+	return true; //fdw->GetCreatePrivilege();
+}
+
+
+void pgForeignServerObject::SetContextInfo(frmMain *form)
+{
+}
+
+
+pgSet *pgForeignServerObject::ExecuteSet(const wxString &sql)
+{
+	return srv->GetDatabase()->ExecuteSet(sql);
+}
+
+wxString pgForeignServerObject::ExecuteScalar(const wxString &sql)
+{
+	return srv->GetDatabase()->ExecuteScalar(sql);
+}
+
+
+bool pgForeignServerObject::ExecuteVoid(const wxString &sql)
+{
+	return srv->GetDatabase()->ExecuteVoid(sql);
+}
+
+
 ///////////////////////////////////////////////////
 
 #include "images/foreignserver.pngc"
diff --git a/pgadmin/schema/pgObject.cpp b/pgadmin/schema/pgObject.cpp
index 56faa73..2b7d8c6 100644
--- a/pgadmin/schema/pgObject.cpp
+++ b/pgadmin/schema/pgObject.cpp
@@ -35,6 +35,7 @@
 #include "schema/pgTablespace.h"
 #include "schema/pgGroup.h"
 #include "schema/pgUser.h"
+#include "schema/pgUserMapping.h"
 #include "schema/pgIndex.h"
 #include "schema/pgTrigger.h"
 #include "schema/pgCheck.h"
@@ -187,6 +188,8 @@ wxString pgObject::GetTranslatedMessage(int kindOfMessage) const
 		message = ((pgType *)this)->GetTranslatedMessage(kindOfMessage);
 	else if (type == wxT("User"))
 		message = ((pgUser *)this)->GetTranslatedMessage(kindOfMessage);
+	else if (type == wxT("User Mapping"))
+		message = ((pgUserMapping *)this)->GetTranslatedMessage(kindOfMessage);
 	else if (type == wxT("View"))
 		message = ((pgView *)this)->GetTranslatedMessage(kindOfMessage);
 
@@ -218,7 +221,7 @@ wxString pgObject::GetTranslatedMessage(int kindOfMessage) const
 		else if (type == wxT("Foreign Data Wrappers"))
 			message = ((pgForeignDataWrapperObjCollection *)this)->GetTranslatedMessage(kindOfMessage);
 		else if (type == wxT("Foreign Servers"))
-			message = ((pgForeignServerCollection *)this)->GetTranslatedMessage(kindOfMessage);
+			message = ((pgForeignServerObjCollection *)this)->GetTranslatedMessage(kindOfMessage);
 		else if (type == wxT("FTS Configurations"))
 			message = ((pgTextSearchConfigurationCollection *)this)->GetTranslatedMessage(kindOfMessage);
 		else if (type == wxT("FTS Dictionaries"))
@@ -282,6 +285,8 @@ wxString pgObject::GetTranslatedMessage(int kindOfMessage) const
 			message = ((pgTypeCollection *)this)->GetTranslatedMessage(kindOfMessage);
 		else if (type == wxT("Users"))
 			message = ((pgUserCollection *)this)->GetTranslatedMessage(kindOfMessage);
+		else if (type == wxT("User Mappings"))
+			message = ((pgUserMappingCollection *)this)->GetTranslatedMessage(kindOfMessage);
 		else if (type == wxT("Views"))
 			message = ((pgViewCollection *)this)->GetTranslatedMessage(kindOfMessage);
 	}
diff --git a/pgadmin/schema/pgUserMapping.cpp b/pgadmin/schema/pgUserMapping.cpp
new file mode 100644
index 0000000..d4efe03
--- /dev/null
+++ b/pgadmin/schema/pgUserMapping.cpp
@@ -0,0 +1,231 @@
+//////////////////////////////////////////////////////////////////////////
+//
+// pgAdmin III - PostgreSQL Tools
+// RCS-ID:      $Id$
+// Copyright (C) 2002 - 2010, The pgAdmin Development Team
+// This software is released under the PostgreSQL Licence
+//
+// pgUserMapping.cpp - User Mapping class
+//
+//////////////////////////////////////////////////////////////////////////
+
+// wxWindows headers
+#include <wx/wx.h>
+
+// App headers
+#include "pgAdmin3.h"
+#include "utils/misc.h"
+#include "schema/pgForeignServer.h"
+#include "schema/pgUserMapping.h"
+#include "schema/pgDatatype.h"
+
+
+pgUserMapping::pgUserMapping(pgForeignServer *newForeignServer, const wxString &newName)
+	: pgForeignServerObject(newForeignServer, userMappingFactory, newName)
+{
+}
+
+
+wxString pgUserMapping::GetTranslatedMessage(int kindOfMessage) const
+{
+	wxString message = wxEmptyString;
+
+	switch (kindOfMessage)
+	{
+		case RETRIEVINGDETAILS:
+			message = _("Retrieving details on user mapping");
+			message += wxT(" ") + GetName();
+			break;
+		case REFRESHINGDETAILS:
+			message = _("Refreshing user mapping");
+			message += wxT(" ") + GetName();
+			break;
+		case DROPINCLUDINGDEPS:
+			message = wxString::Format(_("Are you sure you wish to drop user mapping \"%s\" including all objects that depend on it?"),
+			                           GetFullIdentifier().c_str());
+			break;
+		case DROPEXCLUDINGDEPS:
+			message = wxString::Format(_("Are you sure you wish to drop user mapping \"%s?\""),
+			                           GetFullIdentifier().c_str());
+			break;
+		case DROPCASCADETITLE:
+			message = _("Drop user mapping cascaded?");
+			break;
+		case DROPTITLE:
+			message = _("Drop user mapping?");
+			break;
+	}
+
+	return message;
+}
+
+
+bool pgUserMapping::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded)
+{
+	wxString sql = wxT("DROP USER MAPPING FOR ") + GetUsr() + wxT(" SERVER ") + GetForeignServer()->GetName();
+	return GetDatabase()->ExecuteVoid(sql);
+}
+
+
+wxString pgUserMapping::GetSql(ctlTree *browser)
+{
+	if (sql.IsNull())
+	{
+		sql = wxT("-- Server: ") + GetQuotedFullIdentifier() + wxT("\n\n")
+		      + wxT("-- DROP USER MAPPING FOR ") + GetUsr() + wxT(" SERVER ") + GetForeignServer()->GetName() + wxT(";")
+		      + wxT("\n\nCREATE USER MAPPING ")
+		      + wxT("\n   FOR ") + qtIdent(GetUsr())
+		      + wxT("\n   SERVER ") + qtIdent(GetForeignServer()->GetName());
+
+		if (!GetOptions().IsEmpty())
+			sql += wxT("\n  OPTIONS (") + GetCreateOptions() + wxT(")");
+
+		sql += wxT(";\n");
+	}
+	return sql;
+}
+
+
+void pgUserMapping::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane)
+{
+	if (properties)
+	{
+		CreateListColumns(properties);
+
+		properties->AppendItem(_("Name"), GetName());
+		properties->AppendItem(_("OID"), GetOid());
+		properties->AppendItem(_("User"), GetUsr());
+		properties->AppendItem(_("Options"), GetOptions());
+	}
+}
+
+
+
+pgObject *pgUserMapping::Refresh(ctlTree *browser, const wxTreeItemId item)
+{
+	pgObject *um = 0;
+	pgCollection *coll = browser->GetParentCollection(item);
+	if (coll)
+		um = userMappingFactory.CreateObjects(coll, 0, wxT(" AND u.oid=") + GetOidStr());
+
+	return um;
+}
+
+
+////////////////////////////////////////////////////
+
+
+pgObject *pgUserMappingFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction)
+{
+	wxString sql;
+	pgUserMapping *um = 0;
+
+	sql = wxT("SELECT u.oid AS um_oid,\n")
+	      wxT("CASE WHEN u.umuser = 0::oid THEN 'public'::name ELSE a.rolname END AS usr_name,\n")
+          wxT("array_to_string(u.umoptions, ',') AS um_options\n")
+	      wxT("FROM pg_user_mapping u\n")
+	      wxT("  LEFT JOIN pg_authid a ON a.oid = u.umuser\n")
+          wxT(" WHERE u.umserver = ") + collection->GetOidStr()
+	      + restriction + wxT("\n")
+	      wxT("ORDER BY 2");
+	pgSet *usermappings = collection->GetDatabase()->ExecuteSet(sql);
+	if (usermappings)
+	{
+		while (!usermappings->Eof())
+		{
+			um = new pgUserMapping(collection->GetForeignServer(), usermappings->GetVal(wxT("usr_name")));
+			um->iSetOid(usermappings->GetOid(wxT("um_oid")));
+			um->iSetUsr(usermappings->GetVal(wxT("usr_name")));
+			um->iSetOptions(usermappings->GetVal(wxT("um_options")));
+
+			if (browser)
+			{
+				browser->AppendObject(collection, um);
+				usermappings->MoveNext();
+			}
+			else
+				break;
+		}
+
+		delete usermappings;
+	}
+
+	return um;
+}
+
+
+wxString pgUserMapping::GetCreateOptions()
+{
+	wxString options_create = wxEmptyString;
+	wxString opt;
+	wxString val;
+
+	wxStringTokenizer tkz_options(options, wxT(","));
+	while (tkz_options.HasMoreTokens())
+	{
+		wxStringTokenizer tkz_option(tkz_options.GetNextToken(), wxT("="));
+		opt = tkz_option.GetNextToken();
+		val = tkz_option.GetNextToken();
+
+		if (!options_create.IsEmpty())
+			options_create += wxT(",");
+
+		options_create += opt + wxT(" '") + val + wxT("'");
+	}
+
+	return options_create;
+}
+
+
+pgCollection *pgUserMappingObjFactory::CreateCollection(pgObject *obj)
+{
+	return new pgUserMappingCollection(GetCollectionFactory(), (pgUserMapping *)obj);
+}
+
+
+/////////////////////////////
+
+pgUserMappingCollection::pgUserMappingCollection(pgaFactory *factory, pgUserMapping *newum)
+	: pgCollection(factory)
+{
+    um = newum;
+    fsrv = um->GetForeignServer();
+	fdw = fsrv->GetForeignDataWrapper();
+	database = fdw->GetDatabase();
+	server = database->GetServer();
+	iSetOid(fsrv->GetOid());
+}
+
+
+wxString pgUserMappingCollection::GetTranslatedMessage(int kindOfMessage) const
+{
+	wxString message = wxEmptyString;
+
+	switch (kindOfMessage)
+	{
+		case RETRIEVINGDETAILS:
+			message = _("Retrieving details on user mappings");
+			break;
+		case REFRESHINGDETAILS:
+			message = _("Refreshing user mappings");
+			break;
+	}
+
+	return message;
+}
+
+///////////////////////////////////////////////////
+
+#include "images/usermapping.pngc"
+#include "images/usermapping-sm.pngc"
+#include "images/usermappings.pngc"
+
+pgUserMappingFactory::pgUserMappingFactory()
+	: pgForeignServerObjFactory(__("User Mapping"), __("New User Mapping..."),
+	                                 __("Create a new User Mapping."), usermapping_png_img, usermapping_sm_png_img)
+{
+}
+
+
+pgUserMappingFactory userMappingFactory;
+static pgaCollectionFactory cf(&userMappingFactory, __("User Mappings"), usermappings_png_img);
diff --git a/pgadmin/ui/dlgForeignServer.xrc b/pgadmin/ui/dlgForeignServer.xrc
index 9aea897..176aecb 100644
--- a/pgadmin/ui/dlgForeignServer.xrc
+++ b/pgadmin/ui/dlgForeignServer.xrc
@@ -17,10 +17,10 @@
             <object class="wxPanel" name="pnlProperties">
               <object class="wxFlexGridSizer">
                 <cols>2</cols>
-                <rows>8</rows>
+                <rows>7</rows>
                 <vgap>5</vgap>
                 <hgap>5</hgap>
-                <growablerows>6</growablerows>
+                <growablerows>5</growablerows>
                 <growablecols>1</growablecols>
                 <object class="sizeritem">
                   <object class="wxStaticText" name="stName">
@@ -67,22 +67,6 @@
                   <border>4</border>
                 </object>
                 <object class="sizeritem">
-                  <object class="wxStaticText" name="stForeignDataWrapper">
-                    <label>Foreign Data Wrapper</label>
-                  </object>
-                  <flag>wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT</flag>
-                  <border>4</border>
-                </object>
-                <object class="sizeritem">
-                  <object class="ctlComboBox" name="cbForeignDataWrapper">
-                    <size>135,-1d</size>
-                    <content/>
-                    <style>wxCB_DROPDOWN</style>
-                  </object>
-                  <flag>wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT</flag>
-                  <border>4</border>
-                </object>
-                <object class="sizeritem">
                   <object class="wxStaticText" name="stType">
                     <label>Type</label>
                   </object>
diff --git a/pgadmin/ui/dlgUserMapping.xrc b/pgadmin/ui/dlgUserMapping.xrc
new file mode 100644
index 0000000..17c8e6d
--- /dev/null
+++ b/pgadmin/ui/dlgUserMapping.xrc
@@ -0,0 +1,211 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<resource>
+  <object class="wxDialog" name="dlgUserMapping">
+    <title></title>
+    <size>220,250d</size>
+    <style>wxDEFAULT_DIALOG_STYLE|wxCAPTION|wxSYSTEM_MENU|wxRESIZE_BORDER|wxRESIZE_BOX|wxTHICK_FRAME</style>
+    <object class="wxFlexGridSizer">
+      <cols>1</cols>
+      <growablecols>0</growablecols>
+      <growablerows>0</growablerows>
+      <object class="sizeritem">
+        <object class="wxNotebook" name="nbNotebook">
+          <size>216,225d</size>
+          <selected>0</selected>
+          <object class="notebookpage">
+            <label>Properties</label>
+            <object class="wxPanel" name="pnlProperties">
+              <object class="wxFlexGridSizer">
+                <cols>2</cols>
+                <rows>3</rows>
+                <vgap>5</vgap>
+                <hgap>5</hgap>
+                <growablerows>1</growablerows>
+                <growablecols>1</growablecols>
+                <object class="sizeritem">
+                  <object class="wxStaticText" name="stUser">
+                    <label>User</label>
+                  </object>
+                  <flag>wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT</flag>
+                  <border>4</border>
+                </object>
+                <object class="sizeritem">
+                  <object class="ctlComboBox" name="cbUser">
+                    <size>135,-1d</size>
+                    <content/>
+                    <style>wxCB_DROPDOWN</style>
+                  </object>
+                  <flag>wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT</flag>
+                  <border>4</border>
+                </object>
+                <object class="sizeritem">
+                  <object class="wxStaticText" name="stComment">
+                    <label>Comment</label>
+                  </object>
+                  <flag>wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT</flag>
+                  <border>4</border>
+                </object>
+                <object class="sizeritem">
+                  <object class="wxTextCtrl" name="txtComment">
+                    <size>135,-1d</size>
+                    <style>wxTE_MULTILINE</style>
+                  </object>
+                  <flag>wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT</flag>
+                  <border>4</border>
+                </object>
+                <object class="sizeritem">
+                  <object class="wxStaticText" name="stClusterSet">
+                    <label>Use replication</label>
+                  </object>
+                  <flag>wxALIGN_CENTRE_VERTICAL|wxALL</flag>
+                  <border>4</border>
+                </object>
+                <object class="sizeritem">
+                  <object class="wxComboBox" name="cbClusterSet">
+                    <content/>
+                    <size>135,-1d</size>
+                    <style>wxCB_READONLY|wxCB_DROPDOWN</style>
+                  </object>
+                  <flag>wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL</flag>
+                  <border>4</border>
+                </object>
+              </object>
+            </object>
+          </object>
+          <object class="notebookpage">
+            <label>Options</label>
+            <object class="wxPanel" name="pnlOptions">
+              <object class="wxFlexGridSizer">
+                <cols>1</cols>
+                <rows>3</rows>
+                <growablerows>0</growablerows>
+                <growablecols>0</growablecols>
+                <object class="sizeritem">
+                  <object class="wxListCtrl" name="lstOptions">
+                    <pos>70,15d</pos>
+                    <style>wxLC_REPORT|wxLC_SINGLE_SEL</style>
+                  </object>
+                  <option>80</option>
+                  <flag>wxALL|wxEXPAND</flag>
+                  <border>5</border>
+                </object>
+                <object class="sizeritem">
+                  <object class="wxFlexGridSizer">
+                    <cols>2</cols>
+                    <rows>2</rows>
+                    <vgap>5</vgap>
+                    <hgap>5</hgap>
+                    <growablecols>1</growablecols>
+                    <object class="sizeritem">
+                      <object class="wxStaticText" name="stOption">
+                        <label>Option</label>
+                      </object>
+                      <flag>wxALIGN_CENTRE_VERTICAL</flag>
+                    </object>
+                    <object class="sizeritem">
+                      <object class="wxTextCtrl" name="txtOption">
+                        <size>135,-1d</size>
+                      </object>
+                      <flag>wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT</flag>
+                      <border>4</border>
+                      <flag>wxEXPAND|wxALIGN_CENTRE_VERTICAL</flag>
+                    </object>
+                    <object class="sizeritem">
+                      <object class="wxStaticText" name="stValue">
+                        <label>Value</label>
+                      </object>
+                      <flag>wxALIGN_CENTRE_VERTICAL</flag>
+                    </object>
+                    <object class="sizeritem">
+                      <object class="wxTextCtrl" name="txtValue">
+                        <size>135,-1d</size>
+                      </object>
+                      <flag>wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT</flag>
+                      <border>4</border>
+                      <flag>wxEXPAND|wxALIGN_CENTRE_VERTICAL</flag>
+                    </object>
+                  </object>
+                  <flag>wxALL|wxEXPAND|wxALIGN_BOTTOM|wxALIGN_CENTRE_HORIZONTAL</flag>
+                  <border>5</border>
+                </object>
+                <object class="sizeritem">
+                  <object class="wxFlexGridSizer">
+                    <cols>2</cols>
+                    <rows>1</rows>
+                    <object class="sizeritem">
+                      <object class="wxButton" name="wxID_REMOVE">
+                        <label>Remove</label>
+                        <pos>13,58d</pos>
+                      </object>
+                      <flag>wxALL|wxALIGN_RIGHT</flag>
+                      <border>2</border>
+                    </object>
+                    <object class="sizeritem">
+                      <object class="wxButton" name="wxID_ADD">
+                        <label>Add/Change</label>
+                        <pos>13,78d</pos>
+                      </object>
+                      <flag>wxALL|wxALIGN_RIGHT</flag>
+                      <border>2</border>
+                    </object>
+                  </object>
+                  <flag>wxALIGN_RIGHT</flag>
+                </object>
+              </object>
+            </object>
+          </object>
+        </object>
+        <flag>wxALL|wxGROW|wxALIGN_CENTRE</flag>
+        <border>3</border>
+      </object>
+      <object class="spacer">
+        <size>2,2d</size>
+      </object>
+      <object class="sizeritem">
+        <object class="wxFlexGridSizer">
+          <cols>7</cols>
+          <growablecols>2</growablecols>
+          <object class="spacer">
+            <size>3,3d</size>
+          </object>
+          <object class="sizeritem">
+            <object class="wxButton" name="wxID_HELP">
+              <label>Help</label>
+            </object>
+          </object>
+          <object class="spacer">
+            <size>3,3d</size>
+          </object>
+          <object class="sizeritem">
+            <object class="wxButton" name="wxID_OK">
+              <label>&amp;OK</label>
+              <default>1</default>
+            </object>
+          </object>
+          <object class="spacer">
+            <size>3,3d</size>
+          </object>
+          <object class="sizeritem">
+            <object class="wxButton" name="wxID_CANCEL">
+              <label>&amp;Cancel</label>
+            </object>
+          </object>
+          <object class="spacer">
+            <size>3,3d</size>
+          </object>
+        </object>
+        <flag>wxTOP|wxLEFT|wxRIGHT|wxGROW</flag>
+      </object>
+      <object class="spacer">
+        <size>3,3d</size>
+      </object>
+      <object class="sizeritem">
+        <object class="wxStatusBar" name="unkStatusBar">
+          <style>wxST_SIZEGRIP</style>
+        </object>
+        <flag>wxGROW|wxALIGN_CENTRE</flag>
+        <border>3</border>
+      </object>
+    </object>
+  </object>
+</resource>
diff --git a/pgadmin/ui/module.mk b/pgadmin/ui/module.mk
index 79da290..a1d2ca6 100644
--- a/pgadmin/ui/module.mk
+++ b/pgadmin/ui/module.mk
@@ -72,6 +72,7 @@ TMP_ui += \
 	$(srcdir)/ui/dlgTrigger.xrc \
 	$(srcdir)/ui/dlgType.xrc \
 	$(srcdir)/ui/dlgUser.xrc \
+	$(srcdir)/ui/dlgUserMapping.xrc \
 	$(srcdir)/ui/dlgView.xrc \
 	$(srcdir)/ui/frmBackup.xrc \
 	$(srcdir)/ui/frmBackupGlobals.xrc \