public static void DeserializeNullableCollection <T>(BufferedTextReader sr, int nextToken, Func <int, T> factory, ICollection <T> res)
     where T : class
 {
     if (nextToken == 'n')
     {
         if (sr.Read() == 'u' && sr.Read() == 'l' && sr.Read() == 'l')
         {
             res.Add(null);
         }
         else
         {
             throw new SerializationException("Invalid value found at position " + PositionInStream(sr) + " for string value. Expecting '\"' or null");
         }
     }
     else
     {
         res.Add(factory(nextToken));
     }
     while ((nextToken = GetNextToken(sr)) == ',')
     {
         nextToken = GetNextToken(sr);
         if (nextToken == 'n')
         {
             if (sr.Read() == 'u' && sr.Read() == 'l' && sr.Read() == 'l')
             {
                 res.Add(null);
             }
             else
             {
                 throw new SerializationException("Invalid value found at position " + PositionInStream(sr) + " for string value. Expecting '\"' or null");
             }
         }
         else
         {
             res.Add(factory(nextToken));
         }
     }
     if (nextToken != ']')
     {
         if (nextToken == -1)
         {
             throw new SerializationException("Unexpected end of json in collection.");
         }
         else
         {
             throw new SerializationException("Expecting ']' at position " + JsonSerialization.PositionInStream(sr) + ". Found " + (char)nextToken);
         }
     }
 }
 private static int Memorize(BufferedTextReader sr, int nextToken, TextWriter sw)
 {
     if (nextToken == '"')
     {
         return(MemoizeSkipString(sr, sw));
     }
     else if (nextToken == '{')
     {
         nextToken = MemoizeGetNextToken(sr, sw);
         if (nextToken == '}')
         {
             return(MemoizeGetNextToken(sr, sw));
         }
         if (nextToken == '"')
         {
             nextToken = MemoizeSkipString(sr, sw);
         }
         else
         {
             throw new SerializationException("Expecting '\"' at position " + JsonSerialization.PositionInStream(sr) + ". Found " + (char)nextToken);
         }
         if (nextToken != ':')
         {
             throw new SerializationException("Expecting ':' at position " + JsonSerialization.PositionInStream(sr) + ". Found " + (char)nextToken);
         }
         nextToken = MemoizeGetNextToken(sr, sw);
         nextToken = Memorize(sr, nextToken, sw);
         while (nextToken == ',')
         {
             nextToken = MemoizeGetNextToken(sr, sw);
             if (nextToken == '"')
             {
                 nextToken = MemoizeSkipString(sr, sw);
             }
             else
             {
                 throw new SerializationException("Expecting '\"' at position " + JsonSerialization.PositionInStream(sr) + ". Found " + (char)nextToken);
             }
             if (nextToken != ':')
             {
                 throw new SerializationException("Expecting ':' at position " + JsonSerialization.PositionInStream(sr) + ". Found " + (char)nextToken);
             }
             nextToken = MemoizeGetNextToken(sr, sw);
             nextToken = Memorize(sr, nextToken, sw);
         }
         if (nextToken != '}')
         {
             throw new SerializationException("Expecting '}' at position " + JsonSerialization.PositionInStream(sr) + ". Found " + (char)nextToken);
         }
         return(MemoizeGetNextToken(sr, sw));
     }
     else if (nextToken == '[')
     {
         nextToken = MemoizeGetNextToken(sr, sw);
         nextToken = Memorize(sr, nextToken, sw);
         while (nextToken == ',')
         {
             nextToken = MemoizeGetNextToken(sr, sw);
             nextToken = Memorize(sr, nextToken, sw);
         }
         if (nextToken != ']')
         {
             throw new SerializationException("Expecting ']' at position " + JsonSerialization.PositionInStream(sr) + ". Found " + (char)nextToken);
         }
         return(MemoizeGetNextToken(sr, sw));
     }
     else
     {
         while (nextToken != ',' && nextToken != '}' && nextToken != ']' && nextToken != -1)
         {
             nextToken = sr.Read();
             sw.Write((char)nextToken);
         }
         return(MoveToNextToken(sr, nextToken));
     }
 }