protected static void appendPropertyValue(
     final JsonStreamWriter jsonStreamWriter,
     final EntityPropertyInfo propertyInfo,
     final Object value)
     throws IOException, EdmException, EntityProviderException {
   if (propertyInfo.isComplex()) {
     if (value == null || value instanceof Map<?, ?>) {
       jsonStreamWriter.beginObject();
       appendPropertyMetadata(jsonStreamWriter, propertyInfo.getType());
       for (final EntityPropertyInfo childPropertyInfo :
           ((EntityComplexPropertyInfo) propertyInfo).getPropertyInfos()) {
         jsonStreamWriter.separator();
         final String name = childPropertyInfo.getName();
         jsonStreamWriter.name(name);
         appendPropertyValue(
             jsonStreamWriter,
             childPropertyInfo,
             value == null ? null : ((Map<?, ?>) value).get(name));
       }
       jsonStreamWriter.endObject();
     } else {
       throw new EntityProviderException(
           EntityProviderException.ILLEGAL_ARGUMENT.addContent(
               "A complex property must have a Map as data"));
     }
   } else {
     final EdmSimpleType type = (EdmSimpleType) propertyInfo.getType();
     final Object contentValue =
         value instanceof Map ? ((Map<?, ?>) value).get(propertyInfo.getName()) : value;
     final String valueAsString =
         type.valueToString(contentValue, EdmLiteralKind.JSON, propertyInfo.getFacets());
     switch (EdmSimpleTypeKind.valueOf(type.getName())) {
       case String:
         jsonStreamWriter.stringValue(valueAsString);
         break;
       case Boolean:
       case Byte:
       case SByte:
       case Int16:
       case Int32:
         jsonStreamWriter.unquotedValue(valueAsString);
         break;
       case DateTime:
       case DateTimeOffset:
         // Although JSON escaping is (and should be) done in the JSON
         // serializer, we backslash-escape the forward slash here explicitly
         // because it is not required to escape it in JSON but in OData.
         jsonStreamWriter.stringValueRaw(
             valueAsString == null ? null : valueAsString.replace("/", "\\/"));
         break;
       default:
         jsonStreamWriter.stringValueRaw(valueAsString);
         break;
     }
   }
 }
  public void append(final Writer writer, final EntityPropertyInfo propertyInfo, final Object value)
      throws EntityProviderException {
    JsonStreamWriter jsonStreamWriter = new JsonStreamWriter(writer);

    try {
      jsonStreamWriter.beginObject().name(FormatJson.D).beginObject();

      jsonStreamWriter.name(propertyInfo.getName());
      appendPropertyValue(
          jsonStreamWriter,
          propertyInfo.isComplex() ? (EntityComplexPropertyInfo) propertyInfo : propertyInfo,
          value);

      jsonStreamWriter.endObject().endObject();
    } catch (final IOException e) {
      throw new EntityProviderException(
          EntityProviderException.EXCEPTION_OCCURRED.addContent(e.getClass().getSimpleName()), e);
    } catch (final EdmException e) {
      throw new EntityProviderException(
          EntityProviderException.EXCEPTION_OCCURRED.addContent(e.getClass().getSimpleName()), e);
    }
  }