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 96176 3f7291bc4efc003964fb98b1390019771042f3ac
parent 96175 345ae68f15f4bbd6f0a669f8d8bba0fe2fa6889a
child 96177 ff13f71571591493b19c29ddae3403a33c7f0686
push id1439
push userlsblakk@mozilla.com
push dateMon, 04 Jun 2012 20:19:22 +0000
treeherdermozilla-aurora@ea74834dccd3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs732875
milestone15.0a1
backs out345ae68f15f4bbd6f0a669f8d8bba0fe2fa6889a
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;
+}