diff --git a/lib/crypto.dart b/lib/crypto.dart
index 892626f..eb2905a 100644
--- a/lib/crypto.dart
+++ b/lib/crypto.dart
@@ -10,6 +10,7 @@
 
 import 'dart:math';
 import 'dart:typed_data';
+import 'dart:convert';
 
 part 'src/crypto_utils.dart';
 part 'src/hash_utils.dart';
@@ -17,6 +18,7 @@
 part 'src/md5.dart';
 part 'src/sha1.dart';
 part 'src/sha256.dart';
+part 'src/base64.dart';
 
 /**
  * Interface for cryptographic hash functions.
diff --git a/lib/src/base64.dart b/lib/src/base64.dart
new file mode 100644
index 0000000..7ccf4aa
--- /dev/null
+++ b/lib/src/base64.dart
@@ -0,0 +1,377 @@
+part of crypto;
+
+const Base64Codec BASE64 = const Base64Codec();
+
+const List<int> _decodeTable =
+      const [ -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -1, -2, -2, -1, -2, -2,
+              -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
+              -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, 62, -2, 62, -2, 63,
+              52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -2, -2, -2,  0, -2, -2,
+              -2,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,
+              15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -2, -2, -2, -2, 63,
+              -2, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
+              41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -2, -2, -2, -2, -2,
+              -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
+              -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
+              -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
+              -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
+              -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
+              -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
+              -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
+              -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2 ];
+
+const String _encodeTableUrlSafe =
+      "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
+
+const String _encodeTable =
+      "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+const List<String> _URL_SAFE_CHARACTERS = const ['+', '/'];
+const List<String> _URL_UNSAFE_CHARACTERS = const ['-', '_'];
+
+const int _LINE_LENGTH = 76;
+const int _PAD = 61; // '='
+const int _CR = 13;  // '\r'
+const int _LF = 10;  // '\n'
+
+class Base64Codec extends Codec<List<int>, String> {
+
+  final bool _urlSafe;
+  final bool _addLineSeparator;
+
+  /**
+   * Instantiates a new [Base64Codec].
+   *
+   * The optional [urlSafe] argument specifies if [encoder] and [encode]
+   * should generate a string, that is safe to use in an URL.
+   *
+   * If [urlSafe] is `true` (and not overriden at the method invocation)
+   * the [encoder] and [encode] use '-' instead of '+' and '_' instead of '/'.
+   *
+   * The default value of [urlSafe] is `false`.
+   *
+   * The optional [addLineSeparator] argument specifies if the [encoder] and
+   * [encode] should add line separators.
+   *
+   * If `addLineSeparator` is `true` [encode] adds an
+   * optional line separator (CR + LF) for each 76 char output.
+   *
+   * The default value of [addLineSeparator] if `false`.
+   */
+  const Base64Codec({bool urlSafe: false, bool addLineSeparator: false})
+      : _urlSafe = urlSafe,
+        _addLineSeparator = addLineSeparator;
+
+  String get name => "base64";
+
+  String encode(List<int> bytes,
+                {bool urlSafe,
+                 bool addLineSeparator}) {
+    if (urlSafe == null) urlSafe = _urlSafe;
+    if (addLineSeparator == null) addLineSeparator = _addLineSeparator;
+    return new Base64Encoder(urlSafe: urlSafe,
+                   addLineSeparator: addLineSeparator).convert(bytes);
+
+
+  }
+
+  Base64Encoder get encoder => new Base64Encoder(
+                                     urlSafe: _urlSafe,
+                                     addLineSeparator: _addLineSeparator);
+
+  Base64Decoder get decoder => new Base64Decoder();
+
+}
+
+/**
+ * This class encodes byte strings (lists of unsigned
+ * 8-bit integers) to strings according to Base64.
+ */
+class Base64Encoder extends Converter<List<int>, String> {
+  final bool _urlSafe;
+  final bool _addLineSeparator;
+
+  /**
+   * Instantiates a new [Base64Encoder].
+   *
+   * The optional [urlSafe] argument specifies if [convert]
+   * should generate a string, that is safe to use in an URL.
+   *
+   * If it is `true` the [convert] use
+   * '-' instead of '+' and '_' instead of '/'.
+   *
+   * The default value of [urlSafe] is `false`.
+   *
+   * The optional [addLineSeparator] argument specifies if [convert]
+   * should add line separators.
+   *
+   * If it is `true` [convert] adds an optional line separator(CR + LF)
+   * for each 76 char output.
+   *
+   * The default value of [addLineSeparator] if `false`.
+   */
+  const Base64Encoder({bool urlSafe: false, bool addLineSeparator: false})
+      : _urlSafe = urlSafe,
+        _addLineSeparator = addLineSeparator;
+
+  /**
+   * Converts [bytes] to its Base64 representation as a string.
+   *
+   * if [start] and [end] are provided, only the sublist
+   * `bytes.sublist(start, end)` is converted.
+   */
+
+  String convert(List<int> bytes, [int start = 0, int end]) {
+    int bytes_length = bytes.length;
+    RangeError.checkValidRange(start, end, bytes_length);
+    if (end == null) end = bytes_length;
+    int length = end - start;
+    if (length == 0) {
+      return "";
+    }
+    final String lookup = _urlSafe ? _encodeTableUrlSafe : _encodeTable;
+    // Size of 24 bit chunks.
+    final int remainderLength = length.remainder(3);
+    final int chunkLength = length - remainderLength;
+    // Size of base output.
+    int baseOutputLength = ((length ~/ 3) * 4);
+    int remainderOutputLength = ((remainderLength > 0) ? 4 : 0);
+    int outputLength = baseOutputLength + remainderOutputLength;
+    // Add extra for line separators.
+    if (_addLineSeparator) {
+      outputLength += ((outputLength - 1) ~/ _LINE_LENGTH) << 1;
+    }
+    List<int> out = new List<int>(outputLength);
+
+    // Encode 24 bit chunks.
+    int j = 0, i = start, c = 0;
+    while (i < chunkLength) {
+      int x = ((bytes[i++] << 16) & 0x00FFFFFF) |
+              ((bytes[i++] << 8) & 0x00FFFFFF) |
+                bytes[i++];
+      out[j++] = lookup.codeUnitAt(x >> 18);
+      out[j++] = lookup.codeUnitAt((x >> 12) & 0x3F);
+      out[j++] = lookup.codeUnitAt((x >> 6)  & 0x3F);
+      out[j++] = lookup.codeUnitAt(x & 0x3F);
+      // Add optional line separator for each 76 char output.
+      if (_addLineSeparator && ++c == 19 && j < outputLength - 2) {
+        out[j++] = _CR;
+        out[j++] = _LF;
+        c = 0;
+      }
+    }
+
+    // If input length if not a multiple of 3, encode remaining bytes and
+    // add padding.
+    if (remainderLength == 1) {
+      int x = bytes[i];
+      out[j++] = lookup.codeUnitAt(x >> 2);
+      out[j++] = lookup.codeUnitAt((x << 4) & 0x3F);
+      out[j++] = _PAD;
+      out[j++] = _PAD;
+    } else if (remainderLength == 2) {
+      int x = bytes[i];
+      int y = bytes[i + 1];
+      out[j++] = lookup.codeUnitAt(x >> 2);
+      out[j++] = lookup.codeUnitAt(((x << 4) | (y >> 4)) & 0x3F);
+      out[j++] = lookup.codeUnitAt((y << 2) & 0x3F);
+      out[j++] = _PAD;
+    }
+
+    return new String.fromCharCodes(out);
+  }
+
+  _Base64EncoderSink startChunkedConversion(Sink<String> sink) {
+    StringConversionSink stringSink;
+    if (sink is StringConversionSink) {
+      stringSink = sink;
+    } else {
+      stringSink = new StringConversionSink.from(sink);
+    }
+    return new _Base64EncoderSink(stringSink, _urlSafe, _addLineSeparator);
+  }
+}
+
+class _Base64EncoderSink extends ChunkedConversionSink<List<int>> {
+
+  final Base64Encoder _encoder;
+  final ChunkedConversionSink<String> _outSink;
+  final List<int> _buffer = new List<int>();
+  int _bufferCount = 0;
+
+  _Base64EncoderSink(this._outSink, urlSafe, addLineSeparator)
+      : _encoder = new Base64Encoder(urlSafe: urlSafe,
+                                     addLineSeparator: addLineSeparator);
+
+
+  void add(List<int> chunk) {
+    var nextBufferCount = (chunk.length + _bufferCount) % 3;
+
+    int decodableLength = _bufferCount + chunk.length - nextBufferCount;
+
+    if (_bufferCount + chunk.length > _buffer.length) {
+      _buffer.replaceRange(_bufferCount,
+                           _buffer.length,
+                           chunk.sublist(0, _buffer.length - _bufferCount));
+      _buffer.addAll(chunk.sublist(_buffer.length - _bufferCount));
+    } else {
+      _buffer.replaceRange(_bufferCount, _bufferCount + chunk.length, chunk);
+    }
+
+    _outSink.add(_encoder.convert(_buffer, 0, decodableLength));
+    _buffer.removeRange(0, decodableLength);
+    _bufferCount = nextBufferCount;
+  }
+
+  void close() {
+    if (_bufferCount > 0) {
+      _outSink.add(_encoder.convert(_buffer.sublist(0, _bufferCount)));
+    }
+    _outSink.close();
+  }
+}
+
+/**
+ * This class decodes strings to lists of bytes(lists of
+ * unsigned 8-bit integers) according to Base64.
+ */
+class Base64Decoder extends Converter<String, List<int>> {
+
+  /**
+   * Instantiates a new [Base64Decoder]
+   */
+  const Base64Decoder();
+
+  List<int> convert(String input, {bool alwaysPadding: false}) {
+    int length = input.length;
+    if (length == 0) {
+      return new List<int>(0);
+    }
+
+    // Count '\r', '\n' and illegal characters, check if
+    // '/', '+' / '-', '_' are used consistently, for illegal characters,
+    // throw an exception.
+    int extrasLength = 0;
+    bool expectedSafe = false;
+    bool expectedUnsafe = false;
+
+    for (int i = 0; i < length; i++) {
+      int c = _decodeTable[input.codeUnitAt(i)];
+      if (c < 0) {
+        extrasLength++;
+        if (c == -2) {
+          throw new FormatException('Invalid character', input, i);
+        }
+      } else if (input[i] == _URL_UNSAFE_CHARACTERS[0] ||
+                 input[i] == _URL_UNSAFE_CHARACTERS[1]) {
+
+        if (expectedSafe) {
+          throw new FormatException('Unsafe character in URL-safe string',
+                                    input, i);
+        }
+        expectedUnsafe = true;
+      } else if (input[i] == _URL_SAFE_CHARACTERS[0] ||
+                 input[i] == _URL_SAFE_CHARACTERS[1]) {
+        if (expectedUnsafe) {
+          throw new FormatException('Invalid character', input, i);
+        }
+        expectedSafe = true;
+      }
+    }
+
+    if ((length - extrasLength) % 4 != 0) {
+      throw new FormatException('''Size of Base 64 characters in Input
+          must be a multiple of 4''', input, length - extrasLength);
+    }
+
+    // Count pad characters.
+    int padLength = 0;
+    for (int i = length - 1; i >= 0; i--) {
+      int currentCodeUnit = input.codeUnitAt(i);
+      if (_decodeTable[currentCodeUnit] > 0) break;
+      if (currentCodeUnit == _PAD) padLength++;
+    }
+    int outputLength = (((length - extrasLength) * 6) >> 3) - padLength;
+    List<int> out = new List<int>(outputLength);
+
+    for (int i = 0, o = 0; o < outputLength; ) {
+      // Accumulate 4 valid 6 bit Base 64 characters into an int.
+      int x = 0;
+      for (int j = 4; j > 0; ) {
+        int c = _decodeTable[input.codeUnitAt(i++)];
+        if (c >= 0) {
+          x = ((x << 6) & 0x00FFFFFF) | c;
+          j--;
+        }
+      }
+      out[o++] = x >> 16;
+      if (o < outputLength) {
+        out[o++] = (x >> 8) & 0xFF;
+        if (o < outputLength) out[o++] = x & 0xFF;
+      }
+    }
+
+    return out;
+  }
+
+  _Base64DecoderSink startChunkedConversion(Sink<List<int>> sink) {
+    if (sink is! ByteConversionSink) {
+      sink = new ByteConversionSink.from(sink);
+    }
+    return new _Base64DecoderSink(sink);
+  }
+}
+
+
+class _Base64DecoderSink extends ChunkedConversionSink<String> {
+
+  final Base64Decoder _decoder = new Base64Decoder();
+  final ChunkedConversionSink<List<int>> _outSink;
+  String _buffer = "";
+  bool _isSafe = false;
+  bool _isUnsafe = false;
+
+  _Base64DecoderSink(this._outSink);
+
+  void add(String chunk) {
+    int nextBufferLength = (chunk.length + _buffer.length) % 4;
+
+    if (chunk.length + _buffer.length >= 4) {
+      int remainder = chunk.length - nextBufferLength;
+      String decodable = _buffer + chunk.substring(0, remainder);
+      _buffer = chunk.substring(remainder);
+
+      for (int i = 0;i < decodable.length; i++) {
+        if (decodable[i] == _URL_UNSAFE_CHARACTERS[0] ||
+            decodable[i] == _URL_UNSAFE_CHARACTERS[1]) {
+          if (_isSafe) {
+            throw new FormatException('Unsafe character in URL-safe string',
+                                       decodable, i);
+          }
+          _isUnsafe = true;
+        } else if (decodable[i] == _URL_SAFE_CHARACTERS[0] ||
+                   decodable[i] == _URL_SAFE_CHARACTERS[1]) {
+          if (_isUnsafe) {
+            throw new FormatException('Invalid character', decodable, i);
+          }
+          _isSafe = true;
+        }
+      }
+
+      _outSink.add(_decoder.convert(decodable));
+    } else {
+      _buffer += chunk;
+    }
+  }
+
+  void close() {
+    if (!_buffer.isEmpty) {
+      throw new FormatException(
+          "Size of Base 64 input must be a multiple of 4",
+          _buffer,
+          _buffer.length);
+    }
+    _outSink.close();
+  }
+}
+
diff --git a/lib/src/crypto_utils.dart b/lib/src/crypto_utils.dart
index 515c1e9..7111d6f 100644
--- a/lib/src/crypto_utils.dart
+++ b/lib/src/crypto_utils.dart
@@ -13,148 +13,15 @@
     return result.toString();
   }
 
