void odata_json_operation_payload_parameter_writer::handle_serialize_odata_value(
	::utility::stringstream_t& ss, const std::shared_ptr<::odata::edm::edm_named_type>& property_type, const std::shared_ptr<odata_value>& property_value)
{
	if (!property_type || !property_value)
	{
		ss << "null";

		return ;
	}

    switch(property_type->get_type_kind())
	{
	case edm_type_kind_t::Primitive:
		{
			auto p_value = std::dynamic_pointer_cast<odata_primitive_value>(property_value);
			auto p_primitive_type = std::dynamic_pointer_cast<edm_primitive_type>(property_type);

			if (p_value && p_primitive_type)
			{
				handle_serialize_primitive_value(ss, p_primitive_type, p_value);
			}
			else
			{
				ss << "null";
			}
		}
		break;
	case edm_type_kind_t::PayloadAnnotation:
		{
			auto p_value = std::dynamic_pointer_cast<odata_primitive_value>(property_value);

			if (p_value)
			{
				ss << U('"') << p_value->to_string() << U('"');
			}
			else
			{
				ss << "null";
			}
		}
		break;
	case edm_type_kind_t::Enum:
		{
			auto p_value = std::dynamic_pointer_cast<odata_enum_value>(property_value);
			
			if (p_value)
			{
				handle_serialize_enum_value(ss, p_value);
			}
			else
			{
				ss << "null";
			}
		}
		break;
	case edm_type_kind_t::Complex:
		{
			auto p_value = std::dynamic_pointer_cast<odata_complex_value>(property_value);

			if (p_value)
			{
				handle_serialize_odata_properties(ss, p_value->properties());
			}
			else
			{
				ss << "null";
			}
		}
		break;
	case edm_type_kind_t::Collection:
		{
			auto p_value = std::dynamic_pointer_cast<odata_collection_value>(property_value);

			if (p_value)
			{
				handle_serialize_collection_value(ss, p_value);
			}
			else
			{
				ss << "[]";
			}
		}
		break;
	case edm_type_kind_t::Entity:
		{
			throw std::runtime_error("writer unsupported type!");  
		}
		break;
	default:
		{
			throw std::runtime_error("writer unsupported type!");  
		}
		break;
	}
}
void odata_json_writer_minimal::handle_serialize_odata_value(::utility::stringstream_t& ss, 
    const std::shared_ptr<edm_named_type>& property_type, const std::shared_ptr<odata_value>& property_value)
{
	if (!property_type || !property_value)
	{
		ss << "null";

		return ;
	}

    switch(property_type->get_type_kind())
	{
	case edm_type_kind_t::Primitive:
		{
			auto p_value = std::dynamic_pointer_cast<odata_primitive_value>(property_value);
			auto p_primitive_type = std::dynamic_pointer_cast<edm_primitive_type>(property_type);

			if (p_value && p_primitive_type)
			{
				handle_serialize_primitive_value(ss, p_primitive_type, p_value);
			}
			else
			{
				ss << "null";
			}
		}
		break;
	case edm_type_kind_t::Enum:
		{
			auto p_value = std::dynamic_pointer_cast<odata_enum_value>(property_value);
			
			if (p_value)
			{
				handle_serialize_enum_value(ss, p_value);
			}
			else
			{
				ss << "null";
			}
		}
		break;
	case edm_type_kind_t::PayloadAnnotation:
		{
			auto p_value = std::dynamic_pointer_cast<odata_primitive_value>(property_value);

			if (p_value)
			{
				ss << U('"') << p_value->to_string() << U('"');
			}
			else
			{
				ss << "null";
			}
		}
		break;
	case edm_type_kind_t::Complex:
		{
			auto p_value = std::dynamic_pointer_cast<odata_complex_value>(property_value);

			if (p_value)
			{
				::utility::string_t type_link;
				if (p_value->try_get(PAYLOAD_ANNOTATION_TYPE, type_link) && !type_link.empty())
				{
					if (type_link.find(U("#")) != 0)
					{
						type_link = U("#") + type_link;
						p_value->set_value(PAYLOAD_ANNOTATION_TYPE, 
							std::make_shared<odata_primitive_value>(std::make_shared<edm_payload_annotation_type>(PAYLOAD_ANNOTATION_TYPE), type_link));
					}
				}

				handle_serialize_odata_properties(ss, p_value->properties());
			}
			else
			{
				ss << "null";
			}
		}
		break;
	case edm_type_kind_t::Collection:
		{
			auto p_value = std::dynamic_pointer_cast<odata_collection_value>(property_value);

			if (p_value)
			{
				handle_serialize_collection_value(ss, p_value);
			}
			else
			{
				ss << "[]";
			}
		}
		break;
	case edm_type_kind_t::Entity:
		{
			auto p_value = std::dynamic_pointer_cast<odata_entity_value>(property_value);

			if (p_value)
			{
				::utility::string_t type_link;
				if (p_value->try_get(PAYLOAD_ANNOTATION_TYPE, type_link) && !type_link.empty())
				{
					if (type_link.find(U("#")) != 0)
					{
						type_link = U("#") + type_link;
						p_value->set_value(PAYLOAD_ANNOTATION_TYPE, 
							std::make_shared<odata_primitive_value>(std::make_shared<edm_payload_annotation_type>(PAYLOAD_ANNOTATION_TYPE), type_link));
					}
				}

				handle_serialize_odata_properties(ss, p_value->properties());
			}
			else
			{
				ss << "null";
			}
		}
		break;
	default:
		{
			throw std::runtime_error("write unsupported property type!");  
		}
		break;
	}
}