diff --git a/KodoTest/KodoTest.sdf b/KodoTest/KodoTest.sdf
index 9fee1c334278a3efe28b597ede7b5894717c6ef2..2ae811d6a39c71f6dd334b62816184f936519195 100644
Binary files a/KodoTest/KodoTest.sdf and b/KodoTest/KodoTest.sdf differ
diff --git a/KodoTest/KodoTest.v12.suo b/KodoTest/KodoTest.v12.suo
index bee61c52ca0269dab36f165da5944a12f462b08f..4f4fe616e9de58f1ae4850ae54e570068ef6b44b 100644
Binary files a/KodoTest/KodoTest.v12.suo and b/KodoTest/KodoTest.v12.suo differ
diff --git a/KodoTest/KodoTest/Source.cpp b/KodoTest/KodoTest/Source.cpp
index 3e16e6e2dde37f2d99f3ac2d9da6f803f1dec582..d9269310f3b1c0b05c5aa8aa68beb1479f63e9da 100644
--- a/KodoTest/KodoTest/Source.cpp
+++ b/KodoTest/KodoTest/Source.cpp
@@ -1,72 +1,143 @@
-// Copyright Steinwurf ApS 2011-2012.
+// Copyright Steinwurf ApS 2011.
 // Distributed under the "STEINWURF RESEARCH LICENSE 1.0".
 // See accompanying file LICENSE.rst or
 // http://www.steinwurf.com/licensing
 
+
+//! [0]
+#include <kodo/object/file_encoder.hpp>
+#include <kodo/object/file_decoder.hpp>
+
 #include <kodo/rlnc/full_rlnc_codes.hpp>
+//! [1]
 
-/// @example encode_decode_simple.cpp
+#include <cassert>
+#include <cstdint>
+#include <fstream>
+#include <iostream>
+#include <vector>
+
+/// @example encode_decode_file.cpp
 ///
