diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 768fdd410303ba493570a3236a47e0413d8b8404..7254fff664a6a0e64f2b15cca2cc55e04102b11d 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -5558,6 +5558,17 @@
       <key>Value</key>
       <integer>1</integer>
     </map>
+    <key>RegInClient</key>
+    <map>
+      <key>Comment</key>
+      <string>Experimental: Embed registration in login screen</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>0</integer>
+    </map>
     <key>RegionTextureSize</key>
     <map>
       <key>Comment</key>
diff --git a/indra/newview/llloginhandler.cpp b/indra/newview/llloginhandler.cpp
index 6f0b8a3c1e6a0d25cf3128845b647159a6d28367..2a1f42c3c4bf2828ebe43a0514c68ba2b7478cfe 100644
--- a/indra/newview/llloginhandler.cpp
+++ b/indra/newview/llloginhandler.cpp
@@ -56,7 +56,7 @@ bool LLLoginHandler::parseDirectLogin(std::string url)
 	LLURI uri(url);
 	parse(uri.queryMap());
 
-	if (mWebLoginKey.isNull() ||
+	if (/*mWebLoginKey.isNull() ||*/
 		mFirstName.empty() ||
 		mLastName.empty())
 	{
@@ -71,7 +71,7 @@ bool LLLoginHandler::parseDirectLogin(std::string url)
 
 void LLLoginHandler::parse(const LLSD& queryMap)
 {
-	mWebLoginKey = queryMap["web_login_key"].asUUID();
+	//mWebLoginKey = queryMap["web_login_key"].asUUID();
 	mFirstName = queryMap["first_name"].asString();
 	mLastName = queryMap["last_name"].asString();
 	
@@ -165,7 +165,15 @@ void LLLoginHandler::parse(const LLSD& queryMap)
 bool LLLoginHandler::handle(const LLSD& tokens,
 							const LLSD& query_map,
 							LLMediaCtrl* web)
-{	
+{
+	if (tokens.size() == 1
+		&& tokens[0].asString() == "show")
+	{
+		// We're using reg-in-client, so show the XUI login widgets
+		LLPanelLogin::showLoginWidgets();
+		return true;
+	}
+
 	parse(query_map);
 	
 	//if we haven't initialized stuff yet, this is 
@@ -200,14 +208,15 @@ bool LLLoginHandler::handle(const LLSD& tokens,
 			LLPanelLogin::setFields(mFirstName, mLastName, password);
 		}
 
-		if (mWebLoginKey.isNull())
-		{
-			LLPanelLogin::loadLoginPage();
-		}
-		else
-		{
-			LLStartUp::setStartupState( STATE_LOGIN_CLEANUP );
-		}
+		//if (mWebLoginKey.isNull())
+		//{
+		//	LLPanelLogin::loadLoginPage();
+		//}
+		//else
+		//{
+		//	LLStartUp::setStartupState( STATE_LOGIN_CLEANUP );
+		//}
+		LLStartUp::setStartupState( STATE_LOGIN_CLEANUP );
 	}
 	return true;
 }
diff --git a/indra/newview/llloginhandler.h b/indra/newview/llloginhandler.h
index d36ceaf3cc05564cb88c913bb03ddbafb2d103cc..ac4648761b2a447c27bee3e142819059f8bd603e 100644
--- a/indra/newview/llloginhandler.h
+++ b/indra/newview/llloginhandler.h
@@ -48,7 +48,9 @@ class LLLoginHandler : public LLCommandHandler
 
 	std::string getFirstName() const { return mFirstName; }
 	std::string getLastName() const { return mLastName; }
-	LLUUID getWebLoginKey() const { return mWebLoginKey; }
+
+	// Web-based login unsupported
+	//LLUUID getWebLoginKey() const { return mWebLoginKey; }
 
 private:
 	void parse(const LLSD& queryMap);
@@ -56,7 +58,7 @@ class LLLoginHandler : public LLCommandHandler
 private:
 	std::string mFirstName;
 	std::string mLastName;
-	LLUUID mWebLoginKey;
+	//LLUUID mWebLoginKey;
 };
 
 extern LLLoginHandler gLoginHandler;
diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp
index 24e76e2c6e0e64c8282e5e7d4bd842a0c5bb8ee6..5d826f0a561c895cc1c0e99ff12915c46db17266 100644
--- a/indra/newview/llpanellogin.cpp
+++ b/indra/newview/llpanellogin.cpp
@@ -198,7 +198,16 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
 	//leave room for the login menu bar
 	setRect(LLRect(0, rect.getHeight()-18, rect.getWidth(), 0)); 
 #endif
-	reshape(rect.getWidth(), rect.getHeight());
+	// Legacy login web page is hidden under the menu bar.
+	// Adjust reg-in-client web browser widget to not be hidden.
+	if (gSavedSettings.getBOOL("RegInClient"))
+	{
+		reshape(rect.getWidth(), rect.getHeight() - MENU_BAR_HEIGHT);
+	}
+	else
+	{
+		reshape(rect.getWidth(), rect.getHeight());
+	}
 
 #if !USE_VIEWER_AUTH
 	childSetPrevalidate("first_name_edit", LLLineEditor::prevalidatePrintableNoSpace);
@@ -234,9 +243,7 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
 
 	childSetAction("connect_btn", onClickConnect, this);
 
-	setDefaultBtn("connect_btn");
-
-	// childSetAction("quit_btn", onClickQuit, this);
+	getChild<LLPanel>("login_widgets")->setDefaultBtn("connect_btn");
 
 	std::string channel = gSavedSettings.getString("VersionChannelName");
 	std::string version = llformat("%d.%d.%d (%d)",
@@ -267,19 +274,20 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
 	web_browser->setTabStop(FALSE);
 	// web_browser->navigateToLocalPage( "loading", "loading.html" );
 
-	// make links open in external browser
-	web_browser->setOpenInExternalBrowser( true );
+	if (gSavedSettings.getBOOL("RegInClient"))
+	{
+		// need to follow links in the internal browser
+		web_browser->setOpenInExternalBrowser( false );
 
-	// force the size to be correct (XML doesn't seem to be sufficient to do this) (with some padding so the other login screen doesn't show through)
-	LLRect htmlRect = getRect();
-#if USE_VIEWER_AUTH
-	htmlRect.setCenterAndSize( getRect().getCenterX() - 2, getRect().getCenterY(), getRect().getWidth() + 6, getRect().getHeight());
-#else
-	htmlRect.setCenterAndSize( getRect().getCenterX() - 2, getRect().getCenterY() + 40, getRect().getWidth() + 6, getRect().getHeight() - 78 );
-#endif
-	web_browser->setRect( htmlRect );
-	web_browser->reshape( htmlRect.getWidth(), htmlRect.getHeight(), TRUE );
-	reshape( getRect().getWidth(), getRect().getHeight(), 1 );
+		getChild<LLView>("login_widgets")->setVisible(false);
+	}
+	else
+	{
+		// make links open in external browser
+		web_browser->setOpenInExternalBrowser( true );
+
+		reshapeBrowser();
+	}
 
 	// kick off a request to grab the url manually
 	gResponsePtr = LLIamHereLogin::build( this );
@@ -297,6 +305,27 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
 
 }
 
+// force the size to be correct (XML doesn't seem to be sufficient to do this)
+// (with some padding so the other login screen doesn't show through)
+void LLPanelLogin::reshapeBrowser()
+{
+	LLMediaCtrl* web_browser = getChild<LLMediaCtrl>("login_html");
+	LLRect rect = gViewerWindow->getVirtualWindowRect();
+	LLRect html_rect;
+#if USE_VIEWER_AUTH
+	html_rect.setCenterAndSize( 
+		rect.getCenterX() - 2, rect.getCenterY(), 
+		rect.getWidth() + 6, rect.getHeight());
+#else
+	html_rect.setCenterAndSize(
+		rect.getCenterX() - 2, rect.getCenterY() + 40,
+		rect.getWidth() + 6, rect.getHeight() - 78 );
+#endif
+	web_browser->setRect( html_rect );
+	web_browser->reshape( html_rect.getWidth(), html_rect.getHeight(), TRUE );
+	reshape( rect.getWidth(), rect.getHeight(), 1 );
+}
+
 void LLPanelLogin::setSiteIsAlive( bool alive )
 {
 	LLMediaCtrl* web_browser = getChild<LLMediaCtrl>("login_html");
@@ -384,10 +413,14 @@ void LLPanelLogin::draw()
 		if ( mHtmlAvailable )
 		{
 #if !USE_VIEWER_AUTH
-			// draw a background box in black
-			gl_rect_2d( 0, height - 264, width, 264, LLColor4( 0.0f, 0.0f, 0.0f, 1.f ) );
-			// draw the bottom part of the background image - just the blue background to the native client UI
-			mLogoImage->draw(0, -264, width + 8, mLogoImage->getHeight());
+			if (getChild<LLView>("login_widgets")->getVisible())
+			{
+				// draw a background box in black
+				gl_rect_2d( 0, height - 264, width, 264, LLColor4::black );
+				// draw the bottom part of the background image
+				// just the blue background to the native client UI
+				mLogoImage->draw(0, -264, width + 8, mLogoImage->getHeight());
+			}
 #endif
 		}
 		else
@@ -418,12 +451,6 @@ BOOL LLPanelLogin::handleKeyHere(KEY key, MASK mask)
 		return TRUE;
 	}
 
-	if (KEY_RETURN == key && MASK_NONE == mask)
-	{
-		// let the panel handle UICtrl processing: calls onClickConnect()
-		return LLPanel::handleKeyHere(key, mask);
-	}
-
 	return LLPanel::handleKeyHere(key, mask);
 }
 
@@ -483,6 +510,19 @@ void LLPanelLogin::giveFocus()
 #endif
 }
 
