    private TCPSniffer(String[] args)
    {
	SnifferFilter requestFilter = new EchoFilter();
	SnifferFilter responseFilter = new EchoFilter();
	int localPort = 8001;
	String remoteHost = "localhost";
	String localHost = "localhost";
	int remotePort = 7001;
	boolean useSSL = false;
	boolean proxy = false;
	int initialTest = 0;
	int timeout = 0; 
	boolean useColour = false;
	try {
	    for (int i=0; i < args.length; i++)
	    {
		if (args[i].equals("-initialTest")) {
		    initialTest = Integer.parseInt(args[++i]);
		}
	    }
	    System.setProperty(INITIAL_TEST_PROPERTY,
			       Integer.toString(initialTest));
	    for (int i=0; i<args.length; i++)
	    {
		if (args[i].equals("-requestFilter")) {
		    requestFilter = instantiateFilter(args[++i]);
		}
		else if (args[i].equals("-responseFilter")) {
		    responseFilter = instantiateFilter(args[++i]);
		}
		else if (args[i].equals("-httpPluginFilter")) {
		    requestFilter = new HttpPluginSnifferFilter();
		    responseFilter = new HttpPluginSnifferResponseFilter();
		}
		else if (args[i].equals("-localHost")) {
		    localHost = args[++i];
		}
		else if (args[i].equals("-localPort")) {
		    localPort = Integer.parseInt(args[++i]);
		}
		else if (args[i].equals("-remoteHost")) {
		    remoteHost = args[++i];
		}
		else if (args[i].equals("-remotePort")) {
		    remotePort = Integer.parseInt(args[++i]);
		}
		else if (args[i].equals("-ssl")) {
		    useSSL = true;
		}
		else if (args[i].equals("-keyStore")) {
		    System.setProperty(JSSEConstants.KEYSTORE_PROPERTY,
				       args[++i]);
		}
		else if (args[i].equals("-keyStorePassword")) {
		    System.setProperty(
			JSSEConstants.KEYSTORE_PASSWORD_PROPERTY, args[++i]);
		}
		else if (args[i].equals("-keyStoreType")) {
		    System.setProperty(JSSEConstants.KEYSTORE_TYPE_PROPERTY,
				       args[++i]);
		}
		else if (args[i].equals("-proxy")) {
		    proxy = true;
		}
		else if (args[i].equals("-timeout")) {
		    timeout = Integer.parseInt(args[++i]) * 1000;
		}
		else if (args[i].equals("-output")) {
		    final String outputFile = args[++i];
		    System.setOut(new PrintStream(
			new FileOutputStream(outputFile + ".out"), true));
		    System.setErr(new PrintStream(
			new FileOutputStream(outputFile + ".err"), true));
		}
		else if (args[i].equals("-colour")) {
		    useColour = true;
		}
		else if (args[i].equals("-initialTest")) {
		    ++i;
		}
		else {
		    throw barfUsage();
		}
	    }
	}
	catch (Exception e) {
	    throw barfUsage();
	}
	if (timeout < 0) {
	    throw barfUsage("Timeout must be non-negative");
	}
	final StringBuffer startMessage = new StringBuffer();
	startMessage.append(
	    "Initialising " + (useSSL ? "SSL" : "standard") +
	    " sniffer engine with the parameters:" +
	    "\n   Request filter:  " + requestFilter.getClass().getName() +
	    "\n   Response filter: " + responseFilter.getClass().getName() +
	    "\n   Local host:       " + localHost + 
	    "\n   Local port:       " + localPort);
	if (proxy) {
	    startMessage.append(
		"\n   Listening as " + (useSSL ? "an HTTP/HTTPS" : "an HTTP") +
		" proxy");
	} else {
	    startMessage.append(
		"\n   Remote host:      " + remoteHost +
		"\n   Remote port:      " + remotePort);
	}
	if (useSSL) {
	    startMessage.append(
		"\n   (SSL setup could take a few seconds)");
	}
	System.err.println(startMessage);
	try {
	    final SnifferSocketFactory sslSocketFactory;
	    if (useSSL) {
		final Class socketFactoryClass =
		    Class.forName(SSL_SOCKET_FACTORY_CLASS);
		sslSocketFactory =
		    (SnifferSocketFactory)socketFactoryClass.newInstance();
	    }
	    else {
		sslSocketFactory = null;
	    }
	    if (proxy) {
		m_snifferEngine = 
		    new HTTPProxySnifferEngine(new SnifferPlainSocketFactory(),
					       sslSocketFactory,
					       requestFilter,
					       responseFilter,
					       localHost,
					       localPort,
					       useColour,
					       timeout);
	    }
	    else {
		m_snifferEngine =
		    new SnifferEngineImplementation(
			useSSL ?
			new SnifferPlainSocketFactory() : sslSocketFactory,
			requestFilter,
			responseFilter,
			new ConnectionDetails(localHost, localPort,
					      remoteHost, remotePort,
					      useSSL),
			useColour,
			timeout);
	    }
	    System.err.println("Engine initialised, listening on port " +
			       localPort);
	}
	catch (Exception e){
	    System.err.println("Could not initialise engine:");
	    e.printStackTrace();
	    System.exit(2);
	}
    }

    private TCPSniffer(String[] args)
    {
	SnifferFilter requestFilter = new EchoFilter();
	SnifferFilter responseFilter = new EchoFilter();
	int localPort = 8001;
	String remoteHost = "localhost";
	String localHost = "localhost";
	int remotePort = 7001;
	boolean useSSL = false;
	boolean proxy = false;
	int initialTest = 0;
	int timeout = 0; 
	boolean useColour = false;
	try {
	    for (int i=0; i < args.length; i++)
	    {
		if (args[i].equals("-initialTest")) {
		    initialTest = Integer.parseInt(args[++i]);
		}
	    }
	    System.setProperty(INITIAL_TEST_PROPERTY,
			       Integer.toString(initialTest));
	    for (int i=0; i<args.length; i++)
	    {
		if (args[i].equals("-requestFilter")) {
		    requestFilter = instantiateFilter(args[++i]);
		}
		else if (args[i].equals("-responseFilter")) {
		    responseFilter = instantiateFilter(args[++i]);
		}
		else if (args[i].equals("-httpPluginFilter")) {
		    requestFilter = new HttpPluginSnifferFilter();
		    responseFilter = new HttpPluginSnifferResponseFilter();
		}
		else if (args[i].equals("-localHost")) {
		    localHost = args[++i];
		}
		else if (args[i].equals("-localPort")) {
		    localPort = Integer.parseInt(args[++i]);
		}
		else if (args[i].equals("-remoteHost")) {
		    remoteHost = args[++i];
		}
		else if (args[i].equals("-remotePort")) {
		    remotePort = Integer.parseInt(args[++i]);
		}
		else if (args[i].equals("-ssl")) {
		    useSSL = true;
		}
		else if (args[i].equals("-keyStore")) {
		    System.setProperty(JSSEConstants.KEYSTORE_PROPERTY,
				       args[++i]);
		}
		else if (args[i].equals("-keyStorePassword")) {
		    System.setProperty(
			JSSEConstants.KEYSTORE_PASSWORD_PROPERTY, args[++i]);
		}
		else if (args[i].equals("-keyStoreType")) {
		    System.setProperty(JSSEConstants.KEYSTORE_TYPE_PROPERTY,
				       args[++i]);
		}
		else if (args[i].equals("-proxy")) {
		    proxy = true;
		}
		else if (args[i].equals("-timeout")) {
		    timeout = Integer.parseInt(args[++i]) * 1000;
		}
		else if (args[i].equals("-output")) {
		    final String outputFile = args[++i];
		    System.setOut(new PrintStream(
			new FileOutputStream(outputFile + ".out"), true));
		    System.setErr(new PrintStream(
			new FileOutputStream(outputFile + ".err"), true));
		}
		else if (args[i].equals("-colour")) {
		    useColour = true;
		}
		else if (args[i].equals("-initialTest")) {
		    ++i;
		}
		else {
		    throw barfUsage();
		}
	    }
	}
	catch (Exception e) {
	    throw barfUsage();
	}
	if (timeout < 0) {
	    throw barfUsage("Timeout must be non-negative");
	}
	final StringBuffer startMessage = new StringBuffer();
	startMessage.append(
	    "Initialising " + (useSSL ? "SSL" : "standard") +
	    " sniffer engine with the parameters:" +
	    "\n   Request filter:  " + requestFilter.getClass().getName() +
	    "\n   Response filter: " + responseFilter.getClass().getName() +
	    "\n   Local host:       " + localHost + 
	    "\n   Local port:       " + localPort);
	if (proxy) {
	    startMessage.append(
		"\n   Listening as " + (useSSL ? "an HTTP/HTTPS" : "an HTTP") +
		" proxy");
	} else {
	    startMessage.append(
		"\n   Remote host:      " + remoteHost +
		"\n   Remote port:      " + remotePort);
	}
	if (useSSL) {
	    startMessage.append(
		"\n   (SSL setup could take a few seconds)");
	}
	System.err.println(startMessage);
	try {
	    final SnifferSocketFactory sslSocketFactory;
	    if (useSSL) {
		final Class socketFactoryClass =
		    Class.forName(SSL_SOCKET_FACTORY_CLASS);
		sslSocketFactory =
		    (SnifferSocketFactory)socketFactoryClass.newInstance();
	    }
	    else {
		sslSocketFactory = null;
	    }
	    if (proxy) {
		m_snifferEngine = 
		    new HTTPProxySnifferEngine(new SnifferPlainSocketFactory(),
					       sslSocketFactory,
					       requestFilter,
					       responseFilter,
					       localHost,
					       localPort,
					       useColour,
					       timeout);
	    }
	    else {
		m_snifferEngine =
		    new SnifferEngineImplementation(
			useSSL ?
			sslSocketFactory : new SnifferPlainSocketFactory(),
			requestFilter,
			responseFilter,
			new ConnectionDetails(localHost, localPort,
					      remoteHost, remotePort,
					      useSSL),
			useColour,
			timeout);
	    }
	    System.err.println("Engine initialised, listening on port " +
			       localPort);
	}
	catch (Exception e){
	    System.err.println("Could not initialise engine:");
	    e.printStackTrace();
	    System.exit(2);
	}
    }
