Fix [JACKSON-709] for 1.9.x as well

diff --git a/release-notes/CREDITS b/release-notes/CREDITS
index 11b4d89..6eba2ec 100644
--- a/release-notes/CREDITS
+++ b/release-notes/CREDITS
@@ -733,6 +733,26 @@
     "Internal Error"
    [1.8.4]
 
+Paul Marynchev:
+  * Reported [JACKSON-637] NumberSerializer was missing proper handling of
+    Integer, Long
+   [1.8.5]
+
+Ransom Briggs:
+  * Reported [JACKSON-668] Problems with 'JsonParser.getDecimalValue'
+    not clearing earlier state
+   [1.8.6]
+
+William Burns:
+  * Reported [JACKSON-677], suggested fix for: Inner generic type references
+    not working properly
+   [1.8.6]
+
+Tom Boettcher:
+  * Reported [JACKSON-709] Problems converting base64-encoded Strings
+    between JsonNode, POJOs
+   [1.8.7]
+
 Anand Hatrwalne:
   * Requested [JACKSON-558] Add 'DeserializationConfig.Feature.UNWRAP_ROOT_VALUE' as
     matching counterpart for 'SerializationConfig.Feature.WRAP_ROOT_VALUE'
diff --git a/src/java/org/codehaus/jackson/impl/JsonParserBase.java b/src/java/org/codehaus/jackson/impl/JsonParserBase.java
index 93665d4..686a6d8 100644
--- a/src/java/org/codehaus/jackson/impl/JsonParserBase.java
+++ b/src/java/org/codehaus/jackson/impl/JsonParserBase.java
@@ -432,8 +432,6 @@
     protected abstract void _finishString() throws IOException, JsonParseException;
 
     protected abstract void _closeInput() throws IOException;
-
-    protected abstract byte[] _decodeBase64(Base64Variant b64variant) throws IOException, JsonParseException;
     
     /*
     /**********************************************************
diff --git a/src/java/org/codehaus/jackson/impl/JsonParserMinimalBase.java b/src/java/org/codehaus/jackson/impl/JsonParserMinimalBase.java
index 8d09c1d..1e5f6d0 100644
--- a/src/java/org/codehaus/jackson/impl/JsonParserMinimalBase.java
+++ b/src/java/org/codehaus/jackson/impl/JsonParserMinimalBase.java
@@ -5,11 +5,16 @@
 import org.codehaus.jackson.*;
 import org.codehaus.jackson.JsonParser.Feature;
 import org.codehaus.jackson.io.NumberInput;
+import org.codehaus.jackson.util.ByteArrayBuilder;
 
 /**
  * Intermediate base class used by all Jackson {@link JsonParser}
  * implementations, but does not add any additional fields that depend
  * on particular method of obtaining input.
+ *<p>
+ * Note that 'minimal' here mostly refers to minimal number of fields
+ * (size) and functionality that is specific to certain types
+ * of parser implementations; but not necessarily to number of methods.
  * 
  * @since 1.6
  *
@@ -292,10 +297,141 @@
 
     /*
     /**********************************************************
-    /* Error reporting
+    /* Base64 decoding
     /**********************************************************
      */
 