-/// Simple example showing how to encode and decode a block
-/// of memory.
+/// Often we want to encode / decode data that exceed a single
+/// encoding/decoding block. In this case we need to "chop" up
+/// the data into manageable chunks and then encode and decode
+/// each chuck separately. This example shows how to use the
+/// file encoder in Kodo. The file encoder operates directly on
+/// a file in the file-system. For decoding we use an object decoder
+/// which decodes data to memory, but which is compatible with
+/// file encoder.
+
+#define BUFFER_SIZE 1000
+
+bool isFilesEqual(const std::string& lFilePath, const std::string& rFilePath)
+{
+	std::ifstream lFile(lFilePath.c_str(), std::ifstream::in | std::ifstream::binary);
+	std::ifstream rFile(rFilePath.c_str(), std::ifstream::in | std::ifstream::binary);
+
+	if (!lFile.is_open() || !rFile.is_open())
+	{
+		return false;
+	}
+
+	char *lBuffer = new char[BUFFER_SIZE]();
+	char *rBuffer = new char[BUFFER_SIZE]();
+
+	do {
+		lFile.read(lBuffer, BUFFER_SIZE);
+		rFile.read(rBuffer, BUFFER_SIZE);
+
+		if (std::memcmp(lBuffer, rBuffer, BUFFER_SIZE) != 0)
+		{
+			delete[] lBuffer;
+			delete[] rBuffer;
+			return false;
+		}
+	} while (lFile.good() || rFile.good());
+
+	delete[] lBuffer;
+	delete[] rBuffer;
+	return true;
+}
 
 int main()
 {
+	//! [2]
 	// Set the number of symbols (i.e. the generation size in RLNC
 	// terminology) and the size of a symbol in bytes
-	uint32_t symbols = 42;
-	uint32_t symbol_size = 160;
+	uint32_t max_symbols = 42;
+	uint32_t max_symbol_size = 64;
 
-	// Typdefs for the encoder/decoder type we wish to use
-	typedef kodo::full_rlnc_encoder<fifi::binary8> rlnc_encoder;
-	typedef kodo::full_rlnc_decoder<fifi::binary8> rlnc_decoder;
+	uint32_t file_size = 23456;
 
-	// In the following we will make an encoder/decoder factory.
-	// The factories are used to build actual encoders/decoders
-	rlnc_encoder::factory encoder_factory(symbols, symbol_size);
-	auto encoder = encoder_factory.build();
+	std::string encode_filename = "encode-file.bin";
+	std::string decode_filename = "decode-file.bin";
 
-	rlnc_decoder::factory decoder_factory(symbols, symbol_size);
-	auto decoder = decoder_factory.build();
+	using file_encoder = kodo::object::file_encoder<
+		kodo::shallow_full_rlnc_encoder<fifi::binary >> ;
 
-	// Allocate some storage for a "payload" the payload is what we would
-	// eventually send over a network
-	std::vector<uint8_t> payload(encoder->payload_size());
+	using file_decoder = kodo::object::file_decoder<
+		kodo::shallow_full_rlnc_decoder<fifi::binary >> ;
+	//! [3]
 
-	// Allocate some data to encode. In this case we make a buffer
-	// with the same size as the encoder's block size (the max.
-	// amount a single encoder can encode)
-	std::vector<uint8_t> data_in(encoder->block_size());
+	//! [4]
+	// Create a test file for encoding.
+	std::ofstream encode_file;
 
-	// Just for fun - fill the data with random data
-	for (auto &e : data_in)
-		e = rand() % 256;
+	encode_file.open(encode_filename, std::ios::binary);
+	std::vector<char> data_in(file_size, 'x');
 
-	// Assign the data buffer to the encoder so that we may start
-	// to produce encoded symbols from it
-	encoder->set_symbols(sak::storage(data_in));
+	encode_file.write(data_in.data(), data_in.size());
+	encode_file.close();
+	//! [5]
 
-	while (!decoder->is_complete())
-	{
-		// Encode a packet into the payload buffer
-		encoder->encode(&payload[0]);
+	//! [6]
+	// Actual encoding/decoding of the file
+	file_encoder::factory encoder_factory(max_symbols, max_symbol_size);
+	file_decoder::factory decoder_factory(max_symbols, max_symbol_size);
 
-		// Pass that packet to the decoder
-		decoder->decode(&payload[0]);
-	}
+	encoder_factory.set_filename(encode_filename);
 
-	// The decoder is complete, now copy the symbols from the decoder
-	std::vector<uint8_t> data_out(decoder->block_size());
-	decoder->copy_symbols(sak::storage(data_out));
+	decoder_factory.set_filename(decode_filename);
+	decoder_factory.set_file_size(file_size);
 
-	// Check we properly decoded the data
-	if (std::equal(data_out.begin(), data_out.end(), data_in.begin()))
-	{
-		std::cout << "Data decoded correctly" << std::endl;
-	}
-	else
+	auto encoder = encoder_factory.build();
+	auto decoder = decoder_factory.build();
+
+	std::cout << "encoder blocks = " << encoder->blocks() << std::endl;
+	std::cout << "decoder blocks = " << decoder->blocks() << std::endl;
+	//! [7]
+
+	//! [8]
+	for (uint32_t i = 0; i < encoder->blocks(); ++i)
 	{
-		std::cout << "Unexpected failure to decode "
-			<< "please file a bug report :)" << std::endl;
+		// If you want to store the encoder/decoder built. You should use
+		// the type available as `stack_pointer` in the
+		// file_encoder/file_decoder types.
+		//
+		// file_encoder::stack_pointer e = encoder->build(i);
+		// file_decoder::stack_pointer d = decoder->build(i);
+
+		auto e = encoder->build(i);
+		auto d = decoder->build(i);
+
+		std::vector<uint8_t> payload(e->payload_size());
+
+		while (!d->is_complete())
+		{
+			e->encode(payload.data());
+
+			// Here we would send and receive the payload over a
+			// network. Lets throw away some packet to simulate.
+			if (rand() % 2)
+			{
+				continue;
+			}
+
+			d->decode(payload.data());
+		}
 	}
-}
+	//! [9]
+
+	std::cout << isFilesEqual(encode_filename, decode_filename);
+}
\ No newline at end of file