more work for non-blocking
diff --git a/src/main/java/com/fasterxml/jackson/core/json/async/NonBlockingJsonParser.java b/src/main/java/com/fasterxml/jackson/core/json/async/NonBlockingJsonParser.java
index 6fb067b..607e1a6 100644
--- a/src/main/java/com/fasterxml/jackson/core/json/async/NonBlockingJsonParser.java
+++ b/src/main/java/com/fasterxml/jackson/core/json/async/NonBlockingJsonParser.java
@@ -169,13 +169,12 @@
         if (_currToken == JsonToken.NOT_AVAILABLE) {
             return _finishToken();
         }
-
         // No: fresh new token; may or may not have existing one
         _numTypesValid = NR_UNKNOWN;
         _tokenInputTotal = _currInputProcessed + _inputPtr;
         // also: clear any data retained so far
         _binaryValue = null;
-        int ch = _inputBuffer[_inputPtr++];
+        int ch = _inputBuffer[_inputPtr++] & 0xFF;
 
         switch (_majorState) {
         case MAJOR_INITIAL:
@@ -184,14 +183,21 @@
         case MAJOR_ROOT:
             return _startValue(ch);
 
-        case MAJOR_OBJECT_FIELD: // field or end-object
+        case MAJOR_OBJECT_FIELD_FIRST: // field or end-object
             // expect name
             return _startFieldName(ch);
-            
-        case MAJOR_OBJECT_VALUE:
-        case MAJOR_ARRAY_ELEMENT: // element or end-array
+        case MAJOR_OBJECT_FIELD_NEXT: // comma
+            return _startFieldNameAfterComma(ch);
+
+        case MAJOR_OBJECT_VALUE: // require semicolon first
+            return _startValueAfterColon(ch);
+
+        case MAJOR_ARRAY_ELEMENT_FIRST: // value without leading comma
             return _startValue(ch);
 
+        case MAJOR_ARRAY_ELEMENT_NEXT: // require leading comma
+            return _startValueAfterComma(ch);
+
         default:
         }
         VersionUtil.throwInternal();
@@ -207,12 +213,19 @@
         // NOTE: caller ensures availability of at least one byte
 
         switch (_minorState) {
+        case MINOR_VALUE_LEADING_WS:
+            return _startValue(_inputBuffer[_inputPtr++] & 0xFF);
+        case MINOR_VALUE_LEADING_COMMA:
+            return _startValueAfterComma(_inputBuffer[_inputPtr++] & 0xFF);
+        case MINOR_VALUE_LEADING_COLON:
+            return _startValueAfterColon(_inputBuffer[_inputPtr++] & 0xFF);
+
         case MINOR_VALUE_TOKEN_NULL:
             return _finishKeywordToken("null", _pending32, JsonToken.VALUE_NULL);
         case MINOR_VALUE_TOKEN_TRUE:
-            return _finishKeywordToken("null", _pending32, JsonToken.VALUE_TRUE);
+            return _finishKeywordToken("true", _pending32, JsonToken.VALUE_TRUE);
         case MINOR_VALUE_TOKEN_FALSE:
-            return _finishKeywordToken("null", _pending32, JsonToken.VALUE_FALSE);
+            return _finishKeywordToken("false", _pending32, JsonToken.VALUE_FALSE);
         case MINOR_VALUE_TOKEN_ERROR: // case of "almost token", just need tokenize for error
             return _finishErrorToken();
         }