-  static const int PAD = 61; // '='
-  static const int CR = 13;  // '\r'
-  static const int LF = 10;  // '\n'
-  static const int LINE_LENGTH = 76;
-
-  static const String _encodeTable =
-      "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-
-  static const String _encodeTableUrlSafe =
-      "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
-
-  // Lookup table used for finding Base 64 alphabet index of a given byte.
-  // -2 : Outside Base 64 alphabet.
-  // -1 : '\r' or '\n'
-  //  0 : = (Padding character).
-  // >0 : Base 64 alphabet index of given byte.
-  static const List<int> _decodeTable =
-      const [ -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -1, -2, -2, -1, -2, -2,
-              -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
-              -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, 62, -2, 62, -2, 63,
-              52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -2, -2, -2,  0, -2, -2,
-              -2,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,
-              15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -2, -2, -2, -2, 63,
-              -2, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
-              41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -2, -2, -2, -2, -2,
-              -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
-              -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
-              -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
-              -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
-              -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
-              -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
-              -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
-              -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2 ];
-
   static String bytesToBase64(List<int> bytes,
                               [bool urlSafe = false,
                                bool addLineSeparator = false]) {
-    int len = bytes.length;
-    if (len == 0) {
-      return "";
-    }
-    final String lookup = urlSafe ? _encodeTableUrlSafe : _encodeTable;
-    // Size of 24 bit chunks.
-    final int remainderLength = len.remainder(3);
-    final int chunkLength = len - remainderLength;
-    // Size of base output.
-    int outputLen = ((len ~/ 3) * 4) + ((remainderLength > 0) ? 4 : 0);
-    // Add extra for line separators.
-    if (addLineSeparator) {
-      outputLen += ((outputLen - 1) ~/ LINE_LENGTH) << 1;
-    }
-    List<int> out = new List<int>(outputLen);
-
-    // Encode 24 bit chunks.
-    int j = 0, i = 0, c = 0;
-    while (i < chunkLength) {
-      int x = ((bytes[i++] << 16) & 0xFFFFFF) |
-              ((bytes[i++] << 8) & 0xFFFFFF) |
-                bytes[i++];
-      out[j++] = lookup.codeUnitAt(x >> 18);
-      out[j++] = lookup.codeUnitAt((x >> 12) & 0x3F);
-      out[j++] = lookup.codeUnitAt((x >> 6)  & 0x3F);
-      out[j++] = lookup.codeUnitAt(x & 0x3f);
-      // Add optional line separator for each 76 char output.
-      if (addLineSeparator && ++c == 19 && j < outputLen - 2) {
-        out[j++] = CR;
-        out[j++] = LF;
-        c = 0;
-      }
-    }
-
-    // If input length if not a multiple of 3, encode remaining bytes and
-    // add padding.
-    if (remainderLength == 1) {
-      int x = bytes[i];
-      out[j++] = lookup.codeUnitAt(x >> 2);
-      out[j++] = lookup.codeUnitAt((x << 4) & 0x3F);
-      out[j++] = PAD;
-      out[j++] = PAD;
-    } else if (remainderLength == 2) {
-      int x = bytes[i];
-      int y = bytes[i + 1];
-      out[j++] = lookup.codeUnitAt(x >> 2);
-      out[j++] = lookup.codeUnitAt(((x << 4) | (y >> 4)) & 0x3F);
-      out[j++] = lookup.codeUnitAt((y << 2) & 0x3F);
-      out[j++] = PAD;
-    }
-
-    return new String.fromCharCodes(out);
+    return BASE64.encode(bytes,
+                         urlSafe: urlSafe,
+                         addLineSeparator: addLineSeparator);
   }
 
   static List<int> base64StringToBytes(String input) {
-    int len = input.length;
-    if (len == 0) {
-      return new List<int>(0);
-    }
-
-    // Count '\r', '\n' and illegal characters, For illegal characters,
-    // throw an exception.
-    int extrasLen = 0;
-    for (int i = 0; i < len; i++) {
-      int c = _decodeTable[input.codeUnitAt(i)];
-      if (c < 0) {
-        extrasLen++;
-        if (c == -2) {
-          throw new FormatException('Invalid character: ${input[i]}');
-        }
-      }
-    }
-
-    if ((len - extrasLen) % 4 != 0) {
-      throw new FormatException('''Size of Base 64 characters in Input
-          must be a multiple of 4. Input: $input''');
-    }
-
-    // Count pad characters.
-    int padLength = 0;
-    for (int i = len - 1; i >= 0; i--) {
-      int currentCodeUnit = input.codeUnitAt(i);
-      if (_decodeTable[currentCodeUnit] > 0) break;
-      if (currentCodeUnit == PAD) padLength++;
-    }
-    int outputLen = (((len - extrasLen) * 6) >> 3) - padLength;
-    List<int> out = new List<int>(outputLen);
-
-    for (int i = 0, o = 0; o < outputLen; ) {
-      // Accumulate 4 valid 6 bit Base 64 characters into an int.
-      int x = 0;
-      for (int j = 4; j > 0; ) {
-        int c = _decodeTable[input.codeUnitAt(i++)];
-        if (c >= 0) {
-          x = ((x << 6) & 0xFFFFFF) | c;
-          j--;
-        }
-      }
-      out[o++] = x >> 16;
-      if (o < outputLen) {
-        out[o++] = (x >> 8) & 0xFF;
-        if (o < outputLen) out[o++] = x & 0xFF;
-      }
-    }
-    return out;
+    return BASE64.decode(input);
   }
