Backout 345ae68f15f4, b3b40121ac8d, 0d18b7a246d7, 9dbb6064ab58, dee9d7fa8eb6, 63eec6bfa948, 323c6be7cfe8 & f4aac7523a48 (bug 732875) for compilation failures
authorEd Morley <emorley@mozilla.com>
Mon, 14 May 2012 21:05:24 +0100
changeset 93909 3f7291bc4efc003964fb98b1390019771042f3ac
parent 93908 345ae68f15f4bbd6f0a669f8d8bba0fe2fa6889a
child 93910 ff13f71571591493b19c29ddae3403a33c7f0686
push id22688
push useremorley@mozilla.com
push dateTue, 15 May 2012 11:33:31 +0000
treeherderautoland@b69d000b726a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs732875
milestone15.0a1
backs out345ae68f15f4bbd6f0a669f8d8bba0fe2fa6889a
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Backout 345ae68f15f4, b3b40121ac8d, 0d18b7a246d7, 9dbb6064ab58, dee9d7fa8eb6, 63eec6bfa948, 323c6be7cfe8 & f4aac7523a48 (bug 732875) for compilation failures
content/base/src/nsDOMBlobBuilder.cpp
content/base/src/nsDOMBlobBuilder.h
content/base/src/nsDOMFile.cpp
content/canvas/src/CanvasUtils.h
content/canvas/src/CustomQS_Canvas2D.h
content/canvas/src/WebGLContext.cpp
content/canvas/src/WebGLContext.h
content/canvas/src/WebGLContextGL.cpp
content/canvas/src/WebGLContextValidate.cpp
content/canvas/src/nsCanvasRenderingContext2D.cpp
content/canvas/src/nsCanvasRenderingContext2DAzure.cpp
content/html/content/src/nsHTMLCanvasElement.cpp
content/media/VideoUtils.h
content/media/nsBuiltinDecoderReader.cpp
content/media/nsBuiltinDecoderStateMachine.cpp
content/media/ogg/nsOggCodecState.cpp
content/media/raw/nsRawReader.cpp
content/media/webm/nsWebMReader.cpp
gfx/2d/Blur.cpp
gfx/thebes/gfxASurface.cpp
mfbt/CheckedInt.h
mfbt/Makefile.in
mfbt/exported_headers.mk
mfbt/tests/Makefile.in
mfbt/tests/TestCheckedInt.cpp
xpcom/ds/CheckedInt.h
xpcom/ds/Makefile.in
xpcom/tests/Makefile.in
xpcom/tests/TestCheckedInt.cpp
--- a/content/base/src/nsDOMBlobBuilder.cpp
+++ b/content/base/src/nsDOMBlobBuilder.cpp
@@ -65,17 +65,17 @@ nsDOMMultipartFile::GetSize(PRUint64* aL
       PRUint64 l = 0;
   
       nsresult rv = blob->GetSize(&l);
       NS_ENSURE_SUCCESS(rv, rv);
   
       length += l;
     }
   
-    NS_ENSURE_TRUE(length.isValid(), NS_ERROR_FAILURE);
+    NS_ENSURE_TRUE(length.valid(), NS_ERROR_FAILURE);
 
     mLength = length.value();
   }
 
   *aLength = mLength;
   return NS_OK;
 }
 
--- a/content/base/src/nsDOMBlobBuilder.h
+++ b/content/base/src/nsDOMBlobBuilder.h
@@ -34,18 +34,19 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef nsDOMBlobBuilder_h
 #define nsDOMBlobBuilder_h
 
 #include "nsDOMFile.h"
+#include "CheckedInt.h"
 
