From 00dbacb215da8d6b6739b4bcefebee552de89a9c Mon Sep 17 00:00:00 2001
From: Josh Bell <josh@lindenlab.com>
Date: Wed, 14 Mar 2007 23:03:50 +0000
Subject: [PATCH] svn merge
 svn+ssh://svn.lindenlab.com/svn/linden/release@59161
 svn+ssh://svn.lindenlab.com/svn/linden/branches/release-candidate@59163 -->
 release

---
 doc/contributions.txt                         |   2 +-
 indra/llcommon/indra_constants.h              |   1 +
 indra/llcommon/llstreamtools.cpp              |   2 +-
 indra/llcommon/lluri.cpp                      | 483 +++++-----------
 indra/llcommon/lluri.h                        |  87 +--
 indra/llinventory/llinventory.cpp             |  60 +-
 indra/llinventory/llnotecard.cpp              |   5 +-
 indra/llinventory/llnotecard.h                |  15 +-
 indra/llmessage/llhttpclient.cpp              |  26 +
 indra/llmessage/llhttpclient.h                |   1 +
 indra/newview/English.lproj/InfoPlist.strings |   4 +-
 indra/newview/Info-SecondLife.plist           |   2 +-
 indra/newview/llassetuploadresponders.cpp     | 518 +++++++++++++-----
 indra/newview/llassetuploadresponders.h       |  69 ++-
 indra/newview/llfloaterpostcard.cpp           |  44 +-
 indra/newview/llfloaterreporter.cpp           | 424 ++++++++------
 indra/newview/llfloaterreporter.h             |  12 +-
 indra/newview/llfloatertos.cpp                |  12 +-
 indra/newview/llpreviewgesture.cpp            |  34 +-
 indra/newview/llpreviewnotecard.cpp           |  64 ++-
 indra/newview/llpreviewnotecard.h             |   8 +
 indra/newview/llpreviewscript.cpp             | 482 +++++++++-------
 indra/newview/llpreviewscript.h               |  27 +-
 indra/newview/llstartup.cpp                   |   2 +
 indra/newview/llviewermenu.cpp                |  15 +-
 indra/newview/llviewernetwork.cpp             |   4 +
 indra/newview/llviewernetwork.h               |   1 +
 indra/newview/llviewerobject.cpp              |  78 +--
 indra/newview/llviewerobject.h                |   5 +
 indra/newview/llviewerregion.cpp              |  26 +-
 indra/newview/llviewerregion.h                |   1 +
 indra/newview/llviewertexteditor.cpp          |  20 +-
 indra/newview/llviewertexteditor.h            |   9 +-
 indra/newview/llwearable.cpp                  |  29 +-
 indra/newview/viewer_manifest.py              |  15 +-
 35 files changed, 1564 insertions(+), 1023 deletions(-)

diff --git a/doc/contributions.txt b/doc/contributions.txt
index 8842a9a903e..59663640e3b 100644
--- a/doc/contributions.txt
+++ b/doc/contributions.txt
@@ -4,7 +4,7 @@ along with the issue identifier corresponding to the patches we've
 received from them.  To see more about these contributions, visit
 http://jira.secondlife.com/ , and enter the issue identifier.
 
-Alissa Sabre - VWR-81, VWR-86
+Alissa Sabre - VWR-81, VWR-83
 blino Nakamura - VWR-17
 Drewan Keats - VWR-28
 Dylan Haskell - VWR-72
diff --git a/indra/llcommon/indra_constants.h b/indra/llcommon/indra_constants.h
index c13860033e0..20499d4ad33 100644
--- a/indra/llcommon/indra_constants.h
+++ b/indra/llcommon/indra_constants.h
@@ -97,6 +97,7 @@ const	U32		DEFAULT_USER_SERVER_PORT		= 12036;
 const	U32		DEFAULT_RPC_SERVER_PORT			= 12037;
 const	U32		DEFAULT_LOG_DATA_SERVER_PORT	= 12039;
 const	U32		DEFAULT_BACKBONE_PORT			= 12040;
+const	U32		DEFAULT_CGI_SERVICES_PORT		= 12045;
 const   U32		DEFAULT_LOCAL_ASSET_PORT		= 12041;
 //const   U32		DEFAULT_BACKBONE_CAP_PORT		= 12042; // Deprecated
 const   U32		DEFAULT_CAP_PROXY_PORT			= 12043;
