Merge branch 'master' of github.com:FasterXML/jackson-core
diff --git a/release-notes/VERSION b/release-notes/VERSION
index c1a4051..634cf3f 100644
--- a/release-notes/VERSION
+++ b/release-notes/VERSION
@@ -33,6 +33,7 @@
 #282: Fail to report error for trying to write field name outside Object (root level)
 #285: Add `JsonParser.getText(Writer)`
  (contributed by LokesN)
+#290: Add `JsonGenerator.canWriteFormattedNumbers()` for introspection
 - Add `JsonParser.currentToken()` and `JsonParser.currentTokenId()` as replacements
   for `getCurrentToken()` and `getCurrentTokenId()`, respectively. Existing methods
   will likely be deprecated in 2.9.
diff --git a/src/main/java/com/fasterxml/jackson/core/JsonGenerator.java b/src/main/java/com/fasterxml/jackson/core/JsonGenerator.java
index 4c22760..f474c65 100644
--- a/src/main/java/com/fasterxml/jackson/core/JsonGenerator.java
+++ b/src/main/java/com/fasterxml/jackson/core/JsonGenerator.java
@@ -698,6 +698,20 @@
      */
     public boolean canOmitFields() { return true; }
 
+    /**
+     * Introspection method to call to check whether it is possible
+     * to write numbers using {@link #writeNumber(java.lang.String)}
+     * using possible custom format, or not. Typically textual formats
+     * allow this (and JSON specifically does), whereas binary formats
+     * do not allow this (except by writing them as Strings).
+     * Usual reason for calling this method is to check whether custom
+     * formatting of numbers may be applied by higher-level code (databinding)
+     * or not.
+     *
+     * @since 2.8
+     */
+    public boolean canWriteFormattedNumbers() { return false; }
+    
     /*
     /**********************************************************
     /* Public API, write methods, structural
diff --git a/src/main/java/com/fasterxml/jackson/core/json/WriterBasedJsonGenerator.java b/src/main/java/com/fasterxml/jackson/core/json/WriterBasedJsonGenerator.java
index 6e5b9ff..8b0f5de 100644
--- a/src/main/java/com/fasterxml/jackson/core/json/WriterBasedJsonGenerator.java
+++ b/src/main/java/com/fasterxml/jackson/core/json/WriterBasedJsonGenerator.java
@@ -79,7 +79,7 @@
     
     /*
     /**********************************************************
-    /* Overridden configuration methods
+    /* Overridden configuration, introspection methods
     /**********************************************************
      */
     
@@ -95,6 +95,10 @@
         return Math.max(0, len);
     }
 
+    // json does allow this so
+    @Override
+    public boolean canWriteFormattedNumbers() { return true; }
+
     /*
     /**********************************************************
     /* Overridden methods
diff --git a/src/test/java/com/fasterxml/jackson/core/json/GeneratorFeaturesTest.java b/src/test/java/com/fasterxml/jackson/core/json/GeneratorFeaturesTest.java
index 94cbcd9..a04e5e6 100644
--- a/src/test/java/com/fasterxml/jackson/core/json/GeneratorFeaturesTest.java
+++ b/src/test/java/com/fasterxml/jackson/core/json/GeneratorFeaturesTest.java
@@ -20,6 +20,13 @@
         JsonGenerator g = JSON_F.createGenerator(new StringWriter());
         assertFalse(g.isEnabled(JsonGenerator.Feature.WRITE_NUMBERS_AS_STRINGS));
         assertFalse(g.isEnabled(JsonGenerator.Feature.WRITE_BIGDECIMAL_AS_PLAIN));
+
+        assertTrue(g.canOmitFields());
+        assertFalse(g.canWriteBinaryNatively());
+        assertTrue(g.canWriteFormattedNumbers());
+        assertFalse(g.canWriteObjectId());
+        assertFalse(g.canWriteTypeId());
+        
         g.close();
     }
 
diff --git a/src/test/java/com/fasterxml/jackson/core/main/TestParserFeatures.java b/src/test/java/com/fasterxml/jackson/core/main/TestParserFeatures.java
index c66d5a6..e1841f1 100644
--- a/src/test/java/com/fasterxml/jackson/core/main/TestParserFeatures.java
+++ b/src/test/java/com/fasterxml/jackson/core/main/TestParserFeatures.java
@@ -1,5 +1,7 @@
 package com.fasterxml.jackson.core.main;
 
+import java.io.*;
+
 import com.fasterxml.jackson.core.*;
 
 /**
@@ -9,7 +11,7 @@
 public class TestParserFeatures
     extends com.fasterxml.jackson.core.BaseTest
 {
-    public void testDefaultSettings()
+    public void testDefaultSettings() throws Exception
     {
         JsonFactory f = new JsonFactory();
         assertTrue(f.isEnabled(JsonParser.Feature.AUTO_CLOSE_SOURCE));
@@ -17,6 +19,13 @@
         assertFalse(f.isEnabled(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES));
         assertFalse(f.isEnabled(JsonParser.Feature.ALLOW_SINGLE_QUOTES));
         assertFalse(f.isEnabled(JsonParser.Feature.ALLOW_UNQUOTED_CONTROL_CHARS));
+
+        JsonParser p = f.createParser(new StringReader("{}"));
+        _testDefaultSettings(p);
+        p.close();
+        p = f.createParser(new ByteArrayInputStream("{}".getBytes("UTF-8")));
+        _testDefaultSettings(p);
+        p.close();
     }
 
     public void testQuotesRequired() throws Exception
@@ -25,7 +34,6 @@
         _testQuotesRequired(true);
     }
 
-
     // // Tests for [JACKSON-208], unquoted tabs:
 
     public void testTabsDefault() throws Exception
@@ -46,23 +54,28 @@
     /****************************************************************
      */
 