-
 }
diff --git a/test/base64_test.dart b/test/base64_test.dart
index b5647b0..725ac3f 100644
--- a/test/base64_test.dart
+++ b/test/base64_test.dart
@@ -6,6 +6,7 @@
 library base64_test;
 
 import 'dart:math';
+import 'dart:async';
 
 import "package:crypto/crypto.dart";
 import "package:test/test.dart";
@@ -16,7 +17,23 @@
   test('decoder for malformed input', _testDecoderForMalformedInput);
   test('encode decode lists', _testEncodeDecodeLists);
   test('url safe encode-decode', _testUrlSafeEncodeDecode);
+  test('consistent safe/unsafe character decoding',
+       _testConsistentSafeUnsafeDecode);
+  test('streaming encoder', _testStreamingEncoder);
+  test('streaming decoder', _testStreamingDecoder);
+  test('streaming decoder for malformed input',
+       _testStreamingDecoderForMalformedInput);
+  test('streaming encoder for different decompositions of a list of bytes',
+       _testStreamingEncoderForDecompositions);
+  test('streaming decoder for different decompositions of a string',
+       _testStreamingDecoderForDecompositions);
+  test('consistent safe/unsafe character streaming decoding',
+       _testConsistentSafeUnsafeStreamDecode);
+  test('old api', _testOldApi);
+  test('url safe streaming encoder/decoder', _testUrlSafeStreaming);
   test('performance', _testPerformance);