diff --git a/indra/llcommon/llstreamtools.cpp b/indra/llcommon/llstreamtools.cpp
index f9038afedc5..a92f1c93882 100644
--- a/indra/llcommon/llstreamtools.cpp
+++ b/indra/llcommon/llstreamtools.cpp
@@ -534,7 +534,7 @@ std::istream& fullread(std::istream& str, char *buf, std::streamsize requested)
 
 std::istream& operator>>(std::istream& str, const char *tocheck)
 {
-	char c;
+	char c = '\0';
 	const char *p;
 	p = tocheck;
 	while (*p && !str.bad())
diff --git a/indra/llcommon/lluri.cpp b/indra/llcommon/lluri.cpp
index 1f64c3bde30..a2c651b4445 100644
--- a/indra/llcommon/lluri.cpp
+++ b/indra/llcommon/lluri.cpp
@@ -13,273 +13,86 @@
 #include "llapp.h"
 #include "lluri.h"
 #include "llsd.h"
-
+#include <iomanip>
+  
 #include "../llmath/lluuid.h"
 
-// uric = reserved | unreserved | escaped
-// reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | "$" | ","
-// unreserved = alphanum | mark
-// mark = "-" | "_" | "." | "!" | "~" | "*" | "'" | "(" | ")"
-// escaped = "%" hex hex
-static const char* ESCAPED_CHARACTERS[256] =
+
+// static
+std::string LLURI::escape(const std::string& str, const std::string & allowed)
+{
+	std::ostringstream ostr;
+
+	std::string::const_iterator it = str.begin();
+	std::string::const_iterator end = str.end();
+	for(; it != end; ++it)
+	{
+		std::string::value_type c = *it;
+		if(allowed.find(c) == std::string::npos)
+		  {
+		    ostr << "%"
+			 << std::uppercase << std::hex << std::setw(2) << std::setfill('0')
+			 << static_cast<U32>(c);
+		  }
+		else
+		  {
+		    ostr << c;
+		  }
+	}
+	return ostr.str();
+}
+
+// static
+std::string LLURI::unescape(const std::string& str)
+{
+	std::ostringstream ostr;
+	std::string::const_iterator it = str.begin();
+	std::string::const_iterator end = str.end();
+	for(; it != end; ++it)
+	{
+		if((*it) == '%')
+		{
+			++it;
+			if(it == end) break;
+			U8 c = hex_as_nybble(*it++);
+			c = c << 4;
+			if (it == end) break;
+			c |= hex_as_nybble(*it);
+			ostr.put((char)c);
+		}
+		else
+		{
+			ostr.put(*it);
+		}
+	}
+	return ostr.str();
+}
+
+namespace
 {
-	"%00",		// 0
-	"%01",		// 1
-	"%02",		// 2
-	"%03",		// 3
-	"%04",		// 4
-	"%05",		// 5
-	"%06",		// 6
-	"%07",		// 7
-	"%08",		// 8
-	"%09",		// 9
-	"%0a",		// 10
-	"%0b",		// 11
-	"%0c",		// 12
-	"%0d",		// 13
-	"%0e",		// 14
-	"%0f",		// 15
-	"%10",		// 16
-	"%11",		// 17
-	"%12",		// 18
-	"%13",		// 19
-	"%14",		// 20
-	"%15",		// 21
-	"%16",		// 22
-	"%17",		// 23
-	"%18",		// 24
-	"%19",		// 25
-	"%1a",		// 26
-	"%1b",		// 27
-	"%1c",		// 28
-	"%1d",		// 29
-	"%1e",		// 30
-	"%1f",		// 31
-	"%20",		// 32
-	"!",		// 33
-	"%22",		// 34
-	"%23",		// 35
-	"$",		// 36
-	"%25",		// 37
-	"&",		// 38
-	"'",		// 39
-	"(",		// 40
-	")",		// 41
-	"*",		// 42
-	"+",		// 43
-	",",		// 44
-	"-",		// 45
-	".",		// 46
-	"/",		// 47
-	"0",		// 48
-	"1",		// 49
-	"2",		// 50
-	"3",		// 51
-	"4",		// 52
-	"5",		// 53
-	"6",		// 54
-	"7",		// 55
-	"8",		// 56
-	"9",		// 57
-	":",		// 58
-	";",		// 59
-	"%3c",		// 60
-	"=",		// 61
-	"%3e",		// 62
-	"?",		// 63
-	"@",		// 64
-	"A",		// 65
-	"B",		// 66
-	"C",		// 67
-	"D",		// 68
-	"E",		// 69
-	"F",		// 70
-	"G",		// 71
-	"H",		// 72
-	"I",		// 73
-	"J",		// 74
-	"K",		// 75
-	"L",		// 76
-	"M",		// 77
-	"N",		// 78
-	"O",		// 79
-	"P",		// 80
-	"Q",		// 81
-	"R",		// 82
-	"S",		// 83
-	"T",		// 84
-	"U",		// 85
-	"V",		// 86
-	"W",		// 87
-	"X",		// 88
-	"Y",		// 89
-	"Z",		// 90
-	"%5b",		// 91
-	"%5c",		// 92
-	"%5d",		// 93
-	"%5e",		// 94
-	"_",		// 95
-	"%60",		// 96
-	"a",		// 97
-	"b",		// 98
-	"c",		// 99
-	"d",		// 100
-	"e",		// 101
-	"f",		// 102
-	"g",		// 103
-	"h",		// 104
-	"i",		// 105
-	"j",		// 106
-	"k",		// 107
-	"l",		// 108
-	"m",		// 109
-	"n",		// 110
-	"o",		// 111
-	"p",		// 112
-	"q",		// 113
-	"r",		// 114
-	"s",		// 115
-	"t",		// 116
-	"u",		// 117
-	"v",		// 118
-	"w",		// 119
-	"x",		// 120
-	"y",		// 121
-	"z",		// 122
-	"%7b",		// 123
-	"%7c",		// 124
-	"%7d",		// 125
-	"~",		// 126
-	"%7f",		// 127
-	"%80",		// 128
-	"%81",		// 129
-	"%82",		// 130
-	"%83",		// 131
-	"%84",		// 132
-	"%85",		// 133
-	"%86",		// 134
-	"%87",		// 135
-	"%88",		// 136
-	"%89",		// 137
-	"%8a",		// 138
-	"%8b",		// 139
-	"%8c",		// 140
-	"%8d",		// 141
-	"%8e",		// 142
-	"%8f",		// 143
-	"%90",		// 144
-	"%91",		// 145
-	"%92",		// 146
-	"%93",		// 147
-	"%94",		// 148
-	"%95",		// 149
-	"%96",		// 150
-	"%97",		// 151
-	"%98",		// 152
-	"%99",		// 153
-	"%9a",		// 154
-	"%9b",		// 155
-	"%9c",		// 156
-	"%9d",		// 157
-	"%9e",		// 158
-	"%9f",		// 159
-	"%a0",		// 160
-	"%a1",		// 161
-	"%a2",		// 162
-	"%a3",		// 163
-	"%a4",		// 164
-	"%a5",		// 165
-	"%a6",		// 166
-	"%a7",		// 167
-	"%a8",		// 168
-	"%a9",		// 169
-	"%aa",		// 170
-	"%ab",		// 171
-	"%ac",		// 172
-	"%ad",		// 173
-	"%ae",		// 174
-	"%af",		// 175
-	"%b0",		// 176
-	"%b1",		// 177
-	"%b2",		// 178
-	"%b3",		// 179
-	"%b4",		// 180
-	"%b5",		// 181
-	"%b6",		// 182
-	"%b7",		// 183
-	"%b8",		// 184
-	"%b9",		// 185
-	"%ba",		// 186
-	"%bb",		// 187
-	"%bc",		// 188
-	"%bd",		// 189
-	"%be",		// 190
-	"%bf",		// 191
-	"%c0",		// 192
-	"%c1",		// 193
-	"%c2",		// 194
-	"%c3",		// 195
-	"%c4",		// 196
-	"%c5",		// 197
-	"%c6",		// 198
-	"%c7",		// 199
-	"%c8",		// 200
-	"%c9",		// 201
-	"%ca",		// 202
-	"%cb",		// 203
-	"%cc",		// 204
-	"%cd",		// 205
-	"%ce",		// 206
-	"%cf",		// 207
-	"%d0",		// 208
-	"%d1",		// 209
-	"%d2",		// 210
-	"%d3",		// 211
-	"%d4",		// 212
-	"%d5",		// 213
-	"%d6",		// 214
-	"%d7",		// 215
-	"%d8",		// 216
-	"%d9",		// 217
-	"%da",		// 218
-	"%db",		// 219
-	"%dc",		// 220
-	"%dd",		// 221
-	"%de",		// 222
-	"%df",		// 223
-	"%e0",		// 224
-	"%e1",		// 225
-	"%e2",		// 226
-	"%e3",		// 227
-	"%e4",		// 228
-	"%e5",		// 229
-	"%e6",		// 230
-	"%e7",		// 231
-	"%e8",		// 232
-	"%e9",		// 233
-	"%ea",		// 234
-	"%eb",		// 235
-	"%ec",		// 236
-	"%ed",		// 237
-	"%ee",		// 238
-	"%ef",		// 239
-	"%f0",		// 240
-	"%f1",		// 241
-	"%f2",		// 242
-	"%f3",		// 243
-	"%f4",		// 244
-	"%f5",		// 245
-	"%f6",		// 246
-	"%f7",		// 247
-	"%f8",		// 248
-	"%f9",		// 249
-	"%fa",		// 250
-	"%fb",		// 251
-	"%fc",		// 252
-	"%fd",		// 253
-	"%fe",		// 254
-	"%ff"		// 255
-};
+	const std::string unreserved()
+	{
+		static const std::string s =   
+			"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
+			"0123456789"
+			"-._~";
+		return s;
+	}
+	const std::string sub_delims()
+	{
+		static const std::string s = "!$&'()*+,;=";
+		return s;
+	}
+
+	std::string escapeHostAndPort(const std::string& s)
+		{ return LLURI::escape(s, unreserved() + sub_delims() +":"); }
+	std::string escapePathComponent(const std::string& s)
+		{ return LLURI::escape(s, unreserved() + sub_delims() + ":@"); }
+	std::string escapeQueryVariable(const std::string& s)
+		{ return LLURI::escape(s, unreserved() + ":@!$'()*+,"); }	 // sub_delims - "&;=" + ":@"
+	std::string escapeQueryValue(const std::string& s)
+		{ return LLURI::escape(s, unreserved() + ":@!$'()*+,="); }	// sub_delims - "&;" + ":@"
+}
 
 LLURI::LLURI()
 {
@@ -352,23 +165,23 @@ LLURI::~LLURI()
 {
 }
 
-
-LLURI LLURI::buildHTTP(const std::string& host_port,
+// static
+LLURI LLURI::buildHTTP(const std::string& prefix,
 					   const LLSD& path)
 {
 	LLURI result;
 	
 	// TODO: deal with '/' '?' '#' in host_port
-	if (host_port.find("://") != host_port.npos)
+	if (prefix.find("://") != prefix.npos)
 	{
-		// The scheme is part of the host_port
-		result.mScheme = "";
-		result.mEscapedAuthority = escape(host_port);
+		// it is a prefix
+		result = LLURI(prefix);
 	}
 	else
 	{
-		result.mScheme = "HTTP";
-		result.mEscapedAuthority = "//" + escape(host_port);
+		// it is just a host and optional port
+		result.mScheme = "http";
+		result.mEscapedAuthority = escapeHostAndPort(prefix);
 	}
 
 	if (path.isArray())
@@ -379,20 +192,20 @@ LLURI LLURI::buildHTTP(const std::string& host_port,
 			 ++it)
 		{
 			lldebugs << "PATH: inserting " << it->asString() << llendl;
-			result.mEscapedPath += "/" + escape(it->asString());
+			result.mEscapedPath += "/" + escapePathComponent(it->asString());
 		}
 	}
-	result.mEscapedOpaque = result.mEscapedAuthority +
+	result.mEscapedOpaque = "//" + result.mEscapedAuthority +
 		result.mEscapedPath;
 	return result;
 }
 
 // static
-LLURI LLURI::buildHTTP(const std::string& host_port,
+LLURI LLURI::buildHTTP(const std::string& prefix,
 					   const LLSD& path,
 					   const LLSD& query)
 {
-	LLURI result = buildHTTP(host_port, path);
+	LLURI result = buildHTTP(prefix, path);
 	// break out and escape each query component
 	if (query.isMap())
 	{
@@ -400,8 +213,8 @@ LLURI LLURI::buildHTTP(const std::string& host_port,
 			 it != query.endMap();
 			 it++)
 		{
-			result.mEscapedQuery += escape(it->first) +
-				(it->second.isUndefined() ? "" : "=" + it->second.asString()) +
+			result.mEscapedQuery += escapeQueryVariable(it->first) +
+				(it->second.isUndefined() ? "" : "=" + escapeQueryValue(it->second.asString())) +
 				"&";
 		}
 		if (query.size() > 0)
@@ -413,56 +226,62 @@ LLURI LLURI::buildHTTP(const std::string& host_port,
 }
 
 // static
-LLURI LLURI::buildAgentPresenceURI(const LLUUID& agent_id, LLApp* app)
+LLURI LLURI::buildHTTP(const std::string& host,
+					   const U32& port,
+					   const LLSD& path)
 {
-	std::string host = "localhost:12040";
+	return LLURI::buildHTTP(llformat("%s:%u", host.c_str(), port), path);
+}
 
-	if (app)
+// static
+LLURI LLURI::buildHTTP(const std::string& host,
+					   const U32& port,
+					   const LLSD& path,
+					   const LLSD& query)
+{
+	return LLURI::buildHTTP(llformat("%s:%u", host.c_str(), port), path, query);
+}
+
+
+namespace {
+	LLURI buildBackboneURL(LLApp* app,
+				const std::string& p1 = "",
+				const std::string& p2 = "",
+				const std::string& p3 = "")
 	{
-		host = app->getOption("backbone-host-port").asString();
+		std::string host = "localhost:12040";
+
+		if (app)
+		{
+			host = app->getOption("backbone-host-port").asString();
+		}
+
+		LLSD path = LLSD::emptyArray();
+		if (!p1.empty())	path.append(p1);
+		if (!p2.empty())	path.append(p2);
+		if (!p3.empty())	path.append(p3);
+
+		return LLURI::buildHTTP(host, path);
 	}
+}
 
-	LLSD path = LLSD::emptyArray();
-	path.append("agent");
-	path.append(agent_id);
-	path.append("presence");
 
-	return buildHTTP(host, path);
+// static
+LLURI LLURI::buildAgentPresenceURI(const LLUUID& agent_id, LLApp* app)
+{
+	return buildBackboneURL(app, "agent", agent_id.asString(), "presence");
 }
 
 // static
 LLURI LLURI::buildBulkAgentPresenceURI(LLApp* app)
 {
-	std::string host = "localhost:12040";
-
-	if (app)
-	{
-		host = app->getOption("backbone-host-port").asString();
-	}
-
-	LLSD path = LLSD::emptyArray();
-	path.append("agent");
-	path.append("presence");
-
-	return buildHTTP(host, path);
+	return buildBackboneURL(app, "agent", "presence");
 }
 
 // static
 LLURI LLURI::buildAgentSessionURI(const LLUUID& agent_id, LLApp* app)
 {
-	std::string host = "localhost:12040";
-
-	if (app)
-	{
-		host = app->getOption("backbone-host-port").asString();
-	}
-
-	LLSD path = LLSD::emptyArray();
-	path.append("agent");
-	path.append(agent_id);
-	path.append("session");
-
-	return buildHTTP(host, path);
+	return buildBackboneURL(app, "agent", agent_id.asString(), "session");
 }
 
 // static
@@ -635,43 +454,3 @@ LLSD LLURI::queryMap(std::string escaped_query_string)
 	return result;
 }
 
-// static
-std::string LLURI::escape(const std::string& str)
-{
-	std::ostringstream ostr;
-	std::string::const_iterator it = str.begin();
-	std::string::const_iterator end = str.end();
-	S32 c;
-	for(; it != end; ++it)
-	{
-		c = (S32)(*it);
-		ostr << ESCAPED_CHARACTERS[c];
-	}
-	return ostr.str();
-}
-
-// static
-std::string LLURI::unescape(const std::string& str)
-{
-	std::ostringstream ostr;
-	std::string::const_iterator it = str.begin();
-	std::string::const_iterator end = str.end();
-	for(; it != end; ++it)
-	{
-		if((*it) == '%')
-		{
-			++it;
-			if(it == end) break;
-			U8 c = hex_as_nybble(*it++);
-			c = c << 4;
-			if (it == end) break;
-			c |= hex_as_nybble(*it);
-			ostr.put((char)c);
-		}
-		else
-		{
-			ostr.put(*it);
-		}
-	}
-	return ostr.str();
-}
diff --git a/indra/llcommon/lluri.h b/indra/llcommon/lluri.h
index 514628237d0..b5c3a841738 100644
--- a/indra/llcommon/lluri.h
+++ b/indra/llcommon/lluri.h
@@ -26,42 +26,55 @@ class LLApp;
 class LLURI
 {
 public:
-	LLURI();
-	LLURI(const std::string& escaped_str);
-		// construct from escaped string, as would be transmitted on the net
+  LLURI();
+  LLURI(const std::string& escaped_str);
+  // construct from escaped string, as would be transmitted on the net
 
-	~LLURI();
+  ~LLURI();
 
-	static LLURI buildHTTP(const std::string& host_port,
-						   const LLSD& path);
-	static LLURI buildHTTP(const std::string& host_port,
-						   const LLSD& path,
-						   const LLSD& query);
-	
-	std::string asString() const;
-		// the whole URI, escaped as needed
-
-	// Parts of a URI
-	// These functions return parts of the decoded URI.  The returned
-	// strings are un-escaped as needed
-	
-	// for all schemes
-	std::string scheme() const;		// ex.: "http", note lack of colon
-	std::string opaque() const;		// everything after the colon
+  static LLURI buildHTTP(const std::string& prefix,
+			 const LLSD& path);
+  static LLURI buildHTTP(const std::string& prefix,
+			 const LLSD& path,
+			 const LLSD& query);
+	// prefix is either a full URL prefix of the form "http://example.com:8080",
+	// or it can be simply a host and optional port like "example.com" or 
+	// "example.com:8080", in these cases, the "http://" will be added
 
-	// for schemes that follow path like syntax (http, https, ftp)
-	std::string authority() const;	// ex.: "bob@host.com:80"
-	std::string hostName() const;	// ex.: "host.com"
-	U16 hostPort() const;			// ex.: 80, will include implicit port
-	std::string path() const;		// ex.: "/abc/def", includes leading slash
-//    LLSD pathArray() const;			// above decoded into an array of strings
-	std::string query() const;		// ex.: "x=34", section after "?"
-    LLSD queryMap() const;			// above decoded into a map
-    static LLSD queryMap(std::string escaped_query_string);
+  static LLURI buildHTTP(const std::string& host,
+			 const U32& port,
+			 const LLSD& path);
+  static LLURI buildHTTP(const std::string& host,
+			 const U32& port,
+			 const LLSD& path,
+			 const LLSD& query);
+			 
+	  
+  std::string asString() const;
+  // the whole URI, escaped as needed
+  
+  // Parts of a URI
+  // These functions return parts of the decoded URI.  The returned
+  // strings are un-escaped as needed
+  
+  // for all schemes
+  std::string scheme() const;		// ex.: "http", note lack of colon
+  std::string opaque() const;		// everything after the colon
+  
+  // for schemes that follow path like syntax (http, https, ftp)
+  std::string authority() const;	// ex.: "host.com:80"
+  std::string hostName() const;	// ex.: "host.com"
+  U16 hostPort() const;			// ex.: 80, will include implicit port
+  std::string path() const;		// ex.: "/abc/def", includes leading slash
+  //    LLSD pathArray() const;			// above decoded into an array of strings
+  std::string query() const;		// ex.: "x=34", section after "?"
+  LLSD queryMap() const;			// above decoded into a map
+  static LLSD queryMap(std::string escaped_query_string);
 
-	// Escaping Utilities
-	static std::string escape(const std::string& str);
-	static std::string unescape(const std::string& str);
+  // Escaping Utilities
+  // Escape a string by urlencoding all the characters that aren't in the allowed string.
+  static std::string escape(const std::string& str, const std::string & allowed); 
+  static std::string unescape(const std::string& str);
 
 	// Functions for building specific URIs for web services
 	static LLURI buildAgentPresenceURI(const LLUUID& agent_id, LLApp* app);
@@ -71,11 +84,11 @@ class LLURI
 	static LLURI buildInventoryHostURI(const LLUUID& agent_id, LLApp* app);
 	
 private:
-	std::string mScheme;
-	std::string mEscapedOpaque;
-	std::string mEscapedAuthority;
-	std::string mEscapedPath;
-	std::string mEscapedQuery;
+  std::string mScheme;
+  std::string mEscapedOpaque;
+  std::string mEscapedAuthority;
+  std::string mEscapedPath;
+  std::string mEscapedQuery;
 };
 
 #endif // LL_LLURI_H
diff --git a/indra/llinventory/llinventory.cpp b/indra/llinventory/llinventory.cpp
index 0bc3f19cdf2..c392d23d22f 100644
--- a/indra/llinventory/llinventory.cpp
+++ b/indra/llinventory/llinventory.cpp
@@ -22,6 +22,24 @@
 
 #include "llsdutil.h"
 
+///----------------------------------------------------------------------------
+/// exported functions
+///----------------------------------------------------------------------------
+
+static const std::string INV_ITEM_ID_LABEL("item_id");
+static const std::string INV_FOLDER_ID_LABEL("folder_id");
+static const std::string INV_PARENT_ID_LABEL("parent_id");
+static const std::string INV_ASSET_TYPE_LABEL("type");
+static const std::string INV_PREFERRED_TYPE_LABEL("preferred_type");
+static const std::string INV_INVENTORY_TYPE_LABEL("inv_type");
+static const std::string INV_NAME_LABEL("name");
+static const std::string INV_DESC_LABEL("desc");
+static const std::string INV_PERMISSIONS_LABEL("permissions");
+static const std::string INV_ASSET_ID_LABEL("asset_id");
+static const std::string INV_SALE_INFO_LABEL("sale_info");
+static const std::string INV_FLAGS_LABEL("flags");
+static const std::string INV_CREATION_DATE_LABEL("created_at");
+
 ///----------------------------------------------------------------------------
 /// Local function declarations, constants, enums, and typedefs
 ///----------------------------------------------------------------------------
@@ -1113,24 +1131,24 @@ bool LLInventoryItem::fromLLSD(LLSD& sd)
 {
 	mInventoryType = LLInventoryType::IT_NONE;
 	mAssetUUID.setNull();
-	const char *w;
+	std::string w;
 
-	w = "item_id";
+	w = INV_ITEM_ID_LABEL;
 	if (sd.has(w))
 	{
 		mUUID = sd[w];
 	}
-	w = "parent_id";
+	w = INV_PARENT_ID_LABEL;
 	if (sd.has(w))
 	{
 		mParentUUID = sd[w];
 	}
-	w = "permissions";
+	w = INV_PERMISSIONS_LABEL;
 	if (sd.has(w))
 	{
 		mPermissions = ll_permissions_from_sd(sd[w]);
 	}
-	w = "sale_info";
+	w = INV_SALE_INFO_LABEL;
 	if (sd.has(w))
 	{
 		// Sale info used to contain next owner perm. It is now in
@@ -1164,40 +1182,40 @@ bool LLInventoryItem::fromLLSD(LLSD& sd)
 		LLXORCipher cipher(MAGIC_ID.mData, UUID_BYTES);
 		cipher.decrypt(mAssetUUID.mData, UUID_BYTES);
 	}
-	w = "asset_id";
+	w = INV_ASSET_ID_LABEL;
 	if (sd.has(w))
 	{
 		mAssetUUID = sd[w];
 	}
-	w = "type";
+	w = INV_ASSET_TYPE_LABEL;
 	if (sd.has(w))
 	{
 		mType = LLAssetType::lookup(sd[w].asString().c_str());
 	}
-	w = "inv_type";
+	w = INV_INVENTORY_TYPE_LABEL;
 	if (sd.has(w))
 	{
 		mInventoryType = LLInventoryType::lookup(sd[w].asString().c_str());
 	}
-	w = "flags";
+	w = INV_FLAGS_LABEL;
 	if (sd.has(w))
 	{
 		mFlags = ll_U32_from_sd(sd[w]);
 	}
-	w = "name";
+	w = INV_NAME_LABEL;
 	if (sd.has(w))
 	{
 		mName = sd[w].asString();
 		LLString::replaceNonstandardASCII(mName, ' ');
 		LLString::replaceChar(mName, '|', ' ');
 	}
-	w = "desc";
+	w = INV_DESC_LABEL;
 	if (sd.has(w))
 	{
 		mDescription = sd[w].asString();
 		LLString::replaceNonstandardASCII(mDescription, ' ');
 	}
-	w = "creation_date";
+	w = INV_CREATION_DATE_LABEL;
 	if (sd.has(w))
 	{
 		mCreationDate = sd[w];
@@ -1720,24 +1738,6 @@ bool inventory_and_asset_types_match(
 	return rv;
 }
 
-///----------------------------------------------------------------------------
-/// exported functions
-///----------------------------------------------------------------------------
-
-static const std::string INV_ITEM_ID_LABEL("item_id");
-static const std::string INV_FOLDER_ID_LABEL("folder_id");
-static const std::string INV_PARENT_ID_LABEL("parent_id");
-static const std::string INV_ASSET_TYPE_LABEL("type");
-static const std::string INV_PREFERRED_TYPE_LABEL("preferred_type");
-static const std::string INV_INVENTORY_TYPE_LABEL("inv_type");
-static const std::string INV_NAME_LABEL("name");
-static const std::string INV_DESC_LABEL("desc");
-static const std::string INV_PERMISSIONS_LABEL("permissions");
-static const std::string INV_ASSET_ID_LABEL("asset_id");
-static const std::string INV_SALE_INFO_LABEL("sale_info");
-static const std::string INV_FLAGS_LABEL("flags");
-static const std::string INV_CREATION_DATE_LABEL("created_at");
-
 LLSD ll_create_sd_from_inventory_item(LLPointer<LLInventoryItem> item)
 {
 	LLSD rv;
diff --git a/indra/llinventory/llnotecard.cpp b/indra/llinventory/llnotecard.cpp
index 79545874b46..96ee7ff8006 100644
--- a/indra/llinventory/llnotecard.cpp
+++ b/indra/llinventory/llnotecard.cpp
@@ -7,11 +7,10 @@
  */
 
 #include "linden_common.h"
-#include "llinventory.h"
 #include "llnotecard.h"
 #include "llstreamtools.h"
 
-LLNotecard::LLNotecard(U32 max_text)
+LLNotecard::LLNotecard(S32 max_text)
 : mMaxText(max_text)
 {
 }
@@ -179,7 +178,7 @@ bool LLNotecard::importStream(std::istream& str)
 	}
 	line_buf[STD_STRING_STR_LEN] = '\0';
 	
-	U32 text_len = 0;
+	S32 text_len = 0;
 	if( 1 != sscanf(line_buf, "Text length %d", &text_len) )
 	{
 		llwarns << "Invalid Linden text length field" << llendl;
diff --git a/indra/llinventory/llnotecard.h b/indra/llinventory/llnotecard.h
index 5f510a674f0..04fe6665623 100644
--- a/indra/llinventory/llnotecard.h
+++ b/indra/llinventory/llnotecard.h
@@ -9,12 +9,21 @@
 #ifndef LL_NOTECARD_H
 #define LL_NOTECARD_H
 
-const S32 MAX_NOTECARD_SIZE = 65536;
+#include "llmemory.h"
+#include "llinventory.h"
 
 class LLNotecard
 {
 public:
-	LLNotecard(U32 max_text);
+	/**
+	 * @brief anonymous enumeration to set max size.
+	 */
+	enum
+	{
+		MAX_SIZE = 65536
+	};
+	
+	LLNotecard(S32 max_text = LLNotecard::MAX_SIZE);
 	virtual ~LLNotecard();
 
 	bool importStream(std::istream& str);
@@ -33,7 +42,7 @@ class LLNotecard
 	bool exportEmbeddedItemsStream(std::ostream& str);
 	std::vector<LLPointer<LLInventoryItem> > mItems;
 	LLString mText;
-	U32 mMaxText;
+	S32 mMaxText;
 	S32 mVersion;
 	S32 mEmbeddedVersion;
 };
diff --git a/indra/llmessage/llhttpclient.cpp b/indra/llmessage/llhttpclient.cpp
index d83308d082d..f93a12b2743 100644
--- a/indra/llmessage/llhttpclient.cpp
+++ b/indra/llmessage/llhttpclient.cpp
@@ -131,6 +131,27 @@ namespace
 
 		const LLSD mSD;
 	};
+
+	class RawInjector : public Injector
+	{
+	public:
+		RawInjector(const U8* data, S32 size) : mData(data), mSize(size) {}
+		virtual ~RawInjector() {}
+
+		const char* contentType() { return "application/octet-stream"; }
+
+		virtual EStatus process_impl(const LLChannelDescriptors& channels,
+			buffer_ptr_t& buffer, bool& eos, LLSD& context, LLPumpIO* pump)
+		{
+			LLBufferStream ostream(channels, buffer.get());
+			ostream.write((const char *)mData, mSize);  // hopefully chars are always U8s
+			eos = true;
+			return STATUS_DONE;
+		}
+
+		const U8* mData;
+		S32 mSize;
+	};
 	
 	class FileInjector : public Injector
 	{
@@ -301,6 +322,11 @@ void LLHTTPClient::post(const std::string& url, const LLSD& body, ResponderPtr r
 	request(url, LLURLRequest::HTTP_POST, new LLSDInjector(body), responder);
 }
 
+void LLHTTPClient::post(const std::string& url, const U8* data, S32 size, ResponderPtr responder)
+{
+	request(url, LLURLRequest::HTTP_POST, new RawInjector(data, size), responder);
+}
+
 void LLHTTPClient::del(const std::string& url, ResponderPtr responder)
 {
 	request(url, LLURLRequest::HTTP_DELETE, NULL, responder);
diff --git a/indra/llmessage/llhttpclient.h b/indra/llmessage/llhttpclient.h
index d64662e41dc..a8afea312d3 100644
--- a/indra/llmessage/llhttpclient.h
+++ b/indra/llmessage/llhttpclient.h
@@ -54,6 +54,7 @@ class LLHTTPClient
 	static void put(const std::string& url, const LLSD& body, ResponderPtr);
 		///< non-blocking
 	static void post(const std::string& url, const LLSD& body, ResponderPtr);
+	static void post(const std::string& url, const U8* data, S32 size, ResponderPtr responder);
 	static void postFile(const std::string& url, const std::string& filename, ResponderPtr);
 	static void postFile(const std::string& url, const LLUUID& uuid,
 		LLAssetType::EType asset_type, ResponderPtr responder);
diff --git a/indra/newview/English.lproj/InfoPlist.strings b/indra/newview/English.lproj/InfoPlist.strings
index 66ce4155414..f49ffa16039 100644
--- a/indra/newview/English.lproj/InfoPlist.strings
+++ b/indra/newview/English.lproj/InfoPlist.strings
@@ -1,5 +1,5 @@
 /* Localized versions of Info.plist keys */
 
 CFBundleName = "Second Life";
-CFBundleShortVersionString = "Second Life version 1.13.3.3";
-CFBundleGetInfoString = "Second Life version 1.13.3.3, Copyright 2004-2006 Linden Research, Inc.";
+CFBundleShortVersionString = "Second Life version 1.13.4.8";
+CFBundleGetInfoString = "Second Life version 1.13.4.8, Copyright 2004-2007 Linden Research, Inc.";
diff --git a/indra/newview/Info-SecondLife.plist b/indra/newview/Info-SecondLife.plist
index 13901656b5d..448c7922ff8 100644
--- a/indra/newview/Info-SecondLife.plist
+++ b/indra/newview/Info-SecondLife.plist
@@ -32,7 +32,7 @@
 		</dict>
 	</array>
 	<key>CFBundleVersion</key>
-	<string>1.13.3.3</string>
+	<string>1.13.4.8</string>
 	<key>CSResourcesFileMapped</key>
 	<true/>
 </dict>
diff --git a/indra/newview/llassetuploadresponders.cpp b/indra/newview/llassetuploadresponders.cpp
index b37538f0233..7c615dd1595 100644
--- a/indra/newview/llassetuploadresponders.cpp
+++ b/indra/newview/llassetuploadresponders.cpp
@@ -1,10 +1,6 @@
-/** 
- * @file llmapresponders.h
- * @brief Processes responses received for asset upload requests.
- *
- * Copyright (c) 2006-$CurrentYear$, Linden Research, Inc.
- * $License$
- */
+// llassetuploadresponders.cpp
+// Copyright 2006, Linden Research, Inc.
+// Processes responses received for asset upload requests.
 
 #include "llviewerprecompiledheaders.h"
 
@@ -19,39 +15,71 @@
 #include "llinventorymodel.h"
 #include "llinventoryview.h"
 #include "llpermissionsflags.h"
+#include "llpreviewnotecard.h"
+#include "llpreviewscript.h"
+#include "llscrolllistctrl.h"
 #include "lluploaddialog.h"
-#include "llviewermenu.h"	// for upload_new_resource()
+#include "llviewerobject.h"
+#include "llviewerobjectlist.h"
+#include "llviewermenu.h"
 #include "llviewerwindow.h"
 #include "viewer.h"
 
-LLNewAgentInventoryResponder::LLNewAgentInventoryResponder(const LLUUID& uuid,
-														   const LLSD &post_data)
-	: LLHTTPClient::Responder()
+void dialog_refresh_all();
+
+LLAssetUploadResponder::LLAssetUploadResponder(const LLSD &post_data,
+											   const LLUUID& vfile_id,
+											   LLAssetType::EType asset_type)
+	: LLHTTPClient::Responder(),
+	  mPostData(post_data),
+	  mVFileID(vfile_id),
+	  mAssetType(asset_type)
+{
+	if (!gVFS->getExists(vfile_id, asset_type))
+	{
+		llwarns << "LLAssetUploadResponder called with nonexistant vfile_id" << llendl;
+		mVFileID.setNull();
+		mAssetType = LLAssetType::AT_NONE;
+		return;
+	}
+}
+
+LLAssetUploadResponder::LLAssetUploadResponder(const LLSD &post_data,
+											   const std::string& file_name)
+	: LLHTTPClient::Responder(),
+	  mPostData(post_data),
+	  mFileName(file_name)
+{
+}
+
+LLAssetUploadResponder::~LLAssetUploadResponder()
 {
-	mUUID = uuid;
-	mPostData = post_data;
+	if (!mFileName.empty())
+	{
+		// Delete temp file
+		LLFile::remove(mFileName.c_str());
+	}
 }
 
 // virtual
-void LLNewAgentInventoryResponder::error(U32 statusNum, const std::string& reason)
+void LLAssetUploadResponder::error(U32 statusNum, const std::string& reason)
 {
-	llinfos << "LLNewAgentInventoryResponder::error " << statusNum << llendl;
+	llinfos << "LLAssetUploadResponder::error " << statusNum 
+			<< " reason: " << reason << llendl;
 	LLStringBase<char>::format_map_t args;
 	switch(statusNum)
 	{
 		case 400:
-			args["[FILE]"] = mPostData["inventory_type"].asString();
-			args["[REASON]"] = "invalid parameters in upload request";
+			args["[FILE]"] = (mFileName.empty() ? mVFileID.asString() : mFileName);
+			args["[REASON]"] = "Error in upload request.  Please contact "
+				"support@lindenlab.com for help fixing this problem.";
 			gViewerWindow->alertXml("CannotUploadReason", args);
 			break;
-		case 402:
-			//(result["message"].asString() == "insufficient funds")
-			LLFloaterBuyCurrency::buyCurrency("Uploading costs", gGlobalEconomy->getPriceUpload());
-			break;
 		case 500:
 		default:
-			args["[FILE]"] = mPostData["inventory_type"].asString();
-			args["[REASON]"] = "the server is experiencing unexpected difficulties";
+			args["[FILE]"] = (mFileName.empty() ? mVFileID.asString() : mFileName);
+			args["[REASON]"] = "The server is experiencing unexpected "
+				"difficulties. Please try again later.";
 			gViewerWindow->alertXml("CannotUploadReason", args);
 			break;
 	}
@@ -59,139 +87,373 @@ void LLNewAgentInventoryResponder::error(U32 statusNum, const std::string& reaso
 }
 
 //virtual 
-void LLNewAgentInventoryResponder::result(const LLSD& result)
+void LLAssetUploadResponder::result(const LLSD& content)
 {
-	lldebugs << "LLNewAgentInventoryResponder::result from capabilities" << llendl;
+	lldebugs << "LLAssetUploadResponder::result from capabilities" << llendl;
 
-	if (!result["success"])
+	std::string state = content["state"];
+	if (state == "upload")
+	{
+		uploadUpload(content);
+	}
+	else if (state == "complete")
+	{
+		// rename file in VFS with new asset id
+		if (mFileName.empty())
+		{
+			// rename the file in the VFS to the actual asset id
+			gVFS->renameFile(mVFileID, mAssetType, content["new_asset"].asUUID(), mAssetType);
+		}
+		uploadComplete(content);
+	}
+	else
+	{
+		uploadFailure(content);
+	}
+}
+
+void LLAssetUploadResponder::uploadUpload(const LLSD& content)
+{
+	std::string uploader = content["uploader"];
+	if (mFileName.empty())
+	{
+		LLHTTPClient::postFile(uploader, mVFileID, mAssetType, this);
+	}
+	else
+	{
+		LLHTTPClient::postFile(uploader, mFileName, this);
+	}
+}
+
+void LLAssetUploadResponder::uploadFailure(const LLSD& content)
+{
+	std::string reason = content["state"];
+	// deal with money errors
+	if (reason == "insufficient funds")
+	{
+		LLFloaterBuyCurrency::buyCurrency("Uploading costs", gGlobalEconomy->getPriceUpload());
+	}
+	else
 	{
 		LLStringBase<char>::format_map_t args;
-		args["[FILE]"] = mPostData["inventory_type"].asString();
-		args["[REASON]"] = "the server is experiencing unexpected difficulties";
+		args["[FILE]"] = (mFileName.empty() ? mVFileID.asString() : mFileName);
+		args["[REASON]"] = content["message"].asString();
 		gViewerWindow->alertXml("CannotUploadReason", args);
-		return;
 	}
+}
+
+void LLAssetUploadResponder::uploadComplete(const LLSD& content)
+{
+}
+
+LLNewAgentInventoryResponder::LLNewAgentInventoryResponder(const LLSD& post_data,
+														   const LLUUID& vfile_id,
+														   LLAssetType::EType asset_type)
+: LLAssetUploadResponder(post_data, vfile_id, asset_type)
+{
+}
+
+LLNewAgentInventoryResponder::LLNewAgentInventoryResponder(const LLSD& post_data, const std::string& file_name)
+: LLAssetUploadResponder(post_data, file_name)
+{
+}
+
+//virtual 
+void LLNewAgentInventoryResponder::uploadComplete(const LLSD& content)
+{
+	lldebugs << "LLNewAgentInventoryResponder::result from capabilities" << llendl;
 
-	std::string uploader = result["uploader"];
 	LLAssetType::EType asset_type = LLAssetType::lookup(mPostData["asset_type"].asString().c_str());
 	LLInventoryType::EType inventory_type = LLInventoryType::lookup(mPostData["inventory_type"].asString().c_str());
-	// request succeeded
-	if (!uploader.empty())
+
+	// Update money and ownership credit information
+	// since it probably changed on the server
+	if (asset_type == LLAssetType::AT_TEXTURE ||
+		asset_type == LLAssetType::AT_SOUND ||
+		asset_type == LLAssetType::AT_ANIMATION)
 	{
-		LLHTTPClient::postFile(uploader, mUUID, asset_type, this);
+		gMessageSystem->newMessageFast(_PREHASH_MoneyBalanceRequest);
+		gMessageSystem->nextBlockFast(_PREHASH_AgentData);
+		gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+		gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+		gMessageSystem->nextBlockFast(_PREHASH_MoneyData);
+		gMessageSystem->addUUIDFast(_PREHASH_TransactionID, LLUUID::null );
+		gAgent.sendReliableMessage();
+
+		LLString::format_map_t args;
+		args["[AMOUNT]"] = llformat("%d",gGlobalEconomy->getPriceUpload());
+		LLNotifyBox::showXml("UploadPayment", args);
 	}
-	// upload succeeded
-	else
-	{
-		// rename the file in the VFS to the actual asset id
-		gVFS->renameFile(mUUID, asset_type, result["new_asset"].asUUID(), asset_type);
 
-		// TODO: only request for textures, sound, and animation uploads
-		// Update money and ownership credit information
-		// since it probably changed on the server
-		if (mPostData["asset_type"].asString() == "texture" || 
-			mPostData["asset_type"].asString() == "sound" ||
-			mPostData["asset_type"].asString() == "animatn")
+	// Actually add the upload to viewer inventory
+	llinfos << "Adding " << content["new_inventory_item"].asUUID() << " "
+			<< content["new_asset"].asUUID() << " to inventory." << llendl;
+	if(mPostData["folder_id"].asUUID().notNull())
+	{
+		LLPermissions perm;
+		U32 next_owner_perm;
+		perm.init(gAgent.getID(), gAgent.getID(), LLUUID::null, LLUUID::null);
+		if (mPostData["inventory_type"].asString() == "snapshot")
 		{
-			gMessageSystem->newMessageFast(_PREHASH_MoneyBalanceRequest);
-			gMessageSystem->nextBlockFast(_PREHASH_AgentData);
-			gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
-			gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
-			gMessageSystem->nextBlockFast(_PREHASH_MoneyData);
-			gMessageSystem->addUUIDFast(_PREHASH_TransactionID, LLUUID::null );
-			gAgent.sendReliableMessage();
-
-			LLString::format_map_t args;
-			args["[AMOUNT]"] = llformat("%d",gGlobalEconomy->getPriceUpload());
-			LLNotifyBox::showXml("UploadPayment", args);
+			next_owner_perm = PERM_ALL;
 		}
-		// Actually add the upload to viewer inventory
-		llinfos << "Adding " << result["new_inventory_item"].asUUID() << " "
-				<< result["new_asset"].asUUID() << " to inventory." << llendl;
-		if(mPostData["folder_id"].asUUID().notNull())
+		else
 		{
-			LLPermissions perm;
-			U32 next_owner_perm;
-			perm.init(gAgent.getID(), gAgent.getID(), LLUUID::null, LLUUID::null);
-			if (mPostData["inventory_type"].asString() == "snapshot")
+			next_owner_perm = PERM_MOVE | PERM_TRANSFER;
+		}
+		perm.initMasks(PERM_ALL, PERM_ALL, PERM_NONE, PERM_NONE, next_owner_perm);
+		S32 creation_date_now = time_corrected();
+		LLPointer<LLViewerInventoryItem> item
+			= new LLViewerInventoryItem(content["new_inventory_item"].asUUID(),
+										mPostData["folder_id"].asUUID(),
+										perm,
+										content["new_asset"].asUUID(),
+										asset_type,
+										inventory_type,
+										mPostData["name"].asString(),
+										mPostData["description"].asString(),
+										LLSaleInfo::DEFAULT,
+										LLInventoryItem::II_FLAGS_NONE,
+										creation_date_now);
+		gInventory.updateItem(item);
+		gInventory.notifyObservers();
+
+		// Show the preview panel for textures and sounds to let
+		// user know that the image (or snapshot) arrived intact.
+		LLInventoryView* view = LLInventoryView::getActiveInventory();
+		if(view)
+		{
+			LLUICtrl* focus_ctrl = gFocusMgr.getKeyboardFocus();
+			LLFocusMgr::FocusLostCallback callback = gFocusMgr.getFocusCallback();
+
+			view->getPanel()->setSelection(content["new_inventory_item"].asUUID(), TAKE_FOCUS_NO);
+			if((LLAssetType::AT_TEXTURE == asset_type)
+				|| (LLAssetType::AT_SOUND == asset_type))
 			{
-				next_owner_perm = PERM_ALL;
+				view->getPanel()->openSelected();
 			}
-			else
+			//LLInventoryView::dumpSelectionInformation((void*)view);
+			// restore keyboard focus
+			gFocusMgr.setKeyboardFocus(focus_ctrl, callback);
+		}
+	}
+	else
+	{
+		llwarns << "Can't find a folder to put it in" << llendl;
+	}
+
+	// remove the "Uploading..." message
+	LLUploadDialog::modalUploadFinished();
+	
+	// *FIX: This is a pretty big hack. What this does is check the
+	// file picker if there are any more pending uploads. If so,
+	// upload that file.
+	const char* next_file = LLFilePicker::instance().getNextFile();
+	if(next_file)
+	{
+		const char* name = LLFilePicker::instance().getDirname();
+
+		LLString asset_name = name;
+		LLString::replaceNonstandardASCII( asset_name, '?' );
+		LLString::replaceChar(asset_name, '|', '?');
+		LLString::stripNonprintable(asset_name);
+		LLString::trim(asset_name);
+
+		char* asset_name_str = (char*)asset_name.c_str();
+		char* end_p = strrchr(asset_name_str, '.');		 // strip extension if exists
+		if( !end_p )
+		{
+			 end_p = asset_name_str + strlen( asset_name_str );			/*Flawfinder: ignore*/
+		}
+			
+		S32 len = llmin( (S32) (DB_INV_ITEM_NAME_STR_LEN), (S32) (end_p - asset_name_str) );
+
+		asset_name = asset_name.substr( 0, len );
+
+		upload_new_resource(next_file, asset_name, asset_name,
+							0, LLAssetType::AT_NONE, LLInventoryType::IT_NONE);
+	}
+}
+
+
+LLUpdateAgentInventoryResponder::LLUpdateAgentInventoryResponder(const LLSD& post_data,
+																 const LLUUID& vfile_id,
+																 LLAssetType::EType asset_type)
+: LLAssetUploadResponder(post_data, vfile_id, asset_type)
+{
+}
+
+LLUpdateAgentInventoryResponder::LLUpdateAgentInventoryResponder(const LLSD& post_data,
+																 const std::string& file_name)
+: LLAssetUploadResponder(post_data, file_name)
+{
+}
+
+//virtual 
+void LLUpdateAgentInventoryResponder::uploadComplete(const LLSD& content)
+{
+	llinfos << "LLUpdateAgentInventoryResponder::result from capabilities" << llendl;
+	LLUUID item_id = mPostData["item_id"];
+
+	LLViewerInventoryItem* item = (LLViewerInventoryItem*)gInventory.getItem(item_id);
+	if(!item)
+	{
+		llwarns << "Inventory item for " << mVFileID
+			<< " is no longer in agent inventory." << llendl;
+		return;
+	}
+
+	// Update viewer inventory item
+	LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item);
+	new_item->setAssetUUID(content["new_asset"].asUUID());
+	gInventory.updateItem(new_item);
+	gInventory.notifyObservers();
+
+	llinfos << "Inventory item " << item->getName() << " saved into "
+		<< content["new_asset"].asString() << llendl;
+
+	LLInventoryType::EType inventory_type = new_item->getInventoryType();
+	switch(inventory_type)
+	{
+		case LLInventoryType::IT_NOTECARD:
 			{
-				next_owner_perm = PERM_MOVE | PERM_TRANSFER;
+
+				// Update the UI with the new asset.
+				LLPreviewNotecard* nc;
+				nc = (LLPreviewNotecard*)LLPreview::find(new_item->getUUID());
+				if(nc)
+				{
+					// *HACK: we have to delete the asset in the VFS so
+					// that the viewer will redownload it. This is only
+					// really necessary if the asset had to be modified by
+					// the uploader, so this can be optimized away in some
+					// cases. A better design is to have a new uuid if the
+					// script actually changed the asset.
+					if(nc->hasEmbeddedInventory())
+					{
+						gVFS->removeFile(
+							content["new_asset"].asUUID(),
+							LLAssetType::AT_NOTECARD);
+					}
+					nc->refreshFromInventory();
+				}
 			}
-			perm.initMasks(PERM_ALL, PERM_ALL, PERM_NONE, PERM_NONE, next_owner_perm);
-			S32 creation_date_now = time_corrected();
-			LLPointer<LLViewerInventoryItem> item
-				= new LLViewerInventoryItem(result["new_inventory_item"].asUUID(),
-											mPostData["folder_id"].asUUID(),
-											perm,
-											result["new_asset"].asUUID(),
-											asset_type,
-											inventory_type,
-											mPostData["name"].asString(),
-											mPostData["description"].asString(),
-											LLSaleInfo::DEFAULT,
-											LLInventoryItem::II_FLAGS_NONE,
-											creation_date_now);
-			gInventory.updateItem(item);
-			gInventory.notifyObservers();
-
-			// Show the preview panel for textures and sounds to let
-			// user know that the image (or snapshot) arrived intact.
-			LLInventoryView* view = LLInventoryView::getActiveInventory();
-			if(view)
+			break;
+		case LLInventoryType::IT_LSL:
 			{
-				LLUICtrl* focus_ctrl = gFocusMgr.getKeyboardFocus();
-				LLFocusMgr::FocusLostCallback callback = gFocusMgr.getFocusCallback();
-
-				view->getPanel()->setSelection(result["new_inventory_item"].asUUID(), TAKE_FOCUS_NO);
-				if((LLAssetType::AT_TEXTURE == asset_type)
-					|| (LLAssetType::AT_SOUND == asset_type))
+				// Find our window and close it if requested.
+				LLPreviewLSL* preview = (LLPreviewLSL*)LLPreview::find(item_id);
+				if (preview)
 				{
-					view->getPanel()->openSelected();
+					// Bytecode save completed
+					if (content["compiled"])
+					{
+						preview->callbackLSLCompileSucceeded();
+					}
+					else
+					{
+						preview->callbackLSLCompileFailed(content["errors"]);
+					}
 				}
-				//LLInventoryView::dumpSelectionInformation((void*)view);
-				// restore keyboard focus
-				gFocusMgr.setKeyboardFocus(focus_ctrl, callback);
 			}
-		}
-		else
-		{
-			llwarns << "Can't find a folder to put it in" << llendl;
-		}
+			break;
+		case LLInventoryType::IT_WEARABLE:
+		default:
+			break;
+	}
+}
 
-		// remove the "Uploading..." message
-		LLUploadDialog::modalUploadFinished();
-		
-		// *NOTE: This is a pretty big hack. What this does is check
-		// the file picker if there are any more pending uploads. If
-		// so, upload that file.
-		const char* next_file = LLFilePicker::instance().getNextFile();
-		if(next_file)
-		{
-			const char* name = LLFilePicker::instance().getDirname();
 
-			LLString asset_name = name;
-			LLString::replaceNonstandardASCII( asset_name, '?' );
-			LLString::replaceChar(asset_name, '|', '?');
-			LLString::stripNonprintable(asset_name);
-			LLString::trim(asset_name);
+LLUpdateTaskInventoryResponder::LLUpdateTaskInventoryResponder(const LLSD& post_data,
+																 const LLUUID& vfile_id,
+																 LLAssetType::EType asset_type)
+: LLAssetUploadResponder(post_data, vfile_id, asset_type)
+{
+}
 
-			char* asset_name_str = (char*)asset_name.c_str();
-			char* end_p = strrchr(asset_name_str, '.');		 // strip extension if exists
-			if( !end_p )
+LLUpdateTaskInventoryResponder::LLUpdateTaskInventoryResponder(const LLSD& post_data,
+															   const std::string& file_name)
+: LLAssetUploadResponder(post_data, file_name)
+{
+}
+
+//virtual 
+void LLUpdateTaskInventoryResponder::uploadComplete(const LLSD& content)
+{
+	llinfos << "LLUpdateTaskInventoryResponder::result from capabilities" << llendl;
+	LLUUID item_id = mPostData["item_id"];
+	LLUUID task_id = mPostData["task_id"];
+
+	LLViewerObject* object = gObjectList.findObject(task_id);
+	if (!object)
+	{
+		llwarns << "LLUpdateTaskInventoryResponder::uploadComplete task " << task_id
+			<< " no longer exist." << llendl;
+		return;
+	}
+	LLViewerInventoryItem* item = (LLViewerInventoryItem*)object->getInventoryObject(item_id);
+	if (!item)
+	{
+		llwarns << "LLUpdateTaskInventoryResponder::uploadComplete item "
+			<< item_id << " is no longer in task " << task_id
+			<< "'s inventory." << llendl;
+		return;
+	}
+	LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item);
+	// Update Viewer inventory
+	object->updateViewerInventoryAsset(new_item, content["new_asset"]);
+	dialog_refresh_all();
+	
+	LLInventoryType::EType inventory_type = new_item->getInventoryType();
+	switch(inventory_type)
+	{
+		case LLInventoryType::IT_NOTECARD:
 			{
-				end_p = asset_name_str + strlen( asset_name_str );			/*Flawfinder: ignore*/
-			}
-				
-			S32 len = llmin( (S32) (DB_INV_ITEM_NAME_STR_LEN), (S32) (end_p - asset_name_str) );
 
-			asset_name = asset_name.substr( 0, len );
+				// Update the UI with the new asset.
+				LLPreviewNotecard* nc;
+				nc = (LLPreviewNotecard*)LLPreview::find(new_item->getUUID());
+				if(nc)
+				{
+					// *HACK: we have to delete the asset in the VFS so
+					// that the viewer will redownload it. This is only
+					// really necessary if the asset had to be modified by
+					// the uploader, so this can be optimized away in some
+					// cases. A better design is to have a new uuid if the
+					// script actually changed the asset.
+					if(nc->hasEmbeddedInventory())
+					{
+						gVFS->removeFile(
+							content["new_asset"].asUUID(),
+							LLAssetType::AT_NOTECARD);
+					}
 
-			upload_new_resource(next_file, asset_name, asset_name,
-								0, LLAssetType::AT_NONE, LLInventoryType::IT_NONE);
-		}
+					nc->refreshFromInventory();
+				}
+			}
+			break;
+		case LLInventoryType::IT_LSL:
+			{
+				LLLiveLSLEditor* preview = LLLiveLSLEditor::find(item_id, task_id);
+				if (preview)
+				{
+					// Bytecode save completed
+					if (content["compiled"])
+					{
+						preview->callbackLSLCompileSucceeded(
+							task_id,
+							item_id,
+							mPostData["is_script_running"]);
+					}
+					else
+					{
+						preview->callbackLSLCompileFailed(content["errors"]);
+					}
+				}
+			}
+			break;
+		case LLInventoryType::IT_WEARABLE:
+		default:
+			break;
 	}
 }
diff --git a/indra/newview/llassetuploadresponders.h b/indra/newview/llassetuploadresponders.h
index b4d5377601a..ef8cd3834a8 100644
--- a/indra/newview/llassetuploadresponders.h
+++ b/indra/newview/llassetuploadresponders.h
@@ -1,26 +1,65 @@
-/** 
- * @file llmapresponders.h
- * @brief Processes responses received for asset upload requests.
- *
- * Copyright (c) 2006-$CurrentYear$, Linden Research, Inc.
- * $License$
- */
+// llassetuploadresponders.h
+// Copyright 2006, Linden Research, Inc.
+// Processes responses received for asset upload requests.
 
-#ifndef LL_LLNEWAGENTINVENTORYRESPONDER_H
-#define LL_LLNEWAGENTINVENTORYRESPONDER_H
+#ifndef LL_LLASSETUPLOADRESPONDER_H
+#define LL_LLASSETUPLOADRESPONDER_H
 
 #include "llhttpclient.h"
 
-class LLNewAgentInventoryResponder : public LLHTTPClient::Responder
+// Abstract class for supporting asset upload
+// via capabilities
+class LLAssetUploadResponder : public LLHTTPClient::Responder
 {
 public:
-	LLNewAgentInventoryResponder(const LLUUID& uuid, const LLSD& post_data);
-    void error(U32 statusNum, const std::string& reason);
+	LLAssetUploadResponder(const LLSD& post_data,
+							const LLUUID& vfile_id,
+							LLAssetType::EType asset_type);
+	LLAssetUploadResponder(const LLSD& post_data, const std::string& file_name);
+	~LLAssetUploadResponder();
+    virtual void error(U32 statusNum, const std::string& reason);
 	virtual void result(const LLSD& content);
+	virtual void uploadUpload(const LLSD& content);
+	virtual void uploadComplete(const LLSD& content);
+	virtual void uploadFailure(const LLSD& content);
 
-private:
-	LLUUID mUUID;
+protected:
 	LLSD mPostData;
+	LLUUID mVFileID;
+	LLAssetType::EType mAssetType;
+	std::string mFileName;
 };
 
-#endif // LL_LLNEWAGENTINVENTORYRESPONDER_H
+class LLNewAgentInventoryResponder : public LLAssetUploadResponder
+{
+public:
+	LLNewAgentInventoryResponder(const LLSD& post_data,
+								const LLUUID& vfile_id,
+								LLAssetType::EType asset_type);
+	LLNewAgentInventoryResponder(const LLSD& post_data, const std::string& file_name);
+	virtual void uploadComplete(const LLSD& content);
+};
+
+class LLUpdateAgentInventoryResponder : public LLAssetUploadResponder
+{
+public:
+	LLUpdateAgentInventoryResponder(const LLSD& post_data,
+								const LLUUID& vfile_id,
+								LLAssetType::EType asset_type);
+	LLUpdateAgentInventoryResponder(const LLSD& post_data,
+								const std::string& file_name);
+	virtual void uploadComplete(const LLSD& content);
+};
+
+class LLUpdateTaskInventoryResponder : public LLAssetUploadResponder
+{
+public:
+	LLUpdateTaskInventoryResponder(const LLSD& post_data,
+								const LLUUID& vfile_id,
+								LLAssetType::EType asset_type);
+	LLUpdateTaskInventoryResponder(const LLSD& post_data,
+								const std::string& file_name);
+	virtual void uploadComplete(const LLSD& content);
+};
+
+#endif // LL_LLASSETUPLOADRESPONDER_H
diff --git a/indra/newview/llfloaterpostcard.cpp b/indra/newview/llfloaterpostcard.cpp
index f82978c5fc9..7eaac8887cc 100644
--- a/indra/newview/llfloaterpostcard.cpp
+++ b/indra/newview/llfloaterpostcard.cpp
@@ -39,6 +39,8 @@
 #include "llvfs.h"
 #include "viewer.h"
 
+#include "llassetuploadresponders.h"
+
 ///----------------------------------------------------------------------------
 /// Local function declarations, constants, enums, and typedefs
 ///----------------------------------------------------------------------------
@@ -206,6 +208,23 @@ void LLFloaterPostcard::onClickCancel(void* data)
 	}
 }
 
+class LLSendPostcardResponder : public LLAssetUploadResponder
+{
+public:
+	LLSendPostcardResponder(const LLSD &post_data,
+							const LLUUID& vfile_id,
+							LLAssetType::EType asset_type):
+	    LLAssetUploadResponder(post_data, vfile_id, asset_type)
+	{	
+	}
+	// *TODO define custom uploadFailed here so it's not such a generic message
+	void LLSendPostcardResponder::uploadComplete(const LLSD& content)
+	{
+		// we don't care about what the server returns from this post, just clean up the UI
+		LLUploadDialog::modalUploadFinished();
+	}
+};
+
 // static
 void LLFloaterPostcard::onClickSend(void* data)
 {
@@ -230,12 +249,31 @@ void LLFloaterPostcard::onClickSend(void* data)
 
 		if (self->mJPEGImage.notNull())
 		{
-			// upload the image
 			self->mTransactionID.generate();
 			self->mAssetID = self->mTransactionID.makeAssetID(gAgent.getSecureSessionID());
 			LLVFile::writeFile(self->mJPEGImage->getData(), self->mJPEGImage->getDataSize(), gVFS, self->mAssetID, LLAssetType::AT_IMAGE_JPEG);
-			
-			gAssetStorage->storeAssetData(self->mTransactionID, LLAssetType::AT_IMAGE_JPEG, &uploadCallback, (void *)self, FALSE);
+
+			// upload the image
+			std::string url = gAgent.getRegion()->getCapability("SendPostcard");
+			if(!url.empty())
+			{
+				llinfos << "Send Postcard via capability" << llendl;
+				LLSD body = LLSD::emptyMap();
+				// the capability already encodes: agent ID, region ID
+				body["pos-global"] = self->mPosTakenGlobal.getValue();
+				body["to"] = self->childGetValue("to_form").asString();
+				body["from"] = self->childGetValue("from_form").asString();
+				body["name"] = self->childGetValue("name_form").asString();
+				body["subject"] = self->childGetValue("subject_form").asString();
+				body["msg"] = self->childGetValue("msg_form").asString();
+				body["allow-publish"] = self->childGetValue("allow_publish_check").asBoolean();
+				body["mature-publish"] = self->childGetValue("mature_check").asBoolean();
+				LLHTTPClient::post(url, body, new LLSendPostcardResponder(body, self->mAssetID, LLAssetType::AT_IMAGE_JPEG));
+			} 
+			else
+			{
+				gAssetStorage->storeAssetData(self->mTransactionID, LLAssetType::AT_IMAGE_JPEG, &uploadCallback, (void *)self, FALSE);
+			}
 
 			LLUploadDialog::modalUploadDialog("Uploading...\n\nPostcard");
 
diff --git a/indra/newview/llfloaterreporter.cpp b/indra/newview/llfloaterreporter.cpp
index 84c99db8daa..62f5fd21d50 100644
--- a/indra/newview/llfloaterreporter.cpp
+++ b/indra/newview/llfloaterreporter.cpp
@@ -44,6 +44,7 @@
 #include "lltooldraganddrop.h"
 #include "llfloatermap.h"
 #include "lluiconstants.h"
+#include "lluploaddialog.h"
 #include "llcallingcard.h"
 #include "llviewerobjectlist.h"
 #include "llagent.h"
@@ -61,6 +62,7 @@
 #include "llvieweruictrlfactory.h"
 #include "viewer.h"
 
+#include "llassetuploadresponders.h"
 
 const U32 INCLUDE_SCREENSHOT  = 0x01 << 0;
 
@@ -96,7 +98,8 @@ LLFloaterReporter::LLFloaterReporter(
 	mDeselectOnClose( FALSE ),
 	mPicking( FALSE), 
 	mPosition(),
-	mCopyrightWarningSeen( FALSE )
+	mCopyrightWarningSeen( FALSE ),
+	mResourceDatap(new LLResourceData())
 {
 	if (report_type == BUG_REPORT)
 	{
@@ -147,9 +150,9 @@ LLFloaterReporter::LLFloaterReporter(
 
 	gReporterInstances.addData(report_type, this);
 
-	// Upload a screenshot, but don't draw this floater.
+	// Take a screenshot, but don't draw this floater.
 	setVisible(FALSE);
-	uploadScreenshot();
+	takeScreenshot();
 	setVisible(TRUE);
 
 	// Default text to be blank
@@ -211,6 +214,7 @@ LLFloaterReporter::~LLFloaterReporter()
 	std::for_each(mMCDList.begin(), mMCDList.end(), DeletePointer() );
 	mMCDList.clear();
 
+	delete mResourceDatap;
 	gDialogVisible = FALSE;
 }
 
@@ -344,7 +348,7 @@ void LLFloaterReporter::callbackAvatarID(const std::vector<std::string>& names,
 	if ( self->mReportType != BUG_REPORT )
 	{
 		self->childSetText("abuser_name_edit", names[0] );
-
+		
 		self->mAbuserID = ids[0];
 
 		self->refresh();
@@ -355,31 +359,59 @@ void LLFloaterReporter::callbackAvatarID(const std::vector<std::string>& names,
 void LLFloaterReporter::onClickSend(void *userdata)
 {
 	LLFloaterReporter *self = (LLFloaterReporter *)userdata;
+	
+	if (self->mPicking)
+	{
+		closePickTool(self);
+	}
 
-	// only do this for abuse reports
-	if ( self->mReportType != BUG_REPORT )
+	if(self->validateReport())
 	{
-		if ( ! self->mCopyrightWarningSeen )
+		// only show copyright alert for abuse reports
+		if ( self->mReportType != BUG_REPORT )
 		{
-			LLString details_lc = self->childGetText("details_edit");
-			LLString::toLower( details_lc );
-			LLString summary_lc = self->childGetText("summary_edit");
-			LLString::toLower( summary_lc );
-			if ( details_lc.find( "copyright" ) != std::string::npos ||
-				summary_lc.find( "copyright" ) != std::string::npos )
+			if ( ! self->mCopyrightWarningSeen )
 			{
-				gViewerWindow->alertXml("HelpReportAbuseContainsCopyright");
-				self->mCopyrightWarningSeen = TRUE;
-				return;
+				LLString details_lc = self->childGetText("details_edit");
+				LLString::toLower( details_lc );
+				LLString summary_lc = self->childGetText("summary_edit");
+				LLString::toLower( summary_lc );
+				if ( details_lc.find( "copyright" ) != std::string::npos ||
+					summary_lc.find( "copyright" ) != std::string::npos )
+				{
+					gViewerWindow->alertXml("HelpReportAbuseContainsCopyright");
+					self->mCopyrightWarningSeen = TRUE;
+					return;
+				};
 			};
 		};
-	};
 
-	if (self->mPicking)
-	{
-		closePickTool(self);
+		LLUploadDialog::modalUploadDialog("Uploading...\n\nReport");
+		// *TODO don't upload image if checkbox isn't checked
+		std::string url = gAgent.getRegion()->getCapability("SendUserReport");
+		std::string sshot_url = gAgent.getRegion()->getCapability("SendUserReportWithScreenshot");
+		if(!url.empty() || !sshot_url.empty())
+		{
+			self->sendReportViaCaps(url, sshot_url, self->gatherReport());
+			self->close();
+		}
+		else
+		{
+			if(self->childGetValue("screen_check"))
+			{
+				self->childDisable("send_btn");
+				self->childDisable("cancel_btn");
+				// the callback from uploading the image calls sendReportViaLegacy()
+				self->uploadImage();
+			}
+			else
+			{
+				self->sendReportViaLegacy(self->gatherReport());
+				LLUploadDialog::modalUploadFinished();
+				self->close();
+			}
+		}
 	}
-	self->sendReport();
 }
 
 
@@ -532,10 +564,9 @@ void LLFloaterReporter::setPickedObjectProperties(const char *object_name, const
 	childSetText("owner_name", owner_name);
 }
 
-void LLFloaterReporter::sendReport()
+
+bool LLFloaterReporter::validateReport()
 {
-	LLViewerRegion *regionp = gAgent.getRegion();
-	if (!regionp) return;
 	// Ensure user selected a category from the list
 	LLSD category_sd = childGetValue("category_combo");
 	U8 category = (U8)category_sd.asInteger();
@@ -549,7 +580,7 @@ void LLFloaterReporter::sendReport()
 		{
 			gViewerWindow->alertXml("HelpReportBugSelectCategory");
 		}
-		return;
+		return false;
 	}
 
 	if ( mReportType != BUG_REPORT )
@@ -557,13 +588,13 @@ void LLFloaterReporter::sendReport()
 	  if ( childGetText("abuser_name_edit").empty() )
 	  {
 		  gViewerWindow->alertXml("HelpReportAbuseAbuserNameEmpty");
-		  return;
+		  return false;
 	  };
   
 	  if ( childGetText("abuse_location_edit").empty() )
 	  {
 		  gViewerWindow->alertXml("HelpReportAbuseAbuserLocationEmpty");
-		  return;
+		  return false;
 	  };
 	};
 
@@ -577,7 +608,7 @@ void LLFloaterReporter::sendReport()
 		{
 			gViewerWindow->alertXml("HelpReportBugSummaryEmpty");
 		}
-		return;
+		return false;
 	};
 
 	if ( childGetText("details_edit") == mDefaultSummary )
@@ -590,53 +621,19 @@ void LLFloaterReporter::sendReport()
 		{
 			gViewerWindow->alertXml("HelpReportBugDetailsEmpty");
 		}
-		return;
+		return false;
 	};
+	return true;
+}
+
+LLSD LLFloaterReporter::gatherReport()
+{	
+	LLViewerRegion *regionp = gAgent.getRegion();
+	if (!regionp) return LLSD(); // *TODO handle this failure case more gracefully
 
 	// reset flag in case the next report also contains this text
 	mCopyrightWarningSeen = FALSE;
 
-	U32 check_flags = 0;
-	if (childGetValue("screen_check"))
-	{
-		check_flags |= INCLUDE_SCREENSHOT;
-	}
-
-	LLMessageSystem *msg = gMessageSystem;
-	msg->newMessageFast(_PREHASH_UserReport);
-	msg->nextBlockFast(_PREHASH_AgentData);
-	msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
-	msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
-	msg->nextBlockFast(_PREHASH_ReportData);
-	msg->addU8Fast(_PREHASH_ReportType, 	(U8) mReportType);
-	msg->addU8(_PREHASH_Category, category);
-	msg->addVector3Fast(_PREHASH_Position, 	mPosition);
-	msg->addU8Fast(_PREHASH_CheckFlags, 	(U8) check_flags);
-
-	// only send a screenshot ID if we're asked too and the email is 
-	// going to LL - Estate Owners cannot see the screenshot asset
-	LLSD screenshot_id = LLUUID::null;
-	if (childGetValue("screen_check"))
-	{
-		if ( mReportType != BUG_REPORT )
-		{
-			if ( gEmailToEstateOwner == FALSE )
-			{
-				screenshot_id = childGetValue("screenshot");
-			}
-		}
-		else
-		{
-			screenshot_id = childGetValue("screenshot");
-		};
-	};
-	msg->addUUIDFast(_PREHASH_ScreenshotID, screenshot_id);
-	msg->addUUIDFast(_PREHASH_ObjectID, 	mObjectID);
-
-	msg->addUUID("AbuserID", mAbuserID );
-	msg->addString("AbuseRegionName", "");
-	msg->addUUID("AbuseRegionID", LLUUID::null);
-
 	std::ostringstream summary;
 	if (!gInProductionGrid)
 	{
@@ -684,7 +681,6 @@ void LLFloaterReporter::sendReport()
 			<< " {" << childGetText("abuser_name_edit") << "} "					// name of abuse entered in report (chosen using LLAvatarPicker)
 			<< " \"" << childGetValue("summary_edit").asString() << "\"";		// summary as entered
 	};
-	msg->addStringFast(_PREHASH_Summary, summary.str().c_str());
 
 	std::ostringstream details;
 	if (mReportType != BUG_REPORT)
@@ -709,7 +705,6 @@ void LLFloaterReporter::sendReport()
 	};
 
 	details << childGetValue("details_edit").asString();
-	msg->addStringFast(_PREHASH_Details, details.str() );
 
 	char version_string[MAX_STRING];		/* Flawfinder: ignore */
 	snprintf(version_string,						/* Flawfinder: ignore */
@@ -722,120 +717,204 @@ void LLFloaterReporter::sendReport()
 			gSysCPU.getFamily().c_str(),
 			gGLManager.mGLRenderer.c_str(),
 			gGLManager.mDriverVersionVendorString.c_str());
-	msg->addString("VersionString", version_string);
 
-	msg->sendReliable(regionp->getHost());
+	// only send a screenshot ID if we're asked to and the email is 
+	// going to LL - Estate Owners cannot see the screenshot asset
+	LLUUID screenshot_id = LLUUID::null;
+	if (childGetValue("screen_check"))
+	{
+		if ( mReportType != BUG_REPORT )
+		{
+			if ( gEmailToEstateOwner == FALSE )
+			{
+				screenshot_id = childGetValue("screenshot");
+			}
+		}
+		else
+		{
+			screenshot_id = childGetValue("screenshot");
+		};
+	};
 
-	close();
+	LLSD report = LLSD::emptyMap();
+	report["report-type"] = (U8) mReportType;
+	report["category"] = childGetValue("category_combo");
+	report["position"] = mPosition.getValue();
+	report["check-flags"] = (U8)0; // this is not used
+	report["screenshot-id"] = screenshot_id;
+	report["object-id"] = mObjectID;
+	report["abuser-id"] = mAbuserID;
+	report["abuse-region-name"] = "";
+	report["abuse-region-id"] = LLUUID::null;
+	report["summary"] = summary.str();
+	report["version-string"] = version_string;
+	report["details"] = details.str();
+	return report;
 }
 
+void LLFloaterReporter::sendReportViaLegacy(const LLSD & report)
+{
+	LLViewerRegion *regionp = gAgent.getRegion();
+	if (!regionp) return;
+	LLMessageSystem *msg = gMessageSystem;
+	msg->newMessageFast(_PREHASH_UserReport);
+	msg->nextBlockFast(_PREHASH_AgentData);
+	msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+	msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+	
+	msg->nextBlockFast(_PREHASH_ReportData);
+	msg->addU8Fast(_PREHASH_ReportType, report["report-type"].asInteger());
+	msg->addU8(_PREHASH_Category, report["category"].asInteger());
+	msg->addVector3Fast(_PREHASH_Position, 	LLVector3(report["position"]));
+	msg->addU8Fast(_PREHASH_CheckFlags, report["check-flags"].asInteger());
+	msg->addUUIDFast(_PREHASH_ScreenshotID, report["screenshot-id"].asUUID());
+	msg->addUUIDFast(_PREHASH_ObjectID, report["object-id"].asUUID());
+	msg->addUUID("AbuserID", report["abuser-id"].asUUID());
+	msg->addString("AbuseRegionName", report["abuse-region-name"].asString());
+	msg->addUUID("AbuseRegionID", report["abuse-region-id"].asUUID());
+
+	msg->addStringFast(_PREHASH_Summary, report["summary"].asString().c_str());
+	msg->addString("VersionString", report["version-string"]);
+	msg->addStringFast(_PREHASH_Details, report["details"] );
+	
+	msg->sendReliable(regionp->getHost());
+}
 
-void LLFloaterReporter::uploadScreenshot()
+class LLUserReportScreenshotResponder : public LLAssetUploadResponder
+{
+public:
+	LLUserReportScreenshotResponder(const LLSD & post_data, 
+									const LLUUID & vfile_id, 
+									LLAssetType::EType asset_type):
+	  LLAssetUploadResponder(post_data, vfile_id, asset_type)
+	{
+	}
+	void uploadFailed(const LLSD& content)
+	{
+		// *TODO pop up a dialog so the user knows their report screenshot didn't make it
+		LLUploadDialog::modalUploadFinished();
+	}
+	void uploadComplete(const LLSD& content)
+	{
+		// we don't care about what the server returns from this post, just clean up the UI
+		LLUploadDialog::modalUploadFinished();
+	}
+};
+
+class LLUserReportResponder : public LLHTTPClient::Responder
+{
+public:
+	LLUserReportResponder(): LLHTTPClient::Responder()  {}
+
+	void error(U32 status, const std::string& reason)
+	{
+		// *TODO do some user messaging here
+		LLUploadDialog::modalUploadFinished();
+	}
+	void result(const LLSD& content)
+	{
+		// we don't care about what the server returns
+		LLUploadDialog::modalUploadFinished();
+	}
+};
+
+void LLFloaterReporter::sendReportViaCaps(std::string url, std::string sshot_url, const LLSD& report)
+{
+	if(childGetValue("screen_check").asBoolean() && !sshot_url.empty())
+	{
+		// try to upload screenshot
+		LLHTTPClient::post(sshot_url, report, new LLUserReportScreenshotResponder(report, 
+															mResourceDatap->mAssetInfo.mUuid, 
+															mResourceDatap->mAssetInfo.mType));			
+	}
+	else
+	{
+		// screenshot not wanted or we don't have screenshot cap
+		LLHTTPClient::post(url, report, new LLUserReportResponder());			
+	}
+}
+
+void LLFloaterReporter::takeScreenshot()
 {
 	const S32 IMAGE_WIDTH = 1024;
 	const S32 IMAGE_HEIGHT = 768;
-	LLString filename("report_screenshot.bmp");
 
-	if( !gViewerWindow->saveSnapshot( filename, IMAGE_WIDTH, IMAGE_HEIGHT, TRUE, FALSE ) )
+	LLPointer<LLImageRaw> raw = new LLImageRaw;
+	if( !gViewerWindow->rawSnapshot(raw, IMAGE_WIDTH, IMAGE_HEIGHT, TRUE, TRUE, FALSE))
 	{
+		llwarns << "Unable to take screenshot" << llendl;
 		return;
 	}
+	LLPointer<LLImageJ2C> upload_data = LLViewerImageList::convertToUploadFile(raw);
 
-	// Generate the temporary filename
-	std::string temp_filename = gDirUtilp->getTempFilename();
-
-	// try to create the upload file
-	if (!LLViewerImageList::createUploadFile(filename,
-										 	temp_filename,
-										 	IMG_CODEC_BMP ))
+	// create a resource data
+	mResourceDatap->mInventoryType = LLInventoryType::IT_NONE;
+	mResourceDatap->mAssetInfo.mTransactionID.generate();
+	mResourceDatap->mAssetInfo.mUuid = mResourceDatap->mAssetInfo.mTransactionID.makeAssetID(gAgent.getSecureSessionID());
+	if (BUG_REPORT == mReportType)
 	{
-		llwarns << "Unable to upload report screenshot " << filename << ":\n\n" << LLImageBase::getLastError() << "\n" << llendl;
-		if(LLFile::remove(temp_filename.c_str()) == -1)
-		{
-			lldebugs << "unable to remove temp file" << llendl;
-		}
-		LLFilePicker::instance().reset();
+		mResourceDatap->mAssetInfo.mType = LLAssetType::AT_TEXTURE;
+		mResourceDatap->mPreferredLocation = LLAssetType::EType(-1);
+	}
+	else if (COMPLAINT_REPORT == mReportType)
+	{
+		mResourceDatap->mAssetInfo.mType = LLAssetType::AT_TEXTURE;
+		mResourceDatap->mPreferredLocation = LLAssetType::EType(-2);
 	}
 	else
 	{
-		// create a resource data
-		LLResourceData* data = NULL;
-		data = new LLResourceData;
-		data->mInventoryType = LLInventoryType::IT_NONE;
-		data->mAssetInfo.mTransactionID.generate();
-		data->mAssetInfo.mUuid = data->mAssetInfo.mTransactionID.makeAssetID(gAgent.getSecureSessionID());
-		if (BUG_REPORT == mReportType)
-		{
-			//data->mAssetInfo.mType = LLAssetType::AT_BUG_REPORT_SCREENSHOT;
-			data->mAssetInfo.mType = LLAssetType::AT_TEXTURE;
-			data->mPreferredLocation = LLAssetType::EType(-1);
-		}
-		else if (COMPLAINT_REPORT == mReportType)
-		{
-			//data->mAssetInfo.mType = LLAssetType::AT_COMPLAINT_REPORT_SCREENSHOT;
-			data->mAssetInfo.mType = LLAssetType::AT_TEXTURE;
-			data->mPreferredLocation = LLAssetType::EType(-2);
-		}
-		else
-		{
-			llwarns << "Unknown LLFloaterReporter type" << llendl;
-		}
-		data->mAssetInfo.mCreatorID = gAgentID;
-		data->mAssetInfo.setName("screenshot_name");
-		data->mAssetInfo.setDescription("screenshot_descr");
-
-		llinfos << "*** Uploading: " << llendl;
-		llinfos << "Type: " << LLAssetType::lookup(data->mAssetInfo.mType) << llendl;
-		llinfos << "File: " << filename << llendl;
-		llinfos << "Dest: " << temp_filename << llendl;
-		llinfos << "Name: " << data->mAssetInfo.getName() << llendl;
-		llinfos << "Desc: " << data->mAssetInfo.getDescription() << llendl;
-
-		gAssetStorage->storeAssetData(temp_filename.c_str(),
-										data->mAssetInfo.mTransactionID,
-										data->mAssetInfo.mType,
-										LLFloaterReporter::uploadDoneCallback,
-										(void*)data, TRUE);
+		llwarns << "Unknown LLFloaterReporter type" << llendl;
+	}
+	mResourceDatap->mAssetInfo.mCreatorID = gAgentID;
+	mResourceDatap->mAssetInfo.setName("screenshot_name");
+	mResourceDatap->mAssetInfo.setDescription("screenshot_descr");
+
+	// store in VFS
+	LLVFile::writeFile(upload_data->getData(), 
+						upload_data->getDataSize(), 
+						gVFS, 
+						mResourceDatap->mAssetInfo.mUuid, 
+						mResourceDatap->mAssetInfo.mType);
+
+	// store in the image list so it doesn't try to fetch from the server
+	LLViewerImage* image_in_list = new LLViewerImage(mResourceDatap->mAssetInfo.mUuid, TRUE);
+	image_in_list->createGLTexture(0, raw);
+	gImageList.addImage(image_in_list); 
+
+	// the texture picker then uses that texture
+	LLTexturePicker* texture = LLUICtrlFactory::getTexturePickerByName(this, "screenshot");
+	if (texture)
+	{
+		texture->setImageAssetID(mResourceDatap->mAssetInfo.mUuid);
+		texture->setDefaultImageAssetID(mResourceDatap->mAssetInfo.mUuid);
+		texture->setCaption("Screenshot");
 	}
+
+}
+
+void LLFloaterReporter::uploadImage()
+{
+	llinfos << "*** Uploading: " << llendl;
+	llinfos << "Type: " << LLAssetType::lookup(mResourceDatap->mAssetInfo.mType) << llendl;
+	llinfos << "UUID: " << mResourceDatap->mAssetInfo.mUuid << llendl;
+	llinfos << "Name: " << mResourceDatap->mAssetInfo.getName() << llendl;
+	llinfos << "Desc: " << mResourceDatap->mAssetInfo.getDescription() << llendl;
+
+	gAssetStorage->storeAssetData(mResourceDatap->mAssetInfo.mTransactionID,
+									mResourceDatap->mAssetInfo.mType,
+									LLFloaterReporter::uploadDoneCallback,
+									(void*)mResourceDatap, TRUE);
 }
 
 
 // static
 void LLFloaterReporter::uploadDoneCallback(const LLUUID &uuid, void *user_data, S32 result) // StoreAssetData callback (fixed)
 {
-	LLResourceData* data = (LLResourceData*)user_data;
+	LLUploadDialog::modalUploadFinished();
 
-	if(result >= 0)
-	{
-		EReportType report_type = UNKNOWN_REPORT;
-		if (data->mPreferredLocation == -1)
-		{
-			report_type = BUG_REPORT;
-		}
-		else if (data->mPreferredLocation == -2)
-		{
-			report_type = COMPLAINT_REPORT;
-		}
-		else 
-		{
-			llwarns << "Unknown report type : " << data->mPreferredLocation << llendl;
-		}
+	LLResourceData* data = (LLResourceData*)user_data;
 
-		LLFloaterReporter *self = getReporter(report_type);
-		if (self)
-		{
-			LLTexturePicker* texture = LLUICtrlFactory::getTexturePickerByName(self, "screenshot");
-			if (texture)
-			{
-				texture->setImageAssetID(uuid);
-				texture->setDefaultImageAssetID(uuid);
-				texture->setCaption("Screenshot");
-			}
-			self->mScreenID = uuid;
-			llinfos << "Got screen shot " << uuid << llendl;
-		}
-	}
-	else // 	if(result >= 0)
+	if(result < 0)
 	{
 		LLStringBase<char>::format_map_t args;
 		args["[REASON]"] = std::string(LLAssetStorage::getErrorString(result));
@@ -844,8 +923,31 @@ void LLFloaterReporter::uploadDoneCallback(const LLUUID &uuid, void *user_data,
 		std::string err_msg("There was a problem uploading a report screenshot");
 		err_msg += " due to the following reason: " + args["[REASON]"];
 		llwarns << err_msg << llendl;
+		return;
+	}
+
+	EReportType report_type = UNKNOWN_REPORT;
+	if (data->mPreferredLocation == -1)
+	{
+		report_type = BUG_REPORT;
 	}
-	delete data;
+	else if (data->mPreferredLocation == -2)
+	{
+		report_type = COMPLAINT_REPORT;
+	}
+	else 
+	{
+		llwarns << "Unknown report type : " << data->mPreferredLocation << llendl;
+	}
+
+	LLFloaterReporter *self = getReporter(report_type);
+	if (self)
+	{
+		self->mScreenID = uuid;
+		llinfos << "Got screen shot " << uuid << llendl;
+		self->sendReportViaLegacy(self->gatherReport());
+	}
+	self->close();
 }
 
 
diff --git a/indra/newview/llfloaterreporter.h b/indra/newview/llfloaterreporter.h
index 795ef45e530..e8483b98ef6 100644
--- a/indra/newview/llfloaterreporter.h
+++ b/indra/newview/llfloaterreporter.h
@@ -21,6 +21,7 @@ class LLViewerObject;
 class LLAgent;
 class LLToolObjPicker;
 class LLMeanCollisionData;
+struct LLResourceData;
 
 // these flags are used to label info requests to the server
 const U32 BUG_REPORT_REQUEST 		= 0x01 << 0;
@@ -51,7 +52,6 @@ enum EReportType
 	CS_REQUEST_REPORT = 4
 };
 
-
 class LLFloaterReporter
 :	public LLFloater
 {
@@ -87,11 +87,16 @@ class LLFloaterReporter
 	static void processRegionInfo(LLMessageSystem* msg);
 	
 	void setPickedObjectProperties(const char *object_name, const char *owner_name);
-	void uploadScreenshot();
 
 private:
+	void takeScreenshot();
+	void sendReportViaCaps(std::string url);
+	void uploadImage();
+	bool validateReport();
 	void setReporterID();
-	void sendReport();
+	LLSD gatherReport();
+	void sendReportViaLegacy(const LLSD & report);
+	void sendReportViaCaps(std::string url, std::string sshot_url, const LLSD & report);
 	void setPosBox(const LLVector3d &pos);
 	void enableControls(BOOL own_avatar);
 	void getObjectInfo(const LLUUID& object_id);
@@ -108,6 +113,7 @@ class LLFloaterReporter
 	BOOL			mCopyrightWarningSeen;
 	std::list<LLMeanCollisionData*> mMCDList;
 	LLString		mDefaultSummary;
+	LLResourceData* mResourceDatap;
 };
 
 #endif
diff --git a/indra/newview/llfloatertos.cpp b/indra/newview/llfloatertos.cpp
index 34f394610fc..c178d0d4168 100644
--- a/indra/newview/llfloatertos.cpp
+++ b/indra/newview/llfloatertos.cpp
@@ -163,18 +163,8 @@ BOOL LLFloaterTOS::postBuild()
 		gResponsePtr = LLIamHere::build( this );
 		LLHTTPClient::get( childGetValue( "real_url" ).asString(), gResponsePtr );
 	};
-	#else
-	LLTextEditor *Editor = LLUICtrlFactory::getTextEditorByName(this, "tos_text");
-	if (Editor)
-	{
-		Editor->setHandleEditKeysDirectly( TRUE );
-		Editor->setEnabled( FALSE );
-		Editor->setReadOnlyFgColor(LLColor4::white);
-		Editor->setWordWrap(TRUE);
-		Editor->setFocus(TRUE);
-	}
-	childSetValue("tos_text", LLSD(mMessage));	
 	#endif
+
 	return TRUE;
 }
 
diff --git a/indra/newview/llpreviewgesture.cpp b/indra/newview/llpreviewgesture.cpp
index 938976241b5..862dbcf377b 100644
--- a/indra/newview/llpreviewgesture.cpp
+++ b/indra/newview/llpreviewgesture.cpp
@@ -22,6 +22,7 @@
 
 // newview
 #include "llagent.h"		// todo: remove
+#include "llassetuploadresponders.h"
 #include "llbutton.h"
 #include "llcheckboxctrl.h"
 #include "llcombobox.h"
@@ -38,6 +39,7 @@
 #include "llviewerinventory.h"
 #include "llviewerobject.h"
 #include "llviewerobjectlist.h"
+#include "llviewerregion.h"
 #include "llviewerstats.h"
 #include "llviewerwindow.h"		// busycount
 #include "viewer.h"			// gVFS
@@ -1101,13 +1103,31 @@ void LLPreviewGesture::saveIfNeeded()
 		LLInventoryItem* item = getItem();
 		if (item)
 		{
-			LLLineEditor* descEditor = LLUICtrlFactory::getLineEditorByName(this, "desc");
-			LLSaveInfo* info = new LLSaveInfo(mItemUUID, mObjectUUID, descEditor->getText(), tid);
-
-			const BOOL temp_file = FALSE;
-
-			gAssetStorage->storeAssetData(tid, LLAssetType::AT_GESTURE, onSaveComplete, info, temp_file);
-
+			std::string agent_url = gAgent.getRegion()->getCapability("UpdateGestureAgentInventory");
+			std::string task_url = gAgent.getRegion()->getCapability("UpdateGestureTaskInventory");
+			if (mObjectUUID.isNull() && !agent_url.empty())
+			{
+				// Saving into agent inventory
+				LLSD body;
+				body["item_id"] = mItemUUID;
+				LLHTTPClient::post(agent_url, body,
+					new LLUpdateAgentInventoryResponder(body, asset_id, LLAssetType::AT_GESTURE));
+			}
+			else if (!mObjectUUID.isNull() && !task_url.empty())
+			{
+				// Saving into task inventory
+				LLSD body;
+				body["task_id"] = mObjectUUID;
+				body["item_id"] = mItemUUID;
+				LLHTTPClient::post(task_url, body,
+					new LLUpdateTaskInventoryResponder(body, asset_id, LLAssetType::AT_GESTURE));
+			}
+			else if (gAssetStorage)
+			{
+				LLLineEditor* descEditor = LLUICtrlFactory::getLineEditorByName(this, "desc");
+				LLSaveInfo* info = new LLSaveInfo(mItemUUID, mObjectUUID, descEditor->getText(), tid);
+				gAssetStorage->storeAssetData(tid, LLAssetType::AT_GESTURE, onSaveComplete, info, FALSE);
+			}
 		}
 
 		// If this gesture is active, then we need to update the in-memory
diff --git a/indra/newview/llpreviewnotecard.cpp b/indra/newview/llpreviewnotecard.cpp
index 6b8cc626ee4..154ce5b07c3 100644
--- a/indra/newview/llpreviewnotecard.cpp
+++ b/indra/newview/llpreviewnotecard.cpp
@@ -13,6 +13,7 @@
 #include "llinventory.h"
 
 #include "llagent.h"
+#include "llassetuploadresponders.h"
 #include "llviewerwindow.h"
 #include "llbutton.h"
 #include "llinventorymodel.h"
@@ -219,6 +220,22 @@ const LLInventoryItem* LLPreviewNotecard::getDragItem()
 	return NULL;
 }
 
+bool LLPreviewNotecard::hasEmbeddedInventory()
+{
+	LLViewerTextEditor* editor = NULL;
+	editor = LLViewerUICtrlFactory::getViewerTextEditorByName(
+		this,
+		"Notecard Editor");
+	if (!editor) return false;
+	return editor->hasEmbeddedInventory();
+}
+
+void LLPreviewNotecard::refreshFromInventory()
+{
+	lldebugs << "LLPreviewNotecard::refreshFromInventory()" << llendl;
+	loadAsset();
+}
+
 void LLPreviewNotecard::loadAsset()
 {
 	// request the asset.
@@ -348,7 +365,7 @@ void LLPreviewNotecard::onLoadComplete(LLVFS *vfs,
 			LLInventoryItem* item = preview->getItem();
 			BOOL modifiable = item && gAgent.allowOperation(PERM_MODIFY,
 								item->getPermissions(), GP_OBJECT_MANIPULATE);
-			previewEditor->setEnabled(modifiable);
+			preview->setEnabled(modifiable);
 			delete[] buffer;
 			preview->mAssetStatus = PREVIEW_ASSET_LOADED;
 		}
@@ -453,14 +470,43 @@ bool LLPreviewNotecard::saveIfNeeded(LLInventoryItem* copyitem)
 		LLInventoryItem* item = getItem();
 		// save it out to database
 		if (item)
-		{
-			
-			LLSaveNotecardInfo* info = new LLSaveNotecardInfo(this, mItemUUID, mObjectUUID,
-															  tid, copyitem);
-			gAssetStorage->storeAssetData(tid, LLAssetType::AT_NOTECARD,
-											&onSaveComplete,
-											(void*)info,
-											FALSE);
+		{			
+			std::string agent_url = gAgent.getRegion()->getCapability("UpdateNotecardAgentInventory");
+			std::string task_url = gAgent.getRegion()->getCapability("UpdateNotecardTaskInventory");
+			if (mObjectUUID.isNull() && !agent_url.empty())
+			{
+				// Saving into agent inventory
+				mAssetStatus = PREVIEW_ASSET_LOADING;
+				setEnabled(FALSE);
+				LLSD body;
+				body["item_id"] = mItemUUID;
+				llinfos << "Saving notecard " << mItemUUID
+					<< " into agent inventory via " << agent_url << llendl;
+				LLHTTPClient::post(agent_url, body,
+					new LLUpdateAgentInventoryResponder(body, asset_id, LLAssetType::AT_NOTECARD));
+			}
+			else if (!mObjectUUID.isNull() && !task_url.empty())
+			{
+				// Saving into task inventory
+				mAssetStatus = PREVIEW_ASSET_LOADING;
+				setEnabled(FALSE);
+				LLSD body;
+				body["task_id"] = mObjectUUID;
+				body["item_id"] = mItemUUID;
+				llinfos << "Saving notecard " << mItemUUID << " into task "
+					<< mObjectUUID << " via " << task_url << llendl;
+				LLHTTPClient::post(task_url, body,
+					new LLUpdateTaskInventoryResponder(body, asset_id, LLAssetType::AT_NOTECARD));
+			}
+			else if (gAssetStorage)
+			{
+				LLSaveNotecardInfo* info = new LLSaveNotecardInfo(this, mItemUUID, mObjectUUID,
+																tid, copyitem);
+				gAssetStorage->storeAssetData(tid, LLAssetType::AT_NOTECARD,
+												&onSaveComplete,
+												(void*)info,
+												FALSE);
+			}
 		}
 	}
 	return true;
diff --git a/indra/newview/llpreviewnotecard.h b/indra/newview/llpreviewnotecard.h
index 3bb3da5f549..730c56833a1 100644
--- a/indra/newview/llpreviewnotecard.h
+++ b/indra/newview/llpreviewnotecard.h
@@ -50,6 +50,14 @@ class LLPreviewNotecard : public LLPreview
 	const LLInventoryItem* getDragItem();
 
 
+	// return true if there is any embedded inventory.
+	bool hasEmbeddedInventory();
+
+	// After saving a notecard, the tcp based upload system will
+	// change the asset, therefore, we need to re-fetch it from the
+	// asset system. :(
+	void refreshFromInventory();
+
 protected:
 
 	virtual void loadAsset();
diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp
index 479f1b1812f..a7d29a65912 100644
--- a/indra/newview/llpreviewscript.cpp
+++ b/indra/newview/llpreviewscript.cpp
@@ -11,6 +11,7 @@
 #include "llpreviewscript.h"
 
 #include "llassetstorage.h"
+#include "llassetuploadresponders.h"
 #include "llbutton.h"
 #include "llcheckboxctrl.h"
 #include "llcombobox.h"
@@ -832,6 +833,33 @@ LLPreviewLSL::LLPreviewLSL(const std::string& name, const LLRect& rect,
 	}
 }
 
+// virtual
+void LLPreviewLSL::callbackLSLCompileSucceeded()
+{
+	llinfos << "LSL Bytecode saved" << llendl;
+	mScriptEd->mErrorList->addSimpleItem("Compile successful!");
+	mScriptEd->mErrorList->addSimpleItem("Save complete.");
+	closeIfNeeded();
+}
+
+// virtual
+void LLPreviewLSL::callbackLSLCompileFailed(const LLSD& compile_errors)
+{
+	llinfos << "Compile failed!" << llendl;
+
+	const LLFontGL* err_font = gResMgr->getRes(LLFONT_OCRA);
+	LLScrollListItem* item = NULL;
+	for(LLSD::array_const_iterator line = compile_errors.beginArray();
+		line < compile_errors.endArray();
+		line++)
+	{
+		item = new LLScrollListItem();
+		item->addColumn(line->asString(), err_font);
+		mScriptEd->mErrorList->addItem(item);
+	}
+	mScriptEd->selectFirstError();
+	closeIfNeeded();
+}
 
 void LLPreviewLSL::loadAsset()
 {
@@ -893,6 +921,17 @@ BOOL LLPreviewLSL::canClose()
 	return mScriptEd->canClose();
 }
 
+void LLPreviewLSL::closeIfNeeded()
+{
+	// Find our window and close it if requested.
+	getWindow()->decBusyCount();
+	mPendingUploads--;
+	if (mPendingUploads <= 0 && mCloseAfterSave)
+	{
+		close();
+	}
+}
+
 //override the llpreview open which attempts to load asset, load after xml ui made
 void LLPreviewLSL::open()		/*Flawfinder: ignore*/
 {
@@ -914,152 +953,152 @@ void LLPreviewLSL::onSave(void* userdata, BOOL close_after_save)
 	self->saveIfNeeded();
 }
 
-
 // Save needs to compile the text in the buffer. If the compile
 // succeeds, then save both assets out to the database. If the compile
 // fails, go ahead and save the text anyway so that the user doesn't
 // get too fucked.
 void LLPreviewLSL::saveIfNeeded()
 {
-	// llinfos << "LLPreviewLSL::save()" << llendl;
-	if(!mScriptEd->mEditor->isPristine())
+	// llinfos << "LLPreviewLSL::saveIfNeeded()" << llendl;
+	if(mScriptEd->mEditor->isPristine())
 	{
-		mPendingUploads = 0;
-		mScriptEd->mErrorList->deleteAllItems();
-		mScriptEd->mEditor->makePristine();
-
-		// We need to update the asset information
-		LLTransactionID tid;
-		LLAssetID uuid;
-		tid.generate();
-		uuid = tid.makeAssetID(gAgent.getSecureSessionID());
-		char uuid_string[UUID_STR_LENGTH];		/*Flawfinder: ignore*/
-		uuid.toString(uuid_string);
-		char filename[LL_MAX_PATH];		/*Flawfinder: ignore*/
-		snprintf(filename, LL_MAX_PATH, "%s.lsl", gDirUtilp->getExpandedFilename(LL_PATH_CACHE,uuid_string).c_str());		/*Flawfinder: ignore*/
-		FILE* fp = LLFile::fopen(filename, "wb");		/*Flawfinder: ignore*/
-		if(!fp)
-		{
-			llwarns << "Unable to write to " << filename << llendl;
-			LLScrollListItem* item = new LLScrollListItem();
-			item->addColumn("Error writing to local file. Is your hard drive full?", LLFontGL::sSansSerifSmall);
-			mScriptEd->mErrorList->addItem(item);
-			return;
-		}
+		return;
+	}
 
-		LLString utf8text = mScriptEd->mEditor->getText();
-		//fprintf(fp, "%s|%s\n", LLAssetType::lookup(LLAssetType::AT_LSL_TEXT),
-		//uuid_string);
-		//fprintf(fp,"{\n%s}\n", text.c_str());
-		fputs(utf8text.c_str(), fp);
-		fclose(fp);
-		fp = NULL;
+	mPendingUploads = 0;
+	mScriptEd->mErrorList->deleteAllItems();
+	mScriptEd->mEditor->makePristine();
 
-		// also write it out to the vfs for upload
-		LLVFile file(gVFS, uuid, LLAssetType::AT_LSL_TEXT, LLVFile::APPEND);
-		S32 size = utf8text.length() + 1;
+	// save off asset into file
+	LLTransactionID tid;
+	tid.generate();
+	LLAssetID asset_id = tid.makeAssetID(gAgent.getSecureSessionID());
+	std::string filepath = gDirUtilp->getExpandedFilename(LL_PATH_CACHE,asset_id.asString());
+	std::string filename = llformat("%s.lsl", filepath.c_str());
 
-		file.setMaxSize(size);
-		file.write((U8*)utf8text.c_str(), size);
+	FILE* fp = LLFile::fopen(filename.c_str(), "wb");
+	if(!fp)
+	{
+		llwarns << "Unable to write to " << filename << llendl;
+		LLScrollListItem* item = new LLScrollListItem();
+		item->addColumn("Error writing to local file. Is your hard drive full?", LLFontGL::sSansSerifSmall);
+		mScriptEd->mErrorList->addItem(item);
+		return;
+	}
 
-		LLInventoryItem *inv_item = getItem();
+	LLString utf8text = mScriptEd->mEditor->getText();
+	fputs(utf8text.c_str(), fp);
+	fclose(fp);
+	fp = NULL;
 
-		// save it out to database
-		if(gAssetStorage && inv_item)
+	LLInventoryItem *inv_item = getItem();
+	// save it out to asset server
+	std::string url = gAgent.getRegion()->getCapability("UpdateScriptAgentInventory");
+	if(inv_item)
+	{
+		getWindow()->incBusyCount();
+		mPendingUploads++;
+		if (!url.empty())
 		{
-			getWindow()->incBusyCount();
-			mPendingUploads++;
-			LLScriptSaveInfo* info = NULL;
+			uploadAssetViaCaps(url, filename, mItemUUID);
+		}
+		else if (gAssetStorage)
+		{
+			uploadAssetLegacy(filename, mItemUUID, tid);
+		}
+	}
+}
 
-			LLLineEditor* descEditor = LLUICtrlFactory::getLineEditorByName(this, "desc");
+void LLPreviewLSL::uploadAssetViaCaps(const std::string& url,
+									  const std::string& filename,
+									  const LLUUID& item_id)
+{
+	llinfos << "Update Agent Inventory via capability" << llendl;
+	LLSD body;
+	body["item_id"] = item_id;
+	LLHTTPClient::post(url, body, new LLUpdateAgentInventoryResponder(body, filename));
+}
 
-			info = new LLScriptSaveInfo(mItemUUID,
-										descEditor->getText(),
-										tid);
-			gAssetStorage->storeAssetData(tid, LLAssetType::AT_LSL_TEXT, &LLPreviewLSL::onSaveComplete, info);
-		}
+void LLPreviewLSL::uploadAssetLegacy(const std::string& filename,
+									  const LLUUID& item_id,
+									  const LLTransactionID& tid)
+{
+	LLLineEditor* descEditor = LLUICtrlFactory::getLineEditorByName(this, "desc");
+	LLScriptSaveInfo* info = new LLScriptSaveInfo(item_id,
+								descEditor->getText(),
+								tid);
+	gAssetStorage->storeAssetData(filename.c_str(),	tid,
+								  LLAssetType::AT_LSL_TEXT,
+								  &LLPreviewLSL::onSaveComplete,
+								  info);
 
-		char dst_filename[LL_MAX_PATH];		/*Flawfinder: ignore*/
-		snprintf(dst_filename, LL_MAX_PATH, "%s.lso", gDirUtilp->getExpandedFilename(LL_PATH_CACHE,uuid_string).c_str());		/*Flawfinder: ignore*/
-		char err_filename[LL_MAX_PATH];		/*Flawfinder: ignore*/
-		snprintf(err_filename, LL_MAX_PATH, "%s.out", gDirUtilp->getExpandedFilename(LL_PATH_CACHE,uuid_string).c_str());		/*Flawfinder: ignore*/
-		LLScrollListItem* item = NULL;
-		const LLFontGL* err_font = gResMgr->getRes(LLFONT_OCRA);
-		if(!lscript_compile(filename, dst_filename, err_filename, gAgent.isGodlike()))
-		{
-			llinfos << "Compile failed!" << llendl;
-			//char command[256];
-			//sprintf(command, "type %s\n", err_filename);
-			//system(command);
+	LLAssetID asset_id = tid.makeAssetID(gAgent.getSecureSessionID());
+	std::string filepath = gDirUtilp->getExpandedFilename(LL_PATH_CACHE,asset_id.asString());
+	std::string dst_filename = llformat("%s.lso", filepath.c_str());
+	std::string err_filename = llformat("%s.out", filepath.c_str());
 
-			// load the error file into the error scrolllist
-			if(NULL != (fp = LLFile::fopen(err_filename, "r")))		/*Flawfinder: ignore*/
+	LLScrollListItem* item = NULL;
+	const LLFontGL* err_font = gResMgr->getRes(LLFONT_OCRA);
+	if(!lscript_compile(filename.c_str(),
+						dst_filename.c_str(),
+						err_filename.c_str(),
+						gAgent.isGodlike()))
+	{
+		llinfos << "Compile failed!" << llendl;
+		//char command[256];
+		//sprintf(command, "type %s\n", err_filename);
+		//system(command);
+
+		// load the error file into the error scrolllist
+		FILE* fp = LLFile::fopen(err_filename.c_str(), "r");
+		if(fp)
+		{
+			char buffer[MAX_STRING];		/*Flawfinder: ignore*/
+			LLString line;
+			while(!feof(fp)) 
 			{
-				char buffer[MAX_STRING];		/*Flawfinder: ignore*/
-				LLString line;
-				while(!feof(fp)) 
+				fgets(buffer, MAX_STRING, fp);
+				if(feof(fp))
 				{
-					
-					fgets(buffer, MAX_STRING, fp);
-					if(feof(fp))
-					{
-						break;
-					}
-					else if(!buffer)
-					{
-						continue;
-					}
-					else
-					{
-						line.assign(buffer);
-						LLString::stripNonprintable(line);
-						item = new LLScrollListItem();
-						item->addColumn(line, err_font);
-						mScriptEd->mErrorList->addItem(item);
-					}
+					break;
 				}
-				fclose(fp);
-				mScriptEd->selectFirstError();
-			}
-		}
-		else
-		{
-			llinfos << "Compile worked!" << llendl;
-			if(gAssetStorage)
-			{
-				// move the compiled file into the vfs for transport
-				FILE* fp = LLFile::fopen(dst_filename, "rb");			/*Flawfinder: ignore*/
-				LLVFile file(gVFS, uuid, LLAssetType::AT_LSL_BYTECODE, LLVFile::APPEND);
-
-				fseek(fp, 0, SEEK_END);
-				S32 size = ftell(fp);
-				fseek(fp, 0, SEEK_SET);
-
-				file.setMaxSize(size);
-
-				const S32 buf_size = 65536;
-				U8 copy_buf[buf_size];
-				while ((size = fread(copy_buf, 1, buf_size, fp)))
+				else if(!buffer)
 				{
-					file.write(copy_buf, size);
+					continue;
+				}
+				else
+				{
+					line.assign(buffer);
+					LLString::stripNonprintable(line);
+					item = new LLScrollListItem();
+					item->addColumn(line, err_font);
+					mScriptEd->mErrorList->addItem(item);
 				}
-				fclose(fp);
-				fp = NULL;
-				getWindow()->incBusyCount();
-				mPendingUploads++;
-				LLUUID* this_uuid = new LLUUID(mItemUUID);
-				gAssetStorage->storeAssetData(tid,
-											  LLAssetType::AT_LSL_BYTECODE,
-											  &LLPreviewLSL::onSaveBytecodeComplete,
-											  (void**)this_uuid);
 			}
+			fclose(fp);
+			mScriptEd->selectFirstError();
 		}
-
-		// get rid of any temp files left lying around
-		LLFile::remove(filename);
-		LLFile::remove(err_filename);
-		LLFile::remove(dst_filename);
 	}
+	else
+	{
+		llinfos << "Compile worked!" << llendl;
+		if(gAssetStorage)
+		{
+			getWindow()->incBusyCount();
+			mPendingUploads++;
+			LLUUID* this_uuid = new LLUUID(mItemUUID);
+			gAssetStorage->storeAssetData(dst_filename.c_str(),
+										  tid,
+										  LLAssetType::AT_LSL_BYTECODE,
+										  &LLPreviewLSL::onSaveBytecodeComplete,
+										  (void**)this_uuid);
+		}
+	}
+
+	// get rid of any temp files left lying around
+	LLFile::remove(filename.c_str());
+	LLFile::remove(err_filename.c_str());
+	LLFile::remove(dst_filename.c_str());
 }
 
 
@@ -1333,6 +1372,35 @@ void LLLiveLSLEditor::loadAsset()
 	loadAsset(FALSE);
 }
 
+// virtual
+void LLLiveLSLEditor::callbackLSLCompileSucceeded(const LLUUID& task_id,
+												  const LLUUID& item_id,
+												  bool is_script_running)
+{
+	lldebugs << "LSL Bytecode saved" << llendl;
+	mScriptEd->mErrorList->addSimpleItem("Compile successful!");
+	mScriptEd->mErrorList->addSimpleItem("Save complete.");
+	closeIfNeeded();
+}
+
+// virtual
+void LLLiveLSLEditor::callbackLSLCompileFailed(const LLSD& compile_errors)
+{
+	lldebugs << "Compile failed!" << llendl;
+	const LLFontGL* err_font = gResMgr->getRes(LLFONT_OCRA);
+	LLScrollListItem* item = NULL;
+	for(LLSD::array_const_iterator line = compile_errors.beginArray();
+		line < compile_errors.endArray();
+		line++)
+	{
+		item = new LLScrollListItem();
+		item->addColumn(line->asString(), err_font);
+		mScriptEd->mErrorList->addItem(item);
+	}
+	mScriptEd->selectFirstError();
+	closeIfNeeded();
+}
+
 void LLLiveLSLEditor::loadAsset(BOOL is_new)
 {
 	//llinfos << "LLLiveLSLEditor::loadAsset()" << llendl;
@@ -1676,18 +1744,16 @@ void LLLiveLSLEditor::saveIfNeeded()
 	// set up the save on the local machine.
 	mScriptEd->mEditor->makePristine();
 	LLTransactionID tid;
-	LLAssetID uuid;
 	tid.generate();
-	uuid = tid.makeAssetID(gAgent.getSecureSessionID());
-	mItem->setAssetUUID(uuid);
+	LLAssetID asset_id = tid.makeAssetID(gAgent.getSecureSessionID());
+	std::string filepath = gDirUtilp->getExpandedFilename(LL_PATH_CACHE,asset_id.asString());
+	std::string filename = llformat("%s.lsl", filepath.c_str());
+
+	mItem->setAssetUUID(asset_id);
 	mItem->setTransactionID(tid);
 
 	// write out the data, and store it in the asset database
-	char uuid_string[UUID_STR_LENGTH];		/*Flawfinder: ignore*/
-	uuid.toString(uuid_string);
-	char filename[LL_MAX_PATH];		/*Flawfinder: ignore*/
-	snprintf(filename, LL_MAX_PATH, "%s.lsl", gDirUtilp->getExpandedFilename(LL_PATH_CACHE,uuid_string).c_str());		/*Flawfinder: ignore*/
-	FILE* fp = LLFile::fopen(filename, "wb");		/*Flawfinder: ignore*/
+	FILE* fp = LLFile::fopen(filename.c_str(), "wb");
 	if(!fp)
 	{
 		llwarns << "Unable to write to " << filename << llendl;
@@ -1699,63 +1765,69 @@ void LLLiveLSLEditor::saveIfNeeded()
 	LLString utf8text = mScriptEd->mEditor->getText();
 	fputs(utf8text.c_str(), fp);
 	fclose(fp);
-
-	LLCheckBoxCtrl* runningCheckbox = LLUICtrlFactory::getCheckBoxByName(this, "running");
+	fp = NULL;
 	
-	// save it out to database
-	if(gAssetStorage)
+	// save it out to asset server
+	std::string url = gAgent.getRegion()->getCapability("UpdateScriptTaskInventory");
+	getWindow()->incBusyCount();
+	mPendingUploads++;
+	BOOL is_running = LLUICtrlFactory::getCheckBoxByName(this, "running")->get();
+	if (!url.empty())
 	{
-		// write it out to the vfs for upload
-		LLVFile file(gVFS, uuid, LLAssetType::AT_LSL_TEXT, LLVFile::APPEND);
-		S32 size = utf8text.length() + 1;
-
-		file.setMaxSize(size);
-		file.write((U8*)utf8text.c_str(), size);
-
-		getWindow()->incBusyCount();
-		mPendingUploads++;
-		LLLiveLSLSaveData* data = new LLLiveLSLSaveData(mObjectID,
-														mItem,
-														runningCheckbox->get());
-		gAssetStorage->storeAssetData(tid, LLAssetType::AT_LSL_TEXT, &onSaveTextComplete, (void*)data, FALSE);
+		uploadAssetViaCaps(url, filename, mObjectID,
+						   mItemID, is_running);
 	}
-
-#if LL_WINDOWS
-	// This major hack was inserted because sometimes compilation
-	// would fail because it couldn't open this file... I decided
-	// to make a loop until open was successful. This seems to be
-	// a problem specific to ntfs.
-	fp = NULL;
-	const U32 MAX_TRIES = 20;
-	U32 tries = MAX_TRIES;
-	while((!fp) && --tries)
+	else if (gAssetStorage)
 	{
-		ms_sleep(17);
-		fp = LLFile::fopen(filename, "r");		/*Flawfinder: ignore*/
-		if(!fp)
-		{
-			llwarns << "Trying to open the source file " << filename
-					<< " again" << llendl;
-		}
-		else
-		{
-			fclose(fp);
-		}
+		uploadAssetLegacy(filename, object, tid, is_running);
 	}
-	fp = NULL;
-#endif
+}
+
+void LLLiveLSLEditor::uploadAssetViaCaps(const std::string& url,
+										 const std::string& filename,
+										 const LLUUID& task_id,
+										 const LLUUID& item_id,
+										 BOOL is_running)
+{
+	llinfos << "Update Task Inventory via capability" << llendl;
+	LLSD body;
+	body["task_id"] = task_id;
+	body["item_id"] = item_id;
+	body["is_script_running"] = is_running;
+	LLHTTPClient::post(url, body,
+		new LLUpdateTaskInventoryResponder(body, filename));
+}
+
+void LLLiveLSLEditor::uploadAssetLegacy(const std::string& filename,
+										LLViewerObject* object,
+										const LLTransactionID& tid,
+										BOOL is_running)
+{
+	LLLiveLSLSaveData* data = new LLLiveLSLSaveData(mObjectID,
+													mItem,
+													is_running);
+	gAssetStorage->storeAssetData(filename.c_str(), tid,
+								  LLAssetType::AT_LSL_TEXT,
+								  &onSaveTextComplete,
+								  (void*)data,
+								  FALSE);
+
+	LLAssetID asset_id = tid.makeAssetID(gAgent.getSecureSessionID());
+	std::string filepath = gDirUtilp->getExpandedFilename(LL_PATH_CACHE,asset_id.asString());
+	std::string dst_filename = llformat("%s.lso", filepath.c_str());
+	std::string err_filename = llformat("%s.out", filepath.c_str());
 
-	char dst_filename[LL_MAX_PATH];		/*Flawfinder: ignore*/
-	snprintf(dst_filename, LL_MAX_PATH, "%s.lso", gDirUtilp->getExpandedFilename(LL_PATH_CACHE,uuid_string).c_str());		/*Flawfinder: ignore*/
-	char err_filename[LL_MAX_PATH];		/*Flawfinder: ignore*/
-	snprintf(err_filename, LL_MAX_PATH, "%s.out", gDirUtilp->getExpandedFilename(LL_PATH_CACHE,uuid_string).c_str());		/*Flawfinder: ignore*/
 	LLScrollListItem* item = NULL;
 	const LLFontGL* err_font = gResMgr->getRes(LLFONT_OCRA);
-	if(!lscript_compile(filename, dst_filename, err_filename, gAgent.isGodlike()))
+	FILE *fp;
+	if(!lscript_compile(filename.c_str(),
+						dst_filename.c_str(),
+						err_filename.c_str(),
+						gAgent.isGodlike()))
 	{
 		// load the error file into the error scrolllist
 		llinfos << "Compile failed!" << llendl;
-		if(NULL != (fp = LLFile::fopen(err_filename, "r")))		/*Flawfinder: ignore*/
+		if(NULL != (fp = LLFile::fopen(err_filename.c_str(), "r")))
 		{
 			char buffer[MAX_STRING];		/*Flawfinder: ignore*/
 			LLString line;
@@ -1797,33 +1869,14 @@ void LLLiveLSLEditor::saveIfNeeded()
 		{
 			llinfos << "LLLiveLSLEditor::saveAsset "
 					<< mItem->getAssetUUID() << llendl;
-
-			// move the compiled file into the vfs for transport
-			FILE* fp = LLFile::fopen(dst_filename, "rb");		/*Flawfinder: ignore*/
-			LLVFile file(gVFS, uuid, LLAssetType::AT_LSL_BYTECODE, LLVFile::APPEND);
-
-			fseek(fp, 0, SEEK_END);
-			S32 size = ftell(fp);
-			fseek(fp, 0, SEEK_SET);
-
-			file.setMaxSize(size);
-
-			const S32 buf_size = 65536;
-			U8 copy_buf[buf_size];
-			while ((size = fread(copy_buf, 1, buf_size, fp)))
-			{
-				file.write(copy_buf, size);
-			}
-			fclose(fp);
-			fp = NULL;
-
 			getWindow()->incBusyCount();
 			mPendingUploads++;
 			LLLiveLSLSaveData* data = NULL;
 			data = new LLLiveLSLSaveData(mObjectID,
 										 mItem,
-										 runningCheckbox->get());
-			gAssetStorage->storeAssetData(tid,
+										 is_running);
+			gAssetStorage->storeAssetData(dst_filename.c_str(),
+										  tid,
 										  LLAssetType::AT_LSL_BYTECODE,
 										  &LLLiveLSLEditor::onSaveBytecodeComplete,
 										  (void*)data);
@@ -1832,11 +1885,12 @@ void LLLiveLSLEditor::saveIfNeeded()
 	}
 
 	// get rid of any temp files left lying around
-	LLFile::remove(filename);
-	LLFile::remove(err_filename);
-	LLFile::remove(dst_filename);
+	LLFile::remove(filename.c_str());
+	LLFile::remove(err_filename.c_str());
+	LLFile::remove(dst_filename.c_str());
 
 	// If we successfully saved it, then we should be able to check/uncheck the running box!
+	LLCheckBoxCtrl* runningCheckbox = LLUICtrlFactory::getCheckBoxByName(this, "running");
 	runningCheckbox->setLabel(ENABLED_RUNNING_CHECKBOX_LABEL);
 	runningCheckbox->setEnabled(TRUE);
 }
@@ -1912,13 +1966,10 @@ void LLLiveLSLEditor::onSaveBytecodeComplete(const LLUUID& asset_uuid, void* use
 		args["[REASON]"] = std::string(LLAssetStorage::getErrorString(status));
 		gViewerWindow->alertXml("CompileQueueSaveBytecode", args);
 	}
-	char uuid_string[UUID_STR_LENGTH];		/*Flawfinder: ignore*/
-	data->mItem->getAssetUUID().toString(uuid_string);
-	char dst_filename[LL_MAX_PATH];		/*Flawfinder: ignore*/
-	snprintf(dst_filename, LL_MAX_PATH, "%s.lso", gDirUtilp->getExpandedFilename(LL_PATH_CACHE,uuid_string).c_str());		/*Flawfinder: ignore*/
-	LLFile::remove(dst_filename);
-	snprintf(dst_filename, LL_MAX_PATH, "%s.lsl", gDirUtilp->getExpandedFilename(LL_PATH_CACHE,uuid_string).c_str());		/*Flawfinder: ignore*/
-	LLFile::remove(dst_filename);
+
+	std::string filepath = gDirUtilp->getExpandedFilename(LL_PATH_CACHE,asset_uuid.asString());
+	std::string dst_filename = llformat("%s.lso", filepath.c_str());
+	LLFile::remove(dst_filename.c_str());
 	delete data;
 }
 
@@ -1927,6 +1978,16 @@ BOOL LLLiveLSLEditor::canClose()
 	return (mScriptEd->canClose());
 }
 
+void LLLiveLSLEditor::closeIfNeeded()
+{
+	getWindow()->decBusyCount();
+	mPendingUploads--;
+	if (mPendingUploads <= 0 && mCloseAfterSave)
+	{
+		close();
+	}
+}
+
 // static
 void LLLiveLSLEditor::onLoad(void* userdata)
 {
@@ -1970,6 +2031,13 @@ void LLLiveLSLEditor::hide(const LLUUID& script_id, const LLUUID& object_id)
 		delete instance;
 	}
 }
+// static
+LLLiveLSLEditor* LLLiveLSLEditor::find(const LLUUID& script_id, const LLUUID& object_id)
+{
+	LLUUID xored_id = script_id ^ object_id;
+	return sInstances.getIfThere(xored_id);
+}
+
 
 // static
 void LLLiveLSLEditor::processScriptRunningReply(LLMessageSystem* msg, void**)
diff --git a/indra/newview/llpreviewscript.h b/indra/newview/llpreviewscript.h
index 9b2beb9ce93..5b15fda2227 100644
--- a/indra/newview/llpreviewscript.h
+++ b/indra/newview/llpreviewscript.h
@@ -116,15 +116,24 @@ class LLPreviewLSL : public LLPreview
 public:
 	LLPreviewLSL(const std::string& name, const LLRect& rect, const std::string& title,
 				 const LLUUID& item_uuid );
+	virtual void callbackLSLCompileSucceeded();
+	virtual void callbackLSLCompileFailed(const LLSD& compile_errors);
 
 	/*virtual*/ void open();		/*Flawfinder: ignore*/
 
 protected:
 	virtual BOOL canClose();
+	void closeIfNeeded();
 	virtual void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
 
 	virtual void loadAsset();
 	void saveIfNeeded();
+	void uploadAssetViaCaps(const std::string& url,
+							const std::string& filename, 
+							const LLUUID& item_id);
+	void uploadAssetLegacy(const std::string& filename,
+							const LLUUID& item_id,
+							const LLTransactionID& tid);
 
 	static void onLoad(void* userdata);
 	static void onSave(void* userdata, BOOL close_after_save);
@@ -158,17 +167,33 @@ class LLLiveLSLEditor : public LLPreview
 
 	static LLLiveLSLEditor* show(const LLUUID& item_id, const LLUUID& object_id);
 	static void hide(const LLUUID& item_id, const LLUUID& object_id);
+	static LLLiveLSLEditor* find(const LLUUID& item_id, const LLUUID& object_id);
 
 	static void processScriptRunningReply(LLMessageSystem* msg, void**);
-	
+
+	virtual void callbackLSLCompileSucceeded(const LLUUID& task_id,
+											const LLUUID& item_id,
+											bool is_script_running);
+	virtual void callbackLSLCompileFailed(const LLSD& compile_errors);
+
 protected:
 	virtual BOOL canClose();
+	void closeIfNeeded();
 	virtual void draw();
 	virtual void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
 
 	virtual void loadAsset();
 	void loadAsset(BOOL is_new);
 	void saveIfNeeded();
+	void uploadAssetViaCaps(const std::string& url,
+							const std::string& filename, 
+							const LLUUID& task_id,
+							const LLUUID& item_id,
+							BOOL is_running);
+	void uploadAssetLegacy(const std::string& filename,
+						   LLViewerObject* object,
+						   const LLTransactionID& tid,
+						   BOOL is_running);
 
 	static void onLoad(void* userdata);
 	static void onSave(void* userdata, BOOL close_after_save);
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index e6c6576ae18..f8cc68d6838 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -833,6 +833,7 @@ BOOL idle_startup()
 		case USERSERVER_SHAKTI:
 		case USERSERVER_DURGA:
 		case USERSERVER_SOMA:
+		case USERSERVER_VAAK:
 		case USERSERVER_GANGA:
 		case USERSERVER_UMA:
 		{
@@ -2557,6 +2558,7 @@ void login_show()
 	LLPanelLogin::addServer( gUserServerDomainName[USERSERVER_GANGA].mLabel,	USERSERVER_GANGA );
 	LLPanelLogin::addServer( gUserServerDomainName[USERSERVER_UMA].mLabel,	USERSERVER_UMA );
 	LLPanelLogin::addServer( gUserServerDomainName[USERSERVER_SOMA].mLabel,	USERSERVER_SOMA );
+	LLPanelLogin::addServer( gUserServerDomainName[USERSERVER_VAAK].mLabel,	USERSERVER_VAAK );
 }
 
 // Callback for when login screen is closed.  Option 0 = connect, option 1 = quit.
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index 9ac566b02b7..a638d993812 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -273,6 +273,7 @@ BOOL enable_save_as(void *);
 
 // Edit menu
 void handle_dump_group_info(void *);
+void handle_dump_capabilities_info(void *);
 void handle_dump_focus(void*);
 
 void handle_region_dump_settings(void*);
@@ -716,6 +717,8 @@ void init_client_menu(LLMenuGL* menu)
 			&handle_region_dump_settings, NULL));
 		sub->append(new LLMenuItemCallGL("Group Info to Debug Console",
 			&handle_dump_group_info, NULL, NULL));
