Check in actual sources, moved to the new package, cleaned up a bit
diff --git a/src/main/java/com/fasterxml/jackson/core/JsonFactory.java b/src/main/java/com/fasterxml/jackson/core/JsonFactory.java
new file mode 100644
index 0000000..4ad28ca
--- /dev/null
+++ b/src/main/java/com/fasterxml/jackson/core/JsonFactory.java
@@ -0,0 +1,831 @@
+/* Jackson JSON-processor.
+ *
+ * Copyright (c) 2007- Tatu Saloranta, tatu.saloranta@iki.fi
+ *
+ * Licensed under the License specified in file LICENSE, included with
+ * the source code and binary code bundles.
+ * You may not use this file except in compliance with the License.
+ *
+ * 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.
+ */
+package com.fasterxml.jackson.core;
+
+import java.io.*;
+import java.lang.ref.SoftReference;
+import java.net.URL;
+
+import com.fasterxml.jackson.core.format.InputAccessor;
+import com.fasterxml.jackson.core.format.MatchStrength;
+import com.fasterxml.jackson.core.io.*;
+import com.fasterxml.jackson.core.json.ByteSourceJsonBootstrapper;
+import com.fasterxml.jackson.core.json.ReaderBasedJsonParser;
+import com.fasterxml.jackson.core.json.UTF8JsonGenerator;
+import com.fasterxml.jackson.core.json.WriterBasedJsonGenerator;
+import com.fasterxml.jackson.core.sym.BytesToNameCanonicalizer;
+import com.fasterxml.jackson.core.sym.CharsToNameCanonicalizer;
+import com.fasterxml.jackson.core.util.BufferRecycler;
+import com.fasterxml.jackson.core.util.VersionUtil;
+
+/**
+ * The main factory class of Jackson package, used to configure and
+ * construct reader (aka parser, {@link JsonParser})
+ * and writer (aka generator, {@link JsonGenerator})
+ * instances.
+ *<p>
+ * Factory instances are thread-safe and reusable after configuration
+ * (if any). Typically applications and services use only a single
+ * globally shared factory instance, unless they need differently
+ * configured factories. Factory reuse is important if efficiency matters;
+ * most recycling of expensive construct is done on per-factory basis.
+ *<p>
+ * Creation of a factory instance is a light-weight operation,
+ * and since there is no need for pluggable alternative implementations
+ * (as there is no "standard" JSON processor API to implement),
+ * the default constructor is used for constructing factory
+ * instances.
+ *
+ * @author Tatu Saloranta
+ */
+public class JsonFactory implements Versioned
+{
+    /**
+     * Name used to identify JSON format
+     * (and returned by {@link #getFormatName()}
+     */
+    public final static String FORMAT_NAME_JSON = "JSON";
+    
+    /**
+     * Bitfield (set of flags) of all parser features that are enabled
+     * by default.
+     */
+    final static int DEFAULT_PARSER_FEATURE_FLAGS = JsonParser.Feature.collectDefaults();
+
+    /**
+     * Bitfield (set of flags) of all generator features that are enabled
+     * by default.
+     */
+    final static int DEFAULT_GENERATOR_FEATURE_FLAGS = JsonGenerator.Feature.collectDefaults();
+
+    /*
+    /**********************************************************
+    /* Buffer, symbol table management
+    /**********************************************************
+     */
+
+    /**
+     * This <code>ThreadLocal</code> contains a {@link java.lang.ref.SoftRerefence}
+     * to a {@link BufferRecycler} used to provide a low-cost
+     * buffer recycling between reader and writer instances.
+     */
+    final protected static ThreadLocal<SoftReference<BufferRecycler>> _recyclerRef
+        = new ThreadLocal<SoftReference<BufferRecycler>>();
+
+    /**
+     * Each factory comes equipped with a shared root symbol table.
+     * It should not be linked back to the original blueprint, to
+     * avoid contents from leaking between factories.
+     */
+    protected CharsToNameCanonicalizer _rootCharSymbols = CharsToNameCanonicalizer.createRoot();
+
+    /**
+     * Alternative to the basic symbol table, some stream-based
+     * parsers use different name canonicalization method.
+     *<p>
+     * TODO: should clean up this; looks messy having 2 alternatives
+     * with not very clear differences.
+     */
+    protected BytesToNameCanonicalizer _rootByteSymbols = BytesToNameCanonicalizer.createRoot();
+
+    /*
+    /**********************************************************
+    /* Configuration
+    /**********************************************************
+     */
+
+    /**
+     * Object that implements conversion functionality between
+     * Java objects and JSON content. For base JsonFactory implementation
+     * usually not set by default, but can be explicitly set.
+     * Sub-classes (like @link org.codehaus.jackson.map.MappingJsonFactory}
+     * usually provide an implementation.
+     */
+    protected ObjectCodec _objectCodec;
+
+    /**
+     * Currently enabled parser features.
+     */
+    protected int _parserFeatures = DEFAULT_PARSER_FEATURE_FLAGS;
+
+    /**
+     * Currently enabled generator features.
+     */
+    protected int _generatorFeatures = DEFAULT_GENERATOR_FEATURE_FLAGS;
+
+    /**
+     * Definition of custom character escapes to use for generators created
+     * by this factory, if any. If null, standard data format specific
+     * escapes are used.
+     */
+    protected CharacterEscapes _characterEscapes;
+
+    /**
+     * Optional helper object that may decorate input sources, to do
+     * additional processing on input during parsing.
+     */
+    protected InputDecorator _inputDecorator;
+
+    /**
+     * Optional helper object that may decorate output object, to do
+     * additional processing on output during content generation.
+     */
+    protected OutputDecorator _outputDecorator;
+    
+    /*
+    /**********************************************************
+    /* Construction
+    /**********************************************************
+     */
+    
+    /**
+     * Default constructor used to create factory instances.
+     * Creation of a factory instance is a light-weight operation,
+     * but it is still a good idea to reuse limited number of
+     * factory instances (and quite often just a single instance):
+     * factories are used as context for storing some reused
+     * processing objects (such as symbol tables parsers use)
+     * and this reuse only works within context of a single
+     * factory instance.
+     */
+    public JsonFactory() { this(null); }
+
+    public JsonFactory(ObjectCodec oc) { _objectCodec = oc; }
+
+    /*
+    /**********************************************************
+    /* Format detection functionality (since 1.8)
+    /**********************************************************
+     */
+
+    /**
+     * Method that returns short textual id identifying format
+     * this factory supports.
+     *<p>
+     * Note: sub-classes should override this method; default
+     * implementation will return null for all sub-classes
+     */
+    public String getFormatName()
+    {
+        /* Somewhat nasty check: since we can't make this abstract
+         * (due to backwards compatibility concerns), need to prevent
+         * format name "leakage"
+         */
+        if (getClass() == JsonFactory.class) {
+            return FORMAT_NAME_JSON;
+        }
+        return null;
+    }
+
+    public MatchStrength hasFormat(InputAccessor acc) throws IOException
+    {
+        // since we can't keep this abstract, only implement for "vanilla" instance
+        if (getClass() == JsonFactory.class) {
+            return hasJSONFormat(acc);
+        }
+        return null;
+    }
+
+    protected MatchStrength hasJSONFormat(InputAccessor acc) throws IOException
+    {
+        return ByteSourceJsonBootstrapper.hasJSONFormat(acc);
+    }    
+    
+    /*
+    /**********************************************************
+    /* Versioned
+    /**********************************************************
+     */
+
+    @Override
+    public Version version() {
+        // VERSION is included under impl, so can't pass this class:
+        return VersionUtil.versionFor(UTF8JsonGenerator.class);
+    }
+
+    /*
+    /**********************************************************
+    /* Configuration, parser settings
+    /**********************************************************
+     */
+
+    /**
+     * Method for enabling or disabling specified parser feature
+     * (check {@link JsonParser.Feature} for list of features)
+     */
+    public final JsonFactory configure(JsonParser.Feature f, boolean state)
+    {
+        if (state) {
+            enable(f);
+        } else {
+            disable(f);
+        }
+        return this;
+    }
+
+    /**
+     * Method for enabling specified parser feature
+     * (check {@link JsonParser.Feature} for list of features)
+     */
+    public JsonFactory enable(JsonParser.Feature f) {
+        _parserFeatures |= f.getMask();
+        return this;
+    }
+
+    /**
+     * Method for disabling specified parser features
+     * (check {@link JsonParser.Feature} for list of features)
+     */
+    public JsonFactory disable(JsonParser.Feature f) {
+        _parserFeatures &= ~f.getMask();
+        return this;
+    }
+
+    /**
+     * Checked whether specified parser feature is enabled.
+     */
+    public final boolean isEnabled(JsonParser.Feature f) {
+        return (_parserFeatures & f.getMask()) != 0;
+    }
+
+    /**
+     * Method for getting currently configured input decorator (if any;
+     * there is no default decorator).
+     */
+    public InputDecorator getInputDecorator() {
+        return _inputDecorator;
+    }
+
+    /**
+     * Method for overriding currently configured input decorator
+     */
+    public JsonFactory setInputDecorator(InputDecorator d) {
+        _inputDecorator = d;
+        return this;
+    }
+    
+    /*
+    /**********************************************************
+    /* Configuration, generator settings
+    /**********************************************************
+     */
+
+    /**
+     * Method for enabling or disabling specified generator feature
+     * (check {@link JsonGenerator.Feature} for list of features)
+     */
+    public final JsonFactory configure(JsonGenerator.Feature f, boolean state) {
+        if (state) {
+            enable(f);
+        } else {
+            disable(f);
+        }
+        return this;
+    }
+
+
+    /**
+     * Method for enabling specified generator features
+     * (check {@link JsonGenerator.Feature} for list of features)
+     */
+    public JsonFactory enable(JsonGenerator.Feature f) {
+        _generatorFeatures |= f.getMask();
+        return this;
+    }
+
+    /**
+     * Method for disabling specified generator feature
+     * (check {@link JsonGenerator.Feature} for list of features)
+     */
+    public JsonFactory disable(JsonGenerator.Feature f) {
+        _generatorFeatures &= ~f.getMask();
+        return this;
+    }
+
+    /**
+     * Check whether specified generator feature is enabled.
+     */
+    public final boolean isEnabled(JsonGenerator.Feature f) {
+        return (_generatorFeatures & f.getMask()) != 0;
+    }
+
+    /**
+     * Method for accessing custom escapes factory uses for {@link JsonGenerator}s
+     * it creates.
+     */
+    public CharacterEscapes getCharacterEscapes() {
+        return _characterEscapes;
+    }
+
+    /**
+     * Method for defining custom escapes factory uses for {@link JsonGenerator}s
+     * it creates.
+     */
+    public JsonFactory setCharacterEscapes(CharacterEscapes esc) {
+        _characterEscapes = esc;
+        return this;
+    }
+
+    /**
+     * Method for getting currently configured output decorator (if any;
+     * there is no default decorator).
+     */
+    public OutputDecorator getOutputDecorator() {
+        return _outputDecorator;
+    }
+
+    /**
+     * Method for overriding currently configured output decorator
+     */
+    public JsonFactory setOutputDecorator(OutputDecorator d) {
+        _outputDecorator = d;
+        return this;
+    }
+    
+    /*
+    /**********************************************************
+    /* Configuration, other
+    /**********************************************************
+     */
+
+    /**
+     * Method for associating a {@link ObjectCodec} (typically
+     * a {@link org.codehaus.jackson.map.ObjectMapper}) with
+     * this factory (and more importantly, parsers and generators
+     * it constructs). This is needed to use data-binding methods
+     * of {@link JsonParser} and {@link JsonGenerator} instances.
+     */
+    public JsonFactory setCodec(ObjectCodec oc) {
+        _objectCodec = oc;
+        return this;
+    }
+
+    public ObjectCodec getCodec() { return _objectCodec; }
+
+    /*
+    /**********************************************************
+    /* Reader factories
+    /**********************************************************
+     */
+
+    /**
+     * Method for constructing JSON parser instance to parse
+     * contents of specified file. Encoding is auto-detected
+     * from contents according to JSON specification recommended
+     * mechanism.
+     *<p>
+     * Underlying input stream (needed for reading contents)
+     * will be <b>owned</b> (and managed, i.e. closed as need be) by
+     * the parser, since caller has no access to it.
+     *
+     * @param f File that contains JSON content to parse
+     */
+    public JsonParser createJsonParser(File f)
+        throws IOException, JsonParseException
+    {
+        // true, since we create InputStream from File
+        IOContext ctxt = _createContext(f, true);
+        InputStream in = new FileInputStream(f);
+        // [JACKSON-512]: allow wrapping with InputDecorator
+        if (_inputDecorator != null) {
+            in = _inputDecorator.decorate(ctxt, in);
+        }
+        return _createJsonParser(in, ctxt);
+    }
+
+    /**
+     * Method for constructing JSON parser instance to parse
+     * contents of resource reference by given URL.
+     * Encoding is auto-detected
+     * from contents according to JSON specification recommended
+     * mechanism.
+     *<p>
+     * Underlying input stream (needed for reading contents)
+     * will be <b>owned</b> (and managed, i.e. closed as need be) by
+     * the parser, since caller has no access to it.
+     *
+     * @param url URL pointing to resource that contains JSON content to parse
+     */
+    public JsonParser createJsonParser(URL url)
+        throws IOException, JsonParseException
+    {
+        // true, since we create InputStream from URL
+        IOContext ctxt = _createContext(url, true);
+        InputStream in = _optimizedStreamFromURL(url);
+        // [JACKSON-512]: allow wrapping with InputDecorator
+        if (_inputDecorator != null) {
+            in = _inputDecorator.decorate(ctxt, in);
+        }
+        return _createJsonParser(in, ctxt);
+    }
+
+    /**
+     * Method for constructing JSON parser instance to parse
+     * the contents accessed via specified input stream.
+     *<p>
+     * The input stream will <b>not be owned</b> by
+     * the parser, it will still be managed (i.e. closed if
+     * end-of-stream is reacher, or parser close method called)
+     * if (and only if) {@link com.fasterxml.jackson.core.JsonParser.Feature#AUTO_CLOSE_SOURCE}
+     * is enabled.
+     *<p>
+     * Note: no encoding argument is taken since it can always be
+     * auto-detected as suggested by Json RFC.
+     *
+     * @param in InputStream to use for reading JSON content to parse
+     */
+    public JsonParser createJsonParser(InputStream in)
+        throws IOException, JsonParseException
+    {
+        IOContext ctxt = _createContext(in, false);
+        // [JACKSON-512]: allow wrapping with InputDecorator
+        if (_inputDecorator != null) {
+            in = _inputDecorator.decorate(ctxt, in);
+        }
+        return _createJsonParser(in, ctxt);
+    }
+
+    /**
+     * Method for constructing parser for parsing
+     * the contents accessed via specified Reader.
+     <p>
+     * The read stream will <b>not be owned</b> by
+     * the parser, it will still be managed (i.e. closed if
+     * end-of-stream is reacher, or parser close method called)
+     * if (and only if) {@link com.fasterxml.jackson.core.JsonParser.Feature#AUTO_CLOSE_SOURCE}
+     * is enabled.
+     *<p>
+     *
+     * @param r Reader to use for reading JSON content to parse
+     */
+    public JsonParser createJsonParser(Reader r)
+        throws IOException, JsonParseException
+    {
+        // false -> we do NOT own Reader (did not create it)
+        IOContext ctxt = _createContext(r, false);
+        // [JACKSON-512]: allow wrapping with InputDecorator
+        if (_inputDecorator != null) {
+            r = _inputDecorator.decorate(ctxt, r);
+        }
+	return _createJsonParser(r, ctxt);
+    }
+
+    /**
+     * Method for constructing parser for parsing
+     * the contents of given byte array.
+     */
+    public JsonParser createJsonParser(byte[] data)
+        throws IOException, JsonParseException
+    {
+        IOContext ctxt = _createContext(data, true);
+        // [JACKSON-512]: allow wrapping with InputDecorator
+        if (_inputDecorator != null) {
+            InputStream in = _inputDecorator.decorate(ctxt, data, 0, data.length);
+            if (in != null) {
+                return _createJsonParser(in, ctxt);
+            }
+        }
+        return _createJsonParser(data, 0, data.length, ctxt);
+    }
+
+    /**
+     * Method for constructing parser for parsing
+     * the contents of given byte array.
+     * 
+     * @param data Buffer that contains data to parse
+     * @param offset Offset of the first data byte within buffer
+     * @param len Length of contents to parse within buffer
+     */
+    public JsonParser createJsonParser(byte[] data, int offset, int len)
+        throws IOException, JsonParseException
+    {
+        IOContext ctxt = _createContext(data, true);
+        // [JACKSON-512]: allow wrapping with InputDecorator
+        if (_inputDecorator != null) {
+            InputStream in = _inputDecorator.decorate(ctxt, data, offset, len);
+            if (in != null) {
+                return _createJsonParser(in, ctxt);
+            }
+        }
+	return _createJsonParser(data, offset, len, ctxt);
+    }
+
+    /**
+     * Method for constructing parser for parsing
+     * contents of given String.
+     */
+    public JsonParser createJsonParser(String content)
+        throws IOException, JsonParseException
+    {
+	Reader r = new StringReader(content);
+        // true -> we own the Reader (and must close); not a big deal
+        IOContext ctxt = _createContext(r, true);
+        // [JACKSON-512]: allow wrapping with InputDecorator
+        if (_inputDecorator != null) {
+            r = _inputDecorator.decorate(ctxt, r);
+        }
+	return _createJsonParser(r, ctxt);
+    }
+
+    /*
+    /**********************************************************
+    /* Generator factories
+    /**********************************************************
+     */
+
+    /**
+     * Method for constructing JSON generator for writing JSON content
+     * using specified output stream.
+     * Encoding to use must be specified, and needs to be one of available
+     * types (as per JSON specification).
+     *<p>
+     * Underlying stream <b>is NOT owned</b> by the generator constructed,
+     * so that generator will NOT close the output stream when
+     * {@link JsonGenerator#close} is called (unless auto-closing
+     * feature,
+     * {@link com.fasterxml.jackson.core.JsonGenerator.Feature#AUTO_CLOSE_TARGET}
+     * is enabled).
+     * Using application needs to close it explicitly if this is the case.
+     *<p>
+     * Note: there are formats that use fixed encoding (like most binary data formats)
+     * and that ignore passed in encoding.
+     *
+     * @param out OutputStream to use for writing JSON content 
+     * @param enc Character encoding to use
+     */
+    public JsonGenerator createJsonGenerator(OutputStream out, JsonEncoding enc)
+        throws IOException
+    {
+	// false -> we won't manage the stream unless explicitly directed to
+        IOContext ctxt = _createContext(out, false);
+        ctxt.setEncoding(enc);
+        if (enc == JsonEncoding.UTF8) {
+            // [JACKSON-512]: allow wrapping with _outputDecorator
+            if (_outputDecorator != null) {
+                out = _outputDecorator.decorate(ctxt, out);
+            }
+            return _createUTF8JsonGenerator(out, ctxt);
+        }
+        Writer w = _createWriter(out, enc, ctxt);
+        // [JACKSON-512]: allow wrapping with _outputDecorator
+        if (_outputDecorator != null) {
+            w = _outputDecorator.decorate(ctxt, w);
+        }
+	return _createJsonGenerator(w, ctxt);
+    }
+
+    /**
+     * Method for constructing JSON generator for writing JSON content
+     * using specified Writer.
+     *<p>
+     * Underlying stream <b>is NOT owned</b> by the generator constructed,
+     * so that generator will NOT close the Reader when
+     * {@link JsonGenerator#close} is called (unless auto-closing
+     * feature,
+     * {@link com.fasterxml.jackson.core.JsonGenerator.Feature#AUTO_CLOSE_TARGET} is enabled).
+     * Using application needs to close it explicitly.
+     *
+     * @param out Writer to use for writing JSON content 
+     */
+    public JsonGenerator createJsonGenerator(Writer out)
+        throws IOException
+    {
+        IOContext ctxt = _createContext(out, false);
+        // [JACKSON-512]: allow wrapping with _outputDecorator
+        if (_outputDecorator != null) {
+            out = _outputDecorator.decorate(ctxt, out);
+        }
+	return _createJsonGenerator(out, ctxt);
+    }
+
+    /**
+     * Convenience method for constructing generator that uses default
+     * encoding of the format (UTF-8 for JSON and most other data formats).
+     *<p>
+     * Note: there are formats that use fixed encoding (like most binary data formats).
+     */
+    public JsonGenerator createJsonGenerator(OutputStream out) throws IOException {
+        return createJsonGenerator(out, JsonEncoding.UTF8);
+    }
+    
+    /**
+     * Method for constructing JSON generator for writing JSON content
+     * to specified file, overwriting contents it might have (or creating
+     * it if such file does not yet exist).
+     * Encoding to use must be specified, and needs to be one of available
+     * types (as per JSON specification).
+     *<p>
+     * Underlying stream <b>is owned</b> by the generator constructed,
+     * i.e. generator will handle closing of file when
+     * {@link JsonGenerator#close} is called.
+     *
+     * @param f File to write contents to
+     * @param enc Character encoding to use
+     */
+    public JsonGenerator createJsonGenerator(File f, JsonEncoding enc)
+        throws IOException
+    {
+	OutputStream out = new FileOutputStream(f);
+	// true -> yes, we have to manage the stream since we created it
+        IOContext ctxt = _createContext(out, true);
+        ctxt.setEncoding(enc);
+        if (enc == JsonEncoding.UTF8) {
+            // [JACKSON-512]: allow wrapping with _outputDecorator
+            if (_outputDecorator != null) {
+                out = _outputDecorator.decorate(ctxt, out);
+            }
+            return _createUTF8JsonGenerator(out, ctxt);
+        }
+        Writer w = _createWriter(out, enc, ctxt);
+        // [JACKSON-512]: allow wrapping with _outputDecorator
+        if (_outputDecorator != null) {
+            w = _outputDecorator.decorate(ctxt, w);
+        }
+	return _createJsonGenerator(w, ctxt);
+    }
+
+    /*
+    /**********************************************************
+    /* Factory methods used by factory for creating parser instances,
+    /* overridable by sub-classes
+    /**********************************************************
+     */
+
+    /**
+     * Overridable factory method that actually instantiates desired parser
+     * given {@link InputStream} and context object.
+     *<p>
+     * This method is specifically designed to remain
+     * compatible between minor versions so that sub-classes can count
+     * on it being called as expected. That is, it is part of official
+     * interface from sub-class perspective, although not a public
+     * method available to users of factory implementations.
+     */
+    protected JsonParser _createJsonParser(InputStream in, IOContext ctxt)
+        throws IOException, JsonParseException
+    {
+        return new ByteSourceJsonBootstrapper(ctxt, in).constructParser(_parserFeatures,
+                _objectCodec, _rootByteSymbols, _rootCharSymbols);
+    }
+
+    /**
+     * Overridable factory method that actually instantiates parser
+     * using given {@link Reader} object for reading content.
+     *<p>
+     * This method is specifically designed to remain
+     * compatible between minor versions so that sub-classes can count
+     * on it being called as expected. That is, it is part of official
+     * interface from sub-class perspective, although not a public
+     * method available to users of factory implementations.
+     */
+    protected JsonParser _createJsonParser(Reader r, IOContext ctxt)
+	throws IOException, JsonParseException
+    {
+        return new ReaderBasedJsonParser(ctxt, _parserFeatures, r, _objectCodec,
+                _rootCharSymbols.makeChild(isEnabled(JsonParser.Feature.CANONICALIZE_FIELD_NAMES),
+                    isEnabled(JsonParser.Feature.INTERN_FIELD_NAMES)));
+    }
+
+    /**
+     * Overridable factory method that actually instantiates parser
+     * using given {@link Reader} object for reading content
+     * passed as raw byte array.
+     *<p>
+     * This method is specifically designed to remain
+     * compatible between minor versions so that sub-classes can count
+     * on it being called as expected. That is, it is part of official
+     * interface from sub-class perspective, although not a public
+     * method available to users of factory implementations.
+     */
+    protected JsonParser _createJsonParser(byte[] data, int offset, int len, IOContext ctxt)
+        throws IOException, JsonParseException
+    {
+        return new ByteSourceJsonBootstrapper(ctxt, data, offset, len).constructParser(_parserFeatures,
+                _objectCodec, _rootByteSymbols, _rootCharSymbols);
+    }
+
+    /*
+    /**********************************************************
+    /* Factory methods used by factory for creating generator instances,
+    /* overridable by sub-classes
+    /**********************************************************
+     */
+    
+    /**
+     * Overridable factory method that actually instantiates generator for
+     * given {@link Writer} and context object.
+     *<p>
+     * This method is specifically designed to remain
+     * compatible between minor versions so that sub-classes can count
+     * on it being called as expected. That is, it is part of official
+     * interface from sub-class perspective, although not a public
+     * method available to users of factory implementations.
+     */
+    protected JsonGenerator _createJsonGenerator(Writer out, IOContext ctxt)
+        throws IOException
+    {
+        WriterBasedJsonGenerator gen = new WriterBasedJsonGenerator(ctxt, _generatorFeatures, _objectCodec, out);
+        if (_characterEscapes != null) {
+            gen.setCharacterEscapes(_characterEscapes);
+        }
+        return gen;
+    }
+
+    /**
+     * Overridable factory method that actually instantiates generator for
+     * given {@link OutputStream} and context object, using UTF-8 encoding.
+     *<p>
+     * This method is specifically designed to remain
+     * compatible between minor versions so that sub-classes can count
+     * on it being called as expected. That is, it is part of official
+     * interface from sub-class perspective, although not a public
+     * method available to users of factory implementations.
+     */
+    protected JsonGenerator _createUTF8JsonGenerator(OutputStream out, IOContext ctxt)
+        throws IOException
+    {
+        UTF8JsonGenerator gen = new UTF8JsonGenerator(ctxt, _generatorFeatures, _objectCodec, out);
+        if (_characterEscapes != null) {
+            gen.setCharacterEscapes(_characterEscapes);
+        }
+        return gen;
+    }
+
+    protected Writer _createWriter(OutputStream out, JsonEncoding enc, IOContext ctxt) throws IOException
+    {
+        // note: this should not get called any more (caller checks, dispatches)
+        if (enc == JsonEncoding.UTF8) { // We have optimized writer for UTF-8
+            return new UTF8Writer(ctxt, out);
+        }
+        // not optimal, but should do unless we really care about UTF-16/32 encoding speed
+        return new OutputStreamWriter(out, enc.getJavaName());
+    }
+    
+    /*
+    /**********************************************************
+    /* Internal factory methods, other
+    /**********************************************************
+     */
+
+    /**
+     * Overridable factory method that actually instantiates desired
+     * context object.
+     */
+    protected IOContext _createContext(Object srcRef, boolean resourceManaged)
+    {
+        return new IOContext(_getBufferRecycler(), srcRef, resourceManaged);
+    }
+
+    /**
+     * Method used by factory to create buffer recycler instances
+     * for parsers and generators.
+     *<p>
+     * Note: only public to give access for <code>ObjectMapper</code>
+     */
+    public BufferRecycler _getBufferRecycler()
+    {
+        SoftReference<BufferRecycler> ref = _recyclerRef.get();
+        BufferRecycler br = (ref == null) ? null : ref.get();
+
+        if (br == null) {
+            br = new BufferRecycler();
+            _recyclerRef.set(new SoftReference<BufferRecycler>(br));
+        }
+        return br;
+    }
+    
+    /**
+     * Helper methods used for constructing an optimal stream for
+     * parsers to use, when input is to be read from an URL.
+     * This helps when reading file content via URL.
+     */
+    protected InputStream _optimizedStreamFromURL(URL url)
+        throws IOException
+    {
+        if ("file".equals(url.getProtocol())) {
+            /* Can not do this if the path refers
+             * to a network drive on windows. This fixes the problem;
+             * might not be needed on all platforms (NFS?), but should not
+             * matter a lot: performance penalty of extra wrapping is more
+             * relevant when accessing local file system.
+             */
+            String host = url.getHost();
+            if (host == null || host.length() == 0) {
+                return new FileInputStream(url.getPath());
+            }
+        }
+        return url.openStream();
+    }
+}