diff --git a/indra/newview/llfloateropenobject.cpp b/indra/newview/llfloateropenobject.cpp
index 56a86c2cb72c09f03781150ae1e96c22611ee437..c1e8d251eeb50843cf6a49eface5b071df9b9203 100644
--- a/indra/newview/llfloateropenobject.cpp
+++ b/indra/newview/llfloateropenobject.cpp
@@ -72,11 +72,14 @@ LLFloaterOpenObject::~LLFloaterOpenObject()
 {
 //	sInstance = NULL;
 }
+
 // virtual
 BOOL LLFloaterOpenObject::postBuild()
 {
 	childSetTextArg("object_name", "[DESC]", std::string("Object") ); // *Note: probably do not want to translate this
 	mPanelInventoryObject = getChild<LLPanelObjectInventory>("object_contents");
+	
+	refresh();
 	return TRUE;
 }
 
@@ -95,29 +98,57 @@ void LLFloaterOpenObject::onOpen(const LLSD& key)
 		return;
 	}
 	mObjectSelection = LLSelectMgr::getInstance()->getEditSelection();
+	refresh();
 }
+
 void LLFloaterOpenObject::refresh()
 {
 	mPanelInventoryObject->refresh();
 
-	std::string name;
-	BOOL enabled;
+	std::string name = "";
+	
+	// Enable the copy || copy & wear buttons only if we have something we can copy or copy & wear (respectively).
+	bool copy_enabled = false;
+	bool wear_enabled = false;
 
 	LLSelectNode* node = mObjectSelection->getFirstRootNode();
-	if (node)
+	if (node) 
 	{
 		name = node->mName;
-		enabled = TRUE;
-	}
-	else
-	{
-		name = "";
-		enabled = FALSE;
+		copy_enabled = true;
+		
+		LLViewerObject* object = node->getObject();
+		if (object)
+		{
+			// this folder is coming from an object, as there is only one folder in an object, the root,
+			// we need to collect the entire contents and handle them as a group
+			InventoryObjectList inventory_objects;
+			object->getInventoryContents(inventory_objects);
+			
+			if (!inventory_objects.empty())
+			{
+				for (InventoryObjectList::iterator it = inventory_objects.begin(); 
+					 it != inventory_objects.end(); 
+					 ++it)
+				{
+					LLInventoryItem* item = static_cast<LLInventoryItem*> ((LLInventoryObject*)(*it));
+					LLInventoryType::EType type = item->getInventoryType();
+					if (type == LLInventoryType::IT_OBJECT 
+						|| type == LLInventoryType::IT_ATTACHMENT 
+						|| type == LLInventoryType::IT_WEARABLE
+						|| type == LLInventoryType::IT_GESTURE)
+					{
+						wear_enabled = true;
+						break;
+					}
+				}
+			}
+		}
 	}
 
 	childSetTextArg("object_name", "[DESC]", name);
-	childSetEnabled("copy_to_inventory_button", enabled);
-	childSetEnabled("copy_and_wear_button", enabled);
+	childSetEnabled("copy_to_inventory_button", copy_enabled);
+	childSetEnabled("copy_and_wear_button", wear_enabled);
 
 }
 
diff --git a/indra/newview/llpanelplaces.cpp b/indra/newview/llpanelplaces.cpp
index e21eb01da341ce4e884a077756daa964e703ef66..685104a8b1f10ae2257641e235c8bef6845760be 100644
--- a/indra/newview/llpanelplaces.cpp
+++ b/indra/newview/llpanelplaces.cpp
@@ -54,6 +54,7 @@
 #include "llavatarpropertiesprocessor.h"
 #include "llfloaterworldmap.h"
 #include "llinventorybridge.h"
+#include "llinventoryobserver.h"
 #include "llinventorymodel.h"
 #include "lllandmarkactions.h"
 #include "lllandmarklist.h"
@@ -62,6 +63,7 @@
 #include "llpanelpick.h"
 #include "llpanelplaceprofile.h"
 #include "llpanelteleporthistory.h"
+#include "llremoteparcelrequest.h"
 #include "llteleporthistorystorage.h"
 #include "lltoggleablemenu.h"
 #include "llviewerinventory.h"