+		sub->append(new LLMenuItemCallGL("Capabilities Info to Debug Console",
+			&handle_dump_capabilities_info, NULL, NULL));
 		sub->createJumpKeys();
 	}
 	
@@ -2451,6 +2454,14 @@ void handle_dump_group_info(void *)
 	//llinfos << "insig   " << gAgent.mGroupInsigniaID << llendl;
 }
 
+void handle_dump_capabilities_info(void *)
+{
+	LLViewerRegion* regionp = gAgent.getRegion();
+	if (regionp)
+	{
+		regionp->logActiveCapabilities();
+	}
+}
 
 void handle_dump_focus(void *)
 {
@@ -5689,7 +5700,7 @@ void upload_new_resource(const LLTransactionID &tid, LLAssetType::EType asset_ty
 	llinfos << "Desc: " << desc << llendl;
 	lldebugs << "Folder: " << gInventory.findCategoryUUIDForType(destination_folder_type) << llendl;
 	lldebugs << "Asset Type: " << LLAssetType::lookup(asset_type) << llendl;
-	std::string url = gAgent.getRegion()->getCapability("NewAgentInventory");
+	std::string url = gAgent.getRegion()->getCapability("NewFileAgentInventory");
 	if (!url.empty())
 	{
 		llinfos << "New Agent Inventory via capability" << llendl;
@@ -5703,7 +5714,7 @@ void upload_new_resource(const LLTransactionID &tid, LLAssetType::EType asset_ty
 		std::ostringstream llsdxml;
 		LLSDSerialize::toXML(body, llsdxml);
 		lldebugs << "posting body to capability: " << llsdxml.str() << llendl;
-		LLHTTPClient::post(url, body, new LLNewAgentInventoryResponder(uuid, body));
+		LLHTTPClient::post(url, body, new LLNewAgentInventoryResponder(body, uuid, asset_type));
 	}
 	else
 	{
diff --git a/indra/newview/llviewernetwork.cpp b/indra/newview/llviewernetwork.cpp
index 189b314e55a..f62949cadfd 100644
--- a/indra/newview/llviewernetwork.cpp
+++ b/indra/newview/llviewernetwork.cpp
@@ -46,6 +46,10 @@ LLUserServerData gUserServerDomainName[USERSERVER_COUNT] =
 	  "userserver.ganga.lindenlab.com",
 	  "https://login.ganga.lindenlab.com/cgi-bin/login.cgi",
 	  "http://ganga-secondlife.webdev.lindenlab.com/helpers/" },
+	{ "Vaak",
+	  "userserver.vaak.lindenlab.com",
+	  "https://login.vaak.lindenlab.com/cgi-bin/login.cgi",
+	  "http://vaak-secondlife.webdev.lindenlab.com/helpers/" },
 	{ "Uma",
 	  "userserver.uma.lindenlab.com",
 	  "https://login.uma.lindenlab.com/cgi-bin/login.cgi",
diff --git a/indra/newview/llviewernetwork.h b/indra/newview/llviewernetwork.h
index d461369d028..9eb2d9fcddb 100644
--- a/indra/newview/llviewernetwork.h
+++ b/indra/newview/llviewernetwork.h
@@ -23,6 +23,7 @@ enum EUserServerDomain
 	USERSERVER_SHAKTI,
 	USERSERVER_SOMA,
 	USERSERVER_GANGA,
+	USERSERVER_VAAK,
 	USERSERVER_UMA,
 	USERSERVER_LOCAL,
 	USERSERVER_OTHER, // IP address set via -user or other command line option
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index 6a20aa4a952..a09ce3011f5 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -2323,41 +2323,45 @@ void LLViewerObject::processTaskInv(LLMessageSystem* msg, void** user_data)
 	LLUUID task_id;
 	msg->getUUIDFast(_PREHASH_InventoryData, _PREHASH_TaskID, task_id);
 	LLViewerObject* object = gObjectList.findObject(task_id);
-	if(object)
+	if(!object)
 	{
-		msg->getS16Fast(_PREHASH_InventoryData, _PREHASH_Serial, object->mInventorySerialNum);
-		LLFilenameAndTask* ft = new LLFilenameAndTask;
-		ft->mTaskID = task_id;
-		msg->getStringFast(_PREHASH_InventoryData, _PREHASH_Filename, MAX_STRING, ft->mFilename);
-		if(!ft->mFilename[0])
+		llwarns << "LLViewerObject::processTaskInv object "
+			<< task_id << " does not exist." << llendl;
+		return;
+	}
+
+	msg->getS16Fast(_PREHASH_InventoryData, _PREHASH_Serial, object->mInventorySerialNum);
+	LLFilenameAndTask* ft = new LLFilenameAndTask;
+	ft->mTaskID = task_id;
+	msg->getStringFast(_PREHASH_InventoryData, _PREHASH_Filename, MAX_STRING, ft->mFilename);
+	if(!ft->mFilename[0])
+	{
+		lldebugs << "Task has no inventory" << llendl;
+		// mock up some inventory to make a drop target.
+		if(object->mInventory)
 		{
-			lldebugs << "Task has no inventory" << llendl;
-			// mock up some inventory to make a drop target.
-			if(object->mInventory)
-			{
-				object->mInventory->clear(); // will deref and delete it
-			}
-			else
-			{
-				object->mInventory = new InventoryObjectList();
-			}
-			LLPointer<LLInventoryObject> obj;
-			obj = new LLInventoryObject(object->mID, LLUUID::null,
-										LLAssetType::AT_CATEGORY,
-										"Contents");
-			object->mInventory->push_front(obj);
-			object->doInventoryCallback();
-			delete ft;
-			return;
+			object->mInventory->clear(); // will deref and delete it
 		}
-		gXferManager->requestFile(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, ft->mFilename).c_str(), 
-								  ft->mFilename, LL_PATH_CACHE,
-								  object->mRegionp->getHost(),
-								  TRUE,
-								  &LLViewerObject::processTaskInvFile,
-								  (void**)ft,
-								  LLXferManager::HIGH_PRIORITY);
+		else
+		{
+			object->mInventory = new InventoryObjectList();
+		}
+		LLPointer<LLInventoryObject> obj;
+		obj = new LLInventoryObject(object->mID, LLUUID::null,
+									LLAssetType::AT_CATEGORY,
+									"Contents");
+		object->mInventory->push_front(obj);
+		object->doInventoryCallback();
+		delete ft;
+		return;
 	}
+	gXferManager->requestFile(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, ft->mFilename).c_str(), 
+								ft->mFilename, LL_PATH_CACHE,
+								object->mRegionp->getHost(),
+								TRUE,
+								&LLViewerObject::processTaskInvFile,
+								(void**)ft,
+								LLXferManager::HIGH_PRIORITY);
 }
 
 void LLViewerObject::processTaskInvFile(void** user_data, S32 error_code)
@@ -2582,6 +2586,18 @@ LLViewerInventoryItem* LLViewerObject::getInventoryItemByAsset(const LLUUID& ass
 	return rv;
 }
 
+void LLViewerObject::updateViewerInventoryAsset(
+					const LLViewerInventoryItem* item,
+					const LLUUID& new_asset)
+{
+	LLPointer<LLViewerInventoryItem> task_item =
+		new LLViewerInventoryItem(item);
+	task_item->setAssetUUID(new_asset);
+
+	// do the internal logic
+	doUpdateInventory(task_item, TASK_INVENTORY_ITEM_KEY, false);
+}
+
 void LLViewerObject::setPixelAreaAndAngle(LLAgent &agent)
 {
 	if (getVolume())
diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h
index d8b5a14897d..80d32409043 100644
--- a/indra/newview/llviewerobject.h
+++ b/indra/newview/llviewerobject.h
@@ -363,6 +363,11 @@ class LLViewerObject : public LLPrimitive, public LLRefCount
 	LLViewerInventoryItem* getInventoryItemByAsset(const LLUUID& asset_id);
 	S16 getInventorySerial() const { return mInventorySerialNum; }
 
+	// These functions does viewer-side only object inventory modifications
+	void updateViewerInventoryAsset(
+		const LLViewerInventoryItem* item,
+		const LLUUID& new_asset);
+
 	// This function will make sure that we refresh the inventory.
 	void dirtyInventory();
 	BOOL isInventoryDirty() { return mInventoryDirty; }
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index 52354101562..262c7d8ed72 100644
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -1260,8 +1260,19 @@ void LLViewerRegion::setSeedCapability(const std::string& url)
 	LLSD capabilityNames = LLSD::emptyArray();
 	capabilityNames.append("MapLayer");
 	capabilityNames.append("MapLayerGod");
-	capabilityNames.append("NewAgentInventory");
+	capabilityNames.append("NewFileAgentInventory");
 	capabilityNames.append("EventQueueGet");
+	capabilityNames.append("UpdateGestureAgentInventory");
+	capabilityNames.append("UpdateNotecardAgentInventory");
+	capabilityNames.append("UpdateScriptAgentInventory");
+	capabilityNames.append("UpdateGestureTaskInventory");
+	capabilityNames.append("UpdateNotecardTaskInventory");
+	capabilityNames.append("UpdateScriptTaskInventory");
+	capabilityNames.append("SendPostcard");
+	capabilityNames.append("ViewerStartAuction");
+	capabilityNames.append("ParcelGodReserveForNewbie");
+	capabilityNames.append("SendUserReport");
+	capabilityNames.append("SendUserReportWithScreenshot");
 	capabilityNames.append("RequestTextureDownload");
 	LLHTTPClient::post(url, capabilityNames, BaseCapabilitiesComplete::build(this));
 }
@@ -1304,3 +1315,16 @@ std::string LLViewerRegion::getCapability(const std::string& name) const
 	return iter->second;
 }
 
