anchor.diff:                [{apply_actions,
                   [{output, fc_utils:id_to_port_no(OutPort), no_buffer} || OutPort <- OutPorts]}],
                 [{table_id, 0}, {cookie, unique_cookie()}, {priority, DefaultPriority}]}};
  -        {Cookie, Matches, Instructions} ->
  +        {EncodedCookie, Matches, Instructions} ->
  +            Cookie = decode_cookie(EncodedCookie),
               ExistingOutports =
                   case [Instruction ||
                            Instruction = #{<<"instruction">> := <<"apply_actions">>} <- Instructions] of
  
positive.code:                 end,
              NewOutPorts = lists:usort(lists:map(fun fc_utils:id_to_port_no/1, OutPorts)
                                        ++ ExistingOutports),
              {SwitchId, ?OF_VERSION,
               {Matches,
                [{apply_actions,
                  [{output, OutPort, no_buffer} || OutPort <- NewOutPorts]}],
                %% XXX: should we take priority of existing rule into account?
  
negative.code:                   {continue, Acc};
               (Id, #{<<"type">> := #{value := <<"of_flow_mod">>},
                      <<"matches">> := #{value := Matches},
                      <<"instructions">> := #{value := Instructions}} = FlowMod,
                _, Acc) ->
                    %% A flow rule.
                    case is_flow_rule_from_to(InPortNo, OutPortNo, FlowMod) of
                        true ->
                            {continue, [{Id, Matches, Instructions}] ++ Acc};
                        false ->
                            %% No, the output port doesn't match.
                            {skip, Acc}
                    end;
               (_, _, _, Acc) ->
                    %% Skip everything else.
                    {skip, Acc}
            end,
            [],
            SwitchId,
            [breadth, {max_depth, 4}]),
      DefaultPriority = 50,
      case ExistingFlowRules of
          [] ->
              io:format(standard_error,
                        "Expected flow rule in switch ~s from port ~p to port ~p, but none found~n",
                        [SwitchId, InPort, OutPort]),
              [];
          [_|_] ->
              lists:map(
                fun({EncodedCookie, Matches, Instructions}) ->
                        Cookie = decode_cookie(EncodedCookie),
                        ExistingOutports =
                            case [Instruction ||
                                     Instruction = #{<<"instruction">> := <<"apply_actions">>} <- Instructions] of
                                [] ->
                                    [];
                                [#{<<"actions">> := Actions}] ->
                                    [TheOutPort || #{<<"action">> := <<"output">>, <<"port">> := TheOutPort} <- Actions]
                            end,
                        NewOutPorts = lists:usort([controller] ++ ExistingOutports),
                        DecodedMatches = dofl_identifier:decode_matches(Matches),
                        {SwitchId, ?OF_VERSION,
                         {DecodedMatches,
                          [{apply_actions,
                            [{output, TheOutPort, no_buffer} || TheOutPort <- NewOutPorts]}],
                          %% XXX: should we take priority of existing rule into account?
                          [{table_id, 0}, {cookie, Cookie}, {priority, DefaultPriority}]}}
                end, ExistingFlowRules)
      end.
  
  is_flow_rule_from_to(InPortNo, OutPortNo,
                       #{<<"type">> := #{value := <<"of_flow_mod">>},
                         <<"matches">> := #{value := Matches},
                         <<"instructions">> := #{value := Instructions}}) ->
      %% A flow rule.
      case lists:any(
             fun(#{<<"match">> := MatchField,
                   <<"value">> := MatchValue}) ->
                     MatchField =:= <<"in_port">> andalso
                         MatchValue =:= InPortNo
             end, Matches) of
          true ->
              %% Match the same inport we care about.
              %% Check that it outputs to the right port.
              case [Instruction ||
                       Instruction = #{<<"instruction">> := <<"apply_actions">>} <- Instructions] of
                  [] ->
                      %% No "apply actions" instruction.  Not interesting.
                      false;
                  [#{<<"actions">> := Actions}] ->
                      OutPorts = [ThisOutPort ||
                                     #{<<"action">> := <<"output">>, <<"port">> := ThisOutPort} <- Actions],
                      case lists:member(OutPortNo, OutPorts) of
                          true ->
                              %% Output port matches as
                              %% well.  This is the rule
                              %% we want to tap.
                              true;
                          false ->
                              %% No, the output port doesn't match.
                              false
                      end
              end;
          false ->
              %% Not the rule we're looking for.
              false
      end.
  
  decode_cookie(Bin) when is_binary(Bin) ->
      %% In Dobby, flow mod cookies are currently encoded as string
      %% representation of Erlang binaries.
      case erl_scan:string(binary_to_list(Bin) ++ ".") of
          {ok, Tokens, _} ->
              case erl_parse:parse_term(Tokens) of
                  {ok, Cookie} ->
                      Cookie;
                  {error, ErrorInfo} ->
                      error({parse_error, ErrorInfo}, [Bin])
              end;
          {error, ErrorInfo, _ErrorLocation} ->
              error({scan_error, ErrorInfo}, [Bin])
      end.
  