anchor.diff:  
   -export([tcp_packet_array/1
            ,tcp_flows/1
  -         ,tcp_establishment_times/1         
  +         ,tcp_flow_parts/3
  +         ,tcp_flow/1
  +         ,tcp_establishment_times/1
           ]).
  +
  +-export([read_tcp_stream/2,
  +         read_tcp_streams/1]).
  +
  +read_tcp_streams(File) ->
  +    {PacketArray, _Count} = tcp_packet_array(File),
  +    Flows = tcp_flows(PacketArray),
  +    [begin
  +         {A,B} = tcp_flow_parts2(Flow, Idxs, PacketArray),
  +         {{element(1, A), read_tcp_stream(A, PacketArray)},
  +          {element(1, B), read_tcp_stream(B, PacketArray)}}
  +     end || {Flow, Idxs} <- Flows ].
   
   tcp_packet_array(File) ->
       enet_pcap:file_foldl(File,
  
positive.code:               end
                || {Flow, [A, B]} <- tcp_flows(PacketArray)],
      lists:reverse(lists:keysort(2, Times)).
  
negative.code: tcp_pa_fold(#pcap_hdr{datalinktype=Link},
              #pcap_pkt{ts={S,US},data=P},
              {Array,Cnt}) ->
      Pkt = enet_codec:decode(Link, P, [null, ethernet, ipv4, ipv6, tcp]),
      TS = (S * 1000000) + US,
      {array:set(Cnt, {TS, Pkt}, Array), Cnt + 1}.
  
  %% Classifies based on src and dst hosts and ports only. Assumes that
  %% a flow isn't re-used within a capture.
  tcp_flows(PacketArray) ->
      D = array:foldl(fun tcp_flow_fold/3,
                      dict:new(),
                      PacketArray),
      dict:to_list(D).
  
  tcp_flow_parts(Flow = {A,B}, Flows, PacketArray) ->
      Idxs = proplists:get_value(Flow, Flows),
      tcp_flow_parts2(Flow, Idxs, PacketArray).
  
  tcp_flow_parts2(Flow = {A,B}, Idxs, PacketArray) ->
      { {{A,B},
         [ I || I <- Idxs,
                tcp_flow(element(2, array:get(I, PacketArray))) =:= {A,B} ]},
        {{B, A},
         [ I || I <- Idxs,
                tcp_flow(element(2, array:get(I, PacketArray))) =:= {B,A} ]}
      }.
  
  tcp_flow(#null{type = T, data = Pkt}) when T =:= ipv4;
                                             T =:= ipv6 ->
      tcp_flow(Pkt);
  tcp_flow(#eth{type = T, data = Pkt}) when T =:= ipv4;
                                            T =:= ipv6 ->
      tcp_flow(Pkt);
  tcp_flow(#ipv4{src=S,
                 dst=D,
                 proto=tcp,
                 data=#tcp{src_port=Sp,
                           dst_port=Dp}}) ->
      tcp_flow(S, Sp, D, Dp);
  tcp_flow(#ipv6{src=S,
                 dst=D,
                 payload=Payload}) ->
      case lists:keyfind(tcp, 1, Payload) of
          #tcp{src_port=Sp,
               dst_port=Dp} ->
              tcp_flow(S, Sp, D, Dp);
          _ -> not_tcp
      end;
  tcp_flow(_) -> not_tcp.
      
  tcp_flow(Srcaddr, Srcport, Dstaddr, Dstport) ->
      Src = {Srcaddr, Srcport},
      Dst = {Dstaddr, Dstport},
      {Src, Dst}.
  
  tcp_flow_sort(Data) ->
      {A,B} = tcp_flow(Data),
      {erlang:min(A, B), erlang:max(A, B)}.
  
  tcp_flow_fold(Idx, {_TS,Pkt}, FlowD) ->
      case tcp_flow_sort(Pkt) of
          not_tcp -> FlowD;
          Flow -> dict:append(Flow, Idx, FlowD)
      end.
  
  tcp_establishment_times(File) ->
      {PacketArray,_Count} = tcp_packet_array(File),
  