+void LLViewerRegion::logActiveCapabilities() const
+{
+	CapabilityMap::const_iterator iter;
+	for (iter = mCapabilities.begin(); iter != mCapabilities.end(); iter++)
+	{
+		if (!iter->second.empty())
+		{
+			// llinfos << "Active capability is " << iter->first << llendl;
+			llinfos << iter->first << " URL is " << iter->second << llendl;
+		}
+	}
+}
+
diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h
index b3392baf814..1dc1b3af205 100644
--- a/indra/newview/llviewerregion.h
+++ b/indra/newview/llviewerregion.h
@@ -169,6 +169,7 @@ class LLViewerRegion
 	void setSeedCapability(const std::string& url);
 	void setCapability(const std::string& name, const std::string& url);
 	std::string getCapability(const std::string& name) const;
+	void logActiveCapabilities() const;
 
 	const LLHost	&getHost() const			{ return mHost; }
 	const U64 		&getHandle() const 			{ return mHandle; }
diff --git a/indra/newview/llviewertexteditor.cpp b/indra/newview/llviewertexteditor.cpp
index 7d04f04528b..259fa093098 100644
--- a/indra/newview/llviewertexteditor.cpp
+++ b/indra/newview/llviewertexteditor.cpp
@@ -53,6 +53,9 @@ class LLEmbeddedItems
 	LLEmbeddedItems(const LLViewerTextEditor* editor);
 	~LLEmbeddedItems();
 	void clear();