@@ -248,7 +261,7 @@
                 }
             }
             if (_inputPtr >= _inputEnd) {
-                _minorState = MINOR_FIELD_ROOT_GOT_SEPARATOR;
+                _minorState = MINOR_ROOT_GOT_SEPARATOR;
                 if (_closed) {
                     return null;
                 }
@@ -272,10 +285,19 @@
     /**
      * Helper method called to detect type of a value token (at any level), and possibly
      * decode it if contained in input buffer.
-     * Note that possible header has been ruled out by caller and is not checked here.
+     * Value may be preceded by leading white-space, but no separator (comma).
      */
     private final JsonToken _startValue(int ch) throws IOException
     {
+        // First: any leading white space?
+        if (ch <= 0x0020) {
+            ch = _skipWS(ch);
+            if (ch <= 0) {
+                _minorState = MINOR_VALUE_LEADING_WS;
+                return _currToken;
+            }
+        }
+
         if (ch == INT_QUOTE) {
             return _startString(ch);
         }
@@ -316,6 +338,143 @@
         return _startUnexpectedValue(ch);
     }
 
+    /**
+     * Helper method called to parse token that is either a value token in array
+     * or end-array marker
+     */
+    private final JsonToken _startValueAfterComma(int ch) throws IOException
+    {
+        // First: any leading white space?
+        if (ch <= 0x0020) {
+            ch = _skipWS(ch);
+            if (ch <= 0) {
+                _minorState = MINOR_VALUE_LEADING_COMMA;
+                return _currToken;
+            }
+        }
+        if (ch != INT_COMMA) {
+            if (ch == INT_RBRACKET) {
+                return _closeArrayScope();
+            }
+            _reportUnexpectedChar(ch, "was expecting comma to separate "+_parsingContext.typeDesc()+" entries");
+        }
+        int ptr = _inputPtr;
+        if (ptr >= _inputEnd) {
+            _minorState = MINOR_VALUE_LEADING_WS;
+            return (_currToken = JsonToken.NOT_AVAILABLE);
+        }
+        ch = _inputBuffer[ptr];
+        _inputPtr = ptr+1;
+        if (ch <= 0x0020) {
+            ch = _skipWS(ch);
+            if (ch <= 0) {
+                _minorState = MINOR_VALUE_LEADING_WS;
+                return _currToken;
+            }
+        }
+        if (ch == INT_QUOTE) {
+            return _startString(ch);
+        }
+        switch (ch) {
+        case '-':
+            return _startNegativeNumber();
+
+        // Should we have separate handling for plus? Although
+        // it is not allowed per se, it may be erroneously used,
+        // and could be indicate by a more specific error message.
+        case '0': case '1':
+        case '2': case '3':
+        case '4': case '5':
+        case '6': case '7':
+        case '8': case '9':
+            return _startPositiveNumber(ch);
+        case 'f':
+            return _startFalseToken();
+        case 'n':
+            return _startNullToken();
+        case 't':
+            return _startTrueToken();
+        case '[':
+            return _startArrayScope();
+        case ']':
+            return _closeArrayScope();
+        case '{':
+            return _startObjectScope();
+        case '}':
+            return _closeObjectScope();
+        default:
+        }
+        return _startUnexpectedValue(ch);
+    }
+
+    /**
+     * Helper method called to detect type of a value token (at any level), and possibly
+     * decode it if contained in input buffer.
+     * Value MUST be preceded by a semi-colon (which may be surrounded by white-space)
+     */
+    private final JsonToken _startValueAfterColon(int ch) throws IOException
+    {
+        // First: any leading white space?
+        if (ch <= 0x0020) {
+            ch = _skipWS(ch);
+            if (ch <= 0) {
+                _minorState = MINOR_VALUE_LEADING_COLON;
+                return _currToken;
+            }
+        }
+        if (ch != INT_COLON) {
+            _reportUnexpectedChar(ch, "was expecting a colon to separate field name and value");
+        }
+        int ptr = _inputPtr;
+        if (ptr >= _inputEnd) {
+            _minorState = MINOR_VALUE_LEADING_WS;
+            return (_currToken = JsonToken.NOT_AVAILABLE);
+        }
+        ch = _inputBuffer[ptr];
+        _inputPtr = ptr+1;
+        if (ch <= 0x0020) {
+            ch = _skipWS(ch);
+            if (ch <= 0) {
+                _minorState = MINOR_VALUE_LEADING_WS;
+                return _currToken;
+            }
+        }
+        if (ch == INT_QUOTE) {
+            return _startString(ch);
+        }
+        switch (ch) {
+        case '-':
+            return _startNegativeNumber();
+
+        // Should we have separate handling for plus? Although
+        // it is not allowed per se, it may be erroneously used,
+        // and could be indicate by a more specific error message.
+        case '0': case '1':
+        case '2': case '3':
+        case '4': case '5':
+        case '6': case '7':
+        case '8': case '9':
+            return _startPositiveNumber(ch);
+        case 'f':
+            return _startFalseToken();
+        case 'n':
+            return _startNullToken();
+        case 't':
+            return _startTrueToken();
+        case '[':
+            return _startArrayScope();
+        case ']':
+            return _closeArrayScope();
+        case '{':
+            return _startObjectScope();
+        case '}':
+            return _closeObjectScope();
+        default:
+        }
+        return _startUnexpectedValue(ch);
+    }
+
+    
     protected JsonToken _startUnexpectedValue(int ch) throws IOException
     {
         // TODO: Maybe support non-standard tokens that streaming parser does:
@@ -345,6 +504,33 @@
         return null;
     }
 
+    private final int _skipWS(int ch) throws IOException
+    {
+        do {
+            if (ch != INT_SPACE) {
+                if (ch == INT_LF) {
+                    ++_currInputRow;
+                    _currInputRowStart = _inputPtr;
+                } else if (ch == INT_CR) {
+                    ++_currInputRowAlt;
+                    _currInputRowStart = _inputPtr;
+                } else if (ch != INT_TAB) {
+                    _throwInvalidSpace(ch);
+                }
+            }
+            if (_inputPtr >= _inputEnd) {
+                if (_endOfInput) { // except for this special case
+                    _eofAsNextToken();
+                } else {
+                    _currToken = JsonToken.NOT_AVAILABLE;
+                }
+                return 0;
+            }
+            ch = _inputBuffer[_inputPtr++] & 0xFF;
+        } while (ch <= 0x0020);
+        return ch;
+    }
+
     /*
     /**********************************************************************
     /* Second-level decoding, simple tokens
@@ -405,7 +591,7 @@
                 }
             }
         }
-        _minorState = MINOR_VALUE_TOKEN_TRUE;
+        _minorState = MINOR_VALUE_TOKEN_NULL;
         return _finishKeywordToken("null", 1, JsonToken.VALUE_NULL);
     }
 
@@ -422,16 +608,18 @@
             int ch = _inputBuffer[_inputPtr] & 0xFF;
             if (matched == end) { // need to verify trailing separator
                 if (ch < INT_0 || (ch == INT_RBRACKET) || (ch == INT_RCURLY)) { // expected/allowed chars
-                    return _valueComplete(JsonToken.VALUE_NULL);
+                    return _valueComplete(result);
                 }
+                break;
             }
             if (ch != expToken.charAt(matched)) {
                 break;
             }
+            ++matched;
             ++_inputPtr;
         }
         _minorState = MINOR_VALUE_TOKEN_ERROR;
-        _textBuffer.resetWithString(expToken.substring(0, matched));
+        _textBuffer.resetWithCopy(expToken, 0, matched);
         return _finishErrorToken();
     }
 
@@ -500,4 +688,9 @@
     {
         return null;
     }
+
+    protected final JsonToken _startFieldNameAfterComma(int ch) throws IOException
+    {
+        return null;
+    }
 }