+// static
+void LLPanelLogin::showLoginWidgets()
+{
+	sInstance->childSetVisible("login_widgets", true);
+	LLMediaCtrl* web_browser = sInstance->getChild<LLMediaCtrl>("login_html");
+	web_browser->setOpenInExternalBrowser( true );
+	sInstance->reshapeBrowser();
+	// *TODO: Append all the usual login parameters, like first_login=Y etc.
+	std::string splash_screen_url = sInstance->getString("real_url");
+	web_browser->navigateTo( splash_screen_url, "text/html" );
+	LLUICtrl* first_name_edit = sInstance->getChild<LLUICtrl>("first_name_edit");
+	first_name_edit->setFocus(TRUE);
+}
 
 // static
 void LLPanelLogin::show(const LLRect &rect,
@@ -797,8 +837,17 @@ void LLPanelLogin::loadLoginPage()
 	
 	LLMediaCtrl* web_browser = sInstance->getChild<LLMediaCtrl>("login_html");
 	
-	// navigate to the "real" page 
-	web_browser->navigateTo( oStr.str(), "text/html" );
+	// navigate to the "real" page
+	if (gSavedSettings.getBOOL("RegInClient"))
+	{
+		web_browser->setFocus(TRUE);
+		login_page = sInstance->getString("reg_in_client_url");
+		web_browser->navigateTo(login_page, "text/html");
+	}
+	else
+	{
+		web_browser->navigateTo( oStr.str(), "text/html" );
+	}
 }
 
 void LLPanelLogin::handleMediaEvent(LLPluginClassMedia* /*self*/, EMediaEvent event)