+
+	// return true if there are no embedded items.
+	bool empty();
 	
 	void	bindEmbeddedChars(const LLFontGL* font);
 	void	unbindEmbeddedChars(const LLFontGL* font);
@@ -115,6 +118,13 @@ void LLEmbeddedItems::clear()
 		removeEmbeddedItem(*nextiter);
 	}
 	mEmbeddedUsedChars.clear();
+	mEmbeddedIndexedChars.clear();
+}
+
+bool LLEmbeddedItems::empty()
+{
+	removeUnusedChars();
+	return mEmbeddedUsedChars.empty();
 }
 
 // Inserts a new unique entry
@@ -1367,10 +1377,11 @@ S32 LLViewerTextEditor::insertEmbeddedItem( S32 pos, LLInventoryItem* item )
 
 bool LLViewerTextEditor::importStream(std::istream& str)
 {
-	LLNotecard nc(MAX_NOTECARD_SIZE);
+	LLNotecard nc(LLNotecard::MAX_SIZE);
 	bool success = nc.importStream(str);
 	if (success)
 	{
+		mEmbeddedItemList->clear();
 		const std::vector<LLPointer<LLInventoryItem> >& items = nc.getItems();
 		mEmbeddedItemList->addItems(items);
 		// Actually set the text
@@ -1396,6 +1407,11 @@ void LLViewerTextEditor::copyInventory(LLInventoryItem* item)
 								 item);
 }
 
