Index: trunk/src/com/drew/lang/BufferBoundsException.java
===================================================================
--- trunk/src/com/drew/lang/BufferBoundsException.java	(revision 8243)
+++ trunk/src/com/drew/lang/BufferBoundsException.java	(revision 10862)
@@ -1,4 +1,4 @@
 /*
- * Copyright 2002-2015 Drew Noakes
+ * Copyright 2002-2016 Drew Noakes
  *
  *    Licensed under the Apache License, Version 2.0 (the "License");
Index: trunk/src/com/drew/lang/ByteArrayReader.java
===================================================================
--- trunk/src/com/drew/lang/ByteArrayReader.java	(revision 8243)
+++ trunk/src/com/drew/lang/ByteArrayReader.java	(revision 10862)
@@ -1,4 +1,4 @@
 /*
- * Copyright 2002-2015 Drew Noakes
+ * Copyright 2002-2016 Drew Noakes
  *
  *    Licensed under the Apache License, Version 2.0 (the "License");
@@ -22,7 +22,7 @@
 package com.drew.lang;
 
+import java.io.IOException;
+
 import com.drew.lang.annotations.NotNull;
-
-import java.io.IOException;
 
 /**
@@ -40,6 +40,4 @@
     private final byte[] _buffer;
 
-    @SuppressWarnings({ "ConstantConditions" })
-    @com.drew.lang.annotations.SuppressWarnings(value = "EI_EXPOSE_REP2", justification = "Design intent")
     public ByteArrayReader(@NotNull byte[] buffer)
     {
@@ -74,5 +72,5 @@
         return bytesRequested >= 0
             && index >= 0
-            && (long)index + (long)bytesRequested - 1L < (long)_buffer.length;
+            && (long)index + (long)bytesRequested - 1L < _buffer.length;
     }
 
Index: trunk/src/com/drew/lang/CompoundException.java
===================================================================
--- trunk/src/com/drew/lang/CompoundException.java	(revision 8243)
+++ trunk/src/com/drew/lang/CompoundException.java	(revision 10862)
@@ -1,4 +1,4 @@
 /*
- * Copyright 2002-2015 Drew Noakes
+ * Copyright 2002-2016 Drew Noakes
  *
  *    Licensed under the Apache License, Version 2.0 (the "License");
Index: trunk/src/com/drew/lang/DateUtil.java
===================================================================
--- trunk/src/com/drew/lang/DateUtil.java	(revision 10862)
+++ trunk/src/com/drew/lang/DateUtil.java	(revision 10862)
@@ -0,0 +1,32 @@
+package com.drew.lang;
+
+/**
+ * @author Drew Noakes http://drewnoakes.com
+ */
+public class DateUtil
+{
+    private static int[] _daysInMonth365 = new int[] {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
+
+    public static boolean isValidDate(int year, int month, int day)
+    {
+        if (year < 1 || year > 9999 || month < 0 || month > 11)
+            return false;
+
+        int daysInMonth = _daysInMonth365[month];
+        if (month == 1)
+        {
+            boolean isLeapYear = year % 4 == 0 && (year % 100 != 0 || year % 400 == 0);
+            if (isLeapYear)
+                daysInMonth++;
+        }
+
+        return day >= 1 && day <= daysInMonth;
+    }
+
+    public static boolean isValidTime(int hours, int minutes, int seconds)
+    {
+        return hours >= 0 && hours < 24
+            && minutes >= 0 && minutes < 60
+            && seconds >= 0 && seconds < 60;
+    }
+}
Index: trunk/src/com/drew/lang/GeoLocation.java
===================================================================
--- trunk/src/com/drew/lang/GeoLocation.java	(revision 8243)
+++ trunk/src/com/drew/lang/GeoLocation.java	(revision 10862)
@@ -1,4 +1,4 @@
 /*
- * Copyright 2002-2015 Drew Noakes
+ * Copyright 2002-2016 Drew Noakes
  *
  *    Licensed under the Apache License, Version 2.0 (the "License");
@@ -84,5 +84,5 @@
         double[] dms = decimalToDegreesMinutesSeconds(decimal);
         DecimalFormat format = new DecimalFormat("0.##");
-        return String.format("%s° %s' %s\"", format.format(dms[0]), format.format(dms[1]), format.format(dms[2]));
+        return String.format("%s\u00B0 %s' %s\"", format.format(dms[0]), format.format(dms[1]), format.format(dms[2]));
     }
 
Index: trunk/src/com/drew/lang/NullOutputStream.java
===================================================================
--- trunk/src/com/drew/lang/NullOutputStream.java	(revision 8243)
+++ 	(revision )
@@ -1,43 +1,0 @@
-/*
- * Copyright 2002-2015 Drew Noakes
- *
- *    Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
- *
- *    Unless required by applicable law or agreed to in writing, software
- *    distributed under the License is distributed on an "AS IS" BASIS,
- *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *    See the License for the specific language governing permissions and
- *    limitations under the License.
- *
- * More information about this project is available at:
- *
- *    https://drewnoakes.com/code/exif/
- *    https://github.com/drewnoakes/metadata-extractor
- */
-package com.drew.lang;
-
-import java.io.IOException;
-import java.io.OutputStream;
-
-/**
- * An implementation of OutputSteam that ignores write requests by doing nothing.  This class may be useful in tests.
- *
- * @author Drew Noakes https://drewnoakes.com
- */
-public class NullOutputStream extends OutputStream
-{
-    public NullOutputStream()
-    {
-        super();
-    }
-
-    @Override
-    public void write(int b) throws IOException
-    {
-        // do nothing
-    }
-}
Index: trunk/src/com/drew/lang/RandomAccessReader.java
===================================================================
--- trunk/src/com/drew/lang/RandomAccessReader.java	(revision 8243)
+++ trunk/src/com/drew/lang/RandomAccessReader.java	(revision 10862)
@@ -1,4 +1,4 @@
 /*
- * Copyright 2002-2015 Drew Noakes
+ * Copyright 2002-2016 Drew Noakes
  *
  *    Licensed under the Apache License, Version 2.0 (the "License");
@@ -53,5 +53,5 @@
      * @param index The index from which to read the byte
      * @return The read byte value
-     * @throws IllegalArgumentException <code>index</code> or <code>count</code> are negative
+     * @throws IllegalArgumentException <code>index</code> is negative
      * @throws BufferBoundsException if the requested byte is beyond the end of the underlying data source
      * @throws IOException if the byte is unable to be read
Index: trunk/src/com/drew/lang/Rational.java
===================================================================
--- trunk/src/com/drew/lang/Rational.java	(revision 8243)
+++ trunk/src/com/drew/lang/Rational.java	(revision 10862)
@@ -1,4 +1,4 @@
 /*
- * Copyright 2002-2015 Drew Noakes
+ * Copyright 2002-2016 Drew Noakes
  *
  *    Licensed under the Apache License, Version 2.0 (the "License");
Index: trunk/src/com/drew/lang/SequentialByteArrayReader.java
===================================================================
--- trunk/src/com/drew/lang/SequentialByteArrayReader.java	(revision 8243)
+++ trunk/src/com/drew/lang/SequentialByteArrayReader.java	(revision 10862)
@@ -1,4 +1,4 @@
 /*
- * Copyright 2002-2015 Drew Noakes
+ * Copyright 2002-2016 Drew Noakes
  *
  *    Licensed under the Apache License, Version 2.0 (the "License");
@@ -42,5 +42,4 @@
     }
 
-    @SuppressWarnings("ConstantConditions")
     public SequentialByteArrayReader(@NotNull byte[] bytes, int baseIndex)
     {
Index: trunk/src/com/drew/lang/SequentialReader.java
===================================================================
--- trunk/src/com/drew/lang/SequentialReader.java	(revision 8243)
+++ trunk/src/com/drew/lang/SequentialReader.java	(revision 10862)
@@ -1,4 +1,4 @@
 /*
- * Copyright 2002-2015 Drew Noakes
+ * Copyright 2002-2016 Drew Noakes
  *
  *    Licensed under the Apache License, Version 2.0 (the "License");
Index: trunk/src/com/drew/lang/StreamReader.java
===================================================================
--- trunk/src/com/drew/lang/StreamReader.java	(revision 8243)
+++ trunk/src/com/drew/lang/StreamReader.java	(revision 10862)
@@ -1,4 +1,4 @@
 /*
- * Copyright 2002-2015 Drew Noakes
+ * Copyright 2002-2016 Drew Noakes
  *
  *    Licensed under the Apache License, Version 2.0 (the "License");
@@ -37,5 +37,4 @@
     private final InputStream _stream;
 
-    @SuppressWarnings("ConstantConditions")
     public StreamReader(@NotNull InputStream stream)
     {
Index: trunk/src/com/drew/lang/StringUtil.java
===================================================================
--- trunk/src/com/drew/lang/StringUtil.java	(revision 8243)
+++ trunk/src/com/drew/lang/StringUtil.java	(revision 10862)
@@ -1,4 +1,4 @@
 /*
- * Copyright 2002-2015 Drew Noakes
+ * Copyright 2002-2016 Drew Noakes
  *
  *    Licensed under the Apache License, Version 2.0 (the "License");
Index: trunk/src/com/drew/lang/annotations/NotNull.java
===================================================================
--- trunk/src/com/drew/lang/annotations/NotNull.java	(revision 8243)
+++ trunk/src/com/drew/lang/annotations/NotNull.java	(revision 10862)
@@ -1,4 +1,4 @@
 /*
- * Copyright 2002-2015 Drew Noakes
+ * Copyright 2002-2016 Drew Noakes
  *
  *    Licensed under the Apache License, Version 2.0 (the "License");
Index: trunk/src/com/drew/lang/annotations/Nullable.java
===================================================================
--- trunk/src/com/drew/lang/annotations/Nullable.java	(revision 8243)
+++ trunk/src/com/drew/lang/annotations/Nullable.java	(revision 10862)
@@ -1,4 +1,4 @@
 /*
- * Copyright 2002-2015 Drew Noakes
+ * Copyright 2002-2016 Drew Noakes
  *
  *    Licensed under the Apache License, Version 2.0 (the "License");
Index: trunk/src/com/drew/lang/annotations/SuppressWarnings.java
===================================================================
--- trunk/src/com/drew/lang/annotations/SuppressWarnings.java	(revision 8243)
+++ 	(revision )
@@ -1,42 +1,0 @@
-/*
- * Copyright 2002-2011 Andreas Ziermann
- *
- *    Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
- *
- *    Unless required by applicable law or agreed to in writing, software
- *    distributed under the License is distributed on an "AS IS" BASIS,
- *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *    See the License for the specific language governing permissions and
- *    limitations under the License.
- *
- * More information about this project is available at:
- *
- *    https://drewnoakes.com/code/exif/
- *    https://github.com/drewnoakes/metadata-extractor
- */
-
-package com.drew.lang.annotations;
-
-/**
- * Used to suppress specific code analysis warnings produced by the Findbugs tool.
- *
- * @author Andreas Ziermann
- */
-public @interface SuppressWarnings
-{
-    /**
-     * The name of the warning to be suppressed.
-     * @return The name of the warning to be suppressed.
-     */
-    @NotNull String value();
-
-    /**
-     * An explanation of why it is valid to suppress the warning in a particular situation/context.
-     * @return An explanation of why it is valid to suppress the warning in a particular situation/context.
-     */
-    @NotNull String justification();
-}
Index: trunk/src/com/drew/lang/annotations/package.html
===================================================================
--- trunk/src/com/drew/lang/annotations/package.html	(revision 8243)
+++ trunk/src/com/drew/lang/annotations/package.html	(revision 10862)
@@ -1,4 +1,4 @@
 <!--
-  ~ Copyright 2002-2015 Drew Noakes
+  ~ Copyright 2002-2016 Drew Noakes
   ~
   ~    Licensed under the Apache License, Version 2.0 (the "License");
Index: trunk/src/com/drew/lang/package.html
===================================================================
--- trunk/src/com/drew/lang/package.html	(revision 8243)
+++ trunk/src/com/drew/lang/package.html	(revision 10862)
@@ -1,4 +1,4 @@
 <!--
-  ~ Copyright 2002-2015 Drew Noakes
+  ~ Copyright 2002-2016 Drew Noakes
   ~
   ~    Licensed under the Apache License, Version 2.0 (the "License");
