/// <summary>
 /// Matches a JSON array content: the match ends with the first ].
 /// Whitespaces and JS comments (//... or /* ... */) are skipped.
 /// </summary>
 /// <param name="this">This <see cref="VirtualStringMatcher"/>.</param>
 /// <param name="value">The list of objects on success.</param>
 /// <returns>True on success, false otherwise.</returns>
 public static bool MatchJSONArrayContent(this VirtualStringMatcher @this, out List <object> value)
 {
     value = null;
     while ([email protected])
     {
         @this.SkipWhiteSpacesAndJSComments();
         if (@this.TryMatchChar(']'))
         {
             if (value == null)
             {
                 value = new List <object>();
             }
             return(true);
         }
         object cell;
         if (!MatchJSONObject(@this, out cell))
         {
             return(false);
         }
         if (value == null)
         {
             value = new List <object>();
         }
         value.Add(cell);
         @this.SkipWhiteSpacesAndJSComments();
         // Allow trailing comma: ,] is valid.
         @this.TryMatchChar(',');
     }
     return(@this.SetError("JSON array definition but reached end of match."));
 }
 /// <summary>
 /// Matches a { "JSON" : "object" }, a ["JSON", "array"] or a terminal value (string, null, double, true or false)
 /// and any combination of them.
 /// Whitespaces and JS comments (//... or /* ... */) are skipped.
 /// </summary>
 /// <param name="this">This <see cref="VirtualStringMatcher"/>.</param>
 /// <param name="value">
 /// A list of objects (for array), a list of KeyValuePair&lt;string,object&gt; for object or
 /// a double, string, bollean or null (for null).</param>
 /// <returns>True on success, false on error.</returns>
 public static bool MatchJSONObject(this VirtualStringMatcher @this, out object value)
 {
     value = null;
     @this.SkipWhiteSpacesAndJSComments();
     if (@this.TryMatchChar('{'))
     {
         List <KeyValuePair <string, object> > c;
         if (!MatchJSONObjectContent(@this, out c))
         {
             return(false);
         }
         value = c;
         return(true);
     }
     if (@this.TryMatchChar('['))
     {
         List <object> t;
         if (!MatchJSONArrayContent(@this, out t))
         {
             return(false);
         }
         value = t;
         return(true);
     }
     if (TryMatchJSONTerminalValue(@this, out value))
     {
         return(true);
     }
     return(@this.SetError("JSON value."));
 }
 /// <summary>
 /// Matches a very simple version of a JSON object content: this match stops at the first closing }.
 /// Whitespaces and JS comments (//... or /* ... */) are skipped.
 /// </summary>
 /// <param name="this">This <see cref="VirtualStringMatcher"/>.</param>
 /// <param name="o">The read object on success as a list of KeyValuePair.</param>
 /// <returns>True on success, false on error.</returns>
 public static bool MatchJSONObjectContent(this VirtualStringMatcher @this, out List <KeyValuePair <string, object> > o)
 {
     o = null;
     while ([email protected])
     {
         @this.SkipWhiteSpacesAndJSComments();
         string propName;
         object value;
         if (@this.TryMatchChar('}'))
         {
             if (o == null)
             {
                 o = new List <KeyValuePair <string, object> >();
             }
             return(true);
         }
         if ([email protected](out propName))
         {
             o = null;
             return(@this.SetError("Quoted Property Name."));
         }
         @this.SkipWhiteSpacesAndJSComments();
         if ([email protected](':') || !MatchJSONObject(@this, out value))
         {
             o = null;
             return(false);
         }
         if (o == null)
         {
             o = new List <KeyValuePair <string, object> >();
         }
         o.Add(new KeyValuePair <string, object>(propName, value));
         @this.SkipWhiteSpacesAndJSComments();
         // This accepts e trailing comma at the end of a property list: ..."a":0,} is not an error.
         @this.TryMatchChar(',');
     }
     return(@this.SetError("JSON object definition but reached end of match."));
 }