+    /**
+     * Helper method that can be used for base64 decoding in cases where
+     * encoded content has already been read as a String.
+     * 
+     * @since 1.9.3
+     */
+    protected void _decodeBase64(String str, ByteArrayBuilder builder, Base64Variant b64variant)
+        throws IOException, JsonParseException
+    {
+        int ptr = 0;
+        int len = str.length();
+        
+        main_loop:
+        while (ptr < len) {
+            // first, we'll skip preceding white space, if any
+            char ch;
+            do {
+                ch = str.charAt(ptr++);
+                if (ptr >= len) {
+                    break main_loop;
+                }
+            } while (ch <= INT_SPACE);
+            int bits = b64variant.decodeBase64Char(ch);
+            if (bits < 0) {
+                _reportInvalidBase64(b64variant, ch, 0, null);
+            }
+            int decodedData = bits;
+            // then second base64 char; can't get padding yet, nor ws
+            if (ptr >= len) {
+                _reportBase64EOF();
+            }
+            ch = str.charAt(ptr++);
+            bits = b64variant.decodeBase64Char(ch);
+            if (bits < 0) {
+                _reportInvalidBase64(b64variant, ch, 1, null);
+            }
+            decodedData = (decodedData << 6) | bits;
+            // third base64 char; can be padding, but not ws
+            if (ptr >= len) {
+                // but as per [JACKSON-631] can be end-of-input, iff not using padding
+                if (!b64variant.usesPadding()) {
+                    decodedData >>= 4;
+                    builder.append(decodedData);
+                    break;
+                }
+                _reportBase64EOF();
+            }
+            ch = str.charAt(ptr++);
+            bits = b64variant.decodeBase64Char(ch);
+            
+            // First branch: can get padding (-> 1 byte)
+            if (bits < 0) {
+                if (bits != Base64Variant.BASE64_VALUE_PADDING) {
+                    _reportInvalidBase64(b64variant, ch, 2, null);
+                }
+                // Ok, must get padding
+                if (ptr >= len) {
+                    _reportBase64EOF();
+                }
+                ch = str.charAt(ptr++);
+                if (!b64variant.usesPaddingChar(ch)) {
+                    _reportInvalidBase64(b64variant, ch, 3, "expected padding character '"+b64variant.getPaddingChar()+"'");
+                }
+                // Got 12 bits, only need 8, need to shift
+                decodedData >>= 4;
+                builder.append(decodedData);
+                continue;
+            }
+            // Nope, 2 or 3 bytes
+            decodedData = (decodedData << 6) | bits;
+            // fourth and last base64 char; can be padding, but not ws
+            if (ptr >= len) {
+                // but as per [JACKSON-631] can be end-of-input, iff not using padding
+                if (!b64variant.usesPadding()) {
+                    decodedData >>= 2;
+                    builder.appendTwoBytes(decodedData);
+                    break;
+                }
+                _reportBase64EOF();
+            }
+            ch = str.charAt(ptr++);
+            bits = b64variant.decodeBase64Char(ch);
+            if (bits < 0) {
+                if (bits != Base64Variant.BASE64_VALUE_PADDING) {
+                    _reportInvalidBase64(b64variant, ch, 3, null);
+                }
+                decodedData >>= 2;
+                builder.appendTwoBytes(decodedData);
+            } else {
+                // otherwise, our triple is now complete
+                decodedData = (decodedData << 6) | bits;
+                builder.appendThreeBytes(decodedData);
+            }
+        }
+    }
+
+    /**
+     * @param bindex Relative index within base64 character unit; between 0
+     *   and 3 (as unit has exactly 4 characters)
+     */
+    protected void _reportInvalidBase64(Base64Variant b64variant, char ch, int bindex, String msg)
+        throws JsonParseException
+    {
+        String base;
+        if (ch <= INT_SPACE) {
+            base = "Illegal white space character (code 0x"+Integer.toHexString(ch)+") as character #"+(bindex+1)+" of 4-char base64 unit: can only used between units";
+        } else if (b64variant.usesPaddingChar(ch)) {
+            base = "Unexpected padding character ('"+b64variant.getPaddingChar()+"') as character #"+(bindex+1)+" of 4-char base64 unit: padding only legal as 3rd or 4th character";
+        } else if (!Character.isDefined(ch) || Character.isISOControl(ch)) {
+            // Not sure if we can really get here... ? (most illegal xml chars are caught at lower level)
+            base = "Illegal character (code 0x"+Integer.toHexString(ch)+") in base64 content";
+        } else {
+            base = "Illegal character '"+ch+"' (code 0x"+Integer.toHexString(ch)+") in base64 content";
+        }
+        if (msg != null) {
+            base = base + ": " + msg;
+        }
+        throw _constructError(base);
+    }
+
+    protected void _reportBase64EOF() throws JsonParseException {
+        throw _constructError("Unexpected end-of-String in base64 content");
+    }
+    
+    
+    /*
+    /**********************************************************
+    /* Error reporting
+    /**********************************************************
+     */
+    
     protected void _reportUnexpectedChar(int ch, String comment)
         throws JsonParseException
     {
diff --git a/src/java/org/codehaus/jackson/impl/ReaderBasedParser.java b/src/java/org/codehaus/jackson/impl/ReaderBasedParser.java
index 3e215df..a6b07ff 100644
--- a/src/java/org/codehaus/jackson/impl/ReaderBasedParser.java
+++ b/src/java/org/codehaus/jackson/impl/ReaderBasedParser.java
@@ -329,7 +329,13 @@
              * textual content in error cases
              */
             _tokenIncomplete = false;
-        }        
+        } else { // may actually require conversion...
+            if (_binaryValue == null) {
+                ByteArrayBuilder builder = _getByteArrayBuilder();
+                _decodeBase64(getText(), builder, b64variant);
+                _binaryValue = builder.toByteArray();
+            }
+        }
         return _binaryValue;
     }
     
