Index: trunk/src/com/drew/lang/BufferBoundsException.java
===================================================================
--- trunk/src/com/drew/lang/BufferBoundsException.java	(revision 6127)
+++ trunk/src/com/drew/lang/BufferBoundsException.java	(revision 8132)
@@ -1,4 +1,4 @@
 /*
- * Copyright 2002-2012 Drew Noakes
+ * Copyright 2002-2015 Drew Noakes
  *
  *    Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,26 +16,24 @@
  * More information about this project is available at:
  *
- *    http://drewnoakes.com/code/exif/
- *    http://code.google.com/p/metadata-extractor/
+ *    https://drewnoakes.com/code/exif/
+ *    https://github.com/drewnoakes/metadata-extractor
  */
 
 package com.drew.lang;
 
-import com.drew.lang.annotations.NotNull;
-
 import java.io.IOException;
 
 /**
- * A checked replacement for IndexOutOfBoundsException.  Used by BufferReader.
- * 
- * @author Drew Noakes http://drewnoakes.com
+ * A checked replacement for {@link IndexOutOfBoundsException}.  Used by {@link RandomAccessReader}.
+ *
+ * @author Drew Noakes https://drewnoakes.com
  */
-public final class BufferBoundsException extends Exception
+public final class BufferBoundsException extends IOException
 {
     private static final long serialVersionUID = 2911102837808946396L;
 
-    public BufferBoundsException(@NotNull byte[] buffer, int index, int bytesRequested)
+    public BufferBoundsException(int index, int bytesRequested, long bufferLength)
     {
-        super(getMessage(buffer, index, bytesRequested));
+        super(getMessage(index, bytesRequested, bufferLength));
     }
 
@@ -45,16 +43,17 @@
     }
 
-    public BufferBoundsException(final String message, final IOException innerException)
-    {
-        super(message, innerException);
-    }
-
-    private static String getMessage(@NotNull byte[] buffer, int index, int bytesRequested)
+    private static String getMessage(int index, int bytesRequested, long bufferLength)
     {
         if (index < 0)
-            return String.format("Attempt to read from buffer using a negative index (%s)", index);
+            return String.format("Attempt to read from buffer using a negative index (%d)", index);
 
-        return String.format("Attempt to read %d byte%s from beyond end of buffer (requested index: %d, max index: %d)",
-                bytesRequested, bytesRequested==1?"":"s", index, buffer.length - 1);
+        if (bytesRequested < 0)
+            return String.format("Number of requested bytes cannot be negative (%d)", bytesRequested);
+
+        if ((long)index + (long)bytesRequested - 1L > (long)Integer.MAX_VALUE)
+            return String.format("Number of requested bytes summed with starting index exceed maximum range of signed 32 bit integers (requested index: %d, requested count: %d)", index, bytesRequested);
+
+        return String.format("Attempt to read from beyond end of underlying data source (requested index: %d, requested count: %d, max index: %d)",
+                index, bytesRequested, bufferLength - 1);
     }
 }
