anchor.diff:                  end,
               NewOutPorts = lists:usort(lists:map(fun fc_utils:id_to_port_no/1, OutPorts)
                                         ++ ExistingOutports),
  +            DecodedMatches = dofl_identifier:decode_matches(Matches),
               {SwitchId, ?OF_VERSION,
  -             {Matches,
  +             {DecodedMatches,
                 [{apply_actions,
                   [{output, OutPort, no_buffer} || OutPort <- NewOutPorts]}],
                 %% XXX: should we take priority of existing rule into account?
  
positive.code:                   {continue, Acc};
               (Id, #{<<"type">> := #{value := <<"of_flow_mod">>},
                      <<"matches">> := #{value := Matches},
                      <<"instructions">> := #{value := Instructions}},
                _, Acc) ->
                    %% A flow rule.
                    case Matches of
                        [#{<<"match">> := <<"in_port">>,
                           <<"value">> := TheInPortNo}] when TheInPortNo =:= InPortNo ->
                            %% Match the same inport we care about, and nothing else.
                            %% Check that it outputs to the right port.
                            case [Instruction ||
                                     Instruction = #{<<"instruction">> := <<"apply_actions">>} <- Instructions] of
                                [] ->
                                    %% No "apply actions" instruction.  Not interesting.
                                    {skip, Acc};
                                [#{<<"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.
                                            {stop, {Id, Matches, Instructions}};
                                        false ->
                                            %% No, the output port doesn't match.
                                            {skip, Acc}
                                    end
                            end;
                        _ ->
                            %% Not the rule we're looking for.
                            {skip, Acc}
                    end;
               (_, _, _, Acc) ->
                    %% Skip everything else.
                    {skip, Acc}
            end,
            not_found,
            SwitchId,
            [depth, {max_depth, 2}]),
      DefaultPriority = 50,
      case ExistingFlowRule of
          not_found ->
              io:format(standard_error,
                        "Expected flow rule in switch ~s from port ~p to port ~p, but none found~n",
                        [SwitchId, InPort, OutPort]),
              [];
          {Cookie, Matches, Instructions} ->
              ExistingOutports =
                  case [Instruction ||
                           Instruction = #{<<"instruction">> := <<"apply_actions">>} <- Instructions] of
                      [] ->
                          [];
                      [#{<<"actions">> := Actions}] ->
                          [TheOutPort || #{<<"action">> := <<"output">>, <<"port">> := TheOutPort} <- Actions]
                  end,
              NewOutPorts = lists:usort([controller] ++ ExistingOutports),
              DecodedMatches = lists:map(
                                 fun(#{<<"match">> := Field, <<"value">> := Value}) ->
                                         {binary_to_atom(Field, utf8), Value}
                                 end, 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.
  
negative.code:     OutPortNo = fc_utils:id_to_port_no(OutPort),
      %% First, check if there is already a flow rule with the same
      %% match.
      ExistingFlowRules =
          dby:search(
            fun(Id, _NodeMetadata, [], Acc) when Id =:= SwitchId ->
                    %% Starting point. Go on.
  