@@ -1664,7 +1670,10 @@
     /**********************************************************
      */
 
-    @Override
+    /**
+     * Efficient handling for incremental parsing of base64-encoded
+     * textual content.
+     */
     protected byte[] _decodeBase64(Base64Variant b64variant)
         throws IOException, JsonParseException
     {
@@ -1757,12 +1766,11 @@
                     bits = _decodeBase64Escape(b64variant, ch, 3);
                 }
                 if (bits == Base64Variant.BASE64_VALUE_PADDING) {
-                    /* With padding we only get 2 bytes; but we have
-                     * to shift it a bit so it is identical to triplet
-                     * case with partial output.
-                     * 3 chars gives 3x6 == 18 bits, of which 2 are
-                     * dummies, need to discard:
-                     */
+                    // With padding we only get 2 bytes; but we have
+                    // to shift it a bit so it is identical to triplet
+                    // case with partial output.
+                    // 3 chars gives 3x6 == 18 bits, of which 2 are
+                    // dummies, need to discard:
                     decodedData >>= 2;
                     builder.appendTwoBytes(decodedData);
                     continue;
diff --git a/src/java/org/codehaus/jackson/impl/Utf8StreamParser.java b/src/java/org/codehaus/jackson/impl/Utf8StreamParser.java
index 5de0a8f..00527ed 100644
--- a/src/java/org/codehaus/jackson/impl/Utf8StreamParser.java
+++ b/src/java/org/codehaus/jackson/impl/Utf8StreamParser.java
@@ -405,7 +405,13 @@
              * textual content in error cases
              */
             _tokenIncomplete = false;
-        }        
+        } else { // may actually require conversion...
+            if (_binaryValue == null) {
+                ByteArrayBuilder builder = _getByteArrayBuilder();
+                _decodeBase64(getText(), builder, b64variant);
+                _binaryValue = builder.toByteArray();
+            }
+        }
         return _binaryValue;
     }
     
@@ -2827,7 +2833,10 @@
     /**********************************************************
      */
 
