/// <summary>
		/// Writes the JSON representation of the object.
		/// </summary>
		/// <param name="writer">The <see cref="JsonWriter"/> to write to.</param>
		/// <param name="value">The value.</param>
		/// <param name="serializer">The calling serializer.</param>
		public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
		{
			var dataSet = (DataSet) value;
			var resolver = serializer.ContractResolver as DefaultContractResolver;

			var converter = new DataTableConverter();

			writer.WriteStartObject();

			foreach (DataTable table in dataSet.Tables)
			{
				writer.WritePropertyName((resolver != null) ? resolver.GetResolvedPropertyName(table.TableName) : table.TableName);

				converter.WriteJson(writer, table, serializer);
			}

			writer.WriteEndObject();
		}
		/// <summary>
		/// Reads the JSON representation of the object.
		/// </summary>
		/// <param name="reader">The <see cref="JsonReader"/> to read from.</param>
		/// <param name="objectType">Type of the object.</param>
		/// <param name="existingValue">The existing value of object being read.</param>
		/// <param name="serializer">The calling serializer.</param>
		/// <returns>The object value.</returns>
		public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
		{
			// handle typed datasets
			DataSet ds = (objectType == typeof (DataSet)) ? new DataSet() : (DataSet) Activator.CreateInstance(objectType);

			var converter = new DataTableConverter();

			reader.Read();

			while (reader.TokenType == JsonToken.PropertyName)
			{
				DataTable dt = ds.Tables[(string) reader.Value];
				bool exists = (dt != null);

				dt = (DataTable) converter.ReadJson(reader, typeof (DataTable), dt, serializer);

				if (!exists)
					ds.Tables.Add(dt);

				reader.Read();
			}

			return ds;
		}