anchor.diff:    keys = ${tun.keys}
     address = ${tun.address}
     port = ${toString tun.port}
  +  inbound.length = ${toString tun.inbound.length}
  +  outbound.length = ${toString tun.outbound.length}
  +  inbound.quantity = ${toString tun.inbound.quantity}
  +  outbound.quantity = ${toString tun.outbound.quantity}
  +  crypto.tagsToSend = ${toString tun.crypto.tagsToSend}
     '')
     }
     ${flip concatMapStrings
  -    (collect (tun: tun ? port && tun ? host) cfg.outTunnels)
  +    (collect (tun: tun ? port && tun ? host) cfg.inTunnels)
       (tun: let portStr = toString tun.port; in ''
     [${tun.name}]
     type = server
  
positive.code:         '';
        };
  
        http = {
          port = mkOption {
            type = types.int;
            default = 7070;
            description = ''
              HTTP listen port.
            '';
          };
        };
  
        proxy = {
          httpPort = mkOption {
            type = types.int;
            default = 4446;
            description = ''
              HTTP proxy listen port.
            '';
          };
          socksPort = mkOption {
            type = types.int;
            default = 4447;
            description = ''
              SOCKS proxy listen port.
            '';
          };
        };
  
        irc = {
          host = mkOption {
            type = types.str;
            default = "127.0.0.1";
            description = ''
              Address to forward incoming traffic to. 127.0.0.1 by default.
            '';
          };
          dest = mkOption {
            type = types.str;
            default = "irc.postman.i2p";
            description = ''
              Destination I2P tunnel endpoint address of IRC server. irc.postman.i2p by default.
            '';
          };
          port = mkOption {
            type = types.int;
            default = 6668;
            description = ''
              Local IRC tunnel endoint port to listen on. 6668 by default.
            '';
          };
          keyFile = mkOption {
            type = types.str;
            default = "privKeys.dat";
            description = ''
              File name containing destination keys. privKeys.dat by default.
            '';
          };
        };
  
        eep = {
          host = mkOption {
            type = types.str;
            default = "127.0.0.1";
            description = ''
              Address to forward incoming traffic to. 127.0.0.1 by default.
            '';
          };
          port = mkOption {
            type = types.int;
            default = 80;
            description = ''
              Port to forward incoming traffic to. 80 by default.
            '';
          };
          keyFile = mkOption {
            type = types.str;
            default = "privKeys.dat";
            description = ''
              File name containing destination keys. privKeys.dat by default.
            '';
          };
        };
  
        sam = {
          port = mkOption {
            type = with types; nullOr int;
            default = null;
            description = ''
              Local SAM tunnel endpoint. Usually 7656. SAM is disabled if not specified.
            '';
          };
        };
  
        outTunnels = mkOption {
          default = {};
  	      type = with types; loaOf optionSet;
  	      description = ''
  	      '';
  	      options = [ ({ name, config, ... }: {
  
  	        options = {
  	          name = mkOption {
  	            type = types.str;
  	            description = "The name of the tunnel.";
  	          };
  	          destination = mkOption {
  	            type = types.str;
  	            description = "Remote endpoint, I2P hostname or b32.i2p address.";
  	          };
  	          keys = mkOption {
  	            type = types.str;
  	            default = name + "-keys.dat";
  	            description = "Keyset used for tunnel identity.";
  	          };
  	          address = mkOption {
  	            type = types.str;
  	            default = "127.0.0.1";
  	            description = "Local bind address for tunnel.";
  	          };
  	          port = mkOption {
  	            type = types.int;
  	            default = 0;
  	            description = "Local tunnel listen port.";
  	          };
  	        };
  
  	        config = {
  	          name = mkDefault name;
  	        };
  
  	      }) ];
        };
  
        inTunnels = mkOption {
          default = {};
  	      type = with types; loaOf optionSet;
  	      description = ''
  	      '';
  	      options = [ ({ name, config, ... }: {
  
  	        options = {
  
  	          name = mkOption {
  	            type = types.str;
  	            description = "The name of the tunnel.";
  	          };
  	          keys = mkOption {
  	            type = types.path;
  	            default = name + "-keys.dat";
  	            description = "Keyset used for tunnel identity.";
  	          };
  	          address = mkOption {
  	            type = types.str;
  	            default = "127.0.0.1";
  	            description = "Local service IP address.";
  	          };
  	          port = mkOption {
  	            type = types.int;
  	            default = 0;
  	            description = "Local tunnel listen port.";
  	          };
  	          inPort = mkOption {
  	            type = types.int;
  	            default = 0;
  	            description = "I2P service port. Default to the tunnel's listen port.";
  	          };
  	          accessList = mkOption {
  	            type = with types; listOf str;
  	            default = [];
  	            description = "I2P nodes that are allowed to connect to this service.";
  	          };
  
  	        };
  
  	        config = {
  	          name = mkDefault name;
  	        };
  
  	      }) ];
        };
      };
    };
  
negative.code: 
    toOneZero = b: if b then "1" else "0";
  
    mkEndpointOpt = name: addr: port: {
      name = mkOption {
        type = types.str;
        default = name;
        description = "The endpoint name.";
      };
      address = mkOption {
        type = types.str;
        default = addr;
        description = "Bind address for ${name} endpoint. Default: " + addr;
      };
      port = mkOption {
        type = types.int;
        default = port;
        description = "Bind port for ${name} endoint. Default: " + toString port;
      };
    };
  
    commonTunOpts = let
      i2cpOpts = {
        length = mkOption {
          type = types.int;
          description = "Guaranteed minimum hops.";
          default = 3;
        };
        quantity = mkOption {
          type = types.int;
          description = "Number of simultaneous tunnels.";
          default = 5;
        };
      };
    in name: {
      outbound = i2cpOpts;
      inbound = i2cpOpts;
      crypto.tagsToSend = mkOption {
        type = types.int;
        description = "Number of ElGamal/AES tags to send.";
        default = 40;
      };
     destination = mkOption {
        type = types.str;
        description = "Remote endpoint, I2P hostname or b32.i2p address.";
      };
      keys = mkOption {
        type = types.str;
        default = name + "-keys.dat";
        description = "Keyset used for tunnel identity.";
      };
    } // mkEndpointOpt name "127.0.0.1" 0;
  
    i2pdConf = pkgs.writeText "i2pd.conf" ''
        ipv6 = ${toOneZero cfg.enableIPv6}
        notransit = ${toOneZero cfg.notransit}
        floodfill = ${toOneZero cfg.floodfill}
        ${if isNull cfg.port then "" else "port = ${toString cfg.port}"}
        ${flip concatMapStrings
          (collect (proto: proto ? port && proto ? address && proto ? name) cfg.proto)
          (proto: let portStr = toString proto.port; in ''
        [${proto.name}]
        address = ${proto.address}
        port = ${toString proto.port}
        '')
        }
    '';
  
    i2pdTunnelConf = pkgs.writeText "i2pd-tunnels.conf" ''
  