Merge mozilla-central and mozilla-inbound
authorEd Morley <bmo@edmorley.co.uk>
Sun, 23 Oct 2011 17:16:21 +0100
changeset 79132 a1b89b4913ca9d9e647eebc4858f695c74b2e2a8
parent 79122 1fa31fa8508280b5299234e9c2981925f9aeca84 (current diff)
parent 79131 969648d5182542a4c7472a7e94a5d252f856a0b1 (diff)
child 79133 182a55b58e0171f0e14e5e750204f6e26299db23
child 79139 7e48b16bb2d49c132e3bf008691a2451428f7392
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
milestone10.0a1
Merge mozilla-central and mozilla-inbound
layout/reftests/css-gradients/linear-keywords-ref.html
layout/reftests/css-gradients/linear-keywords.html
layout/reftests/css-gradients/linear-ref.html
layout/reftests/css-gradients/linear.html
security/nss/lib/ssl/sslerrstrs.h
security/nss/lib/ssl/sslutil.h
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -72,17 +72,17 @@ pref("extensions.blocklist.url", "https:
 pref("extensions.blocklist.detailsURL", "https://www.mozilla.com/%LOCALE%/blocklist/");
 pref("extensions.blocklist.itemURL", "https://addons.mozilla.org/%LOCALE%/%APP%/blocked/%blockID%");
 
 pref("extensions.update.autoUpdateDefault", true);
 
 // Disable add-ons installed into the shared user and shared system areas by
 // default. This does not include the application directory. See the SCOPE
 // constants in AddonManager.jsm for values to use here
-pref("extensions.autoDisableScopes", 10);
+pref("extensions.autoDisableScopes", 15);
 
 // Dictionary download preference
 pref("browser.dictionaries.download.url", "https://addons.mozilla.org/%LOCALE%/firefox/dictionaries/");
 
 // The minimum delay in seconds for the timer to fire.
 // default=2 minutes
 pref("app.update.timerMinimumDelay", 120);
 
--- a/build/automation.py.in
+++ b/build/automation.py.in
@@ -1016,19 +1016,19 @@ user_pref("camino.use_system_proxy_setti
                   this is the name of the folder in the <profileDir>/extensions/<extensionID>
     """
     if not os.path.isdir(profileDir):
       self.log.info("INFO | automation.py | Cannot install extension, invalid profileDir at: %s", profileDir)
       return
 
     installRDFFilename = "install.rdf"
 
-    extensionsRootDir = os.path.join(profileDir, "extensions")
+    extensionsRootDir = os.path.join(profileDir, "extensions", "staged")
     if not os.path.isdir(extensionsRootDir):
-      os.mkdir(extensionsRootDir)
+      os.makedirs(extensionsRootDir)
 
     if os.path.isfile(extensionSource):
       reader = ZipFileReader(extensionSource)
 
       for filename in reader.namelist():
         # Sanity check the zip file.
         if os.path.isabs(filename):
           self.log.info("INFO | automation.py | Cannot install extension, bad files in xpi")
--- a/js/src/jsgcmark.cpp
+++ b/js/src/jsgcmark.cpp
@@ -181,17 +181,17 @@ MarkCrossCompartmentObject(JSTracer *trc
     if (rt->gcCurrentCompartment && rt->gcCurrentCompartment != obj.compartment())
         return;
 
     MarkObject(trc, obj, name);
 }
 
 void
 MarkObjectWithPrinter(JSTracer *trc, JSObject &obj, JSTraceNamePrinter printer,
-		      const void *arg, size_t index)
+                      const void *arg, size_t index)
 {
     JS_ASSERT(trc);
     JS_ASSERT(&obj);
     JS_SET_TRACING_DETAILS(trc, printer, arg, index);
     Mark(trc, &obj);
 }
 
 void
@@ -991,29 +991,29 @@ GCMarker::drainMarkStack()
 
 } /* namespace js */
 
 JS_PUBLIC_API(void)
 JS_TraceChildren(JSTracer *trc, void *thing, JSGCTraceKind kind)
 {
     switch (kind) {
       case JSTRACE_OBJECT:
-	MarkChildren(trc, static_cast<JSObject *>(thing));
+        MarkChildren(trc, static_cast<JSObject *>(thing));
         break;
 
       case JSTRACE_STRING:
-	MarkChildren(trc, static_cast<JSString *>(thing));
+        MarkChildren(trc, static_cast<JSString *>(thing));
         break;
 
       case JSTRACE_SCRIPT:
-	MarkChildren(trc, static_cast<JSScript *>(thing));
+        MarkChildren(trc, static_cast<JSScript *>(thing));
         break;
 
       case JSTRACE_SHAPE:
-	MarkChildren(trc, static_cast<Shape *>(thing));
+        MarkChildren(trc, static_cast<Shape *>(thing));
         break;
 
       case JSTRACE_TYPE_OBJECT:
         MarkChildren(trc, (types::TypeObject *)thing);
         break;
 
 #if JS_HAS_XML_SUPPORT
       case JSTRACE_XML:
--- a/js/src/jsinfer.cpp
+++ b/js/src/jsinfer.cpp
@@ -1453,16 +1453,18 @@ GetValueTypeFromTypeFlags(TypeFlags flag
       case TYPE_FLAG_INT32:
         return JSVAL_TYPE_INT32;
       case (TYPE_FLAG_INT32 | TYPE_FLAG_DOUBLE):
         return JSVAL_TYPE_DOUBLE;
       case TYPE_FLAG_STRING:
         return JSVAL_TYPE_STRING;
       case TYPE_FLAG_LAZYARGS:
         return JSVAL_TYPE_MAGIC;
+      case TYPE_FLAG_ANYOBJECT:
+        return JSVAL_TYPE_OBJECT;
       default:
         return JSVAL_TYPE_UNKNOWN;
     }
 }
 
 JSValueType
 TypeSet::getKnownTypeTag(JSContext *cx)
 {
--- a/js/src/methodjit/MonoIC.cpp
+++ b/js/src/methodjit/MonoIC.cpp
@@ -936,28 +936,37 @@ class CallCompiler : public BaseCompiler
 
         RecompilationMonitor monitor(cx);
 
         if (!CallJSNative(cx, fun->u.n.native, args))
             THROWV(true);
 
         types::TypeScript::Monitor(f.cx, f.script(), f.pc(), args.rval());
 
+        /*
+         * Native stubs are not generated for inline frames. The overhead of
+         * bailing out from the IC is far greater than the time saved by
+         * inlining the parent frame in the first place, so mark the immediate
+         * caller as uninlineable.
+         */
+        if (f.script()->hasFunction) {
+            f.script()->uninlineable = true;
+            MarkTypeObjectFlags(cx, f.script()->function(), types::OBJECT_FLAG_UNINLINEABLE);
+        }
+
         /* Don't touch the IC if the call triggered a recompilation. */
         if (monitor.recompiled())
             return true;
 
+        JS_ASSERT(!f.regs.inlined());
+
         /* Right now, take slow-path for IC misses or multiple stubs. */
         if (ic.fastGuardedNative || ic.hasJsFunCheck)
             return true;
 
-        /* Don't generate native MICs within inlined frames, we can't recompile them yet. */
-        if (f.regs.inlined())
-            return true;
-
         /* Native MIC needs to warm up first. */
         if (!ic.hit) {
             ic.hit = true;
             return true;
         }
 
         /* Generate fast-path for calling this native. */
         Assembler masm;
--- a/js/src/methodjit/PolyIC.cpp
+++ b/js/src/methodjit/PolyIC.cpp
@@ -809,18 +809,27 @@ struct GetPropertyHelper {
                     return ic.disable(cx, "method valued shape");
             } else {
                 if (shape->hasGetterValue())
                     return ic.disable(cx, "getter value shape");
                 if (shape->hasSlot() && holder != obj)
                     return ic.disable(cx, "slotful getter hook through prototype");
                 if (!ic.canCallHook)
                     return ic.disable(cx, "can't call getter hook");
-                if (f.regs.inlined())
-                    return ic.disable(cx, "hook called from inline frame");
+                if (f.regs.inlined()) {
+                    /*
+                     * As with native stubs, getter hook stubs can't be
+                     * generated for inline frames. Mark the inner function
+                     * as uninlineable and recompile.
+                     */
+                    f.script()->uninlineable = true;
+                    MarkTypeObjectFlags(cx, f.script()->function(),
+                                        types::OBJECT_FLAG_UNINLINEABLE);
+                    return Lookup_Uncacheable;
+                }
             }
         } else if (!shape->hasSlot()) {
             return ic.disable(cx, "no slot");
         }
 
         return Lookup_Cacheable;
     }
 
--- a/js/src/vm/CallObject.h
+++ b/js/src/vm/CallObject.h
@@ -51,26 +51,26 @@ class CallObject : public ::JSObject
      * private               - the stack frame corresponding to the Call object
      *                         until js_PutCallObject or its on-trace analog
      *                         is called, null thereafter
      * JSSLOT_CALL_CALLEE    - callee function for the stack frame, or null if
      *                         the stack frame is for strict mode eval code
      * JSSLOT_CALL_ARGUMENTS - arguments object for non-strict mode eval stack
      *                         frames (not valid for strict mode eval frames)
      */
-    static const uint32 CALLEE_SLOT = 0;
-    static const uint32 ARGUMENTS_SLOT = 1;
+    static const uintN CALLEE_SLOT = 0;
+    static const uintN ARGUMENTS_SLOT = 1;
 
-public:
+  public:
+    static const uintN RESERVED_SLOTS = 2;
+
     /* Create a CallObject for the given callee function. */
     static CallObject *
     create(JSContext *cx, JSScript *script, JSObject &scopeChain, JSObject *callee);
 
-    static const uint32 RESERVED_SLOTS = 2;
-
     /* True if this is for a strict mode eval frame or for a function call. */
     inline bool isForEval() const;
 
     /* The stack frame for this CallObject, if the frame is still active. */
     inline js::StackFrame *maybeStackFrame() const;
     inline void setStackFrame(js::StackFrame *frame);
 
     /*
--- a/layout/base/nsCSSRendering.cpp
+++ b/layout/base/nsCSSRendering.cpp
@@ -1799,16 +1799,23 @@ ComputeLinearGradientLine(nsPresContext*
     if (aGradient->mAngle.IsAngleValue()) {
       angle = aGradient->mAngle.GetAngleValueInRadians();
     } else {
       angle = -M_PI_2; // defaults to vertical gradient starting from top
     }
     gfxPoint center(aBoxSize.width/2, aBoxSize.height/2);
     *aLineEnd = ComputeGradientLineEndFromAngle(center, angle, aBoxSize);
     *aLineStart = gfxPoint(aBoxSize.width, aBoxSize.height) - *aLineEnd;
+  } else if (aGradient->mToCorner) {
+    float xSign = aGradient->mBgPosX.GetPercentValue() * 2 - 1;
+    float ySign = 1 - aGradient->mBgPosY.GetPercentValue() * 2;
+    double angle = atan2(ySign * aBoxSize.width, xSign * aBoxSize.height);
+    gfxPoint center(aBoxSize.width/2, aBoxSize.height/2);
+    *aLineEnd = ComputeGradientLineEndFromAngle(center, angle, aBoxSize);
+    *aLineStart = gfxPoint(aBoxSize.width, aBoxSize.height) - *aLineEnd;
   } else {
     PRInt32 appUnitsPerPixel = aPresContext->AppUnitsPerDevPixel();
     *aLineStart = gfxPoint(
       ConvertGradientValueToPixels(aGradient->mBgPosX, aBoxSize.width,
                                    appUnitsPerPixel),
       ConvertGradientValueToPixels(aGradient->mBgPosY, aBoxSize.height,
                                    appUnitsPerPixel));
     if (aGradient->mAngle.IsAngleValue()) {
--- a/layout/base/nsDisplayList.cpp
+++ b/layout/base/nsDisplayList.cpp
@@ -615,16 +615,22 @@ void nsDisplayList::PaintForFrame(nsDisp
     if (content) {
       usingDisplayport = nsLayoutUtils::GetDisplayPort(content, &displayport);
     }
   }
   RecordFrameMetrics(aForFrame, rootScrollFrame,
                      root, mVisibleRect, mVisibleRect,
                      (usingDisplayport ? &displayport : nsnull), id,
                      containerParameters);
+  if (usingDisplayport &&
+      !(root->GetContentFlags() & Layer::CONTENT_OPAQUE)) {
+    // See bug 693938, attachment 567017
+    NS_WARNING("We don't support transparent content with displayports, force it to be opqaue");
+    root->SetContentFlags(Layer::CONTENT_OPAQUE);
+  }
 
   layerManager->SetRoot(root);
   aBuilder->LayerBuilder()->WillEndTransaction(layerManager);
   layerManager->EndTransaction(FrameLayerBuilder::DrawThebesLayer,
                                aBuilder);
   aBuilder->LayerBuilder()->DidEndTransaction(layerManager);
 
   if (aFlags & PAINT_FLUSH_LAYERS) {
--- a/layout/base/nsPresShell.cpp
+++ b/layout/base/nsPresShell.cpp
@@ -194,16 +194,17 @@
 
 // Content viewer interfaces
 #include "nsIContentViewer.h"
 #include "imgIEncoder.h"
 #include "gfxPlatform.h"
 
 #include "mozilla/FunctionTimer.h"
 #include "mozilla/Preferences.h"
+#include "mozilla/Telemetry.h"
 
 #include "Layers.h"
 
 #ifdef NS_FUNCTION_TIMER
 #define NS_TIME_FUNCTION_DECLARE_DOCURL                \
   nsCAutoString docURL__("N/A");                       \
   nsIURI *uri__ = mDocument->GetDocumentURI();         \
   if (uri__) uri__->GetSpec(docURL__);
@@ -1901,16 +1902,17 @@ PresShell::InitialReflow(nscoord aWidth,
   }
 
   if (!mDocument) {
     // Nothing to do
     return NS_OK;
   }
 
   NS_TIME_FUNCTION_WITH_DOCURL;
+  mozilla::TimeStamp timerStart = mozilla::TimeStamp::Now();
 
   NS_ASSERTION(!mDidInitialReflow, "Why are we being called?");
 
   nsCOMPtr<nsIPresShell> kungFuDeathGrip(this);
   mDidInitialReflow = true;
 
 #ifdef NS_DEBUG
   if (VERIFY_REFLOW_NOISY_RC & gVerifyReflowFlags) {
@@ -2041,16 +2043,21 @@ PresShell::InitialReflow(nscoord aWidth,
                             PAINTLOCK_EVENT_DELAY);
 
       mPaintSuppressionTimer->InitWithFuncCallback(sPaintSuppressionCallback,
                                                    this, delay, 
                                                    nsITimer::TYPE_ONE_SHOT);
     }
   }
 
+  if (root && root->IsXUL()) {
+    mozilla::Telemetry::AccumulateTimeDelta(Telemetry::XUL_INITIAL_FRAME_CONSTRUCTION,
+                                            timerStart);
+  }
+
   return NS_OK; //XXX this needs to be real. MMP
 }
 
 void
 PresShell::sPaintSuppressionCallback(nsITimer *aTimer, void* aPresShell)
 {
   nsRefPtr<PresShell> self = static_cast<PresShell*>(aPresShell);
   if (self)
@@ -7326,17 +7333,17 @@ PresShell::DoVerifyReflow()
   }
 }
 #endif
 
 bool
 PresShell::ProcessReflowCommands(bool aInterruptible)
 {
   NS_TIME_FUNCTION_WITH_DOCURL;
-
+  mozilla::TimeStamp timerStart = mozilla::TimeStamp::Now();
   bool interrupted = false;
   if (0 != mDirtyRoots.Length()) {
 
 #ifdef DEBUG
     if (VERIFY_REFLOW_DUMP_COMMANDS & gVerifyReflowFlags) {
       printf("ProcessReflowCommands: begin incremental reflow\n");
     }
 #endif
@@ -7405,16 +7412,21 @@ PresShell::ProcessReflowCommands(bool aI
     // We only unlock if we're out of reflows.  It's pointless
     // to unlock if reflows are still pending, since reflows
     // are just going to thrash the frames around some more.  By
     // waiting we avoid an overeager "jitter" effect.
     mShouldUnsuppressPainting = false;
     UnsuppressAndInvalidate();
   }
 
+  if (mDocument->GetRootElement() && mDocument->GetRootElement()->IsXUL()) {
+    mozilla::Telemetry::AccumulateTimeDelta(Telemetry::XUL_REFLOW_MS,
+                                            timerStart);
+  }
+
   return !interrupted;
 }
 
 #ifdef MOZ_XUL
 /*
  * It's better to add stuff to the |DidSetStyleContext| method of the
  * relevant frames than adding it here.  These methods should (ideally,
  * anyway) go away.
rename from layout/reftests/css-gradients/linear-ref.html
rename to layout/reftests/css-gradients/linear-1-ref.html
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-gradients/linear-1a.html
@@ -0,0 +1,1 @@
+<div style="background: -moz-linear-gradient(to right, red 0%, #7777FF 50%, rgb(100, 200, 0) 100%) no-repeat; width: 300px; height: 300px;"><br></div>
rename from layout/reftests/css-gradients/linear.html
rename to layout/reftests/css-gradients/linear-1b.html
--- a/layout/reftests/css-gradients/linear-diagonal-1-ref.html
+++ b/layout/reftests/css-gradients/linear-diagonal-1-ref.html
@@ -1,1 +1,1 @@
-<div style="background: -moz-linear-gradient(top left, white, black) no-repeat; width: 300px; height: 300px;"></div>
+<div style="background: -moz-linear-gradient(to bottom right, white, black) no-repeat; width: 300px; height: 300px;"></div>
copy from layout/reftests/css-gradients/linear-diagonal-1-ref.html
copy to layout/reftests/css-gradients/linear-diagonal-1c.html
--- a/layout/reftests/css-gradients/linear-diagonal-2-ref.html
+++ b/layout/reftests/css-gradients/linear-diagonal-2-ref.html
@@ -1,1 +1,1 @@
-<div style="background: -moz-linear-gradient(top right, white, black) no-repeat; width: 300px; height: 300px;"></div>
+<div style="background: -moz-linear-gradient(to bottom left, white, black) no-repeat; width: 300px; height: 300px;"></div>
copy from layout/reftests/css-gradients/linear-diagonal-2-ref.html
copy to layout/reftests/css-gradients/linear-diagonal-2c.html
--- a/layout/reftests/css-gradients/linear-diagonal-3-ref.html
+++ b/layout/reftests/css-gradients/linear-diagonal-3-ref.html
@@ -1,1 +1,1 @@
-<div style="background: -moz-linear-gradient(bottom right, white, black) no-repeat; width: 300px; height: 300px;"></div>
+<div style="background: -moz-linear-gradient(to top left, white, black) no-repeat; width: 300px; height: 300px;"></div>
copy from layout/reftests/css-gradients/linear-diagonal-3-ref.html
copy to layout/reftests/css-gradients/linear-diagonal-3c.html
--- a/layout/reftests/css-gradients/linear-diagonal-4-ref.html
+++ b/layout/reftests/css-gradients/linear-diagonal-4-ref.html
@@ -1,1 +1,1 @@
-<div style="background: -moz-linear-gradient(bottom left, white, black) no-repeat; width: 300px; height: 300px;"></div>
+<div style="background: -moz-linear-gradient(to top right, white, black) no-repeat; width: 300px; height: 300px;"></div>
copy from layout/reftests/css-gradients/linear-diagonal-4-ref.html
copy to layout/reftests/css-gradients/linear-diagonal-4c.html
--- a/layout/reftests/css-gradients/linear-diagonal-5-ref.html
+++ b/layout/reftests/css-gradients/linear-diagonal-5-ref.html
@@ -1,1 +1,1 @@
-<div style="background: -moz-linear-gradient(bottom right 135deg, white 75%, black); width: 400px; height: 400px;"></div>
+<div style="background: -moz-linear-gradient(to top left, white 75%, black); width: 400px; height: 400px;"></div>
--- a/layout/reftests/css-gradients/linear-diagonal-6-ref.html
+++ b/layout/reftests/css-gradients/linear-diagonal-6-ref.html
@@ -1,1 +1,1 @@
-<div style="background: -moz-linear-gradient(bottom left 45deg, white 75%, black); width: 400px; height: 400px;"></div>
+<div style="background: -moz-linear-gradient(to top right, white 75%, black); width: 400px; height: 400px;"></div>
--- a/layout/reftests/css-gradients/linear-diagonal-7-ref.html
+++ b/layout/reftests/css-gradients/linear-diagonal-7-ref.html
@@ -1,1 +1,1 @@
-<div style="background: -moz-linear-gradient(top left -45deg, white 75%, black); width: 400px; height: 400px;"></div>
+<div style="background: -moz-linear-gradient(to bottom right, white 75%, black); width: 400px; height: 400px;"></div>
--- a/layout/reftests/css-gradients/linear-diagonal-8-ref.html
+++ b/layout/reftests/css-gradients/linear-diagonal-8-ref.html
@@ -1,1 +1,1 @@
-<div style="background: -moz-linear-gradient(top right -135deg, white 75%, black); width: 400px; height: 400px;"></div>
+<div style="background: -moz-linear-gradient(to bottom left, white 75%, black); width: 400px; height: 400px;"></div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-gradients/linear-diagonal-9-ref.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<style>
+.x { width: 200px; height: 100px; display: inline-block; }
+.a { background: -moz-linear-gradient(top -90deg, blue, white, red); }
+.e { background: -moz-linear-gradient(top right -2.03444394rad, blue, white, red); }
+.g { background: -moz-linear-gradient(right 180deg, blue, white, red); }
+.i { background: -moz-linear-gradient(bottom right 2.03444394rad, blue, white, red); }
+.k { background: -moz-linear-gradient(bottom 90deg, blue, white, red); }
+.m { background: -moz-linear-gradient(bottom left 1.10714872rad, blue, white, red); }
+.o { background: -moz-linear-gradient(left 0deg, blue, white, red); }
+.q { background: -moz-linear-gradient(top left -1.10714872rad, blue, white, red); }
+</style>
+<div class="x a"></div>
+<div class="x e"></div>
+<div class="x g"></div>
+<div class="x i"></div>
+<div class="x k"></div>
+<div class="x m"></div>
+<div class="x o"></div>
+<div class="x q"></div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-gradients/linear-diagonal-9a.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<style>
+.x { width: 200px; height: 100px; display: inline-block; }
+.a { background: -moz-linear-gradient(to bottom, blue, white, red); }
+.e { background: -moz-linear-gradient(to bottom left, blue, white, red); }
+.g { background: -moz-linear-gradient(to left, blue, white, red); }
+.i { background: -moz-linear-gradient(to top left, blue, white, red); }
+.k { background: -moz-linear-gradient(to top, blue, white, red); }
+.m { background: -moz-linear-gradient(to top right, blue, white, red); }
+.o { background: -moz-linear-gradient(to right, blue, white, red); }
+.q { background: -moz-linear-gradient(to bottom right, blue, white, red); }
+</style>
+<div class="x a"></div>
+<div class="x e"></div>
+<div class="x g"></div>
+<div class="x i"></div>
+<div class="x k"></div>
+<div class="x m"></div>
+<div class="x o"></div>
+<div class="x q"></div>
rename from layout/reftests/css-gradients/linear-keywords-ref.html
rename to layout/reftests/css-gradients/linear-keywords-1-ref.html
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-gradients/linear-keywords-1a.html
@@ -0,0 +1,1 @@
+<div style="background: -moz-linear-gradient(to right bottom, #0000ff, #000000) no-repeat; width: 300px; height: 300px;"><br></div>
rename from layout/reftests/css-gradients/linear-keywords.html
rename to layout/reftests/css-gradients/linear-keywords-1b.html
--- a/layout/reftests/css-gradients/linear-onestopposition-1-ref.html
+++ b/layout/reftests/css-gradients/linear-onestopposition-1-ref.html
@@ -1,12 +1,12 @@
 <!DOCTYPE HTML>
 <title>Test for -moz-linear-gradient() with all stops at the same position</title>
 <style>
 
 div {
   width: 200px;
   height: 200px;
-  background-image: -moz-linear-gradient(left, blue 0%, blue 25%, orange 25%, orange 100%);
+  background-image: -moz-linear-gradient(to right, blue 0%, blue 25%, orange 25%, orange 100%);
 }
 
 </style>
 <div></div>
--- a/layout/reftests/css-gradients/linear-position-1-ref.html
+++ b/layout/reftests/css-gradients/linear-position-1-ref.html
@@ -1,2 +1,2 @@
 <body style="margin:0;">
-<div style="background: -moz-linear-gradient(left, white, black) no-repeat; position:relative; left:-200px; width: 300px; height: 300px;"><br></div>
+<div style="background: -moz-linear-gradient(to right, white, black) no-repeat; position:relative; left:-200px; width: 300px; height: 300px;"><br></div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-gradients/linear-vertical-1e.html
@@ -0,0 +1,1 @@
+<div style="background: -moz-linear-gradient(to bottom, white, black) no-repeat; width: 300px; height: 300px;"></div>
--- a/layout/reftests/css-gradients/nostops.html
+++ b/layout/reftests/css-gradients/nostops.html
@@ -1,1 +1,1 @@
-<div style="background: -moz-linear-gradient(left top) no-repeat; width: 300px; height: 300px;"><br></div>
+<div style="background: -moz-linear-gradient(to right bottom) no-repeat; width: 300px; height: 300px;"><br></div>
--- a/layout/reftests/css-gradients/onestop.html
+++ b/layout/reftests/css-gradients/onestop.html
@@ -1,1 +1,1 @@
-<div style="background: -moz-linear-gradient(left top, #0000ff 50%) no-repeat; width: 300px; height: 300px;"><br></div>
+<div style="background: -moz-linear-gradient(to right bottom, #0000ff 50%) no-repeat; width: 300px; height: 300px;"><br></div>
--- a/layout/reftests/css-gradients/reftest.list
+++ b/layout/reftests/css-gradients/reftest.list
@@ -1,24 +1,31 @@
-fails-if(Android) == linear.html linear-ref.html
-fails-if(Android) == linear-keywords.html linear-keywords-ref.html
+fails-if(Android) == linear-1a.html linear-1-ref.html
+fails-if(Android) == linear-1b.html linear-1-ref.html
+fails-if(Android) == linear-keywords-1a.html linear-keywords-1-ref.html
+fails-if(Android) == linear-keywords-1b.html linear-keywords-1-ref.html
 fails-if(Android) == linear-percent.html linear-percent-ref.html
 fails-if(Android) == linear-mix.html linear-mix-ref.html
 == linear-diagonal-1a.html linear-diagonal-1-ref.html
 == linear-diagonal-1b.html linear-diagonal-1-ref.html
+== linear-diagonal-1c.html linear-diagonal-1-ref.html
 == linear-diagonal-2a.html linear-diagonal-2-ref.html
 == linear-diagonal-2b.html linear-diagonal-2-ref.html
+== linear-diagonal-2c.html linear-diagonal-2-ref.html
 == linear-diagonal-3a.html linear-diagonal-3-ref.html
 == linear-diagonal-3b.html linear-diagonal-3-ref.html
+== linear-diagonal-3c.html linear-diagonal-3-ref.html
 == linear-diagonal-4a.html linear-diagonal-4-ref.html
 == linear-diagonal-4b.html linear-diagonal-4-ref.html
+== linear-diagonal-4c.html linear-diagonal-4-ref.html
 == linear-diagonal-5a.html linear-diagonal-5-ref.html
 == linear-diagonal-6a.html linear-diagonal-6-ref.html
 == linear-diagonal-7a.html linear-diagonal-7-ref.html
 == linear-diagonal-8a.html linear-diagonal-8-ref.html
+== linear-diagonal-9a.html linear-diagonal-9-ref.html
 == linear-position-1a.html linear-position-1-ref.html
 == linear-repeat-1a.html linear-repeat-1-ref.html
 fails-if(d2d) == linear-repeat-1b.html linear-repeat-1-ref.html # bug 582236
 == linear-repeat-1c.html linear-repeat-1-ref.html
 fails-if(d2d) == linear-repeat-1d.html linear-repeat-1-ref.html # bug 582236
 == linear-repeat-1e.html linear-repeat-1-ref.html
 fails-if(d2d) == linear-repeat-1f.html linear-repeat-1-ref.html # bug 582236
 fails-if(d2d) == linear-repeat-1g.html linear-repeat-1-ref.html # bug 582236
@@ -28,16 +35,17 @@ fails-if(d2d) == linear-repeat-1g.html l
 == linear-stops-1c.html linear-stops-1-ref.html
 == linear-stops-1d.html linear-stops-1-ref.html
 == linear-stops-1e.html linear-stops-1-ref.html
 == linear-stops-1f.html linear-stops-1-ref.html
 fails-if(Android) == linear-vertical-1a.html linear-vertical-1-ref.html
 fails-if(Android) == linear-vertical-1b.html linear-vertical-1-ref.html
 fails-if(Android) == linear-vertical-1c.html linear-vertical-1-ref.html
 fails-if(Android) == linear-vertical-1d.html linear-vertical-1-ref.html
+fails-if(Android) == linear-vertical-1e.html linear-vertical-1-ref.html
 == linear-viewport.html linear-viewport-ref.html
 == linear-zero-length-1a.html linear-zero-length-1-ref.html
 == linear-zero-length-1b.html linear-zero-length-1-ref.html
 == linear-zero-length-1c.html linear-zero-length-1-ref.html
 == nostops.html about:blank
 == onestop.html about:blank
 fails-if(Android) random-if(d2d) == radial-1a.html radial-1-ref.html
 fails-if(Android) == radial-2a.html radial-2-ref.html
@@ -60,16 +68,18 @@ fails-if(d2d) == repeating-linear-1b.htm
 == repeating-radial-1a.html repeating-radial-1-ref.html
 == repeating-radial-1b.html repeating-radial-1-ref.html
 == repeating-radial-2a.html repeating-radial-2-ref.html
 == twostops-1a.html twostops-1-ref.html
 == twostops-1b.html twostops-1-ref.html
 fails-if(cocoaWidget) == twostops-1c.html twostops-1-ref.html # bug 524173
 == twostops-1d.html twostops-1-ref.html
 == twostops-1e.html twostops-1-ref.html
+== twostops-1f.html twostops-1-ref.html
+== twostops-1g.html twostops-1-ref.html
 
 # from http://www.xanthir.com/:4bhipd by way of http://a-ja.net/newgrad.html
 fails-if(Android) == aja-linear-1a.html aja-linear-1-ref.html
 fails-if(!d2d) == aja-linear-1b.html aja-linear-1-ref.html # bug 526694
 fails-if(Android) == aja-linear-1c.html aja-linear-1-ref.html
 fails-if(Android) == aja-linear-1d.html aja-linear-1-ref.html
 fails-if(Android) == aja-linear-1e.html aja-linear-1-ref.html
 fails-if(Android) == aja-linear-1f.html aja-linear-1-ref.html
--- a/layout/reftests/css-gradients/repeating-linear-onestopposition-1.html
+++ b/layout/reftests/css-gradients/repeating-linear-onestopposition-1.html
@@ -1,12 +1,12 @@
 <!DOCTYPE HTML>
 <title>Test for -moz-repeating-linear-gradient() with all stops at the same position</title>
 <style>
 
 div {
   width: 200px;
   height: 200px;
-  background-image: -moz-repeating-linear-gradient(left, blue 25%, orange 25%);
+  background-image: -moz-repeating-linear-gradient(to right, blue 25%, orange 25%);
 }
 
 </style>
 <div></div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-gradients/twostops-1f.html
@@ -0,0 +1,1 @@
+<div style="background: -moz-linear-gradient(to bottom, #0000ff 50%, #ff0000 50%) no-repeat; width: 300px; height: 300px;"><br></div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-gradients/twostops-1g.html
@@ -0,0 +1,1 @@
+<div style="background: -moz-linear-gradient(to top, #ff0000 50%, #0000ff 50%) no-repeat; width: 300px; height: 300px;"><br></div>
--- a/layout/style/nsCSSParser.cpp
+++ b/layout/style/nsCSSParser.cpp
@@ -466,17 +466,18 @@ protected:
         mAttachment(aAttachment), mClip(aClip), mOrigin(aOrigin),
         mPosition(aPosition), mSize(aSize) {};
   };
 
   bool ParseBackgroundItem(BackgroundParseState& aState);
 
   bool ParseValueList(nsCSSProperty aPropID); // a single value prop-id
   bool ParseBackgroundPosition();
-  bool ParseBoxPositionValues(nsCSSValuePair& aOut, bool aAcceptsInherit);
+  bool ParseBoxPositionValues(nsCSSValuePair& aOut, bool aAcceptsInherit,
+                              bool aAllowExplicitCenter = true);
   bool ParseBackgroundSize();
   bool ParseBackgroundSizeValues(nsCSSValuePair& aOut);
   bool ParseBorderColor();
   bool ParseBorderColors(nsCSSProperty aProperty);
   bool ParseBorderImage();
   bool ParseBorderSpacing();
   bool ParseBorderSide(const nsCSSProperty aPropIDs[],
                          bool aSetAllSides);
@@ -4899,17 +4900,19 @@ CSSParserImpl::ParseColorStop(nsCSSValue
   return true;
 }
 
 // <gradient>
 //    : linear-gradient( <gradient-line>? <color-stops> ')'
 //    : radial-gradient( <gradient-line>? <gradient-shape-size>?
 //                       <color-stops> ')'
 //
-// <gradient-line> : [<bg-position> || <angle>] ,
+// <gradient-line> : [ to [left | right] || [top | bottom] ] ,
+//                 | <legacy-gradient-line>
+// <legacy-gradient-line> : [ <bg-position> || <angle>] ,
 //
 // <gradient-shape-size> : [<gradient-shape> || <gradient-size>] ,
 // <gradient-shape> : circle | ellipse
 // <gradient-size> : closest-side | closest-corner
 //                 | farthest-side | farthest-corner
 //                 | contain | cover
 //
 // <color-stops> : <color-stop> , <color-stop> [, <color-stop>]*
@@ -4928,18 +4931,29 @@ CSSParserImpl::ParseGradient(nsCSSValue&
   // if there is no alternative to consuming a <box-position>.
   // ParseVariant, as used here, will either succeed and consume
   // a single token, or fail and consume none, so we can be more
   // cavalier about calling it.
 
   if (!GetToken(true)) {
     return false;
   }
+
+  bool toCorner = false;
+  if (mToken.mType == eCSSToken_Ident &&
+      mToken.mIdent.LowerCaseEqualsLiteral("to")) {
+    toCorner = true;
+    if (!GetToken(true)) {
+      return false;
+    }
+  }
+
   nsCSSTokenType ty = mToken.mType;
   nsString id = mToken.mIdent;
+  cssGradient->mIsToCorner = toCorner;
   UngetToken();
 
   bool haveGradientLine = false;
   switch (ty) {
   case eCSSToken_Percentage:
   case eCSSToken_Number:
   case eCSSToken_Dimension:
     haveGradientLine = true;
@@ -4970,36 +4984,69 @@ CSSParserImpl::ParseGradient(nsCSSValue&
 
   default:
     // error
     SkipUntil(')');
     return false;
   }
 
   if (haveGradientLine) {
-    bool haveAngle =
-      ParseVariant(cssGradient->mAngle, VARIANT_ANGLE, nsnull);
-
-    // if we got an angle, we might now have a comma, ending the gradient-line
-    if (!haveAngle || !ExpectSymbol(',', true)) {
-      if (!ParseBoxPositionValues(cssGradient->mBgPos, false)) {
+    if (toCorner) {
+      // "to" syntax only allows box position keywords
+      if (ty != eCSSToken_Ident) {
+        SkipUntil(')');
+        return false;
+      }
+
+      // "to" syntax doesn't allow explicit "center"
+      if (!ParseBoxPositionValues(cssGradient->mBgPos, false, false)) {
+        SkipUntil(')');
+        return false;
+      }
+
+      const nsCSSValue& xValue = cssGradient->mBgPos.mXValue;
+      const nsCSSValue& yValue = cssGradient->mBgPos.mYValue;
+      if (xValue.GetUnit() != eCSSUnit_Enumerated ||
+          !(xValue.GetIntValue() & (NS_STYLE_BG_POSITION_LEFT |
+                                    NS_STYLE_BG_POSITION_CENTER |
+                                    NS_STYLE_BG_POSITION_RIGHT)) ||
+          yValue.GetUnit() != eCSSUnit_Enumerated ||
+          !(yValue.GetIntValue() & (NS_STYLE_BG_POSITION_TOP |
+                                    NS_STYLE_BG_POSITION_CENTER |
+                                    NS_STYLE_BG_POSITION_BOTTOM))) {
         SkipUntil(')');
         return false;
       }
 
-      if (!ExpectSymbol(',', true) &&
-          // if we didn't already get an angle, we might have one now,
-          // otherwise it's an error
-          (haveAngle ||
-           !ParseVariant(cssGradient->mAngle, VARIANT_ANGLE, nsnull) ||
-           // now we better have a comma
-           !ExpectSymbol(',', true))) {
+      if (!ExpectSymbol(',', true)) {
         SkipUntil(')');
         return false;
       }
+    } else {
+      bool haveAngle =
+        ParseVariant(cssGradient->mAngle, VARIANT_ANGLE, nsnull);
+
+      // if we got an angle, we might now have a comma, ending the gradient-line
+      if (!haveAngle || !ExpectSymbol(',', true)) {
+        if (!ParseBoxPositionValues(cssGradient->mBgPos, false)) {
+          SkipUntil(')');
+          return false;
+        }
+
+        if (!ExpectSymbol(',', true) &&
+            // if we didn't already get an angle, we might have one now,
+            // otherwise it's an error
+            (haveAngle ||
+             !ParseVariant(cssGradient->mAngle, VARIANT_ANGLE, nsnull) ||
+             // now we better have a comma
+             !ExpectSymbol(',', true))) {
+          SkipUntil(')');
+          return false;
+        }
+      }
     }
   }
 
   // radial gradients might have a <gradient-shape-size> here
   if (aIsRadial) {
     bool haveShape =
       ParseVariant(cssGradient->mRadialShape, VARIANT_KEYWORD,
                    nsCSSProps::kRadialGradientShapeKTable);
@@ -6017,20 +6064,22 @@ CSSParserImpl::ParseBackgroundPosition()
 
 /**
  * Parses two values that correspond to positions in a box.  These can be
  * values corresponding to percentages of the box, raw offsets, or keywords
  * like "top," "left center," etc.
  *
  * @param aOut The nsCSSValuePair in which to place the result.
  * @param aAcceptsInherit If true, 'inherit' and 'initial' are legal values
+ * @param aAllowExplicitCenter If true, 'center' is a legal value
  * @return Whether or not the operation succeeded.
  */
 bool CSSParserImpl::ParseBoxPositionValues(nsCSSValuePair &aOut,
-                                             bool aAcceptsInherit)
+                                           bool aAcceptsInherit,
+                                           bool aAllowExplicitCenter)
 {
   // First try a percentage or a length value
   nsCSSValue &xValue = aOut.mXValue,
              &yValue = aOut.mYValue;
   PRInt32 variantMask =
     (aAcceptsInherit ? VARIANT_INHERIT : 0) | VARIANT_LP | VARIANT_CALC;
   if (ParseVariant(xValue, variantMask, nsnull)) {
     if (eCSSUnit_Inherit == xValue.GetUnit() ||
@@ -6091,17 +6140,18 @@ bool CSSParserImpl::ParseBoxPositionValu
         return true;
       }
     }
   }
 
   // Check for bad input. Bad input consists of no matching keywords,
   // or pairs of x keywords or pairs of y keywords.
   if ((mask == 0) || (mask == (BG_TOP | BG_BOTTOM)) ||
-      (mask == (BG_LEFT | BG_RIGHT))) {
+      (mask == (BG_LEFT | BG_RIGHT)) ||
+      (!aAllowExplicitCenter && (mask & BG_CENTER))) {
     return false;
   }
 
   // Create style values
   xValue = BoxPositionMaskToCSSValue(mask, true);
   yValue = BoxPositionMaskToCSSValue(mask, false);
   return true;
 }
--- a/layout/style/nsCSSValue.cpp
+++ b/layout/style/nsCSSValue.cpp
@@ -952,17 +952,33 @@ nsCSSValue::AppendToString(nsCSSProperty
         aResult.AppendLiteral("-moz-repeating-linear-gradient(");
     } else {
       if (gradient->mIsRadial)
         aResult.AppendLiteral("-moz-radial-gradient(");
       else
         aResult.AppendLiteral("-moz-linear-gradient(");
     }
 
-    if (gradient->mBgPos.mXValue.GetUnit() != eCSSUnit_None ||
+    if (gradient->mIsToCorner) {
+      aResult.AppendLiteral("to");
+      NS_ABORT_IF_FALSE(gradient->mBgPos.mXValue.GetUnit() == eCSSUnit_Enumerated &&
+                        gradient->mBgPos.mYValue.GetUnit() == eCSSUnit_Enumerated,
+                        "unexpected unit");
+      if (!(gradient->mBgPos.mXValue.GetIntValue() & NS_STYLE_BG_POSITION_CENTER)) {
+        aResult.AppendLiteral(" ");
+        gradient->mBgPos.mXValue.AppendToString(eCSSProperty_background_position,
+                                                aResult);
+      }
+      if (!(gradient->mBgPos.mYValue.GetIntValue() & NS_STYLE_BG_POSITION_CENTER)) {
+        aResult.AppendLiteral(" ");
+        gradient->mBgPos.mYValue.AppendToString(eCSSProperty_background_position,
+                                                aResult);
+      }
+      aResult.AppendLiteral(", ");
+    } else if (gradient->mBgPos.mXValue.GetUnit() != eCSSUnit_None ||
         gradient->mBgPos.mYValue.GetUnit() != eCSSUnit_None ||
         gradient->mAngle.GetUnit() != eCSSUnit_None) {
       if (gradient->mBgPos.mXValue.GetUnit() != eCSSUnit_None) {
         gradient->mBgPos.mXValue.AppendToString(eCSSProperty_background_position,
                                                 aResult);
         aResult.AppendLiteral(" ");
       }
       if (gradient->mBgPos.mXValue.GetUnit() != eCSSUnit_None) {
@@ -1434,16 +1450,17 @@ nsCSSValueGradientStop::~nsCSSValueGradi
 {
   MOZ_COUNT_DTOR(nsCSSValueGradientStop);
 }
 
 nsCSSValueGradient::nsCSSValueGradient(bool aIsRadial,
                                        bool aIsRepeating)
   : mIsRadial(aIsRadial),
     mIsRepeating(aIsRepeating),
+    mIsToCorner(false),
     mBgPos(eCSSUnit_None),
     mAngle(eCSSUnit_None),
     mRadialShape(eCSSUnit_None),
     mRadialSize(eCSSUnit_None)
 {
 }
 
 // --- nsCSSCornerSizes -----------------
--- a/layout/style/nsCSSValue.h
+++ b/layout/style/nsCSSValue.h
@@ -1027,30 +1027,32 @@ public:
 };
 
 struct nsCSSValueGradient {
   nsCSSValueGradient(bool aIsRadial, bool aIsRepeating);
 
   // true if gradient is radial, false if it is linear
   bool mIsRadial;
   bool mIsRepeating;
+  bool mIsToCorner;
   // line position and angle
   nsCSSValuePair mBgPos;
   nsCSSValue mAngle;
 
   // Only meaningful if mIsRadial is true
   nsCSSValue mRadialShape;
   nsCSSValue mRadialSize;
 
   InfallibleTArray<nsCSSValueGradientStop> mStops;
 
   bool operator==(const nsCSSValueGradient& aOther) const
   {
     if (mIsRadial != aOther.mIsRadial ||
         mIsRepeating != aOther.mIsRepeating ||
+        mIsToCorner != aOther.mIsToCorner ||
         mBgPos != aOther.mBgPos ||
         mAngle != aOther.mAngle ||
         mRadialShape != aOther.mRadialShape ||
         mRadialSize != aOther.mRadialSize)
       return false;
 
     if (mStops.Length() != aOther.mStops.Length())
       return false;
--- a/layout/style/nsComputedDOMStyle.cpp
+++ b/layout/style/nsComputedDOMStyle.cpp
@@ -1400,16 +1400,51 @@ AppendCSSGradientLength(const nsStyleCoo
   else if (aValue.GetUnit() == eStyleUnit_Coord)
     aPrimitive->SetAppUnits(aValue.GetCoordValue());
   else
     aPrimitive->SetPercent(aValue.GetPercentValue());
   aPrimitive->GetCssText(tokenString);
   aString.Append(tokenString);
 }
 
+static void
+AppendCSSGradientToBoxPosition(const nsStyleGradient* aGradient,
+                               nsAString& aString,
+                               bool& aNeedSep)
+{
+  float xValue = aGradient->mBgPosX.GetPercentValue();
+  float yValue = aGradient->mBgPosY.GetPercentValue();
+
+  if (yValue == 1.0f && xValue == 0.5f) {
+    // omit "to bottom"
+    return;
+  }
+  NS_ASSERTION(yValue != 0.5f || xValue != 0.5f, "invalid box position");
+
+  aString.AppendLiteral("to");
+
+  if (yValue == 0.0f) {
+    aString.AppendLiteral(" top");
+  } else if (yValue == 1.0f) {
+    aString.AppendLiteral(" bottom");
+  } else if (yValue != 0.5f) { // do not write "center" keyword
+    NS_NOTREACHED("invalid box position");
+  }
+
+  if (xValue == 0.0f) {
+    aString.AppendLiteral(" left");
+  } else if (xValue == 1.0f) {
+    aString.AppendLiteral(" right");
+  } else if (xValue != 0.5f) { // do not write "center" keyword
+    NS_NOTREACHED("invalid box position");
+  }
+
+  aNeedSep = true;
+}
+
 void
 nsComputedDOMStyle::GetCSSGradientString(const nsStyleGradient* aGradient,
                                          nsAString& aString)
 {
   if (aGradient->mRepeating) {
     if (aGradient->mShape == NS_STYLE_GRADIENT_SHAPE_LINEAR)
       aString.AssignLiteral("-moz-repeating-linear-gradient(");
     else
@@ -1420,26 +1455,30 @@ nsComputedDOMStyle::GetCSSGradientString
     else
       aString.AssignLiteral("-moz-radial-gradient(");
   }
 
   bool needSep = false;
   nsAutoString tokenString;
   nsROCSSPrimitiveValue *tmpVal = GetROCSSPrimitiveValue();
 
-  if (aGradient->mBgPosX.mUnit != eStyleUnit_None) {
-    AppendCSSGradientLength(aGradient->mBgPosX, tmpVal, aString);
-    needSep = true;
-  }
-  if (aGradient->mBgPosY.mUnit != eStyleUnit_None) {
-    if (needSep) {
-      aString.AppendLiteral(" ");
+  if (aGradient->mToCorner) {
+    AppendCSSGradientToBoxPosition(aGradient, aString, needSep);
+  } else {
+    if (aGradient->mBgPosX.mUnit != eStyleUnit_None) {
+      AppendCSSGradientLength(aGradient->mBgPosX, tmpVal, aString);
+      needSep = true;
     }
-    AppendCSSGradientLength(aGradient->mBgPosY, tmpVal, aString);
-    needSep = true;
+    if (aGradient->mBgPosY.mUnit != eStyleUnit_None) {
+      if (needSep) {
+        aString.AppendLiteral(" ");
+      }
+      AppendCSSGradientLength(aGradient->mBgPosY, tmpVal, aString);
+      needSep = true;
+    }
   }
   if (aGradient->mAngle.mUnit != eStyleUnit_None) {
     if (needSep) {
       aString.AppendLiteral(" ");
     }
     tmpVal->SetNumber(aGradient->mAngle.GetAngleValue());
     tmpVal->GetCssText(tokenString);
     aString.Append(tokenString);
--- a/layout/style/nsRuleNode.cpp
+++ b/layout/style/nsRuleNode.cpp
@@ -860,16 +860,18 @@ static void SetGradient(const nsCSSValue
     }
   } else {
     NS_ASSERTION(gradient->mRadialShape.GetUnit() == eCSSUnit_None,
                  "bad unit for linear shape");
     NS_ASSERTION(gradient->mRadialSize.GetUnit() == eCSSUnit_None,
                  "bad unit for linear size");
     aResult.mShape = NS_STYLE_GRADIENT_SHAPE_LINEAR;
     aResult.mSize = NS_STYLE_GRADIENT_SIZE_FARTHEST_CORNER;
+
+    aResult.mToCorner = gradient->mIsToCorner;
   }
 
   // bg-position
   SetGradientCoord(gradient->mBgPos.mXValue, aPresContext, aContext,
                    aResult.mBgPosX, aCanStoreInRuleTree);
 
   SetGradientCoord(gradient->mBgPos.mYValue, aPresContext, aContext,
                    aResult.mBgPosY, aCanStoreInRuleTree);
--- a/layout/style/nsStyleStruct.cpp
+++ b/layout/style/nsStyleStruct.cpp
@@ -1346,16 +1346,17 @@ nsStyleGradient::operator==(const nsStyl
                     "incorrect combination of shape and size");
   NS_ABORT_IF_FALSE(aOther.mSize == NS_STYLE_GRADIENT_SIZE_FARTHEST_CORNER ||
                     aOther.mShape != NS_STYLE_GRADIENT_SHAPE_LINEAR,
                     "incorrect combination of shape and size");
 
   if (mShape != aOther.mShape ||
       mSize != aOther.mSize ||
       mRepeating != aOther.mRepeating ||
+      mToCorner != aOther.mToCorner ||
       mBgPosX != aOther.mBgPosX ||
       mBgPosY != aOther.mBgPosY ||
       mAngle != aOther.mAngle)
     return false;
 
   if (mStops.Length() != aOther.mStops.Length())
     return false;
 
@@ -1367,16 +1368,17 @@ nsStyleGradient::operator==(const nsStyl
 
   return true;
 }
 
 nsStyleGradient::nsStyleGradient(void)
   : mShape(NS_STYLE_GRADIENT_SHAPE_LINEAR)
   , mSize(NS_STYLE_GRADIENT_SIZE_FARTHEST_CORNER)
   , mRepeating(false)
+  , mToCorner(false)
 {
 }
 
 bool
 nsStyleGradient::IsOpaque()
 {
   for (PRUint32 i = 0; i < mStops.Length(); i++) {
     if (NS_GET_A(mStops[i].mColor) < 255)
--- a/layout/style/nsStyleStruct.h
+++ b/layout/style/nsStyleStruct.h
@@ -153,16 +153,17 @@ struct nsStyleGradientStop {
 
 class nsStyleGradient {
 public:
   nsStyleGradient();
   PRUint8 mShape;  // NS_STYLE_GRADIENT_SHAPE_*
   PRUint8 mSize;   // NS_STYLE_GRADIENT_SIZE_*;
                    // not used (must be FARTHEST_CORNER) for linear shape
   bool mRepeating;
+  bool mToCorner;
 
   nsStyleCoord mBgPosX; // percent, coord, calc, none
   nsStyleCoord mBgPosY; // percent, coord, calc, none
   nsStyleCoord mAngle;  // none, angle
 
   // stops are in the order specified in the stylesheet
   nsTArray<nsStyleGradientStop> mStops;
 
--- a/layout/style/test/property_database.js
+++ b/layout/style/test/property_database.js
@@ -1186,16 +1186,29 @@ var gCSSProperties = {
 		"-moz-linear-gradient(red, yellow, blue)",
 		"-moz-linear-gradient(red 1px, yellow 20%, blue 24em, green)",
 		"-moz-linear-gradient(red, yellow, green, blue 50%)",
 		"-moz-linear-gradient(red -50%, yellow -25%, green, blue)",
 		"-moz-linear-gradient(red -99px, yellow, green, blue 120%)",
 		"-moz-linear-gradient(#ffff00, #ef3, rgba(10, 20, 30, 0.4))",
 		"-moz-linear-gradient(rgba(10, 20, 30, 0.4), #ffff00, #ef3)",
 
+		"-moz-linear-gradient(to top, red, blue)",
+		"-moz-linear-gradient(to bottom, red, blue)",
+		"-moz-linear-gradient(to left, red, blue)",
+		"-moz-linear-gradient(to right, red, blue)",
+		"-moz-linear-gradient(to top left, red, blue)",
+		"-moz-linear-gradient(to top right, red, blue)",
+		"-moz-linear-gradient(to bottom left, red, blue)",
+		"-moz-linear-gradient(to bottom right, red, blue)",
+		"-moz-linear-gradient(to left top, red, blue)",
+		"-moz-linear-gradient(to left bottom, red, blue)",
+		"-moz-linear-gradient(to right top, red, blue)",
+		"-moz-linear-gradient(to right bottom, red, blue)",
+
 		"-moz-linear-gradient(top left, red, blue)",
 		"-moz-linear-gradient(0 0, red, blue)",
 		"-moz-linear-gradient(20% bottom, red, blue)",
 		"-moz-linear-gradient(center 20%, red, blue)",
 		"-moz-linear-gradient(left 35px, red, blue)",
 		"-moz-linear-gradient(10% 10em, red, blue)",
 		"-moz-linear-gradient(44px top, red, blue)",
 
@@ -1264,16 +1277,29 @@ var gCSSProperties = {
 		"-moz-repeating-linear-gradient(red, yellow, blue)",
 		"-moz-repeating-linear-gradient(red 1px, yellow 20%, blue 24em, green)",
 		"-moz-repeating-linear-gradient(red, yellow, green, blue 50%)",
 		"-moz-repeating-linear-gradient(red -50%, yellow -25%, green, blue)",
 		"-moz-repeating-linear-gradient(red -99px, yellow, green, blue 120%)",
 		"-moz-repeating-linear-gradient(#ffff00, #ef3, rgba(10, 20, 30, 0.4))",
 		"-moz-repeating-linear-gradient(rgba(10, 20, 30, 0.4), #ffff00, #ef3)",
 
+		"-moz-repeating-linear-gradient(to top, red, blue)",
+		"-moz-repeating-linear-gradient(to bottom, red, blue)",
+		"-moz-repeating-linear-gradient(to left, red, blue)",
+		"-moz-repeating-linear-gradient(to right, red, blue)",
+		"-moz-repeating-linear-gradient(to top left, red, blue)",
+		"-moz-repeating-linear-gradient(to top right, red, blue)",
+		"-moz-repeating-linear-gradient(to bottom left, red, blue)",
+		"-moz-repeating-linear-gradient(to bottom right, red, blue)",
+		"-moz-repeating-linear-gradient(to left top, red, blue)",
+		"-moz-repeating-linear-gradient(to left bottom, red, blue)",
+		"-moz-repeating-linear-gradient(to right top, red, blue)",
+		"-moz-repeating-linear-gradient(to right bottom, red, blue)",
+
 		"-moz-repeating-linear-gradient(top left, red, blue)",
 		"-moz-repeating-linear-gradient(0 0, red, blue)",
 		"-moz-repeating-linear-gradient(20% bottom, red, blue)",
 		"-moz-repeating-linear-gradient(center 20%, red, blue)",
 		"-moz-repeating-linear-gradient(left 35px, red, blue)",
 		"-moz-repeating-linear-gradient(10% 10em, red, blue)",
 		"-moz-repeating-linear-gradient(44px top, red, blue)",
 
@@ -1393,27 +1419,71 @@ var gCSSProperties = {
 			"-moz-linear-gradient(45px, center, red, blue)",
 			"-moz-linear-gradient(45px, center red, blue)",
 			"-moz-radial-gradient(contain, ellipse, red, blue)",
 			"-moz-radial-gradient(10deg contain, red, blue)",
 			"-moz-radial-gradient(10deg, contain,, red, blue)",
 			"-moz-radial-gradient(contain contain, red, blue)",
 			"-moz-radial-gradient(ellipse circle, red, blue)",
 
+			"-moz-linear-gradient(to 0 0, red, blue)",
+			"-moz-linear-gradient(to 20% bottom, red, blue)",
+			"-moz-linear-gradient(to center 20%, red, blue)",
+			"-moz-linear-gradient(to left 35px, red, blue)",
+			"-moz-linear-gradient(to 10% 10em, red, blue)",
+			"-moz-linear-gradient(to 44px top, red, blue)",
+			"-moz-linear-gradient(to top left 45deg, red, blue)",
+			"-moz-linear-gradient(to 20% bottom -300deg, red, blue)",
+			"-moz-linear-gradient(to center 20% 1.95929rad, red, blue)",
+			"-moz-linear-gradient(to left 35px 30grad, red, blue)",
+			"-moz-linear-gradient(to 10% 10em 99999deg, red, blue)",
+			"-moz-linear-gradient(to 44px top -33deg, red, blue)",
+			"-moz-linear-gradient(to -33deg, red, blue)",
+			"-moz-linear-gradient(to 30grad left 35px, red, blue)",
+			"-moz-linear-gradient(to 10deg 20px, red, blue)",
+			"-moz-linear-gradient(to .414rad bottom, red, blue)",
+
+			"-moz-linear-gradient(to top top, red, blue)",
+			"-moz-linear-gradient(to bottom bottom, red, blue)",
+			"-moz-linear-gradient(to left left, red, blue)",
+			"-moz-linear-gradient(to right right, red, blue)",
+
 			"-moz-repeating-linear-gradient(10px 10px, 20px, 30px 30px, 40px, blue 0, red 100%)",
 			"-moz-repeating-radial-gradient(20px 20px, 10px 10px, from(green), to(#ff00ff))",
 			"-moz-repeating-radial-gradient(10px 10px, 20%, 40px 40px, 10px, from(green), to(#ff00ff))",
 			"-moz-repeating-linear-gradient(10px, 20px, 30px, 40px, #00ccff 50%)",
 			"-moz-repeating-linear-gradient(40px 40px, 10px 10px, blue 0 fuchsia 10% red 100%)",
 			"-moz-repeating-linear-gradient(20px 20px 30px, 10px 10px, red 0, #ff0000 100%)",
 			"-moz-repeating-radial-gradient(left top, center, 20px 20px, 10px, from(blue), to(red))",
 			"-moz-repeating-linear-gradient(left left, top top, blue 0)",
 			"-moz-repeating-linear-gradient(inherit, 10px 10px, blue 0)",
 			"-moz-repeating-linear-gradient(left left blue red)",
-			"-moz-repeating-linear-gradient()" ]
+			"-moz-repeating-linear-gradient()",
+
+			"-moz-repeating-linear-gradient(to 0 0, red, blue)",
+			"-moz-repeating-linear-gradient(to 20% bottom, red, blue)",
+			"-moz-repeating-linear-gradient(to center 20%, red, blue)",
+			"-moz-repeating-linear-gradient(to left 35px, red, blue)",
+			"-moz-repeating-linear-gradient(to 10% 10em, red, blue)",
+			"-moz-repeating-linear-gradient(to 44px top, red, blue)",
+			"-moz-repeating-linear-gradient(to top left 45deg, red, blue)",
+			"-moz-repeating-linear-gradient(to 20% bottom -300deg, red, blue)",
+			"-moz-repeating-linear-gradient(to center 20% 1.95929rad, red, blue)",
+			"-moz-repeating-linear-gradient(to left 35px 30grad, red, blue)",
+			"-moz-repeating-linear-gradient(to 10% 10em 99999deg, red, blue)",
+			"-moz-repeating-linear-gradient(to 44px top -33deg, red, blue)",
+			"-moz-repeating-linear-gradient(to -33deg, red, blue)",
+			"-moz-repeating-linear-gradient(to 30grad left 35px, red, blue)",
+			"-moz-repeating-linear-gradient(to 10deg 20px, red, blue)",
+			"-moz-repeating-linear-gradient(to .414rad bottom, red, blue)",
+
+			"-moz-repeating-linear-gradient(to top top, red, blue)",
+			"-moz-repeating-linear-gradient(to bottom bottom, red, blue)",
+			"-moz-repeating-linear-gradient(to left left, red, blue)",
+			"-moz-repeating-linear-gradient(to right right, red, blue)" ]
 	},
 	"background-origin": {
 		domProp: "backgroundOrigin",
 		inherited: false,
 		type: CSS_TYPE_LONGHAND,
 		initial_values: [ "padding-box" ],
 		other_values: [ "border-box", "content-box", "border-box, padding-box", "padding-box, padding-box, padding-box", "border-box, border-box" ],
 		invalid_values: [ "margin-box", "padding-box padding-box" ]
--- a/layout/style/test/test_unclosed_parentheses.html
+++ b/layout/style/test/test_unclosed_parentheses.html
@@ -49,16 +49,24 @@ var declarations = [
   "color: url(http://www.foo.com",
   "color: url('http://www.foo.com'",
   "background-image: -moz-linear-gradient(",
   "background-image: -moz-linear-gradient( ",
   "background-image: -moz-linear-gradient(red, blue",
   "background-image: -moz-linear-gradient(red, yellow, blue",
   "background-image: -moz-linear-gradient(red 1px, yellow 5px, blue 10px",
   "background-image: -moz-linear-gradient(red, yellow, rgb(0, 0, 255)",
+  "background-image: -moz-linear-gradient(to",
+  "background-image: -moz-linear-gradient(to top",
+  "background-image: -moz-linear-gradient(to top left",
+  "background-image: -moz-linear-gradient(to top left,",
+  "background-image: -moz-repeating-linear-gradient(to top left, red, blue",
+  "background-image: -moz-linear-gradient(to top left, red, yellow, blue",
+  "background-image: -moz-linear-gradient(to top left, red 1px, yellow 5px, blue 10px",
+  "background-image: -moz-linear-gradient(to top left, red, yellow, rgb(0, 0, 255)",
   "background-image: -moz-repeating-linear-gradient(top left, red, blue",
   "background-image: -moz-linear-gradient(top left, red, yellow, blue",
   "background-image: -moz-linear-gradient(top left, red 1px, yellow 5px, blue 10px",
   "background-image: -moz-linear-gradient(top left, red, yellow, rgb(0, 0, 255)",
   "background-image: -moz-radial-gradient(",
   "background-image: -moz-radial-gradient( ",
   "background-image: -moz-radial-gradient(top left 45deg, red, blue",
   "background-image: -moz-radial-gradient(cover, red, blue",
--- a/security/coreconf/coreconf.dep
+++ b/security/coreconf/coreconf.dep
@@ -37,8 +37,9 @@
 
 /*
  * A dummy header file that is a dependency for all the object files.
  * Used to force a full recompilation of NSS in Mozilla's Tinderbox
  * depend builds.  See comments in rules.mk.
  */
 
 #error "Do not include this header file."
+
--- a/security/nss/TAG-INFO
+++ b/security/nss/TAG-INFO
@@ -1,1 +1,1 @@
-NSS_3_13_1_BETA1
+NSS_3_13_1_BETA2
--- a/security/nss/cmd/lib/secutil.c
+++ b/security/nss/cmd/lib/secutil.c
@@ -3758,16 +3758,18 @@ SECU_StringToSignatureAlgTag(const char 
 	if (!PL_strcmp(alg, "MD2")) {
 	    hashAlgTag = SEC_OID_MD2;
 	} else if (!PL_strcmp(alg, "MD4")) {
 	    hashAlgTag = SEC_OID_MD4;
 	} else if (!PL_strcmp(alg, "MD5")) {
 	    hashAlgTag = SEC_OID_MD5;
 	} else if (!PL_strcmp(alg, "SHA1")) {
 	    hashAlgTag = SEC_OID_SHA1;
+	} else if (!PL_strcmp(alg, "SHA224")) {
+	    hashAlgTag = SEC_OID_SHA224;
 	} else if (!PL_strcmp(alg, "SHA256")) {
 	    hashAlgTag = SEC_OID_SHA256;
 	} else if (!PL_strcmp(alg, "SHA384")) {
 	    hashAlgTag = SEC_OID_SHA384;
 	} else if (!PL_strcmp(alg, "SHA512")) {
 	    hashAlgTag = SEC_OID_SHA512;
 	}
     }
--- a/security/nss/lib/cryptohi/seckey.c
+++ b/security/nss/lib/cryptohi/seckey.c
@@ -545,16 +545,17 @@ seckey_GetKeyType (SECOidTag tag) {
 	break;
       case SEC_OID_ANSIX962_EC_PUBLIC_KEY:
 	keyType = ecKey;
 	break;
       /* accommodate applications that hand us a signature type when they 
 	* should be handing us a cipher type */
       case SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION:
       case SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION:
+      case SEC_OID_PKCS1_SHA224_WITH_RSA_ENCRYPTION:
       case SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION:
       case SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION:
       case SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION:
 	keyType = rsaKey;
 	break;
       default:
 	keyType = nullKey;
     }
--- a/security/nss/lib/cryptohi/secsign.c
+++ b/security/nss/lib/cryptohi/secsign.c
@@ -32,17 +32,17 @@
  * under the terms of either the GPL or the LGPL, and not to allow others to
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
-/* $Id: secsign.c,v 1.26 2011/07/24 13:48:12 wtc%google.com Exp $ */
+/* $Id: secsign.c,v 1.27 2011/10/22 14:35:42 wtc%google.com Exp $ */
 
 #include <stdio.h>
 #include "cryptohi.h"
 #include "sechash.h"
 #include "secder.h"
 #include "keyhi.h"
 #include "secoid.h"
 #include "secdig.h"
@@ -473,16 +473,18 @@ SEC_GetSignatureAlgorithmOidTag(KeyType 
 	switch (hashAlgTag) {
 	case SEC_OID_MD2:
 	    sigTag = SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION;	break;
 	case SEC_OID_MD5:
 	    sigTag = SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION;	break;
 	case SEC_OID_UNKNOWN:	/* default for RSA if not specified */
 	case SEC_OID_SHA1:
 	    sigTag = SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION;	break;
+	case SEC_OID_SHA224:
+	    sigTag = SEC_OID_PKCS1_SHA224_WITH_RSA_ENCRYPTION;	break;
 	case SEC_OID_SHA256:
 	    sigTag = SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION;	break;
 	case SEC_OID_SHA384:
 	    sigTag = SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION;	break;
 	case SEC_OID_SHA512:
 	    sigTag = SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION;	break;
 	default:
 	    break;
@@ -497,16 +499,18 @@ SEC_GetSignatureAlgorithmOidTag(KeyType 
 	    break;
 	}
 	break;
     case ecKey:
 	switch (hashAlgTag) {
 	case SEC_OID_UNKNOWN:	/* default for ECDSA if not specified */
 	case SEC_OID_SHA1:
             sigTag = SEC_OID_ANSIX962_ECDSA_SHA1_SIGNATURE; break;
+	case SEC_OID_SHA224:
+            sigTag = SEC_OID_ANSIX962_ECDSA_SHA224_SIGNATURE; break;
 	case SEC_OID_SHA256:
             sigTag = SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE; break;
 	case SEC_OID_SHA384:
             sigTag = SEC_OID_ANSIX962_ECDSA_SHA384_SIGNATURE; break;
 	case SEC_OID_SHA512:
             sigTag = SEC_OID_ANSIX962_ECDSA_SHA512_SIGNATURE; break;
 	default:
 	break;
--- a/security/nss/lib/cryptohi/secvfy.c
+++ b/security/nss/lib/cryptohi/secvfy.c
@@ -32,17 +32,17 @@
  * under the terms of either the GPL or the LGPL, and not to allow others to
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
-/* $Id: secvfy.c,v 1.24 2010/06/23 02:13:56 wtc%google.com Exp $ */
+/* $Id: secvfy.c,v 1.25 2011/10/22 14:35:42 wtc%google.com Exp $ */
 
 #include <stdio.h>
 #include "cryptohi.h"
 #include "sechash.h"
 #include "keyhi.h"
 #include "secasn1.h"
 #include "secoid.h"
 #include "pk11func.h"
@@ -236,16 +236,20 @@ sec_DecodeSigAlg(const SECKEYPublicKey *
       case SEC_OID_ISO_SHA1_WITH_RSA_SIGNATURE:
         *hashalg = SEC_OID_SHA1;
 	break;
       case SEC_OID_PKCS1_RSA_ENCRYPTION:
       case SEC_OID_PKCS1_RSA_PSS_SIGNATURE:
         *hashalg = SEC_OID_UNKNOWN; /* get it from the RSA signature */
 	break;
 
+      case SEC_OID_ANSIX962_ECDSA_SHA224_SIGNATURE:
+      case SEC_OID_PKCS1_SHA224_WITH_RSA_ENCRYPTION:
+	*hashalg = SEC_OID_SHA224;
+	break;
       case SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE:
       case SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION:
 	*hashalg = SEC_OID_SHA256;
 	break;
       case SEC_OID_ANSIX962_ECDSA_SHA384_SIGNATURE:
       case SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION:
 	*hashalg = SEC_OID_SHA384;
 	break;
@@ -271,19 +275,17 @@ sec_DecodeSigAlg(const SECKEYPublicKey *
 	 * hash algorithm that is not reduced by the keysize of 
 	 * the EC algorithm. Note that key strength is in bytes and
 	 * algorithms are specified in bits. Never use an algorithm
 	 * weaker than sha1. */
 	len = SECKEY_PublicKeyStrength(key);
 	if (len < 28) { /* 28 bytes == 224 bits */
 	    *hashalg = SEC_OID_SHA1;
 	} else if (len < 32) { /* 32 bytes == 256 bits */
-	    /* SHA 224 not supported in NSS */
-	    PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
-	    return SECFailure;
+	    *hashalg = SEC_OID_SHA224;
 	} else if (len < 48) { /* 48 bytes == 384 bits */
 	    *hashalg = SEC_OID_SHA256;
 	} else if (len < 64) { /* 48 bytes == 512 bits */
 	    *hashalg = SEC_OID_SHA384;
 	} else {
 	    /* use the largest in this case */
 	    *hashalg = SEC_OID_SHA512;
 	}
@@ -318,16 +320,17 @@ sec_DecodeSigAlg(const SECKEYPublicKey *
     /* get the "encryption" algorithm */ 
     switch (sigAlg) {
       case SEC_OID_PKCS1_RSA_ENCRYPTION:
       case SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION:
       case SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION:
       case SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION:
       case SEC_OID_ISO_SHA_WITH_RSA_SIGNATURE:
       case SEC_OID_ISO_SHA1_WITH_RSA_SIGNATURE:
+      case SEC_OID_PKCS1_SHA224_WITH_RSA_ENCRYPTION:
       case SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION:
       case SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION:
       case SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION:
 	*encalg = SEC_OID_PKCS1_RSA_ENCRYPTION;
 	break;
       case SEC_OID_PKCS1_RSA_PSS_SIGNATURE:
 	*encalg = SEC_OID_PKCS1_RSA_PSS_SIGNATURE;
 	break;
@@ -339,16 +342,17 @@ sec_DecodeSigAlg(const SECKEYPublicKey *
 	break;
       case SEC_OID_MISSI_DSS:
       case SEC_OID_MISSI_KEA_DSS:
       case SEC_OID_MISSI_KEA_DSS_OLD:
       case SEC_OID_MISSI_DSS_OLD:
 	*encalg = SEC_OID_MISSI_DSS;
 	break;
       case SEC_OID_ANSIX962_ECDSA_SHA1_SIGNATURE:
+      case SEC_OID_ANSIX962_ECDSA_SHA224_SIGNATURE:
       case SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE:
       case SEC_OID_ANSIX962_ECDSA_SHA384_SIGNATURE:
       case SEC_OID_ANSIX962_ECDSA_SHA512_SIGNATURE:
       case SEC_OID_ANSIX962_ECDSA_SIGNATURE_RECOMMENDED_DIGEST:
       case SEC_OID_ANSIX962_ECDSA_SIGNATURE_SPECIFIED_DIGEST:
 	*encalg = SEC_OID_ANSIX962_EC_PUBLIC_KEY;
 	break;
       /* we don't implement MD4 hashes */
--- a/security/nss/lib/pk11wrap/pk11mech.c
+++ b/security/nss/lib/pk11wrap/pk11mech.c
@@ -558,16 +558,17 @@ PK11_GetKeyGenWithSize(CK_MECHANISM_TYPE
     case CKM_CAST5_KEY_GEN:
 	return CKM_CAST5_KEY_GEN;
     case CKM_RSA_PKCS:
     case CKM_RSA_9796:
     case CKM_RSA_X_509:
     case CKM_MD2_RSA_PKCS:
     case CKM_MD5_RSA_PKCS:
     case CKM_SHA1_RSA_PKCS:
+    case CKM_SHA224_RSA_PKCS:
     case CKM_SHA256_RSA_PKCS:
     case CKM_SHA384_RSA_PKCS:
     case CKM_SHA512_RSA_PKCS:
     case CKM_KEY_WRAP_SET_OAEP:
     case CKM_RSA_PKCS_KEY_PAIR_GEN:
 	return CKM_RSA_PKCS_KEY_PAIR_GEN;
     case CKM_RSA_X9_31_KEY_PAIR_GEN:
 	return CKM_RSA_X9_31_KEY_PAIR_GEN;
@@ -591,16 +592,18 @@ PK11_GetKeyGenWithSize(CK_MECHANISM_TYPE
     case CKM_SSL3_KEY_AND_MAC_DERIVE:
     case CKM_SSL3_SHA1_MAC:
     case CKM_SSL3_MD5_MAC:
     case CKM_TLS_MASTER_KEY_DERIVE:
     case CKM_TLS_KEY_AND_MAC_DERIVE:
 	return CKM_SSL3_PRE_MASTER_KEY_GEN;
     case CKM_SHA_1_HMAC:
     case CKM_SHA_1_HMAC_GENERAL:
+    case CKM_SHA224_HMAC:
+    case CKM_SHA224_HMAC_GENERAL:
     case CKM_SHA256_HMAC:
     case CKM_SHA256_HMAC_GENERAL:
     case CKM_SHA384_HMAC:
     case CKM_SHA384_HMAC_GENERAL:
     case CKM_SHA512_HMAC:
     case CKM_SHA512_HMAC_GENERAL:
     case CKM_MD2_HMAC:
     case CKM_MD2_HMAC_GENERAL:
--- a/security/nss/lib/pk11wrap/pk11slot.c
+++ b/security/nss/lib/pk11wrap/pk11slot.c
@@ -54,30 +54,31 @@
 
 /*************************************************************
  * local static and global data
  *************************************************************/
 
 /*
  * This array helps parsing between names, mechanisms, and flags.
  * to make the config files understand more entries, add them
- * to this table. (NOTE: we need function to export this table and it's size)
+ * to this table. (NOTE: we need function to export this table and its size)
  */
 PK11DefaultArrayEntry PK11_DefaultArray[] = {
 	{ "RSA", SECMOD_RSA_FLAG, CKM_RSA_PKCS },
 	{ "DSA", SECMOD_DSA_FLAG, CKM_DSA },
 	{ "DH", SECMOD_DH_FLAG, CKM_DH_PKCS_DERIVE },
 	{ "RC2", SECMOD_RC2_FLAG, CKM_RC2_CBC },
 	{ "RC4", SECMOD_RC4_FLAG, CKM_RC4 },
 	{ "DES", SECMOD_DES_FLAG, CKM_DES_CBC },
 	{ "AES", SECMOD_AES_FLAG, CKM_AES_CBC },
 	{ "Camellia", SECMOD_CAMELLIA_FLAG, CKM_CAMELLIA_CBC },
 	{ "SEED", SECMOD_SEED_FLAG, CKM_SEED_CBC },
 	{ "RC5", SECMOD_RC5_FLAG, CKM_RC5_CBC },
 	{ "SHA-1", SECMOD_SHA1_FLAG, CKM_SHA_1 },
+/*	{ "SHA224", SECMOD_SHA256_FLAG, CKM_SHA224 }, */
 	{ "SHA256", SECMOD_SHA256_FLAG, CKM_SHA256 },
 /*	{ "SHA384", SECMOD_SHA512_FLAG, CKM_SHA384 }, */
 	{ "SHA512", SECMOD_SHA512_FLAG, CKM_SHA512 },
 	{ "MD5", SECMOD_MD5_FLAG, CKM_MD5 },
 	{ "MD2", SECMOD_MD2_FLAG, CKM_MD2 },
 	{ "SSL", SECMOD_SSL_FLAG, CKM_SSL3_PRE_MASTER_KEY_GEN },
 	{ "TLS", SECMOD_TLS_FLAG, CKM_TLS_MASTER_KEY_DERIVE },
 	{ "SKIPJACK", SECMOD_FORTEZZA_FLAG, CKM_SKIPJACK_CBC64 },
@@ -852,16 +853,17 @@ PK11_GetSlotList(CK_MECHANISM_TYPE type)
     case CKM_DES3_CBC:
 	return &pk11_desSlotList;
     case CKM_RC4:
 	return &pk11_rc4SlotList;
     case CKM_RC5_CBC:
 	return &pk11_rc5SlotList;
     case CKM_SHA_1:
 	return &pk11_sha1SlotList;
+    case CKM_SHA224:
     case CKM_SHA256:
 	return &pk11_sha256SlotList;
     case CKM_SHA384:
     case CKM_SHA512:
 	return &pk11_sha512SlotList;
     case CKM_MD5:
 	return &pk11_md5SlotList;
     case CKM_MD2:
@@ -2019,16 +2021,17 @@ PK11_GetBestSlotMultiple(CK_MECHANISM_TY
 
     PORT_SetError(0);
 
 
     listNeedLogin = PR_FALSE;
     for (i=0; i < mech_count; i++) {
 	if ((type[i] != CKM_FAKE_RANDOM) && 
 	    (type[i] != CKM_SHA_1) &&
+	    (type[i] != CKM_SHA224) &&
 	    (type[i] != CKM_SHA256) &&
 	    (type[i] != CKM_SHA384) &&
 	    (type[i] != CKM_SHA512) &&
 	    (type[i] != CKM_MD5) && 
 	    (type[i] != CKM_MD2)) {
 	    listNeedLogin = PR_TRUE;
 	    break;
 	}
--- a/security/nss/lib/pkcs12/p12local.c
+++ b/security/nss/lib/pkcs12/p12local.c
@@ -57,16 +57,18 @@ sec_pkcs12_algtag_to_mech(SECOidTag algt
 {
     switch (algtag) {
     case SEC_OID_MD2:
 	return CKM_MD2_HMAC;
     case SEC_OID_MD5:
 	return CKM_MD5_HMAC;
     case SEC_OID_SHA1:
 	return CKM_SHA_1_HMAC;
+    case SEC_OID_SHA224:
+	return CKM_SHA224_HMAC;
     case SEC_OID_SHA256:
 	return CKM_SHA256_HMAC;
     case SEC_OID_SHA384:
 	return CKM_SHA384_HMAC;
     case SEC_OID_SHA512:
 	return CKM_SHA512_HMAC;
     default:
 	break;
--- a/security/nss/lib/softoken/rsawrapr.c
+++ b/security/nss/lib/softoken/rsawrapr.c
@@ -33,17 +33,17 @@
  * under the terms of either the GPL or the LGPL, and not to allow others to
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
-/* $Id: rsawrapr.c,v 1.18 2011/10/04 22:05:53 wtc%google.com Exp $ */
+/* $Id: rsawrapr.c,v 1.19 2011/10/22 14:35:43 wtc%google.com Exp $ */
 
 #include "blapi.h"
 #include "softoken.h"
 #include "sechash.h"
 
 #include "lowkeyi.h"
 #include "secerr.h"
 
@@ -1164,21 +1164,23 @@ emsa_pss_verify(const unsigned char *mHa
 
     PORT_Free(H_);
     return rv;
 }
 
 static HASH_HashType
 GetHashTypeFromMechanism(CK_MECHANISM_TYPE mech)
 {
-    /* TODO(wtc): add SHA-224. */
     switch (mech) {
         case CKM_SHA_1:
         case CKG_MGF1_SHA1:
 	    return HASH_AlgSHA1;
+        case CKM_SHA224:
+        case CKG_MGF1_SHA224:
+	    return HASH_AlgSHA224;
         case CKM_SHA256:
         case CKG_MGF1_SHA256:
 	    return HASH_AlgSHA256;
         case CKM_SHA384:
         case CKG_MGF1_SHA384:
 	    return HASH_AlgSHA384;
         case CKM_SHA512:
         case CKG_MGF1_SHA512:
--- a/security/nss/lib/ssl/ssl3ecc.c
+++ b/security/nss/lib/ssl/ssl3ecc.c
@@ -35,17 +35,17 @@
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 /* ECC code moved here from ssl3con.c */
-/* $Id: ssl3ecc.c,v 1.24 2010/03/15 08:03:14 nelson%bolyard.com Exp $ */
+/* $Id: ssl3ecc.c,v 1.25 2011/10/22 14:35:44 wtc%google.com Exp $ */
 
 #include "nss.h"
 #include "cert.h"
 #include "ssl.h"
 #include "cryptohi.h"	/* for DSAU_ stuff */
 #include "keyhi.h"
 #include "secder.h"
 #include "secitem.h"
@@ -963,16 +963,17 @@ ssl3_FilterECCipherSuitesByServerCerts(s
 	SECOidTag sigTag = SECOID_GetAlgorithmTag(&svrCert->signature);
 
 	switch (sigTag) {
 	case SEC_OID_PKCS1_RSA_ENCRYPTION:
 	case SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION:
 	case SEC_OID_PKCS1_MD4_WITH_RSA_ENCRYPTION:
 	case SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION:
 	case SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION:
+	case SEC_OID_PKCS1_SHA224_WITH_RSA_ENCRYPTION:
 	case SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION:
 	case SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION:
 	case SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION:
 	    ssl3_DisableECCSuites(ss, ecdh_ecdsa_suites);
 	    break;
 	case SEC_OID_ANSIX962_ECDSA_SHA1_SIGNATURE:
 	case SEC_OID_ANSIX962_ECDSA_SHA224_SIGNATURE:
 	case SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE:
--- a/security/nss/lib/ssl/sslerrstrs.c
+++ b/security/nss/lib/ssl/sslerrstrs.c
@@ -33,17 +33,16 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 #include "prerror.h"
 #include "sslerr.h"
 #include "prinit.h"
 #include "nssutil.h"
 #include "ssl.h"
-#include "sslerrstrs.h"
 
 #define ER3(name, value, str) {#name, str},
 
 static const struct PRErrorMessage ssltext[] = {
 #include "SSLerrs.h"
     {0,0}
 };
 
@@ -54,13 +53,14 @@ static const struct PRErrorTable ssl_et 
 
 static PRStatus
 ssl_InitializePRErrorTableOnce(void) {
     return PR_ErrorInstallTable(&ssl_et);
 }
 
 static PRCallOnceType once;
 
-PRStatus
+SECStatus
 ssl_InitializePRErrorTable(void)
 {
-    return PR_CallOnce(&once, ssl_InitializePRErrorTableOnce);
+    return (PR_SUCCESS == PR_CallOnce(&once, ssl_InitializePRErrorTableOnce))
+		? SECSuccess : SECFailure;
 }
deleted file mode 100644
--- a/security/nss/lib/ssl/sslerrstrs.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * This file contains prototypes for the public SSL functions.
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is the Netscape security libraries.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1994-2000
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-/* $Id: sslerrstrs.h,v 1.1 2011/08/17 14:41:02 emaldona%redhat.com Exp $ */
-
-#ifndef __sslerrstrs_h_
-#define __sslerrstrs_h_
-
-#include "prtypes.h"
-
-SEC_BEGIN_PROTOS
-
-extern PRStatus 
-ssl_InitializePRErrorTable(void);
-
-SEC_END_PROTOS
-
-#endif /* __sslerrstrs_h_ */
--- a/security/nss/lib/ssl/sslimpl.h
+++ b/security/nss/lib/ssl/sslimpl.h
@@ -34,17 +34,17 @@
  * under the terms of either the GPL or the LGPL, and not to allow others to
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
-/* $Id: sslimpl.h,v 1.83 2011/10/01 03:59:54 bsmith%mozilla.com Exp $ */
+/* $Id: sslimpl.h,v 1.84 2011/10/22 16:45:40 emaldona%redhat.com Exp $ */
 
 #ifndef __sslimpl_h_
 #define __sslimpl_h_
 
 #ifdef DEBUG
 #undef NDEBUG
 #else
 #undef NDEBUG
@@ -1146,16 +1146,20 @@ extern const char * const      ssl3_ciph
 extern sslSessionIDLookupFunc  ssl_sid_lookup;
 extern sslSessionIDCacheFunc   ssl_sid_cache;
 extern sslSessionIDUncacheFunc ssl_sid_uncache;
 
 /************************************************************************/
 
 SEC_BEGIN_PROTOS
 
+/* Internal initialization and installation of the SSL error tables */
+extern SECStatus ssl_Init(void);
+extern SECStatus ssl_InitializePRErrorTable(void);
+
 /* Implementation of ops for default (non socks, non secure) case */
 extern int ssl_DefConnect(sslSocket *ss, const PRNetAddr *addr);
 extern PRFileDesc *ssl_DefAccept(sslSocket *ss, PRNetAddr *addr);
 extern int ssl_DefBind(sslSocket *ss, const PRNetAddr *addr);
 extern int ssl_DefListen(sslSocket *ss, int backlog);
 extern int ssl_DefShutdown(sslSocket *ss, int how);
 extern int ssl_DefClose(sslSocket *ss);
 extern int ssl_DefRecv(sslSocket *ss, unsigned char *buf, int len, int flags);
--- a/security/nss/lib/ssl/sslinit.c
+++ b/security/nss/lib/ssl/sslinit.c
@@ -31,30 +31,31 @@
  * under the terms of either the GPL or the LGPL, and not to allow others to
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
-/* $Id: sslinit.c,v 1.1 2011/08/17 14:41:05 emaldona%redhat.com Exp $ */
+/* $Id: sslinit.c,v 1.2 2011/10/22 16:45:40 emaldona%redhat.com Exp $ */
 
 #include "prtypes.h"
 #include "prinit.h"
 #include "seccomon.h"
 #include "secerr.h"
 #include "ssl.h"
-#include "sslerrstrs.h"
+#include "sslimpl.h"
 
 static int ssl_inited = 0;
 
 SECStatus
 ssl_Init(void)
 {
     if (!ssl_inited) {
-	if (ssl_InitializePRErrorTable() == PR_FAILURE) {
-	   return (SEC_ERROR_NO_MEMORY);
+	if (ssl_InitializePRErrorTable() != SECSuccess) {
+	    PORT_SetError(SEC_ERROR_NO_MEMORY);
+	    return (SECFailure);
 	}
 	ssl_inited = 1;
     }
     return SECSuccess;
 }
--- a/security/nss/lib/ssl/sslsnce.c
+++ b/security/nss/lib/ssl/sslsnce.c
@@ -31,17 +31,17 @@
  * under the terms of either the GPL or the LGPL, and not to allow others to
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
-/* $Id: sslsnce.c,v 1.58 2011/10/01 00:11:02 wtc%google.com Exp $ */
+/* $Id: sslsnce.c,v 1.59 2011/10/22 16:45:40 emaldona%redhat.com Exp $ */
 
 /* Note: ssl_FreeSID() in sslnonce.c gets used for both client and server 
  * cache sids!
  *
  * About record locking among different server processes:
  *
  * All processes that are part of the same conceptual server (serving on 
  * the same address and port) MUST share a common SSL session cache. 
@@ -78,17 +78,16 @@
 #include "seccomon.h"
 
 #if defined(XP_UNIX) || defined(XP_WIN32) || defined (XP_OS2) || defined(XP_BEOS)
 
 #include "cert.h"
 #include "ssl.h"
 #include "sslimpl.h"
 #include "sslproto.h"
-#include "sslutil.h"
 #include "pk11func.h"
 #include "base64.h"
 #include "keyhi.h"
 #include "blapi.h"
 
 #include <stdio.h>
 
 #if defined(XP_UNIX) || defined(XP_BEOS)
--- a/security/nss/lib/ssl/sslsock.c
+++ b/security/nss/lib/ssl/sslsock.c
@@ -35,24 +35,23 @@
  * under the terms of either the GPL or the LGPL, and not to allow others to
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
-/* $Id: sslsock.c,v 1.74 2011/10/06 22:42:34 wtc%google.com Exp $ */
+/* $Id: sslsock.c,v 1.75 2011/10/22 16:45:40 emaldona%redhat.com Exp $ */
 #include "seccomon.h"
 #include "cert.h"
 #include "keyhi.h"
 #include "ssl.h"
 #include "sslimpl.h"
 #include "sslproto.h"
-#include "sslutil.h"
 #include "nspr.h"
 #include "private/pprio.h"
 #include "blapi.h"
 #include "nss.h"
 
 #define SET_ERROR_CODE   /* reminder */
 
 struct cipherPolicyStr {
deleted file mode 100644
--- a/security/nss/lib/ssl/sslutil.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * This file contains prototypes for the public SSL functions.
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is the Netscape security libraries.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1994-2000
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-/* $Id: sslutil.h,v 1.1 2011/08/17 14:41:20 emaldona%redhat.com Exp $ */
-
-#ifndef __sslutil_h_
-#define __sslutil_h_
-
-#include "prtypes.h"
-
-SEC_BEGIN_PROTOS
-
-extern PRStatus SSL_InitializePRErrorTable(void);
-extern SECStatus ssl_Init(void);
-
-SEC_END_PROTOS
-
-#endif /* __sslutil_h_ */
--- a/security/nss/lib/util/secalgid.c
+++ b/security/nss/lib/util/secalgid.c
@@ -65,24 +65,26 @@ SECOID_SetAlgorithmID(PRArenaPool *arena
     if (SECITEM_CopyItem(arena, &id->algorithm, &oiddata->oid))
 	return SECFailure;
 
     switch (which) {
       case SEC_OID_MD2:
       case SEC_OID_MD4:
       case SEC_OID_MD5:
       case SEC_OID_SHA1:
+      case SEC_OID_SHA224:
       case SEC_OID_SHA256:
       case SEC_OID_SHA384:
       case SEC_OID_SHA512:
       case SEC_OID_PKCS1_RSA_ENCRYPTION:
       case SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION:
       case SEC_OID_PKCS1_MD4_WITH_RSA_ENCRYPTION:
       case SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION:
       case SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION:
+      case SEC_OID_PKCS1_SHA224_WITH_RSA_ENCRYPTION:
       case SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION:
       case SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION:
       case SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION:
 	add_null_param = PR_TRUE;
 	break;
       default:
 	add_null_param = PR_FALSE;
 	break;
--- a/testing/mochitest/runtests.py
+++ b/testing/mochitest/runtests.py
@@ -810,17 +810,17 @@ overlay chrome://navigator/content/navig
   def installChromeJar(self, jarDirName, chrome, options):
     """
       copy mochijar directory to profile as an extension so we have chrome://mochikit for all harness code
     """
     self.automation.installExtension(os.path.join(self.SCRIPT_DIRECTORY, jarDirName), \
                                      options.profilePath, "mochikit@mozilla.org")
 
     # Write chrome.manifest.
-    with open(os.path.join(options.profilePath, "extensions", "mochikit@mozilla.org", "chrome.manifest"), "a") as mfile:
+    with open(os.path.join(options.profilePath, "extensions", "staged", "mochikit@mozilla.org", "chrome.manifest"), "a") as mfile:
       mfile.write(chrome)
 
   def copyTestsJarToProfile(self, options):
     """ copy tests.jar to the profile directory so we can auto register it in the .xul harness """
     testsJarFile = os.path.join(self.SCRIPT_DIRECTORY, "tests.jar")
     if not os.path.isfile(testsJarFile):
       return False
 
--- a/toolkit/components/telemetry/TelemetryHistograms.h
+++ b/toolkit/components/telemetry/TelemetryHistograms.h
@@ -230,8 +230,10 @@ HISTOGRAM(PLACES_AUTOCOMPLETE_1ST_RESULT
  */
 #ifdef MOZ_THUNDERBIRD
 HISTOGRAM(THUNDERBIRD_GLODA_SIZE_MB, 1, 1000, 40, LINEAR, "Gloda: size of global-messages-db.sqlite (MB)")
 HISTOGRAM(THUNDERBIRD_CONVERSATIONS_TIME_TO_2ND_GLODA_QUERY_MS, 1, 10000, 30, EXPONENTIAL, "Conversations: time between the moment we click and the second gloda query returns (ms)")
 HISTOGRAM(THUNDERBIRD_INDEXING_RATE_MSG_PER_S, 1, 100, 20, LINEAR, "Gloda: indexing rate (message/s)")
 #endif
 
 HISTOGRAM(INNERWINDOWS_WITH_MUTATION_LISTENERS, 0, 1, 2, BOOLEAN, "Deleted or to-be-reused innerwindow which has had mutation event listeners.")
+HISTOGRAM(XUL_REFLOW_MS, 1, 3000, 10, EXPONENTIAL, "xul reflows")
+HISTOGRAM(XUL_INITIAL_FRAME_CONSTRUCTION, 1, 3000, 10, EXPONENTIAL, "initial xul frame construction")
--- a/toolkit/mozapps/extensions/AddonRepository.jsm
+++ b/toolkit/mozapps/extensions/AddonRepository.jsm
@@ -55,16 +55,25 @@ const PREF_GETADDONS_CACHE_TYPES        
 const PREF_GETADDONS_CACHE_ID_ENABLED    = "extensions.%ID%.getAddons.cache.enabled"
 const PREF_GETADDONS_BROWSEADDONS        = "extensions.getAddons.browseAddons";
 const PREF_GETADDONS_BYIDS               = "extensions.getAddons.get.url";
 const PREF_GETADDONS_BROWSERECOMMENDED   = "extensions.getAddons.recommended.browseURL";
 const PREF_GETADDONS_GETRECOMMENDED      = "extensions.getAddons.recommended.url";
 const PREF_GETADDONS_BROWSESEARCHRESULTS = "extensions.getAddons.search.browseURL";
 const PREF_GETADDONS_GETSEARCHRESULTS    = "extensions.getAddons.search.url";
 
+const PREF_CHECK_COMPATIBILITY_BASE = "extensions.checkCompatibility";
+#ifdef MOZ_COMPATIBILITY_NIGHTLY
+const PREF_CHECK_COMPATIBILITY = PREF_CHECK_COMPATIBILITY_BASE +
+                                 ".nightly";
+#else
+const PREF_CHECK_COMPATIBILITY = PREF_CHECK_COMPATIBILITY_BASE + "." +
+                                 Services.appinfo.version.replace(BRANCH_REGEXP, "$1");
+#endif
+
 const XMLURI_PARSE_ERROR  = "http://www.mozilla.org/newlayout/xml/parsererror.xml";
 
 const API_VERSION = "1.5";
 const DEFAULT_CACHE_TYPES = "extension,theme,locale,dictionary";
 
 const KEY_PROFILEDIR = "ProfD";
 const FILE_DATABASE  = "addons.sqlite";
 const DB_SCHEMA      = 2;
@@ -805,23 +814,33 @@ var AddonRepository = {
    * @param  aSearchTerms
    *         The terms to search for
    * @param  aMaxResults
    *         The maximum number of results to return
    * @param  aCallback
    *         The callback to pass results to
    */
   searchAddons: function(aSearchTerms, aMaxResults, aCallback) {
-    let url = this._formatURLPref(PREF_GETADDONS_GETSEARCHRESULTS, {
+    let substitutions = {
       API_VERSION : API_VERSION,
       TERMS : encodeURIComponent(aSearchTerms),
 
       // Get twice as many results to account for potential filtering
       MAX_RESULTS : 2 * aMaxResults
-    });
+    };
+
+    let checkCompatibility = true;
+    try {
+      checkCompatibility = Services.prefs.getBoolPref(PREF_CHECK_COMPATIBILITY);
+    } catch(e) { }
+
+    if (!checkCompatibility)
+      substitutions.VERSION = "";
+
+    let url = this._formatURLPref(PREF_GETADDONS_GETSEARCHRESULTS, substitutions);
 
     let self = this;
     function handleResults(aElements, aTotalResults) {
       self._getLocalAddonIds(function(aLocalAddonIds) {
         self._parseAddons(aElements, aTotalResults, aLocalAddonIds);
       });
     }
 
@@ -1074,42 +1093,57 @@ var AddonRepository = {
     }
 
     return result;
   },
 
   _parseAddons: function(aElements, aTotalResults, aSkip) {
     let self = this;
     let results = [];
+
+    let checkCompatibility = true;
+    try {
+      checkCompatibility = Services.prefs.getBoolPref(PREF_CHECK_COMPATIBILITY);
+    } catch(e) { }
+
+    function isSameApplication(aAppNode) {
+      return self._getTextContent(aAppNode) == Services.appinfo.ID;
+    }
+
     for (let i = 0; i < aElements.length && results.length < this._maxResults; i++) {
       let element = aElements[i];
 
-      // Ignore add-ons not compatible with this Application
       let tags = this._getUniqueDescendant(element, "compatible_applications");
       if (tags == null)
         continue;
 
       let applications = tags.getElementsByTagName("appID");
       let compatible = Array.some(applications, function(aAppNode) {
-        if (self._getTextContent(aAppNode) != Services.appinfo.ID)
+        if (!isSameApplication(aAppNode))
           return false;
 
         let parent = aAppNode.parentNode;
         let minVersion = self._getDescendantTextContent(parent, "min_version");
         let maxVersion = self._getDescendantTextContent(parent, "max_version");
         if (minVersion == null || maxVersion == null)
           return false;
 
         let currentVersion = Services.appinfo.version;
         return (Services.vc.compare(minVersion, currentVersion) <= 0 &&
                 Services.vc.compare(currentVersion, maxVersion) <= 0);
       });
 
-      if (!compatible)
-        continue;
+      // Ignore add-ons not compatible with this Application
+      if (!compatible) {
+        if (checkCompatibility)
+          continue;
+
+        if (!Array.some(applications, isSameApplication))
+          continue;
+      }
 
       // Add-on meets all requirements, so parse out data
       let result = this._parseAddon(element, aSkip);
       if (result == null)
         continue;
 
       // Ignore add-on missing a required attribute
       let requiredAttributes = ["id", "name", "version", "type", "creator"];
@@ -1120,16 +1154,18 @@ var AddonRepository = {
       if (!result.addon.isPlatformCompatible)
         continue;
 
       // Add only if there was an xpi compatible with this OS or there was a
       // way to purchase the add-on
       if (!result.xpiURL && !result.addon.purchaseURL)
         continue;
 
+      result.addon.isCompatible = compatible;
+
       results.push(result);
       // Ignore this add-on from now on by adding it to the skip array
       aSkip.ids.push(result.addon.id);
     }
 
     // Immediately report success if no AddonInstall instances to create
     let pendingResults = results.length;
     if (pendingResults == 0) {
--- a/toolkit/mozapps/extensions/LightweightThemeManager.jsm
+++ b/toolkit/mozapps/extensions/LightweightThemeManager.jsm
@@ -551,16 +551,20 @@ AddonWrapper.prototype = {
   get isPlatformCompatible() {
     return true;
   },
 
   get scope() {
     return AddonManager.SCOPE_PROFILE;
   },
 
+  get foreignInstall() {
+    return false;
+  },
+
   // Lightweight themes are always compatible
   isCompatibleWith: function(appVersion, platformVersion) {
     return true;
   },
 
   // Lightweight themes are always securely updated
   get providesUpdatesSecurely() {
     return true;
--- a/toolkit/mozapps/extensions/PluginProvider.jsm
+++ b/toolkit/mozapps/extensions/PluginProvider.jsm
@@ -334,16 +334,20 @@ PluginWrapper.prototype = {
   get isPlatformCompatible() {
     return true;
   },
 
   get providesUpdatesSecurely() {
     return true;
   },
 
+  get foreignInstall() {
+    return true;
+  },
+
   isCompatibleWith: function(aAppVerison, aPlatformVersion) {
     return true;
   },
 
   findUpdates: function(aListener, aReason, aAppVersion, aPlatformVersion) {
     if ("onNoCompatibilityUpdateAvailable" in aListener)
       aListener.onNoCompatibilityUpdateAvailable(this);
     if ("onNoUpdateAvailable" in aListener)
--- a/toolkit/mozapps/extensions/XPIProvider.jsm
+++ b/toolkit/mozapps/extensions/XPIProvider.jsm
@@ -117,17 +117,17 @@ const PREFIX_ITEM_URI                 = 
 const RDFURI_ITEM_ROOT                = "urn:mozilla:item:root"
 const RDFURI_INSTALL_MANIFEST_ROOT    = "urn:mozilla:install-manifest";
 const PREFIX_NS_EM                    = "http://www.mozilla.org/2004/em-rdf#";
 
 const TOOLKIT_ID                      = "toolkit@mozilla.org";
 
 const BRANCH_REGEXP                   = /^([^\.]+\.[0-9]+[a-z]*).*/gi;
 
-const DB_SCHEMA                       = 5;
+const DB_SCHEMA                       = 6;
 const REQ_VERSION                     = 2;
 
 #ifdef MOZ_COMPATIBILITY_NIGHTLY
 const PREF_EM_CHECK_COMPATIBILITY = PREF_EM_CHECK_COMPATIBILITY_BASE +
                                     ".nightly";
 #else
 const PREF_EM_CHECK_COMPATIBILITY = PREF_EM_CHECK_COMPATIBILITY_BASE + "." +
                                     Services.appinfo.version.replace(BRANCH_REGEXP, "$1");
@@ -141,17 +141,17 @@ const PROP_LOCALE_SINGLE = ["name", "des
 const PROP_LOCALE_MULTI  = ["developers", "translators", "contributors"];
 const PROP_TARGETAPP     = ["id", "minVersion", "maxVersion"];
 
 // Properties that only exist in the database
 const DB_METADATA        = ["installDate", "updateDate", "size", "sourceURI",
                             "releaseNotesURI", "applyBackgroundUpdates"];
 const DB_BOOL_METADATA   = ["visible", "active", "userDisabled", "appDisabled",
                             "pendingUninstall", "bootstrap", "skinnable",
-                            "softDisabled"];
+                            "softDisabled", "foreignInstall"];
 
 const BOOTSTRAP_REASONS = {
   APP_STARTUP     : 1,
   APP_SHUTDOWN    : 2,
   ADDON_ENABLE    : 3,
   ADDON_DISABLE   : 4,
   ADDON_INSTALL   : 5,
   ADDON_UNINSTALL : 6,
@@ -2551,20 +2551,26 @@ var XPIProvider = {
 
       let newAddon = null;
       // Check the updated manifests lists for the install location, If there
       // is no manifest for the add-on ID then newAddon will be undefined
       if (aInstallLocation.name in aManifests)
         newAddon = aManifests[aInstallLocation.name][aId];
 
       try {
-        // Otherwise load the manifest from the add-on
+        // Otherwise the add-on has appeared in the install location.
         if (!newAddon) {
+          // Load the manifest from the add-on.
           let file = aInstallLocation.getLocationForID(aId);
           newAddon = loadManifestFromFile(file);
+
+          // The default theme is never a foreign install
+          if (newAddon.type != "theme" || newAddon.internalName != XPIProvider.defaultSkin)
+            newAddon.foreignInstall = true;
+
         }
         // The add-on in the manifest should match the add-on ID.
         if (newAddon.id != aId)
           throw new Error("Incorrect id in install manifest");
       }
       catch (e) {
         WARN("Add-on is invalid", e);
 
@@ -2578,19 +2584,20 @@ var XPIProvider = {
       }
 
       // Update the AddonInternal properties.
       newAddon._installLocation = aInstallLocation;
       newAddon.visible = !(newAddon.id in visibleAddons);
       newAddon.installDate = aAddonState.mtime;
       newAddon.updateDate = aAddonState.mtime;
 
-      // Check if the add-on is in a scope where add-ons should install disabled
+      // Check if the add-on is a foreign install and is in a scope where
+      // add-ons that were dropped in should default to disabled.
       let disablingScopes = Prefs.getIntPref(PREF_EM_AUTO_DISABLED_SCOPES, 0);
-      if (aInstallLocation.scope & disablingScopes)
+      if (newAddon.foreignInstall && aInstallLocation.scope & disablingScopes)
         newAddon.userDisabled = true;
 
       // If there is migration data then apply it.
       if (aMigrateData) {
         LOG("Migrating data from old database");
         // A theme's disabled state is determined by the selected theme
         // preference which is read in loadManifestFromRDF
         if (newAddon.type != "theme")
@@ -2600,16 +2607,18 @@ var XPIProvider = {
         if ("softDisabled" in aMigrateData)
           newAddon.softDisabled = aMigrateData.softDisabled;
         if ("applyBackgroundUpdates" in aMigrateData)
           newAddon.applyBackgroundUpdates = aMigrateData.applyBackgroundUpdates;
         if ("sourceURI" in aMigrateData)
           newAddon.sourceURI = aMigrateData.sourceURI;
         if ("releaseNotesURI" in aMigrateData)
           newAddon.releaseNotesURI = aMigrateData.releaseNotesURI;
+        if ("foreignInstall" in aMigrateData)
+          newAddon.foreignInstall = aMigrateData.foreignInstall;
 
         // Some properties should only be migrated if the add-on hasn't changed.
         // The version property isn't a perfect check for this but covers the
         // vast majority of cases.
         if (aMigrateData.version == newAddon.version &&
             "targetApplications" in aMigrateData) {
           LOG("Migrating compatibility info");
           newAddon.applyCompatibilityUpdate(aMigrateData, true);
@@ -3855,17 +3864,18 @@ var XPIProvider = {
   }
 };
 
 const FIELDS_ADDON = "internal_id, id, location, version, type, internalName, " +
                      "updateURL, updateKey, optionsURL, optionsType, aboutURL, " +
                      "iconURL, icon64URL, defaultLocale, visible, active, " +
                      "userDisabled, appDisabled, pendingUninstall, descriptor, " +
                      "installDate, updateDate, applyBackgroundUpdates, bootstrap, " +
-                     "skinnable, size, sourceURI, releaseNotesURI, softDisabled";
+                     "skinnable, size, sourceURI, releaseNotesURI, softDisabled, " +
+                     "foreignInstall";
 
 /**
  * A helper function to log an SQL error.
  *
  * @param  aError
  *         The storage error code associated with the error
  * @param  aErrorString
  *         An error message
@@ -4000,17 +4010,18 @@ var XPIDatabase = {
 
     addAddonMetadata_addon: "INSERT INTO addon VALUES (NULL, :id, :location, " +
                             ":version, :type, :internalName, :updateURL, " +
                             ":updateKey, :optionsURL, :optionsType, :aboutURL, " +
                             ":iconURL, :icon64URL, :locale, :visible, :active, " +
                             ":userDisabled, :appDisabled, :pendingUninstall, " +
                             ":descriptor, :installDate, :updateDate, " +
                             ":applyBackgroundUpdates, :bootstrap, :skinnable, " +
-                            ":size, :sourceURI, :releaseNotesURI, :softDisabled)",
+                            ":size, :sourceURI, :releaseNotesURI, :softDisabled, " +
+                            ":foreignInstall)",
     addAddonMetadata_addon_locale: "INSERT INTO addon_locale VALUES " +
                                    "(:internal_id, :name, :locale)",
     addAddonMetadata_locale: "INSERT INTO locale (name, description, creator, " +
                              "homepageURL) VALUES (:name, :description, " +
                              ":creator, :homepageURL)",
     addAddonMetadata_strings: "INSERT INTO locale_strings VALUES (:locale, " +
                               ":type, :value)",
     addAddonMetadata_targetApplication: "INSERT INTO targetApplication VALUES " +
@@ -4368,16 +4379,19 @@ var XPIDatabase = {
     // Attempt to migrate data from a different (even future!) version of the
     // database
     try {
       // Build a list of sql statements that might recover useful data from this
       // and future versions of the schema
       var sql = [];
       sql.push("SELECT internal_id, id, location, userDisabled, " +
                "softDisabled, installDate, version, applyBackgroundUpdates, " +
+               "sourceURI, releaseNotesURI, foreignInstall FROM addon");
+      sql.push("SELECT internal_id, id, location, userDisabled, " +
+               "softDisabled, installDate, version, applyBackgroundUpdates, " +
                "sourceURI, releaseNotesURI FROM addon");
       sql.push("SELECT internal_id, id, location, userDisabled, " +
                "installDate, version, applyBackgroundUpdates, " +
                "sourceURI, releaseNotesURI FROM addon");
       sql.push("SELECT internal_id, id, location, userDisabled, installDate, " +
                "version FROM addon");
 
       var stmt = null;
@@ -4408,16 +4422,18 @@ var XPIDatabase = {
         if ("softDisabled" in row)
           migrateData[row.location][row.id].softDisabled = row.softDisabled == 1;
         if ("applyBackgroundUpdates" in row)
           migrateData[row.location][row.id].applyBackgroundUpdates = row.applyBackgroundUpdates == 1;
         if ("sourceURI" in row)
           migrateData[row.location][row.id].sourceURI = row.sourceURI;
         if ("releaseNotesURI" in row)
           migrateData[row.location][row.id].releaseNotesURI = row.releaseNotesURI;
+        if ("foreignInstall" in row)
+          migrateData[row.location][row.id].foreignInstall = row.foreignInstall;
       }
 
       var taStmt = this.connection.createStatement("SELECT id, minVersion, " +
                                                    "maxVersion FROM " +
                                                    "targetApplication WHERE " +
                                                    "addon_internal_id=:internal_id");
 
       for (let location in migrateData) {
@@ -4528,16 +4544,17 @@ var XPIDatabase = {
                                   "visible INTEGER, active INTEGER, " +
                                   "userDisabled INTEGER, appDisabled INTEGER, " +
                                   "pendingUninstall INTEGER, descriptor TEXT, " +
                                   "installDate INTEGER, updateDate INTEGER, " +
                                   "applyBackgroundUpdates INTEGER, " +
                                   "bootstrap INTEGER, skinnable INTEGER, " +
                                   "size INTEGER, sourceURI TEXT, " +
                                   "releaseNotesURI TEXT, softDisabled INTEGER, " +
+                                  "foreignInstall INTEGER, " +
                                   "UNIQUE (id, location)");
       this.connection.createTable("targetApplication",
                                   "addon_internal_id INTEGER, " +
                                   "id TEXT, minVersion TEXT, maxVersion TEXT, " +
                                   "UNIQUE (addon_internal_id, id)");
       this.connection.createTable("targetPlatform",
                                   "addon_internal_id INTEGER, " +
                                   "os, abi TEXT, " +
@@ -5202,16 +5219,17 @@ var XPIDatabase = {
                                                           aDescriptor) {
     this.beginTransaction();
 
     // Any errors in here should rollback the transaction
     try {
       this.removeAddonMetadata(aOldAddon);
       aNewAddon.installDate = aOldAddon.installDate;
       aNewAddon.applyBackgroundUpdates = aOldAddon.applyBackgroundUpdates;
+      aNewAddon.foreignInstall = aOldAddon.foreignInstall;
       aNewAddon.active = (aNewAddon.visible && !aNewAddon.userDisabled &&
                           !aNewAddon.appDisabled)
       this.addAddonMetadata(aNewAddon, aDescriptor);
       this.commitTransaction();
     }
     catch (e) {
       this.rollbackTransaction();
       throw e;
@@ -6817,16 +6835,17 @@ AddonInternal.prototype = {
   _selectedLocale: null,
   active: false,
   visible: false,
   userDisabled: false,
   appDisabled: false,
   softDisabled: false,
   sourceURI: null,
   releaseNotesURI: null,
+  foreignInstall: false,
 
   get selectedLocale() {
     if (this._selectedLocale)
       return this._selectedLocale;
     let locale = findClosestLocale(this.locales);
     this._selectedLocale = locale ? locale : this.defaultLocale;
     return this._selectedLocale;
   },
@@ -7089,17 +7108,17 @@ function AddonWrapper(aAddon) {
       return [repositoryAddon[aProp], true];
     }
 
     return [objValue, false];
   }
 
   ["id", "version", "type", "isCompatible", "isPlatformCompatible",
    "providesUpdatesSecurely", "blocklistState", "blocklistURL", "appDisabled",
-   "softDisabled", "skinnable", "size"].forEach(function(aProp) {
+   "softDisabled", "skinnable", "size", "foreignInstall"].forEach(function(aProp) {
      this.__defineGetter__(aProp, function() aAddon[aProp]);
   }, this);
 
   ["fullDescription", "developerComments", "eula", "supportURL",
    "contributionURL", "contributionAmount", "averageRating", "reviewCount",
    "reviewURL", "totalDownloads", "weeklyDownloads", "dailyUsers",
    "repositoryStatus"].forEach(function(aProp) {
     this.__defineGetter__(aProp, function() {
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/extensions/test/addons/test_migrate4_7/install.rdf
@@ -0,0 +1,23 @@
+<?xml version="1.0"?>
+
+<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+     xmlns:em="http://www.mozilla.org/2004/em-rdf#">
+
+  <Description about="urn:mozilla:install-manifest">
+    <em:id>addon7@tests.mozilla.org</em:id>
+    <em:version>1.0</em:version>
+
+    <!-- Front End MetaData -->
+    <em:name>Test 7</em:name>
+    <em:description>Test Description</em:description>
+
+    <em:targetApplication>
+      <Description>
+        <em:id>xpcshell@tests.mozilla.org</em:id>
+        <em:minVersion>1</em:minVersion>
+        <em:maxVersion>2</em:maxVersion>
+      </Description>
+    </em:targetApplication>
+
+  </Description>
+</RDF>
--- a/toolkit/mozapps/extensions/test/browser/browser_searching.js
+++ b/toolkit/mozapps/extensions/test/browser/browser_searching.js
@@ -584,16 +584,32 @@ add_test(function() {
 
     search(QUERY, true, function() {
       check_filtered_results(QUERY, "relevancescore", false);
       run_next_test();
     });
   });
 });
 
+// Tests that incompatible add-ons are shown with a warning if compatibility checking is disabled
+add_test(function() {
+  Services.prefs.setBoolPref("extensions.checkCompatibility.nightly", false);
+  search("incompatible", false, function() {
+    var item = get_addon_item("remote5");
+    is_element_visible(item, "Incompatible addon should be visible");
+    is(item.getAttribute("notification"), "warning", "Compatibility warning should be shown");
+
+    var item = get_addon_item("remote6");
+    is(item, null, "Addon incompatible with the product should not be visible");
+
+    Services.prefs.clearUserPref("extensions.checkCompatibility.nightly");
+    run_next_test();
+  });
+});
+
 // Tests that restarting the manager doesn't change search results
 add_test(function() {
   restart_manager(gManagerWindow, null, function(aWindow) {
     gManagerWindow = aWindow;
     gCategoryUtilities = new CategoryUtilities(gManagerWindow);
 
     // We never restore to the search pane
     is(gCategoryUtilities.selectedCategory, "discover", "View should have changed to discover");
--- a/toolkit/mozapps/extensions/test/browser/browser_searching.xml
+++ b/toolkit/mozapps/extensions/test/browser/browser_searching.xml
@@ -181,10 +181,66 @@
         <appID>{92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a}</appID>
         <min_version>0</min_version>
         <max_version>*</max_version>
       </application>
     </compatible_applications>
     <compatible_os>ALL</compatible_os>
     <install size="4">http://example.com/remote4.xpi</install>
   </addon>
+  <addon>
+    <name>PASS - i</name>
+    <type id='1'>Extension</type>
+    <guid>remote5@tests.mozilla.org</guid>
+    <version>6.0</version>
+    <authors>
+      <author>
+        <name>Test Creator</name>
+        <link>http://example.com/creator.html</link>
+      </author>
+    </authors>
+    <status id='4'>Public</status>
+    <summary>Incompatible test</summary>
+    <description>Test description</description>
+    <compatible_applications>
+      <application>
+        <name>Firefox</name>
+        <appID>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</appID>
+        <min_version>0</min_version>
+        <max_version>1</max_version>
+      </application>
+      <application>
+        <name>SeaMonkey</name>
+        <appID>{92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a}</appID>
+        <min_version>0</min_version>
+        <max_version>1</max_version>
+      </application>
+    </compatible_applications>
+    <compatible_os>ALL</compatible_os>
+    <install size="1">http://example.com/addon1.xpi</install>
+  </addon>
+  <addon>
+    <name>FAIL - j</name>
+    <type id='1'>Extension</type>
+    <guid>remote6@tests.mozilla.org</guid>
+    <version>6.0</version>
+    <authors>
+      <author>
+        <name>Test Creator</name>
+        <link>http://example.com/creator.html</link>
+      </author>
+    </authors>
+    <status id='4'>Public</status>
+    <summary>Incompatible test</summary>
+    <description>Test description</description>
+    <compatible_applications>
+      <application>
+        <name>Fake Product</name>
+        <appID>fakeproduct@mozilla.org</appID>
+        <min_version>0</min_version>
+        <max_version>1</max_version>
+      </application>
+    </compatible_applications>
+    <compatible_os>ALL</compatible_os>
+    <install size="1">http://example.com/addon1.xpi</install>
+  </addon>
 </searchresults>
 
--- a/toolkit/mozapps/extensions/test/xpcshell/test_distribution.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_distribution.js
@@ -84,16 +84,17 @@ function run_test_1() {
 
   startupManager();
 
   AddonManager.getAddonByID("addon1@tests.mozilla.org", function(a1) {
     do_check_neq(a1, null);
     do_check_eq(a1.version, "1.0");
     do_check_true(a1.isActive);
     do_check_eq(a1.scope, AddonManager.SCOPE_PROFILE);
+    do_check_false(a1.foreignInstall);
 
     run_test_2();
   });
 }
 
 // Tests that starting with a newer version in the distribution dir doesn't
 // install it yet
 function run_test_2() {
@@ -117,16 +118,17 @@ function run_test_2() {
 function run_test_3() {
   restartManager("2");
 
   AddonManager.getAddonByID("addon1@tests.mozilla.org", function(a1) {
     do_check_neq(a1, null);
     do_check_eq(a1.version, "2.0");
     do_check_true(a1.isActive);
     do_check_eq(a1.scope, AddonManager.SCOPE_PROFILE);
+    do_check_false(a1.foreignInstall);
 
     run_test_4();
   });
 }
 
 // Test that an app upgrade doesn't downgrade the extension
 function run_test_4() {
   setOldModificationTime();
--- a/toolkit/mozapps/extensions/test/xpcshell/test_install.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_install.js
@@ -158,16 +158,17 @@ function check_test_1() {
           do_check_neq(a1, null);
           do_check_eq(a1.type, "extension");
           do_check_eq(a1.version, "1.0");
           do_check_eq(a1.name, "Test 1");
           do_check_true(isExtensionInAddonsList(profileDir, a1.id));
           do_check_true(do_get_addon("test_install1").exists());
           do_check_in_crash_annotation(a1.id, a1.version);
           do_check_eq(a1.size, ADDON1_SIZE);
+          do_check_false(a1.foreignInstall);
 
           do_check_eq(a1.sourceURI.spec,
                       Services.io.newFileURI(do_get_addon("test_install1")).spec);
           let difference = a1.installDate.getTime() - updateDate;
           if (Math.abs(difference) > MAX_TIME_DIFFERENCE)
             do_throw("Add-on install time was out by " + difference + "ms");
 
           difference = a1.updateDate.getTime() - updateDate;
@@ -377,16 +378,17 @@ function check_test_5(install) {
           do_check_eq(a2.version, "3.0");
           do_check_eq(a2.name, "Real Test 3");
           do_check_true(a2.isActive);
           do_check_true(isExtensionInAddonsList(profileDir, a2.id));
           do_check_true(do_get_addon("test_install2_2").exists());
           do_check_in_crash_annotation(a2.id, a2.version);
           do_check_eq(a2.sourceURI.spec,
                       "http://localhost:4444/addons/test_install2_2.xpi");
+          do_check_false(a2.foreignInstall);
 
           do_check_eq(a2.installDate.getTime(), gInstallDate);
           // Update date should be later (or the same if this test is too fast)
           do_check_true(a2.installDate <= a2.updateDate);
 
           a2.uninstall();
           restartManager();
 
--- a/toolkit/mozapps/extensions/test/xpcshell/test_migrate4.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_migrate4.js
@@ -106,39 +106,41 @@ function prepare_profile() {
                                "addon6@tests.mozilla.org"],
                                function([a1, a2, a3, a4, a5, a6]) {
     a2.userDisabled = true;
     a2.applyBackgroundUpdates = false;
     a4.userDisabled = true;
     a6.userDisabled = true;
 
     a6.findUpdates({
-      onUpdateAvailable: function(aAddon, aInstall) {
-        completeAllInstalls([aInstall], function() {
-          restartManager();
+      onUpdateAvailable: function(aAddon, aInstall6) {
+        AddonManager.getInstallForURL("http://localhost:4444/addons/test_migrate4_7.xpi", function(aInstall7) {
+          completeAllInstalls([aInstall6, aInstall7], function() {
+            restartManager();
 
-          AddonManager.getAddonsByIDs(["addon1@tests.mozilla.org",
-                                       "addon2@tests.mozilla.org",
-                                       "addon3@tests.mozilla.org",
-                                       "addon4@tests.mozilla.org",
-                                       "addon5@tests.mozilla.org",
-                                       "addon6@tests.mozilla.org"],
-                                       function([a1, a2, a3, a4, a5, a6]) {
-            a3.userDisabled = true;
-            a4.userDisabled = false;
+            AddonManager.getAddonsByIDs(["addon1@tests.mozilla.org",
+                                         "addon2@tests.mozilla.org",
+                                         "addon3@tests.mozilla.org",
+                                         "addon4@tests.mozilla.org",
+                                         "addon5@tests.mozilla.org",
+                                         "addon6@tests.mozilla.org"],
+                                         function([a1, a2, a3, a4, a5, a6]) {
+              a3.userDisabled = true;
+              a4.userDisabled = false;
 
-            a5.findUpdates({
-              onUpdateFinished: function() {
-                shutdownManager();
+              a5.findUpdates({
+                onUpdateFinished: function() {
+                  shutdownManager();
 
-                perform_migration();
-              }
-            }, AddonManager.UPDATE_WHEN_USER_REQUESTED);
+                  perform_migration();
+                }
+              }, AddonManager.UPDATE_WHEN_USER_REQUESTED);
+            });
           });
-        });
+        }, "application/x-xpinstall");
       }
     }, AddonManager.UPDATE_WHEN_USER_REQUESTED);
   });
 }
 
 function perform_migration() {
   let dbfile = gProfD.clone();
   dbfile.append("extensions.sqlite");
@@ -161,62 +163,80 @@ function test_results() {
   check_startup_changes("disabled", []);
   check_startup_changes("enabled", []);
 
   AddonManager.getAddonsByIDs(["addon1@tests.mozilla.org",
                                "addon2@tests.mozilla.org",
                                "addon3@tests.mozilla.org",
                                "addon4@tests.mozilla.org",
                                "addon5@tests.mozilla.org",
-                               "addon6@tests.mozilla.org"],
-                               function([a1, a2, a3, a4, a5, a6]) {
+                               "addon6@tests.mozilla.org",
+                               "addon7@tests.mozilla.org"],
+                               function([a1, a2, a3, a4, a5, a6, a7]) {
     // addon1 was enabled
     do_check_neq(a1, null);
     do_check_false(a1.userDisabled);
     do_check_false(a1.appDisabled);
     do_check_true(a1.isActive);
     do_check_true(a1.applyBackgroundUpdates);
+    do_check_true(a1.foreignInstall);
 
     // addon2 was disabled
     do_check_neq(a2, null);
     do_check_true(a2.userDisabled);
     do_check_false(a2.appDisabled);
     do_check_false(a2.isActive);
     do_check_false(a2.applyBackgroundUpdates);
+    do_check_true(a2.foreignInstall);
 
     // addon3 was pending-disable in the database
     do_check_neq(a3, null);
     do_check_true(a3.userDisabled);
     do_check_false(a3.appDisabled);
     do_check_false(a3.isActive);
     do_check_true(a3.applyBackgroundUpdates);
+    do_check_true(a3.foreignInstall);
 
     // addon4 was pending-enable in the database
     do_check_neq(a4, null);
     do_check_false(a4.userDisabled);
     do_check_false(a4.appDisabled);
     do_check_true(a4.isActive);
     do_check_true(a4.applyBackgroundUpdates);
+    do_check_true(a4.foreignInstall);
 
     // addon5 was enabled in the database but needed a compatibiltiy update
     do_check_neq(a5, null);
     do_check_false(a5.userDisabled);
     do_check_false(a5.appDisabled);
     do_check_true(a5.isActive);
     do_check_true(a5.applyBackgroundUpdates);
+    do_check_true(a5.foreignInstall);
 
     // addon6 was disabled and compatible but a new version has been installed
     do_check_neq(a6, null);
     do_check_eq(a6.version, "2.0");
     do_check_true(a6.userDisabled);
     do_check_false(a6.appDisabled);
     do_check_false(a6.isActive);
     do_check_true(a6.applyBackgroundUpdates);
+    do_check_true(a6.foreignInstall);
     do_check_eq(a6.sourceURI.spec, "http://localhost:4444/addons/test_migrate4_6.xpi");
     do_check_eq(a6.releaseNotesURI.spec, "http://example.com/updateInfo.xhtml");
+
+    // addon7 was installed manually
+    do_check_neq(a7, null);
+    do_check_eq(a7.version, "1.0");
+    do_check_false(a7.userDisabled);
+    do_check_false(a7.appDisabled);
+    do_check_true(a7.isActive);
+    do_check_true(a7.applyBackgroundUpdates);
+    do_check_false(a7.foreignInstall);
+    do_check_eq(a7.sourceURI.spec, "http://localhost:4444/addons/test_migrate4_7.xpi");
+    do_check_eq(a7.releaseNotesURI, null);
     testserver.stop(do_test_finished);
   });
 }
 
 function run_test() {
   do_test_pending();
 
   prepare_profile();
--- a/toolkit/mozapps/extensions/test/xpcshell/test_startup.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_startup.js
@@ -197,38 +197,41 @@ function run_test_1() {
     do_check_eq(a1.version, "1.0");
     do_check_eq(a1.name, "Test 1");
     do_check_true(isExtensionInAddonsList(profileDir, a1.id));
     do_check_true(hasFlag(a1.permissions, AddonManager.PERM_CAN_UNINSTALL));
     do_check_true(hasFlag(a1.permissions, AddonManager.PERM_CAN_UPGRADE));
     do_check_in_crash_annotation(addon1.id, addon1.version);
     do_check_eq(a1.scope, AddonManager.SCOPE_PROFILE);
     do_check_eq(a1.sourceURI, null);
+    do_check_true(a1.foreignInstall);
 
     do_check_neq(a2, null);
     do_check_eq(a2.id, "addon2@tests.mozilla.org");
     do_check_eq(a2.version, "2.0");
     do_check_eq(a2.name, "Test 2");
     do_check_true(isExtensionInAddonsList(profileDir, a2.id));
     do_check_true(hasFlag(a2.permissions, AddonManager.PERM_CAN_UNINSTALL));
     do_check_true(hasFlag(a2.permissions, AddonManager.PERM_CAN_UPGRADE));
     do_check_in_crash_annotation(addon2.id, addon2.version);
     do_check_eq(a2.scope, AddonManager.SCOPE_PROFILE);
     do_check_eq(a2.sourceURI, null);
+    do_check_true(a2.foreignInstall);
 
     do_check_neq(a3, null);
     do_check_eq(a3.id, "addon3@tests.mozilla.org");
     do_check_eq(a3.version, "3.0");
     do_check_eq(a3.name, "Test 3");
     do_check_true(isExtensionInAddonsList(profileDir, a3.id));
     do_check_true(hasFlag(a3.permissions, AddonManager.PERM_CAN_UNINSTALL));
     do_check_true(hasFlag(a3.permissions, AddonManager.PERM_CAN_UPGRADE));
     do_check_in_crash_annotation(addon3.id, addon3.version);
     do_check_eq(a3.scope, AddonManager.SCOPE_PROFILE);
     do_check_eq(a3.sourceURI, null);
+    do_check_true(a3.foreignInstall);
 
     do_check_eq(a4, null);
     do_check_false(isExtensionInAddonsList(profileDir, "addon4@tests.mozilla.org"));
     dest = profileDir.clone();
     dest.append(do_get_expected_addon_name("addon4@tests.mozilla.org"));
     do_check_false(dest.exists());
 
     do_check_eq(a5, null);
@@ -292,27 +295,29 @@ function run_test_2() {
     do_check_eq(a1.id, "addon1@tests.mozilla.org");
     do_check_eq(a1.version, "1.0");
     do_check_true(isExtensionInAddonsList(profileDir, a1.id));
     do_check_false(isExtensionInAddonsList(userDir, a1.id));
     do_check_true(hasFlag(a1.permissions, AddonManager.PERM_CAN_UNINSTALL));
     do_check_true(hasFlag(a1.permissions, AddonManager.PERM_CAN_UPGRADE));
     do_check_in_crash_annotation(addon1.id, a1.version);
     do_check_eq(a1.scope, AddonManager.SCOPE_PROFILE);
+    do_check_true(a1.foreignInstall);
 
     do_check_neq(a2, null);
     do_check_eq(a2.id, "addon2@tests.mozilla.org");
     do_check_eq(a2.version, "2.1");
     do_check_true(isExtensionInAddonsList(profileDir, a2.id));
     do_check_false(isExtensionInAddonsList(userDir, a2.id));
     do_check_false(isExtensionInAddonsList(globalDir, a2.id));
     do_check_true(hasFlag(a2.permissions, AddonManager.PERM_CAN_UNINSTALL));
     do_check_true(hasFlag(a2.permissions, AddonManager.PERM_CAN_UPGRADE));
     do_check_in_crash_annotation(addon2.id, a2.version);
     do_check_eq(a2.scope, AddonManager.SCOPE_PROFILE);
+    do_check_true(a2.foreignInstall);
 
     do_check_eq(a3, null);
     do_check_false(isExtensionInAddonsList(profileDir, "addon3@tests.mozilla.org"));
     do_check_not_in_crash_annotation(addon3.id, addon3.version);
 
     do_check_eq(a4, null);
     do_check_false(isExtensionInAddonsList(profileDir, "addon4@tests.mozilla.org"));
 
--- a/toolkit/mozapps/extensions/test/xpcshell/test_theme.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_theme.js
@@ -89,34 +89,37 @@ function run_test() {
   AddonManager.addInstallListener(InstallListener);
 
   AddonManager.getAddonsByIDs(["default@tests.mozilla.org",
                                "theme1@tests.mozilla.org",
                                "theme2@tests.mozilla.org"],
                                function([d, t1, t2]) {
     do_check_neq(d, null);
     do_check_false(d.skinnable);
+    do_check_false(d.foreignInstall);
 
     do_check_neq(t1, null);
     do_check_false(t1.userDisabled);
     do_check_false(t1.appDisabled);
     do_check_true(t1.isActive);
     do_check_true(t1.skinnable);
+    do_check_true(t1.foreignInstall);
     do_check_eq(t1.screenshots, null);
     do_check_true(isThemeInAddonsList(profileDir, t1.id));
     do_check_false(hasFlag(t1.permissions, AddonManager.PERM_CAN_DISABLE));
     do_check_false(hasFlag(t1.permissions, AddonManager.PERM_CAN_ENABLE));
     do_check_eq(t1.operationsRequiringRestart, AddonManager.OP_NEEDS_RESTART_UNINSTALL |
                                                AddonManager.OP_NEEDS_RESTART_DISABLE);
 
     do_check_neq(t2, null);
     do_check_true(t2.userDisabled);
     do_check_false(t2.appDisabled);
     do_check_false(t2.isActive);
     do_check_false(t2.skinnable);
+    do_check_true(t2.foreignInstall);
     do_check_eq(t2.screenshots, null);
     do_check_false(isThemeInAddonsList(profileDir, t2.id));
     do_check_false(hasFlag(t2.permissions, AddonManager.PERM_CAN_DISABLE));
     do_check_true(hasFlag(t2.permissions, AddonManager.PERM_CAN_ENABLE));
     do_check_eq(t2.operationsRequiringRestart, AddonManager.OP_NEEDS_RESTART_ENABLE);
 
     run_test_1();
   });
--- a/toolkit/mozapps/extensions/test/xpcshell/test_update.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_update.js
@@ -85,16 +85,17 @@ function end_test() {
 
 // Verify that an update is available and can be installed.
 function run_test_1() {
   AddonManager.getAddonByID("addon1@tests.mozilla.org", function(a1) {
     do_check_neq(a1, null);
     do_check_eq(a1.version, "1.0");
     do_check_eq(a1.applyBackgroundUpdates, AddonManager.AUTOUPDATE_DEFAULT);
     do_check_eq(a1.releaseNotesURI, null);
+    do_check_true(a1.foreignInstall);
 
     a1.applyBackgroundUpdates = AddonManager.AUTOUPDATE_DEFAULT;
 
     prepare_test({
       "addon1@tests.mozilla.org": [
         ["onPropertyChanged", ["applyBackgroundUpdates"]]
       ]
     });
@@ -214,16 +215,17 @@ function check_test_2() {
     do_check_true(isExtensionInAddonsList(profileDir, olda1.id));
 
     AddonManager.getAddonByID("addon1@tests.mozilla.org", function(a1) {
       do_check_neq(a1, null);
       do_check_eq(a1.version, "2.0");
       do_check_true(isExtensionInAddonsList(profileDir, a1.id));
       do_check_eq(a1.applyBackgroundUpdates, AddonManager.AUTOUPDATE_DISABLE);
       do_check_eq(a1.releaseNotesURI.spec, "http://example.com/updateInfo.xhtml");
+      do_check_true(a1.foreignInstall);
 
       a1.uninstall();
       restartManager();
 
       run_test_3();
     });
   });
 }