+
+
 }
 
 // Data from http://tools.ietf.org/html/rfc4648.
@@ -24,6 +41,45 @@
     const [ '', 'f', 'fo', 'foo', 'foob', 'fooba', 'foobar'];
 const _RESULTS =
     const [ '', 'Zg==', 'Zm8=', 'Zm9v', 'Zm9vYg==', 'Zm9vYmE=', 'Zm9vYmFy'];
+var _STREAMING_ENCODER_INPUT =
+    [[102, 102], [111, 102],
+     [111, 111, 102, 111, 111, 98, 102, 111,
+      111, 98, 97, 102, 111, 111, 98, 97, 114]];
+
+const _STREAMING_ENCODED = 'ZmZvZm9vZm9vYmZvb2JhZm9vYmFy';
+const _STREAMING_DECODER_INPUT =
+    const ['YmFz', 'ZTY', '0I', 'GRlY29kZXI='];
+const _STREAMING_DECODED =
+    const [98, 97, 115, 101, 54, 52, 32, 100, 101, 99, 111, 100, 101, 114];
+const _STREAMING_DECODER_INPUT_FOR_ZEROES =
+    const ['AAAA', 'AAA=', 'AA==', ''];
+var _STREAMING_DECODED_ZEROES = [0, 0, 0, 0, 0, 0];
+
+var _DECOMPOSITIONS_FOR_DECODING = [
+    ["A", "", "BCD"], ["A", "BCD", "", ""], ["A", "B", "", "", "CD", ""],
+    ["", "A", "BC", "", "D"], ["", "AB", "C", "", "", "D"], ["AB", "CD", ""],
+    ["", "ABC", "", "D"], ["", "ABC", "D", ""], ["", "", "ABCD", ""],
+    ["A", "B", "C", "D"], ["", "A", "B", "C", "D", ""],
+    ["", "A", "B", "", "", "C", "", "D", ""]];
+
+const _DECOMPOSITION_DECODED = const [0, 16, 131];
+
+var _DECOMPOSITIONS_FOR_ENCODING = [
+    [[196, 16], [], [158], [196]],
+    [[196, 16], [158, 196], [], []],
+    [[196], [], [16], [], [], [158], [], [196]],
+    [[196], [], [16], [158, 196], [], []],
+    [[], [196], [], [], [16, 158], [], [196]],
+    [[], [196], [16, 158, 196], []],
+    [[196, 16, 158], [], [], [196]],
+    [[196, 16, 158], [], [196], []],
+    [[196, 16, 158, 196], [], [], []]];
+
+const _DECOMPOSITION_ENCODED = 'xBCexA==';
+
+const _INCONSISTENT_SAFE_RESULT = 'A+_x';
+
+const _INCONSISTENT_SAFE_STREAMING_RESULT = const ['A+AAA', '_x='];
 
 // Test data with only zeroes.
 var inputsWithZeroes = [[0, 0, 0], [0, 0], [0], []];