@@ -883,22 +932,6 @@ void LLPanelLogin::onClickNewAccount(void*)
 }
 
 
-// *NOTE: This function is dead as of 2008 August.  I left it here in case
-// we suddenly decide to put the Quit button back. JC
-// static
-void LLPanelLogin::onClickQuit(void*)
-{
-	if (sInstance && sInstance->mCallback)
-	{
-		// tell the responder we're not here anymore
-		if ( gResponsePtr )
-			gResponsePtr->setParent( 0 );
-
-		sInstance->mCallback(1, sInstance->mCallbackData);
-	}
-}
-
-
 // static
 void LLPanelLogin::onClickVersion(void*)
 {
diff --git a/indra/newview/llpanellogin.h b/indra/newview/llpanellogin.h
index 5692b8d345a392365c75deea1dc1e3364799c4a2..acb2001c22f186ede7afec2017c6b062cdbc45a0 100644
--- a/indra/newview/llpanellogin.h
+++ b/indra/newview/llpanellogin.h
@@ -56,6 +56,10 @@ class LLPanelLogin:
 	virtual void draw();
 	virtual void setFocus( BOOL b );
 
+	// Show the XUI first name, last name, and password widgets.  They are
+	// hidden on startup for reg-in-client
+	static void showLoginWidgets();
+
 	static void show(const LLRect &rect, BOOL show_server, 
 		void (*callback)(S32 option, void* user_data), 
 		void* callback_data);
@@ -86,10 +90,10 @@ class LLPanelLogin:
 	/*virtual*/ void handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event);
 
 private:
