content: package im.actor.runtime.webrtc.sdp;
  
  import java.util.ArrayList;
  import java.util.HashMap;
  
  import im.actor.runtime.webrtc.sdp.entities.SDPMedia;
  import im.actor.runtime.webrtc.sdp.entities.SDPMediaMode;
  import im.actor.runtime.webrtc.sdp.entities.SDPRawRecord;
  import im.actor.runtime.webrtc.sdp.entities.SDPSession;
  import im.actor.runtime.webrtc.sdp.entities.SDPCodec;
  
  public abstract class SDP {
  
      public static SDPScheme parse(String sdp) {
          SDPReader reader = new SDPReader(sdp);
          SDPRawRecord record;
  
          //
          // Session
          //
          int version = reader.readVersion();
          String originator = reader.readRecord('o').getValue();
          String sessionName = reader.readRecord('s').getValue();
          SDPSession session = new SDPSession(version, originator, sessionName);
          while ((record = reader.readUntil('m')) != null) {
              session.getRecords().add(record);
          }
  
          //
          // Media Lines
          //
          ArrayList<SDPMedia> medias = new ArrayList<>();
          SDPRawRecord mediaLine;
          while ((mediaLine = reader.readOptionalRecord('m')) != null) {
              String[] mediaDesc = mediaLine.getValue().split(" ");
              String mediaType = mediaDesc[0];
              int port = Integer.parseInt(mediaDesc[1]);
              String protocol = mediaDesc[2];
              ArrayList<Integer> codecIds = new ArrayList<>();
              for (int i = 3; i < mediaDesc.length; i++) {
                  codecIds.add(Integer.parseInt(mediaDesc[i]));
              }
              SDPMediaMode mode = SDPMediaMode.SEND_RECEIVE;
              ArrayList<SDPRawRecord> records = new ArrayList<>();
              // ArrayList<SDPCodec> codecs = new ArrayList<>();
              HashMap<Integer, SDPCodec> codecs = new HashMap<>();
              HashMap<Integer, HashMap<String, String>> args = new HashMap<>();
              HashMap<Integer, ArrayList<String>> codecFeedbackMessages = new HashMap<>();
              while ((record = reader.readUntil('m')) != null) {
                  if (record.getType() == 'a' && "sendrecv".equals(record.getValue())) {
                      mode = SDPMediaMode.SEND_RECEIVE;
                  } else if (record.getType() == 'a' && "inactive".equals(record.getValue())) {
                      mode = SDPMediaMode.INACTIVE;
                  } else if (record.getType() == 'a' && "recvonly".equals(record.getValue())) {
                      mode = SDPMediaMode.RECEIVE_ONLY;
                  } else if (record.getType() == 'a' && "sendonly".equals(record.getValue())) {
                      mode = SDPMediaMode.SEND_ONLY;
                  } else if (record.getType() == 'a' && record.getValue().startsWith("rtpmap:")) {
                      String[] codecMap = record.getValue().split(" ", 2);
                      int index = Integer.parseInt(codecMap[0].substring("rtpmap:".length()));
                      String[] codecDef = codecMap[1].split("/");
                      String codecName = codecDef[0];
                      int clockRate = Integer.parseInt(codecDef[1]);
                      String codecArgs = codecDef.length >= 3 ? codecDef[2] : null;
                      codecs.put(index, new SDPCodec(index, codecName, clockRate, codecArgs));
                  } else if (record.getType() == 'a' && record.getValue().startsWith("fmtp:")) {
                      String[] codecMap = record.getValue().split(" ", 2);
                      int index = Integer.parseInt(codecMap[0].substring("fmtp:".length()));
                      String params = codecMap[1];
                      String[] pLines = params.trim().split(";");
                      HashMap<String, String> p = new HashMap<>();
                      for (String s : pLines) {
                          s = s.trim();
                          String[] v2 = s.split("=", 2);
                          p.put(v2[0], v2[1]);
                      }
                      args.put(index, p);
                  } else if (record.getType() == 'a' && record.getValue().startsWith("rtcp-fb:")) {
                      String[] codecMap = record.getValue().split(" ", 2);
                      int index = Integer.parseInt(codecMap[0].substring("rtcp-fb:".length()));
                      if (!codecFeedbackMessages.containsKey(index)) {
                          codecFeedbackMessages.put(index, new ArrayList<String>());
                      }
                      codecFeedbackMessages.get(index).add(codecMap[1]);
                  } else {
                      records.add(record);
                  }
              }
  
              ArrayList<SDPCodec> codec = new ArrayList<>();
              for (int index : codecIds) {
                  SDPCodec sdpCodec = codecs.get(index);
                  sdpCodec.setFormat(args.get(index));
                  sdpCodec.setCodecFeedback(codecFeedbackMessages.get(index));
                  codec.add(sdpCodec);
              }
              medias.add(new SDPMedia(mediaType, port, protocol, codec, mode, records));
          }
  
          return new SDPScheme(session, medias);
      }
  }