@@ -61,52 +117,132 @@
 
 void _testEncoder() {
   for (var i = 0; i < _INPUTS.length; i++) {
-    expect(CryptoUtils.bytesToBase64(_INPUTS[i].codeUnits), _RESULTS[i]);
+    expect(BASE64.encode(_INPUTS[i].codeUnits), _RESULTS[i]);
   }
   for (var i = 0; i < inputsWithZeroes.length; i++) {
-    expect(CryptoUtils.bytesToBase64(inputsWithZeroes[i]),
-        _RESULTS_WITH_ZEROS[i]);
+    expect(BASE64.encode(inputsWithZeroes[i]),
+           _RESULTS_WITH_ZEROS[i]);
   }
-  expect(
-      CryptoUtils.bytesToBase64(_LONG_LINE.codeUnits, addLineSeparator : true),
-      _LONG_LINE_RESULT);
-  expect(CryptoUtils.bytesToBase64(_LONG_LINE.codeUnits),
-      _LONG_LINE_RESULT_NO_BREAK);
+  expect(BASE64.encode(_LONG_LINE.codeUnits, addLineSeparator : true),
+         _LONG_LINE_RESULT);
+  expect(BASE64.encode(_LONG_LINE.codeUnits),
+         _LONG_LINE_RESULT_NO_BREAK);
 }
 
 void _testDecoder() {
   for (var i = 0; i < _RESULTS.length; i++) {
     expect(
-        new String.fromCharCodes(CryptoUtils.base64StringToBytes(_RESULTS[i])),
+        new String.fromCharCodes(BASE64.decode(_RESULTS[i])),
         _INPUTS[i]);
   }
+
   for (var i = 0; i < _RESULTS_WITH_ZEROS.length; i++) {
-    expect(CryptoUtils.base64StringToBytes(_RESULTS_WITH_ZEROS[i]),
+    expect(BASE64.decode(_RESULTS_WITH_ZEROS[i]),
         inputsWithZeroes[i]);
   }
-  var longLineDecoded = CryptoUtils.base64StringToBytes(_LONG_LINE_RESULT);
+
+  var longLineDecoded = BASE64.decode(_LONG_LINE_RESULT);
   expect(new String.fromCharCodes(longLineDecoded), _LONG_LINE);
-  var longLineResultNoBreak =
-      CryptoUtils.base64StringToBytes(_LONG_LINE_RESULT);
+
+  var longLineResultNoBreak = BASE64.decode(_LONG_LINE_RESULT);
   expect(new String.fromCharCodes(longLineResultNoBreak), _LONG_LINE);
 }
 
+Future _testStreamingEncoder() async {
+  expect(
+      await new Stream.fromIterable(_STREAMING_ENCODER_INPUT)
+                      .transform(BASE64.encoder)
+                      .join(),
+      _STREAMING_ENCODED);
+}
+
+Future _testStreamingDecoder() async {
+  expect(
+      await new Stream.fromIterable(_STREAMING_DECODER_INPUT)
+                      .transform(BASE64.decoder)
+                      .expand((l) => l)
+                      .toList(),
+      _STREAMING_DECODED);
+
+  expect(
+      await new Stream.fromIterable(_STREAMING_DECODER_INPUT_FOR_ZEROES)
+                      .transform(BASE64.decoder)
+                      .expand((l) => l)
+                      .toList(),
+      _STREAMING_DECODED_ZEROES);
+}
+
+Future _testStreamingDecoderForMalformedInput() async {
+  expect(new Stream.fromIterable(['ABz'])
+                   .transform(BASE64.decoder)
+                   .toList(),
+         throwsFormatException);
+
+  expect(new Stream.fromIterable(['AB', 'Lx', 'z', 'xx'])
+                   .transform(BASE64.decoder)
+                   .toList(),
+         throwsFormatException);
+}
+
+Future _testStreamingEncoderForDecompositions() async {
+  for(var decomposition in _DECOMPOSITIONS_FOR_ENCODING) {
+    expect(
+        await new Stream.fromIterable(decomposition)
+                        .transform(BASE64.encoder)
+                        .join(),
+        _DECOMPOSITION_ENCODED);
+  }
+}
+
+Future _testStreamingDecoderForDecompositions() async {
+  for(var decomposition in _DECOMPOSITIONS_FOR_DECODING) {
+    expect(
+        await new Stream.fromIterable(decomposition)
+                        .transform(BASE64.decoder)
+                        .expand((x) => x)
+                        .toList(),
+        _DECOMPOSITION_DECODED);
+  }
+}
+
 void _testDecoderForMalformedInput() {
   expect(() {
-    CryptoUtils.base64StringToBytes('AB~');
+    BASE64.decode('AB~');
   }, throwsFormatException);
 
   expect(() {
-    CryptoUtils.base64StringToBytes('A');
+    BASE64.decode('A');
   }, throwsFormatException);
 }
 
+Future _testUrlSafeStreaming() async {
+  String encUrlSafe = '-_A=';
+  List<List<int>> dec = [BASE64.decode('+/A=')];
+  var streamedResult = await new Stream.fromIterable(dec)
+      .transform(new Base64Encoder(urlSafe: true)).join();
+
+  expect(streamedResult, encUrlSafe);
+}
+
+void _testConsistentSafeUnsafeDecode() {
+  expect(() {
+    BASE64.decode(_INCONSISTENT_SAFE_RESULT);
+  }, throwsFormatException);
+}
+
+Future _testConsistentSafeUnsafeStreamDecode() {
+  expect(new Stream.fromIterable(_INCONSISTENT_SAFE_STREAMING_RESULT)
+                   .transform(BASE64.decoder)
+                   .toList(),
+         throwsFormatException);
+}
+
 void _testUrlSafeEncodeDecode() {
-  List<int> decUrlSafe = CryptoUtils.base64StringToBytes('-_A=');
-  List<int> dec = CryptoUtils.base64StringToBytes('+/A=');
+  List<int> decUrlSafe = BASE64.decode('-_A=');
+  List<int> dec = BASE64.decode('+/A=');
   expect(decUrlSafe, orderedEquals(dec));
-  expect(CryptoUtils.bytesToBase64(dec, urlSafe: true), '-_A=');
-  expect(CryptoUtils.bytesToBase64(dec), '+/A=');
+  expect(BASE64.encode(dec, urlSafe: true), '-_A=');
+  expect(BASE64.encode(dec), '+/A=');
 }
 
 void _testEncodeDecodeLists() {
@@ -116,8 +252,8 @@
       for (int k = 0; k < i; k++) {
         x[k] = j;
       }
-      var enc = CryptoUtils.bytesToBase64(x);
-      var dec = CryptoUtils.base64StringToBytes(enc);
+      var enc = BASE64.encode(x);
+      var dec = BASE64.decode(enc);
       expect(dec, orderedEquals(x));
     }
   }