+	void reshapeBrowser();
 	static void onClickConnect(void*);
 	static void onClickNewAccount(void*);
 //	static bool newAccountAlertCallback(const LLSD& notification, const LLSD& response);
-	static void onClickQuit(void*);
 	static void onClickVersion(void*);
 	static void onClickForgotPassword(void*);
 	static void onPassKey(LLLineEditor* caller, void* user_data);
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 9aa74e8b9f90c39ebdda57db4dc1ae8120d963d5..9bdea57491a0159bcb674f764a8837518c845b9a 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -738,7 +738,7 @@ bool idle_startup()
 		}
 		if (!gLoginHandler.getFirstName().empty()
 			|| !gLoginHandler.getLastName().empty()
-			|| !gLoginHandler.getWebLoginKey().isNull() )
+			/*|| !gLoginHandler.getWebLoginKey().isNull()*/ )
 		{
 			// We have at least some login information on a SLURL
 			gFirstname = gLoginHandler.getFirstName();
@@ -895,13 +895,9 @@ bool idle_startup()
 		gViewerWindow->moveProgressViewToFront();
 
 		//reset the values that could have come in from a slurl
-		if (!gLoginHandler.getWebLoginKey().isNull())
-		{
-			gFirstname = gLoginHandler.getFirstName();
-			gLastname = gLoginHandler.getLastName();
-//			gWebLoginKey = gLoginHandler.getWebLoginKey();
-		}
-				
+		gFirstname = gLoginHandler.getFirstName();
+		gLastname = gLoginHandler.getLastName();
+
 		if (show_connect_box)
 		{
 			// TODO if not use viewer auth
diff --git a/indra/newview/skins/default/xui/en/panel_login.xml b/indra/newview/skins/default/xui/en/panel_login.xml
index 317c79e08f49b00c949ce02d9fae0ada62aa3317..1646cba0a730b4cba09f85fdb3f02cc12e154ad8 100644
--- a/indra/newview/skins/default/xui/en/panel_login.xml
+++ b/indra/newview/skins/default/xui/en/panel_login.xml
@@ -15,19 +15,30 @@
      name="real_url">
         http://secondlife.com/app/login/
     </panel.string>
+    <string name="reg_in_client_url">
+      http://secondlife.eniac15.lindenlab.com/reg-in-client/
+    </string>
     <panel.string
      name="forgot_password_url">
         http://secondlife.com/account/request.php
     </panel.string>
+  <!-- *NOTE: Custom resize logic for login_html in llpanellogin.cpp -->
     <web_browser
      border_visible="false"
      bottom="600"
      follows="all"
      left="0"
      name="login_html"
-     right="-1"
      start_url=""
-     top="1" />
+     top="0"
+     height="600"
+     width="800"/>
+    <panel
+     follows="left|bottom|right"
+     name="login_widgets"
+     layout="topleft"
+     left="0"
+     top="0">
     <text
      follows="left|bottom"
      font="SansSerif"
@@ -182,4 +193,5 @@
      width="300">
         [VERSION]
     </text>
+  </panel>
 </panel>