+bool LLViewerTextEditor::hasEmbeddedInventory()
+{
+	return (!(mEmbeddedItemList->empty()));
+}
+
 ////////////////////////////////////////////////////////////////////////////
 
 BOOL LLViewerTextEditor::importBuffer( const LLString& buffer )
@@ -1406,7 +1422,7 @@ BOOL LLViewerTextEditor::importBuffer( const LLString& buffer )
 
 BOOL LLViewerTextEditor::exportBuffer( LLString& buffer )
 {
-	LLNotecard nc(MAX_NOTECARD_SIZE);
+	LLNotecard nc(LLNotecard::MAX_SIZE);
 
 	std::vector<LLPointer<LLInventoryItem> > embedded_items;
 	mEmbeddedItemList->getEmbeddedItemList(embedded_items);
diff --git a/indra/newview/llviewertexteditor.h b/indra/newview/llviewertexteditor.h
index 99e971b33ca..de57b68e7df 100644
--- a/indra/newview/llviewertexteditor.h
+++ b/indra/newview/llviewertexteditor.h
@@ -67,7 +67,14 @@ class LLViewerTextEditor : public LLTextEditor
 		// If this starts a line, you need to prepend a newline.
 
 	void copyInventory(LLInventoryItem* item);
-	
+
+	// returns true if there is embedded inventory.
+	// *HACK: This is only useful because the notecard verifier may
+	// change the asset if there is embedded inventory. This mechanism
+	// should be changed to get a different asset id from the verifier
+	// rather than checking if a re-load is necessary. Phoenix 2007-02-27
+	bool hasEmbeddedInventory();
+
 protected:
 	// Embedded object operations
 	virtual llwchar	pasteEmbeddedItem(llwchar ext_char);
diff --git a/indra/newview/llwearable.cpp b/indra/newview/llwearable.cpp
index 522e9c9a56a..9e85e293d49 100644
--- a/indra/newview/llwearable.cpp
+++ b/indra/newview/llwearable.cpp
@@ -15,11 +15,13 @@
 #include "llquantize.h"
 
 #include "llagent.h"
+#include "llassetuploadresponders.h"
 #include "llviewerwindow.h"
 #include "llfloatercustomize.h"
 #include "llinventorymodel.h"
 #include "llviewerimagelist.h"
 #include "llviewerinventory.h"
+#include "llviewerregion.h"
 #include "llvoavatar.h"
 #include "llwearable.h"
 
@@ -886,11 +888,28 @@ void LLWearable::saveNewAsset()
 	// save it out to database
 	if( gAssetStorage )
 	{
-		LLWearableSaveData* data = new LLWearableSaveData;
-		data->mType = mType;
-		gAssetStorage->storeAssetData(filename, mTransactionID, getAssetType(),
-										&LLWearable::onSaveNewAssetComplete,
-										(void*)data);
+		 /*
+		std::string url = gAgent.getRegion()->getCapability("NewAgentInventory");
+		if (!url.empty())
+		{
+			llinfos << "Update Agent Inventory via capability" << llendl;
+			LLSD body;
+			body["folder_id"] = gInventory.findCategoryUUIDForType(getAssetType());
+			body["asset_type"] = LLAssetType::lookup(getAssetType());
+			body["inventory_type"] = LLInventoryType::lookup(LLInventoryType::IT_WEARABLE);
+			body["name"] = getName();
+			body["description"] = getDescription();
+			LLHTTPClient::post(url, body, new LLNewAgentInventoryResponder(body, filename));
+		}
+		else
+		{
+		}
+		 */
+		 LLWearableSaveData* data = new LLWearableSaveData;
+		 data->mType = mType;
+		 gAssetStorage->storeAssetData(filename, mTransactionID, getAssetType(),
+                                     &LLWearable::onSaveNewAssetComplete,
+                                     (void*)data);
 	}
 }
 
diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index 301ab310d93..2c04a34da8a 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -324,12 +324,15 @@ def package_finish(self):
                 volpath = re.search('HFS\s+(.+)', hdi_output).group(1).strip()
 
                 # Copy everything in to the mounted .dmg
-                for s,d in {self.get_dst_prefix():("Second Life " + self.args['grid']).strip()+ ".app",
-                                        "lsl_guide.html":"Linden Scripting Language Guide.html",
-                                        "releasenotes.txt":"Release Notes.txt",
-                                        "installers/darwin/mac_image_hidden":".hidden",
-                                        "installers/darwin/mac_image_background.tga":"background.tga",
-                                        "installers/darwin/mac_image_DS_Store":".DS_Store"}.items():
+                # TODO change name of .app once mac_updater can handle it.
+                for s,d in {
+                        self.get_dst_prefix():"Second Life.app",
+                        "lsl_guide.html":"Linden Scripting Language Guide.html",
+                        "releasenotes.txt":"Release Notes.txt",
+                        "installers/darwin/mac_image_hidden":".hidden",
+                        "installers/darwin/mac_image_background.tga":"background.tga",
+                        "installers/darwin/mac_image_DS_Store":".DS_Store"}.items():
+                        
                         print "Copying to dmg", s, d
                         self.copy_action(self.src_path_of(s), os.path.join(volpath, d))
 
-- 
GitLab