Merge branch '2.7'
diff --git a/release-notes/VERSION b/release-notes/VERSION
index 994cc2e..b83ff4a 100644
--- a/release-notes/VERSION
+++ b/release-notes/VERSION
@@ -14,6 +14,11 @@
 === Releases ===
 ------------------------------------------------------------------------
 
+2.7.2 (not yet released)
+
+#246: Fix UTF8JsonGenerator to allow QUOTE_FIELD_NAMES to be toggled
+ (suggested by philipa@github)
+
 2.7.1 (02-Feb-2016)
 
 No changes since 2.7.0.
diff --git a/src/main/java/com/fasterxml/jackson/core/base/GeneratorBase.java b/src/main/java/com/fasterxml/jackson/core/base/GeneratorBase.java
index 38302b5..c99832b 100644
--- a/src/main/java/com/fasterxml/jackson/core/base/GeneratorBase.java
+++ b/src/main/java/com/fasterxml/jackson/core/base/GeneratorBase.java
@@ -26,7 +26,8 @@
      * 
      * @since 2.5
      */
-    protected final static int DERIVED_FEATURES_MASK = Feature.WRITE_NUMBERS_AS_STRINGS.getMask()
+    protected final static int DERIVED_FEATURES_MASK =
+            Feature.WRITE_NUMBERS_AS_STRINGS.getMask()
             | Feature.ESCAPE_NON_ASCII.getMask()
             | Feature.STRICT_DUPLICATE_DETECTION.getMask()
             ;
