diff --git a/src/net/sf/briar/plugins/modem/Ack.java b/src/net/sf/briar/plugins/modem/Ack.java
index 436d3350524f97b990ce009ff40694a5a52c7f14..4f8e1da8604228a01dd6743a5a04f2d54ec55e71 100644
--- a/src/net/sf/briar/plugins/modem/Ack.java
+++ b/src/net/sf/briar/plugins/modem/Ack.java
@@ -7,20 +7,21 @@ class Ack extends Frame {
 	static final int LENGTH = 12;
 
 	Ack() {
-		super(new byte[LENGTH], LENGTH);
-		b[0] = (byte) Frame.ACK_FLAG;
+		super(new byte[LENGTH]);
+		buf[0] = (byte) Frame.ACK_FLAG;
 	}
 
-	Ack(byte[] b) {
-		super(b, LENGTH);
-		b[0] = (byte) Frame.ACK_FLAG;
+	Ack(byte[] buf) {
+		super(buf);
+		if(buf.length != LENGTH) throw new IllegalArgumentException();
+		buf[0] = (byte) Frame.ACK_FLAG;
 	}
 
 	int getWindowSize() {
-		return ByteUtils.readUint24(b, 5);
+		return ByteUtils.readUint24(buf, 5);
 	}
 
 	void setWindowSize(int windowSize) {
-		ByteUtils.writeUint24(windowSize, b, 5);
+		ByteUtils.writeUint24(windowSize, buf, 5);
 	}
 }
diff --git a/src/net/sf/briar/plugins/modem/Data.java b/src/net/sf/briar/plugins/modem/Data.java
index 58d42d4622341f89d1b22373606cb0abb9c45364..4cfd7cc8638bfd70b4f56d972b0c5f26ede104ae 100644
--- a/src/net/sf/briar/plugins/modem/Data.java
+++ b/src/net/sf/briar/plugins/modem/Data.java
@@ -7,21 +7,21 @@ class Data extends Frame {
 	static final int MAX_PAYLOAD_LENGTH = 1024;
 	static final int MAX_LENGTH = MIN_LENGTH + MAX_PAYLOAD_LENGTH;
 
-	Data(byte[] b, int length) {
-		super(b, length);
-		if(length < MIN_LENGTH || length > MAX_LENGTH)
+	Data(byte[] buf) {
+		super(buf);
+		if(buf.length < MIN_LENGTH || buf.length > MAX_LENGTH)
 			throw new IllegalArgumentException();
 	}
 
 	boolean isLastFrame() {
-		return b[0] == Frame.FIN_FLAG;
+		return buf[0] == Frame.FIN_FLAG;
 	}
 
 	void setLastFrame(boolean lastFrame) {
-		if(lastFrame) b[0] = (byte) Frame.FIN_FLAG;
+		if(lastFrame) buf[0] = (byte) Frame.FIN_FLAG;
 	}
 
 	int getPayloadLength() {
-		return length - MIN_LENGTH;
+		return buf.length - MIN_LENGTH;
 	}
 }
diff --git a/src/net/sf/briar/plugins/modem/Frame.java b/src/net/sf/briar/plugins/modem/Frame.java
index aa7e20432cd1a7b133b7c94bfda7b201ed6787d1..3feb0e47e6581c7201b3170bba212912461e944c 100644
--- a/src/net/sf/briar/plugins/modem/Frame.java
+++ b/src/net/sf/briar/plugins/modem/Frame.java
@@ -6,40 +6,38 @@ abstract class Frame {
 
 	static final byte ACK_FLAG = (byte) 128, FIN_FLAG = 64;
 
-	protected final byte[] b;
-	protected final int length;
+	protected final byte[] buf;
 
-	Frame(byte[] b, int length) {
-		this.b = b;
-		this.length = length;
+	Frame(byte[] buf) {
+		this.buf = buf;
 	}
 
 	byte[] getBuffer() {
-		return b;
+		return buf;
 	}
 
 	int getLength() {
-		return length;
+		return buf.length;
 	}
 
 	long getChecksum() {
-		return ByteUtils.readUint32(b, length - 4);
+		return ByteUtils.readUint32(buf, buf.length - 4);
 	}
 
 	void setChecksum(long checksum) {
-		ByteUtils.writeUint32(checksum, b, length - 4);
+		ByteUtils.writeUint32(checksum, buf, buf.length - 4);
 	}
 
 	long calculateChecksum() {
-		return Crc32.crc(b, 0, length - 4);
+		return Crc32.crc(buf, 0, buf.length - 4);
 	}
 
 	long getSequenceNumber() {
-		return ByteUtils.readUint32(b, 1);
+		return ByteUtils.readUint32(buf, 1);
 	}
 
 	void setSequenceNumber(long sequenceNumber) {
-		ByteUtils.writeUint32(sequenceNumber, b, 1);
+		ByteUtils.writeUint32(sequenceNumber, buf, 1);
 	}
 
 	@Override
@@ -51,7 +49,7 @@ abstract class Frame {
 	public boolean equals(Object o) {
 		if(o instanceof Frame) {
 			Frame f = (Frame) o;
-			if(b[0] != f.b[0]) return false;
+			if(buf[0] != f.buf[0]) return false;
 			return getSequenceNumber() == f.getSequenceNumber();
 		}
 		return false;
diff --git a/src/net/sf/briar/plugins/modem/ModemImpl.java b/src/net/sf/briar/plugins/modem/ModemImpl.java
index 5ca78fee18a998a714b89190971c9dd69b8b19e4..1ecebc3360c710e4a4df80c7289bf9e4d3b4d9fd 100644
--- a/src/net/sf/briar/plugins/modem/ModemImpl.java
+++ b/src/net/sf/briar/plugins/modem/ModemImpl.java
@@ -135,12 +135,7 @@ class ModemImpl implements Modem, WriteHandler, SerialPortEventListener {
 		offHook.release();
 	}
 
-	public void handleWrite(byte[] b, int length) throws IOException {
-		if(length < b.length) {
-			byte[] copy = new byte[length];
-			System.arraycopy(b, 0, copy, 0, length);
-			b = copy;
-		}
+	public void handleWrite(byte[] b) throws IOException {
 		try {
 			port.writeBytes(b);
 		} catch(SerialPortException e) {
@@ -153,7 +148,7 @@ class ModemImpl implements Modem, WriteHandler, SerialPortEventListener {
 		try {
 			if(ev.isRXCHAR()) {
 				byte[] b = port.readBytes();
-				if(connected.get()) reliabilityLayer.handleRead(b, b.length);
+				if(connected.get()) reliabilityLayer.handleRead(b);
 				else handleText(b);
 			} else if(ev.isDSR() && ev.getEventValue() == 0) {
 				if(LOG.isLoggable(INFO)) LOG.info("Remote end hung up");
@@ -188,7 +183,7 @@ class ModemImpl implements Modem, WriteHandler, SerialPortEventListener {
 					if(off < b.length) {
 						byte[] data = new byte[b.length - off];
 						System.arraycopy(b, off, data, 0, data.length);
-						reliabilityLayer.handleRead(data, data.length);
+						reliabilityLayer.handleRead(data);
 					}
 					return;
 				} else if(s.equals("OK")) {
diff --git a/src/net/sf/briar/plugins/modem/ReadHandler.java b/src/net/sf/briar/plugins/modem/ReadHandler.java
index 46b19329dc529bbf2328f58d6056ef5a38dbc59e..0e2bc8c9717b5bd79b2ad6687bb9643e1178e320 100644
--- a/src/net/sf/briar/plugins/modem/ReadHandler.java
+++ b/src/net/sf/briar/plugins/modem/ReadHandler.java
@@ -4,5 +4,5 @@ import java.io.IOException;
 
 interface ReadHandler {
 
-	void handleRead(byte[] b, int length) throws IOException;
+	void handleRead(byte[] b) throws IOException;
 }
diff --git a/src/net/sf/briar/plugins/modem/Receiver.java b/src/net/sf/briar/plugins/modem/Receiver.java
index 6ce7b53d6d9f24978b8f7e99206658d6aa0ba0ba..e11c8e5d436eb5a28a1a21654ab513c659b85bde 100644
--- a/src/net/sf/briar/plugins/modem/Receiver.java
+++ b/src/net/sf/briar/plugins/modem/Receiver.java
@@ -65,20 +65,15 @@ class Receiver implements ReadHandler {
 		}
 	}
 
-	public void handleRead(byte[] b, int length) throws IOException {
+	public void handleRead(byte[] b) throws IOException {
 		if(!valid) throw new IOException("Connection closed");
-		if(length < Data.MIN_LENGTH || length > Data.MAX_LENGTH) {
-			if(LOG.isLoggable(FINE))
-				LOG.fine("Ignoring frame with invalid length");
-			return;
-		}
 		switch(b[0]) {
 		case 0:
 		case Frame.FIN_FLAG:
-			handleData(b, length);
+			handleData(b);
 			break;
 		case Frame.ACK_FLAG:
-			sender.handleAck(b, length);
+			sender.handleAck(b);
 			break;
 		default:
 			if(LOG.isLoggable(FINE)) LOG.fine("Ignoring unknown frame type");
@@ -86,9 +81,13 @@ class Receiver implements ReadHandler {
 		}
 	}
 
-	private synchronized void handleData(byte[] b, int length)
-			throws IOException {
-		Data d = new Data(b, length);
+	private synchronized void handleData(byte[] b) throws IOException {
+		if(b.length < Data.MIN_LENGTH || b.length > Data.MAX_LENGTH) {
+			if(LOG.isLoggable(FINE))
+				LOG.fine("Ignoring data frame with invalid length");
+			return;
+		}
+		Data d = new Data(b);
 		int payloadLength = d.getPayloadLength();
 		if(payloadLength > windowSize) {
 			if(LOG.isLoggable(FINE)) LOG.fine("No space in the window");
diff --git a/src/net/sf/briar/plugins/modem/ReliabilityLayer.java b/src/net/sf/briar/plugins/modem/ReliabilityLayer.java
index ccab001be118875ad8d90d82b42bcb1e80b1c84e..d27e599b4bc5f2f33d8cdfd46512407475bb875a 100644
--- a/src/net/sf/briar/plugins/modem/ReliabilityLayer.java
+++ b/src/net/sf/briar/plugins/modem/ReliabilityLayer.java
@@ -42,7 +42,7 @@ class ReliabilityLayer implements ReadHandler, WriteHandler {
 					while(valid) {
 						byte[] b = writes.take();
 						if(b.length == 0) return; // Poison pill
-						writeHandler.handleWrite(b, b.length);
+						writeHandler.handleWrite(b);
 					}
 				} catch(InterruptedException e) {
 					if(LOG.isLoggable(WARNING))
@@ -73,20 +73,14 @@ class ReliabilityLayer implements ReadHandler, WriteHandler {
 	}
 
 	// The modem calls this method to pass data up to the SLIP decoder
-	public void handleRead(byte[] b, int length) throws IOException {
+	public void handleRead(byte[] b) throws IOException {
 		if(!valid) throw new IOException("Connection closed");
-		decoder.handleRead(b, length);
+		decoder.handleRead(b);
 	}
 
 	// The SLIP encoder calls this method to pass data down to the modem
-	public void handleWrite(byte[] b, int length) throws IOException {
+	public void handleWrite(byte[] b) throws IOException {
 		if(!valid) throw new IOException("Connection closed");
-		if(length == 0) return;
-		if(length < b.length) {
-			byte[] copy = new byte[length];
-			System.arraycopy(b, 0, copy, 0, length);
-			b = copy;
-		}
-		writes.add(b);
+		if(b.length > 0) writes.add(b);
 	}
 }
diff --git a/src/net/sf/briar/plugins/modem/Sender.java b/src/net/sf/briar/plugins/modem/Sender.java
index 8fabb35ebf9b49a7b4feb25f9efae88c824a4f08..5b5779bc6010ac05080294128f432c2e2e7de33d 100644
--- a/src/net/sf/briar/plugins/modem/Sender.java
+++ b/src/net/sf/briar/plugins/modem/Sender.java
@@ -47,13 +47,13 @@ class Sender {
 			if(LOG.isLoggable(FINE))
 				LOG.fine("Acknowledging #" + sequenceNumber);
 		}
-		writeHandler.handleWrite(a.getBuffer(), a.getLength());
+		writeHandler.handleWrite(a.getBuffer());
 	}
 
-	void handleAck(byte[] b, int length) {
-		if(length != Ack.LENGTH) {
+	void handleAck(byte[] b) {
+		if(b.length != Ack.LENGTH) {
 			if(LOG.isLoggable(FINE))
-				LOG.fine("Ignoring ack frame with wrong length");
+				LOG.fine("Ignoring ack frame with invalid length");
 			return;
 		}
 		Ack a = new Ack(b);
@@ -115,7 +115,7 @@ class Sender {
 		if(fastRetransmit != null) {
 			Data d = fastRetransmit.data;
 			try {
-				writeHandler.handleWrite(d.getBuffer(), d.getLength());
+				writeHandler.handleWrite(d.getBuffer());
 			} catch(IOException e) {
 				// FIXME: Do something more meaningful
 				if(LOG.isLoggable(WARNING)) LOG.warning(e.toString());
@@ -169,16 +169,14 @@ class Sender {
 			// Send a window probe if necessary
 			if(sendProbe) {
 				byte[] buf = new byte[Data.MIN_LENGTH];
-				Data probe = new Data(buf, Data.MIN_LENGTH);
+				Data probe = new Data(buf);
 				probe.setChecksum(probe.calculateChecksum());
-				writeHandler.handleWrite(buf, Data.MIN_LENGTH);
+				writeHandler.handleWrite(buf);
 			}
 			// Retransmit any lost data frames
 			if(retransmit != null) {
-				for(Outstanding o : retransmit) {
-					Data d = o.data;
-					writeHandler.handleWrite(d.getBuffer(), d.getLength());
-				}
+				for(Outstanding o : retransmit)
+					writeHandler.handleWrite(o.data.getBuffer());
 			}
 		} catch(IOException e) {
 			// FIXME: Do something more meaningful
@@ -202,7 +200,7 @@ class Sender {
 		}
 		if(LOG.isLoggable(FINE))
 			LOG.fine("Transmitting #" + d.getSequenceNumber());
-		writeHandler.handleWrite(d.getBuffer(), d.getLength());
+		writeHandler.handleWrite(d.getBuffer());
 	}
 
 	private static class Outstanding {
diff --git a/src/net/sf/briar/plugins/modem/SenderOutputStream.java b/src/net/sf/briar/plugins/modem/SenderOutputStream.java
index ca3a5f7b2322461784f7ba5710590cb46e6e45d1..5014c010a7cfb62434614e63a8bea397544516fe 100644
--- a/src/net/sf/briar/plugins/modem/SenderOutputStream.java
+++ b/src/net/sf/briar/plugins/modem/SenderOutputStream.java
@@ -6,8 +6,8 @@ import java.io.OutputStream;
 class SenderOutputStream extends OutputStream {
 
 	private final Sender sender;
+	private final byte[] buf = new byte[Data.MAX_LENGTH];
 
-	private byte[] buf = null;
 	private int offset = 0;
 	private long sequenceNumber = 1L;
 
@@ -17,18 +17,16 @@ class SenderOutputStream extends OutputStream {
 
 	@Override
 	public void close() throws IOException {
-		if(buf == null) assignBuffer();
 		send(true);
 	}
 
 	@Override
 	public void flush() throws IOException {
-		if(buf != null) send(false);
+		if(offset > Data.HEADER_LENGTH) send(false);
 	}
 
 	@Override
 	public void write(int b) throws IOException {
-		if(buf == null) assignBuffer();
 		buf[offset] = (byte) b;
 		offset++;
 		if(offset == Data.HEADER_LENGTH + Data.MAX_PAYLOAD_LENGTH) send(false);
@@ -41,13 +39,11 @@ class SenderOutputStream extends OutputStream {
 
 	@Override
 	public void write(byte[] b, int off, int len) throws IOException {
-		if(buf == null) assignBuffer();
 		int available = Data.MAX_LENGTH - offset - Data.FOOTER_LENGTH;
 		while(available <= len) {
 			System.arraycopy(b, off, buf, offset, available);
 			offset += available;
 			send(false);
-			assignBuffer();
 			off += available;
 			len -= available;
 			available = Data.MAX_LENGTH - offset - Data.FOOTER_LENGTH;
@@ -56,13 +52,10 @@ class SenderOutputStream extends OutputStream {
 		offset += len;
 	}
 
-	private void assignBuffer() {
-		buf = new byte[Data.MAX_LENGTH];
-		offset = Data.HEADER_LENGTH;
-	}
-
 	private void send(boolean lastFrame) throws IOException {
-		Data d = new Data(buf, offset + Data.FOOTER_LENGTH);
+		byte[] frame = new byte[offset + Data.FOOTER_LENGTH];
+		System.arraycopy(buf, 0, frame, 0, frame.length);
+		Data d = new Data(frame);
 		d.setLastFrame(lastFrame);
 		d.setSequenceNumber(sequenceNumber++);
 		d.setChecksum(d.calculateChecksum());
@@ -72,7 +65,6 @@ class SenderOutputStream extends OutputStream {
 			Thread.currentThread().interrupt();
 			throw new IOException("Interrupted while writing");
 		}
-		buf = null;
-		offset = 0;
+		offset = Data.HEADER_LENGTH;
 	}
 }
diff --git a/src/net/sf/briar/plugins/modem/SlipDecoder.java b/src/net/sf/briar/plugins/modem/SlipDecoder.java
index 883010ed6541328eab429088378f3eb630cc4dde..88170ae8fbdf2c0a0156f6010440c3f4a19a7432 100644
--- a/src/net/sf/briar/plugins/modem/SlipDecoder.java
+++ b/src/net/sf/briar/plugins/modem/SlipDecoder.java
@@ -24,16 +24,17 @@ class SlipDecoder implements ReadHandler {
 		this.readHandler = readHandler;
 	}
 
-	public void handleRead(byte[] b, int length) throws IOException {
-		for(int i = 0; i < length; i++) {
+	public void handleRead(byte[] b) throws IOException {
+		for(int i = 0; i < b.length; i++) {
 			switch(b[i]) {
 			case END:
 				if(escape) {
 					reset(true);
 				} else {
 					if(decodedLength > 0) {
-						readHandler.handleRead(buf, decodedLength);
-						buf = new byte[Data.MAX_LENGTH];
+						byte[] decoded = new byte[decodedLength];
+						System.arraycopy(buf, 0, decoded, 0, decodedLength);
+						readHandler.handleRead(decoded);
 					}
 					reset(false);
 				}
diff --git a/src/net/sf/briar/plugins/modem/SlipEncoder.java b/src/net/sf/briar/plugins/modem/SlipEncoder.java
index 577ce7dd21236ed16a3bd4a0b89a64e60d22aae8..0fc327a43f07687b01216eb3f0342c0368ab93e8 100644
--- a/src/net/sf/briar/plugins/modem/SlipEncoder.java
+++ b/src/net/sf/briar/plugins/modem/SlipEncoder.java
@@ -14,26 +14,25 @@ class SlipEncoder implements WriteHandler {
 		this.writeHandler = writeHandler;
 	}
 
-	public void handleWrite(byte[] b, int length) throws IOException {
-		if(length > Data.MAX_LENGTH) throw new IllegalArgumentException();
-		int encodedLength = length + 2;
-		for(int i = 0; i < length; i++) {
+	public void handleWrite(byte[] b) throws IOException {
+		if(b.length > Data.MAX_LENGTH) throw new IllegalArgumentException();
+		int encodedLength = b.length + 2;
+		for(int i = 0; i < b.length; i++)
 			if(b[i] == END || b[i] == ESC) encodedLength++;
-		}
-		byte[] buf = new byte[encodedLength];
-		buf[0] = END;
-		for(int i = 0, j = 1; i < length; i++) {
+		byte[] encoded = new byte[encodedLength];
+		encoded[0] = END;
+		for(int i = 0, j = 1; i < b.length; i++) {
 			if(b[i] == END) {
-				buf[j++] = ESC;
-				buf[j++] = TEND;
+				encoded[j++] = ESC;
+				encoded[j++] = TEND;
 			} else if(b[i] == ESC) {
-				buf[j++] = ESC;
-				buf[j++] = TESC;
+				encoded[j++] = ESC;
+				encoded[j++] = TESC;
 			} else {
-				buf[j++] = b[i];
+				encoded[j++] = b[i];
 			}
 		}
-		buf[encodedLength - 1] = END;
-		writeHandler.handleWrite(buf, encodedLength);
+		encoded[encodedLength - 1] = END;
+		writeHandler.handleWrite(encoded);
 	}
 }
diff --git a/src/net/sf/briar/plugins/modem/WriteHandler.java b/src/net/sf/briar/plugins/modem/WriteHandler.java
index a0637da755967fc6e7b45eaf1082e9ec16681d0c..fdf4d2c153cecd7ea792de01c52d2a2f66b83849 100644
--- a/src/net/sf/briar/plugins/modem/WriteHandler.java
+++ b/src/net/sf/briar/plugins/modem/WriteHandler.java
@@ -4,5 +4,5 @@ import java.io.IOException;
 
 interface WriteHandler {
 
-	void handleWrite(byte[] b, int length) throws IOException;
+	void handleWrite(byte[] b) throws IOException;
 }