diff --git a/mercurial/bundle2.py b/mercurial/bundle2.py
new file mode 100644
index 0000000000000000000000000000000000000000..9c5183cb9bca46c95b0e8cd94e99cb168df0a057_bWVyY3VyaWFsL2J1bmRsZTIucHk=
--- /dev/null
+++ b/mercurial/bundle2.py
@@ -0,0 +1,84 @@
+# bundle2.py - generic container format to transmit arbitrary data.
+#
+# Copyright 2013 Facebook, Inc.
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2 or any later version.
+"""Handling of the new bundle2 format
+
+The goal of bundle2 is to act as an atomically packet to transmit a set of
+payloads in an application agnostic way. It consist in a sequence of "parts"
+that will be handed to and processed by the application layer.
+
+
+General format architecture
+===========================
+
+The format is architectured as follow
+
+ - magic string
+ - stream level parameters
+ - payload parts (any number)
+ - end of stream marker.
+
+The current implementation is limited to empty bundle.
+
+Details on the Binary format
+============================
+
+All numbers are unsigned and big endian.
+
+stream level parameters
+------------------------
+
+Binary format is as follow
+
+:params size: (16 bits integer)
+
+  The total number of Bytes used by the parameters
+
+  Currently force to 0.
+
+:params value: arbitrary number of Bytes
+
+  A blob of `params size` containing the serialized version of all stream level
+  parameters.
+
+  Currently always empty.
+
+
+Payload part
+------------------------
+
+Binary format is as follow
+
+:header size: (16 bits inter)
+
+  The total number of Bytes used by the part headers. When the header is empty
+  (size = 0) this is interpreted as the end of stream marker.
+
+  Currently forced to 0 in the current state of the implementation
+"""
+
+_magicstring = 'HG20'
+
+class bundle20(object):
+    """represent an outgoing bundle2 container
+
+    People will eventually be able to add param and parts to this object and
+    generated a stream from it."""
+
+    def __init__(self):
+        self._params = []
+        self._parts = []
+
+    def getchunks(self):
+        yield _magicstring
+        # no support for any param yet
+        # to be obviously fixed soon.
+        assert not self._params
+        yield '\0\0'
+        # no support for parts
+        # to be obviously fixed soon.
+        assert not self._parts
+        yield '\0\0'
diff --git a/tests/test-bundle2.t b/tests/test-bundle2.t
new file mode 100644
index 0000000000000000000000000000000000000000..9c5183cb9bca46c95b0e8cd94e99cb168df0a057_dGVzdHMvdGVzdC1idW5kbGUyLnQ=
--- /dev/null
+++ b/tests/test-bundle2.t
@@ -0,0 +1,36 @@
+
+Create an extension to test bundle2 API
+
+  $ cat > bundle2.py << EOF
+  > """A small extension to test bundle2 implementation
+  > 
+  > Current bundle2 implementation is far too limited to be used in any core
+  > code. We still need to be able to test it while it grow up.
+  > """
+  > 
+  > from mercurial import cmdutil
+  > from mercurial import bundle2
+  > cmdtable = {}
+  > command = cmdutil.command(cmdtable)
+  > 
+  > @command('bundle2', [], '')
+  > def cmdbundle2(ui, repo):
+  >     """write a bundle2 container on standard ouput"""
+  >     bundle = bundle2.bundle20()
+  >     for chunk in bundle.getchunks():
+  >         ui.write(chunk)
+  > EOF
+  $ cat >> $HGRCPATH << EOF
+  > [extensions]
+  > bundle2=$TESTTMP/bundle2.py
+  > EOF
+
+The extension requires a repo (currently unused)
+
+  $ hg init main
+  $ cd main
+
+Test simple generation of empty bundle
+
+  $ hg bundle2
+  HG20\x00\x00\x00\x00 (no-eol) (esc)