I think it makes the most sense to require a client and socket for each authenticator upon initialization, then have the authenticator remember this information so it can log itself in and out without hassle.  This makes initialization a bit messier, but would make the rest cleaner, I think:

```
auth = get('testdb', 'samantha', client, socket, 'PLAIN', { :password => 'secret' })
auth.login
...
auth.logout
```

The current implementation doesn't need to pass around the client because it's implemented as methods on the client itself.  Also, it does require passing around sockets to ```login``` and ```logout```, which was necessary for that implementation, but I think since we're moving to a more object-oriented approach it would make sense to save this state.