@@ -61,7 +62,7 @@
      * {@link com.fasterxml.jackson.core.JsonGenerator.Feature#WRITE_NUMBERS_AS_STRINGS}).
      */
     protected boolean _cfgNumbersAsStrings;
-    
+
     /*
     /**********************************************************
     /* State
@@ -136,12 +137,13 @@
     @Override public int getFeatureMask() { return _features; }
 
     //public JsonGenerator configure(Feature f, boolean state) { }
-    
+
     @Override
     public JsonGenerator enable(Feature f) {
         final int mask = f.getMask();
         _features |= mask;
         if ((mask & DERIVED_FEATURES_MASK) != 0) {
+            // why not switch? Requires addition of a generated class, alas
             if (f == Feature.WRITE_NUMBERS_AS_STRINGS) {
                 _cfgNumbersAsStrings = true;
             } else if (f == Feature.ESCAPE_NON_ASCII) {
@@ -226,7 +228,7 @@
             }
         }
     }
-    
+
     @Override public JsonGenerator useDefaultPrettyPrinter() {
         // Should not override a pretty printer if one already assigned.
         if (getPrettyPrinter() != null) {
diff --git a/src/main/java/com/fasterxml/jackson/core/json/JsonGeneratorImpl.java b/src/main/java/com/fasterxml/jackson/core/json/JsonGeneratorImpl.java
index c09d2cf..1270eae 100644
--- a/src/main/java/com/fasterxml/jackson/core/json/JsonGeneratorImpl.java
+++ b/src/main/java/com/fasterxml/jackson/core/json/JsonGeneratorImpl.java
@@ -84,6 +84,14 @@
     protected SerializableString _rootValueSeparator
         = DefaultPrettyPrinter.DEFAULT_ROOT_VALUE_SEPARATOR;
 
+    /**
+     * Flag that is set if quoting is not to be added around
+     * JSON Object property names.
+     *
+     * @since 2.7
+     */
+    protected boolean _cfgUnqNames;
+
     /*
     /**********************************************************
     /* Life-cycle
@@ -94,10 +102,11 @@
     {
         super(features, codec);
         _ioContext = ctxt;
-        if (isEnabled(Feature.ESCAPE_NON_ASCII)) {
+        if (Feature.ESCAPE_NON_ASCII.enabledIn(features)) {
             // inlined `setHighestNonEscapedChar()`
             _maximumNonEscapedChar = 127;
         }
+        _cfgUnqNames = !Feature.QUOTE_FIELD_NAMES.enabledIn(features);
     }
 
     /*
@@ -107,6 +116,30 @@
      */
 
     @Override
+    public JsonGenerator enable(Feature f) {
+        super.enable(f);
+        if (f == Feature.QUOTE_FIELD_NAMES) {
+            _cfgUnqNames = false;
+        }
+        return this;
+    }
+
+    @Override
+    public JsonGenerator disable(Feature f) {
+        super.disable(f);
+        if (f == Feature.QUOTE_FIELD_NAMES) {
+            _cfgUnqNames = true;
+        }
+        return this;
+    }
+
+    @Override
+    protected void _checkStdFeatureChanges(int newFeatureFlags, int changedFeatures) {
+        super._checkStdFeatureChanges(newFeatureFlags, changedFeatures);
+        _cfgUnqNames = !Feature.QUOTE_FIELD_NAMES.enabledIn(newFeatureFlags);
+    }
+
+    @Override
     public JsonGenerator setHighestNonEscapedChar(int charCode) {
         _maximumNonEscapedChar = (charCode < 0) ? 0 : charCode;
         return this;
diff --git a/src/main/java/com/fasterxml/jackson/core/json/UTF8JsonGenerator.java b/src/main/java/com/fasterxml/jackson/core/json/UTF8JsonGenerator.java
index 90079f1..8f17ea3 100644
--- a/src/main/java/com/fasterxml/jackson/core/json/UTF8JsonGenerator.java
+++ b/src/main/java/com/fasterxml/jackson/core/json/UTF8JsonGenerator.java
@@ -93,18 +93,6 @@
 
     /*
     /**********************************************************
-    /* Quick flags
-    /**********************************************************
-     */
-
-    /**
-     * Flag that is set if quoting is not to be added around
-     * JSON Object property names.
-     */
-    protected boolean _cfgUnqNames;
-
-    /*
-    /**********************************************************
     /* Life-cycle
     /**********************************************************
      */
@@ -130,7 +118,6 @@
         if (isEnabled(Feature.ESCAPE_NON_ASCII)) {
             setHighestNonEscapedChar(127);
         }
-        _cfgUnqNames = !Feature.QUOTE_FIELD_NAMES.enabledIn(features);
     }
     
     public UTF8JsonGenerator(IOContext ctxt, int features, ObjectCodec codec,
@@ -148,7 +135,6 @@
         _outputMaxContiguous = (_outputEnd >> 3);
         _charBuffer = ctxt.allocConcatBuffer();
         _charBufferLength = _charBuffer.length;
-        _cfgUnqNames = !Feature.QUOTE_FIELD_NAMES.enabledIn(features);
     }
 
     /*
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 af871ce..316886b 100644
--- a/src/main/java/com/fasterxml/jackson/core/json/WriterBasedJsonGenerator.java
+++ b/src/main/java/com/fasterxml/jackson/core/json/WriterBasedJsonGenerator.java
@@ -136,7 +136,7 @@
             _outputBuffer[_outputTail++] = ',';
         }
         // Alternate mode, in which quoting of field names disabled?
-        if (!isEnabled(Feature.QUOTE_FIELD_NAMES)) {
+        if (_cfgUnqNames) {
             _writeString(name);
             return;
         }
@@ -166,7 +166,7 @@
         }
         // Alternate mode, in which quoting of field names disabled?
         final char[] quoted = name.asQuotedChars();
-        if (!isEnabled(Feature.QUOTE_FIELD_NAMES)) {
+        if (_cfgUnqNames) {
             writeRaw(quoted, 0, quoted.length);
             return;
         }
@@ -270,7 +270,9 @@
             _cfgPrettyPrinter.beforeObjectEntries(this);
         }
 
-        if (isEnabled(Feature.QUOTE_FIELD_NAMES)) { // standard
+        if (_cfgUnqNames) {// non-standard, omit quotes
+            _writeString(name);
+        } else { 
             if (_outputTail >= _outputEnd) {
                 _flushBuffer();
             }
@@ -280,8 +282,6 @@
                 _flushBuffer();
             }
             _outputBuffer[_outputTail++] = '"';
-        } else { // non-standard, omit quotes
-            _writeString(name);
         }
     }
 
@@ -294,7 +294,9 @@
         }
     
         final char[] quoted = name.asQuotedChars();
-        if (isEnabled(Feature.QUOTE_FIELD_NAMES)) { // standard
+        if (_cfgUnqNames) {// non-standard, omit quotes
+            writeRaw(quoted, 0, quoted.length);
+        } else {
             if (_outputTail >= _outputEnd) {
                 _flushBuffer();
             }
@@ -304,8 +306,6 @@
                 _flushBuffer();
             }
             _outputBuffer[_outputTail++] = '"';
-        } else { // non-standard, omit quotes
-            writeRaw(quoted, 0, quoted.length);
         }
     }
 
diff --git a/src/test/java/com/fasterxml/jackson/core/json/TestJsonGeneratorFeatures.java b/src/test/java/com/fasterxml/jackson/core/json/TestJsonGeneratorFeatures.java
index 5a42c83..68b7b7b 100644
--- a/src/test/java/com/fasterxml/jackson/core/json/TestJsonGeneratorFeatures.java
+++ b/src/test/java/com/fasterxml/jackson/core/json/TestJsonGeneratorFeatures.java
@@ -13,10 +13,11 @@
 public class TestJsonGeneratorFeatures
     extends com.fasterxml.jackson.core.BaseTest
 {
+    private final JsonFactory JSON_F = new JsonFactory();
+
     public void testConfigDefaults() throws IOException
     {
-        JsonFactory jf = new JsonFactory();
-        JsonGenerator jg = jf.createGenerator(new StringWriter());
+        JsonGenerator jg = JSON_F.createGenerator(new StringWriter());
         assertFalse(jg.isEnabled(JsonGenerator.Feature.WRITE_NUMBERS_AS_STRINGS));
         assertFalse(jg.isEnabled(JsonGenerator.Feature.WRITE_BIGDECIMAL_AS_PLAIN));
         jg.close();
@@ -35,8 +36,7 @@
         _testFieldNameQuoting(jf, true);
     }
 
-    public void testNonNumericQuoting()
-        throws IOException
+    public void testNonNumericQuoting() throws IOException
     {
         JsonFactory jf = new JsonFactory();
         // by default, quoting should be enabled
@@ -126,6 +126,54 @@
         return sw.toString();
     }
 
+    // for [core#246]
+    public void testFieldNameQuotingEnabled() throws IOException
+    {
+        // // First, test with default factory, with quoting enabled by default
+        
+        // First, default, with quotes
+        _testFieldNameQuotingEnabled(JSON_F, true, true, "{\"foo\":1}");
+        _testFieldNameQuotingEnabled(JSON_F, false, true, "{\"foo\":1}");
+
+        // then without quotes
+        _testFieldNameQuotingEnabled(JSON_F, true, false, "{foo:1}");
+        _testFieldNameQuotingEnabled(JSON_F, false, false, "{foo:1}");
+
+        // // Then with alternatively configured factory
+
+        JsonFactory JF2 = new JsonFactory();
+        JF2.disable(JsonGenerator.Feature.QUOTE_FIELD_NAMES);
+
+        _testFieldNameQuotingEnabled(JF2, true, true, "{\"foo\":1}");
+        _testFieldNameQuotingEnabled(JF2, false, true, "{\"foo\":1}");
+
+        // then without quotes
+        _testFieldNameQuotingEnabled(JF2, true, false, "{foo:1}");
+        _testFieldNameQuotingEnabled(JF2, false, false, "{foo:1}");
+    }
+
+    private void _testFieldNameQuotingEnabled(JsonFactory jf, boolean useBytes,
+            boolean useQuotes, String exp) throws IOException
+    {
+        ByteArrayOutputStream bytes = useBytes ? new ByteArrayOutputStream() : null;
+        StringWriter sw = useBytes ? null : new StringWriter();
+        JsonGenerator gen = useBytes ? jf.createGenerator(bytes) : jf.createGenerator(sw);
+        if (useQuotes) {
+            gen.enable(JsonGenerator.Feature.QUOTE_FIELD_NAMES);
+        } else {
+            gen.disable(JsonGenerator.Feature.QUOTE_FIELD_NAMES);
+        }
+
+        gen.writeStartObject();
+        gen.writeFieldName("foo");
+        gen.writeNumber(1);
+        gen.writeEndObject();
+        gen.close();
+
+        String json = useBytes ? bytes.toString("UTF-8") : sw.toString();
+        assertEquals(exp, json);
+    }
+    
     /*
     /**********************************************************
     /* Helper methods