@@ -130,6 +266,13 @@
   }
 }
 
+void _testOldApi() {
+  for (int i = 0; i < _INPUTS.length; i++) {
+    expect(CryptoUtils.bytesToBase64(_INPUTS[i].codeUnits), _RESULTS[i]);
+    expect(CryptoUtils.base64StringToBytes(_RESULTS[i]), _INPUTS[i].codeUnits);
+  }
+}
+
 void _testPerformance() {
     var l = new List<int>(1024);
     var iters = 5000;
@@ -137,17 +280,17 @@
     String enc;
     var w = new Stopwatch()..start();
     for( int i = 0; i < iters; ++i ) {
-      enc = CryptoUtils.bytesToBase64(l);
+      enc = BASE64.encode(l);
     }
     int ms = w.elapsedMilliseconds;
     int perSec = (iters * l.length) * 1000 ~/ ms;
     // print("Encode 1024 bytes for $iters times: $ms msec. $perSec b/s");
     w..reset();
     for( int i = 0; i < iters; ++i ) {
-      CryptoUtils.base64StringToBytes(enc);
+      BASE64.decode(enc);
     }
     ms = w.elapsedMilliseconds;
     perSec = (iters * l.length) * 1000 ~/ ms;
-    // print('''Decode into ${l.length} bytes for $iters
+    // ('''Decode into ${l.length} bytes for $iters
     //     times: $ms msec. $perSec b/s''');
 }
