private JToken CreateJObject (JsonReader reader)
		{
			ValidationUtils.ArgumentNotNull(reader, "reader");

			// this is needed because we've already read inside the object, looking for metadata properties
			using (JTokenWriter writer = new JTokenWriter()) {
				writer.WriteStartObject();

				do {
					if (reader.TokenType == JsonToken.PropertyName) {
						string propertyName = (string)reader.Value;
						do {
							if (!reader.Read())
								break;
						} while (reader.TokenType == JsonToken.Comment);

						if (CheckPropertyName(reader, propertyName))
							continue;

						writer.WritePropertyName(propertyName);
						writer.WriteToken(reader, true, true);
					}
					else if (reader.TokenType == JsonToken.Comment) {
						// eat
					}
					else {
						writer.WriteEndObject();
						return writer.Token;
					}
				} while (reader.Read());

				throw JsonSerializationException.Create(reader, "Unexpected end when deserializing object.");
			}
		}
		private JToken CreateJToken (JsonReader reader, JsonContract contract)
		{
			ValidationUtils.ArgumentNotNull(reader, "reader");

			if (contract != null) {
				if (contract.UnderlyingType == typeof(JRaw))
					return JRaw.Create(reader);
				if (reader.TokenType == JsonToken.Null
				                && !(contract.UnderlyingType == typeof(JValue) || contract.UnderlyingType == typeof(JToken)))
					return null;
			}

			JToken token;
			using (JTokenWriter writer = new JTokenWriter()) {
				writer.WriteToken(reader);
				token = writer.Token;
			}

			return token;
		}