private static JsonArray transformStreamStatToJson(Map<String, List<RTCRtpStreamStats>> streamStatMap, boolean fullyDetailed) {
    JsonArrayBuilder arrayBuilder = Json.createArrayBuilder();
    
    for (String streamId : streamStatMap.keySet()) {
      List<RTCRtpStreamStats> streamStatsList = streamStatMap.get(streamId);
      
      boolean inbound = streamStatsList.get(0) instanceof RTCReceivedRtpStreamStats;
      boolean audio = streamStatsList.get(0).getKind().equals("audio");
      boolean video = !audio;
      int size = streamStatsList.size();
      int last = size -1;
      long duration = streamStatsList.get(last).getTimestamp() - streamStatsList.get(0).getTimestamp();
     
      JsonObjectBuilder objectBuilder = Json.createObjectBuilder();
      objectBuilder.add("streamId", streamId);
      
      List<Double> bytes = addStatToJsonBuilder(objectBuilder, streamStatsList, StatEnum.BYTES, fullyDetailed);
//      objectBuilder.add(inbound
//          ? StatEnum.TOTAL_BYTES_RECEIVED.toString()
//          : StatEnum.TOTAL_BYTES_SENT.toString()
//        , checkNegativeValue(bytes.get(last)));

      objectBuilder.add(inbound
          ? StatEnum.RECEIVED_BITRATE.toString()
          : StatEnum.SENT_BITRATE.toString()
        , checkNegativeValue(8 * getDiffEndToStart(bytes)/duration));
  
      List<Double> packets = addStatToJsonBuilder(objectBuilder, streamStatsList, StatEnum.PACKETS, fullyDetailed);
      
      Double packetsReceivedDiff = getDiffEndToStart(packets);
      

      if (video) {
        List<Double> frames = addStatToJsonBuilder(objectBuilder, streamStatsList, StatEnum.FRAME, fullyDetailed);
        objectBuilder.add(inbound
          ? StatEnum.TOTAL_FRAME_RECEIVED.toString()
          : StatEnum.TOTAL_FRAME_SENT.toString(), checkNegativeValue(frames.get(last)));
//        System.out.println((inbound ? "inbound" : "outbound") + "\n" + frames );
        List<Double> framerate = addStatToJsonBuilder(objectBuilder, streamStatsList, StatEnum.FRAME_RATE, fullyDetailed);

        objectBuilder.add(StatEnum.AVG_FRAME_RATE.toString(),  checkNegativeValue(1000 * getDiffEndToStart(frames)/duration));
      }
      
      if (inbound) {
        if (audio) {
          List<Double> audioLvl = addStatToJsonBuilder(objectBuilder, streamStatsList, StatEnum.AUDIO_LEVEL, fullyDetailed);
          objectBuilder.add(StatEnum.AVG_AUDIO_LEVEL.toString(), checkNegativeValue(getAverage(audioLvl)));
        }
        List<Double> packetsLost = addStatToJsonBuilder(objectBuilder, streamStatsList, StatEnum.PACKETS_LOST, fullyDetailed);
        objectBuilder.add(StatEnum.TOTAL_PACKETS_LOST.toString(), "" + packetsLost.get(last).intValue());
        Double packetsLostDiff = getDiffEndToStart(packetsLost);
        objectBuilder.add(StatEnum.PACKETS_LOST_PERCENTAGE.toString(), 
          checkNegativeValue((100 * packetsLostDiff/ (packetsLostDiff + packetsReceivedDiff))) + "%");
//        objectBuilder.add(StatEnum.PACKETS_LOST_CUMULATIVE_PERCENTAGE.toString(),
//          checkNegativeValue(100 * packetsLost.get(last)/ (packetsLost.get(last) + packets.get(last))));
        
        
        
//        List<Double> packetsDiscarded = addStatToJsonBuilder(objectBuilder, streamStatsList, StatEnum.PACKETS_DISCARDED, fullyDetailed);
//        Double packetsDiscardedDiff = getDiffEndToStart(packets);
//        objectBuilder.add(StatEnum.TOTAL_PACKETS_DISCARDED.toString(), packetsDiscarded.get(last).intValue());
//        objectBuilder.add(StatEnum.PACKETS_DISCARDED_PERCENTAGE.toString(),
//          checkNegativeValue(100 * packetsDiscardedDiff/ (packetsDiscardedDiff + packetsReceivedDiff)));
  
  
        if (audio) {
          List<Double> jitter = addStatToJsonBuilder(objectBuilder, streamStatsList, StatEnum.JITTER, fullyDetailed);
          objectBuilder.add(StatEnum.AVG_JITTER.toString(), checkNegativeValue(getAverage(jitter)/1000));
//          objectBuilder.add(StatEnum.AVG_JITTER.toString(), checkNegativeValue(jitter.get(last)));

        } else {
          List<Double> framerate = addStatToJsonBuilder(objectBuilder, streamStatsList, StatEnum.FRAME_RATE, fullyDetailed);
//          objectBuilder.add(StatEnum.AVG_FRAME_RATE.toString(),  checkNegativeValue(1000 * getDiffEndToStart(framerate)/duration));
//          objectBuilder.add(StatEnum.AVG_FRAME_RATE_DECODED.toString(),  checkNegativeValue(1000 * getDiffEndToStart(framerate)/duration));

          // could be useful someday
          List<Double> framedropped = addStatToJsonBuilder(objectBuilder, streamStatsList, StatEnum.FRAME_DROPPED, fullyDetailed);
          
        }
      }
      arrayBuilder.add(objectBuilder);
    }
    return arrayBuilder.build();
  }
@param statArray     array of stats provided from getStats()
@param fullyDetailed true if the detailed arrays of specific stat values are to be added to the summary

@return  the stat summary : (Sample stats on Chrome 74)
    "Starting Timestamp": "2019-06-28 162729",
    "Ending Timestamp": "2019-06-28 162740",
    "Total Inbound Bytes Received (Bytes)": 642114,
    "Total Inbound Audio Bytes Received (Bytes)": 114190,
    "Total Inbound Video Bytes Received (Bytes)": 527924,
    "Total Outbound Bytes Sent (Bytes)": 644136,
    "Total Outbound Audio Bytes Sent (Bytes)": 114371,
    "Total Outbound Video Bytes Sent (Bytes)": 529765,
    "Total Round Trip Time (ms)": 0.0,
    "Average Current Round Trip Time (ms)": 0.0,
    "inbound": {
            "audio": [
            {
                "streamId": "RTCInboundRTPAudioStream_3333556480",
                "Total Bytes Received (Bytes)": "34997",
                "Average Received Bitrate (kbps)": "3071",
                "Total Packets Received": "585",
                "Average Audio Level (dB)": "0",
                "Total Packets Lost": 0,
                "Packets Lost (%)": "0",
                "Packets Discarded (%)": "0",
                "Average Audio Jitter (ms)": "0"
            }
        ],
        "video": [
            {
                "streamId": "RTCInboundRTPVideoStream_3131213379",
                "Total Bytes Received (Bytes)": "1031833",
                "Average Received Bitrate (kbps)": "95078",
                "Total Packets Received": "1006",
                "Frames Received": "234",
                "Average Frame Rate (fps)": "0",
                "Total Packets Lost": 0,
                "Packets Lost (%)": "0",
                "Packets Discarded (%)": "0"
            }
        ]
    },
    "outbound": {
        "audio": [ same as inbound stats ],
        "video": [ same as inbound stats ]
    }
KITE-Framework/src/main/java/org/webrtc/kite/stats/StatsUtils.java