+    private void _testDefaultSettings(JsonParser p) {
+        assertFalse(p.canReadObjectId());
+        assertFalse(p.canReadTypeId());
+    }
+    
     private void _testQuotesRequired(boolean useStream) throws Exception
     {
         final String JSON = "{ test : 3 }";
         final String EXP_ERROR_FRAGMENT = "was expecting double-quote to start";
         JsonFactory f = new JsonFactory();
-        JsonParser jp = useStream ?
+        JsonParser p = useStream ?
             createParserUsingStream(f, JSON, "UTF-8")
             : createParserUsingReader(f, JSON)
             ;
 
-        assertToken(JsonToken.START_OBJECT, jp.nextToken());
+        assertToken(JsonToken.START_OBJECT, p.nextToken());
         try {
-            jp.nextToken();
+            p.nextToken();
         } catch (JsonParseException je) {
             verifyException(je, EXP_ERROR_FRAGMENT);
         } finally {
-            jp.close();
+            p.close();
         }
     }
 
@@ -73,16 +86,16 @@
         JsonFactory f = new JsonFactory();
         // First, let's see that by default unquoted tabs are illegal
         String JSON = "[\"tab:\t\"]";
-        JsonParser jp = useStream ? createParserUsingStream(f, JSON, "UTF-8") : createParserUsingReader(f, JSON);
-        assertToken(JsonToken.START_ARRAY, jp.nextToken());
+        JsonParser p = useStream ? createParserUsingStream(f, JSON, "UTF-8") : createParserUsingReader(f, JSON);
+        assertToken(JsonToken.START_ARRAY, p.nextToken());
         try {
-            jp.nextToken();
-            jp.getText();
+            p.nextToken();
+            p.getText();
             fail("Expected exception");
         } catch (JsonParseException e) {
             verifyException(e, "Illegal unquoted character");
         } finally {
-            jp.close();
+            p.close();
         }
     }
 
@@ -94,14 +107,14 @@
         String FIELD = "a\tb";
         String VALUE = "\t";
         String JSON = "{ "+quote(FIELD)+" : "+quote(VALUE)+"}";
-        JsonParser jp = useStream ? createParserUsingStream(f, JSON, "UTF-8") : createParserUsingReader(f, JSON);
+        JsonParser p = useStream ? createParserUsingStream(f, JSON, "UTF-8") : createParserUsingReader(f, JSON);
 
-        assertToken(JsonToken.START_OBJECT, jp.nextToken());
-        assertToken(JsonToken.FIELD_NAME, jp.nextToken());
-        assertEquals(FIELD, jp.getText());
-        assertToken(JsonToken.VALUE_STRING, jp.nextToken());
-        assertEquals(VALUE, jp.getText());
-        assertToken(JsonToken.END_OBJECT, jp.nextToken());
-        jp.close();
+        assertToken(JsonToken.START_OBJECT, p.nextToken());
+        assertToken(JsonToken.FIELD_NAME, p.nextToken());
+        assertEquals(FIELD, p.getText());
+        assertToken(JsonToken.VALUE_STRING, p.nextToken());
+        assertEquals(VALUE, p.getText());
+        assertToken(JsonToken.END_OBJECT, p.nextToken());
+        p.close();
     }
 }