diff --git a/org/antlr/v4/tool/templates/codegen/Java/Java.stg b/org/antlr/v4/tool/templates/codegen/Java/Java.stg
new file mode 100644
index 0000000000..fc455cfa1d
--- /dev/null
+++ b/org/antlr/v4/tool/templates/codegen/Java/Java.stg
@@ -0,0 +1,1006 @@
+/*
+ * [The "BSD license"]
+ * Copyright (c) 2012-2016 Terence Parr
+ * Copyright (c) 2012-2016 Sam Harwell
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+javaTypeInitMap ::= [
+ "int":"0",
+ "long":"0",
+ "float":"0.0f",
+ "double":"0.0",
+ "boolean":"false",
+ "byte":"0",
+ "short":"0",
+ "char":"0",
+ default:"null" // anything other than a primitive type is an object
+]
+
+// args must be
The default implementation does nothing.\
+ */ +@Override public void exitThe default implementation does nothing.\
+ */ + @Override public void enterEveryRule(ParserRuleContext ctx) { } + /** + * {@inheritDoc\} + * + * \The default implementation does nothing.\
+ */ + @Override public void exitEveryRule(ParserRuleContext ctx) { } + /** + * {@inheritDoc\} + * + * \The default implementation does nothing.\
+ */ + @Override public void visitTerminal(TerminalNode node) { } + /** + * {@inheritDoc\} + * + * \The default implementation does nothing.\
+ */ + @Override public void visitErrorNode(ErrorNode node) { } +} +>> + +VisitorFile(file, header, namedActions) ::= << +
+
+
+ }
+
+
+
+ catch (RecognitionException re) {
+ _localctx.exception = re;
+ _errHandler.reportError(this, re);
+ _errHandler.recover(this, re);
+ }
+
+ finally {
+
+ exitRule();
+ }
+ return _localctx;
+}
+>>
+
+LeftRecursiveRuleFunction(currentRule,args,code,locals,ruleCtx,altLabelCtxs,
+ namedActions,finallyAction,postamble) ::=
+<<
+
+
+}; separator="\n">
+
+ }>public final () throws RecognitionException {
+ return (0}>);
+}
+
+private (int _p}>) throws RecognitionException {
+ ParserRuleContext _parentctx = _ctx;
+ int _parentState = getState();
+ _localctx = new (_ctx, _parentState}>);
+ _prevctx = _localctx;
+ int _startState = ;
+ enterRecursionRule(_localctx, , RULE_, _p);
+
+
+ try {
+
+ int _alt;
+
+
+
+
+ }
+ catch (RecognitionException re) {
+ _localctx.exception = re;
+ _errHandler.reportError(this, re);
+ _errHandler.recover(this, re);
+ }
+ finally {
+
+ unrollRecursionContexts(_parentctx);
+ }
+ return _localctx;
+}
+>>
+
+CodeBlockForOuterMostAlt(currentOuterMostAltCodeBlock, locals, preamble, ops) ::= <<
+_localctx = new Context(_localctx);
+enterOuterAlt(_localctx, );
+
+>>
+
+CodeBlockForAlt(currentAltCodeBlock, locals, preamble, ops) ::= <<
+{
+
+
+
+}
+>>
+
+LL1AltBlock(choice, preamble, alts, error) ::= <<
+setState();
+_errHandler.sync(this);
+ = _input.LT(1);
+
+switch (_input.LA(1)) {
+
+
+ break;}; separator="\n">
+default:
+
+}
+>>
+
+LL1OptionalBlock(choice, alts, error) ::= <<
+setState();
+_errHandler.sync(this);
+switch (_input.LA(1)) {
+
+
+ break;}; separator="\n">
+default:
+ break;
+}
+>>
+
+LL1OptionalBlockSingleAlt(choice, expr, alts, preamble, error, followExpr) ::= <<
+setState();
+_errHandler.sync(this);
+
+if () {
+
+}
+) ) !>
+>>
+
+LL1StarBlockSingleAlt(choice, loopExpr, alts, preamble, iteration) ::= <<
+setState();
+_errHandler.sync(this);
+
+while () {
+
+ setState();
+ _errHandler.sync(this);
+
+}
+>>
+
+LL1PlusBlockSingleAlt(choice, loopExpr, alts, preamble, iteration) ::= <<
+setState();
+_errHandler.sync(this);
+
+do {
+
+ setState();
+ _errHandler.sync(this);
+
+} while ( );
+>>
+
+// LL(*) stuff
+
+AltBlock(choice, preamble, alts, error) ::= <<
+setState();
+_errHandler.sync(this);
+ = _input.LT(1);
+
+switch ( getInterpreter().adaptivePredict(_input,,_ctx) ) {
+:
+
+ break;}; separator="\n">
+}
+>>
+
+OptionalBlock(choice, alts, error) ::= <<
+setState();
+_errHandler.sync(this);
+switch ( getInterpreter().adaptivePredict(_input,,_ctx) ) {
++1:
+
+ break;}; separator="\n">
+}
+>>
+
+StarBlock(choice, alts, sync, iteration) ::= <<
+setState();
+_errHandler.sync(this);
+_alt = getInterpreter().adaptivePredict(_input,,_ctx);
+while ( _alt!= && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) {
+ if ( _alt==1+1 ) {
+
+
+ }
+ setState();
+ _errHandler.sync(this);
+ _alt = getInterpreter().adaptivePredict(_input,,_ctx);
+}
+>>
+
+PlusBlock(choice, alts, error) ::= <<
+setState();
+_errHandler.sync(this);
+_alt = 1+1;
+do {
+ switch (_alt) {
+ +1:
+
+ break;}; separator="\n">
+ default:
+
+ }
+ setState();
+ _errHandler.sync(this);
+ _alt = getInterpreter().adaptivePredict(_input,,_ctx);
+} while ( _alt!= && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER );
+>>
+
+Sync(s) ::= "sync();"
+
+ThrowNoViableAlt(t) ::= "throw new NoViableAltException(this);"
+
+TestSetInline(s) ::= <<
+}; separator=" || ">
+>>
+
+// Java language spec 15.19 - shift operators mask operands rather than overflow to 0... need range test
+testShiftInRange(shiftAmount) ::= <<
+(() & ~0x3f) == 0
+>>
+
+bitsetBitfieldComparison(s, bits) ::= <%
+(})> && ((1L \<\< ) & L) != 0)
+%>
+
+isZero ::= [
+"0":true,
+default:false
+]
+
+offsetShift(shiftAmount, offset) ::= <%
+( - )
+%>
+
+bitsetInlineComparison(s, bits) ::= <%
+==}; separator=" || ">
+%>
+
+cases(tokens) ::= <<
+:}; separator="\n">
+>>
+
+InvokeRule(r, argExprsChunks) ::= <<
+setState();
+ = }>(,);
+>>
+
+MatchToken(m) ::= <<
+setState();
+ = }>match();
+>>
+
+MatchSet(m, expr, capture) ::= ""
+
+MatchNotSet(m, expr, capture) ::= "