-#include "mozilla/CheckedInt.h"
+#include "mozilla/StandardInteger.h"
 
 using namespace mozilla;
 
 class nsDOMMultipartFile : public nsDOMFileBase,
                            public nsIJSNativeInitializer
 {
 public:
   // Create as a file
@@ -122,20 +123,20 @@ protected:
   {
     if (mDataBufferLen >= mDataLen + aSize) {
       mDataLen += aSize;
       return true;
     }
 
     // Start at 1 or we'll loop forever.
     CheckedUint32 bufferLen = NS_MAX<PRUint32>(mDataBufferLen, 1);
-    while (bufferLen.isValid() && bufferLen.value() < mDataLen + aSize)
+    while (bufferLen.valid() && bufferLen.value() < mDataLen + aSize)
       bufferLen *= 2;
 
-    if (!bufferLen.isValid())
+    if (!bufferLen.valid())
       return false;
 
     // PR_ memory functions are still fallible
     void* data = PR_Realloc(mData, bufferLen.value());
     if (!data)
       return false;
 
     mData = data;
--- a/content/base/src/nsDOMFile.cpp
+++ b/content/base/src/nsDOMFile.cpp
@@ -56,18 +56,18 @@
 #include "nsISeekableStream.h"
 #include "nsIUnicharInputStream.h"
 #include "nsIUnicodeDecoder.h"
 #include "nsNetCID.h"
 #include "nsNetUtil.h"
 #include "nsIUUIDGenerator.h"
 #include "nsBlobProtocolHandler.h"
 #include "nsStringStream.h"
+#include "CheckedInt.h"
 #include "nsJSUtils.h"
-#include "mozilla/CheckedInt.h"
 #include "mozilla/Preferences.h"
 
 #include "plbase64.h"
 #include "prmem.h"
 #include "dombindings.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
@@ -222,17 +222,17 @@ ParseSize(PRInt64 aSize, PRInt64& aStart
   }
   else if (aEnd < 0) {
     newEndOffset += aSize;
   }
   else if (aEnd > aSize) {
     newEndOffset = aSize;
   }
 
-  if (!newStartOffset.isValid() || !newEndOffset.isValid() ||
+  if (!newStartOffset.valid() || !newEndOffset.valid() ||
       newStartOffset.value() >= newEndOffset.value()) {
     aStart = aEnd = 0;
   }
   else {
     aStart = newStartOffset.value();
     aEnd = newEndOffset.value();
   }
 }
--- a/content/canvas/src/CanvasUtils.h
+++ b/content/canvas/src/CanvasUtils.h
@@ -35,17 +35,17 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef _CANVASUTILS_H_
 #define _CANVASUTILS_H_
 
 #include "prtypes.h"
 
-#include "mozilla/CheckedInt.h"
+#include "CheckedInt.h"
 
 class nsHTMLCanvasElement;
 class nsIPrincipal;
 
 namespace mozilla {
 
 namespace gfx {
 class Matrix;
@@ -58,19 +58,19 @@ using namespace gfx;
 // Check that the rectangle [x,y,w,h] is a subrectangle of [0,0,realWidth,realHeight]
 
 inline bool CheckSaneSubrectSize(PRInt32 x, PRInt32 y, PRInt32 w, PRInt32 h,
                             PRInt32 realWidth, PRInt32 realHeight) {
     CheckedInt32 checked_xmost  = CheckedInt32(x) + w;
     CheckedInt32 checked_ymost  = CheckedInt32(y) + h;
 
     return w >= 0 && h >= 0 && x >= 0 && y >= 0 &&
-        checked_xmost.isValid() &&
+        checked_xmost.valid() &&
         checked_xmost.value() <= realWidth &&
-        checked_ymost.isValid() &&
+        checked_ymost.valid() &&
         checked_ymost.value() <= realHeight;
 }
 
 // Flag aCanvasElement as write-only if drawing an image with aPrincipal
 // onto it would make it such.
 
 void DoDrawImageSecurityCheck(nsHTMLCanvasElement *aCanvasElement,
                               nsIPrincipal *aPrincipal,
--- a/content/canvas/src/CustomQS_Canvas2D.h
+++ b/content/canvas/src/CustomQS_Canvas2D.h
@@ -35,17 +35,17 @@
  * 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 ***** */
 
 #include "nsDOMError.h"
 #include "nsIDOMCanvasRenderingContext2D.h"
-#include "mozilla/CheckedInt.h"
+#include "CheckedInt.h"
 #include "nsMathUtils.h"
 #include "CustomQS_Canvas.h"
 
 #include "jsapi.h"
 #include "jsfriendapi.h"
 
 typedef NS_STDCALL_FUNCPROTO(nsresult, CanvasStyleSetterType, nsIDOMCanvasRenderingContext2D,
                              SetStrokeStyle_multi, (const nsAString &, nsISupports *));
@@ -164,17 +164,17 @@ CreateImageData(JSContext* cx, JSObject*
     using mozilla::CheckedInt;
 
     if (w == 0)
         w = 1;
     if (h == 0)
         h = 1;
 
     CheckedInt<uint32_t> len = CheckedInt<uint32_t>(w) * h * 4;
-    if (!len.isValid()) {
+    if (!len.valid()) {
         return xpc_qsThrow(cx, NS_ERROR_DOM_INDEX_SIZE_ERR);
     }
 
     // Create the fast typed array; it's initialized to 0 by default.
     JSObject* darray = JS_NewUint8ClampedArray(cx, len.value());
     JS::AutoObjectRooter rd(cx, darray);
     if (!darray) {
         return false;
--- a/content/canvas/src/WebGLContext.cpp
+++ b/content/canvas/src/WebGLContext.cpp
@@ -420,17 +420,17 @@ WebGLContext::SetDimensions(PRInt32 widt
     // We're going to create an entirely new context.  If our
     // generation is not 0 right now (that is, if this isn't the first
     // context we're creating), we may have to dispatch a context lost
     // event.
 
     // If incrementing the generation would cause overflow,
     // don't allow it.  Allowing this would allow us to use
     // resource handles created from older context generations.
-    if (!(mGeneration + 1).isValid())
+    if (!(mGeneration+1).valid())
         return NS_ERROR_FAILURE; // exit without changing the value of mGeneration
 
     gl::ContextFormat format(gl::ContextFormat::BasicRGBA32);
     if (mOptions.depth) {
         format.depth = 24;
         format.minDepth = 16;
     }
 
--- a/content/canvas/src/WebGLContext.h
+++ b/content/canvas/src/WebGLContext.h
@@ -59,19 +59,19 @@
 #include "nsIJSNativeInitializer.h"
 #include "nsContentUtils.h"
 #include "nsWrapperCache.h"
 #include "nsIObserver.h"
 
 #include "GLContextProvider.h"
 #include "Layers.h"
 
+#include "CheckedInt.h"
 #include "nsDataHashtable.h"
 
-#include "mozilla/CheckedInt.h"
 #include "mozilla/dom/ImageData.h"
 
 #ifdef XP_MACOSX
 #include "ForceDiscreteGPUHelperCGL.h"
 #endif
 
 #include "angle/ShaderLang.h"
 
@@ -476,17 +476,17 @@ public:
     {
         mArray.RemoveElementSorted(Entry(ElementType(), monotonicHandle),
                                    typename Entry::Comparator());
     }
 
 private:
     WebGLMonotonicHandle NextMonotonicHandle() {
         ++mCurrentMonotonicHandle;
-        if (!mCurrentMonotonicHandle.isValid())
+        if (!mCurrentMonotonicHandle.valid())
             NS_RUNTIMEABORT("ran out of monotonic ids!");
         return mCurrentMonotonicHandle.value();
     }
 
     nsTArray<Entry> mArray;
     CheckedInt<WebGLMonotonicHandle> mCurrentMonotonicHandle;
 };
 
@@ -1743,17 +1743,17 @@ public:
     }
 
     const ImageInfo& ImageInfoAt(size_t level, size_t face) const {
         return const_cast<WebGLTexture*>(this)->ImageInfoAt(level, face);
     }
 
     bool HasImageInfoAt(size_t level, size_t face) const {
         CheckedUint32 checked_index = CheckedUint32(level) * mFacesCount + face;
-        return checked_index.isValid() &&
+        return checked_index.valid() &&
                checked_index.value() < mImageInfos.Length() &&
                ImageInfoAt(level, face).mIsDefined;
     }
 
     static size_t FaceForTarget(WebGLenum target) {
         return target == LOCAL_GL_TEXTURE_2D ? 0 : target - LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X;
     }
 
@@ -2323,17 +2323,17 @@ public:
     bool HasBothShaderTypesAttached() {
         return
             HasAttachedShaderOfType(LOCAL_GL_VERTEX_SHADER) &&
             HasAttachedShaderOfType(LOCAL_GL_FRAGMENT_SHADER);
     }
 
     bool NextGeneration()
     {
-        if (!(mGeneration + 1).isValid())
+        if (!(mGeneration+1).valid())
             return false; // must exit without changing mGeneration
         ++mGeneration;
         return true;
     }
 
     /* Called only after LinkProgram */
     bool UpdateInfo();
 
--- a/content/canvas/src/WebGLContextGL.cpp
+++ b/content/canvas/src/WebGLContextGL.cpp
@@ -682,17 +682,17 @@ WebGLContext::BufferSubData(GLenum targe
 
     if (byteOffset < 0)
         return ErrorInvalidValue("bufferSubData: negative offset");
 
     if (!boundBuffer)
         return ErrorInvalidOperation("BufferData: no buffer bound!");
 
     CheckedUint32 checked_neededByteLength = CheckedUint32(byteOffset) + data->mLength;
-    if (!checked_neededByteLength.isValid())
+    if (!checked_neededByteLength.valid())
         return ErrorInvalidOperation("bufferSubData: integer overflow computing the needed byte length");
 
     if (checked_neededByteLength.value() > boundBuffer->ByteLength())
         return ErrorInvalidOperation("BufferSubData: not enough data - operation requires %d bytes, but buffer only has %d bytes",
                                      checked_neededByteLength.value(), boundBuffer->ByteLength());
 
     MakeContextCurrent();
 
@@ -721,17 +721,17 @@ WebGLContext::BufferSubData(WebGLenum ta
 
     if (byteOffset < 0)
         return ErrorInvalidValue("bufferSubData: negative offset");
 
     if (!boundBuffer)
         return ErrorInvalidOperation("BufferSubData: no buffer bound!");
 
     CheckedUint32 checked_neededByteLength = CheckedUint32(byteOffset) + data.mLength;
-    if (!checked_neededByteLength.isValid())
+    if (!checked_neededByteLength.valid())
         return ErrorInvalidOperation("bufferSubData: integer overflow computing the needed byte length");
 
     if (checked_neededByteLength.value() > boundBuffer->ByteLength())
         return ErrorInvalidOperation("BufferSubData: not enough data -- operation requires %d bytes, but buffer only has %d bytes",
                                      checked_neededByteLength.value(), boundBuffer->ByteLength());
 
     MakeContextCurrent();
 
@@ -936,17 +936,17 @@ WebGLContext::CopyTexSubImage2D_base(Web
 
         PRUint32 texelSize = 0;
         if (!ValidateTexFormatAndType(internalformat, LOCAL_GL_UNSIGNED_BYTE, -1, &texelSize, info))
             return;
 
         CheckedUint32 checked_neededByteLength = 
             GetImageSize(height, width, texelSize, mPixelStoreUnpackAlignment);
 
-        if (!checked_neededByteLength.isValid())
+        if (!checked_neededByteLength.valid())
             return ErrorInvalidOperation("%s: integer overflow computing the needed buffer size", info);
 
         PRUint32 bytesNeeded = checked_neededByteLength.value();
 
         // now that the size is known, create the buffer
 
         // We need some zero pages, because GL doesn't guarantee the
         // contents of a texture allocated with NULL data.
@@ -1557,17 +1557,17 @@ WebGLContext::DoFakeVertexAttrib0(WebGLu
 {
     int whatDoesAttrib0Need = WhatDoesVertexAttrib0Need();
 
     if (whatDoesAttrib0Need == VertexAttrib0Status::Default)
         return true;
 
     CheckedUint32 checked_dataSize = CheckedUint32(vertexCount) * 4 * sizeof(WebGLfloat);
     
-    if (!checked_dataSize.isValid()) {
+    if (!checked_dataSize.valid()) {
         ErrorOutOfMemory("Integer overflow trying to construct a fake vertex attrib 0 array for a draw-operation "
                          "with %d vertices. Try reducing the number of vertices.", vertexCount);
         return false;
     }
     
     WebGLuint dataSize = checked_dataSize.value();
 
     if (!mFakeVertexAttrib0BufferObject) {
@@ -1774,17 +1774,17 @@ WebGLContext::DrawArrays(GLenum mode, We
         return;
 
     PRInt32 maxAllowedCount = 0;
     if (!ValidateBuffers(&maxAllowedCount, "drawArrays"))
         return;
 
     CheckedInt32 checked_firstPlusCount = CheckedInt32(first) + count;
 
-    if (!checked_firstPlusCount.isValid())
+    if (!checked_firstPlusCount.valid())
         return ErrorInvalidOperation("drawArrays: overflow in first+count");
 
     if (checked_firstPlusCount.value() > maxAllowedCount)
         return ErrorInvalidOperation("drawArrays: bound vertex attribute buffers do not have sufficient size for given first and count");
 
     MakeContextCurrent();
 
     if (mBoundFramebuffer) {
@@ -1842,63 +1842,63 @@ WebGLContext::DrawElements(WebGLenum mod
         if (byteOffset % 2 != 0)
             return ErrorInvalidOperation("DrawElements: invalid byteOffset for UNSIGNED_SHORT (must be a multiple of 2)");
     } else if (type == LOCAL_GL_UNSIGNED_BYTE) {
         checked_byteCount = count;
     } else {
         return ErrorInvalidEnum("DrawElements: type must be UNSIGNED_SHORT or UNSIGNED_BYTE");
     }
 
-    if (!checked_byteCount.isValid())
+    if (!checked_byteCount.valid())
         return ErrorInvalidValue("DrawElements: overflow in byteCount");
 
     // If there is no current program, this is silently ignored.
     // Any checks below this depend on a program being available.
     if (!mCurrentProgram)
         return;
 
     if (!mBoundElementArrayBuffer)
         return ErrorInvalidOperation("DrawElements: must have element array buffer binding");
 
     if (!mBoundElementArrayBuffer->Data())
         return ErrorInvalidOperation("drawElements: bound element array buffer doesn't have any data");
 
     CheckedUint32 checked_neededByteCount = checked_byteCount + byteOffset;
 
-    if (!checked_neededByteCount.isValid())
+    if (!checked_neededByteCount.valid())
         return ErrorInvalidOperation("DrawElements: overflow in byteOffset+byteCount");
 
     if (checked_neededByteCount.value() > mBoundElementArrayBuffer->ByteLength())
         return ErrorInvalidOperation("DrawElements: bound element array buffer is too small for given count and offset");
 
     PRInt32 maxAllowedCount = 0;
     if (!ValidateBuffers(&maxAllowedCount, "drawElements"))
       return;
 
     PRInt32 maxIndex
       = type == LOCAL_GL_UNSIGNED_SHORT
         ? mBoundElementArrayBuffer->FindMaxUshortElement()
         : mBoundElementArrayBuffer->FindMaxUbyteElement();
 
     CheckedInt32 checked_maxIndexPlusOne = CheckedInt32(maxIndex) + 1;
 
-    if (!checked_maxIndexPlusOne.isValid() ||
+    if (!checked_maxIndexPlusOne.valid() ||
         checked_maxIndexPlusOne.value() > maxAllowedCount)
     {
         // the index array contains invalid indices for the current drawing state, but they
         // might not be used by the present drawElements call, depending on first and count.
 
         PRInt32 maxIndexInSubArray
           = type == LOCAL_GL_UNSIGNED_SHORT
             ? mBoundElementArrayBuffer->FindMaxElementInSubArray<GLushort>(count, byteOffset)
             : mBoundElementArrayBuffer->FindMaxElementInSubArray<GLubyte>(count, byteOffset);
 
         CheckedInt32 checked_maxIndexInSubArrayPlusOne = CheckedInt32(maxIndexInSubArray) + 1;
 
-        if (!checked_maxIndexInSubArrayPlusOne.isValid() ||
+        if (!checked_maxIndexInSubArrayPlusOne.valid() ||
             checked_maxIndexInSubArrayPlusOne.value() > maxAllowedCount)
         {
             return ErrorInvalidOperation(
                 "DrawElements: bound vertex attribute buffers do not have sufficient "
                 "size for given indices from the bound element array");
         }
     }
 
@@ -3878,17 +3878,17 @@ WebGLContext::ReadPixels(WebGLint x, Web
     CheckedUint32 checked_neededByteLength =
         GetImageSize(height, width, bytesPerPixel, mPixelStorePackAlignment);
 
     CheckedUint32 checked_plainRowSize = CheckedUint32(width) * bytesPerPixel;
 
     CheckedUint32 checked_alignedRowSize =
         RoundedToNextMultipleOf(checked_plainRowSize, mPixelStorePackAlignment);
 
-    if (!checked_neededByteLength.isValid())
+    if (!checked_neededByteLength.valid())
         return ErrorInvalidOperation("ReadPixels: integer overflow computing the needed buffer size");
 
     if (checked_neededByteLength.value() > dataByteLen)
         return ErrorInvalidOperation("ReadPixels: buffer too small");
 
     // Check the format and type params to assure they are an acceptable pair (as per spec)
     switch (format) {
         case LOCAL_GL_RGBA: {
@@ -5596,17 +5596,17 @@ WebGLContext::TexImage2D_base(WebGLenum 
     CheckedUint32 checked_neededByteLength = 
         GetImageSize(height, width, srcTexelSize, mPixelStoreUnpackAlignment);
 
     CheckedUint32 checked_plainRowSize = CheckedUint32(width) * srcTexelSize;
 
     CheckedUint32 checked_alignedRowSize =
         RoundedToNextMultipleOf(checked_plainRowSize.value(), mPixelStoreUnpackAlignment);
 
-    if (!checked_neededByteLength.isValid())
+    if (!checked_neededByteLength.valid())
         return ErrorInvalidOperation("texImage2D: integer overflow computing the needed buffer size");
 
     PRUint32 bytesNeeded = checked_neededByteLength.value();
 
     if (byteLength && byteLength < bytesNeeded)
         return ErrorInvalidOperation("TexImage2D: not enough data for operation (need %d, have %d)",
                                  bytesNeeded, byteLength);
 
@@ -5837,17 +5837,17 @@ WebGLContext::TexSubImage2D_base(WebGLen
     CheckedUint32 checked_neededByteLength = 
         GetImageSize(height, width, srcTexelSize, mPixelStoreUnpackAlignment);
 
     CheckedUint32 checked_plainRowSize = CheckedUint32(width) * srcTexelSize;
 
     CheckedUint32 checked_alignedRowSize = 
         RoundedToNextMultipleOf(checked_plainRowSize.value(), mPixelStoreUnpackAlignment);
 
-    if (!checked_neededByteLength.isValid())
+    if (!checked_neededByteLength.valid())
         return ErrorInvalidOperation("texSubImage2D: integer overflow computing the needed buffer size");
 
     PRUint32 bytesNeeded = checked_neededByteLength.value();
  
     if (byteLength < bytesNeeded)
         return ErrorInvalidOperation("texSubImage2D: not enough data for operation (need %d, have %d)", bytesNeeded, byteLength);
 
     WebGLTexture *tex = activeBoundTextureForTarget(target);
--- a/content/canvas/src/WebGLContextValidate.cpp
+++ b/content/canvas/src/WebGLContextValidate.cpp
@@ -35,17 +35,18 @@
  * 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 ***** */
 
 #include "WebGLContext.h"
 
 #include "mozilla/Preferences.h"
-#include "mozilla/CheckedInt.h"
+
+#include "CheckedInt.h"
 
 #include "jsfriendapi.h"
 
 #if defined(USE_ANGLE)
 #include "angle/ShaderLang.h"
 #endif
 
 #include <algorithm>
@@ -137,30 +138,30 @@ WebGLContext::ValidateBuffers(PRInt32 *m
             continue;
 
         // the base offset
         CheckedInt32 checked_byteLength
           = CheckedInt32(vd.buf->ByteLength()) - vd.byteOffset;
         CheckedInt32 checked_sizeOfLastElement
           = CheckedInt32(vd.componentSize()) * vd.size;
 
-        if (!checked_byteLength.isValid() ||
-            !checked_sizeOfLastElement.isValid())
+        if (!checked_byteLength.valid() ||
+            !checked_sizeOfLastElement.valid())
         {
           ErrorInvalidOperation("%s: integer overflow occured while checking vertex attrib %d", info, i);
           return false;
         }
 
         if (checked_byteLength.value() < checked_sizeOfLastElement.value()) {
           *maxAllowedCount = 0;
         } else {
           CheckedInt32 checked_maxAllowedCount
             = ((checked_byteLength - checked_sizeOfLastElement) / vd.actualStride()) + 1;
 
-          if (!checked_maxAllowedCount.isValid()) {
+          if (!checked_maxAllowedCount.valid()) {
             ErrorInvalidOperation("%s: integer overflow occured while checking vertex attrib %d", info, i);
             return false;
           }
 
           if (*maxAllowedCount == -1 || *maxAllowedCount > checked_maxAllowedCount.value())
               *maxAllowedCount = checked_maxAllowedCount.value();
         }
     }
@@ -395,37 +396,37 @@ bool WebGLContext::ValidateTexImage2DTar
     return true;
 }
 
 bool WebGLContext::ValidateCompressedTextureSize(WebGLint level, WebGLenum format, WebGLsizei width,
                                                  WebGLsizei height, uint32_t byteLength, const char* info)
 {
     CheckedUint32 calculated_byteLength = 0;
     CheckedUint32 checked_byteLength = byteLength;
-    if (!checked_byteLength.isValid()) {
+    if (!checked_byteLength.valid()) {
         ErrorInvalidValue("%s: data length out of bounds", info);
         return false;
     }
 
     switch (format) {
         case LOCAL_GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
         case LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
         {
             calculated_byteLength = ((CheckedUint32(width) + 3) / 4) * ((CheckedUint32(height) + 3) / 4) * 8;
-            if (!calculated_byteLength.isValid() || !(checked_byteLength == calculated_byteLength)) {
+            if (!calculated_byteLength.valid() || !(checked_byteLength == calculated_byteLength)) {
                 ErrorInvalidValue("%s: data size does not match dimensions", info);
                 return false;
             }
             break;
         }
         case LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
         case LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
         {
             calculated_byteLength = ((CheckedUint32(width) + 3) / 4) * ((CheckedUint32(height) + 3) / 4) * 16;
-            if (!calculated_byteLength.isValid() || !(checked_byteLength == calculated_byteLength)) {
+            if (!calculated_byteLength.valid() || !(checked_byteLength == calculated_byteLength)) {
                 ErrorInvalidValue("%s: data size does not match dimensions", info);
                 return false;
             }
             break;
         }
     }
 
     switch (format) {
--- a/content/canvas/src/nsCanvasRenderingContext2D.cpp
+++ b/content/canvas/src/nsCanvasRenderingContext2D.cpp
@@ -103,24 +103,24 @@
 #include "nsFrameLoader.h"
 #include "nsBidi.h"
 #include "nsBidiPresUtils.h"
 #include "Layers.h"
 #include "CanvasUtils.h"
 #include "nsIMemoryReporter.h"
 #include "nsStyleUtil.h"
 #include "CanvasImageCache.h"
+#include "CheckedInt.h"
 
 #include <algorithm>
 
 #include "jsapi.h"
 #include "jsfriendapi.h"
 
 #include "mozilla/Assertions.h"
-#include "mozilla/CheckedInt.h"
 #include "mozilla/dom/ContentParent.h"
 #include "mozilla/dom/ImageData.h"
 #include "mozilla/dom/PBrowserParent.h"
 #include "mozilla/ipc/DocumentRendererParent.h"
 #include "mozilla/ipc/PDocumentRendererParent.h"
 
 // windows.h (included by chromium code) defines this, in its infinite wisdom
 #undef DrawText
@@ -3921,24 +3921,24 @@ nsCanvasRenderingContext2D::GetImageData
                                               int32_t aY,
                                               uint32_t aWidth,
                                               uint32_t aHeight,
                                               JSObject** aRetval)
 {
     MOZ_ASSERT(aWidth && aHeight);
 
     CheckedInt<uint32_t> len = CheckedInt<uint32_t>(aWidth) * aHeight * 4;
-    if (!len.isValid()) {
+    if (!len.valid()) {
         return NS_ERROR_DOM_INDEX_SIZE_ERR;
     }
 
     CheckedInt<int32_t> rightMost = CheckedInt<int32_t>(aX) + aWidth;
     CheckedInt<int32_t> bottomMost = CheckedInt<int32_t>(aY) + aHeight;
 
-    if (!rightMost.isValid() || !bottomMost.isValid()) {
+    if (!rightMost.valid() || !bottomMost.valid()) {
         return NS_ERROR_DOM_SYNTAX_ERR;
     }
 
     JSObject* darray = JS_NewUint8ClampedArray(aCx, len.value());
     if (!darray) {
         return NS_ERROR_OUT_OF_MEMORY;
     }
 
@@ -4061,29 +4061,29 @@ nsCanvasRenderingContext2D::PutImageData
 
     if (hasDirtyRect) {
         // fix up negative dimensions
         if (dirtyWidth < 0) {
             NS_ENSURE_TRUE(dirtyWidth != INT_MIN, NS_ERROR_DOM_INDEX_SIZE_ERR);
 
             CheckedInt32 checkedDirtyX = CheckedInt32(dirtyX) + dirtyWidth;
 
-            if (!checkedDirtyX.isValid())
+            if (!checkedDirtyX.valid())
                 return NS_ERROR_DOM_INDEX_SIZE_ERR;
 
             dirtyX = checkedDirtyX.value();
             dirtyWidth = -(int32)dirtyWidth;
         }
 
         if (dirtyHeight < 0) {
             NS_ENSURE_TRUE(dirtyHeight != INT_MIN, NS_ERROR_DOM_INDEX_SIZE_ERR);
 
             CheckedInt32 checkedDirtyY = CheckedInt32(dirtyY) + dirtyHeight;
 
-            if (!checkedDirtyY.isValid())
+            if (!checkedDirtyY.valid())
                 return NS_ERROR_DOM_INDEX_SIZE_ERR;
 
             dirtyY = checkedDirtyY.value();
             dirtyHeight = -(int32)dirtyHeight;
         }
 
         // bound the dirty rect within the imageData rectangle
         dirtyRect = imageDataRect.Intersect(gfxRect(dirtyX, dirtyY, dirtyWidth, dirtyHeight));
--- a/content/canvas/src/nsCanvasRenderingContext2DAzure.cpp
+++ b/content/canvas/src/nsCanvasRenderingContext2DAzure.cpp
@@ -99,24 +99,24 @@
 #include "nsFrameLoader.h"
 #include "nsBidi.h"
 #include "nsBidiPresUtils.h"
 #include "Layers.h"
 #include "CanvasUtils.h"
 #include "nsIMemoryReporter.h"
 #include "nsStyleUtil.h"
 #include "CanvasImageCache.h"
+#include "CheckedInt.h"
 
 #include <algorithm>
 
 #include "jsapi.h"
 #include "jsfriendapi.h"
 
 #include "mozilla/Assertions.h"
-#include "mozilla/CheckedInt.h"
 #include "mozilla/dom/ContentParent.h"
 #include "mozilla/dom/ImageData.h"
 #include "mozilla/dom/PBrowserParent.h"
 #include "mozilla/gfx/2D.h"
 #include "mozilla/gfx/PathHelpers.h"
 #include "mozilla/ipc/DocumentRendererParent.h"
 #include "mozilla/ipc/PDocumentRendererParent.h"
 #include "mozilla/Preferences.h"
@@ -4090,24 +4090,24 @@ nsCanvasRenderingContext2DAzure::GetImag
                                                    int32_t aY,
                                                    uint32_t aWidth,
                                                    uint32_t aHeight,
                                                    JSObject** aRetval)
 {
   MOZ_ASSERT(aWidth && aHeight);
 
   CheckedInt<uint32_t> len = CheckedInt<uint32_t>(aWidth) * aHeight * 4;
-  if (!len.isValid()) {
+  if (!len.valid()) {
     return NS_ERROR_DOM_INDEX_SIZE_ERR;
   }
 
   CheckedInt<int32_t> rightMost = CheckedInt<int32_t>(aX) + aWidth;
   CheckedInt<int32_t> bottomMost = CheckedInt<int32_t>(aY) + aHeight;
 
-  if (!rightMost.isValid() || !bottomMost.isValid()) {
+  if (!rightMost.valid() || !bottomMost.valid()) {
     return NS_ERROR_DOM_SYNTAX_ERR;
   }
 
   JSObject* darray = JS_NewUint8ClampedArray(aCx, len.value());
   if (!darray) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
@@ -4228,29 +4228,29 @@ nsCanvasRenderingContext2DAzure::PutImag
 
   if (hasDirtyRect) {
     // fix up negative dimensions
     if (dirtyWidth < 0) {
       NS_ENSURE_TRUE(dirtyWidth != INT_MIN, NS_ERROR_DOM_INDEX_SIZE_ERR);
 
       CheckedInt32 checkedDirtyX = CheckedInt32(dirtyX) + dirtyWidth;
 
-      if (!checkedDirtyX.isValid())
+      if (!checkedDirtyX.valid())
           return NS_ERROR_DOM_INDEX_SIZE_ERR;
 
       dirtyX = checkedDirtyX.value();
       dirtyWidth = -(int32)dirtyWidth;
     }
 
     if (dirtyHeight < 0) {
       NS_ENSURE_TRUE(dirtyHeight != INT_MIN, NS_ERROR_DOM_INDEX_SIZE_ERR);
 
       CheckedInt32 checkedDirtyY = CheckedInt32(dirtyY) + dirtyHeight;
 
-      if (!checkedDirtyY.isValid())
+      if (!checkedDirtyY.valid())
           return NS_ERROR_DOM_INDEX_SIZE_ERR;
 
       dirtyY = checkedDirtyY.value();
       dirtyHeight = -(int32)dirtyHeight;
     }
 
     // bound the dirty rect within the imageData rectangle
     dirtyRect = imageDataRect.Intersect(IntRect(dirtyX, dirtyY, dirtyWidth, dirtyHeight));
--- a/content/html/content/src/nsHTMLCanvasElement.cpp
+++ b/content/html/content/src/nsHTMLCanvasElement.cpp
@@ -33,20 +33,20 @@
  * 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 ***** */
 
 #include "nsHTMLCanvasElement.h"
 
 #include "mozilla/Base64.h"
-#include "mozilla/CheckedInt.h"
 #include "nsNetUtil.h"
 #include "prmem.h"
 #include "nsDOMFile.h"
+#include "CheckedInt.h"
 
 #include "nsIScriptSecurityManager.h"
 #include "nsIXPConnect.h"
 #include "jsapi.h"
 #include "nsContentUtils.h"
 #include "nsJSUtils.h"
 #include "nsMathUtils.h"
 #include "nsStreamUtils.h"
--- a/content/media/VideoUtils.h
+++ b/content/media/VideoUtils.h
@@ -35,22 +35,23 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef VideoUtils_h
 #define VideoUtils_h
 
 #include "mozilla/ReentrantMonitor.h"
-#include "mozilla/CheckedInt.h"
 
 #include "nsRect.h"
 #include "nsIThreadManager.h"
 #include "nsThreadUtils.h"
 
+#include "CheckedInt.h"
+
 using mozilla::CheckedInt64;
 using mozilla::CheckedUint64;
 using mozilla::CheckedInt32;
 using mozilla::CheckedUint32;
 
 // This file contains stuff we'd rather put elsewhere, but which is
 // dependent on other changes which we don't want to wait for. We plan to
 // remove this file in the near future.
--- a/content/media/nsBuiltinDecoderReader.cpp
+++ b/content/media/nsBuiltinDecoderReader.cpp
@@ -159,18 +159,18 @@ VideoData* VideoData::Create(nsVideoInfo
     NS_WARNING("Invalid plane size");
     return nsnull;
   }
 
   // Ensure the picture size specified in the headers can be extracted out of
   // the frame we've been supplied without indexing out of bounds.
   CheckedUint32 xLimit = aPicture.x + CheckedUint32(aPicture.width);
   CheckedUint32 yLimit = aPicture.y + CheckedUint32(aPicture.height);
-  if (!xLimit.isValid() || xLimit.value() > aBuffer.mPlanes[0].mStride ||
-      !yLimit.isValid() || yLimit.value() > aBuffer.mPlanes[0].mHeight)
+  if (!xLimit.valid() || xLimit.value() > aBuffer.mPlanes[0].mStride ||
+      !yLimit.valid() || yLimit.value() > aBuffer.mPlanes[0].mHeight)
   {
     // The specified picture dimensions can't be contained inside the video
     // frame, we'll stomp memory if we try to copy it. Fail.
     NS_WARNING("Overflowing picture rect");
     return nsnull;
   }
 
   nsAutoPtr<VideoData> v(new VideoData(aOffset,
@@ -341,17 +341,17 @@ nsresult nsBuiltinDecoderReader::DecodeT
           }
         }
       }
       const AudioData* audio = mAudioQueue.PeekFront();
       if (!audio)
         break;
       CheckedInt64 startFrame = UsecsToFrames(audio->mTime, mInfo.mAudioRate);
       CheckedInt64 targetFrame = UsecsToFrames(aTarget, mInfo.mAudioRate);
-      if (!startFrame.isValid() || !targetFrame.isValid()) {
+      if (!startFrame.valid() || !targetFrame.valid()) {
         return NS_ERROR_FAILURE;
       }
       if (startFrame.value() + audio->mFrames <= targetFrame.value()) {
         // Our seek target lies after the frames in this AudioData. Pop it
         // off the queue, and keep decoding forwards.
         delete mAudioQueue.PopFront();
         audio = nsnull;
         continue;
@@ -385,17 +385,17 @@ nsresult nsBuiltinDecoderReader::DecodeT
       }
       PRUint32 frames = audio->mFrames - static_cast<PRUint32>(framesToPrune);
       PRUint32 channels = audio->mChannels;
       nsAutoArrayPtr<AudioDataValue> audioData(new AudioDataValue[frames * channels]);
       memcpy(audioData.get(),
              audio->mAudioData.get() + (framesToPrune * channels),
              frames * channels * sizeof(AudioDataValue));
       CheckedInt64 duration = FramesToUsecs(frames, mInfo.mAudioRate);
-      if (!duration.isValid()) {
+      if (!duration.valid()) {
         return NS_ERROR_FAILURE;
       }
       nsAutoPtr<AudioData> data(new AudioData(audio->mOffset,
                                               aTarget,
                                               duration.value(),
                                               frames,
                                               audioData.forget(),
                                               channels));
--- a/content/media/nsBuiltinDecoderStateMachine.cpp
+++ b/content/media/nsBuiltinDecoderStateMachine.cpp
@@ -542,17 +542,17 @@ void nsBuiltinDecoderStateMachine::SendO
   NS_ASSERTION(aOutput->GetChannels() == aAudio->mChannels,
                "Wrong number of channels");
 
   // This logic has to mimic AudioLoop closely to make sure we write
   // the exact same silences
   CheckedInt64 audioWrittenOffset = UsecsToFrames(mInfo.mAudioRate,
       aStream->mAudioFramesWrittenBaseTime + mStartTime) + aStream->mAudioFramesWritten;
   CheckedInt64 frameOffset = UsecsToFrames(mInfo.mAudioRate, aAudio->mTime);
-  if (!audioWrittenOffset.isValid() || !frameOffset.isValid())
+  if (!audioWrittenOffset.valid() || !frameOffset.valid())
     return;
   if (audioWrittenOffset.value() < frameOffset.value()) {
     // Write silence to catch up
     LOG(PR_LOG_DEBUG, ("%p Decoder writing %d frames of silence to MediaStream",
                        mDecoder.get(), PRInt32(frameOffset.value() - audioWrittenOffset.value())));
     AudioSegment silence;
     silence.InitFrom(*aOutput);
     silence.InsertNullDataAtStart(frameOffset.value() - audioWrittenOffset.value());
@@ -1110,17 +1110,17 @@ void nsBuiltinDecoderStateMachine::Audio
     // Calculate the number of frames that have been pushed onto the audio
     // hardware.
     CheckedInt64 playedFrames = UsecsToFrames(audioStartTime, rate) +
                                               audioDuration;
     // Calculate the timestamp of the next chunk of audio in numbers of
     // samples.
     CheckedInt64 sampleTime = UsecsToFrames(s->mTime, rate);
     CheckedInt64 missingFrames = sampleTime - playedFrames;
-    if (!missingFrames.isValid() || !sampleTime.isValid()) {
+    if (!missingFrames.valid() || !sampleTime.valid()) {
       NS_WARNING("Int overflow adding in AudioLoop()");
       break;
     }
 
     PRInt64 framesWritten = 0;
     if (missingFrames.value() > 0) {
       // The next audio chunk begins some time after the end of the last chunk
       // we pushed to the audio hardware. We must push silence into the audio
@@ -1134,17 +1134,17 @@ void nsBuiltinDecoderStateMachine::Audio
                                   channels, playedFrames.value());
     } else {
       framesWritten = PlayFromAudioQueue(sampleTime.value(), channels);
     }
     audioDuration += framesWritten;
     {
       ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
       CheckedInt64 playedUsecs = FramesToUsecs(audioDuration, rate) + audioStartTime;
-      if (!playedUsecs.isValid()) {
+      if (!playedUsecs.valid()) {
         NS_WARNING("Int overflow calculating audio end time");
         break;
       }
       mAudioEndTime = playedUsecs.value();
     }
   }
   {
     ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
--- a/content/media/ogg/nsOggCodecState.cpp
+++ b/content/media/ogg/nsOggCodecState.cpp
@@ -348,28 +348,28 @@ PRInt64 nsTheoraState::Time(th_info* aIn
   }
   // Implementation of th_granule_frame inlined here to operate
   // on the th_info structure instead of the theora_state.
   int shift = aInfo->keyframe_granule_shift; 
   ogg_int64_t iframe = aGranulepos >> shift;
   ogg_int64_t pframe = aGranulepos - (iframe << shift);
   PRInt64 frameno = iframe + pframe - TH_VERSION_CHECK(aInfo, 3, 2, 1);
   CheckedInt64 t = ((CheckedInt64(frameno) + 1) * USECS_PER_S) * aInfo->fps_denominator;
-  if (!t.isValid())
+  if (!t.valid())
     return -1;
   t /= aInfo->fps_numerator;
-  return t.isValid() ? t.value() : -1;
+  return t.valid() ? t.value() : -1;
 }
 
 PRInt64 nsTheoraState::StartTime(PRInt64 granulepos) {
   if (granulepos < 0 || !mActive || mInfo.fps_numerator == 0) {
     return -1;
   }
   CheckedInt64 t = (CheckedInt64(th_granule_frame(mCtx, granulepos)) * USECS_PER_S) * mInfo.fps_denominator;
-  if (!t.isValid())
+  if (!t.valid())
     return -1;
   return t.value() / mInfo.fps_numerator;
 }
 
 PRInt64
 nsTheoraState::MaxKeyframeOffset()
 {
   // Determine the maximum time in microseconds by which a key frame could
@@ -617,17 +617,17 @@ PRInt64 nsVorbisState::Time(PRInt64 gran
 }
 
 PRInt64 nsVorbisState::Time(vorbis_info* aInfo, PRInt64 aGranulepos)
 {
   if (aGranulepos == -1 || aInfo->rate == 0) {
     return -1;
   }
   CheckedInt64 t = CheckedInt64(aGranulepos) * USECS_PER_S;
-  if (!t.isValid())
+  if (!t.valid())
     t = 0;
   return t.value() / aInfo->rate;
 }
 
 bool
 nsVorbisState::IsHeader(ogg_packet* aPacket)
 {
   // The first byte in each Vorbis header packet is either 0x01, 0x03, or 0x05,
@@ -879,17 +879,17 @@ bool nsOpusState::DecodeHeader(ogg_packe
 /* Return the timestamp (in microseconds) equivalent to a granulepos. */
 PRInt64 nsOpusState::Time(PRInt64 granulepos)
 {
   if (!mActive || granulepos < 0)
     return -1;
 
   // Ogg Opus always runs at a granule rate of 48 kHz.
   CheckedInt64 t = CheckedInt64(granulepos - mPreSkip) * USECS_PER_S;
-  return t.isValid() ? t.value() / mRate : -1;
+  return t.valid() ? t.value() / mRate : -1;
 }
 
 bool nsOpusState::IsHeader(ogg_packet* aPacket)
 {
   return aPacket->bytes >= 16 &&
          (!memcmp(aPacket->packet, "OpusHead\0", 9) ||
           !memcmp(aPacket->packet, "OpusTags", 8));
 }
@@ -1043,34 +1043,34 @@ bool nsSkeletonState::DecodeIndex(ogg_pa
   if (timeDenom == 0) {
     LOG(PR_LOG_DEBUG, ("Ogg Skeleton Index packet for stream %u has 0 "
                        "timestamp denominator.", serialno));
     return (mActive = false);
   }
 
   // Extract the start time.
   CheckedInt64 t = CheckedInt64(LEInt64(p + INDEX_FIRST_NUMER_OFFSET)) * USECS_PER_S;
-  if (!t.isValid()) {
+  if (!t.valid()) {
     return (mActive = false);
   } else {
     startTime = t.value() / timeDenom;
   }
 
   // Extract the end time.
   t = LEInt64(p + INDEX_LAST_NUMER_OFFSET) * USECS_PER_S;
-  if (!t.isValid()) {
+  if (!t.valid()) {
     return (mActive = false);
   } else {
     endTime = t.value() / timeDenom;
   }
 
   // Check the numKeyPoints value read, ensure we're not going to run out of
   // memory while trying to decode the index packet.
   CheckedInt64 minPacketSize = (CheckedInt64(numKeyPoints) * MIN_KEY_POINT_SIZE) + INDEX_KEYPOINT_OFFSET;
-  if (!minPacketSize.isValid())
+  if (!minPacketSize.valid())
   {
     return (mActive = false);
   }
   
   PRInt64 sizeofIndex = aPacket->bytes - INDEX_KEYPOINT_OFFSET;
   PRInt64 maxNumKeyPoints = sizeofIndex / MIN_KEY_POINT_SIZE;
   if (aPacket->bytes < minPacketSize.value() ||
       numKeyPoints > maxNumKeyPoints || 
@@ -1098,32 +1098,32 @@ bool nsSkeletonState::DecodeIndex(ogg_pa
   CheckedInt64 time = 0;
   while (p < limit &&
          numKeyPointsRead < numKeyPoints)
   {
     PRInt64 delta = 0;
     p = ReadVariableLengthInt(p, limit, delta);
     offset += delta;
     if (p == limit ||
-        !offset.isValid() ||
+        !offset.valid() ||
         offset.value() > mLength ||
         offset.value() < 0)
     {
       return (mActive = false);
     }
     p = ReadVariableLengthInt(p, limit, delta);
     time += delta;
-    if (!time.isValid() ||
+    if (!time.valid() ||
         time.value() > endTime ||
         time.value() < startTime)
     {
       return (mActive = false);
     }
     CheckedInt64 timeUsecs = time * USECS_PER_S;
-    if (!timeUsecs.isValid())
+    if (!timeUsecs.valid())
       return mActive = false;
     timeUsecs /= timeDenom;
     keyPoints->Add(offset.value(), timeUsecs.value());
     numKeyPointsRead++;
   }
 
   PRInt32 keyPointsRead = keyPoints->Length();
   if (keyPointsRead > 0) {
@@ -1223,18 +1223,18 @@ nsresult nsSkeletonState::GetDuration(co
       endTime = index->mEndTime;
     }
     if (index->mStartTime < startTime) {
       startTime = index->mStartTime;
     }
   }
   NS_ASSERTION(endTime > startTime, "Duration must be positive");
   CheckedInt64 duration = CheckedInt64(endTime) - startTime;
-  aDuration = duration.isValid() ? duration.value() : 0;
-  return duration.isValid() ? NS_OK : NS_ERROR_FAILURE;
+  aDuration = duration.valid() ? duration.value() : 0;
+  return duration.valid() ? NS_OK : NS_ERROR_FAILURE;
 }
 
 bool nsSkeletonState::DecodeHeader(ogg_packet* aPacket)
 {
   if (IsSkeletonBOS(aPacket)) {
     PRUint16 verMajor = LEUint16(aPacket->packet + SKELETON_VERSION_MAJOR_OFFSET);
     PRUint16 verMinor = LEUint16(aPacket->packet + SKELETON_VERSION_MINOR_OFFSET);
 
--- a/content/media/raw/nsRawReader.cpp
+++ b/content/media/raw/nsRawReader.cpp
@@ -82,17 +82,17 @@ nsresult nsRawReader::ReadMetadata(nsVid
   if (!(mMetadata.headerPacketID == 0 /* Packet ID of 0 for the header*/ &&
         mMetadata.codecID == RAW_ID /* "YUV" */ &&
         mMetadata.majorVersion == 0 &&
         mMetadata.minorVersion == 1))
     return NS_ERROR_FAILURE;
 
   CheckedUint32 dummy = CheckedUint32(static_cast<PRUint32>(mMetadata.frameWidth)) *
                           static_cast<PRUint32>(mMetadata.frameHeight);
-  NS_ENSURE_TRUE(dummy.isValid(), NS_ERROR_FAILURE);
+  NS_ENSURE_TRUE(dummy.valid(), NS_ERROR_FAILURE);
 
   if (mMetadata.aspectDenominator == 0 ||
       mMetadata.framerateDenominator == 0)
     return NS_ERROR_FAILURE; // Invalid data
 
   // Determine and verify frame display size.
   float pixelAspectRatio = static_cast<float>(mMetadata.aspectNumerator) / 
                             mMetadata.aspectDenominator;
@@ -263,17 +263,17 @@ nsresult nsRawReader::Seek(PRInt64 aTime
 
   PRUint32 frame = mCurrentFrame;
   if (aTime >= UINT_MAX)
     return NS_ERROR_FAILURE;
   mCurrentFrame = aTime * mFrameRate / USECS_PER_S;
 
   CheckedUint32 offset = CheckedUint32(mCurrentFrame) * mFrameSize;
   offset += sizeof(nsRawVideoHeader);
-  NS_ENSURE_TRUE(offset.isValid(), NS_ERROR_FAILURE);
+  NS_ENSURE_TRUE(offset.valid(), NS_ERROR_FAILURE);
 
   nsresult rv = resource->Seek(nsISeekableStream::NS_SEEK_SET, offset.value());
   NS_ENSURE_SUCCESS(rv, rv);
 
   mVideoQueue.Erase();
 
   while(mVideoQueue.GetSize() == 0) {
     bool keyframeSkip = false;
--- a/content/media/webm/nsWebMReader.cpp
+++ b/content/media/webm/nsWebMReader.cpp
@@ -443,30 +443,30 @@ bool nsWebMReader::DecodeAudioPacket(nes
     mAudioStartUsec = tstamp_usecs;
   }
   // If there's a gap between the start of this audio chunk and the end of
   // the previous audio chunk, we need to increment the packet count so that
   // the vorbis decode doesn't use data from before the gap to help decode
   // from after the gap.
   CheckedInt64 tstamp_frames = UsecsToFrames(tstamp_usecs, rate);
   CheckedInt64 decoded_frames = UsecsToFrames(mAudioStartUsec, rate);
-  if (!tstamp_frames.isValid() || !decoded_frames.isValid()) {
+  if (!tstamp_frames.valid() || !decoded_frames.valid()) {
     NS_WARNING("Int overflow converting WebM times to frames");
     return false;
   }
   decoded_frames += mAudioFrames;
-  if (!decoded_frames.isValid()) {
+  if (!decoded_frames.valid()) {
     NS_WARNING("Int overflow adding decoded_frames");
     return false;
   }
   if (tstamp_frames.value() > decoded_frames.value()) {
 #ifdef DEBUG
     CheckedInt64 usecs = FramesToUsecs(tstamp_frames.value() - decoded_frames.value(), rate);
     LOG(PR_LOG_DEBUG, ("WebMReader detected gap of %lld, %lld frames, in audio stream\n",
-      usecs.isValid() ? usecs.value() : -1,
+      usecs.valid() ? usecs.value(): -1,
       tstamp_frames.value() - decoded_frames.value()));
 #endif
     mPacketCount++;
     mAudioStartUsec = tstamp_usecs;
     mAudioFrames = 0;
   }
 
   PRInt32 total_frames = 0;
@@ -496,28 +496,28 @@ bool nsWebMReader::DecodeAudioPacket(nes
       for (PRUint32 j = 0; j < mChannels; ++j) {
         VorbisPCMValue* channel = pcm[j];
         for (PRUint32 i = 0; i < PRUint32(frames); ++i) {
           buffer[i*mChannels + j] = MOZ_CONVERT_VORBIS_SAMPLE(channel[i]);
         }
       }
 
       CheckedInt64 duration = FramesToUsecs(frames, rate);
-      if (!duration.isValid()) {
+      if (!duration.valid()) {
         NS_WARNING("Int overflow converting WebM audio duration");
         return false;
       }
       CheckedInt64 total_duration = FramesToUsecs(total_frames, rate);
-      if (!total_duration.isValid()) {
+      if (!total_duration.valid()) {
         NS_WARNING("Int overflow converting WebM audio total_duration");
         return false;
       }
       
       CheckedInt64 time = total_duration + tstamp_usecs;
-      if (!time.isValid()) {
+      if (!time.valid()) {
         NS_WARNING("Int overflow adding total_duration and tstamp_usecs");
         nestegg_free_packet(aPacket);
         return false;
       };
 
       total_frames += frames;
       mAudioQueue.Push(new AudioData(aOffset,
                                      time.value(),
--- a/gfx/2d/Blur.cpp
+++ b/gfx/2d/Blur.cpp
@@ -34,17 +34,17 @@
  * ***** END LICENSE BLOCK ***** */
 
 #include "mozilla/gfx/Blur.h"
 
 #include <algorithm>
 #include <math.h>
 #include <string.h>
 
-#include "mozilla/CheckedInt.h"
+#include "CheckedInt.h"
 #include "mozilla/Util.h"
 
 #ifndef M_PI
 #define M_PI 3.14159265358979323846
 #endif
 
 using namespace std;
 
@@ -76,17 +76,17 @@ BoxBlurHorizontal(unsigned char* aInput,
 
     int32_t boxSize = aLeftLobe + aRightLobe + 1;
     bool skipRectCoversWholeRow = 0 >= aSkipRect.x &&
                                   aWidth <= aSkipRect.XMost();
     if (boxSize == 1) {
         memcpy(aOutput, aInput, aWidth*aRows);
         return;
     }
-    uint32_t reciprocal = (uint64_t(1) << 32) / boxSize;
+    PRUint32 reciprocal = (PRUint64(1) << 32)/boxSize;
 
     for (int32_t y = 0; y < aRows; y++) {
         // Check whether the skip rect intersects this row. If the skip
         // rect covers the whole surface in this row, we can avoid
         // this row entirely (and any others along the skip rect).
         bool inSkipRectY = y >= aSkipRect.y &&
                            y < aSkipRect.YMost();
         if (inSkipRectY && skipRectCoversWholeRow) {
@@ -123,17 +123,17 @@ BoxBlurHorizontal(unsigned char* aInput,
                     pos = min(pos, aWidth - 1);
                     alphaSum += aInput[aWidth * y + pos];
                 }
             }
             int32_t tmp = x - aLeftLobe;
             int32_t last = max(tmp, 0);
             int32_t next = min(tmp + boxSize, aWidth - 1);
 
-            aOutput[aWidth * y + x] = (uint64_t(alphaSum) * reciprocal) >> 32;
+            aOutput[aWidth * y + x] = (PRUint64(alphaSum)*reciprocal) >> 32;
 
             alphaSum += aInput[aWidth * y + next] -
                         aInput[aWidth * y + last];
         }
     }
 }
 
 /**
@@ -154,17 +154,17 @@ BoxBlurVertical(unsigned char* aInput,
 
     int32_t boxSize = aTopLobe + aBottomLobe + 1;
     bool skipRectCoversWholeColumn = 0 >= aSkipRect.y &&
                                      aRows <= aSkipRect.YMost();
     if (boxSize == 1) {
         memcpy(aOutput, aInput, aWidth*aRows);
         return;
     }
-    uint32_t reciprocal = (uint64_t(1) << 32) / boxSize;
+    PRUint32 reciprocal = (PRUint64(1) << 32)/boxSize;
 
     for (int32_t x = 0; x < aWidth; x++) {
         bool inSkipRectX = x >= aSkipRect.x &&
                            x < aSkipRect.XMost();
         if (inSkipRectX && skipRectCoversWholeColumn) {
             x = aSkipRect.XMost() - 1;
             continue;
         }
@@ -194,17 +194,17 @@ BoxBlurVertical(unsigned char* aInput,
                     pos = min(pos, aRows - 1);
                     alphaSum += aInput[aWidth * pos + x];
                 }
             }
             int32_t tmp = y - aTopLobe;
             int32_t last = max(tmp, 0);
             int32_t next = min(tmp + boxSize, aRows - 1);
 
-            aOutput[aWidth * y + x] = (uint64_t(alphaSum) * reciprocal) >> 32;
+            aOutput[aWidth * y + x] = (PRUint64(alphaSum)*reciprocal) >> 32;
 
             alphaSum += aInput[aWidth * next + x] -
                         aInput[aWidth * last + x];
         }
     }
 }
 
 static void ComputeLobes(int32_t aRadius, int32_t aLobes[3][2])
@@ -404,22 +404,22 @@ AlphaBoxBlur::AlphaBoxBlur(const Rect& a
     mSkipRect -= shadowIntRect.TopLeft();
   } else {
     mSkipRect = IntRect(0, 0, 0, 0);
   }
 
   mRect = IntRect(rect.x, rect.y, rect.width, rect.height);
 
   CheckedInt<int32_t> stride = RoundUpToMultipleOf4(mRect.width);
-  if (stride.isValid()) {
+  if (stride.valid()) {
     mStride = stride.value();
 
     CheckedInt<int32_t> size = CheckedInt<int32_t>(mStride) * mRect.height *
                                sizeof(unsigned char);
-    if (size.isValid()) {
+    if (size.valid()) {
       mData = static_cast<unsigned char*>(malloc(size.value()));
       memset(mData, 0, size.value());
     }
   }
 }
 
 AlphaBoxBlur::~AlphaBoxBlur()
 {
--- a/gfx/thebes/gfxASurface.cpp
+++ b/gfx/thebes/gfxASurface.cpp
@@ -33,17 +33,17 @@
  * 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 ***** */
 
 #include "nsIMemoryReporter.h"
 #include "nsMemory.h"
-#include "mozilla/CheckedInt.h"
+#include "CheckedInt.h"
 
 #include "gfxASurface.h"
 #include "gfxContext.h"
 #include "gfxImageSurface.h"
 
 #include "nsRect.h"
 
 #include "cairo.h"
@@ -373,25 +373,25 @@ gfxASurface::CheckSurfaceSize(const gfxI
         NS_WARNING("Surface size too large (exceeds CoreGraphics limit)!");
         return false;
     }
 #endif
 
     // make sure the surface area doesn't overflow a PRInt32
     CheckedInt<PRInt32> tmp = sz.width;
     tmp *= sz.height;
-    if (!tmp.isValid()) {
+    if (!tmp.valid()) {
         NS_WARNING("Surface size too large (would overflow)!");
         return false;
     }
 
     // assuming 4-byte stride, make sure the allocation size
     // doesn't overflow a PRInt32 either
     tmp *= 4;
-    if (!tmp.isValid()) {
+    if (!tmp.valid()) {
         NS_WARNING("Allocation too large (would overflow)!");
         return false;
     }
 
     return true;
 }
 
 /* static */
deleted file mode 100644
--- a/mfbt/CheckedInt.h
+++ /dev/null
@@ -1,789 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/* Provides checked integers, detecting integer overflow and divide-by-0. */
-
-#ifndef mozilla_CheckedInt_h_
-#define mozilla_CheckedInt_h_
-
-/*
- * Build options. Comment out these #defines to disable the corresponding
- * optional feature. Disabling features may be useful for code using
- * CheckedInt outside of Mozilla (e.g. WebKit)
- */
-
-// Enable usage of MOZ_STATIC_ASSERT to check for unsupported types.
-// If disabled, static asserts are replaced by regular assert().
-#define MOZ_CHECKEDINT_ENABLE_MOZ_ASSERTS
-
-/*
- * End of build options
- */
-
-
-#ifdef MOZ_CHECKEDINT_ENABLE_MOZ_ASSERTS
-#  include "mozilla/Assertions.h"
-#else
-#  ifndef MOZ_STATIC_ASSERT
-#    include <cassert>
-#    define MOZ_STATIC_ASSERT(cond, reason) assert((cond) && reason)
-#    define MOZ_ASSERT(cond, reason) assert((cond) && reason)
-#  endif
-#endif
-
-#include "mozilla/StandardInteger.h"
-
-#include <climits>
-#include <cstddef>
-
-namespace mozilla {
-
-namespace detail {
-
-/*
- * Step 1: manually record supported types
- *
- * What's nontrivial here is that there are different families of integer
- * types: basic integer types and stdint types. It is merrily undefined which
- * types from one family may be just typedefs for a type from another family.
- *
- * For example, on GCC 4.6, aside from the basic integer types, the only other
- * type that isn't just a typedef for some of them, is int8_t.
- */
-
-struct UnsupportedType {};
-
-template<typename IntegerType>
-struct IsSupportedPass2
-{
-    static const bool value = false;
-};
-
-template<typename IntegerType>
-struct IsSupported
-{
-    static const bool value = IsSupportedPass2<IntegerType>::value;
-};
-
-template<>
-struct IsSupported<int8_t>
-{ static const bool value = true; };
-
-template<>
-struct IsSupported<uint8_t>
-{ static const bool value = true; };
-
-template<>
-struct IsSupported<int16_t>
-{ static const bool value = true; };
-
-template<>
-struct IsSupported<uint16_t>
-{ static const bool value = true; };
-
-template<>
-struct IsSupported<int32_t>
-{ static const bool value = true; };
-
-template<>
-struct IsSupported<uint32_t>
-{ static const bool value = true; };
-
-template<>
-struct IsSupported<int64_t>
-{ static const bool value = true; };
-
-template<>
-struct IsSupported<uint64_t>
-{ static const bool value = true; };
-
-
-template<>
-struct IsSupportedPass2<char>
-{ static const bool value = true; };
-
-template<>
-struct IsSupportedPass2<unsigned char>
-{ static const bool value = true; };
-
-template<>
-struct IsSupportedPass2<short>
-{ static const bool value = true; };
-
-template<>
-struct IsSupportedPass2<unsigned short>
-{ static const bool value = true; };
-
-template<>
-struct IsSupportedPass2<int>
-{ static const bool value = true; };
-
-template<>
-struct IsSupportedPass2<unsigned int>
-{ static const bool value = true; };
-
-template<>
-struct IsSupportedPass2<long>
-{ static const bool value = true; };
-
-template<>
-struct IsSupportedPass2<unsigned long>
-{ static const bool value = true; };
-
-
-/*
- * Step 2: some integer-traits kind of stuff.
- */
-
-template<size_t Size, bool Signedness>
-struct StdintTypeForSizeAndSignedness
-{};
-
-template<>
-struct StdintTypeForSizeAndSignedness<1, true>
-{ typedef int8_t   Type; };
-
-template<>
-struct StdintTypeForSizeAndSignedness<1, false>
-{ typedef uint8_t  Type; };
-
-template<>
-struct StdintTypeForSizeAndSignedness<2, true>
-{ typedef int16_t  Type; };
-
-template<>
-struct StdintTypeForSizeAndSignedness<2, false>
-{ typedef uint16_t Type; };
-
-template<>
-struct StdintTypeForSizeAndSignedness<4, true>
-{ typedef int32_t  Type; };
-
-template<>
-struct StdintTypeForSizeAndSignedness<4, false>
-{ typedef uint32_t Type; };
-
-template<>
-struct StdintTypeForSizeAndSignedness<8, true>
-{ typedef int64_t  Type; };
-
-template<>
-struct StdintTypeForSizeAndSignedness<8, false>
-{ typedef uint64_t Type; };
-
-template<typename IntegerType>
-struct UnsignedType
-{
-    typedef typename StdintTypeForSizeAndSignedness<sizeof(IntegerType),
-                                                    false>::Type Type;
-};
-
-template<typename IntegerType>
-struct IsSigned
-{
-    static const bool value = IntegerType(-1) <= IntegerType(0);
-};
-
-template<typename IntegerType, size_t Size = sizeof(IntegerType)>
-struct TwiceBiggerType
-{
-    typedef typename StdintTypeForSizeAndSignedness<
-                       sizeof(IntegerType) * 2,
-                       IsSigned<IntegerType>::value
-                     >::Type Type;
-};
-
-template<typename IntegerType>
-struct TwiceBiggerType<IntegerType, 8>
-{
-    typedef UnsupportedType Type;
-};
-
-template<typename IntegerType>
-struct PositionOfSignBit
-{
-    static const size_t value = CHAR_BIT * sizeof(IntegerType) - 1;
-};
-
-template<typename IntegerType>
-struct MinValue
-{
-    static IntegerType value()
-    {
-      // Bitwise ops may return a larger type, that's why we cast explicitly.
-      // In C++, left bit shifts on signed values is undefined by the standard
-      // unless the shifted value is representable.
-      // Notice that signed-to-unsigned conversions are always well-defined in
-      // the standard as the value congruent to 2**n, as expected. By contrast,
-      // unsigned-to-signed is only well-defined if the value is representable.
-      return IsSigned<IntegerType>::value
-             ? IntegerType(typename UnsignedType<IntegerType>::Type(1)
-                             << PositionOfSignBit<IntegerType>::value)
-             : IntegerType(0);
-    }
-};
-
-template<typename IntegerType>
-struct MaxValue
-{
-    static IntegerType value()
-    {
-      // Tricksy, but covered by the unit test.
-      // Relies heavily on the return type of MinValue<IntegerType>::value()
-      // being IntegerType.
-      return ~MinValue<IntegerType>::value();
-    }
-};
-
-/*
- * Step 3: Implement the actual validity checks.
- *
- * Ideas taken from IntegerLib, code different.
- */
-
-// Bitwise ops may return a larger type, so it's good to use these inline
-// helpers guaranteeing that the result is really of type T.
-
-template<typename T>
-inline T
-HasSignBit(T x)
-{
-  // In C++, right bit shifts on negative values is undefined by the standard.
-  // Notice that signed-to-unsigned conversions are always well-defined in the
-  // standard, as the value congruent modulo 2**n as expected. By contrast,
-  // unsigned-to-signed is only well-defined if the value is representable.
-  // Here the unsigned-to-signed conversion is OK because the value
-  // (the result of the shift) is 0 or 1.
-  return T(typename UnsignedType<T>::Type(x)
-              >> PositionOfSignBit<T>::value);
-}
-
-template<typename T>
-inline T
-BinaryComplement(T x)
-{
-  return ~x;
-}
-
-template<typename T,
-         typename U,
-         bool IsTSigned = IsSigned<T>::value,
-         bool IsUSigned = IsSigned<U>::value>
-struct IsInRangeImpl {};
-
-template<typename T, typename U>
-struct IsInRangeImpl<T, U, true, true>
-{
-    static bool run(U x)
-    {
-      return x <= MaxValue<T>::value() &&
-             x >= MinValue<T>::value();
-    }
-};
-
-template<typename T, typename U>
-struct IsInRangeImpl<T, U, false, false>
-{
-    static bool run(U x)
-    {
-      return x <= MaxValue<T>::value();
-    }
-};
-
-template<typename T, typename U>
-struct IsInRangeImpl<T, U, true, false>
-{
-    static bool run(U x)
-    {
-      return sizeof(T) > sizeof(U)
-             ? true
-             : x <= U(MaxValue<T>::value());
-    }
-};
-
-template<typename T, typename U>
-struct IsInRangeImpl<T, U, false, true>
-{
-    static bool run(U x)
-    {
-      return sizeof(T) >= sizeof(U)
-             ? x >= 0
-             : x >= 0 && x <= U(MaxValue<T>::value());
-    }
-};
-
-template<typename T, typename U>
-inline bool
-IsInRange(U x)
-{
-  return IsInRangeImpl<T, U>::run(x);
-}
-
-template<typename T>
-inline bool
-IsAddValid(T x, T y, T result)
-{
-  // Addition is valid if the sign of x+y is equal to either that of x or that
-  // of y. Beware! These bitwise operations can return a larger integer type,
-  // if T was a small type like int8_t, so we explicitly cast to T.
-  return IsSigned<T>::value
-         ? HasSignBit(BinaryComplement(T((result ^ x) & (result ^ y))))
-         : BinaryComplement(x) >= y;
-}
-
-template<typename T>
-inline bool
-IsSubValid(T x, T y, T result)
-{
-  // Subtraction is valid if either x and y have same sign, or x-y and x have
-  // same sign.
-  return IsSigned<T>::value
-         ? HasSignBit(BinaryComplement(T((result ^ x) & (x ^ y))))
-         : x >= y;
-}
-
-template<typename T,
-         bool IsSigned = IsSigned<T>::value,
-         bool TwiceBiggerTypeIsSupported =
-           IsSupported<typename TwiceBiggerType<T>::Type>::value>
-struct IsMulValidImpl {};
-
-template<typename T, bool IsSigned>
-struct IsMulValidImpl<T, IsSigned, true>
-{
-    static bool run(T x, T y)
-    {
-      typedef typename TwiceBiggerType<T>::Type TwiceBiggerType;
-      TwiceBiggerType product = TwiceBiggerType(x) * TwiceBiggerType(y);
-      return IsInRange<T>(product);
-    }
-};
-
-template<typename T>
-struct IsMulValidImpl<T, true, false>
-{
-    static bool run(T x, T y)
-    {
-      const T max = MaxValue<T>::value();
-      const T min = MinValue<T>::value();
-
-      if (x == 0 || y == 0)
-        return true;
-
-      if (x > 0) {
-        return y > 0
-               ? x <= max / y
-               : y >= min / x;
-      }
-
-      // If we reach this point, we know that x < 0.
-      return y > 0
-             ? x >= min / y
-             : y >= max / x;
-    }
-};
-
-template<typename T>
-struct IsMulValidImpl<T, false, false>
-{
-    static bool run(T x, T y)
-    {
-      return y == 0 ||
-             x <= MaxValue<T>::value() / y;
-    }
-};
-
-template<typename T>
-inline bool
-IsMulValid(T x, T y, T /* result not used */)
-{
-  return IsMulValidImpl<T>::run(x, y);
-}
-
-template<typename T>
-inline bool
-IsDivValid(T x, T y)
-{
-  // Keep in mind that in the signed case, min/-1 is invalid because abs(min)>max.
-  return IsSigned<T>::value
-         ? (y != 0) && (x != MinValue<T>::value() || y != T(-1))
-         : y != 0;
-}
-
-// This is just to shut up msvc warnings about negating unsigned ints.
-template<typename T, bool IsSigned = IsSigned<T>::value>
-struct OppositeIfSignedImpl
-{
-    static T run(T x) { return -x; }
-};
-template<typename T>
-struct OppositeIfSignedImpl<T, false>
-{
-    static T run(T x) { return x; }
-};
-template<typename T>
-inline T
-OppositeIfSigned(T x)
-{
-  return OppositeIfSignedImpl<T>::run(x);
-}
-
-} // namespace detail
-
-
-/*
- * Step 4: Now define the CheckedInt class.
- */
-
-/**
- * @class CheckedInt
- * @brief Integer wrapper class checking for integer overflow and other errors
- * @param T the integer type to wrap. Can be any type among the following:
- *            - any basic integer type such as |int|
- *            - any stdint type such as |int8_t|
- *
- * This class implements guarded integer arithmetic. Do a computation, check
- * that isValid() returns true, you then have a guarantee that no problem, such
- * as integer overflow, happened during this computation, and you can call
- * value() to get the plain integer value.
- *
- * The arithmetic operators in this class are guaranteed not to raise a signal
- * (e.g. in case of a division by zero).
- *
- * For example, suppose that you want to implement a function that computes
- * (x+y)/z, that doesn't crash if z==0, and that reports on error (divide by
- * zero or integer overflow). You could code it as follows:
-   @code
-   bool computeXPlusYOverZ(int x, int y, int z, int *result)
-   {
-       CheckedInt<int> checkedResult = (CheckedInt<int>(x) + y) / z;
-       if (checkedResult.isValid()) {
-           *result = checkedResult.value();
-           return true;
-       } else {
-           return false;
-       }
-   }
-   @endcode
- *
- * Implicit conversion from plain integers to checked integers is allowed. The
- * plain integer is checked to be in range before being casted to the
- * destination type. This means that the following lines all compile, and the
- * resulting CheckedInts are correctly detected as valid or invalid:
- * @code
-   // 1 is of type int, is found to be in range for uint8_t, x is valid
-   CheckedInt<uint8_t> x(1);
-   // -1 is of type int, is found not to be in range for uint8_t, x is invalid
-   CheckedInt<uint8_t> x(-1);
-   // -1 is of type int, is found to be in range for int8_t, x is valid
-   CheckedInt<int8_t> x(-1);
-   // 1000 is of type int16_t, is found not to be in range for int8_t,
-   // x is invalid
-   CheckedInt<int8_t> x(int16_t(1000)); 
-   // 3123456789 is of type uint32_t, is found not to be in range for int32_t,
-   // x is invalid
-   CheckedInt<int32_t> x(uint32_t(3123456789));
- * @endcode
- * Implicit conversion from
- * checked integers to plain integers is not allowed. As shown in the
- * above example, to get the value of a checked integer as a normal integer,
- * call value().
- *
- * Arithmetic operations between checked and plain integers is allowed; the
- * result type is the type of the checked integer.
- *
- * Checked integers of different types cannot be used in the same arithmetic
- * expression.
- *
- * There are convenience typedefs for all stdint types, of the following form
- * (these are just 2 examples):
-   @code
-   typedef CheckedInt<int32_t> CheckedInt32;
-   typedef CheckedInt<uint16_t> CheckedUint16;
-   @endcode
- */
-template<typename T>
-class CheckedInt
-{
-  protected:
-    T mValue;
-    bool mIsValid;
-
-    template<typename U>
-    CheckedInt(U value, bool isValid) : mValue(value), mIsValid(isValid)
-    {
-      MOZ_STATIC_ASSERT(detail::IsSupported<T>::value,
-                        "This type is not supported by CheckedInt");
-    }
-
-  public:
-    /**
-     * Constructs a checked integer with given @a value. The checked integer is
-     * initialized as valid or invalid depending on whether the @a value
-     * is in range.
-     *
-     * This constructor is not explicit. Instead, the type of its argument is a
-     * separate template parameter, ensuring that no conversion is performed
-     * before this constructor is actually called. As explained in the above
-     * documentation for class CheckedInt, this constructor checks that its
-     * argument is valid.
-     */
-    template<typename U>
-    CheckedInt(U value)
-      : mValue(T(value)),
-        mIsValid(detail::IsInRange<T>(value))
-    {
-      MOZ_STATIC_ASSERT(detail::IsSupported<T>::value,
-                        "This type is not supported by CheckedInt");
-    }
-
-    /** Constructs a valid checked integer with initial value 0 */
-    CheckedInt() : mValue(0), mIsValid(true)
-    {
-      MOZ_STATIC_ASSERT(detail::IsSupported<T>::value,
-                        "This type is not supported by CheckedInt");
-    }
-
-    /** @returns the actual value */
-    T value() const
-    {
-      MOZ_ASSERT(mIsValid, "Invalid checked integer (division by zero or integer overflow)");
-      return mValue;
-    }
-
-    /**
-     * @returns true if the checked integer is valid, i.e. is not the result
-     * of an invalid operation or of an operation involving an invalid checked
-     * integer
-     */
-    bool isValid() const
-    {
-      return mIsValid;
-    }
-
-    template<typename U>
-    friend CheckedInt<U> operator +(const CheckedInt<U>& lhs,
-                                    const CheckedInt<U>& rhs);
-    template<typename U>
-    CheckedInt& operator +=(U rhs);
-    template<typename U>
-    friend CheckedInt<U> operator -(const CheckedInt<U>& lhs,
-                                    const CheckedInt<U> &rhs);
-    template<typename U>
-    CheckedInt& operator -=(U rhs);
-    template<typename U>
-    friend CheckedInt<U> operator *(const CheckedInt<U>& lhs,
-                                    const CheckedInt<U> &rhs);
-    template<typename U>
-    CheckedInt& operator *=(U rhs);
-    template<typename U>
-    friend CheckedInt<U> operator /(const CheckedInt<U>& lhs,
-                                    const CheckedInt<U> &rhs);
-    template<typename U>
-    CheckedInt& operator /=(U rhs);
-
-    CheckedInt operator -() const
-    {
-      // Circumvent msvc warning about - applied to unsigned int.
-      // if we're unsigned, the only valid case anyway is 0
-      // in which case - is a no-op.
-      T result = detail::OppositeIfSigned(mValue);
-      /* Help the compiler perform RVO (return value optimization). */
-      return CheckedInt(result,
-                        mIsValid && detail::IsSubValid(T(0),
-                                                       mValue,
-                                                       result));
-    }
-
-    /**
-     * @returns true if the left and right hand sides are valid
-     * and have the same value.
-     *
-     * Note that these semantics are the reason why we don't offer
-     * a operator!=. Indeed, we'd want to have a!=b be equivalent to !(a==b)
-     * but that would mean that whenever a or b is invalid, a!=b
-     * is always true, which would be very confusing.
-     *
-     * For similar reasons, operators <, >, <=, >= would be very tricky to
-     * specify, so we just avoid offering them.
-     *
-     * Notice that these == semantics are made more reasonable by these facts:
-     *  1. a==b implies equality at the raw data level
-     *     (the converse is false, as a==b is never true among invalids)
-     *  2. This is similar to the behavior of IEEE floats, where a==b
-     *     means that a and b have the same value *and* neither is NaN.
-     */
-    bool operator ==(const CheckedInt& other) const
-    {
-      return mIsValid && other.mIsValid && mValue == other.mValue;
-    }
-
-    /** prefix ++ */
-    CheckedInt& operator++()
-    {
-      *this += 1;
-      return *this;
-    }
-
-    /** postfix ++ */
-    CheckedInt operator++(int)
-    {
-      CheckedInt tmp = *this;
-      *this += 1;
-      return tmp;
-    }
-
-    /** prefix -- */
-    CheckedInt& operator--()
-    {
-      *this -= 1;
-      return *this;
-    }
-
-    /** postfix -- */
-    CheckedInt operator--(int)
-    {
-      CheckedInt tmp = *this;
-      *this -= 1;
-      return tmp;
-    }
-
-  private:
-    /**
-     * The !=, <, <=, >, >= operators are disabled:
-     * see the comment on operator==.
-     */
-    template<typename U>
-    bool operator !=(U other) const MOZ_DELETE;
-    template<typename U>
-    bool operator <(U other) const MOZ_DELETE;
-    template<typename U>
-    bool operator <=(U other) const MOZ_DELETE;
-    template<typename U>
-    bool operator >(U other) const MOZ_DELETE;
-    template<typename U>
-    bool operator >=(U other) const MOZ_DELETE;
-};
-
-#define MOZ_CHECKEDINT_BASIC_BINARY_OPERATOR(NAME, OP)                \
-template<typename T>                                                  \
-inline CheckedInt<T> operator OP(const CheckedInt<T> &lhs,            \
-                                 const CheckedInt<T> &rhs)            \
-{                                                                     \
-  T x = lhs.mValue;                                                   \
-  T y = rhs.mValue;                                                   \
-  T result = x OP y;                                                  \
-  T isOpValid                                                         \
-      = detail::Is##NAME##Valid(x, y, result);                        \
-  /* Help the compiler perform RVO (return value optimization). */    \
-  return CheckedInt<T>(result,                                        \
-                       lhs.mIsValid && rhs.mIsValid && isOpValid);    \
-}
-
-MOZ_CHECKEDINT_BASIC_BINARY_OPERATOR(Add, +)
-MOZ_CHECKEDINT_BASIC_BINARY_OPERATOR(Sub, -)
-MOZ_CHECKEDINT_BASIC_BINARY_OPERATOR(Mul, *)
-
-#undef MOZ_CHECKEDINT_BASIC_BINARY_OPERATOR
-
-// Division can't be implemented by MOZ_CHECKEDINT_BASIC_BINARY_OPERATOR
-// because if rhs == 0, we are not allowed to even try to compute the quotient.
-template<typename T>
-inline CheckedInt<T> operator /(const CheckedInt<T> &lhs,
-                                const CheckedInt<T> &rhs)
-{
-  T x = lhs.mValue;
-  T y = rhs.mValue;
-  bool isOpValid = detail::IsDivValid(x, y);
-  T result = isOpValid ? (x / y) : 0;
-  /* give the compiler a good chance to perform RVO */
-  return CheckedInt<T>(result,
-                       lhs.mIsValid && rhs.mIsValid && isOpValid);
-}
-
-// Implement castToCheckedInt<T>(x), making sure that
-//  - it allows x to be either a CheckedInt<T> or any integer type
-//    that can be casted to T
-//  - if x is already a CheckedInt<T>, we just return a reference to it,
-//    instead of copying it (optimization)
-
-namespace detail {
-
-template<typename T, typename U>
-struct CastToCheckedIntImpl
-{
-    typedef CheckedInt<T> ReturnType;
-    static CheckedInt<T> run(U u) { return u; }
-};
-
-template<typename T>
-struct CastToCheckedIntImpl<T, CheckedInt<T> >
-{
-    typedef const CheckedInt<T>& ReturnType;
-    static const CheckedInt<T>& run(const CheckedInt<T>& u) { return u; }
-};
-
-} // namespace detail
-
-template<typename T, typename U>
-inline typename detail::CastToCheckedIntImpl<T, U>::ReturnType
-castToCheckedInt(U u)
-{
-  return detail::CastToCheckedIntImpl<T, U>::run(u);
-}
-
-#define MOZ_CHECKEDINT_CONVENIENCE_BINARY_OPERATORS(OP, COMPOUND_OP)  \
-template<typename T>                                              \
-template<typename U>                                              \
-CheckedInt<T>& CheckedInt<T>::operator COMPOUND_OP(U rhs)         \
-{                                                                 \
-  *this = *this OP castToCheckedInt<T>(rhs);                      \
-  return *this;                                                   \
-}                                                                 \
-template<typename T, typename U>                                  \
-inline CheckedInt<T> operator OP(const CheckedInt<T> &lhs, U rhs) \
-{                                                                 \
-  return lhs OP castToCheckedInt<T>(rhs);                         \
-}                                                                 \
-template<typename T, typename U>                                  \
-inline CheckedInt<T> operator OP(U lhs, const CheckedInt<T> &rhs) \
-{                                                                 \
-  return castToCheckedInt<T>(lhs) OP rhs;                         \
-}
-
-MOZ_CHECKEDINT_CONVENIENCE_BINARY_OPERATORS(+, +=)
-MOZ_CHECKEDINT_CONVENIENCE_BINARY_OPERATORS(*, *=)
-MOZ_CHECKEDINT_CONVENIENCE_BINARY_OPERATORS(-, -=)
-MOZ_CHECKEDINT_CONVENIENCE_BINARY_OPERATORS(/, /=)
-
-#undef MOZ_CHECKEDINT_CONVENIENCE_BINARY_OPERATORS
-
-template<typename T, typename U>
-inline bool
-operator ==(const CheckedInt<T> &lhs, U rhs)
-{
-  return lhs == castToCheckedInt<T>(rhs);
-}
-
-template<typename T, typename U>
-inline bool
-operator ==(U  lhs, const CheckedInt<T> &rhs)
-{
-  return castToCheckedInt<T>(lhs) == rhs;
-}
-
-// Convenience typedefs.
-typedef CheckedInt<int8_t>   CheckedInt8;
-typedef CheckedInt<uint8_t>  CheckedUint8;
-typedef CheckedInt<int16_t>  CheckedInt16;
-typedef CheckedInt<uint16_t> CheckedUint16;
-typedef CheckedInt<int32_t>  CheckedInt32;
-typedef CheckedInt<uint32_t> CheckedUint32;
-typedef CheckedInt<int64_t>  CheckedInt64;
-typedef CheckedInt<uint64_t> CheckedUint64;
-
-} // namespace mozilla
-
-#endif /* mozilla_CheckedInt_h_ */
--- a/mfbt/Makefile.in
+++ b/mfbt/Makefile.in
@@ -42,19 +42,17 @@ VPATH = @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
 MODULE = mozglue
 LIBRARY_NAME = mfbt
 FORCE_STATIC_LIB = 1
 STL_FLAGS =
 
-TEST_DIRS = \
-  tests \
-  $(NULL)
+DIRS =
 
 # exported_headers.mk defines the headers exported by mfbt.  It is included by
 # mfbt itself and by the JS engine, which, when built standalone, must do the
 # work to install mfbt's exported headers itself.
 include $(srcdir)/exported_headers.mk
 
 # sources.mk defines the source files built for mfbt. It is included by mfbt
 # itself and by the JS engine, which, when built standalone, must do the work
--- a/mfbt/exported_headers.mk
+++ b/mfbt/exported_headers.mk
@@ -40,17 +40,16 @@
 # mfbt's exported headers itself.
 
 EXPORTS_NAMESPACES += mozilla
 
 EXPORTS_mozilla += \
   Assertions.h \
   Attributes.h \
   BloomFilter.h \
-  CheckedInt.h \
   FloatingPoint.h \
   GuardObjects.h \
   HashFunctions.h \
   Likely.h \
   LinkedList.h \
   MSStdInt.h \
   RangedPtr.h \
   RefPtr.h \
deleted file mode 100644
--- a/mfbt/tests/Makefile.in
+++ /dev/null
@@ -1,21 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this file,
-# You can obtain one at http://mozilla.org/MPL/2.0/.
-
-DEPTH = ../..
-topsrcdir = @top_srcdir@
-srcdir = @srcdir@
-VPATH = @srcdir@
-
-include $(DEPTH)/config/autoconf.mk
-
-STL_FLAGS =
-
-CPP_UNIT_TESTS = \
-  TestCheckedInt.cpp \
-  $(NULL)
-
-include $(topsrcdir)/config/rules.mk
-
-LIBS=
-MOZ_GLUE_PROGRAM_LDFLAGS=
\ No newline at end of file
deleted file mode 100644
--- a/mfbt/tests/TestCheckedInt.cpp
+++ /dev/null
@@ -1,492 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "mozilla/CheckedInt.h"
-
-#include <iostream>
-#include <climits>
-
-#ifndef MOZ_CHECKEDINT_ENABLE_MOZ_ASSERTS
-#  error MOZ_CHECKEDINT_ENABLE_MOZ_ASSERTS should be defined by CheckedInt.h
-#endif
-
-using namespace mozilla;
-
-int gIntegerTypesTested = 0;
-int gTestsPassed = 0;
-int gTestsFailed = 0;
-
-void verifyImplFunction(bool x, bool expected,
-                        const char* file, int line,
-                        int size, bool isTSigned)
-{
-  if (x == expected) {
-    gTestsPassed++;
-  } else {
-    gTestsFailed++;
-    std::cerr << "Test failed at " << file << ":" << line;
-    std::cerr << " with T a ";
-    if (isTSigned)
-      std::cerr << "signed";
-    else
-      std::cerr << "unsigned";
-    std::cerr << " " << CHAR_BIT*size << "-bit integer type" << std::endl;
-  }
-}
-
-#define VERIFY_IMPL(x, expected) \
-    verifyImplFunction((x), \
-    (expected), \
-    __FILE__, \
-    __LINE__, \
-    sizeof(T), \
-    detail::IsSigned<T>::value)
-
-#define VERIFY(x)            VERIFY_IMPL(x, true)
-#define VERIFY_IS_FALSE(x)   VERIFY_IMPL(x, false)
-#define VERIFY_IS_VALID(x)   VERIFY_IMPL((x).isValid(), true)
-#define VERIFY_IS_INVALID(x) VERIFY_IMPL((x).isValid(), false)
-#define VERIFY_IS_VALID_IF(x,condition) VERIFY_IMPL((x).isValid(), (condition))
-
-template<typename T, size_t Size = sizeof(T)>
-struct testTwiceBiggerType
-{
-    static void run()
-    {
-      VERIFY(detail::IsSupported<typename detail::TwiceBiggerType<T>::Type>::value);
-      VERIFY(sizeof(typename detail::TwiceBiggerType<T>::Type)
-               == 2 * sizeof(T));
-      VERIFY(bool(detail::IsSigned<typename detail::TwiceBiggerType<T>::Type>::value)
-               == bool(detail::IsSigned<T>::value));
-    }
-};
-
-template<typename T>
-struct testTwiceBiggerType<T, 8>
-{
-    static void run()
-    {
-      VERIFY_IS_FALSE(detail::IsSupported<
-                        typename detail::TwiceBiggerType<T>::Type
-                      >::value);
-    }
-};
-
-
-template<typename T>
-void test()
-{
-  static bool alreadyRun = false;
-  // Integer types from different families may just be typedefs for types from other families.
-  // e.g. int32_t might be just a typedef for int. No point re-running the same tests then.
-  if (alreadyRun)
-      return;
-  alreadyRun = true;
-
-  VERIFY(detail::IsSupported<T>::value);
-  const bool isTSigned = detail::IsSigned<T>::value;
-  VERIFY(bool(isTSigned) == !bool(T(-1) > T(0)));
-
-  testTwiceBiggerType<T>::run();
-
-  typedef typename detail::UnsignedType<T>::Type unsignedT;
-
-  VERIFY(sizeof(unsignedT) == sizeof(T));
-  VERIFY(detail::IsSigned<unsignedT>::value == false);
-
-  const CheckedInt<T> max(detail::MaxValue<T>::value());
-  const CheckedInt<T> min(detail::MinValue<T>::value());
-
-  // Check min() and max(), since they are custom implementations and a mistake there
-  // could potentially NOT be caught by any other tests... while making everything wrong!
-
-  T bit = 1;
-  for (size_t i = 0; i < sizeof(T) * CHAR_BIT - 1; i++)
-  {
-    VERIFY((min.value() & bit) == 0);
-    bit <<= 1;
-  }
-  VERIFY((min.value() & bit) == (isTSigned ? bit : T(0)));
-  VERIFY(max.value() == T(~(min.value())));
-
-  const CheckedInt<T> zero(0);
-  const CheckedInt<T> one(1);
-  const CheckedInt<T> two(2);
-  const CheckedInt<T> three(3);
-  const CheckedInt<T> four(4);
-
-  /* Addition / substraction checks */
-
-  VERIFY_IS_VALID(zero + zero);
-  VERIFY(zero + zero == zero);
-  VERIFY_IS_FALSE(zero + zero == one); // Check that == doesn't always return true
-  VERIFY_IS_VALID(zero + one);
-  VERIFY(zero + one == one);
-  VERIFY_IS_VALID(one + one);
-  VERIFY(one + one == two);
-
-  const CheckedInt<T> maxMinusOne = max - one;
-  const CheckedInt<T> maxMinusTwo = max - two;
-  VERIFY_IS_VALID(maxMinusOne);
-  VERIFY_IS_VALID(maxMinusTwo);
-  VERIFY_IS_VALID(maxMinusOne + one);
-  VERIFY_IS_VALID(maxMinusTwo + one);
-  VERIFY_IS_VALID(maxMinusTwo + two);
-  VERIFY(maxMinusOne + one == max);
-  VERIFY(maxMinusTwo + one == maxMinusOne);
-  VERIFY(maxMinusTwo + two == max);
-
-  VERIFY_IS_VALID(max + zero);
-  VERIFY_IS_VALID(max - zero);
-  VERIFY_IS_INVALID(max + one);
-  VERIFY_IS_INVALID(max + two);
-  VERIFY_IS_INVALID(max + maxMinusOne);
-  VERIFY_IS_INVALID(max + max);
-
-  const CheckedInt<T> minPlusOne = min + one;
-  const CheckedInt<T> minPlusTwo = min + two;
-  VERIFY_IS_VALID(minPlusOne);
-  VERIFY_IS_VALID(minPlusTwo);
-  VERIFY_IS_VALID(minPlusOne - one);
-  VERIFY_IS_VALID(minPlusTwo - one);
-  VERIFY_IS_VALID(minPlusTwo - two);
-  VERIFY(minPlusOne - one == min);
-  VERIFY(minPlusTwo - one == minPlusOne);
-  VERIFY(minPlusTwo - two == min);
-
-  const CheckedInt<T> minMinusOne = min - one;
-  VERIFY_IS_VALID(min + zero);
-  VERIFY_IS_VALID(min - zero);
-  VERIFY_IS_INVALID(min - one);
-  VERIFY_IS_INVALID(min - two);
-  VERIFY_IS_INVALID(min - minMinusOne);
-  VERIFY_IS_VALID(min - min);
-
-  const CheckedInt<T> maxOverTwo = max / two;
-  VERIFY_IS_VALID(maxOverTwo + maxOverTwo);
-  VERIFY_IS_VALID(maxOverTwo + one);
-  VERIFY((maxOverTwo + one) - one == maxOverTwo);
-  VERIFY_IS_VALID(maxOverTwo - maxOverTwo);
-  VERIFY(maxOverTwo - maxOverTwo == zero);
-
-  const CheckedInt<T> minOverTwo = min / two;
-  VERIFY_IS_VALID(minOverTwo + minOverTwo);
-  VERIFY_IS_VALID(minOverTwo + one);
-  VERIFY((minOverTwo + one) - one == minOverTwo);
-  VERIFY_IS_VALID(minOverTwo - minOverTwo);
-  VERIFY(minOverTwo - minOverTwo == zero);
-
-  VERIFY_IS_INVALID(min - one);
-  VERIFY_IS_INVALID(min - two);
-
-  if (isTSigned) {
-    VERIFY_IS_INVALID(min + min);
-    VERIFY_IS_INVALID(minOverTwo + minOverTwo + minOverTwo);
-    VERIFY_IS_INVALID(zero - min + min);
-    VERIFY_IS_INVALID(one - min + min);
-  }
-
-  /* Unary operator- checks */
-
-  const CheckedInt<T> negOne = -one;
-  const CheckedInt<T> negTwo = -two;
-
-  if (isTSigned) {
-    VERIFY_IS_VALID(-max);
-    VERIFY_IS_VALID(-max - one);
-    VERIFY_IS_VALID(negOne);
-    VERIFY_IS_VALID(-max + negOne);
-    VERIFY_IS_VALID(negOne + one);
-    VERIFY(negOne + one == zero);
-    VERIFY_IS_VALID(negTwo);
-    VERIFY_IS_VALID(negOne + negOne);
-    VERIFY(negOne + negOne == negTwo);
-  } else {
-    VERIFY_IS_INVALID(negOne);
-  }
-
-  /* multiplication checks */
-
-  VERIFY_IS_VALID(zero * zero);
-  VERIFY(zero * zero == zero);
-  VERIFY_IS_VALID(zero * one);
-  VERIFY(zero * one == zero);
-  VERIFY_IS_VALID(one * zero);
-  VERIFY(one * zero == zero);
-  VERIFY_IS_VALID(one * one);
-  VERIFY(one * one == one);
-  VERIFY_IS_VALID(one * three);
-  VERIFY(one * three == three);
-  VERIFY_IS_VALID(two * two);
-  VERIFY(two * two == four);
-
-  VERIFY_IS_INVALID(max * max);
-  VERIFY_IS_INVALID(maxOverTwo * max);
-  VERIFY_IS_INVALID(maxOverTwo * maxOverTwo);
-
-  const CheckedInt<T> maxApproxSqrt(T(T(1) << (CHAR_BIT*sizeof(T)/2)));
-
-  VERIFY_IS_VALID(maxApproxSqrt);
-  VERIFY_IS_VALID(maxApproxSqrt * two);
-  VERIFY_IS_INVALID(maxApproxSqrt * maxApproxSqrt);
-  VERIFY_IS_INVALID(maxApproxSqrt * maxApproxSqrt * maxApproxSqrt);
-
-  if (isTSigned) {
-    VERIFY_IS_INVALID(min * min);
-    VERIFY_IS_INVALID(minOverTwo * min);
-    VERIFY_IS_INVALID(minOverTwo * minOverTwo);
-
-    const CheckedInt<T> minApproxSqrt = -maxApproxSqrt;
-
-    VERIFY_IS_VALID(minApproxSqrt);
-    VERIFY_IS_VALID(minApproxSqrt * two);
-    VERIFY_IS_INVALID(minApproxSqrt * maxApproxSqrt);
-    VERIFY_IS_INVALID(minApproxSqrt * minApproxSqrt);
-  }
-
-  // make sure to check all 4 paths in signed multiplication validity check.
-  // test positive * positive
-  VERIFY_IS_VALID(max * one);
-  VERIFY(max * one == max);
-  VERIFY_IS_INVALID(max * two);
-  VERIFY_IS_VALID(maxOverTwo * two);
-  VERIFY((maxOverTwo + maxOverTwo) == (maxOverTwo * two));
-
-  if (isTSigned) {
-    // test positive * negative
-    VERIFY_IS_VALID(max * negOne);
-    VERIFY_IS_VALID(-max);
-    VERIFY(max * negOne == -max);
-    VERIFY_IS_VALID(one * min);
-    VERIFY_IS_INVALID(max * negTwo);
-    VERIFY_IS_VALID(maxOverTwo * negTwo);
-    VERIFY_IS_VALID(two * minOverTwo);
-    VERIFY_IS_VALID((maxOverTwo + one) * negTwo);
-    VERIFY_IS_INVALID((maxOverTwo + two) * negTwo);
-    VERIFY_IS_INVALID(two * (minOverTwo - one));
-
-    // test negative * positive
-    VERIFY_IS_VALID(min * one);
-    VERIFY_IS_VALID(minPlusOne * one);
-    VERIFY_IS_INVALID(min * two);
-    VERIFY_IS_VALID(minOverTwo * two);
-    VERIFY(minOverTwo * two == min);
-    VERIFY_IS_INVALID((minOverTwo - one) * negTwo);
-    VERIFY_IS_INVALID(negTwo * max);
-    VERIFY_IS_VALID(minOverTwo * two);
-    VERIFY(minOverTwo * two == min);
-    VERIFY_IS_VALID(negTwo * maxOverTwo);
-    VERIFY_IS_INVALID((minOverTwo - one) * two);
-    VERIFY_IS_VALID(negTwo * (maxOverTwo + one));
-    VERIFY_IS_INVALID(negTwo * (maxOverTwo + two));
-
-    // test negative * negative
-    VERIFY_IS_INVALID(min * negOne);
-    VERIFY_IS_VALID(minPlusOne * negOne);
-    VERIFY(minPlusOne * negOne == max);
-    VERIFY_IS_INVALID(min * negTwo);
-    VERIFY_IS_INVALID(minOverTwo * negTwo);
-    VERIFY_IS_INVALID(negOne * min);
-    VERIFY_IS_VALID(negOne * minPlusOne);
-    VERIFY(negOne * minPlusOne == max);
-    VERIFY_IS_INVALID(negTwo * min);
-    VERIFY_IS_INVALID(negTwo * minOverTwo);
-  }
-
-  /* Division checks */
-
-  VERIFY_IS_VALID(one / one);
-  VERIFY(one / one == one);
-  VERIFY_IS_VALID(three / three);
-  VERIFY(three / three == one);
-  VERIFY_IS_VALID(four / two);
-  VERIFY(four / two == two);
-  VERIFY((four*three)/four == three);
-
-  // Check that div by zero is invalid
-  VERIFY_IS_INVALID(zero / zero);
-  VERIFY_IS_INVALID(one / zero);
-  VERIFY_IS_INVALID(two / zero);
-  VERIFY_IS_INVALID(negOne / zero);
-  VERIFY_IS_INVALID(max / zero);
-  VERIFY_IS_INVALID(min / zero);
-
-  if (isTSigned) {
-    // Check that min / -1 is invalid
-    VERIFY_IS_INVALID(min / negOne);
-
-    // Check that the test for div by -1 isn't banning other numerators than min
-    VERIFY_IS_VALID(one / negOne);
-    VERIFY_IS_VALID(zero / negOne);
-    VERIFY_IS_VALID(negOne / negOne);
-    VERIFY_IS_VALID(max / negOne);
-  }
-
-  /* Check that invalidity is correctly preserved by arithmetic ops */
-
-  const CheckedInt<T> someInvalid = max + max;
-  VERIFY_IS_INVALID(someInvalid + zero);
-  VERIFY_IS_INVALID(someInvalid - zero);
-  VERIFY_IS_INVALID(zero + someInvalid);
-  VERIFY_IS_INVALID(zero - someInvalid);
-  VERIFY_IS_INVALID(-someInvalid);
-  VERIFY_IS_INVALID(someInvalid * zero);
-  VERIFY_IS_INVALID(someInvalid * one);
-  VERIFY_IS_INVALID(zero * someInvalid);
-  VERIFY_IS_INVALID(one * someInvalid);
-  VERIFY_IS_INVALID(someInvalid / zero);
-  VERIFY_IS_INVALID(someInvalid / one);
-  VERIFY_IS_INVALID(zero / someInvalid);
-  VERIFY_IS_INVALID(one / someInvalid);
-  VERIFY_IS_INVALID(someInvalid + someInvalid);
-  VERIFY_IS_INVALID(someInvalid - someInvalid);
-  VERIFY_IS_INVALID(someInvalid * someInvalid);
-  VERIFY_IS_INVALID(someInvalid / someInvalid);
-
-  /* Check that mixing checked integers with plain integers in expressions is allowed */
-
-  VERIFY(one + T(2) == three);
-  VERIFY(2 + one == three);
-  {
-    CheckedInt<T> x = one;
-    x += 2;
-    VERIFY(x == three);
-  }
-  VERIFY(two - 1 == one);
-  VERIFY(2 - one == one);
-  {
-    CheckedInt<T> x = two;
-    x -= 1;
-    VERIFY(x == one);
-  }
-  VERIFY(one * 2 == two);
-  VERIFY(2 * one == two);
-  {
-    CheckedInt<T> x = one;
-    x *= 2;
-    VERIFY(x == two);
-  }
-  VERIFY(four / 2 == two);
-  VERIFY(4 / two == two);
-  {
-    CheckedInt<T> x = four;
-    x /= 2;
-    VERIFY(x == two);
-  }
-
-  VERIFY(one == 1);
-  VERIFY(1 == one);
-  VERIFY_IS_FALSE(two == 1);
-  VERIFY_IS_FALSE(1 == two);
-  VERIFY_IS_FALSE(someInvalid == 1);
-  VERIFY_IS_FALSE(1 == someInvalid);
-
-  /* Check that construction of CheckedInt from an integer value of a mismatched type is checked */
-
-  #define VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE(U) \
-  { \
-    bool isUSigned = detail::IsSigned<U>::value; \
-    VERIFY_IS_VALID(CheckedInt<T>(U(0))); \
-    VERIFY_IS_VALID(CheckedInt<T>(U(1))); \
-    VERIFY_IS_VALID(CheckedInt<T>(U(100))); \
-    if (isUSigned) \
-      VERIFY_IS_VALID_IF(CheckedInt<T>(U(-1)), isTSigned); \
-    if (sizeof(U) > sizeof(T)) \
-      VERIFY_IS_INVALID(CheckedInt<T>(U(detail::MaxValue<T>::value())+1)); \
-    VERIFY_IS_VALID_IF(CheckedInt<T>(detail::MaxValue<U>::value()), \
-      (sizeof(T) > sizeof(U) || ((sizeof(T) == sizeof(U)) && (isUSigned || !isTSigned)))); \
-    VERIFY_IS_VALID_IF(CheckedInt<T>(detail::MinValue<U>::value()), \
-      isUSigned == false ? 1 : \
-      bool(isTSigned) == false ? 0 : \
-      sizeof(T) >= sizeof(U)); \
-  }
-  VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE(int8_t)
-  VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE(uint8_t)
-  VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE(int16_t)
-  VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE(uint16_t)
-  VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE(int32_t)
-  VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE(uint32_t)
-  VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE(int64_t)
-  VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE(uint64_t)
-
-  typedef unsigned char unsignedChar;
-  typedef unsigned short unsignedShort;
-  typedef unsigned int  unsignedInt;
-  typedef unsigned long unsignedLong;
-
-  VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE(char)
-  VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE(unsignedChar)
-  VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE(short)
-  VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE(unsignedShort)
-  VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE(int)
-  VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE(unsignedInt)
-  VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE(long)
-  VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE(unsignedLong)
-
-  /* Test increment/decrement operators */
-
-  CheckedInt<T> x, y;
-  x = one;
-  y = x++;
-  VERIFY(x == two);
-  VERIFY(y == one);
-  x = one;
-  y = ++x;
-  VERIFY(x == two);
-  VERIFY(y == two);
-  x = one;
-  y = x--;
-  VERIFY(x == zero);
-  VERIFY(y == one);
-  x = one;
-  y = --x;
-  VERIFY(x == zero);
-  VERIFY(y == zero);
-  x = max;
-  VERIFY_IS_VALID(x++);
-  x = max;
-  VERIFY_IS_INVALID(++x);
-  x = min;
-  VERIFY_IS_VALID(x--);
-  x = min;
-  VERIFY_IS_INVALID(--x);
-
-  gIntegerTypesTested++;
-}
-
-int main()
-{
-  test<int8_t>();
-  test<uint8_t>();
-  test<int16_t>();
-  test<uint16_t>();
-  test<int32_t>();
-  test<uint32_t>();
-  test<int64_t>();
-  test<uint64_t>();
-
-  test<char>();
-  test<unsigned char>();
-  test<short>();
-  test<unsigned short>();
-  test<int>();
-  test<unsigned int>();
-  test<long>();
-  test<unsigned long>();
-
-  if (gIntegerTypesTested < 8) {
-    std::cerr << "Only " << gIntegerTypesTested << " have been tested. "
-              << "This should not be less than 8." << std::endl;
-    gTestsFailed++;
-  }
-
-  std::cerr << gTestsFailed << " tests failed, "
-            << gTestsPassed << " tests passed out of "
-            << gTestsFailed + gTestsPassed
-            << " tests, covering " << gIntegerTypesTested
-            << " distinct integer types." << std::endl;
-
-  return gTestsFailed > 0;
-}
new file mode 100644
--- /dev/null
+++ b/xpcom/ds/CheckedInt.h
@@ -0,0 +1,595 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* ***** 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 Mozilla code.
+ *
+ * The Initial Developer of the Original Code is the Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *  Benoit Jacob <bjacob@mozilla.com>
+ *  Jeff Muizelaar <jmuizelaar@mozilla.com>
+ *
+ * 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 ***** */
+
+#ifndef mozilla_CheckedInt_h
+#define mozilla_CheckedInt_h
+
+#include "prtypes.h"
+
+#include <climits>
+
+namespace mozilla {
+
+namespace CheckedInt_internal {
+
+/* we don't want to use std::numeric_limits here because PRInt... types may not support it,
+ * depending on the platform, e.g. on certain platforms they use nonstandard built-in types
+ */
+
+/*** Step 1: manually record information for all the types that we want to support
+ ***/
+
+struct unsupported_type {};
+
+template<typename T> struct integer_type_manually_recorded_info
+{
+    enum { is_supported = 0 };
+    typedef unsupported_type twice_bigger_type;
+    typedef unsupported_type unsigned_type;
+};
+
+
+#define CHECKEDINT_REGISTER_SUPPORTED_TYPE(T,_twice_bigger_type,_unsigned_type)  \
+template<> struct integer_type_manually_recorded_info<T>       \
+{                                                              \
+    enum { is_supported = 1 };                                 \
+    typedef _twice_bigger_type twice_bigger_type;              \
+    typedef _unsigned_type unsigned_type;                      \
+    static void TYPE_NOT_SUPPORTED_BY_CheckedInt() {}          \
+};
+
+//                                 Type      Twice Bigger Type     Unsigned Type
+CHECKEDINT_REGISTER_SUPPORTED_TYPE(PRInt8,   PRInt16,              PRUint8)
+CHECKEDINT_REGISTER_SUPPORTED_TYPE(PRUint8,  PRUint16,             PRUint8)
+CHECKEDINT_REGISTER_SUPPORTED_TYPE(PRInt16,  PRInt32,              PRUint16)
+CHECKEDINT_REGISTER_SUPPORTED_TYPE(PRUint16, PRUint32,             PRUint16)
+CHECKEDINT_REGISTER_SUPPORTED_TYPE(PRInt32,  PRInt64,              PRUint32)
+CHECKEDINT_REGISTER_SUPPORTED_TYPE(PRUint32, PRUint64,             PRUint32)
+CHECKEDINT_REGISTER_SUPPORTED_TYPE(PRInt64,  unsupported_type,     PRUint64)
+CHECKEDINT_REGISTER_SUPPORTED_TYPE(PRUint64, unsupported_type,     PRUint64)
+
+
+/*** Step 2: record some info about a given integer type,
+ ***         including whether it is supported, whether a twice bigger integer type
+ ***         is supported, what that twice bigger type is, and some stuff as found
+ ***         in std::numeric_limits (which we don't use because PRInt.. types may
+ ***         not support it, if they are defined directly from compiler built-in types).
+ ***         We use function names min_value() and max_value() instead of min() and max()
+ ***         because of stupid min/max macros in Windows headers.
+ ***/
+
+template<typename T> struct is_unsupported_type { enum { answer = 0 }; };
+template<> struct is_unsupported_type<unsupported_type> { enum { answer = 1 }; };
+
+template<typename T> struct integer_traits
+{
+    typedef typename integer_type_manually_recorded_info<T>::twice_bigger_type twice_bigger_type;
+    typedef typename integer_type_manually_recorded_info<T>::unsigned_type unsigned_type;
+
+    enum {
+        is_supported = integer_type_manually_recorded_info<T>::is_supported,
+        twice_bigger_type_is_supported
+            = is_unsupported_type<
+                  typename integer_type_manually_recorded_info<T>::twice_bigger_type
+              >::answer ? 0 : 1,
+        size = sizeof(T),
+        position_of_sign_bit = CHAR_BIT * size - 1,
+        is_signed = (T(-1) > T(0)) ? 0 : 1
+    };
+
+    static T min_value()
+    {
+        // bitwise ops may return a larger type, that's why we cast explicitly to T
+        // in C++, left bit shifts on signed values is undefined by the standard unless the shifted value is representable.
+        // notice that signed-to-unsigned conversions are always well-defined in the standard,
+        // as the value congruent to 2^n as expected. By contrast, unsigned-to-signed is only well-defined if the value is
+        // representable.
+        return is_signed ? T(unsigned_type(1) << position_of_sign_bit) : T(0);
+    }
+
+    static T max_value()
+    {
+        return ~min_value();
+    }
+};
+
+/*** Step 3: Implement the actual validity checks --- ideas taken from IntegerLib, code different.
+ ***/
+
+// bitwise ops may return a larger type, so it's good to use these inline helpers guaranteeing that
+// the result is really of type T
+
+template<typename T> inline T has_sign_bit(T x)
+{
+    // in C++, right bit shifts on negative values is undefined by the standard.
+    // notice that signed-to-unsigned conversions are always well-defined in the standard,
+    // as the value congruent modulo 2^n as expected. By contrast, unsigned-to-signed is only well-defined if the value is
+    // representable. Here the unsigned-to-signed conversion is OK because the value (the result of the shift) is 0 or 1.
+    typedef typename integer_traits<T>::unsigned_type unsigned_T;
+    return T(unsigned_T(x) >> integer_traits<T>::position_of_sign_bit);
+}
+
+template<typename T> inline T binary_complement(T x)
+{
+    return ~x;
+}
+
+template<typename T, typename U,
+         bool is_T_signed = integer_traits<T>::is_signed,
+         bool is_U_signed = integer_traits<U>::is_signed>
+struct is_in_range_impl {};
+
+template<typename T, typename U>
+struct is_in_range_impl<T, U, true, true>
+{
+    static T run(U x)
+    {
+        return (x <= integer_traits<T>::max_value()) &&
+               (x >= integer_traits<T>::min_value());
+    }
+};
+
+template<typename T, typename U>
+struct is_in_range_impl<T, U, false, false>
+{
+    static T run(U x)
+    {
+        return x <= integer_traits<T>::max_value();
+    }
+};
+
+template<typename T, typename U>
+struct is_in_range_impl<T, U, true, false>
+{
+    static T run(U x)
+    {
+        if (sizeof(T) > sizeof(U))
+            return 1;
+        else
+            return x <= U(integer_traits<T>::max_value());
+    }
+};
+
+template<typename T, typename U>
+struct is_in_range_impl<T, U, false, true>
+{
+    static T run(U x)
+    {
+        if (sizeof(T) >= sizeof(U))
+            return x >= 0;
+        else
+            return (x >= 0) && (x <= U(integer_traits<T>::max_value()));
+    }
+};
+
+template<typename T, typename U> inline T is_in_range(U x)
+{
+    return is_in_range_impl<T, U>::run(x);
+}
+
+template<typename T> inline T is_add_valid(T x, T y, T result)
+{
+    return integer_traits<T>::is_signed ?
+                        // addition is valid if the sign of x+y is equal to either that of x or that of y.
+                        // Beware! These bitwise operations can return a larger integer type, if T was a
+                        // small type like int8, so we explicitly cast to T.
+                        has_sign_bit(binary_complement(T((result^x) & (result^y))))
+                    :
+                        binary_complement(x) >= y;
+}
+
+template<typename T> inline T is_sub_valid(T x, T y, T result)
+{
+    return integer_traits<T>::is_signed ?
+                        // substraction is valid if either x and y have same sign, or x-y and x have same sign
+                        has_sign_bit(binary_complement(T((result^x) & (x^y))))
+                    :
+                        x >= y;
+}
+
+template<typename T,
+         bool is_signed =  integer_traits<T>::is_signed,
+         bool twice_bigger_type_is_supported = integer_traits<T>::twice_bigger_type_is_supported>
+struct is_mul_valid_impl {};
+
+template<typename T, bool is_signed>
+struct is_mul_valid_impl<T, is_signed, true>
+{
+    static T run(T x, T y)
+    {
+        typedef typename integer_traits<T>::twice_bigger_type twice_bigger_type;
+        twice_bigger_type product = twice_bigger_type(x) * twice_bigger_type(y);
+        return is_in_range<T>(product);
+    }
+};
+
+template<typename T>
+struct is_mul_valid_impl<T, true, false>
+{
+    static T run(T x, T y)
+    {
+        const T max_value = integer_traits<T>::max_value();
+        const T min_value = integer_traits<T>::min_value();
+
+        if (x == 0 || y == 0) return true;
+
+        if (x > 0) {
+            if (y > 0)
+                return x <= max_value / y;
+            else
+                return y >= min_value / x;
+        } else {
+            if (y > 0)
+                return x >= min_value / y;
+            else
+                return y >= max_value / x;
+        }
+    }
+};
+
+template<typename T>
+struct is_mul_valid_impl<T, false, false>
+{
+    static T run(T x, T y)
+    {
+        const T max_value = integer_traits<T>::max_value();
+        if (x == 0 || y == 0) return true;
+        return x <= max_value / y;
+    }
+};
+
+template<typename T> inline T is_mul_valid(T x, T y, T /*result not used*/)
+{
+    return is_mul_valid_impl<T>::run(x, y);
+}
+
+template<typename T> inline T is_div_valid(T x, T y)
+{
+    return integer_traits<T>::is_signed ?
+                        // keep in mind that min/-1 is invalid because abs(min)>max
+                        (y != 0) && (x != integer_traits<T>::min_value() || y != T(-1))
+                    :
+                        y != 0;
+}
+
+// this is just to shut up msvc warnings about negating unsigned ints.
+template<typename T, bool is_signed = integer_traits<T>::is_signed>
+struct opposite_if_signed_impl
+{
+    static T run(T x) { return -x; }
+};
+template<typename T>
+struct opposite_if_signed_impl<T, false>
+{
+    static T run(T x) { return x; }
+};
+template<typename T>
+inline T opposite_if_signed(T x) { return opposite_if_signed_impl<T>::run(x); }
+
+
+
+} // end namespace CheckedInt_internal
+
+
+/*** Step 4: Now define the CheckedInt class.
+ ***/
+
+/** \class CheckedInt
+  * \brief Integer wrapper class checking for integer overflow and other errors
+  * \param T the integer type to wrap. Can be any of PRInt8, PRUint8, PRInt16, PRUint16,
+  *          PRInt32, PRUint32, PRInt64, PRUint64.
+  *
+  * This class implements guarded integer arithmetic. Do a computation, check that
+  * valid() returns true, you then have a guarantee that no problem, such as integer overflow,
+  * happened during this computation.
+  *
+  * The arithmetic operators in this class are guaranteed not to crash your app
+  * in case of a division by zero.
+  *
+  * For example, suppose that you want to implement a function that computes (x+y)/z,
+  * that doesn't crash if z==0, and that reports on error (divide by zero or integer overflow).
+  * You could code it as follows:
+    \code
+    bool compute_x_plus_y_over_z(PRInt32 x, PRInt32 y, PRInt32 z, PRInt32 *result)
+    {
+        CheckedInt<PRInt32> checked_result = (CheckedInt<PRInt32>(x) + y) / z;
+        *result = checked_result.value();
+        return checked_result.valid();
+    }
+    \endcode
+  *
+  * Implicit conversion from plain integers to checked integers is allowed. The plain integer
+  * is checked to be in range before being casted to the destination type. This means that the following
+  * lines all compile, and the resulting CheckedInts are correctly detected as valid or invalid:
+  * \code
+    CheckedInt<PRUint8> x(1);   // 1 is of type int, is found to be in range for PRUint8, x is valid
+    CheckedInt<PRUint8> x(-1);  // -1 is of type int, is found not to be in range for PRUint8, x is invalid
+    CheckedInt<PRInt8> x(-1);   // -1 is of type int, is found to be in range for PRInt8, x is valid
+    CheckedInt<PRInt8> x(PRInt16(1000)); // 1000 is of type PRInt16, is found not to be in range for PRInt8, x is invalid
+    CheckedInt<PRInt32> x(PRUint32(3123456789)); // 3123456789 is of type PRUint32, is found not to be in range
+                                             // for PRInt32, x is invalid
+  * \endcode
+  * Implicit conversion from
+  * checked integers to plain integers is not allowed. As shown in the
+  * above example, to get the value of a checked integer as a normal integer, call value().
+  *
+  * Arithmetic operations between checked and plain integers is allowed; the result type
+  * is the type of the checked integer.
+  *
+  * Checked integers of different types cannot be used in the same arithmetic expression.
+  *
+  * There are convenience typedefs for all PR integer types, of the following form (these are just 2 examples):
+    \code
+    typedef CheckedInt<PRInt32> CheckedInt32;
+    typedef CheckedInt<PRUint16> CheckedUint16;
+    \endcode
+  */
+template<typename T>
+class CheckedInt
+{
+protected:
+    T mValue;
+    T mIsValid; // stored as a T to limit the number of integer conversions when
+                // evaluating nested arithmetic expressions.
+
+    template<typename U>
+    CheckedInt(U value, T isValid) : mValue(value), mIsValid(isValid)
+    {
+        CheckedInt_internal::integer_type_manually_recorded_info<T>
+            ::TYPE_NOT_SUPPORTED_BY_CheckedInt();
+    }
+
+public:
+    /** Constructs a checked integer with given \a value. The checked integer is initialized as valid or invalid
+      * depending on whether the \a value is in range.
+      *
+      * This constructor is not explicit. Instead, the type of its argument is a separate template parameter,
+      * ensuring that no conversion is performed before this constructor is actually called.
+      * As explained in the above documentation for class CheckedInt, this constructor checks that its argument is
+      * valid.
+      */
+    template<typename U>
+    CheckedInt(U value)
+        : mValue(T(value)),
+          mIsValid(CheckedInt_internal::is_in_range<T>(value))
+    {
+        CheckedInt_internal::integer_type_manually_recorded_info<T>
+            ::TYPE_NOT_SUPPORTED_BY_CheckedInt();
+    }
+
+    /** Constructs a valid checked integer with initial value 0 */
+    CheckedInt() : mValue(0), mIsValid(1)
+    {
+        CheckedInt_internal::integer_type_manually_recorded_info<T>
+            ::TYPE_NOT_SUPPORTED_BY_CheckedInt();
+    }
+
+    /** \returns the actual value */
+    T value() const { return mValue; }
+
+    /** \returns true if the checked integer is valid, i.e. is not the result
+      * of an invalid operation or of an operation involving an invalid checked integer
+      */
+    bool valid() const
+    {
+        return bool(mIsValid);
+    }
+
+    /** \returns the sum. Checks for overflow. */
+    template<typename U> friend CheckedInt<U> operator +(const CheckedInt<U>& lhs, const CheckedInt<U>& rhs);
+    /** Adds. Checks for overflow. \returns self reference */
+    template<typename U> CheckedInt& operator +=(U rhs);
+    /** \returns the difference. Checks for overflow. */
+    template<typename U> friend CheckedInt<U> operator -(const CheckedInt<U>& lhs, const CheckedInt<U> &rhs);
+    /** Substracts. Checks for overflow. \returns self reference */
+    template<typename U> CheckedInt& operator -=(U rhs);
+    /** \returns the product. Checks for overflow. */
+    template<typename U> friend CheckedInt<U> operator *(const CheckedInt<U>& lhs, const CheckedInt<U> &rhs);
+    /** Multiplies. Checks for overflow. \returns self reference */
+    template<typename U> CheckedInt& operator *=(U rhs);
+    /** \returns the quotient. Checks for overflow and for divide-by-zero. */
+    template<typename U> friend CheckedInt<U> operator /(const CheckedInt<U>& lhs, const CheckedInt<U> &rhs);
+    /** Divides. Checks for overflow and for divide-by-zero. \returns self reference */
+    template<typename U> CheckedInt& operator /=(U rhs);
+
+    /** \returns the opposite value. Checks for overflow. */
+    CheckedInt operator -() const
+    {
+        // circumvent msvc warning about - applied to unsigned int.
+        // if we're unsigned, the only valid case anyway is 0 in which case - is a no-op.
+        T result = CheckedInt_internal::opposite_if_signed(value());
+        /* give the compiler a good chance to perform RVO */
+        return CheckedInt(result,
+                          mIsValid & CheckedInt_internal::is_sub_valid(T(0), value(), result));
+    }
+
+    /** \returns true if the left and right hand sides are valid and have the same value. */
+    bool operator ==(const CheckedInt& other) const
+    {
+        return bool(mIsValid & other.mIsValid & (value() == other.mValue));
+    }
+
+    /** prefix ++ */
+    CheckedInt& operator++()
+    {
+        *this = *this + 1;
+        return *this;
+    }
+
+    /** postfix ++ */
+    CheckedInt operator++(int)
+    {
+        CheckedInt tmp = *this;
+        *this = *this + 1;
+        return tmp;
+    }
+
+    /** prefix -- */
+    CheckedInt& operator--()
+    {
+        *this = *this - 1;
+        return *this;
+    }
+
+    /** postfix -- */
+    CheckedInt operator--(int)
+    {
+        CheckedInt tmp = *this;
+        *this = *this - 1;
+        return tmp;
+    }
+
+private:
+    /** operator!= is disabled. Indeed, (a!=b) should be the same as !(a==b) but that
+      * would mean that if a or b is invalid, (a!=b) is always true, which is very tricky.
+      */
+    template<typename U>
+    bool operator !=(U other) const { return !(*this == other); }
+};
+
+#define CHECKEDINT_BASIC_BINARY_OPERATOR(NAME, OP)               \
+template<typename T>                                          \
+inline CheckedInt<T> operator OP(const CheckedInt<T> &lhs, const CheckedInt<T> &rhs) \
+{                                                                     \
+    T x = lhs.mValue;                                                \
+    T y = rhs.mValue;                                                \
+    T result = x OP y;                                                \
+    T is_op_valid                                                     \
+        = CheckedInt_internal::is_##NAME##_valid(x, y, result);       \
+    /* give the compiler a good chance to perform RVO */              \
+    return CheckedInt<T>(result,                                      \
+                         lhs.mIsValid & rhs.mIsValid & is_op_valid);  \
+}
+
+CHECKEDINT_BASIC_BINARY_OPERATOR(add, +)
+CHECKEDINT_BASIC_BINARY_OPERATOR(sub, -)
+CHECKEDINT_BASIC_BINARY_OPERATOR(mul, *)
+
+// division can't be implemented by CHECKEDINT_BASIC_BINARY_OPERATOR
+// because if rhs == 0, we are not allowed to even try to compute the quotient.
+template<typename T>
+inline CheckedInt<T> operator /(const CheckedInt<T> &lhs, const CheckedInt<T> &rhs)
+{
+    T x = lhs.mValue;
+    T y = rhs.mValue;
+    T is_op_valid = CheckedInt_internal::is_div_valid(x, y);
+    T result = is_op_valid ? (x / y) : 0;
+    /* give the compiler a good chance to perform RVO */
+    return CheckedInt<T>(result,
+                         lhs.mIsValid & rhs.mIsValid & is_op_valid);
+}
+
+// implement cast_to_CheckedInt<T>(x), making sure that
+//  - it allows x to be either a CheckedInt<T> or any integer type that can be casted to T
+//  - if x is already a CheckedInt<T>, we just return a reference to it, instead of copying it (optimization)
+
+template<typename T, typename U>
+struct cast_to_CheckedInt_impl
+{
+    typedef CheckedInt<T> return_type;
+    static CheckedInt<T> run(U u) { return u; }
+};
+
+template<typename T>
+struct cast_to_CheckedInt_impl<T, CheckedInt<T> >
+{
+    typedef const CheckedInt<T>& return_type;
+    static const CheckedInt<T>& run(const CheckedInt<T>& u) { return u; }
+};
+
+template<typename T, typename U>
+inline typename cast_to_CheckedInt_impl<T, U>::return_type
+cast_to_CheckedInt(U u)
+{
+    return cast_to_CheckedInt_impl<T, U>::run(u);
+}
+
+#define CHECKEDINT_CONVENIENCE_BINARY_OPERATORS(OP, COMPOUND_OP) \
+template<typename T>                                          \
+template<typename U>                                          \
+CheckedInt<T>& CheckedInt<T>::operator COMPOUND_OP(U rhs)    \
+{                                                             \
+    *this = *this OP cast_to_CheckedInt<T>(rhs);                 \
+    return *this;                                             \
+}                                                             \
+template<typename T, typename U>                              \
+inline CheckedInt<T> operator OP(const CheckedInt<T> &lhs, U rhs) \
+{                                                             \
+    return lhs OP cast_to_CheckedInt<T>(rhs);                    \
+}                                                             \
+template<typename T, typename U>                              \
+inline CheckedInt<T> operator OP(U lhs, const CheckedInt<T> &rhs) \
+{                                                             \
+    return cast_to_CheckedInt<T>(lhs) OP rhs;                    \
+}
+
+CHECKEDINT_CONVENIENCE_BINARY_OPERATORS(+, +=)
+CHECKEDINT_CONVENIENCE_BINARY_OPERATORS(*, *=)
+CHECKEDINT_CONVENIENCE_BINARY_OPERATORS(-, -=)
+CHECKEDINT_CONVENIENCE_BINARY_OPERATORS(/, /=)
+
+template<typename T, typename U>
+inline bool operator ==(const CheckedInt<T> &lhs, U rhs)
+{
+    return lhs == cast_to_CheckedInt<T>(rhs);
+}
+
+template<typename T, typename U>
+inline bool operator ==(U  lhs, const CheckedInt<T> &rhs)
+{
+    return cast_to_CheckedInt<T>(lhs) == rhs;
+}
+
+// convenience typedefs.
+// the use of a macro here helps make sure that we don't let a typo slip into some of these.
+#define CHECKEDINT_MAKE_TYPEDEF(Type) \
+typedef CheckedInt<PR##Type> Checked##Type;
+
+CHECKEDINT_MAKE_TYPEDEF(Int8)
+CHECKEDINT_MAKE_TYPEDEF(Uint8)
+CHECKEDINT_MAKE_TYPEDEF(Int16)
+CHECKEDINT_MAKE_TYPEDEF(Uint16)
+CHECKEDINT_MAKE_TYPEDEF(Int32)
+CHECKEDINT_MAKE_TYPEDEF(Uint32)
+CHECKEDINT_MAKE_TYPEDEF(Int64)
+CHECKEDINT_MAKE_TYPEDEF(Uint64)
+
+} // end namespace mozilla
+
+#endif /* mozilla_CheckedInt_h */
--- a/xpcom/ds/Makefile.in
+++ b/xpcom/ds/Makefile.in
@@ -105,16 +105,17 @@ EXPORTS		= \
 		nsStaticAtom.h \
 		nsSupportsArray.h \
 		nsSupportsPrimitives.h \
 		nsVariant.h \
 		nsStringEnumerator.h \
 		nsHashPropertyBag.h \
 		nsWhitespaceTokenizer.h \
 		nsCharSeparatedTokenizer.h \
+		CheckedInt.h \
 		$(NULL)			
 
 XPIDLSRCS	= \
 		nsIAtom.idl \
 		nsIAtomService.idl \
 		nsICollection.idl \
 		nsIEnumerator.idl \
 		nsIINIParser.idl \
--- a/xpcom/tests/Makefile.in
+++ b/xpcom/tests/Makefile.in
@@ -100,16 +100,17 @@ CPP_UNIT_TESTS = \
                  TestHashtables.cpp \
                  TestID.cpp \
                  TestObserverArray.cpp \
                  TestObserverService.cpp \
                  TestPipe.cpp \
                  TestRefPtr.cpp \
                  TestSettingsAPI.cpp \
                  TestTextFormatter.cpp \
+                 TestCheckedInt.cpp \
                  TestTArray.cpp \
                  $(NULL)
 
 ifdef MOZ_MEMORY
 CPP_UNIT_TESTS += TestJemalloc.cpp
 endif
 
 # XXX Make this tests work in libxul builds.
new file mode 100644
--- /dev/null
+++ b/xpcom/tests/TestCheckedInt.cpp
@@ -0,0 +1,488 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* ***** 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 Mozilla code.
+ *
+ * The Initial Developer of the Original Code is the Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *  Benoit Jacob <bjacob@mozilla.com>
+ *
+ * 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 ***** */
+
+
+#include "CheckedInt.h"
+#include <iostream>
+
+namespace CheckedInt_test {
+
+using namespace mozilla::CheckedInt_internal;
+using mozilla::CheckedInt;
+
+int g_tests_passed = 0;
+int g_tests_failed = 0;
+
+void verify_impl_function(bool x, bool expected,
+                          const char* file, int line,
+                          int T_size, bool T_is_signed)
+{
+    if (x == expected) {
+        g_tests_passed++;
+    } else {
+        g_tests_failed++;
+        std::cerr << "Test failed at " << file << ":" << line;
+        std::cerr << " with T a ";
+        if(T_is_signed)
+            std::cerr << "signed";
+        else
+            std::cerr << "unsigned";
+        std::cerr << " " << CHAR_BIT*T_size << "-bit integer type" << std::endl;
+    }
+}
+
+#define VERIFY_IMPL(x, expected) \
+    verify_impl_function((x), (expected), __FILE__, __LINE__, sizeof(T), integer_traits<T>::is_signed)
+
+#define VERIFY(x)            VERIFY_IMPL(x, true)
+#define VERIFY_IS_FALSE(x)   VERIFY_IMPL(x, false)
+#define VERIFY_IS_VALID(x)   VERIFY_IMPL((x).valid(), true)
+#define VERIFY_IS_INVALID(x) VERIFY_IMPL((x).valid(), false)
+#define VERIFY_IS_VALID_IF(x,condition) VERIFY_IMPL((x).valid(), (condition))
+
+template<typename T, unsigned int size = sizeof(T)>
+struct test_twice_bigger_type
+{
+    static void run()
+    {
+        VERIFY(integer_traits<T>::twice_bigger_type_is_supported);
+        VERIFY(sizeof(typename integer_traits<T>::twice_bigger_type)
+                    == 2 * sizeof(T));
+        VERIFY(bool(integer_traits<
+                    typename integer_traits<T>::twice_bigger_type
+                >::is_signed) == bool(integer_traits<T>::is_signed));
+    }
+};
+
+template<typename T>
+struct test_twice_bigger_type<T, 8>
+{
+    static void run()
+    {
+        VERIFY_IS_FALSE(integer_traits<T>::twice_bigger_type_is_supported);
+    }
+};
+
+
+template<typename T>
+void test()
+{
+    static bool already_run = false;
+    if (already_run) {
+        g_tests_failed++;
+        std::cerr << "You already tested this type. Copy/paste typo??" << std::endl;
+        return;
+    }
+    already_run = true;
+
+    VERIFY(integer_traits<T>::is_supported);
+    VERIFY(integer_traits<T>::size == sizeof(T));
+    enum{ is_signed = integer_traits<T>::is_signed };
+    VERIFY(bool(is_signed) == !bool(T(-1) > T(0)));
+
+    test_twice_bigger_type<T>::run();
+
+    typedef typename integer_traits<T>::unsigned_type unsigned_T;
+
+    VERIFY(sizeof(unsigned_T) == sizeof(T));
+    VERIFY(integer_traits<unsigned_T>::is_signed == false);
+
+    CheckedInt<T> max_value(integer_traits<T>::max_value());
+    CheckedInt<T> min_value(integer_traits<T>::min_value());
+
+    // check min_value() and max_value(), since they are custom implementations and a mistake there
+    // could potentially NOT be caught by any other tests... while making everything wrong!
+
+    T bit = 1;
+    for(unsigned int i = 0; i < sizeof(T) * CHAR_BIT - 1; i++)
+    {
+        VERIFY((min_value.value() & bit) == 0);
+        bit <<= 1;
+    }
+    VERIFY((min_value.value() & bit) == (is_signed ? bit : T(0)));
+    VERIFY(max_value.value() == T(~(min_value.value())));
+
+    CheckedInt<T> zero(0);
+    CheckedInt<T> one(1);
+    CheckedInt<T> two(2);
+    CheckedInt<T> three(3);
+    CheckedInt<T> four(4);
+
+    /* addition / substraction checks */
+
+    VERIFY_IS_VALID(zero+zero);
+    VERIFY(zero+zero == zero);
+    VERIFY_IS_FALSE(zero+zero == one); // check that == doesn't always return true
+    VERIFY_IS_VALID(zero+one);
+    VERIFY(zero+one == one);
+    VERIFY_IS_VALID(one+one);
+    VERIFY(one+one == two);
+
+    CheckedInt<T> max_value_minus_one = max_value - one;
+    CheckedInt<T> max_value_minus_two = max_value - two;
+    VERIFY_IS_VALID(max_value_minus_one);
+    VERIFY_IS_VALID(max_value_minus_two);
+    VERIFY_IS_VALID(max_value_minus_one + one);
+    VERIFY_IS_VALID(max_value_minus_two + one);
+    VERIFY_IS_VALID(max_value_minus_two + two);
+    VERIFY(max_value_minus_one + one == max_value);
+    VERIFY(max_value_minus_two + one == max_value_minus_one);
+    VERIFY(max_value_minus_two + two == max_value);
+
+    VERIFY_IS_VALID(max_value + zero);
+    VERIFY_IS_VALID(max_value - zero);
+    VERIFY_IS_INVALID(max_value + one);
+    VERIFY_IS_INVALID(max_value + two);
+    VERIFY_IS_INVALID(max_value + max_value_minus_one);
+    VERIFY_IS_INVALID(max_value + max_value);
+
+    CheckedInt<T> min_value_plus_one = min_value + one;
+    CheckedInt<T> min_value_plus_two = min_value + two;
+    VERIFY_IS_VALID(min_value_plus_one);
+    VERIFY_IS_VALID(min_value_plus_two);
+    VERIFY_IS_VALID(min_value_plus_one - one);
+    VERIFY_IS_VALID(min_value_plus_two - one);
+    VERIFY_IS_VALID(min_value_plus_two - two);
+    VERIFY(min_value_plus_one - one == min_value);
+    VERIFY(min_value_plus_two - one == min_value_plus_one);
+    VERIFY(min_value_plus_two - two == min_value);
+
+    CheckedInt<T> min_value_minus_one = min_value - one;
+    VERIFY_IS_VALID(min_value + zero);
+    VERIFY_IS_VALID(min_value - zero);
+    VERIFY_IS_INVALID(min_value - one);
+    VERIFY_IS_INVALID(min_value - two);
+    VERIFY_IS_INVALID(min_value - min_value_minus_one);
+    VERIFY_IS_VALID(min_value - min_value);
+
+    CheckedInt<T> max_value_over_two = max_value / two;
+    VERIFY_IS_VALID(max_value_over_two + max_value_over_two);
+    VERIFY_IS_VALID(max_value_over_two + one);
+    VERIFY((max_value_over_two + one) - one == max_value_over_two);
+    VERIFY_IS_VALID(max_value_over_two - max_value_over_two);
+    VERIFY(max_value_over_two - max_value_over_two == zero);
+
+    CheckedInt<T> min_value_over_two = min_value / two;
+    VERIFY_IS_VALID(min_value_over_two + min_value_over_two);
+    VERIFY_IS_VALID(min_value_over_two + one);
+    VERIFY((min_value_over_two + one) - one == min_value_over_two);
+    VERIFY_IS_VALID(min_value_over_two - min_value_over_two);
+    VERIFY(min_value_over_two - min_value_over_two == zero);
+
+    VERIFY_IS_INVALID(min_value - one);
+    VERIFY_IS_INVALID(min_value - two);
+
+    if (is_signed) {
+        VERIFY_IS_INVALID(min_value + min_value);
+        VERIFY_IS_INVALID(min_value_over_two + min_value_over_two + min_value_over_two);
+        VERIFY_IS_INVALID(zero - min_value + min_value);
+        VERIFY_IS_INVALID(one - min_value + min_value);
+    }
+
+    /* unary operator- checks */
+
+    CheckedInt<T> neg_one = -one;
+    CheckedInt<T> neg_two = -two;
+
+    if (is_signed) {
+        VERIFY_IS_VALID(-max_value);
+        VERIFY_IS_VALID(-max_value - one);
+        VERIFY_IS_VALID(neg_one);
+        VERIFY_IS_VALID(-max_value + neg_one);
+        VERIFY_IS_VALID(neg_one + one);
+        VERIFY(neg_one + one == zero);
+        VERIFY_IS_VALID(neg_two);
+        VERIFY_IS_VALID(neg_one + neg_one);
+        VERIFY(neg_one + neg_one == neg_two);
+    } else {
+        VERIFY_IS_INVALID(neg_one);
+    }
+
+    /* multiplication checks */
+
+    VERIFY_IS_VALID(zero*zero);
+    VERIFY(zero*zero == zero);
+    VERIFY_IS_VALID(zero*one);
+    VERIFY(zero*one == zero);
+    VERIFY_IS_VALID(one*zero);
+    VERIFY(one*zero == zero);
+    VERIFY_IS_VALID(one*one);
+    VERIFY(one*one == one);
+    VERIFY_IS_VALID(one*three);
+    VERIFY(one*three == three);
+    VERIFY_IS_VALID(two*two);
+    VERIFY(two*two == four);
+
+    VERIFY_IS_INVALID(max_value * max_value);
+    VERIFY_IS_INVALID(max_value_over_two * max_value);
+    VERIFY_IS_INVALID(max_value_over_two * max_value_over_two);
+
+    CheckedInt<T> max_value_approx_sqrt(T(T(1) << (CHAR_BIT*sizeof(T)/2)));
+
+    VERIFY_IS_VALID(max_value_approx_sqrt);
+    VERIFY_IS_VALID(max_value_approx_sqrt * two);
+    VERIFY_IS_INVALID(max_value_approx_sqrt * max_value_approx_sqrt);
+    VERIFY_IS_INVALID(max_value_approx_sqrt * max_value_approx_sqrt * max_value_approx_sqrt);
+
+    if (is_signed) {
+        VERIFY_IS_INVALID(min_value * min_value);
+        VERIFY_IS_INVALID(min_value_over_two * min_value);
+        VERIFY_IS_INVALID(min_value_over_two * min_value_over_two);
+
+        CheckedInt<T> min_value_approx_sqrt = -max_value_approx_sqrt;
+
+        VERIFY_IS_VALID(min_value_approx_sqrt);
+        VERIFY_IS_VALID(min_value_approx_sqrt * two);
+        VERIFY_IS_INVALID(min_value_approx_sqrt * max_value_approx_sqrt);
+        VERIFY_IS_INVALID(min_value_approx_sqrt * min_value_approx_sqrt);
+    }
+
+    // make sure to check all 4 paths in signed multiplication validity check.
+    // test positive * positive
+    VERIFY_IS_VALID(max_value * one);
+    VERIFY(max_value * one == max_value);
+    VERIFY_IS_INVALID(max_value * two);
+    VERIFY_IS_VALID(max_value_over_two * two);
+    VERIFY((max_value_over_two + max_value_over_two) == (max_value_over_two * two));
+
+    if (is_signed) {
+        // test positive * negative
+        VERIFY_IS_VALID(max_value * neg_one);
+        VERIFY_IS_VALID(-max_value);
+        VERIFY(max_value * neg_one == -max_value);
+        VERIFY_IS_VALID(one * min_value);
+        VERIFY_IS_INVALID(max_value * neg_two);
+        VERIFY_IS_VALID(max_value_over_two * neg_two);
+        VERIFY_IS_VALID(two * min_value_over_two);
+        VERIFY_IS_VALID((max_value_over_two + one) * neg_two);
+        VERIFY_IS_INVALID((max_value_over_two + two) * neg_two);
+        VERIFY_IS_INVALID(two * (min_value_over_two - one));
+
+        // test negative * positive
+        VERIFY_IS_VALID(min_value * one);
+        VERIFY_IS_VALID(min_value_plus_one * one);
+        VERIFY_IS_INVALID(min_value * two);
+        VERIFY_IS_VALID(min_value_over_two * two);
+        VERIFY(min_value_over_two * two == min_value);
+        VERIFY_IS_INVALID((min_value_over_two - one) * neg_two);
+        VERIFY_IS_INVALID(neg_two * max_value);
+        VERIFY_IS_VALID(min_value_over_two * two);
+        VERIFY(min_value_over_two * two == min_value);
+        VERIFY_IS_VALID(neg_two * max_value_over_two);
+        VERIFY_IS_INVALID((min_value_over_two - one) * two);
+        VERIFY_IS_VALID(neg_two * (max_value_over_two + one));
+        VERIFY_IS_INVALID(neg_two * (max_value_over_two + two));
+
+        // test negative * negative
+        VERIFY_IS_INVALID(min_value * neg_one);
+        VERIFY_IS_VALID(min_value_plus_one * neg_one);
+        VERIFY(min_value_plus_one * neg_one == max_value);
+        VERIFY_IS_INVALID(min_value * neg_two);
+        VERIFY_IS_INVALID(min_value_over_two * neg_two);
+        VERIFY_IS_INVALID(neg_one * min_value);
+        VERIFY_IS_VALID(neg_one * min_value_plus_one);
+        VERIFY(neg_one * min_value_plus_one == max_value);
+        VERIFY_IS_INVALID(neg_two * min_value);
+        VERIFY_IS_INVALID(neg_two * min_value_over_two);
+    }
+
+    /* division checks */
+
+    VERIFY_IS_VALID(one / one);
+    VERIFY(one / one == one);
+    VERIFY_IS_VALID(three / three);
+    VERIFY(three / three == one);
+    VERIFY_IS_VALID(four / two);
+    VERIFY(four / two == two);
+    VERIFY((four*three)/four == three);
+
+    // check that div by zero is invalid
+    VERIFY_IS_INVALID(zero / zero);
+    VERIFY_IS_INVALID(one / zero);
+    VERIFY_IS_INVALID(two / zero);
+    VERIFY_IS_INVALID(neg_one / zero);
+    VERIFY_IS_INVALID(max_value / zero);
+    VERIFY_IS_INVALID(min_value / zero);
+
+    if (is_signed) {
+        // check that min_value / -1 is invalid
+        VERIFY_IS_INVALID(min_value / neg_one);
+
+        // check that the test for div by -1 isn't banning other numerators than min_value
+        VERIFY_IS_VALID(one / neg_one);
+        VERIFY_IS_VALID(zero / neg_one);
+        VERIFY_IS_VALID(neg_one / neg_one);
+        VERIFY_IS_VALID(max_value / neg_one);
+    }
+
+    /* check that invalidity is correctly preserved by arithmetic ops */
+
+    CheckedInt<T> some_invalid = max_value + max_value;
+    VERIFY_IS_INVALID(some_invalid + zero);
+    VERIFY_IS_INVALID(some_invalid - zero);
+    VERIFY_IS_INVALID(zero + some_invalid);
+    VERIFY_IS_INVALID(zero - some_invalid);
+    VERIFY_IS_INVALID(-some_invalid);
+    VERIFY_IS_INVALID(some_invalid * zero);
+    VERIFY_IS_INVALID(some_invalid * one);
+    VERIFY_IS_INVALID(zero * some_invalid);
+    VERIFY_IS_INVALID(one * some_invalid);
+    VERIFY_IS_INVALID(some_invalid / zero);
+    VERIFY_IS_INVALID(some_invalid / one);
+    VERIFY_IS_INVALID(zero / some_invalid);
+    VERIFY_IS_INVALID(one / some_invalid);
+    VERIFY_IS_INVALID(some_invalid + some_invalid);
+    VERIFY_IS_INVALID(some_invalid - some_invalid);
+    VERIFY_IS_INVALID(some_invalid * some_invalid);
+    VERIFY_IS_INVALID(some_invalid / some_invalid);
+
+    /* check that mixing checked integers with plain integers in expressions is allowed */
+
+    VERIFY(one + T(2) == three);
+    VERIFY(2 + one == three);
+    {
+        CheckedInt<T> x = one;
+        x += 2;
+        VERIFY(x == three);
+    }
+    VERIFY(two - 1 == one);
+    VERIFY(2 - one == one);
+    {
+        CheckedInt<T> x = two;
+        x -= 1;
+        VERIFY(x == one);
+    }
+    VERIFY(one * 2 == two);
+    VERIFY(2 * one == two);
+    {
+        CheckedInt<T> x = one;
+        x *= 2;
+        VERIFY(x == two);
+    }
+    VERIFY(four / 2 == two);
+    VERIFY(4 / two == two);
+    {
+        CheckedInt<T> x = four;
+        x /= 2;
+        VERIFY(x == two);
+    }
+
+    VERIFY(one == 1);
+    VERIFY(1 == one);
+    VERIFY_IS_FALSE(two == 1);
+    VERIFY_IS_FALSE(1 == two);
+    VERIFY_IS_FALSE(some_invalid == 1);
+    VERIFY_IS_FALSE(1 == some_invalid);
+
+    /* Check that construction of CheckedInt from an integer value of a mismatched type is checked */
+
+    #define VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE(U) \
+    { \
+        bool is_U_signed = integer_traits<U>::is_signed; \
+        VERIFY_IS_VALID(CheckedInt<T>(U(0))); \
+        VERIFY_IS_VALID(CheckedInt<T>(U(1))); \
+        VERIFY_IS_VALID(CheckedInt<T>(U(100))); \
+        if (is_U_signed) \
+            VERIFY_IS_VALID_IF(CheckedInt<T>(U(-1)), is_signed); \
+        if (sizeof(U) > sizeof(T)) \
+            VERIFY_IS_INVALID(CheckedInt<T>(U(integer_traits<T>::max_value())+1)); \
+        VERIFY_IS_VALID_IF(CheckedInt<T>(integer_traits<U>::max_value()), \
+            (sizeof(T) > sizeof(U) || ((sizeof(T) == sizeof(U)) && (is_U_signed || !is_signed)))); \
+        VERIFY_IS_VALID_IF(CheckedInt<T>(integer_traits<U>::min_value()), \
+            is_U_signed == false ? 1 : \
+            bool(is_signed) == false ? 0 : \
+            sizeof(T) >= sizeof(U)); \
+    }
+    VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE(PRInt8)
+    VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE(PRUint8)
+    VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE(PRInt16)
+    VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE(PRUint16)
+    VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE(PRInt32)
+    VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE(PRUint32)
+    VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE(PRInt64)
+    VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE(PRUint64)
+
+    /* Test increment/decrement operators */
+
+    CheckedInt<T> x, y;
+    x = one;
+    y = x++;
+    VERIFY(x == two);
+    VERIFY(y == one);
+    x = one;
+    y = ++x;
+    VERIFY(x == two);
+    VERIFY(y == two);
+    x = one;
+    y = x--;
+    VERIFY(x == zero);
+    VERIFY(y == one);
+    x = one;
+    y = --x;
+    VERIFY(x == zero);
+    VERIFY(y == zero);
+    x = max_value;
+    VERIFY_IS_VALID(x++);
+    x = max_value;
+    VERIFY_IS_INVALID(++x);
+    x = min_value;
+    VERIFY_IS_VALID(x--);
+    x = min_value;
+    VERIFY_IS_INVALID(--x);
+}
+
+} // end namespace CheckedInt_test
+
+int main()
+{
+    CheckedInt_test::test<PRInt8>();
+    CheckedInt_test::test<PRUint8>();
+    CheckedInt_test::test<PRInt16>();
+    CheckedInt_test::test<PRUint16>();
+    CheckedInt_test::test<PRInt32>();
+    CheckedInt_test::test<PRUint32>();
+    CheckedInt_test::test<PRInt64>();
+    CheckedInt_test::test<PRUint64>();
+
+    std::cerr << CheckedInt_test::g_tests_failed << " tests failed, "
+              << CheckedInt_test::g_tests_passed << " tests passed out of "
+              << CheckedInt_test::g_tests_failed + CheckedInt_test::g_tests_passed
+              << " tests." << std::endl;
+
+    return CheckedInt_test::g_tests_failed > 0;
+}