-    @Override
+    /**
+     * Efficient handling for incremental parsing of base64-encoded
+     * textual content.
+     */
     protected byte[] _decodeBase64(Base64Variant b64variant)
         throws IOException, JsonParseException
     {
diff --git a/src/java/org/codehaus/jackson/util/TokenBuffer.java b/src/java/org/codehaus/jackson/util/TokenBuffer.java
index 60a3ee4..3c3cfb5 100644
--- a/src/java/org/codehaus/jackson/util/TokenBuffer.java
+++ b/src/java/org/codehaus/jackson/util/TokenBuffer.java
@@ -1090,96 +1090,6 @@
         /**********************************************************
          */
 
-        protected void _decodeBase64(String str, ByteArrayBuilder builder, Base64Variant b64variant)
-            throws IOException, JsonParseException
-        {
-            int ptr = 0;
-            int len = str.length();
-            
-            main_loop:
-            while (ptr < len) {
-                // first, we'll skip preceding white space, if any
-                char ch;
-                do {
-                    ch = str.charAt(ptr++);
-                    if (ptr >= len) {
-                        break main_loop;
-                    }
-                } while (ch <= INT_SPACE);
-                int bits = b64variant.decodeBase64Char(ch);
-                if (bits < 0) {
-                    _reportInvalidBase64(b64variant, ch, 0, null);
-                }
-                int decodedData = bits;
-                // then second base64 char; can't get padding yet, nor ws
-                if (ptr >= len) {
-                    _reportBase64EOF();
-                }
-                ch = str.charAt(ptr++);
-                bits = b64variant.decodeBase64Char(ch);
-                if (bits < 0) {
-                    _reportInvalidBase64(b64variant, ch, 1, null);
-                }
-                decodedData = (decodedData << 6) | bits;
-                // third base64 char; can be padding, but not ws
-                if (ptr >= len) {
-                    // but as per [JACKSON-631] can be end-of-input, iff not using padding
-                    if (!b64variant.usesPadding()) {
-                        decodedData >>= 4;
-                        builder.append(decodedData);
-                        break;
-                    }
-                    _reportBase64EOF();
-                }
-                ch = str.charAt(ptr++);
-                bits = b64variant.decodeBase64Char(ch);
-                
-                // First branch: can get padding (-> 1 byte)
-                if (bits < 0) {
-                    if (bits != Base64Variant.BASE64_VALUE_PADDING) {
-                        _reportInvalidBase64(b64variant, ch, 2, null);
-                    }
-                    // Ok, must get padding
-                    if (ptr >= len) {
-                        _reportBase64EOF();
-                    }
-                    ch = str.charAt(ptr++);
-                    if (!b64variant.usesPaddingChar(ch)) {
-                        _reportInvalidBase64(b64variant, ch, 3, "expected padding character '"+b64variant.getPaddingChar()+"'");
-                    }
-                    // Got 12 bits, only need 8, need to shift
-                    decodedData >>= 4;
-                    builder.append(decodedData);
-                    continue;
-                }
-                // Nope, 2 or 3 bytes
-                decodedData = (decodedData << 6) | bits;
-                // fourth and last base64 char; can be padding, but not ws
-                if (ptr >= len) {
-                    // but as per [JACKSON-631] can be end-of-input, iff not using padding
-                    if (!b64variant.usesPadding()) {
-                        decodedData >>= 2;
-                        builder.appendTwoBytes(decodedData);
-                        break;
-                    }
-                    _reportBase64EOF();
-                }
-                ch = str.charAt(ptr++);
-                bits = b64variant.decodeBase64Char(ch);
-                if (bits < 0) {
-                    if (bits != Base64Variant.BASE64_VALUE_PADDING) {
-                        _reportInvalidBase64(b64variant, ch, 3, null);
-                    }
-                    decodedData >>= 2;
-                    builder.appendTwoBytes(decodedData);
-                } else {
-                    // otherwise, our triple is now complete
-                    decodedData = (decodedData << 6) | bits;
-                    builder.appendThreeBytes(decodedData);
-                }
-            }
-        }
-
         protected final Object _currentObject() {
             return _segment.get(_segmentPtr);
         }
@@ -1191,34 +1101,6 @@
             }
         }
 