@@ -85,8 +87,10 @@ static void onSLURLBuilt(std::string& slurl);
 class LLPlacesParcelObserver : public LLParcelObserver
 {
 public:
-	LLPlacesParcelObserver(LLPanelPlaces* places_panel)
-	: mPlaces(places_panel) {}
+	LLPlacesParcelObserver(LLPanelPlaces* places_panel) :
+		LLParcelObserver(),
+		mPlaces(places_panel)
+	{}
 
 	/*virtual*/ void changed()
 	{
@@ -101,8 +105,10 @@ class LLPlacesParcelObserver : public LLParcelObserver
 class LLPlacesInventoryObserver : public LLInventoryObserver
 {
 public:
-	LLPlacesInventoryObserver(LLPanelPlaces* places_panel)
-	: mPlaces(places_panel) {}
+	LLPlacesInventoryObserver(LLPanelPlaces* places_panel) :
+		LLInventoryObserver(),
+		mPlaces(places_panel)
+	{}
 
 	/*virtual*/ void changed(U32 mask)
 	{
@@ -114,6 +120,59 @@ class LLPlacesInventoryObserver : public LLInventoryObserver
 	LLPanelPlaces*		mPlaces;
 };
 
+class LLPlacesRemoteParcelInfoObserver : public LLRemoteParcelInfoObserver
+{
+public:
+	LLPlacesRemoteParcelInfoObserver(LLPanelPlaces* places_panel) :
+		LLRemoteParcelInfoObserver(),
+		mPlaces(places_panel)
+	{}
+
+	~LLPlacesRemoteParcelInfoObserver()
+	{
+		// remove any in-flight observers
+		std::set<LLUUID>::iterator it;
+		for (it = mParcelIDs.begin(); it != mParcelIDs.end(); ++it)
+		{
+			const LLUUID &id = *it;
+			LLRemoteParcelInfoProcessor::getInstance()->removeObserver(id, this);
+		}
+		mParcelIDs.clear();
+	}
+
+	/*virtual*/ void processParcelInfo(const LLParcelData& parcel_data)
+	{
+		if (mPlaces)
+		{
+			mPlaces->changedGlobalPos(LLVector3d(parcel_data.global_x,
+												 parcel_data.global_y,
+												 parcel_data.global_z));
+		}
+
+		mParcelIDs.erase(parcel_data.parcel_id);
+		LLRemoteParcelInfoProcessor::getInstance()->removeObserver(parcel_data.parcel_id, this);
+	}
+	/*virtual*/ void setParcelID(const LLUUID& parcel_id)
+	{
+		if (!parcel_id.isNull())
+		{
+			mParcelIDs.insert(parcel_id);
+			LLRemoteParcelInfoProcessor::getInstance()->addObserver(parcel_id, this);
+			LLRemoteParcelInfoProcessor::getInstance()->sendParcelInfoRequest(parcel_id);
+		}
+	}
+	/*virtual*/ void setErrorStatus(U32 status, const std::string& reason)
+	{
+		llerrs << "Can't complete remote parcel request. Http Status: "
+			   << status << ". Reason : " << reason << llendl;
+	}
+
+private:
+	std::set<LLUUID>	mParcelIDs;
+	LLPanelPlaces*		mPlaces;
+};
+
+
 static LLRegisterPanelClassWrapper<LLPanelPlaces> t_places("panel_places");
 
 LLPanelPlaces::LLPanelPlaces()
@@ -131,6 +190,7 @@ LLPanelPlaces::LLPanelPlaces()
 {
 	mParcelObserver = new LLPlacesParcelObserver(this);
 	mInventoryObserver = new LLPlacesInventoryObserver(this);
+	mRemoteParcelObserver = new LLPlacesRemoteParcelInfoObserver(this);
 
 	gInventory.addObserver(mInventoryObserver);
 
@@ -149,6 +209,7 @@ LLPanelPlaces::~LLPanelPlaces()
 
 	delete mInventoryObserver;
 	delete mParcelObserver;
+	delete mRemoteParcelObserver;
 }
 
 BOOL LLPanelPlaces::postBuild()
@@ -239,7 +300,6 @@ void LLPanelPlaces::onOpen(const LLSD& key)
 	mItem = NULL;
 	isLandmarkEditModeOn = false;
 	togglePlaceInfoPanel(TRUE);
-	updateVerbs();
 
 	if (mPlaceInfoType == AGENT_INFO_TYPE)
 	{
@@ -282,6 +342,10 @@ void LLPanelPlaces::onOpen(const LLSD& key)
 		{
 			LLUUID parcel_id = key["id"].asUUID();
 			mPlaceProfile->setParcelID(parcel_id);
+
+			// query the server to get the global 3D position of this
+			// parcel - we need this for teleport/mapping functions.
+			mRemoteParcelObserver->setParcelID(parcel_id);
 		}
 		else
 		{
@@ -306,6 +370,8 @@ void LLPanelPlaces::onOpen(const LLSD& key)
 		mPlaceProfile->displayParcelInfo(LLUUID(), mPosGlobal);
 	}
 
+	updateVerbs();
+
 	LLViewerParcelMgr* parcel_mgr = LLViewerParcelMgr::getInstance();
 	if (!parcel_mgr)
 		return;
@@ -837,6 +903,12 @@ void LLPanelPlaces::changedInventory(U32 mask)
 	gInventory.removeObserver(mInventoryObserver);
 }
 
+void LLPanelPlaces::changedGlobalPos(const LLVector3d &global_pos)
+{
+	mPosGlobal = global_pos;
+	updateVerbs();
+}
+
 void LLPanelPlaces::updateVerbs()
 {
 	bool is_place_info_visible;
@@ -853,6 +925,7 @@ void LLPanelPlaces::updateVerbs()
 
 	bool is_agent_place_info_visible = mPlaceInfoType == AGENT_INFO_TYPE;
 	bool is_create_landmark_visible = mPlaceInfoType == CREATE_LANDMARK_INFO_TYPE;
+	bool have_3d_pos = ! mPosGlobal.isExactlyZero();
 
 	mTeleportBtn->setVisible(!is_create_landmark_visible && !isLandmarkEditModeOn);
 	mShowOnMapBtn->setVisible(!is_create_landmark_visible && !isLandmarkEditModeOn);
@@ -862,7 +935,7 @@ void LLPanelPlaces::updateVerbs()
 	mCancelBtn->setVisible(isLandmarkEditModeOn);
 	mCloseBtn->setVisible(is_create_landmark_visible && !isLandmarkEditModeOn);
 
-	mShowOnMapBtn->setEnabled(!is_create_landmark_visible && !isLandmarkEditModeOn);
+	mShowOnMapBtn->setEnabled(!is_create_landmark_visible && !isLandmarkEditModeOn && have_3d_pos);
 	mOverflowBtn->setEnabled(is_place_info_visible && !is_create_landmark_visible);
 
 	if (is_place_info_visible)
@@ -871,12 +944,12 @@ void LLPanelPlaces::updateVerbs()
 		{
 			// We don't need to teleport to the current location
 			// so check if the location is not within the current parcel.
-			mTeleportBtn->setEnabled(!mPosGlobal.isExactlyZero() &&
+			mTeleportBtn->setEnabled(have_3d_pos &&
 									 !LLViewerParcelMgr::getInstance()->inAgentParcel(mPosGlobal));
 		}
 		else if (mPlaceInfoType == LANDMARK_INFO_TYPE || mPlaceInfoType == REMOTE_PLACE_INFO_TYPE)
 		{
-			mTeleportBtn->setEnabled(TRUE);
+			mTeleportBtn->setEnabled(have_3d_pos);
 		}
 	}
 	else
diff --git a/indra/newview/llpanelplaces.h b/indra/newview/llpanelplaces.h
index 5f9aed63571cf4bcb3e41a06551859a73f69ec39..5ee87049926cd55545d6538c9ebf44e37621b431 100644
--- a/indra/newview/llpanelplaces.h
+++ b/indra/newview/llpanelplaces.h
@@ -47,6 +47,7 @@ class LLPanelPlacesTab;
 class LLParcelSelection;
 class LLPlacesInventoryObserver;
 class LLPlacesParcelObserver;
+class LLRemoteParcelInfoObserver;
 class LLTabContainer;
 class LLToggleableMenu;
 
@@ -65,6 +66,8 @@ class LLPanelPlaces : public LLPanel
 	void changedParcelSelection();
 	// Called on agent inventory change to find out when inventory gets usable.
 	void changedInventory(U32 mask);
+	// Called when we receive the global 3D position of a parcel.
+	void changedGlobalPos(const LLVector3d &global_pos);
 
 	void setItem(LLInventoryItem* item);
 
@@ -112,6 +115,7 @@ class LLPanelPlaces : public LLPanel
 
 	LLPlacesInventoryObserver*	mInventoryObserver;
 	LLPlacesParcelObserver*		mParcelObserver;
+	LLRemoteParcelInfoObserver* mRemoteParcelObserver;
 
 	// Pointer to a landmark item or to a linked landmark
 	LLPointer<LLInventoryItem>	mItem;