anchor.diff:      tapestry_config/2,
       tapestry_config/3,
       tapestry_config/4,
  +    tapestry_config_add/3,
  +    tapestry_config_add/4,
       connect/2,
       disconnect/0,
       disconnect/1,
  
positive.code: %% Configure switch associated with Key for tapestry.  Remove all the
  %% flows on table 0, dns_tap with priority 200 from Port1 to Port2 and
  %% the controller.  Bridge between Port1 and Port2.
  %% If Key is ``default'', clear all flows on the default switch.
  %% @end
  -spec tapestry_config(switch_key(), integer(), integer(), [ipaddress()]) -> ok.
  tapestry_config(Key, Port1, Port2, DnsIps) ->
      ?DEBUG("clear_flows: ~p~n", [clear_flows(Key, 0)]),
      ?DEBUG("bridge: ~p~n", [bridge(Key, 100, Port1, Port2)]),
      ?DEBUG("dns_tap: ~p~n",
                  [dns_tap(Key, 200, Port1, Port2, controller, DnsIps)]),
  
negative.code: 
  do_tapestry_config(Key, Config) ->
      ?DEBUG("configuring ~p with ~p~n", [Key, Config]),
      Port1List = config_values(dns_port, Config),
      Port2List = config_values(client_port, Config),
      DnsIpsList = config_values(dns_ips, Config),
      [{FirstPort1, FirstPort2, FirstDnsIps} | Rest] = 
                                  lists:zip3(Port1List, Port2List, DnsIpsList),
      tapestry_config(Key, FirstPort1, FirstPort2, FirstDnsIps),
      [tapestry_config_add(Key, Port1, Port2, DnsIps) ||
          {Port1, Port2, DnsIps} <- Rest],
      ok.
  
  consult_config(Filename) ->
      case file:consult(Filename) of
  