diff --git a/bridge/irc/handlers.go b/bridge/irc/handlers.go
new file mode 100644
index 00000000..41d69b0a
--- /dev/null
+++ b/bridge/irc/handlers.go
@@ -0,0 +1,238 @@
+package birc
+
+import (
+	"bytes"
+	"fmt"
+	"io"
+	"io/ioutil"
+	"regexp"
+	"strconv"
+	"strings"
+	"time"
+
+	"github.com/42wim/matterbridge/bridge/config"
+	"github.com/42wim/matterbridge/bridge/helper"
+	"github.com/dfordsoft/golib/ic"
+	"github.com/lrstanley/girc"
+	"github.com/paulrosania/go-charset/charset"
+	"github.com/saintfish/chardet"
+
+	// We need to import the 'data' package as an implicit dependency.
+	// See: https://godoc.org/github.com/paulrosania/go-charset/charset
+	_ "github.com/paulrosania/go-charset/data"
+)
+
+func (b *Birc) handleCharset(msg *config.Message) error {
+	if b.GetString("Charset") != "" {
+		switch b.GetString("Charset") {
+		case "gbk", "gb18030", "gb2312", "big5", "euc-kr", "euc-jp", "shift-jis", "iso-2022-jp":
+			msg.Text = ic.ConvertString("utf-8", b.GetString("Charset"), msg.Text)
+		default:
+			buf := new(bytes.Buffer)
+			w, err := charset.NewWriter(b.GetString("Charset"), buf)
+			if err != nil {
+				b.Log.Errorf("charset from utf-8 conversion failed: %s", err)
+				return err
+			}
+			fmt.Fprint(w, msg.Text)
+			w.Close()
+			msg.Text = buf.String()
+		}
+	}
+	return nil
+}
+
+// handleFiles returns true if we have handled the files, otherwise return false
+func (b *Birc) handleFiles(msg *config.Message) bool {
+	if msg.Extra == nil {
+		return false
+	}
+	for _, rmsg := range helper.HandleExtra(msg, b.General) {
+		b.Local <- rmsg
+	}
+	if len(msg.Extra["file"]) == 0 {
+		return false
+	}
+	for _, f := range msg.Extra["file"] {
+		fi := f.(config.FileInfo)
+		if fi.Comment != "" {
+			msg.Text += fi.Comment + ": "
+		}
+		if fi.URL != "" {
+			msg.Text = fi.URL
+			if fi.Comment != "" {
+				msg.Text = fi.Comment + ": " + fi.URL
+			}
+		}
+		b.Local <- config.Message{Text: msg.Text, Username: msg.Username, Channel: msg.Channel, Event: msg.Event}
+	}
+	return true
+}
+
+func (b *Birc) handleJoinPart(client *girc.Client, event girc.Event) {
+	if len(event.Params) == 0 {
+		b.Log.Debugf("handleJoinPart: empty Params? %#v", event)
+		return
+	}
+	channel := strings.ToLower(event.Params[0])
+	if event.Command == "KICK" && event.Params[1] == b.Nick {
+		b.Log.Infof("Got kicked from %s by %s", channel, event.Source.Name)
+		time.Sleep(time.Duration(b.GetInt("RejoinDelay")) * time.Second)
+		b.Remote <- config.Message{Username: "system", Text: "rejoin", Channel: channel, Account: b.Account, Event: config.EventRejoinChannels}
+		return
+	}
+	if event.Command == "QUIT" {
+		if event.Source.Name == b.Nick && strings.Contains(event.Trailing, "Ping timeout") {
+			b.Log.Infof("%s reconnecting ..", b.Account)
+			b.Remote <- config.Message{Username: "system", Text: "reconnect", Channel: channel, Account: b.Account, Event: config.EventFailure}
+			return
+		}
+	}
+	if event.Source.Name != b.Nick {
+		if b.GetBool("nosendjoinpart") {
+			return
+		}
+		b.Log.Debugf("<= Sending JOIN_LEAVE event from %s to gateway", b.Account)
+		msg := config.Message{Username: "system", Text: event.Source.Name + " " + strings.ToLower(event.Command) + "s", Channel: channel, Account: b.Account, Event: config.EventJoinLeave}
+		b.Log.Debugf("<= Message is %#v", msg)
+		b.Remote <- msg
+		return
+	}
+	b.Log.Debugf("handle %#v", event)
+}
+
+func (b *Birc) handleNewConnection(client *girc.Client, event girc.Event) {
+	b.Log.Debug("Registering callbacks")
+	i := b.i
+	b.Nick = event.Params[0]
+
+	i.Handlers.Add("PRIVMSG", b.handlePrivMsg)
+	i.Handlers.Add("CTCP_ACTION", b.handlePrivMsg)
+	i.Handlers.Add(girc.RPL_TOPICWHOTIME, b.handleTopicWhoTime)
+	i.Handlers.Add(girc.NOTICE, b.handleNotice)
+	i.Handlers.Add("JOIN", b.handleJoinPart)
+	i.Handlers.Add("PART", b.handleJoinPart)
+	i.Handlers.Add("QUIT", b.handleJoinPart)
+	i.Handlers.Add("KICK", b.handleJoinPart)
+}
+
+func (b *Birc) handleNickServ() {
+	if !b.GetBool("UseSASL") && b.GetString("NickServNick") != "" && b.GetString("NickServPassword") != "" {
+		b.Log.Debugf("Sending identify to nickserv %s", b.GetString("NickServNick"))
+		b.i.Cmd.Message(b.GetString("NickServNick"), "IDENTIFY "+b.GetString("NickServPassword"))
+	}
+	if strings.EqualFold(b.GetString("NickServNick"), "Q@CServe.quakenet.org") {
+		b.Log.Debugf("Authenticating %s against %s", b.GetString("NickServUsername"), b.GetString("NickServNick"))
+		b.i.Cmd.Message(b.GetString("NickServNick"), "AUTH "+b.GetString("NickServUsername")+" "+b.GetString("NickServPassword"))
+	}
+	// give nickserv some slack
+	time.Sleep(time.Second * 5)
+	b.authDone = true
+}
+
+func (b *Birc) handleNotice(client *girc.Client, event girc.Event) {
+	if strings.Contains(event.String(), "This nickname is registered") && event.Source.Name == b.GetString("NickServNick") {
+		b.handleNickServ()
+	} else {
+		b.handlePrivMsg(client, event)
+	}
+}
+
+func (b *Birc) handleOther(client *girc.Client, event girc.Event) {
+	if b.GetInt("DebugLevel") == 1 {
+		if event.Command != "CLIENT_STATE_UPDATED" &&
+			event.Command != "CLIENT_GENERAL_UPDATED" {
+			b.Log.Debugf("%#v", event.String())
+		}
+		return
+	}
+	switch event.Command {
+	case "372", "375", "376", "250", "251", "252", "253", "254", "255", "265", "266", "002", "003", "004", "005":
+		return
+	}
+	b.Log.Debugf("%#v", event.String())
+}
+
+func (b *Birc) handleOtherAuth(client *girc.Client, event girc.Event) {
+	b.handleNickServ()
+	b.handleRunCommands()
+	// we are now fully connected
+	b.connected <- nil
+}
+
+func (b *Birc) handlePrivMsg(client *girc.Client, event girc.Event) {
+	if b.skipPrivMsg(event) {
+		return
+	}
+	rmsg := config.Message{Username: event.Source.Name, Channel: strings.ToLower(event.Params[0]), Account: b.Account, UserID: event.Source.Ident + "@" + event.Source.Host}
+	b.Log.Debugf("== Receiving PRIVMSG: %s %s %#v", event.Source.Name, event.Trailing, event)
+
+	// set action event
+	if event.IsAction() {
+		rmsg.Event = config.EventUserAction
+	}
+
+	// strip action, we made an event if it was an action
+	rmsg.Text += event.StripAction()
+
+	// strip IRC colors
+	re := regexp.MustCompile(`\x03(?:\d{1,2}(?:,\d{1,2})?)?|[[:cntrl:]]`)
+	rmsg.Text = re.ReplaceAllString(rmsg.Text, "")
+
+	// start detecting the charset
+	var r io.Reader
+	var err error
+	mycharset := b.GetString("Charset")
+	if mycharset == "" {
+		// detect what were sending so that we convert it to utf-8
+		detector := chardet.NewTextDetector()
+		result, err := detector.DetectBest([]byte(rmsg.Text))
+		if err != nil {
+			b.Log.Infof("detection failed for rmsg.Text: %#v", rmsg.Text)
+			return
+		}
+		b.Log.Debugf("detected %s confidence %#v", result.Charset, result.Confidence)
+		mycharset = result.Charset
+		// if we're not sure, just pick ISO-8859-1
+		if result.Confidence < 80 {
+			mycharset = "ISO-8859-1"
+		}
+	}
+	switch mycharset {
+	case "gbk", "gb18030", "gb2312", "big5", "euc-kr", "euc-jp", "shift-jis", "iso-2022-jp":
+		rmsg.Text = ic.ConvertString("utf-8", b.GetString("Charset"), rmsg.Text)
+	default:
+		r, err = charset.NewReader(mycharset, strings.NewReader(rmsg.Text))
+		if err != nil {
+			b.Log.Errorf("charset to utf-8 conversion failed: %s", err)
+			return
+		}
+		output, _ := ioutil.ReadAll(r)
+		rmsg.Text = string(output)
+	}
+
+	b.Log.Debugf("<= Sending message from %s on %s to gateway", event.Params[0], b.Account)
+	b.Remote <- rmsg
+}
+
+func (b *Birc) handleRunCommands() {
+	for _, cmd := range b.GetStringSlice("RunCommands") {
+		if err := b.i.Cmd.SendRaw(cmd); err != nil {
+			b.Log.Errorf("RunCommands %s failed: %s", cmd, err)
+		}
+		time.Sleep(time.Second)
+	}
+}
+
+func (b *Birc) handleTopicWhoTime(client *girc.Client, event girc.Event) {
+	parts := strings.Split(event.Params[2], "!")
+	t, err := strconv.ParseInt(event.Params[3], 10, 64)
+	if err != nil {
+		b.Log.Errorf("Invalid time stamp: %s", event.Params[3])
+	}
+	user := parts[0]
+	if len(parts) > 1 {
+		user += " [" + parts[1] + "]"
+	}
+	b.Log.Debugf("%s: Topic set by %s [%s]", event.Command, user, time.Unix(t, 0))
+}
diff --git a/bridge/irc/irc.go b/bridge/irc/irc.go
index 1e813246..721aba64 100644
--- a/bridge/irc/irc.go
+++ b/bridge/irc/irc.go
@@ -1,14 +1,10 @@
 package birc
 
 import (
-	"bytes"
 	"crypto/tls"
 	"fmt"
 	"hash/crc32"
-	"io"
-	"io/ioutil"
 	"net"
-	"regexp"
 	"sort"
 	"strconv"
 	"strings"
@@ -17,10 +13,7 @@ import (
 	"github.com/42wim/matterbridge/bridge"
 	"github.com/42wim/matterbridge/bridge/config"
 	"github.com/42wim/matterbridge/bridge/helper"
-	"github.com/dfordsoft/golib/ic"
 	"github.com/lrstanley/girc"
-	"github.com/paulrosania/go-charset/charset"
-	"github.com/saintfish/chardet"
 
 	// We need to import the 'data' package as an implicit dependency.
 	// See: https://godoc.org/github.com/paulrosania/go-charset/charset
@@ -68,7 +61,7 @@ func (b *Birc) Command(msg *config.Message) string {
 	if msg.Text == "!users" {
 		b.i.Handlers.Add(girc.RPL_NAMREPLY, b.storeNames)
 		b.i.Handlers.Add(girc.RPL_ENDOFNAMES, b.endNames)
-		b.i.Cmd.SendRaw("NAMES " + msg.Channel)
+		b.i.Cmd.SendRaw("NAMES " + msg.Channel) //nolint:errcheck
 	}
 	return ""
 }
@@ -76,35 +69,11 @@ func (b *Birc) Command(msg *config.Message) string {
 func (b *Birc) Connect() error {
 	b.Local = make(chan config.Message, b.MessageQueue+10)
 	b.Log.Infof("Connecting %s", b.GetString("Server"))
-	server, portstr, err := net.SplitHostPort(b.GetString("Server"))
-	if err != nil {
-		return err
-	}
-	port, err := strconv.Atoi(portstr)
-	if err != nil {
-		return err
-	}
-	// fix strict user handling of girc
-	user := b.GetString("Nick")
-	for !girc.IsValidUser(user) {
-		if len(user) == 1 {
-			user = "matterbridge"
-			break
-		}
-		user = user[1:]
-	}
 
-	i := girc.New(girc.Config{
-		Server:     server,
-		ServerPass: b.GetString("Password"),
-		Port:       port,
-		Nick:       b.GetString("Nick"),
-		User:       user,
-		Name:       b.GetString("Nick"),
-		SSL:        b.GetBool("UseTLS"),
-		TLSConfig:  &tls.Config{InsecureSkipVerify: b.GetBool("SkipTLSVerify"), ServerName: server},
-		PingDelay:  time.Minute,
-	})
+	i, err := b.getClient()
+	if err != nil {
+		return err
+	}
 
 	if b.GetBool("UseSASL") {
 		i.Config.SASL = &girc.SASLPlain{
@@ -117,27 +86,8 @@ func (b *Birc) Connect() error {
 	i.Handlers.Add(girc.RPL_ENDOFMOTD, b.handleOtherAuth)
 	i.Handlers.Add(girc.ALL_EVENTS, b.handleOther)
 
-	go func() {
-		for {
-			if err := i.Connect(); err != nil {
-				b.Log.Errorf("disconnect: error: %s", err)
-				if b.FirstConnection {
-					b.connected <- err
-					return
-				}
-			} else {
-				b.Log.Info("disconnect: client requested quit")
-			}
-			b.Log.Info("reconnecting in 30 seconds...")
-			time.Sleep(30 * time.Second)
-			i.Handlers.Clear(girc.RPL_WELCOME)
-			i.Handlers.Add(girc.RPL_WELCOME, func(client *girc.Client, event girc.Event) {
-				b.Remote <- config.Message{Username: "system", Text: "rejoin", Channel: "", Account: b.Account, Event: config.EventRejoinChannels}
-				// set our correct nick on reconnect if necessary
-				b.Nick = event.Source.Name
-			})
-		}
-	}()
+	go b.doConnect()
+
 	b.i = i
 	err = <-b.connected
 	if err != nil {
@@ -195,44 +145,13 @@ func (b *Birc) Send(msg config.Message) (string, error) {
 	}
 
 	// convert to specified charset
-	if b.GetString("Charset") != "" {
-		switch b.GetString("Charset") {
-		case "gbk", "gb18030", "gb2312", "big5", "euc-kr", "euc-jp", "shift-jis", "iso-2022-jp":
-			msg.Text = ic.ConvertString("utf-8", b.GetString("Charset"), msg.Text)
-		default:
-			buf := new(bytes.Buffer)
-			w, err := charset.NewWriter(b.GetString("Charset"), buf)
-			if err != nil {
-				b.Log.Errorf("charset from utf-8 conversion failed: %s", err)
-				return "", err
-			}
-			fmt.Fprint(w, msg.Text)
-			w.Close()
-			msg.Text = buf.String()
-		}
+	if err := b.handleCharset(&msg); err != nil {
+		return "", err
 	}
 
-	// Handle files
-	if msg.Extra != nil {
-		for _, rmsg := range helper.HandleExtra(&msg, b.General) {
-			b.Local <- rmsg
-		}
-		if len(msg.Extra["file"]) > 0 {
-			for _, f := range msg.Extra["file"] {
-				fi := f.(config.FileInfo)
-				if fi.Comment != "" {
-					msg.Text += fi.Comment + ": "
-				}
-				if fi.URL != "" {
-					msg.Text = fi.URL
-					if fi.Comment != "" {
-						msg.Text = fi.Comment + ": " + fi.URL
-					}
-				}
-				b.Local <- config.Message{Text: msg.Text, Username: msg.Username, Channel: msg.Channel, Event: msg.Event}
-			}
-			return "", nil
-		}
+	// handle files, return if we're done here
+	if ok := b.handleFiles(&msg); ok {
+		return "", nil
 	}
 
 	var msgLines []string
@@ -257,6 +176,28 @@ func (b *Birc) Send(msg config.Message) (string, error) {
 	return "", nil
 }
 
+func (b *Birc) doConnect() {
+	for {
+		if err := b.i.Connect(); err != nil {
+			b.Log.Errorf("disconnect: error: %s", err)
+			if b.FirstConnection {
+				b.connected <- err
+				return
+			}
+		} else {
+			b.Log.Info("disconnect: client requested quit")
+		}
+		b.Log.Info("reconnecting in 30 seconds...")
+		time.Sleep(30 * time.Second)
+		b.i.Handlers.Clear(girc.RPL_WELCOME)
+		b.i.Handlers.Add(girc.RPL_WELCOME, func(client *girc.Client, event girc.Event) {
+			b.Remote <- config.Message{Username: "system", Text: "rejoin", Channel: "", Account: b.Account, Event: config.EventRejoinChannels}
+			// set our correct nick on reconnect if necessary
+			b.Nick = event.Source.Name
+		})
+	}
+}
+
 func (b *Birc) doSend() {
 	rate := time.Millisecond * time.Duration(b.MessageDelay)
 	throttle := time.NewTicker(rate)
@@ -277,6 +218,40 @@ func (b *Birc) doSend() {
 	}
 }
 
+// validateInput validates the server/port/nick configuration. Returns a *girc.Client if successful
+func (b *Birc) getClient() (*girc.Client, error) {
+	server, portstr, err := net.SplitHostPort(b.GetString("Server"))
+	if err != nil {
+		return nil, err
+	}
+	port, err := strconv.Atoi(portstr)
+	if err != nil {
+		return nil, err
+	}
+	// fix strict user handling of girc
+	user := b.GetString("Nick")
+	for !girc.IsValidUser(user) {
+		if len(user) == 1 {
+			user = "matterbridge"
+			break
+		}
+		user = user[1:]
+	}
+
+	i := girc.New(girc.Config{
+		Server:     server,
+		ServerPass: b.GetString("Password"),
+		Port:       port,
+		Nick:       b.GetString("Nick"),
+		User:       user,
+		Name:       b.GetString("Nick"),
+		SSL:        b.GetBool("UseTLS"),
+		TLSConfig:  &tls.Config{InsecureSkipVerify: b.GetBool("SkipTLSVerify"), ServerName: server}, //nolint:gosec
+		PingDelay:  time.Minute,
+	})
+	return i, nil
+}
+
 func (b *Birc) endNames(client *girc.Client, event girc.Event) {
 	channel := event.Params[1]
 	sort.Strings(b.names[channel])
@@ -293,83 +268,6 @@ func (b *Birc) endNames(client *girc.Client, event girc.Event) {
 	b.i.Handlers.Clear(girc.RPL_ENDOFNAMES)
 }
 
-func (b *Birc) handleNewConnection(client *girc.Client, event girc.Event) {
-	b.Log.Debug("Registering callbacks")
-	i := b.i
-	b.Nick = event.Params[0]
-
-	i.Handlers.Add("PRIVMSG", b.handlePrivMsg)
-	i.Handlers.Add("CTCP_ACTION", b.handlePrivMsg)
-	i.Handlers.Add(girc.RPL_TOPICWHOTIME, b.handleTopicWhoTime)
-	i.Handlers.Add(girc.NOTICE, b.handleNotice)
-	i.Handlers.Add("JOIN", b.handleJoinPart)
-	i.Handlers.Add("PART", b.handleJoinPart)
-	i.Handlers.Add("QUIT", b.handleJoinPart)
-	i.Handlers.Add("KICK", b.handleJoinPart)
-}
-
-func (b *Birc) handleJoinPart(client *girc.Client, event girc.Event) {
-	if len(event.Params) == 0 {
-		b.Log.Debugf("handleJoinPart: empty Params? %#v", event)
-		return
-	}
-	channel := strings.ToLower(event.Params[0])
-	if event.Command == "KICK" && event.Params[1] == b.Nick {
-		b.Log.Infof("Got kicked from %s by %s", channel, event.Source.Name)
-		time.Sleep(time.Duration(b.GetInt("RejoinDelay")) * time.Second)
-		b.Remote <- config.Message{Username: "system", Text: "rejoin", Channel: channel, Account: b.Account, Event: config.EventRejoinChannels}
-		return
-	}
-	if event.Command == "QUIT" {
-		if event.Source.Name == b.Nick && strings.Contains(event.Trailing, "Ping timeout") {
-			b.Log.Infof("%s reconnecting ..", b.Account)
-			b.Remote <- config.Message{Username: "system", Text: "reconnect", Channel: channel, Account: b.Account, Event: config.EventFailure}
-			return
-		}
-	}
-	if event.Source.Name != b.Nick {
-		if b.GetBool("nosendjoinpart") {
-			return
-		}
-		b.Log.Debugf("<= Sending JOIN_LEAVE event from %s to gateway", b.Account)
-		msg := config.Message{Username: "system", Text: event.Source.Name + " " + strings.ToLower(event.Command) + "s", Channel: channel, Account: b.Account, Event: config.EventJoinLeave}
-		b.Log.Debugf("<= Message is %#v", msg)
-		b.Remote <- msg
-		return
-	}
-	b.Log.Debugf("handle %#v", event)
-}
-
-func (b *Birc) handleNotice(client *girc.Client, event girc.Event) {
-	if strings.Contains(event.String(), "This nickname is registered") && event.Source.Name == b.GetString("NickServNick") {
-		b.handleNickServ()
-	} else {
-		b.handlePrivMsg(client, event)
-	}
-}
-
-func (b *Birc) handleOther(client *girc.Client, event girc.Event) {
-	if b.GetInt("DebugLevel") == 1 {
-		if event.Command != "CLIENT_STATE_UPDATED" &&
-			event.Command != "CLIENT_GENERAL_UPDATED" {
-			b.Log.Debugf("%#v", event.String())
-		}
-		return
-	}
-	switch event.Command {
-	case "372", "375", "376", "250", "251", "252", "253", "254", "255", "265", "266", "002", "003", "004", "005":
-		return
-	}
-	b.Log.Debugf("%#v", event.String())
-}
-
-func (b *Birc) handleOtherAuth(client *girc.Client, event girc.Event) {
-	b.handleNickServ()
-	b.handleRunCommands()
-	// we are now fully connected
-	b.connected <- nil
-}
-
 func (b *Birc) skipPrivMsg(event girc.Event) bool {
 	// Our nick can be changed
 	b.Nick = b.i.GetNick()
@@ -389,74 +287,6 @@ func (b *Birc) skipPrivMsg(event girc.Event) bool {
 	return false
 }
 
-func (b *Birc) handlePrivMsg(client *girc.Client, event girc.Event) {
-	if b.skipPrivMsg(event) {
-		return
-	}
-	rmsg := config.Message{Username: event.Source.Name, Channel: strings.ToLower(event.Params[0]), Account: b.Account, UserID: event.Source.Ident + "@" + event.Source.Host}
-	b.Log.Debugf("== Receiving PRIVMSG: %s %s %#v", event.Source.Name, event.Trailing, event)
-
-	// set action event
-	if event.IsAction() {
-		rmsg.Event = config.EventUserAction
-	}
-
-	// strip action, we made an event if it was an action
-	rmsg.Text += event.StripAction()
-
-	// strip IRC colors
-	re := regexp.MustCompile(`\x03(?:\d{1,2}(?:,\d{1,2})?)?|[[:cntrl:]]`)
-	rmsg.Text = re.ReplaceAllString(rmsg.Text, "")
-
-	// start detecting the charset
-	var r io.Reader
-	var err error
-	mycharset := b.GetString("Charset")
-	if mycharset == "" {
-		// detect what were sending so that we convert it to utf-8
-		detector := chardet.NewTextDetector()
-		result, err := detector.DetectBest([]byte(rmsg.Text))
-		if err != nil {
-			b.Log.Infof("detection failed for rmsg.Text: %#v", rmsg.Text)
-			return
-		}
-		b.Log.Debugf("detected %s confidence %#v", result.Charset, result.Confidence)
-		mycharset = result.Charset
-		// if we're not sure, just pick ISO-8859-1
-		if result.Confidence < 80 {
-			mycharset = "ISO-8859-1"
-		}
-	}
-	switch mycharset {
-	case "gbk", "gb18030", "gb2312", "big5", "euc-kr", "euc-jp", "shift-jis", "iso-2022-jp":
-		rmsg.Text = ic.ConvertString("utf-8", b.GetString("Charset"), rmsg.Text)
-	default:
-		r, err = charset.NewReader(mycharset, strings.NewReader(rmsg.Text))
-		if err != nil {
-			b.Log.Errorf("charset to utf-8 conversion failed: %s", err)
-			return
-		}
-		output, _ := ioutil.ReadAll(r)
-		rmsg.Text = string(output)
-	}
-
-	b.Log.Debugf("<= Sending message from %s on %s to gateway", event.Params[0], b.Account)
-	b.Remote <- rmsg
-}
-
-func (b *Birc) handleTopicWhoTime(client *girc.Client, event girc.Event) {
-	parts := strings.Split(event.Params[2], "!")
-	t, err := strconv.ParseInt(event.Params[3], 10, 64)
-	if err != nil {
-		b.Log.Errorf("Invalid time stamp: %s", event.Params[3])
-	}
-	user := parts[0]
-	if len(parts) > 1 {
-		user += " [" + parts[1] + "]"
-	}
-	b.Log.Debugf("%s: Topic set by %s [%s]", event.Command, user, time.Unix(t, 0))
-}
-
 func (b *Birc) nicksPerRow() int {
 	return 4
 }
@@ -471,26 +301,3 @@ func (b *Birc) storeNames(client *girc.Client, event girc.Event) {
 func (b *Birc) formatnicks(nicks []string) string {
 	return strings.Join(nicks, ", ") + " currently on IRC"
 }
-
-func (b *Birc) handleRunCommands() {
-	for _, cmd := range b.GetStringSlice("RunCommands") {
-		if err := b.i.Cmd.SendRaw(cmd); err != nil {
-			b.Log.Errorf("RunCommands %s failed: %s", cmd, err)
-		}
-		time.Sleep(time.Second)
-	}
-}
-
-func (b *Birc) handleNickServ() {
-	if !b.GetBool("UseSASL") && b.GetString("NickServNick") != "" && b.GetString("NickServPassword") != "" {
-		b.Log.Debugf("Sending identify to nickserv %s", b.GetString("NickServNick"))
-		b.i.Cmd.Message(b.GetString("NickServNick"), "IDENTIFY "+b.GetString("NickServPassword"))
-	}
-	if strings.EqualFold(b.GetString("NickServNick"), "Q@CServe.quakenet.org") {
-		b.Log.Debugf("Authenticating %s against %s", b.GetString("NickServUsername"), b.GetString("NickServNick"))
-		b.i.Cmd.Message(b.GetString("NickServNick"), "AUTH "+b.GetString("NickServUsername")+" "+b.GetString("NickServPassword"))
-	}
-	// give nickserv some slack
-	time.Sleep(time.Second * 5)
-	b.authDone = true
-}