-        /**
-         * @param bindex Relative index within base64 character unit; between 0
-         *   and 3 (as unit has exactly 4 characters)
-         */
-        protected void _reportInvalidBase64(Base64Variant b64variant, char ch, int bindex, String msg)
-            throws JsonParseException
-        {
-            String base;
-            if (ch <= INT_SPACE) {
-                base = "Illegal white space character (code 0x"+Integer.toHexString(ch)+") as character #"+(bindex+1)+" of 4-char base64 unit: can only used between units";
-            } else if (b64variant.usesPaddingChar(ch)) {
-                base = "Unexpected padding character ('"+b64variant.getPaddingChar()+"') as character #"+(bindex+1)+" of 4-char base64 unit: padding only legal as 3rd or 4th character";
-            } else if (!Character.isDefined(ch) || Character.isISOControl(ch)) {
-                // Not sure if we can really get here... ? (most illegal xml chars are caught at lower level)
-                base = "Illegal character (code 0x"+Integer.toHexString(ch)+") in base64 content";
-            } else {
-                base = "Illegal character '"+ch+"' (code 0x"+Integer.toHexString(ch)+") in base64 content";
-            }
-            if (msg != null) {
-                base = base + ": " + msg;
-            }
-            throw _constructError(base);
-        }
-
-        protected void _reportBase64EOF() throws JsonParseException {
-            throw _constructError("Unexpected end-of-String in base64 content");
-        }
-
         @Override
         protected void _handleEOF() throws JsonParseException {
             _throwInternal();
diff --git a/src/mapper/java/org/codehaus/jackson/map/deser/std/PrimitiveArrayDeserializers.java b/src/mapper/java/org/codehaus/jackson/map/deser/std/PrimitiveArrayDeserializers.java
index a3428a4..9945bec 100644
--- a/src/mapper/java/org/codehaus/jackson/map/deser/std/PrimitiveArrayDeserializers.java
+++ b/src/mapper/java/org/codehaus/jackson/map/deser/std/PrimitiveArrayDeserializers.java
@@ -283,7 +283,7 @@
             throws IOException, JsonProcessingException
         {
             JsonToken t = jp.getCurrentToken();
-
+            
             // Most likely case: base64 encoded String?
             if (t == JsonToken.VALUE_STRING) {
                 return jp.getBinaryValue(ctxt.getBase64Variant());
diff --git a/src/mapper/java/org/codehaus/jackson/node/TreeTraversingParser.java b/src/mapper/java/org/codehaus/jackson/node/TreeTraversingParser.java
index 147edab..42586df 100644
--- a/src/mapper/java/org/codehaus/jackson/node/TreeTraversingParser.java
+++ b/src/mapper/java/org/codehaus/jackson/node/TreeTraversingParser.java
@@ -306,11 +306,17 @@
     }
 
     @Override
-    public Object getEmbeddedObject() {
+    public Object getEmbeddedObject()
+    {
         if (!_closed) {
             JsonNode n = currentNode();
-            if (n != null && n.isPojo()) {
-                return ((POJONode) n).getPojo();
+            if (n != null) {
+                if (n.isPojo()) {
+                    return ((POJONode) n).getPojo();
+                }
+                if (n.isBinary()) {
+                    return ((BinaryNode) n).getBinaryValue();
+                }
             }
         }
         return null;
diff --git a/src/smile/java/org/codehaus/jackson/smile/SmileParser.java b/src/smile/java/org/codehaus/jackson/smile/SmileParser.java
index bbb55d2..3f636fa 100644
--- a/src/smile/java/org/codehaus/jackson/smile/SmileParser.java
+++ b/src/smile/java/org/codehaus/jackson/smile/SmileParser.java
@@ -1186,7 +1186,11 @@
         return _binaryValue;
     }
 
-    @Override
+    /* NOTE: must still implement just because 1.9.0 - 1.9.2 did require
+     * its implementation (and we'll try to avoid introducing binary
+     * incompatibilities); however, should be deleted from 2.0
+     */
+    // @Deprecated
     protected byte[] _decodeBase64(Base64Variant b64variant)
         throws IOException, JsonParseException
     {
diff --git a/src/test/org/codehaus/jackson/map/TestFormatSchema.java b/src/test/org/codehaus/jackson/map/TestFormatSchema.java
index 910cf78..d5f88b9 100644
--- a/src/test/org/codehaus/jackson/map/TestFormatSchema.java
+++ b/src/test/org/codehaus/jackson/map/TestFormatSchema.java
@@ -67,11 +67,6 @@
         public void setSchema(FormatSchema schema) {
             throw new SchemaException(schema);
         }
-        
-        @Override
-        protected byte[] _decodeBase64(Base64Variant b64variant) {
-            return null;
-        }
 
         @Override
         protected void _finishString() throws IOException, JsonParseException { }